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

Commit fb483cc9 authored by Clara Bayarri's avatar Clara Bayarri
Browse files

XML Support for non system font providers

The certs needed to identify non preinstalled providers
can now be declared in XML, using a resources array.

Test: runtest --path frameworks/base/core/tests/coretests/src/android/provider/FontsContractTest.java
runtest --path frameworks/base/core/tests/coretests/src/android/content/res/FontResourcesParserTest.java
Bug: 35025705
Change-Id: Ibf12ad409aa5a873ddb32b1383c147728e664c23
parent c0e002b4
Loading
Loading
Loading
Loading
+1 −0
Original line number Diff line number Diff line
@@ -608,6 +608,7 @@ package android {
    field public static final int fontFamily = 16843692; // 0x10103ac
    field public static final int fontFeatureSettings = 16843959; // 0x10104b7
    field public static final int fontProviderAuthority = 16844114; // 0x1010552
    field public static final int fontProviderCerts = 16844128; // 0x1010560
    field public static final int fontProviderPackage = 16844122; // 0x101055a
    field public static final int fontProviderQuery = 16844115; // 0x1010553
    field public static final int fontStyle = 16844095; // 0x101053f
+1 −0
Original line number Diff line number Diff line
@@ -721,6 +721,7 @@ package android {
    field public static final int fontFamily = 16843692; // 0x10103ac
    field public static final int fontFeatureSettings = 16843959; // 0x10104b7
    field public static final int fontProviderAuthority = 16844114; // 0x1010552
    field public static final int fontProviderCerts = 16844128; // 0x1010560
    field public static final int fontProviderPackage = 16844122; // 0x101055a
    field public static final int fontProviderQuery = 16844115; // 0x1010553
    field public static final int fontStyle = 16844095; // 0x101053f
+1 −0
Original line number Diff line number Diff line
@@ -608,6 +608,7 @@ package android {
    field public static final int fontFamily = 16843692; // 0x10103ac
    field public static final int fontFeatureSettings = 16843959; // 0x10104b7
    field public static final int fontProviderAuthority = 16844114; // 0x1010552
    field public static final int fontProviderCerts = 16844128; // 0x1010560
    field public static final int fontProviderPackage = 16844122; // 0x101055a
    field public static final int fontProviderQuery = 16844115; // 0x1010553
    field public static final int fontStyle = 16844095; // 0x101053f
+30 −2
Original line number Diff line number Diff line
@@ -26,6 +26,7 @@ import org.xmlpull.v1.XmlPullParserException;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
@@ -44,12 +45,14 @@ public class FontResourcesParser {
        private final @NonNull String mProviderAuthority;
        private final @NonNull String mProviderPackage;
        private final @NonNull String mQuery;
        private final @Nullable List<List<String>> mCerts;

        public ProviderResourceEntry(@NonNull String authority, @NonNull String pkg,
                @NonNull String query) {
                @NonNull String query, @Nullable List<List<String>> certs) {
            mProviderAuthority = authority;
            mProviderPackage = pkg;
            mQuery = query;
            mCerts = certs;
        }

        public @NonNull String getAuthority() {
@@ -63,6 +66,10 @@ public class FontResourcesParser {
        public @NonNull String getQuery() {
            return mQuery;
        }

        public @Nullable List<List<String>> getCerts() {
            return mCerts;
        }
    }

    // A class represents font element in xml file which points a file in resource.
@@ -144,12 +151,33 @@ public class FontResourcesParser {
        String authority = array.getString(R.styleable.FontFamily_fontProviderAuthority);
        String providerPackage = array.getString(R.styleable.FontFamily_fontProviderPackage);
        String query = array.getString(R.styleable.FontFamily_fontProviderQuery);
        int certsId = array.getResourceId(R.styleable.FontFamily_fontProviderCerts, 0);
        array.recycle();
        if (authority != null && providerPackage != null && query != null) {
            while (parser.next() != XmlPullParser.END_TAG) {
                skip(parser);
            }
            return new ProviderResourceEntry(authority, providerPackage, query);
            List<List<String>> certs = null;
            if (certsId != 0) {
                TypedArray typedArray = resources.obtainTypedArray(certsId);
                if (typedArray.length() > 0) {
                    certs = new ArrayList<>();
                    boolean isArrayOfArrays = typedArray.getResourceId(0, 0) != 0;
                    if (isArrayOfArrays) {
                        for (int i = 0; i < typedArray.length(); i++) {
                            int certId = typedArray.getResourceId(i, 0);
                            String[] certsArray = resources.getStringArray(certId);
                            List<String> certsList = Arrays.asList(certsArray);
                            certs.add(certsList);
                        }
                    } else {
                        String[] certsArray = resources.getStringArray(certsId);
                        List<String> certsList = Arrays.asList(certsArray);
                        certs.add(certsList);
                    }
                }
            }
            return new ProviderResourceEntry(authority, providerPackage, query, certs);
        }
        List<FontFileResourceEntry> fonts = new ArrayList<>();
        while (parser.next() != XmlPullParser.END_TAG) {
+36 −15
Original line number Diff line number Diff line
@@ -15,7 +15,6 @@
 */
package android.provider;

import android.app.ActivityThread;
import android.content.ContentResolver;
import android.content.ContentUris;
import android.content.Context;
@@ -42,9 +41,10 @@ import com.android.internal.annotations.VisibleForTesting;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Set;

/**
 * Utility class to deal with Font ContentProviders.
@@ -207,11 +207,12 @@ public class FontsContract {
            return info;
        }

        Set<byte[]> signatures;
        List<byte[]> signatures;
        try {
            PackageInfo packageInfo = mPackageManager.getPackageInfo(info.packageName,
                    PackageManager.GET_SIGNATURES);
            signatures = convertToSet(packageInfo.signatures);
            signatures = convertToByteArrayList(packageInfo.signatures);
            Collections.sort(signatures, sByteArrayComparator);
        } catch (PackageManager.NameNotFoundException e) {
            Log.e(TAG, "Can't find content provider " + providerAuthority, e);
            receiver.send(RESULT_CODE_PROVIDER_NOT_FOUND, null);
@@ -219,8 +220,10 @@ public class FontsContract {
        }
        List<List<byte[]>> requestCertificatesList = request.getCertificates();
        for (int i = 0; i < requestCertificatesList.size(); ++i) {
            final Set<byte[]> requestCertificates = convertToSet(requestCertificatesList.get(i));
            if (signatures.equals(requestCertificates)) {
            // Make a copy so we can sort it without modifying the incoming data.
            List<byte[]> requestSignatures = new ArrayList<>(requestCertificatesList.get(i));
            Collections.sort(requestSignatures, sByteArrayComparator);
            if (equalsByteArrayList(signatures, requestSignatures)) {
                return info;
            }
        }
@@ -229,17 +232,35 @@ public class FontsContract {
        return null;
    }

    private Set<byte[]> convertToSet(Signature[] signatures) {
        Set<byte[]> shas = new HashSet<>();
        for (int i = 0; i < signatures.length; ++i) {
            shas.add(signatures[i].toByteArray());
    private static final Comparator<byte[]> sByteArrayComparator = (l, r) -> {
        if (l.length != r.length) {
            return l.length - r.length;
        }
        for (int i = 0; i < l.length; ++i) {
            if (l[i] != r[i]) {
                return l[i] - r[i];
            }
        return shas;
        }
        return 0;
    };

    private Set<byte[]> convertToSet(List<byte[]> certs) {
        Set<byte[]> shas = new HashSet<>();
        shas.addAll(certs);
    private boolean equalsByteArrayList(List<byte[]> signatures, List<byte[]> requestSignatures) {
        if (signatures.size() != requestSignatures.size()) {
            return false;
        }
        for (int i = 0; i < signatures.size(); ++i) {
            if (!Arrays.equals(signatures.get(i), requestSignatures.get(i))) {
                return false;
            }
        }
        return true;
    }

    private List<byte[]> convertToByteArrayList(Signature[] signatures) {
        List<byte[]> shas = new ArrayList<>();
        for (int i = 0; i < signatures.length; ++i) {
            shas.add(signatures[i].toByteArray());
        }
        return shas;
    }

Loading