summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author TreeHugger Robot <treehugger-gerrit@google.com> 2021-01-12 05:18:59 +0000
committer Android (Google) Code Review <android-gerrit@google.com> 2021-01-12 05:18:59 +0000
commit55b6a818e0cbddb7152601a3a2c666d025b7b2f0 (patch)
tree522dd593747b26878bc9c587e9d209dd4d1d5655
parent368efbc3db82a6b5aed93aea2835caa8a37bc8fa (diff)
parent87036d61ecbaba9131a666f5104ffff758d0a526 (diff)
Merge "Check updatable font dir in FontListParser."
-rw-r--r--core/tests/coretests/src/android/graphics/TypefaceSystemFallbackTest.java65
-rw-r--r--graphics/java/android/graphics/FontListParser.java40
-rw-r--r--graphics/java/android/graphics/fonts/FontCustomizationParser.java2
-rw-r--r--graphics/java/android/graphics/fonts/SystemFonts.java30
4 files changed, 106 insertions, 31 deletions
diff --git a/core/tests/coretests/src/android/graphics/TypefaceSystemFallbackTest.java b/core/tests/coretests/src/android/graphics/TypefaceSystemFallbackTest.java
index 82d066f6ab16..05ff21853131 100644
--- a/core/tests/coretests/src/android/graphics/TypefaceSystemFallbackTest.java
+++ b/core/tests/coretests/src/android/graphics/TypefaceSystemFallbackTest.java
@@ -67,6 +67,7 @@ public class TypefaceSystemFallbackTest {
private static final String TEST_FONT_DIR;
private static final String TEST_OEM_XML;
private static final String TEST_OEM_DIR;
+ private static final String TEST_UPDATABLE_FONT_DIR;
private static final float GLYPH_1EM_WIDTH;
private static final float GLYPH_2EM_WIDTH;
@@ -82,9 +83,11 @@ public class TypefaceSystemFallbackTest {
TEST_FONTS_XML = new File(cacheDir, "fonts.xml").getAbsolutePath();
TEST_OEM_DIR = cacheDir.getAbsolutePath() + "/oem_fonts/";
TEST_OEM_XML = new File(cacheDir, "fonts_customization.xml").getAbsolutePath();
+ TEST_UPDATABLE_FONT_DIR = cacheDir.getAbsolutePath() + "/updatable_fonts/";
new File(TEST_FONT_DIR).mkdirs();
new File(TEST_OEM_DIR).mkdirs();
+ new File(TEST_UPDATABLE_FONT_DIR).mkdirs();
final AssetManager am =
InstrumentationRegistry.getInstrumentation().getContext().getAssets();
@@ -103,18 +106,11 @@ public class TypefaceSystemFallbackTest {
InstrumentationRegistry.getInstrumentation().getContext().getAssets();
for (final String fontFile : TEST_FONT_FILES) {
final String sourceInAsset = "fonts/" + fontFile;
- final File outInCache = new File(TEST_FONT_DIR, fontFile);
- try (InputStream is = am.open(sourceInAsset)) {
- Files.copy(is, outInCache.toPath(), StandardCopyOption.REPLACE_EXISTING);
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- final File outOemInCache = new File(TEST_OEM_DIR, fontFile);
- try (InputStream is = am.open(sourceInAsset)) {
- Files.copy(is, outOemInCache.toPath(), StandardCopyOption.REPLACE_EXISTING);
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
+ copyAssetToFile(sourceInAsset, new File(TEST_FONT_DIR, fontFile));
+ copyAssetToFile(sourceInAsset, new File(TEST_OEM_DIR, fontFile));
+ }
+ for (final File fontFile : new File(TEST_UPDATABLE_FONT_DIR).listFiles()) {
+ fontFile.delete();
}
}
@@ -124,7 +120,20 @@ public class TypefaceSystemFallbackTest {
final File outInCache = new File(TEST_FONT_DIR, fontFile);
outInCache.delete();
final File outOemInCache = new File(TEST_OEM_DIR, fontFile);
- outInCache.delete();
+ outOemInCache.delete();
+ }
+ for (final File fontFile : new File(TEST_UPDATABLE_FONT_DIR).listFiles()) {
+ fontFile.delete();
+ }
+ }
+
+ private static void copyAssetToFile(String sourceInAsset, File out) {
+ final AssetManager am =
+ InstrumentationRegistry.getInstrumentation().getContext().getAssets();
+ try (InputStream is = am.open(sourceInAsset)) {
+ Files.copy(is, out.toPath(), StandardCopyOption.REPLACE_EXISTING);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
}
}
@@ -138,7 +147,7 @@ public class TypefaceSystemFallbackTest {
}
final FontConfig.Alias[] aliases = SystemFonts.buildSystemFallback(TEST_FONTS_XML,
- TEST_FONT_DIR, oemCustomization, fallbackMap);
+ TEST_FONT_DIR, TEST_UPDATABLE_FONT_DIR, oemCustomization, fallbackMap);
Typeface.initSystemDefaultTypefaces(fontMap, fallbackMap, aliases);
}
@@ -835,4 +844,32 @@ public class TypefaceSystemFallbackTest {
+ "</fonts-modification>";
readFontCustomization(oemXml);
}
+
+
+ @Test
+ public void testBuildSystemFallback_UpdatableFont() {
+ final String xml = "<?xml version='1.0' encoding='UTF-8'?>"
+ + "<familyset>"
+ + " <family name='test'>"
+ + " <font weight='400' style='normal'>a3em.ttf</font>"
+ + " </family>"
+ + "</familyset>";
+ final ArrayMap<String, Typeface> fontMap = new ArrayMap<>();
+ final ArrayMap<String, FontFamily[]> fallbackMap = new ArrayMap<>();
+ final FontCustomizationParser.Result oemCustomization =
+ new FontCustomizationParser.Result();
+
+ // Install all2em.ttf as a3em.ttf
+ copyAssetToFile("fonts/all2em.ttf", new File(TEST_UPDATABLE_FONT_DIR, "a3em.ttf"));
+ buildSystemFallback(xml, oemCustomization, fontMap, fallbackMap);
+
+ final Paint paint = new Paint();
+
+ final Typeface sansSerifTypeface = fontMap.get("test");
+ assertNotNull(sansSerifTypeface);
+ paint.setTypeface(sansSerifTypeface);
+ assertEquals(GLYPH_2EM_WIDTH, paint.measureText("a"), 0.0f);
+ assertEquals(GLYPH_2EM_WIDTH, paint.measureText("b"), 0.0f);
+ assertEquals(GLYPH_2EM_WIDTH, paint.measureText("c"), 0.0f);
+ }
}
diff --git a/graphics/java/android/graphics/FontListParser.java b/graphics/java/android/graphics/FontListParser.java
index 0782f8dfd9d3..73fff7207c45 100644
--- a/graphics/java/android/graphics/FontListParser.java
+++ b/graphics/java/android/graphics/FontListParser.java
@@ -16,6 +16,7 @@
package android.graphics;
+import android.annotation.Nullable;
import android.compat.annotation.UnsupportedAppUsage;
import android.graphics.fonts.FontVariationAxis;
import android.os.Build;
@@ -25,6 +26,7 @@ import android.util.Xml;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
+import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
@@ -41,26 +43,26 @@ public class FontListParser {
/* Parse fallback list (no names) */
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
public static FontConfig parse(InputStream in) throws XmlPullParserException, IOException {
- return parse(in, "/system/fonts");
+ return parse(in, "/system/fonts", null);
}
/**
* Parse the fonts.xml
*/
- public static FontConfig parse(InputStream in, String fontDir)
- throws XmlPullParserException, IOException {
+ public static FontConfig parse(InputStream in, String fontDir,
+ @Nullable String updatableFontDir) throws XmlPullParserException, IOException {
try {
XmlPullParser parser = Xml.newPullParser();
parser.setInput(in, null);
parser.nextTag();
- return readFamilies(parser, fontDir);
+ return readFamilies(parser, fontDir, updatableFontDir);
} finally {
in.close();
}
}
- private static FontConfig readFamilies(XmlPullParser parser, String fontDir)
- throws XmlPullParserException, IOException {
+ private static FontConfig readFamilies(XmlPullParser parser, String fontDir,
+ @Nullable String updatableFontDir) throws XmlPullParserException, IOException {
List<FontConfig.Family> families = new ArrayList<>();
List<FontConfig.Alias> aliases = new ArrayList<>();
@@ -69,7 +71,7 @@ public class FontListParser {
if (parser.getEventType() != XmlPullParser.START_TAG) continue;
String tag = parser.getName();
if (tag.equals("family")) {
- families.add(readFamily(parser, fontDir));
+ families.add(readFamily(parser, fontDir, updatableFontDir));
} else if (tag.equals("alias")) {
aliases.add(readAlias(parser));
} else {
@@ -83,8 +85,8 @@ public class FontListParser {
/**
* Reads a family element
*/
- public static FontConfig.Family readFamily(XmlPullParser parser, String fontDir)
- throws XmlPullParserException, IOException {
+ public static FontConfig.Family readFamily(XmlPullParser parser, String fontDir,
+ @Nullable String updatableFontDir) throws XmlPullParserException, IOException {
final String name = parser.getAttributeValue(null, "name");
final String lang = parser.getAttributeValue("", "lang");
final String variant = parser.getAttributeValue(null, "variant");
@@ -93,7 +95,7 @@ public class FontListParser {
if (parser.getEventType() != XmlPullParser.START_TAG) continue;
final String tag = parser.getName();
if (tag.equals("font")) {
- fonts.add(readFont(parser, fontDir));
+ fonts.add(readFont(parser, fontDir, updatableFontDir));
} else {
skip(parser);
}
@@ -114,8 +116,8 @@ public class FontListParser {
private static final Pattern FILENAME_WHITESPACE_PATTERN =
Pattern.compile("^[ \\n\\r\\t]+|[ \\n\\r\\t]+$");
- private static FontConfig.Font readFont(XmlPullParser parser, String fontDir)
- throws XmlPullParserException, IOException {
+ private static FontConfig.Font readFont(XmlPullParser parser, String fontDir,
+ @Nullable String updatableFontDir) throws XmlPullParserException, IOException {
String indexStr = parser.getAttributeValue(null, "index");
int index = indexStr == null ? 0 : Integer.parseInt(indexStr);
List<FontVariationAxis> axes = new ArrayList<FontVariationAxis>();
@@ -137,10 +139,22 @@ public class FontListParser {
}
}
String sanitizedName = FILENAME_WHITESPACE_PATTERN.matcher(filename).replaceAll("");
- return new FontConfig.Font(fontDir + sanitizedName, index, axes.toArray(
+ String fontName = findFontFile(sanitizedName, fontDir, updatableFontDir);
+ return new FontConfig.Font(fontName, index, axes.toArray(
new FontVariationAxis[axes.size()]), weight, isItalic, fallbackFor);
}
+ private static String findFontFile(String fileName, String fontDir,
+ @Nullable String updatableFontDir) {
+ if (updatableFontDir != null) {
+ String updatableFontName = updatableFontDir + fileName;
+ if (new File(updatableFontName).exists()) {
+ return updatableFontName;
+ }
+ }
+ return fontDir + fileName;
+ }
+
private static FontVariationAxis readAxis(XmlPullParser parser)
throws XmlPullParserException, IOException {
String tagStr = parser.getAttributeValue(null, "tag");
diff --git a/graphics/java/android/graphics/fonts/FontCustomizationParser.java b/graphics/java/android/graphics/fonts/FontCustomizationParser.java
index 0291d7484dc5..f95da82ee07c 100644
--- a/graphics/java/android/graphics/fonts/FontCustomizationParser.java
+++ b/graphics/java/android/graphics/fonts/FontCustomizationParser.java
@@ -97,7 +97,7 @@ public class FontCustomizationParser {
throw new IllegalArgumentException("customizationType must be specified");
}
if (customizationType.equals("new-named-family")) {
- out.mAdditionalNamedFamilies.add(FontListParser.readFamily(parser, fontDir));
+ out.mAdditionalNamedFamilies.add(FontListParser.readFamily(parser, fontDir, null));
} else {
throw new IllegalArgumentException("Unknown customizationType=" + customizationType);
}
diff --git a/graphics/java/android/graphics/fonts/SystemFonts.java b/graphics/java/android/graphics/fonts/SystemFonts.java
index fb6ea99be7ab..16a53c25db08 100644
--- a/graphics/java/android/graphics/fonts/SystemFonts.java
+++ b/graphics/java/android/graphics/fonts/SystemFonts.java
@@ -91,7 +91,9 @@ public final class SystemFonts {
final FontCustomizationParser.Result oemCustomization =
readFontCustomization("/product/etc/fonts_customization.xml", "/product/fonts/");
Map<String, FontFamily[]> map = new ArrayMap<>();
- buildSystemFallback("/system/etc/fonts.xml", "/system/fonts/", oemCustomization, map);
+ // TODO: use updated fonts
+ buildSystemFallback("/system/etc/fonts.xml", "/system/fonts/", null /* updatableFontDir */,
+ oemCustomization, map);
Set<Font> res = new HashSet<>();
for (FontFamily[] families : map.values()) {
for (FontFamily family : families) {
@@ -226,11 +228,26 @@ public final class SystemFonts {
}
/**
+ * @see #buildSystemFallback(String, String, String, FontCustomizationParser.Result, Map)
+ * @hide
+ */
+ @VisibleForTesting
+ public static FontConfig.Alias[] buildSystemFallback(@NonNull String xmlPath,
+ @NonNull String fontDir,
+ @NonNull FontCustomizationParser.Result oemCustomization,
+ @NonNull Map<String, FontFamily[]> fallbackMap) {
+ return buildSystemFallback(xmlPath, fontDir, null /* updatableFontDir */,
+ oemCustomization, fallbackMap);
+ }
+
+ /**
* Build the system fallback from xml file.
*
* @param xmlPath A full path string to the fonts.xml file.
* @param fontDir A full path string to the system font directory. This must end with
* slash('/').
+ * @param updatableFontDir A full path string to the updatable system font directory. This
+ * must end with slash('/').
* @param fallbackMap An output system fallback map. Caller must pass empty map.
* @return a list of aliases
* @hide
@@ -238,11 +255,12 @@ public final class SystemFonts {
@VisibleForTesting
public static FontConfig.Alias[] buildSystemFallback(@NonNull String xmlPath,
@NonNull String fontDir,
+ @Nullable String updatableFontDir,
@NonNull FontCustomizationParser.Result oemCustomization,
@NonNull Map<String, FontFamily[]> fallbackMap) {
try {
final FileInputStream fontsIn = new FileInputStream(xmlPath);
- final FontConfig fontConfig = FontListParser.parse(fontsIn, fontDir);
+ final FontConfig fontConfig = FontListParser.parse(fontsIn, fontDir, updatableFontDir);
final HashMap<String, ByteBuffer> bufferCache = new HashMap<String, ByteBuffer>();
final FontConfig.Family[] xmlFamilies = fontConfig.getFamilies();
@@ -306,11 +324,17 @@ public final class SystemFonts {
/** @hide */
public static @NonNull Pair<FontConfig.Alias[], Map<String, FontFamily[]>>
initializePreinstalledFonts() {
+ return initializeSystemFonts(null);
+ }
+
+ /** @hide */
+ public static Pair<FontConfig.Alias[], Map<String, FontFamily[]>>
+ initializeSystemFonts(@Nullable String updatableFontDir) {
final FontCustomizationParser.Result oemCustomization =
readFontCustomization("/product/etc/fonts_customization.xml", "/product/fonts/");
Map<String, FontFamily[]> map = new ArrayMap<>();
FontConfig.Alias[] aliases = buildSystemFallback("/system/etc/fonts.xml", "/system/fonts/",
- oemCustomization, map);
+ updatableFontDir, oemCustomization, map);
synchronized (LOCK) {
sFamilyMap = map;
}