summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--core/java/android/content/pm/PackageParser.java165
-rw-r--r--core/java/android/os/FileUtils.java5
-rw-r--r--core/java/com/android/internal/content/NativeLibraryHelper.java140
-rw-r--r--packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java16
-rw-r--r--services/core/java/com/android/server/pm/PackageInstallerSession.java67
-rw-r--r--services/core/java/com/android/server/pm/PackageManagerService.java23
6 files changed, 256 insertions, 160 deletions
diff --git a/core/java/android/content/pm/PackageParser.java b/core/java/android/content/pm/PackageParser.java
index 319559a..a5290aa 100644
--- a/core/java/android/content/pm/PackageParser.java
+++ b/core/java/android/content/pm/PackageParser.java
@@ -227,6 +227,48 @@ public class PackageParser {
}
/**
+ * Lightweight parsed details about a single package.
+ */
+ public static class PackageLite {
+ public final String packageName;
+ public final int versionCode;
+
+ /** Names of any split APKs, ordered by parsed splitName */
+ public final String[] splitNames;
+
+ /**
+ * Path where this package was found on disk. For monolithic packages
+ * this is path to single base APK file; for cluster packages this is
+ * path to the cluster directory.
+ */
+ public final String codePath;
+
+ /** Path of base APK */
+ public final String baseCodePath;
+ /** Paths of any split APKs, ordered by parsed splitName */
+ public final String[] splitCodePaths;
+
+ private PackageLite(String packageName, int versionCode, String[] splitNames,
+ String codePath, String baseCodePath, String[] splitCodePaths) {
+ this.packageName = packageName;
+ this.versionCode = versionCode;
+ this.splitNames = splitNames;
+ this.codePath = codePath;
+ this.baseCodePath = baseCodePath;
+ this.splitCodePaths = splitCodePaths;
+ }
+
+ public List<String> getAllCodePaths() {
+ ArrayList<String> paths = new ArrayList<>();
+ paths.add(baseCodePath);
+ if (!ArrayUtils.isEmpty(splitCodePaths)) {
+ Collections.addAll(paths, splitCodePaths);
+ }
+ return paths;
+ }
+ }
+
+ /**
* Lightweight parsed details about a single APK file.
*/
public static class ApkLite {
@@ -279,12 +321,8 @@ public class PackageParser {
mMetrics = metrics;
}
- public static final boolean isPackageFilename(File file) {
- return isPackageFilename(file.getName());
- }
-
- public static final boolean isPackageFilename(String name) {
- return name.endsWith(".apk");
+ public static final boolean isApkFile(File file) {
+ return file.isFile() && file.getName().endsWith(".apk");
}
/*
@@ -543,17 +581,26 @@ public class PackageParser {
}
}
- /**
- * Parse all APKs contained in the given directory, treating them as a
- * single package. This also performs sanity checking, such as requiring
- * identical package name and version codes, a single base APK, and unique
- * split names.
- * <p>
- * Note that this <em>does not</em> perform signature verification; that
- * must be done separately in {@link #collectCertificates(Package, int)}.
- */
- public Package parseClusterPackage(File apkDir, int flags) throws PackageParserException {
- final File[] files = apkDir.listFiles();
+ public static PackageLite parsePackageLite(File packageFile, int flags)
+ throws PackageParserException {
+ if (packageFile.isDirectory()) {
+ return parseClusterPackageLite(packageFile, flags);
+ } else {
+ return parseMonolithicPackageLite(packageFile, flags);
+ }
+ }
+
+ private static PackageLite parseMonolithicPackageLite(File packageFile, int flags)
+ throws PackageParserException {
+ final ApkLite lite = parseApkLite(packageFile, flags);
+ final String packagePath = packageFile.getAbsolutePath();
+ return new PackageLite(lite.packageName, lite.versionCode, null,
+ packagePath, packagePath, null);
+ }
+
+ private static PackageLite parseClusterPackageLite(File packageDir, int flags)
+ throws PackageParserException {
+ final File[] files = packageDir.listFiles();
if (ArrayUtils.isEmpty(files)) {
throw new PackageParserException(INSTALL_PARSE_FAILED_NOT_APK,
"No packages found in split");
@@ -564,8 +611,8 @@ public class PackageParser {
final ArrayMap<String, File> apks = new ArrayMap<>();
for (File file : files) {
- if (file.isFile() && isPackageFilename(file)) {
- final ApkLite lite = parseApkLite(file, 0);
+ if (isApkFile(file)) {
+ final ApkLite lite = parseApkLite(file, flags);
// Assert that all package names and version codes are
// consistent with the first one we encounter.
@@ -594,29 +641,73 @@ public class PackageParser {
}
}
- final File baseFile = apks.remove(null);
- if (baseFile == null) {
+ final File baseApk = apks.remove(null);
+ if (baseApk == null) {
throw new PackageParserException(INSTALL_PARSE_FAILED_BAD_MANIFEST,
- "Missing base APK in " + apkDir);
+ "Missing base APK in " + packageDir);
+ }
+
+ // Always apply deterministic ordering based on splitName
+ final int size = apks.size();
+
+ String[] splitNames = null;
+ String[] splitCodePaths = null;
+ if (size > 0) {
+ splitNames = new String[size];
+ splitCodePaths = new String[size];
+
+ splitNames = apks.keySet().toArray(splitNames);
+ Arrays.sort(splitNames, sSplitNameComparator);
+
+ for (int i = 0; i < size; i++) {
+ splitCodePaths[i] = apks.get(splitNames[i]).getAbsolutePath();
+ }
}
- final Package pkg = parseBaseApk(baseFile, flags);
+ final String codePath = packageDir.getAbsolutePath();
+ final String baseCodePath = baseApk.getAbsolutePath();
+ return new PackageLite(packageName, versionCode, splitNames, codePath, baseCodePath,
+ splitCodePaths);
+ }
+
+ public Package parsePackage(File packageFile, int flags) throws PackageParserException {
+ if (packageFile.isDirectory()) {
+ return parseClusterPackage(packageFile, flags);
+ } else {
+ return parseMonolithicPackage(packageFile, flags);
+ }
+ }
+
+ /**
+ * Parse all APKs contained in the given directory, treating them as a
+ * single package. This also performs sanity checking, such as requiring
+ * identical package name and version codes, a single base APK, and unique
+ * split names.
+ * <p>
+ * Note that this <em>does not</em> perform signature verification; that
+ * must be done separately in {@link #collectCertificates(Package, int)}.
+ */
+ private Package parseClusterPackage(File packageDir, int flags) throws PackageParserException {
+ final PackageLite lite = parseClusterPackageLite(packageDir, 0);
+
+ final File baseApk = new File(lite.baseCodePath);
+ final Package pkg = parseBaseApk(baseApk, flags);
if (pkg == null) {
throw new PackageParserException(INSTALL_PARSE_FAILED_NOT_APK,
- "Failed to parse base APK: " + baseFile);
+ "Failed to parse base APK: " + baseApk);
}
- // Always apply deterministic ordering based on splitName
- final int size = apks.size();
- final String[] splitNames = apks.keySet().toArray(new String[size]);
- Arrays.sort(splitNames, sSplitNameComparator);
+ if (!ArrayUtils.isEmpty(lite.splitNames)) {
+ pkg.splitNames = lite.splitNames;
+ pkg.splitCodePaths = lite.splitCodePaths;
- for (String splitName : splitNames) {
- final File splitFile = apks.get(splitName);
- parseSplitApk(pkg, splitFile, splitName, flags);
+ for (String splitCodePath : lite.splitCodePaths) {
+ final File splitApk = new File(splitCodePath);
+ parseSplitApk(pkg, splitApk, flags);
+ }
}
- pkg.codePath = apkDir.getAbsolutePath();
+ pkg.codePath = packageDir.getAbsolutePath();
return pkg;
}
@@ -648,8 +739,7 @@ public class PackageParser {
mParseError = PackageManager.INSTALL_PARSE_FAILED_NOT_APK;
return null;
}
- if (!isPackageFilename(apkFile.getName())
- && (flags&PARSE_MUST_BE_APK) != 0) {
+ if (!isApkFile(apkFile) && (flags & PARSE_MUST_BE_APK) != 0) {
if ((flags&PARSE_IS_SYSTEM) == 0) {
// We expect to have non-.apk files in the system dir,
// so don't warn about them.
@@ -732,16 +822,11 @@ public class PackageParser {
return pkg;
}
- private void parseSplitApk(Package pkg, File apkFile, String splitName, int flags)
- throws PackageParserException {
+ private void parseSplitApk(Package pkg, File apkFile, int flags) throws PackageParserException {
final String splitCodePath = apkFile.getAbsolutePath();
mArchiveSourcePath = apkFile.getAbsolutePath();
// TODO: expand split APK parsing
- // TODO: extract splitName during parse
- pkg.splitNames = ArrayUtils.appendElement(String.class, pkg.splitNames, splitName);
- pkg.splitCodePaths = ArrayUtils.appendElement(String.class, pkg.splitCodePaths,
- splitCodePath);
}
/**
diff --git a/core/java/android/os/FileUtils.java b/core/java/android/os/FileUtils.java
index d5d5eb8..4c34d46 100644
--- a/core/java/android/os/FileUtils.java
+++ b/core/java/android/os/FileUtils.java
@@ -392,7 +392,10 @@ public class FileUtils {
if (file.isDirectory()) {
success &= deleteContents(file);
}
- success &= file.delete();
+ if (!file.delete()) {
+ Log.w(TAG, "Failed to delete " + file);
+ success = false;
+ }
}
}
return success;
diff --git a/core/java/com/android/internal/content/NativeLibraryHelper.java b/core/java/com/android/internal/content/NativeLibraryHelper.java
index 832829d..af0068e 100644
--- a/core/java/com/android/internal/content/NativeLibraryHelper.java
+++ b/core/java/com/android/internal/content/NativeLibraryHelper.java
@@ -16,12 +16,22 @@
package com.android.internal.content;
+import static android.content.pm.PackageManager.INSTALL_FAILED_NO_MATCHING_ABIS;
+import static android.content.pm.PackageManager.INSTALL_SUCCEEDED;
+import static android.content.pm.PackageManager.NO_NATIVE_LIBRARIES;
+
import android.content.pm.PackageManager;
+import android.content.pm.PackageParser;
+import android.content.pm.PackageParser.PackageLite;
+import android.content.pm.PackageParser.PackageParserException;
import android.util.Slog;
+import dalvik.system.CloseGuard;
+
import java.io.Closeable;
import java.io.File;
import java.io.IOException;
+import java.util.List;
/**
* Native libraries helper.
@@ -34,40 +44,72 @@ public class NativeLibraryHelper {
private static final boolean DEBUG_NATIVE = false;
/**
- * A handle to an opened APK. Used as input to the various NativeLibraryHelper
- * methods. Allows us to scan and parse the APK exactly once instead of doing
- * it multiple times.
+ * A handle to an opened package, consisting of one or more APKs. Used as
+ * input to the various NativeLibraryHelper methods. Allows us to scan and
+ * parse the APKs exactly once instead of doing it multiple times.
*
* @hide
*/
- public static class ApkHandle implements Closeable {
- final String apkPath;
- final long apkHandle;
-
- public static ApkHandle create(String path) throws IOException {
- final long handle = nativeOpenApk(path);
- if (handle == 0) {
- throw new IOException("Unable to open APK: " + path);
+ public static class Handle implements Closeable {
+ private final CloseGuard mGuard = CloseGuard.get();
+ private volatile boolean mClosed;
+
+ final long[] apkHandles;
+
+ public static Handle create(File packageFile) throws IOException {
+ final PackageLite lite;
+ try {
+ lite = PackageParser.parsePackageLite(packageFile, 0);
+ } catch (PackageParserException e) {
+ throw new IOException("Failed to parse package: " + packageFile, e);
}
- return new ApkHandle(path, handle);
- }
+ final List<String> codePaths = lite.getAllCodePaths();
+ final int size = codePaths.size();
+ final long[] apkHandles = new long[size];
+ for (int i = 0; i < size; i++) {
+ final String path = codePaths.get(i);
+ apkHandles[i] = nativeOpenApk(path);
+ if (apkHandles[i] == 0) {
+ // Unwind everything we've opened so far
+ for (int j = 0; j < i; j++) {
+ nativeClose(apkHandles[j]);
+ }
+ throw new IOException("Unable to open APK: " + path);
+ }
+ }
- public static ApkHandle create(File path) throws IOException {
- return create(path.getAbsolutePath());
+ return new Handle(apkHandles);
}
- private ApkHandle(String apkPath, long apkHandle) {
- this.apkPath = apkPath;
- this.apkHandle = apkHandle;
+ Handle(long[] apkHandles) {
+ this.apkHandles = apkHandles;
+ mGuard.open("close");
}
@Override
public void close() {
- nativeClose(apkHandle);
+ for (long apkHandle : apkHandles) {
+ nativeClose(apkHandle);
+ }
+ mGuard.close();
+ mClosed = true;
}
- }
+ @Override
+ protected void finalize() throws Throwable {
+ if (mGuard != null) {
+ mGuard.warnIfOpen();
+ }
+ try {
+ if (!mClosed) {
+ close();
+ }
+ } finally {
+ super.finalize();
+ }
+ }
+ }
private static native long nativeOpenApk(String path);
private static native void nativeClose(long handle);
@@ -79,8 +121,12 @@ public class NativeLibraryHelper {
*
* @return size of all native binary files in bytes
*/
- public static long sumNativeBinariesLI(ApkHandle handle, String abi) {
- return nativeSumNativeBinaries(handle.apkHandle, abi);
+ public static long sumNativeBinariesLI(Handle handle, String abi) {
+ long sum = 0;
+ for (long apkHandle : handle.apkHandles) {
+ sum += nativeSumNativeBinaries(apkHandle, abi);
+ }
+ return sum;
}
private native static int nativeCopyNativeBinaries(long handle,
@@ -94,9 +140,15 @@ public class NativeLibraryHelper {
* @return {@link PackageManager#INSTALL_SUCCEEDED} if successful or another
* error code from that class if not
*/
- public static int copyNativeBinariesIfNeededLI(ApkHandle handle, File sharedLibraryDir,
+ public static int copyNativeBinariesIfNeededLI(Handle handle, File sharedLibraryDir,
String abi) {
- return nativeCopyNativeBinaries(handle.apkHandle, sharedLibraryDir.getPath(), abi);
+ for (long apkHandle : handle.apkHandles) {
+ int res = nativeCopyNativeBinaries(apkHandle, sharedLibraryDir.getPath(), abi);
+ if (res != INSTALL_SUCCEEDED) {
+ return res;
+ }
+ }
+ return INSTALL_SUCCEEDED;
}
/**
@@ -106,8 +158,29 @@ public class NativeLibraryHelper {
* APK doesn't contain any native code, and
* {@link PackageManager#INSTALL_FAILED_NO_MATCHING_ABIS} if none of the ABIs match.
*/
- public static int findSupportedAbi(ApkHandle handle, String[] supportedAbis) {
- return nativeFindSupportedAbi(handle.apkHandle, supportedAbis);
+ public static int findSupportedAbi(Handle handle, String[] supportedAbis) {
+ int finalRes = NO_NATIVE_LIBRARIES;
+ for (long apkHandle : handle.apkHandles) {
+ final int res = nativeFindSupportedAbi(apkHandle, supportedAbis);
+ if (res == NO_NATIVE_LIBRARIES) {
+ // No native code, keep looking through all APKs.
+ } else if (res == INSTALL_FAILED_NO_MATCHING_ABIS) {
+ // Found some native code, but no ABI match; update our final
+ // result if we haven't found other valid code.
+ if (finalRes < 0) {
+ finalRes = INSTALL_FAILED_NO_MATCHING_ABIS;
+ }
+ } else if (res >= 0) {
+ // Found valid native code, track the best ABI match
+ if (finalRes < 0 || res < finalRes) {
+ finalRes = res;
+ }
+ } else {
+ // Unexpected error; bail
+ return res;
+ }
+ }
+ return finalRes;
}
private native static int nativeFindSupportedAbi(long handle, String[] supportedAbis);
@@ -156,13 +229,16 @@ public class NativeLibraryHelper {
// We don't care about the other return values for now.
private static final int BITCODE_PRESENT = 1;
- public static boolean hasRenderscriptBitcode(ApkHandle handle) throws IOException {
- final int returnVal = hasRenderscriptBitcode(handle.apkHandle);
- if (returnVal < 0) {
- throw new IOException("Error scanning APK, code: " + returnVal);
+ public static boolean hasRenderscriptBitcode(Handle handle) throws IOException {
+ for (long apkHandle : handle.apkHandles) {
+ final int res = hasRenderscriptBitcode(apkHandle);
+ if (res < 0) {
+ throw new IOException("Error scanning APK, code: " + res);
+ } else if (res == BITCODE_PRESENT) {
+ return true;
+ }
}
-
- return (returnVal == BITCODE_PRESENT);
+ return false;
}
private static native int hasRenderscriptBitcode(long apkHandle);
diff --git a/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java b/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java
index 74ff3b1..4a61f1f 100644
--- a/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java
+++ b/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java
@@ -48,7 +48,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.NativeLibraryHelper.Handle;
import com.android.internal.content.PackageHelper;
import libcore.io.IoUtils;
@@ -116,9 +116,9 @@ public class DefaultContainerService extends IntentService {
}
}
- ApkHandle handle = null;
+ Handle handle = null;
try {
- handle = ApkHandle.create(packagePath);
+ handle = Handle.create(new File(packagePath));
return copyResourceInner(packagePath, cid, key, resFileName, publicResFileName,
isExternal, isForwardLocked, handle, abiOverride);
} catch (IOException ioe) {
@@ -349,7 +349,7 @@ public class DefaultContainerService extends IntentService {
private String copyResourceInner(String packagePath, String newCid, String key, String resFileName,
String publicResFileName, boolean isExternal, boolean isForwardLocked,
- ApkHandle handle, String abiOverride) {
+ Handle handle, String abiOverride) {
// The .apk file
String codePath = packagePath;
File codeFile = new File(codePath);
@@ -834,9 +834,9 @@ public class DefaultContainerService extends IntentService {
private int calculateContainerSize(File apkFile, boolean forwardLocked,
String abiOverride) throws IOException {
- ApkHandle handle = null;
+ Handle handle = null;
try {
- handle = ApkHandle.create(apkFile);
+ handle = Handle.create(apkFile);
final int abi = NativeLibraryHelper.findSupportedAbi(handle,
(abiOverride != null) ? new String[] { abiOverride } : Build.SUPPORTED_ABIS);
return calculateContainerSize(handle, apkFile, abi, forwardLocked);
@@ -852,7 +852,7 @@ public class DefaultContainerService extends IntentService {
* @return size in megabytes (2^20 bytes)
* @throws IOException when there is a problem reading the file
*/
- private int calculateContainerSize(NativeLibraryHelper.ApkHandle apkHandle,
+ private int calculateContainerSize(NativeLibraryHelper.Handle handle,
File apkFile, int abiIndex, boolean forwardLocked) throws IOException {
// Calculate size of container needed to hold base APK.
long sizeBytes = apkFile.length();
@@ -863,7 +863,7 @@ public class DefaultContainerService extends IntentService {
// Check all the native files that need to be copied and add that to the
// container size.
if (abiIndex >= 0) {
- sizeBytes += NativeLibraryHelper.sumNativeBinariesLI(apkHandle,
+ sizeBytes += NativeLibraryHelper.sumNativeBinariesLI(handle,
Build.SUPPORTED_ABIS[abiIndex]);
}
diff --git a/services/core/java/com/android/server/pm/PackageInstallerSession.java b/services/core/java/com/android/server/pm/PackageInstallerSession.java
index 11e546f..c011cf9 100644
--- a/services/core/java/com/android/server/pm/PackageInstallerSession.java
+++ b/services/core/java/com/android/server/pm/PackageInstallerSession.java
@@ -20,7 +20,6 @@ import static android.content.pm.PackageManager.INSTALL_FAILED_ALREADY_EXISTS;
import static android.content.pm.PackageManager.INSTALL_FAILED_INTERNAL_ERROR;
import static android.content.pm.PackageManager.INSTALL_FAILED_INVALID_APK;
import static android.content.pm.PackageManager.INSTALL_FAILED_PACKAGE_CHANGED;
-import static android.content.pm.PackageManager.INSTALL_SUCCEEDED;
import android.content.pm.ApplicationInfo;
import android.content.pm.IPackageInstallObserver2;
@@ -31,7 +30,6 @@ import android.content.pm.PackageParser;
import android.content.pm.PackageParser.ApkLite;
import android.content.pm.PackageParser.PackageParserException;
import android.content.pm.Signature;
-import android.os.Build;
import android.os.Bundle;
import android.os.FileBridge;
import android.os.FileUtils;
@@ -40,7 +38,6 @@ import android.os.Looper;
import android.os.Message;
import android.os.ParcelFileDescriptor;
import android.os.RemoteException;
-import android.os.SELinux;
import android.os.UserHandle;
import android.system.ErrnoException;
import android.system.OsConstants;
@@ -48,11 +45,9 @@ import android.system.StructStat;
import android.util.ArraySet;
import android.util.Slog;
-import com.android.internal.content.NativeLibraryHelper;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.Preconditions;
-import libcore.io.IoUtils;
import libcore.io.Libcore;
import java.io.File;
@@ -110,7 +105,6 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
private Signature[] mSignatures;
private boolean mMutationsAllowed;
- private boolean mVerifierConfirmed;
private boolean mPermissionsConfirmed;
private boolean mInvalid;
@@ -238,21 +232,12 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
Preconditions.checkNotNull(mPackageName);
Preconditions.checkNotNull(mSignatures);
- if (!mVerifierConfirmed) {
- // TODO: async communication with verifier
- // when they confirm, we'll kick off another install() pass
- mVerifierConfirmed = true;
- }
-
if (!mPermissionsConfirmed) {
// TODO: async confirm permissions with user
// when they confirm, we'll kick off another install() pass
mPermissionsConfirmed = true;
}
- // Unpack any native libraries contained in this session
- unpackNativeLibraries();
-
// Inherit any packages and native libraries from existing install that
// haven't been overridden.
if (!params.fullInstall) {
@@ -425,58 +410,6 @@ public class PackageInstallerSession extends IPackageInstallerSession.Stub {
}
}
- private void unpackNativeLibraries() throws InstallFailedException {
- final File libDir = new File(sessionDir, "lib");
-
- if (!libDir.mkdir()) {
- throw new InstallFailedException(INSTALL_FAILED_INTERNAL_ERROR,
- "Failed to create " + libDir);
- }
-
- try {
- Libcore.os.chmod(libDir.getAbsolutePath(), 0755);
- } catch (ErrnoException e) {
- throw new InstallFailedException(INSTALL_FAILED_INTERNAL_ERROR,
- "Failed to prepare " + libDir + ": " + e);
- }
-
- if (!SELinux.restorecon(libDir)) {
- throw new InstallFailedException(INSTALL_FAILED_INTERNAL_ERROR,
- "Failed to set context on " + libDir);
- }
-
- // Unpack all native libraries under stage
- final File[] files = sessionDir.listFiles();
- if (ArrayUtils.isEmpty(files)) {
- throw new InstallFailedException(INSTALL_FAILED_INVALID_APK, "No packages staged");
- }
-
- for (File file : files) {
- NativeLibraryHelper.ApkHandle handle = null;
- try {
- handle = NativeLibraryHelper.ApkHandle.create(file);
- final int abiIndex = NativeLibraryHelper.findSupportedAbi(handle,
- Build.SUPPORTED_ABIS);
- if (abiIndex >= 0) {
- int copyRet = NativeLibraryHelper.copyNativeBinariesIfNeededLI(handle, libDir,
- Build.SUPPORTED_ABIS[abiIndex]);
- if (copyRet != INSTALL_SUCCEEDED) {
- throw new InstallFailedException(copyRet,
- "Failed to copy native libraries for " + file);
- }
- } else if (abiIndex != PackageManager.NO_NATIVE_LIBRARIES) {
- throw new InstallFailedException(abiIndex,
- "Failed to copy native libraries for " + file);
- }
- } catch (IOException ioe) {
- throw new InstallFailedException(INSTALL_FAILED_INTERNAL_ERROR,
- "Failed to create handle for " + file);
- } finally {
- IoUtils.closeQuietly(handle);
- }
- }
- }
-
@Override
public void destroy() {
try {
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java
index 91f119d..27b4843 100644
--- a/services/core/java/com/android/server/pm/PackageManagerService.java
+++ b/services/core/java/com/android/server/pm/PackageManagerService.java
@@ -24,7 +24,7 @@ import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED
import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_UNTIL_USED;
import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_DISABLED_USER;
import static android.content.pm.PackageManager.COMPONENT_ENABLED_STATE_ENABLED;
-import static android.content.pm.PackageParser.isPackageFilename;
+import static android.content.pm.PackageParser.isApkFile;
import static android.os.Process.PACKAGE_INFO_GID;
import static android.os.Process.SYSTEM_UID;
import static android.system.OsConstants.S_IRGRP;
@@ -42,7 +42,6 @@ import com.android.internal.R;
import com.android.internal.app.IMediaContainerService;
import com.android.internal.app.ResolverActivity;
import com.android.internal.content.NativeLibraryHelper;
-import com.android.internal.content.NativeLibraryHelper.ApkHandle;
import com.android.internal.content.PackageHelper;
import com.android.internal.util.ArrayUtils;
import com.android.internal.util.FastPrintWriter;
@@ -4096,7 +4095,7 @@ public class PackageManagerService extends IPackageManager.Stub {
}
for (File file : files) {
- if (!isPackageFilename(file)) {
+ if (!isApkFile(file)) {
// Ignore entries which are not apk's
continue;
}
@@ -5358,10 +5357,9 @@ public class PackageManagerService extends IPackageManager.Stub {
* only for non-system apps and system app upgrades.
*/
if (pkg.applicationInfo.nativeLibraryDir != null) {
- // TODO: extend to extract native code from split APKs
- ApkHandle handle = null;
+ NativeLibraryHelper.Handle handle = null;
try {
- handle = ApkHandle.create(scanFile.getPath());
+ handle = NativeLibraryHelper.Handle.create(scanFile);
// 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
@@ -6178,7 +6176,7 @@ public class PackageManagerService extends IPackageManager.Stub {
}
}
- private static int copyNativeLibrariesForInternalApp(ApkHandle handle,
+ private static int copyNativeLibrariesForInternalApp(NativeLibraryHelper.Handle handle,
final File nativeLibraryDir, String[] abiList) throws IOException {
if (!nativeLibraryDir.isDirectory()) {
nativeLibraryDir.delete();
@@ -7486,7 +7484,7 @@ public class PackageManagerService extends IPackageManager.Stub {
if (DEBUG_APP_DIR_OBSERVER)
Log.v(TAG, "File " + fullPathStr + " changed: " + Integer.toHexString(event));
- if (!isPackageFilename(path)) {
+ if (!isApkFile(fullPath)) {
if (DEBUG_APP_DIR_OBSERVER)
Log.v(TAG, "Ignoring change of non-package file: " + fullPathStr);
return;
@@ -9211,9 +9209,9 @@ public class PackageManagerService extends IPackageManager.Stub {
String[] abiList = (abiOverride != null) ?
new String[] { abiOverride } : Build.SUPPORTED_ABIS;
- ApkHandle handle = null;
+ NativeLibraryHelper.Handle handle = null;
try {
- handle = ApkHandle.create(codeFile);
+ handle = NativeLibraryHelper.Handle.create(codeFile);
if (Build.SUPPORTED_64_BIT_ABIS.length > 0 &&
abiOverride == null &&
NativeLibraryHelper.hasRenderscriptBitcode(handle)) {
@@ -12955,9 +12953,10 @@ public class PackageManagerService extends IPackageManager.Stub {
final File newNativeDir = new File(newNativePath);
if (!isForwardLocked(pkg) && !isExternal(pkg)) {
- ApkHandle handle = null;
+ NativeLibraryHelper.Handle handle = null;
try {
- handle = ApkHandle.create(newCodePath);
+ handle = NativeLibraryHelper.Handle.create(
+ new File(newCodePath));
final int abi = NativeLibraryHelper.findSupportedAbi(
handle, Build.SUPPORTED_ABIS);
if (abi >= 0) {