Android系统存储可用空间不足监控DeviceStorageMonitorService

前言

对于低存储空间的设备,比如穿戴设备等,存储空间可能只有32G。在这样的设备上安装第三方应用会占用较大的存储空间,因此需要对可用的存储空间进行监控。

一、DeviceStorageMonitorService

系统中存在原生的存储空间的监控机制,当可用空间很少时,会发出notification提示用户。
该监控是存在于DeviceStorageMonitorService.java中。

/frameworks/base/services/java/com/android/server/SystemServer.java

t.traceBegin("StartDeviceMonitor");
mSystemServiceManager.startService(DeviceStorageMonitorService.class);
t.traceEnd();

/frameworks/base/services/core/java/com/android/server/storage/DeviceStorageMonitorService.java

    @Override    
    public void onStart() {        
        final Context context = getContext();
        mNotifManager = context.getSystemService(NotificationManager.class);

        mCacheFileDeletedObserver = new CacheFileDeletedObserver();
        mCacheFileDeletedObserver.startWatching();
        ...
        publishBinderService(SERVICE, mRemoteService);
        publishLocalService(DeviceStorageMonitorInternal.class, mLocalService);

        // Kick off pass to examine storage statemHandler.removeMessages(MSG_CHECK);
        // 服务开始后便开始进行check
        mHandler.obtainMessage(MSG_CHECK).sendToTarget();
    }

在check()方法中检查存储空间,之后发送1分钟的delay message,然后是下次的重复检查。当出现低存储时会发送notification以及broadcast。

     @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;
            }
            //发送notification以及broadcast
            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);
        }
    }

当前系统分了几个等级
LEVEL_UNKNOWN:
LEVEL_NORMAL:正常
LEVEL_LOW:低存储空间,空间不足5%或者不足500M时(选其中较低的值)
LEVEL_FULL:存储空间已满,空间不足1M时

updateNotifications(vol, oldLevel, newLevel);会在空间不足或者解除了空间不足时发送相关的notification。
updateBroadcasts(vol, oldLevel, newLevel, seq);会发送一些广播来通知其他应用空间不足或者解除空间不足的情况。

LEVEL_LOW时发送广播

@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
@Deprecated
public static final String ACTION_DEVICE_STORAGE_LOW = "android.intent.action.DEVICE_STORAGE_LOW";

退出LEVEL_LOW时发送广播

@SdkConstant(SdkConstantType.BROADCAST_INTENT_ACTION)
@Deprecated
public static final String ACTION_DEVICE_STORAGE_OK = "android.intent.action.DEVICE_STORAGE_OK";
  • 8
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值