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

Commit 88ae1a2d authored by Kohsuke Yatoh's avatar Kohsuke Yatoh
Browse files

Do not crash if setSystemFont is called twice.

ActivityThread.mBoundApplication has @UnsupportedAppUsage, so apps can
re-send BIND_APPLICATION message with the same AppBindData by using
reflection.

Bug: 174969232
Test: manually tested with the test app in the bug
Change-Id: Ic96d670f6346d9d1373607b4ae6e78b78194a09c
parent 7cb30de8
Loading
Loading
Loading
Loading
+17 −2
Original line number Diff line number Diff line
@@ -25,6 +25,7 @@ import android.annotation.IntDef;
import android.annotation.IntRange;
import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.UiThread;
import android.compat.annotation.UnsupportedAppUsage;
import android.content.res.AssetManager;
import android.graphics.fonts.Font;
@@ -149,8 +150,8 @@ public class Typeface {
    static final Map<String, Typeface> sSystemFontMap = new HashMap<>();

    // DirectByteBuffer object to hold sSystemFontMap's backing memory mapping.
    @GuardedBy("SYSTEM_FONT_MAP_LOCK")
    static ByteBuffer sSystemFontMapBuffer = null;
    static SharedMemory sSystemFontMapSharedMemory = null;

    // Lock to guard sSystemFontMap and derived default or public typefaces.
    // sStyledCacheLock may be held while this lock is held. Holding them in the reverse order may
@@ -1252,14 +1253,27 @@ public class Typeface {
     * per process.
     */
    /** @hide */
    public static void setSystemFontMap(SharedMemory sharedMemory)
    @UiThread
    public static void setSystemFontMap(@Nullable SharedMemory sharedMemory)
            throws IOException, ErrnoException {
        if (sSystemFontMapBuffer != null) {
            // Apps can re-send BIND_APPLICATION message from their code. This is a work around to
            // detect it and avoid crashing.
            if (sharedMemory == null || sharedMemory == sSystemFontMapSharedMemory) {
                return;
            }
            throw new UnsupportedOperationException(
                    "Once set, buffer-based system font map cannot be updated");
        }
        sSystemFontMapSharedMemory = sharedMemory;
        Trace.traceBegin(Trace.TRACE_TAG_GRAPHICS, "setSystemFontMap");
        try {
            if (sharedMemory == null) {
                // FontManagerService is not started. This may happen in FACTORY_TEST_LOW_LEVEL
                // mode for example.
                loadPreinstalledSystemFontMap();
                return;
            }
            sSystemFontMapBuffer = sharedMemory.mapReadOnly().order(ByteOrder.BIG_ENDIAN);
            Map<String, Typeface> systemFontMap = deserializeFontMap(sSystemFontMapBuffer);
            setSystemFontMap(systemFontMap);
@@ -1319,6 +1333,7 @@ public class Typeface {
                SharedMemory.unmap(sSystemFontMapBuffer);
            }
            sSystemFontMapBuffer = null;
            sSystemFontMapSharedMemory = null;
        }
    }