天天看点

Android 8.0系统源码分析--Binder进程间通信(三)

     没事了就看看老罗的书,感觉老罗是走过来的人,说出来的话都是硬道理,我们开始分析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方法有三个重载,如下图:

Android 8.0系统源码分析--Binder进程间通信(三)

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

     吃晚饭吧!!!

继续阅读