Java层中的binder和Native层的Binder在命名上尽量保持了一致,且Java层的Binder依托于Native层的Binder,其实就是对底层的Binder的真正实现的一个封装,最终还是通过JNI技术调用到C/C++代码的实现。。
本文我们从PKMS服务的初始化注册和PKMS的服务调用来学习Java层Binder的知识。
废话不说先上图:
这图是学完整个Java层Binder机制之后总结出来的,先放这里引导一下:
1. 从该图中我们发现Java层的Binder框架的确是依靠Native层的Binder框架的,通过JNI层使得两者联系在一起。Native Service中Client端会有一个BpBinder的引用,Service端会有一个BBinder的引用来实现通信;而Java层Service在Client端会有个BinderProxy的引用,在Service端会有个JavaBBinder对象的引用来实现通信。当然Java层的Binder机制是基于native层的,native层的binder机制是基于Binder驱动的。
2. 同Native层Service调用一样,Client端调用远程Service时需要向ServiceManager进程请求Service的代理对象,Service代理对象XXSeviceProxy是通过BinderProxy对象new出来的,而BinderProxy对象是由ServiceManager根据查询到的Service的Bp端的Binder代理BpBinder(handle)构造出来的,供java层Client端中的XXServiceProxy使用。Java层的BinderProxy与native层的BpBinder对应。
3. Java Service进行注册服务时将Java service的name和通过JNI层封装后service的JavaBBinder对象注册至service_manager中。
4. JavaService响应请求时,在Native层的IPCThreadState中调用BBinder的transact进而调用到JavaService的JavaBBinder的onTransact()函数,通过JNI层调用到Binder子类的IXXServiceInterface.stub中的onTransact()方法,在xx.stub类中的onTransact()方法中调用到指定的xx.stub的具体实现函数即XXService中的具体实现方法,从而完成Java Service的响应。
Android启动初期,系统会提前一个专门负责搭建Java Binder和Native Binder交互关系的函数,该函数是register_android_os_Binder,代码如下:
//frameworks/base/core/jni/android_util_Binder.cpp
int register_android_os_Binder(JNIEnv* env)
{
// 初始化Java Binder类和Native层的关系
if (int_register_android_os_Binder(env) < 0)
return -1;
// 初始化Java BinderInternal类和Native层的关系
if (int_register_android_os_BinderInternal(env) < 0)
return -1;
// 初始化Java BinderProxy类和Native层的关系
if (int_register_android_os_BinderProxy(env) < 0)
return -1;
......
return 0;
}
//java层的Binder类的全路径名
const char* const kBinderPathName = "android/os/Binder";
static int int_register_android_os_Binder(JNIEnv* env)
{
//找到java层的Binder类,保存至clazz变量中
jclass clazz = FindClassOrDie(env, kBinderPathName);
gBinderOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
//将Binder类中的execTransact方法保存至gBinderOffsets的mExectransact变量中
gBinderOffsets.mExecTransact = GetMethodIDOrDie(env, clazz, "execTransact", "(IJJI)Z");
//将Binder的mObject变量保存到gBinderOffsets的mObject中
gBinderOffsets.mObject = GetFieldIDOrDie(env, clazz, "mObject", "J");
//注册Java Binder类的native函数实现
return RegisterMethodsOrDie(
env, kBinderPathName,
gBinderMethods, NELEM(gBinderMethods));
}
我们看到gBinderOffsets对象保存了Binder类相关的信息,这些信息将在JNI层中使用到,下面两个方法类似;
const char* const kBinderInternalPathName = "com/android/internal/os/BinderInternal";
static int int_register_android_os_BinderInternal(JNIEnv* env)
{
jclass clazz = FindClassOrDie(env, kBinderInternalPathName);
gBinderInternalOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
gBinderInternalOffsets.mForceGc = GetStaticMethodIDOrDie(env, clazz, "forceBinderGc", "()V");
return RegisterMethodsOrDie(env, kBinderInternalPathName, gBinderInternalMethods, NELEM(gBinderInternalMethods));
}
const char* const kBinderProxyPathName = "android/os/BinderProxy";
static int int_register_android_os_BinderProxy(JNIEnv* env)
{
jclass clazz = FindClassOrDie(env, "java/lang/Error");
gErrorOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
clazz = FindClassOrDie(env, kBinderProxyPathName);
gBinderProxyOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
gBinderProxyOffsets.mConstructor = GetMethodIDOrDie(env, clazz, "" , "()V");
gBinderProxyOffsets.mSendDeathNotice = GetStaticMethodIDOrDie(env, clazz, "sendDeathNotice",
"(Landroid/os/IBinder$DeathRecipient;)V");
gBinderProxyOffsets.mObject = GetFieldIDOrDie(env, clazz, "mObject", "J");
gBinderProxyOffsets.mSelf = GetFieldIDOrDie(env, clazz, "mSelf",
"Ljava/lang/ref/WeakReference;");
gBinderProxyOffsets.mOrgue = GetFieldIDOrDie(env, clazz, "mOrgue", "J");
clazz = FindClassOrDie(env, "java/lang/Class");
gClassOffsets.mGetName = GetMethodIDOrDie(env, clazz, "getName", "()Ljava/lang/String;");
return RegisterMethodsOrDie(env, kBinderProxyPathName, gBinderProxyMethods, NELEM(gBinderProxyMethods));
}
至此,初始了JavaBinder重要成员变量,gBinderOffsets,gBinderInternalOffsets,gBinderProxyOffsets,分别保存了对应的Java对象类的方法和变量等信息,这些信息将会在JNI层native和java对象类型转换时使用到,先保存下来能节约一定的时间。
static const JNINativeMethod gBinderMethods[] = {
/* name, signature, funcPtr */
{ "getCallingPid", "()I", (void*)android_os_Binder_getCallingPid },
{ "getCallingUid", "()I", (void*)android_os_Binder_getCallingUid },
{ "clearCallingIdentity", "()J", (void*)android_os_Binder_clearCallingIdentity },
{ "restoreCallingIdentity", "(J)V", (void*)android_os_Binder_restoreCallingIdentity },
{ "setThreadStrictModePolicy", "(I)V", (void*)android_os_Binder_setThreadStrictModePolicy },
{ "getThreadStrictModePolicy", "()I", (void*)android_os_Binder_getThreadStrictModePolicy },
{ "flushPendingCommands", "()V", (void*)android_os_Binder_flushPendingCommands },
{ "init", "()V", (void*)android_os_Binder_init },
{ "destroy", "()V", (void*)android_os_Binder_destroy },
{ "blockUntilThreadAvailable", "()V", (void*)android_os_Binder_blockUntilThreadAvailable }
};
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 },
{ "setMaxThreads", "(I)V", (void*)android_os_BinderInternal_setMaxThreads },
{ "handleGc", "()V", (void*)android_os_BinderInternal_handleGc }
};
static const JNINativeMethod gBinderProxyMethods[] = {
/* name, signature, funcPtr */
{"pingBinder", "()Z", (void*)android_os_BinderProxy_pingBinder},
{"isBinderAlive", "()Z", (void*)android_os_BinderProxy_isBinderAlive},
{"getInterfaceDescriptor", "()Ljava/lang/String;", (void*)android_os_BinderProxy_getInterfaceDescriptor},
{"transactNative", "(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z", (void*)android_os_BinderProxy_transact},
{"linkToDeath", "(Landroid/os/IBinder$DeathRecipient;I)V", (void*)android_os_BinderProxy_linkToDeath},
{"unlinkToDeath", "(Landroid/os/IBinder$DeathRecipient;I)Z", (void*)android_os_BinderProxy_unlinkToDeath},
{"destroy", "()V", (void*)android_os_BinderProxy_destroy},
};
保存一下方便日后查看。
我们以PKMS初始化作为分析Binder java层的入口。
在SystemServer启动PMKS的时候会在PackageManagerService的main函数中new出一个PKMS的实例m,并将PKMS的名称和实例注册至ServiceManager:
//frameworks\base\services\core\java\com\android\server\pm\PackageManagerService.java
public static PackageManagerService main(Context context, Installer installer,
boolean factoryTest, boolean onlyCore) {
PackageManagerService m = new PackageManagerService(context, installer,
factoryTest, onlyCore);
ServiceManager.addService("package", m);
}
从这个地方我们继续跟下去:
//frameworks\base\core\java\android\os\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通过ServiceManagerNative类获取到ServiceManager的代理对象:
private static IServiceManager getIServiceManager() {
if (sServiceManager != null) {
return sServiceManager;
}
// Find the service manager
sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject());
return sServiceManager;
}
看下BinderInternal.getContextObject是如何活的SM的Binder代理的:
//frameworks\base\core\java\com\android\internal\os\BinderInternal.java
public static final native IBinder getContextObject();
看到getContextObject是个native方法,我们找到它native的实现:
//frameworks/base/core/jni/android_util_Binder.cpp
static jobject android_os_BinderInternal_getContextObject(JNIEnv* env, jobject clazz)
{
sp b = ProcessState::self()->getContextObject(NULL);//1,获得native的BpBinder(0)对象
return javaObjectForIBinder(env, b);//2,利用BpBinder对象构造出java层使用的对应的BinderProxy对象
}
首先获取native service_manager的Bp端代理BpBinder(0),在 Android Framework:Binder(4)-Native Service的注册中的第二段的第2小结得知这里最终获得的是Native的BpBinder(0).
然后将Native层的BpBinder(0)通过javaObjectForIBinder()方法包装成java层使用的BinderProxy对象:
//frameworks/base/core/jni/android_util_Binder.cpp
jobject javaObjectForIBinder(JNIEnv* env, const sp& val)
{
if (val == NULL) return NULL;
//创建一个新的BinderProxy对象
object = env->NewObject(gBinderProxyOffsets.mClass, gBinderProxyOffsets.mConstructor);
if (object != NULL) {
// The proxy holds a reference to the native object.
//代理持有一份native对象的的应用,这里的native对象即指的是BpBinder(0),
//将BpBinder对象保存到BinderProxy的mObject成员变量中
env->SetLongField(object, gBinderProxyOffsets.mObject, (jlong)val.get());
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));
//native对象需要持有对应java对象BinderProxy的一份弱引用。
val->attachObject(&gBinderProxyOffsets, refObject,
jnienv_to_javavm(env), proxy_cleanup);
...
}
//返回这个BinderProxy对象
return object;
}
javaObjectForIBinder的作用是,新建一个Java层的BinderProxy对象,将Native层的BpBinder保存到BinderProxy.mObject,并将BinderProxy的弱引用通过attachObject保存到Native层的BpBinder(0)(成员mObjects中),这样Java层的BinderProxy与Native层的BpBinder就可以相互引用了。
通过上的分析可知,BinderInternal.getContextObject()的目的就是得到ServiceManager进程对应的BpBinder,即BpBinder(0),这里需要利用该BpBinder构造出java层使用的BinderProxy对象。
//frameworks\base\core\java\android\os\ServiceManagerNative.java
static final String descriptor = "android.os.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);
}
看到IServiceManager asInterface的方法中将返回一个ServiceManagerProxy的ServiceManager的代理对象,即类似于ServiceManagerProxy(BinderProxy(BpBinder(0)))【当然这种写法不准确,仅仅表示结构关系,下面类似的情况也是相同原因】。
我们来看下ServiceManagerProxy,ServiceManagerProxy实现了IServiceManager中的方法,提供了SM的方法接口:
//frameworks/base/core/java/android/os/ServiceManagerNative.java::ServiceManagerProxy
class ServiceManagerProxy implements IServiceManager {
public ServiceManagerProxy(IBinder remote) {
//这里看到在ServiceManagerProxy的构造函数时就将remote赋值给了ServiceManagerProxy的成员变量mRemote
//而这里的remote值即是上一步中包装给java层用的BpBinder(0)
mRemote = remote;
}
public IBinder asBinder() { return mRemote; }
public IBinder checkService(String name) {mRemote.transact(CHECK_SERVICE_TRANSACTION, data, reply, 0);}
public void addService(String name, IBinder service,){mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0);}
public String[] listServices() { boolean res = mRemote.transact(LIST_SERVICES_TRANSACTION, data, reply, 0);}
private IBinder mRemote;
}
从上面的分析得知getIServiceManager()方法得到的是ServiceManager的代理实例,ServiceManagerProxy(BinderProxy(BpBinder(0)));当调用SM代理的接口方法时会调用成员变量mRemote的transact()方法,由上面的分析我们知道这里的mRemote变量即是由BpBinder(0)构造来的BinderProxy对象;
至此,我们在Client端,PKMS的进程中获得了SM进程的代理对象ServiceManagerProxy,这个SM的代理对象与Native层的service_manager进程息息相关,通过BinderProxy与BpBinder(0)之间的关系传递着联系。
获得Servicemanager代理对象ServiceManagerProxy(BinderProxy(BpBinder(0))),所以调用addService方法即调用到ServiceManagerProxy中的addService方法:
//frameworks/base/core/java/android/os/ServiceManagerNative.java::ServiceManagerProxy
public void addService(String name, IBinder service, boolean allowIsolated)
throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IServiceManager.descriptor);
data.writeString(name);
data.writeStrongBinder(service);//这里
data.writeInt(allowIsolated ? 1 : 0);
mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0);//发送不同的执行code
reply.recycle();
data.recycle();
}
这里我们看到java层的Binder子类即Service通过writeStrongBinder()方法写到Parcel载体对象data中,看下writeStrongBinder()是做什么的:
//frameworks/base/core/java/android/os/Parcel.java
public final void writeStrongBinder(IBinder val) {
nativeWriteStrongBinder(mNativePtr, val);
}
这是个Native方法实现的,找到该方法native实现的地方:
//frameworks/base/core/jni/android_os_Parcel.cpp
static void android_os_Parcel_writeStrongBinder(JNIEnv* env, jclass clazz, jlong nativePtr, jobject object)
{
Parcel* parcel = reinterpret_cast(nativePtr);
if (parcel != NULL) {
const status_t err = parcel->writeStrongBinder(ibinderForJavaObject(env, object));
}
}
看到writeStrongBinder中调用Native Parcel类中writeStrongBinder方法,参数是通过ibinderForJavaObject()函数生成的对象,首先看看这个ibinderForJavaObject()函数做了什么:
2.1.1 iBinderForJavaObject():
sp<IBinder> ibinderForJavaObject(JNIEnv* env, jobject obj)
{
if (obj == NULL) return NULL;
//查看这个java对象是否是Binder.java子类,PKMS继承自IPackageManager.Stub,在生成的IPackageManager.java文件中
//可以看到子类Stub类是继承自android.os.binder的,因此这里PKMS应该是Binder子类
if (env->IsInstanceOf(obj, gBinderOffsets.mClass)) {
//如果是则先获得JavaBBinderHolder对象,然后调用他的get函数,get函数返回一个JavaBBinder对象
JavaBBinderHolder* jbh = (JavaBBinderHolder*)
env->GetLongField(obj, gBinderOffsets.mObject);
return jbh != NULL ? jbh->get(env, obj) : NULL;
}
//如果这个java对象是BinderProxy类,则返回Native层的BpBinder对象
if (env->IsInstanceOf(obj, gBinderProxyOffsets.mClass)) {
return (IBinder*)
env->GetLongField(obj, gBinderProxyOffsets.mObject);
}
return NULL;
}
从上面的分析至从事obj正是PKMS的实例对象,而PKMS继承自IPackageManager.stub类,IPackageManager.stub继承自android.os.Binder类,因此这里的obj这个java对象是Binder的子类,所以经过ibinderForJavaObject()函数,通过JavaBBinderHolder对象的get方法获得并返回一个JavaBBinder对象。
2.1.2 JavaBBinder,Binder,BinderProxy
PKMS继承自IPackageManager.stub,IPackageManager.stub继承自Binder,在注册PKMS之前,需要new一个PKMS实例,因此这时会调用到爷爷类的Binder的构造函数Binder();
//frameworks/base/core/java/android/os/Binder.java
public Binder() {
init();
...
}
private native final void init();
init是一个native实现的方法,我们找到它实现的地方:
//frameworks/base/core/jni/android_util_Binder.cpp
static void android_os_Binder_init(JNIEnv* env, jobject obj)
{
JavaBBinderHolder* jbh = new JavaBBinderHolder();
...
jbh->incStrong((void*)android_os_Binder_init);
env->SetLongField(obj, gBinderOffsets.mObject, (jlong)jbh);
}
我们看到Binder初始化时new了一个JavaBBinderHolder对象,然后把这个JavaBBinderHolder对象保存在了Binder类中的mObject对象中。
再看JavaBBinderHolder的定义:
class JavaBBinderHolder : public RefBase
{
public:
sp get(JNIEnv* env, jobject obj)
{
sp b = mBinder.promote();
if (b == NULL) { b = new JavaBBinder(env, obj);mBinder = b; }
return b;
}
private:
wp mBinder;
};
我们看到JavaBBinderHolder 中持有一个JavaBBinder类型的成员变量mBinder。
而JavaBBinder定义:
class JavaBBinder : public BBinder
{
virtual status_t onTransact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0)
{
JNIEnv* env = javavm_to_jnienv(mVM);
jboolean res = env->CallBooleanMethod(mObject, gBinderOffsets.mExecTransact,
code, reinterpret_cast(&data), reinterpret_cast(reply), flags);
}
private:
JavaVM* const mVM;
jobject const mObject;
};
看到JavaBBinder中有个成员变量mObject指向一个Java层的Binder对象。
三者的关系:
从上面1.1.2小节中我们知道BinderProxy中的mObject指向native层中对应的BpBinder对象,同时该BpBinder对象也持有者BinderProxy的一份弱引用,两者相互引用:
2.1.3 Native层的writeStrongBinder:
//frameworks/native/libs/binder/Parcel.cpp
status_t Parcel::writeStrongBinder(const sp& val)
{
return flatten_binder(ProcessState::self(), val, this);
}
status_t flatten_binder(const sp& /*proc*/,
const sp& binder, Parcel* out)
{
flat_binder_object obj;
obj.flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;
if (binder != NULL) {
IBinder *local = binder->localBinder();
if (!local) {
BpBinder *proxy = binder->remoteBinder();
const int32_t handle = proxy ? proxy->handle() : 0;
obj.type = BINDER_TYPE_HANDLE;
obj.handle = handle;
} else {
obj.type = BINDER_TYPE_BINDER;
obj.binder = reinterpret_cast(local->getWeakRefs());
obj.cookie = reinterpret_cast(local);
}
} ...
return finish_flatten_binder(binder, obj, out);
}
可以看到Native层的writeStrongBinder最终将得到的JavaBBinder对象封装成一个flat_binder_object对象用于写到Parcel数据体中传给Binder驱动,flat_binder_object的数据结构我们在前几篇中见到很多,多为对binder与进程之间对传递的binder对象的封装。
从这里看来,ServiceManagerProxy的addService方法中,data.writeStrongBinder(service);这一步加入的并不是PKMS本身,而是与PKMS对象对应的JavaBBinder对象,将这个JavaBBinder这个对象传递到binder驱动中,最终加入到service_manager中的也是这个JavaBBinder。
接着执行mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0)方法,由上面的分析我们得知mRemote实际上是BinderProxy(BpBinder(0)),因此下面会调用到BinderProxy中的transact方法:
我们接着看下BinderProxy中的transact()方法:
//frameworks/base/core/java/android/os/Binder.java$BinderProxy
final class BinderProxy implements IBinder {
...
public boolean transact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {
Binder.checkParcel(this, code, data, "Unreasonably large binder buffer");
if (Binder.isTracingEnabled()) { Binder.getTransactionTracker().addTrace(); }
return transactNative(code, data, reply, flags);
}
public native boolean transactNative(int code, Parcel data, Parcel reply,
int flags) throws RemoteException;
...
}
BinderProxy的transact()方法调用到native方法transactNative(),我们看到transactNative()中的四个参数和native层的BpBinder的transact方法中的参数正好一一对应。
我们看下transactNative的实现地方:
static jboolean android_os_BinderProxy_transact(JNIEnv* env, jobject obj,
jint code, jobject dataObj, jobject replyObj, jint flags) // throws RemoteException
{
//将java对象转化为native对象
Parcel* data = parcelForJavaObject(env, dataObj);
Parcel* reply = parcelForJavaObject(env, replyObj);
//得到native层的BpBinder,
IBinder* target = (IBinder*)
env->GetLongField(obj, gBinderProxyOffsets.mObject);
...
//通过BpBinder利用IPCThreadState,将请求写入binder驱动,继而传给service_manager进程
status_t err = target->transact(code, *data, reply, flags);
...
}
同过上面分析我们知道BinderProxy的mObject保存的是对应的BpBinder的引用,因此这里的target是构造BinderProxy对象时所用到的BpBinder对象,即BpBinder(0)。
这里就比较熟悉了,最终调用到native层的BpBinder去与binder驱动进行通信,最终由service_manager进程向Binder驱动中去取指令与数据进行处理。这里我们知道发给service_manager进程的指令是ADD_SERVICE_TRANSACTION,
数据是ServiceName及Service对象对应的JavaBBinder。
Native层的binder机制在前几篇文章中已经叙述的足够详细,请参考Android Framework:Binder(4)-Native Service的注册中的第二节的第3小节,这里不再赘述。
PKMS服务注册小结:
ServiceManager是公开的管理类,ServiceManager中定义了公开的接口方法,而这些接口方法中通过ServiceManagerNative类调用ServiceManager代理对象ServiceManagerProxy中的方法来实现,
而ServiceManagerProxy中持有一个由service_manager的Bp端代理BpBinder(0)构造出来的BinderProxy对象,在执行ServiceManagerProxy中对应的方法时会执行到BinderProxy的transact方法,通过传入
BinderProxy的transact()中的操作指令不同来实现不同的方法。
至此,我们跟踪了PKMS初始化向service_manager注册自己的过程。
上图总结下:
这里以PackageInstaller使用PackageManager卸载应用为例进行学习;
/packages/apps/PackageInstaller/src/com/android/packageinstaller/wear/WearPackageInstallerService.java
private void uninstallPackage(Bundle argsBundle) {
final PackageManager pm = getPackageManager();
pm.deletePackage(packageName, new PackageDeleteObserver(lock, startId),
PackageManager.DELETE_ALL_USERS);
}
通过前面的学习我们知道要调用Service方法需要先获得Service的代理,所以这里先看如何得到PKMS的代理:
public static IPackageManager getPackageManager() {
if (sPackageManager != null) {
return sPackageManager;
}
IBinder b = ServiceManager.getService("package");
sPackageManager = IPackageManager.Stub.asInterface(b);
return sPackageManager;
}
要得到PKMS的代理需要借助ServiceManager的getService()方法,参数为PKMS注册时注册的名字”package”,而ServiceManager的getService()方法大部分步骤和第三节分析的addService步骤是一致的:
1. 获取ServiceManager的代理对象ServiceManagerProxy(BinderProxy(BpBinder(0))),
2. 调用ServiceManagerProxy的getService方法,
3. 调用BinderProxy的transact()方法,传入的操作指令code是GET_SERVICE_TRANSACTION,
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();
reply.recycle();
data.recycle();
return binder;
}
从上面的分析知mRemote实际是BinderProxy(BpBinder(0)),执行BinderProxy的transact()方法,然后调用到其native的实现方法,android_os_BinderProxy_transact(),在这个native方法中先获取该BinderProxy中mObject中保存的BpBinder对象,再调用该BpBinder的transact()方法实现与binder驱动通信,进而与service_manager进程通信得到写在指针reply地址中的返回数据。
在native层的binder介绍中我们知道reply指针指向的地址中是service_manager返回的包含PKMS handle值的flat_binder_object类型对象;
看下面这一步:
Binder binder = reply.readStrongBinder();
调用了Parcel.java中的readStrongBinder()方法:
public final IBinder readStrongBinder() {
return nativeReadStrongBinder(mNativePtr);
}
nativeReadStrongBinder方法是个Native方法,找到它native实现的地方:
//frameworks/base/core/jni/android_os_Parcel.cpp
static jobject android_os_Parcel_readStrongBinder(JNIEnv* env, jclass clazz, jlong nativePtr)
{
Parcel* parcel = reinterpret_cast(nativePtr);
if (parcel != NULL) {
return javaObjectForIBinder(env, parcel->readStrongBinder());
}
return NULL;
}
又是两步操作,第一步是Native的Parcel的readStrongBinder()方法,第二步又是这个javaObejctForIBinder()方法。
1.2.1 Native Parcell的readStrongBinder
先看这一步,parcel->readStrongBinder():
status_t Parcel::readStrongBinder(sp* val) const
{ //
return unflatten_binder(ProcessState::self(), *this, val);
}
unflatten_binder()中主要将binder驱动传过来的包含PMS的handle值的flat_binder_object对象还原成BpBinder(handle)对象写至val指针指向的地址上。
status_t unflatten_binder(const sp& proc,
const Parcel& in, sp* out)
{
const flat_binder_object* flat = in.readObject(false);
if (flat) {
switch (flat->type) {
case BINDER_TYPE_BINDER:
*out = reinterpret_cast(flat->cookie);
return finish_unflatten_binder(NULL, *flat, in);
case BINDER_TYPE_HANDLE:
*out = proc->getStrongProxyForHandle(flat->handle);
return finish_unflatten_binder(
static_cast(out->get()), *flat, in);
}
}
return BAD_TYPE;
}
之前在第二节的第2.1.3小节中分析过Native Parcel类的writeStrongBinder方法,是将JavaBBinder对象打扁成flat_binder_object类型的对象,以这样的类型向binder驱动传递binder对象;这里的readStrongBinder方法正好和它相反,是将Binder驱动传递过来的flat_binder_object对象(service_manager查询到PKMS的handle值然后构造封装成flat_binder_object对象通过binder驱动返回请求的cilent端)unflatten还原成一个对应的BpBinder(handle)对象,这个BpBinder对象就是PKMS 在native层Bp端的代理BpBinder。
1.2.2 JNI层中的javaObjectForIBinder方法:
而在上面第二节的1.1小节中我们分析了javaObjectForIBinder函数的作用:javaObjectForIBinder(env,BpBinder(handle))会将第二个参数BpBinder(handle)转化成一个BinderProxy对象返回给Java层。
这样Client端就得到了PMSjava层的代理Binder对象BinderProxy(BpBinder(handle)).
sPackageManager = IPackageManager.Stub.asInterface(b);
我们在Android Framework源码中没有搜到IPackageManager.Stub.asInterface的定义的地方,原因是这个定义的地方是Android跟据IPackageManager.aidl文件在编译时生成的在out目录下我们搜到了IPackageManager.java。
简要摘录点IPackageManager.java的code,整理下结构方便查看:
//out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/core/java/android/content/pm/IPackageManager.java
public interface IPackageManager extends android.os.IInterface {
public static abstract class Stub extends android.os.Binder implements android.content.pm.IPackageManager {
private static final java.lang.String DESCRIPTOR = "android.content.pm.IPackageManager";
public Stub() {
this.attachInterface(this, DESCRIPTOR);
}
public static android.content.pm.IPackageManager asInterface(android.os.IBinder obj) {
if ((obj == null)) {
return null;
}
android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
if (((iin != null) && (iin instanceof android.content.pm.IPackageManager))) {
return ((android.content.pm.IPackageManager) iin);
}
return new android.content.pm.IPackageManager.Stub.Proxy(obj);
}
@Override
public android.os.IBinder asBinder() {
return this;
}
@Override
public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException {
switch (code) {
case INTERFACE_TRANSACTION: {...}
case TRANSACTION_checkPackageStartable: {...}
case TRANSACTION_isPackageAvailable: {...}
....
}
...
}
...
private static class Proxy implements android.content.pm.IPackageManager
{
private android.os.IBinder mRemote;
Proxy(android.os.IBinder remote)
{
mRemote = remote;
}
@Override public android.os.IBinder asBinder()
{
return mRemote;
}
public java.lang.String getInterfaceDescriptor()
{
return DESCRIPTOR;
}
@Override public void checkPackageStartable(java.lang.String packageName, int userId) throws android.os.RemoteException
{ ...
mRemote.transact(Stub.TRANSACTION_checkPackageStartable, _data, _reply, 0);
}
@Override public boolean isPackageAvailable(java.lang.String packageName, int userId) throws android.os.RemoteException
{
...
mRemote.transact(Stub.TRANSACTION_isPackageAvailable, _data, _reply, 0);
...
}
}
}
...
}
查看上面的code之后看到IPackageManager.Stub.asInterface(b)之后得到一个android.content.pm.IPackageManager.Stub.Proxy(obj)的对象(下面简写为PKMProxy实在是太长了好吓人)赋值给sPackageManager。这个对象即是PackageManagerService的代理对象,obj是传入的Binderproxy(BpBinder(handle))的PMS的代理Binder对象。
这里和上面得到ServiceManager的代理对象类似,ServiceManager得到的是ServiceManagerProxy(BinderProxy(BpBinder(0)))。
至此,我们及得到了PKMS服务的代理类对象PKMProxy,下面就可以使用PKMSProxy类对象进行PKMS的方法调用了。
同Servicemanager中分析的,执行BinderProxy对象的transact()方法通过JNI层的传递调用到native层中对应的BpBinder(handle)的transact()方法,接下来就是通过BpBinder中的IPCThreadState与Binder驱动进行交互了。
我们知道PackageManagerService是跑在SystemServer进程里的,Zygote的第一个子进程就是SystemServer,在启动SystemServer进程后期会去为SystemServer起一个Binder线程用于SystemServer与Binder驱动进程通信。
///frameworks/base/cmds/app_process/app_main.cpp
virtual void onZygoteInit() {
sp proc = ProcessState::self();
proc->startThreadPool(); // 启动一个线程,用于Binder通信。
}
从之前的BinderNative学习中知道proc->startThreadPool()即是启动了一个线程用于Binder通信了,具体可以看Android Framework:Binder(4)-Native Service的注册中的第二节的第4小节 “4.Service线程池管理,处理请求”相关的分析。
也就是说同样的SystemServer进程中也是有个Binder线程在不断向Binder驱动查看是否有请求数据。
当有个systemServer的请求时会调用systemserver进程的IPCThreadState的joinThreadPool里调用getAndExecuteCommand()函数去处理请求,最终会调用到BBinder的transact()处理请求,transact会调用虚函数onTransact(),而此时JavaBBinder继承自BBinder,所以会调用JavaBBinder::onTransact()方法:
//frameworks/base/core/jni/android_util_Binder.cpp::JavaBBinder
virtual status_t onTransact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0)
{
JNIEnv* env = javavm_to_jnienv(mVM);
...
//通过JNI调用了java类的方法
jboolean res = env->CallBooleanMethod(mObject, gBinderOffsets.mExecTransact,
code, reinterpret_cast(&data), reinterpret_cast(reply), flags);
return res != JNI_FALSE ? NO_ERROR : UNKNOWN_TRANSACTION;
}
前面我们知道了,Java实现的Service中,Service对象,JavaBBinderHolder,JavaBBinder存在相互引用关系,JavaBBinder的成员mObject引用了Java中的Service的Binder对象,比如此处的PMS,而且在int_register_android_os_Binder中通过
gBinderOffsets.mExecTransact = env->GetMethodID(clazz, "execTransact", "(IIII)Z");
将Service的execTransact方法(其实是Binder的方法)保存在了gBinderOffsets.mExecTransact中,所在以JavaBBinder::onTransact中会调用Binder.execTransact。
public class Binder implements IBinder {
// Entry point from android_util_Binder.cpp's onTransact
private boolean execTransact(int code, long dataObj, long replyObj,
int flags) {
Parcel data = Parcel.obtain(dataObj);
Parcel reply = Parcel.obtain(replyObj);
boolean res;
try {
res = onTransact(code, data, reply, flags);
} catch{...}
}
}
在Binder.execTransact中调用了onTransact,执行子类即IPackageManager.stub类的onTransact()方法
//out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/src/core/java/android/content/pm/IPackageManager.java
public static abstract class Stub extends android.os.Binder implements android.content.pm.IPackageManager {
...
@Override
public boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException {
switch (code){
case INTERFACE_TRANSACTION:{return;}
...
case TRANSACTION_deletePackage:{
data.enforceInterface(DESCRIPTOR);
java.lang.String _arg0;
_arg0 = data.readString();
android.content.pm.IPackageDeleteObserver2 _arg1;
_arg1 = android.content.pm.IPackageDeleteObserver2.Stub.asInterface(data.readStrongBinder());
int _arg2;
_arg2 = data.readInt();
int _arg3;
_arg3 = data.readInt();
this.deletePackage(_arg0, _arg1, _arg2, _arg3);//调到这里
reply.writeNoException();
return true;
}
...
}
...
}
...
}
在IPackageManager.stub的onTransact方法中中根据code值执行相应的方法这里即调用 this.deletePackage()方法,最终则调用PackageManagerService类(继承自Stub)中相应的deletePackage()接口方法,执行该接口方法的功能。
至此,完成了Client端跨进程调用PKMS的deletePackage服务方法。
参考博客:
Android FrameWork——Binder机制详解(1)
http://blog.csdn.net/stonecao/article/details/6657438
Android情景分析之深入解析system_server
http://blog.csdn.net/hu3167343/article/details/38375167
Binder in java
http://www.cnblogs.com/angeldevil/p/3328748.html
Android7.0 Binder通信(4) Java层中的Binder
http://blog.csdn.net/gaugamela/article/details/52577381
Binder机制4—Framework层
http://www.jcodecraeer.com/a/anzhuokaifa/androidkaifa/2015/0319/2622.html
《深入理解Android卷2》第2章 深入理解Java Binder 邓凡平