diff --git a/packages/SystemUI/res/xml/people_space_widget_info.xml b/packages/SystemUI/res/xml/people_space_widget_info.xml index b2bf6da65163f..e3861470891d2 100644 --- a/packages/SystemUI/res/xml/people_space_widget_info.xml +++ b/packages/SystemUI/res/xml/people_space_widget_info.xml @@ -15,12 +15,13 @@ --> @@ -119,6 +120,7 @@ public class PeopleSpaceWidgetManager { mPeopleManager = mContext.getSystemService(PeopleManager.class); mNotificationEntryManager = Dependency.get(NotificationEntryManager.class); mPackageManager = mContext.getPackageManager(); + mPeopleSpaceWidgetProvider = new PeopleSpaceWidgetProvider(); } /** @@ -129,7 +131,7 @@ public class PeopleSpaceWidgetManager { AppWidgetManager appWidgetManager, IPeopleManager iPeopleManager, PeopleManager peopleManager, LauncherApps launcherApps, NotificationEntryManager notificationEntryManager, PackageManager packageManager, - boolean isForTesting) { + boolean isForTesting, PeopleSpaceWidgetProvider peopleSpaceWidgetProvider) { mAppWidgetManager = appWidgetManager; mIPeopleManager = iPeopleManager; mPeopleManager = peopleManager; @@ -137,6 +139,7 @@ public class PeopleSpaceWidgetManager { mNotificationEntryManager = notificationEntryManager; mPackageManager = packageManager; mIsForTesting = isForTesting; + mPeopleSpaceWidgetProvider = peopleSpaceWidgetProvider; } /** @@ -616,7 +619,20 @@ public class PeopleSpaceWidgetManager { return; } - mUiEventLogger.log(PeopleSpaceUtils.PeopleSpaceWidgetEvent.PEOPLE_SPACE_WIDGET_ADDED); + PeopleTileKey existingKeyIfStored; + synchronized (mLock) { + existingKeyIfStored = getKeyFromStorageByWidgetId(appWidgetId); + } + // Delete previous storage if the widget already existed and is just reconfigured. + if (existingKeyIfStored.isValid()) { + if (DEBUG) Log.d(TAG, "Remove previous storage for widget: " + appWidgetId); + deleteWidgets(new int[]{appWidgetId}); + } else { + // Widget newly added. + mUiEventLogger.log( + PeopleSpaceUtils.PeopleSpaceWidgetEvent.PEOPLE_SPACE_WIDGET_ADDED); + } + synchronized (mLock) { if (DEBUG) Log.d(TAG, "Add storage for : " + tile.getId()); PeopleTileKey key = new PeopleTileKey(tile); @@ -634,8 +650,7 @@ public class PeopleSpaceWidgetManager { PeopleSpaceUtils.updateAppWidgetOptionsAndView( mAppWidgetManager, mContext, appWidgetId, tile); - PeopleSpaceWidgetProvider provider = new PeopleSpaceWidgetProvider(); - provider.onUpdate(mContext, mAppWidgetManager, new int[]{appWidgetId}); + mPeopleSpaceWidgetProvider.onUpdate(mContext, mAppWidgetManager, new int[]{appWidgetId}); } /** Registers a conversation listener for {@code appWidgetId} if not already registered. */ @@ -644,12 +659,7 @@ public class PeopleSpaceWidgetManager { // Retrieve storage needed for registration. PeopleTileKey key; synchronized (mLock) { - SharedPreferences widgetSp = mContext.getSharedPreferences(String.valueOf(widgetId), - Context.MODE_PRIVATE); - key = new PeopleTileKey( - widgetSp.getString(SHORTCUT_ID, EMPTY_STRING), - widgetSp.getInt(USER_ID, INVALID_USER_ID), - widgetSp.getString(PACKAGE_NAME, EMPTY_STRING)); + key = getKeyFromStorageByWidgetId(widgetId); if (!key.isValid()) { if (DEBUG) Log.w(TAG, "Could not register listener for widget: " + widgetId); return; @@ -669,6 +679,20 @@ public class PeopleSpaceWidgetManager { mContext.getMainExecutor()); } + /** + * Attempts to get a key from storage for {@code widgetId}, returning null if an invalid key is + * found. + */ + private PeopleTileKey getKeyFromStorageByWidgetId(int widgetId) { + SharedPreferences widgetSp = mContext.getSharedPreferences(String.valueOf(widgetId), + Context.MODE_PRIVATE); + PeopleTileKey key = new PeopleTileKey( + widgetSp.getString(SHORTCUT_ID, EMPTY_STRING), + widgetSp.getInt(USER_ID, INVALID_USER_ID), + widgetSp.getString(PACKAGE_NAME, EMPTY_STRING)); + return key; + } + /** Deletes all storage, listeners, and caching for {@code appWidgetIds}. */ public void deleteWidgets(int[] appWidgetIds) { for (int widgetId : appWidgetIds) { diff --git a/packages/SystemUI/tests/src/com/android/systemui/people/widget/PeopleSpaceWidgetManagerTest.java b/packages/SystemUI/tests/src/com/android/systemui/people/widget/PeopleSpaceWidgetManagerTest.java index d91625eb7fab0..7125500c1fe65 100644 --- a/packages/SystemUI/tests/src/com/android/systemui/people/widget/PeopleSpaceWidgetManagerTest.java +++ b/packages/SystemUI/tests/src/com/android/systemui/people/widget/PeopleSpaceWidgetManagerTest.java @@ -186,11 +186,11 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase { mLauncherApps = mock(LauncherApps.class); mDependency.injectTestDependency(NotificationEntryManager.class, mNotificationEntryManager); mManager = new PeopleSpaceWidgetManager(mContext); - mManager.setAppWidgetManager(mAppWidgetManager, mIPeopleManager, mPeopleManager, - mLauncherApps, mNotificationEntryManager, mPackageManager, true); - mManager.attach(mListenerService); mProvider = new PeopleSpaceWidgetProvider(); mProvider.setPeopleSpaceWidgetManager(mManager); + mManager.setAppWidgetManager(mAppWidgetManager, mIPeopleManager, mPeopleManager, + mLauncherApps, mNotificationEntryManager, mPackageManager, true, mProvider); + mManager.attach(mListenerService); verify(mListenerService).addNotificationHandler(mListenerCaptor.capture()); NotificationHandler serviceListener = requireNonNull(mListenerCaptor.getValue()); @@ -842,6 +842,52 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase { any()); } + + @Test + public void testAddThenReconfigureWidgetsUpdatesStorageCacheAndListeners() + throws Exception { + clearStorage(); + mManager.addNewWidget(WIDGET_ID_WITH_SHORTCUT, PERSON_TILE); + // Check storage. + SharedPreferences widgetSp = mContext.getSharedPreferences( + String.valueOf(WIDGET_ID_WITH_SHORTCUT), + Context.MODE_PRIVATE); + assertThat(widgetSp.getString(PACKAGE_NAME, null)).isEqualTo(TEST_PACKAGE_A); + assertThat(widgetSp.getString(PeopleSpaceUtils.SHORTCUT_ID, null)).isEqualTo( + PERSON_TILE.getId()); + assertThat(widgetSp.getInt(USER_ID, INVALID_USER_ID)).isEqualTo(0); + // Check listener and caching. + verify(mPeopleManager).registerConversationListener(eq(TEST_PACKAGE_A), anyInt(), + eq(SHORTCUT_ID), any(), + any()); + verify(mLauncherApps, times(1)).cacheShortcuts( + eq(TEST_PACKAGE_A), + eq(Arrays.asList(SHORTCUT_ID)), eq(UserHandle.of(0)), + eq(LauncherApps.FLAG_CACHE_PEOPLE_TILE_SHORTCUTS)); + + // Reconfigure WIDGET_ID_WITH_SHORTCUT from PERSON_TILE to PERSON_TILE_WITH_SAME_URI + mManager.addNewWidget(WIDGET_ID_WITH_SHORTCUT, PERSON_TILE_WITH_SAME_URI); + + // Check listener is removed and shortcut is uncached. + verify(mPeopleManager).unregisterConversationListener(any()); + verify(mLauncherApps).uncacheShortcuts(eq(TEST_PACKAGE_A), + eq(Arrays.asList(PERSON_TILE.getId())), eq(UserHandle.of(0)), + eq(LauncherApps.FLAG_CACHE_PEOPLE_TILE_SHORTCUTS)); + // Check reconfigured storage from TEST_PACKAGE_A to B and SHORTCUT_ID to OTHER_SHORTCUT_ID. + assertThat(widgetSp.getString(PACKAGE_NAME, null)).isEqualTo(TEST_PACKAGE_B); + assertThat(widgetSp.getString(PeopleSpaceUtils.SHORTCUT_ID, null)).isEqualTo( + OTHER_SHORTCUT_ID); + assertThat(widgetSp.getInt(USER_ID, INVALID_USER_ID)).isEqualTo(0); + // Check listener & caching are reconfigured to TEST_PACKAGE_B and OTHER_SHORTCUT_ID. + verify(mPeopleManager, times(1)).registerConversationListener(eq(TEST_PACKAGE_B), anyInt(), + eq(OTHER_SHORTCUT_ID), any(), + any()); + verify(mLauncherApps, times(1)).cacheShortcuts( + eq(TEST_PACKAGE_B), + eq(Arrays.asList(OTHER_SHORTCUT_ID)), eq(UserHandle.of(0)), + eq(LauncherApps.FLAG_CACHE_PEOPLE_TILE_SHORTCUTS)); + } + @Test public void testDeleteAllWidgetsForConversationsUncachesShortcutAndRemovesListeners() throws Exception {