diff options
| author | Winson Chiu <chiuwinson@google.com> | 2019-10-01 00:31:40 +0000 |
|---|---|---|
| committer | Android (Google) Code Review <android-gerrit@google.com> | 2019-10-01 00:31:40 +0000 |
| commit | 29f3a0b63d4c8a0111fcac9d2b436db94ba696ca (patch) | |
| tree | 50edb91476057f82ba6a5d6de2607b1a1d5684b0 /core/java | |
| parent | 4c23a5980500d7d0888b0de5c86b6e2bd9e9a299 (diff) | |
| parent | 8e18a0ab8980a3092d6c7e1d2edc6407655af609 (diff) | |
Merge "Revert "Deprecate PackageParser#Package""
Diffstat (limited to 'core/java')
25 files changed, 334 insertions, 12310 deletions
diff --git a/core/java/android/content/pm/ActivityInfo.java b/core/java/android/content/pm/ActivityInfo.java index 29f243f76905..415c2428405f 100644 --- a/core/java/android/content/pm/ActivityInfo.java +++ b/core/java/android/content/pm/ActivityInfo.java @@ -1379,8 +1379,7 @@ public class ActivityInfo extends ComponentInfo implements Parcelable { this.minHeight = minHeight; } - /** @hide */ - public WindowLayout(Parcel source) { + WindowLayout(Parcel source) { width = source.readInt(); widthFraction = source.readFloat(); height = source.readInt(); diff --git a/core/java/android/content/pm/parsing/library/AndroidHidlUpdater.java b/core/java/android/content/pm/AndroidHidlUpdater.java index 81b4bc574197..d0657e5eb8ec 100644 --- a/core/java/android/content/pm/parsing/library/AndroidHidlUpdater.java +++ b/core/java/android/content/pm/AndroidHidlUpdater.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 The Android Open Source Project + * 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. @@ -13,12 +13,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package android.content.pm.parsing.library; +package android.content.pm; -import static android.content.pm.parsing.library.SharedLibraryNames.ANDROID_HIDL_BASE; -import static android.content.pm.parsing.library.SharedLibraryNames.ANDROID_HIDL_MANAGER; +import static android.content.pm.SharedLibraryNames.ANDROID_HIDL_BASE; +import static android.content.pm.SharedLibraryNames.ANDROID_HIDL_MANAGER; -import android.content.pm.parsing.ParsedPackage; +import android.content.pm.PackageParser.Package; import android.os.Build; import com.android.internal.annotations.VisibleForTesting; @@ -33,18 +33,20 @@ import com.android.internal.annotations.VisibleForTesting; public class AndroidHidlUpdater extends PackageSharedLibraryUpdater { @Override - public void updatePackage(ParsedPackage parsedPackage) { + public void updatePackage(Package pkg) { + ApplicationInfo info = pkg.applicationInfo; + // This was the default <= P and is maintained for backwards compatibility. - boolean isLegacy = parsedPackage.getTargetSdkVersion() <= Build.VERSION_CODES.P; + boolean isLegacy = info.targetSdkVersion <= Build.VERSION_CODES.P; // Only system apps use these libraries - boolean isSystem = parsedPackage.isSystemApp() || parsedPackage.isUpdatedSystemApp(); + boolean isSystem = info.isSystemApp() || info.isUpdatedSystemApp(); if (isLegacy && isSystem) { - prefixRequiredLibrary(parsedPackage, ANDROID_HIDL_BASE); - prefixRequiredLibrary(parsedPackage, ANDROID_HIDL_MANAGER); + prefixRequiredLibrary(pkg, ANDROID_HIDL_BASE); + prefixRequiredLibrary(pkg, ANDROID_HIDL_MANAGER); } else { - removeLibrary(parsedPackage, ANDROID_HIDL_BASE); - removeLibrary(parsedPackage, ANDROID_HIDL_MANAGER); + removeLibrary(pkg, ANDROID_HIDL_BASE); + removeLibrary(pkg, ANDROID_HIDL_MANAGER); } } } diff --git a/core/java/android/content/pm/parsing/library/AndroidTestBaseUpdater.java b/core/java/android/content/pm/AndroidTestBaseUpdater.java index 25c309931554..da1a693b13c3 100644 --- a/core/java/android/content/pm/parsing/library/AndroidTestBaseUpdater.java +++ b/core/java/android/content/pm/AndroidTestBaseUpdater.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 The Android Open Source Project + * 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. @@ -13,13 +13,12 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package android.content.pm.parsing.library; +package android.content.pm; -import static android.content.pm.parsing.library.SharedLibraryNames.ANDROID_TEST_BASE; -import static android.content.pm.parsing.library.SharedLibraryNames.ANDROID_TEST_RUNNER; +import static android.content.pm.SharedLibraryNames.ANDROID_TEST_BASE; +import static android.content.pm.SharedLibraryNames.ANDROID_TEST_RUNNER; -import android.content.pm.parsing.AndroidPackage; -import android.content.pm.parsing.ParsedPackage; +import android.content.pm.PackageParser.Package; import android.os.Build; import com.android.internal.annotations.VisibleForTesting; @@ -39,22 +38,23 @@ import com.android.internal.annotations.VisibleForTesting; @VisibleForTesting public class AndroidTestBaseUpdater extends PackageSharedLibraryUpdater { - private static boolean apkTargetsApiLevelLessThanOrEqualToQ(AndroidPackage pkg) { - return pkg.getTargetSdkVersion() <= Build.VERSION_CODES.Q; + private static boolean apkTargetsApiLevelLessThanOrEqualToQ(Package pkg) { + int targetSdkVersion = pkg.applicationInfo.targetSdkVersion; + return targetSdkVersion <= Build.VERSION_CODES.Q; } @Override - public void updatePackage(ParsedPackage parsedPackage) { + public void updatePackage(Package pkg) { // 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(parsedPackage)) { - prefixRequiredLibrary(parsedPackage, ANDROID_TEST_BASE); + if (apkTargetsApiLevelLessThanOrEqualToQ(pkg)) { + prefixRequiredLibrary(pkg, 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(parsedPackage, ANDROID_TEST_RUNNER, ANDROID_TEST_BASE); + prefixImplicitDependency(pkg, ANDROID_TEST_RUNNER, ANDROID_TEST_BASE); } } } diff --git a/core/java/android/content/pm/parsing/library/OrgApacheHttpLegacyUpdater.java b/core/java/android/content/pm/OrgApacheHttpLegacyUpdater.java index 613a06b636e9..707443b19679 100644 --- a/core/java/android/content/pm/parsing/library/OrgApacheHttpLegacyUpdater.java +++ b/core/java/android/content/pm/OrgApacheHttpLegacyUpdater.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 The Android Open Source Project + * 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. @@ -13,12 +13,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package android.content.pm.parsing.library; +package android.content.pm; -import static android.content.pm.parsing.library.SharedLibraryNames.ORG_APACHE_HTTP_LEGACY; +import static android.content.pm.SharedLibraryNames.ORG_APACHE_HTTP_LEGACY; -import android.content.pm.parsing.AndroidPackage; -import android.content.pm.parsing.ParsedPackage; +import android.content.pm.PackageParser.Package; import android.os.Build; import com.android.internal.annotations.VisibleForTesting; @@ -32,17 +31,18 @@ import com.android.internal.annotations.VisibleForTesting; @VisibleForTesting public class OrgApacheHttpLegacyUpdater extends PackageSharedLibraryUpdater { - private static boolean apkTargetsApiLevelLessThanOrEqualToOMR1(AndroidPackage pkg) { - return pkg.getTargetSdkVersion() < Build.VERSION_CODES.P; + private static boolean apkTargetsApiLevelLessThanOrEqualToOMR1(Package pkg) { + int targetSdkVersion = pkg.applicationInfo.targetSdkVersion; + return targetSdkVersion < Build.VERSION_CODES.P; } @Override - public void updatePackage(ParsedPackage parsedPackage) { + public void updatePackage(Package pkg) { // 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(parsedPackage)) { - prefixRequiredLibrary(parsedPackage, ORG_APACHE_HTTP_LEGACY); + if (apkTargetsApiLevelLessThanOrEqualToOMR1(pkg)) { + prefixRequiredLibrary(pkg, ORG_APACHE_HTTP_LEGACY); } } } diff --git a/core/java/android/content/pm/parsing/library/PackageBackwardCompatibility.java b/core/java/android/content/pm/PackageBackwardCompatibility.java index 1220fc497b04..4331bd4ac4d4 100644 --- a/core/java/android/content/pm/parsing/library/PackageBackwardCompatibility.java +++ b/core/java/android/content/pm/PackageBackwardCompatibility.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 The Android Open Source Project + * Copyright (C) 2017 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.parsing.library; +package android.content.pm; -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 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 android.content.pm.parsing.ParsedPackage; +import android.content.pm.PackageParser.Package; 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 ParsedPackage} in order to maintain backwards compatibility. + * Modifies {@link Package} 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.parsing.library.AndroidTestBaseUpdater", + "android.content.pm.AndroidTestBaseUpdater", RemoveUnnecessaryAndroidTestBaseLibrary::new); PackageSharedLibraryUpdater[] updaterArray = packageUpdaters @@ -123,20 +123,20 @@ public class PackageBackwardCompatibility extends PackageSharedLibraryUpdater { } /** - * Modify the shared libraries in the supplied {@link ParsedPackage} to maintain backwards + * Modify the shared libraries in the supplied {@link Package} to maintain backwards * compatibility. * - * @param parsedPackage the {@link ParsedPackage} to modify. + * @param pkg the {@link Package} to modify. */ @VisibleForTesting - public static void modifySharedLibraries(ParsedPackage parsedPackage) { - INSTANCE.updatePackage(parsedPackage); + public static void modifySharedLibraries(Package pkg) { + INSTANCE.updatePackage(pkg); } @Override - public void updatePackage(ParsedPackage parsedPackage) { + public void updatePackage(Package pkg) { for (PackageSharedLibraryUpdater packageUpdater : mPackageUpdaters) { - packageUpdater.updatePackage(parsedPackage); + packageUpdater.updatePackage(pkg); } } @@ -161,10 +161,10 @@ public class PackageBackwardCompatibility extends PackageSharedLibraryUpdater { public static class AndroidTestRunnerSplitUpdater extends PackageSharedLibraryUpdater { @Override - public void updatePackage(ParsedPackage parsedPackage) { + public void updatePackage(Package pkg) { // 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(parsedPackage, ANDROID_TEST_RUNNER, ANDROID_TEST_MOCK); + prefixImplicitDependency(pkg, ANDROID_TEST_RUNNER, ANDROID_TEST_MOCK); } } @@ -177,8 +177,8 @@ public class PackageBackwardCompatibility extends PackageSharedLibraryUpdater { extends PackageSharedLibraryUpdater { @Override - public void updatePackage(ParsedPackage parsedPackage) { - removeLibrary(parsedPackage, ORG_APACHE_HTTP_LEGACY); + public void updatePackage(Package pkg) { + removeLibrary(pkg, ORG_APACHE_HTTP_LEGACY); } } @@ -192,8 +192,8 @@ public class PackageBackwardCompatibility extends PackageSharedLibraryUpdater { extends PackageSharedLibraryUpdater { @Override - public void updatePackage(ParsedPackage parsedPackage) { - removeLibrary(parsedPackage, ANDROID_TEST_BASE); + public void updatePackage(Package pkg) { + removeLibrary(pkg, ANDROID_TEST_BASE); } } } diff --git a/core/java/android/content/pm/PackageInfo.java b/core/java/android/content/pm/PackageInfo.java index aa0002df2c3a..d6fb28f694fd 100644 --- a/core/java/android/content/pm/PackageInfo.java +++ b/core/java/android/content/pm/PackageInfo.java @@ -373,9 +373,8 @@ public class PackageInfo implements Parcelable { /** * Whether the overlay is static, meaning it cannot be enabled/disabled at runtime. - * @hide */ - public boolean mOverlayIsStatic; + 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 6adf0387bb4c..3eef92fc0aa7 100644 --- a/core/java/android/content/pm/PackageManagerInternal.java +++ b/core/java/android/content/pm/PackageManagerInternal.java @@ -28,8 +28,6 @@ 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; @@ -319,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(AndroidPackage pkg, + public abstract boolean setInstalled(PackageParser.Package pkg, @UserIdInt int userId, boolean installed); /** @@ -398,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(AndroidPackage pkg); + public abstract boolean isLegacySystemApp(PackageParser.Package pkg); /** * Get all overlay packages for a user. @@ -490,17 +488,13 @@ public abstract class PackageManagerInternal { /** * Returns a package object for the given package name. */ - 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); + public abstract @Nullable PackageParser.Package getPackage(@NonNull 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 AndroidPackage getPackage(int uid); + public abstract @Nullable PackageParser.Package getPackage(int uid); /** * Returns a list without a change observer. @@ -531,19 +525,17 @@ 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 Object getDisabledSystemPackage(@NonNull String packageName); + public abstract @Nullable PackageParser.Package getDisabledSystemPackage( + @NonNull String packageName); /** * Returns the package name for the disabled system package. * * This is equivalent to - * {@link #getDisabledSystemPackage(String)} - * .{@link com.android.server.pm.PackageSetting#pkg} - * .{@link AndroidPackage#getPackageName()} + * {@link #getDisabledSystemPackage(String)}.{@link PackageParser.Package#packageName} */ public abstract @Nullable String getDisabledSystemPackageName(@NonNull String packageName); @@ -577,7 +569,7 @@ public abstract class PackageManagerInternal { * @see #canAccessInstantApps */ public abstract boolean filterAppAccess( - @NonNull AndroidPackage pkg, int callingUid, int userId); + @NonNull PackageParser.Package pkg, int callingUid, int userId); /** * Returns whether or not access to the application should be filtered. @@ -651,8 +643,7 @@ 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 ComponentParseUtils.ParsedComponent component, int flags, int userId); + public abstract boolean isEnabledAndMatches(@NonNull ComponentInfo info, int flags, int userId); /** Returns {@code true} if the given user requires extra badging for icons. */ public abstract boolean userNeedsBadging(int userId); @@ -663,14 +654,14 @@ public abstract class PackageManagerInternal { * * @param actionLocked action to be performed */ - public abstract void forEachPackage(Consumer<AndroidPackage> actionLocked); + public abstract void forEachPackage(Consumer<PackageParser.Package> 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<AndroidPackage> actionLocked, @UserIdInt int userId); + @NonNull Consumer<PackageParser.Package> actionLocked, @UserIdInt int userId); /** Returns the list of enabled components */ public abstract ArraySet<String> getEnabledComponents(String packageName, int userId); @@ -804,7 +795,7 @@ public abstract class PackageManagerInternal { * Otherwise, {@code false}. */ public abstract boolean isCallerInstallerOfRecord( - @NonNull AndroidPackage pkg, int callingUid); + @NonNull PackageParser.Package 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 2ded5dcae0d9..0b157fa3bb1e 100644 --- a/core/java/android/content/pm/PackageParser.java +++ b/core/java/android/content/pm/PackageParser.java @@ -57,12 +57,6 @@ 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; @@ -73,6 +67,7 @@ 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; @@ -161,22 +156,21 @@ import java.util.concurrent.atomic.AtomicInteger; * @hide */ public class PackageParser { - - 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 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; private static final String PROPERTY_CHILD_PACKAGES_ENABLED = "persist.sys.child_packages_enabled"; - public static final boolean MULTI_PACKAGE_APK_ENABLED = Build.IS_DEBUGGABLE && + private static final boolean MULTI_PACKAGE_APK_ENABLED = Build.IS_DEBUGGABLE && SystemProperties.getBoolean(PROPERTY_CHILD_PACKAGES_ENABLED, false); - 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 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; private static final int DEFAULT_MIN_SDK_VERSION = 1; private static final int DEFAULT_TARGET_SDK_VERSION = 0; @@ -188,38 +182,37 @@ public class PackageParser { public static final String ANDROID_MANIFEST_FILENAME = "AndroidManifest.xml"; /** Path prefix for apps on expanded storage */ - 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"; + 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"; /** * Bit mask of all the valid bits that can be set in recreateOnConfigChanges. @@ -229,25 +222,25 @@ public class PackageParser { ActivityInfo.CONFIG_MCC | ActivityInfo.CONFIG_MNC; // These are the tags supported by child packages - public static final Set<String> CHILD_PACKAGE_TAGS = new ArraySet<>(); + private static final Set<String> CHILD_PACKAGE_TAGS = new ArraySet<>(); static { CHILD_PACKAGE_TAGS.add(TAG_APPLICATION); - 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_INSTRUMENTATION); - CHILD_PACKAGE_TAGS.add(TAG_SUPPORT_SCREENS); - CHILD_PACKAGE_TAGS.add(TAG_SUPPORTS_INPUT); - 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_PERMISSION_SDK_23); + CHILD_PACKAGE_TAGS.add(TAG_USES_CONFIGURATION); + CHILD_PACKAGE_TAGS.add(TAG_USES_FEATURE); + 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_SUPPORTS_INPUT); + CHILD_PACKAGE_TAGS.add(TAG_EAT_COMMENT); } - public static final boolean LOG_UNSAFE_BROADCASTS = false; + private static final boolean LOG_UNSAFE_BROADCASTS = false; /** * Total number of packages that were read from the cache. We use it only for logging. @@ -255,7 +248,7 @@ public class PackageParser { public static final AtomicInteger sCachedPackageReadCount = new AtomicInteger(); // Set of broadcast actions that are safe for manifest receivers - public static final Set<String> SAFE_BROADCASTS = new ArraySet<>(); + private static final Set<String> SAFE_BROADCASTS = new ArraySet<>(); static { SAFE_BROADCASTS.add(Intent.ACTION_BOOT_COMPLETED); } @@ -302,29 +295,26 @@ public class PackageParser { * @deprecated callers should move to explicitly passing around source path. */ @Deprecated - public String mArchiveSourcePath; + private String mArchiveSourcePath; - public String[] mSeparateProcesses; + private String[] mSeparateProcesses; private boolean mOnlyCoreApps; private DisplayMetrics mMetrics; @UnsupportedAppUsage - public Callback mCallback; + private Callback mCallback; private File mCacheDir; - 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 static final int SDK_VERSION = Build.VERSION.SDK_INT; + private static final String[] SDK_CODENAMES = Build.VERSION.ACTIVE_CODENAMES; - public ThreadLocal<ApkParseUtils.ParseResult> mSharedResult - = ThreadLocal.withInitial(ApkParseUtils.ParseResult::new); + private int mParseError = PackageManager.INSTALL_SUCCEEDED; - public static boolean sCompatibilityModeEnabled = true; - public static boolean sUseRoundIcon = false; + private static boolean sCompatibilityModeEnabled = true; + private static boolean sUseRoundIcon = false; - public static final int PARSE_DEFAULT_INSTALL_LOCATION = + private static final int PARSE_DEFAULT_INSTALL_LOCATION = PackageInfo.INSTALL_LOCATION_UNSPECIFIED; - public static final int PARSE_DEFAULT_TARGET_SANDBOX = 1; + private static final int PARSE_DEFAULT_TARGET_SANDBOX = 1; static class ParsePackageItemArgs { final Package owner; @@ -546,7 +536,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. */ - public static final boolean RIGID_PARSER = false; + private static final boolean RIGID_PARSER = false; private static final String TAG = "PackageParser"; @@ -907,7 +897,7 @@ public class PackageParser { @Retention(RetentionPolicy.SOURCE) public @interface ParseFlags {} - public static final Comparator<String> sSplitNameComparator = new SplitNameComparator(); + private static final Comparator<String> sSplitNameComparator = new SplitNameComparator(); /** * Used to sort a set of APKs based on their split names, always placing the @@ -1053,7 +1043,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 ApkParseUtils#collectCertificates(AndroidPackage, boolean)}. + * must be done separately in {@link #collectCertificates(Package, int)}. * * 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 @@ -1061,54 +1051,21 @@ 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 { - 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; + Package parsed = useCaches ? getCachedResult(packageFile, flags) : null; if (parsed != null) { return parsed; } long parseTime = LOG_PARSE_TIMINGS ? SystemClock.uptimeMillis() : 0; - ApkParseUtils.ParseInput parseInput = mSharedResult.get().reset(); - parsed = ApkParseUtils.parsePackage( - parseInput, - mSeparateProcesses, - mCallback, - mMetrics, - mOnlyCoreApps, - packageFile, - flags - ) - .hideAsParsed(); + if (packageFile.isDirectory()) { + parsed = parseClusterPackage(packageFile, flags); + } else { + parsed = parseMonolithicPackage(packageFile, flags); + } long cacheTime = LOG_PARSE_TIMINGS ? SystemClock.uptimeMillis() : 0; cacheResult(packageFile, flags, parsed); @@ -1120,12 +1077,19 @@ public class PackageParser { + "ms, update_cache=" + cacheTime + " ms"); } } - return parsed; } /** - * Returns the cache key for a specified {@code packageFile} and {@code flags}. + * 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 */); + } + + /** + * Returns the cache key for a specificied {@code packageFile} and {@code flags}. */ private String getCacheKey(File packageFile, int flags) { StringBuilder sb = new StringBuilder(packageFile.getName()); @@ -1136,13 +1100,13 @@ public class PackageParser { } @VisibleForTesting - protected ParsedPackage fromCacheEntry(byte[] bytes) { + protected Package fromCacheEntry(byte[] bytes) { return fromCacheEntryStatic(bytes); } /** static version of {@link #fromCacheEntry} for unit tests. */ @VisibleForTesting - public static ParsedPackage fromCacheEntryStatic(byte[] bytes) { + public static Package fromCacheEntryStatic(byte[] bytes) { final Parcel p = Parcel.obtain(); p.unmarshall(bytes, 0, bytes.length); p.setDataPosition(0); @@ -1150,8 +1114,7 @@ public class PackageParser { final ReadHelper helper = new ReadHelper(p); helper.startAndInstall(); - // TODO(b/135203078): Hide PackageImpl constructor? - ParsedPackage pkg = new PackageImpl(p); + PackageParser.Package pkg = new PackageParser.Package(p); p.recycle(); @@ -1161,14 +1124,14 @@ public class PackageParser { } @VisibleForTesting - protected byte[] toCacheEntry(ParsedPackage pkg) { + protected byte[] toCacheEntry(Package pkg) { return toCacheEntryStatic(pkg); } /** static version of {@link #toCacheEntry} for unit tests. */ @VisibleForTesting - public static byte[] toCacheEntryStatic(ParsedPackage pkg) { + public static byte[] toCacheEntryStatic(Package pkg) { final Parcel p = Parcel.obtain(); final WriteHelper helper = new WriteHelper(p); @@ -1217,7 +1180,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. */ - public ParsedPackage getCachedResult(File packageFile, int flags) { + private Package getCachedResult(File packageFile, int flags) { if (mCacheDir == null) { return null; } @@ -1232,9 +1195,9 @@ public class PackageParser { } final byte[] bytes = IoUtils.readFileAsByteArray(cacheFile.getAbsolutePath()); - ParsedPackage p = fromCacheEntry(bytes); + Package p = fromCacheEntry(bytes); if (mCallback != null) { - String[] overlayApks = mCallback.getOverlayApks(p.getPackageName()); + String[] overlayApks = mCallback.getOverlayApks(p.packageName); if (overlayApks != null && overlayApks.length > 0) { for (String overlayApk : overlayApks) { // If a static RRO is updated, return null. @@ -1258,7 +1221,7 @@ public class PackageParser { /** * Caches the parse result for {@code packageFile} with flags {@code flags}. */ - public void cacheResult(File packageFile, int flags, ParsedPackage parsed) { + private void cacheResult(File packageFile, int flags, Package parsed) { if (mCacheDir == null) { return; } @@ -1297,8 +1260,7 @@ public class PackageParser { * split names. * <p> * Note that this <em>does not</em> perform signature verification; that - * must be done separately in - * {@link ApkParseUtils#collectCertificates(AndroidPackage, boolean)}. + * must be done separately in {@link #collectCertificates(Package, int)}. */ private Package parseClusterPackage(File packageDir, int flags) throws PackageParserException { final PackageLite lite = parseClusterPackageLite(packageDir, 0); @@ -1362,11 +1324,10 @@ 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 ApkParseUtils#collectCertificates(AndroidPackage, boolean)}. + * must be done separately in {@link #collectCertificates(Package, int)}. * * @deprecated external callers should move to - * {@link #parseParsedPackage(File, int, boolean)}. Eventually this method will + * {@link #parsePackage(File, int)}. Eventually this method will * be marked private. */ @Deprecated @@ -1566,11 +1527,8 @@ 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); @@ -1749,7 +1707,7 @@ public class PackageParser { ? null : "must have at least one '.' separator"; } - public static Pair<String, String> parsePackageSplitNames(XmlPullParser parser, + private static Pair<String, String> parsePackageSplitNames(XmlPullParser parser, AttributeSet attrs) throws IOException, XmlPullParserException, PackageParserException { @@ -2529,6 +2487,8 @@ 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 + " " @@ -2998,7 +2958,7 @@ public class PackageParser { return true; } - public static String buildClassName(String pkg, CharSequence clsSeq, + private static String buildClassName(String pkg, CharSequence clsSeq, String[] outError) { if (clsSeq == null || clsSeq.length() <= 0) { outError[0] = "Empty class name in package " + pkg; @@ -3046,7 +3006,7 @@ public class PackageParser { return proc; } - public static String buildProcessName(String pkg, String defProc, + private static String buildProcessName(String pkg, String defProc, CharSequence procSeq, int flags, String[] separateProcesses, String[] outError) { if ((flags&PARSE_IGNORE_PROCESSES) != 0 && !"system".equals(procSeq)) { @@ -3066,7 +3026,7 @@ public class PackageParser { return TextUtils.safeIntern(buildCompoundName(pkg, procSeq, "process", outError)); } - public static String buildTaskAffinityName(String pkg, String defProc, + private static String buildTaskAffinityName(String pkg, String defProc, CharSequence procSeq, String[] outError) { if (procSeq == null) { return defProc; @@ -3628,6 +3588,9 @@ 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)) { @@ -4089,6 +4052,89 @@ 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 */ @@ -5800,7 +5846,7 @@ public class PackageParser { return null; } - public static final String ANDROID_RESOURCES + private static final String ANDROID_RESOURCES = "http://schemas.android.com/apk/res/android"; private boolean parseIntent(Resources res, XmlResourceParser parser, boolean allowGlobs, @@ -6495,10 +6541,7 @@ 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 @@ -6606,6 +6649,9 @@ 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); @@ -6711,6 +6757,9 @@ 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; @@ -7214,6 +7263,9 @@ 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) { @@ -7229,7 +7281,7 @@ public class PackageParser { * Sets the package owner and the the {@code applicationInfo} for every component * owner by this package. */ - public void fixupOwner(List<? extends Component<?>> list) { + private void fixupOwner(List<? extends Component<?>> list) { if (list != null) { for (Component<?> c : list) { c.owner = this; @@ -7339,8 +7391,12 @@ 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. */ @@ -7412,10 +7468,6 @@ public class PackageParser { }; } - /** - * @deprecated use a {@link ComponentParseUtils.ParsedComponent} - */ - @Deprecated public static abstract class Component<II extends IntentInfo> { @UnsupportedAppUsage public final ArrayList<II> intents; @@ -7596,10 +7648,6 @@ public class PackageParser { } } - /** - * @deprecated use {@link ComponentParseUtils.ParsedPermission} - */ - @Deprecated public final static class Permission extends Component<IntentInfo> implements Parcelable { @UnsupportedAppUsage public final PermissionInfo info; @@ -7674,10 +7722,6 @@ public class PackageParser { }; } - /** - * @deprecated use {@link ComponentParseUtils.ParsedPermissionGroup} - */ - @Deprecated public final static class PermissionGroup extends Component<IntentInfo> implements Parcelable { @UnsupportedAppUsage public final PermissionGroupInfo info; @@ -7777,12 +7821,7 @@ 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()); @@ -7839,12 +7878,7 @@ 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; @@ -7884,11 +7918,6 @@ 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; @@ -7908,12 +7937,7 @@ 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; @@ -7925,12 +7949,7 @@ 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; @@ -7942,10 +7961,6 @@ 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; @@ -8061,12 +8076,7 @@ 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; @@ -8084,11 +8094,6 @@ 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; @@ -8102,10 +8107,6 @@ 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; @@ -8167,12 +8168,7 @@ 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; @@ -8190,10 +8186,6 @@ 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; @@ -8274,12 +8266,7 @@ 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; @@ -8302,10 +8289,6 @@ public class PackageParser { return pi; } - /** - * @deprecated use {@link ComponentParseUtils.ParsedInstrumentation} - */ - @Deprecated public final static class Instrumentation extends Component<IntentInfo> implements Parcelable { @UnsupportedAppUsage @@ -8366,12 +8349,7 @@ 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; @@ -8383,10 +8361,6 @@ public class PackageParser { return ii; } - /** - * @deprecated use {@link ComponentParseUtils.ParsedIntentInfo} - */ - @Deprecated public static abstract class IntentInfo extends IntentFilter { @UnsupportedAppUsage public boolean hasDefault; @@ -8430,10 +8404,8 @@ public class PackageParser { } } - /** - * @deprecated use {@link ComponentParseUtils.ParsedActivityIntentInfo} - */ - @Deprecated + public static final class QueriesIntentInfo extends IntentInfo {} + public final static class ActivityIntentInfo extends IntentInfo { @UnsupportedAppUsage public Activity activity; @@ -8457,10 +8429,6 @@ public class PackageParser { } } - /** - * @deprecated use {@link ComponentParseUtils.ParsedServiceIntentInfo} - */ - @Deprecated public final static class ServiceIntentInfo extends IntentInfo { @UnsupportedAppUsage public Service service; @@ -8484,10 +8452,6 @@ 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/parsing/library/PackageSharedLibraryUpdater.java b/core/java/android/content/pm/PackageSharedLibraryUpdater.java index 8b27d140a8f4..1565d9ce77d4 100644 --- a/core/java/android/content/pm/parsing/library/PackageSharedLibraryUpdater.java +++ b/core/java/android/content/pm/PackageSharedLibraryUpdater.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 The Android Open Source Project + * 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. @@ -13,20 +13,18 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package android.content.pm.parsing.library; +package android.content.pm; 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 ParsedPackage}'s shared libraries. + * Base for classes that update a {@link PackageParser.Package}'s shared libraries. * * @hide */ @@ -36,13 +34,14 @@ public abstract class PackageSharedLibraryUpdater { /** * Update the package's shared libraries. * - * @param parsedPackage the package to update. + * @param pkg the package to update. */ - public abstract void updatePackage(ParsedPackage parsedPackage); + public abstract void updatePackage(PackageParser.Package pkg); - static void removeLibrary(ParsedPackage parsedPackage, String libraryName) { - parsedPackage.removeUsesLibrary(libraryName) - .removeUsesOptionalLibrary(libraryName); + static void removeLibrary(PackageParser.Package pkg, String libraryName) { + pkg.usesLibraries = ArrayUtils.remove(pkg.usesLibraries, libraryName); + pkg.usesOptionalLibraries = + ArrayUtils.remove(pkg.usesOptionalLibraries, libraryName); } static @NonNull @@ -54,8 +53,8 @@ public abstract class PackageSharedLibraryUpdater { return cur; } - private static boolean isLibraryPresent(List<String> usesLibraries, - List<String> usesOptionalLibraries, String apacheHttpLegacy) { + private static boolean isLibraryPresent(ArrayList<String> usesLibraries, + ArrayList<String> usesOptionalLibraries, String apacheHttpLegacy) { return ArrayUtils.contains(usesLibraries, apacheHttpLegacy) || ArrayUtils.contains(usesOptionalLibraries, apacheHttpLegacy); } @@ -66,32 +65,37 @@ 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 parsedPackage the {@link ParsedPackage} to update. + * @param pkg the {@link PackageParser.Package} to update. * @param existingLibrary the existing library. * @param implicitDependency the implicit dependency to add */ - void prefixImplicitDependency(ParsedPackage parsedPackage, String existingLibrary, + void prefixImplicitDependency(PackageParser.Package pkg, String existingLibrary, String implicitDependency) { - List<String> usesLibraries = parsedPackage.getUsesLibraries(); - List<String> usesOptionalLibraries = parsedPackage.getUsesOptionalLibraries(); + ArrayList<String> usesLibraries = pkg.usesLibraries; + ArrayList<String> usesOptionalLibraries = pkg.usesOptionalLibraries; if (!isLibraryPresent(usesLibraries, usesOptionalLibraries, implicitDependency)) { if (ArrayUtils.contains(usesLibraries, existingLibrary)) { - parsedPackage.addUsesLibrary(0, implicitDependency); + prefix(usesLibraries, implicitDependency); } else if (ArrayUtils.contains(usesOptionalLibraries, existingLibrary)) { - parsedPackage.addUsesOptionalLibrary(0, implicitDependency); + prefix(usesOptionalLibraries, implicitDependency); } + + pkg.usesLibraries = usesLibraries; + pkg.usesOptionalLibraries = usesOptionalLibraries; } } - void prefixRequiredLibrary(ParsedPackage parsedPackage, String libraryName) { - List<String> usesLibraries = parsedPackage.getUsesLibraries(); - List<String> usesOptionalLibraries = parsedPackage.getUsesOptionalLibraries(); + void prefixRequiredLibrary(PackageParser.Package pkg, String libraryName) { + ArrayList<String> usesLibraries = pkg.usesLibraries; + ArrayList<String> usesOptionalLibraries = pkg.usesOptionalLibraries; boolean alreadyPresent = isLibraryPresent( usesLibraries, usesOptionalLibraries, libraryName); if (!alreadyPresent) { - parsedPackage.addUsesLibrary(0, libraryName); + usesLibraries = prefix(usesLibraries, libraryName); + + pkg.usesLibraries = usesLibraries; } } } diff --git a/core/java/android/content/pm/PackageUserState.java b/core/java/android/content/pm/PackageUserState.java index 55574c3cb880..5c74efb8ff1b 100644 --- a/core/java/android/content/pm/PackageUserState.java +++ b/core/java/android/content/pm/PackageUserState.java @@ -28,7 +28,6 @@ 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; @@ -128,18 +127,6 @@ 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. @@ -148,33 +135,28 @@ 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(boolean isSystem, boolean isPackageEnabled, boolean isComponentEnabled, - boolean isComponentDirectBootAware, String componentName, int flags) { + public boolean isMatch(ComponentInfo componentInfo, int flags) { + final boolean isSystemApp = componentInfo.applicationInfo.isSystemApp(); final boolean matchUninstalled = (flags & PackageManager.MATCH_KNOWN_PACKAGES) != 0; - if (!isAvailable(flags) && !(isSystem && matchUninstalled)) { - return reportIfDebug(false, flags); - } - - if (!isEnabled(isPackageEnabled, isComponentEnabled, componentName, flags)) { - return reportIfDebug(false, flags); - } + if (!isAvailable(flags) + && !(isSystemApp && matchUninstalled)) return reportIfDebug(false, flags); + if (!isEnabled(componentInfo, flags)) return reportIfDebug(false, flags); if ((flags & MATCH_SYSTEM_ONLY) != 0) { - if (!isSystem) { + if (!isSystemApp) { return reportIfDebug(false, flags); } } final boolean matchesUnaware = ((flags & MATCH_DIRECT_BOOT_UNAWARE) != 0) - && !isComponentDirectBootAware; + && !componentInfo.directBootAware; final boolean matchesAware = ((flags & MATCH_DIRECT_BOOT_AWARE) != 0) - && isComponentDirectBootAware; + && componentInfo.directBootAware; return reportIfDebug(matchesUnaware || matchesAware, flags); } - public boolean reportIfDebug(boolean result, int flags) { + private boolean reportIfDebug(boolean result, int flags) { if (DEBUG && !result) { Slog.i(LOG_TAG, "No match!; flags: " + DebugUtils.flagsToString(PackageManager.class, "MATCH_", flags) + " " @@ -183,22 +165,10 @@ 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(boolean isPackageEnabled, boolean isComponentEnabled, - String componentName, int flags) { + public boolean isEnabled(ComponentInfo componentInfo, int flags) { if ((flags & MATCH_DISABLED_COMPONENTS) != 0) { return true; } @@ -213,26 +183,24 @@ public class PackageUserState { if ((flags & MATCH_DISABLED_UNTIL_USED_COMPONENTS) == 0) { return false; } - // fallthrough case COMPONENT_ENABLED_STATE_DEFAULT: - if (!isPackageEnabled) { + if (!componentInfo.applicationInfo.enabled) { 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, componentName)) { + if (ArrayUtils.contains(this.enabledComponents, componentInfo.name)) { return true; } - if (ArrayUtils.contains(this.disabledComponents, componentName)) { + if (ArrayUtils.contains(this.disabledComponents, componentInfo.name)) { return false; } - return isComponentEnabled; + return componentInfo.enabled; } @Override diff --git a/core/java/android/content/pm/SharedLibraryInfo.java b/core/java/android/content/pm/SharedLibraryInfo.java index 2863b268e795..3488cc30892c 100644 --- a/core/java/android/content/pm/SharedLibraryInfo.java +++ b/core/java/android/content/pm/SharedLibraryInfo.java @@ -20,7 +20,6 @@ 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; @@ -39,24 +38,20 @@ import java.util.List; public final class SharedLibraryInfo implements Parcelable { /** @hide */ - public static SharedLibraryInfo createForStatic(AndroidPackage pkg) { - return new SharedLibraryInfo(null, pkg.getPackageName(), - pkg.makeListAllCodePaths(), - pkg.getStaticSharedLibName(), - pkg.getStaticSharedLibVersion(), + public static SharedLibraryInfo createForStatic(PackageParser.Package pkg) { + return new SharedLibraryInfo(null, pkg.packageName, pkg.getAllCodePaths(), + pkg.staticSharedLibName, + pkg.staticSharedLibVersion, TYPE_STATIC, - new VersionedPackage(pkg.getManifestPackageName(), - pkg.getLongVersionCode()), + new VersionedPackage(pkg.manifestPackageName, pkg.getLongVersionCode()), null, null); } /** @hide */ - public static SharedLibraryInfo createForDynamic(AndroidPackage pkg, String name) { - return new SharedLibraryInfo(null, pkg.getPackageName(), - pkg.makeListAllCodePaths(), name, + public static SharedLibraryInfo createForDynamic(PackageParser.Package pkg, String name) { + return new SharedLibraryInfo(null, pkg.packageName, pkg.getAllCodePaths(), name, (long) VERSION_UNDEFINED, - TYPE_DYNAMIC, new VersionedPackage(pkg.getPackageName(), - pkg.getLongVersionCode()), + TYPE_DYNAMIC, new VersionedPackage(pkg.packageName, pkg.getLongVersionCode()), null, null); } diff --git a/core/java/android/content/pm/parsing/library/SharedLibraryNames.java b/core/java/android/content/pm/SharedLibraryNames.java index 7b691c06718e..a607a9ff682b 100644 --- a/core/java/android/content/pm/parsing/library/SharedLibraryNames.java +++ b/core/java/android/content/pm/SharedLibraryNames.java @@ -1,5 +1,5 @@ /* - * Copyright (C) 2019 The Android Open Source Project + * 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. @@ -13,7 +13,7 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package android.content.pm.parsing.library; +package android.content.pm; /** * A set of shared library names diff --git a/core/java/android/content/pm/dex/DexMetadataHelper.java b/core/java/android/content/pm/dex/DexMetadataHelper.java index 4cd201fbe538..5d10b8826b00 100644 --- a/core/java/android/content/pm/dex/DexMetadataHelper.java +++ b/core/java/android/content/pm/dex/DexMetadataHelper.java @@ -22,7 +22,6 @@ 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; @@ -87,8 +86,8 @@ public class DexMetadataHelper { * * NOTE: involves I/O checks. */ - public static Map<String, String> getPackageDexMetadata(AndroidPackage pkg) { - return buildPackageApkToDexMetadataMap(pkg.makeListAllCodePaths()); + public static Map<String, String> getPackageDexMetadata(PackageParser.Package pkg) { + return buildPackageApkToDexMetadataMap(pkg.getAllCodePaths()); } /** @@ -161,7 +160,7 @@ public class DexMetadataHelper { * * @throws PackageParserException in case of errors. */ - public static void validatePackageDexMetadata(AndroidPackage pkg) + public static void validatePackageDexMetadata(PackageParser.Package 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 deleted file mode 100644 index ab3cf7cb8c65..000000000000 --- a/core/java/android/content/pm/parsing/AndroidPackage.aidl +++ /dev/null @@ -1,21 +0,0 @@ -/* -** -** 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 deleted file mode 100644 index bef984df4c10..000000000000 --- a/core/java/android/content/pm/parsing/AndroidPackage.java +++ /dev/null @@ -1,468 +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 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 deleted file mode 100644 index b7595d2dd710..000000000000 --- a/core/java/android/content/pm/parsing/AndroidPackageWrite.java +++ /dev/null @@ -1,59 +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 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 deleted file mode 100644 index ac2e373f000d..000000000000 --- a/core/java/android/content/pm/parsing/ApkLiteParseUtils.java +++ /dev/null @@ -1,428 +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 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 deleted file mode 100644 index 0f35b27de7e2..000000000000 --- a/core/java/android/content/pm/parsing/ApkParseUtils.java +++ /dev/null @@ -1,3197 +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 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 deleted file mode 100644 index adf2a4f85780..000000000000 --- a/core/java/android/content/pm/parsing/ComponentParseUtils.java +++ /dev/null @@ -1,3289 +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 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 deleted file mode 100644 index 363cf80a0a1d..000000000000 --- a/core/java/android/content/pm/parsing/PackageImpl.java +++ /dev/null @@ -1,3213 +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 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 deleted file mode 100644 index 7b329ebc5b83..000000000000 --- a/core/java/android/content/pm/parsing/PackageInfoUtils.java +++ /dev/null @@ -1,732 +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 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 deleted file mode 100644 index 05cf586522f2..000000000000 --- a/core/java/android/content/pm/parsing/ParsedPackage.java +++ /dev/null @@ -1,155 +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 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 deleted file mode 100644 index 43c1f6e335b0..000000000000 --- a/core/java/android/content/pm/parsing/ParsingPackage.java +++ /dev/null @@ -1,327 +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 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/com/android/internal/content/NativeLibraryHelper.java b/core/java/com/android/internal/content/NativeLibraryHelper.java index f04a6715e55f..fee8345d1660 100644 --- a/core/java/com/android/internal/content/NativeLibraryHelper.java +++ b/core/java/com/android/internal/content/NativeLibraryHelper.java @@ -28,11 +28,12 @@ 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; @@ -87,12 +88,11 @@ public class NativeLibraryHelper { } } - 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(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(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 bc8019796d22..821022f1f917 100644 --- a/core/java/com/android/internal/util/ArrayUtils.java +++ b/core/java/com/android/internal/util/ArrayUtils.java @@ -600,14 +600,6 @@ 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; |
