Merge "Clean Up: Groundwork for making TypefaceCompat implementation for API24." into oc-support-26.0-dev
diff --git a/compat/java/android/support/v4/graphics/TypefaceCompat.java b/compat/java/android/support/v4/graphics/TypefaceCompat.java
index 99ce7eb..444616a 100644
--- a/compat/java/android/support/v4/graphics/TypefaceCompat.java
+++ b/compat/java/android/support/v4/graphics/TypefaceCompat.java
@@ -18,12 +18,10 @@
 
 import static android.support.annotation.RestrictTo.Scope.LIBRARY_GROUP;
 
-import android.annotation.TargetApi;
 import android.content.Context;
 import android.content.res.Resources;
 import android.graphics.Typeface;
 import android.net.Uri;
-import android.support.annotation.GuardedBy;
 import android.support.annotation.NonNull;
 import android.support.annotation.Nullable;
 import android.support.annotation.RestrictTo;
@@ -32,6 +30,7 @@
 import android.support.v4.content.res.FontResourcesParserCompat.ProviderResourceEntry;
 import android.support.v4.provider.FontsContractCompat;
 import android.support.v4.provider.FontsContractCompat.FontInfo;
+import android.support.v4.util.LruCache;
 
 import java.nio.ByteBuffer;
 import java.util.Map;
@@ -42,38 +41,26 @@
  */
 @RestrictTo(LIBRARY_GROUP)
 public class TypefaceCompat {
-    @GuardedBy("sLock")
-    private static TypefaceCompatImpl sTypefaceCompatImpl;
-    private static final Object sLock = new Object();
+    // TODO(nona): Introduce API 24 implementation.
+    private static final TypefaceCompatImpl sTypefaceCompatImpl = new TypefaceCompatBaseImpl();
+
+    /**
+     * Cache for Typeface objects dynamically loaded from assets.
+     */
+    private static final LruCache<String, Typeface> sTypefaceCache = new LruCache<>(16);
 
     interface TypefaceCompatImpl {
         // Create Typeface from font file in res/font directory.
-        Typeface createFromResourcesFontFile(Resources resources, int id, int style);
+        Typeface createFromResourcesFontFile(Context context, Resources resources, int id,
+                int style);
 
         // Create Typeface from XML which root node is "font-family"
         Typeface createFromFontFamilyFilesResourceEntry(
-                FontFamilyFilesResourceEntry entry, Resources resources, int id, int style);
+                Context context, FontFamilyFilesResourceEntry entry, Resources resources, int id,
+                int style);
 
-        // For finiding cache before parsing xml data.
-        Typeface findFromCache(Resources resources, int id, int style);
-
-        Typeface createTypeface(@NonNull FontInfo[] fonts, Map<Uri, ByteBuffer> uriBuffer);
-    }
-
-    /**
-     * If the current implementation is not set, set it according to the current build version. This
-     * is safe to call several times, even if the implementation has already been set.
-     */
-    @TargetApi(26)
-    private static void maybeInitImpl(Context context) {
-        if (sTypefaceCompatImpl == null) {
-            synchronized (sLock) {
-                if (sTypefaceCompatImpl == null) {
-                    // TODO: Maybe we can do better thing on Android N or later.
-                    sTypefaceCompatImpl = new TypefaceCompatBaseImpl(context);
-                }
-            }
-        }
+        Typeface createTypeface(Context context, @NonNull FontInfo[] fonts,
+                Map<Uri, ByteBuffer> uriBuffer);
     }
 
     private TypefaceCompat() {}
@@ -84,13 +71,19 @@
      * @return null if not found.
      */
     public static Typeface findFromCache(Resources resources, int id, int style) {
-        synchronized (sLock) {
-            // There is no cache if there is no impl.
-            if (sTypefaceCompatImpl == null) {
-                return null;
-            }
-        }
-        return sTypefaceCompatImpl.findFromCache(resources, id, style);
+        return sTypefaceCache.get(createResourceUid(resources, id, style));
+    }
+
+    /**
+     * Create a unique id for a given Resource and id.
+     *
+     * @param resources Resources instance
+     * @param id a resource id
+     * @param a style to be used for this resource, -1 if not availbale.
+     * @return Unique id for a given resource and id.
+     */
+    private static String createResourceUid(final Resources resources, int id, int style) {
+        return resources.getResourcePackageName(id) + "-" + id + "-" + style;
     }
 
     /**
@@ -100,14 +93,18 @@
      */
     public static Typeface createFromResourcesFamilyXml(
             Context context, FamilyResourceEntry entry, Resources resources, int id, int style) {
-        maybeInitImpl(context);
+        Typeface typeface;
         if (entry instanceof ProviderResourceEntry) {
-            return FontsContractCompat.getFontSync(context,
+            typeface = FontsContractCompat.getFontSync(context,
                     ((ProviderResourceEntry) entry).getRequest());
         } else {
-            return sTypefaceCompatImpl.createFromFontFamilyFilesResourceEntry(
-                    (FontFamilyFilesResourceEntry) entry, resources, id, style);
+            typeface = sTypefaceCompatImpl.createFromFontFamilyFilesResourceEntry(
+                    context, (FontFamilyFilesResourceEntry) entry, resources, id, style);
         }
+        if (typeface != null) {
+            sTypefaceCache.put(createResourceUid(resources, id, style), typeface);
+        }
+        return typeface;
     }
 
     /**
@@ -116,8 +113,12 @@
     @Nullable
     public static Typeface createFromResourcesFontFile(
             Context context, Resources resources, int id, int style) {
-        maybeInitImpl(context);
-        return sTypefaceCompatImpl.createFromResourcesFontFile(resources, id, style);
+        Typeface typeface = sTypefaceCompatImpl.createFromResourcesFontFile(
+                context, resources, id, style);
+        if (typeface != null) {
+            sTypefaceCache.put(createResourceUid(resources, id, style), typeface);
+        }
+        return typeface;
     }
 
     /**
@@ -125,7 +126,6 @@
      */
     public static Typeface createTypeface(Context context, @NonNull FontInfo[] fonts,
             Map<Uri, ByteBuffer> uriBuffer) {
-        maybeInitImpl(context);
-        return sTypefaceCompatImpl.createTypeface(fonts, uriBuffer);
+        return sTypefaceCompatImpl.createTypeface(context, fonts, uriBuffer);
     }
 }
diff --git a/compat/java/android/support/v4/graphics/TypefaceCompatBaseImpl.java b/compat/java/android/support/v4/graphics/TypefaceCompatBaseImpl.java
index ffc57a1..86bcae8 100644
--- a/compat/java/android/support/v4/graphics/TypefaceCompatBaseImpl.java
+++ b/compat/java/android/support/v4/graphics/TypefaceCompatBaseImpl.java
@@ -29,7 +29,6 @@
 import android.support.v4.content.res.FontResourcesParserCompat.FontFamilyFilesResourceEntry;
 import android.support.v4.content.res.FontResourcesParserCompat.FontFileResourceEntry;
 import android.support.v4.provider.FontsContractCompat.FontInfo;
-import android.support.v4.util.LruCache;
 import android.util.Log;
 
 import java.io.Closeable;
@@ -50,21 +49,9 @@
     private static final String TAG = "TypefaceCompatBaseImpl";
     private static final String CACHE_FILE_PREFIX = "cached_font_";
 
-    /**
-     * Cache for Typeface objects dynamically loaded from assets. Currently max size is 16.
-     */
-    private static final LruCache<String, Typeface> sDynamicTypefaceCache =
-            new LruCache<>(16);
-
-    private final Context mApplicationContext;
-
-    TypefaceCompatBaseImpl(Context context) {
-        mApplicationContext = context.getApplicationContext();
-    }
-
     @Override
-    public Typeface createTypeface(
-            @NonNull FontInfo[] fonts, Map<Uri, ByteBuffer> uriBuffer) {
+    public Typeface createTypeface(Context context, @NonNull FontInfo[] fonts,
+            Map<Uri, ByteBuffer> uriBuffer) {
         // When we load from file, we can only load one font so just take the first one.
         if (fonts.length < 1) {
             return null;
@@ -72,7 +59,7 @@
         Typeface typeface = null;
         FontInfo font = fonts[0];
         ByteBuffer buffer = uriBuffer.get(font.getUri());
-        File tmpFile = copyToCacheFile(buffer);
+        File tmpFile = copyToCacheFile(context, buffer);
         if (tmpFile != null) {
             try {
                 typeface = Typeface.createFromFile(tmpFile.getPath());
@@ -88,11 +75,11 @@
         return typeface;
     }
 
-    private File copyToCacheFile(final InputStream is) {
+    private static File copyToCacheFile(Context context, final InputStream is) {
         FileOutputStream fos = null;
         File cacheFile;
         try {
-            cacheFile = new File(mApplicationContext.getCacheDir(),
+            cacheFile = new File(context.getCacheDir(),
                     CACHE_FILE_PREFIX + Thread.currentThread().getId());
             fos = new FileOutputStream(cacheFile, false);
 
@@ -111,11 +98,11 @@
         return cacheFile;
     }
 
-    private File copyToCacheFile(final ByteBuffer is) {
+    private static File copyToCacheFile(Context context, final ByteBuffer is) {
         FileOutputStream fos = null;
         File cacheFile;
         try {
-            cacheFile = new File(mApplicationContext.getCacheDir(),
+            cacheFile = new File(context.getCacheDir(),
                     CACHE_FILE_PREFIX + Thread.currentThread().getId());
             fos = new FileOutputStream(cacheFile, false);
 
@@ -134,7 +121,7 @@
         return cacheFile;
     }
 
-    static void closeQuietly(InputStream is) {
+    private static void closeQuietly(InputStream is) {
         if (is != null) {
             try {
                 is.close();
@@ -146,17 +133,12 @@
 
     @Nullable
     @Override
-    public Typeface createFromResourcesFontFile(Resources resources, int id, int style) {
+    public Typeface createFromResourcesFontFile(Context context, Resources resources, int id,
+            int style) {
         InputStream is = null;
         try {
             is = resources.openRawResource(id);
-            Typeface typeface = createTypeface(resources, is);
-            if (typeface == null) {
-                return null;
-            }
-            final String key = createAssetUid(resources, id, style);
-            sDynamicTypefaceCache.put(key, typeface);
-            return typeface;
+            return createTypeface(context, resources, is);
         } catch (IOException e) {
             return null;
         } finally {
@@ -164,18 +146,6 @@
         }
     }
 
-    @Nullable
-    @Override
-    public Typeface createFromFontFamilyFilesResourceEntry(
-            FontFamilyFilesResourceEntry filesEntry, Resources resources, int id, int style) {
-        Typeface typeface = createFromResources(filesEntry, resources, id, style);
-        if (typeface != null) {
-            final String key = createAssetUid(resources, id, style);
-            sDynamicTypefaceCache.put(key, typeface);
-        }
-        return typeface;
-    }
-
     private FontFileResourceEntry findBestEntry(FontFamilyFilesResourceEntry entry,
             int targetWeight, boolean isTargetItalic) {
         FontFileResourceEntry bestEntry = null;
@@ -193,13 +163,10 @@
         return bestEntry;
     }
 
-    /**
-     * Implementation of resources font retrieval for a file type xml resource. This should be
-     * overriden by other implementations.
-     */
     @Nullable
-    Typeface createFromResources(FontFamilyFilesResourceEntry entry, Resources resources,
-            int id, int style) {
+    @Override
+    public Typeface createFromFontFamilyFilesResourceEntry(Context context,
+            FontFamilyFilesResourceEntry entry, Resources resources, int id, int style) {
         FontFileResourceEntry best = findBestEntry(
                 entry, ((style & Typeface.BOLD) == 0) ? 400 : 700, (style & Typeface.ITALIC) != 0);
         if (best == null) {
@@ -209,7 +176,7 @@
         InputStream is = null;
         try {
             is = resources.openRawResource(best.getResourceId());
-            return createTypeface(resources, is);
+            return createTypeface(context, resources, is);
         } catch (IOException e) {
             // This is fine. The resource can be string type which indicates a name of Typeface.
         } finally {
@@ -218,29 +185,10 @@
         return null;
     }
 
-    @Override
-    public Typeface findFromCache(Resources resources, int id, int style) {
-        final String key = createAssetUid(resources, id, style);
-        synchronized (sDynamicTypefaceCache) {
-            return sDynamicTypefaceCache.get(key);
-        }
-    }
-
-    /**
-     * Creates a unique id for a given AssetManager and asset id
-     *
-     * @param resources Resources instance
-     * @param id a resource id
-     * @param style a style to be used for this resource, -1 if not avaialble.
-     * @return Unique id for a given AssetManager and id
-     */
-    private static String createAssetUid(final Resources resources, int id, int style) {
-        return resources.getResourcePackageName(id) + "-" + id + "-" + style;
-    }
-
     // Caller must close "is"
-    Typeface createTypeface(Resources resources, InputStream is) throws IOException {
-        File tmpFile = copyToCacheFile(is);
+    Typeface createTypeface(Context context, Resources resources, InputStream is)
+            throws IOException {
+        File tmpFile = copyToCacheFile(context, is);
         if (tmpFile != null) {
             try {
                 return Typeface.createFromFile(tmpFile.getPath());