Android 8.0系统源码分析--Binder进程间通信(三)
来源:互联网 发布:杭州红绿灯 人工智能 编辑:程序博客网 时间:2024/06/07 18:56
没事了就看看老罗的书,感觉老罗是走过来的人,说出来的话都是硬道理,我们开始分析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通信代码已经非常稳定了。虽然写了这三篇博客,但是感觉还是有很多不清楚的地方,后续还要继续努力。
吃晚饭吧!!!
- Android 8.0系统源码分析--Binder进程间通信(三)
- Android 8.0系统源码分析--Binder进程间通信(一)
- Android 8.0系统源码分析--Binder进程间通信(二)
- Android开发知识(三)Android进程间Binder通信机制的源码分析(上)
- Android进程间通信之Binder机制源码分析
- Android源码分析之Binder进程间通信一
- android系统源码阅读--进程间通信Binder机制
- Android开发知识(四)Android进程间Binder通信机制的源码分析(下)
- [Binder.3] Android系统进程间通信(IPC)机制Binder中的Server启动过程源代码分析
- [Binder.4] Android系统进程间通信(IPC)机制Binder中的Client获得Server远程接口过程源代码分析
- Android系统进程间通信(IPC)机制Binder中的Server启动过程源代码分析
- Android系统进程间通信(IPC)机制Binder中的Server启动过程源代码分析
- Android系统进程间通信(IPC)机制Binder中的Server启动过程源代码分析
- Android系统进程间通信(IPC)机制Binder中的Server启动过程源代码分析
- Android系统进程间通信(IPC)机制Binder中的Server启动过程源代码分析
- Android系统进程间通信(IPC)机制Binder中的Server启动过程源代码分析
- Android系统进程间通信(IPC)机制Binder中的Server启动过程源代码分析
- Android系统进程间通信(IPC)机制Binder中的Server启动过程源代码分析
- Android源码解析之广播(Broadcast)机制简要介绍和学习计划
- 基于Windows10 x64+visual Studio2013+Python2.7.12环境下的Caffe配置学习
- Oracal11g的安装教程
- MongoDB Plugin 部分文档
- 一款可以驱动三相无刷直流电机的驱动IC AT8313
- Android 8.0系统源码分析--Binder进程间通信(三)
- lua 代码规范
- qemu模拟器搭建arm运行环境
- javascript中函数eval()的用法
- PHP编程之路,第一期 composer+laravel 创建项目、启动项目
- oracle安装
- 凤凰金融邢志峰:人工智能打败人类只是一个开始,AI真正落地业务场景仍面临严峻挑战
- WinSCP(版本5.7.6)中文文件名显示乱码
- LayUi