summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Song Chun Fan <schfan@google.com> 2024-05-22 22:16:30 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2024-05-22 22:16:30 +0000
commita58797d1a69ecac5b36ba454515813e5477758bd (patch)
treeaf36ea056d108211776721fb6fa9d70e24d53271
parent592fca977abf84a465bbe324f56577ca551ec550 (diff)
parent019214175d545c9b83cf02e7c0077158857cdf22 (diff)
Merge "[pm] add a fd variant of the parseAndroidManifest API" into main
-rw-r--r--core/api/current.txt1
-rw-r--r--core/java/android/app/ApplicationPackageManager.java32
-rw-r--r--core/java/android/content/pm/PackageManager.java22
-rw-r--r--core/java/android/content/pm/flags.aconfig8
4 files changed, 63 insertions, 0 deletions
diff --git a/core/api/current.txt b/core/api/current.txt
index 8a99e45af0ea..c0bc6d96f7ef 100644
--- a/core/api/current.txt
+++ b/core/api/current.txt
@@ -13040,6 +13040,7 @@ package android.content.pm {
method @CheckResult public abstract boolean isPermissionRevokedByPolicy(@NonNull String, @NonNull String);
method public abstract boolean isSafeMode();
method @FlaggedApi("android.content.pm.get_package_info") @WorkerThread public <T> T parseAndroidManifest(@NonNull java.io.File, @NonNull java.util.function.Function<android.content.res.XmlResourceParser,T>) throws java.io.IOException;
+ method @FlaggedApi("android.content.pm.get_package_info_with_fd") @WorkerThread public <T> T parseAndroidManifest(@NonNull android.os.ParcelFileDescriptor, @NonNull java.util.function.Function<android.content.res.XmlResourceParser,T>) throws java.io.IOException;
method @NonNull public java.util.List<android.content.pm.PackageManager.Property> queryActivityProperty(@NonNull String);
method @NonNull public java.util.List<android.content.pm.PackageManager.Property> queryApplicationProperty(@NonNull String);
method @NonNull public abstract java.util.List<android.content.pm.ResolveInfo> queryBroadcastReceivers(@NonNull android.content.Intent, int);
diff --git a/core/java/android/app/ApplicationPackageManager.java b/core/java/android/app/ApplicationPackageManager.java
index b9906bf3d668..c0f723241c82 100644
--- a/core/java/android/app/ApplicationPackageManager.java
+++ b/core/java/android/app/ApplicationPackageManager.java
@@ -4097,6 +4097,38 @@ public class ApplicationPackageManager extends PackageManager {
}
}
+
+ @Override
+ public <T> T parseAndroidManifest(@NonNull ParcelFileDescriptor apkFileDescriptor,
+ @NonNull Function<XmlResourceParser, T> parserFunction) throws IOException {
+ Objects.requireNonNull(apkFileDescriptor, "apkFileDescriptor cannot be null");
+ Objects.requireNonNull(parserFunction, "parserFunction cannot be null");
+ try (XmlResourceParser xmlResourceParser = getAndroidManifestParser(apkFileDescriptor)) {
+ return parserFunction.apply(xmlResourceParser);
+ } catch (IOException e) {
+ Log.w(TAG, "Failed to get the android manifest parser", e);
+ throw e;
+ }
+ }
+
+ private static XmlResourceParser getAndroidManifestParser(@NonNull ParcelFileDescriptor fd)
+ throws IOException {
+ ApkAssets apkAssets = null;
+ try {
+ apkAssets = ApkAssets.loadFromFd(
+ fd.getFileDescriptor(), fd.toString(), /* flags= */ 0 , /* assets= */null);
+ return apkAssets.openXml(ApkLiteParseUtils.ANDROID_MANIFEST_FILENAME);
+ } finally {
+ if (apkAssets != null) {
+ try {
+ apkAssets.close();
+ } catch (Throwable ignored) {
+ Log.w(TAG, "Failed to close apkAssets", ignored);
+ }
+ }
+ }
+ }
+
@Override
public TypedArray extractPackageItemInfoAttributes(PackageItemInfo info, String name,
String rootTag, int[] attributes) {
diff --git a/core/java/android/content/pm/PackageManager.java b/core/java/android/content/pm/PackageManager.java
index c506c9741635..2d9881abc4a5 100644
--- a/core/java/android/content/pm/PackageManager.java
+++ b/core/java/android/content/pm/PackageManager.java
@@ -75,6 +75,7 @@ import android.os.Handler;
import android.os.IBinder;
import android.os.IRemoteCallback;
import android.os.Parcel;
+import android.os.ParcelFileDescriptor;
import android.os.Parcelable;
import android.os.PersistableBundle;
import android.os.RemoteException;
@@ -11755,6 +11756,27 @@ public abstract class PackageManager {
}
/**
+ * Similar to {@link #parseAndroidManifest(File, Function)}, but accepting a file descriptor
+ * instead of a File object.
+ *
+ * @param apkFileDescriptor The file descriptor of an application apk.
+ * The parserFunction will be invoked with the XmlResourceParser object
+ * after getting the AndroidManifest.xml of an application package.
+ *
+ * @return Returns the result of the {@link Function#apply(Object)}.
+ *
+ * @throws IOException if the AndroidManifest.xml of an application package cannot be
+ * read or accessed.
+ */
+ @FlaggedApi(android.content.pm.Flags.FLAG_GET_PACKAGE_INFO_WITH_FD)
+ @WorkerThread
+ public <T> T parseAndroidManifest(@NonNull ParcelFileDescriptor apkFileDescriptor,
+ @NonNull Function<XmlResourceParser, T> parserFunction) throws IOException {
+ throw new UnsupportedOperationException(
+ "parseAndroidManifest not implemented in subclass");
+ }
+
+ /**
* @param info The {@link ServiceInfo} to pull the attributes from.
* @param name The name of the Xml metadata where the attributes are stored.
* @param rootTag The root tag of the attributes.
diff --git a/core/java/android/content/pm/flags.aconfig b/core/java/android/content/pm/flags.aconfig
index 061e7f711ba5..d9b0e6dd2681 100644
--- a/core/java/android/content/pm/flags.aconfig
+++ b/core/java/android/content/pm/flags.aconfig
@@ -276,3 +276,11 @@ flag {
bug: "300309050"
is_fixed_read_only: true
}
+
+flag {
+ name: "get_package_info_with_fd"
+ is_exported: true
+ namespace: "package_manager_service"
+ description: "Feature flag to enable the feature to retrieve package info without installation with a file descriptor."
+ bug: "340879905"
+} \ No newline at end of file