FileDocCategorySizeDatePackage
DefaultContainerService.javaAPI DocAndroid 5.1 API16773Thu Mar 12 22:22:40 GMT 2015com.android.defcontainer

DefaultContainerService

public class DefaultContainerService extends android.app.IntentService
Service that offers to inspect and copy files that may reside on removable storage. This is designed to prevent the system process from holding onto open files that cause the kernel to kill it when the underlying device is removed.

Fields Summary
private static final String
TAG
private IMediaContainerService.Stub
mBinder
Constructors Summary
public DefaultContainerService()


      
        super("DefaultContainerService");
        setIntentRedelivery(true);
    
Methods Summary
private voidcopyFile(java.lang.String sourcePath, com.android.internal.os.IParcelFileDescriptorFactory target, java.lang.String targetName)

        Slog.d(TAG, "Copying " + sourcePath + " to " + targetName);
        InputStream in = null;
        OutputStream out = null;
        try {
            in = new FileInputStream(sourcePath);
            out = new ParcelFileDescriptor.AutoCloseOutputStream(
                    target.open(targetName, ParcelFileDescriptor.MODE_READ_WRITE));
            Streams.copy(in, out);
        } finally {
            IoUtils.closeQuietly(out);
            IoUtils.closeQuietly(in);
        }
    
private voidcopyFile(java.lang.String sourcePath, java.io.File targetDir, java.lang.String targetName, boolean isForwardLocked)

        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 intcopyPackageInner(android.content.pm.PackageParser.PackageLite pkg, com.android.internal.os.IParcelFileDescriptorFactory 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], target, "split_" + pkg.splitNames[i] + ".apk");
            }
        }

        return PackageManager.INSTALL_SUCCEEDED;
    
private java.lang.StringcopyPackageToContainerInner(android.content.pm.PackageParser.PackageLite pkg, NativeLibraryHelper.Handle handle, java.lang.String newCid, java.lang.String key, boolean isExternal, boolean isForwardLocked, java.lang.String abiOverride)


        // Calculate container size, rounding up to nearest MB and adding an
        // extra MB for filesystem overhead
        final long sizeBytes = PackageHelper.calculateInstalledSize(pkg, handle,
                isForwardLocked, abiOverride);

        // Create new container
        final String newMountPath = PackageHelper.createSdDir(sizeBytes, newCid, key,
                Process.myUid(), isExternal);
        if (newMountPath == null) {
            throw new IOException("Failed to create container " + newCid);
        }
        final File targetDir = new File(newMountPath);

        try {
            // 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);
                }
            }

            // Extract native code
            final File libraryRoot = new File(targetDir, LIB_DIR_NAME);
            final int res = NativeLibraryHelper.copyNativeBinariesWithOverride(handle, libraryRoot,
                    abiOverride);
            if (res != PackageManager.INSTALL_SUCCEEDED) {
                throw new IOException("Failed to extract native code, res=" + res);
            }

            if (!PackageHelper.finalizeSdDir(newCid)) {
                throw new IOException("Failed to finalize " + newCid);
            }

            if (PackageHelper.isContainerMounted(newCid)) {
                PackageHelper.unMountSdDir(newCid);
            }

        } catch (ErrnoException e) {
            PackageHelper.destroySdDir(newCid);
            throw e.rethrowAsIOException();
        } catch (IOException e) {
            PackageHelper.destroySdDir(newCid);
            throw e;
        }

        return newMountPath;
    
voideraseFiles(java.io.File[] paths)

        for (File path : paths) {
            eraseFiles(path);
        }
    
voideraseFiles(java.io.File path)

        if (path.isDirectory()) {
            String[] files = path.list();
            if (files != null) {
                for (String file : files) {
                    eraseFiles(new File(path, file));
                }
            }
        }
        path.delete();
    
public android.os.IBinderonBind(android.content.Intent intent)

        return mBinder;
    
protected voidonHandleIntent(android.content.Intent intent)

        if (PackageManager.ACTION_CLEAN_EXTERNAL_STORAGE.equals(intent.getAction())) {
            final IPackageManager pm = IPackageManager.Stub.asInterface(
                    ServiceManager.getService("package"));
            PackageCleanItem item = null;
            try {
                while ((item = pm.nextPackageToClean(item)) != null) {
                    final UserEnvironment userEnv = new UserEnvironment(item.userId);
                    eraseFiles(userEnv.buildExternalStorageAppDataDirs(item.packageName));
                    eraseFiles(userEnv.buildExternalStorageAppMediaDirs(item.packageName));
                    if (item.andCode) {
                        eraseFiles(userEnv.buildExternalStorageAppObbDirs(item.packageName));
                    }
                }
            } catch (RemoteException e) {
            }
        }