Android Framework:Binder(6)-Java層Service的註冊及跨進程調用
1、Java層Binder概述java
Java層中的binder和Native層的Binder在命名上儘可能保持了一致,且Java層的Binder依託於Native層的Binder,其實就是對底層的Binder的真正實現的一個封裝,最終仍是經過JNI技術調用到C/C++代碼的實現。。
本文咱們從PKMS服務的初始化註冊和PKMS的服務調用來學習Java層Binder的知識。
廢話不說先上圖:android
1. Java Binder及PKMS框架:
2. 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的響應。cookie
2、Java層Binder框架初始化
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;
} 架構
1.Java層Binder框架JNI層的初始化
1.1 Binder類JNI層初始化
//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));
}app
咱們看到gBinderOffsets對象保存了Binder類相關的信息,這些信息將在JNI層中使用到,下面兩個方法相似;框架
1.2 BinderInternal類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));
}ide
1.3 BinderProxy類JNI層初始化
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, "<init>", "()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對象類型轉換時使用到,先保存下來能節約必定的時間。
2. Java Binder中重要Native方法映射
2.1 Java層Binder類中的native方法:
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 }
};
2.2 Java層BinderInternal類中的native方法:
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 }
};
2.3 Java層BinderProxy類中的native方法:
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},
};
保存一下方便往後查看。
3、PKMS初始化註冊服務
咱們以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);
}
}
1. 獲取ServiceManager的代理對象:
getIServiceManager經過ServiceManagerNative類獲取到ServiceManager的代理對象:
private static IServiceManager getIServiceManager() {
if (sServiceManager != null) {
return sServiceManager;
}
// Find the service manager
sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject());
return sServiceManager;
}
1.1 獲取Service的Binder代理BinderProxy
看下BinderInternal.getContextObject是如何活的SM的Binder代理的:
//frameworks\base\core\java\com\android\internal\os\BinderInternal.java
public static final native IBinder getContextObject();
1
2
看到getContextObject是個native方法,咱們找到它native的實現:
//frameworks/base/core/jni/android_util_Binder.cpp
static jobject android_os_BinderInternal_getContextObject(JNIEnv* env, jobject clazz)
{
sp<IBinder> b = ProcessState::self()->getContextObject(NULL);//1,得到native的BpBinder(0)對象
return javaObjectForIBinder(env, b);//2,利用BpBinder對象構造出java層使用的對應的BinderProxy對象
}
1.1.1 獲取SM的Bp端的BpBinder(0)
首先獲取native service_manager的Bp端代理BpBinder(0),在 Android Framework:Binder(4)-Native Service的註冊中的第二段的第2小結得知這裏最終得到的是Native的BpBinder(0).
1.1.2 javaObjectForIBinder方法構造出BinderProxy對象
而後將Native層的BpBinder(0)經過javaObjectForIBinder()方法包裝成java層使用的BinderProxy對象:
//frameworks/base/core/jni/android_util_Binder.cpp
jobject javaObjectForIBinder(JNIEnv* env, const sp<IBinder>& 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對象。
1.2 ISM asInterface方法利用BinderProxy構造服務代理對象SMProxy:
//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)))【固然這種寫法不許確,僅僅表示結構關係,下面相似的狀況也是相同緣由】。
1.3.分析ServiceManagerProxy
咱們來看下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)之間的關係傳遞着聯繫。
2. 跨進程調用ServiceManager的addService方法:
得到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();
}
2.1 數據Binder的封裝 data.writeStrongBinder(service):
這裏咱們看到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<Parcel*>(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<JavaBBinder> get(JNIEnv* env, jobject obj)
{
sp<JavaBBinder> b = mBinder.promote();
if (b == NULL) { b = new JavaBBinder(env, obj);mBinder = b; }
return b;
}
private:
wp<JavaBBinder> 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<jlong>(&data), reinterpret_cast<jlong>(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<IBinder>& val)
{
return flatten_binder(ProcessState::self(), val, this);
}
status_t flatten_binder(const sp<ProcessState>& /*proc*/,
const sp<IBinder>& 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<uintptr_t>(local->getWeakRefs());
obj.cookie = reinterpret_cast<uintptr_t>(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。
2.2 執行BinderProxy的transact方法:
接着執行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)。
2.3 Native層BpBinder向BinderDriver傳輸請求
這裏就比較熟悉了,最終調用到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註冊本身的過程。
上圖總結下:
4、跨進程調用PKMS服務
這裏以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);
}
1.獲取PKMS服務的代理:
經過前面的學習咱們知道要調用Service方法須要先得到Service的代理,因此這裏先看如何獲得PKMS的代理:
public static IPackageManager getPackageManager() {
if (sPackageManager != null) {
return sPackageManager;
}
IBinder b = ServiceManager.getService("package");
sPackageManager = IPackageManager.Stub.asInterface(b);
return sPackageManager;
}
1.1 獲取SM服務代理,向SM請求獲取PKMS的服務代理:
要獲得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類型對象;
1.2 readStongBinder獲取Java層PKMS的代理Binder對象:
看下面這一步:
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<Parcel*>(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<IBinder>* 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<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:
*out = reinterpret_cast<IBinder*>(flat->cookie);
return finish_unflatten_binder(NULL, *flat, in);
case BINDER_TYPE_HANDLE:
*out = proc->getStrongProxyForHandle(flat->handle);
return finish_unflatten_binder(
static_cast<BpBinder*>(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)).
1.3 xx.stub.asInterface獲取PKMS服務的proxy(BinderProxy)
sPackageManager = IPackageManager.Stub.asInterface(b);
1
咱們在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的方法調用了。
2. 使用PKMProxy類對象調用PKMS方法
2.1 PKMS家族主要結構
android.content.pm.IPackageManager.Stub.Proxy是在IPackageManager.java中IPackageManager內部類Stub中的內部類,咱們看PMS的proxy中實現了IPackageManager的接口,而PKMProxy具體是經過mRemote的transact方法實現。而這個mRemote就是咱們new PKMProxy(obj)時傳入的BinderProxy(BpBidner(handle))對象。
BinderProxy由對應的BpBinder構造而來,且BinderProxy與BpBinder相互引用,BinderProxy的transact()方法會經過JNI層調用到對應的成員變量mObject中的BpBinder的transact()方法;
經過JNI層的支持,native層的JavaBBinder對象對java層的Binder持有引用,在Binder初始化時即經過JavaBBinderHolder持有了Java Binder的引用,Java Binder的引用保存在JavaBBinder的成員變量mObject中,所以PKMS響應時是由JavaBBinder這個BBinder的子類經過JNI層通知上層Java Binder繼而實現java層服務的響應請求。
2.2 使用PKMS服務代理調用服務方法
同Servicemanager中分析的,執行BinderProxy對象的transact()方法經過JNI層的傳遞調用到native層中對應的BpBinder(handle)的transact()方法,接下來就是經過BpBinder中的IPCThreadState與Binder驅動進行交互了。
3 PKMS服務響應Client端請求
咱們知道PackageManagerService是跑在SystemServer進程裏的,Zygote的第一個子進程就是SystemServer,在啓動SystemServer進程後期會去爲SystemServer起一個Binder線程用於SystemServer與Binder驅動進程通訊。
///frameworks/base/cmds/app_process/app_main.cpp
virtual void onZygoteInit() {
sp<ProcessState> proc = ProcessState::self();
proc->startThreadPool(); // 啓動一個線程,用於Binder通訊。
}
從以前的BinderNative學習中知道proc->startThreadPool()便是啓動了一個線程用於Binder通訊了,具體能夠看Android Framework:Binder(4)-Native Service的註冊中的第二節的第4小節 「4.Service線程池管理,處理請求」相關的分析。
也就是說一樣的SystemServer進程中也是有個Binder線程在不斷向Binder驅動查看是否有請求數據。
3.1 PKMS進程讀取Binder驅動請求數據調用JavaBBinder的onTransact()方法
當有個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<jlong>(&data), reinterpret_cast<jlong>(reply), flags);
return res != JNI_FALSE ? NO_ERROR : UNKNOWN_TRANSACTION;
}
3.2 JavaBBinder經過JNI層調用到Java Binder的execTransact方法:
前面咱們知道了,Java實現的Service中,Service對象,JavaBBinderHolder,JavaBBinder存在相互引用關係,JavaBBinder的成員mObject引用了Java中的Service的Binder對象,好比此處的PMS,並且在int_register_android_os_Binder中經過
gBinderOffsets.mExecTransact = env->GetMethodID(clazz, "execTransact", "(IIII)Z");
1
將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{...}
}
}
3.3 Java Binder調用子類stub類中的onTransact()方法:
在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;
}
...
}
...
}
...
}
3.4 stub類onTransact()方法調用子類Service類的接口方法完成服務調用:
在IPackageManager.stub的onTransact方法中中根據code值執行相應的方法這裏即調用 this.deletePackage()方法,最終則調用PackageManagerService類(繼承自Stub)中相應的deletePackage()接口方法,執行該接口方法的功能。
至此,完成了Client端跨進程調用PKMS的deletePackage服務方法。
5、Java層Binder機制總結
Java層Binder機制依賴於Native層的Binder框架,是對Native層的binder進行了java層的封裝,經過JNI層進行聯繫。
java層的binder機制的跨進程調用主要能夠經過如下這張圖高度歸納:
Client端經過獲取Service端的服務代理XXServiceProxy來和Binder驅動進行通訊; Service端有一個Binder線程監聽着Binder驅動,監聽到有發向本身的請求即經過native層的BBinder子類JavaBBinder經由JNI層通知到Java層的Binder子類IXXService.stub,從而通知到stub的子類Service的實現方法; Client端Service的服務代理XXServiceProxy持有一個BinderProxy類型的成員變量mRemote,該變量經過JNI層技術與native層的BpBinder對象相互持有引用,而BpBinder中的IPCThreadState與Binder驅動進行交流,經過這樣的聯繫達到Java層Client端與Binder驅動交流的目的 JavaBBinder對象經過JavaBBinderHolder與Java層的Binder類相互引用聯繫,而JavaBBinder的父類BBinder與BpBinder是一一對應的,這樣Client端Binder代理對象通過Binder驅動與Server端Binder對象也創建了對應的 關係. Java層的Service其實就是個Binder,Service是Binder的子類的子類 ,Client端獲取的是Binder的代理。 引用鄧凡平的書中的經典的話,從通訊的角度看,Binder的架構不論採用Native語言仍是Java語言,都是Client要把請求傳遞到Binder驅動,Server端從Binder驅動中獲取數據,通訊的目的是向binder發送請求和接收回復。 本文只講述了系統核心服務PKMS的註冊及跨進程調用,固然跨進程調用的服務不止這些,往後繼續分析普通service的跨進程調用,aidl的使用,以及應用層service的註冊及調用細節。