Merge "Merge Missed calls onto tiles by Contact Uri" into sc-dev
This commit is contained in:
@@ -16,9 +16,9 @@
|
|||||||
|
|
||||||
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
|
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
android:minWidth="120dp"
|
android:minWidth="120dp"
|
||||||
android:minHeight="54dp"
|
android:minHeight="50dp"
|
||||||
android:minResizeWidth="60dp"
|
android:minResizeWidth="60dp"
|
||||||
android:minResizeHeight="54dp"
|
android:minResizeHeight="50dp"
|
||||||
android:maxResizeHeight="207dp"
|
android:maxResizeHeight="207dp"
|
||||||
android:updatePeriodMillis="60000"
|
android:updatePeriodMillis="60000"
|
||||||
android:description="@string/people_tile_description"
|
android:description="@string/people_tile_description"
|
||||||
|
|||||||
@@ -175,7 +175,7 @@ public class PeopleSpaceUtils {
|
|||||||
|
|
||||||
/** Sets all relevant storage for {@code appWidgetId} association to {@code tile}. */
|
/** Sets all relevant storage for {@code appWidgetId} association to {@code tile}. */
|
||||||
public static void setSharedPreferencesStorageForTile(Context context, PeopleTileKey key,
|
public static void setSharedPreferencesStorageForTile(Context context, PeopleTileKey key,
|
||||||
int appWidgetId) {
|
int appWidgetId, Uri contactUri) {
|
||||||
// Write relevant persisted storage.
|
// Write relevant persisted storage.
|
||||||
SharedPreferences widgetSp = context.getSharedPreferences(String.valueOf(appWidgetId),
|
SharedPreferences widgetSp = context.getSharedPreferences(String.valueOf(appWidgetId),
|
||||||
Context.MODE_PRIVATE);
|
Context.MODE_PRIVATE);
|
||||||
@@ -186,27 +186,24 @@ public class PeopleSpaceUtils {
|
|||||||
widgetEditor.apply();
|
widgetEditor.apply();
|
||||||
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
|
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
|
||||||
SharedPreferences.Editor editor = sp.edit();
|
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.
|
// Don't overwrite existing widgets with the same key.
|
||||||
Set<String> storedWidgetIds = new HashSet<>(
|
addAppWidgetIdForKey(sp, editor, appWidgetId, key.toString());
|
||||||
sp.getStringSet(key.toString(), new HashSet<>()));
|
addAppWidgetIdForKey(sp, editor, appWidgetId, contactUriString);
|
||||||
storedWidgetIds.add(String.valueOf(appWidgetId));
|
|
||||||
editor.putStringSet(key.toString(), storedWidgetIds);
|
|
||||||
editor.apply();
|
editor.apply();
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Removes stored data when tile is deleted. */
|
/** Removes stored data when tile is deleted. */
|
||||||
public static void removeSharedPreferencesStorageForTile(Context context, PeopleTileKey key,
|
public static void removeSharedPreferencesStorageForTile(Context context, PeopleTileKey key,
|
||||||
int widgetId) {
|
int widgetId, String contactUriString) {
|
||||||
// Delete widgetId mapping to key.
|
// Delete widgetId mapping to key.
|
||||||
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
|
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
|
||||||
SharedPreferences.Editor editor = sp.edit();
|
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));
|
editor.remove(String.valueOf(widgetId));
|
||||||
|
removeAppWidgetIdForKey(sp, editor, widgetId, key.toString());
|
||||||
|
removeAppWidgetIdForKey(sp, editor, widgetId, contactUriString);
|
||||||
editor.apply();
|
editor.apply();
|
||||||
|
|
||||||
// Delete all data specifically mapped to widgetId.
|
// Delete all data specifically mapped to widgetId.
|
||||||
@@ -219,6 +216,23 @@ public class PeopleSpaceUtils {
|
|||||||
widgetEditor.apply();
|
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. */
|
/** Augments a single {@link PeopleSpaceTile} with notification content, if one is present. */
|
||||||
public static PeopleSpaceTile augmentSingleTileFromVisibleNotifications(Context context,
|
public static PeopleSpaceTile augmentSingleTileFromVisibleNotifications(Context context,
|
||||||
PeopleSpaceTile tile, NotificationEntryManager notificationEntryManager) {
|
PeopleSpaceTile tile, NotificationEntryManager notificationEntryManager) {
|
||||||
@@ -256,7 +270,7 @@ public class PeopleSpaceUtils {
|
|||||||
PeopleSpaceTile tile, Map<PeopleTileKey, NotificationEntry> visibleNotifications) {
|
PeopleSpaceTile tile, Map<PeopleTileKey, NotificationEntry> visibleNotifications) {
|
||||||
PeopleTileKey key = new PeopleTileKey(
|
PeopleTileKey key = new PeopleTileKey(
|
||||||
tile.getId(), getUserId(tile), tile.getPackageName());
|
tile.getId(), getUserId(tile), tile.getPackageName());
|
||||||
|
// TODO: Match missed calls with matching Uris in addition to keys.
|
||||||
if (!visibleNotifications.containsKey(key)) {
|
if (!visibleNotifications.containsKey(key)) {
|
||||||
if (DEBUG) Log.d(TAG, "No existing notifications for key:" + key.toString());
|
if (DEBUG) Log.d(TAG, "No existing notifications for key:" + key.toString());
|
||||||
return tile;
|
return tile;
|
||||||
|
|||||||
@@ -16,17 +16,23 @@
|
|||||||
|
|
||||||
package com.android.systemui.people.widget;
|
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.EMPTY_STRING;
|
||||||
import static com.android.systemui.people.PeopleSpaceUtils.INVALID_USER_ID;
|
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.PACKAGE_NAME;
|
||||||
import static com.android.systemui.people.PeopleSpaceUtils.SHORTCUT_ID;
|
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.USER_ID;
|
||||||
import static com.android.systemui.people.PeopleSpaceUtils.augmentTileFromNotification;
|
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.getStoredWidgetIds;
|
||||||
import static com.android.systemui.people.PeopleSpaceUtils.updateAppWidgetOptionsAndView;
|
import static com.android.systemui.people.PeopleSpaceUtils.updateAppWidgetOptionsAndView;
|
||||||
import static com.android.systemui.people.PeopleSpaceUtils.updateAppWidgetViews;
|
import static com.android.systemui.people.PeopleSpaceUtils.updateAppWidgetViews;
|
||||||
|
|
||||||
import android.annotation.Nullable;
|
import android.annotation.Nullable;
|
||||||
|
import android.app.Notification;
|
||||||
import android.app.NotificationChannel;
|
import android.app.NotificationChannel;
|
||||||
import android.app.PendingIntent;
|
import android.app.PendingIntent;
|
||||||
import android.app.Person;
|
import android.app.Person;
|
||||||
@@ -39,6 +45,7 @@ import android.content.ComponentName;
|
|||||||
import android.content.Context;
|
import android.content.Context;
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
import android.content.pm.LauncherApps;
|
import android.content.pm.LauncherApps;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
import android.content.pm.ShortcutInfo;
|
import android.content.pm.ShortcutInfo;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
import android.os.Bundle;
|
import android.os.Bundle;
|
||||||
@@ -54,16 +61,20 @@ import com.android.internal.annotations.GuardedBy;
|
|||||||
import com.android.internal.annotations.VisibleForTesting;
|
import com.android.internal.annotations.VisibleForTesting;
|
||||||
import com.android.internal.logging.UiEventLogger;
|
import com.android.internal.logging.UiEventLogger;
|
||||||
import com.android.internal.logging.UiEventLoggerImpl;
|
import com.android.internal.logging.UiEventLoggerImpl;
|
||||||
|
import com.android.settingslib.utils.ThreadUtils;
|
||||||
import com.android.systemui.Dependency;
|
import com.android.systemui.Dependency;
|
||||||
import com.android.systemui.people.PeopleSpaceUtils;
|
import com.android.systemui.people.PeopleSpaceUtils;
|
||||||
import com.android.systemui.statusbar.NotificationListener;
|
import com.android.systemui.statusbar.NotificationListener;
|
||||||
import com.android.systemui.statusbar.NotificationListener.NotificationHandler;
|
import com.android.systemui.statusbar.NotificationListener.NotificationHandler;
|
||||||
import com.android.systemui.statusbar.notification.NotificationEntryManager;
|
import com.android.systemui.statusbar.notification.NotificationEntryManager;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Objects;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import javax.inject.Inject;
|
import javax.inject.Inject;
|
||||||
@@ -83,11 +94,19 @@ public class PeopleSpaceWidgetManager {
|
|||||||
private SharedPreferences mSharedPrefs;
|
private SharedPreferences mSharedPrefs;
|
||||||
private PeopleManager mPeopleManager;
|
private PeopleManager mPeopleManager;
|
||||||
private NotificationEntryManager mNotificationEntryManager;
|
private NotificationEntryManager mNotificationEntryManager;
|
||||||
|
private PackageManager mPackageManager;
|
||||||
public UiEventLogger mUiEventLogger = new UiEventLoggerImpl();
|
public UiEventLogger mUiEventLogger = new UiEventLoggerImpl();
|
||||||
@GuardedBy("mLock")
|
@GuardedBy("mLock")
|
||||||
public static Map<PeopleTileKey, PeopleSpaceWidgetProvider.TileConversationListener>
|
public static Map<PeopleTileKey, PeopleSpaceWidgetProvider.TileConversationListener>
|
||||||
mListeners = new HashMap<>();
|
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
|
@Inject
|
||||||
public PeopleSpaceWidgetManager(Context context) {
|
public PeopleSpaceWidgetManager(Context context) {
|
||||||
if (DEBUG) Log.d(TAG, "constructor");
|
if (DEBUG) Log.d(TAG, "constructor");
|
||||||
@@ -99,6 +118,7 @@ public class PeopleSpaceWidgetManager {
|
|||||||
mSharedPrefs = PreferenceManager.getDefaultSharedPreferences(mContext);
|
mSharedPrefs = PreferenceManager.getDefaultSharedPreferences(mContext);
|
||||||
mPeopleManager = mContext.getSystemService(PeopleManager.class);
|
mPeopleManager = mContext.getSystemService(PeopleManager.class);
|
||||||
mNotificationEntryManager = Dependency.get(NotificationEntryManager.class);
|
mNotificationEntryManager = Dependency.get(NotificationEntryManager.class);
|
||||||
|
mPackageManager = mContext.getPackageManager();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -108,12 +128,15 @@ public class PeopleSpaceWidgetManager {
|
|||||||
protected void setAppWidgetManager(
|
protected void setAppWidgetManager(
|
||||||
AppWidgetManager appWidgetManager, IPeopleManager iPeopleManager,
|
AppWidgetManager appWidgetManager, IPeopleManager iPeopleManager,
|
||||||
PeopleManager peopleManager, LauncherApps launcherApps,
|
PeopleManager peopleManager, LauncherApps launcherApps,
|
||||||
NotificationEntryManager notificationEntryManager) {
|
NotificationEntryManager notificationEntryManager, PackageManager packageManager,
|
||||||
|
boolean isForTesting) {
|
||||||
mAppWidgetManager = appWidgetManager;
|
mAppWidgetManager = appWidgetManager;
|
||||||
mIPeopleManager = iPeopleManager;
|
mIPeopleManager = iPeopleManager;
|
||||||
mPeopleManager = peopleManager;
|
mPeopleManager = peopleManager;
|
||||||
mLauncherApps = launcherApps;
|
mLauncherApps = launcherApps;
|
||||||
mNotificationEntryManager = notificationEntryManager;
|
mNotificationEntryManager = notificationEntryManager;
|
||||||
|
mPackageManager = packageManager;
|
||||||
|
mIsForTesting = isForTesting;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -222,6 +245,16 @@ public class PeopleSpaceWidgetManager {
|
|||||||
public void updateWidgetsWithNotificationChanged(StatusBarNotification sbn,
|
public void updateWidgetsWithNotificationChanged(StatusBarNotification sbn,
|
||||||
PeopleSpaceUtils.NotificationAction notificationAction) {
|
PeopleSpaceUtils.NotificationAction notificationAction) {
|
||||||
if (DEBUG) Log.d(TAG, "updateWidgetsWithNotificationChanged called");
|
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 {
|
try {
|
||||||
String sbnShortcutId = sbn.getShortcutId();
|
String sbnShortcutId = sbn.getShortcutId();
|
||||||
if (sbnShortcutId == null) {
|
if (sbnShortcutId == null) {
|
||||||
@@ -235,23 +268,175 @@ public class PeopleSpaceWidgetManager {
|
|||||||
Log.d(TAG, "No app widget ids returned");
|
Log.d(TAG, "No app widget ids returned");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
PeopleTileKey key = new PeopleTileKey(
|
||||||
|
sbnShortcutId,
|
||||||
|
sbn.getUser().getIdentifier(),
|
||||||
|
sbn.getPackageName());
|
||||||
|
if (!key.isValid()) {
|
||||||
|
Log.d(TAG, "Invalid key");
|
||||||
|
return;
|
||||||
|
}
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
PeopleTileKey key = new PeopleTileKey(
|
// First, update People Tiles associated with the Notification's package/shortcut.
|
||||||
sbnShortcutId,
|
Set<String> tilesUpdatedByKey = getStoredWidgetIds(mSharedPrefs, key);
|
||||||
UserHandle.getUserHandleForUid(sbn.getUid()).getIdentifier(),
|
updateWidgetIdsForNotificationAction(tilesUpdatedByKey, sbn, action);
|
||||||
sbn.getPackageName());
|
|
||||||
Set<String> storedWidgetIds = getStoredWidgetIds(mSharedPrefs, key);
|
// Then, update People Tiles across other packages that use the same Uri.
|
||||||
for (String widgetIdString : storedWidgetIds) {
|
updateTilesByUri(key, sbn, action);
|
||||||
int widgetId = Integer.parseInt(widgetIdString);
|
|
||||||
if (DEBUG) Log.d(TAG, "Storing notification change, key:" + sbn.getKey());
|
|
||||||
updateStorageAndViewWithNotificationData(sbn, notificationAction, widgetId);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
Log.e(TAG, "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.
|
* Update the tiles associated with the incoming conversation update.
|
||||||
*/
|
*/
|
||||||
@@ -309,16 +494,11 @@ public class PeopleSpaceWidgetManager {
|
|||||||
private void updateStorageAndViewWithNotificationData(
|
private void updateStorageAndViewWithNotificationData(
|
||||||
StatusBarNotification sbn,
|
StatusBarNotification sbn,
|
||||||
PeopleSpaceUtils.NotificationAction notificationAction,
|
PeopleSpaceUtils.NotificationAction notificationAction,
|
||||||
int appWidgetId) {
|
int appWidgetId, PeopleSpaceTile storedTile) {
|
||||||
PeopleSpaceTile storedTile = getTileForExistingWidget(appWidgetId);
|
|
||||||
if (storedTile == null) {
|
|
||||||
if (DEBUG) Log.d(TAG, "Could not find stored tile to add notification to");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (notificationAction == PeopleSpaceUtils.NotificationAction.POSTED) {
|
if (notificationAction == PeopleSpaceUtils.NotificationAction.POSTED) {
|
||||||
if (DEBUG) Log.i(TAG, "Adding notification to storage, appWidgetId: " + appWidgetId);
|
if (DEBUG) Log.i(TAG, "Adding notification to storage, appWidgetId: " + appWidgetId);
|
||||||
storedTile = augmentTileFromNotification(mContext, storedTile, sbn);
|
storedTile = augmentTileFromNotification(mContext, storedTile, sbn);
|
||||||
} else {
|
} else if (storedTile.getNotificationKey().equals(sbn.getKey())) {
|
||||||
if (DEBUG) {
|
if (DEBUG) {
|
||||||
Log.i(TAG, "Removing notification from storage, appWidgetId: " + appWidgetId);
|
Log.i(TAG, "Removing notification from storage, appWidgetId: " + appWidgetId);
|
||||||
}
|
}
|
||||||
@@ -440,7 +620,8 @@ public class PeopleSpaceWidgetManager {
|
|||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
if (DEBUG) Log.d(TAG, "Add storage for : " + tile.getId());
|
if (DEBUG) Log.d(TAG, "Add storage for : " + tile.getId());
|
||||||
PeopleTileKey key = new PeopleTileKey(tile);
|
PeopleTileKey key = new PeopleTileKey(tile);
|
||||||
PeopleSpaceUtils.setSharedPreferencesStorageForTile(mContext, key, appWidgetId);
|
PeopleSpaceUtils.setSharedPreferencesStorageForTile(mContext, key, appWidgetId,
|
||||||
|
tile.getContactUri());
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
if (DEBUG) Log.d(TAG, "Caching shortcut for PeopleTile: " + tile.getId());
|
if (DEBUG) Log.d(TAG, "Caching shortcut for PeopleTile: " + tile.getId());
|
||||||
@@ -496,6 +677,7 @@ public class PeopleSpaceWidgetManager {
|
|||||||
// Retrieve storage needed for widget deletion.
|
// Retrieve storage needed for widget deletion.
|
||||||
PeopleTileKey key;
|
PeopleTileKey key;
|
||||||
Set<String> storedWidgetIdsForKey;
|
Set<String> storedWidgetIdsForKey;
|
||||||
|
String contactUriString;
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
SharedPreferences widgetSp = mContext.getSharedPreferences(String.valueOf(widgetId),
|
SharedPreferences widgetSp = mContext.getSharedPreferences(String.valueOf(widgetId),
|
||||||
Context.MODE_PRIVATE);
|
Context.MODE_PRIVATE);
|
||||||
@@ -509,9 +691,11 @@ public class PeopleSpaceWidgetManager {
|
|||||||
}
|
}
|
||||||
storedWidgetIdsForKey = new HashSet<>(
|
storedWidgetIdsForKey = new HashSet<>(
|
||||||
mSharedPrefs.getStringSet(key.toString(), new HashSet<>()));
|
mSharedPrefs.getStringSet(key.toString(), new HashSet<>()));
|
||||||
|
contactUriString = mSharedPrefs.getString(String.valueOf(widgetId), null);
|
||||||
}
|
}
|
||||||
synchronized (mLock) {
|
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 another tile with the conversation is still stored, we need to keep the listener.
|
||||||
if (DEBUG) Log.d(TAG, "Stored widget IDs: " + storedWidgetIdsForKey.toString());
|
if (DEBUG) Log.d(TAG, "Stored widget IDs: " + storedWidgetIdsForKey.toString());
|
||||||
|
|||||||
@@ -17,11 +17,14 @@
|
|||||||
package com.android.systemui.people.widget;
|
package com.android.systemui.people.widget;
|
||||||
|
|
||||||
import static android.app.Notification.CATEGORY_MISSED_CALL;
|
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_DEFAULT;
|
||||||
import static android.app.NotificationManager.IMPORTANCE_HIGH;
|
import static android.app.NotificationManager.IMPORTANCE_HIGH;
|
||||||
import static android.app.people.ConversationStatus.ACTIVITY_ANNIVERSARY;
|
import static android.app.people.ConversationStatus.ACTIVITY_ANNIVERSARY;
|
||||||
import static android.app.people.ConversationStatus.ACTIVITY_BIRTHDAY;
|
import static android.app.people.ConversationStatus.ACTIVITY_BIRTHDAY;
|
||||||
import static android.app.people.ConversationStatus.ACTIVITY_GAME;
|
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.EMPTY_STRING;
|
||||||
import static com.android.systemui.people.PeopleSpaceUtils.INVALID_USER_ID;
|
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.Intent;
|
||||||
import android.content.SharedPreferences;
|
import android.content.SharedPreferences;
|
||||||
import android.content.pm.LauncherApps;
|
import android.content.pm.LauncherApps;
|
||||||
|
import android.content.pm.PackageManager;
|
||||||
import android.content.pm.ShortcutInfo;
|
import android.content.pm.ShortcutInfo;
|
||||||
import android.graphics.drawable.Icon;
|
import android.graphics.drawable.Icon;
|
||||||
import android.net.Uri;
|
import android.net.Uri;
|
||||||
@@ -86,6 +90,7 @@ import org.mockito.Captor;
|
|||||||
import org.mockito.Mock;
|
import org.mockito.Mock;
|
||||||
import org.mockito.MockitoAnnotations;
|
import org.mockito.MockitoAnnotations;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
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 SECOND_WIDGET_ID_WITH_SHORTCUT = 3;
|
||||||
private static final int WIDGET_ID_WITHOUT_SHORTCUT = 2;
|
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_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 SHORTCUT_ID = "101";
|
||||||
private static final String OTHER_SHORTCUT_ID = "102";
|
private static final String OTHER_SHORTCUT_ID = "102";
|
||||||
private static final String NOTIFICATION_KEY = "0|com.android.systemui.tests|0|null|0";
|
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
|
new PeopleSpaceTile
|
||||||
.Builder(SHORTCUT_ID, "username", ICON, new Intent())
|
.Builder(SHORTCUT_ID, "username", ICON, new Intent())
|
||||||
.setPackageName(TEST_PACKAGE_A)
|
.setPackageName(TEST_PACKAGE_A)
|
||||||
.setUserHandle(new UserHandle(1))
|
.setUserHandle(new UserHandle(0))
|
||||||
.setNotificationKey(NOTIFICATION_KEY + "1")
|
.setNotificationKey(NOTIFICATION_KEY + "1")
|
||||||
.setNotificationContent(NOTIFICATION_CONTENT)
|
.setNotificationContent(NOTIFICATION_CONTENT)
|
||||||
.setNotificationDataUri(URI)
|
.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();
|
.build();
|
||||||
private final ShortcutInfo mShortcutInfo = new ShortcutInfo.Builder(mContext,
|
private final ShortcutInfo mShortcutInfo = new ShortcutInfo.Builder(mContext,
|
||||||
SHORTCUT_ID).setLongLabel("name").build();
|
SHORTCUT_ID).setLongLabel("name").build();
|
||||||
@@ -149,6 +167,8 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
|
|||||||
private LauncherApps mLauncherApps;
|
private LauncherApps mLauncherApps;
|
||||||
@Mock
|
@Mock
|
||||||
private NotificationEntryManager mNotificationEntryManager;
|
private NotificationEntryManager mNotificationEntryManager;
|
||||||
|
@Mock
|
||||||
|
private PackageManager mPackageManager;
|
||||||
|
|
||||||
@Captor
|
@Captor
|
||||||
private ArgumentCaptor<NotificationHandler> mListenerCaptor;
|
private ArgumentCaptor<NotificationHandler> mListenerCaptor;
|
||||||
@@ -167,7 +187,7 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
|
|||||||
mDependency.injectTestDependency(NotificationEntryManager.class, mNotificationEntryManager);
|
mDependency.injectTestDependency(NotificationEntryManager.class, mNotificationEntryManager);
|
||||||
mManager = new PeopleSpaceWidgetManager(mContext);
|
mManager = new PeopleSpaceWidgetManager(mContext);
|
||||||
mManager.setAppWidgetManager(mAppWidgetManager, mIPeopleManager, mPeopleManager,
|
mManager.setAppWidgetManager(mAppWidgetManager, mIPeopleManager, mPeopleManager,
|
||||||
mLauncherApps, mNotificationEntryManager);
|
mLauncherApps, mNotificationEntryManager, mPackageManager, true);
|
||||||
mManager.attach(mListenerService);
|
mManager.attach(mListenerService);
|
||||||
mProvider = new PeopleSpaceWidgetProvider();
|
mProvider = new PeopleSpaceWidgetProvider();
|
||||||
mProvider.setPeopleSpaceWidgetManager(mManager);
|
mProvider.setPeopleSpaceWidgetManager(mManager);
|
||||||
@@ -177,16 +197,10 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
|
|||||||
mNoMan.addListener(serviceListener);
|
mNoMan.addListener(serviceListener);
|
||||||
|
|
||||||
clearStorage();
|
clearStorage();
|
||||||
setStorageForTile(SHORTCUT_ID, TEST_PACKAGE_A, WIDGET_ID_WITH_SHORTCUT);
|
addTileForWidget(PERSON_TILE, WIDGET_ID_WITH_SHORTCUT);
|
||||||
|
addTileForWidget(PERSON_TILE_WITH_SAME_URI, WIDGET_ID_WITH_SAME_URI);
|
||||||
Bundle options = new Bundle();
|
|
||||||
options.putParcelable(OPTIONS_PEOPLE_TILE, PERSON_TILE);
|
|
||||||
when(mAppWidgetManager.getAppWidgetOptions(eq(WIDGET_ID_WITH_SHORTCUT)))
|
|
||||||
.thenReturn(options);
|
|
||||||
when(mAppWidgetManager.getAppWidgetOptions(eq(WIDGET_ID_WITHOUT_SHORTCUT)))
|
when(mAppWidgetManager.getAppWidgetOptions(eq(WIDGET_ID_WITHOUT_SHORTCUT)))
|
||||||
.thenReturn(new Bundle());
|
.thenReturn(new Bundle());
|
||||||
when(mIPeopleManager.getConversation(TEST_PACKAGE_A, 0, SHORTCUT_ID)).thenReturn(
|
|
||||||
getConversationWithShortcutId(SHORTCUT_ID));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@@ -477,7 +491,7 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
|
|||||||
addSecondWidgetForPersonTile();
|
addSecondWidgetForPersonTile();
|
||||||
|
|
||||||
PeopleSpaceUtils.removeSharedPreferencesStorageForTile(
|
PeopleSpaceUtils.removeSharedPreferencesStorageForTile(
|
||||||
mContext, KEY, SECOND_WIDGET_ID_WITH_SHORTCUT);
|
mContext, KEY, SECOND_WIDGET_ID_WITH_SHORTCUT, EMPTY_STRING);
|
||||||
NotifEvent notif1 = mNoMan.postNotif(new NotificationEntryBuilder()
|
NotifEvent notif1 = mNoMan.postNotif(new NotificationEntryBuilder()
|
||||||
.setSbn(createNotification(
|
.setSbn(createNotification(
|
||||||
SHORTCUT_ID, /* isMessagingStyle = */ true, /* isMissedCall = */ false))
|
SHORTCUT_ID, /* isMessagingStyle = */ true, /* isMissedCall = */ false))
|
||||||
@@ -501,7 +515,6 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
|
|||||||
throws Exception {
|
throws Exception {
|
||||||
int[] widgetIdsArray = {WIDGET_ID_WITH_SHORTCUT, WIDGET_ID_WITHOUT_SHORTCUT};
|
int[] widgetIdsArray = {WIDGET_ID_WITH_SHORTCUT, WIDGET_ID_WITHOUT_SHORTCUT};
|
||||||
when(mAppWidgetManager.getAppWidgetIds(any())).thenReturn(widgetIdsArray);
|
when(mAppWidgetManager.getAppWidgetIds(any())).thenReturn(widgetIdsArray);
|
||||||
setStorageForTile(SHORTCUT_ID, TEST_PACKAGE_A, WIDGET_ID_WITH_SHORTCUT);
|
|
||||||
|
|
||||||
NotifEvent notif1 = mNoMan.postNotif(new NotificationEntryBuilder()
|
NotifEvent notif1 = mNoMan.postNotif(new NotificationEntryBuilder()
|
||||||
.setSbn(createNotification(
|
.setSbn(createNotification(
|
||||||
@@ -527,7 +540,6 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
|
|||||||
throws Exception {
|
throws Exception {
|
||||||
int[] widgetIdsArray = {WIDGET_ID_WITH_SHORTCUT, WIDGET_ID_WITHOUT_SHORTCUT};
|
int[] widgetIdsArray = {WIDGET_ID_WITH_SHORTCUT, WIDGET_ID_WITHOUT_SHORTCUT};
|
||||||
when(mAppWidgetManager.getAppWidgetIds(any())).thenReturn(widgetIdsArray);
|
when(mAppWidgetManager.getAppWidgetIds(any())).thenReturn(widgetIdsArray);
|
||||||
setStorageForTile(SHORTCUT_ID, TEST_PACKAGE_A, WIDGET_ID_WITH_SHORTCUT);
|
|
||||||
|
|
||||||
NotifEvent notif1 = mNoMan.postNotif(new NotificationEntryBuilder()
|
NotifEvent notif1 = mNoMan.postNotif(new NotificationEntryBuilder()
|
||||||
.setSbn(createNotification(
|
.setSbn(createNotification(
|
||||||
@@ -547,11 +559,268 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
|
|||||||
any());
|
any());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@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
|
@Test
|
||||||
public void testUpdateNotificationRemovedIfExistingTile() throws Exception {
|
public void testUpdateNotificationRemovedIfExistingTile() throws Exception {
|
||||||
int[] widgetIdsArray = {WIDGET_ID_WITH_SHORTCUT, WIDGET_ID_WITHOUT_SHORTCUT};
|
int[] widgetIdsArray = {WIDGET_ID_WITH_SHORTCUT, WIDGET_ID_WITHOUT_SHORTCUT};
|
||||||
when(mAppWidgetManager.getAppWidgetIds(any())).thenReturn(widgetIdsArray);
|
when(mAppWidgetManager.getAppWidgetIds(any())).thenReturn(widgetIdsArray);
|
||||||
setStorageForTile(SHORTCUT_ID, TEST_PACKAGE_A, WIDGET_ID_WITH_SHORTCUT);
|
|
||||||
|
|
||||||
StatusBarNotification sbn = createNotification(
|
StatusBarNotification sbn = createNotification(
|
||||||
SHORTCUT_ID, /* isMessagingStyle = */ true, /* isMissedCall = */ false);
|
SHORTCUT_ID, /* isMessagingStyle = */ true, /* isMissedCall = */ false);
|
||||||
@@ -574,7 +843,8 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testDeleteAllWidgetsForConversationsUncachesShortcutAndRemovesListeners() {
|
public void testDeleteAllWidgetsForConversationsUncachesShortcutAndRemovesListeners()
|
||||||
|
throws Exception {
|
||||||
addSecondWidgetForPersonTile();
|
addSecondWidgetForPersonTile();
|
||||||
mProvider.onUpdate(mContext, mAppWidgetManager,
|
mProvider.onUpdate(mContext, mAppWidgetManager,
|
||||||
new int[]{WIDGET_ID_WITH_SHORTCUT, SECOND_WIDGET_ID_WITH_SHORTCUT});
|
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
|
* Adds another widget for {@code PERSON_TILE} with widget ID: {@code
|
||||||
* SECOND_WIDGET_ID_WITH_SHORTCUT}.
|
* SECOND_WIDGET_ID_WITH_SHORTCUT}.
|
||||||
*/
|
*/
|
||||||
private void addSecondWidgetForPersonTile() {
|
private void addSecondWidgetForPersonTile() throws Exception {
|
||||||
Bundle options = new Bundle();
|
|
||||||
options.putParcelable(OPTIONS_PEOPLE_TILE, PERSON_TILE);
|
|
||||||
when(mAppWidgetManager.getAppWidgetOptions(eq(SECOND_WIDGET_ID_WITH_SHORTCUT)))
|
|
||||||
.thenReturn(options);
|
|
||||||
// Set the same Person associated on another People Tile widget ID.
|
// Set the same Person associated on another People Tile widget ID.
|
||||||
setStorageForTile(SHORTCUT_ID, TEST_PACKAGE_A, WIDGET_ID_WITH_SHORTCUT);
|
addTileForWidget(PERSON_TILE, SECOND_WIDGET_ID_WITH_SHORTCUT);
|
||||||
setStorageForTile(SHORTCUT_ID, TEST_PACKAGE_A, SECOND_WIDGET_ID_WITH_SHORTCUT);
|
|
||||||
int[] widgetIdsArray = {WIDGET_ID_WITH_SHORTCUT, WIDGET_ID_WITHOUT_SHORTCUT,
|
int[] widgetIdsArray = {WIDGET_ID_WITH_SHORTCUT, WIDGET_ID_WITHOUT_SHORTCUT,
|
||||||
SECOND_WIDGET_ID_WITH_SHORTCUT};
|
SECOND_WIDGET_ID_WITH_SHORTCUT};
|
||||||
when(mAppWidgetManager.getAppWidgetIds(any())).thenReturn(widgetIdsArray);
|
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}.
|
* Returns a single conversation associated with {@code shortcutId}.
|
||||||
*/
|
*/
|
||||||
@@ -772,7 +1049,7 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
|
|||||||
private ConversationChannel getConversationWithShortcutId(String shortcutId,
|
private ConversationChannel getConversationWithShortcutId(String shortcutId,
|
||||||
List<ConversationStatus> statuses) throws Exception {
|
List<ConversationStatus> statuses) throws Exception {
|
||||||
ShortcutInfo shortcutInfo = new ShortcutInfo.Builder(mContext, shortcutId).setLongLabel(
|
ShortcutInfo shortcutInfo = new ShortcutInfo.Builder(mContext, shortcutId).setLongLabel(
|
||||||
"name").build();
|
"name").setPerson(PERSON).build();
|
||||||
ConversationChannel convo = new ConversationChannel(shortcutInfo, 0, null, null,
|
ConversationChannel convo = new ConversationChannel(shortcutInfo, 0, null, null,
|
||||||
0L, false, false, statuses);
|
0L, false, false, statuses);
|
||||||
return convo;
|
return convo;
|
||||||
@@ -780,6 +1057,30 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
|
|||||||
|
|
||||||
private Notification createMessagingStyleNotification(String shortcutId,
|
private Notification createMessagingStyleNotification(String shortcutId,
|
||||||
boolean isMessagingStyle, boolean isMissedCall) {
|
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)
|
||||||
|
.addMessage(
|
||||||
|
new Notification.MessagingStyle.Message(NOTIFICATION_CONTENT, 10,
|
||||||
|
PERSON))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
if (isMissedCall) {
|
||||||
|
builder.setCategory(CATEGORY_MISSED_CALL);
|
||||||
|
}
|
||||||
|
return builder.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Notification.Builder createMessagingStyleNotificationWithoutExtras(String shortcutId,
|
||||||
|
boolean isMessagingStyle, boolean isMissedCall) {
|
||||||
Notification.Builder builder = new Notification.Builder(mContext)
|
Notification.Builder builder = new Notification.Builder(mContext)
|
||||||
.setContentTitle("TEST_TITLE")
|
.setContentTitle("TEST_TITLE")
|
||||||
.setContentText("TEST_TEXT")
|
.setContentText("TEST_TEXT")
|
||||||
@@ -794,9 +1095,10 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
|
|||||||
if (isMissedCall) {
|
if (isMissedCall) {
|
||||||
builder.setCategory(CATEGORY_MISSED_CALL);
|
builder.setCategory(CATEGORY_MISSED_CALL);
|
||||||
}
|
}
|
||||||
return builder.build();
|
return builder;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private StatusBarNotification createNotification(String shortcutId,
|
private StatusBarNotification createNotification(String shortcutId,
|
||||||
boolean isMessagingStyle, boolean isMissedCall) {
|
boolean isMessagingStyle, boolean isMissedCall) {
|
||||||
Notification notification = createMessagingStyleNotification(
|
Notification notification = createMessagingStyleNotification(
|
||||||
@@ -804,6 +1106,8 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
|
|||||||
return new SbnBuilder()
|
return new SbnBuilder()
|
||||||
.setNotification(notification)
|
.setNotification(notification)
|
||||||
.setPkg(TEST_PACKAGE_A)
|
.setPkg(TEST_PACKAGE_A)
|
||||||
|
.setUid(0)
|
||||||
|
.setUser(new UserHandle(0))
|
||||||
.build();
|
.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -824,11 +1128,16 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
|
|||||||
String.valueOf(WIDGET_ID_WITH_KEY_IN_OPTIONS),
|
String.valueOf(WIDGET_ID_WITH_KEY_IN_OPTIONS),
|
||||||
Context.MODE_PRIVATE);
|
Context.MODE_PRIVATE);
|
||||||
widgetSp4.edit().clear().commit();
|
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);
|
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mContext);
|
||||||
sp.edit().clear().commit();
|
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(
|
SharedPreferences widgetSp = mContext.getSharedPreferences(
|
||||||
String.valueOf(widgetId),
|
String.valueOf(widgetId),
|
||||||
Context.MODE_PRIVATE);
|
Context.MODE_PRIVATE);
|
||||||
@@ -840,11 +1149,17 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
|
|||||||
|
|
||||||
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mContext);
|
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mContext);
|
||||||
SharedPreferences.Editor editor = sp.edit();
|
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();
|
String key = new PeopleTileKey(shortcutId, 0, packageName).toString();
|
||||||
Set<String> storedWidgetIds = new HashSet<>(sp.getStringSet(key, new HashSet<>()));
|
Set<String> storedWidgetIds = new HashSet<>(sp.getStringSet(key, new HashSet<>()));
|
||||||
storedWidgetIds.add(String.valueOf(widgetId));
|
storedWidgetIds.add(String.valueOf(widgetId));
|
||||||
editor.putStringSet(key, storedWidgetIds);
|
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();
|
editor.apply();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user