目录 \frameworks\base\services\core\java\com\android\server\storage
DeviceStorageMonitorService
@Override
public void onStart() {
final Context context = getContext();
mNotifManager = context.getSystemService(NotificationManager.class);
mCacheFileDeletedObserver = new CacheFileDeletedObserver();
mCacheFileDeletedObserver.startWatching();
// Ensure that the notification channel is set up
//确保已设置通知通道
PackageManager packageManager = context.getPackageManager();
boolean isTv = packageManager.hasSystemFeature(PackageManager.FEATURE_LEANBACK);
if (isTv) {
mNotifManager.createNotificationChannel(new NotificationChannel(
TV_NOTIFICATION_CHANNEL_ID,
context.getString(
com.android.internal.R.string.device_storage_monitor_notification_channel),
NotificationManager.IMPORTANCE_HIGH));
}
//发布 binderservice
publishBinderService(SERVICE, mRemoteService);
//发布localservice
publishLocalService(DeviceStorageMonitorInternal.class, mLocalService);
// Kick off pass to examine storage state
mHandler.removeMessages(MSG_CHECK);
mHandler.obtainMessage(MSG_CHECK).sendToTarget();
}
private final DeviceStorageMonitorInternal mLocalService = new DeviceStorageMonitorInternal() {
@Override
public void checkMemory() {
// Kick off pass to examine storage state
mHandler.removeMessages(MSG_CHECK);
mHandler.obtainMessage(MSG_CHECK).sendToTarget();
}
@Override
public boolean isMemoryLow() {
return Environment.getDataDirectory().getUsableSpace() < getMemoryLowThreshold();
}
@Override
public long getMemoryLowThreshold() {
return getContext().getSystemService(StorageManager.class)
.getStorageLowBytes(Environment.getDataDirectory());
}
};
private final Binder mRemoteService = new Binder() {
@Override
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
if (!DumpUtils.checkDumpPermission(getContext(), TAG, pw)) return;
dumpImpl(fd, pw, args);
}
@Override
public void onShellCommand(FileDescriptor in, FileDescriptor out,
FileDescriptor err, String[] args, ShellCallback callback,
ResultReceiver resultReceiver) {
(new Shell()).exec(this, in, out, err, args, callback, resultReceiver);
}
};
我理解的这里发布的localservice是为其他模块提供一个可以主动检测存储使用状态的方式
//主动去checkMemory
DeviceStorageMonitorInternal dsm = LocalServices
.getService(DeviceStorageMonitorInternal.class);
if (dsm != null) {
dsm.checkMemory();
}
发送检查存储状态的message
// Kick off pass to examine storage state
mHandler.removeMessages(MSG_CHECK);
mHandler.obtainMessage(MSG_CHECK).sendToTarget();
接受消息之后去check
/**
* Handler that checks the amount of disk space on the device and sends a
* notification if the device runs low on disk space
*/
private final Handler mHandler = new Handler(IoThread.get().getLooper()) {
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case MSG_CHECK:
check();
return;
}
}
};
循环检测,当存储空间不足或者空间满或者空间又恢复ok会发送通知栏消息和广播
/**
* 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
;
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);
}
}
ACTION_DEVICE_STORAGE_LOW
空间由正常变为不足时发出的广播,每次开机的时候不足也会发出
ACTION_DEVICE_STORAGE_OK
空间由不足变为正常时发出的广播
根据需要去监听这两个广播就可以监听到系统本身存储不足。