Filter Alias which points non-existing font family name

The FontFamily will be removed if none of font files exist on the
device.

Bug: 192479819
Test: atest FontListParserTest
Change-Id: I36f6476fe37bc04ec8737936747385c63908d651
(cherry picked from commit 691cfe8818513e576300cdb963a65341984659c4)
This commit is contained in:
Seigo Nonaka 2021-07-12 18:37:27 -07:00
parent 8b5f287dcb
commit 4ed687a48f
2 changed files with 85 additions and 2 deletions

View File

@ -27,6 +27,7 @@ import static com.google.common.truth.Truth.assertThat;
import static junit.framework.Assert.fail;
import android.graphics.fonts.FontCustomizationParser;
import android.graphics.fonts.FontStyle;
import android.os.LocaleList;
import android.text.FontConfig;
@ -46,6 +47,7 @@ import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.List;
@SmallTest
@RunWith(AndroidJUnit4.class)
@ -318,6 +320,52 @@ public final class FontListParserTest {
}
}
@Test
public void alias() throws Exception {
String xml = "<?xml version='1.0' encoding='UTF-8'?>"
+ "<familyset>"
+ " <family name='sans-serif'>"
+ " <font>test.ttf</font>"
+ " </family>"
+ " <family name='custom-family'>"
+ " <font>missing.ttf</font>"
+ " </family>"
+ " <alias name='custom-alias' to='sans-serif'/>"
+ "</familyset>";
FontConfig config = readFamilies(xml, true /* include non-existing font files */);
List<FontConfig.Alias> aliases = config.getAliases();
assertThat(aliases.size()).isEqualTo(1);
assertThat(aliases.get(0).getName()).isEqualTo("custom-alias");
assertThat(aliases.get(0).getOriginal()).isEqualTo("sans-serif");
}
@Test
public void dropped_FamilyAlias() throws Exception {
String xml = "<?xml version='1.0' encoding='UTF-8'?>"
+ "<familyset>"
+ " <family name='sans-serif'>"
+ " <font>test.ttf</font>"
+ " </family>"
+ " <family name='custom-family'>"
+ " <font>missing.ttf</font>"
+ " </family>"
+ " <alias name='custom-alias' to='custom-family'/>"
+ "</familyset>";
FontConfig config = readFamilies(xml, false /* exclude not existing file */);
assertThat(config.getAliases()).isEmpty();
}
private FontConfig readFamilies(String xml, boolean allowNonExisting)
throws IOException, XmlPullParserException {
ByteArrayInputStream buffer = new ByteArrayInputStream(
xml.getBytes(StandardCharsets.UTF_8));
XmlPullParser parser = Xml.newPullParser();
parser.setInput(buffer, "UTF-8");
parser.nextTag();
return FontListParser.readFamilies(parser, "", new FontCustomizationParser.Result(), null,
0L /* last modified date */, 0 /* config version */, allowNonExisting);
}
private FontConfig.FontFamily readFamily(String xml)
throws IOException, XmlPullParserException {
ByteArrayInputStream buffer = new ByteArrayInputStream(

View File

@ -25,6 +25,7 @@ import android.graphics.fonts.FontVariationAxis;
import android.os.Build;
import android.os.LocaleList;
import android.text.FontConfig;
import android.util.ArraySet;
import android.util.Xml;
import org.xmlpull.v1.XmlPullParser;
@ -37,6 +38,7 @@ import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.regex.Pattern;
/**
@ -120,7 +122,23 @@ public class FontListParser {
}
}
private static FontConfig readFamilies(
/**
* Parses the familyset tag in font.xml
* @param parser a XML pull parser
* @param fontDir A system font directory, e.g. "/system/fonts"
* @param customization A OEM font customization
* @param updatableFontMap A map of updated font files
* @param lastModifiedDate A date that the system font is updated.
* @param configVersion A version of system font config.
* @param allowNonExistingFile true if allowing non-existing font files during parsing fonts.xml
* @return result of fonts.xml
*
* @throws XmlPullParserException
* @throws IOException
*
* @hide
*/
public static FontConfig readFamilies(
@NonNull XmlPullParser parser,
@NonNull String fontDir,
@NonNull FontCustomizationParser.Result customization,
@ -159,7 +177,24 @@ public class FontListParser {
}
families.addAll(oemNamedFamilies.values());
return new FontConfig(families, aliases, lastModifiedDate, configVersion);
// Filters aliases that point to non-existing families.
Set<String> namedFamilies = new ArraySet<>();
for (int i = 0; i < families.size(); ++i) {
String name = families.get(i).getName();
if (name != null) {
namedFamilies.add(name);
}
}
List<FontConfig.Alias> filtered = new ArrayList<>();
for (int i = 0; i < aliases.size(); ++i) {
FontConfig.Alias alias = aliases.get(i);
if (namedFamilies.contains(alias.getOriginal())) {
filtered.add(alias);
}
}
return new FontConfig(families, filtered, lastModifiedDate, configVersion);
}
private static boolean keepReading(XmlPullParser parser)