| 本文參考一個朋友兼同事ShadowN1ght的文章客戶端到驅(qū)動通信流程;用一個簡單的案例闡述了完整的Binder 通信過程;
 Binder之于Android,猶如電話之于人類,都是用于傳遞信息;
 寫這篇文章前我醞釀了很久,不知道該何從下筆,文章寫了又刪,刪了又寫,因為始終感覺寫的有點(diǎn)雜,一不注意就丟失了主線;現(xiàn)在通過跟蹤一個完整的Binder調(diào)用來說明Binder IPC的過程——PowerManger調(diào)用isScreenOn();
 方案設(shè)計:Binder通信涉及APP層,framework層,Kernel層,雖然涉及的東西比較雜,但是都是代碼實現(xiàn)的,既然如此,我們都可以通過增加調(diào)試Log信息來跟蹤這個流程,本文的思路就是如此; 為了更好的理解 Binder 通信過程,你最好有一套完整的 Android 源碼,再配上一個代碼搜索神器 OpenGrok,如果你沒有 android源碼,不想自己搭建 OpenGrok 服務(wù)器,這里推薦一個公開的 Android Code In OpenGrok,只不過由于網(wǎng)速問題你可能得多花點(diǎn)時間等待;
 1. APP——> frameworkimport com.example.bindservice.ProcessInfo;
 public class MainActivity extends AppCompatActivity {
 String TAG = "Bindertest MainActivity";
 
 @Override
 protected void onCreate(Bundle savedInstanceState) {
 super.onCreate(savedInstanceState);
 setContentView(R.layout.activity_main);
 findViewById(R.id.mybtn).setOnClickListener(new View.OnClickListener() {
 @Override
 public void onClick(View v) {
 ProcessInfo processInfo = new ProcessInfo();
 processInfo.nativeSelfCall();
 PowerManager powerManager = (PowerManager) getSystemService(Context.POWER_SERVICE);
 Log.e(TAG,"App begin nativeCall");
 boolean bool = powerManager.isScreenOn();
 Log.e(TAG,"App end nativeCall");
 Log.e(TAG,"" + bool);
 }
 });
 }
 }
Binder過程很簡單,就是調(diào)用了powerManager.isScreenOn();//Binder Call 代碼;processInfo.nativeSelfCall()是自己添加的JNI,目的是向Binder Kernel中傳遞cmd,然后在Binder Kernel中根據(jù)cmd獲取到應(yīng)用進(jìn)程ID,過濾Log;這里暫時不說;
 /frameworks/base/core/java/android/os/PowerManager.java
 @Deprecatedpublic boolean isScreenOn() {
 return isInteractive();
 }
 
 public boolean isInteractive() {
 try {
 return mService.isInteractive();
 } catch (RemoteException e) {
 return false;
 }
 }
PowerManger.java中的isScreenOn最終會調(diào)用 mService.isInteractive();這里的mService是什么呢???
 mServicefinal IPowerManager mService;/**
 * {@hide}
 */
 public PowerManager(Context context, IPowerManager service, Handler handler) {
 mContext = context;
 mService = service;//mService初始化是在PowerManager構(gòu)造方法中
 mHandler = handler;
 }
mService 是IPowerManager 對象;這里根據(jù)名字我們就知道IPowerManager是通過AIDL生成的代碼,可以在Android Studio中查找;找到:out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/core/java/android/os/IPowerManager.java
 ------> IPowerManager.java——>Proxy@Override
 public boolean isInteractive() throws android.os.RemoteException {
 android.os.Parcel _data = android.os.Parcel.obtain();
 android.os.Parcel _reply = android.os.Parcel.obtain();
 boolean _result;
 try {
 _data.writeInterfaceToken(DESCRIPTOR);
 mRemote.transact(Stub.TRANSACTION_isInteractive, _data, _reply, 0);//核心核心
 _reply.readException();
 _result = (0 != _reply.readInt());
 } finally {
 _reply.recycle();
 _data.recycle();
 }
 return _result;
 }
_data用于包裝客戶端數(shù)據(jù),_reply用于從服務(wù)端獲取數(shù)據(jù),mRemote是android.os.IBinder對象,DESCRIPTOR標(biāo)識了IPowerManager ,DESCRIPTOR = "android.os.IPowerManager";TRANSACTION_isInteractive 是方法號,TRANSACTION_isInteractive = (android.os.IBinder.FIRST_CALL_TRANSACTION + 11);_result即我們應(yīng)用層得到的值,這里是根據(jù)reply獲取的值來賦值的;
 這里我重點(diǎn)看看mRemote; ------> IPowerManager.java——>Proxy......
 private static class Proxy implements android.os.IPowerManager {
 private android.os.IBinder mRemote;
 
 Proxy(android.os.IBinder remote) {
 mRemote = remote;//賦值
 }
 
 @Override
 public android.os.IBinder asBinder() {
 return mRemote;
 }
 ......
 }
這里mRemote是在Proxy的構(gòu)造方法中被調(diào)用,那Proxy是在什么地方調(diào)用呢? ------>IPowerManager.java——>Stub/**
 * Cast an IBinder object into an android.os.IPowerManager interface,
 * generating a proxy if needed.
 */
 public static android.os.IPowerManager asInterface(android.os.IBinder obj) {
 if ((obj == null)) {
 return null;
 }
 android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
 if (((iin != null) && (iin instanceof android.os.IPowerManager))) {
 return ((android.os.IPowerManager) iin);
 }
 return new android.os.IPowerManager.Stub.Proxy(obj);//調(diào)用Proxy構(gòu)造函數(shù)
 }
這里IPowerManger.Stub asInterface在什么地方調(diào)用呢?asInterface返回的對象是IPowerManager對象;在Android Studio 查看該方法在那些地方被調(diào)用,你會發(fā)現(xiàn)有很對,但是我相信你會特別在ContextImpl的;/frameworks/base/core/java/android/app/ContextImpl.java
 ------> ContextImpl.javaregisterService(POWER_SERVICE, new ServiceFetcher() {
 public Object createService(ContextImpl ctx) {
 IBinder b = ServiceManager.getService(POWER_SERVICE);
 IPowerManager service = IPowerManager.Stub.asInterface(b);
 //調(diào)用IPowerManger.stub.asInterface,傳入的IBinder對象參數(shù)是從
 //ServiceManager.getService(POWER_SERVICE)獲取的
 if (service == null) {
 Log.wtf(TAG, "Failed to get power manager service.");
 }
 return new PowerManager(ctx.getOuterContext(),
 service, ctx.mMainThread.getHandler());//返回PowerManager對象,
 //這里的service就是PowerManger類中的mService,
 //我們在應(yīng)用層調(diào)用的  (PowerManager) getSystemService(Context.POWER_SERVICE)
 //得到的powerManger對象就是這里返回的new PowerManager,這部分代碼跟著邏輯就能看到;
 }});
看到registerService方法,我相信很多人都很熟悉,這里的service就是PowerManger類中的mService,應(yīng)用層調(diào)用的  (PowerManager) getSystemService(Context.POWER_SERVICE)得到的powerManger對象
 就是這里返回的new PowerManager,順著Activity的getSystemService方法的邏輯看就會清楚;
 PowerManager中的mService就是這里的service,通過 IPowerManager.Stub.asInterface(b)獲得;
 IBinder b = ServiceManager.getService(POWER_SERVICE);IPowerManager service = IPowerManager.Stub.asInterface(b);
 這里真正開始接觸IBiner,這里做個標(biāo)記,等會可能會回頭再來看,
 這里調(diào)用 IPowerManager.Stub.asInterface(b)的IBinder b參數(shù)是從ServiceManager.getService(POWER_SERVICE)獲取的,那這個IBinder b值是什么呢???(我這里先透露一下,IBinder b是一個BinderProxy對象)
 /frameworks/base/core/java/android/os/ServiceManager.java
 ------> ServiceManager.java/**
 * Returns a reference to a service with the given name.
 *
 * @param name the name of the service to get
 * @return a reference to the service, or <code>null</code> if the service doesn't exist
 */
 public static IBinder getService(String name) {
 try {
 IBinder service = sCache.get(name);
 if (service != null) {
 return service;
 } else {
 return getIServiceManager().getService(name);//核心核心
 }
 } catch (RemoteException e) {
 Log.e(TAG, "error in getService", e);
 }
 return null;
 }
這里先從緩存中獲取IBinder,緩存中沒有則調(diào)用getIServiceManager().getService(name)獲取; ------> ServiceManager.javaprivate static IServiceManager getIServiceManager() {
 if (sServiceManager != null) {
 return sServiceManager;
 }
 // Find the service manager
 sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject());//核心核心
 return sServiceManager;
 }
/frameworks/base/core/java/android/os/ServiceManagerNative.javaServiceManagerNative.asInterface(BinderInternal.getContextObject())的參數(shù)為BinderInternal.getContextObject();
 ------> ServiceManagerNative.javastatic public IServiceManager asInterface(IBinder obj)
 {
 if (obj == null) {
 return null;
 }
 IServiceManager in =
 (IServiceManager)obj.queryLocalInterface(descriptor);//如果沒有真正的跨進(jìn)程通信,則從這里返回
 //Binder 類有實現(xiàn),BinderProxy沒有實現(xiàn)queryLocalInterface方法;
 if (in != null) {
 return in;//判斷是否是真的跨進(jìn)程,比如應(yīng)用內(nèi)部實現(xiàn)service,就沒真正跨進(jìn)程,從這里返回;
 }
 return new ServiceManagerProxy(obj);//核心核心核心,跨進(jìn)程
 }
使用OpenGrok搜索"implements IBinder",會發(fā)現(xiàn)Binder.java 文件中class Binder和class BinderProxy兩個類實現(xiàn)了IBinder;此處我先不確定queryLocalInterface是否是調(diào)用的這里;我們先確定
 static public IServiceManager asInterface(IBinder obj)的參數(shù)IBinder obj;obj是ServiceManager.java中調(diào)用ServiceManagerNative.asInterface(BinderInternal.getContextObject())傳遞過來的,所以
 obj = BinderInternal.getContextObject();我們看看ServiceManagerProxy的構(gòu)造方法,會發(fā)現(xiàn)ServiceManagerProxy中
 public ServiceManagerProxy(IBinder remote) {
 mRemote = remote;
 },即BinderInternal.getContextObject()的返回值將賦值給mRemote
 /frameworks/base/core/java/com/android/internal/os/BinderInternal.java
 ------> BinderInternal.java
public static final native IBinder getContextObject();這里使用JNI來獲取IBinder對象;根據(jù)Android JNI命名規(guī)則,我們知道getContextObject方法在android_util_Binder.cpp中實現(xiàn);
 ------> android_util_Binder.cppstatic const JNINativeMethod gBinderInternalMethods[] = {
 /* name, signature, funcPtr */
 { "getContextObject", "()Landroid/os/IBinder;", (void*)android_os_BinderInternal_getContextObject },
 { "joinThreadPool", "()V", (void*)android_os_BinderInternal_joinThreadPool },
 { "disableBackgroundScheduling", "(Z)V", (void*)android_os_BinderInternal_disableBackgroundScheduling },
 { "handleGc", "()V", (void*)android_os_BinderInternal_handleGc }
 };
 
 static jobject android_os_BinderInternal_getContextObject(JNIEnv* env, jobject clazz)
 {
 sp<IBinder> b = ProcessState::self()->getContextObject(NULL);//ProcessState采用單列,整個應(yīng)用只有一個實例
 return javaObjectForIBinder(env, b);//將native binder轉(zhuǎn)換為Java Binder對象,這里返回BinderProxy對象,下面會說明;
 }
這里通過 ProcessState創(chuàng)建native IBinder對象;再調(diào)用javaObjectForIBinder將native Binder對象轉(zhuǎn)換成Java層的Binder對象;
 ------> ProcessState.cppsp<IBinder> ProcessState::getContextObject(const sp<IBinder>& /*caller*/)//caller 上面?zhèn)鬟f的值為null
 {
 return getStrongProxyForHandle(0);//參數(shù)為0
 }
 
 sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle)
 {
 sp<IBinder> result;
 
 AutoMutex _l(mLock);
 
 handle_entry* e = lookupHandleLocked(handle);//此時handle=0
 
 if (e != NULL) {
 // We need to create a new BpBinder if there isn't currently one, OR we
 // are unable to acquire a weak reference on this current one.  See comment
 // in getWeakProxyForHandle() for more info about this.
 IBinder* b = e->binder;
 if (b == NULL || !e->refs->attemptIncWeak(this)) {
 if (handle == 0) {
 // Special case for context manager...
 // The context manager is the only object for which we create
 // a BpBinder proxy without already holding a reference.
 // Perform a dummy transaction to ensure the context manager
 // is registered before we create the first local reference
 // to it (which will occur when creating the BpBinder).
 // If a local reference is created for the BpBinder when the
 // context manager is not present, the driver will fail to
 // provide a reference to the context manager, but the
 // driver API does not return status.
 //
 // Note that this is not race-free if the context manager
 // dies while this code runs.
 //
 // TODO: add a driver API to wait for context manager, or
 // stop special casing handle 0 for context manager and add
 // a driver API to get a handle to the context manager with
 // proper reference counting.
 
 Parcel data;
 status_t status = IPCThreadState::self()->transact(
 0, IBinder::PING_TRANSACTION, data, NULL, 0);
 if (status == DEAD_OBJECT)
 return NULL;
 }
 
 b = new BpBinder(handle); //創(chuàng)建BpBinder,即b = new BpBinder(0);
 e->binder = b;
 if (b) e->refs = b->getWeakRefs();
 result = b;//用new BpBinder(0)給result賦值,最后返回result
 } else {
 // This little bit of nastyness is to allow us to add a primary
 // reference to the remote proxy when this team doesn't have one
 // but another team is sending the handle to us.
 result.force_set(b);
 e->refs->decWeak(this);
 }
 }
 
 return result;//返回new BpBinder(0)
 }
sp<IBinder> b = ProcessState::self()->getContextObject(NULL)返回的是new BpBinder(0);返回到android_os_BinderInternal_getContextObject方法中,接下來會調(diào)用javaObjectForIBinder方法;
 ------> javaObjectForIBinderjobject javaObjectForIBinder(JNIEnv* env, const sp<IBinder>& val)
 {
 if (val == NULL) return NULL;
 
 if (val->checkSubclass(&gBinderOffsets)) {
 // One of our own!
 jobject object = static_cast<JavaBBinder*>(val.get())->object();
 LOGDEATH("objectForBinder %p: it's our own %p!\n", val.get(), object);
 return object;
 }
 
 // For the rest of the function we will hold this lock, to serialize
 // looking/creation of Java proxies for native Binder proxies.
 AutoMutex _l(mProxyLock);
 
 // Someone else's...  do we know about it?
 jobject object = (jobject)val->findObject(&gBinderProxyOffsets);//gBinderProxyOffsets很重要,
 //gBinderProxyOffets在int_register_android_os_BinderProxy中初始化,指向Java層的BinderProxy(核心核心核心),
 //int_register_android_os_BinderProxy在register_android_os_Binder中調(diào)用,register_android_os_Binder
 //在開機(jī)過程中AndroidRuntime.startReg方法中被調(diào)用;
 if (object != NULL) {
 jobject res = jniGetReferent(env, object);
 if (res != NULL) {
 ALOGV("objectForBinder %p: found existing %p!\n", val.get(), res);
 return res;
 }
 LOGDEATH("Proxy object %p of IBinder %p no longer in working set!!!", object, val.get());
 android_atomic_dec(&gNumProxyRefs);
 val->detachObject(&gBinderProxyOffsets);
 env->DeleteGlobalRef(object);
 }
 
 object = env->NewObject(gBinderProxyOffsets.mClass, gBinderProxyOffsets.mConstructor);
 //gBinderProxyOffsets.mClass指向BinderProxy class,gBinderProxyOffsets.mConstructor指向BinderProxy構(gòu)造方法;
 if (object != NULL) {
 LOGDEATH("objectForBinder %p: created new proxy %p !\n", val.get(), object);
 // The proxy holds a reference to the native object.
 env->SetLongField(object, gBinderProxyOffsets.mObject, (jlong)val.get());//val是BpBinder,
 //這里利用JNI 調(diào)用java將讀到的BpBinder 對象val存入BinderProxy的mObject變量中
 val->incStrong((void*)javaObjectForIBinder);
 // The native object needs to hold a weak reference back to the
 // proxy, so we can retrieve the same proxy if it is still active.
 jobject refObject = env->NewGlobalRef(
 env->GetObjectField(object, gBinderProxyOffsets.mSelf));
 val->attachObject(&gBinderProxyOffsets, refObject,
 jnienv_to_javavm(env), proxy_cleanup);
 // Also remember the death recipients registered on this proxy
 sp<DeathRecipientList> drl = new DeathRecipientList;
 drl->incStrong((void*)javaObjectForIBinder);
 env->SetLongField(object, gBinderProxyOffsets.mOrgue, reinterpret_cast<jlong>(drl.get()));
 // Note that a new object reference has been created.
 android_atomic_inc(&gNumProxyRefs);
 incRefsCreated(env);
 }
 return object;//返回Java BinderProxy對象
 }
所以前面BinderInternal.java 中 getContextObject()方法會返回一個BinderProxy對象;并將獲取到的BpBinder對象存入Java層BinderProxy類的mObject變量中;
 是不是有點(diǎn)蒙圈了,休息休息休息休息一下下,你還記得我們的這個BinderProxy返回到什么地方嗎?哈哈,反正我是記得;因為我都記下來了,哈哈;BinderProxy是BinderInternal.getContextObject()返回的,即這個BinderProxy將作為ServiceManagerNative.java 中static public IServiceManager asInterface(IBinder obj)方法的參數(shù)IBinder obj;如果Binder通信確實跨進(jìn)程ServiceManagerNative.java的asInterface方法將返回new ServiceManagerProxy(BinderProxy binderProxy)
 到這里我想使用goto 語句了,調(diào)到我想去的地方,還記得我們是從什么時候開始分析這個IBinder對象的嗎?
 ------> ContextImpl.javaregisterService(POWER_SERVICE, new ServiceFetcher() {
 public Object createService(ContextImpl ctx) {
 IBinder b = ServiceManager.getService(POWER_SERVICE);
 IPowerManager service = IPowerManager.Stub.asInterface(b);
 //調(diào)用IPowerManger.stub.asInterface,傳入的IBinder對象參數(shù)是從
 //ServiceManager.getService(POWER_SERVICE)獲取的
 if (service == null) {
 Log.wtf(TAG, "Failed to get power manager service.");
 }
 return new PowerManager(ctx.getOuterContext(),
 service, ctx.mMainThread.getHandler());//返回PowerManager對象,
 //這里的service就是PowerManger類中的mService,
 //我們在應(yīng)用層調(diào)用的  (PowerManager) getSystemService(Context.POWER_SERVICE)
 //得到的powerManger對象就是這里返回的new PowerManager,這部分代碼跟著邏輯就能看到;
 }});
我們重新回到ContextImpl.java 中開始分析, IBinder b = ServiceManager.getService(POWER_SERVICE);其實就是ServiceManagerProxy的getService方法,ServiceManagerProxy類中mRemote的值就是BinderProxy,所以 IBinder b = ServiceManager.getService(POWER_SERVICE)最終會調(diào)用ServiceManagerProxy的方法;
 ------> ServiceMangerNative.java ——>ServiceManagerProxypublic IBinder getService(String name) throws RemoteException {
 Parcel data = Parcel.obtain();
 Parcel reply = Parcel.obtain();
 data.writeInterfaceToken(IServiceManager.descriptor);
 data.writeString(name);
 mRemote.transact(GET_SERVICE_TRANSACTION, data, reply, 0);
 IBinder binder = reply.readStrongBinder();//這里返回IBinder對象
 reply.recycle();
 data.recycle();
 return binder;
 }
IPowerManager service = IPowerManager.Stub.asInterface(b),這里asInterface方法的參數(shù)b就是ServiceManagerProxy類中g(shù)etService返回的IBinder,這里是通過reply.readStrongBinder();reply是一個Parcel;
 /frameworks/base/core/java/android/os/Parcel.java
 ------> Parcel.java
 public final IBinder readStrongBinder() {
   return nativeReadStrongBinder(mNativePtr);//JNI方法
 }我們根據(jù)Android JNI命名規(guī)則,可以到android_os_Parcel.cpp中查看nativeReadStrongBinder方法:
 ------> android_os_Parcel.cppstatic jobject android_os_Parcel_readStrongBinder(JNIEnv* env, jclass clazz, jlong nativePtr)
 {
 Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
 if (parcel != NULL) {
 return javaObjectForIBinder(env, parcel->readStrongBinder());//這個方法前面有說過,
 //根據(jù)parcel->readStrongBinder()的值返回,
 //提前透露一下,parcel->readStrongBinder()返回的值是BpBinder對象
 }
 return NULL;
 }
parcel->readStrongBinder() ------> Parcel.cppsp<IBinder> Parcel::readStrongBinder() const
 {
 sp<IBinder> val;
 unflatten_binder(ProcessState::self(), *this, &val);//核心,解析Binder
 return val;
 }
 ------> Parcel.cpp
 status_t unflatten_binder(const sp<ProcessState>& proc,
 const Parcel& in, sp<IBinder>* out)
 {
 const flat_binder_object* flat = in.readObject(false);
 
 if (flat) {
 switch (flat->type) {
 case BINDER_TYPE_BINDER://Binder實體
 *out = reinterpret_cast<IBinder*>(flat->cookie);
 return finish_unflatten_binder(NULL, *flat, in);
 case BINDER_TYPE_HANDLE://Binder 引用,我們這里是通過ServiceManager.getService獲取的服務(wù)代理,即Binder引用
 *out = proc->getStrongProxyForHandle(flat->handle);//核心核心,是不是很熟悉呢???
 //該方法返回一個new BpBinder(flat->handle),這里的new BpBinder將會傳遞給readStringBinder方法的&val然后直接返回;
 return finish_unflatten_binder(
 static_cast<BpBinder*>(out->get()), *flat, in);//類型轉(zhuǎn)換
 }
 }
 return BAD_TYPE;
 }
Parcel.cpp中的readStrongBinder方法將返回一個new BpBinder()對象,接著繼續(xù)返回給android_os_Parcel.cpp的android_os_Parcel_readStrongBinder,在android_os_Parcel_readStrongBinder中調(diào)用javaObjectForIBinder方法將這個BpBinder對象轉(zhuǎn)換為Java 層的BinderProxy對象返回,javaObjectForIBinder還會調(diào)用SetLongField將獲取到的BpBinder對象保存到j(luò)ava層BinderProxy類的mObject變量中,所以呢所以呢???ServiceManagerProxy的getService方法將返回一個BinderProxy對象
 
 再回到ContextImpl中,你將會明白所有參數(shù):IBinder b = ServiceManager.getService(POWER_SERVICE)    //IBinder b其實就是一個BinderProxy對象,是不是和前面透露的保持一致,其實我都怕透露出錯,哈哈
 IPowerManager service = IPowerManager.Stub.asInterface(b);//這里我們知道asInterface(b)最終會將參數(shù)b傳遞到IPowerManager.Stub.Proxy的構(gòu)造函數(shù),將BinderProxy對象賦值給IPowerManager.Stub.Proxy的mRemote;IPowerManager.Stub.asInterface(b)調(diào)用最終會返回IPowerManager.Stub.Proxy對象;
 有沒有真相大白的感覺,困擾你的mRemote終于驗明正身了;又沒有很興奮激動,反正我還是比較激動的。
 小結(jié):本小結(jié)主要闡述了Binder通信從APP層到framework層的通信過程,即PowerManager powerManager = (PowerManager) getSystemService(Context.POWER_SERVICE)
 boolean bool = powerManager.isScreenOn()=========>mService.isInteractive(mService是IPowerManager對象)=========>mRemote.transact(Stub.TRANSACTION_isInteractive, _data, _reply, 0)(mRemote是一個BinderProxy對象)=========>BinderProxy.transact;下一篇文章將從BinderProxy開始分析
 |