diff options
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) { |