diff options
| -rw-r--r-- | core/java/android/content/res/ApkAssets.java | 44 | ||||
| -rw-r--r-- | core/jni/android_content_res_ApkAssets.cpp | 8 |
2 files changed, 36 insertions, 16 deletions
diff --git a/core/java/android/content/res/ApkAssets.java b/core/java/android/content/res/ApkAssets.java index f5e171905096..2d381eb85e90 100644 --- a/core/java/android/content/res/ApkAssets.java +++ b/core/java/android/content/res/ApkAssets.java @@ -25,6 +25,8 @@ import android.content.res.loader.ResourcesProvider; import com.android.internal.annotations.GuardedBy; +import libcore.util.NativeAllocationRegistry; + import java.io.FileDescriptor; import java.io.IOException; import java.lang.annotation.Retention; @@ -101,11 +103,11 @@ public final class ApkAssets { public @interface FormatType {} @GuardedBy("this") - private long mNativePtr; // final, except cleared in finalizer. + private final long mNativePtr; @Nullable @GuardedBy("this") - private final StringBlock mStringBlock; // null or closed if mNativePtr = 0. + private final StringBlock mStringBlock; @PropertyFlags private final int mFlags; @@ -113,6 +115,19 @@ public final class ApkAssets { @Nullable private final AssetsProvider mAssets; + @GuardedBy("this") + @Nullable + private final Runnable mRunNativeCleanup; + + // Use a Holder to allow static initialization of ApkAssets in the boot image, and + // possibly to avoid some initialization ordering issues. + private static class NoImagePreloadHolder { + // TODO(175425996): Make size estimate more accurate + public static final NativeAllocationRegistry REGISTRY = + NativeAllocationRegistry.createMalloced(ApkAssets.class.getClassLoader(), + nativeGetFinalizer()); + } + /** * Creates a new ApkAssets instance from the given path on disk. * @@ -287,6 +302,8 @@ public final class ApkAssets { mFlags = flags; mNativePtr = nativeLoad(format, path, flags, assets); mStringBlock = new StringBlock(nativeGetStringBlock(mNativePtr), true /*useSparse*/); + mRunNativeCleanup = NoImagePreloadHolder.REGISTRY.registerNativeAllocation( + this, mNativePtr); mAssets = assets; } @@ -298,6 +315,8 @@ public final class ApkAssets { mFlags = flags; mNativePtr = nativeLoadFd(format, fd, friendlyName, flags, assets); mStringBlock = new StringBlock(nativeGetStringBlock(mNativePtr), true /*useSparse*/); + mRunNativeCleanup = NoImagePreloadHolder.REGISTRY.registerNativeAllocation( + this, mNativePtr); mAssets = assets; } @@ -309,6 +328,8 @@ public final class ApkAssets { mFlags = flags; mNativePtr = nativeLoadFdOffsets(format, fd, friendlyName, offset, length, flags, assets); mStringBlock = new StringBlock(nativeGetStringBlock(mNativePtr), true /*useSparse*/); + mRunNativeCleanup = NoImagePreloadHolder.REGISTRY.registerNativeAllocation( + this, mNativePtr); mAssets = assets; } @@ -316,6 +337,7 @@ public final class ApkAssets { mFlags = flags; mNativePtr = nativeLoadEmpty(flags, assets); mStringBlock = null; + mRunNativeCleanup = null; mAssets = assets; } @@ -403,22 +425,16 @@ public final class ApkAssets { return "ApkAssets{path=" + getAssetPath() + "}"; } - @Override - protected void finalize() throws Throwable { - close(); - } - /** * Closes this class and the contained {@link #mStringBlock}. */ public void close() { synchronized (this) { - if (mNativePtr != 0) { - if (mStringBlock != null) { - mStringBlock.close(); - } - nativeDestroy(mNativePtr); - mNativePtr = 0; + if (mStringBlock != null) { + mStringBlock.close(); + } + if (mRunNativeCleanup != null) { + mRunNativeCleanup.run(); } } } @@ -433,7 +449,6 @@ public final class ApkAssets { private static native long nativeLoadFdOffsets(@FormatType int format, @NonNull FileDescriptor fd, @NonNull String friendlyName, long offset, long length, @PropertyFlags int flags, @Nullable AssetsProvider asset) throws IOException; - private static native void nativeDestroy(long ptr); private static native @NonNull String nativeGetAssetPath(long ptr); private static native long nativeGetStringBlock(long ptr); private static native boolean nativeIsUpToDate(long ptr); @@ -441,4 +456,5 @@ public final class ApkAssets { private static native @Nullable OverlayableInfo nativeGetOverlayableInfo(long ptr, String overlayableName) throws IOException; private static native boolean nativeDefinesOverlayable(long ptr) throws IOException; + private static native final long nativeGetFinalizer(); } diff --git a/core/jni/android_content_res_ApkAssets.cpp b/core/jni/android_content_res_ApkAssets.cpp index 444bb668dc57..66753e4fc2ee 100644 --- a/core/jni/android_content_res_ApkAssets.cpp +++ b/core/jni/android_content_res_ApkAssets.cpp @@ -315,10 +315,14 @@ static jlong NativeLoadEmpty(JNIEnv* env, jclass /*clazz*/, jint flags, jobject return reinterpret_cast<jlong>(apk_assets.release()); } -static void NativeDestroy(JNIEnv* /*env*/, jclass /*clazz*/, jlong ptr) { +static void NativeDestroy(void* ptr) { delete reinterpret_cast<ApkAssets*>(ptr); } +static jlong NativeGetFinalizer(JNIEnv* /*env*/, jclass /*clazz*/) { + return reinterpret_cast<jlong>(&NativeDestroy); +} + static jstring NativeGetAssetPath(JNIEnv* env, jclass /*clazz*/, jlong ptr) { const ApkAssets* apk_assets = reinterpret_cast<const ApkAssets*>(ptr); return env->NewStringUTF(apk_assets->GetPath().c_str()); @@ -427,7 +431,7 @@ static const JNINativeMethod gApkAssetsMethods[] = { {"nativeLoadFdOffsets", "(ILjava/io/FileDescriptor;Ljava/lang/String;JJILandroid/content/res/loader/AssetsProvider;)J", (void*)NativeLoadFromFdOffset}, - {"nativeDestroy", "(J)V", (void*)NativeDestroy}, + {"nativeGetFinalizer", "()J", (void*)NativeGetFinalizer}, {"nativeGetAssetPath", "(J)Ljava/lang/String;", (void*)NativeGetAssetPath}, {"nativeGetStringBlock", "(J)J", (void*)NativeGetStringBlock}, {"nativeIsUpToDate", "(J)Z", (void*)NativeIsUpToDate}, |