沒事了就看看老羅的書,感覺老羅是走過來的人,說出來的話都是硬道理,我們開始分析Android系統源碼時确實感覺很慢,但是随着我們腳步的前進,有了大量的沉澱之後,大家自己就會感覺我們的功力越來越厚,前進的步伐也越來越快。
前面兩篇Binder程序間通信的分析完了之後,再對比下老羅的部落格,感覺差距還是十萬八千裡啊!!!還有很多地方沒說清楚,是以這篇我們繼續來看一下Binder程序間通信中的Server啟動過程。我們的目标就是ActivityManagerService,它是Android系統的大管家,很多的工作都是由它來處理的。我們這節就來看看ActivityManagerService是如何在SystemServer程序中一步步啟動起來的。
ActivityManagerService運作在SystemServer程序空間,它的啟動是在SystemServer.java類的startBootstrapServices方法中完成的,SystemServer.java類的完整路徑為SystemServer.javaframeworks\base\services\java\com\android\server\SystemServer.java,startBootstrapServices方法的源碼如下:
private void startBootstrapServices() {
Slog.i(TAG, "Reading configuration...");
final String TAG_SYSTEM_CONFIG = "ReadingSystemConfig";
traceBeginAndSlog(TAG_SYSTEM_CONFIG);
SystemServerInitThreadPool.get().submit(SystemConfig::getInstance, TAG_SYSTEM_CONFIG);
traceEnd();
// Wait for installd to finish starting up so that it has a chance to
// create critical directories such as /data/user with the appropriate
// permissions. We need this to complete before we initialize other services.
traceBeginAndSlog("StartInstaller");
Installer installer = mSystemServiceManager.startService(Installer.class);
traceEnd();
// In some cases after launching an app we need to access device identifiers,
// therefore register the device identifier policy before the activity manager.
traceBeginAndSlog("DeviceIdentifiersPolicyService");
mSystemServiceManager.startService(DeviceIdentifiersPolicyService.class);
traceEnd();
// Activity manager runs the show.
traceBeginAndSlog("StartActivityManager");
mActivityManagerService = mSystemServiceManager.startService(
ActivityManagerService.Lifecycle.class).getService();
mActivityManagerService.setSystemServiceManager(mSystemServiceManager);
mActivityManagerService.setInstaller(installer);
traceEnd();
// Power manager needs to be started early because other services need it.
// Native daemons may be watching for it to be registered so it must be ready
// to handle incoming binder calls immediately (including being able to verify
// the permissions for those calls).
traceBeginAndSlog("StartPowerManager");
mPowerManagerService = mSystemServiceManager.startService(PowerManagerService.class);
traceEnd();
// Now that the power manager has been started, let the activity manager
// initialize power management features.
traceBeginAndSlog("InitPowerManagement");
mActivityManagerService.initPowerManagement();
traceEnd();
// Bring up recovery system in case a rescue party needs a reboot
if (!SystemProperties.getBoolean("config.disable_noncore", false)) {
traceBeginAndSlog("StartRecoverySystemService");
mSystemServiceManager.startService(RecoverySystemService.class);
traceEnd();
}
// Now that we have the bare essentials of the OS up and running, take
// note that we just booted, which might send out a rescue party if
// we're stuck in a runtime restart loop.
RescueParty.noteBoot(mSystemContext);
// Manages LEDs and display backlight so we need it to bring up the display.
traceBeginAndSlog("StartLightsService");
mSystemServiceManager.startService(LightsService.class);
traceEnd();
// Display manager is needed to provide display metrics before package manager
// starts up.
traceBeginAndSlog("StartDisplayManager");
mDisplayManagerService = mSystemServiceManager.startService(DisplayManagerService.class);
traceEnd();
// We need the default display before we can initialize the package manager.
traceBeginAndSlog("WaitForDisplay");
mSystemServiceManager.startBootPhase(SystemService.PHASE_WAIT_FOR_DEFAULT_DISPLAY);
traceEnd();
// Only run "core" apps if we're encrypting the device.
String cryptState = SystemProperties.get("vold.decrypt");
if (ENCRYPTING_STATE.equals(cryptState)) {
Slog.w(TAG, "Detected encryption in progress - only parsing core apps");
mOnlyCore = true;
} else if (ENCRYPTED_STATE.equals(cryptState)) {
Slog.w(TAG, "Device encrypted - only parsing core apps");
mOnlyCore = true;
}
// Start the package manager.
if (!mRuntimeRestart) {
MetricsLogger.histogram(null, "boot_package_manager_init_start",
(int) SystemClock.elapsedRealtime());
}
traceBeginAndSlog("StartPackageManagerService");
mPackageManagerService = PackageManagerService.main(mSystemContext, installer,
mFactoryTestMode != FactoryTest.FACTORY_TEST_OFF, mOnlyCore);
mFirstBoot = mPackageManagerService.isFirstBoot();
mPackageManager = mSystemContext.getPackageManager();
traceEnd();
if (!mRuntimeRestart && !isFirstBootOrUpgrade()) {
MetricsLogger.histogram(null, "boot_package_manager_init_ready",
(int) SystemClock.elapsedRealtime());
}
// Manages A/B OTA dexopting. This is a bootstrap service as we need it to rename
// A/B artifacts after boot, before anything else might touch/need them.
// Note: this isn't needed during decryption (we don't have /data anyways).
if (!mOnlyCore) {
boolean disableOtaDexopt = SystemProperties.getBoolean("config.disable_otadexopt",
false);
if (!disableOtaDexopt) {
traceBeginAndSlog("StartOtaDexOptService");
try {
OtaDexoptService.main(mSystemContext, mPackageManagerService);
} catch (Throwable e) {
reportWtf("starting OtaDexOptService", e);
} finally {
traceEnd();
}
}
}
traceBeginAndSlog("StartUserManagerService");
mSystemServiceManager.startService(UserManagerService.LifeCycle.class);
traceEnd();
// Initialize attribute cache used to cache resources from packages.
traceBeginAndSlog("InitAttributerCache");
AttributeCache.init(mSystemContext);
traceEnd();
// Set up the Application instance for the system process and get started.
traceBeginAndSlog("SetSystemProcess");
mActivityManagerService.setSystemProcess();
traceEnd();
// DisplayManagerService needs to setup android.display scheduling related policies
// since setSystemProcess() would have overridden policies due to setProcessGroup
mDisplayManagerService.setupSchedulerPolicies();
// Manages Overlay packages
traceBeginAndSlog("StartOverlayManagerService");
mSystemServiceManager.startService(new OverlayManagerService(mSystemContext, installer));
traceEnd();
// The sensor service needs access to package manager service, app ops
// service, and permissions service, therefore we start it after them.
// Start sensor service in a separate thread. Completion should be checked
// before using it.
mSensorServiceStart = SystemServerInitThreadPool.get().submit(() -> {
BootTimingsTraceLog traceLog = new BootTimingsTraceLog(
SYSTEM_SERVER_TIMING_ASYNC_TAG, Trace.TRACE_TAG_SYSTEM_SERVER);
traceLog.traceBegin(START_SENSOR_SERVICE);
startSensorService();
traceLog.traceEnd();
}, START_SENSOR_SERVICE);
}
從該方法中的邏輯我們可以很清楚的看到,在這裡啟動了很多核心的服務,包括:Installer、PowerManagerService、RecoverySystemService、LightsService、DisplayManagerService等等,它們都是我們應用層的核心服務,我們在應用層需要執行的很多邏輯最終都是由它們來實作的。這裡跟我們密切相關的就是mActivityManagerService = mSystemServiceManager.startService(ActivityManagerService.Lifecycle.class).getService();這句邏輯了,mSystemServiceManager是SystemServer對象的類型為SystemServiceManager的成員變量,傳入的參數是ActivityManagerServer的内部類Lifecycle,mSystemServiceManager.startService方法的傳回值是<T extends SystemService>,是一個繼續了SystemService類型的範型,也就是我們傳入的ActivityManagerService的内部類Lifecycle,它的getService()方法傳回的就是在構造方法中執行個體化好的ActivityManagerService對象的執行個體了。
ActivityManagerService的路徑為frameworks\base\services\core\java\com\android\server\am\ActivityManagerService.java,它的内部類Lifecycle的源碼如下:
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;
}
}
ActivityManagerService對象的執行個體化就是在Lifecycle類的構造方法中完成的,getService方法傳回的就是執行個體化好的ActivityManagerService的執行個體對象。
我們再來看下SystemServiceManager.java類的startService方法的實作,這裡需要注意,SystemServiceManager類的startService方法有三個重載,如下圖:
我們在SystemServer類中調用startService方法時,傳入的參數為ActivityManagerService.Lifecycle.class,是一個類對象,是以這裡調用的就是上圖中第一個startService方法,它的路徑為frameworks\base\services\core\java\com\android\server\SystemServiceManager.java,startService方法的源碼如下:
@SuppressWarnings("unchecked")
public <T extends SystemService> T startService(Class<T> serviceClass) {
try {
final String name = serviceClass.getName();
Slog.i(TAG, "Starting " + name);
Trace.traceBegin(Trace.TRACE_TAG_SYSTEM_SERVER, "StartService " + name);
// Create the service.
if (!SystemService.class.isAssignableFrom(serviceClass)) {
throw new RuntimeException("Failed to create " + name
+ ": service must extend " + SystemService.class.getName());
}
final T service;
try {
Constructor<T> constructor = serviceClass.getConstructor(Context.class);
service = constructor.newInstance(mContext);
} catch (InstantiationException ex) {
throw new RuntimeException("Failed to create service " + name
+ ": service could not be instantiated", ex);
} catch (IllegalAccessException ex) {
throw new RuntimeException("Failed to create service " + name
+ ": service must have a public constructor with a Context argument", ex);
} catch (NoSuchMethodException ex) {
throw new RuntimeException("Failed to create service " + name
+ ": service must have a public constructor with a Context argument", ex);
} catch (InvocationTargetException ex) {
throw new RuntimeException("Failed to create service " + name
+ ": service constructor threw an exception", ex);
}
startService(service);
return service;
} finally {
Trace.traceEnd(Trace.TRACE_TAG_SYSTEM_SERVER);
}
}
該方法中的第一句調用final String name = serviceClass.getName()擷取目前方法參數serviceClass的完整類名,getName()是Class對象的方法,name的值就是com.android.server.am.ActivityManagerService$Lifecycle,然後取到它的構造子Constructor,調用newInstance方法構造出一個Lifecycle執行個體對象,最後調用另一個重載的startService方法啟動ActivityManagerService。最後調用startService方法時傳入的參數就是一個SystemService對象了,是以此時執行的就是上圖中第三個方法,它的源碼如下:
public void startService(@NonNull final SystemService service) {
// Register it.
mServices.add(service);
// Start it.
long time = System.currentTimeMillis();
try {
service.onStart();
} catch (RuntimeException ex) {
throw new RuntimeException("Failed to start service " + service.getClass().getName()
+ ": onStart threw an exception", ex);
}
warnIfTooLong(System.currentTimeMillis() - time, service, "onStart");
}
該方法中的邏輯比較簡單,第一是将目前的SystemService執行個體對象添加到成員變量mServices的一個List清單中,第二步調用service.onStart()啟動Serviec,第三步檢測啟動耗時,如果onStart方法執行耗時超過SERVICE_CALL_WARN_TIME_MS,就會列印Slog.w(TAG, "Service " + service.getClass().getName() + " took " + duration + " ms in " + operation);告警日志,SERVICE_CALL_WARN_TIME_MS是SystemServiceManager類的成員變量,它的值為50ms。
我們繼續分析service.onStart方法的邏輯,Lifecycle類的onStart方法很簡單,就是調用ActivityManagerService類的start去啟動它。ActivityManagerService類的start方法源碼如下:
private void start() {
removeAllProcessGroups();
mProcessCpuThread.start();
mBatteryStatsService.publish(mContext);
mAppOpsService.publish(mContext);
Slog.d("AppOps", "AppOpsService published");
LocalServices.addService(ActivityManagerInternal.class, new LocalService());
// Wait for the synchronized block started in mProcessCpuThread,
// so that any other acccess to mProcessCpuTracker from main thread
// will be blocked during mProcessCpuTracker initialization.
try {
mProcessCpuInitLatch.await();
} catch (InterruptedException e) {
Slog.wtf(TAG, "Interrupted wait during start", e);
Thread.currentThread().interrupt();
throw new IllegalStateException("Interrupted wait during start");
}
}
mProcessCpuThread是ActivityManagerService類的類型為Thread的一個成員變量,它主要是在某個程序發生ANR的時候,用來統計各程序的CPU占用時間的,比如當某個程序發生ANR的時候,會列印如下日志:
CPU usage from 1ms to 8900ms later:
62% 18431/system_server: 31% user + 31% kernel / faults: 13821 minor 449 major
32% 27729/com.google.android.googlequicksearchbox:search: 25% user + 6.5% kernel / faults: 8209 minor 375 major
21% 13882/com.yahoo.mobile.client.android.weather: 8.3% user + 13% kernel / faults: 16612 minor 404 major
13% 26814/com.google.android.apps.maps: 8.7% user + 5% kernel / faults: 17040 minor 1139 major
10% 8656/zygote64: 8.6% user + 2.2% kernel / faults: 5543 minor 141 major
這就是該線程完成的,它會統計CPU從上一個取樣節點到發生ANR的時間點中間所有程序的CPU占用比,我也有一篇部落格: Android ANR問題原因分析 是分析ANR産生原因的,但是可惜,當時碰到的這個問題是google原生app發生的ANR,沒有app源碼,無法追究到最終問題發生的根因,網上ANR的文章也非常多,大家都可以參考。
好,到這裡我們ActivityManagerService類的執行就告一段落,我們主要還要跟蹤我們的目标,它是如何把自己添加到ServiceManager中供其他應用來調用的呢?
回到前面ActivityManagerService類的構造方法,它是繼承IActivityManager.Stub的,而android為我們提供的AIDL架構對aidl檔案編譯時就會自動生成java檔案,我們還是以我們的ICameraService為例來說明。ICameraService的源碼如下:
public interface ICameraService extends android.os.IInterface {
/**
* Local-side IPC implementation stub class.
*/
public static abstract class Stub extends android.os.Binder implements com.huawei.cameraservice.ICameraService {
private static final java.lang.String DESCRIPTOR = "com.huawei.cameraservice.ICameraService";
/**
* Construct the stub at attach it to the interface.
*/
public Stub() {
this.attachInterface(this, DESCRIPTOR);
}
/**
* Cast an IBinder object into an com.huawei.cameraservice.ICameraService interface,
* generating a proxy if needed.
*/
public static com.huawei.cameraservice.ICameraService asInterface(android.os.IBinder obj) {
if ((obj == null)) {
return null;
}
android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);
if (((iin != null) && (iin instanceof com.huawei.cameraservice.ICameraService))) {
return ((com.huawei.cameraservice.ICameraService) iin);
}
return new com.huawei.cameraservice.ICameraService.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: {
reply.writeString(DESCRIPTOR);
return true;
}
case TRANSACTION_getMainCameraId: {
data.enforceInterface(DESCRIPTOR);
int _result = this.getMainCameraId();
reply.writeNoException();
reply.writeInt(_result);
return true;
}
case TRANSACTION_openCamera: {
data.enforceInterface(DESCRIPTOR);
int _arg0;
_arg0 = data.readInt();
int _result = this.openCamera(_arg0);
reply.writeNoException();
reply.writeInt(_result);
return true;
}
}
return super.onTransact(code, data, reply, flags);
}
private static class Proxy implements com.huawei.cameraservice.ICameraService {
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 int getMainCameraId() throws android.os.RemoteException {
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
int _result;
try {
_data.writeInterfaceToken(DESCRIPTOR);
mRemote.transact(Stub.TRANSACTION_getMainCameraId, _data, _reply, 0);
_reply.readException();
_result = _reply.readInt();
} finally {
_reply.recycle();
_data.recycle();
}
return _result;
}
@Override
public int openCamera(int id) throws android.os.RemoteException {
android.os.Parcel _data = android.os.Parcel.obtain();
android.os.Parcel _reply = android.os.Parcel.obtain();
int _result;
try {
_data.writeInterfaceToken(DESCRIPTOR);
_data.writeInt(id);
mRemote.transact(Stub.TRANSACTION_openCamera, _data, _reply, 0);
_reply.readException();
_result = _reply.readInt();
} finally {
_reply.recycle();
_data.recycle();
}
return _result;
}
}
static final int TRANSACTION_getMainCameraId = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);
static final int TRANSACTION_openCamera = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);
}
public int getMainCameraId() throws android.os.RemoteException;
public int openCamera(int id) throws android.os.RemoteException;
}
生成的java檔案中定義有兩個内部類,一個是Stub,一個是Proxy,ActivityManagerService繼承的是Stub類,當執行ActivityManagerService的構造方法執行個體化對象時,JVM同時也會執行父類Stub中定義無參的構造方法,它當中的實作很簡單,就是調用this.attachInterface(this, DESCRIPTOR)來繼續處理了。而Stub類又是繼承Binder類的,是以也會調用Binder類的構造方法。我們先看完attachInterface方法的實作,然後再回過來繼續分析Binder類的構造方法。
Stub類的attachInterface方法的實作在Binder.java類中,它的路徑為frameworks\base\core\java\android\os\Binder.java,attachInterface方法的源碼如下:
public void attachInterface(IInterface owner, String descriptor) {
mOwner = owner;
mDescriptor = descriptor;
}
該方法的實作很簡單,就是将傳進來的兩個參數指派給Binder類的成員變量。好,我們繼續看Binder類的構造方法,源碼如下:
public Binder() {
init();
if (FIND_POTENTIAL_LEAKS) {
final Class<? extends Binder> klass = getClass();
if ((klass.isAnonymousClass() || klass.isMemberClass() || klass.isLocalClass()) &&
(klass.getModifiers() & Modifier.STATIC) == 0) {
Log.w(TAG, "The following Binder class should be static or leaks might occur: " +
klass.getCanonicalName());
}
}
}
Binder類的構造方法中調用init來繼續處理,init方法的實作在android_util_Binder.cpp檔案中,路徑為frameworks\base\core\jni\android_util_Binder.cpp,它是通過JVM中注冊的類型為JNINativeMethod的常量方法清單gBinderMethods來調用android_os_Binder_init實作的,android_os_Binder_init方法的源碼如下:
static void android_os_Binder_init(JNIEnv* env, jobject obj)
{
JavaBBinderHolder* jbh = new JavaBBinderHolder();
if (jbh == NULL) {
jniThrowException(env, "java/lang/OutOfMemoryError", NULL);
return;
}
ALOGV("Java Binder %p: acquiring first ref on holder %p", obj, jbh);
jbh->incStrong((void*)android_os_Binder_init);
env->SetLongField(obj, gBinderOffsets.mObject, (jlong)jbh);
}
這裡首先構造了一個JavaBBinderHolder對象,然後增加它的引用計數,最後設定對象執行個體(非靜态)域的值。我們繼續來看一下JavaBBinderHolder的構造方法的實作。JavaBBinderHolder類的定義仍然在android_util_Binder.cpp檔案中,源碼如下:
class JavaBBinderHolder : public RefBase
{
public:
sp<JavaBBinder> get(JNIEnv* env, jobject obj)
{
AutoMutex _l(mLock);
sp<JavaBBinder> b = mBinder.promote();
if (b == NULL) {
b = new JavaBBinder(env, obj);
mBinder = b;
ALOGV("Creating JavaBinder %p (refs %p) for Object %p, weakCount=%" PRId32 "\n",
b.get(), b->getWeakRefs(), obj, b->getWeakRefs()->getWeakCount());
}
return b;
}
sp<JavaBBinder> getExisting()
{
AutoMutex _l(mLock);
return mBinder.promote();
}
private:
Mutex mLock;
wp<JavaBBinder> mBinder;
};
它是繼承了RefBase的,是一個智能指針,如果大家想學習Android智能指針的相關知識,可以去: Android 8.0系統源碼分析--開篇 中下載下傳老羅的書,書中對智能指針有非常詳細的分析。當調用它的get方法擷取引用執行個體時,如果擷取結果為空,則就會構造一個JavaBBinder對象,并指派給成員變量mBinder,這個JavaBBinder就是Binder對象的執行個體了。
好了,整個構造過程我們就分析到這裡,接下來我們繼續分析目前構造的對象是如何添加到ServiceManager中去的。SystemServer在前面作好了準備工作後,就會執行startBootstrapServices方法,該方法中會調用mActivityManagerService.setSystemProcess(),它是由ActivityManagerService來實作的,setSystemProcess方法的源碼如下:
public void setSystemProcess() {
try {
ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
ServiceManager.addService("meminfo", new MemBinder(this));
ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
ServiceManager.addService("dbinfo", new DbBinder(this));
if (MONITOR_CPU_USAGE) {
ServiceManager.addService("cpuinfo", new CpuBinder(this));
}
ServiceManager.addService("permission", new PermissionController(this));
ServiceManager.addService("processinfo", new ProcessInfoService(this));
ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
"android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
synchronized (this) {
ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
app.persistent = true;
app.pid = MY_PID;
app.maxAdj = ProcessList.SYSTEM_ADJ;
app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
synchronized (mPidsSelfLocked) {
mPidsSelfLocked.put(app.pid, app);
}
updateLruProcessLocked(app, false, null);
updateOomAdjLocked();
}
} catch (PackageManager.NameNotFoundException e) {
throw new RuntimeException(
"Unable to find android system package", e);
}
}
這裡的第一句就會調用ServiceManager.addService将執行個體化好的ActivityManagerService對象添加到ServiceManager中去。addService的方法實作在ServiceManager中,它的路徑為frameworks\base\core\java\android\os\ServiceManager.java,addService方法的源碼如下:
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);
}
}
getIServiceManager()方法最終的實作在ServiceManagerNative類中,源碼如下:
private static IServiceManager getIServiceManager() {
if (sServiceManager != null) {
return sServiceManager;
}
// Find the service manager
sServiceManager = ServiceManagerNative
.asInterface(Binder.allowBlocking(BinderInternal.getContextObject()));
return sServiceManager;
}
假設這裡的成員變量sServiceManager為空,那麼就繼續執行ServiceManagerNative.asInterface去尋找我們的大管家。ServiceManagerNative類的路徑為frameworks\base\core\java\android\os\ServiceManagerNative.java,源碼如下:
public abstract class ServiceManagerNative extends Binder implements IServiceManager
{
/**
* Cast a Binder object into a service manager interface, generating
* a proxy if needed.
*/
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);
}
public ServiceManagerNative()
{
attachInterface(this, descriptor);
}
public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
{
try {
switch (code) {
case IServiceManager.GET_SERVICE_TRANSACTION: {
data.enforceInterface(IServiceManager.descriptor);
String name = data.readString();
IBinder service = getService(name);
reply.writeStrongBinder(service);
return true;
}
case IServiceManager.CHECK_SERVICE_TRANSACTION: {
data.enforceInterface(IServiceManager.descriptor);
String name = data.readString();
IBinder service = checkService(name);
reply.writeStrongBinder(service);
return true;
}
case IServiceManager.ADD_SERVICE_TRANSACTION: {
data.enforceInterface(IServiceManager.descriptor);
String name = data.readString();
IBinder service = data.readStrongBinder();
boolean allowIsolated = data.readInt() != 0;
addService(name, service, allowIsolated);
return true;
}
case IServiceManager.LIST_SERVICES_TRANSACTION: {
data.enforceInterface(IServiceManager.descriptor);
String[] list = listServices();
reply.writeStringArray(list);
return true;
}
case IServiceManager.SET_PERMISSION_CONTROLLER_TRANSACTION: {
data.enforceInterface(IServiceManager.descriptor);
IPermissionController controller
= IPermissionController.Stub.asInterface(
data.readStrongBinder());
setPermissionController(controller);
return true;
}
}
} catch (RemoteException e) {
}
return false;
}
public IBinder asBinder()
{
return this;
}
}
class ServiceManagerProxy implements IServiceManager {
public ServiceManagerProxy(IBinder remote) {
mRemote = remote;
}
public IBinder asBinder() {
return mRemote;
}
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 IBinder checkService(String name) throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IServiceManager.descriptor);
data.writeString(name);
mRemote.transact(CHECK_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();
}
public String[] listServices() throws RemoteException {
ArrayList<String> services = new ArrayList<String>();
int n = 0;
while (true) {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IServiceManager.descriptor);
data.writeInt(n);
n++;
try {
boolean res = mRemote.transact(LIST_SERVICES_TRANSACTION, data, reply, 0);
if (!res) {
break;
}
} catch (RuntimeException e) {
// The result code that is returned by the C++ code can
// cause the call to throw an exception back instead of
// returning a nice result... so eat it here and go on.
break;
}
services.add(reply.readString());
reply.recycle();
data.recycle();
}
String[] array = new String[services.size()];
services.toArray(array);
return array;
}
public void setPermissionController(IPermissionController controller)
throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IServiceManager.descriptor);
data.writeStrongBinder(controller.asBinder());
mRemote.transact(SET_PERMISSION_CONTROLLER_TRANSACTION, data, reply, 0);
reply.recycle();
data.recycle();
}
private IBinder mRemote;
}
如果我們在SystemServer程序中首次調用的話,那麼asInterface方法中的前兩個if判斷均不成立,直接構造一個ServiceManagerProxy對象傳回給我們。接下來我們繼續分析ServiceManagerProxy類的addService方法的實作。它的實作就和我們前兩節分析的過程基本相同了,構造兩個Parcel對象用來存儲資料,然後調用mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0)來和Binder驅動進行通信,最後一個參數為0,表示同步請求,需要等待回複結果。中間BinderProxy、android_util_Binder、BpBinder、IPCThreadState的過程我們就跳過了,有不熟悉的同學可以去看看前面兩節我們的分析過程。
我們要添加的資料最終在IPCThreadState類經過封裝,通過talkWithDriver方法調用系統函數ioctl來與binder驅動進行通信,binder驅動将資料處理好之後,就會喚醒ServiceManager來處理了。ServiceManager的啟動過程請看:淺談Service Manager成為Android程序間通信(IPC)機制Binder守護程序之路。
ServiceManager類的源碼在service_manager.c檔案中,路徑為frameworks\native\cmds\servicemanager\service_manager.c,它的main函數源碼如下:
int main(int argc, char** argv)
{
struct binder_state *bs;
union selinux_callback cb;
char *driver;
if (argc > 1) {
driver = argv[1];
} else {
driver = "/dev/binder";
}
bs = binder_open(driver, 128*1024);
if (!bs) {
#ifdef VENDORSERVICEMANAGER
ALOGW("failed to open binder driver %s\n", driver);
while (true) {
sleep(UINT_MAX);
}
#else
ALOGE("failed to open binder driver %s\n", driver);
#endif
return -1;
}
if (binder_become_context_manager(bs)) {
ALOGE("cannot become context manager (%s)\n", strerror(errno));
return -1;
}
cb.func_audit = audit_callback;
selinux_set_callback(SELINUX_CB_AUDIT, cb);
cb.func_log = selinux_log_callback;
selinux_set_callback(SELINUX_CB_LOG, cb);
#ifdef VENDORSERVICEMANAGER
sehandle = selinux_android_vendor_service_context_handle();
#else
sehandle = selinux_android_service_context_handle();
#endif
selinux_status_open(true);
if (sehandle == NULL) {
ALOGE("SELinux: Failed to acquire sehandle. Aborting.\n");
abort();
}
if (getcon(&service_manager_context) != 0) {
ALOGE("SELinux: Failed to acquire service_manager context. Aborting.\n");
abort();
}
binder_loop(bs, svcmgr_handler);
return 0;
}
它把自己啟動起來之後,就會在binder_loop方法中不斷循環等待Client去請求了。binder_loop方法的第二個參數是一個類型為binder_handler的方法指針,實際指向的就是service_manager檔案中的svcmgr_handler方法了,該方法的源碼如下:
int svcmgr_handler(struct binder_state *bs,
struct binder_transaction_data *txn,
struct binder_io *msg,
struct binder_io *reply)
{
struct svcinfo *si;
uint16_t *s;
size_t len;
uint32_t handle;
uint32_t strict_policy;
int allow_isolated;
//ALOGI("target=%p code=%d pid=%d uid=%d\n",
// (void*) txn->target.ptr, txn->code, txn->sender_pid, txn->sender_euid);
if (txn->target.ptr != BINDER_SERVICE_MANAGER)
return -1;
if (txn->code == PING_TRANSACTION)
return 0;
// Equivalent to Parcel::enforceInterface(), reading the RPC
// header with the strict mode policy mask and the interface name.
// Note that we ignore the strict_policy and don't propagate it
// further (since we do no outbound RPCs anyway).
strict_policy = bio_get_uint32(msg);
s = bio_get_string16(msg, &len);
if (s == NULL) {
return -1;
}
if ((len != (sizeof(svcmgr_id) / 2)) ||
memcmp(svcmgr_id, s, sizeof(svcmgr_id))) {
fprintf(stderr,"invalid id %s\n", str8(s, len));
return -1;
}
if (sehandle && selinux_status_updated() > 0) {
struct selabel_handle *tmp_sehandle = selinux_android_service_context_handle();
if (tmp_sehandle) {
selabel_close(sehandle);
sehandle = tmp_sehandle;
}
}
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;
case SVC_MGR_LIST_SERVICES: {
uint32_t n = bio_get_uint32(msg);
if (!svc_can_list(txn->sender_pid, txn->sender_euid)) {
ALOGE("list_service() uid=%d - PERMISSION DENIED\n",
txn->sender_euid);
return -1;
}
si = svclist;
while ((n-- > 0) && si)
si = si->next;
if (si) {
bio_put_string16(reply, si->name);
return 0;
}
return -1;
}
default:
ALOGE("unknown code %d\n", txn->code);
return -1;
}
bio_put_uint32(reply, 0);
return 0;
}
我們目前的場景下,執行的就是case SVC_MGR_ADD_SERVICE分支的邏輯,它當中就是調用do_add_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;
//ALOGI("add_service('%s',%x,%s) uid=%d\n", str8(s, len), handle,
// allow_isolated ? "allow_isolated" : "!allow_isolated", uid);
if (!handle || (len == 0) || (len > 127))
return -1;
if (!svc_can_register(s, len, spid, uid)) {
ALOGE("add_service('%s',%x) uid=%d - PERMISSION DENIED\n",
str8(s, len), handle, uid);
return -1;
}
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));
if (!si) {
ALOGE("add_service('%s',%x) uid=%d - OUT OF MEMORY\n",
str8(s, len), handle, uid);
return -1;
}
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;
}
binder_acquire(bs, handle);
binder_link_to_death(bs, handle, &si->death);
return 0;
}
首先對binder驅動傳遞過來的資料進行檢查,如果資料出錯,那麼就直接傳回-1。然後調用svc_can_register進行權限檢查,接着再調用find_svc去已注冊的Serviec清單svclist中查詢,如果查詢到的對象不為空,說明目标Service已經注冊過,不需要再注冊;否則執行else分支将目标binder實體的名稱和句柄值寫入到一個struct svcinfo結構體中,到此我們的ActivityManagerService就添加到ServiceManager當中了。
從最後的代碼中我們可以看到,添加到ServiceManager當中的隻是一個名稱和句柄,并不是我們的Binder實體,而Binder實體隻有一個,而且是停留在它注冊的程序當中的,隻是說其他程序需要使用時,通過ServiceManager這個大管家可以查到它的引用就行了。
好了,我們就分析到這裡,對比老羅的書和8.0的系統源碼,Binder程序間通信這塊的邏輯修改也很小,說明之前版本的Binder通信代碼已經非常穩定了。雖然寫了這三篇部落格,但是感覺還是有很多不清楚的地方,後續還要繼續努力。
吃晚飯吧!!!