1 /* 2 * Copyright (C) 2017 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package androidx.core.provider; 18 19 import static androidx.annotation.RestrictTo.Scope.LIBRARY; 20 import static androidx.annotation.RestrictTo.Scope.LIBRARY_GROUP_PREFIX; 21 22 import android.content.Context; 23 import android.content.pm.PackageManager; 24 import android.content.pm.ProviderInfo; 25 import android.content.res.Resources; 26 import android.graphics.Typeface; 27 import android.net.Uri; 28 import android.os.CancellationSignal; 29 import android.os.Handler; 30 import android.os.ParcelFileDescriptor; 31 import android.provider.BaseColumns; 32 33 import androidx.annotation.IntDef; 34 import androidx.annotation.IntRange; 35 import androidx.annotation.RestrictTo; 36 import androidx.annotation.VisibleForTesting; 37 import androidx.core.content.res.ResourcesCompat; 38 import androidx.core.graphics.TypefaceCompat; 39 import androidx.core.graphics.TypefaceCompatUtil; 40 import androidx.core.util.Preconditions; 41 42 import org.jspecify.annotations.NonNull; 43 import org.jspecify.annotations.Nullable; 44 45 import java.lang.annotation.Retention; 46 import java.lang.annotation.RetentionPolicy; 47 import java.nio.ByteBuffer; 48 import java.util.Collections; 49 import java.util.List; 50 import java.util.Map; 51 import java.util.concurrent.Executor; 52 53 /** 54 * Utility class to deal with Font ContentProviders. 55 */ 56 public class FontsContractCompat { FontsContractCompat()57 private FontsContractCompat() { } 58 59 @RestrictTo(RestrictTo.Scope.LIBRARY) 60 @Retention(RetentionPolicy.SOURCE) 61 @IntDef({ 62 Typeface.NORMAL, 63 Typeface.BOLD, 64 Typeface.ITALIC, 65 Typeface.BOLD_ITALIC 66 }) 67 public @interface TypefaceStyle {} 68 69 /** 70 * Build a Typeface from an array of {@link FontInfo} 71 * 72 * Results that are marked as not ready will be skipped. 73 * 74 * @param context A {@link Context} that will be used to fetch the font contents. 75 * @param cancellationSignal A signal to cancel the operation in progress, or null if none. If 76 * the operation is canceled, then {@link 77 * android.os.OperationCanceledException} will be thrown. 78 * @param fonts An array of {@link FontInfo} to be used to create a Typeface. 79 * @return A Typeface object. Returns null if typeface creation fails. 80 */ buildTypeface( @onNull Context context, @Nullable CancellationSignal cancellationSignal, FontInfo @NonNull [] fonts )81 public static @Nullable Typeface buildTypeface( 82 @NonNull Context context, 83 @Nullable CancellationSignal cancellationSignal, 84 FontInfo @NonNull [] fonts 85 ) { 86 return TypefaceCompat.createFromFontInfo(context, cancellationSignal, fonts, 87 Typeface.NORMAL); 88 } 89 90 /** 91 * Fetch fonts given a font request. 92 * 93 * @param context A {@link Context} to be used for fetching fonts. 94 * @param cancellationSignal A signal to cancel the operation in progress, or null if none. If 95 * the operation is canceled, then {@link 96 * android.os.OperationCanceledException} will be thrown when the 97 * query is executed. 98 * @param request A {@link FontRequest} object that identifies the provider and query for the 99 * request. 100 * 101 * @return {@link FontFamilyResult} 102 * 103 * @throws PackageManager.NameNotFoundException If requested package or authority was not found 104 * in the system. 105 */ fetchFonts( @onNull Context context, @Nullable CancellationSignal cancellationSignal, @NonNull FontRequest request )106 public static @NonNull FontFamilyResult fetchFonts( 107 @NonNull Context context, 108 @Nullable CancellationSignal cancellationSignal, 109 @NonNull FontRequest request 110 ) throws PackageManager.NameNotFoundException { 111 return FontProvider.getFontFamilyResult(context, List.of(request), cancellationSignal); 112 } 113 114 /** 115 * Create a typeface object given a font request. The font will be asynchronously fetched, 116 * therefore the result is delivered to the given callback. See {@link FontRequest}. 117 * Only one of the methods in callback will be invoked, depending on whether the request 118 * succeeds or fails. These calls will happen on the main thread. 119 * 120 * @deprecated due to the non-standard pattern of taking a handler for a non-UI thread - leading 121 * to both easily passing an incorrect handler and requiring all callers spin up an extra 122 * thread. 123 * 124 * @see this#requestFont(Context, FontRequest, int, Executor, Executor, FontRequestCallback) 125 * 126 * @param context A context to be used for fetching from font provider. 127 * @param request A {@link FontRequest} object that identifies the provider and query for the 128 * request. May not be null. 129 * @param callback A callback that will be triggered when results are obtained. May not be null. 130 * @param handler A handler for running font fetch tasks on. 131 */ 132 // Deprecating this to direct developers to use Executor based loading/callback, but no 133 // intention to remove this from binary since it's a very old method. 134 @Deprecated // deprecated in 1.14.0-alpha02 requestFont( final @NonNull Context context, final @NonNull FontRequest request, final @NonNull FontRequestCallback callback, final @NonNull Handler handler )135 public static void requestFont( 136 final @NonNull Context context, 137 final @NonNull FontRequest request, 138 final @NonNull FontRequestCallback callback, 139 final @NonNull Handler handler 140 ) { 141 CallbackWrapper callbackWrapper = new CallbackWrapper(callback); 142 Executor executor = RequestExecutor.createHandlerExecutor(handler); 143 FontRequestWorker.requestFontAsync(context.getApplicationContext(), 144 List.of(request), Typeface.NORMAL, executor, callbackWrapper); 145 } 146 147 /** 148 * Request a font async as specified with {@link FontRequest} 149 * 150 * Loading may take several seconds, and the {@code loadingExecutor} passed should be available 151 * to run blocking requests for several seconds. Results will be returned via 152 * {@code callbackExecutor}. 153 * 154 * @param context A context to be used for fetching from font provider 155 * @param request A {@link FontRequest} object that identifies the provider and query for the 156 * request. 157 * @param style Typeface Style such as {@link Typeface#NORMAL}, {@link Typeface#BOLD} 158 * {@link Typeface#ITALIC}, {@link Typeface#BOLD_ITALIC}. 159 * @param loadingExecutor executor to load font on. Loading may take several _seconds_. If 160 * {@code null}, a default executor shared with other null-requests will 161 * be used. 162 * @param callbackExecutor Used to dispatch callback 163 * @param callback A callback that will be triggered when results are obtained. 164 */ requestFont( @onNull Context context, @NonNull FontRequest request, @TypefaceStyle int style, @Nullable Executor loadingExecutor, @NonNull Executor callbackExecutor, @NonNull FontRequestCallback callback )165 public static void requestFont( 166 @NonNull Context context, 167 @NonNull FontRequest request, 168 @TypefaceStyle int style, 169 @Nullable Executor loadingExecutor, 170 @NonNull Executor callbackExecutor, 171 @NonNull FontRequestCallback callback 172 ) { 173 CallbackWrapper callbacKWrapper = new CallbackWrapper(callback, callbackExecutor); 174 Context applicationContext = context.getApplicationContext(); 175 FontRequestWorker.requestFontAsync(applicationContext, List.of(request), 176 style, loadingExecutor, callbacKWrapper); 177 } 178 179 /** 180 * Request a font async as specified with {@link FontRequest} 181 * 182 * Loading may take several seconds, and the {@code loadingExecutor} passed should be available 183 * to run blocking requests for several seconds. Results will be returned via 184 * {@code callbackExecutor}. 185 * 186 * @param context A context to be used for fetching from font provider 187 * @param requests An array of {@link FontRequest} objects that identify the provider and query 188 * for the request, followed by any fallbacks. 189 * Fallbacks are used in the order specified. 190 * Note that the performance implications of font fallback scale with the number 191 * of fonts involved, so the length of this parameter should be kept to a 192 * minimum; we recommend no more than 2 (that is, the primary font and a single 193 * downloadable custom fallback). 194 * @param style Typeface Style such as {@link Typeface#NORMAL}, {@link Typeface#BOLD} 195 * {@link Typeface#ITALIC}, {@link Typeface#BOLD_ITALIC}. 196 * @param loadingExecutor executor to load font on. Loading may take several _seconds_. If 197 * {@code null}, a default executor shared with other null-requests will 198 * be used. 199 * @param callbackExecutor Used to dispatch callback 200 * @param callback A callback that will be triggered when results are obtained. 201 */ requestFontWithFallbackChain( @onNull Context context, @NonNull List<FontRequest> requests, @TypefaceStyle int style, @Nullable Executor loadingExecutor, @NonNull Executor callbackExecutor, @NonNull FontRequestCallback callback )202 public static void requestFontWithFallbackChain( 203 @NonNull Context context, 204 @NonNull List<FontRequest> requests, 205 @TypefaceStyle int style, 206 @Nullable Executor loadingExecutor, 207 @NonNull Executor callbackExecutor, 208 @NonNull FontRequestCallback callback 209 ) { 210 CallbackWrapper callbacKWrapper = new CallbackWrapper(callback, callbackExecutor); 211 Context applicationContext = context.getApplicationContext(); 212 FontRequestWorker.requestFontAsync(applicationContext, requests, 213 style, loadingExecutor, callbacKWrapper); 214 } 215 216 /** 217 * Loads a Typeface. Based on the parameters isBlockingFetch, and timeoutInMillis, the fetch 218 * is either sync or async. 219 * - If timeoutInMillis is infinite, and isBlockingFetch is true -> sync 220 * - If timeoutInMillis is NOT infinite, and isBlockingFetch is true -> sync with timeout 221 * - else -> async without timeout. 222 * 223 * Used by TypefaceCompat and tests. 224 * 225 * @param context Context 226 * @param requests List of FontRequests that define the font to be loaded, followed by any 227 * custom fallbacks, in order 228 * @param style Typeface Style such as {@link Typeface#NORMAL}, {@link Typeface#BOLD} 229 * {@link Typeface#ITALIC}, {@link Typeface#BOLD_ITALIC}. 230 * @param isBlockingFetch when true the call will be synchronous. 231 * @param timeout timeout in milliseconds for the request. It is not used for async 232 * request. 233 * @param handler the handler to call the callback on. 234 * @param callback the callback to be called. 235 * 236 * @return the resulting Typeface if the requested font is in the cache or the request is a 237 * sync request. 238 * 239 */ 240 @RestrictTo(LIBRARY) requestFont( final @NonNull Context context, final @NonNull List<FontRequest> requests, @TypefaceStyle final int style, boolean isBlockingFetch, @IntRange(from = 0) int timeout, final @NonNull Handler handler, final @NonNull FontRequestCallback callback )241 public static @Nullable Typeface requestFont( 242 final @NonNull Context context, 243 final @NonNull List<FontRequest> requests, 244 @TypefaceStyle final int style, 245 boolean isBlockingFetch, 246 @IntRange(from = 0) int timeout, 247 final @NonNull Handler handler, 248 final @NonNull FontRequestCallback callback 249 ) { 250 CallbackWrapper callbackWrapper = new CallbackWrapper( 251 callback, RequestExecutor.createHandlerExecutor(handler)); 252 253 if (isBlockingFetch) { 254 if (requests.size() > 1) { 255 throw new IllegalArgumentException( 256 "Fallbacks with blocking fetches are not supported for performance " 257 + "reasons"); 258 } 259 return FontRequestWorker.requestFontSync(context, requests.get(0), callbackWrapper, 260 style, timeout); 261 } else { 262 return FontRequestWorker.requestFontAsync(context, requests, style, null /*executor*/, 263 callbackWrapper); 264 } 265 } 266 267 /** 268 * Loads a Typeface. Based on the parameters isBlockingFetch, and timeoutInMillis, the fetch 269 * is either sync or async. 270 * - If timeoutInMillis is infinite, and isBlockingFetch is true -> sync 271 * - If timeoutInMillis is NOT infinite, and isBlockingFetch is true -> sync with timeout 272 * - else -> async without timeout. 273 * 274 * Used by TypefaceCompat and tests. 275 * 276 * @param context Context 277 * @param request FontRequest that define the font to be loaded and any fallbacks 278 * @param style Typeface Style such as {@link Typeface#NORMAL}, {@link Typeface#BOLD} 279 * {@link Typeface#ITALIC}, {@link Typeface#BOLD_ITALIC}. 280 * @param isBlockingFetch when true the call will be synchronous. 281 * @param timeout timeout in milliseconds for the request. It is not used for async 282 * request. 283 * @param handler the handler to call the callback on. 284 * @param callback the callback to be called. 285 * 286 * @return the resulting Typeface if the requested font is in the cache or the request is a 287 * sync request. 288 * 289 */ 290 @RestrictTo(LIBRARY_GROUP_PREFIX) requestFont( final @NonNull Context context, final @NonNull FontRequest request, @TypefaceStyle final int style, boolean isBlockingFetch, @IntRange(from = 0) int timeout, final @NonNull Handler handler, final @NonNull FontRequestCallback callback )291 public static @Nullable Typeface requestFont( 292 final @NonNull Context context, 293 final @NonNull FontRequest request, 294 @TypefaceStyle final int style, 295 boolean isBlockingFetch, 296 @IntRange(from = 0) int timeout, 297 final @NonNull Handler handler, 298 final @NonNull FontRequestCallback callback 299 ) { 300 return requestFont(context, List.of(request), style, isBlockingFetch, timeout, handler, 301 callback); 302 } 303 304 @RestrictTo(LIBRARY) 305 @VisibleForTesting resetTypefaceCache()306 public static void resetTypefaceCache() { 307 FontRequestWorker.resetTypefaceCache(); 308 } 309 310 /** 311 * Defines the constants used in a response from a Font Provider. The cursor returned from the 312 * query should have the ID column populated with the content uri ID for the resulting font. 313 * This should point to a real file or shared memory, as the client will mmap the given file 314 * descriptor. Pipes, sockets and other non-mmap-able file descriptors will fail to load in the 315 * client application. 316 */ 317 public static final class Columns implements BaseColumns { 318 /** 319 * Constant used to request data from a font provider. The cursor returned from the query 320 * may populate this column with a long for the font file ID. The client will request a file 321 * descriptor to "file/FILE_ID" with this ID immediately under the top-level content URI. If 322 * not present, the client will request a file descriptor to the top-level URI with the 323 * given base font ID. Note that several results may return the same file ID, e.g. for TTC 324 * files with different indices. 325 */ 326 public static final String FILE_ID = "file_id"; 327 /** 328 * Constant used to request data from a font provider. The cursor returned from the query 329 * should have this column populated with an int for the ttc index for the resulting font. 330 */ 331 public static final String TTC_INDEX = android.provider.FontsContract.Columns.TTC_INDEX; 332 /** 333 * Constant used to request data from a font provider. The cursor returned from the query 334 * may populate this column with the font variation settings String information for the 335 * font. 336 */ 337 public static final String VARIATION_SETTINGS = 338 android.provider.FontsContract.Columns.VARIATION_SETTINGS; 339 /** 340 * Constant used to request data from a font provider. The cursor returned from the query 341 * should have this column populated with the int weight for the resulting font. This value 342 * should be between 100 and 900. The most common values are 400 for regular weight and 700 343 * for bold weight. 344 */ 345 public static final String WEIGHT = android.provider.FontsContract.Columns.WEIGHT; 346 /** 347 * Constant used to request data from a font provider. The cursor returned from the query 348 * should have this column populated with the int italic for the resulting font. This should 349 * be 0 for regular style and 1 for italic. 350 */ 351 public static final String ITALIC = android.provider.FontsContract.Columns.ITALIC; 352 /** 353 * Constant used to request data from a font provider. The cursor returned from the query 354 * should have this column populated to indicate the result status of the 355 * query. This will be checked before any other data in the cursor. Possible values are 356 * {@link #RESULT_CODE_OK}, {@link #RESULT_CODE_FONT_NOT_FOUND}, 357 * {@link #RESULT_CODE_MALFORMED_QUERY} and {@link #RESULT_CODE_FONT_UNAVAILABLE}. If not 358 * present, {@link #RESULT_CODE_OK} will be assumed. 359 */ 360 public static final String RESULT_CODE = android.provider.FontsContract.Columns.RESULT_CODE; 361 362 /** 363 * Constant used to represent a result was retrieved successfully. The given fonts will be 364 * attempted to retrieve immediately via 365 * {@link android.content.ContentProvider#openFile(Uri, String)}. See {@link #RESULT_CODE}. 366 */ 367 public static final int RESULT_CODE_OK = 368 android.provider.FontsContract.Columns.RESULT_CODE_OK; 369 /** 370 * Constant used to represent a result was not found. See {@link #RESULT_CODE}. 371 */ 372 public static final int RESULT_CODE_FONT_NOT_FOUND = 373 android.provider.FontsContract.Columns.RESULT_CODE_FONT_NOT_FOUND; 374 /** 375 * Constant used to represent a result was found, but cannot be provided at this moment. Use 376 * this to indicate, for example, that a font needs to be fetched from the network. See 377 * {@link #RESULT_CODE}. 378 */ 379 public static final int RESULT_CODE_FONT_UNAVAILABLE = 380 android.provider.FontsContract.Columns.RESULT_CODE_FONT_UNAVAILABLE; 381 /** 382 * Constant used to represent that the query was not in a supported format by the provider. 383 * See {@link #RESULT_CODE}. 384 */ 385 public static final int RESULT_CODE_MALFORMED_QUERY = 386 android.provider.FontsContract.Columns.RESULT_CODE_MALFORMED_QUERY; 387 } 388 389 /** 390 * Object represent a font entry in the family returned from {@link #fetchFonts}. 391 */ 392 public static class FontInfo { 393 private final Uri mUri; 394 private final int mTtcIndex; 395 private final int mWeight; 396 private final boolean mItalic; 397 private final int mResultCode; 398 399 /** 400 * Creates a Font with all the information needed about a provided font. 401 * @param uri A URI associated to the font file. 402 * @param ttcIndex If providing a TTC_INDEX file, the index to point to. Otherwise, 0. 403 * @param weight An integer that indicates the font weight. 404 * @param italic A boolean that indicates the font is italic style or not. 405 * @param resultCode A boolean that indicates the font contents is ready. 406 * 407 * @deprecated Not being used by any cross library, and should not be used, internal 408 * implementation detail. 409 * 410 */ 411 // TODO after removing from public API make package private. 412 @Deprecated 413 @RestrictTo(LIBRARY_GROUP_PREFIX) FontInfo( @onNull Uri uri, @IntRange(from = 0) int ttcIndex, @IntRange(from = 1, to = 1000) int weight, boolean italic, int resultCode )414 public FontInfo( 415 @NonNull Uri uri, 416 @IntRange(from = 0) int ttcIndex, 417 @IntRange(from = 1, to = 1000) int weight, 418 boolean italic, 419 int resultCode 420 ) { 421 mUri = Preconditions.checkNotNull(uri); 422 mTtcIndex = ttcIndex; 423 mWeight = weight; 424 mItalic = italic; 425 mResultCode = resultCode; 426 } 427 428 @SuppressWarnings("deprecation") create( @onNull Uri uri, @IntRange(from = 0) int ttcIndex, @IntRange(from = 1, to = 1000) int weight, boolean italic, int resultCode )429 static FontInfo create( 430 @NonNull Uri uri, 431 @IntRange(from = 0) int ttcIndex, 432 @IntRange(from = 1, to = 1000) int weight, 433 boolean italic, 434 int resultCode 435 ) { 436 return new FontInfo(uri, ttcIndex, weight, italic, resultCode); 437 } 438 439 /** 440 * Returns a URI associated to this record. 441 */ getUri()442 public @NonNull Uri getUri() { 443 return mUri; 444 } 445 446 /** 447 * Returns the index to be used to access this font when accessing a TTC file. 448 */ getTtcIndex()449 public @IntRange(from = 0) int getTtcIndex() { 450 return mTtcIndex; 451 } 452 453 /** 454 * Returns the weight value for this font. 455 */ getWeight()456 public @IntRange(from = 1, to = 1000) int getWeight() { 457 return mWeight; 458 } 459 460 /** 461 * Returns whether this font is italic. 462 */ isItalic()463 public boolean isItalic() { 464 return mItalic; 465 } 466 467 /** 468 * Returns result code. 469 * 470 * {@link FontsContractCompat.Columns#RESULT_CODE} 471 */ getResultCode()472 public int getResultCode() { 473 return mResultCode; 474 } 475 } 476 477 /** 478 * Object returned from {@link #fetchFonts}. 479 */ 480 public static class FontFamilyResult { 481 /** 482 * Constant represents that the font was successfully retrieved. Note that when this value 483 * is set and {@link #getFonts} returns an empty array, it means there were no fonts 484 * matching the given query. 485 */ 486 public static final int STATUS_OK = 0; 487 488 /** 489 * Constant represents that the given certificate was not matched with the provider's 490 * signature. {@link #getFonts} returns null if this status was set. 491 */ 492 public static final int STATUS_WRONG_CERTIFICATES = 1; 493 494 /** 495 * Constant represents that the provider returns unexpected data. {@link #getFonts} returns 496 * null if this status was set. For example, this value is set when the font provider 497 * gives invalid format of variation settings. 498 */ 499 public static final int STATUS_UNEXPECTED_DATA_PROVIDED = 2; 500 501 @RestrictTo(LIBRARY) 502 @IntDef({STATUS_OK, STATUS_WRONG_CERTIFICATES, STATUS_UNEXPECTED_DATA_PROVIDED}) 503 @Retention(RetentionPolicy.SOURCE) 504 @interface FontResultStatus {} 505 506 private final @FontResultStatus int mStatusCode; 507 private final List<FontInfo[]> mFonts; 508 509 /** 510 * @deprecated Not being used by any cross library, and should not be used, internal 511 * implementation detail. 512 */ 513 // TODO after removing from public API make package private. 514 @Deprecated 515 @RestrictTo(LIBRARY_GROUP_PREFIX) FontFamilyResult(@ontResultStatus int statusCode, FontInfo @Nullable [] fonts)516 public FontFamilyResult(@FontResultStatus int statusCode, FontInfo @Nullable [] fonts) { 517 mStatusCode = statusCode; 518 mFonts = Collections.singletonList(fonts); 519 } 520 FontFamilyResult(@ontResultStatus int statusCode, @NonNull List<FontInfo[]> fonts)521 FontFamilyResult(@FontResultStatus int statusCode, @NonNull List<FontInfo[]> fonts) { 522 mStatusCode = statusCode; 523 mFonts = fonts; 524 } 525 getStatusCode()526 public @FontResultStatus int getStatusCode() { 527 return mStatusCode; 528 } 529 530 /** 531 * For a single request, returns an array of the fonts making up the family. 532 * <p> 533 * For a request with fallbacks, use {@link #getFontsWithFallbacks()}, 534 * as this will only return the information for the first requested family. 535 */ getFonts()536 public FontInfo[] getFonts() { 537 return mFonts.get(0); 538 } 539 hasFallback()540 boolean hasFallback() { 541 return mFonts.size() > 1; 542 } 543 544 /** 545 * Returns a list of arrays of fonts for each font family requested, in order. 546 */ getFontsWithFallbacks()547 public @NonNull List<FontInfo[]> getFontsWithFallbacks() { 548 return mFonts; 549 } 550 551 @SuppressWarnings("deprecation") create( @ontResultStatus int statusCode, FontInfo @Nullable [] fonts)552 static FontFamilyResult create( 553 @FontResultStatus int statusCode, 554 FontInfo @Nullable [] fonts) { 555 return new FontFamilyResult(statusCode, fonts); 556 } 557 create( @ontResultStatus int statusCode, @Nullable List<FontInfo[]> fonts)558 static FontFamilyResult create( 559 @FontResultStatus int statusCode, 560 @Nullable List<FontInfo[]> fonts) { 561 return new FontFamilyResult(statusCode, fonts); 562 } 563 } 564 565 /** 566 * Interface used to receive asynchronously fetched typefaces. 567 */ 568 public static class FontRequestCallback { 569 /** 570 * @deprecated Not being used by any cross library, and should not be used, internal 571 * implementation detail. 572 */ 573 @Deprecated 574 @RestrictTo(LIBRARY_GROUP_PREFIX) 575 public static final int RESULT_OK = Columns.RESULT_CODE_OK; 576 577 static final int RESULT_SUCCESS = Columns.RESULT_CODE_OK; 578 579 /** 580 * Constant returned by {@link #onTypefaceRequestFailed(int)} signaling that the given 581 * provider was not found on the device. 582 */ 583 public static final int FAIL_REASON_PROVIDER_NOT_FOUND = -1; 584 585 /** 586 * Constant returned by {@link #onTypefaceRequestFailed(int)} signaling that the given 587 * provider must be authenticated and the given certificates do not match its signature. 588 */ 589 public static final int FAIL_REASON_WRONG_CERTIFICATES = -2; 590 591 /** 592 * Constant returned by {@link #onTypefaceRequestFailed(int)} signaling that the font 593 * returned by the provider was not loaded properly. 594 */ 595 public static final int FAIL_REASON_FONT_LOAD_ERROR = -3; 596 597 /** 598 * Constant that signals that the font was not loaded due to security issues. This usually 599 * means the font was attempted to load on a restricted context. 600 */ 601 public static final int FAIL_REASON_SECURITY_VIOLATION = -4; 602 603 /** 604 * Constant returned by {@link #onTypefaceRequestFailed(int)} signaling that the font 605 * provider did not return any results for the given query. 606 */ 607 public static final int FAIL_REASON_FONT_NOT_FOUND = Columns.RESULT_CODE_FONT_NOT_FOUND; 608 609 /** 610 * Constant returned by {@link #onTypefaceRequestFailed(int)} signaling that the font 611 * provider found the queried font, but it is currently unavailable. 612 */ 613 public static final int FAIL_REASON_FONT_UNAVAILABLE = Columns.RESULT_CODE_FONT_UNAVAILABLE; 614 615 /** 616 * Constant returned by {@link #onTypefaceRequestFailed(int)} signaling that the given 617 * query was not supported by the provider. 618 */ 619 public static final int FAIL_REASON_MALFORMED_QUERY = Columns.RESULT_CODE_MALFORMED_QUERY; 620 621 @SuppressWarnings("deprecation") 622 @RestrictTo(LIBRARY_GROUP_PREFIX) 623 @IntDef({ FAIL_REASON_PROVIDER_NOT_FOUND, FAIL_REASON_FONT_LOAD_ERROR, 624 FAIL_REASON_FONT_NOT_FOUND, FAIL_REASON_FONT_UNAVAILABLE, 625 FAIL_REASON_MALFORMED_QUERY, FAIL_REASON_WRONG_CERTIFICATES, 626 FAIL_REASON_SECURITY_VIOLATION, RESULT_OK }) 627 @Retention(RetentionPolicy.SOURCE) 628 public @interface FontRequestFailReason {} 629 FontRequestCallback()630 public FontRequestCallback() {} 631 632 /** 633 * Called then a Typeface request done via {@link #requestFont(Context, FontRequest, 634 * FontRequestCallback, Handler)} is complete. Note that this method will not be called if 635 * {@link #onTypefaceRequestFailed(int)} is called instead. 636 * @param typeface The Typeface object retrieved. 637 */ onTypefaceRetrieved(Typeface typeface)638 public void onTypefaceRetrieved(Typeface typeface) {} 639 640 /** 641 * Called when a Typeface request done via {@link #requestFont(Context, FontRequest, 642 * FontRequestCallback, Handler)} fails. 643 * @param reason May be one of {@link #FAIL_REASON_PROVIDER_NOT_FOUND}, 644 * {@link #FAIL_REASON_FONT_NOT_FOUND}, 645 * {@link #FAIL_REASON_FONT_LOAD_ERROR}, 646 * {@link #FAIL_REASON_FONT_UNAVAILABLE}, 647 * {@link #FAIL_REASON_MALFORMED_QUERY} or 648 * {@link #FAIL_REASON_WRONG_CERTIFICATES}, or a provider defined positive 649 * code number. 650 */ onTypefaceRequestFailed(@ontRequestFailReason int reason)651 public void onTypefaceRequestFailed(@FontRequestFailReason int reason) {} 652 } 653 654 /** 655 * Constant used to identify the List of {@link ParcelFileDescriptor} item in the Bundle 656 * returned to the ResultReceiver in getFont. 657 * 658 * @deprecated Not being used by any cross library, and should not be used, internal 659 * implementation detail. 660 * 661 */ 662 @Deprecated // unused 663 @RestrictTo(LIBRARY_GROUP_PREFIX) 664 public static final String PARCEL_FONT_RESULTS = "font_results"; 665 666 // Error codes internal to the system, which can not come from a provider. To keep the number 667 // space open for new provider codes, these should all be negative numbers. 668 /** 669 * @deprecated Not being used by any cross library, and should not be used, internal 670 * implementation detail. 671 */ 672 @Deprecated // unused 673 @RestrictTo(LIBRARY_GROUP_PREFIX) 674 static final int RESULT_CODE_PROVIDER_NOT_FOUND = -1; 675 676 /** 677 * @deprecated Not being used by any cross library, and should not be used, internal 678 * implementation detail. 679 */ 680 @Deprecated // unused 681 @RestrictTo(LIBRARY_GROUP_PREFIX) 682 static final int RESULT_CODE_WRONG_CERTIFICATES = -2; 683 // Note -3 is used by FontRequestCallback to indicate the font failed to load. 684 685 /** 686 * @deprecated Not being used by any cross library, and should not be used, internal 687 * implementation detail. 688 */ 689 @Deprecated // unused 690 @RestrictTo(LIBRARY_GROUP_PREFIX) getFontSync( final Context context, final FontRequest request, final ResourcesCompat.@Nullable FontCallback fontCallback, final @Nullable Handler handler, boolean isBlockingFetch, int timeout, @TypefaceStyle final int style )691 public static Typeface getFontSync( 692 final Context context, 693 final FontRequest request, 694 final ResourcesCompat.@Nullable FontCallback fontCallback, 695 final @Nullable Handler handler, 696 boolean isBlockingFetch, 697 int timeout, 698 @TypefaceStyle final int style 699 ) { 700 FontRequestCallback newCallback = new TypefaceCompat.ResourcesCallbackAdapter(fontCallback); 701 Handler newHandler = ResourcesCompat.FontCallback.getHandler(handler); 702 return requestFont(context, List.of(request), style, isBlockingFetch, timeout, 703 newHandler, newCallback 704 ); 705 } 706 707 /** 708 * @deprecated Not being used by any cross library, and should not be used, internal 709 * implementation detail. 710 */ 711 @Deprecated // unused 712 @RestrictTo(LIBRARY_GROUP_PREFIX) resetCache()713 public static void resetCache() { 714 FontRequestWorker.resetTypefaceCache(); 715 } 716 717 /** 718 * A helper function to create a mapping from {@link Uri} to {@link ByteBuffer}. 719 * 720 * Skip if the file contents is not ready to be read. 721 * 722 * @param context A {@link Context} to be used for resolving content URI in 723 * {@link FontInfo}. 724 * @param fonts An array of {@link FontInfo}. 725 * @return A map from {@link Uri} to {@link ByteBuffer}. 726 * 727 * @deprecated Not being used by any cross library, and should not be used, internal 728 * implementation detail. 729 * 730 */ 731 @Deprecated // unused 732 @RestrictTo(LIBRARY_GROUP_PREFIX) prepareFontData( Context context, FontInfo[] fonts, CancellationSignal cancellationSignal )733 public static Map<Uri, ByteBuffer> prepareFontData( 734 Context context, 735 FontInfo[] fonts, 736 CancellationSignal cancellationSignal 737 ) { 738 return TypefaceCompatUtil.readFontInfoIntoByteBuffer(context, fonts, cancellationSignal); 739 } 740 741 /** 742 * @deprecated Not being used by any cross library, and should not be used, internal 743 * implementation detail. 744 */ 745 @Deprecated // unused 746 @VisibleForTesting 747 @RestrictTo(LIBRARY_GROUP_PREFIX) getProvider( @onNull PackageManager packageManager, @NonNull FontRequest request, @Nullable Resources resources )748 public static @Nullable ProviderInfo getProvider( 749 @NonNull PackageManager packageManager, 750 @NonNull FontRequest request, 751 @Nullable Resources resources 752 ) throws PackageManager.NameNotFoundException { 753 return FontProvider.getProvider(packageManager, request, resources); 754 } 755 } 756