Loading api/current.txt +0 −3 Original line number Diff line number Diff line Loading @@ -12897,11 +12897,8 @@ package android.content.res.loader { method @Nullable public android.content.res.loader.AssetsProvider getAssetsProvider(); method @NonNull public static android.content.res.loader.ResourcesProvider loadFromApk(@NonNull android.os.ParcelFileDescriptor) throws java.io.IOException; method @NonNull public static android.content.res.loader.ResourcesProvider loadFromApk(@NonNull android.os.ParcelFileDescriptor, @Nullable android.content.res.loader.AssetsProvider) throws java.io.IOException; method @NonNull public static android.content.res.loader.ResourcesProvider loadFromApk(@NonNull android.os.SharedMemory) throws java.io.IOException; method @NonNull public static android.content.res.loader.ResourcesProvider loadFromApk(@NonNull android.os.SharedMemory, @Nullable android.content.res.loader.AssetsProvider) throws java.io.IOException; method @NonNull public static android.content.res.loader.ResourcesProvider loadFromSplit(@NonNull android.content.Context, @NonNull String) throws java.io.IOException; method @NonNull public static android.content.res.loader.ResourcesProvider loadFromTable(@NonNull android.os.ParcelFileDescriptor, @Nullable android.content.res.loader.AssetsProvider) throws java.io.IOException; method @NonNull public static android.content.res.loader.ResourcesProvider loadFromTable(@NonNull android.os.SharedMemory, @Nullable android.content.res.loader.AssetsProvider) throws java.io.IOException; } } core/java/android/app/ResourcesManager.java +2 −3 Original line number Diff line number Diff line Loading @@ -346,10 +346,9 @@ public class ResourcesManager { // We must load this from disk. if (overlay) { apkAssets = ApkAssets.loadOverlayFromPath(overlayPathToIdmapPath(path), false /*system*/); apkAssets = ApkAssets.loadOverlayFromPath(overlayPathToIdmapPath(path), 0 /*flags*/); } else { apkAssets = ApkAssets.loadFromPath(path, false /*system*/, sharedLib); apkAssets = ApkAssets.loadFromPath(path, sharedLib ? ApkAssets.PROPERTY_DYNAMIC : 0); } if (mLoadedApkAssets != null) { Loading core/java/android/content/pm/PackageParser.java +1 −1 Original line number Diff line number Diff line Loading @@ -1443,7 +1443,7 @@ public class PackageParser { try { try { apkAssets = fd != null ? ApkAssets.loadFromFd(fd, debugPathName, false, false) ? ApkAssets.loadFromFd(fd, debugPathName, 0 /* flags */) : ApkAssets.loadFromPath(apkPath); } catch (IOException e) { throw new PackageParserException(INSTALL_PARSE_FAILED_NOT_APK, Loading core/java/android/content/pm/parsing/ApkLiteParseUtils.java +1 −1 Original line number Diff line number Diff line Loading @@ -220,7 +220,7 @@ public class ApkLiteParseUtils { try { try { apkAssets = fd != null ? ApkAssets.loadFromFd(fd, debugPathName, false, false) ? ApkAssets.loadFromFd(fd, debugPathName, 0 /* flags */) : ApkAssets.loadFromPath(apkPath); } catch (IOException e) { throw new PackageParser.PackageParserException( Loading core/java/android/content/res/ApkAssets.java +147 −88 Original line number Diff line number Diff line Loading @@ -15,17 +15,19 @@ */ package android.content.res; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.compat.annotation.UnsupportedAppUsage; import android.content.om.OverlayableInfo; import android.content.res.loader.ResourcesProvider; import android.text.TextUtils; import com.android.internal.annotations.GuardedBy; import java.io.FileDescriptor; import java.io.IOException; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.Objects; /** Loading @@ -39,14 +41,72 @@ import java.util.Objects; * @hide */ public final class ApkAssets { @GuardedBy("this") private final long mNativePtr; /** * The apk assets contains framework resource values specified by the system. * This allows some functions to filter out this package when computing what * configurations/resources are available. */ public static final int PROPERTY_SYSTEM = 1 << 0; /** * The apk assets is a shared library or was loaded as a shared library by force. * The package ids of dynamic apk assets are assigned at runtime instead of compile time. */ public static final int PROPERTY_DYNAMIC = 1 << 1; /** * The apk assets has been loaded dynamically using a {@link ResourcesProvider}. * Loader apk assets overlay resources like RROs except they are not backed by an idmap. */ public static final int PROPERTY_LOADER = 1 << 2; /** * The apk assets is a RRO. * An RRO overlays resource values of its target package. */ private static final int PROPERTY_OVERLAY = 1 << 3; /** Flags that change the behavior of loaded apk assets. */ @IntDef(prefix = { "PROPERTY_" }, value = { PROPERTY_SYSTEM, PROPERTY_DYNAMIC, PROPERTY_LOADER, PROPERTY_OVERLAY, }) @Retention(RetentionPolicy.SOURCE) public @interface PropertyFlags {} /** The path used to load the apk assets represents an APK file. */ private static final int FORMAT_APK = 0; /** The path used to load the apk assets represents an idmap file. */ private static final int FORMAT_IDMAP = 1; /** The path used to load the apk assets represents an resources.arsc file. */ private static final int FORMAT_ARSC = 2; // Format types that change how the apk assets are loaded. @IntDef(prefix = { "FORMAT_" }, value = { FORMAT_APK, FORMAT_IDMAP, FORMAT_ARSC, }) @Retention(RetentionPolicy.SOURCE) public @interface FormatType {} @GuardedBy("this") private final long mNativePtr; @Nullable @GuardedBy("this") private final StringBlock mStringBlock; @GuardedBy("this") private final StringBlock mStringBlock; @GuardedBy("this") private boolean mOpen = true; @GuardedBy("this") private boolean mOpen = true; private final boolean mForLoader; @PropertyFlags private final int mFlags; /** * Creates a new ApkAssets instance from the given path on disk. Loading @@ -56,59 +116,59 @@ public final class ApkAssets { * @throws IOException if a disk I/O error or parsing error occurred. */ public static @NonNull ApkAssets loadFromPath(@NonNull String path) throws IOException { return new ApkAssets(path, false /*system*/, false /*forceSharedLib*/, false /*overlay*/, false /*arscOnly*/, false /*forLoader*/); return loadFromPath(path, 0 /* flags */); } /** * Creates a new ApkAssets instance from the given path on disk. * * @param path The path to an APK on disk. * @param system When true, the APK is loaded as a system APK (framework). * @param flags flags that change the behavior of loaded apk assets * @return a new instance of ApkAssets. * @throws IOException if a disk I/O error or parsing error occurred. */ public static @NonNull ApkAssets loadFromPath(@NonNull String path, boolean system) public static @NonNull ApkAssets loadFromPath(@NonNull String path, @PropertyFlags int flags) throws IOException { return new ApkAssets(path, system, false /*forceSharedLib*/, false /*overlay*/, false /*arscOnly*/, false /*forLoader*/); return new ApkAssets(FORMAT_APK, path, flags); } /** * Creates a new ApkAssets instance from the given path on disk. * Creates a new ApkAssets instance from the given file descriptor. * * @param path The path to an APK on disk. * @param system When true, the APK is loaded as a system APK (framework). * @param forceSharedLibrary When true, any packages within the APK with package ID 0x7f are * loaded as a shared library. * Performs a dup of the underlying fd, so you must take care of still closing * the FileDescriptor yourself (and can do that whenever you want). * * @param fd The FileDescriptor of an open, readable APK. * @param friendlyName The friendly name used to identify this ApkAssets when logging. * @param flags flags that change the behavior of loaded apk assets * @return a new instance of ApkAssets. * @throws IOException if a disk I/O error or parsing error occurred. */ public static @NonNull ApkAssets loadFromPath(@NonNull String path, boolean system, boolean forceSharedLibrary) throws IOException { return new ApkAssets(path, system, forceSharedLibrary, false /*overlay*/, false /*arscOnly*/, false /*forLoader*/); public static @NonNull ApkAssets loadFromFd(@NonNull FileDescriptor fd, @NonNull String friendlyName, @PropertyFlags int flags) throws IOException { return new ApkAssets(FORMAT_APK, fd, friendlyName, flags); } /** * Creates a new ApkAssets instance from the given file descriptor. Not for use by applications. * Creates a new ApkAssets instance from the given file descriptor. * * Performs a dup of the underlying fd, so you must take care of still closing * the FileDescriptor yourself (and can do that whenever you want). * * @param fd The FileDescriptor of an open, readable APK. * @param friendlyName The friendly name used to identify this ApkAssets when logging. * @param system When true, the APK is loaded as a system APK (framework). * @param forceSharedLibrary When true, any packages within the APK with package ID 0x7f are * loaded as a shared library. * @param offset The location within the file that the apk starts. This must be 0 if length is * {@link AssetFileDescriptor#UNKNOWN_LENGTH}. * @param length The number of bytes of the apk, or {@link AssetFileDescriptor#UNKNOWN_LENGTH} * if it extends to the end of the file. * @param flags flags that change the behavior of loaded apk assets * @return a new instance of ApkAssets. * @throws IOException if a disk I/O error or parsing error occurred. */ public static @NonNull ApkAssets loadFromFd(@NonNull FileDescriptor fd, @NonNull String friendlyName, boolean system, boolean forceSharedLibrary) @NonNull String friendlyName, long offset, long length, @PropertyFlags int flags) throws IOException { return new ApkAssets(fd, friendlyName, system, forceSharedLibrary, false /*arscOnly*/, false /*forLoader*/); return new ApkAssets(FORMAT_APK, fd, friendlyName, offset, length, flags); } /** Loading @@ -116,99 +176,101 @@ public final class ApkAssets { * is encoded within the IDMAP. * * @param idmapPath Path to the IDMAP of an overlay APK. * @param system When true, the APK is loaded as a system APK (framework). * @param flags flags that change the behavior of loaded apk assets * @return a new instance of ApkAssets. * @throws IOException if a disk I/O error or parsing error occurred. */ public static @NonNull ApkAssets loadOverlayFromPath(@NonNull String idmapPath, boolean system) throws IOException { return new ApkAssets(idmapPath, system, false /*forceSharedLibrary*/, true /*overlay*/, false /*arscOnly*/, false /*forLoader*/); public static @NonNull ApkAssets loadOverlayFromPath(@NonNull String idmapPath, @PropertyFlags int flags) throws IOException { return new ApkAssets(FORMAT_IDMAP, idmapPath, flags); } /** * Creates a new ApkAssets instance from the given path on disk for use with a * {@link ResourcesProvider}. * * @param path The path to an APK on disk. * @return a new instance of ApkAssets. * @throws IOException if a disk I/O error or parsing error occurred. */ public static @NonNull ApkAssets loadApkForLoader(@NonNull String path) throws IOException { return new ApkAssets(path, false /*system*/, false /*forceSharedLibrary*/, false /*overlay*/, false /*arscOnly*/, true /*forLoader*/); } /** * Creates a new ApkAssets instance from the given file descriptor for use with a * {@link ResourcesProvider}. * Creates a new ApkAssets instance from the given file descriptor representing a resources.arsc * for use with a {@link ResourcesProvider}. * * Performs a dup of the underlying fd, so you must take care of still closing * the FileDescriptor yourself (and can do that whenever you want). * * @param fd The FileDescriptor of an open, readable APK. * @param fd The FileDescriptor of an open, readable resources.arsc. * @param friendlyName The friendly name used to identify this ApkAssets when logging. * @param flags flags that change the behavior of loaded apk assets * @return a new instance of ApkAssets. * @throws IOException if a disk I/O error or parsing error occurred. */ @NonNull public static ApkAssets loadApkForLoader(@NonNull FileDescriptor fd) throws IOException { return new ApkAssets(fd, TextUtils.emptyIfNull(fd.toString()), false /*system*/, false /*forceSharedLib*/, false /*arscOnly*/, true /*forLoader*/); public static @NonNull ApkAssets loadTableFromFd(@NonNull FileDescriptor fd, @NonNull String friendlyName, @PropertyFlags int flags) throws IOException { return new ApkAssets(FORMAT_ARSC, fd, friendlyName, flags); } /** * Creates a new ApkAssets instance from the given file descriptor representing an ARSC * Creates a new ApkAssets instance from the given file descriptor representing a resources.arsc * for use with a {@link ResourcesProvider}. * * Performs a dup of the underlying fd, so you must take care of still closing * the FileDescriptor yourself (and can do that whenever you want). * * @param fd The FileDescriptor of an open, readable .arsc. * @param fd The FileDescriptor of an open, readable resources.arsc. * @param friendlyName The friendly name used to identify this ApkAssets when logging. * @param offset The location within the file that the table starts. This must be 0 if length is * {@link AssetFileDescriptor#UNKNOWN_LENGTH}. * @param length The number of bytes of the table, or {@link AssetFileDescriptor#UNKNOWN_LENGTH} * if it extends to the end of the file. * @param flags flags that change the behavior of loaded apk assets * @return a new instance of ApkAssets. * @throws IOException if a disk I/O error or parsing error occurred. */ public static @NonNull ApkAssets loadArscForLoader(@NonNull FileDescriptor fd) public static @NonNull ApkAssets loadTableFromFd(@NonNull FileDescriptor fd, @NonNull String friendlyName, long offset, long length, @PropertyFlags int flags) throws IOException { return new ApkAssets(fd, TextUtils.emptyIfNull(fd.toString()), false /*system*/, false /*forceSharedLib*/, true /*arscOnly*/, true /*forLoader*/); return new ApkAssets(FORMAT_ARSC, fd, friendlyName, offset, length, flags); } /** * Generates an entirely empty ApkAssets. Needed because the ApkAssets instance and presence * is required for a lot of APIs, and it's easier to have a non-null reference rather than * tracking a separate identifier. * * @param flags flags that change the behavior of loaded apk assets */ @NonNull public static ApkAssets loadEmptyForLoader() { return new ApkAssets(true); public static ApkAssets loadEmptyForLoader(@PropertyFlags int flags) { return new ApkAssets(flags); } private ApkAssets(boolean forLoader) { mForLoader = forLoader; mNativePtr = nativeLoadEmpty(forLoader); mStringBlock = null; private ApkAssets(@FormatType int format, @NonNull String path, @PropertyFlags int flags) throws IOException { Objects.requireNonNull(path, "path"); mFlags = flags; mNativePtr = nativeLoad(format, path, flags); mStringBlock = new StringBlock(nativeGetStringBlock(mNativePtr), true /*useSparse*/); } private ApkAssets(@NonNull String path, boolean system, boolean forceSharedLib, boolean overlay, boolean arscOnly, boolean forLoader) throws IOException { mForLoader = forLoader; Objects.requireNonNull(path, "path"); mNativePtr = arscOnly ? nativeLoadArsc(path, forLoader) : nativeLoad(path, system, forceSharedLib, overlay, forLoader); private ApkAssets(@FormatType int format, @NonNull FileDescriptor fd, @NonNull String friendlyName, @PropertyFlags int flags) throws IOException { Objects.requireNonNull(fd, "fd"); Objects.requireNonNull(friendlyName, "friendlyName"); mFlags = flags; mNativePtr = nativeLoadFd(format, fd, friendlyName, flags); mStringBlock = new StringBlock(nativeGetStringBlock(mNativePtr), true /*useSparse*/); } private ApkAssets(@NonNull FileDescriptor fd, @NonNull String friendlyName, boolean system, boolean forceSharedLib, boolean arscOnly, boolean forLoader) throws IOException { mForLoader = forLoader; private ApkAssets(@FormatType int format, @NonNull FileDescriptor fd, @NonNull String friendlyName, long offset, long length, @PropertyFlags int flags) throws IOException { Objects.requireNonNull(fd, "fd"); Objects.requireNonNull(friendlyName, "friendlyName"); mNativePtr = arscOnly ? nativeLoadArscFromFd(fd, friendlyName, forLoader) : nativeLoadFromFd(fd, friendlyName, system, forceSharedLib, forLoader); mFlags = flags; mNativePtr = nativeLoadFdOffsets(format, fd, friendlyName, offset, length, flags); mStringBlock = new StringBlock(nativeGetStringBlock(mNativePtr), true /*useSparse*/); } private ApkAssets(@PropertyFlags int flags) { mFlags = flags; mNativePtr = nativeLoadEmpty(flags); mStringBlock = null; } @UnsupportedAppUsage public @NonNull String getAssetPath() { synchronized (this) { Loading @@ -226,8 +288,9 @@ public final class ApkAssets { } } /** Returns whether this apk assets was loaded using a {@link ResourcesProvider}. */ public boolean isForLoader() { return mForLoader; return (mFlags & PROPERTY_LOADER) != 0; } /** Loading Loading @@ -300,18 +363,14 @@ public final class ApkAssets { } } private static native long nativeLoad(@NonNull String path, boolean system, boolean forceSharedLib, boolean overlay, boolean forLoader) throws IOException; private static native long nativeLoadFromFd(@NonNull FileDescriptor fd, @NonNull String friendlyName, boolean system, boolean forceSharedLib, boolean forLoader) throws IOException; private static native long nativeLoadArsc(@NonNull String path, boolean forLoader) throws IOException; private static native long nativeLoadArscFromFd(@NonNull FileDescriptor fd, @NonNull String friendlyName, boolean forLoader) throws IOException; private static native long nativeLoadEmpty(boolean forLoader); private static native long nativeLoad(@FormatType int format, @NonNull String path, @PropertyFlags int flags) throws IOException; private static native long nativeLoadEmpty(@PropertyFlags int flags); private static native long nativeLoadFd(@FormatType int format, @NonNull FileDescriptor fd, @NonNull String friendlyName, @PropertyFlags int flags) throws IOException; private static native long nativeLoadFdOffsets(@FormatType int format, @NonNull FileDescriptor fd, @NonNull String friendlyName, long offset, long length, @PropertyFlags int flags) throws IOException; private static native void nativeDestroy(long ptr); private static native @NonNull String nativeGetAssetPath(long ptr); private static native long nativeGetStringBlock(long ptr); Loading Loading
api/current.txt +0 −3 Original line number Diff line number Diff line Loading @@ -12897,11 +12897,8 @@ package android.content.res.loader { method @Nullable public android.content.res.loader.AssetsProvider getAssetsProvider(); method @NonNull public static android.content.res.loader.ResourcesProvider loadFromApk(@NonNull android.os.ParcelFileDescriptor) throws java.io.IOException; method @NonNull public static android.content.res.loader.ResourcesProvider loadFromApk(@NonNull android.os.ParcelFileDescriptor, @Nullable android.content.res.loader.AssetsProvider) throws java.io.IOException; method @NonNull public static android.content.res.loader.ResourcesProvider loadFromApk(@NonNull android.os.SharedMemory) throws java.io.IOException; method @NonNull public static android.content.res.loader.ResourcesProvider loadFromApk(@NonNull android.os.SharedMemory, @Nullable android.content.res.loader.AssetsProvider) throws java.io.IOException; method @NonNull public static android.content.res.loader.ResourcesProvider loadFromSplit(@NonNull android.content.Context, @NonNull String) throws java.io.IOException; method @NonNull public static android.content.res.loader.ResourcesProvider loadFromTable(@NonNull android.os.ParcelFileDescriptor, @Nullable android.content.res.loader.AssetsProvider) throws java.io.IOException; method @NonNull public static android.content.res.loader.ResourcesProvider loadFromTable(@NonNull android.os.SharedMemory, @Nullable android.content.res.loader.AssetsProvider) throws java.io.IOException; } }
core/java/android/app/ResourcesManager.java +2 −3 Original line number Diff line number Diff line Loading @@ -346,10 +346,9 @@ public class ResourcesManager { // We must load this from disk. if (overlay) { apkAssets = ApkAssets.loadOverlayFromPath(overlayPathToIdmapPath(path), false /*system*/); apkAssets = ApkAssets.loadOverlayFromPath(overlayPathToIdmapPath(path), 0 /*flags*/); } else { apkAssets = ApkAssets.loadFromPath(path, false /*system*/, sharedLib); apkAssets = ApkAssets.loadFromPath(path, sharedLib ? ApkAssets.PROPERTY_DYNAMIC : 0); } if (mLoadedApkAssets != null) { Loading
core/java/android/content/pm/PackageParser.java +1 −1 Original line number Diff line number Diff line Loading @@ -1443,7 +1443,7 @@ public class PackageParser { try { try { apkAssets = fd != null ? ApkAssets.loadFromFd(fd, debugPathName, false, false) ? ApkAssets.loadFromFd(fd, debugPathName, 0 /* flags */) : ApkAssets.loadFromPath(apkPath); } catch (IOException e) { throw new PackageParserException(INSTALL_PARSE_FAILED_NOT_APK, Loading
core/java/android/content/pm/parsing/ApkLiteParseUtils.java +1 −1 Original line number Diff line number Diff line Loading @@ -220,7 +220,7 @@ public class ApkLiteParseUtils { try { try { apkAssets = fd != null ? ApkAssets.loadFromFd(fd, debugPathName, false, false) ? ApkAssets.loadFromFd(fd, debugPathName, 0 /* flags */) : ApkAssets.loadFromPath(apkPath); } catch (IOException e) { throw new PackageParser.PackageParserException( Loading
core/java/android/content/res/ApkAssets.java +147 −88 Original line number Diff line number Diff line Loading @@ -15,17 +15,19 @@ */ package android.content.res; import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.compat.annotation.UnsupportedAppUsage; import android.content.om.OverlayableInfo; import android.content.res.loader.ResourcesProvider; import android.text.TextUtils; import com.android.internal.annotations.GuardedBy; import java.io.FileDescriptor; import java.io.IOException; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.util.Objects; /** Loading @@ -39,14 +41,72 @@ import java.util.Objects; * @hide */ public final class ApkAssets { @GuardedBy("this") private final long mNativePtr; /** * The apk assets contains framework resource values specified by the system. * This allows some functions to filter out this package when computing what * configurations/resources are available. */ public static final int PROPERTY_SYSTEM = 1 << 0; /** * The apk assets is a shared library or was loaded as a shared library by force. * The package ids of dynamic apk assets are assigned at runtime instead of compile time. */ public static final int PROPERTY_DYNAMIC = 1 << 1; /** * The apk assets has been loaded dynamically using a {@link ResourcesProvider}. * Loader apk assets overlay resources like RROs except they are not backed by an idmap. */ public static final int PROPERTY_LOADER = 1 << 2; /** * The apk assets is a RRO. * An RRO overlays resource values of its target package. */ private static final int PROPERTY_OVERLAY = 1 << 3; /** Flags that change the behavior of loaded apk assets. */ @IntDef(prefix = { "PROPERTY_" }, value = { PROPERTY_SYSTEM, PROPERTY_DYNAMIC, PROPERTY_LOADER, PROPERTY_OVERLAY, }) @Retention(RetentionPolicy.SOURCE) public @interface PropertyFlags {} /** The path used to load the apk assets represents an APK file. */ private static final int FORMAT_APK = 0; /** The path used to load the apk assets represents an idmap file. */ private static final int FORMAT_IDMAP = 1; /** The path used to load the apk assets represents an resources.arsc file. */ private static final int FORMAT_ARSC = 2; // Format types that change how the apk assets are loaded. @IntDef(prefix = { "FORMAT_" }, value = { FORMAT_APK, FORMAT_IDMAP, FORMAT_ARSC, }) @Retention(RetentionPolicy.SOURCE) public @interface FormatType {} @GuardedBy("this") private final long mNativePtr; @Nullable @GuardedBy("this") private final StringBlock mStringBlock; @GuardedBy("this") private final StringBlock mStringBlock; @GuardedBy("this") private boolean mOpen = true; @GuardedBy("this") private boolean mOpen = true; private final boolean mForLoader; @PropertyFlags private final int mFlags; /** * Creates a new ApkAssets instance from the given path on disk. Loading @@ -56,59 +116,59 @@ public final class ApkAssets { * @throws IOException if a disk I/O error or parsing error occurred. */ public static @NonNull ApkAssets loadFromPath(@NonNull String path) throws IOException { return new ApkAssets(path, false /*system*/, false /*forceSharedLib*/, false /*overlay*/, false /*arscOnly*/, false /*forLoader*/); return loadFromPath(path, 0 /* flags */); } /** * Creates a new ApkAssets instance from the given path on disk. * * @param path The path to an APK on disk. * @param system When true, the APK is loaded as a system APK (framework). * @param flags flags that change the behavior of loaded apk assets * @return a new instance of ApkAssets. * @throws IOException if a disk I/O error or parsing error occurred. */ public static @NonNull ApkAssets loadFromPath(@NonNull String path, boolean system) public static @NonNull ApkAssets loadFromPath(@NonNull String path, @PropertyFlags int flags) throws IOException { return new ApkAssets(path, system, false /*forceSharedLib*/, false /*overlay*/, false /*arscOnly*/, false /*forLoader*/); return new ApkAssets(FORMAT_APK, path, flags); } /** * Creates a new ApkAssets instance from the given path on disk. * Creates a new ApkAssets instance from the given file descriptor. * * @param path The path to an APK on disk. * @param system When true, the APK is loaded as a system APK (framework). * @param forceSharedLibrary When true, any packages within the APK with package ID 0x7f are * loaded as a shared library. * Performs a dup of the underlying fd, so you must take care of still closing * the FileDescriptor yourself (and can do that whenever you want). * * @param fd The FileDescriptor of an open, readable APK. * @param friendlyName The friendly name used to identify this ApkAssets when logging. * @param flags flags that change the behavior of loaded apk assets * @return a new instance of ApkAssets. * @throws IOException if a disk I/O error or parsing error occurred. */ public static @NonNull ApkAssets loadFromPath(@NonNull String path, boolean system, boolean forceSharedLibrary) throws IOException { return new ApkAssets(path, system, forceSharedLibrary, false /*overlay*/, false /*arscOnly*/, false /*forLoader*/); public static @NonNull ApkAssets loadFromFd(@NonNull FileDescriptor fd, @NonNull String friendlyName, @PropertyFlags int flags) throws IOException { return new ApkAssets(FORMAT_APK, fd, friendlyName, flags); } /** * Creates a new ApkAssets instance from the given file descriptor. Not for use by applications. * Creates a new ApkAssets instance from the given file descriptor. * * Performs a dup of the underlying fd, so you must take care of still closing * the FileDescriptor yourself (and can do that whenever you want). * * @param fd The FileDescriptor of an open, readable APK. * @param friendlyName The friendly name used to identify this ApkAssets when logging. * @param system When true, the APK is loaded as a system APK (framework). * @param forceSharedLibrary When true, any packages within the APK with package ID 0x7f are * loaded as a shared library. * @param offset The location within the file that the apk starts. This must be 0 if length is * {@link AssetFileDescriptor#UNKNOWN_LENGTH}. * @param length The number of bytes of the apk, or {@link AssetFileDescriptor#UNKNOWN_LENGTH} * if it extends to the end of the file. * @param flags flags that change the behavior of loaded apk assets * @return a new instance of ApkAssets. * @throws IOException if a disk I/O error or parsing error occurred. */ public static @NonNull ApkAssets loadFromFd(@NonNull FileDescriptor fd, @NonNull String friendlyName, boolean system, boolean forceSharedLibrary) @NonNull String friendlyName, long offset, long length, @PropertyFlags int flags) throws IOException { return new ApkAssets(fd, friendlyName, system, forceSharedLibrary, false /*arscOnly*/, false /*forLoader*/); return new ApkAssets(FORMAT_APK, fd, friendlyName, offset, length, flags); } /** Loading @@ -116,99 +176,101 @@ public final class ApkAssets { * is encoded within the IDMAP. * * @param idmapPath Path to the IDMAP of an overlay APK. * @param system When true, the APK is loaded as a system APK (framework). * @param flags flags that change the behavior of loaded apk assets * @return a new instance of ApkAssets. * @throws IOException if a disk I/O error or parsing error occurred. */ public static @NonNull ApkAssets loadOverlayFromPath(@NonNull String idmapPath, boolean system) throws IOException { return new ApkAssets(idmapPath, system, false /*forceSharedLibrary*/, true /*overlay*/, false /*arscOnly*/, false /*forLoader*/); public static @NonNull ApkAssets loadOverlayFromPath(@NonNull String idmapPath, @PropertyFlags int flags) throws IOException { return new ApkAssets(FORMAT_IDMAP, idmapPath, flags); } /** * Creates a new ApkAssets instance from the given path on disk for use with a * {@link ResourcesProvider}. * * @param path The path to an APK on disk. * @return a new instance of ApkAssets. * @throws IOException if a disk I/O error or parsing error occurred. */ public static @NonNull ApkAssets loadApkForLoader(@NonNull String path) throws IOException { return new ApkAssets(path, false /*system*/, false /*forceSharedLibrary*/, false /*overlay*/, false /*arscOnly*/, true /*forLoader*/); } /** * Creates a new ApkAssets instance from the given file descriptor for use with a * {@link ResourcesProvider}. * Creates a new ApkAssets instance from the given file descriptor representing a resources.arsc * for use with a {@link ResourcesProvider}. * * Performs a dup of the underlying fd, so you must take care of still closing * the FileDescriptor yourself (and can do that whenever you want). * * @param fd The FileDescriptor of an open, readable APK. * @param fd The FileDescriptor of an open, readable resources.arsc. * @param friendlyName The friendly name used to identify this ApkAssets when logging. * @param flags flags that change the behavior of loaded apk assets * @return a new instance of ApkAssets. * @throws IOException if a disk I/O error or parsing error occurred. */ @NonNull public static ApkAssets loadApkForLoader(@NonNull FileDescriptor fd) throws IOException { return new ApkAssets(fd, TextUtils.emptyIfNull(fd.toString()), false /*system*/, false /*forceSharedLib*/, false /*arscOnly*/, true /*forLoader*/); public static @NonNull ApkAssets loadTableFromFd(@NonNull FileDescriptor fd, @NonNull String friendlyName, @PropertyFlags int flags) throws IOException { return new ApkAssets(FORMAT_ARSC, fd, friendlyName, flags); } /** * Creates a new ApkAssets instance from the given file descriptor representing an ARSC * Creates a new ApkAssets instance from the given file descriptor representing a resources.arsc * for use with a {@link ResourcesProvider}. * * Performs a dup of the underlying fd, so you must take care of still closing * the FileDescriptor yourself (and can do that whenever you want). * * @param fd The FileDescriptor of an open, readable .arsc. * @param fd The FileDescriptor of an open, readable resources.arsc. * @param friendlyName The friendly name used to identify this ApkAssets when logging. * @param offset The location within the file that the table starts. This must be 0 if length is * {@link AssetFileDescriptor#UNKNOWN_LENGTH}. * @param length The number of bytes of the table, or {@link AssetFileDescriptor#UNKNOWN_LENGTH} * if it extends to the end of the file. * @param flags flags that change the behavior of loaded apk assets * @return a new instance of ApkAssets. * @throws IOException if a disk I/O error or parsing error occurred. */ public static @NonNull ApkAssets loadArscForLoader(@NonNull FileDescriptor fd) public static @NonNull ApkAssets loadTableFromFd(@NonNull FileDescriptor fd, @NonNull String friendlyName, long offset, long length, @PropertyFlags int flags) throws IOException { return new ApkAssets(fd, TextUtils.emptyIfNull(fd.toString()), false /*system*/, false /*forceSharedLib*/, true /*arscOnly*/, true /*forLoader*/); return new ApkAssets(FORMAT_ARSC, fd, friendlyName, offset, length, flags); } /** * Generates an entirely empty ApkAssets. Needed because the ApkAssets instance and presence * is required for a lot of APIs, and it's easier to have a non-null reference rather than * tracking a separate identifier. * * @param flags flags that change the behavior of loaded apk assets */ @NonNull public static ApkAssets loadEmptyForLoader() { return new ApkAssets(true); public static ApkAssets loadEmptyForLoader(@PropertyFlags int flags) { return new ApkAssets(flags); } private ApkAssets(boolean forLoader) { mForLoader = forLoader; mNativePtr = nativeLoadEmpty(forLoader); mStringBlock = null; private ApkAssets(@FormatType int format, @NonNull String path, @PropertyFlags int flags) throws IOException { Objects.requireNonNull(path, "path"); mFlags = flags; mNativePtr = nativeLoad(format, path, flags); mStringBlock = new StringBlock(nativeGetStringBlock(mNativePtr), true /*useSparse*/); } private ApkAssets(@NonNull String path, boolean system, boolean forceSharedLib, boolean overlay, boolean arscOnly, boolean forLoader) throws IOException { mForLoader = forLoader; Objects.requireNonNull(path, "path"); mNativePtr = arscOnly ? nativeLoadArsc(path, forLoader) : nativeLoad(path, system, forceSharedLib, overlay, forLoader); private ApkAssets(@FormatType int format, @NonNull FileDescriptor fd, @NonNull String friendlyName, @PropertyFlags int flags) throws IOException { Objects.requireNonNull(fd, "fd"); Objects.requireNonNull(friendlyName, "friendlyName"); mFlags = flags; mNativePtr = nativeLoadFd(format, fd, friendlyName, flags); mStringBlock = new StringBlock(nativeGetStringBlock(mNativePtr), true /*useSparse*/); } private ApkAssets(@NonNull FileDescriptor fd, @NonNull String friendlyName, boolean system, boolean forceSharedLib, boolean arscOnly, boolean forLoader) throws IOException { mForLoader = forLoader; private ApkAssets(@FormatType int format, @NonNull FileDescriptor fd, @NonNull String friendlyName, long offset, long length, @PropertyFlags int flags) throws IOException { Objects.requireNonNull(fd, "fd"); Objects.requireNonNull(friendlyName, "friendlyName"); mNativePtr = arscOnly ? nativeLoadArscFromFd(fd, friendlyName, forLoader) : nativeLoadFromFd(fd, friendlyName, system, forceSharedLib, forLoader); mFlags = flags; mNativePtr = nativeLoadFdOffsets(format, fd, friendlyName, offset, length, flags); mStringBlock = new StringBlock(nativeGetStringBlock(mNativePtr), true /*useSparse*/); } private ApkAssets(@PropertyFlags int flags) { mFlags = flags; mNativePtr = nativeLoadEmpty(flags); mStringBlock = null; } @UnsupportedAppUsage public @NonNull String getAssetPath() { synchronized (this) { Loading @@ -226,8 +288,9 @@ public final class ApkAssets { } } /** Returns whether this apk assets was loaded using a {@link ResourcesProvider}. */ public boolean isForLoader() { return mForLoader; return (mFlags & PROPERTY_LOADER) != 0; } /** Loading Loading @@ -300,18 +363,14 @@ public final class ApkAssets { } } private static native long nativeLoad(@NonNull String path, boolean system, boolean forceSharedLib, boolean overlay, boolean forLoader) throws IOException; private static native long nativeLoadFromFd(@NonNull FileDescriptor fd, @NonNull String friendlyName, boolean system, boolean forceSharedLib, boolean forLoader) throws IOException; private static native long nativeLoadArsc(@NonNull String path, boolean forLoader) throws IOException; private static native long nativeLoadArscFromFd(@NonNull FileDescriptor fd, @NonNull String friendlyName, boolean forLoader) throws IOException; private static native long nativeLoadEmpty(boolean forLoader); private static native long nativeLoad(@FormatType int format, @NonNull String path, @PropertyFlags int flags) throws IOException; private static native long nativeLoadEmpty(@PropertyFlags int flags); private static native long nativeLoadFd(@FormatType int format, @NonNull FileDescriptor fd, @NonNull String friendlyName, @PropertyFlags int flags) throws IOException; private static native long nativeLoadFdOffsets(@FormatType int format, @NonNull FileDescriptor fd, @NonNull String friendlyName, long offset, long length, @PropertyFlags int flags) throws IOException; private static native void nativeDestroy(long ptr); private static native @NonNull String nativeGetAssetPath(long ptr); private static native long nativeGetStringBlock(long ptr); Loading