diff options
| author | 2018-05-11 17:44:53 +0000 | |
|---|---|---|
| committer | 2018-05-11 17:44:53 +0000 | |
| commit | 92b64bb1bbabcc2908fe510e71b4a60426ca3cb0 (patch) | |
| tree | 28889555714f248aed622010d4fba9a723841867 /services | |
| parent | 92a339736f5ef8cd86c6b022f1dcacc96d0b81c7 (diff) | |
| parent | a525e2239a95c79d62e27b18fc5e4f13789ab352 (diff) | |
Merge changes from topic "b_78809704" into pi-dev
* changes:
OMS: teach the OMS about static RROs
OMS: rebase settings when overlays update
Diffstat (limited to 'services')
3 files changed, 72 insertions, 30 deletions
diff --git a/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java b/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java index 36390823bd40..112059daf95e 100644 --- a/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java +++ b/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java @@ -18,6 +18,7 @@ package com.android.server.om; import static android.content.om.OverlayInfo.STATE_DISABLED; import static android.content.om.OverlayInfo.STATE_ENABLED; +import static android.content.om.OverlayInfo.STATE_ENABLED_STATIC; import static android.content.om.OverlayInfo.STATE_MISSING_TARGET; import static android.content.om.OverlayInfo.STATE_NO_IDMAP; import static android.content.om.OverlayInfo.STATE_OVERLAY_UPGRADING; @@ -63,6 +64,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, @@ -99,42 +132,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); } @@ -148,6 +168,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()) { @@ -355,15 +391,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)) { @@ -608,6 +642,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); @@ -650,6 +686,10 @@ final class OverlayManagerServiceImpl { return STATE_NO_IDMAP; } + if (overlayPackage.isStaticOverlayPackage()) { + return STATE_ENABLED_STATIC; + } + final boolean enabled = mSettings.getEnabled(overlayPackage.packageName, userId); return enabled ? STATE_ENABLED : STATE_DISABLED; } diff --git a/services/core/java/com/android/server/om/OverlayManagerSettings.java b/services/core/java/com/android/server/om/OverlayManagerSettings.java index e176351fcb76..36bf83dfe92c 100644 --- a/services/core/java/com/android/server/om/OverlayManagerSettings.java +++ b/services/core/java/com/android/server/om/OverlayManagerSettings.java @@ -309,6 +309,7 @@ final class OverlayManagerSettings { pw.print("mState.............: "); pw.println(OverlayInfo.stateToString(item.getState())); pw.print("mIsEnabled.........: "); pw.println(item.isEnabled()); pw.print("mIsStatic..........: "); pw.println(item.isStatic()); + pw.print("mPriority..........: "); pw.println(item.mPriority); pw.print("mCategory..........: "); pw.println(item.mCategory); pw.decreaseIndent(); @@ -528,7 +529,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; } diff --git a/services/core/java/com/android/server/om/OverlayManagerShellCommand.java b/services/core/java/com/android/server/om/OverlayManagerShellCommand.java index 54bb115c5405..d576d330c4a8 100644 --- a/services/core/java/com/android/server/om/OverlayManagerShellCommand.java +++ b/services/core/java/com/android/server/om/OverlayManagerShellCommand.java @@ -126,6 +126,7 @@ final class OverlayManagerShellCommand extends ShellCommand { final OverlayInfo oi = overlaysForTarget.get(i); String status; switch (oi.state) { + case OverlayInfo.STATE_ENABLED_STATIC: case OverlayInfo.STATE_ENABLED: status = "[x]"; break; |