コアサービス開発に必要な情報を整理2

onTransact()(IBinder.transact())を直接扱う実装が必要で煩雑になるところを、Proxy-Stubパターンでより簡単に扱える。というC++Javaの実装例をまとめるのがこのテーマのゴール。で、これは自分用のメモメモ。

chiaki@ubuntu:~/mydroid/frameworks/base/libs/binder$ view ProcessState.cpp 
sp<ProcessState> ProcessState::self()
{
    if (gProcess != NULL) return gProcess;
   
    AutoMutex _l(gProcessMutex);
    if (gProcess == NULL) gProcess = new ProcessState;
    return gProcess;
}

void ProcessState::startThreadPool()
{
    AutoMutex _l(mLock);
    if (!mThreadPoolStarted) {
        mThreadPoolStarted = true;
        spawnPooledThread(true);
    }
}

void ProcessState::spawnPooledThread(bool isMain)
{
    if (mThreadPoolStarted) {
        int32_t s = android_atomic_add(1, &mThreadPoolSeq);
        char buf[32];
        sprintf(buf, "Binder Thread #%d", s);
        LOGV("Spawning new pooled thread, name=%s\n", buf);
        sp<Thread> t = new PoolThread(isMain);
        t->run(buf);
    }
}
chiaki@ubuntu:~/mydroid/frameworks/base/libs/binder$ vi IPCThreadState.cpp 
void IPCThreadState::joinThreadPool(bool isMain)
{
}
status_t IPCThreadState::transact(int32_t handle,
                                  uint32_t code, const Parcel& data,
                                  Parcel* reply, uint32_t flags)
{
}
status_t IPCThreadState::talkWithDriver(bool doReceive)
{
}
status_t IPCThreadState::executeCommand(int32_t cmd)
{
…略
 case BR_TRANSACTION:
        {
		…略
		if (tr.target.ptr) {
                sp<BBinder> b((BBinder*)tr.cookie);
                const status_t error = b->transact(tr.code, buffer, &reply, tr.flags);
		…略
		}
	}
}
chiaki@ubuntu:~/mydroid/frameworks$ vi base/core/jni/android_util_Binder.cpp
virtual status_t onTransact(
        uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0)
    {
	…略
	jboolean res = env->CallBooleanMethod(mObject, gBinderOffsets.mExecTransact,
            code, (int32_t)&data, (int32_t)reply, flags);
chiaki@ubuntu:~/mydroid/frameworks$ vi base/core/java/android/os/Binder.java 
 private boolean execTransact(int code, int dataObj, int replyObj,
            int flags) {
		…略
		try {
            res = onTransact(code, data, reply, flags);
        } catch (RemoteException e) {
		…略

のあたり。

ProcessState::self()->startThreadPool();
IPCThreadState::self()->joinThreadPool();