Expose some package APIs for ART
This was separated out to make review easier. Applies @SystemApi
to expose a subset of PackageState and its child type APIs.
Bug: 235462722
Bug: 246609797
Bug: 244444049
Bug: 229089418
Bug: 229090204
Bug: 229090094
Test: presubmit
Change-Id: Ifc0ee3584347a79fbb0e7815d42bac6d2c2f3a4a
diff --git a/core/java/android/content/pm/SharedLibraryInfo.java b/core/java/android/content/pm/SharedLibraryInfo.java
index 4c0e2e6..fdd2aa1 100644
--- a/core/java/android/content/pm/SharedLibraryInfo.java
+++ b/core/java/android/content/pm/SharedLibraryInfo.java
@@ -49,7 +49,7 @@
TYPE_SDK_PACKAGE,
})
@Retention(RetentionPolicy.SOURCE)
- @interface Type{}
+ public @interface Type{}
/**
* Shared library type: this library is a part of the OS
diff --git a/services/api/current.txt b/services/api/current.txt
index 5f203df..42ae10e 100644
--- a/services/api/current.txt
+++ b/services/api/current.txt
@@ -48,10 +48,82 @@
public interface PackageManagerLocal {
method public void reconcileSdkData(@Nullable String, @NonNull String, @NonNull java.util.List<java.lang.String>, int, int, int, @NonNull String, int) throws java.io.IOException;
+ method @NonNull public com.android.server.pm.PackageManagerLocal.FilteredSnapshot withFilteredSnapshot();
+ method @NonNull public com.android.server.pm.PackageManagerLocal.FilteredSnapshot withFilteredSnapshot(int, @NonNull android.os.UserHandle);
+ method @NonNull public com.android.server.pm.PackageManagerLocal.UnfilteredSnapshot withUnfilteredSnapshot();
field public static final int FLAG_STORAGE_CE = 2; // 0x2
field public static final int FLAG_STORAGE_DE = 1; // 0x1
}
+ public static interface PackageManagerLocal.FilteredSnapshot extends java.lang.AutoCloseable {
+ method public void close();
+ method public void forAllPackageStates(@NonNull java.util.function.Consumer<com.android.server.pm.pkg.PackageState>);
+ method @Nullable public com.android.server.pm.pkg.PackageState getPackageState(@NonNull String);
+ }
+
+ public static interface PackageManagerLocal.UnfilteredSnapshot extends java.lang.AutoCloseable {
+ method public void close();
+ method @NonNull public com.android.server.pm.PackageManagerLocal.FilteredSnapshot filtered(int, @NonNull android.os.UserHandle);
+ method @NonNull public java.util.Map<java.lang.String,com.android.server.pm.pkg.PackageState> getPackageStates();
+ }
+
+}
+
+package com.android.server.pm.pkg {
+
+ public interface AndroidPackage {
+ method @NonNull public java.util.List<java.lang.String> getLibraryNames();
+ method @Nullable public String getSdkLibraryName();
+ method @NonNull public java.util.List<com.android.server.pm.pkg.AndroidPackageSplit> getSplits();
+ method @Nullable public String getStaticSharedLibraryName();
+ method public int getTargetSdkVersion();
+ method public boolean isDebuggable();
+ method public boolean isIsolatedSplitLoading();
+ method public boolean isSignedWithPlatformKey();
+ method public boolean isUseEmbeddedDex();
+ method public boolean isUsesNonSdkApi();
+ method public boolean isVmSafeMode();
+ }
+
+ public interface AndroidPackageSplit {
+ method @Nullable public String getClassLoaderName();
+ method @NonNull public java.util.List<com.android.server.pm.pkg.AndroidPackageSplit> getDependencies();
+ method @Nullable public String getName();
+ method @NonNull public String getPath();
+ method public int getRevisionCode();
+ method public boolean isHasCode();
+ }
+
+ public interface PackageState {
+ method @Nullable public com.android.server.pm.pkg.AndroidPackage getAndroidPackage();
+ method public int getAppId();
+ method @NonNull public String getPackageName();
+ method @Nullable public String getPrimaryCpuAbi();
+ method @Nullable public String getSecondaryCpuAbi();
+ method @NonNull public com.android.server.pm.pkg.PackageUserState getStateForUser(@NonNull android.os.UserHandle);
+ method @NonNull public java.util.List<com.android.server.pm.pkg.SharedLibrary> getUsesLibraries();
+ method public boolean isPrivileged();
+ method public boolean isSystem();
+ method public boolean isUpdatedSystemApp();
+ }
+
+ public interface PackageUserState {
+ method public boolean isInstalled();
+ }
+
+ public interface SharedLibrary {
+ method @NonNull public java.util.List<java.lang.String> getAllCodePaths();
+ method @NonNull public android.content.pm.VersionedPackage getDeclaringPackage();
+ method @NonNull public java.util.List<com.android.server.pm.pkg.SharedLibrary> getDependencies();
+ method @NonNull public java.util.List<android.content.pm.VersionedPackage> getDependentPackages();
+ method @Nullable public String getName();
+ method @Nullable public String getPackageName();
+ method @Nullable public String getPath();
+ method public int getType();
+ method public long getVersion();
+ method public boolean isNative();
+ }
+
}
package com.android.server.pm.snapshot {
diff --git a/services/core/java/com/android/server/pm/PackageManagerLocal.java b/services/core/java/com/android/server/pm/PackageManagerLocal.java
index c9b48bf3..21c2f2c 100644
--- a/services/core/java/com/android/server/pm/PackageManagerLocal.java
+++ b/services/core/java/com/android/server/pm/PackageManagerLocal.java
@@ -95,8 +95,6 @@
* <p/>
* The snapshot assumes the caller is acting on behalf of the system and will not filter any
* results.
- *
- * @hide
*/
@NonNull
UnfilteredSnapshot withUnfilteredSnapshot();
@@ -106,7 +104,6 @@
* caller through {@link Binder#getCallingUid()} and {@link Binder#getCallingUserHandle()}.
*
* @see #withFilteredSnapshot(int, UserHandle)
- * @hide
*/
@NonNull
FilteredSnapshot withFilteredSnapshot();
@@ -121,7 +118,6 @@
* and permissions, including cross-user enforcement.
* @param user The user to query as, should usually be the user that the caller was
* invoked from.
- * @hide
*/
@SuppressWarnings("UserHandleName") // Ignore naming convention, not invoking action as user
@NonNull
@@ -130,6 +126,7 @@
/**
* @hide
*/
+ @SystemApi(client = SystemApi.Client.SYSTEM_SERVER)
interface UnfilteredSnapshot extends AutoCloseable {
/**
@@ -160,6 +157,7 @@
/**
* @hide
*/
+ @SystemApi(client = SystemApi.Client.SYSTEM_SERVER)
interface FilteredSnapshot extends AutoCloseable {
/**
diff --git a/services/core/java/com/android/server/pm/local/PackageManagerLocalImpl.java b/services/core/java/com/android/server/pm/local/PackageManagerLocalImpl.java
index 00c8f84..4ff0d59 100644
--- a/services/core/java/com/android/server/pm/local/PackageManagerLocalImpl.java
+++ b/services/core/java/com/android/server/pm/local/PackageManagerLocalImpl.java
@@ -31,6 +31,7 @@
import java.io.IOException;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;
@@ -82,6 +83,7 @@
mSnapshot = (Computer) snapshot;
}
+ @CallSuper
@Override
public void close() {
mClosed = true;
@@ -100,6 +102,9 @@
private static class UnfilteredSnapshotImpl extends BaseSnapshotImpl implements
UnfilteredSnapshot {
+ @Nullable
+ private Map<String, PackageState> mCachedUnmodifiablePackageStates;
+
private UnfilteredSnapshotImpl(@NonNull PackageDataSnapshot snapshot) {
super(snapshot);
}
@@ -115,8 +120,17 @@
public Map<String, PackageState> getPackageStates() {
checkClosed();
- //noinspection unchecked, RedundantCast
- return (Map<String, PackageState>) (Map<?, ?>) mSnapshot.getPackageStates();
+ if (mCachedUnmodifiablePackageStates == null) {
+ mCachedUnmodifiablePackageStates =
+ Collections.unmodifiableMap(mSnapshot.getPackageStates());
+ }
+ return mCachedUnmodifiablePackageStates;
+ }
+
+ @Override
+ public void close() {
+ super.close();
+ mCachedUnmodifiablePackageStates = null;
}
}
@@ -152,6 +166,12 @@
super.checkClosed();
}
+ @Override
+ public void close() {
+ super.close();
+ mFilteredPackageStates = null;
+ }
+
@Nullable
@Override
public PackageState getPackageState(@NonNull String packageName) {
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 5108fcd..e3dad45 100644
--- a/services/core/java/com/android/server/pm/pkg/AndroidPackage.java
+++ b/services/core/java/com/android/server/pm/pkg/AndroidPackage.java
@@ -18,6 +18,7 @@
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;
@@ -58,8 +59,27 @@
import java.util.Map;
import java.util.Set;
-/** @hide */
-//@SystemApi(client = SystemApi.Client.SYSTEM_SERVER)
+/**
+ * The representation of an application on disk, as parsed from its split APKs' manifests.
+ *
+ * Metadata available here is mostly device-state independent and indicates what the application
+ * author declared for their app.
+ *
+ * This is the system server in-process API equivalent of the public API {@link ApplicationInfo}.
+ * Note that because {@link ApplicationInfo} is stateful, several methods that exist on it may not
+ * be available here and need to be read through {@link PackageState} or {@link PackageUserState}.
+ *
+ * All instances of {@link AndroidPackage} are associated with a {@link PackageState}, and the
+ * only way to retrieve one is through {@link PackageState}. Note that the inverse does not apply
+ * and {@link AndroidPackage} may be null in several cases. See
+ * {@link PackageState#getAndroidPackage()}.
+ *
+ * The data available here is immutable and will throw {@link UnsupportedOperationException} if any
+ * collection type is mutated.
+ *
+ * @hide
+ */
+@SystemApi(client = SystemApi.Client.SYSTEM_SERVER)
@Immutable
public interface AndroidPackage {
@@ -98,11 +118,13 @@
/**
* @see ApplicationInfo#FLAG_DEBUGGABLE
+ * @see R.styleable#AndroidManifestApplication_debuggable
*/
boolean isDebuggable();
/**
* @see ApplicationInfo#PRIVATE_FLAG_ISOLATED_SPLIT_LOADING
+ * @see R.styleable#AndroidManifest_isolatedSplits
*/
boolean isIsolatedSplitLoading();
@@ -113,16 +135,19 @@
/**
* @see ApplicationInfo#PRIVATE_FLAG_USE_EMBEDDED_DEX
+ * @see R.styleable#AndroidManifestApplication_useEmbeddedDex
*/
boolean isUseEmbeddedDex();
/**
* @see ApplicationInfo#PRIVATE_FLAG_USES_NON_SDK_API
+ * @see R.styleable#AndroidManifestApplication_usesNonSdkApi
*/
boolean isUsesNonSdkApi();
/**
* @see ApplicationInfo#FLAG_VM_SAFE_MODE
+ * @see R.styleable#AndroidManifestApplication_vmSafeMode
*/
boolean isVmSafeMode();
@@ -147,6 +172,7 @@
*
* @see ActivityInfo
* @see PackageInfo#activities
+ * @see R.styleable#AndroidManifestActivity
* @hide
*/
@Immutable.Ignore
@@ -179,7 +205,10 @@
@Nullable
String getAppComponentFactory();
- /** @hide */
+ /**
+ * @see R.styleable#AndroidManifestAttribution
+ * @hide
+ */
@Immutable.Ignore
@NonNull
List<ParsedAttribution> getAttributions();
@@ -188,6 +217,7 @@
* @see ApplicationInfo#AUTO_REVOKE_ALLOWED
* @see ApplicationInfo#AUTO_REVOKE_DISCOURAGED
* @see ApplicationInfo#AUTO_REVOKE_DISALLOWED
+ * @see R.styleable#AndroidManifestApplication_autoRevokePermissions
* @hide
*/
int getAutoRevokePermissions();
@@ -217,6 +247,7 @@
/**
* @see PackageInfo#baseRevisionCode
+ * @see R.styleable#AndroidManifest_revisionCode
* @hide
*/
int getBaseRevisionCode();
@@ -338,6 +369,7 @@
/**
* @see InstrumentationInfo
* @see PackageInfo#instrumentation
+ * @see R.styleable#AndroidManifestInstrumentation
* @hide
*/
@Immutable.Ignore
@@ -396,6 +428,8 @@
/**
* @see PackageInfo#getLongVersionCode()
+ * @see R.styleable#AndroidManifest_versionCode
+ * @see R.styleable#AndroidManifest_versionCodeMajor
* @hide
*/
long getLongVersionCode();
@@ -439,13 +473,17 @@
/**
* TODO(b/135203078): Make all the Bundles immutable (and non-null by shared empty reference?)
+ * @see R.styleable#AndroidManifestMetaData
* @hide
*/
@Immutable.Ignore
@Nullable
Bundle getMetaData();
- /** @hide */
+ /**
+ * @see R.attr#mimeGroup
+ * @hide
+ */
@Nullable
Set<String> getMimeGroups();
@@ -583,6 +621,7 @@
/**
* @see android.content.pm.PermissionGroupInfo
+ * @see R.styleable#AndroidManifestPermissionGroup
* @hide
*/
@Immutable.Ignore
@@ -619,6 +658,7 @@
/**
* @see android.content.pm.ProcessInfo
+ * @see R.styleable#AndroidManifestProcess
* @hide
*/
@Immutable.Ignore
@@ -627,6 +667,7 @@
/**
* Returns the properties set on the application
+ * @see R.styleable#AndroidManifestProperty
* @hide
*/
@Immutable.Ignore
@@ -653,6 +694,7 @@
*
* @see ProviderInfo
* @see PackageInfo#providers
+ * @see R.styleable#AndroidManifestProvider
* @hide
*/
@Immutable.Ignore
@@ -703,6 +745,7 @@
*
* @see ActivityInfo
* @see PackageInfo#receivers
+ * @see R.styleable#AndroidManifestReceiver
* @hide
*/
@Immutable.Ignore
@@ -751,6 +794,7 @@
*
* @see ApplicationInfo#PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_RESIZEABLE
* @see ApplicationInfo#PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_UNRESIZEABLE
+ * @see R.styleable#AndroidManifestApplication_resizeableActivity
* @hide
*/
@Nullable
@@ -807,6 +851,7 @@
*
* @see ServiceInfo
* @see PackageInfo#services
+ * @see R.styleable#AndroidManifestService
* @hide
*/
@Immutable.Ignore
@@ -1050,7 +1095,11 @@
@Nullable
String getVolumeUuid();
- /** @hide */
+ /**
+ * @see ApplicationInfo#zygotePreloadName
+ * @see R.styleable#AndroidManifestApplication_zygotePreloadName
+ * @hide
+ */
@Nullable
String getZygotePreloadName();
@@ -1073,36 +1122,42 @@
/**
* @see ApplicationInfo#PRIVATE_FLAG_ALLOW_AUDIO_PLAYBACK_CAPTURE
+ * @see R.styleable#AndroidManifestApplication_allowAudioPlaybackCapture
* @hide
*/
boolean isAllowAudioPlaybackCapture();
/**
* @see ApplicationInfo#FLAG_ALLOW_BACKUP
+ * @see R.styleable#AndroidManifestApplication_allowBackup
* @hide
*/
boolean isAllowBackup();
/**
* @see ApplicationInfo#FLAG_ALLOW_CLEAR_USER_DATA
+ * @see R.styleable#AndroidManifestApplication_allowClearUserData
* @hide
*/
boolean isAllowClearUserData();
/**
* @see ApplicationInfo#PRIVATE_FLAG_ALLOW_CLEAR_USER_DATA_ON_FAILED_RESTORE
+ * @see R.styleable#AndroidManifestApplication_allowClearUserDataOnFailedRestore
* @hide
*/
boolean isAllowClearUserDataOnFailedRestore();
/**
* @see ApplicationInfo#PRIVATE_FLAG_ALLOW_NATIVE_HEAP_POINTER_TAGGING
+ * @see R.styleable#AndroidManifestApplication_allowNativeHeapPointerTagging
* @hide
*/
boolean isAllowNativeHeapPointerTagging();
/**
* @see ApplicationInfo#FLAG_ALLOW_TASK_REPARENTING
+ * @see R.styleable#AndroidManifestApplication_allowTaskReparenting
* @hide
*/
boolean isAllowTaskReparenting();
@@ -1122,18 +1177,21 @@
/**
* @see ApplicationInfo#PRIVATE_FLAG_BACKUP_IN_FOREGROUND
+ * @see R.styleable#AndroidManifestApplication_backupInForeground
* @hide
*/
boolean isBackupInForeground();
/**
* @see ApplicationInfo#FLAG_HARDWARE_ACCELERATED
+ * @see R.styleable#AndroidManifestApplication_hardwareAccelerated
* @hide
*/
boolean isBaseHardwareAccelerated();
/**
* @see ApplicationInfo#PRIVATE_FLAG_CANT_SAVE_STATE
+ * @see R.styleable#AndroidManifestApplication_cantSaveState
* @hide
*/
boolean isCantSaveState();
@@ -1146,18 +1204,21 @@
/**
* @see ApplicationInfo#crossProfile
+ * @see R.styleable#AndroidManifestApplication_crossProfile
* @hide
*/
boolean isCrossProfile();
/**
* @see ApplicationInfo#PRIVATE_FLAG_DEFAULT_TO_DEVICE_PROTECTED_STORAGE
+ * @see R.styleable#AndroidManifestApplication_defaultToDeviceProtectedStorage
* @hide
*/
boolean isDefaultToDeviceProtectedStorage();
/**
* @see ApplicationInfo#PRIVATE_FLAG_DIRECT_BOOT_AWARE
+ * @see R.styleable#AndroidManifestApplication_directBootAware
* @hide
*/
boolean isDirectBootAware();
@@ -1177,6 +1238,7 @@
/**
* @see ApplicationInfo#FLAG_EXTRACT_NATIVE_LIBS
+ * @see R.styleable#AndroidManifestApplication_extractNativeLibs
* @hide
*/
boolean isExtractNativeLibs();
@@ -1195,12 +1257,14 @@
/**
* @see ApplicationInfo#FLAG_FULL_BACKUP_ONLY
+ * @see R.styleable#AndroidManifestApplication_fullBackupOnly
* @hide
*/
boolean isFullBackupOnly();
/**
* @see ApplicationInfo#FLAG_IS_GAME
+ * @see R.styleable#AndroidManifestApplication_isGame
* @hide
*/
@Deprecated
@@ -1208,30 +1272,35 @@
/**
* @see ApplicationInfo#FLAG_HAS_CODE
+ * @see R.styleable#AndroidManifestApplication_hasCode
* @hide
*/
boolean isHasCode();
/**
* @see ApplicationInfo#PRIVATE_FLAG_HAS_DOMAIN_URLS
+ * @see R.styleable#AndroidManifestIntentFilter
* @hide
*/
boolean isHasDomainUrls();
/**
* @see ApplicationInfo#PRIVATE_FLAG_HAS_FRAGILE_USER_DATA
+ * @see R.styleable#AndroidManifestApplication_hasFragileUserData
* @hide
*/
boolean isHasFragileUserData();
/**
* @see ApplicationInfo#FLAG_KILL_AFTER_RESTORE
+ * @see R.styleable#AndroidManifestApplication_killAfterRestore
* @hide
*/
boolean isKillAfterRestore();
/**
* @see ApplicationInfo#FLAG_LARGE_HEAP
+ * @see R.styleable#AndroidManifestApplication_largeHeap
* @hide
*/
boolean isLargeHeap();
@@ -1247,6 +1316,7 @@
/**
* @see ApplicationInfo#FLAG_MULTIARCH
+ * @see R.styleable#AndroidManifestApplication_multiArch
* @hide
*/
boolean isMultiArch();
@@ -1278,6 +1348,7 @@
/**
* @see ApplicationInfo#PRIVATE_FLAG_IS_RESOURCE_OVERLAY
* @see ApplicationInfo#isResourceOverlay()
+ * @see R.styleable#AndroidManifestResourceOverlay
* @hide
*/
boolean isOverlay();
@@ -1290,12 +1361,17 @@
/**
* @see ApplicationInfo#PRIVATE_FLAG_PARTIALLY_DIRECT_BOOT_AWARE
+ * @see R.styleable#AndroidManifestActivity_directBootAware
+ * @see R.styleable#AndroidManifestProvider_directBootAware
+ * @see R.styleable#AndroidManifestReceiver_directBootAware
+ * @see R.styleable#AndroidManifestService_directBootAware
* @hide
*/
boolean isPartiallyDirectBootAware();
/**
* @see ApplicationInfo#FLAG_PERSISTENT
+ * @see R.styleable#AndroidManifestApplication_persistent
* @hide
*/
boolean isPersistent();
@@ -1314,18 +1390,21 @@
/**
* @see ApplicationInfo#PRIVATE_FLAG_EXT_PROFILEABLE
+ * @see R.styleable#AndroidManifestProfileable
* @hide
*/
boolean isProfileable();
/**
* @see ApplicationInfo#PRIVATE_FLAG_PROFILEABLE_BY_SHELL
+ * @see R.styleable#AndroidManifestProfileable_shell
* @hide
*/
boolean isProfileableByShell();
/**
* @see ApplicationInfo#PRIVATE_FLAG_REQUEST_LEGACY_EXTERNAL_STORAGE
+ * @see R.styleable#AndroidManifestApplication_requestLegacyExternalStorage
* @hide
*/
boolean isRequestLegacyExternalStorage();
@@ -1358,24 +1437,28 @@
/**
* @see ApplicationInfo#PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION
+ * @see R.styleable#AppWidgetProviderInfo_resizeMode
* @hide
*/
boolean isResizeableActivityViaSdkVersion();
/**
* @see ApplicationInfo#FLAG_RESTORE_ANY_VERSION
+ * @see R.styleable#AndroidManifestApplication_restoreAnyVersion
* @hide
*/
boolean isRestoreAnyVersion();
/**
* True means that this package/app contains an SDK library.
+ * @see R.styleable#AndroidManifestSdkLibrary
* @hide
*/
boolean isSdkLibrary();
/**
* @see ApplicationInfo#PRIVATE_FLAG_STATIC_SHARED_LIBRARY
+ * @see R.styleable#AndroidManifestStaticLibrary
* @hide
*/
boolean isStaticSharedLibrary();
@@ -1417,6 +1500,7 @@
/**
* @see ApplicationInfo#FLAG_SUPPORTS_RTL
+ * @see R.styleable#AndroidManifestApplication_supportsRtl
* @hide
*/
boolean isSupportsRtl();
@@ -1445,6 +1529,7 @@
/**
* @see ApplicationInfo#FLAG_TEST_ONLY
+ * @see R.styleable#AndroidManifestApplication_testOnly
* @hide
*/
boolean isTestOnly();
@@ -1461,6 +1546,7 @@
/**
* @see ApplicationInfo#FLAG_USES_CLEARTEXT_TRAFFIC
+ * @see R.styleable#AndroidManifestApplication_usesCleartextTraffic
* @hide
*/
boolean isUsesCleartextTraffic();
diff --git a/services/core/java/com/android/server/pm/pkg/AndroidPackageSplit.java b/services/core/java/com/android/server/pm/pkg/AndroidPackageSplit.java
index a17ecc3..9024c27 100644
--- a/services/core/java/com/android/server/pm/pkg/AndroidPackageSplit.java
+++ b/services/core/java/com/android/server/pm/pkg/AndroidPackageSplit.java
@@ -18,27 +18,58 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.SystemApi;
import android.processor.immutability.Immutable;
+import com.android.internal.R;
+
import java.util.List;
-/** @hide */
+/**
+ * Representation of the parsed state of a single split APK. Note this includes the base.apk.
+ *
+ * The information here is very minimal, mostly used for loading a specific class, and most
+ * important state is collected across all splits for a package into the parent
+ * {@link AndroidPackage} values.
+ *
+ * @hide
+ */
+@SystemApi(client = SystemApi.Client.SYSTEM_SERVER)
@Immutable
public interface AndroidPackageSplit {
+ /**
+ * @return The unique name given to the split, or null if this is the base.
+ */
@Nullable
String getName();
+ /**
+ * @return Physical location of the split APK on disk, pointing to a single file with the .apk
+ * extension.
+ */
@NonNull
String getPath();
+ /**
+ * @see R.styleable#AndroidManifest_revisionCode
+ */
int getRevisionCode();
+ /**
+ * @see R.styleable#AndroidManifestApplication_hasCode
+ */
boolean isHasCode();
+ /**
+ * @see R.styleable#AndroidManifestApplication_classLoader
+ */
@Nullable
String getClassLoaderName();
+ /**
+ * @see R.styleable#AndroidManifestUsesSplit
+ */
@NonNull
List<AndroidPackageSplit> getDependencies();
}
diff --git a/services/core/java/com/android/server/pm/pkg/AndroidPackageSplitImpl.java b/services/core/java/com/android/server/pm/pkg/AndroidPackageSplitImpl.java
index 9aac8a8..c0f2c25 100644
--- a/services/core/java/com/android/server/pm/pkg/AndroidPackageSplitImpl.java
+++ b/services/core/java/com/android/server/pm/pkg/AndroidPackageSplitImpl.java
@@ -24,6 +24,7 @@
import java.util.List;
import java.util.Objects;
+/** @hide */
public class AndroidPackageSplitImpl implements AndroidPackageSplit {
@Nullable
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 fa1a63f..3c79cdf 100644
--- a/services/core/java/com/android/server/pm/pkg/PackageState.java
+++ b/services/core/java/com/android/server/pm/pkg/PackageState.java
@@ -16,29 +16,45 @@
package com.android.server.pm.pkg;
+import android.annotation.AppIdInt;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.Size;
+import android.annotation.SystemApi;
import android.annotation.UserIdInt;
import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
import android.content.pm.SigningInfo;
import android.os.UserHandle;
import android.processor.immutability.Immutable;
import android.util.SparseArray;
+import com.android.internal.R;
+
import java.io.File;
import java.util.List;
import java.util.Map;
import java.util.Set;
/**
- * The exposed system server process API for package data, shared with the internal
- * PackageManagerService implementation. All returned data is guaranteed immutable.
+ * A wrapper containing device-specific state for an application. It wraps the mostly stateless
+ * {@link AndroidPackage}, available through {@link #getAndroidPackage()}.
+ *
+ * Any fields whose values depend on dynamic state, disk location, enforcement policy,
+ * cross-package dependencies, system/device owner/admin configuration, etc. are placed in this
+ * interface.
+ *
+ * The backing memory is shared with the internal system server and thus there is no cost to
+ * access these objects, unless the public API equivalent {@link PackageInfo} or
+ * {@link ApplicationInfo}.
+ *
+ * This also means the data is immutable and will throw {@link UnsupportedOperationException} if
+ * any collection type is mutated.
*
* @hide
*/
-//@SystemApi(client = SystemApi.Client.SYSTEM_SERVER)
+@SystemApi(client = SystemApi.Client.SYSTEM_SERVER)
@Immutable
public interface PackageState {
@@ -92,9 +108,11 @@
* The non-user-specific UID, or the UID if the user ID is
* {@link android.os.UserHandle#SYSTEM}.
*/
+ @AppIdInt
int getAppId();
/**
+ * @see PackageInfo#packageName
* @see AndroidPackage#getPackageName()
*/
@NonNull
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 a68e59b..366f8e5 100644
--- a/services/core/java/com/android/server/pm/pkg/PackageUserState.java
+++ b/services/core/java/com/android/server/pm/pkg/PackageUserState.java
@@ -18,6 +18,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.SystemApi;
import android.content.pm.PackageManager;
import android.content.pm.overlay.OverlayPaths;
import android.os.UserHandle;
@@ -28,12 +29,19 @@
/**
- * The parent of this class is {@link PackageState}, which handles non-user state, exposing this
- * interface for per-user state.
+ * State for an app for a specific user, such as installed/enabled.
+ *
+ * Querying for a non-existent user does not throw an exception, so it is the responsibility of
+ * the caller to check for valid users if necessary. A default value assuming the app is installed
+ * for the non-existent user will be returned.
+ *
+ * The parent of this class is {@link PackageState}, which handles non-user state and holds one or
+ * many different {@link PackageUserState PackageUserStates}. This class is
+ * accessed through {@link PackageState#getStateForUser(UserHandle)}.
*
* @hide
*/
-//@SystemApi(client = SystemApi.Client.SYSTEM_SERVER)
+@SystemApi(client = SystemApi.Client.SYSTEM_SERVER)
@Immutable
public interface PackageUserState {
diff --git a/services/core/java/com/android/server/pm/pkg/SharedLibrary.java b/services/core/java/com/android/server/pm/pkg/SharedLibrary.java
index 20f05f6..ee793f7 100644
--- a/services/core/java/com/android/server/pm/pkg/SharedLibrary.java
+++ b/services/core/java/com/android/server/pm/pkg/SharedLibrary.java
@@ -18,6 +18,7 @@
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.annotation.SystemApi;
import android.content.pm.SharedLibraryInfo;
import android.content.pm.VersionedPackage;
import android.processor.immutability.Immutable;
@@ -25,9 +26,22 @@
import java.util.List;
/**
+ * Information for a shared library dependency, which is resolved to a real package on the device.
+ *
+ * There are four types of shared libraries:
+ * <table>
+ * <tr><td>Built-in</td> <td>Non-updatable part of OS</td></tr>
+ * <tr><td>Dynamic</td> <td>Updatable backwards-compatible dynamically linked</td></tr>
+ * <tr><td>Static</td> <td>Non-backwards-compatible emulating static linking</td></tr>
+ * <tr><td>SDK</td> <td>Updatable backwards-incompatible dynamically loaded</td></tr>
+ * </table>
+ *
+ * This class is a clone of {@link SharedLibraryInfo} but as an interface with more guaranteed
+ * immutability.
+ *
* @hide
*/
-//@SystemApi(client = SystemApi.Client.SYSTEM_SERVER)
+@SystemApi(client = SystemApi.Client.SYSTEM_SERVER)
@Immutable
public interface SharedLibrary {
@@ -63,6 +77,7 @@
/**
* @see SharedLibraryInfo#getType()
*/
+ @SharedLibraryInfo.Type
int getType();
/**
diff --git a/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java b/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java
index f3ac246..88932b0 100644
--- a/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java
+++ b/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java
@@ -64,6 +64,7 @@
import com.android.server.pm.parsing.pkg.PackageImpl;
import com.android.server.pm.parsing.pkg.ParsedPackage;
import com.android.server.pm.permission.LegacyPermissionDataProvider;
+import com.android.server.pm.pkg.AndroidPackage;
import com.android.server.pm.pkg.PackageUserState;
import com.android.server.pm.pkg.PackageUserStateInternal;
import com.android.server.pm.pkg.SuspendParams;
@@ -657,6 +658,7 @@
null /*usesStaticLibrariesVersions*/,
null /*mimeGroups*/,
UUID.randomUUID());
+ origPkgSetting01.setPkg(mockAndroidPackage(origPkgSetting01));
final PackageSetting testPkgSetting01 = new PackageSetting(origPkgSetting01);
verifySettingCopy(origPkgSetting01, testPkgSetting01);
}
@@ -698,6 +700,7 @@
.build();
origPkgSetting01.modifyUserState(0).putSuspendParams("suspendingPackage1",
new SuspendParams(dialogInfo1, appExtras1, launcherExtras1));
+ origPkgSetting01.setPkg(mockAndroidPackage(origPkgSetting01));
final PackageSetting testPkgSetting01 = new PackageSetting(
PACKAGE_NAME /*pkgName*/,
REAL_PACKAGE_NAME /*realPkgName*/,
@@ -719,6 +722,8 @@
testPkgSetting01.copyPackageSetting(origPkgSetting01, true);
verifySettingCopy(origPkgSetting01, testPkgSetting01);
verifyUserStatesCopy(origPkgSetting01.readUserState(0),
+ origPkgSetting01.getStateForUser(UserHandle.of(0)));
+ verifyUserStatesCopy(origPkgSetting01.readUserState(0),
testPkgSetting01.readUserState(0));
}
@@ -749,7 +754,9 @@
null /*usesStaticLibrariesVersions*/,
null /*mimeGroups*/,
UUID.randomUUID());
+ assertThat(testPkgSetting01.getPrimaryCpuAbi(), is("arm64-v8a"));
assertThat(testPkgSetting01.getPrimaryCpuAbiLegacy(), is("arm64-v8a"));
+ assertThat(testPkgSetting01.getSecondaryCpuAbi(), is("armeabi"));
assertThat(testPkgSetting01.getSecondaryCpuAbiLegacy(), is("armeabi"));
assertThat(testPkgSetting01.getFlags(), is(0));
assertThat(testPkgSetting01.getPrivateFlags(), is(0));
@@ -785,10 +792,14 @@
null /*usesStaticLibrariesVersions*/,
null /*mimeGroups*/,
UUID.randomUUID());
+ assertThat(testPkgSetting01.getPrimaryCpuAbi(), is("arm64-v8a"));
assertThat(testPkgSetting01.getPrimaryCpuAbiLegacy(), is("arm64-v8a"));
+ assertThat(testPkgSetting01.getSecondaryCpuAbi(), is("armeabi"));
assertThat(testPkgSetting01.getSecondaryCpuAbiLegacy(), is("armeabi"));
assertThat(testPkgSetting01.getFlags(), is(ApplicationInfo.FLAG_SYSTEM));
+ assertThat(testPkgSetting01.isSystem(), is(true));
assertThat(testPkgSetting01.getPrivateFlags(), is(ApplicationInfo.PRIVATE_FLAG_PRIVILEGED));
+ assertThat(testPkgSetting01.isPrivileged(), is(true));
final PackageUserState userState = testPkgSetting01.readUserState(0);
verifyUserState(userState, false /*notLaunched*/,
false /*stopped*/, true /*installed*/);
@@ -859,8 +870,12 @@
assertThat(testPkgSetting01.getPath(), is(UPDATED_CODE_PATH));
assertThat(testPkgSetting01.getPackageName(), is(PACKAGE_NAME));
assertThat(testPkgSetting01.getFlags(), is(ApplicationInfo.FLAG_SYSTEM));
+ assertThat(testPkgSetting01.isSystem(), is(true));
assertThat(testPkgSetting01.getPrivateFlags(), is(ApplicationInfo.PRIVATE_FLAG_PRIVILEGED));
+ assertThat(testPkgSetting01.isPrivileged(), is(true));
+ assertThat(testPkgSetting01.getPrimaryCpuAbi(), is("arm64-v8a"));
assertThat(testPkgSetting01.getPrimaryCpuAbiLegacy(), is("arm64-v8a"));
+ assertThat(testPkgSetting01.getSecondaryCpuAbi(), is("armeabi"));
assertThat(testPkgSetting01.getSecondaryCpuAbiLegacy(), is("armeabi"));
// signatures object must be different
assertNotSame(testPkgSetting01.getSignatures(), originalSignatures);
@@ -901,6 +916,7 @@
assertThat(testPkgSetting01.getPackageName(), is(PACKAGE_NAME));
assertThat(testPkgSetting01.getFlags(), is(0));
assertThat(testPkgSetting01.getPrivateFlags(), is(0));
+ assertThat(testPkgSetting01.getPrimaryCpuAbi(), is("x86_64"));
assertThat(testPkgSetting01.getPrimaryCpuAbiLegacy(), is("x86_64"));
assertThat(testPkgSetting01.getSecondaryCpuAbiLegacy(), is("x86"));
assertThat(testPkgSetting01.getVersionCode(), is(INITIAL_VERSION_CODE));
@@ -944,7 +960,9 @@
assertThat(testPkgSetting01.getPackageName(), is(PACKAGE_NAME));
assertThat(testPkgSetting01.getFlags(), is(0));
assertThat(testPkgSetting01.getPrivateFlags(), is(0));
+ assertThat(testPkgSetting01.getPrimaryCpuAbi(), is("x86_64"));
assertThat(testPkgSetting01.getPrimaryCpuAbiLegacy(), is("x86_64"));
+ assertThat(testPkgSetting01.getSecondaryCpuAbi(), is("x86"));
assertThat(testPkgSetting01.getSecondaryCpuAbiLegacy(), is("x86"));
assertThat(testPkgSetting01.getVersionCode(), is(INITIAL_VERSION_CODE));
final PackageUserState userState = testPkgSetting01.readUserState(0);
@@ -987,7 +1005,9 @@
assertThat(testPkgSetting01.getPackageName(), is(PACKAGE_NAME));
assertThat(testPkgSetting01.getFlags(), is(0));
assertThat(testPkgSetting01.getPrivateFlags(), is(0));
+ assertThat(testPkgSetting01.getPrimaryCpuAbi(), is("arm64-v8a"));
assertThat(testPkgSetting01.getPrimaryCpuAbiLegacy(), is("arm64-v8a"));
+ assertThat(testPkgSetting01.getSecondaryCpuAbi(), is("armeabi"));
assertThat(testPkgSetting01.getSecondaryCpuAbiLegacy(), is("armeabi"));
assertNotSame(testPkgSetting01.getSignatures(), disabledSignatures);
assertThat(testPkgSetting01.getVersionCode(), is(UPDATED_VERSION_CODE));
@@ -1207,13 +1227,20 @@
// assertNotSame(origPkgSetting.mOldCodePaths, testPkgSetting.mOldCodePaths);
// assertThat(origPkgSetting.mOldCodePaths, is(not(testPkgSetting.mOldCodePaths)));
assertSame(origPkgSetting.getPkg(), testPkgSetting.getPkg());
+ assertSame(origPkgSetting.getAndroidPackage(), origPkgSetting.getPkg());
+ assertThat(origPkgSetting.getAndroidPackage().getPackageName(),
+ is(origPkgSetting.getPackageName()));
// No equals() method for this object
// assertThat(origPkgSetting.pkg, is(testPkgSetting.pkg));
assertThat(origPkgSetting.getFlags(), is(testPkgSetting.getFlags()));
assertThat(origPkgSetting.getPrivateFlags(), is(testPkgSetting.getPrivateFlags()));
+ assertSame(origPkgSetting.getPrimaryCpuAbi(), testPkgSetting.getPrimaryCpuAbi());
+ assertThat(origPkgSetting.getPrimaryCpuAbi(), is(testPkgSetting.getPrimaryCpuAbi()));
assertSame(origPkgSetting.getPrimaryCpuAbiLegacy(), testPkgSetting.getPrimaryCpuAbiLegacy());
assertThat(origPkgSetting.getPrimaryCpuAbiLegacy(), is(testPkgSetting.getPrimaryCpuAbiLegacy()));
assertThat(origPkgSetting.getRealName(), is(testPkgSetting.getRealName()));
+ assertSame(origPkgSetting.getSecondaryCpuAbi(), testPkgSetting.getSecondaryCpuAbi());
+ assertThat(origPkgSetting.getSecondaryCpuAbi(), is(testPkgSetting.getSecondaryCpuAbi()));
assertSame(origPkgSetting.getSecondaryCpuAbiLegacy(), testPkgSetting.getSecondaryCpuAbiLegacy());
assertThat(origPkgSetting.getSecondaryCpuAbiLegacy(), is(testPkgSetting.getSecondaryCpuAbiLegacy()));
assertSame(origPkgSetting.getSignatures(), testPkgSetting.getSignatures());
@@ -1241,6 +1268,11 @@
origSuspendParams.getAppExtras(), testSuspendParams.getAppExtras()), is(true));
assertThat(BaseBundle.kindofEquals(origSuspendParams.getLauncherExtras(),
testSuspendParams.getLauncherExtras()), is(true));
+ }
+
+ private void verifyUserStatesCopy(PackageUserState origPus,
+ PackageUserState testPus) {
+ assertThat(userStateEquals(origPus, testPus), is(true));
// Verify that disabledComponents and enabledComponents are copied
assertThat(origPus.getDisabledComponents(), is(notNullValue()));
assertThat(origPus.getDisabledComponents().equals(testPus.getDisabledComponents()),
@@ -1573,4 +1605,9 @@
assertThat(ps.getKeySetData().getUpgradeKeySets().length, is(1));
assertThat(ps.getKeySetData().getUpgradeKeySets()[0], is(3L));
}
+
+ @NonNull
+ private AndroidPackage mockAndroidPackage(PackageSetting pkgSetting) {
+ return PackageImpl.forTesting(pkgSetting.getPackageName()).hideAsParsed().hideAsFinal();
+ }
}