ServiceManager(Java层)源码分析

上篇文章中我们分析了Native层的ServiceManager处理流程,系统给应用层调用的话会提供Java层接口,接下来我们分析这个情景。我们通常可以通过下面代码来获取AudioManager,本文基于aosp13进行分析:

context.getSystemService(Context.AUDIO_SERVICE) as AudioManager

1.Context.getSystemService()

// frameworks/base/core/java/android/app/ContextImpl.java
public Object getSystemService(String name) {
    
    
    return SystemServiceRegistry.getSystemService(this, name);
}

2.SystemServiceRegistry.getSystemService()

// frameworks/base/core/java/android/app/SystemServiceRegistry.java
// 缓存服务
private static final Map<String, ServiceFetcher<?>> SYSTEM_SERVICE_FETCHERS = new ArrayMap<String, ServiceFetcher<?>>();
// 获取服务
public static Object getSystemService(ContextImpl ctx, String name) {
    
    
    if (name == null) {
    
    
        return null;
    }
    final ServiceFetcher<?> fetcher = SYSTEM_SERVICE_FETCHERS.get(name);
    // 部分log打印省略
    final Object ret = fetcher.getService(ctx);
    return ret;
}

// 静态代码块中注册服务
static {
    
    
   registerService(Context.AUDIO_SERVICE, AudioManager.class, new CachedServiceFetcher<AudioManager>() {
    
    
    @Override
       public AudioManager createService(ContextImpl ctx) {
    
    
       return new AudioManager(ctx);
    }});
}
// 到这里可以知道,获取到了AudioManager对象

3.AudioManager.getService()


// /frameworks/base/media/java/android/media/AudioManager.java

// aidl很熟悉的代码,创建了IAudioService,但是多了个ServiceManager是啥,这个很关键,我们接着看
static IAudioService getService()
{
    
    
    if (sService != null) {
    
    
        return sService;
    }
    IBinder b = ServiceManager.getService(Context.AUDIO_SERVICE);
    sService = IAudioService.Stub.asInterface(b);
    return sService;
}

4.ServiceManager.getService()

// /frameworks/base/core/java/android/os/ServiceManager.java
// 获取Binder服务
public static IBinder getService(String name) {
    
    
    try {
    
    
        IBinder service = sCache.get(name);
        if (service != null) {
    
    
            return service;
        } else {
    
    
            return Binder.allowBlocking(rawGetService(name)); // Binder.allowBlocking可以忽略
        }
    } catch (RemoteException e) {
    
    
        Log.e(TAG, "error in getService", e);
    }
    return null;
}

// 获取IServiceManager
private static IServiceManager getIServiceManager() {
    
    
    if (sServiceManager != null) {
    
    
        return sServiceManager;
    }
    // Find the service manager
    sServiceManager = ServiceManagerNative.asInterface(Binder.allowBlocking(BinderInternal.getContextObject()));
    return sServiceManager;
}

// 获取Binder
private static IBinder rawGetService(String name) throws RemoteException {
    
    
    final IBinder binder = getIServiceManager().getService(name);
    // ......省略一些log打印
    return binder;
}

5.BinderInternal.getContextObject()

getContextObject()是本地方法,我们往下接着看native方法

// frameworks/base/core/java/com/android/internal/os/BinderInternal.java

/**
 * Return the global "context object" of the system.  This is usually
 * an implementation of IServiceManager, which you can use to find
 * other services.
 */
public static final native IBinder getContextObject();

下面android_util_Binder.cpp代码段作用是创建BinderProxy

// frameworks\base\core\jni\android_util_Binder.cpp
// 创建了native层Binder对象
static jobject android_os_BinderInternal_getContextObject(JNIEnv* env, jobject clazz)
{
    
    
    // 通过ProcessState创建了BpBinder对象,下面会接着看
    sp<IBinder> b = ProcessState::self()->getContextObject(NULL);
    // 看javaObjectForIBinder方法注释,可以知道是创建了BinderProxy
    return javaObjectForIBinder(env, b);
}

// If the argument is a JavaBBinder, return the Java object that was used to create it.
// Otherwise return a BinderProxy for the IBinder. If a previous call was passed the
// same IBinder, and the original BinderProxy is still alive, return the same BinderProxy.
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;
    }

    BinderProxyNativeData* nativeData = new BinderProxyNativeData();
    nativeData->mOrgue = new DeathRecipientList;
    nativeData->mObject = val;

    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.
        return NULL;
    }
    BinderProxyNativeData* actualNativeData = getBPNativeData(env, object);
    if (actualNativeData == nativeData) {
    
    
        // Created a new Proxy
        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) {
    
    
            // Multiple threads can get here, make sure only one of them gets to
            // update the warn counter.
            if (gProxiesWarned.compare_exchange_strong(numLastWarned,
                        numLastWarned + PROXY_WARN_INTERVAL, std::memory_order_relaxed)) {
    
    
                ALOGW("Unexpectedly many live BinderProxies: %d\n", numProxies);
            }
        }
    } else {
    
    
        delete nativeData;
    }

    return object;
}

下面ProcessState.cpp代码段展示了创建BpBinder过程

// frameworks\native\libs\binder\ProcessState.cpp

// 这个init方法我们在上篇博客中分析过,作用是打开binder驱动
sp<ProcessState> ProcessState::self()
{
    
    
    return init(kDefaultDriver, false /*requireDefault*/);
}

// 通过getStrongProxyForHandle()创建
sp<IBinder> ProcessState::getContextObject(const sp<IBinder>& /*caller*/)
{
    
    
    sp<IBinder> context = getStrongProxyForHandle(0);

    if (context) {
    
    
        // The root object is special since we get it directly from the driver, it is never
        // written by Parcell::writeStrongBinder.
        internal::Stability::markCompilationUnit(context.get());
    } else {
    
    
        ALOGW("Not able to get context object on %s.", mDriverName.c_str());
    }

    return context;
}
// VNDK
extern sp<BBinder> the_context_object;
sp<IBinder> ProcessState::getStrongProxyForHandle(int32_t handle)
{
    
    
    sp<IBinder> result;

    AutoMutex _l(mLock);

    // the_context_object为null这个不会走
    if (handle == 0 && the_context_object != nullptr) return the_context_object;

    handle_entry* e = lookupHandleLocked(handle);

    if (e != nullptr) {
    
    
        // We need to create a new BpBinder if there isn't currently one, OR we
        // are unable to acquire a weak reference on this current one.  The
        // attemptIncWeak() is safe because we know the BpBinder destructor will always
        // call expungeHandle(), which acquires the same lock we are holding now.
        // We need to do this because there is a race condition between someone
        // releasing a reference on this BpBinder, and a new reference on its handle
        // arriving from the driver.
        IBinder* b = e->binder;
        if (b == nullptr || !e->refs->attemptIncWeak(this)) {
    
    
            if (handle == 0) {
    
    
                // Special case for context manager...
                // The context manager is the only object for which we create
                // a BpBinder proxy without already holding a reference.
                // Perform a dummy transaction to ensure the context manager
                // is registered before we create the first local reference
                // to it (which will occur when creating the BpBinder).
                // If a local reference is created for the BpBinder when the
                // context manager is not present, the driver will fail to
                // provide a reference to the context manager, but the
                // driver API does not return status.
                //
                // Note that this is not race-free if the context manager
                // dies while this code runs.

                IPCThreadState* ipc = IPCThreadState::self();

                CallRestriction originalCallRestriction = ipc->getCallRestriction();
                ipc->setCallRestriction(CallRestriction::NONE);
                // 发送PING_TRANSACTION命令
                Parcel data;
                status_t status = ipc->transact(
                        0, IBinder::PING_TRANSACTION, data, nullptr, 0);

                ipc->setCallRestriction(originalCallRestriction);

                if (status == DEAD_OBJECT)
                   return nullptr;
            }
            // 创建BpBinder对象
            sp<BpBinder> b = BpBinder::PrivateAccessor::create(handle);
            e->binder = b.get();
            if (b) e->refs = b->getWeakRefs();
            result = b;
        } else {
    
    
            // This little bit of nastyness is to allow us to add a primary
            // reference to the remote proxy when this team doesn't have one
            // but another team is sending the handle to us.
            result.force_set(b);
            e->refs->decWeak(this);
        }
    }

    return result;
}

6.ServiceManagerNative.asInterface()

ServiceManagerNative.asInterface(Binder.allowBlocking(BinderInternal.getContextObject()));

从上面分析可以知道BinderInternal.getContextObject()​是将native层BpBinder对象转换成java层Binder对象

ServiceManagerNative返回了ServiceManagerProxy对象,这样就将native层ServiceManager和java层ServiceManager关联起来了

// frameworks\base\core\java\android\os\ServiceManagerNative.java
/**
 * Native implementation of the service manager.  Most clients will only
 * care about asInterface().
 *
 * @hide
 */
public final class ServiceManagerNative {
    
    
    private ServiceManagerNative() {
    
    }

    /**
     * Cast a Binder object into a service manager interface, generating
     * a proxy if needed.
     *
     * TODO: delete this method and have clients use
     *     IServiceManager.Stub.asInterface instead
     */
    @UnsupportedAppUsage
    public static IServiceManager asInterface(IBinder obj) {
    
    
        if (obj == null) {
    
    
            return null;
        }

        // ServiceManager is never local
        return new ServiceManagerProxy(obj);
    }
}

// This class should be deleted and replaced with IServiceManager.Stub whenever
// mRemote is no longer used
class ServiceManagerProxy implements IServiceManager {
    
    
    public ServiceManagerProxy(IBinder remote) {
    
    
        mRemote = remote;
        mServiceManager = IServiceManager.Stub.asInterface(remote);
    }

    public IBinder asBinder() {
    
    
        return mRemote;
    }

    @UnsupportedAppUsage
    public IBinder getService(String name) throws RemoteException {
    
    
        // Same as checkService (old versions of servicemanager had both methods).
        return mServiceManager.checkService(name);
    }

    public IBinder checkService(String name) throws RemoteException {
    
    
        return mServiceManager.checkService(name);
    }

    public void addService(String name, IBinder service, boolean allowIsolated, int dumpPriority)
            throws RemoteException {
    
    
        mServiceManager.addService(name, service, allowIsolated, dumpPriority);
    }

    public String[] listServices(int dumpPriority) throws RemoteException {
    
    
        return mServiceManager.listServices(dumpPriority);
    }

    public void registerForNotifications(String name, IServiceCallback cb)
            throws RemoteException {
    
    
        mServiceManager.registerForNotifications(name, cb);
    }

    public void unregisterForNotifications(String name, IServiceCallback cb)
            throws RemoteException {
    
    
        throw new RemoteException();
    }

    public boolean isDeclared(String name) throws RemoteException {
    
    
        return mServiceManager.isDeclared(name);
    }

    public String[] getDeclaredInstances(String iface) throws RemoteException {
    
    
        return mServiceManager.getDeclaredInstances(iface);
    }

    public String updatableViaApex(String name) throws RemoteException {
    
    
        return mServiceManager.updatableViaApex(name);
    }

    public ConnectionInfo getConnectionInfo(String name) throws RemoteException {
    
    
        return mServiceManager.getConnectionInfo(name);
    }

    public void registerClientCallback(String name, IBinder service, IClientCallback cb)
            throws RemoteException {
    
    
        throw new RemoteException();
    }

    public void tryUnregisterService(String name, IBinder service) throws RemoteException {
    
    
        throw new RemoteException();
    }

    public ServiceDebugInfo[] getServiceDebugInfo() throws RemoteException {
    
    
        return mServiceManager.getServiceDebugInfo();
    }

    /**
     * Same as mServiceManager but used by apps.
     *
     * Once this can be removed, ServiceManagerProxy should be removed entirely.
     */
    @UnsupportedAppUsage
    private IBinder mRemote;

    private IServiceManager mServiceManager;
}

猜你喜欢

转载自blog.csdn.net/wangadping/article/details/128541403