Android9.0版本Vold服务源码分析之上层处理SD卡挂载

本文接上一篇SD卡挂载之后,上层处理,主要是创建通知,提示用户.涉及

xref: /frameworks/base/services/core/java/com/android/server/StorageManagerService.java

xref: /frameworks/base/core/java/android/os/storage/StorageManager.java

xref: /frameworks/base/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java

先看下流程图:

Android9.0版本Vold服务源码分析之上层处理SD卡挂载_第1张图片当SD卡挂载成功,vold服务会通过binder通信通知StorageManagerService当前卷轴状态改变,从check->mount.即走到onVolumeStateChanged.

xref: /frameworks/base/services/core/java/com/android/server/StorageManagerService.java
private final IVoldListener mListener = new IVoldListener.Stub() {
            ......
        @Override
        public void onVolumeStateChanged(String volId, int state) {
            synchronized (mLock) {
                final VolumeInfo vol = mVolumes.get(volId);
                if (vol != null) {
                    final int oldState = vol.state;
                    final int newState = state;
                    vol.state = newState;
                    onVolumeStateChangedLocked(vol, oldState, newState);
                }
            }
        }

IStorageEventListener注册在RemoteCallbackList中,从而mCallbacks调用notifyVolumeStateChanged就是调用                
IStorageEventListener里面的notifyVolumeStateChanged.这里其实是对binder机制的一种封装.跨进程通信还是靠的binder.
RemoteCallbackList.java的定义
负责维护远程接口列表,特别是用于执行service 跟 clients之间回调的。
具体的讲
1. 保持跟踪 注册的IInterface 回调,通过这些回调的 unique IBindler(通过调用IInterface.asBindler())。
2. 将每一个注册的借口通过IBindler.DeathRecipient绑定,这样若进程被清楚就可以清除list。
3. 锁定 interfaces列表处理多线程的调用,然后不需要持有lock的方式,用线程安全的方式遍历列表

用这个类,可以简单的创建一个实例,通过其register(E)和unregister(E)函数注册或注销clients。
通过beginBroadcast(), getBroadcastItem(int), finishBroadcast().回调给client。
如果一个注册了callback的进程消失了,这个类会自动将其从list中清除。
可以通过onCallbackDied(E)对这个注册的callback进行额外处理。

@GuardedBy("mLock")
    private void onVolumeStateChangedLocked(VolumeInfo vol, int oldState, int newState) {
        ......
        //省略部分代码
        //这个mCallbacks是Callbacks对象,是StorageManagerService的内部类,所以这里调用的是Callbacks里面的notifyVolumeStateChanged.
        mCallbacks.notifyVolumeStateChanged(vol, oldState, newState);

        ......
    }

再看下Callbacks这个类.new了一个RemoteCallbackList,并注册了IStorageEventListener这个binder,也就是mCallbacks关联了IStorageEventListener,相当于拿到了这个对象.可以调用里面的方法onVolumeStateChanged

private static class Callbacks extends Handler {
......

        private final RemoteCallbackList
                mCallbacks = new RemoteCallbackList<>();

        public Callbacks(Looper looper) {
            super(looper);
        }

        public void register(IStorageEventListener callback) {
            mCallbacks.register(callback);
        }

        public void unregister(IStorageEventListener callback) {
            mCallbacks.unregister(callback);
        }

        @Override
        public void handleMessage(Message msg) {
            final SomeArgs args = (SomeArgs) msg.obj;
            final int n = mCallbacks.beginBroadcast();
            for (int i = 0; i < n; i++) {
                //这里拿到的callback就是IStorageEventListener对象了.可以调用里面的方法.
                final IStorageEventListener callback = mCallbacks.getBroadcastItem(i);
                try {
                    invokeCallback(callback, msg.what, args);
                } catch (RemoteException ignored) {
                }
            }
            mCallbacks.finishBroadcast();
            args.recycle();
        }

        private void invokeCallback(IStorageEventListener callback, int what, SomeArgs args)
                throws RemoteException {
            switch (what) {
                case MSG_STORAGE_STATE_CHANGED: {
                    callback.onStorageStateChanged((String) args.arg1, (String) args.arg2,
                            (String) args.arg3);
                    break;
                }
                case MSG_VOLUME_STATE_CHANGED: {
                    //调用IStorageEventListener的方法.这里通过binder机制跨进程调到了StorageManager.
                    callback.onVolumeStateChanged((VolumeInfo) args.arg1, args.argi2, args.argi3);
                    break;
                }
                case MSG_VOLUME_RECORD_CHANGED: {
                    callback.onVolumeRecordChanged((VolumeRecord) args.arg1);
                    break;
                }
                case MSG_VOLUME_FORGOTTEN: {
                    callback.onVolumeForgotten((String) args.arg1);
                    break;
                }
                case MSG_DISK_SCANNED: {
                    callback.onDiskScanned((DiskInfo) args.arg1, args.argi2);
                    break;
                }
                case MSG_DISK_DESTROYED: {
                    callback.onDiskDestroyed((DiskInfo) args.arg1);
                    break;
                }
            }
        }

        private void notifyStorageStateChanged(String path, String oldState, String newState) {
            final SomeArgs args = SomeArgs.obtain();
            args.arg1 = path;
            args.arg2 = oldState;
            args.arg3 = newState;
            obtainMessage(MSG_STORAGE_STATE_CHANGED, args).sendToTarget();
        }

        private void notifyVolumeStateChanged(VolumeInfo vol, int oldState, int newState) {
            final SomeArgs args = SomeArgs.obtain();
            args.arg1 = vol.clone();
            args.argi2 = oldState;
            args.argi3 = newState;
            obtainMessage(MSG_VOLUME_STATE_CHANGED, args).sendToTarget();
        }

           ......
    }

StorageManagerService通过binder机制,调用IStorageEventListener的onVolumeStateChanged.而IStorageEventListener的
真正实现在StorageManager中,可以看到StorageEventListenerDelegate实现了IStorageEventListener.Stub

xref: /frameworks/base/core/java/android/os/storage/StorageManager.java
private static class StorageEventListenerDelegate extends IStorageEventListener.Stub implements
            Handler.Callback {
        ......

        public StorageEventListenerDelegate(StorageEventListener callback, Looper looper) {
               //传进来的callback就是StorageEventListener,而StorageNotification通过getService拿到StorageManager对象,在通过
               //registerListener(mListener);这样mCallback.onVolumeStateChanged就调到了StorageEventListener的onVolumeStateChanged.
            mCallback = callback;
            mHandler = new Handler(looper, this);
        }

        @Override
        public boolean handleMessage(Message msg) {
            final SomeArgs args = (SomeArgs) msg.obj;
            switch (msg.what) {
                case MSG_STORAGE_STATE_CHANGED:
                    mCallback.onStorageStateChanged((String) args.arg1, (String) args.arg2,
                            (String) args.arg3);
                    args.recycle();
                    return true;
                case MSG_VOLUME_STATE_CHANGED:
                    mCallback.onVolumeStateChanged((VolumeInfo) args.arg1, args.argi2, args.argi3);
                    args.recycle();
                    return true;
               ......
            args.recycle();
            return false;
        }
         //StorageManagerService调用的是此处的onVolumeStateChanged,通过发送消息MSG_VOLUME_STATE_CHANGED,在handleMessage调用  
         //StorageNotification的onVolumeStateChanged.
        @Override
        public void onVolumeStateChanged(VolumeInfo vol, int oldState, int newState) {
            final SomeArgs args = SomeArgs.obtain();
            args.arg1 = vol;
            args.argi2 = oldState;
            args.argi3 = newState;
            mHandler.obtainMessage(MSG_VOLUME_STATE_CHANGED, args).sendToTarget();
        }
}
xref: /frameworks/base/packages/SystemUI/src/com/android/systemui/usb/StorageNotification.java
    @Override
    public void start() {
        mNotificationManager = mContext.getSystemService(NotificationManager.class);

        mStorageManager = mContext.getSystemService(StorageManager.class);
           //把StorageEventListener的实现,注册到StorageManager.
        mStorageManager.registerListener(mListener);

        ......
    }

    private final StorageEventListener mListener = new StorageEventListener() {
        @Override
        public void onVolumeStateChanged(VolumeInfo vol, int oldState, int newState) {
            onVolumeStateChangedInternal(vol);
        }

    private void onVolumeStateChangedInternal(VolumeInfo vol) {
        switch (vol.getType()) {
            case VolumeInfo.TYPE_PRIVATE:
                onPrivateVolumeStateChangedInternal(vol);
                break;
            case VolumeInfo.TYPE_PUBLIC:
                onPublicVolumeStateChangedInternal(vol);
                break;
        }
    }
       //当StorageManager那边接收到StorageManagerService的消息,会回调此处.从而根据不同的类型创建不同的通知.
    private void onPublicVolumeStateChangedInternal(VolumeInfo vol) {
        Log.d(TAG, "Notifying about public volume: " + vol.toString());

        final Notification notif;
        switch (vol.getState()) {
            ......
            case VolumeInfo.STATE_MOUNTED:
            case VolumeInfo.STATE_MOUNTED_READ_ONLY:
                notif = onVolumeMounted(vol);
                break;
            ......
            default:
                notif = null;
                break;
        }

        if (notif != null) {
            mNotificationManager.notifyAsUser(vol.getId(), SystemMessage.NOTE_STORAGE_PUBLIC,
                    notif, UserHandle.of(vol.getMountUserId()));
        } else {
            mNotificationManager.cancelAsUser(vol.getId(), SystemMessage.NOTE_STORAGE_PUBLIC,
                    UserHandle.of(vol.getMountUserId()));
        }
    }

       //这里只列出挂载的实现.至此,通知就创建完毕了.在通知栏就可以显示相关通知了.
    private Notification onVolumeMounted(VolumeInfo vol) {
        final VolumeRecord rec = mStorageManager.findRecordByUuid(vol.getFsUuid());
        final DiskInfo disk = vol.getDisk();

        // Don't annoy when user dismissed in past.  (But make sure the disk is adoptable; we
        // used to allow snoozing non-adoptable disks too.)
        if (rec.isSnoozed() && disk.isAdoptable()) {
            return null;
        }

        if (disk.isAdoptable() && !rec.isInited()) {
            final CharSequence title = disk.getDescription();
            final CharSequence text = mContext.getString(
                    R.string.ext_media_new_notification_message, disk.getDescription());

            final PendingIntent initIntent = buildInitPendingIntent(vol);
            return buildNotificationBuilder(vol, title, text)
                    .addAction(new Action(R.drawable.ic_settings_24dp,
                            mContext.getString(R.string.ext_media_init_action), initIntent))
                    .addAction(new Action(R.drawable.ic_eject_24dp,
                            mContext.getString(R.string.ext_media_unmount_action),
                            buildUnmountPendingIntent(vol)))
                    .setContentIntent(initIntent)
                    .setDeleteIntent(buildSnoozeIntent(vol.getFsUuid()))
                    .build();

        } else {
            final CharSequence title = disk.getDescription();
            final CharSequence text = mContext.getString(
                    R.string.ext_media_ready_notification_message, disk.getDescription());

            final PendingIntent browseIntent = buildBrowsePendingIntent(vol);
            final Notification.Builder builder = buildNotificationBuilder(vol, title, text)
                    .addAction(new Action(R.drawable.ic_folder_24dp,
                            mContext.getString(R.string.ext_media_browse_action),
                            browseIntent))
                    .addAction(new Action(R.drawable.ic_eject_24dp,
                            mContext.getString(R.string.ext_media_unmount_action),
                            buildUnmountPendingIntent(vol)))
                    .setContentIntent(browseIntent)
                    .setCategory(Notification.CATEGORY_SYSTEM);
            // Non-adoptable disks can't be snoozed.
            if (disk.isAdoptable()) {
                builder.setDeleteIntent(buildSnoozeIntent(vol.getFsUuid()));
            }

            return builder.build();
        }
    }

以上就是vold服务挂载完毕后通知上层的处理流程.从StorageManagerService到StorageManager在到StorageNotification,利用IStorageEventListener.aidl和StorageEventListener.java,谷歌巧妙的实现了跨进程通信,还是值得看下的.

 

参考:
https://blog.csdn.net/wangxueming/article/details/51189751

你可能感兴趣的:(Vold相关)