Search in sources :

Example 26 with VolumeInfo

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

the class OpenExternalDirectoryActivity method showFragment.

/**
     * Validates the given path (volume + directory) and display the appropriate dialog asking the
     * user to grant access to it.
     */
private static boolean showFragment(OpenExternalDirectoryActivity activity, int userId, StorageVolume storageVolume, String directoryName) {
    if (DEBUG)
        Log.d(TAG, "showFragment() for volume " + storageVolume.dump() + ", directory " + directoryName + ", and user " + userId);
    final boolean isRoot = directoryName.equals(DIRECTORY_ROOT);
    final boolean isPrimary = storageVolume.isPrimary();
    if (isRoot && isPrimary) {
        if (DEBUG)
            Log.d(TAG, "root access requested on primary volume");
        return false;
    }
    final File volumeRoot = storageVolume.getPathFile();
    File file;
    try {
        file = isRoot ? volumeRoot : new File(volumeRoot, directoryName).getCanonicalFile();
    } catch (IOException e) {
        Log.e(TAG, "Could not get canonical file for volume " + storageVolume.dump() + " and directory " + directoryName);
        logInvalidScopedAccessRequest(activity, SCOPED_DIRECTORY_ACCESS_ERROR);
        return false;
    }
    final StorageManager sm = (StorageManager) activity.getSystemService(Context.STORAGE_SERVICE);
    final String root, directory;
    if (isRoot) {
        root = volumeRoot.getAbsolutePath();
        directory = ".";
    } else {
        root = file.getParent();
        directory = file.getName();
        // Verify directory is valid.
        if (TextUtils.isEmpty(directory) || !isStandardDirectory(directory)) {
            if (DEBUG)
                Log.d(TAG, "Directory '" + directory + "' is not standard (full path: '" + file.getAbsolutePath() + "')");
            logInvalidScopedAccessRequest(activity, SCOPED_DIRECTORY_ACCESS_INVALID_DIRECTORY);
            return false;
        }
    }
    // Gets volume label and converted path.
    String volumeLabel = null;
    String volumeUuid = null;
    final List<VolumeInfo> volumes = sm.getVolumes();
    if (DEBUG)
        Log.d(TAG, "Number of volumes: " + volumes.size());
    File internalRoot = null;
    boolean found = true;
    for (VolumeInfo volume : volumes) {
        if (isRightVolume(volume, root, userId)) {
            found = true;
            internalRoot = volume.getInternalPathForUser(userId);
            // Must convert path before calling getDocIdForFileCreateNewDir()
            if (DEBUG)
                Log.d(TAG, "Converting " + root + " to " + internalRoot);
            file = isRoot ? internalRoot : new File(internalRoot, directory);
            volumeUuid = storageVolume.getUuid();
            volumeLabel = sm.getBestVolumeDescription(volume);
            if (TextUtils.isEmpty(volumeLabel)) {
                volumeLabel = storageVolume.getDescription(activity);
            }
            if (TextUtils.isEmpty(volumeLabel)) {
                volumeLabel = activity.getString(android.R.string.unknownName);
                Log.w(TAG, "No volume description  for " + volume + "; using " + volumeLabel);
            }
            break;
        }
    }
    if (internalRoot == null) {
        // Should not happen on normal circumstances, unless app crafted an invalid volume
        // using reflection or the list of mounted volumes changed.
        Log.e(TAG, "Didn't find right volume for '" + storageVolume.dump() + "' on " + volumes);
        return false;
    }
    // Checks if the user has granted the permission already.
    final Intent intent = getIntentForExistingPermission(activity, isRoot, internalRoot, file);
    if (intent != null) {
        logValidScopedAccessRequest(activity, directory, SCOPED_DIRECTORY_ACCESS_ALREADY_GRANTED);
        activity.setResult(RESULT_OK, intent);
        activity.finish();
        return true;
    }
    if (!found) {
        Log.e(TAG, "Could not get volume for " + file);
        logInvalidScopedAccessRequest(activity, SCOPED_DIRECTORY_ACCESS_ERROR);
        return false;
    }
    // Gets the package label.
    final String appLabel = getAppLabel(activity);
    if (appLabel == null) {
        // Error already logged.
        return false;
    }
    // Sets args that will be retrieve on onCreate()
    final Bundle args = new Bundle();
    args.putString(EXTRA_FILE, file.getAbsolutePath());
    args.putString(EXTRA_VOLUME_LABEL, volumeLabel);
    args.putString(EXTRA_VOLUME_UUID, volumeUuid);
    args.putString(EXTRA_APP_LABEL, appLabel);
    args.putBoolean(EXTRA_IS_ROOT, isRoot);
    args.putBoolean(EXTRA_IS_PRIMARY, isPrimary);
    final FragmentManager fm = activity.getFragmentManager();
    final FragmentTransaction ft = fm.beginTransaction();
    final OpenExternalDirectoryDialogFragment fragment = new OpenExternalDirectoryDialogFragment();
    fragment.setArguments(args);
    ft.add(fragment, FM_TAG);
    ft.commitAllowingStateLoss();
    return true;
}
Also used : FragmentManager(android.app.FragmentManager) FragmentTransaction(android.app.FragmentTransaction) Bundle(android.os.Bundle) StorageManager(android.os.storage.StorageManager) VolumeInfo(android.os.storage.VolumeInfo) Intent(android.content.Intent) IOException(java.io.IOException) File(java.io.File)

Example 27 with VolumeInfo

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

the class ExternalStorageProvider method updateVolumesLocked.

private void updateVolumesLocked() {
    mRoots.clear();
    VolumeInfo primaryVolume = null;
    final int userId = UserHandle.myUserId();
    final List<VolumeInfo> volumes = mStorageManager.getVolumes();
    for (VolumeInfo volume : volumes) {
        if (!volume.isMountedReadable())
            continue;
        final String rootId;
        final String title;
        if (volume.getType() == VolumeInfo.TYPE_EMULATED) {
            // a time, and it's always considered the primary
            if (DEBUG)
                Log.d(TAG, "Found primary volume: " + volume);
            rootId = ROOT_ID_PRIMARY_EMULATED;
            if (VolumeInfo.ID_EMULATED_INTERNAL.equals(volume.getId())) {
                // This is basically the user's primary device storage.
                // Use device name for the volume since this is likely same thing
                // the user sees when they mount their phone on another device.
                String deviceName = Settings.Global.getString(getContext().getContentResolver(), Settings.Global.DEVICE_NAME);
                // Device name should always be set. In case it isn't, though,
                // fall back to a localized "Internal Storage" string.
                title = !TextUtils.isEmpty(deviceName) ? deviceName : getContext().getString(R.string.root_internal_storage);
            } else {
                // This should cover all other storage devices, like an SD card
                // or USB OTG drive plugged in. Using getBestVolumeDescription()
                // will give us a nice string like "Samsung SD card" or "SanDisk USB drive"
                final VolumeInfo privateVol = mStorageManager.findPrivateForEmulated(volume);
                title = mStorageManager.getBestVolumeDescription(privateVol);
            }
        } else if (volume.getType() == VolumeInfo.TYPE_PUBLIC && volume.getMountUserId() == userId) {
            rootId = volume.getFsUuid();
            title = mStorageManager.getBestVolumeDescription(volume);
        } else {
            // Unsupported volume; ignore
            continue;
        }
        if (TextUtils.isEmpty(rootId)) {
            Log.d(TAG, "Missing UUID for " + volume.getId() + "; skipping");
            continue;
        }
        if (mRoots.containsKey(rootId)) {
            Log.w(TAG, "Duplicate UUID " + rootId + " for " + volume.getId() + "; skipping");
            continue;
        }
        final RootInfo root = new RootInfo();
        mRoots.put(rootId, root);
        root.rootId = rootId;
        root.flags = Root.FLAG_LOCAL_ONLY | Root.FLAG_SUPPORTS_SEARCH | Root.FLAG_SUPPORTS_IS_CHILD;
        final DiskInfo disk = volume.getDisk();
        if (DEBUG)
            Log.d(TAG, "Disk for root " + rootId + " is " + disk);
        if (disk != null && disk.isSd()) {
            root.flags |= Root.FLAG_REMOVABLE_SD;
        } else if (disk != null && disk.isUsb()) {
            root.flags |= Root.FLAG_REMOVABLE_USB;
        }
        if (volume.isPrimary()) {
            // save off the primary volume for subsequent "Home" dir initialization.
            primaryVolume = volume;
            root.flags |= Root.FLAG_ADVANCED;
        }
        // Dunno when this would NOT be the case, but never hurts to be correct.
        if (volume.isMountedWritable()) {
            root.flags |= Root.FLAG_SUPPORTS_CREATE;
        }
        root.title = title;
        if (volume.getType() == VolumeInfo.TYPE_PUBLIC) {
            root.flags |= Root.FLAG_HAS_SETTINGS;
        }
        if (volume.isVisibleForRead(userId)) {
            root.visiblePath = volume.getPathForUser(userId);
        } else {
            root.visiblePath = null;
        }
        root.path = volume.getInternalPathForUser(userId);
        try {
            root.docId = getDocIdForFile(root.path);
        } catch (FileNotFoundException e) {
            throw new IllegalStateException(e);
        }
    }
    // by calling either getPathForUser, or getInternalPathForUser.
    if (primaryVolume != null && primaryVolume.isVisible()) {
        final RootInfo root = new RootInfo();
        root.rootId = ROOT_ID_HOME;
        mRoots.put(root.rootId, root);
        root.title = getContext().getString(R.string.root_documents);
        // Only report bytes on *volumes*...as a matter of policy.
        root.reportAvailableBytes = false;
        root.flags = Root.FLAG_LOCAL_ONLY | Root.FLAG_SUPPORTS_SEARCH | Root.FLAG_SUPPORTS_IS_CHILD;
        // Dunno when this would NOT be the case, but never hurts to be correct.
        if (primaryVolume.isMountedWritable()) {
            root.flags |= Root.FLAG_SUPPORTS_CREATE;
        }
        // Create the "Documents" directory on disk (don't use the localized title).
        root.visiblePath = new File(primaryVolume.getPathForUser(userId), Environment.DIRECTORY_DOCUMENTS);
        root.path = new File(primaryVolume.getInternalPathForUser(userId), Environment.DIRECTORY_DOCUMENTS);
        try {
            root.docId = getDocIdForFile(root.path);
        } catch (FileNotFoundException e) {
            throw new IllegalStateException(e);
        }
    }
    Log.d(TAG, "After updating volumes, found " + mRoots.size() + " active roots");
    // Note this affects content://com.android.externalstorage.documents/root/39BD-07C5
    // as well as content://com.android.externalstorage.documents/document/*/children,
    // so just notify on content://com.android.externalstorage.documents/.
    getContext().getContentResolver().notifyChange(BASE_URI, null, false);
}
Also used : FileNotFoundException(java.io.FileNotFoundException) DiskInfo(android.os.storage.DiskInfo) VolumeInfo(android.os.storage.VolumeInfo) File(java.io.File) Point(android.graphics.Point)

Example 28 with VolumeInfo

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

the class ExternalStorageProvider method updateVolumesLocked.

private void updateVolumesLocked() {
    mRoots.clear();
    VolumeInfo primaryVolume = null;
    final int userId = UserHandle.myUserId();
    final List<VolumeInfo> volumes = mStorageManager.getVolumes();
    for (VolumeInfo volume : volumes) {
        if (!volume.isMountedReadable())
            continue;
        final String rootId;
        final String title;
        if (volume.getType() == VolumeInfo.TYPE_EMULATED) {
            // a time, and it's always considered the primary
            if (DEBUG)
                Log.d(TAG, "Found primary volume: " + volume);
            rootId = ROOT_ID_PRIMARY_EMULATED;
            if (VolumeInfo.ID_EMULATED_INTERNAL.equals(volume.getId())) {
                // This is basically the user's primary device storage.
                // Use device name for the volume since this is likely same thing
                // the user sees when they mount their phone on another device.
                String deviceName = Settings.Global.getString(getContext().getContentResolver(), Settings.Global.DEVICE_NAME);
                // Device name should always be set. In case it isn't, though,
                // fall back to a localized "Internal Storage" string.
                title = !TextUtils.isEmpty(deviceName) ? deviceName : getContext().getString(R.string.root_internal_storage);
            } else {
                // This should cover all other storage devices, like an SD card
                // or USB OTG drive plugged in. Using getBestVolumeDescription()
                // will give us a nice string like "Samsung SD card" or "SanDisk USB drive"
                final VolumeInfo privateVol = mStorageManager.findPrivateForEmulated(volume);
                title = mStorageManager.getBestVolumeDescription(privateVol);
            }
        } else if (volume.getType() == VolumeInfo.TYPE_PUBLIC) {
            rootId = volume.getFsUuid();
            title = mStorageManager.getBestVolumeDescription(volume);
        } else {
            // Unsupported volume; ignore
            continue;
        }
        if (TextUtils.isEmpty(rootId)) {
            Log.d(TAG, "Missing UUID for " + volume.getId() + "; skipping");
            continue;
        }
        if (mRoots.containsKey(rootId)) {
            Log.w(TAG, "Duplicate UUID " + rootId + " for " + volume.getId() + "; skipping");
            continue;
        }
        final RootInfo root = new RootInfo();
        mRoots.put(rootId, root);
        root.rootId = rootId;
        root.flags = Root.FLAG_LOCAL_ONLY | Root.FLAG_SUPPORTS_SEARCH | Root.FLAG_SUPPORTS_IS_CHILD;
        final DiskInfo disk = volume.getDisk();
        if (DEBUG)
            Log.d(TAG, "Disk for root " + rootId + " is " + disk);
        if (disk != null && disk.isSd()) {
            root.flags |= Root.FLAG_REMOVABLE_SD;
        } else if (disk != null && disk.isUsb()) {
            root.flags |= Root.FLAG_REMOVABLE_USB;
        }
        if (volume.isPrimary()) {
            // save off the primary volume for subsequent "Home" dir initialization.
            primaryVolume = volume;
            root.flags |= Root.FLAG_ADVANCED;
        }
        // Dunno when this would NOT be the case, but never hurts to be correct.
        if (volume.isMountedWritable()) {
            root.flags |= Root.FLAG_SUPPORTS_CREATE;
        }
        root.title = title;
        if (volume.getType() == VolumeInfo.TYPE_PUBLIC) {
            root.flags |= Root.FLAG_HAS_SETTINGS;
        }
        if (volume.isVisibleForRead(userId)) {
            root.visiblePath = volume.getPathForUser(userId);
        } else {
            root.visiblePath = null;
        }
        root.path = volume.getInternalPathForUser(userId);
        try {
            root.docId = getDocIdForFile(root.path);
        } catch (FileNotFoundException e) {
            throw new IllegalStateException(e);
        }
    }
    // by calling either getPathForUser, or getInternalPathForUser.
    if (primaryVolume != null && primaryVolume.isVisible()) {
        final RootInfo root = new RootInfo();
        root.rootId = ROOT_ID_HOME;
        mRoots.put(root.rootId, root);
        root.title = getContext().getString(R.string.root_documents);
        // Only report bytes on *volumes*...as a matter of policy.
        root.reportAvailableBytes = false;
        root.flags = Root.FLAG_LOCAL_ONLY | Root.FLAG_SUPPORTS_SEARCH | Root.FLAG_SUPPORTS_IS_CHILD;
        // Dunno when this would NOT be the case, but never hurts to be correct.
        if (primaryVolume.isMountedWritable()) {
            root.flags |= Root.FLAG_SUPPORTS_CREATE;
        }
        // Create the "Documents" directory on disk (don't use the localized title).
        root.visiblePath = new File(primaryVolume.getPathForUser(userId), Environment.DIRECTORY_DOCUMENTS);
        root.path = new File(primaryVolume.getInternalPathForUser(userId), Environment.DIRECTORY_DOCUMENTS);
        try {
            root.docId = getDocIdForFile(root.path);
        } catch (FileNotFoundException e) {
            throw new IllegalStateException(e);
        }
    }
    Log.d(TAG, "After updating volumes, found " + mRoots.size() + " active roots");
    // Note this affects content://com.android.externalstorage.documents/root/39BD-07C5
    // as well as content://com.android.externalstorage.documents/document/*/children,
    // so just notify on content://com.android.externalstorage.documents/.
    getContext().getContentResolver().notifyChange(BASE_URI, null, false);
}
Also used : FileNotFoundException(java.io.FileNotFoundException) DiskInfo(android.os.storage.DiskInfo) VolumeInfo(android.os.storage.VolumeInfo) File(java.io.File) Point(android.graphics.Point)

Example 29 with VolumeInfo

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

the class MountService method onVolumeCreatedLocked.

private void onVolumeCreatedLocked(VolumeInfo vol) {
    if (mPms.isOnlyCoreApps()) {
        Slog.d(TAG, "System booted in core-only mode; ignoring volume " + vol.getId());
        return;
    }
    if (vol.type == VolumeInfo.TYPE_EMULATED) {
        final StorageManager storage = mContext.getSystemService(StorageManager.class);
        final VolumeInfo privateVol = storage.findPrivateForEmulated(vol);
        if (Objects.equals(StorageManager.UUID_PRIVATE_INTERNAL, mPrimaryStorageUuid) && VolumeInfo.ID_PRIVATE_INTERNAL.equals(privateVol.id)) {
            Slog.v(TAG, "Found primary storage at " + vol);
            vol.mountFlags |= VolumeInfo.MOUNT_FLAG_PRIMARY;
            vol.mountFlags |= VolumeInfo.MOUNT_FLAG_VISIBLE;
            mHandler.obtainMessage(H_VOLUME_MOUNT, vol).sendToTarget();
        } else if (Objects.equals(privateVol.fsUuid, mPrimaryStorageUuid)) {
            Slog.v(TAG, "Found primary storage at " + vol);
            vol.mountFlags |= VolumeInfo.MOUNT_FLAG_PRIMARY;
            vol.mountFlags |= VolumeInfo.MOUNT_FLAG_VISIBLE;
            mHandler.obtainMessage(H_VOLUME_MOUNT, vol).sendToTarget();
        }
    } else if (vol.type == VolumeInfo.TYPE_PUBLIC) {
        // TODO: only look at first public partition
        if (Objects.equals(StorageManager.UUID_PRIMARY_PHYSICAL, mPrimaryStorageUuid) && vol.disk.isDefaultPrimary()) {
            Slog.v(TAG, "Found primary storage at " + vol);
            vol.mountFlags |= VolumeInfo.MOUNT_FLAG_PRIMARY;
            vol.mountFlags |= VolumeInfo.MOUNT_FLAG_VISIBLE;
        }
        // public API requirement of being in a stable location.
        if (vol.disk.isAdoptable()) {
            vol.mountFlags |= VolumeInfo.MOUNT_FLAG_VISIBLE;
        }
        vol.mountUserId = mCurrentUserId;
        mHandler.obtainMessage(H_VOLUME_MOUNT, vol).sendToTarget();
    } else if (vol.type == VolumeInfo.TYPE_PRIVATE) {
        mHandler.obtainMessage(H_VOLUME_MOUNT, vol).sendToTarget();
    } else {
        Slog.d(TAG, "Skipping automatic mounting of " + vol);
    }
}
Also used : StorageManager(android.os.storage.StorageManager) VolumeInfo(android.os.storage.VolumeInfo)

Example 30 with VolumeInfo

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

the class MountService method shouldBenchmark.

private boolean shouldBenchmark() {
    final long benchInterval = Settings.Global.getLong(mContext.getContentResolver(), Settings.Global.STORAGE_BENCHMARK_INTERVAL, DateUtils.WEEK_IN_MILLIS);
    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)

Aggregations

VolumeInfo (android.os.storage.VolumeInfo)290 StorageManager (android.os.storage.StorageManager)81 File (java.io.File)49 Test (org.junit.Test)42 Intent (android.content.Intent)39 DiskInfo (android.os.storage.DiskInfo)29 Bundle (android.os.Bundle)28 ArrayList (java.util.ArrayList)26 VolumeRecord (android.os.storage.VolumeRecord)22 Context (android.content.Context)21 Before (org.junit.Before)21 UserHandle (android.os.UserHandle)19 LayoutInflater (android.view.LayoutInflater)19 CountDownLatch (java.util.concurrent.CountDownLatch)18 IOException (java.io.IOException)17 StorageStatsManager (android.app.usage.StorageStatsManager)14 MenuItem (android.view.MenuItem)14 StorageVolumeProvider (com.android.settingslib.deviceinfo.StorageVolumeProvider)14 NonNull (android.annotation.NonNull)10 Notification (android.app.Notification)10