Loading services/core/java/com/android/server/pm/PackageManagerService.java +176 −118 Original line number Original line Diff line number Diff line Loading @@ -5494,7 +5494,6 @@ public class PackageManagerService extends IPackageManager.Stub { } } final String path = scanFile.getPath(); final String path = scanFile.getPath(); final String codePath = pkg.applicationInfo.getCodePath(); final String cpuAbiOverride = deriveAbiOverride(pkg.cpuAbiOverride, pkgSetting); final String cpuAbiOverride = deriveAbiOverride(pkg.cpuAbiOverride, pkgSetting); if (isSystemApp(pkg) && !pkg.isUpdatedSystemApp()) { if (isSystemApp(pkg) && !pkg.isUpdatedSystemApp()) { setBundledAppAbisAndRoots(pkg, pkgSetting); setBundledAppAbisAndRoots(pkg, pkgSetting); Loading @@ -5520,128 +5519,28 @@ public class PackageManagerService extends IPackageManager.Stub { setNativeLibraryPaths(pkg); setNativeLibraryPaths(pkg); } else { } else { // TODO: We can probably be smarter about this stuff. For installed apps, if ((scanFlags & SCAN_NEW_INSTALL) == 0) { // we can calculate this information at install time once and for all. For deriveNonSystemPackageAbi(pkg, scanFile, cpuAbiOverride, true /* extract libs */); // system apps, we can probably assume that this information doesn't change // after the first boot scan. As things stand, we do lots of unnecessary work. // Give ourselves some initial paths; we'll come back for another // pass once we've determined ABI below. setNativeLibraryPaths(pkg); final boolean isAsec = pkg.isForwardLocked() || isExternal(pkg); final String nativeLibraryRootStr = pkg.applicationInfo.nativeLibraryRootDir; final boolean useIsaSpecificSubdirs = pkg.applicationInfo.nativeLibraryRootRequiresIsa; NativeLibraryHelper.Handle handle = null; try { handle = NativeLibraryHelper.Handle.create(scanFile); // TODO(multiArch): This can be null for apps that didn't go through the // usual installation process. We can calculate it again, like we // do during install time. // // TODO(multiArch): Why do we need to rescan ASEC apps again ? It seems totally // unnecessary. final File nativeLibraryRoot = new File(nativeLibraryRootStr); // Null out the abis so that they can be recalculated. pkg.applicationInfo.primaryCpuAbi = null; pkg.applicationInfo.secondaryCpuAbi = null; if (isMultiArch(pkg.applicationInfo)) { // Warn if we've set an abiOverride for multi-lib packages.. // By definition, we need to copy both 32 and 64 bit libraries for // such packages. if (pkg.cpuAbiOverride != null && !NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(pkg.cpuAbiOverride)) { Slog.w(TAG, "Ignoring abiOverride for multi arch application."); } int abi32 = PackageManager.NO_NATIVE_LIBRARIES; int abi64 = PackageManager.NO_NATIVE_LIBRARIES; if (Build.SUPPORTED_32_BIT_ABIS.length > 0) { if (isAsec) { abi32 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_32_BIT_ABIS); } else { abi32 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle, nativeLibraryRoot, Build.SUPPORTED_32_BIT_ABIS, useIsaSpecificSubdirs); } } maybeThrowExceptionForMultiArchCopy( "Error unpackaging 32 bit native libs for multiarch app.", abi32); if (Build.SUPPORTED_64_BIT_ABIS.length > 0) { if (isAsec) { abi64 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_64_BIT_ABIS); } else { abi64 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle, nativeLibraryRoot, Build.SUPPORTED_64_BIT_ABIS, useIsaSpecificSubdirs); } } maybeThrowExceptionForMultiArchCopy( "Error unpackaging 64 bit native libs for multiarch app.", abi64); if (abi64 >= 0) { pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[abi64]; } if (abi32 >= 0) { final String abi = Build.SUPPORTED_32_BIT_ABIS[abi32]; if (abi64 >= 0) { pkg.applicationInfo.secondaryCpuAbi = abi; } else { } else { pkg.applicationInfo.primaryCpuAbi = abi; // Verify the ABIs haven't changed since we last deduced them. } String oldPrimaryCpuAbi = pkg.applicationInfo.primaryCpuAbi; } String oldSecondaryCpuAbi = pkg.applicationInfo.secondaryCpuAbi; } else { String[] abiList = (cpuAbiOverride != null) ? new String[] { cpuAbiOverride } : Build.SUPPORTED_ABIS; // Enable gross and lame hacks for apps that are built with old // TODO: The only purpose of this code is to update the native library paths // SDK tools. We must scan their APKs for renderscript bitcode and // based on the final install location. We can simplify this and avoid having // not launch them if it's present. Don't bother checking on devices // to scan the package again. // that don't have 64 bit support. deriveNonSystemPackageAbi(pkg, scanFile, cpuAbiOverride, false /* extract libs */); boolean needsRenderScriptOverride = false; if (!TextUtils.equals(oldPrimaryCpuAbi, pkg.applicationInfo.primaryCpuAbi)) { if (Build.SUPPORTED_64_BIT_ABIS.length > 0 && cpuAbiOverride == null && throw new IllegalStateException("unexpected abi change for " + pkg.packageName + " (" NativeLibraryHelper.hasRenderscriptBitcode(handle)) { + oldPrimaryCpuAbi + "-> " + pkg.applicationInfo.primaryCpuAbi); abiList = Build.SUPPORTED_32_BIT_ABIS; needsRenderScriptOverride = true; } } final int copyRet; if (!TextUtils.equals(oldSecondaryCpuAbi, pkg.applicationInfo.secondaryCpuAbi)) { if (isAsec) { throw new IllegalStateException("unexpected abi change for " + pkg.packageName + " (" copyRet = NativeLibraryHelper.findSupportedAbi(handle, abiList); + oldSecondaryCpuAbi + "-> " + pkg.applicationInfo.secondaryCpuAbi); } else { copyRet = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle, nativeLibraryRoot, abiList, useIsaSpecificSubdirs); } } if (copyRet < 0 && copyRet != PackageManager.NO_NATIVE_LIBRARIES) { throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR, "Error unpackaging native libs for app, errorCode=" + copyRet); } if (copyRet >= 0) { pkg.applicationInfo.primaryCpuAbi = abiList[copyRet]; } else if (copyRet == PackageManager.NO_NATIVE_LIBRARIES && cpuAbiOverride != null) { pkg.applicationInfo.primaryCpuAbi = cpuAbiOverride; } else if (needsRenderScriptOverride) { pkg.applicationInfo.primaryCpuAbi = abiList[0]; } } } catch (IOException ioe) { Slog.e(TAG, "Unable to get canonical file " + ioe.toString()); } finally { IoUtils.closeQuietly(handle); } } // Now that we've calculated the ABIs and determined if it's an internal app, // we will go ahead and populate the nativeLibraryPath. setNativeLibraryPaths(pkg); if (DEBUG_INSTALL) Slog.i(TAG, "Linking native library dir for " + path); if (DEBUG_INSTALL) Slog.i(TAG, "Linking native library dir for " + path); final int[] userIds = sUserManager.getUserIds(); final int[] userIds = sUserManager.getUserIds(); synchronized (mInstallLock) { synchronized (mInstallLock) { Loading Loading @@ -5670,9 +5569,21 @@ public class PackageManagerService extends IPackageManager.Stub { Build.SUPPORTED_64_BIT_ABIS[0] : Build.SUPPORTED_32_BIT_ABIS[0]; Build.SUPPORTED_64_BIT_ABIS[0] : Build.SUPPORTED_32_BIT_ABIS[0]; } } // If there's a mismatch between the abi-override in the package setting // and the abiOverride specified for the install. Warn about this because we // would've already compiled the app without taking the package setting into // account. if ((scanFlags & SCAN_NO_DEX) == 0 && (scanFlags & SCAN_NEW_INSTALL) != 0) { if (cpuAbiOverride == null && pkgSetting.cpuAbiOverrideString != null) { Slog.w(TAG, "Ignoring persisted ABI override " + cpuAbiOverride + " for package: " + pkg.packageName); } } pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi; pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi; pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi; pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi; pkgSetting.cpuAbiOverrideString = cpuAbiOverride; pkgSetting.cpuAbiOverrideString = cpuAbiOverride; // Copy the derived override back to the parsed package, so that we can // Copy the derived override back to the parsed package, so that we can // update the package settings accordingly. // update the package settings accordingly. pkg.cpuAbiOverride = cpuAbiOverride; pkg.cpuAbiOverride = cpuAbiOverride; Loading Loading @@ -6175,6 +6086,144 @@ public class PackageManagerService extends IPackageManager.Stub { return pkg; return pkg; } } /** * Derive the ABI of a non-system package located at {@code scanFile}. This information * is derived purely on the basis of the contents of {@code scanFile} and * {@code cpuAbiOverride}. * * If {@code extractLibs} is true, native libraries are extracted from the app if required. */ public void deriveNonSystemPackageAbi(PackageParser.Package pkg, File scanFile, String cpuAbiOverride, boolean extractLibs) throws PackageManagerException { // TODO: We can probably be smarter about this stuff. For installed apps, // we can calculate this information at install time once and for all. For // system apps, we can probably assume that this information doesn't change // after the first boot scan. As things stand, we do lots of unnecessary work. // Give ourselves some initial paths; we'll come back for another // pass once we've determined ABI below. setNativeLibraryPaths(pkg); // We would never need to extract libs for forward-locked and external packages, // since the container service will do it for us. if (pkg.isForwardLocked() || isExternal(pkg)) { extractLibs = false; } final String nativeLibraryRootStr = pkg.applicationInfo.nativeLibraryRootDir; final boolean useIsaSpecificSubdirs = pkg.applicationInfo.nativeLibraryRootRequiresIsa; NativeLibraryHelper.Handle handle = null; try { handle = NativeLibraryHelper.Handle.create(scanFile); // TODO(multiArch): This can be null for apps that didn't go through the // usual installation process. We can calculate it again, like we // do during install time. // // TODO(multiArch): Why do we need to rescan ASEC apps again ? It seems totally // unnecessary. final File nativeLibraryRoot = new File(nativeLibraryRootStr); // Null out the abis so that they can be recalculated. pkg.applicationInfo.primaryCpuAbi = null; pkg.applicationInfo.secondaryCpuAbi = null; if (isMultiArch(pkg.applicationInfo)) { // Warn if we've set an abiOverride for multi-lib packages.. // By definition, we need to copy both 32 and 64 bit libraries for // such packages. if (pkg.cpuAbiOverride != null && !NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(pkg.cpuAbiOverride)) { Slog.w(TAG, "Ignoring abiOverride for multi arch application."); } int abi32 = PackageManager.NO_NATIVE_LIBRARIES; int abi64 = PackageManager.NO_NATIVE_LIBRARIES; if (Build.SUPPORTED_32_BIT_ABIS.length > 0) { if (extractLibs) { abi32 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle, nativeLibraryRoot, Build.SUPPORTED_32_BIT_ABIS, useIsaSpecificSubdirs); } else { abi32 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_32_BIT_ABIS); } } maybeThrowExceptionForMultiArchCopy( "Error unpackaging 32 bit native libs for multiarch app.", abi32); if (Build.SUPPORTED_64_BIT_ABIS.length > 0) { if (extractLibs) { abi64 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle, nativeLibraryRoot, Build.SUPPORTED_64_BIT_ABIS, useIsaSpecificSubdirs); } else { abi64 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_64_BIT_ABIS); } } maybeThrowExceptionForMultiArchCopy( "Error unpackaging 64 bit native libs for multiarch app.", abi64); if (abi64 >= 0) { pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[abi64]; } if (abi32 >= 0) { final String abi = Build.SUPPORTED_32_BIT_ABIS[abi32]; if (abi64 >= 0) { pkg.applicationInfo.secondaryCpuAbi = abi; } else { pkg.applicationInfo.primaryCpuAbi = abi; } } } else { String[] abiList = (cpuAbiOverride != null) ? new String[] { cpuAbiOverride } : Build.SUPPORTED_ABIS; // 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 // that don't have 64 bit support. boolean needsRenderScriptOverride = false; if (Build.SUPPORTED_64_BIT_ABIS.length > 0 && cpuAbiOverride == null && NativeLibraryHelper.hasRenderscriptBitcode(handle)) { abiList = Build.SUPPORTED_32_BIT_ABIS; needsRenderScriptOverride = true; } final int copyRet; if (extractLibs) { copyRet = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle, nativeLibraryRoot, abiList, useIsaSpecificSubdirs); } else { copyRet = NativeLibraryHelper.findSupportedAbi(handle, abiList); } if (copyRet < 0 && copyRet != PackageManager.NO_NATIVE_LIBRARIES) { throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR, "Error unpackaging native libs for app, errorCode=" + copyRet); } if (copyRet >= 0) { pkg.applicationInfo.primaryCpuAbi = abiList[copyRet]; } else if (copyRet == PackageManager.NO_NATIVE_LIBRARIES && cpuAbiOverride != null) { pkg.applicationInfo.primaryCpuAbi = cpuAbiOverride; } else if (needsRenderScriptOverride) { pkg.applicationInfo.primaryCpuAbi = abiList[0]; } } } catch (IOException ioe) { Slog.e(TAG, "Unable to get canonical file " + ioe.toString()); } finally { IoUtils.closeQuietly(handle); } // Now that we've calculated the ABIs and determined if it's an internal app, // we will go ahead and populate the nativeLibraryPath. setNativeLibraryPaths(pkg); } /** /** * Adjusts ABIs for a set of packages belonging to a shared user so that they all match. * Adjusts ABIs for a set of packages belonging to a shared user so that they all match. * i.e, so that all packages can be run inside a single process if required. * i.e, so that all packages can be run inside a single process if required. Loading Loading @@ -10425,6 +10474,15 @@ public class PackageManagerService extends IPackageManager.Stub { if (!forwardLocked && pkg.applicationInfo.isInternal()) { if (!forwardLocked && pkg.applicationInfo.isInternal()) { // Enable SCAN_NO_DEX flag to skip dexopt at a later stage // Enable SCAN_NO_DEX flag to skip dexopt at a later stage scanFlags |= SCAN_NO_DEX; scanFlags |= SCAN_NO_DEX; try { deriveNonSystemPackageAbi(pkg, new File(pkg.codePath), args.abiOverride, true /* extract libs */); } catch (PackageManagerException pme) { Slog.e(TAG, "Error deriving application ABI", pme); res.setError(INSTALL_FAILED_INTERNAL_ERROR, "Error "); return; } // Run dexopt before old package gets removed, to minimize time when app is unavailable // Run dexopt before old package gets removed, to minimize time when app is unavailable int result = mPackageDexOptimizer int result = mPackageDexOptimizer .performDexOpt(pkg, null /* instruction sets */, true /* forceDex */, .performDexOpt(pkg, null /* instruction sets */, true /* forceDex */, Loading Loading
services/core/java/com/android/server/pm/PackageManagerService.java +176 −118 Original line number Original line Diff line number Diff line Loading @@ -5494,7 +5494,6 @@ public class PackageManagerService extends IPackageManager.Stub { } } final String path = scanFile.getPath(); final String path = scanFile.getPath(); final String codePath = pkg.applicationInfo.getCodePath(); final String cpuAbiOverride = deriveAbiOverride(pkg.cpuAbiOverride, pkgSetting); final String cpuAbiOverride = deriveAbiOverride(pkg.cpuAbiOverride, pkgSetting); if (isSystemApp(pkg) && !pkg.isUpdatedSystemApp()) { if (isSystemApp(pkg) && !pkg.isUpdatedSystemApp()) { setBundledAppAbisAndRoots(pkg, pkgSetting); setBundledAppAbisAndRoots(pkg, pkgSetting); Loading @@ -5520,128 +5519,28 @@ public class PackageManagerService extends IPackageManager.Stub { setNativeLibraryPaths(pkg); setNativeLibraryPaths(pkg); } else { } else { // TODO: We can probably be smarter about this stuff. For installed apps, if ((scanFlags & SCAN_NEW_INSTALL) == 0) { // we can calculate this information at install time once and for all. For deriveNonSystemPackageAbi(pkg, scanFile, cpuAbiOverride, true /* extract libs */); // system apps, we can probably assume that this information doesn't change // after the first boot scan. As things stand, we do lots of unnecessary work. // Give ourselves some initial paths; we'll come back for another // pass once we've determined ABI below. setNativeLibraryPaths(pkg); final boolean isAsec = pkg.isForwardLocked() || isExternal(pkg); final String nativeLibraryRootStr = pkg.applicationInfo.nativeLibraryRootDir; final boolean useIsaSpecificSubdirs = pkg.applicationInfo.nativeLibraryRootRequiresIsa; NativeLibraryHelper.Handle handle = null; try { handle = NativeLibraryHelper.Handle.create(scanFile); // TODO(multiArch): This can be null for apps that didn't go through the // usual installation process. We can calculate it again, like we // do during install time. // // TODO(multiArch): Why do we need to rescan ASEC apps again ? It seems totally // unnecessary. final File nativeLibraryRoot = new File(nativeLibraryRootStr); // Null out the abis so that they can be recalculated. pkg.applicationInfo.primaryCpuAbi = null; pkg.applicationInfo.secondaryCpuAbi = null; if (isMultiArch(pkg.applicationInfo)) { // Warn if we've set an abiOverride for multi-lib packages.. // By definition, we need to copy both 32 and 64 bit libraries for // such packages. if (pkg.cpuAbiOverride != null && !NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(pkg.cpuAbiOverride)) { Slog.w(TAG, "Ignoring abiOverride for multi arch application."); } int abi32 = PackageManager.NO_NATIVE_LIBRARIES; int abi64 = PackageManager.NO_NATIVE_LIBRARIES; if (Build.SUPPORTED_32_BIT_ABIS.length > 0) { if (isAsec) { abi32 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_32_BIT_ABIS); } else { abi32 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle, nativeLibraryRoot, Build.SUPPORTED_32_BIT_ABIS, useIsaSpecificSubdirs); } } maybeThrowExceptionForMultiArchCopy( "Error unpackaging 32 bit native libs for multiarch app.", abi32); if (Build.SUPPORTED_64_BIT_ABIS.length > 0) { if (isAsec) { abi64 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_64_BIT_ABIS); } else { abi64 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle, nativeLibraryRoot, Build.SUPPORTED_64_BIT_ABIS, useIsaSpecificSubdirs); } } maybeThrowExceptionForMultiArchCopy( "Error unpackaging 64 bit native libs for multiarch app.", abi64); if (abi64 >= 0) { pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[abi64]; } if (abi32 >= 0) { final String abi = Build.SUPPORTED_32_BIT_ABIS[abi32]; if (abi64 >= 0) { pkg.applicationInfo.secondaryCpuAbi = abi; } else { } else { pkg.applicationInfo.primaryCpuAbi = abi; // Verify the ABIs haven't changed since we last deduced them. } String oldPrimaryCpuAbi = pkg.applicationInfo.primaryCpuAbi; } String oldSecondaryCpuAbi = pkg.applicationInfo.secondaryCpuAbi; } else { String[] abiList = (cpuAbiOverride != null) ? new String[] { cpuAbiOverride } : Build.SUPPORTED_ABIS; // Enable gross and lame hacks for apps that are built with old // TODO: The only purpose of this code is to update the native library paths // SDK tools. We must scan their APKs for renderscript bitcode and // based on the final install location. We can simplify this and avoid having // not launch them if it's present. Don't bother checking on devices // to scan the package again. // that don't have 64 bit support. deriveNonSystemPackageAbi(pkg, scanFile, cpuAbiOverride, false /* extract libs */); boolean needsRenderScriptOverride = false; if (!TextUtils.equals(oldPrimaryCpuAbi, pkg.applicationInfo.primaryCpuAbi)) { if (Build.SUPPORTED_64_BIT_ABIS.length > 0 && cpuAbiOverride == null && throw new IllegalStateException("unexpected abi change for " + pkg.packageName + " (" NativeLibraryHelper.hasRenderscriptBitcode(handle)) { + oldPrimaryCpuAbi + "-> " + pkg.applicationInfo.primaryCpuAbi); abiList = Build.SUPPORTED_32_BIT_ABIS; needsRenderScriptOverride = true; } } final int copyRet; if (!TextUtils.equals(oldSecondaryCpuAbi, pkg.applicationInfo.secondaryCpuAbi)) { if (isAsec) { throw new IllegalStateException("unexpected abi change for " + pkg.packageName + " (" copyRet = NativeLibraryHelper.findSupportedAbi(handle, abiList); + oldSecondaryCpuAbi + "-> " + pkg.applicationInfo.secondaryCpuAbi); } else { copyRet = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle, nativeLibraryRoot, abiList, useIsaSpecificSubdirs); } } if (copyRet < 0 && copyRet != PackageManager.NO_NATIVE_LIBRARIES) { throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR, "Error unpackaging native libs for app, errorCode=" + copyRet); } if (copyRet >= 0) { pkg.applicationInfo.primaryCpuAbi = abiList[copyRet]; } else if (copyRet == PackageManager.NO_NATIVE_LIBRARIES && cpuAbiOverride != null) { pkg.applicationInfo.primaryCpuAbi = cpuAbiOverride; } else if (needsRenderScriptOverride) { pkg.applicationInfo.primaryCpuAbi = abiList[0]; } } } catch (IOException ioe) { Slog.e(TAG, "Unable to get canonical file " + ioe.toString()); } finally { IoUtils.closeQuietly(handle); } } // Now that we've calculated the ABIs and determined if it's an internal app, // we will go ahead and populate the nativeLibraryPath. setNativeLibraryPaths(pkg); if (DEBUG_INSTALL) Slog.i(TAG, "Linking native library dir for " + path); if (DEBUG_INSTALL) Slog.i(TAG, "Linking native library dir for " + path); final int[] userIds = sUserManager.getUserIds(); final int[] userIds = sUserManager.getUserIds(); synchronized (mInstallLock) { synchronized (mInstallLock) { Loading Loading @@ -5670,9 +5569,21 @@ public class PackageManagerService extends IPackageManager.Stub { Build.SUPPORTED_64_BIT_ABIS[0] : Build.SUPPORTED_32_BIT_ABIS[0]; Build.SUPPORTED_64_BIT_ABIS[0] : Build.SUPPORTED_32_BIT_ABIS[0]; } } // If there's a mismatch between the abi-override in the package setting // and the abiOverride specified for the install. Warn about this because we // would've already compiled the app without taking the package setting into // account. if ((scanFlags & SCAN_NO_DEX) == 0 && (scanFlags & SCAN_NEW_INSTALL) != 0) { if (cpuAbiOverride == null && pkgSetting.cpuAbiOverrideString != null) { Slog.w(TAG, "Ignoring persisted ABI override " + cpuAbiOverride + " for package: " + pkg.packageName); } } pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi; pkgSetting.primaryCpuAbiString = pkg.applicationInfo.primaryCpuAbi; pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi; pkgSetting.secondaryCpuAbiString = pkg.applicationInfo.secondaryCpuAbi; pkgSetting.cpuAbiOverrideString = cpuAbiOverride; pkgSetting.cpuAbiOverrideString = cpuAbiOverride; // Copy the derived override back to the parsed package, so that we can // Copy the derived override back to the parsed package, so that we can // update the package settings accordingly. // update the package settings accordingly. pkg.cpuAbiOverride = cpuAbiOverride; pkg.cpuAbiOverride = cpuAbiOverride; Loading Loading @@ -6175,6 +6086,144 @@ public class PackageManagerService extends IPackageManager.Stub { return pkg; return pkg; } } /** * Derive the ABI of a non-system package located at {@code scanFile}. This information * is derived purely on the basis of the contents of {@code scanFile} and * {@code cpuAbiOverride}. * * If {@code extractLibs} is true, native libraries are extracted from the app if required. */ public void deriveNonSystemPackageAbi(PackageParser.Package pkg, File scanFile, String cpuAbiOverride, boolean extractLibs) throws PackageManagerException { // TODO: We can probably be smarter about this stuff. For installed apps, // we can calculate this information at install time once and for all. For // system apps, we can probably assume that this information doesn't change // after the first boot scan. As things stand, we do lots of unnecessary work. // Give ourselves some initial paths; we'll come back for another // pass once we've determined ABI below. setNativeLibraryPaths(pkg); // We would never need to extract libs for forward-locked and external packages, // since the container service will do it for us. if (pkg.isForwardLocked() || isExternal(pkg)) { extractLibs = false; } final String nativeLibraryRootStr = pkg.applicationInfo.nativeLibraryRootDir; final boolean useIsaSpecificSubdirs = pkg.applicationInfo.nativeLibraryRootRequiresIsa; NativeLibraryHelper.Handle handle = null; try { handle = NativeLibraryHelper.Handle.create(scanFile); // TODO(multiArch): This can be null for apps that didn't go through the // usual installation process. We can calculate it again, like we // do during install time. // // TODO(multiArch): Why do we need to rescan ASEC apps again ? It seems totally // unnecessary. final File nativeLibraryRoot = new File(nativeLibraryRootStr); // Null out the abis so that they can be recalculated. pkg.applicationInfo.primaryCpuAbi = null; pkg.applicationInfo.secondaryCpuAbi = null; if (isMultiArch(pkg.applicationInfo)) { // Warn if we've set an abiOverride for multi-lib packages.. // By definition, we need to copy both 32 and 64 bit libraries for // such packages. if (pkg.cpuAbiOverride != null && !NativeLibraryHelper.CLEAR_ABI_OVERRIDE.equals(pkg.cpuAbiOverride)) { Slog.w(TAG, "Ignoring abiOverride for multi arch application."); } int abi32 = PackageManager.NO_NATIVE_LIBRARIES; int abi64 = PackageManager.NO_NATIVE_LIBRARIES; if (Build.SUPPORTED_32_BIT_ABIS.length > 0) { if (extractLibs) { abi32 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle, nativeLibraryRoot, Build.SUPPORTED_32_BIT_ABIS, useIsaSpecificSubdirs); } else { abi32 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_32_BIT_ABIS); } } maybeThrowExceptionForMultiArchCopy( "Error unpackaging 32 bit native libs for multiarch app.", abi32); if (Build.SUPPORTED_64_BIT_ABIS.length > 0) { if (extractLibs) { abi64 = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle, nativeLibraryRoot, Build.SUPPORTED_64_BIT_ABIS, useIsaSpecificSubdirs); } else { abi64 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_64_BIT_ABIS); } } maybeThrowExceptionForMultiArchCopy( "Error unpackaging 64 bit native libs for multiarch app.", abi64); if (abi64 >= 0) { pkg.applicationInfo.primaryCpuAbi = Build.SUPPORTED_64_BIT_ABIS[abi64]; } if (abi32 >= 0) { final String abi = Build.SUPPORTED_32_BIT_ABIS[abi32]; if (abi64 >= 0) { pkg.applicationInfo.secondaryCpuAbi = abi; } else { pkg.applicationInfo.primaryCpuAbi = abi; } } } else { String[] abiList = (cpuAbiOverride != null) ? new String[] { cpuAbiOverride } : Build.SUPPORTED_ABIS; // 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 // that don't have 64 bit support. boolean needsRenderScriptOverride = false; if (Build.SUPPORTED_64_BIT_ABIS.length > 0 && cpuAbiOverride == null && NativeLibraryHelper.hasRenderscriptBitcode(handle)) { abiList = Build.SUPPORTED_32_BIT_ABIS; needsRenderScriptOverride = true; } final int copyRet; if (extractLibs) { copyRet = NativeLibraryHelper.copyNativeBinariesForSupportedAbi(handle, nativeLibraryRoot, abiList, useIsaSpecificSubdirs); } else { copyRet = NativeLibraryHelper.findSupportedAbi(handle, abiList); } if (copyRet < 0 && copyRet != PackageManager.NO_NATIVE_LIBRARIES) { throw new PackageManagerException(INSTALL_FAILED_INTERNAL_ERROR, "Error unpackaging native libs for app, errorCode=" + copyRet); } if (copyRet >= 0) { pkg.applicationInfo.primaryCpuAbi = abiList[copyRet]; } else if (copyRet == PackageManager.NO_NATIVE_LIBRARIES && cpuAbiOverride != null) { pkg.applicationInfo.primaryCpuAbi = cpuAbiOverride; } else if (needsRenderScriptOverride) { pkg.applicationInfo.primaryCpuAbi = abiList[0]; } } } catch (IOException ioe) { Slog.e(TAG, "Unable to get canonical file " + ioe.toString()); } finally { IoUtils.closeQuietly(handle); } // Now that we've calculated the ABIs and determined if it's an internal app, // we will go ahead and populate the nativeLibraryPath. setNativeLibraryPaths(pkg); } /** /** * Adjusts ABIs for a set of packages belonging to a shared user so that they all match. * Adjusts ABIs for a set of packages belonging to a shared user so that they all match. * i.e, so that all packages can be run inside a single process if required. * i.e, so that all packages can be run inside a single process if required. Loading Loading @@ -10425,6 +10474,15 @@ public class PackageManagerService extends IPackageManager.Stub { if (!forwardLocked && pkg.applicationInfo.isInternal()) { if (!forwardLocked && pkg.applicationInfo.isInternal()) { // Enable SCAN_NO_DEX flag to skip dexopt at a later stage // Enable SCAN_NO_DEX flag to skip dexopt at a later stage scanFlags |= SCAN_NO_DEX; scanFlags |= SCAN_NO_DEX; try { deriveNonSystemPackageAbi(pkg, new File(pkg.codePath), args.abiOverride, true /* extract libs */); } catch (PackageManagerException pme) { Slog.e(TAG, "Error deriving application ABI", pme); res.setError(INSTALL_FAILED_INTERNAL_ERROR, "Error "); return; } // Run dexopt before old package gets removed, to minimize time when app is unavailable // Run dexopt before old package gets removed, to minimize time when app is unavailable int result = mPackageDexOptimizer int result = mPackageDexOptimizer .performDexOpt(pkg, null /* instruction sets */, true /* forceDex */, .performDexOpt(pkg, null /* instruction sets */, true /* forceDex */, Loading