Merge changes I7850ea5b,I9759b7dd

* changes:
  Prepare PackageState/PackageUserState for API
  Add runtime unmodifiable check for PackageState
diff --git a/services/core/java/com/android/server/pm/ApexPackageInfo.java b/services/core/java/com/android/server/pm/ApexPackageInfo.java
index 4dd9c49..672ae2e 100644
--- a/services/core/java/com/android/server/pm/ApexPackageInfo.java
+++ b/services/core/java/com/android/server/pm/ApexPackageInfo.java
@@ -329,17 +329,15 @@
             ApexInfo ai = parsingApexInfo.get(parseResult.scanFile);
 
             if (throwable == null) {
-                // Calling hideAsFinal to assign derived fields for the app info flags.
-                parseResult.parsedPackage.hideAsFinal();
-
                 // TODO: When ENABLE_FEATURE_SCAN_APEX is finalized, remove this and the entire
                 //  calling path code
                 ScanPackageUtils.applyPolicy(parseResult.parsedPackage,
                         PackageManagerService.SCAN_AS_SYSTEM,
                         mPackageManager == null ? null : mPackageManager.getPlatformPackage(),
                         false);
-                results.add(new ApexManager.ScanResult(
-                        ai, parseResult.parsedPackage, parseResult.parsedPackage.getPackageName()));
+                // Calling hideAsFinal to assign derived fields for the app info flags.
+                AndroidPackage finalPkg = parseResult.parsedPackage.hideAsFinal();
+                results.add(new ApexManager.ScanResult(ai, finalPkg, finalPkg.getPackageName()));
             } else if (throwable instanceof PackageManagerException) {
                 throw new IllegalStateException("Unable to parse: " + ai.modulePath, throwable);
             } else {
diff --git a/services/core/java/com/android/server/pm/InstallPackageHelper.java b/services/core/java/com/android/server/pm/InstallPackageHelper.java
index 2354868..1746d93 100644
--- a/services/core/java/com/android/server/pm/InstallPackageHelper.java
+++ b/services/core/java/com/android/server/pm/InstallPackageHelper.java
@@ -3451,8 +3451,8 @@
 
             if (throwable == null) {
                 try {
-                    AndroidPackage pkg = addForInitLI(
-                            parseResult.parsedPackage, newParseFlags, newScanFlags, null);
+                    addForInitLI(parseResult.parsedPackage, newParseFlags, newScanFlags, null);
+                    AndroidPackage pkg = parseResult.parsedPackage.hideAsFinal();
                     if (ai.isFactory && !ai.isActive) {
                         disableSystemPackageLPw(pkg);
                     }
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index b2f3d58..9481f8a 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -210,6 +210,7 @@
 import com.android.server.pm.permission.PermissionManagerService;
 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.PackageStateInternal;
 import com.android.server.pm.pkg.PackageUserState;
 import com.android.server.pm.pkg.PackageUserStateInternal;
@@ -222,6 +223,7 @@
 import com.android.server.pm.pkg.parsing.ParsingPackageUtils;
 import com.android.server.pm.resolution.ComponentResolver;
 import com.android.server.pm.resolution.ComponentResolverApi;
+import com.android.server.pm.snapshot.PackageDataSnapshot;
 import com.android.server.pm.verify.domain.DomainVerificationManagerInternal;
 import com.android.server.pm.verify.domain.DomainVerificationService;
 import com.android.server.pm.verify.domain.proxy.DomainVerificationProxy;
diff --git a/services/core/java/com/android/server/pm/PackageSetting.java b/services/core/java/com/android/server/pm/PackageSetting.java
index 4764a5c..03f17bd 100644
--- a/services/core/java/com/android/server/pm/PackageSetting.java
+++ b/services/core/java/com/android/server/pm/PackageSetting.java
@@ -1208,11 +1208,23 @@
     }
 
     @NonNull
+    public PackageSetting addUsesLibraryInfo(@NonNull SharedLibraryInfo value) {
+        pkgState.addUsesLibraryInfo(value);
+        return this;
+    }
+
+    @NonNull
     @Override
     public List<String> getUsesLibraryFiles() {
         return pkgState.getUsesLibraryFiles();
     }
 
+    @NonNull
+    public PackageSetting addUsesLibraryFile(String value) {
+        pkgState.addUsesLibraryFile(value);
+        return this;
+    }
+
     @Override
     public boolean isHiddenUntilInstalled() {
         return pkgState.isHiddenUntilInstalled();
diff --git a/services/core/java/com/android/server/pm/parsing/pkg/PackageImpl.java b/services/core/java/com/android/server/pm/parsing/pkg/PackageImpl.java
index 70aca99..fe63dec 100644
--- a/services/core/java/com/android/server/pm/parsing/pkg/PackageImpl.java
+++ b/services/core/java/com/android/server/pm/parsing/pkg/PackageImpl.java
@@ -385,16 +385,16 @@
     @Nullable
     @DataClass.ParcelWith(Parcelling.BuiltIn.ForBoolean.class)
     private Boolean requestRawExternalStorageAccess;
-    // TODO(chiuwinson): Non-null
-    @Nullable
-    private ArraySet<String> mimeGroups;
+    @NonNull
+    @DataClass.ParcelWith(Parcelling.BuiltIn.ForInternedStringSet.class)
+    private Set<String> mimeGroups = emptySet();
     // Usually there's code to set enabled to true during parsing, but it's possible to install
     // an APK targeting <R that doesn't contain an <application> tag. That code would be skipped
     // and never assign this, so initialize this to true for those cases.
     private long mBooleans = Booleans.ENABLED;
     private long mBooleans2;
-    @Nullable
-    private Set<String> mKnownActivityEmbeddingCerts;
+    @NonNull
+    private Set<String> mKnownActivityEmbeddingCerts = emptySet();
     // Derived fields
     private long mLongVersionCode;
     private int mLocaleConfigRes;
@@ -549,7 +549,7 @@
                 if (mimeGroups != null && mimeGroups.size() > 500) {
                     throw new IllegalStateException("Max limit on number of MIME Groups reached");
                 }
-                mimeGroups = ArrayUtils.add(mimeGroups, filter.getMimeGroup(groupIndex));
+                mimeGroups = CollectionUtils.add(mimeGroups, filter.getMimeGroup(groupIndex));
             }
         }
     }
@@ -935,8 +935,7 @@
     @NonNull
     @Override
     public Set<String> getKnownActivityEmbeddingCerts() {
-        return mKnownActivityEmbeddingCerts == null ? Collections.emptySet()
-                : mKnownActivityEmbeddingCerts;
+        return mKnownActivityEmbeddingCerts;
     }
 
     @Override
@@ -1949,8 +1948,7 @@
     }
 
     @Override
-    public ParsingPackage setKnownActivityEmbeddingCerts(
-            @Nullable Set<String> knownEmbeddingCerts) {
+    public ParsingPackage setKnownActivityEmbeddingCerts(@NonNull Set<String> knownEmbeddingCerts) {
         mKnownActivityEmbeddingCerts = knownEmbeddingCerts;
         return this;
     }
@@ -2516,7 +2514,7 @@
         appInfo.setVersionCode(mLongVersionCode);
         appInfo.setAppClassNamesByProcess(buildAppClassNamesByProcess());
         appInfo.setLocaleConfigRes(mLocaleConfigRes);
-        if (mKnownActivityEmbeddingCerts != null) {
+        if (!mKnownActivityEmbeddingCerts.isEmpty()) {
             appInfo.setKnownActivityEmbeddingCerts(mKnownActivityEmbeddingCerts);
         }
 
@@ -2593,11 +2591,11 @@
 
     @Override
     public AndroidPackageInternal hideAsFinal() {
-        // TODO(b/135203078): Lock as immutable
         if (mStorageUuid == null) {
             assignDerivedFields();
         }
         assignDerivedFields2();
+        makeImmutable();
         return this;
     }
 
@@ -2613,6 +2611,48 @@
                 baseAppDataDir + Environment.DIR_USER_DE + systemUserSuffix);
     }
 
+    private void makeImmutable() {
+        usesLibraries = Collections.unmodifiableList(usesLibraries);
+        usesOptionalLibraries = Collections.unmodifiableList(usesOptionalLibraries);
+        usesNativeLibraries = Collections.unmodifiableList(usesNativeLibraries);
+        usesOptionalNativeLibraries = Collections.unmodifiableList(usesOptionalNativeLibraries);
+        originalPackages = Collections.unmodifiableList(originalPackages);
+        adoptPermissions = Collections.unmodifiableList(adoptPermissions);
+        requestedPermissions = Collections.unmodifiableList(requestedPermissions);
+        protectedBroadcasts = Collections.unmodifiableList(protectedBroadcasts);
+        apexSystemServices = Collections.unmodifiableList(apexSystemServices);
+
+        activities = Collections.unmodifiableList(activities);
+        receivers = Collections.unmodifiableList(receivers);
+        services = Collections.unmodifiableList(services);
+        providers = Collections.unmodifiableList(providers);
+        permissions = Collections.unmodifiableList(permissions);
+        permissionGroups = Collections.unmodifiableList(permissionGroups);
+        instrumentations = Collections.unmodifiableList(instrumentations);
+
+        overlayables = Collections.unmodifiableMap(overlayables);
+        libraryNames = Collections.unmodifiableList(libraryNames);
+        usesStaticLibraries = Collections.unmodifiableList(usesStaticLibraries);
+        usesSdkLibraries = Collections.unmodifiableList(usesSdkLibraries);
+        configPreferences = Collections.unmodifiableList(configPreferences);
+        reqFeatures = Collections.unmodifiableList(reqFeatures);
+        featureGroups = Collections.unmodifiableList(featureGroups);
+        usesPermissions = Collections.unmodifiableList(usesPermissions);
+        usesSdkLibraries = Collections.unmodifiableList(usesSdkLibraries);
+        implicitPermissions = Collections.unmodifiableList(implicitPermissions);
+        upgradeKeySets = Collections.unmodifiableSet(upgradeKeySets);
+        keySetMapping = Collections.unmodifiableMap(keySetMapping);
+        attributions = Collections.unmodifiableList(attributions);
+        preferredActivityFilters = Collections.unmodifiableList(preferredActivityFilters);
+        processes = Collections.unmodifiableMap(processes);
+        mProperties = Collections.unmodifiableMap(mProperties);
+        queriesIntents = Collections.unmodifiableList(queriesIntents);
+        queriesPackages = Collections.unmodifiableList(queriesPackages);
+        queriesProviders = Collections.unmodifiableSet(queriesProviders);
+        mimeGroups = Collections.unmodifiableSet(mimeGroups);
+        mKnownActivityEmbeddingCerts = Collections.unmodifiableSet(mKnownActivityEmbeddingCerts);
+    }
+
     @Override
     public long getLongVersionCode() {
         return PackageInfo.composeLongVersionCode(versionCodeMajor, versionCode);
@@ -3041,7 +3081,7 @@
         dest.writeIntArray(this.splitRevisionCodes);
         sForBoolean.parcel(this.resizeableActivity, dest, flags);
         dest.writeInt(this.autoRevokePermissions);
-        dest.writeArraySet(this.mimeGroups);
+        sForInternedStringSet.parcel(this.mimeGroups, dest, flags);
         dest.writeInt(this.gwpAsanMode);
         dest.writeSparseIntArray(this.minExtensionVersions);
         dest.writeMap(this.mProperties);
@@ -3201,7 +3241,7 @@
         this.resizeableActivity = sForBoolean.unparcel(in);
 
         this.autoRevokePermissions = in.readInt();
-        this.mimeGroups = (ArraySet<String>) in.readArraySet(boot);
+        this.mimeGroups = sForInternedStringSet.unparcel(in);
         this.gwpAsanMode = in.readInt();
         this.minExtensionVersions = in.readSparseIntArray();
         this.mProperties = in.readHashMap(boot);
@@ -3224,6 +3264,9 @@
 
         assignDerivedFields();
         assignDerivedFields2();
+
+        // Do not call makeImmutable here as cached parsing will need
+        // to mutate this instance before it's finalized.
     }
 
     @NonNull
diff --git a/services/core/java/com/android/server/pm/pkg/AndroidPackage.java b/services/core/java/com/android/server/pm/pkg/AndroidPackage.java
index 8a82d6e..e07b77e 100644
--- a/services/core/java/com/android/server/pm/pkg/AndroidPackage.java
+++ b/services/core/java/com/android/server/pm/pkg/AndroidPackage.java
@@ -18,7 +18,6 @@
 
 import android.annotation.NonNull;
 import android.annotation.Nullable;
-import android.annotation.SystemApi;
 import android.content.ComponentName;
 import android.content.Intent;
 import android.content.pm.ActivityInfo;
@@ -59,19 +58,17 @@
 import java.util.Map;
 import java.util.Set;
 
-/**
- * Explicit interface used for consumers like mainline who need a {@link SystemApi @SystemApi} form
- * of {@link AndroidPackage}.
- *
- * @hide
- */
+/** @hide */
 //@SystemApi(client = SystemApi.Client.SYSTEM_SERVER)
 @Immutable
 public interface AndroidPackage {
 
+    // Methods below this comment are not yet exposed as API
+
     /**
      * @see ApplicationInfo#areAttributionsUserVisible()
      * @see R.styleable#AndroidManifestApplication_attributionsAreUserVisible
+     * @hide
      */
     @Nullable
     boolean areAttributionsUserVisible();
@@ -87,6 +84,7 @@
      *
      * @see ActivityInfo
      * @see PackageInfo#activities
+     * @hide
      */
     @Immutable.Ignore
     @NonNull
@@ -97,12 +95,14 @@
      * ParsingPackageUtils#TAG_ADOPT_PERMISSIONS}.
      *
      * @see R.styleable#AndroidManifestOriginalPackage_name
+     * @hide
      */
     @NonNull
     List<String> getAdoptPermissions();
 
     /**
      * @see R.styleable#AndroidManifestApexSystemService
+     * @hide
      */
     @Immutable.Ignore
     @NonNull
@@ -111,10 +111,12 @@
     /**
      * @see ApplicationInfo#appComponentFactory
      * @see R.styleable#AndroidManifestApplication_appComponentFactory
+     * @hide
      */
     @Nullable
     String getAppComponentFactory();
 
+    /** @hide */
     @Immutable.Ignore
     @NonNull
     List<ParsedAttribution> getAttributions();
@@ -123,12 +125,14 @@
      * @see ApplicationInfo#AUTO_REVOKE_ALLOWED
      * @see ApplicationInfo#AUTO_REVOKE_DISCOURAGED
      * @see ApplicationInfo#AUTO_REVOKE_DISALLOWED
+     * @hide
      */
     int getAutoRevokePermissions();
 
     /**
      * @see ApplicationInfo#backupAgentName
      * @see R.styleable#AndroidManifestApplication_backupAgent
+     * @hide
      */
     @Nullable
     String getBackupAgentName();
@@ -136,30 +140,35 @@
     /**
      * @see ApplicationInfo#banner
      * @see R.styleable#AndroidManifestApplication_banner
+     * @hide
      */
     int getBanner();
 
     /**
      * @see ApplicationInfo#sourceDir
      * @see ApplicationInfo#getBaseCodePath
+     * @hide
      */
     @NonNull
     String getBaseApkPath();
 
     /**
      * @see PackageInfo#baseRevisionCode
+     * @hide
      */
     int getBaseRevisionCode();
 
     /**
      * @see ApplicationInfo#category
      * @see R.styleable#AndroidManifestApplication_appCategory
+     * @hide
      */
     int getCategory();
 
     /**
      * @see ApplicationInfo#classLoaderName
      * @see R.styleable#AndroidManifestApplication_classLoader
+     * @hide
      */
     @Nullable
     String getClassLoaderName();
@@ -167,6 +176,7 @@
     /**
      * @see ApplicationInfo#className
      * @see R.styleable#AndroidManifestApplication_name
+     * @hide
      */
     @Nullable
     String getClassName();
@@ -174,18 +184,21 @@
     /**
      * @see ApplicationInfo#compatibleWidthLimitDp
      * @see R.styleable#AndroidManifestSupportsScreens_compatibleWidthLimitDp
+     * @hide
      */
     int getCompatibleWidthLimitDp();
 
     /**
      * @see ApplicationInfo#compileSdkVersion
      * @see R.styleable#AndroidManifest_compileSdkVersion
+     * @hide
      */
     int getCompileSdkVersion();
 
     /**
      * @see ApplicationInfo#compileSdkVersionCodename
      * @see R.styleable#AndroidManifest_compileSdkVersionCodename
+     * @hide
      */
     @Nullable
     String getCompileSdkVersionCodeName();
@@ -193,6 +206,7 @@
     /**
      * @see PackageInfo#configPreferences
      * @see R.styleable#AndroidManifestUsesConfiguration
+     * @hide
      */
     @Immutable.Ignore
     @NonNull
@@ -201,18 +215,21 @@
     /**
      * @see ApplicationInfo#dataExtractionRulesRes
      * @see R.styleable#AndroidManifestApplication_dataExtractionRules
+     * @hide
      */
     int getDataExtractionRules();
 
     /**
      * @see ApplicationInfo#descriptionRes
      * @see R.styleable#AndroidManifestApplication_description
+     * @hide
      */
     int getDescriptionRes();
 
     /**
      * @see PackageInfo#featureGroups
      * @see R.styleable#AndroidManifestUsesFeature
+     * @hide
      */
     @Immutable.Ignore
     @NonNull
@@ -221,12 +238,14 @@
     /**
      * @see ApplicationInfo#fullBackupContent
      * @see R.styleable#AndroidManifestApplication_fullBackupContent
+     * @hide
      */
     int getFullBackupContent();
 
     /**
      * @see ApplicationInfo#getGwpAsanMode()
      * @see R.styleable#AndroidManifestApplication_gwpAsanMode
+     * @hide
      */
     @ApplicationInfo.GwpAsanMode
     int getGwpAsanMode();
@@ -234,12 +253,14 @@
     /**
      * @see ApplicationInfo#iconRes
      * @see R.styleable#AndroidManifestApplication_icon
+     * @hide
      */
     int getIconRes();
 
     /**
      * Permissions requested but not in the manifest. These may have been split or migrated from
      * previous versions/definitions.
+     * @hide
      */
     @NonNull
     List<String> getImplicitPermissions();
@@ -247,12 +268,14 @@
     /**
      * @see ApplicationInfo#installLocation
      * @see R.styleable#AndroidManifest_installLocation
+     * @hide
      */
     int getInstallLocation();
 
     /**
      * @see InstrumentationInfo
      * @see PackageInfo#instrumentation
+     * @hide
      */
     @Immutable.Ignore
     @NonNull
@@ -264,6 +287,7 @@
      *
      * @see R.styleable#AndroidManifestKeySet
      * @see R.styleable#AndroidManifestPublicKey
+     * @hide
      */
     @Immutable.Ignore
     @NonNull
@@ -272,6 +296,7 @@
     /**
      * @see ApplicationInfo#mKnownActivityEmbeddingCerts
      * @see R.styleable#AndroidManifestApplication_knownActivityEmbeddingCerts
+     * @hide
      */
     @SuppressWarnings("JavadocReference")
     @NonNull
@@ -280,12 +305,14 @@
     /**
      * @see ApplicationInfo#labelRes
      * @see R.styleable#AndroidManifestApplication_label
+     * @hide
      */
     int getLabelRes();
 
     /**
      * @see ApplicationInfo#largestWidthLimitDp
      * @see R.styleable#AndroidManifestSupportsScreens_largestWidthLimitDp
+     * @hide
      */
     int getLargestWidthLimitDp();
 
@@ -293,6 +320,7 @@
      * Library names this package is declared as, for use by other packages with "uses-library".
      *
      * @see R.styleable#AndroidManifestLibrary
+     * @hide
      */
     @NonNull
     List<String> getLibraryNames();
@@ -301,23 +329,27 @@
      * The resource ID used to provide the application's locales configuration.
      *
      * @see R.styleable#AndroidManifestApplication_localeConfig
+     * @hide
      */
     int getLocaleConfigRes();
 
     /**
      * @see ApplicationInfo#logo
      * @see R.styleable#AndroidManifestApplication_logo
+     * @hide
      */
     int getLogo();
 
     /**
      * @see PackageInfo#getLongVersionCode()
+     * @hide
      */
     long getLongVersionCode();
 
     /**
      * @see ApplicationInfo#manageSpaceActivityName
      * @see R.styleable#AndroidManifestApplication_manageSpaceActivity
+     * @hide
      */
     @Nullable
     String getManageSpaceActivityName();
@@ -325,6 +357,7 @@
     /**
      * The package name as declared in the manifest, since the package can be renamed. For example,
      * static shared libs use synthetic package names.
+     * @hide
      */
     @NonNull
     String getManifestPackageName();
@@ -332,39 +365,46 @@
     /**
      * @see ApplicationInfo#maxAspectRatio
      * @see R.styleable#AndroidManifestApplication_maxAspectRatio
+     * @hide
      */
     float getMaxAspectRatio();
 
     /**
      * @see R.styleable#AndroidManifestUsesSdk_maxSdkVersion
+     * @hide
      */
     int getMaxSdkVersion();
 
     /**
      * @see ApplicationInfo#getMemtagMode()
      * @see R.styleable#AndroidManifestApplication_memtagMode
+     * @hide
      */
     @ApplicationInfo.MemtagMode
     int getMemtagMode();
 
     /**
      * TODO(b/135203078): Make all the Bundles immutable (and non-null by shared empty reference?)
+     * @hide
      */
     @Immutable.Ignore
     @Nullable
     Bundle getMetaData();
 
+    /** @hide */
     @Nullable
     Set<String> getMimeGroups();
 
     /**
      * @see ApplicationInfo#minAspectRatio
      * @see R.styleable#AndroidManifestApplication_minAspectRatio
+     * @hide
      */
     float getMinAspectRatio();
 
     /**
      * @see R.styleable#AndroidManifestExtensionSdk
+     * @hide
      */
     @Immutable.Ignore
     @Nullable
@@ -373,24 +413,28 @@
     /**
      * @see ApplicationInfo#minSdkVersion
      * @see R.styleable#AndroidManifestUsesSdk_minSdkVersion
+     * @hide
      */
     int getMinSdkVersion();
 
     /**
      * @see ApplicationInfo#getNativeHeapZeroInitialized()
      * @see R.styleable#AndroidManifestApplication_nativeHeapZeroInitialized
+     * @hide
      */
     @ApplicationInfo.NativeHeapZeroInitialized
     int getNativeHeapZeroInitialized();
 
     /**
      * @see ApplicationInfo#nativeLibraryDir
+     * @hide
      */
     @Nullable
     String getNativeLibraryDir();
 
     /**
      * @see ApplicationInfo#nativeLibraryRootDir
+     * @hide
      */
     @Nullable
     String getNativeLibraryRootDir();
@@ -398,6 +442,7 @@
     /**
      * @see ApplicationInfo#networkSecurityConfigRes
      * @see R.styleable#AndroidManifestApplication_networkSecurityConfig
+     * @hide
      */
     int getNetworkSecurityConfigRes();
 
@@ -407,6 +452,7 @@
      *
      * @see ApplicationInfo#nonLocalizedLabel
      * @see R.styleable#AndroidManifestApplication_label
+     * @hide
      */
     @Nullable
     CharSequence getNonLocalizedLabel();
@@ -416,6 +462,7 @@
      * available.
      *
      * @see R.styleable#AndroidManifestOriginalPackage}
+     * @hide
      */
     @NonNull
     List<String> getOriginalPackages();
@@ -423,6 +470,7 @@
     /**
      * @see PackageInfo#overlayCategory
      * @see R.styleable#AndroidManifestResourceOverlay_category
+     * @hide
      */
     @Nullable
     String getOverlayCategory();
@@ -430,12 +478,14 @@
     /**
      * @see PackageInfo#overlayPriority
      * @see R.styleable#AndroidManifestResourceOverlay_priority
+     * @hide
      */
     int getOverlayPriority();
 
     /**
      * @see PackageInfo#overlayTarget
      * @see R.styleable#AndroidManifestResourceOverlay_targetPackage
+     * @hide
      */
     @Nullable
     String getOverlayTarget();
@@ -443,24 +493,28 @@
     /**
      * @see PackageInfo#targetOverlayableName
      * @see R.styleable#AndroidManifestResourceOverlay_targetName
+     * @hide
      */
     @Nullable
     String getOverlayTargetOverlayableName();
 
     /**
      * Map of overlayable name to actor name.
+     * @hide
      */
     @NonNull
     Map<String, String> getOverlayables();
 
     /**
      * @see PackageInfo#packageName
+     * @hide
      */
     String getPackageName();
 
     /**
      * @see ApplicationInfo#scanSourceDir
      * @see ApplicationInfo#getCodePath
+     * @hide
      */
     @NonNull
     String getPath();
@@ -468,12 +522,14 @@
     /**
      * @see ApplicationInfo#permission
      * @see R.styleable#AndroidManifestApplication_permission
+     * @hide
      */
     @Nullable
     String getPermission();
 
     /**
      * @see android.content.pm.PermissionGroupInfo
+     * @hide
      */
     @Immutable.Ignore
     @NonNull
@@ -482,6 +538,7 @@
     /**
      * @see PermissionInfo
      * @see PackageInfo#permissions
+     * @hide
      */
     @Immutable.Ignore
     @NonNull
@@ -492,6 +549,7 @@
      * <p>
      * Map of component className to intent info inside that component. TODO(b/135203078): Is this
      * actually used/working?
+     * @hide
      */
     @Immutable.Ignore
     @NonNull
@@ -500,12 +558,14 @@
     /**
      * @see ApplicationInfo#processName
      * @see R.styleable#AndroidManifestApplication_process
+     * @hide
      */
     @NonNull
     String getProcessName();
 
     /**
      * @see android.content.pm.ProcessInfo
+     * @hide
      */
     @Immutable.Ignore
     @NonNull
@@ -513,6 +573,7 @@
 
     /**
      * Returns the properties set on the application
+     * @hide
      */
     @Immutable.Ignore
     @NonNull
@@ -522,6 +583,7 @@
      * System protected broadcasts.
      *
      * @see R.styleable#AndroidManifestProtectedBroadcast
+     * @hide
      */
     @NonNull
     List<String> getProtectedBroadcasts();
@@ -537,6 +599,7 @@
      *
      * @see ProviderInfo
      * @see PackageInfo#providers
+     * @hide
      */
     @Immutable.Ignore
     @NonNull
@@ -546,6 +609,7 @@
      * Intents that this package may query or require and thus requires visibility into.
      *
      * @see R.styleable#AndroidManifestQueriesIntent
+     * @hide
      */
     @Immutable.Ignore
     @NonNull
@@ -555,6 +619,7 @@
      * Other packages that this package may query or require and thus requires visibility into.
      *
      * @see R.styleable#AndroidManifestQueriesPackage
+     * @hide
      */
     @NonNull
     List<String> getQueriesPackages();
@@ -563,6 +628,7 @@
      * Authorities that this package may query or require and thus requires visibility into.
      *
      * @see R.styleable#AndroidManifestQueriesProvider
+     * @hide
      */
     @NonNull
     Set<String> getQueriesProviders();
@@ -583,6 +649,7 @@
      *
      * @see ActivityInfo
      * @see PackageInfo#receivers
+     * @hide
      */
     @Immutable.Ignore
     @NonNull
@@ -591,6 +658,7 @@
     /**
      * @see PackageInfo#reqFeatures
      * @see R.styleable#AndroidManifestUsesFeature
+     * @hide
      */
     @Immutable.Ignore
     @NonNull
@@ -603,6 +671,7 @@
      *
      * @see PackageInfo#requestedPermissions
      * @see R.styleable#AndroidManifestUsesPermission
+     * @hide
      */
     @NonNull
     List<String> getRequestedPermissions();
@@ -610,6 +679,7 @@
     /**
      * @see PackageInfo#requiredAccountType
      * @see R.styleable#AndroidManifestApplication_requiredAccountType
+     * @hide
      */
     @Nullable
     String getRequiredAccountType();
@@ -617,6 +687,7 @@
     /**
      * @see ApplicationInfo#requiresSmallestWidthDp
      * @see R.styleable#AndroidManifestSupportsScreens_requiresSmallestWidthDp
+     * @hide
      */
     int getRequiresSmallestWidthDp();
 
@@ -626,6 +697,7 @@
      *
      * @see ApplicationInfo#PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_RESIZEABLE
      * @see ApplicationInfo#PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_UNRESIZEABLE
+     * @hide
      */
     @Nullable
     Boolean getResizeableActivity();
@@ -634,6 +706,7 @@
      * SHA-512 hash of the only APK that can be used to update a system package.
      *
      * @see R.styleable#AndroidManifestRestrictUpdate
+     * @hide
      */
     @Immutable.Ignore
     @Nullable
@@ -644,6 +717,7 @@
      *
      * @see PackageInfo#restrictedAccountType
      * @see R.styleable#AndroidManifestApplication_restrictedAccountType
+     * @hide
      */
     @Nullable
     String getRestrictedAccountType();
@@ -651,22 +725,26 @@
     /**
      * @see ApplicationInfo#roundIconRes
      * @see R.styleable#AndroidManifestApplication_roundIcon
+     * @hide
      */
     int getRoundIconRes();
 
     /**
      * @see R.styleable#AndroidManifestSdkLibrary_name
+     * @hide
      */
     @Nullable
     String getSdkLibName();
 
     /**
      * @see R.styleable#AndroidManifestSdkLibrary_versionMajor
+     * @hide
      */
     int getSdkLibVersionMajor();
 
     /**
      * @see ApplicationInfo#secondaryNativeLibraryDir
+     * @hide
      */
     @Nullable
     String getSecondaryNativeLibraryDir();
@@ -682,6 +760,7 @@
      *
      * @see ServiceInfo
      * @see PackageInfo#services
+     * @hide
      */
     @Immutable.Ignore
     @NonNull
@@ -690,6 +769,7 @@
     /**
      * @see PackageInfo#sharedUserId
      * @see R.styleable#AndroidManifest_sharedUserId
+     * @hide
      */
     @Nullable
     String getSharedUserId();
@@ -697,12 +777,14 @@
     /**
      * @see PackageInfo#sharedUserLabel
      * @see R.styleable#AndroidManifest_sharedUserLabel
+     * @hide
      */
     int getSharedUserLabel();
 
     /**
      * The signature data of all APKs in this package, which must be exactly the same across the
      * base and splits.
+     * @hide
      */
     @Immutable.Ignore
     @NonNull
@@ -711,6 +793,7 @@
     /**
      * @see ApplicationInfo#splitClassLoaderNames
      * @see R.styleable#AndroidManifestApplication_classLoader
+     * @hide
      */
     @Immutable.Ignore
     @Nullable
@@ -719,6 +802,7 @@
     /**
      * @see ApplicationInfo#splitSourceDirs
      * @see ApplicationInfo#getSplitCodePaths
+     * @hide
      */
     @Immutable.Ignore
     @NonNull
@@ -726,6 +810,7 @@
 
     /**
      * @see ApplicationInfo#splitDependencies
+     * @hide
      */
     @Immutable.Ignore
     @NonNull
@@ -733,6 +818,7 @@
 
     /**
      * Flags of any split APKs; ordered by parsed splitName
+     * @hide
      */
     @Immutable.Ignore
     @Nullable
@@ -743,6 +829,7 @@
      *
      * @see ApplicationInfo#splitNames
      * @see PackageInfo#splitNames
+     * @hide
      */
     @Immutable.Ignore
     @NonNull
@@ -750,6 +837,7 @@
 
     /**
      * @see PackageInfo#splitRevisionCodes
+     * @hide
      */
     @Immutable.Ignore
     @NonNull
@@ -757,30 +845,35 @@
 
     /**
      * @see R.styleable#AndroidManifestStaticLibrary_name
+     * @hide
      */
     @Nullable
     String getStaticSharedLibName();
 
     /**
      * @see R.styleable#AndroidManifestStaticLibrary_version
+     * @hide
      */
     long getStaticSharedLibVersion();
 
     /**
      * @see ApplicationInfo#targetSandboxVersion
      * @see R.styleable#AndroidManifest_targetSandboxVersion
+     * @hide
      */
     int getTargetSandboxVersion();
 
     /**
      * @see ApplicationInfo#targetSdkVersion
      * @see R.styleable#AndroidManifestUsesSdk_targetSdkVersion
+     * @hide
      */
     int getTargetSdkVersion();
 
     /**
      * @see ApplicationInfo#taskAffinity
      * @see R.styleable#AndroidManifestApplication_taskAffinity
+     * @hide
      */
     @Nullable
     String getTaskAffinity();
@@ -788,12 +881,14 @@
     /**
      * @see ApplicationInfo#theme
      * @see R.styleable#AndroidManifestApplication_theme
+     * @hide
      */
     int getTheme();
 
     /**
      * @see ApplicationInfo#uiOptions
      * @see R.styleable#AndroidManifestApplication_uiOptions
+     * @hide
      */
     int getUiOptions();
 
@@ -802,6 +897,7 @@
      * {@link android.os.UserHandle#SYSTEM}.
      *
      * @deprecated Use {@link PackageState#getAppId()} instead.
+     * @hide
      */
     @Deprecated
     int getUid();
@@ -811,18 +907,21 @@
      * ParsingPackageUtils#TAG_KEY_SETS}.
      *
      * @see R.styleable#AndroidManifestUpgradeKeySet
+     * @hide
      */
     @NonNull
     Set<String> getUpgradeKeySets();
 
     /**
      * @see R.styleable#AndroidManifestUsesLibrary
+     * @hide
      */
     @NonNull
     List<String> getUsesLibraries();
 
     /**
      * @see R.styleable#AndroidManifestUsesNativeLibrary
+     * @hide
      */
     @NonNull
     List<String> getUsesNativeLibraries();
@@ -833,6 +932,7 @@
      * absence manually.
      *
      * @see R.styleable#AndroidManifestUsesLibrary
+     * @hide
      */
     @NonNull
     List<String> getUsesOptionalLibraries();
@@ -843,10 +943,12 @@
      * handle absence manually.
      *
      * @see R.styleable#AndroidManifestUsesNativeLibrary
+     * @hide
      */
     @NonNull
     List<String> getUsesOptionalNativeLibraries();
 
+    /** @hide */
     @Immutable.Ignore
     @NonNull
     List<ParsedUsesPermission> getUsesPermissions();
@@ -855,12 +957,14 @@
      * TODO(b/135203078): Move SDK library stuff to an inner data class
      *
      * @see R.styleable#AndroidManifestUsesSdkLibrary
+     * @hide
      */
     @NonNull
     List<String> getUsesSdkLibraries();
 
     /**
      * @see R.styleable#AndroidManifestUsesSdkLibrary_certDigest
+     * @hide
      */
     @Immutable.Ignore
     @Nullable
@@ -868,6 +972,7 @@
 
     /**
      * @see R.styleable#AndroidManifestUsesSdkLibrary_versionMajor
+     * @hide
      */
     @Immutable.Ignore
     @Nullable
@@ -877,12 +982,14 @@
      * TODO(b/135203078): Move static library stuff to an inner data class
      *
      * @see R.styleable#AndroidManifestUsesStaticLibrary
+     * @hide
      */
     @NonNull
     List<String> getUsesStaticLibraries();
 
     /**
      * @see R.styleable#AndroidManifestUsesStaticLibrary_certDigest
+     * @hide
      */
     @Immutable.Ignore
     @Nullable
@@ -890,6 +997,7 @@
 
     /**
      * @see R.styleable#AndroidManifestUsesStaticLibrary_version
+     * @hide
      */
     @Immutable.Ignore
     @Nullable
@@ -897,60 +1005,72 @@
 
     /**
      * @see PackageInfo#versionName
+     * @hide
      */
     @Nullable
     String getVersionName();
 
     /**
      * @see ApplicationInfo#volumeUuid
+     * @hide
      */
     @Nullable
     String getVolumeUuid();
 
+    /** @hide */
     @Nullable
     String getZygotePreloadName();
 
+    /** @hide */
     boolean hasPreserveLegacyExternalStorage();
 
     /**
      * @see ApplicationInfo#PRIVATE_FLAG_EXT_REQUEST_FOREGROUND_SERVICE_EXEMPTION
      * @see R.styleable#AndroidManifestApplication_requestForegroundServiceExemption
+     * @hide
      */
     boolean hasRequestForegroundServiceExemption();
 
     /**
      * @see ApplicationInfo#getRequestRawExternalStorageAccess()
      * @see R.styleable#AndroidManifestApplication_requestRawExternalStorageAccess
+     * @hide
      */
     Boolean hasRequestRawExternalStorageAccess();
 
     /**
      * @see ApplicationInfo#PRIVATE_FLAG_ALLOW_AUDIO_PLAYBACK_CAPTURE
+     * @hide
      */
     boolean isAllowAudioPlaybackCapture();
 
     /**
      * @see ApplicationInfo#FLAG_ALLOW_BACKUP
+     * @hide
      */
     boolean isAllowBackup();
 
     /**
      * @see ApplicationInfo#FLAG_ALLOW_CLEAR_USER_DATA
+     * @hide
      */
     boolean isAllowClearUserData();
 
     /**
      * @see ApplicationInfo#PRIVATE_FLAG_ALLOW_CLEAR_USER_DATA_ON_FAILED_RESTORE
+     * @hide
      */
     boolean isAllowClearUserDataOnFailedRestore();
 
     /**
      * @see ApplicationInfo#PRIVATE_FLAG_ALLOW_NATIVE_HEAP_POINTER_TAGGING
+     * @hide
      */
     boolean isAllowNativeHeapPointerTagging();
 
     /**
      * @see ApplicationInfo#FLAG_ALLOW_TASK_REPARENTING
+     * @hide
      */
     boolean isAllowTaskReparenting();
 
@@ -960,115 +1080,138 @@
      *
      * @see R.styleable#AndroidManifestSupportsScreens_anyDensity
      * @see ApplicationInfo#FLAG_SUPPORTS_SCREEN_DENSITIES
+     * @hide
      */
     boolean isAnyDensity();
 
+    /** @hide */
     boolean isApex();
 
     /**
      * @see ApplicationInfo#PRIVATE_FLAG_BACKUP_IN_FOREGROUND
+     * @hide
      */
     boolean isBackupInForeground();
 
     /**
      * @see ApplicationInfo#FLAG_HARDWARE_ACCELERATED
+     * @hide
      */
     boolean isBaseHardwareAccelerated();
 
     /**
      * @see ApplicationInfo#PRIVATE_FLAG_CANT_SAVE_STATE
+     * @hide
      */
     boolean isCantSaveState();
 
     /**
      * @see PackageInfo#coreApp
+     * @hide
      */
     boolean isCoreApp();
 
     /**
      * @see ApplicationInfo#crossProfile
+     * @hide
      */
     boolean isCrossProfile();
 
     /**
      * @see ApplicationInfo#FLAG_DEBUGGABLE
+     * @hide
      */
     boolean isDebuggable();
 
     /**
      * @see ApplicationInfo#PRIVATE_FLAG_DEFAULT_TO_DEVICE_PROTECTED_STORAGE
+     * @hide
      */
     boolean isDefaultToDeviceProtectedStorage();
 
     /**
      * @see ApplicationInfo#PRIVATE_FLAG_DIRECT_BOOT_AWARE
+     * @hide
      */
     boolean isDirectBootAware();
 
     /**
      * @see ApplicationInfo#enabled
      * @see R.styleable#AndroidManifestApplication_enabled
+     * @hide
      */
     boolean isEnabled();
 
     /**
      * @see ApplicationInfo#FLAG_EXTERNAL_STORAGE
+     * @hide
      */
     boolean isExternalStorage();
 
     /**
      * @see ApplicationInfo#FLAG_EXTRACT_NATIVE_LIBS
+     * @hide
      */
     boolean isExtractNativeLibs();
 
     /**
      * @see ApplicationInfo#FLAG_FACTORY_TEST
+     * @hide
      */
     boolean isFactoryTest();
 
     /**
      * @see R.styleable#AndroidManifestApplication_forceQueryable
+     * @hide
      */
     boolean isForceQueryable();
 
     /**
      * @see ApplicationInfo#FLAG_FULL_BACKUP_ONLY
+     * @hide
      */
     boolean isFullBackupOnly();
 
     /**
      * @see ApplicationInfo#FLAG_IS_GAME
+     * @hide
      */
     @Deprecated
     boolean isGame();
 
     /**
      * @see ApplicationInfo#FLAG_HAS_CODE
+     * @hide
      */
     boolean isHasCode();
 
     /**
      * @see ApplicationInfo#PRIVATE_FLAG_HAS_DOMAIN_URLS
+     * @hide
      */
     boolean isHasDomainUrls();
 
     /**
      * @see ApplicationInfo#PRIVATE_FLAG_HAS_FRAGILE_USER_DATA
+     * @hide
      */
     boolean isHasFragileUserData();
 
     /**
      * @see ApplicationInfo#PRIVATE_FLAG_ISOLATED_SPLIT_LOADING
+     * @hide
      */
     boolean isIsolatedSplitLoading();
 
     /**
      * @see ApplicationInfo#FLAG_KILL_AFTER_RESTORE
+     * @hide
      */
     boolean isKillAfterRestore();
 
     /**
      * @see ApplicationInfo#FLAG_LARGE_HEAP
+     * @hide
      */
     boolean isLargeHeap();
 
@@ -1077,83 +1220,99 @@
      * smaller than the current SDK version.
      *
      * @see R.styleable#AndroidManifest_sharedUserMaxSdkVersion
+     * @hide
      */
     boolean isLeavingSharedUid();
 
     /**
      * @see ApplicationInfo#FLAG_MULTIARCH
+     * @hide
      */
     boolean isMultiArch();
 
     /**
      * @see ApplicationInfo#nativeLibraryRootRequiresIsa
+     * @hide
      */
     boolean isNativeLibraryRootRequiresIsa();
 
     /**
      * @see ApplicationInfo#PRIVATE_FLAG_ODM
+     * @hide
      */
     boolean isOdm();
 
     /**
      * @see ApplicationInfo#PRIVATE_FLAG_OEM
+     * @hide
      */
     boolean isOem();
 
     /**
      * @see R.styleable#AndroidManifestApplication_enableOnBackInvokedCallback
+     * @hide
      */
     boolean isOnBackInvokedCallbackEnabled();
 
     /**
      * @see ApplicationInfo#PRIVATE_FLAG_IS_RESOURCE_OVERLAY
      * @see ApplicationInfo#isResourceOverlay()
+     * @hide
      */
     boolean isOverlay();
 
     /**
      * @see PackageInfo#mOverlayIsStatic
+     * @hide
      */
     boolean isOverlayIsStatic();
 
     /**
      * @see ApplicationInfo#PRIVATE_FLAG_PARTIALLY_DIRECT_BOOT_AWARE
+     * @hide
      */
     boolean isPartiallyDirectBootAware();
 
     /**
      * @see ApplicationInfo#FLAG_PERSISTENT
+     * @hide
      */
     boolean isPersistent();
 
     /**
      * @see ApplicationInfo#PRIVATE_FLAG_PRIVILEGED
+     * @hide
      */
     boolean isPrivileged();
 
     /**
      * @see ApplicationInfo#PRIVATE_FLAG_PRODUCT
+     * @hide
      */
     boolean isProduct();
 
     /**
      * @see ApplicationInfo#PRIVATE_FLAG_EXT_PROFILEABLE
+     * @hide
      */
     boolean isProfileable();
 
     /**
      * @see ApplicationInfo#PRIVATE_FLAG_PROFILEABLE_BY_SHELL
+     * @hide
      */
     boolean isProfileableByShell();
 
     /**
      * @see ApplicationInfo#PRIVATE_FLAG_REQUEST_LEGACY_EXTERNAL_STORAGE
+     * @hide
      */
     boolean isRequestLegacyExternalStorage();
 
     /**
      * @see PackageInfo#requiredForAllUsers
      * @see R.styleable#AndroidManifestApplication_requiredForAllUsers
+     * @hide
      */
     boolean isRequiredForAllUsers();
 
@@ -1162,6 +1321,7 @@
      * when the application's user data is cleared.
      *
      * @see R.styleable#AndroidManifestApplication_resetEnabledSettingsOnAppDataCleared
+     * @hide
      */
     boolean isResetEnabledSettingsOnAppDataCleared();
 
@@ -1171,36 +1331,43 @@
      *
      * @see R.styleable#AndroidManifestSupportsScreens_resizeable
      * @see ApplicationInfo#FLAG_RESIZEABLE_FOR_SCREENS
+     * @hide
      */
     boolean isResizeable();
 
     /**
      * @see ApplicationInfo#PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION
+     * @hide
      */
     boolean isResizeableActivityViaSdkVersion();
 
     /**
      * @see ApplicationInfo#FLAG_RESTORE_ANY_VERSION
+     * @hide
      */
     boolean isRestoreAnyVersion();
 
     /**
      * True means that this package/app contains an SDK library.
+     * @hide
      */
     boolean isSdkLibrary();
 
     /**
      * @see ApplicationInfo#PRIVATE_FLAG_SIGNED_WITH_PLATFORM_KEY
+     * @hide
      */
     boolean isSignedWithPlatformKey();
 
     /**
      * @see ApplicationInfo#PRIVATE_FLAG_STATIC_SHARED_LIBRARY
+     * @hide
      */
     boolean isStaticSharedLibrary();
 
     /**
      * @see PackageInfo#isStub
+     * @hide
      */
     boolean isStub();
 
@@ -1210,6 +1377,7 @@
      *
      * @see R.styleable#AndroidManifestSupportsScreens_xlargeScreens
      * @see ApplicationInfo#FLAG_SUPPORTS_XLARGE_SCREENS
+     * @hide
      */
     boolean isSupportsExtraLargeScreens();
 
@@ -1219,6 +1387,7 @@
      *
      * @see R.styleable#AndroidManifestSupportsScreens_largeScreens
      * @see ApplicationInfo#FLAG_SUPPORTS_LARGE_SCREENS
+     * @hide
      */
     boolean isSupportsLargeScreens();
 
@@ -1227,11 +1396,13 @@
      *
      * @see R.styleable#AndroidManifestSupportsScreens_normalScreens
      * @see ApplicationInfo#FLAG_SUPPORTS_NORMAL_SCREENS
+     * @hide
      */
     boolean isSupportsNormalScreens();
 
     /**
      * @see ApplicationInfo#FLAG_SUPPORTS_RTL
+     * @hide
      */
     boolean isSupportsRtl();
 
@@ -1241,21 +1412,25 @@
      *
      * @see R.styleable#AndroidManifestSupportsScreens_smallScreens
      * @see ApplicationInfo#FLAG_SUPPORTS_SMALL_SCREENS
+     * @hide
      */
     boolean isSupportsSmallScreens();
 
     /**
      * @see ApplicationInfo#FLAG_SYSTEM
+     * @hide
      */
     boolean isSystem();
 
     /**
      * @see ApplicationInfo#PRIVATE_FLAG_SYSTEM_EXT
+     * @hide
      */
     boolean isSystemExt();
 
     /**
      * @see ApplicationInfo#FLAG_TEST_ONLY
+     * @hide
      */
     boolean isTestOnly();
 
@@ -1265,26 +1440,31 @@
      * cpuAbiOverride is also set.
      *
      * @see R.attr#use32bitAbi
+     * @hide
      */
     boolean isUse32BitAbi();
 
     /**
      * @see ApplicationInfo#PRIVATE_FLAG_USE_EMBEDDED_DEX
+     * @hide
      */
     boolean isUseEmbeddedDex();
 
     /**
      * @see ApplicationInfo#FLAG_USES_CLEARTEXT_TRAFFIC
+     * @hide
      */
     boolean isUsesCleartextTraffic();
 
     /**
      * @see ApplicationInfo#PRIVATE_FLAG_USES_NON_SDK_API
+     * @hide
      */
     boolean isUsesNonSdkApi();
 
     /**
      * @see ApplicationInfo#PRIVATE_FLAG_VENDOR
+     * @hide
      */
     boolean isVendor();
 
@@ -1294,11 +1474,13 @@
      * @see R.styleable#AndroidManifestActivity_visibleToInstantApps
      * @see R.styleable#AndroidManifestProvider_visibleToInstantApps
      * @see R.styleable#AndroidManifestService_visibleToInstantApps
+     * @hide
      */
     boolean isVisibleToInstantApps();
 
     /**
      * @see ApplicationInfo#FLAG_VM_SAFE_MODE
+     * @hide
      */
     boolean isVmSafeMode();
 }
diff --git a/services/core/java/com/android/server/pm/pkg/PackageState.java b/services/core/java/com/android/server/pm/pkg/PackageState.java
index 12e9671..c0e063d 100644
--- a/services/core/java/com/android/server/pm/pkg/PackageState.java
+++ b/services/core/java/com/android/server/pm/pkg/PackageState.java
@@ -21,37 +21,20 @@
 import android.annotation.Size;
 import android.annotation.UserIdInt;
 import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageInfo;
 import android.content.pm.PackageManager;
 import android.content.pm.SharedLibraryInfo;
 import android.content.pm.SigningInfo;
 import android.processor.immutability.Immutable;
 import android.util.SparseArray;
 
-import com.android.server.pm.PackageSetting;
-import com.android.server.pm.Settings;
-
 import java.io.File;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
 
 /**
- * The API surface for a {@link PackageSetting}. Methods are expected to return immutable objects.
- * This may mean copying data on each invocation until related classes are refactored to be
- * immutable.
- * <p>
- * Note that until immutability or read-only caching is enabled, {@link PackageSetting} cannot be
- * returned directly, so {@link PackageStateImpl} is used to temporarily copy the data. This is a
- * relatively expensive operation since it has to create an object for every package, but it's much
- * lighter than the alternative of generating {@link PackageInfo} objects.
- * <p>
- * TODO: Documentation TODO: Currently missing, should be exposed as API?
- * <ul>
- *     <li>keySetData</li>
- *     <li>installSource</li>
- *     <li>incrementalStates</li>
- * </ul>
+ * The exposed system server process API for package data, shared with the internal
+ * PackageManagerService implementation. All returned data is guaranteed immutable.
  *
  * @hide
  */
@@ -59,28 +42,61 @@
 @Immutable
 public interface PackageState {
 
+    // Methods below this comment are not yet exposed as API
+
+    /*
+     * Until immutability or read-only caching is enabled, {@link PackageSetting} cannot be
+     * returned directly, so {@link PackageStateImpl} is used to temporarily copy the data.
+     * This is a relatively expensive operation since it has to create an object for every package,
+     * but it's much lighter than the alternative of generating {@link PackageInfo} objects.
+     * <p>
+     * TODO: Documentation
+     * TODO: Currently missing, should be exposed as API?
+     *   - keySetData
+     *   - installSource
+     *   - incrementalStates
+     */
+
+    // Non-doc comment invisible to API consumers:
+    // Guidelines:
+    //  - All return values should prefer non-null, immutable interfaces with only exposed getters
+    //    - Unless null itself communicates something important
+    //    - If the type is a Java collection type, it must be wrapped with unmodifiable
+    //  - All type names must be non-suffixed, with any internal types being refactored to suffix
+    //    with _Internal as necessary
+    //  - No exposure of raw values that are overridden during parsing, such as CPU ABI
+    //  - Mirroring another available system or public API is not enough justification to violate
+    //    these guidelines
+
     /**
      * This can be null whenever a physical APK on device is missing. This can be the result of
      * removing an external storage device where the APK resides.
-     * <p>
-     * This will result in the system reading the {@link PackageSetting} from disk, but without
-     * being able to parse the base APK's AndroidManifest.xml to read all of its metadata. The data
-     * that is written and read in {@link Settings} includes a minimal set of metadata needed to
-     * perform other checks in the system.
-     * <p>
+     * <p/>
+     * This will result in the system reading the state from disk, but without being able to parse
+     * the base APK's AndroidManifest.xml to read all of its metadata. The only available data that
+     * is written and read is the minimal set required to perform other checks in the system.
+     * <p/>
      * This is important in order to enforce uniqueness within the system, as the package, even if
      * on a removed storage device, is still considered installed. Another package of the same
      * application ID or declaring the same permissions or similar cannot be installed.
-     * <p>
+     * <p/>
      * Re-attaching the storage device to make the APK available should allow the user to use the
      * app once the device reboots or otherwise re-scans it.
+     * <p/>
+     * This can also occur in an device OTA situation where the package is no longer parseable on
+     * an updated SDK version, causing it to be rejectd, but the state associated with it retained,
+     * similarly to if the package had been uninstalled with the --keep-data option.
+     *
+     * @hide
      */
     @Nullable
     AndroidPackage getAndroidPackage();
 
     /**
      * The non-user-specific UID, or the UID if the user ID is
-     * {@link android.os.UserHandle#USER_SYSTEM}.
+     * {@link android.os.UserHandle#SYSTEM}.
+     *
+     * @hide
      */
     int getAppId();
 
@@ -89,6 +105,7 @@
      * applied if the application itself does not declare a category.
      *
      * @see AndroidPackage#getCategory()
+     * @hide
      */
     int getCategoryOverride();
 
@@ -96,6 +113,8 @@
      * The install time CPU override, if any. This value is written at install time
      * and doesn't change during the life of an install. If non-null,
      * {@link #getPrimaryCpuAbi()} will also contain the same value.
+     *
+     * @hide
      */
     @Nullable
     String getCpuAbiOverride();
@@ -103,6 +122,8 @@
     /**
      * In epoch milliseconds. The last modified time of the file directory which houses the app
      * APKs. Only updated on package update; does not track realtime modifications.
+     *
+     * @hide
      */
     long getLastModifiedTime();
 
@@ -110,6 +131,8 @@
      * An aggregation across the framework of the last time an app was used for a particular reason.
      * Keys are indexes into the array represented by {@link PackageManager.NotifyReason}, values
      * are in epoch milliseconds.
+     *
+     * @hide
      */
     @Immutable.Ignore
     @Size(PackageManager.NOTIFY_PACKAGE_USE_REASONS_COUNT)
@@ -119,12 +142,15 @@
     /**
      * In epoch milliseconds. The timestamp of the last time the package on device went through
      * an update package installation.
+     *
+     * @hide
      */
     long getLastUpdateTime();
 
     /**
      * Cached here in case the physical code directory on device is unmounted.
      * @see AndroidPackage#getLongVersionCode()
+     * @hide
      */
     long getVersionCode();
 
@@ -132,37 +158,43 @@
      * Maps mime group name to the set of Mime types in a group. Mime groups declared by app are
      * populated with empty sets at construction. Mime groups can not be created/removed at runtime,
      * thus keys in this map should not change.
+     *
+     * @hide
      */
     @NonNull
     Map<String, Set<String>> getMimeGroups();
 
     /**
      * @see AndroidPackage#getPackageName()
+     * @hide
      */
     @NonNull
     String getPackageName();
 
     /**
-     * TODO: Rename this to getCodePath
      * @see AndroidPackage#getPath()
+     * @hide
      */
     @NonNull
     File getPath();
 
     /**
      * @see ApplicationInfo#primaryCpuAbi
+     * @hide
      */
     @Nullable
     String getPrimaryCpuAbi();
 
     /**
      * @see ApplicationInfo#secondaryCpuAbi
+     * @hide
      */
     @Nullable
     String getSecondaryCpuAbi();
 
     /**
      * Whether the package shares the same user ID as other packages
+     * @hide
      */
     boolean hasSharedUser();
 
@@ -172,13 +204,16 @@
      *
      * @return the app ID of the shared user that this package is a part of, or -1 if it's not part
      * of a shared user.
+     * @hide
      */
     int getSharedUserAppId();
 
+    /** @hide */
     @Immutable.Ignore
     @NonNull
     SigningInfo getSigningInfo();
 
+    /** @hide */
     @Immutable.Ignore
     @NonNull
     SparseArray<? extends PackageUserState> getUserStates();
@@ -186,6 +221,7 @@
     /**
      * @return the result of {@link #getUserStates()}.get(userId) or
      * {@link PackageUserState#DEFAULT} if the state doesn't exist.
+     * @hide
      */
     @NonNull
     default PackageUserState getUserStateOrDefault(@UserIdInt int userId) {
@@ -197,12 +233,14 @@
      * The actual files resolved for each shared library.
      *
      * @see R.styleable#AndroidManifestUsesLibrary
+     * @hide
      */
     @NonNull
     List<String> getUsesLibraryFiles();
 
     /**
      * @see R.styleable#AndroidManifestUsesLibrary
+     * @hide
      */
     @Immutable.Ignore
     @NonNull
@@ -210,6 +248,7 @@
 
     /**
      * @see R.styleable#AndroidManifestUsesSdkLibrary
+     * @hide
      */
     @Immutable.Ignore
     @NonNull
@@ -217,6 +256,7 @@
 
     /**
      * @see R.styleable#AndroidManifestUsesSdkLibrary_versionMajor
+     * @hide
      */
     @Immutable.Ignore
     @NonNull
@@ -224,6 +264,7 @@
 
     /**
      * @see R.styleable#AndroidManifestUsesStaticLibrary
+     * @hide
      */
     @Immutable.Ignore
     @NonNull
@@ -231,6 +272,7 @@
 
     /**
      * @see R.styleable#AndroidManifestUsesStaticLibrary_version
+     * @hide
      */
     @Immutable.Ignore
     @NonNull
@@ -238,18 +280,22 @@
 
     /**
      * @see AndroidPackage#getVolumeUuid()
+     * @hide
      */
     @Nullable
     String getVolumeUuid();
 
     /**
      * @see AndroidPackage#isExternalStorage()
+     * @hide
      */
     boolean isExternalStorage();
 
     /**
      * Whether a package was installed --force-queryable such that it is always queryable by any
      * package, regardless of their manifest content.
+     *
+     * @hide
      */
     boolean isForceQueryableOverride();
 
@@ -258,67 +304,82 @@
      *
      * @see PackageManager#MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS
      * @see PackageManager#setSystemAppState
+     * @hide
      */
     boolean isHiddenUntilInstalled();
 
     /**
      * @see com.android.server.pm.permission.UserPermissionState
+     * @hide
      */
     boolean isInstallPermissionsFixed();
 
     /**
      * @see AndroidPackage#isOdm()
+     * @hide
      */
     boolean isOdm();
 
     /**
      * @see AndroidPackage#isOem()
+     * @hide
      */
     boolean isOem();
 
     /**
      * @see AndroidPackage#isPrivileged()
+     * @hide
      */
     boolean isPrivileged();
 
     /**
      * @see AndroidPackage#isProduct()
+     * @hide
      */
     boolean isProduct();
 
     /**
      * @see ApplicationInfo#PRIVATE_FLAG_REQUIRED_FOR_SYSTEM_USER
+     * @hide
      */
     boolean isRequiredForSystemUser();
 
     /**
      * @see AndroidPackage#isSystem()
+     * @hide
      */
     boolean isSystem();
 
     /**
      * @see AndroidPackage#isSystemExt()
+     * @hide
      */
     boolean isSystemExt();
 
     /**
      * Whether or not an update is available. Ostensibly only for instant apps.
+     * @hide
      */
     boolean isUpdateAvailable();
 
     /**
      * Whether this app is on the /data partition having been upgraded from a preinstalled app on a
      * system partition.
+     *
+     * @hide
      */
     boolean isUpdatedSystemApp();
 
     /**
      * Whether this app is packaged in an updated apex.
+     *
+     * @hide
      */
     boolean isApkInUpdatedApex();
 
     /**
      * @see AndroidPackage#isVendor()
+     * @hide
      */
     boolean isVendor();
 }
diff --git a/services/core/java/com/android/server/pm/pkg/PackageStateImpl.java b/services/core/java/com/android/server/pm/pkg/PackageStateImpl.java
index eac0842..28309c7 100644
--- a/services/core/java/com/android/server/pm/pkg/PackageStateImpl.java
+++ b/services/core/java/com/android/server/pm/pkg/PackageStateImpl.java
@@ -33,6 +33,7 @@
 import com.android.server.pm.Settings;
 
 import java.io.File;
+import java.util.Collections;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
@@ -170,7 +171,7 @@
         mLastModifiedTime = pkgState.getLastModifiedTime();
         mLastUpdateTime = pkgState.getLastUpdateTime();
         mLongVersionCode = pkgState.getVersionCode();
-        mMimeGroups = pkgState.getMimeGroups();
+        mMimeGroups = Collections.unmodifiableMap(pkgState.getMimeGroups());
         mPath = pkgState.getPath();
         mPrimaryCpuAbi = pkgState.getPrimaryCpuAbi();
         mSecondaryCpuAbi = pkgState.getSecondaryCpuAbi();
@@ -180,8 +181,8 @@
         mUsesSdkLibrariesVersionsMajor = pkgState.getUsesSdkLibrariesVersionsMajor();
         mUsesStaticLibraries = pkgState.getUsesStaticLibraries();
         mUsesStaticLibrariesVersions = pkgState.getUsesStaticLibrariesVersions();
-        mUsesLibraryInfos = pkgState.getUsesLibraryInfos();
-        mUsesLibraryFiles = pkgState.getUsesLibraryFiles();
+        mUsesLibraryInfos = Collections.unmodifiableList(pkgState.getUsesLibraryInfos());
+        mUsesLibraryFiles = Collections.unmodifiableList(pkgState.getUsesLibraryFiles());
         setBoolean(Booleans.FORCE_QUERYABLE_OVERRIDE, pkgState.isForceQueryableOverride());
         setBoolean(Booleans.HIDDEN_UNTIL_INSTALLED, pkgState.isHiddenUntilInstalled());
         setBoolean(Booleans.INSTALL_PERMISSIONS_FIXED, pkgState.isInstallPermissionsFixed());
@@ -195,8 +196,8 @@
         int userStatesSize = userStates.size();
         mUserStates = new SparseArray<>(userStatesSize);
         for (int index = 0; index < userStatesSize; index++) {
-            mUserStates.put(mUserStates.keyAt(index),
-                    UserStateImpl.copy(mUserStates.valueAt(index)));
+            mUserStates.put(userStates.keyAt(index),
+                    UserStateImpl.copy(userStates.valueAt(index)));
         }
     }
 
diff --git a/services/core/java/com/android/server/pm/pkg/PackageStateInternal.java b/services/core/java/com/android/server/pm/pkg/PackageStateInternal.java
index 84799ea..8f5795b 100644
--- a/services/core/java/com/android/server/pm/pkg/PackageStateInternal.java
+++ b/services/core/java/com/android/server/pm/pkg/PackageStateInternal.java
@@ -31,6 +31,7 @@
 
 /**
  * Exposes internal types for internal usage of {@link PackageState}.
+ * @hide
  */
 public interface PackageStateInternal extends PackageState {
 
diff --git a/services/core/java/com/android/server/pm/pkg/PackageStateUnserialized.java b/services/core/java/com/android/server/pm/pkg/PackageStateUnserialized.java
index 2c8b977..1ae00d3 100644
--- a/services/core/java/com/android/server/pm/pkg/PackageStateUnserialized.java
+++ b/services/core/java/com/android/server/pm/pkg/PackageStateUnserialized.java
@@ -23,6 +23,7 @@
 import android.content.pm.PackageManager;
 import android.content.pm.SharedLibraryInfo;
 
+import com.android.internal.util.CollectionUtils;
 import com.android.internal.util.DataClass;
 import com.android.server.pm.PackageSetting;
 
@@ -38,6 +39,7 @@
  *
  * These fields are also not copied into any cloned PackageSetting, to preserve the old behavior
  * where they would be lost implicitly by re-generating the package object.
+ * @hide
  */
 @DataClass(genSetters = true, genConstructor = false, genBuilder = false)
 @DataClass.Suppress({"setLastPackageUsageTimeInMills", "setPackageSetting"})
@@ -69,6 +71,18 @@
         mPackageSetting = packageSetting;
     }
 
+    @NonNull
+    public PackageStateUnserialized addUsesLibraryInfo(@NonNull SharedLibraryInfo value) {
+        usesLibraryInfos = CollectionUtils.add(usesLibraryInfos, value);
+        return this;
+    }
+
+    @NonNull
+    public PackageStateUnserialized addUsesLibraryFile(@NonNull String value) {
+        usesLibraryFiles = CollectionUtils.add(usesLibraryFiles, value);
+        return this;
+    }
+
     private long[] lazyInitLastPackageUsageTimeInMills() {
         return new long[PackageManager.NOTIFY_PACKAGE_USE_REASONS_COUNT];
     }
diff --git a/services/core/java/com/android/server/pm/pkg/PackageStateUtils.java b/services/core/java/com/android/server/pm/pkg/PackageStateUtils.java
index a883a05..9749cfa 100644
--- a/services/core/java/com/android/server/pm/pkg/PackageStateUtils.java
+++ b/services/core/java/com/android/server/pm/pkg/PackageStateUtils.java
@@ -24,6 +24,7 @@
 
 import com.android.server.pm.pkg.component.ParsedMainComponent;
 
+/** @hide */
 public class PackageStateUtils {
 
     public static boolean isMatch(PackageState packageState, long flags) {
diff --git a/services/core/java/com/android/server/pm/pkg/PackageUserState.java b/services/core/java/com/android/server/pm/pkg/PackageUserState.java
index 2d25385..a1b6f1d 100644
--- a/services/core/java/com/android/server/pm/pkg/PackageUserState.java
+++ b/services/core/java/com/android/server/pm/pkg/PackageUserState.java
@@ -26,9 +26,8 @@
 
 import java.util.Map;
 
+
 /**
- * The API surface for {@link PackageUserStateInternal}, for use by in-process mainline consumers.
- *
  * The parent of this class is {@link PackageState}, which handles non-user state, exposing this
  * interface for per-user state.
  *
@@ -36,123 +35,164 @@
  */
 // TODO(b/173807334): Expose API
 //@SystemApi(client = SystemApi.Client.SYSTEM_SERVER)
-@Immutable.Ignore(reason = "Exposed through PackageState pending refactor")
+@Immutable
 public interface PackageUserState {
 
-    /** @hide */
+    /**
+     * @hide
+     */
     @NonNull
     PackageUserState DEFAULT = PackageUserStateInternal.DEFAULT;
 
     /**
      * Combination of {@link #getOverlayPaths()} and {@link #getSharedLibraryOverlayPaths()}
+     *
      * @hide
      */
+    @Immutable.Ignore
     @Nullable
     OverlayPaths getAllOverlayPaths();
 
     /**
      * Credential encrypted /data partition inode.
+     *
+     * @hide
      */
     long getCeDataInode();
 
     /**
      * Fully qualified class names of components explicitly disabled.
+     *
+     * @hide
      */
     @NonNull
     ArraySet<String> getDisabledComponents();
 
+    /**
+     * @hide
+     */
     @PackageManager.DistractionRestriction
     int getDistractionFlags();
 
     /**
      * Fully qualified class names of components explicitly enabled.
+     *
+     * @hide
      */
     @NonNull
     ArraySet<String> getEnabledComponents();
 
     /**
      * Retrieve the effective enabled state of the package itself.
+     *
+     * @hide
      */
     @PackageManager.EnabledState
     int getEnabledState();
 
     /**
+     * @hide
      * @see PackageManager#setHarmfulAppWarning(String, CharSequence)
      */
     @Nullable
     String getHarmfulAppWarning();
 
+    /**
+     * @hide
+     */
     @PackageManager.InstallReason
     int getInstallReason();
 
     /**
      * Tracks the last calling package to set a specific enabled state for the package.
+     *
+     * @hide
      */
     @Nullable
     String getLastDisableAppCaller();
 
-    /** @hide */
+    /**
+     * @hide
+     */
+    @Immutable.Ignore
     @Nullable
     OverlayPaths getOverlayPaths();
 
-    /** @hide */
+    /**
+     * @hide
+     */
+    @Immutable.Ignore
     @NonNull
     Map<String, OverlayPaths> getSharedLibraryOverlayPaths();
 
+    /**
+     * @hide
+     */
     @PackageManager.UninstallReason
     int getUninstallReason();
 
     /**
      * @return whether the given fully qualified class name is explicitly enabled
+     * @hide
      */
     boolean isComponentEnabled(@NonNull String componentName);
 
     /**
      * @return {@link #isComponentEnabled(String)} but for explicitly disabled
+     * @hide
      */
     boolean isComponentDisabled(@NonNull String componentName);
 
     /**
+     * @hide
      * @see PackageManager#setApplicationHiddenSettingAsUser(String, boolean, UserHandle)
      */
     boolean isHidden();
 
     /**
      * @return whether the package is marked as installed for all users
+     * @hide
      */
     boolean isInstalled();
 
     /**
      * @return whether the package is marked as an ephemeral app, which restricts permissions,
      * features, visibility
+     * @hide
      */
     boolean isInstantApp();
 
     /**
      * @return whether the package has not been launched since being explicitly stopped
+     * @hide
      */
     boolean isNotLaunched();
 
     /**
      * @return whether the package has been stopped, which can occur if it's force-stopped, data
      * cleared, or just been installed
+     * @hide
      */
     boolean isStopped();
 
     /**
      * @return whether the package has been suspended, maybe by the device admin, disallowing its
      * launch
+     * @hide
      */
     boolean isSuspended();
 
     /**
      * @return whether the package was installed as a virtual preload, which may be done as part
      * of device infrastructure auto installation outside of the initial device image
+     * @hide
      */
     boolean isVirtualPreload();
 
     /**
      * The "package:type/entry" form of the theme resource ID previously set as the splash screen.
+     *
+     * @hide
      * @see android.window.SplashScreen#setSplashScreenTheme(int)
      * @see android.content.res.Resources#getResourceName(int)
      */
@@ -163,8 +203,10 @@
      * In epoch milliseconds. The timestamp of the first install of the app of the particular user
      * on the device, surviving past app updates. Different users might have a different first
      * install time.
-     *
+     * <p/>
      * This does not survive full removal of the app (i.e., uninstalls for all users).
+     *
+     * @hide
      */
     long getFirstInstallTime();
 }
diff --git a/services/core/java/com/android/server/pm/pkg/PackageUserStateDefault.java b/services/core/java/com/android/server/pm/pkg/PackageUserStateDefault.java
index daa4545..2d2e062 100644
--- a/services/core/java/com/android/server/pm/pkg/PackageUserStateDefault.java
+++ b/services/core/java/com/android/server/pm/pkg/PackageUserStateDefault.java
@@ -30,6 +30,7 @@
 import java.util.Collections;
 import java.util.Map;
 
+/** @hide */
 class PackageUserStateDefault implements PackageUserStateInternal {
 
     @Override
diff --git a/services/core/java/com/android/server/pm/pkg/PackageUserStateImpl.java b/services/core/java/com/android/server/pm/pkg/PackageUserStateImpl.java
index da22b17..a536f90 100644
--- a/services/core/java/com/android/server/pm/pkg/PackageUserStateImpl.java
+++ b/services/core/java/com/android/server/pm/pkg/PackageUserStateImpl.java
@@ -41,6 +41,7 @@
 import java.util.Map;
 import java.util.Objects;
 
+/** @hide */
 @DataClass(genConstructor = false, genBuilder = false, genEqualsHashCode = true)
 @DataClass.Suppress({"mOverlayPathsLock", "mOverlayPaths", "mSharedLibraryOverlayPathsLock",
         "mSharedLibraryOverlayPaths", "setOverlayPaths", "setCachedOverlayPaths"})
diff --git a/services/core/java/com/android/server/pm/pkg/PackageUserStateInternal.java b/services/core/java/com/android/server/pm/pkg/PackageUserStateInternal.java
index 96225c0..46cc830 100644
--- a/services/core/java/com/android/server/pm/pkg/PackageUserStateInternal.java
+++ b/services/core/java/com/android/server/pm/pkg/PackageUserStateInternal.java
@@ -29,6 +29,8 @@
  * Internal variant of {@link PackageUserState} that includes data not exposed as API. This is
  * still read-only and should be used inside system server code when possible over the
  * implementation.
+ *
+ * @hide
  */
 public interface PackageUserStateInternal extends PackageUserState, FrameworkPackageUserState {
 
diff --git a/services/core/java/com/android/server/pm/pkg/SharedUserApi.java b/services/core/java/com/android/server/pm/pkg/SharedUserApi.java
index 55c305c..063f577 100644
--- a/services/core/java/com/android/server/pm/pkg/SharedUserApi.java
+++ b/services/core/java/com/android/server/pm/pkg/SharedUserApi.java
@@ -27,6 +27,7 @@
 
 import java.util.List;
 
+/** @hide */
 public interface SharedUserApi {
 
     @NonNull
diff --git a/services/tests/PackageManagerServiceTests/unit/Android.bp b/services/tests/PackageManagerServiceTests/unit/Android.bp
index 1bcc3d1..1c6ba33 100644
--- a/services/tests/PackageManagerServiceTests/unit/Android.bp
+++ b/services/tests/PackageManagerServiceTests/unit/Android.bp
@@ -35,6 +35,7 @@
         "kotlin-reflect",
         "services.core",
         "servicestests-utils",
+        "servicestests-core-utils",
         "truth-prebuilt",
     ],
     platform_apis: true,
diff --git a/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/parsing/parcelling/AndroidPackageTest.kt b/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/parsing/parcelling/AndroidPackageTest.kt
index 5361041..b41fd39 100644
--- a/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/parsing/parcelling/AndroidPackageTest.kt
+++ b/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/parsing/parcelling/AndroidPackageTest.kt
@@ -23,7 +23,6 @@
 import android.content.pm.FeatureInfo
 import android.content.pm.PackageManager
 import android.content.pm.SigningDetails
-import com.android.server.pm.pkg.parsing.ParsingPackage
 import android.net.Uri
 import android.os.Bundle
 import android.os.Parcelable
@@ -65,6 +64,7 @@
         "addMimeGroupsFromComponent",
         "assignDerivedFields",
         "assignDerivedFields2",
+        "makeImmutable",
         "buildFakeForDeletion",
         "buildAppClassNamesByProcess",
         "capPermissionPriorities",
@@ -219,6 +219,7 @@
         AndroidPackage::isNativeLibraryRootRequiresIsa,
         AndroidPackage::isOdm,
         AndroidPackage::isOem,
+        AndroidPackage::isOnBackInvokedCallbackEnabled,
         AndroidPackage::isOverlay,
         AndroidPackage::isOverlayIsStatic,
         AndroidPackage::isPartiallyDirectBootAware,
@@ -279,7 +280,7 @@
         adder(AndroidPackage::getUsesOptionalNativeLibraries, "testUsesOptionalNativeLibrary"),
         getSetByValue(
             AndroidPackage::areAttributionsUserVisible,
-            ParsingPackage::setAttributionsAreUserVisible,
+            PackageImpl::setAttributionsAreUserVisible,
             true
         ),
         getSetByValue2(
@@ -513,11 +514,6 @@
             }
         ),
         getter(AndroidPackage::getKnownActivityEmbeddingCerts, setOf("TESTEMBEDDINGCERT")),
-        getSetByValue(
-            AndroidPackage::isOnBackInvokedCallbackEnabled,
-            ParsingPackage::setOnBackInvokedCallbackEnabled,
-            true
-        )
     )
 
     override fun initialObject() = PackageImpl.forParsing(
@@ -560,10 +556,13 @@
         .setSplitHasCode(1, false)
         .setSplitClassLoaderName(0, "testSplitClassLoaderNameZero")
         .setSplitClassLoaderName(1, "testSplitClassLoaderNameOne")
-
         .addUsesSdkLibrary("testSdk", 2L, arrayOf("testCertDigest1"))
         .addUsesStaticLibrary("testStatic", 3L, arrayOf("testCertDigest2"))
 
+    override fun finalizeObject(parcelable: Parcelable) {
+        (parcelable as PackageImpl).hideAsParsed().hideAsFinal()
+    }
+
     override fun extraAssertions(before: Parcelable, after: Parcelable) {
         super.extraAssertions(before, after)
         after as PackageImpl
diff --git a/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/parsing/parcelling/ParcelableComponentTest.kt b/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/parsing/parcelling/ParcelableComponentTest.kt
index e16a187..37bb935 100644
--- a/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/parsing/parcelling/ParcelableComponentTest.kt
+++ b/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/parsing/parcelling/ParcelableComponentTest.kt
@@ -293,12 +293,21 @@
         first?.let { property(it) } == second?.let { property(it) }
     }
 
-    @Test
-    fun valueComparison() {
+    fun buildBefore(): Pair<List<Param>, Parcelable> {
         val params = baseParams.mapNotNull(::buildParams) + extraParams().filterNotNull()
         val before = initialObject()
 
         params.forEach { it.setFunction(arrayOf(before, it.value())) }
+        finalizeObject(before)
+        return params to before
+    }
+
+    protected open fun finalizeObject(parcelable: Parcelable) {
+    }
+
+    @Test
+    fun valueComparison() {
+        val (params, before) = buildBefore()
 
         val parcel = Parcel.obtain()
         writeToParcel(parcel, before)
@@ -307,6 +316,15 @@
 
         parcel.setDataPosition(0)
 
+        val baseline = initialObject()
+        finalizeObject(baseline)
+
+        val baselineParcel = Parcel.obtain()
+        writeToParcel(baselineParcel, baseline)
+
+        // Check that something substantial actually changed in the test object
+        expect.that(parcel.dataSize()).isGreaterThan(baselineParcel.dataSize())
+
         val after = creator.createFromParcel(parcel)
 
         expect.withMessage("Mismatched write and read data sizes")
@@ -314,6 +332,7 @@
             .isEqualTo(dataSize)
 
         parcel.recycle()
+        baselineParcel.recycle()
 
         runAssertions(params, before, after)
     }
diff --git a/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/pkg/PackageStateTest.kt b/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/pkg/PackageStateTest.kt
new file mode 100644
index 0000000..7e9e433
--- /dev/null
+++ b/services/tests/PackageManagerServiceTests/unit/src/com/android/server/pm/test/pkg/PackageStateTest.kt
@@ -0,0 +1,297 @@
+/*
+ * Copyright (C) 2022 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.test.pkg
+
+import android.content.Intent
+import android.content.pm.overlay.OverlayPaths
+import android.content.pm.PackageManager
+import android.content.pm.PathPermission
+import android.content.pm.SharedLibraryInfo
+import android.content.pm.VersionedPackage
+import android.os.PatternMatcher
+import android.util.ArraySet
+import com.android.server.pm.PackageSetting
+import com.android.server.pm.PackageSettingBuilder
+import com.android.server.pm.parsing.pkg.PackageImpl
+import com.android.server.pm.pkg.AndroidPackage
+import com.android.server.pm.pkg.PackageState
+import com.android.server.pm.pkg.PackageStateImpl
+import com.android.server.pm.pkg.PackageUserState
+import com.android.server.pm.pkg.PackageUserStateImpl
+import com.android.server.pm.pkg.component.ParsedActivity
+import com.android.server.pm.pkg.component.ParsedActivityImpl
+import com.android.server.pm.pkg.component.ParsedComponentImpl
+import com.android.server.pm.pkg.component.ParsedInstrumentation
+import com.android.server.pm.pkg.component.ParsedIntentInfoImpl
+import com.android.server.pm.pkg.component.ParsedPermission
+import com.android.server.pm.pkg.component.ParsedPermissionGroup
+import com.android.server.pm.pkg.component.ParsedPermissionImpl
+import com.android.server.pm.pkg.component.ParsedProcess
+import com.android.server.pm.pkg.component.ParsedProcessImpl
+import com.android.server.pm.pkg.component.ParsedProvider
+import com.android.server.pm.pkg.component.ParsedProviderImpl
+import com.android.server.pm.pkg.component.ParsedService
+import com.android.server.pm.test.parsing.parcelling.AndroidPackageTest
+import com.google.common.truth.Expect
+import org.junit.Rule
+import org.junit.Test
+import org.junit.rules.TemporaryFolder
+import kotlin.contracts.ExperimentalContracts
+import kotlin.reflect.KClass
+import kotlin.reflect.KFunction
+import kotlin.reflect.KType
+import kotlin.reflect.full.isSubtypeOf
+import kotlin.reflect.full.memberFunctions
+import kotlin.reflect.full.starProjectedType
+
+class PackageStateTest {
+
+    companion object {
+        private val IGNORED_TYPES = listOf(
+                "java.io.File",
+                "java.lang.Boolean",
+                "java.lang.Byte",
+                "java.lang.CharSequence",
+                "java.lang.Character",
+                "java.lang.Double",
+                "java.lang.Float",
+                "java.lang.Integer",
+                "java.lang.Long",
+                "java.lang.Short",
+                "java.lang.String",
+                "java.lang.Void",
+        )
+        // STOPSHIP: Remove these and fix the implementations
+        private val IGNORED_FUNCTIONS = listOf(
+            ParsedActivity::getIntents,
+            ParsedActivity::getKnownActivityEmbeddingCerts,
+            ParsedActivity::getProperties,
+            ParsedInstrumentation::getIntents,
+            ParsedInstrumentation::getIntents,
+            ParsedInstrumentation::getProperties,
+            ParsedInstrumentation::getProperties,
+            ParsedPermission::getIntents,
+            ParsedPermission::getProperties,
+            ParsedPermissionGroup::getIntents,
+            ParsedPermissionGroup::getProperties,
+            ParsedProcess::getAppClassNamesByPackage,
+            ParsedProvider::getIntents,
+            ParsedProvider::getPathPermissions,
+            ParsedProvider::getProperties,
+            ParsedProvider::getUriPermissionPatterns,
+            ParsedService::getIntents,
+            ParsedService::getProperties,
+            SharedLibraryInfo::getAllCodePaths,
+            SharedLibraryInfo::getDependencies,
+            Intent::getCategories,
+            PackageUserState::getDisabledComponents,
+            PackageUserState::getEnabledComponents,
+            PackageUserState::getSharedLibraryOverlayPaths,
+            OverlayPaths::getOverlayPaths,
+            OverlayPaths::getResourceDirs,
+        )
+    }
+
+    @get:Rule
+    val tempFolder = TemporaryFolder()
+
+    @get:Rule
+    val expect = Expect.create()
+
+    private val collectionType = MutableCollection::class.starProjectedType
+    private val mapType = Map::class.starProjectedType
+
+    @OptIn(ExperimentalContracts::class)
+    @Test
+    fun collectionImmutability() {
+        val seenTypes = mutableSetOf<KType>()
+        val (_, pkg) = AndroidPackageTest().buildBefore()
+        val packageState = PackageSettingBuilder()
+            .setPackage(pkg as AndroidPackage)
+            .setCodePath(tempFolder.newFile().path)
+            .build()
+
+        fillMissingData(packageState, pkg as PackageImpl)
+
+        visitType(seenTypes, emptyList(), PackageStateImpl.copy(packageState),
+            PackageState::class.starProjectedType)
+        visitType(seenTypes, emptyList(), pkg, AndroidPackage::class.starProjectedType)
+        visitType(seenTypes, emptyList(), packageState.getUserStateOrDefault(0),
+                PackageUserState::class.starProjectedType)
+
+        // Don't check empties for defaults since their collections will always be empty
+        visitType(seenTypes, emptyList(), PackageUserState.DEFAULT,
+                PackageUserState::class.starProjectedType, enforceNonEmpty = false)
+
+        // Check that some minimum number of functions were validated,
+        // in case the type checking breaks somehow
+        expect.that(seenTypes.size).isGreaterThan(10)
+    }
+
+    /**
+     * Fill fields in [PackageState] and its children that are not filled by [AndroidPackageTest].
+     * Real objects and real invocations of the live APIs are necessary to ensure that the test
+     * mirrors real device behavior.
+     */
+    private fun fillMissingData(pkgSetting: PackageSetting, pkg: PackageImpl) {
+        pkgSetting.addUsesLibraryFile("usesLibraryFile")
+        pkgSetting.addUsesLibraryInfo(SharedLibraryInfo(
+            "path",
+            "packageName",
+            listOf(tempFolder.newFile().path),
+            "name",
+            1,
+            0,
+            VersionedPackage("versionedPackage0", 1),
+            listOf(VersionedPackage("versionedPackage1", 2)),
+            emptyList(),
+            false
+        ))
+        pkgSetting.addMimeTypes("mimeGroup", setOf("mimeType"))
+        pkgSetting.getOrCreateUserState(0).apply {
+            setEnabledComponents(ArraySet<String>().apply { add("com.test.EnabledComponent") })
+            setDisabledComponents(ArraySet<String>().apply { add("com.test.DisabledComponent") })
+            setSharedLibraryOverlayPaths("sharedLibrary",
+                OverlayPaths.Builder().addApkPath("/test/overlay.apk").build())
+        }
+
+        val property = PackageManager.Property("propertyName", 1, "com.test", null)
+        listOf(
+            pkg.activities,
+            pkg.receivers,
+            pkg.providers,
+            pkg.services,
+            pkg.instrumentations,
+            pkg.permissions,
+            pkg.permissionGroups
+        ).map { it.first() as ParsedComponentImpl }
+            .forEach {
+                it.addIntent(ParsedIntentInfoImpl())
+                it.addProperty(property)
+            }
+
+        (pkg.activities.first() as ParsedActivityImpl).knownActivityEmbeddingCerts =
+            setOf("TESTEMBEDDINGCERT")
+
+        (pkg.permissions.first() as ParsedPermissionImpl).knownCerts = setOf("TESTEMBEDDINGCERT")
+
+        (pkg.providers.first() as ParsedProviderImpl).apply {
+            addPathPermission(PathPermission("pattern", PatternMatcher.PATTERN_LITERAL,
+                "readPermission", "writerPermission"))
+            addUriPermissionPattern(PatternMatcher("*", PatternMatcher.PATTERN_LITERAL))
+        }
+
+        (pkg.processes.values.first() as ParsedProcessImpl).apply {
+            deniedPermissions = setOf("deniedPermission")
+            putAppClassNameForPackage("package", "className")
+        }
+    }
+
+    private fun visitType(
+        seenTypes: MutableSet<KType>,
+        parentChain: List<String>,
+        impl: Any,
+        type: KType,
+        enforceNonEmpty: Boolean = true
+    ) {
+        if (!seenTypes.add(type)) return
+        val kClass = type.classifier as KClass<*>
+        val qualifiedName = kClass.qualifiedName!!
+        if (IGNORED_TYPES.contains(qualifiedName)) return
+
+        val newChain = parentChain + kClass.simpleName!!
+        val newChainText = newChain.joinToString()
+
+        val filteredFunctions = kClass.memberFunctions
+            .filter {
+                // Size 1 because the impl receiver counts as a parameter
+                it.parameters.size == 1
+            }
+            .filterNot(IGNORED_FUNCTIONS::contains)
+
+        filteredFunctions.filter { it.returnType.isSubtypeOf(collectionType) }
+                .forEach {
+                    val collection = it.call(impl)
+                    if (collection as? MutableCollection<*> == null) {
+                        expect.withMessage("Method $newChainText ${it.name} cannot return null")
+                            .fail()
+                        return@forEach
+                    }
+
+                    val value = try {
+                        collection.stream().findFirst().get()!!
+                    } catch (e: Exception) {
+                        if (enforceNonEmpty) {
+                            expect.withMessage("Method $newChainText ${it.name} returns empty")
+                                .that(e)
+                                .isNull()
+                            return@forEach
+                        } else null
+                    }
+
+                    if (value != null) {
+                        it.returnType.arguments.forEach {
+                            visitType(seenTypes, newChain, value, it.type!!)
+                        }
+                    }
+
+                    // Must test clear last in case it works and actually clears the collection
+                    expectUnsupported(newChain, it) { collection.clear() }
+                }
+        filteredFunctions.filter { it.returnType.isSubtypeOf(mapType) }
+                .forEach {
+                    val map = it.call(impl)
+                    if (map as? MutableMap<*, *> == null) {
+                        expect.withMessage("Method $newChainText ${it.name} cannot return null")
+                            .fail()
+                        return@forEach
+                    }
+
+                    val entry = try {
+                        map.entries.stream().findFirst().get()!!
+                    } catch (e: Exception) {
+                        expect.withMessage("Method $newChainText ${it.name} returns empty")
+                                .that(e)
+                                .isNull()
+                        return@forEach
+                    }
+
+                    visitType(seenTypes, newChain, entry.key!!, it.returnType.arguments[0].type!!)
+                    visitType(seenTypes, newChain, entry.value!!, it.returnType.arguments[1].type!!)
+
+                    // Must test clear last in case it works and actually clears the map
+                    expectUnsupported(newChain, it) { map.clear() }
+                }
+    }
+
+    private fun expectUnsupported(
+            parentChain: List<String>,
+            function: KFunction<*>,
+            block: () -> Unit
+    ) {
+        val exception = try {
+            block()
+            null
+        } catch (e: UnsupportedOperationException) {
+            e
+        }
+
+        expect.withMessage("Method ${parentChain.joinToString()} $function doesn't throw")
+                .that(exception)
+                .isNotNull()
+    }
+}
\ No newline at end of file