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

Commit a0af6cf7 authored by Anna Zappone's avatar Anna Zappone
Browse files

Add nonpriority conversations into sorted Recents

Retrieve nonpriority conversations, and delay sorting until we've merged
with Recent conversations. This ensures Priority is sorted at the top,
and then all conversations afterwards are sorted.

Test: PeopleSpaceUtilsTest
Change-Id: I9ff7f16a530b81a36a591989bb24171ac72a78b1
parent b078a298
Loading
Loading
Loading
Loading
+33 −19
Original line number Diff line number Diff line
@@ -23,12 +23,12 @@ import android.app.Notification;
import android.app.PendingIntent;
import android.app.people.ConversationChannel;
import android.app.people.IPeopleManager;
import android.appwidget.AppWidgetHost;
import android.appwidget.AppWidgetManager;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.LauncherApps;
import android.content.pm.ShortcutInfo;
import android.database.Cursor;
import android.database.SQLException;
import android.graphics.Bitmap;
@@ -72,6 +72,7 @@ import java.util.HashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -129,25 +130,36 @@ public class PeopleSpaceUtils {
            throws Exception {
        boolean showOnlyPriority = Settings.Global.getInt(context.getContentResolver(),
                Settings.Global.PEOPLE_SPACE_CONVERSATION_TYPE, 0) == 1;
        List<ConversationChannelWrapper> conversations = notificationManager.getConversations(
                true).getList();
        List<PeopleSpaceTile> tiles = getSortedTiles(peopleManager,
                conversations.stream().filter(c -> c.getShortcutInfo() != null).map(
                        c -> new PeopleSpaceTile.Builder(c.getShortcutInfo(),
                                launcherApps).build()));
        List<ConversationChannelWrapper> conversations =
                notificationManager.getConversations(
                        false).getList();

        // Add priority conversations to tiles list.
        Stream<ShortcutInfo> priorityConversations = conversations.stream()
                .filter(c -> c.getNotificationChannel() != null
                        && c.getNotificationChannel().isImportantConversation())
                .map(c -> c.getShortcutInfo());
        List<PeopleSpaceTile> tiles = getSortedTiles(peopleManager, launcherApps,
                priorityConversations);

        // Sort and then add recent and non priority conversations to tiles list.
        if (!showOnlyPriority) {
            if (DEBUG) Log.d(TAG, "Add recent conversations");
            List<ConversationChannel> recentConversations =
            Stream<ShortcutInfo> nonPriorityConversations = conversations.stream()
                    .filter(c -> c.getNotificationChannel() == null
                            || !c.getNotificationChannel().isImportantConversation())
                    .map(c -> c.getShortcutInfo());

            List<ConversationChannel> recentConversationsList =
                    peopleManager.getRecentConversations().getList();
            List<PeopleSpaceTile> recentTiles =
                    getSortedTiles(peopleManager,
                            recentConversations
            Stream<ShortcutInfo> recentConversations = recentConversationsList
                    .stream()
                                    .filter(
                                            c -> c.getShortcutInfo() != null)
                                    .map(
                                            c -> new PeopleSpaceTile.Builder(c.getShortcutInfo(),
                                                    launcherApps).build()));
                    .map(c -> c.getShortcutInfo());

            Stream<ShortcutInfo> mergedStream = Stream.concat(nonPriorityConversations,
                    recentConversations);
            List<PeopleSpaceTile> recentTiles =
                    getSortedTiles(peopleManager, launcherApps, mergedStream);
            tiles.addAll(recentTiles);
        }
        return tiles;
@@ -417,8 +429,11 @@ public class PeopleSpaceUtils {

    /** Returns a list sorted by ascending last interaction time from {@code stream}. */
    private static List<PeopleSpaceTile> getSortedTiles(IPeopleManager peopleManager,
            Stream<PeopleSpaceTile> stream) {
            LauncherApps launcherApps,
            Stream<ShortcutInfo> stream) {
        return stream
                .filter(Objects::nonNull)
                .map(c -> new PeopleSpaceTile.Builder(c, launcherApps).build())
                .filter(c -> shouldKeepConversation(c))
                .map(c -> c.toBuilder().setLastInteractionTimestamp(
                        getLastInteraction(peopleManager, c)).build())
@@ -654,4 +669,3 @@ public class PeopleSpaceUtils {
        return lookupKeysWithBirthdaysToday;
    }
}
 No newline at end of file
+124 −1
Original line number Diff line number Diff line
@@ -21,6 +21,8 @@ import static com.android.systemui.people.PeopleSpaceUtils.OPTIONS_PEOPLE_SPACE_
import static com.google.common.truth.Truth.assertThat;

import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.anyInt;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.eq;
import static org.mockito.ArgumentMatchers.isNull;
@@ -30,13 +32,19 @@ import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;

import android.app.INotificationManager;
import android.app.Notification;
import android.app.NotificationChannel;
import android.app.NotificationManager;
import android.app.Person;
import android.app.people.ConversationChannel;
import android.app.people.IPeopleManager;
import android.appwidget.AppWidgetManager;
import android.content.ContentResolver;
import android.content.Context;
import android.content.Intent;
import android.content.pm.LauncherApps;
import android.content.pm.ParceledListSlice;
import android.content.pm.ShortcutInfo;
import android.database.Cursor;
import android.graphics.drawable.Icon;
@@ -45,6 +53,7 @@ import android.os.Bundle;
import android.os.RemoteException;
import android.provider.ContactsContract;
import android.provider.Settings;
import android.service.notification.ConversationChannelWrapper;
import android.service.notification.StatusBarNotification;
import android.testing.AndroidTestingRunner;

@@ -62,7 +71,10 @@ import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;

import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@SmallTest
@RunWith(AndroidTestingRunner.class)
@@ -103,6 +115,12 @@ public class PeopleSpaceUtilsTest extends SysuiTestCase {
    @Mock
    private NotificationListener mListenerService;
    @Mock
    private INotificationManager mNotificationManager;
    @Mock
    private IPeopleManager mPeopleManager;
    @Mock
    private LauncherApps mLauncherApps;
    @Mock
    private IAppWidgetService mIAppWidgetService;
    @Mock
    private AppWidgetManager mAppWidgetManager;
@@ -136,6 +154,85 @@ public class PeopleSpaceUtilsTest extends SysuiTestCase {
                mContext.getString(R.string.birthday_status));
    }

    @Test
    public void testGetTilesReturnsSortedListWithMultipleRecentConversations() throws Exception {
        // Ensure the less-recent Important conversation is before more recent conversations.
        ConversationChannelWrapper newerNonImportantConversation = getConversationChannelWrapper(
                SHORTCUT_ID, false, 3);
        ConversationChannelWrapper olderImportantConversation = getConversationChannelWrapper(
                SHORTCUT_ID + 1,
                true, 1);
        when(mNotificationManager.getConversations(anyBoolean())).thenReturn(
                new ParceledListSlice(Arrays.asList(
                        newerNonImportantConversation, olderImportantConversation)));

        // Ensure the non-Important conversation is sorted between these recent conversations.
        ConversationChannel recentConversationBeforeNonImportantConversation =
                getConversationChannel(
                        SHORTCUT_ID + 2, 4);
        ConversationChannel recentConversationAfterNonImportantConversation =
                getConversationChannel(SHORTCUT_ID + 3,
                        2);
        when(mPeopleManager.getRecentConversations()).thenReturn(
                new ParceledListSlice(Arrays.asList(recentConversationAfterNonImportantConversation,
                        recentConversationBeforeNonImportantConversation)));

        List<String> orderedShortcutIds = PeopleSpaceUtils.getTiles(
                mContext, mNotificationManager, mPeopleManager,
                mLauncherApps).stream().map(tile -> tile.getId()).collect(Collectors.toList());

        assertThat(orderedShortcutIds).containsExactly(
                // Even though the oldest conversation, should be first since "important"
                olderImportantConversation.getShortcutInfo().getId(),
                // Non-priority conversations should be sorted within recent conversations.
                recentConversationBeforeNonImportantConversation.getShortcutInfo().getId(),
                newerNonImportantConversation.getShortcutInfo().getId(),
                recentConversationAfterNonImportantConversation.getShortcutInfo().getId())
                .inOrder();
    }

    @Test
    public void testGetTilesReturnsSortedListWithMultipleImportantAndRecentConversations()
            throws Exception {
        // Ensure the less-recent Important conversation is before more recent conversations.
        ConversationChannelWrapper newerNonImportantConversation = getConversationChannelWrapper(
                SHORTCUT_ID, false, 3);
        ConversationChannelWrapper newerImportantConversation = getConversationChannelWrapper(
                SHORTCUT_ID + 1, true, 3);
        ConversationChannelWrapper olderImportantConversation = getConversationChannelWrapper(
                SHORTCUT_ID + 2,
                true, 1);
        when(mNotificationManager.getConversations(anyBoolean())).thenReturn(
                new ParceledListSlice(Arrays.asList(
                        newerNonImportantConversation, newerImportantConversation,
                        olderImportantConversation)));

        // Ensure the non-Important conversation is sorted between these recent conversations.
        ConversationChannel recentConversationBeforeNonImportantConversation =
                getConversationChannel(
                        SHORTCUT_ID + 3, 4);
        ConversationChannel recentConversationAfterNonImportantConversation =
                getConversationChannel(SHORTCUT_ID + 4,
                        2);
        when(mPeopleManager.getRecentConversations()).thenReturn(
                new ParceledListSlice(Arrays.asList(recentConversationAfterNonImportantConversation,
                        recentConversationBeforeNonImportantConversation)));

        List<String> orderedShortcutIds = PeopleSpaceUtils.getTiles(
                mContext, mNotificationManager, mPeopleManager,
                mLauncherApps).stream().map(tile -> tile.getId()).collect(Collectors.toList());

        assertThat(orderedShortcutIds).containsExactly(
                // Important conversations should be sorted at the beginning.
                newerImportantConversation.getShortcutInfo().getId(),
                olderImportantConversation.getShortcutInfo().getId(),
                // Non-priority conversations should be sorted within recent conversations.
                recentConversationBeforeNonImportantConversation.getShortcutInfo().getId(),
                newerNonImportantConversation.getShortcutInfo().getId(),
                recentConversationAfterNonImportantConversation.getShortcutInfo().getId())
                .inOrder();
    }

    @Test
    public void testGetLastMessagingStyleMessageNoMessage() {
        Notification notification = new Notification.Builder(mContext, "test")
@@ -385,4 +482,30 @@ public class PeopleSpaceUtilsTest extends SysuiTestCase {
        verify(mAppWidgetManager, times(1)).updateAppWidget(eq(WIDGET_ID_WITH_SHORTCUT),
                any());
    }

    private ConversationChannelWrapper getConversationChannelWrapper(String shortcutId,
            boolean importantConversation, long lastInteractionTimestamp) throws Exception {
        ConversationChannelWrapper convo = new ConversationChannelWrapper();
        NotificationChannel notificationChannel = new NotificationChannel(shortcutId,
                "channel" + shortcutId,
                NotificationManager.IMPORTANCE_DEFAULT);
        notificationChannel.setImportantConversation(importantConversation);
        convo.setNotificationChannel(notificationChannel);
        convo.setShortcutInfo(new ShortcutInfo.Builder(mContext, shortcutId).setLongLabel(
                "name").build());
        when(mPeopleManager.getLastInteraction(anyString(), anyInt(),
                eq(shortcutId))).thenReturn(lastInteractionTimestamp);
        return convo;
    }

    private ConversationChannel getConversationChannel(String shortcutId,
            long lastInteractionTimestamp) throws Exception {
        ShortcutInfo shortcutInfo = new ShortcutInfo.Builder(mContext, shortcutId).setLongLabel(
                "name").build();
        ConversationChannel convo = new ConversationChannel(shortcutInfo, 0, null, null,
                lastInteractionTimestamp, false);
        when(mPeopleManager.getLastInteraction(anyString(), anyInt(),
                eq(shortcutId))).thenReturn(lastInteractionTimestamp);
        return convo;
    }
}
 No newline at end of file
+7 −7
Original line number Diff line number Diff line
@@ -207,7 +207,7 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
            throws RemoteException {
        Settings.Global.putInt(mContext.getContentResolver(),
                Settings.Global.PEOPLE_SPACE_CONVERSATION_TYPE, 0);
        when(mINotificationManager.getConversations(true)).thenReturn(
        when(mINotificationManager.getConversations(false)).thenReturn(
                new ParceledListSlice(getConversationWithShortcutId()));
        int[] widgetIdsArray = {WIDGET_ID_WITH_SHORTCUT, WIDGET_ID_WITHOUT_SHORTCUT};
        when(mIAppWidgetService.getAppWidgetIds(any())).thenReturn(widgetIdsArray);
@@ -229,7 +229,7 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
            throws RemoteException {
        Settings.Global.putInt(mContext.getContentResolver(),
                Settings.Global.PEOPLE_SPACE_CONVERSATION_TYPE, 0);
        when(mINotificationManager.getConversations(true)).thenReturn(
        when(mINotificationManager.getConversations(false)).thenReturn(
                new ParceledListSlice(getConversationWithShortcutId()));
        int[] widgetIdsArray = {WIDGET_ID_WITH_SHORTCUT, WIDGET_ID_WITHOUT_SHORTCUT};
        when(mIAppWidgetService.getAppWidgetIds(any())).thenReturn(widgetIdsArray);
@@ -326,7 +326,7 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
    public void testDoNotUpdateNotificationPostedIfNoExistingTile() throws RemoteException {
        Settings.Global.putInt(mContext.getContentResolver(),
                Settings.Global.PEOPLE_SPACE_CONVERSATION_TYPE, 0);
        when(mINotificationManager.getConversations(true)).thenReturn(
        when(mINotificationManager.getConversations(false)).thenReturn(
                new ParceledListSlice(getConversationWithShortcutId()));
        int[] widgetIdsArray = {WIDGET_ID_WITH_SHORTCUT, WIDGET_ID_WITHOUT_SHORTCUT};
        when(mIAppWidgetService.getAppWidgetIds(any())).thenReturn(widgetIdsArray);
@@ -346,7 +346,7 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
    public void testDoNotUpdateNotificationRemovedIfNoExistingTile() throws RemoteException {
        Settings.Global.putInt(mContext.getContentResolver(),
                Settings.Global.PEOPLE_SPACE_CONVERSATION_TYPE, 0);
        when(mINotificationManager.getConversations(true)).thenReturn(
        when(mINotificationManager.getConversations(false)).thenReturn(
                new ParceledListSlice(getConversationWithShortcutId()));
        int[] widgetIdsArray = {WIDGET_ID_WITH_SHORTCUT, WIDGET_ID_WITHOUT_SHORTCUT};
        when(mIAppWidgetService.getAppWidgetIds(any())).thenReturn(widgetIdsArray);
@@ -368,7 +368,7 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
    public void testUpdateNotificationPostedIfExistingTile() throws RemoteException {
        Settings.Global.putInt(mContext.getContentResolver(),
                Settings.Global.PEOPLE_SPACE_CONVERSATION_TYPE, 0);
        when(mINotificationManager.getConversations(true)).thenReturn(
        when(mINotificationManager.getConversations(false)).thenReturn(
                new ParceledListSlice(getConversationWithShortcutId()));
        int[] widgetIdsArray = {WIDGET_ID_WITH_SHORTCUT, WIDGET_ID_WITHOUT_SHORTCUT};
        when(mIAppWidgetService.getAppWidgetIds(any())).thenReturn(widgetIdsArray);
@@ -389,7 +389,7 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
            throws RemoteException {
        Settings.Global.putInt(mContext.getContentResolver(),
                Settings.Global.PEOPLE_SPACE_CONVERSATION_TYPE, 0);
        when(mINotificationManager.getConversations(true)).thenReturn(
        when(mINotificationManager.getConversations(false)).thenReturn(
                new ParceledListSlice(getConversationWithShortcutId()));
        int[] widgetIdsArray = {WIDGET_ID_WITH_SHORTCUT, WIDGET_ID_WITHOUT_SHORTCUT};
        when(mIAppWidgetService.getAppWidgetIds(any())).thenReturn(widgetIdsArray);
@@ -416,7 +416,7 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
    public void testUpdateNotificationRemovedIfExistingTile() throws RemoteException {
        Settings.Global.putInt(mContext.getContentResolver(),
                Settings.Global.PEOPLE_SPACE_CONVERSATION_TYPE, 0);
        when(mINotificationManager.getConversations(true)).thenReturn(
        when(mINotificationManager.getConversations(false)).thenReturn(
                new ParceledListSlice(getConversationWithShortcutId()));
        int[] widgetIdsArray = {WIDGET_ID_WITH_SHORTCUT, WIDGET_ID_WITHOUT_SHORTCUT};
        when(mIAppWidgetService.getAppWidgetIds(any())).thenReturn(widgetIdsArray);