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

Commit 384570b5 authored by Willie Koomson's avatar Willie Koomson
Browse files

Avoid updating zombie provider's masked state

This change updates AppWidgetServiceImpl to
 - avoid updating the provider masked state if the provider is a zombie
 - reload provider masked state when the provider is reified

This fixes a bug where widgets are stuck in masked state after a
restore. This happens when the service masks a zombie provider in
reloadProviderMaskedStateLocked, but cannot unmask it in
updateWidgetPackageStoppedMaskedState because it cannot match the
PACKAGE_UNSTOPPED broadcast to the zombie provider's UID (because we do
not know the UID yet).

Bug: 372229859
Test: see bug for repro steps
Flag: EXEMPT bug fix
Change-Id: Ie4e8efe1d33890f6037dfd4074886f82652e45f2
parent 743e80dc
Loading
Loading
Loading
Loading
+38 −29
Original line number Diff line number Diff line
@@ -767,30 +767,38 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
            for (int i = 0; i < N; i++) {
                Provider provider = mProviders.get(i);
                int providerUserId = provider.getUserId();
                if (providerUserId != userId) {
                if (providerUserId != userId || provider.zombie) {
                    continue;
                }
                reloadProviderMaskedStateLocked(provider, lockedProfile, quietProfile);
            }
        } finally {
            Binder.restoreCallingIdentity(identity);
        }
    }

    private void reloadProviderMaskedStateLocked(@NonNull Provider provider,
            boolean isProfileLocked, boolean isQuietModeEnabled) {
        final int userId = provider.getUserId();
        boolean changed = provider.setMaskedByLockedProfileLocked(isProfileLocked);
        changed |= provider.setMaskedByQuietProfileLocked(isQuietModeEnabled);

                boolean changed = provider.setMaskedByLockedProfileLocked(lockedProfile);
                changed |= provider.setMaskedByQuietProfileLocked(quietProfile);
                try {
        boolean suspended;
        boolean stopped;
        try {
            suspended = mPackageManager.isPackageSuspendedForUser(
                                provider.id.componentName.getPackageName(), provider.getUserId());
                provider.id.componentName.getPackageName(), userId);
            stopped = mPackageManager.isPackageStoppedForUser(
                                provider.id.componentName.getPackageName(), provider.getUserId());
                    } catch (IllegalArgumentException ex) {
                        // Package not found.
                provider.id.componentName.getPackageName(), userId);
        } catch (Exception e) {
            Slog.e(TAG, "Could not get package suspended/stopped state for "
                    + provider.id.componentName.getPackageName() + " " + provider.getUserId(), e);
            suspended = false;
            stopped = false;
        }
        changed |= provider.setMaskedBySuspendedPackageLocked(suspended);
        changed |= provider.setMaskedByStoppedPackageLocked(stopped);
                } catch (RemoteException e) {
                    Slog.e(TAG, "Failed to query application info", e);
                }

        if (changed) {
            if (provider.isMaskedLocked()) {
                maskWidgetsViewsLocked(provider, null);
@@ -799,10 +807,6 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
            }
        }
    }
        } finally {
            Binder.restoreCallingIdentity(identity);
        }
    }

    /**
     * Incrementally update the masked state due to package suspension state.
@@ -3338,6 +3342,11 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
                    existing.id = providerId;
                    existing.zombie = false;
                    existing.setPartialInfoLocked(info);
                    final int userId = existing.getUserId();
                    final boolean isLockedProfile = !mUserManager.isUserUnlockingOrUnlocked(userId);
                    final boolean isQuietProfile = mUserManager.getUserInfo(userId)
                            .isQuietModeEnabled();
                    reloadProviderMaskedStateLocked(existing, isLockedProfile, isQuietProfile);
                    if (DEBUG) {
                        Slog.i(TAG, "Provider placeholder now reified: " + existing);
                    }