Loading graphics/java/android/graphics/FontListParser.java +11 −9 Original line number Diff line number Diff line Loading @@ -225,7 +225,14 @@ public class FontListParser { } } String sanitizedName = FILENAME_WHITESPACE_PATTERN.matcher(filename).replaceAll(""); String updatedName = findUpdatedFontFile(sanitizedName, updatableFontMap); if (postScriptName == null) { // If post script name was not provided, assume the file name is same to PostScript // name. postScriptName = sanitizedName.substring(0, sanitizedName.length() - 4); } String updatedName = findUpdatedFontFile(postScriptName, updatableFontMap); String filePath; String originalPath; if (updatedName != null) { Loading @@ -246,12 +253,7 @@ public class FontListParser { File file = new File(filePath); if (postScriptName == null) { // If post script name was not provided, assume the file name is same to PostScript // name. String name = file.getName(); postScriptName = name.substring(0, name.length() - 4); } return new FontConfig.Font(file, originalPath == null ? null : new File(originalPath), Loading @@ -265,10 +267,10 @@ public class FontListParser { fallbackFor); } private static String findUpdatedFontFile(String name, private static String findUpdatedFontFile(String psName, @Nullable Map<String, File> updatableFontMap) { if (updatableFontMap != null) { File updatedFile = updatableFontMap.get(name); File updatedFile = updatableFontMap.get(psName); if (updatedFile != null) { return updatedFile.getAbsolutePath(); } Loading services/core/java/com/android/server/graphics/fonts/FontManagerService.java +1 −4 Original line number Diff line number Diff line Loading @@ -52,7 +52,6 @@ import java.io.PrintWriter; import java.nio.ByteBuffer; import java.nio.NioUtils; import java.nio.channels.FileChannel; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Map; Loading Loading @@ -249,8 +248,6 @@ public final class FontManagerService extends IFontManager.Stub { // If apk verity is supported, fs-verity should be available. if (!VerityUtils.isFsVeritySupported()) return null; return new UpdatableFontDir(new File(FONT_FILES_DIR), Arrays.asList(new File(SystemFonts.SYSTEM_FONT_DIR), new File(SystemFonts.OEM_FONT_DIR)), new OtfFontFileParser(), new FsverityUtilImpl()); } Loading Loading @@ -323,7 +320,7 @@ public final class FontManagerService extends IFontManager.Stub { return Collections.emptyMap(); } synchronized (mUpdatableFontDirLock) { return mUpdatableFontDir.getFontFileMap(); return mUpdatableFontDir.getPostScriptMap(); } } Loading services/core/java/com/android/server/graphics/fonts/UpdatableFontDir.java +48 −30 Original line number Diff line number Diff line Loading @@ -43,6 +43,7 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.function.Function; import java.util.function.Supplier; /** Loading Loading @@ -117,12 +118,12 @@ final class UpdatableFontDir { * randomized dir. The font file path would be {@code mFilesDir/~~{randomStr}/{fontFileName}}. */ private final File mFilesDir; private final List<File> mPreinstalledFontDirs; private final FontFileParser mParser; private final FsverityUtil mFsverityUtil; private final File mConfigFile; private final File mTmpConfigFile; private final Supplier<Long> mCurrentTimeSupplier; private final Function<Map<String, File>, FontConfig> mConfigSupplier; private long mLastModifiedMillis; private int mConfigVersion; Loading @@ -134,22 +135,24 @@ final class UpdatableFontDir { */ private final ArrayMap<String, FontFileInfo> mFontFileInfoMap = new ArrayMap<>(); UpdatableFontDir(File filesDir, List<File> preinstalledFontDirs, FontFileParser parser, FsverityUtil fsverityUtil) { this(filesDir, preinstalledFontDirs, parser, fsverityUtil, new File(CONFIG_XML_FILE), () -> System.currentTimeMillis()); UpdatableFontDir(File filesDir, FontFileParser parser, FsverityUtil fsverityUtil) { this(filesDir, parser, fsverityUtil, new File(CONFIG_XML_FILE), () -> System.currentTimeMillis(), (map) -> SystemFonts.getSystemFontConfig(map, 0, 0) ); } // For unit testing UpdatableFontDir(File filesDir, List<File> preinstalledFontDirs, FontFileParser parser, FsverityUtil fsverityUtil, File configFile, Supplier<Long> currentTimeSupplier) { UpdatableFontDir(File filesDir, FontFileParser parser, FsverityUtil fsverityUtil, File configFile, Supplier<Long> currentTimeSupplier, Function<Map<String, File>, FontConfig> configSupplier) { mFilesDir = filesDir; mPreinstalledFontDirs = preinstalledFontDirs; mParser = parser; mFsverityUtil = fsverityUtil; mConfigFile = configFile; mTmpConfigFile = new File(configFile.getAbsoluteFile() + ".tmp"); mCurrentTimeSupplier = currentTimeSupplier; mConfigSupplier = configSupplier; } /** Loading @@ -174,6 +177,7 @@ final class UpdatableFontDir { File[] dirs = mFilesDir.listFiles(); if (dirs == null) return; FontConfig fontConfig = getSystemFontConfig(); for (File dir : dirs) { if (!dir.getName().startsWith(RANDOM_DIR_PREFIX)) { Slog.e(TAG, "Unexpected dir found: " + dir); Loading @@ -190,7 +194,7 @@ final class UpdatableFontDir { return; } FontFileInfo fontFileInfo = validateFontFile(files[0]); addFileToMapIfSameOrNewer(fontFileInfo, true /* deleteOldFile */); addFileToMapIfSameOrNewer(fontFileInfo, fontConfig, true /* deleteOldFile */); } success = true; } catch (Throwable t) { Loading Loading @@ -302,7 +306,7 @@ final class UpdatableFontDir { * Installs a new font file, or updates an existing font file. * * <p>The new font will be immediately available for new Zygote-forked processes through * {@link #getFontFileMap()}. Old font files will be kept until next system server reboot, * {@link #getPostScriptMap()}. Old font files will be kept until next system server reboot, * because existing Zygote-forked processes have paths to old font files. * * @param fd A file descriptor to the font file. Loading Loading @@ -373,7 +377,8 @@ final class UpdatableFontDir { "Failed to change mode to 711", e); } FontFileInfo fontFileInfo = validateFontFile(newFontFile); if (!addFileToMapIfSameOrNewer(fontFileInfo, false)) { FontConfig fontConfig = getSystemFontConfig(); if (!addFileToMapIfSameOrNewer(fontFileInfo, fontConfig, false)) { throw new SystemFontException( FontManager.RESULT_ERROR_DOWNGRADING, "Downgrading font file is forbidden."); Loading Loading @@ -417,14 +422,15 @@ final class UpdatableFontDir { * equal to or higher than the revision of currently used font file (either in * {@link #mFontFileInfoMap} or {@link #mPreinstalledFontDirs}). */ private boolean addFileToMapIfSameOrNewer(FontFileInfo fontFileInfo, boolean deleteOldFile) { private boolean addFileToMapIfSameOrNewer(FontFileInfo fontFileInfo, FontConfig fontConfig, boolean deleteOldFile) { FontFileInfo existingInfo = lookupFontFileInfo(fontFileInfo.getPostScriptName()); 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'. long preInstalledRev = getPreinstalledFontRevision(fontFileInfo.getFile().getName()); long preInstalledRev = getPreinstalledFontRevision(fontFileInfo, fontConfig); shouldAddToMap = preInstalledRev <= fontFileInfo.getRevision(); } else { shouldAddToMap = existingInfo.getRevision() <= fontFileInfo.getRevision(); Loading @@ -442,21 +448,33 @@ final class UpdatableFontDir { return shouldAddToMap; } private long getPreinstalledFontRevision(String name) { long maxRevision = -1; for (File dir : mPreinstalledFontDirs) { File preinstalledFontFile = new File(dir, name); if (!preinstalledFontFile.exists()) continue; private long getPreinstalledFontRevision(FontFileInfo info, FontConfig fontConfig) { String psName = info.getPostScriptName(); FontConfig.Font targetFont = null; for (int i = 0; i < fontConfig.getFontFamilies().size(); i++) { FontConfig.FontFamily family = fontConfig.getFontFamilies().get(i); for (int j = 0; j < family.getFontList().size(); ++j) { FontConfig.Font font = family.getFontList().get(j); if (font.getPostScriptName().equals(psName)) { targetFont = font; break; } } } if (targetFont == null) { return -1; } File preinstalledFontFile = targetFont.getOriginalFile() != null ? targetFont.getOriginalFile() : targetFont.getFile(); if (!preinstalledFontFile.exists()) { return -1; } long revision = getFontRevision(preinstalledFontFile); if (revision == -1) { Slog.w(TAG, "Invalid preinstalled font file"); continue; } if (revision > maxRevision) { maxRevision = revision; } } return maxRevision; return revision; } /** Loading Loading @@ -515,17 +533,17 @@ final class UpdatableFontDir { null, FontConfig.FontFamily.VARIANT_DEFAULT); } Map<String, File> getFontFileMap() { Map<String, File> getPostScriptMap() { Map<String, File> map = new ArrayMap<>(); for (int i = 0; i < mFontFileInfoMap.size(); ++i) { File file = mFontFileInfoMap.valueAt(i).getFile(); map.put(file.getName(), file); FontFileInfo info = mFontFileInfoMap.valueAt(i); map.put(info.getPostScriptName(), info.getFile()); } return map; } /* package */ FontConfig getSystemFontConfig() { FontConfig config = SystemFonts.getSystemFontConfig(getFontFileMap(), 0, 0); FontConfig config = mConfigSupplier.apply(getPostScriptMap()); PersistentSystemFontConfig.Config persistentConfig = readPersistentConfig(); List<FontUpdateRequest.Family> families = persistentConfig.fontFamilies; Loading services/tests/servicestests/src/com/android/server/graphics/fonts/UpdatableFontDirTest.java +257 −181 File changed.Preview size limit exceeded, changes collapsed. Show changes Loading
graphics/java/android/graphics/FontListParser.java +11 −9 Original line number Diff line number Diff line Loading @@ -225,7 +225,14 @@ public class FontListParser { } } String sanitizedName = FILENAME_WHITESPACE_PATTERN.matcher(filename).replaceAll(""); String updatedName = findUpdatedFontFile(sanitizedName, updatableFontMap); if (postScriptName == null) { // If post script name was not provided, assume the file name is same to PostScript // name. postScriptName = sanitizedName.substring(0, sanitizedName.length() - 4); } String updatedName = findUpdatedFontFile(postScriptName, updatableFontMap); String filePath; String originalPath; if (updatedName != null) { Loading @@ -246,12 +253,7 @@ public class FontListParser { File file = new File(filePath); if (postScriptName == null) { // If post script name was not provided, assume the file name is same to PostScript // name. String name = file.getName(); postScriptName = name.substring(0, name.length() - 4); } return new FontConfig.Font(file, originalPath == null ? null : new File(originalPath), Loading @@ -265,10 +267,10 @@ public class FontListParser { fallbackFor); } private static String findUpdatedFontFile(String name, private static String findUpdatedFontFile(String psName, @Nullable Map<String, File> updatableFontMap) { if (updatableFontMap != null) { File updatedFile = updatableFontMap.get(name); File updatedFile = updatableFontMap.get(psName); if (updatedFile != null) { return updatedFile.getAbsolutePath(); } Loading
services/core/java/com/android/server/graphics/fonts/FontManagerService.java +1 −4 Original line number Diff line number Diff line Loading @@ -52,7 +52,6 @@ import java.io.PrintWriter; import java.nio.ByteBuffer; import java.nio.NioUtils; import java.nio.channels.FileChannel; import java.util.Arrays; import java.util.Collections; import java.util.List; import java.util.Map; Loading Loading @@ -249,8 +248,6 @@ public final class FontManagerService extends IFontManager.Stub { // If apk verity is supported, fs-verity should be available. if (!VerityUtils.isFsVeritySupported()) return null; return new UpdatableFontDir(new File(FONT_FILES_DIR), Arrays.asList(new File(SystemFonts.SYSTEM_FONT_DIR), new File(SystemFonts.OEM_FONT_DIR)), new OtfFontFileParser(), new FsverityUtilImpl()); } Loading Loading @@ -323,7 +320,7 @@ public final class FontManagerService extends IFontManager.Stub { return Collections.emptyMap(); } synchronized (mUpdatableFontDirLock) { return mUpdatableFontDir.getFontFileMap(); return mUpdatableFontDir.getPostScriptMap(); } } Loading
services/core/java/com/android/server/graphics/fonts/UpdatableFontDir.java +48 −30 Original line number Diff line number Diff line Loading @@ -43,6 +43,7 @@ import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.function.Function; import java.util.function.Supplier; /** Loading Loading @@ -117,12 +118,12 @@ final class UpdatableFontDir { * randomized dir. The font file path would be {@code mFilesDir/~~{randomStr}/{fontFileName}}. */ private final File mFilesDir; private final List<File> mPreinstalledFontDirs; private final FontFileParser mParser; private final FsverityUtil mFsverityUtil; private final File mConfigFile; private final File mTmpConfigFile; private final Supplier<Long> mCurrentTimeSupplier; private final Function<Map<String, File>, FontConfig> mConfigSupplier; private long mLastModifiedMillis; private int mConfigVersion; Loading @@ -134,22 +135,24 @@ final class UpdatableFontDir { */ private final ArrayMap<String, FontFileInfo> mFontFileInfoMap = new ArrayMap<>(); UpdatableFontDir(File filesDir, List<File> preinstalledFontDirs, FontFileParser parser, FsverityUtil fsverityUtil) { this(filesDir, preinstalledFontDirs, parser, fsverityUtil, new File(CONFIG_XML_FILE), () -> System.currentTimeMillis()); UpdatableFontDir(File filesDir, FontFileParser parser, FsverityUtil fsverityUtil) { this(filesDir, parser, fsverityUtil, new File(CONFIG_XML_FILE), () -> System.currentTimeMillis(), (map) -> SystemFonts.getSystemFontConfig(map, 0, 0) ); } // For unit testing UpdatableFontDir(File filesDir, List<File> preinstalledFontDirs, FontFileParser parser, FsverityUtil fsverityUtil, File configFile, Supplier<Long> currentTimeSupplier) { UpdatableFontDir(File filesDir, FontFileParser parser, FsverityUtil fsverityUtil, File configFile, Supplier<Long> currentTimeSupplier, Function<Map<String, File>, FontConfig> configSupplier) { mFilesDir = filesDir; mPreinstalledFontDirs = preinstalledFontDirs; mParser = parser; mFsverityUtil = fsverityUtil; mConfigFile = configFile; mTmpConfigFile = new File(configFile.getAbsoluteFile() + ".tmp"); mCurrentTimeSupplier = currentTimeSupplier; mConfigSupplier = configSupplier; } /** Loading @@ -174,6 +177,7 @@ final class UpdatableFontDir { File[] dirs = mFilesDir.listFiles(); if (dirs == null) return; FontConfig fontConfig = getSystemFontConfig(); for (File dir : dirs) { if (!dir.getName().startsWith(RANDOM_DIR_PREFIX)) { Slog.e(TAG, "Unexpected dir found: " + dir); Loading @@ -190,7 +194,7 @@ final class UpdatableFontDir { return; } FontFileInfo fontFileInfo = validateFontFile(files[0]); addFileToMapIfSameOrNewer(fontFileInfo, true /* deleteOldFile */); addFileToMapIfSameOrNewer(fontFileInfo, fontConfig, true /* deleteOldFile */); } success = true; } catch (Throwable t) { Loading Loading @@ -302,7 +306,7 @@ final class UpdatableFontDir { * Installs a new font file, or updates an existing font file. * * <p>The new font will be immediately available for new Zygote-forked processes through * {@link #getFontFileMap()}. Old font files will be kept until next system server reboot, * {@link #getPostScriptMap()}. Old font files will be kept until next system server reboot, * because existing Zygote-forked processes have paths to old font files. * * @param fd A file descriptor to the font file. Loading Loading @@ -373,7 +377,8 @@ final class UpdatableFontDir { "Failed to change mode to 711", e); } FontFileInfo fontFileInfo = validateFontFile(newFontFile); if (!addFileToMapIfSameOrNewer(fontFileInfo, false)) { FontConfig fontConfig = getSystemFontConfig(); if (!addFileToMapIfSameOrNewer(fontFileInfo, fontConfig, false)) { throw new SystemFontException( FontManager.RESULT_ERROR_DOWNGRADING, "Downgrading font file is forbidden."); Loading Loading @@ -417,14 +422,15 @@ final class UpdatableFontDir { * equal to or higher than the revision of currently used font file (either in * {@link #mFontFileInfoMap} or {@link #mPreinstalledFontDirs}). */ private boolean addFileToMapIfSameOrNewer(FontFileInfo fontFileInfo, boolean deleteOldFile) { private boolean addFileToMapIfSameOrNewer(FontFileInfo fontFileInfo, FontConfig fontConfig, boolean deleteOldFile) { FontFileInfo existingInfo = lookupFontFileInfo(fontFileInfo.getPostScriptName()); 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'. long preInstalledRev = getPreinstalledFontRevision(fontFileInfo.getFile().getName()); long preInstalledRev = getPreinstalledFontRevision(fontFileInfo, fontConfig); shouldAddToMap = preInstalledRev <= fontFileInfo.getRevision(); } else { shouldAddToMap = existingInfo.getRevision() <= fontFileInfo.getRevision(); Loading @@ -442,21 +448,33 @@ final class UpdatableFontDir { return shouldAddToMap; } private long getPreinstalledFontRevision(String name) { long maxRevision = -1; for (File dir : mPreinstalledFontDirs) { File preinstalledFontFile = new File(dir, name); if (!preinstalledFontFile.exists()) continue; private long getPreinstalledFontRevision(FontFileInfo info, FontConfig fontConfig) { String psName = info.getPostScriptName(); FontConfig.Font targetFont = null; for (int i = 0; i < fontConfig.getFontFamilies().size(); i++) { FontConfig.FontFamily family = fontConfig.getFontFamilies().get(i); for (int j = 0; j < family.getFontList().size(); ++j) { FontConfig.Font font = family.getFontList().get(j); if (font.getPostScriptName().equals(psName)) { targetFont = font; break; } } } if (targetFont == null) { return -1; } File preinstalledFontFile = targetFont.getOriginalFile() != null ? targetFont.getOriginalFile() : targetFont.getFile(); if (!preinstalledFontFile.exists()) { return -1; } long revision = getFontRevision(preinstalledFontFile); if (revision == -1) { Slog.w(TAG, "Invalid preinstalled font file"); continue; } if (revision > maxRevision) { maxRevision = revision; } } return maxRevision; return revision; } /** Loading Loading @@ -515,17 +533,17 @@ final class UpdatableFontDir { null, FontConfig.FontFamily.VARIANT_DEFAULT); } Map<String, File> getFontFileMap() { Map<String, File> getPostScriptMap() { Map<String, File> map = new ArrayMap<>(); for (int i = 0; i < mFontFileInfoMap.size(); ++i) { File file = mFontFileInfoMap.valueAt(i).getFile(); map.put(file.getName(), file); FontFileInfo info = mFontFileInfoMap.valueAt(i); map.put(info.getPostScriptName(), info.getFile()); } return map; } /* package */ FontConfig getSystemFontConfig() { FontConfig config = SystemFonts.getSystemFontConfig(getFontFileMap(), 0, 0); FontConfig config = mConfigSupplier.apply(getPostScriptMap()); PersistentSystemFontConfig.Config persistentConfig = readPersistentConfig(); List<FontUpdateRequest.Family> families = persistentConfig.fontFamilies; Loading
services/tests/servicestests/src/com/android/server/graphics/fonts/UpdatableFontDirTest.java +257 −181 File changed.Preview size limit exceeded, changes collapsed. Show changes