本文参考一个朋友兼同事ShadowN1ght的文章客户端到驱动通信流程;用一个简单的案例阐述了完整的Binder 通信过程;
Binder之于Android,犹如电话之于人类,都是用于传递信息;
写这篇文章前我酝酿了很久,不知道该何从下笔,文章写了又删,删了又写,因为始终感觉写的有点杂,一不注意就丢失了主线;现在通过跟踪一个完整的Binder调用来说明Binder IPC的过程——PowerManger调用isScreenOn();
方案设计:Binder通信涉及APP层,framework层,Kernel层,虽然涉及的东西比较杂,但是都是代码实现的,既然如此,我们都可以通过增加调试Log信息来跟踪这个流程,本文的思路就是如此; 为了更好的理解 Binder 通信过程,你最好有一套完整的 Android 源码,再配上一个代码搜索神器 OpenGrok,如果你没有 android源码,不想自己搭建 OpenGrok 服务器,这里推荐一个公开的 Android Code In OpenGrok,只不过由于网速问题你可能得多花点时间等待;
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过程很简单,就是调用了powerManager.isScreenOn();//Binder Call 代码; processInfo.nativeSelfCall()是自己添加的JNI,目的是向Binder Kernel中传递cmd,然后在Binder Kernel中根据cmd获取到应用进程ID,过滤Log;这里暂时不说;
/frameworks/base/core/java/android/os/PowerManager.java
@Deprecated public boolean isScreenOn() { return isInteractive(); }
public boolean isInteractive() { try { return mService.isInteractive(); } catch (RemoteException e) { return false; } } PowerManger.java中的isScreenOn最终会调用 mService.isInteractive();这里的mService是什么呢???
mServicefinal IPowerManager mService; /** * {@hide} */ public PowerManager(Context context, IPowerManager service, Handler handler) { mContext = context; mService = service;//mService初始化是在PowerManager构造方法中 mHandler = handler; } mService 是IPowerManager 对象;这里根据名字我们就知道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用于包装客户端数据,_reply用于从服务端获取数据,mRemote是android.os.IBinder对象,DESCRIPTOR标识了IPowerManager ,DESCRIPTOR = "android.os.IPowerManager";TRANSACTION_isInteractive 是方法号,TRANSACTION_isInteractive = (android.os.IBinder.FIRST_CALL_TRANSACTION + 11);_result即我们应用层得到的值,这里是根据reply获取的值来赋值的;
这里我重点看看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的构造方法中被调用,那Proxy是在什么地方调用呢? ------>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);//调用Proxy构造函数 } 这里IPowerManger.Stub asInterface在什么地方调用呢?asInterface返回的对象是IPowerManager对象;在Android Studio 查看该方法在那些地方被调用,你会发现有很对,但是我相信你会特别在ContextImpl的; /frameworks/base/core/java/android/app/ContextImpl.java
------> ContextImpl.java registerService(POWER_SERVICE, new ServiceFetcher() { public Object createService(ContextImpl ctx) { IBinder b = ServiceManager.getService(POWER_SERVICE); IPowerManager service = IPowerManager.Stub.asInterface(b); //调用IPowerManger.stub.asInterface,传入的IBinder对象参数是从 //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, //我们在应用层调用的 (PowerManager) getSystemService(Context.POWER_SERVICE) //得到的powerManger对象就是这里返回的new PowerManager,这部分代码跟着逻辑就能看到; }}); 看到registerService方法,我相信很多人都很熟悉,这里的service就是PowerManger类中的mService, 应用层调用的 (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,这里做个标记,等会可能会回头再来看,
这里调用 IPowerManager.Stub.asInterface(b)的IBinder b参数是从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,缓存中没有则调用getIServiceManager().getService(name)获取; ------> ServiceManager.java private 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.java ServiceManagerNative.asInterface(BinderInternal.getContextObject())的参数为BinderInternal.getContextObject();
------> ServiceManagerNative.java static public IServiceManager asInterface(IBinder obj) { if (obj == null) { return null; } IServiceManager in = (IServiceManager)obj.queryLocalInterface(descriptor);//如果没有真正的跨进程通信,则从这里返回 //Binder 类有实现,BinderProxy没有实现queryLocalInterface方法; if (in != null) { return in;//判断是否是真的跨进程,比如应用内部实现service,就没真正跨进程,从这里返回; } return new ServiceManagerProxy(obj);//核心核心核心,跨进程 } 使用OpenGrok搜索"implements IBinder",会发现Binder.java 文件中class Binder和 class BinderProxy两个类实现了IBinder;此处我先不确定queryLocalInterface是否是调用的这里;我们先确定 static public IServiceManager asInterface(IBinder obj)的参数IBinder obj;obj是ServiceManager.java中调用ServiceManagerNative.asInterface(BinderInternal.getContextObject())传递过来的,所以 obj = BinderInternal.getContextObject();我们看看ServiceManagerProxy的构造方法,会发现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对象;根据Android JNI命名规则,我们知道getContextObject方法在android_util_Binder.cpp中实现;
------> android_util_Binder.cpp static 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采用单列,整个应用只有一个实例 return javaObjectForIBinder(env, b);//将native binder转换为Java Binder对象,这里返回BinderProxy对象,下面会说明; } 这里通过 ProcessState创建native IBinder对象;再调用javaObjectForIBinder将native Binder对象转换成Java层的Binder对象;
------> ProcessState.cpp sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& /*caller*/)//caller 上面传递的值为null { return getStrongProxyForHandle(0);//参数为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); //创建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方法中,接下来会调用javaObjectForIBinder方法;
------> javaObjectForIBinder jobject 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中调用,register_android_os_Binder //在开机过程中AndroidRuntime.startReg方法中被调用; 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构造方法; 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 调用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变量中;
是不是有点蒙圈了,休息休息休息休息一下下,你还记得我们的这个BinderProxy返回到什么地方吗?哈哈,反正我是记得;因为我都记下来了,哈哈;BinderProxy是BinderInternal.getContextObject()返回的,即这个BinderProxy将作为ServiceManagerNative.java 中static public IServiceManager asInterface(IBinder obj)方法的参数IBinder obj;如果Binder通信确实跨进程ServiceManagerNative.java的asInterface方法将返回 new ServiceManagerProxy(BinderProxy binderProxy)
到这里我想使用goto 语句了,调到我想去的地方,还记得我们是从什么时候开始分析这个IBinder对象的吗?
------> ContextImpl.java registerService(POWER_SERVICE, new ServiceFetcher() { public Object createService(ContextImpl ctx) { IBinder b = ServiceManager.getService(POWER_SERVICE); IPowerManager service = IPowerManager.Stub.asInterface(b); //调用IPowerManger.stub.asInterface,传入的IBinder对象参数是从 //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, //我们在应用层调用的 (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)最终会调用ServiceManagerProxy的方法;
------> ServiceMangerNative.java ——>ServiceManagerProxy public 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方法的参数b就是ServiceManagerProxy类中getService返回的IBinder,这里是通过reply.readStrongBinder();reply是一个Parcel;
/frameworks/base/core/java/android/os/Parcel.java
------> Parcel.java
public final IBinder readStrongBinder() {
return nativeReadStrongBinder(mNativePtr);//JNI方法
} 我们根据Android JNI命名规则,可以到android_os_Parcel.cpp中查看nativeReadStrongBinder方法:
------> android_os_Parcel.cpp static 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());//这个方法前面有说过, //根据parcel->readStrongBinder()的值返回, //提前透露一下,parcel->readStrongBinder()返回的值是BpBinder对象 } return NULL; } parcel->readStrongBinder() ------> Parcel.cpp sp<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获取的服务代理,即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);//类型转换 } } return BAD_TYPE; } Parcel.cpp中的readStrongBinder方法将返回一个new BpBinder()对象,接着继续返回给android_os_Parcel.cpp的android_os_Parcel_readStrongBinder,在android_os_Parcel_readStrongBinder中调用javaObjectForIBinder方法将这个BpBinder对象转换为Java 层的BinderProxy对象返回,javaObjectForIBinder还会调用SetLongField将获取到的BpBinder对象保存到java层BinderProxy类的mObject变量中,所以呢所以呢???ServiceManagerProxy的getService方法将返回一个BinderProxy对象

再回到ContextImpl中,你将会明白所有参数: IBinder b = ServiceManager.getService(POWER_SERVICE) //IBinder b其实就是一个BinderProxy对象,是不是和前面透露的保持一致,其实我都怕透露出错,哈哈 IPowerManager service = IPowerManager.Stub.asInterface(b);//这里我们知道asInterface(b)最终会将参数b传递到IPowerManager.Stub.Proxy的构造函数,将BinderProxy对象赋值给IPowerManager.Stub.Proxy的mRemote;IPowerManager.Stub.asInterface(b)调用最终会返回IPowerManager.Stub.Proxy对象;
有没有真相大白的感觉,困扰你的mRemote终于验明正身了;又没有很兴奋激动,反正我还是比较激动的。
小结:本小结主要阐述了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开始分析
|