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

Commit b049d95e authored by Winson's avatar Winson
Browse files

Migrate PackageSetting usages to PackageStateInternal

Moves to a read-only interface inside Computer and all of its
dependencies. This is the next step towards true data model
immutability and mutation time snapshots.

Bug: 202291449

Test: atest PackageManagerServiceUnitTests \
        PackageManagerSettingsTests \
        PackageUserStateTest \
        PackageParserTest \
        PackageManagerTest \
        ScanTests \
        PackageInfoUserFieldsTest \
        DexoptUtilsTest \
        PackageManagerComponentLabelIconOverrideTest

Change-Id: If5afb44e20b50a15b2b99057b0797c9b88e6e60b
parent 87b67784
Loading
Loading
Loading
Loading
+3 −1
Original line number Diff line number Diff line
@@ -51,6 +51,7 @@ import com.android.server.pm.PackageSetting;
import com.android.server.pm.parsing.pkg.AndroidPackage;
import com.android.server.pm.pkg.AndroidPackageApi;
import com.android.server.pm.pkg.PackageState;
import com.android.server.pm.pkg.PackageStateInternal;

import java.io.IOException;
import java.lang.annotation.Retention;
@@ -657,7 +658,8 @@ public abstract class PackageManagerInternal implements PackageSettingsSnapshotP
    @Nullable
    public abstract AndroidPackageApi getAndroidPackage(@NonNull String packageName);

    public abstract @Nullable PackageSetting getPackageSetting(@NonNull String packageName);
    @Nullable
    public abstract PackageStateInternal getPackageStateInternal(@NonNull String packageName);

    public abstract @Nullable PackageState getPackageState(@NonNull String packageName);

+9 −7
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ import android.annotation.NonNull;
import com.android.internal.util.FunctionalUtils;
import com.android.server.pm.PackageManagerService;
import com.android.server.pm.PackageSetting;
import com.android.server.pm.pkg.PackageStateInternal;

import java.util.function.Consumer;
import java.util.function.Function;
@@ -29,28 +30,28 @@ import java.util.function.Function;
public interface PackageSettingsSnapshotProvider {

    /**
     * Run a function block that requires access to {@link PackageSetting} data. This will
     * Run a function block that requires access to {@link PackageStateInternal} data. This will
     * ensure the {@link PackageManagerService} lock is taken before any caller's internal lock
     * to avoid deadlock. Note that this method may or may not lock. If a snapshot is available
     * and valid, it will iterate the snapshot set of data.
     */
    void withPackageSettingsSnapshot(
            @NonNull Consumer<Function<String, PackageSetting>> block);
            @NonNull Consumer<Function<String, PackageStateInternal>> block);

    /**
     * Variant which returns a value to the caller.
     * @see #withPackageSettingsSnapshot(Consumer)
     */
    <Output> Output withPackageSettingsSnapshotReturning(
            @NonNull FunctionalUtils.ThrowingFunction<Function<String, PackageSetting>, Output>
                    block);
            @NonNull FunctionalUtils.ThrowingFunction<Function<String, PackageStateInternal>,
                    Output> block);

    /**
     * Variant which throws.
     * @see #withPackageSettingsSnapshot(Consumer)
     */
    <ExceptionType extends Exception> void withPackageSettingsSnapshotThrowing(
            @NonNull FunctionalUtils.ThrowingCheckedConsumer<Function<String, PackageSetting>,
            @NonNull FunctionalUtils.ThrowingCheckedConsumer<Function<String, PackageStateInternal>,
                    ExceptionType> block) throws ExceptionType;

    /**
@@ -60,7 +61,8 @@ public interface PackageSettingsSnapshotProvider {
    <ExceptionOne extends Exception, ExceptionTwo extends Exception> void
            withPackageSettingsSnapshotThrowing2(
                    @NonNull FunctionalUtils.ThrowingChecked2Consumer<
                            Function<String, PackageSetting>, ExceptionOne, ExceptionTwo> block)
                            Function<String, PackageStateInternal>,
                            ExceptionOne, ExceptionTwo> block)
            throws ExceptionOne, ExceptionTwo;

    /**
@@ -70,6 +72,6 @@ public interface PackageSettingsSnapshotProvider {
    <Output, ExceptionType extends Exception> Output
            withPackageSettingsSnapshotReturningThrowing(
                    @NonNull FunctionalUtils.ThrowingCheckedFunction<
                            Function<String, PackageSetting>, Output, ExceptionType> block)
                            Function<String, PackageStateInternal>, Output, ExceptionType> block)
            throws ExceptionType;
}
+1 −1
Original line number Diff line number Diff line
@@ -3321,7 +3321,7 @@ public class AppOpsService extends IAppOpsService.Stub {

    private boolean isPackageExisted(String packageName) {
        return LocalServices.getService(PackageManagerInternal.class)
                .getPackageSetting(packageName) != null;
                .getPackageStateInternal(packageName) != null;
    }

    /**
+57 −50
Original line number Diff line number Diff line
@@ -61,6 +61,7 @@ import com.android.server.compat.CompatChange;
import com.android.server.om.OverlayReferenceMapper;
import com.android.server.pm.parsing.pkg.AndroidPackage;
import com.android.server.pm.parsing.pkg.AndroidPackageUtils;
import com.android.server.pm.pkg.PackageStateInternal;
import com.android.server.utils.Snappable;
import com.android.server.utils.SnapshotCache;
import com.android.server.utils.Snapshots;
@@ -166,7 +167,7 @@ public class AppsFilter implements Watchable, Snappable {
    /**
     * This structure maps uid -> uid and indicates whether access from the first should be
     * filtered to the second. It's essentially a cache of the
     * {@link #shouldFilterApplicationInternal(int, SettingBase, PackageSetting, int)} call.
     * {@link #shouldFilterApplicationInternal(int, Object, PackageStateInternal, int)} call.
     * NOTE: It can only be relied upon after the system is ready to avoid unnecessary update on
     * initial scam and is null until {@link #onSystemReady()} is called.
     */
@@ -311,7 +312,8 @@ public class AppsFilter implements Watchable, Snappable {
        void runWithState(CurrentStateCallback callback);

        interface CurrentStateCallback {
            void currentState(ArrayMap<String, PackageSetting> settings, UserInfo[] users);
            void currentState(ArrayMap<String, ? extends PackageStateInternal> settings,
                    UserInfo[] users);
        }
    }

@@ -343,7 +345,7 @@ public class AppsFilter implements Watchable, Snappable {
         *
         * @param removed true if adding, false if removing
         */
        void updatePackageState(PackageSetting setting, boolean removed);
        void updatePackageState(PackageStateInternal setting, boolean removed);
    }

    private static class FeatureConfigImpl implements FeatureConfig, CompatChange.ChangeListener {
@@ -467,7 +469,7 @@ public class AppsFilter implements Watchable, Snappable {
        }

        @Override
        public void updatePackageState(PackageSetting setting, boolean removed) {
        public void updatePackageState(PackageStateInternal setting, boolean removed) {
            final boolean enableLogging = setting.getPkg() != null &&
                    !removed && (setting.getPkg().isTestOnly() || setting.getPkg().isDebuggable());
            enableLogging(setting.getAppId(), enableLogging);
@@ -538,7 +540,7 @@ public class AppsFilter implements Watchable, Snappable {
                && querying.getQueriesPackages().contains(potentialTarget.getPackageName());
    }

    private static boolean canQueryAsInstaller(PackageSetting querying,
    private static boolean canQueryAsInstaller(PackageStateInternal querying,
            AndroidPackage potentialTarget) {
        final InstallSource installSource = querying.getInstallSource();
        if (potentialTarget.getPackageName().equals(installSource.installerPackageName)) {
@@ -689,7 +691,7 @@ public class AppsFilter implements Watchable, Snappable {
     * @param newPkgSetting the new setting being added
     * @param isReplace if the package is being replaced and may need extra cleanup.
     */
    public void addPackage(PackageSetting newPkgSetting, boolean isReplace) {
    public void addPackage(PackageStateInternal newPkgSetting, boolean isReplace) {
        if (DEBUG_TRACING) {
            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "filter.addPackage");
        }
@@ -708,7 +710,8 @@ public class AppsFilter implements Watchable, Snappable {
                        if (additionalChangedPackages != null) {
                            for (int index = 0; index < additionalChangedPackages.size(); index++) {
                                String changedPackage = additionalChangedPackages.valueAt(index);
                                PackageSetting changedPkgSetting = settings.get(changedPackage);
                                PackageStateInternal changedPkgSetting =
                                        settings.get(changedPackage);
                                if (changedPkgSetting == null) {
                                    // It's possible for the overlay mapper to know that an actor
                                    // package changed via an explicit reference, even if the actor
@@ -737,14 +740,14 @@ public class AppsFilter implements Watchable, Snappable {
     * to be updated in the cache. Returns null if there are no additional packages.
     */
    @Nullable
    private ArraySet<String> addPackageInternal(PackageSetting newPkgSetting,
            ArrayMap<String, PackageSetting> existingSettings) {
    private ArraySet<String> addPackageInternal(PackageStateInternal newPkgSetting,
            ArrayMap<String, ? extends PackageStateInternal> existingSettings) {
        if (Objects.equals("android", newPkgSetting.getPackageName())) {
            // let's set aside the framework signatures
            mSystemSigningDetails = newPkgSetting.getSigningDetails();
            // and since we add overlays before we add the framework, let's revisit already added
            // packages for signature matches
            for (PackageSetting setting : existingSettings.values()) {
            for (PackageStateInternal setting : existingSettings.values()) {
                if (isSystemSigned(mSystemSigningDetails, setting)) {
                    mForceQueryable.add(setting.getAppId());
                }
@@ -775,7 +778,7 @@ public class AppsFilter implements Watchable, Snappable {
        }

        for (int i = existingSettings.size() - 1; i >= 0; i--) {
            final PackageSetting existingSetting = existingSettings.valueAt(i);
            final PackageStateInternal existingSetting = existingSettings.valueAt(i);
            if (existingSetting.getAppId() == newPkgSetting.getAppId() || existingSetting.getPkg()
                    == null) {
                continue;
@@ -823,7 +826,7 @@ public class AppsFilter implements Watchable, Snappable {
        int existingSize = existingSettings.size();
        ArrayMap<String, AndroidPackage> existingPkgs = new ArrayMap<>(existingSize);
        for (int index = 0; index < existingSize; index++) {
            PackageSetting pkgSetting = existingSettings.valueAt(index);
            PackageStateInternal pkgSetting = existingSettings.valueAt(index);
            if (pkgSetting.getPkg() != null) {
                existingPkgs.put(pkgSetting.getPackageName(), pkgSetting.getPkg());
            }
@@ -881,7 +884,8 @@ public class AppsFilter implements Watchable, Snappable {
    }

    private WatchedSparseBooleanMatrix updateEntireShouldFilterCacheInner(
            ArrayMap<String, PackageSetting> settings, UserInfo[] users, int subjectUserId) {
            ArrayMap<String, ? extends PackageStateInternal> settings, UserInfo[] users,
            int subjectUserId) {
        final WatchedSparseBooleanMatrix cache;
        if (subjectUserId == USER_ALL) {
            cache = new WatchedSparseBooleanMatrix(users.length * settings.size());
@@ -900,7 +904,7 @@ public class AppsFilter implements Watchable, Snappable {

    private void updateEntireShouldFilterCacheAsync() {
        mBackgroundExecutor.execute(() -> {
            final ArrayMap<String, PackageSetting> settingsCopy = new ArrayMap<>();
            final ArrayMap<String, PackageStateInternal> settingsCopy = new ArrayMap<>();
            final ArrayMap<String, AndroidPackage> packagesCache = new ArrayMap<>();
            final UserInfo[][] usersRef = new UserInfo[1][];
            mStateProvider.runWithState((settings, users) -> {
@@ -977,10 +981,11 @@ public class AppsFilter implements Watchable, Snappable {
    }

    private void updateShouldFilterCacheForPackage(WatchedSparseBooleanMatrix cache,
            @Nullable String skipPackageName, PackageSetting subjectSetting, ArrayMap<String,
            PackageSetting> allSettings, UserInfo[] allUsers, int subjectUserId, int maxIndex) {
            @Nullable String skipPackageName, PackageStateInternal subjectSetting, ArrayMap<String,
            ? extends PackageStateInternal> allSettings, UserInfo[] allUsers, int subjectUserId,
            int maxIndex) {
        for (int i = Math.min(maxIndex, allSettings.size() - 1); i >= 0; i--) {
            PackageSetting otherSetting = allSettings.valueAt(i);
            PackageStateInternal otherSetting = allSettings.valueAt(i);
            if (subjectSetting.getAppId() == otherSetting.getAppId()) {
                continue;
            }
@@ -1002,8 +1007,8 @@ public class AppsFilter implements Watchable, Snappable {
    }

    private void updateShouldFilterCacheForUser(WatchedSparseBooleanMatrix cache,
            PackageSetting subjectSetting, UserInfo[] allUsers, PackageSetting otherSetting,
            int subjectUserId) {
            PackageStateInternal subjectSetting, UserInfo[] allUsers,
            PackageStateInternal otherSetting, int subjectUserId) {
        for (int ou = 0; ou < allUsers.length; ou++) {
            int otherUser = allUsers[ou].id;
            int subjectUid = UserHandle.getUid(subjectUserId, subjectSetting.getAppId());
@@ -1041,16 +1046,17 @@ public class AppsFilter implements Watchable, Snappable {
    }

    private static boolean isSystemSigned(@NonNull SigningDetails sysSigningDetails,
            PackageSetting pkgSetting) {
            PackageStateInternal pkgSetting) {
        return pkgSetting.isSystem()
                && pkgSetting.getSigningDetails().signaturesMatchExactly(sysSigningDetails);
    }

    private ArraySet<String> collectProtectedBroadcasts(
            ArrayMap<String, PackageSetting> existingSettings, @Nullable String excludePackage) {
            ArrayMap<String, ? extends PackageStateInternal> existingSettings,
            @Nullable String excludePackage) {
        ArraySet<String> ret = new ArraySet<>();
        for (int i = existingSettings.size() - 1; i >= 0; i--) {
            PackageSetting setting = existingSettings.valueAt(i);
            PackageStateInternal setting = existingSettings.valueAt(i);
            if (setting.getPkg() == null || setting.getPkg().getPackageName().equals(
                    excludePackage)) {
                continue;
@@ -1065,13 +1071,13 @@ public class AppsFilter implements Watchable, Snappable {

    /**
     * This method recomputes all component / intent-based visibility and is intended to match the
     * relevant logic of {@link #addPackageInternal(PackageSetting, ArrayMap)}
     * relevant logic of {@link #addPackageInternal(PackageStateInternal, ArrayMap)}
     */
    private void recomputeComponentVisibility(
            ArrayMap<String, PackageSetting> existingSettings) {
            ArrayMap<String, ? extends PackageStateInternal> existingSettings) {
        mQueriesViaComponent.clear();
        for (int i = existingSettings.size() - 1; i >= 0; i--) {
            PackageSetting setting = existingSettings.valueAt(i);
            PackageStateInternal setting = existingSettings.valueAt(i);
            if (setting.getPkg() == null || requestsQueryAllPackages(setting.getPkg())) {
                continue;
            }
@@ -1079,7 +1085,7 @@ public class AppsFilter implements Watchable, Snappable {
                if (i == j) {
                    continue;
                }
                final PackageSetting otherSetting = existingSettings.valueAt(j);
                final PackageStateInternal otherSetting = existingSettings.valueAt(j);
                if (otherSetting.getPkg() == null || mForceQueryable.contains(
                        otherSetting.getAppId())) {
                    continue;
@@ -1108,8 +1114,8 @@ public class AppsFilter implements Watchable, Snappable {
     * applied.
     */
    @Nullable
    public SparseArray<int[]> getVisibilityAllowList(PackageSetting setting, int[] users,
            ArrayMap<String, PackageSetting> existingSettings) {
    public SparseArray<int[]> getVisibilityAllowList(PackageStateInternal setting, int[] users,
            ArrayMap<String, ? extends PackageStateInternal> existingSettings) {
        if (mForceQueryable.contains(setting.getAppId())) {
            return null;
        }
@@ -1121,7 +1127,7 @@ public class AppsFilter implements Watchable, Snappable {
            int[] buffer = null;
            int allowListSize = 0;
            for (int i = existingSettings.size() - 1; i >= 0; i--) {
                final PackageSetting existingSetting = existingSettings.valueAt(i);
                final PackageStateInternal existingSetting = existingSettings.valueAt(i);
                final int existingAppId = existingSetting.getAppId();
                if (existingAppId < Process.FIRST_APPLICATION_UID) {
                    continue;
@@ -1152,17 +1158,17 @@ public class AppsFilter implements Watchable, Snappable {
     */
    @VisibleForTesting(visibility = PRIVATE)
    @Nullable
    SparseArray<int[]> getVisibilityAllowList(PackageSetting setting, int[] users,
            WatchedArrayMap<String, PackageSetting> existingSettings) {
    SparseArray<int[]> getVisibilityAllowList(PackageStateInternal setting, int[] users,
            WatchedArrayMap<String, ? extends PackageStateInternal> existingSettings) {
        return getVisibilityAllowList(setting, users, existingSettings.untrackedStorage());
    }

    /**
     * Equivalent to calling {@link #addPackage(PackageSetting, boolean)} with {@code isReplace}
     * equal to {@code false}.
     * @see AppsFilter#addPackage(PackageSetting, boolean)
     * Equivalent to calling {@link #addPackage(PackageStateInternal, boolean)} with
     * {@code isReplace} equal to {@code false}.
     * @see AppsFilter#addPackage(PackageStateInternal, boolean)
     */
    public void addPackage(PackageSetting newPkgSetting) {
    public void addPackage(PackageStateInternal newPkgSetting) {
        addPackage(newPkgSetting, false /* isReplace */);
    }

@@ -1172,7 +1178,7 @@ public class AppsFilter implements Watchable, Snappable {
     * @param setting the setting of the package being removed.
     * @param isReplace if the package is being replaced.
     */
    public void removePackage(PackageSetting setting, boolean isReplace) {
    public void removePackage(PackageStateInternal setting, boolean isReplace) {
        mStateProvider.runWithState((settings, users) -> {
            final int userCount = users.length;
            for (int u = 0; u < userCount; u++) {
@@ -1244,7 +1250,8 @@ public class AppsFilter implements Watchable, Snappable {
                removeAppIdFromVisibilityCache(setting.getAppId());
                if (mShouldFilterCache != null && setting.getSharedUser() != null) {
                    for (int i = setting.getSharedUser().packages.size() - 1; i >= 0; i--) {
                        PackageSetting siblingSetting = setting.getSharedUser().packages.valueAt(i);
                        PackageStateInternal siblingSetting =
                                setting.getSharedUser().packages.valueAt(i);
                        if (siblingSetting == setting) {
                            continue;
                        }
@@ -1258,7 +1265,7 @@ public class AppsFilter implements Watchable, Snappable {
                    if (additionalChangedPackages != null) {
                        for (int index = 0; index < additionalChangedPackages.size(); index++) {
                            String changedPackage = additionalChangedPackages.valueAt(index);
                            PackageSetting changedPkgSetting = settings.get(changedPackage);
                            PackageStateInternal changedPkgSetting = settings.get(changedPackage);
                            if (changedPkgSetting == null) {
                                // It's possible for the overlay mapper to know that an actor
                                // package changed via an explicit reference, even if the actor
@@ -1287,8 +1294,8 @@ public class AppsFilter implements Watchable, Snappable {
     * @param targetPkgSetting the package being accessed
     * @param userId           the user in which this access is being attempted
     */
    public boolean shouldFilterApplication(int callingUid, @Nullable SettingBase callingSetting,
            PackageSetting targetPkgSetting, int userId) {
    public boolean shouldFilterApplication(int callingUid, @Nullable Object callingSetting,
            PackageStateInternal targetPkgSetting, int userId) {
        if (DEBUG_TRACING) {
            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "shouldFilterApplication");
        }
@@ -1333,8 +1340,8 @@ public class AppsFilter implements Watchable, Snappable {
        }
    }

    private boolean shouldFilterApplicationInternal(int callingUid, SettingBase callingSetting,
            PackageSetting targetPkgSetting, int targetUserId) {
    private boolean shouldFilterApplicationInternal(int callingUid, Object callingSetting,
            PackageStateInternal targetPkgSetting, int targetUserId) {
        if (DEBUG_TRACING) {
            Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "shouldFilterApplicationInternal");
        }
@@ -1350,19 +1357,19 @@ public class AppsFilter implements Watchable, Snappable {
                Slog.wtf(TAG, "No setting found for non system uid " + callingUid);
                return true;
            }
            final PackageSetting callingPkgSetting;
            final ArraySet<PackageSetting> callingSharedPkgSettings;
            final PackageStateInternal callingPkgSetting;
            final ArraySet<? extends PackageStateInternal> callingSharedPkgSettings;
            if (DEBUG_TRACING) {
                Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "callingSetting instanceof");
            }
            if (callingSetting instanceof PackageSetting) {
                if (((PackageSetting) callingSetting).getSharedUser() == null) {
                    callingPkgSetting = (PackageSetting) callingSetting;
            if (callingSetting instanceof PackageStateInternal) {
                if (((PackageStateInternal) callingSetting).getSharedUser() == null) {
                    callingPkgSetting = (PackageStateInternal) callingSetting;
                    callingSharedPkgSettings = null;
                } else {
                    callingPkgSetting = null;
                    callingSharedPkgSettings =
                            ((PackageSetting) callingSetting).getSharedUser().packages;
                            ((PackageStateInternal) callingSetting).getSharedUser().packages;
                }
            } else {
                callingPkgSetting = null;
@@ -1544,7 +1551,7 @@ public class AppsFilter implements Watchable, Snappable {
                if (callingSharedPkgSettings != null) {
                    int size = callingSharedPkgSettings.size();
                    for (int index = 0; index < size; index++) {
                        PackageSetting pkgSetting = callingSharedPkgSettings.valueAt(index);
                        PackageStateInternal pkgSetting = callingSharedPkgSettings.valueAt(index);
                        if (mOverlayReferenceMapper.isValidActor(targetName,
                                pkgSetting.getPackageName())) {
                            if (DEBUG_LOGGING) {
@@ -1642,7 +1649,7 @@ public class AppsFilter implements Watchable, Snappable {
        }
    }

    private static void log(SettingBase callingSetting, PackageSetting targetPkgSetting,
    private static void log(Object callingSetting, PackageStateInternal targetPkgSetting,
            String description) {
        Slog.i(TAG,
                "interaction: " + (callingSetting == null ? "system" : callingSetting) + " -> "
+22 −23

File changed.

Preview size limit exceeded, changes collapsed.

Loading