Fix crash in NotificationManager when WP is off

Shortcuts will crash if queried when locked. Early opt-out any calls into
LauncherApps when the user is locked.

Bug: 182575662
Test: NotificationManagerServiceTest, ShortcutHelperTest
Change-Id: Icf1c9fb09f3d1732f6d40b75412f833d7952f5d6
diff --git a/services/core/java/com/android/server/notification/NotificationManagerService.java b/services/core/java/com/android/server/notification/NotificationManagerService.java
index 5b5d5d4..b26485b 100755
--- a/services/core/java/com/android/server/notification/NotificationManagerService.java
+++ b/services/core/java/com/android/server/notification/NotificationManagerService.java
@@ -2661,8 +2661,10 @@
             mRoleObserver = roleObserver;
             LauncherApps launcherApps =
                     (LauncherApps) getContext().getSystemService(Context.LAUNCHER_APPS_SERVICE);
+            UserManager userManager = (UserManager) getContext().getSystemService(
+                    Context.USER_SERVICE);
             mShortcutHelper = new ShortcutHelper(launcherApps, mShortcutListener, getLocalService(
-                    ShortcutServiceInternal.class));
+                    ShortcutServiceInternal.class), userManager);
             BubbleExtractor bubbsExtractor = mRankingHelper.findExtractor(BubbleExtractor.class);
             if (bubbsExtractor != null) {
                 bubbsExtractor.setShortcutHelper(mShortcutHelper);
diff --git a/services/core/java/com/android/server/notification/ShortcutHelper.java b/services/core/java/com/android/server/notification/ShortcutHelper.java
index b0be206..fc106b8 100644
--- a/services/core/java/com/android/server/notification/ShortcutHelper.java
+++ b/services/core/java/com/android/server/notification/ShortcutHelper.java
@@ -29,6 +29,7 @@
 import android.os.Binder;
 import android.os.Handler;
 import android.os.UserHandle;
+import android.os.UserManager;
 import android.text.TextUtils;
 import android.util.Slog;
 
@@ -67,6 +68,7 @@
     private LauncherApps mLauncherAppsService;
     private ShortcutListener mShortcutListener;
     private ShortcutServiceInternal mShortcutServiceInternal;
+    private UserManager mUserManager;
 
     // Key: packageName Value: <shortcutId, notifId>
     private HashMap<String, HashMap<String, String>> mActiveShortcutBubbles = new HashMap<>();
@@ -144,10 +146,11 @@
     };
 
     ShortcutHelper(LauncherApps launcherApps, ShortcutListener listener,
-            ShortcutServiceInternal shortcutServiceInternal) {
+            ShortcutServiceInternal shortcutServiceInternal, UserManager userManager) {
         mLauncherAppsService = launcherApps;
         mShortcutListener = listener;
         mShortcutServiceInternal = shortcutServiceInternal;
+        mUserManager = userManager;
     }
 
     @VisibleForTesting
@@ -160,6 +163,11 @@
         mShortcutServiceInternal = shortcutServiceInternal;
     }
 
+    @VisibleForTesting
+    void setUserManager(UserManager userManager) {
+        mUserManager = userManager;
+    }
+
     /**
      * Returns whether the given shortcut info is a conversation shortcut.
      */
@@ -182,7 +190,8 @@
      * Only returns shortcut info if it's found and if it's a conversation shortcut.
      */
     ShortcutInfo getValidShortcutInfo(String shortcutId, String packageName, UserHandle user) {
-        if (mLauncherAppsService == null) {
+        // Shortcuts cannot be accessed when the user is locked.
+        if (mLauncherAppsService == null  || !mUserManager.isUserUnlocked(user)) {
             return null;
         }
         final long token = Binder.clearCallingIdentity();
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
index 2c7c3e3..70ba2cf 100755
--- a/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/NotificationManagerServiceTest.java
@@ -65,6 +65,8 @@
 import static com.android.server.notification.NotificationManagerService.ACTION_ENABLE_NAS;
 import static com.android.server.notification.NotificationManagerService.ACTION_LEARNMORE_NAS;
 
+import static com.google.common.truth.Truth.assertThat;
+
 import static junit.framework.Assert.assertEquals;
 import static junit.framework.Assert.assertFalse;
 import static junit.framework.Assert.assertNotNull;
@@ -261,6 +263,8 @@
     @Mock
     private ShortcutServiceInternal mShortcutServiceInternal;
     @Mock
+    private UserManager mUserManager;
+    @Mock
     ActivityManager mActivityManager;
     @Mock
     Resources mResources;
@@ -526,6 +530,7 @@
         mShortcutHelper = mService.getShortcutHelper();
         mShortcutHelper.setLauncherApps(mLauncherApps);
         mShortcutHelper.setShortcutServiceInternal(mShortcutServiceInternal);
+        mShortcutHelper.setUserManager(mUserManager);
 
         // Capture PackageIntentReceiver
         ArgumentCaptor<BroadcastReceiver> broadcastReceiverCaptor =
@@ -567,6 +572,7 @@
         when(mLauncherApps.getShortcuts(any(), any())).thenReturn(shortcutInfos);
         when(mShortcutServiceInternal.isSharingShortcut(anyInt(), anyString(), anyString(),
                 anyString(), anyInt(), any())).thenReturn(true);
+        when(mUserManager.isUserUnlocked(any(UserHandle.class))).thenReturn(true);
 
         // Set the testable bubble extractor
         RankingHelper rankingHelper = mService.getRankingHelper();
@@ -7506,6 +7512,13 @@
                 mBinderService.getConversationsForPackage(PKG_P, mUid).getList();
         assertEquals(si, conversations.get(0).getShortcutInfo());
         assertEquals(si, conversations.get(1).getShortcutInfo());
+
+        // Returns null shortcuts when locked.
+        when(mUserManager.isUserUnlocked(any(UserHandle.class))).thenReturn(false);
+        conversations =
+                mBinderService.getConversationsForPackage(PKG_P, mUid).getList();
+        assertThat(conversations.get(0).getShortcutInfo()).isNull();
+        assertThat(conversations.get(1).getShortcutInfo()).isNull();
     }
 
     @Test
diff --git a/services/tests/uiservicestests/src/com/android/server/notification/ShortcutHelperTest.java b/services/tests/uiservicestests/src/com/android/server/notification/ShortcutHelperTest.java
index f43e5a8..11cb150 100644
--- a/services/tests/uiservicestests/src/com/android/server/notification/ShortcutHelperTest.java
+++ b/services/tests/uiservicestests/src/com/android/server/notification/ShortcutHelperTest.java
@@ -34,6 +34,7 @@
 import android.content.pm.ShortcutQueryWrapper;
 import android.content.pm.ShortcutServiceInternal;
 import android.os.UserHandle;
+import android.os.UserManager;
 import android.service.notification.StatusBarNotification;
 import android.test.suitebuilder.annotation.SmallTest;
 import android.testing.TestableLooper;
@@ -71,6 +72,8 @@
     @Mock
     ShortcutHelper.ShortcutListener mShortcutListener;
     @Mock
+    UserManager mUserManager;
+    @Mock
     ShortcutServiceInternal mShortcutServiceInternal;
     @Mock
     NotificationRecord mNr;
@@ -92,11 +95,12 @@
         MockitoAnnotations.initMocks(this);
 
         mShortcutHelper = new ShortcutHelper(
-                mLauncherApps, mShortcutListener, mShortcutServiceInternal);
+                mLauncherApps, mShortcutListener, mShortcutServiceInternal, mUserManager);
         when(mSbn.getPackageName()).thenReturn(PKG);
         when(mShortcutInfo.getId()).thenReturn(SHORTCUT_ID);
         when(mNotif.getBubbleMetadata()).thenReturn(mBubbleMetadata);
         when(mBubbleMetadata.getShortcutId()).thenReturn(SHORTCUT_ID);
+        when(mUserManager.isUserUnlocked(any(UserHandle.class))).thenReturn(true);
 
         setUpMockNotificationRecord(mNr, KEY);
     }
@@ -317,6 +321,25 @@
                 .isSameInstanceAs(si);
     }
 
+
+    @Test
+    public void testGetValidShortcutInfo_isValidButUserLocked() {
+        ShortcutInfo si = mock(ShortcutInfo.class);
+        when(si.getPackage()).thenReturn(PKG);
+        when(si.getId()).thenReturn(SHORTCUT_ID);
+        when(si.getUserId()).thenReturn(UserHandle.USER_SYSTEM);
+        when(si.isLongLived()).thenReturn(true);
+        when(si.isEnabled()).thenReturn(true);
+        when(si.getPersons()).thenReturn(new Person[]{PERSON});
+        ArrayList<ShortcutInfo> shortcuts = new ArrayList<>();
+        shortcuts.add(si);
+        when(mLauncherApps.getShortcuts(any(), any())).thenReturn(shortcuts);
+        when(mUserManager.isUserUnlocked(any(UserHandle.class))).thenReturn(false);
+
+        assertThat(mShortcutHelper.getValidShortcutInfo("a", "p", UserHandle.SYSTEM))
+                .isNull();
+    }
+
     @Test
     public void testGetValidShortcutInfo_hasGetPersonsDataFlag() {