summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--core/java/android/widget/NumberPicker.java2
-rw-r--r--core/java/com/android/internal/app/LocalePicker.java3
-rw-r--r--core/java/com/android/internal/content/NativeLibraryHelper.java24
-rw-r--r--libs/androidfw/AssetManager.cpp57
-rw-r--r--packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java48
-rwxr-xr-xservices/java/com/android/server/pm/PackageManagerService.java45
6 files changed, 132 insertions, 47 deletions
diff --git a/core/java/android/widget/NumberPicker.java b/core/java/android/widget/NumberPicker.java
index 26c5732..7f6823d 100644
--- a/core/java/android/widget/NumberPicker.java
+++ b/core/java/android/widget/NumberPicker.java
@@ -59,7 +59,7 @@ import java.util.List;
import java.util.Locale;
/**
- * A widget that enables the user to select a number form a predefined range.
+ * A widget that enables the user to select a number from a predefined range.
* There are two flavors of this widget and which one is presented to the user
* depends on the current theme.
* <ul>
diff --git a/core/java/com/android/internal/app/LocalePicker.java b/core/java/com/android/internal/app/LocalePicker.java
index 6973615..f5c498a 100644
--- a/core/java/com/android/internal/app/LocalePicker.java
+++ b/core/java/com/android/internal/app/LocalePicker.java
@@ -131,7 +131,8 @@ public class LocalePicker extends ListFragment {
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())) {
+ if (l == null || "und".equals(l.getLanguage())
+ || l.getLanguage().isEmpty() || l.getCountry().isEmpty()) {
continue;
}
diff --git a/core/java/com/android/internal/content/NativeLibraryHelper.java b/core/java/com/android/internal/content/NativeLibraryHelper.java
index dab3aff..832829d 100644
--- a/core/java/com/android/internal/content/NativeLibraryHelper.java
+++ b/core/java/com/android/internal/content/NativeLibraryHelper.java
@@ -19,6 +19,7 @@ package com.android.internal.content;
import android.content.pm.PackageManager;
import android.util.Slog;
+import java.io.Closeable;
import java.io.File;
import java.io.IOException;
@@ -39,20 +40,29 @@ public class NativeLibraryHelper {
*
* @hide
*/
- public static class ApkHandle {
+ public static class ApkHandle implements Closeable {
final String apkPath;
final long apkHandle;
- public ApkHandle(String path) {
- apkPath = path;
- apkHandle = nativeOpenApk(apkPath);
+ public static ApkHandle create(String path) throws IOException {
+ final long handle = nativeOpenApk(path);
+ if (handle == 0) {
+ throw new IOException("Unable to open APK: " + path);
+ }
+
+ return new ApkHandle(path, handle);
+ }
+
+ public static ApkHandle create(File path) throws IOException {
+ return create(path.getAbsolutePath());
}
- public ApkHandle(File apkFile) {
- apkPath = apkFile.getPath();
- apkHandle = nativeOpenApk(apkPath);
+ private ApkHandle(String apkPath, long apkHandle) {
+ this.apkPath = apkPath;
+ this.apkHandle = apkHandle;
}
+ @Override
public void close() {
nativeClose(apkHandle);
}
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 @@ void AssetManager::setLocale(const char* locale)
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 @@ void AssetManager::setLocaleLocked(const char* locale)
//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 @@ void AssetManager::getLocales(Vector<String8>* locales) const
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/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java b/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java
index ec87c6e..16a0d35 100644
--- a/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java
+++ b/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java
@@ -49,6 +49,7 @@ import android.util.Slog;
import com.android.internal.app.IMediaContainerService;
import com.android.internal.content.NativeLibraryHelper;
+import com.android.internal.content.NativeLibraryHelper.ApkHandle;
import com.android.internal.content.PackageHelper;
import java.io.BufferedInputStream;
@@ -106,8 +107,27 @@ public class DefaultContainerService extends IntentService {
return null;
}
- return copyResourceInner(packageURI, cid, key, resFileName, publicResFileName,
- isExternal, isForwardLocked, abiOverride);
+
+ if (isExternal) {
+ // Make sure the sdcard is mounted.
+ String status = Environment.getExternalStorageState();
+ if (!status.equals(Environment.MEDIA_MOUNTED)) {
+ Slog.w(TAG, "Make sure sdcard is mounted.");
+ return null;
+ }
+ }
+
+ ApkHandle handle = null;
+ try {
+ handle = ApkHandle.create(packageURI.getPath());
+ return copyResourceInner(packageURI, cid, key, resFileName, publicResFileName,
+ isExternal, isForwardLocked, handle, abiOverride);
+ } catch (IOException ioe) {
+ Slog.w(TAG, "Problem opening APK: " + packageURI.getPath());
+ return null;
+ } finally {
+ IoUtils.closeQuietly(handle);
+ }
}
/**
@@ -328,21 +348,11 @@ public class DefaultContainerService extends IntentService {
private String copyResourceInner(Uri packageURI, String newCid, String key, String resFileName,
String publicResFileName, boolean isExternal, boolean isForwardLocked,
- String abiOverride) {
-
- if (isExternal) {
- // Make sure the sdcard is mounted.
- String status = Environment.getExternalStorageState();
- if (!status.equals(Environment.MEDIA_MOUNTED)) {
- Slog.w(TAG, "Make sure sdcard is mounted.");
- return null;
- }
- }
-
+ ApkHandle handle, String abiOverride) {
// The .apk file
String codePath = packageURI.getPath();
File codeFile = new File(codePath);
- NativeLibraryHelper.ApkHandle handle = new NativeLibraryHelper.ApkHandle(codePath);
+
String[] abiList = Build.SUPPORTED_ABIS;
if (abiOverride != null) {
abiList = new String[] { abiOverride };
@@ -849,14 +859,14 @@ public class DefaultContainerService extends IntentService {
private int calculateContainerSize(File apkFile, boolean forwardLocked,
String abiOverride) throws IOException {
- NativeLibraryHelper.ApkHandle handle = new NativeLibraryHelper.ApkHandle(apkFile);
- final int abi = NativeLibraryHelper.findSupportedAbi(handle,
- (abiOverride != null) ? new String[] { abiOverride } : Build.SUPPORTED_ABIS);
-
+ ApkHandle handle = null;
try {
+ handle = ApkHandle.create(apkFile);
+ final int abi = NativeLibraryHelper.findSupportedAbi(handle,
+ (abiOverride != null) ? new String[] { abiOverride } : Build.SUPPORTED_ABIS);
return calculateContainerSize(handle, apkFile, abi, forwardLocked);
} finally {
- handle.close();
+ IoUtils.closeQuietly(handle);
}
}
diff --git a/services/java/com/android/server/pm/PackageManagerService.java b/services/java/com/android/server/pm/PackageManagerService.java
index 2d5e357..273813d 100755
--- a/services/java/com/android/server/pm/PackageManagerService.java
+++ b/services/java/com/android/server/pm/PackageManagerService.java
@@ -5019,8 +5019,9 @@ public class PackageManagerService extends IPackageManager.Stub {
* only for non-system apps and system app upgrades.
*/
if (pkg.applicationInfo.nativeLibraryDir != null) {
- final NativeLibraryHelper.ApkHandle handle = new NativeLibraryHelper.ApkHandle(scanFile);
+ ApkHandle handle = null;
try {
+ handle = ApkHandle.create(scanFile.getPath());
// Enable gross and lame hacks for apps that are built with old
// SDK tools. We must scan their APKs for renderscript bitcode and
// not launch them if it's present. Don't bother checking on devices
@@ -5135,7 +5136,7 @@ public class PackageManagerService extends IPackageManager.Stub {
} catch (IOException ioe) {
Slog.e(TAG, "Unable to get canonical file " + ioe.toString());
} finally {
- handle.close();
+ IoUtils.closeQuietly(handle);
}
}
pkg.mScanPath = path;
@@ -8768,10 +8769,11 @@ public class PackageManagerService extends IPackageManager.Stub {
nativeLibraryFile.delete();
}
- final NativeLibraryHelper.ApkHandle handle = new NativeLibraryHelper.ApkHandle(codeFile);
String[] abiList = (abiOverride != null) ?
new String[] { abiOverride } : Build.SUPPORTED_ABIS;
+ ApkHandle handle = null;
try {
+ handle = ApkHandle.create(codeFile);
if (Build.SUPPORTED_64_BIT_ABIS.length > 0 &&
abiOverride == null &&
NativeLibraryHelper.hasRenderscriptBitcode(handle)) {
@@ -8786,7 +8788,7 @@ public class PackageManagerService extends IPackageManager.Stub {
Slog.e(TAG, "Copying native libraries failed", e);
ret = PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
} finally {
- handle.close();
+ IoUtils.closeQuietly(handle);
}
return ret;
@@ -12229,23 +12231,30 @@ public class PackageManagerService extends IPackageManager.Stub {
final File newNativeDir = new File(newNativePath);
if (!isForwardLocked(pkg) && !isExternal(pkg)) {
- // NOTE: We do not report any errors from the APK scan and library
- // copy at this point.
- NativeLibraryHelper.ApkHandle handle =
- new NativeLibraryHelper.ApkHandle(newCodePath);
- final int abi = NativeLibraryHelper.findSupportedAbi(
- handle, Build.SUPPORTED_ABIS);
- if (abi >= 0) {
- NativeLibraryHelper.copyNativeBinariesIfNeededLI(
- handle, newNativeDir, Build.SUPPORTED_ABIS[abi]);
+ ApkHandle handle = null;
+ try {
+ handle = ApkHandle.create(newCodePath);
+ final int abi = NativeLibraryHelper.findSupportedAbi(
+ handle, Build.SUPPORTED_ABIS);
+ if (abi >= 0) {
+ NativeLibraryHelper.copyNativeBinariesIfNeededLI(
+ handle, newNativeDir, Build.SUPPORTED_ABIS[abi]);
+ }
+ } catch (IOException ioe) {
+ Slog.w(TAG, "Unable to extract native libs for package :"
+ + mp.packageName, ioe);
+ returnCode = PackageManager.MOVE_FAILED_INTERNAL_ERROR;
+ } finally {
+ IoUtils.closeQuietly(handle);
}
- handle.close();
}
final int[] users = sUserManager.getUserIds();
- for (int user : users) {
- if (mInstaller.linkNativeLibraryDirectory(pkg.packageName,
- newNativePath, user) < 0) {
- returnCode = PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE;
+ if (returnCode == PackageManager.MOVE_SUCCEEDED) {
+ for (int user : users) {
+ if (mInstaller.linkNativeLibraryDirectory(pkg.packageName,
+ newNativePath, user) < 0) {
+ returnCode = PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE;
+ }
}
}