Java Binder是借助Native Binder来进行工作的,所以想要深入学习Java Binder,首先要熟悉Native Binder,下面是作者前面写的Native Binder的文章链接:
深入理解Native Binder_AD钙奶-lalala的博客-CSDN博客我在前面的一篇文章中已经对Binder有一个概述,下面就开始来深入研究Binder吧。上一篇文章链接:听宇哥讲Binder(Binder核心原理最全解析)_AD钙奶-lalala的博客-CSDN博客前面写了一篇关于AIDL的文章,那我们就从AIDL谈起吧。如果对AIDL有不理解的,可以先看看这一篇文章:再探AIDL_AD钙奶-lalala的博客-CSDN博客我们还是延续前面一篇文章的例子来讲解,我们创建的AIDL文件如下:然后Build->Make Project,会自动在build->generated-https://blog.csdn.net/qq_36428821/article/details/125708384?spm=1001.2014.3001.5501我们也是从一个例子来看整个Java Binder的流程吧:AMS注册到ServiceManager中。
在AMS的setSystemProcess方法中,会调用ServiceManager的addService方法。源码路径:frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
public void setSystemProcess() {
try {
ServiceManager.addService(Context.ACTIVITY_SERVICE,
this, /* allowIsolated= */ true,
DUMP_FLAG_PRIORITY_CRITICAL |
DUMP_FLAG_PRIORITY_NORMAL | DUMP_FLAG_PROTO);//1
```
} catch (PackageManager.NameNotFoundException e) {
throw new RuntimeException(
"Unable to find android system package", e);
}
```
}
public static final String ACTIVITY_SERVICE = "activity";
注释1处的Context.ACTIVITY_SERVICE的值为"activity",作用就是将AMS注册到ServiceManager。我们再来看一下ServiceManager的addService方法:
路径:frameworks/base/core/java/android/os/ServiceManager.java
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方法,那么getIServiceManager方法返回的是什么呢?
private static IServiceManager sServiceManager;
private static IServiceManager getIServiceManager() {
if (sServiceManager != null) {
return sServiceManager;
}
// Find the service manager
sServiceManager = ServiceManagerNative
.asInterface(Binder.allowBlocking(BinderInternal
.getContextObject()));
return sServiceManager;
}
我们结合源码分成以下几个方面来分析:
- BinderInternal.getContextObject
- ServiceManagerNative.asInterface
- getIServiceManager().addService
这个getContextObject我们是不是似曾相识,我们先把源码调出来看下:
public static final native IBinder getContextObject();
我们发现这是一个Native方法:
路径:frameworks/base/core/jni/android_util_Binder.cpp
static jobject android_os_BinderInternal_getContextObject(JNIEnv* env, jobject clazz)
{
sp<IBinder> b = ProcessState::self()->getContextObject(NULL);//1
return javaObjectForIBinder(env, b);//2
}
通过JNI最终调用的事Native层的getContextObject方法,我们在学Native Binder的时候知道,这个方法返回一个BpBinder。但是BpBinder是不能在Java层直接使用的,所以会有注释2处的代码,我们进去看一下:
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;
}
// 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(gProxyLock);
BinderProxyNativeData* nativeData = gNativeDataCache;
if (nativeData == nullptr) {
nativeData = new BinderProxyNativeData();
}
// gNativeDataCache is now logically empty.
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.
gNativeDataCache = nullptr;
return NULL;
}
BinderProxyNativeData* actualNativeData = getBPNativeData(env, object);
if (actualNativeData == nativeData) {
// New BinderProxy; we still have exclusive access.
nativeData->mOrgue = new DeathRecipientList;
nativeData->mObject = val;
gNativeDataCache = nullptr;
++gNumProxies;
if (gNumProxies >= gProxiesWarned + PROXY_WARN_INTERVAL) {
ALOGW("Unexpectedly many live BinderProxies: %d\n", gNumProxies);
gProxiesWarned = gNumProxies;
}
} else {
// nativeData wasn't used. Reuse it the next time.
gNativeDataCache = nativeData;
}
return object;
}
struct BinderProxyNativeData {
// Both fields are constant and not null once javaObjectForIBinder returns this as
// part of a BinderProxy.
// The native IBinder proxied by this BinderProxy.
sp<IBinder> mObject;
// Death recipients for mObject. Reference counted only because DeathRecipients
// hold a weak reference that can be temporarily promoted.
sp<DeathRecipientList> mOrgue; // Death recipients for mObject.
};
BinderProxyNativeData* getBPNativeData(JNIEnv* env, jobject obj) {
return (BinderProxyNativeData *) env->GetLongField(obj, gBinderProxyOffsets.mNativeData);
}
这个方法会为我们创建一个BinderProxy对象,会将BpBinder保存到mObject里面。
再来看ServiceManagerNative.asInterface方法:
路径:frameworks/base/core/java/android/os/ServiceManagerNative.java
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);
}
可见,返回了ServiceManagerProxy对象。进去看看:
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, int dumpPriority)
throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IServiceManager.descriptor);
data.writeString(name);
data.writeStrongBinder(service);//1
data.writeInt(allowIsolated ? 1 : 0);
data.writeInt(dumpPriority);
mRemote.transact(ADD_SERVICE_TRANSACTION, data, reply, 0);//2
reply.recycle();
data.recycle();
}
public String[] listServices(int dumpPriority) 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);
data.writeInt(dumpPriority);
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;
}
我们关注一下注释2处,mRemote是初始化传进来的,毫无疑问这是一个BinderProxy对象。注意,注释2处是一个native函数:
路径:frameworks/base/core/jni/android_util_Binder.cpp
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;
}
Parcel* data = parcelForJavaObject(env, dataObj);//1
if (data == NULL) {
return JNI_FALSE;
}
Parcel* reply = parcelForJavaObject(env, replyObj);//2
if (reply == NULL && replyObj != NULL) {
return JNI_FALSE;
}
IBinder* target = getBPNativeData(env, obj)->mObject.get();//3
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();
}
}
//printf("Transact from Java code to %p sending: ", target); data->print();
status_t err = target->transact(code, *data, reply, flags);//4
//if (reply) printf("Transact from Java code to %p received: ", target); reply->print();
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;
}
注释1和注释2处将Java的Parcel对象转换为Native的Parcel对象,注释3处从BinderProxy获取mObject,也就是BpBinder,注释4处调用BpBinder的transact方法。Native后面的流程这里就不再重复了,这样整个流程是不是就通透啦!
谈谈JavaBBiner
我们看前面的data.writeStrongBuider(service)这行代码:
路径:frameworks/base/core/java/android/os/Parcel.java
public final void writeStrongBinder(IBinder val) {
nativeWriteStrongBinder(mNativePtr, val);
}
这是一个native方法:
路径:frameworks/base/core/jni/android_os_Parcel.cpp
static void android_os_Parcel_writeStrongBinder(JNIEnv* env, jclass clazz, jlong nativePtr, jobject object)
{
Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
if (parcel != NULL) {
const status_t err = parcel->
writeStrongBinder(ibinderForJavaObject(env, object));
if (err != NO_ERROR) {
signalExceptionForError(env, clazz, err);
}
}
}
我们重点关注ibinderForJavaObject方法:
路径:frameworks/base/core/jni/android_util_Binder.cpp
sp<IBinder> ibinderForJavaObject(JNIEnv* env, jobject obj)
{
if (obj == NULL) return NULL;
// Instance of Binder?
if (env->IsInstanceOf(obj, gBinderOffsets.mClass)) {
JavaBBinderHolder* jbh = (JavaBBinderHolder*)
env->GetLongField(obj, gBinderOffsets.mObject);
return jbh->get(env, obj);//3
}//1
// Instance of BinderProxy?
if (env->IsInstanceOf(obj, gBinderProxyOffsets.mClass)) {
return getBPNativeData(env, obj)->mObject;
}//2
ALOGW("ibinderForJavaObject: %p is not a Binder object", obj);
return NULL;
}
注释1处,如果obj是Binder类型,返回JavaBBinder;如果是BinderProxy类型,返回BpBinder。
很明显AMS继承自Binder,所以会返回JavaBBinder。注释3处get方法:
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;
};
解析JavaBBinder
路径:frameworks/base/core/jni/android_util_Binder.cpp
class JavaBBinder : public BBinder
{
public:
JavaBBinder(JNIEnv* env, jobject /* Java Binder */ object)
: mVM(jnienv_to_javavm(env)), mObject(env->NewGlobalRef(object))
{
ALOGV("Creating JavaBBinder %p\n", this);
gNumLocalRefsCreated.fetch_add(1, std::memory_order_relaxed);
gcIfManyNewRefs(env);
}
bool checkSubclass(const void* subclassID) const
{
return subclassID == &gBinderOffsets;
}
jobject object() const
{
return mObject;
}
protected:
virtual ~JavaBBinder()
{
ALOGV("Destroying JavaBBinder %p\n", this);
gNumLocalRefsDeleted.fetch_add(1, memory_order_relaxed);
JNIEnv* env = javavm_to_jnienv(mVM);
env->DeleteGlobalRef(mObject);
}
virtual status_t onTransact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0)
{
JNIEnv* env = javavm_to_jnienv(mVM);
ALOGV("onTransact() on %p calling object %p in env %p vm %p\n", this, mObject, env, mVM);
IPCThreadState* thread_state = IPCThreadState::self();
const int32_t strict_policy_before = thread_state->getStrictModePolicy();
//printf("Transact from %p to Java code sending: ", this);
//data.print();
//printf("\n");
jboolean res =
env->CallBooleanMethod(mObject,
gBinderOffsets.mExecTransact,
code,
reinterpret_cast<jlong>(&data),
reinterpret_cast<jlong>(reply), flags);//1
if (env->ExceptionCheck()) {
ScopedLocalRef<jthrowable> excep(env, env->ExceptionOccurred());
report_exception(env, excep.get(),
"*** Uncaught remote exception! "
"(Exceptions are not yet supported across processes.)");
res = JNI_FALSE;
}
// Check if the strict mode state changed while processing the
// call. The Binder state will be restored by the underlying
// Binder system in IPCThreadState, however we need to take care
// of the parallel Java state as well.
if (thread_state->getStrictModePolicy() != strict_policy_before) {
set_dalvik_blockguard_policy(env, strict_policy_before);
}
if (env->ExceptionCheck()) {
ScopedLocalRef<jthrowable> excep(env, env->ExceptionOccurred());
report_exception(env, excep.get(),
"*** Uncaught exception in onBinderStrictModePolicyChange");
}
// Need to always call through the native implementation of
// SYSPROPS_TRANSACTION.
if (code == SYSPROPS_TRANSACTION) {
BBinder::onTransact(code, data, reply, flags);
}
//aout << "onTransact to Java code; result=" << res << endl
// << "Transact from " << this << " to Java code returning "
// << reply << ": " << *reply << endl;
return res != JNI_FALSE ? NO_ERROR : UNKNOWN_TRANSACTION;
}
virtual status_t dump(int fd, const Vector<String16>& args)
{
return 0;
}
private:
JavaVM* const mVM;
jobject const mObject; // GlobalRef to Java Binder
};
当Binder驱动得到客户端请求的时候,Binder驱动会将响应发送给JavaBBinder,进而调用JavaBBinder的onTransact方法。我们注意注释1,这里调用了Java层的execTransact方法:
路径:frameworks/base/core/java/android/os/Binder.java
private boolean execTransact(int code, long dataObj, long replyObj,
int flags) {
BinderCallsStats binderCallsStats = BinderCallsStats.getInstance();
BinderCallsStats.CallSession callSession = binderCallsStats.callStarted(this, code);
Parcel data = Parcel.obtain(dataObj);
Parcel reply = Parcel.obtain(replyObj);
// theoretically, we should call transact, which will call onTransact,
// but all that does is rewind it, and we just got these from an IPC,
// so we'll just call it directly.
boolean res;
// Log any exceptions as warnings, don't silently suppress them.
// If the call was FLAG_ONEWAY then these exceptions disappear into the ether.
final boolean tracingEnabled = Binder.isTracingEnabled();
try {
if (tracingEnabled) {
Trace.traceBegin(Trace.TRACE_TAG_ALWAYS, getClass().getName() + ":" + code);
}
res = onTransact(code, data, reply, flags);//1
} catch (RemoteException|RuntimeException e) {
if (LOG_RUNTIME_EXCEPTION) {
Log.w(TAG, "Caught a RuntimeException from the binder stub implementation.", e);
}
if ((flags & FLAG_ONEWAY) != 0) {
if (e instanceof RemoteException) {
Log.w(TAG, "Binder call failed.", e);
} else {
Log.w(TAG, "Caught a RuntimeException from the binder stub implementation.", e);
}
} else {
reply.setDataPosition(0);
reply.writeException(e);
}
res = true;
} finally {
if (tracingEnabled) {
Trace.traceEnd(Trace.TRACE_TAG_ALWAYS);
}
}
checkParcel(this, code, reply, "Unreasonably large binder reply buffer");
reply.recycle();
data.recycle();
// Just in case -- we are done with the IPC, so there should be no more strict
// mode violations that have gathered for this thread. Either they have been
// parceled and are now in transport off to the caller, or we are returning back
// to the main transaction loop to wait for another incoming transaction. Either
// way, strict mode begone!
StrictMode.clearGatheredViolations();
binderCallsStats.callEnded(callSession);
return res;
}
}
注意注释1处,调用了onTransact,而AMS继承Binder,实现了onTransact函数。
我们通过AMS注册进ServiceManager来总结一下Java Binder的核心流程吧:
AMS(客户端)addService的时候会生成一个Native的BpBinder,封装成可供Java使用的BinderProxy。ServiceManager的addService最终会交给ServiceManager的addService来处理。而ServiceManager初始化是传入BinderProxy,最终处理的事BinderProxy的mObject(BpBinder)。传入的AMS会被转换成JavaBBinder,最终回调AMS的onTransact方法。