Merge "Use language tags to store Configuration's locale list." into qt-dev
am: 6dfa267f91
Change-Id: Ia7f30abab7396bc36eb2d69990129143601b028b
This commit is contained in:
@@ -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);
|
||||
@@ -1283,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 {
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user