下面列出了android.os.storage.StorageManager#getStorageLowBytes ( ) 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
@Override
public void allocateBytes(String volumeUuid, long bytes, int flags, String callingPackage) {
flags = adjustAllocateFlags(flags, Binder.getCallingUid(), callingPackage);
final long allocatableBytes = getAllocatableBytes(volumeUuid, flags, callingPackage);
if (bytes > allocatableBytes) {
throw new ParcelableException(new IOException("Failed to allocate " + bytes
+ " because only " + allocatableBytes + " allocatable"));
}
final StorageManager storage = mContext.getSystemService(StorageManager.class);
final long token = Binder.clearCallingIdentity();
try {
// Free up enough disk space to satisfy both the requested allocation
// and our low disk warning space.
final File path = storage.findPathForUuid(volumeUuid);
if ((flags & StorageManager.FLAG_ALLOCATE_AGGRESSIVE) != 0) {
bytes += storage.getStorageFullBytes(path);
} else {
bytes += storage.getStorageLowBytes(path);
}
mPms.freeStorage(volumeUuid, bytes, flags);
} catch (IOException e) {
throw new ParcelableException(e);
} finally {
Binder.restoreCallingIdentity(token);
}
}
@Override
public long getAllocatableBytes(String volumeUuid, int flags, String callingPackage) {
flags = adjustAllocateFlags(flags, Binder.getCallingUid(), callingPackage);
final StorageManager storage = mContext.getSystemService(StorageManager.class);
final StorageStatsManager stats = mContext.getSystemService(StorageStatsManager.class);
final long token = Binder.clearCallingIdentity();
try {
// In general, apps can allocate as much space as they want, except
// we never let them eat into either the minimum cache space or into
// the low disk warning space. To avoid user confusion, this logic
// should be kept in sync with getFreeBytes().
final File path = storage.findPathForUuid(volumeUuid);
final long usable = path.getUsableSpace();
final long lowReserved = storage.getStorageLowBytes(path);
final long fullReserved = storage.getStorageFullBytes(path);
if (stats.isQuotaSupported(volumeUuid)) {
final long cacheTotal = stats.getCacheBytes(volumeUuid);
final long cacheReserved = storage.getStorageCacheBytes(path, flags);
final long cacheClearable = Math.max(0, cacheTotal - cacheReserved);
if ((flags & StorageManager.FLAG_ALLOCATE_AGGRESSIVE) != 0) {
return Math.max(0, (usable + cacheClearable) - fullReserved);
} else {
return Math.max(0, (usable + cacheClearable) - lowReserved);
}
} else {
// When we don't have fast quota information, we ignore cached
// data and only consider unused bytes.
if ((flags & StorageManager.FLAG_ALLOCATE_AGGRESSIVE) != 0) {
return Math.max(0, usable - fullReserved);
} else {
return Math.max(0, usable - lowReserved);
}
}
} catch (IOException e) {
throw new ParcelableException(e);
} finally {
Binder.restoreCallingIdentity(token);
}
}
/**
* Core logic that checks the storage state of every mounted private volume.
* Since this can do heavy I/O, callers should invoke indirectly using
* {@link #MSG_CHECK}.
*/
@WorkerThread
private void check() {
final StorageManager storage = getContext().getSystemService(StorageManager.class);
final int seq = mSeq.get();
// Check every mounted private volume to see if they're low on space
for (VolumeInfo vol : storage.getWritablePrivateVolumes()) {
final File file = vol.getPath();
final long fullBytes = storage.getStorageFullBytes(file);
final long lowBytes = storage.getStorageLowBytes(file);
// Automatically trim cached data when nearing the low threshold;
// when it's within 150% of the threshold, we try trimming usage
// back to 200% of the threshold.
if (file.getUsableSpace() < (lowBytes * 3) / 2) {
final PackageManagerService pms = (PackageManagerService) ServiceManager
.getService("package");
try {
pms.freeStorage(vol.getFsUuid(), lowBytes * 2, 0);
} catch (IOException e) {
Slog.w(TAG, e);
}
}
// Send relevant broadcasts and show notifications based on any
// recently noticed state transitions.
final UUID uuid = StorageManager.convert(vol.getFsUuid());
final State state = findOrCreateState(uuid);
final long totalBytes = file.getTotalSpace();
final long usableBytes = file.getUsableSpace();
int oldLevel = state.level;
int newLevel;
if (mForceLevel != State.LEVEL_UNKNOWN) {
// When in testing mode, use unknown old level to force sending
// of any relevant broadcasts.
oldLevel = State.LEVEL_UNKNOWN;
newLevel = mForceLevel;
} else if (usableBytes <= fullBytes) {
newLevel = State.LEVEL_FULL;
} else if (usableBytes <= lowBytes) {
newLevel = State.LEVEL_LOW;
} else if (StorageManager.UUID_DEFAULT.equals(uuid) && !isBootImageOnDisk()
&& usableBytes < BOOT_IMAGE_STORAGE_REQUIREMENT) {
newLevel = State.LEVEL_LOW;
} else {
newLevel = State.LEVEL_NORMAL;
}
// Log whenever we notice drastic storage changes
if ((Math.abs(state.lastUsableBytes - usableBytes) > DEFAULT_LOG_DELTA_BYTES)
|| oldLevel != newLevel) {
EventLogTags.writeStorageState(uuid.toString(), oldLevel, newLevel,
usableBytes, totalBytes);
state.lastUsableBytes = usableBytes;
}
updateNotifications(vol, oldLevel, newLevel);
updateBroadcasts(vol, oldLevel, newLevel, seq);
state.level = newLevel;
}
// Loop around to check again in future; we don't remove messages since
// there might be an immediate request pending.
if (!mHandler.hasMessages(MSG_CHECK)) {
mHandler.sendMessageDelayed(mHandler.obtainMessage(MSG_CHECK),
DEFAULT_CHECK_INTERVAL);
}
}