ServiceManager (Java layer) source code analysis

From the previous article, we analyzed the ServiceManager processing flow of the Native layer. If the system calls the application layer, it will provide a Java layer interface. Next, we analyze this scenario. We can usually get AudioManager through the following code, this article analyzes based on 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() is a local method, let's look at the native method next

// 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();

The following android_util_Binder.cpp code segment is used to create 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;
}

The following ProcessState.cpp code snippet shows the process of creating 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()));

From the above analysis, we can know BinderInternal.getContextObject()that it is to convert the native layer BpBinder object into the java layer Binder object

ServiceManagerNative returns the ServiceManagerProxy object, which associates the native layer ServiceManager with the java layer 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;
}

Guess you like

Origin blog.csdn.net/wangadping/article/details/128541403