ServiceManager在Java层的调用
addService()
@UnsupportedAppUsage
public static void addService(String name, IBinder service) {
addService(name, service, false, IServiceManager.DUMP_FLAG_PRIORITY_DEFAULT);
}
@UnsupportedAppUsage(maxTargetSdk = Build.VERSION_CODES.R, trackingBug = 170729553)
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);
}
}
initServiceCache缓存的初始化
//该方法只有在ActivityThread. bindApplication() 里面调用
public static void initServiceCache(Map<String, IBinder> cache) {
if (sCache.size() != 0) {
throw new IllegalStateException("setServiceCache may only be called once");
}
sCache.putAll(cache);
}
getService() 获取服务
//core/java/android/os/ServiceManager.java
@UnsupportedAppUsage
public static IBinder getService(String name) {
try {
IBinder service = sCache.get(name);
if (service != null) {
return service;
} else {
return Binder.allowBlocking(rawGetService(name));
}
} catch (RemoteException e) {
Log.e(TAG, "error in getService", e);
}
return null;
}
IBinder rawGetService(String name){
//省略
final IBinder binder = getIServiceManager().getService(name);
}
其实可以看出Java这块,还算是比较简单,做了对服务的缓存,如果找不到就会获取SM去查询。addService(),也是调用IServiceManager 。
我们将getIServiceManager().getService(name)拆分为2部分来看,第一部分SM的获取,第二部分方法的调用。
ServiceManager的获取流程
其实这里获取的是ServiceManager的一个远端,我们看下基础流程
//frameworks/base/core/java/com/android/internal/os/BinderInternal.java
// BinderInternal.getContextObject() 其实调用的是 android_util_Binder.cpp 中的 android_os_BinderInternal_getContextObjec ,返回了一个Ibinder
//native/cmds/servicemanager/ServiceManager.cpp 这里有对应的实现
@UnsupportedAppUsage
private static IServiceManager getIServiceManager() {
if (sServiceManager != null) {
return sServiceManager;
}
// Find the service manager
sServiceManager = ServiceManagerNative
.asInterface(Binder.allowBlocking(BinderInternal.getContextObject()));
return sServiceManager;
}
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;
}
//AIDL 转换
@UnsupportedAppUsage
public static IServiceManager asInterface(IBinder obj) {
if (obj == null) {
return null;
}
// ServiceManager is never local
return new ServiceManagerProxy(obj);
}
public ServiceManagerProxy(IBinder remote) {
mRemote = remote;
mServiceManager = IServiceManager.Stub.asInterface(remote);
}
进入 native 调用
//frameworks/base/core/jni/android_util_Binder.cpp
static jobject android_os_BinderInternal_getContextObject(JNIEnv* env, jobject clazz)
{
//这里返回一个Ibinder 其实是个接口 ,所以外面可以强转类型 进入了 ProcessState
sp<IBinder> b = ProcessState::self()->getContextObject(NULL);
return javaObjectForIBinder(env, b);
}
这里要分为2部分梳理
ProcessState
sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& /*caller*/)
{
//这里直接把参数写死为0 回想SM构建的时候 第一个把自己加入进去了 每个进程启动的时候 这里0 是句柄的意思
//上来加入的肯定就是 SM
sp<IBinder> context = getStrongProxyForHandle(0);
if (context) {
internal::Stability::markCompilationUnit(context.get());
} else {
ALOGW("Not able to get context object on %s.", mDriverName.c_str());
}
return context;
}
sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle)
{
sp<IBinder> result;
AutoMutex _l(mLock);
//这里相当于构建了一个 并保存到缓存里 然后返回构建对象 对象俩属性都是null
handle_entry* e = lookupHandleLocked(handle);
if (e != nullptr) {
IBinder* b = e->binder;
if (b == nullptr || !e->refs->attemptIncWeak(this)) {
if (handle == 0) {
IPCThreadState* ipc = IPCThreadState::self();
CallRestriction originalCallRestriction = ipc->getCallRestriction();
ipc->setCallRestriction(CallRestriction::NONE);
Parcel data;
// pin一下
status_t status = ipc->transact(
0, IBinder::PING_TRANSACTION, data, nullptr, 0);
ipc->setCallRestriction(originalCallRestriction);
if (status == DEAD_OBJECT)
return nullptr;
}
//将handler 传过去 进行通信 返回弱引用 到现在还是SM
sp<BpBinder> b = BpBinder::create(handle);
e->binder = b.get();
if (b) e->refs = b->getWeakRefs();
result = b;
} else {
result.force_set(b);
e->refs->decWeak(this);
}
}
return result;
}
到这里可以理解为c层的ServiceManager 构建完成,可以调用了。当然 实际的ServiceManager 在init启动的时候就已经构建完成了。
具体可以看:juejin.cn/post/740515… 启动流程,这里也解释了为什么getStrongProxyForHandle(0); 返回的是SM。
javaObjectForIBinder()转为java 层可以使用的对象
//这里jni 转为java 对象
//const char* const kBinderProxyPathName = "android/os/BinderProxy";
//
// jclass clazz = FindClassOrDie(env, kBinderProxyPathName);
// gBinderProxyOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
jobject javaObjectForIBinder(JNIEnv* env, const sp<IBinder>& val)
{
//null 就返回了
if (val == NULL) return NULL;
if (val->checkSubclass(&gBinderOffsets)) {
//先找 默认找不到 因为第一次不会构建
jobject object = static_cast<JavaBBinder*>(val.get())->object();
return object;
}
/** 创建一个代理 这里要构建的是 BinderProxy.java
调用的方法是
gBinderProxyOffsets.mGetInstance = GetStaticMethodIDOrDie(env, clazz, "getInstance","(JJ)Landroid/os/BinderProxy;");
*/
//这里意思就是构建一个BinderProxyNativeData 将上一步构建的iBinder 赋值到mObject 其实这就是SM
BinderProxyNativeData* nativeData = new BinderProxyNativeData();
nativeData->mOrgue = new DeathRecipientList;
nativeData->mObject = val; //把val 给到native
//调用getinstance 方法 把 nativeData 赋值进去 //getInstance(long nativeData, long iBinder)
//简单 构建一个 BinderProxy ,他的构造传入了 nativeData 也就是sm
jobject object = env->CallStaticObjectMethod(gBinderProxyOffsets.mClass,
gBinderProxyOffsets.mGetInstance, (jlong) nativeData, (jlong) val.get());
if (env->ExceptionCheck()) {
return NULL;
}
// 互相映射 获取 mNativeData 属性
BinderProxyNativeData* actualNativeData = getBPNativeData(env, object);
if (actualNativeData == nativeData) {
//这里为什么判断== 如果相等那就是新建出来的,要设 计计数问题,比如一个服务被多人调用等
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) {
//多线程 只能一个线程到这里
if (gProxiesWarned.compare_exchange_strong(numLastWarned,
numLastWarned + PROXY_WARN_INTERVAL, std::memory_order_relaxed)) {
}
}
} else {
delete nativeData;
}
//将代理返回 可以理解为 BinderProxy
return object;
}
BinderProxy.java
//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) {
NativeAllocationRegistry.applyFreeFunction(NoImagePreloadHolder.sNativeFinalizer,
nativeData);
throw e;
}
NoImagePreloadHolder.sRegistry.registerNativeAllocation(result, nativeData);
sProxyMap.set(iBinder, result);
}
return result;
}
简单梳理一下:
BinderInternal.*getContextObject*()
先调用到BinderInternal 然后调用到 android_util_Binder中的 android_os_BinderInternal_getContextObject()
这个方法 分两步 ProcessState::self()->getContextObject(NULL)
主要就是 ProcessState 调用getStrongProxyForHandle 因为参数是0 所以返回的肯定是IBinder, 其实是SM 并pin了一下保证联通.
然后执行 javaObjectForIBinder(env, b);
构建了一个BinderProxy ,将构建好的IBinder 也就是SM和IBinder 相互绑定一下
然后返回 BinderProxy 这里已经有了SM的远端引用。
ServiceManager方法的调用
其实我在这里迷茫了很久,因为我所用的版本代码是android12,这方面的资料不算很多。
为了避免大家走我的老路,我这里写的可能比较重复。
getStrongProxyForHandle(0),返回SM。是因为在启动的时候,将SM添加了进去。
我当时迷茫的是 IServiceManager.aidl 谁实现的。
当时搞了好久才想明白,我习惯性认为AIDL只能Java层实现,实际IServiceManager.aidl是 native/libs/binder/IServiceManager.cpp 的 ServiceManagerShim 实现的 ,也就是说 远端 是 ServiceManager,服务端是 ServiceManagerShim。
using AidlServiceManager = android::os::IServiceManager;
class ServiceManagerShim : public IServiceManager{
status_t addService(const String16& name, const sp<IBinder>& service,
bool allowIsolated, int dumpsysPriority) override;
sp<IBinder> getService(const String16& name) const override;
}
status_t ServiceManagerShim::addService(const String16& name, const sp<IBinder>& service,
bool allowIsolated, int dumpsysPriority)
{
Status status = mTheRealServiceManager->addService(
String8(name).c_str(), service, allowIsolated, dumpsysPriority);
return status.exceptionCode();
}
sp<IBinder> ServiceManagerShim::getService(const String16& name) const
{
static bool gSystemBootCompleted = false;
sp<IBinder> svc = checkService(name);
//省略
return nullptr;
}
其实最后反而调用到了 frameworks/native/cmds/servicemanager/ServiceManager.cpp
Status ServiceManager::addService(const std::string& name, const sp<IBinder>& binder, bool allowIsolated, int32_t dumpPriority) {
auto ctx = mAccess->getCallingContext();
// apps cannot add services
if (multiuser_get_app_id(ctx.uid) >= AID_APP) {
return Status::fromExceptionCode(Status::EX_SECURITY);
}
if (!mAccess->canAdd(ctx, name)) {
return Status::fromExceptionCode(Status::EX_SECURITY);
}
if (binder == nullptr) {
return Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT);
}
if (!isValidServiceName(name)) {
LOG(ERROR) << "Invalid service name: " << name;
return Status::fromExceptionCode(Status::EX_ILLEGAL_ARGUMENT);
}
Status ServiceManager::getService(const std::string& name, sp<IBinder>* outBinder) {
*outBinder = tryGetService(name, true);
return Status::ok();
}
这里不展开具体代码解析,需要可以去查看,简单点理解就是缓存到集合,从集合里去找。