Merge "Font provider cleaning ups." into oc-dev

This commit is contained in:
Seigo Nonaka
2017-04-25 21:40:35 +00:00
committed by Android (Google) Code Review
6 changed files with 45 additions and 99 deletions

View File

@@ -350,10 +350,6 @@ package android.provider {
field public static final deprecated java.lang.String TIMESTAMP = "timestamp"; field public static final deprecated java.lang.String TIMESTAMP = "timestamp";
} }
public static final class FontsContract.Columns implements android.provider.BaseColumns {
field public static final java.lang.String STYLE = "font_style";
}
public static final class Settings.Global extends android.provider.Settings.NameValueTable { public static final class Settings.Global extends android.provider.Settings.NameValueTable {
field public static final deprecated java.lang.String CONTACT_METADATA_SYNC = "contact_metadata_sync"; field public static final deprecated java.lang.String CONTACT_METADATA_SYNC = "contact_metadata_sync";
} }

View File

@@ -344,10 +344,6 @@ package android.provider {
field public static final deprecated java.lang.String TIMESTAMP = "timestamp"; field public static final deprecated java.lang.String TIMESTAMP = "timestamp";
} }
public static final class FontsContract.Columns implements android.provider.BaseColumns {
field public static final java.lang.String STYLE = "font_style";
}
public static final class Settings.Global extends android.provider.Settings.NameValueTable { public static final class Settings.Global extends android.provider.Settings.NameValueTable {
field public static final deprecated java.lang.String CONTACT_METADATA_SYNC = "contact_metadata_sync"; field public static final deprecated java.lang.String CONTACT_METADATA_SYNC = "contact_metadata_sync";
} }

View File

@@ -350,10 +350,6 @@ package android.provider {
field public static final deprecated java.lang.String TIMESTAMP = "timestamp"; field public static final deprecated java.lang.String TIMESTAMP = "timestamp";
} }
public static final class FontsContract.Columns implements android.provider.BaseColumns {
field public static final java.lang.String STYLE = "font_style";
}
public static final class Settings.Global extends android.provider.Settings.NameValueTable { public static final class Settings.Global extends android.provider.Settings.NameValueTable {
field public static final deprecated java.lang.String CONTACT_METADATA_SYNC = "contact_metadata_sync"; field public static final deprecated java.lang.String CONTACT_METADATA_SYNC = "contact_metadata_sync";
} }

View File

@@ -51,7 +51,6 @@ import android.database.sqlite.SQLiteDebug;
import android.database.sqlite.SQLiteDebug.DbStats; import android.database.sqlite.SQLiteDebug.DbStats;
import android.graphics.Bitmap; import android.graphics.Bitmap;
import android.graphics.Canvas; import android.graphics.Canvas;
import android.graphics.Typeface;
import android.hardware.display.DisplayManagerGlobal; import android.hardware.display.DisplayManagerGlobal;
import android.net.ConnectivityManager; import android.net.ConnectivityManager;
import android.net.IConnectivityManager; import android.net.IConnectivityManager;
@@ -90,6 +89,7 @@ import android.provider.CalendarContract;
import android.provider.CallLog; import android.provider.CallLog;
import android.provider.ContactsContract; import android.provider.ContactsContract;
import android.provider.Downloads; import android.provider.Downloads;
import android.provider.FontsContract;
import android.provider.Settings; import android.provider.Settings;
import android.security.NetworkSecurityPolicy; import android.security.NetworkSecurityPolicy;
import android.security.net.config.NetworkSecurityConfigProvider; import android.security.net.config.NetworkSecurityConfigProvider;
@@ -5793,7 +5793,7 @@ public final class ActivityThread {
} }
// Preload fonts resources // Preload fonts resources
Typeface.setApplicationContext(appContext); FontsContract.setApplicationContextForResources(appContext);
try { try {
final ApplicationInfo info = final ApplicationInfo info =
getPackageManager().getApplicationInfo( getPackageManager().getApplicationInfo(

View File

@@ -104,14 +104,6 @@ public class FontsContract {
* font. * font.
*/ */
public static final String VARIATION_SETTINGS = "font_variation_settings"; public static final String VARIATION_SETTINGS = "font_variation_settings";
/**
* DO NOT USE THIS COLUMN.
* This column is kept for preventing demo apps.
* TODO: Remove once nobody uses this column.
* @hide
* @removed
*/
public static final String STYLE = "font_style";
/** /**
* Constant used to request data from a font provider. The cursor returned from the query * Constant used to request data from a font provider. The cursor returned from the query
* should have this column populated with the int weight for the resulting font. This value * should have this column populated with the int weight for the resulting font. This value
@@ -159,38 +151,24 @@ public class FontsContract {
public static final int RESULT_CODE_MALFORMED_QUERY = 3; public static final int RESULT_CODE_MALFORMED_QUERY = 3;
} }
/** private static final Object sLock = new Object();
* Constant used to identify the List of {@link ParcelFileDescriptor} item in the Bundle @GuardedBy("sLock")
* returned to the ResultReceiver in getFont. private static Handler sHandler;
* @hide @GuardedBy("sLock")
*/ private static HandlerThread sThread;
public static final String PARCEL_FONT_RESULTS = "font_results"; @GuardedBy("sLock")
// Error codes internal to the system, which can not come from a provider. To keep the number private static Set<String> sInQueueSet;
// space open for new provider codes, these should all be negative numbers.
/** @hide */
public static final int RESULT_CODE_PROVIDER_NOT_FOUND = -1;
/** @hide */
public static final int RESULT_CODE_WRONG_CERTIFICATES = -2;
// Note -3 is used by Typeface to indicate the font failed to load.
private static final int THREAD_RENEWAL_THRESHOLD_MS = 10000; private volatile static Context sContext; // set once in setApplicationContextForResources
private final Context mContext;
private final PackageManager mPackageManager;
private final Object mLock = new Object();
@GuardedBy("mLock")
private Handler mHandler;
@GuardedBy("mLock")
private HandlerThread mThread;
@GuardedBy("mLock")
private Set<String> mInQueueSet;
private static final LruCache<String, Typeface> sTypefaceCache = new LruCache<>(16); private static final LruCache<String, Typeface> sTypefaceCache = new LruCache<>(16);
private FontsContract() {
}
/** @hide */ /** @hide */
public FontsContract(Context context) { public static void setApplicationContextForResources(Context context) {
mContext = context.getApplicationContext(); sContext = context.getApplicationContext();
mPackageManager = mContext.getPackageManager();
} }
/** /**
@@ -323,24 +301,27 @@ public class FontsContract {
} }
} }
private static final int THREAD_RENEWAL_THRESHOLD_MS = 10000;
// We use a background thread to post the content resolving work for all requests on. This // 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. // thread should be quit/stopped after all requests are done.
private final Runnable mReplaceDispatcherThreadRunnable = new Runnable() { // TODO: Factor out to other class. Consider to switch MessageQueue.IdleHandler.
private static final Runnable sReplaceDispatcherThreadRunnable = new Runnable() {
@Override @Override
public void run() { public void run() {
synchronized (mLock) { synchronized (sLock) {
if (mThread != null) { if (sThread != null) {
mThread.quitSafely(); sThread.quitSafely();
mThread = null; sThread = null;
mHandler = null; sHandler = null;
mInQueueSet = null; sInQueueSet = null;
} }
} }
} }
}; };
/** @hide */ /** @hide */
public Typeface getFontOrWarmUpCache(FontRequest request) { public static Typeface getFontOrWarmUpCache(FontRequest request) {
final String id = request.getIdentifier(); final String id = request.getIdentifier();
Typeface cachedTypeface = sTypefaceCache.get(id); Typeface cachedTypeface = sTypefaceCache.get(id);
if (cachedTypeface != null) { if (cachedTypeface != null) {
@@ -350,25 +331,25 @@ public class FontsContract {
// Unfortunately the typeface is not available at this time, but requesting from the font // Unfortunately the typeface is not available at this time, but requesting from the font
// provider takes too much time. For now, request the font data to ensure it is in the cache // provider takes too much time. For now, request the font data to ensure it is in the cache
// next time and return. // next time and return.
synchronized (mLock) { synchronized (sLock) {
if (mHandler == null) { if (sHandler == null) {
mThread = new HandlerThread("fonts", Process.THREAD_PRIORITY_BACKGROUND); sThread = new HandlerThread("fonts", Process.THREAD_PRIORITY_BACKGROUND);
mThread.start(); sThread.start();
mHandler = new Handler(mThread.getLooper()); sHandler = new Handler(sThread.getLooper());
mInQueueSet = new ArraySet<String>(); sInQueueSet = new ArraySet<>();
} }
if (mInQueueSet.contains(id)) { if (sInQueueSet.contains(id)) {
return null; // Already requested. return null; // Already requested.
} }
mInQueueSet.add(id); sInQueueSet.add(id);
mHandler.post(() -> { sHandler.post(() -> {
synchronized (mLock) { synchronized (sLock) {
mInQueueSet.remove(id); sInQueueSet.remove(id);
} }
try { try {
FontFamilyResult result = fetchFonts(mContext, null, request); FontFamilyResult result = fetchFonts(sContext, null, request);
if (result.getStatusCode() == FontFamilyResult.STATUS_OK) { if (result.getStatusCode() == FontFamilyResult.STATUS_OK) {
Typeface typeface = buildTypeface(mContext, null, result.getFonts()); Typeface typeface = buildTypeface(sContext, null, result.getFonts());
if (typeface != null) { if (typeface != null) {
sTypefaceCache.put(id, typeface); sTypefaceCache.put(id, typeface);
} }
@@ -377,8 +358,8 @@ public class FontsContract {
// Ignore. // Ignore.
} }
}); });
mHandler.removeCallbacks(mReplaceDispatcherThreadRunnable); sHandler.removeCallbacks(sReplaceDispatcherThreadRunnable);
mHandler.postDelayed(mReplaceDispatcherThreadRunnable, THREAD_RENEWAL_THRESHOLD_MS); sHandler.postDelayed(sReplaceDispatcherThreadRunnable, THREAD_RENEWAL_THRESHOLD_MS);
} }
return null; return null;
} }
@@ -391,12 +372,12 @@ public class FontsContract {
* Constant returned by {@link #onTypefaceRequestFailed(int)} signaling that the given * Constant returned by {@link #onTypefaceRequestFailed(int)} signaling that the given
* provider was not found on the device. * provider was not found on the device.
*/ */
public static final int FAIL_REASON_PROVIDER_NOT_FOUND = RESULT_CODE_PROVIDER_NOT_FOUND; public static final int FAIL_REASON_PROVIDER_NOT_FOUND = -1;
/** /**
* Constant returned by {@link #onTypefaceRequestFailed(int)} signaling that the given * Constant returned by {@link #onTypefaceRequestFailed(int)} signaling that the given
* provider must be authenticated and the given certificates do not match its signature. * 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; public static final int FAIL_REASON_WRONG_CERTIFICATES = -2;
/** /**
* Constant returned by {@link #onTypefaceRequestFailed(int)} signaling that the font * Constant returned by {@link #onTypefaceRequestFailed(int)} signaling that the font
* returned by the provider was not loaded properly. * returned by the provider was not loaded properly.
@@ -767,7 +748,7 @@ public class FontsContract {
.build(); .build();
try (Cursor cursor = context.getContentResolver().query(uri, new String[] { Columns._ID, try (Cursor cursor = context.getContentResolver().query(uri, new String[] { Columns._ID,
Columns.FILE_ID, Columns.TTC_INDEX, Columns.VARIATION_SETTINGS, Columns.FILE_ID, Columns.TTC_INDEX, Columns.VARIATION_SETTINGS,
Columns.STYLE, Columns.WEIGHT, Columns.ITALIC, Columns.RESULT_CODE }, Columns.WEIGHT, Columns.ITALIC, Columns.RESULT_CODE },
"query = ?", new String[] { request.getQuery() }, null, cancellationSignal);) { "query = ?", new String[] { request.getQuery() }, null, cancellationSignal);) {
// TODO: Should we restrict the amount of fonts that can be returned? // 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. // TODO: Write documentation explaining that all results should be from the same family.
@@ -780,7 +761,6 @@ public class FontsContract {
final int vsColumnIndex = cursor.getColumnIndex(Columns.VARIATION_SETTINGS); final int vsColumnIndex = cursor.getColumnIndex(Columns.VARIATION_SETTINGS);
final int weightColumnIndex = cursor.getColumnIndex(Columns.WEIGHT); final int weightColumnIndex = cursor.getColumnIndex(Columns.WEIGHT);
final int italicColumnIndex = cursor.getColumnIndex(Columns.ITALIC); final int italicColumnIndex = cursor.getColumnIndex(Columns.ITALIC);
final int styleColumnIndex = cursor.getColumnIndex(Columns.STYLE);
while (cursor.moveToNext()) { while (cursor.moveToNext()) {
int resultCode = resultCodeColumnIndex != -1 int resultCode = resultCodeColumnIndex != -1
? cursor.getInt(resultCodeColumnIndex) : Columns.RESULT_CODE_OK; ? cursor.getInt(resultCodeColumnIndex) : Columns.RESULT_CODE_OK;
@@ -797,17 +777,11 @@ public class FontsContract {
long id = cursor.getLong(fileIdColumnIndex); long id = cursor.getLong(fileIdColumnIndex);
fileUri = ContentUris.withAppendedId(fileBaseUri, id); fileUri = ContentUris.withAppendedId(fileBaseUri, id);
} }
// TODO: Stop using STYLE column and enforce WEIGHT/ITALIC column.
int weight; int weight;
boolean italic; boolean italic;
if (weightColumnIndex != -1 && italicColumnIndex != -1) { if (weightColumnIndex != -1 && italicColumnIndex != -1) {
weight = cursor.getInt(weightColumnIndex); weight = cursor.getInt(weightColumnIndex);
italic = cursor.getInt(italicColumnIndex) == 1; italic = cursor.getInt(italicColumnIndex) == 1;
} else if (styleColumnIndex != -1) {
final int style = cursor.getInt(styleColumnIndex);
weight = (style & Typeface.BOLD) != 0 ?
Typeface.Builder.BOLD_WEIGHT : Typeface.Builder.NORMAL_WEIGHT;
italic = (style & Typeface.ITALIC) != 0;
} else { } else {
weight = Typeface.Builder.NORMAL_WEIGHT; weight = Typeface.Builder.NORMAL_WEIGHT;
italic = false; italic = false;

View File

@@ -27,7 +27,6 @@ import android.annotation.IntDef;
import android.annotation.IntRange; import android.annotation.IntRange;
import android.annotation.NonNull; import android.annotation.NonNull;
import android.annotation.Nullable; import android.annotation.Nullable;
import android.content.Context;
import android.content.res.AssetManager; import android.content.res.AssetManager;
import android.graphics.FontListParser; import android.graphics.FontListParser;
import android.graphics.fonts.FontRequest; import android.graphics.fonts.FontRequest;
@@ -99,8 +98,6 @@ public class Typeface {
static Typeface[] sDefaults; static Typeface[] sDefaults;
private static final LongSparseArray<SparseArray<Typeface>> sTypefaceCache = private static final LongSparseArray<SparseArray<Typeface>> sTypefaceCache =
new LongSparseArray<>(3); new LongSparseArray<>(3);
@GuardedBy("sLock")
private static FontsContract sFontsContract;
/** /**
* Cache for Typeface objects dynamically loaded from assets. Currently max size is 16. * Cache for Typeface objects dynamically loaded from assets. Currently max size is 16.
@@ -221,7 +218,7 @@ public class Typeface {
// default font instead (nothing we can do now). // default font instead (nothing we can do now).
FontRequest request = new FontRequest(providerEntry.getAuthority(), FontRequest request = new FontRequest(providerEntry.getAuthority(),
providerEntry.getPackage(), providerEntry.getQuery(), certs); providerEntry.getPackage(), providerEntry.getQuery(), certs);
Typeface typeface = sFontsContract.getFontOrWarmUpCache(request); Typeface typeface = FontsContract.getFontOrWarmUpCache(request);
return typeface == null ? DEFAULT : typeface; return typeface == null ? DEFAULT : typeface;
} }
@@ -276,19 +273,6 @@ public class Typeface {
return null; return null;
} }
/**
* Set the application context so we can generate font requests from the provider. This should
* be called from ActivityThread when the application binds, as we preload fonts.
* @hide
*/
public static void setApplicationContext(Context context) {
synchronized (sLock) {
if (sFontsContract == null) {
sFontsContract = new FontsContract(context);
}
}
}
/** /**
* A builder class for creating new Typeface instance. * A builder class for creating new Typeface instance.
* *