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通信代码已经非常稳定了。虽然写了这三篇博客,但是感觉还是有很多不清楚的地方,后续还要继续努力。

     吃晚饭吧!!!

阅读全文
0 0
原创粉丝点击