summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--packages/SystemUI/res/xml/people_space_widget_info.xml4
-rw-r--r--packages/SystemUI/src/com/android/systemui/people/PeopleSpaceUtils.java38
-rw-r--r--packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetManager.java224
-rw-r--r--packages/SystemUI/tests/src/com/android/systemui/people/widget/PeopleSpaceWidgetManagerTest.java365
4 files changed, 572 insertions, 59 deletions
diff --git a/packages/SystemUI/res/xml/people_space_widget_info.xml b/packages/SystemUI/res/xml/people_space_widget_info.xml
index d2bff180ef8a..b2bf6da65163 100644
--- a/packages/SystemUI/res/xml/people_space_widget_info.xml
+++ b/packages/SystemUI/res/xml/people_space_widget_info.xml
@@ -16,9 +16,9 @@
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:minWidth="120dp"
- android:minHeight="54dp"
+ android:minHeight="50dp"
android:minResizeWidth="60dp"
- android:minResizeHeight="54dp"
+ android:minResizeHeight="50dp"
android:maxResizeHeight="207dp"
android:updatePeriodMillis="60000"
android:description="@string/people_tile_description"
diff --git a/packages/SystemUI/src/com/android/systemui/people/PeopleSpaceUtils.java b/packages/SystemUI/src/com/android/systemui/people/PeopleSpaceUtils.java
index 5bc128062adc..440c5efab008 100644
--- a/packages/SystemUI/src/com/android/systemui/people/PeopleSpaceUtils.java
+++ b/packages/SystemUI/src/com/android/systemui/people/PeopleSpaceUtils.java
@@ -175,7 +175,7 @@ public class PeopleSpaceUtils {
/** Sets all relevant storage for {@code appWidgetId} association to {@code tile}. */
public static void setSharedPreferencesStorageForTile(Context context, PeopleTileKey key,
- int appWidgetId) {
+ int appWidgetId, Uri contactUri) {
// Write relevant persisted storage.
SharedPreferences widgetSp = context.getSharedPreferences(String.valueOf(appWidgetId),
Context.MODE_PRIVATE);
@@ -186,27 +186,24 @@ public class PeopleSpaceUtils {
widgetEditor.apply();
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
SharedPreferences.Editor editor = sp.edit();
- editor.putString(String.valueOf(appWidgetId), key.getShortcutId());
+ String contactUriString = contactUri == null ? EMPTY_STRING : contactUri.toString();
+ editor.putString(String.valueOf(appWidgetId), contactUriString);
// Don't overwrite existing widgets with the same key.
- Set<String> storedWidgetIds = new HashSet<>(
- sp.getStringSet(key.toString(), new HashSet<>()));
- storedWidgetIds.add(String.valueOf(appWidgetId));
- editor.putStringSet(key.toString(), storedWidgetIds);
+ addAppWidgetIdForKey(sp, editor, appWidgetId, key.toString());
+ addAppWidgetIdForKey(sp, editor, appWidgetId, contactUriString);
editor.apply();
}
/** Removes stored data when tile is deleted. */
public static void removeSharedPreferencesStorageForTile(Context context, PeopleTileKey key,
- int widgetId) {
+ int widgetId, String contactUriString) {
// Delete widgetId mapping to key.
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
SharedPreferences.Editor editor = sp.edit();
- Set<String> storedWidgetIds = new HashSet<>(
- sp.getStringSet(key.toString(), new HashSet<>()));
- storedWidgetIds.remove(String.valueOf(widgetId));
- editor.putStringSet(key.toString(), storedWidgetIds);
editor.remove(String.valueOf(widgetId));
+ removeAppWidgetIdForKey(sp, editor, widgetId, key.toString());
+ removeAppWidgetIdForKey(sp, editor, widgetId, contactUriString);
editor.apply();
// Delete all data specifically mapped to widgetId.
@@ -219,6 +216,23 @@ public class PeopleSpaceUtils {
widgetEditor.apply();
}
+ private static void addAppWidgetIdForKey(SharedPreferences sp, SharedPreferences.Editor editor,
+ int widgetId, String storageKey) {
+ Set<String> storedWidgetIdsByKey = new HashSet<>(
+ sp.getStringSet(storageKey, new HashSet<>()));
+ storedWidgetIdsByKey.add(String.valueOf(widgetId));
+ editor.putStringSet(storageKey, storedWidgetIdsByKey);
+ }
+
+ private static void removeAppWidgetIdForKey(SharedPreferences sp,
+ SharedPreferences.Editor editor,
+ int widgetId, String storageKey) {
+ Set<String> storedWidgetIds = new HashSet<>(
+ sp.getStringSet(storageKey, new HashSet<>()));
+ storedWidgetIds.remove(String.valueOf(widgetId));
+ editor.putStringSet(storageKey, storedWidgetIds);
+ }
+
/** Augments a single {@link PeopleSpaceTile} with notification content, if one is present. */
public static PeopleSpaceTile augmentSingleTileFromVisibleNotifications(Context context,
PeopleSpaceTile tile, NotificationEntryManager notificationEntryManager) {
@@ -256,7 +270,7 @@ public class PeopleSpaceUtils {
PeopleSpaceTile tile, Map<PeopleTileKey, NotificationEntry> visibleNotifications) {
PeopleTileKey key = new PeopleTileKey(
tile.getId(), getUserId(tile), tile.getPackageName());
-
+ // TODO: Match missed calls with matching Uris in addition to keys.
if (!visibleNotifications.containsKey(key)) {
if (DEBUG) Log.d(TAG, "No existing notifications for key:" + key.toString());
return tile;
diff --git a/packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetManager.java b/packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetManager.java
index 776e8a246bf6..5be2d4a05f54 100644
--- a/packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetManager.java
+++ b/packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetManager.java
@@ -16,17 +16,23 @@
package com.android.systemui.people.widget;
+import static android.Manifest.permission.READ_CONTACTS;
+import static android.app.Notification.CATEGORY_MISSED_CALL;
+import static android.app.Notification.EXTRA_PEOPLE_LIST;
+
import static com.android.systemui.people.PeopleSpaceUtils.EMPTY_STRING;
import static com.android.systemui.people.PeopleSpaceUtils.INVALID_USER_ID;
import static com.android.systemui.people.PeopleSpaceUtils.PACKAGE_NAME;
import static com.android.systemui.people.PeopleSpaceUtils.SHORTCUT_ID;
import static com.android.systemui.people.PeopleSpaceUtils.USER_ID;
import static com.android.systemui.people.PeopleSpaceUtils.augmentTileFromNotification;
+import static com.android.systemui.people.PeopleSpaceUtils.getMessagingStyleMessages;
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.Nullable;
+import android.app.Notification;
import android.app.NotificationChannel;
import android.app.PendingIntent;
import android.app.Person;
@@ -39,6 +45,7 @@ import android.content.ComponentName;
import android.content.Context;
import android.content.SharedPreferences;
import android.content.pm.LauncherApps;
+import android.content.pm.PackageManager;
import android.content.pm.ShortcutInfo;
import android.net.Uri;
import android.os.Bundle;
@@ -54,16 +61,20 @@ import com.android.internal.annotations.GuardedBy;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.logging.UiEventLogger;
import com.android.internal.logging.UiEventLoggerImpl;
+import com.android.settingslib.utils.ThreadUtils;
import com.android.systemui.Dependency;
import com.android.systemui.people.PeopleSpaceUtils;
import com.android.systemui.statusbar.NotificationListener;
import com.android.systemui.statusbar.NotificationListener.NotificationHandler;
import com.android.systemui.statusbar.notification.NotificationEntryManager;
+import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.List;
import java.util.Map;
+import java.util.Objects;
import java.util.Set;
import javax.inject.Inject;
@@ -83,11 +94,19 @@ public class PeopleSpaceWidgetManager {
private SharedPreferences mSharedPrefs;
private PeopleManager mPeopleManager;
private NotificationEntryManager mNotificationEntryManager;
+ private PackageManager mPackageManager;
public UiEventLogger mUiEventLogger = new UiEventLoggerImpl();
@GuardedBy("mLock")
public static Map<PeopleTileKey, PeopleSpaceWidgetProvider.TileConversationListener>
mListeners = new HashMap<>();
+ @GuardedBy("mLock")
+ // Map of notification key mapped to widget IDs previously updated by the contact Uri field.
+ // This is required because on notification removal, the contact Uri field is stripped and we
+ // only have the notification key to determine which widget IDs should be updated.
+ private Map<String, Set<String>> mNotificationKeyToWidgetIdsMatchedByUri = new HashMap<>();
+ private boolean mIsForTesting;
+
@Inject
public PeopleSpaceWidgetManager(Context context) {
if (DEBUG) Log.d(TAG, "constructor");
@@ -99,6 +118,7 @@ public class PeopleSpaceWidgetManager {
mSharedPrefs = PreferenceManager.getDefaultSharedPreferences(mContext);
mPeopleManager = mContext.getSystemService(PeopleManager.class);
mNotificationEntryManager = Dependency.get(NotificationEntryManager.class);
+ mPackageManager = mContext.getPackageManager();
}
/**
@@ -108,12 +128,15 @@ public class PeopleSpaceWidgetManager {
protected void setAppWidgetManager(
AppWidgetManager appWidgetManager, IPeopleManager iPeopleManager,
PeopleManager peopleManager, LauncherApps launcherApps,
- NotificationEntryManager notificationEntryManager) {
+ NotificationEntryManager notificationEntryManager, PackageManager packageManager,
+ boolean isForTesting) {
mAppWidgetManager = appWidgetManager;
mIPeopleManager = iPeopleManager;
mPeopleManager = peopleManager;
mLauncherApps = launcherApps;
mNotificationEntryManager = notificationEntryManager;
+ mPackageManager = packageManager;
+ mIsForTesting = isForTesting;
}
/**
@@ -222,6 +245,16 @@ public class PeopleSpaceWidgetManager {
public void updateWidgetsWithNotificationChanged(StatusBarNotification sbn,
PeopleSpaceUtils.NotificationAction notificationAction) {
if (DEBUG) Log.d(TAG, "updateWidgetsWithNotificationChanged called");
+ if (mIsForTesting) {
+ updateWidgetsWithNotificationChangedInBackground(sbn, notificationAction);
+ return;
+ }
+ ThreadUtils.postOnBackgroundThread(
+ () -> updateWidgetsWithNotificationChangedInBackground(sbn, notificationAction));
+ }
+
+ private void updateWidgetsWithNotificationChangedInBackground(StatusBarNotification sbn,
+ PeopleSpaceUtils.NotificationAction action) {
try {
String sbnShortcutId = sbn.getShortcutId();
if (sbnShortcutId == null) {
@@ -235,23 +268,175 @@ public class PeopleSpaceWidgetManager {
Log.d(TAG, "No app widget ids returned");
return;
}
+ PeopleTileKey key = new PeopleTileKey(
+ sbnShortcutId,
+ sbn.getUser().getIdentifier(),
+ sbn.getPackageName());
+ if (!key.isValid()) {
+ Log.d(TAG, "Invalid key");
+ return;
+ }
synchronized (mLock) {
- PeopleTileKey key = new PeopleTileKey(
- sbnShortcutId,
- UserHandle.getUserHandleForUid(sbn.getUid()).getIdentifier(),
- sbn.getPackageName());
- Set<String> storedWidgetIds = getStoredWidgetIds(mSharedPrefs, key);
- for (String widgetIdString : storedWidgetIds) {
- int widgetId = Integer.parseInt(widgetIdString);
- if (DEBUG) Log.d(TAG, "Storing notification change, key:" + sbn.getKey());
- updateStorageAndViewWithNotificationData(sbn, notificationAction, widgetId);
- }
+ // First, update People Tiles associated with the Notification's package/shortcut.
+ Set<String> tilesUpdatedByKey = getStoredWidgetIds(mSharedPrefs, key);
+ updateWidgetIdsForNotificationAction(tilesUpdatedByKey, sbn, action);
+
+ // Then, update People Tiles across other packages that use the same Uri.
+ updateTilesByUri(key, sbn, action);
}
} catch (Exception e) {
Log.e(TAG, "Exception: " + e);
}
}
+ /** Updates {@code widgetIdsToUpdate} with {@code action}. */
+ private void updateWidgetIdsForNotificationAction(Set<String> widgetIdsToUpdate,
+ StatusBarNotification sbn, PeopleSpaceUtils.NotificationAction action) {
+ for (String widgetIdString : widgetIdsToUpdate) {
+ int widgetId = Integer.parseInt(widgetIdString);
+ PeopleSpaceTile storedTile = getTileForExistingWidget(widgetId);
+ if (storedTile == null) {
+ if (DEBUG) Log.d(TAG, "Could not find stored tile for notification");
+ continue;
+ }
+ if (DEBUG) Log.d(TAG, "Storing notification change, key:" + sbn.getKey());
+ updateStorageAndViewWithNotificationData(sbn, action, widgetId,
+ storedTile);
+ }
+ }
+
+ /**
+ * Updates tiles with matched Uris, dependent on the {@code action}.
+ *
+ * <p>If the notification was added, adds the notification based on the contact Uri within
+ * {@code sbn}.
+ * <p>If the notification was removed, removes the notification based on the in-memory map of
+ * widgets previously updated by Uri (since the contact Uri is stripped from the {@code sbn}).
+ */
+ private void updateTilesByUri(PeopleTileKey key, StatusBarNotification sbn,
+ PeopleSpaceUtils.NotificationAction action) {
+ if (action.equals(PeopleSpaceUtils.NotificationAction.POSTED)) {
+ Set<String> widgetIdsUpdatedByUri = supplementTilesByUri(sbn, action, key);
+ if (widgetIdsUpdatedByUri != null && !widgetIdsUpdatedByUri.isEmpty()) {
+ if (DEBUG) Log.d(TAG, "Added due to uri: " + widgetIdsUpdatedByUri);
+ mNotificationKeyToWidgetIdsMatchedByUri.put(sbn.getKey(), widgetIdsUpdatedByUri);
+ }
+ } else {
+ // Remove the notification on any widgets where the notification was added
+ // purely based on the Uri.
+ Set<String> widgetsPreviouslyUpdatedByUri =
+ mNotificationKeyToWidgetIdsMatchedByUri.remove(sbn.getKey());
+ if (widgetsPreviouslyUpdatedByUri != null && !widgetsPreviouslyUpdatedByUri.isEmpty()) {
+ if (DEBUG) Log.d(TAG, "Remove due to uri: " + widgetsPreviouslyUpdatedByUri);
+ updateWidgetIdsForNotificationAction(widgetsPreviouslyUpdatedByUri, sbn,
+ action);
+ }
+ }
+ }
+
+ /**
+ * Retrieves from storage any tiles with the same contact Uri as linked via the {@code sbn}.
+ * Supplements the tiles with the notification content only if they still have {@link
+ * android.Manifest.permission.READ_CONTACTS} permission.
+ */
+ @Nullable
+ private Set<String> supplementTilesByUri(StatusBarNotification sbn,
+ PeopleSpaceUtils.NotificationAction notificationAction, PeopleTileKey key) {
+ if (!shouldMatchNotificationByUri(sbn)) {
+ if (DEBUG) Log.d(TAG, "Should not supplement conversation");
+ return null;
+ }
+
+ // Try to get the Contact Uri from the Missed Call notification directly.
+ String contactUri = getContactUri(sbn);
+ if (contactUri == null) {
+ if (DEBUG) Log.d(TAG, "No contact uri");
+ return null;
+ }
+
+ // Supplement any tiles with the same Uri.
+ Set<String> storedWidgetIdsByUri =
+ new HashSet<>(mSharedPrefs.getStringSet(contactUri, new HashSet<>()));
+ if (storedWidgetIdsByUri.isEmpty()) {
+ if (DEBUG) Log.d(TAG, "No tiles for contact");
+ return null;
+ }
+
+ if (mPackageManager.checkPermission(READ_CONTACTS,
+ sbn.getPackageName()) != PackageManager.PERMISSION_GRANTED) {
+ if (DEBUG) Log.d(TAG, "Notifying app missing permissions");
+ return null;
+ }
+
+ Set<String> widgetIdsUpdatedByUri = new HashSet<>();
+ for (String widgetIdString : storedWidgetIdsByUri) {
+ int widgetId = Integer.parseInt(widgetIdString);
+ PeopleSpaceTile storedTile = getTileForExistingWidget(widgetId);
+ // Don't update a widget already updated.
+ if (key.equals(new PeopleTileKey(storedTile))) {
+ continue;
+ }
+ if (storedTile == null || mPackageManager.checkPermission(READ_CONTACTS,
+ storedTile.getPackageName()) != PackageManager.PERMISSION_GRANTED) {
+ if (DEBUG) Log.d(TAG, "Cannot supplement tile: " + storedTile.getUserName());
+ continue;
+ }
+ if (DEBUG) Log.d(TAG, "Adding notification by uri: " + sbn.getKey());
+ updateStorageAndViewWithNotificationData(sbn, notificationAction,
+ widgetId, storedTile);
+ widgetIdsUpdatedByUri.add(String.valueOf(widgetId));
+ }
+ return widgetIdsUpdatedByUri;
+ }
+
+ /**
+ * Try to retrieve a valid Uri via {@code sbn}, falling back to the {@code
+ * contactUriFromShortcut} if valid.
+ */
+ @Nullable
+ private String getContactUri(StatusBarNotification sbn) {
+ // First, try to get a Uri from the Person directly set on the Notification.
+ ArrayList<Person> people = sbn.getNotification().extras.getParcelableArrayList(
+ EXTRA_PEOPLE_LIST);
+ if (people != null && people.get(0) != null) {
+ String contactUri = people.get(0).getUri();
+ if (contactUri != null && !contactUri.isEmpty()) {
+ return contactUri;
+ }
+ }
+
+ // Then, try to get a Uri from the Person set on the Notification message.
+ List<Notification.MessagingStyle.Message> messages =
+ getMessagingStyleMessages(sbn.getNotification());
+ if (messages != null && !messages.isEmpty()) {
+ Notification.MessagingStyle.Message message = messages.get(0);
+ Person sender = message.getSenderPerson();
+ if (sender != null && sender.getUri() != null && !sender.getUri().isEmpty()) {
+ return sender.getUri();
+ }
+ }
+
+ return null;
+ }
+
+ /**
+ * Returns whether a notification should be matched to other Tiles by Uri.
+ *
+ * <p>Currently only matches missed calls.
+ */
+ private boolean shouldMatchNotificationByUri(StatusBarNotification sbn) {
+ Notification notification = sbn.getNotification();
+ if (notification == null) {
+ if (DEBUG) Log.d(TAG, "Notification is null");
+ return false;
+ }
+ if (!Objects.equals(notification.category, CATEGORY_MISSED_CALL)) {
+ if (DEBUG) Log.d(TAG, "Not missed call");
+ return false;
+ }
+ return true;
+ }
+
/**
* Update the tiles associated with the incoming conversation update.
*/
@@ -309,16 +494,11 @@ public class PeopleSpaceWidgetManager {
private void updateStorageAndViewWithNotificationData(
StatusBarNotification sbn,
PeopleSpaceUtils.NotificationAction notificationAction,
- int appWidgetId) {
- PeopleSpaceTile storedTile = getTileForExistingWidget(appWidgetId);
- if (storedTile == null) {
- if (DEBUG) Log.d(TAG, "Could not find stored tile to add notification to");
- return;
- }
+ int appWidgetId, PeopleSpaceTile storedTile) {
if (notificationAction == PeopleSpaceUtils.NotificationAction.POSTED) {
if (DEBUG) Log.i(TAG, "Adding notification to storage, appWidgetId: " + appWidgetId);
storedTile = augmentTileFromNotification(mContext, storedTile, sbn);
- } else {
+ } else if (storedTile.getNotificationKey().equals(sbn.getKey())) {
if (DEBUG) {
Log.i(TAG, "Removing notification from storage, appWidgetId: " + appWidgetId);
}
@@ -440,7 +620,8 @@ public class PeopleSpaceWidgetManager {
synchronized (mLock) {
if (DEBUG) Log.d(TAG, "Add storage for : " + tile.getId());
PeopleTileKey key = new PeopleTileKey(tile);
- PeopleSpaceUtils.setSharedPreferencesStorageForTile(mContext, key, appWidgetId);
+ PeopleSpaceUtils.setSharedPreferencesStorageForTile(mContext, key, appWidgetId,
+ tile.getContactUri());
}
try {
if (DEBUG) Log.d(TAG, "Caching shortcut for PeopleTile: " + tile.getId());
@@ -496,6 +677,7 @@ public class PeopleSpaceWidgetManager {
// Retrieve storage needed for widget deletion.
PeopleTileKey key;
Set<String> storedWidgetIdsForKey;
+ String contactUriString;
synchronized (mLock) {
SharedPreferences widgetSp = mContext.getSharedPreferences(String.valueOf(widgetId),
Context.MODE_PRIVATE);
@@ -509,9 +691,11 @@ public class PeopleSpaceWidgetManager {
}
storedWidgetIdsForKey = new HashSet<>(
mSharedPrefs.getStringSet(key.toString(), new HashSet<>()));
+ contactUriString = mSharedPrefs.getString(String.valueOf(widgetId), null);
}
synchronized (mLock) {
- PeopleSpaceUtils.removeSharedPreferencesStorageForTile(mContext, key, widgetId);
+ PeopleSpaceUtils.removeSharedPreferencesStorageForTile(mContext, key, widgetId,
+ contactUriString);
}
// If another tile with the conversation is still stored, we need to keep the listener.
if (DEBUG) Log.d(TAG, "Stored widget IDs: " + storedWidgetIdsForKey.toString());
diff --git a/packages/SystemUI/tests/src/com/android/systemui/people/widget/PeopleSpaceWidgetManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/people/widget/PeopleSpaceWidgetManagerTest.java
index 7090e781a316..d91625eb7fab 100644
--- a/packages/SystemUI/tests/src/com/android/systemui/people/widget/PeopleSpaceWidgetManagerTest.java
+++ b/packages/SystemUI/tests/src/com/android/systemui/people/widget/PeopleSpaceWidgetManagerTest.java
@@ -17,11 +17,14 @@
package com.android.systemui.people.widget;
import static android.app.Notification.CATEGORY_MISSED_CALL;
+import static android.app.Notification.EXTRA_PEOPLE_LIST;
import static android.app.NotificationManager.IMPORTANCE_DEFAULT;
import static android.app.NotificationManager.IMPORTANCE_HIGH;
import static android.app.people.ConversationStatus.ACTIVITY_ANNIVERSARY;
import static android.app.people.ConversationStatus.ACTIVITY_BIRTHDAY;
import static android.app.people.ConversationStatus.ACTIVITY_GAME;
+import static android.content.PermissionChecker.PERMISSION_GRANTED;
+import static android.content.PermissionChecker.PERMISSION_HARD_DENIED;
import static com.android.systemui.people.PeopleSpaceUtils.EMPTY_STRING;
import static com.android.systemui.people.PeopleSpaceUtils.INVALID_USER_ID;
@@ -55,6 +58,7 @@ import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.pm.LauncherApps;
+import android.content.pm.PackageManager;
import android.content.pm.ShortcutInfo;
import android.graphics.drawable.Icon;
import android.net.Uri;
@@ -86,6 +90,7 @@ import org.mockito.Captor;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
+import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
@@ -106,6 +111,8 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
private static final int SECOND_WIDGET_ID_WITH_SHORTCUT = 3;
private static final int WIDGET_ID_WITHOUT_SHORTCUT = 2;
private static final int WIDGET_ID_WITH_KEY_IN_OPTIONS = 4;
+ private static final int WIDGET_ID_WITH_SAME_URI = 5;
+ private static final int WIDGET_ID_WITH_DIFFERENT_URI = 6;
private static final String SHORTCUT_ID = "101";
private static final String OTHER_SHORTCUT_ID = "102";
private static final String NOTIFICATION_KEY = "0|com.android.systemui.tests|0|null|0";
@@ -123,10 +130,21 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
new PeopleSpaceTile
.Builder(SHORTCUT_ID, "username", ICON, new Intent())
.setPackageName(TEST_PACKAGE_A)
- .setUserHandle(new UserHandle(1))
+ .setUserHandle(new UserHandle(0))
.setNotificationKey(NOTIFICATION_KEY + "1")
.setNotificationContent(NOTIFICATION_CONTENT)
.setNotificationDataUri(URI)
+ .setContactUri(URI)
+ .build();
+ private static final PeopleSpaceTile PERSON_TILE_WITH_SAME_URI =
+ new PeopleSpaceTile
+ // Different shortcut ID
+ .Builder(OTHER_SHORTCUT_ID, "username", ICON, new Intent())
+ // Different package name
+ .setPackageName(TEST_PACKAGE_B)
+ .setUserHandle(new UserHandle(0))
+ // Same contact uri.
+ .setContactUri(URI)
.build();
private final ShortcutInfo mShortcutInfo = new ShortcutInfo.Builder(mContext,
SHORTCUT_ID).setLongLabel("name").build();
@@ -149,6 +167,8 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
private LauncherApps mLauncherApps;
@Mock
private NotificationEntryManager mNotificationEntryManager;
+ @Mock
+ private PackageManager mPackageManager;
@Captor
private ArgumentCaptor<NotificationHandler> mListenerCaptor;
@@ -167,7 +187,7 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
mDependency.injectTestDependency(NotificationEntryManager.class, mNotificationEntryManager);
mManager = new PeopleSpaceWidgetManager(mContext);
mManager.setAppWidgetManager(mAppWidgetManager, mIPeopleManager, mPeopleManager,
- mLauncherApps, mNotificationEntryManager);
+ mLauncherApps, mNotificationEntryManager, mPackageManager, true);
mManager.attach(mListenerService);
mProvider = new PeopleSpaceWidgetProvider();
mProvider.setPeopleSpaceWidgetManager(mManager);
@@ -177,16 +197,10 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
mNoMan.addListener(serviceListener);
clearStorage();
- setStorageForTile(SHORTCUT_ID, TEST_PACKAGE_A, WIDGET_ID_WITH_SHORTCUT);
-
- Bundle options = new Bundle();
- options.putParcelable(OPTIONS_PEOPLE_TILE, PERSON_TILE);
- when(mAppWidgetManager.getAppWidgetOptions(eq(WIDGET_ID_WITH_SHORTCUT)))
- .thenReturn(options);
+ addTileForWidget(PERSON_TILE, WIDGET_ID_WITH_SHORTCUT);
+ addTileForWidget(PERSON_TILE_WITH_SAME_URI, WIDGET_ID_WITH_SAME_URI);
when(mAppWidgetManager.getAppWidgetOptions(eq(WIDGET_ID_WITHOUT_SHORTCUT)))
.thenReturn(new Bundle());
- when(mIPeopleManager.getConversation(TEST_PACKAGE_A, 0, SHORTCUT_ID)).thenReturn(
- getConversationWithShortcutId(SHORTCUT_ID));
}
@Test
@@ -477,7 +491,7 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
addSecondWidgetForPersonTile();
PeopleSpaceUtils.removeSharedPreferencesStorageForTile(
- mContext, KEY, SECOND_WIDGET_ID_WITH_SHORTCUT);
+ mContext, KEY, SECOND_WIDGET_ID_WITH_SHORTCUT, EMPTY_STRING);
NotifEvent notif1 = mNoMan.postNotif(new NotificationEntryBuilder()
.setSbn(createNotification(
SHORTCUT_ID, /* isMessagingStyle = */ true, /* isMissedCall = */ false))
@@ -501,7 +515,6 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
throws Exception {
int[] widgetIdsArray = {WIDGET_ID_WITH_SHORTCUT, WIDGET_ID_WITHOUT_SHORTCUT};
when(mAppWidgetManager.getAppWidgetIds(any())).thenReturn(widgetIdsArray);
- setStorageForTile(SHORTCUT_ID, TEST_PACKAGE_A, WIDGET_ID_WITH_SHORTCUT);
NotifEvent notif1 = mNoMan.postNotif(new NotificationEntryBuilder()
.setSbn(createNotification(
@@ -527,7 +540,6 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
throws Exception {
int[] widgetIdsArray = {WIDGET_ID_WITH_SHORTCUT, WIDGET_ID_WITHOUT_SHORTCUT};
when(mAppWidgetManager.getAppWidgetIds(any())).thenReturn(widgetIdsArray);
- setStorageForTile(SHORTCUT_ID, TEST_PACKAGE_A, WIDGET_ID_WITH_SHORTCUT);
NotifEvent notif1 = mNoMan.postNotif(new NotificationEntryBuilder()
.setSbn(createNotification(
@@ -548,10 +560,267 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
}
@Test
+ public void testUpdateMissedCallNotificationWithContentPostedIfMatchingUriTile()
+ throws Exception {
+ int[] widgetIdsArray =
+ {WIDGET_ID_WITH_SHORTCUT, WIDGET_ID_WITHOUT_SHORTCUT, WIDGET_ID_WITH_SAME_URI};
+ when(mAppWidgetManager.getAppWidgetIds(any())).thenReturn(widgetIdsArray);
+
+ NotifEvent notif1 = mNoMan.postNotif(new NotificationEntryBuilder()
+ .setSbn(createNotification(
+ SHORTCUT_ID, /* isMessagingStyle = */ true, /* isMissedCall = */ true))
+ .setId(1));
+ mClock.advanceTime(MIN_LINGER_DURATION);
+
+ verify(mAppWidgetManager, times(1))
+ .updateAppWidgetOptions(eq(WIDGET_ID_WITH_SHORTCUT),
+ mBundleArgumentCaptor.capture());
+ Bundle bundle = requireNonNull(mBundleArgumentCaptor.getValue());
+ PeopleSpaceTile tileWithMissedCallOrigin = bundle.getParcelable(OPTIONS_PEOPLE_TILE);
+ assertThat(tileWithMissedCallOrigin.getNotificationKey()).isEqualTo(NOTIFICATION_KEY);
+ assertThat(tileWithMissedCallOrigin.getNotificationContent()).isEqualTo(
+ NOTIFICATION_CONTENT);
+ verify(mAppWidgetManager, times(1)).updateAppWidget(eq(WIDGET_ID_WITH_SHORTCUT),
+ any());
+ verify(mAppWidgetManager, times(1))
+ .updateAppWidgetOptions(eq(WIDGET_ID_WITH_SAME_URI),
+ mBundleArgumentCaptor.capture());
+ Bundle bundleForSameUriTile = requireNonNull(mBundleArgumentCaptor.getValue());
+ PeopleSpaceTile tileWithSameUri = bundleForSameUriTile.getParcelable(OPTIONS_PEOPLE_TILE);
+ assertThat(tileWithSameUri.getNotificationKey()).isEqualTo(NOTIFICATION_KEY);
+ assertThat(tileWithSameUri.getNotificationContent()).isEqualTo(NOTIFICATION_CONTENT);
+ verify(mAppWidgetManager, times(1)).updateAppWidget(eq(WIDGET_ID_WITH_SAME_URI),
+ any());
+ }
+
+ @Test
+ public void testRemoveMissedCallNotificationWithContentPostedIfMatchingUriTile()
+ throws Exception {
+ int[] widgetIdsArray =
+ {WIDGET_ID_WITH_SHORTCUT, WIDGET_ID_WITHOUT_SHORTCUT, WIDGET_ID_WITH_SAME_URI};
+ when(mAppWidgetManager.getAppWidgetIds(any())).thenReturn(widgetIdsArray);
+
+ NotifEvent notif1 = mNoMan.postNotif(new NotificationEntryBuilder()
+ .setSbn(createNotification(
+ SHORTCUT_ID, /* isMessagingStyle = */ true, /* isMissedCall = */ true))
+ .setId(1));
+ mClock.advanceTime(MIN_LINGER_DURATION);
+ NotifEvent notif1b = mNoMan.retractNotif(notif1.sbn.cloneLight(), 0);
+ mClock.advanceTime(MIN_LINGER_DURATION);
+
+ verify(mAppWidgetManager, times(2)).updateAppWidgetOptions(eq(WIDGET_ID_WITH_SHORTCUT),
+ mBundleArgumentCaptor.capture());
+ Bundle bundle = mBundleArgumentCaptor.getValue();
+ PeopleSpaceTile tileWithMissedCallOrigin = bundle.getParcelable(OPTIONS_PEOPLE_TILE);
+ assertThat(tileWithMissedCallOrigin.getNotificationKey()).isEqualTo(null);
+ assertThat(tileWithMissedCallOrigin.getNotificationContent()).isEqualTo(null);
+ verify(mAppWidgetManager, times(2)).updateAppWidget(eq(WIDGET_ID_WITH_SHORTCUT),
+ any());
+ verify(mAppWidgetManager, times(2))
+ .updateAppWidgetOptions(eq(WIDGET_ID_WITH_SAME_URI),
+ mBundleArgumentCaptor.capture());
+ Bundle bundleForSameUriTile = requireNonNull(mBundleArgumentCaptor.getValue());
+ PeopleSpaceTile tileWithSameUri = bundleForSameUriTile.getParcelable(OPTIONS_PEOPLE_TILE);
+ assertThat(tileWithSameUri.getNotificationKey()).isEqualTo(null);
+ assertThat(tileWithSameUri.getNotificationContent()).isEqualTo(null);
+ verify(mAppWidgetManager, times(2)).updateAppWidget(eq(WIDGET_ID_WITH_SAME_URI),
+ any());
+ }
+
+ @Test
+ public void testDoNotRemoveMissedCallIfMatchingUriTileMissingReadContactsPermissionWhenPosted()
+ throws Exception {
+ when(mPackageManager.checkPermission(any(),
+ eq(PERSON_TILE_WITH_SAME_URI.getPackageName()))).thenReturn(
+ PERMISSION_HARD_DENIED);
+ int[] widgetIdsArray =
+ {WIDGET_ID_WITH_SHORTCUT, WIDGET_ID_WITHOUT_SHORTCUT, WIDGET_ID_WITH_SAME_URI};
+ when(mAppWidgetManager.getAppWidgetIds(any())).thenReturn(widgetIdsArray);
+
+ NotifEvent notif1 = mNoMan.postNotif(new NotificationEntryBuilder()
+ .setSbn(createNotification(
+ SHORTCUT_ID, /* isMessagingStyle = */ true, /* isMissedCall = */ true))
+ .setId(1));
+ mClock.advanceTime(MIN_LINGER_DURATION);
+ // We should only try to remove the notification if the Missed Call was added when posted.
+ NotifEvent notif1b = mNoMan.retractNotif(notif1.sbn.cloneLight(), 0);
+ mClock.advanceTime(MIN_LINGER_DURATION);
+
+ verify(mAppWidgetManager, times(2)).updateAppWidgetOptions(eq(WIDGET_ID_WITH_SHORTCUT),
+ mBundleArgumentCaptor.capture());
+ Bundle bundle = mBundleArgumentCaptor.getValue();
+ PeopleSpaceTile tileWithMissedCallOrigin = bundle.getParcelable(OPTIONS_PEOPLE_TILE);
+ assertThat(tileWithMissedCallOrigin.getNotificationKey()).isEqualTo(null);
+ assertThat(tileWithMissedCallOrigin.getNotificationContent()).isEqualTo(null);
+ verify(mAppWidgetManager, times(2)).updateAppWidget(eq(WIDGET_ID_WITH_SHORTCUT),
+ any());
+ verify(mAppWidgetManager, times(0))
+ .updateAppWidgetOptions(eq(WIDGET_ID_WITH_SAME_URI), any());
+ verify(mAppWidgetManager, times(0)).updateAppWidget(eq(WIDGET_ID_WITH_SAME_URI),
+ any());
+ }
+
+ @Test
+ public void testUpdateMissedCallNotificationWithContentPostedIfMatchingUriTileFromSender()
+ throws Exception {
+ int[] widgetIdsArray =
+ {WIDGET_ID_WITH_SHORTCUT, WIDGET_ID_WITHOUT_SHORTCUT, WIDGET_ID_WITH_SAME_URI};
+ when(mAppWidgetManager.getAppWidgetIds(any())).thenReturn(widgetIdsArray);
+
+ Notification notificationWithPersonOnlyInSender =
+ createMessagingStyleNotificationWithoutExtras(
+ SHORTCUT_ID, /* isMessagingStyle = */ true, /* isMissedCall = */
+ true).build();
+ StatusBarNotification sbn = new SbnBuilder()
+ .setNotification(notificationWithPersonOnlyInSender)
+ .setPkg(TEST_PACKAGE_A)
+ .setUid(0)
+ .setUser(new UserHandle(0))
+ .build();
+ NotifEvent notif1 = mNoMan.postNotif(new NotificationEntryBuilder()
+ .setSbn(sbn)
+ .setId(1));
+ mClock.advanceTime(MIN_LINGER_DURATION);
+
+ verify(mAppWidgetManager, times(1))
+ .updateAppWidgetOptions(eq(WIDGET_ID_WITH_SHORTCUT),
+ mBundleArgumentCaptor.capture());
+ Bundle bundle = requireNonNull(mBundleArgumentCaptor.getValue());
+ PeopleSpaceTile tileWithMissedCallOrigin = bundle.getParcelable(OPTIONS_PEOPLE_TILE);
+ assertThat(tileWithMissedCallOrigin.getNotificationKey()).isEqualTo(NOTIFICATION_KEY);
+ assertThat(tileWithMissedCallOrigin.getNotificationContent()).isEqualTo(
+ NOTIFICATION_CONTENT);
+ verify(mAppWidgetManager, times(1)).updateAppWidget(eq(WIDGET_ID_WITH_SHORTCUT),
+ any());
+ verify(mAppWidgetManager, times(1))
+ .updateAppWidgetOptions(eq(WIDGET_ID_WITH_SAME_URI),
+ mBundleArgumentCaptor.capture());
+ Bundle bundleForSameUriTile = requireNonNull(mBundleArgumentCaptor.getValue());
+ PeopleSpaceTile tileWithSameUri = bundleForSameUriTile.getParcelable(OPTIONS_PEOPLE_TILE);
+ assertThat(tileWithSameUri.getNotificationKey()).isEqualTo(NOTIFICATION_KEY);
+ assertThat(tileWithSameUri.getNotificationContent()).isEqualTo(NOTIFICATION_CONTENT);
+ verify(mAppWidgetManager, times(1)).updateAppWidget(eq(WIDGET_ID_WITH_SAME_URI),
+ any());
+ }
+
+ @Test
+ public void testDoNotUpdateMissedCallNotificationWithContentPostedIfNoPersonsAttached()
+ throws Exception {
+ int[] widgetIdsArray =
+ {WIDGET_ID_WITH_SHORTCUT, WIDGET_ID_WITHOUT_SHORTCUT, WIDGET_ID_WITH_SAME_URI};
+ when(mAppWidgetManager.getAppWidgetIds(any())).thenReturn(widgetIdsArray);
+
+ // Notification posted without any Person attached.
+ Notification notificationWithoutPersonObject =
+ createMessagingStyleNotificationWithoutExtras(
+ SHORTCUT_ID, /* isMessagingStyle = */ true, /* isMissedCall = */
+ true).setStyle(new Notification.MessagingStyle("sender")
+ .addMessage(
+ new Notification.MessagingStyle.Message(NOTIFICATION_CONTENT, 10,
+ "sender"))
+ ).build();
+ StatusBarNotification sbn = new SbnBuilder()
+ .setNotification(notificationWithoutPersonObject)
+ .setPkg(TEST_PACKAGE_A)
+ .setUid(0)
+ .setUser(new UserHandle(0))
+ .build();
+ NotifEvent notif1 = mNoMan.postNotif(new NotificationEntryBuilder()
+ .setSbn(sbn)
+ .setId(1));
+ mClock.advanceTime(MIN_LINGER_DURATION);
+
+ verify(mAppWidgetManager, times(1))
+ .updateAppWidgetOptions(eq(WIDGET_ID_WITH_SHORTCUT),
+ mBundleArgumentCaptor.capture());
+ Bundle bundle = requireNonNull(mBundleArgumentCaptor.getValue());
+ PeopleSpaceTile tileWithMissedCallOrigin = bundle.getParcelable(OPTIONS_PEOPLE_TILE);
+ assertThat(tileWithMissedCallOrigin.getNotificationKey()).isEqualTo(NOTIFICATION_KEY);
+ assertThat(tileWithMissedCallOrigin.getNotificationContent()).isEqualTo(
+ NOTIFICATION_CONTENT);
+ verify(mAppWidgetManager, times(1)).updateAppWidget(eq(WIDGET_ID_WITH_SHORTCUT),
+ any());
+ // Do not update since notification doesn't include a Person reference.
+ verify(mAppWidgetManager, times(0))
+ .updateAppWidgetOptions(eq(WIDGET_ID_WITH_SAME_URI),
+ any());
+ verify(mAppWidgetManager, times(0)).updateAppWidget(eq(WIDGET_ID_WITH_SAME_URI),
+ any());
+ }
+
+ @Test
+ public void testDoNotUpdateMissedCallNotificationWithContentPostedIfNotMatchingUriTile()
+ throws Exception {
+ clearStorage();
+ addTileForWidget(PERSON_TILE, WIDGET_ID_WITH_SHORTCUT);
+ addTileForWidget(PERSON_TILE_WITH_SAME_URI.toBuilder().setContactUri(
+ Uri.parse("different_uri")).build(), WIDGET_ID_WITH_DIFFERENT_URI);
+ int[] widgetIdsArray =
+ {WIDGET_ID_WITH_SHORTCUT, WIDGET_ID_WITHOUT_SHORTCUT, WIDGET_ID_WITH_DIFFERENT_URI};
+ when(mAppWidgetManager.getAppWidgetIds(any())).thenReturn(widgetIdsArray);
+
+ NotifEvent notif1 = mNoMan.postNotif(new NotificationEntryBuilder()
+ .setSbn(createNotification(
+ SHORTCUT_ID, /* isMessagingStyle = */ true, /* isMissedCall = */ true))
+ .setId(1));
+ mClock.advanceTime(MIN_LINGER_DURATION);
+
+ verify(mAppWidgetManager, times(1))
+ .updateAppWidgetOptions(eq(WIDGET_ID_WITH_SHORTCUT),
+ mBundleArgumentCaptor.capture());
+ Bundle bundle = requireNonNull(mBundleArgumentCaptor.getValue());
+ PeopleSpaceTile tileWithMissedCallOrigin = bundle.getParcelable(OPTIONS_PEOPLE_TILE);
+ assertThat(tileWithMissedCallOrigin.getNotificationKey()).isEqualTo(NOTIFICATION_KEY);
+ assertThat(tileWithMissedCallOrigin.getNotificationContent()).isEqualTo(
+ NOTIFICATION_CONTENT);
+ verify(mAppWidgetManager, times(1)).updateAppWidget(eq(WIDGET_ID_WITH_SHORTCUT),
+ any());
+ // Do not update since missing permission to read contacts.
+ verify(mAppWidgetManager, times(0))
+ .updateAppWidgetOptions(eq(WIDGET_ID_WITH_DIFFERENT_URI),
+ any());
+ verify(mAppWidgetManager, times(0)).updateAppWidget(eq(WIDGET_ID_WITH_DIFFERENT_URI),
+ any());
+ }
+
+ @Test
+ public void testDoNotUpdateMissedCallIfMatchingUriTileMissingReadContactsPermission()
+ throws Exception {
+ when(mPackageManager.checkPermission(any(),
+ eq(PERSON_TILE_WITH_SAME_URI.getPackageName()))).thenReturn(
+ PERMISSION_HARD_DENIED);
+ int[] widgetIdsArray =
+ {WIDGET_ID_WITH_SHORTCUT, WIDGET_ID_WITHOUT_SHORTCUT, WIDGET_ID_WITH_SAME_URI};
+ when(mAppWidgetManager.getAppWidgetIds(any())).thenReturn(widgetIdsArray);
+
+ NotifEvent notif1 = mNoMan.postNotif(new NotificationEntryBuilder()
+ .setSbn(createNotification(
+ SHORTCUT_ID, /* isMessagingStyle = */ true, /* isMissedCall = */ true))
+ .setId(1));
+ mClock.advanceTime(MIN_LINGER_DURATION);
+
+ verify(mAppWidgetManager, times(1))
+ .updateAppWidgetOptions(eq(WIDGET_ID_WITH_SHORTCUT),
+ mBundleArgumentCaptor.capture());
+ Bundle bundle = requireNonNull(mBundleArgumentCaptor.getValue());
+ PeopleSpaceTile tileWithMissedCallOrigin = bundle.getParcelable(OPTIONS_PEOPLE_TILE);
+ assertThat(tileWithMissedCallOrigin.getNotificationKey()).isEqualTo(NOTIFICATION_KEY);
+ assertThat(tileWithMissedCallOrigin.getNotificationContent()).isEqualTo(
+ NOTIFICATION_CONTENT);
+ verify(mAppWidgetManager, times(1)).updateAppWidget(eq(WIDGET_ID_WITH_SHORTCUT),
+ any());
+ // Do not update since missing permission to read contacts.
+ verify(mAppWidgetManager, times(0))
+ .updateAppWidgetOptions(eq(WIDGET_ID_WITH_SAME_URI),
+ any());
+ verify(mAppWidgetManager, times(0)).updateAppWidget(eq(WIDGET_ID_WITH_SAME_URI),
+ any());
+ }
+
+ @Test
public void testUpdateNotificationRemovedIfExistingTile() throws Exception {
int[] widgetIdsArray = {WIDGET_ID_WITH_SHORTCUT, WIDGET_ID_WITHOUT_SHORTCUT};
when(mAppWidgetManager.getAppWidgetIds(any())).thenReturn(widgetIdsArray);
- setStorageForTile(SHORTCUT_ID, TEST_PACKAGE_A, WIDGET_ID_WITH_SHORTCUT);
StatusBarNotification sbn = createNotification(
SHORTCUT_ID, /* isMessagingStyle = */ true, /* isMissedCall = */ false);
@@ -574,7 +843,8 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
}
@Test
- public void testDeleteAllWidgetsForConversationsUncachesShortcutAndRemovesListeners() {
+ public void testDeleteAllWidgetsForConversationsUncachesShortcutAndRemovesListeners()
+ throws Exception {
addSecondWidgetForPersonTile();
mProvider.onUpdate(mContext, mAppWidgetManager,
new int[]{WIDGET_ID_WITH_SHORTCUT, SECOND_WIDGET_ID_WITH_SHORTCUT});
@@ -746,19 +1016,26 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
* Adds another widget for {@code PERSON_TILE} with widget ID: {@code
* SECOND_WIDGET_ID_WITH_SHORTCUT}.
*/
- private void addSecondWidgetForPersonTile() {
- Bundle options = new Bundle();
- options.putParcelable(OPTIONS_PEOPLE_TILE, PERSON_TILE);
- when(mAppWidgetManager.getAppWidgetOptions(eq(SECOND_WIDGET_ID_WITH_SHORTCUT)))
- .thenReturn(options);
+ private void addSecondWidgetForPersonTile() throws Exception {
// Set the same Person associated on another People Tile widget ID.
- setStorageForTile(SHORTCUT_ID, TEST_PACKAGE_A, WIDGET_ID_WITH_SHORTCUT);
- setStorageForTile(SHORTCUT_ID, TEST_PACKAGE_A, SECOND_WIDGET_ID_WITH_SHORTCUT);
+ addTileForWidget(PERSON_TILE, SECOND_WIDGET_ID_WITH_SHORTCUT);
int[] widgetIdsArray = {WIDGET_ID_WITH_SHORTCUT, WIDGET_ID_WITHOUT_SHORTCUT,
SECOND_WIDGET_ID_WITH_SHORTCUT};
when(mAppWidgetManager.getAppWidgetIds(any())).thenReturn(widgetIdsArray);
}
+ private void addTileForWidget(PeopleSpaceTile tile, int widgetId) throws Exception {
+ setStorageForTile(tile.getId(), tile.getPackageName(), widgetId, tile.getContactUri());
+ Bundle options = new Bundle();
+ options.putParcelable(OPTIONS_PEOPLE_TILE, tile);
+ when(mAppWidgetManager.getAppWidgetOptions(eq(widgetId)))
+ .thenReturn(options);
+ when(mIPeopleManager.getConversation(tile.getPackageName(), 0, tile.getId())).thenReturn(
+ getConversationWithShortcutId(tile.getId()));
+ when(mPackageManager.checkPermission(any(), eq(tile.getPackageName()))).thenReturn(
+ PERMISSION_GRANTED);
+ }
+
/**
* Returns a single conversation associated with {@code shortcutId}.
*/
@@ -772,7 +1049,7 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
private ConversationChannel getConversationWithShortcutId(String shortcutId,
List<ConversationStatus> statuses) throws Exception {
ShortcutInfo shortcutInfo = new ShortcutInfo.Builder(mContext, shortcutId).setLongLabel(
- "name").build();
+ "name").setPerson(PERSON).build();
ConversationChannel convo = new ConversationChannel(shortcutInfo, 0, null, null,
0L, false, false, statuses);
return convo;
@@ -780,9 +1057,14 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
private Notification createMessagingStyleNotification(String shortcutId,
boolean isMessagingStyle, boolean isMissedCall) {
+ Bundle extras = new Bundle();
+ ArrayList<Person> person = new ArrayList<Person>();
+ person.add(PERSON);
+ extras.putParcelableArrayList(EXTRA_PEOPLE_LIST, person);
Notification.Builder builder = new Notification.Builder(mContext)
.setContentTitle("TEST_TITLE")
.setContentText("TEST_TEXT")
+ .setExtras(extras)
.setShortcutId(shortcutId);
if (isMessagingStyle) {
builder.setStyle(new Notification.MessagingStyle(PERSON)
@@ -797,6 +1079,26 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
return builder.build();
}
+ private Notification.Builder createMessagingStyleNotificationWithoutExtras(String shortcutId,
+ boolean isMessagingStyle, boolean isMissedCall) {
+ Notification.Builder builder = new Notification.Builder(mContext)
+ .setContentTitle("TEST_TITLE")
+ .setContentText("TEST_TEXT")
+ .setShortcutId(shortcutId);
+ if (isMessagingStyle) {
+ builder.setStyle(new Notification.MessagingStyle(PERSON)
+ .addMessage(
+ new Notification.MessagingStyle.Message(NOTIFICATION_CONTENT, 10,
+ PERSON))
+ );
+ }
+ if (isMissedCall) {
+ builder.setCategory(CATEGORY_MISSED_CALL);
+ }
+ return builder;
+ }
+
+
private StatusBarNotification createNotification(String shortcutId,
boolean isMessagingStyle, boolean isMissedCall) {
Notification notification = createMessagingStyleNotification(
@@ -804,6 +1106,8 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
return new SbnBuilder()
.setNotification(notification)
.setPkg(TEST_PACKAGE_A)
+ .setUid(0)
+ .setUser(new UserHandle(0))
.build();
}
@@ -824,11 +1128,16 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
String.valueOf(WIDGET_ID_WITH_KEY_IN_OPTIONS),
Context.MODE_PRIVATE);
widgetSp4.edit().clear().commit();
+ SharedPreferences widgetSp5 = mContext.getSharedPreferences(
+ String.valueOf(WIDGET_ID_WITH_SAME_URI),
+ Context.MODE_PRIVATE);
+ widgetSp5.edit().clear().commit();
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mContext);
sp.edit().clear().commit();
}
- private void setStorageForTile(String shortcutId, String packageName, int widgetId) {
+ private void setStorageForTile(String shortcutId, String packageName, int widgetId,
+ Uri contactUri) {
SharedPreferences widgetSp = mContext.getSharedPreferences(
String.valueOf(widgetId),
Context.MODE_PRIVATE);
@@ -840,11 +1149,17 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mContext);
SharedPreferences.Editor editor = sp.edit();
- editor.putString(String.valueOf(widgetId), shortcutId);
+ editor.putString(String.valueOf(widgetId), contactUri.toString());
+
String key = new PeopleTileKey(shortcutId, 0, packageName).toString();
Set<String> storedWidgetIds = new HashSet<>(sp.getStringSet(key, new HashSet<>()));
storedWidgetIds.add(String.valueOf(widgetId));
editor.putStringSet(key, storedWidgetIds);
+
+ Set<String> storedWidgetIdsByUri = new HashSet<>(
+ sp.getStringSet(contactUri.toString(), new HashSet<>()));
+ storedWidgetIdsByUri.add(String.valueOf(widgetId));
+ editor.putStringSet(contactUri.toString(), storedWidgetIdsByUri);
editor.apply();
}
}