diff options
| -rw-r--r-- | api/current.txt | 17 | ||||
| -rw-r--r-- | api/system-current.txt | 17 | ||||
| -rw-r--r-- | api/test-current.txt | 17 | ||||
| -rw-r--r-- | core/java/android/provider/FontsContract.java | 144 | ||||
| -rw-r--r-- | graphics/java/android/graphics/Typeface.java | 2 |
5 files changed, 191 insertions, 6 deletions
diff --git a/api/current.txt b/api/current.txt index 45fb4d96aad3..84ebdf3118f6 100644 --- a/api/current.txt +++ b/api/current.txt @@ -13762,7 +13762,7 @@ package android.graphics { } public class Typeface { - method public static void create(android.graphics.fonts.FontRequest, android.graphics.Typeface.FontRequestCallback); + method public static deprecated void create(android.graphics.fonts.FontRequest, android.graphics.Typeface.FontRequestCallback); method public static android.graphics.Typeface create(java.lang.String, int); method public static android.graphics.Typeface create(android.graphics.Typeface, int); method public static android.graphics.Typeface createFromAsset(android.content.res.AssetManager, java.lang.String); @@ -13796,7 +13796,7 @@ package android.graphics { method public android.graphics.Typeface.Builder setWeight(int); } - public static abstract interface Typeface.FontRequestCallback { + public static abstract deprecated interface Typeface.FontRequestCallback { method public abstract void onTypefaceRequestFailed(int); method public abstract void onTypefaceRetrieved(android.graphics.Typeface); field public static final int FAIL_REASON_FONT_LOAD_ERROR = -3; // 0xfffffffd @@ -34505,6 +34505,7 @@ package android.provider { method public static android.graphics.Typeface buildTypeface(android.content.Context, android.os.CancellationSignal, android.provider.FontsContract.FontInfo[], int, boolean, java.lang.String); method public static android.graphics.Typeface buildTypeface(android.content.Context, android.os.CancellationSignal, android.provider.FontsContract.FontInfo[]); method public static android.provider.FontsContract.FontFamilyResult fetchFonts(android.content.Context, android.os.CancellationSignal, android.graphics.fonts.FontRequest) throws android.content.pm.PackageManager.NameNotFoundException; + method public static void requestFont(android.content.Context, android.graphics.fonts.FontRequest, android.provider.FontsContract.FontRequestCallback, android.os.Handler); } public static final class FontsContract.Columns implements android.provider.BaseColumns { @@ -34538,6 +34539,18 @@ package android.provider { method public boolean isItalic(); } + public static class FontsContract.FontRequestCallback { + ctor public FontsContract.FontRequestCallback(); + method public void onTypefaceRequestFailed(int); + method public void onTypefaceRetrieved(android.graphics.Typeface); + field public static final int FAIL_REASON_FONT_LOAD_ERROR = -3; // 0xfffffffd + field public static final int FAIL_REASON_FONT_NOT_FOUND = 1; // 0x1 + field public static final int FAIL_REASON_FONT_UNAVAILABLE = 2; // 0x2 + field public static final int FAIL_REASON_MALFORMED_QUERY = 3; // 0x3 + field public static final int FAIL_REASON_PROVIDER_NOT_FOUND = -1; // 0xffffffff + field public static final int FAIL_REASON_WRONG_CERTIFICATES = -2; // 0xfffffffe + } + public final deprecated class LiveFolders implements android.provider.BaseColumns { field public static final java.lang.String ACTION_CREATE_LIVE_FOLDER = "android.intent.action.CREATE_LIVE_FOLDER"; field public static final java.lang.String DESCRIPTION = "description"; diff --git a/api/system-current.txt b/api/system-current.txt index 8ae3f516dbad..7b0e10b1429f 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -14529,7 +14529,7 @@ package android.graphics { } public class Typeface { - method public static void create(android.graphics.fonts.FontRequest, android.graphics.Typeface.FontRequestCallback); + method public static deprecated void create(android.graphics.fonts.FontRequest, android.graphics.Typeface.FontRequestCallback); method public static android.graphics.Typeface create(java.lang.String, int); method public static android.graphics.Typeface create(android.graphics.Typeface, int); method public static android.graphics.Typeface createFromAsset(android.content.res.AssetManager, java.lang.String); @@ -14563,7 +14563,7 @@ package android.graphics { method public android.graphics.Typeface.Builder setWeight(int); } - public static abstract interface Typeface.FontRequestCallback { + public static abstract deprecated interface Typeface.FontRequestCallback { method public abstract void onTypefaceRequestFailed(int); method public abstract void onTypefaceRetrieved(android.graphics.Typeface); field public static final int FAIL_REASON_FONT_LOAD_ERROR = -3; // 0xfffffffd @@ -37482,6 +37482,7 @@ package android.provider { method public static android.graphics.Typeface buildTypeface(android.content.Context, android.os.CancellationSignal, android.provider.FontsContract.FontInfo[], int, boolean, java.lang.String); method public static android.graphics.Typeface buildTypeface(android.content.Context, android.os.CancellationSignal, android.provider.FontsContract.FontInfo[]); method public static android.provider.FontsContract.FontFamilyResult fetchFonts(android.content.Context, android.os.CancellationSignal, android.graphics.fonts.FontRequest) throws android.content.pm.PackageManager.NameNotFoundException; + method public static void requestFont(android.content.Context, android.graphics.fonts.FontRequest, android.provider.FontsContract.FontRequestCallback, android.os.Handler); } public static final class FontsContract.Columns implements android.provider.BaseColumns { @@ -37515,6 +37516,18 @@ package android.provider { method public boolean isItalic(); } + public static class FontsContract.FontRequestCallback { + ctor public FontsContract.FontRequestCallback(); + method public void onTypefaceRequestFailed(int); + method public void onTypefaceRetrieved(android.graphics.Typeface); + field public static final int FAIL_REASON_FONT_LOAD_ERROR = -3; // 0xfffffffd + field public static final int FAIL_REASON_FONT_NOT_FOUND = 1; // 0x1 + field public static final int FAIL_REASON_FONT_UNAVAILABLE = 2; // 0x2 + field public static final int FAIL_REASON_MALFORMED_QUERY = 3; // 0x3 + field public static final int FAIL_REASON_PROVIDER_NOT_FOUND = -1; // 0xffffffff + field public static final int FAIL_REASON_WRONG_CERTIFICATES = -2; // 0xfffffffe + } + public final deprecated class LiveFolders implements android.provider.BaseColumns { field public static final java.lang.String ACTION_CREATE_LIVE_FOLDER = "android.intent.action.CREATE_LIVE_FOLDER"; field public static final java.lang.String DESCRIPTION = "description"; diff --git a/api/test-current.txt b/api/test-current.txt index fd8c2d001b6a..f3a5adc8d89b 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -13813,7 +13813,7 @@ package android.graphics { } public class Typeface { - method public static void create(android.graphics.fonts.FontRequest, android.graphics.Typeface.FontRequestCallback); + method public static deprecated void create(android.graphics.fonts.FontRequest, android.graphics.Typeface.FontRequestCallback); method public static android.graphics.Typeface create(java.lang.String, int); method public static android.graphics.Typeface create(android.graphics.Typeface, int); method public static android.graphics.Typeface createFromAsset(android.content.res.AssetManager, java.lang.String); @@ -13847,7 +13847,7 @@ package android.graphics { method public android.graphics.Typeface.Builder setWeight(int); } - public static abstract interface Typeface.FontRequestCallback { + public static abstract deprecated interface Typeface.FontRequestCallback { method public abstract void onTypefaceRequestFailed(int); method public abstract void onTypefaceRetrieved(android.graphics.Typeface); field public static final int FAIL_REASON_FONT_LOAD_ERROR = -3; // 0xfffffffd @@ -34649,6 +34649,7 @@ package android.provider { method public static android.graphics.Typeface buildTypeface(android.content.Context, android.os.CancellationSignal, android.provider.FontsContract.FontInfo[], int, boolean, java.lang.String); method public static android.graphics.Typeface buildTypeface(android.content.Context, android.os.CancellationSignal, android.provider.FontsContract.FontInfo[]); method public static android.provider.FontsContract.FontFamilyResult fetchFonts(android.content.Context, android.os.CancellationSignal, android.graphics.fonts.FontRequest) throws android.content.pm.PackageManager.NameNotFoundException; + method public static void requestFont(android.content.Context, android.graphics.fonts.FontRequest, android.provider.FontsContract.FontRequestCallback, android.os.Handler); } public static final class FontsContract.Columns implements android.provider.BaseColumns { @@ -34682,6 +34683,18 @@ package android.provider { method public boolean isItalic(); } + public static class FontsContract.FontRequestCallback { + ctor public FontsContract.FontRequestCallback(); + method public void onTypefaceRequestFailed(int); + method public void onTypefaceRetrieved(android.graphics.Typeface); + field public static final int FAIL_REASON_FONT_LOAD_ERROR = -3; // 0xfffffffd + field public static final int FAIL_REASON_FONT_NOT_FOUND = 1; // 0x1 + field public static final int FAIL_REASON_FONT_UNAVAILABLE = 2; // 0x2 + field public static final int FAIL_REASON_MALFORMED_QUERY = 3; // 0x3 + field public static final int FAIL_REASON_PROVIDER_NOT_FOUND = -1; // 0xffffffff + field public static final int FAIL_REASON_WRONG_CERTIFICATES = -2; // 0xfffffffe + } + public final deprecated class LiveFolders implements android.provider.BaseColumns { field public static final java.lang.String ACTION_CREATE_LIVE_FOLDER = "android.intent.action.CREATE_LIVE_FOLDER"; field public static final java.lang.String DESCRIPTION = "description"; diff --git a/core/java/android/provider/FontsContract.java b/core/java/android/provider/FontsContract.java index f9508902d49f..7e56ff988158 100644 --- a/core/java/android/provider/FontsContract.java +++ b/core/java/android/provider/FontsContract.java @@ -394,6 +394,150 @@ public class FontsContract { } /** + * Interface used to receive asynchronously fetched typefaces. + */ + public static class FontRequestCallback { + /** + * Constant returned by {@link #onTypefaceRequestFailed(int)} signaling that the given + * provider was not found on the device. + */ + public static final int FAIL_REASON_PROVIDER_NOT_FOUND = RESULT_CODE_PROVIDER_NOT_FOUND; + /** + * Constant returned by {@link #onTypefaceRequestFailed(int)} signaling that the given + * provider must be authenticated and the given certificates do not match its signature. + */ + public static final int FAIL_REASON_WRONG_CERTIFICATES = RESULT_CODE_WRONG_CERTIFICATES; + /** + * Constant returned by {@link #onTypefaceRequestFailed(int)} signaling that the font + * returned by the provider was not loaded properly. + */ + public static final int FAIL_REASON_FONT_LOAD_ERROR = -3; + /** + * Constant returned by {@link #onTypefaceRequestFailed(int)} signaling that the font + * provider did not return any results for the given query. + */ + public static final int FAIL_REASON_FONT_NOT_FOUND = Columns.RESULT_CODE_FONT_NOT_FOUND; + /** + * Constant returned by {@link #onTypefaceRequestFailed(int)} signaling that the font + * provider found the queried font, but it is currently unavailable. + */ + public static final int FAIL_REASON_FONT_UNAVAILABLE = Columns.RESULT_CODE_FONT_UNAVAILABLE; + /** + * Constant returned by {@link #onTypefaceRequestFailed(int)} signaling that the given + * query was not supported by the provider. + */ + public static final int FAIL_REASON_MALFORMED_QUERY = Columns.RESULT_CODE_MALFORMED_QUERY; + + /** @hide */ + @IntDef({ FAIL_REASON_PROVIDER_NOT_FOUND, FAIL_REASON_FONT_LOAD_ERROR, + FAIL_REASON_FONT_NOT_FOUND, FAIL_REASON_FONT_UNAVAILABLE, + FAIL_REASON_MALFORMED_QUERY }) + @Retention(RetentionPolicy.SOURCE) + @interface FontRequestFailReason {} + + public FontRequestCallback() {} + + /** + * Called then a Typeface request done via {@link Typeface#create(FontRequest, + * FontRequestCallback)} is complete. Note that this method will not be called if + * {@link #onTypefaceRequestFailed(int)} is called instead. + * @param typeface The Typeface object retrieved. + */ + public void onTypefaceRetrieved(Typeface typeface) {} + + /** + * Called when a Typeface request done via {@link Typeface#create(FontRequest, + * FontRequestCallback)} fails. + * @param reason One of {@link #FAIL_REASON_PROVIDER_NOT_FOUND}, + * {@link #FAIL_REASON_FONT_NOT_FOUND}, + * {@link #FAIL_REASON_FONT_LOAD_ERROR}, + * {@link #FAIL_REASON_FONT_UNAVAILABLE} or + * {@link #FAIL_REASON_MALFORMED_QUERY}. + */ + public void onTypefaceRequestFailed(@FontRequestFailReason int reason) {} + } + + /** + * Create a typeface object given a font request. The font will be asynchronously fetched, + * therefore the result is delivered to the given callback. See {@link FontRequest}. + * Only one of the methods in callback will be invoked, depending on whether the request + * succeeds or fails. These calls will happen on the caller thread. + * @param context A context to be used for fetching from font provider. + * @param request A {@link FontRequest} object that identifies the provider and query for the + * request. May not be null. + * @param callback A callback that will be triggered when results are obtained. May not be null. + * @param handler A handler to be processed the font fetching. + */ + public static void requestFont(@NonNull Context context, @NonNull FontRequest request, + @NonNull FontRequestCallback callback, @NonNull Handler handler) { + + final Handler callerThreadHandler = new Handler(); + handler.post(() -> { + // TODO: Cache the result. + FontFamilyResult result; + try { + result = fetchFonts(context, null /* cancellation signal */, request); + } catch (NameNotFoundException e) { + callerThreadHandler.post(() -> callback.onTypefaceRequestFailed( + FontRequestCallback.FAIL_REASON_PROVIDER_NOT_FOUND)); + return; + } + + if (result.getStatusCode() != FontFamilyResult.STATUS_OK) { + switch (result.getStatusCode()) { + case FontFamilyResult.STATUS_WRONG_CERTIFICATES: + callerThreadHandler.post(() -> callback.onTypefaceRequestFailed( + FontRequestCallback.FAIL_REASON_WRONG_CERTIFICATES)); + return; + case FontFamilyResult.STATUS_UNEXPECTED_DATA_PROVIDED: + callerThreadHandler.post(() -> callback.onTypefaceRequestFailed( + FontRequestCallback.FAIL_REASON_FONT_LOAD_ERROR)); + return; + default: + // fetchFont returns unexpected status type. Fallback to load error. + callerThreadHandler.post(() -> callback.onTypefaceRequestFailed( + FontRequestCallback.FAIL_REASON_FONT_LOAD_ERROR)); + return; + } + } + + final FontInfo[] fonts = result.getFonts(); + if (fonts == null || fonts.length == 0) { + callerThreadHandler.post(() -> callback.onTypefaceRequestFailed( + FontRequestCallback.FAIL_REASON_FONT_NOT_FOUND)); + return; + } + for (final FontInfo font : fonts) { + if (font.getResultCode() != Columns.RESULT_CODE_OK) { + // We proceed if all font entry is ready to use. Otherwise report the first + // error. + final int resultCode = font.getResultCode(); + if (resultCode < 0) { + // Negative values are reserved for internal errors. Fallback to load error. + callerThreadHandler.post(() -> callback.onTypefaceRequestFailed( + FontRequestCallback.FAIL_REASON_FONT_LOAD_ERROR)); + } else { + callerThreadHandler.post(() -> callback.onTypefaceRequestFailed( + resultCode)); + } + return; + } + } + + final Typeface typeface = buildTypeface(context, null /* cancellation signal */, fonts); + if (typeface == null) { + // Something went wrong during reading font files. This happens if the given font + // file is an unsupported font type. + callerThreadHandler.post(() -> callback.onTypefaceRequestFailed( + FontRequestCallback.FAIL_REASON_FONT_LOAD_ERROR)); + return; + } + + callerThreadHandler.post(() -> callback.onTypefaceRetrieved(typeface)); + }); + } + + /** * Fetch fonts given a font request. * * @param context A {@link Context} to be used for fetching fonts. diff --git a/graphics/java/android/graphics/Typeface.java b/graphics/java/android/graphics/Typeface.java index 21533f8ce6c9..c3588dc3c10d 100644 --- a/graphics/java/android/graphics/Typeface.java +++ b/graphics/java/android/graphics/Typeface.java @@ -292,6 +292,7 @@ public class Typeface { * request. May not be null. * @param callback A callback that will be triggered when results are obtained. May not be null. */ + @Deprecated public static void create(@NonNull FontRequest request, @NonNull FontRequestCallback callback) { // Check the cache first // TODO: would the developer want to avoid a cache hit and always ask for the freshest @@ -404,6 +405,7 @@ public class Typeface { /** * Interface used to receive asynchronously fetched typefaces. */ + @Deprecated public interface FontRequestCallback { /** * Constant returned by {@link #onTypefaceRequestFailed(int)} signaling that the given |