vold模块收到内核消息后,通过前面建立的socket通信各上去发送相应的消息,我们可以看到主要发了两类消息:
1、DirectVolume::handleDiskAdded以及handlePartitionAdded都调用setState发送了一条VolumeStateChange消息。
2、handleDiskAdded中还发送了 VolumeDiskInserted消息。
我们先看下FrameWork层的消息处理流程:
这里的消息处理还算比较简单,主要只要处理VolumeDiskInserted消息,另外两条消息收到后都被忽略了,
我们看下VolumeDiskInserted的处理,首先阻塞在listenToSocket等待vold消息的到来:
while (true) {
int count = inputStream.read(buffer, start, BUFFER_SIZE - start);
if (count < 0) break;
。
。
。
try {
if (!mCallbacks.onEvent(code, event, tokens)) {
Slog.w(TAG, String.format(
"Unhandled event (%s)", event));
}
} 。。。
收到消息后,调用onEvent函数
onEvent的函数实现在MountService中
public boolean onEvent(int code, String raw, String[] cooked) {
Intent in = null;
.
.
.
if (code == VoldResponseCode.VolumeDiskInserted) {
new Thread() {
public void run() {
try {
int rc;
if ((rc = doMountVolume(path)) != StorageResultCode.OperationSucceeded) {
Slog.w(TAG, String.format("Insertion mount failed (%d)", rc));
}
} catch (Exception ex) {
Slog.w(TAG, "Failed to mount media on insertion", ex);
}
}
}.start();
这里的消息为VolumeDiskInserted,new 一个Thread并start,在run函数中调用doMountVolume函数向vold层发送挂载命令:
private int doMountVolume(String path) {
int rc = StorageResultCode.OperationSucceeded;
if (DEBUG_EVENTS) Slog.i(TAG, "doMountVolume: Mouting " + path);
try {
mConnector.doCommand(String.format("volume mount %s", path));
}
.
.
.
}
这里调用doCommand并以volume mount path为参数,我们看下doCommand:
public synchronized ArrayList<String> doCommand(String cmd)
throws NativeDaemonConnectorException {
sendCommand(cmd);
.
.
.
}
继续看sendCommand:
private void sendCommand(String command, String argument)
throws NativeDaemonConnectorException {
.
。
.
try {
mOutputStream.write(builder.toString().getBytes());
} catch (IOException ex) {
Slog.e(TAG, "IOException in sendCommand", ex);
}
}
调用write函数把消息发送到vold层,这样FrameWork层就把挂载命令下发到了vold层。