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

Commit a8afb50f authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Require sharing shortcuts for the conversation space" into rvc-dev

parents 2bf744ab fa27307a
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);
    }
}