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

Commit 1fb2040c authored by Alex Stetson's avatar Alex Stetson Committed by Android (Google) Code Review
Browse files

Merge "Ensure AppWidgetManager is optional" into main

parents 1f51823f fa5cfb3e
Loading
Loading
Loading
Loading
+0 −6
Original line number Diff line number Diff line
@@ -41,12 +41,6 @@ interface CommunalWidgetModule {
        const val APP_WIDGET_HOST_ID = 116
        const val DEFAULT_WIDGETS = "default_widgets"

        @SysUISingleton
        @Provides
        fun provideAppWidgetManager(@Application context: Context): Optional<AppWidgetManager> {
            return Optional.ofNullable(AppWidgetManager.getInstance(context))
        }

        @SysUISingleton
        @Provides
        fun provideCommunalAppWidgetHost(
+7 −0
Original line number Diff line number Diff line
@@ -42,6 +42,7 @@ import android.app.job.JobScheduler;
import android.app.role.RoleManager;
import android.app.smartspace.SmartspaceManager;
import android.app.trust.TrustManager;
import android.appwidget.AppWidgetManager;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothManager;
import android.companion.virtual.VirtualDeviceManager;
@@ -372,6 +373,12 @@ public class FrameworkServicesModule {
        return context.getSystemService(InputMethodManager.class);
    }

    @Provides
    @Singleton
    static Optional<AppWidgetManager> provideAppWidgetManager(@Application Context context) {
        return Optional.ofNullable(AppWidgetManager.getInstance(context));
    }

    @Provides
    @Singleton
    static IAppWidgetService provideIAppWidgetService() {
+11 −1
Original line number Diff line number Diff line
@@ -41,6 +41,8 @@ import android.preference.PreferenceManager;
import android.text.TextUtils;
import android.util.Log;

import androidx.annotation.Nullable;

import com.android.internal.annotations.VisibleForTesting;
import com.android.systemui.people.PeopleBackupFollowUpJob;
import com.android.systemui.people.SharedPreferencesHelper;
@@ -67,6 +69,7 @@ public class PeopleBackupHelper extends SharedPreferencesBackupHelper {
    private final UserHandle mUserHandle;
    private final PackageManager mPackageManager;
    private final IPeopleManager mIPeopleManager;
    @Nullable
    private final AppWidgetManager mAppWidgetManager;

    /**
@@ -404,6 +407,9 @@ public class PeopleBackupHelper extends SharedPreferencesBackupHelper {

    private List<String> getExistingWidgetsForUser(int userId) {
        List<String> existingWidgets = new ArrayList<>();
        if (mAppWidgetManager == null) {
            return existingWidgets;
        }
        int[] ids = mAppWidgetManager.getAppWidgetIds(
                new ComponentName(mContext, PeopleSpaceWidgetProvider.class));
        for (int id : ids) {
@@ -491,7 +497,11 @@ public class PeopleBackupHelper extends SharedPreferencesBackupHelper {

    /** Sends a broadcast to update the existing Conversation widgets. */
    public static void updateWidgets(Context context) {
        int[] widgetIds = AppWidgetManager.getInstance(context)
        AppWidgetManager manager = AppWidgetManager.getInstance(context);
        if (manager == null) {
            return;
        }
        int[] widgetIds = manager
                .getAppWidgetIds(new ComponentName(context, PeopleSpaceWidgetProvider.class));
        if (DEBUG) {
            for (int id : widgetIds) {
+55 −19
Original line number Diff line number Diff line
@@ -140,7 +140,7 @@ public class PeopleSpaceWidgetManager implements Dumpable {
    private final Object mLock = new Object();
    private final Context mContext;
    private LauncherApps mLauncherApps;
    private AppWidgetManager mAppWidgetManager;
    private Optional<AppWidgetManager> mAppWidgetManagerOptional;
    private IPeopleManager mIPeopleManager;
    private SharedPreferences mSharedPrefs;
    private PeopleManager mPeopleManager;
@@ -183,8 +183,9 @@ public class PeopleSpaceWidgetManager implements Dumpable {
            };

    @Inject
    public PeopleSpaceWidgetManager(Context context, LauncherApps launcherApps,
            CommonNotifCollection notifCollection,
    public PeopleSpaceWidgetManager(Context context,
            Optional<AppWidgetManager> appWidgetManagerOptional,
            LauncherApps launcherApps, CommonNotifCollection notifCollection,
            PackageManager packageManager, Optional<Bubbles> bubblesOptional,
            UserManager userManager, NotificationManager notificationManager,
            BroadcastDispatcher broadcastDispatcher, @Background Executor bgExecutor,
@@ -192,7 +193,7 @@ public class PeopleSpaceWidgetManager implements Dumpable {
            @NonNull KeyguardUpdateMonitor keyguardUpdateMonitor) {
        if (DEBUG) Log.d(TAG, "constructor");
        mContext = context;
        mAppWidgetManager = AppWidgetManager.getInstance(context);
        mAppWidgetManagerOptional = appWidgetManagerOptional;
        mIPeopleManager = IPeopleManager.Stub.asInterface(
                ServiceManager.getService(Context.PEOPLE_SERVICE));
        mLauncherApps = launcherApps;
@@ -266,14 +267,14 @@ public class PeopleSpaceWidgetManager implements Dumpable {
     */
    @VisibleForTesting
    PeopleSpaceWidgetManager(Context context,
            AppWidgetManager appWidgetManager, IPeopleManager iPeopleManager,
            Optional<AppWidgetManager> appWidgetManager, IPeopleManager iPeopleManager,
            PeopleManager peopleManager, LauncherApps launcherApps,
            CommonNotifCollection notifCollection, PackageManager packageManager,
            Optional<Bubbles> bubblesOptional, UserManager userManager, BackupManager backupManager,
            INotificationManager iNotificationManager, NotificationManager notificationManager,
            @Background Executor executor, UserTracker userTracker) {
        mContext = context;
        mAppWidgetManager = appWidgetManager;
        mAppWidgetManagerOptional = appWidgetManager;
        mIPeopleManager = iPeopleManager;
        mPeopleManager = peopleManager;
        mLauncherApps = launcherApps;
@@ -337,6 +338,10 @@ public class PeopleSpaceWidgetManager implements Dumpable {

    /** Updates the current widget view with provided {@link PeopleSpaceTile}. */
    private void updateAppWidgetViews(int appWidgetId, PeopleSpaceTile tile, Bundle options) {
        if (mAppWidgetManagerOptional.isEmpty()) {
            return;
        }

        PeopleTileKey key = getKeyFromStorageByWidgetId(appWidgetId);
        if (DEBUG) Log.d(TAG, "Widget: " + appWidgetId + " for: " + key.toString());

@@ -349,7 +354,7 @@ public class PeopleSpaceWidgetManager implements Dumpable {

        // Tell the AppWidgetManager to perform an update on the current app widget.
        if (DEBUG) Log.d(TAG, "Calling update widget for widgetId: " + appWidgetId);
        mAppWidgetManager.updateAppWidget(appWidgetId, views);
        mAppWidgetManagerOptional.get().updateAppWidget(appWidgetId, views);
    }

    /** Updates tile in app widget options and the current view. */
@@ -362,13 +367,17 @@ public class PeopleSpaceWidgetManager implements Dumpable {

    /** Updates tile in app widget options and the current view. */
    public void updateAppWidgetOptionsAndView(int appWidgetId, PeopleSpaceTile tile) {
        if (mAppWidgetManagerOptional.isEmpty()) {
            return;
        }

        if (tile == null) {
            Log.w(TAG, "Storing null tile for widget " + appWidgetId);
        }
        synchronized (mTiles) {
            mTiles.put(appWidgetId, tile);
        }
        Bundle options = mAppWidgetManager.getAppWidgetOptions(appWidgetId);
        Bundle options = mAppWidgetManagerOptional.get().getAppWidgetOptions(appWidgetId);
        updateAppWidgetViews(appWidgetId, tile, options);
    }

@@ -484,6 +493,10 @@ public class PeopleSpaceWidgetManager implements Dumpable {
    private void updateWidgetsWithNotificationChangedInBackground(StatusBarNotification sbn,
            PeopleSpaceUtils.NotificationAction action,
            Collection<NotificationEntry> notifications) {
        if (mAppWidgetManagerOptional.isEmpty()) {
            return;
        }

        try {
            PeopleTileKey key = new PeopleTileKey(
                    sbn.getShortcutId(), sbn.getUser().getIdentifier(), sbn.getPackageName());
@@ -491,7 +504,7 @@ public class PeopleSpaceWidgetManager implements Dumpable {
                if (DEBUG) Log.d(TAG, "Sbn doesn't contain valid PeopleTileKey: " + key.toString());
                return;
            }
            int[] widgetIds = mAppWidgetManager.getAppWidgetIds(
            int[] widgetIds = mAppWidgetManagerOptional.get().getAppWidgetIds(
                    new ComponentName(mContext, PeopleSpaceWidgetProvider.class)
            );
            if (widgetIds.length == 0) {
@@ -807,10 +820,14 @@ public class PeopleSpaceWidgetManager implements Dumpable {
                UserHandle user,
                NotificationChannel channel,
                int modificationType) {
            if (mAppWidgetManagerOptional.isEmpty()) {
                return;
            }

            if (channel.isConversation()) {
                mBgExecutor.execute(() -> {
                    if (mUserManager.isUserUnlocked(user)) {
                        updateWidgets(mAppWidgetManager.getAppWidgetIds(
                        updateWidgets(mAppWidgetManagerOptional.get().getAppWidgetIds(
                                new ComponentName(mContext, PeopleSpaceWidgetProvider.class)
                        ));
                    }
@@ -829,13 +846,18 @@ public class PeopleSpaceWidgetManager implements Dumpable {
        // learning about the widget. If so, the widget adder should have populated options with
        // PeopleTileKey arguments.
        if (DEBUG) Log.d(TAG, "onAppWidgetOptionsChanged called for widget: " + appWidgetId);
        if (mAppWidgetManagerOptional.isEmpty()) {
            return;
        }

        PeopleTileKey optionsKey = AppWidgetOptionsHelper.getPeopleTileKeyFromBundle(newOptions);
        if (PeopleTileKey.isValid(optionsKey)) {
            if (DEBUG) {
                Log.d(TAG, "PeopleTileKey was present in Options, shortcutId: "
                        + optionsKey.getShortcutId());
            }
            AppWidgetOptionsHelper.removePeopleTileKey(mAppWidgetManager, appWidgetId);
            AppWidgetOptionsHelper.removePeopleTileKey(mAppWidgetManagerOptional.get(),
                    appWidgetId);
            addNewWidget(appWidgetId, optionsKey);
        }
        // Update views for new widget dimensions.
@@ -1004,6 +1026,10 @@ public class PeopleSpaceWidgetManager implements Dumpable {
    public boolean requestPinAppWidget(ShortcutInfo shortcutInfo, Bundle options) {
        if (DEBUG) Log.d(TAG, "Requesting pin widget, shortcutId: " + shortcutInfo.getId());

        if (mAppWidgetManagerOptional.isEmpty()) {
            return false;
        }

        RemoteViews widgetPreview = getPreview(shortcutInfo.getId(),
                shortcutInfo.getUserHandle(), shortcutInfo.getPackage(), options);
        if (widgetPreview == null) {
@@ -1017,7 +1043,8 @@ public class PeopleSpaceWidgetManager implements Dumpable {
                PeopleSpaceWidgetPinnedReceiver.getPendingIntent(mContext, shortcutInfo);

        ComponentName componentName = new ComponentName(mContext, PeopleSpaceWidgetProvider.class);
        return mAppWidgetManager.requestPinAppWidget(componentName, extras, successCallback);
        return mAppWidgetManagerOptional.get().requestPinAppWidget(componentName, extras,
                successCallback);
    }

    /** Returns a list of map entries corresponding to user's priority conversations. */
@@ -1104,7 +1131,11 @@ public class PeopleSpaceWidgetManager implements Dumpable {
    /** Updates any app widget to the current state, triggered by a broadcast update. */
    @VisibleForTesting
    void updateWidgetsFromBroadcastInBackground(String entryPoint) {
        int[] appWidgetIds = mAppWidgetManager.getAppWidgetIds(
        if (mAppWidgetManagerOptional.isEmpty()) {
            return;
        }

        int[] appWidgetIds = mAppWidgetManagerOptional.get().getAppWidgetIds(
                new ComponentName(mContext, PeopleSpaceWidgetProvider.class));
        if (appWidgetIds == null) {
            return;
@@ -1272,13 +1303,17 @@ public class PeopleSpaceWidgetManager implements Dumpable {
        remapSharedFile(widgets);
        remapFollowupFile(widgets);

        int[] widgetIds = mAppWidgetManager.getAppWidgetIds(
        if (mAppWidgetManagerOptional.isEmpty()) {
            return;
        }

        int[] widgetIds = mAppWidgetManagerOptional.get().getAppWidgetIds(
                new ComponentName(mContext, PeopleSpaceWidgetProvider.class));
        Bundle b = new Bundle();
        b.putBoolean(AppWidgetManager.OPTION_APPWIDGET_RESTORE_COMPLETED, true);
        for (int id : widgetIds) {
            if (DEBUG) Log.d(TAG, "Setting widget as restored, widget id:" + id);
            mAppWidgetManager.updateAppWidgetOptions(id, b);
            mAppWidgetManagerOptional.get().updateAppWidgetOptions(id, b);
        }

        updateWidgets(widgetIds);
@@ -1437,13 +1472,14 @@ public class PeopleSpaceWidgetManager implements Dumpable {
    @VisibleForTesting
    void updateGeneratedPreviewForUser(UserHandle user) {
        if (!generatedPreviews() || mUpdatedPreviews.get(user.getIdentifier())
                || !mUserManager.isUserUnlocked(user)) {
                || !mUserManager.isUserUnlocked(user) || mAppWidgetManagerOptional.isEmpty()) {
            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(
        List<AppWidgetProviderInfo> infos =
                mAppWidgetManagerOptional.get().getInstalledProvidersForPackage(
                        mContext.getPackageName(), user);
        if (infos.stream().noneMatch(info -> info.provider.equals(provider))) {
            return;
@@ -1452,7 +1488,7 @@ public class PeopleSpaceWidgetManager implements Dumpable {
        if (DEBUG) {
            Log.d(TAG, "Updating People Space widget preview for user " + user.getIdentifier());
        }
        boolean success = mAppWidgetManager.setWidgetPreview(
        boolean success = mAppWidgetManagerOptional.get().setWidgetPreview(
                provider, WIDGET_CATEGORY_HOME_SCREEN | WIDGET_CATEGORY_KEYGUARD,
                new RemoteViews(mContext.getPackageName(),
                        R.layout.people_space_placeholder_layout));
+2 −2
Original line number Diff line number Diff line
@@ -276,8 +276,8 @@ public class PeopleSpaceWidgetManagerTest extends SysuiTestCase {
    public void setUp() throws Exception {
        MockitoAnnotations.initMocks(this);
        mLauncherApps = mock(LauncherApps.class);
        mManager = new PeopleSpaceWidgetManager(mContext, mAppWidgetManager, mIPeopleManager,
                mPeopleManager, mLauncherApps, mNotifCollection, mPackageManager,
        mManager = new PeopleSpaceWidgetManager(mContext, Optional.of(mAppWidgetManager),
                mIPeopleManager, mPeopleManager, mLauncherApps, mNotifCollection, mPackageManager,
                Optional.of(mBubbles), mUserManager, mBackupManager, mINotificationManager,
                mNotificationManager, mFakeExecutor, mUserTracker);
        mManager.attach(mListenerService);