Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 89d36feb authored by Willie Koomson's avatar Willie Koomson Committed by Android (Google) Code Review
Browse files

Merge "Reland "Add support for generated previews to People Space widget"" into main

parents 46a0f6e3 29ccc81b
Loading
Loading
Loading
Loading
+56 −2
Original line number Diff line number Diff line
@@ -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);
    }
}
+50 −2
Original line number Diff line number Diff line
@@ -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);