Search in sources :

Example 71 with VolumeInfo

use of android.os.storage.VolumeInfo in project platform_frameworks_base by android.

the class MountService method unmount.

@Override
public void unmount(String volId) {
    enforcePermission(android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS);
    waitForReady();
    final VolumeInfo vol = findVolumeByIdOrThrow(volId);
    // TODO: expand PMS to know about multiple volumes
    if (vol.isPrimaryPhysical()) {
        final long ident = Binder.clearCallingIdentity();
        try {
            synchronized (mUnmountLock) {
                mUnmountSignal = new CountDownLatch(1);
                mPms.updateExternalMediaStatus(false, true);
                waitForLatch(mUnmountSignal, "mUnmountSignal");
                mUnmountSignal = null;
            }
        } finally {
            Binder.restoreCallingIdentity(ident);
        }
    }
    try {
        mConnector.execute("volume", "unmount", vol.id);
    } catch (NativeDaemonConnectorException e) {
        throw e.rethrowAsParcelableException();
    }
}
Also used : VolumeInfo(android.os.storage.VolumeInfo) CountDownLatch(java.util.concurrent.CountDownLatch)

Example 72 with VolumeInfo

use of android.os.storage.VolumeInfo in project platform_frameworks_base by android.

the class MountService method format.

@Override
public void format(String volId) {
    enforcePermission(android.Manifest.permission.MOUNT_FORMAT_FILESYSTEMS);
    waitForReady();
    final VolumeInfo vol = findVolumeByIdOrThrow(volId);
    try {
        mConnector.execute("volume", "format", vol.id, "auto");
    } catch (NativeDaemonConnectorException e) {
        throw e.rethrowAsParcelableException();
    }
}
Also used : VolumeInfo(android.os.storage.VolumeInfo)

Example 73 with VolumeInfo

use of android.os.storage.VolumeInfo in project platform_frameworks_base by android.

the class MountService method setPrimaryStorageUuid.

@Override
public void setPrimaryStorageUuid(String volumeUuid, IPackageMoveObserver callback) {
    enforcePermission(android.Manifest.permission.MOUNT_UNMOUNT_FILESYSTEMS);
    waitForReady();
    final VolumeInfo from;
    final VolumeInfo to;
    synchronized (mLock) {
        if (Objects.equals(mPrimaryStorageUuid, volumeUuid)) {
            throw new IllegalArgumentException("Primary storage already at " + volumeUuid);
        }
        if (mMoveCallback != null) {
            throw new IllegalStateException("Move already in progress");
        }
        mMoveCallback = callback;
        mMoveTargetUuid = volumeUuid;
        // the current storage location, so we have nothing to move.
        if (Objects.equals(StorageManager.UUID_PRIMARY_PHYSICAL, mPrimaryStorageUuid) || Objects.equals(StorageManager.UUID_PRIMARY_PHYSICAL, volumeUuid)) {
            Slog.d(TAG, "Skipping move to/from primary physical");
            onMoveStatusLocked(MOVE_STATUS_COPY_FINISHED);
            onMoveStatusLocked(PackageManager.MOVE_SUCCEEDED);
            mHandler.obtainMessage(H_RESET).sendToTarget();
            return;
        } else {
            from = findStorageForUuid(mPrimaryStorageUuid);
            to = findStorageForUuid(volumeUuid);
            if (from == null) {
                Slog.w(TAG, "Failing move due to missing from volume " + mPrimaryStorageUuid);
                onMoveStatusLocked(PackageManager.MOVE_FAILED_INTERNAL_ERROR);
                return;
            } else if (to == null) {
                Slog.w(TAG, "Failing move due to missing to volume " + volumeUuid);
                onMoveStatusLocked(PackageManager.MOVE_FAILED_INTERNAL_ERROR);
                return;
            }
        }
    }
    try {
        mConnector.execute("volume", "move_storage", from.id, to.id);
    } catch (NativeDaemonConnectorException e) {
        throw e.rethrowAsParcelableException();
    }
}
Also used : VolumeInfo(android.os.storage.VolumeInfo)

Example 74 with VolumeInfo

use of android.os.storage.VolumeInfo in project platform_frameworks_base by android.

the class MountService method onDiskScannedLocked.

private void onDiskScannedLocked(DiskInfo disk) {
    int volumeCount = 0;
    for (int i = 0; i < mVolumes.size(); i++) {
        final VolumeInfo vol = mVolumes.valueAt(i);
        if (Objects.equals(disk.id, vol.getDiskId())) {
            volumeCount++;
        }
    }
    final Intent intent = new Intent(DiskInfo.ACTION_DISK_SCANNED);
    intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT | Intent.FLAG_RECEIVER_INCLUDE_BACKGROUND);
    intent.putExtra(DiskInfo.EXTRA_DISK_ID, disk.id);
    intent.putExtra(DiskInfo.EXTRA_VOLUME_COUNT, volumeCount);
    mHandler.obtainMessage(H_INTERNAL_BROADCAST, intent).sendToTarget();
    final CountDownLatch latch = mDiskScanLatches.remove(disk.id);
    if (latch != null) {
        latch.countDown();
    }
    disk.volumeCount = volumeCount;
    mCallbacks.notifyDiskScanned(disk, volumeCount);
}
Also used : VolumeInfo(android.os.storage.VolumeInfo) Intent(android.content.Intent) CountDownLatch(java.util.concurrent.CountDownLatch)

Example 75 with VolumeInfo

use of android.os.storage.VolumeInfo in project platform_frameworks_base by android.

the class PackageManagerService method movePackageInternal.

private void movePackageInternal(final String packageName, final String volumeUuid, final int moveId, UserHandle user) throws PackageManagerException {
    final StorageManager storage = mContext.getSystemService(StorageManager.class);
    final PackageManager pm = mContext.getPackageManager();
    final boolean currentAsec;
    final String currentVolumeUuid;
    final File codeFile;
    final String installerPackageName;
    final String packageAbiOverride;
    final int appId;
    final String seinfo;
    final String label;
    final int targetSdkVersion;
    final PackageFreezer freezer;
    final int[] installedUserIds;
    // reader
    synchronized (mPackages) {
        final PackageParser.Package pkg = mPackages.get(packageName);
        final PackageSetting ps = mSettings.mPackages.get(packageName);
        if (pkg == null || ps == null) {
            throw new PackageManagerException(MOVE_FAILED_DOESNT_EXIST, "Missing package");
        }
        if (pkg.applicationInfo.isSystemApp()) {
            throw new PackageManagerException(MOVE_FAILED_SYSTEM_PACKAGE, "Cannot move system application");
        }
        if (pkg.applicationInfo.isExternalAsec()) {
            currentAsec = true;
            currentVolumeUuid = StorageManager.UUID_PRIMARY_PHYSICAL;
        } else if (pkg.applicationInfo.isForwardLocked()) {
            currentAsec = true;
            currentVolumeUuid = "forward_locked";
        } else {
            currentAsec = false;
            currentVolumeUuid = ps.volumeUuid;
            final File probe = new File(pkg.codePath);
            final File probeOat = new File(probe, "oat");
            if (!probe.isDirectory() || !probeOat.isDirectory()) {
                throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, "Move only supported for modern cluster style installs");
            }
        }
        if (Objects.equals(currentVolumeUuid, volumeUuid)) {
            throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, "Package already moved to " + volumeUuid);
        }
        if (pkg.applicationInfo.isInternal() && isPackageDeviceAdminOnAnyUser(packageName)) {
            throw new PackageManagerException(MOVE_FAILED_DEVICE_ADMIN, "Device admin cannot be moved");
        }
        if (mFrozenPackages.contains(packageName)) {
            throw new PackageManagerException(MOVE_FAILED_OPERATION_PENDING, "Failed to move already frozen package");
        }
        codeFile = new File(pkg.codePath);
        installerPackageName = ps.installerPackageName;
        packageAbiOverride = ps.cpuAbiOverrideString;
        appId = UserHandle.getAppId(pkg.applicationInfo.uid);
        seinfo = pkg.applicationInfo.seinfo;
        label = String.valueOf(pm.getApplicationLabel(pkg.applicationInfo));
        targetSdkVersion = pkg.applicationInfo.targetSdkVersion;
        freezer = freezePackage(packageName, "movePackageInternal");
        installedUserIds = ps.queryInstalledUsers(sUserManager.getUserIds(), true);
    }
    final Bundle extras = new Bundle();
    extras.putString(Intent.EXTRA_PACKAGE_NAME, packageName);
    extras.putString(Intent.EXTRA_TITLE, label);
    mMoveCallbacks.notifyCreated(moveId, extras);
    int installFlags;
    final boolean moveCompleteApp;
    final File measurePath;
    if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, volumeUuid)) {
        installFlags = INSTALL_INTERNAL;
        moveCompleteApp = !currentAsec;
        measurePath = Environment.getDataAppDirectory(volumeUuid);
    } else if (Objects.equals(StorageManager.UUID_PRIMARY_PHYSICAL, volumeUuid)) {
        installFlags = INSTALL_EXTERNAL;
        moveCompleteApp = false;
        measurePath = storage.getPrimaryPhysicalVolume().getPath();
    } else {
        final VolumeInfo volume = storage.findVolumeByUuid(volumeUuid);
        if (volume == null || volume.getType() != VolumeInfo.TYPE_PRIVATE || !volume.isMountedWritable()) {
            freezer.close();
            throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, "Move location not mounted private volume");
        }
        Preconditions.checkState(!currentAsec);
        installFlags = INSTALL_INTERNAL;
        moveCompleteApp = true;
        measurePath = Environment.getDataAppDirectory(volumeUuid);
    }
    final PackageStats stats = new PackageStats(null, -1);
    synchronized (mInstaller) {
        for (int userId : installedUserIds) {
            if (!getPackageSizeInfoLI(packageName, userId, stats)) {
                freezer.close();
                throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, "Failed to measure package size");
            }
        }
    }
    if (DEBUG_INSTALL)
        Slog.d(TAG, "Measured code size " + stats.codeSize + ", data size " + stats.dataSize);
    final long startFreeBytes = measurePath.getFreeSpace();
    final long sizeBytes;
    if (moveCompleteApp) {
        sizeBytes = stats.codeSize + stats.dataSize;
    } else {
        sizeBytes = stats.codeSize;
    }
    if (sizeBytes > storage.getStorageBytesUntilLow(measurePath)) {
        freezer.close();
        throw new PackageManagerException(MOVE_FAILED_INTERNAL_ERROR, "Not enough free space to move");
    }
    mMoveCallbacks.notifyStatusChanged(moveId, 10);
    final CountDownLatch installedLatch = new CountDownLatch(1);
    final IPackageInstallObserver2 installObserver = new IPackageInstallObserver2.Stub() {

        @Override
        public void onUserActionRequired(Intent intent) throws RemoteException {
            throw new IllegalStateException();
        }

        @Override
        public void onPackageInstalled(String basePackageName, int returnCode, String msg, Bundle extras) throws RemoteException {
            if (DEBUG_INSTALL)
                Slog.d(TAG, "Install result for move: " + PackageManager.installStatusToString(returnCode, msg));
            installedLatch.countDown();
            freezer.close();
            final int status = PackageManager.installStatusToPublicStatus(returnCode);
            switch(status) {
                case PackageInstaller.STATUS_SUCCESS:
                    mMoveCallbacks.notifyStatusChanged(moveId, PackageManager.MOVE_SUCCEEDED);
                    break;
                case PackageInstaller.STATUS_FAILURE_STORAGE:
                    mMoveCallbacks.notifyStatusChanged(moveId, PackageManager.MOVE_FAILED_INSUFFICIENT_STORAGE);
                    break;
                default:
                    mMoveCallbacks.notifyStatusChanged(moveId, PackageManager.MOVE_FAILED_INTERNAL_ERROR);
                    break;
            }
        }
    };
    final MoveInfo move;
    if (moveCompleteApp) {
        // Kick off a thread to report progress estimates
        new Thread() {

            @Override
            public void run() {
                while (true) {
                    try {
                        if (installedLatch.await(1, TimeUnit.SECONDS)) {
                            break;
                        }
                    } catch (InterruptedException ignored) {
                    }
                    final long deltaFreeBytes = startFreeBytes - measurePath.getFreeSpace();
                    final int progress = 10 + (int) MathUtils.constrain(((deltaFreeBytes * 80) / sizeBytes), 0, 80);
                    mMoveCallbacks.notifyStatusChanged(moveId, progress);
                }
            }
        }.start();
        final String dataAppName = codeFile.getName();
        move = new MoveInfo(moveId, currentVolumeUuid, volumeUuid, packageName, dataAppName, appId, seinfo, targetSdkVersion);
    } else {
        move = null;
    }
    installFlags |= PackageManager.INSTALL_REPLACE_EXISTING;
    final Message msg = mHandler.obtainMessage(INIT_COPY);
    final OriginInfo origin = OriginInfo.fromExistingFile(codeFile);
    final InstallParams params = new InstallParams(origin, move, installObserver, installFlags, installerPackageName, volumeUuid, null, /*verificationInfo*/
    user, packageAbiOverride, null, /*grantedPermissions*/
    null);
    params.setTraceMethod("movePackage").setTraceCookie(System.identityHashCode(params));
    msg.obj = params;
    Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "movePackage", System.identityHashCode(msg.obj));
    Trace.asyncTraceBegin(TRACE_TAG_PACKAGE_MANAGER, "queueInstall", System.identityHashCode(msg.obj));
    mHandler.sendMessage(msg);
}
Also used : Message(android.os.Message) StorageManager(android.os.storage.StorageManager) VolumeInfo(android.os.storage.VolumeInfo) PackageManager(android.content.pm.PackageManager) IPackageManager(android.content.pm.IPackageManager) PackageStats(android.content.pm.PackageStats) Bundle(android.os.Bundle) Intent(android.content.Intent) CountDownLatch(java.util.concurrent.CountDownLatch) ServiceThread(com.android.server.ServiceThread) FgThread(com.android.server.FgThread) PackageParser(android.content.pm.PackageParser) IPackageInstallObserver2(android.content.pm.IPackageInstallObserver2) PackageParser.isApkFile(android.content.pm.PackageParser.isApkFile) File(java.io.File) DexFile(dalvik.system.DexFile) StrictJarFile(android.util.jar.StrictJarFile)

Aggregations

VolumeInfo (android.os.storage.VolumeInfo)145 StorageManager (android.os.storage.StorageManager)43 File (java.io.File)31 ArrayList (java.util.ArrayList)26 Intent (android.content.Intent)21 CountDownLatch (java.util.concurrent.CountDownLatch)18 DiskInfo (android.os.storage.DiskInfo)16 VolumeRecord (android.os.storage.VolumeRecord)16 Test (org.junit.Test)12 NonNull (android.annotation.NonNull)10 Notification (android.app.Notification)10 PendingIntent (android.app.PendingIntent)10 StorageVolume (android.os.storage.StorageVolume)10 IOException (java.io.IOException)10 CopyOnWriteArrayList (java.util.concurrent.CopyOnWriteArrayList)10 Bundle (android.os.Bundle)9 ApplicationInfo (android.content.pm.ApplicationInfo)8 PackageStats (android.content.pm.PackageStats)8 FragmentManager (android.app.FragmentManager)5 FragmentTransaction (android.app.FragmentTransaction)5