diff --git a/core/api/current.txt b/core/api/current.txt index 3dd1f598f94f9..b49e7247708c1 100644 --- a/core/api/current.txt +++ b/core/api/current.txt @@ -657,6 +657,7 @@ package android { field @Deprecated public static final int fontProviderCerts = 16844125; // 0x101055d field @Deprecated public static final int fontProviderPackage = 16844119; // 0x1010557 field @Deprecated public static final int fontProviderQuery = 16844113; // 0x1010551 + field public static final int fontProviderSystemFontFamily = 16844322; // 0x1010622 field public static final int fontStyle = 16844095; // 0x101053f field public static final int fontVariationSettings = 16844144; // 0x1010570 field public static final int fontWeight = 16844083; // 0x1010533 diff --git a/core/java/android/content/res/FontResourcesParser.java b/core/java/android/content/res/FontResourcesParser.java index 14eb11ab88636..ecd240d9e4dcf 100644 --- a/core/java/android/content/res/FontResourcesParser.java +++ b/core/java/android/content/res/FontResourcesParser.java @@ -47,14 +47,17 @@ public class FontResourcesParser { private final @NonNull String mProviderAuthority; private final @NonNull String mProviderPackage; private final @NonNull String mQuery; + private final @Nullable String mSystemFontFamilyName; private final @Nullable List> mCerts; public ProviderResourceEntry(@NonNull String authority, @NonNull String pkg, - @NonNull String query, @Nullable List> certs) { + @NonNull String query, @Nullable List> certs, + @Nullable String systemFontFamilyName) { mProviderAuthority = authority; mProviderPackage = pkg; mQuery = query; mCerts = certs; + mSystemFontFamilyName = systemFontFamilyName; } public @NonNull String getAuthority() { @@ -69,6 +72,10 @@ public class FontResourcesParser { return mQuery; } + public @NonNull String getSystemFontFamilyName() { + return mSystemFontFamilyName; + } + public @Nullable List> getCerts() { return mCerts; } @@ -166,6 +173,8 @@ public class FontResourcesParser { String providerPackage = array.getString(R.styleable.FontFamily_fontProviderPackage); String query = array.getString(R.styleable.FontFamily_fontProviderQuery); int certsId = array.getResourceId(R.styleable.FontFamily_fontProviderCerts, 0); + String systemFontFamilyName = array.getString( + R.styleable.FontFamily_fontProviderSystemFontFamily); array.recycle(); if (authority != null && providerPackage != null && query != null) { while (parser.next() != XmlPullParser.END_TAG) { @@ -191,7 +200,13 @@ public class FontResourcesParser { } } } - return new ProviderResourceEntry(authority, providerPackage, query, certs); + return new ProviderResourceEntry( + authority, + providerPackage, + query, + certs, + systemFontFamilyName + ); } List fonts = new ArrayList<>(); while (parser.next() != XmlPullParser.END_TAG) { diff --git a/core/res/res/values/attrs.xml b/core/res/res/values/attrs.xml index 415a0a2ed5958..14f1e0e20ef68 100644 --- a/core/res/res/values/attrs.xml +++ b/core/res/res/values/attrs.xml @@ -9276,6 +9276,12 @@ {@deprecated Use app:fontProviderCerts with Jetpack Core library instead.} --> + + diff --git a/core/res/res/values/public.xml b/core/res/res/values/public.xml index ddf3c5f09e9e3..9c1c51cdd48e9 100644 --- a/core/res/res/values/public.xml +++ b/core/res/res/values/public.xml @@ -3058,6 +3058,7 @@ + diff --git a/core/tests/coretests/res/font/samplexmldownloadedfont.xml b/core/tests/coretests/res/font/samplexmldownloadedfont.xml index f1bdc473b9d26..9c32ffb0f4c97 100644 --- a/core/tests/coretests/res/font/samplexmldownloadedfont.xml +++ b/core/tests/coretests/res/font/samplexmldownloadedfont.xml @@ -2,5 +2,6 @@ + android:fontProviderQuery="MyRequestedFont" + android:fontProviderSystemFontFamily="my-request-font"> \ No newline at end of file diff --git a/core/tests/coretests/src/android/content/res/FontResourcesParserTest.java b/core/tests/coretests/src/android/content/res/FontResourcesParserTest.java index 7ab9d7f4ffe1e..57f01e9884402 100644 --- a/core/tests/coretests/src/android/content/res/FontResourcesParserTest.java +++ b/core/tests/coretests/src/android/content/res/FontResourcesParserTest.java @@ -105,6 +105,7 @@ public class FontResourcesParserTest { assertEquals("com.example.test.fontprovider.authority", providerEntry.getAuthority()); assertEquals("com.example.test.fontprovider.package", providerEntry.getPackage()); assertEquals("MyRequestedFont", providerEntry.getQuery()); + assertEquals("my-request-font", providerEntry.getSystemFontFamilyName()); } @Test diff --git a/graphics/java/android/graphics/Typeface.java b/graphics/java/android/graphics/Typeface.java index a0568bf3bf5c0..005a72661091e 100644 --- a/graphics/java/android/graphics/Typeface.java +++ b/graphics/java/android/graphics/Typeface.java @@ -70,6 +70,7 @@ import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; +import java.util.Objects; /** * The Typeface class specifies the typeface and intrinsic style of a font. @@ -248,6 +249,21 @@ public class Typeface { return (mStyle & ITALIC) != 0; } + /** + * Returns true if the system has the font family with the name [familyName]. For example + * querying with "sans-serif" would check if the "sans-serif" family is defined in the system + * and return true if does. + * + * @param familyName The name of the font family, cannot be null. If null, exception will be + * thrown. + */ + private static boolean hasFontFamily(@NonNull String familyName) { + Objects.requireNonNull(familyName, "familyName cannot be null"); + synchronized (SYSTEM_FONT_MAP_LOCK) { + return sSystemFontMap.containsKey(familyName); + } + } + /** * @hide * Used by Resources to load a font resource of type xml. @@ -257,6 +273,11 @@ public class Typeface { FamilyResourceEntry entry, AssetManager mgr, String path) { if (entry instanceof ProviderResourceEntry) { final ProviderResourceEntry providerEntry = (ProviderResourceEntry) entry; + + String systemFontFamilyName = providerEntry.getSystemFontFamilyName(); + if (systemFontFamilyName != null && hasFontFamily(systemFontFamilyName)) { + return Typeface.create(systemFontFamilyName, NORMAL); + } // Downloadable font List> givenCerts = providerEntry.getCerts(); List> certs = new ArrayList<>();