ServiceManager源码
- 声明:基于google10 开源代码
- frameworks\base\core\java\android\os\ServiceManager.java
比如我们常用的代码:获取一个系统服务
ServiceManager.getService(Context.LOCATION_SERVICE)
//注意与mContext.getSystemService(InputMethodManager.class)的区别
我们从ServiceManager.getService 一点点往下看,可以看出返回是Ibinder类型对象 ,调用getIServiceManager取获取
public static IBinder getService(String name) {
}
final IBinder binder = getIServiceManager().getService(name);
- 仔细看下这个getIServiceManager,其中ServiceManagerNative :public abstract class ServiceManagerNative extends Binder implements IServiceManager,有兴趣的可以取看看源码,跟aidl生成的中间文件几乎一样。
private static IServiceManager getIServiceManager() {
if (sServiceManager != null) {
return sServiceManager;
}
// Find the service manager
sServiceManager = ServiceManagerNative
.asInterface(Binder.allowBlocking(BinderInternal.getContextObject()));
return sServiceManager;
}
- BinderInternal.getContextObject() 这个是关键,它返回了一个Bbinder ,看下面代码流程
frameworks\base\core\jni\android_util_Binder.cpp ,重点看 ProcessState::self()->getContextObject
最后返回了创建好的BpBinder::create(handle) ->Bpbinder对象
static jobject android_os_BinderInternal_getContextObject(JNIEnv* env, jobject clazz)
{
sp<IBinder> b = ProcessState::self()->getContextObject(NULL);
return javaObjectForIBinder(env, b);//这里调用了 BinderProxy的 getInstance 构造了一个java 的BinderProxy
}
frameworks\native\libs\binder\ProcessState.cpp
sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& /*caller*/)
{
return getStrongProxyForHandle(0);//这里传的是0 很关键
}
//省略了很多代码,看关键的地方
b = BpBinder::create(handle);
-
回到 sServiceManager = ServiceManagerNative
.asInterface(Binder.allowBlocking(BinderInternal.getContextObject())); -> asInterface代码
这里跟aidl实现基本一致,如果不是同一个进程调用的就创建一个远程代理,也就是说调用ServiceManager.getService(Context.LOCATION_SERVICE)这个方法有可能是不在同一个进程中,就是远程代理帮你返回对应的service ,就是调用ServiceManagerProxy 的getService ,ServiceManagerProxy的构造参数 IBinder remote 就是一个BinderProxy -
getService即调用BinderProxy的transact函数,发起的code是GET_SERVICE_TRANSACTION。然后从底层绕了一圈mRemote.transact(GET_SERVICE_TRANSACTION, data, reply, 0); 就是调用到BinderProxy 的transact 方法
-
BinderProxy 的transact 方法 又调用了native 的 transactNative(code, data, reply, flags);
transactNative 保留了 native的BBinder
frameworks\native\libs\binder\BpBinder.cpp
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 的transact
frameworks\native\libs\binder\IPCThreadState.cpp 涉及了biner驱动的一次拷贝 mmap映射内存知识点
第一步 err = writeTransactionData(BC_TRANSACTION, flags, handle, code, data, nullptr); 交给驱动binder处理
第二步 err = waitForResponse(reply); 从binder驱动返回
waitForResponse 里面 循环talkWithDriver
接收用
case BR_TRANSACTION:
reinterpret_cast<BBinder*>(tr.cookie)->transact(tr.code, buffer,
&reply, tr.flags);
- 接着调用了BBinder 的 transact 方法
transact 实际上又调用自己子类的onTransact方法
err = onTransact(code, data, reply, flags);
class JavaBBinder : public BBinder
status_t onTransact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags = 0) override
{
jboolean res = env->CallBooleanMethod(mObject, gBinderOffsets.mExecTransact,
code, reinterpret_cast<jlong>(&data), reinterpret_cast<jlong>(reply), flags);
}
- 回到java的binder
frameworks\base\core\java\android\os\Binder.java
// Entry point from android_util_Binder.cpp's onTransact
@UnsupportedAppUsage
private boolean execTransact(int code, long dataObj, long replyObj,
int flags) {
// At that point, the parcel request headers haven't been parsed so we do not know what
// WorkSource the caller has set. Use calling uid as the default.
final int callingUid = Binder.getCallingUid();
final long origWorkSource = ThreadLocalWorkSource.setUid(callingUid);
try {
return execTransactInternal(code, dataObj, replyObj, flags, callingUid);
} finally {
ThreadLocalWorkSource.restore(origWorkSource);
}
}
- 之后又回到
ServiceManagerNative.java 的 onTransact