Android Framework- ServiceManger方法调用流程

353 阅读5分钟

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, 其实是SMpin了一下保证联通.

然后执行 javaObjectForIBinder(env, b);

构建了一个BinderProxy ,将构建好的IBinder 也就是SMIBinder 相互绑定一下

然后返回 BinderProxy 这里已经有了SM的远端引用。

ServiceManager方法的调用

其实我在这里迷茫了很久,因为我所用的版本代码是android12,这方面的资料不算很多。

为了避免大家走我的老路,我这里写的可能比较重复。

getStrongProxyForHandle(0),返回SM。是因为在启动的时候,将SM添加了进去。

我当时迷茫的是 IServiceManager.aidl 谁实现的。

当时搞了好久才想明白,我习惯性认为AIDL只能Java层实现,实际IServiceManager.aidlnative/libs/binder/IServiceManager.cppServiceManagerShim 实现的 ,也就是说 远端 是 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();
}

这里不展开具体代码解析,需要可以去查看,简单点理解就是缓存到集合,从集合里去找。