Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 7c4e5a69 authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "Clear updated font files in safe mode." into sc-dev

parents 673a8c59 d18a901b
Loading
Loading
Loading
Loading
+29 −17
Original line number Diff line number Diff line
@@ -62,6 +62,7 @@ public final class FontManagerService extends IFontManager.Stub {
    private static final String TAG = "FontManagerService";

    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)
    @Override
@@ -130,9 +131,9 @@ public final class FontManagerService extends IFontManager.Stub {
    public static final class Lifecycle extends SystemService {
        private final FontManagerService mService;

        public Lifecycle(@NonNull Context context) {
        public Lifecycle(@NonNull Context context, boolean safeMode) {
            super(context);
            mService = new FontManagerService(context);
            mService = new FontManagerService(context, safeMode);
        }

        @Override
@@ -187,18 +188,24 @@ public final class FontManagerService extends IFontManager.Stub {
    @Nullable
    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;
        mUpdatableFontDir = createUpdatableFontDir();
        mUpdatableFontDir = createUpdatableFontDir(safeMode);
        initialize();
    }

    @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 (!VerityUtils.isFsVeritySupported()) return null;
        return new UpdatableFontDir(new File(FONT_FILES_DIR),
                new OtfFontFileParser(), new FsverityUtilImpl());
        return new UpdatableFontDir(new File(FONT_FILES_DIR), new OtfFontFileParser(),
                new FsverityUtilImpl(), new File(CONFIG_XML_FILE));
    }

    private void initialize() {
@@ -243,18 +250,23 @@ public final class FontManagerService extends IFontManager.Stub {
        }
    }

    /* package */ void clearUpdates() throws SystemFontException {
        if (mUpdatableFontDir == null) {
            throw new SystemFontException(
                    FontManager.RESULT_ERROR_FONT_UPDATER_DISABLED,
                    "The font updater is disabled.");
        }
        synchronized (mUpdatableFontDirLock) {
            mUpdatableFontDir.clearUpdates();
            updateSerializedFontMap();
        }
    /**
     * Clears all updates and restarts FontManagerService.
     *
     * <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 clearUpdates() {
        UpdatableFontDir.deleteAllFiles(new File(FONT_FILES_DIR), new File(CONFIG_XML_FILE));
        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() {
        initialize();
    }
+1 −1
Original line number Diff line number Diff line
@@ -448,7 +448,7 @@ public class FontManagerShellCommand extends ShellCommand {
        }
    }

    private int clear(ShellCommand shell) throws SystemFontException {
    private int clear(ShellCommand shell) {
        mService.clearUpdates();
        shell.getOutPrintWriter().println("Success");
        return 0;
+18 −15
Original line number Diff line number Diff line
@@ -59,8 +59,6 @@ final class UpdatableFontDir {
    private static final String TAG = "UpdatableFontDir";
    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 FontFileParser {
        String getPostScriptName(File file) throws IOException;
@@ -139,8 +137,9 @@ final class UpdatableFontDir {
     */
    private final ArrayMap<String, FontFileInfo> mFontFileInfoMap = new ArrayMap<>();

    UpdatableFontDir(File filesDir, FontFileParser parser, FsverityUtil fsverityUtil) {
        this(filesDir, parser, fsverityUtil, new File(CONFIG_XML_FILE),
    UpdatableFontDir(File filesDir, FontFileParser parser, FsverityUtil fsverityUtil,
            File configFile) {
        this(filesDir, parser, fsverityUtil, configFile,
                System::currentTimeMillis,
                (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.
     * 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;
    }

    /* 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);
        }
    }
}
+1 −1
Original line number Diff line number Diff line
@@ -1793,7 +1793,7 @@ public final class SystemServer implements Dumpable {
            t.traceEnd();

            t.traceBegin("StartFontManagerService");
            mSystemServiceManager.startService(FontManagerService.Lifecycle.class);
            mSystemServiceManager.startService(new FontManagerService.Lifecycle(context, safeMode));
            t.traceEnd();

            t.traceBegin("StartTextServicesManager");
+18 −0
Original line number Diff line number Diff line
@@ -947,6 +947,24 @@ public final class UpdatableFontDirTest {
        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)
            throws Exception {
        File file = File.createTempFile("font", "ttf", mCacheDir);