0x00 从进程的角度来看Android系统启动
1、SystemServer:java层binder机制的构建者,最初一个主线程和一个子线程来处理Binder进程间通信请求。另外一个子线程处理Hander线程间通信请求。
通过ServiceManager来加载ActiviryMangerService,以便在应用程序进程中可以通过Binder进程间通信访问到ActiviryMangerService。
ActivityManagerService m = mSelf;
ServiceManager.addService("activity", m);
2、servicemanager:binder dns,C++编写。
3、Zygote:所有进程的孵化器,SystemServer通过socket进行进程间通信请求。
4、MediaServer:C++层binder机制的构建者,最初一个主线程和一个子线程来处理Binder进程间通信请求。
sp<ProcessState> proc(ProcessState::self());
125 sp<IServiceManager> sm = defaultServiceManager();
126 ALOGI("ServiceManager: %p", sm.get());
127 AudioFlinger::instantiate();
128 MediaPlayerService::instantiate();
129 CameraService::instantiate();
130 AudioPolicyService::instantiate();
131 registerExtensions();
132 ProcessState::self()->startThreadPool();
133 IPCThreadState::self()->joinThreadPool();
void MediaPlayerService::instantiate() {
defaultServiceManager()->addService(
String16("media.player"), new MediaPlayerService());
}
在C++层通过servicemanager添加MediaPlayerService。
0x01 一次同步Binder进程间通信
Client:处理从Binder Driver返回的命令
status_t IPCThreadState::waitForResponse(Parcel *reply, status_t *acquireResult)
{
int32_t cmd;
int32_t err;
while (1) {
if ((err=talkWithDriver()) < NO_ERROR) break;
err = mIn.errorCheck();
if (err < NO_ERROR) break;
if (mIn.dataAvail() == 0) continue;
cmd = mIn.readInt32();
IF_LOG_COMMANDS() {
alog << "Processing waitForResponse Command: "
<< getReturnString(cmd) << endl;
}
switch (cmd) {
case BR_TRANSACTION_COMPLETE:
if (!reply && !acquireResult) goto finish;
break;
case BR_DEAD_REPLY:
err = DEAD_OBJECT;
goto finish;
case BR_FAILED_REPLY:
err = FAILED_TRANSACTION;
goto finish;
case BR_ACQUIRE_RESULT:
{
LOG_ASSERT(acquireResult != NULL, "Unexpected brACQUIRE_RESULT");
const int32_t result = mIn.readInt32();
if (!acquireResult) continue;
*acquireResult = result ? NO_ERROR : INVALID_OPERATION;
}
goto finish;
case BR_REPLY:
{
binder_transaction_data tr;
err = mIn.read(&tr, sizeof(tr));
LOG_ASSERT(err == NO_ERROR, "Not enough command data for brREPLY");
if (err != NO_ERROR) goto finish;
if (reply) {
if ((tr.flags & TF_STATUS_CODE) == 0) {
reply->ipcSetDataReference(
reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),
tr.data_size,
reinterpret_cast<const size_t*>(tr.data.ptr.offsets),
tr.offsets_size/sizeof(size_t),
freeBuffer, this);
} else {
err = *static_cast<const status_t*>(tr.data.ptr.buffer);
freeBuffer(NULL,
reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),
tr.data_size,