Use new widget functionality to reconfigure widget

Users can now reconfigure which conversation shows on their widgets.

Bug: 183084171
Test: PeopleSpaceWidgetManagerTest
Change-Id: I0eab87c88408c8b8039f654177891e62762109c3
This commit is contained in:
Anna Zappone
2021-04-09 19:49:28 +00:00
parent 6fb83178e0
commit d7a54bfa66
4 changed files with 87 additions and 19 deletions

View File

@@ -15,12 +15,13 @@
-->
<appwidget-provider xmlns:android="http://schemas.android.com/apk/res/android"
android:minWidth="120dp"
android:minHeight="50dp"
android:minWidth="136dp"
android:minHeight="55dp"
android:minResizeWidth="60dp"
android:minResizeHeight="50dp"
android:maxResizeHeight="207dp"
android:updatePeriodMillis="60000"
android:widgetFeatures="reconfigurable"
android:description="@string/people_tile_description"
android:previewLayout="@layout/people_space_placeholder_layout"
android:resizeMode="horizontal|vertical"

View File

@@ -29,7 +29,6 @@ import android.app.people.PeopleSpaceTile;
import android.content.Context;
import android.content.Intent;
import android.content.pm.LauncherApps;
import android.content.pm.PackageManager;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.graphics.Outline;
@@ -60,7 +59,6 @@ public class PeopleSpaceActivity extends Activity {
private IPeopleManager mPeopleManager;
private PeopleSpaceWidgetManager mPeopleSpaceWidgetManager;
private INotificationManager mNotificationManager;
private PackageManager mPackageManager;
private LauncherApps mLauncherApps;
private Context mContext;
private NotificationEntryManager mNotificationEntryManager;
@@ -81,7 +79,6 @@ public class PeopleSpaceActivity extends Activity {
mContext = getApplicationContext();
mNotificationManager = INotificationManager.Stub.asInterface(
ServiceManager.getService(Context.NOTIFICATION_SERVICE));
mPackageManager = getPackageManager();
mPeopleManager = IPeopleManager.Stub.asInterface(
ServiceManager.getService(Context.PEOPLE_SERVICE));
mLauncherApps = mContext.getSystemService(LauncherApps.class);
@@ -112,7 +109,7 @@ public class PeopleSpaceActivity extends Activity {
LinearLayout item = findViewById(R.id.item);
GradientDrawable shape = (GradientDrawable) item.getBackground();
final TypedArray ta = mContext.obtainStyledAttributes(
new int[] {android.R.attr.colorBackgroundFloating});
new int[]{android.R.attr.colorBackgroundFloating});
shape.setColor(ta.getColor(0, Color.WHITE));
return;
}

View File

@@ -95,6 +95,7 @@ public class PeopleSpaceWidgetManager {
private PeopleManager mPeopleManager;
private NotificationEntryManager mNotificationEntryManager;
private PackageManager mPackageManager;
private PeopleSpaceWidgetProvider mPeopleSpaceWidgetProvider;
public UiEventLogger mUiEventLogger = new UiEventLoggerImpl();
@GuardedBy("mLock")
public static Map<PeopleTileKey, PeopleSpaceWidgetProvider.TileConversationListener>
@@ -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) {

View File

@@ -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 {