diff options
author | Derek Sollenberger <djsollen@google.com> | 2020-02-11 13:11:42 +0000 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2020-02-11 13:11:42 +0000 |
commit | e2edcebb2b0de717df588ad9b2c2747b6fdc5711 (patch) | |
tree | 02da29b0d155c81d4b144c772a72de284f8f913c | |
parent | 20024529db5c3b5d216faa1a654981f4ebff95b8 (diff) | |
parent | 4db7bd28e76897a97a848adfd1051904492bf400 (diff) |
Merge "Consolidate AssetManager calls in Font/FontFamily"
-rw-r--r-- | core/jni/android/graphics/FontFamily.cpp | 61 | ||||
-rw-r--r-- | core/jni/android/graphics/fonts/Font.cpp | 63 | ||||
-rw-r--r-- | graphics/java/android/graphics/FontFamily.java | 20 | ||||
-rw-r--r-- | graphics/java/android/graphics/fonts/Font.java | 104 |
4 files changed, 75 insertions, 173 deletions
diff --git a/core/jni/android/graphics/FontFamily.cpp b/core/jni/android/graphics/FontFamily.cpp index 2a56fd6d6d17..0fd9cc7e9989 100644 --- a/core/jni/android/graphics/FontFamily.cpp +++ b/core/jni/android/graphics/FontFamily.cpp @@ -27,8 +27,6 @@ #include <nativehelper/ScopedPrimitiveArray.h> #include <nativehelper/ScopedUtfChars.h> #include <android_runtime/AndroidRuntime.h> -#include <android_runtime/android_util_AssetManager.h> -#include <androidfw/AssetManager2.h> #include "Utils.h" #include "FontUtils.h" @@ -212,63 +210,6 @@ static jboolean FontFamily_addFontWeightStyle(JNIEnv* env, jobject clazz, jlong return addSkTypeface(builder, std::move(data), ttcIndex, weight, isItalic); } -static void releaseAsset(const void* ptr, void* context) { - delete static_cast<Asset*>(context); -} - -static jboolean FontFamily_addFontFromAssetManager(JNIEnv* env, jobject, jlong builderPtr, - jobject jassetMgr, jstring jpath, jint cookie, jboolean isAsset, jint ttcIndex, - jint weight, jint isItalic) { -#ifdef __ANDROID__ // Layoutlib does not support native AssetManager - NPE_CHECK_RETURN_ZERO(env, jassetMgr); - NPE_CHECK_RETURN_ZERO(env, jpath); - - NativeFamilyBuilder* builder = toNativeBuilder(builderPtr); - Guarded<AssetManager2>* mgr = AssetManagerForJavaObject(env, jassetMgr); - if (NULL == mgr) { - builder->axes.clear(); - return false; - } - - ScopedUtfChars str(env, jpath); - if (str.c_str() == nullptr) { - builder->axes.clear(); - return false; - } - - std::unique_ptr<Asset> asset; - { - ScopedLock<AssetManager2> locked_mgr(*mgr); - if (isAsset) { - asset = locked_mgr->Open(str.c_str(), Asset::ACCESS_BUFFER); - } else if (cookie > 0) { - // Valid java cookies are 1-based, but AssetManager cookies are 0-based. - asset = locked_mgr->OpenNonAsset(str.c_str(), static_cast<ApkAssetsCookie>(cookie - 1), - Asset::ACCESS_BUFFER); - } else { - asset = locked_mgr->OpenNonAsset(str.c_str(), Asset::ACCESS_BUFFER); - } - } - - if (nullptr == asset) { - builder->axes.clear(); - return false; - } - - const void* buf = asset->getBuffer(false); - if (NULL == buf) { - builder->axes.clear(); - return false; - } - - sk_sp<SkData> data(SkData::MakeWithProc(buf, asset->getLength(), releaseAsset, - asset.release())); - return addSkTypeface(builder, std::move(data), ttcIndex, weight, isItalic); -#else - return false; -#endif -} - static void FontFamily_addAxisValue(CRITICAL_JNI_PARAMS_COMMA jlong builderPtr, jint tag, jfloat value) { NativeFamilyBuilder* builder = toNativeBuilder(builderPtr); builder->axes.push_back({static_cast<minikin::AxisTag>(tag), value}); @@ -284,8 +225,6 @@ static const JNINativeMethod gFontFamilyMethods[] = { { "nAddFont", "(JLjava/nio/ByteBuffer;III)Z", (void*)FontFamily_addFont }, { "nAddFontWeightStyle", "(JLjava/nio/ByteBuffer;III)Z", (void*)FontFamily_addFontWeightStyle }, - { "nAddFontFromAssetManager", "(JLandroid/content/res/AssetManager;Ljava/lang/String;IZIII)Z", - (void*)FontFamily_addFontFromAssetManager }, { "nAddAxisValue", "(JIF)V", (void*)FontFamily_addAxisValue }, }; diff --git a/core/jni/android/graphics/fonts/Font.cpp b/core/jni/android/graphics/fonts/Font.cpp index 8d84e870d205..bfb9bae45f0c 100644 --- a/core/jni/android/graphics/fonts/Font.cpp +++ b/core/jni/android/graphics/fonts/Font.cpp @@ -26,8 +26,6 @@ #include "GraphicsJNI.h" #include <nativehelper/ScopedUtfChars.h> #include <android_runtime/AndroidRuntime.h> -#include <android_runtime/android_util_AssetManager.h> -#include <androidfw/AssetManager2.h> #include "Utils.h" #include "FontUtils.h" @@ -48,14 +46,6 @@ static inline NativeFontBuilder* toBuilder(jlong ptr) { return reinterpret_cast<NativeFontBuilder*>(ptr); } -static inline Asset* toAsset(jlong ptr) { - return reinterpret_cast<Asset*>(ptr); -} - -static void releaseAsset(jlong asset) { - delete toAsset(asset); -} - static void releaseFont(jlong font) { delete reinterpret_cast<FontWrapper*>(font); } @@ -79,54 +69,6 @@ static void release_global_ref(const void* /*data*/, void* context) { } // Regular JNI -static jlong Font_Builder_getNativeAsset( - JNIEnv* env, jobject clazz, jobject assetMgr, jstring path, jboolean isAsset, jint cookie) { -#ifdef __ANDROID__ // Layoutlib does not support native AssetManager - NPE_CHECK_RETURN_ZERO(env, assetMgr); - NPE_CHECK_RETURN_ZERO(env, path); - - Guarded<AssetManager2>* mgr = AssetManagerForJavaObject(env, assetMgr); - if (mgr == nullptr) { - return 0; - } - - ScopedUtfChars str(env, path); - if (str.c_str() == nullptr) { - return 0; - } - - std::unique_ptr<Asset> asset; - { - ScopedLock<AssetManager2> locked_mgr(*mgr); - if (isAsset) { - asset = locked_mgr->Open(str.c_str(), Asset::ACCESS_BUFFER); - } else if (cookie > 0) { - // Valid java cookies are 1-based, but AssetManager cookies are 0-based. - asset = locked_mgr->OpenNonAsset(str.c_str(), static_cast<ApkAssetsCookie>(cookie - 1), - Asset::ACCESS_BUFFER); - } else { - asset = locked_mgr->OpenNonAsset(str.c_str(), Asset::ACCESS_BUFFER); - } - } - - return reinterpret_cast<jlong>(asset.release()); -#else - return 0; -#endif -} - -// Regular JNI -static jobject Font_Builder_getAssetBuffer(JNIEnv* env, jobject clazz, jlong nativeAsset) { - Asset* asset = toAsset(nativeAsset); - return env->NewDirectByteBuffer(const_cast<void*>(asset->getBuffer(false)), asset->getLength()); -} - -// CriticalNative -static jlong Font_Builder_getReleaseNativeAssetFunc(CRITICAL_JNI_PARAMS) { - return reinterpret_cast<jlong>(&releaseAsset); -} - -// Regular JNI static jlong Font_Builder_initBuilder(JNIEnv*, jobject) { return reinterpret_cast<jlong>(new NativeFontBuilder()); } @@ -196,11 +138,6 @@ static const JNINativeMethod gFontBuilderMethods[] = { { "nAddAxis", "(JIF)V", (void*) Font_Builder_addAxis }, { "nBuild", "(JLjava/nio/ByteBuffer;Ljava/lang/String;IZI)J", (void*) Font_Builder_build }, { "nGetReleaseNativeFont", "()J", (void*) Font_Builder_getReleaseNativeFont }, - - { "nGetNativeAsset", "(Landroid/content/res/AssetManager;Ljava/lang/String;ZI)J", - (void*) Font_Builder_getNativeAsset }, - { "nGetAssetBuffer", "(J)Ljava/nio/ByteBuffer;", (void*) Font_Builder_getAssetBuffer }, - { "nGetReleaseNativeAssetFunc", "()J", (void*) Font_Builder_getReleaseNativeAssetFunc }, }; int register_android_graphics_fonts_Font(JNIEnv* env) { diff --git a/graphics/java/android/graphics/FontFamily.java b/graphics/java/android/graphics/FontFamily.java index 447f043392c2..f50de1665453 100644 --- a/graphics/java/android/graphics/FontFamily.java +++ b/graphics/java/android/graphics/FontFamily.java @@ -19,6 +19,7 @@ package android.graphics; import android.annotation.Nullable; import android.compat.annotation.UnsupportedAppUsage; import android.content.res.AssetManager; +import android.graphics.fonts.Font; import android.graphics.fonts.FontVariationAxis; import android.os.Build; import android.text.TextUtils; @@ -195,18 +196,13 @@ public class FontFamily { if (mBuilderPtr == 0) { throw new IllegalStateException("Unable to call addFontFromAsset after freezing."); } - if (axes != null) { - for (FontVariationAxis axis : axes) { - nAddAxisValue(mBuilderPtr, axis.getOpenTypeTagValue(), axis.getStyleValue()); - } - } - return nAddFontFromAssetManager(mBuilderPtr, mgr, path, cookie, isAsset, ttcIndex, weight, - isItalic); - } - // TODO: Remove once internal user stop using private API. - private static boolean nAddFont(long builderPtr, ByteBuffer font, int ttcIndex) { - return nAddFont(builderPtr, font, ttcIndex, -1, -1); + try { + ByteBuffer buffer = Font.Builder.createBuffer(mgr, path, isAsset, cookie); + return addFontFromBuffer(buffer, ttcIndex, axes, weight, isItalic); + } catch (IOException e) { + return false; + } } private static native long nInitBuilder(String langs, int variant); @@ -225,8 +221,6 @@ public class FontFamily { int weight, int isItalic); private static native boolean nAddFontWeightStyle(long builderPtr, ByteBuffer font, int ttcIndex, int weight, int isItalic); - private static native boolean nAddFontFromAssetManager(long builderPtr, AssetManager mgr, - String path, int cookie, boolean isAsset, int ttcIndex, int weight, int isItalic); // The added axis values are only valid for the next nAddFont* method call. @CriticalNative diff --git a/graphics/java/android/graphics/fonts/Font.java b/graphics/java/android/graphics/fonts/Font.java index ba96a06cc852..4899fbe431cc 100644 --- a/graphics/java/android/graphics/fonts/Font.java +++ b/graphics/java/android/graphics/fonts/Font.java @@ -19,6 +19,7 @@ package android.graphics.fonts; import android.annotation.IntRange; import android.annotation.NonNull; import android.annotation.Nullable; +import android.content.res.AssetFileDescriptor; import android.content.res.AssetManager; import android.content.res.Resources; import android.os.LocaleList; @@ -35,7 +36,9 @@ import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; +import java.io.InputStream; import java.nio.ByteBuffer; +import java.nio.ByteOrder; import java.nio.channels.FileChannel; import java.util.Arrays; import java.util.Objects; @@ -54,10 +57,6 @@ public final class Font { * A builder class for creating new Font. */ public static final class Builder { - private static final NativeAllocationRegistry sAssetByteBufferRegistry = - NativeAllocationRegistry.createMalloced(ByteBuffer.class.getClassLoader(), - nGetReleaseNativeAssetFunc()); - private static final NativeAllocationRegistry sFontRegistry = NativeAllocationRegistry.createMalloced(Font.class.getClassLoader(), nGetReleaseNativeFont()); @@ -151,7 +150,11 @@ public final class Font { * @param path the file name of the font data in the asset directory */ public Builder(@NonNull AssetManager am, @NonNull String path) { - this(am, path, true /* is asset */, 0 /* cookie */); + try { + mBuffer = createBuffer(am, path, true /* is asset */, 0 /* cookie */); + } catch (IOException e) { + mException = e; + } } /** @@ -165,18 +168,11 @@ public final class Font { */ public Builder(@NonNull AssetManager am, @NonNull String path, boolean isAsset, int cookie) { - final long nativeAsset = nGetNativeAsset(am, path, isAsset, cookie); - if (nativeAsset == 0) { - mException = new FileNotFoundException("Unable to open " + path); - return; - } - final ByteBuffer b = nGetAssetBuffer(nativeAsset); - sAssetByteBufferRegistry.registerNativeAllocation(b, nativeAsset); - if (b == null) { - mException = new FileNotFoundException(path + " not found"); - return; + try { + mBuffer = createBuffer(am, path, isAsset, cookie); + } catch (IOException e) { + mException = e; } - mBuffer = b; } /** @@ -199,19 +195,64 @@ public final class Font { mException = new FileNotFoundException(resId + " must be font file."); return; } - final long nativeAsset = nGetNativeAsset(res.getAssets(), str, false /* is asset */, - value.assetCookie); - if (nativeAsset == 0) { - mException = new FileNotFoundException("Unable to open " + str); - return; + + try { + mBuffer = createBuffer(res.getAssets(), str, false, value.assetCookie); + } catch (IOException e) { + mException = e; } - final ByteBuffer b = nGetAssetBuffer(nativeAsset); - sAssetByteBufferRegistry.registerNativeAllocation(b, nativeAsset); - if (b == null) { - mException = new FileNotFoundException(str + " not found"); - return; + } + + /** + * Creates a buffer containing font data using the assetManager and other + * provided inputs. + * + * @param am the application's asset manager + * @param path the file name of the font data in the asset directory + * @param isAsset true if the undelying data is in asset + * @param cookie set asset cookie + * @return buffer containing the contents of the file + * + * @hide + */ + public static ByteBuffer createBuffer(@NonNull AssetManager am, @NonNull String path, + boolean isAsset, int cookie) throws IOException { + Preconditions.checkNotNull(am, "assetManager can not be null"); + Preconditions.checkNotNull(path, "path can not be null"); + + if (!isAsset) { + // Attempt to open as FD, which should work unless the asset is compressed + AssetFileDescriptor assetFD; + try { + if (cookie > 0) { + assetFD = am.openNonAssetFd(cookie, path); + } else { + assetFD = am.openNonAssetFd(path); + } + + try (FileInputStream fis = assetFD.createInputStream()) { + final FileChannel fc = fis.getChannel(); + return fc.map(FileChannel.MapMode.READ_ONLY, 0, fc.size()); + } + } catch (IOException e) { + // failed to open as FD so now we will attempt to open as an input stream + } + } + + try (InputStream assetStream = isAsset ? am.open(path, AssetManager.ACCESS_BUFFER) + : am.openNonAsset(cookie, path, AssetManager.ACCESS_BUFFER)) { + + int capacity = assetStream.available(); + ByteBuffer buffer = ByteBuffer.allocateDirect(capacity); + buffer.order(ByteOrder.nativeOrder()); + assetStream.read(buffer.array(), buffer.arrayOffset(), assetStream.available()); + + if (assetStream.read() != -1) { + throw new IOException("Unable to access full contents of " + path); + } + + return buffer; } - mBuffer = b; } /** @@ -396,15 +437,6 @@ public final class Font { } /** - * Native methods for accessing underlying buffer in Asset - */ - private static native long nGetNativeAsset( - @NonNull AssetManager am, @NonNull String path, boolean isAsset, int cookie); - private static native ByteBuffer nGetAssetBuffer(long nativeAsset); - @CriticalNative - private static native long nGetReleaseNativeAssetFunc(); - - /** * Native methods for creating Font */ private static native long nInitBuilder(); |