本文接上一篇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
先看下流程图:
当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