Android O Low Storage机制(DeviceStorageMonitorService)

1.low storage简介(DeviceStorageMonitorService)

Device storage monitor module is composed of device monitor service (Google default)The purposes of device storage monitor service are monitoring device storage status and handling low storage conditions.。

在O之前mtk会定制些low storage的处理,后续已经取消

设备存储监视器服务是一个模块用来
    1.监视设备存储(“/ data”)。
    2.每60秒扫描一次免费存储空间(谷歌默认值)
    3.当设备的存储空间不足时生成“低存储”通知。 //updateNotifications
    4.引导用户管理设备中安装的所有应用程序,并发送意图。 //updateBroadcasts
    5.存储严重不足时显示警告对话框。
    6.为AMS/PMS提供公共API以查询存储状态

2.代码流程

//60s检测一次
public DeviceStorageMonitorService(Context context) {
    super(context);

    mHandlerThread = new HandlerThread(TAG, android.os.Process.THREAD_PRIORITY_BACKGROUND);
    mHandlerThread.start();

    mHandler = new Handler(mHandlerThread.getLooper()) {
        @Override
        public void handleMessage(Message msg) {
            switch (msg.what) {
                case MSG_CHECK:
                    check();
                    return;
            }
        }
    };
}
/frameworks/base/services/core/java/com/android/server/storage/DeviceStorageMonitorService.java
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);
    ...
        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); //update notification
        updateBroadcasts(vol, oldLevel, newLevel, seq); //notify braodcast

        state.level = newLevel;
    }
}
 
//小于500M时为低存储
/frameworks/base/core/java/android/os/storage/StorageManager.java
public long getStorageLowBytes(File path) {
    final long lowPercent = Settings.Global.getInt(mResolver,
            Settings.Global.SYS_STORAGE_THRESHOLD_PERCENTAGE, DEFAULT_THRESHOLD_PERCENTAGE);
    final long lowBytes = (path.getTotalSpace() * lowPercent) / 100;

    final long maxLowBytes = Settings.Global.getLong(mResolver,
            Settings.Global.SYS_STORAGE_THRESHOLD_MAX_BYTES, DEFAULT_THRESHOLD_MAX_BYTES);

    return Math.min(lowBytes, maxLowBytes);
}
private static final int LEVEL_UNKNOWN = -1;
private static final int LEVEL_NORMAL = 0;
private static final int LEVEL_LOW = 1;
private static final int LEVEL_FULL = 2;

//代表进入low storage,就会发送广播和通知,退出低内存后,发出取消广播和通知
private static boolean isEntering(int level, int oldLevel, int newLevel) {
    return newLevel >= level && (oldLevel < level || oldLevel == LEVEL_UNKNOWN);
}

private void updateNotifications(VolumeInfo vol, int oldLevel, int newLevel) {
    final Context context = getContext();
    final UUID uuid = StorageManager.convert(vol.getFsUuid());

    if (State.isEntering(State.LEVEL_LOW, oldLevel, newLevel)) {
...
        final CharSequence title = context.getText(
                com.android.internal.R.string.low_internal_storage_view_title); //"存储空间不足"

        PendingIntent intent = PendingIntent.getActivityAsUser(context, 0, lowMemIntent, 0,
                null, UserHandle.CURRENT);
        Notification notification =
                new Notification.Builder(context, SystemNotificationChannels.ALERTS)
                        .setSmallIcon(com.android.internal.R.drawable.stat_notify_disk_full)
                        .setTicker(title)
                        .setColor(context.getColor(
                            com.android.internal.R.color.system_notification_accent_color))
                        .setContentTitle(title)
...
                        .build();
        notification.flags |= Notification.FLAG_NO_CLEAR;
        mNotifManager.notifyAsUser(uuid.toString(), SystemMessage.NOTE_LOW_STORAGE,
                notification, UserHandle.ALL);
    } else if (State.isLeaving(State.LEVEL_LOW, oldLevel, newLevel)) {
        mNotifManager.cancelAsUser(uuid.toString(), SystemMessage.NOTE_LOW_STORAGE,
                UserHandle.ALL);
    }
}

猜你喜欢

转载自blog.csdn.net/wd229047557/article/details/82856374