Android Binder getService(java)源码分析
Posted we1less
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Android Binder getService(java)源码分析相关的知识,希望对你有一定的参考价值。
本篇是继续上一篇进行分析的https://blog.csdn.net/we1less/article/details/120731185
代码回到ServiceManager.java 路径frameworks/base/core/java/android/os/ServiceManager.java
上一篇文章说道 BinderInternal.getContextObject() 返回的是android/os/BinderProxy对象,它是java层的,这个对象的mObject成员变量带有native层ServiceManager代理类对象
而getIServiceManager().getService(name) 其实调用的是ServiceManagerProxy的getService
public static IBinder getService(String name) {
try {
IBinder service = sCache.get(name);
if (service != null) {
return service;
} else {
return Binder.allowBlocking(getIServiceManager().getService(name));
}
} catch (RemoteException e) {
Log.e(TAG, "error in getService", e);
}
return null;
}
private static IServiceManager getIServiceManager() {
if (sServiceManager != null) {
return sServiceManager;
}
// Find the service manager
sServiceManager = ServiceManagerNative
.asInterface(Binder.allowBlocking(BinderInternal.getContextObject()));
return sServiceManager;
}
ServiceManagerNative .asInterface
路径 :frameworks/base/core/java/android/os/ServiceManagerNative.java
所以asInterface就是new ServiceManagerProxy(obj);
这个obj就是上面返回的带有native层ServiceManager代理类对象的java层的android/os/BinderProxy对象。把它赋值给ServiceManagerProxy中的mRemote成员,通信就是调用mRemote成员的transact方法。
到此我们知道getIServiceManager().getService(name) 其实调用的是ServiceManagerProxy的getService
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.getService
路径 :frameworks/base/core/java/android/os/ServiceManagerNative.java
mRemote 就是 android/os/BinderProxy对象
IServiceManager.descriptor :
static final String descriptor = "android.os.IServiceManager";
int GET_SERVICE_TRANSACTION = IBinder.FIRST_CALL_TRANSACTION;
其实最后就是变成了与Binder驱动通信获取对应服务,Binder驱动填充reply的过程
public IBinder getService(String name) throws RemoteException {
Parcel data = Parcel.obtain();
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IServiceManager.descriptor);
data.writeString(name);
//mRemote 就是 android/os/BinderProxy对象
mRemote.transact(GET_SERVICE_TRANSACTION, data, reply, 0);
IBinder binder = reply.readStrongBinder();
reply.recycle();
data.recycle();
return binder;
}
BinderProxy.transact
路径 :frameworks/base/core/java/android/os/Binder.java
核心就是调用的 transactNative,这是一个native方法
public boolean transact(int code, Parcel data, Parcel reply, int flags) throws RemoteException {
...
try {
//native方法
return transactNative(code, data, reply, flags);
} finally {
if (tracingEnabled) {
Trace.traceEnd(Trace.TRACE_TAG_ALWAYS);
}
}
}
public native boolean transactNative(int code, Parcel data, Parcel reply,
int flags) throws RemoteException;
transactNative
路径 frameworks/base/core/jni/android_util_Binder.cpp
gBinderProxyOffsets 就是 android/os/BinderProxy
gBinderProxyOffsets.mObject 就是native层的ServiceManager
调用BpBinder(0)的transact方法
最后就是填充reply 将replyObj填充为java的android/os/Parcel 可打包对象
static jboolean android_os_BinderProxy_transact(JNIEnv* env, jobject obj,
jint code, jobject dataObj, jobject replyObj, jint flags) // throws RemoteException
{
//一系列的判空 ...
//填充reply 将replyObj填充为java的android/os/Parcel 可打包对象
Parcel* reply = parcelForJavaObject(env, replyObj);
IBinder* target = (IBinder*)
env->GetLongField(obj, gBinderProxyOffsets.mObject);
//一系列判空 ...
status_t err = target->transact(code, *data, reply, flags);
...
signalExceptionForError(env, obj, err, true /*canThrowRemoteException*/, data->dataSize());
return JNI_FALSE;
}
这里补一下JNINativeMethod
//路径 frameworks/base/core/jni/core_jni_helpers.h
static inline int RegisterMethodsOrDie(JNIEnv* env, const char* className,
const JNINativeMethod* gMethods, int numMethods) {
int res = AndroidRuntime::registerNativeMethods(env, className, gMethods, numMethods);
LOG_ALWAYS_FATAL_IF(res < 0, "Unable to register native methods.");
return res;
}
//路径 frameworks/base/core/jni/android_util_Binder.cpp
static const JNINativeMethod gBinderProxyMethods[] = {
/* name, signature, funcPtr */
{"pingBinder", "()Z", (void*)android_os_BinderProxy_pingBinder},
{"isBinderAlive", "()Z", (void*)android_os_BinderProxy_isBinderAlive},
{"getInterfaceDescriptor", "()Ljava/lang/String;", (void*)android_os_BinderProxy_getInterfaceDescriptor},
{"transactNative", "(ILandroid/os/Parcel;Landroid/os/Parcel;I)Z", (void*)android_os_BinderProxy_transact},
{"linkToDeath", "(Landroid/os/IBinder$DeathRecipient;I)V", (void*)android_os_BinderProxy_linkToDeath},
{"unlinkToDeath", "(Landroid/os/IBinder$DeathRecipient;I)Z", (void*)android_os_BinderProxy_unlinkToDeath},
{"destroy", "()V", (void*)android_os_BinderProxy_destroy},
};
BpBinder(0)的transact
路径 frameworks/native/libs/binder/BpBinder.cpp
调用了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) {
status_t status = IPCThreadState::self()->transact(
mHandle, code, data, reply, flags);
if (status == DEAD_OBJECT) mAlive = 0;
return status;
}
return DEAD_OBJECT;
}
IPCThreadState::self()->transact
路径:frameworks/native/libs/binder/IPCThreadState.cpp
调用了writeTransactionData
//BC_TRANSACTION 一般代表客户端调用驱动端 BR_xxx 一般指驱动返回给客户端
(flags & TF_ONE_WAY) == 0 判断是不是oneway函数 很显然获取服务不是
填充reply
然后调用waitForResponse
status_t IPCThreadState::transact(int32_t handle,
uint32_t code, const Parcel& data,
Parcel* reply, uint32_t flags)
{
...
//BC_TRANSACTION 一般代表客户端调用驱动端
err = writeTransactionData(BC_TRANSACTION, flags, handle, code, data, NULL);
}
...
//oneway ? 1 : 0
if ((flags & TF_ONE_WAY) == 0) {
...
if (reply) {
//填充reply
err = waitForResponse(reply);
...
return err;
}
writeTransactionData
路径 : frameworks/native/libs/binder/IPCThreadState.cpp
主要是填充 binder_transaction_data 结构体向驱动发送
code为java传递过来的GET_SERVICE_TRANSACTION == 0
status_t IPCThreadState::writeTransactionData(int32_t cmd, uint32_t binderFlags,
int32_t handle, uint32_t code, const Parcel& data, status_t* statusBuffer)
{
binder_transaction_data tr;
...
mOut.writeInt32(cmd);
mOut.write(&tr, sizeof(tr));
return NO_ERROR;
}
waitForResponse
路径 : frameworks/native/libs/binder/IPCThreadState.cpp
最终到这里就是跟驱动获取返回数据了
status_t IPCThreadState::waitForResponse(Parcel *reply, status_t *acquireResult)
{
uint32_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 = (uint32_t)mIn.readInt32();
IF_LOG_COMMANDS() {
alog << "Processing waitForResponse Command: "
<< getReturnString(cmd) << endl;
}
switch (cmd) {
case BR_TRANSACTION_COMPLETE:
if (!reply && !acquireResult) goto finish;
break;
case BR_DEAD_REPLY:
err = DEAD_OBJECT;
goto finish;
case BR_FAILED_REPLY:
err = FAILED_TRANSACTION;
goto finish;
case BR_ACQUIRE_RESULT:
{
ALOG_ASSERT(acquireResult != NULL, "Unexpected brACQUIRE_RESULT");
const int32_t result = mIn.readInt32();
if (!acquireResult) continue;
*acquireResult = result ? NO_ERROR : INVALID_OPERATION;
}
goto finish;
case BR_REPLY:
{
binder_transaction_data tr;
err = mIn.read(&tr, sizeof(tr));
ALOG_ASSERT(err == NO_ERROR, "Not enough command data for brREPLY");
if (err != NO_ERROR) goto finish;
if (reply) {
if ((tr.flags & TF_STATUS_CODE) == 0) {
reply->ipcSetDataReference(
reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),
tr.data_size,
reinterpret_cast<const binder_size_t*>(tr.data.ptr.offsets),
tr.offsets_size/sizeof(binder_size_t),
freeBuffer, this);
} else {
err = *reinterpret_cast<const status_t*>(tr.data.ptr.buffer);
freeBuffer(NULL,
reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),
tr.data_size,
reinterpret_cast<const binder_size_t*>(tr.data.ptr.offsets),
tr.offsets_size/sizeof(binder_size_t), this);
}
} else {
freeBuffer(NULL,
reinterpret_cast<const uint8_t*>(tr.data.ptr.buffer),
tr.data_size,
reinterpret_cast<const binder_size_t*>(tr.data.ptr.offsets),
tr.offsets_size/sizeof(binder_size_t), this);
continue;
}
}
goto finish;
default:
err = executeCommand(cmd);
if (err != NO_ERROR) goto finish;
break;
}
}
finish:
if (err != NO_ERROR) {
if (acquireResult) *acquireResult = err;
if (reply) reply->setError(err);
mLastError = err;
}
return err;
}
其实后面与binder驱动相关的可以参考这篇原理Android Binder(C语言版本例子)_we1less的博客-CSDN博客
这里返回结果为对应的Serivce的handle,然后利用这个handle构造出对应的BpBinder,这一部分就完全和IServiceManager的获取是一样的,只不过ServiceManager是直接new BpBinder(0)
而远程服务则是需要先从ServiceManager中获取handle,然后再new BpBinder(handle)
以上是关于Android Binder getService(java)源码分析的主要内容,如果未能解决你的问题,请参考以下文章
Android驱动学习-内部机制_回顾binder框架关键点
Android 进阶——Binder IPC之Native 服务的启动及代理对象的获取详解