diff options
4 files changed, 125 insertions, 66 deletions
diff --git a/graphics/java/android/graphics/fonts/FontFileUtil.java b/graphics/java/android/graphics/fonts/FontFileUtil.java index af49619fb840..917eef2ffede 100644 --- a/graphics/java/android/graphics/fonts/FontFileUtil.java +++ b/graphics/java/android/graphics/fonts/FontFileUtil.java @@ -183,6 +183,23 @@ public class FontFileUtil { return nIsPostScriptType1Font(buffer, index); } + /** + * Analyze the file content and returns 1 if the font file is an OpenType collection file, 0 if + * the font file is a OpenType font file, -1 otherwise. + */ + public static int isCollectionFont(@NonNull ByteBuffer buffer) { + ByteBuffer copied = buffer.slice(); + copied.order(ByteOrder.BIG_ENDIAN); + int magicNumber = copied.getInt(0); + if (magicNumber == TTC_TAG) { + return 1; + } else if (magicNumber == SFNT_VERSION_1 || magicNumber == SFNT_VERSION_OTTO) { + return 0; + } else { + return -1; + } + } + @FastNative private static native long nGetFontRevision(@NonNull ByteBuffer buffer, @IntRange(from = 0) int index); diff --git a/services/core/java/com/android/server/graphics/fonts/FontManagerService.java b/services/core/java/com/android/server/graphics/fonts/FontManagerService.java index 900ec905609f..673d4082a6d7 100644 --- a/services/core/java/com/android/server/graphics/fonts/FontManagerService.java +++ b/services/core/java/com/android/server/graphics/fonts/FontManagerService.java @@ -31,6 +31,7 @@ import android.os.SharedMemory; import android.os.ShellCallback; import android.system.ErrnoException; import android.text.FontConfig; +import android.text.TextUtils; import android.util.AndroidException; import android.util.IndentingPrintWriter; import android.util.Slog; @@ -148,10 +149,24 @@ public final class FontManagerService extends IFontManager.Stub { /* package */ static class OtfFontFileParser implements UpdatableFontDir.FontFileParser { @Override - public String getPostScriptName(File file) throws IOException { + public String getCanonicalFileName(File file) throws IOException { ByteBuffer buffer = mmap(file); try { - return FontFileUtil.getPostScriptName(buffer, 0); + String psName = FontFileUtil.getPostScriptName(buffer, 0); + int isType1Font = FontFileUtil.isPostScriptType1Font(buffer, 0); + int isCollection = FontFileUtil.isCollectionFont(buffer); + + if (TextUtils.isEmpty(psName) || isType1Font == -1 || isCollection == -1) { + return null; + } + + String extension; + if (isCollection == 1) { + extension = isType1Font == 1 ? ".otc" : ".ttc"; + } else { + extension = isType1Font == 1 ? ".otf" : ".ttf"; + } + return psName + extension; } finally { NioUtils.freeDirectBuffer(buffer); } diff --git a/services/core/java/com/android/server/graphics/fonts/UpdatableFontDir.java b/services/core/java/com/android/server/graphics/fonts/UpdatableFontDir.java index 86dbe86f85ee..4f95d27a085e 100644 --- a/services/core/java/com/android/server/graphics/fonts/UpdatableFontDir.java +++ b/services/core/java/com/android/server/graphics/fonts/UpdatableFontDir.java @@ -56,14 +56,12 @@ final class UpdatableFontDir { private static final String TAG = "UpdatableFontDir"; private static final String RANDOM_DIR_PREFIX = "~~"; - // TODO: Support .otf - private static final String ALLOWED_EXTENSION = ".ttf"; private static final String CONFIG_XML_FILE = "/data/fonts/config/config.xml"; /** Interface to mock font file access in tests. */ interface FontFileParser { - String getPostScriptName(File file) throws IOException; + String getCanonicalFileName(File file) throws IOException; long getRevision(File file) throws IOException; } @@ -321,20 +319,20 @@ final class UpdatableFontDir { FontManager.RESULT_ERROR_VERIFICATION_FAILURE, "Failed to setup fs-verity.", e); } - String postScriptName; + String canonicalFileName; try { - postScriptName = mParser.getPostScriptName(tempNewFontFile); + canonicalFileName = mParser.getCanonicalFileName(tempNewFontFile); } catch (IOException e) { throw new SystemFontException( FontManager.RESULT_ERROR_INVALID_FONT_FILE, "Failed to read PostScript name from font file", e); } - if (postScriptName == null) { + if (canonicalFileName == null) { throw new SystemFontException( FontManager.RESULT_ERROR_INVALID_FONT_NAME, "Failed to read PostScript name from font file"); } - File newFontFile = new File(newDir, postScriptName + ALLOWED_EXTENSION); + File newFontFile = new File(newDir, canonicalFileName); if (!mFsverityUtil.rename(tempNewFontFile, newFontFile)) { throw new SystemFontException( FontManager.RESULT_ERROR_FAILED_TO_WRITE_FONT_FILE, @@ -380,20 +378,38 @@ final class UpdatableFontDir { return dir; } + private FontFileInfo lookupFontFileInfo(File file) { + String name = file.getName(); + + if (!name.endsWith(".ttf") && !name.endsWith(".otf") && !name.endsWith(".ttc") + && !name.endsWith(".otc")) { + return null; + } + String key = name.substring(0, name.length() - 4); + return mFontFileInfoMap.get(key); + } + + private void putFontFileInfo(FontFileInfo info) { + String name = info.getFile().getName(); + // The file name in FontFileInfo is already validated. Thus, just strip last 4 chars. + String key = name.substring(0, name.length() - 4); + mFontFileInfoMap.put(key, info); + } + /** * Add the given {@link FontFileInfo} to {@link #mFontFileInfoMap} if its font revision is * higher than the currently used font file (either in {@link #mFontFileInfoMap} or {@link * #mPreinstalledFontDirs}). */ private boolean addFileToMapIfNewer(FontFileInfo fontFileInfo, boolean deleteOldFile) { - String name = fontFileInfo.getFile().getName(); - FontFileInfo existingInfo = mFontFileInfoMap.get(name); + FontFileInfo existingInfo = lookupFontFileInfo(fontFileInfo.getFile()); final boolean shouldAddToMap; if (existingInfo == null) { // We got a new updatable font. We need to check if it's newer than preinstalled fonts. // Note that getPreinstalledFontRevision() returns -1 if there is no preinstalled font // with 'name'. - shouldAddToMap = getPreinstalledFontRevision(name) < fontFileInfo.getRevision(); + long preInstalledRev = getPreinstalledFontRevision(fontFileInfo.getFile().getName()); + shouldAddToMap = preInstalledRev < fontFileInfo.getRevision(); } else { shouldAddToMap = existingInfo.getRevision() < fontFileInfo.getRevision(); } @@ -401,7 +417,7 @@ final class UpdatableFontDir { if (deleteOldFile && existingInfo != null) { FileUtils.deleteContentsAndDir(existingInfo.getRandomizedFontDir()); } - mFontFileInfoMap.put(name, fontFileInfo); + putFontFileInfo(fontFileInfo); } else { if (deleteOldFile) { FileUtils.deleteContentsAndDir(fontFileInfo.getRandomizedFontDir()); @@ -464,15 +480,18 @@ final class UpdatableFontDir { */ private boolean validateFontFileName(File file) { String fileName = file.getName(); - String postScriptName = getPostScriptName(file); - return (postScriptName + ALLOWED_EXTENSION).equals(fileName); + String canonicalFileName = getCanonicalFileName(file); + if (canonicalFileName == null) { + return false; + } + return canonicalFileName.equals(fileName); } /** Returns the PostScript name of the given font file, or null. */ @Nullable - private String getPostScriptName(File file) { + private String getCanonicalFileName(File file) { try { - return mParser.getPostScriptName(file); + return mParser.getCanonicalFileName(file); } catch (IOException e) { Slog.e(TAG, "Failed to read font file", e); return null; @@ -514,7 +533,7 @@ final class UpdatableFontDir { List<FontConfig.Font> fontList = fontFamily.getFontList(); for (int i = 0; i < fontList.size(); i++) { FontConfig.Font font = fontList.get(i); - FontFileInfo info = mFontFileInfoMap.get(font.getFile().getName()); + FontFileInfo info = lookupFontFileInfo(font.getFile()); if (info == null) { return null; } @@ -537,8 +556,9 @@ final class UpdatableFontDir { Map<String, File> getFontFileMap() { Map<String, File> map = new ArrayMap<>(); - for (Map.Entry<String, FontFileInfo> entry : mFontFileInfoMap.entrySet()) { - map.put(entry.getKey(), entry.getValue().getFile()); + for (int i = 0; i < mFontFileInfoMap.size(); ++i) { + File file = mFontFileInfoMap.valueAt(i).getFile(); + map.put(file.getName(), file); } return map; } diff --git a/services/tests/servicestests/src/com/android/server/graphics/fonts/UpdatableFontDirTest.java b/services/tests/servicestests/src/com/android/server/graphics/fonts/UpdatableFontDirTest.java index 843296e31800..dbb415c88a5f 100644 --- a/services/tests/servicestests/src/com/android/server/graphics/fonts/UpdatableFontDirTest.java +++ b/services/tests/servicestests/src/com/android/server/graphics/fonts/UpdatableFontDirTest.java @@ -68,7 +68,7 @@ public final class UpdatableFontDirTest { */ private static class FakeFontFileParser implements UpdatableFontDir.FontFileParser { @Override - public String getPostScriptName(File file) throws IOException { + public String getCanonicalFileName(File file) throws IOException { String content = FileUtils.readTextFile(file, 100, ""); return content.split(",")[0]; } @@ -160,10 +160,10 @@ public final class UpdatableFontDirTest { assertThat(dirForPreparation.getSystemFontConfig().getLastModifiedTimeMillis()) .isEqualTo(expectedModifiedDate); dirForPreparation.update(Arrays.asList( - newFontUpdateRequest("foo,1", GOOD_SIGNATURE), - newFontUpdateRequest("bar,2", GOOD_SIGNATURE), - newFontUpdateRequest("foo,3", GOOD_SIGNATURE), - newFontUpdateRequest("bar,4", GOOD_SIGNATURE), + newFontUpdateRequest("foo.ttf,1", GOOD_SIGNATURE), + newFontUpdateRequest("bar.ttf,2", GOOD_SIGNATURE), + newFontUpdateRequest("foo.ttf,3", GOOD_SIGNATURE), + newFontUpdateRequest("bar.ttf,4", GOOD_SIGNATURE), newAddFontFamilyRequest("<family name='foobar'>" + " <font>foo.ttf</font>" + " <font>bar.ttf</font>" @@ -214,10 +214,10 @@ public final class UpdatableFontDirTest { mConfigFile); dirForPreparation.loadFontFileMap(); dirForPreparation.update(Arrays.asList( - newFontUpdateRequest("foo,1", GOOD_SIGNATURE), - newFontUpdateRequest("bar,2", GOOD_SIGNATURE), - newFontUpdateRequest("foo,3", GOOD_SIGNATURE), - newFontUpdateRequest("bar,4", GOOD_SIGNATURE), + newFontUpdateRequest("foo.ttf,1", GOOD_SIGNATURE), + newFontUpdateRequest("bar.ttf,2", GOOD_SIGNATURE), + newFontUpdateRequest("foo.ttf,3", GOOD_SIGNATURE), + newFontUpdateRequest("bar.ttf,4", GOOD_SIGNATURE), newAddFontFamilyRequest("<family name='foobar'>" + " <font>foo.ttf</font>" + " <font>bar.ttf</font>" @@ -246,10 +246,10 @@ public final class UpdatableFontDirTest { mConfigFile); dirForPreparation.loadFontFileMap(); dirForPreparation.update(Arrays.asList( - newFontUpdateRequest("foo,1", GOOD_SIGNATURE), - newFontUpdateRequest("bar,2", GOOD_SIGNATURE), - newFontUpdateRequest("foo,3", GOOD_SIGNATURE), - newFontUpdateRequest("bar,4", GOOD_SIGNATURE), + newFontUpdateRequest("foo.ttf,1", GOOD_SIGNATURE), + newFontUpdateRequest("bar.ttf,2", GOOD_SIGNATURE), + newFontUpdateRequest("foo.ttf,3", GOOD_SIGNATURE), + newFontUpdateRequest("bar.ttf,4", GOOD_SIGNATURE), newAddFontFamilyRequest("<family name='foobar'>" + " <font>foo.ttf</font>" + " <font>bar.ttf</font>" @@ -279,10 +279,10 @@ public final class UpdatableFontDirTest { mConfigFile); dirForPreparation.loadFontFileMap(); dirForPreparation.update(Arrays.asList( - newFontUpdateRequest("foo,1", GOOD_SIGNATURE), - newFontUpdateRequest("bar,2", GOOD_SIGNATURE), - newFontUpdateRequest("foo,3", GOOD_SIGNATURE), - newFontUpdateRequest("bar,4", GOOD_SIGNATURE), + newFontUpdateRequest("foo.ttf,1", GOOD_SIGNATURE), + newFontUpdateRequest("bar.ttf,2", GOOD_SIGNATURE), + newFontUpdateRequest("foo.ttf,3", GOOD_SIGNATURE), + newFontUpdateRequest("bar.ttf,4", GOOD_SIGNATURE), newAddFontFamilyRequest("<family name='foobar'>" + " <font>foo.ttf</font>" + " <font>bar.ttf</font>" @@ -332,14 +332,14 @@ public final class UpdatableFontDirTest { mConfigFile); dirForPreparation.loadFontFileMap(); dirForPreparation.update(Arrays.asList( - newFontUpdateRequest("foo,1", GOOD_SIGNATURE), + newFontUpdateRequest("foo.ttf,1", GOOD_SIGNATURE), newAddFontFamilyRequest("<family name='foobar'>" + " <font>foo.ttf</font>" + "</family>"))); try { dirForPreparation.update(Arrays.asList( - newFontUpdateRequest("foo,2", GOOD_SIGNATURE), - newFontUpdateRequest("bar,2", "Invalid signature"), + newFontUpdateRequest("foo.ttf,2", GOOD_SIGNATURE), + newFontUpdateRequest("bar.ttf,2", "Invalid signature"), newAddFontFamilyRequest("<family name='foobar'>" + " <font>foo.ttf</font>" + " <font>bar.ttf</font>" @@ -372,7 +372,7 @@ public final class UpdatableFontDirTest { mConfigFile); dir.loadFontFileMap(); - dir.update(Collections.singletonList(newFontUpdateRequest("test,1", GOOD_SIGNATURE))); + dir.update(Collections.singletonList(newFontUpdateRequest("test.ttf,1", GOOD_SIGNATURE))); assertThat(dir.getFontFileMap()).containsKey("test.ttf"); assertThat(parser.getRevision(dir.getFontFileMap().get("test.ttf"))).isEqualTo(1); File fontFile = dir.getFontFileMap().get("test.ttf"); @@ -390,9 +390,9 @@ public final class UpdatableFontDirTest { mConfigFile); dir.loadFontFileMap(); - dir.update(Collections.singletonList(newFontUpdateRequest("test,1", GOOD_SIGNATURE))); + dir.update(Collections.singletonList(newFontUpdateRequest("test.ttf,1", GOOD_SIGNATURE))); Map<String, File> mapBeforeUpgrade = dir.getFontFileMap(); - dir.update(Collections.singletonList(newFontUpdateRequest("test,2", GOOD_SIGNATURE))); + dir.update(Collections.singletonList(newFontUpdateRequest("test.ttf,2", GOOD_SIGNATURE))); assertThat(dir.getFontFileMap()).containsKey("test.ttf"); assertThat(parser.getRevision(dir.getFontFileMap().get("test.ttf"))).isEqualTo(2); assertThat(mapBeforeUpgrade).containsKey("test.ttf"); @@ -409,9 +409,10 @@ public final class UpdatableFontDirTest { mConfigFile); dir.loadFontFileMap(); - dir.update(Collections.singletonList(newFontUpdateRequest("test,2", GOOD_SIGNATURE))); + dir.update(Collections.singletonList(newFontUpdateRequest("test.ttf,2", GOOD_SIGNATURE))); try { - dir.update(Collections.singletonList(newFontUpdateRequest("test,1", GOOD_SIGNATURE))); + dir.update(Collections.singletonList(newFontUpdateRequest("test.ttf,1", + GOOD_SIGNATURE))); fail("Expect SystemFontException"); } catch (FontManagerService.SystemFontException e) { assertThat(e.getErrorCode()).isEqualTo(FontManager.RESULT_ERROR_DOWNGRADING); @@ -430,8 +431,8 @@ public final class UpdatableFontDirTest { mConfigFile); dir.loadFontFileMap(); - dir.update(Collections.singletonList(newFontUpdateRequest("foo,1", GOOD_SIGNATURE))); - dir.update(Collections.singletonList(newFontUpdateRequest("bar,2", GOOD_SIGNATURE))); + dir.update(Collections.singletonList(newFontUpdateRequest("foo.ttf,1", GOOD_SIGNATURE))); + dir.update(Collections.singletonList(newFontUpdateRequest("bar.ttf,2", GOOD_SIGNATURE))); assertThat(dir.getFontFileMap()).containsKey("foo.ttf"); assertThat(parser.getRevision(dir.getFontFileMap().get("foo.ttf"))).isEqualTo(1); assertThat(dir.getFontFileMap()).containsKey("bar.ttf"); @@ -448,8 +449,8 @@ public final class UpdatableFontDirTest { dir.loadFontFileMap(); dir.update(Arrays.asList( - newFontUpdateRequest("foo,1", GOOD_SIGNATURE), - newFontUpdateRequest("bar,2", GOOD_SIGNATURE))); + newFontUpdateRequest("foo.ttf,1", GOOD_SIGNATURE), + newFontUpdateRequest("bar.ttf,2", GOOD_SIGNATURE))); assertThat(dir.getFontFileMap()).containsKey("foo.ttf"); assertThat(parser.getRevision(dir.getFontFileMap().get("foo.ttf"))).isEqualTo(1); assertThat(dir.getFontFileMap()).containsKey("bar.ttf"); @@ -467,7 +468,8 @@ public final class UpdatableFontDirTest { try { dir.update( - Collections.singletonList(newFontUpdateRequest("test,1", "Invalid signature"))); + Collections.singletonList(newFontUpdateRequest("test.ttf,1", + "Invalid signature"))); fail("Expect SystemFontException"); } catch (FontManagerService.SystemFontException e) { assertThat(e.getErrorCode()) @@ -480,14 +482,15 @@ public final class UpdatableFontDirTest { public void installFontFile_olderThanPreinstalledFont() throws Exception { FakeFontFileParser parser = new FakeFontFileParser(); FakeFsverityUtil fakeFsverityUtil = new FakeFsverityUtil(); - FileUtils.stringToFile(new File(mPreinstalledFontDirs.get(0), "test.ttf"), "test,1"); + FileUtils.stringToFile(new File(mPreinstalledFontDirs.get(0), "test.ttf"), "test.ttf,1"); UpdatableFontDir dir = new UpdatableFontDir( mUpdatableFontFilesDir, mPreinstalledFontDirs, parser, fakeFsverityUtil, mConfigFile); dir.loadFontFileMap(); try { - dir.update(Collections.singletonList(newFontUpdateRequest("test,1", GOOD_SIGNATURE))); + dir.update(Collections.singletonList(newFontUpdateRequest("test.ttf,1", + GOOD_SIGNATURE))); fail("Expect SystemFontException"); } catch (FontManagerService.SystemFontException e) { assertThat(e.getErrorCode()).isEqualTo(FontManager.RESULT_ERROR_DOWNGRADING); @@ -500,7 +503,7 @@ public final class UpdatableFontDirTest { long expectedModifiedDate = 1234567890; FakeFontFileParser parser = new FakeFontFileParser(); FakeFsverityUtil fakeFsverityUtil = new FakeFsverityUtil(); - FileUtils.stringToFile(new File(mPreinstalledFontDirs.get(0), "test.ttf"), "test,1"); + FileUtils.stringToFile(new File(mPreinstalledFontDirs.get(0), "test.ttf"), "test.ttf,1"); File readonlyDir = new File(mCacheDir, "readonly"); assertThat(readonlyDir.mkdir()).isTrue(); @@ -519,7 +522,8 @@ public final class UpdatableFontDirTest { try { dir.update( - Collections.singletonList(newFontUpdateRequest("test,2", GOOD_SIGNATURE))); + Collections.singletonList(newFontUpdateRequest("test.ttf,2", + GOOD_SIGNATURE))); } catch (FontManagerService.SystemFontException e) { assertThat(e.getErrorCode()) .isEqualTo(FontManager.RESULT_ERROR_FAILED_UPDATE_CONFIG); @@ -539,7 +543,7 @@ public final class UpdatableFontDirTest { mUpdatableFontFilesDir, mPreinstalledFontDirs, new UpdatableFontDir.FontFileParser() { @Override - public String getPostScriptName(File file) throws IOException { + public String getCanonicalFileName(File file) throws IOException { return null; } @@ -551,7 +555,8 @@ public final class UpdatableFontDirTest { dir.loadFontFileMap(); try { - dir.update(Collections.singletonList(newFontUpdateRequest("foo,1", GOOD_SIGNATURE))); + dir.update(Collections.singletonList(newFontUpdateRequest("foo.ttf,1", + GOOD_SIGNATURE))); fail("Expect SystemFontException"); } catch (FontManagerService.SystemFontException e) { assertThat(e.getErrorCode()) @@ -567,7 +572,7 @@ public final class UpdatableFontDirTest { mUpdatableFontFilesDir, mPreinstalledFontDirs, new UpdatableFontDir.FontFileParser() { @Override - public String getPostScriptName(File file) throws IOException { + public String getCanonicalFileName(File file) throws IOException { throw new IOException(); } @@ -579,7 +584,8 @@ public final class UpdatableFontDirTest { dir.loadFontFileMap(); try { - dir.update(Collections.singletonList(newFontUpdateRequest("foo,1", GOOD_SIGNATURE))); + dir.update(Collections.singletonList(newFontUpdateRequest("foo.ttf,1", + GOOD_SIGNATURE))); fail("Expect SystemFontException"); } catch (FontManagerService.SystemFontException e) { assertThat(e.getErrorCode()) @@ -615,7 +621,8 @@ public final class UpdatableFontDirTest { dir.loadFontFileMap(); try { - dir.update(Collections.singletonList(newFontUpdateRequest("foo,1", GOOD_SIGNATURE))); + dir.update(Collections.singletonList(newFontUpdateRequest("foo.ttf,1", + GOOD_SIGNATURE))); fail("Expect SystemFontException"); } catch (FontManagerService.SystemFontException e) { assertThat(e.getErrorCode()) @@ -633,11 +640,11 @@ public final class UpdatableFontDirTest { mConfigFile); dir.loadFontFileMap(); - dir.update(Collections.singletonList(newFontUpdateRequest("foo,1", GOOD_SIGNATURE))); + dir.update(Collections.singletonList(newFontUpdateRequest("foo.ttf,1", GOOD_SIGNATURE))); try { dir.update(Arrays.asList( - newFontUpdateRequest("foo,2", GOOD_SIGNATURE), - newFontUpdateRequest("bar,2", "Invalid signature"))); + newFontUpdateRequest("foo.ttf,2", GOOD_SIGNATURE), + newFontUpdateRequest("bar.ttf,2", "Invalid signature"))); fail("Batch update with invalid signature should fail"); } catch (FontManagerService.SystemFontException e) { // Expected @@ -657,7 +664,7 @@ public final class UpdatableFontDirTest { dir.loadFontFileMap(); dir.update(Arrays.asList( - newFontUpdateRequest("test,1", GOOD_SIGNATURE), + newFontUpdateRequest("test.ttf,1", GOOD_SIGNATURE), newAddFontFamilyRequest("<family name='test'>" + " <font>test.ttf</font>" + "</family>"))); @@ -680,7 +687,7 @@ public final class UpdatableFontDirTest { try { dir.update(Arrays.asList( - newFontUpdateRequest("test,1", GOOD_SIGNATURE), + newFontUpdateRequest("test.ttf,1", GOOD_SIGNATURE), newAddFontFamilyRequest("<family lang='en'>" + " <font>test.ttf</font>" + "</family>"))); @@ -722,7 +729,7 @@ public final class UpdatableFontDirTest { assertNamedFamilyExists(dir.getSystemFontConfig(), "monospace"); dir.update(Arrays.asList( - newFontUpdateRequest("test,1", GOOD_SIGNATURE), + newFontUpdateRequest("test.ttf,1", GOOD_SIGNATURE), // Updating an existing font family. newAddFontFamilyRequest("<family name='monospace'>" + " <font>test.ttf</font>" @@ -755,7 +762,7 @@ public final class UpdatableFontDirTest { assertThat(firstFontFamily.getName()).isNotEmpty(); dir.update(Arrays.asList( - newFontUpdateRequest("test,1", GOOD_SIGNATURE), + newFontUpdateRequest("test.ttf,1", GOOD_SIGNATURE), newAddFontFamilyRequest("<family name='" + firstFontFamily.getName() + "'>" + " <font>test.ttf</font>" + "</family>"))); |