/* * Copyright (C) 2017 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package android.support.text.emoji; import android.content.Context; import android.graphics.Typeface; import android.os.Bundle; import android.os.ParcelFileDescriptor; import android.support.annotation.NonNull; import android.support.annotation.RequiresApi; import android.support.annotation.RestrictTo; import android.support.v4.graphics.TypefaceCompat; import android.support.v4.graphics.TypefaceCompat.FontRequestCallback; import android.support.v4.graphics.fonts.FontResult; import android.support.v4.os.ResultReceiver; import android.support.v4.provider.FontRequest; import android.support.v4.provider.FontsContractCompat; import android.support.v4.provider.FontsContractInternal; import android.support.v4.util.Preconditions; import java.io.FileInputStream; import java.io.IOException; import java.nio.ByteBuffer; import java.nio.channels.FileChannel; import java.util.Arrays; import java.util.List; /** * {@link EmojiCompat.Config} implementation that asynchronously fetches the required font and the * metadata using a {@link FontRequest}. FontRequest should be constructed to fetch an EmojiCompat * compatible emoji font. *
* See {@link FontsContractCompat.FontRequestCallback#onTypefaceRequestFailed(int)} for more * information about the cases where the font loading can fail. */ public class FontRequestEmojiCompatConfig extends EmojiCompat.Config { /** * @param context Context instance, cannot be {@code null} * @param request {@link FontRequest} to fetch the font asynchronously, cannot be {@code null} */ public FontRequestEmojiCompatConfig(@NonNull Context context, @NonNull FontRequest request) { super(new FontRequestMetadataLoader(context, request)); } /** * @hide */ @RestrictTo(RestrictTo.Scope.LIBRARY_GROUP) public FontRequestEmojiCompatConfig(@NonNull Context context, @NonNull FontRequest request, @NonNull FontsContractInternal fontsContract) { super(new FontRequestMetadataLoader(context, request, fontsContract)); } /** * MetadataLoader implementation that uses FontsContractInternal and TypefaceCompat to load a * given FontRequest. */ private static class FontRequestMetadataLoader implements EmojiCompat.MetadataLoader { private final Context mContext; private final FontRequest mRequest; private final FontsContractInternal mFontsContract; FontRequestMetadataLoader(@NonNull Context context, @NonNull FontRequest request) { this(context, request, new FontsContractInternal(context)); } FontRequestMetadataLoader(@NonNull Context context, @NonNull FontRequest request, @NonNull FontsContractInternal fontsContract) { Preconditions.checkNotNull(context, "Context cannot be null"); Preconditions.checkNotNull(request, "FontRequest cannot be null"); mContext = context.getApplicationContext(); mRequest = request; mFontsContract = fontsContract; } @Override @RequiresApi(19) public void load(@NonNull final EmojiCompat.LoaderCallback loaderCallback) { Preconditions.checkNotNull(loaderCallback, "LoaderCallback cannot be null"); final ResultReceiver receiver = new ResultReceiver(null) { @Override public void onReceiveResult(final int resultCode, final Bundle resultData) { receiveResult(loaderCallback, resultCode, resultData); } }; try { mFontsContract.getFont(mRequest, receiver); } catch (Throwable throwable) { loaderCallback.onFailed(throwable); } } @RequiresApi(19) private void receiveResult(final EmojiCompat.LoaderCallback loaderCallback, final int resultCode, final Bundle resultData) { try { if (resultCode != FontsContractCompat.Columns.RESULT_CODE_OK) { throwException(resultCode); } if (resultData == null) { throwException(FontRequestCallback.FAIL_REASON_FONT_NOT_FOUND); } final List