Loading packages/SystemUI/src/com/android/systemui/people/PeopleSpaceActivity.java +3 −21 Original line number Diff line number Diff line Loading @@ -23,18 +23,14 @@ import static com.android.systemui.people.PeopleTileViewHelper.getPersonIconBitm import static com.android.systemui.people.PeopleTileViewHelper.getSizeInDp; import android.app.Activity; import android.app.INotificationManager; import android.app.people.IPeopleManager; import android.app.people.PeopleSpaceTile; import android.content.Context; import android.content.Intent; import android.content.pm.LauncherApps; import android.content.res.TypedArray; import android.graphics.Color; import android.graphics.Outline; import android.graphics.drawable.GradientDrawable; import android.os.Bundle; import android.os.ServiceManager; import android.util.Log; import android.view.View; import android.view.ViewGroup; Loading @@ -43,7 +39,6 @@ import android.widget.LinearLayout; import com.android.systemui.R; import com.android.systemui.people.widget.PeopleSpaceWidgetManager; import com.android.systemui.statusbar.notification.NotificationEntryManager; import java.util.ArrayList; import java.util.List; Loading @@ -56,19 +51,13 @@ public class PeopleSpaceActivity extends Activity { private static final String TAG = "PeopleSpaceActivity"; private static final boolean DEBUG = PeopleSpaceUtils.DEBUG; private IPeopleManager mPeopleManager; private PeopleSpaceWidgetManager mPeopleSpaceWidgetManager; private INotificationManager mNotificationManager; private LauncherApps mLauncherApps; private Context mContext; private NotificationEntryManager mNotificationEntryManager; private int mAppWidgetId; @Inject public PeopleSpaceActivity(NotificationEntryManager notificationEntryManager, PeopleSpaceWidgetManager peopleSpaceWidgetManager) { public PeopleSpaceActivity(PeopleSpaceWidgetManager peopleSpaceWidgetManager) { super(); mNotificationEntryManager = notificationEntryManager; mPeopleSpaceWidgetManager = peopleSpaceWidgetManager; } Loading @@ -77,11 +66,6 @@ public class PeopleSpaceActivity extends Activity { protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mContext = getApplicationContext(); mNotificationManager = INotificationManager.Stub.asInterface( ServiceManager.getService(Context.NOTIFICATION_SERVICE)); mPeopleManager = IPeopleManager.Stub.asInterface( ServiceManager.getService(Context.PEOPLE_SERVICE)); mLauncherApps = mContext.getSystemService(LauncherApps.class); mAppWidgetId = getIntent().getIntExtra(EXTRA_APPWIDGET_ID, INVALID_APPWIDGET_ID); setResult(RESULT_CANCELED); Loading @@ -92,10 +76,8 @@ public class PeopleSpaceActivity extends Activity { List<PeopleSpaceTile> priorityTiles = new ArrayList<>(); List<PeopleSpaceTile> recentTiles = new ArrayList<>(); try { priorityTiles = PeopleSpaceUtils.getPriorityTiles(mContext, mNotificationManager, mPeopleManager, mLauncherApps, mNotificationEntryManager); recentTiles = PeopleSpaceUtils.getRecentTiles(mContext, mNotificationManager, mPeopleManager, mLauncherApps, mNotificationEntryManager); priorityTiles = mPeopleSpaceWidgetManager.getPriorityTiles(); recentTiles = mPeopleSpaceWidgetManager.getRecentTiles(); } catch (Exception e) { Log.e(TAG, "Couldn't retrieve conversations", e); } Loading packages/SystemUI/src/com/android/systemui/people/PeopleSpaceUtils.java +6 −58 Original line number Diff line number Diff line Loading @@ -19,8 +19,6 @@ package com.android.systemui.people; import static android.app.Notification.CATEGORY_MISSED_CALL; import static android.app.Notification.EXTRA_MESSAGES; import android.annotation.NonNull; import android.app.INotificationManager; import android.app.Notification; import android.app.people.ConversationChannel; import android.app.people.IPeopleManager; Loading @@ -41,8 +39,8 @@ import android.os.Bundle; import android.os.Parcelable; import android.os.ServiceManager; import android.os.UserHandle; import android.os.UserManager; import android.provider.ContactsContract; import android.service.notification.ConversationChannelWrapper; import android.service.notification.StatusBarNotification; import android.text.TextUtils; import android.util.Log; Loading Loading @@ -119,58 +117,6 @@ public class PeopleSpaceUtils { } } /** Returns a list of map entries corresponding to user's priority conversations. */ @NonNull public static List<PeopleSpaceTile> getPriorityTiles( Context context, INotificationManager notificationManager, IPeopleManager peopleManager, LauncherApps launcherApps, NotificationEntryManager notificationEntryManager) throws Exception { 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> priorityTiles = getSortedTiles(peopleManager, launcherApps, priorityConversations); priorityTiles = augmentTilesFromVisibleNotifications( context, priorityTiles, notificationEntryManager); return priorityTiles; } /** Returns a list of map entries corresponding to user's recent conversations. */ @NonNull public static List<PeopleSpaceTile> getRecentTiles( Context context, INotificationManager notificationManager, IPeopleManager peopleManager, LauncherApps launcherApps, NotificationEntryManager notificationEntryManager) throws Exception { if (DEBUG) Log.d(TAG, "Add recent conversations"); List<ConversationChannelWrapper> conversations = notificationManager.getConversations( false).getList(); Stream<ShortcutInfo> nonPriorityConversations = conversations.stream() .filter(c -> c.getNotificationChannel() == null || !c.getNotificationChannel().isImportantConversation()) .map(c -> c.getShortcutInfo()); List<ConversationChannel> recentConversationsList = peopleManager.getRecentConversations().getList(); Stream<ShortcutInfo> recentConversations = recentConversationsList .stream() .map(c -> c.getShortcutInfo()); Stream<ShortcutInfo> mergedStream = Stream.concat(nonPriorityConversations, recentConversations); List<PeopleSpaceTile> recentTiles = getSortedTiles(peopleManager, launcherApps, mergedStream); recentTiles = augmentTilesFromVisibleNotifications( context, recentTiles, notificationEntryManager); return recentTiles; } /** Returns stored widgets for the conversation specified. */ public static Set<String> getStoredWidgetIds(SharedPreferences sp, PeopleTileKey key) { if (!key.isValid()) { Loading Loading @@ -247,7 +193,8 @@ public class PeopleSpaceUtils { return augmentedTile.get(0); } static List<PeopleSpaceTile> augmentTilesFromVisibleNotifications(Context context, /** Adds to {@code tiles} any visible notifications. */ public static List<PeopleSpaceTile> augmentTilesFromVisibleNotifications(Context context, List<PeopleSpaceTile> tiles, NotificationEntryManager notificationEntryManager) { if (notificationEntryManager == null) { Log.w(TAG, "NotificationEntryManager is null"); Loading Loading @@ -348,11 +295,12 @@ public class PeopleSpaceUtils { } /** Returns a list sorted by ascending last interaction time from {@code stream}. */ private static List<PeopleSpaceTile> getSortedTiles(IPeopleManager peopleManager, LauncherApps launcherApps, public static List<PeopleSpaceTile> getSortedTiles(IPeopleManager peopleManager, LauncherApps launcherApps, UserManager userManager, Stream<ShortcutInfo> stream) { return stream .filter(Objects::nonNull) .filter(c -> !userManager.isQuietModeEnabled(c.getUserHandle())) .map(c -> new PeopleSpaceTile.Builder(c, launcherApps).build()) .filter(c -> shouldKeepConversation(c)) .map(c -> c.toBuilder().setLastInteractionTimestamp( Loading packages/SystemUI/src/com/android/systemui/people/widget/LaunchConversationActivity.java +17 −1 Original line number Diff line number Diff line Loading @@ -23,11 +23,13 @@ import android.content.pm.LauncherApps; import android.os.Bundle; import android.os.ServiceManager; import android.os.UserHandle; import android.os.UserManager; import android.service.notification.NotificationStats; import android.text.TextUtils; import android.util.Log; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.app.UnlaunchableAppActivity; import com.android.internal.logging.UiEventLogger; import com.android.internal.logging.UiEventLoggerImpl; import com.android.internal.statusbar.IStatusBarService; Loading @@ -48,15 +50,17 @@ public class LaunchConversationActivity extends Activity { private UiEventLogger mUiEventLogger = new UiEventLoggerImpl(); private NotificationEntryManager mNotificationEntryManager; private final Optional<BubblesManager> mBubblesManagerOptional; private final UserManager mUserManager; private boolean mIsForTesting; private IStatusBarService mIStatusBarService; @Inject public LaunchConversationActivity(NotificationEntryManager notificationEntryManager, Optional<BubblesManager> bubblesManagerOptional) { Optional<BubblesManager> bubblesManagerOptional, UserManager userManager) { super(); mNotificationEntryManager = notificationEntryManager; mBubblesManagerOptional = bubblesManagerOptional; mUserManager = userManager; } @Override Loading @@ -80,12 +84,24 @@ public class LaunchConversationActivity extends Activity { } mUiEventLogger.log(PeopleSpaceUtils.PeopleSpaceWidgetEvent.PEOPLE_SPACE_WIDGET_CLICKED); try { if (mUserManager.isQuietModeEnabled(userHandle)) { if (DEBUG) Log.d(TAG, "Cannot launch app when quieted"); final Intent dialogIntent = UnlaunchableAppActivity.createInQuietModeDialogIntent( userHandle.getIdentifier()); this.getApplicationContext().startActivity(dialogIntent); finish(); return; } NotificationEntry entry = mNotificationEntryManager.getPendingOrActiveNotif( notificationKey); if (entry != null && entry.canBubble() && mBubblesManagerOptional.isPresent()) { if (DEBUG) Log.d(TAG, "Open bubble for conversation"); mBubblesManagerOptional.get().expandStackAndSelectBubble(entry); // Just opt-out and don't cancel the notification for bubbles. finish(); return; } Loading packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetManager.java +63 −2 Original line number Diff line number Diff line Loading @@ -31,7 +31,9 @@ import static com.android.systemui.people.PeopleSpaceUtils.getStoredWidgetIds; import static com.android.systemui.people.PeopleSpaceUtils.updateAppWidgetOptionsAndView; import static com.android.systemui.people.PeopleSpaceUtils.updateAppWidgetViews; import android.annotation.NonNull; import android.annotation.Nullable; import android.app.INotificationManager; import android.app.Notification; import android.app.NotificationChannel; import android.app.PendingIntent; Loading @@ -51,7 +53,9 @@ import android.net.Uri; import android.os.Bundle; import android.os.ServiceManager; import android.os.UserHandle; import android.os.UserManager; import android.preference.PreferenceManager; import android.service.notification.ConversationChannelWrapper; import android.service.notification.NotificationListenerService; import android.service.notification.StatusBarNotification; import android.util.Log; Loading @@ -76,6 +80,7 @@ import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Set; import java.util.stream.Stream; import javax.inject.Inject; import javax.inject.Singleton; Loading @@ -96,6 +101,8 @@ public class PeopleSpaceWidgetManager { private NotificationEntryManager mNotificationEntryManager; private PackageManager mPackageManager; private PeopleSpaceWidgetProvider mPeopleSpaceWidgetProvider; private INotificationManager mINotificationManager; private UserManager mUserManager; public UiEventLogger mUiEventLogger = new UiEventLoggerImpl(); @GuardedBy("mLock") public static Map<PeopleTileKey, PeopleSpaceWidgetProvider.TileConversationListener> Loading @@ -121,17 +128,21 @@ public class PeopleSpaceWidgetManager { mNotificationEntryManager = Dependency.get(NotificationEntryManager.class); mPackageManager = mContext.getPackageManager(); mPeopleSpaceWidgetProvider = new PeopleSpaceWidgetProvider(); mINotificationManager = INotificationManager.Stub.asInterface( ServiceManager.getService(Context.NOTIFICATION_SERVICE)); mUserManager = context.getSystemService(UserManager.class); } /** * AppWidgetManager setter used for testing. */ @VisibleForTesting protected void setAppWidgetManager( public void setAppWidgetManager( AppWidgetManager appWidgetManager, IPeopleManager iPeopleManager, PeopleManager peopleManager, LauncherApps launcherApps, NotificationEntryManager notificationEntryManager, PackageManager packageManager, boolean isForTesting, PeopleSpaceWidgetProvider peopleSpaceWidgetProvider) { boolean isForTesting, PeopleSpaceWidgetProvider peopleSpaceWidgetProvider, UserManager userManager, INotificationManager notificationManager) { mAppWidgetManager = appWidgetManager; mIPeopleManager = iPeopleManager; mPeopleManager = peopleManager; Loading @@ -140,6 +151,8 @@ public class PeopleSpaceWidgetManager { mPackageManager = packageManager; mIsForTesting = isForTesting; mPeopleSpaceWidgetProvider = peopleSpaceWidgetProvider; mUserManager = userManager; mINotificationManager = notificationManager; } /** Loading Loading @@ -783,4 +796,52 @@ public class PeopleSpaceWidgetManager { ComponentName componentName = new ComponentName(mContext, PeopleSpaceWidgetProvider.class); return mAppWidgetManager.requestPinAppWidget(componentName, extras, successCallback); } /** Returns a list of map entries corresponding to user's priority conversations. */ @NonNull public List<PeopleSpaceTile> getPriorityTiles() throws Exception { List<ConversationChannelWrapper> conversations = mINotificationManager.getConversations(true).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> priorityTiles = PeopleSpaceUtils.getSortedTiles(mIPeopleManager, mLauncherApps, mUserManager, priorityConversations); priorityTiles = PeopleSpaceUtils.augmentTilesFromVisibleNotifications( mContext, priorityTiles, mNotificationEntryManager); return priorityTiles; } /** Returns a list of map entries corresponding to user's recent conversations. */ @NonNull public List<PeopleSpaceTile> getRecentTiles() throws Exception { if (DEBUG) Log.d(TAG, "Add recent conversations"); List<ConversationChannelWrapper> conversations = mINotificationManager.getConversations(false).getList(); Stream<ShortcutInfo> nonPriorityConversations = conversations.stream() .filter(c -> c.getNotificationChannel() == null || !c.getNotificationChannel().isImportantConversation()) .map(c -> c.getShortcutInfo()); List<ConversationChannel> recentConversationsList = mIPeopleManager.getRecentConversations().getList(); Stream<ShortcutInfo> recentConversations = recentConversationsList .stream() .map(c -> c.getShortcutInfo()); Stream<ShortcutInfo> mergedStream = Stream.concat(nonPriorityConversations, recentConversations); List<PeopleSpaceTile> recentTiles = PeopleSpaceUtils.getSortedTiles(mIPeopleManager, mLauncherApps, mUserManager, mergedStream); recentTiles = PeopleSpaceUtils.augmentTilesFromVisibleNotifications( mContext, recentTiles, mNotificationEntryManager); return recentTiles; } } packages/SystemUI/tests/src/com/android/systemui/people/PeopleSpaceUtilsTest.java +0 −115 Original line number Diff line number Diff line Loading @@ -22,8 +22,6 @@ import static com.android.systemui.people.widget.AppWidgetOptionsHelper.OPTIONS_ 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; Loading @@ -35,10 +33,7 @@ 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.app.people.PeopleSpaceTile; import android.appwidget.AppWidgetManager; Loading @@ -47,7 +42,6 @@ import android.content.Context; import android.content.Intent; import android.content.pm.LauncherApps; import android.content.pm.PackageManager; import android.content.pm.ParceledListSlice; import android.content.pm.ShortcutInfo; import android.content.res.Configuration; import android.content.res.Resources; Loading @@ -57,7 +51,6 @@ import android.net.Uri; import android.os.Bundle; import android.os.UserHandle; import android.provider.ContactsContract; import android.service.notification.ConversationChannelWrapper; import android.service.notification.StatusBarNotification; import android.testing.AndroidTestingRunner; import android.util.DisplayMetrics; Loading @@ -81,10 +74,8 @@ 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; @RunWith(AndroidTestingRunner.class) @SmallTest Loading Loading @@ -185,8 +176,6 @@ public class PeopleSpaceUtilsTest extends SysuiTestCase { @Mock private IPeopleManager mPeopleManager; @Mock private LauncherApps mLauncherApps; @Mock private IAppWidgetService mIAppWidgetService; @Mock private AppWidgetManager mAppWidgetManager; Loading Loading @@ -238,84 +227,6 @@ public class PeopleSpaceUtilsTest extends SysuiTestCase { .thenReturn(List.of(mNotificationEntry1, mNotificationEntry2, mNotificationEntry3)); } @Test public void testGetRecentTilesReturnsSortedListWithOnlyRecentConversations() throws Exception { // Ensure the less-recent Important conversation is before more recent conversations. ConversationChannelWrapper newerNonImportantConversation = getConversationChannelWrapper( SHORTCUT_ID_1, false, 3); ConversationChannelWrapper newerImportantConversation = getConversationChannelWrapper( SHORTCUT_ID_1 + 1, true, 3); ConversationChannelWrapper olderImportantConversation = getConversationChannelWrapper( SHORTCUT_ID_1 + 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_1 + 3, 4); ConversationChannel recentConversationAfterNonImportantConversation = getConversationChannel(SHORTCUT_ID_1 + 4, 2); when(mPeopleManager.getRecentConversations()).thenReturn( new ParceledListSlice(Arrays.asList(recentConversationAfterNonImportantConversation, recentConversationBeforeNonImportantConversation))); List<String> orderedShortcutIds = PeopleSpaceUtils.getRecentTiles( mContext, mNotificationManager, mPeopleManager, mLauncherApps, mNotificationEntryManager) .stream().map(tile -> tile.getId()).collect(Collectors.toList()); // Check for sorted recent conversations. assertThat(orderedShortcutIds).containsExactly( recentConversationBeforeNonImportantConversation.getShortcutInfo().getId(), newerNonImportantConversation.getShortcutInfo().getId(), recentConversationAfterNonImportantConversation.getShortcutInfo().getId()) .inOrder(); } @Test public void testGetPriorityTilesReturnsSortedListWithOnlyImportantConversations() throws Exception { // Ensure the less-recent Important conversation is before more recent conversations. ConversationChannelWrapper newerNonImportantConversation = getConversationChannelWrapper( SHORTCUT_ID_1, false, 3); ConversationChannelWrapper newerImportantConversation = getConversationChannelWrapper( SHORTCUT_ID_1 + 1, true, 3); ConversationChannelWrapper olderImportantConversation = getConversationChannelWrapper( SHORTCUT_ID_1 + 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_1 + 3, 4); ConversationChannel recentConversationAfterNonImportantConversation = getConversationChannel(SHORTCUT_ID_1 + 4, 2); when(mPeopleManager.getRecentConversations()).thenReturn( new ParceledListSlice(Arrays.asList(recentConversationAfterNonImportantConversation, recentConversationBeforeNonImportantConversation))); List<String> orderedShortcutIds = PeopleSpaceUtils.getPriorityTiles( mContext, mNotificationManager, mPeopleManager, mLauncherApps, mNotificationEntryManager) .stream().map(tile -> tile.getId()).collect(Collectors.toList()); // Check for sorted priority conversations. assertThat(orderedShortcutIds).containsExactly( newerImportantConversation.getShortcutInfo().getId(), olderImportantConversation.getShortcutInfo().getId()) .inOrder(); } @Test public void testGetMessagingStyleMessagesNoMessage() { Notification notification = new Notification.Builder(mContext, "test") Loading Loading @@ -570,30 +481,4 @@ 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; } } Loading
packages/SystemUI/src/com/android/systemui/people/PeopleSpaceActivity.java +3 −21 Original line number Diff line number Diff line Loading @@ -23,18 +23,14 @@ import static com.android.systemui.people.PeopleTileViewHelper.getPersonIconBitm import static com.android.systemui.people.PeopleTileViewHelper.getSizeInDp; import android.app.Activity; import android.app.INotificationManager; import android.app.people.IPeopleManager; import android.app.people.PeopleSpaceTile; import android.content.Context; import android.content.Intent; import android.content.pm.LauncherApps; import android.content.res.TypedArray; import android.graphics.Color; import android.graphics.Outline; import android.graphics.drawable.GradientDrawable; import android.os.Bundle; import android.os.ServiceManager; import android.util.Log; import android.view.View; import android.view.ViewGroup; Loading @@ -43,7 +39,6 @@ import android.widget.LinearLayout; import com.android.systemui.R; import com.android.systemui.people.widget.PeopleSpaceWidgetManager; import com.android.systemui.statusbar.notification.NotificationEntryManager; import java.util.ArrayList; import java.util.List; Loading @@ -56,19 +51,13 @@ public class PeopleSpaceActivity extends Activity { private static final String TAG = "PeopleSpaceActivity"; private static final boolean DEBUG = PeopleSpaceUtils.DEBUG; private IPeopleManager mPeopleManager; private PeopleSpaceWidgetManager mPeopleSpaceWidgetManager; private INotificationManager mNotificationManager; private LauncherApps mLauncherApps; private Context mContext; private NotificationEntryManager mNotificationEntryManager; private int mAppWidgetId; @Inject public PeopleSpaceActivity(NotificationEntryManager notificationEntryManager, PeopleSpaceWidgetManager peopleSpaceWidgetManager) { public PeopleSpaceActivity(PeopleSpaceWidgetManager peopleSpaceWidgetManager) { super(); mNotificationEntryManager = notificationEntryManager; mPeopleSpaceWidgetManager = peopleSpaceWidgetManager; } Loading @@ -77,11 +66,6 @@ public class PeopleSpaceActivity extends Activity { protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); mContext = getApplicationContext(); mNotificationManager = INotificationManager.Stub.asInterface( ServiceManager.getService(Context.NOTIFICATION_SERVICE)); mPeopleManager = IPeopleManager.Stub.asInterface( ServiceManager.getService(Context.PEOPLE_SERVICE)); mLauncherApps = mContext.getSystemService(LauncherApps.class); mAppWidgetId = getIntent().getIntExtra(EXTRA_APPWIDGET_ID, INVALID_APPWIDGET_ID); setResult(RESULT_CANCELED); Loading @@ -92,10 +76,8 @@ public class PeopleSpaceActivity extends Activity { List<PeopleSpaceTile> priorityTiles = new ArrayList<>(); List<PeopleSpaceTile> recentTiles = new ArrayList<>(); try { priorityTiles = PeopleSpaceUtils.getPriorityTiles(mContext, mNotificationManager, mPeopleManager, mLauncherApps, mNotificationEntryManager); recentTiles = PeopleSpaceUtils.getRecentTiles(mContext, mNotificationManager, mPeopleManager, mLauncherApps, mNotificationEntryManager); priorityTiles = mPeopleSpaceWidgetManager.getPriorityTiles(); recentTiles = mPeopleSpaceWidgetManager.getRecentTiles(); } catch (Exception e) { Log.e(TAG, "Couldn't retrieve conversations", e); } Loading
packages/SystemUI/src/com/android/systemui/people/PeopleSpaceUtils.java +6 −58 Original line number Diff line number Diff line Loading @@ -19,8 +19,6 @@ package com.android.systemui.people; import static android.app.Notification.CATEGORY_MISSED_CALL; import static android.app.Notification.EXTRA_MESSAGES; import android.annotation.NonNull; import android.app.INotificationManager; import android.app.Notification; import android.app.people.ConversationChannel; import android.app.people.IPeopleManager; Loading @@ -41,8 +39,8 @@ import android.os.Bundle; import android.os.Parcelable; import android.os.ServiceManager; import android.os.UserHandle; import android.os.UserManager; import android.provider.ContactsContract; import android.service.notification.ConversationChannelWrapper; import android.service.notification.StatusBarNotification; import android.text.TextUtils; import android.util.Log; Loading Loading @@ -119,58 +117,6 @@ public class PeopleSpaceUtils { } } /** Returns a list of map entries corresponding to user's priority conversations. */ @NonNull public static List<PeopleSpaceTile> getPriorityTiles( Context context, INotificationManager notificationManager, IPeopleManager peopleManager, LauncherApps launcherApps, NotificationEntryManager notificationEntryManager) throws Exception { 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> priorityTiles = getSortedTiles(peopleManager, launcherApps, priorityConversations); priorityTiles = augmentTilesFromVisibleNotifications( context, priorityTiles, notificationEntryManager); return priorityTiles; } /** Returns a list of map entries corresponding to user's recent conversations. */ @NonNull public static List<PeopleSpaceTile> getRecentTiles( Context context, INotificationManager notificationManager, IPeopleManager peopleManager, LauncherApps launcherApps, NotificationEntryManager notificationEntryManager) throws Exception { if (DEBUG) Log.d(TAG, "Add recent conversations"); List<ConversationChannelWrapper> conversations = notificationManager.getConversations( false).getList(); Stream<ShortcutInfo> nonPriorityConversations = conversations.stream() .filter(c -> c.getNotificationChannel() == null || !c.getNotificationChannel().isImportantConversation()) .map(c -> c.getShortcutInfo()); List<ConversationChannel> recentConversationsList = peopleManager.getRecentConversations().getList(); Stream<ShortcutInfo> recentConversations = recentConversationsList .stream() .map(c -> c.getShortcutInfo()); Stream<ShortcutInfo> mergedStream = Stream.concat(nonPriorityConversations, recentConversations); List<PeopleSpaceTile> recentTiles = getSortedTiles(peopleManager, launcherApps, mergedStream); recentTiles = augmentTilesFromVisibleNotifications( context, recentTiles, notificationEntryManager); return recentTiles; } /** Returns stored widgets for the conversation specified. */ public static Set<String> getStoredWidgetIds(SharedPreferences sp, PeopleTileKey key) { if (!key.isValid()) { Loading Loading @@ -247,7 +193,8 @@ public class PeopleSpaceUtils { return augmentedTile.get(0); } static List<PeopleSpaceTile> augmentTilesFromVisibleNotifications(Context context, /** Adds to {@code tiles} any visible notifications. */ public static List<PeopleSpaceTile> augmentTilesFromVisibleNotifications(Context context, List<PeopleSpaceTile> tiles, NotificationEntryManager notificationEntryManager) { if (notificationEntryManager == null) { Log.w(TAG, "NotificationEntryManager is null"); Loading Loading @@ -348,11 +295,12 @@ public class PeopleSpaceUtils { } /** Returns a list sorted by ascending last interaction time from {@code stream}. */ private static List<PeopleSpaceTile> getSortedTiles(IPeopleManager peopleManager, LauncherApps launcherApps, public static List<PeopleSpaceTile> getSortedTiles(IPeopleManager peopleManager, LauncherApps launcherApps, UserManager userManager, Stream<ShortcutInfo> stream) { return stream .filter(Objects::nonNull) .filter(c -> !userManager.isQuietModeEnabled(c.getUserHandle())) .map(c -> new PeopleSpaceTile.Builder(c, launcherApps).build()) .filter(c -> shouldKeepConversation(c)) .map(c -> c.toBuilder().setLastInteractionTimestamp( Loading
packages/SystemUI/src/com/android/systemui/people/widget/LaunchConversationActivity.java +17 −1 Original line number Diff line number Diff line Loading @@ -23,11 +23,13 @@ import android.content.pm.LauncherApps; import android.os.Bundle; import android.os.ServiceManager; import android.os.UserHandle; import android.os.UserManager; import android.service.notification.NotificationStats; import android.text.TextUtils; import android.util.Log; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.app.UnlaunchableAppActivity; import com.android.internal.logging.UiEventLogger; import com.android.internal.logging.UiEventLoggerImpl; import com.android.internal.statusbar.IStatusBarService; Loading @@ -48,15 +50,17 @@ public class LaunchConversationActivity extends Activity { private UiEventLogger mUiEventLogger = new UiEventLoggerImpl(); private NotificationEntryManager mNotificationEntryManager; private final Optional<BubblesManager> mBubblesManagerOptional; private final UserManager mUserManager; private boolean mIsForTesting; private IStatusBarService mIStatusBarService; @Inject public LaunchConversationActivity(NotificationEntryManager notificationEntryManager, Optional<BubblesManager> bubblesManagerOptional) { Optional<BubblesManager> bubblesManagerOptional, UserManager userManager) { super(); mNotificationEntryManager = notificationEntryManager; mBubblesManagerOptional = bubblesManagerOptional; mUserManager = userManager; } @Override Loading @@ -80,12 +84,24 @@ public class LaunchConversationActivity extends Activity { } mUiEventLogger.log(PeopleSpaceUtils.PeopleSpaceWidgetEvent.PEOPLE_SPACE_WIDGET_CLICKED); try { if (mUserManager.isQuietModeEnabled(userHandle)) { if (DEBUG) Log.d(TAG, "Cannot launch app when quieted"); final Intent dialogIntent = UnlaunchableAppActivity.createInQuietModeDialogIntent( userHandle.getIdentifier()); this.getApplicationContext().startActivity(dialogIntent); finish(); return; } NotificationEntry entry = mNotificationEntryManager.getPendingOrActiveNotif( notificationKey); if (entry != null && entry.canBubble() && mBubblesManagerOptional.isPresent()) { if (DEBUG) Log.d(TAG, "Open bubble for conversation"); mBubblesManagerOptional.get().expandStackAndSelectBubble(entry); // Just opt-out and don't cancel the notification for bubbles. finish(); return; } Loading
packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetManager.java +63 −2 Original line number Diff line number Diff line Loading @@ -31,7 +31,9 @@ import static com.android.systemui.people.PeopleSpaceUtils.getStoredWidgetIds; import static com.android.systemui.people.PeopleSpaceUtils.updateAppWidgetOptionsAndView; import static com.android.systemui.people.PeopleSpaceUtils.updateAppWidgetViews; import android.annotation.NonNull; import android.annotation.Nullable; import android.app.INotificationManager; import android.app.Notification; import android.app.NotificationChannel; import android.app.PendingIntent; Loading @@ -51,7 +53,9 @@ import android.net.Uri; import android.os.Bundle; import android.os.ServiceManager; import android.os.UserHandle; import android.os.UserManager; import android.preference.PreferenceManager; import android.service.notification.ConversationChannelWrapper; import android.service.notification.NotificationListenerService; import android.service.notification.StatusBarNotification; import android.util.Log; Loading @@ -76,6 +80,7 @@ import java.util.List; import java.util.Map; import java.util.Objects; import java.util.Set; import java.util.stream.Stream; import javax.inject.Inject; import javax.inject.Singleton; Loading @@ -96,6 +101,8 @@ public class PeopleSpaceWidgetManager { private NotificationEntryManager mNotificationEntryManager; private PackageManager mPackageManager; private PeopleSpaceWidgetProvider mPeopleSpaceWidgetProvider; private INotificationManager mINotificationManager; private UserManager mUserManager; public UiEventLogger mUiEventLogger = new UiEventLoggerImpl(); @GuardedBy("mLock") public static Map<PeopleTileKey, PeopleSpaceWidgetProvider.TileConversationListener> Loading @@ -121,17 +128,21 @@ public class PeopleSpaceWidgetManager { mNotificationEntryManager = Dependency.get(NotificationEntryManager.class); mPackageManager = mContext.getPackageManager(); mPeopleSpaceWidgetProvider = new PeopleSpaceWidgetProvider(); mINotificationManager = INotificationManager.Stub.asInterface( ServiceManager.getService(Context.NOTIFICATION_SERVICE)); mUserManager = context.getSystemService(UserManager.class); } /** * AppWidgetManager setter used for testing. */ @VisibleForTesting protected void setAppWidgetManager( public void setAppWidgetManager( AppWidgetManager appWidgetManager, IPeopleManager iPeopleManager, PeopleManager peopleManager, LauncherApps launcherApps, NotificationEntryManager notificationEntryManager, PackageManager packageManager, boolean isForTesting, PeopleSpaceWidgetProvider peopleSpaceWidgetProvider) { boolean isForTesting, PeopleSpaceWidgetProvider peopleSpaceWidgetProvider, UserManager userManager, INotificationManager notificationManager) { mAppWidgetManager = appWidgetManager; mIPeopleManager = iPeopleManager; mPeopleManager = peopleManager; Loading @@ -140,6 +151,8 @@ public class PeopleSpaceWidgetManager { mPackageManager = packageManager; mIsForTesting = isForTesting; mPeopleSpaceWidgetProvider = peopleSpaceWidgetProvider; mUserManager = userManager; mINotificationManager = notificationManager; } /** Loading Loading @@ -783,4 +796,52 @@ public class PeopleSpaceWidgetManager { ComponentName componentName = new ComponentName(mContext, PeopleSpaceWidgetProvider.class); return mAppWidgetManager.requestPinAppWidget(componentName, extras, successCallback); } /** Returns a list of map entries corresponding to user's priority conversations. */ @NonNull public List<PeopleSpaceTile> getPriorityTiles() throws Exception { List<ConversationChannelWrapper> conversations = mINotificationManager.getConversations(true).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> priorityTiles = PeopleSpaceUtils.getSortedTiles(mIPeopleManager, mLauncherApps, mUserManager, priorityConversations); priorityTiles = PeopleSpaceUtils.augmentTilesFromVisibleNotifications( mContext, priorityTiles, mNotificationEntryManager); return priorityTiles; } /** Returns a list of map entries corresponding to user's recent conversations. */ @NonNull public List<PeopleSpaceTile> getRecentTiles() throws Exception { if (DEBUG) Log.d(TAG, "Add recent conversations"); List<ConversationChannelWrapper> conversations = mINotificationManager.getConversations(false).getList(); Stream<ShortcutInfo> nonPriorityConversations = conversations.stream() .filter(c -> c.getNotificationChannel() == null || !c.getNotificationChannel().isImportantConversation()) .map(c -> c.getShortcutInfo()); List<ConversationChannel> recentConversationsList = mIPeopleManager.getRecentConversations().getList(); Stream<ShortcutInfo> recentConversations = recentConversationsList .stream() .map(c -> c.getShortcutInfo()); Stream<ShortcutInfo> mergedStream = Stream.concat(nonPriorityConversations, recentConversations); List<PeopleSpaceTile> recentTiles = PeopleSpaceUtils.getSortedTiles(mIPeopleManager, mLauncherApps, mUserManager, mergedStream); recentTiles = PeopleSpaceUtils.augmentTilesFromVisibleNotifications( mContext, recentTiles, mNotificationEntryManager); return recentTiles; } }
packages/SystemUI/tests/src/com/android/systemui/people/PeopleSpaceUtilsTest.java +0 −115 Original line number Diff line number Diff line Loading @@ -22,8 +22,6 @@ import static com.android.systemui.people.widget.AppWidgetOptionsHelper.OPTIONS_ 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; Loading @@ -35,10 +33,7 @@ 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.app.people.PeopleSpaceTile; import android.appwidget.AppWidgetManager; Loading @@ -47,7 +42,6 @@ import android.content.Context; import android.content.Intent; import android.content.pm.LauncherApps; import android.content.pm.PackageManager; import android.content.pm.ParceledListSlice; import android.content.pm.ShortcutInfo; import android.content.res.Configuration; import android.content.res.Resources; Loading @@ -57,7 +51,6 @@ import android.net.Uri; import android.os.Bundle; import android.os.UserHandle; import android.provider.ContactsContract; import android.service.notification.ConversationChannelWrapper; import android.service.notification.StatusBarNotification; import android.testing.AndroidTestingRunner; import android.util.DisplayMetrics; Loading @@ -81,10 +74,8 @@ 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; @RunWith(AndroidTestingRunner.class) @SmallTest Loading Loading @@ -185,8 +176,6 @@ public class PeopleSpaceUtilsTest extends SysuiTestCase { @Mock private IPeopleManager mPeopleManager; @Mock private LauncherApps mLauncherApps; @Mock private IAppWidgetService mIAppWidgetService; @Mock private AppWidgetManager mAppWidgetManager; Loading Loading @@ -238,84 +227,6 @@ public class PeopleSpaceUtilsTest extends SysuiTestCase { .thenReturn(List.of(mNotificationEntry1, mNotificationEntry2, mNotificationEntry3)); } @Test public void testGetRecentTilesReturnsSortedListWithOnlyRecentConversations() throws Exception { // Ensure the less-recent Important conversation is before more recent conversations. ConversationChannelWrapper newerNonImportantConversation = getConversationChannelWrapper( SHORTCUT_ID_1, false, 3); ConversationChannelWrapper newerImportantConversation = getConversationChannelWrapper( SHORTCUT_ID_1 + 1, true, 3); ConversationChannelWrapper olderImportantConversation = getConversationChannelWrapper( SHORTCUT_ID_1 + 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_1 + 3, 4); ConversationChannel recentConversationAfterNonImportantConversation = getConversationChannel(SHORTCUT_ID_1 + 4, 2); when(mPeopleManager.getRecentConversations()).thenReturn( new ParceledListSlice(Arrays.asList(recentConversationAfterNonImportantConversation, recentConversationBeforeNonImportantConversation))); List<String> orderedShortcutIds = PeopleSpaceUtils.getRecentTiles( mContext, mNotificationManager, mPeopleManager, mLauncherApps, mNotificationEntryManager) .stream().map(tile -> tile.getId()).collect(Collectors.toList()); // Check for sorted recent conversations. assertThat(orderedShortcutIds).containsExactly( recentConversationBeforeNonImportantConversation.getShortcutInfo().getId(), newerNonImportantConversation.getShortcutInfo().getId(), recentConversationAfterNonImportantConversation.getShortcutInfo().getId()) .inOrder(); } @Test public void testGetPriorityTilesReturnsSortedListWithOnlyImportantConversations() throws Exception { // Ensure the less-recent Important conversation is before more recent conversations. ConversationChannelWrapper newerNonImportantConversation = getConversationChannelWrapper( SHORTCUT_ID_1, false, 3); ConversationChannelWrapper newerImportantConversation = getConversationChannelWrapper( SHORTCUT_ID_1 + 1, true, 3); ConversationChannelWrapper olderImportantConversation = getConversationChannelWrapper( SHORTCUT_ID_1 + 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_1 + 3, 4); ConversationChannel recentConversationAfterNonImportantConversation = getConversationChannel(SHORTCUT_ID_1 + 4, 2); when(mPeopleManager.getRecentConversations()).thenReturn( new ParceledListSlice(Arrays.asList(recentConversationAfterNonImportantConversation, recentConversationBeforeNonImportantConversation))); List<String> orderedShortcutIds = PeopleSpaceUtils.getPriorityTiles( mContext, mNotificationManager, mPeopleManager, mLauncherApps, mNotificationEntryManager) .stream().map(tile -> tile.getId()).collect(Collectors.toList()); // Check for sorted priority conversations. assertThat(orderedShortcutIds).containsExactly( newerImportantConversation.getShortcutInfo().getId(), olderImportantConversation.getShortcutInfo().getId()) .inOrder(); } @Test public void testGetMessagingStyleMessagesNoMessage() { Notification notification = new Notification.Builder(mContext, "test") Loading Loading @@ -570,30 +481,4 @@ 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; } }