美文网首页
ServiceManager Java 代理对象的获取

ServiceManager Java 代理对象的获取

作者: ColdWave | 来源:发表于2018-07-21 16:51 被阅读0次

    我们先把 Binder 相关的文件罗列一下:

    JNI: framework/base/core/jni/android_util_Binder.cpp
    
    Java: 
    
    framework/base/core/java/com/android/internal/os/BinderInternal.java
    
    framework/base/core/java/android/os/IBinder.java
    framework/base/core/java/android/os/Binder.java
    
    framework/base/core/java/android/os/IInterface.java
    
    framework/base/core/java/android/os/IServiceManager.java
    framework/base/core/java/android/os/ServiceManagerNative.java
    framework/base/core/java/android/os/ServiceManager.java
    
    

    Binder 有 3 个类: IBinder, Binder, BinderProxy

    • IBinder 类似于 C++ 的 IBinder
    • Binder 类似于 C++ 的 BBinder
    • BinderProxy 类似于 C++ 的 BpBinder

    Binder 内部成员变量 mObject 指向了 C++ 的 BBinder, 这样, Java 和 C++ 就关联起来了.

    ServiceManager 提供了 3 个类: ServiceManager, ServiceManagerNative, ServiceManagerProxy

    • ServiceManagerNative 类似于 BnServiceManager
    • ServiceManagerProxy 类似于 BpServiceManager

    ServiceManager.java 中有一个静态成员变量 sServiceManager, ServiceManager 的静态成员函数 getService, checkService, addService, listService 都是通过它实现的.

    ServiceManager 提供了 getIServiceManager 方法来创建 ServiceManager 的 Java 代理对象,并且保存在 sServiceManager 中.

    getIServiceManager

    public final class ServiceManager {
        private static final String TAG = "ServiceManager";
    
        private static IServiceManager sServiceManager;
        private static HashMap<String, IBinder> sCache = new HashMap<String, IBinder>();
    
        private static IServiceManager getIServiceManager() {
            if (sServiceManager != null) {
                return sServiceManager;
            }
    
            // Find the service manager
            sServiceManager = ServiceManagerNative
                    .asInterface(Binder.allowBlocking(BinderInternal.getContextObject()));
            return sServiceManager;
        }
    
        ......
    };
    

    BinderInternal.getContextObject()

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

    android_os_BinderInternal_getContextObject

    // android_util_Binder.cpp
    static jobject android_os_BinderInternal_getContextObject(JNIEnv* env, jobject clazz)
    {
        sp<IBinder> b = ProcessState::self()->getContextObject(NULL); // 实例化 BpBinder
        return javaObjectForIBinder(env, b); // 创建 BinderProxy 对象
    }
    

    javaObjectForIBinder

    gBinderOffsets
    static struct bindernative_offsets_t
    {
        // Class state.
        jclass mClass;            // 指向 Java 层中的 Binder 类
        jmethodID mExecTransact;  // 指向 Java Binder 类的 execTransact 方法
    
        // Object state.
        jfieldID mObject;         // 指向 Java Binder 类的 mObject 变量
    
    } gBinderOffsets;
    
    static int int_register_android_os_Binder(JNIEnv* env)
    {
        jclass clazz = FindClassOrDie(env, kBinderPathName);
    
        gBinderOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
        gBinderOffsets.mExecTransact = GetMethodIDOrDie(env, clazz, "execTransact", "(IJJI)Z");
        gBinderOffsets.mObject = GetFieldIDOrDie(env, clazz, "mObject", "J");
    
        return RegisterMethodsOrDie(
            env, kBinderPathName,
            gBinderMethods, NELEM(gBinderMethods));
    }
    
    gBinderProxyOffsets
    static struct binderproxy_offsets_t
    {
        // Class state.
        jclass mClass;               // 指向 Java BinderProxy
        jmethodID mConstructor;      // 指向 Java BinderProxy init 方法
        jmethodID mSendDeathNotice;  // 指向 Java BinderProxy sendDeathNotice 方法
    
        // Object state.
        jfieldID mObject;           // 指向 Java BinderProxy mObject 变量
        jfieldID mSelf;             // 指向 Java BinderProxy mSelf 变量
        jfieldID mOrgue;            // 指向 Java BinderProxy mOrgue 变量
    
    } gBinderProxyOffsets;
    
    const char* const kBinderProxyPathName = "android/os/BinderProxy";
    
    static int int_register_android_os_BinderProxy(JNIEnv* env)
    {
        jclass clazz = FindClassOrDie(env, "java/lang/Error");
        gErrorOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
    
        clazz = FindClassOrDie(env, kBinderProxyPathName);
        gBinderProxyOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
        gBinderProxyOffsets.mConstructor = GetMethodIDOrDie(env, clazz, "<init>", "()V");
        gBinderProxyOffsets.mSendDeathNotice = GetStaticMethodIDOrDie(env, clazz, "sendDeathNotice",
                "(Landroid/os/IBinder$DeathRecipient;)V");
    
        gBinderProxyOffsets.mObject = GetFieldIDOrDie(env, clazz, "mObject", "J");
        gBinderProxyOffsets.mSelf = GetFieldIDOrDie(env, clazz, "mSelf",
                                                    "Ljava/lang/ref/WeakReference;");
        gBinderProxyOffsets.mOrgue = GetFieldIDOrDie(env, clazz, "mOrgue", "J");
    
        clazz = FindClassOrDie(env, "java/lang/Class");
        gClassOffsets.mGetName = GetMethodIDOrDie(env, clazz, "getName", "()Ljava/lang/String;");
    
        return RegisterMethodsOrDie(
            env, kBinderProxyPathName,
            gBinderProxyMethods, NELEM(gBinderProxyMethods));
    }
    
    gBinderInternalOffsets
    static struct binderinternal_offsets_t
    {
        // Class state.
        jclass mClass;       // 指向 Java BinderInternal 类
        jmethodID mForceGc;  // 指向 Java BinderInternal forceBinderGc 方法
    
    } gBinderInternalOffsets;
    
    static int int_register_android_os_BinderInternal(JNIEnv* env)
    {
        jclass clazz = FindClassOrDie(env, kBinderInternalPathName);
    
        gBinderInternalOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
        gBinderInternalOffsets.mForceGc = GetStaticMethodIDOrDie(env, clazz, "forceBinderGc", "()V");
    
        return RegisterMethodsOrDie(
            env, kBinderInternalPathName,
            gBinderInternalMethods, NELEM(gBinderInternalMethods));
    }
    
    javaObjectForIBinder
    jobject javaObjectForIBinder(JNIEnv* env, const sp<IBinder>& val)
    {
        if (val == NULL) return NULL;
    
        /*
         * val 指向的 BpBinder.
        */
        // checkSubclass 是 IBinder 定义. BpBinder 并没有重写, checkSubclass 返回 false
        // JavaBBinder 继承自 BBinder, checkSubclass 检查 subclassID 和 gBinderOffsets 是否相等,相等返回 true
        if (val->checkSubclass(&gBinderOffsets)) {
            /*
             * 如果 val 指向 JavaBBinder, 那么会进入
            */
            // One of our own!
            jobject object = static_cast<JavaBBinder*>(val.get())->object();       // 获取 Java 对象
            /*
             * JavaBBinder 的 mObject 实际上指向的是 Java 的一个 Binder 对象.
            */
            LOGDEATH("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/destruction of Java proxies for native Binder proxies.
        AutoMutex _l(mProxyLock);
    
        // 先看 BpBinder -> ObjectManager
    
        /*
         * findObject 检查当前进程是否已经创建过 BinderProxy 了?
        */
        // Someone else's...  do we know about it?
        jobject object = (jobject)val->findObject(&gBinderProxyOffsets);
        if (object != NULL) {
            jobject res = jniGetReferent(env, object);
            if (res != NULL) {
                ALOGV("objectForBinder %p: found existing %p!\n", val.get(), res);
                return res;
                /*
                 * 如果创建过 BinderProxy ,就直接返回了
                */
            }
            /*
             * 无效的 BinderProxy, 解除它.
            */
            LOGDEATH("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) {
            LOGDEATH("objectForBinder %p: created new proxy %p !\n", val.get(), object);
            // The proxy holds a reference to the native object.
            env->SetLongField(object, gBinderProxyOffsets.mObject, (jlong)val.get());
            val->incStrong((void*)javaObjectForIBinder);
    
            // 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);
    
            // Also remember the death recipients registered on this proxy
            sp<DeathRecipientList> drl = new DeathRecipientList;
            drl->incStrong((void*)javaObjectForIBinder);
            env->SetLongField(object, gBinderProxyOffsets.mOrgue, reinterpret_cast<jlong>(drl.get()));
    
            // Note that a new object reference has been created.
            android_atomic_inc(&gNumProxyRefs);
            incRefsCreated(env);
        }
    
        return object;
    }
    
    ObjectManager

    BpBinder 内部类型为 ObjectManager 的成员变量 mObjects, 用来管理与该 BpBinder 关联的外部对象.

    例如: javaObjectForIBinder 在为 BpBinder 创建 Java 的 BinderProxy 时,会将创建的 BinderProxy 用 ObjectManager 管理,以便后续使用.

    由于一个 BpBinder 可能关联多个 外部对象,因此,需要通过额外的参数来关联一个 BpBinder 和 BinderProxy, 这就是全局变量 gBinderProxyOffsets 的值.

    class BpBinder {
        class ObjectManager
        {
        public:
                        ObjectManager();
                        ~ObjectManager();
    
            void        attach( const void* objectID,
                                void* object,
                                void* cleanupCookie,
                                IBinder::object_cleanup_func func);
            void*       find(const void* objectID) const;
            void        detach(const void* objectID);
    
            void        kill();
    
        private:
                        ObjectManager(const ObjectManager&);
            ObjectManager& operator=(const ObjectManager&);
    
            struct entry_t
            {
                void* object;                       // object 指向外部对象的弱引用计数
                void* cleanupCookie;                // 是函数 object_cleanup_func 的参数
                IBinder::object_cleanup_func func;  // 用来清理成员变量 object 所指向的外部对象的函数
            };
    
            KeyedVector<const void*, entry_t> mObjects;
        };
    
    private:
        ObjectManager       mObjects;
    };
    

    ObjectManaer 在 BpBinder 析构时 析构.

    BpBinder::ObjectManager::ObjectManager()
    {
    }
    
    BpBinder::ObjectManager::~ObjectManager()
    {
        kill();
    }
    
    void BpBinder::ObjectManager::attach(
        const void* objectID, void* object, void* cleanupCookie,
        IBinder::object_cleanup_func func)
    {
        entry_t e;
        e.object = object;
        e.cleanupCookie = cleanupCookie;
        e.func = func;
    
        if (mObjects.indexOfKey(objectID) >= 0) {
            ALOGE("Trying to attach object ID %p to binder ObjectManager %p with object %p, but object ID already in use",
                    objectID, this,  object);
            return;
        }
    
        mObjects.add(objectID, e);
    }
    
    void* BpBinder::ObjectManager::find(const void* objectID) const
    {
        const ssize_t i = mObjects.indexOfKey(objectID);
        if (i < 0) return NULL;
        return mObjects.valueAt(i).object;
    }
    
    void BpBinder::ObjectManager::detach(const void* objectID)
    {
        mObjects.removeItem(objectID);
    }
    
    void BpBinder::ObjectManager::kill()
    {
        const size_t N = mObjects.size();
        ALOGV("Killing %zu objects in manager %p", N, this);
        /*
         * 遍历 mObjects, 然后调用每个外部对象的清理函数
        */
        for (size_t i=0; i<N; i++) {
            const entry_t& e = mObjects.valueAt(i);
            if (e.func != NULL) {
                e.func(mObjects.keyAt(i), e.object, e.cleanupCookie);
            }
        }
    
        mObjects.clear();
    }
    

    BpBinder 定义了几个方法来操作 ObjectManager

    void BpBinder::attachObject(
        const void* objectID, void* object, void* cleanupCookie,
        object_cleanup_func func)
    {
        AutoMutex _l(mLock);
        ALOGV("Attaching object %p to binder %p (manager=%p)", object, this, &mObjects);
        mObjects.attach(objectID, object, cleanupCookie, func);
    }
    
    void* BpBinder::findObject(const void* objectID) const
    {
        AutoMutex _l(mLock);
        return mObjects.find(objectID);
    }
    
    void BpBinder::detachObject(const void* objectID)
    {
        AutoMutex _l(mLock);
        mObjects.detach(objectID);
    }
    
    javaObjectForIBinder

    再次回到 javaObjectForIBinder.

    jobject javaObjectForIBinder(JNIEnv* env, const sp<IBinder>& val)
    {
        ......
    
        /*
         * 创建 BinderProxy
        */
        object = env->NewObject(gBinderProxyOffsets.mClass, gBinderProxyOffsets.mConstructor);
        if (object != NULL) {
            LOGDEATH("objectForBinder %p: created new proxy %p !\n", val.get(), object);
            // The proxy holds a reference to the native object.
            /*
             * BinderProxy 的成员变量 mObject 设置为 BpBinder 的地址 val
            */
            env->SetLongField(object, gBinderProxyOffsets.mObject, (jlong)val.get());
            val->incStrong((void*)javaObjectForIBinder);
    
            // 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));  // 先获取 BinderProxy mSelf, 然后增加全局 引用
            val->attachObject(&gBinderProxyOffsets, refObject,
                    jnienv_to_javavm(env), proxy_cleanup);
    
            // Also remember the death recipients registered on this proxy
            sp<DeathRecipientList> drl = new DeathRecipientList; // 创建死亡通知链表
            drl->incStrong((void*)javaObjectForIBinder);
            env->SetLongField(object, gBinderProxyOffsets.mOrgue, reinterpret_cast<jlong>(drl.get()));
            // BinderProxy mOrgue 指向死亡通知链表
    
            // Note that a new object reference has been created.
            android_atomic_inc(&gNumProxyRefs);
            incRefsCreated(env);
        }
    
        return object;
    }
    
    /*
     * 如果 创建了 200个 BinderProxy ,就主动申请 Java 进行 GC 操作.
    */
    static void incRefsCreated(JNIEnv* env)
    {
        int old = android_atomic_inc(&gNumRefsCreated);
        if (old == 200) {
            android_atomic_and(0, &gNumRefsCreated);
            env->CallStaticVoidMethod(gBinderInternalOffsets.mClass,
                    gBinderInternalOffsets.mForceGc);
        } else {
            ALOGV("Now have %d binder ops", old);
        }
    }
    

    getIServiceManager

    再次回到 getIServiceManager

    public final class ServiceManager {
        private static final String TAG = "ServiceManager";
    
        private static IServiceManager sServiceManager;
        private static HashMap<String, IBinder> sCache = new HashMap<String, IBinder>();
    
        private static IServiceManager getIServiceManager() {
            if (sServiceManager != null) {
                return sServiceManager;
            }
    
            // Find the service manager
            sServiceManager = ServiceManagerNative
                    .asInterface(Binder.allowBlocking(BinderInternal.getContextObject()));
            return sServiceManager;
        }
    
        ......
    };
    
    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);
            /*
             * static final String descriptor = "android.os.IServiceManager"; (IServiceManager.java)
             * obj 是个什么玩意儿? 是 BinderProxy, 并且 BinderProxy 是和 BpBinder 进行了关联.
             * 
             * BinderProxy 的 queryLocalInterface 返回 null [ 这个 C++ 的 BpBinder 的 queryLocalInterface 返回 NULL 一致 ]
             * 
            */
            
            if (in != null) {
                return in;
            }
            
            return new ServiceManagerProxy(obj);  // 创建 ServiceManagerProxy
        }
    }
    

    相关文章

      网友评论

          本文标题:ServiceManager Java 代理对象的获取

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