Binder解析之 addService() 过程理解(四)

880 阅读15分钟

背景

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();
    }
  1. 往parcel写入service的名字
  2. 往parcel写入service实例:HelloService对象
  3. 调用mRemote.transact()方法发送数据
  4. 回收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()

BinderInternalgetContextObject() :

    //返回IBinder 的是IServiceManager的实现 
 public static final native IBinder getContextObject();

是一个native方法,调用到jni层的方法,最终返回一个nativeBpBinder对象。

/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();
}
  1. 获取两个parcel容器,用来存储发送数据和接收返回数据
  2. 写入service name和对应的实例对象
  3. 开始发送

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层的BinderonTransact方法中去,这里暂不深究。

至此,我们得到了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  }

调用了 JavaBBinderHolderget()方法。内部会创建 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 对象,赋值objtype、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对象。因此,看BpBindertransact()方法

3.2 BpBinder的transact()

BpBindertransact 方法:

/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过程

  1. Server端进入内核态,创建binder_proc对象对应该server进程。创建binder_node节点对应某个服务(HelloService),加入proc里面的nodes红黑树中。
  2. binder_node节点包含关键信息:cookies:对应c++层的BBinder对象。proc:对应server进程。
  3. 根据handle=0,找到binder大管家ServiceManager进程。创建binder_ref对象。其中node节点指向server的binder_node对象,分配desc
  4. 把数据加入到ServiceManager的binder_proc todo链表中。唤醒serviceManager进程,自己进入休眠。
  5. ServiceManager被唤醒,把desc和解析后的数据返回到用户空间。处理数据,进入到 svcmgr_handler 函数
  6. addService逻辑,创建svcinfo:包含desc和name。加入到infos链表
  7. 把结果写回到server进程

4.2 ServiceManager写回到Server过程

  1. 调用 binder_send_reply()
  2. binder_write()通过ioctl()向驱动发送数据。
  3. 通过返回栈找到 server 进程。把数据加入到 server 进程binder_proctodo链表中
  4. 唤醒 server 进程,SM进入休眠
  5. server 进程被唤醒,开始从驱动中读取数据,进入用户空间,然后回调 case BR_REPLY:逻辑。

五、ServiceManager添加服务过程

在ServiceManager进程启动分析的时候,我们知道做了三件事情:

  1. open 驱动,完成mmap映射
  2. 设置全局binder管理者,handle值对应为0
  3. 开启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() 返回数据:

/frameworks/native/cmds/servicemanager/binder.c

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的返回。

六、问题

  1. Java层的ServiceManager和native的ServiceManager是什么关系?

答: 二者没有什么必然联系,都是对ServiceManager大管家的的封装。底层都是通过 ProcessState::self()->getContextObject(NULL)来获得指向ServiceManagerBpBinder对象来完成与ServiceManager的通信。

此外,就算没有java层的封装对象。native 层也是可以单独完成binder 通信的。因此,java层的binder实际上是对native层的封装,真正的实现逻辑基本在native层。

参考

gityuan.com/2015/11/14/…

blog.csdn.net/wangwei7088…