參考鏈接:
從一個(gè)簡(jiǎn)單的AIDL實(shí)現(xiàn)看binder原理(一)簡(jiǎn)單的AIDL實(shí)現(xiàn)
從一個(gè)簡(jiǎn)單的AIDL實(shí)現(xiàn)看binder原理(二)bindService的調(diào)用過(guò)程
從一個(gè)簡(jiǎn)單的AIDL實(shí)現(xiàn)看binder原理(三)bindService調(diào)用過(guò)程中Binder的傳遞
在上一篇博文中缔杉,我們分析了在bindService的過(guò)程中binder對(duì)象是怎么從Service進(jìn)程傳遞到Activity所在進(jìn)程的矛物,但是為什么傳遞的時(shí)候是一個(gè)Binder,但最后接收到的是個(gè)BinderProxy并沒(méi)有分析到布疼,本篇講分析Binder對(duì)象是在什么時(shí)機(jī)轉(zhuǎn)換為BinderProxy對(duì)象的
首先看一下Binder和BinderProxy的類(lèi)結(jié)構(gòu):
從上圖可以看出恨溜,Binder和BinderProxy是實(shí)現(xiàn)了IBinder接口的兩個(gè)類(lèi)止后,Binder和BinderProxy是不存在繼承關(guān)系的湘捎,所以不可能進(jìn)行強(qiáng)轉(zhuǎn)靶衍,最有可能的觸發(fā)節(jié)點(diǎn)就是在IPC的過(guò)程中,接下來(lái)我們驗(yàn)證一下這種猜測(cè)
我們繼續(xù)從ActivityThread#handleBindService方法說(shuō)起
private void handleBindService(BindServiceData data) {
Service s = mServices.get(data.token);
if (DEBUG_SERVICE)
Slog.v(TAG, "handleBindService s=" + s + " rebind=" + data.rebind);
if (s != null) {
try {
data.intent.setExtrasClassLoader(s.getClassLoader());
data.intent.prepareToEnterProcess();
try {
if (!data.rebind) {
IBinder binder = s.onBind(data.intent);
ActivityManager.getService().publishService(
data.token, data.intent, binder);
} else {
s.onRebind(data.intent);
ActivityManager.getService().serviceDoneExecuting(
data.token, SERVICE_DONE_EXECUTING_ANON, 0, 0);
}
ensureJitEnabled();
} catch (RemoteException ex) {
throw ex.rethrowFromSystemServer();
}
} catch (Exception e) {
if (!mInstrumentation.onException(s, e)) {
throw new RuntimeException(
"Unable to bind to service " + s
+ " with " + data.intent + ": " + e.toString(), e);
}
}
}
}
在代碼的第11行這里調(diào)用了Service的onBinder方法夫植,我們回顧一下第一篇博文中Service的實(shí)現(xiàn):
@Nullable
@Override
public IBinder onBind(Intent intent) {
StudentStub stub = new StudentStub();
Log.d("ipcLog", "stub = " + stub.getClass());
return stub;
}
public class StudentStub extends IAIDLInterface.Stub {
@Override
public List<Student> getStudent() throws RemoteException {
return studentList;
}
@Override
public void setStudent(Student student) throws RemoteException {
studentList.add(student);
}
}
從這里可以看出讹剔,onBind的返回時(shí)其實(shí)就是StudentStub 對(duì)象,也就是一個(gè)Binder對(duì)象详民,
我們繼續(xù)看第12行代碼:
ActivityManager.getService().publishService(
data.token, data.intent, binder);
這是一個(gè)IPC過(guò)程延欠,我們回顧一下第一篇博文中IPC的發(fā)起:
@Override
public void onClick(View v) {
switch (v.getId()) {
case R.id.btn_start:
bindService(new Intent(this, RemoteService.class), connection, BIND_AUTO_CREATE);
break;
case R.id.btn_add:
int code = Integer.valueOf(codeEt.getText().toString().trim());
String name = nameEt.getText().toString().trim();
try {
proxy.setStudent(new Student(code, name));
} catch (RemoteException e) {
e.printStackTrace();
}
break;
case R.id.btn_get:
try {
List<Student> students = proxy.getStudent();
if (students != null && students.size() > 0) {
StringBuilder sb = new StringBuilder();
for (Student student : students) {
sb.append(student.toString());
sb.append("\n");
}
studentListText.setText(sb.toString());
}
} catch (RemoteException e) {
e.printStackTrace();
}
break;
default:
break;
}
}
從上述代碼可以看到,在我們發(fā)起IPC的請(qǐng)求時(shí)沈跨,使用的是BinderBorxy的對(duì)象由捎,同理我們可以得出,在跨進(jìn)程調(diào)用ActivityManagerService中的方法時(shí)饿凛,也是使用AMS的BinderProxy對(duì)象狞玛,這個(gè)對(duì)象的實(shí)現(xiàn)是在IActivityManager的Proxy類(lèi)中,Proxy類(lèi)是Stub的內(nèi)部類(lèi)涧窒,而Stub是IActivityManager的內(nèi)部類(lèi),其類(lèi)文件結(jié)構(gòu)如圖所示:
看到這里是不是有一種豁然開(kāi)朗的感覺(jué)心肪?原來(lái)大名鼎鼎的ActivityMangerService的實(shí)現(xiàn)原理和我們普通的AIDL是一模一樣的!
我們繼續(xù)跟進(jìn)publishService方法的實(shí)現(xiàn)纠吴,首先看發(fā)起端硬鞍,即IActivityManager$Stub中Proxy的實(shí)現(xiàn):
@Override
public void publishService(android.os.IBinder token, android.content.Intent intent, android.os.IBinder service) throws android.os.RemoteException {
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
try {
_data.writeInterfaceToken(DESCRIPTOR);
_data.writeStrongBinder(token);
if ((intent != null)) {
_data.writeInt(1);
intent.writeToParcel(_data, 0);
} else {
_data.writeInt(0);
}
_data.writeStrongBinder(service);
mRemote.transact(Stub.TRANSACTION_publishService, _data, _reply, 0);
_reply.readException();
} finally {
_reply.recycle();
_data.recycle();
}
}
方法的第三個(gè)參數(shù)就是我們要傳遞的RemoteService中的Binder,在這里將他傳入了Parcel的writeStrongBinder方法的參數(shù)里戴已,繼續(xù)跟進(jìn)Parcel的writeStrongBinder方法:
public final void writeStrongBinder(IBinder val) {
nativeWriteStrongBinder(mNativePtr, val);
}
這里轉(zhuǎn)入了jni層的nativeWriteStrongBinder方法繼續(xù)執(zhí)行固该,具體實(shí)現(xiàn)在android_os_Parcel.cpp中:
static void android_os_Parcel_writeStrongBinder(JNIEnv* env, jclass clazz, jlong nativePtr, jobject object)
{
Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
if (parcel != NULL) {
const status_t err = parcel->writeStrongBinder(ibinderForJavaObject(env, object));
if (err != NO_ERROR) {
signalExceptionForError(env, clazz, err);
}
}
}
這里轉(zhuǎn)到了Parcel.cpp的writeStrongBinder方法中,其傳遞的參數(shù)是android_util_Binder.cpp的ibinderForJavaObject方法的返回值:
// android_util_Binder.cpp
sp<IBinder> ibinderForJavaObject(JNIEnv* env, jobject obj)
{
if (obj == NULL) return NULL;
//Java層的Binder對(duì)象
if (env->IsInstanceOf(obj, gBinderOffsets.mClass)) {
JavaBBinderHolder* jbh = (JavaBBinderHolder*)
env->GetLongField(obj, gBinderOffsets.mObject);
return jbh != NULL ? jbh->get(env, obj) : NULL; //【見(jiàn)3.5.3】
}
//Java層的BinderProxy對(duì)象
if (env->IsInstanceOf(obj, gBinderProxyOffsets.mClass)) {
return (IBinder*)env->GetLongField(obj, gBinderProxyOffsets.mObject);
}
return NULL;
}
這個(gè)方法的主要工作是根據(jù)Binde(Java)生成JavaBBinderHolder(C++)對(duì)象. 主要工作是創(chuàng)建JavaBBinderHolder對(duì)象,并把JavaBBinderHolder對(duì)象地址保存到Binder.mObject成員變量.
// android_util_Binder.cpp
sp<JavaBBinder> get(JNIEnv* env, jobject obj)
{
AutoMutex _l(mLock);
sp<JavaBBinder> b = mBinder.promote();
if (b == NULL) {
//首次進(jìn)來(lái)糖儡,創(chuàng)建JavaBBinder對(duì)象【見(jiàn)3.5.4】
b = new JavaBBinder(env, obj);
mBinder = b;
}
return b;
}
JavaBBinder的初始化在這里:
// android_util_Binder.cpp
JavaBBinder(JNIEnv* env, jobject object)
: mVM(jnienv_to_javavm(env)), mObject(env->NewGlobalRef(object))
{
android_atomic_inc(&gNumLocalRefs);
incRefsCreated(env);
}
創(chuàng)建JavaBBinder伐坏,該對(duì)象繼承于BBinder對(duì)象。
data.writeStrongBinder(service)最終等價(jià)于parcel->writeStrongBinder(new JavaBBinder(env, obj));
也就是將java的Binder對(duì)象轉(zhuǎn)成了C++的BBinder對(duì)象
分析過(guò)參數(shù)后握联,繼續(xù)分析Parcel.cpp的writeStrongBinder方法:
// Parcel.cpp
status_t Parcel::writeStrongBinder(const sp<IBinder>& val)
{
return flatten_binder(ProcessState::self(), val, this);
}
status_t flatten_binder(const sp<ProcessState>& /*proc*/,
const sp<IBinder>& binder, Parcel* out)
{
flat_binder_object obj;
obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;
if (binder != NULL) {
IBinder *local = binder->localBinder();
if (!local) {
BpBinder *proxy = binder->remoteBinder();
const int32_t handle = proxy ? proxy->handle() : 0;
obj.type = BINDER_TYPE_HANDLE; //遠(yuǎn)程Binder
obj.binder = 0;
obj.handle = handle;
obj.cookie = 0;
} else {
obj.type = BINDER_TYPE_BINDER; //本地Binder桦沉,進(jìn)入該分支
obj.binder = reinterpret_cast<uintptr_t>(local->getWeakRefs());
obj.cookie = reinterpret_cast<uintptr_t>(local);
}
} else {
obj.type = BINDER_TYPE_BINDER; //本地Binder
obj.binder = 0;
obj.cookie = 0;
}
return finish_flatten_binder(binder, obj, out);
}
對(duì)于Binder實(shí)體,則cookie記錄Binder實(shí)體的指針拴疤;
對(duì)于Binder代理永部,則用handle記錄Binder代理的句柄;
binder->localBinder()呐矾,可以看Binder.cpp苔埋,binder->binder->remoteBinder(),可以看BpBinder.cpp
// Binder.cpp
BBinder* BBinder::localBinder()
{
return this;
}
BpBinder* IBinder::remoteBinder()
{
return NULL;
}
// BpBinder.cpp
BBinder* IBinder::localBinder()
{
return NULL;
}
BpBinder* BpBinder::remoteBinder()
{
return this;
}
從這里可以看出蜒犯,如果是BBinder對(duì)象组橄,locaBinder方法會(huì)返回其自身荞膘,如果是BpBinder對(duì)象,remoteBinder方法會(huì)返回其自身玉工,因?yàn)槲覀冊(cè)贐inder傳遞過(guò)程中羽资,傳遞的是Binder的實(shí)體,即Java的Binder對(duì)象遵班、C++的BBinder對(duì)象屠升,因此Parcel.cpp的flatten_binder方法會(huì)走入下面的分支:
obj.type = BINDER_TYPE_BINDER; //本地Binder,進(jìn)入該分支
obj.binder = reinterpret_cast<uintptr_t>(local->getWeakRefs());
obj.cookie = reinterpret_cast<uintptr_t>(local);
到這里狭郑,Binder對(duì)象的扁平化處理就完成了
接下來(lái)接著看IActivityManager#publishService方法腹暖,在執(zhí)行完成_data.writeStrongBinder(service)后繼續(xù)執(zhí)行了 mRemote.transact(Stub.TRANSACTION_publishService, _data, _reply, 0),這個(gè)mRemote是BinderProxy的一個(gè)實(shí)例翰萨,具體為啥可參考第一篇博文脏答,即AIDL的實(shí)現(xiàn)。
因此亩鬼,這里的執(zhí)行就轉(zhuǎn)到了Binder.java$BinderProxy#transact中:
public boolean transact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {
Binder.checkParcel(this, code, data, "Unreasonably large binder buffer");
if (mWarnOnBlocking && ((flags & FLAG_ONEWAY) == 0)) {
// For now, avoid spamming the log by disabling after we've logged
// about this interface at least once
mWarnOnBlocking = false;
Log.w(Binder.TAG, "Outgoing transactions from this process must be FLAG_ONEWAY",
new Throwable());
}
final boolean tracingEnabled = Binder.isTracingEnabled();
if (tracingEnabled) {
final Throwable tr = new Throwable();
Binder.getTransactionTracker().addTrace(tr);
StackTraceElement stackTraceElement = tr.getStackTrace()[1];
Trace.traceBegin(Trace.TRACE_TAG_ALWAYS,
stackTraceElement.getClassName() + "." + stackTraceElement.getMethodName());
}
try {
return transactNative(code, data, reply, flags);
} finally {
if (tracingEnabled) {
Trace.traceEnd(Trace.TRACE_TAG_ALWAYS);
}
}
}
在方法的結(jié)尾殖告,有一次轉(zhuǎn)入了jni層執(zhí)行transactNative方法,這個(gè)方法的實(shí)現(xiàn)是android_util_Binder.cpp的android_os_BinderProxy_transact方法:
static jboolean android_os_BinderProxy_transact(JNIEnv* env, jobject obj,
jint code, jobject dataObj, jobject replyObj, jint flags) // throws RemoteException
{
...
// java Parcel對(duì)象轉(zhuǎn)為native Parcel對(duì)象
Parcel* data = parcelForJavaObject(env, dataObj);
...
// java Parcel對(duì)象轉(zhuǎn)為native Parcel對(duì)象
Parcel* reply = parcelForJavaObject(env, replyObj);
//java BinderProxy對(duì)象(即mRemote)轉(zhuǎn)為native BinderProxy對(duì)象
IBinder* target = (IBinder*)env->GetLongField(obj, gBinderProxyOffsets.mObject);
...
status_t err = target->transact(code, *data, reply, flags);
...
}
這段代碼主要是對(duì)java層的對(duì)象進(jìn)行了一次轉(zhuǎn)換后轉(zhuǎn)入native層進(jìn)行調(diào)用雳锋,因?yàn)閙Remote是BinderProxy對(duì)象黄绩,因此target是一個(gè)BpBinder對(duì)象,最終 target->transact轉(zhuǎn)入BpBinder.cpp->transact方法中:
// BpBinder.cpp
status_t BpBinder::transact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
// Once a binder has died, it will never come back to life.
if (mAlive) {
status_t status = IPCThreadState::self()->transact(
mHandle, code, data, reply, flags);
if (status == DEAD_OBJECT) mAlive = 0;
return status;
}
return DEAD_OBJECT;
}
其中data就是我們要傳遞的Parcel對(duì)象玷过。
在這里又繼續(xù)調(diào)用了IPCThreadState::self()->transact方法宝与,從本篇開(kāi)始到現(xiàn)在,這些邏輯一直在RemoteService所在進(jìn)程中執(zhí)行冶匹,一直沒(méi)有看到有跨進(jìn)程調(diào)用的跡象,當(dāng)我們看到IPC開(kāi)頭的這個(gè)類(lèi)名時(shí)咆瘟,我們知道嚼隘,離真正開(kāi)始跨進(jìn)程調(diào)用不遠(yuǎn)了!OK袒餐,接下來(lái)繼續(xù)分析IPCThreadState.cpp的transact方法:
// IPCThreadState.cpp
tatus_t IPCThreadState::transact(int32_t handle,
uint32_t code, const Parcel& data,
Parcel* reply, uint32_t flags)
{
status_t err = data.errorCheck();
flags |= TF_ACCEPT_FDS;
IF_LOG_TRANSACTIONS() {
TextOutput::Bundle _b(alog);
alog << "BC_TRANSACTION thr " << (void*)pthread_self() << " / hand "
<< handle << " / code " << TypeCode(code) << ": "
<< indent << data << dedent << endl;
}
if (err == NO_ERROR) {
LOG_ONEWAY(">>>> SEND from pid %d uid %d %s", getpid(), getuid(),
(flags & TF_ONE_WAY) == 0 ? "READ REPLY" : "ONE WAY");
err = writeTransactionData(BC_TRANSACTION, flags, handle, code, data, NULL);
}
if (err != NO_ERROR) {
if (reply) reply->setError(err);
return (mLastError = err);
}
if ((flags & TF_ONE_WAY) == 0) {
#if 0
if (code == 4) { // relayout
ALOGI(">>>>>> CALLING transaction 4");
} else {
ALOGI(">>>>>> CALLING transaction %d", code);
}
#endif
if (reply) {
err = waitForResponse(reply);
} else {
Parcel fakeReply;
err = waitForResponse(&fakeReply);
}
#if 0
if (code == 4) { // relayout
ALOGI("<<<<<< RETURNING transaction 4");
} else {
ALOGI("<<<<<< RETURNING transaction %d", code);
}
#endif
IF_LOG_TRANSACTIONS() {
TextOutput::Bundle _b(alog);
alog << "BR_REPLY thr " << (void*)pthread_self() << " / hand "
<< handle << ": ";
if (reply) alog << indent << *reply << dedent << endl;
else alog << "(none requested)" << endl;
}
} else {
err = waitForResponse(NULL, NULL);
}
return err;
}
其中調(diào)用writeTransactionData即是寫(xiě)入要傳輸數(shù)據(jù)的過(guò)程飞蛹,它的實(shí)現(xiàn)如下:
// IPCThreadState.cpp
status_t IPCThreadState::writeTransactionData(int32_t cmd, uint32_t binderFlags,
int32_t handle, uint32_t code, const Parcel& data, status_t* statusBuffer)
{
binder_transaction_data tr;
tr.target.ptr = 0;
tr.target.handle = handle; // handle = 0
tr.code = code; // code = ADD_SERVICE_TRANSACTION
tr.flags = binderFlags; // binderFlags = 0
tr.cookie = 0;
tr.sender_pid = 0;
tr.sender_euid = 0;
// data為記錄Media服務(wù)信息的Parcel對(duì)象
const status_t err = data.errorCheck();
if (err == NO_ERROR) {
tr.data_size = data.ipcDataSize(); // mDataSize
tr.data.ptr.buffer = data.ipcData(); //mData
tr.offsets_size = data.ipcObjectsCount()*sizeof(binder_size_t); //mObjectsSize
tr.data.ptr.offsets = data.ipcObjects(); //mObjects
} else if (statusBuffer) {
...
} else {
return (mLastError = err);
}
mOut.writeInt32(cmd); //cmd = BC_TRANSACTION
mOut.write(&tr, sizeof(tr)); //寫(xiě)入binder_transaction_data數(shù)據(jù)
return NO_ERROR;
}
這里的handle是BpBinder對(duì)象所持有mHandle,即BpBinder所對(duì)應(yīng)的BBinder,也就是Binder的本地實(shí)體灸眼,
binder_transaction_data結(jié)構(gòu)體是binder驅(qū)動(dòng)通信的數(shù)據(jù)結(jié)構(gòu)卧檐,該過(guò)程最終是把Binder請(qǐng)求碼BC_TRANSACTION和binder_transaction_data結(jié)構(gòu)體寫(xiě)入到mOut
接下來(lái)會(huì)執(zhí)行到IPCThreadState.cpp->waitForResponse方法:
status_t IPCThreadState::waitForResponse(Parcel *reply, status_t *acquireResult)
{
int32_t cmd;
int32_t err;
while (1) {
if ((err=talkWithDriver()) < NO_ERROR) break;
...
if (mIn.dataAvail() == 0) continue;
cmd = mIn.readInt32();
switch (cmd) {
case BR_TRANSACTION_COMPLETE: ...
case BR_DEAD_REPLY: ...
case BR_FAILED_REPLY: ...
case BR_ACQUIRE_RESULT: ...
case BR_REPLY: ...
goto finish;
default:
err = executeCommand(cmd);
if (err != NO_ERROR) goto finish;
break;
}
}
...
return err;
}
注意看talkWithDriver方法,在這里會(huì)正式進(jìn)入Android內(nèi)核焰宣,即Binder驅(qū)動(dòng)中進(jìn)行跨進(jìn)程傳遞和轉(zhuǎn)換霉囚。
具體的細(xì)節(jié)篇幅有限,我們下一篇再講匕积。