TypefaceCompatApi21Impl.java revision 9dede51868bbbe16aadcd65e04860bea8ea50e05
108df2afeec46f363ef5f17146750bdf011412e56Seigo Nonaka/* 208df2afeec46f363ef5f17146750bdf011412e56Seigo Nonaka * Copyright (C) 2017 The Android Open Source Project 308df2afeec46f363ef5f17146750bdf011412e56Seigo Nonaka * 408df2afeec46f363ef5f17146750bdf011412e56Seigo Nonaka * Licensed under the Apache License, Version 2.0 (the "License"); 508df2afeec46f363ef5f17146750bdf011412e56Seigo Nonaka * you may not use this file except in compliance with the License. 608df2afeec46f363ef5f17146750bdf011412e56Seigo Nonaka * You may obtain a copy of the License at 708df2afeec46f363ef5f17146750bdf011412e56Seigo Nonaka * 808df2afeec46f363ef5f17146750bdf011412e56Seigo Nonaka * http://www.apache.org/licenses/LICENSE-2.0 908df2afeec46f363ef5f17146750bdf011412e56Seigo Nonaka * 1008df2afeec46f363ef5f17146750bdf011412e56Seigo Nonaka * Unless required by applicable law or agreed to in writing, software 1108df2afeec46f363ef5f17146750bdf011412e56Seigo Nonaka * distributed under the License is distributed on an "AS IS" BASIS, 1208df2afeec46f363ef5f17146750bdf011412e56Seigo Nonaka * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 1308df2afeec46f363ef5f17146750bdf011412e56Seigo Nonaka * See the License for the specific language governing permissions and 1408df2afeec46f363ef5f17146750bdf011412e56Seigo Nonaka * limitations under the License. 1508df2afeec46f363ef5f17146750bdf011412e56Seigo Nonaka */ 1608df2afeec46f363ef5f17146750bdf011412e56Seigo Nonaka 17ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikaspackage androidx.core.graphics; 1808df2afeec46f363ef5f17146750bdf011412e56Seigo Nonaka 19ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikasimport static androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP; 2008df2afeec46f363ef5f17146750bdf011412e56Seigo Nonaka 2108df2afeec46f363ef5f17146750bdf011412e56Seigo Nonakaimport android.content.ContentResolver; 2208df2afeec46f363ef5f17146750bdf011412e56Seigo Nonakaimport android.content.Context; 2308df2afeec46f363ef5f17146750bdf011412e56Seigo Nonakaimport android.graphics.Typeface; 2408df2afeec46f363ef5f17146750bdf011412e56Seigo Nonakaimport android.os.CancellationSignal; 2508df2afeec46f363ef5f17146750bdf011412e56Seigo Nonakaimport android.os.ParcelFileDescriptor; 269dede51868bbbe16aadcd65e04860bea8ea50e05Aurimas Liutikasimport android.system.ErrnoException; 279dede51868bbbe16aadcd65e04860bea8ea50e05Aurimas Liutikasimport android.system.Os; 289dede51868bbbe16aadcd65e04860bea8ea50e05Aurimas Liutikasimport android.system.OsConstants; 299dede51868bbbe16aadcd65e04860bea8ea50e05Aurimas Liutikas 30ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikasimport androidx.annotation.NonNull; 31ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikasimport androidx.annotation.RequiresApi; 32ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikasimport androidx.annotation.RestrictTo; 33ac5fe7c617c66850fff75a9fce9979c6e5674b0fAurimas Liutikasimport androidx.core.provider.FontsContractCompat.FontInfo; 3408df2afeec46f363ef5f17146750bdf011412e56Seigo Nonaka 3508df2afeec46f363ef5f17146750bdf011412e56Seigo Nonakaimport java.io.File; 3608df2afeec46f363ef5f17146750bdf011412e56Seigo Nonakaimport java.io.FileInputStream; 3708df2afeec46f363ef5f17146750bdf011412e56Seigo Nonakaimport java.io.IOException; 3808df2afeec46f363ef5f17146750bdf011412e56Seigo Nonaka 3908df2afeec46f363ef5f17146750bdf011412e56Seigo Nonaka 4008df2afeec46f363ef5f17146750bdf011412e56Seigo Nonaka/** 4108df2afeec46f363ef5f17146750bdf011412e56Seigo Nonaka * Implementation of the Typeface compat methods for API 21 and above. 4208df2afeec46f363ef5f17146750bdf011412e56Seigo Nonaka * @hide 4308df2afeec46f363ef5f17146750bdf011412e56Seigo Nonaka */ 4408df2afeec46f363ef5f17146750bdf011412e56Seigo Nonaka@RestrictTo(LIBRARY_GROUP) 4508df2afeec46f363ef5f17146750bdf011412e56Seigo Nonaka@RequiresApi(21) 4608df2afeec46f363ef5f17146750bdf011412e56Seigo Nonakaclass TypefaceCompatApi21Impl extends TypefaceCompatBaseImpl { 4708df2afeec46f363ef5f17146750bdf011412e56Seigo Nonaka private static final String TAG = "TypefaceCompatApi21Impl"; 4808df2afeec46f363ef5f17146750bdf011412e56Seigo Nonaka 4908df2afeec46f363ef5f17146750bdf011412e56Seigo Nonaka private File getFile(ParcelFileDescriptor fd) { 5008df2afeec46f363ef5f17146750bdf011412e56Seigo Nonaka try { 5108df2afeec46f363ef5f17146750bdf011412e56Seigo Nonaka final String path = Os.readlink("/proc/self/fd/" + fd.getFd()); 5208df2afeec46f363ef5f17146750bdf011412e56Seigo Nonaka // Check if the symbolic link points the regular file. 5308df2afeec46f363ef5f17146750bdf011412e56Seigo Nonaka if (OsConstants.S_ISREG(Os.stat(path).st_mode)) { 5408df2afeec46f363ef5f17146750bdf011412e56Seigo Nonaka return new File(path); 5508df2afeec46f363ef5f17146750bdf011412e56Seigo Nonaka } else { 5608df2afeec46f363ef5f17146750bdf011412e56Seigo Nonaka return null; 5708df2afeec46f363ef5f17146750bdf011412e56Seigo Nonaka } 5808df2afeec46f363ef5f17146750bdf011412e56Seigo Nonaka } catch (ErrnoException e) { 5908df2afeec46f363ef5f17146750bdf011412e56Seigo Nonaka return null; // Mostly permission error. 6008df2afeec46f363ef5f17146750bdf011412e56Seigo Nonaka } 6108df2afeec46f363ef5f17146750bdf011412e56Seigo Nonaka } 6208df2afeec46f363ef5f17146750bdf011412e56Seigo Nonaka 6308df2afeec46f363ef5f17146750bdf011412e56Seigo Nonaka @Override 6408df2afeec46f363ef5f17146750bdf011412e56Seigo Nonaka public Typeface createFromFontInfo(Context context, CancellationSignal cancellationSignal, 6508df2afeec46f363ef5f17146750bdf011412e56Seigo Nonaka @NonNull FontInfo[] fonts, int style) { 6608df2afeec46f363ef5f17146750bdf011412e56Seigo Nonaka if (fonts.length < 1) { 6708df2afeec46f363ef5f17146750bdf011412e56Seigo Nonaka return null; 6808df2afeec46f363ef5f17146750bdf011412e56Seigo Nonaka } 6908df2afeec46f363ef5f17146750bdf011412e56Seigo Nonaka final FontInfo bestFont = findBestInfo(fonts, style); 7008df2afeec46f363ef5f17146750bdf011412e56Seigo Nonaka final ContentResolver resolver = context.getContentResolver(); 7108df2afeec46f363ef5f17146750bdf011412e56Seigo Nonaka try (ParcelFileDescriptor pfd = 7208df2afeec46f363ef5f17146750bdf011412e56Seigo Nonaka resolver.openFileDescriptor(bestFont.getUri(), "r", cancellationSignal)) { 7308df2afeec46f363ef5f17146750bdf011412e56Seigo Nonaka final File file = getFile(pfd); 7408df2afeec46f363ef5f17146750bdf011412e56Seigo Nonaka if (file == null || !file.canRead()) { 7508df2afeec46f363ef5f17146750bdf011412e56Seigo Nonaka // Unable to use the real file for creating Typeface. Fallback to copying 7608df2afeec46f363ef5f17146750bdf011412e56Seigo Nonaka // implementation. 7708df2afeec46f363ef5f17146750bdf011412e56Seigo Nonaka try (FileInputStream fis = new FileInputStream(pfd.getFileDescriptor())) { 7808df2afeec46f363ef5f17146750bdf011412e56Seigo Nonaka return super.createFromInputStream(context, fis); 7908df2afeec46f363ef5f17146750bdf011412e56Seigo Nonaka } 8008df2afeec46f363ef5f17146750bdf011412e56Seigo Nonaka } 8108df2afeec46f363ef5f17146750bdf011412e56Seigo Nonaka return Typeface.createFromFile(file); 8208df2afeec46f363ef5f17146750bdf011412e56Seigo Nonaka } catch (IOException e) { 8308df2afeec46f363ef5f17146750bdf011412e56Seigo Nonaka return null; 8408df2afeec46f363ef5f17146750bdf011412e56Seigo Nonaka } 8508df2afeec46f363ef5f17146750bdf011412e56Seigo Nonaka } 8608df2afeec46f363ef5f17146750bdf011412e56Seigo Nonaka} 87