summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorandroid-build-team Robot <android-build-team-robot@google.com>2019-09-16 20:56:48 +0000
committerandroid-build-team Robot <android-build-team-robot@google.com>2019-09-16 20:56:48 +0000
commit5960d27c445abd8617349db1a2a9702c3b139c4b (patch)
treeded3b995a05f70e990b62f31617a100dfb3b1307
parent5fd590d32d91ac237513a502f55fdae926edea14 (diff)
parent57213b0ce51506a3a70e1eebbdae8134affae133 (diff)
downloadbase-android10-s2-release.tar.gz
Merge cherrypicks of [9399564, 9400400, 9399396, 9399397, 9400257] into qt-releaseandroid-10.0.0_r5android-10.0.0_r4android10-s2-release
Change-Id: Ie48954405cdc2d6e49f4534b81145b46cc2598fc
-rw-r--r--core/java/android/content/res/Configuration.java21
-rw-r--r--core/java/android/os/LocaleList.java22
-rw-r--r--core/proto/android/content/configuration.proto3
-rw-r--r--core/proto/android/content/locale.proto1
-rw-r--r--core/tests/coretests/src/android/content/res/ConfigurationTest.java79
5 files changed, 101 insertions, 25 deletions
diff --git a/core/java/android/content/res/Configuration.java b/core/java/android/content/res/Configuration.java
index 861ae7ba122e..ac1cbd4619df 100644
--- a/core/java/android/content/res/Configuration.java
+++ b/core/java/android/content/res/Configuration.java
@@ -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();
- list.add(locale);
+ // 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 {
diff --git a/core/java/android/os/LocaleList.java b/core/java/android/os/LocaleList.java
index 7782753e4abc..0de09efad8ea 100644
--- a/core/java/android/os/LocaleList.java
+++ b/core/java/android/os/LocaleList.java
@@ -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;
@@ -143,26 +141,6 @@ public final class LocaleList implements Parcelable {
}
/**
- * 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.
*/
@NonNull
diff --git a/core/proto/android/content/configuration.proto b/core/proto/android/content/configuration.proto
index 57ced09240f2..7fa0ff64f8bf 100644
--- a/core/proto/android/content/configuration.proto
+++ b/core/proto/android/content/configuration.proto
@@ -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;
}
/**
diff --git a/core/proto/android/content/locale.proto b/core/proto/android/content/locale.proto
index bae6ec141981..a8f2a1334038 100644
--- a/core/proto/android/content/locale.proto
+++ b/core/proto/android/content/locale.proto
@@ -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;
diff --git a/core/tests/coretests/src/android/content/res/ConfigurationTest.java b/core/tests/coretests/src/android/content/res/ConfigurationTest.java
index 2fc3e36e7948..ad97ff101cb0 100644
--- a/core/tests/coretests/src/android/content/res/ConfigurationTest.java
+++ b/core/tests/coretests/src/android/content/res/ConfigurationTest.java
@@ -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);
+ }
+ }
+ }
+ }
}