Loading services/core/java/android/content/pm/PackageManagerInternal.java +2 −14 Original line number Diff line number Diff line Loading @@ -901,32 +901,20 @@ public abstract class PackageManagerInternal implements PackageSettingsSnapshotP /** * Perform the given action for each package. * * @param locked whether to hold the packages lock. If the lock is not held, the objects will * be iterated using a temporary data structure. In the vast majority of cases, * the lock should not have to be held. This is exposed to mirror the * functionality of the other forEach methods, for eventual migration. * @param action action to be performed */ public abstract void forEachPackageState(boolean locked, Consumer<PackageStateInternal> action); public abstract void forEachPackageState(Consumer<PackageStateInternal> action); /** * {@link #forEachPackageState(boolean, Consumer)} but filtered to only states with packages * {@link #forEachPackageState(Consumer)} but filtered to only states with packages * on device where {@link PackageStateInternal#getPkg()} is not null. */ public abstract void forEachPackage(Consumer<AndroidPackage> action); /** * Perform the given action for each installed package for a user. * Note that packages lock will be held while performing the actions. */ public abstract void forEachInstalledPackage( @NonNull Consumer<AndroidPackage> actionLocked, @UserIdInt int userId); /** * Perform the given action for each installed package for a user. */ public abstract void forEachInstalledPackage(boolean locked, @NonNull Consumer<AndroidPackage> action, @UserIdInt int userId); /** Returns the list of enabled components */ Loading services/core/java/com/android/server/pm/AppDataHelper.java +4 −3 Original line number Diff line number Diff line Loading @@ -49,6 +49,7 @@ import com.android.server.pm.dex.ArtManagerService; import com.android.server.pm.parsing.pkg.AndroidPackage; import com.android.server.pm.parsing.pkg.AndroidPackageUtils; import com.android.server.pm.pkg.SELinuxUtil; import com.android.server.pm.pkg.PackageStateInternal; import dalvik.system.VMRuntime; Loading Loading @@ -277,8 +278,8 @@ final class AppDataHelper { }); } public void prepareAppDataContentsLIF(AndroidPackage pkg, @Nullable PackageSetting pkgSetting, int userId, int flags) { public void prepareAppDataContentsLIF(AndroidPackage pkg, @Nullable PackageStateInternal pkgSetting, int userId, int flags) { if (pkg == null) { Slog.wtf(TAG, "Package was null!", new Throwable()); return; Loading @@ -287,7 +288,7 @@ final class AppDataHelper { } private void prepareAppDataContentsLeafLIF(AndroidPackage pkg, @Nullable PackageSetting pkgSetting, int userId, int flags) { @Nullable PackageStateInternal pkgSetting, int userId, int flags) { final String volumeUuid = pkg.getVolumeUuid(); final String packageName = pkg.getPackageName(); Loading services/core/java/com/android/server/pm/AppsFilter.java +11 −7 Original line number Diff line number Diff line Loading @@ -1237,21 +1237,25 @@ public class AppsFilter implements Watchable, Snappable { // NOTE: this must come after all removals from data structures but before we update the // cache if (setting.getSharedUser() != null) { for (int i = setting.getSharedUser().packages.size() - 1; i >= 0; i--) { if (setting.getSharedUser().packages.valueAt(i) == setting) { final ArraySet<? extends PackageStateInternal> sharedUserPackages = setting.getSharedUser().getPackageStates(); for (int i = sharedUserPackages.size() - 1; i >= 0; i--) { if (sharedUserPackages.valueAt(i) == setting) { continue; } addPackageInternal( setting.getSharedUser().packages.valueAt(i), settings); sharedUserPackages.valueAt(i), settings); } } synchronized (mCacheLock) { removeAppIdFromVisibilityCache(setting.getAppId()); if (mShouldFilterCache != null && setting.getSharedUser() != null) { for (int i = setting.getSharedUser().packages.size() - 1; i >= 0; i--) { final ArraySet<? extends PackageStateInternal> sharedUserPackages = setting.getSharedUser().getPackageStates(); for (int i = sharedUserPackages.size() - 1; i >= 0; i--) { PackageStateInternal siblingSetting = setting.getSharedUser().packages.valueAt(i); sharedUserPackages.valueAt(i); if (siblingSetting == setting) { continue; } Loading Loading @@ -1368,8 +1372,8 @@ public class AppsFilter implements Watchable, Snappable { callingSharedPkgSettings = null; } else { callingPkgSetting = null; callingSharedPkgSettings = ((PackageStateInternal) callingSetting).getSharedUser().packages; callingSharedPkgSettings = ((PackageStateInternal) callingSetting) .getSharedUser().getPackageStates(); } } else { callingPkgSetting = null; Loading services/core/java/com/android/server/pm/ChangedPackagesTracker.java 0 → 100644 +114 −0 Original line number Diff line number Diff line /* * Copyright (C) 2021 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.server.pm; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.UserIdInt; import android.content.pm.ChangedPackages; import android.util.SparseArray; import com.android.internal.annotations.GuardedBy; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.function.BiConsumer; class ChangedPackagesTracker { @NonNull private final Object mLock = new Object(); @GuardedBy("mLock") @NonNull private int mChangedPackagesSequenceNumber; /** * List of changed [installed, removed or updated] packages. * mapping from user id -> sequence number -> package name */ @GuardedBy("mLock") @NonNull private final SparseArray<SparseArray<String>> mUserIdToSequenceToPackage = new SparseArray<>(); /** * The sequence number of the last change to a package. * mapping from user id -> package name -> sequence number */ @GuardedBy("mLock") @NonNull private final SparseArray<Map<String, Integer>> mChangedPackagesSequenceNumbers = new SparseArray<>(); @Nullable public ChangedPackages getChangedPackages(int sequenceNumber, @UserIdInt int userId) { synchronized (mLock) { if (sequenceNumber >= mChangedPackagesSequenceNumber) { return null; } final SparseArray<String> changedPackages = mUserIdToSequenceToPackage.get(userId); if (changedPackages == null) { return null; } final List<String> packageNames = new ArrayList<>(mChangedPackagesSequenceNumber - sequenceNumber); for (int i = sequenceNumber; i < mChangedPackagesSequenceNumber; i++) { final String packageName = changedPackages.get(i); if (packageName != null) { packageNames.add(packageName); } } return packageNames.isEmpty() ? null : new ChangedPackages(mChangedPackagesSequenceNumber, packageNames); } } int getSequenceNumber() { return mChangedPackagesSequenceNumber; } void iterateAll(@NonNull BiConsumer<Integer, SparseArray<SparseArray<String>>> sequenceNumberAndValues) { synchronized (mLock) { sequenceNumberAndValues.accept(mChangedPackagesSequenceNumber, mUserIdToSequenceToPackage); } } void updateSequenceNumber(@NonNull String packageName, int[] userList) { for (int i = userList.length - 1; i >= 0; --i) { final int userId = userList[i]; SparseArray<String> changedPackages = mUserIdToSequenceToPackage.get(userId); if (changedPackages == null) { changedPackages = new SparseArray<>(); mUserIdToSequenceToPackage.put(userId, changedPackages); } Map<String, Integer> sequenceNumbers = mChangedPackagesSequenceNumbers.get(userId); if (sequenceNumbers == null) { sequenceNumbers = new HashMap<>(); mChangedPackagesSequenceNumbers.put(userId, sequenceNumbers); } final Integer sequenceNumber = sequenceNumbers.get(packageName); if (sequenceNumber != null) { changedPackages.remove(sequenceNumber); } changedPackages.put(mChangedPackagesSequenceNumber, packageName); sequenceNumbers.put(packageName, mChangedPackagesSequenceNumber); } mChangedPackagesSequenceNumber++; } } services/core/java/com/android/server/pm/ComponentResolver.java +81 −66 Original line number Diff line number Diff line Loading @@ -616,38 +616,47 @@ public class ComponentResolver } void dumpActivityResolvers(PrintWriter pw, DumpState dumpState, String packageName) { synchronized (mLock) { if (mActivities.dump(pw, dumpState.getTitlePrinted() ? "\nActivity Resolver Table:" : "Activity Resolver Table:", " ", packageName, dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) { dumpState.setTitlePrinted(true); } } } void dumpProviderResolvers(PrintWriter pw, DumpState dumpState, String packageName) { synchronized (mLock) { if (mProviders.dump(pw, dumpState.getTitlePrinted() ? "\nProvider Resolver Table:" : "Provider Resolver Table:", " ", packageName, dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) { dumpState.setTitlePrinted(true); } } } void dumpReceiverResolvers(PrintWriter pw, DumpState dumpState, String packageName) { synchronized (mLock) { if (mReceivers.dump(pw, dumpState.getTitlePrinted() ? "\nReceiver Resolver Table:" : "Receiver Resolver Table:", " ", packageName, dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) { dumpState.setTitlePrinted(true); } } } void dumpServiceResolvers(PrintWriter pw, DumpState dumpState, String packageName) { synchronized (mLock) { if (mServices.dump(pw, dumpState.getTitlePrinted() ? "\nService Resolver Table:" : "Service Resolver Table:", " ", packageName, dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) { dumpState.setTitlePrinted(true); } } } void dumpContentProviders(PrintWriter pw, DumpState dumpState, String packageName) { synchronized (mLock) { boolean printedSomething = false; for (ParsedProvider p : mProviders.mProviders.values()) { if (packageName != null && !packageName.equals(p.getPackageName())) { Loading Loading @@ -680,8 +689,11 @@ public class ComponentResolver pw.println("ContentProvider Authorities:"); printedSomething = true; } pw.print(" ["); pw.print(entry.getKey()); pw.println("]:"); pw.print(" "); pw.println(p.toString()); pw.print(" ["); pw.print(entry.getKey()); pw.println("]:"); pw.print(" "); pw.println(p.toString()); AndroidPackage pkg = sPackageManagerInternal.getPackage(p.getPackageName()); Loading @@ -691,8 +703,10 @@ public class ComponentResolver } } } } void dumpServicePermissions(PrintWriter pw, DumpState dumpState) { synchronized (mLock) { if (dumpState.onTitlePrinted()) pw.println(); pw.println("Service permissions:"); Loading @@ -711,6 +725,7 @@ public class ComponentResolver } } } } @GuardedBy("mLock") private void addActivitiesLocked(AndroidPackage pkg, Loading Loading
services/core/java/android/content/pm/PackageManagerInternal.java +2 −14 Original line number Diff line number Diff line Loading @@ -901,32 +901,20 @@ public abstract class PackageManagerInternal implements PackageSettingsSnapshotP /** * Perform the given action for each package. * * @param locked whether to hold the packages lock. If the lock is not held, the objects will * be iterated using a temporary data structure. In the vast majority of cases, * the lock should not have to be held. This is exposed to mirror the * functionality of the other forEach methods, for eventual migration. * @param action action to be performed */ public abstract void forEachPackageState(boolean locked, Consumer<PackageStateInternal> action); public abstract void forEachPackageState(Consumer<PackageStateInternal> action); /** * {@link #forEachPackageState(boolean, Consumer)} but filtered to only states with packages * {@link #forEachPackageState(Consumer)} but filtered to only states with packages * on device where {@link PackageStateInternal#getPkg()} is not null. */ public abstract void forEachPackage(Consumer<AndroidPackage> action); /** * Perform the given action for each installed package for a user. * Note that packages lock will be held while performing the actions. */ public abstract void forEachInstalledPackage( @NonNull Consumer<AndroidPackage> actionLocked, @UserIdInt int userId); /** * Perform the given action for each installed package for a user. */ public abstract void forEachInstalledPackage(boolean locked, @NonNull Consumer<AndroidPackage> action, @UserIdInt int userId); /** Returns the list of enabled components */ Loading
services/core/java/com/android/server/pm/AppDataHelper.java +4 −3 Original line number Diff line number Diff line Loading @@ -49,6 +49,7 @@ import com.android.server.pm.dex.ArtManagerService; import com.android.server.pm.parsing.pkg.AndroidPackage; import com.android.server.pm.parsing.pkg.AndroidPackageUtils; import com.android.server.pm.pkg.SELinuxUtil; import com.android.server.pm.pkg.PackageStateInternal; import dalvik.system.VMRuntime; Loading Loading @@ -277,8 +278,8 @@ final class AppDataHelper { }); } public void prepareAppDataContentsLIF(AndroidPackage pkg, @Nullable PackageSetting pkgSetting, int userId, int flags) { public void prepareAppDataContentsLIF(AndroidPackage pkg, @Nullable PackageStateInternal pkgSetting, int userId, int flags) { if (pkg == null) { Slog.wtf(TAG, "Package was null!", new Throwable()); return; Loading @@ -287,7 +288,7 @@ final class AppDataHelper { } private void prepareAppDataContentsLeafLIF(AndroidPackage pkg, @Nullable PackageSetting pkgSetting, int userId, int flags) { @Nullable PackageStateInternal pkgSetting, int userId, int flags) { final String volumeUuid = pkg.getVolumeUuid(); final String packageName = pkg.getPackageName(); Loading
services/core/java/com/android/server/pm/AppsFilter.java +11 −7 Original line number Diff line number Diff line Loading @@ -1237,21 +1237,25 @@ public class AppsFilter implements Watchable, Snappable { // NOTE: this must come after all removals from data structures but before we update the // cache if (setting.getSharedUser() != null) { for (int i = setting.getSharedUser().packages.size() - 1; i >= 0; i--) { if (setting.getSharedUser().packages.valueAt(i) == setting) { final ArraySet<? extends PackageStateInternal> sharedUserPackages = setting.getSharedUser().getPackageStates(); for (int i = sharedUserPackages.size() - 1; i >= 0; i--) { if (sharedUserPackages.valueAt(i) == setting) { continue; } addPackageInternal( setting.getSharedUser().packages.valueAt(i), settings); sharedUserPackages.valueAt(i), settings); } } synchronized (mCacheLock) { removeAppIdFromVisibilityCache(setting.getAppId()); if (mShouldFilterCache != null && setting.getSharedUser() != null) { for (int i = setting.getSharedUser().packages.size() - 1; i >= 0; i--) { final ArraySet<? extends PackageStateInternal> sharedUserPackages = setting.getSharedUser().getPackageStates(); for (int i = sharedUserPackages.size() - 1; i >= 0; i--) { PackageStateInternal siblingSetting = setting.getSharedUser().packages.valueAt(i); sharedUserPackages.valueAt(i); if (siblingSetting == setting) { continue; } Loading Loading @@ -1368,8 +1372,8 @@ public class AppsFilter implements Watchable, Snappable { callingSharedPkgSettings = null; } else { callingPkgSetting = null; callingSharedPkgSettings = ((PackageStateInternal) callingSetting).getSharedUser().packages; callingSharedPkgSettings = ((PackageStateInternal) callingSetting) .getSharedUser().getPackageStates(); } } else { callingPkgSetting = null; Loading
services/core/java/com/android/server/pm/ChangedPackagesTracker.java 0 → 100644 +114 −0 Original line number Diff line number Diff line /* * Copyright (C) 2021 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.server.pm; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.UserIdInt; import android.content.pm.ChangedPackages; import android.util.SparseArray; import com.android.internal.annotations.GuardedBy; import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.function.BiConsumer; class ChangedPackagesTracker { @NonNull private final Object mLock = new Object(); @GuardedBy("mLock") @NonNull private int mChangedPackagesSequenceNumber; /** * List of changed [installed, removed or updated] packages. * mapping from user id -> sequence number -> package name */ @GuardedBy("mLock") @NonNull private final SparseArray<SparseArray<String>> mUserIdToSequenceToPackage = new SparseArray<>(); /** * The sequence number of the last change to a package. * mapping from user id -> package name -> sequence number */ @GuardedBy("mLock") @NonNull private final SparseArray<Map<String, Integer>> mChangedPackagesSequenceNumbers = new SparseArray<>(); @Nullable public ChangedPackages getChangedPackages(int sequenceNumber, @UserIdInt int userId) { synchronized (mLock) { if (sequenceNumber >= mChangedPackagesSequenceNumber) { return null; } final SparseArray<String> changedPackages = mUserIdToSequenceToPackage.get(userId); if (changedPackages == null) { return null; } final List<String> packageNames = new ArrayList<>(mChangedPackagesSequenceNumber - sequenceNumber); for (int i = sequenceNumber; i < mChangedPackagesSequenceNumber; i++) { final String packageName = changedPackages.get(i); if (packageName != null) { packageNames.add(packageName); } } return packageNames.isEmpty() ? null : new ChangedPackages(mChangedPackagesSequenceNumber, packageNames); } } int getSequenceNumber() { return mChangedPackagesSequenceNumber; } void iterateAll(@NonNull BiConsumer<Integer, SparseArray<SparseArray<String>>> sequenceNumberAndValues) { synchronized (mLock) { sequenceNumberAndValues.accept(mChangedPackagesSequenceNumber, mUserIdToSequenceToPackage); } } void updateSequenceNumber(@NonNull String packageName, int[] userList) { for (int i = userList.length - 1; i >= 0; --i) { final int userId = userList[i]; SparseArray<String> changedPackages = mUserIdToSequenceToPackage.get(userId); if (changedPackages == null) { changedPackages = new SparseArray<>(); mUserIdToSequenceToPackage.put(userId, changedPackages); } Map<String, Integer> sequenceNumbers = mChangedPackagesSequenceNumbers.get(userId); if (sequenceNumbers == null) { sequenceNumbers = new HashMap<>(); mChangedPackagesSequenceNumbers.put(userId, sequenceNumbers); } final Integer sequenceNumber = sequenceNumbers.get(packageName); if (sequenceNumber != null) { changedPackages.remove(sequenceNumber); } changedPackages.put(mChangedPackagesSequenceNumber, packageName); sequenceNumbers.put(packageName, mChangedPackagesSequenceNumber); } mChangedPackagesSequenceNumber++; } }
services/core/java/com/android/server/pm/ComponentResolver.java +81 −66 Original line number Diff line number Diff line Loading @@ -616,38 +616,47 @@ public class ComponentResolver } void dumpActivityResolvers(PrintWriter pw, DumpState dumpState, String packageName) { synchronized (mLock) { if (mActivities.dump(pw, dumpState.getTitlePrinted() ? "\nActivity Resolver Table:" : "Activity Resolver Table:", " ", packageName, dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) { dumpState.setTitlePrinted(true); } } } void dumpProviderResolvers(PrintWriter pw, DumpState dumpState, String packageName) { synchronized (mLock) { if (mProviders.dump(pw, dumpState.getTitlePrinted() ? "\nProvider Resolver Table:" : "Provider Resolver Table:", " ", packageName, dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) { dumpState.setTitlePrinted(true); } } } void dumpReceiverResolvers(PrintWriter pw, DumpState dumpState, String packageName) { synchronized (mLock) { if (mReceivers.dump(pw, dumpState.getTitlePrinted() ? "\nReceiver Resolver Table:" : "Receiver Resolver Table:", " ", packageName, dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) { dumpState.setTitlePrinted(true); } } } void dumpServiceResolvers(PrintWriter pw, DumpState dumpState, String packageName) { synchronized (mLock) { if (mServices.dump(pw, dumpState.getTitlePrinted() ? "\nService Resolver Table:" : "Service Resolver Table:", " ", packageName, dumpState.isOptionEnabled(DumpState.OPTION_SHOW_FILTERS), true)) { dumpState.setTitlePrinted(true); } } } void dumpContentProviders(PrintWriter pw, DumpState dumpState, String packageName) { synchronized (mLock) { boolean printedSomething = false; for (ParsedProvider p : mProviders.mProviders.values()) { if (packageName != null && !packageName.equals(p.getPackageName())) { Loading Loading @@ -680,8 +689,11 @@ public class ComponentResolver pw.println("ContentProvider Authorities:"); printedSomething = true; } pw.print(" ["); pw.print(entry.getKey()); pw.println("]:"); pw.print(" "); pw.println(p.toString()); pw.print(" ["); pw.print(entry.getKey()); pw.println("]:"); pw.print(" "); pw.println(p.toString()); AndroidPackage pkg = sPackageManagerInternal.getPackage(p.getPackageName()); Loading @@ -691,8 +703,10 @@ public class ComponentResolver } } } } void dumpServicePermissions(PrintWriter pw, DumpState dumpState) { synchronized (mLock) { if (dumpState.onTitlePrinted()) pw.println(); pw.println("Service permissions:"); Loading @@ -711,6 +725,7 @@ public class ComponentResolver } } } } @GuardedBy("mLock") private void addActivitiesLocked(AndroidPackage pkg, Loading