Merge "Clear updated font files in safe mode." into sc-dev am: 7c4e5a69b0
Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/13743173 Change-Id: I2cc29e58d6b9ab08e40dbd84fe63b70b04a7315d
This commit is contained in:
@@ -62,6 +62,7 @@ public final class FontManagerService extends IFontManager.Stub {
|
|||||||
private static final String TAG = "FontManagerService";
|
private static final String TAG = "FontManagerService";
|
||||||
|
|
||||||
private static final String FONT_FILES_DIR = "/data/fonts/files";
|
private static final String FONT_FILES_DIR = "/data/fonts/files";
|
||||||
|
private static final String CONFIG_XML_FILE = "/data/fonts/config/config.xml";
|
||||||
|
|
||||||
@RequiresPermission(Manifest.permission.UPDATE_FONTS)
|
@RequiresPermission(Manifest.permission.UPDATE_FONTS)
|
||||||
@Override
|
@Override
|
||||||
@@ -130,9 +131,9 @@ public final class FontManagerService extends IFontManager.Stub {
|
|||||||
public static final class Lifecycle extends SystemService {
|
public static final class Lifecycle extends SystemService {
|
||||||
private final FontManagerService mService;
|
private final FontManagerService mService;
|
||||||
|
|
||||||
public Lifecycle(@NonNull Context context) {
|
public Lifecycle(@NonNull Context context, boolean safeMode) {
|
||||||
super(context);
|
super(context);
|
||||||
mService = new FontManagerService(context);
|
mService = new FontManagerService(context, safeMode);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -187,18 +188,24 @@ public final class FontManagerService extends IFontManager.Stub {
|
|||||||
@Nullable
|
@Nullable
|
||||||
private SharedMemory mSerializedFontMap = null;
|
private SharedMemory mSerializedFontMap = null;
|
||||||
|
|
||||||
private FontManagerService(Context context) {
|
private FontManagerService(Context context, boolean safeMode) {
|
||||||
|
if (safeMode) {
|
||||||
|
Slog.i(TAG, "Entering safe mode. Deleting all font updates.");
|
||||||
|
UpdatableFontDir.deleteAllFiles(new File(FONT_FILES_DIR), new File(CONFIG_XML_FILE));
|
||||||
|
}
|
||||||
mContext = context;
|
mContext = context;
|
||||||
mUpdatableFontDir = createUpdatableFontDir();
|
mUpdatableFontDir = createUpdatableFontDir(safeMode);
|
||||||
initialize();
|
initialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nullable
|
@Nullable
|
||||||
private static UpdatableFontDir createUpdatableFontDir() {
|
private static UpdatableFontDir createUpdatableFontDir(boolean safeMode) {
|
||||||
|
// Never read updatable font files in safe mode.
|
||||||
|
if (safeMode) return null;
|
||||||
// If apk verity is supported, fs-verity should be available.
|
// If apk verity is supported, fs-verity should be available.
|
||||||
if (!VerityUtils.isFsVeritySupported()) return null;
|
if (!VerityUtils.isFsVeritySupported()) return null;
|
||||||
return new UpdatableFontDir(new File(FONT_FILES_DIR),
|
return new UpdatableFontDir(new File(FONT_FILES_DIR), new OtfFontFileParser(),
|
||||||
new OtfFontFileParser(), new FsverityUtilImpl());
|
new FsverityUtilImpl(), new File(CONFIG_XML_FILE));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void initialize() {
|
private void initialize() {
|
||||||
@@ -243,18 +250,23 @@ public final class FontManagerService extends IFontManager.Stub {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* package */ void clearUpdates() throws SystemFontException {
|
/**
|
||||||
if (mUpdatableFontDir == null) {
|
* Clears all updates and restarts FontManagerService.
|
||||||
throw new SystemFontException(
|
*
|
||||||
FontManager.RESULT_ERROR_FONT_UPDATER_DISABLED,
|
* <p>CAUTION: this method is not safe. Existing processes may crash due to missing font files.
|
||||||
"The font updater is disabled.");
|
* This method is only for {@link FontManagerShellCommand}.
|
||||||
}
|
*/
|
||||||
synchronized (mUpdatableFontDirLock) {
|
/* package */ void clearUpdates() {
|
||||||
mUpdatableFontDir.clearUpdates();
|
UpdatableFontDir.deleteAllFiles(new File(FONT_FILES_DIR), new File(CONFIG_XML_FILE));
|
||||||
updateSerializedFontMap();
|
initialize();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Restarts FontManagerService, removing not-the-latest font files.
|
||||||
|
*
|
||||||
|
* <p>CAUTION: this method is not safe. Existing processes may crash due to missing font files.
|
||||||
|
* This method is only for {@link FontManagerShellCommand}.
|
||||||
|
*/
|
||||||
/* package */ void restart() {
|
/* package */ void restart() {
|
||||||
initialize();
|
initialize();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -448,7 +448,7 @@ public class FontManagerShellCommand extends ShellCommand {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private int clear(ShellCommand shell) throws SystemFontException {
|
private int clear(ShellCommand shell) {
|
||||||
mService.clearUpdates();
|
mService.clearUpdates();
|
||||||
shell.getOutPrintWriter().println("Success");
|
shell.getOutPrintWriter().println("Success");
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@@ -59,8 +59,6 @@ final class UpdatableFontDir {
|
|||||||
private static final String TAG = "UpdatableFontDir";
|
private static final String TAG = "UpdatableFontDir";
|
||||||
private static final String RANDOM_DIR_PREFIX = "~~";
|
private static final String RANDOM_DIR_PREFIX = "~~";
|
||||||
|
|
||||||
private static final String CONFIG_XML_FILE = "/data/fonts/config/config.xml";
|
|
||||||
|
|
||||||
/** Interface to mock font file access in tests. */
|
/** Interface to mock font file access in tests. */
|
||||||
interface FontFileParser {
|
interface FontFileParser {
|
||||||
String getPostScriptName(File file) throws IOException;
|
String getPostScriptName(File file) throws IOException;
|
||||||
@@ -139,8 +137,9 @@ final class UpdatableFontDir {
|
|||||||
*/
|
*/
|
||||||
private final ArrayMap<String, FontFileInfo> mFontFileInfoMap = new ArrayMap<>();
|
private final ArrayMap<String, FontFileInfo> mFontFileInfoMap = new ArrayMap<>();
|
||||||
|
|
||||||
UpdatableFontDir(File filesDir, FontFileParser parser, FsverityUtil fsverityUtil) {
|
UpdatableFontDir(File filesDir, FontFileParser parser, FsverityUtil fsverityUtil,
|
||||||
this(filesDir, parser, fsverityUtil, new File(CONFIG_XML_FILE),
|
File configFile) {
|
||||||
|
this(filesDir, parser, fsverityUtil, configFile,
|
||||||
System::currentTimeMillis,
|
System::currentTimeMillis,
|
||||||
(map) -> SystemFonts.getSystemFontConfig(map, 0, 0)
|
(map) -> SystemFonts.getSystemFontConfig(map, 0, 0)
|
||||||
);
|
);
|
||||||
@@ -215,17 +214,6 @@ final class UpdatableFontDir {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* package */ void clearUpdates() throws SystemFontException {
|
|
||||||
mFontFileInfoMap.clear();
|
|
||||||
FileUtils.deleteContents(mFilesDir);
|
|
||||||
|
|
||||||
mLastModifiedMillis = mCurrentTimeSupplier.get();
|
|
||||||
PersistentSystemFontConfig.Config config = new PersistentSystemFontConfig.Config();
|
|
||||||
config.lastModifiedMillis = mLastModifiedMillis;
|
|
||||||
writePersistentConfig(config);
|
|
||||||
mConfigVersion++;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Applies multiple {@link FontUpdateRequest}s in transaction.
|
* Applies multiple {@link FontUpdateRequest}s in transaction.
|
||||||
* If one of the request fails, the fonts and config are rolled back to the previous state
|
* If one of the request fails, the fonts and config are rolled back to the previous state
|
||||||
@@ -616,4 +604,19 @@ final class UpdatableFontDir {
|
|||||||
}
|
}
|
||||||
return familyMap;
|
return familyMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* package */ static void deleteAllFiles(File filesDir, File configFile) {
|
||||||
|
// As this method is called in safe mode, try to delete all files even though an exception
|
||||||
|
// is thrown.
|
||||||
|
try {
|
||||||
|
new AtomicFile(configFile).delete();
|
||||||
|
} catch (Throwable t) {
|
||||||
|
Slog.w(TAG, "Failed to delete " + configFile);
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
FileUtils.deleteContents(filesDir);
|
||||||
|
} catch (Throwable t) {
|
||||||
|
Slog.w(TAG, "Failed to delete " + filesDir);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1793,7 +1793,7 @@ public final class SystemServer implements Dumpable {
|
|||||||
t.traceEnd();
|
t.traceEnd();
|
||||||
|
|
||||||
t.traceBegin("StartFontManagerService");
|
t.traceBegin("StartFontManagerService");
|
||||||
mSystemServiceManager.startService(FontManagerService.Lifecycle.class);
|
mSystemServiceManager.startService(new FontManagerService.Lifecycle(context, safeMode));
|
||||||
t.traceEnd();
|
t.traceEnd();
|
||||||
|
|
||||||
t.traceBegin("StartTextServicesManager");
|
t.traceBegin("StartTextServicesManager");
|
||||||
|
|||||||
@@ -947,6 +947,24 @@ public final class UpdatableFontDirTest {
|
|||||||
assertThat(updated).isNotEqualTo(firstFontFamily);
|
assertThat(updated).isNotEqualTo(firstFontFamily);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void deleteAllFiles() throws Exception {
|
||||||
|
FakeFontFileParser parser = new FakeFontFileParser();
|
||||||
|
FakeFsverityUtil fakeFsverityUtil = new FakeFsverityUtil();
|
||||||
|
UpdatableFontDir dirForPreparation = new UpdatableFontDir(
|
||||||
|
mUpdatableFontFilesDir, parser, fakeFsverityUtil,
|
||||||
|
mConfigFile, mCurrentTimeSupplier, mConfigSupplier);
|
||||||
|
dirForPreparation.loadFontFileMap();
|
||||||
|
dirForPreparation.update(Collections.singletonList(
|
||||||
|
newFontUpdateRequest("foo.ttf,1,foo", GOOD_SIGNATURE)));
|
||||||
|
assertThat(mConfigFile.exists()).isTrue();
|
||||||
|
assertThat(mUpdatableFontFilesDir.list()).hasLength(1);
|
||||||
|
|
||||||
|
UpdatableFontDir.deleteAllFiles(mUpdatableFontFilesDir, mConfigFile);
|
||||||
|
assertThat(mConfigFile.exists()).isFalse();
|
||||||
|
assertThat(mUpdatableFontFilesDir.list()).hasLength(0);
|
||||||
|
}
|
||||||
|
|
||||||
private FontUpdateRequest newFontUpdateRequest(String content, String signature)
|
private FontUpdateRequest newFontUpdateRequest(String content, String signature)
|
||||||
throws Exception {
|
throws Exception {
|
||||||
File file = File.createTempFile("font", "ttf", mCacheDir);
|
File file = File.createTempFile("font", "ttf", mCacheDir);
|
||||||
|
|||||||
Reference in New Issue
Block a user