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

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

Up to date apps must provide conversation shortcuts

Apps targeting R must provide a valid conversation
shortcut to appear in the conversation space.

Test: atest
Fixes: 155189337
Change-Id: I79d24a74e448f08c118e8aadf0e147bfbeccc9e9
parent de9867d3
Loading
Loading
Loading
Loading
+10 −2
Original line number Diff line number Diff line
@@ -1382,13 +1382,21 @@ public final class NotificationRecord {
     */
    public boolean isConversation() {
        Notification notification = getNotification();
        if (mChannel.isDemoted()
                || !Notification.MessagingStyle.class.equals(notification.getNotificationStyle())) {
        if (!Notification.MessagingStyle.class.equals(notification.getNotificationStyle())) {
            // very common; don't bother logging
            return false;
        }
        if (mChannel.isDemoted()) {
            return false;
        }
        if (mIsNotConversationOverride) {
            return false;
        }
        if (mTargetSdkVersion >= Build.VERSION_CODES.R
            && Notification.MessagingStyle.class.equals(notification.getNotificationStyle())
            && mShortcutInfo == null) {
            return false;
        }
        return true;
    }

+3 −0
Original line number Diff line number Diff line
@@ -41,6 +41,7 @@ public class UiServiceTestCase {
    protected static final String PKG_N_MR1 = "com.example.n_mr1";
    protected static final String PKG_O = "com.example.o";
    protected static final String PKG_P = "com.example.p";
    protected static final String PKG_R = "com.example.r";

    @Rule
    public final TestableContext mContext =
@@ -69,6 +70,8 @@ public class UiServiceTestCase {
                            return Build.VERSION_CODES.O;
                        case PKG_P:
                            return Build.VERSION_CODES.P;
                        case PKG_R:
                            return Build.VERSION_CODES.R;
                        default:
                            return Build.VERSION_CODES.CUR_DEVELOPMENT;
                    }
+22 −27
Original line number Diff line number Diff line
@@ -250,6 +250,8 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {

    private static final int NOTIFICATION_LOCATION_UNKNOWN = 0;

    private static final String VALID_CONVO_SHORTCUT_ID = "shortcut";

    @Mock
    private NotificationListeners mListeners;
    @Mock private NotificationAssistants mAssistants;
@@ -471,6 +473,19 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
        mShortcutHelper.setLauncherApps(mLauncherApps);
        mShortcutHelper.setShortcutServiceInternal(mShortcutServiceInternal);

        // Pretend the shortcut exists
        List<ShortcutInfo> shortcutInfos = new ArrayList<>();
        ShortcutInfo info = mock(ShortcutInfo.class);
        when(info.getPackage()).thenReturn(PKG);
        when(info.getId()).thenReturn(VALID_CONVO_SHORTCUT_ID);
        when(info.getUserId()).thenReturn(USER_SYSTEM);
        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);

        // Set the testable bubble extractor
        RankingHelper rankingHelper = mService.getRankingHelper();
        BubbleExtractor extractor = rankingHelper.findExtractor(BubbleExtractor.class);
@@ -704,6 +719,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
                )
                .setActions(replyAction)
                .setSmallIcon(android.R.drawable.sym_def_app_icon)
                .setShortcutId(VALID_CONVO_SHORTCUT_ID)
                .setGroupSummary(isSummary);
        if (groupKey != null) {
            nb.setGroup(groupKey);
@@ -6075,7 +6091,6 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
    @Test
    public void testNotificationBubbles_flagRemoved_whenShortcutRemoved()
            throws RemoteException {
        final String shortcutId = "someshortcutId";
        setUpPrefsForBubbles(PKG, mUid,
                true /* global */,
                BUBBLE_PREFERENCE_ALL /* app */,
@@ -6086,27 +6101,16 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {

        // Messaging notification with shortcut info
        Notification.BubbleMetadata metadata =
                new Notification.BubbleMetadata.Builder(shortcutId).build();
                new Notification.BubbleMetadata.Builder(VALID_CONVO_SHORTCUT_ID).build();
        Notification.Builder nb = getMessageStyleNotifBuilder(false /* addDefaultMetadata */,
                null /* groupKey */, false /* isSummary */);
        nb.setShortcutId(shortcutId);
        nb.setShortcutId(VALID_CONVO_SHORTCUT_ID);
        nb.setBubbleMetadata(metadata);
        StatusBarNotification sbn = new StatusBarNotification(PKG, PKG, 1,
                "tag", mUid, 0, nb.build(), new UserHandle(mUid), null, 0);
        NotificationRecord nr = new NotificationRecord(mContext, sbn, mTestNotificationChannel);

        // Pretend the shortcut exists
        List<ShortcutInfo> shortcutInfos = new ArrayList<>();
        ShortcutInfo info = mock(ShortcutInfo.class);
        when(info.getPackage()).thenReturn(PKG);
        when(info.getId()).thenReturn(shortcutId);
        when(info.getUserId()).thenReturn(USER_SYSTEM);
        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(),
@@ -6124,7 +6128,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {

        // Make sure the shortcut is cached.
        verify(mShortcutServiceInternal).cacheShortcuts(
                anyInt(), any(), eq(PKG), eq(Collections.singletonList(shortcutId)),
                anyInt(), any(), eq(PKG), eq(Collections.singletonList(VALID_CONVO_SHORTCUT_ID)),
                eq(USER_SYSTEM));

        // Test: Remove the shortcut
@@ -6588,6 +6592,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
        convo2.setNotificationChannel(channel2);
        convos.add(convo2);
        when(mPreferencesHelper.getConversations(anyString(), anyInt())).thenReturn(convos);
        when(mLauncherApps.getShortcuts(any(), any())).thenReturn(null);

        List<ConversationChannelWrapper> conversations =
                mBinderService.getConversationsForPackage(PKG_P, mUid).getList();
@@ -6615,6 +6620,7 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
        NotificationRecord nr =
                generateMessageBubbleNotifRecord(mTestNotificationChannel,
                        "testRecordMessages_invalidMsg");
        when(mLauncherApps.getShortcuts(any(), any())).thenReturn(null);
        mBinderService.enqueueNotificationWithTag(PKG, PKG, nr.getSbn().getTag(),
                nr.getSbn().getId(), nr.getSbn().getNotification(), nr.getSbn().getUserId());
        waitForIdle();
@@ -6635,17 +6641,6 @@ public class NotificationManagerServiceTest extends UiServiceTestCase {
                "testRecordMessages_validMsg", mUid, 0, nb.build(), new UserHandle(mUid), null, 0);
        NotificationRecord nr = new NotificationRecord(mContext, sbn, mTestNotificationChannel);

        // Pretend the shortcut exists
        List<ShortcutInfo> shortcutInfos = new ArrayList<>();
        ShortcutInfo info = mock(ShortcutInfo.class);
        when(info.getPackage()).thenReturn(PKG);
        when(info.getId()).thenReturn("id");
        when(info.getUserId()).thenReturn(USER_SYSTEM);
        when(info.isLongLived()).thenReturn(true);
        when(info.isEnabled()).thenReturn(true);
        shortcutInfos.add(info);
        when(mLauncherApps.getShortcuts(any(), any())).thenReturn(shortcutInfos);

        mBinderService.enqueueNotificationWithTag(PKG, PKG, nr.getSbn().getTag(),
                nr.getSbn().getId(), nr.getSbn().getNotification(), nr.getSbn().getUserId());
        waitForIdle();
+18 −6
Original line number Diff line number Diff line
@@ -39,7 +39,6 @@ import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;

import android.annotation.Nullable;
import android.app.ActivityManager;
import android.app.IActivityManager;
import android.app.Notification;
@@ -90,7 +89,7 @@ public class NotificationRecordTest extends UiServiceTestCase {
    @Mock private PackageManager mPm;
    @Mock private ContentResolver mContentResolver;

    private final String pkg = PKG_N_MR1;
    private final String mPkg = PKG_O;
    private final int uid = 9583;
    private final int id1 = 1;
    private final String tag1 = "tag1";
@@ -198,10 +197,14 @@ public class NotificationRecordTest extends UiServiceTestCase {
        }

        Notification n = builder.build();
        return new StatusBarNotification(pkg, pkg, id1, tag1, uid, uid, n, mUser, null, uid);
        return new StatusBarNotification(mPkg, mPkg, id1, tag1, uid, uid, n, mUser, null, uid);
    }

    private StatusBarNotification getMessagingStyleNotification() {
        return getMessagingStyleNotification(mPkg);
    }

    private StatusBarNotification getMessagingStyleNotification(String pkg) {
        final Builder builder = new Builder(mMockContext)
                .setContentTitle("foo")
                .setSmallIcon(android.R.drawable.sym_def_app_icon);
@@ -658,7 +661,7 @@ public class NotificationRecordTest extends UiServiceTestCase {

        Bundle signals = new Bundle();
        signals.putInt(Adjustment.KEY_USER_SENTIMENT, USER_SENTIMENT_NEGATIVE);
        record.addAdjustment(new Adjustment(pkg, record.getKey(), signals, null, sbn.getUserId()));
        record.addAdjustment(new Adjustment(mPkg, record.getKey(), signals, null, sbn.getUserId()));

        record.applyAdjustments();

@@ -687,7 +690,7 @@ public class NotificationRecordTest extends UiServiceTestCase {

        Bundle signals = new Bundle();
        signals.putInt(Adjustment.KEY_USER_SENTIMENT, USER_SENTIMENT_NEGATIVE);
        record.addAdjustment(new Adjustment(pkg, record.getKey(), signals, null, sbn.getUserId()));
        record.addAdjustment(new Adjustment(mPkg, record.getKey(), signals, null, sbn.getUserId()));
        record.applyAdjustments();

        assertEquals(USER_SENTIMENT_POSITIVE, record.getUserSentiment());
@@ -705,7 +708,7 @@ public class NotificationRecordTest extends UiServiceTestCase {

        Bundle signals = new Bundle();
        signals.putInt(Adjustment.KEY_USER_SENTIMENT, USER_SENTIMENT_NEGATIVE);
        record.addAdjustment(new Adjustment(pkg, record.getKey(), signals, null, sbn.getUserId()));
        record.addAdjustment(new Adjustment(mPkg, record.getKey(), signals, null, sbn.getUserId()));

        record.applyAdjustments();

@@ -1133,6 +1136,15 @@ public class NotificationRecordTest extends UiServiceTestCase {
        assertTrue(record.isConversation());
    }

    @Test
    public void testIsConversation_noShortcut_targetsR() {
        StatusBarNotification sbn = getMessagingStyleNotification(PKG_R);
        NotificationRecord record = new NotificationRecord(mMockContext, sbn, channel);
        record.setShortcutInfo(null);

        assertFalse(record.isConversation());
    }

    @Test
    public void testIsConversation_channelDemoted() {
        StatusBarNotification sbn = getMessagingStyleNotification();