上篇我们介绍了Android的存储系统中native层的Vold的启动流程,Vold在init进程中通过init脚本进行启动,而MountService则是在Java的服务总站SystemServer中配置启动的,下面我们就来看一下Java层的MountService是如何启动的。
MountService启动流程
Java层的MountService服务是在SystemServer中配置的,我们来分析一下其启动流程。
SystemServer启动配置
private static final String MOUNT_SERVICE_CLASS = "com.android.server.MountService$Lifecycle";
private void startOtherServices() {
...
if (mFactoryTestMode != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
if (!disableStorage &&
!"0".equals(SystemProperties.get("system_init.startmountservice"))) {
try {
/*
* NotificationManagerService is dependant on MountService,
* (for media / usb notifications) so we must start MountService first.
*/
//启动MountService服务
mSystemServiceManager.startService(MOUNT_SERVICE_CLASS);
//等价new IMountService.Stub.Proxy(),即获取MountService的proxy对象
mountService = IMountService.Stub.asInterface(
ServiceManager.getService("mount"));
} catch (Throwable e) {
reportWtf("starting Mount Service", e);
}
}
}
...
}
这里可以看出,启动MountService并非直接启动,而是通过其静态内部类Lifecycle实现启动,下面我们看一下其内部静态类的实现。
静态内部类Lifecycle
// Lifecycle继承SystemService,受制于父类的生命周期方法回调,其为MountService的内部静态类,控制MountService的实例化操作
public static class Lifecycle extends SystemService {
private MountService mMountService;
public Lifecycle(Context context) {
super(context);
}
@Override
public void onStart() {
//创建MountService对象【见小节2.3】
mMountService = new MountService(getContext());
//登记Binder服务
publishBinderService("mount", mMountService);
}
// 由SystenServer启动到指定阶段进行回调,其内部由mServices持有
@Override
public void onBootPhase(int phase) {
// 由于MountService的内部Lifecycle已添加SystemServiceManager的mServices服务列表;
// 系统启动到PHASE_ACTIVITY_MANAGER_READY时会回调mServices中的onBootPhase方法
if (phase == SystemService.PHASE_ACTIVITY_MANAGER_READY) {
mMountService.systemReady();
}
}
...
}
静态内部类Lifecycle中实现MountService的初始化操作,然后通过publishBinderService将新建的MountService添加到服务列表中。
MountService初始化
MountService在其静态内部类LifeCycle中进行初始化,具体如下:
public MountService(Context context) {
sSelf = this;
mContext = context;
//FgThread线程名为“"android.fg",创建IMountServiceListener回调方法(1线程)
mCallbacks = new Callbacks(FgThread.get().getLooper());
// XXX: This will go away soon in favor of IMountServiceObserver
//获取PKMS的Client端对象
mPms = (PackageManagerService) ServiceManager.getService("package");
//创建“MountService”线程(2线程)
HandlerThread hthread = new HandlerThread(TAG);
hthread.start();
mHandler = new MountServiceHandler(hthread.getLooper());
// Add OBB Action Handler to MountService thread.
//IoThread线程名为"android.io",创建OBB操作的handler(3线程)
mObbActionHandler = new ObbActionHandler(IoThread.get().getLooper());
// Initialize the last-fstrim tracking if necessary
File dataDir = Environment.getDataDirectory();
File systemDir = new File(dataDir, "system");
mLastMaintenanceFile = new File(systemDir, LAST_FSTRIM_FILE);
//判断/data/system/last-fstrim文件,不存在则创建,存在则更新最后修改时间
if (!mLastMaintenanceFile.exists()) {
// Not setting mLastMaintenance here means that we will force an
// fstrim during reboot following the OTA that installs this code.
try {
(new FileOutputStream(mLastMaintenanceFile)).close();
} catch (IOException e) {
Slog.e(TAG, "Unable to create fstrim record " + mLastMaintenanceFile.getPath());
}
} else {
mLastMaintenance = mLastMaintenanceFile.lastModified();
}
mSettingsFile = new AtomicFile(
new File(Environment.getSystemSecureDirectory(), "storage.xml"));
synchronized (mLock) {
readSettingsLocked();
}
//将MountServiceInternalImpl登记到sLocalServiceObjects,区别Binder的RemoteService
LocalServices.addService(MountServiceInternal.class, mMountServiceInternal);
/*
* Create the connection to vold with a maximum queue of twice the
* amount of containers we'd ever expect to have. This keeps an
* "asec list" from blocking a thread repeatedly.
*/
//创建用于VoldConnector的NDC(native守护进程连接器)对象
mConnector = new NativeDaemonConnector(this, "vold", MAX_CONTAINERS * 2, VOLD_TAG, 25,
null);
mConnector.setDebug(true);
//创建线程名为"VoldConnector"的线程,用于跟vold通信,启动(4线程)
Thread thread = new Thread(mConnector, VOLD_TAG);
thread.start();
// Reuse parameters from first connector since they are tested and safe
//创建用于CryptdConnector工作的NDC对象,同上面的一样
mCryptConnector = new NativeDaemonConnector(this, "cryptd",
MAX_CONTAINERS * 2, CRYPTD_TAG, 25, null);
mCryptConnector.setDebug(true);
//创建线程名为"CryptdConnector"的线程,用于加密(5线程)
Thread crypt_thread = new Thread(mCryptConnector, CRYPTD_TAG);
crypt_thread.start();
//注册监听用户添加、删除的广播
final IntentFilter userFilter = new IntentFilter();
userFilter.addAction(Intent.ACTION_USER_ADDED);
userFilter.addAction(Intent.ACTION_USER_REMOVED);
mContext.registerReceiver(mUserReceiver, userFilter, null, mHandler);
//内部私有volume的路径为/data,该volume通过dumpsys mount是不会显示的
addInternalVolume();
// Add ourself to the Watchdog monitors if enabled.
if (WATCHDOG_ENABLE) {
Watchdog.getInstance().addMonitor(this);
}
}
代码内容比较多,我们梳理一下其主要工作:
- 创建线程 Callbacks,线程名android.fg
- 创建线程 HandlerThread,线程名MountService,并开启
- 创建线程 ObbActionHandler,线程名android.io
- 创建 NativeDaemonConnector对象,线程 thread并开启,线程名VoldConnector
- 创建 NativeDaemonConnector对象,线程 crypt_thread并开启,线程名CryptdConnector
- 注册广播和其他操作
这里设计线程数量比较多,新建了三个线程:MountService,VoldConnector,CryptdConnector;还有两个额外的系统进程中的线程android.fg和android.io
Callbacke
private static class Callbacks extends Handler {
private static final int MSG_STORAGE_STATE_CHANGED = 1;
private static final int MSG_VOLUME_STATE_CHANGED = 2;
private static final int MSG_VOLUME_RECORD_CHANGED = 3;
private static final int MSG_VOLUME_FORGOTTEN = 4;
private static final int MSG_DISK_SCANNED = 5;
private static final int MSG_DISK_DESTROYED = 6;
//通过 register() 方法添加 IMountServiceListener 对象信息到 mCallbacks 成员变量。
// RemoteCallbackList 的内部类 Callback 继承于 IBinder.DeathRecipient,这是死亡通知
//当 binder 服务端进程死亡后,回调 binderDied 方法通知 binder 客户端进行相应地处理
private final RemoteCallbackList<IMountServiceListener>
mCallbacks = new RemoteCallbackList<>();
public Callbacks(Looper looper) {
super(looper);
}
public void register(IMountServiceListener callback) {
mCallbacks.register(callback);
}
public void unregister(IMountServiceListener 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++) {
final IMountServiceListener callback = mCallbacks.getBroadcastItem(i);
try {
invokeCallback(callback, msg.what, args);
} catch (RemoteException ignored) {
}
}
mCallbacks.finishBroadcast();
args.recycle();
}
private void invokeCallback(IMountServiceListener 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;
}
...
}
}
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();
}
...
}
Callback继承自handler,其中Looper采用的是系统进程线程android.fg,其内部还有一个成员变量mCallbacks,通过register()方法添加IMountServiceListener对象信息到mCallbacks成员变量。RemoteCallbackList的内部类Callback继承于IBinder.DeathRecipient,很显然这是死亡通知,当binder服务端进程死亡后,回调binderDied方法通知binder客户端进行相应地处理。
MountServiceHandler
class MountServiceHandler extends Handler {
public MountServiceHandler(Looper looper) {
super(looper);
}
@Override
public void handleMessage(Message msg) {
switch (msg.what) {
case H_SYSTEM_READY: {
// 处理system_server主线程发送 H_SYSTEM_READY 消息
handleSystemReady();
break;
}
case H_DAEMON_CONNECTED: {
// Daemon-Socket 已经建立连接
handleDaemonConnected();
break;
}
...
case H_VOLUME_MOUNT: {
final VolumeInfo vol = (VolumeInfo) msg.obj;
if (isMountDisallowed(vol)) {
Slog.i(TAG, "Ignoring mount " + vol.getId() + " due to policy");
break;
}
try {
mConnector.execute("volume", "mount", vol.id, vol.mountFlags,
vol.mountUserId);
} catch (NativeDaemonConnectorException ignored) {
}
break;
}
...
}
}
}
Handler主线程,负责处理所有的UI事件。
NativeDaemonConnector初始化
NativeDaemonConnector(INativeDaemonConnectorCallbacks callbacks, String socket,
int responseQueueSize, String logTag, int maxLogSize, PowerManager.WakeLock wl) {
this(callbacks, socket, responseQueueSize, logTag, maxLogSize, wl,
FgThread.get().getLooper());
}
// mLooper 为 FgThread.get().getLooper(),即运行在 ”android.fg” 线程
NativeDaemonConnector(INativeDaemonConnectorCallbacks callbacks, String socket,
int responseQueueSize, String logTag, int maxLogSize, PowerManager.WakeLock wl,
Looper looper) {
mCallbacks = callbacks;
//socket名为"vold"
mSocket = socket;
// mResponseQueue 对象中成员变量 mPendingCmds 数据类型为 LinkedList
//记录着 vold 进程上报的响应事件,事件个数上限为500
mResponseQueue = new ResponseQueue(responseQueueSize);
mWakeLock = wl;
if (mWakeLock != null) {
mWakeLock.setReferenceCounted(true);
}
mLooper = looper;
mSequenceNumber = new AtomicInteger(0);
// TAG 为"VoldConnector"
TAG = logTag != null ? logTag : "NativeDaemonConnector";
mLocalLog = new LocalLog(maxLogSize);
}
NativeDaemonConnector使用的线程为android.fg,其主要负责和Native层Vold进程通过Socket进行痛惜,其中mResponseQueue对象中成员变量mPendingCmds数据类型为LinkedList,记录着vold进程上报的响应事件,事件个数上限为500。
在线程VoldConnector中建立了名为vold的socket的客户端,通过循环方式不断监听Vold服务端发送过来的消息。 另外,同理还有一个线程CryptdConnector也采用类似的方式,建立了cryptd的socket客户端,监听Vold中另个线程发送过来的消息。
NDC->run
接下来就是NDC的start进入run方法,如下;
@Override
public void run() {
mCallbackHandler = new Handler(mLooper, this);
while (true) {
try {
//监听vold的socket
listenToSocket();
} catch (Exception e) {
loge("Error in NativeDaemonConnector: " + e);
SystemClock.sleep(5000);
}
}
}
listenToSocket
// 监听 socket 内数据
private void listenToSocket() throws IOException {
LocalSocket socket = null;
try {
socket = new LocalSocket();
LocalSocketAddress address = determineSocketAddress();
// 建立与"/dev/socket/vold"的socket连接
socket.connect(address);
InputStream inputStream = socket.getInputStream();
synchronized (mDaemonLock) {
mOutputStream = socket.getOutputStream();
}
// 建立连接后,回调 MS.onDaemonConnected
mCallbacks.onDaemonConnected();
byte[] buffer = new byte[BUFFER_SIZE];
int start = 0;
while (true) {
int count = inputStream.read(buffer, start, BUFFER_SIZE - start);
if (count < 0) {
loge("got " + count + " reading with start = " + start);
break;
}
// Add our starting point to the count and reset the start.
count += start;
start = 0;
for (int i = 0; i < count; i++) {
if (buffer[i] == 0) {
// Note - do not log this raw message since it may contain
// sensitive data
final String rawEvent = new String(
buffer, start, i - start, StandardCharsets.UTF_8);
boolean releaseWl = false;
try {
//解析 socket 服务端发送的 event
final NativeDaemonEvent event = NativeDaemonEvent.parseRawEvent(
rawEvent);
log("RCV <- {" + event + "}");
//当事件的响应码区间为[600,700),则发送消息交由 mCallbackHandler 处理
if (event.isClassUnsolicited()) {
// TODO: migrate to sending NativeDaemonEvent instances
if (mCallbacks.onCheckHoldWakeLock(event.getCode())
&& mWakeLock != null) {
mWakeLock.acquire();
releaseWl = true;
}
if (mCallbackHandler.sendMessage(mCallbackHandler.obtainMessage(
event.getCode(), event.getRawEvent()))) {
releaseWl = false;
}
} else {
// 对于其他的响应码则添加到 mResponseQueue 队列
// 该方法便能触发 ResponseQueue.poll 阻塞操作继续往下执行
mResponseQueue.add(event.getCmdNumber(), event);
}
} catch (IllegalArgumentException e) {
log("Problem parsing message " + e);
} finally {
if (releaseWl) {
mWakeLock.acquire();
}
}
start = i + 1;
}
}
if (start == 0) {
log("RCV incomplete");
}
// We should end at the amount we read. If not, compact then
// buffer and read again.
if (start != count) {
final int remaining = BUFFER_SIZE - start;
System.arraycopy(buffer, start, buffer, 0, remaining);
start = remaining;
} else {
start = 0;
}
}
} catch (IOException ex) {
loge("Communications error: " + ex);
throw ex;
} finally {
//收尾清理类工作,关闭mOutputStream, socket
synchronized (mDaemonLock) {
if (mOutputStream != null) {
try {
loge("closing stream for " + mSocket);
mOutputStream.close();
} catch (IOException e) {
loge("Failed closing output stream: " + e);
}
mOutputStream = null;
}
}
try {
if (socket != null) {
socket.close();
}
} catch (IOException ex) {
loge("Failed closing socket: " + ex);
}
}
}
内容比较多,这里也是比较重要的部分,建立连接后,便会进行onDaemonConnected回调。之后进入死循环不断监听,调用NativeDaemonEvent.parseRawEvent解析Socket内的元数据,根据事件类型进行分类处理。当事件的响应码区间为[600,700),则发送消息交由 mCallbackHandler 处理,其他的则添加到 mResponseQueue 队列,触发 ResponseQueue.poll 阻塞操作继续往下执行。最终在finally释放锁和清理工作。
onDaemonConnected
// 主线程发送消息 H_DAEMON_CONNECTED 给线程 MountService
// 该线程收到消息后调用 MountServiceHandler 的 handleMessage()
@Override
public void onDaemonConnected() {
mDaemonConnected = true;
mHandler.obtainMessage(H_DAEMON_CONNECTED).sendToTarget();
}
其通过handler,最终调用到handleDaemonConnected,如下:
MountService.handleDaemonConnected
private void handleDaemonConnected() {
synchronized (mLock) {
// 重置清理工作
resetIfReadyAndConnectedLocked();
}
/*
* Now that we've done our initialization, release
* the hounds!
*/
// 类型为 CountDownLatch,用于多线程同步,阻塞await()直到计数器为零
mConnectedSignal.countDown();
if (mConnectedSignal.getCount() != 0) {
// More daemons need to connect
return;
}
// On an encrypted device we can't see system properties yet, so pull
// the system locale out of the mount service.
if ("".equals(SystemProperties.get("vold.encrypt_progress"))) {
copyLocaleFromMountService();
}
// Let package manager load internal ASECs.
//调用PMS来加载ASECs
mPms.scanAvailableAsecs();
// Notify people waiting for ASECs to be scanned that it's done.
//用于通知ASEC扫描已完成
mAsecsScanned.countDown();
}
mResponseQueue.add
public void add(int cmdNum, NativeDaemonEvent response) {
PendingCmd found = null;
synchronized (mPendingCmds) {
for (PendingCmd pendingCmd : mPendingCmds) {
if (pendingCmd.cmdNum == cmdNum) {
found = pendingCmd;
break;
}
}
//没有找到则创建相应的PendingCmd
if (found == null) {
// 没有找到,在添加之前,确保队列容量不溢出
while (mPendingCmds.size() >= mMaxCount) {
Slog.e("NativeDaemonConnector.ResponseQueue",
"more buffered than allowed: " + mPendingCmds.size() +
" >= " + mMaxCount);
// let any waiter timeout waiting for this
PendingCmd pendingCmd = mPendingCmds.remove();
Slog.e("NativeDaemonConnector.ResponseQueue",
"Removing request: " + pendingCmd.logCmd + " (" +
pendingCmd.cmdNum + ")");
}
found = new PendingCmd(cmdNum, null);
mPendingCmds.add(found);
}
found.availableResponseCount++;
// if a matching remove call has already retrieved this we can remove this
// instance from our list
if (found.availableResponseCount == 0) mPendingCmds.remove(found);
}
try {
found.responses.put(response);
} catch (InterruptedException e) { }
}
mResponseQueue.add(),通过该方法便能触发ResponseQueue.poll阻塞操作继续往下执行。
到此,MountService与NativeDaemonConnector都已经启动,之前我们看到MountService内部静态类LifeCycle继承自SystemService,那么接下来到系统启动到达阶段PHASE_ACTIVITY_MANAGER_READY,则调用到其onBootPhase方法。
Lifecycle->onBootPhase
// 由SystenServer启动到指定阶段进行回调,其内部由mServices持有
@Override
public void onBootPhase(int phase) {
// 由于MountService的内部Lifecycle已添加SystemServiceManager的mServices服务列表;
// 系统启动到PHASE_ACTIVITY_MANAGER_READY时会回调mServices中的onBootPhase方法
if (phase == SystemService.PHASE_ACTIVITY_MANAGER_READY) {
mMountService.systemReady();
}
}
由SystemService统一管理其声明流程,之后调用systemReady方法,如下:
systemReady
private void systemReady() {
mSystemReady = true;
// 此处 mHandler = new MountServiceHandler(hthread.getLooper())
// 采用的是线程 ”MountService” 中的 Looper
// system_server 主线程通过 handler 向线程 ”MountService” 发送 H_SYSTEM_READY 消息
mHandler.obtainMessage(H_SYSTEM_READY).sendToTarget();
}
MountService的systemReady通过Handler发送消息到MountServiceHandler中进行处理,其收到消息处理后进入handleSystemReady方法
handleSystemReady
private void handleSystemReady() {
synchronized (mLock) {
// 重置...
resetIfReadyAndConnectedLocked();
}
// Start scheduling nominally-daily fstrim operations
// 计划执行日常的 fstrim 操作【】
MountServiceIdler.scheduleIdlePass(mContext);
}
主要做了两件事情,一件事重置操作,一件事执行fstrim操作。
resetIfReadyAndConnectedLocked
private void resetIfReadyAndConnectedLocked() {
Slog.d(TAG, "Thinking about reset, mSystemReady=" + mSystemReady
+ ", mDaemonConnected=" + mDaemonConnected);
if (mSystemReady && mDaemonConnected) {
killMediaProvider();
// Mstar Android Patch Begin
new Thread() {
public void run() {
try {
mConnector.execute("volume", "reset");
// Tell vold about all existing and started users
//告知所有已经存在和启动的 users
final UserManager um = mContext.getSystemService(UserManager.class);
final List<UserInfo> users = um.getUsers();
for (UserInfo user : users) {
mConnector.execute("volume", "user_added", user.id, user.serialNumber);
}
for (int userId : mStartedUsers) {
mConnector.execute("volume", "user_started", userId);
}
} catch (NativeDaemonConnectorException e) {
Slog.w(TAG, "Failed to reset vold", e);
}
}
}.start();
// Mstar Android Patch End
}
}
首先检测系统是否启动完毕,是否和Vold建立连接,之后开启线程通过mConnector执行execute(“volume”, “reset”),并再次通过mConnector告知所有的用户user_added和user_started。
NDC->execute
NativeDaemonConnector执行execute经过层层调用,最终走到executeForList,此时命令执行超时时长为1分钟,具体如下:
public NativeDaemonEvent[] executeForList(long timeoutMs, String cmd, Object... args)
throws NativeDaemonConnectorException {
final long startTime = SystemClock.elapsedRealtime();
final ArrayList<NativeDaemonEvent> events = Lists.newArrayList();
final StringBuilder rawBuilder = new StringBuilder();
final StringBuilder logBuilder = new StringBuilder();
// mSequenceNumber初始化值为0,每执行一次该方法则进行加1操作
final int sequenceNumber = mSequenceNumber.incrementAndGet();
makeCommand(rawBuilder, logBuilder, sequenceNumber, cmd, args);
//例如:“7 volume mount”
final String rawCmd = rawBuilder.toString();
final String logCmd = logBuilder.toString();
log("SND -> {" + logCmd + "}");
synchronized (mDaemonLock) {
if (mOutputStream == null) {
throw new NativeDaemonConnectorException("missing output stream");
} else {
try {
//将 cmd 写入到 socket 的输出流
mOutputStream.write(rawCmd.getBytes(StandardCharsets.UTF_8));
} catch (IOException e) {
throw new NativeDaemonConnectorException("problem sending command", e);
}
}
}
NativeDaemonEvent event = null;
do {
event = mResponseQueue.remove(sequenceNumber, timeoutMs, logCmd);
if (event == null) {
loge("timed-out waiting for response to " + logCmd);
throw new NativeDaemonTimeoutException(logCmd, event);
}
if (VDBG) log("RMV <- {" + event + "}");
events.add(event);
// 当收到的事件响应码属于[100,200)区间,则继续等待后续事件上报
} while (event.isClassContinue());
final long endTime = SystemClock.elapsedRealtime();
//对于执行时间超过500ms则会记录到log
if (endTime - startTime > WARN_EXECUTE_DELAY_MS) {
loge("NDC Command {" + logCmd + "} took too long (" + (endTime - startTime) + "ms)");
}
if (event.isClassClientError()) {
throw new NativeDaemonArgumentException(logCmd, event);
}
if (event.isClassServerError()) {
throw new NativeDaemonFailureException(logCmd, event);
}
return events.toArray(new NativeDaemonEvent[events.size()]);
}
其流程也是比较重要的,主要是和Socket进行打交道。首先,将带执行的命令mSequenceNumber执行加1操作,再将cmd(例如7 volume mount)写入到socket的输出流,通知Vold进行处理。然后通过循环与poll机制等待执行底层响应该操作结果,否则直到1分钟超时才结束该方法。即便收到底层的响应码,如果响应码属于[100,200)区间,则继续阻塞等待后续事件上报。
mResponseQueue.remove
和上面的add操作相反,这里是将阻塞队列ResponseQueue移除操作,多有操作都是由ReentrantLock同步锁来控制,实现多线程下并发操作。
public NativeDaemonEvent remove(int cmdNum, long timeoutMs, String logCmd) {
PendingCmd found = null;
synchronized (mPendingCmds) {
// 从mPendingCmds查询cmdNum
for (PendingCmd pendingCmd : mPendingCmds) {
if (pendingCmd.cmdNum == cmdNum) {
found = pendingCmd;
break;
}
}
// 如果已有的mPendingCmds中查询不到,则创建一个新的PendingCmd
if (found == null) {
found = new PendingCmd(cmdNum, logCmd);
mPendingCmds.add(found);
}
found.availableResponseCount--;
// if a matching add call has already retrieved this we can remove this
// instance from our list
if (found.availableResponseCount == 0) mPendingCmds.remove(found);
}
NativeDaemonEvent result = null;
try {
//采用poll轮询方式等待底层上报该事件,直到1分钟超时
//这里用到poll,先来看看responses
result = found.responses.poll(timeoutMs, TimeUnit.MILLISECONDS);
} catch (InterruptedException e) {}
if (result == null) {
Slog.e("NativeDaemonConnector.ResponseQueue", "Timeout waiting for response");
}
return result;
}
- 关于ArrayBlockingQueue可以参考如下链接:
MountService总结
MountService启动方式和其他的Service有点不同,主要是由其静态内部类LifeCycle控制其实例化过程,然后LifeCycle又继承SystemService,从而其受到SystemService的控制,系统启动到Ready阶段便会回调LifeCycle对应的方法,然后由发送消息到MountService进行处理。
MountService启动时候,自行建立了三个子线程:MountService、VoldConnector、CryptdConnector,其中VoldConnector,CryptdConnector分别对应监听Vold进程中的两个线程,接受他它们传递过来的消息。
其中重要的NativeDaemonConnector负责和Vold传递来的Socket进行通信,其运行在VoldConnector线程中。同理还有一个NDC运行在CryptdConnecto线程中。
部分内容参考如下: