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

Commit d4c21606 authored by Winson Chiu's avatar Winson Chiu Committed by Winson
Browse files

Remove AndroidPackage#is_ partition APIs

These are moved to PackageState so that they can be queried in a
single location regardless of whether the physical APKs are
available on device (getAndroidPackage would be null in that case).

This also means any existing framework callers have to be migrated
to PackageState, but that ended up being fairly simple for all
methods except isSystem, which has a lot of usages.

That will be addressed in a follow-up.

This CL does not move the physical data storage of these booleans
to PackageState, but that should be done in the future, so that
the underlying fields can be removed fro, PackageImpl.

That will likely have to be done with a full install refactor, as
there's no PackageSetting available at some points where the flags
are queried, and so no holder for the fields without some messy
temporary objects.

This also removes the SettingsFlag set(Private)Flags mask
restrictor, since that legacy subset flag behavior isn't worth
keeping.

API-Coverage-Bug: 262593427

Test: atest AndroidPackageTest
Test: atest OverlayActorEnforcerTests
Test: atest SELinuxMMACTest

Change-Id: I2a915e55f609992729e082815d78fd2d73cb79fd
parent 392a8cb4
Loading
Loading
Loading
Loading
+10 −8
Original line number Diff line number Diff line
@@ -161,6 +161,7 @@ import com.android.server.pm.PackageList;
import com.android.server.pm.UserManagerInternal;
import com.android.server.pm.permission.PermissionManagerServiceInternal;
import com.android.server.pm.pkg.AndroidPackage;
import com.android.server.pm.pkg.PackageState;
import com.android.server.pm.pkg.component.ParsedAttribution;
import com.android.server.policy.AppOpsPolicy;

@@ -3590,11 +3591,11 @@ public class AppOpsService extends IAppOpsService.Stub implements PersistenceSch
     *
     * @return The restriction matching the package
     */
    private RestrictionBypass getBypassforPackage(@NonNull AndroidPackage pkg) {
        return new RestrictionBypass(pkg.getUid() == Process.SYSTEM_UID, pkg.isPrivileged(),
                mContext.checkPermission(android.Manifest.permission
                        .EXEMPT_FROM_AUDIO_RECORD_RESTRICTIONS, -1, pkg.getUid())
                == PackageManager.PERMISSION_GRANTED);
    private RestrictionBypass getBypassforPackage(@NonNull PackageState packageState) {
        return new RestrictionBypass(packageState.getAppId() == Process.SYSTEM_UID,
                packageState.isPrivileged(), mContext.checkPermission(
                android.Manifest.permission.EXEMPT_FROM_AUDIO_RECORD_RESTRICTIONS, -1,
                packageState.getAppId()) == PackageManager.PERMISSION_GRANTED);
    }

    /**
@@ -3690,11 +3691,12 @@ public class AppOpsService extends IAppOpsService.Stub implements PersistenceSch
        final long ident = Binder.clearCallingIdentity();
        try {
            PackageManagerInternal pmInt = LocalServices.getService(PackageManagerInternal.class);
            AndroidPackage pkg = pmInt.getPackage(packageName);
            var pkgState = pmInt.getPackageStateInternal(packageName);
            var pkg = pkgState == null ? null : pkgState.getAndroidPackage();
            if (pkg != null) {
                isAttributionTagValid = isAttributionInPackage(pkg, attributionTag);
                pkgUid = UserHandle.getUid(userId, UserHandle.getAppId(pkg.getUid()));
                bypass = getBypassforPackage(pkg);
                pkgUid = UserHandle.getUid(userId, pkgState.getAppId());
                bypass = getBypassforPackage(pkgState);
            }
            if (!isAttributionTagValid) {
                AndroidPackage proxyPkg = proxyPackageName != null
+19 −14
Original line number Diff line number Diff line
@@ -21,6 +21,7 @@ import static com.android.server.om.OverlayManagerService.TAG;

import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.UserIdInt;
import android.content.om.OverlayInfo;
import android.content.om.OverlayableInfo;
import android.os.Build.VERSION_CODES;
@@ -32,6 +33,7 @@ import android.text.TextUtils;
import android.util.Slog;

import com.android.server.pm.pkg.AndroidPackage;
import com.android.server.pm.pkg.PackageState;

import java.io.IOException;
import java.lang.annotation.Retention;
@@ -99,16 +101,17 @@ final class IdmapManager {
     * </ul>.
     */
    @IdmapStatus int createIdmap(@NonNull final AndroidPackage targetPackage,
            @NonNull final AndroidPackage overlayPackage, String overlayBasePath,
            String overlayName, int userId) {
            @NonNull PackageState overlayPackageState, @NonNull final AndroidPackage overlayPackage,
            String overlayBasePath, String overlayName, @UserIdInt int userId) {
        if (DEBUG) {
            Slog.d(TAG, "create idmap for " + targetPackage.getPackageName() + " and "
                    + overlayPackage.getPackageName());
        }
        final String targetPath = targetPackage.getBaseApkPath();
        final String targetPath = targetPackage.getSplits().get(0).getPath();
        try {
            int policies = calculateFulfilledPolicies(targetPackage, overlayPackage, userId);
            boolean enforce = enforceOverlayable(overlayPackage);
            int policies = calculateFulfilledPolicies(targetPackage, overlayPackageState,
                    overlayPackage, userId);
            boolean enforce = enforceOverlayable(overlayPackageState, overlayPackage);
            if (mIdmapDaemon.verifyIdmap(targetPath, overlayBasePath, overlayName, policies,
                    enforce, userId)) {
                return IDMAP_IS_VERIFIED;
@@ -174,13 +177,14 @@ final class IdmapManager {
     * Checks if overlayable and policies should be enforced on the specified overlay for backwards
     * compatibility with pre-Q overlays.
     */
    private boolean enforceOverlayable(@NonNull final AndroidPackage overlayPackage) {
    private boolean enforceOverlayable(@NonNull PackageState overlayPackageState,
            @NonNull final AndroidPackage overlayPackage) {
        if (overlayPackage.getTargetSdkVersion() >= VERSION_CODES.Q) {
            // Always enforce policies for overlays targeting Q+.
            return true;
        }

        if (overlayPackage.isVendor()) {
        if (overlayPackageState.isVendor()) {
            // If the overlay is on a pre-Q vendor partition, do not enforce overlayable
            // restrictions on this overlay because the pre-Q platform has no understanding of
            // overlayable.
@@ -189,14 +193,15 @@ final class IdmapManager {

        // Do not enforce overlayable restrictions on pre-Q overlays that are signed with the
        // platform signature or that are preinstalled.
        return !(overlayPackage.isSystem() || overlayPackage.isSignedWithPlatformKey());
        return !(overlayPackageState.isSystem() || overlayPackage.isSignedWithPlatformKey());
    }

    /**
     * Retrieves a bitmask for idmap2 that represents the policies the overlay fulfills.
     */
    private int calculateFulfilledPolicies(@NonNull final AndroidPackage targetPackage,
            @NonNull final AndroidPackage overlayPackage, int userId)  {
            @NonNull PackageState overlayPackageState, @NonNull final AndroidPackage overlayPackage,
            @UserIdInt int userId)  {
        int fulfilledPolicies = OverlayablePolicy.PUBLIC;

        // Overlay matches target signature
@@ -221,28 +226,28 @@ final class IdmapManager {
        }

        // Vendor partition (/vendor)
        if (overlayPackage.isVendor()) {
        if (overlayPackageState.isVendor()) {
            return fulfilledPolicies | OverlayablePolicy.VENDOR_PARTITION;
        }

        // Product partition (/product)
        if (overlayPackage.isProduct()) {
        if (overlayPackageState.isProduct()) {
            return fulfilledPolicies | OverlayablePolicy.PRODUCT_PARTITION;
        }

        // Odm partition (/odm)
        if (overlayPackage.isOdm()) {
        if (overlayPackageState.isOdm()) {
            return fulfilledPolicies | OverlayablePolicy.ODM_PARTITION;
        }

        // Oem partition (/oem)
        if (overlayPackage.isOem()) {
        if (overlayPackageState.isOem()) {
            return fulfilledPolicies | OverlayablePolicy.OEM_PARTITION;
        }

        // System_ext partition (/system_ext) is considered as system
        // Check this last since every partition except for data is scanned as system in the PMS.
        if (overlayPackage.isSystem() || overlayPackage.isSystemExt()) {
        if (overlayPackageState.isSystem() || overlayPackageState.isSystemExt()) {
            return fulfilledPolicies | OverlayablePolicy.SYSTEM_PARTITION;
        }

+7 −8
Original line number Diff line number Diff line
@@ -28,7 +28,6 @@ import android.util.Slog;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.CollectionUtils;
import com.android.server.pm.pkg.AndroidPackage;

import java.io.IOException;
import java.util.List;
@@ -112,13 +111,13 @@ public class OverlayActorEnforcer {
        }

        final String targetPackageName = overlayInfo.targetPackageName;
        final AndroidPackage targetPkgInfo = mPackageManager.getPackageForUser(targetPackageName,
                userId);
        if (targetPkgInfo == null) {
        var targetPkgState = mPackageManager.getPackageStateForUser(targetPackageName, userId);
        var targetPkg = targetPkgState == null ? null : targetPkgState.getAndroidPackage();
        if (targetPkg == null) {
            return ActorState.TARGET_NOT_FOUND;
        }

        if (targetPkgInfo.isDebuggable()) {
        if (targetPkg.isDebuggable()) {
            return ActorState.ALLOWED;
        }

@@ -189,13 +188,13 @@ public class OverlayActorEnforcer {
        }

        String actorPackageName = actorUriPair.first;
        AndroidPackage actorPackage = mPackageManager.getPackageForUser(actorPackageName, userId);
        if (actorPackage == null) {
        var actorPackageState = mPackageManager.getPackageStateForUser(actorPackageName, userId);
        if (actorPackageState == null || actorPackageState.getAndroidPackage() == null) {
            return ActorState.ACTOR_NOT_FOUND;
        }

        // Currently only pre-installed apps can be actors
        if (!actorPackage.isSystem()) {
        if (!actorPackageState.isSystem()) {
            return ActorState.ACTOR_NOT_PREINSTALLED;
        }

+53 −47
Original line number Diff line number Diff line
@@ -90,7 +90,7 @@ import com.android.server.SystemConfig;
import com.android.server.SystemService;
import com.android.server.pm.KnownPackages;
import com.android.server.pm.UserManagerService;
import com.android.server.pm.pkg.AndroidPackage;
import com.android.server.pm.pkg.PackageState;

import libcore.util.EmptyArray;

@@ -424,9 +424,9 @@ public final class OverlayManagerService extends SystemService {
                traceBegin(TRACE_TAG_RRO, "OMS#onPackageAdded " + packageName);
                for (final int userId : userIds) {
                    synchronized (mLock) {
                        final AndroidPackage pkg = mPackageManager.onPackageAdded(
                                packageName, userId);
                        if (pkg != null && !mPackageManager.isInstantApp(packageName, userId)) {
                        var packageState = mPackageManager.onPackageAdded(packageName, userId);
                        if (packageState != null && !mPackageManager.isInstantApp(packageName,
                                userId)) {
                            try {
                                updateTargetPackagesLocked(
                                        mImpl.onPackageAdded(packageName, userId));
@@ -447,9 +447,9 @@ public final class OverlayManagerService extends SystemService {
                traceBegin(TRACE_TAG_RRO, "OMS#onPackageChanged " + packageName);
                for (int userId : userIds) {
                    synchronized (mLock) {
                        final AndroidPackage pkg = mPackageManager.onPackageUpdated(
                                packageName, userId);
                        if (pkg != null && !mPackageManager.isInstantApp(packageName, userId)) {
                        var packageState = mPackageManager.onPackageUpdated(packageName, userId);
                        if (packageState != null && !mPackageManager.isInstantApp(packageName,
                                userId)) {
                            try {
                                updateTargetPackagesLocked(
                                        mImpl.onPackageChanged(packageName, userId));
@@ -470,9 +470,9 @@ public final class OverlayManagerService extends SystemService {
                traceBegin(TRACE_TAG_RRO, "OMS#onPackageReplacing " + packageName);
                for (int userId : userIds) {
                    synchronized (mLock) {
                        final AndroidPackage pkg = mPackageManager.onPackageUpdated(
                                packageName, userId);
                        if (pkg != null && !mPackageManager.isInstantApp(packageName, userId)) {
                        var packageState = mPackageManager.onPackageUpdated(packageName, userId);
                        if (packageState != null && !mPackageManager.isInstantApp(packageName,
                                userId)) {
                            try {
                                updateTargetPackagesLocked(mImpl.onPackageReplacing(packageName,
                                        systemUpdateUninstall, userId));
@@ -493,9 +493,9 @@ public final class OverlayManagerService extends SystemService {
                traceBegin(TRACE_TAG_RRO, "OMS#onPackageReplaced " + packageName);
                for (int userId : userIds) {
                    synchronized (mLock) {
                        final AndroidPackage pkg = mPackageManager.onPackageUpdated(
                                packageName, userId);
                        if (pkg != null && !mPackageManager.isInstantApp(packageName, userId)) {
                        var packageState = mPackageManager.onPackageUpdated(packageName, userId);
                        if (packageState != null && !mPackageManager.isInstantApp(packageName,
                                userId)) {
                            try {
                                updateTargetPackagesLocked(
                                        mImpl.onPackageReplaced(packageName, userId));
@@ -1120,11 +1120,11 @@ public final class OverlayManagerService extends SystemService {
    };

    private static final class PackageManagerHelperImpl implements PackageManagerHelper {
        private static class AndroidPackageUsers {
            private AndroidPackage mPackage;
        private static class PackageStateUsers {
            private PackageState mPackageState;
            private final Set<Integer> mInstalledUsers = new ArraySet<>();
            private AndroidPackageUsers(@NonNull AndroidPackage pkg) {
                this.mPackage = pkg;
            private PackageStateUsers(@NonNull PackageState packageState) {
                this.mPackageState = packageState;
            }
        }
        private final Context mContext;
@@ -1136,7 +1136,7 @@ public final class OverlayManagerService extends SystemService {
        // intent, querying the PackageManagerService for the actual current
        // state may lead to contradictions within OMS. Better then to lag
        // behind until all pending intents have been processed.
        private final ArrayMap<String, AndroidPackageUsers> mCache = new ArrayMap<>();
        private final ArrayMap<String, PackageStateUsers> mCache = new ArrayMap<>();
        private final Set<Integer> mInitializedUsers = new ArraySet<>();

        PackageManagerHelperImpl(Context context) {
@@ -1152,18 +1152,22 @@ public final class OverlayManagerService extends SystemService {
         * @return a map of package name to all packages installed in the user
         */
        @NonNull
        public ArrayMap<String, AndroidPackage> initializeForUser(final int userId) {
        public ArrayMap<String, PackageState> initializeForUser(final int userId) {
            if (!mInitializedUsers.contains(userId)) {
                mInitializedUsers.add(userId);
                mPackageManagerInternal.forEachInstalledPackage(
                        (pkg) -> addPackageUser(pkg, userId), userId);
                mPackageManagerInternal.forEachPackageState((packageState -> {
                    if (packageState.getPkg() != null
                            && packageState.getUserStateOrDefault(userId).isInstalled()) {
                        addPackageUser(packageState, userId);
                    }
                }));
            }

            final ArrayMap<String, AndroidPackage> userPackages = new ArrayMap<>();
            final ArrayMap<String, PackageState> userPackages = new ArrayMap<>();
            for (int i = 0, n = mCache.size(); i < n; i++) {
                final AndroidPackageUsers pkg = mCache.valueAt(i);
                final PackageStateUsers pkg = mCache.valueAt(i);
                if (pkg.mInstalledUsers.contains(userId)) {
                    userPackages.put(mCache.keyAt(i), pkg.mPackage);
                    userPackages.put(mCache.keyAt(i), pkg.mPackageState);
                }
            }
            return userPackages;
@@ -1171,11 +1175,11 @@ public final class OverlayManagerService extends SystemService {

        @Override
        @Nullable
        public AndroidPackage getPackageForUser(@NonNull final String packageName,
        public PackageState getPackageStateForUser(@NonNull final String packageName,
                final int userId) {
            final AndroidPackageUsers pkg = mCache.get(packageName);
            final PackageStateUsers pkg = mCache.get(packageName);
            if (pkg != null && pkg.mInstalledUsers.contains(userId)) {
                return pkg.mPackage;
                return pkg.mPackageState;
            }
            try {
                if (!mPackageManager.isPackageAvailable(packageName, userId)) {
@@ -1190,9 +1194,9 @@ public final class OverlayManagerService extends SystemService {
        }

        @NonNull
        private AndroidPackage addPackageUser(@NonNull final String packageName,
        private PackageState addPackageUser(@NonNull final String packageName,
                final int user) {
            final AndroidPackage pkg = mPackageManagerInternal.getPackage(packageName);
            final PackageState pkg = mPackageManagerInternal.getPackageStateInternal(packageName);
            if (pkg == null) {
                Slog.w(TAG, "Android package for '" + packageName + "' could not be found;"
                        + " continuing as if package was never added", new Throwable());
@@ -1202,23 +1206,23 @@ public final class OverlayManagerService extends SystemService {
        }

        @NonNull
        private AndroidPackage addPackageUser(@NonNull final AndroidPackage pkg,
        private PackageState addPackageUser(@NonNull final PackageState pkg,
                final int user) {
            AndroidPackageUsers pkgUsers = mCache.get(pkg.getPackageName());
            PackageStateUsers pkgUsers = mCache.get(pkg.getPackageName());
            if (pkgUsers == null) {
                pkgUsers = new AndroidPackageUsers(pkg);
                pkgUsers = new PackageStateUsers(pkg);
                mCache.put(pkg.getPackageName(), pkgUsers);
            } else {
                pkgUsers.mPackage = pkg;
                pkgUsers.mPackageState = pkg;
            }
            pkgUsers.mInstalledUsers.add(user);
            return pkgUsers.mPackage;
            return pkgUsers.mPackageState;
        }


        @NonNull
        private void removePackageUser(@NonNull final String packageName, final int user) {
            final AndroidPackageUsers pkgUsers = mCache.get(packageName);
            final PackageStateUsers pkgUsers = mCache.get(packageName);
            if (pkgUsers == null) {
                return;
            }
@@ -1226,20 +1230,20 @@ public final class OverlayManagerService extends SystemService {
        }

        @NonNull
        private void removePackageUser(@NonNull final AndroidPackageUsers pkg, final int user) {
        private void removePackageUser(@NonNull final PackageStateUsers pkg, final int user) {
            pkg.mInstalledUsers.remove(user);
            if (pkg.mInstalledUsers.isEmpty()) {
                mCache.remove(pkg.mPackage.getPackageName());
                mCache.remove(pkg.mPackageState.getPackageName());
            }
        }

        @Nullable
        public AndroidPackage onPackageAdded(@NonNull final String packageName, final int userId) {
        public PackageState onPackageAdded(@NonNull final String packageName, final int userId) {
            return addPackageUser(packageName, userId);
        }

        @Nullable
        public AndroidPackage onPackageUpdated(@NonNull final String packageName,
        public PackageState onPackageUpdated(@NonNull final String packageName,
                final int userId) {
            return addPackageUser(packageName, userId);
        }
@@ -1286,14 +1290,15 @@ public final class OverlayManagerService extends SystemService {
        public OverlayableInfo getOverlayableForTarget(@NonNull String packageName,
                @NonNull String targetOverlayableName, int userId)
                throws IOException {
            final AndroidPackage packageInfo = getPackageForUser(packageName, userId);
            if (packageInfo == null) {
            var packageState = getPackageStateForUser(packageName, userId);
            var pkg = packageState == null ? null : packageState.getAndroidPackage();
            if (pkg == null) {
                throw new IOException("Unable to get target package");
            }

            ApkAssets apkAssets = null;
            try {
                apkAssets = ApkAssets.loadFromPath(packageInfo.getBaseApkPath());
                apkAssets = ApkAssets.loadFromPath(pkg.getSplits().get(0).getPath());
                return apkAssets.getOverlayableInfo(targetOverlayableName);
            } finally {
                if (apkAssets != null) {
@@ -1308,14 +1313,15 @@ public final class OverlayManagerService extends SystemService {
        @Override
        public boolean doesTargetDefineOverlayable(String targetPackageName, int userId)
                throws IOException {
            AndroidPackage packageInfo = getPackageForUser(targetPackageName, userId);
            if (packageInfo == null) {
            var packageState = getPackageStateForUser(targetPackageName, userId);
            var pkg = packageState == null ? null : packageState.getAndroidPackage();
            if (pkg == null) {
                throw new IOException("Unable to get target package");
            }

            ApkAssets apkAssets = null;
            try {
                apkAssets = ApkAssets.loadFromPath(packageInfo.getBaseApkPath());
                apkAssets = ApkAssets.loadFromPath(pkg.getSplits().get(0).getPath());
                return apkAssets.definesOverlayable();
            } finally {
                if (apkAssets != null) {
@@ -1367,8 +1373,8 @@ public final class OverlayManagerService extends SystemService {

            for (int i = 0, n = mCache.size(); i < n; i++) {
                final String packageName = mCache.keyAt(i);
                final AndroidPackageUsers pkg = mCache.valueAt(i);
                pw.print(TAB1 + packageName + ": " + pkg.mPackage + " users=");
                final PackageStateUsers pkg = mCache.valueAt(i);
                pw.print(TAB1 + packageName + ": " + pkg.mPackageState + " users=");
                pw.println(TextUtils.join(", ", pkg.mInstalledUsers));
            }
        }
+31 −16

File changed.

Preview size limit exceeded, changes collapsed.

Loading