diff options
2 files changed, 106 insertions, 4 deletions
diff --git a/packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetManager.java b/packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetManager.java index 1d820a14be4e..0a880293ca76 100644 --- a/packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetManager.java +++ b/packages/SystemUI/src/com/android/systemui/people/widget/PeopleSpaceWidgetManager.java @@ -21,6 +21,9 @@ import static android.app.NotificationManager.INTERRUPTION_FILTER_ALARMS; import static android.app.NotificationManager.INTERRUPTION_FILTER_ALL; import static android.app.NotificationManager.INTERRUPTION_FILTER_NONE; import static android.app.NotificationManager.INTERRUPTION_FILTER_PRIORITY; +import static android.appwidget.AppWidgetProviderInfo.WIDGET_CATEGORY_HOME_SCREEN; +import static android.appwidget.AppWidgetProviderInfo.WIDGET_CATEGORY_KEYGUARD; +import static android.appwidget.flags.Flags.generatedPreviews; import static android.content.Intent.ACTION_BOOT_COMPLETED; import static android.content.Intent.ACTION_PACKAGE_ADDED; import static android.content.Intent.ACTION_PACKAGE_REMOVED; @@ -56,6 +59,7 @@ import android.app.people.IPeopleManager; import android.app.people.PeopleManager; import android.app.people.PeopleSpaceTile; import android.appwidget.AppWidgetManager; +import android.appwidget.AppWidgetProviderInfo; import android.content.BroadcastReceiver; import android.content.ComponentName; import android.content.Context; @@ -80,12 +84,15 @@ import android.service.notification.StatusBarNotification; import android.service.notification.ZenModeConfig; import android.text.TextUtils; import android.util.Log; +import android.util.SparseBooleanArray; import android.widget.RemoteViews; import com.android.internal.annotations.GuardedBy; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.logging.UiEventLogger; import com.android.internal.logging.UiEventLoggerImpl; +import com.android.keyguard.KeyguardUpdateMonitor; +import com.android.keyguard.KeyguardUpdateMonitorCallback; import com.android.systemui.Dumpable; import com.android.systemui.broadcast.BroadcastDispatcher; import com.android.systemui.dagger.SysUISingleton; @@ -96,6 +103,8 @@ import com.android.systemui.people.PeopleBackupFollowUpJob; import com.android.systemui.people.PeopleSpaceUtils; import com.android.systemui.people.PeopleTileViewHelper; import com.android.systemui.people.SharedPreferencesHelper; +import com.android.systemui.res.R; +import com.android.systemui.settings.UserTracker; import com.android.systemui.statusbar.NotificationListener; import com.android.systemui.statusbar.NotificationListener.NotificationHandler; import com.android.systemui.statusbar.notification.collection.NotificationEntry; @@ -160,13 +169,27 @@ public class PeopleSpaceWidgetManager implements Dumpable { @GuardedBy("mLock") public static Map<Integer, PeopleSpaceTile> mTiles = new HashMap<>(); + @NonNull private final UserTracker mUserTracker; + @NonNull private final SparseBooleanArray mUpdatedPreviews = new SparseBooleanArray(); + @NonNull private final KeyguardUpdateMonitorCallback mKeyguardUpdateMonitorCallback = + new KeyguardUpdateMonitorCallback() { + @Override + public void onUserUnlocked() { + if (DEBUG) { + Log.d(TAG, "onUserUnlocked " + mUserTracker.getUserId()); + } + updateGeneratedPreviewForUser(mUserTracker.getUserHandle()); + } + }; + @Inject public PeopleSpaceWidgetManager(Context context, LauncherApps launcherApps, CommonNotifCollection notifCollection, PackageManager packageManager, Optional<Bubbles> bubblesOptional, UserManager userManager, NotificationManager notificationManager, BroadcastDispatcher broadcastDispatcher, @Background Executor bgExecutor, - DumpManager dumpManager) { + DumpManager dumpManager, @NonNull UserTracker userTracker, + @NonNull KeyguardUpdateMonitor keyguardUpdateMonitor) { if (DEBUG) Log.d(TAG, "constructor"); mContext = context; mAppWidgetManager = AppWidgetManager.getInstance(context); @@ -187,6 +210,8 @@ public class PeopleSpaceWidgetManager implements Dumpable { mBroadcastDispatcher = broadcastDispatcher; mBgExecutor = bgExecutor; dumpManager.registerNormalDumpable(TAG, this); + mUserTracker = userTracker; + keyguardUpdateMonitor.registerCallback(mKeyguardUpdateMonitorCallback); } /** Initializes {@PeopleSpaceWidgetManager}. */ @@ -246,7 +271,7 @@ public class PeopleSpaceWidgetManager implements Dumpable { CommonNotifCollection notifCollection, PackageManager packageManager, Optional<Bubbles> bubblesOptional, UserManager userManager, BackupManager backupManager, INotificationManager iNotificationManager, NotificationManager notificationManager, - @Background Executor executor) { + @Background Executor executor, UserTracker userTracker) { mContext = context; mAppWidgetManager = appWidgetManager; mIPeopleManager = iPeopleManager; @@ -262,6 +287,7 @@ public class PeopleSpaceWidgetManager implements Dumpable { mManager = this; mSharedPrefs = PreferenceManager.getDefaultSharedPreferences(context); mBgExecutor = executor; + mUserTracker = userTracker; } /** @@ -1407,4 +1433,32 @@ public class PeopleSpaceWidgetManager implements Dumpable { Trace.traceEnd(Trace.TRACE_TAG_APP); } + + @VisibleForTesting + void updateGeneratedPreviewForUser(UserHandle user) { + if (!generatedPreviews() || mUpdatedPreviews.get(user.getIdentifier()) + || !mUserManager.isUserUnlocked(user)) { + return; + } + + // The widget provider may be disabled on SystemUI implementers, e.g. TvSystemUI. + ComponentName provider = new ComponentName(mContext, PeopleSpaceWidgetProvider.class); + List<AppWidgetProviderInfo> infos = mAppWidgetManager.getInstalledProvidersForPackage( + mContext.getPackageName(), user); + if (infos.stream().noneMatch(info -> info.provider.equals(provider))) { + return; + } + + if (DEBUG) { + Log.d(TAG, "Updating People Space widget preview for user " + user.getIdentifier()); + } + boolean success = mAppWidgetManager.setWidgetPreview( + provider, WIDGET_CATEGORY_HOME_SCREEN | WIDGET_CATEGORY_KEYGUARD, + new RemoteViews(mContext.getPackageName(), + R.layout.people_space_placeholder_layout)); + if (DEBUG && !success) { + Log.d(TAG, "Failed to update generated preview for user " + user.getIdentifier()); + } + mUpdatedPreviews.put(user.getIdentifier(), success); + } } 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 a63b2211f71a..db0c0bcfa8f5 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 @@ -80,6 +80,8 @@ import android.app.people.IPeopleManager; import android.app.people.PeopleManager; import android.app.people.PeopleSpaceTile; import android.appwidget.AppWidgetManager; +import android.appwidget.AppWidgetProviderInfo; +import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.SharedPreferences; @@ -101,11 +103,12 @@ import android.text.TextUtils; import androidx.preference.PreferenceManager; import androidx.test.filters.SmallTest; -import com.android.systemui.res.R; import com.android.systemui.SysuiTestCase; import com.android.systemui.people.PeopleBackupFollowUpJob; import com.android.systemui.people.PeopleSpaceUtils; import com.android.systemui.people.SharedPreferencesHelper; +import com.android.systemui.res.R; +import com.android.systemui.settings.FakeUserTracker; import com.android.systemui.statusbar.NotificationListener; import com.android.systemui.statusbar.NotificationListener.NotificationHandler; import com.android.systemui.statusbar.SbnBuilder; @@ -265,6 +268,8 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase { private final FakeExecutor mFakeExecutor = new FakeExecutor(mClock); + private final FakeUserTracker mUserTracker = new FakeUserTracker(); + @Before public void setUp() throws Exception { MockitoAnnotations.initMocks(this); @@ -272,7 +277,7 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase { mManager = new PeopleSpaceWidgetManager(mContext, mAppWidgetManager, mIPeopleManager, mPeopleManager, mLauncherApps, mNotifCollection, mPackageManager, Optional.of(mBubbles), mUserManager, mBackupManager, mINotificationManager, - mNotificationManager, mFakeExecutor); + mNotificationManager, mFakeExecutor, mUserTracker); mManager.attach(mListenerService); verify(mListenerService).addNotificationHandler(mListenerCaptor.capture()); @@ -309,6 +314,12 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase { .setId(1) .setShortcutInfo(mShortcutInfo) .build(); + + AppWidgetProviderInfo providerInfo = new AppWidgetProviderInfo(); + providerInfo.provider = new ComponentName("com.android.systemui.tests", + "com.android.systemui.people.widget.PeopleSpaceWidgetProvider"); + when(mAppWidgetManager.getInstalledProvidersForPackage(anyString(), any())) + .thenReturn(List.of(providerInfo)); } @Test @@ -1562,6 +1573,43 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase { String.valueOf(WIDGET_ID_WITH_KEY_IN_OPTIONS)); } + @Test + public void testUpdateGeneratedPreview_flagDisabled() { + mSetFlagsRule.disableFlags(android.appwidget.flags.Flags.FLAG_GENERATED_PREVIEWS); + mManager.updateGeneratedPreviewForUser(mUserTracker.getUserHandle()); + verify(mAppWidgetManager, times(0)).setWidgetPreview(any(), anyInt(), any()); + } + + @Test + public void testUpdateGeneratedPreview_userLocked() { + mSetFlagsRule.enableFlags(android.appwidget.flags.Flags.FLAG_GENERATED_PREVIEWS); + when(mUserManager.isUserUnlocked(mUserTracker.getUserHandle())).thenReturn(false); + + mManager.updateGeneratedPreviewForUser(mUserTracker.getUserHandle()); + verify(mAppWidgetManager, times(0)).setWidgetPreview(any(), anyInt(), any()); + } + + @Test + public void testUpdateGeneratedPreview_userUnlocked() { + mSetFlagsRule.enableFlags(android.appwidget.flags.Flags.FLAG_GENERATED_PREVIEWS); + when(mUserManager.isUserUnlocked(mUserTracker.getUserHandle())).thenReturn(true); + when(mAppWidgetManager.setWidgetPreview(any(), anyInt(), any())).thenReturn(true); + + mManager.updateGeneratedPreviewForUser(mUserTracker.getUserHandle()); + verify(mAppWidgetManager, times(1)).setWidgetPreview(any(), anyInt(), any()); + } + + @Test + public void testUpdateGeneratedPreview_doesNotSetTwice() { + mSetFlagsRule.enableFlags(android.appwidget.flags.Flags.FLAG_GENERATED_PREVIEWS); + when(mUserManager.isUserUnlocked(mUserTracker.getUserHandle())).thenReturn(true); + when(mAppWidgetManager.setWidgetPreview(any(), anyInt(), any())).thenReturn(true); + + mManager.updateGeneratedPreviewForUser(mUserTracker.getUserHandle()); + mManager.updateGeneratedPreviewForUser(mUserTracker.getUserHandle()); + verify(mAppWidgetManager, times(1)).setWidgetPreview(any(), anyInt(), any()); + } + private void setFinalField(String fieldName, int value) { try { Field field = NotificationManager.Policy.class.getDeclaredField(fieldName); |