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

Commit 475752ad authored by Adam Lesinski's avatar Adam Lesinski Committed by android-build-merger
Browse files

Merge "OverlayManagerService: Make broadcasts/updates explicit" into oc-dev

am: ec8f3536

Change-Id: Ied4fc0b2fe79c69e6fd1b8677a5d615300119b39
parents 8a9db875 ec8f3536
Loading
Loading
Loading
Loading
+0 −23
Original line number Original line Diff line number Diff line
@@ -3215,13 +3215,6 @@ public class Intent implements Parcelable, Cloneable {
    public static final String ACTION_MEDIA_RESOURCE_GRANTED =
    public static final String ACTION_MEDIA_RESOURCE_GRANTED =
            "android.intent.action.MEDIA_RESOURCE_GRANTED";
            "android.intent.action.MEDIA_RESOURCE_GRANTED";


    /**
     * Broadcast Action: An overlay package has been installed. The data
     * contains the name of the added overlay package.
     * @hide
     */
    public static final String ACTION_OVERLAY_ADDED = "android.intent.action.OVERLAY_ADDED";

    /**
    /**
     * Broadcast Action: An overlay package has changed. The data contains the
     * Broadcast Action: An overlay package has changed. The data contains the
     * name of the overlay package which has changed. This is broadcast on all
     * name of the overlay package which has changed. This is broadcast on all
@@ -3233,22 +3226,6 @@ public class Intent implements Parcelable, Cloneable {
     */
     */
    public static final String ACTION_OVERLAY_CHANGED = "android.intent.action.OVERLAY_CHANGED";
    public static final String ACTION_OVERLAY_CHANGED = "android.intent.action.OVERLAY_CHANGED";


    /**
     * Broadcast Action: An overlay package has been removed. The data contains
     * the name of the overlay package which has been removed.
     * @hide
     */
    public static final String ACTION_OVERLAY_REMOVED = "android.intent.action.OVERLAY_REMOVED";

    /**
     * Broadcast Action: The order of a package's list of overlay packages has
     * changed. The data contains the package name of the overlay package that
     * had its position in the list adjusted.
     * @hide
     */
    public static final String
            ACTION_OVERLAY_PRIORITY_CHANGED = "android.intent.action.OVERLAY_PRIORITY_CHANGED";

    /**
    /**
     * Activity Action: Allow the user to select and return one or more existing
     * Activity Action: Allow the user to select and return one or more existing
     * documents. When invoked, the system will display the various
     * documents. When invoked, the system will display the various
+52 −90
Original line number Original line Diff line number Diff line
@@ -193,13 +193,10 @@ import java.util.concurrent.atomic.AtomicBoolean;
 * </ul>
 * </ul>
 */
 */
public final class OverlayManagerService extends SystemService {
public final class OverlayManagerService extends SystemService {

    static final String TAG = "OverlayManager";
    static final String TAG = "OverlayManager";


    static final boolean DEBUG = false;
    static final boolean DEBUG = false;


    static final String PERMISSION_DENIED = "Operation not permitted for user shell";

    /**
    /**
     * The system property that specifies the default overlays to apply.
     * The system property that specifies the default overlays to apply.
     * This is a semicolon separated list of package names.
     * This is a semicolon separated list of package names.
@@ -234,7 +231,7 @@ public final class OverlayManagerService extends SystemService {
        IdmapManager im = new IdmapManager(installer);
        IdmapManager im = new IdmapManager(installer);
        mSettings = new OverlayManagerSettings();
        mSettings = new OverlayManagerSettings();
        mImpl = new OverlayManagerServiceImpl(mPackageManager, im, mSettings,
        mImpl = new OverlayManagerServiceImpl(mPackageManager, im, mSettings,
                getDefaultOverlayPackages());
                getDefaultOverlayPackages(), new OverlayChangeListener());
        mInitCompleteSignal = SystemServerInitThreadPool.get().submit(() -> {
        mInitCompleteSignal = SystemServerInitThreadPool.get().submit(() -> {
            final IntentFilter packageFilter = new IntentFilter();
            final IntentFilter packageFilter = new IntentFilter();
            packageFilter.addAction(ACTION_PACKAGE_ADDED);
            packageFilter.addAction(ACTION_PACKAGE_ADDED);
@@ -251,9 +248,6 @@ public final class OverlayManagerService extends SystemService {


            restoreSettings();
            restoreSettings();
            onSwitchUser(UserHandle.USER_SYSTEM);
            onSwitchUser(UserHandle.USER_SYSTEM);
            schedulePersistSettings();

            mSettings.addChangeListener(new OverlayChangeListener());


            publishBinderService(Context.OVERLAY_SERVICE, mService);
            publishBinderService(Context.OVERLAY_SERVICE, mService);
            publishLocalService(OverlayManagerService.class, this);
            publishLocalService(OverlayManagerService.class, this);
@@ -281,8 +275,9 @@ public final class OverlayManagerService extends SystemService {
        final List<String> targets;
        final List<String> targets;
        synchronized (mLock) {
        synchronized (mLock) {
            targets = mImpl.onSwitchUser(newUserId);
            targets = mImpl.onSwitchUser(newUserId);
            updateAssetsLocked(newUserId, targets);
        }
        }
        updateAssets(newUserId, targets);
        schedulePersistSettings();
    }
    }


    private static Set<String> getDefaultOverlayPackages() {
    private static Set<String> getDefaultOverlayPackages() {
@@ -348,7 +343,8 @@ public final class OverlayManagerService extends SystemService {
                @NonNull final int[] userIds) {
                @NonNull final int[] userIds) {
            for (final int userId : userIds) {
            for (final int userId : userIds) {
                synchronized (mLock) {
                synchronized (mLock) {
                    final PackageInfo pi = mPackageManager.getPackageInfo(packageName, userId, false);
                    final PackageInfo pi = mPackageManager.getPackageInfo(packageName, userId,
                            false);
                    if (pi != null) {
                    if (pi != null) {
                        mPackageManager.cachePackageInfo(packageName, userId, pi);
                        mPackageManager.cachePackageInfo(packageName, userId, pi);
                        if (!isOverlayPackage(pi)) {
                        if (!isOverlayPackage(pi)) {
@@ -365,7 +361,8 @@ public final class OverlayManagerService extends SystemService {
                @NonNull final int[] userIds) {
                @NonNull final int[] userIds) {
            for (int userId : userIds) {
            for (int userId : userIds) {
                synchronized (mLock) {
                synchronized (mLock) {
                    final PackageInfo pi = mPackageManager.getPackageInfo(packageName, userId, false);
                    final PackageInfo pi = mPackageManager.getPackageInfo(packageName, userId,
                            false);
                    if (pi != null) {
                    if (pi != null) {
                        mPackageManager.cachePackageInfo(packageName, userId, pi);
                        mPackageManager.cachePackageInfo(packageName, userId, pi);
                        if (!isOverlayPackage(pi)) {
                        if (!isOverlayPackage(pi)) {
@@ -397,7 +394,8 @@ public final class OverlayManagerService extends SystemService {
                @NonNull final int[] userIds) {
                @NonNull final int[] userIds) {
            for (int userId : userIds) {
            for (int userId : userIds) {
                synchronized (mLock) {
                synchronized (mLock) {
                    final PackageInfo pi = mPackageManager.getPackageInfo(packageName, userId, false);
                    final PackageInfo pi = mPackageManager.getPackageInfo(packageName, userId,
                            false);
                    if (pi != null) {
                    if (pi != null) {
                        mPackageManager.cachePackageInfo(packageName, userId, pi);
                        mPackageManager.cachePackageInfo(packageName, userId, pi);
                        if (!isOverlayPackage(pi)) {
                        if (!isOverlayPackage(pi)) {
@@ -449,8 +447,7 @@ public final class OverlayManagerService extends SystemService {


    private final IBinder mService = new IOverlayManager.Stub() {
    private final IBinder mService = new IOverlayManager.Stub() {
        @Override
        @Override
        public Map<String, List<OverlayInfo>> getAllOverlays(int userId)
        public Map<String, List<OverlayInfo>> getAllOverlays(int userId) throws RemoteException {
                throws RemoteException {
            userId = handleIncomingUser(userId, "getAllOverlays");
            userId = handleIncomingUser(userId, "getAllOverlays");


            synchronized (mLock) {
            synchronized (mLock) {
@@ -508,14 +505,14 @@ public final class OverlayManagerService extends SystemService {
                int userId) throws RemoteException {
                int userId) throws RemoteException {
            enforceChangeOverlayPackagesPermission("setEnabled");
            enforceChangeOverlayPackagesPermission("setEnabled");
            userId = handleIncomingUser(userId, "setEnabled");
            userId = handleIncomingUser(userId, "setEnabled");
            if (packageName == null) {
            if (packageName == null || !enable) {
                return false;
                return false;
            }
            }


            final long ident = Binder.clearCallingIdentity();
            final long ident = Binder.clearCallingIdentity();
            try {
            try {
                synchronized (mLock) {
                synchronized (mLock) {
                    return mImpl.setEnabledExclusive(packageName, enable, userId);
                    return mImpl.setEnabledExclusive(packageName, userId);
                }
                }
            } finally {
            } finally {
                Binder.restoreCallingIdentity(ident);
                Binder.restoreCallingIdentity(ident);
@@ -643,68 +640,24 @@ public final class OverlayManagerService extends SystemService {
        return pi != null && pi.overlayTarget != null;
        return pi != null && pi.overlayTarget != null;
    }
    }


    private final class OverlayChangeListener implements OverlayManagerSettings.ChangeListener {
    private final class OverlayChangeListener
            implements OverlayManagerServiceImpl.OverlayChangeListener {
        @Override
        @Override
        public void onSettingsChanged() {
        public void onOverlaysChanged(@NonNull final String targetPackageName, final int userId) {
            schedulePersistSettings();
            schedulePersistSettings();
            FgThread.getHandler().post(() -> {
                synchronized (mLock) {
                    updateAssetsLocked(userId, targetPackageName);
                }
                }


        @Override
                final Intent intent = new Intent(Intent.ACTION_OVERLAY_CHANGED,
        public void onOverlayAdded(@NonNull final OverlayInfo oi) {
                        Uri.fromParts("package", targetPackageName, null));
            scheduleBroadcast(Intent.ACTION_OVERLAY_ADDED, oi, oi.isEnabled());
        }

        @Override
        public void onOverlayRemoved(@NonNull final OverlayInfo oi) {
            scheduleBroadcast(Intent.ACTION_OVERLAY_REMOVED, oi, oi.isEnabled());
        }

        @Override
        public void onOverlayChanged(@NonNull final OverlayInfo oi,
                @NonNull final OverlayInfo oldOi) {
            scheduleBroadcast(Intent.ACTION_OVERLAY_CHANGED, oi, oi.isEnabled() != oldOi.isEnabled());
        }

        @Override
        public void onOverlayPriorityChanged(@NonNull final OverlayInfo oi) {
            scheduleBroadcast(Intent.ACTION_OVERLAY_PRIORITY_CHANGED, oi, oi.isEnabled());
        }

        private void scheduleBroadcast(@NonNull final String action, @NonNull final OverlayInfo oi,
                final boolean doUpdate) {
            FgThread.getHandler().post(new BroadcastRunnable(action, oi, doUpdate));
        }

        private final class BroadcastRunnable implements Runnable {
            private final String mAction;
            private final OverlayInfo mOverlayInfo;
            private final boolean mDoUpdate;

            BroadcastRunnable(@NonNull final String action, @NonNull final OverlayInfo oi,
                    final boolean doUpdate) {
                mAction = action;
                mOverlayInfo = oi;
                mDoUpdate = doUpdate;
            }

            @Override
            public void run() {
                if (mDoUpdate) {
                    updateAssets(mOverlayInfo.userId, mOverlayInfo.targetPackageName);
                }
                sendBroadcast(mAction, mOverlayInfo.targetPackageName, mOverlayInfo.packageName,
                        mOverlayInfo.userId);
            }

            private void sendBroadcast(@NonNull final String action,
                    @NonNull final String targetPackageName, @NonNull final String packageName,
                    final int userId) {
                final Intent intent = new Intent(action, Uri.fromParts("package",
                            String.format("%s/%s", targetPackageName, packageName), null));
                intent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);
                intent.setFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT);

                if (DEBUG) {
                if (DEBUG) {
                    Slog.d(TAG, String.format("send broadcast %s", intent));
                    Slog.d(TAG, "send broadcast " + intent);
                }
                }

                try {
                try {
                    ActivityManager.getService().broadcastIntent(null, intent, null, null, 0,
                    ActivityManager.getService().broadcastIntent(null, intent, null, null, 0,
                            null, null, null, android.app.AppOpsManager.OP_NONE, null, false, false,
                            null, null, null, android.app.AppOpsManager.OP_NONE, null, false, false,
@@ -712,18 +665,20 @@ public final class OverlayManagerService extends SystemService {
                } catch (RemoteException e) {
                } catch (RemoteException e) {
                    // Intentionally left empty.
                    // Intentionally left empty.
                }
                }
            }
            });

        }
        }
    }
    }


    private void updateAssets(final int userId, final String targetPackageName) {
    private void updateAssetsLocked(final int userId, final String targetPackageName) {
        final List<String> list = new ArrayList<>();
        final List<String> list = new ArrayList<>();
        list.add(targetPackageName);
        list.add(targetPackageName);
        updateAssets(userId, list);
        updateAssetsLocked(userId, list);
    }
    }


    private void updateAssets(final int userId, List<String> targetPackageNames) {
    private void updateAssetsLocked(final int userId, List<String> targetPackageNames) {
        if (DEBUG) {
            Slog.d(TAG, "Updating overlay assets");
        }
        final PackageManagerInternal pm = LocalServices.getService(PackageManagerInternal.class);
        final PackageManagerInternal pm = LocalServices.getService(PackageManagerInternal.class);
        final boolean updateFrameworkRes = targetPackageNames.contains("android");
        final boolean updateFrameworkRes = targetPackageNames.contains("android");
        if (updateFrameworkRes) {
        if (updateFrameworkRes) {
@@ -743,6 +698,12 @@ public final class OverlayManagerService extends SystemService {
        final int N = targetPackageNames.size();
        final int N = targetPackageNames.size();
        for (int i = 0; i < N; i++) {
        for (int i = 0; i < N; i++) {
            final String targetPackageName = targetPackageNames.get(i);
            final String targetPackageName = targetPackageNames.get(i);
            if (DEBUG) {
                Slog.d(TAG, "-> Updating overlay: target=" + targetPackageName + " overlays=["
                        + TextUtils.join(",", pendingChanges.get(targetPackageName))
                        + "] userId=" + userId);
            }

            if (!pm.setEnabledOverlayPackages(
            if (!pm.setEnabledOverlayPackages(
                        userId, targetPackageName, pendingChanges.get(targetPackageName))) {
                        userId, targetPackageName, pendingChanges.get(targetPackageName))) {
                Slog.e(TAG, String.format("Failed to change enabled overlays for %s user %d",
                Slog.e(TAG, String.format("Failed to change enabled overlays for %s user %d",
@@ -762,10 +723,11 @@ public final class OverlayManagerService extends SystemService {
        if (mPersistSettingsScheduled.getAndSet(true)) {
        if (mPersistSettingsScheduled.getAndSet(true)) {
            return;
            return;
        }
        }
        IoThread.getHandler().post(new Runnable() {
        IoThread.getHandler().post(() -> {
            @Override
            public void run() {
            mPersistSettingsScheduled.set(false);
            mPersistSettingsScheduled.set(false);
            if (DEBUG) {
                Slog.d(TAG, "Writing overlay settings");
            }
            synchronized (mLock) {
            synchronized (mLock) {
                FileOutputStream stream = null;
                FileOutputStream stream = null;
                try {
                try {
@@ -777,7 +739,6 @@ public final class OverlayManagerService extends SystemService {
                    Slog.e(TAG, "failed to persist overlay state", e);
                    Slog.e(TAG, "failed to persist overlay state", e);
                }
                }
            }
            }
            }
        });
        });
    }
    }


@@ -862,7 +823,8 @@ public final class OverlayManagerService extends SystemService {
            // The package manager does not support different versions of packages
            // The package manager does not support different versions of packages
            // to be installed for different users: ignore userId for now.
            // to be installed for different users: ignore userId for now.
            try {
            try {
                return mPackageManager.checkSignatures(packageName1, packageName2) == SIGNATURE_MATCH;
                return mPackageManager.checkSignatures(
                        packageName1, packageName2) == SIGNATURE_MATCH;
            } catch (RemoteException e) {
            } catch (RemoteException e) {
                // Intentionally left blank
                // Intentionally left blank
            }
            }
+122 −33
Original line number Original line Diff line number Diff line
@@ -54,15 +54,18 @@ final class OverlayManagerServiceImpl {
    private final IdmapManager mIdmapManager;
    private final IdmapManager mIdmapManager;
    private final OverlayManagerSettings mSettings;
    private final OverlayManagerSettings mSettings;
    private final Set<String> mDefaultOverlays;
    private final Set<String> mDefaultOverlays;
    private final OverlayChangeListener mListener;


    OverlayManagerServiceImpl(@NonNull final PackageManagerHelper packageManager,
    OverlayManagerServiceImpl(@NonNull final PackageManagerHelper packageManager,
            @NonNull final IdmapManager idmapManager,
            @NonNull final IdmapManager idmapManager,
            @NonNull final OverlayManagerSettings settings,
            @NonNull final OverlayManagerSettings settings,
            @NonNull final Set<String> defaultOverlays) {
            @NonNull final Set<String> defaultOverlays,
            @NonNull final OverlayChangeListener listener) {
        mPackageManager = packageManager;
        mPackageManager = packageManager;
        mIdmapManager = idmapManager;
        mIdmapManager = idmapManager;
        mSettings = settings;
        mSettings = settings;
        mDefaultOverlays = defaultOverlays;
        mDefaultOverlays = defaultOverlays;
        mListener = listener;
    }
    }


    /*
    /*
@@ -145,7 +148,6 @@ final class OverlayManagerServiceImpl {
                iter.remove();
                iter.remove();
            }
            }
        }
        }

        return new ArrayList<>(packagesToUpdateAssets);
        return new ArrayList<>(packagesToUpdateAssets);
    }
    }


@@ -199,25 +201,30 @@ final class OverlayManagerServiceImpl {
        updateAllOverlaysForTarget(packageName, userId, null);
        updateAllOverlaysForTarget(packageName, userId, null);
    }
    }


    private void updateAllOverlaysForTarget(@NonNull final String packageName, final int userId,
    /**
     * Returns true if the settings were modified for this target.
     */
    private boolean updateAllOverlaysForTarget(@NonNull final String packageName, final int userId,
            @Nullable final PackageInfo targetPackage) {
            @Nullable final PackageInfo targetPackage) {
        boolean modified = false;
        final List<OverlayInfo> ois = mSettings.getOverlaysForTarget(packageName, userId);
        final List<OverlayInfo> ois = mSettings.getOverlaysForTarget(packageName, userId);
        final int N = ois.size();
        final int N = ois.size();
        for (int i = 0; i < N; i++) {
        for (int i = 0; i < N; i++) {
            final OverlayInfo oi = ois.get(i);
            final OverlayInfo oi = ois.get(i);
            final PackageInfo overlayPackage = mPackageManager.getPackageInfo(oi.packageName, userId);
            final PackageInfo overlayPackage = mPackageManager.getPackageInfo(oi.packageName, userId);
            if (overlayPackage == null) {
            if (overlayPackage == null) {
                mSettings.remove(oi.packageName, oi.userId);
                modified |= mSettings.remove(oi.packageName, oi.userId);
                removeIdmapIfPossible(oi);
                removeIdmapIfPossible(oi);
            } else {
            } else {
                try {
                try {
                    updateState(targetPackage, overlayPackage, userId);
                    modified |= updateState(targetPackage, overlayPackage, userId);
                } catch (OverlayManagerSettings.BadKeyException e) {
                } catch (OverlayManagerSettings.BadKeyException e) {
                    Slog.e(TAG, "failed to update settings", e);
                    Slog.e(TAG, "failed to update settings", e);
                    mSettings.remove(oi.packageName, userId);
                    modified |= mSettings.remove(oi.packageName, userId);
                }
                }
            }
            }
        }
        }
        return modified;
    }
    }


    void onOverlayPackageAdded(@NonNull final String packageName, final int userId) {
    void onOverlayPackageAdded(@NonNull final String packageName, final int userId) {
@@ -238,7 +245,9 @@ final class OverlayManagerServiceImpl {
        mSettings.init(packageName, userId, overlayPackage.overlayTarget,
        mSettings.init(packageName, userId, overlayPackage.overlayTarget,
                overlayPackage.applicationInfo.getBaseCodePath());
                overlayPackage.applicationInfo.getBaseCodePath());
        try {
        try {
            updateState(targetPackage, overlayPackage, userId);
            if (updateState(targetPackage, overlayPackage, userId)) {
                mListener.onOverlaysChanged(overlayPackage.overlayTarget, userId);
            }
        } catch (OverlayManagerSettings.BadKeyException e) {
        } catch (OverlayManagerSettings.BadKeyException e) {
            Slog.e(TAG, "failed to update settings", e);
            Slog.e(TAG, "failed to update settings", e);
            mSettings.remove(packageName, userId);
            mSettings.remove(packageName, userId);
@@ -289,8 +298,9 @@ final class OverlayManagerServiceImpl {
        if (overlayPackage == null) {
        if (overlayPackage == null) {
            return false;
            return false;
        }
        }
        // Static overlay is always being enabled.

        if (!enable && overlayPackage.isStaticOverlay) {
        // Ignore static overlays.
        if (overlayPackage.isStaticOverlay) {
            return false;
            return false;
        }
        }


@@ -298,19 +308,21 @@ final class OverlayManagerServiceImpl {
            final OverlayInfo oi = mSettings.getOverlayInfo(packageName, userId);
            final OverlayInfo oi = mSettings.getOverlayInfo(packageName, userId);
            final PackageInfo targetPackage =
            final PackageInfo targetPackage =
                    mPackageManager.getPackageInfo(oi.targetPackageName, userId);
                    mPackageManager.getPackageInfo(oi.targetPackageName, userId);
            mSettings.setEnabled(packageName, userId, enable);
            boolean modified = mSettings.setEnabled(packageName, userId, enable);
            updateState(targetPackage, overlayPackage, userId);
            modified |= updateState(targetPackage, overlayPackage, userId);

            if (modified) {
                mListener.onOverlaysChanged(oi.targetPackageName, userId);
            }
            return true;
            return true;
        } catch (OverlayManagerSettings.BadKeyException e) {
        } catch (OverlayManagerSettings.BadKeyException e) {
            return false;
            return false;
        }
        }
    }
    }


    boolean setEnabledExclusive(@NonNull final String packageName, final boolean enable,
    boolean setEnabledExclusive(@NonNull final String packageName, final int userId) {
            final int userId) {
        if (DEBUG) {
        if (DEBUG) {
            Slog.d(TAG, String.format("setEnabled packageName=%s enable=%s userId=%d",
            Slog.d(TAG, String.format("setEnabledExclusive packageName=%s userId=%d", packageName, userId));
                        packageName, enable, userId));
        }
        }


        final PackageInfo overlayPackage = mPackageManager.getPackageInfo(packageName, userId);
        final PackageInfo overlayPackage = mPackageManager.getPackageInfo(packageName, userId);
@@ -320,23 +332,48 @@ final class OverlayManagerServiceImpl {


        try {
        try {
            final OverlayInfo oi = mSettings.getOverlayInfo(packageName, userId);
            final OverlayInfo oi = mSettings.getOverlayInfo(packageName, userId);
            final PackageInfo targetPackage =
                    mPackageManager.getPackageInfo(oi.targetPackageName, userId);

            List<OverlayInfo> allOverlays = getOverlayInfosForTarget(oi.targetPackageName, userId);
            List<OverlayInfo> allOverlays = getOverlayInfosForTarget(oi.targetPackageName, userId);


            boolean modified = false;

            // Disable all other overlays.
            // Disable all other overlays.
            allOverlays.remove(oi);
            allOverlays.remove(oi);
            for (int i = 0; i < allOverlays.size(); i++) {
            for (int i = 0; i < allOverlays.size(); i++) {
                // TODO: Optimize this to only send updates after all changes.
                final String disabledOverlayPackageName = allOverlays.get(i).packageName;
                setEnabled(allOverlays.get(i).packageName, false, userId);
                final PackageInfo disabledOverlayPackageInfo = mPackageManager.getPackageInfo(
                        disabledOverlayPackageName, userId);
                if (disabledOverlayPackageInfo == null) {
                    modified |= mSettings.remove(disabledOverlayPackageName, userId);
                    continue;
                }

                if (disabledOverlayPackageInfo.isStaticOverlay) {
                    // Don't touch static overlays.
                    continue;
                }
                }


            setEnabled(packageName, enable, userId);
                // Disable the overlay.
                modified |= mSettings.setEnabled(disabledOverlayPackageName, userId, false);
                modified |= updateState(targetPackage, disabledOverlayPackageInfo, userId);
            }

            // Enable the selected overlay.
            modified |= mSettings.setEnabled(packageName, userId, true);
            modified |= updateState(targetPackage, overlayPackage, userId);

            if (modified) {
                mListener.onOverlaysChanged(oi.targetPackageName, userId);
            }
            return true;
            return true;
        } catch (OverlayManagerSettings.BadKeyException e) {
        } catch (OverlayManagerSettings.BadKeyException e) {
            return false;
            return false;
        }
        }
    }
    }


    boolean isPackageUpdatableOverlay(@NonNull final String packageName, final int userId) {
    private boolean isPackageUpdatableOverlay(@NonNull final String packageName, final int userId) {
        final PackageInfo overlayPackage = mPackageManager.getPackageInfo(packageName, userId);
        final PackageInfo overlayPackage = mPackageManager.getPackageInfo(packageName, userId);
        if (overlayPackage == null || overlayPackage.isStaticOverlay) {
        if (overlayPackage == null || overlayPackage.isStaticOverlay) {
            return false;
            return false;
@@ -346,18 +383,64 @@ final class OverlayManagerServiceImpl {


    boolean setPriority(@NonNull final String packageName,
    boolean setPriority(@NonNull final String packageName,
            @NonNull final String newParentPackageName, final int userId) {
            @NonNull final String newParentPackageName, final int userId) {
        return isPackageUpdatableOverlay(packageName, userId) &&
        if (DEBUG) {
                mSettings.setPriority(packageName, newParentPackageName, userId);
            Slog.d(TAG, "setPriority packageName=" + packageName + " newParentPackageName="
                    + newParentPackageName + " userId=" + userId);
        }

        if (!isPackageUpdatableOverlay(packageName, userId)) {
            return false;
        }

        final PackageInfo overlayPackage = mPackageManager.getPackageInfo(packageName, userId);
        if (overlayPackage == null) {
            return false;
        }

        if (mSettings.setPriority(packageName, newParentPackageName, userId)) {
            mListener.onOverlaysChanged(overlayPackage.overlayTarget, userId);
        }
        return true;
    }
    }


    boolean setHighestPriority(@NonNull final String packageName, final int userId) {
    boolean setHighestPriority(@NonNull final String packageName, final int userId) {
        return isPackageUpdatableOverlay(packageName, userId) &&
        if (DEBUG) {
                mSettings.setHighestPriority(packageName, userId);
            Slog.d(TAG, "setHighestPriority packageName=" + packageName + " userId=" + userId);
        }

        if (!isPackageUpdatableOverlay(packageName, userId)) {
            return false;
        }

        final PackageInfo overlayPackage = mPackageManager.getPackageInfo(packageName, userId);
        if (overlayPackage == null) {
            return false;
        }

        if (mSettings.setHighestPriority(packageName, userId)) {
            mListener.onOverlaysChanged(overlayPackage.overlayTarget, userId);
        }
        return true;
    }
    }


    boolean setLowestPriority(@NonNull final String packageName, final int userId) {
    boolean setLowestPriority(@NonNull final String packageName, final int userId) {
        return isPackageUpdatableOverlay(packageName, userId) &&
        if (DEBUG) {
                mSettings.setLowestPriority(packageName, userId);
            Slog.d(TAG, "setLowestPriority packageName=" + packageName + " userId=" + userId);
        }

        if (!isPackageUpdatableOverlay(packageName, userId)) {
            return false;
        }

        final PackageInfo overlayPackage = mPackageManager.getPackageInfo(packageName, userId);
        if (overlayPackage == null) {
            return false;
        }

        if (mSettings.setLowestPriority(packageName, userId)) {
            mListener.onOverlaysChanged(overlayPackage.overlayTarget, userId);
        }
        return true;
    }
    }


    void onDump(@NonNull final PrintWriter pw) {
    void onDump(@NonNull final PrintWriter pw) {
@@ -379,7 +462,10 @@ final class OverlayManagerServiceImpl {
        return paths;
        return paths;
    }
    }


    private void updateState(@Nullable final PackageInfo targetPackage,
    /**
     * Returns true if the settings/state was modified, false otherwise.
     */
    private boolean updateState(@Nullable final PackageInfo targetPackage,
            @NonNull final PackageInfo overlayPackage, final int userId)
            @NonNull final PackageInfo overlayPackage, final int userId)
            throws OverlayManagerSettings.BadKeyException {
            throws OverlayManagerSettings.BadKeyException {
        // Static RROs targeting to "android", ie framework-res.apk, are handled by native layers.
        // Static RROs targeting to "android", ie framework-res.apk, are handled by native layers.
@@ -388,7 +474,7 @@ final class OverlayManagerServiceImpl {
            mIdmapManager.createIdmap(targetPackage, overlayPackage, userId);
            mIdmapManager.createIdmap(targetPackage, overlayPackage, userId);
        }
        }


        mSettings.setBaseCodePath(overlayPackage.packageName, userId,
        boolean modified = mSettings.setBaseCodePath(overlayPackage.packageName, userId,
                overlayPackage.applicationInfo.getBaseCodePath());
                overlayPackage.applicationInfo.getBaseCodePath());


        final int currentState = mSettings.getState(overlayPackage.packageName, userId);
        final int currentState = mSettings.getState(overlayPackage.packageName, userId);
@@ -400,8 +486,9 @@ final class OverlayManagerServiceImpl {
                            OverlayInfo.stateToString(currentState),
                            OverlayInfo.stateToString(currentState),
                            OverlayInfo.stateToString(newState)));
                            OverlayInfo.stateToString(newState)));
            }
            }
            mSettings.setState(overlayPackage.packageName, userId, newState);
            modified |= mSettings.setState(overlayPackage.packageName, userId, newState);
        }
        }
        return modified;
    }
    }


    private int calculateNewState(@Nullable final PackageInfo targetPackage,
    private int calculateNewState(@Nullable final PackageInfo targetPackage,
@@ -441,10 +528,8 @@ final class OverlayManagerServiceImpl {
        if (!mIdmapManager.idmapExists(oi)) {
        if (!mIdmapManager.idmapExists(oi)) {
            return;
            return;
        }
        }
        final List<Integer> userIds = mSettings.getUsers();
        final int[] userIds = mSettings.getUsers();
        final int N = userIds.size();
        for (int userId : userIds) {
        for (int i = 0; i < N; i++) {
            final int userId = userIds.get(i);
            try {
            try {
                final OverlayInfo tmp = mSettings.getOverlayInfo(oi.packageName, userId);
                final OverlayInfo tmp = mSettings.getOverlayInfo(oi.packageName, userId);
                if (tmp != null && tmp.isEnabled()) {
                if (tmp != null && tmp.isEnabled()) {
@@ -458,6 +543,10 @@ final class OverlayManagerServiceImpl {
        mIdmapManager.removeIdmap(oi, oi.userId);
        mIdmapManager.removeIdmap(oi, oi.userId);
    }
    }


    interface OverlayChangeListener {
        void onOverlaysChanged(@NonNull String targetPackage, int userId);
    }

    interface PackageManagerHelper {
    interface PackageManagerHelper {
        PackageInfo getPackageInfo(@NonNull String packageName, int userId);
        PackageInfo getPackageInfo(@NonNull String packageName, int userId);
        boolean signaturesMatching(@NonNull String packageName1, @NonNull String packageName2,
        boolean signaturesMatching(@NonNull String packageName1, @NonNull String packageName2,
+173 −319

File changed.

Preview size limit exceeded, changes collapsed.