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

Commit fc54f251 authored by Winson Chiu's avatar Winson Chiu
Browse files

Prepare PackageState/PackageUserState for API

Marks the applicable places as @hide. Only the immediate APIs
needed for the ART services integration will be exposed in the
first round. This makes review easier and isolates the changes.

Bug: 235462722

Test: m update-api with classes marked as API succeeds

Change-Id: I7850ea5b1deb479c596112f88c92f0045ebed743
parent fad1ef99
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -210,6 +210,7 @@ import com.android.server.pm.permission.LegacyPermissionManagerService;
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.mutate.PackageUserStateWrite;
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;
+189 −7

File changed.

Preview size limit exceeded, changes collapsed.

+89 −28
Original line number Diff line number Diff line
@@ -21,37 +21,20 @@ import android.annotation.Nullable;
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 @@ import java.util.Set;
@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 @@ public interface PackageState {
     * applied if the application itself does not declare a category.
     *
     * @see AndroidPackage#getCategory()
     * @hide
     */
    int getCategoryOverride();

@@ -96,6 +113,8 @@ public interface PackageState {
     * 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 @@ public interface PackageState {
    /**
     * 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 @@ public interface PackageState {
     * 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 @@ public interface PackageState {
    /**
     * 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 @@ public interface PackageState {
     * 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 @@ public interface PackageState {
     *
     * @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 @@ public interface PackageState {
    /**
     * @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 @@ public interface PackageState {
     * 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 @@ public interface PackageState {

    /**
     * @see R.styleable#AndroidManifestUsesSdkLibrary
     * @hide
     */
    @Immutable.Ignore
    @NonNull
@@ -217,6 +256,7 @@ public interface PackageState {

    /**
     * @see R.styleable#AndroidManifestUsesSdkLibrary_versionMajor
     * @hide
     */
    @Immutable.Ignore
    @NonNull
@@ -224,6 +264,7 @@ public interface PackageState {

    /**
     * @see R.styleable#AndroidManifestUsesStaticLibrary
     * @hide
     */
    @Immutable.Ignore
    @NonNull
@@ -231,6 +272,7 @@ public interface PackageState {

    /**
     * @see R.styleable#AndroidManifestUsesStaticLibrary_version
     * @hide
     */
    @Immutable.Ignore
    @NonNull
@@ -238,18 +280,22 @@ public interface PackageState {

    /**
     * @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 @@ public interface PackageState {
     *
     * @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();
}
+1 −0
Original line number Diff line number Diff line
@@ -31,6 +31,7 @@ import java.util.UUID;

/**
 * Exposes internal types for internal usage of {@link PackageState}.
 * @hide
 */
public interface PackageStateInternal extends PackageState {

+1 −0
Original line number Diff line number Diff line
@@ -39,6 +39,7 @@ import java.util.stream.Collectors;
 *
 * 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"})
Loading