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

Commit fa27307a authored by Julia Reynolds's avatar Julia Reynolds
Browse files

Require sharing shortcuts for the conversation space

Test: atest
Fixes: 150410079
Change-Id: Ib47f14d2fbdeff401651b1fecac0345e77a8f5bd
parent d3f12e83
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -156,6 +156,7 @@ import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.PackageManagerInternal;
import android.content.pm.ParceledListSlice;
import android.content.pm.ShortcutInfo;
import android.content.pm.ShortcutServiceInternal;
import android.content.pm.UserInfo;
import android.content.res.Resources;
import android.database.ContentObserver;
@@ -2300,7 +2301,8 @@ public class NotificationManagerService extends SystemService {
            mRoleObserver.init();
            LauncherApps launcherApps =
                    (LauncherApps) getContext().getSystemService(Context.LAUNCHER_APPS_SERVICE);
            mShortcutHelper = new ShortcutHelper(launcherApps, mShortcutListener);
            mShortcutHelper = new ShortcutHelper(launcherApps, mShortcutListener, getLocalService(
                    ShortcutServiceInternal.class));
            BubbleExtractor bubbsExtractor = mRankingHelper.findExtractor(BubbleExtractor.class);
            if (bubbsExtractor != null) {
                bubbsExtractor.setShortcutHelper(mShortcutHelper);
+2 −0
Original line number Diff line number Diff line
@@ -590,6 +590,8 @@ public final class NotificationRecord {
            pw.println(prefix + "snoozeCriteria=" + TextUtils.join(",", getSnoozeCriteria()));
        }
        pw.println(prefix + "mAdjustments=" + mAdjustments);
        pw.println(prefix + "shortcut=" + notification.getShortcutId()
                + " found valid? " + (mShortcutInfo != null));
    }

    @Override
+29 −2
Original line number Diff line number Diff line
@@ -21,11 +21,15 @@ import static android.content.pm.LauncherApps.ShortcutQuery.FLAG_MATCH_DYNAMIC;
import static android.content.pm.LauncherApps.ShortcutQuery.FLAG_MATCH_PINNED;

import android.annotation.NonNull;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.LauncherApps;
import android.content.pm.ShortcutInfo;
import android.content.pm.ShortcutServiceInternal;
import android.os.Binder;
import android.os.Handler;
import android.os.UserHandle;
import android.util.Slog;

import com.android.internal.annotations.VisibleForTesting;

@@ -38,6 +42,7 @@ import java.util.List;
 * Helper for querying shortcuts.
 */
class ShortcutHelper {
    private static final String TAG = "ShortcutHelper";

    /**
     * Listener to call when a shortcut we're tracking has been removed.
@@ -48,6 +53,8 @@ class ShortcutHelper {

    private LauncherApps mLauncherAppsService;
    private ShortcutListener mShortcutListener;
    private ShortcutServiceInternal mShortcutServiceInternal;
    private IntentFilter mSharingFilter;

    // Key: packageName Value: <shortcutId, notifId>
    private HashMap<String, HashMap<String, String>> mActiveShortcutBubbles = new HashMap<>();
@@ -111,9 +118,17 @@ class ShortcutHelper {
        }
    };

    ShortcutHelper(LauncherApps launcherApps, ShortcutListener listener) {
    ShortcutHelper(LauncherApps launcherApps, ShortcutListener listener,
            ShortcutServiceInternal shortcutServiceInternal) {
        mLauncherAppsService = launcherApps;
        mShortcutListener = listener;
        mSharingFilter = new IntentFilter();
        try {
            mSharingFilter.addDataType("*/*");
        } catch (IntentFilter.MalformedMimeTypeException e) {
            Slog.e(TAG, "Bad mime type", e);
        }
        mShortcutServiceInternal = shortcutServiceInternal;
    }

    @VisibleForTesting
@@ -121,6 +136,11 @@ class ShortcutHelper {
        mLauncherAppsService = launcherApps;
    }

    @VisibleForTesting
    void setShortcutServiceInternal(ShortcutServiceInternal shortcutServiceInternal) {
        mShortcutServiceInternal = shortcutServiceInternal;
    }

    /**
     * Only returns shortcut info if it's found and if it's {@link ShortcutInfo#isLongLived()}.
     */
@@ -141,7 +161,14 @@ class ShortcutHelper {
            ShortcutInfo info = shortcuts != null && shortcuts.size() > 0
                    ? shortcuts.get(0)
                    : null;
            return info != null && info.isLongLived() ? info : null;
            if (info == null || !info.isLongLived() || !info.isEnabled()) {
                return null;
            }
            if (mShortcutServiceInternal.isSharingShortcut(user.getIdentifier(),
                    "android", packageName, shortcutId, user.getIdentifier(), mSharingFilter)) {
                return info;
            }
            return null;
        } finally {
            Binder.restoreCallingIdentity(token);
        }
+13 −0
Original line number Diff line number Diff line
@@ -113,6 +113,7 @@ import android.content.pm.LauncherApps;
import android.content.pm.PackageManager;
import android.content.pm.ParceledListSlice;
import android.content.pm.ShortcutInfo;
import android.content.pm.ShortcutServiceInternal;
import android.content.pm.UserInfo;
import android.content.res.Resources;
import android.graphics.Color;
@@ -234,6 +235,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
    @Mock
    private LauncherApps mLauncherApps;
    @Mock
    private ShortcutServiceInternal mShortcutServiceInternal;
    @Mock
    ActivityManager mActivityManager;
    @Mock
    Resources mResources;
@@ -466,6 +469,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {

        mShortcutHelper = mService.getShortcutHelper();
        mShortcutHelper.setLauncherApps(mLauncherApps);
        mShortcutHelper.setShortcutServiceInternal(mShortcutServiceInternal);

        // Set the testable bubble extractor
        RankingHelper rankingHelper = mService.getRankingHelper();
@@ -6088,8 +6092,11 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
        List<ShortcutInfo> shortcutInfos = new ArrayList<>();
        ShortcutInfo info = mock(ShortcutInfo.class);
        when(info.isLongLived()).thenReturn(true);
        when(info.isEnabled()).thenReturn(true);
        shortcutInfos.add(info);
        when(mLauncherApps.getShortcuts(any(), any())).thenReturn(shortcutInfos);
        when(mShortcutServiceInternal.isSharingShortcut(anyInt(), anyString(), anyString(),
                anyString(), anyInt(), any())).thenReturn(true);

        // Test: Send the bubble notification
        mBinderService.enqueueNotificationWithTag(PKG, PKG, nr.getSbn().getTag(),
@@ -6148,8 +6155,11 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
        List<ShortcutInfo> shortcutInfos = new ArrayList<>();
        ShortcutInfo info = mock(ShortcutInfo.class);
        when(info.isLongLived()).thenReturn(true);
        when(info.isEnabled()).thenReturn(true);
        shortcutInfos.add(info);
        when(mLauncherApps.getShortcuts(any(), any())).thenReturn(shortcutInfos);
        when(mShortcutServiceInternal.isSharingShortcut(anyInt(), anyString(), anyString(),
                anyString(), anyInt(), any())).thenReturn(true);

        // Test: Send the bubble notification
        mBinderService.enqueueNotificationWithTag(PKG, PKG, nr.getSbn().getTag(),
@@ -6492,7 +6502,10 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
        ShortcutInfo si = mock(ShortcutInfo.class);
        when(si.getShortLabel()).thenReturn("Hello");
        when(si.isLongLived()).thenReturn(true);
        when(si.isEnabled()).thenReturn(true);
        when(mLauncherApps.getShortcuts(any(), any())).thenReturn(Arrays.asList(si));
        when(mShortcutServiceInternal.isSharingShortcut(anyInt(), anyString(), anyString(),
                anyString(), anyInt(), any())).thenReturn(true);

        List<ConversationChannelWrapper> conversations =
                mBinderService.getConversationsForPackage(PKG_P, mUid).getList();
+85 −1
Original line number Diff line number Diff line
@@ -16,7 +16,11 @@

package com.android.server.notification;

import static com.google.common.truth.Truth.assertThat;

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
@@ -25,6 +29,7 @@ import static org.mockito.Mockito.when;
import android.app.Notification;
import android.content.pm.LauncherApps;
import android.content.pm.ShortcutInfo;
import android.content.pm.ShortcutServiceInternal;
import android.os.UserHandle;
import android.service.notification.StatusBarNotification;
import android.test.suitebuilder.annotation.SmallTest;
@@ -58,6 +63,8 @@ public class ShortcutHelperTest extends UiServiceTestCase {
    @Mock
    ShortcutHelper.ShortcutListener mShortcutListener;
    @Mock
    ShortcutServiceInternal mShortcutServiceInternal;
    @Mock
    NotificationRecord mNr;
    @Mock
    Notification mNotif;
@@ -72,7 +79,8 @@ public class ShortcutHelperTest extends UiServiceTestCase {
    public void setUp() {
        MockitoAnnotations.initMocks(this);

        mShortcutHelper = new ShortcutHelper(mLauncherApps, mShortcutListener);
        mShortcutHelper = new ShortcutHelper(
                mLauncherApps, mShortcutListener, mShortcutServiceInternal);
        when(mNr.getKey()).thenReturn(KEY);
        when(mNr.getSbn()).thenReturn(mSbn);
        when(mSbn.getPackageName()).thenReturn(PKG);
@@ -138,4 +146,80 @@ public class ShortcutHelperTest extends UiServiceTestCase {
        callback.onShortcutsChanged(PKG, shortcutInfos, mock(UserHandle.class));
        verify(mShortcutListener).onShortcutRemoved(mNr.getKey());
    }

    @Test
    public void testGetValidShortcutInfo_noMatchingShortcut() {
        when(mLauncherApps.getShortcuts(any(), any())).thenReturn(null);
        when(mShortcutServiceInternal.isSharingShortcut(anyInt(), anyString(), anyString(),
                anyString(), anyInt(), any())).thenReturn(true);

        assertThat(mShortcutHelper.getValidShortcutInfo("a", "p", UserHandle.SYSTEM)).isNull();
    }

    @Test
    public void testGetValidShortcutInfo_nullShortcut() {
        ArrayList<ShortcutInfo> shortcuts = new ArrayList<>();
        shortcuts.add(null);
        when(mLauncherApps.getShortcuts(any(), any())).thenReturn(shortcuts);
        when(mShortcutServiceInternal.isSharingShortcut(anyInt(), anyString(), anyString(),
                anyString(), anyInt(), any())).thenReturn(true);

        assertThat(mShortcutHelper.getValidShortcutInfo("a", "p", UserHandle.SYSTEM)).isNull();
    }

    @Test
    public void testGetValidShortcutInfo_notLongLived() {
        ShortcutInfo si = mock(ShortcutInfo.class);
        when(si.isLongLived()).thenReturn(false);
        when(si.isEnabled()).thenReturn(true);
        ArrayList<ShortcutInfo> shortcuts = new ArrayList<>();
        shortcuts.add(si);
        when(mLauncherApps.getShortcuts(any(), any())).thenReturn(shortcuts);
        when(mShortcutServiceInternal.isSharingShortcut(anyInt(), anyString(), anyString(),
                anyString(), anyInt(), any())).thenReturn(true);

        assertThat(mShortcutHelper.getValidShortcutInfo("a", "p", UserHandle.SYSTEM)).isNull();
    }

    @Test
    public void testGetValidShortcutInfo_notSharingShortcut() {
        ShortcutInfo si = mock(ShortcutInfo.class);
        when(si.isLongLived()).thenReturn(true);
        when(si.isEnabled()).thenReturn(true);
        ArrayList<ShortcutInfo> shortcuts = new ArrayList<>();
        shortcuts.add(si);
        when(mLauncherApps.getShortcuts(any(), any())).thenReturn(shortcuts);
        when(mShortcutServiceInternal.isSharingShortcut(anyInt(), anyString(), anyString(),
                anyString(), anyInt(), any())).thenReturn(false);

        assertThat(mShortcutHelper.getValidShortcutInfo("a", "p", UserHandle.SYSTEM)).isNull();
    }

    @Test
    public void testGetValidShortcutInfo_notEnabled() {
        ShortcutInfo si = mock(ShortcutInfo.class);
        when(si.isLongLived()).thenReturn(true);
        when(si.isEnabled()).thenReturn(false);
        ArrayList<ShortcutInfo> shortcuts = new ArrayList<>();
        shortcuts.add(si);
        when(mLauncherApps.getShortcuts(any(), any())).thenReturn(shortcuts);
        when(mShortcutServiceInternal.isSharingShortcut(anyInt(), anyString(), anyString(),
                anyString(), anyInt(), any())).thenReturn(true);

        assertThat(mShortcutHelper.getValidShortcutInfo("a", "p", UserHandle.SYSTEM)).isNull();
    }

    @Test
    public void testGetValidShortcutInfo_isValid() {
        ShortcutInfo si = mock(ShortcutInfo.class);
        when(si.isLongLived()).thenReturn(true);
        when(si.isEnabled()).thenReturn(true);
        ArrayList<ShortcutInfo> shortcuts = new ArrayList<>();
        shortcuts.add(si);
        when(mLauncherApps.getShortcuts(any(), any())).thenReturn(shortcuts);
        when(mShortcutServiceInternal.isSharingShortcut(anyInt(), anyString(), anyString(),
                anyString(), anyInt(), any())).thenReturn(true);

        assertThat(mShortcutHelper.getValidShortcutInfo("a", "p", UserHandle.SYSTEM)).isSameAs(si);
    }
}