大家都知道的是 Binder 采用的是 C/S 架构思想,由 Client 端发起调用请求,由 Server 执行请求并返回结果(没有结果)。
写 App 程序进行 IPC 调用时,需要在调用端中 bindService
获取服务端的 Binder
接口对象,再调用方法。这篇文章尝试通过 bindService
方法的核心调用过程,分析Binder客户端的流程。
bindService()
我们在 Activity
中写到的 bindService(Intent service, ServiceConnection conn, BindServiceFlags flags)
调用到的是 ContextWrapper
中的方法。
// frameworks/base/core/java/android/content/ContextWrapper.java
@UnsupportedAppUsage
Context mBase;
@Override
public boolean bindService(@NonNull Intent service, @NonNull ServiceConnection conn,
@NonNull BindServiceFlags flags) {
return mBase.bindService(service, conn, flags);
}
在 ContextWrapper.bindService
调用到了 mBase.bindService(service, conn, flags)
,最终会调用到 ContextImpl.bindService()
方法。
@Override
public boolean bindService(Intent service, ServiceConnection conn, int flags) {
warnIfCallingFromSystemProcess();
return bindServiceCommon(service, conn, Integer.toUnsignedLong(flags), null,
mMainThread.getHandler(), null, getUser());
}
private boolean bindServiceCommon(Intent service, ServiceConnection conn, long flags,
String instanceName, Handler handler, Executor executor, UserHandle user) {
IServiceConnection sd;
// ......
try {
IBinder token = getActivityToken();
// ......
service.prepareToLeaveProcess(this); // 同一进程内,内部的比较 leavingPackage=false
// 下面是执行的 bindService 过程中的一个关键方法调用
int res = ActivityManager.getService().bindServiceInstance(
mMainThread.getApplicationThread(), getActivityToken(), service,
service.resolveTypeIfNeeded(getContentResolver()),
sd, flags, instanceName, getOpPackageName(), user.getIdentifier());
// ......
return res != 0;
} catch (RemoteException e) {
throw e.rethrowFromSystemServer();
}
}
主要关注主要流程的实现,因此移除一些代码,全部的代码放开很占篇幅。很多更深层源码的理解,涉及到更深的知识,也有超出我理解的范围的地方,请不吝赐教。
在 bindServiceCommon()
方法中,主要流程调用到了
int res = ActivityManager.getService().bindServiceInstance(
mMainThread.getApplicationThread(), getActivityToken(), service,
service.resolveTypeIfNeeded(getContentResolver()),
sd, flags, instanceName, getOpPackageName(), user.getIdentifier());
这条语句中,先通过 ActivityManager.getService()
获取到 ActivityManagerService
的 Binder 对象。
// frameworks/base/core/java/android/app/ActivityManager.java
@UnsupportedAppUsage
public static IActivityManager getService() {
return IActivityManagerSingleton.get();
}
// 定义 singleton 对象。
@UnsupportedAppUsage
private static final Singleton<IActivityManager> IActivityManagerSingleton =
new Singleton<IActivityManager>() {
@Override
protected IActivityManager create() {
// 从 ServiceManager 中获取 AMS 的 binder 对象
final IBinder b = ServiceManager.getService(Context.ACTIVITY_SERVICE);
final IActivityManager am = IActivityManager.Stub.asInterface(b);
return am;
}
};
基于当前分析的流程,getService(String name)
的参数值是 Context.ACTIVITY_SERVICE
。
// frameworks/base/core/java/android/os/ServiceManager.java
@UnsupportedAppUsage
private static IServiceManager sServiceManager;
// IServiceManager 这是接口类型,对应的是 IServiceManager.aidl 文件编译后得到的java类型。
@UnsupportedAppUsage
private static IServiceManager getIServiceManager() {
if (sServiceManager != null) {
return sServiceManager;
}
// Find the service manager
sServiceManager = ServiceManagerNative
.asInterface(Binder.allowBlocking(BinderInternal.getContextObject()));
return sServiceManager;
}
// 执行的逻辑比较简单,在缓存列表中查找 name 对应的 Binder 对象,
@UnsupportedAppUsage
public static IBinder getService(String name) { // 此时这里的值是 Context.ACTIVITY_SERVICE
try {
IBinder service = sCache.get(name);
if (service != null) {
return service;
} else {
return Binder.allowBlocking(rawGetService(name)); // 这是获取 Binder 对象的关键。
}
} catch (RemoteException e) {
Log.e(TAG, "error in getService", e);
}
return null;
}
private static IBinder rawGetService(String name) throws RemoteException {
final long start = sStatLogger.getTime();
final IBinder binder = getIServiceManager().getService(name);
final int time = (int) sStatLogger.logDurationStat(Stats.GET_SERVICE, start);
final int myUid = Process.myUid();
final boolean isCore = UserHandle.isCore(myUid);
// ...... 后续的代码中,并没有对 binder 对象作出关键的修改。
return binder;
}
从 getService()
调用到 Binder.allowBloking()
。
// frameworks/base/core/java/android/os/Binder.java
// 方法的返回还是传入的 binder
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;
}
allowBlocking
方法中,没有处理具体的修改,针对传入的 binder
也没有作出影响执行流程的修改。因此,回到 ServiceManager.getService()
方法中,关键的执行流程在 rawGetService(name)
方法中。
在 ServiceManager.rawGetService(String name)
方法中,关键在
final IBinder binder = getIServiceManager().getService(name); // 这个 binder 对象值最终方法返回的对象。
getIServiceManager()
返回的是 IServiceManager
类型,对应的是 IServiceManager.aidl
文件编译后得到的java接口类型。在它的实现中,调用 ServiceManagerNative.asInterface()
方法。
// frameworks/base/core/java/android/os/ServiceManagerNative.java
public final class ServiceManagerNative {
private ServiceManagerNative() {
}
// 参数 obj 将是获取到的服务端的 Binder 对象,整个设计是 代理模式 。
@UnsupportedAppUsage
public static IServiceManager asInterface(IBinder obj) {
if (obj == null) {
return null;
}
// ServiceManager is never local
return new ServiceManagerProxy(obj);
}
}
ServiceManagerNative
的方法中返回的是带有 Binder 对象的 ServiceManagerProxy
代理类。
紧接着:要知道 ServiceManagerNative.asInterface(IBinder)
是从怎么获取到的?
从方法调用上,返回到 ServiceManager.getIServiceManager()
方法中,之前分析到 Binder.allowBlocking(IBinder)
方法内并没有对参数作出关键的修改,因此 Binder 需要从BinderInternal.getContextObject()
的调用中获取。
// frameworks/base/core/java/com/android/internal/os/BinderInternal.java
@UnsupportedAppUsage
public static final native IBinder getContextObject();
从上面这个方法定义可知,这是一个 JNI 调用,需要知道 getContextObject()
方法对应的 C/C++ 层的具体实现函数。
要在 Android 系统中找 JNI 接口定义的注册位置, jni 接口是属于java虚拟机的一部分,因此大概的位置应该要在 VM 相关的代码中查找,就查找到 AndroidRuntime.cpp 看看是不是会有与 Binder 注册有关的函数。
static const RegJNIRec gRegJNI[] = { // .... }
可以看到这个数组的声明,在这里可以看到很多
register_*
的函数注册,可以搜索到register_android_os_Binder
的注册,进而查找到文件android_util_Binder.cpp
文件,对应的register_android_os_Binder
函数定义也有。另一个查找方式就是全局搜索文件内容
getContextObject
,再过滤信息找到 JNI 定义位置。
在查找到 Binder 相关注册函数在文件 android_util_Binder.cpp
文件。
// frameworks/base/core/jni/android_util_Binder.cpp
int register_android_os_Binder(JNIEnv* env)
{
if (int_register_android_os_Binder(env) < 0)
return -1;
if (int_register_android_os_BinderInternal(env) < 0) // 看到 BinderInternal 类的注册函数
return -1;
if (int_register_android_os_BinderProxy(env) < 0)
return -1;
// ......
return 0;
}
const char* const kBinderProxyPathName = "android/os/BinderProxy";
static int int_register_android_os_BinderProxy(JNIEnv* env)
{
// ...... 加载 Java 层的异常类。
// JNI调用,找到 Java 层类 android.os.BinderProxy,得到 jclass 对象。
jclass clazz = FindClassOrDie(env, kBinderProxyPathName);
gBinderProxyOffsets.mClass = MakeGlobalRefOrDie(env, clazz);
gBinderProxyOffsets.mGetInstance = GetStaticMethodIDOrDie(env, clazz, "getInstance",
"(JJ)Landroid/os/BinderProxy;");
gBinderProxyOffsets.mSendDeathNotice =
GetStaticMethodIDOrDie(env, clazz, "sendDeathNotice",
"(Landroid/os/IBinder$DeathRecipient;Landroid/os/IBinder;)V");
gBinderProxyOffsets.mNativeData = GetFieldIDOrDie(env, clazz, "mNativeData", "J");
clazz = FindClassOrDie(env, "java/lang/Class");
gClassOffsets.mGetName = GetMethodIDOrDie(env, clazz, "getName", "()Ljava/lang/String;");
return RegisterMethodsOrDie(
env, kBinderProxyPathName,
gBinderProxyMethods, NELEM(gBinderProxyMethods));
}
static const JNINativeMethod gBinderInternalMethods[] = { // BinderInternal 方法对应关系
/* name, signature, funcPtr */
{ "getContextObject", "()Landroid/os/IBinder;", (void*)android_os_BinderInternal_getContextObject },
// ...... 其他要注册的函数
};
// BidnerInternal java类的包限定名的目录形式
const char* const kBinderInternalPathName = "com/android/internal/os/BinderInternal";
static int int_register_android_os_BinderInternal(JNIEnv* env)
{
jclass clazz = FindClassOrDie(env, kBinderInternalPathName); // 找到java类
// ......
BpBinder::setLimitCallback(android_os_BinderInternal_proxyLimitcallback);
return RegisterMethodsOrDie(
env, kBinderInternalPathName,
gBinderInternalMethods, NELEM(gBinderInternalMethods));
}
在函数 int_register_android_os_BinderInternal()
中进行了函数的注册,在函数数组 gBinderInternalMethods[]
的第一个看到了要查找的目标 getContextObject
,对应的函数是 android_os_BinderInternal_getContextObject
(实现在 android_util.Binder.cpp 文件)。
// frameworks/base/core/jni/android_util_Binder.cpp
static jobject android_os_BinderInternal_getContextObject(JNIEnv* env, jobject clazz)
{
sp b = ProcessState::self()->getContextObject(NULL);
return javaObjectForIBinder(env, b);
}
ProcessState
是每一个进程创建起都有的进程对象。
// frameworks/native/libs/binder/ProcessState.cpp
sp ProcessState::getContextObject(const sp& /*caller*/)
{
// 获取 IBinder 对象并返回。
sp context = getStrongProxyForHandle(0); // 参数 0 是 servicemanager 进程id
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;
}
sp ProcessState::getStrongProxyForHandle(int32_t handle)
{
sp result;
std::unique_lock _l(mLock);
if (handle == 0 && the_context_object != nullptr) return the_context_object;
// 在数组Vector在中查找 handle_entry,若刚开始数组大小是 0,系统会创建一个 handle_entry,放入到数组中。
handle_entry* e = lookupHandleLocked(handle);
if (e != nullptr) {
IBinder* b = e->binder; // 在数组是大小是0的情况下,这里的 binder=nullptr。
if (b == nullptr || !e->refs->attemptIncWeak(this)) {
if (handle == 0) { // 本篇幅中,这个 handle 传入的就是 0。
IPCThreadState* ipc = IPCThreadState::self();
CallRestriction originalCallRestriction = ipc->getCallRestriction();
ipc->setCallRestriction(CallRestriction::NONE);
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 b = BpBinder::PrivateAccessor::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/C++ 层的 IBinder(实际是 BpBinder) 对象。
Binder 客户端 获取 Binder 对象执行到这里获取到 IBinder
对象。我们再往回逐步查看,ProcessState::getContextObject()
-> android_util_Binder::android_os_BinderInternal_getContextObject()
。 在 C/C++层获取到 IBinder
对象之后,调用了 javaObjectForIBinder()
函数。
// frameworks/base/core/jni/android_util_Binder.cpp
jobject javaObjectForIBinder(JNIEnv* env, const sp& val)
{
if (val == NULL) return NULL;
if (val->checkSubclass(&gBinderOffsets)) {
jobject object = static_cast(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;
// 通过JNI调用 android.os.BinderProxy::getInstance() 方法,创建Java层 BinderProxy 对象。
jobject object = env->CallStaticObjectMethod(gBinderProxyOffsets.mClass,
gBinderProxyOffsets.mGetInstance, (jlong) nativeData, (jlong) val.get());
if (env->ExceptionCheck()) {
return NULL;
}
BinderProxyNativeData* actualNativeData = getBPNativeData(env, object);
if (actualNativeData != nativeData) {
delete nativeData;
}
return object;
}
这个函数的作用即是将 C/C++ 层的 BpBinder
对象的数据转换成 Java 层 BinderProxy
对象数据。
执行完这个函数后,就会将 android.os.BinderProxy
对象作为 Java 层 getContextObject()
的返回值返回。这样ServiceManager::getIServiceManager()
执行完成,返回到 ServiceManager::rawGetService()
方法。
private static IBinder rawGetService(String name) throws RemoteException {
final long start = sStatLogger.getTime();
// 上述一切的重点在于 getIServiceManager() 任何获取 Client 端的 BinderProxy(BpBidner)。
// 它返回的就是 ServiceManagerProxy,其中封装有 BinderProxy 对象。
final IBinder binder = getIServiceManager().getService(name);
// ......
return binder;
}
在这里将 binder 返回,再返回到 ActivityManager.getService()
的最初位置,接着调用 bindServiceInstance()
方法。
// frameworks/base/services/core/java/com/android/server/am/ActivityManagerService.java
final ActiveServices mServices;
public int bindServiceInstance(IApplicationThread caller, IBinder token, Intent service,
String resolvedType, IServiceConnection connection, long flags, String instanceName,
String callingPackage, int userId) throws TransactionTooLargeException {
return bindServiceInstance(caller, token, service, resolvedType, connection, flags,
instanceName, false, INVALID_UID, null, null, callingPackage, userId);
}
private int bindServiceInstance(IApplicationThread caller, IBinder token, Intent service,
String resolvedType, IServiceConnection connection, long flags, String instanceName,
boolean isSdkSandboxService, int sdkSandboxClientAppUid,
String sdkSandboxClientAppPackage,
IApplicationThread sdkSandboxClientApplicationThread,
String callingPackage, int userId)
throws TransactionTooLargeException {
// ......
try {
// ......
synchronized (this) {
return mServices.bindServiceLocked(caller, token, service, resolvedType, connection,
flags, instanceName, isSdkSandboxService, sdkSandboxClientAppUid,
sdkSandboxClientAppPackage, sdkSandboxClientApplicationThread,
callingPackage, userId);
}
} finally {
Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
}
}
这样来完成从 Client 端获取到 Server 端的 Binder 代理,从而调用到 Server 端的方法。
后续会上一张图