背景
从addService()
场景分析:
此时,Server
作为客户端,ServiceManager
进程作为服务端。
一、Java层addService()
java层注册service,通过ServiceManager的addService()。
ServiceManager.java
public static void addService(String name, IBinder service) {
try {
getIServiceManager().addService(name, service, false);
} catch (RemoteException e) {
Log.e(TAG, "error in addService", e);
}
}
getIServiceManager() 返回一个 ServiceManagerProxy对象,ServiceManagerProxy是ServiceManagerNative的静态内部类。
最终调用 ServiceManagerProxy 的addService():
ServiceManagerProxy.java
private IBinder mRemote; // 本质上是BinderProxy对象
public void addService(String name, IBinder service, boolean allowIsolated)
throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IServiceManager.descriptor);
//往parcel写入service的名字
data.writeString(name);
//往parcel写入service实例
data.writeStrongBinder(service);
data.writeInt(allowIsolated ? 1 : 0);
mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0);
//回收parcel的内存
reply.recycle();
data.recycle();
}
- 往parcel写入service的名字
- 往parcel写入service实例:HelloService对象
- 调用mRemote.transact()方法发送数据
- 回收parcel的内存
mRemote
是什么? ?
先回答: mRemote
是一个BinderProxy
对象。
1.1 IServiceManager代理服务的获取
既然server端是往ServiceManager注册服务,那么第一步就要获取到SM的代理对象BinderProxy。
初始化如下:
private static IServiceManager getIServiceManager() {
if (sServiceManager != null) {
return sServiceManager; //单例
}
// Find the service manager
sServiceManager = ServiceManagerNative
.asInterface(Binder.allowBlocking(BinderInternal.getContextObject()));
return sServiceManager;
}
1.1.1 getContextObject()
BinderInternal
的 getContextObject()
:
//返回IBinder 的是IServiceManager的实现
public static final native IBinder getContextObject();
是一个native方法,调用到jni层的方法,最终返回一个native
的BpBinder
对象。
/frameworks/base/core/jni/android_util_Binder.cpp
static jobject android_os_BinderInternal_getContextObject(JNIEnv* env, jobject clazz)
{
sp<IBinder> b = ProcessState::self()->getContextObject(NULL);
// 返回给java层
return javaObjectForIBinder(env, b);
}
根据ProcessState
单例对象,得到一个BpBinder()
。 继续深入ProcessState的getContextObject()
:
//传入的null。0 表示ServiceManager的 handle值。
sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& /*caller*/)
117 {
118 return getStrongProxyForHandle(0);
119 }
1.1.2 getStrongProxyForHandle()
0 表示 ServiceManager
进程的 handle
值,继续看getStrongProxyForHandle(0)
:
sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle)
260 {
261 sp<IBinder> result;
262
263 AutoMutex _l(mLock);
264
265 handle_entry* e = lookupHandleLocked(handle);
266
267 if (e != nullptr) {
268 // We need to create a new BpBinder if there isn't currently one, OR we
269 // are unable to acquire a weak reference on this current one. See comment
270 // in getWeakProxyForHandle() for more info about this.
271 IBinder* b = e->binder;
272 ...
299 // 创建一个BpBinder 对象
300 b = BpBinder::create(handle);
301 e->binder = b;
302 if (b) e->refs = b->getWeakRefs();
303 result = b;
304 } else {
305 // This little bit of nastyness is to allow us to add a primary
306 // reference to the remote proxy when this team doesn't have one
307 // but another team is sending the handle to us.
308 result.force_set(b);
309 e->refs->decWeak(this);
310 }
311 }
312
313 return result;
314 }
至此,通过BpBinder::create(handle)
创建了一个BpBinder
对象并返回给java
层, handle表示ServiceManager的引用。BpBinder
对象里面的 mRemote
就等于此处 handle
。
那么是如何返回给java层的呢? 通过 javaObjectForIBinder()
。
1.2 javaObjectForIBinder()
661
662 // If the argument is a JavaBBinder, return the Java object that was used to create it.
663 // Otherwise return a BinderProxy for the IBinder. If a previous call was passed the
664 // same IBinder, and the original BinderProxy is still alive, return the same BinderProxy.
// 如果参数是一个JavaBBinder,那么久返回一个JavaBBinder 的java对象。否则返回 BinderProxy java对象
665 jobject javaObjectForIBinder(JNIEnv* env, const sp<IBinder>& val)
666 {
667 if (val == NULL) return NULL;
668
669 if (val->checkSubclass(&gBinderOffsets)) {
670 // It's a JavaBBinder created by ibinderForJavaObject. Already has Java object.
671 jobject object = static_cast<JavaBBinder*>(val.get())->object();
672 LOGDEATH("objectForBinder %p: it's our own %p!\n", val.get(), object);
673 return object;
674 }
675
676 BinderProxyNativeData* nativeData = new BinderProxyNativeData();
677 nativeData->mOrgue = new DeathRecipientList;
678 nativeData->mObject = val;
679 // 反射构造 BinderProxy java对象,同时long nativeData 成员变量指向 native的 BpBinder对象
//这样,java层就与native层建立了通信通道。
680 jobject object = env->CallStaticObjectMethod(gBinderProxyOffsets.mClass,
681 gBinderProxyOffsets.mGetInstance, (jlong) nativeData, (jlong) val.get());
682 if (env->ExceptionCheck()) {
683 // In the exception case, getInstance still took ownership of nativeData.
684 return NULL;
685 }
686 BinderProxyNativeData* actualNativeData = getBPNativeData(env, object);
687 ...
699 } else {
700 delete nativeData;
701 }
702
703 return object;
704 }
通过反射构造 BinderProxy
java对象,同时它的long nativeData
成员变量指向 native的 BpBinder
对象。
这样,java
层就与native
层建立了通信通道。
1.3 ServiceManagerNative.asInterface
//把一个IBinder(BinderProxy)代理对象转换为一个IServiceManager对象
static public IServiceManager asInterface(IBinder obj)
{
if (obj == null) {
return null;
}
IServiceManager in =
(IServiceManager)obj.queryLocalInterface(descriptor);
if (in != null) {
return in;
}
// 得到代理对象
return new ServiceManagerProxy(obj);
}
往 ServiceManager
发送数据都是通过 ServiceManagerProxy
代理对象发起的。在发送数据前,我们的先构造数据!
二、构造数据
public void addService(String name, IBinder service, boolean allowIsolated)
throws RemoteException {
//1
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
//2
data.writeInterfaceToken(IServiceManager.descriptor);
data.writeString(name);
data.writeStrongBinder(service);
data.writeInt(allowIsolated ? 1 : 0);
//3
mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0);
reply.recycle();
data.recycle();
}
- 获取两个parcel容器,用来存储发送数据和接收返回数据
- 写入service name和对应的实例对象
- 开始发送
2.1 obtain()
public static Parcel obtain() {
final Parcel[] pool = sOwnedPool;
synchronized (pool) {
Parcel p;
for (int i=0; i<POOL_SIZE; i++) {
p = pool[i];
if (p != null) {
pool[i] = null;
if (DEBUG_RECYCLE) {
p.mStack = new RuntimeException();
}
p.mReadWriteHelper = ReadWriteHelper.DEFAULT;
return p;
}
}
}
return new Parcel(0);
}
从缓存池中获取一个parcel
对象。 最终会在java层和native分别创建出 parcel
对象(具体过程可以参考第三篇文章),且java层的parcel对象中成员mNative
指向了native
层的parcel
对象。
2.2 service实例对象的构造
我们可以看下继承关系:
HelloService
继承Stub
抽象类Stub
类继承了Binder
类Binder
类实现了IBinder
接口
HelloService
构造时候会调用Binder
类的构造方法:
public Binder(@Nullable String descriptor) {
mObject = getNativeBBinderHolder();
NoImagePreloadHolder.sRegistry.registerNativeAllocation(this, mObject);
if (FIND_POTENTIAL_LEAKS) {
final Class<? extends Binder> klass = getClass();
if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) &&
(klass.getModifiers() & Modifier.STATIC) == 0) {
Log.w(TAG, "The following Binder class should be static or leaks might occur: " +
klass.getCanonicalName());
}
}
mDescriptor = descriptor;
}
mObject
引用了C++ 层 JavaBBinderHolder
对象。
2.2.1 getNativeBBinderHolder()
private static native long getNativeBBinderHolder();
是一个jni方法,返回一个c++的 JavaBBinderHolder
对象的引用(long)。
/frameworks/base/core/jni/android_util_Binder.cpp
static jlong android_os_Binder_getNativeBBinderHolder(JNIEnv* env, jobject clazz)
938 {
939 JavaBBinderHolder* jbh = new JavaBBinderHolder();
940 return (jlong) jbh;
941 }
2.2.2 JavaBBinderHolder构造方法
class JavaBBinderHolder
421 {
422 public:
// 提供了一个get方法,里面会创建javaBBinder对象
423 sp<JavaBBinder> get(JNIEnv* env, jobject obj)
424 {
425 AutoMutex _l(mLock);
426 sp<JavaBBinder> b = mBinder.promote();
427 if (b == NULL) {
// 实例化JavaBBinder 对象 ,赋值给mBinder。 obj表示java层的binder对象
428 b = new JavaBBinder(env, obj);
429 mBinder = b;
430 ALOGV("Creating JavaBinder %p (refs %p) for Object %p, weakCount=%" PRId32 "\n",
431 b.get(), b->getWeakRefs(), obj, b->getWeakRefs()->getWeakCount());
432 }
433
434 return b;
435 }
436
437 sp<JavaBBinder> getExisting()
438 {
439 AutoMutex _l(mLock);
440 return mBinder.promote();
441 }
442
443 private:
444 Mutex mLock;
445 wp<JavaBBinder> mBinder;
446 };
提供了一个get方法,里面会创建 JavaBBinder
对象。但是此时,不会创建。那什么时候创建呢?是在 writeStrongBinder()
里面调用,不过我们先暂时不管这个顺序,先看看JavaBBinder的构造
2.2.3 JavaBBinder类
class JavaBBinder : public BBinder
302 {
303 public:
//object 指向的是java层 Binder对象,也就是HelloService对象
304 JavaBBinder(JNIEnv* env, jobject /* Java Binder */ object)
305 : mVM(jnienv_to_javavm(env)), mObject(env->NewGlobalRef(object))
306 {
307 ALOGV("Creating JavaBBinder %p\n", this);
308 gNumLocalRefsCreated.fetch_add(1, std::memory_order_relaxed);
309 gcIfManyNewRefs(env);
310 }
311
312 bool checkSubclass(const void* subclassID) const
313 {
314 return subclassID == &gBinderOffsets;
315 }
316
317 jobject object() const
318 {
319 return mObject; // 表示 java的binder
320 }
321
322 protected:
323 virtual ~JavaBBinder()
324 {
325 ALOGV("Destroying JavaBBinder %p\n", this);
326 gNumLocalRefsDeleted.fetch_add(1, memory_order_relaxed);
327 JNIEnv* env = javavm_to_jnienv(mVM);
328 env->DeleteGlobalRef(mObject);
329 }
330
// 重写了onTransact函数
status_t onTransact(
356 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0) override
357 {
358 JNIEnv* env = javavm_to_jnienv(mVM);
359
360 ALOGV("onTransact() on %p calling object %p in env %p vm %p\n", this, mObject, env, mVM);
361
362 IPCThreadState* thread_state = IPCThreadState::self();
363 const int32_t strict_policy_before = thread_state->getStrictModePolicy();
364
365 //printf("Transact from %p to Java code sending: ", this);
366 //data.print();
367 //printf("\n");
// 回调java层的 Binder对象的 onTransact方法
368 jboolean res = env->CallBooleanMethod(mObject, gBinderOffsets.mExecTransact,
369 code, reinterpret_cast<jlong>(&data), reinterpret_cast<jlong>(reply), flags);
370
371 if (env->ExceptionCheck()) {
372 ScopedLocalRef<jthrowable> excep(env, env->ExceptionOccurred());
373 report_exception(env, excep.get(),
374 "*** Uncaught remote exception! "
375 "(Exceptions are not yet supported across processes.)");
376 res = JNI_FALSE;
377 }
378 ...
402 return res != JNI_FALSE ? NO_ERROR : UNKNOWN_TRANSACTION;
403 }
1. JavaBBinder
重写了onTransact
函数。
2. 回调java层的 Binder的 onTransact
方法。当驱动层后续处理完数据后,就会回调到这里,最终就回调到java
层的Binder
的onTransact
方法中去,这里暂不深究。
至此,我们得到了java层的HelloService
对象,且成员变量mObject引用了c++ 层的JavaBBinderHolder
对象。
2.3 writeStrongBinder()
这一步,我们把 HelloService
对象写入到 Parcel
容器里,准备跨进程发送。
//在parcel对象的当前位置写入一个IBinder对象
public final void writeStrongBinder(IBinder val) {
//jni方法 参数:mNativePtr c++层parcel对象引用。 val:当前的HelloService对象
nativeWriteStrongBinder(mNativePtr, val);
}
看jni的方法:
static void android_os_Parcel_writeStrongBinder(JNIEnv* env, jclass clazz, jlong nativePtr, jobject object)
299 { //强转为 parcel对象
300 Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
301 if (parcel != NULL) {
302 const status_t err = parcel->writeStrongBinder(ibinderForJavaObject(env, object));
303 if (err != NO_ERROR) {
304 signalExceptionForError(env, clazz, err);
305 }
306 }
307 }
2.3.1 ibinderForJavaObject()
sp<IBinder> ibinderForJavaObject(JNIEnv* env, jobject obj)
707 {
708 if (obj == NULL) return NULL;
709
710 // Instance of Binder?
711 if (env->IsInstanceOf(obj, gBinderOffsets.mClass)) {
//根据java层的Binder对象中的mObject对象得到 JavaBBinderHolder对象。
// 参考 2.2
712 JavaBBinderHolder* jbh = (JavaBBinderHolder*)
713 env->GetLongField(obj, gBinderOffsets.mObject);
//调用了JavaBBinderHolder的get方法,还记得之前的调用实际吧!!
714 return jbh->get(env, obj);
715 }
716
717 // Instance of BinderProxy?
718 if (env->IsInstanceOf(obj, gBinderProxyOffsets.mClass)) {
719 return getBPNativeData(env, obj)->mObject;
720 }
721
722 ALOGW("ibinderForJavaObject: %p is not a Binder object", obj);
723 return NULL;
724 }
调用了 JavaBBinderHolder
的get()
方法。内部会创建 JavaBBinder
对象。
继续看parcel的 writeStrongBinder(IBinder binder)
:
2.3.2 writeStrongBinder()
status_t Parcel::writeStrongBinder(const sp<IBinder>& val)
1135 { // val是binder对象, this是parcel对象,此时为写入
1136 return flatten_binder(ProcessState::self(), val, this);
1137 }
1138
status_t flatten_binder(const sp<ProcessState>& /*proc*/,
205 const sp<IBinder>& binder, Parcel* out)
206 {
207 flat_binder_object obj; // 构造无障碍 flat_binder_object对象
208
209 ...
216
217 if (binder != nullptr) {
218 BBinder *local = binder->localBinder();
219 if (!local) {
...
229 } else {
//本地binder,存入
230 if (local->isRequestingSid()) {
231 obj.flags |= FLAT_BINDER_FLAG_TXN_SECURITY_CTX;
232 }
233 obj.hdr.type = BINDER_TYPE_BINDER; // 类型为binder
234 obj.binder = reinterpret_cast<uintptr_t>(local->getWeakRefs()); //存入弱引用
// 把本地的binder对象存入到obj的cookies中
235 obj.cookie = reinterpret_cast<uintptr_t>(local);
236 }
237 } else {
238 obj.hdr.type = BINDER_TYPE_BINDER;
239 obj.binder = 0;
240 obj.cookie = 0;
241 }
242
243 return finish_flatten_binder(binder, obj, out);
244 }
245
构造一个 flat_binder_object
对象,赋值obj
的type、binder、coolkies
信息。其中cookies可认为就是 JavaBinder对象,它继承了BBinder对象。
2.3.3 finish_flatten_binder()
inline static status_t finish_flatten_binder(
199 const sp<IBinder>& /*binder*/, const flat_binder_object& flat, Parcel* out)
200 {
201 return out->writeObject(flat, false);
202 }
把flat
对象写入到Parcel
中。
至此,要发送的Parcel
对象的数据已经全部构造完毕。可以发送!
三、向服务发起请求
3.1 java层发起请求
mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0)
。
而 mRemote
就是 BinderProxy
。
3.1.1 BinderProxy的 transact()
public boolean transact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {
...
try { // native方法
return transactNative(code, data, reply, flags);
} finally {
...
}
}
- code:需要调用的方法编号。这里对应addService方法。
- data:Parcel容器对象。包含发送的数据
- reply: 返回接收数据的Parcel容器。
- flags:一般为0。
继续看jni方法:
transactNative()
根据jni注册表可知,对应的jni方法为 android_os_BinderProxy_transact
static const JNINativeMethod gBinderProxyMethods[] = {
1429 /* name, signature, funcPtr */
1430 {"pingBinder", "()Z", (void*)android_os_BinderProxy_pingBinder},
1431 {"isBinderAlive", "()Z", (void*)android_os_BinderProxy_isBinderAlive},
1432 {"getInterfaceDescriptor", "()Ljava/lang/String;", (void*)android_os_BinderProxy_getInterfaceDescriptor},
1433 {"transactNative", "(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z", (void*)android_os_BinderProxy_transact},
1434 {"linkToDeath", "(Landroid/os/IBinder$DeathRecipient;I)V", (void*)android_os_BinderProxy_linkToDeath},
1435 {"unlinkToDeath", "(Landroid/os/IBinder$DeathRecipient;I)Z", (void*)android_os_BinderProxy_unlinkToDeath},
1436 {"getNativeFinalizer", "()J", (void*)android_os_BinderProxy_getNativeFinalizer},
1437 };
继续深入 android_os_BinderProxy_transact():
static jboolean android_os_BinderProxy_transact(JNIEnv* env, jobject obj,
1280 jint code, jobject dataObj, jobject replyObj, jint flags) // throws RemoteException
1281 {
...
// 根据java的parcel得到c++ 层的parcel对象
Parcel* data = parcelForJavaObject(env, dataObj);
1288 if (data == NULL) {
1289 return JNI_FALSE;
1290 }
1291 Parcel* reply = parcelForJavaObject(env, replyObj);
1292 if (reply == NULL && replyObj != NULL) {
1293 return JNI_FALSE;
1294 }
// mObject 为BinderProxy对象,这里获取到mNative指向的BpBinder对象
// 因此,target指针指向的就是BpBinder对象
1296 IBinder* target = getBPNativeData(env, obj)->mObject.get();
1297 if (target == NULL) {
1298 jniThrowException(env, "java/lang/IllegalStateException", "Binder has been finalized!");
1299 return JNI_FALSE;
1300 }
...
// 调用BpBinder的transact方法
1319 status_t err = target->transact(code, *data, reply, flags);
1320 //if (reply) printf("Transact from Java code to %p received: ", target); reply->print();
....
1333
1334 signalExceptionForError(env, obj, err, true /*canThrowRemoteException*/, data->dataSize());
1335 return JNI_FALSE;
1336 }
target
指针指向的就是BpBinder
对象。因此,看BpBinder
的transact()
方法
3.2 BpBinder的transact()
BpBinder
的 transact
方法:
/frameworks/native/libs/binder/BpBinder.cpp
status_t BpBinder::transact(
211 uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
212 {
213 // Once a binder has died, it will never come back to life.
214 if (mAlive) {
//mHandle 是在BpBinder创建的时候目的进程的引用,这里为0.
215 status_t status = IPCThreadState::self()->transact(
216 mHandle, code, data, reply, flags);
217 if (status == DEAD_OBJECT) mAlive = 0;
218 return status;
219 }
220
221 return DEAD_OBJECT;
222 }
223
里面调用的是 IPCThreadState
单例对象来发起请求。 IPCThreadState
是每个线程
独有的单例对象。
mHandle
: 表示服务端进程的引用。这里为0
,对应 ServiceManager
进程。
查看它的transact方法:
3.2.1 IPCThreadState::transact()
status_t IPCThreadState::transact(int32_t handle,
651 uint32_t code, const Parcel& data,
652 Parcel* reply, uint32_t flags)
653 {
654 status_t err;
655
656 flags |= TF_ACCEPT_FDS;
657 ...
// 构造数据到mOut变量中
667 err = writeTransactionData(BC_TRANSACTION, flags, handle, code, data, nullptr);
668
669 if (err != NO_ERROR) {
//调用出错
670 if (reply) reply->setError(err);
671 return (mLastError = err);
672 }
673
674 if ((flags & TF_ONE_WAY) == 0) {
675 if (UNLIKELY(mCallRestriction != ProcessState::CallRestriction::NONE)) {
676 if (mCallRestriction == ProcessState::CallRestriction::ERROR_IF_NOT_ONEWAY) {
677 ALOGE("Process making non-oneway call but is restricted.");
678 CallStack::logStack("non-oneway call", CallStack::getCurrent(10).get(),
679 ANDROID_LOG_ERROR);
680 } else /* FATAL_IF_NOT_ONEWAY */ {
681 LOG_ALWAYS_FATAL("Process may not make oneway calls.");
682 }
683 }
684
685 #if 0
686 if (code == 4) { // relayout
687 ALOGI(">>>>>> CALLING transaction 4");
688 } else {
689 ALOGI(">>>>>> CALLING transaction %d", code);
690 }
691 #endif
692 if (reply) {
// 循环得去数据,等待返回
693 err = waitForResponse(reply);
694 } else {
695 Parcel fakeReply;
696 err = waitForResponse(&fakeReply);
697 }
706
713 } else {
714 err = waitForResponse(nullptr, nullptr);
715 }
716
717 return err;
718 }
3.2.2 writeTransactionData()
构造数据到mOut变量中,mOut
变量是parcel
类型。
status_t IPCThreadState::writeTransactionData(int32_t cmd, uint32_t binderFlags,
1026 int32_t handle, uint32_t code, const Parcel& data, status_t* statusBuffer)
1027 {
// 构造binder_transaction_data 对象
1028 binder_transaction_data tr;
1029
1030 tr.target.ptr = 0; /* Don't pass uninitialized stack data to a remote process */
1031 tr.target.handle = handle; // 目标进程
1032 tr.code = code; //想要调用哪个函数
1033 tr.flags = binderFlags;
1034 tr.cookie = 0;
1035 tr.sender_pid = 0;
1036 tr.sender_euid = 0;
1037
1038 const status_t err = data.errorCheck();
1039 if (err == NO_ERROR) {
1040 tr.data_size = data.ipcDataSize();
1041 tr.data.ptr.buffer = data.ipcData();
1042 tr.offsets_size = data.ipcObjectsCount()*sizeof(binder_size_t);
1043 tr.data.ptr.offsets = data.ipcObjects();
1044 } else if (statusBuffer) {
1045 tr.flags |= TF_STATUS_CODE;
1046 *statusBuffer = err;
1047 tr.data_size = sizeof(status_t);
1048 tr.data.ptr.buffer = reinterpret_cast<uintptr_t>(statusBuffer);
1049 tr.offsets_size = 0;
1050 tr.data.ptr.offsets = 0;
1051 } else {
1052 return (mLastError = err);
1053 }
1054
1055 mOut.writeInt32(cmd);
//把tr写入parcel容器中
1056 mOut.write(&tr, sizeof(tr));
1057
1058 return NO_ERROR;
1059 }
创建 binder_transaction_data
tr
对象,把handle、code、以及data
写入tr,然后在把tr写入到 mOut
中。
这里只是把数据写到 mOut
中,那在哪里执行真正的发送逻辑呢?
3.2.3 waitForResponse()
status_t IPCThreadState::waitForResponse(Parcel *reply, status_t *acquireResult)
832 {
833 uint32_t cmd;
834 int32_t err;
835
836 while (1) {
//内部不断的通过 ioctl读写驱动数据
837 if ((err=talkWithDriver()) < NO_ERROR) break;
838 err = mIn.errorCheck();
839 if (err < NO_ERROR) break;
840 if (mIn.dataAvail() == 0) continue;
841 //得到cmd
842 cmd = (uint32_t)mIn.readInt32();
843
844
848
849 switch (cmd) {
850 case BR_TRANSACTION_COMPLETE: ...
854 case BR_DEAD_REPLY: ...
858 case BR_FAILED_REPLY: ...
862 case BR_ACQUIRE_RESULT:...
871 case BR_REPLY: //得到返回值code
872 {
873 binder_transaction_data tr; //构造tr
874 err = mIn.read(&tr, sizeof(tr));
875 ALOG_ASSERT(err == NO_ERROR, "Not enough command data for brREPLY");
876 if (err != NO_ERROR) goto finish;
877
878 if (reply) {
879 if ((tr.flags & TF_STATUS_CODE) == 0) {
// 把数据转换,填充到reply中
880 reply->ipcSetDataReference(
881 reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),
882 tr.data_size,
883 reinterpret_cast<const binder_size_t*>(tr.data.ptr.offsets),
884 tr.offsets_size/sizeof(binder_size_t),
885 freeBuffer, this);
886 } else {
887 err = *reinterpret_cast<const status_t*>(tr.data.ptr.buffer);
888 freeBuffer(nullptr,
889 reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),
890 tr.data_size,
891 reinterpret_cast<const binder_size_t*>(tr.data.ptr.offsets),
892 tr.offsets_size/sizeof(binder_size_t), this);
893 }
894 } else {
895 freeBuffer(nullptr,
896 reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),
897 tr.data_size,
898 reinterpret_cast<const binder_size_t*>(tr.data.ptr.offsets),
899 tr.offsets_size/sizeof(binder_size_t), this);
900 continue;
901 }
902 }
903 goto finish;
904
905 default:
906 err = executeCommand(cmd);
907 if (err != NO_ERROR) goto finish;
908 break;
909 }
910 }
911
912 finish:
913 if (err != NO_ERROR) {
914 if (acquireResult) *acquireResult = err;
915 if (reply) reply->setError(err);
916 mLastError = err;
917 }
918
919 return err;
920 }
不断循环向驱动读写数据,如果没有数据,则休眠挂起。等待reply返回。
不过我们要明白一个知识,想要与驱动通信必须要经过三步:
1. open binder
驱动
2. mmap()
完成虚拟地址与内核物理内存的映射
3. 不断的读取数据
目前只是第三步,那么前面两步是在哪里开始的呢? 其实是在ProcessState的构造函数中
ProcessState::ProcessState(const char *driver)
425 : mDriverName(String8(driver))
426 , mDriverFD(open_driver(driver)) // 内部调用了open函数,打开驱动。
427 , mVMStart(MAP_FAILED)
428 , mThreadCountLock(PTHREAD_MUTEX_INITIALIZER)
429 , mThreadCountDecrement(PTHREAD_COND_INITIALIZER)
430 , mExecutingThreadsCount(0)
431 , mMaxThreads(DEFAULT_MAX_BINDER_THREADS)
432 , mStarvationStartTimeMs(0)
433 , mManagesContexts(false)
434 , mBinderContextCheckFunc(nullptr)
435 , mBinderContextUserData(nullptr)
436 , mThreadPoolStarted(false)
437 , mThreadPoolSeq(1)
438 , mCallRestriction(CallRestriction::NONE)
439 {
440 if (mDriverFD >= 0) {
441 // mmap the binder, providing a chunk of virtual address space to receive transactions.
// mmap 映射虚拟地址到内核物理空间
442 mVMStart = mmap(nullptr, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0);
443 if (mVMStart == MAP_FAILED) {
444 // *sigh*
445 ALOGE("Using %s failed: unable to mmap transaction memory.\n", mDriverName.c_str());
446 close(mDriverFD);
447 mDriverFD = -1;
448 mDriverName.clear();
449 }
450 }
451
452 LOG_ALWAYS_FATAL_IF(mDriverFD < 0, "Binder driver could not be opened. Terminating.");
453 }
内部调用了open
函数,打开驱动。并且把驱动的fd``赋值给mDriverFD变量
。
经历过以上三个步骤,作为客户端
终于可以向ServiceManager
注册服务了。
四、binder驱动层
驱动层具体过程可参考第二篇文章,这里就不具体展开。只列出关键步骤:
4.1 Server到ServiceManager过程
- Server端进入内核态,创建
binder_proc
对象对应该server进程。创建binder_node
节点对应某个服务(HelloService),加入proc里面的nodes
红黑树中。 - binder_node节点包含关键信息:
cookies
:对应c++层的BBinder对象。proc:对应server进程。 - 根据handle=0,找到binder大管家ServiceManager进程。创建
binder_ref
对象。其中node节点指向server的binder_node
对象,分配desc
。 - 把数据加入到ServiceManager的binder_proc
todo链表
中。唤醒serviceManager进程,自己进入休眠。 - ServiceManager被唤醒,把desc和解析后的数据返回到用户空间。处理数据,进入到
svcmgr_handler
函数 - addService逻辑,创建
svcinfo
:包含desc和name。加入到infos链表 - 把结果写回到server进程
4.2 ServiceManager写回到Server过程
- 调用
binder_send_reply()
binder_write()
通过ioctl()
向驱动发送数据。- 通过返回栈找到
server
进程。把数据加入到server
进程binder_proc
的todo
链表中 - 唤醒
server
进程,SM进入休眠 server
进程被唤醒,开始从驱动中读取数据,进入用户空间,然后回调case BR_REPLY:
逻辑。
五、ServiceManager添加服务过程
在ServiceManager进程启动分析的时候,我们知道做了三件事情:
- open 驱动,完成mmap映射
- 设置全局binder管理者,handle值对应为0
- 开启loop循环,不断的从驱动中读取数据,处理数据
尤其是在第三步的解析过程中,如果有数据,则会回调svcmgr_handler函数。 然后根据code来调用对应的函数,如 addService、 getService等。
int svcmgr_handler(struct binder_state *bs,
struct binder_transaction_data_secctx *txn_secctx,
struct binder_io *msg,
struct binder_io *reply)
{
struct svcinfo *si; // 每个service都用svcinfo结构体表示
...
switch(txn->code) {
case SVC_MGR_GET_SERVICE: //终于看到熟悉的东西了, getService
case SVC_MGR_CHECK_SERVICE:
s = bio_get_string16(msg, &len);
if (s == NULL) {
return -1;
}
handle = do_find_service(s, len, txn->sender_euid, txn->sender_pid,
(const char*) txn_secctx->secctx);
if (!handle)
break;
bio_put_ref(reply, handle);
return 0;
case SVC_MGR_ADD_SERVICE: // addService
s = bio_get_string16(msg, &len);
if (s == NULL) {
return -1;
}
handle = bio_get_ref(msg);
allow_isolated = bio_get_uint32(msg) ? 1 : 0;
dumpsys_priority = bio_get_uint32(msg);
//会创建servinfo 加入infos链表中
if (do_add_service(bs, s, len, handle, txn->sender_euid, allow_isolated, dumpsys_priority,
txn->sender_pid, (const char*) txn_secctx->secctx))
return -1;
break;
case SVC_MGR_LIST_SERVICES: { // listServices
uint32_t n = bio_get_uint32(msg);
uint32_t req_dumpsys_priority = bio_get_uint32(msg);
if (!svc_can_list(txn->sender_pid, (const char*) txn_secctx->secctx, txn->sender_euid)) {
ALOGE("list_service() uid=%d - PERMISSION DENIED\n",
txn->sender_euid);
return -1;
}
si = svclist;
// walk through the list of services n times skipping services that
// do not support the requested priority
while (si) {
if (si->dumpsys_priority & req_dumpsys_priority) {
if (n == 0) break;
n--;
}
si = si->next;
}
if (si) {
bio_put_string16(reply, si->name);
return 0;
}
return -1;
}
default:
ALOGE("unknown code %d\n", txn->code);
return -1;
}
bio_put_uint32(reply, 0);
return 0;
}
至此,addService
执行完毕。 那么什么时候返回数据呢?
ServiceManager的binder_parse()
在addService()
之后,会执行 binder_send_reply()
返回数据:
void binder_send_reply(struct binder_state *bs,
196 struct binder_io *reply,
197 binder_uintptr_t buffer_to_free,
198 int status)
199 {
200 struct {
201 uint32_t cmd_free;
202 binder_uintptr_t buffer;
203 uint32_t cmd_reply;
204 struct binder_transaction_data txn;
205 } __attribute__((packed)) data;
206
207 data.cmd_free = BC_FREE_BUFFER;
208 data.buffer = buffer_to_free;
209 data.cmd_reply = BC_REPLY; //构造返回的cmd
210 data.txn.target.ptr = 0;
211 data.txn.cookie = 0;
212 data.txn.code = 0;
213 if (status) {
214 data.txn.flags = TF_STATUS_CODE;
215 data.txn.data_size = sizeof(int);
216 data.txn.offsets_size = 0;
217 data.txn.data.ptr.buffer = (uintptr_t)&status;
218 data.txn.data.ptr.offsets = 0;
219 } else {
220 data.txn.flags = 0;
221 data.txn.data_size = reply->data - reply->data0;
222 data.txn.offsets_size = ((char*) reply->offs) - ((char*) reply->offs0);
223 data.txn.data.ptr.buffer = (uintptr_t)reply->data0;
224 data.txn.data.ptr.offsets = (uintptr_t)reply->offs0;
225 }
//内部也是通过ioctl发给驱动层
226 binder_write(bs, &data, sizeof(data));
227 }
构造返回数据,通过驱动向server
进程发送,server
就会收到reply
的返回。
六、问题
- Java层的
ServiceManager
和native的ServiceManager
是什么关系?
答: 二者没有什么必然联系,都是对ServiceManager大管家
的的封装。底层都是通过
ProcessState::self()->getContextObject(NULL)
来获得指向ServiceManager
的BpBinder
对象来完成与ServiceManager
的通信。
此外,就算没有java
层的封装对象。native
层也是可以单独完成binder
通信的。因此,java
层的binder
实际上是对native
层的封装,真正的实现逻辑基本在native
层。