美文网首页
Binder之三:ServiceManager的获取

Binder之三:ServiceManager的获取

作者: 81bad73e9053 | 来源:发表于2016-10-16 18:58 被阅读800次

    第三部分 Binder之三:ServiceManager的获取

    0 入口. getIServiceManager()

    ServiceManager.java

        private static IServiceManager sServiceManager;
        private static IServiceManager getIServiceManager() {
            if (sServiceManager != null) {
                return sServiceManager;
            }
    
            // Find the service manager
            sServiceManager = ServiceManagerNative.asInterface(BinderInternal.getContextObject());
            return sServiceManager;
        }
    

    1. asInterface

    ServiceManagerNative

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

    2. ServiceManagerProxy的构造函数

    ServiceManagerProxy是SM的代理,必定会参与Binder通信,所以在构造函数中传进来了一个IBinder对象。其实ServiceManagerProxy中的所有操作最终都是通过这个IBinder对象来完成的。

    //IServiceManager.java中定义了SM的所有功能
    class ServiceManagerProxy implements IServiceManager {
        
        private IBinder mRemote;
        
        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 {
           //...
        }
    
        public void setPermissionController(IPermissionController controller)
                throws RemoteException { 
                //...
        } 
    }
    

    3.IBinder的queryLocalInterface方法

    我们的目标是为应用程序使用SM服务提供方便,其中的核心是ServiceManagerProxy,其外围又包装了ServiceManager.java和ServiceManagerNative.java。
    在创建ServiceManagerProxy的时候,传入了一个IBinder对象,然后借助于它的transact方法,可以方便的与BInderDriver进行通信。
    用户希望通过尽可能精简的步骤来使用BInder的功能,Binder的功能可以统一在IBinder中表示

    public interface IBinder {
         ...
         public IInterface queryLocalInterface(String descriptor);
         public boolean transact(int code, Parcel data, Parcel reply, int flags)
            throws RemoteException;
         ...
    }
    

    4.BInderInternal.getContextObject();

    获取IBinder的类是BInderInternal

     public class BinderInternal {
              ...
          public static final native IBinder getContextObject();
              ...
    }
    

    getContextObject是native 方法,需要jni实现

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

    IBinder只是一个接口,在Native层,它的实现类是BpBinder.cpp,在java层它的实现是Binder.java中的BinderProxy,通过 ProcessState::self()->getContextObject(NULL)返回一个BpBinder,然后通过javaObjectForIBinder方法转换成BinderProxy

    6.BinderProxy的transact方法

    BinderProxy的transact方法

        public boolean transact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {
            Binder.checkParcel(this, code, data, "Unreasonably large binder buffer");
            return transactNative(code, data, reply, flags);
        }
    //会执行到这里,这里是一个本地方法
    public native boolean transactNative(int code, Parcel data, Parcel reply,
                int flags) throws RemoteException;
    

    native实现

    static jboolean android_os_BinderProxy_transact(JNIEnv* env, jobject obj,
            jint code, jobject dataObj, jobject replyObj, jint flags) // throws RemoteException
    {
        //data和reply分别是来自BinderProxy的参数,这里是把他们专程native中的Parcel实现
        Parcel* data = parcelForJavaObject(env, dataObj);
       
        Parcel* reply = parcelForJavaObject(env, replyObj);
        
        IBinder* target = (IBinder*)
            env->GetLongField(obj, gBinderProxyOffsets.mObject);
     
    
        //IBinder的native实现是BpBinder,所以这里就是调用BpBinder的transact方法
        status_t err = target->transact(code, *data, reply, flags); 
    
        signalExceptionForError(env, obj, err, true /*canThrowRemoteException*/, data->dataSize());
        return JNI_FALSE;
    }
    

    BpBinder的transact方法:最终会调用到IPCThreadState::self()->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) {
           //调用IPCThreadState的transact方法
            status_t status = IPCThreadState::self()->transact(
                mHandle, code, data, reply, flags);
            if (status == DEAD_OBJECT) mAlive = 0;
            return status;
        }
    
        return DEAD_OBJECT;
    }
    

    概览

    Paste_Image.png

    总体分为三大步
    1.ProcessState::self():用于获取ProcessState对象(也是单例模式),每个进程有且只有一个ProcessState对象,存在则直接返回,不存在则创建(1-3)
    2.getContextObject(): 用于获取BpBiner对象,对于handle=0的BpBiner对象,存在则直接返回,不存在才创建(4-7)
    3.interface_cast<IServiceManager>():创建BpServiceManager对象(8-10)

    sp<IServiceManager> defaultServiceManager()
    {
        if (gDefaultServiceManager != NULL) return gDefaultServiceManager;
        
        {
            AutoMutex _l(gDefaultServiceManagerLock);
            while (gDefaultServiceManager == NULL) {
                gDefaultServiceManager = interface_cast<IServiceManager>(
                    ProcessState::self()->getContextObject(NULL));
                if (gDefaultServiceManager == NULL)
                    sleep(1);
            }
        }
        
        return gDefaultServiceManager;
    }
    

    1-3 ProcessState和IPCThreadState

    ProcessState:专门管理进程中Binder操作的类,执行Binder驱动的一系列名对对上层用户透明。ProcessState采用单粒模式创建ProcessState::self,在构造函数的中通过binder_open,binder_mmap等操作建立了与BinderDriver通信的通道。

    在BinderDriver的分析中可以看到binder_proc中有threads红黑树用来管理进程中所有线程的IPC业务,进程中每个线程都有与BinderDriver沟通的权利,与BiderDriver驱动实际进行命令通信的是IPCThreadState

    1. ProcessState::self

    sp<ProcessState> ProcessState::self()
    {
     Mutex::Autolock _l(gProcessMutex);
     if (gProcess != NULL) {
     return gProcess;
     }
    
     //实例化ProcessState  
     gProcess = new ProcessState;
     return gProcess;
    }
    

    2. new ProcessState

    ProcessState::ProcessState()
     : mDriverFD(open_driver()) // 打开Binder驱动 
     , mVMStart(MAP_FAILED)
     , mThreadCountLock(PTHREAD_MUTEX_INITIALIZER)
     , mThreadCountDecrement(PTHREAD_COND_INITIALIZER)
     , mExecutingThreadsCount(0)
     , mMaxThreads(DEFAULT_MAX_BINDER_THREADS)
     , mManagesContexts(false)
     , mBinderContextCheckFunc(NULL)
     , mBinderContextUserData(NULL)
     , mThreadPoolStarted(false)
     , mThreadPoolSeq(1)
    {
     if (mDriverFD >= 0) {
     //采用内存映射函数mmap,给binder分配一块虚拟地址空间,用来接收事务
     mVMStart = mmap(0, BINDER_VM_SIZE, PROT_READ, MAP_PRIVATE | MAP_NORESERVE, mDriverFD, 0);
     if (mVMStart == MAP_FAILED) {
     close(mDriverFD); //没有足够空间分配给/dev/binder,则关闭驱动
     mDriverFD = -1;
     }
     }
    }
    

    3.open_driver

    static int open_driver()
    {
     // 打开/dev/binder设备,建立与内核的Binder驱动的交互通道
     int fd = open("/dev/binder", O_RDWR);
     if (fd >= 0) {
     fcntl(fd, F_SETFD, FD_CLOEXEC);
     int vers = 0;
     status_t result = ioctl(fd, BINDER_VERSION, &vers);
     if (result == -1) {
     close(fd);
     fd = -1;
     }
     if (result != 0 || vers != BINDER_CURRENT_PROTOCOL_VERSION) {
     close(fd);
     fd = -1;
     }
     size_t maxThreads = DEFAULT_MAX_BINDER_THREADS;
    
     // 通过ioctl设置binder驱动,能支持的最大线程数
     result = ioctl(fd, BINDER_SET_MAX_THREADS, &maxThreads);
     if (result == -1) {
     ALOGE("Binder ioctl to set max threads failed: %s", strerror(errno));
     }
     } else {
     ALOGW("Opening '/dev/binder' failed: %s\n", strerror(errno));
     }
     return fd;
    

    4. getContextObject:获取handle=0的IBinder

    sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& /*caller*/)
    {
     return getStrongProxyForHandle(0);  
    }
    

    5.getStrongProxyForHandle

    sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle)
    {
     sp<IBinder> result;
    
     AutoMutex _l(mLock);
     //查找handle对应的资源项
     handle_entry* e = lookupHandleLocked(handle);
    
     if (e != NULL) {
     IBinder* b = e->binder;
     if (b == NULL || !e->refs->attemptIncWeak(this)) {
     if (handle == 0) {
     Parcel data;
     //通过ping操作测试binder是否准备就绪
     status_t status = IPCThreadState::self()->transact(
     0, IBinder::PING_TRANSACTION, data, NULL, 0);
     if (status == DEAD_OBJECT)
     return NULL;
     }
     //当handle值所对应的IBinder不存在或弱引用无效时,则创建BpBinder对象 
     b = new BpBinder(handle);
     e->binder = b;
     if (b) e->refs = b->getWeakRefs();
     result = b;
     } else {
     result.force_set(b);
     e->refs->decWeak(this);
     }
     }
     return result;
    }
    

    6. lookupHandleLocked

    根据handle值来查找对应的handle_entry,handle_entry是一个结构体,里面记录IBinder和weakref_type两个指针。当handle大于mHandleToObject的Vector长度时,则向该Vector中添加(handle+1-N)个handle_entry结构体,然后再返回handle向对应位置的handle_entry结构体指针

    ProcessState::handle_entry* ProcessState::lookupHandleLocked(int32_t handle)
    {
     const size_t N=mHandleToObject.size();
     //当handle大于mHandleToObject的长度时,进入该分支
     if (N <= (size_t)handle) {
     handle_entry e;
     e.binder = NULL;
     e.refs = NULL;
     //从mHandleToObject的第N个位置开始,插入(handle+1-N)个e到队列中
     status_t err = mHandleToObject.insertAt(e, N, handle+1-N);
     if (err < NO_ERROR) return NULL;
     }
     return &mHandleToObject.editItemAt(handle);
    }
    

    7.new BpBinder

    BpBinder::BpBinder(int32_t handle)
     : mHandle(handle)
     , mAlive(1)
     , mObitsSent(0)
     , mObituaries(NULL)
    {
     extendObjectLifetime(OBJECT_LIFETIME_WEAK); //延长对象的生命时间
     IPCThreadState::self()->incWeakHandle(handle); //handle所对应的bindle弱引用 + 1
    }
    

    8.interface_cast

    template<typename INTERFACE>
    inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj)
    {
     return INTERFACE::asInterface(obj); //【见流程10】
    }
    

    9.IServiceManager::asInterface

    //位于IServiceManager.h文件
    DECLARE_META_INTERFACE(IServiceManager)
    //位于IServiceManager.cpp文件
    IMPLEMENT_META_INTERFACE(ServiceManager,"android.os.IServiceManager")
    

    9.1

    const android::String16 IServiceManager::descriptor(“android.os.IServiceManager”);
    
    const android::String16& IServiceManager::getInterfaceDescriptor() const
    {
     return IServiceManager::descriptor;
    }
    
     android::sp<IServiceManager> IServiceManager::asInterface(const android::sp<android::IBinder>& obj)
    {
     android::sp<IServiceManager> intr;
     if(obj != NULL) {
     intr = static_cast<IServiceManager *>(
     obj->queryLocalInterface(IServiceManager::descriptor).get());
     if (intr == NULL) {
     intr = new BpServiceManager(obj); //【见流程11】
     }
     }
     return intr;
    }
    
    IServiceManager::IServiceManager () { }
    IServiceManager::~ IServiceManager() { }
    

    10 new BpServiceManager

    10.1初始化BpServiceManager

    BpServiceManager(const sp<IBinder>& impl)
     : BpInterface<IServiceManager>(impl)
    {
    }
    

    10.2 初始化父类BpInterface

    inline BpInterface<INTERFACE>::BpInterface(const sp<IBinder>& remote)
     :BpRefBase(remote)
    {
    }
    

    10.3 初始化父类BpRefBase

    BpRefBase::BpRefBase(const sp<IBinder>& o)
     : mRemote(o.get()), mRefs(NULL), mState(0)
    {
     extendObjectLifetime(OBJECT_LIFETIME_WEAK);
    
     if (mRemote) {
     mRemote->incStrong(this);
     mRefs = mRemote->createWeak(this);
     }
    }
    

    参考
    《深入理解android内核设计》
    Binder系列4—获取ServiceManager

    相关文章

      网友评论

          本文标题:Binder之三:ServiceManager的获取

          本文链接:https://www.haomeiwen.com/subject/acqayttx.html