diff options
5 files changed, 99 insertions, 57 deletions
diff --git a/core/java/android/content/pm/overlay/OverlayPaths.java b/core/java/android/content/pm/overlay/OverlayPaths.java index a4db733af013..bd74b0b9293c 100644 --- a/core/java/android/content/pm/overlay/OverlayPaths.java +++ b/core/java/android/content/pm/overlay/OverlayPaths.java @@ -49,6 +49,13 @@ public class OverlayPaths { public static class Builder { final OverlayPaths mPaths = new OverlayPaths(); + public Builder() {} + + public Builder(@NonNull OverlayPaths base) { + mPaths.mResourceDirs.addAll(base.getResourceDirs()); + mPaths.mOverlayPaths.addAll(base.getOverlayPaths()); + } + /** * Adds a non-APK path to the contents of {@link OverlayPaths#getOverlayPaths()}. */ diff --git a/services/core/java/com/android/server/om/IdmapManager.java b/services/core/java/com/android/server/om/IdmapManager.java index 25a39cc8456f..86d05d92c95b 100644 --- a/services/core/java/com/android/server/om/IdmapManager.java +++ b/services/core/java/com/android/server/om/IdmapManager.java @@ -257,7 +257,7 @@ final class IdmapManager { private boolean matchesActorSignature(@NonNull AndroidPackage targetPackage, @NonNull AndroidPackage overlayPackage, int userId) { String targetOverlayableName = overlayPackage.getOverlayTargetOverlayableName(); - if (targetOverlayableName != null) { + if (targetOverlayableName != null && !mPackageManager.getNamedActors().isEmpty()) { try { OverlayableInfo overlayableInfo = mPackageManager.getOverlayableForTarget( targetPackage.getPackageName(), targetOverlayableName, userId); diff --git a/services/core/java/com/android/server/om/OverlayManagerService.java b/services/core/java/com/android/server/om/OverlayManagerService.java index b9464d96a019..a61b03fdbb39 100644 --- a/services/core/java/com/android/server/om/OverlayManagerService.java +++ b/services/core/java/com/android/server/om/OverlayManagerService.java @@ -32,6 +32,7 @@ import static android.os.Process.INVALID_UID; import static android.os.Trace.TRACE_TAG_RRO; import static android.os.Trace.traceBegin; import static android.os.Trace.traceEnd; + import static com.android.server.om.OverlayManagerServiceImpl.OperationFailedException; import android.annotation.NonNull; @@ -362,7 +363,7 @@ public final class OverlayManagerService extends SystemService { defaultPackages.add(packageName); } } - return defaultPackages.toArray(new String[defaultPackages.size()]); + return defaultPackages.toArray(new String[0]); } private final class OverlayManagerPackageMonitor extends PackageMonitor { @@ -1143,9 +1144,10 @@ public final class OverlayManagerService extends SystemService { }; private static final class PackageManagerHelperImpl implements PackageManagerHelper { - private static class PackageStateUsers { + private static final class PackageStateUsers { private PackageState mPackageState; - private final Set<Integer> mInstalledUsers = new ArraySet<>(); + private Boolean mDefinesOverlayable = null; + private final ArraySet<Integer> mInstalledUsers = new ArraySet<>(); private PackageStateUsers(@NonNull PackageState packageState) { this.mPackageState = packageState; } @@ -1160,7 +1162,7 @@ public final class OverlayManagerService extends SystemService { // state may lead to contradictions within OMS. Better then to lag // behind until all pending intents have been processed. private final ArrayMap<String, PackageStateUsers> mCache = new ArrayMap<>(); - private final Set<Integer> mInitializedUsers = new ArraySet<>(); + private final ArraySet<Integer> mInitializedUsers = new ArraySet<>(); PackageManagerHelperImpl(Context context) { mContext = context; @@ -1176,8 +1178,7 @@ public final class OverlayManagerService extends SystemService { */ @NonNull public ArrayMap<String, PackageState> initializeForUser(final int userId) { - if (!mInitializedUsers.contains(userId)) { - mInitializedUsers.add(userId); + if (mInitializedUsers.add(userId)) { mPackageManagerInternal.forEachPackageState((packageState -> { if (packageState.getPkg() != null && packageState.getUserStateOrDefault(userId).isInstalled()) { @@ -1196,13 +1197,11 @@ public final class OverlayManagerService extends SystemService { return userPackages; } - @Override - @Nullable - public PackageState getPackageStateForUser(@NonNull final String packageName, + private PackageStateUsers getRawPackageStateForUser(@NonNull final String packageName, final int userId) { final PackageStateUsers pkg = mCache.get(packageName); if (pkg != null && pkg.mInstalledUsers.contains(userId)) { - return pkg.mPackageState; + return pkg; } try { if (!mPackageManager.isPackageAvailable(packageName, userId)) { @@ -1216,8 +1215,14 @@ public final class OverlayManagerService extends SystemService { return addPackageUser(packageName, userId); } - @NonNull - private PackageState addPackageUser(@NonNull final String packageName, + @Override + public PackageState getPackageStateForUser(@NonNull final String packageName, + final int userId) { + final PackageStateUsers pkg = getRawPackageStateForUser(packageName, userId); + return pkg != null ? pkg.mPackageState : null; + } + + private PackageStateUsers addPackageUser(@NonNull final String packageName, final int user) { final PackageState pkg = mPackageManagerInternal.getPackageStateInternal(packageName); if (pkg == null) { @@ -1229,20 +1234,20 @@ public final class OverlayManagerService extends SystemService { } @NonNull - private PackageState addPackageUser(@NonNull final PackageState pkg, + private PackageStateUsers addPackageUser(@NonNull final PackageState pkg, final int user) { PackageStateUsers pkgUsers = mCache.get(pkg.getPackageName()); if (pkgUsers == null) { pkgUsers = new PackageStateUsers(pkg); mCache.put(pkg.getPackageName(), pkgUsers); - } else { + } else if (pkgUsers.mPackageState != pkg) { pkgUsers.mPackageState = pkg; + pkgUsers.mDefinesOverlayable = null; } pkgUsers.mInstalledUsers.add(user); - return pkgUsers.mPackageState; + return pkgUsers; } - @NonNull private void removePackageUser(@NonNull final String packageName, final int user) { final PackageStateUsers pkgUsers = mCache.get(packageName); @@ -1260,15 +1265,15 @@ public final class OverlayManagerService extends SystemService { } } - @Nullable public PackageState onPackageAdded(@NonNull final String packageName, final int userId) { - return addPackageUser(packageName, userId); + final var pu = addPackageUser(packageName, userId); + return pu != null ? pu.mPackageState : null; } - @Nullable public PackageState onPackageUpdated(@NonNull final String packageName, final int userId) { - return addPackageUser(packageName, userId); + final var pu = addPackageUser(packageName, userId); + return pu != null ? pu.mPackageState : null; } public void onPackageRemoved(@NonNull final String packageName, final int userId) { @@ -1308,22 +1313,30 @@ public final class OverlayManagerService extends SystemService { return (pkgs.length == 0) ? null : pkgs[0]; } - @Nullable @Override public OverlayableInfo getOverlayableForTarget(@NonNull String packageName, @NonNull String targetOverlayableName, int userId) throws IOException { - var packageState = getPackageStateForUser(packageName, userId); - var pkg = packageState == null ? null : packageState.getAndroidPackage(); + final var psu = getRawPackageStateForUser(packageName, userId); + final var pkg = (psu == null || psu.mPackageState == null) + ? null : psu.mPackageState.getAndroidPackage(); if (pkg == null) { throw new IOException("Unable to get target package"); } + if (Boolean.FALSE.equals(psu.mDefinesOverlayable)) { + return null; + } + ApkAssets apkAssets = null; try { apkAssets = ApkAssets.loadFromPath(pkg.getSplits().get(0).getPath(), ApkAssets.PROPERTY_ONLY_OVERLAYABLES); - return apkAssets.getOverlayableInfo(targetOverlayableName); + if (psu.mDefinesOverlayable == null) { + psu.mDefinesOverlayable = apkAssets.definesOverlayable(); + } + return Boolean.FALSE.equals(psu.mDefinesOverlayable) + ? null : apkAssets.getOverlayableInfo(targetOverlayableName); } finally { if (apkAssets != null) { try { @@ -1337,24 +1350,29 @@ public final class OverlayManagerService extends SystemService { @Override public boolean doesTargetDefineOverlayable(String targetPackageName, int userId) throws IOException { - var packageState = getPackageStateForUser(targetPackageName, userId); - var pkg = packageState == null ? null : packageState.getAndroidPackage(); + final var psu = getRawPackageStateForUser(targetPackageName, userId); + var pkg = (psu == null || psu.mPackageState == null) + ? null : psu.mPackageState.getAndroidPackage(); if (pkg == null) { throw new IOException("Unable to get target package"); } - ApkAssets apkAssets = null; - try { - apkAssets = ApkAssets.loadFromPath(pkg.getSplits().get(0).getPath()); - return apkAssets.definesOverlayable(); - } finally { - if (apkAssets != null) { - try { - apkAssets.close(); - } catch (Throwable ignored) { + if (psu.mDefinesOverlayable == null) { + ApkAssets apkAssets = null; + try { + apkAssets = ApkAssets.loadFromPath(pkg.getSplits().get(0).getPath(), + ApkAssets.PROPERTY_ONLY_OVERLAYABLES); + psu.mDefinesOverlayable = apkAssets.definesOverlayable(); + } finally { + if (apkAssets != null) { + try { + apkAssets.close(); + } catch (Throwable ignored) { + } } } } + return psu.mDefinesOverlayable; } @Override @@ -1545,8 +1563,7 @@ public final class OverlayManagerService extends SystemService { final OverlayPaths frameworkOverlays = mImpl.getEnabledOverlayPaths("android", userId, false); for (final String targetPackageName : targetPackageNames) { - final OverlayPaths.Builder list = new OverlayPaths.Builder(); - list.addAll(frameworkOverlays); + final var list = new OverlayPaths.Builder(frameworkOverlays); if (!"android".equals(targetPackageName)) { list.addAll(mImpl.getEnabledOverlayPaths(targetPackageName, userId, true)); } @@ -1558,17 +1575,21 @@ public final class OverlayManagerService extends SystemService { final HashSet<String> invalidPackages = new HashSet<>(); pm.setEnabledOverlayPackages(userId, pendingChanges, updatedPackages, invalidPackages); - for (final String targetPackageName : targetPackageNames) { - if (DEBUG) { - Slog.d(TAG, "-> Updating overlay: target=" + targetPackageName + " overlays=[" - + pendingChanges.get(targetPackageName) - + "] userId=" + userId); - } + if (DEBUG || !invalidPackages.isEmpty()) { + for (final String targetPackageName : targetPackageNames) { + if (DEBUG) { + Slog.d(TAG, + "-> Updating overlay: target=" + targetPackageName + " overlays=[" + + pendingChanges.get(targetPackageName) + + "] userId=" + userId); + } - if (invalidPackages.contains(targetPackageName)) { - Slog.e(TAG, TextUtils.formatSimple( - "Failed to change enabled overlays for %s user %d", targetPackageName, - userId)); + if (invalidPackages.contains(targetPackageName)) { + Slog.e(TAG, TextUtils.formatSimple( + "Failed to change enabled overlays for %s user %d", + targetPackageName, + userId)); + } } } return new ArrayList<>(updatedPackages); diff --git a/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java b/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java index 972c78db9460..c1b6ccc7e25c 100644 --- a/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java +++ b/services/core/java/com/android/server/om/OverlayManagerServiceImpl.java @@ -772,24 +772,20 @@ final class OverlayManagerServiceImpl { OverlayPaths getEnabledOverlayPaths(@NonNull final String targetPackageName, final int userId, boolean includeImmutableOverlays) { - final List<OverlayInfo> overlays = mSettings.getOverlaysForTarget(targetPackageName, - userId); - final OverlayPaths.Builder paths = new OverlayPaths.Builder(); - final int n = overlays.size(); - for (int i = 0; i < n; i++) { - final OverlayInfo oi = overlays.get(i); + final var paths = new OverlayPaths.Builder(); + mSettings.forEachMatching(userId, null, targetPackageName, oi -> { if (!oi.isEnabled()) { - continue; + return; } if (!includeImmutableOverlays && !oi.isMutable) { - continue; + return; } if (oi.isFabricated()) { paths.addNonApkPath(oi.baseCodePath); } else { paths.addApkPath(oi.baseCodePath); } - } + }); return paths.build(); } diff --git a/services/core/java/com/android/server/om/OverlayManagerSettings.java b/services/core/java/com/android/server/om/OverlayManagerSettings.java index eae614ac9e77..b8b49f3eed2f 100644 --- a/services/core/java/com/android/server/om/OverlayManagerSettings.java +++ b/services/core/java/com/android/server/om/OverlayManagerSettings.java @@ -47,6 +47,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Objects; import java.util.Set; +import java.util.function.Consumer; import java.util.function.Predicate; import java.util.stream.Stream; @@ -182,6 +183,23 @@ final class OverlayManagerSettings { return CollectionUtils.map(items, SettingsItem::getOverlayInfo); } + void forEachMatching(int userId, String overlayName, String targetPackageName, + @NonNull Consumer<OverlayInfo> consumer) { + for (int i = 0, n = mItems.size(); i < n; i++) { + final SettingsItem item = mItems.get(i); + if (item.getUserId() != userId) { + continue; + } + if (overlayName != null && !item.mOverlay.getPackageName().equals(overlayName)) { + continue; + } + if (targetPackageName != null && !item.mTargetPackageName.equals(targetPackageName)) { + continue; + } + consumer.accept(item.getOverlayInfo()); + } + } + ArrayMap<String, List<OverlayInfo>> getOverlaysForUser(final int userId) { final List<SettingsItem> items = selectWhereUser(userId); |