Android应用程序与Su易做图ceFlinger服务之间的共享UI元数据(SharedClient)的创建过程分析
在前面一篇文章中,我们分析了Android应用程序与Su易做图ceFlinger服务的连接过程。Android应用程序成功连接上Su易做图ceFlinger服务之后,还需要一块匿名共享内存来和Su易做图ceFlinger服务共享它的UI元数据,以便使得Su易做图ceFlinger服务可以正确地为它创建以及渲染Su易做图ce。在本文中,我们将详细地分析这块用来保存UI元数据的匿名共享内存的创建过程。
在Android应用程序与Su易做图ceFlinger服务的关系概述和学习计划一文中提到,用来保存Android应用程序的UI元数据的匿名共享内存最终是被结构化为一个SharedClient对象来访问的。每一个与UI有关的Android应用程序进程有且仅有一个SharedClient对象,而且这些SharedClient对象是由Android应用程序请求Su易做图ceFlinger服务创建的:Android应用程序首先获得Su易做图ceFlinger服务的一个Binder代理接口,然后再通过这个代理接口得到另外一个类型为UserClient的Binder代理接口,最后就可以通过后一个Binder代理接口来获得一个SharedClient对象。
由于每一个与UI有关的Android应用程序进程有且仅有一个SharedClient对象,因此,Android系统就通过一个单例模式的类来专负责创建和管理这个SharedClient对象。这个类的名称为Su易做图ceClient,定义在frameworks/base/libs/su易做图ceflinger_client/Su易做图ce.cpp文件中,如下所示:
[cpp]
class Su易做图ceClient : public Singleton<Su易做图ceClient>
{
// all these attributes are constants
sp<ISu易做图ceComposer> mComposerService;
sp<ISu易做图ceComposerClient> mClient;
status_t mStatus;
SharedClient* mControl;
sp<IMemoryHeap> mControlMemory;
Su易做图ceClient()
: Singleton<Su易做图ceClient>(), mStatus(NO_INIT)
{
sp<ISu易做图ceComposer> sf(ComposerService::getComposerService());
mComposerService = sf;
mClient = sf->createClientConnection();
if (mClient != NULL) {
mControlMemory = mClient->getControlBlock();
if (mControlMemory != NULL) {
mControl = static_cast<SharedClient *>(
mControlMemory->getBase());
if (mControl) {
mStatus = NO_ERROR;
}
}
}
}
friend class Singleton<Su易做图ceClient>;
public:
status_t initCheck() const {
return mStatus;
}
SharedClient* getSharedClient() const {
return mControl;
}
ssize_t getTokenForSu易做图ce(const sp<ISu易做图ce>& sur) const {
// TODO: we could cache a few tokens here to avoid an IPC
return mClient->getTokenForSu易做图ce(sur);
}
void signalServer() const {
mComposerService->signal();
}
};
当Su易做图ceClient类的静态成员函数getInstance第一次被调用的时候,系统就会在对应的应用程序进程中创建一个Su易做图ceClient对象,即会调用Su易做图ceClient类的构造函数。Su易做图ceClient类的构造函数首先会调用ComposerService类的静态成员函数getComposerService来获得一个Su易做图ceFlinger服务的代理接口,并且保存在Su易做图ceClient类的成员变量mComposerService中,以便以后可以使用。ComposerService类的静态成员函数getComposerService在前面Android应用程序与Su易做图ceFlinger服务的连接过程分析一文中已经分析过了,这里不再详述。有了Su易做图ceFlinger服务的代理接口sf之后,Su易做图ceClient类的构造函数接着就可以调用它的成员函数createUserClient来获得一个类型为UserClient的Binder代理接口,这个Binder代理接口实现了ISu易做图ceComposerClient接口,因此,我们可以将它保存在Su易做图ceClient类的成员变量mClient中。最后,Su易做图ceClient类的构造函数就调用前面获得的类型为ISu易做图ceComposerClient的Binder代理接口mClient的成员函数getControlBlock来获得一块用来描述应用程序UI元数据的匿名共享内存mControlMemory ,并且将这些匿名共享内存强制转化为一个SharedClient对象mControl,以便后面可以方便地访问UI元数据。
以上就是Android应用程序与Su易做图ceFlinger服务之间的共享UI元数据(SharedClient)的创建过程的总体描述,接下来我们再详细分析每一步的实现。现在,我们继续分析一下Su易做图ceClient类的其余成员函数的实现:
1. 成员函数initCheck用来检查一个Android应用程序进程是否已经成功地请求Su易做图ceFlinger服务创建了一块用来描述UI元数据的SharedClient对象了。
2. 成员函数getSharedClient用来返回用来描述UI元数据的SharedClient对象mControl。
3. 成员函数getTokenForSu易做图ce用来返回由参数sur所描述的一个Su易做图ce的Token值。这个Token值由Su易做图ceFlinger服务来创建和管理,并且可以通过前面所获得的类型为UserClient的Binder代理接口mClient的成员函数getTokenSu易做图ce来获得。
4. 成员函数signalServer用来通知Su易做图ceFlinger服务更新Android应用程序UI,这是通过调用Su易做图ceFlinger服务的代理接口mComposerService的成员函数signal来实现的,实际上就是向Su易做图ceFlinger服务发送一个信号,以便可以将它唤醒起来更新UI。
介绍完成Su易做图ceClient类的实现之后,我们还需要了解一下两个类的实现,即UserClient类和SharedClient类的实现,以便可以帮助我们了解用来保存Android应用程序的UI元数据的匿名共享内存的创建过程,以及帮助后面两篇文章对Su易做图ce的创建和渲染过程的分析。
接下来,我们就首先分析UserClient类的实现,接着再分析SharedClient类的实现。
在Android应用程序与Su易做图ceFlinger服务的连接过程分析一文的图2中,我们介绍了用来连接Android应用程序和Su易做图ceFlinger服务的Client类,而UserClient类和Client类是类似的,它们都实现了相同的接口,只不过是侧重点有所不同。Android应用程序与Su易做图ceFlinger服务的连接过程分析一文的图2中的Client类替换成UserClient类,就可以得到UserClient类的实现结构图,如图1所示:
图1 UserClient类的实现结构图
UserClient类与Client类最重要的区别是,前者实现了ISu易做图ceComposerClient接口的成员函数getControlBlock,而后者实现了ISu易做图ceComposerClient接口的成员函数createSu易做图ce。后面我们就会分析UserClient类是如何实现ISu易做图ceComposerClient接口的成员函数getControlBlock的。
UserClient类的实现暂时就介绍到这里,接下来我们来看SharedClient类的实现。为了方便描述,我们把Android应用程序与Su易做图ceFlinger服务的关系概述和学习计划一文的图4和图5贴出来,如以下图2和图3所示:
图2 用来描
补充:移动开发 , Android ,