Search in sources :

Example 11 with VolumeInfo

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

the class AppCollectorTest method testAppOnExternalVolume.

@Test
public void testAppOnExternalVolume() throws Exception {
    addApplication("com.test.app", "differentuuid");
    VolumeInfo volume = new VolumeInfo("testuuid", 0, null, null);
    volume.fsUuid = "testuuid";
    AppCollector collector = new AppCollector(mContext, volume);
    assertThat(collector.getPackageStats(TIMEOUT)).isEmpty();
}
Also used : VolumeInfo(android.os.storage.VolumeInfo) Test(org.junit.Test)

Example 12 with VolumeInfo

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

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

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

the class Sm method runListVolumes.

public void runListVolumes() throws RemoteException {
    final String filter = nextArg();
    final int filterType;
    if ("public".equals(filter)) {
        filterType = VolumeInfo.TYPE_PUBLIC;
    } else if ("private".equals(filter)) {
        filterType = VolumeInfo.TYPE_PRIVATE;
    } else if ("emulated".equals(filter)) {
        filterType = VolumeInfo.TYPE_EMULATED;
    } else {
        filterType = -1;
    }
    final VolumeInfo[] vols = mSm.getVolumes(0);
    for (VolumeInfo vol : vols) {
        if (filterType == -1 || filterType == vol.getType()) {
            final String envState = VolumeInfo.getEnvironmentForState(vol.getState());
            System.out.println(vol.getId() + " " + envState + " " + vol.getFsUuid());
        }
    }
}
Also used : VolumeInfo(android.os.storage.VolumeInfo)

Example 14 with VolumeInfo

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

the class PackageHelper method resolveInstallVolume.

/**
     * Given a requested {@link PackageInfo#installLocation} and calculated
     * install size, pick the actual volume to install the app. Only considers
     * internal and private volumes, and prefers to keep an existing package on
     * its current volume.
     *
     * @return the {@link VolumeInfo#fsUuid} to install onto, or {@code null}
     *         for internal storage.
     */
public static String resolveInstallVolume(Context context, String packageName, int installLocation, long sizeBytes) throws IOException {
    final boolean forceAllowOnExternal = Settings.Global.getInt(context.getContentResolver(), Settings.Global.FORCE_ALLOW_ON_EXTERNAL, 0) != 0;
    // TODO: handle existing apps installed in ASEC; currently assumes
    // they'll end up back on internal storage
    ApplicationInfo existingInfo = null;
    try {
        existingInfo = context.getPackageManager().getApplicationInfo(packageName, PackageManager.GET_UNINSTALLED_PACKAGES);
    } catch (NameNotFoundException ignored) {
    }
    final StorageManager storageManager = context.getSystemService(StorageManager.class);
    final boolean fitsOnInternal = fitsOnInternal(context, sizeBytes);
    final ArraySet<String> allCandidates = new ArraySet<>();
    VolumeInfo bestCandidate = null;
    long bestCandidateAvailBytes = Long.MIN_VALUE;
    for (VolumeInfo vol : storageManager.getVolumes()) {
        if (vol.type == VolumeInfo.TYPE_PRIVATE && vol.isMountedWritable()) {
            final long availBytes = storageManager.getStorageBytesUntilLow(new File(vol.path));
            if (availBytes >= sizeBytes) {
                allCandidates.add(vol.fsUuid);
            }
            if (availBytes >= bestCandidateAvailBytes) {
                bestCandidate = vol;
                bestCandidateAvailBytes = availBytes;
            }
        }
    }
    // System apps always forced to internal storage
    if (existingInfo != null && existingInfo.isSystemApp()) {
        installLocation = PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY;
    }
    // If app expresses strong desire for internal storage, honor it
    if (!forceAllowOnExternal && installLocation == PackageInfo.INSTALL_LOCATION_INTERNAL_ONLY) {
        if (existingInfo != null && !Objects.equals(existingInfo.volumeUuid, StorageManager.UUID_PRIVATE_INTERNAL)) {
            throw new IOException("Cannot automatically move " + packageName + " from " + existingInfo.volumeUuid + " to internal storage");
        }
        if (fitsOnInternal) {
            return StorageManager.UUID_PRIVATE_INTERNAL;
        } else {
            throw new IOException("Requested internal only, but not enough space");
        }
    }
    // If app already exists somewhere, we must stay on that volume
    if (existingInfo != null) {
        if (Objects.equals(existingInfo.volumeUuid, StorageManager.UUID_PRIVATE_INTERNAL) && fitsOnInternal) {
            return StorageManager.UUID_PRIVATE_INTERNAL;
        } else if (allCandidates.contains(existingInfo.volumeUuid)) {
            return existingInfo.volumeUuid;
        } else {
            throw new IOException("Not enough space on existing volume " + existingInfo.volumeUuid + " for " + packageName + " upgrade");
        }
    }
    // volume with most space
    if (bestCandidate != null) {
        return bestCandidate.fsUuid;
    } else if (fitsOnInternal) {
        return StorageManager.UUID_PRIVATE_INTERNAL;
    } else {
        throw new IOException("No special requests, but no room anywhere");
    }
}
Also used : ArraySet(android.util.ArraySet) NameNotFoundException(android.content.pm.PackageManager.NameNotFoundException) ApplicationInfo(android.content.pm.ApplicationInfo) StorageManager(android.os.storage.StorageManager) VolumeInfo(android.os.storage.VolumeInfo) IOException(java.io.IOException) ZipFile(java.util.zip.ZipFile) File(java.io.File)

Example 15 with VolumeInfo

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

the class FileCollector method getSystemSize.

/**
     * Returns the size of a system for a given context. This is done by finding the difference
     * between the shared data and the total primary storage size.
     * @param context Context to use to get storage information.
     */
public static long getSystemSize(Context context) {
    PackageManager pm = context.getPackageManager();
    VolumeInfo primaryVolume = pm.getPrimaryStorageCurrentVolume();
    StorageManager sm = context.getSystemService(StorageManager.class);
    VolumeInfo shared = sm.findEmulatedForPrivate(primaryVolume);
    if (shared == null) {
        return 0;
    }
    final long sharedDataSize = shared.getPath().getTotalSpace();
    long systemSize = sm.getPrimaryStorageSize() - sharedDataSize;
    // This case is not exceptional -- we just fallback to the shared data volume in this case.
    if (systemSize <= 0) {
        return 0;
    }
    return systemSize;
}
Also used : PackageManager(android.content.pm.PackageManager) StorageManager(android.os.storage.StorageManager) 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