Binder Java 层服务注册过程分析

1. Java 层整体框架

在分析之前,我们要明白,Java 只是一层方便 Java 程序使用的接口,Binder 的核心功能实现都是通过 JNI 调用到 Native 层来实现的,这里先给出 Java 层的整体框架图:

图片

接下来几篇文章我们逐步分析,解密整张框架图。

2. 服务注册

在 Binder 程序示例之 Java 篇 中介绍的示例程序中,Server 端我们使用如下代码添加我们定义的服务:

ServiceManager.addService("hello", new HelloService());

这里我们先关注一下 new HelloService() :

public class HelloService extends IHelloService.Stub {
    //......
}

HelloService 继承自 IHelloService.Stub:

public static abstract class Stub extends android.os.Binder implements com.yuandaima.IHelloService {

}

Stub 类继承自 Binder,那么当我们 new HelloService() 的时候,就会调用到 Binder 类的构造函数:

// frameworks/base/core/java/android/os/Binder.java
    public Binder() {
        this(null);
    }

    public Binder(@Nullable String descriptor)  {
        mObject = getNativeBBinderHolder();
        NoImagePreloadHolder.sRegistry.registerNativeAllocation(this, mObject);

        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());
            }
        }
        mDescriptor = descriptor;
    }    

其中 mObject 是一个 native 指针,指向 native 层的 JavaBBinderHolder 对象:

//mObject 是一个 native 指针,指向 native 层的 JavaBBinderHolder 对象
private final long mObject;

mObject = getNativeBBinderHolder();

// getNativeBBinderHolder 是一个 native 方法
private static native long getNativeBBinderHolder();

getNativeBBinderHolder 对应的 native 方法如下:

static jlong android_os_Binder_getNativeBBinderHolder(JNIEnv* env, jobject clazz)
{
    JavaBBinderHolder* jbh = new JavaBBinderHolder();
    return (jlong) jbh;
}

从名字可以看出 JavaBBinderHolder 就是 JavaBinder 的马甲:

class JavaBBinderHolder
{
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;
};

上面的内容总结一下:

  • Stub 类的父类是 Binder

  • Binder 中有一个 mObject 成员,是一个 native 指针,指向 native 层的 JavaBBinderHolder 对象

  • JavaBBinderHolder 就是 JavaBinder 的马甲,其内部有一个 mBinder 指针指向一个 JavaBinder 对象。服务端的 binder 操作都是通过这个 JavaBinder 对象来执行。

addService 是 frameworks/base/core/java/android/os/ServiceManager.java 中定义的静态方法:

@UnsupportedAppUsage
public static  void addService(String name, IBinder service) {
    addService(name, service, false, IServiceManager.DUMP_FLAG_PRIORITY_DEFAULT);
}

 @UnsupportedAppUsage
public static void addService(String name, IBinder service, boolean allowIsolated) {
    addService(name, service, allowIsolated, IServiceManager.DUMP_FLAG_PRIORITY_DEFAULT);
}

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

通过层层调用,调用到 getIServiceManager().addService(name, service, allowIsolated, dumpPriority); :

2.1 getIServiceManager()

我们先看看 getIServiceManager,该方法是定义在 ServiceManager 类中的静态方法:

//frameworks/base/core/java/android/os/ServiceManager.java
    @UnsupportedAppUsage
    private static IServiceManager getIServiceManager() {
        if (sServiceManager != null) {
            return sServiceManager;
        }

        // 等价于 new ServiceManagerProxy(new BinderProxy(0))
        // 但是实际过程有点曲折
        sServiceManager = ServiceManagerNative
                .asInterface(Binder.allowBlocking(BinderInternal.getContextObject()));
        return sServiceManager;
    }

接着我们逐一分析三个方法调用:

BinderInternal.getContextObject()
Binder.allowBlocking
ServiceManagerNative.asInterface
2.1.1 BinderInternal.getContextObject
//frameworks/base/core/java/com/android/internal/os/BinderInternal.java
// 返回一个 BinderProxy 对象
@UnsupportedAppUsage
public static final native IBinder getContextObject();

getContextObject 是一个 native 方法,在之前的文章中我们提到 BinderInternal 在进程启动时注册了其 native 方法,其 native 实现在 frameworks/base/core/jni/android_util_Binder.cpp 中:

static jobject android_os_BinderInternal_getContextObject(JNIEnv* env, jobject clazz)
{
    //此处返回的是 new BpBinder(0)  C++ 对象
    sp<IBinder> b = ProcessState::self()->getContextObject(NULL);
    //此处返回的是 new BinderProxy()  Java 对象
    return javaObjectForIBinder(env, b);
}

接着看 getContextObject 的实现:

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

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

    AutoMutex _l(mLock);

    handle_entry* e = lookupHandleLocked(handle);

    if (e != nullptr) {
        IBinder* b = e->binder;
        if (b == nullptr || !e->refs->attemptIncWeak(this)) {
            if (handle == 0) {
                Parcel data;
                status_t status = IPCThreadState::self()->transact(
                        0, IBinder::PING_TRANSACTION, data, nullptr, 0);
                if (status == DEAD_OBJECT)
                   return nullptr;
            }

            //走这里
            b = BpBinder::create(handle);
            e->binder = b;
            if (b) e->refs = b->getWeakRefs();
            result = b;
        } else {
            result.force_set(b);
            e->refs->decWeak(this);
        }
    }

    return result;
}

BpBinder* BpBinder::create(int32_t handle) {
    int32_t trackedUid = -1;
    if (sCountByUidEnabled) {
        trackedUid = IPCThreadState::self()->getCallingUid();
        AutoMutex _l(sTrackingLock);
        uint32_t trackedValue = sTrackingMap[trackedUid];
        if (CC_UNLIKELY(trackedValue & LIMIT_REACHED_MASK)) {
            if (sBinderProxyThrottleCreate) {
                return nullptr;
            }
        } else {
            if ((trackedValue & COUNTING_VALUE_MASK) >= sBinderProxyCountHighWatermark) {
                ALOGE("Too many binder proxy objects sent to uid %d from uid %d (%d proxies held)",
                      getuid(), trackedUid, trackedValue);
                sTrackingMap[trackedUid] |= LIMIT_REACHED_MASK;
                if (sLimitCallback) sLimitCallback(trackedUid);
                if (sBinderProxyThrottleCreate) {
                    ALOGI("Throttling binder proxy creates from uid %d in uid %d until binder proxy"
                          " count drops below %d",
                          trackedUid, getuid(), sBinderProxyCountLowWatermark);
                    return nullptr;
                }
            }
        }
        sTrackingMap[trackedUid]++;
    }
    //走这里
    return new BpBinder(handle, trackedUid);
}

代码看着很繁琐,实际流程其实很简单就是 new BpBinder(0)

接着看 javaObjectForIBinder 的实现:

//frameworks/base/core/jni/android_util_Binder.cpp

//当前情景下, val 的类型是 BpBinder
jobject javaObjectForIBinder(JNIEnv* env, const sp<IBinder>& val)
{
    if (val == NULL) return NULL;

    if (val->checkSubclass(&gBinderOffsets)) {
        // It's a JavaBBinder created by ibinderForJavaObject. Already has Java object.
        jobject object = static_cast<JavaBBinder*>(val.get())->object();
        LOGDEATH("objectForBinder %p: it's our own %p!\n", val.get(), object);
        return object;
    }

    //构造 BinderProxyNativeData 结构体
    BinderProxyNativeData* nativeData = new BinderProxyNativeData();
    nativeData->mOrgue = new DeathRecipientList;
    nativeData->mObject = val;

    //gBinderProxyOffsets 中保存了 BinderProxy 类相关的信息
    //调用 Java 层 GetInstance 方法获得一个 BinderProxy 对象
    jobject object = env->CallStaticObjectMethod(gBinderProxyOffsets.mClass,
            gBinderProxyOffsets.mGetInstance, (jlong) nativeData, (jlong) val.get());
    if (env->ExceptionCheck()) { //异常处理
        // In the exception case, getInstance still took ownership of nativeData.
        return NULL;
    }
    BinderProxyNativeData* actualNativeData = getBPNativeData(env, object);
    if (actualNativeData == nativeData) {
        // Created a new Proxy
        uint32_t numProxies = gNumProxies.fetch_add(1, std::memory_order_relaxed);
        uint32_t numLastWarned = gProxiesWarned.load(std::memory_order_relaxed);
        if (numProxies >= numLastWarned + PROXY_WARN_INTERVAL) {
            // Multiple threads can get here, make sure only one of them gets to
            // update the warn counter.
            if (gProxiesWarned.compare_exchange_strong(numLastWarned,
                        numLastWarned + PROXY_WARN_INTERVAL, std::memory_order_relaxed)) {
                ALOGW("Unexpectedly many live BinderProxies: %d\n", numProxies);
            }
        }
    } else {
        delete nativeData;
    }

    //返回 BinderProxy
    return object;
}

native 代码调用了 BinderProxy 的 getInstance 方法:

// frameworks/base/core/java/android/os/BinderProxy.java
 private static BinderProxy getInstance(long nativeData, long iBinder) {
        BinderProxy result;
        synchronized (sProxyMap) {
            try {
                result = sProxyMap.get(iBinder);
                if (result != null) {
                    return result;
                }
                result = new BinderProxy(nativeData);
            } catch (Throwable e) {
                // We're throwing an exception (probably OOME); don't drop nativeData.
                NativeAllocationRegistry.applyFreeFunction(NoImagePreloadHolder.sNativeFinalizer,
                        nativeData);
                throw e;
            }
            NoImagePreloadHolder.sRegistry.registerNativeAllocation(result, nativeData);
            // The registry now owns nativeData, even if registration threw an exception.
            sProxyMap.set(iBinder, result);
        }
        return result;
    }

代码很繁琐,但是从结果上来说还是比较简单的:

  • getContextObject 函数 new 了一个 BpBinder(c++结构体),其内部的 handle 是 0

  • javaObjectForIBinder 函数 new 了一个 BinderProxy(Java 对象),其内部成员 mNativeData 是一个 native 层指针,指向一个 BinderProxyNativeData,BinderProxyNativeData 的成员 mObject 指向上述的 BpBinder。

整体结构用一个图表示如下:

图片

2.1.2 Binder.allowBlocking
    //这里传入的是 BinderProxy 对象
    public static IBinder allowBlocking(IBinder binder) {
        try {
            if (binder instanceof BinderProxy) { //走这里
                ((BinderProxy) binder).mWarnOnBlocking = false;
            } else if (binder != null && binder.getInterfaceDescriptor() != null
                    && binder.queryLocalInterface(binder.getInterfaceDescriptor()) == null) {
                Log.w(TAG, "Unable to allow blocking on interface " + binder);
            }
        } catch (RemoteException ignored) {
        }
        return binder;
    }

这个方法比较简单,主要是设置 binder 的成员变量 mWarnOnBlocking 为 false。从名字来看,作用是允许阻塞调用。

2.1.3 ServiceManagerNative.asInterface
    //frameworks/base/core/java/android/os/ServiceManagerNative.java
    //传入的参数是 BinderProxy
    @UnsupportedAppUsage
    static public IServiceManager asInterface(IBinder obj)
    {
        if (obj == null) {
            return null;
        }

        //返回 null
        IServiceManager in =
            (IServiceManager)obj.queryLocalInterface(descriptor);
        if (in != null) {
            return in;
        }

        //走这里,构建一个 ServiceManagerProxy
        return new ServiceManagerProxy(obj);
    }

    //从名字来看,本来要做缓存的,但是没有做
    // frameworks/base/core/java/android/os/BinderProxy.java
    public IInterface queryLocalInterface(String descriptor) {
        return null;
    }

最终是构建一个 ServiceManagerProxy 结构体。其内部持有一个 BinderProxy 。

至此,getIServiceManager 的整体流程就分析完了。

2.2 addService

    // frameworks/base/core/java/android/os/ServiceManagerNative.java
    public void addService(String name, IBinder service, boolean allowIsolated, int dumpPriority)
            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);
        data.writeInt(dumpPriority);
        mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0);
        reply.recycle();
        data.recycle();
    }

构造两个 Parcel 结构,然后调用 mRemote.transact 发起远程过程调用。

mRemote 就是 new ServiceManagerProxy 时传入的 BinderProxy:

 public ServiceManagerProxy(IBinder remote) {
        mRemote = remote;
}

进入 frameworks/base/core/java/android/os/BinderProxy.java 查看:

public boolean transact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {
        Binder.checkParcel(this, code, data, "Unreasonably large binder buffer");

        //......

        try {
            //关注这里
            return transactNative(code, data, reply, flags);
        } finally {
           //......
        }
}

//native 方法
public native boolean transactNative(int code, Parcel data, Parcel reply,int flags) throws RemoteException;

transact 会调用 transactNative 发起远程调用,transactNative 是一个 native 方法,具体实现在 frameworks/base/core/jni/android_util_Binder.cpp

// obj 对应类型为 BinderProxy
static jboolean android_os_BinderProxy_transact(JNIEnv* env, jobject obj,
        jint code, jobject dataObj, jobject replyObj, jint flags) // throws RemoteException
{
    if (dataObj == NULL) {
        jniThrowNullPointerException(env, NULL);
        return JNI_FALSE;
    }

    // Java 对象 转为 c++ 对象
    Parcel* data = parcelForJavaObject(env, dataObj);
    if (data == NULL) {
        return JNI_FALSE;
    }

    // Java 对象 转为 c++ 对象
    Parcel* reply = parcelForJavaObject(env, replyObj);
    if (reply == NULL && replyObj != NULL) {
        return JNI_FALSE;
    }

    //拿到 BinderProxyNativeData 成员的 mObject,实际是一个 BpBinder
    IBinder* target = getBPNativeData(env, obj)->mObject.get();
    if (target == NULL) {
        jniThrowException(env, "java/lang/IllegalStateException", "Binder has been finalized!");
        return JNI_FALSE;
    }

    ALOGV("Java code calling transact on %p in Java object %p with code %" PRId32 "\n",
            target, obj, code);


    bool time_binder_calls;
    int64_t start_millis;
    if (kEnableBinderSample) {
        // Only log the binder call duration for things on the Java-level main thread.
        // But if we don't
        time_binder_calls = should_time_binder_calls();

        if (time_binder_calls) {
            start_millis = uptimeMillis();
        }
    }

    //BpBinder 发起远程调用
    status_t err = target->transact(code, *data, reply, flags);

    if (kEnableBinderSample) {
        if (time_binder_calls) {
            conditionally_log_binder_call(start_millis, target, code);
        }
    }

    if (err == NO_ERROR) {
        return JNI_TRUE;
    } else if (err == UNKNOWN_TRANSACTION) {
        return JNI_FALSE;
    }

    signalExceptionForError(env, obj, err, true /*canThrowRemoteException*/, data->dataSize());
    return JNI_FALSE;
}

可以看出,绕了一圈还是通过 native 层的 BpBinder 发起远程调用,native 层的调用过程可以参考之前的文章Binder 服务注册过程情景分析之 C++ 篇

 

转自:Binder Java 层服务注册过程分析

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值