《深入理解Android(卷2)》笔记 6.第二章 深入理解Java Binder
2013-01-04 23:43 ...平..淡... 阅读(1616) 评论(0) 编辑 收藏 举报只学习了这一章中与Binder有关的部分。因为这一部分涉及java层的Binder机制,所以就直接来学习下。
先整体总结下:
1.AMS如何将自己注册到SM中
(1)AMS.setSystemProcess--->SM.addService--->getIServiceManager().addService() (2)分析getIServiceManager函数 getIServiceManager--->SMN.asInterface(BinderInternal.getContextObject()) (3)分析getContextObject函数 getContextObject--->android_os_BinderInternal_getContextObject---> (a)sp<IBinder> b = ProcessState::self()->getContextObject(NULL) (b)return javaObjectForIBinder(env,b) (4)分析b中的javaObjectForIBinder函数,该函数返回值是BinderProxy对象。 作用是创建了一个BinderProxy对象,并且将其和native层的一个BpBinder对象挂钩。 (2)回到SMN.asInterface(BinderInternal.getContextObject()),此时该语句变成了SMN.asInterface(BinderProxy对象) 分析SMN.asInterface函数:SMN.asInterface--->根据传递过来的参数,创建了一个ServiceManagerProxy对象并返回 (1)因此getIServiceManager().addService()变成了ServiceManagerProxy.addService()---> (a)data.writeStrongBinder (b)mRemote.transact--->从Java的BinderProxy对象中得到之前已创建好的native层的BpBinder对象-->通过BpBinder对象,将请求发送给ServiceManager完成注册。
1的延伸:在1中的AMS.setSystemProcess函数中,AMS创建了一个AMS对象,此时会执行构造函数。
(1)在初始化AMS服务时,因为ActivityManagerService继承自ActivityManagerNative,而ActivityManagerNative继承自Binder,又实现了IActivityManager接口,所以先来看下基类的构造函数。 Binder的构造函数中,有一个init函数。init函数-->android_os_Binder_init函数-->创建了JavaBBinderHolder对象,并将该对象保存在Java Binder对象的mObject成员中。这样完成了Java层的Binder对象和native层的JavaBBinderHolder对象的关联。 (2)分析JavaBBinderHolder类 JavaBBinderHolder.get函数--->new JavaBBinder(env,obj)--->创建了一个JavaBBinder对象,其中obj是Java层的Binder对象。 此时,构造函数分析结束~~ (3)现在,跳转到1的(1)中的(a)data.writeStrongBinder函数--->android_os_Parcel_WriteStrongBinder--->parcel->writeStrongBinder(ibinderForJavaObject(env,obj)) (a)ibinderForJavaObject(env,obj)---> 如果obj是Binder,则先获得JavaBBinderHolder对象,再调用JavaBBinderHolder.get函数。get函数会返回一个JavaBBinder对象。/ 如果obj是BinderProxy,则返回native的BpBinder对象。
2.ActivityManagerService如何响应请求
Binder客户端发送请求给Binder驱动,然后驱动调用JavaBBinder.onTransact--->Binder.java::execTransact--->调用子类的onTransact--->AMN.onTransact--->举个例子:如果switch(code)的结果是START_ACTIVITY_TRANSACTION,则调用startActivity函数启动activity
接下来开始详细分析~~~
知识点1:Java层Binder架构分析
1.Binder架构总览
(1) 系统定义了IBinder接口和DeathRecipient接口。
(2) Binder类和BinderProxy类分别实现了IBinder接口。其中,
(2.1) Binder类作为服务端的Bn的代表;
(2.2) BinderProxy类作为客户端Bp的代表。
(3) BinderInternal类仅供Binder架构使用。它内部有一个GcWatch类,专门用于处理和Binder架构相关的垃圾回收。
(4) Java层同样提供了一个承载通信数据的Parcel类。
ps: IBinder接口中有一个FLAG_ONEWAY的整型变量。一般情况下,当客户端利用Binder机制发起一个跨进程的函数调用时,客户端一般会阻塞,直到服务器返回结果。但是如果设置了FLAG_ONEWAY标志,则客户端只要把请求发送到Binder驱动即可返回,无须等待,这是一种非阻塞方式。在Native层中涉及的Binder调用基本上都是阻塞的,但是在java层的framework中,使用FLAG_ONEWAY的情况非常多。
2.初始化Java层的Binder框架
Java层Binder系统最终还是借助Natvive层的Binder系统开展工作,所以使用前,需要先建立它们之间的这种关系。
在Java初创时期,系统会提前注册一些JNI函数,其中有一个函数(android_util_Binder.cpp::register_android_os_Binder)专门负责搭建Java Binder和Native Binder的交互关系。该函数是在AndroidRuntime.cpp中被调用的:在gRegJNI[]数组中:REG_JNI(register_android_os_Binder), 因此,java世界初创时,该函数会被提前注册。
代码如下:
int register_android_os_Binder(JNIEnv* env) { //a.初始化Java Binder类和Native层的关系 if (int_register_android_os_Binder(env) < 0) return -1; //b.初始化Java BinderInternal类和Native层的关系 if (int_register_android_os_BinderInternal(env) < 0) return -1; //c.初始化Java BinderProxy类和Native层的关系 if (int_register_android_os_BinderProxy(env) < 0) return -1; //d.初始化Java Parcel类和Native层的关系 if (int_register_android_os_Parcel(env) < 0) return -1; return 0; }
a. Binder类的初始化
分析int_register_android_os_Binder函数
static int int_register_android_os_Binder(JNIEnv* env) { jclass clazz; clazz = env->FindClass(kBinderPathName); LOG_FATAL_IF(clazz == NULL, "Unable to find class android.os.Binder"); //gBinderOffsets是一个静态类对象,它专门保存Binder类的一些在JNI层中使用的信息,如成员函数execTransact的methodID,Binder类中数据成员mObject的fieldID。 gBinderOffsets.mClass = (jclass) env->NewGlobalRef(clazz); gBinderOffsets.mExecTransact = env->GetMethodID(clazz, "execTransact", "(IIII)Z"); assert(gBinderOffsets.mExecTransact); gBinderOffsets.mObject = env->GetFieldID(clazz, "mObject", "I"); assert(gBinderOffsets.mObject); //注册Binder类中native函数的实现 return AndroidRuntime::registerNativeMethods( env, kBinderPathName, gBinderMethods, NELEM(gBinderMethods)); }
分析代码可知,gBinderOffsets对象保存了和Binder类相关的某些在JNI层中使用的信息。
b. BinderInternal类的初始化
分析int_register_android_os_BinderInternal函数
static int int_register_android_os_BinderInternal(JNIEnv* env) { jclass clazz; //根据BinderInternal的全路径名找到代表该类的jclass对象,全路径名为”com/android/internal/os/BinderInternal” clazz = env->FindClass(kBinderInternalPathName); LOG_FATAL_IF(clazz == NULL, "Unable to find class com.android.internal.os.BinderInternal"); // gBinderInternalOffsets也是一个静态类对象,它专门保存BinderInternal类的一些信息。 gBinderInternalOffsets.mClass = (jclass) env->NewGlobalRef(clazz); gBinderInternalOffsets.mForceGc = env->GetStaticMethodID(clazz, "forceBinderGc", "()V"); assert(gBinderInternalOffsets.mForceGc); //注册Binder类中native函数的实现 return AndroidRuntime::registerNativeMethods( env, kBinderInternalPathName, gBinderInternalMethods, NELEM(gBinderInternalMethods)); }
以上Binder类和BinderInternal类的初始化工作类似,包括以下两个方面:
(1) 获取一些有用的methodID和fieldID。这表明JNI层一定会向上调用Java层的函数。
(2) 注册相关类中native函数的实现。
c. BinderProxy类的初始化
分析int_register_android_os_BinderProxy函数
static int int_register_android_os_BinderProxy(JNIEnv* env) { jclass clazz; clazz = env->FindClass("java/lang/ref/WeakReference"); LOG_FATAL_IF(clazz == NULL, "Unable to find class java.lang.ref.WeakReference"); // gWeakReferenceOffsets用来和WeakReference类打交道 gWeakReferenceOffsets.mClass = (jclass) env->NewGlobalRef(clazz); //获取WeakReference类get函数的methodID gWeakReferenceOffsets.mGet = env->GetMethodID(clazz, "get", "()Ljava/lang/Object;"); assert(gWeakReferenceOffsets.mGet); clazz = env->FindClass("java/lang/Error"); LOG_FATAL_IF(clazz == NULL, "Unable to find class java.lang.Error"); // gWeakReferenceOffsets用来和Error类打交道 gErrorOffsets.mClass = (jclass) env->NewGlobalRef(clazz); clazz = env->FindClass(kBinderProxyPathName); LOG_FATAL_IF(clazz == NULL, "Unable to find class android.os.BinderProxy"); // gWeakReferenceOffsets用来和BinderProxy类打交道 gBinderProxyOffsets.mClass = (jclass) env->NewGlobalRef(clazz); gBinderProxyOffsets.mConstructor = env->GetMethodID(clazz, "<init>", "()V"); assert(gBinderProxyOffsets.mConstructor); gBinderProxyOffsets.mSendDeathNotice = env->GetStaticMethodID(clazz, "sendDeathNotice", "(Landroid/os/IBinder$DeathRecipient;)V"); assert(gBinderProxyOffsets.mSendDeathNotice); gBinderProxyOffsets.mObject = env->GetFieldID(clazz, "mObject", "I"); assert(gBinderProxyOffsets.mObject); gBinderProxyOffsets.mSelf = env->GetFieldID(clazz, "mSelf", "Ljava/lang/ref/WeakReference;"); assert(gBinderProxyOffsets.mSelf); //注册BinderProxy native函数的实现 return AndroidRuntime::registerNativeMethods( env, kBinderProxyPathName, gBinderProxyMethods, NELEM(gBinderProxyMethods)); }
int_register_android_os_BinderProxy函数不仅初始化了BinderProxy类,还获取了WeakReference类和Error类的一些信息。由此可见,BinderProxy对象的生命周期会委托WeakReference来管理,因此JNI层会获取该类get函数的methodID。
小结:框架的初始化其实就是提前获取一些JNI层的信息。这样就能够节省每次使用时获取这些信息的时间。当Binder频繁调用时,这些时间累积起来是不容小觑的。
3.分析ActivityManagerService(AMS)
AMS是Android核心服务中的核心。通过分析AMS,揭示Java层Binder的工作原理。分两步:
(1) 首先分析AMS如何将自己注册到ServiceManager。
(2) 然后分析AMS如何响应客户端的Binder调用请求。
3.1分析ActivityManagerService.java::setSystemProcess函数,该函数是在systemServer.java中被调用。
public static void setSystemProcess() { try { ActivityManagerService m = mSelf; //将ActivityManagerService服务注册到ServiceManager中 ServiceManager.addService("activity", m); ServiceManager.addService("meminfo", new MemBinder(m)); if (MONITOR_CPU_USAGE) { ServiceManager.addService("cpuinfo", new CpuBinder(m)); } ServiceManager.addService("permission", new PermissionController(m)); ApplicationInfo info = mSelf.mContext.getPackageManager().getApplicationInfo( "android", STOCK_PM_FLAGS); mSystemThread.installSystemApplicationInfo(info); synchronized (mSelf) { ProcessRecord app = mSelf.newProcessRecordLocked( mSystemThread.getApplicationThread(), info, info.processName); app.persistent = true; app.pid = MY_PID; app.maxAdj = SYSTEM_ADJ; mSelf.mProcessNames.put(app.processName, app.info.uid, app); synchronized (mSelf.mPidsSelfLocked) { mSelf.mPidsSelfLocked.put(app.pid, app); } mSelf.updateLruProcessLocked(app, true, true); } } catch (PackageManager.NameNotFoundException e) { throw new RuntimeException( "Unable to find android system package", e); } }
3.2在SM中注册服务
(1) 创建ServiceManagerProxy
根据setSystemProcess函数中的ServiceManager.addService("activity", m);语句,进行分析:
public static void addService(String name, IBinder service){ try { getIServiceManager().addService(name, service); } catch (RemoteException e) { Log.e(TAG, "error in addService", e); } } //分析getIServiceManager函数 private static IServiceManager getIServiceManager() { if (sServiceManager != null) { return sServiceManager; } // Find the service manager sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject()); return sServiceManager; }
分析BinderInternal.getContextObject()函数,它是一个native函数,实现如下:
static jobject android_os_BinderInternal_getContextObject(JNIEnv* env, jobject clazz) { //b是一个BpBinder对象 sp<IBinder> b = ProcessState::self()->getContextObject(NULL); //由native对象创建一个Java return javaObjectForIBinder(env, b); }
分析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(); //printf("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? //事实上,在native层的BpBinder中有一个ObjectManager,它用来管理在native BpBinder上创建的Java BpBinder对象。 //findObject函数用来判断gBinderProxyOffsets是否已经保存在ObjectManager中。如果是,则删除旧的object。 jobject object = (jobject)val->findObject(&gBinderProxyOffsets); if (object != NULL) { jobject res = env->CallObjectMethod(object, gWeakReferenceOffsets.mGet); if (res != NULL) { LOGV("objectForBinder %p: found existing %p!\n", val.get(), res); return res; } LOGV("Proxy object %p of IBinder %p no longer in working set!!!", object, val.get()); android_atomic_dec(&gNumProxyRefs); val->detachObject(&gBinderProxyOffsets); env->DeleteGlobalRef(object); } //创建一个新的BinderProxy对象 object = env->NewObject(gBinderProxyOffsets.mClass, gBinderProxyOffsets.mConstructor); if (object != NULL) { LOGV("objectForBinder %p: created new %p!\n", val.get(), object); // The proxy holds a reference to the native object. env->SetIntField(object, gBinderProxyOffsets.mObject, (int)val.get()); val->incStrong(object); // 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)); //将这个新创建的BinderProxy对象注册(attach)到BpBinder的ObjectManager中。同时注册一个回收函数proxy_cleanup。当BinderProxy对象被撤销(detach)时,该函数会被调用,以释放一些资源。 val->attachObject(&gBinderProxyOffsets, refObject, jnienv_to_javavm(env), proxy_cleanup); // Note that a new object reference has been created. //增加该Proxy对象的引用计数 android_atomic_inc(&gNumProxyRefs); //用于垃圾回收。创建的Proxy对象一旦超过200个,该函数将调用BinderInternal类的forceGc做一次垃圾回收。 incRefsCreated(env); } return object; }
分析可知,BinderInternal.getContextObject函数完成了两个工作:
(a) 创建了一个Java层的BinderProxy对象。
(b) 通过JNI,该BinderProxy对象和一个native的BpBinder对象挂钩,而该BpBinder对象的通信目标就是ServiceManager。
因此,sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject());就变成了sServiceManager = ServiceManagerNative.asInterface(new BinderProxy);
回顾:在native层的Binder中,有一个interface_cast宏,而Java层中,定义了一个功能类似的函数,就是这个asInterface函数。
static public IServiceManager asInterface(IBinder obj) { if (obj == null) { return null; } IServiceManager in = (IServiceManager)obj.queryLocalInterface(descriptor); if (in != null) { return in; } //参数是obj,创建了一个ServiceManagerProxy对象 return new ServiceManagerProxy(obj); }
ServiceManagerProxy对象的各个业务函数会将相应请求打包后交给BpBinder对象,最终由BpBinder对象发送给Binder驱动完成一次通信。
因此getIServiceManager函数最终返回的值是ServiceManagerProxy对象。因此语句
getIServiceManager().addService(name, service);
最终将调用ServiceManagerProxy对象的addService函数进行处理。
(2) addService函数分析
public void addService(String name, IBinder service) throws RemoteException { Parcel data = Parcel.obtain(); Parcel reply = Parcel.obtain(); data.writeInterfaceToken(IServiceManager.descriptor); data.writeString(name); //稍后分析writeStrongBinder函数 data.writeStrongBinder(service); //mRemote其实就是BinderProxy对象,调用它的transact函数,将封装好的请求数据发送出去 mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0); reply.recycle(); data.recycle(); }
BinderProxy的transact函数是一个native函数,其实现代码如下:
static jboolean android_os_BinderProxy_transact(JNIEnv* env, jobject obj, jint code, jobject dataObj, jobject replyObj, jint flags) { if (dataObj == NULL) { jniThrowException(env, "java/lang/NullPointerException", NULL); return JNI_FALSE; } //从Java的Parcel对象中得到native的Parcel对象 Parcel* data = parcelForJavaObject(env, dataObj); if (data == NULL) { return JNI_FALSE; } //得到一个用于接收回复的Parcel对象 Parcel* reply = parcelForJavaObject(env, replyObj); if (reply == NULL && replyObj != NULL) { return JNI_FALSE; } //从Java的BinderProxy对象中得到之前已经创建好的那个native的BpBinder对象。 IBinder* target = (IBinder*) env->GetIntField(obj, gBinderProxyOffsets.mObject); if (target == NULL) { jniThrowException(env, "java/lang/IllegalStateException", "Binder has been finalized!"); return JNI_FALSE; } LOGV("Java code calling transact on %p in Java object %p with code %d\n", target, obj, code); // Only log the binder call duration for things on the Java-level main thread. // But if we don't const bool time_binder_calls = should_time_binder_calls(); int64_t start_millis; if (time_binder_calls) { start_millis = uptimeMillis(); } //通过native的BpBinder对象,将请求发送给ServiceManager status_t err = target->transact(code, *data, reply, flags); //if (reply) printf("Transact from Java code to %p received: ", target); reply->print(); if (time_binder_calls) { conditionally_log_binder_call(start_millis, target, code); } if (err == NO_ERROR) { return JNI_TRUE; } else if (err == UNKNOWN_TRANSACTION) { return JNI_FALSE; } signalExceptionForError(env, obj, err); return JNI_FALSE; }
通过上面的代码可知,Java层的Binder架构最终还是借助native的Binder架构进行通信。
之前在addService函数中说稍后分析writeStrongBinder函数,它很特别。先分析下面三者关系,writeStrongBinder函数将会在某一处被调用到。
(3) Binder、JavaBBinderHolder、JavaBBinder
ActivityManagerService类继承自ActivityManagerNative类,并实现了一些接口,其中和Binder架构相关的只有这个ActivityManagerNative类。原型如下:
public abstract class ActivityManagerNative extends Binder implements IActivityManager
再分析其构造函数:
public ActivityManagerNative() { attachInterface(this, descriptor); }
分析其父类Binder的构造函数:
public Binder() { init(); …… }
该init函数是native层的函数,实现代码如下:
static void android_os_Binder_init(JNIEnv* env, jobject clazz) { //创建了一个JavaBBinderHolder对象 JavaBBinderHolder* jbh = new JavaBBinderHolder(env, clazz); if (jbh == NULL) { jniThrowException(env, "java/lang/OutOfMemoryError", NULL); return; } LOGV("Java Binder %p: acquiring first ref on holder %p", clazz, jbh); jbh->incStrong(clazz); //将这个JavaBBinderHolder对象保存到Java Binder对象的mObject数据成员中 env->SetIntField(clazz, gBinderOffsets.mObject, (int)jbh); }
上面的代码分析得知,Java的Binder对象将和一个native的JavaBBinderHolder对象相关联。
JavaBBinderHolder类的定义:
class JavaBBinderHolder : public RefBase { public: JavaBBinderHolder(JNIEnv* env, jobject object) : mObject(object) { LOGV("Creating JavaBBinderHolder for Object %p\n", object); } ~JavaBBinderHolder() { LOGV("Destroying JavaBBinderHolder for Object %p\n", mObject); } sp<JavaBBinder> get(JNIEnv* env) { AutoMutex _l(mLock); sp<JavaBBinder> b = mBinder.promote(); if (b == NULL) { //创建了一个JavaBBinder对象,mObject实际上是Java层中的Binder对象 b = new JavaBBinder(env, mObject); mBinder = b; LOGV("Creating JavaBinder %p (refs %p) for Object %p, weakCount=%d\n", b.get(), b->getWeakRefs(), mObject, b->getWeakRefs()->getWeakCount()); } return b; } sp<JavaBBinder> getExisting() { AutoMutex _l(mLock); return mBinder.promote(); } private: Mutex mLock; jobject mObject; wp<JavaBBinder> mBinder; };
分析JavaBBinderHolder类的定义可知,JavaBBinderHolder类的get函数中创建了一个JavaBBinder对象,这个对象就是从BnBinder派生的。
问:那么get函数在哪里调用?
答:就是在writeStrongBinder函数中。
writeStrongBinder函数会做一个替换工作,函数代码如下:
static void android_os_Parcel_writeStrongBinder(JNIEnv* env, jobject clazz, jobject object) { Parcel* parcel = parcelForJavaObject(env, clazz); if (parcel != NULL) { //parcel是一个native的对象,writeStrongBinder函数的真正参数是ibinderForJavaObject的返回值 const status_t err = parcel->writeStrongBinder(ibinderForJavaObject(env, object)); if (err != NO_ERROR) { jniThrowException(env, "java/lang/OutOfMemoryError", NULL); } } }
分析ibinderForJavaObject函数
sp<IBinder> ibinderForJavaObject(JNIEnv* env, jobject obj) { if (obj == NULL) return NULL; //如果Java的obj是Binder类,则首先获得JavaBBinderHolder对象,然后调用它的get函数,而这个get函数将返回一个JavaBBinder if (env->IsInstanceOf(obj, gBinderOffsets.mClass)) { JavaBBinderHolder* jbh = (JavaBBinderHolder*) env->GetIntField(obj, gBinderOffsets.mObject); return jbh != NULL ? jbh->get(env) : NULL; } //如果obj是BinderProxy类,则返回native的BpBinder对象 if (env->IsInstanceOf(obj, gBinderProxyOffsets.mClass)) { return (IBinder*) env->GetIntField(obj, gBinderProxyOffsets.mObject); } LOGW("ibinderForJavaObject: %p is not a Binder object", obj); return NULL; }
分析可得,addService函数实际是将JavaBBinder对象(而不是AMS本身)添加到Parcel中,最终传递给Binder驱动。
其实,Java层中所有的Binder对应的都是这个JavaBBinder。
由图可知,
(a) Java层的Binder通过mObject执行一个native层的JavaBBinderHolder对象。
(b) native层的JavaBBinderHolder对象通过mBinder成员变量指向一个native的JavaBBinder对象
(c) native的JavaBBinder对象又通过mObject变量指向一个Java层的Binder对象。
问:为什么不直接从Binder指向JavaBBinder呢?
答:作者的解释是可能和回收机制有关,因为JavaBBinderHolder中的mBinder对象的类型被定义成弱引用wp了。
3.3 ActivityManagerService响应请求
区别:native层的Binder架构 vs Java层的Binder架构
(1) native层的Binder架构中:在代码中调用的是Binder类提供的接口,但其对象是一个实际的服务端对象,如MediaPlayerService对象、AudioFlinger对象。
(2) Java层的Binder架构中:JavaBBinder却是一个和业务完全无关的对象。这个对象如何实现不同业务呢?
当收到请求时,系统会调用JavaBBinder类的onTransact函数。代码如下:
virtual status_t onTransact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0) { JNIEnv* env = javavm_to_jnienv(mVM); LOGV("onTransact() on %p calling object %p in env %p vm %p\n", this, mObject, env, mVM); IPCThreadState* thread_state = IPCThreadState::self(); const int strict_policy_before = thread_state->getStrictModePolicy(); thread_state->setLastTransactionBinderFlags(flags); //调用Java层的Binder对象的execTransact函数 jboolean res = env->CallBooleanMethod(mObject, gBinderOffsets.mExecTransact, code, (int32_t)&data, (int32_t)reply, flags); jthrowable excep = env->ExceptionOccurred(); // Restore the Java binder thread's state if it changed while // processing a call (as it would if the Parcel's header had a // new policy mask and Parcel.enforceInterface() changed // it...) const int strict_policy_after = thread_state->getStrictModePolicy(); if (strict_policy_after != strict_policy_before) { // Our thread-local... thread_state->setStrictModePolicy(strict_policy_before); // And the Java-level thread-local... set_dalvik_blockguard_policy(env, strict_policy_before); } if (excep) { report_exception(env, excep, "*** Uncaught remote exception! " "(Exceptions are not yet supported across processes.)"); res = JNI_FALSE; /* clean up JNI local ref -- we don't return to Java code */ env->DeleteLocalRef(excep); } return res != JNI_FALSE ? NO_ERROR : UNKNOWN_TRANSACTION; }
因为分析的是AMS,所以上述代码中的mObject是AMS,现在调用它的execTransact函数:
private boolean execTransact(int code, int dataObj, int replyObj, int flags) { Parcel data = Parcel.obtain(dataObj); Parcel reply = Parcel.obtain(replyObj); // theoretically, we should call transact, which will call onTransact, // but all that does is rewind it, and we just got these from an IPC, // so we'll just call it directly. boolean res; try { //调用onTransact函数,派生类可重新实现此类,以完成业务功能 res = onTransact(code, data, reply, flags); } catch (RemoteException e) { reply.writeException(e); res = true; } catch (RuntimeException e) { reply.writeException(e); res = true; } reply.recycle(); data.recycle(); return res; } }
ActivityManagerNative类实现了onTransact函数,代码如下:
public boolean onTransact(int code, Parcel data, Parcel reply, int flags) throws RemoteException { switch (code) { case START_ACTIVITY_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); IBinder b = data.readStrongBinder(); IApplicationThread app = ApplicationThreadNative.asInterface(b); Intent intent = Intent.CREATOR.createFromParcel(data); String resolvedType = data.readString(); Uri[] grantedUriPermissions = data.createTypedArray(Uri.CREATOR); int grantedMode = data.readInt(); IBinder resultTo = data.readStrongBinder(); String resultWho = data.readString(); int requestCode = data.readInt(); boolean onlyIfNeeded = data.readInt() != 0; boolean debug = data.readInt() != 0; //再由AMS实现业务函数startActivity int result = startActivity(app, intent, resolvedType, grantedUriPermissions, grantedMode, resultTo, resultWho, requestCode, onlyIfNeeded, debug); reply.writeNoException(); reply.writeInt(result); return true; } case START_ACTIVITY_AND_WAIT_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); IBinder b = data.readStrongBinder(); IApplicationThread app = ApplicationThreadNative.asInterface(b); Intent intent = Intent.CREATOR.createFromParcel(data); String resolvedType = data.readString(); Uri[] grantedUriPermissions = data.createTypedArray(Uri.CREATOR); int grantedMode = data.readInt(); IBinder resultTo = data.readStrongBinder(); String resultWho = data.readString(); int requestCode = data.readInt(); boolean onlyIfNeeded = data.readInt() != 0; boolean debug = data.readInt() != 0; WaitResult result = startActivityAndWait(app, intent, resolvedType, grantedUriPermissions, grantedMode, resultTo, resultWho, requestCode, onlyIfNeeded, debug); reply.writeNoException(); result.writeToParcel(reply, 0); return true; } case START_ACTIVITY_WITH_CONFIG_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); IBinder b = data.readStrongBinder(); IApplicationThread app = ApplicationThreadNative.asInterface(b); Intent intent = Intent.CREATOR.createFromParcel(data); String resolvedType = data.readString(); Uri[] grantedUriPermissions = data.createTypedArray(Uri.CREATOR); int grantedMode = data.readInt(); IBinder resultTo = data.readStrongBinder(); String resultWho = data.readString(); int requestCode = data.readInt(); boolean onlyIfNeeded = data.readInt() != 0; boolean debug = data.readInt() != 0; Configuration config = Configuration.CREATOR.createFromParcel(data); int result = startActivityWithConfig(app, intent, resolvedType, grantedUriPermissions, grantedMode, resultTo, resultWho, requestCode, onlyIfNeeded, debug, config); reply.writeNoException(); reply.writeInt(result); return true; } case START_ACTIVITY_INTENT_SENDER_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); IBinder b = data.readStrongBinder(); IApplicationThread app = ApplicationThreadNative.asInterface(b); IntentSender intent = IntentSender.CREATOR.createFromParcel(data); Intent fillInIntent = null; if (data.readInt() != 0) { fillInIntent = Intent.CREATOR.createFromParcel(data); } String resolvedType = data.readString(); IBinder resultTo = data.readStrongBinder(); String resultWho = data.readString(); int requestCode = data.readInt(); int flagsMask = data.readInt(); int flagsValues = data.readInt(); int result = startActivityIntentSender(app, intent, fillInIntent, resolvedType, resultTo, resultWho, requestCode, flagsMask, flagsValues); reply.writeNoException(); reply.writeInt(result); return true; } case START_NEXT_MATCHING_ACTIVITY_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); IBinder callingActivity = data.readStrongBinder(); Intent intent = Intent.CREATOR.createFromParcel(data); boolean result = startNextMatchingActivity(callingActivity, intent); reply.writeNoException(); reply.writeInt(result ? 1 : 0); return true; } case FINISH_ACTIVITY_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); IBinder token = data.readStrongBinder(); Intent resultData = null; int resultCode = data.readInt(); if (data.readInt() != 0) { resultData = Intent.CREATOR.createFromParcel(data); } boolean res = finishActivity(token, resultCode, resultData); reply.writeNoException(); reply.writeInt(res ? 1 : 0); return true; } case FINISH_SUB_ACTIVITY_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); IBinder token = data.readStrongBinder(); String resultWho = data.readString(); int requestCode = data.readInt(); finishSubActivity(token, resultWho, requestCode); reply.writeNoException(); return true; } case WILL_ACTIVITY_BE_VISIBLE_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); IBinder token = data.readStrongBinder(); boolean res = willActivityBeVisible(token); reply.writeNoException(); reply.writeInt(res ? 1 : 0); return true; } case REGISTER_RECEIVER_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); IBinder b = data.readStrongBinder(); IApplicationThread app = b != null ? ApplicationThreadNative.asInterface(b) : null; b = data.readStrongBinder(); IIntentReceiver rec = b != null ? IIntentReceiver.Stub.asInterface(b) : null; IntentFilter filter = IntentFilter.CREATOR.createFromParcel(data); String perm = data.readString(); Intent intent = registerReceiver(app, rec, filter, perm); reply.writeNoException(); if (intent != null) { reply.writeInt(1); intent.writeToParcel(reply, 0); } else { reply.writeInt(0); } return true; } case UNREGISTER_RECEIVER_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); IBinder b = data.readStrongBinder(); if (b == null) { return true; } IIntentReceiver rec = IIntentReceiver.Stub.asInterface(b); unregisterReceiver(rec); reply.writeNoException(); return true; } case BROADCAST_INTENT_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); IBinder b = data.readStrongBinder(); IApplicationThread app = b != null ? ApplicationThreadNative.asInterface(b) : null; Intent intent = Intent.CREATOR.createFromParcel(data); String resolvedType = data.readString(); b = data.readStrongBinder(); IIntentReceiver resultTo = b != null ? IIntentReceiver.Stub.asInterface(b) : null; int resultCode = data.readInt(); String resultData = data.readString(); Bundle resultExtras = data.readBundle(); String perm = data.readString(); boolean serialized = data.readInt() != 0; boolean sticky = data.readInt() != 0; int res = broadcastIntent(app, intent, resolvedType, resultTo, resultCode, resultData, resultExtras, perm, serialized, sticky); reply.writeNoException(); reply.writeInt(res); return true; } case UNBROADCAST_INTENT_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); IBinder b = data.readStrongBinder(); IApplicationThread app = b != null ? ApplicationThreadNative.asInterface(b) : null; Intent intent = Intent.CREATOR.createFromParcel(data); unbroadcastIntent(app, intent); reply.writeNoException(); return true; } case FINISH_RECEIVER_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); IBinder who = data.readStrongBinder(); int resultCode = data.readInt(); String resultData = data.readString(); Bundle resultExtras = data.readBundle(); boolean resultAbort = data.readInt() != 0; if (who != null) { finishReceiver(who, resultCode, resultData, resultExtras, resultAbort); } reply.writeNoException(); return true; } case ATTACH_APPLICATION_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); IApplicationThread app = ApplicationThreadNative.asInterface( data.readStrongBinder()); if (app != null) { attachApplication(app); } reply.writeNoException(); return true; } case ACTIVITY_IDLE_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); IBinder token = data.readStrongBinder(); Configuration config = null; if (data.readInt() != 0) { config = Configuration.CREATOR.createFromParcel(data); } if (token != null) { activityIdle(token, config); } reply.writeNoException(); return true; } case ACTIVITY_PAUSED_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); IBinder token = data.readStrongBinder(); Bundle map = data.readBundle(); activityPaused(token, map); reply.writeNoException(); return true; } case ACTIVITY_STOPPED_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); IBinder token = data.readStrongBinder(); Bitmap thumbnail = data.readInt() != 0 ? Bitmap.CREATOR.createFromParcel(data) : null; CharSequence description = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(data); activityStopped(token, thumbnail, description); reply.writeNoException(); return true; } case ACTIVITY_DESTROYED_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); IBinder token = data.readStrongBinder(); activityDestroyed(token); reply.writeNoException(); return true; } case GET_CALLING_PACKAGE_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); IBinder token = data.readStrongBinder(); String res = token != null ? getCallingPackage(token) : null; reply.writeNoException(); reply.writeString(res); return true; } case GET_CALLING_ACTIVITY_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); IBinder token = data.readStrongBinder(); ComponentName cn = getCallingActivity(token); reply.writeNoException(); ComponentName.writeToParcel(cn, reply); return true; } case GET_TASKS_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); int maxNum = data.readInt(); int fl = data.readInt(); IBinder receiverBinder = data.readStrongBinder(); IThumbnailReceiver receiver = receiverBinder != null ? IThumbnailReceiver.Stub.asInterface(receiverBinder) : null; List list = getTasks(maxNum, fl, receiver); reply.writeNoException(); int N = list != null ? list.size() : -1; reply.writeInt(N); int i; for (i=0; i<N; i++) { ActivityManager.RunningTaskInfo info = (ActivityManager.RunningTaskInfo)list.get(i); info.writeToParcel(reply, 0); } return true; } case GET_RECENT_TASKS_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); int maxNum = data.readInt(); int fl = data.readInt(); List<ActivityManager.RecentTaskInfo> list = getRecentTasks(maxNum, fl); reply.writeNoException(); reply.writeTypedList(list); return true; } case GET_SERVICES_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); int maxNum = data.readInt(); int fl = data.readInt(); List list = getServices(maxNum, fl); reply.writeNoException(); int N = list != null ? list.size() : -1; reply.writeInt(N); int i; for (i=0; i<N; i++) { ActivityManager.RunningServiceInfo info = (ActivityManager.RunningServiceInfo)list.get(i); info.writeToParcel(reply, 0); } return true; } case GET_PROCESSES_IN_ERROR_STATE_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); List<ActivityManager.ProcessErrorStateInfo> list = getProcessesInErrorState(); reply.writeNoException(); reply.writeTypedList(list); return true; } case GET_RUNNING_APP_PROCESSES_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); List<ActivityManager.RunningAppProcessInfo> list = getRunningAppProcesses(); reply.writeNoException(); reply.writeTypedList(list); return true; } case GET_RUNNING_EXTERNAL_APPLICATIONS_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); List<ApplicationInfo> list = getRunningExternalApplications(); reply.writeNoException(); reply.writeTypedList(list); return true; } case MOVE_TASK_TO_FRONT_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); int task = data.readInt(); moveTaskToFront(task); reply.writeNoException(); return true; } case MOVE_TASK_TO_BACK_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); int task = data.readInt(); moveTaskToBack(task); reply.writeNoException(); return true; } case MOVE_ACTIVITY_TASK_TO_BACK_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); IBinder token = data.readStrongBinder(); boolean nonRoot = data.readInt() != 0; boolean res = moveActivityTaskToBack(token, nonRoot); reply.writeNoException(); reply.writeInt(res ? 1 : 0); return true; } case MOVE_TASK_BACKWARDS_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); int task = data.readInt(); moveTaskBackwards(task); reply.writeNoException(); return true; } case GET_TASK_FOR_ACTIVITY_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); IBinder token = data.readStrongBinder(); boolean onlyRoot = data.readInt() != 0; int res = token != null ? getTaskForActivity(token, onlyRoot) : -1; reply.writeNoException(); reply.writeInt(res); return true; } case FINISH_OTHER_INSTANCES_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); IBinder token = data.readStrongBinder(); ComponentName className = ComponentName.readFromParcel(data); finishOtherInstances(token, className); reply.writeNoException(); return true; } case REPORT_THUMBNAIL_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); IBinder token = data.readStrongBinder(); Bitmap thumbnail = data.readInt() != 0 ? Bitmap.CREATOR.createFromParcel(data) : null; CharSequence description = TextUtils.CHAR_SEQUENCE_CREATOR.createFromParcel(data); reportThumbnail(token, thumbnail, description); reply.writeNoException(); return true; } case GET_CONTENT_PROVIDER_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); IBinder b = data.readStrongBinder(); IApplicationThread app = ApplicationThreadNative.asInterface(b); String name = data.readString(); ContentProviderHolder cph = getContentProvider(app, name); reply.writeNoException(); if (cph != null) { reply.writeInt(1); cph.writeToParcel(reply, 0); } else { reply.writeInt(0); } return true; } case PUBLISH_CONTENT_PROVIDERS_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); IBinder b = data.readStrongBinder(); IApplicationThread app = ApplicationThreadNative.asInterface(b); ArrayList<ContentProviderHolder> providers = data.createTypedArrayList(ContentProviderHolder.CREATOR); publishContentProviders(app, providers); reply.writeNoException(); return true; } case REMOVE_CONTENT_PROVIDER_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); IBinder b = data.readStrongBinder(); IApplicationThread app = ApplicationThreadNative.asInterface(b); String name = data.readString(); removeContentProvider(app, name); reply.writeNoException(); return true; } case GET_RUNNING_SERVICE_CONTROL_PANEL_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); ComponentName comp = ComponentName.CREATOR.createFromParcel(data); PendingIntent pi = getRunningServiceControlPanel(comp); reply.writeNoException(); PendingIntent.writePendingIntentOrNullToParcel(pi, reply); return true; } case START_SERVICE_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); IBinder b = data.readStrongBinder(); IApplicationThread app = ApplicationThreadNative.asInterface(b); Intent service = Intent.CREATOR.createFromParcel(data); String resolvedType = data.readString(); ComponentName cn = startService(app, service, resolvedType); reply.writeNoException(); ComponentName.writeToParcel(cn, reply); return true; } case STOP_SERVICE_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); IBinder b = data.readStrongBinder(); IApplicationThread app = ApplicationThreadNative.asInterface(b); Intent service = Intent.CREATOR.createFromParcel(data); String resolvedType = data.readString(); int res = stopService(app, service, resolvedType); reply.writeNoException(); reply.writeInt(res); return true; } case STOP_SERVICE_TOKEN_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); ComponentName className = ComponentName.readFromParcel(data); IBinder token = data.readStrongBinder(); int startId = data.readInt(); boolean res = stopServiceToken(className, token, startId); reply.writeNoException(); reply.writeInt(res ? 1 : 0); return true; } case SET_SERVICE_FOREGROUND_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); ComponentName className = ComponentName.readFromParcel(data); IBinder token = data.readStrongBinder(); int id = data.readInt(); Notification notification = null; if (data.readInt() != 0) { notification = Notification.CREATOR.createFromParcel(data); } boolean removeNotification = data.readInt() != 0; setServiceForeground(className, token, id, notification, removeNotification); reply.writeNoException(); return true; } case BIND_SERVICE_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); IBinder b = data.readStrongBinder(); IApplicationThread app = ApplicationThreadNative.asInterface(b); IBinder token = data.readStrongBinder(); Intent service = Intent.CREATOR.createFromParcel(data); String resolvedType = data.readString(); b = data.readStrongBinder(); int fl = data.readInt(); IServiceConnection conn = IServiceConnection.Stub.asInterface(b); int res = bindService(app, token, service, resolvedType, conn, fl); reply.writeNoException(); reply.writeInt(res); return true; } case UNBIND_SERVICE_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); IBinder b = data.readStrongBinder(); IServiceConnection conn = IServiceConnection.Stub.asInterface(b); boolean res = unbindService(conn); reply.writeNoException(); reply.writeInt(res ? 1 : 0); return true; } case PUBLISH_SERVICE_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); IBinder token = data.readStrongBinder(); Intent intent = Intent.CREATOR.createFromParcel(data); IBinder service = data.readStrongBinder(); publishService(token, intent, service); reply.writeNoException(); return true; } case UNBIND_FINISHED_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); IBinder token = data.readStrongBinder(); Intent intent = Intent.CREATOR.createFromParcel(data); boolean doRebind = data.readInt() != 0; unbindFinished(token, intent, doRebind); reply.writeNoException(); return true; } case SERVICE_DONE_EXECUTING_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); IBinder token = data.readStrongBinder(); int type = data.readInt(); int startId = data.readInt(); int res = data.readInt(); serviceDoneExecuting(token, type, startId, res); reply.writeNoException(); return true; } case START_INSTRUMENTATION_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); ComponentName className = ComponentName.readFromParcel(data); String profileFile = data.readString(); int fl = data.readInt(); Bundle arguments = data.readBundle(); IBinder b = data.readStrongBinder(); IInstrumentationWatcher w = IInstrumentationWatcher.Stub.asInterface(b); boolean res = startInstrumentation(className, profileFile, fl, arguments, w); reply.writeNoException(); reply.writeInt(res ? 1 : 0); return true; } case FINISH_INSTRUMENTATION_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); IBinder b = data.readStrongBinder(); IApplicationThread app = ApplicationThreadNative.asInterface(b); int resultCode = data.readInt(); Bundle results = data.readBundle(); finishInstrumentation(app, resultCode, results); reply.writeNoException(); return true; } case GET_CONFIGURATION_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); Configuration config = getConfiguration(); reply.writeNoException(); config.writeToParcel(reply, 0); return true; } case UPDATE_CONFIGURATION_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); Configuration config = Configuration.CREATOR.createFromParcel(data); updateConfiguration(config); reply.writeNoException(); return true; } case SET_REQUESTED_ORIENTATION_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); IBinder token = data.readStrongBinder(); int requestedOrientation = data.readInt(); setRequestedOrientation(token, requestedOrientation); reply.writeNoException(); return true; } case GET_REQUESTED_ORIENTATION_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); IBinder token = data.readStrongBinder(); int req = getRequestedOrientation(token); reply.writeNoException(); reply.writeInt(req); return true; } case GET_ACTIVITY_CLASS_FOR_TOKEN_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); IBinder token = data.readStrongBinder(); ComponentName cn = getActivityClassForToken(token); reply.writeNoException(); ComponentName.writeToParcel(cn, reply); return true; } case GET_PACKAGE_FOR_TOKEN_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); IBinder token = data.readStrongBinder(); reply.writeNoException(); reply.writeString(getPackageForToken(token)); return true; } case GET_INTENT_SENDER_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); int type = data.readInt(); String packageName = data.readString(); IBinder token = data.readStrongBinder(); String resultWho = data.readString(); int requestCode = data.readInt(); Intent requestIntent = data.readInt() != 0 ? Intent.CREATOR.createFromParcel(data) : null; String requestResolvedType = data.readString(); int fl = data.readInt(); IIntentSender res = getIntentSender(type, packageName, token, resultWho, requestCode, requestIntent, requestResolvedType, fl); reply.writeNoException(); reply.writeStrongBinder(res != null ? res.asBinder() : null); return true; } case CANCEL_INTENT_SENDER_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); IIntentSender r = IIntentSender.Stub.asInterface( data.readStrongBinder()); cancelIntentSender(r); reply.writeNoException(); return true; } case GET_PACKAGE_FOR_INTENT_SENDER_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); IIntentSender r = IIntentSender.Stub.asInterface( data.readStrongBinder()); String res = getPackageForIntentSender(r); reply.writeNoException(); reply.writeString(res); return true; } case SET_PROCESS_LIMIT_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); int max = data.readInt(); setProcessLimit(max); reply.writeNoException(); return true; } case GET_PROCESS_LIMIT_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); int limit = getProcessLimit(); reply.writeNoException(); reply.writeInt(limit); return true; } case SET_PROCESS_FOREGROUND_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); IBinder token = data.readStrongBinder(); int pid = data.readInt(); boolean isForeground = data.readInt() != 0; setProcessForeground(token, pid, isForeground); reply.writeNoException(); return true; } case CHECK_PERMISSION_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); String perm = data.readString(); int pid = data.readInt(); int uid = data.readInt(); int res = checkPermission(perm, pid, uid); reply.writeNoException(); reply.writeInt(res); return true; } case CHECK_URI_PERMISSION_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); Uri uri = Uri.CREATOR.createFromParcel(data); int pid = data.readInt(); int uid = data.readInt(); int mode = data.readInt(); int res = checkUriPermission(uri, pid, uid, mode); reply.writeNoException(); reply.writeInt(res); return true; } case CLEAR_APP_DATA_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); String packageName = data.readString(); IPackageDataObserver observer = IPackageDataObserver.Stub.asInterface( data.readStrongBinder()); boolean res = clearApplicationUserData(packageName, observer); reply.writeNoException(); reply.writeInt(res ? 1 : 0); return true; } case GRANT_URI_PERMISSION_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); IBinder b = data.readStrongBinder(); IApplicationThread app = ApplicationThreadNative.asInterface(b); String targetPkg = data.readString(); Uri uri = Uri.CREATOR.createFromParcel(data); int mode = data.readInt(); grantUriPermission(app, targetPkg, uri, mode); reply.writeNoException(); return true; } case REVOKE_URI_PERMISSION_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); IBinder b = data.readStrongBinder(); IApplicationThread app = ApplicationThreadNative.asInterface(b); Uri uri = Uri.CREATOR.createFromParcel(data); int mode = data.readInt(); revokeUriPermission(app, uri, mode); reply.writeNoException(); return true; } case SHOW_WAITING_FOR_DEBUGGER_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); IBinder b = data.readStrongBinder(); IApplicationThread app = ApplicationThreadNative.asInterface(b); boolean waiting = data.readInt() != 0; showWaitingForDebugger(app, waiting); reply.writeNoException(); return true; } case GET_MEMORY_INFO_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); ActivityManager.MemoryInfo mi = new ActivityManager.MemoryInfo(); getMemoryInfo(mi); reply.writeNoException(); mi.writeToParcel(reply, 0); return true; } case UNHANDLED_BACK_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); unhandledBack(); reply.writeNoException(); return true; } case OPEN_CONTENT_URI_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); Uri uri = Uri.parse(data.readString()); ParcelFileDescriptor pfd = openContentUri(uri); reply.writeNoException(); if (pfd != null) { reply.writeInt(1); pfd.writeToParcel(reply, Parcelable.PARCELABLE_WRITE_RETURN_VALUE); } else { reply.writeInt(0); } return true; } case GOING_TO_SLEEP_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); goingToSleep(); reply.writeNoException(); return true; } case WAKING_UP_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); wakingUp(); reply.writeNoException(); return true; } case SET_DEBUG_APP_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); String pn = data.readString(); boolean wfd = data.readInt() != 0; boolean per = data.readInt() != 0; setDebugApp(pn, wfd, per); reply.writeNoException(); return true; } case SET_ALWAYS_FINISH_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); boolean enabled = data.readInt() != 0; setAlwaysFinish(enabled); reply.writeNoException(); return true; } case SET_ACTIVITY_CONTROLLER_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); IActivityController watcher = IActivityController.Stub.asInterface( data.readStrongBinder()); setActivityController(watcher); return true; } case ENTER_SAFE_MODE_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); enterSafeMode(); reply.writeNoException(); return true; } case NOTE_WAKEUP_ALARM_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); IIntentSender is = IIntentSender.Stub.asInterface( data.readStrongBinder()); noteWakeupAlarm(is); reply.writeNoException(); return true; } case KILL_PIDS_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); int[] pids = data.createIntArray(); String reason = data.readString(); boolean res = killPids(pids, reason); reply.writeNoException(); reply.writeInt(res ? 1 : 0); return true; } case START_RUNNING_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); String pkg = data.readString(); String cls = data.readString(); String action = data.readString(); String indata = data.readString(); startRunning(pkg, cls, action, indata); reply.writeNoException(); return true; } case HANDLE_APPLICATION_CRASH_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); IBinder app = data.readStrongBinder(); ApplicationErrorReport.CrashInfo ci = new ApplicationErrorReport.CrashInfo(data); handleApplicationCrash(app, ci); reply.writeNoException(); return true; } case HANDLE_APPLICATION_WTF_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); IBinder app = data.readStrongBinder(); String tag = data.readString(); ApplicationErrorReport.CrashInfo ci = new ApplicationErrorReport.CrashInfo(data); boolean res = handleApplicationWtf(app, tag, ci); reply.writeNoException(); reply.writeInt(res ? 1 : 0); return true; } case HANDLE_APPLICATION_STRICT_MODE_VIOLATION_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); IBinder app = data.readStrongBinder(); int violationMask = data.readInt(); StrictMode.ViolationInfo info = new StrictMode.ViolationInfo(data); handleApplicationStrictModeViolation(app, violationMask, info); reply.writeNoException(); return true; } case SIGNAL_PERSISTENT_PROCESSES_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); int sig = data.readInt(); signalPersistentProcesses(sig); reply.writeNoException(); return true; } case KILL_BACKGROUND_PROCESSES_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); String packageName = data.readString(); killBackgroundProcesses(packageName); reply.writeNoException(); return true; } case FORCE_STOP_PACKAGE_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); String packageName = data.readString(); forceStopPackage(packageName); reply.writeNoException(); return true; } case GET_DEVICE_CONFIGURATION_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); ConfigurationInfo config = getDeviceConfigurationInfo(); reply.writeNoException(); config.writeToParcel(reply, 0); return true; } case PROFILE_CONTROL_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); String process = data.readString(); boolean start = data.readInt() != 0; String path = data.readString(); ParcelFileDescriptor fd = data.readInt() != 0 ? data.readFileDescriptor() : null; boolean res = profileControl(process, start, path, fd); reply.writeNoException(); reply.writeInt(res ? 1 : 0); return true; } case SHUTDOWN_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); boolean res = shutdown(data.readInt()); reply.writeNoException(); reply.writeInt(res ? 1 : 0); return true; } case STOP_APP_SWITCHES_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); stopAppSwitches(); reply.writeNoException(); return true; } case RESUME_APP_SWITCHES_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); resumeAppSwitches(); reply.writeNoException(); return true; } case PEEK_SERVICE_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); Intent service = Intent.CREATOR.createFromParcel(data); String resolvedType = data.readString(); IBinder binder = peekService(service, resolvedType); reply.writeNoException(); reply.writeStrongBinder(binder); return true; } case START_BACKUP_AGENT_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); ApplicationInfo info = ApplicationInfo.CREATOR.createFromParcel(data); int backupRestoreMode = data.readInt(); boolean success = bindBackupAgent(info, backupRestoreMode); reply.writeNoException(); reply.writeInt(success ? 1 : 0); return true; } case BACKUP_AGENT_CREATED_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); String packageName = data.readString(); IBinder agent = data.readStrongBinder(); backupAgentCreated(packageName, agent); reply.writeNoException(); return true; } case UNBIND_BACKUP_AGENT_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); ApplicationInfo info = ApplicationInfo.CREATOR.createFromParcel(data); unbindBackupAgent(info); reply.writeNoException(); return true; } case REGISTER_ACTIVITY_WATCHER_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); IActivityWatcher watcher = IActivityWatcher.Stub.asInterface( data.readStrongBinder()); registerActivityWatcher(watcher); return true; } case UNREGISTER_ACTIVITY_WATCHER_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); IActivityWatcher watcher = IActivityWatcher.Stub.asInterface( data.readStrongBinder()); unregisterActivityWatcher(watcher); return true; } case START_ACTIVITY_IN_PACKAGE_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); int uid = data.readInt(); Intent intent = Intent.CREATOR.createFromParcel(data); String resolvedType = data.readString(); IBinder resultTo = data.readStrongBinder(); String resultWho = data.readString(); int requestCode = data.readInt(); boolean onlyIfNeeded = data.readInt() != 0; int result = startActivityInPackage(uid, intent, resolvedType, resultTo, resultWho, requestCode, onlyIfNeeded); reply.writeNoException(); reply.writeInt(result); return true; } case KILL_APPLICATION_WITH_UID_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); String pkg = data.readString(); int uid = data.readInt(); killApplicationWithUid(pkg, uid); reply.writeNoException(); return true; } case CLOSE_SYSTEM_DIALOGS_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); String reason = data.readString(); closeSystemDialogs(reason); reply.writeNoException(); return true; } case GET_PROCESS_MEMORY_INFO_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); int[] pids = data.createIntArray(); Debug.MemoryInfo[] res = getProcessMemoryInfo(pids); reply.writeNoException(); reply.writeTypedArray(res, Parcelable.PARCELABLE_WRITE_RETURN_VALUE); return true; } case KILL_APPLICATION_PROCESS_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); String processName = data.readString(); int uid = data.readInt(); killApplicationProcess(processName, uid); reply.writeNoException(); return true; } case OVERRIDE_PENDING_TRANSITION_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); IBinder token = data.readStrongBinder(); String packageName = data.readString(); int enterAnim = data.readInt(); int exitAnim = data.readInt(); overridePendingTransition(token, packageName, enterAnim, exitAnim); reply.writeNoException(); return true; } case IS_USER_A_MONKEY_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); boolean areThey = isUserAMonkey(); reply.writeNoException(); reply.writeInt(areThey ? 1 : 0); return true; } case FINISH_HEAVY_WEIGHT_APP_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); finishHeavyWeightApp(); reply.writeNoException(); return true; } case CRASH_APPLICATION_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); int uid = data.readInt(); int initialPid = data.readInt(); String packageName = data.readString(); String message = data.readString(); crashApplication(uid, initialPid, packageName, message); reply.writeNoException(); return true; } case GET_PROVIDER_MIME_TYPE_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); Uri uri = Uri.CREATOR.createFromParcel(data); String type = getProviderMimeType(uri); reply.writeNoException(); reply.writeString(type); return true; } case NEW_URI_PERMISSION_OWNER_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); String name = data.readString(); IBinder perm = newUriPermissionOwner(name); reply.writeNoException(); reply.writeStrongBinder(perm); return true; } case GRANT_URI_PERMISSION_FROM_OWNER_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); IBinder owner = data.readStrongBinder(); int fromUid = data.readInt(); String targetPkg = data.readString(); Uri uri = Uri.CREATOR.createFromParcel(data); int mode = data.readInt(); grantUriPermissionFromOwner(owner, fromUid, targetPkg, uri, mode); reply.writeNoException(); return true; } case REVOKE_URI_PERMISSION_FROM_OWNER_TRANSACTION: { data.enforceInterface(IActivityManager.descriptor); IBinder owner = data.readStrongBinder(); Uri uri = null; if (data.readInt() != 0) { Uri.CREATOR.createFromParcel(data); } int mode = data.readInt(); revokeUriPermissionFromOwner(owner, uri, mode); reply.writeNoException(); return true; } } return super.onTransact(code, data, reply, flags); }
可见,JavaBBinder只是一个传声筒,它本身不实现任何业务,它的主要工作是:
(1) 当它收到请求时,只是简单地调用它所绑定的Java层的Binder的execTransact函数。
(2) 该Binder对象的execTransact函数调用其子类实现的onTransact函数。
(3) 子类的onTransact函数将业务又派发给其他类完成。
更简单点说,JavaBBinder就是把来自客户端的请求从native层传递到Java层。
3.4 Java层Binder架构总结
(1) 对于代表客户端的BinderProxy来说,Java层的BinderProxy在native层对应一个BpBinder对象。凡是从Java层发出的请求,首先从Java层的BinderProxy传递到native层的BpBinder,继而由BpBinder将请求发送到Binder驱动。
(2) 对于代表服务端的Service来说,Java层的Binder在native层有一个JavaBBinder对象。
over~~