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

Commit 524c5a21 authored by Seigo Nonaka's avatar Seigo Nonaka Committed by Automerger Merge Worker
Browse files

Merge "Skip buffer equality check for SystemFonts" into sc-dev am: 9c16cc5a

Original change: https://googleplex-android-review.googlesource.com/c/platform/frameworks/base/+/14606651

Change-Id: Icc82cf516beeb190bdc784390edd293fb4984a61
parents c41f1ed3 9c16cc5a
Loading
Loading
Loading
Loading
+10 −7
Original line number Diff line number Diff line
@@ -801,6 +801,15 @@ public final class Font {
        return myBuffer.equals(otherBuffer);
    }

    /** @hide */
    public boolean paramEquals(@NonNull Font f) {
        return f.getStyle().equals(getStyle())
                && f.getTtcIndex() == getTtcIndex()
                && Arrays.equals(f.getAxes(), getAxes())
                && Objects.equals(f.getLocaleList(), getLocaleList())
                && Objects.equals(getFile(), f.getFile());
    }

    @Override
    public boolean equals(@Nullable Object o) {
        if (o == this) {
@@ -818,13 +827,7 @@ public final class Font {
            return true;
        }

        boolean paramEqual = f.getStyle().equals(getStyle())
                && f.getTtcIndex() == getTtcIndex()
                && Arrays.equals(f.getAxes(), getAxes())
                && Objects.equals(f.getLocaleList(), getLocaleList())
                && Objects.equals(getFile(), f.getFile());

        if (!paramEqual) {
        if (!paramEquals(f)) {
            return false;
        }

+42 −5
Original line number Diff line number Diff line
@@ -39,6 +39,7 @@ import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;

/**
@@ -46,7 +47,6 @@ import java.util.Set;
 */
public final class SystemFonts {
    private static final String TAG = "SystemFonts";
    private static final String DEFAULT_FAMILY = "sans-serif";

    private static final String FONTS_XML = "/system/etc/fonts.xml";
    /** @hide */
@@ -59,7 +59,36 @@ public final class SystemFonts {

    private static final Object LOCK = new Object();
    private static @GuardedBy("sLock") Set<Font> sAvailableFonts;
    private static @GuardedBy("sLock") Map<String, FontFamily[]> sFamilyMap;

    /**
     * Helper wrapper class for skipping buffer equality check of Font#equals.
     *
     * Due to historical reasons, the Font#equals checks the byte-by-byte buffer equality which
     * requires heavy IO work in getAvailableFonts. Since the fonts came from system are all regular
     * file backed font instance and stored in the unique place, just comparing file path should be
     * good enough for this case.
     */
    private static final class SystemFontHashWrapper {
        private final Font mFont;
        SystemFontHashWrapper(Font font) {
            mFont = font;
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (o == null || getClass() != o.getClass()) return false;

            // All system fonts are regular-file backed font instance, so no need to
            // compare buffers.
            return mFont.paramEquals(((SystemFontHashWrapper) o).mFont);
        }

        @Override
        public int hashCode() {
            return Objects.hash(mFont);
        }
    }

    /**
     * Returns all available font files in the system.
@@ -69,17 +98,25 @@ public final class SystemFonts {
    public static @NonNull Set<Font> getAvailableFonts() {
        synchronized (LOCK) {
            if (sAvailableFonts == null) {
                Set<Font> set = new ArraySet<>();
                Set<SystemFontHashWrapper> set = new ArraySet<>();
                for (Typeface tf : Typeface.getSystemFontMap().values()) {
                    List<FontFamily> families = tf.getFallback();
                    for (int i = 0; i < families.size(); ++i) {
                        FontFamily family = families.get(i);
                        for (int j = 0; j < family.getSize(); ++j) {
                            set.add(family.getFont(j));
                            set.add(new SystemFontHashWrapper(family.getFont(j)));
                        }
                    }
                }

                // Unwrapping font instance for Set<Font> interface. The ArraySet#add won't call
                // Font#equals function if none of two objects has the same hash, so following
                // unwrapping won't cause bad performance due to byte-by-byte equality check.
                ArraySet<Font> result = new ArraySet(set.size());
                for (SystemFontHashWrapper wrapper : set) {
                    result.add(wrapper.mFont);
                }
                sAvailableFonts = Collections.unmodifiableSet(set);
                sAvailableFonts = Collections.unmodifiableSet(result);
            }
            return sAvailableFonts;
        }