Merge "Cache Downloaded Fonts in Typeface"
diff --git a/core/java/android/content/res/ResourcesImpl.java b/core/java/android/content/res/ResourcesImpl.java
index 3cf36d7..bf81096 100644
--- a/core/java/android/content/res/ResourcesImpl.java
+++ b/core/java/android/content/res/ResourcesImpl.java
@@ -753,7 +753,7 @@
}
final String file = value.string.toString();
- Typeface cached = Typeface.createFromCache(mAssets, file);
+ Typeface cached = Typeface.findFromCache(mAssets, file);
if (cached != null) {
return cached;
}
diff --git a/graphics/java/android/graphics/Typeface.java b/graphics/java/android/graphics/Typeface.java
index 5531871..750ef3f 100644
--- a/graphics/java/android/graphics/Typeface.java
+++ b/graphics/java/android/graphics/Typeface.java
@@ -198,9 +198,10 @@
}
/**
+ * Used by resources for cached loading if the font is available.
* @hide
*/
- public static Typeface createFromCache(AssetManager mgr, String path) {
+ public static Typeface findFromCache(AssetManager mgr, String path) {
synchronized (sDynamicTypefaceCache) {
final String key = createAssetUid(mgr, path);
Typeface typeface = sDynamicTypefaceCache.get(key);
@@ -221,6 +222,15 @@
* @param callback A callback that will be triggered when results are obtained. May not be null.
*/
public static void create(@NonNull FontRequest request, @NonNull FontRequestCallback callback) {
+ // Check the cache first
+ // TODO: would the developer want to avoid a cache hit and always ask for the freshest
+ // result?
+ Typeface cachedTypeface = findFromCache(
+ request.getProviderAuthority(), request.getQuery());
+ if (cachedTypeface != null) {
+ mHandler.post(() -> callback.onTypefaceRetrieved(cachedTypeface));
+ return;
+ }
synchronized (sLock) {
if (sFontsContract == null) {
sFontsContract = new FontsContract();
@@ -229,20 +239,34 @@
final ResultReceiver receiver = new ResultReceiver(null) {
@Override
public void onReceiveResult(int resultCode, Bundle resultData) {
- mHandler.post(new Runnable() {
- @Override
- public void run() {
- receiveResult(request, callback, resultCode, resultData);
- }
- });
+ mHandler.post(() -> receiveResult(request, callback, resultCode, resultData));
}
};
sFontsContract.getFont(request, receiver);
}
}
+ private static Typeface findFromCache(String providerAuthority, String query) {
+ synchronized (sDynamicTypefaceCache) {
+ final String key = createProviderUid(providerAuthority, query);
+ Typeface typeface = sDynamicTypefaceCache.get(key);
+ if (typeface != null) {
+ return typeface;
+ }
+ }
+ return null;
+ }
+
private static void receiveResult(FontRequest request, FontRequestCallback callback,
int resultCode, Bundle resultData) {
+ Typeface cachedTypeface = findFromCache(
+ request.getProviderAuthority(), request.getQuery());
+ if (cachedTypeface != null) {
+ // We already know the result.
+ // Probably the requester requests the same font again in a short interval.
+ callback.onTypefaceRetrieved(cachedTypeface);
+ return;
+ }
if (resultCode == FontsContract.RESULT_CODE_PROVIDER_NOT_FOUND) {
callback.onTypefaceRequestFailed(
FontRequestCallback.FAIL_REASON_PROVIDER_NOT_FOUND);
@@ -296,8 +320,12 @@
}
}
fontFamily.freeze();
- callback.onTypefaceRetrieved(Typeface.createFromFamiliesWithDefault(
- new FontFamily[] {fontFamily}));
+ Typeface typeface = Typeface.createFromFamiliesWithDefault(new FontFamily[] { fontFamily });
+ synchronized (sDynamicTypefaceCache) {
+ String key = createProviderUid(request.getProviderAuthority(), request.getQuery());
+ sDynamicTypefaceCache.put(key, typeface);
+ }
+ callback.onTypefaceRetrieved(typeface);
}
/**
@@ -464,6 +492,7 @@
private static String createAssetUid(final AssetManager mgr, String path) {
final SparseArray<String> pkgs = mgr.getAssignedPackageIdentifiers();
final StringBuilder builder = new StringBuilder();
+ builder.append("asset:");
final int size = pkgs.size();
for (int i = 0; i < size; i++) {
builder.append(pkgs.valueAt(i));
@@ -474,6 +503,18 @@
}
/**
+ * Creates a unique id for a given font provider and query.
+ */
+ private static String createProviderUid(String authority, String query) {
+ final StringBuilder builder = new StringBuilder();
+ builder.append("provider:");
+ builder.append(authority);
+ builder.append("-");
+ builder.append(query);
+ return builder.toString();
+ }
+
+ /**
* Create a new typeface from the specified font file.
*
* @param path The path to the font data.