从上篇文章中我们分析了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;
}