summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWinson <chiuwinson@google.com>2019-08-07 10:51:25 -0700
committerWinson <chiuwinson@google.com>2019-09-26 13:27:17 -0700
commit243e7ea14b32747b3d12b1e83625eddb917c5990 (patch)
treea1e7d5f9521bc8bdb7f809558ccd6b5d04ddc0bd
parent4252183449824d77f5c4035e8c12bf504619a5b1 (diff)
Deprecate PackageParser#Package
Replaces PackageParser#Package and it's related structures with ParsingPackage, ParsedPackage, and AndroidPackage. This is a large scoped CL, the first step in an eventual goal to refactor how data is handled in the package parsing and install process. It introduces as few logic changes as necessary. Mostly migrating to interfaces and renaming, moving parsing data calls into 3 separate interfaces that outline the intended flow for parsing. ParsingPackage is built and used during what was PackageParser, now replaced by ApkParseUtils and it's related classes. This is almost exactly what was parsed from the XML/files on disk. ParsedPackage is used when the object exits PackageParser and is adjusted by PackageManagerService to what is considered the final "parsed" state, adjusted from literal values, but consistent given the same APK on disk. This should eventually be moved out of PMS and possibly collapsed into the previous interface entirely. AndroidPackage is the final state of the package after parsing and adjustment has completed and no more mutations should be expected. There are a few exceptions to this, included in AndroidPackageWrite, which will eventually be refactored into PackageSetting or another state class. This marks PackageParser#Package and all the old infrastructure with @Deprecated, as none of them are used internally. All usages were converted, and the legacy Package is only built for un-converted tests and @UnsupportedAppUsage methods. There are numerous TODOs still outstanding, but addressing them in this initial CL would introduce several logic changes. They've been marked with the bug number and will be handled in follow ups. This is being merged with caution thrown to the wind because testing this on devices and in development will be the best way to debug differences introduced by the migration. Getting it merged as early as possible gives the most amount of time to fix regressions. Waiting for tests of all the functionality could take literal years before covering enough to merge this with all regressions verified. Given a sample size of 4 heap dumps and the caveat it was taken very early in the migration, there is a memory overhead of about 200 KB versus the legacy implementation. This should be verified more accurately and addressed in follow ups. This CL also kills child/parent package support, since that's broken already, and difficult to support with the new interface structure. Bug: 135203078 Test: booted an emulator, works generally as expected Specific tests which failed / failed to build were fixed, but because not all tests are currently passing before this change, not all were verified. Change-Id: I4ba050c228e6c60b8f63a9e3347b1f9a57ef794a
-rw-r--r--Android.bp4
-rw-r--r--config/preloaded-classes12
-rw-r--r--core/java/android/content/pm/ActivityInfo.java3
-rw-r--r--core/java/android/content/pm/PackageInfo.java3
-rw-r--r--core/java/android/content/pm/PackageManagerInternal.java33
-rw-r--r--core/java/android/content/pm/PackageParser.java442
-rw-r--r--core/java/android/content/pm/PackageUserState.java60
-rw-r--r--core/java/android/content/pm/SharedLibraryInfo.java21
-rw-r--r--core/java/android/content/pm/dex/DexMetadataHelper.java7
-rw-r--r--core/java/android/content/pm/parsing/AndroidPackage.aidl21
-rw-r--r--core/java/android/content/pm/parsing/AndroidPackage.java468
-rw-r--r--core/java/android/content/pm/parsing/AndroidPackageWrite.java59
-rw-r--r--core/java/android/content/pm/parsing/ApkLiteParseUtils.java428
-rw-r--r--core/java/android/content/pm/parsing/ApkParseUtils.java3197
-rw-r--r--core/java/android/content/pm/parsing/ComponentParseUtils.java3289
-rw-r--r--core/java/android/content/pm/parsing/PackageImpl.java3213
-rw-r--r--core/java/android/content/pm/parsing/PackageInfoUtils.java732
-rw-r--r--core/java/android/content/pm/parsing/ParsedPackage.java155
-rw-r--r--core/java/android/content/pm/parsing/ParsingPackage.java327
-rw-r--r--core/java/android/content/pm/parsing/library/AndroidHidlUpdater.java (renamed from core/java/android/content/pm/AndroidHidlUpdater.java)26
-rw-r--r--core/java/android/content/pm/parsing/library/AndroidTestBaseUpdater.java (renamed from core/java/android/content/pm/AndroidTestBaseUpdater.java)24
-rw-r--r--core/java/android/content/pm/parsing/library/OrgApacheHttpLegacyUpdater.java (renamed from core/java/android/content/pm/OrgApacheHttpLegacyUpdater.java)20
-rw-r--r--core/java/android/content/pm/parsing/library/PackageBackwardCompatibility.java (renamed from core/java/android/content/pm/PackageBackwardCompatibility.java)42
-rw-r--r--core/java/android/content/pm/parsing/library/PackageSharedLibraryUpdater.java (renamed from core/java/android/content/pm/PackageSharedLibraryUpdater.java)48
-rw-r--r--core/java/android/content/pm/parsing/library/SharedLibraryNames.java (renamed from core/java/android/content/pm/SharedLibraryNames.java)4
-rw-r--r--core/java/com/android/internal/content/NativeLibraryHelper.java14
-rw-r--r--core/java/com/android/internal/util/ArrayUtils.java8
-rw-r--r--core/tests/coretests/Android.bp1
-rw-r--r--core/tests/coretests/apks/install_multi_package/Android.bp6
-rw-r--r--core/tests/coretests/apks/install_multi_package/AndroidManifest.xml104
-rw-r--r--core/tests/coretests/apks/install_multi_package/src/com/android/frameworks/coretests/FirstChildTestActivity.java24
-rw-r--r--core/tests/coretests/apks/install_multi_package/src/com/android/frameworks/coretests/FirstChildTestProvider.java57
-rw-r--r--core/tests/coretests/apks/install_multi_package/src/com/android/frameworks/coretests/FirstChildTestReceiver.java57
-rw-r--r--core/tests/coretests/apks/install_multi_package/src/com/android/frameworks/coretests/FirstChildTestService.java30
-rw-r--r--core/tests/coretests/apks/install_multi_package/src/com/android/frameworks/coretests/SecondChildTestActivity.java24
-rw-r--r--core/tests/coretests/apks/install_multi_package/src/com/android/frameworks/coretests/SecondChildTestProvider.java57
-rw-r--r--core/tests/coretests/apks/install_multi_package/src/com/android/frameworks/coretests/SecondChildTestReceiver.java57
-rw-r--r--core/tests/coretests/apks/install_multi_package/src/com/android/frameworks/coretests/SecondChildTestService.java30
-rw-r--r--core/tests/coretests/apks/install_multi_package/src/com/android/frameworks/coretests/TestActivity.java24
-rw-r--r--core/tests/coretests/apks/install_multi_package/src/com/android/frameworks/coretests/TestProvider.java57
-rw-r--r--core/tests/coretests/apks/install_multi_package/src/com/android/frameworks/coretests/TestReceiver.java57
-rw-r--r--core/tests/coretests/apks/install_multi_package/src/com/android/frameworks/coretests/TestService.java30
-rw-r--r--core/tests/coretests/src/android/content/pm/AndroidHidlUpdaterTest.java136
-rw-r--r--core/tests/coretests/src/android/content/pm/AndroidTestBaseUpdaterTest.java110
-rw-r--r--core/tests/coretests/src/android/content/pm/AndroidTestRunnerSplitUpdaterTest.java64
-rw-r--r--core/tests/coretests/src/android/content/pm/OrgApacheHttpLegacyUpdaterTest.java110
-rw-r--r--core/tests/coretests/src/android/content/pm/PackageBuilder.java104
-rw-r--r--core/tests/coretests/src/android/content/pm/PackageParserTest.java140
-rw-r--r--core/tests/coretests/src/android/content/pm/PackageSharedLibraryUpdaterTest.java32
-rw-r--r--core/tests/coretests/src/android/content/pm/RemoveUnnecessaryAndroidTestBaseLibraryTest.java133
-rw-r--r--core/tests/coretests/src/android/content/pm/RemoveUnnecessaryOrgApacheHttpLegacyLibraryTest.java132
-rw-r--r--core/tests/coretests/src/android/content/pm/dex/DexMetadataHelperTest.java31
-rw-r--r--core/tests/coretests/src/android/content/pm/parsing/library/AndroidHidlUpdaterTest.java191
-rw-r--r--core/tests/coretests/src/android/content/pm/parsing/library/AndroidTestBaseUpdaterTest.java152
-rw-r--r--core/tests/coretests/src/android/content/pm/parsing/library/AndroidTestRunnerSplitUpdaterTest.java79
-rw-r--r--core/tests/coretests/src/android/content/pm/parsing/library/OrgApacheHttpLegacyUpdaterTest.java152
-rw-r--r--core/tests/coretests/src/android/content/pm/parsing/library/PackageBackwardCompatibilityTest.java (renamed from core/tests/coretests/src/android/content/pm/PackageBackwardCompatibilityTest.java)85
-rw-r--r--core/tests/coretests/src/android/content/pm/parsing/library/PackageSharedLibraryUpdaterTest.java50
-rw-r--r--core/tests/coretests/src/android/content/pm/parsing/library/RemoveUnnecessaryAndroidTestBaseLibraryTest.java169
-rw-r--r--core/tests/coretests/src/android/content/pm/parsing/library/RemoveUnnecessaryOrgApacheHttpLegacyLibraryTest.java168
-rw-r--r--services/core/java/com/android/server/pm/AppsFilter.java102
-rw-r--r--services/core/java/com/android/server/pm/ComponentResolver.java933
-rw-r--r--services/core/java/com/android/server/pm/InstantAppRegistry.java140
-rw-r--r--services/core/java/com/android/server/pm/InstructionSets.java36
-rw-r--r--services/core/java/com/android/server/pm/IntentFilterVerificationState.java8
-rw-r--r--services/core/java/com/android/server/pm/KeySetManagerService.java74
-rw-r--r--services/core/java/com/android/server/pm/LauncherAppsService.java8
-rw-r--r--services/core/java/com/android/server/pm/OtaDexoptService.java50
-rw-r--r--services/core/java/com/android/server/pm/PackageAbiHelper.java35
-rw-r--r--services/core/java/com/android/server/pm/PackageAbiHelperImpl.java55
-rw-r--r--services/core/java/com/android/server/pm/PackageDexOptimizer.java138
-rw-r--r--services/core/java/com/android/server/pm/PackageInstallerSession.java5
-rw-r--r--services/core/java/com/android/server/pm/PackageKeySetData.java9
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerService.java3505
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerServiceUtils.java72
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerShellCommand.java4
-rw-r--r--services/core/java/com/android/server/pm/PackageSetting.java43
-rw-r--r--services/core/java/com/android/server/pm/PackageSettingBase.java13
-rw-r--r--services/core/java/com/android/server/pm/PackageUsage.java29
-rw-r--r--services/core/java/com/android/server/pm/ParallelPackageParser.java17
-rw-r--r--services/core/java/com/android/server/pm/SELinuxMMAC.java20
-rw-r--r--services/core/java/com/android/server/pm/Settings.java398
-rw-r--r--services/core/java/com/android/server/pm/SharedUserSetting.java24
-rw-r--r--services/core/java/com/android/server/pm/UserSystemPackageInstaller.java19
-rw-r--r--services/core/java/com/android/server/pm/dex/ArtManagerService.java59
-rw-r--r--services/core/java/com/android/server/pm/dex/DexManager.java2
-rw-r--r--services/core/java/com/android/server/pm/dex/DexoptUtils.java38
-rw-r--r--services/core/java/com/android/server/pm/dex/ViewCompiler.java15
-rw-r--r--services/core/java/com/android/server/pm/permission/BasePermission.java190
-rw-r--r--services/core/java/com/android/server/pm/permission/PermissionManagerService.java640
-rw-r--r--services/core/java/com/android/server/pm/permission/PermissionManagerServiceInternal.java26
-rw-r--r--services/core/java/com/android/server/pm/permission/PermissionSettings.java6
-rw-r--r--services/core/java/com/android/server/pm/permission/PermissionsState.java2
-rw-r--r--services/core/java/com/android/server/policy/PermissionPolicyService.java12
-rw-r--r--services/core/java/com/android/server/policy/SoftRestrictedPermissionPolicy.java82
-rw-r--r--services/core/java/com/android/server/role/RoleManagerService.java10
-rw-r--r--services/tests/servicestests/src/com/android/server/pm/AppsFilterTest.java93
-rw-r--r--services/tests/servicestests/src/com/android/server/pm/KeySetManagerServiceTest.java8
-rw-r--r--services/tests/servicestests/src/com/android/server/pm/PackageBuilder.java176
-rw-r--r--services/tests/servicestests/src/com/android/server/pm/PackageManagerServiceTest.java2
-rw-r--r--services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java38
-rw-r--r--services/tests/servicestests/src/com/android/server/pm/PackageParserTest.java577
-rw-r--r--services/tests/servicestests/src/com/android/server/pm/PackageSettingBuilder.java24
-rw-r--r--services/tests/servicestests/src/com/android/server/pm/PackageSignaturesTest.java5
-rw-r--r--services/tests/servicestests/src/com/android/server/pm/ParallelPackageParserTest.java3
-rw-r--r--services/tests/servicestests/src/com/android/server/pm/ScanRequestBuilder.java11
-rw-r--r--services/tests/servicestests/src/com/android/server/pm/ScanTests.java131
-rw-r--r--services/tests/servicestests/src/com/android/server/pm/UserSystemPackageInstallerTest.java11
-rw-r--r--services/tests/servicestests/src/com/android/server/pm/dex/DexoptUtilsTest.java129
109 files changed, 17159 insertions, 6181 deletions
diff --git a/Android.bp b/Android.bp
index 6fc233c94310..69f5595fd69f 100644
--- a/Android.bp
+++ b/Android.bp
@@ -305,7 +305,7 @@ java_defaults {
exclude_srcs: [
// See comment on framework-atb-backward-compatibility module below
- "core/java/android/content/pm/AndroidTestBaseUpdater.java",
+ "core/java/android/content/pm/parsing/library/AndroidTestBaseUpdater.java",
],
sdk_version: "core_platform",
@@ -435,7 +435,7 @@ java_library {
name: "framework-atb-backward-compatibility",
installable: true,
srcs: [
- "core/java/android/content/pm/AndroidTestBaseUpdater.java",
+ "core/java/android/content/pm/parsing/library/AndroidTestBaseUpdater.java",
],
}
diff --git a/config/preloaded-classes b/config/preloaded-classes
index 8d911443ce06..5698dfe8a586 100644
--- a/config/preloaded-classes
+++ b/config/preloaded-classes
@@ -877,7 +877,7 @@ android.content.pm.-$$Lambda$jpya2qgMDDEok2GAoKRDqPM5lIE
android.content.pm.ActivityInfo$1
android.content.pm.ActivityInfo$WindowLayout
android.content.pm.ActivityInfo
-android.content.pm.AndroidHidlUpdater
+android.content.pm.parsing.library.AndroidHidlUpdater
android.content.pm.ApplicationInfo$1
android.content.pm.ApplicationInfo
android.content.pm.BaseParceledListSlice
@@ -921,10 +921,10 @@ android.content.pm.LauncherApps$1
android.content.pm.LauncherApps
android.content.pm.ModuleInfo$1
android.content.pm.ModuleInfo
-android.content.pm.OrgApacheHttpLegacyUpdater
-android.content.pm.PackageBackwardCompatibility$AndroidTestRunnerSplitUpdater
-android.content.pm.PackageBackwardCompatibility$RemoveUnnecessaryAndroidTestBaseLibrary
-android.content.pm.PackageBackwardCompatibility
+android.content.pm.parsing.library.OrgApacheHttpLegacyUpdater
+android.content.pm.parsing.library.PackageBackwardCompatibility$AndroidTestRunnerSplitUpdater
+android.content.pm.parsing.library.PackageBackwardCompatibility$RemoveUnnecessaryAndroidTestBaseLibrary
+android.content.pm.parsing.library.PackageBackwardCompatibility
android.content.pm.PackageInfo$1
android.content.pm.PackageInfo
android.content.pm.PackageInstaller$Session
@@ -959,7 +959,7 @@ android.content.pm.PackageParser$SigningDetails$1
android.content.pm.PackageParser$SigningDetails
android.content.pm.PackageParser$SplitNameComparator
android.content.pm.PackageParser
-android.content.pm.PackageSharedLibraryUpdater
+android.content.pm.parsing.library.PackageSharedLibraryUpdater
android.content.pm.PackageStats$1
android.content.pm.PackageStats
android.content.pm.PackageUserState
diff --git a/core/java/android/content/pm/ActivityInfo.java b/core/java/android/content/pm/ActivityInfo.java
index 415c2428405f..29f243f76905 100644
--- a/core/java/android/content/pm/ActivityInfo.java
+++ b/core/java/android/content/pm/ActivityInfo.java
@@ -1379,7 +1379,8 @@ public class ActivityInfo extends ComponentInfo implements Parcelable {
this.minHeight = minHeight;
}
- WindowLayout(Parcel source) {
+ /** @hide */
+ public WindowLayout(Parcel source) {
width = source.readInt();
widthFraction = source.readFloat();
height = source.readInt();
diff --git a/core/java/android/content/pm/PackageInfo.java b/core/java/android/content/pm/PackageInfo.java
index d6fb28f694fd..aa0002df2c3a 100644
--- a/core/java/android/content/pm/PackageInfo.java
+++ b/core/java/android/content/pm/PackageInfo.java
@@ -373,8 +373,9 @@ public class PackageInfo implements Parcelable {
/**
* Whether the overlay is static, meaning it cannot be enabled/disabled at runtime.
+ * @hide
*/
- boolean mOverlayIsStatic;
+ public boolean mOverlayIsStatic;
/**
* The user-visible SDK version (ex. 26) of the framework against which the application claims
diff --git a/core/java/android/content/pm/PackageManagerInternal.java b/core/java/android/content/pm/PackageManagerInternal.java
index f28b85ccbedc..746549814c8d 100644
--- a/core/java/android/content/pm/PackageManagerInternal.java
+++ b/core/java/android/content/pm/PackageManagerInternal.java
@@ -28,6 +28,8 @@ import android.content.pm.PackageManager.ApplicationInfoFlags;
import android.content.pm.PackageManager.ComponentInfoFlags;
import android.content.pm.PackageManager.PackageInfoFlags;
import android.content.pm.PackageManager.ResolveInfoFlags;
+import android.content.pm.parsing.AndroidPackage;
+import android.content.pm.parsing.ComponentParseUtils;
import android.os.Bundle;
import android.os.PersistableBundle;
import android.util.ArraySet;
@@ -315,7 +317,7 @@ public abstract class PackageManagerInternal {
* @param installed the new installed state
* @return true if the installed state changed as a result
*/
- public abstract boolean setInstalled(PackageParser.Package pkg,
+ public abstract boolean setInstalled(AndroidPackage pkg,
@UserIdInt int userId, boolean installed);
/**
@@ -394,7 +396,7 @@ public abstract class PackageManagerInternal {
* Returns whether or not the given package represents a legacy system application released
* prior to runtime permissions.
*/
- public abstract boolean isLegacySystemApp(PackageParser.Package pkg);
+ public abstract boolean isLegacySystemApp(AndroidPackage pkg);
/**
* Get all overlay packages for a user.
@@ -486,13 +488,17 @@ public abstract class PackageManagerInternal {
/**
* Returns a package object for the given package name.
*/
- public abstract @Nullable PackageParser.Package getPackage(@NonNull String packageName);
+ public abstract @Nullable AndroidPackage getPackage(@NonNull String packageName);
+
+ // TODO(b/135203078): PackageSetting can't be referenced directly. Should move to a server side
+ // internal PM which is aware of PS.
+ public abstract @Nullable Object getPackageSetting(String packageName);
/**
* Returns a package for the given UID. If the UID is part of a shared user ID, one
* of the packages will be chosen to be returned.
*/
- public abstract @Nullable PackageParser.Package getPackage(int uid);
+ public abstract @Nullable AndroidPackage getPackage(int uid);
/**
* Returns a list without a change observer.
@@ -523,17 +529,19 @@ public abstract class PackageManagerInternal {
*/
public abstract void removePackageListObserver(@NonNull PackageListObserver observer);
+ // TODO(b/135203078): PackageSetting can't be referenced directly
/**
* Returns a package object for the disabled system package name.
*/
- public abstract @Nullable PackageParser.Package getDisabledSystemPackage(
- @NonNull String packageName);
+ public abstract @Nullable Object getDisabledSystemPackage(@NonNull String packageName);
/**
* Returns the package name for the disabled system package.
*
* This is equivalent to
- * {@link #getDisabledSystemPackage(String)}.{@link PackageParser.Package#packageName}
+ * {@link #getDisabledSystemPackage(String)}
+ * .{@link com.android.server.pm.PackageSetting#pkg}
+ * .{@link AndroidPackage#getPackageName()}
*/
public abstract @Nullable String getDisabledSystemPackageName(@NonNull String packageName);
@@ -567,7 +575,7 @@ public abstract class PackageManagerInternal {
* @see #canAccessInstantApps
*/
public abstract boolean filterAppAccess(
- @NonNull PackageParser.Package pkg, int callingUid, int userId);
+ @NonNull AndroidPackage pkg, int callingUid, int userId);
/**
* Returns whether or not access to the application should be filtered.
@@ -641,7 +649,8 @@ public abstract class PackageManagerInternal {
throws IOException;
/** Returns {@code true} if the specified component is enabled and matches the given flags. */
- public abstract boolean isEnabledAndMatches(@NonNull ComponentInfo info, int flags, int userId);
+ public abstract boolean isEnabledAndMatches(
+ @NonNull ComponentParseUtils.ParsedComponent component, int flags, int userId);
/** Returns {@code true} if the given user requires extra badging for icons. */
public abstract boolean userNeedsBadging(int userId);
@@ -652,14 +661,14 @@ public abstract class PackageManagerInternal {
*
* @param actionLocked action to be performed
*/
- public abstract void forEachPackage(Consumer<PackageParser.Package> actionLocked);
+ public abstract void forEachPackage(Consumer<AndroidPackage> actionLocked);
/**
* Perform the given action for each installed package for a user.
* Note that packages lock will be held while performin the actions.
*/
public abstract void forEachInstalledPackage(
- @NonNull Consumer<PackageParser.Package> actionLocked, @UserIdInt int userId);
+ @NonNull Consumer<AndroidPackage> actionLocked, @UserIdInt int userId);
/** Returns the list of enabled components */
public abstract ArraySet<String> getEnabledComponents(String packageName, int userId);
@@ -793,7 +802,7 @@ public abstract class PackageManagerInternal {
* Otherwise, {@code false}.
*/
public abstract boolean isCallerInstallerOfRecord(
- @NonNull PackageParser.Package pkg, int callingUid);
+ @NonNull AndroidPackage pkg, int callingUid);
/** Returns whether or not default runtime permissions are granted for the given user */
public abstract boolean areDefaultRuntimePermissionsGranted(@UserIdInt int userId);
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 0b157fa3bb1e..2ded5dcae0d9 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -57,6 +57,12 @@ import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageParserCacheHelper.ReadHelper;
import android.content.pm.PackageParserCacheHelper.WriteHelper;
+import android.content.pm.parsing.AndroidPackage;
+import android.content.pm.parsing.ApkParseUtils;
+import android.content.pm.parsing.ComponentParseUtils;
+import android.content.pm.parsing.PackageImpl;
+import android.content.pm.parsing.PackageInfoUtils;
+import android.content.pm.parsing.ParsedPackage;
import android.content.pm.permission.SplitPermissionInfoParcelable;
import android.content.pm.split.DefaultSplitAssetLoader;
import android.content.pm.split.SplitAssetDependencyLoader;
@@ -67,7 +73,6 @@ import android.content.res.Configuration;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.content.res.XmlResourceParser;
-import android.net.Uri;
import android.os.Build;
import android.os.Bundle;
import android.os.FileUtils;
@@ -156,21 +161,22 @@ import java.util.concurrent.atomic.AtomicInteger;
* @hide
*/
public class PackageParser {
- private static final boolean DEBUG_JAR = false;
- private static final boolean DEBUG_PARSER = false;
- private static final boolean DEBUG_BACKUP = false;
- private static final boolean LOG_PARSE_TIMINGS = Build.IS_DEBUGGABLE;
- private static final int LOG_PARSE_TIMINGS_THRESHOLD_MS = 100;
+
+ public static final boolean DEBUG_JAR = false;
+ public static final boolean DEBUG_PARSER = false;
+ public static final boolean DEBUG_BACKUP = false;
+ public static final boolean LOG_PARSE_TIMINGS = Build.IS_DEBUGGABLE;
+ public static final int LOG_PARSE_TIMINGS_THRESHOLD_MS = 100;
private static final String PROPERTY_CHILD_PACKAGES_ENABLED =
"persist.sys.child_packages_enabled";
- private static final boolean MULTI_PACKAGE_APK_ENABLED = Build.IS_DEBUGGABLE &&
+ public static final boolean MULTI_PACKAGE_APK_ENABLED = Build.IS_DEBUGGABLE &&
SystemProperties.getBoolean(PROPERTY_CHILD_PACKAGES_ENABLED, false);
- private static final float DEFAULT_PRE_O_MAX_ASPECT_RATIO = 1.86f;
- private static final float DEFAULT_PRE_Q_MIN_ASPECT_RATIO = 1.333f;
- private static final float DEFAULT_PRE_Q_MIN_ASPECT_RATIO_WATCH = 1f;
+ public static final float DEFAULT_PRE_O_MAX_ASPECT_RATIO = 1.86f;
+ public static final float DEFAULT_PRE_Q_MIN_ASPECT_RATIO = 1.333f;
+ public static final float DEFAULT_PRE_Q_MIN_ASPECT_RATIO_WATCH = 1f;
private static final int DEFAULT_MIN_SDK_VERSION = 1;
private static final int DEFAULT_TARGET_SDK_VERSION = 0;
@@ -182,37 +188,38 @@ public class PackageParser {
public static final String ANDROID_MANIFEST_FILENAME = "AndroidManifest.xml";
/** Path prefix for apps on expanded storage */
- private static final String MNT_EXPAND = "/mnt/expand/";
-
- private static final String TAG_MANIFEST = "manifest";
- private static final String TAG_APPLICATION = "application";
- private static final String TAG_PACKAGE_VERIFIER = "package-verifier";
- private static final String TAG_OVERLAY = "overlay";
- private static final String TAG_KEY_SETS = "key-sets";
- private static final String TAG_PERMISSION_GROUP = "permission-group";
- private static final String TAG_PERMISSION = "permission";
- private static final String TAG_PERMISSION_TREE = "permission-tree";
- private static final String TAG_USES_PERMISSION = "uses-permission";
- private static final String TAG_USES_PERMISSION_SDK_M = "uses-permission-sdk-m";
- private static final String TAG_USES_PERMISSION_SDK_23 = "uses-permission-sdk-23";
- private static final String TAG_USES_CONFIGURATION = "uses-configuration";
- private static final String TAG_USES_FEATURE = "uses-feature";
- private static final String TAG_FEATURE_GROUP = "feature-group";
- private static final String TAG_USES_SDK = "uses-sdk";
- private static final String TAG_SUPPORT_SCREENS = "supports-screens";
- private static final String TAG_PROTECTED_BROADCAST = "protected-broadcast";
- private static final String TAG_INSTRUMENTATION = "instrumentation";
- private static final String TAG_ORIGINAL_PACKAGE = "original-package";
- private static final String TAG_ADOPT_PERMISSIONS = "adopt-permissions";
- private static final String TAG_USES_GL_TEXTURE = "uses-gl-texture";
- private static final String TAG_COMPATIBLE_SCREENS = "compatible-screens";
- private static final String TAG_SUPPORTS_INPUT = "supports-input";
- private static final String TAG_EAT_COMMENT = "eat-comment";
- private static final String TAG_PACKAGE = "package";
- private static final String TAG_RESTRICT_UPDATE = "restrict-update";
- private static final String TAG_USES_SPLIT = "uses-split";
-
- private static final String METADATA_MAX_ASPECT_RATIO = "android.max_aspect";
+ public static final String MNT_EXPAND = "/mnt/expand/";
+
+ public static final String TAG_ADOPT_PERMISSIONS = "adopt-permissions";
+ public static final String TAG_APPLICATION = "application";
+ public static final String TAG_COMPATIBLE_SCREENS = "compatible-screens";
+ public static final String TAG_EAT_COMMENT = "eat-comment";
+ public static final String TAG_FEATURE_GROUP = "feature-group";
+ public static final String TAG_INSTRUMENTATION = "instrumentation";
+ public static final String TAG_KEY_SETS = "key-sets";
+ public static final String TAG_MANIFEST = "manifest";
+ public static final String TAG_ORIGINAL_PACKAGE = "original-package";
+ public static final String TAG_OVERLAY = "overlay";
+ public static final String TAG_PACKAGE = "package";
+ public static final String TAG_PACKAGE_VERIFIER = "package-verifier";
+ public static final String TAG_PERMISSION = "permission";
+ public static final String TAG_PERMISSION_GROUP = "permission-group";
+ public static final String TAG_PERMISSION_TREE = "permission-tree";
+ public static final String TAG_PROTECTED_BROADCAST = "protected-broadcast";
+ public static final String TAG_QUERIES = "queries";
+ public static final String TAG_RESTRICT_UPDATE = "restrict-update";
+ public static final String TAG_SUPPORT_SCREENS = "supports-screens";
+ public static final String TAG_SUPPORTS_INPUT = "supports-input";
+ public static final String TAG_USES_CONFIGURATION = "uses-configuration";
+ public static final String TAG_USES_FEATURE = "uses-feature";
+ public static final String TAG_USES_GL_TEXTURE = "uses-gl-texture";
+ public static final String TAG_USES_PERMISSION = "uses-permission";
+ public static final String TAG_USES_PERMISSION_SDK_23 = "uses-permission-sdk-23";
+ public static final String TAG_USES_PERMISSION_SDK_M = "uses-permission-sdk-m";
+ public static final String TAG_USES_SDK = "uses-sdk";
+ public static final String TAG_USES_SPLIT = "uses-split";
+
+ public static final String METADATA_MAX_ASPECT_RATIO = "android.max_aspect";
/**
* Bit mask of all the valid bits that can be set in recreateOnConfigChanges.
@@ -222,25 +229,25 @@ public class PackageParser {
ActivityInfo.CONFIG_MCC | ActivityInfo.CONFIG_MNC;
// These are the tags supported by child packages
- private static final Set<String> CHILD_PACKAGE_TAGS = new ArraySet<>();
+ public static final Set<String> CHILD_PACKAGE_TAGS = new ArraySet<>();
static {
CHILD_PACKAGE_TAGS.add(TAG_APPLICATION);
- CHILD_PACKAGE_TAGS.add(TAG_USES_PERMISSION);
- CHILD_PACKAGE_TAGS.add(TAG_USES_PERMISSION_SDK_M);
- CHILD_PACKAGE_TAGS.add(TAG_USES_PERMISSION_SDK_23);
- CHILD_PACKAGE_TAGS.add(TAG_USES_CONFIGURATION);
- CHILD_PACKAGE_TAGS.add(TAG_USES_FEATURE);
+ CHILD_PACKAGE_TAGS.add(TAG_COMPATIBLE_SCREENS);
+ CHILD_PACKAGE_TAGS.add(TAG_EAT_COMMENT);
CHILD_PACKAGE_TAGS.add(TAG_FEATURE_GROUP);
- CHILD_PACKAGE_TAGS.add(TAG_USES_SDK);
- CHILD_PACKAGE_TAGS.add(TAG_SUPPORT_SCREENS);
CHILD_PACKAGE_TAGS.add(TAG_INSTRUMENTATION);
- CHILD_PACKAGE_TAGS.add(TAG_USES_GL_TEXTURE);
- CHILD_PACKAGE_TAGS.add(TAG_COMPATIBLE_SCREENS);
+ CHILD_PACKAGE_TAGS.add(TAG_SUPPORT_SCREENS);
CHILD_PACKAGE_TAGS.add(TAG_SUPPORTS_INPUT);
- CHILD_PACKAGE_TAGS.add(TAG_EAT_COMMENT);
+ CHILD_PACKAGE_TAGS.add(TAG_USES_CONFIGURATION);
+ CHILD_PACKAGE_TAGS.add(TAG_USES_FEATURE);
+ CHILD_PACKAGE_TAGS.add(TAG_USES_GL_TEXTURE);
+ CHILD_PACKAGE_TAGS.add(TAG_USES_PERMISSION);
+ CHILD_PACKAGE_TAGS.add(TAG_USES_PERMISSION_SDK_23);
+ CHILD_PACKAGE_TAGS.add(TAG_USES_PERMISSION_SDK_M);
+ CHILD_PACKAGE_TAGS.add(TAG_USES_SDK);
}
- private static final boolean LOG_UNSAFE_BROADCASTS = false;
+ public static final boolean LOG_UNSAFE_BROADCASTS = false;
/**
* Total number of packages that were read from the cache. We use it only for logging.
@@ -248,7 +255,7 @@ public class PackageParser {
public static final AtomicInteger sCachedPackageReadCount = new AtomicInteger();
// Set of broadcast actions that are safe for manifest receivers
- private static final Set<String> SAFE_BROADCASTS = new ArraySet<>();
+ public static final Set<String> SAFE_BROADCASTS = new ArraySet<>();
static {
SAFE_BROADCASTS.add(Intent.ACTION_BOOT_COMPLETED);
}
@@ -295,26 +302,29 @@ public class PackageParser {
* @deprecated callers should move to explicitly passing around source path.
*/
@Deprecated
- private String mArchiveSourcePath;
+ public String mArchiveSourcePath;
- private String[] mSeparateProcesses;
+ public String[] mSeparateProcesses;
private boolean mOnlyCoreApps;
private DisplayMetrics mMetrics;
@UnsupportedAppUsage
- private Callback mCallback;
+ public Callback mCallback;
private File mCacheDir;
- private static final int SDK_VERSION = Build.VERSION.SDK_INT;
- private static final String[] SDK_CODENAMES = Build.VERSION.ACTIVE_CODENAMES;
+ public static final int SDK_VERSION = Build.VERSION.SDK_INT;
+ public static final String[] SDK_CODENAMES = Build.VERSION.ACTIVE_CODENAMES;
+
+ public int mParseError = PackageManager.INSTALL_SUCCEEDED;
- private int mParseError = PackageManager.INSTALL_SUCCEEDED;
+ public ThreadLocal<ApkParseUtils.ParseResult> mSharedResult
+ = ThreadLocal.withInitial(ApkParseUtils.ParseResult::new);
- private static boolean sCompatibilityModeEnabled = true;
- private static boolean sUseRoundIcon = false;
+ public static boolean sCompatibilityModeEnabled = true;
+ public static boolean sUseRoundIcon = false;
- private static final int PARSE_DEFAULT_INSTALL_LOCATION =
+ public static final int PARSE_DEFAULT_INSTALL_LOCATION =
PackageInfo.INSTALL_LOCATION_UNSPECIFIED;
- private static final int PARSE_DEFAULT_TARGET_SANDBOX = 1;
+ public static final int PARSE_DEFAULT_TARGET_SANDBOX = 1;
static class ParsePackageItemArgs {
final Package owner;
@@ -536,7 +546,7 @@ public class PackageParser {
* the DTD. Otherwise, we try to get as much from the package as we
* can without failing. This should normally be set to false, to
* support extensions to the DTD in future versions. */
- private static final boolean RIGID_PARSER = false;
+ public static final boolean RIGID_PARSER = false;
private static final String TAG = "PackageParser";
@@ -897,7 +907,7 @@ public class PackageParser {
@Retention(RetentionPolicy.SOURCE)
public @interface ParseFlags {}
- private static final Comparator<String> sSplitNameComparator = new SplitNameComparator();
+ public static final Comparator<String> sSplitNameComparator = new SplitNameComparator();
/**
* Used to sort a set of APKs based on their split names, always placing the
@@ -1043,7 +1053,7 @@ public class PackageParser {
* and unique split names.
* <p>
* Note that this <em>does not</em> perform signature verification; that
- * must be done separately in {@link #collectCertificates(Package, int)}.
+ * must be done separately in {@link ApkParseUtils#collectCertificates(AndroidPackage, boolean)}.
*
* If {@code useCaches} is true, the package parser might return a cached
* result from a previous parse of the same {@code packageFile} with the same
@@ -1051,21 +1061,54 @@ public class PackageParser {
* has changed since the last parse, it's up to callers to do so.
*
* @see #parsePackageLite(File, int)
+ * @deprecated use {@link #parseParsedPackage(File, int, boolean)}
*/
@UnsupportedAppUsage
+ @Deprecated
public Package parsePackage(File packageFile, int flags, boolean useCaches)
throws PackageParserException {
- Package parsed = useCaches ? getCachedResult(packageFile, flags) : null;
+ if (packageFile.isDirectory()) {
+ return parseClusterPackage(packageFile, flags);
+ } else {
+ return parseMonolithicPackage(packageFile, flags);
+ }
+ }
+
+ /**
+ * Equivalent to {@link #parsePackage(File, int, boolean)} with {@code useCaches == false}.
+ * @deprecated use {@link #parseParsedPackage(File, int, boolean)}
+ */
+ @UnsupportedAppUsage
+ @Deprecated
+ public Package parsePackage(File packageFile, int flags) throws PackageParserException {
+ return parsePackage(packageFile, flags, false /* useCaches */);
+ }
+
+ /**
+ * Updated method which returns {@link ParsedPackage}, the current representation of a
+ * package parsed from disk.
+ *
+ * @see #parsePackage(File, int, boolean)
+ */
+ public ParsedPackage parseParsedPackage(File packageFile, int flags, boolean useCaches)
+ throws PackageParserException {
+ ParsedPackage parsed = useCaches ? getCachedResult(packageFile, flags) : null;
if (parsed != null) {
return parsed;
}
long parseTime = LOG_PARSE_TIMINGS ? SystemClock.uptimeMillis() : 0;
- if (packageFile.isDirectory()) {
- parsed = parseClusterPackage(packageFile, flags);
- } else {
- parsed = parseMonolithicPackage(packageFile, flags);
- }
+ ApkParseUtils.ParseInput parseInput = mSharedResult.get().reset();
+ parsed = ApkParseUtils.parsePackage(
+ parseInput,
+ mSeparateProcesses,
+ mCallback,
+ mMetrics,
+ mOnlyCoreApps,
+ packageFile,
+ flags
+ )
+ .hideAsParsed();
long cacheTime = LOG_PARSE_TIMINGS ? SystemClock.uptimeMillis() : 0;
cacheResult(packageFile, flags, parsed);
@@ -1077,19 +1120,12 @@ public class PackageParser {
+ "ms, update_cache=" + cacheTime + " ms");
}
}
- return parsed;
- }
- /**
- * Equivalent to {@link #parsePackage(File, int, boolean)} with {@code useCaches == false}.
- */
- @UnsupportedAppUsage
- public Package parsePackage(File packageFile, int flags) throws PackageParserException {
- return parsePackage(packageFile, flags, false /* useCaches */);
+ return parsed;
}
/**
- * Returns the cache key for a specificied {@code packageFile} and {@code flags}.
+ * Returns the cache key for a specified {@code packageFile} and {@code flags}.
*/
private String getCacheKey(File packageFile, int flags) {
StringBuilder sb = new StringBuilder(packageFile.getName());
@@ -1100,13 +1136,13 @@ public class PackageParser {
}
@VisibleForTesting
- protected Package fromCacheEntry(byte[] bytes) {
+ protected ParsedPackage fromCacheEntry(byte[] bytes) {
return fromCacheEntryStatic(bytes);
}
/** static version of {@link #fromCacheEntry} for unit tests. */
@VisibleForTesting
- public static Package fromCacheEntryStatic(byte[] bytes) {
+ public static ParsedPackage fromCacheEntryStatic(byte[] bytes) {
final Parcel p = Parcel.obtain();
p.unmarshall(bytes, 0, bytes.length);
p.setDataPosition(0);
@@ -1114,7 +1150,8 @@ public class PackageParser {
final ReadHelper helper = new ReadHelper(p);
helper.startAndInstall();
- PackageParser.Package pkg = new PackageParser.Package(p);
+ // TODO(b/135203078): Hide PackageImpl constructor?
+ ParsedPackage pkg = new PackageImpl(p);
p.recycle();
@@ -1124,14 +1161,14 @@ public class PackageParser {
}
@VisibleForTesting
- protected byte[] toCacheEntry(Package pkg) {
+ protected byte[] toCacheEntry(ParsedPackage pkg) {
return toCacheEntryStatic(pkg);
}
/** static version of {@link #toCacheEntry} for unit tests. */
@VisibleForTesting
- public static byte[] toCacheEntryStatic(Package pkg) {
+ public static byte[] toCacheEntryStatic(ParsedPackage pkg) {
final Parcel p = Parcel.obtain();
final WriteHelper helper = new WriteHelper(p);
@@ -1180,7 +1217,7 @@ public class PackageParser {
* Returns the cached parse result for {@code packageFile} for parse flags {@code flags},
* or {@code null} if no cached result exists.
*/
- private Package getCachedResult(File packageFile, int flags) {
+ public ParsedPackage getCachedResult(File packageFile, int flags) {
if (mCacheDir == null) {
return null;
}
@@ -1195,9 +1232,9 @@ public class PackageParser {
}
final byte[] bytes = IoUtils.readFileAsByteArray(cacheFile.getAbsolutePath());
- Package p = fromCacheEntry(bytes);
+ ParsedPackage p = fromCacheEntry(bytes);
if (mCallback != null) {
- String[] overlayApks = mCallback.getOverlayApks(p.packageName);
+ String[] overlayApks = mCallback.getOverlayApks(p.getPackageName());
if (overlayApks != null && overlayApks.length > 0) {
for (String overlayApk : overlayApks) {
// If a static RRO is updated, return null.
@@ -1221,7 +1258,7 @@ public class PackageParser {
/**
* Caches the parse result for {@code packageFile} with flags {@code flags}.
*/
- private void cacheResult(File packageFile, int flags, Package parsed) {
+ public void cacheResult(File packageFile, int flags, ParsedPackage parsed) {
if (mCacheDir == null) {
return;
}
@@ -1260,7 +1297,8 @@ public class PackageParser {
* split names.
* <p>
* Note that this <em>does not</em> perform signature verification; that
- * must be done separately in {@link #collectCertificates(Package, int)}.
+ * must be done separately in
+ * {@link ApkParseUtils#collectCertificates(AndroidPackage, boolean)}.
*/
private Package parseClusterPackage(File packageDir, int flags) throws PackageParserException {
final PackageLite lite = parseClusterPackageLite(packageDir, 0);
@@ -1324,10 +1362,11 @@ public class PackageParser {
* Parse the given APK file, treating it as as a single monolithic package.
* <p>
* Note that this <em>does not</em> perform signature verification; that
- * must be done separately in {@link #collectCertificates(Package, int)}.
+ * must be done separately in
+ * {@link ApkParseUtils#collectCertificates(AndroidPackage, boolean)}.
*
* @deprecated external callers should move to
- * {@link #parsePackage(File, int)}. Eventually this method will
+ * {@link #parseParsedPackage(File, int, boolean)}. Eventually this method will
* be marked private.
*/
@Deprecated
@@ -1527,8 +1566,11 @@ public class PackageParser {
* Collect certificates from all the APKs described in the given package,
* populating {@link Package#mSigningDetails}. Also asserts that all APK
* contents are signed correctly and consistently.
+ *
+ * @deprecated use {@link ApkParseUtils#collectCertificates(AndroidPackage, boolean)}
*/
@UnsupportedAppUsage
+ @Deprecated
public static void collectCertificates(Package pkg, boolean skipVerify)
throws PackageParserException {
collectCertificatesInternal(pkg, skipVerify);
@@ -1707,7 +1749,7 @@ public class PackageParser {
? null : "must have at least one '.' separator";
}
- private static Pair<String, String> parsePackageSplitNames(XmlPullParser parser,
+ public static Pair<String, String> parsePackageSplitNames(XmlPullParser parser,
AttributeSet attrs) throws IOException, XmlPullParserException,
PackageParserException {
@@ -2487,8 +2529,6 @@ public class PackageParser {
mParseError = PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
return null;
- } else if (tagName.equals("queries")) {
- parseQueries(pkg, res, parser, flags, outError);
} else {
Slog.w(TAG, "Unknown element under <manifest>: " + parser.getName()
+ " at " + mArchiveSourcePath + " "
@@ -2958,7 +2998,7 @@ public class PackageParser {
return true;
}
- private static String buildClassName(String pkg, CharSequence clsSeq,
+ public static String buildClassName(String pkg, CharSequence clsSeq,
String[] outError) {
if (clsSeq == null || clsSeq.length() <= 0) {
outError[0] = "Empty class name in package " + pkg;
@@ -3006,7 +3046,7 @@ public class PackageParser {
return proc;
}
- private static String buildProcessName(String pkg, String defProc,
+ public static String buildProcessName(String pkg, String defProc,
CharSequence procSeq, int flags, String[] separateProcesses,
String[] outError) {
if ((flags&PARSE_IGNORE_PROCESSES) != 0 && !"system".equals(procSeq)) {
@@ -3026,7 +3066,7 @@ public class PackageParser {
return TextUtils.safeIntern(buildCompoundName(pkg, procSeq, "process", outError));
}
- private static String buildTaskAffinityName(String pkg, String defProc,
+ public static String buildTaskAffinityName(String pkg, String defProc,
CharSequence procSeq, String[] outError) {
if (procSeq == null) {
return defProc;
@@ -3588,9 +3628,6 @@ public class PackageParser {
owner.mRequiredAccountType = requiredAccountType;
}
- owner.mForceQueryable =
- sa.getBoolean(R.styleable.AndroidManifestApplication_forceQueryable, false);
-
if (sa.getBoolean(
com.android.internal.R.styleable.AndroidManifestApplication_debuggable,
false)) {
@@ -4052,89 +4089,6 @@ public class PackageParser {
return true;
}
- private boolean parseQueries(Package owner, Resources res, XmlResourceParser parser, int flags,
- String[] outError)
- throws IOException, XmlPullParserException {
-
- final int outerDepth = parser.getDepth();
- int type;
- while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
- && (type != XmlPullParser.END_TAG
- || parser.getDepth() > outerDepth)) {
- if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
- continue;
- }
- if (parser.getName().equals("intent")) {
- QueriesIntentInfo intentInfo = new QueriesIntentInfo();
- if (!parseIntent(res, parser, true /*allowGlobs*/, true /*allowAutoVerify*/,
- intentInfo, outError)) {
- return false;
- }
-
- Uri data = null;
- String dataType = null;
- String host = "";
- final int numActions = intentInfo.countActions();
- final int numSchemes = intentInfo.countDataSchemes();
- final int numTypes = intentInfo.countDataTypes();
- final int numHosts = intentInfo.getHosts().length;
- if ((numSchemes == 0 && numTypes == 0 && numActions == 0)) {
- outError[0] = "intent tags must contain either an action or data.";
- return false;
- }
- if (numActions > 1) {
- outError[0] = "intent tag may have at most one action.";
- return false;
- }
- if (numTypes > 1) {
- outError[0] = "intent tag may have at most one data type.";
- return false;
- }
- if (numSchemes > 1) {
- outError[0] = "intent tag may have at most one data scheme.";
- return false;
- }
- if (numHosts > 1) {
- outError[0] = "intent tag may have at most one data host.";
- return false;
- }
- Intent intent = new Intent();
- for (int i = 0, max = intentInfo.countCategories(); i < max; i++) {
- intent.addCategory(intentInfo.getCategory(i));
- }
- if (numHosts == 1) {
- host = intentInfo.getHosts()[0];
- }
- if (numSchemes == 1) {
- data = new Uri.Builder()
- .scheme(intentInfo.getDataScheme(0))
- .authority(host)
- .build();
- }
- if (numTypes == 1) {
- dataType = intentInfo.getDataType(0);
- }
- intent.setDataAndType(data, dataType);
- if (numActions == 1) {
- intent.setAction(intentInfo.getAction(0));
- }
- owner.mQueriesIntents = ArrayUtils.add(owner.mQueriesIntents, intent);
- } else if (parser.getName().equals("package")) {
- final TypedArray sa = res.obtainAttributes(parser,
- com.android.internal.R.styleable.AndroidManifestQueriesPackage);
- final String packageName =
- sa.getString(R.styleable.AndroidManifestQueriesPackage_name);
- if (TextUtils.isEmpty(packageName)) {
- outError[0] = "Package name is missing from package tag.";
- return false;
- }
- owner.mQueriesPackages =
- ArrayUtils.add(owner.mQueriesPackages, packageName.intern());
- }
- }
- return true;
- }
-
/**
* Check if one of the IntentFilter as both actions DEFAULT / VIEW and a HTTP/HTTPS data URI
*/
@@ -5846,7 +5800,7 @@ public class PackageParser {
return null;
}
- private static final String ANDROID_RESOURCES
+ public static final String ANDROID_RESOURCES
= "http://schemas.android.com/apk/res/android";
private boolean parseIntent(Resources res, XmlResourceParser parser, boolean allowGlobs,
@@ -6541,7 +6495,10 @@ public class PackageParser {
/**
* Representation of a full package parsed from APK files on disk. A package
* consists of a single base APK, and zero or more split APKs.
+ *
+ * @deprecated use an {@link AndroidPackage}
*/
+ @Deprecated
public final static class Package implements Parcelable {
@UnsupportedAppUsage
@@ -6649,9 +6606,6 @@ public class PackageParser {
// The major version code declared for this package.
public int mVersionCodeMajor;
- // Whether the package declares that it should be queryable by all normal apps on device.
- public boolean mForceQueryable;
-
// Return long containing mVersionCode and mVersionCodeMajor.
public long getLongVersionCode() {
return PackageInfo.composeLongVersionCode(mVersionCodeMajor, mVersionCode);
@@ -6757,9 +6711,6 @@ public class PackageParser {
/** Whether or not the package is a stub and must be replaced by the full version. */
public boolean isStub;
- public ArrayList<String> mQueriesPackages;
- public ArrayList<Intent> mQueriesIntents;
-
@UnsupportedAppUsage
public Package(String packageName) {
this.packageName = packageName;
@@ -7263,9 +7214,6 @@ public class PackageParser {
use32bitAbi = (dest.readInt() == 1);
restrictUpdateHash = dest.createByteArray();
visibleToInstantApps = dest.readInt() == 1;
- mForceQueryable = dest.readBoolean();
- mQueriesIntents = dest.createTypedArrayList(Intent.CREATOR);
- mQueriesPackages = dest.createStringArrayList();
}
private static void internStringArrayList(List<String> list) {
@@ -7281,7 +7229,7 @@ public class PackageParser {
* Sets the package owner and the the {@code applicationInfo} for every component
* owner by this package.
*/
- private void fixupOwner(List<? extends Component<?>> list) {
+ public void fixupOwner(List<? extends Component<?>> list) {
if (list != null) {
for (Component<?> c : list) {
c.owner = this;
@@ -7391,12 +7339,8 @@ public class PackageParser {
dest.writeInt(use32bitAbi ? 1 : 0);
dest.writeByteArray(restrictUpdateHash);
dest.writeInt(visibleToInstantApps ? 1 : 0);
- dest.writeBoolean(mForceQueryable);
- dest.writeTypedList(mQueriesIntents);
- dest.writeList(mQueriesPackages);
}
-
/**
* Writes the keyset mapping to the provided package. {@code null} mappings are permitted.
*/
@@ -7468,6 +7412,10 @@ public class PackageParser {
};
}
+ /**
+ * @deprecated use a {@link ComponentParseUtils.ParsedComponent}
+ */
+ @Deprecated
public static abstract class Component<II extends IntentInfo> {
@UnsupportedAppUsage
public final ArrayList<II> intents;
@@ -7648,6 +7596,10 @@ public class PackageParser {
}
}
+ /**
+ * @deprecated use {@link ComponentParseUtils.ParsedPermission}
+ */
+ @Deprecated
public final static class Permission extends Component<IntentInfo> implements Parcelable {
@UnsupportedAppUsage
public final PermissionInfo info;
@@ -7722,6 +7674,10 @@ public class PackageParser {
};
}
+ /**
+ * @deprecated use {@link ComponentParseUtils.ParsedPermissionGroup}
+ */
+ @Deprecated
public final static class PermissionGroup extends Component<IntentInfo> implements Parcelable {
@UnsupportedAppUsage
public final PermissionGroupInfo info;
@@ -7821,7 +7777,12 @@ public class PackageParser {
return false;
}
+ /**
+ * @deprecated use {@link PackageInfoUtils#generateApplicationInfo(
+ * AndroidPackage, int, PackageUserState, int)}
+ */
@UnsupportedAppUsage
+ @Deprecated
public static ApplicationInfo generateApplicationInfo(Package p, int flags,
PackageUserState state) {
return generateApplicationInfo(p, flags, state, UserHandle.getCallingUserId());
@@ -7878,7 +7839,12 @@ public class PackageParser {
ai.icon = (sUseRoundIcon && ai.roundIconRes != 0) ? ai.roundIconRes : ai.iconRes;
}
+ /**
+ * @deprecated use {@link PackageInfoUtils#generateApplicationInfo(
+ * AndroidPackage, int, PackageUserState, int)}
+ */
@UnsupportedAppUsage
+ @Deprecated
public static ApplicationInfo generateApplicationInfo(Package p, int flags,
PackageUserState state, int userId) {
if (p == null) return null;
@@ -7918,6 +7884,11 @@ public class PackageParser {
return ai;
}
+ /**
+ * @deprecated use {@link PackageInfoUtils#generateApplicationInfo(
+ * AndroidPackage, int, PackageUserState, int)}
+ */
+ @Deprecated
public static ApplicationInfo generateApplicationInfo(ApplicationInfo ai, int flags,
PackageUserState state, int userId) {
if (ai == null) return null;
@@ -7937,7 +7908,12 @@ public class PackageParser {
return ai;
}
+ /**
+ * @deprecated use {@link PackageInfoUtils#generatePermissionInfo(
+ * ComponentParseUtils.ParsedPermission, int)}
+ */
@UnsupportedAppUsage
+ @Deprecated
public static final PermissionInfo generatePermissionInfo(
Permission p, int flags) {
if (p == null) return null;
@@ -7949,7 +7925,12 @@ public class PackageParser {
return pi;
}
+ /**
+ * @deprecated use {@link PackageInfoUtils#generatePermissionGroupInfo(
+ * ComponentParseUtils.ParsedPermissionGroup, int)}
+ */
@UnsupportedAppUsage
+ @Deprecated
public static final PermissionGroupInfo generatePermissionGroupInfo(
PermissionGroup pg, int flags) {
if (pg == null) return null;
@@ -7961,6 +7942,10 @@ public class PackageParser {
return pgi;
}
+ /**
+ * @deprecated use {@link ComponentParseUtils.ParsedActivity}
+ */
+ @Deprecated
public final static class Activity extends Component<ActivityIntentInfo> implements Parcelable {
@UnsupportedAppUsage
public final ActivityInfo info;
@@ -8076,7 +8061,12 @@ public class PackageParser {
};
}
+ /**
+ * @deprecated use {@link PackageInfoUtils#generateActivityInfo(
+ * AndroidPackage, ComponentParseUtils.ParsedActivity, int, PackageUserState, int)}
+ */
@UnsupportedAppUsage
+ @Deprecated
public static final ActivityInfo generateActivityInfo(Activity a, int flags,
PackageUserState state, int userId) {
if (a == null) return null;
@@ -8094,6 +8084,11 @@ public class PackageParser {
return ai;
}
+ /**
+ * @deprecated use {@link PackageInfoUtils#generateActivityInfo(
+ * AndroidPackage, ComponentParseUtils.ParsedActivity, int, PackageUserState, int)}
+ */
+ @Deprecated
public static final ActivityInfo generateActivityInfo(ActivityInfo ai, int flags,
PackageUserState state, int userId) {
if (ai == null) return null;
@@ -8107,6 +8102,10 @@ public class PackageParser {
return ai;
}
+ /**
+ * @deprecated use {@link ComponentParseUtils.ParsedService}
+ */
+ @Deprecated
public final static class Service extends Component<ServiceIntentInfo> implements Parcelable {
@UnsupportedAppUsage
public final ServiceInfo info;
@@ -8168,7 +8167,12 @@ public class PackageParser {
};
}
+ /**
+ * @deprecated use {@link PackageInfoUtils#generateServiceInfo(
+ * AndroidPackage, ComponentParseUtils.ParsedService, int, PackageUserState, int)}
+ */
@UnsupportedAppUsage
+ @Deprecated
public static final ServiceInfo generateServiceInfo(Service s, int flags,
PackageUserState state, int userId) {
if (s == null) return null;
@@ -8186,6 +8190,10 @@ public class PackageParser {
return si;
}
+ /**
+ * @deprecated use {@link ComponentParseUtils.ParsedProvider}
+ */
+ @Deprecated
public final static class Provider extends Component<ProviderIntentInfo> implements Parcelable {
@UnsupportedAppUsage
public final ProviderInfo info;
@@ -8266,7 +8274,12 @@ public class PackageParser {
};
}
+ /**
+ * @deprecated use {@link PackageInfoUtils#generateProviderInfo(
+ * AndroidPackage, ComponentParseUtils.ParsedProvider, int, PackageUserState, int)}
+ */
@UnsupportedAppUsage
+ @Deprecated
public static final ProviderInfo generateProviderInfo(Provider p, int flags,
PackageUserState state, int userId) {
if (p == null) return null;
@@ -8289,6 +8302,10 @@ public class PackageParser {
return pi;
}
+ /**
+ * @deprecated use {@link ComponentParseUtils.ParsedInstrumentation}
+ */
+ @Deprecated
public final static class Instrumentation extends Component<IntentInfo> implements
Parcelable {
@UnsupportedAppUsage
@@ -8349,7 +8366,12 @@ public class PackageParser {
};
}
+ /**
+ * @deprecated use {@link PackageInfoUtils#generateInstrumentationInfo(
+ * ComponentParseUtils.ParsedInstrumentation, int)}
+ */
@UnsupportedAppUsage
+ @Deprecated
public static final InstrumentationInfo generateInstrumentationInfo(
Instrumentation i, int flags) {
if (i == null) return null;
@@ -8361,6 +8383,10 @@ public class PackageParser {
return ii;
}
+ /**
+ * @deprecated use {@link ComponentParseUtils.ParsedIntentInfo}
+ */
+ @Deprecated
public static abstract class IntentInfo extends IntentFilter {
@UnsupportedAppUsage
public boolean hasDefault;
@@ -8404,8 +8430,10 @@ public class PackageParser {
}
}
- public static final class QueriesIntentInfo extends IntentInfo {}
-
+ /**
+ * @deprecated use {@link ComponentParseUtils.ParsedActivityIntentInfo}
+ */
+ @Deprecated
public final static class ActivityIntentInfo extends IntentInfo {
@UnsupportedAppUsage
public Activity activity;
@@ -8429,6 +8457,10 @@ public class PackageParser {
}
}
+ /**
+ * @deprecated use {@link ComponentParseUtils.ParsedServiceIntentInfo}
+ */
+ @Deprecated
public final static class ServiceIntentInfo extends IntentInfo {
@UnsupportedAppUsage
public Service service;
@@ -8452,6 +8484,10 @@ public class PackageParser {
}
}
+ /**
+ * @deprecated use {@link ComponentParseUtils.ParsedProviderIntentInfo}
+ */
+ @Deprecated
public static final class ProviderIntentInfo extends IntentInfo {
@UnsupportedAppUsage
public Provider provider;
diff --git a/core/java/android/content/pm/PackageUserState.java b/core/java/android/content/pm/PackageUserState.java
index 249b6919fc28..b271ccdad041 100644
--- a/core/java/android/content/pm/PackageUserState.java
+++ b/core/java/android/content/pm/PackageUserState.java
@@ -28,6 +28,7 @@ import static android.content.pm.PackageManager.MATCH_DISABLED_UNTIL_USED_COMPON
import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
import android.annotation.UnsupportedAppUsage;
+import android.content.pm.parsing.ComponentParseUtils;
import android.os.BaseBundle;
import android.os.Debug;
import android.os.PersistableBundle;
@@ -127,6 +128,18 @@ public class PackageUserState {
&& (!this.hidden || matchUninstalled));
}
+ public boolean isMatch(ComponentInfo componentInfo, int flags) {
+ return isMatch(componentInfo.applicationInfo.isSystemApp(),
+ componentInfo.applicationInfo.enabled, componentInfo.enabled,
+ componentInfo.directBootAware, componentInfo.name, flags);
+ }
+
+ public boolean isMatch(boolean isSystem, boolean isPackageEnabled,
+ ComponentParseUtils.ParsedComponent component, int flags) {
+ return isMatch(isSystem, isPackageEnabled, component.isEnabled(),
+ component.isDirectBootAware(), component.getName(), flags);
+ }
+
/**
* Test if the given component is considered installed, enabled and a match
* for the given flags.
@@ -135,28 +148,33 @@ public class PackageUserState {
* Expects at least one of {@link PackageManager#MATCH_DIRECT_BOOT_AWARE} and
* {@link PackageManager#MATCH_DIRECT_BOOT_UNAWARE} are specified in {@code flags}.
* </p>
+ *
*/
- public boolean isMatch(ComponentInfo componentInfo, int flags) {
- final boolean isSystemApp = componentInfo.applicationInfo.isSystemApp();
+ public boolean isMatch(boolean isSystem, boolean isPackageEnabled, boolean isComponentEnabled,
+ boolean isComponentDirectBootAware, String componentName, int flags) {
final boolean matchUninstalled = (flags & PackageManager.MATCH_KNOWN_PACKAGES) != 0;
- if (!isAvailable(flags)
- && !(isSystemApp && matchUninstalled)) return reportIfDebug(false, flags);
- if (!isEnabled(componentInfo, flags)) return reportIfDebug(false, flags);
+ if (!isAvailable(flags) && !(isSystem && matchUninstalled)) {
+ return reportIfDebug(false, flags);
+ }
+
+ if (!isEnabled(isPackageEnabled, isComponentEnabled, componentName, flags)) {
+ return reportIfDebug(false, flags);
+ }
if ((flags & MATCH_SYSTEM_ONLY) != 0) {
- if (!isSystemApp) {
+ if (!isSystem) {
return reportIfDebug(false, flags);
}
}
final boolean matchesUnaware = ((flags & MATCH_DIRECT_BOOT_UNAWARE) != 0)
- && !componentInfo.directBootAware;
+ && !isComponentDirectBootAware;
final boolean matchesAware = ((flags & MATCH_DIRECT_BOOT_AWARE) != 0)
- && componentInfo.directBootAware;
+ && isComponentDirectBootAware;
return reportIfDebug(matchesUnaware || matchesAware, flags);
}
- private boolean reportIfDebug(boolean result, int flags) {
+ public boolean reportIfDebug(boolean result, int flags) {
if (DEBUG && !result) {
Slog.i(LOG_TAG, "No match!; flags: "
+ DebugUtils.flagsToString(PackageManager.class, "MATCH_", flags) + " "
@@ -165,10 +183,22 @@ public class PackageUserState {
return result;
}
+ public boolean isEnabled(ComponentInfo componentInfo, int flags) {
+ return isEnabled(componentInfo.applicationInfo.enabled, componentInfo.enabled,
+ componentInfo.name, flags);
+ }
+
+ public boolean isEnabled(boolean isPackageEnabled,
+ ComponentParseUtils.ParsedComponent parsedComponent, int flags) {
+ return isEnabled(isPackageEnabled, parsedComponent.isEnabled(), parsedComponent.getName(),
+ flags);
+ }
+
/**
* Test if the given component is considered enabled.
*/
- public boolean isEnabled(ComponentInfo componentInfo, int flags) {
+ public boolean isEnabled(boolean isPackageEnabled, boolean isComponentEnabled,
+ String componentName, int flags) {
if ((flags & MATCH_DISABLED_COMPONENTS) != 0) {
return true;
}
@@ -183,24 +213,26 @@ public class PackageUserState {
if ((flags & MATCH_DISABLED_UNTIL_USED_COMPONENTS) == 0) {
return false;
}
+ // fallthrough
case COMPONENT_ENABLED_STATE_DEFAULT:
- if (!componentInfo.applicationInfo.enabled) {
+ if (!isPackageEnabled) {
return false;
}
+ // fallthrough
case COMPONENT_ENABLED_STATE_ENABLED:
break;
}
// Check if component has explicit state before falling through to
// the manifest default
- if (ArrayUtils.contains(this.enabledComponents, componentInfo.name)) {
+ if (ArrayUtils.contains(this.enabledComponents, componentName)) {
return true;
}
- if (ArrayUtils.contains(this.disabledComponents, componentInfo.name)) {
+ if (ArrayUtils.contains(this.disabledComponents, componentName)) {
return false;
}
- return componentInfo.enabled;
+ return isComponentEnabled;
}
@Override
diff --git a/core/java/android/content/pm/SharedLibraryInfo.java b/core/java/android/content/pm/SharedLibraryInfo.java
index 3488cc30892c..2863b268e795 100644
--- a/core/java/android/content/pm/SharedLibraryInfo.java
+++ b/core/java/android/content/pm/SharedLibraryInfo.java
@@ -20,6 +20,7 @@ import android.annotation.IntDef;
import android.annotation.IntRange;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.content.pm.parsing.AndroidPackage;
import android.os.Parcel;
import android.os.Parcelable;
@@ -38,20 +39,24 @@ import java.util.List;
public final class SharedLibraryInfo implements Parcelable {
/** @hide */
- public static SharedLibraryInfo createForStatic(PackageParser.Package pkg) {
- return new SharedLibraryInfo(null, pkg.packageName, pkg.getAllCodePaths(),
- pkg.staticSharedLibName,
- pkg.staticSharedLibVersion,
+ public static SharedLibraryInfo createForStatic(AndroidPackage pkg) {
+ return new SharedLibraryInfo(null, pkg.getPackageName(),
+ pkg.makeListAllCodePaths(),
+ pkg.getStaticSharedLibName(),
+ pkg.getStaticSharedLibVersion(),
TYPE_STATIC,
- new VersionedPackage(pkg.manifestPackageName, pkg.getLongVersionCode()),
+ new VersionedPackage(pkg.getManifestPackageName(),
+ pkg.getLongVersionCode()),
null, null);
}
/** @hide */
- public static SharedLibraryInfo createForDynamic(PackageParser.Package pkg, String name) {
- return new SharedLibraryInfo(null, pkg.packageName, pkg.getAllCodePaths(), name,
+ public static SharedLibraryInfo createForDynamic(AndroidPackage pkg, String name) {
+ return new SharedLibraryInfo(null, pkg.getPackageName(),
+ pkg.makeListAllCodePaths(), name,
(long) VERSION_UNDEFINED,
- TYPE_DYNAMIC, new VersionedPackage(pkg.packageName, pkg.getLongVersionCode()),
+ TYPE_DYNAMIC, new VersionedPackage(pkg.getPackageName(),
+ pkg.getLongVersionCode()),
null, null);
}
diff --git a/core/java/android/content/pm/dex/DexMetadataHelper.java b/core/java/android/content/pm/dex/DexMetadataHelper.java
index 5d10b8826b00..4cd201fbe538 100644
--- a/core/java/android/content/pm/dex/DexMetadataHelper.java
+++ b/core/java/android/content/pm/dex/DexMetadataHelper.java
@@ -22,6 +22,7 @@ import static android.content.pm.PackageParser.APK_FILE_EXTENSION;
import android.content.pm.PackageParser;
import android.content.pm.PackageParser.PackageLite;
import android.content.pm.PackageParser.PackageParserException;
+import android.content.pm.parsing.AndroidPackage;
import android.util.ArrayMap;
import android.util.jar.StrictJarFile;
@@ -86,8 +87,8 @@ public class DexMetadataHelper {
*
* NOTE: involves I/O checks.
*/
- public static Map<String, String> getPackageDexMetadata(PackageParser.Package pkg) {
- return buildPackageApkToDexMetadataMap(pkg.getAllCodePaths());
+ public static Map<String, String> getPackageDexMetadata(AndroidPackage pkg) {
+ return buildPackageApkToDexMetadataMap(pkg.makeListAllCodePaths());
}
/**
@@ -160,7 +161,7 @@ public class DexMetadataHelper {
*
* @throws PackageParserException in case of errors.
*/
- public static void validatePackageDexMetadata(PackageParser.Package pkg)
+ public static void validatePackageDexMetadata(AndroidPackage pkg)
throws PackageParserException {
Collection<String> apkToDexMetadataList = getPackageDexMetadata(pkg).values();
for (String dexMetadata : apkToDexMetadataList) {
diff --git a/core/java/android/content/pm/parsing/AndroidPackage.aidl b/core/java/android/content/pm/parsing/AndroidPackage.aidl
new file mode 100644
index 000000000000..ab3cf7cb8c65
--- /dev/null
+++ b/core/java/android/content/pm/parsing/AndroidPackage.aidl
@@ -0,0 +1,21 @@
+/*
+**
+** Copyright 2019, 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 android.content.pm.parsing;
+
+/* @hide */
+parcelable AndroidPackage;
diff --git a/core/java/android/content/pm/parsing/AndroidPackage.java b/core/java/android/content/pm/parsing/AndroidPackage.java
new file mode 100644
index 000000000000..bef984df4c10
--- /dev/null
+++ b/core/java/android/content/pm/parsing/AndroidPackage.java
@@ -0,0 +1,468 @@
+/*
+ * Copyright (C) 2019 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 android.content.pm.parsing;
+
+import android.annotation.Nullable;
+import android.content.Intent;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.ConfigurationInfo;
+import android.content.pm.FeatureGroupInfo;
+import android.content.pm.FeatureInfo;
+import android.content.pm.PackageParser;
+import android.content.pm.SharedLibraryInfo;
+import android.content.pm.parsing.ComponentParseUtils.ParsedActivity;
+import android.content.pm.parsing.ComponentParseUtils.ParsedActivityIntentInfo;
+import android.content.pm.parsing.ComponentParseUtils.ParsedInstrumentation;
+import android.content.pm.parsing.ComponentParseUtils.ParsedPermission;
+import android.content.pm.parsing.ComponentParseUtils.ParsedPermissionGroup;
+import android.content.pm.parsing.ComponentParseUtils.ParsedProvider;
+import android.content.pm.parsing.ComponentParseUtils.ParsedService;
+import android.os.Bundle;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.util.ArraySet;
+import android.util.SparseArray;
+
+import java.security.PublicKey;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.UUID;
+
+/**
+ * The last state of a package during parsing/install before it is available in
+ * {@link com.android.server.pm.PackageManagerService#mPackages}.
+ *
+ * It is the responsibility of the caller to understand what data is available at what step of the
+ * parsing or install process.
+ *
+ * TODO(b/135203078): Nullability annotations
+ * TODO(b/135203078): Remove get/setAppInfo differences
+ *
+ * @hide
+ */
+public interface AndroidPackage extends Parcelable {
+
+ /**
+ * This will eventually be removed. Avoid calling this at all costs.
+ */
+ @Deprecated
+ AndroidPackageWrite mutate();
+
+ boolean canHaveOatDir();
+
+ boolean cantSaveState();
+
+ List<String> getAdoptPermissions();
+
+ List<String> getAllCodePaths();
+
+ List<String> getAllCodePathsExcludingResourceOnly();
+
+ String getAppComponentFactory();
+
+ /**
+ * TODO(b/135203078): Use non-AppInfo method
+ * @deprecated use {@link #getClassLoaderName()}
+ */
+ @Deprecated
+ String getAppInfoClassLoaderName();
+
+ /**
+ * TODO(b/135203078): Use non-AppInfo method
+ * @deprecated use {@link #getCodePath()}
+ */
+ @Deprecated
+ String getAppInfoCodePath();
+
+ /**
+ * TODO(b/135203078): Use non-AppInfo method
+ * @deprecated use {@link #getName()}
+ */
+ @Deprecated
+ String getAppInfoName();
+
+ /**
+ * TODO(b/135203078): Use non-AppInfo method
+ * @deprecated use {@link #getPackageName()}
+ */
+ @Deprecated
+ String getAppInfoPackageName();
+
+ /**
+ * TODO(b/135203078): Use non-AppInfo method
+ * @deprecated use {@link #getProcessName()}
+ */
+ @Deprecated
+ String getAppInfoProcessName();
+
+ /**
+ * TODO(b/135203078): Use non-AppInfo method
+ * @deprecated use {@link #getCodePath()}
+ */
+ @Deprecated
+ String getAppInfoResourcePath();
+
+ Bundle getAppMetaData();
+
+ /**
+ * TODO(b/135203078): Use non-AppInfo method
+ * @deprecated use {@link #getVolumeUuid()}
+ */
+ @Deprecated
+ String getApplicationInfoVolumeUuid();
+
+ String getBackupAgentName();
+
+ int getBanner();
+
+ String getBaseCodePath();
+
+ int getBaseRevisionCode();
+
+ int getCategory();
+
+ String getClassLoaderName();
+
+ String getClassName();
+
+ String getCodePath();
+
+ int getCompatibleWidthLimitDp();
+
+ int getCompileSdkVersion();
+
+ String getCompileSdkVersionCodeName();
+
+ @Nullable
+ List<ConfigurationInfo> getConfigPreferences();
+
+ String getCpuAbiOverride();
+
+ String getCredentialProtectedDataDir();
+
+ String getDataDir();
+
+ int getDescriptionRes();
+
+ String getDeviceProtectedDataDir();
+
+ List<FeatureGroupInfo> getFeatureGroups();
+
+ int getFlags();
+
+ int getFullBackupContent();
+
+ int getHiddenApiEnforcementPolicy();
+
+ int getIcon();
+
+ int getIconRes();
+
+ List<String> getImplicitPermissions();
+
+ int getInstallLocation();
+
+ Map<String, ArraySet<PublicKey>> getKeySetMapping();
+
+ int getLabelRes();
+
+ int getLargestWidthLimitDp();
+
+ long[] getLastPackageUsageTimeInMills();
+
+ long getLatestForegroundPackageUseTimeInMills();
+
+ long getLatestPackageUseTimeInMills();
+
+ List<String> getLibraryNames();
+
+ int getLogo();
+
+ long getLongVersionCode();
+
+ String getManageSpaceActivityName();
+
+ String getManifestPackageName();
+
+ float getMaxAspectRatio();
+
+ Bundle getMetaData(); // TODO(b/135203078): Make all the Bundles immutable
+
+ float getMinAspectRatio();
+
+ int getMinSdkVersion();
+
+ String getName();
+
+ String getNativeLibraryDir();
+
+ String getNativeLibraryRootDir();
+
+ int getNetworkSecurityConfigRes();
+
+ CharSequence getNonLocalizedLabel();
+
+ @Nullable
+ List<String> getOriginalPackages();
+
+ String getOverlayCategory();
+
+ int getOverlayPriority();
+
+ String getOverlayTarget();
+
+ String getOverlayTargetName();
+
+ // TODO(b/135203078): Does this and getAppInfoPackageName have to be separate methods?
+ // The refactor makes them the same value with no known consequences, so should be redundant.
+ String getPackageName();
+
+ @Nullable
+ List<ParsedActivity> getActivities();
+
+ @Nullable
+ List<ParsedInstrumentation> getInstrumentations();
+
+ @Nullable
+ List<ParsedPermissionGroup> getPermissionGroups();
+
+ @Nullable
+ List<ParsedPermission> getPermissions();
+
+ @Nullable
+ List<ParsedProvider> getProviders();
+
+ @Nullable
+ List<ParsedActivity> getReceivers();
+
+ @Nullable
+ List<ParsedService> getServices();
+
+ String getPermission();
+
+ @Nullable
+ List<ParsedActivityIntentInfo> getPreferredActivityFilters();
+
+ int getPreferredOrder();
+
+ String getPrimaryCpuAbi();
+
+ int getPrivateFlags();
+
+ String getProcessName();
+
+ @Nullable
+ List<String> getProtectedBroadcasts();
+
+ String getPublicSourceDir();
+
+ List<Intent> getQueriesIntents();
+
+ List<String> getQueriesPackages();
+
+ String getRealPackage();
+
+ // TODO(b/135203078): Rename to getRequiredFeatures? Somewhat ambigious whether "Req" is
+ // required or requested.
+ @Nullable
+ List<FeatureInfo> getReqFeatures();
+
+ List<String> getRequestedPermissions();
+
+ String getRequiredAccountType();
+
+ int getRequiresSmallestWidthDp();
+
+ byte[] getRestrictUpdateHash();
+
+ String getRestrictedAccountType();
+
+ int getRoundIconRes();
+
+ String getScanPublicSourceDir();
+
+ String getScanSourceDir();
+
+ String getSeInfo();
+
+ String getSeInfoUser();
+
+ String getSecondaryCpuAbi();
+
+ String getSecondaryNativeLibraryDir();
+
+ String getSharedUserId();
+
+ int getSharedUserLabel();
+
+ PackageParser.SigningDetails getSigningDetails();
+
+ String[] getSplitClassLoaderNames();
+
+ @Nullable
+ String[] getSplitCodePaths();
+
+ @Nullable
+ SparseArray<int[]> getSplitDependencies();
+
+ int[] getSplitFlags();
+
+ String[] getSplitNames();
+
+ String[] getSplitPublicSourceDirs();
+
+ int[] getSplitRevisionCodes();
+
+ String getStaticSharedLibName();
+
+ long getStaticSharedLibVersion();
+
+ // TODO(b/135203078): Return String directly
+ UUID getStorageUuid();
+
+ int getTargetSandboxVersion();
+
+ int getTargetSdkVersion();
+
+ String getTaskAffinity();
+
+ int getTheme();
+
+ int getUiOptions();
+
+ int getUid();
+
+ Set<String> getUpgradeKeySets();
+
+ @Nullable
+ List<String> getUsesLibraries();
+
+ @Nullable
+ String[] getUsesLibraryFiles();
+
+ List<SharedLibraryInfo> getUsesLibraryInfos();
+
+ @Nullable
+ List<String> getUsesOptionalLibraries();
+
+ @Nullable
+ List<String> getUsesStaticLibraries();
+
+ @Nullable
+ String[][] getUsesStaticLibrariesCertDigests();
+
+ @Nullable
+ long[] getUsesStaticLibrariesVersions();
+
+ int getVersionCode();
+
+ int getVersionCodeMajor();
+
+ String getVersionName();
+
+ String getVolumeUuid();
+
+ String getZygotePreloadName();
+
+ boolean hasComponentClassName(String className);
+
+ // App Info
+
+ boolean hasRequestedLegacyExternalStorage();
+
+ boolean isBaseHardwareAccelerated();
+
+ boolean isCoreApp();
+
+ boolean isDefaultToDeviceProtectedStorage();
+
+ boolean isDirectBootAware();
+
+ boolean isEmbeddedDexUsed();
+
+ boolean isEnabled();
+
+ boolean isEncryptionAware();
+
+ boolean isExternal();
+
+ boolean isForceQueryable();
+
+ boolean isForwardLocked();
+
+ boolean isHiddenUntilInstalled();
+
+ boolean isInstantApp();
+
+ boolean isInternal();
+
+ boolean isLibrary();
+
+ // TODO(b/135203078): Should probably be in a utility class
+ boolean isMatch(int flags);
+
+ boolean isNativeLibraryRootRequiresIsa();
+
+ boolean isOem();
+
+ boolean isOverlayIsStatic();
+
+ boolean isPrivileged();
+
+ boolean isProduct();
+
+ boolean isProfileableByShell();
+
+ boolean isRequiredForAllUsers();
+
+ boolean isStaticSharedLibrary();
+
+ boolean isStub();
+
+ boolean isSystem(); // TODO(b/135203078): Collapse with isSystemApp, should be exactly the same.
+
+ boolean isSystemApp();
+
+ boolean isSystemExt();
+
+ boolean isUpdatedSystemApp();
+
+ boolean isUse32BitAbi();
+
+ boolean isVendor();
+
+ boolean isVisibleToInstantApps();
+
+ List<String> makeListAllCodePaths(); // TODO(b/135203078): Collapse with getAllCodePaths
+
+ boolean requestsIsolatedSplitLoading();
+
+ ApplicationInfo toAppInfo();
+
+ Creator<PackageImpl> CREATOR = new Creator<PackageImpl>() {
+ @Override
+ public PackageImpl createFromParcel(Parcel source) {
+ return new PackageImpl(source);
+ }
+
+ @Override
+ public PackageImpl[] newArray(int size) {
+ return new PackageImpl[size];
+ }
+ };
+}
diff --git a/core/java/android/content/pm/parsing/AndroidPackageWrite.java b/core/java/android/content/pm/parsing/AndroidPackageWrite.java
new file mode 100644
index 000000000000..b7595d2dd710
--- /dev/null
+++ b/core/java/android/content/pm/parsing/AndroidPackageWrite.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2019 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 android.content.pm.parsing;
+
+import android.annotation.Nullable;
+import android.content.pm.PackageParser;
+import android.content.pm.SharedLibraryInfo;
+
+import java.util.List;
+
+/**
+ * Contains remaining mutable fields after package parsing has completed.
+ *
+ * Most are state that can probably be tracked outside of the AndroidPackage object. New methods
+ * should never be added to this interface.
+ *
+ * TODO(b/135203078): Remove entirely
+ *
+ * @deprecated the eventual goal is that the object returned from parsing represents exactly what
+ * was parsed from the APK, and so further mutation should be disallowed,
+ * with any state being stored in another class
+ *
+ * @hide
+ */
+@Deprecated
+public interface AndroidPackageWrite extends AndroidPackage {
+
+ AndroidPackageWrite setUsesLibraryFiles(@Nullable String[] usesLibraryFiles);
+
+ // TODO(b/135203078): Remove or use a non-system wide representation of the shared libraries;
+ // this doesn't represent what was parsed from the APK
+ AndroidPackageWrite setUsesLibraryInfos(@Nullable List<SharedLibraryInfo> usesLibraryInfos);
+
+ AndroidPackageWrite setHiddenUntilInstalled(boolean hidden);
+
+ AndroidPackageWrite setUpdatedSystemApp(boolean updatedSystemApp);
+
+ AndroidPackageWrite setLastPackageUsageTimeInMills(int reason, long time);
+
+ AndroidPackageWrite setPrimaryCpuAbi(String primaryCpuAbi);
+
+ AndroidPackageWrite setSeInfo(String seInfo);
+
+ AndroidPackageWrite setSigningDetails(PackageParser.SigningDetails signingDetails);
+}
diff --git a/core/java/android/content/pm/parsing/ApkLiteParseUtils.java b/core/java/android/content/pm/parsing/ApkLiteParseUtils.java
new file mode 100644
index 000000000000..ac2e373f000d
--- /dev/null
+++ b/core/java/android/content/pm/parsing/ApkLiteParseUtils.java
@@ -0,0 +1,428 @@
+/*
+ * Copyright (C) 2019 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 android.content.pm.parsing;
+
+import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER;
+
+import android.annotation.UnsupportedAppUsage;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageParser;
+import android.content.pm.VerifierInfo;
+import android.content.res.ApkAssets;
+import android.content.res.XmlResourceParser;
+import android.os.Trace;
+import android.util.ArrayMap;
+import android.util.AttributeSet;
+import android.util.Pair;
+import android.util.Slog;
+
+import com.android.internal.R;
+import com.android.internal.util.ArrayUtils;
+
+import libcore.io.IoUtils;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.File;
+import java.io.FileDescriptor;
+import java.io.IOException;
+import java.security.PublicKey;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/** @hide */
+public class ApkLiteParseUtils {
+
+ private static final String TAG = ApkParseUtils.TAG;
+
+ // TODO(b/135203078): Consolidate constants
+ private static final int DEFAULT_MIN_SDK_VERSION = 1;
+ private static final int DEFAULT_TARGET_SDK_VERSION = 0;
+
+ private static final int PARSE_DEFAULT_INSTALL_LOCATION =
+ PackageInfo.INSTALL_LOCATION_UNSPECIFIED;
+
+ /**
+ * Parse only lightweight details about the package at the given location.
+ * Automatically detects if the package is a monolithic style (single APK
+ * file) or cluster style (directory of APKs).
+ * <p>
+ * This performs sanity checking on cluster style packages, such as
+ * requiring identical package name and version codes, a single base APK,
+ * and unique split names.
+ *
+ * @see PackageParser#parsePackage(File, int)
+ */
+ @UnsupportedAppUsage
+ public static PackageParser.PackageLite parsePackageLite(File packageFile, int flags)
+ throws PackageParser.PackageParserException {
+ if (packageFile.isDirectory()) {
+ return parseClusterPackageLite(packageFile, flags);
+ } else {
+ return parseMonolithicPackageLite(packageFile, flags);
+ }
+ }
+
+ public static PackageParser.PackageLite parseMonolithicPackageLite(File packageFile, int flags)
+ throws PackageParser.PackageParserException {
+ Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parseApkLite");
+ final PackageParser.ApkLite baseApk = parseApkLite(packageFile, flags);
+ final String packagePath = packageFile.getAbsolutePath();
+ Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
+ return new PackageParser.PackageLite(packagePath, baseApk, null, null, null, null,
+ null, null);
+ }
+
+ public static PackageParser.PackageLite parseClusterPackageLite(File packageDir, int flags)
+ throws PackageParser.PackageParserException {
+ final File[] files = packageDir.listFiles();
+ if (ArrayUtils.isEmpty(files)) {
+ throw new PackageParser.PackageParserException(
+ PackageManager.INSTALL_PARSE_FAILED_NOT_APK, "No packages found in split");
+ }
+
+ String packageName = null;
+ int versionCode = 0;
+
+ Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parseApkLite");
+ final ArrayMap<String, PackageParser.ApkLite> apks = new ArrayMap<>();
+ for (File file : files) {
+ if (PackageParser.isApkFile(file)) {
+ final PackageParser.ApkLite lite = parseApkLite(file, flags);
+
+ // Assert that all package names and version codes are
+ // consistent with the first one we encounter.
+ if (packageName == null) {
+ packageName = lite.packageName;
+ versionCode = lite.versionCode;
+ } else {
+ if (!packageName.equals(lite.packageName)) {
+ throw new PackageParser.PackageParserException(
+ PackageManager.INSTALL_PARSE_FAILED_BAD_MANIFEST,
+ "Inconsistent package " + lite.packageName + " in " + file
+ + "; expected " + packageName);
+ }
+ if (versionCode != lite.versionCode) {
+ throw new PackageParser.PackageParserException(
+ PackageManager.INSTALL_PARSE_FAILED_BAD_MANIFEST,
+ "Inconsistent version " + lite.versionCode + " in " + file
+ + "; expected " + versionCode);
+ }
+ }
+
+ // Assert that each split is defined only oncuses-static-libe
+ if (apks.put(lite.splitName, lite) != null) {
+ throw new PackageParser.PackageParserException(
+ PackageManager.INSTALL_PARSE_FAILED_BAD_MANIFEST,
+ "Split name " + lite.splitName
+ + " defined more than once; most recent was " + file);
+ }
+ }
+ }
+ Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
+
+ final PackageParser.ApkLite baseApk = apks.remove(null);
+ if (baseApk == null) {
+ throw new PackageParser.PackageParserException(
+ PackageManager.INSTALL_PARSE_FAILED_BAD_MANIFEST,
+ "Missing base APK in " + packageDir);
+ }
+
+ // Always apply deterministic ordering based on splitName
+ final int size = apks.size();
+
+ String[] splitNames = null;
+ boolean[] isFeatureSplits = null;
+ String[] usesSplitNames = null;
+ String[] configForSplits = null;
+ String[] splitCodePaths = null;
+ int[] splitRevisionCodes = null;
+ if (size > 0) {
+ splitNames = new String[size];
+ isFeatureSplits = new boolean[size];
+ usesSplitNames = new String[size];
+ configForSplits = new String[size];
+ splitCodePaths = new String[size];
+ splitRevisionCodes = new int[size];
+
+ splitNames = apks.keySet().toArray(splitNames);
+ Arrays.sort(splitNames, PackageParser.sSplitNameComparator);
+
+ for (int i = 0; i < size; i++) {
+ final PackageParser.ApkLite apk = apks.get(splitNames[i]);
+ usesSplitNames[i] = apk.usesSplitName;
+ isFeatureSplits[i] = apk.isFeatureSplit;
+ configForSplits[i] = apk.configForSplit;
+ splitCodePaths[i] = apk.codePath;
+ splitRevisionCodes[i] = apk.revisionCode;
+ }
+ }
+
+ final String codePath = packageDir.getAbsolutePath();
+ return new PackageParser.PackageLite(codePath, baseApk, splitNames, isFeatureSplits,
+ usesSplitNames, configForSplits, splitCodePaths, splitRevisionCodes);
+ }
+
+ /**
+ * Utility method that retrieves lightweight details about a single APK
+ * file, including package name, split name, and install location.
+ *
+ * @param apkFile path to a single APK
+ * @param flags optional parse flags, such as
+ * {@link PackageParser#PARSE_COLLECT_CERTIFICATES}
+ */
+ public static PackageParser.ApkLite parseApkLite(File apkFile, int flags)
+ throws PackageParser.PackageParserException {
+ return parseApkLiteInner(apkFile, null, null, flags);
+ }
+
+ /**
+ * Utility method that retrieves lightweight details about a single APK
+ * file, including package name, split name, and install location.
+ *
+ * @param fd already open file descriptor of an apk file
+ * @param debugPathName arbitrary text name for this file, for debug output
+ * @param flags optional parse flags, such as
+ * {@link PackageParser#PARSE_COLLECT_CERTIFICATES}
+ */
+ public static PackageParser.ApkLite parseApkLite(FileDescriptor fd, String debugPathName,
+ int flags) throws PackageParser.PackageParserException {
+ return parseApkLiteInner(null, fd, debugPathName, flags);
+ }
+
+ private static PackageParser.ApkLite parseApkLiteInner(File apkFile, FileDescriptor fd,
+ String debugPathName, int flags) throws PackageParser.PackageParserException {
+ final String apkPath = fd != null ? debugPathName : apkFile.getAbsolutePath();
+
+ XmlResourceParser parser = null;
+ ApkAssets apkAssets = null;
+ try {
+ try {
+ apkAssets = fd != null
+ ? ApkAssets.loadFromFd(fd, debugPathName, false, false)
+ : ApkAssets.loadFromPath(apkPath);
+ } catch (IOException e) {
+ throw new PackageParser.PackageParserException(
+ PackageManager.INSTALL_PARSE_FAILED_NOT_APK,
+ "Failed to parse " + apkPath, e);
+ }
+
+ parser = apkAssets.openXml(PackageParser.ANDROID_MANIFEST_FILENAME);
+
+ final PackageParser.SigningDetails signingDetails;
+ if ((flags & PackageParser.PARSE_COLLECT_CERTIFICATES) != 0) {
+ final boolean skipVerify = (flags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0;
+ Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "collectCertificates");
+ try {
+ signingDetails =
+ ApkParseUtils.collectCertificates(apkFile.getAbsolutePath(), skipVerify,
+ false, PackageParser.SigningDetails.UNKNOWN);
+ } finally {
+ Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
+ }
+ } else {
+ signingDetails = PackageParser.SigningDetails.UNKNOWN;
+ }
+
+ final AttributeSet attrs = parser;
+ return parseApkLite(apkPath, parser, attrs, signingDetails);
+
+ } catch (XmlPullParserException | IOException | RuntimeException e) {
+ Slog.w(TAG, "Failed to parse " + apkPath, e);
+ throw new PackageParser.PackageParserException(
+ PackageManager.INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION,
+ "Failed to parse " + apkPath, e);
+ } finally {
+ IoUtils.closeQuietly(parser);
+ if (apkAssets != null) {
+ try {
+ apkAssets.close();
+ } catch (Throwable ignored) {
+ }
+ }
+ // TODO(b/72056911): Implement AutoCloseable on ApkAssets.
+ }
+ }
+
+ private static PackageParser.ApkLite parseApkLite(
+ String codePath, XmlPullParser parser, AttributeSet attrs,
+ PackageParser.SigningDetails signingDetails)
+ throws IOException, XmlPullParserException, PackageParser.PackageParserException {
+ final Pair<String, String> packageSplit = PackageParser.parsePackageSplitNames(
+ parser, attrs);
+
+ int installLocation = PARSE_DEFAULT_INSTALL_LOCATION;
+ int versionCode = 0;
+ int versionCodeMajor = 0;
+ int targetSdkVersion = DEFAULT_TARGET_SDK_VERSION;
+ int minSdkVersion = DEFAULT_MIN_SDK_VERSION;
+ int revisionCode = 0;
+ boolean coreApp = false;
+ boolean debuggable = false;
+ boolean multiArch = false;
+ boolean use32bitAbi = false;
+ boolean extractNativeLibs = true;
+ boolean isolatedSplits = false;
+ boolean isFeatureSplit = false;
+ boolean isSplitRequired = false;
+ boolean useEmbeddedDex = false;
+ String configForSplit = null;
+ String usesSplitName = null;
+
+ for (int i = 0; i < attrs.getAttributeCount(); i++) {
+ final String attr = attrs.getAttributeName(i);
+ switch (attr) {
+ case "installLocation":
+ installLocation = attrs.getAttributeIntValue(i,
+ PARSE_DEFAULT_INSTALL_LOCATION);
+ break;
+ case "versionCode":
+ versionCode = attrs.getAttributeIntValue(i, 0);
+ break;
+ case "versionCodeMajor":
+ versionCodeMajor = attrs.getAttributeIntValue(i, 0);
+ break;
+ case "revisionCode":
+ revisionCode = attrs.getAttributeIntValue(i, 0);
+ break;
+ case "coreApp":
+ coreApp = attrs.getAttributeBooleanValue(i, false);
+ break;
+ case "isolatedSplits":
+ isolatedSplits = attrs.getAttributeBooleanValue(i, false);
+ break;
+ case "configForSplit":
+ configForSplit = attrs.getAttributeValue(i);
+ break;
+ case "isFeatureSplit":
+ isFeatureSplit = attrs.getAttributeBooleanValue(i, false);
+ break;
+ case "isSplitRequired":
+ isSplitRequired = attrs.getAttributeBooleanValue(i, false);
+ break;
+ }
+ }
+
+ // Only search the tree when the tag is the direct child of <manifest> tag
+ int type;
+ final int searchDepth = parser.getDepth() + 1;
+
+ final List<VerifierInfo> verifiers = new ArrayList<>();
+ while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
+ && (type != XmlPullParser.END_TAG || parser.getDepth() >= searchDepth)) {
+ if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
+ continue;
+ }
+
+ if (parser.getDepth() != searchDepth) {
+ continue;
+ }
+
+ if (PackageParser.TAG_PACKAGE_VERIFIER.equals(parser.getName())) {
+ final VerifierInfo verifier = parseVerifier(attrs);
+ if (verifier != null) {
+ verifiers.add(verifier);
+ }
+ } else if (PackageParser.TAG_APPLICATION.equals(parser.getName())) {
+ for (int i = 0; i < attrs.getAttributeCount(); ++i) {
+ final String attr = attrs.getAttributeName(i);
+ switch (attr) {
+ case "debuggable":
+ debuggable = attrs.getAttributeBooleanValue(i, false);
+ break;
+ case "multiArch":
+ multiArch = attrs.getAttributeBooleanValue(i, false);
+ break;
+ case "use32bitAbi":
+ use32bitAbi = attrs.getAttributeBooleanValue(i, false);
+ break;
+ case "extractNativeLibs":
+ extractNativeLibs = attrs.getAttributeBooleanValue(i, true);
+ break;
+ case "useEmbeddedDex":
+ useEmbeddedDex = attrs.getAttributeBooleanValue(i, false);
+ break;
+ }
+ }
+ } else if (PackageParser.TAG_USES_SPLIT.equals(parser.getName())) {
+ if (usesSplitName != null) {
+ Slog.w(TAG, "Only one <uses-split> permitted. Ignoring others.");
+ continue;
+ }
+
+ usesSplitName = attrs.getAttributeValue(PackageParser.ANDROID_RESOURCES, "name");
+ if (usesSplitName == null) {
+ throw new PackageParser.PackageParserException(
+ PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED,
+ "<uses-split> tag requires 'android:name' attribute");
+ }
+ } else if (PackageParser.TAG_USES_SDK.equals(parser.getName())) {
+ for (int i = 0; i < attrs.getAttributeCount(); ++i) {
+ final String attr = attrs.getAttributeName(i);
+ if ("targetSdkVersion".equals(attr)) {
+ targetSdkVersion = attrs.getAttributeIntValue(i,
+ DEFAULT_TARGET_SDK_VERSION);
+ }
+ if ("minSdkVersion".equals(attr)) {
+ minSdkVersion = attrs.getAttributeIntValue(i, DEFAULT_MIN_SDK_VERSION);
+ }
+ }
+ }
+ }
+
+ return new PackageParser.ApkLite(codePath, packageSplit.first, packageSplit.second,
+ isFeatureSplit, configForSplit, usesSplitName, isSplitRequired, versionCode,
+ versionCodeMajor, revisionCode, installLocation, verifiers, signingDetails,
+ coreApp, debuggable, multiArch, use32bitAbi, useEmbeddedDex, extractNativeLibs,
+ isolatedSplits, minSdkVersion, targetSdkVersion);
+ }
+
+ public static VerifierInfo parseVerifier(AttributeSet attrs) {
+ String packageName = null;
+ String encodedPublicKey = null;
+
+ final int attrCount = attrs.getAttributeCount();
+ for (int i = 0; i < attrCount; i++) {
+ final int attrResId = attrs.getAttributeNameResource(i);
+ switch (attrResId) {
+ case R.attr.name:
+ packageName = attrs.getAttributeValue(i);
+ break;
+
+ case R.attr.publicKey:
+ encodedPublicKey = attrs.getAttributeValue(i);
+ break;
+ }
+ }
+
+ if (packageName == null || packageName.length() == 0) {
+ Slog.i(TAG, "verifier package name was null; skipping");
+ return null;
+ }
+
+ final PublicKey publicKey = PackageParser.parsePublicKey(encodedPublicKey);
+ if (publicKey == null) {
+ Slog.i(TAG, "Unable to parse verifier public key for " + packageName);
+ return null;
+ }
+
+ return new VerifierInfo(packageName, publicKey);
+ }
+}
diff --git a/core/java/android/content/pm/parsing/ApkParseUtils.java b/core/java/android/content/pm/parsing/ApkParseUtils.java
new file mode 100644
index 000000000000..0f35b27de7e2
--- /dev/null
+++ b/core/java/android/content/pm/parsing/ApkParseUtils.java
@@ -0,0 +1,3197 @@
+/*
+ * Copyright (C) 2019 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 android.content.pm.parsing;
+
+import static android.content.pm.ActivityInfo.FLAG_SUPPORTS_PICTURE_IN_PICTURE;
+import static android.content.pm.ActivityInfo.RESIZE_MODE_FORCE_RESIZEABLE;
+import static android.content.pm.ActivityInfo.RESIZE_MODE_UNRESIZEABLE;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
+import static android.content.pm.PackageManager.FEATURE_WATCH;
+import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_BAD_MANIFEST;
+import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES;
+import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED;
+import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_NOT_APK;
+import static android.content.pm.PackageManager.INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION;
+import static android.os.Build.VERSION_CODES.O;
+import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER;
+import static android.view.WindowManager.LayoutParams.ROTATION_ANIMATION_UNSPECIFIED;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.app.ActivityTaskManager;
+import android.app.ActivityThread;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.ActivityInfo;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.ConfigurationInfo;
+import android.content.pm.FeatureGroupInfo;
+import android.content.pm.FeatureInfo;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageItemInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageParser;
+import android.content.pm.PackageParser.PackageParserException;
+import android.content.pm.PackageParser.SigningDetails;
+import android.content.pm.Signature;
+import android.content.pm.permission.SplitPermissionInfoParcelable;
+import android.content.pm.split.DefaultSplitAssetLoader;
+import android.content.pm.split.SplitAssetDependencyLoader;
+import android.content.pm.split.SplitAssetLoader;
+import android.content.res.AssetManager;
+import android.content.res.Configuration;
+import android.content.res.Resources;
+import android.content.res.TypedArray;
+import android.content.res.XmlResourceParser;
+import android.net.Uri;
+import android.os.Build;
+import android.os.Bundle;
+import android.os.FileUtils;
+import android.os.RemoteException;
+import android.os.SystemProperties;
+import android.os.Trace;
+import android.text.TextUtils;
+import android.util.ArrayMap;
+import android.util.ArraySet;
+import android.util.AttributeSet;
+import android.util.DisplayMetrics;
+import android.util.Pair;
+import android.util.Slog;
+import android.util.SparseArray;
+import android.util.TypedValue;
+import android.util.apk.ApkSignatureVerifier;
+
+import com.android.internal.R;
+import com.android.internal.os.ClassLoaderFactory;
+import com.android.internal.util.ArrayUtils;
+import com.android.internal.util.XmlUtils;
+
+import libcore.io.IoUtils;
+import libcore.util.EmptyArray;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.File;
+import java.io.IOException;
+import java.security.PublicKey;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Set;
+
+/** @hide */
+public class ApkParseUtils {
+
+ // TODO(b/135203078): Consolidate log tags
+ static final String TAG = "PackageParsing";
+
+ /**
+ * Parse the package at the given location. Automatically detects if the
+ * package is a monolithic style (single APK file) or cluster style
+ * (directory of APKs).
+ * <p>
+ * This performs sanity checking on cluster style packages, such as
+ * requiring identical package name and version codes, a single base APK,
+ * and unique split names.
+ * <p>
+ * Note that this <em>does not</em> perform signature verification; that
+ * must be done separately in {@link #collectCertificates(ParsedPackage, boolean)}.
+ *
+ * If {@code useCaches} is true, the package parser might return a cached
+ * result from a previous parse of the same {@code packageFile} with the same
+ * {@code flags}. Note that this method does not check whether {@code packageFile}
+ * has changed since the last parse, it's up to callers to do so.
+ *
+ * @see PackageParser#parsePackageLite(File, int)
+ */
+ public static ParsingPackage parsePackage(
+ ParseInput parseInput,
+ String[] separateProcesses,
+ PackageParser.Callback callback,
+ DisplayMetrics displayMetrics,
+ boolean onlyCoreApps,
+ File packageFile,
+ int flags
+ ) throws PackageParserException {
+ if (packageFile.isDirectory()) {
+ return parseClusterPackage(parseInput, separateProcesses, callback, displayMetrics,
+ onlyCoreApps, packageFile, flags);
+ } else {
+ return parseMonolithicPackage(parseInput, separateProcesses, callback, displayMetrics,
+ onlyCoreApps, packageFile, flags);
+ }
+ }
+
+ /**
+ * Parse all APKs contained in the given directory, treating them as a
+ * single package. This also performs sanity checking, such as requiring
+ * identical package name and version codes, a single base APK, and unique
+ * split names.
+ * <p>
+ * Note that this <em>does not</em> perform signature verification; that
+ * must be done separately in {@link #collectCertificates(ParsedPackage, boolean)}.
+ */
+ private static ParsingPackage parseClusterPackage(
+ ParseInput parseInput,
+ String[] separateProcesses,
+ PackageParser.Callback callback,
+ DisplayMetrics displayMetrics,
+ boolean onlyCoreApps,
+ File packageDir,
+ int flags
+ ) throws PackageParserException {
+ final PackageParser.PackageLite lite = ApkLiteParseUtils.parseClusterPackageLite(packageDir,
+ 0);
+ if (onlyCoreApps && !lite.coreApp) {
+ throw new PackageParserException(INSTALL_PARSE_FAILED_MANIFEST_MALFORMED,
+ "Not a coreApp: " + packageDir);
+ }
+
+ // Build the split dependency tree.
+ SparseArray<int[]> splitDependencies = null;
+ final SplitAssetLoader assetLoader;
+ if (lite.isolatedSplits && !ArrayUtils.isEmpty(lite.splitNames)) {
+ try {
+ splitDependencies = SplitAssetDependencyLoader.createDependenciesFromPackage(lite);
+ assetLoader = new SplitAssetDependencyLoader(lite, splitDependencies, flags);
+ } catch (SplitAssetDependencyLoader.IllegalDependencyException e) {
+ throw new PackageParserException(INSTALL_PARSE_FAILED_BAD_MANIFEST, e.getMessage());
+ }
+ } else {
+ assetLoader = new DefaultSplitAssetLoader(lite, flags);
+ }
+
+ try {
+ final AssetManager assets = assetLoader.getBaseAssetManager();
+ final File baseApk = new File(lite.baseCodePath);
+ ParsingPackage parsingPackage = parseBaseApk(parseInput, separateProcesses, callback,
+ displayMetrics, baseApk, assets, flags);
+ if (parsingPackage == null) {
+ throw new PackageParserException(INSTALL_PARSE_FAILED_NOT_APK,
+ "Failed to parse base APK: " + baseApk);
+ }
+
+ if (!ArrayUtils.isEmpty(lite.splitNames)) {
+ parsingPackage.asSplit(
+ lite.splitNames,
+ lite.splitCodePaths,
+ lite.splitRevisionCodes,
+ splitDependencies
+ );
+ final int num = lite.splitNames.length;
+
+ for (int i = 0; i < num; i++) {
+ final AssetManager splitAssets = assetLoader.getSplitAssetManager(i);
+ parseSplitApk(parseInput, displayMetrics, separateProcesses, parsingPackage, i,
+ splitAssets, flags);
+ }
+ }
+
+ return parsingPackage.setCodePath(packageDir.getCanonicalPath())
+ .setUse32BitAbi(lite.use32bitAbi);
+ } catch (IOException e) {
+ throw new PackageParserException(INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION,
+ "Failed to get path: " + lite.baseCodePath, e);
+ } finally {
+ IoUtils.closeQuietly(assetLoader);
+ }
+ }
+
+ /**
+ * Parse the given APK file, treating it as as a single monolithic package.
+ * <p>
+ * Note that this <em>does not</em> perform signature verification; that
+ * must be done separately in {@link #collectCertificates(AndroidPackage, boolean)}.
+ */
+ public static ParsingPackage parseMonolithicPackage(
+ ParseInput parseInput,
+ String[] separateProcesses,
+ PackageParser.Callback callback,
+ DisplayMetrics displayMetrics,
+ boolean onlyCoreApps,
+ File apkFile,
+ int flags
+ ) throws PackageParserException {
+ final PackageParser.PackageLite lite = ApkLiteParseUtils.parseMonolithicPackageLite(apkFile,
+ flags);
+ if (onlyCoreApps) {
+ if (!lite.coreApp) {
+ throw new PackageParserException(INSTALL_PARSE_FAILED_MANIFEST_MALFORMED,
+ "Not a coreApp: " + apkFile);
+ }
+ }
+
+ final SplitAssetLoader assetLoader = new DefaultSplitAssetLoader(lite, flags);
+ try {
+ return parseBaseApk(parseInput, separateProcesses, callback,
+ displayMetrics, apkFile, assetLoader.getBaseAssetManager(), flags)
+ .setCodePath(apkFile.getCanonicalPath())
+ .setUse32BitAbi(lite.use32bitAbi);
+ } catch (IOException e) {
+ throw new PackageParserException(INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION,
+ "Failed to get path: " + apkFile, e);
+ } finally {
+ IoUtils.closeQuietly(assetLoader);
+ }
+ }
+
+ private static ParsingPackage parseBaseApk(
+ ParseInput parseInput,
+ String[] separateProcesses,
+ PackageParser.Callback callback,
+ DisplayMetrics displayMetrics,
+ File apkFile,
+ AssetManager assets,
+ int flags
+ ) throws PackageParserException {
+ final String apkPath = apkFile.getAbsolutePath();
+
+ String volumeUuid = null;
+ if (apkPath.startsWith(PackageParser.MNT_EXPAND)) {
+ final int end = apkPath.indexOf('/', PackageParser.MNT_EXPAND.length());
+ volumeUuid = apkPath.substring(PackageParser.MNT_EXPAND.length(), end);
+ }
+
+ if (PackageParser.DEBUG_JAR) Slog.d(TAG, "Scanning base APK: " + apkPath);
+
+ XmlResourceParser parser = null;
+ try {
+ final int cookie = assets.findCookieForPath(apkPath);
+ if (cookie == 0) {
+ throw new PackageParserException(INSTALL_PARSE_FAILED_BAD_MANIFEST,
+ "Failed adding asset path: " + apkPath);
+ }
+ parser = assets.openXmlResourceParser(cookie, PackageParser.ANDROID_MANIFEST_FILENAME);
+ final Resources res = new Resources(assets, displayMetrics, null);
+
+ ParseResult result = parseBaseApk(parseInput, separateProcesses, callback, apkPath, res,
+ parser, flags);
+ if (!result.isSuccess()) {
+ throw new PackageParserException(result.getParseError(),
+ apkPath + " (at " + parser.getPositionDescription() + "): "
+ + result.getErrorMessage());
+ }
+
+ return result.getResultAndNull()
+ .setVolumeUuid(volumeUuid)
+ .setApplicationVolumeUuid(volumeUuid)
+ .setSigningDetails(SigningDetails.UNKNOWN);
+ } catch (PackageParserException e) {
+ throw e;
+ } catch (Exception e) {
+ throw new PackageParserException(INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION,
+ "Failed to read manifest from " + apkPath, e);
+ } finally {
+ IoUtils.closeQuietly(parser);
+ }
+ }
+
+ private static void parseSplitApk(
+ ParseInput parseInput,
+ DisplayMetrics displayMetrics,
+ String[] separateProcesses,
+ ParsingPackage parsingPackage,
+ int splitIndex,
+ AssetManager assets,
+ int flags
+ ) throws PackageParserException {
+ final String apkPath = parsingPackage.getSplitCodePaths()[splitIndex];
+
+ if (PackageParser.DEBUG_JAR) Slog.d(TAG, "Scanning split APK: " + apkPath);
+
+ final Resources res;
+ XmlResourceParser parser = null;
+ try {
+ // This must always succeed, as the path has been added to the AssetManager before.
+ final int cookie = assets.findCookieForPath(apkPath);
+ if (cookie == 0) {
+ throw new PackageParserException(INSTALL_PARSE_FAILED_BAD_MANIFEST,
+ "Failed adding asset path: " + apkPath);
+ }
+
+ parser = assets.openXmlResourceParser(cookie, PackageParser.ANDROID_MANIFEST_FILENAME);
+ res = new Resources(assets, displayMetrics, null);
+
+ final String[] outError = new String[1];
+ ParseResult parseResult = parseSplitApk(parseInput, separateProcesses, parsingPackage,
+ res, parser, flags, splitIndex, outError);
+ if (!parseResult.isSuccess()) {
+ throw new PackageParserException(parseResult.getParseError(),
+ apkPath + " (at " + parser.getPositionDescription() + "): "
+ + parseResult.getErrorMessage());
+ }
+ } catch (PackageParserException e) {
+ throw e;
+ } catch (Exception e) {
+ throw new PackageParserException(INSTALL_PARSE_FAILED_UNEXPECTED_EXCEPTION,
+ "Failed to read manifest from " + apkPath, e);
+ } finally {
+ IoUtils.closeQuietly(parser);
+ }
+ }
+
+ /**
+ * Parse the manifest of a <em>base APK</em>. When adding new features you
+ * need to consider whether they should be supported by split APKs and child
+ * packages.
+ *
+ * @param apkPath The package apk file path
+ * @param res The resources from which to resolve values
+ * @param parser The manifest parser
+ * @param flags Flags how to parse
+ * @return Parsed package or null on error.
+ */
+ private static ParseResult parseBaseApk(
+ ParseInput parseInput,
+ String[] separateProcesses,
+ PackageParser.Callback callback,
+ String apkPath,
+ Resources res,
+ XmlResourceParser parser,
+ int flags
+ ) throws XmlPullParserException, IOException {
+ final String splitName;
+ final String pkgName;
+
+ try {
+ Pair<String, String> packageSplit = PackageParser.parsePackageSplitNames(parser,
+ parser);
+ pkgName = packageSplit.first;
+ splitName = packageSplit.second;
+
+ if (!TextUtils.isEmpty(splitName)) {
+ return parseInput.error(
+ PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME,
+ "Expected base APK, but found split " + splitName
+ );
+ }
+ } catch (PackageParserException e) {
+ return parseInput.error(PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME);
+ }
+
+ // TODO: Remove when manifest overlaying removed
+ if (callback != null) {
+ String[] overlayPaths = callback.getOverlayPaths(pkgName, apkPath);
+ if (overlayPaths != null && overlayPaths.length > 0) {
+ for (String overlayPath : overlayPaths) {
+ res.getAssets().addOverlayPath(overlayPath);
+ }
+ }
+ }
+
+ TypedArray manifestArray = null;
+
+ try {
+ manifestArray = res.obtainAttributes(parser, R.styleable.AndroidManifest);
+
+ boolean isCoreApp = parser.getAttributeBooleanValue(null, "coreApp", false);
+
+ ParsingPackage parsingPackage = PackageImpl.forParsing(
+ pkgName,
+ apkPath,
+ manifestArray,
+ isCoreApp
+ );
+
+ ParseResult result = parseBaseApkTags(parseInput, separateProcesses, callback,
+ parsingPackage, manifestArray, res, parser, flags);
+ if (!result.isSuccess()) {
+ return result;
+ }
+
+ return parseInput.success(parsingPackage);
+ } finally {
+ if (manifestArray != null) {
+ manifestArray.recycle();
+ }
+ }
+ }
+
+ /**
+ * Parse the manifest of a <em>split APK</em>.
+ * <p>
+ * Note that split APKs have many more restrictions on what they're capable
+ * of doing, so many valid features of a base APK have been carefully
+ * omitted here.
+ *
+ * @param parsingPackage builder to fill
+ * @return false on failure
+ */
+ private static ParseResult parseSplitApk(
+ ParseInput parseInput,
+ String[] separateProcesses,
+ ParsingPackage parsingPackage,
+ Resources res,
+ XmlResourceParser parser,
+ int flags,
+ int splitIndex,
+ String[] outError
+ ) throws XmlPullParserException, IOException, PackageParserException {
+ AttributeSet attrs = parser;
+
+ // We parsed manifest tag earlier; just skip past it
+ PackageParser.parsePackageSplitNames(parser, attrs);
+
+ int type;
+
+ boolean foundApp = false;
+
+ int outerDepth = parser.getDepth();
+ while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
+ && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
+ if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
+ continue;
+ }
+
+ String tagName = parser.getName();
+ if (tagName.equals(PackageParser.TAG_APPLICATION)) {
+ if (foundApp) {
+ if (PackageParser.RIGID_PARSER) {
+ return parseInput.error(
+ PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED,
+ "<manifest> has more than one <application>"
+ );
+ } else {
+ Slog.w(TAG, "<manifest> has more than one <application>");
+ XmlUtils.skipCurrentTag(parser);
+ continue;
+ }
+ }
+
+ foundApp = true;
+ ParseResult parseResult = parseSplitApplication(parseInput, separateProcesses,
+ parsingPackage, res,
+ parser, flags,
+ splitIndex, outError);
+ if (!parseResult.isSuccess()) {
+ return parseResult;
+ }
+
+ } else if (PackageParser.RIGID_PARSER) {
+ return parseInput.error(
+ PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED,
+ "Bad element under <manifest>: " + parser.getName()
+ );
+
+ } else {
+ Slog.w(TAG, "Unknown element under <manifest>: " + parser.getName()
+ + " at " + parsingPackage.getBaseCodePath() + " "
+ + parser.getPositionDescription());
+ XmlUtils.skipCurrentTag(parser);
+ continue;
+ }
+ }
+
+ if (!foundApp) {
+ return parseInput.error(
+ PackageManager.INSTALL_PARSE_FAILED_MANIFEST_EMPTY,
+ "<manifest> does not contain an <application>"
+ );
+ }
+
+ return parseInput.success(parsingPackage);
+ }
+
+ /**
+ * Parse the {@code application} XML tree at the current parse location in a
+ * <em>split APK</em> manifest.
+ * <p>
+ * Note that split APKs have many more restrictions on what they're capable
+ * of doing, so many valid features of a base APK have been carefully
+ * omitted here.
+ */
+ private static ParseResult parseSplitApplication(
+ ParseInput parseInput,
+ String[] separateProcesses,
+ ParsingPackage parsingPackage,
+ Resources res,
+ XmlResourceParser parser,
+ int flags,
+ int splitIndex,
+ String[] outError
+ ) throws XmlPullParserException, IOException {
+ TypedArray sa = res.obtainAttributes(parser, R.styleable.AndroidManifestApplication);
+
+ parsingPackage.setSplitHasCode(splitIndex, sa.getBoolean(
+ R.styleable.AndroidManifestApplication_hasCode, true));
+
+ final String classLoaderName = sa.getString(
+ R.styleable.AndroidManifestApplication_classLoader);
+ if (classLoaderName == null || ClassLoaderFactory.isValidClassLoaderName(classLoaderName)) {
+ parsingPackage.setSplitClassLoaderName(splitIndex, classLoaderName);
+ } else {
+ return parseInput.error(
+ PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED,
+ "Invalid class loader name: " + classLoaderName
+ );
+ }
+
+ final int innerDepth = parser.getDepth();
+ int type;
+ while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
+ && (type != XmlPullParser.END_TAG || parser.getDepth() > innerDepth)) {
+ if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
+ continue;
+ }
+
+ ComponentParseUtils.ParsedComponent parsedComponent = null;
+
+ String tagName = parser.getName();
+ switch (tagName) {
+ case "activity":
+ ComponentParseUtils.ParsedActivity activity =
+ ComponentParseUtils.parseActivity(separateProcesses,
+ parsingPackage,
+ res, parser, flags,
+ outError,
+ false,
+ parsingPackage.isBaseHardwareAccelerated());
+ if (activity == null) {
+ return parseInput.error(
+ PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED,
+ outError[0]
+ );
+ }
+
+ parsingPackage.addActivity(activity);
+ parsedComponent = activity;
+ break;
+ case "receiver":
+ activity = ComponentParseUtils.parseActivity(
+ separateProcesses, parsingPackage,
+ res, parser, flags, outError,
+ true, false);
+ if (activity == null) {
+ return parseInput.error(
+ PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED,
+ outError[0]
+ );
+ }
+
+ parsingPackage.addReceiver(activity);
+ parsedComponent = activity;
+ break;
+ case "service":
+ ComponentParseUtils.ParsedService s = ComponentParseUtils.parseService(
+ separateProcesses,
+ parsingPackage,
+ res, parser, flags, outError
+ );
+ if (s == null) {
+ return parseInput.error(
+ PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED,
+ outError[0]
+ );
+ }
+
+ parsingPackage.addService(s);
+ parsedComponent = s;
+ break;
+ case "provider":
+ ComponentParseUtils.ParsedProvider p = ComponentParseUtils.parseProvider(
+ separateProcesses,
+ parsingPackage,
+ res, parser, flags, outError);
+ if (p == null) {
+ return parseInput.error(
+ PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED,
+ outError[0]
+ );
+ }
+
+ parsingPackage.addProvider(p);
+ parsedComponent = p;
+ break;
+ case "activity-alias":
+ activity = ComponentParseUtils.parseActivityAlias(
+ parsingPackage,
+ res,
+ parser,
+ outError
+ );
+ if (activity == null) {
+ return parseInput.error(
+ PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED,
+ outError[0]
+ );
+ }
+
+ parsingPackage.addActivity(activity);
+ parsedComponent = activity;
+ break;
+ case "meta-data":
+ // note: application meta-data is stored off to the side, so it can
+ // remain null in the primary copy (we like to avoid extra copies because
+ // it can be large)
+ Bundle appMetaData = parseMetaData(parsingPackage, res, parser,
+ parsingPackage.getAppMetaData(),
+ outError);
+ if (appMetaData == null) {
+ return parseInput.error(
+ PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED,
+ outError[0]
+ );
+ }
+
+ parsingPackage.setAppMetaData(appMetaData);
+ break;
+ case "uses-static-library":
+ ParseResult parseResult = parseUsesStaticLibrary(parseInput, parsingPackage,
+ res, parser);
+ if (!parseResult.isSuccess()) {
+ return parseResult;
+ }
+
+ break;
+ case "uses-library":
+ sa = res.obtainAttributes(parser, R.styleable.AndroidManifestUsesLibrary);
+
+ // Note: don't allow this value to be a reference to a resource
+ // that may change.
+ String lname = sa.getNonResourceString(
+ R.styleable.AndroidManifestUsesLibrary_name);
+ boolean req = sa.getBoolean(
+ R.styleable.AndroidManifestUsesLibrary_required, true);
+
+ sa.recycle();
+
+ if (lname != null) {
+ lname = lname.intern();
+ if (req) {
+ // Upgrade to treat as stronger constraint
+ parsingPackage.addUsesLibrary(lname)
+ .removeUsesOptionalLibrary(lname);
+ } else {
+ // Ignore if someone already defined as required
+ if (!ArrayUtils.contains(parsingPackage.getUsesLibraries(), lname)) {
+ parsingPackage.addUsesOptionalLibrary(lname);
+ }
+ }
+ }
+
+ XmlUtils.skipCurrentTag(parser);
+ break;
+ case "uses-package":
+ // Dependencies for app installers; we don't currently try to
+ // enforce this.
+ XmlUtils.skipCurrentTag(parser);
+ break;
+ default:
+ if (!PackageParser.RIGID_PARSER) {
+ Slog.w(TAG, "Unknown element under <application>: " + tagName
+ + " at " + parsingPackage.getBaseCodePath() + " "
+ + parser.getPositionDescription());
+ XmlUtils.skipCurrentTag(parser);
+ continue;
+ } else {
+ return parseInput.error(
+ PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED,
+ "Bad element under <application>: " + tagName
+ );
+ }
+ }
+
+ if (parsedComponent != null && parsedComponent.getSplitName() == null) {
+ // If the loaded component did not specify a split, inherit the split name
+ // based on the split it is defined in.
+ // This is used to later load the correct split when starting this
+ // component.
+ parsedComponent.setSplitName(parsingPackage.getSplitNames()[splitIndex]);
+ }
+ }
+
+ return parseInput.success(parsingPackage);
+ }
+
+ private static ParseResult parseBaseApkTags(
+ ParseInput parseInput,
+ String[] separateProcesses,
+ PackageParser.Callback callback,
+ ParsingPackage parsingPackage,
+ TypedArray manifestArray,
+ Resources res,
+ XmlResourceParser parser,
+ int flags
+ ) throws XmlPullParserException, IOException {
+ int type;
+ boolean foundApp = false;
+
+ TypedArray sa = manifestArray;
+
+ ParseResult sharedUserResult = parseSharedUser(parseInput, parsingPackage, sa);
+ if (!sharedUserResult.isSuccess()) {
+ return sharedUserResult;
+ }
+
+ parseManifestAttributes(sa, parsingPackage, flags);
+
+ int outerDepth = parser.getDepth();
+ while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
+ && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
+ if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
+ continue;
+ }
+
+ String tagName = parser.getName();
+
+ // All methods return a boolean, even if they can't fail. This can be enforced
+ // by making this final and not assigned, forcing the switch to assign success
+ // once in every branch.
+ final boolean success;
+ ParseResult parseResult = null;
+
+ // TODO(b/135203078): Either use all booleans or all ParseResults
+ // TODO(b/135203078): Convert to instance methods to share variables
+ switch (tagName) {
+ case PackageParser.TAG_APPLICATION:
+ if (foundApp) {
+ if (PackageParser.RIGID_PARSER) {
+ return parseInput.error(
+ PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED,
+ "<manifest> has more than one <application>"
+ );
+ } else {
+ Slog.w(TAG, "<manifest> has more than one <application>");
+ XmlUtils.skipCurrentTag(parser);
+ success = true;
+ }
+ } else {
+ foundApp = true;
+ parseResult = parseBaseApplication(parseInput, separateProcesses,
+ callback,
+ parsingPackage, res, parser, flags);
+ success = parseResult.isSuccess();
+ }
+ break;
+ case PackageParser.TAG_OVERLAY:
+ parseResult = parseOverlay(parseInput, parsingPackage, res, parser);
+ success = parseResult.isSuccess();
+ break;
+ case PackageParser.TAG_KEY_SETS:
+ parseResult = parseKeySets(parseInput, parsingPackage, res, parser);
+ success = parseResult.isSuccess();
+ break;
+ case PackageParser.TAG_PERMISSION_GROUP:
+ parseResult = parsePermissionGroup(parseInput, parsingPackage, res,
+ parser);
+ success = parseResult.isSuccess();
+ break;
+ case PackageParser.TAG_PERMISSION:
+ parseResult = parsePermission(parseInput, parsingPackage, res, parser);
+ success = parseResult.isSuccess();
+ break;
+ case PackageParser.TAG_PERMISSION_TREE:
+ parseResult = parsePermissionTree(parseInput, parsingPackage, res, parser);
+ success = parseResult.isSuccess();
+ break;
+ case PackageParser.TAG_USES_PERMISSION:
+ case PackageParser.TAG_USES_PERMISSION_SDK_M:
+ case PackageParser.TAG_USES_PERMISSION_SDK_23:
+ parseResult = parseUsesPermission(parseInput, parsingPackage, res, parser,
+ callback);
+ success = parseResult.isSuccess();
+ break;
+ case PackageParser.TAG_USES_CONFIGURATION:
+ success = parseUsesConfiguration(parsingPackage, res, parser);
+ break;
+ case PackageParser.TAG_USES_FEATURE:
+ success = parseUsesFeature(parsingPackage, res, parser);
+ break;
+ case PackageParser.TAG_FEATURE_GROUP:
+ success = parseFeatureGroup(parsingPackage, res, parser);
+ break;
+ case PackageParser.TAG_USES_SDK:
+ parseResult = parseUsesSdk(parseInput, parsingPackage, res, parser);
+ success = parseResult.isSuccess();
+ break;
+ case PackageParser.TAG_SUPPORT_SCREENS:
+ success = parseSupportScreens(parsingPackage, res, parser);
+ break;
+ case PackageParser.TAG_PROTECTED_BROADCAST:
+ success = parseProtectedBroadcast(parsingPackage, res, parser);
+ break;
+ case PackageParser.TAG_INSTRUMENTATION:
+ parseResult = parseInstrumentation(parseInput, parsingPackage, res,
+ parser);
+ success = parseResult.isSuccess();
+ break;
+ case PackageParser.TAG_ORIGINAL_PACKAGE:
+ success = parseOriginalPackage(parsingPackage, res, parser);
+ break;
+ case PackageParser.TAG_ADOPT_PERMISSIONS:
+ success = parseAdoptPermissions(parsingPackage, res, parser);
+ break;
+ case PackageParser.TAG_USES_GL_TEXTURE:
+ case PackageParser.TAG_COMPATIBLE_SCREENS:
+ case PackageParser.TAG_SUPPORTS_INPUT:
+ case PackageParser.TAG_EAT_COMMENT:
+ // Just skip this tag
+ XmlUtils.skipCurrentTag(parser);
+ success = true;
+ break;
+ case PackageParser.TAG_RESTRICT_UPDATE:
+ success = parseRestrictUpdateHash(flags, parsingPackage, res, parser);
+ break;
+ case PackageParser.TAG_QUERIES:
+ parseResult = parseQueries(parseInput, parsingPackage, res, parser);
+ success = parseResult.isSuccess();
+ break;
+ default:
+ parseResult = parseUnknownTag(parseInput, parsingPackage, parser);
+ success = parseResult.isSuccess();
+ break;
+ }
+
+ if (parseResult != null && !parseResult.isSuccess()) {
+ return parseResult;
+ }
+
+ if (!success) {
+ return parseResult;
+ }
+ }
+
+ if (!foundApp && ArrayUtils.size(parsingPackage.getInstrumentations()) == 0) {
+ return parseInput.error(
+ PackageManager.INSTALL_PARSE_FAILED_MANIFEST_EMPTY,
+ "<manifest> does not contain an <application> or <instrumentation>"
+ );
+ }
+
+ convertNewPermissions(parsingPackage);
+
+ convertSplitPermissions(parsingPackage);
+
+ // At this point we can check if an application is not supporting densities and hence
+ // cannot be windowed / resized. Note that an SDK version of 0 is common for
+ // pre-Doughnut applications.
+ if (parsingPackage.usesCompatibilityMode()) {
+ adjustPackageToBeUnresizeableAndUnpipable(parsingPackage);
+ }
+
+ return parseInput.success(parsingPackage);
+ }
+
+ private static ParseResult parseUnknownTag(
+ ParseInput parseInput,
+ ParsingPackage parsingPackage,
+ XmlResourceParser parser
+ ) throws IOException, XmlPullParserException {
+ if (PackageParser.RIGID_PARSER) {
+ return parseInput.error(
+ PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED,
+ "Bad element under <manifest>: " + parser.getName()
+ );
+ } else {
+ Slog.w(TAG, "Unknown element under <manifest>: " + parser.getName()
+ + " at " + parsingPackage.getBaseCodePath() + " "
+ + parser.getPositionDescription());
+ XmlUtils.skipCurrentTag(parser);
+ return parseInput.success(parsingPackage);
+ }
+ }
+
+ private static ParseResult parseSharedUser(
+ ParseInput parseInput,
+ ParsingPackage parsingPackage,
+ TypedArray manifestArray
+ ) {
+ String str = manifestArray.getNonConfigurationString(
+ R.styleable.AndroidManifest_sharedUserId, 0);
+ if (TextUtils.isEmpty(str)) {
+ return parseInput.success(parsingPackage);
+ }
+
+ String nameError = validateName(str, true, true);
+ if (nameError != null && !"android".equals(parsingPackage.getPackageName())) {
+ return parseInput.error(
+ PackageManager.INSTALL_PARSE_FAILED_BAD_SHARED_USER_ID,
+ "<manifest> specifies bad sharedUserId name \"" + str + "\": "
+ + nameError
+ );
+ }
+
+ int sharedUserLabel = manifestArray.getResourceId(
+ R.styleable.AndroidManifest_sharedUserLabel, 0);
+ parsingPackage.setSharedUserId(str.intern())
+ .setSharedUserLabel(sharedUserLabel);
+
+ return parseInput.success(parsingPackage);
+ }
+
+ private static void parseManifestAttributes(
+ TypedArray manifestArray,
+ ParsingPackage parsingPackage,
+ int flags
+ ) {
+ int installLocation = manifestArray.getInteger(R.styleable.AndroidManifest_installLocation,
+ PackageParser.PARSE_DEFAULT_INSTALL_LOCATION);
+
+ final int targetSandboxVersion = manifestArray.getInteger(
+ R.styleable.AndroidManifest_targetSandboxVersion,
+ PackageParser.PARSE_DEFAULT_TARGET_SANDBOX);
+
+ parsingPackage.setInstallLocation(installLocation)
+ .setTargetSandboxVersion(targetSandboxVersion);
+
+ /* Set the global "on SD card" flag */
+ parsingPackage.setExternalStorage((flags & PackageParser.PARSE_EXTERNAL_STORAGE) != 0);
+
+ parsingPackage.setIsolatedSplitLoading(manifestArray.getBoolean(
+ R.styleable.AndroidManifest_isolatedSplits, false));
+ }
+
+ private static ParseResult parseKeySets(
+ ParseInput parseInput,
+ ParsingPackage parsingPackage,
+ Resources res,
+ XmlResourceParser parser
+ ) throws XmlPullParserException, IOException {
+ // we've encountered the 'key-sets' tag
+ // all the keys and keysets that we want must be defined here
+ // so we're going to iterate over the parser and pull out the things we want
+ int outerDepth = parser.getDepth();
+ int currentKeySetDepth = -1;
+ int type;
+ String currentKeySet = null;
+ ArrayMap<String, PublicKey> publicKeys = new ArrayMap<>();
+ ArraySet<String> upgradeKeySets = new ArraySet<>();
+ ArrayMap<String, ArraySet<String>> definedKeySets =
+ new ArrayMap<>();
+ ArraySet<String> improperKeySets = new ArraySet<>();
+ while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
+ && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
+ if (type == XmlPullParser.END_TAG) {
+ if (parser.getDepth() == currentKeySetDepth) {
+ currentKeySet = null;
+ currentKeySetDepth = -1;
+ }
+ continue;
+ }
+ String tagName = parser.getName();
+ if (tagName.equals("key-set")) {
+ if (currentKeySet != null) {
+ return parseInput.error(
+ PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED,
+ "Improperly nested 'key-set' tag at " + parser.getPositionDescription()
+ );
+ }
+ final TypedArray sa = res.obtainAttributes(parser,
+ R.styleable.AndroidManifestKeySet);
+ final String keysetName = sa.getNonResourceString(
+ R.styleable.AndroidManifestKeySet_name);
+ definedKeySets.put(keysetName, new ArraySet<>());
+ currentKeySet = keysetName;
+ currentKeySetDepth = parser.getDepth();
+ sa.recycle();
+ } else if (tagName.equals("public-key")) {
+ if (currentKeySet == null) {
+ return parseInput.error(
+ PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED,
+ "Improperly nested 'key-set' tag at " + parser.getPositionDescription()
+ );
+ }
+ final TypedArray sa = res.obtainAttributes(parser,
+ R.styleable.AndroidManifestPublicKey);
+ final String publicKeyName = sa.getNonResourceString(
+ R.styleable.AndroidManifestPublicKey_name);
+ final String encodedKey = sa.getNonResourceString(
+ R.styleable.AndroidManifestPublicKey_value);
+ if (encodedKey == null && publicKeys.get(publicKeyName) == null) {
+ sa.recycle();
+ return parseInput.error(
+ PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED,
+ "'public-key' " + publicKeyName + " must define a public-key value"
+ + " on first use at " + parser.getPositionDescription()
+ );
+ } else if (encodedKey != null) {
+ PublicKey currentKey = PackageParser.parsePublicKey(encodedKey);
+ if (currentKey == null) {
+ Slog.w(TAG, "No recognized valid key in 'public-key' tag at "
+ + parser.getPositionDescription() + " key-set " + currentKeySet
+ + " will not be added to the package's defined key-sets.");
+ sa.recycle();
+ improperKeySets.add(currentKeySet);
+ XmlUtils.skipCurrentTag(parser);
+ continue;
+ }
+ if (publicKeys.get(publicKeyName) == null
+ || publicKeys.get(publicKeyName).equals(currentKey)) {
+
+ /* public-key first definition, or matches old definition */
+ publicKeys.put(publicKeyName, currentKey);
+ } else {
+ sa.recycle();
+ return parseInput.error(
+ PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED,
+ "Value of 'public-key' " + publicKeyName
+ + " conflicts with previously defined value at "
+ + parser.getPositionDescription()
+ );
+ }
+ }
+ definedKeySets.get(currentKeySet).add(publicKeyName);
+ sa.recycle();
+ XmlUtils.skipCurrentTag(parser);
+ } else if (tagName.equals("upgrade-key-set")) {
+ final TypedArray sa = res.obtainAttributes(parser,
+ R.styleable.AndroidManifestUpgradeKeySet);
+ String name = sa.getNonResourceString(
+ R.styleable.AndroidManifestUpgradeKeySet_name);
+ upgradeKeySets.add(name);
+ sa.recycle();
+ XmlUtils.skipCurrentTag(parser);
+ } else if (PackageParser.RIGID_PARSER) {
+ return parseInput.error(
+ PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED,
+ "Bad element under <key-sets>: " + parser.getName()
+ + " at " + parsingPackage.getBaseCodePath() + " "
+ + parser.getPositionDescription()
+ );
+ } else {
+ Slog.w(TAG, "Unknown element under <key-sets>: " + parser.getName()
+ + " at " + parsingPackage.getBaseCodePath() + " "
+ + parser.getPositionDescription());
+ XmlUtils.skipCurrentTag(parser);
+ continue;
+ }
+ }
+ String packageName = parsingPackage.getPackageName();
+ Set<String> publicKeyNames = publicKeys.keySet();
+ if (publicKeyNames.removeAll(definedKeySets.keySet())) {
+ return parseInput.error(
+ PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED,
+ "Package" + packageName + " AndroidManifest.xml "
+ + "'key-set' and 'public-key' names must be distinct."
+ );
+ }
+
+ for (ArrayMap.Entry<String, ArraySet<String>> e : definedKeySets.entrySet()) {
+ final String keySetName = e.getKey();
+ if (e.getValue().size() == 0) {
+ Slog.w(TAG, "Package" + packageName + " AndroidManifest.xml "
+ + "'key-set' " + keySetName + " has no valid associated 'public-key'."
+ + " Not including in package's defined key-sets.");
+ continue;
+ } else if (improperKeySets.contains(keySetName)) {
+ Slog.w(TAG, "Package" + packageName + " AndroidManifest.xml "
+ + "'key-set' " + keySetName + " contained improper 'public-key'"
+ + " tags. Not including in package's defined key-sets.");
+ continue;
+ }
+
+ for (String s : e.getValue()) {
+ parsingPackage.addKeySet(keySetName, publicKeys.get(s));
+ }
+ }
+ if (parsingPackage.getKeySetMapping().keySet().containsAll(upgradeKeySets)) {
+ parsingPackage.setUpgradeKeySets(upgradeKeySets);
+ } else {
+ return parseInput.error(
+ PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED,
+ "Package" + packageName + " AndroidManifest.xml "
+ + "does not define all 'upgrade-key-set's ."
+ );
+ }
+
+ return parseInput.success(parsingPackage);
+ }
+
+ public static boolean parsePackageItemInfo(String packageName, PackageItemInfo outInfo,
+ String[] outError, String tag, TypedArray sa, boolean nameRequired,
+ int nameRes, int labelRes, int iconRes, int roundIconRes, int logoRes, int bannerRes) {
+ // This case can only happen in unit tests where we sometimes need to create fakes
+ // of various package parser data structures.
+ if (sa == null) {
+ outError[0] = tag + " does not contain any attributes";
+ return false;
+ }
+
+ String name = sa.getNonConfigurationString(nameRes, 0);
+ if (name == null) {
+ if (nameRequired) {
+ outError[0] = tag + " does not specify android:name";
+ return false;
+ }
+ } else {
+ String outInfoName = buildClassName(packageName, name);
+ if (PackageManager.APP_DETAILS_ACTIVITY_CLASS_NAME.equals(outInfoName)) {
+ outError[0] = tag + " invalid android:name";
+ return false;
+ }
+ outInfo.name = outInfoName;
+ if (outInfoName == null) {
+ return false;
+ }
+ }
+
+ int roundIconVal = PackageParser.sUseRoundIcon ? sa.getResourceId(roundIconRes, 0) : 0;
+ if (roundIconVal != 0) {
+ outInfo.icon = roundIconVal;
+ outInfo.nonLocalizedLabel = null;
+ } else {
+ int iconVal = sa.getResourceId(iconRes, 0);
+ if (iconVal != 0) {
+ outInfo.icon = iconVal;
+ outInfo.nonLocalizedLabel = null;
+ }
+ }
+
+ int logoVal = sa.getResourceId(logoRes, 0);
+ if (logoVal != 0) {
+ outInfo.logo = logoVal;
+ }
+
+ int bannerVal = sa.getResourceId(bannerRes, 0);
+ if (bannerVal != 0) {
+ outInfo.banner = bannerVal;
+ }
+
+ TypedValue v = sa.peekValue(labelRes);
+ if (v != null && (outInfo.labelRes = v.resourceId) == 0) {
+ outInfo.nonLocalizedLabel = v.coerceToString();
+ }
+
+ outInfo.packageName = packageName;
+
+ return true;
+ }
+
+ private static ParseResult parsePackageItemInfo(
+ ParseInput parseInput,
+ ParsingPackage parsingPackage,
+ String tag,
+ TypedArray sa,
+ boolean nameRequired,
+ int nameRes,
+ int labelRes,
+ int iconRes,
+ int roundIconRes,
+ int logoRes,
+ int bannerRes
+ ) {
+ // This case can only happen in unit tests where we sometimes need to create fakes
+ // of various package parser data structures.
+ if (sa == null) {
+ return parseInput.error(
+ PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED,
+ tag + " does not contain any attributes"
+ );
+ }
+
+ String name = sa.getNonConfigurationString(nameRes, 0);
+ if (name == null) {
+ if (nameRequired) {
+ return parseInput.error(
+ PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED,
+ tag + " does not specify android:name"
+ );
+ }
+ } else {
+ String packageName = parsingPackage.getPackageName();
+ String outInfoName = buildClassName(packageName, name);
+ if (PackageManager.APP_DETAILS_ACTIVITY_CLASS_NAME.equals(outInfoName)) {
+ return parseInput.error(
+ PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED,
+ tag + " invalid android:name"
+ );
+ } else if (outInfoName == null) {
+ return parseInput.error(
+ PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED,
+ "Empty class name in package " + packageName
+ );
+ }
+
+ parsingPackage.setName(outInfoName);
+ }
+
+ int roundIconVal = PackageParser.sUseRoundIcon ? sa.getResourceId(roundIconRes, 0) : 0;
+ if (roundIconVal != 0) {
+ parsingPackage.setIcon(roundIconVal)
+ .setNonLocalizedLabel(null);
+ } else {
+ int iconVal = sa.getResourceId(iconRes, 0);
+ if (iconVal != 0) {
+ parsingPackage.setIcon(iconVal)
+ .setNonLocalizedLabel(null);
+ }
+ }
+
+ int logoVal = sa.getResourceId(logoRes, 0);
+ if (logoVal != 0) {
+ parsingPackage.setLogo(logoVal);
+ }
+
+ int bannerVal = sa.getResourceId(bannerRes, 0);
+ if (bannerVal != 0) {
+ parsingPackage.setBanner(bannerVal);
+ }
+
+ TypedValue v = sa.peekValue(labelRes);
+ if (v != null) {
+ parsingPackage.setLabelRes(v.resourceId);
+ if (v.resourceId == 0) {
+ parsingPackage.setNonLocalizedLabel(v.coerceToString());
+ }
+ }
+
+ return parseInput.success(parsingPackage);
+ }
+
+ private static ParseResult parsePermissionGroup(
+ ParseInput parseInput,
+ ParsingPackage parsingPackage,
+ Resources res,
+ XmlResourceParser parser
+ ) throws XmlPullParserException, IOException {
+ // TODO(b/135203078): Remove, replace with ParseResult
+ String[] outError = new String[1];
+
+ ComponentParseUtils.ParsedPermissionGroup parsedPermissionGroup =
+ ComponentParseUtils.parsePermissionGroup(parsingPackage,
+ res, parser, outError);
+
+ if (parsedPermissionGroup == null || outError[0] != null) {
+ return parseInput.error(
+ PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED,
+ outError[0]
+ );
+ }
+
+ parsingPackage.addPermissionGroup(parsedPermissionGroup);
+
+ return parseInput.success(parsingPackage);
+ }
+
+ private static ParseResult parsePermission(
+ ParseInput parseInput,
+ ParsingPackage parsingPackage,
+ Resources res,
+ XmlResourceParser parser
+ ) throws XmlPullParserException, IOException {
+ // TODO(b/135203078): Remove, replace with ParseResult
+ String[] outError = new String[1];
+
+ ComponentParseUtils.ParsedPermission parsedPermission =
+ ComponentParseUtils.parsePermission(parsingPackage,
+ res, parser, outError);
+
+ if (parsedPermission == null || outError[0] != null) {
+ return parseInput.error(
+ PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED,
+ outError[0]
+ );
+ }
+
+ parsingPackage.addPermission(parsedPermission);
+
+ return parseInput.success(parsingPackage);
+ }
+
+ private static ParseResult parsePermissionTree(
+ ParseInput parseInput,
+ ParsingPackage parsingPackage,
+ Resources res,
+ XmlResourceParser parser
+ ) throws XmlPullParserException, IOException {
+ // TODO(b/135203078): Remove, replace with ParseResult
+ String[] outError = new String[1];
+
+ ComponentParseUtils.ParsedPermission parsedPermission =
+ ComponentParseUtils.parsePermissionTree(parsingPackage,
+ res, parser, outError);
+
+ if (parsedPermission == null || outError[0] != null) {
+ return parseInput.error(
+ PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED,
+ outError[0]
+ );
+ }
+
+ parsingPackage.addPermission(parsedPermission);
+
+ return parseInput.success(parsingPackage);
+ }
+
+ private static ParseResult parseUsesPermission(
+ ParseInput parseInput,
+ ParsingPackage parsingPackage,
+ Resources res,
+ XmlResourceParser parser,
+ PackageParser.Callback callback
+ )
+ throws XmlPullParserException, IOException {
+ TypedArray sa = res.obtainAttributes(parser,
+ R.styleable.AndroidManifestUsesPermission);
+
+ // Note: don't allow this value to be a reference to a resource
+ // that may change.
+ String name = sa.getNonResourceString(
+ R.styleable.AndroidManifestUsesPermission_name);
+
+ int maxSdkVersion = 0;
+ TypedValue val = sa.peekValue(
+ R.styleable.AndroidManifestUsesPermission_maxSdkVersion);
+ if (val != null) {
+ if (val.type >= TypedValue.TYPE_FIRST_INT && val.type <= TypedValue.TYPE_LAST_INT) {
+ maxSdkVersion = val.data;
+ }
+ }
+
+ final String requiredFeature = sa.getNonConfigurationString(
+ R.styleable.AndroidManifestUsesPermission_requiredFeature, 0);
+
+ final String requiredNotfeature = sa.getNonConfigurationString(
+ R.styleable.AndroidManifestUsesPermission_requiredNotFeature,
+ 0);
+
+ sa.recycle();
+
+ XmlUtils.skipCurrentTag(parser);
+
+ // Can only succeed from here on out
+ ParseResult success = parseInput.success(parsingPackage);
+
+ if (name == null) {
+ return success;
+ }
+
+ if ((maxSdkVersion != 0) && (maxSdkVersion < Build.VERSION.RESOURCES_SDK_INT)) {
+ return success;
+ }
+
+ // Only allow requesting this permission if the platform supports the given feature.
+ if (requiredFeature != null && callback != null && !callback.hasFeature(requiredFeature)) {
+ return success;
+ }
+
+ // Only allow requesting this permission if the platform doesn't support the given feature.
+ if (requiredNotfeature != null && callback != null
+ && callback.hasFeature(requiredNotfeature)) {
+ return success;
+ }
+
+ if (!parsingPackage.getRequestedPermissions().contains(name)) {
+ parsingPackage.addRequestedPermission(name.intern());
+ } else {
+ Slog.w(TAG, "Ignoring duplicate uses-permissions/uses-permissions-sdk-m: "
+ + name + " in package: " + parsingPackage.getPackageName() + " at: "
+ + parser.getPositionDescription());
+ }
+
+ return success;
+ }
+
+ private static boolean parseUsesConfiguration(
+ ParsingPackage parsingPackage,
+ Resources res,
+ XmlResourceParser parser
+ ) throws IOException, XmlPullParserException {
+ ConfigurationInfo cPref = new ConfigurationInfo();
+ TypedArray sa = res.obtainAttributes(parser,
+ R.styleable.AndroidManifestUsesConfiguration);
+ cPref.reqTouchScreen = sa.getInt(
+ R.styleable.AndroidManifestUsesConfiguration_reqTouchScreen,
+ Configuration.TOUCHSCREEN_UNDEFINED);
+ cPref.reqKeyboardType = sa.getInt(
+ R.styleable.AndroidManifestUsesConfiguration_reqKeyboardType,
+ Configuration.KEYBOARD_UNDEFINED);
+ if (sa.getBoolean(
+ R.styleable.AndroidManifestUsesConfiguration_reqHardKeyboard,
+ false)) {
+ cPref.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
+ }
+ cPref.reqNavigation = sa.getInt(
+ R.styleable.AndroidManifestUsesConfiguration_reqNavigation,
+ Configuration.NAVIGATION_UNDEFINED);
+ if (sa.getBoolean(
+ R.styleable.AndroidManifestUsesConfiguration_reqFiveWayNav,
+ false)) {
+ cPref.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
+ }
+ sa.recycle();
+ parsingPackage.addConfigPreference(cPref);
+
+ XmlUtils.skipCurrentTag(parser);
+ return true;
+ }
+
+ private static boolean parseUsesFeature(
+ ParsingPackage parsingPackage,
+ Resources res,
+ XmlResourceParser parser
+ ) throws IOException, XmlPullParserException {
+ FeatureInfo fi = parseFeatureInfo(res, parser);
+ parsingPackage.addReqFeature(fi);
+
+ if (fi.name == null) {
+ ConfigurationInfo cPref = new ConfigurationInfo();
+ cPref.reqGlEsVersion = fi.reqGlEsVersion;
+ parsingPackage.addConfigPreference(cPref);
+ }
+
+ XmlUtils.skipCurrentTag(parser);
+ return true;
+ }
+
+ private static FeatureInfo parseFeatureInfo(Resources res, AttributeSet attrs) {
+ FeatureInfo fi = new FeatureInfo();
+ TypedArray sa = res.obtainAttributes(attrs,
+ R.styleable.AndroidManifestUsesFeature);
+ // Note: don't allow this value to be a reference to a resource
+ // that may change.
+ fi.name = sa.getNonResourceString(R.styleable.AndroidManifestUsesFeature_name);
+ fi.version = sa.getInt(R.styleable.AndroidManifestUsesFeature_version, 0);
+ if (fi.name == null) {
+ fi.reqGlEsVersion = sa.getInt(R.styleable.AndroidManifestUsesFeature_glEsVersion,
+ FeatureInfo.GL_ES_VERSION_UNDEFINED);
+ }
+ if (sa.getBoolean(R.styleable.AndroidManifestUsesFeature_required, true)) {
+ fi.flags |= FeatureInfo.FLAG_REQUIRED;
+ }
+ sa.recycle();
+ return fi;
+ }
+
+ private static boolean parseFeatureGroup(
+ ParsingPackage parsingPackage,
+ Resources res,
+ XmlResourceParser parser
+ ) throws IOException, XmlPullParserException {
+ FeatureGroupInfo group = new FeatureGroupInfo();
+ ArrayList<FeatureInfo> features = null;
+ final int innerDepth = parser.getDepth();
+ int type;
+ while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
+ && (type != XmlPullParser.END_TAG
+ || parser.getDepth() > innerDepth)) {
+ if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
+ continue;
+ }
+
+ final String innerTagName = parser.getName();
+ if (innerTagName.equals("uses-feature")) {
+ FeatureInfo featureInfo = parseFeatureInfo(res, parser);
+ // FeatureGroups are stricter and mandate that
+ // any <uses-feature> declared are mandatory.
+ featureInfo.flags |= FeatureInfo.FLAG_REQUIRED;
+ features = ArrayUtils.add(features, featureInfo);
+ } else {
+ Slog.w(TAG,
+ "Unknown element under <feature-group>: " + innerTagName +
+ " at " + parsingPackage.getBaseCodePath() + " " +
+ parser.getPositionDescription());
+ }
+ XmlUtils.skipCurrentTag(parser);
+ }
+
+ if (features != null) {
+ group.features = new FeatureInfo[features.size()];
+ group.features = features.toArray(group.features);
+ }
+
+ parsingPackage.addFeatureGroup(group);
+ return true;
+ }
+
+ private static ParseResult parseUsesSdk(
+ ParseInput parseInput,
+ ParsingPackage parsingPackage,
+ Resources res,
+ XmlResourceParser parser
+ ) throws IOException, XmlPullParserException {
+ if (PackageParser.SDK_VERSION > 0) {
+ TypedArray sa = res.obtainAttributes(parser,
+ R.styleable.AndroidManifestUsesSdk);
+
+ int minVers = 1;
+ String minCode = null;
+ int targetVers = 0;
+ String targetCode = null;
+
+ TypedValue val = sa.peekValue(R.styleable.AndroidManifestUsesSdk_minSdkVersion);
+ if (val != null) {
+ if (val.type == TypedValue.TYPE_STRING && val.string != null) {
+ minCode = val.string.toString();
+ } else {
+ // If it's not a string, it's an integer.
+ minVers = val.data;
+ }
+ }
+
+ val = sa.peekValue(R.styleable.AndroidManifestUsesSdk_targetSdkVersion);
+ if (val != null) {
+ if (val.type == TypedValue.TYPE_STRING && val.string != null) {
+ targetCode = val.string.toString();
+ if (minCode == null) {
+ minCode = targetCode;
+ }
+ } else {
+ // If it's not a string, it's an integer.
+ targetVers = val.data;
+ }
+ } else {
+ targetVers = minVers;
+ targetCode = minCode;
+ }
+
+ sa.recycle();
+
+ // TODO(b/135203078): Remove, replace with ParseResult
+ String[] outError = new String[1];
+ final int minSdkVersion = PackageParser.computeMinSdkVersion(minVers,
+ minCode,
+ PackageParser.SDK_VERSION, PackageParser.SDK_CODENAMES, outError);
+ if (minSdkVersion < 0) {
+ return parseInput.error(
+ PackageManager.INSTALL_FAILED_OLDER_SDK
+ );
+ }
+
+ final int targetSdkVersion = PackageParser.computeTargetSdkVersion(
+ targetVers,
+ targetCode, PackageParser.SDK_CODENAMES, outError);
+ if (targetSdkVersion < 0) {
+ return parseInput.error(
+ PackageManager.INSTALL_FAILED_OLDER_SDK
+ );
+ }
+
+ parsingPackage.setMinSdkVersion(minSdkVersion)
+ .setTargetSdkVersion(targetSdkVersion);
+ }
+
+ XmlUtils.skipCurrentTag(parser);
+ return parseInput.success(parsingPackage);
+ }
+
+ private static boolean parseRestrictUpdateHash(
+ int flags,
+ ParsingPackage parsingPackage,
+ Resources res,
+ XmlResourceParser parser
+ ) throws IOException, XmlPullParserException {
+ if ((flags & PackageParser.PARSE_IS_SYSTEM_DIR) != 0) {
+ TypedArray sa = res.obtainAttributes(parser,
+ R.styleable.AndroidManifestRestrictUpdate);
+ final String hash = sa.getNonConfigurationString(
+ R.styleable.AndroidManifestRestrictUpdate_hash,
+ 0);
+ sa.recycle();
+
+ if (hash != null) {
+ final int hashLength = hash.length();
+ final byte[] hashBytes = new byte[hashLength / 2];
+ for (int i = 0; i < hashLength; i += 2) {
+ hashBytes[i / 2] = (byte) ((Character.digit(hash.charAt(i), 16)
+ << 4)
+ + Character.digit(hash.charAt(i + 1), 16));
+ }
+ parsingPackage.setRestrictUpdateHash(hashBytes);
+ } else {
+ parsingPackage.setRestrictUpdateHash(null);
+ }
+ }
+
+ XmlUtils.skipCurrentTag(parser);
+ return true;
+ }
+
+ private static ParseResult parseQueries(
+ ParseInput parseInput,
+ ParsingPackage parsingPackage,
+ Resources res,
+ XmlResourceParser parser
+ ) throws IOException, XmlPullParserException {
+
+ final int outerDepth = parser.getDepth();
+ int type;
+ while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
+ && (type != XmlPullParser.END_TAG
+ || parser.getDepth() > outerDepth)) {
+ if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
+ continue;
+ }
+ if (parser.getName().equals("intent")) {
+ String[] outError = new String[1];
+ ComponentParseUtils.ParsedQueriesIntentInfo intentInfo =
+ ComponentParseUtils.parsedParsedQueriesIntentInfo(
+ parsingPackage, res, parser, outError
+ );
+ if (intentInfo == null) {
+ return parseInput.error(
+ PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED,
+ outError[0]
+ );
+ }
+
+ Uri data = null;
+ String dataType = null;
+ String host = "";
+ final int numActions = intentInfo.countActions();
+ final int numSchemes = intentInfo.countDataSchemes();
+ final int numTypes = intentInfo.countDataTypes();
+ final int numHosts = intentInfo.getHosts().length;
+ if ((numSchemes == 0 && numTypes == 0 && numActions == 0)) {
+ outError[0] = "intent tags must contain either an action or data.";
+ return parseInput.error(
+ PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED,
+ outError[0]
+ );
+ }
+ if (numActions > 1) {
+ outError[0] = "intent tag may have at most one action.";
+ return parseInput.error(
+ PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED,
+ outError[0]
+ );
+ }
+ if (numTypes > 1) {
+ outError[0] = "intent tag may have at most one data type.";
+ return parseInput.error(
+ PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED,
+ outError[0]
+ );
+ }
+ if (numSchemes > 1) {
+ outError[0] = "intent tag may have at most one data scheme.";
+ return parseInput.error(
+ PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED,
+ outError[0]
+ );
+ }
+ if (numHosts > 1) {
+ outError[0] = "intent tag may have at most one data host.";
+ return parseInput.error(
+ PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED,
+ outError[0]
+ );
+ }
+ Intent intent = new Intent();
+ for (int i = 0, max = intentInfo.countCategories(); i < max; i++) {
+ intent.addCategory(intentInfo.getCategory(i));
+ }
+ if (numHosts == 1) {
+ host = intentInfo.getHosts()[0];
+ }
+ if (numSchemes == 1) {
+ data = new Uri.Builder()
+ .scheme(intentInfo.getDataScheme(0))
+ .authority(host)
+ .build();
+ }
+ if (numTypes == 1) {
+ dataType = intentInfo.getDataType(0);
+ }
+ intent.setDataAndType(data, dataType);
+ if (numActions == 1) {
+ intent.setAction(intentInfo.getAction(0));
+ }
+ parsingPackage.addQueriesIntent(intent);
+ } else if (parser.getName().equals("package")) {
+ final TypedArray sa = res.obtainAttributes(parser,
+ R.styleable.AndroidManifestQueriesPackage);
+ final String packageName =
+ sa.getString(R.styleable.AndroidManifestQueriesPackage_name);
+ if (TextUtils.isEmpty(packageName)) {
+ return parseInput.error(
+ PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED,
+ "Package name is missing from package tag."
+ );
+ }
+ parsingPackage.addQueriesPackage(packageName.intern());
+ }
+ }
+ return parseInput.success(parsingPackage);
+ }
+
+ /**
+ * Parse the {@code application} XML tree at the current parse location in a
+ * <em>base APK</em> manifest.
+ * <p>
+ * When adding new features, carefully consider if they should also be
+ * supported by split APKs.
+ *
+ * @hide
+ */
+ public static ParseResult parseBaseApplication(
+ ParseInput parseInput,
+ String[] separateProcesses,
+ PackageParser.Callback callback,
+ ParsingPackage parsingPackage,
+ Resources res,
+ XmlResourceParser parser,
+ int flags
+ ) throws XmlPullParserException, IOException {
+ final String pkgName = parsingPackage.getPackageName();
+
+ // TODO(b/135203078): Remove, replace with ParseResult
+ String[] outError = new String[1];
+ TypedArray sa = null;
+
+ try {
+ sa = res.obtainAttributes(parser,
+ R.styleable.AndroidManifestApplication);
+
+
+ parsingPackage
+ .setIconRes(
+ sa.getResourceId(R.styleable.AndroidManifestApplication_icon, 0))
+ .setRoundIconRes(
+ sa.getResourceId(R.styleable.AndroidManifestApplication_roundIcon, 0));
+
+ ParseResult result = parsePackageItemInfo(
+ parseInput,
+ parsingPackage,
+ "<application>",
+ sa, false /*nameRequired*/,
+ R.styleable.AndroidManifestApplication_name,
+ R.styleable.AndroidManifestApplication_label,
+ R.styleable.AndroidManifestApplication_icon,
+ R.styleable.AndroidManifestApplication_roundIcon,
+ R.styleable.AndroidManifestApplication_logo,
+ R.styleable.AndroidManifestApplication_banner
+ );
+ if (!result.isSuccess()) {
+ return result;
+ }
+
+ String name = parsingPackage.getName();
+ if (name != null) {
+ parsingPackage.setClassName(name);
+ }
+
+ String manageSpaceActivity = sa.getNonConfigurationString(
+ R.styleable.AndroidManifestApplication_manageSpaceActivity,
+ Configuration.NATIVE_CONFIG_VERSION);
+ if (manageSpaceActivity != null) {
+ String manageSpaceActivityName = buildClassName(pkgName, manageSpaceActivity);
+
+ if (manageSpaceActivityName == null) {
+ return parseInput.error(
+ PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED,
+ "Empty class name in package " + pkgName
+ );
+ }
+
+ parsingPackage.setManageSpaceActivityName(manageSpaceActivityName);
+ }
+
+ boolean allowBackup = sa.getBoolean(
+ R.styleable.AndroidManifestApplication_allowBackup, true);
+ parsingPackage.setAllowBackup(allowBackup);
+
+ if (allowBackup) {
+ // backupAgent, killAfterRestore, fullBackupContent, backupInForeground,
+ // and restoreAnyVersion are only relevant if backup is possible for the
+ // given application.
+ String backupAgent = sa.getNonConfigurationString(
+ R.styleable.AndroidManifestApplication_backupAgent,
+ Configuration.NATIVE_CONFIG_VERSION);
+ if (backupAgent != null) {
+ String backupAgentName = buildClassName(pkgName, backupAgent);
+ if (backupAgentName == null) {
+ return parseInput.error(
+ PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED,
+ "Empty class name in package " + pkgName
+ );
+ }
+
+ if (PackageParser.DEBUG_BACKUP) {
+ Slog.v(TAG, "android:backupAgent = " + backupAgentName
+ + " from " + pkgName + "+" + backupAgent);
+ }
+
+ parsingPackage.setBackupAgentName(backupAgentName);
+
+ parsingPackage.setKillAfterRestore(sa.getBoolean(
+ R.styleable.AndroidManifestApplication_killAfterRestore, true));
+
+ parsingPackage.setRestoreAnyVersion(sa.getBoolean(
+ R.styleable.AndroidManifestApplication_restoreAnyVersion, false));
+
+ parsingPackage.setFullBackupOnly(sa.getBoolean(
+ R.styleable.AndroidManifestApplication_fullBackupOnly, false));
+
+ parsingPackage.setBackupInForeground(sa.getBoolean(
+ R.styleable.AndroidManifestApplication_backupInForeground,
+ false));
+ }
+
+ TypedValue v = sa.peekValue(
+ R.styleable.AndroidManifestApplication_fullBackupContent);
+ int fullBackupContent = 0;
+
+ if (v != null) {
+ fullBackupContent = v.resourceId;
+
+ if (v.resourceId == 0) {
+ if (PackageParser.DEBUG_BACKUP) {
+ Slog.v(TAG, "fullBackupContent specified as boolean=" +
+ (v.data == 0 ? "false" : "true"));
+ }
+ // "false" => -1, "true" => 0
+ fullBackupContent = v.data == 0 ? -1 : 0;
+ }
+
+ parsingPackage.setFullBackupContent(fullBackupContent);
+ }
+ if (PackageParser.DEBUG_BACKUP) {
+ Slog.v(TAG, "fullBackupContent=" + fullBackupContent + " for " + pkgName);
+ }
+ }
+
+ parsingPackage
+ .setTheme(
+ sa.getResourceId(R.styleable.AndroidManifestApplication_theme, 0))
+ .setDescriptionRes(
+ sa.getResourceId(R.styleable.AndroidManifestApplication_description,
+ 0));
+
+ if (sa.getBoolean(
+ R.styleable.AndroidManifestApplication_persistent,
+ false)) {
+ // Check if persistence is based on a feature being present
+ final String requiredFeature = sa.getNonResourceString(R.styleable
+ .AndroidManifestApplication_persistentWhenFeatureAvailable);
+ parsingPackage.setPersistent(requiredFeature == null
+ || callback.hasFeature(requiredFeature));
+ }
+
+ boolean requiredForAllUsers = sa.getBoolean(
+ R.styleable.AndroidManifestApplication_requiredForAllUsers,
+ false);
+ parsingPackage.setRequiredForAllUsers(requiredForAllUsers);
+
+ String restrictedAccountType = sa.getString(R.styleable
+ .AndroidManifestApplication_restrictedAccountType);
+ if (restrictedAccountType != null && restrictedAccountType.length() > 0) {
+ parsingPackage.setRestrictedAccountType(restrictedAccountType);
+ }
+
+ String requiredAccountType = sa.getString(R.styleable
+ .AndroidManifestApplication_requiredAccountType);
+ if (requiredAccountType != null && requiredAccountType.length() > 0) {
+ parsingPackage.setRequiredAccountType(requiredAccountType);
+ }
+
+ parsingPackage.setForceQueryable(
+ sa.getBoolean(R.styleable.AndroidManifestApplication_forceQueryable, false)
+ );
+
+ boolean debuggable = sa.getBoolean(
+ R.styleable.AndroidManifestApplication_debuggable,
+ false
+ );
+
+ parsingPackage.setDebuggable(debuggable);
+
+ if (debuggable) {
+ // Debuggable implies profileable
+ parsingPackage.setProfileableByShell(true);
+ }
+
+ parsingPackage.setVmSafeMode(sa.getBoolean(
+ R.styleable.AndroidManifestApplication_vmSafeMode, false));
+
+ boolean baseHardwareAccelerated = sa.getBoolean(
+ R.styleable.AndroidManifestApplication_hardwareAccelerated,
+ parsingPackage.getTargetSdkVersion()
+ >= Build.VERSION_CODES.ICE_CREAM_SANDWICH);
+ parsingPackage.setBaseHardwareAccelerated(baseHardwareAccelerated);
+
+ parsingPackage.setHasCode(sa.getBoolean(
+ R.styleable.AndroidManifestApplication_hasCode, true));
+
+ parsingPackage.setAllowTaskReparenting(sa.getBoolean(
+ R.styleable.AndroidManifestApplication_allowTaskReparenting, false));
+
+ parsingPackage.setAllowClearUserData(sa.getBoolean(
+ R.styleable.AndroidManifestApplication_allowClearUserData, true));
+
+ parsingPackage.setTestOnly(sa.getBoolean(
+ com.android.internal.R.styleable.AndroidManifestApplication_testOnly,
+ false));
+
+ parsingPackage.setLargeHeap(sa.getBoolean(
+ R.styleable.AndroidManifestApplication_largeHeap, false));
+
+ parsingPackage.setUsesCleartextTraffic(sa.getBoolean(
+ R.styleable.AndroidManifestApplication_usesCleartextTraffic,
+ parsingPackage.getTargetSdkVersion() < Build.VERSION_CODES.P));
+
+ parsingPackage.setSupportsRtl(sa.getBoolean(
+ R.styleable.AndroidManifestApplication_supportsRtl,
+ false /* default is no RTL support*/));
+
+ parsingPackage.setMultiArch(sa.getBoolean(
+ R.styleable.AndroidManifestApplication_multiArch, false));
+
+ parsingPackage.setExtractNativeLibs(sa.getBoolean(
+ R.styleable.AndroidManifestApplication_extractNativeLibs, true));
+
+ parsingPackage.setUseEmbeddedDex(sa.getBoolean(
+ R.styleable.AndroidManifestApplication_useEmbeddedDex, false));
+
+ parsingPackage.setDefaultToDeviceProtectedStorage(sa.getBoolean(
+ R.styleable.AndroidManifestApplication_defaultToDeviceProtectedStorage,
+ false));
+
+ parsingPackage.setDirectBootAware(sa.getBoolean(
+ R.styleable.AndroidManifestApplication_directBootAware, false));
+
+ if (sa.hasValueOrEmpty(R.styleable.AndroidManifestApplication_resizeableActivity)) {
+ parsingPackage.setActivitiesResizeModeResizeable(sa.getBoolean(
+ R.styleable.AndroidManifestApplication_resizeableActivity, true));
+ } else {
+ parsingPackage.setActivitiesResizeModeResizeableViaSdkVersion(
+ parsingPackage.getTargetSdkVersion() >= Build.VERSION_CODES.N);
+ }
+
+ parsingPackage.setAllowClearUserDataOnFailedRestore(sa.getBoolean(
+ R.styleable.AndroidManifestApplication_allowClearUserDataOnFailedRestore,
+ true));
+
+
+ parsingPackage.setAllowAudioPlaybackCapture(sa.getBoolean(
+ R.styleable.AndroidManifestApplication_allowAudioPlaybackCapture,
+ parsingPackage.getTargetSdkVersion() >= Build.VERSION_CODES.Q));
+
+ parsingPackage.setRequestLegacyExternalStorage(sa.getBoolean(
+ R.styleable.AndroidManifestApplication_requestLegacyExternalStorage,
+ parsingPackage.getTargetSdkVersion() < Build.VERSION_CODES.Q));
+
+ parsingPackage
+ .setMaxAspectRatio(
+ sa.getFloat(R.styleable.AndroidManifestApplication_maxAspectRatio, 0))
+ .setMinAspectRatio(
+ sa.getFloat(R.styleable.AndroidManifestApplication_minAspectRatio, 0))
+ .setNetworkSecurityConfigRes(sa.getResourceId(
+ R.styleable.AndroidManifestApplication_networkSecurityConfig, 0))
+ .setCategory(sa.getInt(R.styleable.AndroidManifestApplication_appCategory,
+ ApplicationInfo.CATEGORY_UNDEFINED));
+
+ String str;
+ str = sa.getNonConfigurationString(
+ R.styleable.AndroidManifestApplication_permission, 0);
+ parsingPackage.setPermission((str != null && str.length() > 0) ? str.intern() : null);
+
+ if (parsingPackage.getTargetSdkVersion() >= Build.VERSION_CODES.FROYO) {
+ str = sa.getNonConfigurationString(
+ R.styleable.AndroidManifestApplication_taskAffinity,
+ Configuration.NATIVE_CONFIG_VERSION);
+ } else {
+ // Some older apps have been seen to use a resource reference
+ // here that on older builds was ignored (with a warning). We
+ // need to continue to do this for them so they don't break.
+ str = sa.getNonResourceString(
+ R.styleable.AndroidManifestApplication_taskAffinity);
+ }
+ String packageName = parsingPackage.getPackageName();
+ String taskAffinity = PackageParser.buildTaskAffinityName(packageName,
+ packageName,
+ str, outError);
+
+ if (outError[0] != null) {
+ return parseInput.error(
+ PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED,
+ outError[0]
+ );
+ }
+
+ parsingPackage.setTaskAffinity(taskAffinity);
+ String factory = sa.getNonResourceString(
+ R.styleable.AndroidManifestApplication_appComponentFactory);
+ if (factory != null) {
+ String appComponentFactory = buildClassName(packageName, factory);
+ if (appComponentFactory == null) {
+ return parseInput.error(
+ PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED,
+ "Empty class name in package " + pkgName
+ );
+ }
+
+ parsingPackage.setAppComponentFactory(appComponentFactory);
+ }
+
+ parsingPackage.setUsesNonSdkApi(sa.getBoolean(
+ R.styleable.AndroidManifestApplication_usesNonSdkApi, false));
+
+ parsingPackage.setHasFragileUserData(sa.getBoolean(
+ R.styleable.AndroidManifestApplication_hasFragileUserData, false));
+
+ CharSequence pname;
+ if (parsingPackage.getTargetSdkVersion() >= Build.VERSION_CODES.FROYO) {
+ pname = sa.getNonConfigurationString(
+ R.styleable.AndroidManifestApplication_process,
+ Configuration.NATIVE_CONFIG_VERSION);
+ } else {
+ // Some older apps have been seen to use a resource reference
+ // here that on older builds was ignored (with a warning). We
+ // need to continue to do this for them so they don't break.
+ pname = sa.getNonResourceString(
+ R.styleable.AndroidManifestApplication_process);
+ }
+ String processName = PackageParser.buildProcessName(packageName, null, pname, flags,
+ separateProcesses, outError);
+
+ if (outError[0] != null) {
+ return parseInput.error(
+ PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED,
+ outError[0]
+ );
+ }
+
+ parsingPackage
+ .setProcessName(processName)
+ .setEnabled(
+ sa.getBoolean(R.styleable.AndroidManifestApplication_enabled,
+ true));
+
+ parsingPackage.setIsGame(sa.getBoolean(
+ R.styleable.AndroidManifestApplication_isGame, false));
+
+ boolean cantSaveState = sa.getBoolean(
+ R.styleable.AndroidManifestApplication_cantSaveState, false);
+ parsingPackage.setCantSaveState(cantSaveState);
+ if (cantSaveState) {
+ // A heavy-weight application can not be in a custom process.
+ // We can do direct compare because we intern all strings.
+ if (processName != null && !processName.equals(packageName)) {
+ return parseInput.error(
+ PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED,
+ "cantSaveState applications can not use custom processes"
+ );
+ }
+ }
+
+ String classLoaderName = sa.getString(
+ R.styleable.AndroidManifestApplication_classLoader);
+ parsingPackage
+ .setUiOptions(sa.getInt(R.styleable.AndroidManifestApplication_uiOptions, 0))
+ .setClassLoaderName(classLoaderName)
+ .setZygotePreloadName(
+ sa.getString(R.styleable.AndroidManifestApplication_zygotePreloadName));
+
+ if (classLoaderName != null
+ && !ClassLoaderFactory.isValidClassLoaderName(classLoaderName)) {
+ return parseInput.error(
+ PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED,
+ "Invalid class loader name: " + classLoaderName
+ );
+ }
+ } finally {
+ if (sa != null) {
+ sa.recycle();
+ }
+ }
+
+ final int innerDepth = parser.getDepth();
+ int type;
+ boolean hasActivityOrder = false;
+ boolean hasReceiverOrder = false;
+ boolean hasServiceOrder = false;
+
+ while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
+ && (type != XmlPullParser.END_TAG || parser.getDepth() > innerDepth)) {
+ if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
+ continue;
+ }
+
+ String tagName = parser.getName();
+ switch (tagName) {
+ case "activity":
+ ComponentParseUtils.ParsedActivity activity =
+ ComponentParseUtils.parseActivity(separateProcesses,
+ parsingPackage,
+ res, parser, flags,
+ outError, false,
+ parsingPackage.isBaseHardwareAccelerated());
+ if (activity == null) {
+ return parseInput.error(
+ PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED,
+ outError[0]
+ );
+ }
+
+ hasActivityOrder |= (activity.order != 0);
+ parsingPackage.addActivity(activity);
+ break;
+ case "receiver":
+ activity = ComponentParseUtils.parseActivity(separateProcesses,
+ parsingPackage,
+ res, parser,
+ flags, outError,
+ true, false);
+ if (activity == null) {
+ return parseInput.error(
+ PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED,
+ outError[0]
+ );
+ }
+
+ hasReceiverOrder |= (activity.order != 0);
+ parsingPackage.addReceiver(activity);
+ break;
+ case "service":
+ ComponentParseUtils.ParsedService s = ComponentParseUtils.parseService(
+ separateProcesses,
+ parsingPackage,
+ res, parser, flags,
+ outError);
+ if (s == null) {
+ return parseInput.error(
+ PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED,
+ outError[0]
+ );
+ }
+
+ hasServiceOrder |= (s.order != 0);
+ parsingPackage.addService(s);
+ break;
+ case "provider":
+ ComponentParseUtils.ParsedProvider p = ComponentParseUtils.parseProvider(
+ separateProcesses,
+ parsingPackage,
+ res, parser, flags,
+ outError
+ );
+ if (p == null) {
+ return parseInput.error(
+ PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED,
+ outError[0]
+ );
+ }
+
+ parsingPackage.addProvider(p);
+ break;
+ case "activity-alias":
+ activity = ComponentParseUtils.parseActivityAlias(
+ parsingPackage,
+ res,
+ parser,
+ outError
+ );
+ if (activity == null) {
+ return parseInput.error(
+ PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED,
+ outError[0]
+ );
+ }
+
+ hasActivityOrder |= (activity.order != 0);
+ parsingPackage.addActivity(activity);
+ break;
+ case "meta-data":
+ // note: application meta-data is stored off to the side, so it can
+ // remain null in the primary copy (we like to avoid extra copies because
+ // it can be large)
+ Bundle appMetaData = parseMetaData(parsingPackage, res, parser,
+ parsingPackage.getAppMetaData(),
+ outError);
+ if (appMetaData == null) {
+ return parseInput.error(
+ PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED,
+ outError[0]
+ );
+ }
+
+ parsingPackage.setAppMetaData(appMetaData);
+ break;
+ case "static-library":
+ sa = res.obtainAttributes(parser,
+ R.styleable.AndroidManifestStaticLibrary);
+
+ // Note: don't allow this value to be a reference to a resource
+ // that may change.
+ String lname = sa.getNonResourceString(
+ R.styleable.AndroidManifestStaticLibrary_name);
+ final int version = sa.getInt(
+ R.styleable.AndroidManifestStaticLibrary_version, -1);
+ final int versionMajor = sa.getInt(
+ R.styleable.AndroidManifestStaticLibrary_versionMajor,
+ 0);
+
+ sa.recycle();
+
+ // Since the app canot run without a static lib - fail if malformed
+ if (lname == null || version < 0) {
+ return parseInput.error(
+ PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED,
+ "Bad static-library declaration name: " + lname
+ + " version: " + version
+ );
+ }
+
+ if (parsingPackage.getSharedUserId() != null) {
+ return parseInput.error(
+ PackageManager.INSTALL_PARSE_FAILED_BAD_SHARED_USER_ID,
+ "sharedUserId not allowed in static shared library"
+ );
+ }
+
+ if (parsingPackage.getStaticSharedLibName() != null) {
+ return parseInput.error(
+ PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED,
+ "Multiple static-shared libs for package " + pkgName
+ );
+ }
+
+ parsingPackage.setStaticSharedLibName(lname.intern());
+ if (version >= 0) {
+ parsingPackage.setStaticSharedLibVersion(
+ PackageInfo.composeLongVersionCode(versionMajor, version));
+ } else {
+ parsingPackage.setStaticSharedLibVersion(version);
+ }
+ parsingPackage.setStaticSharedLibrary(true);
+
+ XmlUtils.skipCurrentTag(parser);
+
+ break;
+ case "library":
+ sa = res.obtainAttributes(parser,
+ R.styleable.AndroidManifestLibrary);
+
+ // Note: don't allow this value to be a reference to a resource
+ // that may change.
+ lname = sa.getNonResourceString(
+ R.styleable.AndroidManifestLibrary_name);
+
+ sa.recycle();
+
+ if (lname != null) {
+ lname = lname.intern();
+ if (!ArrayUtils.contains(parsingPackage.getLibraryNames(), lname)) {
+ parsingPackage.addLibraryName(lname);
+ }
+ }
+
+ XmlUtils.skipCurrentTag(parser);
+
+ break;
+ case "uses-static-library":
+ ParseResult parseResult = parseUsesStaticLibrary(parseInput, parsingPackage,
+ res, parser);
+ if (!parseResult.isSuccess()) {
+ return parseResult;
+ }
+ break;
+ case "uses-library":
+ sa = res.obtainAttributes(parser,
+ R.styleable.AndroidManifestUsesLibrary);
+
+ // Note: don't allow this value to be a reference to a resource
+ // that may change.
+ lname = sa.getNonResourceString(
+ R.styleable.AndroidManifestUsesLibrary_name);
+ boolean req = sa.getBoolean(
+ R.styleable.AndroidManifestUsesLibrary_required,
+ true);
+
+ sa.recycle();
+
+ if (lname != null) {
+ lname = lname.intern();
+ if (req) {
+ parsingPackage.addUsesLibrary(lname);
+ } else {
+ parsingPackage.addUsesOptionalLibrary(lname);
+ }
+ }
+
+ XmlUtils.skipCurrentTag(parser);
+
+ break;
+ case "uses-package":
+ // Dependencies for app installers; we don't currently try to
+ // enforce this.
+ XmlUtils.skipCurrentTag(parser);
+ break;
+ case "profileable":
+ sa = res.obtainAttributes(parser,
+ R.styleable.AndroidManifestProfileable);
+ if (sa.getBoolean(
+ R.styleable.AndroidManifestProfileable_shell, false)) {
+ parsingPackage.setProfileableByShell(true);
+ }
+ XmlUtils.skipCurrentTag(parser);
+
+ default:
+ if (!PackageParser.RIGID_PARSER) {
+ Slog.w(TAG, "Unknown element under <application>: " + tagName
+ + " at " + parsingPackage.getBaseCodePath() + " "
+ + parser.getPositionDescription());
+ XmlUtils.skipCurrentTag(parser);
+ continue;
+ } else {
+ return parseInput.error(
+ PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED,
+ "Bad element under <application>: " + tagName
+ );
+ }
+ }
+ }
+
+ if (TextUtils.isEmpty(parsingPackage.getStaticSharedLibName())) {
+ // Add a hidden app detail activity to normal apps which forwards user to App Details
+ // page.
+ ComponentParseUtils.ParsedActivity a = generateAppDetailsHiddenActivity(
+ parsingPackage,
+ outError
+ );
+ // Ignore errors here
+ parsingPackage.addActivity(a);
+ }
+
+ if (hasActivityOrder) {
+ parsingPackage.sortActivities();
+ }
+ if (hasReceiverOrder) {
+ parsingPackage.sortReceivers();
+ }
+ if (hasServiceOrder) {
+ parsingPackage.sortServices();
+ }
+ // Must be ran after the entire {@link ApplicationInfo} has been fully processed and after
+ // every activity info has had a chance to set it from its attributes.
+ setMaxAspectRatio(parsingPackage);
+ setMinAspectRatio(parsingPackage, callback);
+
+ parsingPackage.setHasDomainUrls(hasDomainURLs(parsingPackage));
+
+ return parseInput.success(parsingPackage);
+ }
+
+ private static ParseResult parseUsesStaticLibrary(
+ ParseInput parseInput,
+ ParsingPackage parsingPackage,
+ Resources res,
+ XmlResourceParser parser
+ ) throws XmlPullParserException, IOException {
+ TypedArray sa = res.obtainAttributes(parser,
+ R.styleable.AndroidManifestUsesStaticLibrary);
+
+ // Note: don't allow this value to be a reference to a resource that may change.
+ String lname = sa.getNonResourceString(
+ R.styleable.AndroidManifestUsesLibrary_name);
+ final int version = sa.getInt(
+ R.styleable.AndroidManifestUsesStaticLibrary_version, -1);
+ String certSha256Digest = sa.getNonResourceString(com.android.internal.R.styleable
+ .AndroidManifestUsesStaticLibrary_certDigest);
+ sa.recycle();
+
+ // Since an APK providing a static shared lib can only provide the lib - fail if malformed
+ if (lname == null || version < 0 || certSha256Digest == null) {
+ return parseInput.error(
+ PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED,
+ "Bad uses-static-library declaration name: " + lname + " version: "
+ + version + " certDigest" + certSha256Digest
+ );
+ }
+
+ // Can depend only on one version of the same library
+ List<String> usesStaticLibraries = parsingPackage.getUsesStaticLibraries();
+ if (usesStaticLibraries != null && usesStaticLibraries.contains(lname)) {
+ return parseInput.error(
+ PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED,
+ "Depending on multiple versions of static library " + lname
+ );
+ }
+
+ lname = lname.intern();
+ // We allow ":" delimiters in the SHA declaration as this is the format
+ // emitted by the certtool making it easy for developers to copy/paste.
+ certSha256Digest = certSha256Digest.replace(":", "").toLowerCase();
+
+ // Fot apps targeting O-MR1 we require explicit enumeration of all certs.
+ String[] additionalCertSha256Digests = EmptyArray.STRING;
+ if (parsingPackage.getTargetSdkVersion() >= Build.VERSION_CODES.O_MR1) {
+ // TODO(b/135203078): Remove, replace with ParseResult
+ String[] outError = new String[1];
+ additionalCertSha256Digests = parseAdditionalCertificates(res, parser, outError);
+ if (additionalCertSha256Digests == null || outError[0] != null) {
+ return parseInput.error(
+ PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED,
+ outError[0]
+ );
+ }
+ } else {
+ XmlUtils.skipCurrentTag(parser);
+ }
+
+ final String[] certSha256Digests = new String[additionalCertSha256Digests.length + 1];
+ certSha256Digests[0] = certSha256Digest;
+ System.arraycopy(additionalCertSha256Digests, 0, certSha256Digests,
+ 1, additionalCertSha256Digests.length);
+
+ parsingPackage.addUsesStaticLibrary(lname)
+ .addUsesStaticLibraryVersion(version)
+ .addUsesStaticLibraryCertDigests(certSha256Digests);
+
+ return parseInput.success(parsingPackage);
+ }
+
+ private static String[] parseAdditionalCertificates(
+ Resources resources,
+ XmlResourceParser parser,
+ String[] outError
+ ) throws XmlPullParserException, IOException {
+ String[] certSha256Digests = EmptyArray.STRING;
+
+ int outerDepth = parser.getDepth();
+ int type;
+ while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
+ && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
+ if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
+ continue;
+ }
+
+ final String nodeName = parser.getName();
+ if (nodeName.equals("additional-certificate")) {
+ final TypedArray sa = resources.obtainAttributes(parser, com.android.internal.
+ R.styleable.AndroidManifestAdditionalCertificate);
+ String certSha256Digest = sa.getNonResourceString(com.android.internal.
+ R.styleable.AndroidManifestAdditionalCertificate_certDigest);
+ sa.recycle();
+
+ if (TextUtils.isEmpty(certSha256Digest)) {
+ outError[0] = "Bad additional-certificate declaration with empty"
+ + " certDigest:" + certSha256Digest;
+ XmlUtils.skipCurrentTag(parser);
+ sa.recycle();
+ return null;
+ }
+
+ // We allow ":" delimiters in the SHA declaration as this is the format
+ // emitted by the certtool making it easy for developers to copy/paste.
+ certSha256Digest = certSha256Digest.replace(":", "").toLowerCase();
+ certSha256Digests = ArrayUtils.appendElement(String.class,
+ certSha256Digests, certSha256Digest);
+ } else {
+ XmlUtils.skipCurrentTag(parser);
+ }
+ }
+
+ return certSha256Digests;
+ }
+
+ /**
+ * Generate activity object that forwards user to App Details page automatically.
+ * This activity should be invisible to user and user should not know or see it.
+ *
+ * @hide
+ */
+ @NonNull
+ private static ComponentParseUtils.ParsedActivity generateAppDetailsHiddenActivity(
+ ParsingPackage parsingPackage,
+ String[] outError
+ ) {
+ String packageName = parsingPackage.getPackageName();
+ String processName = parsingPackage.getProcessName();
+ boolean hardwareAccelerated = parsingPackage.isBaseHardwareAccelerated();
+ int uiOptions = parsingPackage.getUiOptions();
+
+ // Build custom App Details activity info instead of parsing it from xml
+ ComponentParseUtils.ParsedActivity activity = new ComponentParseUtils.ParsedActivity();
+ activity.setPackageName(packageName);
+
+ activity.theme = android.R.style.Theme_NoDisplay;
+ activity.exported = true;
+ activity.className = PackageManager.APP_DETAILS_ACTIVITY_CLASS_NAME;
+ activity.setProcessName(processName, processName);
+ activity.uiOptions = uiOptions;
+ activity.taskAffinity = PackageParser.buildTaskAffinityName(packageName,
+ packageName,
+ ":app_details", outError);
+ activity.enabled = true;
+ activity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
+ activity.documentLaunchMode = ActivityInfo.DOCUMENT_LAUNCH_NONE;
+ activity.maxRecents = ActivityTaskManager.getDefaultAppRecentsLimitStatic();
+ activity.configChanges = PackageParser.getActivityConfigChanges(0, 0);
+ activity.softInputMode = 0;
+ activity.persistableMode = ActivityInfo.PERSIST_NEVER;
+ activity.screenOrientation = SCREEN_ORIENTATION_UNSPECIFIED;
+ activity.resizeMode = RESIZE_MODE_FORCE_RESIZEABLE;
+ activity.lockTaskLaunchMode = 0;
+ activity.directBootAware = false;
+ activity.rotationAnimation = ROTATION_ANIMATION_UNSPECIFIED;
+ activity.colorMode = ActivityInfo.COLOR_MODE_DEFAULT;
+ if (hardwareAccelerated) {
+ activity.flags |= ActivityInfo.FLAG_HARDWARE_ACCELERATED;
+ }
+
+ return activity;
+ }
+
+ /**
+ * Check if one of the IntentFilter as both actions DEFAULT / VIEW and a HTTP/HTTPS data URI
+ */
+ private static boolean hasDomainURLs(
+ ParsingPackage parsingPackage) {
+ final List<ComponentParseUtils.ParsedActivity> activities = parsingPackage.getActivities();
+ final int countActivities = activities.size();
+ for (int n = 0; n < countActivities; n++) {
+ ComponentParseUtils.ParsedActivity activity = activities.get(n);
+ List<ComponentParseUtils.ParsedActivityIntentInfo> filters = activity.intents;
+ if (filters == null) continue;
+ final int countFilters = filters.size();
+ for (int m = 0; m < countFilters; m++) {
+ ComponentParseUtils.ParsedActivityIntentInfo aii = filters.get(m);
+ if (!aii.hasAction(Intent.ACTION_VIEW)) continue;
+ if (!aii.hasAction(Intent.ACTION_DEFAULT)) continue;
+ if (aii.hasDataScheme(IntentFilter.SCHEME_HTTP) ||
+ aii.hasDataScheme(IntentFilter.SCHEME_HTTPS)) {
+ return true;
+ }
+ }
+ }
+ return false;
+ }
+
+ /**
+ * Sets the max aspect ratio of every child activity that doesn't already have an aspect
+ * ratio set.
+ */
+ private static void setMaxAspectRatio(
+ ParsingPackage parsingPackage) {
+ // Default to (1.86) 16.7:9 aspect ratio for pre-O apps and unset for O and greater.
+ // NOTE: 16.7:9 was the max aspect ratio Android devices can support pre-O per the CDD.
+ float maxAspectRatio = parsingPackage.getTargetSdkVersion() < O
+ ? PackageParser.DEFAULT_PRE_O_MAX_ASPECT_RATIO : 0;
+
+ float packageMaxAspectRatio = parsingPackage.getMaxAspectRatio();
+ if (packageMaxAspectRatio != 0) {
+ // Use the application max aspect ration as default if set.
+ maxAspectRatio = packageMaxAspectRatio;
+ } else {
+ Bundle appMetaData = parsingPackage.getAppMetaData();
+ if (appMetaData != null && appMetaData.containsKey(
+ PackageParser.METADATA_MAX_ASPECT_RATIO)) {
+ maxAspectRatio = appMetaData.getFloat(PackageParser.METADATA_MAX_ASPECT_RATIO,
+ maxAspectRatio);
+ }
+ }
+
+ if (parsingPackage.getActivities() != null) {
+ for (ComponentParseUtils.ParsedActivity activity : parsingPackage.getActivities()) {
+ // If the max aspect ratio for the activity has already been set, skip.
+ if (activity.hasMaxAspectRatio()) {
+ continue;
+ }
+
+ // By default we prefer to use a values defined on the activity directly than values
+ // defined on the application. We do not check the styled attributes on the activity
+ // as it would have already been set when we processed the activity. We wait to
+ // process the meta data here since this method is called at the end of processing
+ // the application and all meta data is guaranteed.
+ final float activityAspectRatio = activity.metaData != null
+ ? activity.metaData.getFloat(PackageParser.METADATA_MAX_ASPECT_RATIO,
+ maxAspectRatio)
+ : maxAspectRatio;
+
+ activity.setMaxAspectRatio(activity.resizeMode, activityAspectRatio);
+ }
+ }
+ }
+
+ /**
+ * Sets the min aspect ratio of every child activity that doesn't already have an aspect
+ * ratio set.
+ */
+ private static void setMinAspectRatio(
+ ParsingPackage parsingPackage,
+ PackageParser.Callback callback
+ ) {
+ final float minAspectRatio;
+ float packageMinAspectRatio = parsingPackage.getMinAspectRatio();
+ if (packageMinAspectRatio != 0) {
+ // Use the application max aspect ration as default if set.
+ minAspectRatio = packageMinAspectRatio;
+ } else {
+ // Default to (1.33) 4:3 aspect ratio for pre-Q apps and unset for Q and greater.
+ // NOTE: 4:3 was the min aspect ratio Android devices can support pre-Q per the CDD,
+ // except for watches which always supported 1:1.
+ minAspectRatio = parsingPackage.getTargetSdkVersion() >= Build.VERSION_CODES.Q
+ ? 0
+ : (callback != null && callback.hasFeature(FEATURE_WATCH))
+ ? PackageParser.DEFAULT_PRE_Q_MIN_ASPECT_RATIO_WATCH
+ : PackageParser.DEFAULT_PRE_Q_MIN_ASPECT_RATIO;
+ }
+
+ if (parsingPackage.getActivities() != null) {
+ for (ComponentParseUtils.ParsedActivity activity : parsingPackage.getActivities()) {
+ if (activity.hasMinAspectRatio()) {
+ continue;
+ }
+ activity.setMinAspectRatio(activity.resizeMode, minAspectRatio);
+ }
+ }
+ }
+
+ private static ParseResult parseOverlay(
+ ParseInput parseInput,
+ ParsingPackage parsingPackage,
+ Resources res,
+ XmlResourceParser parser
+ ) throws IOException, XmlPullParserException {
+
+ TypedArray sa = res.obtainAttributes(parser, R.styleable.AndroidManifestResourceOverlay);
+ String target = sa.getString(
+ R.styleable.AndroidManifestResourceOverlay_targetPackage);
+ String targetName = sa.getString(
+ R.styleable.AndroidManifestResourceOverlay_targetName);
+ String category = sa.getString(
+ R.styleable.AndroidManifestResourceOverlay_category);
+ int priority = sa.getInt(R.styleable.AndroidManifestResourceOverlay_priority,
+ 0);
+ boolean isStatic = sa.getBoolean(
+ R.styleable.AndroidManifestResourceOverlay_isStatic, false);
+
+ if (target == null) {
+ return parseInput.error(
+ PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED,
+ "<overlay> does not specify a target package"
+ );
+ }
+
+ if (priority < 0 || priority > 9999) {
+ return parseInput.error(
+ PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED,
+ "<overlay> priority must be between 0 and 9999"
+ );
+ }
+
+ // check to see if overlay should be excluded based on system property condition
+ String propName = sa.getString(
+ R.styleable.AndroidManifestResourceOverlay_requiredSystemPropertyName);
+ String propValue = sa.getString(
+ R.styleable.AndroidManifestResourceOverlay_requiredSystemPropertyValue);
+ if (!checkOverlayRequiredSystemProperty(propName, propValue)) {
+ Slog.i(TAG, "Skipping target and overlay pair " + target + " and "
+ + parsingPackage.getBaseCodePath()
+ + ": overlay ignored due to required system property: "
+ + propName + " with value: " + propValue);
+ return parseInput.error(
+ PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED,
+ "Skipping target and overlay pair " + target + " and "
+ + parsingPackage.getBaseCodePath()
+ + ": overlay ignored due to required system property: "
+ + propName + " with value: " + propValue
+ );
+ }
+
+ parsingPackage
+ .setIsOverlay(true)
+ .setOverlayTarget(target)
+ .setOverlayTargetName(targetName)
+ .setOverlayCategory(category)
+ .setOverlayPriority(priority)
+ .setOverlayIsStatic(isStatic);
+
+ sa.recycle();
+
+ XmlUtils.skipCurrentTag(parser);
+ return parseInput.success(parsingPackage);
+ }
+
+ private static boolean parseProtectedBroadcast(
+ ParsingPackage parsingPackage,
+ Resources res,
+ XmlResourceParser parser
+ ) throws IOException, XmlPullParserException {
+ TypedArray sa = res.obtainAttributes(parser,
+ R.styleable.AndroidManifestProtectedBroadcast);
+
+ // Note: don't allow this value to be a reference to a resource
+ // that may change.
+ String name = sa.getNonResourceString(R.styleable.AndroidManifestProtectedBroadcast_name);
+
+ sa.recycle();
+
+ if (name != null) {
+ parsingPackage.addProtectedBroadcast(name);
+ }
+
+ XmlUtils.skipCurrentTag(parser);
+ return true;
+ }
+
+ private static boolean parseSupportScreens(
+ ParsingPackage parsingPackage,
+ Resources res,
+ XmlResourceParser parser
+ ) throws IOException, XmlPullParserException {
+ TypedArray sa = res.obtainAttributes(parser,
+ R.styleable.AndroidManifestSupportsScreens);
+
+ int requiresSmallestWidthDp = sa.getInteger(
+ R.styleable.AndroidManifestSupportsScreens_requiresSmallestWidthDp,
+ 0);
+ int compatibleWidthLimitDp = sa.getInteger(
+ R.styleable.AndroidManifestSupportsScreens_compatibleWidthLimitDp,
+ 0);
+ int largestWidthLimitDp = sa.getInteger(
+ R.styleable.AndroidManifestSupportsScreens_largestWidthLimitDp,
+ 0);
+
+ // This is a trick to get a boolean and still able to detect
+ // if a value was actually set.
+ parsingPackage
+ .setSupportsSmallScreens(
+ sa.getInteger(R.styleable.AndroidManifestSupportsScreens_smallScreens, 1))
+ .setSupportsNormalScreens(
+ sa.getInteger(R.styleable.AndroidManifestSupportsScreens_normalScreens, 1))
+ .setSupportsLargeScreens(
+ sa.getInteger(R.styleable.AndroidManifestSupportsScreens_largeScreens, 1))
+ .setSupportsXLargeScreens(
+ sa.getInteger(R.styleable.AndroidManifestSupportsScreens_xlargeScreens, 1))
+ .setResizeable(
+ sa.getInteger(R.styleable.AndroidManifestSupportsScreens_resizeable, 1))
+ .setAnyDensity(
+ sa.getInteger(R.styleable.AndroidManifestSupportsScreens_anyDensity, 1))
+ .setRequiresSmallestWidthDp(requiresSmallestWidthDp)
+ .setCompatibleWidthLimitDp(compatibleWidthLimitDp)
+ .setLargestWidthLimitDp(largestWidthLimitDp);
+
+ sa.recycle();
+
+ XmlUtils.skipCurrentTag(parser);
+ return true;
+ }
+
+ private static ParseResult parseInstrumentation(
+ ParseInput parseInput,
+ ParsingPackage parsingPackage,
+ Resources res,
+ XmlResourceParser parser
+ ) throws XmlPullParserException, IOException {
+ // TODO(b/135203078): Remove, replace with ParseResult
+ String[] outError = new String[1];
+
+ ComponentParseUtils.ParsedInstrumentation parsedInstrumentation =
+ ComponentParseUtils.parseInstrumentation(parsingPackage,
+ res, parser, outError);
+
+ if (parsedInstrumentation == null || outError[0] != null) {
+ return parseInput.error(
+ PackageManager.INSTALL_PARSE_FAILED_MANIFEST_MALFORMED,
+ outError[0]
+ );
+ }
+
+ parsingPackage.addInstrumentation(parsedInstrumentation);
+
+ return parseInput.success(parsingPackage);
+ }
+
+ private static boolean parseOriginalPackage(
+ ParsingPackage parsingPackage,
+ Resources res,
+ XmlResourceParser parser
+ ) throws IOException, XmlPullParserException {
+ TypedArray sa = res.obtainAttributes(parser,
+ R.styleable.AndroidManifestOriginalPackage);
+
+ String orig = sa.getNonConfigurationString(
+ R.styleable.AndroidManifestOriginalPackage_name,
+ 0);
+ if (!parsingPackage.getPackageName().equals(orig)) {
+ if (parsingPackage.getOriginalPackages() == null) {
+ parsingPackage.setRealPackage(parsingPackage.getPackageName());
+ }
+ parsingPackage.addOriginalPackage(orig);
+ }
+
+ sa.recycle();
+
+ XmlUtils.skipCurrentTag(parser);
+ return true;
+ }
+
+ private static boolean parseAdoptPermissions(
+ ParsingPackage parsingPackage,
+ Resources res,
+ XmlResourceParser parser
+ ) throws IOException, XmlPullParserException {
+ TypedArray sa = res.obtainAttributes(parser,
+ R.styleable.AndroidManifestOriginalPackage);
+
+ String name = sa.getNonConfigurationString(
+ R.styleable.AndroidManifestOriginalPackage_name,
+ 0);
+
+ sa.recycle();
+
+ if (name != null) {
+ parsingPackage.addAdoptPermission(name);
+ }
+
+ XmlUtils.skipCurrentTag(parser);
+ return true;
+ }
+
+ private static void convertNewPermissions(
+ ParsingPackage packageToParse) {
+ final int NP = PackageParser.NEW_PERMISSIONS.length;
+ StringBuilder newPermsMsg = null;
+ for (int ip = 0; ip < NP; ip++) {
+ final PackageParser.NewPermissionInfo npi
+ = PackageParser.NEW_PERMISSIONS[ip];
+ if (packageToParse.getTargetSdkVersion() >= npi.sdkVersion) {
+ break;
+ }
+ if (!packageToParse.getRequestedPermissions().contains(npi.name)) {
+ if (newPermsMsg == null) {
+ newPermsMsg = new StringBuilder(128);
+ newPermsMsg.append(packageToParse.getPackageName());
+ newPermsMsg.append(": compat added ");
+ } else {
+ newPermsMsg.append(' ');
+ }
+ newPermsMsg.append(npi.name);
+ packageToParse.addRequestedPermission(npi.name);
+ packageToParse.addImplicitPermission(npi.name);
+ }
+ }
+ if (newPermsMsg != null) {
+ Slog.i(TAG, newPermsMsg.toString());
+ }
+ }
+
+ private static void convertSplitPermissions(ParsingPackage packageToParse) {
+ List<SplitPermissionInfoParcelable> splitPermissions;
+
+ try {
+ splitPermissions = ActivityThread.getPermissionManager().getSplitPermissions();
+ } catch (RemoteException e) {
+ throw e.rethrowFromSystemServer();
+ }
+
+ final int listSize = splitPermissions.size();
+ for (int is = 0; is < listSize; is++) {
+ final SplitPermissionInfoParcelable spi = splitPermissions.get(is);
+ List<String> requestedPermissions = packageToParse.getRequestedPermissions();
+ if (packageToParse.getTargetSdkVersion() >= spi.getTargetSdk()
+ || !requestedPermissions.contains(spi.getSplitPermission())) {
+ continue;
+ }
+ final List<String> newPerms = spi.getNewPermissions();
+ for (int in = 0; in < newPerms.size(); in++) {
+ final String perm = newPerms.get(in);
+ if (!requestedPermissions.contains(perm)) {
+ packageToParse.addRequestedPermission(perm);
+ packageToParse.addImplicitPermission(perm);
+ }
+ }
+ }
+ }
+
+ private static boolean checkOverlayRequiredSystemProperty(String propName, String propValue) {
+ if (TextUtils.isEmpty(propName) || TextUtils.isEmpty(propValue)) {
+ if (!TextUtils.isEmpty(propName) || !TextUtils.isEmpty(propValue)) {
+ // malformed condition - incomplete
+ Slog.w(TAG, "Disabling overlay - incomplete property :'" + propName
+ + "=" + propValue + "' - require both requiredSystemPropertyName"
+ + " AND requiredSystemPropertyValue to be specified.");
+ return false;
+ }
+ // no valid condition set - so no exclusion criteria, overlay will be included.
+ return true;
+ }
+
+ // check property value - make sure it is both set and equal to expected value
+ final String currValue = SystemProperties.get(propName);
+ return (currValue != null && currValue.equals(propValue));
+ }
+
+ /**
+ * This is a pre-density application which will get scaled - instead of being pixel perfect.
+ * This type of application is not resizable.
+ *
+ * @param parsingPackage The package which needs to be marked as unresizable.
+ */
+ private static void adjustPackageToBeUnresizeableAndUnpipable(
+ ParsingPackage parsingPackage) {
+ if (parsingPackage.getActivities() != null) {
+ for (ComponentParseUtils.ParsedActivity a : parsingPackage.getActivities()) {
+ a.resizeMode = RESIZE_MODE_UNRESIZEABLE;
+ a.flags &= ~FLAG_SUPPORTS_PICTURE_IN_PICTURE;
+ }
+ }
+ }
+
+ private static String validateName(String name, boolean requireSeparator,
+ boolean requireFilename) {
+ final int N = name.length();
+ boolean hasSep = false;
+ boolean front = true;
+ for (int i = 0; i < N; i++) {
+ final char c = name.charAt(i);
+ if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) {
+ front = false;
+ continue;
+ }
+ if (!front) {
+ if ((c >= '0' && c <= '9') || c == '_') {
+ continue;
+ }
+ }
+ if (c == '.') {
+ hasSep = true;
+ front = true;
+ continue;
+ }
+ return "bad character '" + c + "'";
+ }
+ if (requireFilename && !FileUtils.isValidExtFilename(name)) {
+ return "Invalid filename";
+ }
+ return hasSep || !requireSeparator
+ ? null : "must have at least one '.' separator";
+ }
+
+ public static Bundle parseMetaData(
+ ParsingPackage parsingPackage,
+ Resources res,
+ XmlResourceParser parser, Bundle data, String[] outError)
+ throws XmlPullParserException, IOException {
+
+ TypedArray sa = res.obtainAttributes(parser,
+ R.styleable.AndroidManifestMetaData);
+
+ if (data == null) {
+ data = new Bundle();
+ }
+
+ String name = sa.getNonConfigurationString(
+ R.styleable.AndroidManifestMetaData_name, 0);
+ if (name == null) {
+ outError[0] = "<meta-data> requires an android:name attribute";
+ sa.recycle();
+ return null;
+ }
+
+ name = name.intern();
+
+ TypedValue v = sa.peekValue(
+ R.styleable.AndroidManifestMetaData_resource);
+ if (v != null && v.resourceId != 0) {
+ //Slog.i(TAG, "Meta data ref " + name + ": " + v);
+ data.putInt(name, v.resourceId);
+ } else {
+ v = sa.peekValue(
+ R.styleable.AndroidManifestMetaData_value);
+ //Slog.i(TAG, "Meta data " + name + ": " + v);
+ if (v != null) {
+ if (v.type == TypedValue.TYPE_STRING) {
+ CharSequence cs = v.coerceToString();
+ data.putString(name, cs != null ? cs.toString() : null);
+ } else if (v.type == TypedValue.TYPE_INT_BOOLEAN) {
+ data.putBoolean(name, v.data != 0);
+ } else if (v.type >= TypedValue.TYPE_FIRST_INT
+ && v.type <= TypedValue.TYPE_LAST_INT) {
+ data.putInt(name, v.data);
+ } else if (v.type == TypedValue.TYPE_FLOAT) {
+ data.putFloat(name, v.getFloat());
+ } else {
+ if (!PackageParser.RIGID_PARSER) {
+ Slog.w(TAG,
+ "<meta-data> only supports string, integer, float, color, "
+ + "boolean, and resource reference types: "
+ + parser.getName() + " at "
+ + parsingPackage.getBaseCodePath() + " "
+ + parser.getPositionDescription());
+ } else {
+ outError[0] =
+ "<meta-data> only supports string, integer, float, color, "
+ + "boolean, and resource reference types";
+ data = null;
+ }
+ }
+ } else {
+ outError[0] = "<meta-data> requires an android:value or android:resource attribute";
+ data = null;
+ }
+ }
+
+ sa.recycle();
+
+ XmlUtils.skipCurrentTag(parser);
+
+ return data;
+ }
+
+ /**
+ * Collect certificates from all the APKs described in the given package,
+ * populating {@link AndroidPackageWrite#setSigningDetails(SigningDetails)}. Also asserts that
+ * all APK contents are signed correctly and consistently.
+ */
+ public static void collectCertificates(AndroidPackage pkg, boolean skipVerify)
+ throws PackageParserException {
+ pkg.mutate().setSigningDetails(SigningDetails.UNKNOWN);
+
+ Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "collectCertificates");
+ try {
+ pkg.mutate().setSigningDetails(collectCertificates(
+ pkg.getBaseCodePath(),
+ skipVerify,
+ pkg.isStaticSharedLibrary(),
+ pkg.getSigningDetails()
+ ));
+
+ String[] splitCodePaths = pkg.getSplitCodePaths();
+ if (!ArrayUtils.isEmpty(splitCodePaths)) {
+ for (int i = 0; i < splitCodePaths.length; i++) {
+ pkg.mutate().setSigningDetails(collectCertificates(
+ splitCodePaths[i],
+ skipVerify,
+ pkg.isStaticSharedLibrary(),
+ pkg.getSigningDetails()
+ ));
+ }
+ }
+ } finally {
+ Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
+ }
+ }
+
+ public static SigningDetails collectCertificates(
+ String baseCodePath,
+ boolean skipVerify,
+ boolean isStaticSharedLibrary,
+ @NonNull SigningDetails existingSigningDetails
+ ) throws PackageParserException {
+ int minSignatureScheme = SigningDetails.SignatureSchemeVersion.JAR;
+ if (isStaticSharedLibrary) {
+ // must use v2 signing scheme
+ minSignatureScheme = SigningDetails.SignatureSchemeVersion.SIGNING_BLOCK_V2;
+ }
+ SigningDetails verified;
+ if (skipVerify) {
+ // systemDir APKs are already trusted, save time by not verifying
+ verified = ApkSignatureVerifier.unsafeGetCertsWithoutVerification(
+ baseCodePath, minSignatureScheme);
+ } else {
+ verified = ApkSignatureVerifier.verify(baseCodePath, minSignatureScheme);
+ }
+
+ // Verify that entries are signed consistently with the first pkg
+ // we encountered. Note that for splits, certificates may have
+ // already been populated during an earlier parse of a base APK.
+ if (existingSigningDetails == SigningDetails.UNKNOWN) {
+ return verified;
+ } else {
+ if (!Signature.areExactMatch(existingSigningDetails.signatures, verified.signatures)) {
+ throw new PackageParserException(
+ INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES,
+ baseCodePath + " has mismatched certificates");
+ }
+
+ return existingSigningDetails;
+ }
+ }
+
+ @Nullable
+ public static String buildClassName(String pkg, CharSequence clsSeq) {
+ if (clsSeq == null || clsSeq.length() <= 0) {
+ return null;
+ }
+ String cls = clsSeq.toString();
+ char c = cls.charAt(0);
+ if (c == '.') {
+ return pkg + cls;
+ }
+ if (cls.indexOf('.') < 0) {
+ StringBuilder b = new StringBuilder(pkg);
+ b.append('.');
+ b.append(cls);
+ return b.toString();
+ }
+ return cls;
+ }
+
+ public interface ParseInput {
+ ParseResult success(ParsingPackage result);
+
+ ParseResult error(int parseError);
+
+ ParseResult error(int parseError, String errorMessage);
+ }
+
+ public static class ParseResult implements ParseInput {
+
+ private static final boolean DEBUG_FILL_STACK_TRACE = false;
+
+ private ParsingPackage result;
+
+ private int parseError;
+ private String errorMessage;
+
+ public ParseInput reset() {
+ this.result = null;
+ this.parseError = PackageManager.INSTALL_SUCCEEDED;
+ this.errorMessage = null;
+ return this;
+ }
+
+ @Override
+ public ParseResult success(ParsingPackage result) {
+ if (parseError != PackageManager.INSTALL_SUCCEEDED || errorMessage != null) {
+ throw new IllegalStateException("Cannot set to success after set to error");
+ }
+ this.result = result;
+ return this;
+ }
+
+ @Override
+ public ParseResult error(int parseError) {
+ return error(parseError, null);
+ }
+
+ @Override
+ public ParseResult error(int parseError, String errorMessage) {
+ this.parseError = parseError;
+ this.errorMessage = errorMessage;
+
+ if (DEBUG_FILL_STACK_TRACE) {
+ this.errorMessage += Arrays.toString(new Exception().getStackTrace());
+ }
+
+ return this;
+ }
+
+ public ParsingPackage getResultAndNull() {
+ ParsingPackage result = this.result;
+ this.result = null;
+ return result;
+ }
+
+ public boolean isSuccess() {
+ return parseError == PackageManager.INSTALL_SUCCEEDED;
+ }
+
+ public int getParseError() {
+ return parseError;
+ }
+
+ public String getErrorMessage() {
+ return errorMessage;
+ }
+ }
+}
diff --git a/core/java/android/content/pm/parsing/ComponentParseUtils.java b/core/java/android/content/pm/parsing/ComponentParseUtils.java
new file mode 100644
index 000000000000..adf2a4f85780
--- /dev/null
+++ b/core/java/android/content/pm/parsing/ComponentParseUtils.java
@@ -0,0 +1,3289 @@
+/*
+ * Copyright (C) 2019 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 android.content.pm.parsing;
+
+import static android.content.pm.ActivityInfo.FLAG_ALWAYS_FOCUSABLE;
+import static android.content.pm.ActivityInfo.FLAG_SUPPORTS_PICTURE_IN_PICTURE;
+import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE;
+import static android.content.pm.ActivityInfo.RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION;
+import static android.content.pm.ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
+import static android.view.WindowManager.LayoutParams.ROTATION_ANIMATION_UNSPECIFIED;
+
+import android.annotation.CallSuper;
+import android.annotation.UnsupportedAppUsage;
+import android.app.ActivityTaskManager;
+import android.content.ComponentName;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.content.pm.ActivityInfo;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageParser;
+import android.content.pm.PathPermission;
+import android.content.pm.PermissionInfo;
+import android.content.pm.ProviderInfo;
+import android.content.pm.ServiceInfo;
+import android.content.res.Configuration;
+import android.content.res.Resources;
+import android.content.res.TypedArray;
+import android.content.res.XmlResourceParser;
+import android.os.Build;
+import android.os.Bundle;
+import android.os.Parcel;
+import android.os.Parcelable;
+import android.os.PatternMatcher;
+import android.text.TextUtils;
+import android.util.AttributeSet;
+import android.util.Log;
+import android.util.Slog;
+import android.util.SparseArray;
+import android.util.TypedValue;
+import android.view.Gravity;
+
+import com.android.internal.R;
+import com.android.internal.util.XmlUtils;
+
+import org.xmlpull.v1.XmlPullParser;
+import org.xmlpull.v1.XmlPullParserException;
+
+import java.io.IOException;
+import java.lang.reflect.Constructor;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Objects;
+
+/**
+ * TODO(b/135203078): Move the inner classes out to separate files.
+ * TODO(b/135203078): Expose inner classes as immutable through interface methods.
+ *
+ * @hide
+ */
+public class ComponentParseUtils {
+
+ private static final String TAG = ApkParseUtils.TAG;
+
+ // TODO(b/135203078): None of this class's subclasses do anything. Remove in favor of base?
+ public static class ParsedIntentInfo extends IntentFilter {
+
+ /**
+ * <p>
+ * Implementation note: The serialized form for the intent list also contains the name
+ * of the concrete class that's stored in the list, and assumes that every element of the
+ * list is of the same type. This is very similar to the original parcelable mechanism.
+ * We cannot use that directly because IntentInfo extends IntentFilter, which is parcelable
+ * and is public API. It also declares Parcelable related methods as final which means
+ * we can't extend them. The approach of using composition instead of inheritance leads to
+ * a large set of cascading changes in the PackageManagerService, which seem undesirable.
+ *
+ * <p>
+ * <b>WARNING: </b> The list of objects returned by this function might need to be fixed up
+ * to make sure their owner fields are consistent. See {@code fixupOwner}.
+ */
+ public static void writeIntentsList(List<? extends ParsedIntentInfo> list, Parcel out,
+ int flags) {
+ if (list == null) {
+ out.writeInt(-1);
+ return;
+ }
+
+ final int size = list.size();
+ out.writeInt(size);
+
+ // Don't bother writing the component name if the list is empty.
+ if (size > 0) {
+ ParsedIntentInfo info = list.get(0);
+ out.writeString(info.getClass().getName());
+
+ for (int i = 0; i < size; i++) {
+ list.get(i).writeIntentInfoToParcel(out, flags);
+ }
+ }
+ }
+
+ public static <T extends ParsedIntentInfo> ArrayList<T> createIntentsList(Parcel in) {
+ int size = in.readInt();
+ if (size == -1) {
+ return null;
+ }
+
+ if (size == 0) {
+ return new ArrayList<>(0);
+ }
+
+ String className = in.readString();
+ final ArrayList<T> intentsList;
+ try {
+ final Class<T> cls = (Class<T>) Class.forName(className);
+ final Constructor<T> cons = cls.getConstructor(Parcel.class);
+
+ intentsList = new ArrayList<>(size);
+ for (int i = 0; i < size; ++i) {
+ intentsList.add(cons.newInstance(in));
+ }
+ } catch (ReflectiveOperationException ree) {
+ throw new AssertionError("Unable to construct intent list for: "
+ + className, ree);
+ }
+
+ return intentsList;
+ }
+
+ protected String packageName;
+ protected final String className;
+
+ public boolean hasDefault;
+ public int labelRes;
+ public CharSequence nonLocalizedLabel;
+ public int icon;
+
+ protected List<String> rawDataTypes;
+
+ public void addRawDataType(String dataType) throws MalformedMimeTypeException {
+ if (rawDataTypes == null) {
+ rawDataTypes = new ArrayList<>();
+ }
+
+ rawDataTypes.add(dataType);
+ addDataType(dataType);
+ }
+
+ public ParsedIntentInfo(String packageName, String className) {
+ this.packageName = packageName;
+ this.className = className;
+ }
+
+ public ParsedIntentInfo(Parcel in) {
+ super(in);
+ packageName = in.readString();
+ className = in.readString();
+ hasDefault = (in.readInt() == 1);
+ labelRes = in.readInt();
+ nonLocalizedLabel = in.readCharSequence();
+ icon = in.readInt();
+ }
+
+ public void writeIntentInfoToParcel(Parcel dest, int flags) {
+ super.writeToParcel(dest, flags);
+ dest.writeString(packageName);
+ dest.writeString(className);
+ dest.writeInt(hasDefault ? 1 : 0);
+ dest.writeInt(labelRes);
+ dest.writeCharSequence(nonLocalizedLabel);
+ dest.writeInt(icon);
+ }
+
+ public String getPackageName() {
+ return packageName;
+ }
+
+ public String getClassName() {
+ return className;
+ }
+ }
+
+ public static class ParsedActivityIntentInfo extends ParsedIntentInfo {
+
+ public ParsedActivityIntentInfo(String packageName, String className) {
+ super(packageName, className);
+ }
+
+ public ParsedActivityIntentInfo(Parcel in) {
+ super(in);
+ }
+
+ public static final Creator<ParsedActivityIntentInfo> CREATOR =
+ new Creator<ParsedActivityIntentInfo>() {
+ @Override
+ public ParsedActivityIntentInfo createFromParcel(Parcel source) {
+ return new ParsedActivityIntentInfo(source);
+ }
+
+ @Override
+ public ParsedActivityIntentInfo[] newArray(int size) {
+ return new ParsedActivityIntentInfo[size];
+ }
+ };
+ }
+
+ public static class ParsedServiceIntentInfo extends ParsedIntentInfo {
+
+ public ParsedServiceIntentInfo(String packageName, String className) {
+ super(packageName, className);
+ }
+
+ public ParsedServiceIntentInfo(Parcel in) {
+ super(in);
+ }
+
+ public static final Creator<ParsedServiceIntentInfo> CREATOR =
+ new Creator<ParsedServiceIntentInfo>() {
+ @Override
+ public ParsedServiceIntentInfo createFromParcel(Parcel source) {
+ return new ParsedServiceIntentInfo(source);
+ }
+
+ @Override
+ public ParsedServiceIntentInfo[] newArray(int size) {
+ return new ParsedServiceIntentInfo[size];
+ }
+ };
+ }
+
+ public static class ParsedProviderIntentInfo extends ParsedIntentInfo {
+
+ public ParsedProviderIntentInfo(String packageName, String className) {
+ super(packageName, className);
+ }
+
+ public ParsedProviderIntentInfo(Parcel in) {
+ super(in);
+ }
+
+ public static final Creator<ParsedProviderIntentInfo> CREATOR =
+ new Creator<ParsedProviderIntentInfo>() {
+ @Override
+ public ParsedProviderIntentInfo createFromParcel(Parcel source) {
+ return new ParsedProviderIntentInfo(source);
+ }
+
+ @Override
+ public ParsedProviderIntentInfo[] newArray(int size) {
+ return new ParsedProviderIntentInfo[size];
+ }
+ };
+ }
+
+ public static class ParsedQueriesIntentInfo extends ParsedIntentInfo {
+
+ public ParsedQueriesIntentInfo(String packageName, String className) {
+ super(packageName, className);
+ }
+
+ public ParsedQueriesIntentInfo(Parcel in) {
+ super(in);
+ }
+
+ public static final Creator<ParsedQueriesIntentInfo> CREATOR =
+ new Creator<ParsedQueriesIntentInfo>() {
+ @Override
+ public ParsedQueriesIntentInfo createFromParcel(Parcel source) {
+ return new ParsedQueriesIntentInfo(source);
+ }
+
+ @Override
+ public ParsedQueriesIntentInfo[] newArray(int size) {
+ return new ParsedQueriesIntentInfo[size];
+ }
+ };
+ }
+
+ public static class ParsedComponent<IntentInfoType extends ParsedIntentInfo> implements
+ Parcelable {
+
+ // TODO(b/135203078): Replace with "name", as not all usages are an actual class
+ public String className;
+ public int icon;
+ public int labelRes;
+ public CharSequence nonLocalizedLabel;
+ public int logo;
+ public int banner;
+
+ public int descriptionRes;
+
+ // TODO(b/135203078): Make subclass that contains these fields only for the necessary
+ // subtypes
+ protected boolean enabled = true;
+ protected boolean directBootAware;
+ public int flags;
+
+ private String packageName;
+ private String splitName;
+
+ // TODO(b/135203078): Make nullable
+ public List<IntentInfoType> intents = new ArrayList<>();
+
+ private transient ComponentName componentName;
+
+ protected Bundle metaData;
+
+ public void setSplitName(String splitName) {
+ this.splitName = splitName;
+ }
+
+ public String getSplitName() {
+ return splitName;
+ }
+
+ @CallSuper
+ public void setPackageName(String packageName) {
+ this.packageName = packageName;
+ this.componentName = null;
+ }
+
+ void setPackageNameInternal(String packageName) {
+ this.packageName = packageName;
+ this.componentName = null;
+ }
+
+ public String getPackageName() {
+ return packageName;
+ }
+
+ public final boolean isDirectBootAware() {
+ return directBootAware;
+ }
+
+ public final boolean isEnabled() {
+ return enabled;
+ }
+
+ public final String getName() {
+ return className;
+ }
+
+ public final Bundle getMetaData() {
+ return metaData;
+ }
+
+ @UnsupportedAppUsage
+ public ComponentName getComponentName() {
+ if (componentName != null) {
+ return componentName;
+ }
+ if (className != null) {
+ componentName = new ComponentName(getPackageName(),
+ className);
+ }
+ return componentName;
+ }
+
+ public void setFrom(ParsedComponent other) {
+ this.metaData = other.metaData;
+ this.className = other.className;
+ this.icon = other.icon;
+ this.labelRes = other.labelRes;
+ this.nonLocalizedLabel = other.nonLocalizedLabel;
+ this.logo = other.logo;
+ this.banner = other.banner;
+
+ this.descriptionRes = other.descriptionRes;
+
+ this.enabled = other.enabled;
+ this.directBootAware = other.directBootAware;
+ this.flags = other.flags;
+
+ this.setPackageName(other.packageName);
+ this.setSplitName(other.getSplitName());
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeString(this.className);
+ dest.writeInt(this.icon);
+ dest.writeInt(this.labelRes);
+ dest.writeCharSequence(this.nonLocalizedLabel);
+ dest.writeInt(this.logo);
+ dest.writeInt(this.banner);
+ dest.writeInt(this.descriptionRes);
+ dest.writeBoolean(this.enabled);
+ dest.writeBoolean(this.directBootAware);
+ dest.writeInt(this.flags);
+ dest.writeString(this.packageName);
+ dest.writeString(this.splitName);
+ ParsedIntentInfo.writeIntentsList(this.intents, dest, flags);
+ dest.writeBundle(this.metaData);
+ }
+
+ public ParsedComponent() {
+ }
+
+ protected ParsedComponent(Parcel in) {
+ // We use the boot classloader for all classes that we load.
+ final ClassLoader boot = Object.class.getClassLoader();
+ this.className = in.readString();
+ this.icon = in.readInt();
+ this.labelRes = in.readInt();
+ this.nonLocalizedLabel = in.readCharSequence();
+ this.logo = in.readInt();
+ this.banner = in.readInt();
+ this.descriptionRes = in.readInt();
+ this.enabled = in.readByte() != 0;
+ this.directBootAware = in.readByte() != 0;
+ this.flags = in.readInt();
+ this.packageName = in.readString();
+ this.splitName = in.readString();
+ this.intents = ParsedIntentInfo.createIntentsList(in);
+ this.metaData = in.readBundle(boot);
+ }
+ }
+
+ // TODO(b/135203078): Document this. Maybe split out ParsedComponent to be actual components
+ // that can have their own processes, rather than something like permission which cannot.
+ public static class ParsedMainComponent<IntentInfoType extends ParsedIntentInfo> extends
+ ParsedComponent<IntentInfoType> {
+
+ private String processName;
+ private String permission;
+
+ public void setProcessName(String appProcessName, String processName) {
+ // TODO(b/135203078): Is this even necessary anymore?
+ this.processName = TextUtils.safeIntern(
+ processName == null ? appProcessName : processName);
+ }
+
+ public String getProcessName() {
+ return processName;
+ }
+
+ public void setPermission(String permission) {
+ this.permission = TextUtils.safeIntern(permission);
+ }
+
+ public String getPermission() {
+ return permission;
+ }
+
+ @Override
+ public void setFrom(ParsedComponent other) {
+ super.setFrom(other);
+ if (other instanceof ParsedMainComponent) {
+ ParsedMainComponent otherMainComponent = (ParsedMainComponent) other;
+ this.setProcessName(otherMainComponent.getProcessName(),
+ otherMainComponent.getProcessName());
+ this.setPermission(otherMainComponent.getPermission());
+ }
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ super.writeToParcel(dest, flags);
+ dest.writeString(this.processName);
+ dest.writeString(this.permission);
+ }
+
+ public ParsedMainComponent() {
+ }
+
+ protected ParsedMainComponent(Parcel in) {
+ super(in);
+ this.processName = TextUtils.safeIntern(in.readString());
+ this.permission = TextUtils.safeIntern(in.readString());
+ }
+
+ public static final Creator<ParsedMainComponent> CREATOR =
+ new Creator<ParsedMainComponent>() {
+ @Override
+ public ParsedMainComponent createFromParcel(Parcel source) {
+ return new ParsedMainComponent(source);
+ }
+
+ @Override
+ public ParsedMainComponent[] newArray(int size) {
+ return new ParsedMainComponent[size];
+ }
+ };
+ }
+
+ public static class ParsedActivity extends ParsedMainComponent<ParsedActivityIntentInfo>
+ implements Parcelable {
+
+ public boolean exported;
+ public int theme;
+ public int uiOptions;
+
+ public String targetActivity;
+
+ public String parentActivityName;
+ public String taskAffinity;
+ public int privateFlags;
+
+ public int launchMode;
+ public int documentLaunchMode;
+ public int maxRecents;
+ public int configChanges;
+ public int softInputMode;
+ public int persistableMode;
+ public int lockTaskLaunchMode;
+
+ public int screenOrientation = ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
+ public int resizeMode = ActivityInfo.RESIZE_MODE_RESIZEABLE;
+
+ public float maxAspectRatio;
+ public boolean hasMaxAspectRatio;
+
+ public float minAspectRatio;
+ public boolean hasMinAspectRatio;
+
+ public String requestedVrComponent;
+ public int rotationAnimation = -1;
+ public int colorMode;
+ public int order;
+
+ public ActivityInfo.WindowLayout windowLayout;
+
+ @Override
+ public void setPackageName(String packageName) {
+ super.setPackageName(packageName);
+ for (ParsedIntentInfo intent : this.intents) {
+ intent.packageName = packageName;
+ }
+ }
+
+ public boolean hasMaxAspectRatio() {
+ return hasMaxAspectRatio;
+ }
+
+ public boolean hasMinAspectRatio() {
+ return hasMinAspectRatio;
+ }
+
+ public void setMaxAspectRatio(int resizeMode, float maxAspectRatio) {
+ if (resizeMode == ActivityInfo.RESIZE_MODE_RESIZEABLE
+ || resizeMode == ActivityInfo.RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION) {
+ // Resizeable activities can be put in any aspect ratio.
+ return;
+ }
+
+ if (maxAspectRatio < 1.0f && maxAspectRatio != 0) {
+ // Ignore any value lesser than 1.0.
+ return;
+ }
+
+ this.maxAspectRatio = maxAspectRatio;
+ hasMaxAspectRatio = true;
+ }
+
+ public void setMinAspectRatio(int resizeMode, float minAspectRatio) {
+ if (resizeMode == RESIZE_MODE_RESIZEABLE
+ || resizeMode == RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION) {
+ // Resizeable activities can be put in any aspect ratio.
+ return;
+ }
+
+ if (minAspectRatio < 1.0f && minAspectRatio != 0) {
+ // Ignore any value lesser than 1.0.
+ return;
+ }
+
+ this.minAspectRatio = minAspectRatio;
+ hasMinAspectRatio = true;
+ }
+
+ public void addIntent(ParsedActivityIntentInfo intent) {
+ this.intents.add(intent);
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ super.writeToParcel(dest, flags);
+ dest.writeBoolean(this.exported);
+ dest.writeInt(this.theme);
+ dest.writeInt(this.uiOptions);
+ dest.writeString(this.targetActivity);
+ dest.writeString(this.parentActivityName);
+ dest.writeString(this.taskAffinity);
+ dest.writeInt(this.privateFlags);
+ dest.writeInt(this.launchMode);
+ dest.writeInt(this.documentLaunchMode);
+ dest.writeInt(this.maxRecents);
+ dest.writeInt(this.configChanges);
+ dest.writeInt(this.softInputMode);
+ dest.writeInt(this.persistableMode);
+ dest.writeInt(this.lockTaskLaunchMode);
+ dest.writeInt(this.screenOrientation);
+ dest.writeInt(this.resizeMode);
+ dest.writeFloat(this.maxAspectRatio);
+ dest.writeBoolean(this.hasMaxAspectRatio);
+ dest.writeFloat(this.minAspectRatio);
+ dest.writeBoolean(this.hasMinAspectRatio);
+ dest.writeString(this.requestedVrComponent);
+ dest.writeInt(this.rotationAnimation);
+ dest.writeInt(this.colorMode);
+ dest.writeInt(this.order);
+ dest.writeBundle(this.metaData);
+
+ if (windowLayout != null) {
+ dest.writeInt(1);
+ dest.writeInt(windowLayout.width);
+ dest.writeFloat(windowLayout.widthFraction);
+ dest.writeInt(windowLayout.height);
+ dest.writeFloat(windowLayout.heightFraction);
+ dest.writeInt(windowLayout.gravity);
+ dest.writeInt(windowLayout.minWidth);
+ dest.writeInt(windowLayout.minHeight);
+ } else {
+ dest.writeInt(0);
+ }
+ }
+
+ public ParsedActivity() {
+ }
+
+ protected ParsedActivity(Parcel in) {
+ super(in);
+ this.exported = in.readByte() != 0;
+ this.theme = in.readInt();
+ this.uiOptions = in.readInt();
+ this.targetActivity = in.readString();
+ this.parentActivityName = in.readString();
+ this.taskAffinity = in.readString();
+ this.privateFlags = in.readInt();
+ this.launchMode = in.readInt();
+ this.documentLaunchMode = in.readInt();
+ this.maxRecents = in.readInt();
+ this.configChanges = in.readInt();
+ this.softInputMode = in.readInt();
+ this.persistableMode = in.readInt();
+ this.lockTaskLaunchMode = in.readInt();
+ this.screenOrientation = in.readInt();
+ this.resizeMode = in.readInt();
+ this.maxAspectRatio = in.readFloat();
+ this.hasMaxAspectRatio = in.readByte() != 0;
+ this.minAspectRatio = in.readFloat();
+ this.hasMinAspectRatio = in.readByte() != 0;
+ this.requestedVrComponent = in.readString();
+ this.rotationAnimation = in.readInt();
+ this.colorMode = in.readInt();
+ this.order = in.readInt();
+ this.metaData = in.readBundle();
+ if (in.readInt() == 1) {
+ windowLayout = new ActivityInfo.WindowLayout(in);
+ }
+ }
+
+ public static final Creator<ParsedActivity> CREATOR = new Creator<ParsedActivity>() {
+ @Override
+ public ParsedActivity createFromParcel(Parcel source) {
+ return new ParsedActivity(source);
+ }
+
+ @Override
+ public ParsedActivity[] newArray(int size) {
+ return new ParsedActivity[size];
+ }
+ };
+ }
+
+ public static class ParsedService extends ParsedMainComponent<ParsedServiceIntentInfo> {
+
+ public boolean exported;
+ public int flags;
+ public int foregroundServiceType;
+ public int order;
+
+ @Override
+ public void setPackageName(String packageName) {
+ super.setPackageName(packageName);
+ for (ParsedIntentInfo intent : this.intents) {
+ intent.packageName = packageName;
+ }
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ super.writeToParcel(dest, flags);
+ dest.writeBoolean(this.exported);
+ dest.writeBundle(this.metaData);
+ dest.writeInt(this.flags);
+ dest.writeInt(this.foregroundServiceType);
+ dest.writeInt(this.order);
+ }
+
+ public ParsedService() {
+ }
+
+ protected ParsedService(Parcel in) {
+ super(in);
+ this.exported = in.readByte() != 0;
+ this.metaData = in.readBundle();
+ this.flags = in.readInt();
+ this.foregroundServiceType = in.readInt();
+ this.order = in.readInt();
+ }
+
+ public static final Creator<ParsedService> CREATOR = new Creator<ParsedService>() {
+ @Override
+ public ParsedService createFromParcel(Parcel source) {
+ return new ParsedService(source);
+ }
+
+ @Override
+ public ParsedService[] newArray(int size) {
+ return new ParsedService[size];
+ }
+ };
+ }
+
+ public static class ParsedProvider extends ParsedMainComponent<ParsedProviderIntentInfo> {
+
+ protected boolean exported;
+ protected int flags;
+ protected int order;
+ private String authority;
+ protected boolean isSyncable;
+ private String readPermission;
+ private String writePermission;
+ protected boolean grantUriPermissions;
+ protected boolean forceUriPermissions;
+ protected boolean multiProcess;
+ protected int initOrder;
+ protected PatternMatcher[] uriPermissionPatterns;
+ protected PathPermission[] pathPermissions;
+
+ protected void setFrom(ParsedProvider other) {
+ super.setFrom(other);
+ this.exported = other.exported;
+
+ this.intents.clear();
+ if (other.intents != null) {
+ this.intents.addAll(other.intents);
+ }
+
+ this.flags = other.flags;
+ this.order = other.order;
+ this.setAuthority(other.getAuthority());
+ this.isSyncable = other.isSyncable;
+ this.setReadPermission(other.getReadPermission());
+ this.setWritePermission(other.getWritePermission());
+ this.grantUriPermissions = other.grantUriPermissions;
+ this.forceUriPermissions = other.forceUriPermissions;
+ this.multiProcess = other.multiProcess;
+ this.initOrder = other.initOrder;
+ this.uriPermissionPatterns = other.uriPermissionPatterns;
+ this.pathPermissions = other.pathPermissions;
+ }
+
+ @Override
+ public void setPackageName(String packageName) {
+ super.setPackageName(packageName);
+ for (ParsedIntentInfo intent : this.intents) {
+ intent.packageName = packageName;
+ }
+ }
+
+ public boolean isExported() {
+ return exported;
+ }
+
+ public List<ParsedProviderIntentInfo> getIntents() {
+ return intents;
+ }
+
+ public int getFlags() {
+ return flags;
+ }
+
+ public int getOrder() {
+ return order;
+ }
+
+ public void setAuthority(String authority) {
+ this.authority = TextUtils.safeIntern(authority);
+ }
+
+ public String getAuthority() {
+ return authority;
+ }
+
+ public boolean isSyncable() {
+ return isSyncable;
+ }
+
+ public void setReadPermission(String readPermission) {
+ this.readPermission = TextUtils.safeIntern(readPermission);
+ }
+
+ public String getReadPermission() {
+ return readPermission;
+ }
+
+ public void setWritePermission(String writePermission) {
+ this.writePermission = TextUtils.safeIntern(writePermission);
+ }
+
+ public String getWritePermission() {
+ return writePermission;
+ }
+
+ public boolean isGrantUriPermissions() {
+ return grantUriPermissions;
+ }
+
+ public boolean isForceUriPermissions() {
+ return forceUriPermissions;
+ }
+
+ public boolean isMultiProcess() {
+ return multiProcess;
+ }
+
+ public int getInitOrder() {
+ return initOrder;
+ }
+
+ public PatternMatcher[] getUriPermissionPatterns() {
+ return uriPermissionPatterns;
+ }
+
+ public PathPermission[] getPathPermissions() {
+ return pathPermissions;
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ super.writeToParcel(dest, flags);
+ dest.writeBoolean(this.exported);
+ dest.writeInt(this.flags);
+ dest.writeInt(this.order);
+ dest.writeString(this.authority);
+ dest.writeBoolean(this.isSyncable);
+ dest.writeString(this.readPermission);
+ dest.writeString(this.writePermission);
+ dest.writeBoolean(this.grantUriPermissions);
+ dest.writeBoolean(this.forceUriPermissions);
+ dest.writeBoolean(this.multiProcess);
+ dest.writeInt(this.initOrder);
+ dest.writeTypedArray(this.uriPermissionPatterns, flags);
+ dest.writeTypedArray(this.pathPermissions, flags);
+ }
+
+ public ParsedProvider() {
+ }
+
+ protected ParsedProvider(Parcel in) {
+ super(in);
+ this.exported = in.readByte() != 0;
+ this.flags = in.readInt();
+ this.order = in.readInt();
+ this.authority = TextUtils.safeIntern(in.readString());
+ this.isSyncable = in.readByte() != 0;
+ this.readPermission = TextUtils.safeIntern(in.readString());
+ this.writePermission = TextUtils.safeIntern(in.readString());
+ this.grantUriPermissions = in.readByte() != 0;
+ this.forceUriPermissions = in.readByte() != 0;
+ this.multiProcess = in.readByte() != 0;
+ this.initOrder = in.readInt();
+ this.uriPermissionPatterns = in.createTypedArray(PatternMatcher.CREATOR);
+ this.pathPermissions = in.createTypedArray(PathPermission.CREATOR);
+ }
+
+ public static final Creator<ParsedProvider> CREATOR = new Creator<ParsedProvider>() {
+ @Override
+ public ParsedProvider createFromParcel(Parcel source) {
+ return new ParsedProvider(source);
+ }
+
+ @Override
+ public ParsedProvider[] newArray(int size) {
+ return new ParsedProvider[size];
+ }
+ };
+ }
+
+ public static class ParsedPermission extends ParsedComponent<ParsedIntentInfo> {
+
+ public String backgroundPermission;
+ private String group;
+ public int requestRes;
+ public int protectionLevel;
+ public boolean tree;
+
+ public ParsedPermissionGroup parsedPermissionGroup;
+
+ public void setName(String className) {
+ this.className = className;
+ }
+
+ public void setGroup(String group) {
+ this.group = TextUtils.safeIntern(group);
+ }
+
+ public String getGroup() {
+ return group;
+ }
+
+ public boolean isRuntime() {
+ return protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
+ }
+
+ public boolean isAppOp() {
+ return (protectionLevel & PermissionInfo.PROTECTION_FLAG_APPOP) != 0;
+ }
+
+ @PermissionInfo.Protection
+ public int getProtection() {
+ return protectionLevel & PermissionInfo.PROTECTION_MASK_BASE;
+ }
+
+ public int getProtectionFlags() {
+ return protectionLevel & ~PermissionInfo.PROTECTION_MASK_BASE;
+ }
+
+ public int calculateFootprint() {
+ int size = getName().length();
+ if (nonLocalizedLabel != null) {
+ size += nonLocalizedLabel.length();
+ }
+ return size;
+ }
+
+ public ParsedPermission() {
+ }
+
+ public ParsedPermission(ParsedPermission other) {
+ // TODO(b/135203078): Better way to copy this? Maybe refactor to the point where copy
+ // isn't needed.
+ this.className = other.className;
+ this.icon = other.icon;
+ this.labelRes = other.labelRes;
+ this.nonLocalizedLabel = other.nonLocalizedLabel;
+ this.logo = other.logo;
+ this.banner = other.banner;
+ this.descriptionRes = other.descriptionRes;
+ this.enabled = other.enabled;
+ this.directBootAware = other.directBootAware;
+ this.flags = other.flags;
+ this.setSplitName(other.getSplitName());
+ this.setPackageName(other.getPackageName());
+
+ this.intents.addAll(other.intents);
+
+ if (other.metaData != null) {
+ this.metaData = new Bundle();
+ this.metaData.putAll(other.metaData);
+ }
+
+ this.backgroundPermission = other.backgroundPermission;
+ this.setGroup(other.group);
+ this.requestRes = other.requestRes;
+ this.protectionLevel = other.protectionLevel;
+ this.tree = other.tree;
+
+ this.parsedPermissionGroup = other.parsedPermissionGroup;
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ super.writeToParcel(dest, flags);
+ dest.writeString(this.backgroundPermission);
+ dest.writeString(this.group);
+ dest.writeInt(this.requestRes);
+ dest.writeInt(this.protectionLevel);
+ dest.writeBoolean(this.tree);
+ dest.writeParcelable(this.parsedPermissionGroup, flags);
+ }
+
+ protected ParsedPermission(Parcel in) {
+ super(in);
+ // We use the boot classloader for all classes that we load.
+ final ClassLoader boot = Object.class.getClassLoader();
+ this.backgroundPermission = in.readString();
+ this.group = TextUtils.safeIntern(in.readString());
+ this.requestRes = in.readInt();
+ this.protectionLevel = in.readInt();
+ this.tree = in.readBoolean();
+ this.parsedPermissionGroup = in.readParcelable(boot);
+ }
+
+ public static final Creator<ParsedPermission> CREATOR = new Creator<ParsedPermission>() {
+ @Override
+ public ParsedPermission createFromParcel(Parcel source) {
+ return new ParsedPermission(source);
+ }
+
+ @Override
+ public ParsedPermission[] newArray(int size) {
+ return new ParsedPermission[size];
+ }
+ };
+ }
+
+ public static class ParsedPermissionGroup extends ParsedComponent<ParsedIntentInfo> {
+
+ public int requestDetailResourceId;
+ public int backgroundRequestResourceId;
+ public int backgroundRequestDetailResourceId;
+
+ public int requestRes;
+ public int priority;
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ super.writeToParcel(dest, flags);
+ dest.writeInt(this.requestDetailResourceId);
+ dest.writeInt(this.backgroundRequestResourceId);
+ dest.writeInt(this.backgroundRequestDetailResourceId);
+ dest.writeInt(this.requestRes);
+ dest.writeInt(this.priority);
+ }
+
+ public ParsedPermissionGroup() {
+ }
+
+ protected ParsedPermissionGroup(Parcel in) {
+ super(in);
+ this.requestDetailResourceId = in.readInt();
+ this.backgroundRequestResourceId = in.readInt();
+ this.backgroundRequestDetailResourceId = in.readInt();
+ this.requestRes = in.readInt();
+ this.priority = in.readInt();
+ }
+
+ public static final Creator<ParsedPermissionGroup> CREATOR =
+ new Creator<ParsedPermissionGroup>() {
+ @Override
+ public ParsedPermissionGroup createFromParcel(Parcel source) {
+ return new ParsedPermissionGroup(source);
+ }
+
+ @Override
+ public ParsedPermissionGroup[] newArray(int size) {
+ return new ParsedPermissionGroup[size];
+ }
+ };
+ }
+
+ public static class ParsedInstrumentation extends ParsedComponent<ParsedIntentInfo> {
+
+ private String targetPackage;
+ private String targetProcesses;
+ public boolean handleProfiling;
+ public boolean functionalTest;
+
+ public String sourceDir;
+ public String publicSourceDir;
+ public String[] splitNames;
+ public String[] splitSourceDirs;
+ public String[] splitPublicSourceDirs;
+ public SparseArray<int[]> splitDependencies;
+ public String dataDir;
+ public String deviceProtectedDataDir;
+ public String credentialProtectedDataDir;
+ public String primaryCpuAbi;
+ public String secondaryCpuAbi;
+ public String nativeLibraryDir;
+ public String secondaryNativeLibraryDir;
+
+ public ParsedInstrumentation() {
+ }
+
+ public void setTargetPackage(String targetPackage) {
+ this.targetPackage = TextUtils.safeIntern(targetPackage);
+ }
+
+ public String getTargetPackage() {
+ return targetPackage;
+ }
+
+ public void setTargetProcesses(String targetProcesses) {
+ this.targetProcesses = TextUtils.safeIntern(targetProcesses);
+ }
+
+ public String getTargetProcesses() {
+ return targetProcesses;
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ super.writeToParcel(dest, flags);
+ dest.writeString(this.targetPackage);
+ dest.writeString(this.targetProcesses);
+ dest.writeBoolean(this.handleProfiling);
+ dest.writeBoolean(this.functionalTest);
+ dest.writeString(this.sourceDir);
+ dest.writeString(this.publicSourceDir);
+ dest.writeStringArray(this.splitNames);
+ dest.writeStringArray(this.splitSourceDirs);
+ dest.writeStringArray(this.splitPublicSourceDirs);
+ dest.writeSparseArray(this.splitDependencies);
+ dest.writeString(this.dataDir);
+ dest.writeString(this.deviceProtectedDataDir);
+ dest.writeString(this.credentialProtectedDataDir);
+ dest.writeString(this.primaryCpuAbi);
+ dest.writeString(this.secondaryCpuAbi);
+ dest.writeString(this.nativeLibraryDir);
+ dest.writeString(this.secondaryNativeLibraryDir);
+ }
+
+ protected ParsedInstrumentation(Parcel in) {
+ super(in);
+ // We use the boot classloader for all classes that we load.
+ final ClassLoader boot = Object.class.getClassLoader();
+ this.targetPackage = TextUtils.safeIntern(in.readString());
+ this.targetProcesses = TextUtils.safeIntern(in.readString());
+ this.handleProfiling = in.readByte() != 0;
+ this.functionalTest = in.readByte() != 0;
+ this.sourceDir = in.readString();
+ this.publicSourceDir = in.readString();
+ this.splitNames = in.createStringArray();
+ this.splitSourceDirs = in.createStringArray();
+ this.splitPublicSourceDirs = in.createStringArray();
+ this.splitDependencies = in.readSparseArray(boot);
+ this.dataDir = in.readString();
+ this.deviceProtectedDataDir = in.readString();
+ this.credentialProtectedDataDir = in.readString();
+ this.primaryCpuAbi = in.readString();
+ this.secondaryCpuAbi = in.readString();
+ this.nativeLibraryDir = in.readString();
+ this.secondaryNativeLibraryDir = in.readString();
+ }
+
+ public static final Creator<ParsedInstrumentation> CREATOR =
+ new Creator<ParsedInstrumentation>() {
+ @Override
+ public ParsedInstrumentation createFromParcel(Parcel source) {
+ return new ParsedInstrumentation(source);
+ }
+
+ @Override
+ public ParsedInstrumentation[] newArray(int size) {
+ return new ParsedInstrumentation[size];
+ }
+ };
+ }
+
+ public static ParsedActivity parseActivity(
+ String[] separateProcesses,
+ ParsingPackage parsingPackage,
+ Resources res,
+ XmlResourceParser parser, int flags, String[] outError,
+ boolean receiver, boolean hardwareAccelerated)
+ throws XmlPullParserException, IOException {
+
+ TypedArray sa = null;
+ boolean visibleToEphemeral;
+ boolean setExported;
+
+ int targetSdkVersion = parsingPackage.getTargetSdkVersion();
+ String packageName = parsingPackage.getPackageName();
+ String packageProcessName = parsingPackage.getProcessName();
+ ParsedActivity result = new ParsedActivity();
+
+ try {
+ sa = res.obtainAttributes(parser, R.styleable.AndroidManifestActivity);
+
+ String tag = receiver ? "<receiver>" : "<activity>";
+
+ String name = sa.getNonConfigurationString(R.styleable.AndroidManifestActivity_name, 0);
+ if (name == null) {
+ outError[0] = tag + " does not specify android:name";
+ return null;
+ } else {
+ String className = ApkParseUtils.buildClassName(packageName, name);
+ if (PackageManager.APP_DETAILS_ACTIVITY_CLASS_NAME.equals(className)) {
+ outError[0] = tag + " invalid android:name";
+ return null;
+ } else if (className == null) {
+ outError[0] = "Empty class name in package " + packageName;
+ return null;
+ }
+
+ result.className = className;
+ }
+
+ int roundIconVal = PackageParser.sUseRoundIcon ? sa.getResourceId(
+ R.styleable.AndroidManifestActivity_roundIcon, 0) : 0;
+ if (roundIconVal != 0) {
+ result.icon = roundIconVal;
+ result.nonLocalizedLabel = null;
+ } else {
+ int iconVal = sa.getResourceId(R.styleable.AndroidManifestActivity_icon, 0);
+ if (iconVal != 0) {
+ result.icon = iconVal;
+ result.nonLocalizedLabel = null;
+ }
+ }
+
+ int logoVal = sa.getResourceId(R.styleable.AndroidManifestActivity_logo, 0);
+ if (logoVal != 0) {
+ result.logo = logoVal;
+ }
+
+ int bannerVal = sa.getResourceId(R.styleable.AndroidManifestActivity_banner, 0);
+ if (bannerVal != 0) {
+ result.banner = bannerVal;
+ }
+
+ TypedValue v = sa.peekValue(R.styleable.AndroidManifestActivity_label);
+ if (v != null && (result.labelRes = v.resourceId) == 0) {
+ result.nonLocalizedLabel = v.coerceToString();
+ }
+
+ result.setPackageNameInternal(packageName);
+
+ CharSequence pname;
+ if (parsingPackage.getTargetSdkVersion() >= Build.VERSION_CODES.FROYO) {
+ pname = sa.getNonConfigurationString(R.styleable.AndroidManifestActivity_process,
+ Configuration.NATIVE_CONFIG_VERSION);
+ } else {
+ // Some older apps have been seen to use a resource reference
+ // here that on older builds was ignored (with a warning). We
+ // need to continue to do this for them so they don't break.
+ pname = sa.getNonResourceString(R.styleable.AndroidManifestActivity_process);
+ }
+
+ result.setProcessName(packageProcessName, PackageParser.buildProcessName(packageName,
+ packageProcessName, pname,
+ flags, separateProcesses, outError));
+
+ result.descriptionRes = sa.getResourceId(
+ R.styleable.AndroidManifestActivity_description, 0);
+
+ result.enabled = sa.getBoolean(R.styleable.AndroidManifestActivity_enabled, true);
+
+ setExported = sa.hasValue(R.styleable.AndroidManifestActivity_exported);
+ if (setExported) {
+ result.exported = sa.getBoolean(R.styleable.AndroidManifestActivity_exported,
+ false);
+ }
+
+ result.theme = sa.getResourceId(R.styleable.AndroidManifestActivity_theme, 0);
+
+ result.uiOptions = sa.getInt(R.styleable.AndroidManifestActivity_uiOptions,
+ parsingPackage.getUiOptions());
+
+ String parentName = sa.getNonConfigurationString(
+ R.styleable.AndroidManifestActivity_parentActivityName,
+ Configuration.NATIVE_CONFIG_VERSION);
+ if (parentName != null) {
+ String parentClassName = ApkParseUtils.buildClassName(packageName, parentName);
+ if (parentClassName == null) {
+ Log.e(TAG,
+ "Activity " + result.className
+ + " specified invalid parentActivityName " +
+ parentName);
+ } else {
+ result.parentActivityName = parentClassName;
+ }
+ }
+
+ String str;
+ str = sa.getNonConfigurationString(R.styleable.AndroidManifestActivity_permission, 0);
+ if (str == null) {
+ result.setPermission(parsingPackage.getPermission());
+ } else {
+ result.setPermission(str);
+ }
+
+ str = sa.getNonConfigurationString(
+ R.styleable.AndroidManifestActivity_taskAffinity,
+ Configuration.NATIVE_CONFIG_VERSION);
+ result.taskAffinity = PackageParser.buildTaskAffinityName(
+ packageName,
+ parsingPackage.getTaskAffinity(), str, outError);
+
+ result.setSplitName(
+ sa.getNonConfigurationString(R.styleable.AndroidManifestActivity_splitName, 0));
+
+ result.flags = 0;
+ if (sa.getBoolean(
+ R.styleable.AndroidManifestActivity_multiprocess, false)) {
+ result.flags |= ActivityInfo.FLAG_MULTIPROCESS;
+ }
+
+ if (sa.getBoolean(R.styleable.AndroidManifestActivity_finishOnTaskLaunch, false)) {
+ result.flags |= ActivityInfo.FLAG_FINISH_ON_TASK_LAUNCH;
+ }
+
+ if (sa.getBoolean(R.styleable.AndroidManifestActivity_clearTaskOnLaunch, false)) {
+ result.flags |= ActivityInfo.FLAG_CLEAR_TASK_ON_LAUNCH;
+ }
+
+ if (sa.getBoolean(R.styleable.AndroidManifestActivity_noHistory, false)) {
+ result.flags |= ActivityInfo.FLAG_NO_HISTORY;
+ }
+
+ if (sa.getBoolean(R.styleable.AndroidManifestActivity_alwaysRetainTaskState, false)) {
+ result.flags |= ActivityInfo.FLAG_ALWAYS_RETAIN_TASK_STATE;
+ }
+
+ if (sa.getBoolean(R.styleable.AndroidManifestActivity_stateNotNeeded, false)) {
+ result.flags |= ActivityInfo.FLAG_STATE_NOT_NEEDED;
+ }
+
+ if (sa.getBoolean(R.styleable.AndroidManifestActivity_excludeFromRecents, false)) {
+ result.flags |= ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS;
+ }
+
+ if (sa.getBoolean(R.styleable.AndroidManifestActivity_allowTaskReparenting,
+ (parsingPackage.getFlags() & ApplicationInfo.FLAG_ALLOW_TASK_REPARENTING)
+ != 0)) {
+ result.flags |= ActivityInfo.FLAG_ALLOW_TASK_REPARENTING;
+ }
+
+ if (sa.getBoolean(R.styleable.AndroidManifestActivity_finishOnCloseSystemDialogs,
+ false)) {
+ result.flags |= ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS;
+ }
+
+ if (sa.getBoolean(R.styleable.AndroidManifestActivity_showOnLockScreen, false)
+ || sa.getBoolean(R.styleable.AndroidManifestActivity_showForAllUsers, false)) {
+ result.flags |= ActivityInfo.FLAG_SHOW_FOR_ALL_USERS;
+ }
+
+ if (sa.getBoolean(R.styleable.AndroidManifestActivity_immersive, false)) {
+ result.flags |= ActivityInfo.FLAG_IMMERSIVE;
+ }
+
+ if (sa.getBoolean(R.styleable.AndroidManifestActivity_systemUserOnly, false)) {
+ result.flags |= ActivityInfo.FLAG_SYSTEM_USER_ONLY;
+ }
+
+ boolean directBootAware;
+
+ if (!receiver) {
+ if (sa.getBoolean(R.styleable.AndroidManifestActivity_hardwareAccelerated,
+ hardwareAccelerated)) {
+ result.flags |= ActivityInfo.FLAG_HARDWARE_ACCELERATED;
+ }
+
+ result.launchMode = sa.getInt(
+ R.styleable.AndroidManifestActivity_launchMode,
+ ActivityInfo.LAUNCH_MULTIPLE);
+ result.documentLaunchMode = sa.getInt(
+ R.styleable.AndroidManifestActivity_documentLaunchMode,
+ ActivityInfo.DOCUMENT_LAUNCH_NONE);
+ result.maxRecents = sa.getInt(
+ R.styleable.AndroidManifestActivity_maxRecents,
+ ActivityTaskManager.getDefaultAppRecentsLimitStatic());
+ result.configChanges = PackageParser.getActivityConfigChanges(
+ sa.getInt(R.styleable.AndroidManifestActivity_configChanges, 0),
+ sa.getInt(R.styleable.AndroidManifestActivity_recreateOnConfigChanges, 0));
+ result.softInputMode = sa.getInt(
+ R.styleable.AndroidManifestActivity_windowSoftInputMode, 0);
+
+ result.persistableMode = sa.getInteger(
+ R.styleable.AndroidManifestActivity_persistableMode,
+ ActivityInfo.PERSIST_ROOT_ONLY);
+
+ if (sa.getBoolean(R.styleable.AndroidManifestActivity_allowEmbedded, false)) {
+ result.flags |= ActivityInfo.FLAG_ALLOW_EMBEDDED;
+ }
+
+ if (sa.getBoolean(R.styleable.AndroidManifestActivity_autoRemoveFromRecents,
+ false)) {
+ result.flags |= ActivityInfo.FLAG_AUTO_REMOVE_FROM_RECENTS;
+ }
+
+ if (sa.getBoolean(R.styleable.AndroidManifestActivity_relinquishTaskIdentity,
+ false)) {
+ result.flags |= ActivityInfo.FLAG_RELINQUISH_TASK_IDENTITY;
+ }
+
+ if (sa.getBoolean(R.styleable.AndroidManifestActivity_resumeWhilePausing, false)) {
+ result.flags |= ActivityInfo.FLAG_RESUME_WHILE_PAUSING;
+ }
+
+ int screenOrientation = sa.getInt(
+ R.styleable.AndroidManifestActivity_screenOrientation,
+ SCREEN_ORIENTATION_UNSPECIFIED);
+ result.screenOrientation = screenOrientation;
+
+ int resizeMode = getActivityResizeMode(parsingPackage, sa, screenOrientation);
+ result.resizeMode = resizeMode;
+
+ if (sa.getBoolean(R.styleable.AndroidManifestActivity_supportsPictureInPicture,
+ false)) {
+ result.flags |= FLAG_SUPPORTS_PICTURE_IN_PICTURE;
+ }
+
+ if (sa.getBoolean(R.styleable.AndroidManifestActivity_alwaysFocusable, false)) {
+ result.flags |= FLAG_ALWAYS_FOCUSABLE;
+ }
+
+ if (sa.hasValue(R.styleable.AndroidManifestActivity_maxAspectRatio)
+ && sa.getType(R.styleable.AndroidManifestActivity_maxAspectRatio)
+ == TypedValue.TYPE_FLOAT) {
+ result.setMaxAspectRatio(resizeMode,
+ sa.getFloat(R.styleable.AndroidManifestActivity_maxAspectRatio,
+ 0 /*default*/));
+ }
+
+ if (sa.hasValue(R.styleable.AndroidManifestActivity_minAspectRatio)
+ && sa.getType(R.styleable.AndroidManifestActivity_minAspectRatio)
+ == TypedValue.TYPE_FLOAT) {
+ result.setMinAspectRatio(resizeMode,
+ sa.getFloat(R.styleable.AndroidManifestActivity_minAspectRatio,
+ 0 /*default*/));
+ }
+
+ result.lockTaskLaunchMode =
+ sa.getInt(R.styleable.AndroidManifestActivity_lockTaskMode, 0);
+
+ directBootAware = sa.getBoolean(
+ R.styleable.AndroidManifestActivity_directBootAware,
+ false);
+
+ result.requestedVrComponent =
+ sa.getString(R.styleable.AndroidManifestActivity_enableVrMode);
+
+ result.rotationAnimation =
+ sa.getInt(R.styleable.AndroidManifestActivity_rotationAnimation,
+ ROTATION_ANIMATION_UNSPECIFIED);
+
+ result.colorMode = sa.getInt(R.styleable.AndroidManifestActivity_colorMode,
+ ActivityInfo.COLOR_MODE_DEFAULT);
+
+ if (sa.getBoolean(R.styleable.AndroidManifestActivity_showWhenLocked, false)) {
+ result.flags |= ActivityInfo.FLAG_SHOW_WHEN_LOCKED;
+ }
+
+ if (sa.getBoolean(R.styleable.AndroidManifestActivity_turnScreenOn, false)) {
+ result.flags |= ActivityInfo.FLAG_TURN_SCREEN_ON;
+ }
+
+ if (sa.getBoolean(R.styleable.AndroidManifestActivity_inheritShowWhenLocked,
+ false)) {
+ result.privateFlags |= ActivityInfo.FLAG_INHERIT_SHOW_WHEN_LOCKED;
+ }
+ } else {
+ result.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
+ result.configChanges = 0;
+
+ if (sa.getBoolean(R.styleable.AndroidManifestActivity_singleUser, false)) {
+ result.flags |= ActivityInfo.FLAG_SINGLE_USER;
+ }
+ directBootAware = sa.getBoolean(
+ R.styleable.AndroidManifestActivity_directBootAware,
+ false);
+ }
+
+ result.directBootAware = directBootAware;
+
+ if (directBootAware) {
+ parsingPackage.setPartiallyDirectBootAware(true);
+ }
+
+ // can't make this final; we may set it later via meta-data
+ visibleToEphemeral = sa.getBoolean(
+ R.styleable.AndroidManifestActivity_visibleToInstantApps, false);
+ if (visibleToEphemeral) {
+ result.flags |= ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP;
+ parsingPackage.setVisibleToInstantApps(true);
+ }
+ } finally {
+ if (sa != null) {
+ sa.recycle();
+ }
+ }
+
+
+ if (receiver && (parsingPackage.getPrivateFlags()
+ & ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE) != 0) {
+ // A heavy-weight application can not have receives in its main process
+ if (result.getProcessName().equals(packageName)) {
+ outError[0] = "Heavy-weight applications can not have receivers in main process";
+ return null;
+ }
+ }
+
+ if (outError[0] != null) {
+ return null;
+ }
+
+ int outerDepth = parser.getDepth();
+ int type;
+ while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
+ && (type != XmlPullParser.END_TAG
+ || parser.getDepth() > outerDepth)) {
+ if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
+ continue;
+ }
+
+ if (parser.getName().equals("intent-filter")) {
+ ParsedActivityIntentInfo intentInfo = new ParsedActivityIntentInfo(packageName,
+ result.className);
+ if (!parseIntentInfo(intentInfo, parsingPackage, res, parser,
+ true /*allowGlobs*/,
+ true /*allowAutoVerify*/, outError)) {
+ return null;
+ }
+ if (intentInfo.countActions() == 0) {
+ Slog.w(TAG, "No actions in intent filter at "
+ + parsingPackage.getBaseCodePath() + " "
+ + parser.getPositionDescription());
+ } else {
+ result.order = Math.max(intentInfo.getOrder(), result.order);
+ result.addIntent(intentInfo);
+ }
+ // adjust activity flags when we implicitly expose it via a browsable filter
+ final int visibility = visibleToEphemeral
+ ? IntentFilter.VISIBILITY_EXPLICIT
+ : !receiver && isImplicitlyExposedIntent(intentInfo)
+ ? IntentFilter.VISIBILITY_IMPLICIT
+ : IntentFilter.VISIBILITY_NONE;
+ intentInfo.setVisibilityToInstantApp(visibility);
+ if (intentInfo.isVisibleToInstantApp()) {
+ result.flags |= ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP;
+ }
+ if (intentInfo.isImplicitlyVisibleToInstantApp()) {
+ result.flags |= ActivityInfo.FLAG_IMPLICITLY_VISIBLE_TO_INSTANT_APP;
+ }
+ if (PackageParser.LOG_UNSAFE_BROADCASTS && receiver
+ && (targetSdkVersion >= Build.VERSION_CODES.O)) {
+ for (int i = 0; i < intentInfo.countActions(); i++) {
+ final String action = intentInfo.getAction(i);
+ if (action == null || !action.startsWith("android.")) continue;
+ if (!PackageParser.SAFE_BROADCASTS.contains(action)) {
+ Slog.w(TAG, "Broadcast " + action + " may never be delivered to "
+ + packageName + " as requested at: "
+ + parser.getPositionDescription());
+ }
+ }
+ }
+ } else if (!receiver && parser.getName().equals("preferred")) {
+ ParsedActivityIntentInfo intentInfo = new ParsedActivityIntentInfo(packageName,
+ result.className);
+ if (!parseIntentInfo(intentInfo, parsingPackage, res, parser,
+ false /*allowGlobs*/,
+ false /*allowAutoVerify*/, outError)) {
+ return null;
+ }
+ // adjust activity flags when we implicitly expose it via a browsable filter
+ final int visibility = visibleToEphemeral
+ ? IntentFilter.VISIBILITY_EXPLICIT
+ : !receiver && isImplicitlyExposedIntent(intentInfo)
+ ? IntentFilter.VISIBILITY_IMPLICIT
+ : IntentFilter.VISIBILITY_NONE;
+ intentInfo.setVisibilityToInstantApp(visibility);
+ if (intentInfo.isVisibleToInstantApp()) {
+ result.flags |= ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP;
+ }
+ if (intentInfo.isImplicitlyVisibleToInstantApp()) {
+ result.flags |= ActivityInfo.FLAG_IMPLICITLY_VISIBLE_TO_INSTANT_APP;
+ }
+
+ if (intentInfo.countActions() == 0) {
+ Slog.w(TAG, "No actions in preferred at "
+ + parsingPackage.getBaseCodePath() + " "
+ + parser.getPositionDescription());
+ } else {
+ parsingPackage.addPreferredActivityFilter(intentInfo);
+ }
+ } else if (parser.getName().equals("meta-data")) {
+ if ((result.metaData = ApkParseUtils.parseMetaData(parsingPackage, res, parser,
+ result.metaData,
+ outError)) == null) {
+ return null;
+ }
+ } else if (!receiver && parser.getName().equals("layout")) {
+ result.windowLayout = parseLayout(res, parser);
+ } else {
+ if (!PackageParser.RIGID_PARSER) {
+ Slog.w(TAG, "Problem in package " + parsingPackage.getBaseCodePath() + ":");
+ if (receiver) {
+ Slog.w(TAG, "Unknown element under <receiver>: " + parser.getName()
+ + " at " + parsingPackage.getBaseCodePath() + " "
+ + parser.getPositionDescription());
+ } else {
+ Slog.w(TAG, "Unknown element under <activity>: " + parser.getName()
+ + " at " + parsingPackage.getBaseCodePath() + " "
+ + parser.getPositionDescription());
+ }
+ XmlUtils.skipCurrentTag(parser);
+ continue;
+ } else {
+ if (receiver) {
+ outError[0] = "Bad element under <receiver>: " + parser.getName();
+ } else {
+ outError[0] = "Bad element under <activity>: " + parser.getName();
+ }
+ return null;
+ }
+ }
+ }
+
+ if (!setExported) {
+ result.exported = result.intents.size() > 0;
+ }
+
+ return result;
+ }
+
+ public static boolean isImplicitlyExposedIntent(ParsedIntentInfo intentInfo) {
+ return intentInfo.hasCategory(Intent.CATEGORY_BROWSABLE)
+ || intentInfo.hasAction(Intent.ACTION_SEND)
+ || intentInfo.hasAction(Intent.ACTION_SENDTO)
+ || intentInfo.hasAction(Intent.ACTION_SEND_MULTIPLE);
+ }
+
+ public static int getActivityResizeMode(
+ ParsingPackage parsingPackage,
+ TypedArray sa,
+ int screenOrientation
+ ) {
+ int privateFlags = parsingPackage.getPrivateFlags();
+ final boolean appExplicitDefault = (privateFlags
+ & (ApplicationInfo.PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_RESIZEABLE
+ | ApplicationInfo.PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_UNRESIZEABLE)) != 0;
+
+ if (sa.hasValue(R.styleable.AndroidManifestActivity_resizeableActivity)
+ || appExplicitDefault) {
+ // Activity or app explicitly set if it is resizeable or not;
+ final boolean appResizeable = (privateFlags
+ & ApplicationInfo.PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_RESIZEABLE) != 0;
+ if (sa.getBoolean(R.styleable.AndroidManifestActivity_resizeableActivity,
+ appResizeable)) {
+ return ActivityInfo.RESIZE_MODE_RESIZEABLE;
+ } else {
+ return ActivityInfo.RESIZE_MODE_UNRESIZEABLE;
+ }
+ }
+
+ if ((privateFlags
+ & ApplicationInfo.PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION)
+ != 0) {
+ // The activity or app didn't explicitly set the resizing option, however we want to
+ // make it resize due to the sdk version it is targeting.
+ return ActivityInfo.RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION;
+ }
+
+ // resize preference isn't set and target sdk version doesn't support resizing apps by
+ // default. For the app to be resizeable if it isn't fixed orientation or immersive.
+ if (ActivityInfo.isFixedOrientationPortrait(screenOrientation)) {
+ return ActivityInfo.RESIZE_MODE_FORCE_RESIZABLE_PORTRAIT_ONLY;
+ } else if (ActivityInfo.isFixedOrientationLandscape(screenOrientation)) {
+ return ActivityInfo.RESIZE_MODE_FORCE_RESIZABLE_LANDSCAPE_ONLY;
+ } else if (screenOrientation == ActivityInfo.SCREEN_ORIENTATION_LOCKED) {
+ return ActivityInfo.RESIZE_MODE_FORCE_RESIZABLE_PRESERVE_ORIENTATION;
+ } else {
+ return ActivityInfo.RESIZE_MODE_FORCE_RESIZEABLE;
+ }
+ }
+
+ public static ParsedService parseService(
+ String[] separateProcesses,
+ ParsingPackage parsingPackage,
+ Resources res,
+ XmlResourceParser parser, int flags, String[] outError
+ ) throws XmlPullParserException, IOException {
+ TypedArray sa = null;
+ boolean visibleToEphemeral;
+ boolean setExported;
+
+ String packageName = parsingPackage.getPackageName();
+ String packageProcessName = parsingPackage.getProcessName();
+ ParsedService result = new ParsedService();
+
+ try {
+ sa = res.obtainAttributes(parser,
+ R.styleable.AndroidManifestService);
+
+ String name = sa.getNonConfigurationString(R.styleable.AndroidManifestService_name, 0);
+ if (name == null) {
+ outError[0] = "<service> does not specify android:name";
+ return null;
+ } else {
+ String className = ApkParseUtils.buildClassName(packageName, name);
+ if (PackageManager.APP_DETAILS_ACTIVITY_CLASS_NAME.equals(className)) {
+ outError[0] = "<service> invalid android:name";
+ return null;
+ } else if (className == null) {
+ outError[0] = "Empty class name in package " + packageName;
+ return null;
+ }
+
+ result.className = className;
+ }
+
+ int roundIconVal = PackageParser.sUseRoundIcon ? sa.getResourceId(
+ R.styleable.AndroidManifestService_roundIcon, 0) : 0;
+ if (roundIconVal != 0) {
+ result.icon = roundIconVal;
+ result.nonLocalizedLabel = null;
+ } else {
+ int iconVal = sa.getResourceId(R.styleable.AndroidManifestService_icon, 0);
+ if (iconVal != 0) {
+ result.icon = iconVal;
+ result.nonLocalizedLabel = null;
+ }
+ }
+
+ int logoVal = sa.getResourceId(R.styleable.AndroidManifestService_logo, 0);
+ if (logoVal != 0) {
+ result.logo = logoVal;
+ }
+
+ int bannerVal = sa.getResourceId(R.styleable.AndroidManifestService_banner, 0);
+ if (bannerVal != 0) {
+ result.banner = bannerVal;
+ }
+
+ TypedValue v = sa.peekValue(R.styleable.AndroidManifestService_label);
+ if (v != null && (result.labelRes = v.resourceId) == 0) {
+ result.nonLocalizedLabel = v.coerceToString();
+ }
+
+ result.setPackageNameInternal(packageName);
+
+ CharSequence pname;
+ if (parsingPackage.getTargetSdkVersion() >= Build.VERSION_CODES.FROYO) {
+ pname = sa.getNonConfigurationString(R.styleable.AndroidManifestService_process,
+ Configuration.NATIVE_CONFIG_VERSION);
+ } else {
+ // Some older apps have been seen to use a resource reference
+ // here that on older builds was ignored (with a warning). We
+ // need to continue to do this for them so they don't break.
+ pname = sa.getNonResourceString(R.styleable.AndroidManifestService_process);
+ }
+
+ result.setProcessName(packageProcessName, PackageParser.buildProcessName(packageName,
+ packageProcessName, pname,
+ flags, separateProcesses, outError));
+
+ result.descriptionRes = sa.getResourceId(
+ R.styleable.AndroidManifestService_description, 0);
+
+ result.enabled = sa.getBoolean(R.styleable.AndroidManifestService_enabled, true);
+
+ setExported = sa.hasValue(
+ R.styleable.AndroidManifestService_exported);
+ if (setExported) {
+ result.exported = sa.getBoolean(
+ R.styleable.AndroidManifestService_exported, false);
+ }
+
+ String str = sa.getNonConfigurationString(
+ R.styleable.AndroidManifestService_permission, 0);
+ if (str == null) {
+ result.setPermission(parsingPackage.getPermission());
+ } else {
+ result.setPermission(str);
+ }
+
+ result.setSplitName(
+ sa.getNonConfigurationString(R.styleable.AndroidManifestService_splitName, 0));
+
+ result.foregroundServiceType = sa.getInt(
+ R.styleable.AndroidManifestService_foregroundServiceType,
+ ServiceInfo.FOREGROUND_SERVICE_TYPE_NONE);
+
+ result.flags = 0;
+ if (sa.getBoolean(
+ R.styleable.AndroidManifestService_stopWithTask,
+ false)) {
+ result.flags |= ServiceInfo.FLAG_STOP_WITH_TASK;
+ }
+ if (sa.getBoolean(
+ R.styleable.AndroidManifestService_isolatedProcess,
+ false)) {
+ result.flags |= ServiceInfo.FLAG_ISOLATED_PROCESS;
+ }
+ if (sa.getBoolean(
+ R.styleable.AndroidManifestService_externalService,
+ false)) {
+ result.flags |= ServiceInfo.FLAG_EXTERNAL_SERVICE;
+ }
+ if (sa.getBoolean(
+ R.styleable.AndroidManifestService_useAppZygote,
+ false)) {
+ result.flags |= ServiceInfo.FLAG_USE_APP_ZYGOTE;
+ }
+ if (sa.getBoolean(
+ R.styleable.AndroidManifestService_singleUser,
+ false)) {
+ result.flags |= ServiceInfo.FLAG_SINGLE_USER;
+ }
+
+ result.directBootAware = sa.getBoolean(
+ R.styleable.AndroidManifestService_directBootAware,
+ false);
+ if (result.directBootAware) {
+ parsingPackage.setPartiallyDirectBootAware(true);
+ }
+
+ visibleToEphemeral = sa.getBoolean(
+ R.styleable.AndroidManifestService_visibleToInstantApps, false);
+ if (visibleToEphemeral) {
+ result.flags |= ServiceInfo.FLAG_VISIBLE_TO_INSTANT_APP;
+ parsingPackage.setVisibleToInstantApps(true);
+ }
+ } finally {
+ if (sa != null) {
+ sa.recycle();
+ }
+ }
+
+ if (parsingPackage.cantSaveState()) {
+ // A heavy-weight application can not have services in its main process
+ // We can do direct compare because we intern all strings.
+ if (Objects.equals(result.getProcessName(), parsingPackage.getPackageName())) {
+ outError[0] = "Heavy-weight applications can not have services in main process";
+ return null;
+ }
+ }
+
+ int outerDepth = parser.getDepth();
+ int type;
+ while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
+ && (type != XmlPullParser.END_TAG
+ || parser.getDepth() > outerDepth)) {
+ if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
+ continue;
+ }
+
+ if (parser.getName().equals("intent-filter")) {
+ ParsedServiceIntentInfo intent = new ParsedServiceIntentInfo(packageName,
+ result.className);
+ if (!parseIntentInfo(intent, parsingPackage, res, parser, true /*allowGlobs*/,
+ false /*allowAutoVerify*/,
+ outError)) {
+ return null;
+ }
+ if (visibleToEphemeral) {
+ intent.setVisibilityToInstantApp(IntentFilter.VISIBILITY_EXPLICIT);
+ result.flags |= ServiceInfo.FLAG_VISIBLE_TO_INSTANT_APP;
+ }
+ result.order = Math.max(intent.getOrder(), result.order);
+ result.intents.add(intent);
+ } else if (parser.getName().equals("meta-data")) {
+ if ((result.metaData = ApkParseUtils.parseMetaData(parsingPackage, res, parser,
+ result.metaData,
+ outError)) == null) {
+ return null;
+ }
+ } else {
+ if (!PackageParser.RIGID_PARSER) {
+ Slog.w(TAG, "Unknown element under <service>: "
+ + parser.getName() + " at " + parsingPackage.getBaseCodePath() + " "
+ + parser.getPositionDescription());
+ XmlUtils.skipCurrentTag(parser);
+ continue;
+ } else {
+ outError[0] = "Bad element under <service>: " + parser.getName();
+ return null;
+ }
+ }
+ }
+
+ if (!setExported) {
+ result.exported = result.intents.size() > 0;
+ }
+
+ return result;
+ }
+
+ public static ParsedProvider parseProvider(
+ String[] separateProcesses,
+ ParsingPackage parsingPackage,
+ Resources res,
+ XmlResourceParser parser, int flags, String[] outError)
+ throws XmlPullParserException, IOException {
+ TypedArray sa = null;
+ String cpname;
+ boolean visibleToEphemeral;
+
+ int targetSdkVersion = parsingPackage.getTargetSdkVersion();
+ String packageName = parsingPackage.getPackageName();
+ String packageProcessName = parsingPackage.getProcessName();
+ ParsedProvider result = new ParsedProvider();
+
+ try {
+ sa = res.obtainAttributes(parser,
+ R.styleable.AndroidManifestProvider);
+
+ String name = sa.getNonConfigurationString(R.styleable.AndroidManifestProvider_name, 0);
+ if (name == null) {
+ outError[0] = "<provider> does not specify android:name";
+ return null;
+ } else {
+ String className = ApkParseUtils.buildClassName(packageName, name);
+ if (PackageManager.APP_DETAILS_ACTIVITY_CLASS_NAME.equals(className)) {
+ outError[0] = "<provider> invalid android:name";
+ return null;
+ } else if (className == null) {
+ outError[0] = "Empty class name in package " + packageName;
+ return null;
+ }
+
+ result.className = className;
+ }
+
+ int roundIconVal = PackageParser.sUseRoundIcon ? sa.getResourceId(
+ R.styleable.AndroidManifestProvider_roundIcon, 0) : 0;
+ if (roundIconVal != 0) {
+ result.icon = roundIconVal;
+ result.nonLocalizedLabel = null;
+ } else {
+ int iconVal = sa.getResourceId(R.styleable.AndroidManifestProvider_icon, 0);
+ if (iconVal != 0) {
+ result.icon = iconVal;
+ result.nonLocalizedLabel = null;
+ }
+ }
+
+ int logoVal = sa.getResourceId(R.styleable.AndroidManifestProvider_logo, 0);
+ if (logoVal != 0) {
+ result.logo = logoVal;
+ }
+
+ int bannerVal = sa.getResourceId(R.styleable.AndroidManifestProvider_banner, 0);
+ if (bannerVal != 0) {
+ result.banner = bannerVal;
+ }
+
+ TypedValue v = sa.peekValue(R.styleable.AndroidManifestProvider_label);
+ if (v != null && (result.labelRes = v.resourceId) == 0) {
+ result.nonLocalizedLabel = v.coerceToString();
+ }
+
+ result.setPackageNameInternal(packageName);
+
+ CharSequence pname;
+ if (parsingPackage.getTargetSdkVersion() >= Build.VERSION_CODES.FROYO) {
+ pname = sa.getNonConfigurationString(R.styleable.AndroidManifestProvider_process,
+ Configuration.NATIVE_CONFIG_VERSION);
+ } else {
+ // Some older apps have been seen to use a resource reference
+ // here that on older builds was ignored (with a warning). We
+ // need to continue to do this for them so they don't break.
+ pname = sa.getNonResourceString(R.styleable.AndroidManifestProvider_process);
+ }
+
+ result.setProcessName(packageProcessName, PackageParser.buildProcessName(packageName,
+ packageProcessName, pname,
+ flags, separateProcesses, outError));
+
+ result.descriptionRes = sa.getResourceId(
+ R.styleable.AndroidManifestProvider_description, 0);
+
+ result.enabled = sa.getBoolean(R.styleable.AndroidManifestProvider_enabled, true);
+
+ boolean providerExportedDefault = false;
+
+ if (targetSdkVersion < Build.VERSION_CODES.JELLY_BEAN_MR1) {
+ // For compatibility, applications targeting API level 16 or lower
+ // should have their content providers exported by default, unless they
+ // specify otherwise.
+ providerExportedDefault = true;
+ }
+
+ result.exported = sa.getBoolean(
+ R.styleable.AndroidManifestProvider_exported,
+ providerExportedDefault);
+
+ cpname = sa.getNonConfigurationString(
+ R.styleable.AndroidManifestProvider_authorities, 0);
+
+ result.isSyncable = sa.getBoolean(
+ R.styleable.AndroidManifestProvider_syncable,
+ false);
+
+ String permission = sa.getNonConfigurationString(
+ R.styleable.AndroidManifestProvider_permission, 0);
+ String str = sa.getNonConfigurationString(
+ R.styleable.AndroidManifestProvider_readPermission, 0);
+ if (str == null) {
+ str = permission;
+ }
+ if (str == null) {
+ result.setReadPermission(parsingPackage.getPermission());
+ } else {
+ result.setReadPermission(str);
+ }
+ str = sa.getNonConfigurationString(
+ R.styleable.AndroidManifestProvider_writePermission, 0);
+ if (str == null) {
+ str = permission;
+ }
+ if (str == null) {
+ result.setWritePermission(parsingPackage.getPermission());
+ } else {
+ result.setWritePermission(str);
+ }
+
+ result.grantUriPermissions = sa.getBoolean(
+ R.styleable.AndroidManifestProvider_grantUriPermissions,
+ false);
+
+ result.forceUriPermissions = sa.getBoolean(
+ R.styleable.AndroidManifestProvider_forceUriPermissions,
+ false);
+
+ result.multiProcess = sa.getBoolean(
+ R.styleable.AndroidManifestProvider_multiprocess,
+ false);
+
+ result.initOrder = sa.getInt(
+ R.styleable.AndroidManifestProvider_initOrder,
+ 0);
+
+ result.setSplitName(
+ sa.getNonConfigurationString(R.styleable.AndroidManifestProvider_splitName, 0));
+
+ result.flags = 0;
+
+ if (sa.getBoolean(
+ R.styleable.AndroidManifestProvider_singleUser,
+ false)) {
+ result.flags |= ProviderInfo.FLAG_SINGLE_USER;
+ }
+
+ result.directBootAware = sa.getBoolean(
+ R.styleable.AndroidManifestProvider_directBootAware,
+ false);
+ if (result.directBootAware) {
+ parsingPackage.setPartiallyDirectBootAware(true);
+ }
+
+ visibleToEphemeral =
+ sa.getBoolean(R.styleable.AndroidManifestProvider_visibleToInstantApps, false);
+ if (visibleToEphemeral) {
+ result.flags |= ProviderInfo.FLAG_VISIBLE_TO_INSTANT_APP;
+ parsingPackage.setVisibleToInstantApps(true);
+ }
+ } finally {
+ if (sa != null) {
+ sa.recycle();
+ }
+ }
+
+ if ((parsingPackage.getPrivateFlags() & ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE)
+ != 0) {
+ // A heavy-weight application can not have providers in its main process
+ if (result.getProcessName().equals(packageName)) {
+ outError[0] = "Heavy-weight applications can not have providers in main process";
+ return null;
+ }
+ }
+
+ if (cpname == null) {
+ outError[0] = "<provider> does not include authorities attribute";
+ return null;
+ }
+ if (cpname.length() <= 0) {
+ outError[0] = "<provider> has empty authorities attribute";
+ return null;
+ }
+ result.setAuthority(cpname);
+
+ if (!parseProviderTags(parsingPackage, res, parser, visibleToEphemeral, result, outError)) {
+ return null;
+ }
+
+ return result;
+ }
+
+ public static ParsedQueriesIntentInfo parsedParsedQueriesIntentInfo(
+ ParsingPackage parsingPackage,
+ Resources res,
+ XmlResourceParser parser,
+ String[] outError
+ ) throws IOException, XmlPullParserException {
+ ParsedQueriesIntentInfo intentInfo = new ParsedQueriesIntentInfo(
+ parsingPackage.getPackageName(),
+ null
+ );
+ if (!parseIntentInfo(
+ intentInfo,
+ parsingPackage,
+ res,
+ parser,
+ true /*allowGlobs*/,
+ true /*allowAutoVerify*/,
+ outError
+ )) {
+ return null;
+ }
+ return intentInfo;
+ }
+
+ private static boolean parseProviderTags(
+ ParsingPackage parsingPackage,
+ Resources res, XmlResourceParser parser,
+ boolean visibleToEphemeral, ParsedProvider outInfo, String[] outError)
+ throws XmlPullParserException, IOException {
+ int outerDepth = parser.getDepth();
+ int type;
+ while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
+ && (type != XmlPullParser.END_TAG
+ || parser.getDepth() > outerDepth)) {
+ if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
+ continue;
+ }
+
+ if (parser.getName().equals("intent-filter")) {
+ ParsedProviderIntentInfo intent = new ParsedProviderIntentInfo(
+ parsingPackage.getPackageName(), outInfo.className);
+ if (!parseIntentInfo(intent, parsingPackage, res, parser, true /*allowGlobs*/,
+ false /*allowAutoVerify*/,
+ outError)) {
+ return false;
+ }
+ if (visibleToEphemeral) {
+ intent.setVisibilityToInstantApp(IntentFilter.VISIBILITY_EXPLICIT);
+ outInfo.flags |= ProviderInfo.FLAG_VISIBLE_TO_INSTANT_APP;
+ }
+ outInfo.order = Math.max(intent.getOrder(), outInfo.order);
+ outInfo.intents.add(intent);
+
+ } else if (parser.getName().equals("meta-data")) {
+ Bundle metaData = ApkParseUtils.parseMetaData(parsingPackage, res, parser,
+ outInfo.metaData, outError);
+ if (metaData == null) {
+ return false;
+ } else {
+ outInfo.metaData = metaData;
+ }
+
+ } else if (parser.getName().equals("grant-uri-permission")) {
+ TypedArray sa = res.obtainAttributes(parser,
+ R.styleable.AndroidManifestGrantUriPermission);
+
+ PatternMatcher pa = null;
+
+ String str = sa.getNonConfigurationString(
+ R.styleable.AndroidManifestGrantUriPermission_path, 0);
+ if (str != null) {
+ pa = new PatternMatcher(str, PatternMatcher.PATTERN_LITERAL);
+ }
+
+ str = sa.getNonConfigurationString(
+ R.styleable.AndroidManifestGrantUriPermission_pathPrefix, 0);
+ if (str != null) {
+ pa = new PatternMatcher(str, PatternMatcher.PATTERN_PREFIX);
+ }
+
+ str = sa.getNonConfigurationString(
+ R.styleable.AndroidManifestGrantUriPermission_pathPattern, 0);
+ if (str != null) {
+ pa = new PatternMatcher(str, PatternMatcher.PATTERN_SIMPLE_GLOB);
+ }
+
+ sa.recycle();
+
+ if (pa != null) {
+ if (outInfo.uriPermissionPatterns == null) {
+ outInfo.uriPermissionPatterns = new PatternMatcher[1];
+ outInfo.uriPermissionPatterns[0] = pa;
+ } else {
+ final int N = outInfo.uriPermissionPatterns.length;
+ PatternMatcher[] newp = new PatternMatcher[N + 1];
+ System.arraycopy(outInfo.uriPermissionPatterns, 0, newp, 0, N);
+ newp[N] = pa;
+ outInfo.uriPermissionPatterns = newp;
+ }
+ outInfo.grantUriPermissions = true;
+ } else {
+ if (!PackageParser.RIGID_PARSER) {
+ Slog.w(TAG, "Unknown element under <path-permission>: "
+ + parser.getName() + " at " + parsingPackage.getBaseCodePath()
+ + " "
+ + parser.getPositionDescription());
+ XmlUtils.skipCurrentTag(parser);
+ continue;
+ } else {
+ outError[0] = "No path, pathPrefix, or pathPattern for <path-permission>";
+ return false;
+ }
+ }
+ XmlUtils.skipCurrentTag(parser);
+
+ } else if (parser.getName().equals("path-permission")) {
+ TypedArray sa = res.obtainAttributes(parser,
+ R.styleable.AndroidManifestPathPermission);
+
+ PathPermission pa = null;
+
+ String permission = sa.getNonConfigurationString(
+ R.styleable.AndroidManifestPathPermission_permission, 0);
+ String readPermission = sa.getNonConfigurationString(
+ R.styleable.AndroidManifestPathPermission_readPermission, 0);
+ if (readPermission == null) {
+ readPermission = permission;
+ }
+ String writePermission = sa.getNonConfigurationString(
+ R.styleable.AndroidManifestPathPermission_writePermission, 0);
+ if (writePermission == null) {
+ writePermission = permission;
+ }
+
+ boolean havePerm = false;
+ if (readPermission != null) {
+ readPermission = readPermission.intern();
+ havePerm = true;
+ }
+ if (writePermission != null) {
+ writePermission = writePermission.intern();
+ havePerm = true;
+ }
+
+ if (!havePerm) {
+ if (!PackageParser.RIGID_PARSER) {
+ Slog.w(TAG, "No readPermission or writePermssion for <path-permission>: "
+ + parser.getName() + " at " + parsingPackage.getBaseCodePath()
+ + " "
+ + parser.getPositionDescription());
+ XmlUtils.skipCurrentTag(parser);
+ continue;
+ } else {
+ outError[0] = "No readPermission or writePermssion for <path-permission>";
+ return false;
+ }
+ }
+
+ String path = sa.getNonConfigurationString(
+ R.styleable.AndroidManifestPathPermission_path, 0);
+ if (path != null) {
+ pa = new PathPermission(path,
+ PatternMatcher.PATTERN_LITERAL, readPermission, writePermission);
+ }
+
+ path = sa.getNonConfigurationString(
+ R.styleable.AndroidManifestPathPermission_pathPrefix, 0);
+ if (path != null) {
+ pa = new PathPermission(path,
+ PatternMatcher.PATTERN_PREFIX, readPermission, writePermission);
+ }
+
+ path = sa.getNonConfigurationString(
+ R.styleable.AndroidManifestPathPermission_pathPattern, 0);
+ if (path != null) {
+ pa = new PathPermission(path,
+ PatternMatcher.PATTERN_SIMPLE_GLOB, readPermission, writePermission);
+ }
+
+ path = sa.getNonConfigurationString(
+ R.styleable.AndroidManifestPathPermission_pathAdvancedPattern, 0);
+ if (path != null) {
+ pa = new PathPermission(path,
+ PatternMatcher.PATTERN_ADVANCED_GLOB, readPermission, writePermission);
+ }
+
+ sa.recycle();
+
+ if (pa != null) {
+ if (outInfo.pathPermissions == null) {
+ outInfo.pathPermissions = new PathPermission[1];
+ outInfo.pathPermissions[0] = pa;
+ } else {
+ final int N = outInfo.pathPermissions.length;
+ PathPermission[] newp = new PathPermission[N + 1];
+ System.arraycopy(outInfo.pathPermissions, 0, newp, 0, N);
+ newp[N] = pa;
+ outInfo.pathPermissions = newp;
+ }
+ } else {
+ if (!PackageParser.RIGID_PARSER) {
+ Slog.w(TAG, "No path, pathPrefix, or pathPattern for <path-permission>: "
+ + parser.getName() + " at " + parsingPackage.getBaseCodePath()
+ + " "
+ + parser.getPositionDescription());
+ XmlUtils.skipCurrentTag(parser);
+ continue;
+ }
+ outError[0] = "No path, pathPrefix, or pathPattern for <path-permission>";
+ return false;
+ }
+ XmlUtils.skipCurrentTag(parser);
+
+ } else {
+ if (!PackageParser.RIGID_PARSER) {
+ Slog.w(TAG, "Unknown element under <provider>: "
+ + parser.getName() + " at " + parsingPackage.getBaseCodePath() + " "
+ + parser.getPositionDescription());
+ XmlUtils.skipCurrentTag(parser);
+ continue;
+ } else {
+ outError[0] = "Bad element under <provider>: " + parser.getName();
+ return false;
+ }
+ }
+ }
+ return true;
+ }
+
+ public static ParsedActivity parseActivityAlias(
+ ParsingPackage parsingPackage,
+ Resources res,
+ XmlResourceParser parser,
+ String[] outError)
+ throws XmlPullParserException, IOException {
+ TypedArray sa = res.obtainAttributes(parser,
+ R.styleable.AndroidManifestActivityAlias);
+
+ String targetActivity = sa.getNonConfigurationString(
+ R.styleable.AndroidManifestActivityAlias_targetActivity,
+ Configuration.NATIVE_CONFIG_VERSION);
+ if (targetActivity == null) {
+ outError[0] = "<activity-alias> does not specify android:targetActivity";
+ sa.recycle();
+ return null;
+ }
+
+ String packageName = parsingPackage.getPackageName();
+ targetActivity = ApkParseUtils.buildClassName(packageName, targetActivity);
+ if (targetActivity == null) {
+ outError[0] = "Empty class name in package " + packageName;
+ sa.recycle();
+ return null;
+ }
+
+ ParsedActivity target = null;
+
+ List<ParsedActivity> activities = parsingPackage.getActivities();
+ final int NA = activities.size();
+ for (int i = 0; i < NA; i++) {
+ ParsedActivity t = activities.get(i);
+ if (targetActivity.equals(t.className)) {
+ target = t;
+ break;
+ }
+ }
+
+ if (target == null) {
+ outError[0] = "<activity-alias> target activity " + targetActivity
+ + " not found in manifest with activities = " + parsingPackage.getActivities()
+ + ", parsedActivities = " + activities;
+ sa.recycle();
+ return null;
+ }
+
+ ParsedActivity result = new ParsedActivity();
+ result.setPackageNameInternal(target.getPackageName());
+ result.targetActivity = targetActivity;
+ result.configChanges = target.configChanges;
+ result.flags = target.flags;
+ result.privateFlags = target.privateFlags;
+ result.icon = target.icon;
+ result.logo = target.logo;
+ result.banner = target.banner;
+ result.labelRes = target.labelRes;
+ result.nonLocalizedLabel = target.nonLocalizedLabel;
+ result.launchMode = target.launchMode;
+ result.lockTaskLaunchMode = target.lockTaskLaunchMode;
+ result.descriptionRes = target.descriptionRes;
+ result.screenOrientation = target.screenOrientation;
+ result.taskAffinity = target.taskAffinity;
+ result.theme = target.theme;
+ result.softInputMode = target.softInputMode;
+ result.uiOptions = target.uiOptions;
+ result.parentActivityName = target.parentActivityName;
+ result.maxRecents = target.maxRecents;
+ result.windowLayout = target.windowLayout;
+ result.resizeMode = target.resizeMode;
+ result.maxAspectRatio = target.maxAspectRatio;
+ result.hasMaxAspectRatio = target.hasMaxAspectRatio;
+ result.minAspectRatio = target.minAspectRatio;
+ result.hasMinAspectRatio = target.hasMinAspectRatio;
+ result.requestedVrComponent = target.requestedVrComponent;
+ result.directBootAware = target.directBootAware;
+
+ result.setProcessName(parsingPackage.getAppInfoProcessName(), target.getProcessName());
+
+ // Not all attributes from the target ParsedActivity are copied to the alias.
+ // Careful when adding an attribute and determine whether or not it should be copied.
+// result.enabled = target.enabled;
+// result.exported = target.exported;
+// result.permission = target.permission;
+// result.splitName = target.splitName;
+// result.documentLaunchMode = target.documentLaunchMode;
+// result.persistableMode = target.persistableMode;
+// result.rotationAnimation = target.rotationAnimation;
+// result.colorMode = target.colorMode;
+// result.intents.addAll(target.intents);
+// result.order = target.order;
+// result.metaData = target.metaData;
+
+ String name = sa.getNonConfigurationString(R.styleable.AndroidManifestActivityAlias_name,
+ 0);
+ if (name == null) {
+ outError[0] = "<activity-alias> does not specify android:name";
+ return null;
+ } else {
+ String className = ApkParseUtils.buildClassName(packageName, name);
+ if (PackageManager.APP_DETAILS_ACTIVITY_CLASS_NAME.equals(className)) {
+ outError[0] = "<activity-alias> invalid android:name";
+ return null;
+ } else if (className == null) {
+ outError[0] = "Empty class name in package " + packageName;
+ return null;
+ }
+
+ result.className = className;
+ }
+
+ int roundIconVal = PackageParser.sUseRoundIcon ? sa.getResourceId(
+ R.styleable.AndroidManifestActivityAlias_roundIcon, 0) : 0;
+ if (roundIconVal != 0) {
+ result.icon = roundIconVal;
+ result.nonLocalizedLabel = null;
+ } else {
+ int iconVal = sa.getResourceId(R.styleable.AndroidManifestActivityAlias_icon, 0);
+ if (iconVal != 0) {
+ result.icon = iconVal;
+ result.nonLocalizedLabel = null;
+ }
+ }
+
+ int logoVal = sa.getResourceId(R.styleable.AndroidManifestActivityAlias_logo, 0);
+ if (logoVal != 0) {
+ result.logo = logoVal;
+ }
+
+ int bannerVal = sa.getResourceId(R.styleable.AndroidManifestActivityAlias_banner, 0);
+ if (bannerVal != 0) {
+ result.banner = bannerVal;
+ }
+
+ TypedValue v = sa.peekValue(R.styleable.AndroidManifestActivityAlias_label);
+ if (v != null && (result.labelRes = v.resourceId) == 0) {
+ result.nonLocalizedLabel = v.coerceToString();
+ }
+
+ result.setPackageNameInternal(packageName);
+
+ result.descriptionRes = sa.getResourceId(
+ R.styleable.AndroidManifestActivityAlias_description, 0);
+
+ result.enabled = sa.getBoolean(R.styleable.AndroidManifestActivityAlias_enabled, true);
+
+ final boolean setExported = sa.hasValue(
+ R.styleable.AndroidManifestActivityAlias_exported);
+ if (setExported) {
+ result.exported = sa.getBoolean(
+ R.styleable.AndroidManifestActivityAlias_exported, false);
+ }
+
+ String str;
+ str = sa.getNonConfigurationString(
+ R.styleable.AndroidManifestActivityAlias_permission, 0);
+ if (str != null) {
+ result.setPermission(str);
+ }
+
+ String parentName = sa.getNonConfigurationString(
+ R.styleable.AndroidManifestActivityAlias_parentActivityName,
+ Configuration.NATIVE_CONFIG_VERSION);
+ if (parentName != null) {
+ String parentClassName = ApkParseUtils.buildClassName(result.getPackageName(),
+ parentName);
+ if (parentClassName == null) {
+ Log.e(TAG, "Activity alias " + result.className +
+ " specified invalid parentActivityName " + parentName);
+ outError[0] = null;
+ } else {
+ result.parentActivityName = parentClassName;
+ }
+ }
+
+ // TODO add visibleToInstantApps attribute to activity alias
+ final boolean visibleToEphemeral =
+ ((result.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0);
+
+ sa.recycle();
+
+ if (outError[0] != null) {
+ return null;
+ }
+
+ int outerDepth = parser.getDepth();
+ int type;
+ while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
+ && (type != XmlPullParser.END_TAG
+ || parser.getDepth() > outerDepth)) {
+ if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
+ continue;
+ }
+
+ String tagName = parser.getName();
+ if (tagName.equals("intent-filter")) {
+ ParsedActivityIntentInfo intent = new ParsedActivityIntentInfo(packageName,
+ result.className);
+ if (!parseIntentInfo(intent, parsingPackage, res, parser, true /*allowGlobs*/,
+ true /*allowAutoVerify*/, outError)) {
+ return null;
+ }
+ if (intent.countActions() == 0) {
+ Slog.w(TAG, "No actions in intent filter at "
+ + parsingPackage.getBaseCodePath() + " "
+ + parser.getPositionDescription());
+ } else {
+ result.order = Math.max(intent.getOrder(), result.order);
+ result.addIntent(intent);
+ }
+ // adjust activity flags when we implicitly expose it via a browsable filter
+ final int visibility = visibleToEphemeral
+ ? IntentFilter.VISIBILITY_EXPLICIT
+ : isImplicitlyExposedIntent(intent)
+ ? IntentFilter.VISIBILITY_IMPLICIT
+ : IntentFilter.VISIBILITY_NONE;
+ intent.setVisibilityToInstantApp(visibility);
+ if (intent.isVisibleToInstantApp()) {
+ result.flags |= ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP;
+ }
+ if (intent.isImplicitlyVisibleToInstantApp()) {
+ result.flags |= ActivityInfo.FLAG_IMPLICITLY_VISIBLE_TO_INSTANT_APP;
+ }
+ } else if (tagName.equals("meta-data")) {
+ if ((result.metaData = ApkParseUtils.parseMetaData(parsingPackage, res, parser,
+ result.metaData,
+ outError)) == null) {
+ return null;
+ }
+ } else {
+ if (!PackageParser.RIGID_PARSER) {
+ Slog.w(TAG, "Unknown element under <activity-alias>: " + tagName
+ + " at " + parsingPackage.getBaseCodePath() + " "
+ + parser.getPositionDescription());
+ XmlUtils.skipCurrentTag(parser);
+ continue;
+ } else {
+ outError[0] = "Bad element under <activity-alias>: " + tagName;
+ return null;
+ }
+ }
+ }
+
+ if (!setExported) {
+ result.exported = result.intents.size() > 0;
+ }
+
+ return result;
+ }
+
+ public static ParsedPermission parsePermission(
+ ParsingPackage parsingPackage,
+ Resources res,
+ XmlResourceParser parser,
+ String[] outError
+ ) throws IOException, XmlPullParserException {
+ TypedArray sa = null;
+ String packageName = parsingPackage.getPackageName();
+ ParsedPermission result = new ParsedPermission();
+
+ try {
+ sa = res.obtainAttributes(parser, R.styleable.AndroidManifestPermission);
+
+ String name = sa.getNonConfigurationString(R.styleable.AndroidManifestPermission_name,
+ 0);
+ if (name == null) {
+ outError[0] = "<permission> does not specify android:name";
+ return null;
+ } else {
+ String className = ApkParseUtils.buildClassName(packageName, name);
+ if (PackageManager.APP_DETAILS_ACTIVITY_CLASS_NAME.equals(className)) {
+ outError[0] = "<permission> invalid android:name";
+ return null;
+ } else if (className == null) {
+ outError[0] = "Empty class name in package " + packageName;
+ return null;
+ }
+
+ result.className = className;
+ }
+
+ int roundIconVal = PackageParser.sUseRoundIcon ? sa.getResourceId(
+ R.styleable.AndroidManifestPermission_roundIcon, 0) : 0;
+ if (roundIconVal != 0) {
+ result.icon = roundIconVal;
+ result.nonLocalizedLabel = null;
+ } else {
+ int iconVal = sa.getResourceId(R.styleable.AndroidManifestPermission_icon, 0);
+ if (iconVal != 0) {
+ result.icon = iconVal;
+ result.nonLocalizedLabel = null;
+ }
+ }
+
+ int logoVal = sa.getResourceId(R.styleable.AndroidManifestPermission_logo, 0);
+ if (logoVal != 0) {
+ result.logo = logoVal;
+ }
+
+ int bannerVal = sa.getResourceId(R.styleable.AndroidManifestPermission_banner, 0);
+ if (bannerVal != 0) {
+ result.banner = bannerVal;
+ }
+
+ TypedValue v = sa.peekValue(R.styleable.AndroidManifestPermission_label);
+ if (v != null && (result.labelRes = v.resourceId) == 0) {
+ result.nonLocalizedLabel = v.coerceToString();
+ }
+
+ result.setPackageNameInternal(packageName);
+
+ result.descriptionRes = sa.getResourceId(
+ R.styleable.AndroidManifestPermission_description, 0);
+
+ if (sa.hasValue(
+ R.styleable.AndroidManifestPermission_backgroundPermission)) {
+ if ("android".equals(packageName)) {
+ result.backgroundPermission = sa.getNonResourceString(
+ R.styleable
+ .AndroidManifestPermission_backgroundPermission);
+ } else {
+ Slog.w(TAG, packageName + " defines a background permission. Only the "
+ + "'android' package can do that.");
+ }
+ }
+
+ // Note: don't allow this value to be a reference to a resource
+ // that may change.
+ result.setGroup(sa.getNonResourceString(
+ R.styleable.AndroidManifestPermission_permissionGroup));
+
+ result.requestRes = sa.getResourceId(
+ R.styleable.AndroidManifestPermission_request, 0);
+
+ result.protectionLevel = sa.getInt(
+ R.styleable.AndroidManifestPermission_protectionLevel,
+ PermissionInfo.PROTECTION_NORMAL);
+
+ result.flags = sa.getInt(
+ R.styleable.AndroidManifestPermission_permissionFlags, 0);
+
+ // For now only platform runtime permissions can be restricted
+ if (!result.isRuntime() || !"android".equals(result.getPackageName())) {
+ result.flags &= ~PermissionInfo.FLAG_HARD_RESTRICTED;
+ result.flags &= ~PermissionInfo.FLAG_SOFT_RESTRICTED;
+ } else {
+ // The platform does not get to specify conflicting permissions
+ if ((result.flags & PermissionInfo.FLAG_HARD_RESTRICTED) != 0
+ && (result.flags & PermissionInfo.FLAG_SOFT_RESTRICTED) != 0) {
+ throw new IllegalStateException("Permission cannot be both soft and hard"
+ + " restricted: " + result.getName());
+ }
+ }
+
+ } finally {
+ if (sa != null) {
+ sa.recycle();
+ }
+ }
+
+ if (result.protectionLevel == -1) {
+ outError[0] = "<permission> does not specify protectionLevel";
+ return null;
+ }
+
+ result.protectionLevel = PermissionInfo.fixProtectionLevel(result.protectionLevel);
+
+ if (result.getProtectionFlags() != 0) {
+ if ((result.protectionLevel & PermissionInfo.PROTECTION_FLAG_INSTANT) == 0
+ && (result.protectionLevel & PermissionInfo.PROTECTION_FLAG_RUNTIME_ONLY)
+ == 0
+ && (result.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE) !=
+ PermissionInfo.PROTECTION_SIGNATURE) {
+ outError[0] = "<permission> protectionLevel specifies a non-instant flag but is "
+ + "not based on signature type";
+ return null;
+ }
+ }
+
+ boolean success = parseAllMetaData(parsingPackage, res, parser,
+ "<permission>", result, outError);
+ if (!success || outError[0] != null) {
+ return null;
+ }
+
+ return result;
+ }
+
+ public static ParsedPermission parsePermissionTree(
+ ParsingPackage parsingPackage,
+ Resources res,
+ XmlResourceParser parser,
+ String[] outError
+ ) throws IOException, XmlPullParserException {
+ TypedArray sa = null;
+ String packageName = parsingPackage.getPackageName();
+ ParsedPermission result = new ParsedPermission();
+
+ try {
+ sa = res.obtainAttributes(parser, R.styleable.AndroidManifestPermissionTree);
+
+ String name = sa.getNonConfigurationString(
+ R.styleable.AndroidManifestPermissionTree_name, 0);
+ if (name == null) {
+ outError[0] = "<permission-tree> does not specify android:name";
+ return null;
+ } else {
+ String className = ApkParseUtils.buildClassName(packageName, name);
+ if (PackageManager.APP_DETAILS_ACTIVITY_CLASS_NAME.equals(className)) {
+ outError[0] = "<permission-tree> invalid android:name";
+ return null;
+ } else if (className == null) {
+ outError[0] = "Empty class name in package " + packageName;
+ return null;
+ }
+
+ result.className = className;
+ }
+
+ int roundIconVal = PackageParser.sUseRoundIcon ? sa.getResourceId(
+ R.styleable.AndroidManifestPermissionTree_roundIcon, 0) : 0;
+ if (roundIconVal != 0) {
+ result.icon = roundIconVal;
+ result.nonLocalizedLabel = null;
+ } else {
+ int iconVal = sa.getResourceId(R.styleable.AndroidManifestPermissionTree_icon, 0);
+ if (iconVal != 0) {
+ result.icon = iconVal;
+ result.nonLocalizedLabel = null;
+ }
+ }
+
+ int logoVal = sa.getResourceId(R.styleable.AndroidManifestPermissionTree_logo, 0);
+ if (logoVal != 0) {
+ result.logo = logoVal;
+ }
+
+ int bannerVal = sa.getResourceId(R.styleable.AndroidManifestPermissionTree_banner, 0);
+ if (bannerVal != 0) {
+ result.banner = bannerVal;
+ }
+
+ TypedValue v = sa.peekValue(R.styleable.AndroidManifestPermissionTree_label);
+ if (v != null && (result.labelRes = v.resourceId) == 0) {
+ result.nonLocalizedLabel = v.coerceToString();
+ }
+
+ result.setPackageNameInternal(packageName);
+ } finally {
+ if (sa != null) {
+ sa.recycle();
+ }
+ }
+
+ int index = result.getName().indexOf('.');
+ if (index > 0) {
+ index = result.getName().indexOf('.', index + 1);
+ }
+ if (index < 0) {
+ outError[0] =
+ "<permission-tree> name has less than three segments: " + result.getName();
+ return null;
+ }
+
+ result.descriptionRes = 0;
+ result.requestRes = 0;
+ result.protectionLevel = PermissionInfo.PROTECTION_NORMAL;
+ result.tree = true;
+
+ boolean success = parseAllMetaData(parsingPackage, res, parser,
+ "<permission-tree>", result, outError);
+ if (!success || outError[0] != null) {
+ return null;
+ }
+
+ return result;
+ }
+
+ public static ParsedPermissionGroup parsePermissionGroup(
+ ParsingPackage parsingPackage,
+ Resources res,
+ XmlResourceParser parser,
+ String[] outError
+ ) throws IOException, XmlPullParserException {
+ TypedArray sa = null;
+ String packageName = parsingPackage.getPackageName();
+ ParsedPermissionGroup result = new ParsedPermissionGroup();
+
+ try {
+ sa = res.obtainAttributes(parser, R.styleable.AndroidManifestPermissionGroup);
+
+ String name = sa.getNonConfigurationString(
+ R.styleable.AndroidManifestPermissionGroup_name, 0);
+ if (name == null) {
+ outError[0] = "<permission> does not specify android:name";
+ return null;
+ } else {
+ String className = ApkParseUtils.buildClassName(packageName, name);
+ if (PackageManager.APP_DETAILS_ACTIVITY_CLASS_NAME.equals(className)) {
+ outError[0] = "<permission> invalid android:name";
+ return null;
+ } else if (className == null) {
+ outError[0] = "Empty class name in package " + packageName;
+ return null;
+ }
+
+ result.className = className;
+ }
+
+ int roundIconVal = PackageParser.sUseRoundIcon ? sa.getResourceId(
+ R.styleable.AndroidManifestPermissionGroup_roundIcon, 0) : 0;
+ if (roundIconVal != 0) {
+ result.icon = roundIconVal;
+ result.nonLocalizedLabel = null;
+ } else {
+ int iconVal = sa.getResourceId(R.styleable.AndroidManifestPermissionGroup_icon, 0);
+ if (iconVal != 0) {
+ result.icon = iconVal;
+ result.nonLocalizedLabel = null;
+ }
+ }
+
+ int logoVal = sa.getResourceId(R.styleable.AndroidManifestPermissionGroup_logo, 0);
+ if (logoVal != 0) {
+ result.logo = logoVal;
+ }
+
+ int bannerVal = sa.getResourceId(R.styleable.AndroidManifestPermissionGroup_banner, 0);
+ if (bannerVal != 0) {
+ result.banner = bannerVal;
+ }
+
+ TypedValue v = sa.peekValue(R.styleable.AndroidManifestPermissionGroup_label);
+ if (v != null && (result.labelRes = v.resourceId) == 0) {
+ result.nonLocalizedLabel = v.coerceToString();
+ }
+
+ result.setPackageNameInternal(packageName);
+
+ result.descriptionRes = sa.getResourceId(
+ R.styleable.AndroidManifestPermissionGroup_description, 0);
+
+ result.requestDetailResourceId = sa.getResourceId(
+ R.styleable.AndroidManifestPermissionGroup_requestDetail, 0);
+ result.backgroundRequestResourceId = sa.getResourceId(
+ R.styleable.AndroidManifestPermissionGroup_backgroundRequest,
+ 0);
+ result.backgroundRequestDetailResourceId = sa.getResourceId(
+ R.styleable
+ .AndroidManifestPermissionGroup_backgroundRequestDetail, 0);
+
+ result.requestRes = sa.getResourceId(
+ R.styleable.AndroidManifestPermissionGroup_request, 0);
+ result.flags = sa.getInt(
+ R.styleable.AndroidManifestPermissionGroup_permissionGroupFlags,
+ 0);
+ result.priority = sa.getInt(
+ R.styleable.AndroidManifestPermissionGroup_priority, 0);
+
+ } finally {
+ if (sa != null) {
+ sa.recycle();
+ }
+ }
+
+ boolean success = parseAllMetaData(parsingPackage, res, parser,
+ "<permission-group>", result, outError);
+ if (!success || outError[0] != null) {
+ return null;
+ }
+
+ return result;
+ }
+
+ public static ParsedInstrumentation parseInstrumentation(
+ ParsingPackage parsingPackage,
+ Resources res,
+ XmlResourceParser parser,
+ String[] outError
+ ) throws IOException, XmlPullParserException {
+ TypedArray sa = null;
+ String packageName = parsingPackage.getPackageName();
+ ParsedInstrumentation result = new ParsedInstrumentation();
+
+ try {
+ sa = res.obtainAttributes(parser, R.styleable.AndroidManifestInstrumentation);
+
+ // TODO(b/135203078): Re-share all of the configuration for this. ParseComponentArgs was
+ // un-used for this, but can be adjusted and re-added to share all the initial result
+ // parsing for icon/logo/name/etc in all of these parse methods.
+ String name = sa.getNonConfigurationString(
+ R.styleable.AndroidManifestInstrumentation_name, 0);
+ if (name == null) {
+ outError[0] = "<instrumentation> does not specify android:name";
+ return null;
+ } else {
+ String className = ApkParseUtils.buildClassName(packageName, name);
+ if (PackageManager.APP_DETAILS_ACTIVITY_CLASS_NAME.equals(className)) {
+ outError[0] = "<instrumentation> invalid android:name";
+ return null;
+ } else if (className == null) {
+ outError[0] = "Empty class name in package " + packageName;
+ return null;
+ }
+
+ result.className = className;
+ }
+
+ int roundIconVal = PackageParser.sUseRoundIcon ? sa.getResourceId(
+ R.styleable.AndroidManifestInstrumentation_roundIcon, 0) : 0;
+ if (roundIconVal != 0) {
+ result.icon = roundIconVal;
+ result.nonLocalizedLabel = null;
+ } else {
+ int iconVal = sa.getResourceId(R.styleable.AndroidManifestInstrumentation_icon, 0);
+ if (iconVal != 0) {
+ result.icon = iconVal;
+ result.nonLocalizedLabel = null;
+ }
+ }
+
+ int logoVal = sa.getResourceId(R.styleable.AndroidManifestInstrumentation_logo, 0);
+ if (logoVal != 0) {
+ result.logo = logoVal;
+ }
+
+ int bannerVal = sa.getResourceId(R.styleable.AndroidManifestInstrumentation_banner, 0);
+ if (bannerVal != 0) {
+ result.banner = bannerVal;
+ }
+
+ TypedValue v = sa.peekValue(R.styleable.AndroidManifestInstrumentation_label);
+ if (v != null && (result.labelRes = v.resourceId) == 0) {
+ result.nonLocalizedLabel = v.coerceToString();
+ }
+
+ result.setPackageNameInternal(packageName);
+
+ String str;
+ // Note: don't allow this value to be a reference to a resource
+ // that may change.
+ str = sa.getNonResourceString(R.styleable.AndroidManifestInstrumentation_targetPackage);
+ result.setTargetPackage(str);
+
+ str = sa.getNonResourceString(
+ R.styleable.AndroidManifestInstrumentation_targetProcesses);
+ result.setTargetProcesses(str);
+ result.handleProfiling = sa.getBoolean(
+ R.styleable.AndroidManifestInstrumentation_handleProfiling, false);
+ result.functionalTest = sa.getBoolean(
+ R.styleable.AndroidManifestInstrumentation_functionalTest, false);
+
+ } finally {
+ if (sa != null) {
+ sa.recycle();
+ }
+ }
+
+ boolean success = parseAllMetaData(parsingPackage, res, parser,
+ "<instrumentation>", result, outError);
+ if (!success || outError[0] != null) {
+ return null;
+ }
+
+ return result;
+ }
+
+ public static ActivityInfo.WindowLayout parseLayout(Resources res, AttributeSet attrs) {
+ TypedArray sw = res.obtainAttributes(attrs,
+ R.styleable.AndroidManifestLayout);
+ int width = -1;
+ float widthFraction = -1f;
+ int height = -1;
+ float heightFraction = -1f;
+ final int widthType = sw.getType(
+ R.styleable.AndroidManifestLayout_defaultWidth);
+ if (widthType == TypedValue.TYPE_FRACTION) {
+ widthFraction = sw.getFraction(
+ R.styleable.AndroidManifestLayout_defaultWidth,
+ 1, 1, -1);
+ } else if (widthType == TypedValue.TYPE_DIMENSION) {
+ width = sw.getDimensionPixelSize(
+ R.styleable.AndroidManifestLayout_defaultWidth,
+ -1);
+ }
+ final int heightType = sw.getType(
+ R.styleable.AndroidManifestLayout_defaultHeight);
+ if (heightType == TypedValue.TYPE_FRACTION) {
+ heightFraction = sw.getFraction(
+ R.styleable.AndroidManifestLayout_defaultHeight,
+ 1, 1, -1);
+ } else if (heightType == TypedValue.TYPE_DIMENSION) {
+ height = sw.getDimensionPixelSize(
+ R.styleable.AndroidManifestLayout_defaultHeight,
+ -1);
+ }
+ int gravity = sw.getInt(
+ R.styleable.AndroidManifestLayout_gravity,
+ Gravity.CENTER);
+ int minWidth = sw.getDimensionPixelSize(
+ R.styleable.AndroidManifestLayout_minWidth,
+ -1);
+ int minHeight = sw.getDimensionPixelSize(
+ R.styleable.AndroidManifestLayout_minHeight,
+ -1);
+ sw.recycle();
+ return new ActivityInfo.WindowLayout(width, widthFraction,
+ height, heightFraction, gravity, minWidth, minHeight);
+ }
+
+ public static boolean parseIntentInfo(
+ ParsedIntentInfo intentInfo,
+ ParsingPackage parsingPackage,
+ Resources res, XmlResourceParser parser, boolean allowGlobs,
+ boolean allowAutoVerify, String[] outError
+ ) throws XmlPullParserException, IOException {
+ TypedArray sa = res.obtainAttributes(parser,
+ R.styleable.AndroidManifestIntentFilter);
+
+ int priority = sa.getInt(
+ R.styleable.AndroidManifestIntentFilter_priority, 0);
+ intentInfo.setPriority(priority);
+
+ int order = sa.getInt(
+ R.styleable.AndroidManifestIntentFilter_order, 0);
+ intentInfo.setOrder(order);
+
+ TypedValue v = sa.peekValue(
+ R.styleable.AndroidManifestIntentFilter_label);
+ if (v != null && (intentInfo.labelRes = v.resourceId) == 0) {
+ intentInfo.nonLocalizedLabel = v.coerceToString();
+ }
+
+ int roundIconVal = PackageParser.sUseRoundIcon ? sa.getResourceId(
+ R.styleable.AndroidManifestIntentFilter_roundIcon, 0) : 0;
+ if (roundIconVal != 0) {
+ intentInfo.icon = roundIconVal;
+ } else {
+ intentInfo.icon = sa.getResourceId(
+ R.styleable.AndroidManifestIntentFilter_icon, 0);
+ }
+
+ if (allowAutoVerify) {
+ intentInfo.setAutoVerify(sa.getBoolean(
+ R.styleable.AndroidManifestIntentFilter_autoVerify,
+ false));
+ }
+
+ sa.recycle();
+
+ int outerDepth = parser.getDepth();
+ int type;
+ while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
+ && (type != XmlPullParser.END_TAG || parser.getDepth() > outerDepth)) {
+ if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
+ continue;
+ }
+
+ String nodeName = parser.getName();
+ if (nodeName.equals("action")) {
+ String value = parser.getAttributeValue(
+ PackageParser.ANDROID_RESOURCES, "name");
+ if (TextUtils.isEmpty(value)) {
+ outError[0] = "No value supplied for <android:name>";
+ return false;
+ }
+ XmlUtils.skipCurrentTag(parser);
+
+ intentInfo.addAction(value);
+ } else if (nodeName.equals("category")) {
+ String value = parser.getAttributeValue(
+ PackageParser.ANDROID_RESOURCES, "name");
+ if (TextUtils.isEmpty(value)) {
+ outError[0] = "No value supplied for <android:name>";
+ return false;
+ }
+ XmlUtils.skipCurrentTag(parser);
+
+ intentInfo.addCategory(value);
+
+ } else if (nodeName.equals("data")) {
+ sa = res.obtainAttributes(parser,
+ R.styleable.AndroidManifestData);
+
+ String str = sa.getNonConfigurationString(
+ R.styleable.AndroidManifestData_mimeType, 0);
+ if (str != null) {
+ try {
+ intentInfo.addRawDataType(str);
+ } catch (IntentFilter.MalformedMimeTypeException e) {
+ outError[0] = e.toString();
+ sa.recycle();
+ return false;
+ }
+ }
+
+ str = sa.getNonConfigurationString(
+ R.styleable.AndroidManifestData_scheme, 0);
+ if (str != null) {
+ intentInfo.addDataScheme(str);
+ }
+
+ str = sa.getNonConfigurationString(
+ R.styleable.AndroidManifestData_ssp, 0);
+ if (str != null) {
+ intentInfo.addDataSchemeSpecificPart(str, PatternMatcher.PATTERN_LITERAL);
+ }
+
+ str = sa.getNonConfigurationString(
+ R.styleable.AndroidManifestData_sspPrefix, 0);
+ if (str != null) {
+ intentInfo.addDataSchemeSpecificPart(str, PatternMatcher.PATTERN_PREFIX);
+ }
+
+ str = sa.getNonConfigurationString(
+ R.styleable.AndroidManifestData_sspPattern, 0);
+ if (str != null) {
+ if (!allowGlobs) {
+ outError[0] = "sspPattern not allowed here; ssp must be literal";
+ return false;
+ }
+ intentInfo.addDataSchemeSpecificPart(str, PatternMatcher.PATTERN_SIMPLE_GLOB);
+ }
+
+ String host = sa.getNonConfigurationString(
+ R.styleable.AndroidManifestData_host, 0);
+ String port = sa.getNonConfigurationString(
+ R.styleable.AndroidManifestData_port, 0);
+ if (host != null) {
+ intentInfo.addDataAuthority(host, port);
+ }
+
+ str = sa.getNonConfigurationString(
+ R.styleable.AndroidManifestData_path, 0);
+ if (str != null) {
+ intentInfo.addDataPath(str, PatternMatcher.PATTERN_LITERAL);
+ }
+
+ str = sa.getNonConfigurationString(
+ R.styleable.AndroidManifestData_pathPrefix, 0);
+ if (str != null) {
+ intentInfo.addDataPath(str, PatternMatcher.PATTERN_PREFIX);
+ }
+
+ str = sa.getNonConfigurationString(
+ R.styleable.AndroidManifestData_pathPattern, 0);
+ if (str != null) {
+ if (!allowGlobs) {
+ outError[0] = "pathPattern not allowed here; path must be literal";
+ return false;
+ }
+ intentInfo.addDataPath(str, PatternMatcher.PATTERN_SIMPLE_GLOB);
+ }
+
+ str = sa.getNonConfigurationString(
+ R.styleable.AndroidManifestData_pathAdvancedPattern, 0);
+ if (str != null) {
+ if (!allowGlobs) {
+ outError[0] = "pathAdvancedPattern not allowed here; path must be literal";
+ return false;
+ }
+ intentInfo.addDataPath(str, PatternMatcher.PATTERN_ADVANCED_GLOB);
+ }
+
+ sa.recycle();
+ XmlUtils.skipCurrentTag(parser);
+ } else if (!PackageParser.RIGID_PARSER) {
+ Slog.w(TAG, "Unknown element under <intent-filter>: "
+ + parser.getName() + " at " + parsingPackage.getBaseCodePath() + " "
+ + parser.getPositionDescription());
+ XmlUtils.skipCurrentTag(parser);
+ } else {
+ outError[0] = "Bad element under <intent-filter>: " + parser.getName();
+ return false;
+ }
+ }
+
+ intentInfo.hasDefault = intentInfo.hasCategory(Intent.CATEGORY_DEFAULT);
+
+ if (PackageParser.DEBUG_PARSER) {
+ final StringBuilder cats = new StringBuilder("Intent d=");
+ cats.append(intentInfo.hasDefault);
+ cats.append(", cat=");
+
+ final Iterator<String> it = intentInfo.categoriesIterator();
+ if (it != null) {
+ while (it.hasNext()) {
+ cats.append(' ');
+ cats.append(it.next());
+ }
+ }
+ Slog.d(TAG, cats.toString());
+ }
+
+ return true;
+ }
+
+ private static boolean parseAllMetaData(
+ ParsingPackage parsingPackage,
+ Resources res, XmlResourceParser parser, String tag,
+ ParsedComponent outInfo,
+ String[] outError
+ ) throws XmlPullParserException, IOException {
+ int outerDepth = parser.getDepth();
+ int type;
+ while ((type = parser.next()) != XmlPullParser.END_DOCUMENT
+ && (type != XmlPullParser.END_TAG
+ || parser.getDepth() > outerDepth)) {
+ if (type == XmlPullParser.END_TAG || type == XmlPullParser.TEXT) {
+ continue;
+ }
+
+ if (parser.getName().equals("meta-data")) {
+ if ((outInfo.metaData = ApkParseUtils.parseMetaData(parsingPackage, res, parser,
+ outInfo.metaData, outError)) == null) {
+ return false;
+ }
+ } else {
+ if (!PackageParser.RIGID_PARSER) {
+ Slog.w(TAG, "Unknown element under " + tag + ": "
+ + parser.getName() + " at " + parsingPackage.getBaseCodePath() + " "
+ + parser.getPositionDescription());
+ XmlUtils.skipCurrentTag(parser);
+ continue;
+ } else {
+ outError[0] = "Bad element under " + tag + ": " + parser.getName();
+ }
+ }
+ }
+
+ return true;
+ }
+
+ public static boolean isImplicitlyExposedIntent(IntentFilter intent) {
+ return intent.hasCategory(Intent.CATEGORY_BROWSABLE)
+ || intent.hasAction(Intent.ACTION_SEND)
+ || intent.hasAction(Intent.ACTION_SENDTO)
+ || intent.hasAction(Intent.ACTION_SEND_MULTIPLE);
+ }
+}
diff --git a/core/java/android/content/pm/parsing/PackageImpl.java b/core/java/android/content/pm/parsing/PackageImpl.java
new file mode 100644
index 000000000000..363cf80a0a1d
--- /dev/null
+++ b/core/java/android/content/pm/parsing/PackageImpl.java
@@ -0,0 +1,3213 @@
+/*
+ * Copyright (C) 2019 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 android.content.pm.parsing;
+
+import static android.os.Build.VERSION_CODES.DONUT;
+
+import android.annotation.NonNull;
+import android.annotation.Nullable;
+import android.content.Intent;
+import android.content.pm.ActivityInfo;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.ConfigurationInfo;
+import android.content.pm.FeatureGroupInfo;
+import android.content.pm.FeatureInfo;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageParser;
+import android.content.pm.ProviderInfo;
+import android.content.pm.ServiceInfo;
+import android.content.pm.SharedLibraryInfo;
+import android.content.pm.parsing.ComponentParseUtils.ParsedActivity;
+import android.content.pm.parsing.ComponentParseUtils.ParsedActivityIntentInfo;
+import android.content.pm.parsing.ComponentParseUtils.ParsedInstrumentation;
+import android.content.pm.parsing.ComponentParseUtils.ParsedIntentInfo;
+import android.content.pm.parsing.ComponentParseUtils.ParsedPermission;
+import android.content.pm.parsing.ComponentParseUtils.ParsedPermissionGroup;
+import android.content.pm.parsing.ComponentParseUtils.ParsedProvider;
+import android.content.pm.parsing.ComponentParseUtils.ParsedService;
+import android.content.res.TypedArray;
+import android.os.Build;
+import android.os.Bundle;
+import android.os.Environment;
+import android.os.Parcel;
+import android.os.UserHandle;
+import android.os.storage.StorageManager;
+import android.text.TextUtils;
+import android.util.ArrayMap;
+import android.util.ArraySet;
+import android.util.SparseArray;
+
+import com.android.internal.R;
+import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.ArrayUtils;
+import com.android.server.SystemConfig;
+
+import java.security.PublicKey;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.Set;
+import java.util.UUID;
+
+/**
+ * The backing data for a package that was parsed from disk.
+ *
+ * TODO(b/135203078): Convert Lists used as sets into Sets, to better express intended use case
+ * TODO(b/135203078): Field nullability annotations
+ * TODO(b/135203078): Convert = 1 fields into Booleans
+ * TODO(b/135203078): Make all lists nullable and Collections.unmodifiable immutable when returned.
+ * Prefer add/set methods if adding is necessary.
+ * TODO(b/135203078): Consider comments to disable auto-format and single-line, single-space all the
+ * get/set methods to make this class far more compact. Maybe even separate some logic into parent
+ * classes, assuming there is no overhead.
+ * TODO(b/135203078): Copy documentation from PackageParser#Package for the relevant fields included
+ * here. Should clarify and clean up any differences. Also consider renames if it helps make
+ * things clearer.
+ * TODO(b/135203078): Intern all possibl e String values? Initial refactor just mirrored old
+ * behavior.
+ *
+ * @hide
+ */
+public final class PackageImpl implements ParsingPackage, ParsedPackage, AndroidPackage,
+ AndroidPackageWrite {
+
+ private static final String TAG = "PackageImpl";
+
+ // Resource boolean are -1, so 1 means we don't know the value.
+ private int supportsSmallScreens = 1;
+ private int supportsNormalScreens = 1;
+ private int supportsLargeScreens = 1;
+ private int supportsXLargeScreens = 1;
+ private int resizeable = 1;
+ private int anyDensity = 1;
+
+ private long[] lastPackageUsageTimeInMills =
+ new long[PackageManager.NOTIFY_PACKAGE_USE_REASONS_COUNT];
+
+ private int versionCode;
+ private int versionCodeMajor;
+ private int baseRevisionCode;
+ private String versionName;
+
+ private boolean coreApp;
+ private int compileSdkVersion;
+ private String compileSdkVersionCodename;
+
+ private String packageName;
+ private String realPackage;
+ private String manifestPackageName;
+ private String baseCodePath;
+
+ private boolean requiredForAllUsers;
+ private String restrictedAccountType;
+ private String requiredAccountType;
+
+ private boolean baseHardwareAccelerated;
+
+ private String overlayTarget;
+ private String overlayTargetName;
+ private String overlayCategory;
+ private int overlayPriority;
+ private boolean overlayIsStatic;
+
+ private String staticSharedLibName;
+ private long staticSharedLibVersion;
+ private ArrayList<String> libraryNames;
+ private ArrayList<String> usesLibraries;
+ private ArrayList<String> usesOptionalLibraries;
+
+ private ArrayList<String> usesStaticLibraries;
+ private long[] usesStaticLibrariesVersions;
+ private String[][] usesStaticLibrariesCertDigests;
+
+ private String sharedUserId;
+
+ private int sharedUserLabel;
+ private ArrayList<ConfigurationInfo> configPreferences;
+ private ArrayList<FeatureInfo> reqFeatures;
+ private ArrayList<FeatureGroupInfo> featureGroups;
+
+ private byte[] restrictUpdateHash;
+
+ private ArrayList<String> originalPackages;
+ private ArrayList<String> adoptPermissions;
+
+ private ArrayList<String> requestedPermissions;
+ private ArrayList<String> implicitPermissions;
+
+ private ArraySet<String> upgradeKeySets;
+ private Map<String, ArraySet<PublicKey>> keySetMapping;
+
+ private ArrayList<String> protectedBroadcasts;
+
+ @Nullable
+ private ArrayList<ComponentParseUtils.ParsedActivity> activities;
+
+ @Nullable
+ private ArrayList<ComponentParseUtils.ParsedActivity> receivers;
+
+ @Nullable
+ private ArrayList<ComponentParseUtils.ParsedService> services;
+
+ @Nullable
+ private ArrayList<ComponentParseUtils.ParsedProvider> providers;
+
+ @Nullable
+ private ArrayList<ComponentParseUtils.ParsedPermission> permissions;
+
+ @Nullable
+ private ArrayList<ComponentParseUtils.ParsedPermissionGroup> permissionGroups;
+
+ @Nullable
+ private ArrayList<ComponentParseUtils.ParsedInstrumentation> instrumentations;
+
+ private ArrayList<ParsedActivityIntentInfo> preferredActivityFilters;
+
+ private Bundle appMetaData;
+
+ private String volumeUuid;
+ private String applicationVolumeUuid;
+ private PackageParser.SigningDetails signingDetails;
+
+ private String codePath;
+
+ private boolean use32BitAbi;
+ private boolean visibleToInstantApps;
+
+ private String cpuAbiOverride;
+
+ private boolean isStub;
+
+ // TODO(b/135203078): Remove, should be unused
+ private int preferredOrder;
+
+ private boolean forceQueryable;
+
+ @Nullable
+ private ArrayList<Intent> queriesIntents;
+
+ @Nullable
+ private ArrayList<String> queriesPackages;
+
+ private String[] splitClassLoaderNames;
+ private String[] splitCodePaths;
+ private SparseArray<int[]> splitDependencies;
+ private int[] splitFlags;
+ private String[] splitNames;
+ private int[] splitRevisionCodes;
+
+ // TODO(b/135203078): Audit applicationInfo.something usages, which may be different from
+ // package.something usages. There were differing cases of package.field = versus
+ // package.appInfo.field =. This class assumes some obvious ones, like packageName,
+ // were collapsible, but kept the following separate.
+
+ private String applicationInfoBaseResourcePath;
+ private String applicationInfoCodePath;
+ private String applicationInfoResourcePath;
+ private String[] applicationInfoSplitResourcePaths;
+
+ private String appComponentFactory;
+ private String backupAgentName;
+ private int banner;
+ private int category;
+ private String classLoaderName;
+ private String className;
+ private int compatibleWidthLimitDp;
+ private String credentialProtectedDataDir;
+ private String dataDir;
+ private int descriptionRes;
+ private String deviceProtectedDataDir;
+ private boolean enabled;
+ private int flags;
+ private int fullBackupContent;
+ private boolean hiddenUntilInstalled;
+ private int icon;
+ private int iconRes;
+ private int installLocation = PackageParser.PARSE_DEFAULT_INSTALL_LOCATION;
+ private int labelRes;
+ private int largestWidthLimitDp;
+ private int logo;
+ private String manageSpaceActivityName;
+ private float maxAspectRatio;
+ private float minAspectRatio;
+ private int minSdkVersion;
+ private String name;
+ private String nativeLibraryDir;
+ private String nativeLibraryRootDir;
+ private boolean nativeLibraryRootRequiresIsa;
+ private int networkSecurityConfigRes;
+ private CharSequence nonLocalizedLabel;
+ private String permission;
+ private String primaryCpuAbi;
+ private int privateFlags;
+ private String processName;
+ private int requiresSmallestWidthDp;
+ private int roundIconRes;
+ private String secondaryCpuAbi;
+ private String secondaryNativeLibraryDir;
+ private String seInfo;
+ private String seInfoUser;
+ private int targetSandboxVersion;
+ private int targetSdkVersion;
+ private String taskAffinity;
+ private int theme;
+ private int uid = -1;
+ private int uiOptions;
+ private String[] usesLibraryFiles;
+ private List<SharedLibraryInfo> usesLibraryInfos;
+ private String zygotePreloadName;
+
+ @VisibleForTesting
+ public PackageImpl(
+ String packageName,
+ String baseCodePath,
+ TypedArray manifestArray,
+ boolean isCoreApp
+ ) {
+ this.packageName = TextUtils.safeIntern(packageName);
+ this.manifestPackageName = this.packageName;
+ this.baseCodePath = baseCodePath;
+
+ this.versionCode = manifestArray.getInteger(R.styleable.AndroidManifest_versionCode, 0);
+ this.versionCodeMajor = manifestArray.getInteger(
+ R.styleable.AndroidManifest_versionCodeMajor, 0);
+ this.baseRevisionCode = manifestArray.getInteger(R.styleable.AndroidManifest_revisionCode,
+ 0);
+ setVersionName(manifestArray.getNonConfigurationString(
+ R.styleable.AndroidManifest_versionName, 0));
+ this.coreApp = isCoreApp;
+
+ this.compileSdkVersion = manifestArray.getInteger(
+ R.styleable.AndroidManifest_compileSdkVersion, 0);
+ setCompileSdkVersionCodename(manifestArray.getNonConfigurationString(
+ R.styleable.AndroidManifest_compileSdkVersionCodename, 0));
+ }
+
+ private PackageImpl(String packageName) {
+ this.packageName = TextUtils.safeIntern(packageName);
+ this.manifestPackageName = this.packageName;
+ }
+
+ @VisibleForTesting
+ public static ParsingPackage forParsing(String packageName) {
+ return new PackageImpl(packageName);
+ }
+
+ @VisibleForTesting
+ public static ParsingPackage forParsing(
+ String packageName,
+ String baseCodePath,
+ TypedArray manifestArray,
+ boolean isCoreApp) {
+ return new PackageImpl(packageName, baseCodePath, manifestArray, isCoreApp);
+ }
+
+ /**
+ * Mock an unavailable {@link AndroidPackage} to use when removing a package from the system.
+ * This can occur if the package was installed on a storage device that has since been removed.
+ * Since the infrastructure uses {@link AndroidPackage}, but for this case only cares about
+ * volumeUuid, just fake it rather than having separate method paths.
+ */
+ public static AndroidPackage buildFakeForDeletion(String packageName, String volumeUuid) {
+ return new PackageImpl(packageName)
+ .setVolumeUuid(volumeUuid)
+ .hideAsParsed()
+ .hideAsFinal();
+ }
+
+ @Override
+ public ParsedPackage hideAsParsed() {
+ return this;
+ }
+
+ @Override
+ public AndroidPackage hideAsFinal() {
+ updateFlags();
+ return this;
+ }
+
+ @Override
+ @Deprecated
+ public AndroidPackageWrite mutate() {
+ return this;
+ }
+
+ private void updateFlags() {
+ if (supportsSmallScreens < 0 || (supportsSmallScreens > 0
+ && targetSdkVersion
+ >= Build.VERSION_CODES.DONUT)) {
+ this.flags |= ApplicationInfo.FLAG_SUPPORTS_SMALL_SCREENS;
+ }
+ if (supportsNormalScreens != 0) {
+ this.flags |= ApplicationInfo.FLAG_SUPPORTS_NORMAL_SCREENS;
+ }
+ if (supportsLargeScreens < 0 || (supportsLargeScreens > 0
+ && targetSdkVersion
+ >= Build.VERSION_CODES.DONUT)) {
+ this.flags |= ApplicationInfo.FLAG_SUPPORTS_LARGE_SCREENS;
+ }
+ if (supportsXLargeScreens < 0 || (supportsXLargeScreens > 0
+ && targetSdkVersion
+ >= Build.VERSION_CODES.GINGERBREAD)) {
+ this.flags |= ApplicationInfo.FLAG_SUPPORTS_XLARGE_SCREENS;
+ }
+ if (resizeable < 0 || (resizeable > 0
+ && targetSdkVersion
+ >= Build.VERSION_CODES.DONUT)) {
+ this.flags |= ApplicationInfo.FLAG_RESIZEABLE_FOR_SCREENS;
+ }
+ if (anyDensity < 0 || (anyDensity > 0
+ && targetSdkVersion
+ >= Build.VERSION_CODES.DONUT)) {
+ this.flags |= ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES;
+ }
+ }
+
+ @Override
+ public boolean usesCompatibilityMode() {
+ int flags = 0;
+
+ if (supportsSmallScreens < 0 || (supportsSmallScreens > 0
+ && targetSdkVersion
+ >= Build.VERSION_CODES.DONUT)) {
+ flags |= ApplicationInfo.FLAG_SUPPORTS_SMALL_SCREENS;
+ }
+ if (supportsNormalScreens != 0) {
+ flags |= ApplicationInfo.FLAG_SUPPORTS_NORMAL_SCREENS;
+ }
+ if (supportsLargeScreens < 0 || (supportsLargeScreens > 0
+ && targetSdkVersion
+ >= Build.VERSION_CODES.DONUT)) {
+ flags |= ApplicationInfo.FLAG_SUPPORTS_LARGE_SCREENS;
+ }
+ if (supportsXLargeScreens < 0 || (supportsXLargeScreens > 0
+ && targetSdkVersion
+ >= Build.VERSION_CODES.GINGERBREAD)) {
+ flags |= ApplicationInfo.FLAG_SUPPORTS_XLARGE_SCREENS;
+ }
+ if (resizeable < 0 || (resizeable > 0
+ && targetSdkVersion
+ >= Build.VERSION_CODES.DONUT)) {
+ flags |= ApplicationInfo.FLAG_RESIZEABLE_FOR_SCREENS;
+ }
+ if (anyDensity < 0 || (anyDensity > 0
+ && targetSdkVersion
+ >= Build.VERSION_CODES.DONUT)) {
+ flags |= ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES;
+ }
+
+ return targetSdkVersion < DONUT
+ || (flags & (ApplicationInfo.FLAG_SUPPORTS_LARGE_SCREENS
+ | ApplicationInfo.FLAG_SUPPORTS_NORMAL_SCREENS
+ | ApplicationInfo.FLAG_SUPPORTS_SMALL_SCREENS
+ | ApplicationInfo.FLAG_RESIZEABLE_FOR_SCREENS
+ | ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES
+ | ApplicationInfo.FLAG_SUPPORTS_XLARGE_SCREENS)) == 0;
+ }
+
+ @Override
+ public String getBaseCodePath() {
+ return baseCodePath;
+ }
+
+ @Override
+ public int getTargetSdkVersion() {
+ return targetSdkVersion;
+ }
+
+ @Override
+ public String getPackageName() {
+ return packageName;
+ }
+
+ @Override
+ public String getProcessName() {
+ return processName;
+ }
+
+ @Override
+ public String getPermission() {
+ return permission;
+ }
+
+ @Override
+ public String getStaticSharedLibName() {
+ return staticSharedLibName;
+ }
+
+ @Override
+ public long getStaticSharedLibVersion() {
+ return staticSharedLibVersion;
+ }
+
+ @Override
+ public String getSharedUserId() {
+ return sharedUserId;
+ }
+
+ @Override
+ public List<String> getRequestedPermissions() {
+ return requestedPermissions == null ? Collections.emptyList() : requestedPermissions;
+ }
+
+ @Nullable
+ @Override
+ public List<ParsedInstrumentation> getInstrumentations() {
+ return instrumentations;
+ }
+
+ @Override
+ public Map<String, ArraySet<PublicKey>> getKeySetMapping() {
+ return keySetMapping == null ? Collections.emptyMap() : keySetMapping;
+ }
+
+ @Override
+ public float getMaxAspectRatio() {
+ return maxAspectRatio;
+ }
+
+ @Override
+ public float getMinAspectRatio() {
+ return minAspectRatio;
+ }
+
+ @NonNull
+ @Override
+ public List<String> getLibraryNames() {
+ return libraryNames == null ? Collections.emptyList() : libraryNames;
+ }
+
+ @Override
+ public List<ParsedActivity> getActivities() {
+ return activities == null ? Collections.emptyList()
+ : activities;
+ }
+
+ @Override
+ public Bundle getAppMetaData() {
+ return appMetaData;
+ }
+
+ @Nullable
+ @Override
+ public List<String> getUsesLibraries() {
+ return usesLibraries;
+ }
+
+ @Nullable
+ @Override
+ public List<String> getUsesStaticLibraries() {
+ return usesStaticLibraries;
+ }
+
+ @Override
+ public boolean isBaseHardwareAccelerated() {
+ return baseHardwareAccelerated;
+ }
+
+ @Override
+ public int getUiOptions() {
+ return uiOptions;
+ }
+
+ // TODO(b/135203078): Checking flags directly can be error prone,
+ // consider separate interface methods?
+ @Override
+ public int getFlags() {
+ return flags;
+ }
+
+ // TODO(b/135203078): Checking flags directly can be error prone,
+ // consider separate interface methods?
+ @Override
+ public int getPrivateFlags() {
+ return privateFlags;
+ }
+
+ @Override
+ public String getTaskAffinity() {
+ return taskAffinity;
+ }
+
+ @Nullable
+ @Override
+ public List<String> getOriginalPackages() {
+ return originalPackages;
+ }
+
+ @Override
+ public PackageParser.SigningDetails getSigningDetails() {
+ return signingDetails;
+ }
+
+ @Override
+ public String getVolumeUuid() {
+ return volumeUuid;
+ }
+
+ @Nullable
+ @Override
+ public List<ParsedPermissionGroup> getPermissionGroups() {
+ return permissionGroups;
+ }
+
+ @Nullable
+ @Override
+ public List<ParsedPermission> getPermissions() {
+ return permissions;
+ }
+
+ @Override
+ public String getCpuAbiOverride() {
+ return cpuAbiOverride;
+ }
+
+ @Override
+ public String getPrimaryCpuAbi() {
+ return primaryCpuAbi;
+ }
+
+ @Override
+ public String getSecondaryCpuAbi() {
+ return secondaryCpuAbi;
+ }
+
+ @Override
+ public boolean isUse32BitAbi() {
+ return use32BitAbi;
+ }
+
+ @Override
+ public boolean isForceQueryable() {
+ return forceQueryable;
+ }
+
+ @Override
+ public String getCodePath() {
+ return codePath;
+ }
+
+ @Override
+ public String getNativeLibraryDir() {
+ return nativeLibraryDir;
+ }
+
+ @Override
+ public String getNativeLibraryRootDir() {
+ return nativeLibraryRootDir;
+ }
+
+ @Override
+ public boolean isNativeLibraryRootRequiresIsa() {
+ return nativeLibraryRootRequiresIsa;
+ }
+
+ // TODO(b/135203078): Does nothing, remove?
+ @Override
+ public int getPreferredOrder() {
+ return preferredOrder;
+ }
+
+ @Override
+ public long getLongVersionCode() {
+ return PackageInfo.composeLongVersionCode(versionCodeMajor, versionCode);
+ }
+
+ @Override
+ public PackageImpl setIsOverlay(boolean isOverlay) {
+ this.privateFlags = isOverlay
+ ? this.privateFlags | ApplicationInfo.PRIVATE_FLAG_IS_RESOURCE_OVERLAY
+ : this.privateFlags & ~ApplicationInfo.PRIVATE_FLAG_IS_RESOURCE_OVERLAY;
+ return this;
+ }
+
+ @Override
+ public PackageImpl setExternalStorage(boolean externalStorage) {
+ this.flags = externalStorage
+ ? this.flags | ApplicationInfo.FLAG_EXTERNAL_STORAGE
+ : this.flags & ~ApplicationInfo.FLAG_EXTERNAL_STORAGE;
+ return this;
+ }
+
+ @Override
+ public PackageImpl setIsolatedSplitLoading(boolean isolatedSplitLoading) {
+ this.privateFlags = isolatedSplitLoading
+ ? this.privateFlags | ApplicationInfo.PRIVATE_FLAG_ISOLATED_SPLIT_LOADING
+ : this.privateFlags & ~ApplicationInfo.PRIVATE_FLAG_ISOLATED_SPLIT_LOADING;
+ return this;
+ }
+
+ @Override
+ public PackageImpl sortActivities() {
+ Collections.sort(this.activities, (a1, a2) -> Integer.compare(a2.order, a1.order));
+ return this;
+ }
+
+ @Override
+ public PackageImpl sortReceivers() {
+ Collections.sort(this.receivers, (a1, a2) -> Integer.compare(a2.order, a1.order));
+ return this;
+ }
+
+ @Override
+ public PackageImpl sortServices() {
+ Collections.sort(this.services, (a1, a2) -> Integer.compare(a2.order, a1.order));
+ return this;
+ }
+
+ @Override
+ public PackageImpl setBaseRevisionCode(int baseRevisionCode) {
+ this.baseRevisionCode = baseRevisionCode;
+ return this;
+ }
+
+ @Override
+ public PackageImpl setPreferredOrder(int preferredOrder) {
+ this.preferredOrder = preferredOrder;
+ return this;
+ }
+
+ @Override
+ public PackageImpl setVersionName(String versionName) {
+ this.versionName = TextUtils.safeIntern(versionName);
+ return this;
+ }
+
+ @Override
+ public ParsingPackage setCompileSdkVersion(int compileSdkVersion) {
+ this.compileSdkVersion = compileSdkVersion;
+ return this;
+ }
+
+ @Override
+ public ParsingPackage setCompileSdkVersionCodename(String compileSdkVersionCodename) {
+ this.compileSdkVersionCodename = TextUtils.safeIntern(compileSdkVersionCodename);
+ return this;
+ }
+
+ @Override
+ public PackageImpl setMaxAspectRatio(float maxAspectRatio) {
+ this.maxAspectRatio = maxAspectRatio;
+ return this;
+ }
+
+ @Override
+ public PackageImpl setMinAspectRatio(float minAspectRatio) {
+ this.minAspectRatio = minAspectRatio;
+ return this;
+ }
+
+ @Override
+ public PackageImpl setMinSdkVersion(int minSdkVersion) {
+ this.minSdkVersion = minSdkVersion;
+ return this;
+ }
+
+ @Override
+ public PackageImpl setTargetSdkVersion(int targetSdkVersion) {
+ this.targetSdkVersion = targetSdkVersion;
+ return this;
+ }
+
+ @Override
+ public PackageImpl setRealPackage(String realPackage) {
+ this.realPackage = realPackage;
+ return this;
+ }
+
+ @Override
+ public PackageImpl addConfigPreference(ConfigurationInfo configPreference) {
+ this.configPreferences = ArrayUtils.add(this.configPreferences, configPreference);
+ return this;
+ }
+
+ @Override
+ public PackageImpl addReqFeature(FeatureInfo reqFeature) {
+ this.reqFeatures = ArrayUtils.add(this.reqFeatures, reqFeature);
+ return this;
+ }
+
+ @Override
+ public PackageImpl addFeatureGroup(FeatureGroupInfo featureGroup) {
+ this.featureGroups = ArrayUtils.add(this.featureGroups, featureGroup);
+ return this;
+ }
+
+ @Override
+ public PackageImpl addProtectedBroadcast(String protectedBroadcast) {
+ if (this.protectedBroadcasts == null
+ || !this.protectedBroadcasts.contains(protectedBroadcast)) {
+ this.protectedBroadcasts = ArrayUtils.add(this.protectedBroadcasts,
+ TextUtils.safeIntern(protectedBroadcast));
+ }
+ return this;
+ }
+
+ @Override
+ public PackageImpl addInstrumentation(ParsedInstrumentation instrumentation) {
+ this.instrumentations = ArrayUtils.add(this.instrumentations, instrumentation);
+ return this;
+ }
+
+ @Override
+ public PackageImpl addOriginalPackage(String originalPackage) {
+ this.originalPackages = ArrayUtils.add(this.originalPackages, originalPackage);
+ return this;
+ }
+
+ @Override
+ public PackageImpl addAdoptPermission(String adoptPermission) {
+ this.adoptPermissions = ArrayUtils.add(this.adoptPermissions, adoptPermission);
+ return this;
+ }
+
+ @Override
+ public PackageImpl addPermission(ParsedPermission permission) {
+ this.permissions = ArrayUtils.add(this.permissions, permission);
+ return this;
+ }
+
+ @Override
+ public PackageImpl removePermission(int index) {
+ this.permissions.remove(index);
+ return this;
+ }
+
+ @Override
+ public PackageImpl addPermissionGroup(ParsedPermissionGroup permissionGroup) {
+ this.permissionGroups = ArrayUtils.add(this.permissionGroups, permissionGroup);
+ return this;
+ }
+
+ @Override
+ public PackageImpl addRequestedPermission(String permission) {
+ this.requestedPermissions = ArrayUtils.add(this.requestedPermissions,
+ TextUtils.safeIntern(permission));
+ return this;
+ }
+
+ @Override
+ public PackageImpl addImplicitPermission(String permission) {
+ this.implicitPermissions = ArrayUtils.add(this.implicitPermissions,
+ TextUtils.safeIntern(permission));
+ return this;
+ }
+
+ @Override
+ public PackageImpl addKeySet(String keySetName, PublicKey publicKey) {
+ if (keySetMapping == null) {
+ keySetMapping = new ArrayMap<>();
+ }
+
+ ArraySet<PublicKey> publicKeys = keySetMapping.get(keySetName);
+ if (publicKeys == null) {
+ publicKeys = new ArraySet<>();
+ keySetMapping.put(keySetName, publicKeys);
+ }
+
+ publicKeys.add(publicKey);
+
+ return this;
+ }
+
+ @Override
+ public ParsingPackage addActivity(ParsedActivity parsedActivity) {
+ this.activities = ArrayUtils.add(this.activities, parsedActivity);
+ return this;
+ }
+
+ @Override
+ public ParsingPackage addReceiver(ParsedActivity parsedReceiver) {
+ this.receivers = ArrayUtils.add(this.receivers, parsedReceiver);
+ return this;
+ }
+
+ @Override
+ public ParsingPackage addService(ParsedService parsedService) {
+ this.services = ArrayUtils.add(this.services, parsedService);
+ return this;
+ }
+
+ @Override
+ public ParsingPackage addProvider(ParsedProvider parsedProvider) {
+ this.providers = ArrayUtils.add(this.providers, parsedProvider);
+ return this;
+ }
+
+ @Override
+ public PackageImpl addLibraryName(String libraryName) {
+ this.libraryNames = ArrayUtils.add(this.libraryNames, TextUtils.safeIntern(libraryName));
+ return this;
+ }
+
+ @Override
+ public PackageImpl addUsesLibrary(String libraryName) {
+ this.usesLibraries = ArrayUtils.add(this.usesLibraries, TextUtils.safeIntern(libraryName));
+ return this;
+ }
+
+ @Override
+ public PackageImpl addUsesOptionalLibrary(String libraryName) {
+ this.usesOptionalLibraries = ArrayUtils.add(this.usesOptionalLibraries,
+ TextUtils.safeIntern(libraryName));
+ return this;
+ }
+
+ @Override
+ public PackageImpl removeUsesOptionalLibrary(String libraryName) {
+ this.usesOptionalLibraries = ArrayUtils.remove(this.usesOptionalLibraries, libraryName);
+ return this;
+ }
+
+ @Override
+ public PackageImpl addUsesStaticLibrary(String libraryName) {
+ this.usesStaticLibraries = ArrayUtils.add(this.usesStaticLibraries,
+ TextUtils.safeIntern(libraryName));
+ return this;
+ }
+
+ @Override
+ public PackageImpl addUsesStaticLibraryVersion(long version) {
+ this.usesStaticLibrariesVersions = ArrayUtils.appendLong(this.usesStaticLibrariesVersions,
+ version, true);
+ return this;
+ }
+
+ @Override
+ public PackageImpl addUsesStaticLibraryCertDigests(String[] certSha256Digests) {
+ this.usesStaticLibrariesCertDigests = ArrayUtils.appendElement(String[].class,
+ this.usesStaticLibrariesCertDigests, certSha256Digests, true);
+ return this;
+ }
+
+ @Override
+ public PackageImpl addPreferredActivityFilter(
+ ParsedActivityIntentInfo parsedActivityIntentInfo) {
+ this.preferredActivityFilters = ArrayUtils.add(this.preferredActivityFilters,
+ parsedActivityIntentInfo);
+ return this;
+ }
+
+ @Override
+ public PackageImpl addQueriesIntent(Intent intent) {
+ this.queriesIntents = ArrayUtils.add(this.queriesIntents, intent);
+ return this;
+ }
+
+ @Override
+ public PackageImpl addQueriesPackage(String packageName) {
+ this.queriesPackages = ArrayUtils.add(this.queriesPackages,
+ TextUtils.safeIntern(packageName));
+ return this;
+ }
+
+ @Override
+ public PackageImpl setSupportsSmallScreens(int supportsSmallScreens) {
+ if (supportsSmallScreens == 1) {
+ return this;
+ }
+
+ this.supportsSmallScreens = supportsSmallScreens;
+ return this;
+ }
+
+ @Override
+ public PackageImpl setSupportsNormalScreens(int supportsNormalScreens) {
+ if (supportsNormalScreens == 1) {
+ return this;
+ }
+
+ this.supportsNormalScreens = supportsNormalScreens;
+ return this;
+ }
+
+ @Override
+ public PackageImpl setSupportsLargeScreens(int supportsLargeScreens) {
+ if (supportsLargeScreens == 1) {
+ return this;
+ }
+
+ this.supportsLargeScreens = supportsLargeScreens;
+ return this;
+ }
+
+ @Override
+ public PackageImpl setSupportsXLargeScreens(int supportsXLargeScreens) {
+ if (supportsXLargeScreens == 1) {
+ return this;
+ }
+
+ this.supportsXLargeScreens = supportsXLargeScreens;
+ return this;
+ }
+
+ @Override
+ public PackageImpl setResizeable(int resizeable) {
+ if (resizeable == 1) {
+ return this;
+ }
+
+ this.resizeable = resizeable;
+ return this;
+ }
+
+ @Override
+ public PackageImpl setAnyDensity(int anyDensity) {
+ if (anyDensity == 1) {
+ return this;
+ }
+
+ this.anyDensity = anyDensity;
+ return this;
+ }
+
+ @Override
+ public PackageImpl setRequiresSmallestWidthDp(int requiresSmallestWidthDp) {
+ this.requiresSmallestWidthDp = requiresSmallestWidthDp;
+ return this;
+ }
+
+ @Override
+ public PackageImpl setCompatibleWidthLimitDp(int compatibleWidthLimitDp) {
+ this.compatibleWidthLimitDp = compatibleWidthLimitDp;
+ return this;
+ }
+
+ @Override
+ public PackageImpl setLargestWidthLimitDp(int largestWidthLimitDp) {
+ this.largestWidthLimitDp = largestWidthLimitDp;
+ return this;
+ }
+
+ @Override
+ public PackageImpl setInstallLocation(int installLocation) {
+ this.installLocation = installLocation;
+ return this;
+ }
+
+ @Override
+ public PackageImpl setTargetSandboxVersion(int targetSandboxVersion) {
+ this.targetSandboxVersion = targetSandboxVersion;
+ return this;
+ }
+
+ @Override
+ public PackageImpl setRequiredForAllUsers(boolean requiredForAllUsers) {
+ this.requiredForAllUsers = requiredForAllUsers;
+ return this;
+ }
+
+ @Override
+ public PackageImpl setRestrictedAccountType(String restrictedAccountType) {
+ this.restrictedAccountType = restrictedAccountType;
+ return this;
+ }
+
+ @Override
+ public PackageImpl setRequiredAccountType(String requiredAccountType) {
+ this.requiredAccountType = requiredAccountType;
+ return this;
+ }
+
+ @Override
+ public PackageImpl setBaseHardwareAccelerated(boolean baseHardwareAccelerated) {
+ this.baseHardwareAccelerated = baseHardwareAccelerated;
+
+ this.flags = baseHardwareAccelerated
+ ? this.flags | ApplicationInfo.FLAG_HARDWARE_ACCELERATED
+ : this.flags & ~ApplicationInfo.FLAG_HARDWARE_ACCELERATED;
+
+ return this;
+ }
+
+ @Override
+ public PackageImpl setHasDomainUrls(boolean hasDomainUrls) {
+ this.privateFlags = hasDomainUrls
+ ? this.privateFlags | ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS
+ : this.privateFlags & ~ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS;
+ return this;
+ }
+
+ @Override
+ public PackageImpl setAppMetaData(Bundle appMetaData) {
+ this.appMetaData = appMetaData;
+ return this;
+ }
+
+ @Override
+ public PackageImpl setOverlayTarget(String overlayTarget) {
+ this.overlayTarget = overlayTarget;
+ return this;
+ }
+
+ @Override
+ public PackageImpl setOverlayTargetName(String overlayTargetName) {
+ this.overlayTargetName = overlayTargetName;
+ return this;
+ }
+
+ @Override
+ public PackageImpl setOverlayCategory(String overlayCategory) {
+ this.overlayCategory = overlayCategory;
+ return this;
+ }
+
+ @Override
+ public PackageImpl setOverlayPriority(int overlayPriority) {
+ this.overlayPriority = overlayPriority;
+ return this;
+ }
+
+ @Override
+ public PackageImpl setOverlayIsStatic(boolean overlayIsStatic) {
+ this.overlayIsStatic = overlayIsStatic;
+ return this;
+ }
+
+ @Override
+ public PackageImpl setStaticSharedLibName(String staticSharedLibName) {
+ this.staticSharedLibName = TextUtils.safeIntern(staticSharedLibName);
+ return this;
+ }
+
+ @Override
+ public PackageImpl setStaticSharedLibVersion(long staticSharedLibVersion) {
+ this.staticSharedLibVersion = staticSharedLibVersion;
+ return this;
+ }
+
+ @Override
+ public PackageImpl setSharedUserId(String sharedUserId) {
+ this.sharedUserId = TextUtils.safeIntern(sharedUserId);
+ return this;
+ }
+
+ @Override
+ public PackageImpl setSharedUserLabel(int sharedUserLabel) {
+ this.sharedUserLabel = sharedUserLabel;
+ return this;
+ }
+
+ @Override
+ public PackageImpl setRestrictUpdateHash(byte[] restrictUpdateHash) {
+ this.restrictUpdateHash = restrictUpdateHash;
+ return this;
+ }
+
+ @Override
+ public PackageImpl setUpgradeKeySets(ArraySet<String> upgradeKeySets) {
+ this.upgradeKeySets = upgradeKeySets;
+ return this;
+ }
+
+ @Override
+ public PackageImpl setVolumeUuid(String volumeUuid) {
+ this.volumeUuid = volumeUuid;
+ return this;
+ }
+
+ @Deprecated
+ @Override
+ public PackageImpl setApplicationVolumeUuid(String applicationVolumeUuid) {
+ this.applicationVolumeUuid = applicationVolumeUuid;
+ return this;
+ }
+
+ @Override
+ public PackageImpl setSigningDetails(PackageParser.SigningDetails signingDetails) {
+ this.signingDetails = signingDetails;
+ return this;
+ }
+
+ @Override
+ public PackageImpl setCodePath(String codePath) {
+ this.codePath = codePath;
+ return this;
+ }
+
+ @Override
+ public PackageImpl setUse32BitAbi(boolean use32BitAbi) {
+ this.use32BitAbi = use32BitAbi;
+ return this;
+ }
+
+ @Override
+ public PackageImpl setCpuAbiOverride(String cpuAbiOverride) {
+ this.cpuAbiOverride = cpuAbiOverride;
+ return this;
+ }
+
+ @Override
+ public PackageImpl setForceQueryable(boolean forceQueryable) {
+ this.forceQueryable = forceQueryable;
+ return this;
+ }
+
+ // TODO(b/135203078): Remove and move PackageManagerService#renameStaticSharedLibraryPackage
+ // into initial package parsing
+ @Override
+ public PackageImpl setPackageName(String packageName) {
+ this.packageName = packageName.intern();
+
+ if (permissions != null) {
+ for (ParsedPermission permission : permissions) {
+ permission.setPackageName(this.packageName);
+ }
+ }
+
+ if (permissionGroups != null) {
+ for (ParsedPermissionGroup permissionGroup : permissionGroups) {
+ permissionGroup.setPackageName(this.packageName);
+ }
+ }
+
+ if (activities != null) {
+ for (ParsedActivity parsedActivity : activities) {
+ parsedActivity.setPackageName(this.packageName);
+ }
+ }
+
+ if (receivers != null) {
+ for (ParsedActivity receiver : receivers) {
+ receiver.setPackageName(this.packageName);
+ }
+ }
+
+ if (providers != null) {
+ for (ParsedProvider provider : providers) {
+ provider.setPackageName(this.packageName);
+ }
+ }
+
+ if (services != null) {
+ for (ParsedService service : services) {
+ service.setPackageName(this.packageName);
+ }
+ }
+
+ if (instrumentations != null) {
+ for (ParsedInstrumentation instrumentation : instrumentations) {
+ instrumentation.setPackageName(this.packageName);
+ }
+ }
+
+ return this;
+ }
+
+ // Under this is parseBaseApplication
+
+ @Override
+ public PackageImpl setAllowBackup(boolean allowBackup) {
+ this.flags = allowBackup
+ ? this.flags | ApplicationInfo.FLAG_ALLOW_BACKUP
+ : this.flags & ~ApplicationInfo.FLAG_ALLOW_BACKUP;
+ return this;
+ }
+
+ @Override
+ public PackageImpl setKillAfterRestore(boolean killAfterRestore) {
+ this.flags = killAfterRestore
+ ? this.flags | ApplicationInfo.FLAG_KILL_AFTER_RESTORE
+ : this.flags & ~ApplicationInfo.FLAG_KILL_AFTER_RESTORE;
+ return this;
+ }
+
+ @Override
+ public PackageImpl setRestoreAnyVersion(boolean restoreAnyVersion) {
+ this.flags = restoreAnyVersion
+ ? this.flags | ApplicationInfo.FLAG_RESTORE_ANY_VERSION
+ : this.flags & ~ApplicationInfo.FLAG_RESTORE_ANY_VERSION;
+ return this;
+ }
+
+ @Override
+ public PackageImpl setFullBackupOnly(boolean fullBackupOnly) {
+ this.flags = fullBackupOnly
+ ? this.flags | ApplicationInfo.FLAG_FULL_BACKUP_ONLY
+ : this.flags & ~ApplicationInfo.FLAG_FULL_BACKUP_ONLY;
+ return this;
+ }
+
+ @Override
+ public PackageImpl setPersistent(boolean persistent) {
+ this.flags = persistent
+ ? this.flags | ApplicationInfo.FLAG_PERSISTENT
+ : this.flags & ~ApplicationInfo.FLAG_PERSISTENT;
+ return this;
+ }
+
+ @Override
+ public PackageImpl setDebuggable(boolean debuggable) {
+ this.flags = debuggable
+ ? this.flags | ApplicationInfo.FLAG_DEBUGGABLE
+ : this.flags & ~ApplicationInfo.FLAG_DEBUGGABLE;
+ return this;
+ }
+
+ @Override
+ public PackageImpl setProfileableByShell(boolean profileableByShell) {
+ this.privateFlags = profileableByShell
+ ? this.privateFlags | ApplicationInfo.PRIVATE_FLAG_PROFILEABLE_BY_SHELL
+ : this.privateFlags & ~ApplicationInfo.PRIVATE_FLAG_PROFILEABLE_BY_SHELL;
+ return this;
+ }
+
+ @Override
+ public PackageImpl setVmSafeMode(boolean vmSafeMode) {
+ this.flags = vmSafeMode
+ ? this.flags | ApplicationInfo.FLAG_VM_SAFE_MODE
+ : this.flags & ~ApplicationInfo.FLAG_VM_SAFE_MODE;
+ return this;
+ }
+
+ @Override
+ public PackageImpl setHasCode(boolean hasCode) {
+ this.flags = hasCode
+ ? this.flags | ApplicationInfo.FLAG_HAS_CODE
+ : this.flags & ~ApplicationInfo.FLAG_HAS_CODE;
+ return this;
+ }
+
+ @Override
+ public PackageImpl setAllowTaskReparenting(boolean allowTaskReparenting) {
+ this.flags = allowTaskReparenting
+ ? this.flags | ApplicationInfo.FLAG_ALLOW_TASK_REPARENTING
+ : this.flags & ~ApplicationInfo.FLAG_ALLOW_TASK_REPARENTING;
+ return this;
+ }
+
+ @Override
+ public PackageImpl setAllowClearUserData(boolean allowClearUserData) {
+ this.flags = allowClearUserData
+ ? this.flags | ApplicationInfo.FLAG_ALLOW_CLEAR_USER_DATA
+ : this.flags & ~ApplicationInfo.FLAG_ALLOW_CLEAR_USER_DATA;
+ return this;
+ }
+
+ @Override
+ public PackageImpl setLargeHeap(boolean largeHeap) {
+ this.flags = largeHeap
+ ? this.flags | ApplicationInfo.FLAG_LARGE_HEAP
+ : this.flags & ~ApplicationInfo.FLAG_LARGE_HEAP;
+ return this;
+ }
+
+ @Override
+ public PackageImpl setUsesCleartextTraffic(boolean usesCleartextTraffic) {
+ this.flags = usesCleartextTraffic
+ ? this.flags | ApplicationInfo.FLAG_USES_CLEARTEXT_TRAFFIC
+ : this.flags & ~ApplicationInfo.FLAG_USES_CLEARTEXT_TRAFFIC;
+ return this;
+ }
+
+ @Override
+ public PackageImpl setSupportsRtl(boolean supportsRtl) {
+ this.flags = supportsRtl
+ ? this.flags | ApplicationInfo.FLAG_SUPPORTS_RTL
+ : this.flags & ~ApplicationInfo.FLAG_SUPPORTS_RTL;
+ return this;
+ }
+
+ @Override
+ public PackageImpl setTestOnly(boolean testOnly) {
+ this.flags = testOnly
+ ? this.flags | ApplicationInfo.FLAG_TEST_ONLY
+ : this.flags & ~ApplicationInfo.FLAG_TEST_ONLY;
+ return this;
+ }
+
+ @Override
+ public PackageImpl setMultiArch(boolean multiArch) {
+ this.flags = multiArch
+ ? this.flags | ApplicationInfo.FLAG_MULTIARCH
+ : this.flags & ~ApplicationInfo.FLAG_MULTIARCH;
+ return this;
+ }
+
+ @Override
+ public PackageImpl setExtractNativeLibs(boolean extractNativeLibs) {
+ this.flags = extractNativeLibs
+ ? this.flags | ApplicationInfo.FLAG_EXTRACT_NATIVE_LIBS
+ : this.flags & ~ApplicationInfo.FLAG_EXTRACT_NATIVE_LIBS;
+ return this;
+ }
+
+ @Override
+ public PackageImpl setIsGame(boolean isGame) {
+ this.flags = isGame
+ ? this.flags | ApplicationInfo.FLAG_IS_GAME
+ : this.flags & ~ApplicationInfo.FLAG_IS_GAME;
+ return this;
+ }
+
+ @Override
+ public PackageImpl setBackupInForeground(boolean backupInForeground) {
+ this.privateFlags = backupInForeground
+ ? this.privateFlags | ApplicationInfo.PRIVATE_FLAG_BACKUP_IN_FOREGROUND
+ : this.privateFlags & ~ApplicationInfo.PRIVATE_FLAG_BACKUP_IN_FOREGROUND;
+ return this;
+ }
+
+ @Override
+ public PackageImpl setUseEmbeddedDex(boolean useEmbeddedDex) {
+ this.privateFlags = useEmbeddedDex
+ ? this.privateFlags | ApplicationInfo.PRIVATE_FLAG_USE_EMBEDDED_DEX
+ : this.privateFlags & ~ApplicationInfo.PRIVATE_FLAG_USE_EMBEDDED_DEX;
+ return this;
+ }
+
+ @Override
+ public PackageImpl setDefaultToDeviceProtectedStorage(boolean defaultToDeviceProtectedStorage) {
+ this.privateFlags = defaultToDeviceProtectedStorage
+ ? this.privateFlags | ApplicationInfo
+ .PRIVATE_FLAG_DEFAULT_TO_DEVICE_PROTECTED_STORAGE
+ : this.privateFlags & ~ApplicationInfo
+ .PRIVATE_FLAG_DEFAULT_TO_DEVICE_PROTECTED_STORAGE;
+ return this;
+ }
+
+ @Override
+ public PackageImpl setDirectBootAware(boolean directBootAware) {
+ this.privateFlags = directBootAware
+ ? this.privateFlags | ApplicationInfo.PRIVATE_FLAG_DIRECT_BOOT_AWARE
+ : this.privateFlags & ~ApplicationInfo.PRIVATE_FLAG_DIRECT_BOOT_AWARE;
+ return this;
+ }
+
+ @Override
+ public PackageImpl setPartiallyDirectBootAware(boolean partiallyDirectBootAware) {
+ this.privateFlags = partiallyDirectBootAware
+ ? this.privateFlags | ApplicationInfo.PRIVATE_FLAG_PARTIALLY_DIRECT_BOOT_AWARE
+ : this.privateFlags & ~ApplicationInfo.PRIVATE_FLAG_PARTIALLY_DIRECT_BOOT_AWARE;
+ return this;
+ }
+
+ @Override
+ public PackageImpl setActivitiesResizeModeResizeableViaSdkVersion(
+ boolean resizeableViaSdkVersion
+ ) {
+ this.privateFlags = resizeableViaSdkVersion
+ ? this.privateFlags | ApplicationInfo
+ .PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION
+ : this.privateFlags & ~ApplicationInfo
+ .PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_RESIZEABLE_VIA_SDK_VERSION;
+ return this;
+ }
+
+ @Override
+ public PackageImpl setActivitiesResizeModeResizeable(boolean resizeable) {
+ this.privateFlags = resizeable
+ ? this.privateFlags | ApplicationInfo
+ .PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_RESIZEABLE
+ : this.privateFlags & ~ApplicationInfo
+ .PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_RESIZEABLE;
+
+ this.privateFlags = !resizeable
+ ? this.privateFlags | ApplicationInfo
+ .PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_UNRESIZEABLE
+ : this.privateFlags & ~ApplicationInfo
+ .PRIVATE_FLAG_ACTIVITIES_RESIZE_MODE_UNRESIZEABLE;
+ return this;
+ }
+
+ @Override
+ public PackageImpl setAllowClearUserDataOnFailedRestore(
+ boolean allowClearUserDataOnFailedRestore
+ ) {
+ this.privateFlags = allowClearUserDataOnFailedRestore
+ ? this.privateFlags | ApplicationInfo
+ .PRIVATE_FLAG_ALLOW_CLEAR_USER_DATA_ON_FAILED_RESTORE
+ : this.privateFlags & ~ApplicationInfo
+ .PRIVATE_FLAG_ALLOW_CLEAR_USER_DATA_ON_FAILED_RESTORE;
+ return this;
+ }
+
+ @Override
+ public PackageImpl setAllowAudioPlaybackCapture(boolean allowAudioPlaybackCapture) {
+ this.privateFlags = allowAudioPlaybackCapture
+ ? this.privateFlags | ApplicationInfo.PRIVATE_FLAG_ALLOW_AUDIO_PLAYBACK_CAPTURE
+ : this.privateFlags & ~ApplicationInfo.PRIVATE_FLAG_ALLOW_AUDIO_PLAYBACK_CAPTURE;
+ return this;
+ }
+
+ @Override
+ public PackageImpl setRequestLegacyExternalStorage(boolean requestLegacyExternalStorage) {
+ this.privateFlags = requestLegacyExternalStorage
+ ? this.privateFlags | ApplicationInfo.PRIVATE_FLAG_REQUEST_LEGACY_EXTERNAL_STORAGE
+ : this.privateFlags & ~ApplicationInfo.PRIVATE_FLAG_REQUEST_LEGACY_EXTERNAL_STORAGE;
+ return this;
+ }
+
+ @Override
+ public PackageImpl setUsesNonSdkApi(boolean usesNonSdkApi) {
+ this.privateFlags = usesNonSdkApi
+ ? this.privateFlags | ApplicationInfo.PRIVATE_FLAG_USES_NON_SDK_API
+ : this.privateFlags & ~ApplicationInfo.PRIVATE_FLAG_USES_NON_SDK_API;
+ return this;
+ }
+
+ @Override
+ public PackageImpl setHasFragileUserData(boolean hasFragileUserData) {
+ this.privateFlags = hasFragileUserData
+ ? this.privateFlags | ApplicationInfo.PRIVATE_FLAG_HAS_FRAGILE_USER_DATA
+ : this.privateFlags & ~ApplicationInfo.PRIVATE_FLAG_HAS_FRAGILE_USER_DATA;
+ return this;
+ }
+
+ @Override
+ public PackageImpl setCantSaveState(boolean cantSaveState) {
+ this.privateFlags = cantSaveState
+ ? this.privateFlags | ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE
+ : this.privateFlags & ~ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE;
+ return this;
+ }
+
+ @Override
+ public boolean cantSaveState() {
+ return (privateFlags & ApplicationInfo.PRIVATE_FLAG_CANT_SAVE_STATE) != 0;
+ }
+
+ @Override
+ public boolean isLibrary() {
+ return staticSharedLibName != null || !ArrayUtils.isEmpty(libraryNames);
+ }
+
+ // TODO(b/135203078): This does nothing until the final stage without applyPolicy being
+ // part of PackageParser
+ @Override
+ public boolean isSystemApp() {
+ return (flags & ApplicationInfo.FLAG_SYSTEM) != 0;
+ }
+
+ // TODO(b/135203078): This does nothing until the final stage without applyPolicy being
+ // part of PackageParser
+ @Override
+ public boolean isSystemExt() {
+ return (privateFlags & ApplicationInfo.PRIVATE_FLAG_SYSTEM_EXT) != 0;
+ }
+
+ // TODO(b/135203078): This does nothing until the final stage without applyPolicy being
+ // part of PackageParser
+ @Override
+ public boolean isUpdatedSystemApp() {
+ return (flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0;
+ }
+
+ @Override
+ public PackageImpl setStaticSharedLibrary(boolean staticSharedLibrary) {
+ this.privateFlags = staticSharedLibrary
+ ? this.privateFlags | ApplicationInfo.PRIVATE_FLAG_STATIC_SHARED_LIBRARY
+ : this.privateFlags & ~ApplicationInfo.PRIVATE_FLAG_STATIC_SHARED_LIBRARY;
+ return this;
+ }
+
+ @Override
+ public boolean isStaticSharedLibrary() {
+ return (privateFlags & ApplicationInfo.PRIVATE_FLAG_STATIC_SHARED_LIBRARY) != 0;
+ }
+
+ @Override
+ public PackageImpl setVisibleToInstantApps(boolean visibleToInstantApps) {
+ this.visibleToInstantApps = visibleToInstantApps;
+ return this;
+ }
+
+ @Override
+ public PackageImpl setIconRes(int iconRes) {
+ this.iconRes = iconRes;
+ return this;
+ }
+
+ @Override
+ public PackageImpl setRoundIconRes(int roundIconRes) {
+ this.roundIconRes = roundIconRes;
+ return this;
+ }
+
+ @Override
+ public PackageImpl setClassName(String className) {
+ this.className = className;
+ return this;
+ }
+
+ @Override
+ public PackageImpl setManageSpaceActivityName(String manageSpaceActivityName) {
+ this.manageSpaceActivityName = manageSpaceActivityName;
+ return this;
+ }
+
+ @Override
+ public PackageImpl setBackupAgentName(String backupAgentName) {
+ this.backupAgentName = backupAgentName;
+ return this;
+ }
+
+ @Override
+ public PackageImpl setFullBackupContent(int fullBackupContent) {
+ this.fullBackupContent = fullBackupContent;
+ return this;
+ }
+
+ @Override
+ public PackageImpl setTheme(int theme) {
+ this.theme = theme;
+ return this;
+ }
+
+ @Override
+ public PackageImpl setDescriptionRes(int descriptionRes) {
+ this.descriptionRes = descriptionRes;
+ return this;
+ }
+
+ @Override
+ public PackageImpl setNetworkSecurityConfigRes(int networkSecurityConfigRes) {
+ this.networkSecurityConfigRes = networkSecurityConfigRes;
+ return this;
+ }
+
+ @Override
+ public PackageImpl setCategory(int category) {
+ this.category = category;
+ return this;
+ }
+
+ @Override
+ public PackageImpl setPermission(String permission) {
+ this.permission = permission;
+ return this;
+ }
+
+ @Override
+ public PackageImpl setTaskAffinity(String taskAffinity) {
+ this.taskAffinity = taskAffinity;
+ return this;
+ }
+
+ @Override
+ public PackageImpl setAppComponentFactory(String appComponentFactory) {
+ this.appComponentFactory = appComponentFactory;
+ return this;
+ }
+
+ @Override
+ public PackageImpl setProcessName(String processName) {
+ if (processName == null) {
+ this.processName = packageName;
+ } else {
+ this.processName = processName;
+ }
+ return this;
+ }
+
+ @Override
+ public PackageImpl setEnabled(boolean enabled) {
+ this.enabled = enabled;
+ return this;
+ }
+
+ @Override
+ public PackageImpl setUiOptions(int uiOptions) {
+ this.uiOptions = uiOptions;
+ return this;
+ }
+
+ @Override
+ public PackageImpl setClassLoaderName(String classLoaderName) {
+ this.classLoaderName = classLoaderName;
+ return this;
+ }
+
+ @Override
+ public PackageImpl setZygotePreloadName(String zygotePreloadName) {
+ this.zygotePreloadName = zygotePreloadName;
+ return this;
+ }
+
+ // parsePackageItemInfo
+
+ @Override
+ public String getName() {
+ return name;
+ }
+
+ @Override
+ public PackageImpl setName(String name) {
+ this.name = name;
+ return this;
+ }
+
+ @Override
+ public PackageImpl setIcon(int icon) {
+ this.icon = icon;
+ return this;
+ }
+
+ @Override
+ public PackageImpl setNonLocalizedLabel(CharSequence nonLocalizedLabel) {
+ this.nonLocalizedLabel = nonLocalizedLabel;
+ return this;
+ }
+
+ @Override
+ public PackageImpl setLogo(int logo) {
+ this.logo = logo;
+ return this;
+ }
+
+ @Override
+ public PackageImpl setBanner(int banner) {
+ this.banner = banner;
+ return this;
+ }
+
+ @Override
+ public PackageImpl setLabelRes(int labelRes) {
+ this.labelRes = labelRes;
+ return this;
+ }
+
+ @Override
+ public PackageImpl asSplit(
+ String[] splitNames,
+ String[] splitCodePaths,
+ int[] splitRevisionCodes,
+ SparseArray<int[]> splitDependencies
+ ) {
+ this.splitNames = splitNames;
+
+ if (this.splitNames != null) {
+ for (int index = 0; index < this.splitNames.length; index++) {
+ splitNames[index] = TextUtils.safeIntern(splitNames[index]);
+ }
+ }
+
+ this.splitCodePaths = splitCodePaths;
+ this.splitRevisionCodes = splitRevisionCodes;
+ this.splitDependencies = splitDependencies;
+
+ int count = splitNames.length;
+ this.splitFlags = new int[count];
+ this.splitClassLoaderNames = new String[count];
+ return this;
+ }
+
+ @Override
+ public String[] getSplitNames() {
+ return splitNames;
+ }
+
+ @Override
+ public String[] getSplitCodePaths() {
+ return splitCodePaths;
+ }
+
+ @Override
+ public PackageImpl setSplitHasCode(int splitIndex, boolean splitHasCode) {
+ this.splitFlags[splitIndex] = splitHasCode
+ ? this.splitFlags[splitIndex] | ApplicationInfo.FLAG_HAS_CODE
+ : this.splitFlags[splitIndex] & ~ApplicationInfo.FLAG_HAS_CODE;
+ return this;
+ }
+
+ @Override
+ public PackageImpl setSplitClassLoaderName(int splitIndex, String classLoaderName) {
+ this.splitClassLoaderNames[splitIndex] = classLoaderName;
+ return this;
+ }
+
+ @Override
+ public List<String> makeListAllCodePaths() {
+ ArrayList<String> paths = new ArrayList<>();
+ paths.add(baseCodePath);
+
+ if (!ArrayUtils.isEmpty(splitCodePaths)) {
+ Collections.addAll(paths, splitCodePaths);
+ }
+ return paths;
+ }
+
+ @Override
+ public PackageImpl setBaseCodePath(String baseCodePath) {
+ this.baseCodePath = baseCodePath;
+ return this;
+ }
+
+ @Override
+ public PackageImpl setSplitCodePaths(String[] splitCodePaths) {
+ this.splitCodePaths = splitCodePaths;
+ return this;
+ }
+
+ @Override
+ public String toString() {
+ return "Package{"
+ + Integer.toHexString(System.identityHashCode(this))
+ + " " + packageName + "}";
+ }
+
+ @Override
+ public PackageImpl setPrimaryCpuAbi(String primaryCpuAbi) {
+ this.primaryCpuAbi = primaryCpuAbi;
+ return this;
+ }
+
+ @Override
+ public PackageImpl setSecondaryCpuAbi(String secondaryCpuAbi) {
+ this.secondaryCpuAbi = secondaryCpuAbi;
+ return this;
+ }
+
+ @Override
+ public PackageImpl setNativeLibraryRootDir(String nativeLibraryRootDir) {
+ this.nativeLibraryRootDir = nativeLibraryRootDir;
+ return this;
+ }
+
+ @Override
+ public PackageImpl setNativeLibraryRootRequiresIsa(boolean nativeLibraryRootRequiresIsa) {
+ this.nativeLibraryRootRequiresIsa = nativeLibraryRootRequiresIsa;
+ return this;
+ }
+
+ @Override
+ public PackageImpl setNativeLibraryDir(String nativeLibraryDir) {
+ this.nativeLibraryDir = nativeLibraryDir;
+ return this;
+ }
+
+ @Override
+ public PackageImpl setSecondaryNativeLibraryDir(String secondaryNativeLibraryDir) {
+ this.secondaryNativeLibraryDir = secondaryNativeLibraryDir;
+ return this;
+ }
+
+ @Deprecated
+ @Override
+ public PackageImpl setApplicationInfoCodePath(String applicationInfoCodePath) {
+ this.applicationInfoCodePath = applicationInfoCodePath;
+ return this;
+ }
+
+ @Deprecated
+ @Override
+ public PackageImpl setApplicationInfoResourcePath(String applicationInfoResourcePath) {
+ this.applicationInfoResourcePath = applicationInfoResourcePath;
+ return this;
+ }
+
+ @Deprecated
+ @Override
+ public PackageImpl setApplicationInfoBaseResourcePath(
+ String applicationInfoBaseResourcePath) {
+ this.applicationInfoBaseResourcePath = applicationInfoBaseResourcePath;
+ return this;
+ }
+
+ @Deprecated
+ @Override
+ public PackageImpl setApplicationInfoSplitResourcePaths(
+ String[] applicationInfoSplitResourcePaths) {
+ this.applicationInfoSplitResourcePaths = applicationInfoSplitResourcePaths;
+ return this;
+ }
+
+ @Override
+ public boolean isDirectBootAware() {
+ return (privateFlags & ApplicationInfo.PRIVATE_FLAG_DIRECT_BOOT_AWARE) != 0;
+ }
+
+ @Override
+ public PackageImpl setAllComponentsDirectBootAware(boolean allComponentsDirectBootAware) {
+ if (activities != null) {
+ for (ParsedActivity parsedActivity : activities) {
+ parsedActivity.directBootAware = allComponentsDirectBootAware;
+ }
+ }
+
+ if (receivers != null) {
+ for (ParsedActivity parsedReceiver : receivers) {
+ parsedReceiver.directBootAware = allComponentsDirectBootAware;
+ }
+ }
+
+ if (providers != null) {
+ for (ParsedProvider parsedProvider : providers) {
+ parsedProvider.directBootAware = allComponentsDirectBootAware;
+ }
+ }
+
+ if (services != null) {
+ for (ParsedService parsedService : services) {
+ parsedService.directBootAware = allComponentsDirectBootAware;
+ }
+ }
+
+ return this;
+ }
+
+ @Override
+ public PackageImpl setSystem(boolean system) {
+ this.flags = system
+ ? this.flags | ApplicationInfo.FLAG_SYSTEM
+ : this.flags & ~ApplicationInfo.FLAG_SYSTEM;
+ return this;
+ }
+
+ @Override
+ public PackageImpl setSystemExt(boolean systemExt) {
+ this.privateFlags = systemExt
+ ? this.privateFlags | ApplicationInfo.PRIVATE_FLAG_SYSTEM_EXT
+ : this.privateFlags & ~ApplicationInfo.PRIVATE_FLAG_SYSTEM_EXT;
+ return this;
+ }
+
+ @Override
+ public PackageImpl setIsStub(boolean isStub) {
+ this.isStub = isStub;
+ return this;
+ }
+
+ @Override
+ public PackageImpl setCoreApp(boolean coreApp) {
+ this.coreApp = coreApp;
+ return this;
+ }
+
+ @Override
+ public ParsedPackage capPermissionPriorities() {
+ if (permissionGroups != null && !permissionGroups.isEmpty()) {
+ for (int i = permissionGroups.size() - 1; i >= 0; --i) {
+ // TODO(b/135203078): Builder/immutability
+ permissionGroups.get(i).priority = 0;
+ }
+ }
+ return this;
+ }
+
+ @Override
+ public ParsedPackage clearProtectedBroadcasts() {
+ if (protectedBroadcasts != null) {
+ protectedBroadcasts.clear();
+ }
+ return this;
+ }
+
+ @Override
+ public ParsedPackage markNotActivitiesAsNotExportedIfSingleUser() {
+ // ignore export request for single user receivers
+ if (receivers != null) {
+ for (ParsedActivity receiver : receivers) {
+ if ((receiver.flags & ActivityInfo.FLAG_SINGLE_USER) != 0) {
+ receiver.exported = false;
+ }
+ }
+ }
+ // ignore export request for single user services
+ if (services != null) {
+ for (ParsedService service : services) {
+ if ((service.flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
+ service.exported = false;
+ }
+ }
+ }
+ // ignore export request for single user providers
+ if (providers != null) {
+ for (ParsedProvider provider : providers) {
+ if ((provider.flags & ProviderInfo.FLAG_SINGLE_USER) != 0) {
+ provider.exported = false;
+ }
+ }
+ }
+
+ return this;
+ }
+
+ @Override
+ public ParsedPackage setPrivileged(boolean privileged) {
+ this.privateFlags = privileged
+ ? this.privateFlags | ApplicationInfo.PRIVATE_FLAG_PRIVILEGED
+ : this.privateFlags & ~ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
+ return this;
+ }
+
+ @Override
+ public ParsedPackage setOem(boolean oem) {
+ this.privateFlags = oem
+ ? this.privateFlags | ApplicationInfo.PRIVATE_FLAG_OEM
+ : this.privateFlags & ~ApplicationInfo.PRIVATE_FLAG_OEM;
+ return this;
+ }
+
+ @Override
+ public ParsedPackage setVendor(boolean vendor) {
+ this.privateFlags = vendor
+ ? this.privateFlags | ApplicationInfo.PRIVATE_FLAG_VENDOR
+ : this.privateFlags & ~ApplicationInfo.PRIVATE_FLAG_VENDOR;
+ return this;
+ }
+
+ @Override
+ public ParsedPackage setProduct(boolean product) {
+ this.privateFlags = product
+ ? this.privateFlags | ApplicationInfo.PRIVATE_FLAG_PRODUCT
+ : this.privateFlags & ~ApplicationInfo.PRIVATE_FLAG_PRODUCT;
+ return this;
+ }
+
+ @Override
+ public ParsedPackage setOdm(boolean odm) {
+ this.privateFlags = odm
+ ? this.privateFlags | ApplicationInfo.PRIVATE_FLAG_ODM
+ : this.privateFlags & ~ApplicationInfo.PRIVATE_FLAG_ODM;
+ return this;
+ }
+
+ @Override
+ public ParsedPackage setSignedWithPlatformKey(boolean signedWithPlatformKey) {
+ this.privateFlags = signedWithPlatformKey
+ ? this.privateFlags | ApplicationInfo.PRIVATE_FLAG_SIGNED_WITH_PLATFORM_KEY
+ : this.privateFlags & ~ApplicationInfo.PRIVATE_FLAG_SIGNED_WITH_PLATFORM_KEY;
+ return this;
+ }
+
+ @Override
+ public ParsedPackage clearOriginalPackages() {
+ if (originalPackages != null) {
+ originalPackages.clear();
+ }
+ return this;
+ }
+
+ @Override
+ public ParsedPackage clearAdoptPermissions() {
+ if (adoptPermissions != null) {
+ adoptPermissions.clear();
+ }
+ return this;
+ }
+
+ @Override
+ public PackageImpl addUsesLibrary(int index, String libraryName) {
+ this.usesLibraries = ArrayUtils.add(usesLibraries, index, libraryName);
+ return this;
+ }
+
+ @Override
+ public ParsedPackage removeUsesLibrary(String libraryName) {
+ this.usesLibraries = ArrayUtils.remove(this.usesLibraries, libraryName);
+ return this;
+ }
+
+ @Override
+ public PackageImpl addUsesOptionalLibrary(int index, String libraryName) {
+ this.usesOptionalLibraries = ArrayUtils.add(usesOptionalLibraries, index, libraryName);
+ return this;
+ }
+
+ @Nullable
+ @Override
+ public List<String> getUsesOptionalLibraries() {
+ return usesOptionalLibraries;
+ }
+
+ @Override
+ public int getVersionCode() {
+ return versionCode;
+ }
+
+ @Nullable
+ @Override
+ public long[] getUsesStaticLibrariesVersions() {
+ return usesStaticLibrariesVersions;
+ }
+
+ @Override
+ public PackageImpl setPackageSettingCallback(PackageSettingCallback packageSettingCallback) {
+ packageSettingCallback.setAndroidPackage(this);
+ return this;
+ }
+
+ @Override
+ public PackageImpl setUpdatedSystemApp(boolean updatedSystemApp) {
+ this.flags = updatedSystemApp
+ ? this.flags | ApplicationInfo.FLAG_UPDATED_SYSTEM_APP
+ : this.flags & ~ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
+ return this;
+ }
+
+ @Override
+ public boolean isPrivileged() {
+ return (privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0;
+ }
+
+ @Override
+ public PackageImpl setSeInfo(String seInfo) {
+ this.seInfo = seInfo;
+ return this;
+ }
+
+ @Override
+ public PackageImpl setSeInfoUser(String seInfoUser) {
+ this.seInfoUser = seInfoUser;
+ return this;
+ }
+
+ @Override
+ public PackageImpl initForUser(int userId) {
+ // TODO(b/135203078): Move this user state to some other data structure
+ this.uid = UserHandle.getUid(userId, UserHandle.getAppId(this.uid));
+
+ if ("android".equals(packageName)) {
+ dataDir = Environment.getDataSystemDirectory().getAbsolutePath();
+ return this;
+ }
+
+ deviceProtectedDataDir = Environment
+ .getDataUserDePackageDirectory(applicationVolumeUuid, userId, packageName)
+ .getAbsolutePath();
+ credentialProtectedDataDir = Environment
+ .getDataUserCePackageDirectory(applicationVolumeUuid, userId, packageName)
+ .getAbsolutePath();
+
+ if ((privateFlags & ApplicationInfo.PRIVATE_FLAG_DEFAULT_TO_DEVICE_PROTECTED_STORAGE) != 0
+ && PackageManager.APPLY_DEFAULT_TO_DEVICE_PROTECTED_STORAGE) {
+ dataDir = deviceProtectedDataDir;
+ } else {
+ dataDir = credentialProtectedDataDir;
+ }
+ return this;
+ }
+
+ @Override
+ public ParsedPackage setFactoryTest(boolean factoryTest) {
+ this.flags = factoryTest
+ ? this.flags | ApplicationInfo.FLAG_FACTORY_TEST
+ : this.flags & ~ApplicationInfo.FLAG_FACTORY_TEST;
+ return this;
+ }
+
+ @Override
+ public String getManifestPackageName() {
+ return manifestPackageName;
+ }
+
+ @Override
+ public String getRealPackage() {
+ return realPackage;
+ }
+
+ @Override
+ public String getOverlayTarget() {
+ return overlayTarget;
+ }
+
+ @Override
+ public String getOverlayTargetName() {
+ return overlayTargetName;
+ }
+
+ @Override
+ public boolean isOverlayIsStatic() {
+ return overlayIsStatic;
+ }
+
+ @Override
+ public int[] getSplitFlags() {
+ return splitFlags;
+ }
+
+ @Deprecated
+ @Override
+ public String getApplicationInfoVolumeUuid() {
+ return applicationVolumeUuid;
+ }
+
+ @Nullable
+ @Override
+ public List<String> getProtectedBroadcasts() {
+ return protectedBroadcasts;
+ }
+
+ @Nullable
+ @Override
+ public Set<String> getUpgradeKeySets() {
+ return upgradeKeySets;
+ }
+
+ @Nullable
+ @Override
+ public String[][] getUsesStaticLibrariesCertDigests() {
+ return usesStaticLibrariesCertDigests;
+ }
+
+ @Override
+ public int getOverlayPriority() {
+ return overlayPriority;
+ }
+
+ @Deprecated
+ @Override
+ public String getAppInfoPackageName() {
+ return packageName;
+ }
+
+ @Override
+ public UUID getStorageUuid() {
+ return StorageManager.convert(applicationVolumeUuid);
+ }
+
+ @Override
+ public int getUid() {
+ return uid;
+ }
+
+ @Override
+ public boolean isStub() {
+ return isStub;
+ }
+
+ @Deprecated
+ @Override
+ public String getAppInfoCodePath() {
+ return applicationInfoCodePath;
+ }
+
+ @Override
+ public boolean isSystem() {
+ return (flags & ApplicationInfo.FLAG_SYSTEM) != 0;
+ }
+
+ @Override
+ public boolean isMatch(int flags) {
+ if ((flags & PackageManager.MATCH_SYSTEM_ONLY) != 0) {
+ return isSystem();
+ }
+ return true;
+ }
+
+ @Override
+ public boolean isVisibleToInstantApps() {
+ return visibleToInstantApps;
+ }
+
+ @Override
+ public PackageImpl setLastPackageUsageTimeInMills(int reason, long time) {
+ lastPackageUsageTimeInMills[reason] = time;
+ return this;
+ }
+
+ @Override
+ public List<SharedLibraryInfo> getUsesLibraryInfos() {
+ return usesLibraryInfos;
+ }
+
+ @NonNull
+ @Override
+ public List<String> getAllCodePaths() {
+ return makeListAllCodePaths();
+ }
+
+ @Nullable
+ @Override
+ public String[] getUsesLibraryFiles() {
+ return usesLibraryFiles;
+ }
+
+ @Override
+ public PackageImpl setUsesLibraryInfos(
+ @Nullable List<SharedLibraryInfo> usesLibraryInfos) {
+ this.usesLibraryInfos = usesLibraryInfos;
+ return this;
+ }
+
+ @Override
+ public PackageImpl setUsesLibraryFiles(@Nullable String[] usesLibraryFiles) {
+ this.usesLibraryFiles = usesLibraryFiles;
+ return this;
+ }
+
+ @Override
+ public PackageImpl setUid(int uid) {
+ this.uid = uid;
+ return this;
+ }
+
+ @Override
+ public List<String> getAdoptPermissions() {
+ return adoptPermissions;
+ }
+
+ @Override
+ public ApplicationInfo toAppInfo() {
+ updateFlags();
+
+ ApplicationInfo applicationInfo = new ApplicationInfo();
+ applicationInfo.packageName = packageName;
+ applicationInfo.flags = flags;
+ applicationInfo.privateFlags = privateFlags;
+ applicationInfo.sharedLibraryFiles = usesLibraryFiles;
+ applicationInfo.sharedLibraryInfos = usesLibraryInfos;
+
+ applicationInfo.appComponentFactory = appComponentFactory;
+ applicationInfo.backupAgentName = backupAgentName;
+ applicationInfo.banner = banner;
+ applicationInfo.category = category;
+ applicationInfo.classLoaderName = classLoaderName;
+ applicationInfo.className = className;
+ applicationInfo.compatibleWidthLimitDp = compatibleWidthLimitDp;
+ applicationInfo.credentialProtectedDataDir = credentialProtectedDataDir;
+ applicationInfo.dataDir = dataDir;
+ applicationInfo.descriptionRes = descriptionRes;
+ applicationInfo.deviceProtectedDataDir = deviceProtectedDataDir;
+ applicationInfo.enabled = enabled;
+ applicationInfo.fullBackupContent = fullBackupContent;
+ applicationInfo.icon = icon;
+ applicationInfo.iconRes = iconRes;
+ applicationInfo.installLocation = installLocation;
+ applicationInfo.labelRes = labelRes;
+ applicationInfo.largestWidthLimitDp = largestWidthLimitDp;
+ applicationInfo.logo = logo;
+ applicationInfo.manageSpaceActivityName = manageSpaceActivityName;
+ applicationInfo.maxAspectRatio = maxAspectRatio;
+ applicationInfo.minAspectRatio = minAspectRatio;
+ applicationInfo.minSdkVersion = minSdkVersion;
+ applicationInfo.name = name;
+ applicationInfo.nativeLibraryDir = nativeLibraryDir;
+ applicationInfo.nativeLibraryRootDir = nativeLibraryRootDir;
+ applicationInfo.nativeLibraryRootRequiresIsa = nativeLibraryRootRequiresIsa;
+ applicationInfo.networkSecurityConfigRes = networkSecurityConfigRes;
+ applicationInfo.nonLocalizedLabel = nonLocalizedLabel;
+ applicationInfo.permission = permission;
+ applicationInfo.primaryCpuAbi = primaryCpuAbi;
+ applicationInfo.processName = processName;
+ applicationInfo.requiresSmallestWidthDp = requiresSmallestWidthDp;
+ applicationInfo.roundIconRes = roundIconRes;
+ applicationInfo.secondaryCpuAbi = secondaryCpuAbi;
+ applicationInfo.secondaryNativeLibraryDir = secondaryNativeLibraryDir;
+ applicationInfo.seInfo = seInfo;
+ applicationInfo.seInfoUser = seInfoUser;
+ applicationInfo.splitClassLoaderNames = splitClassLoaderNames;
+ applicationInfo.splitDependencies = splitDependencies;
+ applicationInfo.splitNames = splitNames;
+ applicationInfo.storageUuid = StorageManager.convert(applicationVolumeUuid);
+ applicationInfo.targetSandboxVersion = targetSandboxVersion;
+ applicationInfo.targetSdkVersion = targetSdkVersion;
+ applicationInfo.taskAffinity = taskAffinity;
+ applicationInfo.theme = theme;
+ applicationInfo.uid = uid;
+ applicationInfo.uiOptions = uiOptions;
+ applicationInfo.volumeUuid = applicationVolumeUuid;
+ applicationInfo.zygotePreloadName = zygotePreloadName;
+
+ applicationInfo.setBaseCodePath(baseCodePath);
+ applicationInfo.setBaseResourcePath(applicationInfoBaseResourcePath);
+ applicationInfo.setCodePath(applicationInfoCodePath);
+ applicationInfo.setResourcePath(applicationInfoResourcePath);
+ applicationInfo.setSplitCodePaths(splitCodePaths);
+ applicationInfo.setSplitResourcePaths(applicationInfoSplitResourcePaths);
+
+ return applicationInfo;
+ }
+
+ @Override
+ public PackageImpl setVersionCode(int versionCode) {
+ this.versionCode = versionCode;
+ return this;
+ }
+
+ @Override
+ public PackageImpl setHiddenUntilInstalled(boolean hidden) {
+ this.hiddenUntilInstalled = hidden;
+ return this;
+ }
+
+ @Override
+ public String getSeInfo() {
+ return seInfo;
+ }
+
+ @Deprecated
+ @Override
+ public String getAppInfoResourcePath() {
+ return applicationInfoResourcePath;
+ }
+
+ @Override
+ public boolean isForwardLocked() {
+ // TODO(b/135203078): Unused? Move to debug flag?
+ return false;
+ }
+
+ @Override
+ public byte[] getRestrictUpdateHash() {
+ return restrictUpdateHash;
+ }
+
+ @Override
+ public boolean hasComponentClassName(String className) {
+ if (activities != null) {
+ for (ParsedActivity parsedActivity : activities) {
+ if (Objects.equals(className, parsedActivity.className)) {
+ return true;
+ }
+ }
+ }
+
+ if (receivers != null) {
+ for (ParsedActivity receiver : receivers) {
+ if (Objects.equals(className, receiver.className)) {
+ return true;
+ }
+ }
+ }
+
+ if (providers != null) {
+ for (ParsedProvider provider : providers) {
+ if (Objects.equals(className, provider.className)) {
+ return true;
+ }
+ }
+ }
+
+ if (services != null) {
+ for (ParsedService service : services) {
+ if (Objects.equals(className, service.className)) {
+ return true;
+ }
+ }
+ }
+
+ if (instrumentations != null) {
+ for (ParsedInstrumentation instrumentation : instrumentations) {
+ if (Objects.equals(className, instrumentation.className)) {
+ return true;
+ }
+ }
+ }
+
+ return false;
+ }
+
+ @Override
+ public boolean isDefaultToDeviceProtectedStorage() {
+ return (privateFlags & ApplicationInfo.PRIVATE_FLAG_DEFAULT_TO_DEVICE_PROTECTED_STORAGE)
+ != 0;
+ }
+
+ @Override
+ public boolean isInternal() {
+ return (flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) == 0;
+ }
+
+ @Override
+ public int getBaseRevisionCode() {
+ return baseRevisionCode;
+ }
+
+ @Override
+ public int[] getSplitRevisionCodes() {
+ return splitRevisionCodes;
+ }
+
+ @Override
+ public boolean canHaveOatDir() {
+ // The following app types CANNOT have oat directory
+ // - non-updated system apps
+ return !isSystem() || isUpdatedSystemApp();
+ }
+
+ @Override
+ public long getLatestPackageUseTimeInMills() {
+ long latestUse = 0L;
+ for (long use : lastPackageUsageTimeInMills) {
+ latestUse = Math.max(latestUse, use);
+ }
+ return latestUse;
+ }
+
+ @Override
+ public long getLatestForegroundPackageUseTimeInMills() {
+ int[] foregroundReasons = {
+ PackageManager.NOTIFY_PACKAGE_USE_ACTIVITY,
+ PackageManager.NOTIFY_PACKAGE_USE_FOREGROUND_SERVICE
+ };
+
+ long latestUse = 0L;
+ for (int reason : foregroundReasons) {
+ latestUse = Math.max(latestUse, lastPackageUsageTimeInMills[reason]);
+ }
+ return latestUse;
+ }
+
+ @Override
+ public boolean isCoreApp() {
+ return coreApp;
+ }
+
+ @Override
+ public String getVersionName() {
+ return versionName;
+ }
+
+ @Override
+ public PackageImpl setVersionCodeMajor(int versionCodeMajor) {
+ this.versionCodeMajor = versionCodeMajor;
+ return this;
+ }
+
+ @Override
+ public long[] getLastPackageUsageTimeInMills() {
+ return lastPackageUsageTimeInMills;
+ }
+
+ @Override
+ public String getDataDir() {
+ return dataDir;
+ }
+
+ @Override
+ public boolean isExternal() {
+ return (flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
+ }
+
+ @Override
+ public List<String> getImplicitPermissions() {
+ return implicitPermissions == null ? Collections.emptyList() : implicitPermissions;
+ }
+
+ /**
+ * TODO(b/135203078): Remove, ensure b/140256621 is fixed or irrelevant
+ * TODO(b/140256621): Remove after fixing instant app check
+ * @deprecated This method always returns false because there's no paired set method
+ */
+ @Deprecated
+ @Override
+ public boolean isInstantApp() {
+ return (privateFlags & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0;
+ }
+
+ @Override
+ public boolean hasRequestedLegacyExternalStorage() {
+ return (privateFlags & ApplicationInfo.PRIVATE_FLAG_REQUEST_LEGACY_EXTERNAL_STORAGE) != 0;
+ }
+
+ @Override
+ public boolean isVendor() {
+ return (privateFlags & ApplicationInfo.PRIVATE_FLAG_VENDOR) != 0;
+ }
+
+ @Override
+ public boolean isProduct() {
+ return (privateFlags & ApplicationInfo.PRIVATE_FLAG_PRODUCT) != 0;
+ }
+
+ @Override
+ public boolean isOem() {
+ return (privateFlags & ApplicationInfo.PRIVATE_FLAG_OEM) != 0;
+ }
+
+ @Override
+ public boolean isEncryptionAware() {
+ boolean isPartiallyDirectBootAware =
+ (privateFlags & ApplicationInfo.PRIVATE_FLAG_PARTIALLY_DIRECT_BOOT_AWARE) != 0;
+ return isDirectBootAware() || isPartiallyDirectBootAware;
+ }
+
+ @Override
+ public boolean isEmbeddedDexUsed() {
+ return (privateFlags & ApplicationInfo.PRIVATE_FLAG_USE_EMBEDDED_DEX) != 0;
+ }
+
+ @Deprecated
+ @Override
+ public String getAppInfoProcessName() {
+ return processName;
+ }
+
+ @Override
+ public List<String> getAllCodePathsExcludingResourceOnly() {
+ ArrayList<String> paths = new ArrayList<>();
+ if ((flags & ApplicationInfo.FLAG_HAS_CODE) != 0) {
+ paths.add(baseCodePath);
+ }
+ if (!ArrayUtils.isEmpty(splitCodePaths)) {
+ for (int i = 0; i < splitCodePaths.length; i++) {
+ if ((splitFlags[i] & ApplicationInfo.FLAG_HAS_CODE) != 0) {
+ paths.add(splitCodePaths[i]);
+ }
+ }
+ }
+ return paths;
+ }
+
+ @Deprecated
+ @Override
+ public String getAppInfoName() {
+ return name;
+ }
+
+ private boolean isSignedWithPlatformKey() {
+ return (privateFlags & ApplicationInfo.PRIVATE_FLAG_SIGNED_WITH_PLATFORM_KEY) != 0;
+ }
+
+ private boolean usesNonSdkApi() {
+ return (privateFlags & ApplicationInfo.PRIVATE_FLAG_USES_NON_SDK_API) != 0;
+ }
+
+ private boolean isPackageWhitelistedForHiddenApis() {
+ return SystemConfig.getInstance().getHiddenApiWhitelistedApps().contains(packageName);
+ }
+
+ private boolean isAllowedToUseHiddenApis() {
+ if (isSignedWithPlatformKey()) {
+ return true;
+ } else if (isSystemApp() || isUpdatedSystemApp()) {
+ return usesNonSdkApi() || isPackageWhitelistedForHiddenApis();
+ } else {
+ return false;
+ }
+ }
+
+ @Override
+ public int getHiddenApiEnforcementPolicy() {
+ if (isAllowedToUseHiddenApis()) {
+ return ApplicationInfo.HIDDEN_API_ENFORCEMENT_DISABLED;
+ }
+
+ // TODO(b/135203078): Handle maybeUpdateHiddenApiEnforcementPolicy. Right now it's done
+ // entirely through ApplicationInfo and shouldn't touch this specific class, but that
+ // may not always hold true.
+// if (mHiddenApiPolicy != ApplicationInfo.HIDDEN_API_ENFORCEMENT_DEFAULT) {
+// return mHiddenApiPolicy;
+// }
+ return ApplicationInfo.HIDDEN_API_ENFORCEMENT_ENABLED;
+ }
+
+ @Nullable
+ @Override
+ public SparseArray<int[]> getSplitDependencies() {
+ return splitDependencies;
+ }
+
+ @Override
+ public boolean requestsIsolatedSplitLoading() {
+ return (privateFlags & ApplicationInfo.PRIVATE_FLAG_ISOLATED_SPLIT_LOADING) != 0;
+ }
+
+ @Deprecated
+ @Override
+ public String getAppInfoClassLoaderName() {
+ return classLoaderName;
+ }
+
+ @Override
+ public String getClassLoaderName() {
+ return classLoaderName;
+ }
+
+ @Override
+ public String[] getSplitClassLoaderNames() {
+ return splitClassLoaderNames;
+ }
+
+ @Override
+ public String getOverlayCategory() {
+ return overlayCategory;
+ }
+
+ @Override
+ public boolean isProfileableByShell() {
+ return (privateFlags & ApplicationInfo.PRIVATE_FLAG_PROFILEABLE_BY_SHELL) != 0;
+ }
+
+ @Nullable
+ @Override
+ public List<ParsedActivityIntentInfo> getPreferredActivityFilters() {
+ return preferredActivityFilters;
+ }
+
+ @Override
+ public boolean isHiddenUntilInstalled() {
+ return hiddenUntilInstalled;
+ }
+
+ @Override
+ public int getMinSdkVersion() {
+ return minSdkVersion;
+ }
+
+ @Override
+ public String getRestrictedAccountType() {
+ return restrictedAccountType;
+ }
+
+ @Override
+ public String getRequiredAccountType() {
+ return requiredAccountType;
+ }
+
+ @Override
+ public int getInstallLocation() {
+ return installLocation;
+ }
+
+ @Override
+ public List<ParsedActivity> getReceivers() {
+ return receivers;
+ }
+
+ @Override
+ public List<ParsedService> getServices() {
+ return services;
+ }
+
+ @Override
+ public List<ParsedProvider> getProviders() {
+ return providers;
+ }
+
+ @Override
+ public int getSharedUserLabel() {
+ return sharedUserLabel;
+ }
+
+ @Override
+ public int getVersionCodeMajor() {
+ return versionCodeMajor;
+ }
+
+ @Override
+ public boolean isRequiredForAllUsers() {
+ return requiredForAllUsers;
+ }
+
+ @Override
+ public int getCompileSdkVersion() {
+ return compileSdkVersion;
+ }
+
+ @Override
+ public String getCompileSdkVersionCodeName() {
+ return compileSdkVersionCodename;
+ }
+
+ @Nullable
+ @Override
+ public List<ConfigurationInfo> getConfigPreferences() {
+ return configPreferences;
+ }
+
+ @Nullable
+ @Override
+ public List<FeatureInfo> getReqFeatures() {
+ return reqFeatures;
+ }
+
+ @Override
+ public List<FeatureGroupInfo> getFeatureGroups() {
+ return featureGroups;
+ }
+
+ @Override
+ public String getDeviceProtectedDataDir() {
+ return deviceProtectedDataDir;
+ }
+
+ @Override
+ public String getCredentialProtectedDataDir() {
+ return credentialProtectedDataDir;
+ }
+
+ @Override
+ public String getSeInfoUser() {
+ return seInfoUser;
+ }
+
+ @Override
+ public String getClassName() {
+ return className;
+ }
+
+ @Override
+ public int getTheme() {
+ return theme;
+ }
+
+ @Override
+ public int getRequiresSmallestWidthDp() {
+ return requiresSmallestWidthDp;
+ }
+
+ @Override
+ public int getCompatibleWidthLimitDp() {
+ return compatibleWidthLimitDp;
+ }
+
+ @Override
+ public int getLargestWidthLimitDp() {
+ return largestWidthLimitDp;
+ }
+
+ @Override
+ public String getScanSourceDir() {
+ return applicationInfoCodePath;
+ }
+
+ @Override
+ public String getScanPublicSourceDir() {
+ return applicationInfoResourcePath;
+ }
+
+ @Override
+ public String getPublicSourceDir() {
+ return applicationInfoBaseResourcePath;
+ }
+
+ @Override
+ public String[] getSplitPublicSourceDirs() {
+ return applicationInfoSplitResourcePaths;
+ }
+
+ @Override
+ public String getSecondaryNativeLibraryDir() {
+ return secondaryNativeLibraryDir;
+ }
+
+ @Override
+ public boolean isEnabled() {
+ return enabled;
+ }
+
+ @Override
+ public String getManageSpaceActivityName() {
+ return manageSpaceActivityName;
+ }
+
+ @Override
+ public int getDescriptionRes() {
+ return descriptionRes;
+ }
+
+ @Override
+ public String getBackupAgentName() {
+ return backupAgentName;
+ }
+
+ @Override
+ public int getFullBackupContent() {
+ return fullBackupContent;
+ }
+
+ @Override
+ public int getNetworkSecurityConfigRes() {
+ return networkSecurityConfigRes;
+ }
+
+ @Override
+ public int getCategory() {
+ return category;
+ }
+
+ @Override
+ public int getTargetSandboxVersion() {
+ return targetSandboxVersion;
+ }
+
+ @Override
+ public String getAppComponentFactory() {
+ return appComponentFactory;
+ }
+
+ @Override
+ public int getIconRes() {
+ return iconRes;
+ }
+
+ @Override
+ public int getRoundIconRes() {
+ return roundIconRes;
+ }
+
+ @Override
+ public String getZygotePreloadName() {
+ return zygotePreloadName;
+ }
+
+ @Override
+ public int getLabelRes() {
+ return labelRes;
+ }
+
+ @Override
+ public CharSequence getNonLocalizedLabel() {
+ return nonLocalizedLabel;
+ }
+
+ @Override
+ public int getIcon() {
+ return icon;
+ }
+
+ @Override
+ public int getBanner() {
+ return banner;
+ }
+
+ @Override
+ public int getLogo() {
+ return logo;
+ }
+
+ @Override
+ public Bundle getMetaData() {
+ return appMetaData;
+ }
+
+ @Override
+ @Nullable
+ public List<Intent> getQueriesIntents() {
+ return queriesIntents;
+ }
+
+ @Override
+ @Nullable
+ public List<String> getQueriesPackages() {
+ return queriesPackages;
+ }
+
+ private static void internStringArrayList(List<String> list) {
+ if (list != null) {
+ final int N = list.size();
+ for (int i = 0; i < N; ++i) {
+ list.set(i, list.get(i).intern());
+ }
+ }
+ }
+
+ @Override
+ public int describeContents() {
+ return 0;
+ }
+
+ @Override
+ public void writeToParcel(Parcel dest, int flags) {
+ dest.writeInt(this.supportsSmallScreens);
+ dest.writeInt(this.supportsNormalScreens);
+ dest.writeInt(this.supportsLargeScreens);
+ dest.writeInt(this.supportsXLargeScreens);
+ dest.writeInt(this.resizeable);
+ dest.writeInt(this.anyDensity);
+ dest.writeLongArray(this.lastPackageUsageTimeInMills);
+ dest.writeInt(this.versionCode);
+ dest.writeInt(this.versionCodeMajor);
+ dest.writeInt(this.baseRevisionCode);
+ dest.writeString(this.versionName);
+ dest.writeBoolean(this.coreApp);
+ dest.writeInt(this.compileSdkVersion);
+ dest.writeString(this.compileSdkVersionCodename);
+ dest.writeString(this.packageName);
+ dest.writeString(this.realPackage);
+ dest.writeString(this.manifestPackageName);
+ dest.writeString(this.baseCodePath);
+ dest.writeBoolean(this.requiredForAllUsers);
+ dest.writeString(this.restrictedAccountType);
+ dest.writeString(this.requiredAccountType);
+ dest.writeBoolean(this.baseHardwareAccelerated);
+ dest.writeString(this.overlayTarget);
+ dest.writeString(this.overlayTargetName);
+ dest.writeString(this.overlayCategory);
+ dest.writeInt(this.overlayPriority);
+ dest.writeBoolean(this.overlayIsStatic);
+ dest.writeString(this.staticSharedLibName);
+ dest.writeLong(this.staticSharedLibVersion);
+ dest.writeStringList(this.libraryNames);
+ dest.writeStringList(this.usesLibraries);
+ dest.writeStringList(this.usesOptionalLibraries);
+ dest.writeStringList(this.usesStaticLibraries);
+ dest.writeLongArray(this.usesStaticLibrariesVersions);
+
+ if (this.usesStaticLibrariesCertDigests == null) {
+ dest.writeInt(-1);
+ } else {
+ dest.writeInt(this.usesStaticLibrariesCertDigests.length);
+ for (int index = 0; index < this.usesStaticLibrariesCertDigests.length; index++) {
+ dest.writeStringArray(this.usesStaticLibrariesCertDigests[index]);
+ }
+ }
+
+ dest.writeString(this.sharedUserId);
+ dest.writeInt(this.sharedUserLabel);
+ dest.writeTypedList(this.configPreferences);
+ dest.writeTypedList(this.reqFeatures);
+ dest.writeTypedList(this.featureGroups);
+ dest.writeByteArray(this.restrictUpdateHash);
+ dest.writeStringList(this.originalPackages);
+ dest.writeStringList(this.adoptPermissions);
+ dest.writeStringList(this.requestedPermissions);
+ dest.writeStringList(this.implicitPermissions);
+ dest.writeArraySet(this.upgradeKeySets);
+ dest.writeMap(this.keySetMapping);
+ dest.writeStringList(this.protectedBroadcasts);
+ dest.writeTypedList(this.activities);
+ dest.writeTypedList(this.receivers);
+ dest.writeTypedList(this.services);
+ dest.writeTypedList(this.providers);
+ dest.writeTypedList(this.permissions);
+ dest.writeTypedList(this.permissionGroups);
+ dest.writeTypedList(this.instrumentations);
+ ParsedIntentInfo.writeIntentsList(this.preferredActivityFilters, dest, flags);
+ dest.writeBundle(this.appMetaData);
+ dest.writeString(this.volumeUuid);
+ dest.writeString(this.applicationVolumeUuid);
+ dest.writeParcelable(this.signingDetails, flags);
+ dest.writeString(this.codePath);
+ dest.writeBoolean(this.use32BitAbi);
+ dest.writeBoolean(this.visibleToInstantApps);
+ dest.writeString(this.cpuAbiOverride);
+ dest.writeBoolean(this.isStub);
+ dest.writeInt(this.preferredOrder);
+ dest.writeBoolean(this.forceQueryable);
+ dest.writeParcelableList(this.queriesIntents, flags);
+ dest.writeStringList(this.queriesPackages);
+ dest.writeString(this.applicationInfoBaseResourcePath);
+ dest.writeString(this.applicationInfoCodePath);
+ dest.writeString(this.applicationInfoResourcePath);
+ dest.writeStringArray(this.applicationInfoSplitResourcePaths);
+ dest.writeString(this.appComponentFactory);
+ dest.writeString(this.backupAgentName);
+ dest.writeInt(this.banner);
+ dest.writeInt(this.category);
+ dest.writeString(this.classLoaderName);
+ dest.writeString(this.className);
+ dest.writeInt(this.compatibleWidthLimitDp);
+ dest.writeString(this.credentialProtectedDataDir);
+ dest.writeString(this.dataDir);
+ dest.writeInt(this.descriptionRes);
+ dest.writeString(this.deviceProtectedDataDir);
+ dest.writeBoolean(this.enabled);
+ dest.writeInt(this.flags);
+ dest.writeInt(this.fullBackupContent);
+ dest.writeBoolean(this.hiddenUntilInstalled);
+ dest.writeInt(this.icon);
+ dest.writeInt(this.iconRes);
+ dest.writeInt(this.installLocation);
+ dest.writeInt(this.labelRes);
+ dest.writeInt(this.largestWidthLimitDp);
+ dest.writeInt(this.logo);
+ dest.writeString(this.manageSpaceActivityName);
+ dest.writeFloat(this.maxAspectRatio);
+ dest.writeFloat(this.minAspectRatio);
+ dest.writeInt(this.minSdkVersion);
+ dest.writeString(this.name);
+ dest.writeString(this.nativeLibraryDir);
+ dest.writeString(this.nativeLibraryRootDir);
+ dest.writeBoolean(this.nativeLibraryRootRequiresIsa);
+ dest.writeInt(this.networkSecurityConfigRes);
+ dest.writeCharSequence(this.nonLocalizedLabel);
+ dest.writeString(this.permission);
+ dest.writeString(this.primaryCpuAbi);
+ dest.writeInt(this.privateFlags);
+ dest.writeString(this.processName);
+ dest.writeInt(this.requiresSmallestWidthDp);
+ dest.writeInt(this.roundIconRes);
+ dest.writeString(this.secondaryCpuAbi);
+ dest.writeString(this.secondaryNativeLibraryDir);
+ dest.writeString(this.seInfo);
+ dest.writeString(this.seInfoUser);
+ dest.writeInt(this.targetSandboxVersion);
+ dest.writeInt(this.targetSdkVersion);
+ dest.writeString(this.taskAffinity);
+ dest.writeInt(this.theme);
+ dest.writeInt(this.uid);
+ dest.writeInt(this.uiOptions);
+ dest.writeStringArray(this.usesLibraryFiles);
+ dest.writeTypedList(this.usesLibraryInfos);
+ dest.writeString(this.zygotePreloadName);
+ dest.writeStringArray(this.splitClassLoaderNames);
+ dest.writeStringArray(this.splitCodePaths);
+ dest.writeSparseArray(this.splitDependencies);
+ dest.writeIntArray(this.splitFlags);
+ dest.writeStringArray(this.splitNames);
+ dest.writeIntArray(this.splitRevisionCodes);
+ }
+
+ public PackageImpl(Parcel in) {
+ // We use the boot classloader for all classes that we load.
+ final ClassLoader boot = Object.class.getClassLoader();
+ this.supportsSmallScreens = in.readInt();
+ this.supportsNormalScreens = in.readInt();
+ this.supportsLargeScreens = in.readInt();
+ this.supportsXLargeScreens = in.readInt();
+ this.resizeable = in.readInt();
+ this.anyDensity = in.readInt();
+ this.lastPackageUsageTimeInMills = in.createLongArray();
+ this.versionCode = in.readInt();
+ this.versionCodeMajor = in.readInt();
+ this.baseRevisionCode = in.readInt();
+ this.versionName = TextUtils.safeIntern(in.readString());
+ this.coreApp = in.readBoolean();
+ this.compileSdkVersion = in.readInt();
+ this.compileSdkVersionCodename = TextUtils.safeIntern(in.readString());
+ this.packageName = TextUtils.safeIntern(in.readString());
+ this.realPackage = in.readString();
+ this.manifestPackageName = in.readString();
+ this.baseCodePath = in.readString();
+ this.requiredForAllUsers = in.readBoolean();
+ this.restrictedAccountType = in.readString();
+ this.requiredAccountType = in.readString();
+ this.baseHardwareAccelerated = in.readBoolean();
+ this.overlayTarget = in.readString();
+ this.overlayTargetName = in.readString();
+ this.overlayCategory = in.readString();
+ this.overlayPriority = in.readInt();
+ this.overlayIsStatic = in.readBoolean();
+ this.staticSharedLibName = TextUtils.safeIntern(in.readString());
+ this.staticSharedLibVersion = in.readLong();
+ this.libraryNames = in.createStringArrayList();
+ internStringArrayList(this.libraryNames);
+ this.usesLibraries = in.createStringArrayList();
+ internStringArrayList(this.usesLibraries);
+ this.usesOptionalLibraries = in.createStringArrayList();
+ internStringArrayList(this.usesOptionalLibraries);
+ this.usesStaticLibraries = in.createStringArrayList();
+ internStringArrayList(usesStaticLibraries);
+ this.usesStaticLibrariesVersions = in.createLongArray();
+
+ int digestsSize = in.readInt();
+ if (digestsSize >= 0) {
+ this.usesStaticLibrariesCertDigests = new String[digestsSize][];
+ for (int index = 0; index < digestsSize; index++) {
+ this.usesStaticLibrariesCertDigests[index] = in.readStringArray();
+ }
+ }
+
+ this.sharedUserId = TextUtils.safeIntern(in.readString());
+ this.sharedUserLabel = in.readInt();
+ this.configPreferences = in.createTypedArrayList(ConfigurationInfo.CREATOR);
+ this.reqFeatures = in.createTypedArrayList(FeatureInfo.CREATOR);
+ this.featureGroups = in.createTypedArrayList(FeatureGroupInfo.CREATOR);
+ this.restrictUpdateHash = in.createByteArray();
+ this.originalPackages = in.createStringArrayList();
+ this.adoptPermissions = in.createStringArrayList();
+ this.requestedPermissions = in.createStringArrayList();
+ internStringArrayList(this.requestedPermissions);
+ this.implicitPermissions = in.createStringArrayList();
+ internStringArrayList(this.implicitPermissions);
+ this.upgradeKeySets = (ArraySet<String>) in.readArraySet(boot);
+ this.keySetMapping = in.readHashMap(boot);
+ this.protectedBroadcasts = in.createStringArrayList();
+ internStringArrayList(this.protectedBroadcasts);
+ this.activities = in.createTypedArrayList(ParsedActivity.CREATOR);
+ this.receivers = in.createTypedArrayList(ParsedActivity.CREATOR);
+ this.services = in.createTypedArrayList(ParsedService.CREATOR);
+ this.providers = in.createTypedArrayList(ParsedProvider.CREATOR);
+ this.permissions = in.createTypedArrayList(ParsedPermission.CREATOR);
+ this.permissionGroups = in.createTypedArrayList(ParsedPermissionGroup.CREATOR);
+ this.instrumentations = in.createTypedArrayList(ParsedInstrumentation.CREATOR);
+ this.preferredActivityFilters = ParsedIntentInfo.createIntentsList(in);
+ this.appMetaData = in.readBundle(boot);
+ this.volumeUuid = in.readString();
+ this.applicationVolumeUuid = in.readString();
+ this.signingDetails = in.readParcelable(boot);
+ this.codePath = in.readString();
+ this.use32BitAbi = in.readBoolean();
+ this.visibleToInstantApps = in.readBoolean();
+ this.cpuAbiOverride = in.readString();
+ this.isStub = in.readBoolean();
+ this.preferredOrder = in.readInt();
+ this.forceQueryable = in.readBoolean();
+ this.queriesIntents = in.createTypedArrayList(Intent.CREATOR);
+ this.queriesPackages = in.createStringArrayList();
+ internStringArrayList(this.queriesPackages);
+ this.applicationInfoBaseResourcePath = in.readString();
+ this.applicationInfoCodePath = in.readString();
+ this.applicationInfoResourcePath = in.readString();
+ this.applicationInfoSplitResourcePaths = in.createStringArray();
+ this.appComponentFactory = in.readString();
+ this.backupAgentName = in.readString();
+ this.banner = in.readInt();
+ this.category = in.readInt();
+ this.classLoaderName = in.readString();
+ this.className = in.readString();
+ this.compatibleWidthLimitDp = in.readInt();
+ this.credentialProtectedDataDir = in.readString();
+ this.dataDir = in.readString();
+ this.descriptionRes = in.readInt();
+ this.deviceProtectedDataDir = in.readString();
+ this.enabled = in.readBoolean();
+ this.flags = in.readInt();
+ this.fullBackupContent = in.readInt();
+ this.hiddenUntilInstalled = in.readBoolean();
+ this.icon = in.readInt();
+ this.iconRes = in.readInt();
+ this.installLocation = in.readInt();
+ this.labelRes = in.readInt();
+ this.largestWidthLimitDp = in.readInt();
+ this.logo = in.readInt();
+ this.manageSpaceActivityName = in.readString();
+ this.maxAspectRatio = in.readFloat();
+ this.minAspectRatio = in.readFloat();
+ this.minSdkVersion = in.readInt();
+ this.name = in.readString();
+ this.nativeLibraryDir = in.readString();
+ this.nativeLibraryRootDir = in.readString();
+ this.nativeLibraryRootRequiresIsa = in.readBoolean();
+ this.networkSecurityConfigRes = in.readInt();
+ this.nonLocalizedLabel = in.readCharSequence();
+ this.permission = TextUtils.safeIntern(in.readString());
+ this.primaryCpuAbi = in.readString();
+ this.privateFlags = in.readInt();
+ this.processName = in.readString();
+ this.requiresSmallestWidthDp = in.readInt();
+ this.roundIconRes = in.readInt();
+ this.secondaryCpuAbi = in.readString();
+ this.secondaryNativeLibraryDir = in.readString();
+ this.seInfo = in.readString();
+ this.seInfoUser = in.readString();
+ this.targetSandboxVersion = in.readInt();
+ this.targetSdkVersion = in.readInt();
+ this.taskAffinity = in.readString();
+ this.theme = in.readInt();
+ this.uid = in.readInt();
+ this.uiOptions = in.readInt();
+ this.usesLibraryFiles = in.createStringArray();
+ this.usesLibraryInfos = in.createTypedArrayList(SharedLibraryInfo.CREATOR);
+ this.zygotePreloadName = in.readString();
+ this.splitClassLoaderNames = in.createStringArray();
+ this.splitCodePaths = in.createStringArray();
+ this.splitDependencies = in.readSparseArray(boot);
+ this.splitFlags = in.createIntArray();
+ this.splitNames = in.createStringArray();
+ this.splitRevisionCodes = in.createIntArray();
+ }
+
+ public static final Creator<PackageImpl> CREATOR = new Creator<PackageImpl>() {
+ @Override
+ public PackageImpl createFromParcel(Parcel source) {
+ return new PackageImpl(source);
+ }
+
+ @Override
+ public PackageImpl[] newArray(int size) {
+ return new PackageImpl[size];
+ }
+ };
+}
diff --git a/core/java/android/content/pm/parsing/PackageInfoUtils.java b/core/java/android/content/pm/parsing/PackageInfoUtils.java
new file mode 100644
index 000000000000..7b329ebc5b83
--- /dev/null
+++ b/core/java/android/content/pm/parsing/PackageInfoUtils.java
@@ -0,0 +1,732 @@
+/*
+ * Copyright (C) 2019 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 android.content.pm.parsing;
+
+import static android.content.pm.ApplicationInfo.FLAG_SUSPENDED;
+
+import android.annotation.Nullable;
+import android.content.pm.ActivityInfo;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.ComponentInfo;
+import android.content.pm.ConfigurationInfo;
+import android.content.pm.FallbackCategoryProvider;
+import android.content.pm.FeatureGroupInfo;
+import android.content.pm.FeatureInfo;
+import android.content.pm.InstrumentationInfo;
+import android.content.pm.PackageInfo;
+import android.content.pm.PackageItemInfo;
+import android.content.pm.PackageManager;
+import android.content.pm.PackageParser;
+import android.content.pm.PackageUserState;
+import android.content.pm.PermissionGroupInfo;
+import android.content.pm.PermissionInfo;
+import android.content.pm.ProviderInfo;
+import android.content.pm.SELinuxUtil;
+import android.content.pm.ServiceInfo;
+import android.content.pm.Signature;
+import android.content.pm.SigningInfo;
+import android.content.pm.parsing.ComponentParseUtils.ParsedActivity;
+import android.content.pm.parsing.ComponentParseUtils.ParsedInstrumentation;
+import android.content.pm.parsing.ComponentParseUtils.ParsedPermission;
+import android.content.pm.parsing.ComponentParseUtils.ParsedPermissionGroup;
+import android.os.Bundle;
+import android.os.UserHandle;
+
+import com.android.internal.util.ArrayUtils;
+
+import java.util.Set;
+
+/** @hide */
+public class PackageInfoUtils {
+
+ private static final String TAG = ApkParseUtils.TAG;
+
+ /**
+ * Returns true if the package is installed and not hidden, or if the caller
+ * explicitly wanted all uninstalled and hidden packages as well.
+ */
+ private static boolean checkUseInstalledOrHidden(AndroidPackage pkg, PackageUserState state,
+ @PackageManager.PackageInfoFlags int flags) {
+ // Returns false if the package is hidden system app until installed.
+ if ((flags & PackageManager.MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS) == 0
+ && !state.installed
+ && pkg.isHiddenUntilInstalled()) {
+ return false;
+ }
+
+ // If available for the target user, or trying to match uninstalled packages and it's
+ // a system app.
+ return state.isAvailable(flags)
+ || (pkg.isSystemApp()
+ && ((flags & PackageManager.MATCH_KNOWN_PACKAGES) != 0
+ || (flags & PackageManager.MATCH_HIDDEN_UNTIL_INSTALLED_COMPONENTS) != 0));
+ }
+
+ public static PackageInfo generate(AndroidPackage pkg, int[] gids,
+ @PackageManager.PackageInfoFlags int flags, long firstInstallTime, long lastUpdateTime,
+ Set<String> grantedPermissions, PackageUserState state, int userId) {
+ if (!checkUseInstalledOrHidden(pkg, state, flags) || !pkg.isMatch(flags)) {
+ return null;
+ }
+ ApplicationInfo applicationInfo = generateApplicationInfo(pkg, flags, state, userId);
+
+ PackageInfo pi = new PackageInfo();
+ pi.packageName = pkg.getPackageName();
+ pi.splitNames = pkg.getSplitNames();
+ pi.versionCode = pkg.getVersionCode();
+ pi.versionCodeMajor = pkg.getVersionCodeMajor();
+ pi.baseRevisionCode = pkg.getBaseRevisionCode();
+ pi.splitRevisionCodes = pkg.getSplitRevisionCodes();
+ pi.versionName = pkg.getVersionName();
+ pi.sharedUserId = pkg.getSharedUserId();
+ pi.sharedUserLabel = pkg.getSharedUserLabel();
+ pi.applicationInfo = applicationInfo;
+ pi.installLocation = pkg.getInstallLocation();
+ pi.isStub = pkg.isStub();
+ pi.coreApp = pkg.isCoreApp();
+ if ((pi.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0
+ || (pi.applicationInfo.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0) {
+ pi.requiredForAllUsers = pkg.isRequiredForAllUsers();
+ }
+ pi.restrictedAccountType = pkg.getRestrictedAccountType();
+ pi.requiredAccountType = pkg.getRequiredAccountType();
+ pi.overlayTarget = pkg.getOverlayTarget();
+ pi.targetOverlayableName = pkg.getOverlayTargetName();
+ pi.overlayCategory = pkg.getOverlayCategory();
+ pi.overlayPriority = pkg.getOverlayPriority();
+ pi.mOverlayIsStatic = pkg.isOverlayIsStatic();
+ pi.compileSdkVersion = pkg.getCompileSdkVersion();
+ pi.compileSdkVersionCodename = pkg.getCompileSdkVersionCodeName();
+ pi.firstInstallTime = firstInstallTime;
+ pi.lastUpdateTime = lastUpdateTime;
+ if ((flags & PackageManager.GET_GIDS) != 0) {
+ pi.gids = gids;
+ }
+ if ((flags & PackageManager.GET_CONFIGURATIONS) != 0) {
+ int size = pkg.getConfigPreferences() != null ? pkg.getConfigPreferences().size() : 0;
+ if (size > 0) {
+ pi.configPreferences = new ConfigurationInfo[size];
+ pkg.getConfigPreferences().toArray(pi.configPreferences);
+ }
+ size = pkg.getReqFeatures() != null ? pkg.getReqFeatures().size() : 0;
+ if (size > 0) {
+ pi.reqFeatures = new FeatureInfo[size];
+ pkg.getReqFeatures().toArray(pi.reqFeatures);
+ }
+ size = pkg.getFeatureGroups() != null ? pkg.getFeatureGroups().size() : 0;
+ if (size > 0) {
+ pi.featureGroups = new FeatureGroupInfo[size];
+ pkg.getFeatureGroups().toArray(pi.featureGroups);
+ }
+ }
+ if ((flags & PackageManager.GET_ACTIVITIES) != 0) {
+ if (pkg.getActivities() != null) {
+ final int N = pkg.getActivities().size();
+ if (N > 0) {
+ int num = 0;
+ final ActivityInfo[] res = new ActivityInfo[N];
+ for (int i = 0; i < N; i++) {
+ final ParsedActivity a = pkg.getActivities().get(i);
+ if (state.isMatch(pkg.isSystem(), pkg.isEnabled(), a, flags)) {
+ if (PackageManager.APP_DETAILS_ACTIVITY_CLASS_NAME.equals(
+ a.className)) {
+ continue;
+ }
+ res[num++] = generateActivityInfo(pkg, a, flags, state, applicationInfo,
+ userId);
+ }
+ }
+ pi.activities = ArrayUtils.trimToSize(res, num);
+ }
+ }
+ }
+ if ((flags & PackageManager.GET_RECEIVERS) != 0) {
+ if (pkg.getReceivers() != null) {
+ final int size = pkg.getReceivers().size();
+ if (size > 0) {
+ int num = 0;
+ final ActivityInfo[] res = new ActivityInfo[size];
+ for (int i = 0; i < size; i++) {
+ final ParsedActivity a = pkg.getReceivers().get(i);
+ if (state.isMatch(pkg.isSystem(), pkg.isEnabled(), a, flags)) {
+ res[num++] = generateActivityInfo(pkg, a, flags, state, applicationInfo,
+ userId);
+ }
+ }
+ pi.receivers = ArrayUtils.trimToSize(res, num);
+ }
+ }
+ }
+ if ((flags & PackageManager.GET_SERVICES) != 0) {
+ if (pkg.getServices() != null) {
+ final int size = pkg.getServices().size();
+ if (size > 0) {
+ int num = 0;
+ final ServiceInfo[] res = new ServiceInfo[size];
+ for (int i = 0; i < size; i++) {
+ final ComponentParseUtils.ParsedService s = pkg.getServices().get(i);
+ if (state.isMatch(pkg.isSystem(), pkg.isEnabled(), s, flags)) {
+ res[num++] = generateServiceInfo(pkg, s, flags, state, applicationInfo,
+ userId);
+ }
+ }
+ pi.services = ArrayUtils.trimToSize(res, num);
+ }
+ }
+ }
+ if ((flags & PackageManager.GET_PROVIDERS) != 0) {
+ if (pkg.getProviders() != null) {
+ final int size = pkg.getProviders().size();
+ if (size > 0) {
+ int num = 0;
+ final ProviderInfo[] res = new ProviderInfo[size];
+ for (int i = 0; i < size; i++) {
+ final ComponentParseUtils.ParsedProvider pr = pkg.getProviders()
+ .get(i);
+ if (state.isMatch(pkg.isSystem(), pkg.isEnabled(), pr, flags)) {
+ res[num++] = generateProviderInfo(pkg, pr, flags, state,
+ applicationInfo, userId);
+ }
+ }
+ pi.providers = ArrayUtils.trimToSize(res, num);
+ }
+ }
+ }
+ if ((flags & PackageManager.GET_INSTRUMENTATION) != 0) {
+ if (pkg.getInstrumentations() != null) {
+ int N = pkg.getInstrumentations().size();
+ if (N > 0) {
+ pi.instrumentation = new InstrumentationInfo[N];
+ for (int i = 0; i < N; i++) {
+ pi.instrumentation[i] = generateInstrumentationInfo(
+ pkg.getInstrumentations().get(i), flags);
+ }
+ }
+ }
+ }
+ if ((flags & PackageManager.GET_PERMISSIONS) != 0) {
+ if (pkg.getPermissions() != null) {
+ int N = ArrayUtils.size(pkg.getPermissions());
+ if (N > 0) {
+ pi.permissions = new PermissionInfo[N];
+ for (int i = 0; i < N; i++) {
+ pi.permissions[i] = generatePermissionInfo(
+ pkg.getPermissions().get(i),
+ flags
+ );
+ }
+ }
+ }
+ if (pkg.getRequestedPermissions() != null) {
+ int N = pkg.getRequestedPermissions().size();
+ if (N > 0) {
+ pi.requestedPermissions = new String[N];
+ pi.requestedPermissionsFlags = new int[N];
+ for (int i = 0; i < N; i++) {
+ final String perm = pkg.getRequestedPermissions().get(i);
+ pi.requestedPermissions[i] = perm;
+ // The notion of required permissions is deprecated but for compatibility.
+ pi.requestedPermissionsFlags[i] |=
+ PackageInfo.REQUESTED_PERMISSION_REQUIRED;
+ if (grantedPermissions != null && grantedPermissions.contains(perm)) {
+ pi.requestedPermissionsFlags[i] |=
+ PackageInfo.REQUESTED_PERMISSION_GRANTED;
+ }
+ }
+ }
+ }
+ }
+
+ PackageParser.SigningDetails signingDetails = pkg.getSigningDetails();
+ // deprecated method of getting signing certificates
+ if ((flags & PackageManager.GET_SIGNATURES) != 0) {
+ if (signingDetails.hasPastSigningCertificates()) {
+ // Package has included signing certificate rotation information. Return the oldest
+ // cert so that programmatic checks keep working even if unaware of key rotation.
+ pi.signatures = new Signature[1];
+ pi.signatures[0] = signingDetails.pastSigningCertificates[0];
+ } else if (signingDetails.hasSignatures()) {
+ // otherwise keep old behavior
+ int numberOfSigs = signingDetails.signatures.length;
+ pi.signatures = new Signature[numberOfSigs];
+ System.arraycopy(signingDetails.signatures, 0, pi.signatures, 0,
+ numberOfSigs);
+ }
+ }
+
+ // replacement for GET_SIGNATURES
+ if ((flags & PackageManager.GET_SIGNING_CERTIFICATES) != 0) {
+ if (signingDetails != PackageParser.SigningDetails.UNKNOWN) {
+ // only return a valid SigningInfo if there is signing information to report
+ pi.signingInfo = new SigningInfo(signingDetails);
+ } else {
+ pi.signingInfo = null;
+ }
+ }
+
+ return pi;
+ }
+
+ // TODO(b/135203078): Remove this in favor of AndroidPackage.toAppInfo()
+ private static ApplicationInfo appInfoFromFinalPackage(AndroidPackage pkg) {
+ ApplicationInfo appInfo = new ApplicationInfo();
+ appInfo.name = pkg.getName();
+ if (appInfo.name != null) appInfo.name = appInfo.name.trim();
+ appInfo.packageName = pkg.getPackageName();
+ appInfo.labelRes = pkg.getLabelRes();
+ appInfo.nonLocalizedLabel = pkg.getNonLocalizedLabel();
+ if (appInfo.nonLocalizedLabel != null) {
+ appInfo.nonLocalizedLabel = appInfo.nonLocalizedLabel.toString().trim();
+ }
+ appInfo.icon = pkg.getIcon();
+ appInfo.banner = pkg.getBanner();
+ appInfo.logo = pkg.getLogo();
+ appInfo.metaData = pkg.getMetaData();
+
+ // TODO(b/135203078): Can this be removed? Looks only used in ActivityInfo.
+// appInfo.showUserIcon = pkg.getShowUserIcon();
+
+ appInfo.taskAffinity = pkg.getTaskAffinity();
+ appInfo.permission = pkg.getPermission();
+ appInfo.processName = pkg.getProcessName();
+ appInfo.className = pkg.getClassName();
+ appInfo.theme = pkg.getTheme();
+ appInfo.flags = pkg.getFlags();
+ appInfo.privateFlags = pkg.getPrivateFlags();
+ appInfo.requiresSmallestWidthDp = pkg.getRequiresSmallestWidthDp();
+ appInfo.compatibleWidthLimitDp = pkg.getCompatibleWidthLimitDp();
+ appInfo.largestWidthLimitDp = pkg.getLargestWidthLimitDp();
+ appInfo.volumeUuid = pkg.getVolumeUuid();
+ appInfo.storageUuid = pkg.getStorageUuid();
+ appInfo.scanSourceDir = pkg.getScanSourceDir();
+ appInfo.scanPublicSourceDir = pkg.getScanPublicSourceDir();
+ appInfo.sourceDir = pkg.getBaseCodePath();
+ appInfo.publicSourceDir = pkg.getPublicSourceDir();
+ appInfo.splitNames = pkg.getSplitNames();
+ appInfo.splitSourceDirs = pkg.getSplitCodePaths();
+ appInfo.splitPublicSourceDirs = pkg.getSplitPublicSourceDirs();
+ appInfo.splitDependencies = pkg.getSplitDependencies();
+ appInfo.nativeLibraryDir = pkg.getNativeLibraryDir();
+ appInfo.secondaryNativeLibraryDir = pkg.getSecondaryNativeLibraryDir();
+ appInfo.nativeLibraryRootDir = pkg.getNativeLibraryRootDir();
+ appInfo.nativeLibraryRootRequiresIsa = pkg.isNativeLibraryRootRequiresIsa();
+ appInfo.primaryCpuAbi = pkg.getPrimaryCpuAbi();
+ appInfo.secondaryCpuAbi = pkg.getSecondaryCpuAbi();
+
+ // TODO(b/135203078): Unused?
+// appInfo.resourceDirs = pkg.getResourceDirs();
+ appInfo.seInfo = pkg.getSeInfo();
+ appInfo.seInfoUser = pkg.getSeInfoUser();
+ appInfo.sharedLibraryFiles = pkg.getUsesLibraryFiles();
+ appInfo.sharedLibraryInfos = pkg.getUsesLibraryInfos();
+ appInfo.dataDir = pkg.getDataDir();
+ appInfo.deviceProtectedDataDir = pkg.getDeviceProtectedDataDir();
+ appInfo.credentialProtectedDataDir = pkg.getCredentialProtectedDataDir();
+ appInfo.uid = pkg.getUid();
+ appInfo.minSdkVersion = pkg.getMinSdkVersion();
+ appInfo.targetSdkVersion = pkg.getTargetSdkVersion();
+ appInfo.setVersionCode(pkg.getLongVersionCode());
+ appInfo.enabled = pkg.isEnabled();
+
+ // TODO(b/135203078): Unused?
+// appInfo.enabledSetting = pkg.getEnabledSetting();
+ appInfo.installLocation = pkg.getInstallLocation();
+ appInfo.manageSpaceActivityName = pkg.getManageSpaceActivityName();
+ appInfo.descriptionRes = pkg.getDescriptionRes();
+ appInfo.uiOptions = pkg.getUiOptions();
+ appInfo.backupAgentName = pkg.getBackupAgentName();
+ appInfo.fullBackupContent = pkg.getFullBackupContent();
+ appInfo.networkSecurityConfigRes = pkg.getNetworkSecurityConfigRes();
+ appInfo.category = pkg.getCategory();
+ appInfo.targetSandboxVersion = pkg.getTargetSandboxVersion();
+ appInfo.classLoaderName = pkg.getClassLoaderName();
+ appInfo.splitClassLoaderNames = pkg.getSplitClassLoaderNames();
+ appInfo.appComponentFactory = pkg.getAppComponentFactory();
+ appInfo.iconRes = pkg.getIconRes();
+ appInfo.roundIconRes = pkg.getRoundIconRes();
+ appInfo.compileSdkVersion = pkg.getCompileSdkVersion();
+ appInfo.compileSdkVersionCodename = pkg.getCompileSdkVersionCodeName();
+
+ // TODO(b/135203078): See PackageImpl#getHiddenApiEnforcementPolicy
+// appInfo.mHiddenApiPolicy = pkg.getHiddenApiPolicy();
+ appInfo.hiddenUntilInstalled = pkg.isHiddenUntilInstalled();
+ appInfo.zygotePreloadName = pkg.getZygotePreloadName();
+ return appInfo;
+ }
+
+ public static ApplicationInfo generateApplicationInfo(AndroidPackage pkg,
+ @PackageManager.ApplicationInfoFlags int flags, PackageUserState state, int userId) {
+
+ if (pkg == null) return null;
+ if (!checkUseInstalledOrHidden(pkg, state, flags) || !pkg.isMatch(flags)) {
+ return null;
+ }
+ if (!copyNeeded(flags, pkg, state, null, userId)
+ && ((flags & PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS) == 0
+ || state.enabled != PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED)) {
+ // TODO(b/135203078): This isn't applicable anymore, as AppInfo isn't cached and
+ // always built new in toAppInfo(). Remove entire copyNeeded flow? Or find a way to
+ // transiently cache AppInfo, since multiple calls in quick secession probably need
+ // the same AppInfo.
+ // In this case it is safe to directly modify the internal ApplicationInfo state:
+ // - CompatibilityMode is global state, so will be the same for every call.
+ // - We only come in to here if the app should reported as installed; this is the
+ // default state, and we will do a copy otherwise.
+ // - The enable state will always be reported the same for the application across
+ // calls; the only exception is for the UNTIL_USED mode, and in that case we will
+ // be doing a copy.
+ ApplicationInfo applicationInfo = pkg.toAppInfo();
+ updateApplicationInfo(applicationInfo, flags, state);
+ return applicationInfo;
+ }
+
+ // Make shallow copy so we can store the metadata/libraries safely
+ ApplicationInfo ai = appInfoFromFinalPackage(pkg);
+ ai.initForUser(userId);
+ if ((flags & PackageManager.GET_META_DATA) != 0) {
+ ai.metaData = pkg.getAppMetaData();
+ }
+ if ((flags & PackageManager.GET_SHARED_LIBRARY_FILES) != 0) {
+ ai.sharedLibraryFiles = pkg.getUsesLibraryFiles();
+ ai.sharedLibraryInfos = pkg.getUsesLibraryInfos();
+ }
+ if (state.stopped) {
+ ai.flags |= ApplicationInfo.FLAG_STOPPED;
+ } else {
+ ai.flags &= ~ApplicationInfo.FLAG_STOPPED;
+ }
+ updateApplicationInfo(ai, flags, state);
+
+ return ai;
+ }
+
+ private static ActivityInfo generateActivityInfo(AndroidPackage pkg, ParsedActivity a,
+ @PackageManager.ComponentInfoFlags int flags, PackageUserState state,
+ @Nullable ApplicationInfo applicationInfo, int userId) {
+ if (a == null) return null;
+ if (!checkUseInstalledOrHidden(pkg, state, flags)) {
+ return null;
+ }
+ if (applicationInfo == null) {
+ applicationInfo = generateApplicationInfo(pkg, flags, state, userId);
+ }
+ if (!copyNeeded(flags, pkg, state, a.metaData, userId)) {
+ updateApplicationInfo(applicationInfo, flags, state);
+ }
+ // Make shallow copies so we can store the metadata safely
+ ActivityInfo ai = new ActivityInfo();
+ assignSharedFieldsForComponentInfo(ai, a);
+ ai.targetActivity = a.targetActivity;
+ ai.processName = a.getProcessName();
+ ai.exported = a.exported;
+ ai.theme = a.theme;
+ ai.uiOptions = a.uiOptions;
+ ai.parentActivityName = a.parentActivityName;
+ ai.permission = a.getPermission();
+ ai.taskAffinity = a.taskAffinity;
+ ai.flags = a.flags;
+ ai.privateFlags = a.privateFlags;
+ ai.launchMode = a.launchMode;
+ ai.documentLaunchMode = a.documentLaunchMode;
+ ai.maxRecents = a.maxRecents;
+ ai.configChanges = a.configChanges;
+ ai.softInputMode = a.softInputMode;
+ ai.persistableMode = a.persistableMode;
+ ai.lockTaskLaunchMode = a.lockTaskLaunchMode;
+ ai.screenOrientation = a.screenOrientation;
+ ai.resizeMode = a.resizeMode;
+ ai.maxAspectRatio = a.maxAspectRatio;
+ ai.minAspectRatio = a.minAspectRatio;
+ ai.requestedVrComponent = a.requestedVrComponent;
+ ai.rotationAnimation = a.rotationAnimation;
+ ai.colorMode = a.colorMode;
+ ai.windowLayout = a.windowLayout;
+ ai.metaData = a.metaData;
+ ai.applicationInfo = applicationInfo;
+ return ai;
+ }
+
+ public static ActivityInfo generateActivityInfo(AndroidPackage pkg, ParsedActivity a,
+ @PackageManager.ComponentInfoFlags int flags, PackageUserState state, int userId) {
+ return generateActivityInfo(pkg, a, flags, state, null, userId);
+ }
+
+ private static ServiceInfo generateServiceInfo(AndroidPackage pkg,
+ ComponentParseUtils.ParsedService s, @PackageManager.ComponentInfoFlags int flags,
+ PackageUserState state, @Nullable ApplicationInfo applicationInfo, int userId) {
+ if (s == null) return null;
+ if (!checkUseInstalledOrHidden(pkg, state, flags)) {
+ return null;
+ }
+ if (applicationInfo == null) {
+ applicationInfo = generateApplicationInfo(pkg, flags, state, userId);
+ }
+ if (!copyNeeded(flags, pkg, state, s.metaData, userId)) {
+ updateApplicationInfo(applicationInfo, flags, state);
+ }
+ // Make shallow copies so we can store the metadata safely
+ ServiceInfo si = new ServiceInfo();
+ assignSharedFieldsForComponentInfo(si, s);
+ si.exported = s.exported;
+ si.flags = s.flags;
+ si.metaData = s.metaData;
+ si.permission = s.getPermission();
+ si.processName = s.getProcessName();
+ si.mForegroundServiceType = s.foregroundServiceType;
+ si.metaData = s.metaData;
+ si.applicationInfo = applicationInfo;
+ return si;
+ }
+
+ public static ServiceInfo generateServiceInfo(AndroidPackage pkg,
+ ComponentParseUtils.ParsedService s, @PackageManager.ComponentInfoFlags int flags,
+ PackageUserState state, int userId) {
+ return generateServiceInfo(pkg, s, flags, state, null, userId);
+ }
+
+ private static ProviderInfo generateProviderInfo(AndroidPackage pkg,
+ ComponentParseUtils.ParsedProvider p, @PackageManager.ComponentInfoFlags int flags,
+ PackageUserState state, @Nullable ApplicationInfo applicationInfo, int userId) {
+ if (p == null) return null;
+ if (!checkUseInstalledOrHidden(pkg, state, flags)) {
+ return null;
+ }
+ if (applicationInfo == null) {
+ applicationInfo = generateApplicationInfo(pkg, flags, state, userId);
+ }
+ if (!copyNeeded(flags, pkg, state, p.metaData, userId)
+ && ((flags & PackageManager.GET_URI_PERMISSION_PATTERNS) != 0
+ || p.uriPermissionPatterns == null)) {
+ updateApplicationInfo(applicationInfo, flags, state);
+ }
+ // Make shallow copies so we can store the metadata safely
+ ProviderInfo pi = new ProviderInfo();
+ assignSharedFieldsForComponentInfo(pi, p);
+ pi.exported = p.exported;
+ pi.flags = p.flags;
+ pi.processName = p.getProcessName();
+ pi.authority = p.getAuthority();
+ pi.isSyncable = p.isSyncable;
+ pi.readPermission = p.getReadPermission();
+ pi.writePermission = p.getWritePermission();
+ pi.grantUriPermissions = p.grantUriPermissions;
+ pi.forceUriPermissions = p.forceUriPermissions;
+ pi.multiprocess = p.multiProcess;
+ pi.initOrder = p.initOrder;
+ pi.uriPermissionPatterns = p.uriPermissionPatterns;
+ pi.pathPermissions = p.pathPermissions;
+ pi.metaData = p.metaData;
+ if ((flags & PackageManager.GET_URI_PERMISSION_PATTERNS) == 0) {
+ pi.uriPermissionPatterns = null;
+ }
+ pi.applicationInfo = applicationInfo;
+ return pi;
+ }
+
+ public static ProviderInfo generateProviderInfo(AndroidPackage pkg,
+ ComponentParseUtils.ParsedProvider p, @PackageManager.ComponentInfoFlags int flags,
+ PackageUserState state, int userId) {
+ return generateProviderInfo(pkg, p, flags, state, null, userId);
+ }
+
+ public static InstrumentationInfo generateInstrumentationInfo(ParsedInstrumentation i,
+ @PackageManager.ComponentInfoFlags int flags) {
+ if (i == null) return null;
+
+ InstrumentationInfo ii = new InstrumentationInfo();
+ assignSharedFieldsForPackageItemInfo(ii, i);
+ ii.targetPackage = i.getTargetPackage();
+ ii.targetProcesses = i.getTargetProcesses();
+ ii.handleProfiling = i.handleProfiling;
+ ii.functionalTest = i.functionalTest;
+
+ ii.sourceDir = i.sourceDir;
+ ii.publicSourceDir = i.publicSourceDir;
+ ii.splitNames = i.splitNames;
+ ii.splitSourceDirs = i.splitSourceDirs;
+ ii.splitPublicSourceDirs = i.splitPublicSourceDirs;
+ ii.splitDependencies = i.splitDependencies;
+ ii.dataDir = i.dataDir;
+ ii.deviceProtectedDataDir = i.deviceProtectedDataDir;
+ ii.credentialProtectedDataDir = i.credentialProtectedDataDir;
+ ii.primaryCpuAbi = i.primaryCpuAbi;
+ ii.secondaryCpuAbi = i.secondaryCpuAbi;
+ ii.nativeLibraryDir = i.nativeLibraryDir;
+ ii.secondaryNativeLibraryDir = i.secondaryNativeLibraryDir;
+
+ if ((flags & PackageManager.GET_META_DATA) == 0) {
+ return ii;
+ }
+ ii.metaData = i.metaData;
+ return ii;
+ }
+
+ public static PermissionInfo generatePermissionInfo(ParsedPermission p,
+ @PackageManager.ComponentInfoFlags int flags) {
+ if (p == null) return null;
+
+ PermissionInfo pi = new PermissionInfo(p.backgroundPermission);
+ assignSharedFieldsForPackageItemInfo(pi, p);
+ pi.group = p.getGroup();
+ pi.requestRes = p.requestRes;
+ pi.protectionLevel = p.protectionLevel;
+ pi.descriptionRes = p.descriptionRes;
+ pi.flags = p.flags;
+
+ if ((flags & PackageManager.GET_META_DATA) == 0) {
+ return pi;
+ }
+ pi.metaData = p.metaData;
+ return pi;
+ }
+
+ public static PermissionGroupInfo generatePermissionGroupInfo(ParsedPermissionGroup pg,
+ @PackageManager.ComponentInfoFlags int flags) {
+ if (pg == null) return null;
+
+ PermissionGroupInfo pgi = new PermissionGroupInfo(
+ pg.requestDetailResourceId,
+ pg.backgroundRequestResourceId,
+ pg.backgroundRequestDetailResourceId
+ );
+ assignSharedFieldsForPackageItemInfo(pgi, pg);
+ pgi.priority = pg.priority;
+ pgi.requestRes = pg.requestRes;
+ pgi.flags = pg.flags;
+
+ if ((flags & PackageManager.GET_META_DATA) == 0) {
+ return pgi;
+ }
+ pgi.metaData = pg.metaData;
+ return pgi;
+ }
+
+ private static boolean copyNeeded(@PackageManager.ComponentInfoFlags int flags,
+ AndroidPackage pkg, PackageUserState state, Bundle metaData, int userId) {
+ if (userId != UserHandle.USER_SYSTEM) {
+ // We always need to copy for other users, since we need
+ // to fix up the uid.
+ return true;
+ }
+ if (state.enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
+ boolean enabled = state.enabled == PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
+ if (pkg.isEnabled() != enabled) {
+ return true;
+ }
+ }
+ boolean suspended = (pkg.getFlags() & FLAG_SUSPENDED) != 0;
+ if (state.suspended != suspended) {
+ return true;
+ }
+ if (!state.installed || state.hidden) {
+ return true;
+ }
+ if (state.stopped) {
+ return true;
+ }
+ if (state.instantApp != pkg.isInstantApp()) {
+ return true;
+ }
+ if ((flags & PackageManager.GET_META_DATA) != 0
+ && (metaData != null || pkg.getAppMetaData() != null)) {
+ return true;
+ }
+ if ((flags & PackageManager.GET_SHARED_LIBRARY_FILES) != 0
+ && pkg.getUsesLibraryFiles() != null) {
+ return true;
+ }
+ if ((flags & PackageManager.GET_SHARED_LIBRARY_FILES) != 0
+ && pkg.getUsesLibraryInfos() != null) {
+ return true;
+ }
+ return pkg.getStaticSharedLibName() != null;
+ }
+
+ private static void updateApplicationInfo(ApplicationInfo ai,
+ @PackageManager.ApplicationInfoFlags int flags,
+ PackageUserState state) {
+ // CompatibilityMode is global state.
+ if (!PackageParser.sCompatibilityModeEnabled) {
+ ai.disableCompatibilityMode();
+ }
+ if (state.installed) {
+ ai.flags |= ApplicationInfo.FLAG_INSTALLED;
+ } else {
+ ai.flags &= ~ApplicationInfo.FLAG_INSTALLED;
+ }
+ if (state.suspended) {
+ ai.flags |= ApplicationInfo.FLAG_SUSPENDED;
+ } else {
+ ai.flags &= ~ApplicationInfo.FLAG_SUSPENDED;
+ }
+ if (state.instantApp) {
+ ai.privateFlags |= ApplicationInfo.PRIVATE_FLAG_INSTANT;
+ } else {
+ ai.privateFlags &= ~ApplicationInfo.PRIVATE_FLAG_INSTANT;
+ }
+ if (state.virtualPreload) {
+ ai.privateFlags |= ApplicationInfo.PRIVATE_FLAG_VIRTUAL_PRELOAD;
+ } else {
+ ai.privateFlags &= ~ApplicationInfo.PRIVATE_FLAG_VIRTUAL_PRELOAD;
+ }
+ if (state.hidden) {
+ ai.privateFlags |= ApplicationInfo.PRIVATE_FLAG_HIDDEN;
+ } else {
+ ai.privateFlags &= ~ApplicationInfo.PRIVATE_FLAG_HIDDEN;
+ }
+ if (state.enabled == PackageManager.COMPONENT_ENABLED_STATE_ENABLED) {
+ ai.enabled = true;
+ } else if (state.enabled == PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED) {
+ ai.enabled = (flags & PackageManager.GET_DISABLED_UNTIL_USED_COMPONENTS) != 0;
+ } else if (state.enabled == PackageManager.COMPONENT_ENABLED_STATE_DISABLED
+ || state.enabled == PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER) {
+ ai.enabled = false;
+ }
+ ai.enabledSetting = state.enabled;
+ if (ai.category == ApplicationInfo.CATEGORY_UNDEFINED) {
+ ai.category = state.categoryHint;
+ }
+ if (ai.category == ApplicationInfo.CATEGORY_UNDEFINED) {
+ ai.category = FallbackCategoryProvider.getFallbackCategory(ai.packageName);
+ }
+ ai.seInfoUser = SELinuxUtil.assignSeinfoUser(state);
+ ai.resourceDirs = state.overlayPaths;
+ ai.icon = (PackageParser.sUseRoundIcon && ai.roundIconRes != 0)
+ ? ai.roundIconRes : ai.iconRes;
+ }
+
+ private static void assignSharedFieldsForPackageItemInfo(PackageItemInfo packageItemInfo,
+ ComponentParseUtils.ParsedComponent parsedComponent) {
+ packageItemInfo.banner = parsedComponent.banner;
+ packageItemInfo.icon = parsedComponent.icon;
+ packageItemInfo.labelRes = parsedComponent.labelRes;
+ packageItemInfo.logo = parsedComponent.logo;
+ packageItemInfo.name = parsedComponent.className;
+ packageItemInfo.nonLocalizedLabel = parsedComponent.nonLocalizedLabel;
+ packageItemInfo.packageName = parsedComponent.getPackageName();
+ }
+
+ private static void assignSharedFieldsForComponentInfo(ComponentInfo componentInfo,
+ ComponentParseUtils.ParsedComponent parsedComponent) {
+ assignSharedFieldsForPackageItemInfo(componentInfo, parsedComponent);
+ componentInfo.descriptionRes = parsedComponent.descriptionRes;
+ componentInfo.directBootAware = parsedComponent.directBootAware;
+ componentInfo.enabled = parsedComponent.enabled;
+ componentInfo.splitName = parsedComponent.getSplitName();
+ }
+
+}
diff --git a/core/java/android/content/pm/parsing/ParsedPackage.java b/core/java/android/content/pm/parsing/ParsedPackage.java
new file mode 100644
index 000000000000..05cf586522f2
--- /dev/null
+++ b/core/java/android/content/pm/parsing/ParsedPackage.java
@@ -0,0 +1,155 @@
+/*
+ * Copyright (C) 2019 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 android.content.pm.parsing;
+
+import android.content.pm.PackageParser;
+
+/**
+ * Methods used for mutation after direct package parsing, mostly done inside
+ * {@link com.android.server.pm.PackageManagerService}.
+ *
+ * Java disallows defining this as an inner interface, so this must be a separate file.
+ *
+ * @hide
+ */
+public interface ParsedPackage extends AndroidPackage {
+
+ AndroidPackage hideAsFinal();
+
+ ParsedPackage addUsesLibrary(int index, String libraryName);
+
+ ParsedPackage addUsesOptionalLibrary(int index, String libraryName);
+
+ ParsedPackage capPermissionPriorities();
+
+ ParsedPackage clearAdoptPermissions();
+
+ ParsedPackage clearOriginalPackages();
+
+ ParsedPackage clearProtectedBroadcasts();
+
+ /**
+ * TODO(b/135203078): Use non-AppInfo method
+ * @deprecated use {@link #setCodePath(String)}
+ */
+ @Deprecated
+ ParsedPackage setApplicationInfoCodePath(String applicationInfoCodePath);
+
+ /**
+ * TODO(b/135203078): Use non-AppInfo method
+ * @deprecated use {@link #setCodePath(String)}
+ */
+ @Deprecated
+ ParsedPackage setApplicationInfoResourcePath(String applicationInfoResourcePath);
+
+ ParsedPackage setBaseCodePath(String baseCodePath);
+
+ ParsedPackage setCodePath(String codePath);
+
+ ParsedPackage setCpuAbiOverride(String cpuAbiOverride);
+
+ ParsedPackage setNativeLibraryDir(String nativeLibraryDir);
+
+ ParsedPackage setNativeLibraryRootDir(String nativeLibraryRootDir);
+
+ ParsedPackage setPackageName(String packageName);
+
+ ParsedPackage setPrimaryCpuAbi(String primaryCpuAbi);
+
+ ParsedPackage setProcessName(String processName);
+
+ ParsedPackage setRealPackage(String realPackage);
+
+ ParsedPackage setSecondaryCpuAbi(String secondaryCpuAbi);
+
+ ParsedPackage setSigningDetails(PackageParser.SigningDetails signingDetails);
+
+ ParsedPackage setSplitCodePaths(String[] splitCodePaths);
+
+ ParsedPackage initForUser(int userId);
+
+ ParsedPackage setNativeLibraryRootRequiresIsa(boolean nativeLibraryRootRequiresIsa);
+
+ ParsedPackage setAllComponentsDirectBootAware(boolean allComponentsDirectBootAware);
+
+ ParsedPackage setFactoryTest(boolean factoryTest);
+
+ ParsedPackage markNotActivitiesAsNotExportedIfSingleUser();
+
+ ParsedPackage setOdm(boolean odm);
+
+ ParsedPackage setOem(boolean oem);
+
+ ParsedPackage setPrivileged(boolean privileged);
+
+ ParsedPackage setProduct(boolean product);
+
+ ParsedPackage setSignedWithPlatformKey(boolean signedWithPlatformKey);
+
+ ParsedPackage setSystem(boolean system);
+
+ ParsedPackage setSystemExt(boolean systemExt);
+
+ ParsedPackage setUpdatedSystemApp(boolean updatedSystemApp);
+
+ ParsedPackage setVendor(boolean vendor);
+
+ ParsedPackage removePermission(int index);
+
+ ParsedPackage removeUsesLibrary(String libraryName);
+
+ ParsedPackage removeUsesOptionalLibrary(String libraryName);
+
+ ParsedPackage setApplicationInfoBaseResourcePath(String applicationInfoBaseResourcePath);
+
+ ParsedPackage setApplicationInfoSplitResourcePaths(
+ String[] applicationInfoSplitResourcePaths);
+
+ ParsedPackage setApplicationVolumeUuid(String applicationVolumeUuid);
+
+ ParsedPackage setCoreApp(boolean coreApp);
+
+ ParsedPackage setIsStub(boolean isStub);
+
+ // TODO(b/135203078): Remove entirely
+ ParsedPackage setPackageSettingCallback(PackageSettingCallback packageSettingCallback);
+
+ ParsedPackage setRestrictUpdateHash(byte[] restrictUpdateHash);
+
+ ParsedPackage setSeInfo(String seInfo);
+
+ ParsedPackage setSeInfoUser(String seInfoUser);
+
+ ParsedPackage setSecondaryNativeLibraryDir(String secondaryNativeLibraryDir);
+
+ ParsedPackage setUid(int uid);
+
+ ParsedPackage setVersionCode(int versionCode);
+
+ ParsedPackage setVersionCodeMajor(int versionCodeMajor);
+
+ // TODO(b/135203078): Move logic earlier in parse chain so nothing needs to be reverted
+ ParsedPackage setDefaultToDeviceProtectedStorage(boolean defaultToDeviceProtectedStorage);
+
+ ParsedPackage setDirectBootAware(boolean directBootAware);
+
+ ParsedPackage setPersistent(boolean persistent);
+
+ interface PackageSettingCallback {
+ default void setAndroidPackage(AndroidPackage pkg){}
+ }
+}
diff --git a/core/java/android/content/pm/parsing/ParsingPackage.java b/core/java/android/content/pm/parsing/ParsingPackage.java
new file mode 100644
index 000000000000..43c1f6e335b0
--- /dev/null
+++ b/core/java/android/content/pm/parsing/ParsingPackage.java
@@ -0,0 +1,327 @@
+/*
+ * Copyright (C) 2019 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 android.content.pm.parsing;
+
+import android.annotation.Nullable;
+import android.content.Intent;
+import android.content.pm.ConfigurationInfo;
+import android.content.pm.FeatureGroupInfo;
+import android.content.pm.FeatureInfo;
+import android.content.pm.PackageParser;
+import android.content.pm.parsing.ComponentParseUtils.ParsedActivity;
+import android.content.pm.parsing.ComponentParseUtils.ParsedActivityIntentInfo;
+import android.content.pm.parsing.ComponentParseUtils.ParsedInstrumentation;
+import android.content.pm.parsing.ComponentParseUtils.ParsedPermission;
+import android.content.pm.parsing.ComponentParseUtils.ParsedPermissionGroup;
+import android.content.pm.parsing.ComponentParseUtils.ParsedProvider;
+import android.content.pm.parsing.ComponentParseUtils.ParsedService;
+import android.os.Bundle;
+import android.util.ArraySet;
+import android.util.SparseArray;
+
+import java.security.PublicKey;
+
+/**
+ * Methods used for mutation during direct package parsing.
+ *
+ * Java disallows defining this as an inner interface, so this must be a separate file.
+ *
+ * @hide
+ */
+public interface ParsingPackage extends AndroidPackage {
+
+ ParsingPackage addActivity(ParsedActivity parsedActivity);
+
+ ParsingPackage addAdoptPermission(String adoptPermission);
+
+ ParsingPackage addConfigPreference(ConfigurationInfo configPreference);
+
+ ParsingPackage addFeatureGroup(FeatureGroupInfo featureGroup);
+
+ ParsingPackage addImplicitPermission(String permission);
+
+ ParsingPackage addInstrumentation(ParsedInstrumentation instrumentation);
+
+ ParsingPackage addKeySet(String keySetName, PublicKey publicKey);
+
+ ParsingPackage addLibraryName(String libraryName);
+
+ ParsingPackage addOriginalPackage(String originalPackage);
+
+ ParsingPackage addPermission(ParsedPermission permission);
+
+ ParsingPackage addPermissionGroup(ParsedPermissionGroup permissionGroup);
+
+ ParsingPackage addPreferredActivityFilter(ParsedActivityIntentInfo activityIntentInfo);
+
+ ParsingPackage addProtectedBroadcast(String protectedBroadcast);
+
+ ParsingPackage addProvider(ParsedProvider parsedProvider);
+
+ ParsingPackage addReceiver(ParsedActivity parsedReceiver);
+
+ ParsingPackage addReqFeature(FeatureInfo reqFeature);
+
+ ParsingPackage addRequestedPermission(String permission);
+
+ ParsingPackage addService(ParsedService parsedService);
+
+ ParsingPackage addUsesLibrary(String libraryName);
+
+ ParsingPackage addUsesOptionalLibrary(String libraryName);
+
+ ParsingPackage addUsesStaticLibrary(String libraryName);
+
+ ParsingPackage addUsesStaticLibraryCertDigests(String[] certSha256Digests);
+
+ ParsingPackage addUsesStaticLibraryVersion(long version);
+
+ ParsingPackage addQueriesIntent(Intent intent);
+
+ ParsingPackage addQueriesPackage(String packageName);
+
+ ParsingPackage asSplit(
+ String[] splitNames,
+ String[] splitCodePaths,
+ int[] splitRevisionCodes,
+ @Nullable SparseArray<int[]> splitDependencies
+ );
+
+ ParsingPackage setAppMetaData(Bundle appMetaData);
+
+ ParsingPackage setForceQueryable(boolean forceQueryable);
+
+ ParsingPackage setMaxAspectRatio(float maxAspectRatio);
+
+ ParsingPackage setMinAspectRatio(float minAspectRatio);
+
+ ParsingPackage setName(String name);
+
+ ParsingPackage setPermission(String permission);
+
+ ParsingPackage setProcessName(String processName);
+
+ ParsingPackage setSharedUserId(String sharedUserId);
+
+ ParsingPackage setStaticSharedLibName(String staticSharedLibName);
+
+ ParsingPackage setTaskAffinity(String taskAffinity);
+
+ ParsingPackage setTargetSdkVersion(int targetSdkVersion);
+
+ ParsingPackage setUiOptions(int uiOptions);
+
+ ParsingPackage setBaseHardwareAccelerated(boolean baseHardwareAccelerated);
+
+ ParsingPackage setActivitiesResizeModeResizeable(boolean resizeable);
+
+ ParsingPackage setActivitiesResizeModeResizeableViaSdkVersion(boolean resizeableViaSdkVersion);
+
+ ParsingPackage setAllowAudioPlaybackCapture(boolean allowAudioPlaybackCapture);
+
+ ParsingPackage setAllowBackup(boolean allowBackup);
+
+ ParsingPackage setAllowClearUserData(boolean allowClearUserData);
+
+ ParsingPackage setAllowClearUserDataOnFailedRestore(boolean allowClearUserDataOnFailedRestore);
+
+ ParsingPackage setAllowTaskReparenting(boolean allowTaskReparenting);
+
+ ParsingPackage setIsOverlay(boolean isOverlay);
+
+ ParsingPackage setBackupInForeground(boolean backupInForeground);
+
+ ParsingPackage setCantSaveState(boolean cantSaveState);
+
+ ParsingPackage setDebuggable(boolean debuggable);
+
+ ParsingPackage setDefaultToDeviceProtectedStorage(boolean defaultToDeviceProtectedStorage);
+
+ ParsingPackage setDirectBootAware(boolean directBootAware);
+
+ ParsingPackage setExternalStorage(boolean externalStorage);
+
+ ParsingPackage setExtractNativeLibs(boolean extractNativeLibs);
+
+ ParsingPackage setFullBackupOnly(boolean fullBackupOnly);
+
+ ParsingPackage setHasCode(boolean hasCode);
+
+ ParsingPackage setHasFragileUserData(boolean hasFragileUserData);
+
+ ParsingPackage setIsGame(boolean isGame);
+
+ ParsingPackage setIsolatedSplitLoading(boolean isolatedSplitLoading);
+
+ ParsingPackage setKillAfterRestore(boolean killAfterRestore);
+
+ ParsingPackage setLargeHeap(boolean largeHeap);
+
+ ParsingPackage setMultiArch(boolean multiArch);
+
+ ParsingPackage setPartiallyDirectBootAware(boolean partiallyDirectBootAware);
+
+ ParsingPackage setPersistent(boolean persistent);
+
+ ParsingPackage setProfileableByShell(boolean profileableByShell);
+
+ ParsingPackage setRequestLegacyExternalStorage(boolean requestLegacyExternalStorage);
+
+ ParsingPackage setRestoreAnyVersion(boolean restoreAnyVersion);
+
+ ParsingPackage setSplitHasCode(int splitIndex, boolean splitHasCode);
+
+ ParsingPackage setStaticSharedLibrary(boolean staticSharedLibrary);
+
+ ParsingPackage setSupportsRtl(boolean supportsRtl);
+
+ ParsingPackage setTestOnly(boolean testOnly);
+
+ ParsingPackage setUseEmbeddedDex(boolean useEmbeddedDex);
+
+ ParsingPackage setUsesCleartextTraffic(boolean usesCleartextTraffic);
+
+ ParsingPackage setUsesNonSdkApi(boolean usesNonSdkApi);
+
+ ParsingPackage setVisibleToInstantApps(boolean visibleToInstantApps);
+
+ ParsingPackage setVmSafeMode(boolean vmSafeMode);
+
+ ParsingPackage removeUsesOptionalLibrary(String libraryName);
+
+ ParsingPackage setAnyDensity(int anyDensity);
+
+ ParsingPackage setAppComponentFactory(String appComponentFactory);
+
+ ParsingPackage setApplicationVolumeUuid(String applicationVolumeUuid);
+
+ ParsingPackage setBackupAgentName(String backupAgentName);
+
+ ParsingPackage setBanner(int banner);
+
+ ParsingPackage setCategory(int category);
+
+ ParsingPackage setClassLoaderName(String classLoaderName);
+
+ ParsingPackage setClassName(String className);
+
+ ParsingPackage setCodePath(String codePath);
+
+ ParsingPackage setCompatibleWidthLimitDp(int compatibleWidthLimitDp);
+
+ ParsingPackage setDescriptionRes(int descriptionRes);
+
+ ParsingPackage setEnabled(boolean enabled);
+
+ ParsingPackage setFullBackupContent(int fullBackupContent);
+
+ ParsingPackage setHasDomainUrls(boolean hasDomainUrls);
+
+ ParsingPackage setIcon(int icon);
+
+ ParsingPackage setIconRes(int iconRes);
+
+ ParsingPackage setInstallLocation(int installLocation);
+
+ ParsingPackage setLabelRes(int labelRes);
+
+ ParsingPackage setLargestWidthLimitDp(int largestWidthLimitDp);
+
+ ParsingPackage setLogo(int logo);
+
+ ParsingPackage setManageSpaceActivityName(String manageSpaceActivityName);
+
+ ParsingPackage setMinSdkVersion(int minSdkVersion);
+
+ ParsingPackage setNetworkSecurityConfigRes(int networkSecurityConfigRes);
+
+ ParsingPackage setNonLocalizedLabel(CharSequence nonLocalizedLabel);
+
+ ParsingPackage setOverlayCategory(String overlayCategory);
+
+ ParsingPackage setOverlayIsStatic(boolean overlayIsStatic);
+
+ ParsingPackage setOverlayPriority(int overlayPriority);
+
+ ParsingPackage setOverlayTarget(String overlayTarget);
+
+ ParsingPackage setOverlayTargetName(String overlayTargetName);
+
+ ParsingPackage setRealPackage(String realPackage);
+
+ ParsingPackage setRequiredAccountType(String requiredAccountType);
+
+ ParsingPackage setRequiredForAllUsers(boolean requiredForAllUsers);
+
+ ParsingPackage setRequiresSmallestWidthDp(int requiresSmallestWidthDp);
+
+ ParsingPackage setResizeable(int resizeable);
+
+ ParsingPackage setRestrictUpdateHash(byte[] restrictUpdateHash);
+
+ ParsingPackage setRestrictedAccountType(String restrictedAccountType);
+
+ ParsingPackage setRoundIconRes(int roundIconRes);
+
+ ParsingPackage setSharedUserLabel(int sharedUserLabel);
+
+ ParsingPackage setSigningDetails(PackageParser.SigningDetails signingDetails);
+
+ ParsingPackage setSplitClassLoaderName(int splitIndex, String classLoaderName);
+
+ ParsingPackage setStaticSharedLibVersion(long staticSharedLibVersion);
+
+ ParsingPackage setSupportsLargeScreens(int supportsLargeScreens);
+
+ ParsingPackage setSupportsNormalScreens(int supportsNormalScreens);
+
+ ParsingPackage setSupportsSmallScreens(int supportsSmallScreens);
+
+ ParsingPackage setSupportsXLargeScreens(int supportsXLargeScreens);
+
+ ParsingPackage setTargetSandboxVersion(int targetSandboxVersion);
+
+ ParsingPackage setTheme(int theme);
+
+ ParsingPackage setUpgradeKeySets(ArraySet<String> upgradeKeySets);
+
+ ParsingPackage setUse32BitAbi(boolean use32BitAbi);
+
+ ParsingPackage setVolumeUuid(String volumeUuid);
+
+ ParsingPackage setZygotePreloadName(String zygotePreloadName);
+
+ ParsingPackage sortActivities();
+
+ ParsingPackage sortReceivers();
+
+ ParsingPackage sortServices();
+
+ ParsedPackage hideAsParsed();
+
+ ParsingPackage setBaseRevisionCode(int baseRevisionCode);
+
+ ParsingPackage setPreferredOrder(int preferredOrder);
+
+ ParsingPackage setVersionName(String versionName);
+
+ ParsingPackage setCompileSdkVersion(int compileSdkVersion);
+
+ ParsingPackage setCompileSdkVersionCodename(String compileSdkVersionCodename);
+
+ boolean usesCompatibilityMode();
+}
diff --git a/core/java/android/content/pm/AndroidHidlUpdater.java b/core/java/android/content/pm/parsing/library/AndroidHidlUpdater.java
index d0657e5eb8ec..81b4bc574197 100644
--- a/core/java/android/content/pm/AndroidHidlUpdater.java
+++ b/core/java/android/content/pm/parsing/library/AndroidHidlUpdater.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2018 The Android Open Source Project
+ * Copyright (C) 2019 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.
@@ -13,12 +13,12 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package android.content.pm;
+package android.content.pm.parsing.library;
-import static android.content.pm.SharedLibraryNames.ANDROID_HIDL_BASE;
-import static android.content.pm.SharedLibraryNames.ANDROID_HIDL_MANAGER;
+import static android.content.pm.parsing.library.SharedLibraryNames.ANDROID_HIDL_BASE;
+import static android.content.pm.parsing.library.SharedLibraryNames.ANDROID_HIDL_MANAGER;
-import android.content.pm.PackageParser.Package;
+import android.content.pm.parsing.ParsedPackage;
import android.os.Build;
import com.android.internal.annotations.VisibleForTesting;
@@ -33,20 +33,18 @@ import com.android.internal.annotations.VisibleForTesting;
public class AndroidHidlUpdater extends PackageSharedLibraryUpdater {
@Override
- public void updatePackage(Package pkg) {
- ApplicationInfo info = pkg.applicationInfo;
-
+ public void updatePackage(ParsedPackage parsedPackage) {
// This was the default <= P and is maintained for backwards compatibility.
- boolean isLegacy = info.targetSdkVersion <= Build.VERSION_CODES.P;
+ boolean isLegacy = parsedPackage.getTargetSdkVersion() <= Build.VERSION_CODES.P;
// Only system apps use these libraries
- boolean isSystem = info.isSystemApp() || info.isUpdatedSystemApp();
+ boolean isSystem = parsedPackage.isSystemApp() || parsedPackage.isUpdatedSystemApp();
if (isLegacy && isSystem) {
- prefixRequiredLibrary(pkg, ANDROID_HIDL_BASE);
- prefixRequiredLibrary(pkg, ANDROID_HIDL_MANAGER);
+ prefixRequiredLibrary(parsedPackage, ANDROID_HIDL_BASE);
+ prefixRequiredLibrary(parsedPackage, ANDROID_HIDL_MANAGER);
} else {
- removeLibrary(pkg, ANDROID_HIDL_BASE);
- removeLibrary(pkg, ANDROID_HIDL_MANAGER);
+ removeLibrary(parsedPackage, ANDROID_HIDL_BASE);
+ removeLibrary(parsedPackage, ANDROID_HIDL_MANAGER);
}
}
}
diff --git a/core/java/android/content/pm/AndroidTestBaseUpdater.java b/core/java/android/content/pm/parsing/library/AndroidTestBaseUpdater.java
index da1a693b13c3..25c309931554 100644
--- a/core/java/android/content/pm/AndroidTestBaseUpdater.java
+++ b/core/java/android/content/pm/parsing/library/AndroidTestBaseUpdater.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2018 The Android Open Source Project
+ * Copyright (C) 2019 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.
@@ -13,12 +13,13 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package android.content.pm;
+package android.content.pm.parsing.library;
-import static android.content.pm.SharedLibraryNames.ANDROID_TEST_BASE;
-import static android.content.pm.SharedLibraryNames.ANDROID_TEST_RUNNER;
+import static android.content.pm.parsing.library.SharedLibraryNames.ANDROID_TEST_BASE;
+import static android.content.pm.parsing.library.SharedLibraryNames.ANDROID_TEST_RUNNER;
-import android.content.pm.PackageParser.Package;
+import android.content.pm.parsing.AndroidPackage;
+import android.content.pm.parsing.ParsedPackage;
import android.os.Build;
import com.android.internal.annotations.VisibleForTesting;
@@ -38,23 +39,22 @@ import com.android.internal.annotations.VisibleForTesting;
@VisibleForTesting
public class AndroidTestBaseUpdater extends PackageSharedLibraryUpdater {
- private static boolean apkTargetsApiLevelLessThanOrEqualToQ(Package pkg) {
- int targetSdkVersion = pkg.applicationInfo.targetSdkVersion;
- return targetSdkVersion <= Build.VERSION_CODES.Q;
+ private static boolean apkTargetsApiLevelLessThanOrEqualToQ(AndroidPackage pkg) {
+ return pkg.getTargetSdkVersion() <= Build.VERSION_CODES.Q;
}
@Override
- public void updatePackage(Package pkg) {
+ public void updatePackage(ParsedPackage parsedPackage) {
// Packages targeted at <= Q expect the classes in the android.test.base library
// to be accessible so this maintains backward compatibility by adding the
// android.test.base library to those packages.
- if (apkTargetsApiLevelLessThanOrEqualToQ(pkg)) {
- prefixRequiredLibrary(pkg, ANDROID_TEST_BASE);
+ if (apkTargetsApiLevelLessThanOrEqualToQ(parsedPackage)) {
+ prefixRequiredLibrary(parsedPackage, ANDROID_TEST_BASE);
} else {
// If a package already depends on android.test.runner then add a dependency on
// android.test.base because android.test.runner depends on classes from the
// android.test.base library.
- prefixImplicitDependency(pkg, ANDROID_TEST_RUNNER, ANDROID_TEST_BASE);
+ prefixImplicitDependency(parsedPackage, ANDROID_TEST_RUNNER, ANDROID_TEST_BASE);
}
}
}
diff --git a/core/java/android/content/pm/OrgApacheHttpLegacyUpdater.java b/core/java/android/content/pm/parsing/library/OrgApacheHttpLegacyUpdater.java
index 707443b19679..613a06b636e9 100644
--- a/core/java/android/content/pm/OrgApacheHttpLegacyUpdater.java
+++ b/core/java/android/content/pm/parsing/library/OrgApacheHttpLegacyUpdater.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2018 The Android Open Source Project
+ * Copyright (C) 2019 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.
@@ -13,11 +13,12 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package android.content.pm;
+package android.content.pm.parsing.library;
-import static android.content.pm.SharedLibraryNames.ORG_APACHE_HTTP_LEGACY;
+import static android.content.pm.parsing.library.SharedLibraryNames.ORG_APACHE_HTTP_LEGACY;
-import android.content.pm.PackageParser.Package;
+import android.content.pm.parsing.AndroidPackage;
+import android.content.pm.parsing.ParsedPackage;
import android.os.Build;
import com.android.internal.annotations.VisibleForTesting;
@@ -31,18 +32,17 @@ import com.android.internal.annotations.VisibleForTesting;
@VisibleForTesting
public class OrgApacheHttpLegacyUpdater extends PackageSharedLibraryUpdater {
- private static boolean apkTargetsApiLevelLessThanOrEqualToOMR1(Package pkg) {
- int targetSdkVersion = pkg.applicationInfo.targetSdkVersion;
- return targetSdkVersion < Build.VERSION_CODES.P;
+ private static boolean apkTargetsApiLevelLessThanOrEqualToOMR1(AndroidPackage pkg) {
+ return pkg.getTargetSdkVersion() < Build.VERSION_CODES.P;
}
@Override
- public void updatePackage(Package pkg) {
+ public void updatePackage(ParsedPackage parsedPackage) {
// Packages targeted at <= O_MR1 expect the classes in the org.apache.http.legacy library
// to be accessible so this maintains backward compatibility by adding the
// org.apache.http.legacy library to those packages.
- if (apkTargetsApiLevelLessThanOrEqualToOMR1(pkg)) {
- prefixRequiredLibrary(pkg, ORG_APACHE_HTTP_LEGACY);
+ if (apkTargetsApiLevelLessThanOrEqualToOMR1(parsedPackage)) {
+ prefixRequiredLibrary(parsedPackage, ORG_APACHE_HTTP_LEGACY);
}
}
}
diff --git a/core/java/android/content/pm/PackageBackwardCompatibility.java b/core/java/android/content/pm/parsing/library/PackageBackwardCompatibility.java
index 4331bd4ac4d4..1220fc497b04 100644
--- a/core/java/android/content/pm/PackageBackwardCompatibility.java
+++ b/core/java/android/content/pm/parsing/library/PackageBackwardCompatibility.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2017 The Android Open Source Project
+ * Copyright (C) 2019 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.
@@ -14,14 +14,14 @@
* limitations under the License.
*/
-package android.content.pm;
+package android.content.pm.parsing.library;
-import static android.content.pm.SharedLibraryNames.ANDROID_TEST_BASE;
-import static android.content.pm.SharedLibraryNames.ANDROID_TEST_MOCK;
-import static android.content.pm.SharedLibraryNames.ANDROID_TEST_RUNNER;
-import static android.content.pm.SharedLibraryNames.ORG_APACHE_HTTP_LEGACY;
+import static android.content.pm.parsing.library.SharedLibraryNames.ANDROID_TEST_BASE;
+import static android.content.pm.parsing.library.SharedLibraryNames.ANDROID_TEST_MOCK;
+import static android.content.pm.parsing.library.SharedLibraryNames.ANDROID_TEST_RUNNER;
+import static android.content.pm.parsing.library.SharedLibraryNames.ORG_APACHE_HTTP_LEGACY;
-import android.content.pm.PackageParser.Package;
+import android.content.pm.parsing.ParsedPackage;
import android.util.Log;
import com.android.internal.annotations.VisibleForTesting;
@@ -31,7 +31,7 @@ import java.util.List;
import java.util.function.Supplier;
/**
- * Modifies {@link Package} in order to maintain backwards compatibility.
+ * Modifies {@link ParsedPackage} in order to maintain backwards compatibility.
*
* @hide
*/
@@ -60,7 +60,7 @@ public class PackageBackwardCompatibility extends PackageSharedLibraryUpdater {
// will remove any references to org.apache.http.library from the package so that it does
// not try and load the library when it is on the bootclasspath.
boolean bootClassPathContainsATB = !addOptionalUpdater(packageUpdaters,
- "android.content.pm.AndroidTestBaseUpdater",
+ "android.content.pm.parsing.library.AndroidTestBaseUpdater",
RemoveUnnecessaryAndroidTestBaseLibrary::new);
PackageSharedLibraryUpdater[] updaterArray = packageUpdaters
@@ -123,20 +123,20 @@ public class PackageBackwardCompatibility extends PackageSharedLibraryUpdater {
}
/**
- * Modify the shared libraries in the supplied {@link Package} to maintain backwards
+ * Modify the shared libraries in the supplied {@link ParsedPackage} to maintain backwards
* compatibility.
*
- * @param pkg the {@link Package} to modify.
+ * @param parsedPackage the {@link ParsedPackage} to modify.
*/
@VisibleForTesting
- public static void modifySharedLibraries(Package pkg) {
- INSTANCE.updatePackage(pkg);
+ public static void modifySharedLibraries(ParsedPackage parsedPackage) {
+ INSTANCE.updatePackage(parsedPackage);
}
@Override
- public void updatePackage(Package pkg) {
+ public void updatePackage(ParsedPackage parsedPackage) {
for (PackageSharedLibraryUpdater packageUpdater : mPackageUpdaters) {
- packageUpdater.updatePackage(pkg);
+ packageUpdater.updatePackage(parsedPackage);
}
}
@@ -161,10 +161,10 @@ public class PackageBackwardCompatibility extends PackageSharedLibraryUpdater {
public static class AndroidTestRunnerSplitUpdater extends PackageSharedLibraryUpdater {
@Override
- public void updatePackage(Package pkg) {
+ public void updatePackage(ParsedPackage parsedPackage) {
// android.test.runner has a dependency on android.test.mock so if android.test.runner
// is present but android.test.mock is not then add android.test.mock.
- prefixImplicitDependency(pkg, ANDROID_TEST_RUNNER, ANDROID_TEST_MOCK);
+ prefixImplicitDependency(parsedPackage, ANDROID_TEST_RUNNER, ANDROID_TEST_MOCK);
}
}
@@ -177,8 +177,8 @@ public class PackageBackwardCompatibility extends PackageSharedLibraryUpdater {
extends PackageSharedLibraryUpdater {
@Override
- public void updatePackage(Package pkg) {
- removeLibrary(pkg, ORG_APACHE_HTTP_LEGACY);
+ public void updatePackage(ParsedPackage parsedPackage) {
+ removeLibrary(parsedPackage, ORG_APACHE_HTTP_LEGACY);
}
}
@@ -192,8 +192,8 @@ public class PackageBackwardCompatibility extends PackageSharedLibraryUpdater {
extends PackageSharedLibraryUpdater {
@Override
- public void updatePackage(Package pkg) {
- removeLibrary(pkg, ANDROID_TEST_BASE);
+ public void updatePackage(ParsedPackage parsedPackage) {
+ removeLibrary(parsedPackage, ANDROID_TEST_BASE);
}
}
}
diff --git a/core/java/android/content/pm/PackageSharedLibraryUpdater.java b/core/java/android/content/pm/parsing/library/PackageSharedLibraryUpdater.java
index 1565d9ce77d4..8b27d140a8f4 100644
--- a/core/java/android/content/pm/PackageSharedLibraryUpdater.java
+++ b/core/java/android/content/pm/parsing/library/PackageSharedLibraryUpdater.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2018 The Android Open Source Project
+ * Copyright (C) 2019 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.
@@ -13,18 +13,20 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package android.content.pm;
+package android.content.pm.parsing.library;
import android.annotation.NonNull;
import android.annotation.Nullable;
+import android.content.pm.parsing.ParsedPackage;
import com.android.internal.annotations.VisibleForTesting;
import com.android.internal.util.ArrayUtils;
import java.util.ArrayList;
+import java.util.List;
/**
- * Base for classes that update a {@link PackageParser.Package}'s shared libraries.
+ * Base for classes that update a {@link ParsedPackage}'s shared libraries.
*
* @hide
*/
@@ -34,14 +36,13 @@ public abstract class PackageSharedLibraryUpdater {
/**
* Update the package's shared libraries.
*
- * @param pkg the package to update.
+ * @param parsedPackage the package to update.
*/
- public abstract void updatePackage(PackageParser.Package pkg);
+ public abstract void updatePackage(ParsedPackage parsedPackage);
- static void removeLibrary(PackageParser.Package pkg, String libraryName) {
- pkg.usesLibraries = ArrayUtils.remove(pkg.usesLibraries, libraryName);
- pkg.usesOptionalLibraries =
- ArrayUtils.remove(pkg.usesOptionalLibraries, libraryName);
+ static void removeLibrary(ParsedPackage parsedPackage, String libraryName) {
+ parsedPackage.removeUsesLibrary(libraryName)
+ .removeUsesOptionalLibrary(libraryName);
}
static @NonNull
@@ -53,8 +54,8 @@ public abstract class PackageSharedLibraryUpdater {
return cur;
}
- private static boolean isLibraryPresent(ArrayList<String> usesLibraries,
- ArrayList<String> usesOptionalLibraries, String apacheHttpLegacy) {
+ private static boolean isLibraryPresent(List<String> usesLibraries,
+ List<String> usesOptionalLibraries, String apacheHttpLegacy) {
return ArrayUtils.contains(usesLibraries, apacheHttpLegacy)
|| ArrayUtils.contains(usesOptionalLibraries, apacheHttpLegacy);
}
@@ -65,37 +66,32 @@ public abstract class PackageSharedLibraryUpdater {
* <p>If the package has an existing dependency on {@code existingLibrary} then prefix it with
* the {@code implicitDependency} if it is not already in the list of libraries.
*
- * @param pkg the {@link PackageParser.Package} to update.
+ * @param parsedPackage the {@link ParsedPackage} to update.
* @param existingLibrary the existing library.
* @param implicitDependency the implicit dependency to add
*/
- void prefixImplicitDependency(PackageParser.Package pkg, String existingLibrary,
+ void prefixImplicitDependency(ParsedPackage parsedPackage, String existingLibrary,
String implicitDependency) {
- ArrayList<String> usesLibraries = pkg.usesLibraries;
- ArrayList<String> usesOptionalLibraries = pkg.usesOptionalLibraries;
+ List<String> usesLibraries = parsedPackage.getUsesLibraries();
+ List<String> usesOptionalLibraries = parsedPackage.getUsesOptionalLibraries();
if (!isLibraryPresent(usesLibraries, usesOptionalLibraries, implicitDependency)) {
if (ArrayUtils.contains(usesLibraries, existingLibrary)) {
- prefix(usesLibraries, implicitDependency);
+ parsedPackage.addUsesLibrary(0, implicitDependency);
} else if (ArrayUtils.contains(usesOptionalLibraries, existingLibrary)) {
- prefix(usesOptionalLibraries, implicitDependency);
+ parsedPackage.addUsesOptionalLibrary(0, implicitDependency);
}
-
- pkg.usesLibraries = usesLibraries;
- pkg.usesOptionalLibraries = usesOptionalLibraries;
}
}
- void prefixRequiredLibrary(PackageParser.Package pkg, String libraryName) {
- ArrayList<String> usesLibraries = pkg.usesLibraries;
- ArrayList<String> usesOptionalLibraries = pkg.usesOptionalLibraries;
+ void prefixRequiredLibrary(ParsedPackage parsedPackage, String libraryName) {
+ List<String> usesLibraries = parsedPackage.getUsesLibraries();
+ List<String> usesOptionalLibraries = parsedPackage.getUsesOptionalLibraries();
boolean alreadyPresent = isLibraryPresent(
usesLibraries, usesOptionalLibraries, libraryName);
if (!alreadyPresent) {
- usesLibraries = prefix(usesLibraries, libraryName);
-
- pkg.usesLibraries = usesLibraries;
+ parsedPackage.addUsesLibrary(0, libraryName);
}
}
}
diff --git a/core/java/android/content/pm/SharedLibraryNames.java b/core/java/android/content/pm/parsing/library/SharedLibraryNames.java
index a607a9ff682b..7b691c06718e 100644
--- a/core/java/android/content/pm/SharedLibraryNames.java
+++ b/core/java/android/content/pm/parsing/library/SharedLibraryNames.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2018 The Android Open Source Project
+ * Copyright (C) 2019 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.
@@ -13,7 +13,7 @@
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-package android.content.pm;
+package android.content.pm.parsing.library;
/**
* A set of shared library names
diff --git a/core/java/com/android/internal/content/NativeLibraryHelper.java b/core/java/com/android/internal/content/NativeLibraryHelper.java
index fee8345d1660..f04a6715e55f 100644
--- a/core/java/com/android/internal/content/NativeLibraryHelper.java
+++ b/core/java/com/android/internal/content/NativeLibraryHelper.java
@@ -28,12 +28,11 @@ import static android.system.OsConstants.S_IXOTH;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageParser;
-import android.content.pm.PackageParser.Package;
import android.content.pm.PackageParser.PackageLite;
import android.content.pm.PackageParser.PackageParserException;
+import android.content.pm.parsing.AndroidPackage;
import android.os.Build;
import android.os.SELinux;
-import android.os.SystemProperties;
import android.system.ErrnoException;
import android.system.Os;
import android.util.Slog;
@@ -88,11 +87,12 @@ public class NativeLibraryHelper {
}
}
- public static Handle create(Package pkg) throws IOException {
- return create(pkg.getAllCodePaths(),
- (pkg.applicationInfo.flags & ApplicationInfo.FLAG_MULTIARCH) != 0,
- (pkg.applicationInfo.flags & ApplicationInfo.FLAG_EXTRACT_NATIVE_LIBS) != 0,
- (pkg.applicationInfo.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0);
+ public static Handle create(AndroidPackage pkg) throws IOException {
+ return create(
+ pkg.makeListAllCodePaths(),
+ (pkg.getFlags() & ApplicationInfo.FLAG_MULTIARCH) != 0,
+ (pkg.getFlags() & ApplicationInfo.FLAG_EXTRACT_NATIVE_LIBS) != 0,
+ (pkg.getFlags() & ApplicationInfo.FLAG_DEBUGGABLE) != 0);
}
public static Handle create(PackageLite lite) throws IOException {
diff --git a/core/java/com/android/internal/util/ArrayUtils.java b/core/java/com/android/internal/util/ArrayUtils.java
index 821022f1f917..bc8019796d22 100644
--- a/core/java/com/android/internal/util/ArrayUtils.java
+++ b/core/java/com/android/internal/util/ArrayUtils.java
@@ -600,6 +600,14 @@ public class ArrayUtils {
return cur;
}
+ public static @NonNull <T> ArrayList<T> add(@Nullable ArrayList<T> cur, int index, T val) {
+ if (cur == null) {
+ cur = new ArrayList<>();
+ }
+ cur.add(index, val);
+ return cur;
+ }
+
public static @Nullable <T> ArrayList<T> remove(@Nullable ArrayList<T> cur, T val) {
if (cur == null) {
return null;
diff --git a/core/tests/coretests/Android.bp b/core/tests/coretests/Android.bp
index a4c504b9cbdf..c009f588f8a9 100644
--- a/core/tests/coretests/Android.bp
+++ b/core/tests/coretests/Android.bp
@@ -74,7 +74,6 @@ java_genrule {
":FrameworksCoreTests_install_loc_internal",
":FrameworksCoreTests_install_loc_sdcard",
":FrameworksCoreTests_install_loc_unspecified",
- ":FrameworksCoreTests_install_multi_package",
":FrameworksCoreTests_install_split_base",
":FrameworksCoreTests_install_split_feature_a",
":FrameworksCoreTests_install_use_perm_good",
diff --git a/core/tests/coretests/apks/install_multi_package/Android.bp b/core/tests/coretests/apks/install_multi_package/Android.bp
deleted file mode 100644
index 249242e239e4..000000000000
--- a/core/tests/coretests/apks/install_multi_package/Android.bp
+++ /dev/null
@@ -1,6 +0,0 @@
-android_test_helper_app {
- name: "FrameworksCoreTests_install_multi_package",
- defaults: ["FrameworksCoreTests_apks_defaults"],
-
- srcs: ["**/*.java"],
-}
diff --git a/core/tests/coretests/apks/install_multi_package/AndroidManifest.xml b/core/tests/coretests/apks/install_multi_package/AndroidManifest.xml
deleted file mode 100644
index 5164cae9e5c0..000000000000
--- a/core/tests/coretests/apks/install_multi_package/AndroidManifest.xml
+++ /dev/null
@@ -1,104 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!-- Copyright (C) 2011 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.
--->
-<manifest
- xmlns:android="http://schemas.android.com/apk/res/android"
- package="com.android.frameworks.coretests.install_multi_package">
-
-<!--
- This manifest is has child packages with components.
--->
-
- <uses-feature
- android:name="com.android.frameworks.coretests.nonexistent" />
- <uses-configuration
- android:reqFiveWayNav="false" />
-
- <instrumentation
- android:name="android.test.InstrumentationTestRunner"
- android:targetPackage="com.android.frameworks.coretests"
- android:label="Frameworks Core Tests" />
-
- <permission
- android:label="test permission"
- android:name="test_permission"
- android:protectionLevel="normal" />
- <uses-permission android:name="android.permission.INTERNET" />
-
-<!--
- NOTE: This declares a child package, application, then another child
- package, to test potential bugs that are order-dependent. Also, each
- one varies the order.
--->
-
- <package package="com.android.frameworks.coretests.install_multi_package.first_child">
- <uses-permission android:name="android.permission.NFC" />
- <!-- NOTE: A declared permission is ignored since the tag is not whitelisted. -->
- <permission
- android:label="test permission"
- android:name="first_child_permission"
- android:protectionLevel="signature" />
- <application
- android:hasCode="true">
- <activity
- android:name="com.android.frameworks.coretests.FirstChildTestActivity">
- </activity>
- <provider
- android:name="com.android.frameworks.coretests.FirstChildTestProvider"
- android:authorities="com.android.frameworks.coretests.testprovider" />
- <receiver
- android:name="com.android.frameworks.coretests.FirstChildTestReceiver" />
- <service
- android:name="com.android.frameworks.coretests.FirstChildTestService" />
- </application>
- </package>
-
- <application
- android:hasCode="true">
- <service
- android:name="com.android.frameworks.coretests.TestService" />
- <activity
- android:name="com.android.frameworks.coretests.TestActivity">
- </activity>
- <provider
- android:name="com.android.frameworks.coretests.TestProvider"
- android:authorities="com.android.frameworks.coretests.testprovider" />
- <receiver
- android:name="com.android.frameworks.coretests.TestReceiver" />
- </application>
-
- <package package="com.android.frameworks.coretests.blah.second_child">
- <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
- <uses-permission-sdk-23 android:name="android.permission.READ_CONTACTS" />
- <!-- NOTE: A declared permission is ignored since the tag is not whitelisted. -->
- <permission
- android:label="test permission"
- android:name="second_child_permission"
- android:protectionLevel="dangerous" />
- <application
- android:hasCode="true">
- <receiver
- android:name="com.android.frameworks.coretests.SecondChildTestReceiver" />
- <service
- android:name="com.android.frameworks.coretests.SecondChildTestService" />
- <activity
- android:name="com.android.frameworks.coretests.SecondChildTestActivity">
- </activity>
- <provider
- android:name="com.android.frameworks.coretests.SecondChildTestProvider"
- android:authorities="com.android.frameworks.coretests.testprovider" />
- </application>
- </package>
-</manifest>
diff --git a/core/tests/coretests/apks/install_multi_package/src/com/android/frameworks/coretests/FirstChildTestActivity.java b/core/tests/coretests/apks/install_multi_package/src/com/android/frameworks/coretests/FirstChildTestActivity.java
deleted file mode 100644
index 57afcb0e1a0d..000000000000
--- a/core/tests/coretests/apks/install_multi_package/src/com/android/frameworks/coretests/FirstChildTestActivity.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright (C) 2011 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.frameworks.coretests;
-
-import android.app.Activity;
-
-public class FirstChildTestActivity extends Activity {
-
-}
diff --git a/core/tests/coretests/apks/install_multi_package/src/com/android/frameworks/coretests/FirstChildTestProvider.java b/core/tests/coretests/apks/install_multi_package/src/com/android/frameworks/coretests/FirstChildTestProvider.java
deleted file mode 100644
index 2816865b2f1f..000000000000
--- a/core/tests/coretests/apks/install_multi_package/src/com/android/frameworks/coretests/FirstChildTestProvider.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2011 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.frameworks.coretests;
-
-import android.content.ContentProvider;
-import android.content.ContentValues;
-import android.database.Cursor;
-import android.net.Uri;
-
-public class FirstChildTestProvider extends ContentProvider {
-
- @Override
- public boolean onCreate() {
- return false;
- }
-
- @Override
- public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
- String sortOrder) {
- return null;
- }
-
- @Override
- public String getType(Uri uri) {
- return null;
- }
-
- @Override
- public Uri insert(Uri uri, ContentValues values) {
- return null;
- }
-
- @Override
- public int delete(Uri uri, String selection, String[] selectionArgs) {
- return 0;
- }
-
- @Override
- public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
- return 0;
- }
-}
diff --git a/core/tests/coretests/apks/install_multi_package/src/com/android/frameworks/coretests/FirstChildTestReceiver.java b/core/tests/coretests/apks/install_multi_package/src/com/android/frameworks/coretests/FirstChildTestReceiver.java
deleted file mode 100644
index ffe84b73dd37..000000000000
--- a/core/tests/coretests/apks/install_multi_package/src/com/android/frameworks/coretests/FirstChildTestReceiver.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2011 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.frameworks.coretests;
-
-import android.content.ContentProvider;
-import android.content.ContentValues;
-import android.database.Cursor;
-import android.net.Uri;
-
-public class FirstChildTestReceiver extends ContentProvider {
-
- @Override
- public boolean onCreate() {
- return false;
- }
-
- @Override
- public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
- String sortOrder) {
- return null;
- }
-
- @Override
- public String getType(Uri uri) {
- return null;
- }
-
- @Override
- public Uri insert(Uri uri, ContentValues values) {
- return null;
- }
-
- @Override
- public int delete(Uri uri, String selection, String[] selectionArgs) {
- return 0;
- }
-
- @Override
- public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
- return 0;
- }
-}
diff --git a/core/tests/coretests/apks/install_multi_package/src/com/android/frameworks/coretests/FirstChildTestService.java b/core/tests/coretests/apks/install_multi_package/src/com/android/frameworks/coretests/FirstChildTestService.java
deleted file mode 100644
index faa6e9cff2b2..000000000000
--- a/core/tests/coretests/apks/install_multi_package/src/com/android/frameworks/coretests/FirstChildTestService.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2011 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.frameworks.coretests;
-
-import android.app.Service;
-import android.content.Intent;
-import android.os.IBinder;
-
-public class FirstChildTestService extends Service {
-
- @Override
- public IBinder onBind(Intent intent) {
- return null;
- }
-}
diff --git a/core/tests/coretests/apks/install_multi_package/src/com/android/frameworks/coretests/SecondChildTestActivity.java b/core/tests/coretests/apks/install_multi_package/src/com/android/frameworks/coretests/SecondChildTestActivity.java
deleted file mode 100644
index e89f26489959..000000000000
--- a/core/tests/coretests/apks/install_multi_package/src/com/android/frameworks/coretests/SecondChildTestActivity.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright (C) 2011 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.frameworks.coretests;
-
-import android.app.Activity;
-
-public class SecondChildTestActivity extends Activity {
-
-}
diff --git a/core/tests/coretests/apks/install_multi_package/src/com/android/frameworks/coretests/SecondChildTestProvider.java b/core/tests/coretests/apks/install_multi_package/src/com/android/frameworks/coretests/SecondChildTestProvider.java
deleted file mode 100644
index 2bd40a5df94d..000000000000
--- a/core/tests/coretests/apks/install_multi_package/src/com/android/frameworks/coretests/SecondChildTestProvider.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2011 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.frameworks.coretests;
-
-import android.content.ContentProvider;
-import android.content.ContentValues;
-import android.database.Cursor;
-import android.net.Uri;
-
-public class SecondChildTestProvider extends ContentProvider {
-
- @Override
- public boolean onCreate() {
- return false;
- }
-
- @Override
- public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
- String sortOrder) {
- return null;
- }
-
- @Override
- public String getType(Uri uri) {
- return null;
- }
-
- @Override
- public Uri insert(Uri uri, ContentValues values) {
- return null;
- }
-
- @Override
- public int delete(Uri uri, String selection, String[] selectionArgs) {
- return 0;
- }
-
- @Override
- public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
- return 0;
- }
-}
diff --git a/core/tests/coretests/apks/install_multi_package/src/com/android/frameworks/coretests/SecondChildTestReceiver.java b/core/tests/coretests/apks/install_multi_package/src/com/android/frameworks/coretests/SecondChildTestReceiver.java
deleted file mode 100644
index a6c4ddc90c6a..000000000000
--- a/core/tests/coretests/apks/install_multi_package/src/com/android/frameworks/coretests/SecondChildTestReceiver.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2011 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.frameworks.coretests;
-
-import android.content.ContentProvider;
-import android.content.ContentValues;
-import android.database.Cursor;
-import android.net.Uri;
-
-public class SecondChildTestReceiver extends ContentProvider {
-
- @Override
- public boolean onCreate() {
- return false;
- }
-
- @Override
- public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
- String sortOrder) {
- return null;
- }
-
- @Override
- public String getType(Uri uri) {
- return null;
- }
-
- @Override
- public Uri insert(Uri uri, ContentValues values) {
- return null;
- }
-
- @Override
- public int delete(Uri uri, String selection, String[] selectionArgs) {
- return 0;
- }
-
- @Override
- public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
- return 0;
- }
-}
diff --git a/core/tests/coretests/apks/install_multi_package/src/com/android/frameworks/coretests/SecondChildTestService.java b/core/tests/coretests/apks/install_multi_package/src/com/android/frameworks/coretests/SecondChildTestService.java
deleted file mode 100644
index 1e721aa8ae5b..000000000000
--- a/core/tests/coretests/apks/install_multi_package/src/com/android/frameworks/coretests/SecondChildTestService.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2011 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.frameworks.coretests;
-
-import android.app.Service;
-import android.content.Intent;
-import android.os.IBinder;
-
-public class SecondChildTestService extends Service {
-
- @Override
- public IBinder onBind(Intent intent) {
- return null;
- }
-}
diff --git a/core/tests/coretests/apks/install_multi_package/src/com/android/frameworks/coretests/TestActivity.java b/core/tests/coretests/apks/install_multi_package/src/com/android/frameworks/coretests/TestActivity.java
deleted file mode 100644
index 10d0551a3a6f..000000000000
--- a/core/tests/coretests/apks/install_multi_package/src/com/android/frameworks/coretests/TestActivity.java
+++ /dev/null
@@ -1,24 +0,0 @@
-/*
- * Copyright (C) 2011 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.frameworks.coretests;
-
-import android.app.Activity;
-
-public class TestActivity extends Activity {
-
-}
diff --git a/core/tests/coretests/apks/install_multi_package/src/com/android/frameworks/coretests/TestProvider.java b/core/tests/coretests/apks/install_multi_package/src/com/android/frameworks/coretests/TestProvider.java
deleted file mode 100644
index 59f9f10c6efe..000000000000
--- a/core/tests/coretests/apks/install_multi_package/src/com/android/frameworks/coretests/TestProvider.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2011 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.frameworks.coretests;
-
-import android.content.ContentProvider;
-import android.content.ContentValues;
-import android.database.Cursor;
-import android.net.Uri;
-
-public class TestProvider extends ContentProvider {
-
- @Override
- public boolean onCreate() {
- return false;
- }
-
- @Override
- public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
- String sortOrder) {
- return null;
- }
-
- @Override
- public String getType(Uri uri) {
- return null;
- }
-
- @Override
- public Uri insert(Uri uri, ContentValues values) {
- return null;
- }
-
- @Override
- public int delete(Uri uri, String selection, String[] selectionArgs) {
- return 0;
- }
-
- @Override
- public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
- return 0;
- }
-}
diff --git a/core/tests/coretests/apks/install_multi_package/src/com/android/frameworks/coretests/TestReceiver.java b/core/tests/coretests/apks/install_multi_package/src/com/android/frameworks/coretests/TestReceiver.java
deleted file mode 100644
index 21f6263a38bc..000000000000
--- a/core/tests/coretests/apks/install_multi_package/src/com/android/frameworks/coretests/TestReceiver.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2011 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.frameworks.coretests;
-
-import android.content.ContentProvider;
-import android.content.ContentValues;
-import android.database.Cursor;
-import android.net.Uri;
-
-public class TestReceiver extends ContentProvider {
-
- @Override
- public boolean onCreate() {
- return false;
- }
-
- @Override
- public Cursor query(Uri uri, String[] projection, String selection, String[] selectionArgs,
- String sortOrder) {
- return null;
- }
-
- @Override
- public String getType(Uri uri) {
- return null;
- }
-
- @Override
- public Uri insert(Uri uri, ContentValues values) {
- return null;
- }
-
- @Override
- public int delete(Uri uri, String selection, String[] selectionArgs) {
- return 0;
- }
-
- @Override
- public int update(Uri uri, ContentValues values, String selection, String[] selectionArgs) {
- return 0;
- }
-}
diff --git a/core/tests/coretests/apks/install_multi_package/src/com/android/frameworks/coretests/TestService.java b/core/tests/coretests/apks/install_multi_package/src/com/android/frameworks/coretests/TestService.java
deleted file mode 100644
index b330e75308f9..000000000000
--- a/core/tests/coretests/apks/install_multi_package/src/com/android/frameworks/coretests/TestService.java
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
- * Copyright (C) 2011 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.frameworks.coretests;
-
-import android.app.Service;
-import android.content.Intent;
-import android.os.IBinder;
-
-public class TestService extends Service {
-
- @Override
- public IBinder onBind(Intent intent) {
- return null;
- }
-}
diff --git a/core/tests/coretests/src/android/content/pm/AndroidHidlUpdaterTest.java b/core/tests/coretests/src/android/content/pm/AndroidHidlUpdaterTest.java
deleted file mode 100644
index cc48239c4526..000000000000
--- a/core/tests/coretests/src/android/content/pm/AndroidHidlUpdaterTest.java
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Copyright (C) 2018 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 android.content.pm;
-
-import static android.content.pm.PackageBuilder.builder;
-import static android.content.pm.SharedLibraryNames.ANDROID_HIDL_BASE;
-import static android.content.pm.SharedLibraryNames.ANDROID_HIDL_MANAGER;
-
-import android.os.Build;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-/**
- * Test for {@link AndroidHidlUpdater}
- */
-@SmallTest
-@RunWith(JUnit4.class)
-public class AndroidHidlUpdaterTest extends PackageSharedLibraryUpdaterTest {
-
- private static final String OTHER_LIBRARY = "other.library";
-
- @Test
- public void targeted_at_P() {
- PackageBuilder before = builder()
- .targetSdkVersion(Build.VERSION_CODES.P);
-
- // no change, not system
- checkBackwardsCompatibility(before, before);
- }
-
- @Test
- public void targeted_at_P_system() {
- PackageBuilder before = builder().asSystemApp()
- .targetSdkVersion(Build.VERSION_CODES.P);
-
- // Should add both HIDL libraries
- PackageBuilder after = builder().asSystemApp()
- .targetSdkVersion(Build.VERSION_CODES.P)
- .requiredLibraries(ANDROID_HIDL_MANAGER, ANDROID_HIDL_BASE);
-
- checkBackwardsCompatibility(before, after);
- }
-
- @Test
- public void targeted_at_P_not_empty_usesLibraries() {
- PackageBuilder before = builder()
- .targetSdkVersion(Build.VERSION_CODES.P)
- .requiredLibraries(OTHER_LIBRARY);
-
- // no change, not system
- checkBackwardsCompatibility(before, before);
- }
-
- @Test
- public void targeted_at_P_not_empty_usesLibraries_system() {
- PackageBuilder before = builder().asSystemApp()
- .targetSdkVersion(Build.VERSION_CODES.P)
- .requiredLibraries(OTHER_LIBRARY);
-
- // The hidl jars should be added at the start of the list because it
- // is not on the bootclasspath and the package targets pre-P.
- PackageBuilder after = builder().asSystemApp()
- .targetSdkVersion(Build.VERSION_CODES.P)
- .requiredLibraries(ANDROID_HIDL_MANAGER, ANDROID_HIDL_BASE, OTHER_LIBRARY);
-
- checkBackwardsCompatibility(before, after);
- }
-
- @Test
- public void targeted_at_P_in_usesLibraries() {
- PackageBuilder before = builder()
- .targetSdkVersion(Build.VERSION_CODES.P)
- .requiredLibraries(ANDROID_HIDL_MANAGER, ANDROID_HIDL_BASE);
-
- PackageBuilder after = builder()
- .targetSdkVersion(Build.VERSION_CODES.P);
-
- // Libraries are removed because they are not available for non-system apps
- checkBackwardsCompatibility(before, after);
- }
-
- @Test
- public void targeted_at_P_in_usesLibraries_system() {
- PackageBuilder before = builder().asSystemApp()
- .targetSdkVersion(Build.VERSION_CODES.P)
- .requiredLibraries(ANDROID_HIDL_MANAGER, ANDROID_HIDL_BASE);
-
- // No change is required because the package explicitly requests the HIDL libraries
- // and is targeted at the current version so does not need backwards compatibility.
- checkBackwardsCompatibility(before, before);
- }
-
- @Test
- public void in_usesLibraries() {
- PackageBuilder before = builder().requiredLibraries(ANDROID_HIDL_BASE);
-
- // Dependency is removed, it is not available.
- PackageBuilder after = builder();
-
- // Libraries are removed because they are not available for apps targetting Q+
- checkBackwardsCompatibility(before, after);
- }
-
- @Test
- public void in_usesOptionalLibraries() {
- PackageBuilder before = builder().optionalLibraries(ANDROID_HIDL_BASE);
-
- // Dependency is removed, it is not available.
- PackageBuilder after = builder();
-
- // Libraries are removed because they are not available for apps targetting Q+
- checkBackwardsCompatibility(before, after);
- }
-
- private void checkBackwardsCompatibility(PackageBuilder before, PackageBuilder after) {
- checkBackwardsCompatibility(before, after, AndroidHidlUpdater::new);
- }
-}
diff --git a/core/tests/coretests/src/android/content/pm/AndroidTestBaseUpdaterTest.java b/core/tests/coretests/src/android/content/pm/AndroidTestBaseUpdaterTest.java
deleted file mode 100644
index 03108ced4816..000000000000
--- a/core/tests/coretests/src/android/content/pm/AndroidTestBaseUpdaterTest.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright (C) 2018 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 android.content.pm;
-
-import static android.content.pm.PackageBuilder.builder;
-import static android.content.pm.SharedLibraryNames.ANDROID_TEST_BASE;
-
-import android.os.Build;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-/**
- * Test for {@link AndroidTestBaseUpdater}
- */
-@SmallTest
-@RunWith(OptionalClassRunner.class)
-@OptionalClassRunner.OptionalClass("android.content.pm.AndroidTestBaseUpdater")
-public class AndroidTestBaseUpdaterTest extends PackageSharedLibraryUpdaterTest {
-
- private static final String OTHER_LIBRARY = "other.library";
-
- @Test
- public void targeted_at_Q() {
- PackageBuilder before = builder()
- .targetSdkVersion(Build.VERSION_CODES.Q);
-
- // Should add org.apache.http.legacy.
- PackageBuilder after = builder()
- .targetSdkVersion(Build.VERSION_CODES.Q)
- .requiredLibraries(ANDROID_TEST_BASE);
-
- checkBackwardsCompatibility(before, after);
- }
-
- @Test
- public void targeted_at_Q_not_empty_usesLibraries() {
- PackageBuilder before = builder()
- .targetSdkVersion(Build.VERSION_CODES.Q)
- .requiredLibraries(OTHER_LIBRARY);
-
- // The org.apache.http.legacy jar should be added at the start of the list because it
- // is not on the bootclasspath and the package targets pre-Q.
- PackageBuilder after = builder()
- .targetSdkVersion(Build.VERSION_CODES.Q)
- .requiredLibraries(ANDROID_TEST_BASE, OTHER_LIBRARY);
-
- checkBackwardsCompatibility(before, after);
- }
-
- @Test
- public void targeted_at_Q_in_usesLibraries() {
- PackageBuilder before = builder()
- .targetSdkVersion(Build.VERSION_CODES.Q)
- .requiredLibraries(ANDROID_TEST_BASE);
-
- // No change is required because although org.apache.http.legacy has been removed from
- // the bootclasspath the package explicitly requests it.
- checkBackwardsCompatibility(before, before);
- }
-
- @Test
- public void targeted_at_Q_in_usesOptionalLibraries() {
- PackageBuilder before = builder()
- .targetSdkVersion(Build.VERSION_CODES.Q)
- .optionalLibraries(ANDROID_TEST_BASE);
-
- // No change is required because although org.apache.http.legacy has been removed from
- // the bootclasspath the package explicitly requests it.
- checkBackwardsCompatibility(before, before);
- }
-
- @Test
- public void in_usesLibraries() {
- PackageBuilder before = builder().requiredLibraries(ANDROID_TEST_BASE);
-
- // No change is required because the package explicitly requests org.apache.http.legacy
- // and is targeted at the current version so does not need backwards compatibility.
- checkBackwardsCompatibility(before, before);
- }
-
- @Test
- public void in_usesOptionalLibraries() {
- PackageBuilder before = builder().optionalLibraries(ANDROID_TEST_BASE);
-
- // No change is required because the package explicitly requests org.apache.http.legacy
- // and is targeted at the current version so does not need backwards compatibility.
- checkBackwardsCompatibility(before, before);
- }
-
- private void checkBackwardsCompatibility(PackageBuilder before, PackageBuilder after) {
- checkBackwardsCompatibility(before, after, AndroidTestBaseUpdater::new);
- }
-}
diff --git a/core/tests/coretests/src/android/content/pm/AndroidTestRunnerSplitUpdaterTest.java b/core/tests/coretests/src/android/content/pm/AndroidTestRunnerSplitUpdaterTest.java
deleted file mode 100644
index 7f817d66caf7..000000000000
--- a/core/tests/coretests/src/android/content/pm/AndroidTestRunnerSplitUpdaterTest.java
+++ /dev/null
@@ -1,64 +0,0 @@
-/*
- * Copyright (C) 2018 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 android.content.pm;
-
-import static android.content.pm.PackageBuilder.builder;
-import static android.content.pm.SharedLibraryNames.ANDROID_TEST_MOCK;
-import static android.content.pm.SharedLibraryNames.ANDROID_TEST_RUNNER;
-
-import android.content.pm.PackageBackwardCompatibility.AndroidTestRunnerSplitUpdater;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-/**
- * Test for {@link AndroidTestRunnerSplitUpdater}
- */
-@SmallTest
-@RunWith(JUnit4.class)
-public class AndroidTestRunnerSplitUpdaterTest extends PackageSharedLibraryUpdaterTest {
-
- @Test
- public void android_test_runner_in_usesOptionalLibraries() {
- PackageBuilder before = builder().optionalLibraries(ANDROID_TEST_RUNNER);
-
- PackageBuilder after = builder()
- .optionalLibraries(ANDROID_TEST_MOCK, ANDROID_TEST_RUNNER);
-
- checkBackwardsCompatibility(before, after);
- }
-
- @Test
- public void android_test_runner_in_usesLibraries_android_test_mock_in_usesOptionalLibraries() {
- PackageBuilder before = builder()
- .requiredLibraries(ANDROID_TEST_RUNNER)
- .optionalLibraries(ANDROID_TEST_MOCK);
-
- PackageBuilder after = builder()
- .requiredLibraries(ANDROID_TEST_RUNNER)
- .optionalLibraries(ANDROID_TEST_MOCK);
-
- checkBackwardsCompatibility(before, after);
- }
-
- private void checkBackwardsCompatibility(PackageBuilder before, PackageBuilder after) {
- checkBackwardsCompatibility(before, after, AndroidTestRunnerSplitUpdater::new);
- }
-}
diff --git a/core/tests/coretests/src/android/content/pm/OrgApacheHttpLegacyUpdaterTest.java b/core/tests/coretests/src/android/content/pm/OrgApacheHttpLegacyUpdaterTest.java
deleted file mode 100644
index 834a0bbeab89..000000000000
--- a/core/tests/coretests/src/android/content/pm/OrgApacheHttpLegacyUpdaterTest.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Copyright (C) 2018 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 android.content.pm;
-
-import static android.content.pm.PackageBuilder.builder;
-import static android.content.pm.SharedLibraryNames.ORG_APACHE_HTTP_LEGACY;
-
-import android.os.Build;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-
-/**
- * Test for {@link OrgApacheHttpLegacyUpdater}
- */
-@SmallTest
-@RunWith(OptionalClassRunner.class)
-@OptionalClassRunner.OptionalClass("android.content.pm.OrgApacheHttpLegacyUpdater")
-public class OrgApacheHttpLegacyUpdaterTest extends PackageSharedLibraryUpdaterTest {
-
- private static final String OTHER_LIBRARY = "other.library";
-
- @Test
- public void targeted_at_O() {
- PackageBuilder before = builder()
- .targetSdkVersion(Build.VERSION_CODES.O);
-
- // Should add org.apache.http.legacy.
- PackageBuilder after = builder()
- .targetSdkVersion(Build.VERSION_CODES.O)
- .requiredLibraries(ORG_APACHE_HTTP_LEGACY);
-
- checkBackwardsCompatibility(before, after);
- }
-
- @Test
- public void targeted_at_O_not_empty_usesLibraries() {
- PackageBuilder before = builder()
- .targetSdkVersion(Build.VERSION_CODES.O)
- .requiredLibraries(OTHER_LIBRARY);
-
- // The org.apache.http.legacy jar should be added at the start of the list because it
- // is not on the bootclasspath and the package targets pre-P.
- PackageBuilder after = builder()
- .targetSdkVersion(Build.VERSION_CODES.O)
- .requiredLibraries(ORG_APACHE_HTTP_LEGACY, OTHER_LIBRARY);
-
- checkBackwardsCompatibility(before, after);
- }
-
- @Test
- public void targeted_at_O_in_usesLibraries() {
- PackageBuilder before = builder()
- .targetSdkVersion(Build.VERSION_CODES.O)
- .requiredLibraries(ORG_APACHE_HTTP_LEGACY);
-
- // No change is required because although org.apache.http.legacy has been removed from
- // the bootclasspath the package explicitly requests it.
- checkBackwardsCompatibility(before, before);
- }
-
- @Test
- public void targeted_at_O_in_usesOptionalLibraries() {
- PackageBuilder before = builder()
- .targetSdkVersion(Build.VERSION_CODES.O)
- .optionalLibraries(ORG_APACHE_HTTP_LEGACY);
-
- // No change is required because although org.apache.http.legacy has been removed from
- // the bootclasspath the package explicitly requests it.
- checkBackwardsCompatibility(before, before);
- }
-
- @Test
- public void in_usesLibraries() {
- PackageBuilder before = builder().requiredLibraries(ORG_APACHE_HTTP_LEGACY);
-
- // No change is required because the package explicitly requests org.apache.http.legacy
- // and is targeted at the current version so does not need backwards compatibility.
- checkBackwardsCompatibility(before, before);
- }
-
- @Test
- public void in_usesOptionalLibraries() {
- PackageBuilder before = builder().optionalLibraries(ORG_APACHE_HTTP_LEGACY);
-
- // No change is required because the package explicitly requests org.apache.http.legacy
- // and is targeted at the current version so does not need backwards compatibility.
- checkBackwardsCompatibility(before, before);
- }
-
- private void checkBackwardsCompatibility(PackageBuilder before, PackageBuilder after) {
- checkBackwardsCompatibility(before, after, OrgApacheHttpLegacyUpdater::new);
- }
-}
diff --git a/core/tests/coretests/src/android/content/pm/PackageBuilder.java b/core/tests/coretests/src/android/content/pm/PackageBuilder.java
deleted file mode 100644
index f7544af43461..000000000000
--- a/core/tests/coretests/src/android/content/pm/PackageBuilder.java
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
- * Copyright (C) 2018 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 android.content.pm;
-
-import static org.junit.Assert.assertEquals;
-
-import android.os.Build;
-
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-
-/**
- * Test support for building {@link PackageParser.Package} instances.
- */
-class PackageBuilder {
-
- private int mTargetSdkVersion = Build.VERSION_CODES.CUR_DEVELOPMENT;
-
- private int mFlags = 0;
-
- private ArrayList<String> mRequiredLibraries;
-
- private ArrayList<String> mOptionalLibraries;
-
- public static PackageBuilder builder() {
- return new PackageBuilder();
- }
-
- public PackageParser.Package build() {
- PackageParser.Package pkg = new PackageParser.Package("org.package.name");
- pkg.applicationInfo.targetSdkVersion = mTargetSdkVersion;
- pkg.applicationInfo.flags = mFlags;
- pkg.usesLibraries = mRequiredLibraries;
- pkg.usesOptionalLibraries = mOptionalLibraries;
- return pkg;
- }
-
- PackageBuilder targetSdkVersion(int version) {
- this.mTargetSdkVersion = version;
- return this;
- }
-
- PackageBuilder asSystemApp() {
- this.mFlags |= ApplicationInfo.FLAG_SYSTEM;
- return this;
- }
-
- PackageBuilder requiredLibraries(String... names) {
- this.mRequiredLibraries = arrayListOrNull(names);
- return this;
- }
-
- PackageBuilder requiredLibraries(List<String> names) {
- this.mRequiredLibraries = arrayListOrNull(names.toArray(new String[names.size()]));
- return this;
- }
-
- PackageBuilder optionalLibraries(String... names) {
- this.mOptionalLibraries = arrayListOrNull(names);
- return this;
- }
-
- /**
- * Check that this matches the supplied {@link PackageParser.Package}.
- *
- * @param pkg the instance to compare with this.
- */
- public void check(PackageParser.Package pkg) {
- assertEquals("targetSdkVersion should not be changed",
- mTargetSdkVersion,
- pkg.applicationInfo.targetSdkVersion);
- assertEquals("usesLibraries not updated correctly",
- mRequiredLibraries,
- pkg.usesLibraries);
- assertEquals("usesOptionalLibraries not updated correctly",
- mOptionalLibraries,
- pkg.usesOptionalLibraries);
- }
-
- private static ArrayList<String> arrayListOrNull(String... strings) {
- if (strings == null || strings.length == 0) {
- return null;
- }
- ArrayList<String> list = new ArrayList<>();
- Collections.addAll(list, strings);
- return list;
- }
-
-}
diff --git a/core/tests/coretests/src/android/content/pm/PackageParserTest.java b/core/tests/coretests/src/android/content/pm/PackageParserTest.java
index 5c7f2af782b9..cb23850798c3 100644
--- a/core/tests/coretests/src/android/content/pm/PackageParserTest.java
+++ b/core/tests/coretests/src/android/content/pm/PackageParserTest.java
@@ -23,26 +23,26 @@ import static org.junit.Assert.assertTrue;
import android.apex.ApexInfo;
import android.content.Context;
-import android.content.pm.PackageParser.Component;
-import android.content.pm.PackageParser.Package;
-import android.content.pm.PackageParser.Permission;
+import android.content.pm.parsing.AndroidPackage;
+import android.content.pm.parsing.ComponentParseUtils.ParsedComponent;
+import android.content.pm.parsing.ComponentParseUtils.ParsedPermission;
+import android.content.pm.parsing.ParsedPackage;
import android.os.Build;
import android.os.Bundle;
import android.os.FileUtils;
-import android.os.SystemProperties;
import androidx.test.InstrumentationRegistry;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
import com.android.frameworks.coretests.R;
+import com.android.internal.util.ArrayUtils;
import org.junit.Test;
import org.junit.runner.RunWith;
import java.io.File;
import java.io.InputStream;
-import java.util.Arrays;
import java.util.function.Function;
@SmallTest
@@ -59,8 +59,8 @@ public class PackageParserTest {
private static final String PRE_RELEASE_WITH_FINGERPRINT = "B.fingerprint";
private static final String NEWER_PRE_RELEASE_WITH_FINGERPRINT = "C.fingerprint";
- private static final String[] CODENAMES_RELEASED = { /* empty */ };
- private static final String[] CODENAMES_PRE_RELEASE = { PRE_RELEASE };
+ private static final String[] CODENAMES_RELEASED = { /* empty */};
+ private static final String[] CODENAMES_PRE_RELEASE = {PRE_RELEASE};
private static final int OLDER_VERSION = 10;
private static final int PLATFORM_VERSION = 20;
@@ -300,10 +300,6 @@ public class PackageParserTest {
assertEquals(0x0083, finalConfigChanges); // Should be 10000011.
}
- Package parsePackage(String apkFileName, int apkResourceId) throws Exception {
- return parsePackage(apkFileName, apkResourceId, p -> p);
- }
-
/**
* Copies a specified {@code resourceId} to a file. Returns a non-null file if the copy
* succeeded, or {@code null} otherwise.
@@ -331,16 +327,17 @@ public class PackageParserTest {
*
* APKs are put into coretests/apks/packageparser_*.
*
- * @param apkFileName temporary file name to store apk extracted from resources
+ * @param apkFileName temporary file name to store apk extracted from resources
* @param apkResourceId identifier of the apk as a resource
*/
- Package parsePackage(String apkFileName, int apkResourceId,
- Function<Package, Package> converter) throws Exception {
+ ParsedPackage parsePackage(String apkFileName, int apkResourceId,
+ Function<ParsedPackage, ParsedPackage> converter) throws Exception {
// Copy the resource to a file.
File outFile = null;
try {
outFile = copyRawResourceToFile(apkFileName, apkResourceId);
- return converter.apply(new PackageParser().parsePackage(outFile, 0 /* flags */));
+ return converter.apply(
+ new PackageParser().parseParsedPackage(outFile, 0 /* flags */, false));
} finally {
if (outFile != null) {
outFile.delete();
@@ -351,40 +348,40 @@ public class PackageParserTest {
/**
* Asserts basic properties about a component.
*/
- private void assertComponent(String className, String packageName, int numIntents,
- Component<?> component) {
+ private void assertComponent(String className, int numIntents, ParsedComponent<?> component) {
assertEquals(className, component.className);
- assertEquals(packageName, component.owner.packageName);
assertEquals(numIntents, component.intents.size());
}
/**
* Asserts four regularly-named components of each type: one Activity, one Service, one
* Provider, and one Receiver.
+ *
* @param template templated string with %s subbed with Activity, Service, Provider, Receiver
*/
- private void assertOneComponentOfEachType(String template, Package p) {
- String packageName = p.packageName;
+ private void assertOneComponentOfEachType(String template, AndroidPackage p) {
+ assertEquals(2, p.getActivities().size());
+
+ // For normal apps, a Activity that forwards to the App Details page is added.
+ assertEquals("android.app.AppDetailsActivity", p.getActivities().get(1)
+ .className);
- assertEquals(1, p.activities.size());
assertComponent(String.format(template, "Activity"),
- packageName, 0 /* intents */, p.activities.get(0));
- assertEquals(1, p.services.size());
+ 0 /* intents */, p.getActivities().get(0));
+ assertEquals(1, p.getServices().size());
assertComponent(String.format(template, "Service"),
- packageName, 0 /* intents */, p.services.get(0));
- assertEquals(1, p.providers.size());
+ 0 /* intents */, p.getServices().get(0));
+ assertEquals(1, p.getProviders().size());
assertComponent(String.format(template, "Provider"),
- packageName, 0 /* intents */, p.providers.get(0));
- assertEquals(1, p.receivers.size());
+ 0 /* intents */, p.getProviders().get(0));
+ assertEquals(1, p.getReceivers().size());
assertComponent(String.format(template, "Receiver"),
- packageName, 0 /* intents */, p.receivers.get(0));
+ 0 /* intents */, p.getReceivers().get(0));
}
- private void assertPermission(String name, String packageName, int protectionLevel,
- Permission permission) {
- assertEquals(packageName, permission.owner.packageName);
- assertEquals(name, permission.info.name);
- assertEquals(protectionLevel, permission.info.protectionLevel);
+ private void assertPermission(String name, int protectionLevel, ParsedPermission permission) {
+ assertEquals(name, permission.getName());
+ assertEquals(protectionLevel, permission.getProtection());
}
private void assertMetadata(Bundle b, String... keysAndValues) {
@@ -416,25 +413,25 @@ public class PackageParserTest {
}
private void checkPackageWithComponents(
- Function<Package, Package> converter) throws Exception {
- Package p = parsePackage(
+ Function<ParsedPackage, ParsedPackage> converter) throws Exception {
+ ParsedPackage p = parsePackage(
"install_complete_package_info.apk", R.raw.install_complete_package_info,
converter);
String packageName = "com.android.frameworks.coretests.install_complete_package_info";
- assertEquals(packageName, p.packageName);
- assertEquals(1, p.permissions.size());
+ assertEquals(packageName, p.getPackageName());
+ assertEquals(1, p.getPermissions().size());
assertPermission(
"com.android.frameworks.coretests.install_complete_package_info.test_permission",
- packageName, PermissionInfo.PROTECTION_NORMAL, p.permissions.get(0));
+ PermissionInfo.PROTECTION_NORMAL, p.getPermissions().get(0));
// Hidden "app details" activity is added to every package.
boolean foundAppDetailsActivity = false;
- for (int i = 0; i < p.activities.size(); i++) {
- if (p.activities.get(i).className.equals(
+ for (int i = 0; i < ArrayUtils.size(p.getActivities()); i++) {
+ if (p.getActivities().get(i).className.equals(
PackageManager.APP_DETAILS_ACTIVITY_CLASS_NAME)) {
foundAppDetailsActivity = true;
- p.activities.remove(i);
+ p.getActivities().remove(i);
break;
}
}
@@ -442,72 +439,23 @@ public class PackageParserTest {
assertOneComponentOfEachType("com.android.frameworks.coretests.Test%s", p);
- assertMetadata(p.mAppMetaData,
+ assertMetadata(p.getAppMetaData(),
"key1", "value1",
"key2", "this_is_app");
- assertMetadata(p.activities.get(0).metaData,
+ assertMetadata(p.getActivities().get(0).getMetaData(),
"key1", "value1",
"key2", "this_is_activity");
- assertMetadata(p.services.get(0).metaData,
+ assertMetadata(p.getServices().get(0).getMetaData(),
"key1", "value1",
"key2", "this_is_service");
- assertMetadata(p.receivers.get(0).metaData,
+ assertMetadata(p.getReceivers().get(0).getMetaData(),
"key1", "value1",
"key2", "this_is_receiver");
- assertMetadata(p.providers.get(0).metaData,
+ assertMetadata(p.getProviders().get(0).getMetaData(),
"key1", "value1",
"key2", "this_is_provider");
}
- /**
- * Determines if the current device supports multi-package APKs.
- */
- private boolean supportsMultiPackageApk() {
- return SystemProperties.getBoolean("persist.sys.child_packages_enabled", false);
- }
-
- @Test
- public void testMultiPackageComponents() throws Exception {
- // TODO(gboyer): Remove once we decide to launch multi-package APKs.
- if (!supportsMultiPackageApk()) {
- return;
- }
- String parentName = "com.android.frameworks.coretests.install_multi_package";
- String firstChildName =
- "com.android.frameworks.coretests.install_multi_package.first_child";
- String secondChildName = // NOTE: intentionally inconsistent!
- "com.android.frameworks.coretests.blah.second_child";
-
- Package parent = parsePackage("install_multi_package.apk", R.raw.install_multi_package);
- assertEquals(parentName, parent.packageName);
- assertEquals(2, parent.childPackages.size());
- assertOneComponentOfEachType("com.android.frameworks.coretests.Test%s", parent);
- assertEquals(1, parent.permissions.size());
- assertPermission(parentName + ".test_permission", parentName,
- PermissionInfo.PROTECTION_NORMAL, parent.permissions.get(0));
- assertEquals(Arrays.asList("android.permission.INTERNET"),
- parent.requestedPermissions);
-
- Package firstChild = parent.childPackages.get(0);
- assertEquals(firstChildName, firstChild.packageName);
- assertOneComponentOfEachType(
- "com.android.frameworks.coretests.FirstChildTest%s", firstChild);
- assertEquals(0, firstChild.permissions.size()); // Child APKs cannot declare permissions.
- assertEquals(Arrays.asList("android.permission.NFC"),
- firstChild.requestedPermissions);
-
- Package secondChild = parent.childPackages.get(1);
- assertEquals(secondChildName, secondChild.packageName);
- assertOneComponentOfEachType(
- "com.android.frameworks.coretests.SecondChildTest%s", secondChild);
- assertEquals(0, secondChild.permissions.size()); // Child APKs cannot declare permissions.
- assertEquals(
- Arrays.asList(
- "android.permission.ACCESS_NETWORK_STATE",
- "android.permission.READ_CONTACTS"),
- secondChild.requestedPermissions);
- }
-
@Test
public void testApexPackageInfoGeneration() throws Exception {
String apexModuleName = "com.android.tzdata.apex";
@@ -522,7 +470,7 @@ public class PackageParserTest {
int flags = PackageManager.GET_META_DATA | PackageManager.GET_SIGNING_CERTIFICATES;
PackageParser pp = new PackageParser();
- Package p = pp.parsePackage(apexFile, flags, false);
+ PackageParser.Package p = pp.parsePackage(apexFile, flags, false);
PackageParser.collectCertificates(p, false);
PackageInfo pi = PackageParser.generatePackageInfo(p, apexInfo, flags);
diff --git a/core/tests/coretests/src/android/content/pm/PackageSharedLibraryUpdaterTest.java b/core/tests/coretests/src/android/content/pm/PackageSharedLibraryUpdaterTest.java
deleted file mode 100644
index 71a0e5e51b71..000000000000
--- a/core/tests/coretests/src/android/content/pm/PackageSharedLibraryUpdaterTest.java
+++ /dev/null
@@ -1,32 +0,0 @@
-/*
- * Copyright (C) 2018 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 android.content.pm;
-
-import java.util.function.Supplier;
-
-/**
- * Helper for classes that test {@link PackageSharedLibraryUpdater}.
- */
-abstract class PackageSharedLibraryUpdaterTest {
-
- static void checkBackwardsCompatibility(PackageBuilder before, PackageBuilder after,
- Supplier<PackageSharedLibraryUpdater> updaterSupplier) {
- PackageParser.Package pkg = before.build();
- updaterSupplier.get().updatePackage(pkg);
- after.check(pkg);
- }
-}
diff --git a/core/tests/coretests/src/android/content/pm/RemoveUnnecessaryAndroidTestBaseLibraryTest.java b/core/tests/coretests/src/android/content/pm/RemoveUnnecessaryAndroidTestBaseLibraryTest.java
deleted file mode 100644
index 216b0c8950b7..000000000000
--- a/core/tests/coretests/src/android/content/pm/RemoveUnnecessaryAndroidTestBaseLibraryTest.java
+++ /dev/null
@@ -1,133 +0,0 @@
-/*
- * Copyright (C) 2018 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 android.content.pm;
-
-import static android.content.pm.PackageBuilder.builder;
-import static android.content.pm.SharedLibraryNames.ANDROID_TEST_BASE;
-
-import android.content.pm.PackageBackwardCompatibility.RemoveUnnecessaryAndroidTestBaseLibrary;
-import android.os.Build;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-/**
- * Test for {@link RemoveUnnecessaryAndroidTestBaseLibrary}
- */
-@SmallTest
-@RunWith(JUnit4.class)
-public class RemoveUnnecessaryAndroidTestBaseLibraryTest
- extends PackageSharedLibraryUpdaterTest {
-
- private static final String OTHER_LIBRARY = "other.library";
-
- @Test
- public void targeted_at_O() {
- PackageBuilder before = builder()
- .targetSdkVersion(Build.VERSION_CODES.O);
-
- // No change required.
- checkBackwardsCompatibility(before, before);
- }
-
- @Test
- public void targeted_at_O_not_empty_usesLibraries() {
- PackageBuilder before = builder()
- .targetSdkVersion(Build.VERSION_CODES.O)
- .requiredLibraries(OTHER_LIBRARY);
-
- // No change required.
- checkBackwardsCompatibility(before, before);
- }
-
- @Test
- public void targeted_at_O_in_usesLibraries() {
- PackageBuilder before = builder()
- .targetSdkVersion(Build.VERSION_CODES.O)
- .requiredLibraries(ANDROID_TEST_BASE);
-
- // android.test.base should be removed from the libraries because it is provided
- // on the bootclasspath and providing both increases start up cost unnecessarily.
- PackageBuilder after = builder()
- .targetSdkVersion(Build.VERSION_CODES.O);
-
- checkBackwardsCompatibility(before, after);
- }
-
- @Test
- public void targeted_at_O_in_usesOptionalLibraries() {
- PackageBuilder before = builder()
- .targetSdkVersion(Build.VERSION_CODES.O)
- .optionalLibraries(ANDROID_TEST_BASE);
-
- // android.test.base should be removed from the libraries because it is provided
- // on the bootclasspath and providing both increases start up cost unnecessarily.
- PackageBuilder after = builder()
- .targetSdkVersion(Build.VERSION_CODES.O);
-
- checkBackwardsCompatibility(before, after);
- }
-
- @Test
- public void in_usesLibraries() {
- PackageBuilder before = builder().requiredLibraries(ANDROID_TEST_BASE);
-
- // android.test.base should be removed from the libraries because it is provided
- // on the bootclasspath and providing both increases start up cost unnecessarily.
- PackageBuilder after = builder();
-
- checkBackwardsCompatibility(before, after);
- }
-
- @Test
- public void in_usesOptionalLibraries() {
- PackageBuilder before = builder().optionalLibraries(ANDROID_TEST_BASE);
-
- // android.test.base should be removed from the libraries because it is provided
- // on the bootclasspath and providing both increases start up cost unnecessarily.
- PackageBuilder after = builder();
-
- checkBackwardsCompatibility(before, after);
- }
-
- @Test
- public void in_bothLibraries() {
- PackageBuilder before = builder()
- .requiredLibraries(ANDROID_TEST_BASE)
- .optionalLibraries(ANDROID_TEST_BASE);
-
- // android.test.base should be removed from the libraries because it is provided
- // on the bootclasspath and providing both increases start up cost unnecessarily.
- PackageBuilder after = builder();
-
- checkBackwardsCompatibility(before, after);
- }
-
- private void checkBackwardsCompatibility(PackageBuilder before, PackageBuilder after) {
- // TODO(b/72538146) - Cannot use constructor reference here because it is also used in
- // PackageBackwardCompatibility and that seems to create a package-private lambda in
- // android.content.pm which this then tries to reuse but fails because it cannot access
- // package-private classes/members because the test is loaded by a different ClassLoader
- // than the lambda.
- checkBackwardsCompatibility(before, after,
- () -> new RemoveUnnecessaryAndroidTestBaseLibrary());
- }
-
-}
diff --git a/core/tests/coretests/src/android/content/pm/RemoveUnnecessaryOrgApacheHttpLegacyLibraryTest.java b/core/tests/coretests/src/android/content/pm/RemoveUnnecessaryOrgApacheHttpLegacyLibraryTest.java
deleted file mode 100644
index fc60980bb796..000000000000
--- a/core/tests/coretests/src/android/content/pm/RemoveUnnecessaryOrgApacheHttpLegacyLibraryTest.java
+++ /dev/null
@@ -1,132 +0,0 @@
-/*
- * Copyright (C) 2018 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 android.content.pm;
-
-import static android.content.pm.PackageBuilder.builder;
-import static android.content.pm.SharedLibraryNames.ORG_APACHE_HTTP_LEGACY;
-
-import android.content.pm.PackageBackwardCompatibility.RemoveUnnecessaryOrgApacheHttpLegacyLibrary;
-import android.os.Build;
-
-import androidx.test.filters.SmallTest;
-
-import org.junit.Test;
-import org.junit.runner.RunWith;
-import org.junit.runners.JUnit4;
-
-/**
- * Test for {@link RemoveUnnecessaryOrgApacheHttpLegacyLibrary}
- */
-@SmallTest
-@RunWith(JUnit4.class)
-public class RemoveUnnecessaryOrgApacheHttpLegacyLibraryTest
- extends PackageSharedLibraryUpdaterTest {
-
- private static final String OTHER_LIBRARY = "other.library";
-
- @Test
- public void targeted_at_O() {
- PackageBuilder before = builder()
- .targetSdkVersion(Build.VERSION_CODES.O);
-
- // No change required.
- checkBackwardsCompatibility(before, before);
- }
-
- @Test
- public void targeted_at_O_not_empty_usesLibraries() {
- PackageBuilder before = builder()
- .targetSdkVersion(Build.VERSION_CODES.O)
- .requiredLibraries(OTHER_LIBRARY);
-
- // No change required.
- checkBackwardsCompatibility(before, before);
- }
-
- @Test
- public void targeted_at_O_in_usesLibraries() {
- PackageBuilder before = builder()
- .targetSdkVersion(Build.VERSION_CODES.O)
- .requiredLibraries(ORG_APACHE_HTTP_LEGACY);
-
- // org.apache.http.legacy should be removed from the libraries because it is provided
- // on the bootclasspath and providing both increases start up cost unnecessarily.
- PackageBuilder after = builder()
- .targetSdkVersion(Build.VERSION_CODES.O);
-
- checkBackwardsCompatibility(before, after);
- }
-
- @Test
- public void targeted_at_O_in_usesOptionalLibraries() {
- PackageBuilder before = builder()
- .targetSdkVersion(Build.VERSION_CODES.O)
- .optionalLibraries(ORG_APACHE_HTTP_LEGACY);
-
- // org.apache.http.legacy should be removed from the libraries because it is provided
- // on the bootclasspath and providing both increases start up cost unnecessarily.
- PackageBuilder after = builder()
- .targetSdkVersion(Build.VERSION_CODES.O);
-
- checkBackwardsCompatibility(before, after);
- }
-
- @Test
- public void in_usesLibraries() {
- PackageBuilder before = builder().requiredLibraries(ORG_APACHE_HTTP_LEGACY);
-
- // org.apache.http.legacy should be removed from the libraries because it is provided
- // on the bootclasspath and providing both increases start up cost unnecessarily.
- PackageBuilder after = builder();
-
- checkBackwardsCompatibility(before, after);
- }
-
- @Test
- public void in_usesOptionalLibraries() {
- PackageBuilder before = builder().optionalLibraries(ORG_APACHE_HTTP_LEGACY);
-
- // org.apache.http.legacy should be removed from the libraries because it is provided
- // on the bootclasspath and providing both increases start up cost unnecessarily.
- PackageBuilder after = builder();
-
- checkBackwardsCompatibility(before, after);
- }
-
- @Test
- public void in_bothLibraries() {
- PackageBuilder before = builder()
- .requiredLibraries(ORG_APACHE_HTTP_LEGACY)
- .optionalLibraries(ORG_APACHE_HTTP_LEGACY);
-
- // org.apache.http.legacy should be removed from the libraries because it is provided
- // on the bootclasspath and providing both increases start up cost unnecessarily.
- PackageBuilder after = builder();
-
- checkBackwardsCompatibility(before, after);
- }
-
- private void checkBackwardsCompatibility(PackageBuilder before, PackageBuilder after) {
- // TODO(b/72538146) - Cannot use constructor reference here because it is also used in
- // PackageBackwardCompatibility and that seems to create a package-private lambda in
- // android.content.pm which this then tries to reuse but fails because it cannot access
- // package-private classes/members because the test is loaded by a different ClassLoader
- // than the lambda.
- checkBackwardsCompatibility(before, after,
- () -> new RemoveUnnecessaryOrgApacheHttpLegacyLibrary());
- }
-}
diff --git a/core/tests/coretests/src/android/content/pm/dex/DexMetadataHelperTest.java b/core/tests/coretests/src/android/content/pm/dex/DexMetadataHelperTest.java
index 49849ee72a18..1e0bfb08693f 100644
--- a/core/tests/coretests/src/android/content/pm/dex/DexMetadataHelperTest.java
+++ b/core/tests/coretests/src/android/content/pm/dex/DexMetadataHelperTest.java
@@ -25,9 +25,9 @@ import android.content.Context;
import android.content.pm.PackageManager;
import android.content.pm.PackageParser;
import android.content.pm.PackageParser.ApkLite;
-import android.content.pm.PackageParser.Package;
import android.content.pm.PackageParser.PackageLite;
import android.content.pm.PackageParser.PackageParserException;
+import android.content.pm.parsing.ParsedPackage;
import android.os.FileUtils;
import androidx.test.InstrumentationRegistry;
@@ -36,7 +36,6 @@ import androidx.test.runner.AndroidJUnit4;
import com.android.frameworks.coretests.R;
-import org.junit.After;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Rule;
@@ -95,13 +94,13 @@ public class DexMetadataHelperTest {
public void testParsePackageWithDmFileValid() throws IOException, PackageParserException {
copyApkToToTmpDir("install_split_base.apk", R.raw.install_split_base);
createDexMetadataFile("install_split_base.apk");
- Package pkg = new PackageParser().parsePackage(mTmpDir, 0 /* flags */);
+ ParsedPackage pkg = new PackageParser().parseParsedPackage(mTmpDir, 0 /* flags */, false);
Map<String, String> packageDexMetadata = DexMetadataHelper.getPackageDexMetadata(pkg);
assertEquals(1, packageDexMetadata.size());
- String baseDexMetadata = packageDexMetadata.get(pkg.baseCodePath);
+ String baseDexMetadata = packageDexMetadata.get(pkg.getBaseCodePath());
assertNotNull(baseDexMetadata);
- assertTrue(isDexMetadataForApk(baseDexMetadata, pkg.baseCodePath));
+ assertTrue(isDexMetadataForApk(baseDexMetadata, pkg.getBaseCodePath()));
}
@Test
@@ -111,17 +110,17 @@ public class DexMetadataHelperTest {
copyApkToToTmpDir("install_split_feature_a.apk", R.raw.install_split_feature_a);
createDexMetadataFile("install_split_base.apk");
createDexMetadataFile("install_split_feature_a.apk");
- Package pkg = new PackageParser().parsePackage(mTmpDir, 0 /* flags */);
+ ParsedPackage pkg = new PackageParser().parseParsedPackage(mTmpDir, 0 /* flags */, false);
Map<String, String> packageDexMetadata = DexMetadataHelper.getPackageDexMetadata(pkg);
assertEquals(2, packageDexMetadata.size());
- String baseDexMetadata = packageDexMetadata.get(pkg.baseCodePath);
+ String baseDexMetadata = packageDexMetadata.get(pkg.getBaseCodePath());
assertNotNull(baseDexMetadata);
- assertTrue(isDexMetadataForApk(baseDexMetadata, pkg.baseCodePath));
+ assertTrue(isDexMetadataForApk(baseDexMetadata, pkg.getBaseCodePath()));
- String splitDexMetadata = packageDexMetadata.get(pkg.splitCodePaths[0]);
+ String splitDexMetadata = packageDexMetadata.get(pkg.getSplitCodePaths()[0]);
assertNotNull(splitDexMetadata);
- assertTrue(isDexMetadataForApk(splitDexMetadata, pkg.splitCodePaths[0]));
+ assertTrue(isDexMetadataForApk(splitDexMetadata, pkg.getSplitCodePaths()[0]));
}
@Test
@@ -130,14 +129,14 @@ public class DexMetadataHelperTest {
copyApkToToTmpDir("install_split_base.apk", R.raw.install_split_base);
copyApkToToTmpDir("install_split_feature_a.apk", R.raw.install_split_feature_a);
createDexMetadataFile("install_split_feature_a.apk");
- Package pkg = new PackageParser().parsePackage(mTmpDir, 0 /* flags */);
+ ParsedPackage pkg = new PackageParser().parseParsedPackage(mTmpDir, 0 /* flags */, false);
Map<String, String> packageDexMetadata = DexMetadataHelper.getPackageDexMetadata(pkg);
assertEquals(1, packageDexMetadata.size());
- String splitDexMetadata = packageDexMetadata.get(pkg.splitCodePaths[0]);
+ String splitDexMetadata = packageDexMetadata.get(pkg.getSplitCodePaths()[0]);
assertNotNull(splitDexMetadata);
- assertTrue(isDexMetadataForApk(splitDexMetadata, pkg.splitCodePaths[0]));
+ assertTrue(isDexMetadataForApk(splitDexMetadata, pkg.getSplitCodePaths()[0]));
}
@Test
@@ -146,7 +145,8 @@ public class DexMetadataHelperTest {
File invalidDmFile = new File(mTmpDir, "install_split_base.dm");
Files.createFile(invalidDmFile.toPath());
try {
- PackageParser.Package pkg = new PackageParser().parsePackage(mTmpDir, 0 /* flags */);
+ ParsedPackage pkg = new PackageParser()
+ .parseParsedPackage(mTmpDir, 0 /* flags */, false);
DexMetadataHelper.validatePackageDexMetadata(pkg);
} catch (PackageParserException e) {
assertEquals(e.error, PackageManager.INSTALL_FAILED_BAD_DEX_METADATA);
@@ -163,7 +163,8 @@ public class DexMetadataHelperTest {
Files.createFile(invalidDmFile.toPath());
try {
- PackageParser.Package pkg = new PackageParser().parsePackage(mTmpDir, 0 /* flags */);
+ ParsedPackage pkg = new PackageParser()
+ .parseParsedPackage(mTmpDir, 0 /* flags */, false);
DexMetadataHelper.validatePackageDexMetadata(pkg);
} catch (PackageParserException e) {
assertEquals(e.error, PackageManager.INSTALL_FAILED_BAD_DEX_METADATA);
diff --git a/core/tests/coretests/src/android/content/pm/parsing/library/AndroidHidlUpdaterTest.java b/core/tests/coretests/src/android/content/pm/parsing/library/AndroidHidlUpdaterTest.java
new file mode 100644
index 000000000000..21479c096752
--- /dev/null
+++ b/core/tests/coretests/src/android/content/pm/parsing/library/AndroidHidlUpdaterTest.java
@@ -0,0 +1,191 @@
+/*
+ * Copyright (C) 2019 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 android.content.pm.parsing.library;
+
+import static android.content.pm.parsing.library.SharedLibraryNames.ANDROID_HIDL_BASE;
+import static android.content.pm.parsing.library.SharedLibraryNames.ANDROID_HIDL_MANAGER;
+
+import android.content.pm.parsing.AndroidPackage;
+import android.content.pm.parsing.PackageImpl;
+import android.content.pm.parsing.ParsedPackage;
+import android.os.Build;
+
+import androidx.test.filters.SmallTest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/**
+ * Test for {@link AndroidHidlUpdater}
+ */
+@SmallTest
+@RunWith(JUnit4.class)
+public class AndroidHidlUpdaterTest extends PackageSharedLibraryUpdaterTest {
+
+ private static final String OTHER_LIBRARY = "other.library";
+
+ @Test
+ public void targeted_at_P() {
+ ParsedPackage before = PackageImpl.forParsing(PACKAGE_NAME)
+ .setTargetSdkVersion(Build.VERSION_CODES.P)
+ .hideAsParsed();
+
+ AndroidPackage after = PackageImpl.forParsing(PACKAGE_NAME)
+ .setTargetSdkVersion(Build.VERSION_CODES.P)
+ .hideAsParsed()
+ .hideAsFinal();
+
+ // no change, not system
+ checkBackwardsCompatibility(before, after);
+ }
+
+ @Test
+ public void targeted_at_P_system() {
+ ParsedPackage before = PackageImpl.forParsing(PACKAGE_NAME)
+ .setTargetSdkVersion(Build.VERSION_CODES.P)
+ .hideAsParsed()
+ .setSystem(true);
+
+ // Should add both HIDL libraries
+ AndroidPackage after = PackageImpl.forParsing(PACKAGE_NAME)
+ .setTargetSdkVersion(Build.VERSION_CODES.P)
+ .addUsesLibrary(ANDROID_HIDL_MANAGER)
+ .addUsesLibrary(ANDROID_HIDL_BASE)
+ .hideAsParsed()
+ .setSystem(true)
+ .hideAsFinal();
+
+ checkBackwardsCompatibility(before, after);
+ }
+
+ @Test
+ public void targeted_at_P_not_empty_usesLibraries() {
+ ParsedPackage before = PackageImpl.forParsing(PACKAGE_NAME)
+ .setTargetSdkVersion(Build.VERSION_CODES.P)
+ .addUsesLibrary(OTHER_LIBRARY)
+ .hideAsParsed();
+
+ AndroidPackage after = PackageImpl.forParsing(PACKAGE_NAME)
+ .setTargetSdkVersion(Build.VERSION_CODES.P)
+ .addUsesLibrary(OTHER_LIBRARY)
+ .hideAsParsed()
+ .hideAsFinal();
+
+ // no change, not system
+ checkBackwardsCompatibility(before, after);
+ }
+
+ @Test
+ public void targeted_at_P_not_empty_usesLibraries_system() {
+ ParsedPackage before = PackageImpl.forParsing(PACKAGE_NAME)
+ .setTargetSdkVersion(Build.VERSION_CODES.P)
+ .addUsesLibrary(OTHER_LIBRARY)
+ .hideAsParsed()
+ .setSystem(true);
+
+ // The hidl jars should be added at the start of the list because it
+ // is not on the bootclasspath and the package targets pre-P.
+ AndroidPackage after = PackageImpl.forParsing(PACKAGE_NAME)
+ .setTargetSdkVersion(Build.VERSION_CODES.P)
+ .addUsesLibrary(ANDROID_HIDL_MANAGER)
+ .addUsesLibrary(ANDROID_HIDL_BASE)
+ .addUsesLibrary(OTHER_LIBRARY)
+ .hideAsParsed()
+ .setSystem(true)
+ .hideAsFinal();
+
+ checkBackwardsCompatibility(before, after);
+ }
+
+ @Test
+ public void targeted_at_P_in_usesLibraries() {
+ ParsedPackage before = PackageImpl.forParsing(PACKAGE_NAME)
+ .setTargetSdkVersion(Build.VERSION_CODES.P)
+ .addUsesLibrary(ANDROID_HIDL_MANAGER)
+ .addUsesLibrary(ANDROID_HIDL_BASE)
+ .hideAsParsed();
+
+ AndroidPackage after = PackageImpl.forParsing(PACKAGE_NAME)
+ .setTargetSdkVersion(Build.VERSION_CODES.P)
+ .hideAsParsed()
+ .hideAsFinal();
+
+ // Libraries are removed because they are not available for non-system apps
+ checkBackwardsCompatibility(before, after);
+ }
+
+ @Test
+ public void targeted_at_P_in_usesLibraries_system() {
+ ParsedPackage before = PackageImpl.forParsing(PACKAGE_NAME)
+ .setTargetSdkVersion(Build.VERSION_CODES.P)
+ .addUsesLibrary(ANDROID_HIDL_MANAGER)
+ .addUsesLibrary(ANDROID_HIDL_BASE)
+ .hideAsParsed()
+ .setSystem(true);
+
+ AndroidPackage after = PackageImpl.forParsing(PACKAGE_NAME)
+ .setTargetSdkVersion(Build.VERSION_CODES.P)
+ .addUsesLibrary(ANDROID_HIDL_MANAGER)
+ .addUsesLibrary(ANDROID_HIDL_BASE)
+ .hideAsParsed()
+ .setSystem(true)
+ .hideAsFinal();
+
+ // No change is required because the package explicitly requests the HIDL libraries
+ // and is targeted at the current version so does not need backwards compatibility.
+ checkBackwardsCompatibility(before, after);
+ }
+
+ @Test
+ public void in_usesLibraries() {
+ ParsedPackage before = PackageImpl.forParsing(PACKAGE_NAME)
+ .setTargetSdkVersion(Build.VERSION_CODES.CUR_DEVELOPMENT)
+ .addUsesLibrary(ANDROID_HIDL_BASE)
+ .hideAsParsed();
+
+ // Dependency is removed, it is not available.
+ AndroidPackage after = PackageImpl.forParsing(PACKAGE_NAME)
+ .setTargetSdkVersion(Build.VERSION_CODES.CUR_DEVELOPMENT)
+ .hideAsParsed()
+ .hideAsFinal();
+
+ // Libraries are removed because they are not available for apps targeting Q+
+ checkBackwardsCompatibility(before, after);
+ }
+
+ @Test
+ public void in_usesOptionalLibraries() {
+ ParsedPackage before = PackageImpl.forParsing(PACKAGE_NAME)
+ .setTargetSdkVersion(Build.VERSION_CODES.CUR_DEVELOPMENT)
+ .addUsesOptionalLibrary(ANDROID_HIDL_BASE)
+ .hideAsParsed();
+
+ // Dependency is removed, it is not available.
+ AndroidPackage after = PackageImpl.forParsing(PACKAGE_NAME)
+ .setTargetSdkVersion(Build.VERSION_CODES.CUR_DEVELOPMENT)
+ .hideAsParsed()
+ .hideAsFinal();
+
+ // Libraries are removed because they are not available for apps targeting Q+
+ checkBackwardsCompatibility(before, after);
+ }
+
+ private void checkBackwardsCompatibility(ParsedPackage before, AndroidPackage after) {
+ checkBackwardsCompatibility(before, after, AndroidHidlUpdater::new);
+ }
+}
diff --git a/core/tests/coretests/src/android/content/pm/parsing/library/AndroidTestBaseUpdaterTest.java b/core/tests/coretests/src/android/content/pm/parsing/library/AndroidTestBaseUpdaterTest.java
new file mode 100644
index 000000000000..65ae219058f4
--- /dev/null
+++ b/core/tests/coretests/src/android/content/pm/parsing/library/AndroidTestBaseUpdaterTest.java
@@ -0,0 +1,152 @@
+/*
+ * Copyright (C) 2019 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 android.content.pm.parsing.library;
+
+import static android.content.pm.parsing.library.SharedLibraryNames.ANDROID_TEST_BASE;
+
+import android.content.pm.OptionalClassRunner;
+import android.content.pm.parsing.AndroidPackage;
+import android.content.pm.parsing.PackageImpl;
+import android.content.pm.parsing.ParsedPackage;
+import android.os.Build;
+
+import androidx.test.filters.SmallTest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Test for {@link AndroidTestBaseUpdater}
+ */
+@SmallTest
+@RunWith(OptionalClassRunner.class)
+@OptionalClassRunner.OptionalClass("android.content.pm.parsing.library.AndroidTestBaseUpdater")
+public class AndroidTestBaseUpdaterTest extends PackageSharedLibraryUpdaterTest {
+
+ private static final String OTHER_LIBRARY = "other.library";
+
+ @Test
+ public void targeted_at_Q() {
+ ParsedPackage before = PackageImpl.forParsing(PACKAGE_NAME)
+ .setTargetSdkVersion(Build.VERSION_CODES.Q)
+ .hideAsParsed();
+
+ // Should add org.apache.http.legacy.
+ AndroidPackage after = PackageImpl.forParsing(PACKAGE_NAME)
+ .setTargetSdkVersion(Build.VERSION_CODES.Q)
+ .addUsesLibrary(ANDROID_TEST_BASE)
+ .hideAsParsed()
+ .hideAsFinal();
+
+ checkBackwardsCompatibility(before, after);
+ }
+
+ @Test
+ public void targeted_at_Q_not_empty_usesLibraries() {
+ ParsedPackage before = PackageImpl.forParsing(PACKAGE_NAME)
+ .setTargetSdkVersion(Build.VERSION_CODES.Q)
+ .addUsesLibrary(OTHER_LIBRARY)
+ .hideAsParsed();
+
+ // The org.apache.http.legacy jar should be added at the start of the list because it
+ // is not on the bootclasspath and the package targets pre-Q.
+ AndroidPackage after = PackageImpl.forParsing(PACKAGE_NAME)
+ .setTargetSdkVersion(Build.VERSION_CODES.Q)
+ .addUsesLibrary(ANDROID_TEST_BASE)
+ .addUsesLibrary(OTHER_LIBRARY)
+ .hideAsParsed()
+ .hideAsFinal();
+
+ checkBackwardsCompatibility(before, after);
+ }
+
+ @Test
+ public void targeted_at_Q_in_usesLibraries() {
+ ParsedPackage before = PackageImpl.forParsing(PACKAGE_NAME)
+ .setTargetSdkVersion(Build.VERSION_CODES.Q)
+ .addUsesLibrary(ANDROID_TEST_BASE)
+ .hideAsParsed();
+
+ AndroidPackage after = PackageImpl.forParsing(PACKAGE_NAME)
+ .setTargetSdkVersion(Build.VERSION_CODES.Q)
+ .addUsesLibrary(ANDROID_TEST_BASE)
+ .hideAsParsed()
+ .hideAsFinal();
+
+ // No change is required because although org.apache.http.legacy has been removed from
+ // the bootclasspath the package explicitly requests it.
+ checkBackwardsCompatibility(before, after);
+ }
+
+ @Test
+ public void targeted_at_Q_in_usesOptionalLibraries() {
+ ParsedPackage before = PackageImpl.forParsing(PACKAGE_NAME)
+ .setTargetSdkVersion(Build.VERSION_CODES.Q)
+ .addUsesOptionalLibrary(ANDROID_TEST_BASE)
+ .hideAsParsed();
+
+ AndroidPackage after = PackageImpl.forParsing(PACKAGE_NAME)
+ .setTargetSdkVersion(Build.VERSION_CODES.Q)
+ .addUsesOptionalLibrary(ANDROID_TEST_BASE)
+ .hideAsParsed()
+ .hideAsFinal();
+
+ // No change is required because although org.apache.http.legacy has been removed from
+ // the bootclasspath the package explicitly requests it.
+ checkBackwardsCompatibility(before, after);
+ }
+
+ @Test
+ public void in_usesLibraries() {
+ ParsedPackage before = PackageImpl.forParsing(PACKAGE_NAME)
+ .setTargetSdkVersion(Build.VERSION_CODES.CUR_DEVELOPMENT)
+ .addUsesLibrary(ANDROID_TEST_BASE)
+ .hideAsParsed();
+
+ AndroidPackage after = PackageImpl.forParsing(PACKAGE_NAME)
+ .setTargetSdkVersion(Build.VERSION_CODES.CUR_DEVELOPMENT)
+ .addUsesLibrary(ANDROID_TEST_BASE)
+ .hideAsParsed()
+ .hideAsFinal();
+
+ // No change is required because the package explicitly requests org.apache.http.legacy
+ // and is targeted at the current version so does not need backwards compatibility.
+ checkBackwardsCompatibility(before, after);
+ }
+
+ @Test
+ public void in_usesOptionalLibraries() {
+ ParsedPackage before = PackageImpl.forParsing(PACKAGE_NAME)
+ .setTargetSdkVersion(Build.VERSION_CODES.CUR_DEVELOPMENT)
+ .addUsesOptionalLibrary(ANDROID_TEST_BASE)
+ .hideAsParsed();
+
+ AndroidPackage after = PackageImpl.forParsing(PACKAGE_NAME)
+ .setTargetSdkVersion(Build.VERSION_CODES.CUR_DEVELOPMENT)
+ .addUsesOptionalLibrary(ANDROID_TEST_BASE)
+ .hideAsParsed()
+ .hideAsFinal();
+
+ // No change is required because the package explicitly requests org.apache.http.legacy
+ // and is targeted at the current version so does not need backwards compatibility.
+ checkBackwardsCompatibility(before, after);
+ }
+
+ private void checkBackwardsCompatibility(ParsedPackage before, AndroidPackage after) {
+ checkBackwardsCompatibility(before, after, AndroidTestBaseUpdater::new);
+ }
+}
diff --git a/core/tests/coretests/src/android/content/pm/parsing/library/AndroidTestRunnerSplitUpdaterTest.java b/core/tests/coretests/src/android/content/pm/parsing/library/AndroidTestRunnerSplitUpdaterTest.java
new file mode 100644
index 000000000000..38755b9aa965
--- /dev/null
+++ b/core/tests/coretests/src/android/content/pm/parsing/library/AndroidTestRunnerSplitUpdaterTest.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2019 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 android.content.pm.parsing.library;
+
+import static android.content.pm.parsing.library.SharedLibraryNames.ANDROID_TEST_MOCK;
+import static android.content.pm.parsing.library.SharedLibraryNames.ANDROID_TEST_RUNNER;
+
+import android.content.pm.parsing.AndroidPackage;
+import android.content.pm.parsing.PackageImpl;
+import android.content.pm.parsing.ParsedPackage;
+import android.content.pm.parsing.library.PackageBackwardCompatibility.AndroidTestRunnerSplitUpdater;
+import android.os.Build;
+
+import androidx.test.filters.SmallTest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/**
+ * Test for {@link AndroidTestRunnerSplitUpdater}
+ */
+@SmallTest
+@RunWith(JUnit4.class)
+public class AndroidTestRunnerSplitUpdaterTest extends PackageSharedLibraryUpdaterTest {
+
+ @Test
+ public void android_test_runner_in_usesOptionalLibraries() {
+ ParsedPackage before = PackageImpl.forParsing(PACKAGE_NAME)
+ .setTargetSdkVersion(Build.VERSION_CODES.CUR_DEVELOPMENT)
+ .addUsesOptionalLibrary(ANDROID_TEST_RUNNER)
+ .hideAsParsed();
+
+ AndroidPackage after = PackageImpl.forParsing(PACKAGE_NAME)
+ .setTargetSdkVersion(Build.VERSION_CODES.CUR_DEVELOPMENT)
+ .addUsesOptionalLibrary(ANDROID_TEST_MOCK)
+ .addUsesOptionalLibrary(ANDROID_TEST_RUNNER)
+ .hideAsParsed()
+ .hideAsFinal();
+
+ checkBackwardsCompatibility(before, after);
+ }
+
+ @Test
+ public void android_test_runner_in_usesLibraries_android_test_mock_in_usesOptionalLibraries() {
+ ParsedPackage before = PackageImpl.forParsing(PACKAGE_NAME)
+ .setTargetSdkVersion(Build.VERSION_CODES.CUR_DEVELOPMENT)
+ .addUsesLibrary(ANDROID_TEST_RUNNER)
+ .addUsesOptionalLibrary(ANDROID_TEST_MOCK)
+ .hideAsParsed();
+
+ AndroidPackage after = PackageImpl.forParsing(PACKAGE_NAME)
+ .setTargetSdkVersion(Build.VERSION_CODES.CUR_DEVELOPMENT)
+ .addUsesLibrary(ANDROID_TEST_RUNNER)
+ .addUsesOptionalLibrary(ANDROID_TEST_MOCK)
+ .hideAsParsed()
+ .hideAsFinal();
+
+ checkBackwardsCompatibility(before, after);
+ }
+
+ private void checkBackwardsCompatibility(ParsedPackage before, AndroidPackage after) {
+ checkBackwardsCompatibility(before, after, AndroidTestRunnerSplitUpdater::new);
+ }
+}
diff --git a/core/tests/coretests/src/android/content/pm/parsing/library/OrgApacheHttpLegacyUpdaterTest.java b/core/tests/coretests/src/android/content/pm/parsing/library/OrgApacheHttpLegacyUpdaterTest.java
new file mode 100644
index 000000000000..4c7899b47164
--- /dev/null
+++ b/core/tests/coretests/src/android/content/pm/parsing/library/OrgApacheHttpLegacyUpdaterTest.java
@@ -0,0 +1,152 @@
+/*
+ * Copyright (C) 2019 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 android.content.pm.parsing.library;
+
+import static android.content.pm.parsing.library.SharedLibraryNames.ORG_APACHE_HTTP_LEGACY;
+
+import android.content.pm.OptionalClassRunner;
+import android.content.pm.parsing.AndroidPackage;
+import android.content.pm.parsing.PackageImpl;
+import android.content.pm.parsing.ParsedPackage;
+import android.os.Build;
+
+import androidx.test.filters.SmallTest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ * Test for {@link OrgApacheHttpLegacyUpdater}
+ */
+@SmallTest
+@RunWith(OptionalClassRunner.class)
+@OptionalClassRunner.OptionalClass("android.content.pm.parsing.library.OrgApacheHttpLegacyUpdater")
+public class OrgApacheHttpLegacyUpdaterTest extends PackageSharedLibraryUpdaterTest {
+
+ private static final String OTHER_LIBRARY = "other.library";
+
+ @Test
+ public void targeted_at_O() {
+ ParsedPackage before = PackageImpl.forParsing(PACKAGE_NAME)
+ .setTargetSdkVersion(Build.VERSION_CODES.O)
+ .hideAsParsed();
+
+ // Should add org.apache.http.legacy.
+ AndroidPackage after = PackageImpl.forParsing(PACKAGE_NAME)
+ .setTargetSdkVersion(Build.VERSION_CODES.O)
+ .addUsesLibrary(ORG_APACHE_HTTP_LEGACY)
+ .hideAsParsed()
+ .hideAsFinal();
+
+ checkBackwardsCompatibility(before, after);
+ }
+
+ @Test
+ public void targeted_at_O_not_empty_usesLibraries() {
+ ParsedPackage before = PackageImpl.forParsing(PACKAGE_NAME)
+ .setTargetSdkVersion(Build.VERSION_CODES.O)
+ .addUsesLibrary(OTHER_LIBRARY)
+ .hideAsParsed();
+
+ // The org.apache.http.legacy jar should be added at the start of the list because it
+ // is not on the bootclasspath and the package targets pre-P.
+ AndroidPackage after = PackageImpl.forParsing(PACKAGE_NAME)
+ .setTargetSdkVersion(Build.VERSION_CODES.O)
+ .addUsesLibrary(ORG_APACHE_HTTP_LEGACY)
+ .addUsesLibrary(OTHER_LIBRARY)
+ .hideAsParsed()
+ .hideAsFinal();
+
+ checkBackwardsCompatibility(before, after);
+ }
+
+ @Test
+ public void targeted_at_O_in_usesLibraries() {
+ ParsedPackage before = PackageImpl.forParsing(PACKAGE_NAME)
+ .setTargetSdkVersion(Build.VERSION_CODES.O)
+ .addUsesLibrary(ORG_APACHE_HTTP_LEGACY)
+ .hideAsParsed();
+
+ AndroidPackage after = PackageImpl.forParsing(PACKAGE_NAME)
+ .setTargetSdkVersion(Build.VERSION_CODES.O)
+ .addUsesLibrary(ORG_APACHE_HTTP_LEGACY)
+ .hideAsParsed()
+ .hideAsFinal();
+
+ // No change is required because although org.apache.http.legacy has been removed from
+ // the bootclasspath the package explicitly requests it.
+ checkBackwardsCompatibility(before, after);
+ }
+
+ @Test
+ public void targeted_at_O_in_usesOptionalLibraries() {
+ ParsedPackage before = PackageImpl.forParsing(PACKAGE_NAME)
+ .setTargetSdkVersion(Build.VERSION_CODES.O)
+ .addUsesOptionalLibrary(ORG_APACHE_HTTP_LEGACY)
+ .hideAsParsed();
+
+ AndroidPackage after = PackageImpl.forParsing(PACKAGE_NAME)
+ .setTargetSdkVersion(Build.VERSION_CODES.O)
+ .addUsesOptionalLibrary(ORG_APACHE_HTTP_LEGACY)
+ .hideAsParsed()
+ .hideAsFinal();
+
+ // No change is required because although org.apache.http.legacy has been removed from
+ // the bootclasspath the package explicitly requests it.
+ checkBackwardsCompatibility(before, after);
+ }
+
+ @Test
+ public void in_usesLibraries() {
+ ParsedPackage before = PackageImpl.forParsing(PACKAGE_NAME)
+ .setTargetSdkVersion(Build.VERSION_CODES.CUR_DEVELOPMENT)
+ .addUsesLibrary(ORG_APACHE_HTTP_LEGACY)
+ .hideAsParsed();
+
+ AndroidPackage after = PackageImpl.forParsing(PACKAGE_NAME)
+ .setTargetSdkVersion(Build.VERSION_CODES.CUR_DEVELOPMENT)
+ .addUsesLibrary(ORG_APACHE_HTTP_LEGACY)
+ .hideAsParsed()
+ .hideAsFinal();
+
+ // No change is required because the package explicitly requests org.apache.http.legacy
+ // and is targeted at the current version so does not need backwards compatibility.
+ checkBackwardsCompatibility(before, after);
+ }
+
+ @Test
+ public void in_usesOptionalLibraries() {
+ ParsedPackage before = PackageImpl.forParsing(PACKAGE_NAME)
+ .setTargetSdkVersion(Build.VERSION_CODES.CUR_DEVELOPMENT)
+ .addUsesOptionalLibrary(ORG_APACHE_HTTP_LEGACY)
+ .hideAsParsed();
+
+ AndroidPackage after = PackageImpl.forParsing(PACKAGE_NAME)
+ .setTargetSdkVersion(Build.VERSION_CODES.CUR_DEVELOPMENT)
+ .addUsesOptionalLibrary(ORG_APACHE_HTTP_LEGACY)
+ .hideAsParsed()
+ .hideAsFinal();
+
+ // No change is required because the package explicitly requests org.apache.http.legacy
+ // and is targeted at the current version so does not need backwards compatibility.
+ checkBackwardsCompatibility(before, after);
+ }
+
+ private void checkBackwardsCompatibility(ParsedPackage before, AndroidPackage after) {
+ checkBackwardsCompatibility(before, after, OrgApacheHttpLegacyUpdater::new);
+ }
+}
diff --git a/core/tests/coretests/src/android/content/pm/PackageBackwardCompatibilityTest.java b/core/tests/coretests/src/android/content/pm/parsing/library/PackageBackwardCompatibilityTest.java
index ad9814bd01b1..00d468de4ee4 100644
--- a/core/tests/coretests/src/android/content/pm/PackageBackwardCompatibilityTest.java
+++ b/core/tests/coretests/src/android/content/pm/parsing/library/PackageBackwardCompatibilityTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2017 The Android Open Source Project
+ * Copyright (C) 2019 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.
@@ -14,15 +14,18 @@
* limitations under the License.
*/
-package android.content.pm;
+package android.content.pm.parsing.library;
-import static android.content.pm.PackageBuilder.builder;
-import static android.content.pm.SharedLibraryNames.ANDROID_TEST_BASE;
-import static android.content.pm.SharedLibraryNames.ANDROID_TEST_MOCK;
-import static android.content.pm.SharedLibraryNames.ANDROID_TEST_RUNNER;
-import static android.content.pm.SharedLibraryNames.ORG_APACHE_HTTP_LEGACY;
+import static android.content.pm.parsing.library.SharedLibraryNames.ANDROID_TEST_BASE;
+import static android.content.pm.parsing.library.SharedLibraryNames.ANDROID_TEST_MOCK;
+import static android.content.pm.parsing.library.SharedLibraryNames.ANDROID_TEST_RUNNER;
+import static android.content.pm.parsing.library.SharedLibraryNames.ORG_APACHE_HTTP_LEGACY;
-import android.content.pm.PackageBackwardCompatibility.RemoveUnnecessaryAndroidTestBaseLibrary;
+import android.content.pm.parsing.AndroidPackage;
+import android.content.pm.parsing.PackageImpl;
+import android.content.pm.parsing.ParsedPackage;
+import android.content.pm.parsing.ParsingPackage;
+import android.content.pm.parsing.library.PackageBackwardCompatibility.RemoveUnnecessaryAndroidTestBaseLibrary;
import android.os.Build;
import androidx.test.filters.SmallTest;
@@ -32,17 +35,20 @@ import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;
-import java.util.ArrayList;
-import java.util.List;
-
@SmallTest
@RunWith(JUnit4.class)
public class PackageBackwardCompatibilityTest extends PackageSharedLibraryUpdaterTest {
@Test
public void null_usesLibraries_and_usesOptionalLibraries() {
- PackageBuilder before = builder();
- PackageBuilder after = builder();
+ ParsedPackage before = PackageImpl.forParsing(PACKAGE_NAME)
+ .setTargetSdkVersion(Build.VERSION_CODES.CUR_DEVELOPMENT)
+ .hideAsParsed();
+
+ AndroidPackage after = PackageImpl.forParsing(PACKAGE_NAME)
+ .setTargetSdkVersion(Build.VERSION_CODES.CUR_DEVELOPMENT)
+ .hideAsParsed()
+ .hideAsFinal();
checkBackwardsCompatibility(before, after);
}
@@ -68,20 +74,21 @@ public class PackageBackwardCompatibilityTest extends PackageSharedLibraryUpdate
*/
@Test
public void targeted_at_O() {
- PackageBuilder before = builder()
- .targetSdkVersion(Build.VERSION_CODES.O);
+ ParsedPackage before = PackageImpl.forParsing(PACKAGE_NAME)
+ .setTargetSdkVersion(Build.VERSION_CODES.CUR_DEVELOPMENT)
+ .setTargetSdkVersion(Build.VERSION_CODES.O)
+ .hideAsParsed();
+
+ ParsingPackage after = PackageImpl.forParsing(PACKAGE_NAME)
+ .setTargetSdkVersion(Build.VERSION_CODES.CUR_DEVELOPMENT)
+ .setTargetSdkVersion(Build.VERSION_CODES.O);
- List<String> expected = new ArrayList<>();
if (!PackageBackwardCompatibility.bootClassPathContainsATB()) {
- expected.add(ANDROID_TEST_BASE);
+ after.addUsesLibrary(ANDROID_TEST_BASE);
}
- expected.add(ORG_APACHE_HTTP_LEGACY);
-
- PackageBuilder after = builder()
- .targetSdkVersion(Build.VERSION_CODES.O)
- .requiredLibraries(expected);
+ after.addUsesLibrary(ORG_APACHE_HTTP_LEGACY);
- checkBackwardsCompatibility(before, after);
+ checkBackwardsCompatibility(before, after.hideAsParsed().hideAsFinal());
}
/**
@@ -98,12 +105,17 @@ public class PackageBackwardCompatibilityTest extends PackageSharedLibraryUpdate
+ ANDROID_TEST_BASE + " is on the bootclasspath",
PackageBackwardCompatibility.bootClassPathContainsATB());
- PackageBuilder before = builder()
- .requiredLibraries(ANDROID_TEST_BASE);
+ ParsedPackage before = PackageImpl.forParsing(PACKAGE_NAME)
+ .setTargetSdkVersion(Build.VERSION_CODES.CUR_DEVELOPMENT)
+ .addUsesLibrary(ANDROID_TEST_BASE)
+ .hideAsParsed();
// android.test.base should be removed from the libraries because it is provided
// on the bootclasspath and providing both increases start up cost unnecessarily.
- PackageBuilder after = builder();
+ AndroidPackage after = PackageImpl.forParsing(PACKAGE_NAME)
+ .setTargetSdkVersion(Build.VERSION_CODES.CUR_DEVELOPMENT)
+ .hideAsParsed()
+ .hideAsFinal();
checkBackwardsCompatibility(before, after);
}
@@ -117,22 +129,23 @@ public class PackageBackwardCompatibilityTest extends PackageSharedLibraryUpdate
*/
@Test
public void android_test_runner_in_usesLibraries() {
- PackageBuilder before = builder().requiredLibraries(ANDROID_TEST_RUNNER);
+ ParsedPackage before = PackageImpl.forParsing(PACKAGE_NAME)
+ .setTargetSdkVersion(Build.VERSION_CODES.CUR_DEVELOPMENT)
+ .addUsesLibrary(ANDROID_TEST_RUNNER)
+ .hideAsParsed();
- List<String> expected = new ArrayList<>();
+ ParsingPackage after = PackageImpl.forParsing(PACKAGE_NAME)
+ .setTargetSdkVersion(Build.VERSION_CODES.CUR_DEVELOPMENT);
if (!PackageBackwardCompatibility.bootClassPathContainsATB()) {
- expected.add(ANDROID_TEST_BASE);
+ after.addUsesLibrary(ANDROID_TEST_BASE);
}
- expected.add(ANDROID_TEST_MOCK);
- expected.add(ANDROID_TEST_RUNNER);
-
- PackageBuilder after = builder()
- .requiredLibraries(expected);
+ after.addUsesLibrary(ANDROID_TEST_MOCK);
+ after.addUsesLibrary(ANDROID_TEST_RUNNER);
- checkBackwardsCompatibility(before, after);
+ checkBackwardsCompatibility(before, after.hideAsParsed().hideAsFinal());
}
- private void checkBackwardsCompatibility(PackageBuilder before, PackageBuilder after) {
+ private void checkBackwardsCompatibility(ParsedPackage before, AndroidPackage after) {
checkBackwardsCompatibility(before, after, PackageBackwardCompatibility::getInstance);
}
}
diff --git a/core/tests/coretests/src/android/content/pm/parsing/library/PackageSharedLibraryUpdaterTest.java b/core/tests/coretests/src/android/content/pm/parsing/library/PackageSharedLibraryUpdaterTest.java
new file mode 100644
index 000000000000..e7a80e1a7618
--- /dev/null
+++ b/core/tests/coretests/src/android/content/pm/parsing/library/PackageSharedLibraryUpdaterTest.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2019 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 android.content.pm.parsing.library;
+
+import static org.junit.Assert.assertEquals;
+
+import android.content.pm.parsing.AndroidPackage;
+import android.content.pm.parsing.ParsedPackage;
+
+import java.util.function.Supplier;
+
+/**
+ * Helper for classes that test {@link PackageSharedLibraryUpdater}.
+ */
+abstract class PackageSharedLibraryUpdaterTest {
+
+ protected static final String PACKAGE_NAME = "org.package.name";
+
+ static void checkBackwardsCompatibility(ParsedPackage before, AndroidPackage after,
+ Supplier<PackageSharedLibraryUpdater> updaterSupplier) {
+ updaterSupplier.get().updatePackage(before);
+ check(before.hideAsFinal(), after);
+ }
+
+ private static void check(AndroidPackage before, AndroidPackage after) {
+ assertEquals("targetSdkVersion should not be changed",
+ after.getTargetSdkVersion(),
+ before.getTargetSdkVersion());
+ assertEquals("usesLibraries not updated correctly",
+ after.getUsesLibraries(),
+ before.getUsesLibraries());
+ assertEquals("usesOptionalLibraries not updated correctly",
+ after.getUsesOptionalLibraries(),
+ before.getUsesOptionalLibraries());
+ }
+}
diff --git a/core/tests/coretests/src/android/content/pm/parsing/library/RemoveUnnecessaryAndroidTestBaseLibraryTest.java b/core/tests/coretests/src/android/content/pm/parsing/library/RemoveUnnecessaryAndroidTestBaseLibraryTest.java
new file mode 100644
index 000000000000..fd3ba2bd0c68
--- /dev/null
+++ b/core/tests/coretests/src/android/content/pm/parsing/library/RemoveUnnecessaryAndroidTestBaseLibraryTest.java
@@ -0,0 +1,169 @@
+/*
+ * Copyright (C) 2019 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 android.content.pm.parsing.library;
+
+import static android.content.pm.parsing.library.SharedLibraryNames.ANDROID_TEST_BASE;
+
+import android.content.pm.parsing.AndroidPackage;
+import android.content.pm.parsing.PackageImpl;
+import android.content.pm.parsing.ParsedPackage;
+import android.content.pm.parsing.library.PackageBackwardCompatibility.RemoveUnnecessaryAndroidTestBaseLibrary;
+import android.os.Build;
+
+import androidx.test.filters.SmallTest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/**
+ * Test for {@link RemoveUnnecessaryAndroidTestBaseLibrary}
+ */
+@SmallTest
+@RunWith(JUnit4.class)
+public class RemoveUnnecessaryAndroidTestBaseLibraryTest
+ extends PackageSharedLibraryUpdaterTest {
+
+ private static final String OTHER_LIBRARY = "other.library";
+
+ @Test
+ public void targeted_at_O() {
+ ParsedPackage before = PackageImpl.forParsing(PACKAGE_NAME)
+ .setTargetSdkVersion(Build.VERSION_CODES.O)
+ .hideAsParsed();
+
+ AndroidPackage after = PackageImpl.forParsing(PACKAGE_NAME)
+ .setTargetSdkVersion(Build.VERSION_CODES.O)
+ .hideAsParsed()
+ .hideAsFinal();
+
+ // No change required.
+ checkBackwardsCompatibility(before, after);
+ }
+
+ @Test
+ public void targeted_at_O_not_empty_usesLibraries() {
+ ParsedPackage before = PackageImpl.forParsing(PACKAGE_NAME)
+ .setTargetSdkVersion(Build.VERSION_CODES.O)
+ .addUsesLibrary(OTHER_LIBRARY)
+ .hideAsParsed();
+
+ AndroidPackage after = PackageImpl.forParsing(PACKAGE_NAME)
+ .setTargetSdkVersion(Build.VERSION_CODES.O)
+ .addUsesLibrary(OTHER_LIBRARY)
+ .hideAsParsed()
+ .hideAsFinal();
+
+ // No change required.
+ checkBackwardsCompatibility(before, after);
+ }
+
+ @Test
+ public void targeted_at_O_in_usesLibraries() {
+ ParsedPackage before = PackageImpl.forParsing(PACKAGE_NAME)
+ .setTargetSdkVersion(Build.VERSION_CODES.O)
+ .addUsesLibrary(ANDROID_TEST_BASE)
+ .hideAsParsed();
+
+ // android.test.base should be removed from the libraries because it is provided
+ // on the bootclasspath and providing both increases start up cost unnecessarily.
+ AndroidPackage after = PackageImpl.forParsing(PACKAGE_NAME)
+ .setTargetSdkVersion(Build.VERSION_CODES.O)
+ .hideAsParsed()
+ .hideAsFinal();
+
+ checkBackwardsCompatibility(before, after);
+ }
+
+ @Test
+ public void targeted_at_O_in_usesOptionalLibraries() {
+ ParsedPackage before = PackageImpl.forParsing(PACKAGE_NAME)
+ .setTargetSdkVersion(Build.VERSION_CODES.O)
+ .addUsesOptionalLibrary(ANDROID_TEST_BASE)
+ .hideAsParsed();
+
+ // android.test.base should be removed from the libraries because it is provided
+ // on the bootclasspath and providing both increases start up cost unnecessarily.
+ AndroidPackage after = PackageImpl.forParsing(PACKAGE_NAME)
+ .setTargetSdkVersion(Build.VERSION_CODES.O)
+ .hideAsParsed()
+ .hideAsFinal();
+
+ checkBackwardsCompatibility(before, after);
+ }
+
+ @Test
+ public void in_usesLibraries() {
+ ParsedPackage before = PackageImpl.forParsing(PACKAGE_NAME)
+ .addUsesLibrary(ANDROID_TEST_BASE)
+ .hideAsParsed();
+
+ // android.test.base should be removed from the libraries because it is provided
+ // on the bootclasspath and providing both increases start up cost unnecessarily.
+ AndroidPackage after = PackageImpl.forParsing(PACKAGE_NAME)
+ .hideAsParsed()
+ .hideAsFinal();
+
+ checkBackwardsCompatibility(before, after);
+ }
+
+ @Test
+ public void in_usesOptionalLibraries() {
+ ParsedPackage before = PackageImpl.forParsing(PACKAGE_NAME)
+ .setTargetSdkVersion(Build.VERSION_CODES.CUR_DEVELOPMENT)
+ .addUsesOptionalLibrary(ANDROID_TEST_BASE)
+ .hideAsParsed();
+
+ // android.test.base should be removed from the libraries because it is provided
+ // on the bootclasspath and providing both increases start up cost unnecessarily.
+ AndroidPackage after = PackageImpl.forParsing(PACKAGE_NAME)
+ .setTargetSdkVersion(Build.VERSION_CODES.CUR_DEVELOPMENT)
+ .hideAsParsed()
+ .hideAsFinal();
+
+ checkBackwardsCompatibility(before, after);
+ }
+
+ @Test
+ public void in_bothLibraries() {
+ ParsedPackage before = PackageImpl.forParsing(PACKAGE_NAME)
+ .setTargetSdkVersion(Build.VERSION_CODES.CUR_DEVELOPMENT)
+ .addUsesLibrary(ANDROID_TEST_BASE)
+ .addUsesOptionalLibrary(ANDROID_TEST_BASE)
+ .hideAsParsed();
+
+ // android.test.base should be removed from the libraries because it is provided
+ // on the bootclasspath and providing both increases start up cost unnecessarily.
+ AndroidPackage after = PackageImpl.forParsing(PACKAGE_NAME)
+ .setTargetSdkVersion(Build.VERSION_CODES.CUR_DEVELOPMENT)
+ .hideAsParsed()
+ .hideAsFinal();
+
+ checkBackwardsCompatibility(before, after);
+ }
+
+ private void checkBackwardsCompatibility(ParsedPackage before, AndroidPackage after) {
+ // TODO(b/72538146) - Cannot use constructor reference here because it is also used in
+ // PackageBackwardCompatibility and that seems to create a package-private lambda in
+ // android.content.pm which this then tries to reuse but fails because it cannot access
+ // package-private classes/members because the test is loaded by a different ClassLoader
+ // than the lambda.
+ checkBackwardsCompatibility(before, after,
+ () -> new RemoveUnnecessaryAndroidTestBaseLibrary());
+ }
+
+}
diff --git a/core/tests/coretests/src/android/content/pm/parsing/library/RemoveUnnecessaryOrgApacheHttpLegacyLibraryTest.java b/core/tests/coretests/src/android/content/pm/parsing/library/RemoveUnnecessaryOrgApacheHttpLegacyLibraryTest.java
new file mode 100644
index 000000000000..d3494d93ae52
--- /dev/null
+++ b/core/tests/coretests/src/android/content/pm/parsing/library/RemoveUnnecessaryOrgApacheHttpLegacyLibraryTest.java
@@ -0,0 +1,168 @@
+/*
+ * Copyright (C) 2019 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 android.content.pm.parsing.library;
+
+import static android.content.pm.parsing.library.SharedLibraryNames.ORG_APACHE_HTTP_LEGACY;
+
+import android.content.pm.parsing.AndroidPackage;
+import android.content.pm.parsing.PackageImpl;
+import android.content.pm.parsing.ParsedPackage;
+import android.content.pm.parsing.library.PackageBackwardCompatibility.RemoveUnnecessaryOrgApacheHttpLegacyLibrary;
+import android.os.Build;
+
+import androidx.test.filters.SmallTest;
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.JUnit4;
+
+/**
+ * Test for {@link RemoveUnnecessaryOrgApacheHttpLegacyLibrary}
+ */
+@SmallTest
+@RunWith(JUnit4.class)
+public class RemoveUnnecessaryOrgApacheHttpLegacyLibraryTest
+ extends PackageSharedLibraryUpdaterTest {
+
+ private static final String OTHER_LIBRARY = "other.library";
+
+ @Test
+ public void targeted_at_O() {
+ ParsedPackage before = PackageImpl.forParsing(PACKAGE_NAME)
+ .setTargetSdkVersion(Build.VERSION_CODES.O)
+ .hideAsParsed();
+
+ AndroidPackage after = PackageImpl.forParsing(PACKAGE_NAME)
+ .setTargetSdkVersion(Build.VERSION_CODES.O)
+ .hideAsParsed()
+ .hideAsFinal();
+
+ // No change required.
+ checkBackwardsCompatibility(before, after);
+ }
+
+ @Test
+ public void targeted_at_O_not_empty_usesLibraries() {
+ ParsedPackage before = PackageImpl.forParsing(PACKAGE_NAME)
+ .setTargetSdkVersion(Build.VERSION_CODES.O)
+ .addUsesLibrary(OTHER_LIBRARY)
+ .hideAsParsed();
+
+ AndroidPackage after = PackageImpl.forParsing(PACKAGE_NAME)
+ .setTargetSdkVersion(Build.VERSION_CODES.O)
+ .addUsesLibrary(OTHER_LIBRARY)
+ .hideAsParsed()
+ .hideAsFinal();
+
+ // No change required.
+ checkBackwardsCompatibility(before, after);
+ }
+
+ @Test
+ public void targeted_at_O_in_usesLibraries() {
+ ParsedPackage before = PackageImpl.forParsing(PACKAGE_NAME)
+ .setTargetSdkVersion(Build.VERSION_CODES.O)
+ .addUsesLibrary(ORG_APACHE_HTTP_LEGACY)
+ .hideAsParsed();
+
+ // org.apache.http.legacy should be removed from the libraries because it is provided
+ // on the bootclasspath and providing both increases start up cost unnecessarily.
+ AndroidPackage after = PackageImpl.forParsing(PACKAGE_NAME)
+ .setTargetSdkVersion(Build.VERSION_CODES.O)
+ .hideAsParsed()
+ .hideAsFinal();
+
+ checkBackwardsCompatibility(before, after);
+ }
+
+ @Test
+ public void targeted_at_O_in_usesOptionalLibraries() {
+ ParsedPackage before = PackageImpl.forParsing(PACKAGE_NAME)
+ .setTargetSdkVersion(Build.VERSION_CODES.O)
+ .addUsesOptionalLibrary(ORG_APACHE_HTTP_LEGACY)
+ .hideAsParsed();
+
+ // org.apache.http.legacy should be removed from the libraries because it is provided
+ // on the bootclasspath and providing both increases start up cost unnecessarily.
+ AndroidPackage after = PackageImpl.forParsing(PACKAGE_NAME)
+ .setTargetSdkVersion(Build.VERSION_CODES.O)
+ .hideAsParsed()
+ .hideAsFinal();
+
+ checkBackwardsCompatibility(before, after);
+ }
+
+ @Test
+ public void in_usesLibraries() {
+ ParsedPackage before = PackageImpl.forParsing(PACKAGE_NAME)
+ .setTargetSdkVersion(Build.VERSION_CODES.CUR_DEVELOPMENT)
+ .addUsesLibrary(ORG_APACHE_HTTP_LEGACY)
+ .hideAsParsed();
+
+ // org.apache.http.legacy should be removed from the libraries because it is provided
+ // on the bootclasspath and providing both increases start up cost unnecessarily.
+ AndroidPackage after = PackageImpl.forParsing(PACKAGE_NAME)
+ .hideAsParsed()
+ .hideAsFinal();
+
+ checkBackwardsCompatibility(before, after);
+ }
+
+ @Test
+ public void in_usesOptionalLibraries() {
+ ParsedPackage before = PackageImpl.forParsing(PACKAGE_NAME)
+ .setTargetSdkVersion(Build.VERSION_CODES.CUR_DEVELOPMENT)
+ .addUsesOptionalLibrary(ORG_APACHE_HTTP_LEGACY)
+ .hideAsParsed();
+
+ // org.apache.http.legacy should be removed from the libraries because it is provided
+ // on the bootclasspath and providing both increases start up cost unnecessarily.
+ AndroidPackage after = PackageImpl.forParsing(PACKAGE_NAME)
+ .hideAsParsed()
+ .hideAsFinal();
+
+ checkBackwardsCompatibility(before, after);
+ }
+
+ @Test
+ public void in_bothLibraries() {
+ ParsedPackage before = PackageImpl.forParsing(PACKAGE_NAME)
+ .setTargetSdkVersion(Build.VERSION_CODES.CUR_DEVELOPMENT)
+ .addUsesLibrary(ORG_APACHE_HTTP_LEGACY)
+ .addUsesOptionalLibrary(ORG_APACHE_HTTP_LEGACY)
+ .hideAsParsed();
+
+ // org.apache.http.legacy should be removed from the libraries because it is provided
+ // on the bootclasspath and providing both increases start up cost unnecessarily.
+ AndroidPackage after = PackageImpl.forParsing(PACKAGE_NAME)
+ .setTargetSdkVersion(Build.VERSION_CODES.CUR_DEVELOPMENT)
+ .hideAsParsed()
+ .hideAsFinal();
+
+ checkBackwardsCompatibility(before, after);
+ }
+
+ private void checkBackwardsCompatibility(ParsedPackage before, AndroidPackage after) {
+ // TODO(b/72538146) - Cannot use constructor reference here because it is also used in
+ // PackageBackwardCompatibility and that seems to create a package-private lambda in
+ // android.content.pm which this then tries to reuse but fails because it cannot access
+ // package-private classes/members because the test is loaded by a different ClassLoader
+ // than the lambda.
+ checkBackwardsCompatibility(before, after,
+ () -> new RemoveUnnecessaryOrgApacheHttpLegacyLibrary());
+ }
+}
diff --git a/services/core/java/com/android/server/pm/AppsFilter.java b/services/core/java/com/android/server/pm/AppsFilter.java
index 61ea84f9dc7f..86c709e0d208 100644
--- a/services/core/java/com/android/server/pm/AppsFilter.java
+++ b/services/core/java/com/android/server/pm/AppsFilter.java
@@ -16,8 +16,6 @@
package com.android.server.pm;
-import static android.content.pm.PackageParser.Component;
-import static android.content.pm.PackageParser.IntentInfo;
import static android.provider.DeviceConfig.NAMESPACE_PACKAGE_MANAGER_SERVICE;
import android.Manifest;
@@ -25,8 +23,11 @@ import android.annotation.Nullable;
import android.content.Intent;
import android.content.IntentFilter;
import android.content.pm.PackageManager;
-import android.content.pm.PackageParser;
-import android.content.pm.ProviderInfo;
+import android.content.pm.parsing.AndroidPackage;
+import android.content.pm.parsing.ComponentParseUtils;
+import android.content.pm.parsing.ComponentParseUtils.ParsedComponent;
+import android.content.pm.parsing.ComponentParseUtils.ParsedIntentInfo;
+import android.content.pm.parsing.ComponentParseUtils.ParsedProvider;
import android.net.Uri;
import android.os.Build;
import android.os.Process;
@@ -40,14 +41,15 @@ import android.util.SparseArray;
import com.android.internal.R;
import com.android.internal.annotations.VisibleForTesting;
+import com.android.internal.util.ArrayUtils;
import com.android.server.FgThread;
import com.android.server.compat.PlatformCompat;
import java.io.PrintWriter;
-import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
+import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
@@ -125,8 +127,7 @@ public class AppsFilter {
boolean isGloballyEnabled();
/** @return true if the feature is enabled for the given package. */
- boolean packageIsEnabled(PackageParser.Package pkg);
-
+ boolean packageIsEnabled(AndroidPackage pkg);
}
private static class FeatureConfigImpl implements FeatureConfig {
@@ -159,14 +160,14 @@ public class AppsFilter {
}
@Override
- public boolean packageIsEnabled(PackageParser.Package pkg) {
+ public boolean packageIsEnabled(AndroidPackage pkg) {
final PlatformCompat compatibility = mInjector.getCompatibility();
if (compatibility == null) {
Slog.wtf(TAG, "PlatformCompat is null");
return mFeatureEnabled;
}
- return compatibility.isChangeEnabled(
- PackageManager.FILTER_APPLICATION_QUERY, pkg.applicationInfo);
+ return compatibility.isChangeEnabled(PackageManager.FILTER_APPLICATION_QUERY,
+ pkg.toAppInfo());
}
}
@@ -196,14 +197,13 @@ public class AppsFilter {
}
/** Returns true if the querying package may query for the potential target package */
- private static boolean canQuery(PackageParser.Package querying,
- PackageParser.Package potentialTarget) {
- if (querying.mQueriesIntents == null) {
+ private static boolean canQuery(AndroidPackage querying, AndroidPackage potentialTarget) {
+ if (querying.getQueriesIntents() == null || potentialTarget.getActivities() == null) {
return false;
}
- for (Intent intent : querying.mQueriesIntents) {
- if (matches(intent, potentialTarget.providers, potentialTarget.activities,
- potentialTarget.services, potentialTarget.receivers)) {
+ for (Intent intent : querying.getQueriesIntents()) {
+ if (matches(intent, potentialTarget.getProviders(), potentialTarget.getActivities(),
+ potentialTarget.getServices(), potentialTarget.getReceivers())) {
return true;
}
}
@@ -211,24 +211,24 @@ public class AppsFilter {
}
private static boolean matches(Intent intent,
- ArrayList<PackageParser.Provider> providerList,
- ArrayList<? extends Component<? extends IntentInfo>>... componentLists) {
- for (int p = providerList.size() - 1; p >= 0; p--) {
- PackageParser.Provider provider = providerList.get(p);
- final ProviderInfo providerInfo = provider.info;
+ @Nullable List<ParsedProvider> providerList,
+ List<? extends ParsedComponent<? extends ParsedIntentInfo>>... componentLists) {
+ for (int p = ArrayUtils.size(providerList) - 1; p >= 0; p--) {
+ ParsedProvider provider = providerList.get(p);
final Uri data = intent.getData();
if ("content".equalsIgnoreCase(intent.getScheme())
&& data != null
- && providerInfo.authority.equalsIgnoreCase(data.getAuthority())) {
+ && provider.getAuthority().equalsIgnoreCase(data.getAuthority())) {
return true;
}
}
for (int l = componentLists.length - 1; l >= 0; l--) {
- ArrayList<? extends Component<? extends IntentInfo>> components = componentLists[l];
+ List<? extends ParsedComponent<? extends ParsedIntentInfo>> components =
+ componentLists[l];
for (int c = components.size() - 1; c >= 0; c--) {
- Component<? extends IntentInfo> component = components.get(c);
- ArrayList<? extends IntentInfo> intents = component.intents;
+ ParsedComponent<? extends ParsedIntentInfo> component = components.get(c);
+ List<? extends ParsedIntentInfo> intents = component.intents;
for (int i = intents.size() - 1; i >= 0; i--) {
IntentFilter intentFilter = intents.get(i);
if (intentFilter.match(intent.getAction(), intent.getType(), intent.getScheme(),
@@ -273,44 +273,44 @@ public class AppsFilter {
* @param newPkg the new package being added
* @param existing all other packages currently on the device.
*/
- public void addPackage(PackageParser.Package newPkg,
- Map<String, PackageParser.Package> existing) {
+ public void addPackage(AndroidPackage newPkg, Map<String, AndroidPackage> existing) {
// let's re-evaluate the ability of already added packages to see this new package
- if (newPkg.mForceQueryable
+ if (newPkg.isForceQueryable()
|| (mSystemAppsQueryable && (newPkg.isSystem() || newPkg.isUpdatedSystemApp()))) {
- mForceQueryable.add(newPkg.packageName);
+ mForceQueryable.add(newPkg.getPackageName());
} else {
for (String packageName : mQueriesViaIntent.keySet()) {
- if (packageName == newPkg.packageName) {
+ if (Objects.equals(packageName, newPkg.getPackageName())) {
continue;
}
- final PackageParser.Package existingPackage = existing.get(packageName);
+ final AndroidPackage existingPackage = existing.get(packageName);
if (canQuery(existingPackage, newPkg)) {
- mQueriesViaIntent.get(packageName).add(newPkg.packageName);
+ mQueriesViaIntent.get(packageName).add(newPkg.getPackageName());
}
}
}
// if the new package declares them, let's evaluate its ability to see existing packages
- mQueriesViaIntent.put(newPkg.packageName, new HashSet<>());
- for (PackageParser.Package existingPackage : existing.values()) {
- if (existingPackage.packageName == newPkg.packageName) {
+ mQueriesViaIntent.put(newPkg.getPackageName(), new HashSet<>());
+ for (AndroidPackage existingPackage : existing.values()) {
+ if (Objects.equals(existingPackage.getPackageName(), newPkg.getPackageName())) {
continue;
}
- if (existingPackage.mForceQueryable
+ if (existingPackage.isForceQueryable()
|| (mSystemAppsQueryable
&& (newPkg.isSystem() || newPkg.isUpdatedSystemApp()))) {
continue;
}
if (canQuery(newPkg, existingPackage)) {
- mQueriesViaIntent.get(newPkg.packageName).add(existingPackage.packageName);
+ mQueriesViaIntent.get(newPkg.getPackageName())
+ .add(existingPackage.getPackageName());
}
}
final HashSet<String> queriesPackages = new HashSet<>(
- newPkg.mQueriesPackages == null ? 0 : newPkg.mQueriesPackages.size());
- if (newPkg.mQueriesPackages != null) {
- queriesPackages.addAll(newPkg.mQueriesPackages);
+ newPkg.getQueriesPackages() == null ? 0 : newPkg.getQueriesPackages().size());
+ if (newPkg.getQueriesPackages() != null) {
+ queriesPackages.addAll(newPkg.getQueriesPackages());
}
- mQueriesViaPackage.put(newPkg.packageName, queriesPackages);
+ mQueriesViaPackage.put(newPkg.getPackageName(), queriesPackages);
}
/**
@@ -405,8 +405,8 @@ public class AppsFilter {
private boolean shouldFilterApplicationInternal(
PackageSetting callingPkgSetting, PackageSetting targetPkgSetting, int userId) {
- final String callingName = callingPkgSetting.pkg.packageName;
- final PackageParser.Package targetPkg = targetPkgSetting.pkg;
+ final String callingName = callingPkgSetting.pkg.getPackageName();
+ final AndroidPackage targetPkg = targetPkgSetting.pkg;
if (!mFeatureConfig.packageIsEnabled(callingPkgSetting.pkg)) {
if (DEBUG_LOGGING) {
@@ -422,8 +422,8 @@ public class AppsFilter {
}
return true;
}
- final String targetName = targetPkg.packageName;
- if (callingPkgSetting.pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.R) {
+ final String targetName = targetPkg.getPackageName();
+ if (callingPkgSetting.pkg.getTargetSdkVersion() < Build.VERSION_CODES.R) {
if (DEBUG_LOGGING) {
log(callingPkgSetting, targetPkgSetting, "caller pre-R");
}
@@ -435,7 +435,7 @@ public class AppsFilter {
}
return false;
}
- if (targetPkg.mForceQueryable) {
+ if (targetPkg.isForceQueryable()) {
if (DEBUG_LOGGING) {
log(callingPkgSetting, targetPkgSetting, "manifest forceQueryable");
}
@@ -470,9 +470,11 @@ public class AppsFilter {
}
return false;
}
- if (callingPkgSetting.pkg.instrumentation.size() > 0) {
- for (int i = 0, max = callingPkgSetting.pkg.instrumentation.size(); i < max; i++) {
- if (callingPkgSetting.pkg.instrumentation.get(i).info.targetPackage == targetName) {
+ List<ComponentParseUtils.ParsedInstrumentation> instrumentations =
+ callingPkgSetting.pkg.getInstrumentations();
+ if (ArrayUtils.size(instrumentations) > 0) {
+ for (int i = 0, max = instrumentations.size(); i < max; i++) {
+ if (Objects.equals(instrumentations.get(i).getTargetPackage(), targetName)) {
if (DEBUG_LOGGING) {
log(callingPkgSetting, targetPkgSetting, "instrumentation");
}
@@ -504,7 +506,7 @@ public class AppsFilter {
private boolean isImplicitlyQueryableSystemApp(PackageSetting targetPkgSetting) {
return targetPkgSetting.isSystem() && (mSystemAppsQueryable
- || mForceQueryableByDevice.contains(targetPkgSetting.pkg.packageName));
+ || mForceQueryableByDevice.contains(targetPkgSetting.pkg.getPackageName()));
}
public void dumpQueries(
diff --git a/services/core/java/com/android/server/pm/ComponentResolver.java b/services/core/java/com/android/server/pm/ComponentResolver.java
index 8facce112b52..333a6e9cbfc2 100644
--- a/services/core/java/com/android/server/pm/ComponentResolver.java
+++ b/services/core/java/com/android/server/pm/ComponentResolver.java
@@ -21,7 +21,6 @@ import static android.content.pm.PackageManagerInternal.PACKAGE_SETUP_WIZARD;
import static com.android.server.pm.PackageManagerService.DEBUG_PACKAGE_SCANNING;
import static com.android.server.pm.PackageManagerService.DEBUG_REMOVE;
-import static com.android.server.pm.PackageManagerService.fixProcessName;
import android.content.ComponentName;
import android.content.Intent;
@@ -32,13 +31,18 @@ import android.content.pm.AuxiliaryResolveInfo;
import android.content.pm.InstantAppResolveInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManagerInternal;
-import android.content.pm.PackageParser;
-import android.content.pm.PackageParser.ActivityIntentInfo;
-import android.content.pm.PackageParser.ServiceIntentInfo;
import android.content.pm.PackageUserState;
import android.content.pm.ProviderInfo;
import android.content.pm.ResolveInfo;
import android.content.pm.ServiceInfo;
+import android.content.pm.parsing.AndroidPackage;
+import android.content.pm.parsing.ComponentParseUtils.ParsedActivity;
+import android.content.pm.parsing.ComponentParseUtils.ParsedActivityIntentInfo;
+import android.content.pm.parsing.ComponentParseUtils.ParsedProvider;
+import android.content.pm.parsing.ComponentParseUtils.ParsedProviderIntentInfo;
+import android.content.pm.parsing.ComponentParseUtils.ParsedService;
+import android.content.pm.parsing.ComponentParseUtils.ParsedServiceIntentInfo;
+import android.content.pm.parsing.PackageInfoUtils;
import android.os.UserHandle;
import android.util.ArrayMap;
import android.util.ArraySet;
@@ -49,15 +53,19 @@ import android.util.Pair;
import android.util.Slog;
import com.android.internal.annotations.GuardedBy;
+import com.android.internal.util.ArrayUtils;
import com.android.server.IntentResolver;
import java.io.PrintWriter;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
+import java.util.Objects;
import java.util.Set;
+import java.util.function.Function;
/** Resolves all Android component types [activities, services, providers and receivers]. */
public class ComponentResolver {
@@ -158,7 +166,7 @@ public class ComponentResolver {
/** All available receivers, for your resolving pleasure. */
@GuardedBy("mLock")
- private final ActivityIntentResolver mReceivers = new ActivityIntentResolver();
+ private final ActivityIntentResolver mReceivers = new ReceiverIntentResolver();
/** All available services, for your resolving pleasure. */
@GuardedBy("mLock")
@@ -166,7 +174,7 @@ public class ComponentResolver {
/** Mapping from provider authority [first directory in content URI codePath) to provider. */
@GuardedBy("mLock")
- private final ArrayMap<String, PackageParser.Provider> mProvidersByAuthority = new ArrayMap<>();
+ private final ArrayMap<String, ParsedProvider> mProvidersByAuthority = new ArrayMap<>();
/** Whether or not processing protected filters should be deferred. */
private boolean mDeferProtectedFilters = true;
@@ -181,7 +189,7 @@ public class ComponentResolver {
* /system partition in order to know which component is the setup wizard. This can
* only ever be non-empty if {@link #mDeferProtectedFilters} is {@code true}.
*/
- private List<PackageParser.ActivityIntentInfo> mProtectedFilters;
+ private List<ParsedActivityIntentInfo> mProtectedFilters;
ComponentResolver(UserManagerService userManager,
PackageManagerInternal packageManagerInternal,
@@ -192,28 +200,28 @@ public class ComponentResolver {
}
/** Returns the given activity */
- PackageParser.Activity getActivity(ComponentName component) {
+ ParsedActivity getActivity(ComponentName component) {
synchronized (mLock) {
return mActivities.mActivities.get(component);
}
}
/** Returns the given provider */
- PackageParser.Provider getProvider(ComponentName component) {
+ ParsedProvider getProvider(ComponentName component) {
synchronized (mLock) {
return mProviders.mProviders.get(component);
}
}
/** Returns the given receiver */
- PackageParser.Activity getReceiver(ComponentName component) {
+ ParsedActivity getReceiver(ComponentName component) {
synchronized (mLock) {
return mReceivers.mActivities.get(component);
}
}
/** Returns the given service */
- PackageParser.Service getService(ComponentName component) {
+ ParsedService getService(ComponentName component) {
synchronized (mLock) {
return mServices.mServices.get(component);
}
@@ -226,7 +234,7 @@ public class ComponentResolver {
}
List<ResolveInfo> queryActivities(Intent intent, String resolvedType, int flags,
- List<PackageParser.Activity> activities, int userId) {
+ List<ParsedActivity> activities, int userId) {
synchronized (mLock) {
return mActivities.queryIntentForPackage(
intent, resolvedType, flags, activities, userId);
@@ -240,7 +248,7 @@ public class ComponentResolver {
}
List<ResolveInfo> queryProviders(Intent intent, String resolvedType, int flags,
- List<PackageParser.Provider> providers, int userId) {
+ List<ParsedProvider> providers, int userId) {
synchronized (mLock) {
return mProviders.queryIntentForPackage(intent, resolvedType, flags, providers, userId);
}
@@ -254,25 +262,34 @@ public class ComponentResolver {
List<ProviderInfo> providerList = null;
synchronized (mLock) {
for (int i = mProviders.mProviders.size() - 1; i >= 0; --i) {
- final PackageParser.Provider p = mProviders.mProviders.valueAt(i);
- final PackageSetting ps = (PackageSetting) p.owner.mExtras;
+ final ParsedProvider p = mProviders.mProviders.valueAt(i);
+ if (p.getAuthority() == null) {
+ continue;
+ }
+
+ final PackageSetting ps =
+ (PackageSetting) sPackageManagerInternal.getPackageSetting(
+ p.getPackageName());
if (ps == null) {
continue;
}
- if (p.info.authority == null) {
+
+ AndroidPackage pkg = sPackageManagerInternal.getPackage(p.getPackageName());
+ if (pkg == null) {
continue;
}
- if (processName != null && (!p.info.processName.equals(processName)
- || !UserHandle.isSameApp(p.info.applicationInfo.uid, uid))) {
+
+ if (processName != null && (!p.getProcessName().equals(processName)
+ || !UserHandle.isSameApp(pkg.getUid(), uid))) {
continue;
}
// See PM.queryContentProviders()'s javadoc for why we have the metaData parameter.
if (metaDataKey != null
- && (p.metaData == null || !p.metaData.containsKey(metaDataKey))) {
+ && (p.getMetaData() == null || !p.getMetaData().containsKey(metaDataKey))) {
continue;
}
- final ProviderInfo info = PackageParser.generateProviderInfo(
- p, flags, ps.readUserState(userId), userId);
+ final ProviderInfo info = PackageInfoUtils.generateProviderInfo(
+ pkg, p, flags, ps.readUserState(userId), userId);
if (info == null) {
continue;
}
@@ -285,17 +302,23 @@ public class ComponentResolver {
return providerList;
}
- ProviderInfo queryProvider(String authority, int flags, int userId) {
+ ProviderInfo queryProvider(String authority, int flags, int uid, int userId) {
synchronized (mLock) {
- final PackageParser.Provider p = mProvidersByAuthority.get(authority);
+ final ParsedProvider p = mProvidersByAuthority.get(authority);
if (p == null) {
return null;
}
- final PackageSetting ps = (PackageSetting) p.owner.mExtras;
+ final PackageSetting ps = (PackageSetting) sPackageManagerInternal.getPackageSetting(
+ p.getPackageName());
if (ps == null) {
return null;
}
- return PackageParser.generateProviderInfo(p, flags, ps.readUserState(userId), userId);
+ final AndroidPackage pkg = sPackageManagerInternal.getPackage(p.getPackageName());
+ if (pkg == null) {
+ return null;
+ }
+ return PackageInfoUtils.generateProviderInfo(pkg, p, flags,
+ ps.readUserState(userId), userId);
}
}
@@ -303,20 +326,29 @@ public class ComponentResolver {
int userId) {
synchronized (mLock) {
for (int i = mProvidersByAuthority.size() - 1; i >= 0; --i) {
- final PackageParser.Provider p = mProvidersByAuthority.valueAt(i);
- final PackageSetting ps = (PackageSetting) p.owner.mExtras;
+ final ParsedProvider p = mProvidersByAuthority.valueAt(i);
+ if (!p.isSyncable()) {
+ continue;
+ }
+
+ final PackageSetting ps =
+ (PackageSetting) sPackageManagerInternal.getPackageSetting(
+ p.getPackageName());
if (ps == null) {
continue;
}
- if (!p.syncable) {
+
+ final AndroidPackage pkg = sPackageManagerInternal.getPackage(p.getPackageName());
+ if (pkg == null) {
continue;
}
- if (safeMode
- && (p.info.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) == 0) {
+
+ if (safeMode && (pkg.getFlags() & ApplicationInfo.FLAG_SYSTEM) == 0) {
continue;
}
final ProviderInfo info =
- PackageParser.generateProviderInfo(p, 0, ps.readUserState(userId), userId);
+ PackageInfoUtils.generateProviderInfo(pkg, p, 0,
+ ps.readUserState(userId), userId);
if (info == null) {
continue;
}
@@ -333,7 +365,7 @@ public class ComponentResolver {
}
List<ResolveInfo> queryReceivers(Intent intent, String resolvedType, int flags,
- List<PackageParser.Activity> receivers, int userId) {
+ List<ParsedActivity> receivers, int userId) {
synchronized (mLock) {
return mReceivers.queryIntentForPackage(intent, resolvedType, flags, receivers, userId);
}
@@ -346,7 +378,7 @@ public class ComponentResolver {
}
List<ResolveInfo> queryServices(Intent intent, String resolvedType, int flags,
- List<PackageParser.Service> services, int userId) {
+ List<ParsedService> services, int userId) {
synchronized (mLock) {
return mServices.queryIntentForPackage(intent, resolvedType, flags, services, userId);
}
@@ -360,15 +392,15 @@ public class ComponentResolver {
}
/** Asserts none of the providers defined in the given package haven't already been defined. */
- void assertProvidersNotDefined(PackageParser.Package pkg) throws PackageManagerException {
+ void assertProvidersNotDefined(AndroidPackage pkg) throws PackageManagerException {
synchronized (mLock) {
assertProvidersNotDefinedLocked(pkg);
}
}
/** Add all components defined in the given package to the internal structures. */
- void addAllComponents(PackageParser.Package pkg, boolean chatty) {
- final ArrayList<PackageParser.ActivityIntentInfo> newIntents = new ArrayList<>();
+ void addAllComponents(AndroidPackage pkg, boolean chatty) {
+ final ArrayList<ParsedActivityIntentInfo> newIntents = new ArrayList<>();
synchronized (mLock) {
addActivitiesLocked(pkg, newIntents, chatty);
addReceiversLocked(pkg, chatty);
@@ -378,17 +410,19 @@ public class ComponentResolver {
final String setupWizardPackage = sPackageManagerInternal.getKnownPackageName(
PACKAGE_SETUP_WIZARD, UserHandle.USER_SYSTEM);
for (int i = newIntents.size() - 1; i >= 0; --i) {
- final PackageParser.ActivityIntentInfo intentInfo = newIntents.get(i);
- final PackageParser.Package disabledPkg = sPackageManagerInternal
- .getDisabledSystemPackage(intentInfo.activity.info.packageName);
- final List<PackageParser.Activity> systemActivities =
- disabledPkg != null ? disabledPkg.activities : null;
+ final ParsedActivityIntentInfo intentInfo = newIntents.get(i);
+ final PackageSetting disabledPkgSetting = (PackageSetting) sPackageManagerInternal
+ .getDisabledSystemPackage(intentInfo.getPackageName());
+ final AndroidPackage disabledPkg =
+ disabledPkgSetting == null ? null : disabledPkgSetting.pkg;
+ final List<ParsedActivity> systemActivities =
+ disabledPkg != null ? disabledPkg.getActivities() : null;
adjustPriority(systemActivities, intentInfo, setupWizardPackage);
}
}
/** Removes all components defined in the given package from the internal structures. */
- void removeAllComponents(PackageParser.Package pkg, boolean chatty) {
+ void removeAllComponents(AndroidPackage pkg, boolean chatty) {
synchronized (mLock) {
removeAllComponentsLocked(pkg, chatty);
}
@@ -407,7 +441,7 @@ public class ComponentResolver {
if (mProtectedFilters == null || mProtectedFilters.size() == 0) {
return;
}
- final List<ActivityIntentInfo> protectedFilters = mProtectedFilters;
+ final List<ParsedActivityIntentInfo> protectedFilters = mProtectedFilters;
mProtectedFilters = null;
final String setupWizardPackage = sPackageManagerInternal.getKnownPackageName(
@@ -417,13 +451,13 @@ public class ComponentResolver {
+ " All protected intents capped to priority 0");
}
for (int i = protectedFilters.size() - 1; i >= 0; --i) {
- final ActivityIntentInfo filter = protectedFilters.get(i);
- if (filter.activity.info.packageName.equals(setupWizardPackage)) {
+ final ParsedActivityIntentInfo filter = protectedFilters.get(i);
+ if (filter.getPackageName().equals(setupWizardPackage)) {
if (DEBUG_FILTERS) {
Slog.i(TAG, "Found setup wizard;"
+ " allow priority " + filter.getPriority() + ";"
- + " package: " + filter.activity.info.packageName
- + " activity: " + filter.activity.className
+ + " package: " + filter.getPackageName()
+ + " activity: " + filter.getClassName()
+ " priority: " + filter.getPriority());
}
// skip setup wizard; allow it to keep the high priority filter
@@ -431,8 +465,8 @@ public class ComponentResolver {
}
if (DEBUG_FILTERS) {
Slog.i(TAG, "Protected action; cap priority to 0;"
- + " package: " + filter.activity.info.packageName
- + " activity: " + filter.activity.className
+ + " package: " + filter.getPackageName()
+ + " activity: " + filter.getClassName()
+ " origPrio: " + filter.getPriority());
}
filter.setPriority(0);
@@ -473,8 +507,8 @@ public class ComponentResolver {
void dumpContentProviders(PrintWriter pw, DumpState dumpState, String packageName) {
boolean printedSomething = false;
- for (PackageParser.Provider p : mProviders.mProviders.values()) {
- if (packageName != null && !packageName.equals(p.info.packageName)) {
+ for (ParsedProvider p : mProviders.mProviders.values()) {
+ if (packageName != null && !packageName.equals(p.getPackageName())) {
continue;
}
if (!printedSomething) {
@@ -484,14 +518,17 @@ public class ComponentResolver {
pw.println("Registered ContentProviders:");
printedSomething = true;
}
- pw.print(" "); p.printComponentShortName(pw); pw.println(":");
- pw.print(" "); pw.println(p.toString());
+ pw.print(" ");
+ ComponentName.printShortString(pw, p.getPackageName(), p.className);
+ pw.println(":");
+ pw.print(" ");
+ pw.println(p.toString());
}
printedSomething = false;
- for (Map.Entry<String, PackageParser.Provider> entry :
+ for (Map.Entry<String, ParsedProvider> entry :
mProvidersByAuthority.entrySet()) {
- PackageParser.Provider p = entry.getValue();
- if (packageName != null && !packageName.equals(p.info.packageName)) {
+ ParsedProvider p = entry.getValue();
+ if (packageName != null && !packageName.equals(p.getPackageName())) {
continue;
}
if (!printedSomething) {
@@ -503,25 +540,43 @@ public class ComponentResolver {
}
pw.print(" ["); pw.print(entry.getKey()); pw.println("]:");
pw.print(" "); pw.println(p.toString());
- if (p.info != null && p.info.applicationInfo != null) {
- final String appInfo = p.info.applicationInfo.toString();
- pw.print(" applicationInfo="); pw.println(appInfo);
+
+ AndroidPackage pkg = sPackageManagerInternal.getPackage(p.getPackageName());
+
+ if (pkg != null) {
+ // TODO(b/135203078): Print AppInfo?
+ pw.print(" applicationInfo="); pw.println(pkg.toAppInfo());
}
}
}
- void dumpServicePermissions(PrintWriter pw, DumpState dumpState, String packageName) {
+ void dumpServicePermissions(PrintWriter pw, DumpState dumpState) {
if (dumpState.onTitlePrinted()) pw.println();
pw.println("Service permissions:");
- final Iterator<ServiceIntentInfo> filterIterator = mServices.filterIterator();
+ final Iterator<ParsedServiceIntentInfo> filterIterator = mServices.filterIterator();
while (filterIterator.hasNext()) {
- final ServiceIntentInfo info = filterIterator.next();
- final ServiceInfo serviceInfo = info.service.info;
- final String permission = serviceInfo.permission;
+ final ParsedServiceIntentInfo info = filterIterator.next();
+
+ ParsedService service = null;
+
+ AndroidPackage pkg = sPackageManagerInternal.getPackage(info.getPackageName());
+ if (pkg != null && pkg.getServices() != null) {
+ for (ParsedService parsedService : pkg.getServices()) {
+ if (Objects.equals(parsedService.className, info.getClassName())) {
+ service = parsedService;
+ }
+ }
+ }
+
+ if (service == null) {
+ continue;
+ }
+
+ final String permission = service.getPermission();
if (permission != null) {
pw.print(" ");
- pw.print(serviceInfo.getComponentName().flattenToShortString());
+ pw.print(service.getComponentName().flattenToShortString());
pw.print(": ");
pw.println(permission);
}
@@ -529,14 +584,12 @@ public class ComponentResolver {
}
@GuardedBy("mLock")
- private void addActivitiesLocked(PackageParser.Package pkg,
- List<PackageParser.ActivityIntentInfo> newIntents, boolean chatty) {
- final int activitiesSize = pkg.activities.size();
+ private void addActivitiesLocked(AndroidPackage pkg,
+ List<ParsedActivityIntentInfo> newIntents, boolean chatty) {
+ final int activitiesSize = ArrayUtils.size(pkg.getActivities());
StringBuilder r = null;
for (int i = 0; i < activitiesSize; i++) {
- PackageParser.Activity a = pkg.activities.get(i);
- a.info.processName =
- fixProcessName(pkg.applicationInfo.processName, a.info.processName);
+ ParsedActivity a = pkg.getActivities().get(i);
mActivities.addActivity(a, "activity", newIntents);
if (DEBUG_PACKAGE_SCANNING && chatty) {
if (r == null) {
@@ -544,7 +597,7 @@ public class ComponentResolver {
} else {
r.append(' ');
}
- r.append(a.info.name);
+ r.append(a.getName());
}
}
if (DEBUG_PACKAGE_SCANNING && chatty) {
@@ -553,20 +606,17 @@ public class ComponentResolver {
}
@GuardedBy("mLock")
- private void addProvidersLocked(PackageParser.Package pkg, boolean chatty) {
- final int providersSize = pkg.providers.size();
+ private void addProvidersLocked(AndroidPackage pkg, boolean chatty) {
+ final int providersSize = ArrayUtils.size(pkg.getProviders());
StringBuilder r = null;
for (int i = 0; i < providersSize; i++) {
- PackageParser.Provider p = pkg.providers.get(i);
- p.info.processName = fixProcessName(pkg.applicationInfo.processName,
- p.info.processName);
+ EffectiveProvider p = new EffectiveProvider(pkg.getProviders().get(i));
mProviders.addProvider(p);
- p.syncable = p.info.isSyncable;
- if (p.info.authority != null) {
- String[] names = p.info.authority.split(";");
- p.info.authority = null;
+ if (p.getAuthority() != null) {
+ String[] names = p.getAuthority().split(";");
+ p.setEffectiveAuthority(null);
for (int j = 0; j < names.length; j++) {
- if (j == 1 && p.syncable) {
+ if (j == 1 && p.isSyncable()) {
// We only want the first authority for a provider to possibly be
// syncable, so if we already added this provider using a different
// authority clear the syncable flag. We copy the provider before
@@ -574,23 +624,23 @@ public class ComponentResolver {
// to a provider that we don't want to change.
// Only do this for the second authority since the resulting provider
// object can be the same for all future authorities for this provider.
- p = new PackageParser.Provider(p);
- p.syncable = false;
+ p = new EffectiveProvider(p);
+ p.setEffectiveSyncable(false);
}
if (!mProvidersByAuthority.containsKey(names[j])) {
mProvidersByAuthority.put(names[j], p);
- if (p.info.authority == null) {
- p.info.authority = names[j];
+ if (p.getAuthority() == null) {
+ p.setEffectiveAuthority(names[j]);
} else {
- p.info.authority = p.info.authority + ";" + names[j];
+ p.setEffectiveAuthority(p.getAuthority() + ";" + names[j]);
}
if (DEBUG_PACKAGE_SCANNING && chatty) {
Log.d(TAG, "Registered content provider: " + names[j]
- + ", className = " + p.info.name
- + ", isSyncable = " + p.info.isSyncable);
+ + ", className = " + p.getName()
+ + ", isSyncable = " + p.isSyncable());
}
} else {
- final PackageParser.Provider other =
+ final ParsedProvider other =
mProvidersByAuthority.get(names[j]);
final ComponentName component =
(other != null && other.getComponentName() != null)
@@ -598,7 +648,7 @@ public class ComponentResolver {
final String packageName =
component != null ? component.getPackageName() : "?";
Slog.w(TAG, "Skipping provider name " + names[j]
- + " (in package " + pkg.applicationInfo.packageName + ")"
+ + " (in package " + pkg.getAppInfoPackageName() + ")"
+ ": name already used by " + packageName);
}
}
@@ -609,7 +659,7 @@ public class ComponentResolver {
} else {
r.append(' ');
}
- r.append(p.info.name);
+ r.append(p.getName());
}
}
if (DEBUG_PACKAGE_SCANNING && chatty) {
@@ -618,13 +668,11 @@ public class ComponentResolver {
}
@GuardedBy("mLock")
- private void addReceiversLocked(PackageParser.Package pkg, boolean chatty) {
- final int receiversSize = pkg.receivers.size();
+ private void addReceiversLocked(AndroidPackage pkg, boolean chatty) {
+ final int receiversSize = ArrayUtils.size(pkg.getReceivers());
StringBuilder r = null;
for (int i = 0; i < receiversSize; i++) {
- PackageParser.Activity a = pkg.receivers.get(i);
- a.info.processName = fixProcessName(pkg.applicationInfo.processName,
- a.info.processName);
+ ParsedActivity a = pkg.getReceivers().get(i);
mReceivers.addActivity(a, "receiver", null);
if (DEBUG_PACKAGE_SCANNING && chatty) {
if (r == null) {
@@ -632,7 +680,7 @@ public class ComponentResolver {
} else {
r.append(' ');
}
- r.append(a.info.name);
+ r.append(a.getName());
}
}
if (DEBUG_PACKAGE_SCANNING && chatty) {
@@ -641,13 +689,11 @@ public class ComponentResolver {
}
@GuardedBy("mLock")
- private void addServicesLocked(PackageParser.Package pkg, boolean chatty) {
- final int servicesSize = pkg.services.size();
+ private void addServicesLocked(AndroidPackage pkg, boolean chatty) {
+ final int servicesSize = ArrayUtils.size(pkg.getServices());
StringBuilder r = null;
for (int i = 0; i < servicesSize; i++) {
- PackageParser.Service s = pkg.services.get(i);
- s.info.processName = fixProcessName(pkg.applicationInfo.processName,
- s.info.processName);
+ ParsedService s = pkg.getServices().get(i);
mServices.addService(s);
if (DEBUG_PACKAGE_SCANNING && chatty) {
if (r == null) {
@@ -655,7 +701,7 @@ public class ComponentResolver {
} else {
r.append(' ');
}
- r.append(s.info.name);
+ r.append(s.getName());
}
}
if (DEBUG_PACKAGE_SCANNING && chatty) {
@@ -663,13 +709,12 @@ public class ComponentResolver {
}
}
-
/**
* <em>WARNING</em> for performance reasons, the passed in intentList WILL BE
* MODIFIED. Do not pass in a list that should not be changed.
*/
- private static <T> void getIntentListSubset(List<ActivityIntentInfo> intentList,
- IterGenerator<T> generator, Iterator<T> searchIterator) {
+ private static <T> void getIntentListSubset(List<ParsedActivityIntentInfo> intentList,
+ Function<ParsedActivityIntentInfo, Iterator<T>> generator, Iterator<T> searchIterator) {
// loop through the set of actions; every one must be found in the intent filter
while (searchIterator.hasNext()) {
// we must have at least one filter in the list to consider a match
@@ -680,14 +725,14 @@ public class ComponentResolver {
final T searchAction = searchIterator.next();
// loop through the set of intent filters
- final Iterator<ActivityIntentInfo> intentIter = intentList.iterator();
+ final Iterator<ParsedActivityIntentInfo> intentIter = intentList.iterator();
while (intentIter.hasNext()) {
- final ActivityIntentInfo intentInfo = intentIter.next();
+ final ParsedActivityIntentInfo intentInfo = intentIter.next();
boolean selectionFound = false;
// loop through the intent filter's selection criteria; at least one
// of them must match the searched criteria
- final Iterator<T> intentSelectionIter = generator.generate(intentInfo);
+ final Iterator<T> intentSelectionIter = generator.apply(intentInfo);
while (intentSelectionIter != null && intentSelectionIter.hasNext()) {
final T intentSelection = intentSelectionIter.next();
if (intentSelection != null && intentSelection.equals(searchAction)) {
@@ -705,7 +750,7 @@ public class ComponentResolver {
}
}
- private static boolean isProtectedAction(ActivityIntentInfo filter) {
+ private static boolean isProtectedAction(ParsedActivityIntentInfo filter) {
final Iterator<String> actionsIter = filter.actionsIterator();
while (actionsIter != null && actionsIter.hasNext()) {
final String filterAction = actionsIter.next();
@@ -719,20 +764,20 @@ public class ComponentResolver {
/**
* Finds a privileged activity that matches the specified activity names.
*/
- private static PackageParser.Activity findMatchingActivity(
- List<PackageParser.Activity> activityList, ActivityInfo activityInfo) {
- for (PackageParser.Activity sysActivity : activityList) {
- if (sysActivity.info.name.equals(activityInfo.name)) {
+ private static ParsedActivity findMatchingActivity(
+ List<ParsedActivity> activityList, ParsedActivity activityInfo) {
+ for (ParsedActivity sysActivity : activityList) {
+ if (sysActivity.getName().equals(activityInfo.getName())) {
return sysActivity;
}
- if (sysActivity.info.name.equals(activityInfo.targetActivity)) {
+ if (sysActivity.getName().equals(activityInfo.targetActivity)) {
return sysActivity;
}
- if (sysActivity.info.targetActivity != null) {
- if (sysActivity.info.targetActivity.equals(activityInfo.name)) {
+ if (sysActivity.targetActivity != null) {
+ if (sysActivity.targetActivity.equals(activityInfo.getName())) {
return sysActivity;
}
- if (sysActivity.info.targetActivity.equals(activityInfo.targetActivity)) {
+ if (sysActivity.targetActivity.equals(activityInfo.targetActivity)) {
return sysActivity;
}
}
@@ -753,24 +798,23 @@ public class ComponentResolver {
* <em>NOTE:</em> There is one exception. For security reasons, the setup wizard is
* allowed to obtain any priority on any action.
*/
- private void adjustPriority(List<PackageParser.Activity> systemActivities,
- ActivityIntentInfo intent, String setupWizardPackage) {
+ private void adjustPriority(List<ParsedActivity> systemActivities,
+ ParsedActivityIntentInfo intent, String setupWizardPackage) {
// nothing to do; priority is fine as-is
if (intent.getPriority() <= 0) {
return;
}
- final ActivityInfo activityInfo = intent.activity.info;
- final ApplicationInfo applicationInfo = activityInfo.applicationInfo;
+ AndroidPackage pkg = sPackageManagerInternal.getPackage(intent.getPackageName());
final boolean privilegedApp =
- ((applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0);
+ ((pkg.getPrivateFlags() & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0);
if (!privilegedApp) {
// non-privileged applications can never define a priority >0
if (DEBUG_FILTERS) {
Slog.i(TAG, "Non-privileged app; cap priority to 0;"
- + " package: " + applicationInfo.packageName
- + " activity: " + intent.activity.className
+ + " package: " + pkg.getPackageName()
+ + " activity: " + intent.getClassName()
+ " origPrio: " + intent.getPriority());
}
intent.setPriority(0);
@@ -794,8 +838,8 @@ public class ComponentResolver {
mProtectedFilters.add(intent);
if (DEBUG_FILTERS) {
Slog.i(TAG, "Protected action; save for later;"
- + " package: " + applicationInfo.packageName
- + " activity: " + intent.activity.className
+ + " package: " + pkg.getPackageName()
+ + " activity: " + intent.getClassName()
+ " origPrio: " + intent.getPriority());
}
return;
@@ -804,12 +848,12 @@ public class ComponentResolver {
Slog.i(TAG, "No setup wizard;"
+ " All protected intents capped to priority 0");
}
- if (intent.activity.info.packageName.equals(setupWizardPackage)) {
+ if (intent.getPackageName().equals(setupWizardPackage)) {
if (DEBUG_FILTERS) {
Slog.i(TAG, "Found setup wizard;"
+ " allow priority " + intent.getPriority() + ";"
- + " package: " + intent.activity.info.packageName
- + " activity: " + intent.activity.className
+ + " package: " + intent.getPackageName()
+ + " activity: " + intent.getClassName()
+ " priority: " + intent.getPriority());
}
// setup wizard gets whatever it wants
@@ -817,8 +861,8 @@ public class ComponentResolver {
}
if (DEBUG_FILTERS) {
Slog.i(TAG, "Protected action; cap priority to 0;"
- + " package: " + intent.activity.info.packageName
- + " activity: " + intent.activity.className
+ + " package: " + intent.getPackageName()
+ + " activity: " + intent.getClassName()
+ " origPrio: " + intent.getPriority());
}
intent.setPriority(0);
@@ -830,14 +874,28 @@ public class ComponentResolver {
}
// privileged app unbundled update ... try to find the same activity
- final PackageParser.Activity foundActivity =
- findMatchingActivity(systemActivities, activityInfo);
+
+ ParsedActivity foundActivity = null;
+ ParsedActivity activity = null;
+
+ if (pkg.getActivities() != null) {
+ for (ParsedActivity parsedProvider : pkg.getActivities()) {
+ if (Objects.equals(parsedProvider.className, intent.getClassName())) {
+ activity = parsedProvider;
+ }
+ }
+ }
+
+ if (activity != null) {
+ foundActivity = findMatchingActivity(systemActivities, activity);
+ }
+
if (foundActivity == null) {
// this is a new activity; it cannot obtain >0 priority
if (DEBUG_FILTERS) {
Slog.i(TAG, "New activity; cap priority to 0;"
- + " package: " + applicationInfo.packageName
- + " activity: " + intent.activity.className
+ + " package: " + pkg.getPackageName()
+ + " activity: " + intent.getClassName()
+ " origPrio: " + intent.getPriority());
}
intent.setPriority(0);
@@ -847,19 +905,19 @@ public class ComponentResolver {
// found activity, now check for filter equivalence
// a shallow copy is enough; we modify the list, not its contents
- final List<ActivityIntentInfo> intentListCopy = new ArrayList<>(foundActivity.intents);
- final List<ActivityIntentInfo> foundFilters = mActivities.findFilters(intent);
+ final List<ParsedActivityIntentInfo> intentListCopy =
+ new ArrayList<>(foundActivity.intents);
// find matching action subsets
final Iterator<String> actionsIterator = intent.actionsIterator();
if (actionsIterator != null) {
- getIntentListSubset(intentListCopy, new ActionIterGenerator(), actionsIterator);
+ getIntentListSubset(intentListCopy, IntentFilter::actionsIterator, actionsIterator);
if (intentListCopy.size() == 0) {
// no more intents to match; we're not equivalent
if (DEBUG_FILTERS) {
Slog.i(TAG, "Mismatched action; cap priority to 0;"
- + " package: " + applicationInfo.packageName
- + " activity: " + intent.activity.className
+ + " package: " + pkg.getPackageName()
+ + " activity: " + intent.getClassName()
+ " origPrio: " + intent.getPriority());
}
intent.setPriority(0);
@@ -870,13 +928,14 @@ public class ComponentResolver {
// find matching category subsets
final Iterator<String> categoriesIterator = intent.categoriesIterator();
if (categoriesIterator != null) {
- getIntentListSubset(intentListCopy, new CategoriesIterGenerator(), categoriesIterator);
+ getIntentListSubset(intentListCopy, IntentFilter::categoriesIterator,
+ categoriesIterator);
if (intentListCopy.size() == 0) {
// no more intents to match; we're not equivalent
if (DEBUG_FILTERS) {
Slog.i(TAG, "Mismatched category; cap priority to 0;"
- + " package: " + applicationInfo.packageName
- + " activity: " + intent.activity.className
+ + " package: " + pkg.getPackageName()
+ + " activity: " + intent.getClassName()
+ " origPrio: " + intent.getPriority());
}
intent.setPriority(0);
@@ -887,13 +946,13 @@ public class ComponentResolver {
// find matching schemes subsets
final Iterator<String> schemesIterator = intent.schemesIterator();
if (schemesIterator != null) {
- getIntentListSubset(intentListCopy, new SchemesIterGenerator(), schemesIterator);
+ getIntentListSubset(intentListCopy, IntentFilter::schemesIterator, schemesIterator);
if (intentListCopy.size() == 0) {
// no more intents to match; we're not equivalent
if (DEBUG_FILTERS) {
Slog.i(TAG, "Mismatched scheme; cap priority to 0;"
- + " package: " + applicationInfo.packageName
- + " activity: " + intent.activity.className
+ + " package: " + pkg.getPackageName()
+ + " activity: " + intent.getClassName()
+ " origPrio: " + intent.getPriority());
}
intent.setPriority(0);
@@ -905,14 +964,14 @@ public class ComponentResolver {
final Iterator<IntentFilter.AuthorityEntry> authoritiesIterator =
intent.authoritiesIterator();
if (authoritiesIterator != null) {
- getIntentListSubset(intentListCopy, new AuthoritiesIterGenerator(),
+ getIntentListSubset(intentListCopy, IntentFilter::authoritiesIterator,
authoritiesIterator);
if (intentListCopy.size() == 0) {
// no more intents to match; we're not equivalent
if (DEBUG_FILTERS) {
Slog.i(TAG, "Mismatched authority; cap priority to 0;"
- + " package: " + applicationInfo.packageName
- + " activity: " + intent.activity.className
+ + " package: " + pkg.getPackageName()
+ + " activity: " + intent.getClassName()
+ " origPrio: " + intent.getPriority());
}
intent.setPriority(0);
@@ -929,8 +988,8 @@ public class ComponentResolver {
if (DEBUG_FILTERS) {
Slog.i(TAG, "Found matching filter(s);"
+ " cap priority to " + cappedPriority + ";"
- + " package: " + applicationInfo.packageName
- + " activity: " + intent.activity.className
+ + " package: " + pkg.getPackageName()
+ + " activity: " + intent.getClassName()
+ " origPrio: " + intent.getPriority());
}
intent.setPriority(cappedPriority);
@@ -940,15 +999,15 @@ public class ComponentResolver {
}
@GuardedBy("mLock")
- private void removeAllComponentsLocked(PackageParser.Package pkg, boolean chatty) {
+ private void removeAllComponentsLocked(AndroidPackage pkg, boolean chatty) {
int componentSize;
StringBuilder r;
int i;
- componentSize = pkg.activities.size();
+ componentSize = ArrayUtils.size(pkg.getActivities());
r = null;
for (i = 0; i < componentSize; i++) {
- PackageParser.Activity a = pkg.activities.get(i);
+ ParsedActivity a = pkg.getActivities().get(i);
mActivities.removeActivity(a, "activity");
if (DEBUG_REMOVE && chatty) {
if (r == null) {
@@ -956,32 +1015,32 @@ public class ComponentResolver {
} else {
r.append(' ');
}
- r.append(a.info.name);
+ r.append(a.getName());
}
}
if (DEBUG_REMOVE && chatty) {
Log.d(TAG, " Activities: " + (r == null ? "<NONE>" : r));
}
- componentSize = pkg.providers.size();
+ componentSize = ArrayUtils.size(pkg.getProviders());
r = null;
for (i = 0; i < componentSize; i++) {
- PackageParser.Provider p = pkg.providers.get(i);
+ ParsedProvider p = pkg.getProviders().get(i);
mProviders.removeProvider(p);
- if (p.info.authority == null) {
+ if (p.getAuthority() == null) {
// Another content provider with this authority existed when this app was
// installed, so this authority is null. Ignore it as we don't have to
// unregister the provider.
continue;
}
- String[] names = p.info.authority.split(";");
+ String[] names = p.getAuthority().split(";");
for (int j = 0; j < names.length; j++) {
if (mProvidersByAuthority.get(names[j]) == p) {
mProvidersByAuthority.remove(names[j]);
if (DEBUG_REMOVE && chatty) {
Log.d(TAG, "Unregistered content provider: " + names[j]
- + ", className = " + p.info.name + ", isSyncable = "
- + p.info.isSyncable);
+ + ", className = " + p.getName() + ", isSyncable = "
+ + p.isSyncable());
}
}
}
@@ -991,17 +1050,17 @@ public class ComponentResolver {
} else {
r.append(' ');
}
- r.append(p.info.name);
+ r.append(p.getName());
}
}
if (DEBUG_REMOVE && chatty) {
Log.d(TAG, " Providers: " + (r == null ? "<NONE>" : r));
}
- componentSize = pkg.receivers.size();
+ componentSize = ArrayUtils.size(pkg.getReceivers());
r = null;
for (i = 0; i < componentSize; i++) {
- PackageParser.Activity a = pkg.receivers.get(i);
+ ParsedActivity a = pkg.getReceivers().get(i);
mReceivers.removeActivity(a, "receiver");
if (DEBUG_REMOVE && chatty) {
if (r == null) {
@@ -1009,17 +1068,17 @@ public class ComponentResolver {
} else {
r.append(' ');
}
- r.append(a.info.name);
+ r.append(a.getName());
}
}
if (DEBUG_REMOVE && chatty) {
Log.d(TAG, " Receivers: " + (r == null ? "<NONE>" : r));
}
- componentSize = pkg.services.size();
+ componentSize = ArrayUtils.size(pkg.getServices());
r = null;
for (i = 0; i < componentSize; i++) {
- PackageParser.Service s = pkg.services.get(i);
+ ParsedService s = pkg.getServices().get(i);
mServices.removeService(s);
if (DEBUG_REMOVE && chatty) {
if (r == null) {
@@ -1027,7 +1086,7 @@ public class ComponentResolver {
} else {
r.append(' ');
}
- r.append(s.info.name);
+ r.append(s.getName());
}
}
if (DEBUG_REMOVE && chatty) {
@@ -1036,26 +1095,26 @@ public class ComponentResolver {
}
@GuardedBy("mLock")
- private void assertProvidersNotDefinedLocked(PackageParser.Package pkg)
+ private void assertProvidersNotDefinedLocked(AndroidPackage pkg)
throws PackageManagerException {
- final int providersSize = pkg.providers.size();
+ final int providersSize = ArrayUtils.size(pkg.getProviders());
int i;
for (i = 0; i < providersSize; i++) {
- PackageParser.Provider p = pkg.providers.get(i);
- if (p.info.authority != null) {
- final String[] names = p.info.authority.split(";");
+ ParsedProvider p = pkg.getProviders().get(i);
+ if (p.getAuthority() != null) {
+ final String[] names = p.getAuthority().split(";");
for (int j = 0; j < names.length; j++) {
if (mProvidersByAuthority.containsKey(names[j])) {
- final PackageParser.Provider other = mProvidersByAuthority.get(names[j]);
+ final ParsedProvider other = mProvidersByAuthority.get(names[j]);
final String otherPackageName =
(other != null && other.getComponentName() != null)
? other.getComponentName().getPackageName() : "?";
// if we're installing over the same already-installed package, this is ok
- if (!otherPackageName.equals(pkg.packageName)) {
+ if (!otherPackageName.equals(pkg.getPackageName())) {
throw new PackageManagerException(
INSTALL_FAILED_CONFLICTING_PROVIDER,
"Can't install because provider name " + names[j]
- + " (in package " + pkg.applicationInfo.packageName
+ + " (in package " + pkg.getPackageName()
+ ") is already used by " + otherPackageName);
}
}
@@ -1064,8 +1123,9 @@ public class ComponentResolver {
}
}
- private static final class ActivityIntentResolver
- extends IntentResolver<PackageParser.ActivityIntentInfo, ResolveInfo> {
+ private static class ActivityIntentResolver
+ extends IntentResolver<ParsedActivityIntentInfo, ResolveInfo> {
+
@Override
public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
boolean defaultOnly, int userId) {
@@ -1086,24 +1146,24 @@ public class ComponentResolver {
}
List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
- int flags, List<PackageParser.Activity> packageActivities, int userId) {
+ int flags, List<ParsedActivity> packageActivities, int userId) {
if (!sUserManager.exists(userId)) {
return null;
}
if (packageActivities == null) {
- return null;
+ return Collections.emptyList();
}
mFlags = flags;
final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0;
final int activitiesSize = packageActivities.size();
- ArrayList<PackageParser.ActivityIntentInfo[]> listCut = new ArrayList<>(activitiesSize);
+ ArrayList<ParsedActivityIntentInfo[]> listCut = new ArrayList<>(activitiesSize);
- ArrayList<PackageParser.ActivityIntentInfo> intentFilters;
+ List<ParsedActivityIntentInfo> intentFilters;
for (int i = 0; i < activitiesSize; ++i) {
intentFilters = packageActivities.get(i).intents;
if (intentFilters != null && intentFilters.size() > 0) {
- PackageParser.ActivityIntentInfo[] array =
- new PackageParser.ActivityIntentInfo[intentFilters.size()];
+ ParsedActivityIntentInfo[] array =
+ new ParsedActivityIntentInfo[intentFilters.size()];
intentFilters.toArray(array);
listCut.add(array);
}
@@ -1111,21 +1171,21 @@ public class ComponentResolver {
return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
}
- private void addActivity(PackageParser.Activity a, String type,
- List<PackageParser.ActivityIntentInfo> newIntents) {
+ private void addActivity(ParsedActivity a, String type,
+ List<ParsedActivityIntentInfo> newIntents) {
mActivities.put(a.getComponentName(), a);
if (DEBUG_SHOW_INFO) {
- final CharSequence label = a.info.nonLocalizedLabel != null
- ? a.info.nonLocalizedLabel
- : a.info.name;
+ final CharSequence label = a.nonLocalizedLabel != null
+ ? a.nonLocalizedLabel
+ : a.getName();
Log.v(TAG, " " + type + " " + label + ":");
}
if (DEBUG_SHOW_INFO) {
- Log.v(TAG, " Class=" + a.info.name);
+ Log.v(TAG, " Class=" + a.getName());
}
final int intentsSize = a.intents.size();
for (int j = 0; j < intentsSize; j++) {
- PackageParser.ActivityIntentInfo intent = a.intents.get(j);
+ ParsedActivityIntentInfo intent = a.intents.get(j);
if (newIntents != null && "activity".equals(type)) {
newIntents.add(intent);
}
@@ -1134,23 +1194,23 @@ public class ComponentResolver {
intent.dump(new LogPrinter(Log.VERBOSE, TAG), " ");
}
if (!intent.debugCheck()) {
- Log.w(TAG, "==> For Activity " + a.info.name);
+ Log.w(TAG, "==> For Activity " + a.getName());
}
addFilter(intent);
}
}
- private void removeActivity(PackageParser.Activity a, String type) {
+ private void removeActivity(ParsedActivity a, String type) {
mActivities.remove(a.getComponentName());
if (DEBUG_SHOW_INFO) {
Log.v(TAG, " " + type + " "
- + (a.info.nonLocalizedLabel != null ? a.info.nonLocalizedLabel
- : a.info.name) + ":");
- Log.v(TAG, " Class=" + a.info.name);
+ + (a.nonLocalizedLabel != null ? a.nonLocalizedLabel
+ : a.getName()) + ":");
+ Log.v(TAG, " Class=" + a.getName());
}
final int intentsSize = a.intents.size();
for (int j = 0; j < intentsSize; j++) {
- PackageParser.ActivityIntentInfo intent = a.intents.get(j);
+ ParsedActivityIntentInfo intent = a.intents.get(j);
if (DEBUG_SHOW_INFO) {
Log.v(TAG, " IntentFilter:");
intent.dump(new LogPrinter(Log.VERBOSE, TAG), " ");
@@ -1161,11 +1221,11 @@ public class ComponentResolver {
@Override
protected boolean allowFilterResult(
- PackageParser.ActivityIntentInfo filter, List<ResolveInfo> dest) {
- ActivityInfo filterAi = filter.activity.info;
+ ParsedActivityIntentInfo filter, List<ResolveInfo> dest) {
for (int i = dest.size() - 1; i >= 0; --i) {
ActivityInfo destAi = dest.get(i).activityInfo;
- if (destAi.name == filterAi.name && destAi.packageName == filterAi.packageName) {
+ if (Objects.equals(destAi.name, filter.getClassName())
+ && Objects.equals(destAi.packageName, filter.getPackageName())) {
return false;
}
}
@@ -1173,34 +1233,39 @@ public class ComponentResolver {
}
@Override
- protected ActivityIntentInfo[] newArray(int size) {
- return new ActivityIntentInfo[size];
+ protected ParsedActivityIntentInfo[] newArray(int size) {
+ return new ParsedActivityIntentInfo[size];
}
@Override
- protected boolean isFilterStopped(PackageParser.ActivityIntentInfo filter, int userId) {
+ protected boolean isFilterStopped(ParsedActivityIntentInfo filter, int userId) {
if (!sUserManager.exists(userId)) return true;
- PackageParser.Package p = filter.activity.owner;
- if (p != null) {
- PackageSetting ps = (PackageSetting) p.mExtras;
- if (ps != null) {
- // System apps are never considered stopped for purposes of
- // filtering, because there may be no way for the user to
- // actually re-launch them.
- return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0
- && ps.getStopped(userId);
- }
+
+ AndroidPackage pkg = sPackageManagerInternal.getPackage(filter.getPackageName());
+ if (pkg == null) {
+ return false;
}
- return false;
+
+ PackageSetting ps = (PackageSetting) sPackageManagerInternal.getPackageSetting(
+ filter.getPackageName());
+ if (ps == null) {
+ return false;
+ }
+
+ // System apps are never considered stopped for purposes of
+ // filtering, because there may be no way for the user to
+ // actually re-launch them.
+ return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0
+ && ps.getStopped(userId);
}
@Override
protected boolean isPackageForFilter(String packageName,
- PackageParser.ActivityIntentInfo info) {
- return packageName.equals(info.activity.owner.packageName);
+ ParsedActivityIntentInfo info) {
+ return packageName.equals(info.getPackageName());
}
- private void log(String reason, ActivityIntentInfo info, int match,
+ private void log(String reason, ParsedActivityIntentInfo info, int match,
int userId) {
Slog.w(TAG, reason
+ "; match: "
@@ -1210,7 +1275,7 @@ public class ComponentResolver {
}
@Override
- protected ResolveInfo newResult(PackageParser.ActivityIntentInfo info,
+ protected ResolveInfo newResult(ParsedActivityIntentInfo info,
int match, int userId) {
if (!sUserManager.exists(userId)) {
if (DEBUG) {
@@ -1218,7 +1283,29 @@ public class ComponentResolver {
}
return null;
}
- if (!sPackageManagerInternal.isEnabledAndMatches(info.activity.info, mFlags, userId)) {
+
+ ParsedActivity activity = null;
+
+ AndroidPackage pkg = sPackageManagerInternal.getPackage(info.getPackageName());
+ if (pkg == null) {
+ return null;
+ }
+
+ // TODO(b/135203078): Consider more efficient ways of doing this.
+ List<ParsedActivity> activities = getResolveList(pkg);
+ if (activities != null) {
+ for (ParsedActivity parsedActivity : activities) {
+ if (Objects.equals(parsedActivity.className, info.getClassName())) {
+ activity = parsedActivity;
+ }
+ }
+ }
+
+ if (activity == null) {
+ return null;
+ }
+
+ if (!sPackageManagerInternal.isEnabledAndMatches(activity, mFlags, userId)) {
if (DEBUG) {
log("!PackageManagerInternal.isEnabledAndMatches; mFlags="
+ DebugUtils.flagsToString(PackageManager.class, "MATCH_", mFlags),
@@ -1226,8 +1313,8 @@ public class ComponentResolver {
}
return null;
}
- final PackageParser.Activity activity = info.activity;
- PackageSetting ps = (PackageSetting) activity.owner.mExtras;
+ PackageSetting ps = (PackageSetting) sPackageManagerInternal.getPackageSetting(
+ info.getPackageName());
if (ps == null) {
if (DEBUG) {
log("info.activity.owner.mExtras == null", info, match, userId);
@@ -1236,10 +1323,10 @@ public class ComponentResolver {
}
final PackageUserState userState = ps.readUserState(userId);
ActivityInfo ai =
- PackageParser.generateActivityInfo(activity, mFlags, userState, userId);
+ PackageInfoUtils.generateActivityInfo(pkg, activity, mFlags, userState, userId);
if (ai == null) {
if (DEBUG) {
- log("Failed to create ActivityInfo based on " + info.activity, info, match,
+ log("Failed to create ActivityInfo based on " + activity, info, match,
userId);
}
return null;
@@ -1289,7 +1376,7 @@ public class ComponentResolver {
}
res.handleAllWebDataURI = info.handleAllWebDataURI();
res.priority = info.getPriority();
- res.preferredOrder = activity.owner.mPreferredOrder;
+ res.preferredOrder = pkg.getPreferredOrder();
//System.out.println("Result: " + res.activityInfo.className +
// " = " + res.priority);
res.match = match;
@@ -1314,40 +1401,64 @@ public class ComponentResolver {
@Override
protected void dumpFilter(PrintWriter out, String prefix,
- PackageParser.ActivityIntentInfo filter) {
+ ParsedActivityIntentInfo filter) {
+ ParsedActivity activity = null;
+
+ AndroidPackage pkg = sPackageManagerInternal.getPackage(filter.getPackageName());
+ if (pkg != null && pkg.getActivities() != null) {
+ for (ParsedActivity parsedActivity : pkg.getActivities()) {
+ if (Objects.equals(parsedActivity.className, filter.getClassName())) {
+ activity = parsedActivity;
+ }
+ }
+ }
+
out.print(prefix);
- out.print(Integer.toHexString(System.identityHashCode(filter.activity)));
+ out.print(Integer.toHexString(System.identityHashCode(activity)));
out.print(' ');
- filter.activity.printComponentShortName(out);
+ ComponentName.printShortString(out, filter.getPackageName(), filter.getClassName());
out.print(" filter ");
out.println(Integer.toHexString(System.identityHashCode(filter)));
}
@Override
- protected Object filterToLabel(PackageParser.ActivityIntentInfo filter) {
- return filter.activity;
+ protected Object filterToLabel(ParsedActivityIntentInfo filter) {
+ return filter;
}
protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
- PackageParser.Activity activity = (PackageParser.Activity) label;
+ ParsedActivityIntentInfo activity = (ParsedActivityIntentInfo) label;
out.print(prefix);
out.print(Integer.toHexString(System.identityHashCode(activity)));
out.print(' ');
- activity.printComponentShortName(out);
+ ComponentName.printShortString(out, activity.getPackageName(), activity.getClassName());
if (count > 1) {
out.print(" ("); out.print(count); out.print(" filters)");
}
out.println();
}
+ protected List<ParsedActivity> getResolveList(AndroidPackage pkg) {
+ return pkg.getActivities();
+ }
+
// Keys are String (activity class name), values are Activity.
- private final ArrayMap<ComponentName, PackageParser.Activity> mActivities =
+ private final ArrayMap<ComponentName, ParsedActivity> mActivities =
new ArrayMap<>();
private int mFlags;
}
+ // Both receivers and activities share a class, but point to different get methods
+ private static final class ReceiverIntentResolver extends ActivityIntentResolver {
+
+ @Override
+ protected List<ParsedActivity> getResolveList(AndroidPackage pkg) {
+ return pkg.getReceivers();
+ }
+ }
+
private static final class ProviderIntentResolver
- extends IntentResolver<PackageParser.ProviderIntentInfo, ResolveInfo> {
+ extends IntentResolver<ParsedProviderIntentInfo, ResolveInfo> {
@Override
public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
boolean defaultOnly, int userId) {
@@ -1367,24 +1478,24 @@ public class ComponentResolver {
}
List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
- int flags, List<PackageParser.Provider> packageProviders, int userId) {
+ int flags, List<ParsedProvider> packageProviders, int userId) {
if (!sUserManager.exists(userId)) {
return null;
}
if (packageProviders == null) {
- return null;
+ return Collections.emptyList();
}
mFlags = flags;
final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0;
final int providersSize = packageProviders.size();
- ArrayList<PackageParser.ProviderIntentInfo[]> listCut = new ArrayList<>(providersSize);
+ ArrayList<ParsedProviderIntentInfo[]> listCut = new ArrayList<>(providersSize);
- ArrayList<PackageParser.ProviderIntentInfo> intentFilters;
+ List<ParsedProviderIntentInfo> intentFilters;
for (int i = 0; i < providersSize; ++i) {
- intentFilters = packageProviders.get(i).intents;
+ intentFilters = packageProviders.get(i).getIntents();
if (intentFilters != null && intentFilters.size() > 0) {
- PackageParser.ProviderIntentInfo[] array =
- new PackageParser.ProviderIntentInfo[intentFilters.size()];
+ ParsedProviderIntentInfo[] array =
+ new ParsedProviderIntentInfo[intentFilters.size()];
intentFilters.toArray(array);
listCut.add(array);
}
@@ -1392,7 +1503,7 @@ public class ComponentResolver {
return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
}
- void addProvider(PackageParser.Provider p) {
+ void addProvider(ParsedProvider p) {
if (mProviders.containsKey(p.getComponentName())) {
Slog.w(TAG, "Provider " + p.getComponentName() + " already defined; ignoring");
return;
@@ -1401,39 +1512,39 @@ public class ComponentResolver {
mProviders.put(p.getComponentName(), p);
if (DEBUG_SHOW_INFO) {
Log.v(TAG, " "
- + (p.info.nonLocalizedLabel != null
- ? p.info.nonLocalizedLabel
- : p.info.name)
+ + (p.nonLocalizedLabel != null
+ ? p.nonLocalizedLabel
+ : p.getName())
+ ":");
- Log.v(TAG, " Class=" + p.info.name);
+ Log.v(TAG, " Class=" + p.getName());
}
- final int intentsSize = p.intents.size();
+ final int intentsSize = p.getIntents().size();
int j;
for (j = 0; j < intentsSize; j++) {
- PackageParser.ProviderIntentInfo intent = p.intents.get(j);
+ ParsedProviderIntentInfo intent = p.getIntents().get(j);
if (DEBUG_SHOW_INFO) {
Log.v(TAG, " IntentFilter:");
intent.dump(new LogPrinter(Log.VERBOSE, TAG), " ");
}
if (!intent.debugCheck()) {
- Log.w(TAG, "==> For Provider " + p.info.name);
+ Log.w(TAG, "==> For Provider " + p.getName());
}
addFilter(intent);
}
}
- void removeProvider(PackageParser.Provider p) {
+ void removeProvider(ParsedProvider p) {
mProviders.remove(p.getComponentName());
if (DEBUG_SHOW_INFO) {
- Log.v(TAG, " " + (p.info.nonLocalizedLabel != null
- ? p.info.nonLocalizedLabel
- : p.info.name) + ":");
- Log.v(TAG, " Class=" + p.info.name);
+ Log.v(TAG, " " + (p.nonLocalizedLabel != null
+ ? p.nonLocalizedLabel
+ : p.getName()) + ":");
+ Log.v(TAG, " Class=" + p.getName());
}
- final int intentsSize = p.intents.size();
+ final int intentsSize = p.getIntents().size();
int j;
for (j = 0; j < intentsSize; j++) {
- PackageParser.ProviderIntentInfo intent = p.intents.get(j);
+ ParsedProviderIntentInfo intent = p.getIntents().get(j);
if (DEBUG_SHOW_INFO) {
Log.v(TAG, " IntentFilter:");
intent.dump(new LogPrinter(Log.VERBOSE, TAG), " ");
@@ -1444,12 +1555,11 @@ public class ComponentResolver {
@Override
protected boolean allowFilterResult(
- PackageParser.ProviderIntentInfo filter, List<ResolveInfo> dest) {
- ProviderInfo filterPi = filter.provider.info;
+ ParsedProviderIntentInfo filter, List<ResolveInfo> dest) {
for (int i = dest.size() - 1; i >= 0; i--) {
ProviderInfo destPi = dest.get(i).providerInfo;
- if (destPi.name == filterPi.name
- && destPi.packageName == filterPi.packageName) {
+ if (Objects.equals(destPi.name, filter.getClassName())
+ && Objects.equals(destPi.packageName, filter.getPackageName())) {
return false;
}
}
@@ -1457,47 +1567,68 @@ public class ComponentResolver {
}
@Override
- protected PackageParser.ProviderIntentInfo[] newArray(int size) {
- return new PackageParser.ProviderIntentInfo[size];
+ protected ParsedProviderIntentInfo[] newArray(int size) {
+ return new ParsedProviderIntentInfo[size];
}
@Override
- protected boolean isFilterStopped(PackageParser.ProviderIntentInfo filter, int userId) {
+ protected boolean isFilterStopped(ParsedProviderIntentInfo filter, int userId) {
if (!sUserManager.exists(userId)) {
return true;
}
- PackageParser.Package p = filter.provider.owner;
- if (p != null) {
- PackageSetting ps = (PackageSetting) p.mExtras;
- if (ps != null) {
- // System apps are never considered stopped for purposes of
- // filtering, because there may be no way for the user to
- // actually re-launch them.
- return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0
- && ps.getStopped(userId);
- }
+
+ AndroidPackage pkg = sPackageManagerInternal.getPackage(filter.getPackageName());
+ if (pkg == null) {
+ return false;
+ }
+
+ PackageSetting ps = (PackageSetting) sPackageManagerInternal.getPackageSetting(
+ filter.getPackageName());
+ if (ps == null) {
+ return false;
}
- return false;
+
+ // System apps are never considered stopped for purposes of
+ // filtering, because there may be no way for the user to
+ // actually re-launch them.
+ return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0
+ && ps.getStopped(userId);
}
@Override
protected boolean isPackageForFilter(String packageName,
- PackageParser.ProviderIntentInfo info) {
- return packageName.equals(info.provider.owner.packageName);
+ ParsedProviderIntentInfo info) {
+ return packageName.equals(info.getPackageName());
}
@Override
- protected ResolveInfo newResult(PackageParser.ProviderIntentInfo filter,
+ protected ResolveInfo newResult(ParsedProviderIntentInfo filter,
int match, int userId) {
if (!sUserManager.exists(userId)) {
return null;
}
- final PackageParser.ProviderIntentInfo info = filter;
- if (!sPackageManagerInternal.isEnabledAndMatches(info.provider.info, mFlags, userId)) {
+
+ ParsedProvider provider = null;
+
+ AndroidPackage pkg = sPackageManagerInternal.getPackage(filter.getPackageName());
+ if (pkg != null && pkg.getProviders() != null) {
+ for (ParsedProvider parsedProvider : pkg.getProviders()) {
+ if (Objects.equals(parsedProvider.className, filter.getClassName())) {
+ provider = parsedProvider;
+ }
+ }
+ }
+
+ if (provider == null) {
+ return null;
+ }
+
+ if (!sPackageManagerInternal.isEnabledAndMatches(provider, mFlags, userId)) {
return null;
}
- final PackageParser.Provider provider = info.provider;
- PackageSetting ps = (PackageSetting) provider.owner.mExtras;
+
+ PackageSetting ps = (PackageSetting) sPackageManagerInternal.getPackageSetting(
+ filter.getPackageName());
if (ps == null) {
return null;
}
@@ -1507,7 +1638,7 @@ public class ComponentResolver {
final boolean isInstantApp = (mFlags & PackageManager.MATCH_INSTANT) != 0;
// throw out filters that aren't visible to instant applications
if (matchVisibleToInstantApp
- && !(info.isVisibleToInstantApp() || userState.instantApp)) {
+ && !(filter.isVisibleToInstantApp() || userState.instantApp)) {
return null;
}
// throw out instant application filters if we're not explicitly requesting them
@@ -1519,8 +1650,8 @@ public class ComponentResolver {
if (userState.instantApp && ps.isUpdateAvailable()) {
return null;
}
- ProviderInfo pi = PackageParser.generateProviderInfo(provider, mFlags,
- userState, userId);
+ ProviderInfo pi = PackageInfoUtils.generateProviderInfo(pkg, provider,
+ mFlags, userState, userId);
if (pi == null) {
return null;
}
@@ -1529,13 +1660,13 @@ public class ComponentResolver {
if ((mFlags & PackageManager.GET_RESOLVED_FILTER) != 0) {
res.filter = filter;
}
- res.priority = info.getPriority();
- res.preferredOrder = provider.owner.mPreferredOrder;
+ res.priority = filter.getPriority();
+ res.preferredOrder = pkg.getPreferredOrder();
res.match = match;
- res.isDefault = info.hasDefault;
- res.labelRes = info.labelRes;
- res.nonLocalizedLabel = info.nonLocalizedLabel;
- res.icon = info.icon;
+ res.isDefault = filter.hasDefault;
+ res.labelRes = filter.labelRes;
+ res.nonLocalizedLabel = filter.nonLocalizedLabel;
+ res.icon = filter.icon;
res.system = res.providerInfo.applicationInfo.isSystemApp();
return res;
}
@@ -1547,26 +1678,37 @@ public class ComponentResolver {
@Override
protected void dumpFilter(PrintWriter out, String prefix,
- PackageParser.ProviderIntentInfo filter) {
+ ParsedProviderIntentInfo filter) {
+ ParsedProvider provider = null;
+
+ AndroidPackage pkg = sPackageManagerInternal.getPackage(filter.getPackageName());
+ if (pkg != null && pkg.getProviders() != null) {
+ for (ParsedProvider parsedProvider : pkg.getProviders()) {
+ if (Objects.equals(parsedProvider.className, filter.getClassName())) {
+ provider = parsedProvider;
+ }
+ }
+ }
+
out.print(prefix);
- out.print(Integer.toHexString(System.identityHashCode(filter.provider)));
+ out.print(Integer.toHexString(System.identityHashCode(provider)));
out.print(' ');
- filter.provider.printComponentShortName(out);
+ ComponentName.printShortString(out, filter.getPackageName(), filter.getClassName());
out.print(" filter ");
out.println(Integer.toHexString(System.identityHashCode(filter)));
}
@Override
- protected Object filterToLabel(PackageParser.ProviderIntentInfo filter) {
- return filter.provider;
+ protected Object filterToLabel(ParsedProviderIntentInfo filter) {
+ return filter;
}
protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
- final PackageParser.Provider provider = (PackageParser.Provider) label;
+ final ParsedProviderIntentInfo provider = (ParsedProviderIntentInfo) label;
out.print(prefix);
out.print(Integer.toHexString(System.identityHashCode(provider)));
out.print(' ');
- provider.printComponentShortName(out);
+ ComponentName.printShortString(out, provider.getPackageName(), provider.getClassName());
if (count > 1) {
out.print(" (");
out.print(count);
@@ -1575,12 +1717,12 @@ public class ComponentResolver {
out.println();
}
- private final ArrayMap<ComponentName, PackageParser.Provider> mProviders = new ArrayMap<>();
+ private final ArrayMap<ComponentName, ParsedProvider> mProviders = new ArrayMap<>();
private int mFlags;
}
private static final class ServiceIntentResolver
- extends IntentResolver<PackageParser.ServiceIntentInfo, ResolveInfo> {
+ extends IntentResolver<ParsedServiceIntentInfo, ResolveInfo> {
@Override
public List<ResolveInfo> queryIntent(Intent intent, String resolvedType,
boolean defaultOnly, int userId) {
@@ -1598,22 +1740,22 @@ public class ComponentResolver {
}
List<ResolveInfo> queryIntentForPackage(Intent intent, String resolvedType,
- int flags, List<PackageParser.Service> packageServices, int userId) {
+ int flags, List<ParsedService> packageServices, int userId) {
if (!sUserManager.exists(userId)) return null;
if (packageServices == null) {
- return null;
+ return Collections.emptyList();
}
mFlags = flags;
final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0;
final int servicesSize = packageServices.size();
- ArrayList<PackageParser.ServiceIntentInfo[]> listCut = new ArrayList<>(servicesSize);
+ ArrayList<ParsedServiceIntentInfo[]> listCut = new ArrayList<>(servicesSize);
- ArrayList<PackageParser.ServiceIntentInfo> intentFilters;
+ List<ParsedServiceIntentInfo> intentFilters;
for (int i = 0; i < servicesSize; ++i) {
intentFilters = packageServices.get(i).intents;
if (intentFilters != null && intentFilters.size() > 0) {
- PackageParser.ServiceIntentInfo[] array =
- new PackageParser.ServiceIntentInfo[intentFilters.size()];
+ ParsedServiceIntentInfo[] array =
+ new ParsedServiceIntentInfo[intentFilters.size()];
intentFilters.toArray(array);
listCut.add(array);
}
@@ -1621,40 +1763,40 @@ public class ComponentResolver {
return super.queryIntentFromList(intent, resolvedType, defaultOnly, listCut, userId);
}
- void addService(PackageParser.Service s) {
+ void addService(ParsedService s) {
mServices.put(s.getComponentName(), s);
if (DEBUG_SHOW_INFO) {
Log.v(TAG, " "
- + (s.info.nonLocalizedLabel != null
- ? s.info.nonLocalizedLabel : s.info.name) + ":");
- Log.v(TAG, " Class=" + s.info.name);
+ + (s.nonLocalizedLabel != null
+ ? s.nonLocalizedLabel : s.getName()) + ":");
+ Log.v(TAG, " Class=" + s.getName());
}
final int intentsSize = s.intents.size();
int j;
for (j = 0; j < intentsSize; j++) {
- PackageParser.ServiceIntentInfo intent = s.intents.get(j);
+ ParsedServiceIntentInfo intent = s.intents.get(j);
if (DEBUG_SHOW_INFO) {
Log.v(TAG, " IntentFilter:");
intent.dump(new LogPrinter(Log.VERBOSE, TAG), " ");
}
if (!intent.debugCheck()) {
- Log.w(TAG, "==> For Service " + s.info.name);
+ Log.w(TAG, "==> For Service " + s.getName());
}
addFilter(intent);
}
}
- void removeService(PackageParser.Service s) {
+ void removeService(ParsedService s) {
mServices.remove(s.getComponentName());
if (DEBUG_SHOW_INFO) {
- Log.v(TAG, " " + (s.info.nonLocalizedLabel != null
- ? s.info.nonLocalizedLabel : s.info.name) + ":");
- Log.v(TAG, " Class=" + s.info.name);
+ Log.v(TAG, " " + (s.nonLocalizedLabel != null
+ ? s.nonLocalizedLabel : s.getName()) + ":");
+ Log.v(TAG, " Class=" + s.getName());
}
final int intentsSize = s.intents.size();
int j;
for (j = 0; j < intentsSize; j++) {
- PackageParser.ServiceIntentInfo intent = s.intents.get(j);
+ ParsedServiceIntentInfo intent = s.intents.get(j);
if (DEBUG_SHOW_INFO) {
Log.v(TAG, " IntentFilter:");
intent.dump(new LogPrinter(Log.VERBOSE, TAG), " ");
@@ -1665,12 +1807,11 @@ public class ComponentResolver {
@Override
protected boolean allowFilterResult(
- PackageParser.ServiceIntentInfo filter, List<ResolveInfo> dest) {
- ServiceInfo filterSi = filter.service.info;
+ ParsedServiceIntentInfo filter, List<ResolveInfo> dest) {
for (int i = dest.size() - 1; i >= 0; --i) {
ServiceInfo destAi = dest.get(i).serviceInfo;
- if (destAi.name == filterSi.name
- && destAi.packageName == filterSi.packageName) {
+ if (Objects.equals(destAi.name, filter.getClassName())
+ && Objects.equals(destAi.packageName, filter.getPackageName())) {
return false;
}
}
@@ -1678,48 +1819,69 @@ public class ComponentResolver {
}
@Override
- protected PackageParser.ServiceIntentInfo[] newArray(int size) {
- return new PackageParser.ServiceIntentInfo[size];
+ protected ParsedServiceIntentInfo[] newArray(int size) {
+ return new ParsedServiceIntentInfo[size];
}
@Override
- protected boolean isFilterStopped(PackageParser.ServiceIntentInfo filter, int userId) {
+ protected boolean isFilterStopped(ParsedServiceIntentInfo filter, int userId) {
if (!sUserManager.exists(userId)) return true;
- PackageParser.Package p = filter.service.owner;
- if (p != null) {
- PackageSetting ps = (PackageSetting) p.mExtras;
- if (ps != null) {
- // System apps are never considered stopped for purposes of
- // filtering, because there may be no way for the user to
- // actually re-launch them.
- return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0
- && ps.getStopped(userId);
- }
+
+ AndroidPackage pkg = sPackageManagerInternal.getPackage(filter.getPackageName());
+ if (pkg == null) {
+ return false;
}
- return false;
+
+ PackageSetting ps = (PackageSetting) sPackageManagerInternal.getPackageSetting(
+ filter.getPackageName());
+ if (ps == null) {
+ return false;
+ }
+
+ // System apps are never considered stopped for purposes of
+ // filtering, because there may be no way for the user to
+ // actually re-launch them.
+ return (ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) == 0
+ && ps.getStopped(userId);
}
@Override
protected boolean isPackageForFilter(String packageName,
- PackageParser.ServiceIntentInfo info) {
- return packageName.equals(info.service.owner.packageName);
+ ParsedServiceIntentInfo info) {
+ return packageName.equals(info.getPackageName());
}
@Override
- protected ResolveInfo newResult(PackageParser.ServiceIntentInfo filter,
+ protected ResolveInfo newResult(ParsedServiceIntentInfo filter,
int match, int userId) {
if (!sUserManager.exists(userId)) return null;
- final PackageParser.ServiceIntentInfo info = (PackageParser.ServiceIntentInfo) filter;
- if (!sPackageManagerInternal.isEnabledAndMatches(info.service.info, mFlags, userId)) {
+
+ ParsedService service = null;
+
+ AndroidPackage pkg = sPackageManagerInternal.getPackage(filter.getPackageName());
+ if (pkg != null && pkg.getServices() != null) {
+ for (ParsedService parsedService : pkg.getServices()) {
+ if (Objects.equals(parsedService.className, filter.getClassName())) {
+ service = parsedService;
+ }
+ }
+ }
+
+ if (service == null) {
+ return null;
+ }
+
+ if (!sPackageManagerInternal.isEnabledAndMatches(service, mFlags, userId)) {
return null;
}
- final PackageParser.Service service = info.service;
- PackageSetting ps = (PackageSetting) service.owner.mExtras;
+
+ PackageSetting ps = (PackageSetting) sPackageManagerInternal.getPackageSetting(
+ filter.getPackageName());
if (ps == null) {
return null;
}
final PackageUserState userState = ps.readUserState(userId);
- ServiceInfo si = PackageParser.generateServiceInfo(service, mFlags,
+ ServiceInfo si = PackageInfoUtils.generateServiceInfo(pkg, service, mFlags,
userState, userId);
if (si == null) {
return null;
@@ -1729,7 +1891,7 @@ public class ComponentResolver {
final boolean isInstantApp = (mFlags & PackageManager.MATCH_INSTANT) != 0;
// throw out filters that aren't visible to ephemeral apps
if (matchVisibleToInstantApp
- && !(info.isVisibleToInstantApp() || userState.instantApp)) {
+ && !(filter.isVisibleToInstantApp() || userState.instantApp)) {
return null;
}
// throw out ephemeral filters if we're not explicitly requesting them
@@ -1746,13 +1908,13 @@ public class ComponentResolver {
if ((mFlags & PackageManager.GET_RESOLVED_FILTER) != 0) {
res.filter = filter;
}
- res.priority = info.getPriority();
- res.preferredOrder = service.owner.mPreferredOrder;
+ res.priority = filter.getPriority();
+ res.preferredOrder = pkg.getPreferredOrder();
res.match = match;
- res.isDefault = info.hasDefault;
- res.labelRes = info.labelRes;
- res.nonLocalizedLabel = info.nonLocalizedLabel;
- res.icon = info.icon;
+ res.isDefault = filter.hasDefault;
+ res.labelRes = filter.labelRes;
+ res.nonLocalizedLabel = filter.nonLocalizedLabel;
+ res.icon = filter.icon;
res.system = res.serviceInfo.applicationInfo.isSystemApp();
return res;
}
@@ -1764,31 +1926,42 @@ public class ComponentResolver {
@Override
protected void dumpFilter(PrintWriter out, String prefix,
- PackageParser.ServiceIntentInfo filter) {
+ ParsedServiceIntentInfo filter) {
+ ParsedService service = null;
+
+ AndroidPackage pkg = sPackageManagerInternal.getPackage(filter.getPackageName());
+ if (pkg != null && pkg.getServices() != null) {
+ for (ParsedService parsedService : pkg.getServices()) {
+ if (Objects.equals(parsedService.className, filter.getClassName())) {
+ service = parsedService;
+ }
+ }
+ }
+
out.print(prefix);
- out.print(Integer.toHexString(System.identityHashCode(filter.service)));
+ out.print(Integer.toHexString(System.identityHashCode(service)));
out.print(' ');
- filter.service.printComponentShortName(out);
+ ComponentName.printShortString(out, filter.getPackageName(), filter.getClassName());
out.print(" filter ");
out.print(Integer.toHexString(System.identityHashCode(filter)));
- if (filter.service.info.permission != null) {
- out.print(" permission "); out.println(filter.service.info.permission);
+ if (service != null && service.getPermission() != null) {
+ out.print(" permission "); out.println(service.getPermission());
} else {
out.println();
}
}
@Override
- protected Object filterToLabel(PackageParser.ServiceIntentInfo filter) {
- return filter.service;
+ protected Object filterToLabel(ParsedServiceIntentInfo filter) {
+ return filter;
}
protected void dumpFilterLabel(PrintWriter out, String prefix, Object label, int count) {
- final PackageParser.Service service = (PackageParser.Service) label;
+ final ParsedServiceIntentInfo service = (ParsedServiceIntentInfo) label;
out.print(prefix);
out.print(Integer.toHexString(System.identityHashCode(service)));
out.print(' ');
- service.printComponentShortName(out);
+ ComponentName.printShortString(out, service.getPackageName(), service.getClassName());
if (count > 1) {
out.print(" ("); out.print(count); out.print(" filters)");
}
@@ -1796,7 +1969,7 @@ public class ComponentResolver {
}
// Keys are String (activity class name), values are Activity.
- private final ArrayMap<ComponentName, PackageParser.Service> mServices = new ArrayMap<>();
+ private final ArrayMap<ComponentName, ParsedService> mServices = new ArrayMap<>();
private int mFlags;
}
@@ -1885,7 +2058,7 @@ public class ComponentResolver {
/** Generic to create an {@link Iterator} for a data type */
static class IterGenerator<E> {
- public Iterator<E> generate(ActivityIntentInfo info) {
+ public Iterator<E> generate(ParsedActivityIntentInfo info) {
return null;
}
}
@@ -1893,7 +2066,7 @@ public class ComponentResolver {
/** Create an {@link Iterator} for intent actions */
static class ActionIterGenerator extends IterGenerator<String> {
@Override
- public Iterator<String> generate(ActivityIntentInfo info) {
+ public Iterator<String> generate(ParsedActivityIntentInfo info) {
return info.actionsIterator();
}
}
@@ -1901,7 +2074,7 @@ public class ComponentResolver {
/** Create an {@link Iterator} for intent categories */
static class CategoriesIterGenerator extends IterGenerator<String> {
@Override
- public Iterator<String> generate(ActivityIntentInfo info) {
+ public Iterator<String> generate(ParsedActivityIntentInfo info) {
return info.categoriesIterator();
}
}
@@ -1909,7 +2082,7 @@ public class ComponentResolver {
/** Create an {@link Iterator} for intent schemes */
static class SchemesIterGenerator extends IterGenerator<String> {
@Override
- public Iterator<String> generate(ActivityIntentInfo info) {
+ public Iterator<String> generate(ParsedActivityIntentInfo info) {
return info.schemesIterator();
}
}
@@ -1917,9 +2090,39 @@ public class ComponentResolver {
/** Create an {@link Iterator} for intent authorities */
static class AuthoritiesIterGenerator extends IterGenerator<IntentFilter.AuthorityEntry> {
@Override
- public Iterator<IntentFilter.AuthorityEntry> generate(ActivityIntentInfo info) {
+ public Iterator<IntentFilter.AuthorityEntry> generate(ParsedActivityIntentInfo info) {
return info.authoritiesIterator();
}
}
+ // TODO(b/135203078): Document or remove this if possible.
+ class EffectiveProvider extends ParsedProvider {
+
+ private String mEffectiveAuthority;
+ private boolean mEffectiveSyncable;
+
+ public EffectiveProvider(ParsedProvider parsedProvider) {
+ this.setFrom(parsedProvider);
+ this.mEffectiveAuthority = parsedProvider.getAuthority();
+ this.mEffectiveSyncable = parsedProvider.isSyncable();
+ }
+
+ public void setEffectiveAuthority(String authority) {
+ this.mEffectiveAuthority = authority;
+ }
+
+ public void setEffectiveSyncable(boolean syncable) {
+ this.mEffectiveSyncable = syncable;
+ }
+
+ @Override
+ public String getAuthority() {
+ return mEffectiveAuthority;
+ }
+
+ @Override
+ public boolean isSyncable() {
+ return mEffectiveSyncable;
+ }
+ }
}
diff --git a/services/core/java/com/android/server/pm/InstantAppRegistry.java b/services/core/java/com/android/server/pm/InstantAppRegistry.java
index 9e04c4b69bd0..f9113fa38825 100644
--- a/services/core/java/com/android/server/pm/InstantAppRegistry.java
+++ b/services/core/java/com/android/server/pm/InstantAppRegistry.java
@@ -20,9 +20,11 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.content.Intent;
+import android.content.pm.ApplicationInfo;
import android.content.pm.InstantAppInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageParser;
+import android.content.pm.parsing.AndroidPackage;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Canvas;
@@ -137,7 +139,7 @@ class InstantAppRegistry {
public byte[] getInstantAppCookieLPw(@NonNull String packageName,
@UserIdInt int userId) {
// Only installed packages can get their own cookie
- PackageParser.Package pkg = mService.mPackages.get(packageName);
+ AndroidPackage pkg = mService.mPackages.get(packageName);
if (pkg == null) {
return null;
}
@@ -171,7 +173,7 @@ class InstantAppRegistry {
}
// Only an installed package can set its own cookie
- PackageParser.Package pkg = mService.mPackages.get(packageName);
+ AndroidPackage pkg = mService.mPackages.get(packageName);
if (pkg == null) {
return false;
}
@@ -264,15 +266,15 @@ class InstantAppRegistry {
}
@GuardedBy("mService.mLock")
- public void onPackageInstalledLPw(@NonNull PackageParser.Package pkg, @NonNull int[] userIds) {
- PackageSetting ps = (PackageSetting) pkg.mExtras;
+ public void onPackageInstalledLPw(@NonNull AndroidPackage pkg, @NonNull int[] userIds) {
+ PackageSetting ps = mService.getPackageSetting(pkg.getPackageName());
if (ps == null) {
return;
}
for (int userId : userIds) {
// Ignore not installed apps
- if (mService.mPackages.get(pkg.packageName) == null || !ps.getInstalled(userId)) {
+ if (mService.mPackages.get(pkg.getPackageName()) == null || !ps.getInstalled(userId)) {
continue;
}
@@ -286,16 +288,16 @@ class InstantAppRegistry {
// Remove the in-memory state
removeUninstalledInstantAppStateLPw((UninstalledInstantAppState state) ->
- state.mInstantAppInfo.getPackageName().equals(pkg.packageName),
+ state.mInstantAppInfo.getPackageName().equals(pkg.getPackageName()),
userId);
// Remove the on-disk state except the cookie
- File instantAppDir = getInstantApplicationDir(pkg.packageName, userId);
+ File instantAppDir = getInstantApplicationDir(pkg.getPackageName(), userId);
new File(instantAppDir, INSTANT_APP_METADATA_FILE).delete();
new File(instantAppDir, INSTANT_APP_ICON_FILE).delete();
// If app signature changed - wipe the cookie
- File currentCookieFile = peekInstantCookieFile(pkg.packageName, userId);
+ File currentCookieFile = peekInstantCookieFile(pkg.getPackageName(), userId);
if (currentCookieFile == null) {
continue;
}
@@ -310,7 +312,7 @@ class InstantAppRegistry {
// We prefer the modern computation procedure where all certs are taken
// into account but also allow the value from the old computation to avoid
// data loss.
- if (pkg.mSigningDetails.checkCapability(currentCookieSha256,
+ if (pkg.getSigningDetails().checkCapability(currentCookieSha256,
PackageParser.SigningDetails.CertCapabilities.INSTALLED_DATA)) {
return;
}
@@ -318,7 +320,7 @@ class InstantAppRegistry {
// For backwards compatibility we accept match based on any signature, since we may have
// recorded only the first for multiply-signed packages
final String[] signaturesSha256Digests =
- PackageUtils.computeSignaturesSha256Digests(pkg.mSigningDetails.signatures);
+ PackageUtils.computeSignaturesSha256Digests(pkg.getSigningDetails().signatures);
for (String s : signaturesSha256Digests) {
if (s.equals(currentCookieSha256)) {
return;
@@ -326,7 +328,7 @@ class InstantAppRegistry {
}
// Sorry, you are out of luck - different signatures - nuke data
- Slog.i(LOG_TAG, "Signature for package " + pkg.packageName
+ Slog.i(LOG_TAG, "Signature for package " + pkg.getPackageName()
+ " changed - dropping cookie");
// Make sure a pending write for the old signed app is cancelled
mCookiePersistence.cancelPendingPersistLPw(pkg, userId);
@@ -335,15 +337,15 @@ class InstantAppRegistry {
}
@GuardedBy("mService.mLock")
- public void onPackageUninstalledLPw(@NonNull PackageParser.Package pkg,
+ public void onPackageUninstalledLPw(@NonNull AndroidPackage pkg,
@NonNull int[] userIds) {
- PackageSetting ps = (PackageSetting) pkg.mExtras;
+ PackageSetting ps = mService.getPackageSetting(pkg.getPackageName());
if (ps == null) {
return;
}
for (int userId : userIds) {
- if (mService.mPackages.get(pkg.packageName) != null && ps.getInstalled(userId)) {
+ if (mService.mPackages.get(pkg.getPackageName()) != null && ps.getInstalled(userId)) {
continue;
}
@@ -353,7 +355,7 @@ class InstantAppRegistry {
removeInstantAppLPw(userId, ps.appId);
} else {
// Deleting an app prunes all instant state such as cookie
- deleteDir(getInstantApplicationDir(pkg.packageName, userId));
+ deleteDir(getInstantApplicationDir(pkg.getPackageName(), userId));
mCookiePersistence.cancelPendingPersistLPw(pkg, userId);
removeAppLPw(userId, ps.appId);
}
@@ -487,7 +489,7 @@ class InstantAppRegistry {
}
@GuardedBy("mService.mLock")
- private void addUninstalledInstantAppLPw(@NonNull PackageParser.Package pkg,
+ private void addUninstalledInstantAppLPw(@NonNull AndroidPackage pkg,
@UserIdInt int userId) {
InstantAppInfo uninstalledApp = createInstantAppInfoForPackage(
pkg, userId, false);
@@ -511,14 +513,15 @@ class InstantAppRegistry {
writeInstantApplicationIconLPw(pkg, userId);
}
- private void writeInstantApplicationIconLPw(@NonNull PackageParser.Package pkg,
+ private void writeInstantApplicationIconLPw(@NonNull AndroidPackage pkg,
@UserIdInt int userId) {
- File appDir = getInstantApplicationDir(pkg.packageName, userId);
+ File appDir = getInstantApplicationDir(pkg.getPackageName(), userId);
if (!appDir.exists()) {
return;
}
- Drawable icon = pkg.applicationInfo.loadIcon(mService.mContext.getPackageManager());
+ // TODO(b/135203078): Remove toAppInfo call? Requires significant additions/changes to PM
+ Drawable icon = pkg.toAppInfo().loadIcon(mService.mContext.getPackageManager());
final Bitmap bitmap;
if (icon instanceof BitmapDrawable) {
@@ -531,7 +534,7 @@ class InstantAppRegistry {
icon.draw(canvas);
}
- File iconFile = new File(getInstantApplicationDir(pkg.packageName, userId),
+ File iconFile = new File(getInstantApplicationDir(pkg.getPackageName(), userId),
INSTANT_APP_ICON_FILE);
try (FileOutputStream out = new FileOutputStream(iconFile)) {
@@ -690,14 +693,16 @@ class InstantAppRegistry {
final int packageCount = mService.mPackages.size();
for (int i = 0; i < packageCount; i++) {
- final PackageParser.Package pkg = mService.mPackages.valueAt(i);
+ final AndroidPackage pkg = mService.mPackages.valueAt(i);
if (now - pkg.getLatestPackageUseTimeInMills() < maxInstalledCacheDuration) {
continue;
}
- if (!(pkg.mExtras instanceof PackageSetting)) {
+
+ final PackageSetting ps = mService.getPackageSetting(pkg.getPackageName());
+ if (ps == null) {
continue;
}
- final PackageSetting ps = (PackageSetting) pkg.mExtras;
+
boolean installedOnlyAsInstantApp = false;
for (int userId : allUsers) {
if (ps.getInstalled(userId)) {
@@ -713,14 +718,14 @@ class InstantAppRegistry {
if (packagesToDelete == null) {
packagesToDelete = new ArrayList<>();
}
- packagesToDelete.add(pkg.packageName);
+ packagesToDelete.add(pkg.getPackageName());
}
}
if (packagesToDelete != null) {
packagesToDelete.sort((String lhs, String rhs) -> {
- final PackageParser.Package lhsPkg = mService.mPackages.get(lhs);
- final PackageParser.Package rhsPkg = mService.mPackages.get(rhs);
+ final AndroidPackage lhsPkg = mService.mPackages.get(lhs);
+ final AndroidPackage rhsPkg = mService.mPackages.get(rhs);
if (lhsPkg == null && rhsPkg == null) {
return 0;
} else if (lhsPkg == null) {
@@ -735,18 +740,23 @@ class InstantAppRegistry {
rhsPkg.getLatestPackageUseTimeInMills()) {
return -1;
} else {
- if (lhsPkg.mExtras instanceof PackageSetting
- && rhsPkg.mExtras instanceof PackageSetting) {
- final PackageSetting lhsPs = (PackageSetting) lhsPkg.mExtras;
- final PackageSetting rhsPs = (PackageSetting) rhsPkg.mExtras;
- if (lhsPs.firstInstallTime > rhsPs.firstInstallTime) {
- return 1;
- } else {
- return -1;
- }
- } else {
+ final PackageSetting lhsPs = mService.getPackageSetting(
+ lhsPkg.getPackageName());
+ if (lhsPs == null) {
+ return 0;
+ }
+
+ final PackageSetting rhsPs = mService.getPackageSetting(
+ rhsPkg.getPackageName());
+ if (rhsPs == null) {
return 0;
}
+
+ if (lhsPs.firstInstallTime > rhsPs.firstInstallTime) {
+ return 1;
+ } else {
+ return -1;
+ }
}
}
});
@@ -818,8 +828,8 @@ class InstantAppRegistry {
final int packageCount = mService.mPackages.size();
for (int i = 0; i < packageCount; i++) {
- final PackageParser.Package pkg = mService.mPackages.valueAt(i);
- final PackageSetting ps = (PackageSetting) pkg.mExtras;
+ final AndroidPackage pkg = mService.mPackages.valueAt(i);
+ final PackageSetting ps = mService.getPackageSetting(pkg.getPackageName());
if (ps == null || !ps.getInstantApp(userId)) {
continue;
}
@@ -839,9 +849,9 @@ class InstantAppRegistry {
private @NonNull
InstantAppInfo createInstantAppInfoForPackage(
- @NonNull PackageParser.Package pkg, @UserIdInt int userId,
+ @NonNull AndroidPackage pkg, @UserIdInt int userId,
boolean addApplicationInfo) {
- PackageSetting ps = (PackageSetting) pkg.mExtras;
+ PackageSetting ps = mService.getPackageSetting(pkg.getPackageName());
if (ps == null) {
return null;
}
@@ -849,19 +859,20 @@ class InstantAppRegistry {
return null;
}
- String[] requestedPermissions = new String[pkg.requestedPermissions.size()];
- pkg.requestedPermissions.toArray(requestedPermissions);
+ String[] requestedPermissions = new String[pkg.getRequestedPermissions().size()];
+ pkg.getRequestedPermissions().toArray(requestedPermissions);
Set<String> permissions = ps.getPermissionsState().getPermissions(userId);
String[] grantedPermissions = new String[permissions.size()];
permissions.toArray(grantedPermissions);
+ ApplicationInfo appInfo = pkg.toAppInfo();
if (addApplicationInfo) {
- return new InstantAppInfo(pkg.applicationInfo,
+ return new InstantAppInfo(appInfo,
requestedPermissions, grantedPermissions);
} else {
- return new InstantAppInfo(pkg.applicationInfo.packageName,
- pkg.applicationInfo.loadLabel(mService.mContext.getPackageManager()),
+ return new InstantAppInfo(appInfo.packageName,
+ appInfo.loadLabel(mService.mContext.getPackageManager()),
requestedPermissions, grantedPermissions);
}
}
@@ -887,10 +898,10 @@ class InstantAppRegistry {
return uninstalledApps;
}
- private void propagateInstantAppPermissionsIfNeeded(@NonNull PackageParser.Package pkg,
+ private void propagateInstantAppPermissionsIfNeeded(@NonNull AndroidPackage pkg,
@UserIdInt int userId) {
InstantAppInfo appInfo = peekOrParseUninstalledInstantAppInfo(
- pkg.packageName, userId);
+ pkg.getPackageName(), userId);
if (appInfo == null) {
return;
}
@@ -902,8 +913,10 @@ class InstantAppRegistry {
for (String grantedPermission : appInfo.getGrantedPermissions()) {
final boolean propagatePermission =
mService.mSettings.canPropagatePermissionToInstantApp(grantedPermission);
- if (propagatePermission && pkg.requestedPermissions.contains(grantedPermission)) {
- mService.grantRuntimePermission(pkg.packageName, grantedPermission, userId);
+ if (propagatePermission && pkg.getRequestedPermissions().contains(
+ grantedPermission)) {
+ mService.grantRuntimePermission(pkg.getPackageName(), grantedPermission,
+ userId);
}
}
} finally {
@@ -1188,18 +1201,19 @@ class InstantAppRegistry {
super(looper);
}
- public void schedulePersistLPw(@UserIdInt int userId, @NonNull PackageParser.Package pkg,
+ public void schedulePersistLPw(@UserIdInt int userId, @NonNull AndroidPackage pkg,
@NonNull byte[] cookie) {
// Before we used only the first signature to compute the SHA 256 but some
// apps could be singed by multiple certs and the cert order is undefined.
// We prefer the modern computation procedure where all certs are taken
// into account and delete the file derived via the legacy hash computation.
- File newCookieFile = computeInstantCookieFile(pkg.packageName,
- PackageUtils.computeSignaturesSha256Digest(pkg.mSigningDetails.signatures), userId);
- if (!pkg.mSigningDetails.hasSignatures()) {
+ File newCookieFile = computeInstantCookieFile(pkg.getPackageName(),
+ PackageUtils.computeSignaturesSha256Digest(pkg.getSigningDetails().signatures),
+ userId);
+ if (!pkg.getSigningDetails().hasSignatures()) {
Slog.wtf(LOG_TAG, "Parsed Instant App contains no valid signatures!");
}
- File oldCookieFile = peekInstantCookieFile(pkg.packageName, userId);
+ File oldCookieFile = peekInstantCookieFile(pkg.getPackageName(), userId);
if (oldCookieFile != null && !newCookieFile.equals(oldCookieFile)) {
oldCookieFile.delete();
}
@@ -1209,12 +1223,12 @@ class InstantAppRegistry {
PERSIST_COOKIE_DELAY_MILLIS);
}
- public @Nullable byte[] getPendingPersistCookieLPr(@NonNull PackageParser.Package pkg,
+ public @Nullable byte[] getPendingPersistCookieLPr(@NonNull AndroidPackage pkg,
@UserIdInt int userId) {
ArrayMap<String, SomeArgs> pendingWorkForUser =
mPendingPersistCookies.get(userId);
if (pendingWorkForUser != null) {
- SomeArgs state = pendingWorkForUser.get(pkg.packageName);
+ SomeArgs state = pendingWorkForUser.get(pkg.getPackageName());
if (state != null) {
return (byte[]) state.arg1;
}
@@ -1222,7 +1236,7 @@ class InstantAppRegistry {
return null;
}
- public void cancelPendingPersistLPw(@NonNull PackageParser.Package pkg,
+ public void cancelPendingPersistLPw(@NonNull AndroidPackage pkg,
@UserIdInt int userId) {
removeMessages(userId, pkg);
SomeArgs state = removePendingPersistCookieLPr(pkg, userId);
@@ -1232,7 +1246,7 @@ class InstantAppRegistry {
}
private void addPendingPersistCookieLPw(@UserIdInt int userId,
- @NonNull PackageParser.Package pkg, @NonNull byte[] cookie,
+ @NonNull AndroidPackage pkg, @NonNull byte[] cookie,
@NonNull File cookieFile) {
ArrayMap<String, SomeArgs> pendingWorkForUser =
mPendingPersistCookies.get(userId);
@@ -1243,16 +1257,16 @@ class InstantAppRegistry {
SomeArgs args = SomeArgs.obtain();
args.arg1 = cookie;
args.arg2 = cookieFile;
- pendingWorkForUser.put(pkg.packageName, args);
+ pendingWorkForUser.put(pkg.getPackageName(), args);
}
- private SomeArgs removePendingPersistCookieLPr(@NonNull PackageParser.Package pkg,
+ private SomeArgs removePendingPersistCookieLPr(@NonNull AndroidPackage pkg,
@UserIdInt int userId) {
ArrayMap<String, SomeArgs> pendingWorkForUser =
mPendingPersistCookies.get(userId);
SomeArgs state = null;
if (pendingWorkForUser != null) {
- state = pendingWorkForUser.remove(pkg.packageName);
+ state = pendingWorkForUser.remove(pkg.getPackageName());
if (pendingWorkForUser.isEmpty()) {
mPendingPersistCookies.remove(userId);
}
@@ -1263,7 +1277,7 @@ class InstantAppRegistry {
@Override
public void handleMessage(Message message) {
int userId = message.what;
- PackageParser.Package pkg = (PackageParser.Package) message.obj;
+ AndroidPackage pkg = (AndroidPackage) message.obj;
SomeArgs state = removePendingPersistCookieLPr(pkg, userId);
if (state == null) {
return;
@@ -1271,7 +1285,7 @@ class InstantAppRegistry {
byte[] cookie = (byte[]) state.arg1;
File cookieFile = (File) state.arg2;
state.recycle();
- persistInstantApplicationCookie(cookie, pkg.packageName, cookieFile, userId);
+ persistInstantApplicationCookie(cookie, pkg.getPackageName(), cookieFile, userId);
}
}
}
diff --git a/services/core/java/com/android/server/pm/InstructionSets.java b/services/core/java/com/android/server/pm/InstructionSets.java
index ec48713b0874..0a065eba4309 100644
--- a/services/core/java/com/android/server/pm/InstructionSets.java
+++ b/services/core/java/com/android/server/pm/InstructionSets.java
@@ -16,7 +16,7 @@
package com.android.server.pm;
-import android.content.pm.ApplicationInfo;
+import android.content.pm.parsing.AndroidPackage;
import android.os.Build;
import android.os.SystemProperties;
import android.text.TextUtils;
@@ -35,30 +35,16 @@ import java.util.List;
public class InstructionSets {
private static final String PREFERRED_INSTRUCTION_SET =
VMRuntime.getInstructionSet(Build.SUPPORTED_ABIS[0]);
- public static String[] getAppDexInstructionSets(ApplicationInfo info) {
- if (info.primaryCpuAbi != null) {
- if (info.secondaryCpuAbi != null) {
- return new String[] {
- VMRuntime.getInstructionSet(info.primaryCpuAbi),
- VMRuntime.getInstructionSet(info.secondaryCpuAbi) };
- } else {
- return new String[] {
- VMRuntime.getInstructionSet(info.primaryCpuAbi) };
- }
- }
- return new String[] { getPreferredInstructionSet() };
- }
-
- public static String[] getAppDexInstructionSets(PackageSetting ps) {
- if (ps.primaryCpuAbiString != null) {
- if (ps.secondaryCpuAbiString != null) {
+ public static String[] getAppDexInstructionSets(String primaryCpuAbi, String secondaryCpuAbi) {
+ if (primaryCpuAbi != null) {
+ if (secondaryCpuAbi != null) {
return new String[] {
- VMRuntime.getInstructionSet(ps.primaryCpuAbiString),
- VMRuntime.getInstructionSet(ps.secondaryCpuAbiString) };
+ VMRuntime.getInstructionSet(primaryCpuAbi),
+ VMRuntime.getInstructionSet(secondaryCpuAbi) };
} else {
return new String[] {
- VMRuntime.getInstructionSet(ps.primaryCpuAbiString) };
+ VMRuntime.getInstructionSet(primaryCpuAbi) };
}
}
@@ -124,4 +110,12 @@ public class InstructionSets {
return VMRuntime.getInstructionSet(abis.primary);
}
+ public static String getPrimaryInstructionSet(AndroidPackage pkg) {
+ if (pkg.getPrimaryCpuAbi() == null) {
+ return getPreferredInstructionSet();
+ }
+
+ return VMRuntime.getInstructionSet(pkg.getPrimaryCpuAbi());
+ }
+
}
diff --git a/services/core/java/com/android/server/pm/IntentFilterVerificationState.java b/services/core/java/com/android/server/pm/IntentFilterVerificationState.java
index a4e9d103b6da..c97d85df00ab 100644
--- a/services/core/java/com/android/server/pm/IntentFilterVerificationState.java
+++ b/services/core/java/com/android/server/pm/IntentFilterVerificationState.java
@@ -17,7 +17,7 @@
package com.android.server.pm;
import android.content.pm.PackageManager;
-import android.content.pm.PackageParser;
+import android.content.pm.parsing.ComponentParseUtils;
import android.util.ArraySet;
import android.util.Slog;
@@ -35,7 +35,7 @@ public class IntentFilterVerificationState {
private int mState;
- private ArrayList<PackageParser.ActivityIntentInfo> mFilters = new ArrayList<>();
+ private ArrayList<ComponentParseUtils.ParsedActivityIntentInfo> mFilters = new ArrayList<>();
private ArraySet<String> mHosts = new ArraySet<>();
private int mUserId;
@@ -66,7 +66,7 @@ public class IntentFilterVerificationState {
setState(STATE_VERIFICATION_PENDING);
}
- public ArrayList<PackageParser.ActivityIntentInfo> getFilters() {
+ public ArrayList<ComponentParseUtils.ParsedActivityIntentInfo> getFilters() {
return mFilters;
}
@@ -123,7 +123,7 @@ public class IntentFilterVerificationState {
return false;
}
- public void addFilter(PackageParser.ActivityIntentInfo filter) {
+ public void addFilter(ComponentParseUtils.ParsedActivityIntentInfo filter) {
mFilters.add(filter);
mHosts.addAll(filter.getHostsList());
}
diff --git a/services/core/java/com/android/server/pm/KeySetManagerService.java b/services/core/java/com/android/server/pm/KeySetManagerService.java
index 93d3b77511bc..70c0f8d98447 100644
--- a/services/core/java/com/android/server/pm/KeySetManagerService.java
+++ b/services/core/java/com/android/server/pm/KeySetManagerService.java
@@ -20,23 +20,26 @@ import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_APK;
import static com.android.server.pm.PackageManagerService.SCAN_INITIAL;
-import com.android.internal.util.Preconditions;
import android.content.pm.PackageParser;
+import android.content.pm.parsing.AndroidPackage;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.Base64;
-import android.util.Slog;
import android.util.LongSparseArray;
+import android.util.Slog;
-import java.io.IOException;
-import java.io.PrintWriter;
-import java.security.PublicKey;
-import java.util.Set;
+import com.android.internal.util.Preconditions;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import org.xmlpull.v1.XmlSerializer;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.security.PublicKey;
+import java.util.Map;
+import java.util.Set;
+
/*
* Manages system-wide KeySet state.
*/
@@ -182,33 +185,31 @@ public class KeySetManagerService {
*
* Returns true if the package can safely be added to the keyset metadata.
*/
- public void assertScannedPackageValid(PackageParser.Package pkg)
+ public void assertScannedPackageValid(AndroidPackage pkg)
throws PackageManagerException {
- if (pkg == null || pkg.packageName == null) {
+ if (pkg == null || pkg.getPackageName() == null) {
throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
"Passed invalid package to keyset validation.");
}
- ArraySet<PublicKey> signingKeys = pkg.mSigningDetails.publicKeys;
+ ArraySet<PublicKey> signingKeys = pkg.getSigningDetails().publicKeys;
if (signingKeys == null || !(signingKeys.size() > 0) || signingKeys.contains(null)) {
throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
"Package has invalid signing-key-set.");
}
- ArrayMap<String, ArraySet<PublicKey>> definedMapping = pkg.mKeySetMapping;
+ Map<String, ArraySet<PublicKey>> definedMapping = pkg.getKeySetMapping();
if (definedMapping != null) {
if (definedMapping.containsKey(null) || definedMapping.containsValue(null)) {
throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
"Package has null defined key set.");
}
- int defMapSize = definedMapping.size();
- for (int i = 0; i < defMapSize; i++) {
- if (!(definedMapping.valueAt(i).size() > 0)
- || definedMapping.valueAt(i).contains(null)) {
+ for (ArraySet<PublicKey> value : definedMapping.values()) {
+ if (!(value.size() > 0) || value.contains(null)) {
throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
"Package has null/no public keys for defined key-sets.");
}
}
}
- ArraySet<String> upgradeAliases = pkg.mUpgradeKeySets;
+ Set<String> upgradeAliases = pkg.getUpgradeKeySets();
if (upgradeAliases != null) {
if (definedMapping == null || !(definedMapping.keySet().containsAll(upgradeAliases))) {
throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
@@ -217,17 +218,17 @@ public class KeySetManagerService {
}
}
- public void addScannedPackageLPw(PackageParser.Package pkg) {
+ public void addScannedPackageLPw(AndroidPackage pkg) {
Preconditions.checkNotNull(pkg, "Attempted to add null pkg to ksms.");
- Preconditions.checkNotNull(pkg.packageName, "Attempted to add null pkg to ksms.");
- PackageSetting ps = mPackages.get(pkg.packageName);
- Preconditions.checkNotNull(ps, "pkg: " + pkg.packageName
+ Preconditions.checkNotNull(pkg.getPackageName(), "Attempted to add null pkg to ksms.");
+ PackageSetting ps = mPackages.get(pkg.getPackageName());
+ Preconditions.checkNotNull(ps, "pkg: " + pkg.getPackageName()
+ "does not have a corresponding entry in mPackages.");
- addSigningKeySetToPackageLPw(ps, pkg.mSigningDetails.publicKeys);
- if (pkg.mKeySetMapping != null) {
- addDefinedKeySetsToPackageLPw(ps, pkg.mKeySetMapping);
- if (pkg.mUpgradeKeySets != null) {
- addUpgradeKeySetsToPackageLPw(ps, pkg.mUpgradeKeySets);
+ addSigningKeySetToPackageLPw(ps, pkg.getSigningDetails().publicKeys);
+ if (pkg.getKeySetMapping() != null) {
+ addDefinedKeySetsToPackageLPw(ps, pkg.getKeySetMapping());
+ if (pkg.getUpgradeKeySets() != null) {
+ addUpgradeKeySetsToPackageLPw(ps, pkg.getUpgradeKeySets());
}
}
}
@@ -280,15 +281,14 @@ public class KeySetManagerService {
* Remove any KeySets the package no longer defines.
*/
void addDefinedKeySetsToPackageLPw(PackageSetting pkg,
- ArrayMap<String, ArraySet<PublicKey>> definedMapping) {
+ Map<String, ArraySet<PublicKey>> definedMapping) {
ArrayMap<String, Long> prevDefinedKeySets = pkg.keySetData.getAliases();
/* add all of the newly defined KeySets */
- ArrayMap<String, Long> newKeySetAliases = new ArrayMap<String, Long>();
- final int defMapSize = definedMapping.size();
- for (int i = 0; i < defMapSize; i++) {
- String alias = definedMapping.keyAt(i);
- ArraySet<PublicKey> pubKeys = definedMapping.valueAt(i);
+ Map<String, Long> newKeySetAliases = new ArrayMap<>();
+ for (Map.Entry<String, ArraySet<PublicKey>> entry : definedMapping.entrySet()) {
+ String alias = entry.getKey();
+ ArraySet<PublicKey> pubKeys = entry.getValue();
if (alias != null && pubKeys != null && pubKeys.size() > 0) {
KeySetHandle ks = addKeySetLPw(pubKeys);
newKeySetAliases.put(alias, ks.getId());
@@ -313,12 +313,10 @@ public class KeySetManagerService {
* after all of the defined KeySets have been added.
*/
void addUpgradeKeySetsToPackageLPw(PackageSetting pkg,
- ArraySet<String> upgradeAliases) {
- final int uaSize = upgradeAliases.size();
- for (int i = 0; i < uaSize; i++) {
- pkg.keySetData.addUpgradeKeySet(upgradeAliases.valueAt(i));
+ Set<String> upgradeAliases) {
+ for (String upgradeAlias : upgradeAliases) {
+ pkg.keySetData.addUpgradeKeySet(upgradeAlias);
}
- return;
}
/**
@@ -364,14 +362,14 @@ public class KeySetManagerService {
return true;
}
- public boolean checkUpgradeKeySetLocked(PackageSettingBase oldPS,
- PackageParser.Package newPkg) {
+ public boolean checkUpgradeKeySetLocked(PackageSettingBase oldPS, AndroidPackage pkg) {
// Upgrade keysets are being used. Determine if new package has a superset of the
// required keys.
long[] upgradeKeySets = oldPS.keySetData.getUpgradeKeySets();
for (int i = 0; i < upgradeKeySets.length; i++) {
Set<PublicKey> upgradeSet = getPublicKeysFromKeySetLPr(upgradeKeySets[i]);
- if (upgradeSet != null && newPkg.mSigningDetails.publicKeys.containsAll(upgradeSet)) {
+ if (upgradeSet != null
+ && pkg.getSigningDetails().publicKeys.containsAll(upgradeSet)) {
return true;
}
}
diff --git a/services/core/java/com/android/server/pm/LauncherAppsService.java b/services/core/java/com/android/server/pm/LauncherAppsService.java
index 3464cab99d93..c844f1bd95ff 100644
--- a/services/core/java/com/android/server/pm/LauncherAppsService.java
+++ b/services/core/java/com/android/server/pm/LauncherAppsService.java
@@ -40,13 +40,13 @@ import android.content.pm.PackageInfo;
import android.content.pm.PackageInstaller.SessionInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManagerInternal;
-import android.content.pm.PackageParser;
import android.content.pm.ParceledListSlice;
import android.content.pm.ResolveInfo;
import android.content.pm.ShortcutInfo;
import android.content.pm.ShortcutServiceInternal;
import android.content.pm.ShortcutServiceInternal.ShortcutChangeListener;
import android.content.pm.UserInfo;
+import android.content.pm.parsing.AndroidPackage;
import android.graphics.Rect;
import android.net.Uri;
import android.os.Binder;
@@ -445,7 +445,7 @@ public class LauncherAppsService extends SystemService {
}
final PackageManagerInternal pmInt =
LocalServices.getService(PackageManagerInternal.class);
- final PackageParser.Package pkg = pmInt.getPackage(appInfo.packageName);
+ final AndroidPackage pkg = pmInt.getPackage(appInfo.packageName);
if (pkg == null) {
// Should not happen, but we shouldn't be failing if it does
return false;
@@ -456,8 +456,8 @@ public class LauncherAppsService extends SystemService {
appInfo.packageName);
}
- private boolean requestsPermissions(@NonNull PackageParser.Package pkg) {
- return !ArrayUtils.isEmpty(pkg.requestedPermissions);
+ private boolean requestsPermissions(@NonNull AndroidPackage pkg) {
+ return !ArrayUtils.isEmpty(pkg.getRequestedPermissions());
}
private boolean hasDefaultEnableLauncherActivity(@NonNull String packageName) {
diff --git a/services/core/java/com/android/server/pm/OtaDexoptService.java b/services/core/java/com/android/server/pm/OtaDexoptService.java
index d49ecdda679d..ae7a4a7b81f5 100644
--- a/services/core/java/com/android/server/pm/OtaDexoptService.java
+++ b/services/core/java/com/android/server/pm/OtaDexoptService.java
@@ -22,7 +22,7 @@ import static com.android.server.pm.InstructionSets.getDexCodeInstructionSets;
import android.annotation.Nullable;
import android.content.Context;
import android.content.pm.IOtaDexopt;
-import android.content.pm.PackageParser;
+import android.content.pm.parsing.AndroidPackage;
import android.os.Environment;
import android.os.RemoteException;
import android.os.ResultReceiver;
@@ -118,8 +118,8 @@ public class OtaDexoptService extends IOtaDexopt.Stub {
if (mDexoptCommands != null) {
throw new IllegalStateException("already called prepare()");
}
- final List<PackageParser.Package> important;
- final List<PackageParser.Package> others;
+ final List<AndroidPackage> important;
+ final List<AndroidPackage> others;
synchronized (mPackageManagerService.mLock) {
// Important: the packages we need to run with ab-ota compiler-reason.
important = PackageManagerServiceUtils.getPackagesForDexopt(
@@ -133,12 +133,12 @@ public class OtaDexoptService extends IOtaDexopt.Stub {
mDexoptCommands = new ArrayList<>(3 * mPackageManagerService.mPackages.size() / 2);
}
- for (PackageParser.Package p : important) {
+ for (AndroidPackage p : important) {
mDexoptCommands.addAll(generatePackageDexopts(p, PackageManagerService.REASON_AB_OTA));
}
- for (PackageParser.Package p : others) {
+ for (AndroidPackage p : others) {
// We assume here that there are no core apps left.
- if (p.coreApp) {
+ if (p.isCoreApp()) {
throw new IllegalStateException("Found a core app that's not important");
}
mDexoptCommands.addAll(
@@ -150,8 +150,8 @@ public class OtaDexoptService extends IOtaDexopt.Stub {
if (spaceAvailable < BULK_DELETE_THRESHOLD) {
Log.i(TAG, "Low on space, deleting oat files in an attempt to free up space: "
+ PackageManagerServiceUtils.packagesToString(others));
- for (PackageParser.Package pkg : others) {
- mPackageManagerService.deleteOatArtifactsOfPackage(pkg.packageName);
+ for (AndroidPackage pkg : others) {
+ mPackageManagerService.deleteOatArtifactsOfPackage(pkg.getPackageName());
}
}
long spaceAvailableNow = getAvailableSpace();
@@ -161,15 +161,15 @@ public class OtaDexoptService extends IOtaDexopt.Stub {
if (DEBUG_DEXOPT) {
try {
// Output some data about the packages.
- PackageParser.Package lastUsed = Collections.max(important,
+ AndroidPackage lastUsed = Collections.max(important,
(pkg1, pkg2) -> Long.compare(
pkg1.getLatestForegroundPackageUseTimeInMills(),
pkg2.getLatestForegroundPackageUseTimeInMills()));
Log.d(TAG, "A/B OTA: lastUsed time = "
+ lastUsed.getLatestForegroundPackageUseTimeInMills());
Log.d(TAG, "A/B OTA: deprioritized packages:");
- for (PackageParser.Package pkg : others) {
- Log.d(TAG, " " + pkg.packageName + " - "
+ for (AndroidPackage pkg : others) {
+ Log.d(TAG, " " + pkg.getPackageName() + " - "
+ pkg.getLatestForegroundPackageUseTimeInMills());
}
} catch (Exception ignored) {
@@ -262,7 +262,7 @@ public class OtaDexoptService extends IOtaDexopt.Stub {
/**
* Generate all dexopt commands for the given package.
*/
- private synchronized List<String> generatePackageDexopts(PackageParser.Package pkg,
+ private synchronized List<String> generatePackageDexopts(AndroidPackage pkg,
int compilationReason) {
// Intercept and collect dexopt requests
final List<String> commands = new ArrayList<String>();
@@ -336,8 +336,9 @@ public class OtaDexoptService extends IOtaDexopt.Stub {
optimizer.performDexOpt(pkg,
null /* ISAs */,
null /* CompilerStats.PackageStats */,
- mPackageManagerService.getDexManager().getPackageUseInfoOrDefault(pkg.packageName),
- new DexoptOptions(pkg.packageName, compilationReason,
+ mPackageManagerService.getDexManager().getPackageUseInfoOrDefault(
+ pkg.getPackageName()),
+ new DexoptOptions(pkg.getPackageName(), compilationReason,
DexoptOptions.DEXOPT_BOOT_COMPLETE));
return commands;
@@ -359,10 +360,10 @@ public class OtaDexoptService extends IOtaDexopt.Stub {
}
// Look into all packages.
- Collection<PackageParser.Package> pkgs = mPackageManagerService.getPackages();
+ Collection<AndroidPackage> pkgs = mPackageManagerService.getPackages();
int packagePaths = 0;
int pathsSuccessful = 0;
- for (PackageParser.Package pkg : pkgs) {
+ for (AndroidPackage pkg : pkgs) {
if (pkg == null) {
continue;
}
@@ -371,27 +372,28 @@ public class OtaDexoptService extends IOtaDexopt.Stub {
if (!PackageDexOptimizer.canOptimizePackage(pkg)) {
continue;
}
- if (pkg.codePath == null) {
+ if (pkg.getCodePath() == null) {
Slog.w(TAG, "Package " + pkg + " can be optimized but has null codePath");
continue;
}
// If the path is in /system, /vendor, /product or /system_ext, ignore. It will
// have been ota-dexopted into /data/ota and moved into the dalvik-cache already.
- if (pkg.codePath.startsWith("/system")
- || pkg.codePath.startsWith("/vendor")
- || pkg.codePath.startsWith("/product")
- || pkg.codePath.startsWith("/system_ext")) {
+ if (pkg.getCodePath().startsWith("/system")
+ || pkg.getCodePath().startsWith("/vendor")
+ || pkg.getCodePath().startsWith("/product")
+ || pkg.getCodePath().startsWith("/system_ext")) {
continue;
}
- final String[] instructionSets = getAppDexInstructionSets(pkg.applicationInfo);
+ final String[] instructionSets = getAppDexInstructionSets(pkg.getPrimaryCpuAbi(),
+ pkg.getSecondaryCpuAbi());
final List<String> paths = pkg.getAllCodePathsExcludingResourceOnly();
final String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets);
for (String dexCodeInstructionSet : dexCodeInstructionSets) {
for (String path : paths) {
- String oatDir = PackageDexOptimizer.getOatDir(new File(pkg.codePath)).
- getAbsolutePath();
+ String oatDir = PackageDexOptimizer.getOatDir(
+ new File(pkg.getCodePath())).getAbsolutePath();
// TODO: Check first whether there is an artifact, to save the roundtrip time.
diff --git a/services/core/java/com/android/server/pm/PackageAbiHelper.java b/services/core/java/com/android/server/pm/PackageAbiHelper.java
index c21d0cf54d91..d7c161cc1a86 100644
--- a/services/core/java/com/android/server/pm/PackageAbiHelper.java
+++ b/services/core/java/com/android/server/pm/PackageAbiHelper.java
@@ -17,7 +17,8 @@
package com.android.server.pm;
import android.annotation.Nullable;
-import android.content.pm.PackageParser;
+import android.content.pm.parsing.AndroidPackage;
+import android.content.pm.parsing.ParsedPackage;
import android.util.Pair;
import com.android.internal.annotations.VisibleForTesting;
@@ -25,21 +26,21 @@ import com.android.internal.annotations.VisibleForTesting;
import java.io.File;
import java.util.Set;
+// TODO: Move to .parsing sub-package
@VisibleForTesting
public interface PackageAbiHelper {
/**
* Derive and get the location of native libraries for the given package,
* which varies depending on where and how the package was installed.
*/
- NativeLibraryPaths getNativeLibraryPaths(
- PackageParser.Package pkg, File appLib32InstallDir);
+ NativeLibraryPaths getNativeLibraryPaths(AndroidPackage pkg, File appLib32InstallDir);
/**
* Calculate the abis for a bundled app. These can uniquely be determined from the contents of
* the system partition, i.e whether it contains 64 or 32 bit shared libraries etc. We do not
* validate any of this information, and instead assume that the system was built sensibly.
*/
- Abis getBundledAppAbis(PackageParser.Package pkg);
+ Abis getBundledAppAbis(AndroidPackage pkg);
/**
* Derive the ABI of a non-system package located at {@code pkg}. This information
@@ -48,7 +49,7 @@ public interface PackageAbiHelper {
* If {@code extractLibs} is true, native libraries are extracted from the app if required.
*/
Pair<Abis, NativeLibraryPaths> derivePackageAbi(
- PackageParser.Package pkg, String cpuAbiOverride, boolean extractLibs)
+ AndroidPackage pkg, String cpuAbiOverride, boolean extractLibs)
throws PackageManagerException;
/**
@@ -69,11 +70,11 @@ public interface PackageAbiHelper {
*/
@Nullable
String getAdjustedAbiForSharedUser(
- Set<PackageSetting> packagesForUser, PackageParser.Package scannedPackage);
+ Set<PackageSetting> packagesForUser, AndroidPackage scannedPackage);
/**
* The native library paths and related properties that should be set on a
- * {@link android.content.pm.PackageParser.Package}.
+ * {@link ParsedPackage}.
*/
final class NativeLibraryPaths {
public final String nativeLibraryRootDir;
@@ -91,11 +92,11 @@ public interface PackageAbiHelper {
this.secondaryNativeLibraryDir = secondaryNativeLibraryDir;
}
- public void applyTo(PackageParser.Package pkg) {
- pkg.applicationInfo.nativeLibraryRootDir = nativeLibraryRootDir;
- pkg.applicationInfo.nativeLibraryRootRequiresIsa = nativeLibraryRootRequiresIsa;
- pkg.applicationInfo.nativeLibraryDir = nativeLibraryDir;
- pkg.applicationInfo.secondaryNativeLibraryDir = secondaryNativeLibraryDir;
+ public void applyTo(ParsedPackage pkg) {
+ pkg.setNativeLibraryRootDir(nativeLibraryRootDir)
+ .setNativeLibraryRootRequiresIsa(nativeLibraryRootRequiresIsa)
+ .setNativeLibraryDir(nativeLibraryDir)
+ .setSecondaryNativeLibraryDir(secondaryNativeLibraryDir);
}
}
@@ -112,13 +113,13 @@ public interface PackageAbiHelper {
this.secondary = secondary;
}
- Abis(PackageParser.Package pkg) {
- this(pkg.applicationInfo.primaryCpuAbi, pkg.applicationInfo.secondaryCpuAbi);
+ Abis(AndroidPackage pkg) {
+ this(pkg.getPrimaryCpuAbi(), pkg.getSecondaryCpuAbi());
}
- public void applyTo(PackageParser.Package pkg) {
- pkg.applicationInfo.primaryCpuAbi = primary;
- pkg.applicationInfo.secondaryCpuAbi = secondary;
+ public void applyTo(ParsedPackage pkg) {
+ pkg.setPrimaryCpuAbi(primary)
+ .setSecondaryCpuAbi(secondary);
}
public void applyTo(PackageSetting pkgSetting) {
// pkgSetting might be null during rescan following uninstall of updates
diff --git a/services/core/java/com/android/server/pm/PackageAbiHelperImpl.java b/services/core/java/com/android/server/pm/PackageAbiHelperImpl.java
index 1d3d24c27041..6de5203f0f73 100644
--- a/services/core/java/com/android/server/pm/PackageAbiHelperImpl.java
+++ b/services/core/java/com/android/server/pm/PackageAbiHelperImpl.java
@@ -28,7 +28,7 @@ import static com.android.server.pm.InstructionSets.getPrimaryInstructionSet;
import android.annotation.Nullable;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
-import android.content.pm.PackageParser;
+import android.content.pm.parsing.AndroidPackage;
import android.os.Build;
import android.os.Environment;
import android.os.FileUtils;
@@ -122,10 +122,10 @@ final class PackageAbiHelperImpl implements PackageAbiHelper {
@Override
public NativeLibraryPaths getNativeLibraryPaths(
- PackageParser.Package pkg, File appLib32InstallDir) {
- return getNativeLibraryPaths(new Abis(pkg), appLib32InstallDir, pkg.codePath,
- pkg.applicationInfo.sourceDir, pkg.applicationInfo.isSystemApp(),
- pkg.applicationInfo.isUpdatedSystemApp());
+ AndroidPackage pkg, File appLib32InstallDir) {
+ return getNativeLibraryPaths(new Abis(pkg), appLib32InstallDir, pkg.getCodePath(),
+ pkg.getBaseCodePath(), pkg.isSystemApp(),
+ pkg.isUpdatedSystemApp());
}
private static NativeLibraryPaths getNativeLibraryPaths(final Abis abis,
@@ -192,12 +192,12 @@ final class PackageAbiHelperImpl implements PackageAbiHelper {
}
@Override
- public Abis getBundledAppAbis(PackageParser.Package pkg) {
- final String apkName = deriveCodePathName(pkg.applicationInfo.getCodePath());
+ public Abis getBundledAppAbis(AndroidPackage pkg) {
+ final String apkName = deriveCodePathName(pkg.getCodePath());
// If "/system/lib64/apkname" exists, assume that is the per-package
// native library directory to use; otherwise use "/system/lib/apkname".
- final String apkRoot = calculateBundledApkRoot(pkg.applicationInfo.sourceDir);
+ final String apkRoot = calculateBundledApkRoot(pkg.getBaseCodePath());
final Abis abis = getBundledAppAbi(pkg, apkRoot, apkName);
return abis;
}
@@ -210,8 +210,8 @@ final class PackageAbiHelperImpl implements PackageAbiHelper {
* {@code /oem} under which system libraries are installed.
* @param apkName the name of the installed package.
*/
- private Abis getBundledAppAbi(PackageParser.Package pkg, String apkRoot, String apkName) {
- final File codeFile = new File(pkg.codePath);
+ private Abis getBundledAppAbi(AndroidPackage pkg, String apkRoot, String apkName) {
+ final File codeFile = new File(pkg.getCodePath());
final boolean has64BitLibs;
final boolean has32BitLibs;
@@ -263,7 +263,7 @@ final class PackageAbiHelperImpl implements PackageAbiHelper {
// ABI that's higher on the list, i.e, a device that's configured to prefer
// 64 bit apps will see a 64 bit primary ABI,
- if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_MULTIARCH) == 0) {
+ if ((pkg.getFlags() & ApplicationInfo.FLAG_MULTIARCH) == 0) {
Slog.e(PackageManagerService.TAG,
"Package " + pkg + " has multiple bundled libs, but is not multiarch.");
}
@@ -284,14 +284,14 @@ final class PackageAbiHelperImpl implements PackageAbiHelper {
@Override
public Pair<Abis, NativeLibraryPaths> derivePackageAbi(
- PackageParser.Package pkg, String cpuAbiOverride, boolean extractLibs)
+ AndroidPackage pkg, String cpuAbiOverride, boolean extractLibs)
throws PackageManagerException {
// Give ourselves some initial paths; we'll come back for another
// pass once we've determined ABI below.
final NativeLibraryPaths initialLibraryPaths = getNativeLibraryPaths(new Abis(pkg),
- PackageManagerService.sAppLib32InstallDir, pkg.codePath,
- pkg.applicationInfo.sourceDir, pkg.applicationInfo.isSystemApp(),
- pkg.applicationInfo.isUpdatedSystemApp());
+ PackageManagerService.sAppLib32InstallDir, pkg.getCodePath(),
+ pkg.getBaseCodePath(), pkg.isSystemApp(),
+ pkg.isUpdatedSystemApp());
// We shouldn't attempt to extract libs from system app when it was not updated.
if (PackageManagerService.isSystemApp(pkg) && !pkg.isUpdatedSystemApp()) {
@@ -318,12 +318,13 @@ final class PackageAbiHelperImpl implements PackageAbiHelper {
// Null out the abis so that they can be recalculated.
primaryCpuAbi = null;
secondaryCpuAbi = null;
- if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_MULTIARCH) != 0) {
+ if ((pkg.getFlags() & ApplicationInfo.FLAG_MULTIARCH) != 0) {
// Warn if we've set an abiOverride for multi-lib packages..
// By definition, we need to copy both 32 and 64 bit libraries for
// such packages.
- if (pkg.cpuAbiOverride != null
- && !NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(pkg.cpuAbiOverride)) {
+ if (pkg.getCpuAbiOverride() != null
+ && !NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(
+ pkg.getCpuAbiOverride())) {
Slog.w(PackageManagerService.TAG,
"Ignoring abiOverride for multi arch application.");
}
@@ -382,7 +383,7 @@ final class PackageAbiHelperImpl implements PackageAbiHelper {
if (abi32 >= 0) {
final String abi = Build.SUPPORTED_32_BIT_ABIS[abi32];
if (abi64 >= 0) {
- if (pkg.use32bitAbi) {
+ if (pkg.isUse32BitAbi()) {
secondaryCpuAbi = primaryCpuAbi;
primaryCpuAbi = abi;
} else {
@@ -449,9 +450,9 @@ final class PackageAbiHelperImpl implements PackageAbiHelper {
final Abis abis = new Abis(primaryCpuAbi, secondaryCpuAbi);
return new Pair<>(abis,
getNativeLibraryPaths(abis, PackageManagerService.sAppLib32InstallDir,
- pkg.codePath, pkg.applicationInfo.sourceDir,
- pkg.applicationInfo.isSystemApp(),
- pkg.applicationInfo.isUpdatedSystemApp()));
+ pkg.getCodePath(), pkg.getBaseCodePath(),
+ pkg.isSystemApp(),
+ pkg.isUpdatedSystemApp()));
}
/**
@@ -470,11 +471,11 @@ final class PackageAbiHelperImpl implements PackageAbiHelper {
@Override
@Nullable
public String getAdjustedAbiForSharedUser(
- Set<PackageSetting> packagesForUser, PackageParser.Package scannedPackage) {
+ Set<PackageSetting> packagesForUser, AndroidPackage scannedPackage) {
String requiredInstructionSet = null;
- if (scannedPackage != null && scannedPackage.applicationInfo.primaryCpuAbi != null) {
+ if (scannedPackage != null && scannedPackage.getPrimaryCpuAbi() != null) {
requiredInstructionSet = VMRuntime.getInstructionSet(
- scannedPackage.applicationInfo.primaryCpuAbi);
+ scannedPackage.getPrimaryCpuAbi());
}
PackageSetting requirer = null;
@@ -483,7 +484,7 @@ final class PackageAbiHelperImpl implements PackageAbiHelper {
// when scannedPackage is an update of an existing package. Without this check,
// we will never be able to change the ABI of any package belonging to a shared
// user, even if it's compatible with other packages.
- if (scannedPackage != null && scannedPackage.packageName.equals(ps.name)) {
+ if (scannedPackage != null && scannedPackage.getPackageName().equals(ps.name)) {
continue;
}
if (ps.primaryCpuAbiString == null) {
@@ -521,7 +522,7 @@ final class PackageAbiHelperImpl implements PackageAbiHelper {
} else {
// requirer == null implies that we're updating all ABIs in the set to
// match scannedPackage.
- adjustedAbi = scannedPackage.applicationInfo.primaryCpuAbi;
+ adjustedAbi = scannedPackage.getPrimaryCpuAbi();
}
return adjustedAbi;
}
diff --git a/services/core/java/com/android/server/pm/PackageDexOptimizer.java b/services/core/java/com/android/server/pm/PackageDexOptimizer.java
index 4f7c8c8da4a9..2b422211077b 100644
--- a/services/core/java/com/android/server/pm/PackageDexOptimizer.java
+++ b/services/core/java/com/android/server/pm/PackageDexOptimizer.java
@@ -41,10 +41,10 @@ import static dalvik.system.DexFile.isProfileGuidedCompilerFilter;
import android.annotation.Nullable;
import android.content.Context;
import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageParser;
import android.content.pm.SharedLibraryInfo;
import android.content.pm.dex.ArtManager;
import android.content.pm.dex.DexMetadataHelper;
+import android.content.pm.parsing.AndroidPackage;
import android.os.FileUtils;
import android.os.PowerManager;
import android.os.SystemClock;
@@ -53,6 +53,7 @@ import android.os.UserHandle;
import android.os.WorkSource;
import android.util.Log;
import android.util.Slog;
+import android.util.SparseArray;
import com.android.internal.annotations.GuardedBy;
import com.android.internal.util.IndentingPrintWriter;
@@ -109,9 +110,9 @@ public class PackageDexOptimizer {
this.mSystemReady = from.mSystemReady;
}
- static boolean canOptimizePackage(PackageParser.Package pkg) {
+ static boolean canOptimizePackage(AndroidPackage pkg) {
// We do not dexopt a package with no code.
- if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_HAS_CODE) == 0) {
+ if ((pkg.getFlags() & ApplicationInfo.FLAG_HAS_CODE) == 0) {
return false;
}
@@ -125,18 +126,18 @@ public class PackageDexOptimizer {
* <p>Calls to {@link com.android.server.pm.Installer#dexopt} on {@link #mInstaller} are
* synchronized on {@link #mInstallLock}.
*/
- int performDexOpt(PackageParser.Package pkg,
+ int performDexOpt(AndroidPackage pkg,
String[] instructionSets, CompilerStats.PackageStats packageStats,
PackageDexUsage.PackageUseInfo packageUseInfo, DexoptOptions options) {
- if (pkg.applicationInfo.uid == -1) {
- throw new IllegalArgumentException("Dexopt for " + pkg.packageName
+ if (pkg.getUid() == -1) {
+ throw new IllegalArgumentException("Dexopt for " + pkg.getPackageName()
+ " has invalid uid.");
}
if (!canOptimizePackage(pkg)) {
return DEX_OPT_SKIPPED;
}
synchronized (mInstallLock) {
- final long acquireTime = acquireWakeLockLI(pkg.applicationInfo.uid);
+ final long acquireTime = acquireWakeLockLI(pkg.getUid());
try {
return performDexOptLI(pkg, instructionSets,
packageStats, packageUseInfo, options);
@@ -151,19 +152,20 @@ public class PackageDexOptimizer {
* It assumes the install lock is held.
*/
@GuardedBy("mInstallLock")
- private int performDexOptLI(PackageParser.Package pkg,
+ private int performDexOptLI(AndroidPackage pkg,
String[] targetInstructionSets, CompilerStats.PackageStats packageStats,
PackageDexUsage.PackageUseInfo packageUseInfo, DexoptOptions options) {
- final List<SharedLibraryInfo> sharedLibraries = pkg.usesLibraryInfos;
+ final List<SharedLibraryInfo> sharedLibraries = pkg.getUsesLibraryInfos();
final String[] instructionSets = targetInstructionSets != null ?
- targetInstructionSets : getAppDexInstructionSets(pkg.applicationInfo);
+ targetInstructionSets : getAppDexInstructionSets(pkg.getPrimaryCpuAbi(),
+ pkg.getSecondaryCpuAbi());
final String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets);
final List<String> paths = pkg.getAllCodePaths();
- int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid);
+ int sharedGid = UserHandle.getSharedAppGid(pkg.getUid());
if (sharedGid == -1) {
- Slog.wtf(TAG, "Well this is awkward; package " + pkg.applicationInfo.name + " had UID "
- + pkg.applicationInfo.uid, new Throwable());
+ Slog.wtf(TAG, "Well this is awkward; package " + pkg.getAppInfoName() + " had UID "
+ + pkg.getUid(), new Throwable());
sharedGid = android.os.Process.NOBODY_UID;
}
@@ -171,21 +173,21 @@ public class PackageDexOptimizer {
// For each code path in the package, this array contains the class loader context that
// needs to be passed to dexopt in order to ensure correct optimizations.
boolean[] pathsWithCode = new boolean[paths.size()];
- pathsWithCode[0] = (pkg.applicationInfo.flags & ApplicationInfo.FLAG_HAS_CODE) != 0;
+ pathsWithCode[0] = (pkg.getFlags() & ApplicationInfo.FLAG_HAS_CODE) != 0;
for (int i = 1; i < paths.size(); i++) {
- pathsWithCode[i] = (pkg.splitFlags[i - 1] & ApplicationInfo.FLAG_HAS_CODE) != 0;
+ pathsWithCode[i] = (pkg.getSplitFlags()[i - 1] & ApplicationInfo.FLAG_HAS_CODE) != 0;
}
String[] classLoaderContexts = DexoptUtils.getClassLoaderContexts(
- pkg.applicationInfo, sharedLibraries, pathsWithCode);
+ pkg, sharedLibraries, pathsWithCode);
// Sanity check that we do not call dexopt with inconsistent data.
if (paths.size() != classLoaderContexts.length) {
- String[] splitCodePaths = pkg.applicationInfo.getSplitCodePaths();
+ String[] splitCodePaths = pkg.getSplitCodePaths();
throw new IllegalStateException("Inconsistent information "
+ "between PackageParser.Package and its ApplicationInfo. "
+ "pkg.getAllCodePaths=" + paths
- + " pkg.applicationInfo.getBaseCodePath=" + pkg.applicationInfo.getBaseCodePath()
- + " pkg.applicationInfo.getSplitCodePaths="
+ + " pkg.getBaseCodePath=" + pkg.getBaseCodePath()
+ + " pkg.getSplitCodePaths="
+ (splitCodePaths == null ? "null" : Arrays.toString(splitCodePaths)));
}
@@ -211,7 +213,8 @@ public class PackageDexOptimizer {
}
}
- String profileName = ArtManager.getProfileName(i == 0 ? null : pkg.splitNames[i - 1]);
+ String profileName = ArtManager.getProfileName(
+ i == 0 ? null : pkg.getSplitNames()[i - 1]);
String dexMetadataPath = null;
if (options.isDexoptInstallWithDexMetadata()) {
@@ -222,7 +225,7 @@ public class PackageDexOptimizer {
final boolean isUsedByOtherApps = options.isDexoptAsSharedLibrary()
|| packageUseInfo.isUsedByOtherApps(path);
- final String compilerFilter = getRealCompilerFilter(pkg.applicationInfo,
+ final String compilerFilter = getRealCompilerFilter(pkg,
options.getCompilerFilter(), isUsedByOtherApps);
final boolean profileUpdated = options.isCheckForProfileUpdates() &&
isProfileUpdated(pkg, sharedGid, profileName, compilerFilter);
@@ -257,7 +260,7 @@ public class PackageDexOptimizer {
* DEX_OPT_SKIPPED if the path does not need to be deopt-ed.
*/
@GuardedBy("mInstallLock")
- private int dexOptPath(PackageParser.Package pkg, String path, String isa,
+ private int dexOptPath(AndroidPackage pkg, String path, String isa,
String compilerFilter, boolean profileUpdated, String classLoaderContext,
int dexoptFlags, int uid, CompilerStats.PackageStats packageStats, boolean downgrade,
String profileName, String dexMetadataPath, int compilationReason) {
@@ -270,7 +273,7 @@ public class PackageDexOptimizer {
String oatDir = getPackageOatDirIfSupported(pkg);
Log.i(TAG, "Running dexopt (dexoptNeeded=" + dexoptNeeded + ") on: " + path
- + " pkg=" + pkg.applicationInfo.packageName + " isa=" + isa
+ + " pkg=" + pkg.getAppInfoPackageName() + " isa=" + isa
+ " dexoptFlags=" + printDexoptFlags(dexoptFlags)
+ " targetFilter=" + compilerFilter + " oatDir=" + oatDir
+ " classLoaderContext=" + classLoaderContext);
@@ -281,9 +284,9 @@ public class PackageDexOptimizer {
// TODO: Consider adding 2 different APIs for primary and secondary dexopt.
// installd only uses downgrade flag for secondary dex files and ignores it for
// primary dex files.
- mInstaller.dexopt(path, uid, pkg.packageName, isa, dexoptNeeded, oatDir, dexoptFlags,
- compilerFilter, pkg.volumeUuid, classLoaderContext, pkg.applicationInfo.seInfo,
- false /* downgrade*/, pkg.applicationInfo.targetSdkVersion,
+ mInstaller.dexopt(path, uid, pkg.getPackageName(), isa, dexoptNeeded, oatDir,
+ dexoptFlags, compilerFilter, pkg.getVolumeUuid(), classLoaderContext,
+ pkg.getSeInfo(), false /* downgrade*/, pkg.getTargetSdkVersion(),
profileName, dexMetadataPath,
getAugmentedReasonName(compilationReason, dexMetadataPath != null));
@@ -446,9 +449,10 @@ public class PackageDexOptimizer {
/**
* Dumps the dexopt state of the given package {@code pkg} to the given {@code PrintWriter}.
*/
- void dumpDexoptState(IndentingPrintWriter pw, PackageParser.Package pkg,
+ void dumpDexoptState(IndentingPrintWriter pw, AndroidPackage pkg,
PackageDexUsage.PackageUseInfo useInfo) {
- final String[] instructionSets = getAppDexInstructionSets(pkg.applicationInfo);
+ final String[] instructionSets = getAppDexInstructionSets(pkg.getPrimaryCpuAbi(),
+ pkg.getSecondaryCpuAbi());
final String[] dexCodeInstructionSets = getDexCodeInstructionSets(instructionSets);
final List<String> paths = pkg.getAllCodePathsExcludingResourceOnly();
@@ -504,7 +508,7 @@ public class PackageDexOptimizer {
// When an app or priv app is configured to run out of box, only verify it.
if (info.isEmbeddedDexUsed()
|| (info.isPrivilegedApp()
- && DexManager.isPackageSelectedToRunOob(info.packageName))) {
+ && DexManager.isPackageSelectedToRunOob(info.packageName))) {
return "verify";
}
@@ -535,12 +539,43 @@ public class PackageDexOptimizer {
}
/**
- * Computes the dex flags that needs to be pass to installd for the given package and compiler
- * filter.
+ * Returns the compiler filter that should be used to optimize the package code.
+ * The target filter will be updated if the package code is used by other apps
+ * or if it has the safe mode flag set.
*/
- private int getDexFlags(PackageParser.Package pkg, String compilerFilter,
- DexoptOptions options) {
- return getDexFlags(pkg.applicationInfo, compilerFilter, options);
+ private String getRealCompilerFilter(AndroidPackage pkg, String targetCompilerFilter,
+ boolean isUsedByOtherApps) {
+ // When an app or priv app is configured to run out of box, only verify it.
+ if (pkg.isEmbeddedDexUsed()
+ || (pkg.isPrivileged()
+ && DexManager.isPackageSelectedToRunOob(pkg.getPackageName()))) {
+ return "verify";
+ }
+
+ // We force vmSafeMode on debuggable apps as well:
+ // - the runtime ignores their compiled code
+ // - they generally have lots of methods that could make the compiler used run
+ // out of memory (b/130828957)
+ // Note that forcing the compiler filter here applies to all compilations (even if they
+ // are done via adb shell commands). That's ok because right now the runtime will ignore
+ // the compiled code anyway. The alternative would have been to update either
+ // PackageDexOptimizer#canOptimizePackage or PackageManagerService#getOptimizablePackages
+ // but that would have the downside of possibly producing a big odex files which would
+ // be ignored anyway.
+ boolean vmSafeModeOrDebuggable = ((pkg.getFlags() & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0)
+ || ((pkg.getFlags() & ApplicationInfo.FLAG_DEBUGGABLE) != 0);
+
+ if (vmSafeModeOrDebuggable) {
+ return getSafeModeCompilerFilter(targetCompilerFilter);
+ }
+
+ if (isProfileGuidedCompilerFilter(targetCompilerFilter) && isUsedByOtherApps) {
+ // If the dex files is used by other apps, apply the shared filter.
+ return PackageManagerServiceCompilerMapping.getCompilerFilterForReason(
+ PackageManagerService.REASON_SHARED);
+ }
+
+ return targetCompilerFilter;
}
private boolean isAppImageEnabled() {
@@ -548,7 +583,24 @@ public class PackageDexOptimizer {
}
private int getDexFlags(ApplicationInfo info, String compilerFilter, DexoptOptions options) {
- int flags = info.flags;
+ return getDexFlags(info.flags, info.getHiddenApiEnforcementPolicy(),
+ info.splitDependencies, info.requestsIsolatedSplitLoading(), compilerFilter,
+ options);
+ }
+ private int getDexFlags(AndroidPackage pkg, String compilerFilter,
+ DexoptOptions options) {
+ return getDexFlags(pkg.getFlags(), pkg.getHiddenApiEnforcementPolicy(),
+ pkg.getSplitDependencies(), pkg.requestsIsolatedSplitLoading(), compilerFilter,
+ options);
+ }
+
+ /**
+ * Computes the dex flags that needs to be pass to installd for the given package and compiler
+ * filter.
+ */
+ private int getDexFlags(int flags, int hiddenApiEnforcementPolicy,
+ SparseArray<int[]> splitDependencies, boolean requestsIsolatedSplitLoading,
+ String compilerFilter, DexoptOptions options) {
boolean debuggable = (flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
// Profile guide compiled oat files should not be public unles they are based
// on profiles from dex metadata archives.
@@ -560,7 +612,9 @@ public class PackageDexOptimizer {
// Some apps are executed with restrictions on hidden API usage. If this app is one
// of them, pass a flag to dexopt to enable the same restrictions during compilation.
// TODO we should pass the actual flag value to dexopt, rather than assuming blacklist
- int hiddenApiFlag = info.getHiddenApiEnforcementPolicy() == HIDDEN_API_ENFORCEMENT_DISABLED
+ // TODO(b/135203078): This flag is no longer set as part of AndroidPackage
+ // and may not be preserved
+ int hiddenApiFlag = hiddenApiEnforcementPolicy == HIDDEN_API_ENFORCEMENT_DISABLED
? 0
: DEXOPT_ENABLE_HIDDEN_API_CHECKS;
// Avoid generating CompactDex for modes that are latency critical.
@@ -578,8 +632,8 @@ public class PackageDexOptimizer {
// declare inter-split dependencies, then all the splits will be loaded in the base
// apk class loader (in the order of their definition, otherwise disable app images
// because they are unsupported for multiple class loaders. b/7269679
- boolean generateAppImage = isProfileGuidedFilter && (info.splitDependencies == null ||
- !info.requestsIsolatedSplitLoading()) && isAppImageEnabled();
+ boolean generateAppImage = isProfileGuidedFilter && (splitDependencies == null ||
+ !requestsIsolatedSplitLoading) && isAppImageEnabled();
int dexFlags =
(isPublic ? DEXOPT_PUBLIC : 0)
| (debuggable ? DEXOPT_DEBUGGABLE : 0)
@@ -617,7 +671,7 @@ public class PackageDexOptimizer {
* current profile and the reference profile will be merged and subsequent calls
* may return a different result.
*/
- private boolean isProfileUpdated(PackageParser.Package pkg, int uid, String profileName,
+ private boolean isProfileUpdated(AndroidPackage pkg, int uid, String profileName,
String compilerFilter) {
// Check if we are allowed to merge and if the compiler filter is profile guided.
if (!isProfileGuidedCompilerFilter(compilerFilter)) {
@@ -625,7 +679,7 @@ public class PackageDexOptimizer {
}
// Merge profiles. It returns whether or not there was an updated in the profile info.
try {
- return mInstaller.mergeProfiles(uid, pkg.packageName, profileName);
+ return mInstaller.mergeProfiles(uid, pkg.getPackageName(), profileName);
} catch (InstallerException e) {
Slog.w(TAG, "Failed to merge profiles", e);
}
@@ -645,11 +699,11 @@ public class PackageDexOptimizer {
* not needed or unsupported for the package.
*/
@Nullable
- private String getPackageOatDirIfSupported(PackageParser.Package pkg) {
+ private String getPackageOatDirIfSupported(AndroidPackage pkg) {
if (!pkg.canHaveOatDir()) {
return null;
}
- File codePath = new File(pkg.codePath);
+ File codePath = new File(pkg.getCodePath());
if (!codePath.isDirectory()) {
return null;
}
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java
index b72029046067..a34ca914f548 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerSession.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java
@@ -66,6 +66,7 @@ import android.content.pm.PackageParser.ApkLite;
import android.content.pm.PackageParser.PackageLite;
import android.content.pm.PackageParser.PackageParserException;
import android.content.pm.dex.DexMetadataHelper;
+import android.content.pm.parsing.ApkLiteParseUtils;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.Binder;
@@ -1573,7 +1574,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
for (File addedFile : addedFiles) {
final ApkLite apk;
try {
- apk = PackageParser.parseApkLite(
+ apk = ApkLiteParseUtils.parseApkLite(
addedFile, PackageParser.PARSE_COLLECT_CERTIFICATES);
} catch (PackageParserException e) {
throw PackageManagerException.from(e);
@@ -1672,7 +1673,7 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
ApplicationInfo appInfo = pkgInfo.applicationInfo;
try {
existing = PackageParser.parsePackageLite(new File(appInfo.getCodePath()), 0);
- existingBase = PackageParser.parseApkLite(new File(appInfo.getBaseCodePath()),
+ existingBase = ApkLiteParseUtils.parseApkLite(new File(appInfo.getBaseCodePath()),
PackageParser.PARSE_COLLECT_CERTIFICATES);
} catch (PackageParserException e) {
throw PackageManagerException.from(e);
diff --git a/services/core/java/com/android/server/pm/PackageKeySetData.java b/services/core/java/com/android/server/pm/PackageKeySetData.java
index 031b5ce3d5b9..10685b06716f 100644
--- a/services/core/java/com/android/server/pm/PackageKeySetData.java
+++ b/services/core/java/com/android/server/pm/PackageKeySetData.java
@@ -20,6 +20,8 @@ import android.util.ArrayMap;
import com.android.internal.util.ArrayUtils;
+import java.util.Map;
+
public class PackageKeySetData {
static final long KEYSET_UNASSIGNED = -1;
@@ -90,16 +92,13 @@ public class PackageKeySetData {
/*
* Replace defined keysets with new ones.
*/
- protected void setAliases(ArrayMap<String, Long> newAliases) {
+ protected void setAliases(Map<String, Long> newAliases) {
/* remove old aliases */
removeAllDefinedKeySets();
/* add new ones */
- final int newAliasSize = newAliases.size();
- for (int i = 0; i < newAliasSize; i++) {
- mKeySetAliases.put(newAliases.keyAt(i), newAliases.valueAt(i));;
- }
+ mKeySetAliases.putAll(newAliases);
}
protected void addDefinedKeySet(long ks, String alias) {
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index d07e2d232ea6..f706dc3d3219 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -34,7 +34,6 @@ import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED
import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED;
import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER;
import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
-import static android.content.pm.PackageManager.DELETE_KEEP_DATA;
import static android.content.pm.PackageManager.FLAG_PERMISSION_GRANTED_BY_DEFAULT;
import static android.content.pm.PackageManager.FLAG_PERMISSION_POLICY_FIXED;
import static android.content.pm.PackageManager.FLAG_PERMISSION_REVOKED_COMPAT;
@@ -158,7 +157,6 @@ import android.content.pm.InstrumentationInfo;
import android.content.pm.IntentFilterVerificationInfo;
import android.content.pm.KeySet;
import android.content.pm.ModuleInfo;
-import android.content.pm.PackageBackwardCompatibility;
import android.content.pm.PackageInfo;
import android.content.pm.PackageInfoLite;
import android.content.pm.PackageInstaller;
@@ -169,7 +167,6 @@ import android.content.pm.PackageManager.ModuleInfoFlags;
import android.content.pm.PackageManagerInternal;
import android.content.pm.PackageManagerInternal.PackageListObserver;
import android.content.pm.PackageParser;
-import android.content.pm.PackageParser.ActivityIntentInfo;
import android.content.pm.PackageParser.PackageLite;
import android.content.pm.PackageParser.PackageParserException;
import android.content.pm.PackageParser.ParseFlags;
@@ -194,6 +191,19 @@ import android.content.pm.VersionedPackage;
import android.content.pm.dex.ArtManager;
import android.content.pm.dex.DexMetadataHelper;
import android.content.pm.dex.IArtManager;
+import android.content.pm.parsing.AndroidPackage;
+import android.content.pm.parsing.ApkParseUtils;
+import android.content.pm.parsing.ComponentParseUtils.ParsedActivity;
+import android.content.pm.parsing.ComponentParseUtils.ParsedActivityIntentInfo;
+import android.content.pm.parsing.ComponentParseUtils.ParsedComponent;
+import android.content.pm.parsing.ComponentParseUtils.ParsedInstrumentation;
+import android.content.pm.parsing.ComponentParseUtils.ParsedPermission;
+import android.content.pm.parsing.ComponentParseUtils.ParsedProvider;
+import android.content.pm.parsing.ComponentParseUtils.ParsedService;
+import android.content.pm.parsing.PackageImpl;
+import android.content.pm.parsing.PackageInfoUtils;
+import android.content.pm.parsing.ParsedPackage;
+import android.content.pm.parsing.library.PackageBackwardCompatibility;
import android.content.res.Resources;
import android.content.rollback.IRollbackManager;
import android.database.ContentObserver;
@@ -460,20 +470,19 @@ public class PackageManagerService extends IPackageManager.Stub
static final int SCAN_REQUIRE_KNOWN = 1 << 7;
static final int SCAN_MOVE = 1 << 8;
static final int SCAN_INITIAL = 1 << 9;
- static final int SCAN_CHECK_ONLY = 1 << 10;
- static final int SCAN_DONT_KILL_APP = 1 << 11;
- static final int SCAN_IGNORE_FROZEN = 1 << 12;
- static final int SCAN_FIRST_BOOT_OR_UPGRADE = 1 << 13;
- static final int SCAN_AS_INSTANT_APP = 1 << 14;
- static final int SCAN_AS_FULL_APP = 1 << 15;
- static final int SCAN_AS_VIRTUAL_PRELOAD = 1 << 16;
- static final int SCAN_AS_SYSTEM = 1 << 17;
- static final int SCAN_AS_PRIVILEGED = 1 << 18;
- static final int SCAN_AS_OEM = 1 << 19;
- static final int SCAN_AS_VENDOR = 1 << 20;
- static final int SCAN_AS_PRODUCT = 1 << 21;
- static final int SCAN_AS_SYSTEM_EXT = 1 << 22;
- static final int SCAN_AS_ODM = 1 << 23;
+ static final int SCAN_DONT_KILL_APP = 1 << 10;
+ static final int SCAN_IGNORE_FROZEN = 1 << 11;
+ static final int SCAN_FIRST_BOOT_OR_UPGRADE = 1 << 12;
+ static final int SCAN_AS_INSTANT_APP = 1 << 13;
+ static final int SCAN_AS_FULL_APP = 1 << 14;
+ static final int SCAN_AS_VIRTUAL_PRELOAD = 1 << 15;
+ static final int SCAN_AS_SYSTEM = 1 << 16;
+ static final int SCAN_AS_PRIVILEGED = 1 << 17;
+ static final int SCAN_AS_OEM = 1 << 18;
+ static final int SCAN_AS_VENDOR = 1 << 19;
+ static final int SCAN_AS_PRODUCT = 1 << 20;
+ static final int SCAN_AS_SYSTEM_EXT = 1 << 21;
+ static final int SCAN_AS_ODM = 1 << 22;
@IntDef(flag = true, prefix = { "SCAN_" }, value = {
SCAN_NO_DEX,
@@ -484,7 +493,6 @@ public class PackageManagerService extends IPackageManager.Stub
SCAN_REQUIRE_KNOWN,
SCAN_MOVE,
SCAN_INITIAL,
- SCAN_CHECK_ONLY,
SCAN_DONT_KILL_APP,
SCAN_IGNORE_FROZEN,
SCAN_FIRST_BOOT_OR_UPGRADE,
@@ -603,11 +611,19 @@ public class PackageManagerService extends IPackageManager.Stub
public static final int REASON_LAST = REASON_SHARED;
/**
- * Whether the package parser cache is enabled.
+ * The initial enabled state of the cache before other checks are done.
*/
private static final boolean DEFAULT_PACKAGE_PARSER_CACHE_ENABLED = true;
/**
+ * Whether to skip all other checks and force the cache to be enabled.
+ *
+ * Setting this to true will cause the cache to be named "debug" to avoid eviction from
+ * build fingerprint changes.
+ */
+ private static final boolean FORCE_PACKAGE_PARSED_CACHE_ENABLED = false;
+
+ /**
* Permissions required in order to receive instant application lifecycle broadcasts.
*/
private static final String[] INSTANT_APP_BROADCAST_PERMISSION =
@@ -664,7 +680,7 @@ public class PackageManagerService extends IPackageManager.Stub
// Keys are String (package name), values are Package.
@GuardedBy("mLock")
- final ArrayMap<String, PackageParser.Package> mPackages = new ArrayMap<>();
+ final ArrayMap<String, AndroidPackage> mPackages = new ArrayMap<>();
// Keys are isolated uids and values are the uid of the application
// that created the isolated proccess.
@@ -977,17 +993,17 @@ public class PackageManagerService extends IPackageManager.Stub
return PackageManagerService.this.hasSystemFeature(feature, 0);
}
- final List<PackageParser.Package> getStaticOverlayPackages(
- Collection<PackageParser.Package> allPackages, String targetPackageName) {
+ final List<AndroidPackage> getStaticOverlayPackages(
+ Collection<AndroidPackage> allPackages, String targetPackageName) {
if ("android".equals(targetPackageName)) {
// Static RROs targeting to "android", ie framework-res.apk, are already applied by
// native AssetManager.
return null;
}
- List<PackageParser.Package> overlayPackages = null;
- for (PackageParser.Package p : allPackages) {
- if (targetPackageName.equals(p.mOverlayTarget) && p.mOverlayIsStatic) {
+ List<AndroidPackage> overlayPackages = null;
+ for (AndroidPackage p : allPackages) {
+ if (targetPackageName.equals(p.getOverlayTarget()) && p.isOverlayIsStatic()) {
if (overlayPackages == null) {
overlayPackages = new ArrayList<>();
}
@@ -995,25 +1011,25 @@ public class PackageManagerService extends IPackageManager.Stub
}
}
if (overlayPackages != null) {
- Comparator<PackageParser.Package> cmp =
- Comparator.comparingInt(p -> p.mOverlayPriority);
+ Comparator<AndroidPackage> cmp =
+ Comparator.comparingInt(p -> p.getOverlayPriority());
overlayPackages.sort(cmp);
}
return overlayPackages;
}
- final String[] getStaticOverlayPaths(List<PackageParser.Package> overlayPackages,
+ final String[] getStaticOverlayPaths(List<AndroidPackage> overlayPackages,
String targetPath) {
if (overlayPackages == null || overlayPackages.isEmpty()) {
return null;
}
List<String> overlayPathList = null;
- for (PackageParser.Package overlayPackage : overlayPackages) {
+ for (AndroidPackage overlayPackage : overlayPackages) {
if (targetPath == null) {
if (overlayPathList == null) {
overlayPathList = new ArrayList<>();
}
- overlayPathList.add(overlayPackage.baseCodePath);
+ overlayPathList.add(overlayPackage.getBaseCodePath());
continue;
}
@@ -1023,23 +1039,23 @@ public class PackageManagerService extends IPackageManager.Stub
//
// OverlayManagerService will update each of them with a correct gid from its
// target package app id.
- mInstaller.idmap(targetPath, overlayPackage.baseCodePath,
+ mInstaller.idmap(targetPath, overlayPackage.getBaseCodePath(),
UserHandle.getSharedAppGid(
UserHandle.getUserGid(UserHandle.USER_SYSTEM)));
if (overlayPathList == null) {
overlayPathList = new ArrayList<>();
}
- overlayPathList.add(overlayPackage.baseCodePath);
+ overlayPathList.add(overlayPackage.getBaseCodePath());
} catch (InstallerException e) {
Slog.e(TAG, "Failed to generate idmap for " + targetPath + " and " +
- overlayPackage.baseCodePath);
+ overlayPackage.getBaseCodePath());
}
}
return overlayPathList == null ? null : overlayPathList.toArray(new String[0]);
}
String[] getStaticOverlayPaths(String targetPackageName, String targetPath) {
- List<PackageParser.Package> overlayPackages;
+ List<AndroidPackage> overlayPackages;
synchronized (mInstallLock) {
synchronized (mLock) {
overlayPackages = getStaticOverlayPackages(
@@ -1062,12 +1078,12 @@ public class PackageManagerService extends IPackageManager.Stub
}
class ParallelPackageParserCallback extends PackageParserCallback {
- List<PackageParser.Package> mOverlayPackages = null;
+ List<AndroidPackage> mOverlayPackages = null;
void findStaticOverlayPackages() {
synchronized (mLock) {
- for (PackageParser.Package p : mPackages.values()) {
- if (p.mOverlayIsStatic) {
+ for (AndroidPackage p : mPackages.values()) {
+ if (p.isOverlayIsStatic()) {
if (mOverlayPackages == null) {
mOverlayPackages = new ArrayList<>();
}
@@ -1101,7 +1117,7 @@ public class PackageManagerService extends IPackageManager.Stub
new ArrayMap<>();
// Mapping from instrumentation class names to info about them.
- final ArrayMap<ComponentName, PackageParser.Instrumentation> mInstrumentation =
+ final ArrayMap<ComponentName, ParsedInstrumentation> mInstrumentation =
new ArrayMap<>();
// Packages whose data we have transfered into another package, thus
@@ -1150,13 +1166,13 @@ public class PackageManagerService extends IPackageManager.Stub
final ActivityInfo mResolveActivity = new ActivityInfo();
final ResolveInfo mResolveInfo = new ResolveInfo();
ComponentName mResolveComponentName;
- PackageParser.Package mPlatformPackage;
+ AndroidPackage mPlatformPackage;
ComponentName mCustomResolverComponentName;
boolean mResolverReplaced = false;
private final @Nullable ComponentName mIntentFilterVerifierComponent;
- private final @Nullable IntentFilterVerifier<ActivityIntentInfo> mIntentFilterVerifier;
+ private final @Nullable IntentFilterVerifier<ParsedActivityIntentInfo> mIntentFilterVerifier;
private int mIntentFilterVerificationToken = 0;
@@ -1189,14 +1205,19 @@ public class PackageManagerService extends IPackageManager.Stub
private Future<?> mPrepareAppDataFuture;
private static class IFVerificationParams {
- PackageParser.Package pkg;
+ String packageName;
+ boolean hasDomainUrls;
+ List<ParsedActivity> activities;
boolean replacing;
int userId;
int verifierUid;
- public IFVerificationParams(PackageParser.Package _pkg, boolean _replacing,
+ public IFVerificationParams(String packageName, boolean hasDomainUrls,
+ List<ParsedActivity> activities, boolean _replacing,
int _userId, int _verifierUid) {
- pkg = _pkg;
+ this.packageName = packageName;
+ this.hasDomainUrls = hasDomainUrls;
+ this.activities = activities;
replacing = _replacing;
userId = _userId;
verifierUid = _verifierUid;
@@ -1210,7 +1231,7 @@ public class PackageManagerService extends IPackageManager.Stub
void receiveVerificationResponse(int verificationId);
}
- private class IntentVerifierProxy implements IntentFilterVerifier<ActivityIntentInfo> {
+ private class IntentVerifierProxy implements IntentFilterVerifier<ParsedActivityIntentInfo> {
private Context mContext;
private ComponentName mIntentFilterVerifierComponent;
private ArrayList<Integer> mCurrentIntentFilterVerifications = new ArrayList<>();
@@ -1235,11 +1256,11 @@ public class PackageManagerService extends IPackageManager.Stub
String packageName = ivs.getPackageName();
- ArrayList<PackageParser.ActivityIntentInfo> filters = ivs.getFilters();
+ ArrayList<ParsedActivityIntentInfo> filters = ivs.getFilters();
final int filterCount = filters.size();
ArraySet<String> domainsSet = new ArraySet<>();
for (int m=0; m<filterCount; m++) {
- PackageParser.ActivityIntentInfo filter = filters.get(m);
+ ParsedActivityIntentInfo filter = filters.get(m);
domainsSet.addAll(filter.getHostsList());
}
synchronized (mLock) {
@@ -1291,14 +1312,14 @@ public class PackageManagerService extends IPackageManager.Stub
final boolean verified = ivs.isVerified();
- ArrayList<PackageParser.ActivityIntentInfo> filters = ivs.getFilters();
+ ArrayList<ParsedActivityIntentInfo> filters = ivs.getFilters();
final int count = filters.size();
if (DEBUG_DOMAIN_VERIFICATION) {
Slog.i(TAG, "Received verification response " + verificationId
+ " for " + count + " filters, verified=" + verified);
}
for (int n=0; n<count; n++) {
- PackageParser.ActivityIntentInfo filter = filters.get(n);
+ ParsedActivityIntentInfo filter = filters.get(n);
filter.setVerified(verified);
if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "IntentFilter " + filter.toString()
@@ -1411,7 +1432,7 @@ public class PackageManagerService extends IPackageManager.Stub
@Override
public boolean addOneIntentFilterVerification(int verifierUid, int userId, int verificationId,
- ActivityIntentInfo filter, String packageName) {
+ ParsedActivityIntentInfo filter, String packageName) {
if (!hasValidDomains(filter)) {
return false;
}
@@ -1440,7 +1461,7 @@ public class PackageManagerService extends IPackageManager.Stub
}
}
- private static boolean hasValidDomains(ActivityIntentInfo filter) {
+ private static boolean hasValidDomains(ParsedActivityIntentInfo filter) {
return filter.hasCategory(Intent.CATEGORY_BROWSABLE)
&& (filter.hasDataScheme(IntentFilter.SCHEME_HTTP) ||
filter.hasDataScheme(IntentFilter.SCHEME_HTTPS));
@@ -1705,7 +1726,7 @@ public class PackageManagerService extends IPackageManager.Stub
final List<String> whitelistedRestrictedPermissions = ((args.installFlags
& PackageManager.INSTALL_ALL_WHITELIST_RESTRICTED_PERMISSIONS) != 0
&& parentRes.pkg != null)
- ? parentRes.pkg.requestedPermissions
+ ? parentRes.pkg.getRequestedPermissions()
: args.whitelistedRestrictedPermissions;
// Handle the parent package
@@ -1851,8 +1872,8 @@ public class PackageManagerService extends IPackageManager.Stub
}
case START_INTENT_FILTER_VERIFICATIONS: {
IFVerificationParams params = (IFVerificationParams) msg.obj;
- verifyIntentFiltersIfNeeded(params.userId, params.verifierUid,
- params.replacing, params.pkg);
+ verifyIntentFiltersIfNeeded(params.userId, params.verifierUid, params.replacing,
+ params.packageName, params.hasDomainUrls, params.activities);
break;
}
case INTENT_FILTER_VERIFIED: {
@@ -2002,20 +2023,11 @@ public class PackageManagerService extends IPackageManager.Stub
? res.removedInfo.installerPackageName
: null;
- // If this is the first time we have child packages for a disabled privileged
- // app that had no children, we grant requested runtime permissions to the new
- // children if the parent on the system image had them already granted.
- if (res.pkg.parentPackage != null) {
- final int callingUid = Binder.getCallingUid();
- mPermissionManager.grantRuntimePermissionsGrantedToDisabledPackage(
- res.pkg, callingUid);
- }
-
synchronized (mLock) {
mInstantAppRegistry.onPackageInstalledLPw(res.pkg, res.newUsers);
}
- final String packageName = res.pkg.applicationInfo.packageName;
+ final String packageName = res.pkg.getAppInfoPackageName();
// Determine the set of users who are adding this package for
// the first time vs. those who are seeing an update.
@@ -2024,7 +2036,7 @@ public class PackageManagerService extends IPackageManager.Stub
int[] updateUserIds = EMPTY_INT_ARRAY;
int[] instantUserIds = EMPTY_INT_ARRAY;
final boolean allNewUsers = res.origUsers == null || res.origUsers.length == 0;
- final PackageSetting ps = (PackageSetting) res.pkg.mExtras;
+ final PackageSetting ps = getPackageSetting(res.pkg.getPackageName());
for (int newUser : res.newUsers) {
final boolean isInstantApp = ps.getInstantApp(newUser);
if (allNewUsers) {
@@ -2058,13 +2070,14 @@ public class PackageManagerService extends IPackageManager.Stub
}
// Send installed broadcasts if the package is not a static shared lib.
- if (res.pkg.staticSharedLibName == null) {
- mProcessLoggingHandler.invalidateProcessLoggingBaseApkHash(res.pkg.baseCodePath);
+ if (res.pkg.getStaticSharedLibName() == null) {
+ mProcessLoggingHandler.invalidateProcessLoggingBaseApkHash(
+ res.pkg.getBaseCodePath());
// Send added for users that see the package for the first time
// sendPackageAddedForNewUsers also deals with system apps
int appId = UserHandle.getAppId(res.uid);
- boolean isSystem = res.pkg.applicationInfo.isSystemApp();
+ boolean isSystem = res.pkg.isSystemApp();
sendPackageAddedForNewUsers(packageName, isSystem || virtualPreload,
virtualPreload /*startReceiver*/, appId, firstUserIds, firstInstantUserIds);
@@ -2142,30 +2155,30 @@ public class PackageManagerService extends IPackageManager.Stub
final StorageManager storage = mInjector.getStorageManager();
VolumeInfo volume =
storage.findVolumeByUuid(
- res.pkg.applicationInfo.storageUuid.toString());
+ res.pkg.getStorageUuid().toString());
int packageExternalStorageType =
getPackageExternalStorageType(volume, isExternal(res.pkg));
// If the package was installed externally, log it.
if (packageExternalStorageType != StorageEnums.UNKNOWN) {
StatsLog.write(StatsLog.APP_INSTALL_ON_EXTERNAL_STORAGE_REPORTED,
- packageExternalStorageType, res.pkg.packageName);
+ packageExternalStorageType, res.pkg.getPackageName());
}
}
if (DEBUG_INSTALL) {
Slog.i(TAG, "upgrading pkg " + res.pkg + " is external");
}
- final int[] uidArray = new int[]{res.pkg.applicationInfo.uid};
+ final int[] uidArray = new int[]{res.pkg.getUid()};
ArrayList<String> pkgList = new ArrayList<>(1);
pkgList.add(packageName);
sendResourcesChangedBroadcast(true, true, pkgList, uidArray, null);
}
} else if (!ArrayUtils.isEmpty(res.libraryConsumers)) { // if static shared lib
for (int i = 0; i < res.libraryConsumers.size(); i++) {
- PackageParser.Package pkg = res.libraryConsumers.get(i);
+ AndroidPackage pkg = res.libraryConsumers.get(i);
// send broadcast that all consumers of the static shared library have changed
- sendPackageChangedBroadcast(pkg.packageName, false /*killFlag*/,
- new ArrayList<>(Collections.singletonList(pkg.packageName)),
- pkg.applicationInfo.uid);
+ sendPackageChangedBroadcast(pkg.getPackageName(), false /*killFlag*/,
+ new ArrayList<>(Collections.singletonList(pkg.getPackageName())),
+ pkg.getUid());
}
}
@@ -2295,7 +2308,7 @@ public class PackageManagerService extends IPackageManager.Stub
private void scheduleDeferredNoKillInstallObserver(PackageInstalledInfo info,
IPackageInstallObserver2 observer) {
- String packageName = info.pkg.packageName;
+ String packageName = info.pkg.getPackageName();
mNoKillInstallObservers.put(packageName, Pair.create(info, observer));
Message message = mHandler.obtainMessage(DEFERRED_NO_KILL_INSTALL_OBSERVER, packageName);
mHandler.sendMessageDelayed(message, DEFERRED_NO_KILL_INSTALL_OBSERVER_DELAY_MS);
@@ -2833,11 +2846,11 @@ public class PackageManagerService extends IPackageManager.Stub
final List<String> stubSystemApps = new ArrayList<>();
if (!mOnlyCore) {
// do this first before mucking with mPackages for the "expecting better" case
- final Iterator<PackageParser.Package> pkgIterator = mPackages.values().iterator();
+ final Iterator<AndroidPackage> pkgIterator = mPackages.values().iterator();
while (pkgIterator.hasNext()) {
- final PackageParser.Package pkg = pkgIterator.next();
- if (pkg.isStub) {
- stubSystemApps.add(pkg.packageName);
+ final AndroidPackage pkg = pkgIterator.next();
+ if (pkg.isStub()) {
+ stubSystemApps.add(pkg.getPackageName());
}
}
@@ -2856,7 +2869,7 @@ public class PackageManagerService extends IPackageManager.Stub
/*
* If the package is scanned, it's not erased.
*/
- final PackageParser.Package scannedPkg = mPackages.get(ps.name);
+ final AndroidPackage scannedPkg = mPackages.get(ps.name);
if (scannedPkg != null) {
/*
* If the system app is both scanned and in the
@@ -2933,7 +2946,7 @@ public class PackageManagerService extends IPackageManager.Stub
// app completely. Otherwise, revoke their system privileges.
for (int i = possiblyDeletedUpdatedSystemApps.size() - 1; i >= 0; --i) {
final String packageName = possiblyDeletedUpdatedSystemApps.get(i);
- final PackageParser.Package pkg = mPackages.get(packageName);
+ final AndroidPackage pkg = mPackages.get(packageName);
final String msg;
// remove from the disabled system list; do this first so any future
@@ -2959,7 +2972,7 @@ public class PackageManagerService extends IPackageManager.Stub
// special privileges
removePackageLI(pkg, true);
try {
- final File codePath = new File(pkg.applicationInfo.getCodePath());
+ final File codePath = new File(pkg.getAppInfoCodePath());
scanPackageTracedLI(codePath, 0, scanFlags, 0, null);
} catch (PackageManagerException e) {
Slog.e(TAG, "Failed to parse updated, ex-system package: "
@@ -3154,7 +3167,7 @@ public class PackageManagerService extends IPackageManager.Stub
}
int count = 0;
for (String pkgName : deferPackages) {
- PackageParser.Package pkg = null;
+ AndroidPackage pkg = null;
synchronized (mLock) {
PackageSetting ps = mSettings.getPackageLPr(pkgName);
if (ps != null && ps.getInstalled(UserHandle.USER_SYSTEM)) {
@@ -3254,12 +3267,12 @@ public class PackageManagerService extends IPackageManager.Stub
// Initialize InstantAppRegistry's Instant App list for all users.
final int[] userIds = UserManagerService.getInstance().getUserIds();
- for (PackageParser.Package pkg : mPackages.values()) {
+ for (AndroidPackage pkg : mPackages.values()) {
if (pkg.isSystem()) {
continue;
}
for (int userId : userIds) {
- final PackageSetting ps = (PackageSetting) pkg.mExtras;
+ final PackageSetting ps = getPackageSetting(pkg.getPackageName());
if (ps == null || !ps.getInstantApp(userId) || !ps.getInstalled(userId)) {
continue;
}
@@ -3346,7 +3359,7 @@ public class PackageManagerService extends IPackageManager.Stub
continue;
}
// skip if the package isn't installed (?!); this should never happen
- final PackageParser.Package pkg = mPackages.get(packageName);
+ final AndroidPackage pkg = mPackages.get(packageName);
if (pkg == null) {
systemStubPackageNames.remove(i);
continue;
@@ -3390,43 +3403,46 @@ public class PackageManagerService extends IPackageManager.Stub
* APK will be installed and the package will be disabled. To recover from this situation,
* the user will need to go into system settings and re-enable the package.
*/
- private boolean enableCompressedPackage(PackageParser.Package stubPkg) {
+ private boolean enableCompressedPackage(AndroidPackage stubPkg) {
final int parseFlags = mDefParseFlags | PackageParser.PARSE_CHATTY
| PackageParser.PARSE_ENFORCE_CODE;
synchronized (mInstallLock) {
- final PackageParser.Package pkg;
+ final AndroidPackage pkg;
try (PackageFreezer freezer =
- freezePackage(stubPkg.packageName, "setEnabledSetting")) {
+ freezePackage(stubPkg.getPackageName(), "setEnabledSetting")) {
pkg = installStubPackageLI(stubPkg, parseFlags, 0 /*scanFlags*/);
synchronized (mLock) {
prepareAppDataAfterInstallLIF(pkg);
try {
- updateSharedLibrariesLocked(pkg, null, mPackages);
+ updateSharedLibrariesLocked(pkg, null,
+ Collections.unmodifiableMap(mPackages));
} catch (PackageManagerException e) {
Slog.e(TAG, "updateAllSharedLibrariesLPw failed: ", e);
}
- mPermissionManager.updatePermissions(pkg.packageName, pkg);
+ mPermissionManager.updatePermissions(pkg.getPackageName(), pkg);
mSettings.writeLPr();
}
} catch (PackageManagerException e) {
// Whoops! Something went very wrong; roll back to the stub and disable the package
try (PackageFreezer freezer =
- freezePackage(stubPkg.packageName, "setEnabledSetting")) {
+ freezePackage(stubPkg.getPackageName(), "setEnabledSetting")) {
synchronized (mLock) {
// NOTE: Ensure the system package is enabled; even for a compressed stub.
// If we don't, installing the system package fails during scan
enableSystemPackageLPw(stubPkg);
}
- installPackageFromSystemLIF(stubPkg.codePath,
+ installPackageFromSystemLIF(stubPkg.getCodePath(),
null /*allUserHandles*/, null /*origUserHandles*/,
null /*origPermissionsState*/, true /*writeSettings*/);
} catch (PackageManagerException pme) {
// Serious WTF; we have to be able to install the stub
- Slog.wtf(TAG, "Failed to restore system package:" + stubPkg.packageName, pme);
+ Slog.wtf(TAG, "Failed to restore system package:" + stubPkg.getPackageName(),
+ pme);
} finally {
// Disable the package; the stub by itself is not runnable
synchronized (mLock) {
- final PackageSetting stubPs = mSettings.mPackages.get(stubPkg.packageName);
+ final PackageSetting stubPs = mSettings.mPackages.get(
+ stubPkg.getPackageName());
if (stubPs != null) {
stubPs.setEnabled(COMPONENT_ENABLED_STATE_DISABLED,
UserHandle.USER_SYSTEM, "android");
@@ -3438,31 +3454,33 @@ public class PackageManagerService extends IPackageManager.Stub
}
clearAppDataLIF(pkg, UserHandle.USER_ALL, FLAG_STORAGE_DE | FLAG_STORAGE_CE
| FLAG_STORAGE_EXTERNAL | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
- mDexManager.notifyPackageUpdated(pkg.packageName,
- pkg.baseCodePath, pkg.splitCodePaths);
+ mDexManager.notifyPackageUpdated(pkg.getPackageName(),
+ pkg.getBaseCodePath(), pkg.getSplitCodePaths());
}
return true;
}
- private PackageParser.Package installStubPackageLI(PackageParser.Package stubPkg,
+ private AndroidPackage installStubPackageLI(AndroidPackage stubPkg,
@ParseFlags int parseFlags, @ScanFlags int scanFlags)
throws PackageManagerException {
if (DEBUG_COMPRESSION) {
- Slog.i(TAG, "Uncompressing system stub; pkg: " + stubPkg.packageName);
+ Slog.i(TAG, "Uncompressing system stub; pkg: " + stubPkg.getPackageName());
}
// uncompress the binary to its eventual destination on /data
- final File scanFile = decompressPackage(stubPkg.packageName, stubPkg.codePath);
+ final File scanFile = decompressPackage(stubPkg.getPackageName(), stubPkg.getCodePath());
if (scanFile == null) {
- throw new PackageManagerException("Unable to decompress stub at " + stubPkg.codePath);
+ throw new PackageManagerException(
+ "Unable to decompress stub at " + stubPkg.getCodePath());
}
synchronized (mLock) {
- mSettings.disableSystemPackageLPw(stubPkg.packageName, true /*replaced*/);
+ mSettings.disableSystemPackageLPw(stubPkg.getPackageName(), true /*replaced*/);
}
removePackageLI(stubPkg, true /*chatty*/);
try {
return scanPackageTracedLI(scanFile, parseFlags, scanFlags, 0, null);
} catch (PackageManagerException e) {
- Slog.w(TAG, "Failed to install compressed system package:" + stubPkg.packageName, e);
+ Slog.w(TAG, "Failed to install compressed system package:" + stubPkg.getPackageName(),
+ e);
// Remove the failed install
removeCodePathLI(scanFile);
throw e;
@@ -3545,18 +3563,20 @@ public class PackageManagerService extends IPackageManager.Stub
}
private static @Nullable File preparePackageParserCache() {
- if (!DEFAULT_PACKAGE_PARSER_CACHE_ENABLED) {
- return null;
- }
+ if (!FORCE_PACKAGE_PARSED_CACHE_ENABLED) {
+ if (!DEFAULT_PACKAGE_PARSER_CACHE_ENABLED) {
+ return null;
+ }
- // Disable package parsing on eng builds to allow for faster incremental development.
- if (Build.IS_ENG) {
- return null;
- }
+ // Disable package parsing on eng builds to allow for faster incremental development.
+ if (Build.IS_ENG) {
+ return null;
+ }
- if (SystemProperties.getBoolean("pm.boot.disable_package_cache", false)) {
- Slog.i(TAG, "Disabling package parser cache due to system property.");
- return null;
+ if (SystemProperties.getBoolean("pm.boot.disable_package_cache", false)) {
+ Slog.i(TAG, "Disabling package parser cache due to system property.");
+ return null;
+ }
}
// The base directory for the package parser cache lives under /data/system/.
@@ -3568,10 +3588,12 @@ public class PackageManagerService extends IPackageManager.Stub
// There are several items that need to be combined together to safely
// identify cached items. In particular, changing the value of certain
// feature flags should cause us to invalidate any caches.
- final String cacheName = SystemProperties.digestOf(
- "ro.build.fingerprint",
- StorageManager.PROP_ISOLATED_STORAGE,
- StorageManager.PROP_ISOLATED_STORAGE_SNAPSHOT);
+ final String cacheName = FORCE_PACKAGE_PARSED_CACHE_ENABLED ? "debug"
+ : SystemProperties.digestOf(
+ "ro.build.fingerprint",
+ StorageManager.PROP_ISOLATED_STORAGE,
+ StorageManager.PROP_ISOLATED_STORAGE_SNAPSHOT
+ );
// Reconcile cache directories, keeping only what we'd actually use.
for (File cacheDir : FileUtils.listFilesOrEmpty(cacheBaseDir)) {
@@ -3895,7 +3917,7 @@ public class PackageManagerService extends IPackageManager.Stub
ArraySet<String> packages = systemConfig.getLinkedApps();
for (String packageName : packages) {
- PackageParser.Package pkg = mPackages.get(packageName);
+ AndroidPackage pkg = mPackages.get(packageName);
if (pkg != null) {
if (!pkg.isSystem()) {
Slog.w(TAG, "Non-system app '" + packageName + "' in sysconfig <app-link>");
@@ -3903,13 +3925,15 @@ public class PackageManagerService extends IPackageManager.Stub
}
ArraySet<String> domains = null;
- for (PackageParser.Activity a : pkg.activities) {
- for (ActivityIntentInfo filter : a.intents) {
- if (hasValidDomains(filter)) {
- if (domains == null) {
- domains = new ArraySet<>();
+ if (pkg.getActivities() != null) {
+ for (ParsedActivity a : pkg.getActivities()) {
+ for (ParsedActivityIntentInfo filter : a.intents) {
+ if (hasValidDomains(filter)) {
+ if (domains == null) {
+ domains = new ArraySet<>();
+ }
+ domains.addAll(filter.getHostsList());
}
- domains.addAll(filter.getHostsList());
}
}
}
@@ -4025,7 +4049,7 @@ public class PackageManagerService extends IPackageManager.Stub
}
final PackageUserState state = ps.readUserState(userId);
- PackageParser.Package p = ps.pkg;
+ AndroidPackage p = ps.pkg;
if (p != null) {
final PermissionsState permissionsState = ps.getPermissionsState();
@@ -4033,10 +4057,10 @@ public class PackageManagerService extends IPackageManager.Stub
final int[] gids = (flags & PackageManager.GET_GIDS) == 0
? EMPTY_INT_ARRAY : permissionsState.computeGids(userId);
// Compute granted permissions only if package has requested permissions
- final Set<String> permissions = ArrayUtils.isEmpty(p.requestedPermissions)
+ final Set<String> permissions = ArrayUtils.isEmpty(p.getRequestedPermissions())
? Collections.emptySet() : permissionsState.getPermissions(userId);
- PackageInfo packageInfo = PackageParser.generatePackageInfo(p, gids, flags,
+ PackageInfo packageInfo = PackageInfoUtils.generate(p, gids, flags,
ps.firstInstallTime, ps.lastUpdateTime, permissions, state, userId);
if (packageInfo == null) {
@@ -4099,7 +4123,7 @@ public class PackageManagerService extends IPackageManager.Stub
throw new SecurityException("Package " + packageName + " is currently frozen!");
}
- if (!userKeyUnlocked && !ps.pkg.applicationInfo.isEncryptionAware()) {
+ if (!userKeyUnlocked && !ps.pkg.isEncryptionAware()) {
throw new SecurityException("Package " + packageName + " is not encryption aware!");
}
}
@@ -4112,9 +4136,9 @@ public class PackageManagerService extends IPackageManager.Stub
mPermissionManager.enforceCrossUserPermission(callingUid, userId,
false /*requireFullPermission*/, false /*checkShell*/, "is package available");
synchronized (mLock) {
- PackageParser.Package p = mPackages.get(packageName);
+ AndroidPackage p = mPackages.get(packageName);
if (p != null) {
- final PackageSetting ps = (PackageSetting) p.mExtras;
+ final PackageSetting ps = getPackageSetting(p.getPackageName());
if (shouldFilterApplicationLocked(ps, callingUid, userId)) {
return false;
}
@@ -4179,21 +4203,22 @@ public class PackageManagerService extends IPackageManager.Stub
}
}
- PackageParser.Package p = mPackages.get(packageName);
+ AndroidPackage p = mPackages.get(packageName);
if (matchFactoryOnly && p != null && !isSystemApp(p)) {
return null;
}
if (DEBUG_PACKAGE_INFO)
Log.v(TAG, "getPackageInfo " + packageName + ": " + p);
if (p != null) {
- final PackageSetting ps = (PackageSetting) p.mExtras;
+ final PackageSetting ps = getPackageSetting(p.getPackageName());
if (filterSharedLibPackageLPr(ps, filterCallingUid, userId, flags)) {
return null;
}
if (ps != null && shouldFilterApplicationLocked(ps, filterCallingUid, userId)) {
return null;
}
- return generatePackageInfo((PackageSetting)p.mExtras, flags, userId);
+
+ return generatePackageInfo(ps, flags, userId);
}
if (!matchFactoryOnly && (flags & MATCH_KNOWN_PACKAGES) != 0) {
final PackageSetting ps = mSettings.mPackages.get(packageName);
@@ -4229,34 +4254,34 @@ public class PackageManagerService extends IPackageManager.Stub
private boolean isComponentVisibleToInstantApp(
@Nullable ComponentName component, @ComponentType int type) {
if (type == TYPE_ACTIVITY) {
- final PackageParser.Activity activity = mComponentResolver.getActivity(component);
+ final ParsedActivity activity = mComponentResolver.getActivity(component);
if (activity == null) {
return false;
}
final boolean visibleToInstantApp =
- (activity.info.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0;
+ (activity.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0;
final boolean explicitlyVisibleToInstantApp =
- (activity.info.flags & ActivityInfo.FLAG_IMPLICITLY_VISIBLE_TO_INSTANT_APP) == 0;
+ (activity.flags & ActivityInfo.FLAG_IMPLICITLY_VISIBLE_TO_INSTANT_APP) == 0;
return visibleToInstantApp && explicitlyVisibleToInstantApp;
} else if (type == TYPE_RECEIVER) {
- final PackageParser.Activity activity = mComponentResolver.getReceiver(component);
+ final ParsedActivity activity = mComponentResolver.getReceiver(component);
if (activity == null) {
return false;
}
final boolean visibleToInstantApp =
- (activity.info.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0;
+ (activity.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0;
final boolean explicitlyVisibleToInstantApp =
- (activity.info.flags & ActivityInfo.FLAG_IMPLICITLY_VISIBLE_TO_INSTANT_APP) == 0;
+ (activity.flags & ActivityInfo.FLAG_IMPLICITLY_VISIBLE_TO_INSTANT_APP) == 0;
return visibleToInstantApp && !explicitlyVisibleToInstantApp;
} else if (type == TYPE_SERVICE) {
- final PackageParser.Service service = mComponentResolver.getService(component);
+ final ParsedService service = mComponentResolver.getService(component);
return service != null
- ? (service.info.flags & ServiceInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0
+ ? (service.flags & ServiceInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0
: false;
} else if (type == TYPE_PROVIDER) {
- final PackageParser.Provider provider = mComponentResolver.getProvider(component);
+ final ParsedProvider provider = mComponentResolver.getProvider(component);
return provider != null
- ? (provider.info.flags & ProviderInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0
+ ? (provider.getFlags() & ProviderInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0
: false;
} else if (type == TYPE_UNKNOWN) {
return isComponentVisibleToInstantApp(component);
@@ -4300,16 +4325,16 @@ public class PackageManagerService extends IPackageManager.Stub
// request for a specific component; if it hasn't been explicitly exposed through
// property or instrumentation target, filter
if (component != null) {
- final PackageParser.Instrumentation instrumentation =
+ final ParsedInstrumentation instrumentation =
mInstrumentation.get(component);
if (instrumentation != null
- && isCallerSameApp(instrumentation.info.targetPackage, callingUid)) {
+ && isCallerSameApp(instrumentation.getTargetPackage(), callingUid)) {
return false;
}
return !isComponentVisibleToInstantApp(component, componentType);
}
// request for application; if no components have been explicitly exposed, filter
- return !ps.pkg.visibleToInstantApps;
+ return !ps.pkg.isVisibleToInstantApps();
}
if (ps.getInstantApp(userId)) {
// caller can see all components of all instant applications, don't filter
@@ -4358,12 +4383,12 @@ public class PackageManagerService extends IPackageManager.Stub
}
// No package means no static lib as it is always on internal storage
- if (ps == null || ps.pkg == null || !ps.pkg.applicationInfo.isStaticSharedLibrary()) {
+ if (ps == null || ps.pkg == null || !ps.pkg.isStaticSharedLibrary()) {
return false;
}
- final SharedLibraryInfo libraryInfo = getSharedLibraryInfoLPr(ps.pkg.staticSharedLibName,
- ps.pkg.staticSharedLibVersion);
+ final SharedLibraryInfo libraryInfo = getSharedLibraryInfoLPr(
+ ps.pkg.getStaticSharedLibName(), ps.pkg.getStaticSharedLibVersion());
if (libraryInfo == null) {
return false;
}
@@ -4385,7 +4410,8 @@ public class PackageManagerService extends IPackageManager.Stub
if (index < 0) {
continue;
}
- if (uidPs.pkg.usesStaticLibrariesVersions[index] == libraryInfo.getLongVersion()) {
+ if (uidPs.pkg.getUsesStaticLibrariesVersions()[index]
+ == libraryInfo.getLongVersion()) {
return false;
}
}
@@ -4459,13 +4485,13 @@ public class PackageManagerService extends IPackageManager.Stub
// reader
synchronized (mLock) {
- final PackageParser.Package p = mPackages.get(packageName);
+ final AndroidPackage p = mPackages.get(packageName);
if (p != null && p.isMatch(flags)) {
- PackageSetting ps = (PackageSetting) p.mExtras;
+ PackageSetting ps = getPackageSetting(p.getPackageName());
if (shouldFilterApplicationLocked(ps, callingUid, userId)) {
return -1;
}
- return UserHandle.getUid(userId, p.applicationInfo.uid);
+ return UserHandle.getUid(userId, p.getUid());
}
if ((flags & MATCH_KNOWN_PACKAGES) != 0) {
final PackageSetting ps = mSettings.mPackages.get(packageName);
@@ -4489,9 +4515,9 @@ public class PackageManagerService extends IPackageManager.Stub
// reader
synchronized (mLock) {
- final PackageParser.Package p = mPackages.get(packageName);
+ final AndroidPackage p = mPackages.get(packageName);
if (p != null && p.isMatch(flags)) {
- PackageSetting ps = (PackageSetting) p.mExtras;
+ PackageSetting ps = getPackageSetting(p.getPackageName());
if (shouldFilterApplicationLocked(ps, callingUid, userId)) {
return null;
}
@@ -4541,7 +4567,7 @@ public class PackageManagerService extends IPackageManager.Stub
}
return null;
}
- ApplicationInfo ai = PackageParser.generateApplicationInfo(ps.pkg, flags,
+ ApplicationInfo ai = PackageInfoUtils.generateApplicationInfo(ps.pkg, flags,
ps.readUserState(userId), userId);
if (ai != null) {
ai.packageName = resolveExternalPackageNameLPr(ps.pkg);
@@ -4579,7 +4605,7 @@ public class PackageManagerService extends IPackageManager.Stub
packageName = resolveInternalPackageNameLPr(packageName,
PackageManager.VERSION_CODE_HIGHEST);
- PackageParser.Package p = mPackages.get(packageName);
+ AndroidPackage p = mPackages.get(packageName);
if (DEBUG_PACKAGE_INFO) Log.v(
TAG, "getApplicationInfo " + packageName
+ ": " + p);
@@ -4593,7 +4619,7 @@ public class PackageManagerService extends IPackageManager.Stub
return null;
}
// Note: isEnabledLP() does not apply here - always return info
- ApplicationInfo ai = PackageParser.generateApplicationInfo(
+ ApplicationInfo ai = PackageInfoUtils.generateApplicationInfo(
p, flags, ps.readUserState(userId), userId);
if (ai != null) {
ai.packageName = resolveExternalPackageNameLPr(p);
@@ -4969,17 +4995,19 @@ public class PackageManagerService extends IPackageManager.Stub
}
synchronized (mLock) {
- PackageParser.Activity a = mComponentResolver.getActivity(component);
+ ParsedActivity a = mComponentResolver.getActivity(component);
if (DEBUG_PACKAGE_INFO) Log.v(TAG, "getActivityInfo " + component + ": " + a);
- if (a != null && mSettings.isEnabledAndMatchLPr(a.info, flags, userId)) {
+
+ AndroidPackage pkg = a == null ? null : mPackages.get(a.getPackageName());
+ if (pkg != null && mSettings.isEnabledAndMatchLPr(pkg, a, flags, userId)) {
PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
if (ps == null) return null;
if (shouldFilterApplicationLocked(
ps, filterCallingUid, component, TYPE_ACTIVITY, userId)) {
return null;
}
- return PackageParser.generateActivityInfo(
+ return PackageInfoUtils.generateActivityInfo(pkg,
a, flags, ps.readUserState(userId), userId);
}
if (mResolveComponentName.equals(component)) {
@@ -5016,7 +5044,7 @@ public class PackageManagerService extends IPackageManager.Stub
}
final int callingUid = Binder.getCallingUid();
final int callingUserId = UserHandle.getUserId(callingUid);
- PackageParser.Activity a = mComponentResolver.getActivity(component);
+ ParsedActivity a = mComponentResolver.getActivity(component);
if (a == null) {
return false;
}
@@ -5046,17 +5074,27 @@ public class PackageManagerService extends IPackageManager.Stub
mPermissionManager.enforceCrossUserPermission(callingUid, userId,
false /* requireFullPermission */, false /* checkShell */, "get receiver info");
synchronized (mLock) {
- PackageParser.Activity a = mComponentResolver.getReceiver(component);
+ ParsedActivity a = mComponentResolver.getReceiver(component);
if (DEBUG_PACKAGE_INFO) Log.v(
TAG, "getReceiverInfo " + component + ": " + a);
- if (a != null && mSettings.isEnabledAndMatchLPr(a.info, flags, userId)) {
+
+ if (a == null) {
+ return null;
+ }
+
+ AndroidPackage pkg = mPackages.get(a.getPackageName());
+ if (pkg == null) {
+ return null;
+ }
+
+ if (mSettings.isEnabledAndMatchLPr(pkg, a, flags, userId)) {
PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
if (ps == null) return null;
if (shouldFilterApplicationLocked(
ps, callingUid, component, TYPE_RECEIVER, userId)) {
return null;
}
- return PackageParser.generateActivityInfo(
+ return PackageInfoUtils.generateActivityInfo(pkg,
a, flags, ps.readUserState(userId), userId);
}
}
@@ -5235,13 +5273,13 @@ public class PackageManagerService extends IPackageManager.Stub
}
// If the dependent is a static shared lib, use the public package name
String dependentPackageName = ps.name;
- if (ps.pkg != null && ps.pkg.applicationInfo.isStaticSharedLibrary()) {
- dependentPackageName = ps.pkg.manifestPackageName;
+ if (ps.pkg != null && ps.pkg.isStaticSharedLibrary()) {
+ dependentPackageName = ps.pkg.getManifestPackageName();
}
versionedPackages.add(new VersionedPackage(dependentPackageName, ps.versionCode));
} else if (ps.pkg != null) {
- if (ArrayUtils.contains(ps.pkg.usesLibraries, libName)
- || ArrayUtils.contains(ps.pkg.usesOptionalLibraries, libName)) {
+ if (ArrayUtils.contains(ps.pkg.getUsesLibraries(), libName)
+ || ArrayUtils.contains(ps.pkg.getUsesOptionalLibraries(), libName)) {
if (versionedPackages == null) {
versionedPackages = new ArrayList<>();
}
@@ -5261,17 +5299,22 @@ public class PackageManagerService extends IPackageManager.Stub
mPermissionManager.enforceCrossUserPermission(callingUid, userId,
false /* requireFullPermission */, false /* checkShell */, "get service info");
synchronized (mLock) {
- PackageParser.Service s = mComponentResolver.getService(component);
+ ParsedService s = mComponentResolver.getService(component);
if (DEBUG_PACKAGE_INFO) Log.v(
- TAG, "getServiceInfo " + component + ": " + s);
- if (s != null && mSettings.isEnabledAndMatchLPr(s.info, flags, userId)) {
+ TAG, "getServiceInfo " + component + ": " + s);
+ if (s == null) {
+ return null;
+ }
+
+ AndroidPackage pkg = mPackages.get(s.getPackageName());
+ if (mSettings.isEnabledAndMatchLPr(pkg, s, flags, userId)) {
PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
if (ps == null) return null;
if (shouldFilterApplicationLocked(
ps, callingUid, component, TYPE_SERVICE, userId)) {
return null;
}
- return PackageParser.generateServiceInfo(
+ return PackageInfoUtils.generateServiceInfo(pkg,
s, flags, ps.readUserState(userId), userId);
}
}
@@ -5286,18 +5329,27 @@ public class PackageManagerService extends IPackageManager.Stub
mPermissionManager.enforceCrossUserPermission(callingUid, userId,
false /* requireFullPermission */, false /* checkShell */, "get provider info");
synchronized (mLock) {
- PackageParser.Provider p = mComponentResolver.getProvider(component);
+ ParsedProvider p = mComponentResolver.getProvider(component);
if (DEBUG_PACKAGE_INFO) Log.v(
- TAG, "getProviderInfo " + component + ": " + p);
- if (p != null && mSettings.isEnabledAndMatchLPr(p.info, flags, userId)) {
+ TAG, "getProviderInfo " + component + ": " + p);
+ if (p == null) {
+ return null;
+ }
+
+ AndroidPackage pkg = mPackages.get(p.getPackageName());
+ if (pkg == null) {
+ return null;
+ }
+
+ if (mSettings.isEnabledAndMatchLPr(pkg, p, flags, userId)) {
PackageSetting ps = mSettings.mPackages.get(component.getPackageName());
if (ps == null) return null;
if (shouldFilterApplicationLocked(
ps, callingUid, component, TYPE_PROVIDER, userId)) {
return null;
}
- return PackageParser.generateProviderInfo(
- p, flags, ps.readUserState(userId), userId);
+ PackageUserState state = ps.readUserState(userId);
+ return PackageInfoUtils.generateProviderInfo(pkg, p, flags, state, userId);
}
}
return null;
@@ -5555,21 +5607,21 @@ public class PackageManagerService extends IPackageManager.Stub
@Override
public int checkSignatures(String pkg1, String pkg2) {
synchronized (mLock) {
- final PackageParser.Package p1 = mPackages.get(pkg1);
- final PackageParser.Package p2 = mPackages.get(pkg2);
- if (p1 == null || p1.mExtras == null
- || p2 == null || p2.mExtras == null) {
+ final AndroidPackage p1 = mPackages.get(pkg1);
+ final AndroidPackage p2 = mPackages.get(pkg2);
+ final PackageSetting ps1 = p1 == null ? null : getPackageSetting(p1.getPackageName());
+ final PackageSetting ps2 = p2 == null ? null : getPackageSetting(p2.getPackageName());
+ if (p1 == null || ps1 == null || p2 == null || ps2 == null) {
return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
}
final int callingUid = Binder.getCallingUid();
final int callingUserId = UserHandle.getUserId(callingUid);
- final PackageSetting ps1 = (PackageSetting) p1.mExtras;
- final PackageSetting ps2 = (PackageSetting) p2.mExtras;
if (shouldFilterApplicationLocked(ps1, callingUid, callingUserId)
|| shouldFilterApplicationLocked(ps2, callingUid, callingUserId)) {
return PackageManager.SIGNATURE_UNKNOWN_PACKAGE;
}
- return compareSignatures(p1.mSigningDetails.signatures, p2.mSigningDetails.signatures);
+ return compareSignatures(p1.getSigningDetails().signatures,
+ p2.getSigningDetails().signatures);
}
}
@@ -5632,21 +5684,21 @@ public class PackageManagerService extends IPackageManager.Stub
String packageName, byte[] certificate, @PackageManager.CertificateInputType int type) {
synchronized (mLock) {
- final PackageParser.Package p = mPackages.get(packageName);
- if (p == null || p.mExtras == null) {
+ final AndroidPackage p = mPackages.get(packageName);
+ final PackageSetting ps = getPackageSetting(p.getPackageName());
+ if (p == null || ps == null) {
return false;
}
final int callingUid = Binder.getCallingUid();
final int callingUserId = UserHandle.getUserId(callingUid);
- final PackageSetting ps = (PackageSetting) p.mExtras;
if (shouldFilterApplicationLocked(ps, callingUid, callingUserId)) {
return false;
}
switch (type) {
case CERT_INPUT_RAW_X509:
- return p.mSigningDetails.hasCertificate(certificate);
+ return p.getSigningDetails().hasCertificate(certificate);
case CERT_INPUT_SHA256:
- return p.mSigningDetails.hasSha256Certificate(certificate);
+ return p.getSigningDetails().hasSha256Certificate(certificate);
default:
return false;
}
@@ -5699,16 +5751,16 @@ public class PackageManagerService extends IPackageManager.Stub
* external storage) is less than the version where package signatures
* were updated, return true.
*/
- private boolean isCompatSignatureUpdateNeeded(PackageParser.Package scannedPkg) {
- return isCompatSignatureUpdateNeeded(getSettingsVersionForPackage(scannedPkg));
+ private boolean isCompatSignatureUpdateNeeded(AndroidPackage pkg) {
+ return isCompatSignatureUpdateNeeded(getSettingsVersionForPackage(pkg));
}
private static boolean isCompatSignatureUpdateNeeded(VersionInfo ver) {
return ver.databaseVersion < DatabaseVersion.SIGNATURE_END_ENTITY;
}
- private boolean isRecoverSignatureUpdateNeeded(PackageParser.Package scannedPkg) {
- return isRecoverSignatureUpdateNeeded(getSettingsVersionForPackage(scannedPkg));
+ private boolean isRecoverSignatureUpdateNeeded(AndroidPackage pkg) {
+ return isRecoverSignatureUpdateNeeded(getSettingsVersionForPackage(pkg));
}
private static boolean isRecoverSignatureUpdateNeeded(VersionInfo ver) {
@@ -5727,24 +5779,23 @@ public class PackageManagerService extends IPackageManager.Stub
final List<String> result = new ArrayList<>();
if (instantAppPkgName != null) {
// caller is an instant application; filter unexposed applications
- for (PackageParser.Package pkg : mPackages.values()) {
- if (!pkg.visibleToInstantApps) {
+ for (AndroidPackage pkg : mPackages.values()) {
+ if (!pkg.isVisibleToInstantApps()) {
continue;
}
- result.add(pkg.packageName);
+ result.add(pkg.getPackageName());
}
} else {
// caller is a normal application; filter instant applications
- for (PackageParser.Package pkg : mPackages.values()) {
- final PackageSetting ps =
- pkg.mExtras != null ? (PackageSetting) pkg.mExtras : null;
+ for (AndroidPackage pkg : mPackages.values()) {
+ final PackageSetting ps = getPackageSetting(pkg.getPackageName());
if (ps != null
&& ps.getInstantApp(callingUserId)
&& !mInstantAppRegistry.isInstantAccessGranted(
callingUserId, UserHandle.getAppId(callingUid), ps.appId)) {
continue;
}
- result.add(pkg.packageName);
+ result.add(pkg.getPackageName());
}
}
return result;
@@ -6590,7 +6641,7 @@ public class PackageManagerService extends IPackageManager.Stub
if (obj instanceof PackageSetting) {
final PackageSetting ps = (PackageSetting) obj;
final boolean isInstantApp = ps.getInstantApp(UserHandle.getUserId(callingUid));
- return isInstantApp ? ps.pkg.packageName : null;
+ return isInstantApp ? ps.pkg.getPackageName() : null;
}
}
return null;
@@ -6662,9 +6713,11 @@ public class PackageManagerService extends IPackageManager.Stub
list.add(ri);
}
}
- return applyPostResolutionFilter(
+
+ List<ResolveInfo> result = applyPostResolutionFilter(
list, instantAppPkgName, allowDynamicSplits, filterCallingUid, resolveForStart,
userId, intent);
+ return result;
}
// reader
@@ -6741,11 +6794,11 @@ public class PackageManagerService extends IPackageManager.Stub
sortResult = true;
}
} else {
- final PackageParser.Package pkg = mPackages.get(pkgName);
+ final AndroidPackage pkg = mPackages.get(pkgName);
result = null;
if (pkg != null) {
result = filterIfNotSystemUser(mComponentResolver.queryActivities(
- intent, resolvedType, flags, pkg.activities, userId), userId);
+ intent, resolvedType, flags, pkg.getActivities(), userId), userId);
}
if (result == null || result.size() == 0) {
// the caller wants to resolve for a particular package; however, there
@@ -7638,10 +7691,10 @@ public class PackageManagerService extends IPackageManager.Stub
result, instantAppPkgName, allowDynamicSplits, callingUid, false, userId,
intent);
}
- final PackageParser.Package pkg = mPackages.get(pkgName);
+ final AndroidPackage pkg = mPackages.get(pkgName);
if (pkg != null) {
final List<ResolveInfo> result = mComponentResolver.queryReceivers(
- intent, resolvedType, flags, pkg.receivers, userId);
+ intent, resolvedType, flags, pkg.getReceivers(), userId);
return applyPostResolutionFilter(
result, instantAppPkgName, allowDynamicSplits, callingUid, false, userId,
intent);
@@ -7740,11 +7793,11 @@ public class PackageManagerService extends IPackageManager.Stub
mComponentResolver.queryServices(intent, resolvedType, flags, userId),
instantAppPkgName);
}
- final PackageParser.Package pkg = mPackages.get(pkgName);
+ final AndroidPackage pkg = mPackages.get(pkgName);
if (pkg != null) {
return applyPostServiceResolutionFilter(
- mComponentResolver.queryServices(intent, resolvedType, flags, pkg.services,
- userId),
+ mComponentResolver.queryServices(intent, resolvedType, flags,
+ pkg.getServices(), userId),
instantAppPkgName);
}
return Collections.emptyList();
@@ -7858,11 +7911,11 @@ public class PackageManagerService extends IPackageManager.Stub
mComponentResolver.queryProviders(intent, resolvedType, flags, userId),
instantAppPkgName);
}
- final PackageParser.Package pkg = mPackages.get(pkgName);
+ final AndroidPackage pkg = mPackages.get(pkgName);
if (pkg != null) {
return applyPostContentProviderResolutionFilter(
mComponentResolver.queryProviders(intent, resolvedType, flags,
- pkg.providers, userId),
+ pkg.getProviders(), userId),
instantAppPkgName);
}
return Collections.emptyList();
@@ -7947,16 +8000,15 @@ public class PackageManagerService extends IPackageManager.Stub
}
} else {
list = new ArrayList<>(mPackages.size());
- for (PackageParser.Package p : mPackages.values()) {
- final PackageSetting ps = (PackageSetting) p.mExtras;
+ for (AndroidPackage p : mPackages.values()) {
+ final PackageSetting ps = getPackageSetting(p.getPackageName());
if (filterSharedLibPackageLPr(ps, callingUid, userId, flags)) {
continue;
}
if (shouldFilterApplicationLocked(ps, callingUid, userId)) {
continue;
}
- final PackageInfo pi = generatePackageInfo((PackageSetting)
- p.mExtras, flags, userId);
+ final PackageInfo pi = generatePackageInfo(ps, flags, userId);
if (pi != null) {
list.add(pi);
}
@@ -8035,8 +8087,8 @@ public class PackageManagerService extends IPackageManager.Stub
userId);
}
} else {
- for (PackageParser.Package pkg : mPackages.values()) {
- PackageSetting ps = (PackageSetting)pkg.mExtras;
+ for (AndroidPackage pkg : mPackages.values()) {
+ PackageSetting ps = getPackageSetting(pkg.getPackageName());
if (ps != null) {
addPackageHoldingPermissions(list, ps, permissions, tmpBools, flags,
userId);
@@ -8089,7 +8141,7 @@ public class PackageManagerService extends IPackageManager.Stub
if (shouldFilterApplicationLocked(ps, callingUid, userId)) {
continue;
}
- ai = PackageParser.generateApplicationInfo(ps.pkg, effectiveFlags,
+ ai = PackageInfoUtils.generateApplicationInfo(ps.pkg, effectiveFlags,
ps.readUserState(userId), userId);
if (ai != null) {
ai.packageName = resolveExternalPackageNameLPr(ps.pkg);
@@ -8106,16 +8158,16 @@ public class PackageManagerService extends IPackageManager.Stub
}
} else {
list = new ArrayList<>(mPackages.size());
- for (PackageParser.Package p : mPackages.values()) {
- if (p.mExtras != null) {
- PackageSetting ps = (PackageSetting) p.mExtras;
+ for (AndroidPackage p : mPackages.values()) {
+ final PackageSetting ps = getPackageSetting(p.getPackageName());
+ if (ps != null) {
if (filterSharedLibPackageLPr(ps, Binder.getCallingUid(), userId, flags)) {
continue;
}
if (shouldFilterApplicationLocked(ps, callingUid, userId)) {
continue;
}
- ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags,
+ ApplicationInfo ai = PackageInfoUtils.generateApplicationInfo(p, flags,
ps.readUserState(userId), userId);
if (ai != null) {
ai.packageName = resolveExternalPackageNameLPr(p);
@@ -8171,7 +8223,6 @@ public class PackageManagerService extends IPackageManager.Stub
callingUid = mIsolatedOwners.get(callingUid);
}
final PackageSetting ps = mSettings.mPackages.get(packageName);
- PackageParser.Package pkg = mPackages.get(packageName);
final boolean returnAllowed =
ps != null
&& (isCallerSameApp(packageName, callingUid)
@@ -8242,9 +8293,9 @@ public class PackageManagerService extends IPackageManager.Stub
}
private boolean isCallerSameApp(String packageName, int uid) {
- PackageParser.Package pkg = mPackages.get(packageName);
+ AndroidPackage pkg = mPackages.get(packageName);
return pkg != null
- && UserHandle.getAppId(uid) == pkg.applicationInfo.uid;
+ && UserHandle.getAppId(uid) == pkg.getUid();
}
@Override
@@ -8260,23 +8311,22 @@ public class PackageManagerService extends IPackageManager.Stub
// reader
synchronized (mLock) {
- final Iterator<PackageParser.Package> i = mPackages.values().iterator();
+ final Iterator<AndroidPackage> i = mPackages.values().iterator();
final int userId = UserHandle.getCallingUserId();
while (i.hasNext()) {
- final PackageParser.Package p = i.next();
- if (p.applicationInfo == null) continue;
+ final AndroidPackage p = i.next();
final boolean matchesUnaware = ((flags & MATCH_DIRECT_BOOT_UNAWARE) != 0)
- && !p.applicationInfo.isDirectBootAware();
+ && !p.isDirectBootAware();
final boolean matchesAware = ((flags & MATCH_DIRECT_BOOT_AWARE) != 0)
- && p.applicationInfo.isDirectBootAware();
+ && p.isDirectBootAware();
- if ((p.applicationInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0
+ if ((p.getFlags() & ApplicationInfo.FLAG_PERSISTENT) != 0
&& (!mSafeMode || isSystemApp(p))
&& (matchesUnaware || matchesAware)) {
- PackageSetting ps = mSettings.mPackages.get(p.packageName);
+ PackageSetting ps = mSettings.mPackages.get(p.getPackageName());
if (ps != null) {
- ApplicationInfo ai = PackageParser.generateApplicationInfo(p, flags,
+ ApplicationInfo ai = PackageInfoUtils.generateApplicationInfo(p, flags,
ps.readUserState(userId), userId);
if (ai != null) {
finalList.add(ai);
@@ -8298,7 +8348,8 @@ public class PackageManagerService extends IPackageManager.Stub
if (!mUserManager.exists(userId)) return null;
flags = updateFlagsForComponent(flags, userId, name);
final int callingUid = Binder.getCallingUid();
- final ProviderInfo providerInfo = mComponentResolver.queryProvider(name, flags, userId);
+ final ProviderInfo providerInfo = mComponentResolver.queryProvider(name, flags, callingUid,
+ userId);
if (providerInfo == null) {
return null;
}
@@ -8380,8 +8431,8 @@ public class PackageManagerService extends IPackageManager.Stub
ps, callingUid, component, TYPE_UNKNOWN, callingUserId)) {
return null;
}
- final PackageParser.Instrumentation i = mInstrumentation.get(component);
- return PackageParser.generateInstrumentationInfo(i, flags);
+ final ParsedInstrumentation i = mInstrumentation.get(component);
+ return PackageInfoUtils.generateInstrumentationInfo(i, flags);
}
}
@@ -8403,12 +8454,12 @@ public class PackageManagerService extends IPackageManager.Stub
// reader
synchronized (mLock) {
- final Iterator<PackageParser.Instrumentation> i = mInstrumentation.values().iterator();
+ final Iterator<ParsedInstrumentation> i = mInstrumentation.values().iterator();
while (i.hasNext()) {
- final PackageParser.Instrumentation p = i.next();
+ final ParsedInstrumentation p = i.next();
if (targetPackage == null
- || targetPackage.equals(p.info.targetPackage)) {
- InstrumentationInfo ii = PackageParser.generateInstrumentationInfo(p,
+ || targetPackage.equals(p.getTargetPackage())) {
+ InstrumentationInfo ii = PackageInfoUtils.generateInstrumentationInfo(p,
flags);
if (ii != null) {
finalList.add(ii);
@@ -8465,18 +8516,18 @@ public class PackageManagerService extends IPackageManager.Stub
if (throwable == null) {
// TODO(toddke): move lower in the scan chain
// Static shared libraries have synthetic package names
- if (parseResult.pkg.applicationInfo.isStaticSharedLibrary()) {
- renameStaticSharedLibraryPackage(parseResult.pkg);
+ if (parseResult.parsedPackage.isStaticSharedLibrary()) {
+ renameStaticSharedLibraryPackage(parseResult.parsedPackage);
}
try {
- scanPackageChildLI(parseResult.pkg, parseFlags, scanFlags,
+ addForInitLI(parseResult.parsedPackage, parseFlags, scanFlags,
currentTime, null);
} catch (PackageManagerException e) {
errorCode = e.error;
Slog.w(TAG, "Failed to scan " + parseResult.scanFile + ": " + e.getMessage());
}
- } else if (throwable instanceof PackageParser.PackageParserException) {
- PackageParser.PackageParserException e = (PackageParser.PackageParserException)
+ } else if (throwable instanceof PackageParserException) {
+ PackageParserException e = (PackageParserException)
throwable;
errorCode = e.error;
Slog.w(TAG, "Failed to parse " + parseResult.scanFile + ": " + e.getMessage());
@@ -8500,15 +8551,16 @@ public class PackageManagerService extends IPackageManager.Stub
logCriticalInfo(priority, msg);
}
- private void collectCertificatesLI(PackageSetting ps, PackageParser.Package pkg,
+ private void collectCertificatesLI(PackageSetting ps, ParsedPackage parsedPackage,
boolean forceCollect, boolean skipVerify) throws PackageManagerException {
// When upgrading from pre-N MR1, verify the package time stamp using the package
// directory and not the APK file.
final long lastModifiedTime = mIsPreNMR1Upgrade
- ? new File(pkg.codePath).lastModified() : getLastModifiedTime(pkg);
- final VersionInfo settingsVersionForPackage = getSettingsVersionForPackage(pkg);
+ ? new File(parsedPackage.getCodePath()).lastModified()
+ : getLastModifiedTime(parsedPackage);
+ final VersionInfo settingsVersionForPackage = getSettingsVersionForPackage(parsedPackage);
if (ps != null && !forceCollect
- && ps.codePathString.equals(pkg.codePath)
+ && ps.codePathString.equals(parsedPackage.getCodePath())
&& ps.timeStamp == lastModifiedTime
&& !isCompatSignatureUpdateNeeded(settingsVersionForPackage)
&& !isRecoverSignatureUpdateNeeded(settingsVersionForPackage)) {
@@ -8518,21 +8570,21 @@ public class PackageManagerService extends IPackageManager.Stub
!= SignatureSchemeVersion.UNKNOWN) {
// Optimization: reuse the existing cached signing data
// if the package appears to be unchanged.
- pkg.mSigningDetails =
- new PackageParser.SigningDetails(ps.signatures.mSigningDetails);
+ parsedPackage.setSigningDetails(
+ new PackageParser.SigningDetails(ps.signatures.mSigningDetails));
return;
}
Slog.w(TAG, "PackageSetting for " + ps.name
+ " is missing signatures. Collecting certs again to recover them.");
} else {
- Slog.i(TAG, pkg.codePath + " changed; collecting certs" +
+ Slog.i(TAG, parsedPackage.getCodePath() + " changed; collecting certs" +
(forceCollect ? " (forced)" : ""));
}
try {
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "collectCertificates");
- PackageParser.collectCertificates(pkg, skipVerify);
+ ApkParseUtils.collectCertificates(parsedPackage, skipVerify);
} catch (PackageParserException e) {
throw PackageManagerException.from(e);
} finally {
@@ -8546,20 +8598,20 @@ public class PackageManagerService extends IPackageManager.Stub
*/
private void maybeClearProfilesForUpgradesLI(
@Nullable PackageSetting originalPkgSetting,
- @NonNull PackageParser.Package currentPkg) {
+ @NonNull AndroidPackage pkg) {
if (originalPkgSetting == null || !isDeviceUpgrading()) {
return;
}
- if (originalPkgSetting.versionCode == currentPkg.mVersionCode) {
+ if (originalPkgSetting.versionCode == pkg.getVersionCode()) {
return;
}
- clearAppProfilesLIF(currentPkg, UserHandle.USER_ALL);
+ clearAppProfilesLIF(pkg, UserHandle.USER_ALL);
if (DEBUG_INSTALL) {
Slog.d(TAG, originalPkgSetting.name
+ " clear profile due to version change "
+ originalPkgSetting.versionCode + " != "
- + currentPkg.mVersionCode);
+ + pkg.getVersionCode());
}
}
@@ -8568,7 +8620,7 @@ public class PackageManagerService extends IPackageManager.Stub
* @see #scanPackageLI(File, int, int, long, UserHandle)
*/
@GuardedBy({"mInstallLock", "mLock"})
- private PackageParser.Package scanPackageTracedLI(File scanFile, final int parseFlags,
+ private AndroidPackage scanPackageTracedLI(File scanFile, final int parseFlags,
int scanFlags, long currentTime, UserHandle user) throws PackageManagerException {
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage [" + scanFile.toString() + "]");
try {
@@ -8583,7 +8635,7 @@ public class PackageManagerService extends IPackageManager.Stub
* Returns {@code null} in case of errors and the error code is stored in mLastScanError
*/
@GuardedBy({"mInstallLock", "mLock"})
- private PackageParser.Package scanPackageLI(File scanFile, int parseFlags, int scanFlags,
+ private AndroidPackage scanPackageLI(File scanFile, int parseFlags, int scanFlags,
long currentTime, UserHandle user) throws PackageManagerException {
if (DEBUG_INSTALL) Slog.d(TAG, "Parsing: " + scanFile);
PackageParser pp = new PackageParser();
@@ -8593,9 +8645,9 @@ public class PackageManagerService extends IPackageManager.Stub
pp.setCallback(mPackageParserCallback);
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage");
- final PackageParser.Package pkg;
+ final ParsedPackage parsedPackage;
try {
- pkg = pp.parsePackage(scanFile, parseFlags);
+ parsedPackage = pp.parseParsedPackage(scanFile, parseFlags, false);
} catch (PackageParserException e) {
throw PackageManagerException.from(e);
} finally {
@@ -8603,66 +8655,25 @@ public class PackageManagerService extends IPackageManager.Stub
}
// Static shared libraries have synthetic package names
- if (pkg.applicationInfo.isStaticSharedLibrary()) {
- renameStaticSharedLibraryPackage(pkg);
- }
-
- return scanPackageChildLI(pkg, parseFlags, scanFlags, currentTime, user);
- }
-
- /**
- * Scans a package and returns the newly parsed package.
- * @throws PackageManagerException on a parse error.
- */
- @GuardedBy({"mInstallLock", "mLock"})
- private PackageParser.Package scanPackageChildLI(PackageParser.Package pkg,
- final @ParseFlags int parseFlags, @ScanFlags int scanFlags, long currentTime,
- @Nullable UserHandle user)
- throws PackageManagerException {
- // If the package has children and this is the first dive in the function
- // we scan the package with the SCAN_CHECK_ONLY flag set to see whether all
- // packages (parent and children) would be successfully scanned before the
- // actual scan since scanning mutates internal state and we want to atomically
- // install the package and its children.
- if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
- if (pkg.childPackages != null && pkg.childPackages.size() > 0) {
- scanFlags |= SCAN_CHECK_ONLY;
- }
- } else {
- scanFlags &= ~SCAN_CHECK_ONLY;
- }
-
- // Scan the parent
- PackageParser.Package scannedPkg = addForInitLI(pkg, parseFlags,
- scanFlags, currentTime, user);
-
- // Scan the children
- final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
- for (int i = 0; i < childCount; i++) {
- PackageParser.Package childPackage = pkg.childPackages.get(i);
- addForInitLI(childPackage, parseFlags, scanFlags,
- currentTime, user);
+ if (parsedPackage.isStaticSharedLibrary()) {
+ renameStaticSharedLibraryPackage(parsedPackage);
}
-
- if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
- return scanPackageChildLI(pkg, parseFlags, scanFlags, currentTime, user);
- }
-
- return scannedPkg;
+ return addForInitLI(parsedPackage, parseFlags, scanFlags, currentTime, user);
}
/**
* Returns if forced apk verification can be skipped for the whole package, including splits.
*/
- private boolean canSkipForcedPackageVerification(PackageParser.Package pkg) {
- if (!canSkipForcedApkVerification(pkg.baseCodePath)) {
+ private boolean canSkipForcedPackageVerification(AndroidPackage pkg) {
+ if (!canSkipForcedApkVerification(pkg.getBaseCodePath())) {
return false;
}
// TODO: Allow base and splits to be verified individually.
- if (!ArrayUtils.isEmpty(pkg.splitCodePaths)) {
- for (int i = 0; i < pkg.splitCodePaths.length; i++) {
- if (!canSkipForcedApkVerification(pkg.splitCodePaths[i])) {
+ String[] splitCodePaths = pkg.getSplitCodePaths();
+ if (!ArrayUtils.isEmpty(splitCodePaths)) {
+ for (int i = 0; i < splitCodePaths.length; i++) {
+ if (!canSkipForcedApkVerification(splitCodePaths[i])) {
return false;
}
}
@@ -8711,7 +8722,7 @@ public class PackageManagerService extends IPackageManager.Stub
* <p>NOTE: The return value should be removed. It's the passed in package object.
*/
@GuardedBy({"mInstallLock", "mLock"})
- private PackageParser.Package addForInitLI(PackageParser.Package pkg,
+ private AndroidPackage addForInitLI(ParsedPackage parsedPackage,
@ParseFlags int parseFlags, @ScanFlags int scanFlags, long currentTime,
@Nullable UserHandle user)
throws PackageManagerException {
@@ -8727,25 +8738,27 @@ public class PackageManagerService extends IPackageManager.Stub
// stack [such as scanPackageOnly()]. However, we verify the application
// info prior to that [in scanPackageNew()] and thus have to setup
// the application info early.
- pkg.setApplicationVolumeUuid(pkg.volumeUuid);
- pkg.setApplicationInfoCodePath(pkg.codePath);
- pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
- pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
- pkg.setApplicationInfoResourcePath(pkg.codePath);
- pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath);
- pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
+ // TODO(b/135203078): Remove all of these application info calls
+ parsedPackage.setApplicationVolumeUuid(parsedPackage.getVolumeUuid())
+ .setApplicationInfoCodePath(parsedPackage.getCodePath())
+ .setApplicationInfoResourcePath(parsedPackage.getCodePath())
+ .setApplicationInfoBaseResourcePath(parsedPackage.getBaseCodePath())
+ .setApplicationInfoSplitResourcePaths(parsedPackage.getSplitCodePaths());
synchronized (mLock) {
- renamedPkgName = mSettings.getRenamedPackageLPr(pkg.mRealPackage);
- final String realPkgName = getRealPackageName(pkg, renamedPkgName);
+ renamedPkgName = mSettings.getRenamedPackageLPr(parsedPackage.getRealPackage());
+ final String realPkgName = getRealPackageName(parsedPackage, renamedPkgName);
if (realPkgName != null) {
- ensurePackageRenamed(pkg, renamedPkgName);
+ ensurePackageRenamed(parsedPackage, renamedPkgName);
}
- final PackageSetting originalPkgSetting = getOriginalPackageLocked(pkg, renamedPkgName);
- final PackageSetting installedPkgSetting = mSettings.getPackageLPr(pkg.packageName);
+ final PackageSetting originalPkgSetting = getOriginalPackageLocked(parsedPackage,
+ renamedPkgName);
+ final PackageSetting installedPkgSetting = mSettings.getPackageLPr(
+ parsedPackage.getPackageName());
pkgSetting = originalPkgSetting == null ? installedPkgSetting : originalPkgSetting;
pkgAlreadyExists = pkgSetting != null;
- final String disabledPkgName = pkgAlreadyExists ? pkgSetting.name : pkg.packageName;
+ final String disabledPkgName =
+ pkgAlreadyExists ? pkgSetting.name : parsedPackage.getPackageName();
disabledPkgSetting = mSettings.getDisabledSystemPkgLPr(disabledPkgName);
isSystemPkgUpdated = disabledPkgSetting != null;
@@ -8753,49 +8766,29 @@ public class PackageManagerService extends IPackageManager.Stub
Slog.d(TAG, "updatedPkg = " + disabledPkgSetting);
}
- final SharedUserSetting sharedUserSetting = (pkg.mSharedUserId != null)
- ? mSettings.getSharedUserLPw(pkg.mSharedUserId,
+ final SharedUserSetting sharedUserSetting = (parsedPackage.getSharedUserId() != null)
+ ? mSettings.getSharedUserLPw(parsedPackage.getSharedUserId(),
0 /*pkgFlags*/, 0 /*pkgPrivateFlags*/, true)
: null;
if (DEBUG_PACKAGE_SCANNING
&& (parseFlags & PackageParser.PARSE_CHATTY) != 0
&& sharedUserSetting != null) {
- Log.d(TAG, "Shared UserID " + pkg.mSharedUserId
+ Log.d(TAG, "Shared UserID " + parsedPackage.getSharedUserId()
+ " (uid=" + sharedUserSetting.userId + "):"
+ " packages=" + sharedUserSetting.packages);
}
if (scanSystemPartition) {
- // Potentially prune child packages. If the application on the /system
- // partition has been updated via OTA, but, is still disabled by a
- // version on /data, cycle through all of its children packages and
- // remove children that are no longer defined.
if (isSystemPkgUpdated) {
- final int scannedChildCount = (pkg.childPackages != null)
- ? pkg.childPackages.size() : 0;
- final int disabledChildCount = disabledPkgSetting.childPackageNames != null
- ? disabledPkgSetting.childPackageNames.size() : 0;
- for (int i = 0; i < disabledChildCount; i++) {
- String disabledChildPackageName =
- disabledPkgSetting.childPackageNames.get(i);
- boolean disabledPackageAvailable = false;
- for (int j = 0; j < scannedChildCount; j++) {
- PackageParser.Package childPkg = pkg.childPackages.get(j);
- if (childPkg.packageName.equals(disabledChildPackageName)) {
- disabledPackageAvailable = true;
- break;
- }
- }
- if (!disabledPackageAvailable) {
- mSettings.removeDisabledSystemPackageLPw(disabledChildPackageName);
- }
- }
// we're updating the disabled package, so, scan it as the package setting
- final ScanRequest request = new ScanRequest(pkg, sharedUserSetting, null,
- disabledPkgSetting /* pkgSetting */, null /* disabledPkgSetting */,
- null /* originalPkgSetting */, null, parseFlags, scanFlags,
- (pkg == mPlatformPackage), user);
- applyPolicy(pkg, parseFlags, scanFlags, mPlatformPackage);
+ boolean isPlatformPackage = mPlatformPackage != null
+ && Objects.equals(mPlatformPackage.getPackageName(),
+ parsedPackage.getPackageName());
+ final ScanRequest request = new ScanRequest(parsedPackage, sharedUserSetting,
+ null, disabledPkgSetting /* pkgSetting */,
+ null /* disabledPkgSetting */, null /* originalPkgSetting */,
+ null, parseFlags, scanFlags, isPlatformPackage, user);
+ applyPolicy(parsedPackage, parseFlags, scanFlags, mPlatformPackage);
final ScanResult scanResult =
scanPackageOnlyLI(request, mInjector, mFactoryTest, -1L);
if (scanResult.existingSettingCopied && scanResult.request.pkgSetting != null) {
@@ -8806,9 +8799,9 @@ public class PackageManagerService extends IPackageManager.Stub
}
final boolean newPkgChangedPaths =
- pkgAlreadyExists && !pkgSetting.codePathString.equals(pkg.codePath);
+ pkgAlreadyExists && !pkgSetting.codePathString.equals(parsedPackage.getCodePath());
final boolean newPkgVersionGreater =
- pkgAlreadyExists && pkg.getLongVersionCode() > pkgSetting.versionCode;
+ pkgAlreadyExists && parsedPackage.getLongVersionCode() > pkgSetting.versionCode;
final boolean isSystemPkgBetter = scanSystemPartition && isSystemPkgUpdated
&& newPkgChangedPaths && newPkgVersionGreater;
if (isSystemPkgBetter) {
@@ -8824,12 +8817,13 @@ public class PackageManagerService extends IPackageManager.Stub
logCriticalInfo(Log.WARN,
"System package updated;"
+ " name: " + pkgSetting.name
- + "; " + pkgSetting.versionCode + " --> " + pkg.getLongVersionCode()
- + "; " + pkgSetting.codePathString + " --> " + pkg.codePath);
+ + "; " + pkgSetting.versionCode + " --> " + parsedPackage.getLongVersionCode()
+ + "; " + pkgSetting.codePathString + " --> " + parsedPackage.getCodePath());
final InstallArgs args = createInstallArgsForExisting(
pkgSetting.codePathString,
- pkgSetting.resourcePathString, getAppDexInstructionSets(pkgSetting));
+ pkgSetting.resourcePathString, getAppDexInstructionSets(
+ pkgSetting.primaryCpuAbiString, pkgSetting.secondaryCpuAbiString));
args.cleanUpResourcesLI();
synchronized (mLock) {
mSettings.enableSystemPackageLPw(pkgSetting.name);
@@ -8840,9 +8834,10 @@ public class PackageManagerService extends IPackageManager.Stub
// The version of the application on the /system partition is less than or
// equal to the version on the /data partition. Throw an exception and use
// the application already installed on the /data partition.
- throw new PackageManagerException(Log.WARN, "Package " + pkg.packageName + " at "
- + pkg.codePath + " ignored: updated version " + pkgSetting.versionCode
- + " better than this " + pkg.getLongVersionCode());
+ throw new PackageManagerException(Log.WARN, "Package " + parsedPackage.getPackageName()
+ + " at " + parsedPackage.getCodePath() + " ignored: updated version "
+ + pkgSetting.versionCode + " better than this "
+ + parsedPackage.getLongVersionCode());
}
// Verify certificates against what was last scanned. Force re-collecting certificate in two
@@ -8853,18 +8848,18 @@ public class PackageManagerService extends IPackageManager.Stub
final boolean forceCollect = scanSystemPartition ? mIsUpgrade
: PackageManagerServiceUtils.isApkVerificationForced(pkgSetting);
if (DEBUG_VERIFY && forceCollect) {
- Slog.d(TAG, "Force collect certificate of " + pkg.packageName);
+ Slog.d(TAG, "Force collect certificate of " + parsedPackage.getPackageName());
}
// Full APK verification can be skipped during certificate collection, only if the file is
// in verified partition, or can be verified on access (when apk verity is enabled). In both
// cases, only data in Signing Block is verified instead of the whole file.
final boolean skipVerify = scanSystemPartition
- || (forceCollect && canSkipForcedPackageVerification(pkg));
- collectCertificatesLI(pkgSetting, pkg, forceCollect, skipVerify);
+ || (forceCollect && canSkipForcedPackageVerification(parsedPackage));
+ collectCertificatesLI(pkgSetting, parsedPackage, forceCollect, skipVerify);
// Reset profile if the application version is changed
- maybeClearProfilesForUpgradesLI(pkgSetting, pkg);
+ maybeClearProfilesForUpgradesLI(pkgSetting, parsedPackage);
/*
* A new system app appeared, but we already had a non-system one of the
@@ -8876,17 +8871,20 @@ public class PackageManagerService extends IPackageManager.Stub
if (scanSystemPartition && !isSystemPkgUpdated && pkgAlreadyExists
&& !pkgSetting.isSystem()) {
- if (!pkg.mSigningDetails.checkCapability(pkgSetting.signatures.mSigningDetails,
+ if (!parsedPackage.getSigningDetails()
+ .checkCapability(pkgSetting.signatures.mSigningDetails,
PackageParser.SigningDetails.CertCapabilities.INSTALLED_DATA)
&& !pkgSetting.signatures.mSigningDetails.checkCapability(
- pkg.mSigningDetails,
+ parsedPackage.getSigningDetails(),
PackageParser.SigningDetails.CertCapabilities.ROLLBACK)) {
logCriticalInfo(Log.WARN,
"System package signature mismatch;"
+ " name: " + pkgSetting.name);
- try (PackageFreezer freezer = freezePackage(pkg.packageName,
+ try (@SuppressWarnings("unused") PackageFreezer freezer = freezePackage(
+ parsedPackage.getPackageName(),
"scanPackageInternalLI")) {
- deletePackageLIF(pkg.packageName, null, true, null, 0, null, false, null);
+ deletePackageLIF(parsedPackage.getPackageName(), null, true, null, 0, null,
+ false, null);
}
pkgSetting = null;
} else if (newPkgVersionGreater) {
@@ -8895,12 +8893,15 @@ public class PackageManagerService extends IPackageManager.Stub
// and replace it with the version on /system.
logCriticalInfo(Log.WARN,
"System package enabled;"
- + " name: " + pkgSetting.name
- + "; " + pkgSetting.versionCode + " --> " + pkg.getLongVersionCode()
- + "; " + pkgSetting.codePathString + " --> " + pkg.codePath);
+ + " name: " + pkgSetting.name
+ + "; " + pkgSetting.versionCode + " --> "
+ + parsedPackage.getLongVersionCode()
+ + "; " + pkgSetting.codePathString + " --> "
+ + parsedPackage.getCodePath());
InstallArgs args = createInstallArgsForExisting(
pkgSetting.codePathString,
- pkgSetting.resourcePathString, getAppDexInstructionSets(pkgSetting));
+ pkgSetting.resourcePathString, getAppDexInstructionSets(
+ pkgSetting.primaryCpuAbiString, pkgSetting.secondaryCpuAbiString));
synchronized (mInstallLock) {
args.cleanUpResourcesLI();
}
@@ -8911,13 +8912,15 @@ public class PackageManagerService extends IPackageManager.Stub
shouldHideSystemApp = true;
logCriticalInfo(Log.INFO,
"System package disabled;"
- + " name: " + pkgSetting.name
- + "; old: " + pkgSetting.codePathString + " @ " + pkgSetting.versionCode
- + "; new: " + pkg.codePath + " @ " + pkg.codePath);
+ + " name: " + pkgSetting.name
+ + "; old: " + pkgSetting.codePathString + " @ "
+ + pkgSetting.versionCode
+ + "; new: " + parsedPackage.getCodePath() + " @ "
+ + parsedPackage.getCodePath());
}
}
- final ScanResult scanResult = scanPackageNewLI(pkg, parseFlags, scanFlags
+ final ScanResult scanResult = scanPackageNewLI(parsedPackage, parseFlags, scanFlags
| SCAN_UPDATE_SIGNATURE, currentTime, user);
if (scanResult.success) {
synchronized (mLock) {
@@ -8930,7 +8933,7 @@ public class PackageManagerService extends IPackageManager.Stub
mSharedLibraries,
mPackages,
Collections.singletonMap(
- pkgName, getSettingsVersionForPackage(pkg)),
+ pkgName, getSettingsVersionForPackage(parsedPackage)),
Collections.singletonMap(pkgName,
getSharedLibLatestVersionSetting(scanResult))),
mSettings.mKeySetManagerService);
@@ -8947,16 +8950,17 @@ public class PackageManagerService extends IPackageManager.Stub
if (shouldHideSystemApp) {
synchronized (mLock) {
- mSettings.disableSystemPackageLPw(pkg.packageName, true);
+ mSettings.disableSystemPackageLPw(parsedPackage.getPackageName(), true);
}
}
return scanResult.pkgSetting.pkg;
}
- private static void renameStaticSharedLibraryPackage(PackageParser.Package pkg) {
+ // TODO:(b/135203078): Move to parsing
+ private static void renameStaticSharedLibraryPackage(ParsedPackage parsedPackage) {
// Derive the new package synthetic package name
- pkg.setPackageName(pkg.packageName + STATIC_SHARED_LIB_DELIMITER
- + pkg.staticSharedLibVersion);
+ parsedPackage.setPackageName(parsedPackage.getPackageName() + STATIC_SHARED_LIB_DELIMITER
+ + parsedPackage.getStaticSharedLibVersion());
}
static String fixProcessName(String defProcessName, String processName) {
@@ -9057,7 +9061,7 @@ public class PackageManagerService extends IPackageManager.Stub
return;
}
- List<PackageParser.Package> pkgs;
+ List<AndroidPackage> pkgs;
synchronized (mLock) {
pkgs = PackageManagerServiceUtils.getPackagesForDexopt(mPackages.values(), this);
}
@@ -9080,8 +9084,8 @@ public class PackageManagerService extends IPackageManager.Stub
/*
* Return the prebuilt profile path given a package base code path.
*/
- private static String getPrebuildProfilePath(PackageParser.Package pkg) {
- return pkg.baseCodePath + ".prof";
+ private static String getPrebuildProfilePath(AndroidPackage pkg) {
+ return pkg.getBaseCodePath() + ".prof";
}
/**
@@ -9090,7 +9094,7 @@ public class PackageManagerService extends IPackageManager.Stub
* which are (in order) {@code numberOfPackagesOptimized}, {@code numberOfPackagesSkipped}
* and {@code numberOfPackagesFailed}.
*/
- private int[] performDexOptUpgrade(List<PackageParser.Package> pkgs, boolean showDialog,
+ private int[] performDexOptUpgrade(List<AndroidPackage> pkgs, boolean showDialog,
final int compilationReason, boolean bootComplete) {
int numberOfPackagesVisited = 0;
@@ -9099,7 +9103,7 @@ public class PackageManagerService extends IPackageManager.Stub
int numberOfPackagesFailed = 0;
final int numberOfPackagesToDexopt = pkgs.size();
- for (PackageParser.Package pkg : pkgs) {
+ for (AndroidPackage pkg : pkgs) {
numberOfPackagesVisited++;
boolean useProfileForDexopt = false;
@@ -9115,7 +9119,7 @@ public class PackageManagerService extends IPackageManager.Stub
// PackageDexOptimizer to prevent this happening on first boot. The issue
// is that we don't have a good way to say "do this only once".
if (!mInstaller.copySystemProfile(profileFile.getAbsolutePath(),
- pkg.applicationInfo.uid, pkg.packageName,
+ pkg.getUid(), pkg.getPackageName(),
ArtManager.getProfileName(null))) {
Log.e(TAG, "Installer failed to copy system profile!");
} else {
@@ -9128,11 +9132,12 @@ public class PackageManagerService extends IPackageManager.Stub
e);
}
} else {
- PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(pkg.packageName);
+ PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(
+ pkg.getPackageName());
// Handle compressed APKs in this path. Only do this for stubs with profiles to
// minimize the number off apps being speed-profile compiled during first boot.
// The other paths will not change the filter.
- if (disabledPs != null && disabledPs.pkg.isStub) {
+ if (disabledPs != null && disabledPs.pkg.isStub()) {
// The package is the stub one, remove the stub suffix to get the normal
// package and APK names.
String systemProfilePath =
@@ -9151,7 +9156,7 @@ public class PackageManagerService extends IPackageManager.Stub
// issue is that we don't have a good way to say "do this only
// once".
if (!mInstaller.copySystemProfile(profileFile.getAbsolutePath(),
- pkg.applicationInfo.uid, pkg.packageName,
+ pkg.getUid(), pkg.getPackageName(),
ArtManager.getProfileName(null))) {
Log.e(TAG, "Failed to copy system profile for stub package!");
} else {
@@ -9168,7 +9173,7 @@ public class PackageManagerService extends IPackageManager.Stub
if (!PackageDexOptimizer.canOptimizePackage(pkg)) {
if (DEBUG_DEXOPT) {
- Log.i(TAG, "Skipping update of of non-optimizable app " + pkg.packageName);
+ Log.i(TAG, "Skipping update of non-optimizable app " + pkg.getPackageName());
}
numberOfPackagesSkipped++;
continue;
@@ -9176,7 +9181,7 @@ public class PackageManagerService extends IPackageManager.Stub
if (DEBUG_DEXOPT) {
Log.i(TAG, "Updating app " + numberOfPackagesVisited + " of " +
- numberOfPackagesToDexopt + ": " + pkg.packageName);
+ numberOfPackagesToDexopt + ": " + pkg.getPackageName());
}
if (showDialog) {
@@ -9213,7 +9218,7 @@ public class PackageManagerService extends IPackageManager.Stub
dexoptFlags |= DexoptOptions.DEXOPT_INSTALL_WITH_DEX_METADATA_FILE;
}
int primaryDexOptStaus = performDexOptTraced(new DexoptOptions(
- pkg.packageName,
+ pkg.getPackageName(),
pkgCompilationReason,
dexoptFlags));
@@ -9257,11 +9262,11 @@ public class PackageManagerService extends IPackageManager.Stub
@GuardedBy("mLock")
private void notifyPackageUseLocked(String packageName, int reason) {
- final PackageParser.Package p = mPackages.get(packageName);
+ final AndroidPackage p = mPackages.get(packageName);
if (p == null) {
return;
}
- p.mLastPackageUsageTimeInMills[reason] = System.currentTimeMillis();
+ p.mutate().setLastPackageUsageTimeInMills(reason, System.currentTimeMillis());
}
@Override
@@ -9341,7 +9346,7 @@ public class PackageManagerService extends IPackageManager.Stub
*/
@Override
public boolean compileLayouts(String packageName) {
- PackageParser.Package pkg;
+ AndroidPackage pkg;
synchronized (mLock) {
pkg = mPackages.get(packageName);
if (pkg == null) {
@@ -9388,7 +9393,7 @@ public class PackageManagerService extends IPackageManager.Stub
// Run dexopt on a given package. Returns true if dexopt did not fail, i.e.
// if the package can now be considered up to date for the given filter.
private int performDexOptInternal(DexoptOptions options) {
- PackageParser.Package p;
+ AndroidPackage p;
synchronized (mLock) {
p = mPackages.get(options.getPackageName());
if (p == null) {
@@ -9411,16 +9416,16 @@ public class PackageManagerService extends IPackageManager.Stub
public ArraySet<String> getOptimizablePackages() {
ArraySet<String> pkgs = new ArraySet<>();
synchronized (mLock) {
- for (PackageParser.Package p : mPackages.values()) {
+ for (AndroidPackage p : mPackages.values()) {
if (PackageDexOptimizer.canOptimizePackage(p)) {
- pkgs.add(p.packageName);
+ pkgs.add(p.getPackageName());
}
}
}
return pkgs;
}
- private int performDexOptInternalWithDependenciesLI(PackageParser.Package p,
+ private int performDexOptInternalWithDependenciesLI(AndroidPackage p,
DexoptOptions options) {
// Select the dex optimizer based on the force parameter.
// Note: The force option is rarely used (cmdline input for testing, mostly), so it's OK to
@@ -9437,14 +9442,15 @@ public class PackageManagerService extends IPackageManager.Stub
// and the first package that uses the library will dexopt it. The
// others will see that the compiled code for the library is up to date.
Collection<SharedLibraryInfo> deps = findSharedLibraries(p);
- final String[] instructionSets = getAppDexInstructionSets(p.applicationInfo);
+ final String[] instructionSets = getAppDexInstructionSets(p.getPrimaryCpuAbi(),
+ p.getSecondaryCpuAbi());
if (!deps.isEmpty()) {
DexoptOptions libraryOptions = new DexoptOptions(options.getPackageName(),
options.getCompilationReason(), options.getCompilerFilter(),
options.getSplitName(),
options.getFlags() | DexoptOptions.DEXOPT_AS_SHARED_LIBRARY);
for (SharedLibraryInfo info : deps) {
- PackageParser.Package depPackage = null;
+ AndroidPackage depPackage = null;
synchronized (mLock) {
depPackage = mPackages.get(info.getPackageName());
}
@@ -9452,7 +9458,7 @@ public class PackageManagerService extends IPackageManager.Stub
// TODO: Analyze and investigate if we (should) profile libraries.
pdo.performDexOpt(depPackage, instructionSets,
getOrCreateCompilerPackageStats(depPackage),
- mDexManager.getPackageUseInfoOrDefault(depPackage.packageName),
+ mDexManager.getPackageUseInfoOrDefault(depPackage.getPackageName()),
libraryOptions);
} else {
// TODO(ngeoffray): Support dexopting system shared libraries.
@@ -9461,7 +9467,7 @@ public class PackageManagerService extends IPackageManager.Stub
}
return pdo.performDexOpt(p, instructionSets,
getOrCreateCompilerPackageStats(p),
- mDexManager.getPackageUseInfoOrDefault(p.packageName), options);
+ mDexManager.getPackageUseInfoOrDefault(p.getPackageName()), options);
}
/**
@@ -9502,11 +9508,11 @@ public class PackageManagerService extends IPackageManager.Stub
}
}
- private static List<SharedLibraryInfo> findSharedLibraries(PackageParser.Package p) {
- if (p.usesLibraryInfos != null) {
+ private static List<SharedLibraryInfo> findSharedLibraries(AndroidPackage p) {
+ if (p.getUsesLibraryInfos() != null) {
ArrayList<SharedLibraryInfo> retValue = new ArrayList<>();
Set<String> collectedNames = new HashSet<>();
- for (SharedLibraryInfo info : p.usesLibraryInfos) {
+ for (SharedLibraryInfo info : p.getUsesLibraryInfos()) {
findSharedLibrariesRecursive(info, retValue, collectedNames);
}
return retValue;
@@ -9529,13 +9535,13 @@ public class PackageManagerService extends IPackageManager.Stub
}
}
- List<PackageParser.Package> findSharedNonSystemLibraries(PackageParser.Package pkg) {
+ List<AndroidPackage> findSharedNonSystemLibraries(AndroidPackage pkg) {
List<SharedLibraryInfo> deps = findSharedLibraries(pkg);
if (!deps.isEmpty()) {
- ArrayList<PackageParser.Package> retValue = new ArrayList<>();
+ ArrayList<AndroidPackage> retValue = new ArrayList<>();
synchronized (mLock) {
for (SharedLibraryInfo info : deps) {
- PackageParser.Package depPackage = mPackages.get(info.getPackageName());
+ AndroidPackage depPackage = mPackages.get(info.getPackageName());
if (depPackage != null) {
retValue.add(depPackage);
}
@@ -9573,9 +9579,9 @@ public class PackageManagerService extends IPackageManager.Stub
return versionedLib.get(version);
}
- private SharedLibraryInfo getLatestSharedLibraVersionLPr(PackageParser.Package pkg) {
+ private SharedLibraryInfo getLatestSharedLibraVersionLPr(AndroidPackage pkg) {
LongSparseArray<SharedLibraryInfo> versionedLib = mSharedLibraries.get(
- pkg.staticSharedLibName);
+ pkg.getStaticSharedLibName());
if (versionedLib == null) {
return null;
}
@@ -9583,7 +9589,7 @@ public class PackageManagerService extends IPackageManager.Stub
final int versionCount = versionedLib.size();
for (int i = 0; i < versionCount; i++) {
final long libVersion = versionedLib.keyAt(i);
- if (libVersion < pkg.staticSharedLibVersion) {
+ if (libVersion < pkg.getStaticSharedLibVersion()) {
previousLibVersion = Math.max(previousLibVersion, libVersion);
}
}
@@ -9599,7 +9605,7 @@ public class PackageManagerService extends IPackageManager.Stub
PackageSetting sharedLibPackage = null;
synchronized (mLock) {
final SharedLibraryInfo latestSharedLibraVersionLPr =
- getLatestSharedLibraVersionLPr(scanResult.pkgSetting.pkg);
+ getLatestSharedLibraVersionLPr(scanResult.request.parsedPackage);
if (latestSharedLibraVersionLPr != null) {
sharedLibPackage = mSettings.getPackageLPr(
latestSharedLibraVersionLPr.getPackageName());
@@ -9628,7 +9634,7 @@ public class PackageManagerService extends IPackageManager.Stub
@Override
public void dumpProfiles(String packageName) {
- PackageParser.Package pkg;
+ AndroidPackage pkg;
synchronized (mLock) {
pkg = mPackages.get(packageName);
if (pkg == null) {
@@ -9639,7 +9645,7 @@ public class PackageManagerService extends IPackageManager.Stub
int callingUid = Binder.getCallingUid();
if (callingUid != Process.SHELL_UID &&
callingUid != Process.ROOT_UID &&
- callingUid != pkg.applicationInfo.uid) {
+ callingUid != pkg.getUid()) {
throw new SecurityException("dumpProfiles");
}
@@ -9654,7 +9660,7 @@ public class PackageManagerService extends IPackageManager.Stub
public void forceDexOpt(String packageName) {
enforceSystemOrRoot("forceDexOpt");
- PackageParser.Package pkg;
+ AndroidPackage pkg;
synchronized (mLock) {
pkg = mPackages.get(packageName);
if (pkg == null) {
@@ -9681,15 +9687,15 @@ public class PackageManagerService extends IPackageManager.Stub
}
@GuardedBy("mLock")
- private boolean verifyPackageUpdateLPr(PackageSetting oldPkg, PackageParser.Package newPkg) {
+ private boolean verifyPackageUpdateLPr(PackageSetting oldPkg, AndroidPackage newPkg) {
if ((oldPkg.pkgFlags&ApplicationInfo.FLAG_SYSTEM) == 0) {
Slog.w(TAG, "Unable to update from " + oldPkg.name
- + " to " + newPkg.packageName
+ + " to " + newPkg.getPackageName()
+ ": old package not in system partition");
return false;
} else if (mPackages.get(oldPkg.name) != null) {
Slog.w(TAG, "Unable to update from " + oldPkg.name
- + " to " + newPkg.packageName
+ + " to " + newPkg.getPackageName()
+ ": old package still exists");
return false;
}
@@ -9713,122 +9719,86 @@ public class PackageManagerService extends IPackageManager.Stub
return (userId == UserHandle.USER_ALL) ? mUserManager.getUserIds() : new int[] { userId };
}
- private void clearAppDataLIF(PackageParser.Package pkg, int userId, int flags) {
+ private void clearAppDataLIF(AndroidPackage pkg, int userId, int flags) {
if (pkg == null) {
Slog.wtf(TAG, "Package was null!", new Throwable());
return;
}
clearAppDataLeafLIF(pkg, userId, flags);
- final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
- for (int i = 0; i < childCount; i++) {
- clearAppDataLeafLIF(pkg.childPackages.get(i), userId, flags);
- }
if ((flags & Installer.FLAG_CLEAR_APP_DATA_KEEP_ART_PROFILES) == 0) {
clearAppProfilesLIF(pkg, UserHandle.USER_ALL);
}
}
- private void clearAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) {
+ private void clearAppDataLeafLIF(AndroidPackage pkg, int userId, int flags) {
final PackageSetting ps;
synchronized (mLock) {
- ps = mSettings.mPackages.get(pkg.packageName);
+ ps = mSettings.mPackages.get(pkg.getPackageName());
}
for (int realUserId : resolveUserIds(userId)) {
final long ceDataInode = (ps != null) ? ps.getCeDataInode(realUserId) : 0;
try {
- mInstaller.clearAppData(pkg.volumeUuid, pkg.packageName, realUserId, flags,
- ceDataInode);
+ mInstaller.clearAppData(pkg.getVolumeUuid(), pkg.getPackageName(), realUserId,
+ flags, ceDataInode);
} catch (InstallerException e) {
Slog.w(TAG, String.valueOf(e));
}
}
}
- private void destroyAppDataLIF(PackageParser.Package pkg, int userId, int flags) {
+ private void destroyAppDataLIF(AndroidPackage pkg, int userId, int flags) {
if (pkg == null) {
Slog.wtf(TAG, "Package was null!", new Throwable());
return;
}
destroyAppDataLeafLIF(pkg, userId, flags);
- final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
- for (int i = 0; i < childCount; i++) {
- destroyAppDataLeafLIF(pkg.childPackages.get(i), userId, flags);
- }
}
- private void destroyAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) {
+ private void destroyAppDataLeafLIF(AndroidPackage pkg, int userId, int flags) {
final PackageSetting ps;
synchronized (mLock) {
- ps = mSettings.mPackages.get(pkg.packageName);
+ ps = mSettings.mPackages.get(pkg.getPackageName());
}
for (int realUserId : resolveUserIds(userId)) {
final long ceDataInode = (ps != null) ? ps.getCeDataInode(realUserId) : 0;
try {
- mInstaller.destroyAppData(pkg.volumeUuid, pkg.packageName, realUserId, flags,
- ceDataInode);
+ mInstaller.destroyAppData(pkg.getVolumeUuid(), pkg.getPackageName(), realUserId,
+ flags, ceDataInode);
} catch (InstallerException e) {
Slog.w(TAG, String.valueOf(e));
}
- mDexManager.notifyPackageDataDestroyed(pkg.packageName, userId);
+ mDexManager.notifyPackageDataDestroyed(pkg.getPackageName(), userId);
}
}
- private void destroyAppProfilesLIF(PackageParser.Package pkg) {
+ private void destroyAppProfilesLIF(AndroidPackage pkg) {
if (pkg == null) {
Slog.wtf(TAG, "Package was null!", new Throwable());
return;
}
destroyAppProfilesLeafLIF(pkg);
- final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
- for (int i = 0; i < childCount; i++) {
- destroyAppProfilesLeafLIF(pkg.childPackages.get(i));
- }
}
- private void destroyAppProfilesLeafLIF(PackageParser.Package pkg) {
+ private void destroyAppProfilesLeafLIF(AndroidPackage pkg) {
try {
- mInstaller.destroyAppProfiles(pkg.packageName);
+ mInstaller.destroyAppProfiles(pkg.getPackageName());
} catch (InstallerException e) {
Slog.w(TAG, String.valueOf(e));
}
}
- private void clearAppProfilesLIF(PackageParser.Package pkg, int userId) {
+ private void clearAppProfilesLIF(AndroidPackage pkg, int userId) {
if (pkg == null) {
Slog.wtf(TAG, "Package was null!", new Throwable());
return;
}
mArtManagerService.clearAppProfiles(pkg);
- final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
- for (int i = 0; i < childCount; i++) {
- mArtManagerService.clearAppProfiles(pkg.childPackages.get(i));
- }
- }
-
- private void setInstallAndUpdateTime(PackageParser.Package pkg, long firstInstallTime,
- long lastUpdateTime) {
- // Set parent install/update time
- PackageSetting ps = (PackageSetting) pkg.mExtras;
- if (ps != null) {
- ps.firstInstallTime = firstInstallTime;
- ps.lastUpdateTime = lastUpdateTime;
- }
- // Set children install/update time
- final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
- for (int i = 0; i < childCount; i++) {
- PackageParser.Package childPkg = pkg.childPackages.get(i);
- ps = (PackageSetting) childPkg.mExtras;
- if (ps != null) {
- ps.firstInstallTime = firstInstallTime;
- ps.lastUpdateTime = lastUpdateTime;
- }
- }
}
@GuardedBy("mLock")
private void applyDefiningSharedLibraryUpdateLocked(
- PackageParser.Package pkg, SharedLibraryInfo libInfo,
+ AndroidPackage pkg, SharedLibraryInfo libInfo,
BiConsumer<SharedLibraryInfo, SharedLibraryInfo> action) {
// Note that libraries defined by this package may be null if:
// - Package manager was unable to create the shared library. The package still
@@ -9837,14 +9807,14 @@ public class PackageManagerService extends IPackageManager.Stub
// - Package manager is in a state where package isn't scanned yet. This will
// get called again after scanning to fix the dependencies.
if (pkg.isLibrary()) {
- if (pkg.staticSharedLibName != null) {
+ if (pkg.getStaticSharedLibName() != null) {
SharedLibraryInfo definedLibrary = getSharedLibraryInfoLPr(
- pkg.staticSharedLibName, pkg.staticSharedLibVersion);
+ pkg.getStaticSharedLibName(), pkg.getStaticSharedLibVersion());
if (definedLibrary != null) {
action.accept(definedLibrary, libInfo);
}
} else {
- for (String libraryName : pkg.libraryNames) {
+ for (String libraryName : pkg.getLibraryNames()) {
SharedLibraryInfo definedLibrary = getSharedLibraryInfoLPr(
libraryName, SharedLibraryInfo.VERSION_UNDEFINED);
if (definedLibrary != null) {
@@ -9856,19 +9826,19 @@ public class PackageManagerService extends IPackageManager.Stub
}
@GuardedBy("mLock")
- private void addSharedLibraryLPr(PackageParser.Package pkg, Set<String> usesLibraryFiles,
- SharedLibraryInfo libInfo, PackageParser.Package changingLib) {
+ private void addSharedLibraryLPr(AndroidPackage pkg, Set<String> usesLibraryFiles,
+ SharedLibraryInfo libInfo, AndroidPackage changingLib) {
if (libInfo.getPath() != null) {
usesLibraryFiles.add(libInfo.getPath());
return;
}
- PackageParser.Package p = mPackages.get(libInfo.getPackageName());
- if (changingLib != null && changingLib.packageName.equals(libInfo.getPackageName())) {
+ AndroidPackage p = mPackages.get(libInfo.getPackageName());
+ if (changingLib != null && changingLib.getPackageName().equals(libInfo.getPackageName())) {
// If we are doing this while in the middle of updating a library apk,
// then we need to make sure to use that new apk for determining the
// dependencies here. (We haven't yet finished committing the new apk
// to the package manager state.)
- if (p == null || p.packageName.equals(changingLib.packageName)) {
+ if (p == null || p.getPackageName().equals(changingLib.getPackageName())) {
p = changingLib;
}
}
@@ -9878,23 +9848,23 @@ public class PackageManagerService extends IPackageManager.Stub
applyDefiningSharedLibraryUpdateLocked(pkg, libInfo, (definingLibrary, dependency) -> {
definingLibrary.addDependency(dependency);
});
- if (p.usesLibraryFiles != null) {
- Collections.addAll(usesLibraryFiles, p.usesLibraryFiles);
+ if (p.getUsesLibraryFiles() != null) {
+ Collections.addAll(usesLibraryFiles, p.getUsesLibraryFiles());
}
}
}
@GuardedBy("mLock")
- private void updateSharedLibrariesLocked(PackageParser.Package pkg,
- PackageParser.Package changingLib, Map<String, PackageParser.Package> availablePackages)
+ private void updateSharedLibrariesLocked(AndroidPackage pkg,
+ AndroidPackage changingLib, Map<String, AndroidPackage> availablePackages)
throws PackageManagerException {
final ArrayList<SharedLibraryInfo> sharedLibraryInfos =
collectSharedLibraryInfos(pkg, availablePackages, mSharedLibraries, null);
executeSharedLibrariesUpdateLPr(pkg, changingLib, sharedLibraryInfos);
}
- private static ArrayList<SharedLibraryInfo> collectSharedLibraryInfos(PackageParser.Package pkg,
- Map<String, PackageParser.Package> availablePackages,
+ private static ArrayList<SharedLibraryInfo> collectSharedLibraryInfos(AndroidPackage pkg,
+ Map<String, AndroidPackage> availablePackages,
@NonNull final Map<String, LongSparseArray<SharedLibraryInfo>> existingLibraries,
@Nullable final Map<String, LongSparseArray<SharedLibraryInfo>> newLibraries)
throws PackageManagerException {
@@ -9905,44 +9875,45 @@ public class PackageManagerService extends IPackageManager.Stub
// that libraries are searched in the correct order) and must have no
// duplicates.
ArrayList<SharedLibraryInfo> usesLibraryInfos = null;
- if (pkg.usesLibraries != null) {
- usesLibraryInfos = collectSharedLibraryInfos(pkg.usesLibraries, null, null,
- pkg.packageName, true, pkg.applicationInfo.targetSdkVersion, null,
+ if (pkg.getUsesLibraries() != null) {
+ usesLibraryInfos = collectSharedLibraryInfos(pkg.getUsesLibraries(), null, null,
+ pkg.getPackageName(), true, pkg.getTargetSdkVersion(), null,
availablePackages, existingLibraries, newLibraries);
}
- if (pkg.usesStaticLibraries != null) {
- usesLibraryInfos = collectSharedLibraryInfos(pkg.usesStaticLibraries,
- pkg.usesStaticLibrariesVersions, pkg.usesStaticLibrariesCertDigests,
- pkg.packageName, true, pkg.applicationInfo.targetSdkVersion, usesLibraryInfos,
+ if (pkg.getUsesStaticLibraries() != null) {
+ usesLibraryInfos = collectSharedLibraryInfos(pkg.getUsesStaticLibraries(),
+ pkg.getUsesStaticLibrariesVersions(), pkg.getUsesStaticLibrariesCertDigests(),
+ pkg.getPackageName(), true, pkg.getTargetSdkVersion(), usesLibraryInfos,
availablePackages, existingLibraries, newLibraries);
}
- if (pkg.usesOptionalLibraries != null) {
- usesLibraryInfos = collectSharedLibraryInfos(pkg.usesOptionalLibraries,
- null, null, pkg.packageName, false, pkg.applicationInfo.targetSdkVersion,
+ if (pkg.getUsesOptionalLibraries() != null) {
+ usesLibraryInfos = collectSharedLibraryInfos(pkg.getUsesOptionalLibraries(),
+ null, null, pkg.getPackageName(), false, pkg.getTargetSdkVersion(),
usesLibraryInfos, availablePackages, existingLibraries, newLibraries);
}
return usesLibraryInfos;
}
- private void executeSharedLibrariesUpdateLPr(PackageParser.Package pkg,
- PackageParser.Package changingLib, ArrayList<SharedLibraryInfo> usesLibraryInfos) {
+ private void executeSharedLibrariesUpdateLPr(AndroidPackage pkg,
+ AndroidPackage changingLib, ArrayList<SharedLibraryInfo> usesLibraryInfos) {
// If the package provides libraries, clear their old dependencies.
// This method will set them up again.
applyDefiningSharedLibraryUpdateLocked(pkg, null, (definingLibrary, dependency) -> {
definingLibrary.clearDependencies();
});
if (usesLibraryInfos != null) {
- pkg.usesLibraryInfos = usesLibraryInfos;
+ pkg.mutate().setUsesLibraryInfos(usesLibraryInfos);
// Use LinkedHashSet to preserve the order of files added to
// usesLibraryFiles while eliminating duplicates.
Set<String> usesLibraryFiles = new LinkedHashSet<>();
for (SharedLibraryInfo libInfo : usesLibraryInfos) {
addSharedLibraryLPr(pkg, usesLibraryFiles, libInfo, changingLib);
}
- pkg.usesLibraryFiles = usesLibraryFiles.toArray(new String[usesLibraryFiles.size()]);
+ pkg.mutate().setUsesLibraryFiles(usesLibraryFiles.toArray(
+ new String[usesLibraryFiles.size()]));
} else {
- pkg.usesLibraryInfos = null;
- pkg.usesLibraryFiles = null;
+ pkg.mutate().setUsesLibraryInfos(null)
+ .setUsesLibraryFiles(null);
}
}
@@ -9952,7 +9923,7 @@ public class PackageManagerService extends IPackageManager.Stub
@Nullable long[] requiredVersions, @Nullable String[][] requiredCertDigests,
@NonNull String packageName, boolean required, int targetSdk,
@Nullable ArrayList<SharedLibraryInfo> outUsedLibraries,
- @NonNull final Map<String, PackageParser.Package> availablePackages,
+ @NonNull final Map<String, AndroidPackage> availablePackages,
@NonNull final Map<String, LongSparseArray<SharedLibraryInfo>> existingLibraries,
@Nullable final Map<String, LongSparseArray<SharedLibraryInfo>> newLibraries)
throws PackageManagerException {
@@ -9981,8 +9952,8 @@ public class PackageManagerService extends IPackageManager.Stub
+ " library " + libName + " version "
+ libraryInfo.getLongVersion() + "; failing!");
}
- PackageParser.Package libPkg =
- availablePackages.get(libraryInfo.getPackageName());
+ AndroidPackage pkg = availablePackages.get(libraryInfo.getPackageName());
+ SigningDetails libPkg = pkg == null ? null : pkg.getSigningDetails();
if (libPkg == null) {
throw new PackageManagerException(INSTALL_FAILED_MISSING_SHARED_LIBRARY,
"Package " + packageName + " requires unavailable static shared"
@@ -9993,9 +9964,9 @@ public class PackageManagerService extends IPackageManager.Stub
// For apps targeting O MR1 we require explicit enumeration of all certs.
final String[] libCertDigests = (targetSdk >= Build.VERSION_CODES.O_MR1)
? PackageUtils.computeSignaturesSha256Digests(
- libPkg.mSigningDetails.signatures)
+ libPkg.signatures)
: PackageUtils.computeSignaturesSha256Digests(
- new Signature[]{libPkg.mSigningDetails.signatures[0]});
+ new Signature[]{libPkg.signatures[0]});
// Take a shortcut if sizes don't match. Note that if an app doesn't
// target O we don't parse the "additional-certificate" tags similarly
@@ -10025,7 +9996,7 @@ public class PackageManagerService extends IPackageManager.Stub
// if the new one has been blessed by the old
byte[] digestBytes = HexEncoding.decode(
expectedCertDigests[0], false /* allowSingleChar */);
- if (!libPkg.mSigningDetails.hasSha256Certificate(digestBytes)) {
+ if (!libPkg.hasSha256Certificate(digestBytes)) {
throw new PackageManagerException(
INSTALL_FAILED_MISSING_SHARED_LIBRARY,
"Package " + packageName + " requires differently signed" +
@@ -10057,28 +10028,28 @@ public class PackageManagerService extends IPackageManager.Stub
}
@GuardedBy("mLock")
- private ArrayList<PackageParser.Package> updateAllSharedLibrariesLocked(
- PackageParser.Package updatedPkg,
- Map<String, PackageParser.Package> availablePackages) {
- ArrayList<PackageParser.Package> resultList = null;
+ private ArrayList<AndroidPackage> updateAllSharedLibrariesLocked(
+ AndroidPackage updatedPkg,
+ Map<String, AndroidPackage> availablePackages) {
+ ArrayList<AndroidPackage> resultList = null;
// Set of all descendants of a library; used to eliminate cycles
ArraySet<String> descendants = null;
// The current list of packages that need updating
- ArrayList<PackageParser.Package> needsUpdating = null;
+ ArrayList<AndroidPackage> needsUpdating = null;
if (updatedPkg != null) {
needsUpdating = new ArrayList<>(1);
needsUpdating.add(updatedPkg);
}
do {
- final PackageParser.Package changingPkg =
+ final AndroidPackage changingPkg =
(needsUpdating == null) ? null : needsUpdating.remove(0);
for (int i = mPackages.size() - 1; i >= 0; --i) {
- final PackageParser.Package pkg = mPackages.valueAt(i);
+ final AndroidPackage pkg = mPackages.valueAt(i);
if (changingPkg != null
- && !hasString(pkg.usesLibraries, changingPkg.libraryNames)
- && !hasString(pkg.usesOptionalLibraries, changingPkg.libraryNames)
- && !ArrayUtils.contains(pkg.usesStaticLibraries,
- changingPkg.staticSharedLibName)) {
+ && !hasString(pkg.getUsesLibraries(), changingPkg.getLibraryNames())
+ && !hasString(pkg.getUsesOptionalLibraries(), changingPkg.getLibraryNames())
+ && !ArrayUtils.contains(pkg.getUsesStaticLibraries(),
+ changingPkg.getStaticSharedLibName())) {
continue;
}
if (resultList == null) {
@@ -10090,8 +10061,8 @@ public class PackageManagerService extends IPackageManager.Stub
if (descendants == null) {
descendants = new ArraySet<>();
}
- if (!descendants.contains(pkg.packageName)) {
- descendants.add(pkg.packageName);
+ if (!descendants.contains(pkg.getPackageName())) {
+ descendants.add(pkg.getPackageName());
needsUpdating.add(pkg);
}
}
@@ -10106,8 +10077,9 @@ public class PackageManagerService extends IPackageManager.Stub
if (!pkg.isSystem() || pkg.isUpdatedSystemApp()) {
final int flags = pkg.isUpdatedSystemApp()
? PackageManager.DELETE_KEEP_DATA : 0;
- deletePackageLIF(pkg.packageName, null, true, mUserManager.getUserIds(),
- flags , null, true, null);
+ deletePackageLIF(pkg.getPackageName(), null, true,
+ mUserManager.getUserIds(), flags, null,
+ true, null);
}
Slog.e(TAG, "updateAllSharedLibrariesLPw failed: " + e.getMessage());
}
@@ -10117,43 +10089,15 @@ public class PackageManagerService extends IPackageManager.Stub
}
@GuardedBy({"mInstallLock", "mLock"})
- private List<ScanResult> scanPackageTracedLI(PackageParser.Package pkg,
+ private ScanResult scanPackageTracedLI(ParsedPackage parsedPackage,
final @ParseFlags int parseFlags, @ScanFlags int scanFlags, long currentTime,
@Nullable UserHandle user) throws PackageManagerException {
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "scanPackage");
- // If the package has children and this is the first dive in the function
- // we recursively scan the package with the SCAN_CHECK_ONLY flag set to see
- // whether all packages (parent and children) would be successfully scanned
- // before the actual scan since scanning mutates internal state and we want
- // to atomically install the package and its children.
- if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
- if (pkg.childPackages != null && pkg.childPackages.size() > 0) {
- scanFlags |= SCAN_CHECK_ONLY;
- }
- } else {
- scanFlags &= ~SCAN_CHECK_ONLY;
- }
-
- final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
- final List<ScanResult> scanResults = new ArrayList<>(1 + childCount);
try {
- // Scan the parent
- scanResults.add(scanPackageNewLI(pkg, parseFlags, scanFlags, currentTime, user));
- // Scan the children
- for (int i = 0; i < childCount; i++) {
- PackageParser.Package childPkg = pkg.childPackages.get(i);
- scanResults.add(scanPackageNewLI(childPkg, parseFlags,
- scanFlags, currentTime, user));
- }
+ return scanPackageNewLI(parsedPackage, parseFlags, scanFlags, currentTime, user);
} finally {
Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
}
-
- if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
- return scanPackageTracedLI(pkg, parseFlags, scanFlags, currentTime, user);
- }
-
- return scanResults;
}
/** The result of a package scan. */
@@ -10200,9 +10144,9 @@ public class PackageManagerService extends IPackageManager.Stub
@VisibleForTesting
static class ScanRequest {
/** The parsed package */
- @NonNull public final PackageParser.Package pkg;
+ @NonNull public final ParsedPackage parsedPackage;
/** The package this package replaces */
- @Nullable public final PackageParser.Package oldPkg;
+ @Nullable public final AndroidPackage oldPkg;
/** Shared user settings, if the package has a shared user */
@Nullable public final SharedUserSetting sharedUserSetting;
/**
@@ -10226,9 +10170,9 @@ public class PackageManagerService extends IPackageManager.Stub
/** Whether or not the platform package is being scanned */
public final boolean isPlatformPackage;
public ScanRequest(
- @NonNull PackageParser.Package pkg,
+ @NonNull ParsedPackage parsedPackage,
@Nullable SharedUserSetting sharedUserSetting,
- @Nullable PackageParser.Package oldPkg,
+ @Nullable AndroidPackage oldPkg,
@Nullable PackageSetting pkgSetting,
@Nullable PackageSetting disabledPkgSetting,
@Nullable PackageSetting originalPkgSetting,
@@ -10237,7 +10181,7 @@ public class PackageManagerService extends IPackageManager.Stub
@ScanFlags int scanFlags,
boolean isPlatformPackage,
@Nullable UserHandle user) {
- this.pkg = pkg;
+ this.parsedPackage = parsedPackage;
this.oldPkg = oldPkg;
this.pkgSetting = pkgSetting;
this.sharedUserSetting = sharedUserSetting;
@@ -10270,7 +10214,7 @@ public class PackageManagerService extends IPackageManager.Stub
*/
private @ScanFlags int adjustScanFlags(@ScanFlags int scanFlags,
PackageSetting pkgSetting, PackageSetting disabledPkgSetting, UserHandle user,
- PackageParser.Package pkg) {
+ AndroidPackage pkg) {
// TODO(patb): Do away entirely with disabledPkgSetting here. PkgSetting will always contain
// the correct isSystem value now that we don't disable system packages before scan.
@@ -10322,12 +10266,14 @@ public class PackageManagerService extends IPackageManager.Stub
&& SystemProperties.getInt("ro.vndk.version", 28) < 28;
if (((scanFlags & SCAN_AS_PRIVILEGED) == 0)
&& !pkg.isPrivileged()
- && (pkg.mSharedUserId != null)
+ && (pkg.getSharedUserId() != null)
&& !skipVendorPrivilegeScan) {
SharedUserSetting sharedUserSetting = null;
try {
- sharedUserSetting = mSettings.getSharedUserLPw(pkg.mSharedUserId, 0, 0, false);
- } catch (PackageManagerException ignore) {}
+ sharedUserSetting = mSettings.getSharedUserLPw(pkg.getSharedUserId(), 0,
+ 0, false);
+ } catch (PackageManagerException ignore) {
+ }
if (sharedUserSetting != null && sharedUserSetting.isPrivileged()) {
// Exempt SharedUsers signed with the platform key.
// TODO(b/72378145) Fix this exemption. Force signature apps
@@ -10336,7 +10282,8 @@ public class PackageManagerService extends IPackageManager.Stub
synchronized (mLock) {
PackageSetting platformPkgSetting = mSettings.mPackages.get("android");
if ((compareSignatures(platformPkgSetting.signatures.mSigningDetails.signatures,
- pkg.mSigningDetails.signatures) != PackageManager.SIGNATURE_MATCH)) {
+ pkg.getSigningDetails().signatures)
+ != PackageManager.SIGNATURE_MATCH)) {
scanFlags |= SCAN_AS_PRIVILEGED;
}
}
@@ -10351,46 +10298,50 @@ public class PackageManagerService extends IPackageManager.Stub
// method. Also, we need to solve the problem of potentially creating a new shared user
// setting. That can probably be done later and patch things up after the fact.
@GuardedBy({"mInstallLock", "mLock"})
- private ScanResult scanPackageNewLI(@NonNull PackageParser.Package pkg,
+ private ScanResult scanPackageNewLI(@NonNull ParsedPackage parsedPackage,
final @ParseFlags int parseFlags, @ScanFlags int scanFlags, long currentTime,
@Nullable UserHandle user) throws PackageManagerException {
- final String renamedPkgName = mSettings.getRenamedPackageLPr(pkg.mRealPackage);
- final String realPkgName = getRealPackageName(pkg, renamedPkgName);
+ final String renamedPkgName = mSettings.getRenamedPackageLPr(
+ parsedPackage.getRealPackage());
+ final String realPkgName = getRealPackageName(parsedPackage, renamedPkgName);
if (realPkgName != null) {
- ensurePackageRenamed(pkg, renamedPkgName);
+ ensurePackageRenamed(parsedPackage, renamedPkgName);
}
- final PackageSetting originalPkgSetting = getOriginalPackageLocked(pkg, renamedPkgName);
- final PackageSetting pkgSetting = mSettings.getPackageLPr(pkg.packageName);
+ final PackageSetting originalPkgSetting = getOriginalPackageLocked(parsedPackage,
+ renamedPkgName);
+ final PackageSetting pkgSetting = mSettings.getPackageLPr(parsedPackage.getPackageName());
final PackageSetting disabledPkgSetting =
- mSettings.getDisabledSystemPkgLPr(pkg.packageName);
+ mSettings.getDisabledSystemPkgLPr(parsedPackage.getPackageName());
- if (mTransferedPackages.contains(pkg.packageName)) {
- Slog.w(TAG, "Package " + pkg.packageName
+ if (mTransferedPackages.contains(parsedPackage.getPackageName())) {
+ Slog.w(TAG, "Package " + parsedPackage.getPackageName()
+ " was transferred to another, but its .apk remains");
}
- scanFlags = adjustScanFlags(scanFlags, pkgSetting, disabledPkgSetting, user, pkg);
+ scanFlags = adjustScanFlags(scanFlags, pkgSetting, disabledPkgSetting, user, parsedPackage);
synchronized (mLock) {
- applyPolicy(pkg, parseFlags, scanFlags, mPlatformPackage);
- assertPackageIsValid(pkg, parseFlags, scanFlags);
+ applyPolicy(parsedPackage, parseFlags, scanFlags, mPlatformPackage);
+ assertPackageIsValid(parsedPackage, parseFlags, scanFlags);
SharedUserSetting sharedUserSetting = null;
- if (pkg.mSharedUserId != null) {
+ if (parsedPackage.getSharedUserId() != null) {
// SIDE EFFECTS; may potentially allocate a new shared user
- sharedUserSetting = mSettings.getSharedUserLPw(
- pkg.mSharedUserId, 0 /*pkgFlags*/, 0 /*pkgPrivateFlags*/, true /*create*/);
+ sharedUserSetting = mSettings.getSharedUserLPw(parsedPackage.getSharedUserId(),
+ 0 /*pkgFlags*/, 0 /*pkgPrivateFlags*/, true /*create*/);
if (DEBUG_PACKAGE_SCANNING) {
if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
- Log.d(TAG, "Shared UserID " + pkg.mSharedUserId
+ Log.d(TAG, "Shared UserID " + parsedPackage.getSharedUserId()
+ " (uid=" + sharedUserSetting.userId + "):"
+ " packages=" + sharedUserSetting.packages);
}
}
- final ScanRequest request = new ScanRequest(pkg, sharedUserSetting,
+ String platformPackageName = mPlatformPackage == null
+ ? null : mPlatformPackage.getPackageName();
+ final ScanRequest request = new ScanRequest(parsedPackage, sharedUserSetting,
pkgSetting == null ? null : pkgSetting.pkg, pkgSetting, disabledPkgSetting,
originalPkgSetting, realPkgName, parseFlags, scanFlags,
- (pkg == mPlatformPackage), user);
+ Objects.equals(parsedPackage.getPackageName(), platformPackageName), user);
return scanPackageOnlyLI(request, mInjector, mFactoryTest, currentTime);
}
}
@@ -10433,11 +10384,18 @@ public class PackageManagerService extends IPackageManager.Stub
* possible and the system is not left in an inconsistent state.
*/
@GuardedBy({"mLock", "mInstallLock"})
- private void commitReconciledScanResultLocked(@NonNull ReconciledPackage reconciledPkg) {
+ private AndroidPackage commitReconciledScanResultLocked(
+ @NonNull ReconciledPackage reconciledPkg) {
final ScanResult result = reconciledPkg.scanResult;
final ScanRequest request = result.request;
- final PackageParser.Package pkg = request.pkg;
- final PackageParser.Package oldPkg = request.oldPkg;
+ // TODO(b/135203078): Move this even further away
+ ParsedPackage parsedPackage = request.parsedPackage;
+ if ("android".equals(parsedPackage.getPackageName())) {
+ // TODO(b/135203078): Move this to initial parse
+ parsedPackage.setVersionCode(mSdkVersion)
+ .setVersionCodeMajor(0);
+ }
+ final AndroidPackage oldPkg = request.oldPkg;
final @ParseFlags int parseFlags = request.parseFlags;
final @ScanFlags int scanFlags = request.scanFlags;
final PackageSetting oldPkgSetting = request.oldPkgSetting;
@@ -10454,13 +10412,11 @@ public class PackageManagerService extends IPackageManager.Stub
if (result.existingSettingCopied) {
pkgSetting = request.pkgSetting;
pkgSetting.updateFrom(result.pkgSetting);
- pkg.mExtras = pkgSetting;
} else {
pkgSetting = result.pkgSetting;
if (originalPkgSetting != null) {
- mSettings.addRenamedPackageLPw(pkg.packageName, originalPkgSetting.name);
- }
- if (originalPkgSetting != null && (scanFlags & SCAN_CHECK_ONLY) == 0) {
+ mSettings.addRenamedPackageLPw(parsedPackage.getPackageName(),
+ originalPkgSetting.name);
mTransferedPackages.add(originalPkgSetting.name);
}
}
@@ -10473,12 +10429,13 @@ public class PackageManagerService extends IPackageManager.Stub
// We need to have this here because addUserToSettingLPw() is sometimes responsible
// for creating the application ID. If we did this earlier, we would be saving the
// correct ID.
- pkg.applicationInfo.uid = pkgSetting.appId;
+ parsedPackage.setUid(pkgSetting.appId);
+ final AndroidPackage pkg = parsedPackage.hideAsFinal();
mSettings.writeUserRestrictionsLPw(pkgSetting, oldPkgSetting);
- if ((scanFlags & SCAN_CHECK_ONLY) == 0 && realPkgName != null) {
- mTransferedPackages.add(pkg.packageName);
+ if (realPkgName != null) {
+ mTransferedPackages.add(pkg.getPackageName());
}
if (reconciledPkg.collectedSharedLibraryInfos != null) {
@@ -10487,7 +10444,7 @@ public class PackageManagerService extends IPackageManager.Stub
final KeySetManagerService ksms = mSettings.mKeySetManagerService;
if (reconciledPkg.removeAppKeySetData) {
- ksms.removeAppKeySetDataLPw(pkg.packageName);
+ ksms.removeAppKeySetDataLPw(pkg.getPackageName());
}
if (reconciledPkg.sharedUserSignaturesChanged) {
pkgSetting.sharedUser.signaturesChanged = Boolean.TRUE;
@@ -10495,17 +10452,17 @@ public class PackageManagerService extends IPackageManager.Stub
}
pkgSetting.signatures.mSigningDetails = reconciledPkg.signingDetails;
- if ((scanFlags & SCAN_CHECK_ONLY) == 0 && pkg.mAdoptPermissions != null) {
+ if (pkg.getAdoptPermissions() != null) {
// This package wants to adopt ownership of permissions from
// another package.
- for (int i = pkg.mAdoptPermissions.size() - 1; i >= 0; i--) {
- final String origName = pkg.mAdoptPermissions.get(i);
+ for (int i = pkg.getAdoptPermissions().size() - 1; i >= 0; i--) {
+ final String origName = pkg.getAdoptPermissions().get(i);
final PackageSetting orig = mSettings.getPackageLPr(origName);
if (orig != null) {
if (verifyPackageUpdateLPr(orig, pkg)) {
Slog.i(TAG, "Adopting permissions from " + origName + " to "
- + pkg.packageName);
- mSettings.mPermissions.transferPermissions(origName, pkg.packageName);
+ + pkg.getPackageName());
+ mSettings.mPermissions.transferPermissions(origName, pkg.getPackageName());
}
}
}
@@ -10522,21 +10479,15 @@ public class PackageManagerService extends IPackageManager.Stub
}
}
- if ((scanFlags & SCAN_CHECK_ONLY) != 0) {
- if (oldPkgSetting != null) {
- synchronized (mLock) {
- mSettings.mPackages.put(oldPkgSetting.name, oldPkgSetting);
- }
- }
- } else {
- final int userId = user == null ? 0 : user.getIdentifier();
- // Modify state for the given package setting
- commitPackageSettings(pkg, oldPkg, pkgSetting, scanFlags,
- (parseFlags & PackageParser.PARSE_CHATTY) != 0 /*chatty*/, reconciledPkg);
- if (pkgSetting.getInstantApp(userId)) {
- mInstantAppRegistry.addInstantAppLPw(userId, pkgSetting.appId);
- }
+ final int userId = user == null ? 0 : user.getIdentifier();
+ // Modify state for the given package setting
+ commitPackageSettings(pkg, oldPkg, pkgSetting, scanFlags,
+ (parseFlags & PackageParser.PARSE_CHATTY) != 0 /*chatty*/, reconciledPkg);
+ if (pkgSetting.getInstantApp(userId)) {
+ mInstantAppRegistry.addInstantAppLPw(userId, pkgSetting.appId);
}
+
+ return pkg;
}
/**
@@ -10544,18 +10495,19 @@ public class PackageManagerService extends IPackageManager.Stub
* <p>This may differ from the package's actual name if the application has already
* been installed under one of this package's original names.
*/
- private static @Nullable String getRealPackageName(@NonNull PackageParser.Package pkg,
+ private static @Nullable String getRealPackageName(@NonNull AndroidPackage pkg,
@Nullable String renamedPkgName) {
if (isPackageRenamed(pkg, renamedPkgName)) {
- return pkg.mRealPackage;
+ return pkg.getRealPackage();
}
return null;
}
/** Returns {@code true} if the package has been renamed. Otherwise, {@code false}. */
- private static boolean isPackageRenamed(@NonNull PackageParser.Package pkg,
+ private static boolean isPackageRenamed(@NonNull AndroidPackage pkg,
@Nullable String renamedPkgName) {
- return pkg.mOriginalPackages != null && pkg.mOriginalPackages.contains(renamedPkgName);
+ return pkg.getOriginalPackages() != null
+ && pkg.getOriginalPackages().contains(renamedPkgName);
}
/**
@@ -10566,14 +10518,14 @@ public class PackageManagerService extends IPackageManager.Stub
* shared user [if any].
*/
@GuardedBy("mLock")
- private @Nullable PackageSetting getOriginalPackageLocked(@NonNull PackageParser.Package pkg,
+ private @Nullable PackageSetting getOriginalPackageLocked(@NonNull AndroidPackage pkg,
@Nullable String renamedPkgName) {
if (!isPackageRenamed(pkg, renamedPkgName)) {
return null;
}
- for (int i = pkg.mOriginalPackages.size() - 1; i >= 0; --i) {
+ for (int i = ArrayUtils.size(pkg.getOriginalPackages()) - 1; i >= 0; --i) {
final PackageSetting originalPs =
- mSettings.getPackageLPr(pkg.mOriginalPackages.get(i));
+ mSettings.getPackageLPr(pkg.getOriginalPackages().get(i));
if (originalPs != null) {
// the package is already installed under its original name...
// but, should we use it?
@@ -10581,18 +10533,18 @@ public class PackageManagerService extends IPackageManager.Stub
// the new package is incompatible with the original
continue;
} else if (originalPs.sharedUser != null) {
- if (!originalPs.sharedUser.name.equals(pkg.mSharedUserId)) {
+ if (!originalPs.sharedUser.name.equals(pkg.getSharedUserId())) {
// the shared user id is incompatible with the original
Slog.w(TAG, "Unable to migrate data from " + originalPs.name
- + " to " + pkg.packageName + ": old uid "
+ + " to " + pkg.getPackageName() + ": old uid "
+ originalPs.sharedUser.name
- + " differs from " + pkg.mSharedUserId);
+ + " differs from " + pkg.getSharedUserId());
continue;
}
// TODO: Add case when shared user id is added [b/28144775]
} else {
if (DEBUG_UPGRADE) Log.v(TAG, "Renaming new package "
- + pkg.packageName + " to old name " + originalPs.name);
+ + pkg.getPackageName() + " to old name " + originalPs.name);
}
return originalPs;
}
@@ -10605,19 +10557,19 @@ public class PackageManagerService extends IPackageManager.Stub
* <p>When we've already installed the package under an original name, update
* the new package so we can continue to have the old name.
*/
- private static void ensurePackageRenamed(@NonNull PackageParser.Package pkg,
+ private static void ensurePackageRenamed(@NonNull ParsedPackage parsedPackage,
@NonNull String renamedPackageName) {
- if (pkg.mOriginalPackages == null
- || !pkg.mOriginalPackages.contains(renamedPackageName)
- || pkg.packageName.equals(renamedPackageName)) {
+ if (parsedPackage.getOriginalPackages() == null
+ || !parsedPackage.getOriginalPackages().contains(renamedPackageName)
+ || parsedPackage.getPackageName().equals(renamedPackageName)) {
return;
}
- pkg.setPackageName(renamedPackageName);
+ parsedPackage.setPackageName(renamedPackageName);
}
/**
* Applies the adjusted ABI calculated by
- * {@link PackageAbiHelper#getAdjustedAbiForSharedUser(Set, PackageParser.Package)} to all
+ * {@link PackageAbiHelper#getAdjustedAbiForSharedUser(Set, AndroidPackage)} to all
* relevant packages and settings.
* @param sharedUserSetting The {@code SharedUserSetting} to adjust
* @param scannedPackage the package being scanned or null
@@ -10625,22 +10577,20 @@ public class PackageManagerService extends IPackageManager.Stub
* @return the list of code paths that belong to packages that had their ABIs adjusted.
*/
private static List<String> applyAdjustedAbiToSharedUser(SharedUserSetting sharedUserSetting,
- PackageParser.Package scannedPackage, String adjustedAbi) {
+ ParsedPackage scannedPackage, String adjustedAbi) {
if (scannedPackage != null) {
- scannedPackage.applicationInfo.primaryCpuAbi = adjustedAbi;
+ scannedPackage.setPrimaryCpuAbi(adjustedAbi);
}
List<String> changedAbiCodePath = null;
for (PackageSetting ps : sharedUserSetting.packages) {
- if (scannedPackage == null || !scannedPackage.packageName.equals(ps.name)) {
+ if (scannedPackage == null || !scannedPackage.getPackageName().equals(ps.name)) {
if (ps.primaryCpuAbiString != null) {
continue;
}
ps.primaryCpuAbiString = adjustedAbi;
- if (ps.pkg != null && ps.pkg.applicationInfo != null
- && !TextUtils.equals(
- adjustedAbi, ps.pkg.applicationInfo.primaryCpuAbi)) {
- ps.pkg.applicationInfo.primaryCpuAbi = adjustedAbi;
+ if (ps.pkg != null && !TextUtils.equals(adjustedAbi, ps.pkg.getPrimaryCpuAbi())) {
+ ps.pkg.mutate().setPrimaryCpuAbi(adjustedAbi);
if (DEBUG_ABI_SELECTION) {
Slog.i(TAG,
"Adjusting ABI for " + ps.name + " to " + adjustedAbi
@@ -10680,7 +10630,7 @@ public class PackageManagerService extends IPackageManager.Stub
throws PackageManagerException {
final PackageAbiHelper packageAbiHelper = injector.getAbiHelper();
final UserManagerInternal userManager = injector.getUserManagerInternal();
- final PackageParser.Package pkg = request.pkg;
+ ParsedPackage parsedPackage = request.parsedPackage;
PackageSetting pkgSetting = request.pkgSetting;
final PackageSetting disabledPkgSetting = request.disabledPkgSetting;
final PackageSetting originalPkgSetting = request.originalPkgSetting;
@@ -10695,13 +10645,12 @@ public class PackageManagerService extends IPackageManager.Stub
if (DEBUG_PACKAGE_SCANNING) {
if ((parseFlags & PackageParser.PARSE_CHATTY) != 0)
- Log.d(TAG, "Scanning package " + pkg.packageName);
+ Log.d(TAG, "Scanning package " + parsedPackage.getPackageName());
}
// Initialize package source and resource directories
- final File scanFile = new File(pkg.codePath);
- final File destCodeFile = new File(pkg.applicationInfo.getCodePath());
- final File destResourceFile = new File(pkg.applicationInfo.getResourcePath());
+ final File destCodeFile = new File(parsedPackage.getAppInfoCodePath());
+ final File destResourceFile = new File(parsedPackage.getAppInfoResourcePath());
// We keep references to the derived CPU Abis from settings in oder to reuse
// them in the case where we're not upgrading or booting for the first time.
@@ -10720,7 +10669,7 @@ public class PackageManagerService extends IPackageManager.Stub
if (pkgSetting != null && pkgSetting.sharedUser != sharedUserSetting) {
PackageManagerService.reportSettingsProblem(Log.WARN,
- "Package " + pkg.packageName + " shared user changed from "
+ "Package " + parsedPackage.getPackageName() + " shared user changed from "
+ (pkgSetting.sharedUser != null
? pkgSetting.sharedUser.name : "<nothing>")
+ " to "
@@ -10730,30 +10679,28 @@ public class PackageManagerService extends IPackageManager.Stub
}
String[] usesStaticLibraries = null;
- if (pkg.usesStaticLibraries != null) {
- usesStaticLibraries = new String[pkg.usesStaticLibraries.size()];
- pkg.usesStaticLibraries.toArray(usesStaticLibraries);
+ if (parsedPackage.getUsesStaticLibraries() != null) {
+ usesStaticLibraries = new String[parsedPackage.getUsesStaticLibraries().size()];
+ parsedPackage.getUsesStaticLibraries().toArray(usesStaticLibraries);
}
final boolean createNewPackage = (pkgSetting == null);
if (createNewPackage) {
- final String parentPackageName = (pkg.parentPackage != null)
- ? pkg.parentPackage.packageName : null;
final boolean instantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0;
final boolean virtualPreload = (scanFlags & SCAN_AS_VIRTUAL_PRELOAD) != 0;
// REMOVE SharedUserSetting from method; update in a separate call
- pkgSetting = Settings.createNewSetting(pkg.packageName, originalPkgSetting,
- disabledPkgSetting, realPkgName, sharedUserSetting, destCodeFile,
- destResourceFile, pkg.applicationInfo.nativeLibraryRootDir,
- pkg.applicationInfo.primaryCpuAbi, pkg.applicationInfo.secondaryCpuAbi,
- pkg.mVersionCode, pkg.applicationInfo.flags, pkg.applicationInfo.privateFlags,
- user, true /*allowInstall*/, instantApp, virtualPreload,
- parentPackageName, pkg.getChildPackageNames(),
- UserManagerService.getInstance(), usesStaticLibraries,
- pkg.usesStaticLibrariesVersions);
+ pkgSetting = Settings.createNewSetting(parsedPackage.getPackageName(),
+ originalPkgSetting, disabledPkgSetting, realPkgName, sharedUserSetting,
+ destCodeFile, destResourceFile, parsedPackage.getNativeLibraryRootDir(),
+ parsedPackage.getPrimaryCpuAbi(), parsedPackage.getSecondaryCpuAbi(),
+ parsedPackage.getVersionCode(), parsedPackage.getFlags(),
+ parsedPackage.getPrivateFlags(), user, true /*allowInstall*/, instantApp,
+ virtualPreload, UserManagerService.getInstance(), usesStaticLibraries,
+ parsedPackage.getUsesStaticLibrariesVersions());
} else {
// make a deep copy to avoid modifying any existing system state.
pkgSetting = new PackageSetting(pkgSetting);
- pkgSetting.pkg = pkg;
+ // TODO(b/135203078): Remove entirely. Set package directly.
+ parsedPackage.setPackageSettingCallback(pkgSetting);
// REMOVE SharedUserSetting from method; update in a separate call.
//
@@ -10761,18 +10708,18 @@ public class PackageManagerService extends IPackageManager.Stub
// secondaryCpuAbi are not known at this point so we always update them
// to null here, only to reset them at a later point.
Settings.updatePackageSetting(pkgSetting, disabledPkgSetting, sharedUserSetting,
- destCodeFile, destResourceFile, pkg.applicationInfo.nativeLibraryDir,
- pkg.applicationInfo.primaryCpuAbi, pkg.applicationInfo.secondaryCpuAbi,
- pkg.applicationInfo.flags, pkg.applicationInfo.privateFlags,
- pkg.getChildPackageNames(), UserManagerService.getInstance(),
- usesStaticLibraries, pkg.usesStaticLibrariesVersions);
+ destCodeFile, destResourceFile, parsedPackage.getNativeLibraryDir(),
+ parsedPackage.getPrimaryCpuAbi(), parsedPackage.getSecondaryCpuAbi(),
+ parsedPackage.getFlags(), parsedPackage.getPrivateFlags(),
+ UserManagerService.getInstance(),
+ usesStaticLibraries, parsedPackage.getUsesStaticLibrariesVersions());
}
if (createNewPackage && originalPkgSetting != null) {
// This is the initial transition from the original package, so,
// fix up the new package's name now. We must do this after looking
// up the package under its new name, so getPackageLP takes care of
// fiddling things correctly.
- pkg.setPackageName(originalPkgSetting.name);
+ parsedPackage.setPackageName(originalPkgSetting.name);
// File a report about this.
String msg = "New package " + pkgSetting.realName
@@ -10791,7 +10738,7 @@ public class PackageManagerService extends IPackageManager.Stub
if (disabledPkgSetting != null
|| (0 != (scanFlags & SCAN_NEW_INSTALL)
&& pkgSetting != null && pkgSetting.isSystem())) {
- pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
+ parsedPackage.mutate().setUpdatedSystemApp(true);
}
// Apps which share a sharedUserId must be placed in the same selinux domain. If this
@@ -10803,68 +10750,72 @@ public class PackageManagerService extends IPackageManager.Stub
// will NOT be modified until next boot, even if a lower targetSdkVersion is used. This
// ensures that all packages continue to run in the same selinux domain.
final int targetSdkVersion =
- ((sharedUserSetting != null) && (sharedUserSetting.packages.size() != 0)) ?
- sharedUserSetting.seInfoTargetSdkVersion : pkg.applicationInfo.targetSdkVersion;
+ ((sharedUserSetting != null) && (sharedUserSetting.packages.size() != 0)) ?
+ sharedUserSetting.seInfoTargetSdkVersion
+ : parsedPackage.getTargetSdkVersion();
// TODO(b/71593002): isPrivileged for sharedUser and appInfo should never be out of sync.
// They currently can be if the sharedUser apps are signed with the platform key.
final boolean isPrivileged = (sharedUserSetting != null) ?
- sharedUserSetting.isPrivileged() | pkg.isPrivileged() : pkg.isPrivileged();
-
- pkg.applicationInfo.seInfo = SELinuxMMAC.getSeInfo(pkg, isPrivileged,
- targetSdkVersion);
- pkg.applicationInfo.seInfoUser = SELinuxUtil.assignSeinfoUser(pkgSetting.readUserState(
- userId == UserHandle.USER_ALL ? UserHandle.USER_SYSTEM : userId));
-
- pkg.mExtras = pkgSetting;
- pkg.applicationInfo.processName = fixProcessName(
- pkg.applicationInfo.packageName,
- pkg.applicationInfo.processName);
+ sharedUserSetting.isPrivileged() | parsedPackage.isPrivileged()
+ : parsedPackage.isPrivileged();
+
+ parsedPackage.setSeInfo(
+ SELinuxMMAC.getSeInfo(parsedPackage, isPrivileged, targetSdkVersion))
+ .setSeInfoUser(
+ SELinuxUtil.assignSeinfoUser(pkgSetting.readUserState(
+ userId == UserHandle.USER_ALL ? UserHandle.USER_SYSTEM : userId)))
+ .setProcessName(fixProcessName(
+ parsedPackage.getPackageName(),
+ parsedPackage.getProcessName()));
if (!isPlatformPackage) {
// Get all of our default paths setup
- pkg.applicationInfo.initForUser(UserHandle.USER_SYSTEM);
+ parsedPackage.initForUser(UserHandle.USER_SYSTEM);
}
- final String cpuAbiOverride = deriveAbiOverride(pkg.cpuAbiOverride, pkgSetting);
+ final String cpuAbiOverride = deriveAbiOverride(parsedPackage.getCpuAbiOverride(),
+ pkgSetting);
if ((scanFlags & SCAN_NEW_INSTALL) == 0) {
if (needToDeriveAbi) {
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "derivePackageAbi");
- final boolean extractNativeLibs = !pkg.isLibrary();
+ final boolean extractNativeLibs = !parsedPackage.isLibrary();
final Pair<PackageAbiHelper.Abis, PackageAbiHelper.NativeLibraryPaths> derivedAbi =
- packageAbiHelper.derivePackageAbi(pkg, cpuAbiOverride, extractNativeLibs);
- derivedAbi.first.applyTo(pkg);
- derivedAbi.second.applyTo(pkg);
+ packageAbiHelper.derivePackageAbi(parsedPackage, cpuAbiOverride,
+ extractNativeLibs);
+ derivedAbi.first.applyTo(parsedPackage);
+ derivedAbi.second.applyTo(parsedPackage);
Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
// Some system apps still use directory structure for native libraries
// in which case we might end up not detecting abi solely based on apk
// structure. Try to detect abi based on directory structure.
- if (isSystemApp(pkg) && !pkg.isUpdatedSystemApp() &&
- pkg.applicationInfo.primaryCpuAbi == null) {
+ if (isSystemApp(parsedPackage) && !parsedPackage.isUpdatedSystemApp() &&
+ parsedPackage.getPrimaryCpuAbi() == null) {
final PackageAbiHelper.Abis abis = packageAbiHelper.getBundledAppAbis(
- pkg);
- abis.applyTo(pkg);
+ parsedPackage);
+ abis.applyTo(parsedPackage);
abis.applyTo(pkgSetting);
final PackageAbiHelper.NativeLibraryPaths nativeLibraryPaths =
- packageAbiHelper.getNativeLibraryPaths(pkg, sAppLib32InstallDir);
- nativeLibraryPaths.applyTo(pkg);
+ packageAbiHelper.getNativeLibraryPaths(parsedPackage,
+ sAppLib32InstallDir);
+ nativeLibraryPaths.applyTo(parsedPackage);
}
} else {
// This is not a first boot or an upgrade, don't bother deriving the
// ABI during the scan. Instead, trust the value that was stored in the
// package setting.
- pkg.applicationInfo.primaryCpuAbi = primaryCpuAbiFromSettings;
- pkg.applicationInfo.secondaryCpuAbi = secondaryCpuAbiFromSettings;
+ parsedPackage.setPrimaryCpuAbi(primaryCpuAbiFromSettings)
+ .setSecondaryCpuAbi(secondaryCpuAbiFromSettings);
final PackageAbiHelper.NativeLibraryPaths nativeLibraryPaths =
- packageAbiHelper.getNativeLibraryPaths(pkg, sAppLib32InstallDir);
- nativeLibraryPaths.applyTo(pkg);
+ packageAbiHelper.getNativeLibraryPaths(parsedPackage, sAppLib32InstallDir);
+ nativeLibraryPaths.applyTo(parsedPackage);
if (DEBUG_ABI_SELECTION) {
Slog.i(TAG, "Using ABIS and native lib paths from settings : " +
- pkg.packageName + " " + pkg.applicationInfo.primaryCpuAbi + ", " +
- pkg.applicationInfo.secondaryCpuAbi);
+ parsedPackage.getPackageName() + " " + parsedPackage.getPrimaryCpuAbi()
+ + ", " + parsedPackage.getSecondaryCpuAbi());
}
}
} else {
@@ -10872,8 +10823,8 @@ public class PackageManagerService extends IPackageManager.Stub
// We haven't run dex-opt for this move (since we've moved the compiled output too)
// but we already have this packages package info in the PackageSetting. We just
// use that and derive the native library path based on the new codepath.
- pkg.applicationInfo.primaryCpuAbi = pkgSetting.primaryCpuAbiString;
- pkg.applicationInfo.secondaryCpuAbi = pkgSetting.secondaryCpuAbiString;
+ parsedPackage.setPrimaryCpuAbi(pkgSetting.primaryCpuAbiString)
+ .setSecondaryCpuAbi(pkgSetting.secondaryCpuAbiString);
}
// Set native library paths again. For moves, the path will be updated based on the
@@ -10881,8 +10832,8 @@ public class PackageManagerService extends IPackageManager.Stub
// ABIs we determined during compilation, but the path will depend on the final
// package path (after the rename away from the stage path).
final PackageAbiHelper.NativeLibraryPaths nativeLibraryPaths =
- packageAbiHelper.getNativeLibraryPaths(pkg, sAppLib32InstallDir);
- nativeLibraryPaths.applyTo(pkg);
+ packageAbiHelper.getNativeLibraryPaths(parsedPackage, sAppLib32InstallDir);
+ nativeLibraryPaths.applyTo(parsedPackage);
}
// This is a special case for the "system" package, where the ABI is
@@ -10890,8 +10841,8 @@ public class PackageManagerService extends IPackageManager.Stub
// of this ABI so that we can deal with "normal" applications that run under
// the same UID correctly.
if (isPlatformPackage) {
- pkg.applicationInfo.primaryCpuAbi = VMRuntime.getRuntime().is64Bit() ?
- Build.SUPPORTED_64_BIT_ABIS[0] : Build.SUPPORTED_32_BIT_ABIS[0];
+ parsedPackage.setPrimaryCpuAbi(VMRuntime.getRuntime().is64Bit() ?
+ Build.SUPPORTED_64_BIT_ABIS[0] : Build.SUPPORTED_32_BIT_ABIS[0]);
}
// If there's a mismatch between the abi-override in the package setting
@@ -10899,34 +10850,34 @@ public class PackageManagerService extends IPackageManager.Stub
// would've already compiled the app without taking the package setting into
// account.
if ((scanFlags & SCAN_NO_DEX) == 0 && (scanFlags & SCAN_NEW_INSTALL) != 0) {
- if (cpuAbiOverride == null && pkg.packageName != null) {
+ if (cpuAbiOverride == null && parsedPackage.getPackageName() != null) {
Slog.w(TAG, "Ignoring persisted ABI override " + cpuAbiOverride +
- " for package " + pkg.packageName);
+ " for package " + parsedPackage.getPackageName());
}
}
- pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi;
- pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi;
+ pkgSetting.primaryCpuAbiString = parsedPackage.getPrimaryCpuAbi();
+ pkgSetting.secondaryCpuAbiString = parsedPackage.getSecondaryCpuAbi();
pkgSetting.cpuAbiOverrideString = cpuAbiOverride;
// Copy the derived override back to the parsed package, so that we can
// update the package settings accordingly.
- pkg.cpuAbiOverride = cpuAbiOverride;
+ parsedPackage.setCpuAbiOverride(cpuAbiOverride);
if (DEBUG_ABI_SELECTION) {
- Slog.d(TAG, "Resolved nativeLibraryRoot for " + pkg.packageName
- + " to root=" + pkg.applicationInfo.nativeLibraryRootDir + ", isa="
- + pkg.applicationInfo.nativeLibraryRootRequiresIsa);
+ Slog.d(TAG, "Resolved nativeLibraryRoot for " + parsedPackage.getPackageName()
+ + " to root=" + parsedPackage.getNativeLibraryRootDir() + ", isa="
+ + parsedPackage.isNativeLibraryRootRequiresIsa());
}
// Push the derived path down into PackageSettings so we know what to
// clean up at uninstall time.
- pkgSetting.legacyNativeLibraryPathString = pkg.applicationInfo.nativeLibraryRootDir;
+ pkgSetting.legacyNativeLibraryPathString = parsedPackage.getNativeLibraryRootDir();
if (DEBUG_ABI_SELECTION) {
- Log.d(TAG, "Abis for package[" + pkg.packageName + "] are" +
- " primary=" + pkg.applicationInfo.primaryCpuAbi +
- " secondary=" + pkg.applicationInfo.secondaryCpuAbi);
+ Log.d(TAG, "Abis for package[" + parsedPackage.getPackageName() + "] are" +
+ " primary=" + parsedPackage.getPrimaryCpuAbi() +
+ " secondary=" + parsedPackage.getSecondaryCpuAbi());
}
if ((scanFlags & SCAN_BOOTING) == 0 && pkgSetting.sharedUser != null) {
@@ -10936,22 +10887,20 @@ public class PackageManagerService extends IPackageManager.Stub
// We also do this *before* we perform dexopt on this package, so that
// we can avoid redundant dexopts, and also to make sure we've got the
// code and package path correct.
- changedAbiCodePath = applyAdjustedAbiToSharedUser(pkgSetting.sharedUser, pkg,
+ changedAbiCodePath = applyAdjustedAbiToSharedUser(pkgSetting.sharedUser, parsedPackage,
packageAbiHelper.getAdjustedAbiForSharedUser(
- pkgSetting.sharedUser.packages, pkg));
+ pkgSetting.sharedUser.packages, parsedPackage));
}
- if (isUnderFactoryTest && pkg.requestedPermissions.contains(
- android.Manifest.permission.FACTORY_TEST)) {
- pkg.applicationInfo.flags |= ApplicationInfo.FLAG_FACTORY_TEST;
- }
+ parsedPackage.setFactoryTest(isUnderFactoryTest && parsedPackage.getRequestedPermissions()
+ .contains(android.Manifest.permission.FACTORY_TEST));
- if (isSystemApp(pkg)) {
+ if (isSystemApp(parsedPackage)) {
pkgSetting.isOrphaned = true;
}
// Take care of first install / last update times.
- final long scanFileTime = getLastModifiedTime(pkg);
+ final long scanFileTime = getLastModifiedTime(parsedPackage);
if (currentTime != 0) {
if (pkgSetting.firstInstallTime == 0) {
pkgSetting.firstInstallTime = pkgSetting.lastUpdateTime = currentTime;
@@ -10969,32 +10918,33 @@ public class PackageManagerService extends IPackageManager.Stub
}
}
pkgSetting.setTimeStamp(scanFileTime);
-
- pkgSetting.pkg = pkg;
- pkgSetting.pkgFlags = pkg.applicationInfo.flags;
- if (pkg.getLongVersionCode() != pkgSetting.versionCode) {
- pkgSetting.versionCode = pkg.getLongVersionCode();
+ // TODO(b/135203078): Remove, move to constructor
+ parsedPackage.setPackageSettingCallback(pkgSetting);
+ pkgSetting.pkgFlags = parsedPackage.getFlags();
+ if (parsedPackage.getLongVersionCode() != pkgSetting.versionCode) {
+ pkgSetting.versionCode = parsedPackage.getLongVersionCode();
}
// Update volume if needed
- final String volumeUuid = pkg.applicationInfo.volumeUuid;
+ final String volumeUuid = parsedPackage.getApplicationInfoVolumeUuid();
if (!Objects.equals(volumeUuid, pkgSetting.volumeUuid)) {
Slog.i(PackageManagerService.TAG,
"Update" + (pkgSetting.isSystem() ? " system" : "")
- + " package " + pkg.packageName
+ + " package " + parsedPackage.getPackageName()
+ " volume from " + pkgSetting.volumeUuid
+ " to " + volumeUuid);
pkgSetting.volumeUuid = volumeUuid;
}
SharedLibraryInfo staticSharedLibraryInfo = null;
- if (!TextUtils.isEmpty(pkg.staticSharedLibName)) {
- staticSharedLibraryInfo = SharedLibraryInfo.createForStatic(pkg);
+ if (!TextUtils.isEmpty(parsedPackage.getStaticSharedLibName())) {
+ staticSharedLibraryInfo = SharedLibraryInfo.createForStatic(parsedPackage);
}
List<SharedLibraryInfo> dynamicSharedLibraryInfos = null;
- if (!ArrayUtils.isEmpty(pkg.libraryNames)) {
- dynamicSharedLibraryInfos = new ArrayList<>(pkg.libraryNames.size());
- for (String name : pkg.libraryNames) {
- dynamicSharedLibraryInfos.add(SharedLibraryInfo.createForDynamic(pkg, name));
+ if (!ArrayUtils.isEmpty(parsedPackage.getLibraryNames())) {
+ dynamicSharedLibraryInfos = new ArrayList<>(parsedPackage.getLibraryNames().size());
+ for (String name : parsedPackage.getLibraryNames()) {
+ dynamicSharedLibraryInfos.add(
+ SharedLibraryInfo.createForDynamic(parsedPackage, name));
}
}
@@ -11030,22 +10980,21 @@ public class PackageManagerService extends IPackageManager.Stub
*
* @throws PackageManagerException If bytecode could not be found when it should exist
*/
- private static void assertCodePolicy(PackageParser.Package pkg)
+ private static void assertCodePolicy(AndroidPackage pkg)
throws PackageManagerException {
- final boolean shouldHaveCode =
- (pkg.applicationInfo.flags & ApplicationInfo.FLAG_HAS_CODE) != 0;
- if (shouldHaveCode && !apkHasCode(pkg.baseCodePath)) {
+ final boolean shouldHaveCode = (pkg.getFlags() & ApplicationInfo.FLAG_HAS_CODE) != 0;
+ if (shouldHaveCode && !apkHasCode(pkg.getBaseCodePath())) {
throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
- "Package " + pkg.baseCodePath + " code is missing");
+ "Package " + pkg.getBaseCodePath() + " code is missing");
}
- if (!ArrayUtils.isEmpty(pkg.splitCodePaths)) {
- for (int i = 0; i < pkg.splitCodePaths.length; i++) {
+ if (!ArrayUtils.isEmpty(pkg.getSplitCodePaths())) {
+ for (int i = 0; i < pkg.getSplitCodePaths().length; i++) {
final boolean splitShouldHaveCode =
- (pkg.splitFlags[i] & ApplicationInfo.FLAG_HAS_CODE) != 0;
- if (splitShouldHaveCode && !apkHasCode(pkg.splitCodePaths[i])) {
+ (pkg.getSplitFlags()[i] & ApplicationInfo.FLAG_HAS_CODE) != 0;
+ if (splitShouldHaveCode && !apkHasCode(pkg.getSplitCodePaths()[i])) {
throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
- "Package " + pkg.splitCodePaths[i] + " code is missing");
+ "Package " + pkg.getSplitCodePaths()[i] + " code is missing");
}
}
}
@@ -11058,118 +11007,59 @@ public class PackageManagerService extends IPackageManager.Stub
* Implementation detail: This method must NOT have any side effect. It would
* ideally be static, but, it requires locks to read system state.
*/
- private static void applyPolicy(PackageParser.Package pkg, final @ParseFlags int parseFlags,
- final @ScanFlags int scanFlags, PackageParser.Package platformPkg) {
+ private static void applyPolicy(ParsedPackage parsedPackage, final @ParseFlags int parseFlags,
+ final @ScanFlags int scanFlags, AndroidPackage platformPkg) {
if ((scanFlags & SCAN_AS_SYSTEM) != 0) {
- pkg.applicationInfo.flags |= ApplicationInfo.FLAG_SYSTEM;
- if (pkg.applicationInfo.isDirectBootAware()) {
- // we're direct boot aware; set for all components
- for (PackageParser.Service s : pkg.services) {
- s.info.directBootAware = true;
- }
- for (PackageParser.Provider p : pkg.providers) {
- p.info.directBootAware = true;
- }
- for (PackageParser.Activity a : pkg.activities) {
- a.info.directBootAware = true;
- }
- for (PackageParser.Activity r : pkg.receivers) {
- r.info.directBootAware = true;
- }
+ parsedPackage.setSystem(true);
+ // TODO(b/135203078): Can this be done in PackageParser? Or just inferred when the flag
+ // is set during parse.
+ if (parsedPackage.isDirectBootAware()) {
+ parsedPackage.setAllComponentsDirectBootAware(true);
}
- if (compressedFileExists(pkg.codePath)) {
- pkg.isStub = true;
+ if (compressedFileExists(parsedPackage.getCodePath())) {
+ parsedPackage.setIsStub(true);
}
} else {
- // non system apps can't be flagged as core
- pkg.coreApp = false;
- // clear flags not applicable to regular apps
- pkg.applicationInfo.flags &=
- ~ApplicationInfo.FLAG_PERSISTENT;
- pkg.applicationInfo.privateFlags &=
- ~ApplicationInfo.PRIVATE_FLAG_DEFAULT_TO_DEVICE_PROTECTED_STORAGE;
- pkg.applicationInfo.privateFlags &=
- ~ApplicationInfo.PRIVATE_FLAG_DIRECT_BOOT_AWARE;
- // cap permission priorities
- if (pkg.permissionGroups != null && pkg.permissionGroups.size() > 0) {
- for (int i = pkg.permissionGroups.size() - 1; i >= 0; --i) {
- pkg.permissionGroups.get(i).info.priority = 0;
- }
- }
+ parsedPackage
+ // non system apps can't be flagged as core
+ .setCoreApp(false)
+ // clear flags not applicable to regular apps
+ .setPersistent(false)
+ .setDefaultToDeviceProtectedStorage(false)
+ .setDirectBootAware(false)
+ // non system apps can't have permission priority
+ .capPermissionPriorities();
}
if ((scanFlags & SCAN_AS_PRIVILEGED) == 0) {
- // clear protected broadcasts
- pkg.protectedBroadcasts = null;
- // ignore export request for single user receivers
- if (pkg.receivers != null) {
- for (int i = pkg.receivers.size() - 1; i >= 0; --i) {
- final PackageParser.Activity receiver = pkg.receivers.get(i);
- if ((receiver.info.flags & ActivityInfo.FLAG_SINGLE_USER) != 0) {
- receiver.info.exported = false;
- }
- }
- }
- // ignore export request for single user services
- if (pkg.services != null) {
- for (int i = pkg.services.size() - 1; i >= 0; --i) {
- final PackageParser.Service service = pkg.services.get(i);
- if ((service.info.flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
- service.info.exported = false;
- }
- }
- }
- // ignore export request for single user providers
- if (pkg.providers != null) {
- for (int i = pkg.providers.size() - 1; i >= 0; --i) {
- final PackageParser.Provider provider = pkg.providers.get(i);
- if ((provider.info.flags & ProviderInfo.FLAG_SINGLE_USER) != 0) {
- provider.info.exported = false;
- }
- }
- }
+ parsedPackage
+ .clearProtectedBroadcasts()
+ .markNotActivitiesAsNotExportedIfSingleUser();
}
- if ((scanFlags & SCAN_AS_PRIVILEGED) != 0) {
- pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_PRIVILEGED;
- }
-
- if ((scanFlags & SCAN_AS_OEM) != 0) {
- pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_OEM;
- }
-
- if ((scanFlags & SCAN_AS_VENDOR) != 0) {
- pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_VENDOR;
- }
-
- if ((scanFlags & SCAN_AS_PRODUCT) != 0) {
- pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_PRODUCT;
- }
-
- if ((scanFlags & SCAN_AS_SYSTEM_EXT) != 0) {
- pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_SYSTEM_EXT;
- }
-
- if ((scanFlags & SCAN_AS_ODM) != 0) {
- pkg.applicationInfo.privateFlags |= ApplicationInfo.PRIVATE_FLAG_ODM;
- }
+ parsedPackage.setPrivileged((scanFlags & SCAN_AS_PRIVILEGED) != 0)
+ .setOem((scanFlags & SCAN_AS_OEM) != 0)
+ .setVendor((scanFlags & SCAN_AS_VENDOR) != 0)
+ .setProduct((scanFlags & SCAN_AS_PRODUCT) != 0)
+ .setSystemExt((scanFlags & SCAN_AS_SYSTEM_EXT) != 0)
+ .setOdm((scanFlags & SCAN_AS_ODM) != 0);
// Check if the package is signed with the same key as the platform package.
- if (PLATFORM_PACKAGE_NAME.equals(pkg.packageName) ||
- (platformPkg != null && compareSignatures(
- platformPkg.mSigningDetails.signatures,
- pkg.mSigningDetails.signatures) == PackageManager.SIGNATURE_MATCH)) {
- pkg.applicationInfo.privateFlags |=
- ApplicationInfo.PRIVATE_FLAG_SIGNED_WITH_PLATFORM_KEY;
- }
-
- if (!isSystemApp(pkg)) {
+ parsedPackage.setSignedWithPlatformKey(
+ (PLATFORM_PACKAGE_NAME.equals(parsedPackage.getPackageName())
+ || (platformPkg != null && compareSignatures(
+ platformPkg.getSigningDetails().signatures,
+ parsedPackage.getSigningDetails().signatures
+ ) == PackageManager.SIGNATURE_MATCH))
+ );
+
+ if (!isSystemApp(parsedPackage)) {
// Only system apps can use these features.
- pkg.mOriginalPackages = null;
- pkg.mRealPackage = null;
- pkg.mAdoptPermissions = null;
+ parsedPackage.clearOriginalPackages()
+ .setRealPackage(null)
+ .clearAdoptPermissions();
}
- PackageBackwardCompatibility.modifySharedLibraries(pkg);
+ PackageBackwardCompatibility.modifySharedLibraries(parsedPackage);
}
private static @NonNull <T> T assertNotNull(@Nullable T object, String message)
@@ -11189,15 +11079,15 @@ public class PackageManagerService extends IPackageManager.Stub
*
* @throws PackageManagerException If the package fails any of the validation checks
*/
- private void assertPackageIsValid(PackageParser.Package pkg, final @ParseFlags int parseFlags,
+ private void assertPackageIsValid(AndroidPackage pkg, final @ParseFlags int parseFlags,
final @ScanFlags int scanFlags)
throws PackageManagerException {
if ((parseFlags & PackageParser.PARSE_ENFORCE_CODE) != 0) {
assertCodePolicy(pkg);
}
- if (pkg.applicationInfo.getCodePath() == null ||
- pkg.applicationInfo.getResourcePath() == null) {
+ if (pkg.getAppInfoCodePath() == null ||
+ pkg.getAppInfoResourcePath() == null) {
// Bail out. The resource and code paths haven't been set.
throw new PackageManagerException(INSTALL_FAILED_INVALID_APK,
"Code and resource paths haven't been set correctly");
@@ -11208,9 +11098,10 @@ public class PackageManagerService extends IPackageManager.Stub
final boolean isUserInstall = (scanFlags & SCAN_BOOTING) == 0;
final boolean isFirstBootOrUpgrade = (scanFlags & SCAN_FIRST_BOOT_OR_UPGRADE) != 0;
if ((isUserInstall || isFirstBootOrUpgrade)
- && mApexManager.isApexPackage(pkg.packageName)) {
+ && mApexManager.isApexPackage(pkg.getPackageName())) {
throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
- pkg.packageName + " is an APEX package and can't be installed as an APK.");
+ pkg.getPackageName()
+ + " is an APEX package and can't be installed as an APK.");
}
// Make sure we're not adding any bogus keyset info
@@ -11219,11 +11110,11 @@ public class PackageManagerService extends IPackageManager.Stub
synchronized (mLock) {
// The special "android" package can only be defined once
- if (pkg.packageName.equals("android")) {
+ if (pkg.getPackageName().equals("android")) {
if (mAndroidApplication != null) {
Slog.w(TAG, "*************************************************");
Slog.w(TAG, "Core android package being redefined. Skipping.");
- Slog.w(TAG, " codePath=" + pkg.codePath);
+ Slog.w(TAG, " codePath=" + pkg.getCodePath());
Slog.w(TAG, "*************************************************");
throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
"Core android package being redefined. Skipping.");
@@ -11231,23 +11122,24 @@ public class PackageManagerService extends IPackageManager.Stub
}
// A package name must be unique; don't allow duplicates
- if ((scanFlags & SCAN_NEW_INSTALL) == 0 && mPackages.containsKey(pkg.packageName)) {
+ if ((scanFlags & SCAN_NEW_INSTALL) == 0
+ && mPackages.containsKey(pkg.getPackageName())) {
throw new PackageManagerException(INSTALL_FAILED_DUPLICATE_PACKAGE,
- "Application package " + pkg.packageName
+ "Application package " + pkg.getPackageName()
+ " already installed. Skipping duplicate.");
}
- if (pkg.applicationInfo.isStaticSharedLibrary()) {
+ if (pkg.isStaticSharedLibrary()) {
// Static libs have a synthetic package name containing the version
// but we still want the base name to be unique.
if ((scanFlags & SCAN_NEW_INSTALL) == 0
- && mPackages.containsKey(pkg.manifestPackageName)) {
+ && mPackages.containsKey(pkg.getManifestPackageName())) {
throw new PackageManagerException(
"Duplicate static shared lib provider package");
}
// Static shared libraries should have at least O target SDK
- if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.O) {
+ if (pkg.getTargetSdkVersion() < Build.VERSION_CODES.O) {
throw new PackageManagerException(
"Packages declaring static-shared libs must target O SDK or higher");
}
@@ -11260,73 +11152,67 @@ public class PackageManagerService extends IPackageManager.Stub
// Package declaring static a shared lib cannot be renamed since the package
// name is synthetic and apps can't code around package manager internals.
- if (!ArrayUtils.isEmpty(pkg.mOriginalPackages)) {
+ if (!ArrayUtils.isEmpty(pkg.getOriginalPackages())) {
throw new PackageManagerException(
"Packages declaring static-shared libs cannot be renamed");
}
- // Package declaring static a shared lib cannot declare child packages
- if (!ArrayUtils.isEmpty(pkg.childPackages)) {
- throw new PackageManagerException(
- "Packages declaring static-shared libs cannot have child packages");
- }
-
// Package declaring static a shared lib cannot declare dynamic libs
- if (!ArrayUtils.isEmpty(pkg.libraryNames)) {
+ if (!ArrayUtils.isEmpty(pkg.getLibraryNames())) {
throw new PackageManagerException(
"Packages declaring static-shared libs cannot declare dynamic libs");
}
// Package declaring static a shared lib cannot declare shared users
- if (pkg.mSharedUserId != null) {
+ if (pkg.getSharedUserId() != null) {
throw new PackageManagerException(
"Packages declaring static-shared libs cannot declare shared users");
}
// Static shared libs cannot declare activities
- if (!pkg.activities.isEmpty()) {
+ if (pkg.getActivities() != null && !pkg.getActivities().isEmpty()) {
throw new PackageManagerException(
"Static shared libs cannot declare activities");
}
// Static shared libs cannot declare services
- if (!pkg.services.isEmpty()) {
+ if (pkg.getServices() != null && !pkg.getServices().isEmpty()) {
throw new PackageManagerException(
"Static shared libs cannot declare services");
}
// Static shared libs cannot declare providers
- if (!pkg.providers.isEmpty()) {
+ if (pkg.getProviders() != null && !pkg.getProviders().isEmpty()) {
throw new PackageManagerException(
"Static shared libs cannot declare content providers");
}
// Static shared libs cannot declare receivers
- if (!pkg.receivers.isEmpty()) {
+ if (pkg.getReceivers() != null && !pkg.getReceivers().isEmpty()) {
throw new PackageManagerException(
"Static shared libs cannot declare broadcast receivers");
}
// Static shared libs cannot declare permission groups
- if (!pkg.permissionGroups.isEmpty()) {
+ if (pkg.getPermissionGroups() != null && !pkg.getPermissionGroups().isEmpty()) {
throw new PackageManagerException(
"Static shared libs cannot declare permission groups");
}
// Static shared libs cannot declare permissions
- if (!pkg.permissions.isEmpty()) {
+ if (pkg.getPermissions() != null && !pkg.getPermissions().isEmpty()) {
throw new PackageManagerException(
"Static shared libs cannot declare permissions");
}
// Static shared libs cannot declare protected broadcasts
- if (pkg.protectedBroadcasts != null) {
+ if (pkg.getProtectedBroadcasts() != null) {
throw new PackageManagerException(
"Static shared libs cannot declare protected broadcasts");
}
// Static shared libs cannot be overlay targets
- if (pkg.mOverlayTarget != null) {
+ if (pkg.getOverlayTarget() != null) {
throw new PackageManagerException(
"Static shared libs cannot be overlay targets");
}
@@ -11336,16 +11222,17 @@ public class PackageManagerService extends IPackageManager.Stub
long maxVersionCode = Long.MAX_VALUE;
LongSparseArray<SharedLibraryInfo> versionedLib = mSharedLibraries.get(
- pkg.staticSharedLibName);
+ pkg.getStaticSharedLibName());
if (versionedLib != null) {
final int versionCount = versionedLib.size();
for (int i = 0; i < versionCount; i++) {
SharedLibraryInfo libInfo = versionedLib.valueAt(i);
final long libVersionCode = libInfo.getDeclaringPackage()
.getLongVersionCode();
- if (libInfo.getLongVersion() < pkg.staticSharedLibVersion) {
+ if (libInfo.getLongVersion() < pkg.getStaticSharedLibVersion()) {
minVersionCode = Math.max(minVersionCode, libVersionCode + 1);
- } else if (libInfo.getLongVersion() > pkg.staticSharedLibVersion) {
+ } else if (libInfo.getLongVersion()
+ > pkg.getStaticSharedLibVersion()) {
maxVersionCode = Math.min(maxVersionCode, libVersionCode - 1);
} else {
minVersionCode = maxVersionCode = libVersionCode;
@@ -11360,23 +11247,6 @@ public class PackageManagerService extends IPackageManager.Stub
}
}
- // Only privileged apps and updated privileged apps can add child packages.
- if (pkg.childPackages != null && !pkg.childPackages.isEmpty()) {
- if ((scanFlags & SCAN_AS_PRIVILEGED) == 0) {
- throw new PackageManagerException("Only privileged apps can add child "
- + "packages. Ignoring package " + pkg.packageName);
- }
- final int childCount = pkg.childPackages.size();
- for (int i = 0; i < childCount; i++) {
- PackageParser.Package childPkg = pkg.childPackages.get(i);
- if (mSettings.hasOtherDisabledSystemPkgWithChildLPr(pkg.packageName,
- childPkg.packageName)) {
- throw new PackageManagerException("Can't override child of "
- + "another disabled app. Ignoring package " + pkg.packageName);
- }
- }
- }
-
// If we're only installing presumed-existing packages, require that the
// scanned APK is both already known and at the path previously established
// for it. Previously unknown packages we pick up normally, but if we have an
@@ -11386,29 +11256,30 @@ public class PackageManagerService extends IPackageManager.Stub
// to the user-installed location. If we don't allow this change, any newer,
// user-installed version of the application will be ignored.
if ((scanFlags & SCAN_REQUIRE_KNOWN) != 0) {
- if (mExpectingBetter.containsKey(pkg.packageName)) {
+ if (mExpectingBetter.containsKey(pkg.getPackageName())) {
logCriticalInfo(Log.WARN,
- "Relax SCAN_REQUIRE_KNOWN requirement for package " + pkg.packageName);
+ "Relax SCAN_REQUIRE_KNOWN requirement for package "
+ + pkg.getPackageName());
} else {
- PackageSetting known = mSettings.getPackageLPr(pkg.packageName);
+ PackageSetting known = mSettings.getPackageLPr(pkg.getPackageName());
if (known != null) {
if (DEBUG_PACKAGE_SCANNING) {
- Log.d(TAG, "Examining " + pkg.codePath
+ Log.d(TAG, "Examining " + pkg.getCodePath()
+ " and requiring known paths " + known.codePathString
+ " & " + known.resourcePathString);
}
- if (!pkg.applicationInfo.getCodePath().equals(known.codePathString)
- || !pkg.applicationInfo.getResourcePath().equals(
+ if (!pkg.getAppInfoCodePath().equals(known.codePathString)
+ || !pkg.getAppInfoResourcePath().equals(
known.resourcePathString)) {
throw new PackageManagerException(INSTALL_FAILED_PACKAGE_CHANGED,
- "Application package " + pkg.packageName
- + " found at " + pkg.applicationInfo.getCodePath()
+ "Application package " + pkg.getPackageName()
+ + " found at " + pkg.getAppInfoCodePath()
+ " but expected at " + known.codePathString
+ "; ignoring.");
}
} else {
throw new PackageManagerException(INSTALL_FAILED_INVALID_INSTALL_LOCATION,
- "Application package " + pkg.packageName
+ "Application package " + pkg.getPackageName()
+ " not found; ignoring.");
}
}
@@ -11423,11 +11294,13 @@ public class PackageManagerService extends IPackageManager.Stub
}
// Verify that packages sharing a user with a privileged app are marked as privileged.
- if (!pkg.isPrivileged() && (pkg.mSharedUserId != null)) {
+ if (!pkg.isPrivileged() && (pkg.getSharedUserId() != null)) {
SharedUserSetting sharedUserSetting = null;
try {
- sharedUserSetting = mSettings.getSharedUserLPw(pkg.mSharedUserId, 0, 0, false);
- } catch (PackageManagerException ignore) {}
+ sharedUserSetting = mSettings.getSharedUserLPw(pkg.getSharedUserId(),
+ 0, 0, false);
+ } catch (PackageManagerException ignore) {
+ }
if (sharedUserSetting != null && sharedUserSetting.isPrivileged()) {
// Exempt SharedUsers signed with the platform key.
PackageSetting platformPkgSetting = mSettings.mPackages.get("android");
@@ -11435,18 +11308,18 @@ public class PackageManagerService extends IPackageManager.Stub
!= PackageParser.SigningDetails.UNKNOWN)
&& (compareSignatures(
platformPkgSetting.signatures.mSigningDetails.signatures,
- pkg.mSigningDetails.signatures)
+ pkg.getSigningDetails().signatures)
!= PackageManager.SIGNATURE_MATCH)) {
throw new PackageManagerException("Apps that share a user with a " +
"privileged app must themselves be marked as privileged. " +
- pkg.packageName + " shares privileged user " +
- pkg.mSharedUserId + ".");
+ pkg.getPackageName() + " shares privileged user " +
+ pkg.getSharedUserId() + ".");
}
}
}
// Apply policies specific for runtime resource overlays (RROs).
- if (pkg.mOverlayTarget != null) {
+ if (pkg.getOverlayTarget() != null) {
// System overlays have some restrictions on their use of the 'static' state.
if ((scanFlags & SCAN_AS_SYSTEM) != 0) {
// We are scanning a system overlay. This can be the first scan of the
@@ -11454,54 +11327,62 @@ public class PackageManagerService extends IPackageManager.Stub
if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
// This must be an update to a system overlay.
final PackageSetting previousPkg = assertNotNull(
- mSettings.getPackageLPr(pkg.packageName),
+ mSettings.getPackageLPr(pkg.getPackageName()),
"previous package state not present");
// previousPkg.pkg may be null: the package will be not be scanned if the
// package manager knows there is a newer version on /data.
// TODO[b/79435695]: Find a better way to keep track of the "static"
// property for RROs instead of having to parse packages on /system
- PackageParser.Package ppkg = previousPkg.pkg;
+ AndroidPackage ppkg = previousPkg.pkg;
if (ppkg == null) {
try {
final PackageParser pp = new PackageParser();
- ppkg = pp.parsePackage(previousPkg.codePath,
- parseFlags | PackageParser.PARSE_IS_SYSTEM_DIR);
+ // TODO(b/135203078): Do we really need to parse here? Maybe use
+ // a shortened path?
+ ppkg = pp.parseParsedPackage(previousPkg.codePath,
+ parseFlags | PackageParser.PARSE_IS_SYSTEM_DIR,
+ false)
+ .hideAsFinal();
} catch (PackageParserException e) {
Slog.w(TAG, "failed to parse " + previousPkg.codePath, e);
}
}
// Static overlays cannot be updated.
- if (ppkg != null && ppkg.mOverlayIsStatic) {
- throw new PackageManagerException("Overlay " + pkg.packageName +
- " is static and cannot be upgraded.");
+ if (ppkg != null && ppkg.isOverlayIsStatic()) {
+ throw new PackageManagerException("Overlay "
+ + pkg.getPackageName()
+ + " is static and cannot be upgraded.");
// Non-static overlays cannot be converted to static overlays.
- } else if (pkg.mOverlayIsStatic) {
- throw new PackageManagerException("Overlay " + pkg.packageName +
- " cannot be upgraded into a static overlay.");
+ } else if (pkg.isOverlayIsStatic()) {
+ throw new PackageManagerException("Overlay "
+ + pkg.getPackageName()
+ + " cannot be upgraded into a static overlay.");
}
}
} else {
// The overlay is a non-system overlay. Non-system overlays cannot be static.
- if (pkg.mOverlayIsStatic) {
- throw new PackageManagerException("Overlay " + pkg.packageName +
- " is static but not pre-installed.");
+ if (pkg.isOverlayIsStatic()) {
+ throw new PackageManagerException("Overlay "
+ + pkg.getPackageName()
+ + " is static but not pre-installed.");
}
// A non-preloaded overlay packages must have targetSdkVersion >= Q, or be
// signed with the platform certificate. Check this in increasing order of
// computational cost.
- if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.Q) {
+ if (pkg.getTargetSdkVersion() < Build.VERSION_CODES.Q) {
final PackageSetting platformPkgSetting =
mSettings.getPackageLPr("android");
if ((platformPkgSetting.signatures.mSigningDetails
!= PackageParser.SigningDetails.UNKNOWN)
&& (compareSignatures(
platformPkgSetting.signatures.mSigningDetails.signatures,
- pkg.mSigningDetails.signatures)
+ pkg.getSigningDetails().signatures)
!= PackageManager.SIGNATURE_MATCH)) {
- throw new PackageManagerException("Overlay " + pkg.packageName
+ throw new PackageManagerException("Overlay "
+ + pkg.getPackageName()
+ " must target Q or later, "
+ "or be signed with the platform certificate");
}
@@ -11511,18 +11392,19 @@ public class PackageManagerService extends IPackageManager.Stub
// only be used if it is signed with the same certificate as its target. If the
// target is already installed, check this here to augment the last line of
// defence which is OMS.
- if (pkg.mOverlayTargetName == null) {
+ if (pkg.getOverlayTargetName() == null) {
final PackageSetting targetPkgSetting =
- mSettings.getPackageLPr(pkg.mOverlayTarget);
+ mSettings.getPackageLPr(pkg.getOverlayTarget());
if (targetPkgSetting != null) {
if ((targetPkgSetting.signatures.mSigningDetails
!= PackageParser.SigningDetails.UNKNOWN)
&& (compareSignatures(
targetPkgSetting.signatures.mSigningDetails.signatures,
- pkg.mSigningDetails.signatures)
+ pkg.getSigningDetails().signatures)
!= PackageManager.SIGNATURE_MATCH)) {
- throw new PackageManagerException("Overlay " + pkg.packageName
- + " and target " + pkg.mOverlayTarget + " signed with"
+ throw new PackageManagerException("Overlay "
+ + pkg.getPackageName() + " and target "
+ + pkg.getOverlayTarget() + " signed with"
+ " different certificates, and the overlay lacks"
+ " <overlay android:targetName>");
}
@@ -11602,71 +11484,67 @@ public class PackageManagerService extends IPackageManager.Stub
* Adds a scanned package to the system. When this method is finished, the package will
* be available for query, resolution, etc...
*/
- private void commitPackageSettings(PackageParser.Package pkg,
- @Nullable PackageParser.Package oldPkg, PackageSetting pkgSetting,
+ private void commitPackageSettings(AndroidPackage pkg,
+ @Nullable AndroidPackage oldPkg, PackageSetting pkgSetting,
final @ScanFlags int scanFlags, boolean chatty, ReconciledPackage reconciledPkg) {
- final String pkgName = pkg.packageName;
+ final String pkgName = pkg.getPackageName();
if (mCustomResolverComponentName != null &&
- mCustomResolverComponentName.getPackageName().equals(pkg.packageName)) {
+ mCustomResolverComponentName.getPackageName().equals(pkg.getPackageName())) {
setUpCustomResolverActivity(pkg);
}
- if (pkg.packageName.equals("android")) {
+ if (pkg.getPackageName().equals("android")) {
synchronized (mLock) {
- if ((scanFlags & SCAN_CHECK_ONLY) == 0) {
- // Set up information for our fall-back user intent resolution activity.
- mPlatformPackage = pkg;
- pkg.mVersionCode = mSdkVersion;
- pkg.mVersionCodeMajor = 0;
- mAndroidApplication = pkg.applicationInfo;
- if (!mResolverReplaced) {
- mResolveActivity.applicationInfo = mAndroidApplication;
- mResolveActivity.name = ResolverActivity.class.getName();
- mResolveActivity.packageName = mAndroidApplication.packageName;
- mResolveActivity.processName = "system:ui";
- mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
- mResolveActivity.documentLaunchMode = ActivityInfo.DOCUMENT_LAUNCH_NEVER;
- mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS;
- mResolveActivity.theme = R.style.Theme_Material_Dialog_Alert;
- mResolveActivity.exported = true;
- mResolveActivity.enabled = true;
- mResolveActivity.resizeMode = ActivityInfo.RESIZE_MODE_RESIZEABLE;
- mResolveActivity.configChanges = ActivityInfo.CONFIG_SCREEN_SIZE
- | ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE
- | ActivityInfo.CONFIG_SCREEN_LAYOUT
- | ActivityInfo.CONFIG_ORIENTATION
- | ActivityInfo.CONFIG_KEYBOARD
- | ActivityInfo.CONFIG_KEYBOARD_HIDDEN;
- mResolveInfo.activityInfo = mResolveActivity;
- mResolveInfo.priority = 0;
- mResolveInfo.preferredOrder = 0;
- mResolveInfo.match = 0;
- mResolveComponentName = new ComponentName(
- mAndroidApplication.packageName, mResolveActivity.name);
- }
- }
- }
- }
-
- ArrayList<PackageParser.Package> clientLibPkgs = null;
+ // Set up information for our fall-back user intent resolution activity.
+ mPlatformPackage = pkg;
+ mAndroidApplication = pkg.toAppInfo();
+ if (!mResolverReplaced) {
+ mResolveActivity.applicationInfo = mAndroidApplication;
+ mResolveActivity.name = ResolverActivity.class.getName();
+ mResolveActivity.packageName = mAndroidApplication.packageName;
+ mResolveActivity.processName = "system:ui";
+ mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
+ mResolveActivity.documentLaunchMode = ActivityInfo.DOCUMENT_LAUNCH_NEVER;
+ mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS;
+ mResolveActivity.theme = R.style.Theme_Material_Dialog_Alert;
+ mResolveActivity.exported = true;
+ mResolveActivity.enabled = true;
+ mResolveActivity.resizeMode = ActivityInfo.RESIZE_MODE_RESIZEABLE;
+ mResolveActivity.configChanges = ActivityInfo.CONFIG_SCREEN_SIZE
+ | ActivityInfo.CONFIG_SMALLEST_SCREEN_SIZE
+ | ActivityInfo.CONFIG_SCREEN_LAYOUT
+ | ActivityInfo.CONFIG_ORIENTATION
+ | ActivityInfo.CONFIG_KEYBOARD
+ | ActivityInfo.CONFIG_KEYBOARD_HIDDEN;
+ mResolveInfo.activityInfo = mResolveActivity;
+ mResolveInfo.priority = 0;
+ mResolveInfo.preferredOrder = 0;
+ mResolveInfo.match = 0;
+ mResolveComponentName = new ComponentName(
+ mAndroidApplication.packageName, mResolveActivity.name);
+ }
+ }
+ }
+
+ ArrayList<AndroidPackage> clientLibPkgs = null;
// writer
synchronized (mLock) {
if (!ArrayUtils.isEmpty(reconciledPkg.allowedSharedLibraryInfos)) {
for (SharedLibraryInfo info : reconciledPkg.allowedSharedLibraryInfos) {
commitSharedLibraryInfoLocked(info);
}
- final Map<String, PackageParser.Package> combinedPackages =
- reconciledPkg.getCombinedPackages();
+ final Map<String, AndroidPackage> combinedSigningDetails =
+ reconciledPkg.getCombinedAvailablePackages();
try {
// Shared libraries for the package need to be updated.
- updateSharedLibrariesLocked(pkg, null, combinedPackages);
+ updateSharedLibrariesLocked(pkg, null, combinedSigningDetails);
} catch (PackageManagerException e) {
Slog.e(TAG, "updateSharedLibrariesLPr failed: ", e);
}
// Update all applications that use this library. Skip when booting
// since this will be done after all packages are scaned.
if ((scanFlags & SCAN_BOOTING) == 0) {
- clientLibPkgs = updateAllSharedLibrariesLocked(pkg, combinedPackages);
+ clientLibPkgs = updateAllSharedLibrariesLocked(pkg, combinedSigningDetails);
}
}
}
@@ -11690,9 +11568,9 @@ public class PackageManagerService extends IPackageManager.Stub
// Also need to kill any apps that are dependent on the library.
if (clientLibPkgs != null) {
for (int i=0; i<clientLibPkgs.size(); i++) {
- PackageParser.Package clientPkg = clientLibPkgs.get(i);
- killApplication(clientPkg.applicationInfo.packageName,
- clientPkg.applicationInfo.uid, "update lib");
+ AndroidPackage clientPkg = clientLibPkgs.get(i);
+ killApplication(clientPkg.getAppInfoPackageName(),
+ clientPkg.getUid(), "update lib");
}
}
@@ -11705,7 +11583,7 @@ public class PackageManagerService extends IPackageManager.Stub
// Add the new setting to mSettings
mSettings.insertPackageSettingLPw(pkgSetting, pkg);
// Add the new setting to mPackages
- mPackages.put(pkg.applicationInfo.packageName, pkg);
+ mPackages.put(pkg.getAppInfoPackageName(), pkg);
// Add the package's KeySets to the global KeySetManagerService
KeySetManagerService ksms = mSettings.mKeySetManagerService;
@@ -11716,7 +11594,7 @@ public class PackageManagerService extends IPackageManager.Stub
// Don't allow ephemeral applications to define new permissions groups.
if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) {
- Slog.w(TAG, "Permission groups from package " + pkg.packageName
+ Slog.w(TAG, "Permission groups from package " + pkg.getPackageName()
+ " ignored: instant apps cannot define new permission groups.");
} else {
mPermissionManager.addAllPermissionGroups(pkg, chatty);
@@ -11724,31 +11602,31 @@ public class PackageManagerService extends IPackageManager.Stub
// Don't allow ephemeral applications to define new permissions.
if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) {
- Slog.w(TAG, "Permissions from package " + pkg.packageName
+ Slog.w(TAG, "Permissions from package " + pkg.getPackageName()
+ " ignored: instant apps cannot define new permissions.");
} else {
mPermissionManager.addAllPermissions(pkg, chatty);
}
- int collectionSize = pkg.instrumentation.size();
+ int collectionSize = ArrayUtils.size(pkg.getInstrumentations());
StringBuilder r = null;
int i;
for (i = 0; i < collectionSize; i++) {
- PackageParser.Instrumentation a = pkg.instrumentation.get(i);
- a.info.packageName = pkg.applicationInfo.packageName;
- a.info.sourceDir = pkg.applicationInfo.sourceDir;
- a.info.publicSourceDir = pkg.applicationInfo.publicSourceDir;
- a.info.splitNames = pkg.splitNames;
- a.info.splitSourceDirs = pkg.applicationInfo.splitSourceDirs;
- a.info.splitPublicSourceDirs = pkg.applicationInfo.splitPublicSourceDirs;
- a.info.splitDependencies = pkg.applicationInfo.splitDependencies;
- a.info.dataDir = pkg.applicationInfo.dataDir;
- a.info.deviceProtectedDataDir = pkg.applicationInfo.deviceProtectedDataDir;
- a.info.credentialProtectedDataDir = pkg.applicationInfo.credentialProtectedDataDir;
- a.info.primaryCpuAbi = pkg.applicationInfo.primaryCpuAbi;
- a.info.secondaryCpuAbi = pkg.applicationInfo.secondaryCpuAbi;
- a.info.nativeLibraryDir = pkg.applicationInfo.nativeLibraryDir;
- a.info.secondaryNativeLibraryDir = pkg.applicationInfo.secondaryNativeLibraryDir;
+ ParsedInstrumentation a = pkg.getInstrumentations().get(i);
+ a.setPackageName(pkg.getAppInfoPackageName());
+ a.sourceDir = pkg.getBaseCodePath();
+ a.publicSourceDir = pkg.getPublicSourceDir();
+ a.splitNames = pkg.getSplitNames();
+ a.splitSourceDirs = pkg.getSplitCodePaths();
+ a.splitPublicSourceDirs = pkg.getSplitPublicSourceDirs();
+ a.splitDependencies = pkg.getSplitDependencies();
+ a.dataDir = pkg.getDataDir();
+ a.deviceProtectedDataDir = pkg.getDeviceProtectedDataDir();
+ a.credentialProtectedDataDir = pkg.getCredentialProtectedDataDir();
+ a.primaryCpuAbi = pkg.getPrimaryCpuAbi();
+ a.secondaryCpuAbi = pkg.getSecondaryCpuAbi();
+ a.nativeLibraryDir = pkg.getNativeLibraryDir();
+ a.secondaryNativeLibraryDir = pkg.getSecondaryNativeLibraryDir();
mInstrumentation.put(a.getComponentName(), a);
if (chatty) {
if (r == null) {
@@ -11756,19 +11634,16 @@ public class PackageManagerService extends IPackageManager.Stub
} else {
r.append(' ');
}
- r.append(a.info.name);
+ r.append(a.getName());
}
}
if (r != null) {
if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, " Instrumentation: " + r);
}
- if (pkg.protectedBroadcasts != null) {
- collectionSize = pkg.protectedBroadcasts.size();
+ if (pkg.getProtectedBroadcasts() != null) {
synchronized (mProtectedBroadcasts) {
- for (i = 0; i < collectionSize; i++) {
- mProtectedBroadcasts.add(pkg.protectedBroadcasts.get(i));
- }
+ mProtectedBroadcasts.addAll(pkg.getProtectedBroadcasts());
}
}
@@ -11792,14 +11667,14 @@ public class PackageManagerService extends IPackageManager.Stub
Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
}
- private void setUpCustomResolverActivity(PackageParser.Package pkg) {
+ private void setUpCustomResolverActivity(AndroidPackage pkg) {
synchronized (mLock) {
mResolverReplaced = true;
// Set up information for custom user intent resolution activity.
- mResolveActivity.applicationInfo = pkg.applicationInfo;
+ mResolveActivity.applicationInfo = pkg.toAppInfo();
mResolveActivity.name = mCustomResolverComponentName.getClassName();
- mResolveActivity.packageName = pkg.applicationInfo.packageName;
- mResolveActivity.processName = pkg.applicationInfo.packageName;
+ mResolveActivity.packageName = pkg.getAppInfoPackageName();
+ mResolveActivity.processName = pkg.getAppInfoProcessName();
mResolveActivity.launchMode = ActivityInfo.LAUNCH_MULTIPLE;
mResolveActivity.flags = ActivityInfo.FLAG_EXCLUDE_FROM_RECENTS |
ActivityInfo.FLAG_FINISH_ON_CLOSE_SYSTEM_DIALOGS;
@@ -11866,22 +11741,13 @@ public class PackageManagerService extends IPackageManager.Stub
}
}
- private void removePackageLI(PackageParser.Package pkg, boolean chatty) {
+ private void removePackageLI(AndroidPackage pkg, boolean chatty) {
// Remove the parent package setting
- PackageSetting ps = (PackageSetting) pkg.mExtras;
+ PackageSetting ps = getPackageSetting(pkg.getPackageName());
if (ps != null) {
removePackageLI(ps.name, chatty);
} else if (DEBUG_REMOVE && chatty) {
- Log.d(TAG, "Not removing package " + pkg.packageName + "; mExtras == null");
- }
- // Remove the child package setting
- final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
- for (int i = 0; i < childCount; i++) {
- PackageParser.Package childPkg = pkg.childPackages.get(i);
- ps = (PackageSetting) childPkg.mExtras;
- if (ps != null) {
- removePackageLI(ps.name, chatty);
- }
+ Log.d(TAG, "Not removing package " + pkg.getPackageName() + "; mExtras == null");
}
}
@@ -11893,45 +11759,23 @@ public class PackageManagerService extends IPackageManager.Stub
// writer
synchronized (mLock) {
- final PackageParser.Package removedPackage = mPackages.remove(packageName);
+ final AndroidPackage removedPackage = mPackages.remove(packageName);
if (removedPackage != null) {
cleanPackageDataStructuresLILPw(removedPackage, chatty);
}
}
}
- void removeInstalledPackageLI(PackageParser.Package pkg, boolean chatty) {
- if (DEBUG_INSTALL) {
- if (chatty)
- Log.d(TAG, "Removing package " + pkg.applicationInfo.packageName);
- }
-
- // writer
- synchronized (mLock) {
- // Remove the parent package
- mPackages.remove(pkg.applicationInfo.packageName);
- cleanPackageDataStructuresLILPw(pkg, chatty);
-
- // Remove the child packages
- final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
- for (int i = 0; i < childCount; i++) {
- PackageParser.Package childPkg = pkg.childPackages.get(i);
- mPackages.remove(childPkg.applicationInfo.packageName);
- cleanPackageDataStructuresLILPw(childPkg, chatty);
- }
- }
- }
-
- void cleanPackageDataStructuresLILPw(PackageParser.Package pkg, boolean chatty) {
+ void cleanPackageDataStructuresLILPw(AndroidPackage pkg, boolean chatty) {
mComponentResolver.removeAllComponents(pkg, chatty);
- mAppsFilter.removePackage(pkg.packageName);
+ mAppsFilter.removePackage(pkg.getPackageName());
mPermissionManager.removeAllPermissions(pkg, chatty);
- final int instrumentationSize = pkg.instrumentation.size();
+ final int instrumentationSize = ArrayUtils.size(pkg.getInstrumentations());
StringBuilder r = null;
int i;
for (i = 0; i < instrumentationSize; i++) {
- PackageParser.Instrumentation a = pkg.instrumentation.get(i);
+ ParsedInstrumentation a = pkg.getInstrumentations().get(i);
mInstrumentation.remove(a.getComponentName());
if (DEBUG_REMOVE && chatty) {
if (r == null) {
@@ -11939,7 +11783,7 @@ public class PackageManagerService extends IPackageManager.Stub
} else {
r.append(' ');
}
- r.append(a.info.name);
+ r.append(a.getName());
}
}
if (r != null) {
@@ -11947,12 +11791,12 @@ public class PackageManagerService extends IPackageManager.Stub
}
r = null;
- if ((pkg.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
+ if ((pkg.getFlags() & ApplicationInfo.FLAG_SYSTEM) != 0) {
// Only system apps can hold shared libraries.
- if (pkg.libraryNames != null) {
- final int libraryNamesSize = pkg.libraryNames.size();
+ if (pkg.getLibraryNames() != null) {
+ final int libraryNamesSize = pkg.getLibraryNames().size();
for (i = 0; i < libraryNamesSize; i++) {
- String name = pkg.libraryNames.get(i);
+ String name = pkg.getLibraryNames().get(i);
if (removeSharedLibraryLPw(name, 0)) {
if (DEBUG_REMOVE && chatty) {
if (r == null) {
@@ -11970,15 +11814,16 @@ public class PackageManagerService extends IPackageManager.Stub
r = null;
// Any package can hold static shared libraries.
- if (pkg.staticSharedLibName != null) {
- if (removeSharedLibraryLPw(pkg.staticSharedLibName, pkg.staticSharedLibVersion)) {
+ if (pkg.getStaticSharedLibName() != null) {
+ if (removeSharedLibraryLPw(pkg.getStaticSharedLibName(),
+ pkg.getStaticSharedLibVersion())) {
if (DEBUG_REMOVE && chatty) {
if (r == null) {
r = new StringBuilder(256);
} else {
r.append(' ');
}
- r.append(pkg.staticSharedLibName);
+ r.append(pkg.getStaticSharedLibName());
}
}
}
@@ -12319,11 +12164,11 @@ public class PackageManagerService extends IPackageManager.Stub
// Cannot hide static shared libs as they are considered
// a part of the using app (emulating static linking). Also
// static libs are installed always on internal storage.
- PackageParser.Package pkg = mPackages.get(packageName);
- if (pkg != null && pkg.staticSharedLibName != null) {
+ AndroidPackage pkg = mPackages.get(packageName);
+ if (pkg != null && pkg.getStaticSharedLibName() != null) {
Slog.w(TAG, "Cannot hide package: " + packageName
+ " providing static shared library: "
- + pkg.staticSharedLibName);
+ + pkg.getStaticSharedLibName());
return false;
}
// Only allow protected packages to hide themselves.
@@ -12369,17 +12214,17 @@ public class PackageManagerService extends IPackageManager.Stub
if (pkgSetting == null || !pkgSetting.isSystem()) {
return;
}
- PackageParser.Package pkg = pkgSetting.pkg;
- if (pkg != null && pkg.applicationInfo != null) {
- pkg.applicationInfo.hiddenUntilInstalled = hidden;
+ AndroidPackage pkg = pkgSetting.pkg;
+ if (pkg != null) {
+ pkg.mutate().setHiddenUntilInstalled(hidden);
}
final PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(packageName);
if (disabledPs == null) {
return;
}
pkg = disabledPs.pkg;
- if (pkg != null && pkg.applicationInfo != null) {
- pkg.applicationInfo.hiddenUntilInstalled = hidden;
+ if (pkg != null) {
+ pkg.mutate().setHiddenUntilInstalled(hidden);
}
}
}
@@ -12575,7 +12420,7 @@ public class PackageManagerService extends IPackageManager.Stub
if (installed) {
if ((installFlags & PackageManager.INSTALL_ALL_WHITELIST_RESTRICTED_PERMISSIONS)
!= 0 && pkgSetting.pkg != null) {
- whiteListedPermissions = pkgSetting.pkg.requestedPermissions;
+ whiteListedPermissions = pkgSetting.pkg.getRequestedPermissions();
}
mPermissionManager.setWhitelistedRestrictedPermissions(packageName,
whiteListedPermissions, FLAG_PERMISSION_WHITELIST_INSTALLER, userId);
@@ -13012,11 +12857,11 @@ public class PackageManagerService extends IPackageManager.Stub
// Cannot suspend static shared libs as they are considered
// a part of the using app (emulating static linking). Also
// static libs are installed always on internal storage.
- PackageParser.Package pkg = mPackages.get(packageName);
- if (pkg != null && pkg.applicationInfo.isStaticSharedLibrary()) {
+ AndroidPackage pkg = mPackages.get(packageName);
+ if (pkg != null && pkg.isStaticSharedLibrary()) {
Slog.w(TAG, "Cannot suspend package: " + packageName
+ " providing static shared library: "
- + pkg.staticSharedLibName);
+ + pkg.getStaticSharedLibName());
continue;
}
}
@@ -13161,10 +13006,10 @@ public class PackageManagerService extends IPackageManager.Stub
private int getUidForVerifier(VerifierInfo verifierInfo) {
synchronized (mLock) {
- final PackageParser.Package pkg = mPackages.get(verifierInfo.packageName);
+ final AndroidPackage pkg = mPackages.get(verifierInfo.packageName);
if (pkg == null) {
return -1;
- } else if (pkg.mSigningDetails.signatures.length != 1) {
+ } else if (pkg.getSigningDetails().signatures.length != 1) {
Slog.i(TAG, "Verifier package " + verifierInfo.packageName
+ " has more than one signature; ignoring");
return -1;
@@ -13178,7 +13023,7 @@ public class PackageManagerService extends IPackageManager.Stub
final byte[] expectedPublicKey;
try {
- final Signature verifierSig = pkg.mSigningDetails.signatures[0];
+ final Signature verifierSig = pkg.getSigningDetails().signatures[0];
final PublicKey publicKey = verifierSig.getPublicKey();
expectedPublicKey = publicKey.getEncoded();
} catch (CertificateException e) {
@@ -13193,7 +13038,7 @@ public class PackageManagerService extends IPackageManager.Stub
return -1;
}
- return pkg.applicationInfo.uid;
+ return pkg.getUid();
}
}
@@ -13381,26 +13226,33 @@ public class PackageManagerService extends IPackageManager.Stub
final int callingUid = Binder.getCallingUid();
final int callingUserId = UserHandle.getUserId(callingUid);
synchronized (mLock) {
- PackageParser.Package pkg = mPackages.get(packageName);
- if (pkg == null || pkg.activities == null) {
+ AndroidPackage pkg = mPackages.get(packageName);
+ if (pkg == null || ArrayUtils.isEmpty(pkg.getActivities())) {
return ParceledListSlice.emptyList();
}
- if (pkg.mExtras == null) {
+ final PackageSetting ps = getPackageSetting(pkg.getPackageName());
+ if (ps == null) {
return ParceledListSlice.emptyList();
}
- final PackageSetting ps = (PackageSetting) pkg.mExtras;
if (shouldFilterApplicationLocked(ps, callingUid, callingUserId)) {
return ParceledListSlice.emptyList();
}
- final int count = pkg.activities.size();
+ final int count = ArrayUtils.size(pkg.getActivities());
ArrayList<IntentFilter> result = new ArrayList<>();
for (int n=0; n<count; n++) {
- PackageParser.Activity activity = pkg.activities.get(n);
+ ParsedActivity activity = pkg.getActivities().get(n);
if (activity.intents != null && activity.intents.size() > 0) {
result.addAll(activity.intents);
}
}
- return new ParceledListSlice<>(result);
+ return new ParceledListSlice<IntentFilter>(result) {
+ @Override
+ protected void writeElement(IntentFilter parcelable, Parcel dest, int callFlags) {
+ // IntentFilter has final Parcelable methods, so redirect to the subclass
+ ((ParsedActivityIntentInfo) parcelable).writeIntentInfoToParcel(dest,
+ callFlags);
+ }
+ };
}
}
@@ -13581,7 +13433,7 @@ public class PackageManagerService extends IPackageManager.Stub
// package has not opted out of backup participation.
final boolean update = res.removedInfo != null
&& res.removedInfo.removedPackage != null;
- final int flags = (res.pkg == null) ? 0 : res.pkg.applicationInfo.flags;
+ final int flags = (res.pkg == null) ? 0 : res.pkg.getFlags();
boolean doRestore = !update
&& ((flags & ApplicationInfo.FLAG_ALLOW_BACKUP) != 0);
@@ -13619,7 +13471,7 @@ public class PackageManagerService extends IPackageManager.Stub
try {
if (bm.isBackupServiceActive(userId)) {
bm.restoreAtInstallForUser(
- userId, res.pkg.applicationInfo.packageName, token);
+ userId, res.pkg.getAppInfoPackageName(), token);
} else {
doRestore = false;
}
@@ -13644,8 +13496,8 @@ public class PackageManagerService extends IPackageManager.Stub
IRollbackManager rm = IRollbackManager.Stub.asInterface(
ServiceManager.getService(Context.ROLLBACK_SERVICE));
- final String packageName = res.pkg.applicationInfo.packageName;
- final String seInfo = res.pkg.applicationInfo.seInfo;
+ final String packageName = res.pkg.getAppInfoPackageName();
+ final String seInfo = res.pkg.getSeInfo();
final int[] allUsers = mUserManager.getUserIds();
final int[] installedUsers;
@@ -13714,7 +13566,7 @@ public class PackageManagerService extends IPackageManager.Stub
if (data.res.returnCode != PackageManager.INSTALL_SUCCEEDED) {
continue;
}
- if (packageName.equals(data.res.pkg.applicationInfo.packageName)) {
+ if (packageName.equals(data.res.pkg.getAppInfoPackageName())) {
// right package; but is it for the right user?
for (int uIndex = 0; uIndex < data.res.newUsers.length; uIndex++) {
if (userId == data.res.newUsers[uIndex]) {
@@ -14056,12 +13908,12 @@ public class PackageManagerService extends IPackageManager.Stub
synchronized (mLock) {
// Currently installed package which the new package is attempting to replace or
// null if no such package is installed.
- PackageParser.Package installedPkg = mPackages.get(packageName);
+ AndroidPackage installedPkg = mPackages.get(packageName);
// Package which currently owns the data which the new package will own if installed.
// If an app is unstalled while keeping data (e.g., adb uninstall -k), installedPkg
// will be null whereas dataOwnerPkg will contain information about the package
// which was uninstalled while keeping its data.
- PackageParser.Package dataOwnerPkg = installedPkg;
+ AndroidPackage dataOwnerPkg = installedPkg;
if (dataOwnerPkg == null) {
PackageSetting ps = mSettings.mPackages.get(packageName);
if (ps != null) {
@@ -14088,7 +13940,7 @@ public class PackageManagerService extends IPackageManager.Stub
if (dataOwnerPkg != null) {
if (!PackageManagerServiceUtils.isDowngradePermitted(installFlags,
- dataOwnerPkg.applicationInfo.flags)) {
+ dataOwnerPkg.getFlags())) {
try {
checkDowngrade(dataOwnerPkg, pkgLite);
} catch (PackageManagerException e) {
@@ -14101,7 +13953,7 @@ public class PackageManagerService extends IPackageManager.Stub
if (installedPkg != null) {
if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
// Check for updated system application.
- if ((installedPkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
+ if ((installedPkg.getFlags() & ApplicationInfo.FLAG_SYSTEM) != 0) {
return PackageHelper.RECOMMEND_INSTALL_INTERNAL;
} else {
// If current upgrade specifies particular preference
@@ -14564,7 +14416,7 @@ public class PackageManagerService extends IPackageManager.Stub
* Rename package into final resting place. All paths on the given
* scanned package should be updated to reflect the rename.
*/
- abstract boolean doRename(int status, PackageParser.Package pkg);
+ abstract boolean doRename(int status, ParsedPackage parsedPackage);
abstract int doPostInstall(int status, int uid);
/** @see PackageSettingBase#codePathString */
@@ -14712,7 +14564,8 @@ public class PackageManagerService extends IPackageManager.Stub
return status;
}
- boolean doRename(int status, PackageParser.Package pkg) {
+ @Override
+ boolean doRename(int status, ParsedPackage parsedPackage) {
if (status != PackageManager.INSTALL_SUCCEEDED) {
cleanUp();
return false;
@@ -14720,7 +14573,7 @@ public class PackageManagerService extends IPackageManager.Stub
final File targetDir = codeFile.getParentFile();
final File beforeCodeFile = codeFile;
- final File afterCodeFile = getNextCodePath(targetDir, pkg.packageName);
+ final File afterCodeFile = getNextCodePath(targetDir, parsedPackage.getPackageName());
if (DEBUG_INSTALL) Slog.d(TAG, "Renaming " + beforeCodeFile + " to " + afterCodeFile);
try {
@@ -14741,24 +14594,23 @@ public class PackageManagerService extends IPackageManager.Stub
// Reflect the rename in scanned details
try {
- pkg.setCodePath(afterCodeFile.getCanonicalPath());
+ parsedPackage.setCodePath(afterCodeFile.getCanonicalPath());
} catch (IOException e) {
Slog.e(TAG, "Failed to get path: " + afterCodeFile, e);
return false;
}
- pkg.setBaseCodePath(FileUtils.rewriteAfterRename(beforeCodeFile,
- afterCodeFile, pkg.baseCodePath));
- pkg.setSplitCodePaths(FileUtils.rewriteAfterRename(beforeCodeFile,
- afterCodeFile, pkg.splitCodePaths));
+ parsedPackage.setBaseCodePath(FileUtils.rewriteAfterRename(beforeCodeFile,
+ afterCodeFile, parsedPackage.getBaseCodePath()));
+ parsedPackage.setSplitCodePaths(FileUtils.rewriteAfterRename(beforeCodeFile,
+ afterCodeFile, parsedPackage.getSplitCodePaths()));
// Reflect the rename in app info
- pkg.setApplicationVolumeUuid(pkg.volumeUuid);
- pkg.setApplicationInfoCodePath(pkg.codePath);
- pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
- pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
- pkg.setApplicationInfoResourcePath(pkg.codePath);
- pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath);
- pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
+ // TODO(b/135203078): Remove all of these application info calls
+ parsedPackage.setApplicationVolumeUuid(parsedPackage.getVolumeUuid())
+ .setApplicationInfoCodePath(parsedPackage.getCodePath())
+ .setApplicationInfoResourcePath(parsedPackage.getCodePath())
+ .setApplicationInfoBaseResourcePath(parsedPackage.getBaseCodePath())
+ .setApplicationInfoSplitResourcePaths(parsedPackage.getSplitCodePaths());
return true;
}
@@ -14861,20 +14713,20 @@ public class PackageManagerService extends IPackageManager.Stub
return status;
}
- boolean doRename(int status, PackageParser.Package pkg) {
+ @Override
+ boolean doRename(int status, ParsedPackage parsedPackage) {
if (status != PackageManager.INSTALL_SUCCEEDED) {
cleanUp(move.toUuid);
return false;
}
// Reflect the move in app info
- pkg.setApplicationVolumeUuid(pkg.volumeUuid);
- pkg.setApplicationInfoCodePath(pkg.codePath);
- pkg.setApplicationInfoBaseCodePath(pkg.baseCodePath);
- pkg.setApplicationInfoSplitCodePaths(pkg.splitCodePaths);
- pkg.setApplicationInfoResourcePath(pkg.codePath);
- pkg.setApplicationInfoBaseResourcePath(pkg.baseCodePath);
- pkg.setApplicationInfoSplitResourcePaths(pkg.splitCodePaths);
+ // TODO(b/135203078): Remove all of these application info calls
+ parsedPackage.setApplicationVolumeUuid(parsedPackage.getVolumeUuid())
+ .setApplicationInfoCodePath(parsedPackage.getCodePath())
+ .setApplicationInfoResourcePath(parsedPackage.getCodePath())
+ .setApplicationInfoBaseResourcePath(parsedPackage.getBaseCodePath())
+ .setApplicationInfoSplitResourcePaths(parsedPackage.getSplitCodePaths());
return true;
}
@@ -14950,14 +14802,14 @@ public class PackageManagerService extends IPackageManager.Stub
int[] origUsers;
// The set of users that now have this package installed.
int[] newUsers;
- PackageParser.Package pkg;
+ AndroidPackage pkg;
int returnCode;
String returnMsg;
String installerPackageName;
PackageRemovedInfo removedInfo;
ArrayMap<String, PackageInstalledInfo> addedChildPackages;
// The set of packages consuming this shared library or null if no consumers exist.
- ArrayList<PackageParser.Package> libraryConsumers;
+ ArrayList<AndroidPackage> libraryConsumers;
public void setError(int code, String msg) {
setReturnCode(code);
@@ -15013,123 +14865,39 @@ public class PackageManagerService extends IPackageManager.Stub
}
}
- /**
- * Checks whether the parent or any of the child packages have a change shared
- * user. For a package to be a valid update the shred users of the parent and
- * the children should match. We may later support changing child shared users.
- * @param oldPkg The updated package.
- * @param newPkg The update package.
- * @return The shared user that change between the versions.
- */
- private String getParentOrChildPackageChangedSharedUser(PackageParser.Package oldPkg,
- PackageParser.Package newPkg) {
- // Check parent shared user
- if (!Objects.equals(oldPkg.mSharedUserId, newPkg.mSharedUserId)) {
- return newPkg.packageName;
- }
- // Check child shared users
- final int oldChildCount = (oldPkg.childPackages != null) ? oldPkg.childPackages.size() : 0;
- final int newChildCount = (newPkg.childPackages != null) ? newPkg.childPackages.size() : 0;
- for (int i = 0; i < newChildCount; i++) {
- PackageParser.Package newChildPkg = newPkg.childPackages.get(i);
- // If this child was present, did it have the same shared user?
- for (int j = 0; j < oldChildCount; j++) {
- PackageParser.Package oldChildPkg = oldPkg.childPackages.get(j);
- if (newChildPkg.packageName.equals(oldChildPkg.packageName)
- && !Objects.equals(newChildPkg.mSharedUserId, oldChildPkg.mSharedUserId)) {
- return newChildPkg.packageName;
- }
- }
- }
- return null;
- }
-
private void removeNativeBinariesLI(PackageSetting ps) {
- // Remove the lib path for the parent package
if (ps != null) {
NativeLibraryHelper.removeNativeBinariesLI(ps.legacyNativeLibraryPathString);
- // Remove the lib path for the child packages
- final int childCount = (ps.childPackageNames != null) ? ps.childPackageNames.size() : 0;
- for (int i = 0; i < childCount; i++) {
- PackageSetting childPs = null;
- synchronized (mLock) {
- childPs = mSettings.getPackageLPr(ps.childPackageNames.get(i));
- }
- if (childPs != null) {
- NativeLibraryHelper.removeNativeBinariesLI(childPs
- .legacyNativeLibraryPathString);
- }
- }
- }
- }
-
- @GuardedBy("mLock")
- private void enableSystemPackageLPw(PackageParser.Package pkg) {
- // Enable the parent package
- mSettings.enableSystemPackageLPw(pkg.packageName);
- // Enable the child packages
- final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
- for (int i = 0; i < childCount; i++) {
- PackageParser.Package childPkg = pkg.childPackages.get(i);
- mSettings.enableSystemPackageLPw(childPkg.packageName);
}
}
@GuardedBy("mLock")
- private boolean disableSystemPackageLPw(PackageParser.Package oldPkg,
- PackageParser.Package newPkg) {
- // Disable the parent package (parent always replaced)
- boolean disabled = mSettings.disableSystemPackageLPw(oldPkg.packageName, true);
- // Disable the child packages
- final int childCount = (oldPkg.childPackages != null) ? oldPkg.childPackages.size() : 0;
- for (int i = 0; i < childCount; i++) {
- PackageParser.Package childPkg = oldPkg.childPackages.get(i);
- final boolean replace = newPkg.hasChildPackage(childPkg.packageName);
- disabled |= mSettings.disableSystemPackageLPw(childPkg.packageName, replace);
- }
- return disabled;
+ private void enableSystemPackageLPw(AndroidPackage pkg) {
+ mSettings.enableSystemPackageLPw(pkg.getPackageName());
}
@GuardedBy("mLock")
- private void setInstallerPackageNameLPw(PackageParser.Package pkg,
- String installerPackageName) {
- // Enable the parent package
- mSettings.setInstallerPackageName(pkg.packageName, installerPackageName);
- // Enable the child packages
- final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
- for (int i = 0; i < childCount; i++) {
- PackageParser.Package childPkg = pkg.childPackages.get(i);
- mSettings.setInstallerPackageName(childPkg.packageName, installerPackageName);
- }
+ private boolean disableSystemPackageLPw(AndroidPackage oldPkg) {
+ return mSettings.disableSystemPackageLPw(oldPkg.getPackageName(), true);
}
- private void updateSettingsLI(PackageParser.Package newPackage, String installerPackageName,
+ private void updateSettingsLI(AndroidPackage newPackage, String installerPackageName,
int[] allUsers, PackageInstalledInfo res, UserHandle user, int installReason) {
- // Update the parent package setting
updateSettingsInternalLI(newPackage, installerPackageName, allUsers, res.origUsers,
res, user, installReason);
- // Update the child packages setting
- final int childCount = (newPackage.childPackages != null)
- ? newPackage.childPackages.size() : 0;
- for (int i = 0; i < childCount; i++) {
- PackageParser.Package childPackage = newPackage.childPackages.get(i);
- PackageInstalledInfo childRes = res.addedChildPackages.get(childPackage.packageName);
- updateSettingsInternalLI(childPackage, installerPackageName, allUsers,
- childRes.origUsers, childRes, user, installReason);
- }
}
- private void updateSettingsInternalLI(PackageParser.Package pkg,
+ private void updateSettingsInternalLI(AndroidPackage pkg,
String installerPackageName, int[] allUsers, int[] installedForUsers,
PackageInstalledInfo res, UserHandle user, int installReason) {
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "updateSettings");
- final String pkgName = pkg.packageName;
+ final String pkgName = pkg.getPackageName();
- if (DEBUG_INSTALL) Slog.d(TAG, "New package installed in " + pkg.codePath);
+ if (DEBUG_INSTALL) Slog.d(TAG, "New package installed in " + pkg.getCodePath());
synchronized (mLock) {
// NOTE: This changes slightly to include UPDATE_PERMISSIONS_ALL regardless of the size of pkg.permissions
- mPermissionManager.updatePermissions(pkg.packageName, pkg);
+ mPermissionManager.updatePermissions(pkg.getPackageName(), pkg);
// For system-bundled packages, we assume that installing an upgraded version
// of the package implies that the user actually wants to run that new code,
// so we enable the package.
@@ -15196,7 +14964,7 @@ public class PackageManagerService extends IPackageManager.Stub
mSettings.writeKernelMappingLPr(ps);
}
res.name = pkgName;
- res.uid = pkg.applicationInfo.uid;
+ res.uid = pkg.getUid();
res.pkg = pkg;
mSettings.setInstallerPackageName(pkgName, installerPackageName);
res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
@@ -15254,7 +15022,7 @@ public class PackageManagerService extends IPackageManager.Stub
private static class ReconcileRequest {
public final Map<String, ScanResult> scannedPackages;
- public final Map<String, PackageParser.Package> allPackages;
+ public final Map<String, AndroidPackage> allPackages;
public final Map<String, LongSparseArray<SharedLibraryInfo>> sharedLibrarySource;
public final Map<String, InstallArgs> installArgs;
public final Map<String, PackageInstalledInfo> installResults;
@@ -15267,7 +15035,7 @@ public class PackageManagerService extends IPackageManager.Stub
Map<String, PackageInstalledInfo> installResults,
Map<String, PrepareResult> preparedPackages,
Map<String, LongSparseArray<SharedLibraryInfo>> sharedLibrarySource,
- Map<String, PackageParser.Package> allPackages,
+ Map<String, AndroidPackage> allPackages,
Map<String, VersionInfo> versionInfos,
Map<String, PackageSetting> lastStaticSharedLibSettings) {
this.scannedPackages = scannedPackages;
@@ -15282,7 +15050,7 @@ public class PackageManagerService extends IPackageManager.Stub
private ReconcileRequest(Map<String, ScanResult> scannedPackages,
Map<String, LongSparseArray<SharedLibraryInfo>> sharedLibrarySource,
- Map<String, PackageParser.Package> allPackages,
+ Map<String, AndroidPackage> allPackages,
Map<String, VersionInfo> versionInfos,
Map<String, PackageSetting> lastStaticSharedLibSettings) {
this(scannedPackages, Collections.emptyMap(), Collections.emptyMap(),
@@ -15350,15 +15118,17 @@ public class PackageManagerService extends IPackageManager.Stub
* with the package(s) currently being installed. The to-be installed packages take
* precedence and may shadow already installed packages.
*/
- private Map<String, PackageParser.Package> getCombinedPackages() {
- final ArrayMap<String, PackageParser.Package> combinedPackages =
+ private Map<String, AndroidPackage> getCombinedAvailablePackages() {
+ final ArrayMap<String, AndroidPackage> combined =
new ArrayMap<>(request.allPackages.size() + request.scannedPackages.size());
- combinedPackages.putAll(request.allPackages);
+ combined.putAll(request.allPackages);
+
for (ScanResult scanResult : request.scannedPackages.values()) {
- combinedPackages.put(scanResult.pkgSetting.name, scanResult.request.pkg);
+ combined.put(scanResult.pkgSetting.name, scanResult.request.parsedPackage);
}
- return combinedPackages;
+
+ return combined;
}
}
@@ -15371,8 +15141,9 @@ public class PackageManagerService extends IPackageManager.Stub
final Map<String, ReconciledPackage> result = new ArrayMap<>(scannedPackages.size());
// make a copy of the existing set of packages so we can combine them with incoming packages
- final ArrayMap<String, PackageParser.Package> combinedPackages =
+ final ArrayMap<String, AndroidPackage> combinedPackages =
new ArrayMap<>(request.allPackages.size() + scannedPackages.size());
+
combinedPackages.putAll(request.allPackages);
final Map<String, LongSparseArray<SharedLibraryInfo>> incomingSharedLibraries =
@@ -15382,7 +15153,7 @@ public class PackageManagerService extends IPackageManager.Stub
final ScanResult scanResult = scannedPackages.get(installPackageName);
// add / replace existing with incoming packages
- combinedPackages.put(scanResult.pkgSetting.name, scanResult.request.pkg);
+ combinedPackages.put(scanResult.pkgSetting.name, scanResult.request.parsedPackage);
// in the first pass, we'll build up the set of incoming shared libraries
final List<SharedLibraryInfo> allowedSharedLibInfos =
@@ -15415,7 +15186,7 @@ public class PackageManagerService extends IPackageManager.Stub
| (killApp ? 0 : PackageManager.DELETE_DONT_KILL_APP);
deletePackageAction = mayDeletePackageLocked(res.removedInfo,
prepareResult.originalPs, prepareResult.disabledPs,
- prepareResult.childPackageSettings, deleteFlags, null /* all users */);
+ deleteFlags, null /* all users */);
if (deletePackageAction == null) {
throw new ReconcileFailure(
PackageManager.INSTALL_FAILED_REPLACE_COULDNT_DELETE,
@@ -15427,7 +15198,7 @@ public class PackageManagerService extends IPackageManager.Stub
final int scanFlags = scanResult.request.scanFlags;
final int parseFlags = scanResult.request.parseFlags;
- final PackageParser.Package pkg = scanResult.request.pkg;
+ final ParsedPackage parsedPackage = scanResult.request.parsedPackage;
final PackageSetting disabledPkgSetting = scanResult.request.disabledPkgSetting;
final PackageSetting lastStaticSharedLibSetting =
@@ -15440,35 +15211,37 @@ public class PackageManagerService extends IPackageManager.Stub
boolean sharedUserSignaturesChanged = false;
SigningDetails signingDetails = null;
if (ksms.shouldCheckUpgradeKeySetLocked(signatureCheckPs, scanFlags)) {
- if (ksms.checkUpgradeKeySetLocked(signatureCheckPs, pkg)) {
+ if (ksms.checkUpgradeKeySetLocked(signatureCheckPs, parsedPackage)) {
// We just determined the app is signed correctly, so bring
// over the latest parsed certs.
} else {
if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
throw new ReconcileFailure(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
- "Package " + pkg.packageName + " upgrade keys do not match the "
- + "previously installed version");
+ "Package " + parsedPackage.getPackageName()
+ + " upgrade keys do not match the previously installed"
+ + " version");
} else {
- String msg = "System package " + pkg.packageName
+ String msg = "System package " + parsedPackage.getPackageName()
+ " signature changed; retaining data.";
reportSettingsProblem(Log.WARN, msg);
}
}
- signingDetails = pkg.mSigningDetails;
+ signingDetails = parsedPackage.getSigningDetails();
} else {
try {
final VersionInfo versionInfo = request.versionInfos.get(installPackageName);
final boolean compareCompat = isCompatSignatureUpdateNeeded(versionInfo);
final boolean compareRecover = isRecoverSignatureUpdateNeeded(versionInfo);
final boolean compatMatch = verifySignatures(signatureCheckPs,
- disabledPkgSetting, pkg.mSigningDetails, compareCompat, compareRecover);
+ disabledPkgSetting, parsedPackage.getSigningDetails(), compareCompat,
+ compareRecover);
// The new KeySets will be re-added later in the scanning process.
if (compatMatch) {
removeAppKeySetData = true;
}
// We just determined the app is signed correctly, so bring
// over the latest parsed certs.
- signingDetails = pkg.mSigningDetails;
+ signingDetails = parsedPackage.getSigningDetails();
// if this is is a sharedUser, check to see if the new package is signed by a
@@ -15476,10 +15249,10 @@ public class PackageManagerService extends IPackageManager.Stub
// signing certificate than the existing one, and if so, copy over the new
// details
if (signatureCheckPs.sharedUser != null) {
- if (pkg.mSigningDetails.hasAncestor(
+ if (parsedPackage.getSigningDetails().hasAncestor(
signatureCheckPs.sharedUser.signatures.mSigningDetails)) {
signatureCheckPs.sharedUser.signatures.mSigningDetails =
- pkg.mSigningDetails;
+ parsedPackage.getSigningDetails();
}
if (signatureCheckPs.sharedUser.signaturesChanged == null) {
signatureCheckPs.sharedUser.signaturesChanged = Boolean.FALSE;
@@ -15489,7 +15262,7 @@ public class PackageManagerService extends IPackageManager.Stub
if ((parseFlags & PackageParser.PARSE_IS_SYSTEM_DIR) == 0) {
throw new ReconcileFailure(e);
}
- signingDetails = pkg.mSigningDetails;
+ signingDetails = parsedPackage.getSigningDetails();
// If the system app is part of a shared user we allow that shared user to
// change
@@ -15504,7 +15277,7 @@ public class PackageManagerService extends IPackageManager.Stub
signatureCheckPs.sharedUser.signatures.mSigningDetails.signatures;
if (signatureCheckPs.sharedUser.signaturesChanged != null
&& compareSignatures(sharedUserSignatures,
- pkg.mSigningDetails.signatures)
+ parsedPackage.getSigningDetails().signatures)
!= PackageManager.SIGNATURE_MATCH) {
if (SystemProperties.getInt("ro.product.first_api_level", 0) <= 29) {
// Mismatched signatures is an error and silently skipping system
@@ -15524,18 +15297,19 @@ public class PackageManagerService extends IPackageManager.Stub
// whichever package happened to be scanned later.
throw new IllegalStateException(
"Signature mismatch on system package "
- + pkg.packageName + " for shared user "
+ + parsedPackage.getPackageName()
+ + " for shared user "
+ scanResult.pkgSetting.sharedUser);
}
}
sharedUserSignaturesChanged = true;
signatureCheckPs.sharedUser.signatures.mSigningDetails =
- pkg.mSigningDetails;
+ parsedPackage.getSigningDetails();
signatureCheckPs.sharedUser.signaturesChanged = Boolean.TRUE;
}
// File a report about this.
- String msg = "System package " + pkg.packageName
+ String msg = "System package " + parsedPackage.getPackageName()
+ " signature changed; retaining data.";
reportSettingsProblem(Log.WARN, msg);
} catch (IllegalArgumentException e) {
@@ -15569,8 +15343,9 @@ public class PackageManagerService extends IPackageManager.Stub
}
try {
result.get(installPackageName).collectedSharedLibraryInfos =
- collectSharedLibraryInfos(scanResult.request.pkg, combinedPackages,
- request.sharedLibrarySource, incomingSharedLibraries);
+ collectSharedLibraryInfos(scanResult.request.parsedPackage,
+ combinedPackages, request.sharedLibrarySource,
+ incomingSharedLibraries);
} catch (PackageManagerException e) {
throw new ReconcileFailure(e.error, e.getMessage());
@@ -15588,7 +15363,7 @@ public class PackageManagerService extends IPackageManager.Stub
ScanResult scanResult,
Map<String, LongSparseArray<SharedLibraryInfo>> existingSharedLibraries) {
// Let's used the parsed package as scanResult.pkgSetting may be null
- final PackageParser.Package pkg = scanResult.request.pkg;
+ final ParsedPackage parsedPackage = scanResult.request.parsedPackage;
if (scanResult.staticSharedLibraryInfo == null
&& scanResult.dynamicSharedLibraryInfos == null) {
return null;
@@ -15599,12 +15374,12 @@ public class PackageManagerService extends IPackageManager.Stub
return Collections.singletonList(scanResult.staticSharedLibraryInfo);
}
final boolean hasDynamicLibraries =
- (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0
+ (parsedPackage.getFlags() & ApplicationInfo.FLAG_SYSTEM) != 0
&& scanResult.dynamicSharedLibraryInfos != null;
if (!hasDynamicLibraries) {
return null;
}
- final boolean isUpdatedSystemApp = pkg.isUpdatedSystemApp();
+ final boolean isUpdatedSystemApp = parsedPackage.isUpdatedSystemApp();
// We may not yet have disabled the updated package yet, so be sure to grab the
// current setting if that's the case.
final PackageSetting updatedSystemPs = isUpdatedSystemApp
@@ -15613,9 +15388,9 @@ public class PackageManagerService extends IPackageManager.Stub
: scanResult.request.disabledPkgSetting
: null;
if (isUpdatedSystemApp && (updatedSystemPs.pkg == null
- || updatedSystemPs.pkg.libraryNames == null)) {
- Slog.w(TAG, "Package " + pkg.packageName + " declares libraries that are not "
- + "declared on the system image; skipping");
+ || updatedSystemPs.pkg.getLibraryNames() == null)) {
+ Slog.w(TAG, "Package " + parsedPackage.getPackageName()
+ + " declares libraries that are not declared on the system image; skipping");
return null;
}
final ArrayList<SharedLibraryInfo> infos =
@@ -15633,16 +15408,17 @@ public class PackageManagerService extends IPackageManager.Stub
// with it. Better to just have the restriction here, be
// conservative, and create many fewer cases that can negatively
// impact the user experience.
- if (!updatedSystemPs.pkg.libraryNames.contains(name)) {
- Slog.w(TAG, "Package " + pkg.packageName + " declares library " + name
+ if (!updatedSystemPs.pkg.getLibraryNames().contains(name)) {
+ Slog.w(TAG, "Package " + parsedPackage.getPackageName()
+ + " declares library " + name
+ " that is not declared on system image; skipping");
continue;
}
}
if (sharedLibExists(
name, SharedLibraryInfo.VERSION_UNDEFINED, existingSharedLibraries)) {
- Slog.w(TAG, "Package " + pkg.packageName + " declares library " + name
- + " that already exists; skipping");
+ Slog.w(TAG, "Package " + parsedPackage.getPackageName() + " declares library "
+ + name + " that already exists; skipping");
continue;
}
infos.add(info);
@@ -15680,68 +15456,38 @@ public class PackageManagerService extends IPackageManager.Stub
for (ReconciledPackage reconciledPkg : request.reconciledPackages.values()) {
final ScanResult scanResult = reconciledPkg.scanResult;
final ScanRequest scanRequest = scanResult.request;
- final PackageParser.Package pkg = scanRequest.pkg;
- final String packageName = pkg.packageName;
+ final ParsedPackage parsedPackage = scanRequest.parsedPackage;
+ final String packageName = parsedPackage.getPackageName();
final PackageInstalledInfo res = reconciledPkg.installResult;
if (reconciledPkg.prepareResult.replace) {
- PackageParser.Package oldPackage = mPackages.get(packageName);
+ AndroidPackage oldPackage = mPackages.get(packageName);
// Set the update and install times
- PackageSetting deletedPkgSetting = (PackageSetting) oldPackage.mExtras;
- setInstallAndUpdateTime(pkg, deletedPkgSetting.firstInstallTime,
- System.currentTimeMillis());
+ PackageSetting deletedPkgSetting = getPackageSetting(oldPackage.getPackageName());
+ reconciledPkg.pkgSetting.firstInstallTime = deletedPkgSetting.firstInstallTime;
+ reconciledPkg.pkgSetting.lastUpdateTime = System.currentTimeMillis();
if (reconciledPkg.prepareResult.system) {
// Remove existing system package
removePackageLI(oldPackage, true);
- if (!disableSystemPackageLPw(oldPackage, pkg)) {
+ if (!disableSystemPackageLPw(oldPackage)) {
// We didn't need to disable the .apk as a current system package,
// which means we are replacing another update that is already
// installed. We need to make sure to delete the older one's .apk.
res.removedInfo.args = createInstallArgsForExisting(
- oldPackage.applicationInfo.getCodePath(),
- oldPackage.applicationInfo.getResourcePath(),
- getAppDexInstructionSets(oldPackage.applicationInfo));
+ oldPackage.getAppInfoCodePath(),
+ oldPackage.getAppInfoResourcePath(),
+ getAppDexInstructionSets(oldPackage.getPrimaryCpuAbi(),
+ oldPackage.getSecondaryCpuAbi()));
} else {
res.removedInfo.args = null;
}
-
- // Update the package dynamic state if succeeded
- // Now that the install succeeded make sure we remove data
- // directories for any child package the update removed.
- final int deletedChildCount = (oldPackage.childPackages != null)
- ? oldPackage.childPackages.size() : 0;
- final int newChildCount = (pkg.childPackages != null)
- ? pkg.childPackages.size() : 0;
- for (int i = 0; i < deletedChildCount; i++) {
- PackageParser.Package deletedChildPkg = oldPackage.childPackages.get(i);
- boolean childPackageDeleted = true;
- for (int j = 0; j < newChildCount; j++) {
- PackageParser.Package newChildPkg = pkg.childPackages.get(j);
- if (deletedChildPkg.packageName.equals(newChildPkg.packageName)) {
- childPackageDeleted = false;
- break;
- }
- }
- if (childPackageDeleted) {
- PackageSetting ps1 = mSettings.getDisabledSystemPkgLPr(
- deletedChildPkg.packageName);
- if (ps1 != null && res.removedInfo.removedChildPackages != null) {
- PackageRemovedInfo removedChildRes = res.removedInfo
- .removedChildPackages.get(deletedChildPkg.packageName);
- removePackageDataLIF(ps1, request.mAllUsers, removedChildRes, 0,
- false);
- removedChildRes.removedForAllUsers = mPackages.get(ps1.name)
- == null;
- }
- }
- }
} else {
try {
// Settings will be written during the call to updateSettingsLI().
executeDeletePackageLIF(reconciledPkg.deletePackageAction, packageName,
- true, request.mAllUsers, false, pkg);
+ true, request.mAllUsers, false, parsedPackage);
} catch (SystemDeleteException e) {
if (Build.IS_ENG) {
throw new RuntimeException("Unexpected failure", e);
@@ -15757,62 +15503,40 @@ public class PackageManagerService extends IPackageManager.Stub
Slog.i(TAG, "upgrading pkg " + oldPackage
+ " is ASEC-hosted -> UNAVAILABLE");
}
- final int[] uidArray = new int[]{oldPackage.applicationInfo.uid};
+ final int[] uidArray = new int[]{oldPackage.getUid()};
final ArrayList<String> pkgList = new ArrayList<>(1);
- pkgList.add(oldPackage.applicationInfo.packageName);
+ pkgList.add(oldPackage.getAppInfoPackageName());
sendResourcesChangedBroadcast(false, true, pkgList, uidArray, null);
}
// Update the in-memory copy of the previous code paths.
PackageSetting ps1 = mSettings.mPackages.get(
- reconciledPkg.prepareResult.existingPackage.packageName);
+ reconciledPkg.prepareResult.existingPackage.getPackageName());
if ((reconciledPkg.installArgs.installFlags & PackageManager.DONT_KILL_APP)
== 0) {
if (ps1.mOldCodePaths == null) {
ps1.mOldCodePaths = new ArraySet<>();
}
- Collections.addAll(ps1.mOldCodePaths, oldPackage.baseCodePath);
- if (oldPackage.splitCodePaths != null) {
- Collections.addAll(ps1.mOldCodePaths, oldPackage.splitCodePaths);
+ Collections.addAll(ps1.mOldCodePaths, oldPackage.getBaseCodePath());
+ if (oldPackage.getSplitCodePaths() != null) {
+ Collections.addAll(ps1.mOldCodePaths, oldPackage.getSplitCodePaths());
}
} else {
ps1.mOldCodePaths = null;
}
- if (ps1.childPackageNames != null) {
- for (int i = ps1.childPackageNames.size() - 1; i >= 0; --i) {
- final String childPkgName = ps1.childPackageNames.get(i);
- final PackageSetting childPs = mSettings.mPackages.get(childPkgName);
- childPs.mOldCodePaths = ps1.mOldCodePaths;
- }
- }
if (reconciledPkg.installResult.returnCode
== PackageManager.INSTALL_SUCCEEDED) {
- PackageSetting ps2 = mSettings.getPackageLPr(pkg.packageName);
+ PackageSetting ps2 = mSettings.getPackageLPr(
+ parsedPackage.getPackageName());
if (ps2 != null) {
res.removedInfo.removedForAllUsers = mPackages.get(ps2.name) == null;
- if (res.removedInfo.removedChildPackages != null) {
- final int childCount1 = res.removedInfo.removedChildPackages.size();
- // Iterate in reverse as we may modify the collection
- for (int i = childCount1 - 1; i >= 0; i--) {
- String childPackageName =
- res.removedInfo.removedChildPackages.keyAt(i);
- if (res.addedChildPackages.containsKey(childPackageName)) {
- res.removedInfo.removedChildPackages.removeAt(i);
- } else {
- PackageRemovedInfo childInfo = res.removedInfo
- .removedChildPackages.valueAt(i);
- childInfo.removedForAllUsers = mPackages.get(
- childInfo.removedPackage) == null;
- }
- }
- }
}
}
}
}
- commitReconciledScanResultLocked(reconciledPkg);
+ AndroidPackage pkg = commitReconciledScanResultLocked(reconciledPkg);
updateSettingsLI(pkg, reconciledPkg.installArgs.installerPackageName, request.mAllUsers,
res, reconciledPkg.installArgs.user, reconciledPkg.installArgs.installReason);
@@ -15821,17 +15545,6 @@ public class PackageManagerService extends IPackageManager.Stub
res.newUsers = ps.queryInstalledUsers(mUserManager.getUserIds(), true);
ps.setUpdateAvailable(false /*updateAvailable*/);
}
- final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
- for (int i = 0; i < childCount; i++) {
- PackageParser.Package childPkg = pkg.childPackages.get(i);
- PackageInstalledInfo childRes = res.addedChildPackages.get(
- childPkg.packageName);
- PackageSetting childPs = mSettings.getPackageLPr(childPkg.packageName);
- if (childPs != null) {
- childRes.newUsers = childPs.queryInstalledUsers(
- mUserManager.getUserIds(), true);
- }
- }
if (res.returnCode == PackageManager.INSTALL_SUCCEEDED) {
updateSequenceNumberLP(ps, res.newUsers);
updateInstantAppInstallerLocked(packageName);
@@ -15891,33 +15604,31 @@ public class PackageManagerService extends IPackageManager.Stub
request.installResult.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
request.installResult.installerPackageName = request.args.installerPackageName;
- final String packageName = prepareResult.packageToScan.packageName;
+ final String packageName = prepareResult.packageToScan.getPackageName();
prepareResults.put(packageName, prepareResult);
installResults.put(packageName, request.installResult);
installArgs.put(packageName, request.args);
try {
- final List<ScanResult> scanResults = scanPackageTracedLI(
+ final ScanResult result = scanPackageTracedLI(
prepareResult.packageToScan, prepareResult.parseFlags,
prepareResult.scanFlags, System.currentTimeMillis(),
request.args.user);
- for (ScanResult result : scanResults) {
- if (null != preparedScans.put(result.pkgSetting.pkg.packageName, result)) {
- request.installResult.setError(
- PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE,
- "Duplicate package " + result.pkgSetting.pkg.packageName
- + " in multi-package install request.");
- return;
- }
- createdAppId.put(packageName, optimisticallyRegisterAppId(result));
- versionInfos.put(result.pkgSetting.pkg.packageName,
- getSettingsVersionForPackage(result.pkgSetting.pkg));
- if (result.staticSharedLibraryInfo != null) {
- final PackageSetting sharedLibLatestVersionSetting =
- getSharedLibLatestVersionSetting(result);
- if (sharedLibLatestVersionSetting != null) {
- lastStaticSharedLibSettings.put(result.pkgSetting.pkg.packageName,
- sharedLibLatestVersionSetting);
- }
+ if (null != preparedScans.put(result.pkgSetting.pkg.getPackageName(), result)) {
+ request.installResult.setError(
+ PackageManager.INSTALL_FAILED_DUPLICATE_PACKAGE,
+ "Duplicate package " + result.pkgSetting.pkg.getPackageName()
+ + " in multi-package install request.");
+ return;
+ }
+ createdAppId.put(packageName, optimisticallyRegisterAppId(result));
+ versionInfos.put(result.pkgSetting.pkg.getPackageName(),
+ getSettingsVersionForPackage(result.pkgSetting.pkg));
+ if (result.staticSharedLibraryInfo != null) {
+ final PackageSetting sharedLibLatestVersionSetting =
+ getSharedLibLatestVersionSetting(result);
+ if (sharedLibLatestVersionSetting != null) {
+ lastStaticSharedLibSettings.put(result.pkgSetting.pkg.getPackageName(),
+ sharedLibLatestVersionSetting);
}
}
} catch (PackageManagerException e) {
@@ -15960,7 +15671,8 @@ public class PackageManagerService extends IPackageManager.Stub
} finally {
if (!success) {
for (ScanResult result : preparedScans.values()) {
- if (createdAppId.getOrDefault(result.request.pkg.packageName, false)) {
+ if (createdAppId.getOrDefault(result.request.parsedPackage.getPackageName(),
+ false)) {
cleanUpAppIdCreation(result);
}
}
@@ -15990,16 +15702,16 @@ public class PackageManagerService extends IPackageManager.Stub
for (ReconciledPackage reconciledPkg : commitRequest.reconciledPackages.values()) {
final boolean instantApp = ((reconciledPkg.scanResult.request.scanFlags
& PackageManagerService.SCAN_AS_INSTANT_APP) != 0);
- final PackageParser.Package pkg = reconciledPkg.pkgSetting.pkg;
- final String packageName = pkg.packageName;
+ final AndroidPackage pkg = reconciledPkg.pkgSetting.pkg;
+ final String packageName = pkg.getPackageName();
prepareAppDataAfterInstallLIF(pkg);
if (reconciledPkg.prepareResult.clearCodeCache) {
clearAppDataLIF(pkg, UserHandle.USER_ALL, FLAG_STORAGE_DE | FLAG_STORAGE_CE
| FLAG_STORAGE_EXTERNAL | Installer.FLAG_CLEAR_CODE_CACHE_ONLY);
}
if (reconciledPkg.prepareResult.replace) {
- mDexManager.notifyPackageUpdated(pkg.packageName,
- pkg.baseCodePath, pkg.splitCodePaths);
+ mDexManager.notifyPackageUpdated(pkg.getPackageName(),
+ pkg.getBaseCodePath(), pkg.getSplitCodePaths());
}
// Prepare the application profiles for the new code paths.
@@ -16013,7 +15725,7 @@ public class PackageManagerService extends IPackageManager.Stub
// Check whether we need to dexopt the app.
//
// NOTE: it is IMPORTANT to call dexopt:
- // - after doRename which will sync the package data from PackageParser.Package and
+ // - after doRename which will sync the package data from AndroidPackage and
// its corresponding ApplicationInfo.
// - after installNewPackageLIF or replacePackageLIF which will update result with the
// uid of the application (pkg.applicationInfo.uid).
@@ -16032,7 +15744,7 @@ public class PackageManagerService extends IPackageManager.Stub
final boolean performDexopt =
(!instantApp || Global.getInt(mContext.getContentResolver(),
Global.INSTANT_APP_DEXOPT_ENABLED, 0) != 0)
- && ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0);
+ && ((pkg.getFlags() & ApplicationInfo.FLAG_DEBUGGABLE) == 0);
if (performDexopt) {
// Compile the layout resources.
@@ -16080,8 +15792,8 @@ public class PackageManagerService extends IPackageManager.Stub
public final int scanFlags;
public final int parseFlags;
@Nullable /* The original Package if it is being replaced, otherwise {@code null} */
- public final PackageParser.Package existingPackage;
- public final PackageParser.Package packageToScan;
+ public final AndroidPackage existingPackage;
+ public final ParsedPackage packageToScan;
public final boolean clearCodeCache;
public final boolean system;
/* The original package name if it was changed during an update, otherwise {@code null}. */
@@ -16090,14 +15802,13 @@ public class PackageManagerService extends IPackageManager.Stub
public final PackageFreezer freezer;
public final PackageSetting originalPs;
public final PackageSetting disabledPs;
- public final PackageSetting[] childPackageSettings;
private PrepareResult(int installReason, String volumeUuid,
String installerPackageName, UserHandle user, boolean replace, int scanFlags,
- int parseFlags, PackageParser.Package existingPackage,
- PackageParser.Package packageToScan, boolean clearCodeCache, boolean system,
+ int parseFlags, AndroidPackage existingPackage,
+ ParsedPackage packageToScan, boolean clearCodeCache, boolean system,
String renamedPackage, PackageFreezer freezer, PackageSetting originalPs,
- PackageSetting disabledPs, PackageSetting[] childPackageSettings) {
+ PackageSetting disabledPs) {
this.installReason = installReason;
this.volumeUuid = volumeUuid;
this.installerPackageName = installerPackageName;
@@ -16113,7 +15824,6 @@ public class PackageManagerService extends IPackageManager.Stub
this.freezer = freezer;
this.originalPs = originalPs;
this.disabledPs = disabledPs;
- this.childPackageSettings = childPackageSettings;
}
}
@@ -16194,10 +15904,10 @@ public class PackageManagerService extends IPackageManager.Stub
pp.setCallback(mPackageParserCallback);
Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "parsePackage");
- final PackageParser.Package pkg;
+ ParsedPackage parsedPackage;
try {
- pkg = pp.parsePackage(tmpPackageFile, parseFlags);
- DexMetadataHelper.validatePackageDexMetadata(pkg);
+ parsedPackage = pp.parseParsedPackage(tmpPackageFile, parseFlags, false);
+ DexMetadataHelper.validatePackageDexMetadata(parsedPackage);
} catch (PackageParserException e) {
throw new PrepareFailure("Failed parse during installPackageLI", e);
} finally {
@@ -16206,23 +15916,23 @@ public class PackageManagerService extends IPackageManager.Stub
// Instant apps have several additional install-time checks.
if (instantApp) {
- if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.O) {
- Slog.w(TAG,
- "Instant app package " + pkg.packageName + " does not target at least O");
+ if (parsedPackage.getTargetSdkVersion() < Build.VERSION_CODES.O) {
+ Slog.w(TAG, "Instant app package " + parsedPackage.getPackageName()
+ + " does not target at least O");
throw new PrepareFailure(INSTALL_FAILED_INSTANT_APP_INVALID,
"Instant app package must target at least O");
}
- if (pkg.mSharedUserId != null) {
- Slog.w(TAG, "Instant app package " + pkg.packageName
+ if (parsedPackage.getSharedUserId() != null) {
+ Slog.w(TAG, "Instant app package " + parsedPackage.getPackageName()
+ " may not declare sharedUserId.");
throw new PrepareFailure(INSTALL_FAILED_INSTANT_APP_INVALID,
"Instant app package may not declare a sharedUserId");
}
}
- if (pkg.applicationInfo.isStaticSharedLibrary()) {
+ if (parsedPackage.isStaticSharedLibrary()) {
// Static shared libraries have synthetic package names
- renameStaticSharedLibraryPackage(pkg);
+ renameStaticSharedLibraryPackage(parsedPackage);
// No static shared libs on external storage
if (onExternal) {
@@ -16232,42 +15942,16 @@ public class PackageManagerService extends IPackageManager.Stub
}
}
- // If we are installing a clustered package add results for the children
- if (pkg.childPackages != null) {
- synchronized (mLock) {
- final int childCount = pkg.childPackages.size();
- for (int i = 0; i < childCount; i++) {
- PackageParser.Package childPkg = pkg.childPackages.get(i);
- PackageInstalledInfo childRes = new PackageInstalledInfo();
- childRes.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
- childRes.pkg = childPkg;
- childRes.name = childPkg.packageName;
- PackageSetting childPs = mSettings.getPackageLPr(childPkg.packageName);
- if (childPs != null) {
- childRes.origUsers = childPs.queryInstalledUsers(
- mUserManager.getUserIds(), true);
- }
- if ((mPackages.containsKey(childPkg.packageName))) {
- childRes.removedInfo = new PackageRemovedInfo(this);
- childRes.removedInfo.removedPackage = childPkg.packageName;
- childRes.removedInfo.installerPackageName = childPs.installerPackageName;
- }
- if (res.addedChildPackages == null) {
- res.addedChildPackages = new ArrayMap<>();
- }
- res.addedChildPackages.put(childPkg.packageName, childRes);
- }
- }
- }
-
// If package doesn't declare API override, mark that we have an install
// time CPU ABI override.
- if (TextUtils.isEmpty(pkg.cpuAbiOverride)) {
- pkg.cpuAbiOverride = args.abiOverride;
+ // TODO(b/135203078): Isn't this always true because cpuAbiOverride isn't assigned during
+ // parsing?
+ if (TextUtils.isEmpty(parsedPackage.getCpuAbiOverride())) {
+ parsedPackage.setCpuAbiOverride(args.abiOverride);
}
- String pkgName = res.name = pkg.packageName;
- if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_TEST_ONLY) != 0) {
+ String pkgName = res.name = parsedPackage.getPackageName();
+ if ((parsedPackage.getFlags() & ApplicationInfo.FLAG_TEST_ONLY) != 0) {
if ((installFlags & PackageManager.INSTALL_ALLOW_TEST) == 0) {
throw new PrepareFailure(INSTALL_FAILED_TEST_ONLY, "installPackageLI");
}
@@ -16276,17 +15960,17 @@ public class PackageManagerService extends IPackageManager.Stub
try {
// either use what we've been given or parse directly from the APK
if (args.signingDetails != PackageParser.SigningDetails.UNKNOWN) {
- pkg.setSigningDetails(args.signingDetails);
+ parsedPackage.setSigningDetails(args.signingDetails);
} else {
- PackageParser.collectCertificates(pkg, false /* skipVerify */);
+ ApkParseUtils.collectCertificates(parsedPackage, false /* skipVerify */);
}
} catch (PackageParserException e) {
throw new PrepareFailure("Failed collect during installPackageLI", e);
}
- if (instantApp && pkg.mSigningDetails.signatureSchemeVersion
+ if (instantApp && parsedPackage.getSigningDetails().signatureSchemeVersion
< SignatureSchemeVersion.SIGNING_BLOCK_V2) {
- Slog.w(TAG, "Instant app package " + pkg.packageName
+ Slog.w(TAG, "Instant app package " + parsedPackage.getPackageName()
+ " is not signed with at least APK Signature Scheme v2");
throw new PrepareFailure(INSTALL_FAILED_INSTANT_APP_INVALID,
"Instant app package must be signed with APK Signature Scheme v2 or greater");
@@ -16300,15 +15984,15 @@ public class PackageManagerService extends IPackageManager.Stub
// Check if installing already existing package
if ((installFlags & PackageManager.INSTALL_REPLACE_EXISTING) != 0) {
String oldName = mSettings.getRenamedPackageLPr(pkgName);
- if (pkg.mOriginalPackages != null
- && pkg.mOriginalPackages.contains(oldName)
+ if (parsedPackage.getOriginalPackages() != null
+ && parsedPackage.getOriginalPackages().contains(oldName)
&& mPackages.containsKey(oldName)) {
// This package is derived from an original package,
// and this device has been updating from that original
// name. We must continue using the original name, so
// rename the new package here.
- pkg.setPackageName(oldName);
- pkgName = pkg.packageName;
+ parsedPackage.setPackageName(oldName);
+ pkgName = parsedPackage.getPackageName();
replace = true;
if (DEBUG_INSTALL) {
Slog.d(TAG, "Replacing existing renamed package: oldName="
@@ -16321,43 +16005,27 @@ public class PackageManagerService extends IPackageManager.Stub
if (DEBUG_INSTALL) Slog.d(TAG, "Replace existing pacakge: " + pkgName);
}
- // Child packages are installed through the parent package
- if (pkg.parentPackage != null) {
- throw new PrepareFailure(
- PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME,
- "Package " + pkg.packageName + " is child of package "
- + pkg.parentPackage.parentPackage + ". Child packages "
- + "can be updated only through the parent package.");
- }
-
if (replace) {
// Prevent apps opting out from runtime permissions
- PackageParser.Package oldPackage = mPackages.get(pkgName);
- final int oldTargetSdk = oldPackage.applicationInfo.targetSdkVersion;
- final int newTargetSdk = pkg.applicationInfo.targetSdkVersion;
+ AndroidPackage oldPackage = mPackages.get(pkgName);
+ final int oldTargetSdk = oldPackage.getTargetSdkVersion();
+ final int newTargetSdk = parsedPackage.getTargetSdkVersion();
if (oldTargetSdk > Build.VERSION_CODES.LOLLIPOP_MR1
&& newTargetSdk <= Build.VERSION_CODES.LOLLIPOP_MR1) {
throw new PrepareFailure(
PackageManager.INSTALL_FAILED_PERMISSION_MODEL_DOWNGRADE,
- "Package " + pkg.packageName + " new target SDK " + newTargetSdk
+ "Package " + parsedPackage.getPackageName()
+ + " new target SDK " + newTargetSdk
+ " doesn't support runtime permissions but the old"
+ " target SDK " + oldTargetSdk + " does.");
}
// Prevent persistent apps from being updated
- if (((oldPackage.applicationInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0)
+ if (((oldPackage.getFlags() & ApplicationInfo.FLAG_PERSISTENT) != 0)
&& ((installFlags & PackageManager.INSTALL_STAGED) == 0)) {
throw new PrepareFailure(PackageManager.INSTALL_FAILED_INVALID_APK,
- "Package " + oldPackage.packageName + " is a persistent app. "
+ "Package " + oldPackage.getPackageName() + " is a persistent app. "
+ "Persistent apps are not updateable.");
}
- // Prevent installing of child packages
- if (oldPackage.parentPackage != null) {
- throw new PrepareFailure(
- PackageManager.INSTALL_PARSE_FAILED_BAD_PACKAGE_NAME,
- "Package " + pkg.packageName + " is child of package "
- + oldPackage.parentPackage + ". Child packages "
- + "can be updated only through the parent package.");
- }
}
}
@@ -16370,8 +16038,8 @@ public class PackageManagerService extends IPackageManager.Stub
// of the same package, therefore we need to compare signatures against
// the package setting for the latest library version.
PackageSetting signatureCheckPs = ps;
- if (pkg.applicationInfo.isStaticSharedLibrary()) {
- SharedLibraryInfo libraryInfo = getLatestSharedLibraVersionLPr(pkg);
+ if (parsedPackage.isStaticSharedLibrary()) {
+ SharedLibraryInfo libraryInfo = getLatestSharedLibraVersionLPr(parsedPackage);
if (libraryInfo != null) {
signatureCheckPs = mSettings.getPackageLPr(libraryInfo.getPackageName());
}
@@ -16382,23 +16050,23 @@ public class PackageManagerService extends IPackageManager.Stub
// bail early here before tripping over redefined permissions.
final KeySetManagerService ksms = mSettings.mKeySetManagerService;
if (ksms.shouldCheckUpgradeKeySetLocked(signatureCheckPs, scanFlags)) {
- if (!ksms.checkUpgradeKeySetLocked(signatureCheckPs, pkg)) {
+ if (!ksms.checkUpgradeKeySetLocked(signatureCheckPs, parsedPackage)) {
throw new PrepareFailure(INSTALL_FAILED_UPDATE_INCOMPATIBLE, "Package "
- + pkg.packageName + " upgrade keys do not match the "
+ + parsedPackage.getPackageName() + " upgrade keys do not match the "
+ "previously installed version");
}
} else {
try {
- final boolean compareCompat = isCompatSignatureUpdateNeeded(pkg);
- final boolean compareRecover = isRecoverSignatureUpdateNeeded(pkg);
+ final boolean compareCompat = isCompatSignatureUpdateNeeded(parsedPackage);
+ final boolean compareRecover = isRecoverSignatureUpdateNeeded(
+ parsedPackage);
// We don't care about disabledPkgSetting on install for now.
- final boolean compatMatch = verifySignatures(
- signatureCheckPs, null, pkg.mSigningDetails, compareCompat,
- compareRecover);
+ final boolean compatMatch = verifySignatures(signatureCheckPs, null,
+ parsedPackage.getSigningDetails(), compareCompat, compareRecover);
// The new KeySets will be re-added later in the scanning process.
if (compatMatch) {
synchronized (mLock) {
- ksms.removeAppKeySetDataLPw(pkg.packageName);
+ ksms.removeAppKeySetDataLPw(parsedPackage.getPackageName());
}
}
} catch (PackageManagerException e) {
@@ -16406,27 +16074,25 @@ public class PackageManagerService extends IPackageManager.Stub
}
}
- if (ps.pkg != null && ps.pkg.applicationInfo != null) {
- systemApp = (ps.pkg.applicationInfo.flags &
- ApplicationInfo.FLAG_SYSTEM) != 0;
+ if (ps.pkg != null) {
+ systemApp = (ps.pkg.getFlags() & ApplicationInfo.FLAG_SYSTEM) != 0;
}
res.origUsers = ps.queryInstalledUsers(mUserManager.getUserIds(), true);
}
- int N = pkg.permissions.size();
+ int N = ArrayUtils.size(parsedPackage.getPermissions());
for (int i = N - 1; i >= 0; i--) {
- final PackageParser.Permission perm = pkg.permissions.get(i);
- final BasePermission bp =
- (BasePermission) mPermissionManager.getPermissionTEMP(perm.info.name);
+ final ParsedPermission perm = parsedPackage.getPermissions().get(i);
+ final BasePermission bp = mPermissionManager.getPermissionTEMP(perm.getName());
// Don't allow anyone but the system to define ephemeral permissions.
- if ((perm.info.protectionLevel & PermissionInfo.PROTECTION_FLAG_INSTANT) != 0
+ if ((perm.protectionLevel & PermissionInfo.PROTECTION_FLAG_INSTANT) != 0
&& !systemApp) {
- Slog.w(TAG, "Non-System package " + pkg.packageName
+ Slog.w(TAG, "Non-System package " + parsedPackage.getPackageName()
+ " attempting to delcare ephemeral permission "
- + perm.info.name + "; Removing ephemeral.");
- perm.info.protectionLevel &= ~PermissionInfo.PROTECTION_FLAG_INSTANT;
+ + perm.getName() + "; Removing ephemeral.");
+ perm.protectionLevel &= ~PermissionInfo.PROTECTION_FLAG_INSTANT;
}
// Check whether the newly-scanned package wants to define an already-defined perm
@@ -16438,26 +16104,27 @@ public class PackageManagerService extends IPackageManager.Stub
final String sourcePackageName = bp.getSourcePackageName();
final PackageSettingBase sourcePackageSetting = bp.getSourcePackageSetting();
final KeySetManagerService ksms = mSettings.mKeySetManagerService;
- if (sourcePackageName.equals(pkg.packageName)
+ if (sourcePackageName.equals(parsedPackage.getPackageName())
&& (ksms.shouldCheckUpgradeKeySetLocked(
sourcePackageSetting, scanFlags))) {
- sigsOk = ksms.checkUpgradeKeySetLocked(sourcePackageSetting, pkg);
+ sigsOk = ksms.checkUpgradeKeySetLocked(sourcePackageSetting, parsedPackage);
} else {
// in the event of signing certificate rotation, we need to see if the
// package's certificate has rotated from the current one, or if it is an
// older certificate with which the current is ok with sharing permissions
if (sourcePackageSetting.signatures.mSigningDetails.checkCapability(
- pkg.mSigningDetails,
+ parsedPackage.getSigningDetails(),
PackageParser.SigningDetails.CertCapabilities.PERMISSION)) {
sigsOk = true;
- } else if (pkg.mSigningDetails.checkCapability(
+ } else if (parsedPackage.getSigningDetails().checkCapability(
sourcePackageSetting.signatures.mSigningDetails,
PackageParser.SigningDetails.CertCapabilities.PERMISSION)) {
// the scanned package checks out, has signing certificate rotation
// history, and is newer; bring it over
- sourcePackageSetting.signatures.mSigningDetails = pkg.mSigningDetails;
+ sourcePackageSetting.signatures.mSigningDetails =
+ parsedPackage.getSigningDetails();
sigsOk = true;
} else {
sigsOk = false;
@@ -16469,30 +16136,31 @@ public class PackageManagerService extends IPackageManager.Stub
// redefinitions.
if (!sourcePackageName.equals("android")) {
throw new PrepareFailure(INSTALL_FAILED_DUPLICATE_PERMISSION, "Package "
- + pkg.packageName
+ + parsedPackage.getPackageName()
+ " attempting to redeclare permission "
- + perm.info.name + " already owned by "
+ + perm.getName() + " already owned by "
+ sourcePackageName)
- .conflictsWithExistingPermission(perm.info.name,
+ .conflictsWithExistingPermission(perm.getName(),
sourcePackageName);
} else {
- Slog.w(TAG, "Package " + pkg.packageName
+ Slog.w(TAG, "Package " + parsedPackage.getPackageName()
+ " attempting to redeclare system permission "
- + perm.info.name + "; ignoring new declaration");
- pkg.permissions.remove(i);
+ + perm.getName() + "; ignoring new declaration");
+ parsedPackage.removePermission(i);
}
- } else if (!PLATFORM_PACKAGE_NAME.equals(pkg.packageName)) {
+ } else if (!PLATFORM_PACKAGE_NAME.equals(parsedPackage.getPackageName())) {
// Prevent apps to change protection level to dangerous from any other
// type as this would allow a privilege escalation where an app adds a
// normal/signature permission in other app's group and later redefines
// it as dangerous leading to the group auto-grant.
- if ((perm.info.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE)
+ if ((perm.protectionLevel & PermissionInfo.PROTECTION_MASK_BASE)
== PermissionInfo.PROTECTION_DANGEROUS) {
if (bp != null && !bp.isRuntime()) {
- Slog.w(TAG, "Package " + pkg.packageName + " trying to change a "
- + "non-runtime permission " + perm.info.name
+ Slog.w(TAG, "Package " + parsedPackage.getPackageName()
+ + " trying to change a non-runtime permission "
+ + perm.getName()
+ " to runtime; keeping old protection level");
- perm.info.protectionLevel = bp.getProtectionLevel();
+ perm.protectionLevel = bp.getProtectionLevel();
}
}
}
@@ -16526,8 +16194,8 @@ public class PackageManagerService extends IPackageManager.Stub
// We moved the entire application as-is, so bring over the
// previously derived ABI information.
- pkg.applicationInfo.primaryCpuAbi = ps.primaryCpuAbiString;
- pkg.applicationInfo.secondaryCpuAbi = ps.secondaryCpuAbiString;
+ parsedPackage.setPrimaryCpuAbi(ps.primaryCpuAbiString)
+ .setSecondaryCpuAbi(ps.secondaryCpuAbiString);
}
} else {
@@ -16535,14 +16203,14 @@ public class PackageManagerService extends IPackageManager.Stub
scanFlags |= SCAN_NO_DEX;
try {
- String abiOverride = (TextUtils.isEmpty(pkg.cpuAbiOverride) ?
- args.abiOverride : pkg.cpuAbiOverride);
- final boolean extractNativeLibs = !pkg.isLibrary();
+ String abiOverride = (TextUtils.isEmpty(parsedPackage.getCpuAbiOverride())
+ ? args.abiOverride : parsedPackage.getCpuAbiOverride());
+ final boolean extractNativeLibs = !parsedPackage.isLibrary();
final Pair<PackageAbiHelper.Abis, PackageAbiHelper.NativeLibraryPaths>
derivedAbi = mInjector.getAbiHelper().derivePackageAbi(
- pkg, abiOverride, extractNativeLibs);
- derivedAbi.first.applyTo(pkg);
- derivedAbi.second.applyTo(pkg);
+ parsedPackage, abiOverride, extractNativeLibs);
+ derivedAbi.first.applyTo(parsedPackage);
+ derivedAbi.second.applyTo(parsedPackage);
} catch (PackageManagerException pme) {
Slog.e(TAG, "Error deriving application ABI", pme);
throw new PrepareFailure(INSTALL_FAILED_INTERNAL_ERROR,
@@ -16550,19 +16218,19 @@ public class PackageManagerService extends IPackageManager.Stub
}
}
- if (!args.doRename(res.returnCode, pkg)) {
+ if (!args.doRename(res.returnCode, parsedPackage)) {
throw new PrepareFailure(INSTALL_FAILED_INSUFFICIENT_STORAGE, "Failed rename");
}
try {
- setUpFsVerityIfPossible(pkg);
+ setUpFsVerityIfPossible(parsedPackage);
} catch (InstallerException | IOException | DigestException | NoSuchAlgorithmException e) {
throw new PrepareFailure(INSTALL_FAILED_INTERNAL_ERROR,
"Failed to set up verity: " + e);
}
if (!instantApp) {
- startIntentFilterVerifications(args.user.getIdentifier(), replace, pkg);
+ startIntentFilterVerifications(args.user.getIdentifier(), replace, parsedPackage);
} else {
if (DEBUG_DOMAIN_VERIFICATION) {
Slog.d(TAG, "Not verifying instant app install for app links: " + pkgName);
@@ -16572,7 +16240,7 @@ public class PackageManagerService extends IPackageManager.Stub
freezePackageForInstall(pkgName, installFlags, "installPackageLI");
boolean shouldCloseFreezerBeforeReturn = true;
try {
- final PackageParser.Package existingPackage;
+ final AndroidPackage existingPackage;
String renamedPackage = null;
boolean sysPkg = false;
String targetVolumeUuid = volumeUuid;
@@ -16583,14 +16251,15 @@ public class PackageManagerService extends IPackageManager.Stub
final PackageSetting[] childPackages;
if (replace) {
targetVolumeUuid = null;
- if (pkg.applicationInfo.isStaticSharedLibrary()) {
+ if (parsedPackage.isStaticSharedLibrary()) {
// Static libs have a synthetic package name containing the version
// and cannot be updated as an update would get a new package name,
// unless this is the exact same version code which is useful for
// development.
- PackageParser.Package existingPkg = mPackages.get(pkg.packageName);
+ AndroidPackage existingPkg = mPackages.get(parsedPackage.getPackageName());
if (existingPkg != null
- && existingPkg.getLongVersionCode() != pkg.getLongVersionCode()) {
+ && existingPkg.getLongVersionCode()
+ != parsedPackage.getLongVersionCode()) {
throw new PrepareFailure(INSTALL_FAILED_DUPLICATE_PACKAGE,
"Packages declaring "
+ "static-shared libs cannot be updated");
@@ -16599,8 +16268,8 @@ public class PackageManagerService extends IPackageManager.Stub
final boolean isInstantApp = (scanFlags & SCAN_AS_INSTANT_APP) != 0;
- final PackageParser.Package oldPackage;
- final String pkgName11 = pkg.packageName;
+ final AndroidPackage oldPackage;
+ final String pkgName11 = parsedPackage.getPackageName();
final int[] allUsers;
final int[] installedUsers;
@@ -16608,8 +16277,9 @@ public class PackageManagerService extends IPackageManager.Stub
oldPackage = mPackages.get(pkgName11);
existingPackage = oldPackage;
if (DEBUG_INSTALL) {
+ // TODO(b/135203078): PackageImpl.toString()
Slog.d(TAG,
- "replacePackageLI: new=" + pkg + ", old=" + oldPackage);
+ "replacePackageLI: new=" + parsedPackage + ", old=" + oldPackage);
}
ps = mSettings.mPackages.get(pkgName11);
@@ -16618,17 +16288,18 @@ public class PackageManagerService extends IPackageManager.Stub
// verify signatures are valid
final KeySetManagerService ksms = mSettings.mKeySetManagerService;
if (ksms.shouldCheckUpgradeKeySetLocked(ps, scanFlags)) {
- if (!ksms.checkUpgradeKeySetLocked(ps, pkg)) {
+ if (!ksms.checkUpgradeKeySetLocked(ps, parsedPackage)) {
throw new PrepareFailure(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
"New package not signed by keys specified by upgrade-keysets: "
+ pkgName11);
}
} else {
// default to original signature matching
- if (!pkg.mSigningDetails.checkCapability(oldPackage.mSigningDetails,
+ if (!parsedPackage.getSigningDetails().checkCapability(
+ oldPackage.getSigningDetails(),
SigningDetails.CertCapabilities.INSTALLED_DATA)
- && !oldPackage.mSigningDetails.checkCapability(
- pkg.mSigningDetails,
+ && !oldPackage.getSigningDetails().checkCapability(
+ parsedPackage.getSigningDetails(),
SigningDetails.CertCapabilities.ROLLBACK)) {
throw new PrepareFailure(INSTALL_FAILED_UPDATE_INCOMPATIBLE,
"New package has a different signature: " + pkgName11);
@@ -16636,13 +16307,13 @@ public class PackageManagerService extends IPackageManager.Stub
}
// don't allow a system upgrade unless the upgrade hash matches
- if (oldPackage.restrictUpdateHash != null && oldPackage.isSystem()) {
+ if (oldPackage.getRestrictUpdateHash() != null && oldPackage.isSystem()) {
final byte[] digestBytes;
try {
final MessageDigest digest = MessageDigest.getInstance("SHA-512");
- updateDigest(digest, new File(pkg.baseCodePath));
- if (!ArrayUtils.isEmpty(pkg.splitCodePaths)) {
- for (String path : pkg.splitCodePaths) {
+ updateDigest(digest, new File(parsedPackage.getBaseCodePath()));
+ if (!ArrayUtils.isEmpty(parsedPackage.getSplitCodePaths())) {
+ for (String path : parsedPackage.getSplitCodePaths()) {
updateDigest(digest, new File(path));
}
}
@@ -16651,21 +16322,25 @@ public class PackageManagerService extends IPackageManager.Stub
throw new PrepareFailure(INSTALL_FAILED_INVALID_APK,
"Could not compute hash: " + pkgName11);
}
- if (!Arrays.equals(oldPackage.restrictUpdateHash, digestBytes)) {
+ if (!Arrays.equals(oldPackage.getRestrictUpdateHash(), digestBytes)) {
throw new PrepareFailure(INSTALL_FAILED_INVALID_APK,
"New package fails restrict-update check: " + pkgName11);
}
// retain upgrade restriction
- pkg.restrictUpdateHash = oldPackage.restrictUpdateHash;
+ parsedPackage.setRestrictUpdateHash(oldPackage.getRestrictUpdateHash());
}
// Check for shared user id changes
- String invalidPackageName =
- getParentOrChildPackageChangedSharedUser(oldPackage, pkg);
+ String invalidPackageName = null;
+ if (!Objects.equals(oldPackage.getSharedUserId(),
+ parsedPackage.getSharedUserId())) {
+ invalidPackageName = parsedPackage.getPackageName();
+ }
+
if (invalidPackageName != null) {
throw new PrepareFailure(INSTALL_FAILED_SHARED_USER_INCOMPATIBLE,
"Package " + invalidPackageName + " tried to change user "
- + oldPackage.mSharedUserId);
+ + oldPackage.getSharedUserId());
}
// In case of rollback, remember per-user/profile install state
@@ -16698,10 +16373,10 @@ public class PackageManagerService extends IPackageManager.Stub
// Update what is removed
res.removedInfo = new PackageRemovedInfo(this);
- res.removedInfo.uid = oldPackage.applicationInfo.uid;
- res.removedInfo.removedPackage = oldPackage.packageName;
+ res.removedInfo.uid = oldPackage.getUid();
+ res.removedInfo.removedPackage = oldPackage.getPackageName();
res.removedInfo.installerPackageName = ps.installerPackageName;
- res.removedInfo.isStaticSharedLib = pkg.staticSharedLibName != null;
+ res.removedInfo.isStaticSharedLib = parsedPackage.getStaticSharedLibName() != null;
res.removedInfo.isUpdate = true;
res.removedInfo.origUsers = installedUsers;
res.removedInfo.installReasons = new SparseArray<>(installedUsers.length);
@@ -16710,52 +16385,6 @@ public class PackageManagerService extends IPackageManager.Stub
res.removedInfo.installReasons.put(userId, ps.getInstallReason(userId));
}
- childPackages = mSettings.getChildSettingsLPr(ps);
- if (childPackages != null) {
- for (PackageSetting childPs : childPackages) {
- boolean childPackageUpdated = false;
- PackageParser.Package childPkg = (childPs == null) ? null : childPs.pkg;
- if (res.addedChildPackages != null) {
- PackageInstalledInfo childRes = res.addedChildPackages.get(
- childPkg.packageName);
- if (childRes != null) {
- childRes.removedInfo.uid = childPkg.applicationInfo.uid;
- childRes.removedInfo.removedPackage = childPkg.packageName;
- if (childPs != null) {
- childRes.removedInfo.installerPackageName =
- childPs.installerPackageName;
- }
- childRes.removedInfo.isUpdate = true;
- childRes.removedInfo.installReasons =
- res.removedInfo.installReasons;
- childPackageUpdated = true;
- }
- }
- if (!childPackageUpdated) {
- PackageRemovedInfo childRemovedRes = new PackageRemovedInfo(this);
- childRemovedRes.removedPackage = childPkg.packageName;
- if (childPs != null) {
- childRemovedRes.installerPackageName = childPs.installerPackageName;
- }
- childRemovedRes.isUpdate = false;
- childRemovedRes.dataRemoved = true;
- synchronized (mLock) {
- if (childPs != null) {
- childRemovedRes.origUsers = childPs.queryInstalledUsers(
- allUsers,
- true);
- }
- }
- if (res.removedInfo.removedChildPackages == null) {
- res.removedInfo.removedChildPackages = new ArrayMap<>();
- }
- res.removedInfo.removedChildPackages.put(childPkg.packageName,
- childRemovedRes);
- }
- }
- }
-
-
sysPkg = (isSystemApp(oldPackage));
if (sysPkg) {
// Set the system/privileged/oem/vendor/product flags as needed
@@ -16774,41 +16403,30 @@ public class PackageManagerService extends IPackageManager.Stub
| (odm ? SCAN_AS_ODM : 0);
if (DEBUG_INSTALL) {
- Slog.d(TAG, "replaceSystemPackageLI: new=" + pkg
+ Slog.d(TAG, "replaceSystemPackageLI: new=" + parsedPackage
+ ", old=" + oldPackage);
}
res.setReturnCode(PackageManager.INSTALL_SUCCEEDED);
- pkg.setApplicationInfoFlags(ApplicationInfo.FLAG_UPDATED_SYSTEM_APP,
- ApplicationInfo.FLAG_UPDATED_SYSTEM_APP);
+ parsedPackage.setUpdatedSystemApp(true);
targetParseFlags = systemParseFlags;
targetScanFlags = systemScanFlags;
} else { // non system replace
replace = true;
if (DEBUG_INSTALL) {
Slog.d(TAG,
- "replaceNonSystemPackageLI: new=" + pkg + ", old="
+ "replaceNonSystemPackageLI: new=" + parsedPackage + ", old="
+ oldPackage);
}
-
- String pkgName1 = oldPackage.packageName;
- boolean deletedPkg = true;
- boolean addedPkg = false;
- boolean updatedSettings = false;
-
- final long origUpdateTime = (pkg.mExtras != null)
- ? ((PackageSetting) pkg.mExtras).lastUpdateTime : 0;
-
}
} else { // new package install
ps = null;
- childPackages = null;
disabledPs = null;
replace = false;
existingPackage = null;
// Remember this for later, in case we need to rollback this install
- String pkgName1 = pkg.packageName;
+ String pkgName1 = parsedPackage.getPackageName();
- if (DEBUG_INSTALL) Slog.d(TAG, "installNewPackageLI: " + pkg);
+ if (DEBUG_INSTALL) Slog.d(TAG, "installNewPackageLI: " + parsedPackage);
// TODO(patb): MOVE TO RECONCILE
synchronized (mLock) {
@@ -16835,9 +16453,9 @@ public class PackageManagerService extends IPackageManager.Stub
shouldCloseFreezerBeforeReturn = false;
return new PrepareResult(args.installReason, targetVolumeUuid, installerPackageName,
- args.user, replace, targetScanFlags, targetParseFlags, existingPackage, pkg,
- replace /* clearCodeCache */, sysPkg, renamedPackage, freezer,
- ps, disabledPs, childPackages);
+ args.user, replace, targetScanFlags, targetParseFlags, existingPackage,
+ parsedPackage, replace /* clearCodeCache */, sysPkg, renamedPackage, freezer,
+ ps, disabledPs);
} finally {
if (shouldCloseFreezerBeforeReturn) {
freezer.close();
@@ -16852,7 +16470,7 @@ public class PackageManagerService extends IPackageManager.Stub
* <p>When the feature flag is set to legacy mode, only APK is supported (with some experimental
* kernel patches). In normal mode, all file format can be supported.
*/
- private void setUpFsVerityIfPossible(PackageParser.Package pkg) throws InstallerException,
+ private void setUpFsVerityIfPossible(AndroidPackage pkg) throws InstallerException,
PrepareFailure, IOException, DigestException, NoSuchAlgorithmException {
final boolean standardMode = PackageManagerServiceUtils.isApkVerityEnabled();
final boolean legacyMode = PackageManagerServiceUtils.isLegacyApkVerityEnabled();
@@ -16864,11 +16482,11 @@ public class PackageManagerService extends IPackageManager.Stub
ArrayMap<String, String> fsverityCandidates = new ArrayMap<>();
if (legacyMode) {
synchronized (mLock) {
- final PackageSetting ps = mSettings.mPackages.get(pkg.packageName);
+ final PackageSetting ps = mSettings.mPackages.get(pkg.getPackageName());
if (ps != null && ps.isPrivileged()) {
- fsverityCandidates.put(pkg.baseCodePath, null);
- if (pkg.splitCodePaths != null) {
- for (String splitPath : pkg.splitCodePaths) {
+ fsverityCandidates.put(pkg.getBaseCodePath(), null);
+ if (pkg.getSplitCodePaths() != null) {
+ for (String splitPath : pkg.getSplitCodePaths()) {
fsverityCandidates.put(splitPath, null);
}
}
@@ -16877,16 +16495,17 @@ public class PackageManagerService extends IPackageManager.Stub
} else {
// NB: These files will become only accessible if the signing key is loaded in kernel's
// .fs-verity keyring.
- fsverityCandidates.put(pkg.baseCodePath,
- VerityUtils.getFsveritySignatureFilePath(pkg.baseCodePath));
+ fsverityCandidates.put(pkg.getBaseCodePath(),
+ VerityUtils.getFsveritySignatureFilePath(pkg.getBaseCodePath()));
- final String dmPath = DexMetadataHelper.buildDexMetadataPathForApk(pkg.baseCodePath);
+ final String dmPath = DexMetadataHelper.buildDexMetadataPathForApk(
+ pkg.getBaseCodePath());
if (new File(dmPath).exists()) {
fsverityCandidates.put(dmPath, VerityUtils.getFsveritySignatureFilePath(dmPath));
}
- if (pkg.splitCodePaths != null) {
- for (String path : pkg.splitCodePaths) {
+ if (pkg.getSplitCodePaths() != null) {
+ for (String path : pkg.getSplitCodePaths()) {
fsverityCandidates.put(path, VerityUtils.getFsveritySignatureFilePath(path));
final String splitDmPath = DexMetadataHelper.buildDexMetadataPathForApk(path);
@@ -16940,8 +16559,7 @@ public class PackageManagerService extends IPackageManager.Stub
}
}
- private void startIntentFilterVerifications(int userId, boolean replacing,
- PackageParser.Package pkg) {
+ private void startIntentFilterVerifications(int userId, boolean replacing, AndroidPackage pkg) {
if (mIntentFilterVerifierComponent == null) {
Slog.w(TAG, "No IntentFilter verification will not be done as "
+ "there is no IntentFilterVerifier available!");
@@ -16954,29 +16572,29 @@ public class PackageManagerService extends IPackageManager.Stub
(userId == UserHandle.USER_ALL) ? UserHandle.USER_SYSTEM : userId);
Message msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS);
- msg.obj = new IFVerificationParams(pkg, replacing, userId, verifierUid);
+ msg.obj = new IFVerificationParams(
+ pkg.getPackageName(),
+ hasDomainURLs(pkg),
+ pkg.getActivities(),
+ replacing,
+ userId,
+ verifierUid
+ );
mHandler.sendMessage(msg);
-
- final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
- for (int i = 0; i < childCount; i++) {
- PackageParser.Package childPkg = pkg.childPackages.get(i);
- msg = mHandler.obtainMessage(START_INTENT_FILTER_VERIFICATIONS);
- msg.obj = new IFVerificationParams(childPkg, replacing, userId, verifierUid);
- mHandler.sendMessage(msg);
- }
}
private void verifyIntentFiltersIfNeeded(int userId, int verifierUid, boolean replacing,
- PackageParser.Package pkg) {
- int size = pkg.activities.size();
+ String packageName,
+ boolean hasDomainUrls,
+ List<ParsedActivity> activities) {
+ int size = activities.size();
if (size == 0) {
if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
"No activity, so no need to verify any IntentFilter!");
return;
}
- final boolean hasDomainURLs = hasDomainURLs(pkg);
- if (!hasDomainURLs) {
+ if (!hasDomainUrls) {
if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
"No domain URLs, so no need to verify any IntentFilter!");
return;
@@ -16987,7 +16605,6 @@ public class PackageManagerService extends IPackageManager.Stub
+ " Activities needs verification ...");
int count = 0;
- final String packageName = pkg.packageName;
synchronized (mLock) {
// If this is a new install and we see that we've already run verification for this
@@ -17006,8 +16623,8 @@ public class PackageManagerService extends IPackageManager.Stub
// If any filters need to be verified, then all need to be.
boolean needToVerify = false;
- for (PackageParser.Activity a : pkg.activities) {
- for (ActivityIntentInfo filter : a.intents) {
+ for (ParsedActivity a : activities) {
+ for (ParsedActivityIntentInfo filter : a.intents) {
if (filter.needsVerification() && needsNetworkVerificationLPr(filter)) {
if (DEBUG_DOMAIN_VERIFICATION) {
Slog.d(TAG,
@@ -17021,8 +16638,8 @@ public class PackageManagerService extends IPackageManager.Stub
if (needToVerify) {
final int verificationId = mIntentFilterVerificationToken++;
- for (PackageParser.Activity a : pkg.activities) {
- for (ActivityIntentInfo filter : a.intents) {
+ for (ParsedActivity a : activities) {
+ for (ParsedActivityIntentInfo filter : a.intents) {
if (filter.handlesWebUris(true) && needsNetworkVerificationLPr(filter)) {
if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
"Verification needed for IntentFilter:" + filter.toString());
@@ -17048,9 +16665,8 @@ public class PackageManagerService extends IPackageManager.Stub
}
@GuardedBy("mLock")
- private boolean needsNetworkVerificationLPr(ActivityIntentInfo filter) {
- final ComponentName cn = filter.activity.getComponentName();
- final String packageName = cn.getPackageName();
+ private boolean needsNetworkVerificationLPr(ParsedActivityIntentInfo filter) {
+ final String packageName = filter.getPackageName();
IntentFilterVerificationInfo ivi = mSettings.getIntentFilterVerificationLPr(
packageName);
@@ -17070,45 +16686,45 @@ public class PackageManagerService extends IPackageManager.Stub
}
}
- private static boolean isExternal(PackageParser.Package pkg) {
- return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
+ private static boolean isExternal(AndroidPackage pkg) {
+ return (pkg.getFlags() & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
}
private static boolean isExternal(PackageSetting ps) {
return (ps.pkgFlags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0;
}
- static boolean isSystemApp(PackageParser.Package pkg) {
- return (pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0;
+ static boolean isSystemApp(AndroidPackage pkg) {
+ return (pkg.getFlags() & ApplicationInfo.FLAG_SYSTEM) != 0;
}
- private static boolean isPrivilegedApp(PackageParser.Package pkg) {
- return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0;
+ private static boolean isPrivilegedApp(AndroidPackage pkg) {
+ return (pkg.getPrivateFlags() & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0;
}
- private static boolean isOemApp(PackageParser.Package pkg) {
- return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_OEM) != 0;
+ private static boolean isOemApp(AndroidPackage pkg) {
+ return (pkg.getPrivateFlags() & ApplicationInfo.PRIVATE_FLAG_OEM) != 0;
}
- private static boolean isVendorApp(PackageParser.Package pkg) {
- return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_VENDOR) != 0;
+ private static boolean isVendorApp(AndroidPackage pkg) {
+ return (pkg.getPrivateFlags() & ApplicationInfo.PRIVATE_FLAG_VENDOR) != 0;
}
- private static boolean isProductApp(PackageParser.Package pkg) {
- return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_PRODUCT) != 0;
+ private static boolean isProductApp(AndroidPackage pkg) {
+ return (pkg.getPrivateFlags() & ApplicationInfo.PRIVATE_FLAG_PRODUCT) != 0;
}
- private static boolean isSystemExtApp(PackageParser.Package pkg) {
- return (pkg.applicationInfo.privateFlags
+ private static boolean isSystemExtApp(AndroidPackage pkg) {
+ return (pkg.getPrivateFlags()
& ApplicationInfo.PRIVATE_FLAG_SYSTEM_EXT) != 0;
}
- private static boolean isOdmApp(PackageParser.Package pkg) {
- return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_ODM) != 0;
+ private static boolean isOdmApp(AndroidPackage pkg) {
+ return (pkg.getPrivateFlags() & ApplicationInfo.PRIVATE_FLAG_ODM) != 0;
}
- private static boolean hasDomainURLs(PackageParser.Package pkg) {
- return (pkg.applicationInfo.privateFlags & ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS) != 0;
+ private static boolean hasDomainURLs(AndroidPackage pkg) {
+ return (pkg.getPrivateFlags() & ApplicationInfo.PRIVATE_FLAG_HAS_DOMAIN_URLS) != 0;
}
private static boolean isSystemApp(PackageSetting ps) {
@@ -17119,12 +16735,12 @@ public class PackageManagerService extends IPackageManager.Stub
return (ps.pkgFlags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0;
}
- private VersionInfo getSettingsVersionForPackage(PackageParser.Package pkg) {
+ private VersionInfo getSettingsVersionForPackage(AndroidPackage pkg) {
if (isExternal(pkg)) {
- if (TextUtils.isEmpty(pkg.volumeUuid)) {
+ if (TextUtils.isEmpty(pkg.getVolumeUuid())) {
return mSettings.getExternalVersion();
} else {
- return mSettings.findOrCreateVersion(pkg.volumeUuid);
+ return mSettings.findOrCreateVersion(pkg.getVolumeUuid());
}
} else {
return mSettings.getInternalVersion();
@@ -17132,6 +16748,7 @@ public class PackageManagerService extends IPackageManager.Stub
}
private void deleteTempPackageFiles() {
+ // TODO: Is this used?
final FilenameFilter filter =
(dir, name) -> name.startsWith("vmdl") && name.endsWith(".tmp");
}
@@ -17265,11 +16882,11 @@ public class PackageManagerService extends IPackageManager.Stub
});
}
- private String resolveExternalPackageNameLPr(PackageParser.Package pkg) {
- if (pkg.staticSharedLibName != null) {
- return pkg.manifestPackageName;
+ private String resolveExternalPackageNameLPr(AndroidPackage pkg) {
+ if (pkg.getStaticSharedLibName() != null) {
+ return pkg.getManifestPackageName();
}
- return pkg.packageName;
+ return pkg.getPackageName();
}
@GuardedBy("mLock")
@@ -17476,7 +17093,7 @@ public class PackageManagerService extends IPackageManager.Stub
final PackageSetting uninstalledPs;
final PackageSetting disabledSystemPs;
- final PackageParser.Package pkg;
+ final AndroidPackage pkg;
// for the uninstall-updates case and restricted profiles, remember the per-
// user handle installed state
@@ -17508,9 +17125,9 @@ public class PackageManagerService extends IPackageManager.Stub
allUsers = mUserManager.getUserIds();
- if (pkg != null && pkg.staticSharedLibName != null) {
- SharedLibraryInfo libraryInfo = getSharedLibraryInfoLPr(pkg.staticSharedLibName,
- pkg.staticSharedLibVersion);
+ if (pkg != null && pkg.getStaticSharedLibName() != null) {
+ SharedLibraryInfo libraryInfo = getSharedLibraryInfoLPr(
+ pkg.getStaticSharedLibName(), pkg.getStaticSharedLibVersion());
if (libraryInfo != null) {
for (int currUserId : allUsers) {
if (removeUser != UserHandle.USER_ALL && removeUser != currUserId) {
@@ -17519,7 +17136,7 @@ public class PackageManagerService extends IPackageManager.Stub
List<VersionedPackage> libClientPackages = getPackagesUsingSharedLibraryLPr(
libraryInfo, 0, currUserId);
if (!ArrayUtils.isEmpty(libClientPackages)) {
- Slog.w(TAG, "Not removing package " + pkg.manifestPackageName
+ Slog.w(TAG, "Not removing package " + pkg.getManifestPackageName()
+ " hosting lib " + libraryInfo.getName() + " version "
+ libraryInfo.getLongVersion() + " used by " + libClientPackages
+ " for user " + currUserId);
@@ -17574,13 +17191,13 @@ public class PackageManagerService extends IPackageManager.Stub
if (info.args != null) {
info.args.doPostDeleteLI(true);
}
- final PackageParser.Package stubPkg =
+ final AndroidPackage stubPkg =
(disabledSystemPs == null) ? null : disabledSystemPs.pkg;
- if (stubPkg != null && stubPkg.isStub) {
+ if (stubPkg != null && stubPkg.isStub()) {
synchronized (mLock) {
// restore the enabled state of the stub; the state is overwritten when
// the stub is uninstalled
- final PackageSetting stubPs = mSettings.mPackages.get(stubPkg.packageName);
+ final PackageSetting stubPs = mSettings.mPackages.get(stubPkg.getPackageName());
if (stubPs != null) {
stubPs.setEnabled(origEnabledState, userId, "android");
}
@@ -17589,7 +17206,7 @@ public class PackageManagerService extends IPackageManager.Stub
|| origEnabledState == COMPONENT_ENABLED_STATE_ENABLED) {
if (DEBUG_COMPRESSION) {
Slog.i(TAG, "Enabling system stub after removal; pkg: "
- + stubPkg.packageName);
+ + stubPkg.getPackageName());
}
enableCompressedPackage(stubPkg);
}
@@ -17617,7 +17234,6 @@ public class PackageManagerService extends IPackageManager.Stub
boolean isStaticSharedLib;
// Clean up resources deleted packages.
InstallArgs args = null;
- ArrayMap<String, PackageRemovedInfo> removedChildPackages;
ArrayMap<String, PackageInstalledInfo> appearedChildPackages;
PackageRemovedInfo(PackageSender packageSender) {
@@ -17626,24 +17242,11 @@ public class PackageManagerService extends IPackageManager.Stub
void sendPackageRemovedBroadcasts(boolean killApp) {
sendPackageRemovedBroadcastInternal(killApp);
- final int childCount = removedChildPackages != null ? removedChildPackages.size() : 0;
- for (int i = 0; i < childCount; i++) {
- PackageRemovedInfo childInfo = removedChildPackages.valueAt(i);
- childInfo.sendPackageRemovedBroadcastInternal(killApp);
- }
}
void sendSystemPackageUpdatedBroadcasts() {
if (isRemovedPackageSystemUpdate) {
sendSystemPackageUpdatedBroadcastsInternal();
- final int childCount = (removedChildPackages != null)
- ? removedChildPackages.size() : 0;
- for (int i = 0; i < childCount; i++) {
- PackageRemovedInfo childInfo = removedChildPackages.valueAt(i);
- if (childInfo.isRemovedPackageSystemUpdate) {
- childInfo.sendSystemPackageUpdatedBroadcastsInternal();
- }
- }
}
}
@@ -17755,12 +17358,12 @@ public class PackageManagerService extends IPackageManager.Stub
String packageName = deletedPs.name;
if (DEBUG_REMOVE) Slog.d(TAG, "removePackageDataLI: " + deletedPs);
// Retrieve object to delete permissions for shared user later on
- final PackageParser.Package deletedPkg = deletedPs.pkg;
+ final AndroidPackage deletedPkg = deletedPs.pkg;
if (outInfo != null) {
outInfo.removedPackage = packageName;
outInfo.installerPackageName = deletedPs.installerPackageName;
outInfo.isStaticSharedLib = deletedPkg != null
- && deletedPkg.staticSharedLibName != null;
+ && deletedPkg.getStaticSharedLibName() != null;
outInfo.populateUsers(deletedPs == null ? null
: deletedPs.queryInstalledUsers(mUserManager.getUserIds(), true), deletedPs);
}
@@ -17768,14 +17371,14 @@ public class PackageManagerService extends IPackageManager.Stub
removePackageLI(deletedPs.name, (flags & PackageManager.DELETE_CHATTY) != 0);
if ((flags & PackageManager.DELETE_KEEP_DATA) == 0) {
- final PackageParser.Package resolvedPkg;
+ final AndroidPackage resolvedPkg;
if (deletedPkg != null) {
resolvedPkg = deletedPkg;
} else {
// We don't have a parsed package when it lives on an ejected
// adopted storage device, so fake something together
- resolvedPkg = new PackageParser.Package(deletedPs.name);
- resolvedPkg.setVolumeUuid(deletedPs.volumeUuid);
+ resolvedPkg = PackageImpl.buildFakeForDeletion(deletedPs.name,
+ deletedPs.volumeUuid);
}
destroyAppDataLIF(resolvedPkg, UserHandle.USER_ALL,
FLAG_STORAGE_DE | FLAG_STORAGE_CE | FLAG_STORAGE_EXTERNAL);
@@ -17887,13 +17490,13 @@ public class PackageManagerService extends IPackageManager.Stub
throws SystemDeleteException {
final boolean applyUserRestrictions =
(allUserHandles != null) && outInfo != null && (outInfo.origUsers != null);
- final PackageParser.Package deletedPkg = deletedPs.pkg;
+ final AndroidPackage deletedPkg = deletedPs.pkg;
// Confirm if the system package has been updated
// An updated system app can be deleted. This will also have to restore
// the system pkg from system partition
// reader
final PackageSetting disabledPs = action.disabledPs;
- if (DEBUG_REMOVE) Slog.d(TAG, "deleteSystemPackageLI: newPs=" + deletedPkg.packageName
+ if (DEBUG_REMOVE) Slog.d(TAG, "deleteSystemPackageLI: newPs=" + deletedPkg.getPackageName()
+ " disabledPs=" + disabledPs);
Slog.d(TAG, "Deleting system pkg from data partition");
@@ -17910,21 +17513,6 @@ public class PackageManagerService extends IPackageManager.Stub
if (outInfo != null) {
// Delete the updated package
outInfo.isRemovedPackageSystemUpdate = true;
- if (outInfo.removedChildPackages != null) {
- final int childCount = (deletedPs.childPackageNames != null)
- ? deletedPs.childPackageNames.size() : 0;
- for (int i = 0; i < childCount; i++) {
- String childPackageName = deletedPs.childPackageNames.get(i);
- if (disabledPs.childPackageNames != null && disabledPs.childPackageNames
- .contains(childPackageName)) {
- PackageRemovedInfo childInfo = outInfo.removedChildPackages.get(
- childPackageName);
- if (childInfo != null) {
- childInfo.isRemovedPackageSystemUpdate = true;
- }
- }
- }
- }
}
if (disabledPs.versionCode < deletedPs.versionCode) {
@@ -17936,7 +17524,7 @@ public class PackageManagerService extends IPackageManager.Stub
}
deleteInstalledPackageLIF(deletedPs, true, flags, allUserHandles,
- outInfo, writeSettings, disabledPs.pkg);
+ outInfo, writeSettings);
// writer
synchronized (mLock) {
@@ -17957,16 +17545,16 @@ public class PackageManagerService extends IPackageManager.Stub
outInfo == null ? null : outInfo.origUsers, deletedPs.getPermissionsState(),
writeSettings);
} catch (PackageManagerException e) {
- Slog.w(TAG, "Failed to restore system package:" + deletedPkg.packageName + ": "
+ Slog.w(TAG, "Failed to restore system package:" + deletedPkg.getPackageName() + ": "
+ e.getMessage());
// TODO(patb): can we avoid this; throw would come from scan...
throw new SystemDeleteException(e);
} finally {
- if (disabledPs.pkg.isStub) {
+ if (disabledPs.pkg.isStub()) {
// We've re-installed the stub; make sure it's disabled here. If package was
// originally enabled, we'll install the compressed version of the application
// and re-enable it afterward.
- final PackageSetting stubPs = mSettings.mPackages.get(deletedPkg.packageName);
+ final PackageSetting stubPs = mSettings.mPackages.get(deletedPkg.getPackageName());
if (stubPs != null) {
stubPs.setEnabled(
COMPONENT_ENABLED_STATE_DISABLED, UserHandle.USER_SYSTEM, "android");
@@ -17978,7 +17566,7 @@ public class PackageManagerService extends IPackageManager.Stub
/**
* Installs a package that's already on the system partition.
*/
- private PackageParser.Package installPackageFromSystemLIF(@NonNull String codePathString,
+ private AndroidPackage installPackageFromSystemLIF(@NonNull String codePathString,
@Nullable int[] allUserHandles, @Nullable int[] origUserHandles,
@Nullable PermissionsState origPermissionState, boolean writeSettings)
throws PackageManagerException {
@@ -17999,7 +17587,7 @@ public class PackageManagerService extends IPackageManager.Stub
}
final File codePath = new File(codePathString);
- final PackageParser.Package pkg =
+ final AndroidPackage pkg =
scanPackageTracedLI(codePath, parseFlags, scanFlags, 0 /*currentTime*/, null);
try {
@@ -18013,7 +17601,7 @@ public class PackageManagerService extends IPackageManager.Stub
// writer
synchronized (mLock) {
- PackageSetting ps = mSettings.mPackages.get(pkg.packageName);
+ PackageSetting ps = mSettings.mPackages.get(pkg.getPackageName());
// Propagate the permissions state as we do not want to drop on the floor
// runtime permissions. The update permissions method below will take
@@ -18021,7 +17609,7 @@ public class PackageManagerService extends IPackageManager.Stub
if (origPermissionState != null) {
ps.getPermissionsState().copyFrom(origPermissionState);
}
- mPermissionManager.updatePermissions(pkg.packageName, pkg);
+ mPermissionManager.updatePermissions(pkg.getPackageName(), pkg);
final boolean applyUserRestrictions
= (allUserHandles != null) && (origUserHandles != null);
@@ -18059,58 +17647,22 @@ public class PackageManagerService extends IPackageManager.Stub
private void deleteInstalledPackageLIF(PackageSetting ps,
boolean deleteCodeAndResources, int flags, int[] allUserHandles,
- PackageRemovedInfo outInfo, boolean writeSettings,
- PackageParser.Package replacingPackage) {
+ PackageRemovedInfo outInfo, boolean writeSettings) {
synchronized (mLock) {
if (outInfo != null) {
outInfo.uid = ps.appId;
}
-
- if (outInfo != null && outInfo.removedChildPackages != null) {
- final int childCount = (ps.childPackageNames != null)
- ? ps.childPackageNames.size() : 0;
- for (int i = 0; i < childCount; i++) {
- String childPackageName = ps.childPackageNames.get(i);
- PackageSetting childPs = mSettings.mPackages.get(childPackageName);
- PackageRemovedInfo childInfo = outInfo.removedChildPackages.get(
- childPackageName);
- if (childInfo != null) {
- childInfo.uid = childPs.appId;
- }
- }
- }
}
// Delete package data from internal structures and also remove data if flag is set
removePackageDataLIF(ps, allUserHandles, outInfo, flags, writeSettings);
- // Delete the child packages data
- final int childCount = (ps.childPackageNames != null) ? ps.childPackageNames.size() : 0;
- for (int i = 0; i < childCount; i++) {
- PackageSetting childPs;
- synchronized (mLock) {
- childPs = mSettings.getPackageLPr(ps.childPackageNames.get(i));
- }
- if (childPs != null) {
- PackageRemovedInfo childOutInfo = (outInfo != null
- && outInfo.removedChildPackages != null)
- ? outInfo.removedChildPackages.get(childPs.name) : null;
- final int deleteFlags = (flags & DELETE_KEEP_DATA) != 0
- && (replacingPackage != null
- && !replacingPackage.hasChildPackage(childPs.name))
- ? flags & ~DELETE_KEEP_DATA : flags;
- removePackageDataLIF(childPs, allUserHandles, childOutInfo,
- deleteFlags, writeSettings);
- }
- }
-
// Delete application code and resources only for parent packages
- if (ps.parentPackageName == null) {
- if (deleteCodeAndResources && (outInfo != null)) {
- outInfo.args = createInstallArgsForExisting(
- ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(ps));
- if (DEBUG_SD_INSTALL) Slog.i(TAG, "args=" + outInfo.args);
- }
+ if (deleteCodeAndResources && (outInfo != null)) {
+ outInfo.args = createInstallArgsForExisting(
+ ps.codePathString, ps.resourcePathString, getAppDexInstructionSets(
+ ps.primaryCpuAbiString, ps.secondaryCpuAbiString));
+ if (DEBUG_SD_INSTALL) Slog.i(TAG, "args=" + outInfo.args);
}
}
@@ -18123,10 +17675,10 @@ public class PackageManagerService extends IPackageManager.Stub
// Cannot block uninstall of static shared libs as they are
// considered a part of the using app (emulating static linking).
// Also static libs are installed always on internal storage.
- PackageParser.Package pkg = mPackages.get(packageName);
- if (pkg != null && pkg.staticSharedLibName != null) {
+ AndroidPackage pkg = mPackages.get(packageName);
+ if (pkg != null && pkg.getStaticSharedLibName() != null) {
Slog.w(TAG, "Cannot block uninstall of package: " + packageName
- + " providing static shared library: " + pkg.staticSharedLibName);
+ + " providing static shared library: " + pkg.getStaticSharedLibName());
return false;
}
mSettings.setBlockUninstallLPw(userId, packageName, blockUninstall);
@@ -18190,40 +17742,22 @@ public class PackageManagerService extends IPackageManager.Stub
@GuardedBy("mLock")
private static DeletePackageAction mayDeletePackageLocked(
PackageRemovedInfo outInfo, PackageSetting ps, @Nullable PackageSetting disabledPs,
- @Nullable PackageSetting[] children, int flags, UserHandle user) {
+ int flags, UserHandle user) {
if (ps == null) {
return null;
}
if (isSystemApp(ps)) {
- if (ps.parentPackageName != null) {
- Slog.w(TAG, "Attempt to delete child system package " + ps.pkg.packageName);
- return null;
- }
-
final boolean deleteSystem = (flags & PackageManager.DELETE_SYSTEM_APP) != 0;
final boolean deleteAllUsers =
user == null || user.getIdentifier() == UserHandle.USER_ALL;
if ((!deleteSystem || deleteAllUsers) && disabledPs == null) {
- Slog.w(TAG, "Attempt to delete unknown system package " + ps.pkg.packageName);
+ Slog.w(TAG, "Attempt to delete unknown system package " + ps.pkg.getPackageName());
return null;
}
// Confirmed if the system package has been updated
// An updated system app can be deleted. This will also have to restore
// the system pkg from system partition reader
}
- final int parentReferenceCount =
- (ps.childPackageNames != null) ? ps.childPackageNames.size() : 0;
- final int childCount = children != null ? children.length : 0;
- if (childCount != parentReferenceCount) {
- return null;
- }
- if (childCount != 0 && outInfo != null && outInfo.removedChildPackages != null) {
- for (PackageSetting child : children) {
- if (child == null || !ps.childPackageNames.contains(child.name)) {
- return null;
- }
- }
- }
return new DeletePackageAction(ps, disabledPs, outInfo, flags, user);
}
@@ -18233,13 +17767,12 @@ public class PackageManagerService extends IPackageManager.Stub
private boolean deletePackageLIF(@NonNull String packageName, UserHandle user,
boolean deleteCodeAndResources, int[] allUserHandles, int flags,
PackageRemovedInfo outInfo, boolean writeSettings,
- PackageParser.Package replacingPackage) {
+ ParsedPackage replacingPackage) {
final DeletePackageAction action;
synchronized (mLock) {
final PackageSetting ps = mSettings.mPackages.get(packageName);
final PackageSetting disabledPs = mSettings.getDisabledSystemPkgLPr(ps);
- PackageSetting[] children = mSettings.getChildSettingsLPr(ps);
- action = mayDeletePackageLocked(outInfo, ps, disabledPs, children, flags, user);
+ action = mayDeletePackageLocked(outInfo, ps, disabledPs, flags, user);
}
if (DEBUG_REMOVE) Slog.d(TAG, "deletePackageLI: " + packageName + " user " + user);
if (null == action) {
@@ -18270,30 +17803,13 @@ public class PackageManagerService extends IPackageManager.Stub
private void executeDeletePackageLIF(DeletePackageAction action,
String packageName, boolean deleteCodeAndResources,
int[] allUserHandles, boolean writeSettings,
- PackageParser.Package replacingPackage) throws SystemDeleteException {
+ ParsedPackage replacingPackage) throws SystemDeleteException {
final PackageSetting ps = action.deletingPs;
final PackageRemovedInfo outInfo = action.outInfo;
final UserHandle user = action.user;
final int flags = action.flags;
final boolean systemApp = isSystemApp(ps);
- if (ps.parentPackageName != null
- && (!systemApp || (flags & PackageManager.DELETE_SYSTEM_APP) != 0)) {
- if (DEBUG_REMOVE) {
- Slog.d(TAG, "Uninstalled child package:" + packageName + " for user:"
- + ((user == null) ? UserHandle.USER_ALL : user));
- }
- final int removedUserId = (user != null) ? user.getIdentifier()
- : UserHandle.USER_ALL;
-
- clearPackageStateForUserLIF(ps, removedUserId, outInfo, flags);
- synchronized (mLock) {
- markPackageUninstalledForUserLPw(ps, user);
- scheduleWritePackageRestrictionsLocked(user);
- }
- return;
- }
-
final int userId = user == null ? UserHandle.USER_ALL : user.getIdentifier();
if (ps.getPermissionsState().hasPermission(Manifest.permission.SUSPEND_APPS, userId)) {
unsuspendForSuspendingPackage(packageName, userId);
@@ -18343,26 +17859,6 @@ public class PackageManagerService extends IPackageManager.Stub
}
}
- // If we are deleting a composite package for all users, keep track
- // of result for each child.
- if (ps.childPackageNames != null && outInfo != null) {
- synchronized (mLock) {
- final int childCount = ps.childPackageNames.size();
- outInfo.removedChildPackages = new ArrayMap<>(childCount);
- for (int i = 0; i < childCount; i++) {
- String childPackageName = ps.childPackageNames.get(i);
- PackageRemovedInfo childInfo = new PackageRemovedInfo(this);
- childInfo.removedPackage = childPackageName;
- childInfo.installerPackageName = ps.installerPackageName;
- outInfo.removedChildPackages.put(childPackageName, childInfo);
- PackageSetting childPs = mSettings.getPackageLPr(childPackageName);
- if (childPs != null) {
- childInfo.origUsers = childPs.queryInstalledUsers(allUserHandles, true);
- }
- }
- }
- }
-
// TODO(b/109941548): break reasons for ret = false out into mayDelete method
if (systemApp) {
if (DEBUG_REMOVE) Slog.d(TAG, "Removing system package: " + ps.name);
@@ -18372,53 +17868,12 @@ public class PackageManagerService extends IPackageManager.Stub
} else {
if (DEBUG_REMOVE) Slog.d(TAG, "Removing non-system package: " + ps.name);
deleteInstalledPackageLIF(ps, deleteCodeAndResources, flags, allUserHandles,
- outInfo, writeSettings, replacingPackage);
+ outInfo, writeSettings);
}
// Take a note whether we deleted the package for all users
if (outInfo != null) {
outInfo.removedForAllUsers = mPackages.get(ps.name) == null;
- if (outInfo.removedChildPackages != null) {
- synchronized (mLock) {
- final int childCount = outInfo.removedChildPackages.size();
- for (int i = 0; i < childCount; i++) {
- PackageRemovedInfo childInfo = outInfo.removedChildPackages.valueAt(i);
- if (childInfo != null) {
- childInfo.removedForAllUsers = mPackages.get(
- childInfo.removedPackage) == null;
- }
- }
- }
- }
- // If we uninstalled an update to a system app there may be some
- // child packages that appeared as they are declared in the system
- // app but were not declared in the update.
- if (systemApp) {
- synchronized (mLock) {
- PackageSetting updatedPs = mSettings.getPackageLPr(ps.name);
- final int childCount = (updatedPs.childPackageNames != null)
- ? updatedPs.childPackageNames.size() : 0;
- for (int i = 0; i < childCount; i++) {
- String childPackageName = updatedPs.childPackageNames.get(i);
- if (outInfo.removedChildPackages == null
- || outInfo.removedChildPackages.indexOfKey(childPackageName) < 0) {
- PackageSetting childPs = mSettings.getPackageLPr(childPackageName);
- if (childPs == null) {
- continue;
- }
- PackageInstalledInfo installRes = new PackageInstalledInfo();
- installRes.name = childPackageName;
- installRes.newUsers = childPs.queryInstalledUsers(allUserHandles, true);
- installRes.pkg = mPackages.get(childPackageName);
- installRes.uid = childPs.pkg.applicationInfo.uid;
- if (outInfo.appearedChildPackages == null) {
- outInfo.appearedChildPackages = new ArrayMap<>();
- }
- outInfo.appearedChildPackages.put(childPackageName, installRes);
- }
- }
- }
- }
}
}
@@ -18455,7 +17910,7 @@ public class PackageManagerService extends IPackageManager.Stub
private void clearPackageStateForUserLIF(PackageSetting ps, int userId,
PackageRemovedInfo outInfo, int flags) {
- final PackageParser.Package pkg;
+ final AndroidPackage pkg;
synchronized (mLock) {
pkg = mPackages.get(ps.name);
}
@@ -18497,7 +17952,7 @@ public class PackageManagerService extends IPackageManager.Stub
if (outInfo != null) {
outInfo.removedPackage = ps.name;
outInfo.installerPackageName = ps.installerPackageName;
- outInfo.isStaticSharedLib = pkg != null && pkg.staticSharedLibName != null;
+ outInfo.isStaticSharedLib = pkg != null && pkg.getStaticSharedLibName() != null;
outInfo.removedAppId = ps.appId;
outInfo.removedUsers = userIds;
outInfo.broadcastUsers = userIds;
@@ -18508,7 +17963,7 @@ public class PackageManagerService extends IPackageManager.Stub
public void clearApplicationProfileData(String packageName) {
enforceSystemOrRoot("Only the system can clear all profile data");
- final PackageParser.Package pkg;
+ final AndroidPackage pkg;
synchronized (mLock) {
pkg = mPackages.get(packageName);
}
@@ -18586,7 +18041,7 @@ public class PackageManagerService extends IPackageManager.Stub
}
// Try finding details about the requested package
- PackageParser.Package pkg;
+ AndroidPackage pkg;
synchronized (mLock) {
pkg = mPackages.get(packageName);
if (pkg == null) {
@@ -18605,7 +18060,7 @@ public class PackageManagerService extends IPackageManager.Stub
clearAppDataLIF(pkg, userId,
FLAG_STORAGE_DE | FLAG_STORAGE_CE | FLAG_STORAGE_EXTERNAL);
- final int appId = UserHandle.getAppId(pkg.applicationInfo.uid);
+ final int appId = UserHandle.getAppId(pkg.getUid());
removeKeystoreDataIfNeeded(mInjector.getUserManagerInternal(), userId, appId);
UserManagerInternal umInternal = mInjector.getUserManagerInternal();
@@ -18682,14 +18137,14 @@ public class PackageManagerService extends IPackageManager.Stub
final int hasAccessInstantApps = mContext.checkCallingOrSelfPermission(
android.Manifest.permission.ACCESS_INSTANT_APPS);
- final PackageParser.Package pkg;
+ final AndroidPackage pkg;
synchronized (mLock) {
pkg = mPackages.get(packageName);
}
// Queue up an async operation since the package deletion may take a little while.
mHandler.post(() -> {
- final PackageSetting ps = pkg == null ? null : (PackageSetting) pkg.mExtras;
+ final PackageSetting ps = pkg == null ? null : getPackageSetting(pkg.getPackageName());
boolean doClearData = true;
if (ps != null) {
final boolean targetIsInstantApp =
@@ -18769,7 +18224,7 @@ public class PackageManagerService extends IPackageManager.Stub
while (it.hasNext()) {
final PackageSetting ps = it.next();
if (ps.pkg != null) {
- int v = ps.pkg.applicationInfo.targetSdkVersion;
+ int v = ps.pkg.getTargetSdkVersion();
if (v < vers) vers = v;
}
}
@@ -18777,7 +18232,7 @@ public class PackageManagerService extends IPackageManager.Stub
} else if (obj instanceof PackageSetting) {
final PackageSetting ps = (PackageSetting) obj;
if (ps.pkg != null) {
- return ps.pkg.applicationInfo.targetSdkVersion;
+ return ps.pkg.getTargetSdkVersion();
}
}
return Build.VERSION_CODES.CUR_DEVELOPMENT;
@@ -18785,9 +18240,9 @@ public class PackageManagerService extends IPackageManager.Stub
@GuardedBy("mLock")
private int getPackageTargetSdkVersionLockedLPr(String packageName) {
- final PackageParser.Package p = mPackages.get(packageName);
+ final AndroidPackage p = mPackages.get(packageName);
if (p != null) {
- return p.applicationInfo.targetSdkVersion;
+ return p.getTargetSdkVersion();
}
return Build.VERSION_CODES.CUR_DEVELOPMENT;
}
@@ -18956,7 +18411,7 @@ public class PackageManagerService extends IPackageManager.Stub
}
// writer
synchronized (mLock) {
- PackageParser.Package pkg = mPackages.get(packageName);
+ AndroidPackage pkg = mPackages.get(packageName);
if (pkg == null || !isCallerSameApp(packageName, callingUid)) {
if (mContext.checkCallingOrSelfPermission(
android.Manifest.permission.SET_PREFERRED_APPLICATIONS)
@@ -19030,8 +18485,8 @@ public class PackageManagerService extends IPackageManager.Stub
private void clearIntentFilterVerificationsLPw(int userId) {
final int packageCount = mPackages.size();
for (int i = 0; i < packageCount; i++) {
- PackageParser.Package pkg = mPackages.valueAt(i);
- clearIntentFilterVerificationsLPw(pkg.packageName, userId);
+ AndroidPackage pkg = mPackages.valueAt(i);
+ clearIntentFilterVerificationsLPw(pkg.getPackageName(), userId);
}
}
@@ -19938,8 +19393,8 @@ public class PackageManagerService extends IPackageManager.Stub
// If we're enabling a system stub, there's a little more work to do.
// Prior to enabling the package, we need to decompress the APK(s) to the
// data partition and then replace the version on the system partition.
- final PackageParser.Package deletedPkg = pkgSetting.pkg;
- final boolean isSystemStub = deletedPkg.isStub
+ final AndroidPackage deletedPkg = pkgSetting.pkg;
+ final boolean isSystemStub = deletedPkg.isStub()
&& deletedPkg.isSystem();
if (isSystemStub
&& (newState == PackageManager.COMPONENT_ENABLED_STATE_DEFAULT
@@ -19960,10 +19415,10 @@ public class PackageManagerService extends IPackageManager.Stub
synchronized (mLock) {
// We're dealing with a component level state change
// First, verify that this is a valid class name.
- PackageParser.Package pkg = pkgSetting.pkg;
+ AndroidPackage pkg = pkgSetting.pkg;
if (pkg == null || !pkg.hasComponentClassName(className)) {
if (pkg != null &&
- pkg.applicationInfo.targetSdkVersion >=
+ pkg.getTargetSdkVersion() >=
Build.VERSION_CODES.JELLY_BEAN) {
throw new IllegalArgumentException("Component class " + className
+ " does not exist in " + packageName);
@@ -20903,7 +20358,7 @@ public class PackageManagerService extends IPackageManager.Stub
if (!checkin && dumpState.isDumping(DumpState.DUMP_SERVICE_PERMISSIONS)
&& packageName == null) {
- mComponentResolver.dumpServicePermissions(pw, dumpState, packageName);
+ mComponentResolver.dumpServicePermissions(pw, dumpState);
}
if (!checkin && dumpState.isDumping(DumpState.DUMP_DEXOPT)) {
@@ -21046,9 +20501,9 @@ public class PackageManagerService extends IPackageManager.Stub
ipw.println();
ipw.println("Dexopt state:");
ipw.increaseIndent();
- Collection<PackageParser.Package> packages;
+ Collection<AndroidPackage> packages;
if (packageName != null) {
- PackageParser.Package targetPackage = mPackages.get(packageName);
+ AndroidPackage targetPackage = mPackages.get(packageName);
if (targetPackage != null) {
packages = Collections.singletonList(targetPackage);
} else {
@@ -21059,11 +20514,11 @@ public class PackageManagerService extends IPackageManager.Stub
packages = mPackages.values();
}
- for (PackageParser.Package pkg : packages) {
- ipw.println("[" + pkg.packageName + "]");
+ for (AndroidPackage pkg : packages) {
+ ipw.println("[" + pkg.getPackageName() + "]");
ipw.increaseIndent();
mPackageDexOptimizer.dumpDexoptState(ipw, pkg,
- mDexManager.getPackageUseInfoOrDefault(pkg.packageName));
+ mDexManager.getPackageUseInfoOrDefault(pkg.getPackageName()));
ipw.decreaseIndent();
}
}
@@ -21075,9 +20530,9 @@ public class PackageManagerService extends IPackageManager.Stub
ipw.println();
ipw.println("Compiler stats:");
ipw.increaseIndent();
- Collection<PackageParser.Package> packages;
+ Collection<AndroidPackage> packages;
if (packageName != null) {
- PackageParser.Package targetPackage = mPackages.get(packageName);
+ AndroidPackage targetPackage = mPackages.get(packageName);
if (targetPackage != null) {
packages = Collections.singletonList(targetPackage);
} else {
@@ -21088,11 +20543,11 @@ public class PackageManagerService extends IPackageManager.Stub
packages = mPackages.values();
}
- for (PackageParser.Package pkg : packages) {
- ipw.println("[" + pkg.packageName + "]");
+ for (AndroidPackage pkg : packages) {
+ ipw.println("[" + pkg.getPackageName() + "]");
ipw.increaseIndent();
- CompilerStats.PackageStats stats = getCompilerPackageStats(pkg.packageName);
+ CompilerStats.PackageStats stats = getCompilerPackageStats(pkg.getPackageName());
if (stats == null) {
ipw.println("(No recorded stats)");
} else {
@@ -21163,14 +20618,14 @@ public class PackageManagerService extends IPackageManager.Stub
}
private void sendResourcesChangedBroadcast(boolean mediaStatus, boolean replacing,
- ArrayList<ApplicationInfo> infos, IIntentReceiver finishedReceiver) {
- final int size = infos.size();
+ ArrayList<AndroidPackage> packages, IIntentReceiver finishedReceiver) {
+ final int size = packages.size();
final String[] packageNames = new String[size];
final int[] packageUids = new int[size];
for (int i = 0; i < size; i++) {
- final ApplicationInfo info = infos.get(i);
- packageNames[i] = info.packageName;
- packageUids[i] = info.uid;
+ final AndroidPackage pkg = packages.get(i);
+ packageNames[i] = pkg.getAppInfoPackageName();
+ packageUids[i] = pkg.getUid();
}
sendResourcesChangedBroadcast(mediaStatus, replacing, packageNames, packageUids,
finishedReceiver);
@@ -21213,7 +20668,7 @@ public class PackageManagerService extends IPackageManager.Stub
}
final ArrayList<PackageFreezer> freezers = new ArrayList<>();
- final ArrayList<ApplicationInfo> loaded = new ArrayList<>();
+ final ArrayList<AndroidPackage> loaded = new ArrayList<>();
final int parseFlags = mDefParseFlags | PackageParser.PARSE_EXTERNAL_STORAGE;
final VersionInfo ver;
@@ -21226,10 +20681,10 @@ public class PackageManagerService extends IPackageManager.Stub
for (PackageSetting ps : packages) {
freezers.add(freezePackage(ps.name, "loadPrivatePackagesInner"));
synchronized (mInstallLock) {
- final PackageParser.Package pkg;
+ final AndroidPackage pkg;
try {
pkg = scanPackageTracedLI(ps.codePath, parseFlags, SCAN_INITIAL, 0, null);
- loaded.add(pkg.applicationInfo);
+ loaded.add(pkg);
} catch (PackageManagerException e) {
Slog.w(TAG, "Failed to scan " + ps.codePath + ": " + e.getMessage());
@@ -21301,14 +20756,14 @@ public class PackageManagerService extends IPackageManager.Stub
return;
}
- final ArrayList<ApplicationInfo> unloaded = new ArrayList<>();
+ final ArrayList<AndroidPackage> unloaded = new ArrayList<>();
synchronized (mInstallLock) {
synchronized (mLock) {
final List<PackageSetting> packages = mSettings.getVolumePackagesLPr(volumeUuid);
for (PackageSetting ps : packages) {
if (ps.pkg == null) continue;
- final ApplicationInfo info = ps.pkg.applicationInfo;
+ final AndroidPackage pkg = ps.pkg;
final int deleteFlags = PackageManager.DELETE_KEEP_DATA;
final PackageRemovedInfo outInfo = new PackageRemovedInfo(this);
@@ -21316,7 +20771,7 @@ public class PackageManagerService extends IPackageManager.Stub
"unloadPrivatePackagesInner")) {
if (deletePackageLIF(ps.name, null, false, null, deleteFlags, outInfo,
false, null)) {
- unloaded.add(info);
+ unloaded.add(pkg);
} else {
Slog.w(TAG, "Failed to unload " + ps.codePath);
}
@@ -21531,7 +20986,7 @@ public class PackageManagerService extends IPackageManager.Stub
continue;
}
// Skip non-core apps if requested
- if (onlyCoreApps && !ps.pkg.coreApp) {
+ if (onlyCoreApps && !ps.pkg.isCoreApp()) {
result.add(packageName);
continue;
}
@@ -21558,10 +21013,10 @@ public class PackageManagerService extends IPackageManager.Stub
* <p>
* <em>Note: To avoid a deadlock, do not call this method with {@code mLock} lock held</em>
*/
- private void prepareAppDataAfterInstallLIF(PackageParser.Package pkg) {
+ private void prepareAppDataAfterInstallLIF(AndroidPackage pkg) {
final PackageSetting ps;
synchronized (mLock) {
- ps = mSettings.mPackages.get(pkg.packageName);
+ ps = mSettings.mPackages.get(pkg.getPackageName());
mSettings.writeKernelMappingLPr(ps);
}
@@ -21591,19 +21046,15 @@ public class PackageManagerService extends IPackageManager.Stub
* will try recovering system apps by wiping data; third-party app data is
* left intact.
*/
- private void prepareAppDataLIF(PackageParser.Package pkg, int userId, int flags) {
+ private void prepareAppDataLIF(AndroidPackage pkg, int userId, int flags) {
if (pkg == null) {
Slog.wtf(TAG, "Package was null!", new Throwable());
return;
}
prepareAppDataLeafLIF(pkg, userId, flags);
- final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
- for (int i = 0; i < childCount; i++) {
- prepareAppDataLeafLIF(pkg.childPackages.get(i), userId, flags);
- }
}
- private void prepareAppDataAndMigrateLIF(PackageParser.Package pkg, int userId, int flags,
+ private void prepareAppDataAndMigrateLIF(AndroidPackage pkg, int userId, int flags,
boolean maybeMigrateAppData) {
prepareAppDataLIF(pkg, userId, flags);
@@ -21614,43 +21065,37 @@ public class PackageManagerService extends IPackageManager.Stub
}
}
- private void prepareAppDataLeafLIF(PackageParser.Package pkg, int userId, int flags) {
+ private void prepareAppDataLeafLIF(AndroidPackage pkg, int userId, int flags) {
if (DEBUG_APP_DATA) {
- Slog.v(TAG, "prepareAppData for " + pkg.packageName + " u" + userId + " 0x"
+ Slog.v(TAG, "prepareAppData for " + pkg.getPackageName() + " u" + userId + " 0x"
+ Integer.toHexString(flags));
}
final PackageSetting ps;
synchronized (mLock) {
- ps = mSettings.mPackages.get(pkg.packageName);
- }
- final String volumeUuid = pkg.volumeUuid;
- final String packageName = pkg.packageName;
-
- ApplicationInfo app = (ps == null)
- ? pkg.applicationInfo
- : PackageParser.generateApplicationInfo(pkg, 0, ps.readUserState(userId), userId);
- if (app == null) {
- app = pkg.applicationInfo;
+ ps = mSettings.mPackages.get(pkg.getPackageName());
}
+ final String volumeUuid = pkg.getVolumeUuid();
+ final String packageName = pkg.getPackageName();
- final int appId = UserHandle.getAppId(app.uid);
+ final int appId = UserHandle.getAppId(pkg.getUid());
- Preconditions.checkNotNull(app.seInfo);
+ Preconditions.checkNotNull(pkg.getSeInfo());
- final String seInfo = app.seInfo + (app.seInfoUser != null ? app.seInfoUser : "");
+ final String seInfo =
+ pkg.getSeInfo() + (pkg.getSeInfoUser() != null ? pkg.getSeInfoUser() : "");
long ceDataInode = -1;
try {
ceDataInode = mInstaller.createAppData(volumeUuid, packageName, userId, flags,
- appId, seInfo, app.targetSdkVersion);
+ appId, seInfo, pkg.getTargetSdkVersion());
} catch (InstallerException e) {
- if (app.isSystemApp()) {
+ if (pkg.isSystemApp()) {
logCriticalInfo(Log.ERROR, "Failed to create app data for " + packageName
+ ", but trying to recover: " + e);
destroyAppDataLeafLIF(pkg, userId, flags);
try {
ceDataInode = mInstaller.createAppData(volumeUuid, packageName, userId, flags,
- appId, seInfo, app.targetSdkVersion);
+ appId, seInfo, pkg.getTargetSdkVersion());
logCriticalInfo(Log.DEBUG, "Recovery succeeded!");
} catch (InstallerException e2) {
logCriticalInfo(Log.DEBUG, "Recovery failed!");
@@ -21692,29 +21137,24 @@ public class PackageManagerService extends IPackageManager.Stub
prepareAppDataContentsLeafLIF(pkg, userId, flags);
}
- private void prepareAppDataContentsLIF(PackageParser.Package pkg, int userId, int flags) {
+ private void prepareAppDataContentsLIF(AndroidPackage pkg, int userId, int flags) {
if (pkg == null) {
Slog.wtf(TAG, "Package was null!", new Throwable());
return;
}
prepareAppDataContentsLeafLIF(pkg, userId, flags);
- final int childCount = (pkg.childPackages != null) ? pkg.childPackages.size() : 0;
- for (int i = 0; i < childCount; i++) {
- prepareAppDataContentsLeafLIF(pkg.childPackages.get(i), userId, flags);
- }
}
- private void prepareAppDataContentsLeafLIF(PackageParser.Package pkg, int userId, int flags) {
- final String volumeUuid = pkg.volumeUuid;
- final String packageName = pkg.packageName;
- final ApplicationInfo app = pkg.applicationInfo;
+ private void prepareAppDataContentsLeafLIF(AndroidPackage pkg, int userId, int flags) {
+ final String volumeUuid = pkg.getVolumeUuid();
+ final String packageName = pkg.getPackageName();
if ((flags & StorageManager.FLAG_STORAGE_CE) != 0) {
// Create a native library symlink only if we have native libraries
// and if the native libraries are 32 bit libraries. We do not provide
// this symlink for 64 bit libraries.
- if (app.primaryCpuAbi != null && !VMRuntime.is64BitAbi(app.primaryCpuAbi)) {
- final String nativeLibPath = app.nativeLibraryDir;
+ if (pkg.getPrimaryCpuAbi() != null && !VMRuntime.is64BitAbi(pkg.getPrimaryCpuAbi())) {
+ final String nativeLibPath = pkg.getNativeLibraryDir();
try {
mInstaller.linkNativeLibraryDirectory(volumeUuid, packageName,
nativeLibPath, userId);
@@ -21730,17 +21170,17 @@ public class PackageManagerService extends IPackageManager.Stub
* CE/DE data to match the {@code defaultToDeviceProtectedStorage} flag
* requested by the app.
*/
- private boolean maybeMigrateAppDataLIF(PackageParser.Package pkg, int userId) {
+ private boolean maybeMigrateAppDataLIF(AndroidPackage pkg, int userId) {
if (pkg.isSystem() && !StorageManager.isFileEncryptedNativeOrEmulated()
&& PackageManager.APPLY_DEFAULT_TO_DEVICE_PROTECTED_STORAGE) {
- final int storageTarget = pkg.applicationInfo.isDefaultToDeviceProtectedStorage()
+ final int storageTarget = pkg.isDefaultToDeviceProtectedStorage()
? StorageManager.FLAG_STORAGE_DE : StorageManager.FLAG_STORAGE_CE;
try {
- mInstaller.migrateAppData(pkg.volumeUuid, pkg.packageName, userId,
+ mInstaller.migrateAppData(pkg.getVolumeUuid(), pkg.getPackageName(), userId,
storageTarget);
} catch (InstallerException e) {
logCriticalInfo(Log.WARN,
- "Failed to migrate " + pkg.packageName + ": " + e.getMessage());
+ "Failed to migrate " + pkg.getPackageName() + ": " + e.getMessage());
}
return true;
} else {
@@ -21791,7 +21231,6 @@ public class PackageManagerService extends IPackageManager.Stub
*/
private class PackageFreezer implements AutoCloseable {
private final String mPackageName;
- private final PackageFreezer[] mChildren;
private final boolean mWeFroze;
@@ -21806,7 +21245,6 @@ public class PackageManagerService extends IPackageManager.Stub
*/
public PackageFreezer() {
mPackageName = null;
- mChildren = null;
mWeFroze = false;
mCloseGuard.open("close");
}
@@ -21820,18 +21258,6 @@ public class PackageManagerService extends IPackageManager.Stub
if (ps != null) {
killApplication(ps.name, ps.appId, userId, killReason);
}
-
- final PackageParser.Package p = mPackages.get(packageName);
- if (p != null && p.childPackages != null) {
- final int N = p.childPackages.size();
- mChildren = new PackageFreezer[N];
- for (int i = 0; i < N; i++) {
- mChildren[i] = new PackageFreezer(p.childPackages.get(i).packageName,
- userId, killReason);
- }
- } else {
- mChildren = null;
- }
}
mCloseGuard.open("close");
}
@@ -21854,12 +21280,6 @@ public class PackageManagerService extends IPackageManager.Stub
if (mWeFroze) {
mFrozenPackages.remove(mPackageName);
}
-
- if (mChildren != null) {
- for (PackageFreezer freezer : mChildren) {
- freezer.close();
- }
- }
}
}
}
@@ -21914,14 +21334,14 @@ public class PackageManagerService extends IPackageManager.Stub
// reader
synchronized (mLock) {
- final PackageParser.Package pkg = mPackages.get(packageName);
+ final AndroidPackage pkg = mPackages.get(packageName);
final PackageSetting ps = mSettings.mPackages.get(packageName);
if (pkg == null
|| ps == null
|| shouldFilterApplicationLocked(ps, callingUid, user.getIdentifier())) {
throw new PackageManagerException(MOVE_FAILED_DOESNT_EXIST, "Missing package");
}
- if (pkg.applicationInfo.isSystemApp()) {
+ if (pkg.isSystemApp()) {
throw new PackageManagerException(MOVE_FAILED_SYSTEM_PACKAGE,
"Cannot move system application");
}
@@ -21936,7 +21356,7 @@ public class PackageManagerService extends IPackageManager.Stub
currentVolumeUuid = ps.volumeUuid;
- final File probe = new File(pkg.codePath);
+ final File probe = new File(pkg.getCodePath());
final File probeOat = new File(probe, "oat");
if (!probe.isDirectory() || !probeOat.isDirectory()) {
throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
@@ -21947,7 +21367,7 @@ public class PackageManagerService extends IPackageManager.Stub
throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR,
"Package already moved to " + volumeUuid);
}
- if (pkg.applicationInfo.isInternal() && isPackageDeviceAdminOnAnyUser(packageName)) {
+ if (pkg.isInternal() && isPackageDeviceAdminOnAnyUser(packageName)) {
throw new PackageManagerException(MOVE_FAILED_DEVICE_ADMIN,
"Device admin cannot be moved");
}
@@ -21958,13 +21378,13 @@ public class PackageManagerService extends IPackageManager.Stub
}
isCurrentLocationExternal = isExternal(pkg);
- codeFile = new File(pkg.codePath);
+ codeFile = new File(pkg.getCodePath());
installerPackageName = ps.installerPackageName;
packageAbiOverride = ps.cpuAbiOverrideString;
- appId = UserHandle.getAppId(pkg.applicationInfo.uid);
- seinfo = pkg.applicationInfo.seInfo;
- label = String.valueOf(pm.getApplicationLabel(pkg.applicationInfo));
- targetSdkVersion = pkg.applicationInfo.targetSdkVersion;
+ appId = UserHandle.getAppId(pkg.getUid());
+ seinfo = pkg.getSeInfo();
+ label = String.valueOf(pm.getApplicationLabel(pkg.toAppInfo()));
+ targetSdkVersion = pkg.getTargetSdkVersion();
freezer = freezePackage(packageName, "movePackageInternal");
installedUserIds = ps.queryInstalledUsers(mUserManager.getUserIds(), true);
}
@@ -22125,7 +21545,7 @@ public class PackageManagerService extends IPackageManager.Stub
* @param packageName The package that was moved.
*/
private void logAppMovedStorage(String packageName, boolean isPreviousLocationExternal) {
- final PackageParser.Package pkg;
+ final AndroidPackage pkg;
synchronized (mLock) {
pkg = mPackages.get(packageName);
}
@@ -22133,8 +21553,8 @@ public class PackageManagerService extends IPackageManager.Stub
return;
}
- final StorageManager storage = mInjector.getStorageManager();
- VolumeInfo volume = storage.findVolumeByUuid(pkg.applicationInfo.storageUuid.toString());
+ final StorageManager storage = mInjector.getStorageManager();;
+ VolumeInfo volume = storage.findVolumeByUuid(pkg.getStorageUuid().toString());
int packageExternalStorageType = getPackageExternalStorageType(volume, isExternal(pkg));
if (!isPreviousLocationExternal && isExternal(pkg)) {
@@ -22248,7 +21668,7 @@ public class PackageManagerService extends IPackageManager.Stub
if (ps.pkg == null) {
continue;
}
- final String packageName = ps.pkg.packageName;
+ final String packageName = ps.pkg.getPackageName();
// Skip over if system app
if ((ps.pkgFlags & ApplicationInfo.FLAG_SYSTEM) != 0) {
continue;
@@ -22377,13 +21797,13 @@ public class PackageManagerService extends IPackageManager.Stub
if (packageName == null || alias == null) {
return null;
}
- synchronized (mLock) {
- final PackageParser.Package pkg = mPackages.get(packageName);
+ synchronized(mLock) {
+ final AndroidPackage pkg = mPackages.get(packageName);
if (pkg == null) {
Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
throw new IllegalArgumentException("Unknown package: " + packageName);
}
- final PackageSetting ps = (PackageSetting) pkg.mExtras;
+ final PackageSetting ps = getPackageSetting(pkg.getPackageName());
if (shouldFilterApplicationLocked(
ps, Binder.getCallingUid(), UserHandle.getCallingUserId())) {
Slog.w(TAG, "KeySet requested for filtered package: " + packageName);
@@ -22402,19 +21822,19 @@ public class PackageManagerService extends IPackageManager.Stub
synchronized (mLock) {
final int callingUid = Binder.getCallingUid();
final int callingUserId = UserHandle.getUserId(callingUid);
- final PackageParser.Package pkg = mPackages.get(packageName);
+ final AndroidPackage pkg = mPackages.get(packageName);
if (pkg == null) {
Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
throw new IllegalArgumentException("Unknown package: " + packageName);
}
- final PackageSetting ps = (PackageSetting) pkg.mExtras;
+ final PackageSetting ps = getPackageSetting(pkg.getPackageName());
if (shouldFilterApplicationLocked(ps, callingUid, callingUserId)) {
// filter and pretend the package doesn't exist
Slog.w(TAG, "KeySet requested for filtered package: " + packageName
+ ", uid:" + callingUid);
throw new IllegalArgumentException("Unknown package: " + packageName);
}
- if (pkg.applicationInfo.uid != callingUid
+ if (pkg.getUid() != callingUid
&& Process.SYSTEM_UID != callingUid) {
throw new SecurityException("May not access signing KeySet of other apps.");
}
@@ -22432,11 +21852,11 @@ public class PackageManagerService extends IPackageManager.Stub
if (packageName == null || ks == null) {
return false;
}
- synchronized (mLock) {
- final PackageParser.Package pkg = mPackages.get(packageName);
+ synchronized(mLock) {
+ final AndroidPackage pkg = mPackages.get(packageName);
if (pkg == null
- || shouldFilterApplicationLocked((PackageSetting) pkg.mExtras, callingUid,
- UserHandle.getUserId(callingUid))) {
+ || shouldFilterApplicationLocked(getPackageSetting(pkg.getPackageName()),
+ callingUid, UserHandle.getUserId(callingUid))) {
Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
throw new IllegalArgumentException("Unknown package: " + packageName);
}
@@ -22459,10 +21879,10 @@ public class PackageManagerService extends IPackageManager.Stub
return false;
}
synchronized (mLock) {
- final PackageParser.Package pkg = mPackages.get(packageName);
+ final AndroidPackage pkg = mPackages.get(packageName);
if (pkg == null
- || shouldFilterApplicationLocked((PackageSetting) pkg.mExtras, callingUid,
- UserHandle.getUserId(callingUid))) {
+ || shouldFilterApplicationLocked(getPackageSetting(pkg.getPackageName()),
+ callingUid, UserHandle.getUserId(callingUid))) {
Slog.w(TAG, "KeySet requested for unknown package: " + packageName);
throw new IllegalArgumentException("Unknown package: " + packageName);
}
@@ -22494,29 +21914,29 @@ public class PackageManagerService extends IPackageManager.Stub
* Check and throw if the given before/after packages would be considered a
* downgrade.
*/
- private static void checkDowngrade(PackageParser.Package before, PackageInfoLite after)
+ private static void checkDowngrade(AndroidPackage before, PackageInfoLite after)
throws PackageManagerException {
if (after.getLongVersionCode() < before.getLongVersionCode()) {
throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
"Update version code " + after.versionCode + " is older than current "
+ before.getLongVersionCode());
} else if (after.getLongVersionCode() == before.getLongVersionCode()) {
- if (after.baseRevisionCode < before.baseRevisionCode) {
+ if (after.baseRevisionCode < before.getBaseRevisionCode()) {
throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
"Update base revision code " + after.baseRevisionCode
- + " is older than current " + before.baseRevisionCode);
+ + " is older than current " + before.getBaseRevisionCode());
}
if (!ArrayUtils.isEmpty(after.splitNames)) {
for (int i = 0; i < after.splitNames.length; i++) {
final String splitName = after.splitNames[i];
- final int j = ArrayUtils.indexOf(before.splitNames, splitName);
+ final int j = ArrayUtils.indexOf(before.getSplitNames(), splitName);
if (j != -1) {
- if (after.splitRevisionCodes[i] < before.splitRevisionCodes[j]) {
+ if (after.splitRevisionCodes[i] < before.getSplitRevisionCodes()[j]) {
throw new PackageManagerException(INSTALL_FAILED_VERSION_DOWNGRADE,
"Update split " + splitName + " revision code "
+ after.splitRevisionCodes[i] + " is older than current "
- + before.splitRevisionCodes[j]);
+ + before.getSplitRevisionCodes()[j]);
}
}
}
@@ -22706,13 +22126,13 @@ public class PackageManagerService extends IPackageManager.Stub
if (packageSetting == null) {
return false;
}
- PackageParser.Package pkg = packageSetting.pkg;
+ AndroidPackage pkg = packageSetting.pkg;
if (pkg == null) {
// May happen if package in on a removable sd card
return false;
}
- return pkg.mSigningDetails.hasAncestorOrSelf(mPlatformPackage.mSigningDetails)
- || mPlatformPackage.mSigningDetails.checkCapability(pkg.mSigningDetails,
+ return pkg.getSigningDetails().hasAncestorOrSelf(mPlatformPackage.getSigningDetails())
+ || mPlatformPackage.getSigningDetails().checkCapability(pkg.getSigningDetails(),
PackageParser.SigningDetails.CertCapabilities.PERMISSION);
}
@@ -22748,11 +22168,11 @@ public class PackageManagerService extends IPackageManager.Stub
private SigningDetails getSigningDetails(@NonNull String packageName) {
synchronized (mLock) {
- PackageParser.Package p = mPackages.get(packageName);
+ AndroidPackage p = mPackages.get(packageName);
if (p == null) {
return null;
}
- return p.mSigningDetails;
+ return p.getSigningDetails();
}
}
@@ -22783,28 +22203,25 @@ public class PackageManagerService extends IPackageManager.Stub
}
@Override
- public boolean filterAppAccess(PackageParser.Package pkg, int callingUid, int userId) {
+ public boolean filterAppAccess(AndroidPackage pkg, int callingUid, int userId) {
synchronized (mLock) {
- return PackageManagerService.this.shouldFilterApplicationLocked(
- (PackageSetting) pkg.mExtras, callingUid, userId);
+ PackageSetting ps = getPackageSetting(pkg.getPackageName());
+ return PackageManagerService.this.shouldFilterApplicationLocked(ps, callingUid,
+ userId);
}
}
@Override
public boolean filterAppAccess(String packageName, int callingUid, int userId) {
synchronized (mLock) {
- final PackageParser.Package pkg = mPackages.get(packageName);
- if (pkg == null) {
- return false;
- }
- return PackageManagerService.this
- .shouldFilterApplicationLocked(
- (PackageSetting) pkg.mExtras, callingUid, userId);
+ PackageSetting ps = getPackageSetting(packageName);
+ return PackageManagerService.this.shouldFilterApplicationLocked(ps, callingUid,
+ userId);
}
}
@Override
- public PackageParser.Package getPackage(String packageName) {
+ public AndroidPackage getPackage(String packageName) {
synchronized (mLock) {
packageName = resolveInternalPackageNameLPr(
packageName, PackageManager.VERSION_CODE_HIGHEST);
@@ -22813,10 +22230,10 @@ public class PackageManagerService extends IPackageManager.Stub
}
@Override
- public PackageParser.Package getPackage(int uid) {
+ public AndroidPackage getPackage(int uid) {
synchronized (mLock) {
final String[] packageNames = getPackagesForUid(uid);
- PackageParser.Package pkg = null;
+ AndroidPackage pkg = null;
final int numPackages = packageNames == null ? 0 : packageNames.length;
for (int i = 0; pkg == null && i < numPackages; i++) {
pkg = mPackages.get(packageNames[i]);
@@ -22825,6 +22242,12 @@ public class PackageManagerService extends IPackageManager.Stub
}
}
+ @Nullable
+ @Override
+ public PackageSetting getPackageSetting(String packageName) {
+ return PackageManagerService.this.getPackageSetting(packageName);
+ }
+
@Override
public PackageList getPackageList(PackageListObserver observer) {
synchronized (mLock) {
@@ -22849,17 +22272,19 @@ public class PackageManagerService extends IPackageManager.Stub
}
@Override
- public PackageParser.Package getDisabledSystemPackage(String packageName) {
+ public Object getDisabledSystemPackage(@NonNull String packageName) {
synchronized (mLock) {
- final PackageSetting ps = mSettings.getDisabledSystemPkgLPr(packageName);
- return (ps != null) ? ps.pkg : null;
+ return mSettings.getDisabledSystemPkgLPr(packageName);
}
}
@Override
- public @Nullable String getDisabledSystemPackageName(@NonNull String packageName) {
- PackageParser.Package pkg = getDisabledSystemPackage(packageName);
- return pkg == null ? null : pkg.packageName;
+ public @Nullable
+ String getDisabledSystemPackageName(@NonNull String packageName) {
+ PackageSetting disabledPkgSetting = (PackageSetting) getDisabledSystemPackage(
+ packageName);
+ AndroidPackage disabledPkg = disabledPkgSetting == null ? null : disabledPkgSetting.pkg;
+ return disabledPkg == null ? null : disabledPkg.getPackageName();
}
@Override
@@ -22930,7 +22355,7 @@ public class PackageManagerService extends IPackageManager.Stub
@Override
public boolean isPermissionsReviewRequired(String packageName, int userId) {
synchronized (mLock) {
- final PackageParser.Package pkg = mPackages.get(packageName);
+ final AndroidPackage pkg = mPackages.get(packageName);
if (pkg == null) {
return false;
}
@@ -23086,9 +22511,10 @@ public class PackageManagerService extends IPackageManager.Stub
}
@Override
- public boolean isEnabledAndMatches(ComponentInfo info, int flags, int userId) {
+ public boolean isEnabledAndMatches(ParsedComponent component, int flags, int userId) {
synchronized (mLock) {
- return mSettings.isEnabledAndMatchLPr(info, flags, userId);
+ AndroidPackage pkg = getPackage(component.getPackageName());
+ return mSettings.isEnabledAndMatchLPr(pkg, component, flags, userId);
}
}
@@ -23105,10 +22531,10 @@ public class PackageManagerService extends IPackageManager.Stub
}
@Override
- public boolean setInstalled(PackageParser.Package pkg, @UserIdInt int userId,
+ public boolean setInstalled(AndroidPackage pkg, @UserIdInt int userId,
boolean installed) {
synchronized (mLock) {
- final PackageSetting ps = mSettings.mPackages.get(pkg.packageName);
+ final PackageSetting ps = mSettings.mPackages.get(pkg.getPackageName());
if (ps.getInstalled(userId) != installed) {
ps.setInstalled(installed, userId);
return true;
@@ -23130,21 +22556,21 @@ public class PackageManagerService extends IPackageManager.Stub
public void grantImplicitAccess(int userId, Intent intent,
int callingUid, int targetAppId) {
synchronized (mLock) {
- final PackageParser.Package callingPackage = getPackage(callingUid);
- final PackageParser.Package targetPackage =
+ final AndroidPackage callingPackage = getPackage(callingUid);
+ final AndroidPackage targetPackage =
getPackage(UserHandle.getUid(userId, targetAppId));
if (callingPackage == null || targetPackage == null) {
return;
}
- final boolean instantApp = isInstantAppInternal(callingPackage.packageName, userId,
- callingUid);
+ final boolean instantApp = isInstantAppInternal(callingPackage.getPackageName(),
+ userId, callingUid);
if (instantApp) {
mInstantAppRegistry.grantInstantAccessLPw(userId, intent,
UserHandle.getAppId(callingUid), targetAppId);
} else {
- mAppsFilter.grantImplicitAccess(
- callingPackage.packageName, targetPackage.packageName, userId);
+ mAppsFilter.grantImplicitAccess(callingPackage.getPackageName(),
+ targetPackage.getPackageName(), userId);
}
}
}
@@ -23176,9 +22602,9 @@ public class PackageManagerService extends IPackageManager.Stub
@Override
public boolean isPackagePersistent(String packageName) {
synchronized (mLock) {
- PackageParser.Package pkg = mPackages.get(packageName);
+ AndroidPackage pkg = mPackages.get(packageName);
return pkg != null
- ? ((pkg.applicationInfo.flags&(ApplicationInfo.FLAG_SYSTEM
+ ? ((pkg.getFlags() & (ApplicationInfo.FLAG_SYSTEM
| ApplicationInfo.FLAG_PERSISTENT)) ==
(ApplicationInfo.FLAG_SYSTEM | ApplicationInfo.FLAG_PERSISTENT))
: false;
@@ -23186,9 +22612,9 @@ public class PackageManagerService extends IPackageManager.Stub
}
@Override
- public boolean isLegacySystemApp(PackageParser.Package pkg) {
+ public boolean isLegacySystemApp(AndroidPackage pkg) {
synchronized (mLock) {
- final PackageSetting ps = (PackageSetting) pkg.mExtras;
+ final PackageSetting ps = getPackageSetting(pkg.getPackageName());
return mPromoteSystemApps
&& ps.isSystem()
&& mExistingSystemPackages.contains(ps.name);
@@ -23199,9 +22625,10 @@ public class PackageManagerService extends IPackageManager.Stub
public List<PackageInfo> getOverlayPackages(int userId) {
final ArrayList<PackageInfo> overlayPackages = new ArrayList<PackageInfo>();
synchronized (mLock) {
- for (PackageParser.Package p : mPackages.values()) {
- if (p.mOverlayTarget != null) {
- PackageInfo pkg = generatePackageInfo((PackageSetting)p.mExtras, 0, userId);
+ for (AndroidPackage p : mPackages.values()) {
+ if (p.getOverlayTarget() != null) {
+ PackageInfo pkg = generatePackageInfo(getPackageSetting(p.getPackageName()),
+ 0, userId);
if (pkg != null) {
overlayPackages.add(pkg);
}
@@ -23215,9 +22642,9 @@ public class PackageManagerService extends IPackageManager.Stub
public List<String> getTargetPackageNames(int userId) {
List<String> targetPackages = new ArrayList<>();
synchronized (mLock) {
- for (PackageParser.Package p : mPackages.values()) {
- if (p.mOverlayTarget == null) {
- targetPackages.add(p.packageName);
+ for (AndroidPackage p : mPackages.values()) {
+ if (p.getOverlayTarget() == null) {
+ targetPackages.add(p.getPackageName());
}
}
}
@@ -23238,12 +22665,12 @@ public class PackageManagerService extends IPackageManager.Stub
overlayPaths = new ArrayList<>(N);
for (int i = 0; i < N; i++) {
final String packageName = overlayPackageNames.get(i);
- final PackageParser.Package pkg = mPackages.get(packageName);
+ final AndroidPackage pkg = mPackages.get(packageName);
if (pkg == null) {
Slog.e(TAG, "failed to find package " + packageName);
return false;
}
- overlayPaths.add(pkg.baseCodePath);
+ overlayPaths.add(pkg.getBaseCodePath());
}
}
@@ -23361,12 +22788,12 @@ public class PackageManagerService extends IPackageManager.Stub
}
@Override
- public void forEachPackage(Consumer<PackageParser.Package> actionLocked) {
+ public void forEachPackage(Consumer<AndroidPackage> actionLocked) {
PackageManagerService.this.forEachPackage(actionLocked);
}
@Override
- public void forEachInstalledPackage(@NonNull Consumer<PackageParser.Package> actionLocked,
+ public void forEachInstalledPackage(@NonNull Consumer<AndroidPackage> actionLocked,
@UserIdInt int userId) {
PackageManagerService.this.forEachInstalledPackage(actionLocked, userId);
}
@@ -23415,7 +22842,7 @@ public class PackageManagerService extends IPackageManager.Stub
*/
@Override
public boolean compileLayouts(String packageName) {
- PackageParser.Package pkg;
+ AndroidPackage pkg;
synchronized (mLock) {
pkg = mPackages.get(packageName);
if (pkg == null) {
@@ -23522,12 +22949,12 @@ public class PackageManagerService extends IPackageManager.Stub
@Override
public boolean isCallerInstallerOfRecord(
- @NonNull PackageParser.Package pkg, int callingUid) {
+ @NonNull AndroidPackage pkg, int callingUid) {
synchronized (mLock) {
if (pkg == null) {
return false;
}
- final PackageSetting packageSetting = (PackageSetting) pkg.mExtras;
+ final PackageSetting packageSetting = getPackageSetting(pkg.getPackageName());
if (packageSetting == null) {
return false;
}
@@ -23624,7 +23051,16 @@ public class PackageManagerService extends IPackageManager.Stub
}
}
- void forEachPackage(Consumer<PackageParser.Package> actionLocked) {
+ @Nullable
+ public PackageSetting getPackageSetting(String packageName) {
+ synchronized (mPackages) {
+ packageName = resolveInternalPackageNameLPr(
+ packageName, PackageManager.VERSION_CODE_HIGHEST);
+ return mSettings.mPackages.get(packageName);
+ }
+ }
+
+ void forEachPackage(Consumer<AndroidPackage> actionLocked) {
synchronized (mLock) {
int numPackages = mPackages.size();
for (int i = 0; i < numPackages; i++) {
@@ -23633,13 +23069,13 @@ public class PackageManagerService extends IPackageManager.Stub
}
}
- void forEachInstalledPackage(@NonNull Consumer<PackageParser.Package> actionLocked,
+ void forEachInstalledPackage(@NonNull Consumer<AndroidPackage> actionLocked,
@UserIdInt int userId) {
synchronized (mLock) {
int numPackages = mPackages.size();
for (int i = 0; i < numPackages; i++) {
- PackageParser.Package pkg = mPackages.valueAt(i);
- PackageSetting setting = mSettings.getPackageLPr(pkg.packageName);
+ AndroidPackage pkg = mPackages.valueAt(i);
+ PackageSetting setting = mSettings.getPackageLPr(pkg.getPackageName());
if (setting == null || !setting.getInstalled(userId)) {
continue;
}
@@ -23656,7 +23092,7 @@ public class PackageManagerService extends IPackageManager.Stub
* Return a <b>copy</b> of the collection of packages known to the package manager.
* @return A copy of the values of mPackages.
*/
- Collection<PackageParser.Package> getPackages() {
+ Collection<AndroidPackage> getPackages() {
synchronized (mLock) {
return new ArrayList<>(mPackages.values());
}
@@ -23692,8 +23128,8 @@ public class PackageManagerService extends IPackageManager.Stub
return mCompilerStats.getPackageStats(pkgName);
}
- public CompilerStats.PackageStats getOrCreateCompilerPackageStats(PackageParser.Package pkg) {
- return getOrCreateCompilerPackageStats(pkg.packageName);
+ public CompilerStats.PackageStats getOrCreateCompilerPackageStats(AndroidPackage pkg) {
+ return getOrCreateCompilerPackageStats(pkg.getPackageName());
}
public CompilerStats.PackageStats getOrCreateCompilerPackageStats(String pkgName) {
@@ -23803,7 +23239,7 @@ public class PackageManagerService extends IPackageManager.Stub
boolean canHaveOatDir(String packageName) {
synchronized (mLock) {
- PackageParser.Package p = mPackages.get(packageName);
+ AndroidPackage p = mPackages.get(packageName);
if (p == null) {
return false;
}
@@ -23811,11 +23247,11 @@ public class PackageManagerService extends IPackageManager.Stub
}
}
- private String getOatDir(PackageParser.Package pkg) {
+ private String getOatDir(AndroidPackage pkg) {
if (!pkg.canHaveOatDir()) {
return null;
}
- File codePath = new File(pkg.codePath);
+ File codePath = new File(pkg.getCodePath());
if (codePath.isDirectory()) {
return PackageDexOptimizer.getOatDir(codePath).getAbsolutePath();
}
@@ -23826,11 +23262,12 @@ public class PackageManagerService extends IPackageManager.Stub
final String[] instructionSets;
final List<String> codePaths;
final String oatDir;
- final PackageParser.Package pkg;
+ final AndroidPackage pkg;
synchronized (mLock) {
pkg = mPackages.get(packageName);
}
- instructionSets = getAppDexInstructionSets(pkg.applicationInfo);
+ instructionSets = getAppDexInstructionSets(pkg.getPrimaryCpuAbi(),
+ pkg.getSecondaryCpuAbi());
codePaths = pkg.getAllCodePaths();
oatDir = getOatDir(pkg);
@@ -23849,19 +23286,19 @@ public class PackageManagerService extends IPackageManager.Stub
Set<String> unusedPackages = new HashSet<>();
long currentTimeInMillis = System.currentTimeMillis();
synchronized (mLock) {
- for (PackageParser.Package pkg : mPackages.values()) {
- PackageSetting ps = mSettings.mPackages.get(pkg.packageName);
+ for (AndroidPackage pkg : mPackages.values()) {
+ PackageSetting ps = mSettings.mPackages.get(pkg.getPackageName());
if (ps == null) {
continue;
}
PackageDexUsage.PackageUseInfo packageUseInfo =
- getDexManager().getPackageUseInfoOrDefault(pkg.packageName);
+ getDexManager().getPackageUseInfoOrDefault(pkg.getPackageName());
if (PackageManagerServiceUtils
.isUnusedSinceTimeInMillis(ps.firstInstallTime, currentTimeInMillis,
downgradeTimeThresholdMillis, packageUseInfo,
pkg.getLatestPackageUseTimeInMills(),
pkg.getLatestForegroundPackageUseTimeInMills())) {
- unusedPackages.add(pkg.packageName);
+ unusedPackages.add(pkg.getPackageName());
}
}
}
diff --git a/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java b/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java
index ef47410ded8c..ded9a9c58c5e 100644
--- a/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java
+++ b/services/core/java/com/android/server/pm/PackageManagerServiceUtils.java
@@ -35,10 +35,13 @@ import android.content.Intent;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfoLite;
import android.content.pm.PackageManager;
+import android.content.pm.PackageManagerInternal;
import android.content.pm.PackageParser;
import android.content.pm.PackageParser.PackageParserException;
import android.content.pm.ResolveInfo;
import android.content.pm.Signature;
+import android.content.pm.parsing.AndroidPackage;
+import android.content.pm.parsing.ApkParseUtils;
import android.os.Build;
import android.os.Debug;
import android.os.Environment;
@@ -120,7 +123,7 @@ public class PackageManagerServiceUtils {
// Sort a list of apps by their last usage, most recently used apps first. The order of
// packages without usage data is undefined (but they will be sorted after the packages
// that do have usage data).
- public static void sortPackagesByUsageDate(List<PackageParser.Package> pkgs,
+ public static void sortPackagesByUsageDate(List<AndroidPackage> pkgs,
PackageManagerService packageManagerService) {
if (!packageManagerService.isHistoricalPackageUsageAvailable()) {
return;
@@ -135,12 +138,12 @@ public class PackageManagerServiceUtils {
// package will be removed from {@code packages} and added to {@code result} with its
// dependencies. If usage data is available, the positive packages will be sorted by usage
// data (with {@code sortTemp} as temporary storage).
- private static void applyPackageFilter(Predicate<PackageParser.Package> filter,
- Collection<PackageParser.Package> result,
- Collection<PackageParser.Package> packages,
- @NonNull List<PackageParser.Package> sortTemp,
+ private static void applyPackageFilter(Predicate<AndroidPackage> filter,
+ Collection<AndroidPackage> result,
+ Collection<AndroidPackage> packages,
+ @NonNull List<AndroidPackage> sortTemp,
PackageManagerService packageManagerService) {
- for (PackageParser.Package pkg : packages) {
+ for (AndroidPackage pkg : packages) {
if (filter.test(pkg)) {
sortTemp.add(pkg);
}
@@ -149,10 +152,10 @@ public class PackageManagerServiceUtils {
sortPackagesByUsageDate(sortTemp, packageManagerService);
packages.removeAll(sortTemp);
- for (PackageParser.Package pkg : sortTemp) {
+ for (AndroidPackage pkg : sortTemp) {
result.add(pkg);
- Collection<PackageParser.Package> deps =
+ Collection<AndroidPackage> deps =
packageManagerService.findSharedNonSystemLibraries(pkg);
if (!deps.isEmpty()) {
deps.removeAll(result);
@@ -166,50 +169,51 @@ public class PackageManagerServiceUtils {
// Sort apps by importance for dexopt ordering. Important apps are given
// more priority in case the device runs out of space.
- public static List<PackageParser.Package> getPackagesForDexopt(
- Collection<PackageParser.Package> packages,
+ public static List<AndroidPackage> getPackagesForDexopt(
+ Collection<AndroidPackage> packages,
PackageManagerService packageManagerService) {
return getPackagesForDexopt(packages, packageManagerService, DEBUG_DEXOPT);
}
- public static List<PackageParser.Package> getPackagesForDexopt(
- Collection<PackageParser.Package> packages,
+ public static List<AndroidPackage> getPackagesForDexopt(
+ Collection<AndroidPackage> packages,
PackageManagerService packageManagerService,
boolean debug) {
- ArrayList<PackageParser.Package> remainingPkgs = new ArrayList<>(packages);
- LinkedList<PackageParser.Package> result = new LinkedList<>();
- ArrayList<PackageParser.Package> sortTemp = new ArrayList<>(remainingPkgs.size());
+ ArrayList<AndroidPackage> remainingPkgs = new ArrayList<>(packages);
+ LinkedList<AndroidPackage> result = new LinkedList<>();
+ ArrayList<AndroidPackage> sortTemp = new ArrayList<>(remainingPkgs.size());
// Give priority to core apps.
- applyPackageFilter((pkg) -> pkg.coreApp, result, remainingPkgs, sortTemp,
+ applyPackageFilter((pkg) -> pkg.isCoreApp(), result, remainingPkgs, sortTemp,
packageManagerService);
// Give priority to system apps that listen for pre boot complete.
Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
final ArraySet<String> pkgNames = getPackageNamesForIntent(intent, UserHandle.USER_SYSTEM);
- applyPackageFilter((pkg) -> pkgNames.contains(pkg.packageName), result, remainingPkgs,
+ applyPackageFilter((pkg) -> pkgNames.contains(pkg.getPackageName()), result, remainingPkgs,
sortTemp, packageManagerService);
// Give priority to apps used by other apps.
DexManager dexManager = packageManagerService.getDexManager();
applyPackageFilter((pkg) ->
- dexManager.getPackageUseInfoOrDefault(pkg.packageName)
+ dexManager.getPackageUseInfoOrDefault(pkg.getPackageName())
.isAnyCodePathUsedByOtherApps(),
result, remainingPkgs, sortTemp, packageManagerService);
// Filter out packages that aren't recently used, add all remaining apps.
// TODO: add a property to control this?
- Predicate<PackageParser.Package> remainingPredicate;
+ Predicate<AndroidPackage> remainingPredicate;
if (!remainingPkgs.isEmpty() && packageManagerService.isHistoricalPackageUsageAvailable()) {
if (debug) {
Log.i(TAG, "Looking at historical package use");
}
// Get the package that was used last.
- PackageParser.Package lastUsed = Collections.max(remainingPkgs, (pkg1, pkg2) ->
+ AndroidPackage lastUsed = Collections.max(remainingPkgs, (pkg1, pkg2) ->
Long.compare(pkg1.getLatestForegroundPackageUseTimeInMills(),
pkg2.getLatestForegroundPackageUseTimeInMills()));
if (debug) {
- Log.i(TAG, "Taking package " + lastUsed.packageName + " as reference in time use");
+ Log.i(TAG, "Taking package " + lastUsed.getPackageName()
+ + " as reference in time use");
}
long estimatedPreviousSystemUseTime =
lastUsed.getLatestForegroundPackageUseTimeInMills();
@@ -285,13 +289,13 @@ public class PackageManagerServiceUtils {
}
}
- public static String packagesToString(Collection<PackageParser.Package> c) {
+ public static String packagesToString(Collection<AndroidPackage> c) {
StringBuilder sb = new StringBuilder();
- for (PackageParser.Package pkg : c) {
+ for (AndroidPackage pkg : c) {
if (sb.length() > 0) {
sb.append(", ");
}
- sb.append(pkg.packageName);
+ sb.append(pkg.getPackageName());
}
return sb.toString();
}
@@ -309,16 +313,16 @@ public class PackageManagerServiceUtils {
return false;
}
- public static long getLastModifiedTime(PackageParser.Package pkg) {
- final File srcFile = new File(pkg.codePath);
+ public static long getLastModifiedTime(AndroidPackage pkg) {
+ final File srcFile = new File(pkg.getCodePath());
if (!srcFile.isDirectory()) {
return srcFile.lastModified();
}
- final File baseFile = new File(pkg.baseCodePath);
+ final File baseFile = new File(pkg.getBaseCodePath());
long maxModifiedTime = baseFile.lastModified();
- if (pkg.splitCodePaths != null) {
- for (int i = pkg.splitCodePaths.length - 1; i >=0; --i) {
- final File splitFile = new File(pkg.splitCodePaths[i]);
+ if (pkg.getSplitCodePaths() != null) {
+ for (int i = pkg.getSplitCodePaths().length - 1; i >=0; --i) {
+ final File splitFile = new File(pkg.getSplitCodePaths()[i]);
maxModifiedTime = Math.max(maxModifiedTime, splitFile.lastModified());
}
}
@@ -539,7 +543,7 @@ public class PackageManagerServiceUtils {
private static boolean matchSignatureInSystem(PackageSetting pkgSetting,
PackageSetting disabledPkgSetting) {
try {
- PackageParser.collectCertificates(disabledPkgSetting.pkg, true /* skipVerify */);
+ ApkParseUtils.collectCertificates(disabledPkgSetting.pkg, true /* skipVerify */);
if (pkgSetting.signatures.mSigningDetails.checkCapability(
disabledPkgSetting.signatures.mSigningDetails,
PackageParser.SigningDetails.CertCapabilities.INSTALLED_DATA)
@@ -905,8 +909,10 @@ public class PackageManagerServiceUtils {
* Returns the {@link PermissionsState} for the given package. If the {@link PermissionsState}
* could not be found, {@code null} will be returned.
*/
- public static PermissionsState getPermissionsState(PackageParser.Package pkg) {
- final PackageSetting packageSetting = (PackageSetting) pkg.mExtras;
+ public static PermissionsState getPermissionsState(
+ PackageManagerInternal packageManagerInternal, AndroidPackage pkg) {
+ final PackageSetting packageSetting =
+ (PackageSetting) packageManagerInternal.getPackageSetting(pkg.getPackageName());
if (packageSetting == null) {
return null;
}
diff --git a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
index 3f32f3dde3ae..121d709cc037 100644
--- a/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
+++ b/services/core/java/com/android/server/pm/PackageManagerShellCommand.java
@@ -48,7 +48,6 @@ import android.content.pm.PackageItemInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.PackageManagerInternal;
-import android.content.pm.PackageParser;
import android.content.pm.PackageParser.ApkLite;
import android.content.pm.PackageParser.PackageLite;
import android.content.pm.PackageParser.PackageParserException;
@@ -62,6 +61,7 @@ import android.content.pm.VersionedPackage;
import android.content.pm.dex.ArtManager;
import android.content.pm.dex.DexMetadataHelper;
import android.content.pm.dex.ISnapshotRuntimeProfileCallback;
+import android.content.pm.parsing.ApkLiteParseUtils;
import android.content.res.AssetManager;
import android.content.res.Resources;
import android.content.rollback.IRollbackManager;
@@ -446,7 +446,7 @@ class PackageManagerShellCommand extends ShellCommand {
throw new IllegalArgumentException("Error: Can't open file: " + inPath);
}
try {
- ApkLite baseApk = PackageParser.parseApkLite(fd.getFileDescriptor(), inPath, 0);
+ ApkLite baseApk = ApkLiteParseUtils.parseApkLite(fd.getFileDescriptor(), inPath, 0);
PackageLite pkgLite = new PackageLite(null, baseApk, null, null, null, null,
null, null);
params.sessionParams.setSize(PackageHelper.calculateInstalledSize(
diff --git a/services/core/java/com/android/server/pm/PackageSetting.java b/services/core/java/com/android/server/pm/PackageSetting.java
index 4ea8a30fa206..44928fbd48c0 100644
--- a/services/core/java/com/android/server/pm/PackageSetting.java
+++ b/services/core/java/com/android/server/pm/PackageSetting.java
@@ -18,8 +18,9 @@ package com.android.server.pm;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
-import android.content.pm.PackageParser;
import android.content.pm.UserInfo;
+import android.content.pm.parsing.AndroidPackage;
+import android.content.pm.parsing.ParsedPackage;
import android.service.pm.PackageProto;
import android.util.proto.ProtoOutputStream;
@@ -31,9 +32,11 @@ import java.util.List;
/**
* Settings data for a particular package we know about.
*/
-public final class PackageSetting extends PackageSettingBase {
+public final class PackageSetting extends PackageSettingBase implements
+ ParsedPackage.PackageSettingCallback {
int appId;
- PackageParser.Package pkg;
+
+ public AndroidPackage pkg;
/**
* WARNING. The object reference is important. We perform integer equality and NOT
* object equality to check whether shared user settings are the same.
@@ -50,12 +53,12 @@ public final class PackageSetting extends PackageSettingBase {
PackageSetting(String name, String realName, File codePath, File resourcePath,
String legacyNativeLibraryPathString, String primaryCpuAbiString,
String secondaryCpuAbiString, String cpuAbiOverrideString,
- long pVersionCode, int pkgFlags, int privateFlags, String parentPackageName,
- List<String> childPackageNames, int sharedUserId, String[] usesStaticLibraries,
+ long pVersionCode, int pkgFlags, int privateFlags,
+ int sharedUserId, String[] usesStaticLibraries,
long[] usesStaticLibrariesVersions) {
super(name, realName, codePath, resourcePath, legacyNativeLibraryPathString,
primaryCpuAbiString, secondaryCpuAbiString, cpuAbiOverrideString,
- pVersionCode, pkgFlags, privateFlags, parentPackageName, childPackageNames,
+ pVersionCode, pkgFlags, privateFlags,
usesStaticLibraries, usesStaticLibrariesVersions);
this.sharedUserId = sharedUserId;
}
@@ -116,10 +119,6 @@ public final class PackageSetting extends PackageSettingBase {
: super.getPermissionsState();
}
- public PackageParser.Package getPackage() {
- return pkg;
- }
-
public int getAppId() {
return appId;
}
@@ -132,6 +131,7 @@ public final class PackageSetting extends PackageSettingBase {
return installPermissionsFixed;
}
+ // TODO(b/135203078): Remove these in favor of reading from the package directly
public boolean isPrivileged() {
return (pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_PRIVILEGED) != 0;
}
@@ -176,10 +176,6 @@ public final class PackageSetting extends PackageSettingBase {
return true;
}
- public boolean hasChildPackages() {
- return childPackageNames != null && !childPackageNames.isEmpty();
- }
-
public void writeToProto(ProtoOutputStream proto, long fieldId, List<UserInfo> users) {
final long packageToken = proto.start(fieldId);
proto.write(PackageProto.NAME, (realName != null ? realName : name));
@@ -190,18 +186,19 @@ public final class PackageSetting extends PackageSettingBase {
proto.write(PackageProto.INSTALLER_NAME, installerPackageName);
if (pkg != null) {
- proto.write(PackageProto.VERSION_STRING, pkg.mVersionName);
+ proto.write(PackageProto.VERSION_STRING, pkg.getVersionName());
long splitToken = proto.start(PackageProto.SPLITS);
proto.write(PackageProto.SplitProto.NAME, "base");
- proto.write(PackageProto.SplitProto.REVISION_CODE, pkg.baseRevisionCode);
+ proto.write(PackageProto.SplitProto.REVISION_CODE, pkg.getBaseRevisionCode());
proto.end(splitToken);
- if (pkg.splitNames != null) {
- for (int i = 0; i < pkg.splitNames.length; i++) {
+ if (pkg.getSplitNames() != null) {
+ for (int i = 0; i < pkg.getSplitNames().length; i++) {
splitToken = proto.start(PackageProto.SPLITS);
- proto.write(PackageProto.SplitProto.NAME, pkg.splitNames[i]);
- proto.write(PackageProto.SplitProto.REVISION_CODE, pkg.splitRevisionCodes[i]);
+ proto.write(PackageProto.SplitProto.NAME, pkg.getSplitNames()[i]);
+ proto.write(PackageProto.SplitProto.REVISION_CODE,
+ pkg.getSplitRevisionCodes()[i]);
proto.end(splitToken);
}
}
@@ -218,4 +215,10 @@ public final class PackageSetting extends PackageSettingBase {
sharedUserId = other.sharedUserId;
sharedUser = other.sharedUser;
}
+
+ // TODO(b/135203078): Move to constructor
+ @Override
+ public void setAndroidPackage(AndroidPackage pkg) {
+ this.pkg = pkg;
+ }
}
diff --git a/services/core/java/com/android/server/pm/PackageSettingBase.java b/services/core/java/com/android/server/pm/PackageSettingBase.java
index 029673ffd87b..09c1789cf445 100644
--- a/services/core/java/com/android/server/pm/PackageSettingBase.java
+++ b/services/core/java/com/android/server/pm/PackageSettingBase.java
@@ -36,7 +36,6 @@ import android.util.proto.ProtoOutputStream;
import com.android.internal.annotations.VisibleForTesting;
import java.io.File;
-import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
@@ -51,9 +50,6 @@ public abstract class PackageSettingBase extends SettingBase {
public final String name;
final String realName;
- String parentPackageName;
- List<String> childPackageNames;
-
/**
* Path where this package was found on disk. For monolithic packages
* this is path to single base APK file; for cluster packages this is
@@ -137,14 +133,10 @@ public abstract class PackageSettingBase extends SettingBase {
String legacyNativeLibraryPathString, String primaryCpuAbiString,
String secondaryCpuAbiString, String cpuAbiOverrideString,
long pVersionCode, int pkgFlags, int pkgPrivateFlags,
- String parentPackageName, List<String> childPackageNames,
String[] usesStaticLibraries, long[] usesStaticLibrariesVersions) {
super(pkgFlags, pkgPrivateFlags);
this.name = name;
this.realName = realName;
- this.parentPackageName = parentPackageName;
- this.childPackageNames = (childPackageNames != null)
- ? new ArrayList<>(childPackageNames) : null;
this.usesStaticLibraries = usesStaticLibraries;
this.usesStaticLibrariesVersions = usesStaticLibrariesVersions;
init(codePath, resourcePath, legacyNativeLibraryPathString, primaryCpuAbiString,
@@ -232,8 +224,6 @@ public abstract class PackageSettingBase extends SettingBase {
}
private void doCopy(PackageSettingBase orig) {
- childPackageNames = (orig.childPackageNames != null)
- ? new ArrayList<>(orig.childPackageNames) : null;
codePath = orig.codePath;
codePathString = orig.codePathString;
cpuAbiOverrideString = orig.cpuAbiOverrideString;
@@ -245,7 +235,6 @@ public abstract class PackageSettingBase extends SettingBase {
lastUpdateTime = orig.lastUpdateTime;
legacyNativeLibraryPathString = orig.legacyNativeLibraryPathString;
// Intentionally skip mOldCodePaths; it's not relevant for copies
- parentPackageName = orig.parentPackageName;
primaryCpuAbiString = orig.primaryCpuAbiString;
resourcePath = orig.resourcePath;
resourcePathString = orig.resourcePathString;
@@ -657,8 +646,6 @@ public abstract class PackageSettingBase extends SettingBase {
protected PackageSettingBase updateFrom(PackageSettingBase other) {
super.copyFrom(other);
- this.parentPackageName = other.parentPackageName;
- this.childPackageNames = other.childPackageNames;
this.codePath = other.codePath;
this.codePathString = other.codePathString;
this.resourcePath = other.resourcePath;
diff --git a/services/core/java/com/android/server/pm/PackageUsage.java b/services/core/java/com/android/server/pm/PackageUsage.java
index ac1f739cd9f8..ce2c9e767d5e 100644
--- a/services/core/java/com/android/server/pm/PackageUsage.java
+++ b/services/core/java/com/android/server/pm/PackageUsage.java
@@ -20,7 +20,7 @@ import static android.os.Process.PACKAGE_INFO_GID;
import static android.os.Process.SYSTEM_UID;
import android.content.pm.PackageManager;
-import android.content.pm.PackageParser;
+import android.content.pm.parsing.AndroidPackage;
import android.os.FileUtils;
import android.util.AtomicFile;
import android.util.Log;
@@ -36,7 +36,7 @@ import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.Map;
-class PackageUsage extends AbstractStatsBase<Map<String, PackageParser.Package>> {
+class PackageUsage extends AbstractStatsBase<Map<String, AndroidPackage>> {
private static final String USAGE_FILE_MAGIC = "PACKAGE_USAGE__VERSION_";
private static final String USAGE_FILE_MAGIC_VERSION_1 = USAGE_FILE_MAGIC + "1";
@@ -52,7 +52,7 @@ class PackageUsage extends AbstractStatsBase<Map<String, PackageParser.Package>>
}
@Override
- protected void writeInternal(Map<String, PackageParser.Package> packages) {
+ protected void writeInternal(Map<String, AndroidPackage> packages) {
AtomicFile file = getFile();
FileOutputStream f = null;
try {
@@ -66,13 +66,13 @@ class PackageUsage extends AbstractStatsBase<Map<String, PackageParser.Package>>
sb.append('\n');
out.write(sb.toString().getBytes(StandardCharsets.US_ASCII));
- for (PackageParser.Package pkg : packages.values()) {
+ for (AndroidPackage pkg : packages.values()) {
if (pkg.getLatestPackageUseTimeInMills() == 0L) {
continue;
}
sb.setLength(0);
- sb.append(pkg.packageName);
- for (long usageTimeInMillis : pkg.mLastPackageUsageTimeInMills) {
+ sb.append(pkg.getPackageName());
+ for (long usageTimeInMillis : pkg.getLastPackageUsageTimeInMills()) {
sb.append(' ');
sb.append(usageTimeInMillis);
}
@@ -90,7 +90,7 @@ class PackageUsage extends AbstractStatsBase<Map<String, PackageParser.Package>>
}
@Override
- protected void readInternal(Map<String, PackageParser.Package> packages) {
+ protected void readInternal(Map<String, AndroidPackage> packages) {
AtomicFile file = getFile();
BufferedInputStream in = null;
try {
@@ -114,7 +114,7 @@ class PackageUsage extends AbstractStatsBase<Map<String, PackageParser.Package>>
}
}
- private void readVersion0LP(Map<String, PackageParser.Package> packages, InputStream in,
+ private void readVersion0LP(Map<String, AndroidPackage> packages, InputStream in,
StringBuffer sb, String firstLine)
throws IOException {
// Initial version of the file had no version number and stored one
@@ -128,7 +128,7 @@ class PackageUsage extends AbstractStatsBase<Map<String, PackageParser.Package>>
}
String packageName = tokens[0];
- PackageParser.Package pkg = packages.get(packageName);
+ AndroidPackage pkg = packages.get(packageName);
if (pkg == null) {
continue;
}
@@ -137,12 +137,12 @@ class PackageUsage extends AbstractStatsBase<Map<String, PackageParser.Package>>
for (int reason = 0;
reason < PackageManager.NOTIFY_PACKAGE_USE_REASONS_COUNT;
reason++) {
- pkg.mLastPackageUsageTimeInMills[reason] = timestamp;
+ pkg.mutate().setLastPackageUsageTimeInMills(reason, timestamp);
}
}
}
- private void readVersion1LP(Map<String, PackageParser.Package> packages, InputStream in,
+ private void readVersion1LP(Map<String, AndroidPackage> packages, InputStream in,
StringBuffer sb) throws IOException {
// Version 1 of the file started with the corresponding version
// number and then stored a package name and eight timestamps per line.
@@ -154,7 +154,7 @@ class PackageUsage extends AbstractStatsBase<Map<String, PackageParser.Package>>
}
String packageName = tokens[0];
- PackageParser.Package pkg = packages.get(packageName);
+ AndroidPackage pkg = packages.get(packageName);
if (pkg == null) {
continue;
}
@@ -162,7 +162,8 @@ class PackageUsage extends AbstractStatsBase<Map<String, PackageParser.Package>>
for (int reason = 0;
reason < PackageManager.NOTIFY_PACKAGE_USE_REASONS_COUNT;
reason++) {
- pkg.mLastPackageUsageTimeInMills[reason] = parseAsLong(tokens[reason + 1]);
+ pkg.mutate().setLastPackageUsageTimeInMills(reason,
+ parseAsLong(tokens[reason + 1]));
}
}
}
@@ -196,4 +197,4 @@ class PackageUsage extends AbstractStatsBase<Map<String, PackageParser.Package>>
sb.append((char)ch);
}
}
-} \ No newline at end of file
+}
diff --git a/services/core/java/com/android/server/pm/ParallelPackageParser.java b/services/core/java/com/android/server/pm/ParallelPackageParser.java
index 4ff3e1218b53..a5065145cafd 100644
--- a/services/core/java/com/android/server/pm/ParallelPackageParser.java
+++ b/services/core/java/com/android/server/pm/ParallelPackageParser.java
@@ -16,7 +16,10 @@
package com.android.server.pm;
+import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER;
+
import android.content.pm.PackageParser;
+import android.content.pm.parsing.ParsedPackage;
import android.os.Process;
import android.os.Trace;
import android.util.DisplayMetrics;
@@ -30,8 +33,6 @@ import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ExecutorService;
-import static android.os.Trace.TRACE_TAG_PACKAGE_MANAGER;
-
/**
* Helper class for parallel parsing of packages using {@link PackageParser}.
* <p>Parsing requests are processed by a thread-pool of {@link #MAX_THREADS}.
@@ -65,14 +66,14 @@ class ParallelPackageParser implements AutoCloseable {
static class ParseResult {
- PackageParser.Package pkg; // Parsed package
+ ParsedPackage parsedPackage; // Parsed package
File scanFile; // File that was parsed
Throwable throwable; // Set if an error occurs during parsing
@Override
public String toString() {
return "ParseResult{" +
- "pkg=" + pkg +
+ "parsedPackage=" + parsedPackage +
", scanFile=" + scanFile +
", throwable=" + throwable +
'}';
@@ -100,7 +101,7 @@ class ParallelPackageParser implements AutoCloseable {
/**
* Submits the file for parsing
* @param scanFile file to scan
- * @param parseFlags parse falgs
+ * @param parseFlags parse flags
*/
public void submit(File scanFile, int parseFlags) {
mService.submit(() -> {
@@ -114,7 +115,7 @@ class ParallelPackageParser implements AutoCloseable {
pp.setCacheDir(mCacheDir);
pp.setCallback(mPackageParserCallback);
pr.scanFile = scanFile;
- pr.pkg = parsePackage(pp, scanFile, parseFlags);
+ pr.parsedPackage = parsePackage(pp, scanFile, parseFlags);
} catch (Throwable e) {
pr.throwable = e;
} finally {
@@ -133,9 +134,9 @@ class ParallelPackageParser implements AutoCloseable {
}
@VisibleForTesting
- protected PackageParser.Package parsePackage(PackageParser packageParser, File scanFile,
+ protected ParsedPackage parsePackage(PackageParser packageParser, File scanFile,
int parseFlags) throws PackageParser.PackageParserException {
- return packageParser.parsePackage(scanFile, parseFlags, true /* useCaches */);
+ return packageParser.parseParsedPackage(scanFile, parseFlags, true);
}
@Override
diff --git a/services/core/java/com/android/server/pm/SELinuxMMAC.java b/services/core/java/com/android/server/pm/SELinuxMMAC.java
index b94047e119d5..4f47afe6956a 100644
--- a/services/core/java/com/android/server/pm/SELinuxMMAC.java
+++ b/services/core/java/com/android/server/pm/SELinuxMMAC.java
@@ -16,9 +16,9 @@
package com.android.server.pm;
-import android.content.pm.PackageParser;
import android.content.pm.PackageParser.SigningDetails;
import android.content.pm.Signature;
+import android.content.pm.parsing.AndroidPackage;
import android.os.Environment;
import android.util.Slog;
import android.util.Xml;
@@ -325,7 +325,7 @@ public final class SELinuxMMAC {
* MINIMUM_TARGETSDKVERSION.
* @return String representing the resulting seinfo.
*/
- public static String getSeInfo(PackageParser.Package pkg, boolean isPrivileged,
+ public static String getSeInfo(AndroidPackage pkg, boolean isPrivileged,
int targetSdkVersion) {
String seInfo = null;
synchronized (sPolicies) {
@@ -354,8 +354,8 @@ public final class SELinuxMMAC {
seInfo += TARGETSDKVERSION_STR + targetSdkVersion;
if (DEBUG_POLICY_INSTALL) {
- Slog.i(TAG, "package (" + pkg.packageName + ") labeled with " +
- "seinfo=" + seInfo);
+ Slog.i(TAG, "package (" + pkg.getPackageName() + ") labeled with "
+ + "seinfo=" + seInfo);
}
return seInfo;
}
@@ -364,7 +364,7 @@ public final class SELinuxMMAC {
/**
* Holds valid policy representations of individual stanzas from a mac_permissions.xml
* file. Each instance can further be used to assign seinfo values to apks using the
- * {@link Policy#getMatchedSeinfo} method. To create an instance of this use the
+ * {@link Policy#getMatchedSeInfo(AndroidPackage)} method. To create an instance of this use the
* {@link PolicyBuilder} pattern class, where each instance is validated against a set
* of invariants before being built and returned. Each instance can be guaranteed to
* hold one valid policy stanza as outlined in the system/sepolicy/mac_permissions.xml
@@ -491,21 +491,21 @@ final class Policy {
* @return A string representing the seinfo matched during policy lookup.
* A value of null can also be returned if no match occured.
*/
- public String getMatchedSeInfo(PackageParser.Package pkg) {
+ public String getMatchedSeInfo(AndroidPackage pkg) {
// Check for exact signature matches across all certs.
Signature[] certs = mCerts.toArray(new Signature[0]);
- if (pkg.mSigningDetails != SigningDetails.UNKNOWN
- && !Signature.areExactMatch(certs, pkg.mSigningDetails.signatures)) {
+ if (pkg.getSigningDetails() != SigningDetails.UNKNOWN
+ && !Signature.areExactMatch(certs, pkg.getSigningDetails().signatures)) {
// certs aren't exact match, but the package may have rotated from the known system cert
- if (certs.length > 1 || !pkg.mSigningDetails.hasCertificate(certs[0])) {
+ if (certs.length > 1 || !pkg.getSigningDetails().hasCertificate(certs[0])) {
return null;
}
}
// Check for inner package name matches given that the
// signature checks already passed.
- String seinfoValue = mPkgMap.get(pkg.packageName);
+ String seinfoValue = mPkgMap.get(pkg.getPackageName());
if (seinfoValue != null) {
return seinfoValue;
}
diff --git a/services/core/java/com/android/server/pm/Settings.java b/services/core/java/com/android/server/pm/Settings.java
index 4349ea75809c..7d6c4824a520 100644
--- a/services/core/java/com/android/server/pm/Settings.java
+++ b/services/core/java/com/android/server/pm/Settings.java
@@ -42,7 +42,6 @@ import android.content.pm.ComponentInfo;
import android.content.pm.IntentFilterVerificationInfo;
import android.content.pm.PackageManager;
import android.content.pm.PackageManagerInternal;
-import android.content.pm.PackageParser;
import android.content.pm.PackageUserState;
import android.content.pm.PermissionInfo;
import android.content.pm.ResolveInfo;
@@ -50,6 +49,10 @@ import android.content.pm.Signature;
import android.content.pm.SuspendDialogInfo;
import android.content.pm.UserInfo;
import android.content.pm.VerifierDeviceIdentity;
+import android.content.pm.parsing.AndroidPackage;
+import android.content.pm.parsing.ComponentParseUtils;
+import android.content.pm.parsing.ComponentParseUtils.ParsedComponent;
+import android.content.pm.parsing.ComponentParseUtils.ParsedPermission;
import android.net.Uri;
import android.os.Binder;
import android.os.Build;
@@ -466,8 +469,8 @@ public final class Settings {
final PackageSetting dp = mDisabledSysPackages.get(name);
// always make sure the system package code and resource paths dont change
if (dp == null && p.pkg != null && p.pkg.isSystem() && !p.pkg.isUpdatedSystemApp()) {
- if((p.pkg != null) && (p.pkg.applicationInfo != null)) {
- p.pkg.applicationInfo.flags |= ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
+ if(p.pkg != null) {
+ p.pkg.mutate().setUpdatedSystemApp(true);
}
final PackageSetting disabled;
if (replaced) {
@@ -493,14 +496,14 @@ public final class Settings {
return null;
}
// Reset flag in ApplicationInfo object
- if((p.pkg != null) && (p.pkg.applicationInfo != null)) {
- p.pkg.applicationInfo.flags &= ~ApplicationInfo.FLAG_UPDATED_SYSTEM_APP;
+ if(p.pkg != null) {
+ p.pkg.mutate().setUpdatedSystemApp(false);
}
PackageSetting ret = addPackageLPw(name, p.realName, p.codePath, p.resourcePath,
p.legacyNativeLibraryPathString, p.primaryCpuAbiString,
p.secondaryCpuAbiString, p.cpuAbiOverrideString,
p.appId, p.versionCode, p.pkgFlags, p.pkgPrivateFlags,
- p.parentPackageName, p.childPackageNames, p.usesStaticLibraries,
+ p.usesStaticLibraries,
p.usesStaticLibrariesVersions);
mDisabledSysPackages.remove(name);
return ret;
@@ -517,8 +520,7 @@ public final class Settings {
PackageSetting addPackageLPw(String name, String realName, File codePath, File resourcePath,
String legacyNativeLibraryPathString, String primaryCpuAbiString,
String secondaryCpuAbiString, String cpuAbiOverrideString, int uid, long vc, int
- pkgFlags, int pkgPrivateFlags, String parentPackageName,
- List<String> childPackageNames, String[] usesStaticLibraries,
+ pkgFlags, int pkgPrivateFlags, String[] usesStaticLibraries,
long[] usesStaticLibraryNames) {
PackageSetting p = mPackages.get(name);
if (p != null) {
@@ -531,8 +533,8 @@ public final class Settings {
}
p = new PackageSetting(name, realName, codePath, resourcePath,
legacyNativeLibraryPathString, primaryCpuAbiString, secondaryCpuAbiString,
- cpuAbiOverrideString, vc, pkgFlags, pkgPrivateFlags, parentPackageName,
- childPackageNames, 0 /*userId*/, usesStaticLibraries, usesStaticLibraryNames);
+ cpuAbiOverrideString, vc, pkgFlags, pkgPrivateFlags,
+ 0 /*userId*/, usesStaticLibraries, usesStaticLibraryNames);
p.appId = uid;
if (registerExistingAppIdLPw(uid, p, name)) {
mPackages.put(name, p);
@@ -598,19 +600,15 @@ public final class Settings {
File codePath, File resourcePath, String legacyNativeLibraryPath, String primaryCpuAbi,
String secondaryCpuAbi, long versionCode, int pkgFlags, int pkgPrivateFlags,
UserHandle installUser, boolean allowInstall, boolean instantApp,
- boolean virtualPreload, String parentPkgName, List<String> childPkgNames,
- UserManagerService userManager,
+ boolean virtualPreload, UserManagerService userManager,
String[] usesStaticLibraries, long[] usesStaticLibrariesVersions) {
final PackageSetting pkgSetting;
if (originalPkg != null) {
if (PackageManagerService.DEBUG_UPGRADE) Log.v(PackageManagerService.TAG, "Package "
+ pkgName + " is adopting original package " + originalPkg.name);
pkgSetting = new PackageSetting(originalPkg, pkgName /*realPkgName*/);
- pkgSetting.childPackageNames =
- (childPkgNames != null) ? new ArrayList<>(childPkgNames) : null;
pkgSetting.codePath = codePath;
pkgSetting.legacyNativeLibraryPathString = legacyNativeLibraryPath;
- pkgSetting.parentPackageName = parentPkgName;
pkgSetting.pkgFlags = pkgFlags;
pkgSetting.pkgPrivateFlags = pkgPrivateFlags;
pkgSetting.primaryCpuAbiString = primaryCpuAbi;
@@ -628,7 +626,7 @@ public final class Settings {
pkgSetting = new PackageSetting(pkgName, realPkgName, codePath, resourcePath,
legacyNativeLibraryPath, primaryCpuAbi, secondaryCpuAbi,
null /*cpuAbiOverrideString*/, versionCode, pkgFlags, pkgPrivateFlags,
- parentPkgName, childPkgNames, 0 /*sharedUserId*/, usesStaticLibraries,
+ 0 /*sharedUserId*/, usesStaticLibraries,
usesStaticLibrariesVersions);
pkgSetting.setTimeStamp(codePath.lastModified());
pkgSetting.sharedUser = sharedUser;
@@ -715,7 +713,7 @@ public final class Settings {
@NonNull File codePath, File resourcePath,
@Nullable String legacyNativeLibraryPath, @Nullable String primaryCpuAbi,
@Nullable String secondaryCpuAbi, int pkgFlags, int pkgPrivateFlags,
- @Nullable List<String> childPkgNames, @NonNull UserManagerService userManager,
+ @NonNull UserManagerService userManager,
@Nullable String[] usesStaticLibraries, @Nullable long[] usesStaticLibrariesVersions)
throws PackageManagerException {
final String pkgName = pkgSetting.name;
@@ -793,9 +791,6 @@ public final class Settings {
pkgPrivateFlags & ApplicationInfo.PRIVATE_FLAG_ODM;
pkgSetting.primaryCpuAbiString = primaryCpuAbi;
pkgSetting.secondaryCpuAbiString = secondaryCpuAbi;
- if (childPkgNames != null) {
- pkgSetting.childPackageNames = new ArrayList<>(childPkgNames);
- }
// Update static shared library dependencies if needed
if (usesStaticLibraries != null && usesStaticLibrariesVersions != null
&& usesStaticLibraries.length == usesStaticLibrariesVersions.length) {
@@ -864,15 +859,15 @@ public final class Settings {
// TODO: Move to scanPackageOnlyLI() after verifying signatures are setup correctly
// by that time.
- void insertPackageSettingLPw(PackageSetting p, PackageParser.Package pkg) {
+ void insertPackageSettingLPw(PackageSetting p, AndroidPackage pkg) {
// Update signatures if needed.
if (p.signatures.mSigningDetails.signatures == null) {
- p.signatures.mSigningDetails = pkg.mSigningDetails;
+ p.signatures.mSigningDetails = pkg.getSigningDetails();
}
// If this app defines a shared user id initialize
// the shared user signatures as well.
if (p.sharedUser != null && p.sharedUser.signatures.mSigningDetails.signatures == null) {
- p.sharedUser.signatures.mSigningDetails = pkg.mSigningDetails;
+ p.sharedUser.signatures.mSigningDetails = pkg.getSigningDetails();
}
addPackageSettingLPw(p, p.sharedUser);
}
@@ -949,7 +944,7 @@ public final class Settings {
int affectedUserId = UserHandle.USER_NULL;
// Update permissions
- for (String eachPerm : deletedPs.pkg.requestedPermissions) {
+ for (String eachPerm : deletedPs.pkg.getRequestedPermissions()) {
BasePermission bp = mPermissions.getPermission(eachPerm);
if (bp == null) {
continue;
@@ -959,8 +954,8 @@ public final class Settings {
boolean used = false;
for (PackageSetting pkg : sus.packages) {
if (pkg.pkg != null
- && !pkg.pkg.packageName.equals(deletedPs.pkg.packageName)
- && pkg.pkg.requestedPermissions.contains(eachPerm)) {
+ && !pkg.pkg.getPackageName().equals(deletedPs.pkg.getPackageName())
+ && pkg.pkg.getRequestedPermissions().contains(eachPerm)) {
used = true;
break;
}
@@ -970,13 +965,13 @@ public final class Settings {
}
PermissionsState permissionsState = sus.getPermissionsState();
- PackageSetting disabledPs = getDisabledSystemPkgLPr(deletedPs.pkg.packageName);
+ PackageSetting disabledPs = getDisabledSystemPkgLPr(deletedPs.pkg.getPackageName());
// If the package is shadowing is a disabled system package,
// do not drop permissions that the shadowed package requests.
if (disabledPs != null) {
boolean reqByDisabledSysPkg = false;
- for (String permission : disabledPs.pkg.requestedPermissions) {
+ for (String permission : disabledPs.pkg.getRequestedPermissions()) {
if (permission.equals(eachPerm)) {
reqByDisabledSysPkg = true;
break;
@@ -2207,20 +2202,6 @@ public final class Settings {
serializer.endTag(null, TAG_PERMISSIONS);
}
- void writeChildPackagesLPw(XmlSerializer serializer, List<String> childPackageNames)
- throws IOException {
- if (childPackageNames == null) {
- return;
- }
- final int childCount = childPackageNames.size();
- for (int i = 0; i < childCount; i++) {
- String childPackageName = childPackageNames.get(i);
- serializer.startTag(null, TAG_CHILD_PACKAGE);
- serializer.attribute(null, ATTR_NAME, childPackageName);
- serializer.endTag(null, TAG_CHILD_PACKAGE);
- }
- }
-
void readUsesStaticLibLPw(XmlPullParser parser, PackageSetting outPs)
throws IOException, XmlPullParserException {
int outerDepth = parser.getDepth();
@@ -2674,17 +2655,15 @@ public final class Settings {
StringBuilder sb = new StringBuilder();
for (final PackageSetting pkg : mPackages.values()) {
- if (pkg.pkg == null || pkg.pkg.applicationInfo == null
- || pkg.pkg.applicationInfo.dataDir == null) {
+ if (pkg.pkg == null || pkg.pkg.getDataDir() == null) {
if (!"android".equals(pkg.name)) {
Slog.w(TAG, "Skipping " + pkg + " due to missing metadata");
}
continue;
}
- final ApplicationInfo ai = pkg.pkg.applicationInfo;
- final String dataPath = ai.dataDir;
- final boolean isDebug = (ai.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
+ final String dataPath = pkg.pkg.getDataDir();
+ final boolean isDebug = (pkg.pkg.getFlags() & ApplicationInfo.FLAG_DEBUGGABLE) != 0;
final int[] gids = pkg.getPermissionsState().computeGids(userIds);
// Avoid any application that has a space in its path.
@@ -2709,13 +2688,13 @@ public final class Settings {
// system/core/libpackagelistparser
//
sb.setLength(0);
- sb.append(ai.packageName);
+ sb.append(pkg.pkg.getPackageName());
sb.append(" ");
- sb.append(ai.uid);
+ sb.append(pkg.pkg.getUid());
sb.append(isDebug ? " 1 " : " 0 ");
sb.append(dataPath);
sb.append(" ");
- sb.append(ai.seInfo);
+ sb.append(pkg.pkg.getSeInfo());
sb.append(" ");
if (gids != null && gids.length > 0) {
sb.append(gids[0]);
@@ -2727,9 +2706,9 @@ public final class Settings {
sb.append("none");
}
sb.append(" ");
- sb.append(ai.isProfileableByShell() ? "1" : "0");
+ sb.append(pkg.pkg.isProfileableByShell() ? "1" : "0");
sb.append(" ");
- sb.append(String.valueOf(ai.longVersionCode));
+ sb.append(pkg.pkg.getLongVersionCode());
sb.append("\n");
writer.append(sb);
}
@@ -2778,12 +2757,6 @@ public final class Settings {
serializer.attribute(null, "sharedUserId", Integer.toString(pkg.appId));
}
- if (pkg.parentPackageName != null) {
- serializer.attribute(null, "parentPackageName", pkg.parentPackageName);
- }
-
- writeChildPackagesLPw(serializer, pkg.childPackageNames);
-
writeUsesStaticLibLPw(serializer, pkg.usesStaticLibraries, pkg.usesStaticLibrariesVersions);
// If this is a shared user, the permissions will be written there.
@@ -2847,15 +2820,10 @@ public final class Settings {
serializer.attribute(null, "categoryHint",
Integer.toString(pkg.categoryHint));
}
- if (pkg.parentPackageName != null) {
- serializer.attribute(null, "parentPackageName", pkg.parentPackageName);
- }
if (pkg.updateAvailable) {
serializer.attribute(null, "updateAvailable", "true");
}
- writeChildPackagesLPw(serializer, pkg.childPackageNames);
-
writeUsesStaticLibLPw(serializer, pkg.usesStaticLibraries, pkg.usesStaticLibrariesVersions);
pkg.signatures.writeXml(serializer, "sigs", mPastSignatures);
@@ -3148,13 +3116,13 @@ public final class Settings {
LocalServices.getService(PackageManagerInternal.class);
for (PackageSetting ps : mPackages.values()) {
if ((ps.pkgFlags&ApplicationInfo.FLAG_SYSTEM) != 0 && ps.pkg != null
- && ps.pkg.preferredActivityFilters != null) {
- ArrayList<PackageParser.ActivityIntentInfo> intents
- = ps.pkg.preferredActivityFilters;
+ && ps.pkg.getPreferredActivityFilters() != null) {
+ List<ComponentParseUtils.ParsedActivityIntentInfo> intents
+ = ps.pkg.getPreferredActivityFilters();
for (int i=0; i<intents.size(); i++) {
- PackageParser.ActivityIntentInfo aii = intents.get(i);
+ ComponentParseUtils.ParsedActivityIntentInfo aii = intents.get(i);
applyDefaultPreferredActivityLPw(pmInternal, aii, new ComponentName(
- ps.name, aii.activity.className), userId);
+ ps.name, aii.getClassName()), userId);
}
}
}
@@ -3513,7 +3481,7 @@ public final class Settings {
PackageSetting ps = new PackageSetting(name, realName, new File(codePathStr),
new File(resourcePathStr), legacyNativeLibraryPathStr, primaryCpuAbiStr,
secondaryCpuAbiStr, cpuAbiOverrideStr, versionCode, pkgFlags, pkgPrivateFlags,
- parentPackageName, null /*childPackageNames*/, 0 /*sharedUserId*/, null, null);
+ 0 /*sharedUserId*/, null, null);
String timeStampStr = parser.getAttributeValue(null, "ft");
if (timeStampStr != null) {
try {
@@ -3562,12 +3530,6 @@ public final class Settings {
if (parser.getName().equals(TAG_PERMISSIONS)) {
readInstallPermissionsLPr(parser, ps.getPermissionsState());
- } else if (parser.getName().equals(TAG_CHILD_PACKAGE)) {
- String childPackageName = parser.getAttributeValue(null, ATTR_NAME);
- if (ps.childPackageNames == null) {
- ps.childPackageNames = new ArrayList<>();
- }
- ps.childPackageNames.add(childPackageName);
} else if (parser.getName().equals(TAG_USES_STATIC_LIB)) {
readUsesStaticLibLPw(parser, ps);
} else {
@@ -3612,7 +3574,6 @@ public final class Settings {
PackageSetting packageSetting = null;
String version = null;
long versionCode = 0;
- String parentPackageName;
try {
name = parser.getAttributeValue(null, ATTR_NAME);
realName = parser.getAttributeValue(null, "realName");
@@ -3624,8 +3585,6 @@ public final class Settings {
legacyCpuAbiString = parser.getAttributeValue(null, "requiredCpuAbi");
- parentPackageName = parser.getAttributeValue(null, "parentPackageName");
-
legacyNativeLibraryPathStr = parser.getAttributeValue(null, "nativeLibraryPath");
primaryCpuAbiString = parser.getAttributeValue(null, "primaryCpuAbi");
secondaryCpuAbiString = parser.getAttributeValue(null, "secondaryCpuAbi");
@@ -3752,7 +3711,7 @@ public final class Settings {
packageSetting = addPackageLPw(name.intern(), realName, new File(codePathStr),
new File(resourcePathStr), legacyNativeLibraryPathStr, primaryCpuAbiString,
secondaryCpuAbiString, cpuAbiOverrideString, userId, versionCode, pkgFlags,
- pkgPrivateFlags, parentPackageName, null /*childPackageNames*/,
+ pkgPrivateFlags,
null /*usesStaticLibraries*/, null /*usesStaticLibraryVersions*/);
if (PackageManagerService.DEBUG_SETTINGS)
Log.i(PackageManagerService.TAG, "Reading package " + name + ": userId="
@@ -3771,8 +3730,8 @@ public final class Settings {
packageSetting = new PackageSetting(name.intern(), realName, new File(
codePathStr), new File(resourcePathStr), legacyNativeLibraryPathStr,
primaryCpuAbiString, secondaryCpuAbiString, cpuAbiOverrideString,
- versionCode, pkgFlags, pkgPrivateFlags, parentPackageName,
- null /*childPackageNames*/, sharedUserId,
+ versionCode, pkgFlags, pkgPrivateFlags,
+ sharedUserId,
null /*usesStaticLibraries*/, null /*usesStaticLibraryVersions*/);
packageSetting.setTimeStamp(timeStamp);
packageSetting.firstInstallTime = firstInstallTime;
@@ -3880,12 +3839,6 @@ public final class Settings {
packageSetting.keySetData.addDefinedKeySet(id, alias);
} else if (tagName.equals(TAG_DOMAIN_VERIFICATION)) {
readDomainVerificationLPw(parser, packageSetting);
- } else if (tagName.equals(TAG_CHILD_PACKAGE)) {
- String childPackageName = parser.getAttributeValue(null, ATTR_NAME);
- if (packageSetting.childPackageNames == null) {
- packageSetting.childPackageNames = new ArrayList<>();
- }
- packageSetting.childPackageNames.add(childPackageName);
} else {
PackageManagerService.reportSettingsProblem(Log.WARN,
"Unknown element under <package>: " + parser.getName());
@@ -4038,13 +3991,13 @@ public final class Settings {
Iterator<PackageSetting> packagesIterator = packages.iterator();
for (int i = 0; i < packagesCount; i++) {
PackageSetting ps = packagesIterator.next();
- if (ps.pkg == null || ps.pkg.applicationInfo == null) {
+ if (ps.pkg == null) {
continue;
}
final boolean shouldInstall = ps.isSystem() &&
(skipPackageWhitelist || installablePackages.contains(ps.name)) &&
!ArrayUtils.contains(disallowedPackages, ps.name) &&
- !ps.pkg.applicationInfo.hiddenUntilInstalled;
+ !ps.pkg.isHiddenUntilInstalled();
// Only system apps are initially installed.
ps.setInstalled(shouldInstall, userHandle);
if (!shouldInstall) {
@@ -4055,8 +4008,8 @@ public final class Settings {
volumeUuids[i] = ps.volumeUuid;
names[i] = ps.name;
appIds[i] = ps.appId;
- seinfos[i] = ps.pkg.applicationInfo.seInfo;
- targetSdkVersions[i] = ps.pkg.applicationInfo.targetSdkVersion;
+ seinfos[i] = ps.pkg.getSeInfo();
+ targetSdkVersions[i] = ps.pkg.getTargetSdkVersion();
}
}
t.traceBegin("createAppData");
@@ -4166,28 +4119,6 @@ public final class Settings {
return mVerifierDeviceIdentity;
}
- boolean hasOtherDisabledSystemPkgWithChildLPr(String parentPackageName,
- String childPackageName) {
- final int packageCount = mDisabledSysPackages.size();
- for (int i = 0; i < packageCount; i++) {
- PackageSetting disabledPs = mDisabledSysPackages.valueAt(i);
- if (disabledPs.childPackageNames == null || disabledPs.childPackageNames.isEmpty()) {
- continue;
- }
- if (disabledPs.name.equals(parentPackageName)) {
- continue;
- }
- final int childCount = disabledPs.childPackageNames.size();
- for (int j = 0; j < childCount; j++) {
- String currChildPackageName = disabledPs.childPackageNames.get(j);
- if (currChildPackageName.equals(childPackageName)) {
- return true;
- }
- }
- }
- return false;
- }
-
/**
* Returns the disabled {@link PackageSetting} for the provided package name if one exists,
* {@code null} otherwise.
@@ -4210,26 +4141,6 @@ public final class Settings {
return getDisabledSystemPkgLPr(enabledPackageSetting.name);
}
- /**
- * Fetches an array of the child {@link PackageSetting}s for all child package names referenced
- * by the provided parent {@link PackageSetting} or {@code null} if no children are referenced.
- *
- * Note: Any child packages not found will be null in the returned array.
- */
- @Nullable
- public PackageSetting[] getChildSettingsLPr(PackageSetting parentPackageSetting) {
- if (parentPackageSetting == null || !parentPackageSetting.hasChildPackages()) {
- return null;
- }
- final int childCount = parentPackageSetting.childPackageNames.size();
- PackageSetting[] children =
- new PackageSetting[childCount];
- for (int i = 0; i < childCount; i++) {
- children[i] = mPackages.get(parentPackageSetting.childPackageNames.get(i));
- }
- return children;
- }
-
boolean isEnabledAndMatchLPr(ComponentInfo componentInfo, int flags, int userId) {
final PackageSetting ps = mPackages.get(componentInfo.packageName);
if (ps == null) return false;
@@ -4238,6 +4149,15 @@ public final class Settings {
return userState.isMatch(componentInfo, flags);
}
+ boolean isEnabledAndMatchLPr(AndroidPackage pkg, ParsedComponent component, int flags,
+ int userId) {
+ final PackageSetting ps = mPackages.get(component.getPackageName());
+ if (ps == null) return false;
+
+ final PackageUserState userState = ps.readUserState(userId);
+ return userState.isMatch(pkg.isSystem(), pkg.isEnabled(), component, flags);
+ }
+
String getInstallerPackageNameLPr(String packageName) {
final PackageSetting pkg = mPackages.get(packageName);
if (pkg == null) {
@@ -4455,6 +4375,7 @@ public final class Settings {
void dumpPackageLPr(PrintWriter pw, String prefix, String checkinTag,
ArraySet<String> permissionNames, PackageSetting ps, SimpleDateFormat sdf,
Date date, List<UserInfo> users, boolean dumpAll, boolean dumpAllComponents) {
+ AndroidPackage pkg = ps.pkg;
if (checkinTag != null) {
pw.print(checkinTag);
pw.print(",");
@@ -4470,15 +4391,16 @@ public final class Settings {
pw.print(",");
pw.print(ps.installerPackageName != null ? ps.installerPackageName : "?");
pw.println();
- if (ps.pkg != null) {
+ if (pkg != null) {
pw.print(checkinTag); pw.print("-"); pw.print("splt,");
pw.print("base,");
- pw.println(ps.pkg.baseRevisionCode);
- if (ps.pkg.splitNames != null) {
- for (int i = 0; i < ps.pkg.splitNames.length; i++) {
+ pw.println(pkg.getBaseRevisionCode());
+ if (pkg.getSplitNames() != null) {
+ int[] splitRevisionCodes = pkg.getSplitRevisionCodes();
+ for (int i = 0; i < pkg.getSplitNames().length; i++) {
pw.print(checkinTag); pw.print("-"); pw.print("splt,");
- pw.print(ps.pkg.splitNames[i]); pw.print(",");
- pw.println(ps.pkg.splitRevisionCodes[i]);
+ pw.print(pkg.getSplitNames()[i]); pw.print(",");
+ pw.println(splitRevisionCodes[i]);
}
}
}
@@ -4525,7 +4447,7 @@ public final class Settings {
if (ps.sharedUser != null) {
pw.print(prefix); pw.print(" sharedUser="); pw.println(ps.sharedUser);
}
- pw.print(prefix); pw.print(" pkg="); pw.println(ps.pkg);
+ pw.print(prefix); pw.print(" pkg="); pw.println(pkg);
pw.print(prefix); pw.print(" codePath="); pw.println(ps.codePathString);
if (permissionNames == null) {
pw.print(prefix); pw.print(" resourcePath="); pw.println(ps.resourcePathString);
@@ -4535,140 +4457,123 @@ public final class Settings {
pw.print(prefix); pw.print(" secondaryCpuAbi="); pw.println(ps.secondaryCpuAbiString);
}
pw.print(prefix); pw.print(" versionCode="); pw.print(ps.versionCode);
- if (ps.pkg != null) {
- pw.print(" minSdk="); pw.print(ps.pkg.applicationInfo.minSdkVersion);
- pw.print(" targetSdk="); pw.print(ps.pkg.applicationInfo.targetSdkVersion);
+ if (pkg != null) {
+ pw.print(" minSdk="); pw.print(pkg.getMinSdkVersion());
+ pw.print(" targetSdk="); pw.print(pkg.getTargetSdkVersion());
}
pw.println();
- if (ps.pkg != null) {
- if (ps.pkg.parentPackage != null) {
- PackageParser.Package parentPkg = ps.pkg.parentPackage;
- PackageSetting pps = mPackages.get(parentPkg.packageName);
- if (pps == null || !pps.codePathString.equals(parentPkg.codePath)) {
- pps = mDisabledSysPackages.get(parentPkg.packageName);
- }
- if (pps != null) {
- pw.print(prefix); pw.print(" parentPackage=");
- pw.println(pps.realName != null ? pps.realName : pps.name);
- }
- } else if (ps.pkg.childPackages != null) {
- pw.print(prefix); pw.print(" childPackages=[");
- final int childCount = ps.pkg.childPackages.size();
- for (int i = 0; i < childCount; i++) {
- PackageParser.Package childPkg = ps.pkg.childPackages.get(i);
- PackageSetting cps = mPackages.get(childPkg.packageName);
- if (cps == null || !cps.codePathString.equals(childPkg.codePath)) {
- cps = mDisabledSysPackages.get(childPkg.packageName);
- }
- if (cps != null) {
- if (i > 0) {
- pw.print(", ");
- }
- pw.print(cps.realName != null ? cps.realName : cps.name);
- }
- }
- pw.println("]");
- }
- pw.print(prefix); pw.print(" versionName="); pw.println(ps.pkg.mVersionName);
- pw.print(prefix); pw.print(" splits="); dumpSplitNames(pw, ps.pkg); pw.println();
- final int apkSigningVersion = ps.pkg.mSigningDetails.signatureSchemeVersion;
+ if (pkg != null) {
+ pw.print(prefix); pw.print(" versionName="); pw.println(pkg.getVersionName());
+ pw.print(prefix); pw.print(" splits="); dumpSplitNames(pw, pkg); pw.println();
+ final int apkSigningVersion = pkg.getSigningDetails().signatureSchemeVersion;
pw.print(prefix); pw.print(" apkSigningVersion="); pw.println(apkSigningVersion);
+ // TODO(b/135203078): Is there anything to print here with AppInfo removed?
pw.print(prefix); pw.print(" applicationInfo=");
- pw.println(ps.pkg.applicationInfo.toString());
- pw.print(prefix); pw.print(" flags="); printFlags(pw, ps.pkg.applicationInfo.flags,
+ pw.println(pkg.toAppInfo().toString());
+ pw.print(prefix); pw.print(" flags="); printFlags(pw, pkg.getFlags(),
FLAG_DUMP_SPEC); pw.println();
- if (ps.pkg.applicationInfo.privateFlags != 0) {
+ if (pkg.getPrivateFlags() != 0) {
pw.print(prefix); pw.print(" privateFlags="); printFlags(pw,
- ps.pkg.applicationInfo.privateFlags, PRIVATE_FLAG_DUMP_SPEC); pw.println();
+ pkg.getPrivateFlags(), PRIVATE_FLAG_DUMP_SPEC); pw.println();
}
- pw.print(prefix); pw.print(" forceQueryable="); pw.println(ps.pkg.mForceQueryable);
- if (ps.pkg.mQueriesPackages != null) {
- pw.append(prefix).append(" queriesPackages=").println(ps.pkg.mQueriesPackages);
+ pw.print(prefix); pw.print(" forceQueryable="); pw.println(ps.pkg.isForceQueryable());
+ if (ps.pkg.getQueriesPackages() != null) {
+ pw.append(prefix).append(" queriesPackages=").println(ps.pkg.getQueriesPackages());
}
- if (ps.pkg.mQueriesIntents != null) {
- pw.append(prefix).append(" queriesIntents=").println(ps.pkg.mQueriesIntents);
+ if (ps.pkg.getQueriesIntents() != null) {
+ pw.append(prefix).append(" queriesIntents=").println(ps.pkg.getQueriesIntents());
}
- pw.print(prefix); pw.print(" dataDir="); pw.println(ps.pkg.applicationInfo.dataDir);
+ pw.print(prefix); pw.print(" dataDir="); pw.println(ps.pkg.getDataDir());
pw.print(prefix); pw.print(" supportsScreens=[");
boolean first = true;
- if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_SUPPORTS_SMALL_SCREENS) != 0) {
+ if ((pkg.getFlags() & ApplicationInfo.FLAG_SUPPORTS_SMALL_SCREENS) != 0) {
if (!first)
pw.print(", ");
first = false;
pw.print("small");
}
- if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_SUPPORTS_NORMAL_SCREENS) != 0) {
+ if ((pkg.getFlags() & ApplicationInfo.FLAG_SUPPORTS_NORMAL_SCREENS) != 0) {
if (!first)
pw.print(", ");
first = false;
pw.print("medium");
}
- if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_SUPPORTS_LARGE_SCREENS) != 0) {
+ if ((pkg.getFlags() & ApplicationInfo.FLAG_SUPPORTS_LARGE_SCREENS) != 0) {
if (!first)
pw.print(", ");
first = false;
pw.print("large");
}
- if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_SUPPORTS_XLARGE_SCREENS) != 0) {
+ if ((pkg.getFlags() & ApplicationInfo.FLAG_SUPPORTS_XLARGE_SCREENS) != 0) {
if (!first)
pw.print(", ");
first = false;
pw.print("xlarge");
}
- if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_RESIZEABLE_FOR_SCREENS) != 0) {
+ if ((pkg.getFlags() & ApplicationInfo.FLAG_RESIZEABLE_FOR_SCREENS) != 0) {
if (!first)
pw.print(", ");
first = false;
pw.print("resizeable");
}
- if ((ps.pkg.applicationInfo.flags & ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES) != 0) {
+ if ((pkg.getFlags() & ApplicationInfo.FLAG_SUPPORTS_SCREEN_DENSITIES) != 0) {
if (!first)
pw.print(", ");
first = false;
pw.print("anyDensity");
}
pw.println("]");
- if (ps.pkg.libraryNames != null && ps.pkg.libraryNames.size() > 0) {
+ List<String> libraryNames = pkg.getLibraryNames();
+ if (libraryNames != null && libraryNames.size() > 0) {
pw.print(prefix); pw.println(" dynamic libraries:");
- for (int i = 0; i<ps.pkg.libraryNames.size(); i++) {
+ for (int i = 0; i< libraryNames.size(); i++) {
pw.print(prefix); pw.print(" ");
- pw.println(ps.pkg.libraryNames.get(i));
+ pw.println(libraryNames.get(i));
}
}
- if (ps.pkg.staticSharedLibName != null) {
+ if (pkg.getStaticSharedLibName() != null) {
pw.print(prefix); pw.println(" static library:");
pw.print(prefix); pw.print(" ");
- pw.print("name:"); pw.print(ps.pkg.staticSharedLibName);
- pw.print(" version:"); pw.println(ps.pkg.staticSharedLibVersion);
+ pw.print("name:"); pw.print(pkg.getStaticSharedLibName());
+ pw.print(" version:"); pw.println(pkg.getStaticSharedLibVersion());
}
- if (ps.pkg.usesLibraries != null && ps.pkg.usesLibraries.size() > 0) {
+
+ List<String> usesLibraries = pkg.getUsesLibraries();
+ if (usesLibraries != null && usesLibraries.size() > 0) {
pw.print(prefix); pw.println(" usesLibraries:");
- for (int i=0; i<ps.pkg.usesLibraries.size(); i++) {
- pw.print(prefix); pw.print(" "); pw.println(ps.pkg.usesLibraries.get(i));
+ for (int i=0; i< usesLibraries.size(); i++) {
+ pw.print(prefix); pw.print(" "); pw.println(usesLibraries.get(i));
}
}
- if (ps.pkg.usesStaticLibraries != null
- && ps.pkg.usesStaticLibraries.size() > 0) {
+
+ List<String> usesStaticLibraries = pkg.getUsesStaticLibraries();
+ long[] usesStaticLibrariesVersions = pkg.getUsesStaticLibrariesVersions();
+ if (usesStaticLibraries != null
+ && usesStaticLibraries.size() > 0) {
pw.print(prefix); pw.println(" usesStaticLibraries:");
- for (int i=0; i<ps.pkg.usesStaticLibraries.size(); i++) {
+ for (int i=0; i< usesStaticLibraries.size(); i++) {
pw.print(prefix); pw.print(" ");
- pw.print(ps.pkg.usesStaticLibraries.get(i)); pw.print(" version:");
- pw.println(ps.pkg.usesStaticLibrariesVersions[i]);
+ pw.print(usesStaticLibraries.get(i)); pw.print(" version:");
+ pw.println(usesStaticLibrariesVersions[i]);
}
}
- if (ps.pkg.usesOptionalLibraries != null
- && ps.pkg.usesOptionalLibraries.size() > 0) {
+
+ List<String> usesOptionalLibraries = pkg.getUsesOptionalLibraries();
+ if (usesOptionalLibraries != null
+ && usesOptionalLibraries.size() > 0) {
pw.print(prefix); pw.println(" usesOptionalLibraries:");
- for (int i=0; i<ps.pkg.usesOptionalLibraries.size(); i++) {
+ for (int i=0; i< usesOptionalLibraries.size(); i++) {
pw.print(prefix); pw.print(" ");
- pw.println(ps.pkg.usesOptionalLibraries.get(i));
+ pw.println(usesOptionalLibraries.get(i));
}
}
- if (ps.pkg.usesLibraryFiles != null
- && ps.pkg.usesLibraryFiles.length > 0) {
+
+ String[] usesLibraryFiles = pkg.getUsesLibraryFiles();
+ if (usesLibraryFiles != null
+ && usesLibraryFiles.length > 0) {
pw.print(prefix); pw.println(" usesLibraryFiles:");
- for (int i=0; i<ps.pkg.usesLibraryFiles.length; i++) {
- pw.print(prefix); pw.print(" "); pw.println(ps.pkg.usesLibraryFiles[i]);
+ for (int i=0; i< usesLibraryFiles.length; i++) {
+ pw.print(prefix); pw.print(" "); pw.println(usesLibraryFiles[i]);
}
}
}
@@ -4696,40 +4601,40 @@ public final class Settings {
pw.print(prefix); pw.print(" pkgFlags="); printFlags(pw, ps.pkgFlags, FLAG_DUMP_SPEC);
pw.println();
- if (ps.pkg != null && ps.pkg.mOverlayTarget != null) {
- pw.print(prefix); pw.print(" overlayTarget="); pw.println(ps.pkg.mOverlayTarget);
- pw.print(prefix); pw.print(" overlayCategory="); pw.println(ps.pkg.mOverlayCategory);
+ if (pkg != null && pkg.getOverlayTarget() != null) {
+ pw.print(prefix); pw.print(" overlayTarget="); pw.println(pkg.getOverlayTarget());
+ pw.print(prefix); pw.print(" overlayCategory="); pw.println(pkg.getOverlayCategory());
}
- if (ps.pkg != null && ps.pkg.permissions != null && ps.pkg.permissions.size() > 0) {
- final ArrayList<PackageParser.Permission> perms = ps.pkg.permissions;
+ if (pkg != null && pkg.getPermissions() != null && pkg.getPermissions().size() > 0) {
+ final List<ParsedPermission> perms = pkg.getPermissions();
pw.print(prefix); pw.println(" declared permissions:");
for (int i=0; i<perms.size(); i++) {
- PackageParser.Permission perm = perms.get(i);
+ ParsedPermission perm = perms.get(i);
if (permissionNames != null
- && !permissionNames.contains(perm.info.name)) {
+ && !permissionNames.contains(perm.getName())) {
continue;
}
- pw.print(prefix); pw.print(" "); pw.print(perm.info.name);
+ pw.print(prefix); pw.print(" "); pw.print(perm.getName());
pw.print(": prot=");
- pw.print(PermissionInfo.protectionToString(perm.info.protectionLevel));
- if ((perm.info.flags&PermissionInfo.FLAG_COSTS_MONEY) != 0) {
+ pw.print(PermissionInfo.protectionToString(perm.protectionLevel));
+ if ((perm.flags&PermissionInfo.FLAG_COSTS_MONEY) != 0) {
pw.print(", COSTS_MONEY");
}
- if ((perm.info.flags&PermissionInfo.FLAG_REMOVED) != 0) {
+ if ((perm.flags&PermissionInfo.FLAG_REMOVED) != 0) {
pw.print(", HIDDEN");
}
- if ((perm.info.flags&PermissionInfo.FLAG_INSTALLED) != 0) {
+ if ((perm.flags&PermissionInfo.FLAG_INSTALLED) != 0) {
pw.print(", INSTALLED");
}
pw.println();
}
}
- if ((permissionNames != null || dumpAll) && ps.pkg != null
- && ps.pkg.requestedPermissions != null
- && ps.pkg.requestedPermissions.size() > 0) {
- final ArrayList<String> perms = ps.pkg.requestedPermissions;
+ if ((permissionNames != null || dumpAll) && pkg != null
+ && pkg.getRequestedPermissions() != null
+ && pkg.getRequestedPermissions().size() > 0) {
+ final List<String> perms = pkg.getRequestedPermissions();
pw.print(prefix); pw.println(" requested permissions:");
for (int i=0; i<perms.size(); i++) {
String perm = perms.get(i);
@@ -4996,22 +4901,24 @@ public final class Settings {
pw.print(mReadMessages.toString());
}
- private static void dumpSplitNames(PrintWriter pw, PackageParser.Package pkg) {
+ private static void dumpSplitNames(PrintWriter pw, AndroidPackage pkg) {
if (pkg == null) {
pw.print("unknown");
} else {
// [base:10, config.mdpi, config.xhdpi:12]
pw.print("[");
pw.print("base");
- if (pkg.baseRevisionCode != 0) {
- pw.print(":"); pw.print(pkg.baseRevisionCode);
+ if (pkg.getBaseRevisionCode() != 0) {
+ pw.print(":"); pw.print(pkg.getBaseRevisionCode());
}
- if (pkg.splitNames != null) {
- for (int i = 0; i < pkg.splitNames.length; i++) {
+ String[] splitNames = pkg.getSplitNames();
+ int[] splitRevisionCodes = pkg.getSplitRevisionCodes();
+ if (splitNames != null) {
+ for (int i = 0; i < splitNames.length; i++) {
pw.print(", ");
- pw.print(pkg.splitNames[i]);
- if (pkg.splitRevisionCodes[i] != 0) {
- pw.print(":"); pw.print(pkg.splitRevisionCodes[i]);
+ pw.print(splitNames[i]);
+ if (splitRevisionCodes[i] != 0) {
+ pw.print(":"); pw.print(splitRevisionCodes[i]);
}
}
}
@@ -5087,22 +4994,23 @@ public final class Settings {
}
void dumpComponents(PrintWriter pw, String prefix, PackageSetting ps) {
- dumpComponents(pw, prefix, ps, "activities:", ps.pkg.activities);
- dumpComponents(pw, prefix, ps, "services:", ps.pkg.services);
- dumpComponents(pw, prefix, ps, "receivers:", ps.pkg.receivers);
- dumpComponents(pw, prefix, ps, "providers:", ps.pkg.providers);
- dumpComponents(pw, prefix, ps, "instrumentations:", ps.pkg.instrumentation);
+ // TODO(b/135203078): ParsedComponent toString methods for dumping
+ dumpComponents(pw, prefix, "activities:", ps.pkg.getActivities());
+ dumpComponents(pw, prefix, "services:", ps.pkg.getServices());
+ dumpComponents(pw, prefix, "receivers:", ps.pkg.getReceivers());
+ dumpComponents(pw, prefix, "providers:", ps.pkg.getProviders());
+ dumpComponents(pw, prefix, "instrumentations:", ps.pkg.getInstrumentations());
}
- void dumpComponents(PrintWriter pw, String prefix, PackageSetting ps,
- String label, List<? extends PackageParser.Component<?>> list) {
+ void dumpComponents(PrintWriter pw, String prefix, String label,
+ List<? extends ParsedComponent> list) {
final int size = CollectionUtils.size(list);
if (size == 0) {
return;
}
pw.print(prefix);pw.println(label);
for (int i = 0; i < size; i++) {
- final PackageParser.Component<?> component = list.get(i);
+ final ParsedComponent component = list.get(i);
pw.print(prefix);pw.print(" ");
pw.println(component.getComponentName().flattenToShortString());
}
diff --git a/services/core/java/com/android/server/pm/SharedUserSetting.java b/services/core/java/com/android/server/pm/SharedUserSetting.java
index 2ee07a2037c3..cff19443a79b 100644
--- a/services/core/java/com/android/server/pm/SharedUserSetting.java
+++ b/services/core/java/com/android/server/pm/SharedUserSetting.java
@@ -18,7 +18,7 @@ package com.android.server.pm;
import android.annotation.Nullable;
import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageParser;
+import android.content.pm.parsing.AndroidPackage;
import android.service.pm.PackageServiceDumpProto;
import android.util.ArraySet;
import android.util.proto.ProtoOutputStream;
@@ -46,7 +46,7 @@ public final class SharedUserSetting extends SettingBase {
// that all apps within the sharedUser run in the same selinux context.
int seInfoTargetSdkVersion;
- final ArraySet<PackageSetting> packages = new ArraySet<PackageSetting>();
+ final ArraySet<PackageSetting> packages = new ArraySet<>();
final PackageSignatures signatures = new PackageSignatures();
Boolean signaturesChanged;
@@ -98,7 +98,7 @@ public final class SharedUserSetting extends SettingBase {
// If this is the first package added to this shared user, temporarily (until next boot) use
// its targetSdkVersion when assigning seInfo for the shared user.
if ((packages.size() == 0) && (packageSetting.pkg != null)) {
- seInfoTargetSdkVersion = packageSetting.pkg.applicationInfo.targetSdkVersion;
+ seInfoTargetSdkVersion = packageSetting.pkg.getTargetSdkVersion();
}
if (packages.add(packageSetting)) {
setFlags(this.pkgFlags | packageSetting.pkgFlags);
@@ -106,11 +106,11 @@ public final class SharedUserSetting extends SettingBase {
}
}
- public @Nullable List<PackageParser.Package> getPackages() {
+ public @Nullable List<AndroidPackage> getPackages() {
if (packages == null || packages.size() == 0) {
return null;
}
- final ArrayList<PackageParser.Package> pkgList = new ArrayList<>(packages.size());
+ final ArrayList<AndroidPackage> pkgList = new ArrayList<>(packages.size());
for (PackageSetting ps : packages) {
if ((ps == null) || (ps.pkg == null)) {
continue;
@@ -131,20 +131,20 @@ public final class SharedUserSetting extends SettingBase {
* restrictive selinux domain.
*/
public void fixSeInfoLocked() {
- final List<PackageParser.Package> pkgList = getPackages();
+ final List<AndroidPackage> pkgList = getPackages();
if (pkgList == null || pkgList.size() == 0) {
return;
}
- for (PackageParser.Package pkg : pkgList) {
- if (pkg.applicationInfo.targetSdkVersion < seInfoTargetSdkVersion) {
- seInfoTargetSdkVersion = pkg.applicationInfo.targetSdkVersion;
+ for (AndroidPackage pkg : pkgList) {
+ if (pkg.getTargetSdkVersion() < seInfoTargetSdkVersion) {
+ seInfoTargetSdkVersion = pkg.getTargetSdkVersion();
}
}
- for (PackageParser.Package pkg : pkgList) {
+ for (AndroidPackage pkg : pkgList) {
final boolean isPrivileged = isPrivileged() | pkg.isPrivileged();
- pkg.applicationInfo.seInfo = SELinuxMMAC.getSeInfo(pkg, isPrivileged,
- seInfoTargetSdkVersion);
+ pkg.mutate().setSeInfo(SELinuxMMAC.getSeInfo(pkg, isPrivileged,
+ seInfoTargetSdkVersion));
}
}
diff --git a/services/core/java/com/android/server/pm/UserSystemPackageInstaller.java b/services/core/java/com/android/server/pm/UserSystemPackageInstaller.java
index 036d1e807f97..793ea47bfd43 100644
--- a/services/core/java/com/android/server/pm/UserSystemPackageInstaller.java
+++ b/services/core/java/com/android/server/pm/UserSystemPackageInstaller.java
@@ -23,6 +23,7 @@ import android.annotation.UserIdInt;
import android.content.pm.PackageManagerInternal;
import android.content.pm.PackageParser;
import android.content.pm.UserInfo;
+import android.content.pm.parsing.AndroidPackage;
import android.content.res.Resources;
import android.os.SystemProperties;
import android.os.UserHandle;
@@ -151,15 +152,15 @@ class UserSystemPackageInstaller {
return;
}
final boolean install =
- (userWhitelist == null || userWhitelist.contains(pkg.packageName))
- && !pkg.applicationInfo.hiddenUntilInstalled;
+ (userWhitelist == null || userWhitelist.contains(pkg.getPackageName()))
+ && !pkg.isHiddenUntilInstalled();
if (isUpgrade && !isFirstBoot && !install) {
return; // To be careful, we don’t uninstall apps during OTAs
}
final boolean changed = pmInt.setInstalled(pkg, userId, install);
if (changed) {
Slog.i(TAG, (install ? "Installed " : "Uninstalled ")
- + pkg.packageName + " for user " + userId);
+ + pkg.getPackageName() + " for user " + userId);
}
});
}
@@ -180,7 +181,7 @@ class UserSystemPackageInstaller {
// Check whether all whitelisted packages are indeed on the system.
for (String pkgName : allWhitelistedPackages) {
- PackageParser.Package pkg = pmInt.getPackage(pkgName);
+ AndroidPackage pkg = pmInt.getPackage(pkgName);
if (pkg == null) {
Slog.w(TAG, pkgName + " is whitelisted but not present.");
} else if (!pkg.isSystem()) {
@@ -194,8 +195,8 @@ class UserSystemPackageInstaller {
}
final boolean doWtf = isEnforceMode(mode);
pmInt.forEachPackage(pkg -> {
- if (pkg.isSystem() && !allWhitelistedPackages.contains(pkg.manifestPackageName)) {
- final String msg = "System package " + pkg.manifestPackageName
+ if (pkg.isSystem() && !allWhitelistedPackages.contains(pkg.getManifestPackageName())) {
+ final String msg = "System package " + pkg.getManifestPackageName()
+ " is not whitelisted using 'install-in-user-type' in SystemConfig "
+ "for any user types!";
if (doWtf) {
@@ -286,7 +287,7 @@ class UserSystemPackageInstaller {
if (shouldInstallPackage(pkg, mWhitelitsedPackagesForUserTypes,
whitelistedPackages, isImplicitWhitelistMode, isSystemUser)) {
// Although the whitelist uses manifest names, this function returns packageNames.
- installPackages.add(pkg.packageName);
+ installPackages.add(pkg.getPackageName());
}
});
return installPackages;
@@ -307,12 +308,12 @@ class UserSystemPackageInstaller {
* @param isSystemUser whether the user is USER_SYSTEM (which gets special treatment).
*/
@VisibleForTesting
- static boolean shouldInstallPackage(PackageParser.Package sysPkg,
+ static boolean shouldInstallPackage(AndroidPackage sysPkg,
@NonNull ArrayMap<String, Integer> userTypeWhitelist,
@NonNull Set<String> userWhitelist, boolean isImplicitWhitelistMode,
boolean isSystemUser) {
- final String pkgName = sysPkg.manifestPackageName;
+ final String pkgName = sysPkg.getManifestPackageName();
boolean install = (isImplicitWhitelistMode && !userTypeWhitelist.containsKey(pkgName))
|| userWhitelist.contains(pkgName);
diff --git a/services/core/java/com/android/server/pm/dex/ArtManagerService.java b/services/core/java/com/android/server/pm/dex/ArtManagerService.java
index b3f1867fdb06..661497cac332 100644
--- a/services/core/java/com/android/server/pm/dex/ArtManagerService.java
+++ b/services/core/java/com/android/server/pm/dex/ArtManagerService.java
@@ -25,13 +25,13 @@ import android.content.pm.ApplicationInfo;
import android.content.pm.IPackageManager;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
-import android.content.pm.PackageParser;
import android.content.pm.dex.ArtManager;
import android.content.pm.dex.ArtManager.ProfileType;
import android.content.pm.dex.ArtManagerInternal;
import android.content.pm.dex.DexMetadataHelper;
import android.content.pm.dex.ISnapshotRuntimeProfileCallback;
import android.content.pm.dex.PackageOptimizationInfo;
+import android.content.pm.parsing.AndroidPackage;
import android.os.Binder;
import android.os.Build;
import android.os.Handler;
@@ -386,9 +386,10 @@ public class ArtManagerService extends android.content.pm.dex.IArtManager.Stub {
* - create the current primary profile to save time at app startup time.
* - copy the profiles from the associated dex metadata file to the reference profile.
*/
- public void prepareAppProfiles(PackageParser.Package pkg, @UserIdInt int user,
+ public void prepareAppProfiles(
+ AndroidPackage pkg, @UserIdInt int user,
boolean updateReferenceProfileContent) {
- final int appId = UserHandle.getAppId(pkg.applicationInfo.uid);
+ final int appId = UserHandle.getAppId(pkg.getUid());
if (user < 0) {
Slog.wtf(TAG, "Invalid user id: " + user);
return;
@@ -411,23 +412,24 @@ public class ArtManagerService extends android.content.pm.dex.IArtManager.Stub {
dexMetadataPath = dexMetadata == null ? null : dexMetadata.getAbsolutePath();
}
synchronized (mInstaller) {
- boolean result = mInstaller.prepareAppProfile(pkg.packageName, user, appId,
+ boolean result = mInstaller.prepareAppProfile(pkg.getPackageName(), user, appId,
profileName, codePath, dexMetadataPath);
if (!result) {
Slog.e(TAG, "Failed to prepare profile for " +
- pkg.packageName + ":" + codePath);
+ pkg.getPackageName() + ":" + codePath);
}
}
}
} catch (InstallerException e) {
- Slog.e(TAG, "Failed to prepare profile for " + pkg.packageName, e);
+ Slog.e(TAG, "Failed to prepare profile for " + pkg.getPackageName(), e);
}
}
/**
* Prepares the app profiles for a set of users. {@see ArtManagerService#prepareAppProfiles}.
*/
- public void prepareAppProfiles(PackageParser.Package pkg, int[] user,
+ public void prepareAppProfiles(
+ AndroidPackage pkg, int[] user,
boolean updateReferenceProfileContent) {
for (int i = 0; i < user.length; i++) {
prepareAppProfiles(pkg, user[i], updateReferenceProfileContent);
@@ -437,12 +439,12 @@ public class ArtManagerService extends android.content.pm.dex.IArtManager.Stub {
/**
* Clear the profiles for the given package.
*/
- public void clearAppProfiles(PackageParser.Package pkg) {
+ public void clearAppProfiles(AndroidPackage pkg) {
try {
ArrayMap<String, String> packageProfileNames = getPackageProfileNames(pkg);
for (int i = packageProfileNames.size() - 1; i >= 0; i--) {
String profileName = packageProfileNames.valueAt(i);
- mInstaller.clearAppProfiles(pkg.packageName, profileName);
+ mInstaller.clearAppProfiles(pkg.getPackageName(), profileName);
}
} catch (InstallerException e) {
Slog.w(TAG, String.valueOf(e));
@@ -452,15 +454,15 @@ public class ArtManagerService extends android.content.pm.dex.IArtManager.Stub {
/**
* Dumps the profiles for the given package.
*/
- public void dumpProfiles(PackageParser.Package pkg) {
- final int sharedGid = UserHandle.getSharedAppGid(pkg.applicationInfo.uid);
+ public void dumpProfiles(AndroidPackage pkg) {
+ final int sharedGid = UserHandle.getSharedAppGid(pkg.getUid());
try {
ArrayMap<String, String> packageProfileNames = getPackageProfileNames(pkg);
for (int i = packageProfileNames.size() - 1; i >= 0; i--) {
String codePath = packageProfileNames.keyAt(i);
String profileName = packageProfileNames.valueAt(i);
synchronized (mInstallLock) {
- mInstaller.dumpProfiles(sharedGid, pkg.packageName, profileName, codePath);
+ mInstaller.dumpProfiles(sharedGid, pkg.getPackageName(), profileName, codePath);
}
}
} catch (InstallerException e) {
@@ -471,14 +473,13 @@ public class ArtManagerService extends android.content.pm.dex.IArtManager.Stub {
/**
* Compile layout resources in a given package.
*/
- public boolean compileLayouts(PackageParser.Package pkg) {
+ public boolean compileLayouts(AndroidPackage pkg) {
try {
- final String packageName = pkg.packageName;
- final String apkPath = pkg.baseCodePath;
- final ApplicationInfo appInfo = pkg.applicationInfo;
- final String outDexFile = appInfo.dataDir + "/code_cache/compiled_view.dex";
- if (appInfo.isPrivilegedApp() || appInfo.isEmbeddedDexUsed()
- || appInfo.isDefaultToDeviceProtectedStorage()) {
+ final String packageName = pkg.getPackageName();
+ final String apkPath = pkg.getBaseCodePath();
+ final String outDexFile = pkg.getDataDir() + "/code_cache/compiled_view.dex";
+ if (pkg.isPrivileged() || pkg.isEmbeddedDexUsed()
+ || pkg.isDefaultToDeviceProtectedStorage()) {
// Privileged apps prefer to load trusted code so they don't use compiled views.
// If the app is not privileged but prefers code integrity, also avoid compiling
// views.
@@ -492,7 +493,7 @@ public class ArtManagerService extends android.content.pm.dex.IArtManager.Stub {
try {
synchronized (mInstallLock) {
return mInstaller.compileLayouts(apkPath, packageName, outDexFile,
- appInfo.uid);
+ pkg.getUid());
}
} finally {
Binder.restoreCallingIdentity(callingId);
@@ -508,15 +509,19 @@ public class ArtManagerService extends android.content.pm.dex.IArtManager.Stub {
* Build the profiles names for all the package code paths (excluding resource only paths).
* Return the map [code path -> profile name].
*/
- private ArrayMap<String, String> getPackageProfileNames(PackageParser.Package pkg) {
+ private ArrayMap<String, String> getPackageProfileNames(AndroidPackage pkg) {
ArrayMap<String, String> result = new ArrayMap<>();
- if ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_HAS_CODE) != 0) {
- result.put(pkg.baseCodePath, ArtManager.getProfileName(null));
+ if ((pkg.getFlags() & ApplicationInfo.FLAG_HAS_CODE) != 0) {
+ result.put(pkg.getBaseCodePath(), ArtManager.getProfileName(null));
}
- if (!ArrayUtils.isEmpty(pkg.splitCodePaths)) {
- for (int i = 0; i < pkg.splitCodePaths.length; i++) {
- if ((pkg.splitFlags[i] & ApplicationInfo.FLAG_HAS_CODE) != 0) {
- result.put(pkg.splitCodePaths[i], ArtManager.getProfileName(pkg.splitNames[i]));
+
+ String[] splitCodePaths = pkg.getSplitCodePaths();
+ int[] splitFlags = pkg.getSplitFlags();
+ String[] splitNames = pkg.getSplitNames();
+ if (!ArrayUtils.isEmpty(splitCodePaths)) {
+ for (int i = 0; i < splitCodePaths.length; i++) {
+ if ((splitFlags[i] & ApplicationInfo.FLAG_HAS_CODE) != 0) {
+ result.put(splitCodePaths[i], ArtManager.getProfileName(splitNames[i]));
}
}
}
diff --git a/services/core/java/com/android/server/pm/dex/DexManager.java b/services/core/java/com/android/server/pm/dex/DexManager.java
index f56231fc02af..5df5380ab8ab 100644
--- a/services/core/java/com/android/server/pm/dex/DexManager.java
+++ b/services/core/java/com/android/server/pm/dex/DexManager.java
@@ -595,7 +595,7 @@ public class DexManager {
// We found the package. Now record the usage for all declared ISAs.
boolean update = false;
- for (String isa : getAppDexInstructionSets(info)) {
+ for (String isa : getAppDexInstructionSets(info.primaryCpuAbi, info.secondaryCpuAbi)) {
boolean newUpdate = mPackageDexUsage.record(searchResult.mOwningPackageName,
dexPath, userId, isa, isUsedByOtherApps, /*primaryOrSplit*/ false,
searchResult.mOwningPackageName,
diff --git a/services/core/java/com/android/server/pm/dex/DexoptUtils.java b/services/core/java/com/android/server/pm/dex/DexoptUtils.java
index 5a473c1819c1..6e6b137d23a2 100644
--- a/services/core/java/com/android/server/pm/dex/DexoptUtils.java
+++ b/services/core/java/com/android/server/pm/dex/DexoptUtils.java
@@ -18,10 +18,12 @@ package com.android.server.pm.dex;
import android.content.pm.ApplicationInfo;
import android.content.pm.SharedLibraryInfo;
+import android.content.pm.parsing.AndroidPackage;
import android.util.Slog;
import android.util.SparseArray;
import com.android.internal.os.ClassLoaderFactory;
+import com.android.internal.util.ArrayUtils;
import java.io.File;
import java.util.List;
@@ -66,7 +68,7 @@ public final class DexoptUtils {
* {@link android.app.LoadedApk#makePaths(
* android.app.ActivityThread, boolean, ApplicationInfo, List, List)}.
*/
- public static String[] getClassLoaderContexts(ApplicationInfo info,
+ public static String[] getClassLoaderContexts(AndroidPackage pkg,
List<SharedLibraryInfo> sharedLibraries, boolean[] pathsWithCode) {
// The base class loader context contains only the shared library.
String sharedLibrariesContext = "";
@@ -75,8 +77,8 @@ public final class DexoptUtils {
}
String baseApkContextClassLoader = encodeClassLoader(
- "", info.classLoaderName, sharedLibrariesContext);
- if (info.getSplitCodePaths() == null) {
+ "", pkg.getAppInfoClassLoaderName(), sharedLibrariesContext);
+ if (pkg.getSplitCodePaths() == null) {
// The application has no splits.
return new String[] {baseApkContextClassLoader};
}
@@ -84,11 +86,11 @@ public final class DexoptUtils {
// The application has splits. Compute their class loader contexts.
// First, cache the relative paths of the splits and do some sanity checks
- String[] splitRelativeCodePaths = getSplitRelativeCodePaths(info);
+ String[] splitRelativeCodePaths = getSplitRelativeCodePaths(pkg);
// The splits have an implicit dependency on the base apk.
// This means that we have to add the base apk file in addition to the shared libraries.
- String baseApkName = new File(info.getBaseCodePath()).getName();
+ String baseApkName = new File(pkg.getBaseCodePath()).getName();
String baseClassPath = baseApkName;
// The result is stored in classLoaderContexts.
@@ -97,7 +99,11 @@ public final class DexoptUtils {
String[] classLoaderContexts = new String[/*base apk*/ 1 + splitRelativeCodePaths.length];
classLoaderContexts[0] = pathsWithCode[0] ? baseApkContextClassLoader : null;
- if (!info.requestsIsolatedSplitLoading() || info.splitDependencies == null) {
+ SparseArray<int[]> splitDependencies = pkg.getSplitDependencies();
+
+ if (!pkg.requestsIsolatedSplitLoading()
+ || splitDependencies == null
+ || splitDependencies.size() == 0) {
// If the app didn't request for the splits to be loaded in isolation or if it does not
// declare inter-split dependencies, then all the splits will be loaded in the base
// apk class loader (in the order of their definition).
@@ -105,7 +111,7 @@ public final class DexoptUtils {
for (int i = 1; i < classLoaderContexts.length; i++) {
if (pathsWithCode[i]) {
classLoaderContexts[i] = encodeClassLoader(
- classpath, info.classLoaderName, sharedLibrariesContext);
+ classpath, pkg.getAppInfoClassLoaderName(), sharedLibrariesContext);
} else {
classLoaderContexts[i] = null;
}
@@ -132,11 +138,10 @@ public final class DexoptUtils {
String[] splitClassLoaderEncodingCache = new String[splitRelativeCodePaths.length];
for (int i = 0; i < splitRelativeCodePaths.length; i++) {
splitClassLoaderEncodingCache[i] = encodeClassLoader(splitRelativeCodePaths[i],
- info.splitClassLoaderNames[i]);
+ pkg.getSplitClassLoaderNames()[i]);
}
String splitDependencyOnBase = encodeClassLoader(
- baseClassPath, info.classLoaderName);
- SparseArray<int[]> splitDependencies = info.splitDependencies;
+ baseClassPath, pkg.getClassLoaderName());
// Note that not all splits have dependencies (e.g. configuration splits)
// The splits without dependencies will have classLoaderContexts[config_split_index]
@@ -154,7 +159,8 @@ public final class DexoptUtils {
// We also need to add the class loader of the current split which should
// come first in the context.
for (int i = 1; i < classLoaderContexts.length; i++) {
- String splitClassLoader = encodeClassLoader("", info.splitClassLoaderNames[i - 1]);
+ String splitClassLoader = encodeClassLoader("",
+ pkg.getSplitClassLoaderNames()[i - 1]);
if (pathsWithCode[i]) {
// If classLoaderContexts[i] is null it means that the split does not have
// any dependency. In this case its context equals its declared class loader.
@@ -394,11 +400,11 @@ public final class DexoptUtils {
* Returns the relative paths of the splits declared by the application {@code info}.
* Assumes that the application declares a non-null array of splits.
*/
- private static String[] getSplitRelativeCodePaths(ApplicationInfo info) {
- String baseCodePath = new File(info.getBaseCodePath()).getParent();
- String[] splitCodePaths = info.getSplitCodePaths();
- String[] splitRelativeCodePaths = new String[splitCodePaths.length];
- for (int i = 0; i < splitCodePaths.length; i++) {
+ private static String[] getSplitRelativeCodePaths(AndroidPackage pkg) {
+ String baseCodePath = new File(pkg.getBaseCodePath()).getParent();
+ String[] splitCodePaths = pkg.getSplitCodePaths();
+ String[] splitRelativeCodePaths = new String[ArrayUtils.size(splitCodePaths)];
+ for (int i = 0; i < splitRelativeCodePaths.length; i++) {
File pathFile = new File(splitCodePaths[i]);
splitRelativeCodePaths[i] = pathFile.getName();
// Sanity check that the base paths of the splits are all the same.
diff --git a/services/core/java/com/android/server/pm/dex/ViewCompiler.java b/services/core/java/com/android/server/pm/dex/ViewCompiler.java
index 8d8e17e92b3d..b7443f36e494 100644
--- a/services/core/java/com/android/server/pm/dex/ViewCompiler.java
+++ b/services/core/java/com/android/server/pm/dex/ViewCompiler.java
@@ -16,10 +16,10 @@
package com.android.server.pm.dex;
-import android.content.pm.ApplicationInfo;
-import android.content.pm.PackageParser;
+import android.content.pm.parsing.AndroidPackage;
import android.os.Binder;
import android.util.Log;
+
import com.android.internal.annotations.GuardedBy;
import com.android.server.pm.Installer;
@@ -33,19 +33,18 @@ public class ViewCompiler {
mInstaller = installer;
}
- public boolean compileLayouts(PackageParser.Package pkg) {
+ public boolean compileLayouts(AndroidPackage pkg) {
try {
- final String packageName = pkg.packageName;
- final String apkPath = pkg.baseCodePath;
- final ApplicationInfo appInfo = pkg.applicationInfo;
- final String outDexFile = appInfo.dataDir + "/code_cache/compiled_view.dex";
+ final String packageName = pkg.getPackageName();
+ final String apkPath = pkg.getBaseCodePath();
+ final String outDexFile = pkg.getDataDir() + "/code_cache/compiled_view.dex";
Log.i("PackageManager", "Compiling layouts in " + packageName + " (" + apkPath +
") to " + outDexFile);
long callingId = Binder.clearCallingIdentity();
try {
synchronized (mInstallLock) {
return mInstaller.compileLayouts(apkPath, packageName, outDexFile,
- appInfo.uid);
+ pkg.getUid());
}
} finally {
Binder.restoreCallingIdentity(callingId);
diff --git a/services/core/java/com/android/server/pm/permission/BasePermission.java b/services/core/java/com/android/server/pm/permission/BasePermission.java
index 6d22faa7032e..29248b50830a 100644
--- a/services/core/java/com/android/server/pm/permission/BasePermission.java
+++ b/services/core/java/com/android/server/pm/permission/BasePermission.java
@@ -29,10 +29,12 @@ import static com.android.server.pm.Settings.TAG_ITEM;
import android.annotation.IntDef;
import android.annotation.NonNull;
import android.annotation.Nullable;
-import android.content.pm.PackageParser;
-import android.content.pm.PackageParser.Permission;
+import android.content.pm.PackageManagerInternal;
import android.content.pm.PermissionInfo;
import android.content.pm.Signature;
+import android.content.pm.parsing.AndroidPackage;
+import android.content.pm.parsing.ComponentParseUtils.ParsedPermission;
+import android.content.pm.parsing.PackageInfoUtils;
import android.os.UserHandle;
import android.util.Log;
import android.util.Slog;
@@ -89,7 +91,7 @@ public final class BasePermission {
int protectionLevel;
- PackageParser.Permission perm;
+ ParsedPermission perm;
PermissionInfo pendingPermissionInfo;
@@ -113,12 +115,6 @@ public final class BasePermission {
protectionLevel = PermissionInfo.PROTECTION_SIGNATURE;
}
- @Override
- public String toString() {
- return "BasePermission{" + Integer.toHexString(System.identityHashCode(this)) + " " + name
- + "}";
- }
-
public String getName() {
return name;
}
@@ -144,7 +140,7 @@ public final class BasePermission {
this.gids = gids;
this.perUser = perUser;
}
- public void setPermission(@Nullable Permission perm) {
+ public void setPermission(@Nullable ParsedPermission perm) {
this.perm = perm;
}
public void setSourcePackageSetting(PackageSettingBase sourcePackageSetting) {
@@ -165,13 +161,13 @@ public final class BasePermission {
public int calculateFootprint(BasePermission perm) {
if (uid == perm.uid) {
- return perm.name.length() + perm.perm.info.calculateFootprint();
+ return perm.name.length() + perm.perm.calculateFootprint();
}
return 0;
}
- public boolean isPermission(Permission perm) {
- return this.perm == perm;
+ public boolean isPermission(ParsedPermission perm) {
+ return Objects.equals(this.perm.className, perm.className);
}
public boolean isDynamic() {
@@ -189,29 +185,24 @@ public final class BasePermission {
}
public boolean isRemoved() {
- return perm != null && perm.info != null
- && (perm.info.flags & PermissionInfo.FLAG_REMOVED) != 0;
+ return perm != null && (perm.flags & PermissionInfo.FLAG_REMOVED) != 0;
}
public boolean isSoftRestricted() {
- return perm != null && perm.info != null
- && (perm.info.flags & PermissionInfo.FLAG_SOFT_RESTRICTED) != 0;
+ return perm != null && (perm.flags & PermissionInfo.FLAG_SOFT_RESTRICTED) != 0;
}
public boolean isHardRestricted() {
- return perm != null && perm.info != null
- && (perm.info.flags & PermissionInfo.FLAG_HARD_RESTRICTED) != 0;
+ return perm != null && (perm.flags & PermissionInfo.FLAG_HARD_RESTRICTED) != 0;
}
public boolean isHardOrSoftRestricted() {
- return perm != null && perm.info != null
- && (perm.info.flags & (PermissionInfo.FLAG_HARD_RESTRICTED
+ return perm != null && (perm.flags & (PermissionInfo.FLAG_HARD_RESTRICTED
| PermissionInfo.FLAG_SOFT_RESTRICTED)) != 0;
}
public boolean isImmutablyRestricted() {
- return perm != null && perm.info != null
- && (perm.info.flags & PermissionInfo.FLAG_IMMUTABLY_RESTRICTED) != 0;
+ return perm != null && (perm.flags & PermissionInfo.FLAG_IMMUTABLY_RESTRICTED) != 0;
}
public boolean isSignature() {
@@ -297,13 +288,12 @@ public final class BasePermission {
(this.protectionLevel != protectionLevel
|| perm == null
|| uid != tree.uid
- || !perm.owner.equals(tree.perm.owner)
- || !comparePermissionInfos(perm.info, info));
+ || !Objects.equals(perm.getPackageName(), tree.perm.getPackageName())
+ || !comparePermissionInfos(perm, info));
this.protectionLevel = protectionLevel;
info = new PermissionInfo(info);
info.protectionLevel = protectionLevel;
- perm = new PackageParser.Permission(tree.perm.owner, info);
- perm.info.packageName = tree.perm.info.packageName;
+ perm = new ParsedPermission(tree.perm);
uid = tree.uid;
return changed;
}
@@ -316,71 +306,89 @@ public final class BasePermission {
final BasePermission tree = findPermissionTree(permissionTrees, name);
if (tree != null && tree.perm != null) {
sourcePackageSetting = tree.sourcePackageSetting;
- perm = new PackageParser.Permission(tree.perm.owner,
- new PermissionInfo(pendingPermissionInfo));
- perm.info.packageName = tree.perm.info.packageName;
- perm.info.name = name;
+ perm = new ParsedPermission(tree.perm);
+ perm.protectionLevel = pendingPermissionInfo.protectionLevel;
+ perm.flags = pendingPermissionInfo.flags;
+ perm.setGroup(pendingPermissionInfo.group);
+ perm.backgroundPermission = pendingPermissionInfo.backgroundPermission;
+ perm.descriptionRes = pendingPermissionInfo.descriptionRes;
+ perm.requestRes = pendingPermissionInfo.requestRes;
+ perm.setPackageName(tree.perm.getPackageName());
+ perm.setName(name);
uid = tree.uid;
}
}
}
- static BasePermission createOrUpdate(@Nullable BasePermission bp, @NonNull Permission p,
- @NonNull PackageParser.Package pkg, Collection<BasePermission> permissionTrees,
+ static BasePermission createOrUpdate(PackageManagerInternal packageManagerInternal,
+ @Nullable BasePermission bp, @NonNull ParsedPermission p,
+ @NonNull AndroidPackage pkg, Collection<BasePermission> permissionTrees,
boolean chatty) {
- final PackageSettingBase pkgSetting = (PackageSettingBase) pkg.mExtras;
+ final PackageSettingBase pkgSetting =
+ (PackageSettingBase) packageManagerInternal.getPackageSetting(pkg.getPackageName());
// Allow system apps to redefine non-system permissions
- if (bp != null && !Objects.equals(bp.sourcePackageName, p.info.packageName)) {
- final boolean currentOwnerIsSystem = (bp.perm != null
- && bp.perm.owner.isSystem());
- if (p.owner.isSystem()) {
+ if (bp != null && !Objects.equals(bp.sourcePackageName, p.getPackageName())) {
+ final boolean currentOwnerIsSystem;
+ if (bp.perm == null) {
+ currentOwnerIsSystem = false;
+ } else {
+ AndroidPackage currentPackage = packageManagerInternal.getPackage(
+ bp.perm.getPackageName());
+ if (currentPackage == null) {
+ currentOwnerIsSystem = false;
+ } else {
+ currentOwnerIsSystem = currentPackage.isSystem();
+ }
+ }
+
+ if (pkg.isSystem()) {
if (bp.type == BasePermission.TYPE_BUILTIN && bp.perm == null) {
// It's a built-in permission and no owner, take ownership now
+ p.flags |= PermissionInfo.FLAG_INSTALLED;
bp.sourcePackageSetting = pkgSetting;
bp.perm = p;
- bp.uid = pkg.applicationInfo.uid;
- bp.sourcePackageName = p.info.packageName;
- p.info.flags |= PermissionInfo.FLAG_INSTALLED;
+ bp.uid = pkg.getUid();
+ bp.sourcePackageName = p.getPackageName();
} else if (!currentOwnerIsSystem) {
- String msg = "New decl " + p.owner + " of permission "
- + p.info.name + " is system; overriding " + bp.sourcePackageName;
+ String msg = "New decl " + pkg + " of permission "
+ + p.getName() + " is system; overriding " + bp.sourcePackageName;
PackageManagerService.reportSettingsProblem(Log.WARN, msg);
bp = null;
}
}
}
if (bp == null) {
- bp = new BasePermission(p.info.name, p.info.packageName, TYPE_NORMAL);
+ bp = new BasePermission(p.getName(), p.getPackageName(), TYPE_NORMAL);
}
StringBuilder r = null;
if (bp.perm == null) {
if (bp.sourcePackageName == null
- || bp.sourcePackageName.equals(p.info.packageName)) {
- final BasePermission tree = findPermissionTree(permissionTrees, p.info.name);
+ || bp.sourcePackageName.equals(p.getPackageName())) {
+ final BasePermission tree = findPermissionTree(permissionTrees, p.getName());
if (tree == null
- || tree.sourcePackageName.equals(p.info.packageName)) {
+ || tree.sourcePackageName.equals(p.getPackageName())) {
+ p.flags |= PermissionInfo.FLAG_INSTALLED;
bp.sourcePackageSetting = pkgSetting;
bp.perm = p;
- bp.uid = pkg.applicationInfo.uid;
- bp.sourcePackageName = p.info.packageName;
- p.info.flags |= PermissionInfo.FLAG_INSTALLED;
+ bp.uid = pkg.getUid();
+ bp.sourcePackageName = p.getPackageName();
if (chatty) {
if (r == null) {
r = new StringBuilder(256);
} else {
r.append(' ');
}
- r.append(p.info.name);
+ r.append(p.getName());
}
} else {
- Slog.w(TAG, "Permission " + p.info.name + " from package "
- + p.info.packageName + " ignored: base tree "
+ Slog.w(TAG, "Permission " + p.getName() + " from package "
+ + p.getPackageName() + " ignored: base tree "
+ tree.name + " is from package "
+ tree.sourcePackageName);
}
} else {
- Slog.w(TAG, "Permission " + p.info.name + " from package "
- + p.info.packageName + " ignored: original from "
+ Slog.w(TAG, "Permission " + p.getName() + " from package "
+ + p.getPackageName() + " ignored: original from "
+ bp.sourcePackageName);
}
} else if (chatty) {
@@ -390,10 +398,10 @@ public final class BasePermission {
r.append(' ');
}
r.append("DUP:");
- r.append(p.info.name);
+ r.append(p.getName());
}
- if (bp.perm == p) {
- bp.protectionLevel = p.info.protectionLevel;
+ if (bp.perm != null && Objects.equals(bp.perm.className, p.className)) {
+ bp.protectionLevel = p.protectionLevel;
}
if (PackageManagerService.DEBUG_PACKAGE_SCANNING && r != null) {
Log.d(TAG, " Permissions: " + r);
@@ -417,17 +425,17 @@ public final class BasePermission {
throw new SecurityException("No permission tree found for " + permName);
}
- public void enforceDeclaredUsedAndRuntimeOrDevelopment(PackageParser.Package pkg) {
- final PackageSetting pkgSetting = (PackageSetting) pkg.mExtras;
+ public void enforceDeclaredUsedAndRuntimeOrDevelopment(AndroidPackage pkg,
+ PackageSetting pkgSetting) {
final PermissionsState permsState = pkgSetting.getPermissionsState();
- int index = pkg.requestedPermissions.indexOf(name);
+ int index = pkg.getRequestedPermissions().indexOf(name);
if (!permsState.hasRequestedPermission(name) && index == -1) {
- throw new SecurityException("Package " + pkg.packageName
+ throw new SecurityException("Package " + pkg.getPackageName()
+ " has not requested permission " + name);
}
if (!isRuntime() && !isDevelopment()) {
- throw new SecurityException("Permission " + name
- + " requested by " + pkg.packageName + " is not a changeable permission type");
+ throw new SecurityException("Permission " + name + " requested by "
+ + pkg.getPackageName() + " is not a changeable permission type");
}
}
@@ -445,12 +453,12 @@ public final class BasePermission {
public @Nullable PermissionInfo generatePermissionInfo(@NonNull String groupName, int flags) {
if (groupName == null) {
- if (perm == null || perm.info.group == null) {
+ if (perm == null || perm.getGroup() == null) {
return generatePermissionInfo(protectionLevel, flags);
}
} else {
- if (perm != null && groupName.equals(perm.info.group)) {
- return PackageParser.generatePermissionInfo(perm, flags);
+ if (perm != null && groupName.equals(perm.getGroup())) {
+ return PackageInfoUtils.generatePermissionInfo(perm, flags);
}
}
return null;
@@ -460,8 +468,8 @@ public final class BasePermission {
PermissionInfo permissionInfo;
if (perm != null) {
final boolean protectionLevelChanged = protectionLevel != adjustedProtectionLevel;
- permissionInfo = PackageParser.generatePermissionInfo(perm, flags);
- if (protectionLevelChanged && permissionInfo == perm.info) {
+ permissionInfo = PackageInfoUtils.generatePermissionInfo(perm, flags);
+ if (protectionLevelChanged) {
// if we return different protection level, don't use the cached info
permissionInfo = new PermissionInfo(permissionInfo);
permissionInfo.protectionLevel = adjustedProtectionLevel;
@@ -541,14 +549,18 @@ public final class BasePermission {
serializer.attribute(null, "protection", Integer.toString(protectionLevel));
}
if (type == BasePermission.TYPE_DYNAMIC) {
- final PermissionInfo pi = perm != null ? perm.info : pendingPermissionInfo;
- if (pi != null) {
+ if (perm != null || pendingPermissionInfo != null) {
serializer.attribute(null, "type", "dynamic");
- if (pi.icon != 0) {
- serializer.attribute(null, "icon", Integer.toString(pi.icon));
+ int icon = perm != null ? perm.icon : pendingPermissionInfo.icon;
+ CharSequence nonLocalizedLabel = perm != null
+ ? perm.nonLocalizedLabel
+ : pendingPermissionInfo.nonLocalizedLabel;
+
+ if (icon != 0) {
+ serializer.attribute(null, "icon", Integer.toString(icon));
}
- if (pi.nonLocalizedLabel != null) {
- serializer.attribute(null, "label", pi.nonLocalizedLabel.toString());
+ if (nonLocalizedLabel != null) {
+ serializer.attribute(null, "label", nonLocalizedLabel.toString());
}
}
}
@@ -568,14 +580,14 @@ public final class BasePermission {
return s1.equals(s2);
}
- private static boolean comparePermissionInfos(PermissionInfo pi1, PermissionInfo pi2) {
+ private static boolean comparePermissionInfos(ParsedPermission pi1, PermissionInfo pi2) {
if (pi1.icon != pi2.icon) return false;
if (pi1.logo != pi2.logo) return false;
if (pi1.protectionLevel != pi2.protectionLevel) return false;
- if (!compareStrings(pi1.name, pi2.name)) return false;
+ if (!compareStrings(pi1.getName(), pi2.name)) return false;
if (!compareStrings(pi1.nonLocalizedLabel, pi2.nonLocalizedLabel)) return false;
// We'll take care of setting this one.
- if (!compareStrings(pi1.packageName, pi2.packageName)) return false;
+ if (!compareStrings(pi1.getPackageName(), pi2.packageName)) return false;
// These are not currently stored in settings.
//if (!compareStrings(pi1.group, pi2.group)) return false;
//if (!compareStrings(pi1.nonLocalizedDescription, pi2.nonLocalizedDescription)) return false;
@@ -611,9 +623,9 @@ public final class BasePermission {
pw.println(PermissionInfo.protectionToString(protectionLevel));
if (perm != null) {
pw.print(" perm="); pw.println(perm);
- if ((perm.info.flags & PermissionInfo.FLAG_INSTALLED) == 0
- || (perm.info.flags & PermissionInfo.FLAG_REMOVED) != 0) {
- pw.print(" flags=0x"); pw.println(Integer.toHexString(perm.info.flags));
+ if ((perm.flags & PermissionInfo.FLAG_INSTALLED) == 0
+ || (perm.flags & PermissionInfo.FLAG_REMOVED) != 0) {
+ pw.print(" flags=0x"); pw.println(Integer.toHexString(perm.flags));
}
}
if (sourcePackageSetting != null) {
@@ -625,4 +637,20 @@ public final class BasePermission {
}
return true;
}
+
+ @Override
+ public String toString() {
+ return "BasePermission{" +
+ "name='" + name + '\'' +
+ ", type=" + type +
+ ", sourcePackageName='" + sourcePackageName + '\'' +
+ ", sourcePackageSetting=" + sourcePackageSetting +
+ ", protectionLevel=" + protectionLevel +
+ ", perm=" + perm +
+ ", pendingPermissionInfo=" + pendingPermissionInfo +
+ ", uid=" + uid +
+ ", gids=" + Arrays.toString(gids) +
+ ", perUser=" + perUser +
+ '}';
+ }
}
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
index b831374cec45..9dadf3e7e8f3 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java
@@ -64,10 +64,13 @@ import android.content.pm.PackageManager.PermissionInfoFlags;
import android.content.pm.PackageManager.PermissionWhitelistFlags;
import android.content.pm.PackageManagerInternal;
import android.content.pm.PackageParser;
-import android.content.pm.PackageParser.Package;
import android.content.pm.ParceledListSlice;
import android.content.pm.PermissionGroupInfo;
import android.content.pm.PermissionInfo;
+import android.content.pm.parsing.AndroidPackage;
+import android.content.pm.parsing.ComponentParseUtils.ParsedPermission;
+import android.content.pm.parsing.ComponentParseUtils.ParsedPermissionGroup;
+import android.content.pm.parsing.PackageInfoUtils;
import android.content.pm.permission.SplitPermissionInfoParcelable;
import android.metrics.LogMaker;
import android.os.Binder;
@@ -420,7 +423,8 @@ public class PermissionManagerService extends IPermissionManager.Stub {
}
}
- @Nullable BasePermission getPermission(String permName) {
+ @Nullable
+ BasePermission getPermission(String permName) {
synchronized (mLock) {
return mSettings.getPermissionLocked(permName);
}
@@ -454,10 +458,9 @@ public class PermissionManagerService extends IPermissionManager.Stub {
}
synchronized (mLock) {
final int n = mSettings.mPermissionGroups.size();
- final ArrayList<PermissionGroupInfo> out =
- new ArrayList<PermissionGroupInfo>(n);
- for (PackageParser.PermissionGroup pg : mSettings.mPermissionGroups.values()) {
- out.add(PackageParser.generatePermissionGroupInfo(pg, flags));
+ final ArrayList<PermissionGroupInfo> out = new ArrayList<>(n);
+ for (ParsedPermissionGroup pg : mSettings.mPermissionGroups.values()) {
+ out.add(PackageInfoUtils.generatePermissionGroupInfo(pg, flags));
}
return new ParceledListSlice<>(out);
}
@@ -473,7 +476,7 @@ public class PermissionManagerService extends IPermissionManager.Stub {
return null;
}
synchronized (mLock) {
- return PackageParser.generatePermissionGroupInfo(
+ return PackageInfoUtils.generatePermissionGroupInfo(
mSettings.mPermissionGroups.get(groupName), flags);
}
}
@@ -597,8 +600,13 @@ public class PermissionManagerService extends IPermissionManager.Stub {
false, // requirePermissionWhenSameUser
"getPermissionFlags");
- final PackageParser.Package pkg = mPackageManagerInt.getPackage(packageName);
- if (pkg == null || pkg.mExtras == null) {
+ final AndroidPackage pkg = mPackageManagerInt.getPackage(packageName);
+ if (pkg == null) {
+ return 0;
+ }
+ final PackageSetting ps = (PackageSetting) mPackageManagerInt.getPackageSetting(
+ pkg.getPackageName());
+ if (ps == null) {
return 0;
}
synchronized (mLock) {
@@ -609,7 +617,6 @@ public class PermissionManagerService extends IPermissionManager.Stub {
if (mPackageManagerInt.filterAppAccess(pkg, callingUid, userId)) {
return 0;
}
- final PackageSetting ps = (PackageSetting) pkg.mExtras;
PermissionsState permissionsState = ps.getPermissionsState();
return permissionsState.getPermissionFlags(permName, userId);
}
@@ -696,8 +703,10 @@ public class PermissionManagerService extends IPermissionManager.Stub {
flagValues &= ~PackageManager.FLAG_PERMISSION_APPLY_RESTRICTION;
}
- final PackageParser.Package pkg = mPackageManagerInt.getPackage(packageName);
- if (pkg == null || pkg.mExtras == null) {
+ final AndroidPackage pkg = mPackageManagerInt.getPackage(packageName);
+ final PackageSetting ps = (PackageSetting) mPackageManagerInt.getPackageSetting(
+ packageName);
+ if (pkg == null || ps == null) {
Log.e(TAG, "Unknown package: " + packageName);
return;
}
@@ -713,7 +722,6 @@ public class PermissionManagerService extends IPermissionManager.Stub {
throw new IllegalArgumentException("Unknown permission: " + permName);
}
- final PackageSetting ps = (PackageSetting) pkg.mExtras;
final PermissionsState permissionsState = ps.getPermissionsState();
final boolean hadState =
permissionsState.getRuntimePermissionState(permName, userId) != null;
@@ -726,11 +734,11 @@ public class PermissionManagerService extends IPermissionManager.Stub {
// Install and runtime permissions are stored in different places,
// so figure out what permission changed and persist the change.
if (permissionsState.getInstallPermissionState(permName) != null) {
- callback.onInstallPermissionUpdatedNotifyListener(pkg.applicationInfo.uid);
+ callback.onInstallPermissionUpdatedNotifyListener(pkg.getUid());
} else if (permissionsState.getRuntimePermissionState(permName, userId) != null
|| hadState) {
- callback.onPermissionUpdatedNotifyListener(new int[] { userId }, false,
- pkg.applicationInfo.uid);
+ callback.onPermissionUpdatedNotifyListener(new int[]{userId}, false,
+ pkg.getUid());
}
}
}
@@ -762,18 +770,16 @@ public class PermissionManagerService extends IPermissionManager.Stub {
? flagValues : flagValues & ~PackageManager.FLAG_PERMISSION_SYSTEM_FIXED;
final boolean[] changed = new boolean[1];
- mPackageManagerInt.forEachPackage(new Consumer<PackageParser.Package>() {
- @Override
- public void accept(Package pkg) {
- final PackageSetting ps = (PackageSetting) pkg.mExtras;
- if (ps == null) {
- return;
- }
- final PermissionsState permissionsState = ps.getPermissionsState();
- changed[0] |= permissionsState.updatePermissionFlagsForAllPermissions(
- userId, effectiveFlagMask, effectiveFlagValues);
- mOnPermissionChangeListeners.onPermissionsChanged(pkg.applicationInfo.uid);
+ mPackageManagerInt.forEachPackage(pkg -> {
+ final PackageSetting ps = (PackageSetting) mPackageManagerInt.getPackageSetting(
+ pkg.getPackageName());
+ if (ps == null) {
+ return;
}
+ final PermissionsState permissionsState = ps.getPermissionsState();
+ changed[0] |= permissionsState.updatePermissionFlagsForAllPermissions(
+ userId, effectiveFlagMask, effectiveFlagValues);
+ mOnPermissionChangeListeners.onPermissionsChanged(pkg.getUid());
});
if (changed[0]) {
@@ -804,7 +810,7 @@ public class PermissionManagerService extends IPermissionManager.Stub {
private int checkPermissionImpl(@NonNull String permissionName, @NonNull String packageName,
@UserIdInt int userId) {
- final PackageParser.Package pkg = mPackageManagerInt.getPackage(packageName);
+ final AndroidPackage pkg = mPackageManagerInt.getPackage(packageName);
if (pkg == null) {
return PackageManager.PERMISSION_DENIED;
}
@@ -812,11 +818,11 @@ public class PermissionManagerService extends IPermissionManager.Stub {
? PackageManager.PERMISSION_GRANTED : PackageManager.PERMISSION_DENIED;
}
- private boolean checkPermissionInternal(@NonNull Package pkg, boolean isPackageExplicit,
+ private boolean checkPermissionInternal(@NonNull AndroidPackage pkg, boolean isPackageExplicit,
@NonNull String permissionName, boolean useRequestedPermissionsForLegacyApps,
@UserIdInt int userId) {
final int callingUid = getCallingUid();
- if (isPackageExplicit || pkg.mSharedUserId == null) {
+ if (isPackageExplicit || pkg.getSharedUserId() == null) {
if (mPackageManagerInt.filterAppAccess(pkg, callingUid, userId)) {
return false;
}
@@ -826,8 +832,9 @@ public class PermissionManagerService extends IPermissionManager.Stub {
}
}
- final int uid = UserHandle.getUid(userId, pkg.applicationInfo.uid);
- final PackageSetting ps = (PackageSetting) pkg.mExtras;
+ final int uid = UserHandle.getUid(userId, pkg.getUid());
+ final PackageSetting ps = (PackageSetting) mPackageManagerInt.getPackageSetting(
+ pkg.getPackageName());
if (ps == null) {
return false;
}
@@ -858,9 +865,9 @@ public class PermissionManagerService extends IPermissionManager.Stub {
final String[] packageNames = mContext.getPackageManager().getPackagesForUid(uid);
final int packageNamesSize = packageNames != null ? packageNames.length : 0;
for (int i = 0; i < packageNamesSize; i++) {
- final PackageParser.Package pkg = mPackageManagerInt.getPackage(packageNames[i]);
- if (pkg != null && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M
- && pkg.requestedPermissions.contains(permissionName)) {
+ final AndroidPackage pkg = mPackageManagerInt.getPackage(packageNames[i]);
+ if (pkg != null && pkg.getTargetSdkVersion() < Build.VERSION_CODES.M
+ && pkg.getRequestedPermissions().contains(permissionName)) {
hasPermission = true;
break;
}
@@ -901,7 +908,7 @@ public class PermissionManagerService extends IPermissionManager.Stub {
}
private int checkUidPermissionImpl(@NonNull String permissionName, int uid) {
- final PackageParser.Package pkg = mPackageManagerInt.getPackage(uid);
+ final AndroidPackage pkg = mPackageManagerInt.getPackage(uid);
return checkUidPermissionInternal(uid, pkg, permissionName, true)
? PackageManager.PERMISSION_GRANTED : PackageManager.PERMISSION_DENIED;
}
@@ -913,7 +920,7 @@ public class PermissionManagerService extends IPermissionManager.Stub {
*
* @see SystemConfig#getSystemPermissions()
*/
- private boolean checkUidPermissionInternal(int uid, @Nullable Package pkg,
+ private boolean checkUidPermissionInternal(int uid, @Nullable AndroidPackage pkg,
@NonNull String permissionName, boolean useRequestedPermissionsForLegacyApps) {
if (pkg != null) {
final int userId = UserHandle.getUserId(uid);
@@ -948,7 +955,7 @@ public class PermissionManagerService extends IPermissionManager.Stub {
}
private boolean isUidPermissionGranted(int uid, @NonNull String permissionName) {
- final PackageParser.Package pkg = mPackageManagerInt.getPackage(uid);
+ final AndroidPackage pkg = mPackageManagerInt.getPackage(uid);
return checkUidPermissionInternal(uid, pkg, permissionName, false);
}
@@ -989,7 +996,7 @@ public class PermissionManagerService extends IPermissionManager.Stub {
"getWhitelistedRestrictedPermissions for user " + userId);
}
- final PackageParser.Package pkg = mPackageManagerInt.getPackage(packageName);
+ final AndroidPackage pkg = mPackageManagerInt.getPackage(packageName);
if (pkg == null) {
return null;
}
@@ -1022,7 +1029,7 @@ public class PermissionManagerService extends IPermissionManager.Stub {
final long identity = Binder.clearCallingIdentity();
try {
final PermissionsState permissionsState =
- PackageManagerServiceUtils.getPermissionsState(pkg);
+ PackageManagerServiceUtils.getPermissionsState(mPackageManagerInt, pkg);
if (permissionsState == null) {
return null;
}
@@ -1040,9 +1047,9 @@ public class PermissionManagerService extends IPermissionManager.Stub {
ArrayList<String> whitelistedPermissions = null;
- final int permissionCount = pkg.requestedPermissions.size();
+ final int permissionCount = ArrayUtils.size(pkg.getRequestedPermissions());
for (int i = 0; i < permissionCount; i++) {
- final String permissionName = pkg.requestedPermissions.get(i);
+ final String permissionName = pkg.getRequestedPermissions().get(i);
final int currentFlags =
permissionsState.getPermissionFlags(permissionName, userId);
if ((currentFlags & queryFlags) != 0) {
@@ -1139,7 +1146,7 @@ public class PermissionManagerService extends IPermissionManager.Stub {
"setWhitelistedRestrictedPermissions for user " + userId);
}
- final PackageParser.Package pkg = mPackageManagerInt.getPackage(packageName);
+ final AndroidPackage pkg = mPackageManagerInt.getPackage(packageName);
if (pkg == null) {
return false;
}
@@ -1168,7 +1175,7 @@ public class PermissionManagerService extends IPermissionManager.Stub {
+ Manifest.permission.WHITELIST_RESTRICTED_PERMISSIONS);
}
final List<String> whitelistedPermissions =
- getWhitelistedRestrictedPermissions(pkg.packageName, flags, userId);
+ getWhitelistedRestrictedPermissions(pkg.getPackageName(), flags, userId);
if (permissions == null || permissions.isEmpty()) {
if (whitelistedPermissions == null || whitelistedPermissions.isEmpty()) {
return true;
@@ -1242,8 +1249,10 @@ public class PermissionManagerService extends IPermissionManager.Stub {
false, // requirePermissionWhenSameUser
"grantRuntimePermission");
- final PackageParser.Package pkg = mPackageManagerInt.getPackage(packageName);
- if (pkg == null || pkg.mExtras == null) {
+ final AndroidPackage pkg = mPackageManagerInt.getPackage(packageName);
+ final PackageSetting ps = (PackageSetting) mPackageManagerInt.getPackageSetting(
+ packageName);
+ if (pkg == null || ps == null) {
Log.e(TAG, "Unknown package: " + packageName);
return;
}
@@ -1258,21 +1267,19 @@ public class PermissionManagerService extends IPermissionManager.Stub {
throw new IllegalArgumentException("Unknown package: " + packageName);
}
- bp.enforceDeclaredUsedAndRuntimeOrDevelopment(pkg);
+ bp.enforceDeclaredUsedAndRuntimeOrDevelopment(pkg, ps);
// If a permission review is required for legacy apps we represent
// their permissions as always granted runtime ones since we need
// to keep the review required permission flag per user while an
// install permission's state is shared across all users.
- if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M
+ if (pkg.getTargetSdkVersion() < Build.VERSION_CODES.M
&& bp.isRuntime()) {
return;
}
- final int uid = UserHandle.getUid(userId,
- UserHandle.getAppId(pkg.applicationInfo.uid));
+ final int uid = UserHandle.getUid(userId, UserHandle.getAppId(pkg.getUid()));
- final PackageSetting ps = (PackageSetting) pkg.mExtras;
final PermissionsState permissionsState = ps.getPermissionsState();
final int flags = permissionsState.getPermissionFlags(permName, userId);
@@ -1295,7 +1302,7 @@ public class PermissionManagerService extends IPermissionManager.Stub {
}
if (bp.isSoftRestricted() && !SoftRestrictedPermissionPolicy.forPermission(mContext,
- pkg.applicationInfo, UserHandle.of(userId), permName).canBeGranted()) {
+ pkg, UserHandle.of(userId), permName).canBeGranted()) {
Log.e(TAG, "Cannot grant soft restricted permission " + permName + " for package "
+ packageName);
return;
@@ -1318,7 +1325,7 @@ public class PermissionManagerService extends IPermissionManager.Stub {
+ permName + " for package " + packageName);
}
- if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
+ if (pkg.getTargetSdkVersion() < Build.VERSION_CODES.M) {
Slog.w(TAG, "Cannot grant runtime permission to a legacy app");
return;
}
@@ -1331,7 +1338,7 @@ public class PermissionManagerService extends IPermissionManager.Stub {
case PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: {
if (callback != null) {
- callback.onGidsChanged(UserHandle.getAppId(pkg.applicationInfo.uid), userId);
+ callback.onGidsChanged(UserHandle.getAppId(pkg.getUid()), userId);
}
}
break;
@@ -1404,8 +1411,10 @@ public class PermissionManagerService extends IPermissionManager.Stub {
false, // requirePermissionWhenSameUser
"revokeRuntimePermission");
- final PackageParser.Package pkg = mPackageManagerInt.getPackage(packageName);
- if (pkg == null || pkg.mExtras == null) {
+ final AndroidPackage pkg = mPackageManagerInt.getPackage(packageName);
+ final PackageSetting ps = (PackageSetting) mPackageManagerInt.getPackageSetting(
+ packageName);
+ if (pkg == null || ps == null) {
Log.e(TAG, "Unknown package: " + packageName);
return;
}
@@ -1417,18 +1426,17 @@ public class PermissionManagerService extends IPermissionManager.Stub {
throw new IllegalArgumentException("Unknown permission: " + permName);
}
- bp.enforceDeclaredUsedAndRuntimeOrDevelopment(pkg);
+ bp.enforceDeclaredUsedAndRuntimeOrDevelopment(pkg, ps);
// If a permission review is required for legacy apps we represent
// their permissions as always granted runtime ones since we need
// to keep the review required permission flag per user while an
// install permission's state is shared across all users.
- if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M
+ if (pkg.getTargetSdkVersion() < Build.VERSION_CODES.M
&& bp.isRuntime()) {
return;
}
- final PackageSetting ps = (PackageSetting) pkg.mExtras;
final PermissionsState permissionsState = ps.getPermissionsState();
final int flags = permissionsState.getPermissionFlags(permName, userId);
@@ -1471,7 +1479,7 @@ public class PermissionManagerService extends IPermissionManager.Stub {
if (callback != null) {
callback.onPermissionRevoked(UserHandle.getUid(userId,
- UserHandle.getAppId(pkg.applicationInfo.uid)), userId);
+ UserHandle.getAppId(pkg.getUid())), userId);
}
if (bp.isRuntime()) {
@@ -1496,7 +1504,7 @@ public class PermissionManagerService extends IPermissionManager.Stub {
StorageManager.UUID_PRIVATE_INTERNAL, false, mDefaultPermissionCallback);
for (final int userId : UserManagerService.getInstance().getUserIds()) {
mPackageManagerInt.forEachPackage(
- (PackageParser.Package pkg) -> resetRuntimePermissionsInternal(pkg, userId));
+ (AndroidPackage pkg) -> resetRuntimePermissionsInternal(pkg, userId));
}
}
@@ -1507,9 +1515,9 @@ public class PermissionManagerService extends IPermissionManager.Stub {
* @param userId The device user for which to do a reset.
*/
@GuardedBy("mLock")
- private void resetRuntimePermissionsInternal(final PackageParser.Package pkg,
+ private void resetRuntimePermissionsInternal(final AndroidPackage pkg,
final int userId) {
- final String packageName = pkg.packageName;
+ final String packageName = pkg.getPackageName();
// These are flags that can change base on user actions.
final int userSettableMask = FLAG_PERMISSION_USER_SET
@@ -1521,7 +1529,7 @@ public class PermissionManagerService extends IPermissionManager.Stub {
| FLAG_PERMISSION_POLICY_FIXED;
// Delay and combine non-async permission callbacks
- final int permissionCount = pkg.requestedPermissions.size();
+ final int permissionCount = ArrayUtils.size(pkg.getRequestedPermissions());
final boolean[] permissionRemoved = new boolean[1];
final ArraySet<Long> revokedPermissions = new ArraySet<>();
final IntArray syncUpdatedUsers = new IntArray(permissionCount);
@@ -1579,7 +1587,7 @@ public class PermissionManagerService extends IPermissionManager.Stub {
final AppOpsManager appOpsManager = mContext.getSystemService(AppOpsManager.class);
for (int i = 0; i < permissionCount; i++) {
- final String permName = pkg.requestedPermissions.get(i);
+ final String permName = pkg.getRequestedPermissions().get(i);
final BasePermission bp;
synchronized (mLock) {
bp = mSettings.getPermissionLocked(permName);
@@ -1594,7 +1602,7 @@ public class PermissionManagerService extends IPermissionManager.Stub {
// If shared user we just reset the state to which only this app contributed.
final String sharedUserId =
- mPackageManagerInt.getSharedUserIdForPackage(pkg.packageName);
+ mPackageManagerInt.getSharedUserIdForPackage(pkg.getPackageName());
final String[] pkgNames =
mPackageManagerInt.getPackagesForSharedUserId(sharedUserId, userId);
if (pkgNames != null && pkgNames.length > 0) {
@@ -1602,10 +1610,10 @@ public class PermissionManagerService extends IPermissionManager.Stub {
final int packageCount = pkgNames.length;
for (int j = 0; j < packageCount; j++) {
final String sharedPkgName = pkgNames[j];
- final PackageParser.Package sharedPkg =
+ final AndroidPackage sharedPkg =
mPackageManagerInt.getPackage(sharedPkgName);
- if (sharedPkg != null && !sharedPkg.packageName.equals(packageName)
- && sharedPkg.requestedPermissions.contains(permName)) {
+ if (sharedPkg != null && !sharedPkg.getPackageName().equals(packageName)
+ && sharedPkg.getRequestedPermissions().contains(permName)) {
used = true;
break;
}
@@ -2028,15 +2036,16 @@ public class PermissionManagerService extends IPermissionManager.Stub {
return protectionLevel;
}
// Normalize package name to handle renamed packages and static libs
- final PackageParser.Package pkg = mPackageManagerInt.getPackage(packageName);
+ final AndroidPackage pkg = mPackageManagerInt.getPackage(packageName);
if (pkg == null) {
return protectionLevel;
}
- if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.O) {
+ if (pkg.getTargetSdkVersion() < Build.VERSION_CODES.O) {
return protectionLevelMasked;
}
// Apps that target O see flags for all protection levels.
- final PackageSetting ps = (PackageSetting) pkg.mExtras;
+ final PackageSetting ps = (PackageSetting) mPackageManagerInt.getPackageSetting(
+ pkg.getPackageName());
if (ps == null) {
return protectionLevel;
}
@@ -2057,35 +2066,35 @@ public class PermissionManagerService extends IPermissionManager.Stub {
* @param permissionCallback Callback for permission changed
*/
private void revokeRuntimePermissionsIfGroupChanged(
- @NonNull PackageParser.Package newPackage,
- @NonNull PackageParser.Package oldPackage,
+ @NonNull AndroidPackage newPackage,
+ @NonNull AndroidPackage oldPackage,
@NonNull ArrayList<String> allPackageNames,
@NonNull PermissionCallback permissionCallback) {
- final int numOldPackagePermissions = oldPackage.permissions.size();
+ final int numOldPackagePermissions = ArrayUtils.size(oldPackage.getPermissions());
final ArrayMap<String, String> oldPermissionNameToGroupName
= new ArrayMap<>(numOldPackagePermissions);
for (int i = 0; i < numOldPackagePermissions; i++) {
- final PackageParser.Permission permission = oldPackage.permissions.get(i);
+ final ParsedPermission permission = oldPackage.getPermissions().get(i);
- if (permission.group != null) {
- oldPermissionNameToGroupName.put(permission.info.name,
- permission.group.info.name);
+ if (permission.parsedPermissionGroup != null) {
+ oldPermissionNameToGroupName.put(permission.getName(),
+ permission.parsedPermissionGroup.getName());
}
}
final int callingUid = Binder.getCallingUid();
- final int numNewPackagePermissions = newPackage.permissions.size();
+ final int numNewPackagePermissions = ArrayUtils.size(newPackage.getPermissions());
for (int newPermissionNum = 0; newPermissionNum < numNewPackagePermissions;
newPermissionNum++) {
- final PackageParser.Permission newPermission =
- newPackage.permissions.get(newPermissionNum);
- final int newProtection = newPermission.info.getProtection();
+ final ParsedPermission newPermission =
+ newPackage.getPermissions().get(newPermissionNum);
+ final int newProtection = newPermission.getProtection();
if ((newProtection & PermissionInfo.PROTECTION_DANGEROUS) != 0) {
- final String permissionName = newPermission.info.name;
- final String newPermissionGroupName =
- newPermission.group == null ? null : newPermission.group.info.name;
+ final String permissionName = newPermission.getName();
+ final String newPermissionGroupName = newPermission.parsedPermissionGroup == null
+ ? null : newPermission.parsedPermissionGroup.getName();
final String oldPermissionGroupName = oldPermissionNameToGroupName.get(
permissionName);
@@ -2103,7 +2112,7 @@ public class PermissionManagerService extends IPermissionManager.Stub {
userId);
if (permissionState == PackageManager.PERMISSION_GRANTED) {
EventLog.writeEvent(0x534e4554, "72710897",
- newPackage.applicationInfo.uid,
+ newPackage.getUid(),
"Revoking permission " + permissionName +
" from package " + packageName +
" as the group changed from " + oldPermissionGroupName +
@@ -2124,54 +2133,56 @@ public class PermissionManagerService extends IPermissionManager.Stub {
}
}
- private void addAllPermissions(PackageParser.Package pkg, boolean chatty) {
- final int N = pkg.permissions.size();
+ private void addAllPermissions(AndroidPackage pkg, boolean chatty) {
+ final int N = ArrayUtils.size(pkg.getPermissions());
for (int i=0; i<N; i++) {
- PackageParser.Permission p = pkg.permissions.get(i);
+ ParsedPermission p = pkg.getPermissions().get(i);
// Assume by default that we did not install this permission into the system.
- p.info.flags &= ~PermissionInfo.FLAG_INSTALLED;
+ p.flags &= ~PermissionInfo.FLAG_INSTALLED;
synchronized (PermissionManagerService.this.mLock) {
// Now that permission groups have a special meaning, we ignore permission
// groups for legacy apps to prevent unexpected behavior. In particular,
// permissions for one app being granted to someone just because they happen
// to be in a group defined by another app (before this had no implications).
- if (pkg.applicationInfo.targetSdkVersion > Build.VERSION_CODES.LOLLIPOP_MR1) {
- p.group = mSettings.mPermissionGroups.get(p.info.group);
+ if (pkg.getTargetSdkVersion() > Build.VERSION_CODES.LOLLIPOP_MR1) {
+ p.parsedPermissionGroup = mSettings.mPermissionGroups.get(p.getGroup());
// Warn for a permission in an unknown group.
if (DEBUG_PERMISSIONS
- && p.info.group != null && p.group == null) {
- Slog.i(TAG, "Permission " + p.info.name + " from package "
- + p.info.packageName + " in an unknown group " + p.info.group);
+ && p.getGroup() != null && p.parsedPermissionGroup == null) {
+ Slog.i(TAG, "Permission " + p.getName() + " from package "
+ + p.getPackageName() + " in an unknown group " + p.getGroup());
}
}
if (p.tree) {
final BasePermission bp = BasePermission.createOrUpdate(
- mSettings.getPermissionTreeLocked(p.info.name), p, pkg,
+ mPackageManagerInt,
+ mSettings.getPermissionTreeLocked(p.getName()), p, pkg,
mSettings.getAllPermissionTreesLocked(), chatty);
- mSettings.putPermissionTreeLocked(p.info.name, bp);
+ mSettings.putPermissionTreeLocked(p.getName(), bp);
} else {
final BasePermission bp = BasePermission.createOrUpdate(
- mSettings.getPermissionLocked(p.info.name),
+ mPackageManagerInt,
+ mSettings.getPermissionLocked(p.getName()),
p, pkg, mSettings.getAllPermissionTreesLocked(), chatty);
- mSettings.putPermissionLocked(p.info.name, bp);
+ mSettings.putPermissionLocked(p.getName(), bp);
}
}
}
}
- private void addAllPermissionGroups(PackageParser.Package pkg, boolean chatty) {
- final int N = pkg.permissionGroups.size();
+ private void addAllPermissionGroups(AndroidPackage pkg, boolean chatty) {
+ final int N = ArrayUtils.size(pkg.getPermissionGroups());
StringBuilder r = null;
for (int i=0; i<N; i++) {
- final PackageParser.PermissionGroup pg = pkg.permissionGroups.get(i);
- final PackageParser.PermissionGroup cur = mSettings.mPermissionGroups.get(pg.info.name);
- final String curPackageName = (cur == null) ? null : cur.info.packageName;
- final boolean isPackageUpdate = pg.info.packageName.equals(curPackageName);
+ final ParsedPermissionGroup pg = pkg.getPermissionGroups().get(i);
+ final ParsedPermissionGroup cur = mSettings.mPermissionGroups.get(pg.getName());
+ final String curPackageName = (cur == null) ? null : cur.getPackageName();
+ final boolean isPackageUpdate = pg.getPackageName().equals(curPackageName);
if (cur == null || isPackageUpdate) {
- mSettings.mPermissionGroups.put(pg.info.name, pg);
+ mSettings.mPermissionGroups.put(pg.getName(), pg);
if (chatty && DEBUG_PACKAGE_SCANNING) {
if (r == null) {
r = new StringBuilder(256);
@@ -2181,12 +2192,12 @@ public class PermissionManagerService extends IPermissionManager.Stub {
if (isPackageUpdate) {
r.append("UPD:");
}
- r.append(pg.info.name);
+ r.append(pg.getName());
}
} else {
- Slog.w(TAG, "Permission group " + pg.info.name + " from package "
- + pg.info.packageName + " ignored: original from "
- + cur.info.packageName);
+ Slog.w(TAG, "Permission group " + pg.getName() + " from package "
+ + pg.getPackageName() + " ignored: original from "
+ + cur.getPackageName());
if (chatty && DEBUG_PACKAGE_SCANNING) {
if (r == null) {
r = new StringBuilder(256);
@@ -2194,7 +2205,7 @@ public class PermissionManagerService extends IPermissionManager.Stub {
r.append(' ');
}
r.append("DUP:");
- r.append(pg.info.name);
+ r.append(pg.getName());
}
}
}
@@ -2204,15 +2215,15 @@ public class PermissionManagerService extends IPermissionManager.Stub {
}
- private void removeAllPermissions(PackageParser.Package pkg, boolean chatty) {
+ private void removeAllPermissions(AndroidPackage pkg, boolean chatty) {
synchronized (mLock) {
- int N = pkg.permissions.size();
+ int N = ArrayUtils.size(pkg.getPermissions());
StringBuilder r = null;
for (int i=0; i<N; i++) {
- PackageParser.Permission p = pkg.permissions.get(i);
- BasePermission bp = (BasePermission) mSettings.mPermissions.get(p.info.name);
+ ParsedPermission p = pkg.getPermissions().get(i);
+ BasePermission bp = mSettings.mPermissions.get(p.getName());
if (bp == null) {
- bp = mSettings.mPermissionTrees.get(p.info.name);
+ bp = mSettings.mPermissionTrees.get(p.getName());
}
if (bp != null && bp.isPermission(p)) {
bp.setPermission(null);
@@ -2222,14 +2233,14 @@ public class PermissionManagerService extends IPermissionManager.Stub {
} else {
r.append(' ');
}
- r.append(p.info.name);
+ r.append(p.getName());
}
}
if (p.isAppOp()) {
ArraySet<String> appOpPkgs =
- mSettings.mAppOpPermissionPackages.get(p.info.name);
+ mSettings.mAppOpPermissionPackages.get(p.getName());
if (appOpPkgs != null) {
- appOpPkgs.remove(pkg.packageName);
+ appOpPkgs.remove(pkg.getPackageName());
}
}
}
@@ -2237,14 +2248,14 @@ public class PermissionManagerService extends IPermissionManager.Stub {
if (DEBUG_REMOVE) Log.d(TAG, " Permissions: " + r);
}
- N = pkg.requestedPermissions.size();
+ N = pkg.getRequestedPermissions().size();
r = null;
for (int i=0; i<N; i++) {
- String perm = pkg.requestedPermissions.get(i);
+ String perm = pkg.getRequestedPermissions().get(i);
if (mSettings.isPermissionAppOp(perm)) {
ArraySet<String> appOpPkgs = mSettings.mAppOpPermissionPackages.get(perm);
if (appOpPkgs != null) {
- appOpPkgs.remove(pkg.packageName);
+ appOpPkgs.remove(pkg.getPackageName());
if (appOpPkgs.isEmpty()) {
mSettings.mAppOpPermissionPackages.remove(perm);
}
@@ -2273,7 +2284,7 @@ public class PermissionManagerService extends IPermissionManager.Stub {
* @param packageOfInterest If this is the name of {@code pkg} add extra logging
* @param callback Result call back
*/
- private void restorePermissionState(@NonNull PackageParser.Package pkg, boolean replace,
+ private void restorePermissionState(@NonNull AndroidPackage pkg, boolean replace,
@Nullable String packageOfInterest, @Nullable PermissionCallback callback) {
// IMPORTANT: There are two types of permissions: install and runtime.
// Install time permissions are granted when the app is installed to
@@ -2286,7 +2297,8 @@ public class PermissionManagerService extends IPermissionManager.Stub {
// being upgraded to target a newer SDK, in which case dangerous permissions
// are transformed from install time to runtime ones.
- final PackageSetting ps = (PackageSetting) pkg.mExtras;
+ final PackageSetting ps = (PackageSetting) mPackageManagerInt.getPackageSetting(
+ pkg.getPackageName());
if (ps == null) {
return;
}
@@ -2327,23 +2339,25 @@ public class PermissionManagerService extends IPermissionManager.Stub {
synchronized (mLock) {
ArraySet<String> newImplicitPermissions = new ArraySet<>();
- final int N = pkg.requestedPermissions.size();
+ final int N = pkg.getRequestedPermissions().size();
for (int i = 0; i < N; i++) {
- final String permName = pkg.requestedPermissions.get(i);
+ final String permName = pkg.getRequestedPermissions().get(i);
final BasePermission bp = mSettings.getPermissionLocked(permName);
final boolean appSupportsRuntimePermissions =
- pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.M;
+ pkg.getTargetSdkVersion() >= Build.VERSION_CODES.M;
String upgradedActivityRecognitionPermission = null;
if (DEBUG_INSTALL) {
- Log.i(TAG, "Package " + pkg.packageName + " checking " + permName + ": " + bp);
+ Log.i(TAG, "Package " + pkg.getPackageName()
+ + " checking " + permName + ": " + bp);
}
if (bp == null || bp.getSourcePackageSetting() == null) {
- if (packageOfInterest == null || packageOfInterest.equals(pkg.packageName)) {
+ if (packageOfInterest == null || packageOfInterest.equals(
+ pkg.getPackageName())) {
if (DEBUG_PERMISSIONS) {
Slog.i(TAG, "Unknown permission " + permName
- + " in package " + pkg.packageName);
+ + " in package " + pkg.getPackageName());
}
}
continue;
@@ -2352,14 +2366,14 @@ public class PermissionManagerService extends IPermissionManager.Stub {
// Cache newImplicitPermissions before modifing permissionsState as for the shared
// uids the original and new state are the same object
if (!origPermissions.hasRequestedPermission(permName)
- && (pkg.implicitPermissions.contains(permName)
+ && (pkg.getImplicitPermissions().contains(permName)
|| (permName.equals(Manifest.permission.ACTIVITY_RECOGNITION)))) {
- if (pkg.implicitPermissions.contains(permName)) {
+ if (pkg.getImplicitPermissions().contains(permName)) {
// If permName is an implicit permission, try to auto-grant
newImplicitPermissions.add(permName);
if (DEBUG_PERMISSIONS) {
- Slog.i(TAG, permName + " is newly added for " + pkg.packageName);
+ Slog.i(TAG, permName + " is newly added for " + pkg.getPackageName());
}
} else {
// Special case for Activity Recognition permission. Even if AR permission
@@ -2382,7 +2396,7 @@ public class PermissionManagerService extends IPermissionManager.Stub {
if (DEBUG_PERMISSIONS) {
Slog.i(TAG, permName + " is newly added for "
- + pkg.packageName);
+ + pkg.getPackageName());
}
break;
}
@@ -2391,10 +2405,10 @@ public class PermissionManagerService extends IPermissionManager.Stub {
}
// Limit ephemeral apps to ephemeral allowed permissions.
- if (pkg.applicationInfo.isInstantApp() && !bp.isInstant()) {
+ if (pkg.isInstantApp() && !bp.isInstant()) {
if (DEBUG_PERMISSIONS) {
Log.i(TAG, "Denying non-ephemeral permission " + bp.getName()
- + " for package " + pkg.packageName);
+ + " for package " + pkg.getPackageName());
}
continue;
}
@@ -2402,7 +2416,7 @@ public class PermissionManagerService extends IPermissionManager.Stub {
if (bp.isRuntimeOnly() && !appSupportsRuntimePermissions) {
if (DEBUG_PERMISSIONS) {
Log.i(TAG, "Denying runtime-only permission " + bp.getName()
- + " for package " + pkg.packageName);
+ + " for package " + pkg.getPackageName());
}
continue;
}
@@ -2413,7 +2427,7 @@ public class PermissionManagerService extends IPermissionManager.Stub {
// Keep track of app op permissions.
if (bp.isAppOp()) {
- mSettings.addAppOpPackage(perm, pkg.packageName);
+ mSettings.addAppOpPackage(perm, pkg.getPackageName());
}
if (bp.isNormal()) {
@@ -2439,7 +2453,7 @@ public class PermissionManagerService extends IPermissionManager.Stub {
if (DEBUG_PERMISSIONS) {
Slog.i(TAG, "Considering granting permission " + perm + " to package "
- + pkg.packageName);
+ + pkg.getPackageName());
}
if (grant != GRANT_DENIED) {
@@ -2725,10 +2739,10 @@ public class PermissionManagerService extends IPermissionManager.Stub {
default: {
if (packageOfInterest == null
- || packageOfInterest.equals(pkg.packageName)) {
+ || packageOfInterest.equals(pkg.getPackageName())) {
if (DEBUG_PERMISSIONS) {
Slog.i(TAG, "Not granting permission " + perm
- + " to package " + pkg.packageName
+ + " to package " + pkg.getPackageName()
+ " because it was previously installed without");
}
}
@@ -2743,9 +2757,9 @@ public class PermissionManagerService extends IPermissionManager.Stub {
changedInstallPermission = true;
if (DEBUG_PERMISSIONS) {
Slog.i(TAG, "Un-granting permission " + perm
- + " from package " + pkg.packageName
+ + " from package " + pkg.getPackageName()
+ " (protectionLevel=" + bp.getProtectionLevel()
- + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
+ + " flags=0x" + Integer.toHexString(pkg.getFlags())
+ ")");
}
} else if (bp.isAppOp()) {
@@ -2753,11 +2767,11 @@ public class PermissionManagerService extends IPermissionManager.Stub {
// not to be granted, there is a UI for the user to decide.
if (DEBUG_PERMISSIONS
&& (packageOfInterest == null
- || packageOfInterest.equals(pkg.packageName))) {
+ || packageOfInterest.equals(pkg.getPackageName()))) {
Slog.i(TAG, "Not granting permission " + perm
- + " to package " + pkg.packageName
+ + " to package " + pkg.getPackageName()
+ " (protectionLevel=" + bp.getProtectionLevel()
- + " flags=0x" + Integer.toHexString(pkg.applicationInfo.flags)
+ + " flags=0x" + Integer.toHexString(pkg.getFlags())
+ ")");
}
}
@@ -2787,7 +2801,7 @@ public class PermissionManagerService extends IPermissionManager.Stub {
}
for (int userId : updatedUserIds) {
- notifyRuntimePermissionStateChanged(pkg.packageName, userId);
+ notifyRuntimePermissionStateChanged(pkg.getPackageName(), userId);
}
}
@@ -2803,10 +2817,10 @@ public class PermissionManagerService extends IPermissionManager.Stub {
* @return The updated value of the {@code updatedUserIds} parameter
*/
private @NonNull int[] revokePermissionsNoLongerImplicitLocked(
- @NonNull PermissionsState ps, @NonNull PackageParser.Package pkg,
+ @NonNull PermissionsState ps, @NonNull AndroidPackage pkg,
@NonNull int[] updatedUserIds) {
- String pkgName = pkg.packageName;
- boolean supportsRuntimePermissions = pkg.applicationInfo.targetSdkVersion
+ String pkgName = pkg.getPackageName();
+ boolean supportsRuntimePermissions = pkg.getTargetSdkVersion()
>= Build.VERSION_CODES.M;
int[] users = UserManagerService.getInstance().getUserIds();
@@ -2815,7 +2829,7 @@ public class PermissionManagerService extends IPermissionManager.Stub {
int userId = users[i];
for (String permission : ps.getPermissions(userId)) {
- if (!pkg.implicitPermissions.contains(permission)) {
+ if (!pkg.getImplicitPermissions().contains(permission)) {
if (!ps.hasInstallPermission(permission)) {
int flags = ps.getRuntimePermissionState(permission, userId).getFlags();
@@ -2865,9 +2879,9 @@ public class PermissionManagerService extends IPermissionManager.Stub {
*/
private void inheritPermissionStateToNewImplicitPermissionLocked(
@NonNull ArraySet<String> sourcePerms, @NonNull String newPerm,
- @NonNull PermissionsState ps, @NonNull PackageParser.Package pkg,
+ @NonNull PermissionsState ps, @NonNull AndroidPackage pkg,
@UserIdInt int userId) {
- String pkgName = pkg.packageName;
+ String pkgName = pkg.getPackageName();
boolean isGranted = false;
int flags = 0;
@@ -2914,10 +2928,10 @@ public class PermissionManagerService extends IPermissionManager.Stub {
* @return The ids of the users that are changed
*/
private @NonNull int[] checkIfLegacyStorageOpsNeedToBeUpdated(
- @NonNull PackageParser.Package pkg, boolean replace, @NonNull int[] updatedUserIds) {
- if (replace && pkg.applicationInfo.hasRequestedLegacyExternalStorage() && (
- pkg.requestedPermissions.contains(READ_EXTERNAL_STORAGE)
- || pkg.requestedPermissions.contains(WRITE_EXTERNAL_STORAGE))) {
+ @NonNull AndroidPackage pkg, boolean replace, @NonNull int[] updatedUserIds) {
+ if (replace && pkg.hasRequestedLegacyExternalStorage() && (
+ pkg.getRequestedPermissions().contains(READ_EXTERNAL_STORAGE)
+ || pkg.getRequestedPermissions().contains(WRITE_EXTERNAL_STORAGE))) {
return UserManagerService.getInstance().getUserIds();
}
@@ -2936,10 +2950,10 @@ public class PermissionManagerService extends IPermissionManager.Stub {
*/
private @NonNull int[] setInitialGrantForNewImplicitPermissionsLocked(
@NonNull PermissionsState origPs,
- @NonNull PermissionsState ps, @NonNull PackageParser.Package pkg,
+ @NonNull PermissionsState ps, @NonNull AndroidPackage pkg,
@NonNull ArraySet<String> newImplicitPermissions,
@NonNull int[] updatedUserIds) {
- String pkgName = pkg.packageName;
+ String pkgName = pkg.getPackageName();
ArrayMap<String, ArraySet<String>> newToSplitPerms = new ArrayMap<>();
final List<SplitPermissionInfoParcelable> permissionList = getSplitPermissions();
@@ -3019,17 +3033,17 @@ public class PermissionManagerService extends IPermissionManager.Stub {
SystemConfig.getInstance().getSplitPermissions());
}
- private boolean isNewPlatformPermissionForPackage(String perm, PackageParser.Package pkg) {
+ private boolean isNewPlatformPermissionForPackage(String perm, AndroidPackage pkg) {
boolean allowed = false;
final int NP = PackageParser.NEW_PERMISSIONS.length;
for (int ip=0; ip<NP; ip++) {
final PackageParser.NewPermissionInfo npi
= PackageParser.NEW_PERMISSIONS[ip];
if (npi.name.equals(perm)
- && pkg.applicationInfo.targetSdkVersion < npi.sdkVersion) {
+ && pkg.getTargetSdkVersion() < npi.sdkVersion) {
allowed = true;
Log.i(TAG, "Auto-granting " + perm + " to old pkg "
- + pkg.packageName);
+ + pkg.getPackageName());
break;
}
}
@@ -3043,29 +3057,26 @@ public class PermissionManagerService extends IPermissionManager.Stub {
*
* <p>This handles parent/child apps.
*/
- private boolean hasPrivappWhitelistEntry(String perm, PackageParser.Package pkg) {
- ArraySet<String> wlPermissions = null;
+ private boolean hasPrivappWhitelistEntry(String perm, AndroidPackage pkg) {
+ ArraySet<String> wlPermissions;
if (pkg.isVendor()) {
wlPermissions =
- SystemConfig.getInstance().getVendorPrivAppPermissions(pkg.packageName);
+ SystemConfig.getInstance().getVendorPrivAppPermissions(pkg.getPackageName());
} else if (pkg.isProduct()) {
wlPermissions =
- SystemConfig.getInstance().getProductPrivAppPermissions(pkg.packageName);
+ SystemConfig.getInstance().getProductPrivAppPermissions(pkg.getPackageName());
} else if (pkg.isSystemExt()) {
wlPermissions =
SystemConfig.getInstance().getSystemExtPrivAppPermissions(
- pkg.packageName);
+ pkg.getPackageName());
} else {
- wlPermissions = SystemConfig.getInstance().getPrivAppPermissions(pkg.packageName);
+ wlPermissions = SystemConfig.getInstance().getPrivAppPermissions(pkg.getPackageName());
}
- // Let's check if this package is whitelisted...
- boolean whitelisted = wlPermissions != null && wlPermissions.contains(perm);
- // If it's not, we'll also tail-recurse to the parent.
- return whitelisted ||
- pkg.parentPackage != null && hasPrivappWhitelistEntry(perm, pkg.parentPackage);
+
+ return wlPermissions != null && wlPermissions.contains(perm);
}
- private boolean grantSignaturePermission(String perm, PackageParser.Package pkg,
+ private boolean grantSignaturePermission(String perm, AndroidPackage pkg,
BasePermission bp, PermissionsState origPermissions) {
boolean oemPermission = bp.isOEM();
boolean vendorPrivilegedPermission = bp.isVendorPrivileged();
@@ -3073,7 +3084,7 @@ public class PermissionManagerService extends IPermissionManager.Stub {
boolean privappPermissionsDisable =
RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_DISABLE;
boolean platformPermission = PLATFORM_PACKAGE_NAME.equals(bp.getSourcePackageName());
- boolean platformPackage = PLATFORM_PACKAGE_NAME.equals(pkg.packageName);
+ boolean platformPackage = PLATFORM_PACKAGE_NAME.equals(pkg.getPackageName());
if (!privappPermissionsDisable && privilegedPermission && pkg.isPrivileged()
&& !platformPackage && platformPermission) {
if (!hasPrivappWhitelistEntry(perm, pkg)) {
@@ -3083,22 +3094,22 @@ public class PermissionManagerService extends IPermissionManager.Stub {
ArraySet<String> deniedPermissions = null;
if (pkg.isVendor()) {
deniedPermissions = SystemConfig.getInstance()
- .getVendorPrivAppDenyPermissions(pkg.packageName);
+ .getVendorPrivAppDenyPermissions(pkg.getPackageName());
} else if (pkg.isProduct()) {
deniedPermissions = SystemConfig.getInstance()
- .getProductPrivAppDenyPermissions(pkg.packageName);
+ .getProductPrivAppDenyPermissions(pkg.getPackageName());
} else if (pkg.isSystemExt()) {
deniedPermissions = SystemConfig.getInstance()
- .getSystemExtPrivAppDenyPermissions(pkg.packageName);
+ .getSystemExtPrivAppDenyPermissions(pkg.getPackageName());
} else {
deniedPermissions = SystemConfig.getInstance()
- .getPrivAppDenyPermissions(pkg.packageName);
+ .getPrivAppDenyPermissions(pkg.getPackageName());
}
final boolean permissionViolation =
deniedPermissions == null || !deniedPermissions.contains(perm);
if (permissionViolation) {
Slog.w(TAG, "Privileged permission " + perm + " for package "
- + pkg.packageName + " (" + pkg.codePath
+ + pkg.getPackageName() + " (" + pkg.getCodePath()
+ ") not in privapp-permissions whitelist");
if (RoSystemProperties.CONTROL_PRIVAPP_PERMISSIONS_ENFORCE) {
@@ -3106,7 +3117,7 @@ public class PermissionManagerService extends IPermissionManager.Stub {
mPrivappPermissionsViolations = new ArraySet<>();
}
mPrivappPermissionsViolations.add(
- pkg.packageName + " (" + pkg.codePath + "): " + perm);
+ pkg.getPackageName() + " (" + pkg.getCodePath() + "): " + perm);
}
} else {
return false;
@@ -3119,7 +3130,7 @@ public class PermissionManagerService extends IPermissionManager.Stub {
}
final String systemPackageName = mPackageManagerInt.getKnownPackageName(
PackageManagerInternal.PACKAGE_SYSTEM, UserHandle.USER_SYSTEM);
- final PackageParser.Package systemPackage =
+ final AndroidPackage systemPackage =
mPackageManagerInt.getPackage(systemPackageName);
// check if the package is allow to use this signature permission. A package is allowed to
@@ -3130,24 +3141,23 @@ public class PermissionManagerService extends IPermissionManager.Stub {
// package, and the defining package still trusts the old certificate for permissions
// - or it shares the above relationships with the system package
boolean allowed =
- pkg.mSigningDetails.hasAncestorOrSelf(
+ pkg.getSigningDetails().hasAncestorOrSelf(
bp.getSourcePackageSetting().getSigningDetails())
|| bp.getSourcePackageSetting().getSigningDetails().checkCapability(
- pkg.mSigningDetails,
+ pkg.getSigningDetails(),
PackageParser.SigningDetails.CertCapabilities.PERMISSION)
- || pkg.mSigningDetails.hasAncestorOrSelf(systemPackage.mSigningDetails)
- || systemPackage.mSigningDetails.checkCapability(
- pkg.mSigningDetails,
+ || pkg.getSigningDetails().hasAncestorOrSelf(systemPackage.getSigningDetails())
+ || systemPackage.getSigningDetails().checkCapability(
+ pkg.getSigningDetails(),
PackageParser.SigningDetails.CertCapabilities.PERMISSION);
if (!allowed && (privilegedPermission || oemPermission)) {
if (pkg.isSystem()) {
// For updated system applications, a privileged/oem permission
// is granted only if it had been defined by the original application.
if (pkg.isUpdatedSystemApp()) {
- final PackageParser.Package disabledPkg =
- mPackageManagerInt.getDisabledSystemPackage(pkg.packageName);
- final PackageSetting disabledPs =
- (disabledPkg != null) ? (PackageSetting) disabledPkg.mExtras : null;
+ final PackageSetting disabledPs = (PackageSetting) mPackageManagerInt
+ .getDisabledSystemPackage(pkg.getPackageName());
+ final AndroidPackage disabledPkg = disabledPs == null ? null : disabledPs.pkg;
if (disabledPs != null
&& disabledPs.getPermissionsState().hasInstallPermission(perm)) {
// If the original was granted this permission, we take
@@ -3172,40 +3182,10 @@ public class PermissionManagerService extends IPermissionManager.Stub {
&& canGrantOemPermission(disabledPs, perm)))) {
allowed = true;
}
- // Also if a privileged parent package on the system image or any of
- // its children requested a privileged/oem permission, the updated child
- // packages can also get the permission.
- if (pkg.parentPackage != null) {
- final PackageParser.Package disabledParentPkg = mPackageManagerInt
- .getDisabledSystemPackage(pkg.parentPackage.packageName);
- final PackageSetting disabledParentPs = (disabledParentPkg != null)
- ? (PackageSetting) disabledParentPkg.mExtras : null;
- if (disabledParentPkg != null
- && ((privilegedPermission && disabledParentPs.isPrivileged())
- || (oemPermission && disabledParentPs.isOem()))) {
- if (isPackageRequestingPermission(disabledParentPkg, perm)
- && canGrantOemPermission(disabledParentPs, perm)) {
- allowed = true;
- } else if (disabledParentPkg.childPackages != null) {
- for (PackageParser.Package disabledChildPkg
- : disabledParentPkg.childPackages) {
- final PackageSetting disabledChildPs =
- (disabledChildPkg != null)
- ? (PackageSetting) disabledChildPkg.mExtras
- : null;
- if (isPackageRequestingPermission(disabledChildPkg, perm)
- && canGrantOemPermission(
- disabledChildPs, perm)) {
- allowed = true;
- break;
- }
- }
- }
- }
- }
}
} else {
- final PackageSetting ps = (PackageSetting) pkg.mExtras;
+ final PackageSetting ps = (PackageSetting) mPackageManagerInt.getPackageSetting(
+ pkg.getPackageName());
allowed = (privilegedPermission && pkg.isPrivileged())
|| (oemPermission && pkg.isOem()
&& canGrantOemPermission(ps, perm));
@@ -3216,7 +3196,8 @@ public class PermissionManagerService extends IPermissionManager.Stub {
if (allowed && privilegedPermission &&
!vendorPrivilegedPermission && pkg.isVendor()) {
Slog.w(TAG, "Permission " + perm + " cannot be granted to privileged vendor apk "
- + pkg.packageName + " because it isn't a 'vendorPrivileged' permission.");
+ + pkg.getPackageName()
+ + " because it isn't a 'vendorPrivileged' permission.");
allowed = false;
}
}
@@ -3224,7 +3205,7 @@ public class PermissionManagerService extends IPermissionManager.Stub {
if (!allowed) {
if (!allowed
&& bp.isPre23()
- && pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M) {
+ && pkg.getTargetSdkVersion() < Build.VERSION_CODES.M) {
// If this was a previously normal/dangerous permission that got moved
// to a system permission as part of the runtime permission redesign, then
// we still want to blindly grant it to old apps.
@@ -3234,9 +3215,9 @@ public class PermissionManagerService extends IPermissionManager.Stub {
// need a separate flag anymore. Hence we need to check which
// permissions are needed by the permission controller
if (!allowed && bp.isInstaller()
- && (pkg.packageName.equals(mPackageManagerInt.getKnownPackageName(
+ && (pkg.getPackageName().equals(mPackageManagerInt.getKnownPackageName(
PackageManagerInternal.PACKAGE_INSTALLER, UserHandle.USER_SYSTEM))
- || pkg.packageName.equals(mPackageManagerInt.getKnownPackageName(
+ || pkg.getPackageName().equals(mPackageManagerInt.getKnownPackageName(
PackageManagerInternal.PACKAGE_PERMISSION_CONTROLLER,
UserHandle.USER_SYSTEM)))) {
// If this permission is to be granted to the system installer and
@@ -3244,7 +3225,7 @@ public class PermissionManagerService extends IPermissionManager.Stub {
allowed = true;
}
if (!allowed && bp.isVerifier()
- && pkg.packageName.equals(mPackageManagerInt.getKnownPackageName(
+ && pkg.getPackageName().equals(mPackageManagerInt.getKnownPackageName(
PackageManagerInternal.PACKAGE_VERIFIER, UserHandle.USER_SYSTEM))) {
// If this permission is to be granted to the system verifier and
// this app is a verifier, then it gets the permission.
@@ -3261,41 +3242,41 @@ public class PermissionManagerService extends IPermissionManager.Stub {
allowed = origPermissions.hasInstallPermission(perm);
}
if (!allowed && bp.isSetup()
- && pkg.packageName.equals(mPackageManagerInt.getKnownPackageName(
+ && pkg.getPackageName().equals(mPackageManagerInt.getKnownPackageName(
PackageManagerInternal.PACKAGE_SETUP_WIZARD, UserHandle.USER_SYSTEM))) {
// If this permission is to be granted to the system setup wizard and
// this app is a setup wizard, then it gets the permission.
allowed = true;
}
if (!allowed && bp.isSystemTextClassifier()
- && pkg.packageName.equals(mPackageManagerInt.getKnownPackageName(
+ && pkg.getPackageName().equals(mPackageManagerInt.getKnownPackageName(
PackageManagerInternal.PACKAGE_SYSTEM_TEXT_CLASSIFIER,
UserHandle.USER_SYSTEM))) {
// Special permissions for the system default text classifier.
allowed = true;
}
if (!allowed && bp.isConfigurator()
- && pkg.packageName.equals(mPackageManagerInt.getKnownPackageName(
+ && pkg.getPackageName().equals(mPackageManagerInt.getKnownPackageName(
PackageManagerInternal.PACKAGE_CONFIGURATOR,
UserHandle.USER_SYSTEM))) {
// Special permissions for the device configurator.
allowed = true;
}
if (!allowed && bp.isWellbeing()
- && pkg.packageName.equals(mPackageManagerInt.getKnownPackageName(
+ && pkg.getPackageName().equals(mPackageManagerInt.getKnownPackageName(
PackageManagerInternal.PACKAGE_WELLBEING, UserHandle.USER_SYSTEM))) {
// Special permission granted only to the OEM specified wellbeing app
allowed = true;
}
if (!allowed && bp.isDocumenter()
- && pkg.packageName.equals(mPackageManagerInt.getKnownPackageName(
+ && pkg.getPackageName().equals(mPackageManagerInt.getKnownPackageName(
PackageManagerInternal.PACKAGE_DOCUMENTER, UserHandle.USER_SYSTEM))) {
// If this permission is to be granted to the documenter and
// this app is the documenter, then it gets the permission.
allowed = true;
}
if (!allowed && bp.isIncidentReportApprover()
- && pkg.packageName.equals(mPackageManagerInt.getKnownPackageName(
+ && pkg.getPackageName().equals(mPackageManagerInt.getKnownPackageName(
PackageManagerInternal.PACKAGE_INCIDENT_REPORT_APPROVER,
UserHandle.USER_SYSTEM))) {
// If this permission is to be granted to the incident report approver and
@@ -3303,7 +3284,7 @@ public class PermissionManagerService extends IPermissionManager.Stub {
allowed = true;
}
if (!allowed && bp.isAppPredictor()
- && pkg.packageName.equals(mPackageManagerInt.getKnownPackageName(
+ && pkg.getPackageName().equals(mPackageManagerInt.getKnownPackageName(
PackageManagerInternal.PACKAGE_APP_PREDICTOR, UserHandle.USER_SYSTEM))) {
// Special permissions for the system app predictor.
allowed = true;
@@ -3326,26 +3307,27 @@ public class PermissionManagerService extends IPermissionManager.Stub {
return Boolean.TRUE == granted;
}
- private boolean isPermissionsReviewRequired(@NonNull PackageParser.Package pkg,
+ private boolean isPermissionsReviewRequired(@NonNull AndroidPackage pkg,
@UserIdInt int userId) {
// Permission review applies only to apps not supporting the new permission model.
- if (pkg.applicationInfo.targetSdkVersion >= Build.VERSION_CODES.M) {
+ if (pkg.getTargetSdkVersion() >= Build.VERSION_CODES.M) {
return false;
}
// Legacy apps have the permission and get user consent on launch.
- if (pkg.mExtras == null) {
+ final PackageSetting ps = (PackageSetting) mPackageManagerInt.getPackageSetting(
+ pkg.getPackageName());
+ if (ps == null) {
return false;
}
- final PackageSetting ps = (PackageSetting) pkg.mExtras;
final PermissionsState permissionsState = ps.getPermissionsState();
return permissionsState.isPermissionReviewRequired(userId);
}
- private boolean isPackageRequestingPermission(PackageParser.Package pkg, String permission) {
- final int permCount = pkg.requestedPermissions.size();
+ private boolean isPackageRequestingPermission(AndroidPackage pkg, String permission) {
+ final int permCount = pkg.getRequestedPermissions().size();
for (int j = 0; j < permCount; j++) {
- String requestedPermission = pkg.requestedPermissions.get(j);
+ String requestedPermission = pkg.getRequestedPermissions().get(j);
if (permission.equals(requestedPermission)) {
return true;
}
@@ -3353,41 +3335,7 @@ public class PermissionManagerService extends IPermissionManager.Stub {
return false;
}
- @GuardedBy("mLock")
- private void grantRuntimePermissionsGrantedToDisabledPackageLocked(
- PackageParser.Package pkg, int callingUid, PermissionCallback callback) {
- if (pkg.parentPackage == null) {
- return;
- }
- if (pkg.requestedPermissions == null) {
- return;
- }
- final PackageParser.Package disabledPkg =
- mPackageManagerInt.getDisabledSystemPackage(pkg.parentPackage.packageName);
- if (disabledPkg == null || disabledPkg.mExtras == null) {
- return;
- }
- final PackageSetting disabledPs = (PackageSetting) disabledPkg.mExtras;
- if (!disabledPs.isPrivileged() || disabledPs.hasChildPackages()) {
- return;
- }
- final int permCount = pkg.requestedPermissions.size();
- for (int i = 0; i < permCount; i++) {
- String permission = pkg.requestedPermissions.get(i);
- BasePermission bp = mSettings.getPermissionLocked(permission);
- if (bp == null || !(bp.isRuntime() || bp.isDevelopment())) {
- continue;
- }
- for (int userId : mUserManagerInt.getUserIds()) {
- if (disabledPs.getPermissionsState().hasRuntimePermission(permission, userId)) {
- grantRuntimePermissionInternal(
- permission, pkg.packageName, false, callingUid, userId, callback);
- }
- }
- }
- }
-
- private void grantRequestedRuntimePermissions(PackageParser.Package pkg, int[] userIds,
+ private void grantRequestedRuntimePermissions(AndroidPackage pkg, int[] userIds,
String[] grantedPermissions, int callingUid, PermissionCallback callback) {
for (int userId : userIds) {
grantRequestedRuntimePermissionsForUser(pkg, userId, grantedPermissions, callingUid,
@@ -3395,9 +3343,10 @@ public class PermissionManagerService extends IPermissionManager.Stub {
}
}
- private void grantRequestedRuntimePermissionsForUser(PackageParser.Package pkg, int userId,
+ private void grantRequestedRuntimePermissionsForUser(AndroidPackage pkg, int userId,
String[] grantedPermissions, int callingUid, PermissionCallback callback) {
- PackageSetting ps = (PackageSetting) pkg.mExtras;
+ PackageSetting ps = (PackageSetting) mPackageManagerInt.getPackageSetting(
+ pkg.getPackageName());
if (ps == null) {
return;
}
@@ -3407,12 +3356,12 @@ public class PermissionManagerService extends IPermissionManager.Stub {
final int immutableFlags = PackageManager.FLAG_PERMISSION_SYSTEM_FIXED
| PackageManager.FLAG_PERMISSION_POLICY_FIXED;
- final boolean supportsRuntimePermissions = pkg.applicationInfo.targetSdkVersion
+ final boolean supportsRuntimePermissions = pkg.getTargetSdkVersion()
>= Build.VERSION_CODES.M;
- final boolean instantApp = mPackageManagerInt.isInstantApp(pkg.packageName, userId);
+ final boolean instantApp = mPackageManagerInt.isInstantApp(pkg.getPackageName(), userId);
- for (String permission : pkg.requestedPermissions) {
+ for (String permission : pkg.getRequestedPermissions()) {
final BasePermission bp;
synchronized (mLock) {
bp = mSettings.getPermissionLocked(permission);
@@ -3426,14 +3375,14 @@ public class PermissionManagerService extends IPermissionManager.Stub {
if (supportsRuntimePermissions) {
// Installer cannot change immutable permissions.
if ((flags & immutableFlags) == 0) {
- grantRuntimePermissionInternal(permission, pkg.packageName, false,
+ grantRuntimePermissionInternal(permission, pkg.getPackageName(), false,
callingUid, userId, callback);
}
} else {
// In permission review mode we clear the review flag when we
// are asked to install the app with all permissions granted.
if ((flags & PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED) != 0) {
- updatePermissionFlagsInternal(permission, pkg.packageName,
+ updatePermissionFlagsInternal(permission, pkg.getPackageName(),
PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED, 0, callingUid,
userId, false, callback);
}
@@ -3442,11 +3391,11 @@ public class PermissionManagerService extends IPermissionManager.Stub {
}
}
- private void setWhitelistedRestrictedPermissionsForUser(@NonNull PackageParser.Package pkg,
+ private void setWhitelistedRestrictedPermissionsForUser(@NonNull AndroidPackage pkg,
@UserIdInt int userId, @Nullable List<String> permissions, int callingUid,
@PermissionWhitelistFlags int whitelistFlags, PermissionCallback callback) {
final PermissionsState permissionsState =
- PackageManagerServiceUtils.getPermissionsState(pkg);
+ PackageManagerServiceUtils.getPermissionsState(mPackageManagerInt, pkg);
if (permissionsState == null) {
return;
}
@@ -3454,9 +3403,9 @@ public class PermissionManagerService extends IPermissionManager.Stub {
ArraySet<String> oldGrantedRestrictedPermissions = null;
boolean updatePermissions = false;
- final int permissionCount = pkg.requestedPermissions.size();
+ final int permissionCount = pkg.getRequestedPermissions().size();
for (int i = 0; i < permissionCount; i++) {
- final String permissionName = pkg.requestedPermissions.get(i);
+ final String permissionName = pkg.getRequestedPermissions().get(i);
final BasePermission bp = mSettings.getPermissionLocked(permissionName);
@@ -3532,19 +3481,19 @@ public class PermissionManagerService extends IPermissionManager.Stub {
// If we are whitelisting an app that does not support runtime permissions
// we need to make sure it goes through the permission review UI at launch.
- if (pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M
+ if (pkg.getTargetSdkVersion() < Build.VERSION_CODES.M
&& !wasWhitelisted && isWhitelisted) {
mask |= PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
newFlags |= PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED;
}
- updatePermissionFlagsInternal(permissionName, pkg.packageName, mask, newFlags,
+ updatePermissionFlagsInternal(permissionName, pkg.getPackageName(), mask, newFlags,
callingUid, userId, false, null /*callback*/);
}
if (updatePermissions) {
// Update permission of this app to take into account the new whitelist state.
- restorePermissionState(pkg, false, pkg.packageName, callback);
+ restorePermissionState(pkg, false, pkg.getPackageName(), callback);
// If this resulted in losing a permission we need to kill the app.
if (oldGrantedRestrictedPermissions != null) {
@@ -3553,9 +3502,9 @@ public class PermissionManagerService extends IPermissionManager.Stub {
final String permission = oldGrantedRestrictedPermissions.valueAt(i);
// Sometimes we create a new permission state instance during update.
final PermissionsState newPermissionsState =
- PackageManagerServiceUtils.getPermissionsState(pkg);
+ PackageManagerServiceUtils.getPermissionsState(mPackageManagerInt, pkg);
if (!newPermissionsState.hasPermission(permission, userId)) {
- callback.onPermissionRevoked(pkg.applicationInfo.uid, userId);
+ callback.onPermissionRevoked(pkg.getUid(), userId);
break;
}
}
@@ -3568,17 +3517,17 @@ public class PermissionManagerService extends IPermissionManager.Stub {
SharedUserSetting suSetting, int[] allUserIds) {
// Collect all used permissions in the UID
final ArraySet<String> usedPermissions = new ArraySet<>();
- final List<PackageParser.Package> pkgList = suSetting.getPackages();
+ final List<AndroidPackage> pkgList = suSetting.getPackages();
if (pkgList == null || pkgList.size() == 0) {
return EmptyArray.INT;
}
- for (PackageParser.Package pkg : pkgList) {
- if (pkg.requestedPermissions == null) {
+ for (AndroidPackage pkg : pkgList) {
+ if (pkg.getRequestedPermissions() == null) {
continue;
}
- final int requestedPermCount = pkg.requestedPermissions.size();
+ final int requestedPermCount = pkg.getRequestedPermissions().size();
for (int j = 0; j < requestedPermCount; j++) {
- String permission = pkg.requestedPermissions.get(j);
+ String permission = pkg.getRequestedPermissions().get(j);
BasePermission bp = mSettings.getPermissionLocked(permission);
if (bp != null) {
usedPermissions.add(permission);
@@ -3640,18 +3589,12 @@ public class PermissionManagerService extends IPermissionManager.Stub {
* @param allPackages All currently known packages
* @param callback Callback to call after permission changes
*/
- private void updatePermissions(@NonNull String packageName, @Nullable PackageParser.Package pkg,
+ private void updatePermissions(@NonNull String packageName, @Nullable AndroidPackage pkg,
@NonNull PermissionCallback callback) {
final int flags =
(pkg != null ? UPDATE_PERMISSIONS_ALL | UPDATE_PERMISSIONS_REPLACE_PKG : 0);
updatePermissions(
packageName, pkg, getVolumeUuidForPackage(pkg), flags, callback);
- if (pkg != null && pkg.childPackages != null) {
- for (PackageParser.Package childPkg : pkg.childPackages) {
- updatePermissions(childPkg.packageName, childPkg,
- getVolumeUuidForPackage(childPkg), flags, callback);
- }
- }
}
/**
@@ -3687,10 +3630,9 @@ public class PermissionManagerService extends IPermissionManager.Stub {
// Only system declares background permissions, hence mapping does never change.
mBackgroundPermissions = new ArrayMap<>();
for (BasePermission bp : mSettings.getAllPermissionsLocked()) {
- if (bp.perm != null && bp.perm.info != null
- && bp.perm.info.backgroundPermission != null) {
+ if (bp.perm != null && bp.perm.backgroundPermission != null) {
String fgPerm = bp.name;
- String bgPerm = bp.perm.info.backgroundPermission;
+ String bgPerm = bp.perm.backgroundPermission;
List<String> fgPerms = mBackgroundPermissions.get(bgPerm);
if (fgPerms == null) {
@@ -3751,7 +3693,7 @@ public class PermissionManagerService extends IPermissionManager.Stub {
* @param callback Callback to call after permission changes
*/
private void updatePermissions(final @Nullable String changingPkgName,
- final @Nullable PackageParser.Package changingPkg,
+ final @Nullable AndroidPackage changingPkg,
final @Nullable String replaceVolumeUuid,
@UpdatePermissionFlags int flags,
final @Nullable PermissionCallback callback) {
@@ -3784,7 +3726,7 @@ public class PermissionManagerService extends IPermissionManager.Stub {
// Now update the permissions for all packages.
if ((flags & UPDATE_PERMISSIONS_ALL) != 0) {
final boolean replaceAll = ((flags & UPDATE_PERMISSIONS_REPLACE_ALL) != 0);
- mPackageManagerInt.forEachPackage((Package pkg) -> {
+ mPackageManagerInt.forEachPackage((AndroidPackage pkg) -> {
if (pkg == changingPkg) {
return;
}
@@ -3823,7 +3765,7 @@ public class PermissionManagerService extends IPermissionManager.Stub {
* @return {@code true} if a permission source package might have changed
*/
private boolean updatePermissionSourcePackage(@Nullable String packageName,
- @Nullable PackageParser.Package pkg,
+ @Nullable AndroidPackage pkg,
final @Nullable PermissionCallback callback) {
boolean changed = false;
@@ -3846,8 +3788,8 @@ public class PermissionManagerService extends IPermissionManager.Stub {
for (int userIdNum = 0; userIdNum < numUserIds; userIdNum++) {
final int userId = userIds[userIdNum];
- mPackageManagerInt.forEachPackage((Package p) -> {
- final String pName = p.packageName;
+ mPackageManagerInt.forEachPackage((AndroidPackage p) -> {
+ final String pName = p.getPackageName();
final ApplicationInfo appInfo =
mPackageManagerInt.getApplicationInfo(pName, 0,
Process.SYSTEM_UID, UserHandle.USER_SYSTEM);
@@ -3892,11 +3834,13 @@ public class PermissionManagerService extends IPermissionManager.Stub {
}
if (needsUpdate != null) {
for (final BasePermission bp : needsUpdate) {
- final PackageParser.Package sourcePkg =
+ final AndroidPackage sourcePkg =
mPackageManagerInt.getPackage(bp.getSourcePackageName());
+ final PackageSetting sourcePs =
+ (PackageSetting) mPackageManagerInt.getPackageSetting(
+ bp.getSourcePackageName());
synchronized (mLock) {
- if (sourcePkg != null && sourcePkg.mExtras != null) {
- final PackageSetting sourcePs = (PackageSetting) sourcePkg.mExtras;
+ if (sourcePkg != null && sourcePs != null) {
if (bp.getSourcePackageSetting() == null) {
bp.setSourcePackageSetting(sourcePs);
}
@@ -3929,7 +3873,7 @@ public class PermissionManagerService extends IPermissionManager.Stub {
* @return {@code true} if a permission tree ownership might have changed
*/
private boolean updatePermissionTreeSourcePackage(@Nullable String packageName,
- @Nullable PackageParser.Package pkg) {
+ @Nullable AndroidPackage pkg) {
boolean changed = false;
Set<BasePermission> needsUpdate = null;
@@ -3955,11 +3899,13 @@ public class PermissionManagerService extends IPermissionManager.Stub {
}
if (needsUpdate != null) {
for (final BasePermission bp : needsUpdate) {
- final PackageParser.Package sourcePkg =
+ final AndroidPackage sourcePkg =
mPackageManagerInt.getPackage(bp.getSourcePackageName());
+ final PackageSetting sourcePs =
+ (PackageSetting) mPackageManagerInt.getPackageSetting(
+ bp.getSourcePackageName());
synchronized (mLock) {
- if (sourcePkg != null && sourcePkg.mExtras != null) {
- final PackageSetting sourcePs = (PackageSetting) sourcePkg.mExtras;
+ if (sourcePkg != null && sourcePs != null) {
if (bp.getSourcePackageSetting() == null) {
bp.setSourcePackageSetting(sourcePs);
}
@@ -4082,24 +4028,28 @@ public class PermissionManagerService extends IPermissionManager.Stub {
}
}
- private static String getVolumeUuidForPackage(PackageParser.Package pkg) {
+ private static String getVolumeUuidForPackage(AndroidPackage pkg) {
if (pkg == null) {
return StorageManager.UUID_PRIVATE_INTERNAL;
}
if (pkg.isExternal()) {
- if (TextUtils.isEmpty(pkg.volumeUuid)) {
+ if (TextUtils.isEmpty(pkg.getVolumeUuid())) {
return StorageManager.UUID_PRIMARY_PHYSICAL;
} else {
- return pkg.volumeUuid;
+ return pkg.getVolumeUuid();
}
} else {
return StorageManager.UUID_PRIVATE_INTERNAL;
}
}
- private static boolean hasPermission(PackageParser.Package pkgInfo, String permName) {
- for (int i=pkgInfo.permissions.size()-1; i>=0; i--) {
- if (pkgInfo.permissions.get(i).info.name.equals(permName)) {
+ private static boolean hasPermission(AndroidPackage pkg, String permName) {
+ if (pkg.getPermissions() == null) {
+ return false;
+ }
+
+ for (int i = pkg.getPermissions().size() - 1; i >= 0; i--) {
+ if (pkg.getPermissions().get(i).getName().equals(permName)) {
return true;
}
}
@@ -4138,37 +4088,39 @@ public class PermissionManagerService extends IPermissionManager.Stub {
PermissionManagerService.this.systemReady();
}
@Override
- public boolean isPermissionsReviewRequired(@NonNull Package pkg, @UserIdInt int userId) {
+ public boolean isPermissionsReviewRequired(@NonNull AndroidPackage pkg,
+ @UserIdInt int userId) {
return PermissionManagerService.this.isPermissionsReviewRequired(pkg, userId);
}
+
@Override
public void revokeRuntimePermissionsIfGroupChanged(
- @NonNull PackageParser.Package newPackage,
- @NonNull PackageParser.Package oldPackage,
+ @NonNull AndroidPackage newPackage,
+ @NonNull AndroidPackage oldPackage,
@NonNull ArrayList<String> allPackageNames) {
PermissionManagerService.this.revokeRuntimePermissionsIfGroupChanged(newPackage,
oldPackage, allPackageNames, mDefaultPermissionCallback);
}
@Override
- public void addAllPermissions(Package pkg, boolean chatty) {
+ public void addAllPermissions(AndroidPackage pkg, boolean chatty) {
PermissionManagerService.this.addAllPermissions(pkg, chatty);
}
@Override
- public void addAllPermissionGroups(Package pkg, boolean chatty) {
+ public void addAllPermissionGroups(AndroidPackage pkg, boolean chatty) {
PermissionManagerService.this.addAllPermissionGroups(pkg, chatty);
}
@Override
- public void removeAllPermissions(Package pkg, boolean chatty) {
+ public void removeAllPermissions(AndroidPackage pkg, boolean chatty) {
PermissionManagerService.this.removeAllPermissions(pkg, chatty);
}
@Override
- public void grantRequestedRuntimePermissions(PackageParser.Package pkg, int[] userIds,
+ public void grantRequestedRuntimePermissions(AndroidPackage pkg, int[] userIds,
String[] grantedPermissions, int callingUid) {
PermissionManagerService.this.grantRequestedRuntimePermissions(
pkg, userIds, grantedPermissions, callingUid, mDefaultPermissionCallback);
}
@Override
- public void setWhitelistedRestrictedPermissions(@NonNull PackageParser.Package pkg,
+ public void setWhitelistedRestrictedPermissions(@NonNull AndroidPackage pkg,
@NonNull int[] userIds, @Nullable List<String> permissions, int callingUid,
@PackageManager.PermissionWhitelistFlags int flags) {
for (int userId : userIds) {
@@ -4183,13 +4135,7 @@ public class PermissionManagerService extends IPermissionManager.Stub {
packageName, permissions, flags, userId);
}
@Override
- public void grantRuntimePermissionsGrantedToDisabledPackage(PackageParser.Package pkg,
- int callingUid) {
- PermissionManagerService.this.grantRuntimePermissionsGrantedToDisabledPackageLocked(
- pkg, callingUid, mDefaultPermissionCallback);
- }
- @Override
- public void updatePermissions(@NonNull String packageName, @Nullable Package pkg) {
+ public void updatePermissions(@NonNull String packageName, @Nullable AndroidPackage pkg) {
PermissionManagerService.this
.updatePermissions(packageName, pkg, mDefaultPermissionCallback);
}
@@ -4199,13 +4145,13 @@ public class PermissionManagerService extends IPermissionManager.Stub {
.updateAllPermissions(volumeUuid, sdkUpdated, mDefaultPermissionCallback);
}
@Override
- public void resetRuntimePermissions(Package pkg, int userId) {
+ public void resetRuntimePermissions(AndroidPackage pkg, int userId) {
PermissionManagerService.this.resetRuntimePermissionsInternal(pkg, userId);
}
@Override
public void resetAllRuntimePermissions(final int userId) {
mPackageManagerInt.forEachPackage(
- (PackageParser.Package pkg) -> resetRuntimePermissionsInternal(pkg, userId));
+ (AndroidPackage pkg) -> resetRuntimePermissionsInternal(pkg, userId));
}
@Override
public String[] getAppOpPermissionPackages(String permName, int callingUid) {
@@ -4251,9 +4197,9 @@ public class PermissionManagerService extends IPermissionManager.Stub {
for (int i = 0; i < numTotalPermissions; i++) {
BasePermission bp = mSettings.mPermissions.valueAt(i);
- if (bp.perm != null && bp.perm.info != null
- && bp.protectionLevel == protectionLevel) {
- matchingPermissions.add(bp.perm.info);
+ if (bp.perm != null && bp.protectionLevel == protectionLevel) {
+ matchingPermissions.add(
+ PackageInfoUtils.generatePermissionInfo(bp.perm, 0));
}
}
}
diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceInternal.java b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceInternal.java
index 8f22f9245a53..752c2dc15d52 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionManagerServiceInternal.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionManagerServiceInternal.java
@@ -21,8 +21,8 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UserIdInt;
import android.content.pm.PackageManager;
-import android.content.pm.PackageParser;
import android.content.pm.PermissionInfo;
+import android.content.pm.parsing.AndroidPackage;
import android.permission.PermissionManagerInternal;
import java.util.ArrayList;
@@ -173,16 +173,14 @@ public abstract class PermissionManagerServiceInternal extends PermissionManager
public abstract void systemReady();
- public abstract boolean isPermissionsReviewRequired(@NonNull PackageParser.Package pkg,
+ public abstract boolean isPermissionsReviewRequired(@NonNull AndroidPackage pkg,
@UserIdInt int userId);
- public abstract void grantRuntimePermissionsGrantedToDisabledPackage(
- @NonNull PackageParser.Package pkg, int callingUid);
public abstract void grantRequestedRuntimePermissions(
- @NonNull PackageParser.Package pkg, @NonNull int[] userIds,
+ @NonNull AndroidPackage pkg, @NonNull int[] userIds,
@NonNull String[] grantedPermissions, int callingUid);
public abstract void setWhitelistedRestrictedPermissions(
- @NonNull PackageParser.Package pkg, @NonNull int[] userIds,
+ @NonNull AndroidPackage pkg, @NonNull int[] userIds,
@NonNull List<String> permissions, int callingUid,
@PackageManager.PermissionWhitelistFlags int whitelistFlags);
/** Sets the whitelisted, restricted permissions for the given package. */
@@ -204,7 +202,7 @@ public abstract class PermissionManagerServiceInternal extends PermissionManager
* @param callback Callback to call after permission changes
*/
public abstract void updatePermissions(@NonNull String packageName,
- @Nullable PackageParser.Package pkg);
+ @Nullable AndroidPackage pkg);
/**
* Update all permissions for all apps.
@@ -224,7 +222,7 @@ public abstract class PermissionManagerServiceInternal extends PermissionManager
* Resets any user permission state changes (eg. permissions and flags) of all
* packages installed for the given user.
*
- * @see #resetRuntimePermissions(android.content.pm.PackageParser.Package, int)
+ * @see #resetRuntimePermissions(AndroidPackage, int)
*/
public abstract void resetAllRuntimePermissions(@UserIdInt int userId);
@@ -232,7 +230,7 @@ public abstract class PermissionManagerServiceInternal extends PermissionManager
* Resets any user permission state changes (eg. permissions and flags) of the
* specified package for the given user.
*/
- public abstract void resetRuntimePermissions(@NonNull PackageParser.Package pkg,
+ public abstract void resetRuntimePermissions(@NonNull AndroidPackage pkg,
@UserIdInt int userId);
/**
@@ -245,8 +243,8 @@ public abstract class PermissionManagerServiceInternal extends PermissionManager
* @param allPackageNames All packages
*/
public abstract void revokeRuntimePermissionsIfGroupChanged(
- @NonNull PackageParser.Package newPackage,
- @NonNull PackageParser.Package oldPackage,
+ @NonNull AndroidPackage newPackage,
+ @NonNull AndroidPackage oldPackage,
@NonNull ArrayList<String> allPackageNames);
/**
@@ -255,9 +253,9 @@ public abstract class PermissionManagerServiceInternal extends PermissionManager
* NOTE: argument {@code groupTEMP} is temporary until mPermissionGroups is moved to
* the permission settings.
*/
- public abstract void addAllPermissions(@NonNull PackageParser.Package pkg, boolean chatty);
- public abstract void addAllPermissionGroups(@NonNull PackageParser.Package pkg, boolean chatty);
- public abstract void removeAllPermissions(@NonNull PackageParser.Package pkg, boolean chatty);
+ public abstract void addAllPermissions(@NonNull AndroidPackage pkg, boolean chatty);
+ public abstract void addAllPermissionGroups(@NonNull AndroidPackage pkg, boolean chatty);
+ public abstract void removeAllPermissions(@NonNull AndroidPackage pkg, boolean chatty);
/** Retrieve the packages that have requested the given app op permission */
public abstract @Nullable String[] getAppOpPermissionPackages(
diff --git a/services/core/java/com/android/server/pm/permission/PermissionSettings.java b/services/core/java/com/android/server/pm/permission/PermissionSettings.java
index 3d8cf2ddc2cc..254b720c57a0 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionSettings.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionSettings.java
@@ -18,7 +18,7 @@ package com.android.server.pm.permission;
import android.annotation.NonNull;
import android.annotation.Nullable;
-import android.content.pm.PackageParser;
+import android.content.pm.parsing.ComponentParseUtils;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.Log;
@@ -65,8 +65,8 @@ public class PermissionSettings {
* name to permission group object.
*/
@GuardedBy("mLock")
- final ArrayMap<String, PackageParser.PermissionGroup> mPermissionGroups =
- new ArrayMap<String, PackageParser.PermissionGroup>();
+ final ArrayMap<String, ComponentParseUtils.ParsedPermissionGroup> mPermissionGroups =
+ new ArrayMap<>();
/**
* Set of packages that request a particular app op. The mapping is from permission
diff --git a/services/core/java/com/android/server/pm/permission/PermissionsState.java b/services/core/java/com/android/server/pm/permission/PermissionsState.java
index 505a0e22eac4..a78f5c4202f0 100644
--- a/services/core/java/com/android/server/pm/permission/PermissionsState.java
+++ b/services/core/java/com/android/server/pm/permission/PermissionsState.java
@@ -23,6 +23,7 @@ import android.util.ArraySet;
import android.util.SparseArray;
import android.util.SparseBooleanArray;
+import com.android.internal.annotations.GuardedBy;
import com.android.internal.util.ArrayUtils;
import java.util.ArrayList;
@@ -30,7 +31,6 @@ import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Set;
-import com.android.internal.annotations.GuardedBy;
/**
* This class encapsulates the permissions for a package or a shared user.
diff --git a/services/core/java/com/android/server/policy/PermissionPolicyService.java b/services/core/java/com/android/server/policy/PermissionPolicyService.java
index 1bf319dfcb69..a98de8909d85 100644
--- a/services/core/java/com/android/server/policy/PermissionPolicyService.java
+++ b/services/core/java/com/android/server/policy/PermissionPolicyService.java
@@ -38,8 +38,8 @@ import android.content.pm.PackageManager;
import android.content.pm.PackageManager.NameNotFoundException;
import android.content.pm.PackageManagerInternal;
import android.content.pm.PackageManagerInternal.PackageListObserver;
-import android.content.pm.PackageParser;
import android.content.pm.PermissionInfo;
+import android.content.pm.parsing.AndroidPackage;
import android.os.Build;
import android.os.Process;
import android.os.RemoteException;
@@ -159,7 +159,8 @@ public final class PermissionPolicyService extends SystemService {
appOpsService.startWatchingMode(getSwitchOp(perm.name), null, appOpsListener);
SoftRestrictedPermissionPolicy policy =
- SoftRestrictedPermissionPolicy.forPermission(null, null, null,
+ SoftRestrictedPermissionPolicy.forPermission(null,
+ (AndroidPackage) null, null,
perm.name);
if (policy.resolveAppOp() != OP_NONE) {
appOpsService.startWatchingMode(policy.resolveAppOp(), null,
@@ -358,10 +359,10 @@ public final class PermissionPolicyService extends SystemService {
pkg.sharedUserId, userId);
if (sharedPkgNames != null) {
for (String sharedPkgName : sharedPkgNames) {
- final PackageParser.Package sharedPkg = packageManagerInternal
+ final AndroidPackage sharedPkg = packageManagerInternal
.getPackage(sharedPkgName);
if (sharedPkg != null) {
- synchroniser.addPackage(sharedPkg.packageName);
+ synchroniser.addPackage(sharedPkg.getPackageName());
}
}
}
@@ -378,7 +379,8 @@ public final class PermissionPolicyService extends SystemService {
PackageManagerInternal.class);
final PermissionToOpSynchroniser synchronizer = new PermissionToOpSynchroniser(
getUserContext(getContext(), UserHandle.of(userId)));
- packageManagerInternal.forEachPackage((pkg) -> synchronizer.addPackage(pkg.packageName));
+ packageManagerInternal.forEachPackage(
+ (pkg) -> synchronizer.addPackage(pkg.getPackageName()));
synchronizer.syncPackages();
}
diff --git a/services/core/java/com/android/server/policy/SoftRestrictedPermissionPolicy.java b/services/core/java/com/android/server/policy/SoftRestrictedPermissionPolicy.java
index c1a6dbd8ae14..34c925826502 100644
--- a/services/core/java/com/android/server/policy/SoftRestrictedPermissionPolicy.java
+++ b/services/core/java/com/android/server/policy/SoftRestrictedPermissionPolicy.java
@@ -36,6 +36,7 @@ import android.app.AppOpsManager;
import android.content.Context;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
+import android.content.pm.parsing.AndroidPackage;
import android.os.Build;
import android.os.UserHandle;
@@ -251,6 +252,87 @@ public abstract class SoftRestrictedPermissionPolicy {
}
/**
+ * Get the policy for a soft restricted permission.
+ *
+ * @param context A context to use
+ * @param pkg The application the permission belongs to. Can be {@code null}, but then
+ * only {@link #resolveAppOp} will work.
+ * @param user The user the app belongs to. Can be {@code null}, but then only
+ * {@link #resolveAppOp} will work.
+ * @param permission The name of the permission
+ *
+ * @return The policy for this permission
+ */
+ public static @NonNull SoftRestrictedPermissionPolicy forPermission(@NonNull Context context,
+ @Nullable AndroidPackage pkg, @Nullable UserHandle user,
+ @NonNull String permission) {
+ switch (permission) {
+ // Storage uses a special app op to decide the mount state and supports soft restriction
+ // where the restricted state allows the permission but only for accessing the medial
+ // collections.
+ case READ_EXTERNAL_STORAGE:
+ case WRITE_EXTERNAL_STORAGE: {
+ final int flags;
+ final boolean applyRestriction;
+ final boolean isWhiteListed;
+ final boolean hasRequestedLegacyExternalStorage;
+ final int targetSDK;
+
+ if (pkg != null) {
+ flags = context.getPackageManager().getPermissionFlags(permission,
+ pkg.getPackageName(), user);
+ applyRestriction = (flags & FLAG_PERMISSION_APPLY_RESTRICTION) != 0;
+ isWhiteListed = (flags & FLAGS_PERMISSION_RESTRICTION_ANY_EXEMPT) != 0;
+ hasRequestedLegacyExternalStorage = pkg.hasRequestedLegacyExternalStorage();
+ targetSDK = pkg.getTargetSdkVersion();
+ } else {
+ flags = 0;
+ applyRestriction = false;
+ isWhiteListed = false;
+ hasRequestedLegacyExternalStorage = false;
+ targetSDK = 0;
+ }
+
+ return new SoftRestrictedPermissionPolicy() {
+ @Override
+ public int resolveAppOp() {
+ return OP_LEGACY_STORAGE;
+ }
+
+ @Override
+ public int getDesiredOpMode() {
+ if (applyRestriction) {
+ return MODE_DEFAULT;
+ } else if (hasRequestedLegacyExternalStorage) {
+ return MODE_ALLOWED;
+ } else {
+ return MODE_IGNORED;
+ }
+ }
+
+ @Override
+ public boolean shouldSetAppOpIfNotDefault() {
+ // Do not switch from allowed -> ignored as this would mean to retroactively
+ // turn on isolated storage. This will make the app loose all its files.
+ return getDesiredOpMode() != MODE_IGNORED;
+ }
+
+ @Override
+ public boolean canBeGranted() {
+ if (isWhiteListed || targetSDK >= Build.VERSION_CODES.Q) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+ };
+ }
+ default:
+ return DUMMY_POLICY;
+ }
+ }
+
+ /**
* @return An app op to be changed based on the state of the permission or
* {@link AppOpsManager#OP_NONE} if not app-op should be set.
*/
diff --git a/services/core/java/com/android/server/role/RoleManagerService.java b/services/core/java/com/android/server/role/RoleManagerService.java
index bf8c042835dd..06876352da0b 100644
--- a/services/core/java/com/android/server/role/RoleManagerService.java
+++ b/services/core/java/com/android/server/role/RoleManagerService.java
@@ -308,12 +308,12 @@ public class RoleManagerService extends SystemService implements RoleUserState.C
ByteArrayOutputStream out = new ByteArrayOutputStream();
pm.forEachInstalledPackage(FunctionalUtils.uncheckExceptions(pkg -> {
- out.write(pkg.packageName.getBytes());
+ out.write(pkg.getPackageName().getBytes());
out.write(BitUtils.toBytes(pkg.getLongVersionCode()));
- out.write(pm.getApplicationEnabledState(pkg.packageName, userId));
+ out.write(pm.getApplicationEnabledState(pkg.getPackageName(), userId));
ArraySet<String> enabledComponents =
- pm.getEnabledComponents(pkg.packageName, userId);
+ pm.getEnabledComponents(pkg.getPackageName(), userId);
int numComponents = CollectionUtils.size(enabledComponents);
out.write(numComponents);
for (int i = 0; i < numComponents; i++) {
@@ -321,12 +321,12 @@ public class RoleManagerService extends SystemService implements RoleUserState.C
}
ArraySet<String> disabledComponents =
- pm.getDisabledComponents(pkg.packageName, userId);
+ pm.getDisabledComponents(pkg.getPackageName(), userId);
numComponents = CollectionUtils.size(disabledComponents);
for (int i = 0; i < numComponents; i++) {
out.write(disabledComponents.valueAt(i).getBytes());
}
- for (Signature signature : pkg.mSigningDetails.signatures) {
+ for (Signature signature : pkg.getSigningDetails().signatures) {
out.write(signature.toByteArray());
}
}), userId);
diff --git a/services/tests/servicestests/src/com/android/server/pm/AppsFilterTest.java b/services/tests/servicestests/src/com/android/server/pm/AppsFilterTest.java
index 819091c378b8..e020945ebefc 100644
--- a/services/tests/servicestests/src/com/android/server/pm/AppsFilterTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/AppsFilterTest.java
@@ -27,10 +27,13 @@ import static org.mockito.Mockito.when;
import android.content.Intent;
import android.content.IntentFilter;
-import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageManager;
-import android.content.pm.PackageParser;
+import android.content.pm.parsing.AndroidPackage;
+import android.content.pm.parsing.ComponentParseUtils.ParsedActivity;
+import android.content.pm.parsing.ComponentParseUtils.ParsedActivityIntentInfo;
+import android.content.pm.parsing.PackageImpl;
+import android.content.pm.parsing.ParsingPackage;
import android.os.Build;
import android.os.Process;
import android.permission.IPermissionManager;
@@ -56,45 +59,55 @@ public class AppsFilterTest {
@Mock
AppsFilter.FeatureConfig mFeatureConfigMock;
- private Map<String, PackageParser.Package> mExisting = new ArrayMap<>();
+ private Map<String, AndroidPackage> mExisting = new ArrayMap<>();
- private static PackageBuilder pkg(String packageName) {
- return new PackageBuilder(packageName)
- .setApplicationInfoTargetSdkVersion(Build.VERSION_CODES.R);
+ private static ParsingPackage pkg(String packageName) {
+ return PackageImpl.forParsing(packageName)
+ .setTargetSdkVersion(Build.VERSION_CODES.R);
}
- private static PackageBuilder pkg(String packageName, Intent... queries) {
- return pkg(packageName).setQueriesIntents(queries);
+ private static ParsingPackage pkg(String packageName, Intent... queries) {
+ ParsingPackage pkg = pkg(packageName);
+ if (queries != null) {
+ for (Intent intent : queries) {
+ pkg.addQueriesIntent(intent);
+ }
+ }
+ return pkg;
}
- private static PackageBuilder pkg(String packageName, String... queriesPackages) {
- return pkg(packageName).setQueriesPackages(queriesPackages);
+ private static ParsingPackage pkg(String packageName, String... queriesPackages) {
+ ParsingPackage pkg = pkg(packageName);
+ if (queriesPackages != null) {
+ for (String queryPackageName : queriesPackages) {
+ pkg.addQueriesPackage(queryPackageName);
+ }
+ }
+ return pkg;
}
- private static PackageBuilder pkg(String packageName, IntentFilter... filters) {
- final PackageBuilder packageBuilder = pkg(packageName).addActivity(
- pkg -> new PackageParser.ParseComponentArgs(pkg, new String[1], 0, 0, 0, 0, 0, 0,
- new String[]{packageName}, 0, 0, 0), new ActivityInfo());
+ private static ParsingPackage pkg(String packageName, IntentFilter... filters) {
+ ParsedActivity activity = new ParsedActivity();
+ activity.setPackageName(packageName);
for (IntentFilter filter : filters) {
- packageBuilder.addActivityIntentInfo(0 /* index */, activity -> {
- final PackageParser.ActivityIntentInfo info =
- new PackageParser.ActivityIntentInfo(activity);
- if (filter.countActions() > 0) {
- filter.actionsIterator().forEachRemaining(info::addAction);
- }
- if (filter.countCategories() > 0) {
- filter.actionsIterator().forEachRemaining(info::addAction);
- }
- if (filter.countDataAuthorities() > 0) {
- filter.authoritiesIterator().forEachRemaining(info::addDataAuthority);
- }
- if (filter.countDataSchemes() > 0) {
- filter.schemesIterator().forEachRemaining(info::addDataScheme);
- }
- return info;
- });
+ final ParsedActivityIntentInfo info = new ParsedActivityIntentInfo(packageName, null);
+ if (filter.countActions() > 0) {
+ filter.actionsIterator().forEachRemaining(info::addAction);
+ }
+ if (filter.countCategories() > 0) {
+ filter.actionsIterator().forEachRemaining(info::addAction);
+ }
+ if (filter.countDataAuthorities() > 0) {
+ filter.authoritiesIterator().forEachRemaining(info::addDataAuthority);
+ }
+ if (filter.countDataSchemes() > 0) {
+ filter.schemesIterator().forEachRemaining(info::addDataScheme);
+ }
+ activity.addIntent(info);
}
- return packageBuilder;
+
+ return pkg(packageName)
+ .addActivity(activity);
}
@Before
@@ -106,7 +119,7 @@ public class AppsFilterTest {
.checkPermission(anyString(), anyString(), anyInt()))
.thenReturn(PackageManager.PERMISSION_DENIED);
when(mFeatureConfigMock.isGloballyEnabled()).thenReturn(true);
- when(mFeatureConfigMock.packageIsEnabled(any(PackageParser.Package.class)))
+ when(mFeatureConfigMock.packageIsEnabled(any(AndroidPackage.class)))
.thenReturn(true);
}
@@ -152,7 +165,7 @@ public class AppsFilterTest {
PackageSetting target = simulateAddPackage(appsFilter, pkg("com.some.package")).build();
PackageSetting calling = simulateAddPackage(appsFilter, pkg("com.some.other.package",
- new Intent("TEST_ACTION")).setApplicationInfoTargetSdkVersion(
+ new Intent("TEST_ACTION")).setTargetSdkVersion(
Build.VERSION_CODES.P)).build();
assertFalse(appsFilter.shouldFilterApplication(DUMMY_CALLING_UID, calling, target, 0));
@@ -245,7 +258,7 @@ public class AppsFilterTest {
@Test
public void testNoQueries_FeatureOff_DoesntFilter() {
- when(mFeatureConfigMock.packageIsEnabled(any(PackageParser.Package.class)))
+ when(mFeatureConfigMock.packageIsEnabled(any(AndroidPackage.class)))
.thenReturn(false);
final AppsFilter appsFilter =
new AppsFilter(mFeatureConfigMock, mPermissionManagerMock,
@@ -301,13 +314,15 @@ public class AppsFilterTest {
}
private PackageSettingBuilder simulateAddPackage(AppsFilter filter,
- PackageBuilder newPkgBuilder) {
- PackageParser.Package newPkg = newPkgBuilder.build();
+ ParsingPackage newPkgBuilder) {
+ AndroidPackage newPkg = newPkgBuilder
+ .hideAsParsed()
+ .hideAsFinal();
filter.addPackage(newPkg, mExisting);
- mExisting.put(newPkg.packageName, newPkg);
+ mExisting.put(newPkg.getPackageName(), newPkg);
return new PackageSettingBuilder()
.setPackage(newPkg)
- .setName(newPkg.packageName)
+ .setName(newPkg.getPackageName())
.setCodePath("/")
.setResourcePath("/")
.setPVersionCode(1L);
diff --git a/services/tests/servicestests/src/com/android/server/pm/KeySetManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/pm/KeySetManagerServiceTest.java
index fec3267c2649..0273a1c5d86e 100644
--- a/services/tests/servicestests/src/com/android/server/pm/KeySetManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/KeySetManagerServiceTest.java
@@ -19,17 +19,17 @@ package com.android.server.pm;
import android.content.pm.PackageParser;
import android.content.pm.Signature;
+import android.test.AndroidTestCase;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.LongSparseArray;
+
import com.android.internal.util.ArrayUtils;
import java.io.File;
import java.io.IOException;
-import java.security.cert.CertificateException;
import java.security.PublicKey;
-
-import android.test.AndroidTestCase;
+import java.security.cert.CertificateException;
public class KeySetManagerServiceTest extends AndroidTestCase {
@@ -39,7 +39,7 @@ public class KeySetManagerServiceTest extends AndroidTestCase {
public PackageSetting generateFakePackageSetting(String name) {
return new PackageSetting(name, name, new File(mContext.getCacheDir(), "fakeCodePath"),
new File(mContext.getCacheDir(), "fakeResPath"), "", "", "",
- "", 1, 0, 0, null, null, 0 /*sharedUserId*/, null /*usesStaticLibraries*/,
+ "", 1, 0, 0, 0 /*sharedUserId*/, null /*usesStaticLibraries*/,
null /*usesStaticLibrariesVersions*/);
}
diff --git a/services/tests/servicestests/src/com/android/server/pm/PackageBuilder.java b/services/tests/servicestests/src/com/android/server/pm/PackageBuilder.java
deleted file mode 100644
index c38672cfc93c..000000000000
--- a/services/tests/servicestests/src/com/android/server/pm/PackageBuilder.java
+++ /dev/null
@@ -1,176 +0,0 @@
-/*
- * Copyright (C) 2019 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;
-
-import android.content.Intent;
-import android.content.pm.ActivityInfo;
-import android.content.pm.PackageParser;
-
-import com.android.internal.util.ArrayUtils;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-
-class PackageBuilder {
- final PackageParser.Package mPkg;
-
- PackageBuilder(String packageName) {
- mPkg = new PackageParser.Package(packageName);
- }
-
- PackageBuilder setApplicationInfoCodePath(String codePath) {
- mPkg.applicationInfo.setCodePath(codePath);
- return this;
- }
-
- PackageBuilder setApplicationInfoResourcePath(String resourcePath) {
- mPkg.applicationInfo.setResourcePath(resourcePath);
- return this;
- }
-
- PackageBuilder setCodePath(String codePath) {
- mPkg.codePath = codePath;
- return this;
- }
-
- PackageBuilder setBaseCodePath(String baseCodePath) {
- mPkg.baseCodePath = baseCodePath;
- return this;
- }
-
- PackageBuilder addUsesStaticLibrary(String name, long version) {
- mPkg.usesStaticLibraries = ArrayUtils.add(mPkg.usesStaticLibraries, name);
- mPkg.usesStaticLibrariesVersions =
- ArrayUtils.appendLong(mPkg.usesStaticLibrariesVersions, version);
- return this;
- }
-
- PackageBuilder setApplicationInfoNativeLibraryRootDir(String dir) {
- mPkg.applicationInfo.nativeLibraryRootDir = dir;
- return this;
- }
-
- PackageBuilder setStaticSharedLib(String staticSharedLibName, long staticSharedLibVersion) {
- mPkg.staticSharedLibVersion = staticSharedLibVersion;
- mPkg.staticSharedLibName = staticSharedLibName;
- return this;
- }
-
- PackageBuilder setManifestPackageName(String manifestPackageName) {
- mPkg.manifestPackageName = manifestPackageName;
- return this;
- }
-
- PackageBuilder setVersionCodeMajor(int versionCodeMajor) {
- mPkg.mVersionCodeMajor = versionCodeMajor;
- return this;
- }
-
- PackageBuilder setVersionCode(int versionCode) {
- mPkg.mVersionCode = versionCode;
- return this;
- }
-
- PackageBuilder addSplitCodePath(String splitCodePath) {
- mPkg.splitCodePaths =
- ArrayUtils.appendElement(String.class, mPkg.splitCodePaths, splitCodePath);
- return this;
- }
-
- PackageBuilder setApplicationInfoVolumeUuid(String volumeUuid) {
- mPkg.applicationInfo.volumeUuid = volumeUuid;
- return this;
- }
-
- PackageBuilder addLibraryName(String libraryName) {
- mPkg.libraryNames = ArrayUtils.add(mPkg.libraryNames, libraryName);
- return this;
- }
-
- PackageBuilder setRealPackageName(String realPackageName) {
- mPkg.mRealPackage = realPackageName;
- return this;
- }
-
- PackageBuilder setCpuAbiOVerride(String cpuAbiOverride) {
- mPkg.cpuAbiOverride = cpuAbiOverride;
- return this;
- }
-
- PackageBuilder addPermissionRequest(String permissionName) {
- mPkg.requestedPermissions.add(permissionName);
- return this;
- }
-
- PackageParser.Package build() {
- return mPkg;
- }
-
- public PackageBuilder addApplicationInfoFlag(int flag) {
- mPkg.applicationInfo.flags |= flag;
- return this;
- }
-
- public PackageBuilder setApplicationInfoTargetSdkVersion(int versionCode) {
- mPkg.applicationInfo.targetSdkVersion = versionCode;
- return this;
- }
-
- public PackageBuilder setQueriesIntents(Collection<Intent> queriesIntents) {
- mPkg.mQueriesIntents = new ArrayList<>(queriesIntents);
- return this;
- }
-
- public PackageBuilder setQueriesIntents(Intent... intents) {
- return setQueriesIntents(Arrays.asList(intents));
- }
-
- public PackageBuilder setQueriesPackages(Collection<String> queriesPackages) {
- mPkg.mQueriesPackages = new ArrayList<>(queriesPackages);
- return this;
- }
-
- public PackageBuilder setQueriesPackages(String... queriesPackages) {
- return setQueriesPackages(Arrays.asList(queriesPackages));
- }
-
- public PackageBuilder setForceQueryable(boolean forceQueryable) {
- mPkg.mForceQueryable = forceQueryable;
- return this;
- }
-
- public interface ParseComponentArgsCreator {
- PackageParser.ParseComponentArgs create(PackageParser.Package pkg);
- }
-
- public PackageBuilder addActivity(ParseComponentArgsCreator argsCreator, ActivityInfo info) {
- mPkg.activities.add(new PackageParser.Activity(argsCreator.create(mPkg), info));
- return this;
- }
-
- public interface ActivityIntentInfoCreator {
- PackageParser.ActivityIntentInfo create(PackageParser.Activity activity);
- }
-
- public PackageBuilder addActivityIntentInfo(
- int activityIndex, ActivityIntentInfoCreator creator) {
- final PackageParser.Activity activity = mPkg.activities.get(activityIndex);
- activity.intents.add(creator.create(activity));
- return this;
- }
-}
diff --git a/services/tests/servicestests/src/com/android/server/pm/PackageManagerServiceTest.java b/services/tests/servicestests/src/com/android/server/pm/PackageManagerServiceTest.java
index 0a310d193675..85840e135909 100644
--- a/services/tests/servicestests/src/com/android/server/pm/PackageManagerServiceTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/PackageManagerServiceTest.java
@@ -87,7 +87,7 @@ public class PackageManagerServiceTest {
setting = new PackageSetting("name", "realName", new File("codePath"),
new File("resourcePath"), "legacyNativeLibraryPathString",
"primaryCpuAbiString", "secondaryCpuAbiString",
- "cpuAbiOverrideString", 0, 0, 0, "parentPackageName", null, 0,
+ "cpuAbiOverrideString", 0, 0, 0, 0,
null, null);
pri.populateUsers(new int[] {
1, 2, 3, 4, 5
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 3fe9b52b8415..6836d3b6e21d 100644
--- a/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java
+++ b/services/tests/servicestests/src/com/android/server/pm/PackageManagerSettingsTests.java
@@ -346,10 +346,6 @@ public class PackageManagerSettingsTests {
private static final String PACKAGE_NAME = "com.android.bar";
private static final String REAL_PACKAGE_NAME = "com.android.foo";
- private static final String PARENT_PACKAGE_NAME = "com.android.bar.parent";
- private static final String CHILD_PACKAGE_NAME_01 = "com.android.bar.child01";
- private static final String CHILD_PACKAGE_NAME_02 = "com.android.bar.child02";
- private static final String CHILD_PACKAGE_NAME_03 = "com.android.bar.child03";
private static final File INITIAL_CODE_PATH =
new File(InstrumentationRegistry.getContext().getFilesDir(), "com.android.bar-1");
private static final File UPDATED_CODE_PATH =
@@ -359,10 +355,6 @@ public class PackageManagerSettingsTests {
@Test
public void testPackageStateCopy01() {
- final List<String> childPackageNames = new ArrayList<>();
- childPackageNames.add(CHILD_PACKAGE_NAME_01);
- childPackageNames.add(CHILD_PACKAGE_NAME_02);
- childPackageNames.add(CHILD_PACKAGE_NAME_03);
final PackageSetting origPkgSetting01 = new PackageSetting(
PACKAGE_NAME,
REAL_PACKAGE_NAME,
@@ -375,8 +367,6 @@ public class PackageManagerSettingsTests {
INITIAL_VERSION_CODE,
ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_HAS_CODE,
ApplicationInfo.PRIVATE_FLAG_PRIVILEGED|ApplicationInfo.PRIVATE_FLAG_HIDDEN,
- PARENT_PACKAGE_NAME,
- childPackageNames,
0,
null /*usesStaticLibraries*/,
null /*usesStaticLibrariesVersions*/);
@@ -386,10 +376,6 @@ public class PackageManagerSettingsTests {
@Test
public void testPackageStateCopy02() {
- final List<String> childPackageNames = new ArrayList<>();
- childPackageNames.add(CHILD_PACKAGE_NAME_01);
- childPackageNames.add(CHILD_PACKAGE_NAME_02);
- childPackageNames.add(CHILD_PACKAGE_NAME_03);
final PackageSetting origPkgSetting01 = new PackageSetting(
PACKAGE_NAME /*pkgName*/,
REAL_PACKAGE_NAME /*realPkgName*/,
@@ -402,8 +388,6 @@ public class PackageManagerSettingsTests {
INITIAL_VERSION_CODE,
ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_HAS_CODE,
ApplicationInfo.PRIVATE_FLAG_PRIVILEGED|ApplicationInfo.PRIVATE_FLAG_HIDDEN,
- PARENT_PACKAGE_NAME,
- childPackageNames,
0,
null /*usesStaticLibraries*/,
null /*usesStaticLibrariesVersions*/);
@@ -419,8 +403,6 @@ public class PackageManagerSettingsTests {
UPDATED_VERSION_CODE,
0 /*pkgFlags*/,
0 /*pkgPrivateFlags*/,
- null /*parentPkgName*/,
- null /*childPkgNames*/,
0,
null /*usesStaticLibraries*/,
null /*usesStaticLibrariesVersions*/);
@@ -448,7 +430,6 @@ public class PackageManagerSettingsTests {
"armeabi" /*secondaryCpuAbi*/,
0 /*pkgFlags*/,
0 /*pkgPrivateFlags*/,
- null /*childPkgNames*/,
UserManagerService.getInstance(),
null /*usesStaticLibraries*/,
null /*usesStaticLibrariesVersions*/);
@@ -482,7 +463,6 @@ public class PackageManagerSettingsTests {
"armeabi" /*secondaryCpuAbi*/,
ApplicationInfo.FLAG_SYSTEM /*pkgFlags*/,
ApplicationInfo.PRIVATE_FLAG_PRIVILEGED /*pkgPrivateFlags*/,
- null /*childPkgNames*/,
UserManagerService.getInstance(),
null /*usesStaticLibraries*/,
null /*usesStaticLibrariesVersions*/);
@@ -522,7 +502,6 @@ public class PackageManagerSettingsTests {
"armeabi" /*secondaryCpuAbi*/,
0 /*pkgFlags*/,
0 /*pkgPrivateFlags*/,
- null /*childPkgNames*/,
UserManagerService.getInstance(),
null /*usesStaticLibraries*/,
null /*usesStaticLibrariesVersions*/);
@@ -555,8 +534,6 @@ public class PackageManagerSettingsTests {
false /*allowInstall*/,
false /*instantApp*/,
false /*virtualPreload*/,
- null /*parentPkgName*/,
- null /*childPkgNames*/,
UserManagerService.getInstance(),
null /*usesStaticLibraries*/,
null /*usesStaticLibrariesVersions*/);
@@ -596,8 +573,6 @@ public class PackageManagerSettingsTests {
true /*allowInstall*/,
false /*instantApp*/,
false /*virtualPreload*/,
- null /*parentPkgName*/,
- null /*childPkgNames*/,
UserManagerService.getInstance(),
null /*usesStaticLibraries*/,
null /*usesStaticLibrariesVersions*/);
@@ -643,8 +618,6 @@ public class PackageManagerSettingsTests {
false /*allowInstall*/,
false /*instantApp*/,
false /*virtualPreload*/,
- null /*parentPkgName*/,
- null /*childPkgNames*/,
UserManagerService.getInstance(),
null /*usesStaticLibraries*/,
null /*usesStaticLibrariesVersions*/);
@@ -687,8 +660,6 @@ public class PackageManagerSettingsTests {
false /*allowInstall*/,
false /*instantApp*/,
false /*virtualPreload*/,
- null /*parentPkgName*/,
- null /*childPkgNames*/,
UserManagerService.getInstance(),
null /*usesStaticLibraries*/,
null /*usesStaticLibrariesVersions*/);
@@ -745,9 +716,6 @@ public class PackageManagerSettingsTests {
private void verifySettingCopy(PackageSetting origPkgSetting, PackageSetting testPkgSetting) {
assertThat(origPkgSetting, is(not(testPkgSetting)));
assertThat(origPkgSetting.appId, is(testPkgSetting.appId));
- // different but equal objects
- assertNotSame(origPkgSetting.childPackageNames, testPkgSetting.childPackageNames);
- assertThat(origPkgSetting.childPackageNames, is(testPkgSetting.childPackageNames));
assertSame(origPkgSetting.codePath, testPkgSetting.codePath);
assertThat(origPkgSetting.codePath, is(testPkgSetting.codePath));
assertSame(origPkgSetting.codePathString, testPkgSetting.codePathString);
@@ -773,8 +741,6 @@ public class PackageManagerSettingsTests {
// mOldCodePaths is _not_ copied
// assertNotSame(origPkgSetting.mOldCodePaths, testPkgSetting.mOldCodePaths);
// assertThat(origPkgSetting.mOldCodePaths, is(not(testPkgSetting.mOldCodePaths)));
- assertSame(origPkgSetting.parentPackageName, testPkgSetting.parentPackageName);
- assertThat(origPkgSetting.parentPackageName, is(testPkgSetting.parentPackageName));
assertSame(origPkgSetting.pkg, testPkgSetting.pkg);
// No equals() method for this object
// assertThat(origPkgSetting.pkg, is(testPkgSetting.pkg));
@@ -826,8 +792,6 @@ public class PackageManagerSettingsTests {
INITIAL_VERSION_CODE,
pkgFlags,
0 /*privateFlags*/,
- null /*parentPackageName*/,
- null /*childPackageNames*/,
sharedUserId,
null /*usesStaticLibraries*/,
null /*usesStaticLibrariesVersions*/);
@@ -846,8 +810,6 @@ public class PackageManagerSettingsTests {
INITIAL_VERSION_CODE,
0,
0 /*privateFlags*/,
- null /*parentPackageName*/,
- null /*childPackageNames*/,
0,
null /*usesStaticLibraries*/,
null /*usesStaticLibrariesVersions*/);
diff --git a/services/tests/servicestests/src/com/android/server/pm/PackageParserTest.java b/services/tests/servicestests/src/com/android/server/pm/PackageParserTest.java
index e33d8ca66ed0..162092b5040a 100644
--- a/services/tests/servicestests/src/com/android/server/pm/PackageParserTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/PackageParserTest.java
@@ -15,35 +15,49 @@
*/
package com.android.server.pm;
-import static android.content.res.Resources.ID_NULL;
-
+import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
-import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.content.pm.ApplicationInfo;
import android.content.pm.ConfigurationInfo;
import android.content.pm.FeatureGroupInfo;
import android.content.pm.FeatureInfo;
-import android.content.pm.InstrumentationInfo;
+import android.content.pm.PackageInfo;
import android.content.pm.PackageParser;
+import android.content.pm.PackageUserState;
import android.content.pm.ProviderInfo;
import android.content.pm.ServiceInfo;
import android.content.pm.SharedLibraryInfo;
import android.content.pm.Signature;
+import android.content.pm.parsing.AndroidPackage;
+import android.content.pm.parsing.ComponentParseUtils;
+import android.content.pm.parsing.ComponentParseUtils.ParsedActivity;
+import android.content.pm.parsing.ComponentParseUtils.ParsedComponent;
+import android.content.pm.parsing.ComponentParseUtils.ParsedInstrumentation;
+import android.content.pm.parsing.ComponentParseUtils.ParsedIntentInfo;
+import android.content.pm.parsing.ComponentParseUtils.ParsedPermission;
+import android.content.pm.parsing.ComponentParseUtils.ParsedPermissionGroup;
+import android.content.pm.parsing.ComponentParseUtils.ParsedProvider;
+import android.content.pm.parsing.ComponentParseUtils.ParsedService;
+import android.content.pm.parsing.PackageImpl;
+import android.content.pm.parsing.PackageInfoUtils;
+import android.content.pm.parsing.ParsedPackage;
+import android.content.pm.parsing.ParsingPackage;
import android.os.Bundle;
import android.os.Parcel;
import android.platform.test.annotations.Presubmit;
-import android.util.ArrayMap;
import android.util.ArraySet;
import androidx.test.filters.MediumTest;
import androidx.test.filters.SmallTest;
import androidx.test.runner.AndroidJUnit4;
+import com.android.internal.util.ArrayUtils;
+
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;
@@ -57,6 +71,7 @@ import java.lang.reflect.Field;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collections;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
@@ -64,6 +79,9 @@ import java.util.Set;
@RunWith(AndroidJUnit4.class)
@MediumTest
public class PackageParserTest {
+ // TODO(b/135203078): Update this test with all fields and validate equality. Initial change
+ // was just migrating to new interfaces. Consider adding actual equals() methods.
+
@Rule
public TemporaryFolder mTemporaryFolder = new TemporaryFolder();
@@ -79,12 +97,12 @@ public class PackageParserTest {
@Test
public void testParse_noCache() throws Exception {
PackageParser pp = new CachePackageNameParser();
- PackageParser.Package pkg = pp.parsePackage(FRAMEWORK, 0 /* parseFlags */,
+ ParsedPackage pkg = pp.parseParsedPackage(FRAMEWORK, 0 /* parseFlags */,
false /* useCaches */);
assertNotNull(pkg);
pp.setCacheDir(mTmpDir);
- pkg = pp.parsePackage(FRAMEWORK, 0 /* parseFlags */,
+ pkg = pp.parseParsedPackage(FRAMEWORK, 0 /* parseFlags */,
false /* useCaches */);
assertNotNull(pkg);
@@ -99,27 +117,27 @@ public class PackageParserTest {
pp.setCacheDir(mTmpDir);
// The first parse will write this package to the cache.
- pp.parsePackage(FRAMEWORK, 0 /* parseFlags */, true /* useCaches */);
+ pp.parseParsedPackage(FRAMEWORK, 0 /* parseFlags */, true /* useCaches */);
// Now attempt to parse the package again, should return the
// cached result.
- PackageParser.Package pkg = pp.parsePackage(FRAMEWORK, 0 /* parseFlags */,
+ ParsedPackage pkg = pp.parseParsedPackage(FRAMEWORK, 0 /* parseFlags */,
true /* useCaches */);
- assertEquals("cache_android", pkg.packageName);
+ assertEquals("cache_android", pkg.getPackageName());
// Try again, with useCaches == false, shouldn't return the parsed
// result.
- pkg = pp.parsePackage(FRAMEWORK, 0 /* parseFlags */, false /* useCaches */);
- assertEquals("android", pkg.packageName);
+ pkg = pp.parseParsedPackage(FRAMEWORK, 0 /* parseFlags */, false /* useCaches */);
+ assertEquals("android", pkg.getPackageName());
// We haven't set a cache directory here : the parse should still succeed,
// just not using the cached results.
pp = new CachePackageNameParser();
- pkg = pp.parsePackage(FRAMEWORK, 0 /* parseFlags */, true /* useCaches */);
- assertEquals("android", pkg.packageName);
+ pkg = pp.parseParsedPackage(FRAMEWORK, 0 /* parseFlags */, true /* useCaches */);
+ assertEquals("android", pkg.getPackageName());
- pkg = pp.parsePackage(FRAMEWORK, 0 /* parseFlags */, false /* useCaches */);
- assertEquals("android", pkg.packageName);
+ pkg = pp.parseParsedPackage(FRAMEWORK, 0 /* parseFlags */, false /* useCaches */);
+ assertEquals("android", pkg.getPackageName());
}
@Test
@@ -127,14 +145,14 @@ public class PackageParserTest {
PackageParser pp = new PackageParser();
pp.setCacheDir(mTmpDir);
- PackageParser.Package pkg = pp.parsePackage(FRAMEWORK, 0 /* parseFlags */,
- true /* useCaches */);
+ ParsedPackage pkg = pp.parseParsedPackage(FRAMEWORK, 0 /* parseFlags */,
+ true /* useCaches */);
Parcel p = Parcel.obtain();
pkg.writeToParcel(p, 0 /* flags */);
p.setDataPosition(0);
- PackageParser.Package deserialized = new PackageParser.Package(p);
+ ParsedPackage deserialized = new PackageImpl(p);
assertPackagesEqual(pkg, deserialized);
}
@@ -143,46 +161,52 @@ public class PackageParserTest {
@SmallTest
@Presubmit
public void test_roundTripKnownFields() throws Exception {
- PackageParser.Package pkg = new PackageParser.Package("foo");
+ ParsingPackage pkg = PackageImpl.forParsing("foo");
setKnownFields(pkg);
Parcel p = Parcel.obtain();
pkg.writeToParcel(p, 0 /* flags */);
p.setDataPosition(0);
- PackageParser.Package deserialized = new PackageParser.Package(p);
+ ParsedPackage deserialized = new PackageImpl(p);
assertAllFieldsExist(deserialized);
}
@Test
public void test_stringInterning() throws Exception {
- PackageParser.Package pkg = new PackageParser.Package("foo");
+ ParsingPackage pkg = PackageImpl.forParsing("foo");
setKnownFields(pkg);
Parcel p = Parcel.obtain();
pkg.writeToParcel(p, 0 /* flags */);
p.setDataPosition(0);
- PackageParser.Package deserialized = new PackageParser.Package(p);
+ ParsingPackage deserialized = new PackageImpl(p);
p.setDataPosition(0);
- PackageParser.Package deserialized2 = new PackageParser.Package(p);
-
- assertSame(deserialized.packageName, deserialized2.packageName);
- assertSame(deserialized.applicationInfo.permission,
- deserialized2.applicationInfo.permission);
- assertSame(deserialized.requestedPermissions.get(0),
- deserialized2.requestedPermissions.get(0));
- assertSame(deserialized.protectedBroadcasts.get(0),
- deserialized2.protectedBroadcasts.get(0));
- assertSame(deserialized.usesLibraries.get(0),
- deserialized2.usesLibraries.get(0));
- assertSame(deserialized.usesOptionalLibraries.get(0),
- deserialized2.usesOptionalLibraries.get(0));
- assertSame(deserialized.mVersionName, deserialized2.mVersionName);
- assertSame(deserialized.mSharedUserId, deserialized2.mSharedUserId);
- }
+ ParsingPackage deserialized2 = new PackageImpl(p);
+ assertSame(deserialized.getPackageName(), deserialized2.getPackageName());
+ assertSame(deserialized.getPermission(),
+ deserialized2.getPermission());
+ assertSame(deserialized.getRequestedPermissions().get(0),
+ deserialized2.getRequestedPermissions().get(0));
+
+ List<String> protectedBroadcastsOne = new ArrayList<>(1);
+ protectedBroadcastsOne.addAll(deserialized.getProtectedBroadcasts());
+
+ List<String> protectedBroadcastsTwo = new ArrayList<>(1);
+ protectedBroadcastsTwo.addAll(deserialized2.getProtectedBroadcasts());
+
+ assertSame(protectedBroadcastsOne.get(0), protectedBroadcastsTwo.get(0));
+
+ assertSame(deserialized.getUsesLibraries().get(0),
+ deserialized2.getUsesLibraries().get(0));
+ assertSame(deserialized.getUsesOptionalLibraries().get(0),
+ deserialized2.getUsesOptionalLibraries().get(0));
+ assertSame(deserialized.getVersionName(), deserialized2.getVersionName());
+ assertSame(deserialized.getSharedUserId(), deserialized2.getSharedUserId());
+ }
/**
* A trivial subclass of package parser that only caches the package name, and throws away
@@ -190,107 +214,111 @@ public class PackageParserTest {
*/
public static class CachePackageNameParser extends PackageParser {
@Override
- public byte[] toCacheEntry(Package pkg) {
- return ("cache_" + pkg.packageName).getBytes(StandardCharsets.UTF_8);
+ public byte[] toCacheEntry(ParsedPackage pkg) {
+ return ("cache_" + pkg.getPackageName()).getBytes(StandardCharsets.UTF_8);
}
@Override
- public Package fromCacheEntry(byte[] cacheEntry) {
- return new Package(new String(cacheEntry, StandardCharsets.UTF_8));
+ public ParsedPackage fromCacheEntry(byte[] cacheEntry) {
+ return PackageImpl.forParsing(new String(cacheEntry, StandardCharsets.UTF_8))
+ .hideAsParsed();
}
}
// NOTE: The equality assertions below are based on code autogenerated by IntelliJ.
- public static void assertPackagesEqual(PackageParser.Package a, PackageParser.Package b) {
- assertEquals(a.baseRevisionCode, b.baseRevisionCode);
- assertEquals(a.baseHardwareAccelerated, b.baseHardwareAccelerated);
- assertEquals(a.mVersionCode, b.mVersionCode);
- assertEquals(a.mSharedUserLabel, b.mSharedUserLabel);
- assertEquals(a.mPreferredOrder, b.mPreferredOrder);
- assertEquals(a.installLocation, b.installLocation);
- assertEquals(a.coreApp, b.coreApp);
- assertEquals(a.mRequiredForAllUsers, b.mRequiredForAllUsers);
- assertEquals(a.mCompileSdkVersion, b.mCompileSdkVersion);
- assertEquals(a.mCompileSdkVersionCodename, b.mCompileSdkVersionCodename);
- assertEquals(a.use32bitAbi, b.use32bitAbi);
- assertEquals(a.packageName, b.packageName);
- assertTrue(Arrays.equals(a.splitNames, b.splitNames));
- assertEquals(a.volumeUuid, b.volumeUuid);
- assertEquals(a.codePath, b.codePath);
- assertEquals(a.baseCodePath, b.baseCodePath);
- assertTrue(Arrays.equals(a.splitCodePaths, b.splitCodePaths));
- assertTrue(Arrays.equals(a.splitRevisionCodes, b.splitRevisionCodes));
- assertTrue(Arrays.equals(a.splitFlags, b.splitFlags));
- assertTrue(Arrays.equals(a.splitPrivateFlags, b.splitPrivateFlags));
- assertApplicationInfoEqual(a.applicationInfo, b.applicationInfo);
-
- assertEquals(a.permissions.size(), b.permissions.size());
- for (int i = 0; i < a.permissions.size(); ++i) {
- assertPermissionsEqual(a.permissions.get(i), b.permissions.get(i));
- assertSame(a.permissions.get(i).owner, a);
- assertSame(b.permissions.get(i).owner, b);
+ public static void assertPackagesEqual(AndroidPackage a, AndroidPackage b) {
+ assertEquals(a.getBaseRevisionCode(), b.getBaseRevisionCode());
+ assertEquals(a.isBaseHardwareAccelerated(), b.isBaseHardwareAccelerated());
+ assertEquals(a.getVersionCode(), b.getVersionCode());
+ assertEquals(a.getSharedUserLabel(), b.getSharedUserLabel());
+ assertEquals(a.getPreferredOrder(), b.getPreferredOrder());
+ assertEquals(a.getInstallLocation(), b.getInstallLocation());
+ assertEquals(a.isCoreApp(), b.isCoreApp());
+ assertEquals(a.isRequiredForAllUsers(), b.isRequiredForAllUsers());
+ assertEquals(a.getCompileSdkVersion(), b.getCompileSdkVersion());
+ assertEquals(a.getCompileSdkVersionCodeName(), b.getCompileSdkVersionCodeName());
+ assertEquals(a.isUse32BitAbi(), b.isUse32BitAbi());
+ assertEquals(a.getPackageName(), b.getPackageName());
+ assertArrayEquals(a.getSplitNames(), b.getSplitNames());
+ assertEquals(a.getVolumeUuid(), b.getVolumeUuid());
+ assertEquals(a.getCodePath(), b.getCodePath());
+ assertEquals(a.getBaseCodePath(), b.getBaseCodePath());
+ assertArrayEquals(a.getSplitCodePaths(), b.getSplitCodePaths());
+ assertArrayEquals(a.getSplitRevisionCodes(), b.getSplitRevisionCodes());
+ assertArrayEquals(a.getSplitFlags(), b.getSplitFlags());
+
+ PackageInfo aInfo = PackageInfoUtils.generate(a, new int[]{}, 0, 0, 0,
+ Collections.emptySet(), new PackageUserState(), 0);
+ PackageInfo bInfo = PackageInfoUtils.generate(b, new int[]{}, 0, 0, 0,
+ Collections.emptySet(), new PackageUserState(), 0);
+ assertApplicationInfoEqual(aInfo.applicationInfo, bInfo.applicationInfo);
+
+ assertEquals(ArrayUtils.size(a.getPermissions()), ArrayUtils.size(b.getPermissions()));
+ for (int i = 0; i < ArrayUtils.size(a.getPermissions()); ++i) {
+ assertPermissionsEqual(a.getPermissions().get(i), b.getPermissions().get(i));
}
- assertEquals(a.permissionGroups.size(), b.permissionGroups.size());
- for (int i = 0; i < a.permissionGroups.size(); ++i) {
- assertPermissionGroupsEqual(a.permissionGroups.get(i), b.permissionGroups.get(i));
+ assertEquals(ArrayUtils.size(a.getPermissionGroups()),
+ ArrayUtils.size(b.getPermissionGroups()));
+ for (int i = 0; i < a.getPermissionGroups().size(); ++i) {
+ assertPermissionGroupsEqual(a.getPermissionGroups().get(i),
+ b.getPermissionGroups().get(i));
}
- assertEquals(a.activities.size(), b.activities.size());
- for (int i = 0; i < a.activities.size(); ++i) {
- assertActivitiesEqual(a.activities.get(i), b.activities.get(i));
+ assertEquals(ArrayUtils.size(a.getActivities()), ArrayUtils.size(b.getActivities()));
+ for (int i = 0; i < ArrayUtils.size(a.getActivities()); ++i) {
+ assertActivitiesEqual(a, a.getActivities().get(i), b, b.getActivities().get(i));
}
- assertEquals(a.receivers.size(), b.receivers.size());
- for (int i = 0; i < a.receivers.size(); ++i) {
- assertActivitiesEqual(a.receivers.get(i), b.receivers.get(i));
+ assertEquals(ArrayUtils.size(a.getReceivers()), ArrayUtils.size(b.getReceivers()));
+ for (int i = 0; i < ArrayUtils.size(a.getReceivers()); ++i) {
+ assertActivitiesEqual(a, a.getReceivers().get(i), b, b.getReceivers().get(i));
}
- assertEquals(a.providers.size(), b.providers.size());
- for (int i = 0; i < a.providers.size(); ++i) {
- assertProvidersEqual(a.providers.get(i), b.providers.get(i));
+ assertEquals(ArrayUtils.size(a.getProviders()), ArrayUtils.size(b.getProviders()));
+ for (int i = 0; i < ArrayUtils.size(a.getProviders()); ++i) {
+ assertProvidersEqual(a, a.getProviders().get(i), b, b.getProviders().get(i));
}
- assertEquals(a.services.size(), b.services.size());
- for (int i = 0; i < a.services.size(); ++i) {
- assertServicesEqual(a.services.get(i), b.services.get(i));
+ assertEquals(ArrayUtils.size(a.getServices()), ArrayUtils.size(b.getServices()));
+ for (int i = 0; i < ArrayUtils.size(a.getServices()); ++i) {
+ assertServicesEqual(a, a.getServices().get(i), b, b.getServices().get(i));
}
- assertEquals(a.instrumentation.size(), b.instrumentation.size());
- for (int i = 0; i < a.instrumentation.size(); ++i) {
- assertInstrumentationEqual(a.instrumentation.get(i), b.instrumentation.get(i));
+ assertEquals(ArrayUtils.size(a.getInstrumentations()),
+ ArrayUtils.size(b.getInstrumentations()));
+ for (int i = 0; i < ArrayUtils.size(a.getInstrumentations()); ++i) {
+ assertInstrumentationEqual(a.getInstrumentations().get(i),
+ b.getInstrumentations().get(i));
}
- assertEquals(a.requestedPermissions, b.requestedPermissions);
- assertEquals(a.protectedBroadcasts, b.protectedBroadcasts);
- assertEquals(a.parentPackage, b.parentPackage);
- assertEquals(a.childPackages, b.childPackages);
- assertEquals(a.libraryNames, b.libraryNames);
- assertEquals(a.usesLibraries, b.usesLibraries);
- assertEquals(a.usesOptionalLibraries, b.usesOptionalLibraries);
- assertTrue(Arrays.equals(a.usesLibraryFiles, b.usesLibraryFiles));
- assertEquals(a.mOriginalPackages, b.mOriginalPackages);
- assertEquals(a.mRealPackage, b.mRealPackage);
- assertEquals(a.mAdoptPermissions, b.mAdoptPermissions);
- assertBundleApproximateEquals(a.mAppMetaData, b.mAppMetaData);
- assertEquals(a.mVersionName, b.mVersionName);
- assertEquals(a.mSharedUserId, b.mSharedUserId);
- assertTrue(Arrays.equals(a.mSigningDetails.signatures, b.mSigningDetails.signatures));
- assertTrue(Arrays.equals(a.mLastPackageUsageTimeInMills, b.mLastPackageUsageTimeInMills));
- assertEquals(a.mExtras, b.mExtras);
- assertEquals(a.mRestrictedAccountType, b.mRestrictedAccountType);
- assertEquals(a.mRequiredAccountType, b.mRequiredAccountType);
- assertEquals(a.mOverlayTarget, b.mOverlayTarget);
- assertEquals(a.mOverlayTargetName, b.mOverlayTargetName);
- assertEquals(a.mOverlayCategory, b.mOverlayCategory);
- assertEquals(a.mOverlayPriority, b.mOverlayPriority);
- assertEquals(a.mOverlayIsStatic, b.mOverlayIsStatic);
- assertEquals(a.mSigningDetails.publicKeys, b.mSigningDetails.publicKeys);
- assertEquals(a.mUpgradeKeySets, b.mUpgradeKeySets);
- assertEquals(a.mKeySetMapping, b.mKeySetMapping);
- assertEquals(a.cpuAbiOverride, b.cpuAbiOverride);
- assertTrue(Arrays.equals(a.restrictUpdateHash, b.restrictUpdateHash));
+ assertEquals(a.getRequestedPermissions(), b.getRequestedPermissions());
+ assertEquals(a.getProtectedBroadcasts(), b.getProtectedBroadcasts());
+ assertEquals(a.getLibraryNames(), b.getLibraryNames());
+ assertEquals(a.getUsesLibraries(), b.getUsesLibraries());
+ assertEquals(a.getUsesOptionalLibraries(), b.getUsesOptionalLibraries());
+ assertArrayEquals(a.getUsesLibraryFiles(), b.getUsesLibraryFiles());
+ assertEquals(a.getOriginalPackages(), b.getOriginalPackages());
+ assertEquals(a.getRealPackage(), b.getRealPackage());
+ assertEquals(a.getAdoptPermissions(), b.getAdoptPermissions());
+ assertBundleApproximateEquals(a.getAppMetaData(), b.getAppMetaData());
+ assertEquals(a.getVersionName(), b.getVersionName());
+ assertEquals(a.getSharedUserId(), b.getSharedUserId());
+ assertArrayEquals(a.getSigningDetails().signatures, b.getSigningDetails().signatures);
+ assertArrayEquals(a.getLastPackageUsageTimeInMills(), b.getLastPackageUsageTimeInMills());
+ assertEquals(a.getRestrictedAccountType(), b.getRestrictedAccountType());
+ assertEquals(a.getRequiredAccountType(), b.getRequiredAccountType());
+ assertEquals(a.getOverlayTarget(), b.getOverlayTarget());
+ assertEquals(a.getOverlayTargetName(), b.getOverlayTargetName());
+ assertEquals(a.getOverlayCategory(), b.getOverlayCategory());
+ assertEquals(a.getOverlayPriority(), b.getOverlayPriority());
+ assertEquals(a.isOverlayIsStatic(), b.isOverlayIsStatic());
+ assertEquals(a.getSigningDetails().publicKeys, b.getSigningDetails().publicKeys);
+ assertEquals(a.getUpgradeKeySets(), b.getUpgradeKeySets());
+ assertEquals(a.getKeySetMapping(), b.getKeySetMapping());
+ assertEquals(a.getCpuAbiOverride(), b.getCpuAbiOverride());
+ assertArrayEquals(a.getRestrictUpdateHash(), b.getRestrictUpdateHash());
}
private static void assertBundleApproximateEquals(Bundle a, Bundle b) {
@@ -305,10 +333,10 @@ public class PackageParserTest {
assertEquals(a.toString(), b.toString());
}
- private static void assertComponentsEqual(PackageParser.Component<?> a,
- PackageParser.Component<?> b) {
+ private static void assertComponentsEqual(ParsedComponent<?> a,
+ ParsedComponent<?> b) {
assertEquals(a.className, b.className);
- assertBundleApproximateEquals(a.metaData, b.metaData);
+ assertBundleApproximateEquals(a.getMetaData(), b.getMetaData());
assertEquals(a.getComponentName(), b.getComponentName());
if (a.intents != null && b.intents != null) {
@@ -318,80 +346,104 @@ public class PackageParserTest {
}
for (int i = 0; i < a.intents.size(); ++i) {
- PackageParser.IntentInfo aIntent = a.intents.get(i);
- PackageParser.IntentInfo bIntent = b.intents.get(i);
+ ParsedIntentInfo aIntent = a.intents.get(i);
+ ParsedIntentInfo bIntent = b.intents.get(i);
assertEquals(aIntent.hasDefault, bIntent.hasDefault);
assertEquals(aIntent.labelRes, bIntent.labelRes);
assertEquals(aIntent.nonLocalizedLabel, bIntent.nonLocalizedLabel);
assertEquals(aIntent.icon, bIntent.icon);
- assertEquals(aIntent.logo, bIntent.logo);
- assertEquals(aIntent.banner, bIntent.banner);
- assertEquals(aIntent.preferred, bIntent.preferred);
}
}
- private static void assertPermissionsEqual(PackageParser.Permission a,
- PackageParser.Permission b) {
+ private static void assertPermissionsEqual(ParsedPermission a,
+ ParsedPermission b) {
assertComponentsEqual(a, b);
assertEquals(a.tree, b.tree);
// Verify basic flags in PermissionInfo to make sure they're consistent. We don't perform
// a full structural equality here because the code that serializes them isn't parser
// specific and is tested elsewhere.
- assertEquals(a.info.protectionLevel, b.info.protectionLevel);
- assertEquals(a.info.group, b.info.group);
- assertEquals(a.info.flags, b.info.flags);
+ assertEquals(a.getProtection(), b.getProtection());
+ assertEquals(a.getGroup(), b.getGroup());
+ assertEquals(a.flags, b.flags);
- if (a.group != null && b.group != null) {
- assertPermissionGroupsEqual(a.group, b.group);
- } else if (a.group != null || b.group != null) {
+ if (a.parsedPermissionGroup != null && b.parsedPermissionGroup != null) {
+ assertPermissionGroupsEqual(a.parsedPermissionGroup, b.parsedPermissionGroup);
+ } else if (a.parsedPermissionGroup != null || b.parsedPermissionGroup != null) {
throw new AssertionError();
}
}
- private static void assertInstrumentationEqual(PackageParser.Instrumentation a,
- PackageParser.Instrumentation b) {
+ private static void assertInstrumentationEqual(ParsedInstrumentation a,
+ ParsedInstrumentation b) {
assertComponentsEqual(a, b);
// Sanity check for InstrumentationInfo.
- assertEquals(a.info.targetPackage, b.info.targetPackage);
- assertEquals(a.info.targetProcesses, b.info.targetProcesses);
- assertEquals(a.info.sourceDir, b.info.sourceDir);
- assertEquals(a.info.publicSourceDir, b.info.publicSourceDir);
+ assertEquals(a.getTargetPackage(), b.getTargetPackage());
+ assertEquals(a.getTargetProcesses(), b.getTargetProcesses());
+ assertEquals(a.sourceDir, b.sourceDir);
+ assertEquals(a.publicSourceDir, b.publicSourceDir);
}
- private static void assertServicesEqual(PackageParser.Service a, PackageParser.Service b) {
+ private static void assertServicesEqual(
+ AndroidPackage aPkg,
+ ParsedService a,
+ AndroidPackage bPkg,
+ ParsedService b
+ ) {
assertComponentsEqual(a, b);
// Sanity check for ServiceInfo.
- assertApplicationInfoEqual(a.info.applicationInfo, b.info.applicationInfo);
- assertEquals(a.info.name, b.info.name);
+ ServiceInfo aInfo = PackageInfoUtils.generateServiceInfo(aPkg, a, 0, new PackageUserState(),
+ 0);
+ ServiceInfo bInfo = PackageInfoUtils.generateServiceInfo(bPkg, b, 0, new PackageUserState(),
+ 0);
+ assertApplicationInfoEqual(aInfo.applicationInfo, bInfo.applicationInfo);
+ assertEquals(a.getName(), b.getName());
}
- private static void assertProvidersEqual(PackageParser.Provider a, PackageParser.Provider b) {
+ private static void assertProvidersEqual(
+ AndroidPackage aPkg,
+ ParsedProvider a,
+ AndroidPackage bPkg,
+ ParsedProvider b
+ ) {
assertComponentsEqual(a, b);
// Sanity check for ProviderInfo
- assertApplicationInfoEqual(a.info.applicationInfo, b.info.applicationInfo);
- assertEquals(a.info.name, b.info.name);
+ ProviderInfo aInfo = PackageInfoUtils.generateProviderInfo(aPkg, a, 0,
+ new PackageUserState(), 0);
+ ProviderInfo bInfo = PackageInfoUtils.generateProviderInfo(bPkg, b, 0,
+ new PackageUserState(), 0);
+ assertApplicationInfoEqual(aInfo.applicationInfo, bInfo.applicationInfo);
+ assertEquals(a.getName(), b.getName());
}
- private static void assertActivitiesEqual(PackageParser.Activity a, PackageParser.Activity b) {
+ private static void assertActivitiesEqual(
+ AndroidPackage aPkg,
+ ParsedActivity a,
+ AndroidPackage bPkg,
+ ParsedActivity b
+ ) {
assertComponentsEqual(a, b);
// Sanity check for ActivityInfo.
- assertApplicationInfoEqual(a.info.applicationInfo, b.info.applicationInfo);
- assertEquals(a.info.name, b.info.name);
+ ActivityInfo aInfo = PackageInfoUtils.generateActivityInfo(aPkg, a, 0,
+ new PackageUserState(), 0);
+ ActivityInfo bInfo = PackageInfoUtils.generateActivityInfo(bPkg, b, 0,
+ new PackageUserState(), 0);
+ assertApplicationInfoEqual(aInfo.applicationInfo, bInfo.applicationInfo);
+ assertEquals(a.getName(), b.getName());
}
- private static void assertPermissionGroupsEqual(PackageParser.PermissionGroup a,
- PackageParser.PermissionGroup b) {
+ private static void assertPermissionGroupsEqual(ParsedPermissionGroup a,
+ ParsedPermissionGroup b) {
assertComponentsEqual(a, b);
// Sanity check for PermissionGroupInfo.
- assertEquals(a.info.name, b.info.name);
- assertEquals(a.info.descriptionRes, b.info.descriptionRes);
+ assertEquals(a.getName(), b.getName());
+ assertEquals(a.descriptionRes, b.descriptionRes);
}
private static void assertApplicationInfoEqual(ApplicationInfo a, ApplicationInfo that) {
@@ -424,11 +476,11 @@ public class PackageParserTest {
assertEquals(a.scanPublicSourceDir, that.scanPublicSourceDir);
assertEquals(a.sourceDir, that.sourceDir);
assertEquals(a.publicSourceDir, that.publicSourceDir);
- assertTrue(Arrays.equals(a.splitSourceDirs, that.splitSourceDirs));
- assertTrue(Arrays.equals(a.splitPublicSourceDirs, that.splitPublicSourceDirs));
- assertTrue(Arrays.equals(a.resourceDirs, that.resourceDirs));
+ assertArrayEquals(a.splitSourceDirs, that.splitSourceDirs);
+ assertArrayEquals(a.splitPublicSourceDirs, that.splitPublicSourceDirs);
+ assertArrayEquals(a.resourceDirs, that.resourceDirs);
assertEquals(a.seInfo, that.seInfo);
- assertTrue(Arrays.equals(a.sharedLibraryFiles, that.sharedLibraryFiles));
+ assertArrayEquals(a.sharedLibraryFiles, that.sharedLibraryFiles);
assertEquals(a.dataDir, that.dataDir);
assertEquals(a.deviceProtectedDataDir, that.deviceProtectedDataDir);
assertEquals(a.credentialProtectedDataDir, that.credentialProtectedDataDir);
@@ -439,132 +491,93 @@ public class PackageParserTest {
assertEquals(a.secondaryCpuAbi, that.secondaryCpuAbi);
}
- public static void setKnownFields(PackageParser.Package pkg) {
- pkg.baseRevisionCode = 100;
- pkg.baseHardwareAccelerated = true;
- pkg.mVersionCode = 100;
- pkg.mSharedUserLabel = 100;
- pkg.mPreferredOrder = 100;
- pkg.installLocation = 100;
- pkg.coreApp = true;
- pkg.mRequiredForAllUsers = true;
- pkg.use32bitAbi = true;
- pkg.packageName = "foo";
- pkg.splitNames = new String[] { "foo2" };
- pkg.volumeUuid = "foo3";
- pkg.codePath = "foo4";
- pkg.baseCodePath = "foo5";
- pkg.splitCodePaths = new String[] { "foo6" };
- pkg.splitRevisionCodes = new int[] { 100 };
- pkg.splitFlags = new int[] { 100 };
- pkg.splitPrivateFlags = new int[] { 100 };
- pkg.applicationInfo = new ApplicationInfo();
-
- pkg.permissions.add(new PackageParser.Permission(pkg, (String) null));
- pkg.permissionGroups.add(new PackageParser.PermissionGroup(pkg, ID_NULL, ID_NULL, ID_NULL));
-
- final PackageParser.ParseComponentArgs dummy = new PackageParser.ParseComponentArgs(
- pkg, new String[1], 0, 0, 0, 0, 0, 0, null, 0, 0, 0);
-
- pkg.activities.add(new PackageParser.Activity(dummy, new ActivityInfo()));
- pkg.receivers.add(new PackageParser.Activity(dummy, new ActivityInfo()));
- pkg.providers.add(new PackageParser.Provider(dummy, new ProviderInfo()));
- pkg.services.add(new PackageParser.Service(dummy, new ServiceInfo()));
- pkg.instrumentation.add(new PackageParser.Instrumentation(dummy, new InstrumentationInfo()));
- pkg.requestedPermissions.add("foo7");
- pkg.implicitPermissions.add("foo25");
-
- pkg.protectedBroadcasts = new ArrayList<>();
- pkg.protectedBroadcasts.add("foo8");
-
- pkg.parentPackage = new PackageParser.Package("foo9");
-
- pkg.childPackages = new ArrayList<>();
- pkg.childPackages.add(new PackageParser.Package("bar"));
-
- pkg.staticSharedLibName = "foo23";
- pkg.staticSharedLibVersion = 100;
- pkg.usesStaticLibraries = new ArrayList<>();
- pkg.usesStaticLibraries.add("foo23");
- pkg.usesStaticLibrariesCertDigests = new String[1][];
- pkg.usesStaticLibrariesCertDigests[0] = new String[] { "digest" };
- pkg.usesStaticLibrariesVersions = new long[] { 100 };
-
- pkg.libraryNames = new ArrayList<>();
- pkg.libraryNames.add("foo10");
-
- pkg.usesLibraries = new ArrayList<>();
- pkg.usesLibraries.add("foo11");
-
- pkg.usesOptionalLibraries = new ArrayList<>();
- pkg.usesOptionalLibraries.add("foo12");
-
- pkg.usesLibraryFiles = new String[] { "foo13"};
-
- pkg.usesLibraryInfos = new ArrayList<>();
- pkg.usesLibraryInfos.add(
- new SharedLibraryInfo(null, null, null, null, 0L, 0, null, null, null));
-
- pkg.mOriginalPackages = new ArrayList<>();
- pkg.mOriginalPackages.add("foo14");
-
- pkg.mRealPackage = "foo15";
-
- pkg.mAdoptPermissions = new ArrayList<>();
- pkg.mAdoptPermissions.add("foo16");
-
- pkg.mAppMetaData = new Bundle();
- pkg.mVersionName = "foo17";
- pkg.mSharedUserId = "foo18";
- pkg.mSigningDetails =
- new PackageParser.SigningDetails(
- new Signature[] { new Signature(new byte[16]) },
- 2,
- new ArraySet<>(),
- null);
- pkg.mExtras = new Bundle();
- pkg.mRestrictedAccountType = "foo19";
- pkg.mRequiredAccountType = "foo20";
- pkg.mOverlayTarget = "foo21";
- pkg.mOverlayPriority = 100;
- pkg.mUpgradeKeySets = new ArraySet<>();
- pkg.mKeySetMapping = new ArrayMap<>();
- pkg.cpuAbiOverride = "foo22";
- pkg.restrictUpdateHash = new byte[16];
-
- pkg.preferredActivityFilters = new ArrayList<>();
- pkg.preferredActivityFilters.add(new PackageParser.ActivityIntentInfo(
- new PackageParser.Activity(dummy, new ActivityInfo())));
-
- pkg.configPreferences = new ArrayList<>();
- pkg.configPreferences.add(new ConfigurationInfo());
-
- pkg.reqFeatures = new ArrayList<>();
- pkg.reqFeatures.add(new FeatureInfo());
-
- pkg.featureGroups = new ArrayList<>();
- pkg.featureGroups.add(new FeatureGroupInfo());
-
- pkg.mCompileSdkVersionCodename = "foo23";
- pkg.mCompileSdkVersion = 100;
- pkg.mVersionCodeMajor = 100;
-
- pkg.mOverlayCategory = "foo24";
- pkg.mOverlayIsStatic = true;
- pkg.mOverlayTargetName = "foo26";
-
- pkg.baseHardwareAccelerated = true;
- pkg.coreApp = true;
- pkg.mRequiredForAllUsers = true;
- pkg.visibleToInstantApps = true;
- pkg.use32bitAbi = true;
- pkg.mForceQueryable = true;
- pkg.mQueriesPackages = new ArrayList<>(Arrays.asList("foo27"));
- pkg.mQueriesIntents = new ArrayList<>(Arrays.asList(new Intent("foo28")));
+ public static void setKnownFields(ParsingPackage pkg) {
+ Bundle bundle = new Bundle();
+ bundle.putString("key", "value");
+
+ ParsedPermission permission = new ParsedPermission();
+ permission.parsedPermissionGroup = new ParsedPermissionGroup();
+
+ pkg.setBaseRevisionCode(100)
+ .setBaseHardwareAccelerated(true)
+ .setSharedUserLabel(100)
+ .setPreferredOrder(100)
+ .setInstallLocation(100)
+ .setRequiredForAllUsers(true)
+ .asSplit(
+ new String[]{"foo2"},
+ new String[]{"foo6"},
+ new int[]{100},
+ null
+ )
+ .setUse32BitAbi(true)
+ .setVolumeUuid("foo3")
+ .setCodePath("foo4")
+ .addPermission(permission)
+ .addPermissionGroup(new ParsedPermissionGroup())
+ .addActivity(new ParsedActivity())
+ .addReceiver(new ParsedActivity())
+ .addProvider(new ParsedProvider())
+ .addService(new ParsedService())
+ .addInstrumentation(new ParsedInstrumentation())
+ .addRequestedPermission("foo7")
+ .addImplicitPermission("foo25")
+ .addProtectedBroadcast("foo8")
+ .setStaticSharedLibName("foo23")
+ .setStaticSharedLibVersion(100)
+ .addUsesStaticLibrary("foo23")
+ .addUsesStaticLibraryCertDigests(new String[]{"digest"})
+ .addUsesStaticLibraryVersion(100)
+ .addLibraryName("foo10")
+ .addUsesLibrary("foo11")
+ .addUsesOptionalLibrary("foo12")
+ .addOriginalPackage("foo14")
+ .setRealPackage("foo15")
+ .addAdoptPermission("foo16")
+ .setAppMetaData(bundle)
+ .setVersionName("foo17")
+ .setSharedUserId("foo18")
+ .setSigningDetails(
+ new PackageParser.SigningDetails(
+ new Signature[]{new Signature(new byte[16])},
+ 2,
+ new ArraySet<>(),
+ null)
+ )
+ .setRestrictedAccountType("foo19")
+ .setRequiredAccountType("foo20")
+ .setOverlayTarget("foo21")
+ .setOverlayPriority(100)
+ .setUpgradeKeySets(new ArraySet<>())
+ .addPreferredActivityFilter(
+ new ComponentParseUtils.ParsedActivityIntentInfo("foo", "className"))
+ .addConfigPreference(new ConfigurationInfo())
+ .addReqFeature(new FeatureInfo())
+ .addFeatureGroup(new FeatureGroupInfo())
+ .setCompileSdkVersionCodename("foo23")
+ .setCompileSdkVersion(100)
+ .setOverlayCategory("foo24")
+ .setOverlayIsStatic(true)
+ .setOverlayTargetName("foo26")
+ .setVisibleToInstantApps(true)
+ .setSplitHasCode(0, true)
+ .hideAsParsed()
+ .setBaseCodePath("foo5")
+ .setVersionCode(100)
+ .setCpuAbiOverride("foo22")
+ .setRestrictUpdateHash(new byte[16])
+ .setVersionCodeMajor(100)
+ .setCoreApp(true)
+ .hideAsFinal()
+ .mutate()
+ .setUsesLibraryInfos(Arrays.asList(
+ new SharedLibraryInfo(null, null, null, null, 0L, 0, null, null, null)
+ ))
+ .setUsesLibraryFiles(new String[]{"foo13"});
}
- private static void assertAllFieldsExist(PackageParser.Package pkg) throws Exception {
- Field[] fields = PackageParser.Package.class.getDeclaredFields();
+ private static void assertAllFieldsExist(ParsedPackage pkg) throws Exception {
+ Field[] fields = ParsedPackage.class.getDeclaredFields();
Set<String> nonSerializedFields = new HashSet<>();
nonSerializedFields.add("mExtras");
@@ -601,7 +614,7 @@ public class PackageParserTest {
} else if (fieldType == boolean.class) {
// boolean fields: Check that they're set to true.
boolean value = (boolean) f.get(pkg);
- assertEquals("Bad value for field: " + f, true, value);
+ assertTrue("Bad value for field: " + f, value);
} else {
// All other fields: Check that they're set.
Object o = f.get(pkg);
diff --git a/services/tests/servicestests/src/com/android/server/pm/PackageSettingBuilder.java b/services/tests/servicestests/src/com/android/server/pm/PackageSettingBuilder.java
index 06c6314ab907..ca9e5b1efb58 100644
--- a/services/tests/servicestests/src/com/android/server/pm/PackageSettingBuilder.java
+++ b/services/tests/servicestests/src/com/android/server/pm/PackageSettingBuilder.java
@@ -16,12 +16,11 @@
package com.android.server.pm;
-import android.content.pm.PackageParser;
import android.content.pm.PackageUserState;
+import android.content.pm.parsing.AndroidPackage;
import android.util.SparseArray;
import java.io.File;
-import java.util.List;
class PackageSettingBuilder {
private String mName;
@@ -35,16 +34,14 @@ class PackageSettingBuilder {
private long mPVersionCode;
private int mPkgFlags;
private int mPrivateFlags;
- private String mParentPackageName;
- private List<String> mChildPackageNames;
private int mSharedUserId;
private String[] mUsesStaticLibraries;
private long[] mUsesStaticLibrariesVersions;
private String mVolumeUuid;
private SparseArray<PackageUserState> mUserStates = new SparseArray<>();
- private PackageParser.Package mPkg;
+ private AndroidPackage mPkg;
- public PackageSettingBuilder setPackage(PackageParser.Package pkg) {
+ public PackageSettingBuilder setPackage(AndroidPackage pkg) {
this.mPkg = pkg;
return this;
}
@@ -105,16 +102,6 @@ class PackageSettingBuilder {
return this;
}
- public PackageSettingBuilder setParentPackageName(String parentPackageName) {
- this.mParentPackageName = parentPackageName;
- return this;
- }
-
- public PackageSettingBuilder setChildPackageNames(List<String> childPackageNames) {
- this.mChildPackageNames = childPackageNames;
- return this;
- }
-
public PackageSettingBuilder setSharedUserId(int sharedUserId) {
this.mSharedUserId = sharedUserId;
return this;
@@ -148,9 +135,8 @@ class PackageSettingBuilder {
final PackageSetting packageSetting = new PackageSetting(mName, mRealName,
new File(mCodePath), new File(mResourcePath),
mLegacyNativeLibraryPathString, mPrimaryCpuAbiString, mSecondaryCpuAbiString,
- mCpuAbiOverrideString, mPVersionCode, mPkgFlags, mPrivateFlags, mParentPackageName,
- mChildPackageNames, mSharedUserId, mUsesStaticLibraries,
- mUsesStaticLibrariesVersions);
+ mCpuAbiOverrideString, mPVersionCode, mPkgFlags, mPrivateFlags, mSharedUserId,
+ mUsesStaticLibraries, mUsesStaticLibrariesVersions);
packageSetting.pkg = mPkg;
packageSetting.volumeUuid = this.mVolumeUuid;
for (int i = 0; i < mUserStates.size(); i++) {
diff --git a/services/tests/servicestests/src/com/android/server/pm/PackageSignaturesTest.java b/services/tests/servicestests/src/com/android/server/pm/PackageSignaturesTest.java
index d3a77d3e80f1..04e769d7dcfb 100644
--- a/services/tests/servicestests/src/com/android/server/pm/PackageSignaturesTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/PackageSignaturesTest.java
@@ -16,8 +16,8 @@
package com.android.server.pm;
import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
@@ -467,8 +467,7 @@ public class PackageSignaturesTest {
File appPath = new File("/data/app/app");
PackageSetting result = new PackageSetting("test.app", null, appPath, appPath,
"/data/app/app", null, null, null,
- 1, 940097092, 0, null,
- null, 0 /*userId*/, null, null);
+ 1, 940097092, 0, 0 /*userId*/, null, null);
return result;
}
}
diff --git a/services/tests/servicestests/src/com/android/server/pm/ParallelPackageParserTest.java b/services/tests/servicestests/src/com/android/server/pm/ParallelPackageParserTest.java
index 41489dc42a6a..a0efc8a03719 100644
--- a/services/tests/servicestests/src/com/android/server/pm/ParallelPackageParserTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/ParallelPackageParserTest.java
@@ -17,6 +17,7 @@
package com.android.server.pm;
import android.content.pm.PackageParser;
+import android.content.pm.parsing.ParsedPackage;
import android.util.Log;
import androidx.test.runner.AndroidJUnit4;
@@ -74,7 +75,7 @@ public class ParallelPackageParserTest {
}
@Override
- protected PackageParser.Package parsePackage(PackageParser packageParser, File scanFile,
+ protected ParsedPackage parsePackage(PackageParser packageParser, File scanFile,
int parseFlags) throws PackageParser.PackageParserException {
// Do not actually parse the package for testing
return null;
diff --git a/services/tests/servicestests/src/com/android/server/pm/ScanRequestBuilder.java b/services/tests/servicestests/src/com/android/server/pm/ScanRequestBuilder.java
index 34a3f860496a..11f154be688b 100644
--- a/services/tests/servicestests/src/com/android/server/pm/ScanRequestBuilder.java
+++ b/services/tests/servicestests/src/com/android/server/pm/ScanRequestBuilder.java
@@ -16,12 +16,13 @@
package com.android.server.pm;
-import android.content.pm.PackageParser;
+import android.content.pm.parsing.AndroidPackage;
+import android.content.pm.parsing.ParsedPackage;
import android.os.UserHandle;
class ScanRequestBuilder {
- private final PackageParser.Package mPkg;
- private PackageParser.Package mOldPkg;
+ private final ParsedPackage mPkg;
+ private AndroidPackage mOldPkg;
private SharedUserSetting mSharedUserSetting;
private PackageSetting mPkgSetting;
private PackageSetting mDisabledPkgSetting;
@@ -32,11 +33,11 @@ class ScanRequestBuilder {
private UserHandle mUser;
private boolean mIsPlatformPackage;
- ScanRequestBuilder(PackageParser.Package pkg) {
+ ScanRequestBuilder(ParsedPackage pkg) {
this.mPkg = pkg;
}
- public ScanRequestBuilder setOldPkg(PackageParser.Package oldPkg) {
+ public ScanRequestBuilder setOldPkg(AndroidPackage oldPkg) {
this.mOldPkg = oldPkg;
return this;
}
diff --git a/services/tests/servicestests/src/com/android/server/pm/ScanTests.java b/services/tests/servicestests/src/com/android/server/pm/ScanTests.java
index 05905d94dda7..1f027a31fbe3 100644
--- a/services/tests/servicestests/src/com/android/server/pm/ScanTests.java
+++ b/services/tests/servicestests/src/com/android/server/pm/ScanTests.java
@@ -35,13 +35,17 @@ import static org.junit.Assert.assertNotSame;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.ArgumentMatchers.anyBoolean;
import static org.mockito.ArgumentMatchers.nullable;
+import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import android.Manifest;
import android.content.pm.ApplicationInfo;
import android.content.pm.PackageInfo;
-import android.content.pm.PackageParser;
import android.content.pm.SharedLibraryInfo;
+import android.content.pm.parsing.PackageImpl;
+import android.content.pm.parsing.ParsedPackage;
+import android.content.pm.parsing.ParsingPackage;
+import android.content.res.TypedArray;
import android.os.Environment;
import android.os.UserHandle;
import android.os.UserManagerInternal;
@@ -58,6 +62,7 @@ import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import java.io.File;
+import java.util.UUID;
@RunWith(MockitoJUnitRunner.class)
@Presubmit
@@ -66,6 +71,9 @@ public class ScanTests {
private static final String DUMMY_PACKAGE_NAME = "some.app.to.test";
+ private static final UUID UUID_ONE = UUID.randomUUID();
+ private static final UUID UUID_TWO = UUID.randomUUID();
+
@Mock
PackageAbiHelper mMockPackageAbiHelper;
@Mock
@@ -87,25 +95,25 @@ public class ScanTests {
@Before
public void setupDefaultAbiBehavior() throws Exception {
when(mMockPackageAbiHelper.derivePackageAbi(
- any(PackageParser.Package.class), nullable(String.class), anyBoolean()))
+ any(ParsedPackage.class), nullable(String.class), anyBoolean()))
.thenReturn(new Pair<>(
new PackageAbiHelper.Abis("derivedPrimary", "derivedSecondary"),
new PackageAbiHelper.NativeLibraryPaths(
"derivedRootDir", true, "derivedNativeDir", "derivedNativeDir2")));
when(mMockPackageAbiHelper.getNativeLibraryPaths(
- any(PackageParser.Package.class), any(File.class)))
+ any(ParsedPackage.class), any(File.class)))
.thenReturn(new PackageAbiHelper.NativeLibraryPaths(
"getRootDir", true, "getNativeDir", "getNativeDir2"
));
when(mMockPackageAbiHelper.getBundledAppAbis(
- any(PackageParser.Package.class)))
+ any(ParsedPackage.class)))
.thenReturn(new PackageAbiHelper.Abis("bundledPrimary", "bundledSecondary"));
}
@Test
public void newInstallSimpleAllNominal() throws Exception {
final PackageManagerService.ScanRequest scanRequest =
- createBasicScanRequestBuilder(createBasicPackage(DUMMY_PACKAGE_NAME).build())
+ createBasicScanRequestBuilder(createBasicPackage(DUMMY_PACKAGE_NAME))
.addScanFlag(PackageManagerService.SCAN_NEW_INSTALL)
.addScanFlag(PackageManagerService.SCAN_AS_FULL_APP)
.build();
@@ -123,7 +131,7 @@ public class ScanTests {
when(mMockUserManager.getUserIds()).thenReturn(userIds);
final PackageManagerService.ScanRequest scanRequest =
- createBasicScanRequestBuilder(createBasicPackage(DUMMY_PACKAGE_NAME).build())
+ createBasicScanRequestBuilder(createBasicPackage(DUMMY_PACKAGE_NAME))
.setRealPkgName(null)
.addScanFlag(PackageManagerService.SCAN_NEW_INSTALL)
.addScanFlag(PackageManagerService.SCAN_AS_FULL_APP)
@@ -138,7 +146,7 @@ public class ScanTests {
@Test
public void installRealPackageName() throws Exception {
final PackageManagerService.ScanRequest scanRequest =
- createBasicScanRequestBuilder(createBasicPackage(DUMMY_PACKAGE_NAME).build())
+ createBasicScanRequestBuilder(createBasicPackage(DUMMY_PACKAGE_NAME))
.setRealPkgName("com.package.real")
.build();
@@ -149,7 +157,7 @@ public class ScanTests {
final PackageManagerService.ScanRequest scanRequestNoRealPkg =
createBasicScanRequestBuilder(
createBasicPackage(DUMMY_PACKAGE_NAME)
- .setRealPackageName("com.package.real").build())
+ .setRealPackage("com.package.real"))
.build();
final PackageManagerService.ScanResult scanResultNoReal = executeScan(scanRequestNoRealPkg);
@@ -165,7 +173,7 @@ public class ScanTests {
.setSecondaryCpuAbiString("secondaryCpuAbi")
.build();
final PackageManagerService.ScanRequest scanRequest =
- createBasicScanRequestBuilder(createBasicPackage(DUMMY_PACKAGE_NAME).build())
+ createBasicScanRequestBuilder(createBasicPackage(DUMMY_PACKAGE_NAME))
.addScanFlag(PackageManagerService.SCAN_AS_FULL_APP)
.setPkgSetting(pkgSetting)
.build();
@@ -197,7 +205,7 @@ public class ScanTests {
.build();
final PackageManagerService.ScanRequest scanRequest =
- createBasicScanRequestBuilder(createBasicPackage(DUMMY_PACKAGE_NAME).build())
+ createBasicScanRequestBuilder(createBasicPackage(DUMMY_PACKAGE_NAME))
.setPkgSetting(existingPkgSetting)
.build();
@@ -209,17 +217,18 @@ public class ScanTests {
@Test
public void installStaticSharedLibrary() throws Exception {
- final PackageParser.Package pkg = createBasicPackage("static.lib.pkg.123")
- .setStaticSharedLib("static.lib", 123L)
- .setManifestPackageName("static.lib.pkg")
+ final ParsedPackage pkg = createBasicPackage("static.lib.pkg")
+ .setStaticSharedLibName("static.lib")
+ .setStaticSharedLibVersion(123L)
+ .hideAsParsed()
+ .setPackageName("static.lib.pkg.123")
.setVersionCodeMajor(1)
.setVersionCode(234)
.setBaseCodePath("/some/path.apk")
- .addSplitCodePath("/some/other/path.apk")
- .build();
+ .setSplitCodePaths(new String[] {"/some/other/path.apk"});
- final PackageManagerService.ScanRequest scanRequest = new ScanRequestBuilder(
- pkg).setUser(UserHandle.of(0)).build();
+ final PackageManagerService.ScanRequest scanRequest = new ScanRequestBuilder(pkg)
+ .setUser(UserHandle.of(0)).build();
final PackageManagerService.ScanResult scanResult = executeScan(scanRequest);
@@ -240,15 +249,14 @@ public class ScanTests {
@Test
public void installDynamicLibraries() throws Exception {
- final PackageParser.Package pkg = createBasicPackage("dynamic.lib.pkg")
- .setManifestPackageName("dynamic.lib.pkg")
+ final ParsedPackage pkg = createBasicPackage("dynamic.lib.pkg")
.addLibraryName("liba")
.addLibraryName("libb")
+ .hideAsParsed()
.setVersionCodeMajor(1)
.setVersionCode(234)
.setBaseCodePath("/some/path.apk")
- .addSplitCodePath("/some/other/path.apk")
- .build();
+ .setSplitCodePaths(new String[] {"/some/other/path.apk"});
final PackageManagerService.ScanRequest scanRequest =
new ScanRequestBuilder(pkg).setUser(UserHandle.of(0)).build();
@@ -290,15 +298,15 @@ public class ScanTests {
.setVolumeUuid("someUuid")
.build();
- final PackageParser.Package basicPackage = createBasicPackage(DUMMY_PACKAGE_NAME)
- .setApplicationInfoVolumeUuid("someNewUuid")
- .build();
+ final ParsedPackage basicPackage = createBasicPackage(DUMMY_PACKAGE_NAME)
+ .hideAsParsed()
+ .setApplicationVolumeUuid(UUID_TWO.toString());
final PackageManagerService.ScanResult scanResult = executeScan(
new ScanRequestBuilder(basicPackage).setPkgSetting(pkgSetting).build());
- assertThat(scanResult.pkgSetting.volumeUuid, is("someNewUuid"));
+ assertThat(scanResult.pkgSetting.volumeUuid, is(UUID_TWO.toString()));
}
@Test
@@ -306,10 +314,10 @@ public class ScanTests {
final PackageSetting pkgSetting =
createBasicPackageSettingBuilder(DUMMY_PACKAGE_NAME).build();
- final PackageParser.Package basicPackage =
+ final ParsedPackage basicPackage =
createBasicPackage(DUMMY_PACKAGE_NAME)
- .setCpuAbiOVerride("testOverride")
- .build();
+ .hideAsParsed()
+ .setCpuAbiOverride("testOverride");
final PackageManagerService.ScanResult scanResult = executeScan(new ScanRequestBuilder(
@@ -326,9 +334,9 @@ public class ScanTests {
final PackageSetting originalPkgSetting =
createBasicPackageSettingBuilder("original.package").build();
- final PackageParser.Package basicPackage =
+ final ParsedPackage basicPackage =
createBasicPackage(DUMMY_PACKAGE_NAME)
- .build();
+ .hideAsParsed();
final PackageManagerService.ScanResult result =
@@ -336,7 +344,7 @@ public class ScanTests {
.setOriginalPkgSetting(originalPkgSetting)
.build());
- assertThat(result.request.pkg.packageName, is("original.package"));
+ assertThat(result.request.parsedPackage.getPackageName(), is("original.package"));
}
@Test
@@ -349,7 +357,7 @@ public class ScanTests {
.build();
final PackageManagerService.ScanRequest scanRequest =
- createBasicScanRequestBuilder(createBasicPackage(DUMMY_PACKAGE_NAME).build())
+ createBasicScanRequestBuilder(createBasicPackage(DUMMY_PACKAGE_NAME))
.setPkgSetting(existingPkgSetting)
.addScanFlag(SCAN_AS_FULL_APP)
.build();
@@ -370,7 +378,7 @@ public class ScanTests {
.build();
final PackageManagerService.ScanRequest scanRequest =
- createBasicScanRequestBuilder(createBasicPackage(DUMMY_PACKAGE_NAME).build())
+ createBasicScanRequestBuilder(createBasicPackage(DUMMY_PACKAGE_NAME))
.setPkgSetting(existingPkgSetting)
.addScanFlag(SCAN_AS_INSTANT_APP)
.build();
@@ -389,7 +397,7 @@ public class ScanTests {
.build();
final PackageManagerService.ScanRequest scanRequest =
- createBasicScanRequestBuilder(createBasicPackage(DUMMY_PACKAGE_NAME).build())
+ createBasicScanRequestBuilder(createBasicPackage(DUMMY_PACKAGE_NAME))
.setPkgSetting(existingPkgSetting)
.setDisabledPkgSetting(existingPkgSetting)
.addScanFlag(SCAN_NEW_INSTALL)
@@ -397,15 +405,14 @@ public class ScanTests {
final PackageManagerService.ScanResult scanResult = executeScan(scanRequest);
- assertThat(scanResult.request.pkg.applicationInfo.flags,
+ assertThat(scanResult.request.parsedPackage.getFlags(),
hasFlag(ApplicationInfo.FLAG_UPDATED_SYSTEM_APP));
}
@Test
public void factoryTestFlagSet() throws Exception {
- final PackageParser.Package basicPackage = createBasicPackage(DUMMY_PACKAGE_NAME)
- .addPermissionRequest(Manifest.permission.FACTORY_TEST)
- .build();
+ final ParsingPackage basicPackage = createBasicPackage(DUMMY_PACKAGE_NAME)
+ .addRequestedPermission(Manifest.permission.FACTORY_TEST);
final PackageManagerService.ScanResult scanResult = PackageManagerService.scanPackageOnlyLI(
createBasicScanRequestBuilder(basicPackage).build(),
@@ -413,15 +420,15 @@ public class ScanTests {
true /*isUnderFactoryTest*/,
System.currentTimeMillis());
- assertThat(scanResult.request.pkg.applicationInfo.flags,
+ assertThat(scanResult.request.parsedPackage.getFlags(),
hasFlag(ApplicationInfo.FLAG_FACTORY_TEST));
}
@Test
public void scanSystemApp_isOrphanedTrue() throws Exception {
- final PackageParser.Package pkg = createBasicPackage(DUMMY_PACKAGE_NAME)
- .addApplicationInfoFlag(ApplicationInfo.FLAG_SYSTEM)
- .build();
+ final ParsedPackage pkg = createBasicPackage(DUMMY_PACKAGE_NAME)
+ .hideAsParsed()
+ .setSystem(true);
final PackageManagerService.ScanRequest scanRequest =
createBasicScanRequestBuilder(pkg)
@@ -476,22 +483,29 @@ public class ScanTests {
.setResourcePath(createResourcePath(packageName));
}
- private static ScanRequestBuilder createBasicScanRequestBuilder(PackageParser.Package pkg) {
- return new ScanRequestBuilder(pkg)
+ private static ScanRequestBuilder createBasicScanRequestBuilder(ParsingPackage pkg) {
+ return new ScanRequestBuilder(pkg.hideAsParsed())
.setUser(UserHandle.of(0));
}
+ private static ScanRequestBuilder createBasicScanRequestBuilder(ParsedPackage pkg) {
+ return new ScanRequestBuilder(pkg)
+ .setUser(UserHandle.of(0));
+ }
- private static PackageBuilder createBasicPackage(String packageName) {
- return new PackageBuilder(packageName)
+ private static ParsingPackage createBasicPackage(String packageName) {
+ // TODO(b/135203078): Make this use PackageImpl.forParsing and separate the steps
+ return new PackageImpl(packageName, null, mock(TypedArray.class), false)
.setCodePath("/data/tmp/randompath")
.setApplicationInfoCodePath(createCodePath(packageName))
.setApplicationInfoResourcePath(createResourcePath(packageName))
- .setApplicationInfoVolumeUuid("volumeUuid")
+ .setApplicationVolumeUuid(UUID_ONE.toString())
.setBaseCodePath("/data/tmp/randompath/base.apk")
- .addUsesStaticLibrary("some.static.library", 234L)
- .addUsesStaticLibrary("some.other.static.library", 456L)
- .setApplicationInfoNativeLibraryRootDir("/data/tmp/randompath/base.apk:/lib")
+ .addUsesStaticLibrary("some.static.library")
+ .addUsesStaticLibraryVersion(234L)
+ .addUsesStaticLibrary("some.other.static.library")
+ .addUsesStaticLibraryVersion(456L)
+ .setNativeLibraryRootDir("/data/tmp/randompath/base.apk:/lib")
.setVersionCodeMajor(1)
.setVersionCode(2345);
}
@@ -503,20 +517,18 @@ public class ScanTests {
final PackageSetting pkgSetting = scanResult.pkgSetting;
assertBasicPackageSetting(scanResult, packageName, isInstant, pkgSetting);
- final ApplicationInfo applicationInfo = pkgSetting.pkg.applicationInfo;
+ final ApplicationInfo applicationInfo = pkgSetting.pkg.toAppInfo();
assertBasicApplicationInfo(scanResult, applicationInfo);
-
}
private static void assertBasicPackageSetting(PackageManagerService.ScanResult scanResult,
String packageName, boolean isInstant, PackageSetting pkgSetting) {
- assertThat(pkgSetting.pkg.packageName, is(packageName));
+ assertThat(pkgSetting.pkg.getPackageName(), is(packageName));
assertThat(pkgSetting.getInstantApp(0), is(isInstant));
assertThat(pkgSetting.usesStaticLibraries,
arrayContaining("some.static.library", "some.other.static.library"));
assertThat(pkgSetting.usesStaticLibrariesVersions, is(new long[]{234L, 456L}));
- assertThat(pkgSetting.pkg, is(scanResult.request.pkg));
- assertThat(pkgSetting.pkg.mExtras, is(pkgSetting));
+ assertThat(pkgSetting.pkg, is(scanResult.request.parsedPackage));
assertThat(pkgSetting.codePath, is(new File(createCodePath(packageName))));
assertThat(pkgSetting.resourcePath, is(new File(createResourcePath(packageName))));
assertThat(pkgSetting.versionCode, is(PackageInfo.composeLongVersionCode(1, 2345)));
@@ -524,20 +536,21 @@ public class ScanTests {
private static void assertBasicApplicationInfo(PackageManagerService.ScanResult scanResult,
ApplicationInfo applicationInfo) {
- assertThat(applicationInfo.processName, is(scanResult.request.pkg.packageName));
+ assertThat(applicationInfo.processName,
+ is(scanResult.request.parsedPackage.getPackageName()));
final int uid = applicationInfo.uid;
assertThat(UserHandle.getUserId(uid), is(UserHandle.USER_SYSTEM));
final String calculatedCredentialId = Environment.getDataUserCePackageDirectory(
applicationInfo.volumeUuid, UserHandle.USER_SYSTEM,
- scanResult.request.pkg.packageName).getAbsolutePath();
+ scanResult.request.parsedPackage.getPackageName()).getAbsolutePath();
assertThat(applicationInfo.credentialProtectedDataDir, is(calculatedCredentialId));
assertThat(applicationInfo.dataDir, is(applicationInfo.credentialProtectedDataDir));
}
private static void assertAbiAndPathssDerived(PackageManagerService.ScanResult scanResult) {
- final ApplicationInfo applicationInfo = scanResult.pkgSetting.pkg.applicationInfo;
+ final ApplicationInfo applicationInfo = scanResult.pkgSetting.pkg.toAppInfo();
assertThat(applicationInfo.primaryCpuAbi, is("derivedPrimary"));
assertThat(applicationInfo.secondaryCpuAbi, is("derivedSecondary"));
@@ -549,7 +562,7 @@ public class ScanTests {
}
private static void assertPathsNotDerived(PackageManagerService.ScanResult scanResult) {
- final ApplicationInfo applicationInfo = scanResult.pkgSetting.pkg.applicationInfo;
+ final ApplicationInfo applicationInfo = scanResult.pkgSetting.pkg.toAppInfo();
assertThat(applicationInfo.nativeLibraryRootDir, is("getRootDir"));
assertThat(scanResult.pkgSetting.legacyNativeLibraryPathString, is("getRootDir"));
assertThat(applicationInfo.nativeLibraryRootRequiresIsa, is(true));
diff --git a/services/tests/servicestests/src/com/android/server/pm/UserSystemPackageInstallerTest.java b/services/tests/servicestests/src/com/android/server/pm/UserSystemPackageInstallerTest.java
index f0b0328ff7d4..ddda10ec19d5 100644
--- a/services/tests/servicestests/src/com/android/server/pm/UserSystemPackageInstallerTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/UserSystemPackageInstallerTest.java
@@ -37,8 +37,9 @@ import static org.junit.Assert.fail;
import android.content.Context;
import android.content.pm.PackageInfo;
import android.content.pm.PackageManager;
-import android.content.pm.PackageParser;
import android.content.pm.UserInfo;
+import android.content.pm.parsing.AndroidPackage;
+import android.content.pm.parsing.PackageImpl;
import android.os.Looper;
import android.os.SystemProperties;
import android.os.UserManager;
@@ -220,10 +221,10 @@ public class UserSystemPackageInstallerTest {
final UserSystemPackageInstaller uspi = new UserSystemPackageInstaller(null, pkgFlgMap);
- final PackageParser.Package pkg1 = new PackageParser.Package(packageName1);
- final PackageParser.Package pkg2 = new PackageParser.Package(packageName2);
- final PackageParser.Package pkg3 = new PackageParser.Package(packageName3);
- final PackageParser.Package pkg4 = new PackageParser.Package(packageName4);
+ final AndroidPackage pkg1 = PackageImpl.forParsing(packageName1).hideAsParsed().hideAsFinal();
+ final AndroidPackage pkg2 = PackageImpl.forParsing(packageName2).hideAsParsed().hideAsFinal();
+ final AndroidPackage pkg3 = PackageImpl.forParsing(packageName3).hideAsParsed().hideAsFinal();
+ final AndroidPackage pkg4 = PackageImpl.forParsing(packageName4).hideAsParsed().hideAsFinal();
// No implicit whitelist, so only install pkg1.
boolean implicit = false;
diff --git a/services/tests/servicestests/src/com/android/server/pm/dex/DexoptUtilsTest.java b/services/tests/servicestests/src/com/android/server/pm/dex/DexoptUtilsTest.java
index 3a55c2290157..66a4946ecc20 100644
--- a/services/tests/servicestests/src/com/android/server/pm/dex/DexoptUtilsTest.java
+++ b/services/tests/servicestests/src/com/android/server/pm/dex/DexoptUtilsTest.java
@@ -22,8 +22,11 @@ import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
-import android.content.pm.ApplicationInfo;
import android.content.pm.SharedLibraryInfo;
+import android.content.pm.parsing.AndroidPackage;
+import android.content.pm.parsing.PackageImpl;
+import android.content.pm.parsing.ParsedPackage;
+import android.content.pm.parsing.ParsingPackage;
import android.util.SparseArray;
import androidx.test.filters.SmallTest;
@@ -51,17 +54,18 @@ public class DexoptUtilsTest {
DelegateLastClassLoader.class.getName();
private static class TestData {
- ApplicationInfo info;
+ AndroidPackage pkg;
boolean[] pathsWithCode;
}
private TestData createMockApplicationInfo(String baseClassLoader, boolean addSplits,
- boolean addSplitDependencies) {
- ApplicationInfo ai = new ApplicationInfo();
+ boolean addSplitDependencies, boolean isolatedSplitLoading) {
String codeDir = "/data/app/mock.android.com";
- ai.setBaseCodePath(codeDir + "/base.dex");
- ai.classLoaderName = baseClassLoader;
- ai.privateFlags = ai.privateFlags | ApplicationInfo.PRIVATE_FLAG_ISOLATED_SPLIT_LOADING;
+ ParsingPackage parsingPackage = PackageImpl.forParsing("mock.android.com")
+ .setClassLoaderName(baseClassLoader);
+
+ parsingPackage.setIsolatedSplitLoading(isolatedSplitLoading);
+
boolean[] pathsWithCode;
if (!addSplits) {
pathsWithCode = new boolean[] {true};
@@ -70,7 +74,7 @@ public class DexoptUtilsTest {
Arrays.fill(pathsWithCode, true);
pathsWithCode[7] = false; // config split
- ai.setSplitCodePaths(new String[]{
+ String[] splitCodePaths = new String[]{
codeDir + "/base-1.dex",
codeDir + "/base-2.dex",
codeDir + "/base-3.dex",
@@ -78,32 +82,51 @@ public class DexoptUtilsTest {
codeDir + "/base-5.dex",
codeDir + "/base-6.dex",
codeDir + "/config-split-7.dex",
- codeDir + "/feature-no-deps.dex"});
-
- ai.splitClassLoaderNames = new String[]{
- DELEGATE_LAST_CLASS_LOADER_NAME,
- DELEGATE_LAST_CLASS_LOADER_NAME,
- PATH_CLASS_LOADER_NAME,
- DEX_CLASS_LOADER_NAME,
- PATH_CLASS_LOADER_NAME,
- null, // A null class loader name should default to PathClassLoader.
- null, // The config split gets a null class loader.
- null}; // The feature split with no dependency and no specified class loader.
+ codeDir + "/feature-no-deps.dex"
+ };
+
+ String[] splitNames = new String[splitCodePaths.length];
+ int[] splitRevisionCodes = new int[splitCodePaths.length];
+ SparseArray<int[]> splitDependencies = null;
+
if (addSplitDependencies) {
- ai.splitDependencies = new SparseArray<>(ai.splitClassLoaderNames.length + 1);
- ai.splitDependencies.put(0, new int[] {-1}); // base has no dependency
- ai.splitDependencies.put(1, new int[] {2}); // split 1 depends on 2
- ai.splitDependencies.put(2, new int[] {4}); // split 2 depends on 4
- ai.splitDependencies.put(3, new int[] {4}); // split 3 depends on 4
- ai.splitDependencies.put(4, new int[] {0}); // split 4 depends on base
- ai.splitDependencies.put(5, new int[] {0}); // split 5 depends on base
- ai.splitDependencies.put(6, new int[] {5}); // split 6 depends on 5
+ splitDependencies = new SparseArray<>(splitCodePaths.length);
+ splitDependencies.put(0, new int[] {-1}); // base has no dependency
+ splitDependencies.put(1, new int[] {2}); // split 1 depends on 2
+ splitDependencies.put(2, new int[] {4}); // split 2 depends on 4
+ splitDependencies.put(3, new int[] {4}); // split 3 depends on 4
+ splitDependencies.put(4, new int[] {0}); // split 4 depends on base
+ splitDependencies.put(5, new int[] {0}); // split 5 depends on base
+ splitDependencies.put(6, new int[] {5}); // split 6 depends on 5
// Do not add the config split to the dependency list.
// Do not add the feature split with no dependency to the dependency list.
}
+
+ parsingPackage
+ .asSplit(
+ splitNames,
+ splitCodePaths,
+ splitRevisionCodes,
+ splitDependencies
+ )
+ .setSplitClassLoaderName(0, DELEGATE_LAST_CLASS_LOADER_NAME)
+ .setSplitClassLoaderName(1, DELEGATE_LAST_CLASS_LOADER_NAME)
+ .setSplitClassLoaderName(2, PATH_CLASS_LOADER_NAME)
+ .setSplitClassLoaderName(3, DEX_CLASS_LOADER_NAME)
+ .setSplitClassLoaderName(4, PATH_CLASS_LOADER_NAME)
+ // A null class loader name should default to PathClassLoader
+ .setSplitClassLoaderName(5, null)
+ // The config split gets a null class loader
+ .setSplitClassLoaderName(6, null)
+ // The feature split with no dependency and no specified class loader.
+ .setSplitClassLoaderName(7, null);
}
+
+ ParsedPackage parsedPackage = parsingPackage.hideAsParsed()
+ .setBaseCodePath(codeDir + "/base.dex");
+
TestData data = new TestData();
- data.info = ai;
+ data.pkg = parsedPackage.hideAsFinal();
data.pathsWithCode = pathsWithCode;
return data;
}
@@ -118,11 +141,11 @@ public class DexoptUtilsTest {
@Test
public void testSplitChain() {
- TestData data = createMockApplicationInfo(PATH_CLASS_LOADER_NAME, true, true);
+ TestData data = createMockApplicationInfo(PATH_CLASS_LOADER_NAME, true, true, true);
List<SharedLibraryInfo> sharedLibrary =
createMockSharedLibrary(new String[] {"a.dex", "b.dex"});
String[] contexts = DexoptUtils.getClassLoaderContexts(
- data.info, sharedLibrary, data.pathsWithCode);
+ data.pkg, sharedLibrary, data.pathsWithCode);
assertEquals(9, contexts.length);
assertEquals("PCL[]{PCL[a.dex:b.dex]}", contexts[0]);
@@ -139,11 +162,11 @@ public class DexoptUtilsTest {
@Test
public void testSplitChainNoSplitDependencies() {
- TestData data = createMockApplicationInfo(PATH_CLASS_LOADER_NAME, true, false);
+ TestData data = createMockApplicationInfo(PATH_CLASS_LOADER_NAME, true, false, true);
List<SharedLibraryInfo> sharedLibrary =
createMockSharedLibrary(new String[] {"a.dex", "b.dex"});
String[] contexts = DexoptUtils.getClassLoaderContexts(
- data.info, sharedLibrary, data.pathsWithCode);
+ data.pkg, sharedLibrary, data.pathsWithCode);
assertEquals(9, contexts.length);
assertEquals("PCL[]{PCL[a.dex:b.dex]}", contexts[0]);
@@ -167,11 +190,9 @@ public class DexoptUtilsTest {
@Test
public void testSplitChainNoIsolationNoSharedLibrary() {
- TestData data = createMockApplicationInfo(PATH_CLASS_LOADER_NAME, true, true);
- data.info.privateFlags = data.info.privateFlags
- & (~ApplicationInfo.PRIVATE_FLAG_ISOLATED_SPLIT_LOADING);
+ TestData data = createMockApplicationInfo(PATH_CLASS_LOADER_NAME, true, true, false);
String[] contexts = DexoptUtils.getClassLoaderContexts(
- data.info, null, data.pathsWithCode);
+ data.pkg, null, data.pathsWithCode);
assertEquals(9, contexts.length);
assertEquals("PCL[]", contexts[0]);
@@ -192,9 +213,9 @@ public class DexoptUtilsTest {
@Test
public void testSplitChainNoSharedLibraries() {
TestData data = createMockApplicationInfo(
- DELEGATE_LAST_CLASS_LOADER_NAME, true, true);
+ DELEGATE_LAST_CLASS_LOADER_NAME, true, true, true);
String[] contexts = DexoptUtils.getClassLoaderContexts(
- data.info, null, data.pathsWithCode);
+ data.pkg, null, data.pathsWithCode);
assertEquals(9, contexts.length);
assertEquals("DLC[]", contexts[0]);
@@ -211,11 +232,11 @@ public class DexoptUtilsTest {
@Test
public void testSplitChainWithNullPrimaryClassLoader() {
// A null classLoaderName should mean PathClassLoader.
- TestData data = createMockApplicationInfo(null, true, true);
+ TestData data = createMockApplicationInfo(null, true, true, true);
List<SharedLibraryInfo> sharedLibrary =
createMockSharedLibrary(new String[] {"a.dex", "b.dex"});
String[] contexts = DexoptUtils.getClassLoaderContexts(
- data.info, sharedLibrary, data.pathsWithCode);
+ data.pkg, sharedLibrary, data.pathsWithCode);
assertEquals(9, contexts.length);
assertEquals("PCL[]{PCL[a.dex:b.dex]}", contexts[0]);
@@ -233,11 +254,11 @@ public class DexoptUtilsTest {
@Test
public void tesNoSplits() {
- TestData data = createMockApplicationInfo(PATH_CLASS_LOADER_NAME, false, false);
+ TestData data = createMockApplicationInfo(PATH_CLASS_LOADER_NAME, false, false, true);
List<SharedLibraryInfo> sharedLibrary =
createMockSharedLibrary(new String[] {"a.dex", "b.dex"});
String[] contexts = DexoptUtils.getClassLoaderContexts(
- data.info, sharedLibrary, data.pathsWithCode);
+ data.pkg, sharedLibrary, data.pathsWithCode);
assertEquals(1, contexts.length);
assertEquals("PCL[]{PCL[a.dex:b.dex]}", contexts[0]);
@@ -245,11 +266,11 @@ public class DexoptUtilsTest {
@Test
public void tesNoSplitsNullClassLoaderName() {
- TestData data = createMockApplicationInfo(null, false, false);
+ TestData data = createMockApplicationInfo(null, false, false, true);
List<SharedLibraryInfo> sharedLibrary =
createMockSharedLibrary(new String[] {"a.dex", "b.dex"});
String[] contexts = DexoptUtils.getClassLoaderContexts(
- data.info, sharedLibrary, data.pathsWithCode);
+ data.pkg, sharedLibrary, data.pathsWithCode);
assertEquals(1, contexts.length);
assertEquals("PCL[]{PCL[a.dex:b.dex]}", contexts[0]);
@@ -258,11 +279,11 @@ public class DexoptUtilsTest {
@Test
public void tesNoSplitDelegateLast() {
TestData data = createMockApplicationInfo(
- DELEGATE_LAST_CLASS_LOADER_NAME, false, false);
+ DELEGATE_LAST_CLASS_LOADER_NAME, false, false, true);
List<SharedLibraryInfo> sharedLibrary =
createMockSharedLibrary(new String[] {"a.dex", "b.dex"});
String[] contexts = DexoptUtils.getClassLoaderContexts(
- data.info, sharedLibrary, data.pathsWithCode);
+ data.pkg, sharedLibrary, data.pathsWithCode);
assertEquals(1, contexts.length);
assertEquals("DLC[]{PCL[a.dex:b.dex]}", contexts[0]);
@@ -270,9 +291,9 @@ public class DexoptUtilsTest {
@Test
public void tesNoSplitsNoSharedLibraries() {
- TestData data = createMockApplicationInfo(PATH_CLASS_LOADER_NAME, false, false);
+ TestData data = createMockApplicationInfo(PATH_CLASS_LOADER_NAME, false, false, true);
String[] contexts = DexoptUtils.getClassLoaderContexts(
- data.info, null, data.pathsWithCode);
+ data.pkg, null, data.pathsWithCode);
assertEquals(1, contexts.length);
assertEquals("PCL[]", contexts[0]);
@@ -281,9 +302,9 @@ public class DexoptUtilsTest {
@Test
public void tesNoSplitDelegateLastNoSharedLibraries() {
TestData data = createMockApplicationInfo(
- DELEGATE_LAST_CLASS_LOADER_NAME, false, false);
+ DELEGATE_LAST_CLASS_LOADER_NAME, false, false, true);
String[] contexts = DexoptUtils.getClassLoaderContexts(
- data.info, null, data.pathsWithCode);
+ data.pkg, null, data.pathsWithCode);
assertEquals(1, contexts.length);
assertEquals("DLC[]", contexts[0]);
@@ -291,13 +312,13 @@ public class DexoptUtilsTest {
@Test
public void testContextWithNoCode() {
- TestData data = createMockApplicationInfo(null, true, false);
+ TestData data = createMockApplicationInfo(null, true, false, true);
Arrays.fill(data.pathsWithCode, false);
List<SharedLibraryInfo> sharedLibrary =
createMockSharedLibrary(new String[] {"a.dex", "b.dex"});
String[] contexts = DexoptUtils.getClassLoaderContexts(
- data.info, sharedLibrary, data.pathsWithCode);
+ data.pkg, sharedLibrary, data.pathsWithCode);
assertEquals(9, contexts.length);
assertEquals(null, contexts[0]);
@@ -312,12 +333,12 @@ public class DexoptUtilsTest {
@Test
public void testContextBaseNoCode() {
- TestData data = createMockApplicationInfo(null, true, true);
+ TestData data = createMockApplicationInfo(null, true, true, true);
data.pathsWithCode[0] = false;
List<SharedLibraryInfo> sharedLibrary =
createMockSharedLibrary(new String[] {"a.dex", "b.dex"});
String[] contexts = DexoptUtils.getClassLoaderContexts(
- data.info, sharedLibrary, data.pathsWithCode);
+ data.pkg, sharedLibrary, data.pathsWithCode);
assertEquals(9, contexts.length);
assertEquals(null, contexts[0]);