summaryrefslogtreecommitdiff
path: root/core/java
diff options
context:
space:
mode:
authorWinson Chiu <chiuwinson@google.com>2019-10-01 00:31:40 +0000
committerAndroid (Google) Code Review <android-gerrit@google.com>2019-10-01 00:31:40 +0000
commit29f3a0b63d4c8a0111fcac9d2b436db94ba696ca (patch)
tree50edb91476057f82ba6a5d6de2607b1a1d5684b0 /core/java
parent4c23a5980500d7d0888b0de5c86b6e2bd9e9a299 (diff)
parent8e18a0ab8980a3092d6c7e1d2edc6407655af609 (diff)
Merge "Revert "Deprecate PackageParser#Package""
Diffstat (limited to 'core/java')
-rw-r--r--core/java/android/content/pm/ActivityInfo.java3
-rw-r--r--core/java/android/content/pm/AndroidHidlUpdater.java (renamed from core/java/android/content/pm/parsing/library/AndroidHidlUpdater.java)26
-rw-r--r--core/java/android/content/pm/AndroidTestBaseUpdater.java (renamed from core/java/android/content/pm/parsing/library/AndroidTestBaseUpdater.java)24
-rw-r--r--core/java/android/content/pm/OrgApacheHttpLegacyUpdater.java (renamed from core/java/android/content/pm/parsing/library/OrgApacheHttpLegacyUpdater.java)20
-rw-r--r--core/java/android/content/pm/PackageBackwardCompatibility.java (renamed from core/java/android/content/pm/parsing/library/PackageBackwardCompatibility.java)42
-rw-r--r--core/java/android/content/pm/PackageInfo.java3
-rw-r--r--core/java/android/content/pm/PackageManagerInternal.java33
-rw-r--r--core/java/android/content/pm/PackageParser.java442
-rw-r--r--core/java/android/content/pm/PackageSharedLibraryUpdater.java (renamed from core/java/android/content/pm/parsing/library/PackageSharedLibraryUpdater.java)48
-rw-r--r--core/java/android/content/pm/PackageUserState.java60
-rw-r--r--core/java/android/content/pm/SharedLibraryInfo.java21
-rw-r--r--core/java/android/content/pm/SharedLibraryNames.java (renamed from core/java/android/content/pm/parsing/library/SharedLibraryNames.java)4
-rw-r--r--core/java/android/content/pm/dex/DexMetadataHelper.java7
-rw-r--r--core/java/android/content/pm/parsing/AndroidPackage.aidl21
-rw-r--r--core/java/android/content/pm/parsing/AndroidPackage.java468
-rw-r--r--core/java/android/content/pm/parsing/AndroidPackageWrite.java59
-rw-r--r--core/java/android/content/pm/parsing/ApkLiteParseUtils.java428
-rw-r--r--core/java/android/content/pm/parsing/ApkParseUtils.java3197
-rw-r--r--core/java/android/content/pm/parsing/ComponentParseUtils.java3289
-rw-r--r--core/java/android/content/pm/parsing/PackageImpl.java3213
-rw-r--r--core/java/android/content/pm/parsing/PackageInfoUtils.java732
-rw-r--r--core/java/android/content/pm/parsing/ParsedPackage.java155
-rw-r--r--core/java/android/content/pm/parsing/ParsingPackage.java327
-rw-r--r--core/java/com/android/internal/content/NativeLibraryHelper.java14
-rw-r--r--core/java/com/android/internal/util/ArrayUtils.java8
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;