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

Commit 477ecd76 authored by Kenny Guy's avatar Kenny Guy Committed by Android (Google) Code Review
Browse files

Merge "Allow widget hosts to see widgets from locked profiles." into nyc-dev

parents 92584673 33f9a9c2
Loading
Loading
Loading
Loading
+60 −19
Original line number Diff line number Diff line
@@ -159,7 +159,7 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
                reloadWidgetsMaskedStateForUser(userId);
            } else if (Intent.ACTION_MANAGED_PROFILE_AVAILABILITY_CHANGED.equals(action)) {
                synchronized (mLock) {
                    reloadWidgetQuietModeMaskedStateLocked(userId);
                    reloadWidgetProfileUnavailableMaskedStateLocked(userId);
                }
            } else if (Intent.ACTION_PACKAGES_SUSPENDED.equals(action)) {
                String[] packages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
@@ -432,7 +432,7 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku

    /**
     * Reload all widgets' masked state for the given user and its associated profiles, including
     * due to quiet mode and package suspension.
     * due to user not being available and package suspension.
     */
    private void reloadWidgetsMaskedStateForUser(int userId) {
        if (!mUserManager.isUserUnlocked(userId)) return;
@@ -442,7 +442,7 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
            if (profiles != null) {
                for (int i = 0; i < profiles.size(); i++) {
                    UserInfo user  = profiles.get(i);
                    reloadWidgetQuietModeMaskedStateLocked(user.id);
                    reloadWidgetProfileUnavailableMaskedStateLocked(user.id);
                    reloadWidgetPackageSuspensionMaskedStateLocked(user.id);
                }
            }
@@ -450,17 +450,18 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
    }

    /**
     * Mask/unmask widgets in the given profile, depending on the quiet state of the profile.
     * Mask/unmask widgets in the given profile, depending on the quiet state
     * or locked state of the profile.
     */
    private void reloadWidgetQuietModeMaskedStateLocked(int profileId) {
        if (!mUserManager.isUserUnlocked(profileId)) return;
    private void reloadWidgetProfileUnavailableMaskedStateLocked(int profileId) {
        final long identity = Binder.clearCallingIdentity();
        try {
            UserInfo user  = mUserManager.getUserInfo(profileId);
            if (!user.isManagedProfile()) {
            if (!isProfileWithUnlockedParent(profileId)) {
                return;
            }
            boolean shouldMask = user.isQuietModeEnabled();
            UserInfo user  = mUserManager.getUserInfo(profileId);
            boolean shouldMask = user.isQuietModeEnabled() ||
                    !mUserManager.isUserUnlocked(user.getUserHandle());
            final int N = mProviders.size();
            for (int i = 0; i < N; i++) {
                Provider provider = mProviders.get(i);
@@ -468,7 +469,7 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
                if (providerUserId != profileId) {
                    continue;
                }
                if (provider.setMaskedByQuietProfileLocked(shouldMask)) {
                if (provider.setMaskedByProfileUnavailabledLocked(shouldMask)) {
                    if (provider.isMaskedLocked()) {
                        maskWidgetsViewsLocked(provider);
                    } else {
@@ -537,8 +538,8 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
        }
    }

    private void maskWidgetsViewsLocked(Provider provider) {
        Bitmap iconBitmap = null;
    private Bitmap createMaskedWidgetBitmap(Provider provider) {
        final long identity = Binder.clearCallingIdentity();
        try {
            // Load the unbadged application icon and pass it to the widget to appear on
            // the masked view.
@@ -548,11 +549,20 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
            PackageManager pm = userContext.getPackageManager();
            Drawable icon = pm.getApplicationInfo(providerPackage, 0).loadUnbadgedIcon(pm);
            // Create a bitmap of the icon which is what the widget's remoteview requires.
            iconBitmap = mIconUtilities.createIconBitmap(icon);
            return mIconUtilities.createIconBitmap(icon);
        } catch (NameNotFoundException e) {
            Slog.e(TAG, "Fail to get application icon", e);
            // Provider package removed, no need to mask its views as its state will be
            // purged very soon.
            return null;
        } finally {
            Binder.restoreCallingIdentity(identity);
        }
    }

    private void maskWidgetsViewsLocked(Provider provider) {
        Bitmap iconBitmap = createMaskedWidgetBitmap(provider);
        if (iconBitmap == null) {
            return;
        }

@@ -2320,7 +2330,7 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
                final PackageManager pm = mContext.getPackageManager();
                final int userId = UserHandle.getUserId(providerId.uid);
                final ApplicationInfo app = pm.getApplicationInfoAsUser(activityInfo.packageName,
                        PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId);
                        0, userId);
                resources = pm.getResourcesForApplication(app);
            } finally {
                Binder.restoreCallingIdentity(identity);
@@ -2423,9 +2433,16 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
            int flags = PackageManager.GET_META_DATA;

            // We really need packages to be around and parsed to know if they
            // provide widgets, and we only load widgets after user is unlocked.
            // provide widgets.
            flags |= PackageManager.MATCH_DEBUG_TRIAGED_MISSING;

            // Widget hosts that are non-crypto aware may be hosting widgets
            // from a profile that is still locked, so let them see those
            // widgets.
            if (isProfileWithUnlockedParent(userId)) {
                flags |= PackageManager.MATCH_ENCRYPTION_AWARE_AND_UNAWARE;
            }

            // Widgets referencing shared libraries need to have their
            // dependencies loaded.
            flags |= PackageManager.GET_SHARED_LIBRARY_FILES;
@@ -2443,6 +2460,7 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
    private void onUserUnlocked(int userId) {
        synchronized (mLock) {
            ensureGroupStateLoadedLocked(userId);
            reloadWidgetsMaskedStateForUser(userId);

            final int N = mProviders.size();
            for (int i = 0; i < N; i++) {
@@ -2580,6 +2598,17 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
            mWidgetPackages.put(userId, packages = new ArraySet<String>());
        }
        packages.add(widget.provider.info.provider.getPackageName());

        // If we are adding a widget it might be for a provider that
        // is currently masked, if so mask the widget.
        if (widget.provider.isMaskedLocked()) {
            Bitmap bitmap = createMaskedWidgetBitmap(widget.provider);
            if (bitmap != null) {
                widget.replaceWithMaskedViewsLocked(mContext, bitmap);
            }
        } else {
            widget.clearMaskedViewsLocked();
        }
    }

    /**
@@ -3277,6 +3306,18 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
        }
    }

    private boolean isProfileWithUnlockedParent(int userId) {
        UserInfo userInfo = mUserManager.getUserInfo(userId);
        if (userInfo != null && userInfo.isManagedProfile()) {
            UserInfo parentInfo = mUserManager.getProfileParent(userId);
            if (parentInfo != null
                    && mUserManager.isUserUnlocked(parentInfo.getUserHandle())) {
                return true;
            }
        }
        return false;
    }

    private final class CallbackHandler extends Handler {
        public static final int MSG_NOTIFY_UPDATE_APP_WIDGET = 1;
        public static final int MSG_NOTIFY_PROVIDER_CHANGED = 2;
@@ -3554,7 +3595,7 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
        PendingIntent broadcast;
        boolean zombie; // if we're in safe mode, don't prune this just because nobody references it

        boolean maskedByQuietProfile;
        boolean maskedByProfileUnavailable;
        boolean maskedBySuspendedPackage;

        int tag = TAG_UNDEFINED; // for use while saving state (the index)
@@ -3587,9 +3628,9 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
        }

        // returns true if the provider's masked state is changed as a result
        public boolean setMaskedByQuietProfileLocked(boolean masked) {
        public boolean setMaskedByProfileUnavailabledLocked(boolean masked) {
            boolean oldMaskedState = isMaskedLocked();
            maskedByQuietProfile = masked;
            maskedByProfileUnavailable = masked;
            return isMaskedLocked() != oldMaskedState;
        }

@@ -3601,7 +3642,7 @@ class AppWidgetServiceImpl extends IAppWidgetService.Stub implements WidgetBacku
        }

        public boolean isMaskedLocked() {
            return maskedByQuietProfile || maskedBySuspendedPackage;
            return maskedByProfileUnavailable || maskedBySuspendedPackage;
        }
    }