Binder—从Ams注册到ServiceManager的角度来观察Binder的运行机制

0.前言


1.Binder前夕-AMS从SytemServer到ServiceManger的大致流程


SystemServer#main()

位置:frameworks\base\services\java\com\android\server\SystemServer.java#ServerThread

看一波它的代码目录结构:
2内部类。若干方法。

main方法:

    public static void main(String[] args) {
       .......

        System.loadLibrary("android_servers");
        init1(args);
    }

SystemServer#native init1()

   /**
     * This method is called from Zygote to initialize the system. This will cause the native
     * services (SurfaceFlinger, AudioFlinger, etc..) to be started. After that it will call back
     * up into init2() to start the Android services.
     */
    native public static void init1(String[] args);

com_android_server_SystemServer#init1()

位置:frameworks\base\services\jni\com_android_server_SystemServer.cpp

static void android_server_SystemServer_init1(JNIEnv* env, jobject clazz)
{
    system_init();
}

com_android_server_SystemServer#system_init()

system_init方法实际上就是初始化一堆系统服务,然后调用init2方法

extern "C" status_t system_init()
{
    ......

    // 启动AudioFunger
    // On the simulator, audioflinger et al don't get started the
    // same way as on the device, and we need to start them here
    if (!proc->supportsProcesses()) {

        // Start the AudioFlinger
        AudioFlinger::instantiate();

        // Start the media playback service
        MediaPlayerService::instantiate();

        // Start the camera service
        CameraService::instantiate();

        // Start the audio policy service
        AudioPolicyService::instantiate();
    }


    //因为Android运行时初始化需要,所以必须启动 Android Runtime
    LOGI("System server: starting Android runtime.\n");

    AndroidRuntime* runtime = AndroidRuntime::getRuntime();

    //这儿调用了init2
    LOGI("System server: starting Android services.\n");
    runtime->callStatic("com/android/server/SystemServer", "init2");

    ......
    return NO_ERROR;
}

SystemServer#init2()

init2方法:new了一个ServerThread线程

    public static final void init2() {
        Slog.i(TAG, "Entered the Android system server!");
        Thread thr = new ServerThread();
        thr.setName("android.server.ServerThread");
        thr.start();
    }

SystemServer#ServerThread

这个ServerThread是SystemServer的一个内部类,很重要的一个线程。
1.类开头和结尾,Looper.prepare();Looper.loop(),说明这个类里边利用了Looper机制;
2.System Server会启动一系列的Service, 其中最重要的就是Acitivity Manager 和Window Manager.
3.这里又出现了一个重要的角色,ServiceManagerServiceManager.addService(String name, IBinder service),第二个参数为Binder。所以这里也是用到了IPC,这里不深究,我们的主线任务时Ams与ServiceManager。


    class ServerThread extends Thread {
        private static final String TAG = "SystemServer";
        ......


        @Override
        public void run() {
            EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_SYSTEM_RUN,
                SystemClock.uptimeMillis());

            Looper.prepare();

            ......

            // Critical services...
            try {

                ......

                Slog.i(TAG, "Activity Manager");
                context = ActivityManagerService.main(factoryTest);

                ......

                ActivityManagerService.setSystemProcess();

                ......
            }

            ......

            Looper.loop();
            Slog.d(TAG, "System ServerThread is exiting!");
        }

    }

ActivityManagerService#main()

一开始就 new AThread()。

    public static final Context main(int factoryTest) {
        AThread thr = new AThread();
        thr.start();

        synchronized (thr) {
            while (thr.mService == null) {
                try {
                    thr.wait();
                } catch (InterruptedException e) {
                }
            }
        }

        ActivityManagerService m = thr.mService;
        mSelf = m;
        ActivityThread at = ActivityThread.systemMain();
        mSystemThread = at;
        Context context = at.getSystemContext();
        m.mContext = context;
        m.mFactoryTest = factoryTest;
        m.mMainStack = new ActivityStack(m, context, true);

        m.mBatteryStatsService.publish(context);
        m.mUsageStatsService.publish(context);

        synchronized (thr) {
            thr.mReady = true;
            thr.notifyAll();
        }

        m.startRunning(null, null, null, null);

        return context;
    }

ActivityManagerService#AThread()

到这一步,ActivityManagerService的实例便被初始化了出来。


  static class AThread extends Thread {
        ActivityManagerService mService;
        boolean mReady = false;

        public AThread() {
            super("ActivityManager");
        }

        public void run() {
            Looper.prepare();

            ......

            ActivityManagerService m = new ActivityManagerService();

            synchronized (this) {
                mService = m;
                notifyAll();
            }

            ......

            Looper.loop();
        }
    }

ActivityManagerService#setSystemProcess()


 public static void setSystemProcess() {
        try {
            ActivityManagerService m = mSelf;

            ServiceManager.addService("activity", m);
            ServiceManager.addService("meminfo", new MemBinder(m));
            if (MONITOR_CPU_USAGE) {
                ServiceManager.addService("cpuinfo", new CpuBinder(m));
            }
            ServiceManager.addService("permission", new PermissionController(m));

            ApplicationInfo info =
                mSelf.mContext.getPackageManager().getApplicationInfo(
                        "android", STOCK_PM_FLAGS);
            mSystemThread.installSystemApplicationInfo(info);

            synchronized (mSelf) {
                ProcessRecord app = mSelf.newProcessRecordLocked(
                        mSystemThread.getApplicationThread(), info,
                        info.processName);
                app.persistent = true;
                app.pid = MY_PID;
                app.maxAdj = SYSTEM_ADJ;
                mSelf.mProcessNames.put(app.processName, app.info.uid, app);
                synchronized (mSelf.mPidsSelfLocked) {
                    mSelf.mPidsSelfLocked.put(app.pid, app);
                }
                mSelf.updateLruProcessLocked(app, true, true);
            }
        } catch (PackageManager.NameNotFoundException e) {
            throw new RuntimeException(
                    "Unable to find android system package", e);
        }
    }

我们可以看到这里几个ServiceManager.addService(m),m就是Ams自身,我们暂且不去深究每一个服务是什么功能,到目前为止可以认为Ams已经在想ServiceManger发起请求,注册服务到ServiceManger了。下面将正式进入Binder的分析。

2.Binder核心-观察AMS注册到ServiceManager以观察Binder机制


流程图

ActivityManagerService#ServiceManager.addService()

    ServiceManager.addService("activity", m);
    ServiceManager.addService("meminfo", new MemBinder(m));
    if (MONITOR_CPU_USAGE) {
        ServiceManager.addService("cpuinfo", new CpuBinder(m));
    }
    ServiceManager.addService("permission", new PermissionController(m));

ServiceManager#addService

位置:frameworks\base\core\java\android\os\ServiceManager.java

这个类代码量不多,122行,我们重点关注addService()方法。


    /** @hide */
    public final class ServiceManager {

        ...

        public static void addService(String name, IBinder service) {
            try {
                getIServiceManager().addService(name, service);
            } catch (RemoteException e) {
                Log.e(TAG, "error in addService", e);
            }
        }

        ...

    }

ServiceManager#getIServiceManager

位置:frameworks\base\core\java\android\os\ServiceManager.java

高能预警,这个方法看似不起眼,功能也就是给变量sServiceManager赋值(通过:ServiceManagerNative.asInterface(BinderInternal.getContextObject())),但它涉及了非常多的概念,这里应该快要触及Binder的核心了,
它是上一步addService内被调用返回一个IServiceManager,多态调用了IServiceManager.addService。这个IServiceManager一看就是个抽象接口。这里我不贴它代码。
我们主要关注这俩:ServiceManagerNative.asInterfaceBinderInternal.getContextObject()


    /** @hide */
    public final class ServiceManager {

        ...

        private static IServiceManager getIServiceManager() {
            if (sServiceManager != null) {
                return sServiceManager;
            }

            // Find the service manager
            sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject());
            return sServiceManager;
        }

        ...

    }

BinderInternal#native getContextObject

关于BinderInternal.getContextObject(),这个返回值挺重要的,它是一个IBinder对象(它最终会被转换成IServiceManager),由于这个方法是抽象的,所以我们需要关注获取到的对象究竟是什么,因为实现就在这个对象内部。

可以看到是个native方法。返回值就是一个IBinder。


    public class BinderInternal {

        /**
         * Return the global "context object" of the system.  This is usually
         * an implementation of IServiceManager, which you can use to find
         * other services.
         */
        public static final native IBinder getContextObject();

    }

frameworks\base\core\jni\android_util_Binder.cpp#android_os_BinderInternal_getContextObject()

这里牵涉到的概念又有个重要的,ProcessState。

    public abstract class ServiceManagerNative extends Binder implements IServiceManager {

        static jobject android_os_BinderInternal_getContextObject(JNIEnv* env, jobject clazz)
        {
            sp<IBinder> b = ProcessState::self()->getContextObject(NULL);
            return javaObjectForIBinder(env, b);
        }
    }

frameworks\base\libs\binder\ProcessState.cpp#self()

这一步是初始化ProcessState构造,构造内又去打开了driver。

    sp<ProcessState> ProcessState::self()
    {
        if (gProcess != NULL) return gProcess;

        AutoMutex _l(gProcessMutex);
        if (gProcess == NULL) gProcess = new ProcessState;
        return gProcess;
    }

frameworks\base\libs\binder\ProcessState.cpp#getContextObject()

真实设备基本都能supportsProcesses()

    sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& caller)
    {
        if (supportsProcesses()) {
            return getStrongProxyForHandle(0);
        } else {
            return getContextObject(String16("default"), caller);
        }
    }

frameworks\base\libs\binder\ProcessState.cpp#getStrongProxyForHandle(0)

new了一个BpBinder,一路返回给frameworks\base\core\jni\android_util_Binder.cpp#android_os_BinderInternal_getContextObject()。


    sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle)
    {
        ...

        if (e != NULL) {
            ...
            IBinder* b = e->binder;
            if (b == NULL || !e->refs->attemptIncWeak(this)) {
                b = new BpBinder(handle); //new了一个BpBinder
                e->binder = b;
                if (b) e->refs = b->getWeakRefs();
                result = b;
            } else {
                ...
                result.force_set(b);
                e->refs->decWeak(this);
            }
        }

        return result;
    }

frameworks\base\libs\binder\ProcessState.cpp#javaObjectForIBinder()

c++层对返回来的Ibinder一顿操作,然后返回给java层ServiceManager的getISericeManager()。


    jobject javaObjectForIBinder(JNIEnv* env, const sp<IBinder>& val)
    {
        if (val == NULL) return NULL;

        if (val->checkSubclass(&gBinderOffsets)) {
            // One of our own!
            jobject object = static_cast<JavaBBinder*>(val.get())->object();
            //printf("objectForBinder %p: it's our own %p!\n", val.get(), object);
            return object;
        }

        // For the rest of the function we will hold this lock, to serialize
        // looking/creation of Java proxies for native Binder proxies.
        AutoMutex _l(mProxyLock);

        // Someone else's...  do we know about it?
        jobject object = (jobject)val->findObject(&gBinderProxyOffsets);
        if (object != NULL) {
            jobject res = env->CallObjectMethod(object, gWeakReferenceOffsets.mGet);
            if (res != NULL) {
                LOGV("objectForBinder %p: found existing %p!\n", val.get(), res);
                return res;
            }
            LOGV("Proxy object %p of IBinder %p no longer in working set!!!", object, val.get());
            android_atomic_dec(&gNumProxyRefs);
            val->detachObject(&gBinderProxyOffsets);
            env->DeleteGlobalRef(object);
        }

        object = env->NewObject(gBinderProxyOffsets.mClass, gBinderProxyOffsets.mConstructor);
        if (object != NULL) {
            LOGV("objectForBinder %p: created new %p!\n", val.get(), object);
            // The proxy holds a reference to the native object.
            env->SetIntField(object, gBinderProxyOffsets.mObject, (int)val.get());
            val->incStrong(object);

            // The native object needs to hold a weak reference back to the
            // proxy, so we can retrieve the same proxy if it is still active.
            jobject refObject = env->NewGlobalRef(
                    env->GetObjectField(object, gBinderProxyOffsets.mSelf));
            val->attachObject(&gBinderProxyOffsets, refObject,
                    jnienv_to_javavm(env), proxy_cleanup);

            // Note that a new object reference has been created.
            android_atomic_inc(&gNumProxyRefs);
            incRefsCreated(env);
        }

        return object;
    }

frameworks\base\core\java\android\os\ServiceManagerNative#asInteface()

queryLocalInterface包含了查询逻辑,是返回本地服务还是远程代理服务。


  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);
    }

frameworks\base\core\java\android\os\Binder#queryLocalInterface()

这儿为什么是Binder类?因上面调的是IBInder,而其实现方法在Binder内,Binder是其子类。
传入参数为”android.OS.IServiceManager”,这里返回为空,说明不是本地服务,返回一个远程代理服务。
new ServiceManagerProxy,见上一步。
返回之后会去调它的addService()方法。


    public IInterface queryLocalInterface(String descriptor) {
        if (mDescriptor.equals(descriptor)) {
            return mOwner;
        }
        return null;
    }

frameworks\base\core\java\android\os\ServiceManagerNative$ServiceManagerProxy.java#addService()

mRemote是个IBinder,由于它是代理对象,所以是ProxyBinder.transact()。

  public void addService(String name, IBinder service)
            throws RemoteException {
        Parcel data = Parcel.obtain();
        Parcel reply = Parcel.obtain();
        data.writeInterfaceToken(IServiceManager.descriptor);
        data.writeString(name);
        data.writeStrongBinder(service);
        mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0);//多态调用transact
        reply.recycle();
        data.recycle();
    }

frameworks\base\core\java\android\os\BinderProxy.java

该方法是native的。

 public native boolean transact(int code, Parcel data, Parcel reply,
            int flags) throws RemoteException;

frameworks\base\core\jni\android_util_Binder.cpp#android_os_BinderProxy_transact()

从 parce 里读,读出来是个bPBinder,然后target->transact,就调到了BpBinder里边的transact()


    static jboolean android_os_BinderProxy_transact(JNIEnv* env, jobject obj,
                                                    jint code, jobject dataObj,
                                                    jobject replyObj, jint flags)
    {

        ...

        Parcel* data = parcelForJavaObject(env, dataObj);
        if (data == NULL) {
            return JNI_FALSE;
        }
        Parcel* reply = parcelForJavaObject(env, replyObj);
        if (reply == NULL && replyObj != NULL) {
            return JNI_FALSE;
        }

        ...

        //printf("Transact from Java code to %p sending: ", target); data->print();
        status_t err = target->transact(code, *data, reply, flags);
        ...

        signalExceptionForError(env, obj, err);
        return JNI_FALSE;
    }

frameworframeworks\base\libs\binder.java#transact()

这里又出现了一个新东西,IPCThreadState,调了它的transact

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

        return DEAD_OBJECT;
    }

frameworks\base\libs\binder\IPCThreadState#transact()

这里又调用了writeTransactionData方法。

    status_t IPCThreadState::transact(int32_t handle,
                                      uint32_t code, const Parcel& data,
                                      Parcel* reply, uint32_t flags)
    {
        ...

        if (err == NO_ERROR) {
            LOG_ONEWAY(">>>> SEND from pid %d uid %d %s", getpid(), getuid(),
                (flags & TF_ONE_WAY) == 0 ? "READ REPLY" : "ONE WAY");
            err = writeTransactionData(BC_TRANSACTION, flags, handle, code, data, NULL);
        }

        ...

        return err;
    }

frameworks\base\libs\binder\IPCThreadState#waitForResponse()

这里调用talkWithDriver()



    status_t IPCThreadState::waitForResponse(Parcel *reply, status_t *acquireResult)
    {
        int32_t cmd;
        int32_t err;

        while (1) {
            if ((err=talkWithDriver()) < NO_ERROR) break;
            err = mIn.errorCheck();
            if (err < NO_ERROR) break;
            if (mIn.dataAvail() == 0) continue;

            cmd = mIn.readInt32();

            IF_LOG_COMMANDS() {
                alog << "Processing waitForResponse Command: "
                    << getReturnString(cmd) << endl;
            }

            switch (cmd) {
            case BR_TRANSACTION_COMPLETE:
            ...
            case BR_DEAD_REPLY:
            ...

            }
        }

        ...

        return err;
    }

frameworks\base\libs\binder\IPCThreadState#talkWithDriver()

到这儿,就调到了binder驱动层的ioctl。本文到此结束。相当于真正的ipc还是在驱动层去实现的。


    status_t IPCThreadState::talkWithDriver(bool doReceive)
    {
        ...

        binder_write_read bwr;

        ...
        do {
            IF_LOG_COMMANDS() {
                alog << "About to read/write, write size = " << mOut.dataSize() << endl;
            }
    #if defined(HAVE_ANDROID_OS)
            if (ioctl(mProcess->mDriverFD, BINDER_WRITE_READ, &bwr) >= 0)
        ...
        }

        return err;
    }


附录


概念回顾

  • 直观来说,Binder是Android中的一个类,它继承了IBinder接口。
  • 从IPC角度来说,Binder是Android中的一种跨进程通信方式,该通信方式在Linux中没有。
  • Binder是ServiceManager连接各种Manager(ActivityManager、WindowManager,等等)和相应ManagerService的桥梁。
  • 从Android Framework角度来说,Binder是ServiceManager连接各种Manager(ActivityManager、WindowManager,等等)和相应ManagerService的桥梁。
  • 从Android应用层来说,Binder是客户端和服务端进行通信的媒介,当bindService的时候,服务端会返回一个包含了服务端业务调用的Binder对象,通过这个Binder对象,客户端就可以获取服务端提供的服务或者数据,这里的服务包括普通服务和基于AIDL的服务。
  • Binder还可以理解为一种虚拟的物理设备,它的设备驱动是/dev/binder。
  • Android开发中,Binder主要用在Service中,包括AIDL和Messenger,其中普通Service中的Binder不涉及进程间通信,所以较为简单,无法触及Binder的核心。而Messenger的底层其实是AIDL,所以这里选择用AIDL来分析Binder的工作机制。为了分析Binder的工作机制。

BpBinder、BBinder

  • BpBinder是客户端用来与Server交互的代理类,p即Proxy的意思。
    BBinder则是与proxy相对的一端,它是proxy交互的目的端。如果说Proxy代表客户端,那么BBinder则代表服务端。
  • BpBinder和BBinder是一一对应的,即某个BpBinder只能和对应的BBinder交互。我们当然不希望通过BpBinderA发送的请求,却由BBinderB来处理。
  • BpBinder如何标识它所对应的BBinder端呢?
    答案是Binder系统通过handler来标识对应的BBinder。以后我们会确认这个Handle值的作用。

Thanks


《android开发艺术探索》—任玉刚
《深入理解android卷2》—邓凡平
漫天尘沙:https://www.cnblogs.com/samchen2009/p/3294713.html
AIDL DEMO地址:https://github.com/zj614android/CaclAIDL
深入理解android卷,关于sp的分析:http://www.cnblogs.com/innost/archive/2011/09/06/2168453.html
ioctl:https://blog.csdn.net/shanshanpt/article/details/19897897

猜你喜欢

转载自blog.csdn.net/user11223344abc/article/details/80626391