1. 程式人生 > >Android系統服務(SystemService)簡介

Android系統服務(SystemService)簡介

什麼是SystemService

我們在Android開發過程中經常會用到各種各樣的系統管理服務,如進行視窗相關的操作會用到視窗管理服務WindowManager,進行電源相關的操作會用到電源管理服務PowerManager,還有很多其他的系統管理服務,如通知管理服務NotifacationManager、振動管理服務Vibrator、電池管理服務BatteryManager…… 這些Manager提供了很多對系統層的控制介面。對於App開發者,只需要瞭解這些介面的使用方式就可以方便的進行系統控制,獲得系統各個服務的資訊,而不需要了解這些介面的具體實現方式。而對於Framework開發者,則需要了解這些Manager服務的常用實現模式,維護這些Manager的介面,擴充套件這些介面,或者實現新的Manager。

一個簡單的SystemService

我們從一個簡單的系統服務Vibrator服務來看一下一個系統服務是怎樣建立的。
Vibrator服務提供的控制手機振動的介面,應用可以呼叫Vibrator的介面來讓手機產生振動,達到提醒使用者的目的。
從Android的官方文件中可以看到Vibrator只是一個抽象類,只有4個抽象介面:

  • abstract void cancel() 取消振動
  • abstract boolean hasVibrator() 是否有振動功能
  • abstract void vibrate(long[] pattern, int repeat)
    按節奏重複振動
  • abstract void vibrate(long milliseconds) 持續振動

應用中使用振動服務的方法也很簡單,如讓手機持續振動500毫秒:

Vibrator mVibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
mVibrator.vibrate(500);

Vibrator使用起來很簡單,我們再來看一下實現起來是不是也簡單。
從文件中可以看到Vibrator只是定義在android.os 包裡的一個抽象類,在原始碼裡的位置即frameworks/base/core/java/android/os/Vibrator.java

,那麼應用中實際使用的是哪個例項呢?應用中使用的Vibrator例項是通過Context的一個方法getSystemService(Context.VIBRATOR_SERVICE)獲得的,而Context的實現一般都在ContextImpl中,那我們就看一下ContextImpl是怎麼實現getSystemService的:
frameworks/base/core/java/android/app/ContextImpl.java

@Override
public Object getSystemService(String name) {
    return SystemServiceRegistry.getSystemService(this, name);
}

frameworks/base/core/java/android/app/SystemServiceRegistry.java
(SystemServiceRegistry是 Android 6.0之後才有的,Android 6.0 之前的程式碼沒有該類,下面的程式碼是直接寫在ContextImpl裡的)

 public static Object getSystemService(ContextImpl ctx, String name) {
    ServiceFetcher<?> fetcher = SYSTEM_SERVICE_FETCHERS.get(name);
    return fetcher != null ? fetcher.getService(ctx) : null;
}

SYSTEM_SERVICE_MAP是一個HashMap,通過我們服務的名字name字串,從這個HashMap裡取出一個ServiceFetcher,再return這個ServiceFetchergetService()ServiceFetcher是什麼?它的getService()又是什麼?既然他是從SYSTEM_SERVICE_MAP這個HashMapget出來的,那就找一找這個HashMapput了什麼。
通過搜尋SystemServiceRegistry可以找到如下程式碼:

private static <T> void registerService(String serviceName, Class<T> serviceClass,
        ServiceFetcher<T> serviceFetcher) {
    SYSTEM_SERVICE_NAMES.put(serviceClass, serviceName);
    SYSTEM_SERVICE_FETCHERS.put(serviceName, serviceFetcher);
}

這裡往SYSTEM_SERVICE_MAPput了一對StringServiceFetcher組成的key/value對,registerService()又是從哪裡呼叫的?繼續搜尋可以發現很多類似下面的程式碼:

static {
    registerService(Context.ACCESSIBILITY_SERVICE, AccessibilityManager.class,
            new CachedServiceFetcher<AccessibilityManager>() {
        @Override
        public AccessibilityManager createService(ContextImpl ctx) {
            return AccessibilityManager.getInstance(ctx);
        }});

    ...
    registerService(Context.VIBRATOR_SERVICE, Vibrator.class,
            new CachedServiceFetcher<Vibrator>() {
        @Override
        public Vibrator createService(ContextImpl ctx) {
            return new SystemVibrator(ctx);
        }});
    ...
}

SystemServiceRegistrystatic程式碼塊裡通過registerService註冊了很多的系統服務,其中就包括我們正在調查的VIBRATOR_SERVICE,通過結合上面的分析程式碼可以可以知道getSystemService(Context.VIBRATOR_SERVICE)得到的是一個SystemVibrator的例項,通過檢視SystemVibrator的程式碼也可以發現SystemVibrator確實是繼承自Vibrator

public class SystemVibrator extends Vibrator {
    ...
}

我們再從SystemVibrator看一下系統的振動控制是怎麼實現的。以hasVibrator()為例,這個是查詢當前系統是否能夠振動,在SystemVibrator中它的實現如下:

public boolean hasVibrator() {
    ...
    try {
        return mService.hasVibrator();
    } catch (RemoteException e) {
    }
    ...
}

這裡直接呼叫了一個mService.hasVibrator()mService是什麼?哪來的?搜尋一下可以發現:

private final IVibratorService mService;
public SystemVibrator() {
    ...
    mService = IVibratorService.Stub.asInterface(
            ServiceManager.getService("vibrator"));
}

mService 是一個IVibratorService,我們先不去管IVibratorService.Stub.asInterface是怎麼回事,先看一下IVibratorService是什麼。搜尋一下程式碼發現這並不是一個java檔案,而是一個aidl檔案:
frameworks/base/core/java/android/os/IVibratorService.aidl
AIDL (Android Interface Definition Language) 是Android中的介面定義檔案,為系統提供了一種簡單跨程序通訊方法。
IVibratorService 中定義了幾個介面,SystemVibrator中使用的也是這幾個介面,包括我們剛才使用的hasVibrator()

interface IVibratorService
{
    boolean hasVibrator();
    void vibrate(...);
    void vibratePattern(...);
    void cancelVibrate(IBinder token);
}

這裡又只是介面定義,介面實現在哪呢?通過在frameworks/base目錄下進行grep搜尋,或者在AndroidXRef搜尋,可以發現IVibratorService介面的實現在frameworks/base/services/java/com/android/server/VibratorService.java

public class VibratorService extends IVibratorService.Stub

可以看到 VibratorService實現了IVibratorService定義的所有介面,並通過JNI呼叫到native層,進行更底層的實現。更底層的實現不是這篇文件討論的內容,我們需要分析的是VibratorService怎麼成為系統服務的。那麼VibratorService是怎麼註冊為系統服務的呢?在SystemServer裡面:

VibratorService vibrator = null;
...
//例項化VibratorService並新增到ServiceManager
traceBeginAndSlog("StartVibratorService");
vibrator = new VibratorService(context);
ServiceManager.addService("vibrator", vibrator);
Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
...
//通知服務系統啟動完成
Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "MakeVibratorServiceReady");
try {
    vibrator.systemReady();
} catch (Throwable e) {
    reportWtf("making Vibrator Service ready", e);
}
Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);

這樣在SystemVibrator裡就可以通過下面的程式碼連線到VibratorService,與底層的系統服務進行通訊了:

IVibratorService.Stub.asInterface(ServiceManager.getService("vibrator"));

mService相當於IVibratorService在應用層的一個代理,所有的實現還是在SystemServerVibratorService裡。
看程式碼時可以發現registerService是在static程式碼塊裡靜態呼叫的,所以getSystemServcr獲得的各個Manager也都是單例的。

System Service實現流程

從上面的分析,我們可以總結出Vibrator服務的整個實現流程:

  1. 定義一個抽象類Vibrator,定義了應用中可以訪問的一些抽象方法
    frameworks/base/core/java/android/os/Vibrator.java
  2. 定義具體的類SystemVibrator繼承Vibrator,實現抽象方法
    frameworks/base/core/java/android/os/SystemVibrator.java
  3. 定義一個AIDL介面檔案IVibratorService,定義系統服務介面
    frameworks/base/core/java/android/os/IVibratorService.aidl
  4. 定義服務VibratorService,實現IVibratorService定義的介面
    frameworks/base/services/java/com/android/server/VibratorService.java

    public class VibratorService extends IVibratorService.Stub
  5. VibratorServicey新增到系統服務
    frameworks/base/services/java/com/android/server/SystemServer.java

    VibratorService vibrator = null;
    ...
    //例項化VibratorService並新增到ServiceManager
    Slog.i(TAG, "Vibrator Service");
    vibrator = new VibratorService(context);
    ServiceManager.addService("vibrator", vibrator);
    ...
    //通知服務系統啟動完成
    try {
        vibrator.systemReady();
    } catch (Throwable e) {
        reportWtf("making Vibrator Service ready", e);
    }
  6. SystemVibrator中通過IVibratorService的代理連線到VibratorService,這樣SystemVibrator的介面實現裡就可以呼叫IVibratorService的介面:
    frameworks/base/core/java/android/os/SystemVibrator.java

    private final IVibratorService mService;
    ...
    public SystemVibrator() {
        ...
        mService = IVibratorService.Stub.asInterface(
                ServiceManager.getService("vibrator"));
        ...
        public boolean hasVibrator() {
            ...
            try {
                return mService.hasVibrator();
            } catch (RemoteException e) {
            }
            ...
        }
    }
  7. Context裡定義一個代表Vibrator服務的字串
    frameworks/base/core/java/android/content/Context.java

    public static final String VIBRATOR_SERVICE = "vibrator";
  8. 在ContextImpl裡新增SystemVibrator的例項化過程
    frameworks/base/core/java/android/app/ContextImpl.java

    registerService(VIBRATOR_SERVICE, new ServiceFetcher() {
    public Object createService(ContextImpl ctx) {
        return new SystemVibrator(ctx);
    }});  
  9. 在應用中使用Vibrator的介面

    Vibrator mVibrator = (Vibrator) getSystemService(Context.VIBRATOR_SERVICE);
    mVibrator.vibrate(500);
  10. 為保證編譯正常,還需要將AIDL檔案新增到編譯配置裡
    frameworks/base/Android.mk

    LOCAL_SRC_FILES += \
    ...
    core/java/android/os/IVibratorService.aidl \

System Service 新加介面

如果我們需要實現一個新的系統服務,就可以按照上面的步驟在系統中擴展出一個新的服務,並給應用層提供出使用介面。如果想在Vibrator裡新增一個新的介面,需要下面3步:

  1. IVibratorService新增介面;
  2. VibratorService新增介面的實現;
  3. VibratorSystemVibrator裡擴充套件新的介面;

這樣應用中就可以使用Vibrator的新介面了。

應用層與 System Service 通訊

上面的實現我們看到的只是從應用層通過服務代理,呼叫系統服務的介面,如果我們想反過來,將系統服務的狀態通知給應用層,該怎麼做呢?

  • 方法一:使用Broadcast

我們知道使用Broadcast廣播可以實現跨程序的訊息傳遞,一些系統服務也使用了這種方法。如電池管理服務BatteryManagerService,收到底層上報的電池狀態變化資訊時,就將當前的電池狀態封裝在一個Intent裡,actionandroid.intent.action.BATTERY_CHANGED。應用只要註冊一個對應的BroadcastReceiver就可以收到BatterManagerService傳送的電池狀態資訊。

  • 方法二:使用AIDL
    從上面我們可以知道,通過AIDL定義一套介面,由系統服務端實現這些介面,應用端使用一個相應的代理就可以訪問系統服務的介面,那反過來讓應用端實現AIDL介面,系統服務端使用代理呼叫應用端的介面可不可以呢?答案是YES。那麼接下來的問題是怎麼讓系統服務得到這個代理。我們再來看一個LocationManager的例子。

LocationManager是系統的定位服務,應用通過LocationManager可以獲得裝置當前的地理位置資訊。下面是LocationManager的使用程式碼片段:

//獲得定位服務
LocationManager locationManager = 
        (LocationManager) getSystemService(Context.LOCATION_SERVICE);

//定義定位監聽器
LocationListener locationListener = new LocationListener() {
    public void onLocationChanged(Location location) {
        //監聽到位置資訊
    }
    ...
};

//註冊監聽器
locationManager.requestLocationUpdates(LocationManager.NETWORK_PROVIDER, 
        0, 0, locationListener);

從上面的程式碼可以看到,我們建立了一個位置監聽器LocationListener,並將這個監聽器在LocationManager裡進行了註冊。當系統定位到系統的位置後,就會回撥監聽器的onLocationChanged(),將位置資訊通知給監聽器。LocationListener就是一個系統服務呼叫應用層介面的例子,我們就研究一下LocationListener的實現方式。
我們先從LocationManager怎麼註冊LocationListener開始研究:
frameworks/base/location/java/android/location/LocationManager.java

private final ILocationManager mService;
...
private void requestLocationUpdates(LocationRequest request, 
        LocationListener listener, Looper looper, PendingIntent intent) {
    ...
    // wrap the listener class
    ListenerTransport transport = wrapListener(listener, looper);
    try {
        mService.requestLocationUpdates(request, transport, 
                intent, packageName);
   } catch (RemoteException e) {
       Log.e(TAG, "RemoteException", e);
   }
}

可以看到LocationListener被重新封裝成了一個ListenerTransport,然後傳遞給了ILocationManager ,從前面的分析可以猜測到這個ILocationManager應該就是LocationManagerService的一個代理。那麼ListenerTransport又是什麼呢?搜尋LocationManager.java可以找到:

private class ListenerTransport extends ILocationListener.Stub {
    ...
    @Override
    public void onLocationChanged(Location location) {
        ...
    }
}

原來是ILocationListener.Stub的一個繼承實現,那麼ILocationListener應該就是一個AIDL介面定義:
frameworks/base/location/java/android/location/ILocationListener.aidl

oneway interface ILocationListener
{
    void onLocationChanged(in Location location);
    ...
}

而在LocationManagerService裡只要呼叫ILocationListener的方法就可以將訊息傳遞給應用層的監聽:

mListener.onLocationChanged(new Location(location));

實現 System Service 的注意事項

  1. 注意防止阻塞
    應用層訪問系統服務提供的介面時會有兩種情況:

    • 一種是應用呼叫端需要等待服務實現端處理完成,返回處理結果,這樣如果服務端發生阻塞,那麼應用端也會發生阻塞,因此在實現服務端的實現時要注意不要發生阻塞。
    • 另一種是呼叫端不需要等待服務端返回結果,呼叫完成後直接返回void,這樣服務端發生阻塞不會影響到應用端,這樣的單向的介面在AIDL裡定義時需要新增oneway關鍵字,如:
    oneway void statusBarVisibilityChanged(int visibility);

    對於需要在服務端呼叫,在應用端實現的介面,考慮到系統的穩定性以及安全性,一般都會設計成上面的第二種,即AIDL裡所有的介面都是單向的,如上面的ILocationListener

    oneway interface ILocationListener
  2. 注意多執行緒訪問
    每個系統服務在系統程序中只有一個例項,而且應用中系統服務的代理也是單例的,而且應用端的訪問,在系統程序都是使用獨立的執行緒進行響應,所以訪問同一個系統服務的介面時必然會出現多個執行緒或者多個程序同時訪問的情況。為保證系統服務的執行緒安全,需要對系統服務的程序進行多執行緒訪問的保護,目前主要有兩種實現執行緒安全的方法:

    • 一種是通過同步鎖機制,鎖住一個物件例項(一般是這個服務物件本身),這樣這個服務同一時間只能響應一個訪問請求,如LocationManagerService裡:
    public boolean callStatusChangedLocked(...) {
        ...
        synchronized (this) {
        ...
        }
    }
    • 另一種方法就是使用Handler機制,這種服務一般會建立一個單獨的執行緒,當有應用端訪問請求到來時會向服務執行緒的Handler裡傳送一個Message,利用單執行緒順序執行的特性,保證所有的訪問都按順序進行處理,但這種方法只適合單向的訪問,不適合需要返回的雙向訪問。

ServiceManager原理

從上面流程的分析我們可以看到,所有的系統服務最終都是由ServiceManager來管理的,那麼ServiceManager是怎麼管理這些系統服務的呢?還是先看上面的VibratorService的實現:

VibratorService通過addService()將自己註冊到ServiceManager裡,SystemVibrator通過getService()獲得一個服務代理,並與服務進行通訊互動,那麼ServiceManager又是什麼?它是怎麼管理服務的註冊與代理的呢?我們先從addService()getService()開始,分析一下ServiceManager:
frameworks/base/core/java/android/os/ServiceManager.java

public final class ServiceManager {
    public static void addService(String name, IBinder service) {
        ...
        getIServiceManager().addService(name, service, false);
    }

    public static IBinder getService(String name) {
        ...
        return getIServiceManager().getService(name);
    }
}

addService()getService()都是直接呼叫了getIServiceManager()的方法,getIServiceManager()返回的又是什麼呢?

private static IServiceManager getIServiceManager() {
    if (sServiceManager != null) {
        return sServiceManager;
    }
    // Find the service manager
    sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject());
    return sServiceManager;
}

這裡是建立了一個IServiceManager型別的單例項,具體的例項又是通過ServiceManagerNative建立的:

ServiceManagerNative.asInterface(BinderInternal.getContextObject());

先來看BinderInternal.getContextObject()
frameworks/base/core/java/com/android/internal/os/BinderInternal.java

public static final native IBinder getContextObject();

getContextObject()是在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);
    return javaObjectForIBinder(env, b);
}

後面的實現過程邏輯比較複雜,這裡就不詳細分析了,只是說明一下大致流程,感興趣的可以自己詳細研究一下binder的實現機制。
ProcessState從名字可以看出這應該是一個儲存程序狀態的類,最好應該用單例項的物件儲存,所以ProcessState::self()得到的也就是ProcessState的一個單例項物件,它的getContextObject()會繼續呼叫getStrongProxyForHandle(int32_t handle)返回一個IBinder
frameworks/native/libs/binder/ProcessState.cpp

sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& caller)
{
    return getStrongProxyForHandle(0);
}

getStrongProxyForHandle()中會根據傳入的引數handle建立一個BpBinder,這個BpBinder會儲存在一個數組mHandleToObject中,下次再用同樣的handle請求時不會再重新建立。由於我們傳入的handle=0,這裡建立的BpBinder也就相當於第0號BpBinder
之後的javaObjectForIBinder()會將C++的BpBinder物件封裝成Java的BinderProxy物件並返回。所以BinderInternal.getContextObject()得到的是一個BinderProxy物件,並關聯了native層的第0號BpBinder

ServiceManagerNative.asInterface(BinderInternal.getContextObject());

相當於

ServiceManagerNative.asInterface(new BinderProxy());

ServiceManagerNative.asInterface()又做了些什麼呢?
frameworks/base/core/java/android/os/ServiceManagerNative.java

static public IServiceManager asInterface(IBinder obj)
{
    ...    
    return new ServiceManagerProxy(obj);
}

這裡會將BinderProxy再封裝成一個ServiceManagerProxy(),所以getIServiceManager()得到的其實是一個ServiceManagerProxy,但是底層指向的是一個BpBinder(0)
ServiceManagerProxyBinderProxy以及BpBinder都是代理模式中的proxy端,真正的實現應該在對應的native端。我們接著看。
addService()getService()在代理端的實現應該是在ServiceManagerProxy()裡:

public IBinder getService(String name) throws RemoteException {
    Parcel data = Parcel.obtain();
    Parcel reply = Parcel.obtain();
    data.writeInterfaceToken(IServiceManager.descriptor);
    data.writeString(name);
    mRemote.transact(GET_SERVICE_TRANSACTION, data, reply, 0);
    IBinder binder = reply.readStrongBinder();
    reply.recycle();
    data.recycle();
    return binder;
}
...
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);
    reply.recycle();
    data.recycle();
}

從上面兩個方法的實現可以看到,首先是建立了兩個可序列化的Parcel datareply,傳入的引數被放到了data裡,datareply又一起傳給了mRemote.transact(),之後又從reply裡讀取結果。addService()的實現裡還通過data.writeStrongBinder(service)寫入了一個IBinder的例項。同時注意到getService()addService()裡面呼叫mRemote.transact()傳遞的第一個引數分別為GET_SERVICE_TRANSACTIONADD_SERVICE_TRANSACTION ,我們可以在IServiceManager裡看到這是兩個int值,分別為1和3
frameworks/base/core/java/android/os/IServiceManager.java

int GET_SERVICE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION;  //值為1
int CHECK_SERVICE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+1;
int ADD_SERVICE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION+2;

mRemote就是BinderProxy,真正的實現是C++裡的BpBinder
frameworks/native/libs/binder/BpBinder.cpp

status_t BpBinder::transact(
        uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
    // Once a binder has died, it will never come back to life.
    if (mAlive) {
        status_t status = IPCThreadState::self()->transact(
            mHandle, code, data, reply, flags);
        if (status == DEAD_OBJECT) mAlive = 0;
        return status;
    }

    return DEAD_OBJECT;
}

IPCThreadState裡的transact會將proxy端的請求通過binder機制寫入到一塊共享記憶體裡,然後會有一個native端從共享記憶體裡讀出請求,並執行相應的操作。那麼這個native端在哪裡呢?是不是ServiceManagerNative呢?但是ServiceManagerNative只是一個抽象類,我們並沒有找到繼承自它的子類。實際上ServiceManagerNative只是架構方面的一個抽象定義,並沒有真正的一個實現,真正實現ServiceManager 的native端功能的是在native層的service_manager.c中。
servicemanager是底層的一個獨立程序,主要的實現程式碼就在service_manager.c中。
frameworks/native/cmds/servicemanager/binder.h

enum {
    /* Must match definitions in IBinder.h and IServiceManager.h */
    PING_TRANSACTION  = B_PACK_CHARS('_','P','N','G'),
    SVC_MGR_GET_SERVICE = 1,
    SVC_MGR_CHECK_SERVICE,
    SVC_MGR_ADD_SERVICE,
    SVC_MGR_LIST_SERVICES,
};

frameworks/native/cmds/servicemanager/service_manager.c

#include "binder.h"
...
int svcmgr_handler(struct binder_state *bs,
                   struct binder_transaction_data *txn,
                   struct binder_io *msg,
                   struct binder_io *reply)
{
    ...
    switch(txn->code) {
    case SVC_MGR_GET_SERVICE:
    case SVC_MGR_CHECK_SERVICE:
        s = bio_get_string16(msg, &len);
        if (s == NULL) {
            return -1;
        }
        handle = do_find_service(s, len, txn->sender_euid, txn->sender_pid);
        if (!handle)
            break;
        bio_put_ref(reply, handle);
        return 0;

    case SVC_MGR_ADD_SERVICE:
        s = bio_get_string16(msg, &len);
        if (s == NULL) {
            return -1;
        }
        handle = bio_get_ref(msg);
        allow_isolated = bio_get_uint32(msg) ? 1 : 0;
        if (do_add_service(bs, s, len, handle, txn->sender_euid,
            allow_isolated, txn->sender_pid))
            return -1;
        break;
        ...
    }
}

service_manager.csvcmgr_handler函式就是監聽代理端請求命令的txn->code就是mRemote.transact()裡傳過來的第一個引數。SVC_MGR_GET_SERVICESVC_MGR_ADD_SERVICE是在標頭檔案binder.h裡定義的,它們的值與IServiceManager.java裡定義的一致,也是1和3。
我們先看SVC_MGR_ADD_SERVICE的響應:

  • 首先通過s = bio_get_string16(msg, &len)獲得了service的名稱,
  • 然後通過handle = bio_get_ref(msg)獲得了一個handle,這個handle就是我們之前通過writeStrongBinder寫入的IBinder
  • 最後通過do_add_service()添加註冊service

do_add_service()的實現如下:

int do_add_service(struct binder_state *bs,
                   const uint16_t *s, size_t len,
                   uint32_t handle, uid_t uid, int allow_isolated,
                   pid_t spid)
{
    struct svcinfo *si;
    si = find_svc(s, len);
    if (si) {
        if (si->handle) {
            ALOGE("add_service('%s',%x) uid=%d - ALREADY REGISTERED, OVERRIDE\n",
                 str8(s, len), handle, uid);
            svcinfo_death(bs, si);
        }
        si->handle = handle;
    } else {
        si = malloc(sizeof(*si) + (len + 1) * sizeof(uint16_t));
        si->handle = handle;
        si->len = len;
        memcpy(si->name, s, (len + 1) * sizeof(uint16_t));
        si->name[len] = '\0';
        si->death.func = (void*) svcinfo_death;
        si->death.ptr = si;
        si->allow_isolated = allow_isolated;
        si->next = svclist;
        svclist = si;
    }
    ...
}

struct svcinfo *find_svc(const uint16_t *s16, size_t len)
{
    struct svcinfo *si;

    for (si = svclist; si; si = si->next) {
        if ((len == si->len) &&
            !memcmp(s16, si->name, len * sizeof(uint16_t))) {
            return si;
        }
    }
    return NULL;
}
  • 首先聲明瞭一個struct svcinfo *si
  • 通過find_svc(s, len)查詢一下同樣名稱的service之前是不是註冊過,防止重複註冊。find_svc()的實現裡可以看到是通過遍歷一個svclist連結串列來查重的,svclist連結串列就是用來儲存所有註冊過的service的
  • 如果確認沒有重複註冊service,就重新構造一個svcinfo新增到svclist連結串列的頭部。

我們再看SVC_MGR_GET_SERVICE的響應,主要是通過do_find_service()查詢到對應的service,並通過bio_put_ref(reply, handle)將查詢到的handle返回。do_find_service()的實現主要也是通過find_svc()svclist連結串列中查詢

uint32_t do_find_service(const uint16_t *s, size_t len, uid_t uid, pid_t spid)
{
    struct svcinfo *si = find_svc(s, len);
    ...
    return si->handle;
}

通過上面的流程梳理我們最終了解到:

  • 每個System Service通過呼叫ServiceManager.addService()將自己的名字以及IBinder引用儲存到servicemanager程序的一個連結串列裡
  • 每個使用該System Service的程序通過呼叫ServiceManager.getService()從servicemanager程序獲得該System Service對應的IBinder,就可以與該System Service進行通訊了。