diff options
-rw-r--r-- | api/current.txt | 32 | ||||
-rw-r--r-- | api/system-current.txt | 32 | ||||
-rw-r--r-- | api/test-current.txt | 32 | ||||
-rw-r--r-- | core/java/android/provider/FontsContract.java | 197 | ||||
-rw-r--r-- | graphics/java/android/graphics/Typeface.java | 155 | ||||
-rw-r--r-- | graphics/java/android/graphics/fonts/FontRequest.java | 93 | ||||
-rw-r--r-- | graphics/java/android/graphics/fonts/FontResult.java | 108 | ||||
-rw-r--r-- | graphics/java/android/graphics/fonts/FontSpec.aidl | 18 |
8 files changed, 665 insertions, 2 deletions
diff --git a/api/current.txt b/api/current.txt index 93f9973126a5..b964a60beead 100644 --- a/api/current.txt +++ b/api/current.txt @@ -13227,6 +13227,7 @@ package android.graphics { } public class Typeface { + method public static 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); @@ -13247,6 +13248,14 @@ package android.graphics { field public static final android.graphics.Typeface SERIF; } + public static abstract 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 = 1; // 0x1 + field public static final int FAIL_REASON_FONT_NOT_FOUND = 2; // 0x2 + field public static final int FAIL_REASON_PROVIDER_NOT_FOUND = 0; // 0x0 + } + public class Xfermode { ctor public Xfermode(); } @@ -13801,6 +13810,19 @@ package android.graphics.drawable.shapes { } +package android.graphics.fonts { + + public final class FontRequest implements android.os.Parcelable { + ctor public FontRequest(java.lang.String, java.lang.String); + method public int describeContents(); + method public java.lang.String getProviderAuthority(); + method public java.lang.String getQuery(); + method public void writeToParcel(android.os.Parcel, int); + field public static final android.os.Parcelable.Creator<android.graphics.fonts.FontRequest> CREATOR; + } + +} + package android.graphics.pdf { public class PdfDocument { @@ -33046,6 +33068,16 @@ package android.provider { method public final int update(android.net.Uri, android.content.ContentValues, java.lang.String, java.lang.String[]); } + public class FontsContract { + } + + public static final class FontsContract.Columns implements android.provider.BaseColumns { + ctor public FontsContract.Columns(); + field public static final java.lang.String STYLE = "font_style"; + field public static final java.lang.String TTC_INDEX = "font_ttc_index"; + field public static final java.lang.String VARIATION_SETTINGS = "font_variation_settings"; + } + 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 af63cbb693a3..d7c8f5aee4e4 100644 --- a/api/system-current.txt +++ b/api/system-current.txt @@ -13774,6 +13774,7 @@ package android.graphics { } public class Typeface { + method public static 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); @@ -13794,6 +13795,14 @@ package android.graphics { field public static final android.graphics.Typeface SERIF; } + public static abstract 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 = 1; // 0x1 + field public static final int FAIL_REASON_FONT_NOT_FOUND = 2; // 0x2 + field public static final int FAIL_REASON_PROVIDER_NOT_FOUND = 0; // 0x0 + } + public class Xfermode { ctor public Xfermode(); } @@ -14348,6 +14357,19 @@ package android.graphics.drawable.shapes { } +package android.graphics.fonts { + + public final class FontRequest implements android.os.Parcelable { + ctor public FontRequest(java.lang.String, java.lang.String); + method public int describeContents(); + method public java.lang.String getProviderAuthority(); + method public java.lang.String getQuery(); + method public void writeToParcel(android.os.Parcel, int); + field public static final android.os.Parcelable.Creator<android.graphics.fonts.FontRequest> CREATOR; + } + +} + package android.graphics.pdf { public class PdfDocument { @@ -35914,6 +35936,16 @@ package android.provider { method public final int update(android.net.Uri, android.content.ContentValues, java.lang.String, java.lang.String[]); } + public class FontsContract { + } + + public static final class FontsContract.Columns implements android.provider.BaseColumns { + ctor public FontsContract.Columns(); + field public static final java.lang.String STYLE = "font_style"; + field public static final java.lang.String TTC_INDEX = "font_ttc_index"; + field public static final java.lang.String VARIATION_SETTINGS = "font_variation_settings"; + } + 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 ab94c0bcad25..c2ae08194263 100644 --- a/api/test-current.txt +++ b/api/test-current.txt @@ -13259,6 +13259,7 @@ package android.graphics { } public class Typeface { + method public static 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); @@ -13279,6 +13280,14 @@ package android.graphics { field public static final android.graphics.Typeface SERIF; } + public static abstract 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 = 1; // 0x1 + field public static final int FAIL_REASON_FONT_NOT_FOUND = 2; // 0x2 + field public static final int FAIL_REASON_PROVIDER_NOT_FOUND = 0; // 0x0 + } + public class Xfermode { ctor public Xfermode(); } @@ -13833,6 +13842,19 @@ package android.graphics.drawable.shapes { } +package android.graphics.fonts { + + public final class FontRequest implements android.os.Parcelable { + ctor public FontRequest(java.lang.String, java.lang.String); + method public int describeContents(); + method public java.lang.String getProviderAuthority(); + method public java.lang.String getQuery(); + method public void writeToParcel(android.os.Parcel, int); + field public static final android.os.Parcelable.Creator<android.graphics.fonts.FontRequest> CREATOR; + } + +} + package android.graphics.pdf { public class PdfDocument { @@ -33162,6 +33184,16 @@ package android.provider { method public final int update(android.net.Uri, android.content.ContentValues, java.lang.String, java.lang.String[]); } + public class FontsContract { + } + + public static final class FontsContract.Columns implements android.provider.BaseColumns { + ctor public FontsContract.Columns(); + field public static final java.lang.String STYLE = "font_style"; + field public static final java.lang.String TTC_INDEX = "font_ttc_index"; + field public static final java.lang.String VARIATION_SETTINGS = "font_variation_settings"; + } + 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 new file mode 100644 index 000000000000..90e710f12c08 --- /dev/null +++ b/core/java/android/provider/FontsContract.java @@ -0,0 +1,197 @@ +/* + * 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.provider; + +import android.app.ActivityThread; +import android.content.ContentResolver; +import android.content.ContentUris; +import android.content.Context; +import android.content.pm.PackageManager; +import android.content.pm.ProviderInfo; +import android.database.Cursor; +import android.graphics.fonts.FontRequest; +import android.graphics.fonts.FontResult; +import android.net.Uri; +import android.os.Bundle; +import android.os.Handler; +import android.os.HandlerThread; +import android.os.ParcelFileDescriptor; +import android.os.Process; +import android.os.ResultReceiver; +import android.util.Log; + +import com.android.internal.annotations.GuardedBy; + +import java.io.FileNotFoundException; +import java.util.ArrayList; + +/** + * Utility class to deal with Font ContentProviders. + */ +public class FontsContract { + private static final String TAG = "FontsContract"; + + /** + * Defines the constants used in a response from a Font Provider. The cursor returned from the + * query should have the ID column populated with the content uri ID for the resulting font. + * This should point to a real file or shared memory, as the client will mmap the given file + * descriptor. Pipes, sockets and other non-mmap-able file descriptors will fail to load in the + * client application. + */ + public static final class Columns implements BaseColumns { + /** + * Constant used to request data from a font provider. The cursor returned from the query + * should have this column populated with an int for the ttc index for the resulting font. + */ + public static final String TTC_INDEX = "font_ttc_index"; + /** + * Constant used to request data from a font provider. The cursor returned from the query + * may populate this column with the font variation settings String information for the + * font. + */ + public static final String VARIATION_SETTINGS = "font_variation_settings"; + /** + * Constant used to request data from a font provider. The cursor returned from the query + * should have this column populated with the int style for the resulting font. This should + * be one of {@link android.graphics.Typeface#NORMAL}, + * {@link android.graphics.Typeface#BOLD}, {@link android.graphics.Typeface#ITALIC} or + * {@link android.graphics.Typeface#BOLD_ITALIC} + */ + public static final String STYLE = "font_style"; + } + + /** + * Constant used to identify the List of {@link ParcelFileDescriptor} item in the Bundle + * returned to the ResultReceiver in getFont. + * @hide + */ + public static final String PARCEL_FONT_RESULTS = "font_results"; + + /** @hide */ + public static final int RESULT_CODE_OK = 0; + /** @hide */ + public static final int RESULT_CODE_FONT_NOT_FOUND = 1; + /** @hide */ + public static final int RESULT_CODE_PROVIDER_NOT_FOUND = 2; + + private static final int THREAD_RENEWAL_THRESHOLD_MS = 10000; + + private final Context mContext; + private final PackageManager mPackageManager; + private final Object mLock = new Object(); + @GuardedBy("mLock") + private Handler mHandler; + @GuardedBy("mLock") + private HandlerThread mThread; + + /** @hide */ + public FontsContract() { + // TODO: investigate if the system context is the best option here. ApplicationContext or + // the one passed by developer? + // TODO: Looks like ActivityThread.currentActivityThread() can return null. Check when it + // returns null and check if we need to handle null case. + mContext = ActivityThread.currentActivityThread().getSystemContext(); + mPackageManager = mContext.getPackageManager(); + } + + // We use a background thread to post the content resolving work for all requests on. This + // thread should be quit/stopped after all requests are done. + private final Runnable mReplaceDispatcherThreadRunnable = new Runnable() { + @Override + public void run() { + synchronized (mLock) { + if (mThread != null) { + mThread.quitSafely(); + mThread = null; + mHandler = null; + } + } + } + }; + + /** + * @hide + */ + public void getFont(FontRequest request, ResultReceiver receiver) { + synchronized (mLock) { + if (mHandler == null) { + mThread = new HandlerThread("fonts", Process.THREAD_PRIORITY_BACKGROUND); + mThread.start(); + mHandler = new Handler(mThread.getLooper()); + } + mHandler.post(() -> { + String providerAuthority = request.getProviderAuthority(); + // TODO: Implement cert checking for non-system apps + ProviderInfo providerInfo = mPackageManager.resolveContentProvider( + providerAuthority, PackageManager.MATCH_SYSTEM_ONLY); + if (providerInfo == null) { + receiver.send(RESULT_CODE_PROVIDER_NOT_FOUND, null); + return; + } + Bundle result = getFontFromProvider(request, receiver, providerInfo); + if (result == null) { + receiver.send(RESULT_CODE_FONT_NOT_FOUND, null); + return; + } + receiver.send(RESULT_CODE_OK, result); + }); + mHandler.removeCallbacks(mReplaceDispatcherThreadRunnable); + mHandler.postDelayed(mReplaceDispatcherThreadRunnable, THREAD_RENEWAL_THRESHOLD_MS); + } + } + + private Bundle getFontFromProvider(FontRequest request, ResultReceiver receiver, + ProviderInfo providerInfo) { + ArrayList<FontResult> result = null; + Uri uri = new Uri.Builder().scheme(ContentResolver.SCHEME_CONTENT) + .authority(providerInfo.authority) + .build(); + try (Cursor cursor = mContext.getContentResolver().query(uri, new String[] { Columns._ID, + Columns.TTC_INDEX, Columns.VARIATION_SETTINGS, Columns.STYLE }, + "query = ?", new String[] { request.getQuery() }, null);) { + // TODO: Should we restrict the amount of fonts that can be returned? + // TODO: Write documentation explaining that all results should be from the same family. + if (cursor != null && cursor.getCount() > 0) { + result = new ArrayList<>(); + final int idColumnIndex = cursor.getColumnIndex(Columns._ID); + final int ttcIndexColumnIndex = cursor.getColumnIndex(Columns.TTC_INDEX); + final int vsColumnIndex = cursor.getColumnIndex(Columns.VARIATION_SETTINGS); + final int styleColumnIndex = cursor.getColumnIndex(Columns.STYLE); + while (cursor.moveToNext()) { + long id = cursor.getLong(idColumnIndex); + Uri fileUri = ContentUris.withAppendedId(uri, id); + try { + ParcelFileDescriptor pfd = + mContext.getContentResolver().openFileDescriptor(fileUri, "r"); + final int ttcIndex = cursor.getInt(ttcIndexColumnIndex); + final String variationSettings = cursor.getString(vsColumnIndex); + final int style = cursor.getInt(styleColumnIndex); + result.add(new FontResult(pfd, ttcIndex, variationSettings, style)); + } catch (FileNotFoundException e) { + Log.e(TAG, "FileNotFoundException raised when interacting with content " + + "provider " + providerInfo.authority, e); + } + } + } + } + if (result != null && !result.isEmpty()) { + Bundle bundle = new Bundle(); + bundle.putParcelableArrayList(PARCEL_FONT_RESULTS, result); + return bundle; + } + return null; + } +} diff --git a/graphics/java/android/graphics/Typeface.java b/graphics/java/android/graphics/Typeface.java index 0a349e91ad1e..4e863e37f363 100644 --- a/graphics/java/android/graphics/Typeface.java +++ b/graphics/java/android/graphics/Typeface.java @@ -16,20 +16,34 @@ package android.graphics; +import android.annotation.IntDef; import android.annotation.NonNull; import android.content.res.AssetManager; +import android.graphics.fonts.FontRequest; +import android.graphics.fonts.FontResult; +import android.os.Bundle; +import android.os.Handler; +import android.os.ParcelFileDescriptor; +import android.os.ResultReceiver; +import android.provider.FontsContract; import android.text.FontConfig; import android.util.Log; import android.util.LongSparseArray; import android.util.LruCache; import android.util.SparseArray; +import com.android.internal.annotations.GuardedBy; + +import libcore.io.IoUtils; + import org.xmlpull.v1.XmlPullParserException; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; import java.nio.ByteBuffer; import java.nio.channels.FileChannel; import java.util.ArrayList; @@ -64,7 +78,11 @@ public class Typeface { static Typeface[] sDefaults; private static final LongSparseArray<SparseArray<Typeface>> sTypefaceCache = - new LongSparseArray<SparseArray<Typeface>>(3); + new LongSparseArray<>(3); + @GuardedBy("sLock") + private static FontsContract sFontsContract; + @GuardedBy("sLock") + private static Handler mHandler; /** * Cache for Typeface objects dynamically loaded from assets. Currently max size is 16. @@ -74,6 +92,7 @@ public class Typeface { static Typeface sDefaultTypeface; static Map<String, Typeface> sSystemFontMap; static FontFamily[] sFallbackFonts; + private static final Object sLock = new Object(); static final String FONTS_CONFIG = "fonts.xml"; @@ -124,7 +143,7 @@ public class Typeface { FontFamily fontFamily = new FontFamily(); if (fontFamily.addFontFromAssetManager(mgr, path, cookie, false /* isAsset */)) { - FontFamily[] families = { fontFamily }; + FontFamily[] families = {fontFamily}; typeface = createFromFamiliesWithDefault(families); sDynamicTypefaceCache.put(key, typeface); return typeface; @@ -135,6 +154,138 @@ public class Typeface { } /** + * 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 main thread. + * @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. + */ + public static void create(@NonNull FontRequest request, @NonNull FontRequestCallback callback) { + synchronized (sLock) { + if (sFontsContract == null) { + sFontsContract = new FontsContract(); + mHandler = new Handler(); + } + final ResultReceiver receiver = new ResultReceiver(null) { + @Override + public void onReceiveResult(int resultCode, Bundle resultData) { + mHandler.post(new Runnable() { + @Override + public void run() { + receiveResult(request, callback, resultCode, resultData); + } + }); + } + }; + sFontsContract.getFont(request, receiver); + } + } + + private static void receiveResult(FontRequest request, FontRequestCallback callback, + int resultCode, Bundle resultData) { + if (resultCode == FontsContract.RESULT_CODE_PROVIDER_NOT_FOUND) { + callback.onTypefaceRequestFailed( + FontRequestCallback.FAIL_REASON_PROVIDER_NOT_FOUND); + return; + } + if (resultCode == FontsContract.RESULT_CODE_FONT_NOT_FOUND + || resultData == null) { + callback.onTypefaceRequestFailed( + FontRequestCallback.FAIL_REASON_FONT_NOT_FOUND); + return; + } + List<FontResult> resultList = + resultData.getParcelableArrayList(FontsContract.PARCEL_FONT_RESULTS); + if (resultList == null || resultList.isEmpty()) { + callback.onTypefaceRequestFailed( + FontRequestCallback.FAIL_REASON_FONT_NOT_FOUND); + return; + } + FontFamily fontFamily = new FontFamily(); + for (int i = 0; i < resultList.size(); ++i) { + FontResult result = resultList.get(i); + ParcelFileDescriptor fd = result.getFileDescriptor(); + if (fd == null) { + callback.onTypefaceRequestFailed( + FontRequestCallback.FAIL_REASON_FONT_LOAD_ERROR); + return; + } + try (FileInputStream is = new FileInputStream(fd.getFileDescriptor())) { + FileChannel fileChannel = is.getChannel(); + long fontSize = fileChannel.size(); + ByteBuffer fontBuffer = fileChannel.map( + FileChannel.MapMode.READ_ONLY, 0, fontSize); + int style = result.getStyle(); + int weight = (style & BOLD) != 0 ? 700 : 400; + // TODO: this method should be + // create(fd, ttcIndex, fontVariationSettings, style). + if (!fontFamily.addFontWeightStyle(fontBuffer, result.getTtcIndex(), + null, weight, (style & ITALIC) != 0)) { + Log.e(TAG, "Error creating font " + request.getQuery()); + callback.onTypefaceRequestFailed( + FontRequestCallback.FAIL_REASON_FONT_LOAD_ERROR); + return; + } + } catch (IOException e) { + Log.e(TAG, "Error reading font " + request.getQuery(), e); + callback.onTypefaceRequestFailed( + FontRequestCallback.FAIL_REASON_FONT_LOAD_ERROR); + return; + } finally { + IoUtils.closeQuietly(fd); + } + } + callback.onTypefaceRetrieved(Typeface.createFromFamiliesWithDefault( + new FontFamily[] {fontFamily})); + } + + /** + * Interface used to receive asynchronously fetched typefaces. + */ + public interface FontRequestCallback { + /** + * Constant returned by {@link #onTypefaceRequestFailed(int)} signaling that the given + * provider was not found on the device. + */ + int FAIL_REASON_PROVIDER_NOT_FOUND = 0; + /** + * Constant returned by {@link #onTypefaceRequestFailed(int)} signaling that the font + * returned by the provider was not loaded properly. + */ + int FAIL_REASON_FONT_LOAD_ERROR = 1; + /** + * Constant returned by {@link #onTypefaceRequestFailed(int)} signaling that the given + * provider did not return any results for the given query. + */ + int FAIL_REASON_FONT_NOT_FOUND = 2; + + /** @hide */ + @IntDef({FAIL_REASON_PROVIDER_NOT_FOUND, FAIL_REASON_FONT_LOAD_ERROR, + FAIL_REASON_FONT_NOT_FOUND}) + @Retention(RetentionPolicy.SOURCE) + @interface FontRequestFailReason {} + + /** + * 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. + */ + 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} or + * {@link #FAIL_REASON_FONT_LOAD_ERROR}. + */ + void onTypefaceRequestFailed(@FontRequestFailReason int reason); + } + + /** * Create a typeface object given a family name, and option style information. * If null is passed for the name, then the "default" font will be chosen. * The resulting typeface object can be queried (getStyle()) to discover what diff --git a/graphics/java/android/graphics/fonts/FontRequest.java b/graphics/java/android/graphics/fonts/FontRequest.java new file mode 100644 index 000000000000..e50df6faa38e --- /dev/null +++ b/graphics/java/android/graphics/fonts/FontRequest.java @@ -0,0 +1,93 @@ +/* + * 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.graphics.fonts; + +import android.annotation.NonNull; +import android.os.Parcel; +import android.os.Parcelable; + +import com.android.internal.util.Preconditions; + +/** + * Information about a font request that may be sent to a Font Provider. + */ +public final class FontRequest implements Parcelable { + private final String mProviderAuthority; + private final String mQuery; + + /** + * @param providerAuthority The authority of the Font Provider to be used for the request. + * @param query The query to be sent over to the provider. Refer to your font provider's + * documentation on the format of this string. + */ + public FontRequest(@NonNull String providerAuthority, @NonNull String query) { + mProviderAuthority = Preconditions.checkNotNull(providerAuthority); + mQuery = Preconditions.checkNotNull(query); + } + + /** + * Returns the selected font provider's authority. This tells the system what font provider + * it should request the font from. + */ + public String getProviderAuthority() { + return mProviderAuthority; + } + + /** + * Returns the query string. Refer to your font provider's documentation on the format of this + * string. + */ + public String getQuery() { + return mQuery; + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeString(mProviderAuthority); + dest.writeString(mQuery); + } + + private FontRequest(Parcel in) { + mProviderAuthority = in.readString(); + mQuery = in.readString(); + } + + public static final Parcelable.Creator<FontRequest> CREATOR = + new Parcelable.Creator<FontRequest>() { + @Override + public FontRequest createFromParcel(Parcel in) { + return new FontRequest(in); + } + + @Override + public FontRequest[] newArray(int size) { + return new FontRequest[size]; + } + }; + + @Override + public String toString() { + return "FontRequest {" + + "mProviderAuthority: " + mProviderAuthority + + ", mQuery: " + mQuery + + "}"; + } +} diff --git a/graphics/java/android/graphics/fonts/FontResult.java b/graphics/java/android/graphics/fonts/FontResult.java new file mode 100644 index 000000000000..3ef99fdd62b7 --- /dev/null +++ b/graphics/java/android/graphics/fonts/FontResult.java @@ -0,0 +1,108 @@ +/* + * 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.graphics.fonts; + +import android.annotation.NonNull; +import android.annotation.Nullable; +import android.graphics.Paint; +import android.os.Parcel; +import android.os.ParcelFileDescriptor; +import android.os.Parcelable; + +import com.android.internal.util.Preconditions; + +import java.io.FileDescriptor; +import java.io.IOException; + +/** + * Results returned from a Font Provider to the system. + * @hide + */ +public final class FontResult implements Parcelable { + private final ParcelFileDescriptor mFileDescriptor; + private final int mTtcIndex; + private final String mFontVariationSettings; + private final int mStyle; + + /** + * Creates a FontResult with all the information needed about a provided font. + * @param fileDescriptor A ParcelFileDescriptor pointing to the font file. This shoult point to + * a real file or shared memory, as the client will mmap the given file + * descriptor. Pipes, sockets and other non-mmap-able file descriptors + * will fail to load in the client application. + * @param ttcIndex If providing a TTC_INDEX file, the index to point to. Otherwise, 0. + * @param fontVariationSettings If providing a variation font, the settings for it. May be null. + * @param style One of {@link android.graphics.Typeface#NORMAL}, + * {@link android.graphics.Typeface#BOLD}, {@link android.graphics.Typeface#ITALIC} + * or {@link android.graphics.Typeface#BOLD_ITALIC} + */ + public FontResult(@NonNull ParcelFileDescriptor fileDescriptor, int ttcIndex, + @Nullable String fontVariationSettings, int style) { + mFileDescriptor = Preconditions.checkNotNull(fileDescriptor); + mTtcIndex = ttcIndex; + mFontVariationSettings = fontVariationSettings; + mStyle = style; + } + + public ParcelFileDescriptor getFileDescriptor() { + return mFileDescriptor; + } + + public int getTtcIndex() { + return mTtcIndex; + } + + public String getFontVariationSettings() { + return mFontVariationSettings; + } + + public int getStyle() { + return mStyle; + } + + @Override + public int describeContents() { + return 0; + } + + @Override + public void writeToParcel(Parcel dest, int flags) { + dest.writeParcelable(mFileDescriptor, flags); + dest.writeInt(mTtcIndex); + dest.writeString(mFontVariationSettings); + dest.writeInt(mStyle); + } + + private FontResult(Parcel in) { + mFileDescriptor = in.readParcelable(null); + mTtcIndex = in.readInt(); + mFontVariationSettings = in.readString(); + mStyle = in.readInt(); + } + + public static final Parcelable.Creator<FontResult> CREATOR = + new Parcelable.Creator<FontResult>() { + @Override + public FontResult createFromParcel(Parcel in) { + return new FontResult(in); + } + + @Override + public FontResult[] newArray(int size) { + return new FontResult[size]; + } + }; +} diff --git a/graphics/java/android/graphics/fonts/FontSpec.aidl b/graphics/java/android/graphics/fonts/FontSpec.aidl new file mode 100644 index 000000000000..dddea2560d3d --- /dev/null +++ b/graphics/java/android/graphics/fonts/FontSpec.aidl @@ -0,0 +1,18 @@ +/* Copyright 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.graphics.fonts; + +parcelable FontSpec;
\ No newline at end of file |