这篇博客可以说是对于上一篇博客 ——《Binder 浅析 —— AMS 注册流程》的一个补充,其整体流程与 AMS 注册流程没有太多的不同,但还是有一些细节需要我们注意
(以下分析的是 Android 6.0 的源码)
APP 进程是如何获取 AMS 的?
以 bindService 的调用流程为例,获取 AMS 是从 ContextImpl.bindServiceCommon()
函数中开始的
(以下分析的只是获取 AMS 的流程,而不是 bindService 的流程)
调用栈如下:
ContextImpl.bindService()
--> ContextImpl.bindServiceCommon()
--> ActivityManagerNative.getDefault()
--> ServiceManager.getService("activity")
--> ServiceManager.getIServiceManager()
--> ServiceManagerProxy.getService()
ContextImpl.bindService()
// frameworks/base/core/java/android/app/ContextImpl.java
public boolean bindService(Intent service, ServiceConnection conn, int flags)
{
......
return bindServiceCommon(service, conn, flags, Process.myUserHandle());
}
ContextImpl.bindServiceCommon()
// frameworks/base/core/java/android/app/ContextImpl.java
private boolean bindServiceCommon(Intent service, ServiceConnection conn,
int flags, UserHandle user
){
......
int res = ActivityManagerNative.getDefault().bindService(
mMainThread.getApplicationThread(), getActivityToken(), service,
service.resolveTypeIfNeeded(getContentResolver()),
sd, flags, getOpPackageName(), user.getIdentifier());
if (res < 0)
{
throw new SecurityException(
"Not allowed to bind to service " + service);
}
return res != 0;
......
}
ActivityManagerNative.getDefault()
// frameworks/base/core/java/android/app/ActivityManagerNative.java
static public IActivityManager getDefault()
{
return gDefault.get();
}
private static final Singleton<IActivityManager> gDefault = new Singleton<IActivityManager>()
{
protected IActivityManager create()
{
IBinder b = ServiceManager.getService("activity");
......
IActivityManager am = asInterface(b);
......
return am;
}
};
Singleton 是一个单例类,当外部调用了 Singleton.get()
函数时,如果对应的泛型对象没有被创建,就会回调内部的 Singleton.create()
函数来创建单例对象
ServiceManager.getService("activity")
// frameworks/base/core/java/android/os/ServiceManager.java
public static IBinder getService(String name)
{
......
getIServiceManager().getService(name);
......
}
ServiceManager.getIServiceManager
函数在上一篇博客中介绍过了,这里就不再重复阐述了
ServiceManagerProxy.getService()
// frameworks/base/core/java/android/os/ServiceManagerNative$ServiceManagerProxy.java
public IBinder getService(String name)
{
// 创建 data
Parcel data = Parcel.obtain();
// 创建 reply
Parcel reply = Parcel.obtain();
data.writeInterfaceToken(IServiceManager.descriptor);
// 将 AMS 名称写入 data
data.writeString(name);
// mRemote = BinderProxy,相当于调用到 BinderProxy.transact
mRemote.transact(GET_SERVICE_TRANSACTION, data, reply, 0);
IBinder binder = reply.readStrongBinder();
reply.recycle();
data.recycle();
return binder;
}
APP 进程是如何发送数据给 SM 的?
// frameworks/base/core/java/android/os/ServiceManagerNative$ServiceManagerProxy.java
public IBinder getService(String name)
{
// 创建 data
Parcel data = Parcel.obtain();
......
// mRemote = BinderProxy,相当于调用到 BinderProxy.transact
mRemote.transact(GET_SERVICE_TRANSACTION, data, reply, 0);
......
}
调用栈如下:
BinderProxy.transact()
--> BpBinder::transact()
--> IPCThreadState::transact()
--> IPCThreadState::waitForResponse()
--> IPCThreadState::talkWithDriver()
--> binder_ioctl_write_read()
--> binder_thread_write()
--> binder_transaction()
--> binder_thread_read()
其中的大部分在上一篇博客中就已经介绍了,这里就不再重复阐述了
除了 mOut 中的数据不同之外,调用流程都是相同的
SM 进程被唤醒后做了什么?
SM 进程被唤醒后,继续执行未完成的 binder_thread_read
函数
调用栈如下:
binder_thread_read()
--> binder_loop()
--> binder_parse()
--> service_manager.svcmgr_handler()
--> binder_send_reply()
--> binder_ioctl_write_read()
--> binder_thread_read()
其中的大部分在上一篇博客中就已经介绍了,这里就不再重复阐述了
service_manager.svcmgr_handler()
// frameworks/native/cmds/servicemanager/service_manager.c
int svcmgr_handler(struct binder_state *bs,
struct binder_transaction_data *txn, // mOut 数据部分
struct binder_io *msg, // mOut 数据部分的信息
struct binder_io *reply
){
struct svcinfo *si;
uint16_t *s;
size_t len;
uint32_t handle;
uint32_t strict_policy;
int allow_isolated;
......
// 此时 txn->code = GET_SERVICE_TRANSACTION = 1 = SVC_MGR_GET_SERVICE
switch(txn->code)
{
......
case SVC_MGR_GET_SERVICE:
case SVC_MGR_CHECK_SERVICE:
// 从 mOut 数据部分中获取 AMS 的名称
s = bio_get_string16(msg, &len);
......
// 根据 AMS 的名称进行查找,获取 AMS 引用(handle)
handle = do_find_service(bs, s, len, txn->sender_euid, txn->sender_pid);
......
// 构建一个 flat_binder_object,将 AMS 引用(handle)写入其中进行封装,
// 再将 flat_binder_object 写入 reply 中
bio_put_ref(reply, handle);
return 0;
......
}
}
do_find_service()
// frameworks/native/cmds/servicemanager/service_manager.c
uint32_t do_find_service(struct binder_state *bs,
const uint16_t *s, size_t len, uid_t uid, pid_t spid
){
// 查找 AMS 是否在 SM 注册过,如果注册过就返回保存的 Service 信息
struct svcinfo *si = find_svc(s, len);
......
// 返回 AMS 的引用(handle)
return si->handle;
}
bio_put_ref()
// frameworks/native/cmds/servicemanager/binder.c
void bio_put_ref(
struct binder_io *bio, // reply
uint32_t handle
){
struct flat_binder_object *obj;
// 此时 if 命中
if (handle)
// 构建一个 flat_binder_object,再将 flat_binder_object 写入 reply 中
obj = bio_alloc_obj(bio);
else
obj = bio_alloc(bio, sizeof(*obj));
if (!obj)
return;
obj->flags = 0x7f | FLAT_BINDER_FLAG_ACCEPTS_FDS;
obj->type = BINDER_TYPE_HANDLE;
// 将 AMS 引用(handle)写入 flat_binder_object 中
obj->handle = handle;
obj->cookie = 0;
}
APP 进程被唤醒后做了什么?
APP 进程被唤醒后,继续执行未完成的 binder_thread_read
函数
返回栈如下:
binder_thread_read()
--> binder_ioctl_write_read()
--> IPCThreadState::talkWithDriver()
--> IPCThreadState::waitForResponse()
--> IPCThreadState::transact()
--> BinderProxy.transact()
--> ServiceManagerProxy.getService()
--> reply.readStrongBinder()
--> ServiceManager.getService("activity")
其中的大部分在上一篇博客中就已经介绍了,这里就不再重复阐述了
reply.readStrongBinder()
// frameworks/base/core/java/android/os/Parcel.java
public final IBinder readStrongBinder()
{
return nativeReadStrongBinder(mNativePtr);
}
// frameworks/base/core/jni/android_os_Parcel.cpp
static const JNINativeMethod gParcelMethods[] = {
......
{"nativeReadStrongBinder", "(J)Landroid/os/IBinder;", (void*)android_os_Parcel_readStrongBinder},
......
}
static jobject android_os_Parcel_readStrongBinder(JNIEnv* env,
jclass clazz,
jlong nativePtr
){
// 将 Java 层的 Parcel 类型(Java的Parcel)对象强制类型转换成 Native 层的 Parcel 类型对象(Native的Parcel)
Parcel* parcel = reinterpret_cast<Parcel*>(nativePtr);
if (parcel != NULL)
{
return javaObjectForIBinder(env, parcel->readStrongBinder());
}
return NULL;
}
Parcel::readStrongBinder()
// frameworks/native/libs/binder/Parcel.cpp
sp<IBinder> Parcel::readStrongBinder() const
{
sp<IBinder> val;
unflatten_binder(ProcessState::self(), *this, &val);
return val;
}
status_t unflatten_binder(const sp<ProcessState>& proc,
const Parcel& in, // reply
sp<IBinder>* out
){
// 从 reply 中读取出 flat_binder_object
const flat_binder_object* flat = in.readObject(false);
// 此时 if 命中
if (flat)
{
// 此时 flat->type = BINDER_TYPE_HANDLE
switch (flat->type)
{
// 当请求 Service 的进程与 Service 同属一个进程
case BINDER_TYPE_BINDER:
*out = reinterpret_cast<IBinder*>(flat->cookie);
return finish_unflatten_binder(NULL, *flat, in);
// 当请求 Service 的进程与 Service 分属不同进程
case BINDER_TYPE_HANDLE:
// 创建 BpBinder 对象
*out = proc->getStrongProxyForHandle(flat->handle);
return finish_unflatten_binder(static_cast<BpBinder*>(out->get()), *flat, in);
}
}
return BAD_TYPE;
}
ProcessState::getStrongProxyForHandle()
// frameworks/native/libs/binder/ProcessState.cpp
sp<IBinder> ProcessState::getStrongProxyForHandle(
int32_t handle // AMS 的引用(handle)
){
sp<IBinder> result;
......
// 创建 BpBinder 对象,handle 为 AMS
b = new BpBinder(handle);
......
result = b;
......
return result;
}
finish_unflatten_binder()
// frameworks/native/libs/binder/Parcel.cpp
inline static status_t finish_unflatten_binder(
BpBinder* /*proxy*/, const flat_binder_object& /*flat*/,
const Parcel& /*in*/)
{
return NO_ERROR;
}
Parcel::readStrongBinder()
函数会创建一个 BpBinder 对象,其 handle 为 AMS
javaObjectForIBinder()
// frameworks/base/core/jni/android_util_Binder.cpp
jobject javaObjectForIBinder(JNIEnv* env,
const sp<IBinder>& val // val = BpBinder
){
......
// 从 gBinderProxyOffsets 中查找 BinderProxy 对象
jobject object = (jobject)val->findObject(&gBinderProxyOffsets);
if (object != NULL)
{
// 通过查找 BinderProxy 对象的引用链,判断其是否正在被引用,返回其引用对象
jobject res = jniGetReferent(env, object);
// 如果 BinderProxy 对象正在被引用
if (res != NULL)
{
ALOGV("objectForBinder %p: found existing %p!\n", val.get(), res);
// 返回引用对象
return res;
}
......
// 移除与当前 BinderProxy 对象的所有引用
android_atomic_dec(&gNumProxyRefs);
val->detachObject(&gBinderProxyOffsets);
env->DeleteGlobalRef(object);
}
// 创建一个新的 BinderProxy 对象
object = env->NewObject(gBinderProxyOffsets.mClass, gBinderProxyOffsets.mConstructor);
if (object != NULL)
{
// 将 gBinderProxyOffsets 结构体中的成员变量 mObject 赋值(BpBinder),
// 记录 BpBinder 对象
env->SetLongField(object, gBinderProxyOffsets.mObject, (jlong)val.get());
// 创建智能指针,相当于当前函数把 BpBinder 强引用了
val->incStrong((void*)javaObjectForIBinder);
// jni 环境变量(env)生成一个对于 BinderProxy 对象的弱引用,用于检索
jobject refObject = env->NewGlobalRef(
env->GetObjectField(object, gBinderProxyOffsets.mSelf));
// 将 BinderProxy 对象信息添加到 BpBinder 的成员变量 mObjects 中,
// 将 BinderProxy 与 BpBinder 互相绑定
val->attachObject(&gBinderProxyOffsets, refObject,
jnienv_to_javavm(env), proxy_cleanup);
......
// BinderProxy.mOrgue 成员变量记录死亡通知对象
env->SetLongField(object, gBinderProxyOffsets.mOrgue,
reinterpret_cast<jlong>(drl.get()));
......
// BinderProxy 对象引用计数加一,标志 BinderProxy 对象已被引用
android_atomic_inc(&gNumProxyRefs);
......
}
return object;
}
此时 BinderProxy 对象绑定的 BpBinder 对象对应的是 AMS
reply.readStrongBinder()
函数会返回一个 BinderProxy 对象,其在 Native 层绑定了一个 BpBinder 对象(对应 AMS)
总结
按照调用栈的顺序,AMS 的获取流程大致如下图
大家结合流程图再去看代码流程可能会更加清晰一些