Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 90bd7895 authored by Anna Zappone's avatar Anna Zappone
Browse files

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
parent 70dedcf3
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -2661,8 +2661,10 @@ public class NotificationManagerService extends SystemService {
            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);
+11 −2
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@ import android.content.pm.ShortcutServiceInternal;
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 @@ public class ShortcutHelper {
    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 @@ public class ShortcutHelper {
    };

    ShortcutHelper(LauncherApps launcherApps, ShortcutListener listener,
            ShortcutServiceInternal shortcutServiceInternal) {
            ShortcutServiceInternal shortcutServiceInternal, UserManager userManager) {
        mLauncherAppsService = launcherApps;
        mShortcutListener = listener;
        mShortcutServiceInternal = shortcutServiceInternal;
        mUserManager = userManager;
    }

    @VisibleForTesting
@@ -160,6 +163,11 @@ public class ShortcutHelper {
        mShortcutServiceInternal = shortcutServiceInternal;
    }

    @VisibleForTesting
    void setUserManager(UserManager userManager) {
        mUserManager = userManager;
    }

    /**
     * Returns whether the given shortcut info is a conversation shortcut.
     */
@@ -182,7 +190,8 @@ public class ShortcutHelper {
     * 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();
+13 −0
Original line number Diff line number Diff line
@@ -65,6 +65,8 @@ import static com.android.server.notification.NotificationManagerService.ACTION_
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 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
    @Mock
    private ShortcutServiceInternal mShortcutServiceInternal;
    @Mock
    private UserManager mUserManager;
    @Mock
    ActivityManager mActivityManager;
    @Mock
    Resources mResources;
@@ -526,6 +530,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
        mShortcutHelper = mService.getShortcutHelper();
        mShortcutHelper.setLauncherApps(mLauncherApps);
        mShortcutHelper.setShortcutServiceInternal(mShortcutServiceInternal);
        mShortcutHelper.setUserManager(mUserManager);

        // Capture PackageIntentReceiver
        ArgumentCaptor<BroadcastReceiver> broadcastReceiverCaptor =
@@ -567,6 +572,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
        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 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
                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
+24 −1
Original line number Diff line number Diff line
@@ -34,6 +34,7 @@ import android.content.pm.ShortcutInfo;
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 @@ public class ShortcutHelperTest extends UiServiceTestCase {
    @Mock
    ShortcutHelper.ShortcutListener mShortcutListener;
    @Mock
    UserManager mUserManager;
    @Mock
    ShortcutServiceInternal mShortcutServiceInternal;
    @Mock
    NotificationRecord mNr;
@@ -92,11 +95,12 @@ public class ShortcutHelperTest extends UiServiceTestCase {
        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 @@ public class ShortcutHelperTest extends UiServiceTestCase {
                .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() {