diff options
Diffstat (limited to 'packages')
-rw-r--r-- | packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java | 246 |
1 files changed, 69 insertions, 177 deletions
diff --git a/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java b/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java index 4c225c1..fae30e5 100644 --- a/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java +++ b/packages/DefaultContainerService/src/com/android/defcontainer/DefaultContainerService.java @@ -30,7 +30,6 @@ import android.content.pm.PackageParser.PackageLite; import android.content.pm.PackageParser.PackageParserException; import android.content.res.ObbInfo; import android.content.res.ObbScanner; -import android.os.Build; import android.os.Environment; import android.os.Environment.UserEnvironment; import android.os.FileUtils; @@ -67,7 +66,6 @@ import java.io.OutputStream; */ public class DefaultContainerService extends IntentService { private static final String TAG = "DefContainer"; - private static final boolean localLOGV = false; private static final String LIB_DIR_NAME = "lib"; @@ -112,7 +110,7 @@ public class DefaultContainerService extends IntentService { return copyPackageToContainerInner(pkg, handle, containerId, key, isExternal, isForwardLocked, abiOverride); } catch (PackageParserException | IOException e) { - Slog.w(TAG, "Failed to parse package at " + packagePath); + Slog.w(TAG, "Failed to copy package at " + packagePath, e); return null; } finally { IoUtils.closeQuietly(handle); @@ -188,7 +186,7 @@ public class DefaultContainerService extends IntentService { ret.installLocation = pkg.installLocation; ret.verifiers = pkg.verifiers; ret.recommendedInstallLocation = PackageHelper.resolveInstallLocation(context, - pkg.installLocation, sizeBytes, flags); + pkg.packageName, pkg.installLocation, sizeBytes, flags); ret.multiArch = pkg.multiArch; return ret; @@ -313,161 +311,73 @@ public class DefaultContainerService extends IntentService { private String copyPackageToContainerInner(PackageLite pkg, NativeLibraryHelper.Handle handle, String newCid, String key, boolean isExternal, boolean isForwardLocked, - String abiOverride) { - // TODO: extend to support copying all split APKs - if (!ArrayUtils.isEmpty(pkg.splitNames)) { - throw new UnsupportedOperationException("Copying split APKs not yet supported"); - } - - final String resFileName = "pkg.apk"; - final String publicResFileName = "res.zip"; - - if (pkg.multiArch) { - // TODO: Support multiArch installs on ASEC. - throw new IllegalArgumentException("multiArch not supported on ASEC installs."); - } + String abiOverride) throws IOException { - // The .apk file - final String codePath = pkg.baseCodePath; - final File codeFile = new File(codePath); - final String[] abis; - try { - abis = calculateAbiList(handle, abiOverride, pkg.multiArch); - } catch (IOException ioe) { - Slog.w(TAG, "Problem determining app ABIS: " + ioe); - return null; - } - - // Calculate size of container needed to hold base APK. Round up to - // nearest MB, and tack on an extra MB for filesystem overhead. - final int sizeMb; - try { - final long sizeBytes = calculateInstalledSizeInner(pkg, handle, isForwardLocked, abis); - sizeMb = ((int) ((sizeBytes + MB_IN_BYTES) / MB_IN_BYTES)) + 1; - } catch (IOException e) { - Slog.w(TAG, "Problem when trying to copy " + codeFile.getPath()); - return null; - } + // Calculate container size, rounding up to nearest MB and adding an + // extra MB for filesystem overhead + final long sizeBytes = calculateInstalledSizeInner(pkg, handle, isForwardLocked, + abiOverride); + final int sizeMb = ((int) ((sizeBytes + MB_IN_BYTES) / MB_IN_BYTES)) + 1; // Create new container - final String newCachePath = PackageHelper.createSdDir(sizeMb, newCid, key, Process.myUid(), + final String newMountPath = PackageHelper.createSdDir(sizeMb, newCid, key, Process.myUid(), isExternal); - if (newCachePath == null) { - Slog.e(TAG, "Failed to create container " + newCid); - return null; - } - - if (localLOGV) { - Slog.i(TAG, "Created container for " + newCid + " at path : " + newCachePath); - } - - final File resFile = new File(newCachePath, resFileName); - if (FileUtils.copyFile(new File(codePath), resFile)) { - if (localLOGV) { - Slog.i(TAG, "Copied " + codePath + " to " + resFile); - } - } else { - Slog.e(TAG, "Failed to copy " + codePath + " to " + resFile); - // Clean up container - PackageHelper.destroySdDir(newCid); - return null; + if (newMountPath == null) { + throw new IOException("Failed to create container " + newCid); } + final File targetDir = new File(newMountPath); try { - Os.chmod(resFile.getAbsolutePath(), 0640); - } catch (ErrnoException e) { - Slog.e(TAG, "Could not chown APK: " + e.getMessage()); - PackageHelper.destroySdDir(newCid); - return null; - } - - if (isForwardLocked) { - File publicZipFile = new File(newCachePath, publicResFileName); - try { - PackageHelper.extractPublicFiles(resFile.getAbsolutePath(), publicZipFile); - if (localLOGV) { - Slog.i(TAG, "Copied resources to " + publicZipFile); + // Copy all APKs + copyFile(pkg.baseCodePath, targetDir, "base.apk", isForwardLocked); + if (!ArrayUtils.isEmpty(pkg.splitNames)) { + for (int i = 0; i < pkg.splitNames.length; i++) { + copyFile(pkg.splitCodePaths[i], targetDir, + "split_" + pkg.splitNames[i] + ".apk", isForwardLocked); } - } catch (IOException e) { - Slog.e(TAG, "Could not chown public APK " + publicZipFile.getAbsolutePath() + ": " - + e.getMessage()); - PackageHelper.destroySdDir(newCid); - return null; } - try { - Os.chmod(publicZipFile.getAbsolutePath(), 0644); - } catch (ErrnoException e) { - Slog.e(TAG, "Could not chown public resource file: " + e.getMessage()); - PackageHelper.destroySdDir(newCid); - return null; + // Extract native code + final File libraryRoot = new File(targetDir, LIB_DIR_NAME); + final int res = NativeLibraryHelper.copyNativeBinariesIfNeededLI(handle, libraryRoot, + abiOverride, pkg.multiArch); + if (res != PackageManager.INSTALL_SUCCEEDED) { + throw new IOException("Failed to extract native code, res=" + res); } - } - final File sharedLibraryDir = new File(newCachePath, LIB_DIR_NAME); - if (sharedLibraryDir.mkdir()) { - int ret = PackageManager.INSTALL_SUCCEEDED; - if (abis != null) { - // TODO(multiArch): Support multi-arch installs on asecs. Note that we are NOT - // using an ISA specific subdir here for now. - final String abi = abis[0]; - ret = NativeLibraryHelper.copyNativeBinariesIfNeededLI(handle, - sharedLibraryDir, abi); - - if (ret != PackageManager.INSTALL_SUCCEEDED) { - Slog.e(TAG, "Could not copy native libraries to " + sharedLibraryDir.getPath()); - PackageHelper.destroySdDir(newCid); - return null; - } + if (!PackageHelper.finalizeSdDir(newCid)) { + throw new IOException("Failed to finalize " + newCid); } - } else { - Slog.e(TAG, "Could not create native lib directory: " + sharedLibraryDir.getPath()); - PackageHelper.destroySdDir(newCid); - return null; - } - if (!PackageHelper.finalizeSdDir(newCid)) { - Slog.e(TAG, "Failed to finalize " + newCid + " at path " + newCachePath); - // Clean up container - PackageHelper.destroySdDir(newCid); - return null; - } - - if (localLOGV) { - Slog.i(TAG, "Finalized container " + newCid); - } - - if (PackageHelper.isContainerMounted(newCid)) { - if (localLOGV) { - Slog.i(TAG, "Unmounting " + newCid + " at path " + newCachePath); + if (PackageHelper.isContainerMounted(newCid)) { + PackageHelper.unMountSdDir(newCid); } - // Force a gc to avoid being killed. - Runtime.getRuntime().gc(); - PackageHelper.unMountSdDir(newCid); - } else { - if (localLOGV) { - Slog.i(TAG, "Container " + newCid + " not mounted"); - } + } catch (ErrnoException e) { + PackageHelper.destroySdDir(newCid); + throw e.rethrowAsIOException(); + } catch (IOException e) { + PackageHelper.destroySdDir(newCid); + throw e; } - return newCachePath; + return newMountPath; } private int copyPackageInner(PackageLite pkg, IParcelFileDescriptorFactory target) throws IOException, RemoteException { - copyFile(pkg.baseCodePath, "base.apk", target); + copyFile(pkg.baseCodePath, target, "base.apk"); if (!ArrayUtils.isEmpty(pkg.splitNames)) { for (int i = 0; i < pkg.splitNames.length; i++) { - copyFile(pkg.splitCodePaths[i], "split_" + pkg.splitNames[i] + ".apk", target); + copyFile(pkg.splitCodePaths[i], target, "split_" + pkg.splitNames[i] + ".apk"); } } return PackageManager.INSTALL_SUCCEEDED; } - private void copyFile(String sourcePath, String targetName, - IParcelFileDescriptorFactory target) throws IOException, RemoteException { + private void copyFile(String sourcePath, IParcelFileDescriptorFactory target, String targetName) + throws IOException, RemoteException { Slog.d(TAG, "Copying " + sourcePath + " to " + targetName); InputStream in = null; OutputStream out = null; @@ -482,76 +392,58 @@ public class DefaultContainerService extends IntentService { } } + private void copyFile(String sourcePath, File targetDir, String targetName, + boolean isForwardLocked) throws IOException, ErrnoException { + final File sourceFile = new File(sourcePath); + final File targetFile = new File(targetDir, targetName); + + Slog.d(TAG, "Copying " + sourceFile + " to " + targetFile); + if (!FileUtils.copyFile(sourceFile, targetFile)) { + throw new IOException("Failed to copy " + sourceFile + " to " + targetFile); + } + + if (isForwardLocked) { + final String publicTargetName = PackageHelper.replaceEnd(targetName, + ".apk", ".zip"); + final File publicTargetFile = new File(targetDir, publicTargetName); + + PackageHelper.extractPublicFiles(sourceFile, publicTargetFile); + + Os.chmod(targetFile.getAbsolutePath(), 0640); + Os.chmod(publicTargetFile.getAbsolutePath(), 0644); + } else { + Os.chmod(targetFile.getAbsolutePath(), 0644); + } + } + private long calculateInstalledSizeInner(PackageLite pkg, boolean isForwardLocked, String abiOverride) throws IOException { NativeLibraryHelper.Handle handle = null; try { handle = NativeLibraryHelper.Handle.create(pkg); - return calculateInstalledSizeInner(pkg, handle, isForwardLocked, - calculateAbiList(handle, abiOverride, pkg.multiArch)); + return calculateInstalledSizeInner(pkg, handle, isForwardLocked, abiOverride); } finally { IoUtils.closeQuietly(handle); } } private long calculateInstalledSizeInner(PackageLite pkg, NativeLibraryHelper.Handle handle, - boolean isForwardLocked, String[] abis) throws IOException { + boolean isForwardLocked, String abiOverride) throws IOException { long sizeBytes = 0; // Include raw APKs, and possibly unpacked resources for (String codePath : pkg.getAllCodePaths()) { - sizeBytes += new File(codePath).length(); + final File codeFile = new File(codePath); + sizeBytes += codeFile.length(); if (isForwardLocked) { - sizeBytes += PackageHelper.extractPublicFiles(codePath, null); + sizeBytes += PackageHelper.extractPublicFiles(codeFile, null); } } // Include all relevant native code - if (!ArrayUtils.isEmpty(abis)) { - sizeBytes += NativeLibraryHelper.sumNativeBinariesLI(handle, abis); - } + sizeBytes += NativeLibraryHelper.sumNativeBinaries(handle, abiOverride, pkg.multiArch); return sizeBytes; } - - private String[] calculateAbiList(NativeLibraryHelper.Handle handle, String abiOverride, - boolean isMultiArch) throws IOException { - if (isMultiArch) { - final int abi32 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_32_BIT_ABIS); - final int abi64 = NativeLibraryHelper.findSupportedAbi(handle, Build.SUPPORTED_64_BIT_ABIS); - - if (abi32 >= 0 && abi64 >= 0) { - return new String[] { Build.SUPPORTED_64_BIT_ABIS[abi64], Build.SUPPORTED_32_BIT_ABIS[abi32] }; - } else if (abi64 >= 0) { - return new String[] { Build.SUPPORTED_64_BIT_ABIS[abi64] }; - } else if (abi32 >= 0) { - return new String[] { Build.SUPPORTED_32_BIT_ABIS[abi32] }; - } - - if (abi64 != PackageManager.NO_NATIVE_LIBRARIES || abi32 != PackageManager.NO_NATIVE_LIBRARIES) { - throw new IOException("Error determining ABI list: errorCode=[" + abi32 + "," + abi64 + "]"); - } - - } else { - String[] abiList = Build.SUPPORTED_ABIS; - if (abiOverride != null) { - abiList = new String[] { abiOverride }; - } else if (Build.SUPPORTED_64_BIT_ABIS.length > 0 && - NativeLibraryHelper.hasRenderscriptBitcode(handle)) { - abiList = Build.SUPPORTED_32_BIT_ABIS; - } - - final int abi = NativeLibraryHelper.findSupportedAbi(handle,abiList); - if (abi >= 0) { - return new String[]{Build.SUPPORTED_ABIS[abi]}; - } - - if (abi != PackageManager.NO_NATIVE_LIBRARIES) { - throw new IOException("Error determining ABI list: errorCode=" + abi); - } - } - - return null; - } } |