summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNarayan Kamath <narayan@google.com>2015-08-12 10:39:13 +0000
committerAndroid Git Automerger <android-git-automerger@android.com>2015-08-12 10:39:13 +0000
commit86b6d204a5321bf2874c2cbee3452e674605c21f (patch)
tree14ec31a6fb8e13120480f4a352586037c16aa232
parente950a4b22caaf849bfeb68768931e0e793877119 (diff)
parentbf88205bef88f78ade5c6830e6203aa343387820 (diff)
downloadframeworks_base-86b6d204a5321bf2874c2cbee3452e674605c21f.zip
frameworks_base-86b6d204a5321bf2874c2cbee3452e674605c21f.tar.gz
frameworks_base-86b6d204a5321bf2874c2cbee3452e674605c21f.tar.bz2
am bf88205b: Fall back to persist.sys.language/country if locale isn\'t set.
* commit 'bf88205bef88f78ade5c6830e6203aa343387820': Fall back to persist.sys.language/country if locale isn't set.
-rw-r--r--core/jni/AndroidRuntime.cpp86
-rw-r--r--services/java/com/android/server/SystemServer.java18
2 files changed, 77 insertions, 27 deletions
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index bae2cde..a3d5b8a 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -43,6 +43,9 @@
#include <dirent.h>
#include <assert.h>
+#include <string>
+#include <vector>
+
using namespace android;
@@ -357,38 +360,66 @@ static bool hasFile(const char* file) {
return false;
}
+// Convenience wrapper over the property API that returns an
+// std::string.
+std::string getProperty(const char* key, const char* defaultValue) {
+ std::vector<char> temp(PROPERTY_VALUE_MAX);
+ const int len = property_get(key, &temp[0], defaultValue);
+ if (len < 0) {
+ return "";
+ }
+ return std::string(&temp[0], len);
+}
+
/*
- * Read the persistent locale. Attempts to read to persist.sys.locale
- * and falls back to the default locale (ro.product.locale) if
- * persist.sys.locale is empty.
+ * Read the persistent locale. Inspects the following system properties
+ * (in order) and returns the first non-empty property in the list :
+ *
+ * (1) persist.sys.locale
+ * (2) persist.sys.language/country/localevar (country and localevar are
+ * inspected iff. language is non-empty.
+ * (3) ro.product.locale
+ * (4) ro.product.locale.language/region
+ *
+ * Note that we need to inspect persist.sys.language/country/localevar to
+ * preserve language settings for devices that are upgrading from Lollipop
+ * to M. The same goes for ro.product.locale.language/region as well.
*/
-static void readLocale(char* locale)
+const std::string readLocale()
{
- // Allocate 4 extra bytes because we might read a property into
- // this array at offset 4.
- char propLocale[PROPERTY_VALUE_MAX + 4];
-
- property_get("persist.sys.locale", propLocale, "");
- if (propLocale[0] == 0) {
- property_get("ro.product.locale", propLocale, "");
-
- if (propLocale[0] == 0) {
- // If persist.sys.locale and ro.product.locale are missing,
- // construct a locale value from the individual locale components.
- property_get("ro.product.locale.language", propLocale, "en");
-
- // The language code is either two or three chars in length. If it
- // isn't 2 chars long, assume three. Anything else is an error
- // anyway.
- const int offset = (propLocale[2] == 0) ? 2 : 3;
- propLocale[offset] = '-';
-
- property_get("ro.product.locale.region", propLocale + offset + 1, "US");
+ const std::string locale = getProperty("persist.sys.locale", "");
+ if (!locale.empty()) {
+ return locale;
+ }
+
+ const std::string language = getProperty("persist.sys.language", "");
+ if (!language.empty()) {
+ const std::string country = getProperty("persist.sys.country", "");
+ const std::string variant = getProperty("persist.sys.localevar", "");
+
+ std::string out = language;
+ if (!country.empty()) {
+ out = out + "-" + country;
+ }
+
+ if (!variant.empty()) {
+ out = out + "-" + variant;
}
+
+ return out;
}
- strncat(locale, propLocale, PROPERTY_VALUE_MAX);
- // ALOGD("[DEBUG] locale=%s", locale);
+ const std::string productLocale = getProperty("ro.product.locale", "");
+ if (!productLocale.empty()) {
+ return productLocale;
+ }
+
+ // If persist.sys.locale and ro.product.locale are missing,
+ // construct a locale value from the individual locale components.
+ const std::string productLanguage = getProperty("ro.product.locale.language", "en");
+ const std::string productRegion = getProperty("ro.product.locale.region", "US");
+
+ return productLanguage + "-" + productRegion;
}
void AndroidRuntime::addOption(const char* optionString, void* extraInfo)
@@ -793,7 +824,8 @@ int AndroidRuntime::startVm(JavaVM** pJavaVM, JNIEnv** pEnv)
/* Set the properties for locale */
{
strcpy(localeOption, "-Duser.locale=");
- readLocale(localeOption);
+ const std::string locale = readLocale();
+ strncat(localeOption, locale.c_str(), PROPERTY_VALUE_MAX);
addOption(localeOption);
}
diff --git a/services/java/com/android/server/SystemServer.java b/services/java/com/android/server/SystemServer.java
index 760c2dc..7dd16d1 100644
--- a/services/java/com/android/server/SystemServer.java
+++ b/services/java/com/android/server/SystemServer.java
@@ -95,6 +95,7 @@ import com.android.server.wm.WindowManagerService;
import dalvik.system.VMRuntime;
import java.io.File;
+import java.util.Locale;
import java.util.Timer;
import java.util.TimerTask;
@@ -182,6 +183,23 @@ public final class SystemServer {
SystemClock.setCurrentTimeMillis(EARLIEST_SUPPORTED_TIME);
}
+ // If the system has "persist.sys.language" and friends set, replace them with
+ // "persist.sys.locale". Note that the default locale at this point is calculated
+ // using the "-Duser.locale" command line flag. That flag is usually populated by
+ // AndroidRuntime using the same set of system properties, but only the system_server
+ // and system apps are allowed to set them.
+ //
+ // NOTE: Most changes made here will need an equivalent change to
+ // core/jni/AndroidRuntime.cpp
+ if (!SystemProperties.get("persist.sys.language").isEmpty()) {
+ final String languageTag = Locale.getDefault().toLanguageTag();
+
+ SystemProperties.set("persist.sys.locale", languageTag);
+ SystemProperties.set("persist.sys.language", "");
+ SystemProperties.set("persist.sys.country", "");
+ SystemProperties.set("persist.sys.localevar", "");
+ }
+
// Here we go!
Slog.i(TAG, "Entered the Android system server!");
EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_SYSTEM_RUN, SystemClock.uptimeMillis());