Loading core/java/android/content/om/OverlayInfo.java +26 −3 Original line number Diff line number Diff line Loading @@ -18,7 +18,6 @@ package android.content.om; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.os.Parcel; import android.os.Parcelable; Loading Loading @@ -125,6 +124,23 @@ public final class OverlayInfo implements Parcelable { */ public final int userId; /** * Priority as read from the manifest. Used if isStatic is true. Not * intended to be exposed to 3rd party. * * @hide */ public final int priority; /** * isStatic as read from the manifest. If true, the overlay is * unconditionally loaded and cannot be unloaded. Not intended to be * exposed to 3rd party. * * @hide */ public final boolean isStatic; /** * Create a new OverlayInfo based on source with an updated state. * Loading @@ -133,17 +149,20 @@ public final class OverlayInfo implements Parcelable { */ public OverlayInfo(@NonNull OverlayInfo source, @State int state) { this(source.packageName, source.targetPackageName, source.category, source.baseCodePath, state, source.userId); state, source.userId, source.priority, source.isStatic); } public OverlayInfo(@NonNull String packageName, @NonNull String targetPackageName, @Nullable String category, @NonNull String baseCodePath, int state, int userId) { @NonNull String category, @NonNull String baseCodePath, int state, int userId, int priority, boolean isStatic) { this.packageName = packageName; this.targetPackageName = targetPackageName; this.category = category; this.baseCodePath = baseCodePath; this.state = state; this.userId = userId; this.priority = priority; this.isStatic = isStatic; ensureValidState(); } Loading @@ -154,6 +173,8 @@ public final class OverlayInfo implements Parcelable { baseCodePath = source.readString(); state = source.readInt(); userId = source.readInt(); priority = source.readInt(); isStatic = source.readBoolean(); ensureValidState(); } Loading Loading @@ -194,6 +215,8 @@ public final class OverlayInfo implements Parcelable { dest.writeString(baseCodePath); dest.writeInt(state); dest.writeInt(userId); dest.writeInt(priority); dest.writeBoolean(isStatic); } public static final Parcelable.Creator<OverlayInfo> CREATOR = Loading services/core/java/com/android/server/om/OverlayManagerServiceImpl.java +64 −29 Original line number Diff line number Diff line Loading @@ -63,6 +63,38 @@ final class OverlayManagerServiceImpl { private final String[] mDefaultOverlays; private final OverlayChangeListener mListener; /** * Helper method to merge the overlay manager's (as read from overlays.xml) * and package manager's (as parsed from AndroidManifest.xml files) views * on overlays. * * Both managers are usually in agreement, but especially after an OTA things * may differ. The package manager is always providing the truth; the overlay * manager has to adapt. Depending on what has changed about an overlay, we * should either scrap the overlay manager's previous settings or merge the old * settings with the new. */ private static boolean mustReinitializeOverlay(@NonNull final PackageInfo theTruth, @Nullable final OverlayInfo oldSettings) { if (oldSettings == null) { return true; } if (!Objects.equals(theTruth.overlayTarget, oldSettings.targetPackageName)) { return true; } if (theTruth.isStaticOverlayPackage() != oldSettings.isStatic) { return true; } // a change in priority is only relevant for static RROs: specifically, // a regular RRO should not have its state reset only because a change // in priority if (theTruth.isStaticOverlayPackage() && theTruth.overlayPriority != oldSettings.priority) { return true; } return false; } OverlayManagerServiceImpl(@NonNull final PackageManagerHelper packageManager, @NonNull final IdmapManager idmapManager, @NonNull final OverlayManagerSettings settings, Loading Loading @@ -99,42 +131,29 @@ final class OverlayManagerServiceImpl { } } // Reset overlays if something critical like the target package name // has changed List<PackageInfo> overlayPackages = mPackageManager.getOverlayPackages(newUserId); final int overlayPackagesSize = overlayPackages.size(); for (int i = 0; i < overlayPackagesSize; i++) { final PackageInfo overlayPackage = overlayPackages.get(i); final OverlayInfo oi = storedOverlayInfos.get(overlayPackage.packageName); if (oi == null || !oi.targetPackageName.equals(overlayPackage.overlayTarget)) { // Reset the overlay if it didn't exist or had the wrong target package. if (mustReinitializeOverlay(overlayPackage, oi)) { // if targetPackageName has changed the package that *used* to // be the target must also update its assets if (oi != null) { packagesToUpdateAssets.add(oi.targetPackageName); } mSettings.init(overlayPackage.packageName, newUserId, overlayPackage.overlayTarget, overlayPackage.applicationInfo.getBaseCodePath(), overlayPackage.isStaticOverlayPackage(), overlayPackage.overlayPriority, overlayPackage.overlayCategory); if (oi != null) { // The targetPackageName we have stored doesn't match the overlay's target. // Queue the old target for an update as well. packagesToUpdateAssets.add(oi.targetPackageName); } } else { // Update all other components of an overlay that don't require a hard reset. if (!Objects.equals(oi.category, overlayPackage.overlayCategory)) { // When changing categories, it is ok just to update our internal state. mSettings.setCategory(overlayPackage.packageName, newUserId, overlayPackage.overlayCategory); } } try { updateState(overlayPackage.overlayTarget, overlayPackage.packageName, newUserId, 0); } catch (OverlayManagerSettings.BadKeyException e) { Slog.e(TAG, "failed to update settings", e); mSettings.remove(overlayPackage.packageName, newUserId); } packagesToUpdateAssets.add(overlayPackage.overlayTarget); storedOverlayInfos.remove(overlayPackage.packageName); } Loading @@ -148,6 +167,22 @@ final class OverlayManagerServiceImpl { packagesToUpdateAssets.add(oi.targetPackageName); } // make sure every overlay's state is up-to-date; this needs to happen // after old overlays have been removed, or we risk removing a // legitimate idmap file if a new overlay package has the same apk path // as the removed overlay package used to have for (int i = 0; i < overlayPackagesSize; i++) { final PackageInfo overlayPackage = overlayPackages.get(i); try { updateState(overlayPackage.overlayTarget, overlayPackage.packageName, newUserId, 0); } catch (OverlayManagerSettings.BadKeyException e) { Slog.e(TAG, "failed to update settings", e); mSettings.remove(overlayPackage.packageName, newUserId); } packagesToUpdateAssets.add(overlayPackage.overlayTarget); } // remove target packages that are not installed final Iterator<String> iter = packagesToUpdateAssets.iterator(); while (iter.hasNext()) { Loading Loading @@ -355,15 +390,13 @@ final class OverlayManagerServiceImpl { try { final OverlayInfo oldOi = mSettings.getOverlayInfo(packageName, userId); if (!oldOi.targetPackageName.equals(pkg.overlayTarget)) { if (mustReinitializeOverlay(pkg, oldOi)) { if (oldOi != null && !oldOi.targetPackageName.equals(pkg.overlayTarget)) { mListener.onOverlaysChanged(pkg.overlayTarget, userId); } mSettings.init(packageName, userId, pkg.overlayTarget, pkg.applicationInfo.getBaseCodePath(), pkg.isStaticOverlayPackage(), pkg.overlayPriority, pkg.overlayCategory); } else { if (!Objects.equals(oldOi.category, pkg.overlayCategory)) { // Update the category in-place. mSettings.setCategory(packageName, userId, pkg.overlayCategory); } } if (updateState(pkg.overlayTarget, packageName, userId, 0)) { Loading Loading @@ -608,6 +641,8 @@ final class OverlayManagerServiceImpl { if (overlayPackage != null) { modified |= mSettings.setBaseCodePath(overlayPackageName, userId, overlayPackage.applicationInfo.getBaseCodePath()); modified |= mSettings.setCategory(overlayPackageName, userId, overlayPackage.overlayCategory); } final @OverlayInfo.State int currentState = mSettings.getState(overlayPackageName, userId); Loading services/core/java/com/android/server/om/OverlayManagerSettings.java +1 −1 Original line number Diff line number Diff line Loading @@ -528,7 +528,7 @@ final class OverlayManagerSettings { private OverlayInfo getOverlayInfo() { if (mCache == null) { mCache = new OverlayInfo(mPackageName, mTargetPackageName, mCategory, mBaseCodePath, mState, mUserId); mState, mUserId, mPriority, mIsStatic); } return mCache; } Loading Loading
core/java/android/content/om/OverlayInfo.java +26 −3 Original line number Diff line number Diff line Loading @@ -18,7 +18,6 @@ package android.content.om; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.os.Parcel; import android.os.Parcelable; Loading Loading @@ -125,6 +124,23 @@ public final class OverlayInfo implements Parcelable { */ public final int userId; /** * Priority as read from the manifest. Used if isStatic is true. Not * intended to be exposed to 3rd party. * * @hide */ public final int priority; /** * isStatic as read from the manifest. If true, the overlay is * unconditionally loaded and cannot be unloaded. Not intended to be * exposed to 3rd party. * * @hide */ public final boolean isStatic; /** * Create a new OverlayInfo based on source with an updated state. * Loading @@ -133,17 +149,20 @@ public final class OverlayInfo implements Parcelable { */ public OverlayInfo(@NonNull OverlayInfo source, @State int state) { this(source.packageName, source.targetPackageName, source.category, source.baseCodePath, state, source.userId); state, source.userId, source.priority, source.isStatic); } public OverlayInfo(@NonNull String packageName, @NonNull String targetPackageName, @Nullable String category, @NonNull String baseCodePath, int state, int userId) { @NonNull String category, @NonNull String baseCodePath, int state, int userId, int priority, boolean isStatic) { this.packageName = packageName; this.targetPackageName = targetPackageName; this.category = category; this.baseCodePath = baseCodePath; this.state = state; this.userId = userId; this.priority = priority; this.isStatic = isStatic; ensureValidState(); } Loading @@ -154,6 +173,8 @@ public final class OverlayInfo implements Parcelable { baseCodePath = source.readString(); state = source.readInt(); userId = source.readInt(); priority = source.readInt(); isStatic = source.readBoolean(); ensureValidState(); } Loading Loading @@ -194,6 +215,8 @@ public final class OverlayInfo implements Parcelable { dest.writeString(baseCodePath); dest.writeInt(state); dest.writeInt(userId); dest.writeInt(priority); dest.writeBoolean(isStatic); } public static final Parcelable.Creator<OverlayInfo> CREATOR = Loading
services/core/java/com/android/server/om/OverlayManagerServiceImpl.java +64 −29 Original line number Diff line number Diff line Loading @@ -63,6 +63,38 @@ final class OverlayManagerServiceImpl { private final String[] mDefaultOverlays; private final OverlayChangeListener mListener; /** * Helper method to merge the overlay manager's (as read from overlays.xml) * and package manager's (as parsed from AndroidManifest.xml files) views * on overlays. * * Both managers are usually in agreement, but especially after an OTA things * may differ. The package manager is always providing the truth; the overlay * manager has to adapt. Depending on what has changed about an overlay, we * should either scrap the overlay manager's previous settings or merge the old * settings with the new. */ private static boolean mustReinitializeOverlay(@NonNull final PackageInfo theTruth, @Nullable final OverlayInfo oldSettings) { if (oldSettings == null) { return true; } if (!Objects.equals(theTruth.overlayTarget, oldSettings.targetPackageName)) { return true; } if (theTruth.isStaticOverlayPackage() != oldSettings.isStatic) { return true; } // a change in priority is only relevant for static RROs: specifically, // a regular RRO should not have its state reset only because a change // in priority if (theTruth.isStaticOverlayPackage() && theTruth.overlayPriority != oldSettings.priority) { return true; } return false; } OverlayManagerServiceImpl(@NonNull final PackageManagerHelper packageManager, @NonNull final IdmapManager idmapManager, @NonNull final OverlayManagerSettings settings, Loading Loading @@ -99,42 +131,29 @@ final class OverlayManagerServiceImpl { } } // Reset overlays if something critical like the target package name // has changed List<PackageInfo> overlayPackages = mPackageManager.getOverlayPackages(newUserId); final int overlayPackagesSize = overlayPackages.size(); for (int i = 0; i < overlayPackagesSize; i++) { final PackageInfo overlayPackage = overlayPackages.get(i); final OverlayInfo oi = storedOverlayInfos.get(overlayPackage.packageName); if (oi == null || !oi.targetPackageName.equals(overlayPackage.overlayTarget)) { // Reset the overlay if it didn't exist or had the wrong target package. if (mustReinitializeOverlay(overlayPackage, oi)) { // if targetPackageName has changed the package that *used* to // be the target must also update its assets if (oi != null) { packagesToUpdateAssets.add(oi.targetPackageName); } mSettings.init(overlayPackage.packageName, newUserId, overlayPackage.overlayTarget, overlayPackage.applicationInfo.getBaseCodePath(), overlayPackage.isStaticOverlayPackage(), overlayPackage.overlayPriority, overlayPackage.overlayCategory); if (oi != null) { // The targetPackageName we have stored doesn't match the overlay's target. // Queue the old target for an update as well. packagesToUpdateAssets.add(oi.targetPackageName); } } else { // Update all other components of an overlay that don't require a hard reset. if (!Objects.equals(oi.category, overlayPackage.overlayCategory)) { // When changing categories, it is ok just to update our internal state. mSettings.setCategory(overlayPackage.packageName, newUserId, overlayPackage.overlayCategory); } } try { updateState(overlayPackage.overlayTarget, overlayPackage.packageName, newUserId, 0); } catch (OverlayManagerSettings.BadKeyException e) { Slog.e(TAG, "failed to update settings", e); mSettings.remove(overlayPackage.packageName, newUserId); } packagesToUpdateAssets.add(overlayPackage.overlayTarget); storedOverlayInfos.remove(overlayPackage.packageName); } Loading @@ -148,6 +167,22 @@ final class OverlayManagerServiceImpl { packagesToUpdateAssets.add(oi.targetPackageName); } // make sure every overlay's state is up-to-date; this needs to happen // after old overlays have been removed, or we risk removing a // legitimate idmap file if a new overlay package has the same apk path // as the removed overlay package used to have for (int i = 0; i < overlayPackagesSize; i++) { final PackageInfo overlayPackage = overlayPackages.get(i); try { updateState(overlayPackage.overlayTarget, overlayPackage.packageName, newUserId, 0); } catch (OverlayManagerSettings.BadKeyException e) { Slog.e(TAG, "failed to update settings", e); mSettings.remove(overlayPackage.packageName, newUserId); } packagesToUpdateAssets.add(overlayPackage.overlayTarget); } // remove target packages that are not installed final Iterator<String> iter = packagesToUpdateAssets.iterator(); while (iter.hasNext()) { Loading Loading @@ -355,15 +390,13 @@ final class OverlayManagerServiceImpl { try { final OverlayInfo oldOi = mSettings.getOverlayInfo(packageName, userId); if (!oldOi.targetPackageName.equals(pkg.overlayTarget)) { if (mustReinitializeOverlay(pkg, oldOi)) { if (oldOi != null && !oldOi.targetPackageName.equals(pkg.overlayTarget)) { mListener.onOverlaysChanged(pkg.overlayTarget, userId); } mSettings.init(packageName, userId, pkg.overlayTarget, pkg.applicationInfo.getBaseCodePath(), pkg.isStaticOverlayPackage(), pkg.overlayPriority, pkg.overlayCategory); } else { if (!Objects.equals(oldOi.category, pkg.overlayCategory)) { // Update the category in-place. mSettings.setCategory(packageName, userId, pkg.overlayCategory); } } if (updateState(pkg.overlayTarget, packageName, userId, 0)) { Loading Loading @@ -608,6 +641,8 @@ final class OverlayManagerServiceImpl { if (overlayPackage != null) { modified |= mSettings.setBaseCodePath(overlayPackageName, userId, overlayPackage.applicationInfo.getBaseCodePath()); modified |= mSettings.setCategory(overlayPackageName, userId, overlayPackage.overlayCategory); } final @OverlayInfo.State int currentState = mSettings.getState(overlayPackageName, userId); Loading
services/core/java/com/android/server/om/OverlayManagerSettings.java +1 −1 Original line number Diff line number Diff line Loading @@ -528,7 +528,7 @@ final class OverlayManagerSettings { private OverlayInfo getOverlayInfo() { if (mCache == null) { mCache = new OverlayInfo(mPackageName, mTargetPackageName, mCategory, mBaseCodePath, mState, mUserId); mState, mUserId, mPriority, mIsStatic); } return mCache; } Loading