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

Commit b013a475 authored by Winson's avatar Winson
Browse files

Open up AndroidPackage as @SystemApi

Moves all the PackageInfo/ApplicationInfo values into core SDK side
interfaces which represent all the mirrored functionality.

Creates AndroidPackageApi, PackageState, and a new PackageUserState
interface that act as the actual exposed interfaces for consumers like
mainline.

To avoid taking the PackageManagerService lock, and to avoid mutability
issues, PackageSettings are shallowly copied into PackageState objects.
And class PackageUserState objects into interface PackageUserState.

Eventually PackageSetting/class PackageUserState should be migrated to
the corresponding interfaces.

Miscellaneous additional changes:
 - Removes PackageSetting#uidError, was never used
 - Removes PackageUserState#categoryHint, was a package level field
   without per-user difference, use PackageSetting#categoryHint instead
 - Add locking to class PackageUserState overlay paths so they can be
   copied for the new interface.

Bug: 173455397

Test: atest com.android.server.pm.ScanTests

Change-Id: Ib98c66a9b4d78d09151724eaf14c16074c3621c9
parent b9f1ce48
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -191,7 +191,7 @@ class PackageParsingPerfTest {
    }

    class ParallelParser2(cacher: PackageCacher2? = null)
        : ParallelParser<ParsingPackageRead>(cacher) {
        : ParallelParser<ParsingPackageImpl>(cacher) {
        val input = ThreadLocal.withInitial {
            // For testing, just disable enforcement to avoid hooking up to compat framework
            ParseTypeImpl(ParseInput.Callback { _, _, _ -> false })
@@ -211,6 +211,7 @@ class PackageParsingPerfTest {

        override fun parseImpl(file: File) =
                parser.parsePackage(input.get()!!.reset(), file, 0).result
                        as ParsingPackageImpl
    }

    abstract class PackageCacher<PackageType : Parcelable>(private val cacheDir: File) {
@@ -266,7 +267,7 @@ class PackageParsingPerfTest {
    /**
     * Re-implementation of the server side PackageCacher, as it's inaccessible here.
     */
    class PackageCacher2(cacheDir: File) : PackageCacher<ParsingPackageRead>(cacheDir) {
    class PackageCacher2(cacheDir: File) : PackageCacher<ParsingPackageImpl>(cacheDir) {
        override fun fromParcel(parcel: Parcel) = ParsingPackageImpl(parcel)
    }
}
+1 −4
Original line number Diff line number Diff line
@@ -7970,13 +7970,10 @@ public class PackageParser {
            ai.enabled = false;
        }
        ai.enabledSetting = state.enabled;
        if (ai.category == ApplicationInfo.CATEGORY_UNDEFINED) {
            ai.category = state.categoryHint;
        }
        if (ai.category == ApplicationInfo.CATEGORY_UNDEFINED) {
            ai.category = FallbackCategoryProvider.getFallbackCategory(ai.packageName);
        }
        ai.seInfoUser = SELinuxUtil.assignSeinfoUser(state);
        ai.seInfoUser = SELinuxUtil.getSeinfoUser(state);
        final OverlayPaths overlayPaths = state.getAllOverlayPaths();
        if (overlayPaths != null) {
            ai.resourceDirs = overlayPaths.getResourceDirs().toArray(new String[0]);
+105 −17
Original line number Diff line number Diff line
@@ -48,20 +48,26 @@ import android.util.TypedXmlSerializer;

import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.CollectionUtils;

import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlSerializer;

import java.io.IOException;
import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

/**
 * Per-user state information about a package.
 * @hide
 */
public class PackageUserState {
public class PackageUserState implements android.content.pm.pkg.PackageUserState {
    private static final boolean DEBUG = false;
    private static final String LOG_TAG = "PackageUserState";

@@ -77,7 +83,7 @@ public class PackageUserState {
    public boolean virtualPreload;
    public int enabled;
    public String lastDisableAppCaller;
    public int categoryHint = ApplicationInfo.CATEGORY_UNDEFINED;
    @PackageManager.InstallReason
    public int installReason;
    public @PackageManager.UninstallReason int uninstallReason;
    public String harmfulAppWarning;
@@ -118,7 +124,6 @@ public class PackageUserState {
        virtualPreload = o.virtualPreload;
        enabled = o.enabled;
        lastDisableAppCaller = o.lastDisableAppCaller;
        categoryHint = o.categoryHint;
        installReason = o.installReason;
        uninstallReason = o.uninstallReason;
        disabledComponents = ArrayUtils.cloneOrNull(o.disabledComponents);
@@ -134,16 +139,6 @@ public class PackageUserState {
        splashScreenTheme = o.splashScreenTheme;
    }

    @Nullable
    public OverlayPaths getOverlayPaths() {
        return overlayPaths;
    }

    @Nullable
    public Map<String, OverlayPaths> getSharedLibraryOverlayPaths() {
        return sharedLibraryOverlayPaths;
    }

    /**
     * Sets the path of overlays currently enabled for this package and user combination.
     * @return true if the path contents differ than what they were previously
@@ -443,9 +438,6 @@ public class PackageUserState {
                        && !lastDisableAppCaller.equals(oldState.lastDisableAppCaller))) {
            return false;
        }
        if (categoryHint != oldState.categoryHint) {
            return false;
        }
        if (installReason != oldState.installReason) {
            return false;
        }
@@ -506,7 +498,6 @@ public class PackageUserState {
        hashCode = 31 * hashCode + Boolean.hashCode(virtualPreload);
        hashCode = 31 * hashCode + enabled;
        hashCode = 31 * hashCode + Objects.hashCode(lastDisableAppCaller);
        hashCode = 31 * hashCode + categoryHint;
        hashCode = 31 * hashCode + installReason;
        hashCode = 31 * hashCode + uninstallReason;
        hashCode = 31 * hashCode + Objects.hashCode(disabledComponents);
@@ -516,6 +507,103 @@ public class PackageUserState {
        return hashCode;
    }

    @Override
    public long getCeDataInode() {
        return ceDataInode;
    }

    @NonNull
    @Override
    public Set<String> getDisabledComponents() {
        return disabledComponents;
    }

    @PackageManager.DistractionRestriction
    @Override
    public int getDistractionFlags() {
        return distractionFlags;
    }

    @NonNull
    @Override
    public Set<String> getEnabledComponents() {
        return enabledComponents;
    }

    @Override
    public int getEnabledState() {
        return enabled;
    }

    @Nullable
    @Override
    public String getHarmfulAppWarning() {
        return harmfulAppWarning;
    }

    @Override
    public int getInstallReason() {
        return installReason;
    }

    @Nullable
    @Override
    public String getLastDisableAppCaller() {
        return lastDisableAppCaller;
    }

    @Nullable
    @Override
    public OverlayPaths getOverlayPaths() {
        return overlayPaths;
    }

    @Nullable
    @Override
    public Map<String, OverlayPaths> getSharedLibraryOverlayPaths() {
        return sharedLibraryOverlayPaths;
    }

    @Override
    public int getUninstallReason() {
        return uninstallReason;
    }

    @Override
    public boolean isHidden() {
        return hidden;
    }

    @Override
    public boolean isInstalled() {
        return installed;
    }

    @Override
    public boolean isInstantApp() {
        return instantApp;
    }

    @Override
    public boolean isNotLaunched() {
        return notLaunched;
    }

    @Override
    public boolean isStopped() {
        return stopped;
    }

    @Override
    public boolean isSuspended() {
        return suspended;
    }

    @Override
    public boolean isVirtualPreload() {
        return virtualPreload;
    }

    /**
     * Container to describe suspension parameters.
     */
+1 −4
Original line number Diff line number Diff line
@@ -16,8 +16,6 @@

package android.content.pm;

import com.android.internal.util.ArrayUtils;

/**
 * Utility methods that need to be used in application space.
 * @hide
@@ -31,11 +29,10 @@ public final class SELinuxUtil {
    public static final String COMPLETE_STR = ":complete";

    /** @hide */
    public static String assignSeinfoUser(PackageUserState userState) {
    public static String getSeinfoUser(PackageUserState userState) {
        if (userState.instantApp) {
           return INSTANT_APP_STR + COMPLETE_STR;
        }
        return COMPLETE_STR;
    }

}
+9 −12
Original line number Diff line number Diff line
@@ -213,8 +213,8 @@ public class PackageInfoWithoutStateUtils {
        PackageInfo pi = new PackageInfo();
        pi.packageName = pkg.getPackageName();
        pi.splitNames = pkg.getSplitNames();
        pi.versionCode = pkg.getVersionCode();
        pi.versionCodeMajor = pkg.getVersionCodeMajor();
        pi.versionCode = ((ParsingPackageHidden) pkg).getVersionCode();
        pi.versionCodeMajor = ((ParsingPackageHidden) pkg).getVersionCodeMajor();
        pi.baseRevisionCode = pkg.getBaseRevisionCode();
        pi.splitRevisionCodes = pkg.getSplitRevisionCodes();
        pi.versionName = pkg.getVersionName();
@@ -229,7 +229,7 @@ public class PackageInfoWithoutStateUtils {
        pi.restrictedAccountType = pkg.getRestrictedAccountType();
        pi.requiredAccountType = pkg.getRequiredAccountType();
        pi.overlayTarget = pkg.getOverlayTarget();
        pi.targetOverlayableName = pkg.getOverlayTargetName();
        pi.targetOverlayableName = pkg.getOverlayTargetOverlayableName();
        pi.overlayCategory = pkg.getOverlayCategory();
        pi.overlayPriority = pkg.getOverlayPriority();
        pi.mOverlayIsStatic = pkg.isOverlayIsStatic();
@@ -246,10 +246,10 @@ public class PackageInfoWithoutStateUtils {
                pi.configPreferences = new ConfigurationInfo[size];
                pkg.getConfigPreferences().toArray(pi.configPreferences);
            }
            size = pkg.getReqFeatures().size();
            size = pkg.getRequestedFeatures().size();
            if (size > 0) {
                pi.reqFeatures = new FeatureInfo[size];
                pkg.getReqFeatures().toArray(pi.reqFeatures);
                pkg.getRequestedFeatures().toArray(pi.reqFeatures);
            }
            size = pkg.getFeatureGroups().size();
            if (size > 0) {
@@ -389,10 +389,10 @@ public class PackageInfoWithoutStateUtils {
     */
    @NonNull
    public static ApplicationInfo generateApplicationInfoUnchecked(@NonNull ParsingPackageRead pkg,
            @PackageManager.ApplicationInfoFlags int flags, PackageUserState state, int userId,
            boolean assignUserFields) {
            @PackageManager.ApplicationInfoFlags int flags, @NonNull PackageUserState state,
            int userId, boolean assignUserFields) {
        // Make shallow copy so we can store the metadata/libraries safely
        ApplicationInfo ai = pkg.toAppInfoWithoutState();
        ApplicationInfo ai = ((ParsingPackageHidden) pkg).toAppInfoWithoutState();

        if (assignUserFields) {
            assignUserFields(pkg, ai, userId);
@@ -434,13 +434,10 @@ public class PackageInfoWithoutStateUtils {
            ai.enabled = false;
        }
        ai.enabledSetting = state.enabled;
        if (ai.category == ApplicationInfo.CATEGORY_UNDEFINED) {
            ai.category = state.categoryHint;
        }
        if (ai.category == ApplicationInfo.CATEGORY_UNDEFINED) {
            ai.category = FallbackCategoryProvider.getFallbackCategory(ai.packageName);
        }
        ai.seInfoUser = SELinuxUtil.assignSeinfoUser(state);
        ai.seInfoUser = SELinuxUtil.getSeinfoUser(state);
        final OverlayPaths overlayPaths = state.getAllOverlayPaths();
        if (overlayPaths != null) {
            ai.resourceDirs = overlayPaths.getResourceDirs().toArray(new String[0]);
Loading