前面兩章學(xué)習(xí)分析了 ServiceManager 的啟動(dòng)流程與獲取它代理對象的流程, 本章節(jié)開始對 Service 組件啟動(dòng)后注冊到 ServiceManager 的流程進(jìn)行分析.
前言
Service 組件是在 Server 進(jìn)程中運(yùn)行的. Server 進(jìn)程在啟動(dòng)時(shí), 會(huì)首先將它里面的 Service 組件注冊到 SM 中, 接著再啟動(dòng)一個(gè) Binder 線程池來等待和處理 Client 進(jìn)程的通信請求.
本章內(nèi)容以 ActivityManagerService 為例, 一步步分析它是怎么從啟動(dòng)到注冊到 SM 中的. 在AMS 服務(wù)的的時(shí)候不會(huì)太詳細(xì), 后面會(huì)有單獨(dú)的章節(jié)來分析它. 重點(diǎn)在于是如何注冊到 SM 中的.
首先是先來到系統(tǒng)服務(wù) SystemServer
中. 看它的 main
方法
一. AMS 的啟動(dòng)
1. SystemServer.main
源碼路徑 /frameworks/base/services/java/com/android/server/SystemServer.java
public static void main(String[] args) {
new SystemServer().run();
}
在內(nèi)部看到又調(diào)用了 run
2. SystemServer.run
源碼路徑 /frameworks/base/services/java/com/android/server/SystemServer.java
private void run() {
...
mSystemServiceManager = new SystemServiceManager(mSystemContext);
...
try {
//啟動(dòng)引導(dǎo)類服務(wù)
02 startBootstrapServices();
//啟動(dòng)核心類服務(wù)
startCoreServices();
//啟動(dòng)其他服務(wù)
startOtherServices();
} catch (Throwable ex) {
...
}
...
}
這里會(huì)先創(chuàng)建 SystemServiceManager
對象, 這個(gè)后面會(huì)分析到, 直接進(jìn)入到 2 處 startBootstrapServices()
. AMS 屬于引導(dǎo)類服務(wù), 很多服務(wù)也都依賴 AMS.
3. SystemServer.startBootstrapServices() 在啟動(dòng)引導(dǎo)類服務(wù)中創(chuàng)建 AMS.
源碼路徑 /frameworks/base/services/java/com/android/server/SystemServer.java
private void startBootstrapServices() {
...
01 mActivityManagerService = mSystemServiceManager.startService(ActivityManagerService.Lifecycle.class).getService();
...
02 mActivityManagerService.setSystemProcess();
...
}
在代碼 01 處, 看到調(diào)用了 mSystemServiceManager.startService
傳入的參數(shù)是 Class, 那么猜想應(yīng)該是用來反射的. 進(jìn)去看一下 startService
這個(gè)函數(shù).
4. SystemServiceManager.startService 傳入 ActivityManagerService.Lifecycle.class
源碼路徑: /frameworks/base/services/core/java/com/android/server/SystemServiceManager.java
private final ArrayList<SystemService> mServices = new ArrayList<SystemService>();
public <T extends SystemService> T startService(Class<T> serviceClass) {
final String name = serviceClass.getName();
...
final T service;
try {
01 Constructor<T> constructor = serviceClass.getConstructor(Context.class);
02 service = constructor.newInstance(mContext);
} catch (InstantiationException ex) {
...
}
...
03 mServices.add(service);
try {
04 service.onStart();
} catch (RuntimeException ex) {
...
}
return service;
}
代碼 01 處 與 02 處創(chuàng)建了 ActivityManagerService.Lifecycle
對象, 并賦值給變量 service
.
代碼 03 處將這個(gè)創(chuàng)建的 ActivityManagerService.Lifecycle
對象添加到變量 mServices
中. 在最上面看到 mServices
是一個(gè)集合. 保存的內(nèi)容就是 SystemService
類型的.
代碼 04 處, 調(diào)用 ActivityManagerService.Lifecycle
的 onStart
函數(shù).
找到 ActivityManagerService.Lifecycle
看一下它的構(gòu)造函數(shù)和 onStart
函數(shù).
5. ActivityManagerService.Lifecycle() & ActivityManagerService.Lifecycle.onStart()
源碼路徑:/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
public final class ActivityManagerService extends ActivityManagerNative
implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
...
public static final class Lifecycle extends SystemService {
private final ActivityManagerService mService;
public Lifecycle(Context context) {
super(context);
mService = new ActivityManagerService(context);
}
@Override
public void onStart() {
mService.start();
}
public ActivityManagerService getService() {
return mService;
}
}
...
Lifecycle
是 AMS 中的一個(gè)靜態(tài)內(nèi)部類. 在構(gòu)造函數(shù)內(nèi)可以看到, 是在這里創(chuàng)建了 ActivityManagerService
并保存到 mService
中.
然后在上面第4步中調(diào)用的 service.onStart();
實(shí)際上調(diào)用的就是 ActivityManagerService.start()
函數(shù).
接著將 AMS 添加到 SM 中. 回到第 3 步中. getService()
獲得了 AMS 對象, 接著在 02 行代碼處將 AMS 添加至 SM 中.
private void startBootstrapServices() {
...
01 mActivityManagerService = mSystemServiceManager.startService(ActivityManagerService.Lifecycle.class).getService();
...
02 mActivityManagerService.setSystemProcess();
...
}
二. 將 ActivityManagerService 添加至 ServiceManager
6. mActivityManagerService.setSystemProcess()
源碼路徑:/frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
public void setSystemProcess() {
...
ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
...
}
終于看到了 addService
函數(shù)的調(diào)用. 進(jìn)入 ServiceManager.addService
看是如何添加的.
其中 Context.ACTIVITY_SERVICE
的定義為 public static final String ACTIVITY_SERVICE = "activity";
`
7. ServiceManager.addService
源碼路徑: /frameworks/base/core/java/android/os/ServiceManager.java
public static void addService(String name, IBinder service, boolean allowIsolated) {
try {
getIServiceManager().addService(name, service, allowIsolated);
} catch (RemoteException e) {
Log.e(TAG, "error in addService", e);
}
}
先調(diào)用 ServiceManager
類的靜態(tài)成員函數(shù) getIServiceManager
來獲得一個(gè) ServiceManager
的 Java 代理對象 ServiceManagerProxy
. 接著再調(diào)用這個(gè) Java 代理對象的成員函數(shù) addService
將 AMS 注冊到 SM 中. 指定了這個(gè) Service 的注冊名稱為 activity
.
這里通過兩步來分析先來看 getIServiceManager
8. getIServiceManager 獲得 SM 的代理對象
源碼路徑: /frameworks/base/core/java/android/os/ServiceManager.java
private static IServiceManager sServiceManager;
private static IServiceManager getIServiceManager() {
if (sServiceManager != null) {
return sServiceManager;
}
...
sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject());
return sServiceManager;
}
首先判斷 ServiceManager.java
類的靜態(tài)成員變量 sServiceManager
是否為 NULL, 不為 NULL 說明之前已經(jīng)獲創(chuàng)建過代理對象. 所以直接返回給調(diào)用者.
否則就先通過 BinderInternal
類的靜態(tài)成員函數(shù) getContextObject
創(chuàng)建一個(gè)句柄值等等于 0 的 Java 服務(wù)代理對象, 接著再通過 ServiceManagerNative.asInterface
函數(shù)將這個(gè) Java 服務(wù)代理對象封裝成一個(gè) ServiceManagerProxy
對象.保存在 sServiceManager
中并返回給調(diào)用者.
下面分別分析BinderInternal.getContextObject()
與 ServiceManagerNative.asInterface
9. BinderInternal.getContextObject()
BinderInternal
類的靜態(tài)成員函數(shù) getContextObject
是一個(gè) JNI 方法, 定義如下
源碼路徑: /frameworks/base/core/java/com/android/internal/os/BinderInternal.java
public static final native IBinder getContextObject();
它是由 C++ 層中的函數(shù) android_os_BinderInternal_getContextObject()
來實(shí)現(xiàn)的.
源碼路徑: /frameworks/base/core/java/jni/android_util_Binder.cpp
static jobject android_os_BinderInternal_getContextObject(JNIEnv* env, jobject clazz)
{
sp<IBinder> b = ProcessState::self()->getContextObject(NULL);
return javaObjectForIBinder(env, b);
}
看到這里, 終于看到熟悉的了 ProcessState::self()->getContextObject
. 如果看過上一章, 對這個(gè)肯定不會(huì)陌生.
這行代碼就是創(chuàng)建一個(gè) BpBinder 對象. 接著調(diào)用 javaObjectForIBinder
對這個(gè) Binder 代理對象創(chuàng)建一個(gè) Java 服務(wù)代理對象, 即一個(gè) BinderProxy 對象. 返回給調(diào)用者.
10. javaObjectForIBinder 創(chuàng)建 Java 服務(wù)代理對象
源碼路徑: /frameworks/base/core/java/com/android/internal/os/BinderInternal.java
jobject javaObjectForIBinder(JNIEnv* env, const sp<IBinder>& val)
{
if (val == NULL) return NULL;
//檢查是 Binder 代理對象還是 本地丟西
if (val->checkSubclass(&gBinderOffsets)) {
...
}
01 jobject object = (jobject)val->findObject(&gBinderProxyOffsets);
if (object != NULL) {
02 jobject res = jniGetReferent(env, object);
if (res != NULL) {
...
return res;
}
...
03 val->detachObject(&gBinderProxyOffsets);
...
}
04 object = env->NewObject(gBinderProxyOffsets.mClass, gBinderProxyOffsets.mConstructor);
if (object != NULL) {
05 env->SetLongField(object, gBinderProxyOffsets.mObject, (jlong)val.get());
06 val->incStrong((void*)javaObjectForIBinder);
jobject refObject = env->NewGlobalRef(
env->GetObjectField(object, gBinderProxyOffsets.mSelf));
07 val->attachObject(&gBinderProxyOffsets, refObject, jnienv_to_javavm(env), proxy_cleanup);
...
}
return object;
}
代碼 01 處調(diào)用 Binder 代理對象(BpBinder) val
的成員函數(shù) findObject
來檢查當(dāng)前進(jìn)程之前是否已經(jīng)創(chuàng)建過一個(gè) Java 服務(wù)代理對象了(BinderProxy), 如果是接著在代碼 02 處接著檢查它的有效性, 如果未失效則直接返回給調(diào)用者. 如果失效就在代碼 03 處調(diào)用 Binder 代理對象(BpBinder) val
的成員函數(shù) detachObject
來解除它與一個(gè)無效 Java 服務(wù)代理對象(BinderProxy) 的對應(yīng)關(guān)系.
如果代碼 01 處檢查之前沒有創(chuàng)建過一個(gè) Java 服務(wù)代理對象(BinderProxy), 在代碼 04 處就會(huì)為它創(chuàng)建一個(gè) Java 服務(wù)代理對象(BinderProxy) object
. 如果創(chuàng)建成功, 接著來在代碼 05 處將 Binder 代理對象(BpBinder) val
的地址值設(shè)置到上一步創(chuàng)建的 Java 服務(wù)代理對象(BinderProxy) object
的成員變量 mObject
中. 即 BinderProxy.mObject
記錄了 BpBinder 對象. 因此在代碼 06 處增加 Binder 代理對象(BpBinder) val
的強(qiáng)引用計(jì)數(shù), 因?yàn)樗?Java 服務(wù)代理對象(BinderProxy) object
引用了
代碼 07 處通過全局變量 gBinderProxyOffsets
將這個(gè)全局引用對象與 Binder 代理對象(BpBinder) val
關(guān)聯(lián)起來. 相當(dāng)于將創(chuàng)建的 Java 服務(wù)代理對象(BinderProxy) object
與 Binder 代理對象(BpBinder)的 val
關(guān)聯(lián)起來. 這樣以后再以 Binder 代理對象(BpBinder) val
為參數(shù)來調(diào)用函數(shù) javaObjectForIBinder
時(shí), 就可以直接獲得保存在它內(nèi)部的成員變量 mObjects
中的 Java 服務(wù)代理對象(BinderProxy) 了.
Binder 代理對象內(nèi)部有一個(gè)成員變量
mObjects
, 類型是ObjectManager
, 用來管理與 Binder 代理對象關(guān)聯(lián)的外部對象. 例如javaObjectForIBinder
函數(shù)在為一個(gè) Binder 代理對象創(chuàng)建一個(gè) Java 服務(wù)代理對象時(shí), 就會(huì)將創(chuàng)建出來的 Java 服務(wù)代理對象保存在該 Binder 代理對象的成員變量mObjects
中, 以便以后需要獲取與該 Binder 代理對象對應(yīng)的 Java 服務(wù)代理對象時(shí), 就可以通過它的成員變量mObjects
來直接獲得. 由于一個(gè) Binder 代理對象所關(guān)聯(lián)的外部對象可能不止一個(gè), 因此需要通過額外的一個(gè)參數(shù)來關(guān)聯(lián)一個(gè) Binder 代理對象和一個(gè) Java 服務(wù)代理對象, 這個(gè)參數(shù)就是全局變量gBinderProxyOffsets
的地址值.
注: Java 服務(wù)代理對象即: BinderProxy.
注: Binder 代理對象級: BpBinder.
最后返回這個(gè) Java 服務(wù)代理對象. 接著回到第 8 步. 繼續(xù)向下分析.
BinderInternal.getContextObject()
已經(jīng)分析完了, 它返回了一個(gè)句柄值等于 0 的Java 服務(wù)代理對象. 接下來就可以調(diào)用 ServiceManagerNative
類的靜態(tài)成員函數(shù) asInterface
將它封裝成一個(gè) ServiceManager 的 Java 代理對象了
private static IServiceManager sServiceManager;
private static IServiceManager getIServiceManager() {
if (sServiceManager != null) {
return sServiceManager;
}
...
sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject());
return sServiceManager;
}
11. ServiceManagerNative.asInterface 創(chuàng)建 ServiceManagerProxy 對象
源碼路徑: /frameworks/base/core/java/android/os/ServiceManagerNative.java
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);
}
參數(shù) obj
指向的是一個(gè) Java 服務(wù)代理對象.即一個(gè) BinderProxy 對象. 它的成員函數(shù) queryLocalInterface
的返回值為 NULL, 因此最后會(huì)創(chuàng)建一個(gè) ServiceManagerProxy
代理對象. 即 SM 的 Java 代理對象. 返回給調(diào)用者.
class ServiceManagerProxy implements IServiceManager {
public ServiceManagerProxy(IBinder remote) {
mRemote = remote;
}
}
ServiceManagerProxy
構(gòu)造方法中將傳入的Java 服務(wù)代理對象賦值給 ServiceManagerProxy
中的類成員變量 mRemote
.
注: mRemote 指向的是句柄值是 0 的 Java 服務(wù)代理對象, 即 BinderProxy, BinderProxy 在第 10 步被創(chuàng)建出來后又與 Binder 代理對象 BpBinder 進(jìn)行了關(guān)聯(lián).
現(xiàn)在第8步分析完成了, 最終返回了一個(gè) Java 代理對象 ServiceManagerProxy
, 繼續(xù)向上返回, 返回到第 7 步. 代碼如下.
public static void addService(String name, IBinder service, boolean allowIsolated) {
try {
getIServiceManager().addService(name, service, allowIsolated);
} catch (RemoteException e) {
Log.e(TAG, "error in addService", e);
}
}
看到又調(diào)用了 ServiceManagerProxy
中的函數(shù) addService
, 其中參數(shù) name
對應(yīng)的值為 activity
. service
為 AMS 對象.
12. ServiceManagerProxy.addService
源碼路徑: frameworks/base/core/java/android/os/ServiceManagerNative.java$ServiceManagerProxy.java
public void addService(String name, IBinder service, boolean allowIsolated)
throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
01 data.writeInterfaceToken(IServiceManager.descriptor);
02 data.writeString(name);
03 data.writeStrongBinder(service);
data.writeInt(allowIsolated ? 1 : 0);
04 mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0);
reply.recycle();
data.recycle();
}
創(chuàng)建了兩個(gè) Parcel
對象 data
與 reply
, data
是用來封裝進(jìn)程間通信數(shù)據(jù)的, reply
是用來封裝進(jìn)程間通信結(jié)果數(shù)據(jù)的.
代碼 01 處調(diào)用 Parcel
對象 data
的成員函數(shù) writeInterfaceToken
寫入一個(gè)進(jìn)程間通信頭.
代碼 02 處是寫入即將要注冊的 Java 服務(wù)的名稱. 這里的名稱為 activity
.
代碼 03 處寫入要注冊的 Java 服務(wù)對象.
代碼 04 處調(diào)用成員變量 mRemote
的 transact
函數(shù)向 SM 發(fā)送一個(gè)類型為 ADD_SERVICE_TRANSACTION
的進(jìn)程間通信請求, 即請求 SM 將一個(gè) Java 服務(wù)注冊進(jìn)去.
mRemote
在第 11 步中有強(qiáng)調(diào)過. 它指向一個(gè)句柄值為 0 的 Java 服務(wù)代理對象 BinderProxy.
這里呢先來分析 data.writeStrongBinder
看是如何將 AMS 寫入到 data
中的.
接著再來看 mRemote.transact
是如何處理這個(gè)進(jìn)程間通信請求的.
Parcel
是用來封裝進(jìn)程間通信數(shù)據(jù)的, Java 層中的每一個(gè)Parcel
對象在 C++層中都有一個(gè)對應(yīng)的Parcel
對象, 后者的地址就保存在前者的成員變量mObject
中. 當(dāng)將進(jìn)程間通信的數(shù)據(jù)封裝在一個(gè) Java 層的Parcel
對象時(shí), 這個(gè) Java 層中的Parcel
對象就會(huì)通過其成員變量mObject
找到與它對應(yīng)的運(yùn)行在 C++ 層中的Parcel
對象.并且將這些進(jìn)程間通信數(shù)據(jù)封裝到 C++ 層中的Parcel
對象里面去.
13. Parcel.writeStrongBinder
Java 層的 writeStrongBinder
是一個(gè) JNI 方法. 定義如下
源碼路徑: /frameworks/base/core/java/android/os/Parcel.java
public final void writeStrongBinder(IBinder val) {
nativeWriteStrongBinder(mNativePtr, val);
}
對應(yīng)的實(shí)現(xiàn)函數(shù)為 android_os_Parcel_writeStrongBinder
.
14. android_os_Parcel.android_os_Parcel_writeStrongBinder
源碼路徑: /frameworks/base/core/jni/android_os_Parcel.cpp
static void android_os_Parcel_writeStrongBinder(JNIEnv* env, jclass clazz, jlong nativePtr, jobject object)
{
01 Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
if (parcel != NULL) {
02 const status_t err = parcel->writeStrongBinder(ibinderForJavaObject(env, object));
...
}
}
代碼 01 處. 調(diào)用函數(shù) reinterpret_cast
得到一個(gè)與 Java 層 Parcel
對應(yīng)的, 運(yùn)行在 C++ 層的 Parcel
對象 parcel
.
代碼 02 處先調(diào)用函數(shù) ibinderForJavaObject
來獲得一個(gè)與他對應(yīng)的 Binder 本地對象, 再將這個(gè) Binder 本地對象寫入到上一步得到的 C++層的 Parcel
對象 parcel
中.
這里也分為兩步. 先看 ibinderForJavaObject
如何獲得一個(gè)對應(yīng)的 Binder 本地對象的.
接著再分析 writeStrongBinder
寫入.
15. android_util_Binder.ibinderForJavaObject
源碼路徑: /frameworks/base/core/jni/android_util_Binder.cpp
sp<IBinder> ibinderForJavaObject(JNIEnv* env, jobject obj)
{
...
//是否是 Java 服務(wù)
if (env->IsInstanceOf(obj, gBinderOffsets.mClass)) {
01 JavaBBinderHolder* jbh = (JavaBBinderHolder*) env->GetLongField(obj, gBinderOffsets.mObject);
return jbh != NULL ? jbh->get(env, obj) : NULL;
}
//是否是 Java 服務(wù)代理對象
if (env->IsInstanceOf(obj, gBinderProxyOffsets.mClass)) {
return (IBinder*) env->GetLongField(obj, gBinderProxyOffsets.mObject);
}
...
return NULL;
}
這兩個(gè) if
意思是 參數(shù) obj
要么指向一個(gè) Java 服務(wù), 要么指向一個(gè) Java 服務(wù)代理對象. 否則最后會(huì)返回 NULL, 表示它不能將參數(shù) obj
轉(zhuǎn)換成一個(gè) Binder 本地對象或者 Binder 代理對象.
此時(shí)我們傳入的 obj
是 AMS, 即是一個(gè) Java 服務(wù).所以命中第一個(gè) if
. gBinderOffsets.mObject
指向的是一個(gè) Java 服務(wù)的成員變量 mObject
中保存的與其對應(yīng)的一個(gè) JavaBBinderHolder
對象.
代碼 01 處就是將參數(shù) obj
即 AMS 服務(wù)對象的成員變量 mObject
轉(zhuǎn)換為一個(gè) JavaBBinderHolder
對象 jbh
.
接著調(diào)用 JavaBBinderHolder
對象的 jbh
的成員函數(shù) get
來獲得一個(gè) Binder 本地對象 BBinder.
如果傳入的
obj
是一個(gè) Java 服務(wù)代理對象, 那么命中第二個(gè)if
, 就找到與它對應(yīng)的一個(gè) Binder 代理對象. 并將這個(gè) Binder 代理對象返回給調(diào)用者. 在上面第 10 步中的 05 行代碼處創(chuàng)建好 Java 服務(wù)代理后將 Binder 代理服務(wù)對象的地址保存在 Java 服務(wù)代理對象的成員變量mObject
中. 因此這里可以輕易的根據(jù) Java 服務(wù)代理對象 BinderProxy 找到與之對應(yīng)的 Binder 代理對象 BpBinder.
16. JavaBBinderHolder.get 獲得 BBinder
源碼路徑: /frameworks/base/core/jni/android_util_Binder.cpp$JavaBBinderHolder
class JavaBBinderHolder : public RefBase
{
private:
...
wp<JavaBBinder> mBinder;
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;
}
}
成員變量 mBinder
指向的是一個(gè)類型為 JavaBBinder
的 Binder 本地對象.
參數(shù) obj
指向的是一個(gè) Java 服務(wù)即 AMS 服務(wù).
成員函數(shù) get
用來將成員變量 mBinder
所指向的一個(gè)JavaBBinder
對象返回給調(diào)用者. 由于成員變量 mBinder
是一個(gè)弱指針, 此時(shí)可能已經(jīng)被銷毀, 因此在返回給調(diào)用者之前, 先要調(diào)用 mBinder.promote()
將它升級為一個(gè)強(qiáng)指針, 如果升級成功, 直接返回給調(diào)用者.
否則就需要先創(chuàng)建一個(gè) JavaBBinder
對象, 將 AMS 服務(wù)傳入, 同時(shí)將結(jié)果保存在成員變量 mBinder
中.
17. new JavaBBinder
源碼路徑: /frameworks/base/core/jni/android_util_Binder.cpp$JavaBBinder
class JavaBBinder : public BBinder
{
private:
...
jobject const mObject;
public:
JavaBBinder(JNIEnv* env, jobject object)
: mVM(jnienv_to_javavm(env)), mObject(env->NewGlobalRef(object))
{
ALOGV("Creating JavaBBinder %p\n", this);
android_atomic_inc(&gNumLocalRefs);
incRefsCreated(env);
}
...
}
JavaBBinder
的 Binder 本地對象內(nèi)部也有一個(gè)成員變量 mObject
, 指向的是一個(gè) Java 服務(wù). 在構(gòu)造函數(shù)中被初始化. 流程走到這里 mObject
指向的就是 AMS 服務(wù).
好了, 第 14 步中的 ibinderForJavaObject
分析完了, 返回了一個(gè)了一個(gè) JavaBBinder
對象. 第 14 步代碼如下
static void android_os_Parcel_writeStrongBinder(JNIEnv* env, jclass clazz, jlong nativePtr, jobject object)
{
01 Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
if (parcel != NULL) {
02 const status_t err = parcel->writeStrongBinder(ibinderForJavaObject(env, object));
...
}
}
接著調(diào)用 parcel->writeStrongBinder
函數(shù), 傳入?yún)?shù)為 JavaBBinder
對象.
18. parcel->writeStrongBinder
源碼路徑: /frameworks/native/libs/binder/Parcel.cpp
status_t Parcel::writeStrongBinder(const sp<IBinder>& val)
{
return flatten_binder(ProcessState::self(), val, this);
}
這一步操作是調(diào)用全局函數(shù) flatten_binder
將 JavaBBinder
封裝成為一個(gè) flat_binder_object
結(jié)構(gòu)體.
19. parcel->flatten_binder
源碼路徑: /frameworks/native/libs/binder/Parcel.cpp
status_t flatten_binder(const sp<ProcessState>& /*proc*/,
const sp<IBinder>& binder, Parcel* out)
{
flat_binder_object obj;
...
if (binder != NULL) {
IBinder *local = binder->localBinder();
if (!local) {
...
} else {
obj.type = BINDER_TYPE_BINDER;
obj.binder = reinterpret_cast<uintptr_t>(local->getWeakRefs());
obj.cookie = reinterpret_cast<uintptr_t>(local);
}
} else {
...
}
return finish_flatten_binder(binder, obj, out);
}
首先定義了一個(gè) flat_binder_object
結(jié)構(gòu)體 obj
. 接著判參數(shù) binder
是否為 NULL, 我們傳入的參數(shù)是 JavaBBinder
對象不為 NULL, 所以直接命中 if
.
通過前面的調(diào)用知道參數(shù) binder
指向的是 JavaBBinder
, 它繼承了 BBinder. 而 BBinder 又是用來描述一個(gè) Binder 本地對象的. 因此 localBinder
函數(shù)返回不為 NULL. 所以 if(!local)
不會(huì)命中, 而是直接執(zhí)行 else
中的代碼. 將flat_binder_object
結(jié)構(gòu)體 obj
設(shè)置為一個(gè) BINDER_TYPE_BINDER
類型的 Binder 對象, 并且將它的成員變量 cookie
和 binder
的值分別設(shè)置為 Binder 本地對象 local
的地址以及其內(nèi)部的一個(gè)弱引用計(jì)數(shù)對象的地址值.
最后調(diào)用全局函數(shù) finish_flatten_binder
將 obj
寫入到 Parcel 對象 out
中.
當(dāng)結(jié)構(gòu)體 flat_binder_object 描述的是一個(gè) Binder 實(shí)體對象時(shí), 就使用成員變量 binder 來指向與該 Binder 實(shí)體對象對應(yīng)的一個(gè) Service 組件內(nèi)部的一個(gè)弱引用計(jì)數(shù)對象的地址, 并且使用成員變量 cookie 來指向該 Service 組件的地址.
當(dāng)結(jié)構(gòu)體 flat_binder_object 描述的是一個(gè) Binder 引用對象時(shí), 那么就使用成員變量 handle 來描述該 Binder 引用對象的句柄值.
20. parcel->finish_flatten_binder
源碼路徑: /frameworks/native/libs/binder/Parcel.cpp
inline static status_t finish_flatten_binder(
const sp<IBinder>& /*binder*/, const flat_binder_object& flat, Parcel* out)
{
return out->writeObject(flat, false);
}
至此, 在第 12 步中的 data.writeStrongBinder(service);
到這里就分析完了. 在第 12 步中傳入的 AMS 服務(wù), 到最后寫入的實(shí)際上是一個(gè) flat_binder_object
結(jié)構(gòu)體. 接下來繼續(xù)分析第 12 步中的下一個(gè)操作. 第 12 步代碼如下
public void addService(String name, IBinder service, boolean allowIsolated)
throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
01 data.writeInterfaceToken(IServiceManager.descriptor);
02 data.writeString(name);
03 data.writeStrongBinder(service);
data.writeInt(allowIsolated ? 1 : 0);
04 mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0);
reply.recycle();
data.recycle();
}
代碼 04 處調(diào)用成員變量 mRemote 的 transact 函數(shù)向 SM 發(fā)送一個(gè)類型為 ADD_SERVICE_TRANSACTION
的進(jìn)程間通信請求, 即請求 SM 將一個(gè) Java 服務(wù)注冊進(jìn)去. mRemote
即 BinderProxy. 指向一個(gè)句柄值為 0 的 Java 服務(wù)代理對象.
21. BinderProxy.transact 開始發(fā)送進(jìn)程間通信請求.
BinderProxy
類的成員函數(shù) transact
是一個(gè) JNI 方法. 定義如下
public boolean transact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {
Binder.checkParcel(this, code, data, "Unreasonably large binder buffer");
return transactNative(code, data, reply, flags);
}
public native boolean transactNative(int code, Parcel data, Parcel reply, int flags) throws RemoteException;
對應(yīng)的實(shí)現(xiàn)在 android_util_Binder.cpp
中的 android_os_BinderProxy_transact
函數(shù).
22. android_util_Binder.android_os_BinderProxy_transact
源碼路徑 /frameworks/base/core/jni/android_util_Binder.cpp
static jboolean android_os_BinderProxy_transact(JNIEnv* env, jobject obj,
jint code, jobject dataObj, jobject replyObj, jint flags) // throws RemoteException
{
...
01 Parcel* data = parcelForJavaObject(env, dataObj);
...
02 Parcel* reply = parcelForJavaObject(env, replyObj);
...
03 IBinder* target = (IBinder*) env->GetLongField(obj, gBinderProxyOffsets.mObject);
...
04 status_t err = target->transact(code, *data, reply, flags);
...
}
代碼 01 處與 02 處分別將 Java 層中的兩個(gè) Parcel 對象 dataObj
, replyObj
轉(zhuǎn)為 C++層中的 Parcel 對象data
,reply
. data
中包含了要傳遞給 SM 的進(jìn)程間通信數(shù)據(jù), reply
用來保存從 SM 返回的數(shù)據(jù)結(jié)果.
參數(shù) obj
指向的是一個(gè) Java 服務(wù)代理對象, 即 BinderProxy.
代碼 03 處就是獲得這個(gè)代理對象的 Binder 代理對象. 即 BpBinder. 保存到變量 target
中.
代碼 04 處調(diào)用 target
的成員函數(shù) transact
想 SM 發(fā)送一個(gè)類型為 code
的進(jìn)程間通信請求. code
值為 ADD_SERVICE_TRANSACTION
. 當(dāng) SM 收到這個(gè)進(jìn)程間通信請求后, 就會(huì)將保存在 Parcel對象 data
中的一個(gè) Binder 本地對象的信息取出來后注冊到它的內(nèi)部去. 那現(xiàn)在進(jìn)入到 BpBinder 的 transact
函數(shù)內(nèi).
data 中保存的 Binder 本地對象信息即在第 13 - 20 步中寫入的 flat_binder_object 結(jié)構(gòu)體, 在 19 步中將這個(gè)結(jié)構(gòu)體的成員變量 cookie 設(shè)置為 Binder 本地對象. 這個(gè)本地對象是在 17 步中創(chuàng)建的 JavaBBinder.
23. BpBinder.transact
源碼路徑: /frameworks/native/libs/binder/BpBinder.cpp
status_t BpBinder::transact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
if (mAlive) {
status_t status = IPCThreadState::self()->transact(mHandle, code, data, reply, flags);
if (status == DEAD_OBJECT) mAlive = 0;
return status;
}
return DEAD_OBJECT;
}
從前面的調(diào)用過程可以知道, 第一個(gè)參數(shù) code
值為 ADD_SERVICE_TRANSACTION
, 第二個(gè)參數(shù) data
包含了要傳遞給 Binder 驅(qū)動(dòng)程序進(jìn)程間通信數(shù)據(jù). 第三個(gè)參數(shù) reply
是一個(gè)輸出參數(shù), 用來保存進(jìn)程間通信的結(jié)果. 第四個(gè)參數(shù) flags
用來描述這是一個(gè)同步的進(jìn)程間通信請求還是異步的. 默認(rèn)值為 0, 表示同步.
成員變量 mAlive
用來描述 Binder 代理對象所引用的 Binder 本地對象是否還活著, 如果還活著,即值為 1. 在 if
內(nèi)才會(huì)調(diào)用當(dāng)前線程的 IPCThreadState
對象的成員函數(shù) transact
想 Binder 驅(qū)動(dòng)發(fā)送一個(gè) BC_TRANSACTION
命令協(xié)議.
Binder 代理對象中的成員變量 mHandle
用來描述該 Binder 代理對象的句柄值. 由于目前正在處理的 Binder 代理對象指向的是 SM 的代理對象. 因此 mHandle
的值就等于 0.
現(xiàn)在進(jìn)入 IPCThreadState
的 transact
函數(shù).
24.IPCThreadState.transact 向 Binder 驅(qū)動(dòng)程序發(fā)送 BC_TRANSACTION 命令協(xié)議
源碼路徑: /frameworks/native/libs/binder/IPCThreadState.cpp
status_t IPCThreadState::transact(int32_t handle,
uint32_t code, const Parcel& data,
Parcel* reply, uint32_t flags)
{
01 status_t err = data.errorCheck();
02 flags |= TF_ACCEPT_FDS;
...
if (err == NO_ERROR) {
...
03 err = writeTransactionData(BC_TRANSACTION, flags, handle, code, data, NULL);
}
...
04 if ((flags & TF_ONE_WAY) == 0) {
...
if (reply) {
05 err = waitForResponse(reply);
} else {
...
}
...
} else {
...
}
return err;
}
代碼 01 處是檢查 Parcel 對象 data
中的進(jìn)程間通信數(shù)據(jù)是否正確.
代碼 02 處將參數(shù) flag
的 TF_ACCEPT_FDS
位設(shè)置為 1, 表示允許 Server 進(jìn)程在返回結(jié)果中攜帶文件描述.
如果 data
中的數(shù)據(jù)沒有問題, 執(zhí)行代碼 03 處. 調(diào)用成員函數(shù) writeTransactionData
將它的內(nèi)容寫到一個(gè) binder_transaction_data
結(jié)構(gòu)體中.
代碼 04 處判斷是同步請求還是異步請求, 本次為同步請求, 接著判斷用來保存通信結(jié)果的 reply
是否為 NULL, 不為 NULL 就調(diào)用成員函數(shù) waitForResponse
向 Binder 驅(qū)動(dòng)程序發(fā)送一個(gè) BC_TRANSACTION
命令協(xié)議.
接下來主要是分析兩個(gè)函數(shù), writeTransactionData
與 waitForResponse
的實(shí)現(xiàn)
25. IPCThreadState.writeTransactionData
源碼路徑: /frameworks/native/libs/binder/IPCThreadState.cpp
status_t IPCThreadState::writeTransactionData(int32_t cmd, uint32_t binderFlags,
int32_t handle, uint32_t code, const Parcel& data, status_t* statusBuffer)
{
01 binder_transaction_data tr;
...
tr.target.handle = handle;
tr.code = code;
tr.flags = binderFlags;
...
02 const status_t err = data.errorCheck();
if (err == NO_ERROR) {
tr.data_size = data.ipcDataSize();
tr.data.ptr.buffer = data.ipcData();
tr.offsets_size = data.ipcObjectsCount()*sizeof(binder_size_t);
tr.data.ptr.offsets = data.ipcObjects();
} else if (statusBuffer) {
...
} else {
...
}
03 mOut.writeInt32(cmd);
04 mOut.write(&tr, sizeof(tr));
return NO_ERROR;
}
在代碼 01 處, 先定義了一個(gè) binder_transaction_data
結(jié)構(gòu)體 tr
, 接著下面幾行代碼就對它進(jìn)行了初始化操作. 經(jīng)過前面調(diào)用已知 handle = 0, code = ADD_SERVICE_TRANSACTION, binderFlags = TF_ACCEPT_FDS
.
代碼 02 處再次確認(rèn) data
中進(jìn)程間通信數(shù)據(jù)的正確性. 如果沒有問題則命中if
.
將 data
內(nèi)部的數(shù)據(jù)緩沖區(qū)和偏移數(shù)組設(shè)置為 binder_transaction_data
結(jié)構(gòu)體 tr
的數(shù)據(jù)緩沖區(qū)與偏移數(shù)組.
代碼 03 與 04 處將 BC_TRANSACTION
命令協(xié)議以及 binder_transaction_data
寫入到 IPCThreadState
成員變量 mOut
所描述的一個(gè)命令協(xié)議緩沖區(qū)中. 表示它有一個(gè) BC_TRANSACTION
命令協(xié)議需要發(fā)送給 Binder 驅(qū)動(dòng)程序處理.
將 BC_TRANSACTION
命令協(xié)議寫入到 IPCThreadState
類內(nèi)部的命令協(xié)議緩沖區(qū)后, 回到 第 24 步. 接下來就需要調(diào)用成員函數(shù) waitForResponse
向 Binder 驅(qū)動(dòng)程序發(fā)送這個(gè)命令協(xié)議了.
26. IPCThreadState.waitForResponse
源碼路徑: /frameworks/native/libs/binder/IPCThreadState.cpp
status_t IPCThreadState::waitForResponse(Parcel *reply, status_t *acquireResult)
{
uint32_t cmd;
int32_t err;
while (1) {
if ((err=talkWithDriver()) < NO_ERROR) break;
...
}
return err;
}
通過一個(gè) while
循環(huán)不斷的調(diào)用成員函數(shù) talkWithDriver
來與 Binder 驅(qū)動(dòng)程序進(jìn)行交互. 以便可以將在第 25 步中準(zhǔn)備好的 BC_TRANSACTION
命令協(xié)議發(fā)送給 Binder 驅(qū)動(dòng)程序處理. 并等待 Binder 驅(qū)動(dòng)程序?qū)⑦M(jìn)程通信結(jié)果返回回來.
OK. 其實(shí)一路分析到這里, 才算是開始. 現(xiàn)在進(jìn)入 talkWithDriver
27. IPCThreadState.talkWithDriver
源碼路徑: /frameworks/native/libs/binder/IPCThreadState.cpp
//參數(shù) doReceive 用來描述調(diào)用者是否希望函數(shù) talkWithDriver
//只接受 Binder 驅(qū)動(dòng)程序發(fā)送給該進(jìn)程的返回協(xié)議. 該參數(shù)默認(rèn)為 `true`.
status_t IPCThreadState::talkWithDriver(bool doReceive)
{
...
//talkWithDriver 函數(shù)使用 IO 控制命令 BINDER_WRITE_READ 來與 Binder 驅(qū)動(dòng)程序進(jìn)行交互
//因此這里需要先定義一個(gè)結(jié)構(gòu)體來指定輸入緩沖區(qū)和輸出緩沖區(qū).
//其中輸出緩沖區(qū)是保存的是進(jìn)程發(fā)給 Binder 驅(qū)動(dòng)程序的命令協(xié)議,
//而輸入緩沖區(qū)保存的是 Binder 驅(qū)動(dòng)程序發(fā)送給進(jìn)程的返回協(xié)議,
//它們分別與 `IPCThreadState` 類內(nèi)部的命令協(xié)議緩沖區(qū) `mOut` 和返回協(xié)議緩沖區(qū) `mIn` 相對應(yīng).
binder_write_read bwr;
01 const bool needRead = mIn.dataPosition() >= mIn.dataSize();
02 const size_t outAvail = (!doReceive || needRead) ? mOut.dataSize() : 0;
//將變量 write_size 的值設(shè)置為 binder_write_read 結(jié)構(gòu)體 bwr 的
//輸出緩沖區(qū)的長度 write_size
bwr.write_size = outAvail;
//將 IPCThreadState 類內(nèi)部的命令協(xié)議緩沖區(qū) mOut
//設(shè)置為 binder_write_read 結(jié)構(gòu)體 bwr 的輸出緩沖區(qū).
bwr.write_buffer = (uintptr_t)mOut.data();
03 if (doReceive && needRead) {
bwr.read_size = mIn.dataCapacity();
bwr.read_buffer = (uintptr_t)mIn.data();
} else {
bwr.read_size = 0;
bwr.read_buffer = 0;
}
...
04 do {
...
if (ioctl(mProcess->mDriverFD, BINDER_WRITE_READ, &bwr) >= 0)
err = NO_ERROR;
else
err = -errno;
...
05 } while (err == -EINTR);
...
if (err >= NO_ERROR) {
06 if (bwr.write_consumed > 0) {
if (bwr.write_consumed < mOut.dataSize())
mOut.remove(0, bwr.write_consumed);
else
mOut.setDataSize(0);
07 }
if (bwr.read_consumed > 0) {
mIn.setDataSize(bwr.read_consumed);
08 mIn.setDataPosition(0);
}
...
return NO_ERROR;
}
return err;
}
從前面的調(diào)用可知, mOut
中存在一個(gè) BC_TRANSACTION
命令協(xié)議.
在
IPCThreadState
內(nèi)部, 除了使用緩沖區(qū)mOut
來保存即將要發(fā)送給 Binder 驅(qū)動(dòng)程序的命令協(xié)議外, 還用緩沖區(qū)mIn
來保存那些從 Binder 驅(qū)動(dòng)程序接收到的返回協(xié)議
一個(gè)進(jìn)程使用 IO 控制命令 BINDER_WRITE_READ
進(jìn)入到 Binder 驅(qū)動(dòng)程序, 傳遞的 binder_write_read
結(jié)構(gòu)體的輸出緩沖區(qū)和輸入緩沖區(qū)的長度分別等于 0 和大于 0 時(shí), Binder 驅(qū)動(dòng)程序就不會(huì)處理進(jìn)程發(fā)送的命令協(xié)議, 而只會(huì)對該進(jìn)程發(fā)送返回命令協(xié)議, 這樣進(jìn)程就達(dá)到了接收返回協(xié)議的結(jié)果.
只接收返回協(xié)議還會(huì)受到返回協(xié)議緩沖區(qū) mIn
的影響. 如果上次 Binder 發(fā)送給進(jìn)程的返回協(xié)議已經(jīng)處理完成, 即返回協(xié)議緩沖區(qū) mIn
中的返回協(xié)議已經(jīng)處理完成, 那么即使參數(shù) doReceive
為 true
, IPCThreadState
的成員函數(shù) talkWithDriver
也會(huì)向 Binder 驅(qū)動(dòng)程序發(fā)送命令協(xié)議.
因此如果返回協(xié)議緩沖區(qū) mIn
的返回協(xié)議已經(jīng)處理完成, 即代碼 01 處得到的 needRead
變量值為 true
. 或者調(diào)用者不是只希望接收 Binder 驅(qū)動(dòng)程序發(fā)送給進(jìn)程的返回協(xié)議, 及參數(shù) doReceive
為 false
, 那么代碼 02 處就將變量 outAvail
的值設(shè)置為 IPCThreadState
類內(nèi)部的命令協(xié)議緩沖區(qū)的長度. 否則就設(shè)置為 0.
從前面的調(diào)用過程可以知道, 參數(shù) doReceive
的值為 true
, 假設(shè)此時(shí) IPCThreadState
類內(nèi)部的返回協(xié)議緩沖區(qū) mIn
沒有包含未處理的返回協(xié)議, 那么 needRead
值為 true
. 命中代碼 03 處 if
判斷. 在判斷內(nèi)將 binder_write_read
結(jié)構(gòu)體 bwr
的輸入緩沖區(qū) read_buffer
設(shè)置為類內(nèi)部的返回協(xié)議緩沖區(qū) mIn
.
代碼 04 處到 05 處的 while
循環(huán)使用 IO 控制命令 BINDER_WRITE_READ
來與 Binder 驅(qū)動(dòng)程序進(jìn)行交互. 由于這時(shí)候傳遞給 Binder 驅(qū)動(dòng)程序的 binder_write_read
結(jié)構(gòu)體 bwr
輸出緩沖區(qū)的長度 write_size
和 輸入緩沖區(qū) read_size
的長度均大于 0. 因此 Binder 驅(qū)動(dòng)程序在處理 IO 控制命令 BINDER_WRITE_READ
時(shí), 就會(huì)首先調(diào)用函數(shù) binder_thread_write
來處理進(jìn)程發(fā)送給它的 BC_TRANSACTION
命令協(xié)議. 接著又會(huì)調(diào)用函數(shù) binder_thread_read
來讀取 Binder 驅(qū)動(dòng)程序給進(jìn)程發(fā)送的返回協(xié)議.
當(dāng)從驅(qū)動(dòng)層返回后, 代碼 06-07 處將 Binder 驅(qū)動(dòng)程序已經(jīng)處理的命令協(xié)議從 IPCThreadState
類內(nèi)部的命令協(xié)議緩沖區(qū) mOut
中移除, 接著在代碼 08 處將從 Binder 驅(qū)動(dòng)程序中讀取出來的返回協(xié)議保存在類內(nèi)部的返回協(xié)議緩沖區(qū) mIn
中. 這樣這個(gè)函數(shù)執(zhí)行完再返回到第 26 步的時(shí)候. 就可以通過解析返回協(xié)議緩沖區(qū) mIn
的內(nèi)容來執(zhí)行相對應(yīng)的操作了.
現(xiàn)在就要進(jìn)入到 Binder 驅(qū)動(dòng)層了, 來分析是如何處理這個(gè)命令協(xié)議的.
28. binder_ioctl_write_read
源碼路徑: kernel 3.18下的 /drivers/staging/android/binder.c
static int binder_ioctl_write_read(struct file *filp,
unsigned int cmd, unsigned long arg,
struct binder_thread *thread)
{
...
...
ret = binder_thread_write(proc, thread,
bwr.write_buffer,
bwr.write_size,
&bwr.write_consumed);
...
}
直接進(jìn)入到 binder_thread_write
函數(shù)
29. binder_thread_write
源碼路徑: kernel 3.18下的 /drivers/staging/android/binder.c
static int binder_thread_write(struct binder_proc *proc,
struct binder_thread *thread,
binder_uintptr_t binder_buffer, size_t size,
binder_size_t *consumed)
{
while (ptr < end && thread->return_error == BR_OK) {
switch (cmd) {
...
case BC_TRANSACTION:
case BC_REPLY: {
...
binder_transaction(proc, thread, &tr, cmd == BC_REPLY, 0);
break;
}
...
}
*consumed = ptr - buffer;
}
return 0;
}
從代碼中可以看出又調(diào)用了 binder_transaction
函數(shù). 進(jìn)入到這個(gè)函數(shù). 傳入的參數(shù)中
cmd == BC_REPLY
值為 false, 因?yàn)檫@個(gè)時(shí)候 cmd
的值為 BC_TRANSACTION
.
30. binder_transaction
源碼路徑: kernel 3.18下的 /drivers/staging/android/binder.c
這個(gè)函數(shù)有點(diǎn)長, 將會(huì)分為四段來分析.
static void binder_transaction(struct binder_proc *proc,
struct binder_thread *thread,
struct binder_transaction_data *tr, int reply,
binder_size_t extra_buffers_size)
{
struct binder_proc *target_proc;
struct binder_node *target_node = NULL;
...
if (reply) {
...
} else {
if (tr->target.handle) {
...
01 } else {
target_node = context->binder_context_mgr_node;
...
}
...
02 target_proc = target_node->proc;
...
}
03 if (target_thread) {
e->to_thread = target_thread->pid;
target_list = &target_thread->todo;
target_wait = &target_thread->wait;
} else {
target_list = &target_proc->todo;
target_wait = &target_proc->wait;
}
在上一步知道 reply
為 fale
, 所以直接進(jìn) else
. 由于目標(biāo) Binder 的引用對象的句柄值為 0, 所以直接執(zhí)行代碼 01 處的 else
邏輯. 將目標(biāo) Binder 實(shí)體對象 target_node
指向一個(gè)引用了 SM 的 Binder 實(shí)體對象 binder_context_mgr_node
. 如果進(jìn)的是 if
就需要先獲得與句柄值對應(yīng)的 Binder 引用對象. 再通過這個(gè)引用對象的成員變量 node
來找到目標(biāo) Binder 實(shí)體對象 target_node
.
binder_context_mgr_node
的賦值是在 上一章 Android Service Manager 的啟動(dòng)流程中的第6 步忘記的,可以返回去看一下.
找到了目標(biāo) Binder 實(shí)體對象以后, 代碼 02 處就可以根據(jù)它的成員變量 proc
來找到目標(biāo)進(jìn)程 target_proc
.
如果在目標(biāo)進(jìn)程 target_proc
中找到了一個(gè)最優(yōu)的目標(biāo)線程 target_thread
來接收 BR_TRANSACTION
返回協(xié)議那么就命中代碼 03 處 if
, 將變量 target_list
與 target_wait
分別指向最優(yōu)線程的 todo
與 wait
隊(duì)列.. 否則就指向目標(biāo)進(jìn)程的 todo
與 wait
隊(duì)列. 有了這兩個(gè)隊(duì)列后, 函數(shù)接下來就可以將一個(gè) BR_TRANSACTION
返回協(xié)議相關(guān)的待處理工作項(xiàng)加入到 todo
隊(duì)列中. 以及通過等待隊(duì)列將目標(biāo)進(jìn)程或線程喚醒來處理這個(gè)工作項(xiàng).
binder_transaction
函數(shù)第二部分代碼
01 t = kzalloc(sizeof(*t), GFP_KERNEL);
...
02 tcomplete = kzalloc(sizeof(*tcomplete), GFP_KERNEL);
...
03 if (!reply && !(tr->flags & TF_ONE_WAY))
t->from = thread;
else
t->from = NULL;
...
...
04 t->buffer = binder_alloc_buf(target_proc, tr->data_size, tr->offsets_size, extra_buffers_size, !reply && (t->flags & TF_ONE_WAY));
...
if (target_node)
binder_inc_node(target_node, 1, 0, NULL);
...
05 if (copy_from_user(t->buffer->data, (const void __user *)(uintptr_t)
tr->data.ptr.buffer, tr->data_size)) {
}
06 if (copy_from_user(offp, (const void __user *)(uintptr_t)
tr->data.ptr.offsets, tr->offsets_size)) {
}
代碼 01 處分配一個(gè) binder_transaction
結(jié)構(gòu)體 t
, 后面會(huì)將它封裝為一個(gè) BINDER_WORKTRANSACTION
類型的工作項(xiàng)加入到目標(biāo)的 todo
隊(duì)列中. 以便目標(biāo)線程可以接收到一個(gè) BR_TRANSACTION
返回協(xié)議.
代碼 02 處分配了一個(gè) binder_work
結(jié)構(gòu)體 tcomplete
. 后面會(huì)將它封裝成一個(gè) BINDER_WORK_TRANSACTION_COMPLETE
類型的工作項(xiàng)加入到源線程的 todo
隊(duì)列中, 以便該線程知道可以馬上返回用戶空間. 并且知道它之前發(fā)送給 Binder 驅(qū)動(dòng)程序的 BC_TRANSACTION
命令協(xié)議已經(jīng)被接收了.
代碼 03 處判斷如果正在處理的是一個(gè) BC_TRANSACTION
命令協(xié)議. 并不且它所描述的是一個(gè)同步的進(jìn)程間通信請求, 那么命中 if
就會(huì)將 binder_transaction
結(jié)構(gòu)體 t
的成員變量 from
指向源線程, 以便目標(biāo)進(jìn)程 target_proc
或者目標(biāo)線程 target_thread
處理完該進(jìn)程間通信請求之后, 能夠找到發(fā)出改進(jìn)程通信請求的線程. 最終將通信結(jié)果返回給它.
代碼 04 處是為 binder_transaction
結(jié)構(gòu)體 t
分配內(nèi)核緩沖區(qū), 以便可以將進(jìn)程間通信結(jié)果拷貝到它里面, 最后傳遞給目標(biāo)進(jìn)程 target_proc
或者目標(biāo)線程處理.
當(dāng)前目標(biāo)進(jìn)程為 SM . 源線程/進(jìn)程為 AMS
代碼 05, 06 處是分別將 binder_transaction
結(jié)構(gòu)體 tr
的數(shù)據(jù)緩沖區(qū)以及偏移數(shù)組的內(nèi)容拷貝到在代碼 04 處為 binder_transaction
結(jié)構(gòu)體 t
分配的內(nèi)核緩沖區(qū)中.
binder_transaction
函數(shù)第三部分代碼
for (; offp < off_end; offp++) {
struct binder_object_header *hdr;
...
switch (hdr->type) {
case BINDER_TYPE_BINDER:
case BINDER_TYPE_WEAK_BINDER: {
01 struct flat_binder_object *fp;
02 struct binder_ref *ref;
03 fp = to_flat_binder_object(hdr);
04 ret = binder_translate_binder(fp, t, thread);
if (ret < 0) {
return_error = BR_FAILED_REPLY;
goto err_translate_failed;
}
} break;
...
}
這整個(gè) for
循環(huán)就是依次處理進(jìn)程間通信數(shù)據(jù)中的 Binder 對象. 如果 Binder 驅(qū)動(dòng)程序是第一次碰到這些 Binder 對象, 那么 Binder 驅(qū)動(dòng)程序就會(huì)根據(jù)它們的類型分別創(chuàng)建一個(gè) Binder 實(shí)體對象或者 Binder 引用對象.
否則, 就會(huì)將之前為他們創(chuàng)建的 Binder 實(shí)體對象或者 Binder 引用對象獲取回來, 增加引用計(jì)數(shù), 避免過早銷毀.
代碼 01 處定義一個(gè) flat_binder_object
結(jié)構(gòu)體 fp
.
從第 19 步的調(diào)用可以知道, 進(jìn)程間通信數(shù)據(jù)中包含一個(gè)類型為
BINDER_TYPE_BINDER
的 Binder 對象, 即一個(gè)flat_binder_object
結(jié)構(gòu)體. 用來描述即將要注冊到 SM 中的 Service 組件 AMS.
代碼 02 處定義一個(gè) binder_ref
結(jié)構(gòu)體 ref
. 表示 Binder 的引用對象.
代碼 03 處獲取獲取在 19 步寫入的 flat_binder_object
結(jié)構(gòu)體, 保存在 fp
中.
主要分析代碼 04 處 binder_translate_binder
函數(shù). 進(jìn)去看一下
31. binder_translate_binder
源碼路徑: kernel 3.18下的 /drivers/staging/android/binder.c
static int binder_translate_binder(struct flat_binder_object *fp,
struct binder_transaction *t,
struct binder_thread *thread)
{
...
01 node = binder_get_node(proc, fp->binder);
02 if (!node) {
...
}
...
03 ref = binder_get_ref_for_node(target_proc, node);
...
if (fp->hdr.type == BINDER_TYPE_BINDER)
04 fp->hdr.type = BINDER_TYPE_HANDLE;
else
fp->hdr.type = BINDER_TYPE_WEAK_HANDLE;
fp->binder = 0;
fp->handle = ref->desc;
fp->cookie = 0;
05 binder_inc_ref(ref, fp->hdr.type == BINDER_TYPE_HANDLE, &thread->todo);
...
return 0;
}
代碼 01 處獲得 Binder 實(shí)體對象 node
. 接著在代碼 02 處判斷是否為 NULL, 此處我們獲得的 Binder 實(shí)體對象不為 NULL,
binder_get_node
函數(shù)是根據(jù)flat_binder_object
結(jié)構(gòu)體中弱引用計(jì)數(shù)對象的地址binder
在目標(biāo)進(jìn)程proc
中找到一個(gè)對應(yīng)的 Binder 實(shí)體對象. 在第 19 步中被賦值.
在代碼 03 處調(diào)用 binder_get_ref_for_node
函數(shù), 在目標(biāo)進(jìn)程 target_proc
中創(chuàng)建一個(gè) Binder 引用對象來引用該 Service 組件 AMS.
在代碼 04 處將 flat_binder_object
結(jié)構(gòu)體 fp
的類型修改為 BINDER_TYPE_HANDLE
, 并設(shè)置好它的句柄值. 這是因?yàn)楫?dāng) Binder 驅(qū)動(dòng)程序?qū)⑦M(jìn)程間通信數(shù)據(jù)傳遞給目標(biāo)進(jìn)程 target_proc
時(shí), 進(jìn)程間通信數(shù)據(jù)中的 Binder 實(shí)體對象就變量 Binder 引用對象. 所以需要修改它的類型.
在目標(biāo)進(jìn)程 target_proc
創(chuàng)建好一個(gè) Binder 引用對象 ref
后, 接著就要將它傳遞給該目標(biāo)進(jìn)程了. 在傳遞過程中, 必須要保證 Binder 引用對象 ref
不會(huì)被銷毀, 因此在代碼 05 處調(diào)用函數(shù) binder_inc_ref
來增加它的引用計(jì)數(shù).
繼續(xù)回到 binder_transaction
中, 看第三部分代碼
32. binder_transaction 發(fā)送進(jìn)程間通信
第四部分代碼
01 if (reply) {
...
02 } else if (!(t->flags & TF_ONE_WAY)) {
t->need_reply = 1;
t->from_parent = thread->transaction_stack;
thread->transaction_stack = t;
} else {
...
}
03 t->work.type = BINDER_WORK_TRANSACTION;
04 list_add_tail(&t->work.entry, target_list);
05 tcomplete->type = BINDER_WORK_TRANSACTION_COMPLETE;
06 list_add_tail(&tcomplete->entry, &thread->todo);
07 if (target_wait)
08 wake_up_interruptible(target_wait);
代碼 01 處值為 false
在第 29 步中有說明.
代碼 02 處判斷正常處理的是否是一個(gè)同步的進(jìn)程間通信請求, 即 binder_transaction
接頭體 t
的成員變量 flags
的 TF_ONE_WAY
為等于 0. 那么命中 else if
, 設(shè)置它的成員變量 need_reply
的值為 1, 表示它需要等待回復(fù). 接著將事務(wù) t
壓入到源線程 thread
的事務(wù)堆棧 transaction_stack
中.
代碼 03 與 04 處將 binder_transaction
結(jié)構(gòu)體 t
封裝成一個(gè)類型為 BINDER_WORK_TRANSACTION
的工作項(xiàng)添加到目標(biāo)進(jìn)程 target_proc
或者目標(biāo)線程 target_thread
的 todo
隊(duì)列中, 并且在 08 行代碼處將目標(biāo)進(jìn)程喚醒, 以便處理該工作項(xiàng).
在 Android Service Manager 的啟動(dòng)流程 一文中的第 12 步分析 3 處調(diào)用了
wait_event_freezable_exclusive
函數(shù)進(jìn)行睡眠等待直到其所屬的進(jìn)程有新的未處理工作項(xiàng). 所以接下來分析SM的時(shí)候, 直接從binder_thread_read
處接著分析 SM 被喚醒后的操作.
如果目標(biāo)進(jìn)程
todo
隊(duì)列target_list
指向的是一個(gè) Binder 實(shí)體對象的異步事務(wù)隊(duì)列async_todo
, 那么目標(biāo)wait
等待隊(duì)列target_wait
就會(huì)等于 NULL, 這時(shí)候就不需要喚醒目標(biāo)進(jìn)程.
代碼 05 與 06 行代碼處將 binder_work
結(jié)構(gòu)體 tcomplete
封裝成一個(gè)類型為 BINDER_WORK_TRANSACTION_COMPLETE
的工作項(xiàng)添加到源線程的 todo
隊(duì)列中, 以便它從 Binder 驅(qū)動(dòng)程序返回到用戶空間之前, 可以處理該工作項(xiàng).
程序執(zhí)行到這里, 源線程, 目標(biāo)進(jìn)程或者目標(biāo)線程就會(huì)并發(fā)的去處理各自 todo
隊(duì)列中的工作項(xiàng). 為了方便描述,
假設(shè)源線程會(huì)首先它的 todo
隊(duì)列中類型為BINDER_WORK_TRANSACTION_COMPLETE
的工作項(xiàng).
接著目標(biāo)進(jìn)程再處理它隊(duì)列中的類型為 BINDER_WORK_TRANSACTION
的工作項(xiàng).
注:
此時(shí)源線程為 AMS 進(jìn)程中請求注冊 Service 組件的線程與目標(biāo)進(jìn)程 SM 需要處理的工作項(xiàng)類型如下
- 源線程: ActivityManagerService 要處理的工作項(xiàng)類型為:
BINDER_WORK_TRANSACTION_COMPLETE
- 目標(biāo)進(jìn)程 SM. 需要處理的工作項(xiàng)類型為
BINDER_WORK_TRANSACTION
.
未完待續(xù)......