Loading services/core/java/com/android/server/graphics/fonts/FontManagerService.java +36 −24 Original line number Diff line number Diff line Loading @@ -26,7 +26,6 @@ import android.graphics.fonts.FontFileUtil; import android.graphics.fonts.FontManager; import android.graphics.fonts.SystemFonts; import android.os.ParcelFileDescriptor; import android.os.RemoteException; import android.os.ResultReceiver; import android.os.SharedMemory; import android.os.ShellCallback; Loading Loading @@ -67,13 +66,12 @@ public final class FontManagerService extends IFontManager.Stub { private static final String CRASH_MARKER_FILE = "/data/fonts/config/crash.txt"; @Override public FontConfig getFontConfig() throws RemoteException { public FontConfig getFontConfig() { return getSystemFontConfig(); } @Override public int updateFont(ParcelFileDescriptor fd, byte[] signature, int baseVersion) throws RemoteException { public int updateFont(ParcelFileDescriptor fd, byte[] signature, int baseVersion) { Objects.requireNonNull(fd); Objects.requireNonNull(signature); Preconditions.checkArgumentNonnegative(baseVersion); Loading Loading @@ -183,14 +181,21 @@ public final class FontManagerService extends IFontManager.Stub { @NonNull private final Context mContext; @GuardedBy("FontManagerService.this") private final Object mUpdatableFontDirLock = new Object(); @GuardedBy("mUpdatableFontDirLock") @NonNull private final FontCrashDetector mFontCrashDetector; @GuardedBy("mUpdatableFontDirLock") @Nullable private final UpdatableFontDir mUpdatableFontDir; @GuardedBy("FontManagerService.this") // mSerializedFontMapLock can be acquired while holding mUpdatableFontDirLock. // mUpdatableFontDirLock should not be newly acquired while holding mSerializedFontMapLock. private final Object mSerializedFontMapLock = new Object(); @GuardedBy("mSerializedFontMapLock") @Nullable private SharedMemory mSerializedFontMap = null; Loading @@ -212,9 +217,9 @@ public final class FontManagerService extends IFontManager.Stub { } private void initialize() { synchronized (FontManagerService.this) { synchronized (mUpdatableFontDirLock) { if (mUpdatableFontDir == null) { mSerializedFontMap = buildNewSerializedFontMap(); updateSerializedFontMap(); return; } if (mFontCrashDetector.hasCrashed()) { Loading @@ -228,7 +233,7 @@ public final class FontManagerService extends IFontManager.Stub { } try (FontCrashDetector.MonitoredBlock ignored = mFontCrashDetector.start()) { mUpdatableFontDir.loadFontFileMap(); mSerializedFontMap = buildNewSerializedFontMap(); updateSerializedFontMap(); } } } Loading @@ -239,7 +244,7 @@ public final class FontManagerService extends IFontManager.Stub { } @Nullable /* package */ SharedMemory getCurrentFontMap() { synchronized (FontManagerService.this) { synchronized (mSerializedFontMapLock) { return mSerializedFontMap; } } Loading @@ -251,7 +256,7 @@ public final class FontManagerService extends IFontManager.Stub { FontManager.RESULT_ERROR_FONT_UPDATER_DISABLED, "The font updater is disabled."); } synchronized (FontManagerService.this) { synchronized (mUpdatableFontDirLock) { // baseVersion == -1 only happens from shell command. This is filtered and treated as // error from SystemApi call. if (baseVersion != -1 && mUpdatableFontDir.getConfigVersion() != baseVersion) { Loading @@ -261,7 +266,7 @@ public final class FontManagerService extends IFontManager.Stub { } try (FontCrashDetector.MonitoredBlock ignored = mFontCrashDetector.start()) { mUpdatableFontDir.installFontFile(fd, pkcs7Signature); mSerializedFontMap = buildNewSerializedFontMap(); updateSerializedFontMap(); } } } Loading @@ -272,10 +277,10 @@ public final class FontManagerService extends IFontManager.Stub { FontManager.RESULT_ERROR_FONT_UPDATER_DISABLED, "The font updater is disabled."); } synchronized (FontManagerService.this) { synchronized (mUpdatableFontDirLock) { try (FontCrashDetector.MonitoredBlock ignored = mFontCrashDetector.start()) { mUpdatableFontDir.clearUpdates(); mSerializedFontMap = buildNewSerializedFontMap(); updateSerializedFontMap(); } } } Loading @@ -283,7 +288,8 @@ public final class FontManagerService extends IFontManager.Stub { /* package */ Map<String, File> getFontFileMap() { if (mUpdatableFontDir == null) { return Collections.emptyMap(); } else { } synchronized (mUpdatableFontDirLock) { return mUpdatableFontDir.getFontFileMap(); } } Loading @@ -301,7 +307,7 @@ public final class FontManagerService extends IFontManager.Stub { @Nullable FileDescriptor err, @NonNull String[] args, @Nullable ShellCallback callback, @NonNull ResultReceiver result) throws RemoteException { @NonNull ResultReceiver result) { new FontManagerShellCommand(this).exec(this, in, out, err, args, callback, result); } Loading @@ -309,24 +315,28 @@ public final class FontManagerService extends IFontManager.Stub { * Returns an active system font configuration. */ public @NonNull FontConfig getSystemFontConfig() { if (mUpdatableFontDir != null) { return mUpdatableFontDir.getSystemFontConfig(); } else { if (mUpdatableFontDir == null) { return SystemFonts.getSystemPreinstalledFontConfig(); } synchronized (mUpdatableFontDirLock) { return mUpdatableFontDir.getSystemFontConfig(); } } /** * Make new serialized font map data. * Makes new serialized font map data and updates mSerializedFontMap. */ public @Nullable SharedMemory buildNewSerializedFontMap() { public void updateSerializedFontMap() { try { final FontConfig fontConfig = getSystemFontConfig(); final Map<String, FontFamily[]> fallback = SystemFonts.buildSystemFallback(fontConfig); final Map<String, Typeface> typefaceMap = SystemFonts.buildSystemTypefaces(fontConfig, fallback); return Typeface.serializeFontMap(typefaceMap); SharedMemory serializeFontMap = Typeface.serializeFontMap(typefaceMap); synchronized (mSerializedFontMapLock) { mSerializedFontMap = serializeFontMap; } } catch (IOException | ErrnoException e) { Slog.w(TAG, "Failed to serialize updatable font map. " + "Retrying with system image fonts.", e); Loading @@ -338,11 +348,13 @@ public final class FontManagerService extends IFontManager.Stub { final Map<String, Typeface> typefaceMap = SystemFonts.buildSystemTypefaces(fontConfig, fallback); return Typeface.serializeFontMap(typefaceMap); SharedMemory serializeFontMap = Typeface.serializeFontMap(typefaceMap); synchronized (mSerializedFontMapLock) { mSerializedFontMap = serializeFontMap; } } catch (IOException | ErrnoException e) { Slog.e(TAG, "Failed to serialize SystemServer system font map", e); } return null; } } services/core/java/com/android/server/graphics/fonts/UpdatableFontDir.java +146 −158 Original line number Diff line number Diff line Loading @@ -29,8 +29,6 @@ import android.text.FontConfig; import android.util.Base64; import android.util.Slog; import com.android.internal.annotations.GuardedBy; import org.xmlpull.v1.XmlPullParserException; import java.io.File; Loading @@ -44,6 +42,11 @@ import java.util.HashMap; import java.util.List; import java.util.Map; /** * Manages set of updatable font files. * * <p>This class is not thread safe. */ final class UpdatableFontDir { private static final String TAG = "UpdatableFontDir"; Loading Loading @@ -113,11 +116,9 @@ final class UpdatableFontDir { private final File mConfigFile; private final File mTmpConfigFile; @GuardedBy("UpdatableFontDir.this") private final PersistentSystemFontConfig.Config mConfig = new PersistentSystemFontConfig.Config(); @GuardedBy("UpdatableFontDir.this") private int mConfigVersion = 1; /** Loading @@ -125,7 +126,6 @@ final class UpdatableFontDir { * FontFileInfo}. All files in this map are validated, and have higher revision numbers than * corresponding font files in {@link #mPreinstalledFontDirs}. */ @GuardedBy("UpdatableFontDir.this") private final Map<String, FontFileInfo> mFontFileInfoMap = new HashMap<>(); UpdatableFontDir(File filesDir, List<File> preinstalledFontDirs, FontFileParser parser, Loading @@ -145,7 +145,6 @@ final class UpdatableFontDir { } /* package */ void loadFontFileMap() { synchronized (UpdatableFontDir.this) { boolean success = false; try (FileInputStream fis = new FileInputStream(mConfigFile)) { Loading @@ -163,7 +162,7 @@ final class UpdatableFontDir { File[] files = dir.listFiles(); if (files == null || files.length != 1) return; FontFileInfo fontFileInfo = validateFontFile(files[0]); addFileToMapIfNewerLocked(fontFileInfo, true /* deleteOldFile */); addFileToMapIfNewer(fontFileInfo, true /* deleteOldFile */); } success = true; } catch (Throwable t) { Loading @@ -178,10 +177,8 @@ final class UpdatableFontDir { } } } } /* package */ void clearUpdates() throws SystemFontException { synchronized (UpdatableFontDir.this) { mFontFileInfoMap.clear(); FileUtils.deleteContents(mFilesDir); Loading @@ -196,7 +193,6 @@ final class UpdatableFontDir { } mConfigVersion++; } } /** * Installs a new font file, or updates an existing font file. Loading @@ -210,7 +206,6 @@ final class UpdatableFontDir { * @throws SystemFontException if error occurs. */ void installFontFile(FileDescriptor fd, byte[] pkcs7Signature) throws SystemFontException { synchronized (UpdatableFontDir.this) { File newDir = getRandomDir(mFilesDir); if (!newDir.mkdir()) { throw new SystemFontException( Loading Loading @@ -289,7 +284,7 @@ final class UpdatableFontDir { // Backup the mapping for rollback. HashMap<String, FontFileInfo> backup = new HashMap<>(mFontFileInfoMap); if (!addFileToMapIfNewerLocked(fontFileInfo, false)) { if (!addFileToMapIfNewer(fontFileInfo, false)) { throw new SystemFontException( FontManager.RESULT_ERROR_DOWNGRADING, "Downgrading font file is forbidden."); Loading @@ -316,7 +311,6 @@ final class UpdatableFontDir { } } } } /** * Given {@code parent}, returns {@code parent/~~[randomStr]}. Loading @@ -341,7 +335,7 @@ final class UpdatableFontDir { * higher than the currently used font file (either in {@link #mFontFileInfoMap} or {@link * #mPreinstalledFontDirs}). */ private boolean addFileToMapIfNewerLocked(FontFileInfo fontFileInfo, boolean deleteOldFile) { private boolean addFileToMapIfNewer(FontFileInfo fontFileInfo, boolean deleteOldFile) { String name = fontFileInfo.getFile().getName(); FontFileInfo existingInfo = mFontFileInfoMap.get(name); final boolean shouldAddToMap; Loading Loading @@ -447,27 +441,21 @@ final class UpdatableFontDir { Map<String, File> getFontFileMap() { Map<String, File> map = new HashMap<>(); synchronized (UpdatableFontDir.this) { for (Map.Entry<String, FontFileInfo> entry : mFontFileInfoMap.entrySet()) { map.put(entry.getKey(), entry.getValue().getFile()); } } return map; } /* package */ FontConfig getSystemFontConfig() { synchronized (UpdatableFontDir.this) { return SystemFonts.getSystemFontConfig( getFontFileMap(), mConfig.lastModifiedDate, mConfigVersion ); } } /* package */ int getConfigVersion() { synchronized (UpdatableFontDir.this) { return mConfigVersion; } } } Loading
services/core/java/com/android/server/graphics/fonts/FontManagerService.java +36 −24 Original line number Diff line number Diff line Loading @@ -26,7 +26,6 @@ import android.graphics.fonts.FontFileUtil; import android.graphics.fonts.FontManager; import android.graphics.fonts.SystemFonts; import android.os.ParcelFileDescriptor; import android.os.RemoteException; import android.os.ResultReceiver; import android.os.SharedMemory; import android.os.ShellCallback; Loading Loading @@ -67,13 +66,12 @@ public final class FontManagerService extends IFontManager.Stub { private static final String CRASH_MARKER_FILE = "/data/fonts/config/crash.txt"; @Override public FontConfig getFontConfig() throws RemoteException { public FontConfig getFontConfig() { return getSystemFontConfig(); } @Override public int updateFont(ParcelFileDescriptor fd, byte[] signature, int baseVersion) throws RemoteException { public int updateFont(ParcelFileDescriptor fd, byte[] signature, int baseVersion) { Objects.requireNonNull(fd); Objects.requireNonNull(signature); Preconditions.checkArgumentNonnegative(baseVersion); Loading Loading @@ -183,14 +181,21 @@ public final class FontManagerService extends IFontManager.Stub { @NonNull private final Context mContext; @GuardedBy("FontManagerService.this") private final Object mUpdatableFontDirLock = new Object(); @GuardedBy("mUpdatableFontDirLock") @NonNull private final FontCrashDetector mFontCrashDetector; @GuardedBy("mUpdatableFontDirLock") @Nullable private final UpdatableFontDir mUpdatableFontDir; @GuardedBy("FontManagerService.this") // mSerializedFontMapLock can be acquired while holding mUpdatableFontDirLock. // mUpdatableFontDirLock should not be newly acquired while holding mSerializedFontMapLock. private final Object mSerializedFontMapLock = new Object(); @GuardedBy("mSerializedFontMapLock") @Nullable private SharedMemory mSerializedFontMap = null; Loading @@ -212,9 +217,9 @@ public final class FontManagerService extends IFontManager.Stub { } private void initialize() { synchronized (FontManagerService.this) { synchronized (mUpdatableFontDirLock) { if (mUpdatableFontDir == null) { mSerializedFontMap = buildNewSerializedFontMap(); updateSerializedFontMap(); return; } if (mFontCrashDetector.hasCrashed()) { Loading @@ -228,7 +233,7 @@ public final class FontManagerService extends IFontManager.Stub { } try (FontCrashDetector.MonitoredBlock ignored = mFontCrashDetector.start()) { mUpdatableFontDir.loadFontFileMap(); mSerializedFontMap = buildNewSerializedFontMap(); updateSerializedFontMap(); } } } Loading @@ -239,7 +244,7 @@ public final class FontManagerService extends IFontManager.Stub { } @Nullable /* package */ SharedMemory getCurrentFontMap() { synchronized (FontManagerService.this) { synchronized (mSerializedFontMapLock) { return mSerializedFontMap; } } Loading @@ -251,7 +256,7 @@ public final class FontManagerService extends IFontManager.Stub { FontManager.RESULT_ERROR_FONT_UPDATER_DISABLED, "The font updater is disabled."); } synchronized (FontManagerService.this) { synchronized (mUpdatableFontDirLock) { // baseVersion == -1 only happens from shell command. This is filtered and treated as // error from SystemApi call. if (baseVersion != -1 && mUpdatableFontDir.getConfigVersion() != baseVersion) { Loading @@ -261,7 +266,7 @@ public final class FontManagerService extends IFontManager.Stub { } try (FontCrashDetector.MonitoredBlock ignored = mFontCrashDetector.start()) { mUpdatableFontDir.installFontFile(fd, pkcs7Signature); mSerializedFontMap = buildNewSerializedFontMap(); updateSerializedFontMap(); } } } Loading @@ -272,10 +277,10 @@ public final class FontManagerService extends IFontManager.Stub { FontManager.RESULT_ERROR_FONT_UPDATER_DISABLED, "The font updater is disabled."); } synchronized (FontManagerService.this) { synchronized (mUpdatableFontDirLock) { try (FontCrashDetector.MonitoredBlock ignored = mFontCrashDetector.start()) { mUpdatableFontDir.clearUpdates(); mSerializedFontMap = buildNewSerializedFontMap(); updateSerializedFontMap(); } } } Loading @@ -283,7 +288,8 @@ public final class FontManagerService extends IFontManager.Stub { /* package */ Map<String, File> getFontFileMap() { if (mUpdatableFontDir == null) { return Collections.emptyMap(); } else { } synchronized (mUpdatableFontDirLock) { return mUpdatableFontDir.getFontFileMap(); } } Loading @@ -301,7 +307,7 @@ public final class FontManagerService extends IFontManager.Stub { @Nullable FileDescriptor err, @NonNull String[] args, @Nullable ShellCallback callback, @NonNull ResultReceiver result) throws RemoteException { @NonNull ResultReceiver result) { new FontManagerShellCommand(this).exec(this, in, out, err, args, callback, result); } Loading @@ -309,24 +315,28 @@ public final class FontManagerService extends IFontManager.Stub { * Returns an active system font configuration. */ public @NonNull FontConfig getSystemFontConfig() { if (mUpdatableFontDir != null) { return mUpdatableFontDir.getSystemFontConfig(); } else { if (mUpdatableFontDir == null) { return SystemFonts.getSystemPreinstalledFontConfig(); } synchronized (mUpdatableFontDirLock) { return mUpdatableFontDir.getSystemFontConfig(); } } /** * Make new serialized font map data. * Makes new serialized font map data and updates mSerializedFontMap. */ public @Nullable SharedMemory buildNewSerializedFontMap() { public void updateSerializedFontMap() { try { final FontConfig fontConfig = getSystemFontConfig(); final Map<String, FontFamily[]> fallback = SystemFonts.buildSystemFallback(fontConfig); final Map<String, Typeface> typefaceMap = SystemFonts.buildSystemTypefaces(fontConfig, fallback); return Typeface.serializeFontMap(typefaceMap); SharedMemory serializeFontMap = Typeface.serializeFontMap(typefaceMap); synchronized (mSerializedFontMapLock) { mSerializedFontMap = serializeFontMap; } } catch (IOException | ErrnoException e) { Slog.w(TAG, "Failed to serialize updatable font map. " + "Retrying with system image fonts.", e); Loading @@ -338,11 +348,13 @@ public final class FontManagerService extends IFontManager.Stub { final Map<String, Typeface> typefaceMap = SystemFonts.buildSystemTypefaces(fontConfig, fallback); return Typeface.serializeFontMap(typefaceMap); SharedMemory serializeFontMap = Typeface.serializeFontMap(typefaceMap); synchronized (mSerializedFontMapLock) { mSerializedFontMap = serializeFontMap; } } catch (IOException | ErrnoException e) { Slog.e(TAG, "Failed to serialize SystemServer system font map", e); } return null; } }
services/core/java/com/android/server/graphics/fonts/UpdatableFontDir.java +146 −158 Original line number Diff line number Diff line Loading @@ -29,8 +29,6 @@ import android.text.FontConfig; import android.util.Base64; import android.util.Slog; import com.android.internal.annotations.GuardedBy; import org.xmlpull.v1.XmlPullParserException; import java.io.File; Loading @@ -44,6 +42,11 @@ import java.util.HashMap; import java.util.List; import java.util.Map; /** * Manages set of updatable font files. * * <p>This class is not thread safe. */ final class UpdatableFontDir { private static final String TAG = "UpdatableFontDir"; Loading Loading @@ -113,11 +116,9 @@ final class UpdatableFontDir { private final File mConfigFile; private final File mTmpConfigFile; @GuardedBy("UpdatableFontDir.this") private final PersistentSystemFontConfig.Config mConfig = new PersistentSystemFontConfig.Config(); @GuardedBy("UpdatableFontDir.this") private int mConfigVersion = 1; /** Loading @@ -125,7 +126,6 @@ final class UpdatableFontDir { * FontFileInfo}. All files in this map are validated, and have higher revision numbers than * corresponding font files in {@link #mPreinstalledFontDirs}. */ @GuardedBy("UpdatableFontDir.this") private final Map<String, FontFileInfo> mFontFileInfoMap = new HashMap<>(); UpdatableFontDir(File filesDir, List<File> preinstalledFontDirs, FontFileParser parser, Loading @@ -145,7 +145,6 @@ final class UpdatableFontDir { } /* package */ void loadFontFileMap() { synchronized (UpdatableFontDir.this) { boolean success = false; try (FileInputStream fis = new FileInputStream(mConfigFile)) { Loading @@ -163,7 +162,7 @@ final class UpdatableFontDir { File[] files = dir.listFiles(); if (files == null || files.length != 1) return; FontFileInfo fontFileInfo = validateFontFile(files[0]); addFileToMapIfNewerLocked(fontFileInfo, true /* deleteOldFile */); addFileToMapIfNewer(fontFileInfo, true /* deleteOldFile */); } success = true; } catch (Throwable t) { Loading @@ -178,10 +177,8 @@ final class UpdatableFontDir { } } } } /* package */ void clearUpdates() throws SystemFontException { synchronized (UpdatableFontDir.this) { mFontFileInfoMap.clear(); FileUtils.deleteContents(mFilesDir); Loading @@ -196,7 +193,6 @@ final class UpdatableFontDir { } mConfigVersion++; } } /** * Installs a new font file, or updates an existing font file. Loading @@ -210,7 +206,6 @@ final class UpdatableFontDir { * @throws SystemFontException if error occurs. */ void installFontFile(FileDescriptor fd, byte[] pkcs7Signature) throws SystemFontException { synchronized (UpdatableFontDir.this) { File newDir = getRandomDir(mFilesDir); if (!newDir.mkdir()) { throw new SystemFontException( Loading Loading @@ -289,7 +284,7 @@ final class UpdatableFontDir { // Backup the mapping for rollback. HashMap<String, FontFileInfo> backup = new HashMap<>(mFontFileInfoMap); if (!addFileToMapIfNewerLocked(fontFileInfo, false)) { if (!addFileToMapIfNewer(fontFileInfo, false)) { throw new SystemFontException( FontManager.RESULT_ERROR_DOWNGRADING, "Downgrading font file is forbidden."); Loading @@ -316,7 +311,6 @@ final class UpdatableFontDir { } } } } /** * Given {@code parent}, returns {@code parent/~~[randomStr]}. Loading @@ -341,7 +335,7 @@ final class UpdatableFontDir { * higher than the currently used font file (either in {@link #mFontFileInfoMap} or {@link * #mPreinstalledFontDirs}). */ private boolean addFileToMapIfNewerLocked(FontFileInfo fontFileInfo, boolean deleteOldFile) { private boolean addFileToMapIfNewer(FontFileInfo fontFileInfo, boolean deleteOldFile) { String name = fontFileInfo.getFile().getName(); FontFileInfo existingInfo = mFontFileInfoMap.get(name); final boolean shouldAddToMap; Loading Loading @@ -447,27 +441,21 @@ final class UpdatableFontDir { Map<String, File> getFontFileMap() { Map<String, File> map = new HashMap<>(); synchronized (UpdatableFontDir.this) { for (Map.Entry<String, FontFileInfo> entry : mFontFileInfoMap.entrySet()) { map.put(entry.getKey(), entry.getValue().getFile()); } } return map; } /* package */ FontConfig getSystemFontConfig() { synchronized (UpdatableFontDir.this) { return SystemFonts.getSystemFontConfig( getFontFileMap(), mConfig.lastModifiedDate, mConfigVersion ); } } /* package */ int getConfigVersion() { synchronized (UpdatableFontDir.this) { return mConfigVersion; } } }