summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDerek Sollenberger <djsollen@google.com>2020-01-06 11:24:34 -0500
committerDerek Sollenberger <djsollen@google.com>2020-02-10 20:05:31 +0000
commit4db7bd28e76897a97a848adfd1051904492bf400 (patch)
tree695868c9067d322940483117de0d8d2c0f86ecce
parent929de647969cf5efa1778fe4b54ee968bff4d613 (diff)
Consolidate AssetManager calls in Font/FontFamily
The Font/FontFamily classes use private API calls in native code to get the contents of an Asset. These calls need to be made on public APIs in order to isolate the graphics module from the rest of the system. Public Java APIs already exist so this CL refactors the code to use those methods. Test: CtsTextTestCases Bug: 147136234 Change-Id: I35a6558b597684e59279d7a841669c5f909d5152
-rw-r--r--core/jni/android/graphics/FontFamily.cpp61
-rw-r--r--core/jni/android/graphics/fonts/Font.cpp63
-rw-r--r--graphics/java/android/graphics/FontFamily.java20
-rw-r--r--graphics/java/android/graphics/fonts/Font.java104
4 files changed, 75 insertions, 173 deletions
diff --git a/core/jni/android/graphics/FontFamily.cpp b/core/jni/android/graphics/FontFamily.cpp
index 8fc6afa0f386..a570bd4966e9 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 bb0654d255c0..6ae24e12e8fe 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();