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

Commit 019d9d0b authored by Xin Li's avatar Xin Li Committed by Gerrit Code Review
Browse files

Merge "DO NOT MERGE - Merge QP1A.191005.007 into master"

parents 85de0791 8efb8c35
Loading
Loading
Loading
Loading
+19 −2
Original line number Diff line number Diff line
@@ -23,6 +23,7 @@ import static android.content.ConfigurationProto.HARD_KEYBOARD_HIDDEN;
import static android.content.ConfigurationProto.KEYBOARD;
import static android.content.ConfigurationProto.KEYBOARD_HIDDEN;
import static android.content.ConfigurationProto.LOCALES;
import static android.content.ConfigurationProto.LOCALE_LIST;
import static android.content.ConfigurationProto.MCC;
import static android.content.ConfigurationProto.MNC;
import static android.content.ConfigurationProto.NAVIGATION;
@@ -1111,7 +1112,7 @@ public final class Configuration implements Parcelable, Comparable<Configuration
            protoOutputStream.write(MCC, mcc);
            protoOutputStream.write(MNC, mnc);
            if (mLocaleList != null) {
                mLocaleList.writeToProto(protoOutputStream, LOCALES);
                protoOutputStream.write(LOCALE_LIST, mLocaleList.toLanguageTags());
            }
            protoOutputStream.write(SCREEN_LAYOUT, screenLayout);
            protoOutputStream.write(COLOR_MODE, colorMode);
@@ -1222,7 +1223,15 @@ public final class Configuration implements Parcelable, Comparable<Configuration
                                                        .setVariant(variant)
                                                        .setScript(script)
                                                        .build();
                                // Log a WTF here if a repeated locale is found to avoid throwing an
                                // exception in system server when LocaleList is created below
                                final int inListIndex = list.indexOf(locale);
                                if (inListIndex != -1) {
                                    Slog.wtf(TAG, "Repeated locale (" + list.get(inListIndex) + ")"
                                            + " found when trying to add: " + locale.toString());
                                } else {
                                    list.add(locale);
                                }
                            } catch (IllformedLocaleException e) {
                                Slog.e(TAG, "readFromProto error building locale with: "
                                        + "language-" + language + ";country-" + country
@@ -1275,6 +1284,14 @@ public final class Configuration implements Parcelable, Comparable<Configuration
                    case (int) WINDOW_CONFIGURATION:
                        windowConfiguration.readFromProto(protoInputStream, WINDOW_CONFIGURATION);
                        break;
                    case (int) LOCALE_LIST:
                        try {
                            setLocales(LocaleList.forLanguageTags(protoInputStream.readString(
                                    LOCALE_LIST)));
                        } catch (Exception e) {
                            Slog.e(TAG, "error parsing locale list in configuration.", e);
                        }
                        break;
                }
            }
        } finally {
+0 −22
Original line number Diff line number Diff line
@@ -21,9 +21,7 @@ import android.annotation.NonNull;
import android.annotation.Nullable;
import android.annotation.Size;
import android.annotation.UnsupportedAppUsage;
import android.content.LocaleProto;
import android.icu.util.ULocale;
import android.util.proto.ProtoOutputStream;

import com.android.internal.annotations.GuardedBy;

@@ -142,26 +140,6 @@ public final class LocaleList implements Parcelable {
        dest.writeString(mStringRepresentation);
    }

    /**
     * Helper to write LocaleList to a protocol buffer output stream.  Assumes the parent
     * protobuf has declared the locale as repeated.
     *
     * @param protoOutputStream Stream to write the locale to.
     * @param fieldId Field Id of the Locale as defined in the parent message.
     * @hide
     */
    public void writeToProto(ProtoOutputStream protoOutputStream, long fieldId) {
        for (int i = 0; i < mList.length; i++) {
            final Locale locale = mList[i];
            final long token = protoOutputStream.start(fieldId);
            protoOutputStream.write(LocaleProto.LANGUAGE, locale.getLanguage());
            protoOutputStream.write(LocaleProto.COUNTRY, locale.getCountry());
            protoOutputStream.write(LocaleProto.VARIANT, locale.getVariant());
            protoOutputStream.write(LocaleProto.SCRIPT, locale.getScript());
            protoOutputStream.end(token);
        }
    }

    /**
     * Retrieves a String representation of the language tags in this list.
     */
+2 −1
Original line number Diff line number Diff line
@@ -32,7 +32,7 @@ message ConfigurationProto {
    optional float font_scale = 1;
    optional uint32 mcc = 2;
    optional uint32 mnc = 3 [ (.android.privacy).dest = DEST_EXPLICIT ];
    repeated LocaleProto locales = 4;
    repeated LocaleProto locales = 4 [deprecated = true];
    optional uint32 screen_layout = 5;
    optional uint32 color_mode = 6;
    optional uint32 touchscreen = 7;
@@ -48,6 +48,7 @@ message ConfigurationProto {
    optional uint32 smallest_screen_width_dp = 17;
    optional uint32 density_dpi = 18;
    optional .android.app.WindowConfigurationProto window_configuration = 19;
    optional string locale_list = 20;
}

/**
+1 −0
Original line number Diff line number Diff line
@@ -22,6 +22,7 @@ import "frameworks/base/core/proto/android/privacy.proto";
package android.content;

message LocaleProto {
    option deprecated = true;
    option (.android.msg_privacy).dest = DEST_AUTOMATIC;

    optional string language = 1;
+79 −0
Original line number Diff line number Diff line
@@ -16,16 +16,29 @@

package android.content.res;

import android.content.Context;
import android.os.LocaleList;
import android.platform.test.annotations.Presubmit;
import android.util.AtomicFile;
import android.util.proto.ProtoInputStream;
import android.util.proto.ProtoOutputStream;

import androidx.test.InstrumentationRegistry;
import androidx.test.filters.SmallTest;

import com.android.server.usage.IntervalStatsProto;

import junit.framework.TestCase;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.JUnit4;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.util.Locale;

/**
 * Build/install/run: bit FrameworksCoreTests:android.content.res.ConfigurationTest
 */
@@ -54,4 +67,70 @@ public class ConfigurationTest extends TestCase {
        config2.updateFrom(config);
        assertEquals(config2.screenLayout, Configuration.SCREENLAYOUT_COMPAT_NEEDED);
    }

    @Test
    public void testReadWriteProto() throws Exception {
        final Context context = InstrumentationRegistry.getTargetContext();
        final File testDir = new File(context.getFilesDir(), "ConfigurationTest");
        testDir.mkdirs();
        final File proto = new File(testDir, "configs");
        if (proto.exists()) {
            proto.delete();
        }

        final Locale arabic = new Locale.Builder().setLocale(new Locale("ar", "AE")).build();
        final Locale urdu = new Locale.Builder().setLocale(new Locale("ur", "IN")).build();
        final Locale urduExtension = new Locale.Builder().setLocale(new Locale("ur", "IN"))
                .setExtension('u', "nu-latn").build();
        Configuration write = new Configuration();
        write.setLocales(new LocaleList(arabic, urdu, urduExtension));
        writeToProto(proto, write);
        assertTrue("Failed to write configs to proto.", proto.exists());

        final Configuration read = new Configuration();
        try {
            readFromProto(proto, read);
        } finally {
            proto.delete();
        }

        assertEquals("Missing locales in proto file written to disk.",
                read.getLocales().size(), write.getLocales().size());
        assertTrue("Arabic locale not found in Configuration locale list.",
                read.getLocales().indexOf(arabic) != -1);
        assertTrue("Urdu locale not found in Configuration locale list.",
                read.getLocales().indexOf(urdu) != -1);
        assertTrue("Urdu locale with extensions not found in Configuration locale list.",
                read.getLocales().indexOf(urduExtension) != -1);
    }

    private void writeToProto(File f, Configuration config) throws Exception {
        final AtomicFile af = new AtomicFile(f);
        FileOutputStream fos = af.startWrite();
        try {
            final ProtoOutputStream protoOut = new ProtoOutputStream(fos);
            final long token = protoOut.start(IntervalStatsProto.CONFIGURATIONS);
            config.writeToProto(protoOut, IntervalStatsProto.Configuration.CONFIG, false, false);
            protoOut.end(token);
            protoOut.flush();
            af.finishWrite(fos);
            fos = null;
        } finally {
            af.failWrite(fos);
        }
    }

    private void readFromProto(File f, Configuration config) throws Exception {
        final AtomicFile afRead = new AtomicFile(f);
        try (FileInputStream in = afRead.openRead()) {
            final ProtoInputStream protoIn = new ProtoInputStream(in);
            if (protoIn.isNextField(IntervalStatsProto.CONFIGURATIONS)) {
                final long token = protoIn.start(IntervalStatsProto.CONFIGURATIONS);
                if (protoIn.isNextField(IntervalStatsProto.Configuration.CONFIG)) {
                    config.readFromProto(protoIn, IntervalStatsProto.Configuration.CONFIG);
                    protoIn.end(token);
                }
            }
        }
    }
}
Loading