Merge "Fix native crashes when APKs can't be opened."
diff --git a/core/java/com/android/internal/app/LocalePicker.java b/core/java/com/android/internal/app/LocalePicker.java
index 043964f..6973615 100644
--- a/core/java/com/android/internal/app/LocalePicker.java
+++ b/core/java/com/android/internal/app/LocalePicker.java
@@ -37,6 +37,8 @@
import java.text.Collator;
import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
import java.util.Locale;
import java.util.ArrayList;
@@ -108,8 +110,9 @@
final int layoutId, final int fieldId, final boolean isInDeveloperMode) {
final Resources resources = context.getResources();
- ArrayList<String> localeList = new ArrayList<String>(Arrays.asList(
- Resources.getSystem().getAssets().getLocales()));
+ String[] locales = Resources.getSystem().getAssets().getLocales();
+ List<String> localeList = new ArrayList<String>(locales.length);
+ Collections.addAll(localeList, locales);
if (isInDeveloperMode) {
if (!localeList.contains("zz_ZZ")) {
localeList.add("zz_ZZ");
@@ -120,78 +123,61 @@
* }
*/
}
- String[] locales = new String[localeList.size()];
- locales = localeList.toArray(locales);
+ Collections.sort(localeList);
final String[] specialLocaleCodes = resources.getStringArray(R.array.special_locale_codes);
final String[] specialLocaleNames = resources.getStringArray(R.array.special_locale_names);
- Arrays.sort(locales);
- final int origSize = locales.length;
- final LocaleInfo[] preprocess = new LocaleInfo[origSize];
- int finalSize = 0;
- for (int i = 0 ; i < origSize; i++ ) {
- final String s = locales[i];
- final int len = s.length();
- if (len == 5) {
- String language = s.substring(0, 2);
- String country = s.substring(3, 5);
- final Locale l = new Locale(language, country);
- if (finalSize == 0) {
+ final ArrayList<LocaleInfo> localeInfos = new ArrayList<LocaleInfo>(localeList.size());
+ for (String locale : localeList) {
+ final Locale l = Locale.forLanguageTag(locale.replace('_', '-'));
+ if (l == null || "und".equals(l.getLanguage())) {
+ continue;
+ }
+
+ if (localeInfos.isEmpty()) {
+ if (DEBUG) {
+ Log.v(TAG, "adding initial "+ toTitleCase(l.getDisplayLanguage(l)));
+ }
+ localeInfos.add(new LocaleInfo(toTitleCase(l.getDisplayLanguage(l)), l));
+ } else {
+ // check previous entry:
+ // same lang and a country -> upgrade to full name and
+ // insert ours with full name
+ // diff lang -> insert ours with lang-only name
+ final LocaleInfo previous = localeInfos.get(localeInfos.size() - 1);
+ if (previous.locale.getLanguage().equals(l.getLanguage()) &&
+ !previous.locale.getLanguage().equals("zz")) {
if (DEBUG) {
- Log.v(TAG, "adding initial "+ toTitleCase(l.getDisplayLanguage(l)));
+ Log.v(TAG, "backing up and fixing " + previous.label + " to " +
+ getDisplayName(previous.locale, specialLocaleCodes, specialLocaleNames));
}
- preprocess[finalSize++] =
- new LocaleInfo(toTitleCase(l.getDisplayLanguage(l)), l);
+ previous.label = toTitleCase(getDisplayName(
+ previous.locale, specialLocaleCodes, specialLocaleNames));
+ if (DEBUG) {
+ Log.v(TAG, " and adding "+ toTitleCase(
+ getDisplayName(l, specialLocaleCodes, specialLocaleNames)));
+ }
+ localeInfos.add(new LocaleInfo(toTitleCase(
+ getDisplayName(l, specialLocaleCodes, specialLocaleNames)), l));
} else {
- // check previous entry:
- // same lang and a country -> upgrade to full name and
- // insert ours with full name
- // diff lang -> insert ours with lang-only name
- if (preprocess[finalSize-1].locale.getLanguage().equals(
- language) &&
- !preprocess[finalSize-1].locale.getLanguage().equals("zz")) {
- if (DEBUG) {
- Log.v(TAG, "backing up and fixing "+
- preprocess[finalSize-1].label+" to "+
- getDisplayName(preprocess[finalSize-1].locale,
- specialLocaleCodes, specialLocaleNames));
- }
- preprocess[finalSize-1].label = toTitleCase(
- getDisplayName(preprocess[finalSize-1].locale,
- specialLocaleCodes, specialLocaleNames));
- if (DEBUG) {
- Log.v(TAG, " and adding "+ toTitleCase(
- getDisplayName(l, specialLocaleCodes, specialLocaleNames)));
- }
- preprocess[finalSize++] =
- new LocaleInfo(toTitleCase(
- getDisplayName(
- l, specialLocaleCodes, specialLocaleNames)), l);
+ String displayName;
+ if (locale.equals("zz_ZZ")) {
+ displayName = "[Developer] Accented English";
+ } else if (locale.equals("zz_ZY")) {
+ displayName = "[Developer] Fake Bi-Directional";
} else {
- String displayName;
- if (s.equals("zz_ZZ")) {
- displayName = "[Developer] Accented English";
- } else if (s.equals("zz_ZY")) {
- displayName = "[Developer] Fake Bi-Directional";
- } else {
- displayName = toTitleCase(l.getDisplayLanguage(l));
- }
- if (DEBUG) {
- Log.v(TAG, "adding "+displayName);
- }
- preprocess[finalSize++] = new LocaleInfo(displayName, l);
+ displayName = toTitleCase(l.getDisplayLanguage(l));
}
+ if (DEBUG) {
+ Log.v(TAG, "adding "+displayName);
+ }
+ localeInfos.add(new LocaleInfo(displayName, l));
}
}
}
- final LocaleInfo[] localeInfos = new LocaleInfo[finalSize];
- for (int i = 0; i < finalSize; i++) {
- localeInfos[i] = preprocess[i];
- }
- Arrays.sort(localeInfos);
-
+ Collections.sort(localeInfos);
final LayoutInflater inflater =
(LayoutInflater)context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
return new ArrayAdapter<LocaleInfo>(context, layoutId, fieldId, localeInfos) {
diff --git a/core/jni/AndroidRuntime.cpp b/core/jni/AndroidRuntime.cpp
index a61901b..e8caa0c1 100644
--- a/core/jni/AndroidRuntime.cpp
+++ b/core/jni/AndroidRuntime.cpp
@@ -391,8 +391,8 @@
property_get("ro.product.locale.language", propLang, "en");
property_get("ro.product.locale.region", propRegn, "US");
}
- strncat(language, propLang, 2);
- strncat(region, propRegn, 2);
+ strncat(language, propLang, 3);
+ strncat(region, propRegn, 3);
//ALOGD("language=%s region=%s\n", language, region);
}
@@ -490,6 +490,8 @@
char profile_backoff[sizeof("-Xprofile-backoff:") + PROPERTY_VALUE_MAX];
char profile_top_k_threshold[sizeof("-Xprofile-top-k-threshold:") + PROPERTY_VALUE_MAX];
char profile_top_k_change_threshold[sizeof("-Xprofile-top-k-change-threshold:") + PROPERTY_VALUE_MAX];
+ char profile_type[sizeof("-Xprofile-type:") + PROPERTY_VALUE_MAX];
+ char profile_max_stack_depth[sizeof("-Xprofile-max-stack-depth:")+PROPERTY_VALUE_MAX];
char langOption[sizeof("-Duser.language=") + 3];
char regionOption[sizeof("-Duser.region=") + 3];
char lockProfThresholdBuf[sizeof("-Xlockprofthreshold:") + sizeof(propBuf)];
@@ -872,6 +874,20 @@
opt.optionString = profile_top_k_change_threshold;
mOptions.add(opt);
}
+
+ // Type of profile data.
+ strcpy(profile_type, "-Xprofile-type:");
+ if (property_get("dalvik.vm.profiler.type", profile_type+15, NULL) > 0) {
+ opt.optionString = profile_type;
+ mOptions.add(opt);
+ }
+
+ // Depth of bounded stack data
+ strcpy(profile_max_stack_depth, "-Xprofile-max-stack-depth:");
+ if (property_get("dalvik.vm.profile.max-stack-depth", profile_max_stack_depth+26, NULL) > 0) {
+ opt.optionString = profile_max_stack_depth;
+ mOptions.add(opt);
+ }
}
initArgs.version = JNI_VERSION_1_4;
diff --git a/libs/androidfw/AssetManager.cpp b/libs/androidfw/AssetManager.cpp
index 87164ca..482dfc8 100644
--- a/libs/androidfw/AssetManager.cpp
+++ b/libs/androidfw/AssetManager.cpp
@@ -347,6 +347,15 @@
setLocaleLocked(locale);
}
+
+static const char kFilPrefix[] = "fil";
+static const char kTlPrefix[] = "tl";
+
+// The sizes of the prefixes, excluding the 0 suffix.
+// char.
+static const int kFilPrefixLen = sizeof(kFilPrefix) - 1;
+static const int kTlPrefixLen = sizeof(kTlPrefix) - 1;
+
void AssetManager::setLocaleLocked(const char* locale)
{
if (mLocale != NULL) {
@@ -355,8 +364,44 @@
//mZipSet.purgeLocale();
delete[] mLocale;
}
- mLocale = strdupNew(locale);
+
+ // If we're attempting to set a locale that starts with "fil",
+ // we should convert it to "tl" for backwards compatibility since
+ // we've been using "tl" instead of "fil" prior to L.
+ //
+ // If the resource table already has entries for "fil", we use that
+ // instead of attempting a fallback.
+ if (strncmp(locale, kFilPrefix, kFilPrefixLen) == 0) {
+ Vector<String8> locales;
+ getLocales(&locales);
+ const size_t localesSize = locales.size();
+ bool hasFil = false;
+ for (size_t i = 0; i < localesSize; ++i) {
+ if (locales[i].find(kFilPrefix) == 0) {
+ hasFil = true;
+ break;
+ }
+ }
+
+
+ if (!hasFil) {
+ const size_t newLocaleLen = strlen(locale);
+ // This isn't a bug. We really do want mLocale to be 1 byte
+ // shorter than locale, because we're replacing "fil-" with
+ // "tl-".
+ mLocale = new char[newLocaleLen];
+ // Copy over "tl".
+ memcpy(mLocale, kTlPrefix, kTlPrefixLen);
+ // Copy the rest of |locale|, including the terminating '\0'.
+ memcpy(mLocale + kTlPrefixLen, locale + kFilPrefixLen,
+ newLocaleLen - kFilPrefixLen + 1);
+ updateResourceParamsLocked();
+ return;
+ }
+ }
+
+ mLocale = strdupNew(locale);
updateResourceParamsLocked();
}
@@ -741,6 +786,16 @@
if (res != NULL) {
res->getLocales(locales);
}
+
+ const size_t numLocales = locales->size();
+ for (size_t i = 0; i < numLocales; ++i) {
+ const String8& localeStr = locales->itemAt(i);
+ if (localeStr.find(kTlPrefix) == 0) {
+ String8 replaced("fil");
+ replaced += (localeStr.string() + kTlPrefixLen);
+ locales->editItemAt(i) = replaced;
+ }
+ }
}
/*
diff --git a/libs/androidfw/ResourceTypes.cpp b/libs/androidfw/ResourceTypes.cpp
index 2c828c1e..2f3b1f7 100644
--- a/libs/androidfw/ResourceTypes.cpp
+++ b/libs/androidfw/ResourceTypes.cpp
@@ -1597,9 +1597,9 @@
out[0] = in[0];
out[1] = in[1];
} else {
- uint8_t first = (in[0] - base) & 0x00ef;
- uint8_t second = (in[1] - base) & 0x00ef;
- uint8_t third = (in[2] - base) & 0x00ef;
+ uint8_t first = (in[0] - base) & 0x007f;
+ uint8_t second = (in[1] - base) & 0x007f;
+ uint8_t third = (in[2] - base) & 0x007f;
out[0] = (0x80 | (third << 2) | (second >> 3));
out[1] = ((second << 5) | first);
diff --git a/libs/androidfw/tests/ResourceTypes_test.cpp b/libs/androidfw/tests/ResourceTypes_test.cpp
index 4888b4a..139f868 100644
--- a/libs/androidfw/tests/ResourceTypes_test.cpp
+++ b/libs/androidfw/tests/ResourceTypes_test.cpp
@@ -75,6 +75,30 @@
EXPECT_EQ(0, out[3]);
}
+TEST(ResourceTypesTest, ResourceConfig_packAndUnpack3LetterLanguageAtOffset16) {
+ ResTable_config config;
+ config.packLanguage("tgp");
+
+ // We had a bug where we would accidentally mask
+ // the 5th bit of both bytes
+ //
+ // packed[0] = 1011 1100
+ // packed[1] = 1101 0011
+ //
+ // which is equivalent to:
+ // 1 [0] [1] [2]
+ // 1-01111-00110-10011
+ EXPECT_EQ(0xbc, config.language[0]);
+ EXPECT_EQ(0xd3, config.language[1]);
+
+ char out[4] = { 1, 1, 1, 1};
+ config.unpackLanguage(out);
+ EXPECT_EQ('t', out[0]);
+ EXPECT_EQ('g', out[1]);
+ EXPECT_EQ('p', out[2]);
+ EXPECT_EQ(0, out[3]);
+}
+
TEST(ResourceTypesTest, ResourceConfig_packAndUnpack3LetterRegion) {
ResTable_config config;
config.packRegion("419");
diff --git a/media/java/android/media/MediaScanner.java b/media/java/android/media/MediaScanner.java
index 06a8f4c..4599bd6 100644
--- a/media/java/android/media/MediaScanner.java
+++ b/media/java/android/media/MediaScanner.java
@@ -1184,6 +1184,7 @@
HashSet<String> existingFiles = new HashSet<String>();
String directory = "/sdcard/DCIM/.thumbnails";
String [] files = (new File(directory)).list();
+ Cursor c = null;
if (files == null)
files = new String[0];
@@ -1193,7 +1194,7 @@
}
try {
- Cursor c = mMediaProvider.query(
+ c = mMediaProvider.query(
mPackageName,
mThumbsUri,
new String [] { "_data" },
@@ -1218,11 +1219,12 @@
}
Log.v(TAG, "/pruneDeadThumbnailFiles... " + c);
+ } catch (RemoteException e) {
+ // We will soon be killed...
+ } finally {
if (c != null) {
c.close();
}
- } catch (RemoteException e) {
- // We will soon be killed...
}
}
diff --git a/services/java/com/android/server/pm/SELinuxMMAC.java b/services/java/com/android/server/pm/SELinuxMMAC.java
index c78249b..81302b9 100644
--- a/services/java/com/android/server/pm/SELinuxMMAC.java
+++ b/services/java/com/android/server/pm/SELinuxMMAC.java
@@ -346,31 +346,21 @@
*/
public static boolean assignSeinfoValue(PackageParser.Package pkg) {
- /*
- * Non system installed apps should be treated the same. This
- * means that any post-loaded apk will be assigned the default
- * tag, if one exists in the policy, else null, without respect
- * to the signing key.
- */
- if (((pkg.applicationInfo.flags & ApplicationInfo.FLAG_SYSTEM) != 0) ||
- ((pkg.applicationInfo.flags & ApplicationInfo.FLAG_UPDATED_SYSTEM_APP) != 0)) {
+ // We just want one of the signatures to match.
+ for (Signature s : pkg.mSignatures) {
+ if (s == null)
+ continue;
- // We just want one of the signatures to match.
- for (Signature s : pkg.mSignatures) {
- if (s == null)
- continue;
+ Policy policy = sSigSeinfo.get(s);
+ if (policy != null) {
+ String seinfo = policy.checkPolicy(pkg.packageName);
+ if (seinfo != null) {
+ pkg.applicationInfo.seinfo = seinfo;
+ if (DEBUG_POLICY_INSTALL)
+ Slog.i(TAG, "package (" + pkg.packageName +
+ ") labeled with seinfo=" + seinfo);
- Policy policy = sSigSeinfo.get(s);
- if (policy != null) {
- String seinfo = policy.checkPolicy(pkg.packageName);
- if (seinfo != null) {
- pkg.applicationInfo.seinfo = seinfo;
- if (DEBUG_POLICY_INSTALL)
- Slog.i(TAG, "package (" + pkg.packageName +
- ") labeled with seinfo=" + seinfo);
-
- return true;
- }
+ return true;
}
}
}