@Test public void testGetFontSync_invalidUri() throws InterruptedException { final Instrumentation inst = InstrumentationRegistry.getInstrumentation(); final FontRequest request = new FontRequest( AUTHORITY, PACKAGE, MockFontProvider.INVALID_URI, SIGNATURE); final CountDownLatch latch = new CountDownLatch(1); final FontCallback callback = new FontCallback(latch); inst.runOnMainSync(new Runnable() { @Override public void run() { FontsContractCompat.getFontSync(mContext, request, callback, null, false , 300 , Typeface.NORMAL); } }); assertTrue(latch.await(5L, TimeUnit.SECONDS)); assertNull(callback.mTypeface); }
@RestrictTo(LIBRARY_GROUP) public static Typeface getFontSync(final Context context, final FontRequest request, final @Nullable ResourcesCompat.FontCallback fontCallback, final @Nullable Handler handler, boolean isBlockingFetch, int timeout, final int style) { final String id = request.getIdentifier() + "-" + style; Typeface cached = sTypefaceCache.get(id); if (cached != null) { if (fontCallback != null) { fontCallback.onFontRetrieved(cached); } return cached; } if (isBlockingFetch && timeout == FontResourcesParserCompat.INFINITE_TIMEOUT_VALUE) { TypefaceResult typefaceResult = getFontInternal(context, request, style); if (fontCallback != null) { if (typefaceResult.mResult == FontFamilyResult.STATUS_OK) { fontCallback.callbackSuccessAsync(typefaceResult.mTypeface, handler); } else { fontCallback.callbackFailAsync(typefaceResult.mResult, handler); } } return typefaceResult.mTypeface; } final Callable<TypefaceResult> fetcher = new Callable<TypefaceResult>() { @Override public TypefaceResult call() throws Exception { TypefaceResult typeface = getFontInternal(context, request, style); if (typeface.mTypeface != null) { sTypefaceCache.put(id, typeface.mTypeface); } return typeface; } }; if (isBlockingFetch) { try { return sBackgroundThread.postAndWait(fetcher, timeout).mTypeface; } catch (InterruptedException e) { return null; } } else { final ReplyCallback<TypefaceResult> reply = fontCallback == null ? null : new ReplyCallback<TypefaceResult>() { @Override public void onReply(final TypefaceResult typeface) { if (typeface == null) { fontCallback.callbackFailAsync( FontRequestCallback.FAIL_REASON_FONT_NOT_FOUND, handler); } else if (typeface.mResult == FontFamilyResult.STATUS_OK) { fontCallback.callbackSuccessAsync(typeface.mTypeface, handler); } else { fontCallback.callbackFailAsync(typeface.mResult, handler); } } }; synchronized (sLock) { if (sPendingReplies.containsKey(id)) { if (reply != null) { sPendingReplies.get(id).add(reply); } return null; } if (reply != null) { ArrayList<ReplyCallback<TypefaceResult>> pendingReplies = new ArrayList<>(); pendingReplies.add(reply); sPendingReplies.put(id, pendingReplies); } } sBackgroundThread.postAndReply(fetcher, new ReplyCallback<TypefaceResult>() { @Override public void onReply(final TypefaceResult typeface) { final ArrayList<ReplyCallback<TypefaceResult>> replies; synchronized (sLock) { replies = sPendingReplies.get(id); if (replies == null) { return; } sPendingReplies.remove(id); } for (int i = 0; i < replies.size(); ++i) { replies.get(i).onReply(typeface); } } }); return null; } }
FontsContractCompat { @RestrictTo(LIBRARY_GROUP) public static Typeface getFontSync(final Context context, final FontRequest request, final @Nullable ResourcesCompat.FontCallback fontCallback, final @Nullable Handler handler, boolean isBlockingFetch, int timeout, final int style) { final String id = request.getIdentifier() + "-" + style; Typeface cached = sTypefaceCache.get(id); if (cached != null) { if (fontCallback != null) { fontCallback.onFontRetrieved(cached); } return cached; } if (isBlockingFetch && timeout == FontResourcesParserCompat.INFINITE_TIMEOUT_VALUE) { TypefaceResult typefaceResult = getFontInternal(context, request, style); if (fontCallback != null) { if (typefaceResult.mResult == FontFamilyResult.STATUS_OK) { fontCallback.callbackSuccessAsync(typefaceResult.mTypeface, handler); } else { fontCallback.callbackFailAsync(typefaceResult.mResult, handler); } } return typefaceResult.mTypeface; } final Callable<TypefaceResult> fetcher = new Callable<TypefaceResult>() { @Override public TypefaceResult call() throws Exception { TypefaceResult typeface = getFontInternal(context, request, style); if (typeface.mTypeface != null) { sTypefaceCache.put(id, typeface.mTypeface); } return typeface; } }; if (isBlockingFetch) { try { return sBackgroundThread.postAndWait(fetcher, timeout).mTypeface; } catch (InterruptedException e) { return null; } } else { final ReplyCallback<TypefaceResult> reply = fontCallback == null ? null : new ReplyCallback<TypefaceResult>() { @Override public void onReply(final TypefaceResult typeface) { if (typeface == null) { fontCallback.callbackFailAsync( FontRequestCallback.FAIL_REASON_FONT_NOT_FOUND, handler); } else if (typeface.mResult == FontFamilyResult.STATUS_OK) { fontCallback.callbackSuccessAsync(typeface.mTypeface, handler); } else { fontCallback.callbackFailAsync(typeface.mResult, handler); } } }; synchronized (sLock) { if (sPendingReplies.containsKey(id)) { if (reply != null) { sPendingReplies.get(id).add(reply); } return null; } if (reply != null) { ArrayList<ReplyCallback<TypefaceResult>> pendingReplies = new ArrayList<>(); pendingReplies.add(reply); sPendingReplies.put(id, pendingReplies); } } sBackgroundThread.postAndReply(fetcher, new ReplyCallback<TypefaceResult>() { @Override public void onReply(final TypefaceResult typeface) { final ArrayList<ReplyCallback<TypefaceResult>> replies; synchronized (sLock) { replies = sPendingReplies.get(id); if (replies == null) { return; } sPendingReplies.remove(id); } for (int i = 0; i < replies.size(); ++i) { replies.get(i).onReply(typeface); } } }); return null; } } }
FontsContractCompat { @RestrictTo(LIBRARY_GROUP) public static Typeface getFontSync(final Context context, final FontRequest request, final @Nullable ResourcesCompat.FontCallback fontCallback, final @Nullable Handler handler, boolean isBlockingFetch, int timeout, final int style) { final String id = request.getIdentifier() + "-" + style; Typeface cached = sTypefaceCache.get(id); if (cached != null) { if (fontCallback != null) { fontCallback.onFontRetrieved(cached); } return cached; } if (isBlockingFetch && timeout == FontResourcesParserCompat.INFINITE_TIMEOUT_VALUE) { TypefaceResult typefaceResult = getFontInternal(context, request, style); if (fontCallback != null) { if (typefaceResult.mResult == FontFamilyResult.STATUS_OK) { fontCallback.callbackSuccessAsync(typefaceResult.mTypeface, handler); } else { fontCallback.callbackFailAsync(typefaceResult.mResult, handler); } } return typefaceResult.mTypeface; } final Callable<TypefaceResult> fetcher = new Callable<TypefaceResult>() { @Override public TypefaceResult call() throws Exception { TypefaceResult typeface = getFontInternal(context, request, style); if (typeface.mTypeface != null) { sTypefaceCache.put(id, typeface.mTypeface); } return typeface; } }; if (isBlockingFetch) { try { return sBackgroundThread.postAndWait(fetcher, timeout).mTypeface; } catch (InterruptedException e) { return null; } } else { final ReplyCallback<TypefaceResult> reply = fontCallback == null ? null : new ReplyCallback<TypefaceResult>() { @Override public void onReply(final TypefaceResult typeface) { if (typeface == null) { fontCallback.callbackFailAsync( FontRequestCallback.FAIL_REASON_FONT_NOT_FOUND, handler); } else if (typeface.mResult == FontFamilyResult.STATUS_OK) { fontCallback.callbackSuccessAsync(typeface.mTypeface, handler); } else { fontCallback.callbackFailAsync(typeface.mResult, handler); } } }; synchronized (sLock) { if (sPendingReplies.containsKey(id)) { if (reply != null) { sPendingReplies.get(id).add(reply); } return null; } if (reply != null) { ArrayList<ReplyCallback<TypefaceResult>> pendingReplies = new ArrayList<>(); pendingReplies.add(reply); sPendingReplies.put(id, pendingReplies); } } sBackgroundThread.postAndReply(fetcher, new ReplyCallback<TypefaceResult>() { @Override public void onReply(final TypefaceResult typeface) { final ArrayList<ReplyCallback<TypefaceResult>> replies; synchronized (sLock) { replies = sPendingReplies.get(id); if (replies == null) { return; } sPendingReplies.remove(id); } for (int i = 0; i < replies.size(); ++i) { replies.get(i).onReply(typeface); } } }); return null; } } private  FontsContractCompat(); }
FontsContractCompat { @RestrictTo(LIBRARY_GROUP) public static Typeface getFontSync(final Context context, final FontRequest request, final @Nullable ResourcesCompat.FontCallback fontCallback, final @Nullable Handler handler, boolean isBlockingFetch, int timeout, final int style) { final String id = request.getIdentifier() + "-" + style; Typeface cached = sTypefaceCache.get(id); if (cached != null) { if (fontCallback != null) { fontCallback.onFontRetrieved(cached); } return cached; } if (isBlockingFetch && timeout == FontResourcesParserCompat.INFINITE_TIMEOUT_VALUE) { TypefaceResult typefaceResult = getFontInternal(context, request, style); if (fontCallback != null) { if (typefaceResult.mResult == FontFamilyResult.STATUS_OK) { fontCallback.callbackSuccessAsync(typefaceResult.mTypeface, handler); } else { fontCallback.callbackFailAsync(typefaceResult.mResult, handler); } } return typefaceResult.mTypeface; } final Callable<TypefaceResult> fetcher = new Callable<TypefaceResult>() { @Override public TypefaceResult call() throws Exception { TypefaceResult typeface = getFontInternal(context, request, style); if (typeface.mTypeface != null) { sTypefaceCache.put(id, typeface.mTypeface); } return typeface; } }; if (isBlockingFetch) { try { return sBackgroundThread.postAndWait(fetcher, timeout).mTypeface; } catch (InterruptedException e) { return null; } } else { final ReplyCallback<TypefaceResult> reply = fontCallback == null ? null : new ReplyCallback<TypefaceResult>() { @Override public void onReply(final TypefaceResult typeface) { if (typeface == null) { fontCallback.callbackFailAsync( FontRequestCallback.FAIL_REASON_FONT_NOT_FOUND, handler); } else if (typeface.mResult == FontFamilyResult.STATUS_OK) { fontCallback.callbackSuccessAsync(typeface.mTypeface, handler); } else { fontCallback.callbackFailAsync(typeface.mResult, handler); } } }; synchronized (sLock) { if (sPendingReplies.containsKey(id)) { if (reply != null) { sPendingReplies.get(id).add(reply); } return null; } if (reply != null) { ArrayList<ReplyCallback<TypefaceResult>> pendingReplies = new ArrayList<>(); pendingReplies.add(reply); sPendingReplies.put(id, pendingReplies); } } sBackgroundThread.postAndReply(fetcher, new ReplyCallback<TypefaceResult>() { @Override public void onReply(final TypefaceResult typeface) { final ArrayList<ReplyCallback<TypefaceResult>> replies; synchronized (sLock) { replies = sPendingReplies.get(id); if (replies == null) { return; } sPendingReplies.remove(id); } for (int i = 0; i < replies.size(); ++i) { replies.get(i).onReply(typeface); } } }); return null; } } private  FontsContractCompat(); @RestrictTo(LIBRARY_GROUP) static void resetCache(); @RestrictTo(LIBRARY_GROUP) static Typeface getFontSync(final Context context, final FontRequest request,
            final @Nullable ResourcesCompat.FontCallback fontCallback,
            final @Nullable Handler handler, boolean isBlockingFetch, int timeout,
            final int style); static void requestFont(final @NonNull Context context,
            final @NonNull FontRequest request, final @NonNull FontRequestCallback callback,
            final @NonNull Handler handler); @Nullable static Typeface buildTypeface(@NonNull Context context,
            @Nullable CancellationSignal cancellationSignal, @NonNull FontInfo[] fonts); @RestrictTo(LIBRARY_GROUP) @RequiresApi(19) static Map<Uri, ByteBuffer> prepareFontData(Context context, FontInfo[] fonts,
            CancellationSignal cancellationSignal); @NonNull static FontFamilyResult fetchFonts(@NonNull Context context,
            @Nullable CancellationSignal cancellationSignal, @NonNull FontRequest request); @VisibleForTesting @RestrictTo(LIBRARY_GROUP) static @Nullable ProviderInfo getProvider(@NonNull PackageManager packageManager,
            @NonNull FontRequest request, @Nullable Resources resources); }
FontsContractCompat { @RestrictTo(LIBRARY_GROUP) public static Typeface getFontSync(final Context context, final FontRequest request, final @Nullable ResourcesCompat.FontCallback fontCallback, final @Nullable Handler handler, boolean isBlockingFetch, int timeout, final int style) { final String id = request.getIdentifier() + "-" + style; Typeface cached = sTypefaceCache.get(id); if (cached != null) { if (fontCallback != null) { fontCallback.onFontRetrieved(cached); } return cached; } if (isBlockingFetch && timeout == FontResourcesParserCompat.INFINITE_TIMEOUT_VALUE) { TypefaceResult typefaceResult = getFontInternal(context, request, style); if (fontCallback != null) { if (typefaceResult.mResult == FontFamilyResult.STATUS_OK) { fontCallback.callbackSuccessAsync(typefaceResult.mTypeface, handler); } else { fontCallback.callbackFailAsync(typefaceResult.mResult, handler); } } return typefaceResult.mTypeface; } final Callable<TypefaceResult> fetcher = new Callable<TypefaceResult>() { @Override public TypefaceResult call() throws Exception { TypefaceResult typeface = getFontInternal(context, request, style); if (typeface.mTypeface != null) { sTypefaceCache.put(id, typeface.mTypeface); } return typeface; } }; if (isBlockingFetch) { try { return sBackgroundThread.postAndWait(fetcher, timeout).mTypeface; } catch (InterruptedException e) { return null; } } else { final ReplyCallback<TypefaceResult> reply = fontCallback == null ? null : new ReplyCallback<TypefaceResult>() { @Override public void onReply(final TypefaceResult typeface) { if (typeface == null) { fontCallback.callbackFailAsync( FontRequestCallback.FAIL_REASON_FONT_NOT_FOUND, handler); } else if (typeface.mResult == FontFamilyResult.STATUS_OK) { fontCallback.callbackSuccessAsync(typeface.mTypeface, handler); } else { fontCallback.callbackFailAsync(typeface.mResult, handler); } } }; synchronized (sLock) { if (sPendingReplies.containsKey(id)) { if (reply != null) { sPendingReplies.get(id).add(reply); } return null; } if (reply != null) { ArrayList<ReplyCallback<TypefaceResult>> pendingReplies = new ArrayList<>(); pendingReplies.add(reply); sPendingReplies.put(id, pendingReplies); } } sBackgroundThread.postAndReply(fetcher, new ReplyCallback<TypefaceResult>() { @Override public void onReply(final TypefaceResult typeface) { final ArrayList<ReplyCallback<TypefaceResult>> replies; synchronized (sLock) { replies = sPendingReplies.get(id); if (replies == null) { return; } sPendingReplies.remove(id); } for (int i = 0; i < replies.size(); ++i) { replies.get(i).onReply(typeface); } } }); return null; } } private  FontsContractCompat(); @RestrictTo(LIBRARY_GROUP) static void resetCache(); @RestrictTo(LIBRARY_GROUP) static Typeface getFontSync(final Context context, final FontRequest request,
            final @Nullable ResourcesCompat.FontCallback fontCallback,
            final @Nullable Handler handler, boolean isBlockingFetch, int timeout,
            final int style); static void requestFont(final @NonNull Context context,
            final @NonNull FontRequest request, final @NonNull FontRequestCallback callback,
            final @NonNull Handler handler); @Nullable static Typeface buildTypeface(@NonNull Context context,
            @Nullable CancellationSignal cancellationSignal, @NonNull FontInfo[] fonts); @RestrictTo(LIBRARY_GROUP) @RequiresApi(19) static Map<Uri, ByteBuffer> prepareFontData(Context context, FontInfo[] fonts,
            CancellationSignal cancellationSignal); @NonNull static FontFamilyResult fetchFonts(@NonNull Context context,
            @Nullable CancellationSignal cancellationSignal, @NonNull FontRequest request); @VisibleForTesting @RestrictTo(LIBRARY_GROUP) static @Nullable ProviderInfo getProvider(@NonNull PackageManager packageManager,
            @NonNull FontRequest request, @Nullable Resources resources); @RestrictTo(LIBRARY_GROUP)
    static final String PARCEL_FONT_RESULTS; }