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层。