Search in sources :

Example 81 with VolumeInfo

use of android.os.storage.VolumeInfo in project android_frameworks_base by DirtyUnicorns.

the class MountService method getVolumeList.

@Override
public StorageVolume[] getVolumeList(int uid, String packageName, int flags) {
    final int userId = UserHandle.getUserId(uid);
    final boolean forWrite = (flags & StorageManager.FLAG_FOR_WRITE) != 0;
    final boolean realState = (flags & StorageManager.FLAG_REAL_STATE) != 0;
    final boolean includeInvisible = (flags & StorageManager.FLAG_INCLUDE_INVISIBLE) != 0;
    final boolean userKeyUnlocked;
    final boolean storagePermission;
    final long token = Binder.clearCallingIdentity();
    try {
        userKeyUnlocked = isUserKeyUnlocked(userId);
        storagePermission = mMountServiceInternal.hasExternalStorage(uid, packageName);
    } finally {
        Binder.restoreCallingIdentity(token);
    }
    boolean foundPrimary = false;
    final ArrayList<StorageVolume> res = new ArrayList<>();
    synchronized (mLock) {
        for (int i = 0; i < mVolumes.size(); i++) {
            final VolumeInfo vol = mVolumes.valueAt(i);
            switch(vol.getType()) {
                case VolumeInfo.TYPE_PUBLIC:
                case VolumeInfo.TYPE_EMULATED:
                    break;
                default:
                    continue;
            }
            boolean match = false;
            if (forWrite) {
                match = vol.isVisibleForWrite(userId);
            } else {
                match = vol.isVisibleForRead(userId) || (includeInvisible && vol.getPath() != null);
            }
            if (!match)
                continue;
            boolean reportUnmounted = false;
            if ((vol.getType() == VolumeInfo.TYPE_EMULATED) && !userKeyUnlocked) {
                reportUnmounted = true;
            } else if (!storagePermission && !realState) {
                reportUnmounted = true;
            }
            final StorageVolume userVol = vol.buildStorageVolume(mContext, userId, reportUnmounted);
            if (vol.isPrimary()) {
                res.add(0, userVol);
                foundPrimary = true;
            } else {
                res.add(userVol);
            }
        }
    }
    if (!foundPrimary) {
        Log.w(TAG, "No primary storage defined yet; hacking together a stub");
        final boolean primaryPhysical = SystemProperties.getBoolean(StorageManager.PROP_PRIMARY_PHYSICAL, false);
        final String id = "stub_primary";
        final File path = Environment.getLegacyExternalStorageDirectory();
        final String description = mContext.getString(android.R.string.unknownName);
        final boolean primary = true;
        final boolean removable = primaryPhysical;
        final boolean emulated = !primaryPhysical;
        final long mtpReserveSize = 0L;
        final boolean allowMassStorage = false;
        final long maxFileSize = 0L;
        final UserHandle owner = new UserHandle(userId);
        final String uuid = null;
        final String state = Environment.MEDIA_REMOVED;
        res.add(0, new StorageVolume(id, StorageVolume.STORAGE_ID_INVALID, path, description, primary, removable, emulated, mtpReserveSize, allowMassStorage, maxFileSize, owner, uuid, state));
    }
    return res.toArray(new StorageVolume[res.size()]);
}
Also used : StorageVolume(android.os.storage.StorageVolume) UserHandle(android.os.UserHandle) CopyOnWriteArrayList(java.util.concurrent.CopyOnWriteArrayList) ArrayList(java.util.ArrayList) VolumeInfo(android.os.storage.VolumeInfo) File(java.io.File) AtomicFile(android.util.AtomicFile)

Example 82 with VolumeInfo

use of android.os.storage.VolumeInfo in project android_frameworks_base by DirtyUnicorns.

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 83 with VolumeInfo

use of android.os.storage.VolumeInfo in project android_frameworks_base by DirtyUnicorns.

the class MountService method shouldBenchmark.

private boolean shouldBenchmark() {
    final long benchInterval = Settings.Global.getLong(mContext.getContentResolver(), Settings.Global.STORAGE_BENCHMARK_INTERVAL, -1);
    if (benchInterval == -1) {
        return false;
    } else if (benchInterval == 0) {
        return true;
    }
    synchronized (mLock) {
        for (int i = 0; i < mVolumes.size(); i++) {
            final VolumeInfo vol = mVolumes.valueAt(i);
            final VolumeRecord rec = mRecords.get(vol.fsUuid);
            if (vol.isMountedWritable() && rec != null) {
                final long benchAge = System.currentTimeMillis() - rec.lastBenchMillis;
                if (benchAge >= benchInterval) {
                    return true;
                }
            }
        }
        return false;
    }
}
Also used : VolumeRecord(android.os.storage.VolumeRecord) VolumeInfo(android.os.storage.VolumeInfo)

Example 84 with VolumeInfo

use of android.os.storage.VolumeInfo in project android_frameworks_base by DirtyUnicorns.

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 85 with VolumeInfo

use of android.os.storage.VolumeInfo in project android_frameworks_base by DirtyUnicorns.

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