Register conversation listeners
Newly registered after reboots and after being added to Launcher. Stored in-memory to avoid duplicate registration. Refactors code out of PeopleSpaceUtils to better handle race conditions Test: PeopleSpaceWidgetManagerTest Bug: 178792356 Change-Id: Ia1bc2671cb29696e537495ff8c1adabb873f0713
This commit is contained in:
committed by
Flavio Fiszman
parent
b8d3b7d210
commit
f0fd893b6e
@@ -23,7 +23,6 @@ import android.app.Activity;
|
||||
import android.app.INotificationManager;
|
||||
import android.app.people.IPeopleManager;
|
||||
import android.app.people.PeopleSpaceTile;
|
||||
import android.appwidget.AppWidgetManager;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.pm.LauncherApps;
|
||||
@@ -34,12 +33,10 @@ import android.provider.Settings;
|
||||
import android.util.Log;
|
||||
import android.view.ViewGroup;
|
||||
|
||||
import com.android.internal.logging.UiEventLogger;
|
||||
import com.android.internal.logging.UiEventLoggerImpl;
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.people.widget.PeopleSpaceWidgetManager;
|
||||
import com.android.systemui.statusbar.notification.NotificationEntryManager;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import javax.inject.Inject;
|
||||
@@ -54,15 +51,14 @@ public class PeopleSpaceActivity extends Activity {
|
||||
|
||||
private ViewGroup mPeopleSpaceLayout;
|
||||
private IPeopleManager mPeopleManager;
|
||||
private PeopleSpaceWidgetManager mPeopleSpaceWidgetManager;
|
||||
private INotificationManager mNotificationManager;
|
||||
private PackageManager mPackageManager;
|
||||
private LauncherApps mLauncherApps;
|
||||
private Context mContext;
|
||||
private AppWidgetManager mAppWidgetManager;
|
||||
private NotificationEntryManager mNotificationEntryManager;
|
||||
private int mAppWidgetId;
|
||||
private boolean mShowSingleConversation;
|
||||
private UiEventLogger mUiEventLogger = new UiEventLoggerImpl();
|
||||
|
||||
@Inject
|
||||
public PeopleSpaceActivity(NotificationEntryManager notificationEntryManager) {
|
||||
@@ -81,8 +77,8 @@ public class PeopleSpaceActivity extends Activity {
|
||||
mPackageManager = getPackageManager();
|
||||
mPeopleManager = IPeopleManager.Stub.asInterface(
|
||||
ServiceManager.getService(Context.PEOPLE_SERVICE));
|
||||
mPeopleSpaceWidgetManager = new PeopleSpaceWidgetManager(mContext);
|
||||
mLauncherApps = mContext.getSystemService(LauncherApps.class);
|
||||
mAppWidgetManager = AppWidgetManager.getInstance(mContext);
|
||||
setTileViewsWithPriorityConversations();
|
||||
mAppWidgetId = getIntent().getIntExtra(EXTRA_APPWIDGET_ID,
|
||||
INVALID_APPWIDGET_ID);
|
||||
@@ -142,29 +138,13 @@ public class PeopleSpaceActivity extends Activity {
|
||||
+ mAppWidgetId);
|
||||
}
|
||||
}
|
||||
|
||||
PeopleSpaceUtils.setStorageForTile(mContext, tile, mAppWidgetId);
|
||||
int[] widgetIds = new int[mAppWidgetId];
|
||||
// TODO: Populate new widget with existing conversation notification, if there is any.
|
||||
PeopleSpaceUtils.updateSingleConversationWidgets(mContext, widgetIds, mAppWidgetManager,
|
||||
mPeopleManager);
|
||||
if (mLauncherApps != null) {
|
||||
try {
|
||||
if (DEBUG) Log.d(TAG, "Caching shortcut for PeopleTile: " + tile.getId());
|
||||
mLauncherApps.cacheShortcuts(tile.getPackageName(),
|
||||
Collections.singletonList(tile.getId()),
|
||||
tile.getUserHandle(), LauncherApps.FLAG_CACHE_PEOPLE_TILE_SHORTCUTS);
|
||||
} catch (Exception e) {
|
||||
Log.w(TAG, "Exception caching shortcut:" + e);
|
||||
}
|
||||
}
|
||||
mPeopleSpaceWidgetManager.addNewWidget(tile, mAppWidgetId);
|
||||
finishActivity();
|
||||
}
|
||||
|
||||
/** Finish activity with a successful widget configuration result. */
|
||||
private void finishActivity() {
|
||||
if (DEBUG) Log.d(TAG, "Widget added!");
|
||||
mUiEventLogger.log(PeopleSpaceUtils.PeopleSpaceWidgetEvent.PEOPLE_SPACE_WIDGET_ADDED);
|
||||
setActivityResult(RESULT_OK);
|
||||
finish();
|
||||
}
|
||||
|
||||
@@ -220,7 +220,7 @@ public class PeopleSpaceUtils {
|
||||
}
|
||||
|
||||
@Nullable
|
||||
private static PeopleSpaceTile getPeopleSpaceTile(IPeopleManager peopleManager,
|
||||
public static PeopleSpaceTile getPeopleSpaceTile(IPeopleManager peopleManager,
|
||||
AppWidgetManager appWidgetManager,
|
||||
Context context, int appWidgetId) {
|
||||
try {
|
||||
@@ -230,7 +230,7 @@ public class PeopleSpaceUtils {
|
||||
String pkg = widgetSp.getString(PACKAGE_NAME, EMPTY_STRING);
|
||||
int userId = widgetSp.getInt(USER_ID, INVALID_USER_ID);
|
||||
String shortcutId = widgetSp.getString(SHORTCUT_ID, EMPTY_STRING);
|
||||
if (pkg.isEmpty() || shortcutId.isEmpty() || userId == INVALID_WIDGET_ID) {
|
||||
if (!validKey(shortcutId, pkg, userId)) {
|
||||
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
shortcutId = sp.getString(String.valueOf(appWidgetId), null);
|
||||
if (shortcutId == null) {
|
||||
@@ -268,6 +268,17 @@ public class PeopleSpaceUtils {
|
||||
}
|
||||
}
|
||||
|
||||
/** Returns stored widgets for the conversation specified. */
|
||||
public static Set<String> getStoredWidgetIds(SharedPreferences sp, String shortcutId,
|
||||
String packageName, int userId) {
|
||||
if (shortcutId == null || packageName == null) {
|
||||
return new HashSet<>();
|
||||
}
|
||||
String key = PeopleSpaceUtils.getKey(shortcutId, packageName, userId);
|
||||
return new HashSet<>(sp.getStringSet(key, new HashSet<>()));
|
||||
}
|
||||
|
||||
|
||||
/** Best-effort attempts to migrate existing users to the new storage format. */
|
||||
// TODO: Remove after sufficient time. Temporary migration storage for existing users.
|
||||
private static void migrateExistingUsersToNewStorage(Context context, String shortcutId,
|
||||
@@ -286,7 +297,11 @@ public class PeopleSpaceUtils {
|
||||
if (DEBUG) Log.d(TAG, "Migrate storage for " + entry.get().getUserName());
|
||||
setStorageForTile(context, entry.get(), appWidgetId);
|
||||
} else {
|
||||
Log.e(TAG, "Could not migrate user");
|
||||
Log.e(TAG, "Could not migrate user. Delete old storage");
|
||||
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
SharedPreferences.Editor editor = sp.edit();
|
||||
editor.remove(String.valueOf(appWidgetId));
|
||||
editor.apply();
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "Could not query conversations");
|
||||
@@ -320,17 +335,10 @@ public class PeopleSpaceUtils {
|
||||
}
|
||||
|
||||
/** Removes stored data when tile is deleted. */
|
||||
public static void removeStorageForTile(Context context, int widgetId) {
|
||||
SharedPreferences widgetSp = context.getSharedPreferences(String.valueOf(widgetId),
|
||||
Context.MODE_PRIVATE);
|
||||
String packageName = widgetSp.getString(PACKAGE_NAME, null);
|
||||
String shortcutId = widgetSp.getString(SHORTCUT_ID, null);
|
||||
int userId = widgetSp.getInt(USER_ID, -1);
|
||||
|
||||
public static void removeStorageForTile(Context context, String key, int widgetId) {
|
||||
// Delete widgetId mapping to key.
|
||||
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(context);
|
||||
SharedPreferences.Editor editor = sp.edit();
|
||||
String key = PeopleSpaceUtils.getKey(shortcutId, packageName, userId);
|
||||
Set<String> storedWidgetIds = new HashSet<>(sp.getStringSet(key, new HashSet<>()));
|
||||
storedWidgetIds.remove(String.valueOf(widgetId));
|
||||
editor.putStringSet(key, storedWidgetIds);
|
||||
@@ -338,6 +346,8 @@ public class PeopleSpaceUtils {
|
||||
editor.apply();
|
||||
|
||||
// Delete all data specifically mapped to widgetId.
|
||||
SharedPreferences widgetSp = context.getSharedPreferences(String.valueOf(widgetId),
|
||||
Context.MODE_PRIVATE);
|
||||
SharedPreferences.Editor widgetEditor = widgetSp.edit();
|
||||
widgetEditor.remove(PACKAGE_NAME);
|
||||
widgetEditor.remove(USER_ID);
|
||||
@@ -345,21 +355,6 @@ public class PeopleSpaceUtils {
|
||||
widgetEditor.apply();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the data mapped to app widget specified by {@code appWidgetId} matches the
|
||||
* requested update data.
|
||||
*/
|
||||
public static boolean isCorrectAppWidget(Context context, int appWidgetId, String shortcutId,
|
||||
String packageName, int userId) {
|
||||
SharedPreferences sp = context.getSharedPreferences(String.valueOf(appWidgetId),
|
||||
Context.MODE_PRIVATE);
|
||||
String storedPackage = sp.getString(PACKAGE_NAME, EMPTY_STRING);
|
||||
int storedUserId = sp.getInt(USER_ID, INVALID_USER_ID);
|
||||
String storedShortcutId = sp.getString(SHORTCUT_ID, EMPTY_STRING);
|
||||
return storedPackage.equals(packageName) && storedShortcutId.equals(shortcutId)
|
||||
&& storedUserId == userId;
|
||||
}
|
||||
|
||||
static List<PeopleSpaceTile> augmentTilesFromVisibleNotifications(Context context,
|
||||
List<PeopleSpaceTile> tiles, NotificationEntryManager notificationEntryManager) {
|
||||
if (notificationEntryManager == null) {
|
||||
@@ -396,39 +391,8 @@ public class PeopleSpaceUtils {
|
||||
return augmentTileFromNotification(context, tile, visibleNotifications.get(key).getSbn());
|
||||
}
|
||||
|
||||
/**
|
||||
* If incoming notification changed tile, store the changes in the tile options.
|
||||
*/
|
||||
public static void updateWidgetWithNotificationChanged(IPeopleManager peopleManager,
|
||||
Context context,
|
||||
StatusBarNotification sbn,
|
||||
NotificationAction notificationAction, AppWidgetManager appWidgetManager,
|
||||
int appWidgetId) {
|
||||
PeopleSpaceTile storedTile = getPeopleSpaceTile(peopleManager, appWidgetManager, context,
|
||||
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 (DEBUG) Log.i(TAG, "Adding notification to storage, appWidgetId: " + appWidgetId);
|
||||
storedTile = augmentTileFromNotification(context, storedTile, sbn);
|
||||
} else {
|
||||
if (DEBUG) {
|
||||
Log.i(TAG, "Removing notification from storage, appWidgetId: " + appWidgetId);
|
||||
}
|
||||
storedTile = storedTile
|
||||
.toBuilder()
|
||||
.setNotificationKey(null)
|
||||
.setNotificationContent(null)
|
||||
.setNotificationDataUri(null)
|
||||
.setNotificationCategory(null)
|
||||
.build();
|
||||
}
|
||||
updateAppWidgetOptionsAndView(appWidgetManager, context, appWidgetId, storedTile);
|
||||
}
|
||||
|
||||
static PeopleSpaceTile augmentTileFromNotification(Context context, PeopleSpaceTile tile,
|
||||
/** Augments {@code tile} with the notification content from {@code sbn}. */
|
||||
public static PeopleSpaceTile augmentTileFromNotification(Context context, PeopleSpaceTile tile,
|
||||
StatusBarNotification sbn) {
|
||||
Notification notification = sbn.getNotification();
|
||||
if (notification == null) {
|
||||
@@ -992,7 +956,7 @@ public class PeopleSpaceUtils {
|
||||
}
|
||||
|
||||
/** Update app widget options and the current view. */
|
||||
private static void updateAppWidgetOptionsAndView(AppWidgetManager appWidgetManager,
|
||||
public static void updateAppWidgetOptionsAndView(AppWidgetManager appWidgetManager,
|
||||
Context context, int appWidgetId, PeopleSpaceTile tile) {
|
||||
updateAppWidgetOptions(appWidgetManager, appWidgetId, tile);
|
||||
RemoteViews views = createRemoteViews(context, tile, appWidgetId);
|
||||
@@ -1065,10 +1029,19 @@ public class PeopleSpaceUtils {
|
||||
* <li>"a/b/0" + "/" + 0 + "/" + "packageName"</li>
|
||||
* </ul>
|
||||
*/
|
||||
@Nullable
|
||||
public static String getKey(String shortcutId, String packageName, int userId) {
|
||||
if (!validKey(shortcutId, packageName, userId)) {
|
||||
return null;
|
||||
}
|
||||
return shortcutId + "/" + userId + "/" + packageName;
|
||||
}
|
||||
|
||||
/** Returns whether the key is valid. */
|
||||
public static boolean validKey(String shortcutId, String packageName, int userId) {
|
||||
return !TextUtils.isEmpty(shortcutId) && !TextUtils.isEmpty(packageName) && userId >= 0;
|
||||
}
|
||||
|
||||
/** Returns the userId associated with a {@link PeopleSpaceTile} */
|
||||
public static int getUserId(PeopleSpaceTile tile) {
|
||||
return tile.getUserHandle().getIdentifier();
|
||||
|
||||
@@ -16,12 +16,28 @@
|
||||
|
||||
package com.android.systemui.people.widget;
|
||||
|
||||
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.getPeopleSpaceTile;
|
||||
import static com.android.systemui.people.PeopleSpaceUtils.getStoredWidgetIds;
|
||||
import static com.android.systemui.people.PeopleSpaceUtils.updateAppWidgetOptionsAndView;
|
||||
|
||||
import android.app.NotificationChannel;
|
||||
import android.app.Person;
|
||||
import android.app.people.ConversationChannel;
|
||||
import android.app.people.IPeopleManager;
|
||||
import android.app.people.PeopleManager;
|
||||
import android.app.people.PeopleSpaceTile;
|
||||
import android.appwidget.AppWidgetManager;
|
||||
import android.content.ComponentName;
|
||||
import android.content.Context;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.pm.LauncherApps;
|
||||
import android.content.pm.ShortcutInfo;
|
||||
import android.net.Uri;
|
||||
import android.os.ServiceManager;
|
||||
import android.os.UserHandle;
|
||||
import android.preference.PreferenceManager;
|
||||
@@ -30,14 +46,18 @@ import android.service.notification.NotificationListenerService;
|
||||
import android.service.notification.StatusBarNotification;
|
||||
import android.util.Log;
|
||||
|
||||
import com.android.internal.annotations.GuardedBy;
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.internal.appwidget.IAppWidgetService;
|
||||
import com.android.systemui.R;
|
||||
import com.android.internal.logging.UiEventLogger;
|
||||
import com.android.internal.logging.UiEventLoggerImpl;
|
||||
import com.android.systemui.people.PeopleSpaceUtils;
|
||||
import com.android.systemui.statusbar.NotificationListener;
|
||||
import com.android.systemui.statusbar.NotificationListener.NotificationHandler;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import javax.inject.Inject;
|
||||
@@ -49,52 +69,49 @@ public class PeopleSpaceWidgetManager {
|
||||
private static final String TAG = "PeopleSpaceWidgetMgr";
|
||||
private static final boolean DEBUG = PeopleSpaceUtils.DEBUG;
|
||||
|
||||
private final Object mLock = new Object();
|
||||
private final Context mContext;
|
||||
private IAppWidgetService mAppWidgetService;
|
||||
private LauncherApps mLauncherApps;
|
||||
private AppWidgetManager mAppWidgetManager;
|
||||
private IPeopleManager mPeopleManager;
|
||||
private IPeopleManager mIPeopleManager;
|
||||
private SharedPreferences mSharedPrefs;
|
||||
private PeopleManager mPeopleManager;
|
||||
public UiEventLogger mUiEventLogger = new UiEventLoggerImpl();
|
||||
@GuardedBy("mLock")
|
||||
public static Map<String, PeopleSpaceWidgetProvider.TileConversationListener> mListeners =
|
||||
new HashMap<>();
|
||||
|
||||
@Inject
|
||||
public PeopleSpaceWidgetManager(Context context, IAppWidgetService appWidgetService) {
|
||||
public PeopleSpaceWidgetManager(Context context) {
|
||||
if (DEBUG) Log.d(TAG, "constructor");
|
||||
mContext = context;
|
||||
mAppWidgetService = appWidgetService;
|
||||
mAppWidgetManager = AppWidgetManager.getInstance(context);
|
||||
mPeopleManager = IPeopleManager.Stub.asInterface(
|
||||
mIPeopleManager = IPeopleManager.Stub.asInterface(
|
||||
ServiceManager.getService(Context.PEOPLE_SERVICE));
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor used for testing.
|
||||
*/
|
||||
@VisibleForTesting
|
||||
protected PeopleSpaceWidgetManager(Context context) {
|
||||
if (DEBUG) Log.d(TAG, "constructor");
|
||||
mContext = context;
|
||||
mAppWidgetService = IAppWidgetService.Stub.asInterface(
|
||||
ServiceManager.getService(Context.APPWIDGET_SERVICE));
|
||||
mLauncherApps = context.getSystemService(LauncherApps.class);
|
||||
mSharedPrefs = PreferenceManager.getDefaultSharedPreferences(mContext);
|
||||
mPeopleManager = mContext.getSystemService(PeopleManager.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* AppWidgetManager setter used for testing.
|
||||
*/
|
||||
@VisibleForTesting
|
||||
protected void setAppWidgetManager(IAppWidgetService appWidgetService,
|
||||
AppWidgetManager appWidgetManager, IPeopleManager peopleManager) {
|
||||
mAppWidgetService = appWidgetService;
|
||||
protected void setAppWidgetManager(
|
||||
AppWidgetManager appWidgetManager, IPeopleManager iPeopleManager,
|
||||
PeopleManager peopleManager, LauncherApps launcherApps) {
|
||||
mAppWidgetManager = appWidgetManager;
|
||||
mIPeopleManager = iPeopleManager;
|
||||
mPeopleManager = peopleManager;
|
||||
mLauncherApps = launcherApps;
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates People Space widgets.
|
||||
*/
|
||||
public void updateWidgets() {
|
||||
public void updateWidgets(int[] widgetIds) {
|
||||
try {
|
||||
if (DEBUG) Log.d(TAG, "updateWidgets called");
|
||||
int[] widgetIds = mAppWidgetService.getAppWidgetIds(
|
||||
new ComponentName(mContext, PeopleSpaceWidgetProvider.class)
|
||||
);
|
||||
if (widgetIds.length == 0) {
|
||||
if (DEBUG) Log.d(TAG, "no widgets to update");
|
||||
return;
|
||||
@@ -103,14 +120,11 @@ public class PeopleSpaceWidgetManager {
|
||||
if (DEBUG) Log.d(TAG, "updating " + widgetIds.length + " widgets");
|
||||
boolean showSingleConversation = Settings.Global.getInt(mContext.getContentResolver(),
|
||||
Settings.Global.PEOPLE_SPACE_CONVERSATION_TYPE, 0) == 0;
|
||||
|
||||
if (showSingleConversation) {
|
||||
PeopleSpaceUtils.updateSingleConversationWidgets(mContext, widgetIds,
|
||||
mAppWidgetManager, mPeopleManager);
|
||||
} else {
|
||||
mAppWidgetService
|
||||
.notifyAppWidgetViewDataChanged(mContext.getOpPackageName(), widgetIds,
|
||||
R.id.widget_list_view);
|
||||
synchronized (mLock) {
|
||||
PeopleSpaceUtils.updateSingleConversationWidgets(mContext, widgetIds,
|
||||
mAppWidgetManager, mIPeopleManager);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "Exception: " + e);
|
||||
@@ -121,9 +135,9 @@ public class PeopleSpaceWidgetManager {
|
||||
* Check if any existing People tiles match the incoming notification change, and store the
|
||||
* change in the tile if so.
|
||||
*/
|
||||
public void updateWidgetWithNotificationChanged(StatusBarNotification sbn,
|
||||
public void updateWidgetsWithNotificationChanged(StatusBarNotification sbn,
|
||||
PeopleSpaceUtils.NotificationAction notificationAction) {
|
||||
if (DEBUG) Log.d(TAG, "updateWidgetWithNotificationChanged called");
|
||||
if (DEBUG) Log.d(TAG, "updateWidgetsWithNotificationChanged called");
|
||||
boolean showSingleConversation = Settings.Global.getInt(mContext.getContentResolver(),
|
||||
Settings.Global.PEOPLE_SPACE_CONVERSATION_TYPE, 0) == 0;
|
||||
if (!showSingleConversation) {
|
||||
@@ -135,32 +149,113 @@ public class PeopleSpaceWidgetManager {
|
||||
if (DEBUG) Log.d(TAG, "Sbn shortcut id is null");
|
||||
return;
|
||||
}
|
||||
int[] widgetIds = mAppWidgetService.getAppWidgetIds(
|
||||
int[] widgetIds = mAppWidgetManager.getAppWidgetIds(
|
||||
new ComponentName(mContext, PeopleSpaceWidgetProvider.class)
|
||||
);
|
||||
if (widgetIds.length == 0) {
|
||||
Log.d(TAG, "No app widget ids returned");
|
||||
return;
|
||||
}
|
||||
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mContext);
|
||||
int userId = UserHandle.getUserHandleForUid(sbn.getUid()).getIdentifier();
|
||||
String key = PeopleSpaceUtils.getKey(sbnShortcutId, sbn.getPackageName(), userId);
|
||||
Set<String> storedWidgetIds = new HashSet<>(sp.getStringSet(key, new HashSet<>()));
|
||||
if (storedWidgetIds.isEmpty()) {
|
||||
Log.d(TAG, "No stored widget ids");
|
||||
return;
|
||||
}
|
||||
for (String widgetIdString : storedWidgetIds) {
|
||||
int widgetId = Integer.parseInt(widgetIdString);
|
||||
if (DEBUG) Log.d(TAG, "Storing notification change, key:" + sbn.getKey());
|
||||
PeopleSpaceUtils.updateWidgetWithNotificationChanged(mPeopleManager, mContext,
|
||||
sbn, notificationAction, mAppWidgetManager, widgetId);
|
||||
synchronized (mLock) {
|
||||
Set<String> storedWidgetIds = getStoredWidgetIds(mSharedPrefs, sbnShortcutId,
|
||||
sbn.getPackageName(),
|
||||
UserHandle.getUserHandleForUid(sbn.getUid()).getIdentifier());
|
||||
for (String widgetIdString : storedWidgetIds) {
|
||||
int widgetId = Integer.parseInt(widgetIdString);
|
||||
if (DEBUG) Log.d(TAG, "Storing notification change, key:" + sbn.getKey());
|
||||
updateStorageAndViewWithNotificationData(sbn, notificationAction, widgetId);
|
||||
}
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Log.e(TAG, "Exception: " + e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the tiles associated with the incoming conversation update.
|
||||
*/
|
||||
public void updateWidgetsWithConversationChanged(ConversationChannel conversation) {
|
||||
ShortcutInfo info = conversation.getShortcutInfo();
|
||||
synchronized (mLock) {
|
||||
Set<String> storedWidgetIds = getStoredWidgetIds(mSharedPrefs, info.getId(),
|
||||
info.getPackage(),
|
||||
info.getUserId());
|
||||
for (String widgetIdString : storedWidgetIds) {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG,
|
||||
"Conversation update for widget " + widgetIdString + " , "
|
||||
+ info.getLabel());
|
||||
}
|
||||
updateStorageAndViewWithConversationData(conversation,
|
||||
Integer.valueOf(widgetIdString));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Update {@code appWidgetId} with the new data provided by {@code conversation}.
|
||||
*/
|
||||
private void updateStorageAndViewWithConversationData(ConversationChannel conversation,
|
||||
int appWidgetId) {
|
||||
PeopleSpaceTile storedTile = getPeopleSpaceTile(mIPeopleManager, mAppWidgetManager,
|
||||
mContext,
|
||||
appWidgetId);
|
||||
if (storedTile == null) {
|
||||
if (DEBUG) Log.d(TAG, "Could not find stored tile to add conversation to");
|
||||
return;
|
||||
}
|
||||
ShortcutInfo info = conversation.getShortcutInfo();
|
||||
Uri uri = null;
|
||||
if (info.getPersons() != null && info.getPersons().length > 0) {
|
||||
Person person = info.getPersons()[0];
|
||||
uri = person.getUri() == null ? null : Uri.parse(person.getUri());
|
||||
}
|
||||
storedTile = storedTile.toBuilder()
|
||||
.setUserName(info.getLabel())
|
||||
.setUserIcon(
|
||||
PeopleSpaceTile.convertDrawableToIcon(mLauncherApps.getShortcutIconDrawable(
|
||||
info, 0))
|
||||
)
|
||||
.setContactUri(uri)
|
||||
.setStatuses(conversation.getStatuses())
|
||||
.setLastInteractionTimestamp(conversation.getLastEventTimestamp())
|
||||
.setIsImportantConversation(conversation.getParentNotificationChannel() != null
|
||||
&& conversation.getParentNotificationChannel().isImportantConversation())
|
||||
.build();
|
||||
updateAppWidgetOptionsAndView(mAppWidgetManager, mContext, appWidgetId, storedTile);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update {@code appWidgetId} with the new data provided by {@code sbn}.
|
||||
*/
|
||||
private void updateStorageAndViewWithNotificationData(
|
||||
StatusBarNotification sbn,
|
||||
PeopleSpaceUtils.NotificationAction notificationAction,
|
||||
int appWidgetId) {
|
||||
PeopleSpaceTile storedTile = getPeopleSpaceTile(mIPeopleManager, mAppWidgetManager,
|
||||
mContext,
|
||||
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 (DEBUG) Log.i(TAG, "Adding notification to storage, appWidgetId: " + appWidgetId);
|
||||
storedTile = augmentTileFromNotification(mContext, storedTile, sbn);
|
||||
} else {
|
||||
if (DEBUG) {
|
||||
Log.i(TAG, "Removing notification from storage, appWidgetId: " + appWidgetId);
|
||||
}
|
||||
storedTile = storedTile
|
||||
.toBuilder()
|
||||
.setNotificationKey(null)
|
||||
.setNotificationContent(null)
|
||||
.setNotificationDataUri(null)
|
||||
.build();
|
||||
}
|
||||
updateAppWidgetOptionsAndView(mAppWidgetManager, mContext, appWidgetId, storedTile);
|
||||
}
|
||||
|
||||
/**
|
||||
* Attaches the manager to the pipeline, making it ready to receive events. Should only be
|
||||
* called once.
|
||||
@@ -174,8 +269,7 @@ public class PeopleSpaceWidgetManager {
|
||||
@Override
|
||||
public void onNotificationPosted(
|
||||
StatusBarNotification sbn, NotificationListenerService.RankingMap rankingMap) {
|
||||
if (DEBUG) Log.d(TAG, "onNotificationPosted");
|
||||
updateWidgetWithNotificationChanged(sbn, PeopleSpaceUtils.NotificationAction.POSTED);
|
||||
updateWidgetsWithNotificationChanged(sbn, PeopleSpaceUtils.NotificationAction.POSTED);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -183,8 +277,7 @@ public class PeopleSpaceWidgetManager {
|
||||
StatusBarNotification sbn,
|
||||
NotificationListenerService.RankingMap rankingMap
|
||||
) {
|
||||
if (DEBUG) Log.d(TAG, "onNotificationRemoved");
|
||||
updateWidgetWithNotificationChanged(sbn, PeopleSpaceUtils.NotificationAction.REMOVED);
|
||||
updateWidgetsWithNotificationChanged(sbn, PeopleSpaceUtils.NotificationAction.REMOVED);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -192,8 +285,7 @@ public class PeopleSpaceWidgetManager {
|
||||
StatusBarNotification sbn,
|
||||
NotificationListenerService.RankingMap rankingMap,
|
||||
int reason) {
|
||||
if (DEBUG) Log.d(TAG, "onNotificationRemoved with reason " + reason);
|
||||
updateWidgetWithNotificationChanged(sbn, PeopleSpaceUtils.NotificationAction.REMOVED);
|
||||
updateWidgetsWithNotificationChanged(sbn, PeopleSpaceUtils.NotificationAction.REMOVED);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -204,7 +296,6 @@ public class PeopleSpaceWidgetManager {
|
||||
@Override
|
||||
public void onNotificationsInitialized() {
|
||||
if (DEBUG) Log.d(TAG, "onNotificationsInitialized");
|
||||
updateWidgets();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -213,11 +304,131 @@ public class PeopleSpaceWidgetManager {
|
||||
UserHandle user,
|
||||
NotificationChannel channel,
|
||||
int modificationType) {
|
||||
if (DEBUG) Log.d(TAG, "onNotificationChannelModified");
|
||||
if (channel.isConversation()) {
|
||||
updateWidgets();
|
||||
updateWidgets(mAppWidgetManager.getAppWidgetIds(
|
||||
new ComponentName(mContext, PeopleSpaceWidgetProvider.class)
|
||||
));
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
/** Adds {@code tile} mapped to {@code appWidgetId}. */
|
||||
public void addNewWidget(PeopleSpaceTile tile, int appWidgetId) {
|
||||
mUiEventLogger.log(PeopleSpaceUtils.PeopleSpaceWidgetEvent.PEOPLE_SPACE_WIDGET_ADDED);
|
||||
synchronized (mLock) {
|
||||
if (DEBUG) Log.d(TAG, "Add storage for : " + tile.getUserName());
|
||||
PeopleSpaceUtils.setStorageForTile(mContext, tile, appWidgetId);
|
||||
}
|
||||
try {
|
||||
if (DEBUG) Log.d(TAG, "Caching shortcut for PeopleTile: " + tile.getId());
|
||||
mLauncherApps.cacheShortcuts(tile.getPackageName(),
|
||||
Collections.singletonList(tile.getId()),
|
||||
tile.getUserHandle(), LauncherApps.FLAG_CACHE_PEOPLE_TILE_SHORTCUTS);
|
||||
} catch (Exception e) {
|
||||
Log.w(TAG, "Exception caching shortcut:" + e);
|
||||
}
|
||||
PeopleSpaceWidgetProvider provider = new PeopleSpaceWidgetProvider();
|
||||
provider.onUpdate(mContext, mAppWidgetManager, new int[]{appWidgetId});
|
||||
}
|
||||
|
||||
/** Registers a conversation listener for {@code appWidgetId} if not already registered. */
|
||||
public void registerConversationListenerIfNeeded(int widgetId,
|
||||
PeopleSpaceWidgetProvider.TileConversationListener newListener) {
|
||||
// Retrieve storage needed for registration.
|
||||
String packageName;
|
||||
String shortcutId;
|
||||
int userId;
|
||||
String key;
|
||||
synchronized (mLock) {
|
||||
SharedPreferences widgetSp = mContext.getSharedPreferences(String.valueOf(widgetId),
|
||||
Context.MODE_PRIVATE);
|
||||
packageName = widgetSp.getString(PACKAGE_NAME, null);
|
||||
shortcutId = widgetSp.getString(SHORTCUT_ID, null);
|
||||
userId = widgetSp.getInt(USER_ID, INVALID_USER_ID);
|
||||
key = PeopleSpaceUtils.getKey(shortcutId, packageName, userId);
|
||||
if (key == null) {
|
||||
if (DEBUG) Log.e(TAG, "Could not register " + widgetId);
|
||||
return;
|
||||
}
|
||||
}
|
||||
synchronized (mListeners) {
|
||||
if (mListeners.containsKey(key)) {
|
||||
if (DEBUG) Log.d(TAG, "Already registered listener");
|
||||
return;
|
||||
}
|
||||
if (DEBUG) Log.d(TAG, "Register listener for " + widgetId + " with " + key);
|
||||
mListeners.put(key, newListener);
|
||||
}
|
||||
mPeopleManager.registerConversationListener(packageName,
|
||||
userId,
|
||||
shortcutId, newListener,
|
||||
mContext.getMainExecutor());
|
||||
}
|
||||
|
||||
/** Deletes all storage, listeners, and caching for {@code appWidgetIds}. */
|
||||
public void deleteWidgets(int[] appWidgetIds) {
|
||||
for (int widgetId : appWidgetIds) {
|
||||
if (DEBUG) Log.d(TAG, "Widget removed: " + widgetId);
|
||||
mUiEventLogger.log(PeopleSpaceUtils.PeopleSpaceWidgetEvent.PEOPLE_SPACE_WIDGET_DELETED);
|
||||
// Retrieve storage needed for widget deletion.
|
||||
String packageName;
|
||||
String shortcutId;
|
||||
int userId;
|
||||
String key;
|
||||
Set<String> storedWidgetIdsForKey;
|
||||
synchronized (mLock) {
|
||||
SharedPreferences widgetSp = mContext.getSharedPreferences(String.valueOf(widgetId),
|
||||
Context.MODE_PRIVATE);
|
||||
packageName = widgetSp.getString(PACKAGE_NAME, null);
|
||||
shortcutId = widgetSp.getString(SHORTCUT_ID, null);
|
||||
userId = widgetSp.getInt(USER_ID, INVALID_USER_ID);
|
||||
key = PeopleSpaceUtils.getKey(shortcutId, packageName, userId);
|
||||
if (key == null) {
|
||||
if (DEBUG) Log.e(TAG, "Could not delete " + widgetId);
|
||||
return;
|
||||
}
|
||||
storedWidgetIdsForKey = new HashSet<>(
|
||||
mSharedPrefs.getStringSet(key, new HashSet<>()));
|
||||
}
|
||||
synchronized (mLock) {
|
||||
PeopleSpaceUtils.removeStorageForTile(mContext, key, widgetId);
|
||||
}
|
||||
// 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 (storedWidgetIdsForKey.contains(String.valueOf(widgetId))
|
||||
&& storedWidgetIdsForKey.size() == 1) {
|
||||
if (DEBUG) Log.d(TAG, "Remove caching and listener");
|
||||
unregisterConversationListener(key, widgetId);
|
||||
uncacheConversationShortcut(shortcutId, packageName, userId);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/** Unregisters the conversation listener for {@code appWidgetId}. */
|
||||
private void unregisterConversationListener(String key, int appWidgetId) {
|
||||
PeopleSpaceWidgetProvider.TileConversationListener registeredListener;
|
||||
synchronized (mListeners) {
|
||||
registeredListener = mListeners.get(key);
|
||||
if (registeredListener == null) {
|
||||
if (DEBUG) Log.d(TAG, "Cannot find listener to unregister");
|
||||
return;
|
||||
}
|
||||
if (DEBUG) Log.d(TAG, "Unregister listener for " + appWidgetId + " with " + key);
|
||||
mListeners.remove(key);
|
||||
}
|
||||
mPeopleManager.unregisterConversationListener(registeredListener);
|
||||
}
|
||||
|
||||
/** Uncaches the conversation shortcut. */
|
||||
private void uncacheConversationShortcut(String shortcutId, String packageName, int userId) {
|
||||
try {
|
||||
if (DEBUG) Log.d(TAG, "Uncaching shortcut for PeopleTile: " + shortcutId);
|
||||
mLauncherApps.uncacheShortcuts(packageName,
|
||||
Collections.singletonList(shortcutId),
|
||||
UserHandle.of(userId),
|
||||
LauncherApps.FLAG_CACHE_PEOPLE_TILE_SHORTCUTS);
|
||||
} catch (Exception e) {
|
||||
Log.d(TAG, "Exception uncaching shortcut:" + e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,31 +16,17 @@
|
||||
|
||||
package com.android.systemui.people.widget;
|
||||
|
||||
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 android.app.PendingIntent;
|
||||
import android.app.people.IPeopleManager;
|
||||
import android.annotation.NonNull;
|
||||
import android.app.people.ConversationChannel;
|
||||
import android.app.people.PeopleManager;
|
||||
import android.appwidget.AppWidgetManager;
|
||||
import android.appwidget.AppWidgetProvider;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.pm.LauncherApps;
|
||||
import android.os.ServiceManager;
|
||||
import android.os.UserHandle;
|
||||
import android.provider.Settings;
|
||||
import android.util.Log;
|
||||
import android.widget.RemoteViews;
|
||||
|
||||
import com.android.internal.logging.UiEventLogger;
|
||||
import com.android.internal.logging.UiEventLoggerImpl;
|
||||
import com.android.systemui.R;
|
||||
import com.android.internal.annotations.VisibleForTesting;
|
||||
import com.android.systemui.people.PeopleSpaceUtils;
|
||||
|
||||
import java.util.Collections;
|
||||
|
||||
/** People Space Widget Provider class. */
|
||||
public class PeopleSpaceWidgetProvider extends AppWidgetProvider {
|
||||
private static final String TAG = "PeopleSpaceWidgetPvd";
|
||||
@@ -50,7 +36,26 @@ public class PeopleSpaceWidgetProvider extends AppWidgetProvider {
|
||||
public static final String EXTRA_PACKAGE_NAME = "extra_package_name";
|
||||
public static final String EXTRA_USER_HANDLE = "extra_user_handle";
|
||||
|
||||
public UiEventLogger mUiEventLogger = new UiEventLoggerImpl();
|
||||
public PeopleSpaceWidgetManager peopleSpaceWidgetManager;
|
||||
|
||||
/** Listener for the shortcut data changes. */
|
||||
public class TileConversationListener implements PeopleManager.ConversationListener {
|
||||
|
||||
@Override
|
||||
public void onConversationUpdate(@NonNull ConversationChannel conversation) {
|
||||
if (DEBUG) {
|
||||
Log.d(TAG,
|
||||
"Received updated conversation: "
|
||||
+ conversation.getShortcutInfo().getLabel());
|
||||
}
|
||||
if (peopleSpaceWidgetManager == null) {
|
||||
// This shouldn't happen since onUpdate is called at reboot.
|
||||
Log.e(TAG, "Skipping conversation update: WidgetManager uninitialized");
|
||||
return;
|
||||
}
|
||||
peopleSpaceWidgetManager.updateWidgetsWithConversationChanged(conversation);
|
||||
}
|
||||
}
|
||||
|
||||
/** Called when widget updates. */
|
||||
@Override
|
||||
@@ -58,70 +63,32 @@ public class PeopleSpaceWidgetProvider extends AppWidgetProvider {
|
||||
super.onUpdate(context, appWidgetManager, appWidgetIds);
|
||||
|
||||
if (DEBUG) Log.d(TAG, "onUpdate called");
|
||||
boolean showSingleConversation = Settings.Global.getInt(context.getContentResolver(),
|
||||
Settings.Global.PEOPLE_SPACE_CONVERSATION_TYPE, 0) == 0;
|
||||
if (showSingleConversation) {
|
||||
PeopleSpaceUtils.updateSingleConversationWidgets(context, appWidgetIds,
|
||||
appWidgetManager, IPeopleManager.Stub.asInterface(
|
||||
ServiceManager.getService(Context.PEOPLE_SERVICE)));
|
||||
return;
|
||||
}
|
||||
// Perform this loop procedure for each App Widget that belongs to this provider
|
||||
ensurePeopleSpaceWidgetManagerInitialized(context);
|
||||
peopleSpaceWidgetManager.updateWidgets(appWidgetIds);
|
||||
for (int appWidgetId : appWidgetIds) {
|
||||
RemoteViews views =
|
||||
new RemoteViews(context.getPackageName(), R.layout.people_space_widget);
|
||||
PeopleSpaceWidgetProvider.TileConversationListener
|
||||
newListener = new PeopleSpaceWidgetProvider.TileConversationListener();
|
||||
peopleSpaceWidgetManager.registerConversationListenerIfNeeded(appWidgetId,
|
||||
newListener);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
Intent intent = new Intent(context, PeopleSpaceWidgetService.class);
|
||||
intent.putExtra(AppWidgetManager.EXTRA_APPWIDGET_ID, appWidgetId);
|
||||
views.setRemoteAdapter(R.id.widget_list_view, intent);
|
||||
|
||||
Intent activityIntent = new Intent(context, LaunchConversationActivity.class);
|
||||
activityIntent.addFlags(
|
||||
Intent.FLAG_ACTIVITY_NEW_TASK
|
||||
| Intent.FLAG_ACTIVITY_CLEAR_TASK
|
||||
| Intent.FLAG_ACTIVITY_NO_HISTORY
|
||||
| Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
|
||||
PendingIntent pendingIntent = PendingIntent.getActivity(
|
||||
context,
|
||||
appWidgetId,
|
||||
activityIntent,
|
||||
PendingIntent.FLAG_UPDATE_CURRENT | PendingIntent.FLAG_MUTABLE);
|
||||
views.setPendingIntentTemplate(R.id.widget_list_view, pendingIntent);
|
||||
|
||||
// Tell the AppWidgetManager to perform an update on the current app widget
|
||||
appWidgetManager.notifyAppWidgetViewDataChanged(appWidgetId, R.id.widget_list_view);
|
||||
appWidgetManager.updateAppWidget(appWidgetId, views);
|
||||
private void ensurePeopleSpaceWidgetManagerInitialized(Context context) {
|
||||
if (peopleSpaceWidgetManager == null) {
|
||||
peopleSpaceWidgetManager = new PeopleSpaceWidgetManager(context);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDeleted(Context context, int[] appWidgetIds) {
|
||||
super.onDeleted(context, appWidgetIds);
|
||||
LauncherApps launcherApps = context.getSystemService(LauncherApps.class);
|
||||
ensurePeopleSpaceWidgetManagerInitialized(context);
|
||||
peopleSpaceWidgetManager.deleteWidgets(appWidgetIds);
|
||||
}
|
||||
|
||||
for (int widgetId : appWidgetIds) {
|
||||
if (DEBUG) Log.d(TAG, "Widget removed");
|
||||
mUiEventLogger.log(PeopleSpaceUtils.PeopleSpaceWidgetEvent.PEOPLE_SPACE_WIDGET_DELETED);
|
||||
if (launcherApps != null) {
|
||||
SharedPreferences widgetSp = context.getSharedPreferences(String.valueOf(widgetId),
|
||||
Context.MODE_PRIVATE);
|
||||
String packageName = widgetSp.getString(PACKAGE_NAME, null);
|
||||
String shortcutId = widgetSp.getString(SHORTCUT_ID, null);
|
||||
int userId = widgetSp.getInt(USER_ID, -1);
|
||||
|
||||
if (packageName != null && shortcutId != null && userId != -1) {
|
||||
try {
|
||||
if (DEBUG) Log.d(TAG, "Uncaching shortcut for PeopleTile: " + shortcutId);
|
||||
launcherApps.uncacheShortcuts(packageName,
|
||||
Collections.singletonList(shortcutId),
|
||||
UserHandle.of(userId),
|
||||
LauncherApps.FLAG_CACHE_PEOPLE_TILE_SHORTCUTS);
|
||||
} catch (Exception e) {
|
||||
Log.d(TAG, "Exception uncaching shortcut:" + e);
|
||||
}
|
||||
}
|
||||
}
|
||||
PeopleSpaceUtils.removeStorageForTile(context, widgetId);
|
||||
}
|
||||
@VisibleForTesting
|
||||
public void setPeopleSpaceWidgetManager(PeopleSpaceWidgetManager manager) {
|
||||
peopleSpaceWidgetManager = manager;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,14 +19,21 @@ package com.android.systemui.people.widget;
|
||||
import static android.app.Notification.CATEGORY_MISSED_CALL;
|
||||
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 com.android.systemui.people.PeopleSpaceUtils.INVALID_USER_ID;
|
||||
import static com.android.systemui.people.PeopleSpaceUtils.OPTIONS_PEOPLE_SPACE_TILE;
|
||||
import static com.android.systemui.people.PeopleSpaceUtils.PACKAGE_NAME;
|
||||
import static com.android.systemui.people.PeopleSpaceUtils.USER_ID;
|
||||
|
||||
import static com.google.common.truth.Truth.assertThat;
|
||||
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyInt;
|
||||
import static org.mockito.ArgumentMatchers.eq;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
@@ -38,12 +45,15 @@ import android.app.Notification;
|
||||
import android.app.NotificationChannel;
|
||||
import android.app.Person;
|
||||
import android.app.people.ConversationChannel;
|
||||
import android.app.people.ConversationStatus;
|
||||
import android.app.people.IPeopleManager;
|
||||
import android.app.people.PeopleManager;
|
||||
import android.app.people.PeopleSpaceTile;
|
||||
import android.appwidget.AppWidgetManager;
|
||||
import android.content.Context;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.content.pm.LauncherApps;
|
||||
import android.content.pm.ShortcutInfo;
|
||||
import android.graphics.drawable.Icon;
|
||||
import android.net.Uri;
|
||||
@@ -56,7 +66,6 @@ import android.testing.AndroidTestingRunner;
|
||||
import androidx.preference.PreferenceManager;
|
||||
import androidx.test.filters.SmallTest;
|
||||
|
||||
import com.android.internal.appwidget.IAppWidgetService;
|
||||
import com.android.systemui.R;
|
||||
import com.android.systemui.SysuiTestCase;
|
||||
import com.android.systemui.people.PeopleSpaceUtils;
|
||||
@@ -76,7 +85,9 @@ import org.mockito.Captor;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.MockitoAnnotations;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
@SmallTest
|
||||
@@ -99,6 +110,7 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
|
||||
private static final String NOTIFICATION_CONTENT = "message text";
|
||||
private static final Uri URI = Uri.parse("fake_uri");
|
||||
private static final Icon ICON = Icon.createWithResource("package", R.drawable.ic_android);
|
||||
private static final String KEY = PeopleSpaceUtils.getKey(SHORTCUT_ID, TEST_PACKAGE_A, 0);
|
||||
private static final Person PERSON = new Person.Builder()
|
||||
.setName("name")
|
||||
.setKey("abc")
|
||||
@@ -121,12 +133,15 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
|
||||
|
||||
@Mock
|
||||
private NotificationListener mListenerService;
|
||||
@Mock
|
||||
private IAppWidgetService mIAppWidgetService;
|
||||
|
||||
@Mock
|
||||
private AppWidgetManager mAppWidgetManager;
|
||||
@Mock
|
||||
private IPeopleManager mIPeopleManager;
|
||||
@Mock
|
||||
private PeopleManager mPeopleManager;
|
||||
@Mock
|
||||
private LauncherApps mLauncherApps;
|
||||
|
||||
@Captor
|
||||
private ArgumentCaptor<NotificationHandler> mListenerCaptor;
|
||||
@@ -136,13 +151,19 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
|
||||
private final NoManSimulator mNoMan = new NoManSimulator();
|
||||
private final FakeSystemClock mClock = new FakeSystemClock();
|
||||
|
||||
private PeopleSpaceWidgetProvider mProvider;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
MockitoAnnotations.initMocks(this);
|
||||
mLauncherApps = mock(LauncherApps.class);
|
||||
mManager =
|
||||
new PeopleSpaceWidgetManager(mContext);
|
||||
mManager.setAppWidgetManager(mIAppWidgetService, mAppWidgetManager, mIPeopleManager);
|
||||
mManager.setAppWidgetManager(mAppWidgetManager, mIPeopleManager, mPeopleManager,
|
||||
mLauncherApps);
|
||||
mManager.attach(mListenerService);
|
||||
mProvider = new PeopleSpaceWidgetProvider();
|
||||
mProvider.setPeopleSpaceWidgetManager(mManager);
|
||||
|
||||
verify(mListenerService).addNotificationHandler(mListenerCaptor.capture());
|
||||
NotificationHandler serviceListener = requireNonNull(mListenerCaptor.getValue());
|
||||
@@ -166,7 +187,7 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
|
||||
@Test
|
||||
public void testDoNotUpdateAppWidgetIfNoWidgets() throws Exception {
|
||||
int[] widgetIdsArray = {};
|
||||
when(mIAppWidgetService.getAppWidgetIds(any())).thenReturn(widgetIdsArray);
|
||||
when(mAppWidgetManager.getAppWidgetIds(any())).thenReturn(widgetIdsArray);
|
||||
|
||||
StatusBarNotification sbn = createNotification(
|
||||
OTHER_SHORTCUT_ID, /* isMessagingStyle = */ false, /* isMissedCall = */ false);
|
||||
@@ -182,7 +203,7 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
|
||||
@Test
|
||||
public void testDoNotUpdateAppWidgetIfNoShortcutInfo() throws Exception {
|
||||
int[] widgetIdsArray = {};
|
||||
when(mIAppWidgetService.getAppWidgetIds(any())).thenReturn(widgetIdsArray);
|
||||
when(mAppWidgetManager.getAppWidgetIds(any())).thenReturn(widgetIdsArray);
|
||||
|
||||
Notification notificationWithoutShortcut = new Notification.Builder(mContext)
|
||||
.setContentTitle("TEST_TITLE")
|
||||
@@ -206,7 +227,7 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
|
||||
@Test
|
||||
public void testDoNotUpdateAppWidgetIfNoPackage() throws Exception {
|
||||
int[] widgetIdsArray = {};
|
||||
when(mIAppWidgetService.getAppWidgetIds(any())).thenReturn(widgetIdsArray);
|
||||
when(mAppWidgetManager.getAppWidgetIds(any())).thenReturn(widgetIdsArray);
|
||||
|
||||
StatusBarNotification sbnWithoutPackageName = new SbnBuilder()
|
||||
.setNotification(createMessagingStyleNotification(
|
||||
@@ -224,7 +245,7 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
|
||||
@Test
|
||||
public void testDoNotUpdateAppWidgetIfNonConversationChannelModified() throws Exception {
|
||||
int[] widgetIdsArray = {1};
|
||||
when(mIAppWidgetService.getAppWidgetIds(any())).thenReturn(widgetIdsArray);
|
||||
when(mAppWidgetManager.getAppWidgetIds(any())).thenReturn(widgetIdsArray);
|
||||
|
||||
NotificationChannel channel =
|
||||
new NotificationChannel(TEST_CHANNEL_ID, TEST_CHANNEL_NAME, IMPORTANCE_DEFAULT);
|
||||
@@ -240,7 +261,7 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
|
||||
@Test
|
||||
public void testUpdateAppWidgetIfConversationChannelModified() throws Exception {
|
||||
int[] widgetIdsArray = {1};
|
||||
when(mIAppWidgetService.getAppWidgetIds(any())).thenReturn(widgetIdsArray);
|
||||
when(mAppWidgetManager.getAppWidgetIds(any())).thenReturn(widgetIdsArray);
|
||||
|
||||
NotificationChannel channel =
|
||||
new NotificationChannel(TEST_CHANNEL_ID, TEST_CHANNEL_NAME, IMPORTANCE_DEFAULT);
|
||||
@@ -257,7 +278,7 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
|
||||
@Test
|
||||
public void testDoNotUpdateNotificationPostedIfDifferentShortcutId() throws Exception {
|
||||
int[] widgetIdsArray = {WIDGET_ID_WITH_SHORTCUT, WIDGET_ID_WITHOUT_SHORTCUT};
|
||||
when(mIAppWidgetService.getAppWidgetIds(any())).thenReturn(widgetIdsArray);
|
||||
when(mAppWidgetManager.getAppWidgetIds(any())).thenReturn(widgetIdsArray);
|
||||
|
||||
StatusBarNotification sbn = createNotification(
|
||||
OTHER_SHORTCUT_ID, /* isMessagingStyle = */ true, /* isMissedCall = */ false);
|
||||
@@ -277,7 +298,7 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
|
||||
Settings.Global.putInt(mContext.getContentResolver(),
|
||||
Settings.Global.PEOPLE_SPACE_CONVERSATION_TYPE, 0);
|
||||
int[] widgetIdsArray = {WIDGET_ID_WITH_SHORTCUT, WIDGET_ID_WITHOUT_SHORTCUT};
|
||||
when(mIAppWidgetService.getAppWidgetIds(any())).thenReturn(widgetIdsArray);
|
||||
when(mAppWidgetManager.getAppWidgetIds(any())).thenReturn(widgetIdsArray);
|
||||
|
||||
StatusBarNotification sbnWithDifferentPackageName = new SbnBuilder()
|
||||
.setNotification(createMessagingStyleNotification(
|
||||
@@ -298,7 +319,7 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
|
||||
@Test
|
||||
public void testDoNotUpdateNotificationRemovedIfDifferentShortcutId() throws Exception {
|
||||
int[] widgetIdsArray = {WIDGET_ID_WITH_SHORTCUT, WIDGET_ID_WITHOUT_SHORTCUT};
|
||||
when(mIAppWidgetService.getAppWidgetIds(any())).thenReturn(widgetIdsArray);
|
||||
when(mAppWidgetManager.getAppWidgetIds(any())).thenReturn(widgetIdsArray);
|
||||
|
||||
StatusBarNotification sbn = createNotification(
|
||||
OTHER_SHORTCUT_ID, /* isMessagingStyle = */ true, /* isMissedCall = */ false);
|
||||
@@ -318,7 +339,7 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
|
||||
@Test
|
||||
public void testDoNotUpdateNotificationRemovedIfDifferentPackageName() throws Exception {
|
||||
int[] widgetIdsArray = {WIDGET_ID_WITH_SHORTCUT, WIDGET_ID_WITHOUT_SHORTCUT};
|
||||
when(mIAppWidgetService.getAppWidgetIds(any())).thenReturn(widgetIdsArray);
|
||||
when(mAppWidgetManager.getAppWidgetIds(any())).thenReturn(widgetIdsArray);
|
||||
|
||||
StatusBarNotification sbnWithDifferentPackageName = new SbnBuilder()
|
||||
.setNotification(createMessagingStyleNotification(
|
||||
@@ -338,10 +359,75 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
|
||||
any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDoNotUpdateStatusPostedIfDifferentShortcutId() throws Exception {
|
||||
int[] widgetIdsArray = {WIDGET_ID_WITH_SHORTCUT, WIDGET_ID_WITHOUT_SHORTCUT};
|
||||
when(mAppWidgetManager.getAppWidgetIds(any())).thenReturn(widgetIdsArray);
|
||||
|
||||
ConversationStatus status1 = new ConversationStatus.Builder(OTHER_SHORTCUT_ID,
|
||||
ACTIVITY_GAME).setDescription("Playing a game!").build();
|
||||
ConversationStatus status2 = new ConversationStatus.Builder(OTHER_SHORTCUT_ID,
|
||||
ACTIVITY_BIRTHDAY).build();
|
||||
ConversationChannel conversationChannel = getConversationWithShortcutId(OTHER_SHORTCUT_ID,
|
||||
Arrays.asList(status1, status2));
|
||||
mManager.updateWidgetsWithConversationChanged(conversationChannel);
|
||||
mClock.advanceTime(MIN_LINGER_DURATION);
|
||||
|
||||
verify(mAppWidgetManager, never())
|
||||
.updateAppWidgetOptions(anyInt(), any());
|
||||
verify(mAppWidgetManager, never()).updateAppWidget(anyInt(),
|
||||
any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateStatusPostedIfExistingTile() throws Exception {
|
||||
int[] widgetIdsArray = {WIDGET_ID_WITH_SHORTCUT, WIDGET_ID_WITHOUT_SHORTCUT};
|
||||
when(mAppWidgetManager.getAppWidgetIds(any())).thenReturn(widgetIdsArray);
|
||||
|
||||
ConversationStatus status = new ConversationStatus.Builder(SHORTCUT_ID,
|
||||
ACTIVITY_GAME).setDescription("Playing a game!").build();
|
||||
ConversationChannel conversationChannel = getConversationWithShortcutId(SHORTCUT_ID,
|
||||
Arrays.asList(status));
|
||||
mManager.updateWidgetsWithConversationChanged(conversationChannel);
|
||||
mClock.advanceTime(MIN_LINGER_DURATION);
|
||||
|
||||
verify(mAppWidgetManager, times(1))
|
||||
.updateAppWidgetOptions(eq(WIDGET_ID_WITH_SHORTCUT),
|
||||
mBundleArgumentCaptor.capture());
|
||||
Bundle bundle = mBundleArgumentCaptor.getValue();
|
||||
PeopleSpaceTile tile = bundle.getParcelable(OPTIONS_PEOPLE_SPACE_TILE);
|
||||
assertThat(tile.getStatuses()).containsExactly(status);
|
||||
verify(mAppWidgetManager, times(1)).updateAppWidget(eq(WIDGET_ID_WITH_SHORTCUT),
|
||||
any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateStatusPostedOnTwoExistingTiles() throws Exception {
|
||||
addSecondWidgetForPersonTile();
|
||||
|
||||
ConversationStatus status = new ConversationStatus.Builder(SHORTCUT_ID,
|
||||
ACTIVITY_ANNIVERSARY).build();
|
||||
ConversationChannel conversationChannel = getConversationWithShortcutId(SHORTCUT_ID,
|
||||
Arrays.asList(status));
|
||||
mManager.updateWidgetsWithConversationChanged(conversationChannel);
|
||||
mClock.advanceTime(MIN_LINGER_DURATION);
|
||||
|
||||
verify(mAppWidgetManager, times(1))
|
||||
.updateAppWidgetOptions(eq(WIDGET_ID_WITH_SHORTCUT),
|
||||
any());
|
||||
verify(mAppWidgetManager, times(1)).updateAppWidget(eq(WIDGET_ID_WITH_SHORTCUT),
|
||||
any());
|
||||
verify(mAppWidgetManager, times(1))
|
||||
.updateAppWidgetOptions(eq(SECOND_WIDGET_ID_WITH_SHORTCUT),
|
||||
any());
|
||||
verify(mAppWidgetManager, times(1)).updateAppWidget(eq(SECOND_WIDGET_ID_WITH_SHORTCUT),
|
||||
any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testUpdateNotificationPostedIfExistingTile() throws Exception {
|
||||
int[] widgetIdsArray = {WIDGET_ID_WITH_SHORTCUT, WIDGET_ID_WITHOUT_SHORTCUT};
|
||||
when(mIAppWidgetService.getAppWidgetIds(any())).thenReturn(widgetIdsArray);
|
||||
when(mAppWidgetManager.getAppWidgetIds(any())).thenReturn(widgetIdsArray);
|
||||
|
||||
NotifEvent notif1 = mNoMan.postNotif(new NotificationEntryBuilder()
|
||||
.setSbn(createNotification(
|
||||
@@ -362,17 +448,7 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
|
||||
|
||||
@Test
|
||||
public void testUpdateNotificationPostedOnTwoExistingTiles() throws Exception {
|
||||
Bundle options = new Bundle();
|
||||
options.putParcelable(PeopleSpaceUtils.OPTIONS_PEOPLE_SPACE_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.
|
||||
setStorageForTile(SHORTCUT_ID, TEST_PACKAGE_A, 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,
|
||||
SECOND_WIDGET_ID_WITH_SHORTCUT};
|
||||
when(mIAppWidgetService.getAppWidgetIds(any())).thenReturn(widgetIdsArray);
|
||||
addSecondWidgetForPersonTile();
|
||||
|
||||
NotifEvent notif1 = mNoMan.postNotif(new NotificationEntryBuilder()
|
||||
.setSbn(createNotification(
|
||||
@@ -395,19 +471,9 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
|
||||
@Test
|
||||
public void testUpdateNotificationOnExistingTileAfterRemovingTileForSamePerson()
|
||||
throws Exception {
|
||||
Bundle options = new Bundle();
|
||||
options.putParcelable(PeopleSpaceUtils.OPTIONS_PEOPLE_SPACE_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.
|
||||
setStorageForTile(SHORTCUT_ID, TEST_PACKAGE_A, WIDGET_ID_WITH_SHORTCUT);
|
||||
setStorageForTile(SHORTCUT_ID, TEST_PACKAGE_A, SECOND_WIDGET_ID_WITH_SHORTCUT);
|
||||
addSecondWidgetForPersonTile();
|
||||
|
||||
int[] widgetIdsArray = {WIDGET_ID_WITH_SHORTCUT, WIDGET_ID_WITHOUT_SHORTCUT,
|
||||
SECOND_WIDGET_ID_WITH_SHORTCUT};
|
||||
when(mIAppWidgetService.getAppWidgetIds(any())).thenReturn(widgetIdsArray);
|
||||
|
||||
PeopleSpaceUtils.removeStorageForTile(mContext, SECOND_WIDGET_ID_WITH_SHORTCUT);
|
||||
PeopleSpaceUtils.removeStorageForTile(mContext, KEY, SECOND_WIDGET_ID_WITH_SHORTCUT);
|
||||
NotifEvent notif1 = mNoMan.postNotif(new NotificationEntryBuilder()
|
||||
.setSbn(createNotification(
|
||||
SHORTCUT_ID, /* isMessagingStyle = */ true, /* isMissedCall = */ false))
|
||||
@@ -430,7 +496,7 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
|
||||
public void testUpdateMissedCallNotificationWithoutContentPostedIfExistingTile()
|
||||
throws Exception {
|
||||
int[] widgetIdsArray = {WIDGET_ID_WITH_SHORTCUT, WIDGET_ID_WITHOUT_SHORTCUT};
|
||||
when(mIAppWidgetService.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()
|
||||
@@ -456,7 +522,7 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
|
||||
public void testUpdateMissedCallNotificationWithContentPostedIfExistingTile()
|
||||
throws Exception {
|
||||
int[] widgetIdsArray = {WIDGET_ID_WITH_SHORTCUT, WIDGET_ID_WITHOUT_SHORTCUT};
|
||||
when(mIAppWidgetService.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()
|
||||
@@ -480,7 +546,7 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
|
||||
@Test
|
||||
public void testUpdateNotificationRemovedIfExistingTile() throws Exception {
|
||||
int[] widgetIdsArray = {WIDGET_ID_WITH_SHORTCUT, WIDGET_ID_WITHOUT_SHORTCUT};
|
||||
when(mIAppWidgetService.getAppWidgetIds(any())).thenReturn(widgetIdsArray);
|
||||
when(mAppWidgetManager.getAppWidgetIds(any())).thenReturn(widgetIdsArray);
|
||||
|
||||
StatusBarNotification sbn = createNotification(
|
||||
SHORTCUT_ID, /* isMessagingStyle = */ true, /* isMissedCall = */ false);
|
||||
@@ -502,14 +568,82 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
|
||||
any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testDeleteAllWidgetsForConversationsUncachesShortcutAndRemovesListeners() {
|
||||
addSecondWidgetForPersonTile();
|
||||
mProvider.onUpdate(mContext, mAppWidgetManager,
|
||||
new int[]{WIDGET_ID_WITH_SHORTCUT, SECOND_WIDGET_ID_WITH_SHORTCUT});
|
||||
|
||||
// Delete only one widget for the conversation.
|
||||
mManager.deleteWidgets(new int[]{WIDGET_ID_WITH_SHORTCUT});
|
||||
|
||||
// Check deleted storage.
|
||||
SharedPreferences widgetSp = mContext.getSharedPreferences(
|
||||
String.valueOf(WIDGET_ID_WITH_SHORTCUT),
|
||||
Context.MODE_PRIVATE);
|
||||
assertThat(widgetSp.getString(PACKAGE_NAME, null)).isNull();
|
||||
assertThat(widgetSp.getString(SHORTCUT_ID, null)).isNull();
|
||||
assertThat(widgetSp.getInt(USER_ID, INVALID_USER_ID)).isEqualTo(INVALID_USER_ID);
|
||||
SharedPreferences sp = PreferenceManager.getDefaultSharedPreferences(mContext);
|
||||
assertThat(sp.getStringSet(KEY, new HashSet<>())).containsExactly(
|
||||
String.valueOf(SECOND_WIDGET_ID_WITH_SHORTCUT));
|
||||
// Check listener & shortcut caching remain for other widget.
|
||||
verify(mPeopleManager, never()).unregisterConversationListener(any());
|
||||
verify(mLauncherApps, never()).uncacheShortcuts(eq(TEST_PACKAGE_A),
|
||||
eq(Arrays.asList(SHORTCUT_ID)), eq(UserHandle.of(0)),
|
||||
eq(LauncherApps.FLAG_CACHE_PEOPLE_TILE_SHORTCUTS));
|
||||
|
||||
// Delete all widgets for the conversation.
|
||||
mProvider.onDeleted(mContext, new int[]{SECOND_WIDGET_ID_WITH_SHORTCUT});
|
||||
|
||||
// Check deleted storage.
|
||||
SharedPreferences secondWidgetSp = mContext.getSharedPreferences(
|
||||
String.valueOf(SECOND_WIDGET_ID_WITH_SHORTCUT),
|
||||
Context.MODE_PRIVATE);
|
||||
assertThat(secondWidgetSp.getString(PACKAGE_NAME, null)).isNull();
|
||||
assertThat(secondWidgetSp.getString(SHORTCUT_ID, null)).isNull();
|
||||
assertThat(secondWidgetSp.getInt(USER_ID, INVALID_USER_ID)).isEqualTo(INVALID_USER_ID);
|
||||
assertThat(sp.getStringSet(KEY, new HashSet<>())).isEmpty();
|
||||
// Check listener is removed and shortcut is uncached.
|
||||
verify(mPeopleManager, times(1)).unregisterConversationListener(any());
|
||||
verify(mLauncherApps, times(1)).uncacheShortcuts(eq(TEST_PACKAGE_A),
|
||||
eq(Arrays.asList(SHORTCUT_ID)), eq(UserHandle.of(0)),
|
||||
eq(LauncherApps.FLAG_CACHE_PEOPLE_TILE_SHORTCUTS));
|
||||
}
|
||||
|
||||
/**
|
||||
* 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(PeopleSpaceUtils.OPTIONS_PEOPLE_SPACE_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.
|
||||
setStorageForTile(SHORTCUT_ID, TEST_PACKAGE_A, 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,
|
||||
SECOND_WIDGET_ID_WITH_SHORTCUT};
|
||||
when(mAppWidgetManager.getAppWidgetIds(any())).thenReturn(widgetIdsArray);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a single conversation associated with {@code shortcutId}.
|
||||
*/
|
||||
private ConversationChannel getConversationWithShortcutId(String shortcutId) throws Exception {
|
||||
return getConversationWithShortcutId(shortcutId, Arrays.asList());
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a single conversation associated with {@code shortcutId} and {@code statuses}.
|
||||
*/
|
||||
private ConversationChannel getConversationWithShortcutId(String shortcutId,
|
||||
List<ConversationStatus> statuses) throws Exception {
|
||||
ShortcutInfo shortcutInfo = new ShortcutInfo.Builder(mContext, shortcutId).setLongLabel(
|
||||
"name").build();
|
||||
ConversationChannel convo = new ConversationChannel(shortcutInfo, 0, null, null,
|
||||
0L, false);
|
||||
0L, false, false, statuses);
|
||||
return convo;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user