「这是我参与2022首次更文挑战的第4天,活动详情查看:2022首次更文挑战」。
Binder在显示图形系统中的应用
Binder简介
Binder是Android系统中进程间通信IPC的一种方式,是安卓系统中的最重要的特性之一。做过Android的开发者均对Android Binder有一定的了解,但是对于分析显示图形系统来说,有必要搞清楚Binder机制在此处的应用。
SurfaceFlinger的启动
SurfaceFlinger是显示图形系统中的一个重要服务,它启动于安卓系统的启动过程中,通过配置文件解析来获取到服务启动的关键数据
service surfaceflinger /system/bin/surfaceflinger
class core animation
user system
group graphics drmrpc readproc
capabilities SYS_NICE
onrestart restart zygote
task_profiles HighPerformance
socket pdx/system/vr/display/client stream 0666 system graphics u:object_r:pdx_display_client_endpoint_socket:s0
socket pdx/system/vr/display/manager stream 0666 system graphics u:object_r:pdx_display_manager_endpoint_socket:s0
socket pdx/system/vr/display/vsync stream 0666 system graphics u:object_r:pdx_display_vsync_endpoint_socket:s0
从这个配置文件可知,此处会生成一个surfaceflinger服务,该服务进程名为surfaceflinger,对应应用程序为/system/bin/surfaceflinger,此后会通过该应用程序的main函数启动该进程,而针对于Binder通信来说,我们主要关注如下代码
frameworks/native/services/surfaceflinger/main_surfaceflinger.cpp
int main(int, char**) {
// ...... 启动图形系统内存分配机制等,此处分析Binder机制,不考虑,省略
// When SF is launched in its own process, limit the number of
// binder threads to 4.
// 1. 设置当前进程的线程池最多只能包含4个binder线程
ProcessState::self()->setThreadPoolMaxThreadCount(4);
// start the thread pool
// 2. 启动线程池
sp<ProcessState> ps(ProcessState::self());
ps->startThreadPool();
// instantiate surfaceflinger
// 3. 初始化一个SurfaceFlinger对象
sp<SurfaceFlinger> flinger = surfaceflinger::createSurfaceFlinger();
// 设置进程优先级
setpriority(PRIO_PROCESS, 0, PRIORITY_URGENT_DISPLAY);
// ...... 和主题无关代码,此处省略
// publish surface flinger
// 4. 将SurfaceFlinger服务添加到系统服务管理器中
sp<IServiceManager> sm(defaultServiceManager());
sm->addService(String16(SurfaceFlinger::getServiceName()), flinger, false,
IServiceManager::DUMP_FLAG_PRIORITY_CRITICAL | IServiceManager::DUMP_FLAG_PROTO);
// ...... 和主题无关代码,此处直接省略
return 0;
}
如上,我们主要分析如下几个步骤
ProcessState的相关函数操作
ProcessState::self()函数,会返回一个指向ProcessState对象的指针,ProcessState的初始化时一个单例模式的构造函数,一个进程只有一个ProcessState指针对象,而在ProcessState的初始化过程中,通过ProcessState::open_driver函数打开/dev/binder驱动设备,并且在打开的过程中,会通过mmap在内核空间中开辟一块存储信息的内存
此段,在网上有很多的实例,在此处,不做过多的阐述
此后通过ProcessState::setThreadPoolMaxThreadCount函数,设置当前进程的Binder线程池中包含的最大Binder线程数为4,若线程池中线程数大于4的时候,会提示无法添加线程数,这段是通过ioctl和/dev/binder驱动设备进行交互设置的
ProcessState::startThreadPool函数,会初始化一个ProcessState::PoolThread线程,并运行,在这个线程运行的过程中,会初始化一个IPCThreadState指针对象,并且运行其joinThreadPool函数,而在这个函数中会直接和binder驱动设备进行交互,调用talkWithDriver函数等待binder驱动设备回应
由这段代码的描述可知,ProcessState是进程相关的,一个进程仅有一个ProcessState指针对象,而IPCThreadState是线程相关的,每个线程会有一个IPCThreadState指针对象
sequenceDiagram
main_surfaceflinger ->> ProcessState : self
ProcessState ->> ProcessState : new
ProcessState ->> binder : open_driver
main_surfaceflinger ->> ProcessState : setThreadPoolMaxThreadCount
ProcessState ->> binder : ioctl
main_surfaceflinger ->> ProcessState : startThreadPool
ProcessState ->> ProcessState : spawnPooledThread
ProcessState ->> PoolThread : new + run
PoolThread ->> IPCThreadState : joinThreadPool
IPCThreadState ->> binder : talkWithDriver
创建一个SurfaceFlinger指针对象
在SurfaceFlinger的初始化过程中,会创建一个MessageQueue指针对象,而由于此处创建的是一个SurfaceFlinger的强指针引用对象,因此还会调用SurfaceFlinger::onFirstRef函数,在这个函数中,会init MessageQueue指针对象
classDiagram
BnSurfaceComposer <|-- SurfaceFlinger
BnInterface <|-- BnSurfaceComposer
ISurfaceComposer <|-- BnInterface
class SurfaceFlinger {
+MessageQueue : mEventQueue
+onFirstRef()
}
将SurfaceFlinger服务添加到系统服务管理器ServiceManager中
sp<IServiceManager> sm(defaultServiceManager());
sm->addService(String16(SurfaceFlinger::getServiceName()), flinger, false,
IServiceManager::DUMP_FLAG_PRIORITY_CRITICAL | IServiceManager::DUMP_FLAG_PROTO);
defaultServiceManager函数
defaultServiceManager函数定义于IServiceManager.h中,在IServiceManager.cpp文件中实现
sp<IServiceManager> defaultServiceManager()
{
// call_once函数确保第二个参数函数指针只会运行一次
std::call_once(gSmOnce, []() {
// 第一个进入的时候,sm为nullptr
sp<AidlServiceManager> sm = nullptr;
while (sm == nullptr) {
// ProcessState是进程相关的,在一个进程中只会初始化一次,此处已经初始化过,binder设备驱动已经打开
// 1. ProcessState指针对象的getContextObject函数调用,注意传入参数为nullptr
// 2. interface_cast是一个模板函数,定义在IInterface.h中
sm = interface_cast<AidlServiceManager>(ProcessState::self()->getContextObject(nullptr));
// ......判空操作,此处省略
}
// 3. 直接初始化一个ServiceManagerShim指针对象并且返回,注意此处参数为刚刚创建的AidlServiceManager指针对象
gDefaultServiceManager = new ServiceManagerShim(sm);
});
return gDefaultServiceManager;
}
ProcessState的getContextObject函数调用
sequenceDiagram
IServiceManager->>ProcessState : getContextObject
ProcessState->>ProcessState : getStrongProxyForHandle
ProcessState->>BpBinder : create
BpBinder-->> ProcessState : 返回创建的BpBinder指针对象
从上述的时序图来看, 在defaultServiceManager函数中,调用了ProcessState的getContextObject函数,这个函数的传入参数为0,然后在ProcessState函数中调用其自身的getStrongProxyForHandle,传入参数为0,表明需要获取索引为0的对应代理对象,而在ProcessState对象中,通过lookupHandleLocked函数无法找到0所对应的对象,因此会直接调用BpBinder的create函数来初始化一个BpBinder指针对象,同时传入参数为0
也就是说,ProcessState的getContextObject函数最终会返回
new BpBinder(0, -1)
这段代码分析在网上有很多实例,此处仅做简要说明,不做具体分析
interface_cast模板函数调用,返回的究竟是什么
interface_cast模板函数定义于IInterface.h文件中
template<typename INTERFACE>
inline sp<INTERFACE> interface_cast(const sp<IBinder>& obj)
{
return INTERFACE::asInterface(obj);
}
而针对于
interface_cast<AidlServiceManager>(new BpBinder(0, -1));
来说,就会转换成如下的代码
AidlServiceManager::asInterface(new BpBinder(0, -1))
AidlServiceManager的定义如下:
using AidlServiceManager = android::os::IServiceManager;
也就是说,这个对象实际是android::os::IServiceManager对象,那么其asInterface函数定义在哪儿呢?原来这边使用了一个障眼法,IServiceManager.h中定义的IServiceManager的命名空间为android::IServiceManager,而此处的android::os::IServiceManager定义在IServiceManager.aidl中 在IServiceManager.aidl编译出来的cpp和头文件中可以看到如下代码
DECLARE_META_INTERFACE(ServiceManager)
而对应的IInterface.h中的定义为
#define DECLARE_META_INTERFACE(INTERFACE) \
public: \
static const ::android::String16 descriptor; \
static ::android::sp<I##INTERFACE> asInterface( \
const ::android::sp<::android::IBinder>& obj); \
virtual const ::android::String16& getInterfaceDescriptor() const; \
I##INTERFACE(); \
virtual ~I##INTERFACE(); \
static bool setDefaultImpl(std::unique_ptr<I##INTERFACE> impl); \
static const std::unique_ptr<I##INTERFACE>& getDefaultImpl(); \
private: \
static std::unique_ptr<I##INTERFACE> default_impl; \
public:
对应地,转换到IServiceManager中,转换为
DECLARE_META_INTERFACE(ServiceManager)
public: \
static const ::android::String16 descriptor; \
static ::android::sp<IServiceManager> asInterface( \
const ::android::sp<::android::IBinder>& obj); \
virtual const ::android::String16& getInterfaceDescriptor() const; \
IServiceManager(); \
virtual ~IServiceManager(); \
static bool setDefaultImpl(std::unique_ptr<IServiceManager> impl); \
static const std::unique_ptr<IServiceManager>& getDefaultImpl(); \
private: \
static std::unique_ptr<IServiceManager> default_impl; \
public:
同时,在IInterface.h和IServiceManager.cpp文件中对于上述声明的实现如下:
#define IMPLEMENT_META_INTERFACE(INTERFACE, NAME) \
DO_NOT_DIRECTLY_USE_ME_IMPLEMENT_META_INTERFACE(INTERFACE, NAME) \
#define DO_NOT_DIRECTLY_USE_ME_IMPLEMENT_META_INTERFACE(INTERFACE, NAME)\
// ...... 跟本篇暂无关,此处省略 \
::android::sp<I##INTERFACE> I##INTERFACE::asInterface( \
const ::android::sp<::android::IBinder>& obj) \
{ \
::android::sp<I##INTERFACE> intr; \
if (obj != nullptr) { \
intr = static_cast<I##INTERFACE*>( \
obj->queryLocalInterface( \
I##INTERFACE::descriptor).get()); \
if (intr == nullptr) { \
intr = new Bp##INTERFACE(obj); \
} \
} \
return intr; \
} \
// ...... 跟本篇暂无关,此处省略 \ \
I##INTERFACE::I##INTERFACE() { } \
I##INTERFACE::~I##INTERFACE() { } \
DO_NOT_DIRECTLY_USE_ME_IMPLEMENT_META_INTERFACE(ServiceManager, "android.os.IServiceManager")
// ...... 跟本篇暂无关,此处省略 \ \
::android::sp<IServiceManager> IServiceManager::asInterface( \
const ::android::sp<::android::IBinder>& obj) \
{ \
::android::sp<IServiceManager> intr; \
if (obj != nullptr) { \
intr = static_cast<IServiceManager*>( \
obj->queryLocalInterface( \
IServiceManager::descriptor).get()); \
if (intr == nullptr) { \
intr = new BpServiceManager(obj); \
} \
} \
return intr; \
} \
// ...... 跟本篇暂无关,此处省略 \ \
IServiceManager:: IServiceManager () { } \
IServiceManager::~ IServiceManager () { } \
因此,回到defaultServiceManager函数中,最终得到的结果是
new BpServiceManager(new BpBinder(0, -1))
生成一个IServiceManager指针对象,并返回
在defaultServiceManager函数中,通过new的方式直接初始化一个ServiceManagerShim指针对象,因此
ServiceManagerShim::ServiceManagerShim(const sp<AidlServiceManager>& impl)
: mTheRealServiceManager(impl)
{}
可知,在最终返回的这个ServiceManagerShim对象中,有一个指针参数mTheRealServiceManager是指向new BpServiceManager(new BpBinder(0, -1))的结果的
总结
综合如上的所有分析,可知,defaultServiceManager函数主要
- 返回一个ServiceManagerShim对象指针,这个对象指针继承自android::IServiceManager
- 这个ServiceManagerShim对象指针中,有一个参数mTheRealServiceManager参数指针,其实质是一个aidl对象android::os::IServiceManager对象,此处是BpServiceManager对象指针
- BpServiceManager对象指针初始化的时候,是以new BpBinder(0, -1)为参数的,在BpServiceManager对象中表现为一个mRemote指针对象
ServiceManagerShim指针对象的addService函数调用
从上述的分析可知,defaultServiceManager返回ServiceManagerShim指针对象,其addService函数定义如下
status_t ServiceManagerShim::addService(const String16& name, const sp<IBinder>& service,
bool allowIsolated, int dumpsysPriority)
{
Status status = mTheRealServiceManager->addService(
String8(name).c_str(), service, allowIsolated, dumpsysPriority);
return status.exceptionCode();
}
从上述分析可知,此处会调用BpServiceManager指针对象的addService函数
::android::binder::Status BpServiceManager::addService(const ::std::string& name, const ::android::sp<::android::IBinder>& service, bool allowIsolated, int32_t dumpPriority) {
// ...... 参数定义,省略
// ...... 数据写入,此处不提,省略
// remote()是什么?通过分析可知,就是上述BpServiceManager在初始化时传入的参数
// 即:new BpBinder(0, -1)
_aidl_ret_status = remote()->transact(::android::IBinder::FIRST_CALL_TRANSACTION + 2 /* addService */, _aidl_data, &_aidl_reply);
// ...... 状态判断代码,省略
return _aidl_status;
}
从这段代码可以看到,最终均是通过BpServiceManager的remote()返回的对象,通过transact来传递的,而通过分析可知,这个remote()返回的是BpServiceManager在初始化的时候传入的参数,即new BpBinder(0, -1)
status_t BpBinder::transact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
// Once a binder has died, it will never come back to life.
// 确定binder是活跃状态
if (mAlive) {
bool privateVendor = flags & FLAG_PRIVATE_VENDOR;
// don't send userspace flags to the kernel
flags = flags & ~FLAG_PRIVATE_VENDOR;
// user transactions require a given stability level
if (code >= FIRST_CALL_TRANSACTION && code <= LAST_CALL_TRANSACTION) {
using android::internal::Stability;
auto stability = Stability::get(this);
auto required = privateVendor ? Stability::VENDOR : Stability::kLocalStability;
// ...... 判空代码,省略
}
// 最终,通过IPCThreadState的transact函数,将数据传递出去
status_t status = IPCThreadState::self()->transact(
mHandle, code, data, reply, flags);
// 如果binder驱动通信无法连接,则表明此时binder驱动和上层连接断开,将binder状态置为非活跃状态
if (status == DEAD_OBJECT) mAlive = 0;
return status;
}
return DEAD_OBJECT;
}
而IPCThreadState的transact函数,在此前我们分析过,主要通过talkWithDriver函数跟binder驱动设备进行通信,将相关的数据发送给binder驱动设备,并等待其给出反馈数据,此处不做具体分析
总结
在这段代码中,主要通过defaultServiceManager获取一个ServiceManagerShim指针对象,然后调用其addService函数将对应的服务信息传递到binder驱动端内核内存中进行保存,待后续其他进程从内核内存中获取到对应的服务信息实现binder通信
Binder机制在显示图形系统中的应用:开机动画进程和SurfaceFlinger进程间的交互
开机动画进程(此处我们仅仅分析bootanim进程)在系统启动的过程中会直接启动,而在这个进程中,会通过和SurfaceFlinger进程进行交互来达到显示在屏幕设备上的目的
开机动画启动
开机动画进程和surfaceflinger进程是一样的,均是通过配置文件分析对配置文件进行解析启动的服务,
service bootanim /system/bin/bootanimation
class core animation
user graphics
group graphics audio
disabled
oneshot
ioprio rt 0
task_profiles MaxPerformance
根据配置文件解析结果可知,此处会解析出一个名称为bootanim的服务,这个服务程序在/system/bin/bootanimation下,分析这个服务代码,需要找到这个应用程序对应的main函数,最终会运行这个应用程序,找到其入口
/frameworks/base/cmds/bootanimation/bootanimation_main.cpp
int main()
{
setpriority(PRIO_PROCESS, 0, ANDROID_PRIORITY_DISPLAY);
// ...... 判空操作,省略代码
// 这段代码,在分析SurfaceFlinger启动的过程中有分析过,
// 此处会通过调用IPCThreadState::joinThreadPool函数跟binder驱动通信并启动线程池
sp<ProcessState> proc(ProcessState::self());
ProcessState::self()->startThreadPool();
// create the boot animation object (may take up to 200ms for 2MB zip)
// 创建一个BootAnimation的指针对象
sp<BootAnimation> boot = new BootAnimation(audioplay::createAnimationCallbacks());
// 等待SurfaceFlinger加载,其实就是等待SurfaceFlinger服务保存到Binder驱动
waitForSurfaceFlinger();
// 运行开机动画
boot->run("BootAnimation", PRIORITY_DISPLAY);
ALOGV("Boot animation set up. Joining pool.");
// 主线程添加线程池,并和binder驱动通信
IPCThreadState::self()->joinThreadPool();
return 0;
}
如上述分析描述,此处会初始化BootAnimation指针对象,等待SurfaceFlinger在binder驱动内核映射内存完成,再运行BootAnimation线程,因此
创建BootAnimation指针对象
BootAnimation的构造函数
BootAnimation::BootAnimation(sp<Callbacks> callbacks)
: Thread(false), mClockEnabled(true), mTimeIsAccurate(false), mTimeFormat12Hour(false),
mTimeCheckThread(nullptr), mCallbacks(callbacks), mLooper(new Looper(false)) {
// 主要是创建一个SurfaceComposerClient指针对象
mSession = new SurfaceComposerClient();
// ...... 条件设置代码,省略
}
// BootAnimation对象是一个强引用指针对象,因此,在构造函数调用的同时,会调用其onFirstRef函数
void BootAnimation::onFirstRef() {
status_t err = mSession->linkToComposerDeath(this);
// ......日志打印,省略
if (err == NO_ERROR) {
// ......日志打印,省略
preloadAnimation();
// ......日志打印,省略
}
}
classDiagram
Thread <|-- BootAnimation
class BootAnimation {
-SurfaceComposerClient : mSession
-preloadAnimation()
+session()
}
此处先创建一个SurfaceComposerClient指针对象,然后让这个SurfaceComposerClient指针对象调用linkToComposerDeath函数,这边应该是跟谁绑定同生共死,最后通过preloadAnimation函数加载动画图片
// frameworks/base/libs/gui/SurfaceComposerClient.cpp
SurfaceComposerClient::SurfaceComposerClient()
: mStatus(NO_INIT)
{}
// 强指针引用对象初始化,调用onFirstRef函数
void SurfaceComposerClient::onFirstRef() {
sp<ISurfaceComposer> sf(ComposerService::getComposerService());
if (sf != nullptr && mStatus == NO_INIT) {
sp<ISurfaceComposerClient> conn;
conn = sf->createConnection();
if (conn != nullptr) {
mClient = conn;
mStatus = NO_ERROR;
}
}
}
因此,在此处,我们需要线确认ComposerService::getComposerService函数究竟返回什么,然后其createConnection做了什么
ComposerService::getComposerService函数返回了什么
这个要从代码中看
/*static*/ sp<ISurfaceComposer> ComposerService::getComposerService() {
// ComposerService对象单例,因此此处返回一个只想ComposerService对象的指针
ComposerService& instance = ComposerService::getInstance();
Mutex::Autolock _l(instance.mLock);
// 刚刚初始化肯定为nullptr
if (instance.mComposerService == nullptr) {
ComposerService::getInstance().connectLocked();
assert(instance.mComposerService != nullptr);
ALOGD("ComposerService reconnected");
}
return instance.mComposerService;
}
void ComposerService::connectLocked() {
// getService函数是IServiceManager.h中定义的一个模板函数
// 需要注意的是,分析getService函数代码可以知道,此处可不是返回的SurfaceFlinger指针对象的
// mComposerService是一个ISurfaceComposer指针对象,因此最终会得到如下的对象
// new BpSurfaceComposer(sp<SurfaceFlinger>)
// 也就是说,此处的mComposerService实际是一个BpSurfaceComposer指针对象
// 其包含了一个mRemote指针指向SurfaceFlinger对象
const String16 name("SurfaceFlinger");
while (getService(name, &mComposerService) != NO_ERROR) {
usleep(250000);
}
assert(mComposerService != nullptr);
// 此处将刚刚创建的BpSurfaceComposer指针对象和此处的ComposerService指针对象关联在一起,并同生共死
// 当BpSurfaceCompsoer被销毁的时候,CompsoerService指针对象同时被销毁
// Create the death listener.
class DeathObserver : public IBinder::DeathRecipient {
ComposerService& mComposerService;
virtual void binderDied(const wp<IBinder>& who) {
ALOGW("ComposerService remote (surfaceflinger) died [%p]",
who.unsafe_get());
mComposerService.composerServiceDied();
}
public:
explicit DeathObserver(ComposerService& mgr) : mComposerService(mgr) { }
};
mDeathObserver = new DeathObserver(*const_cast<ComposerService*>(this));
IInterface::asBinder(mComposerService)->linkToDeath(mDeathObserver);
}
经过上述的代码分析,
- ComposerService中包含一个mComposerService参数指向一个BpSurfaceComposer对象,
- 这个BpSurfaceComposer对象中包含了一个参数名为mRemote的指针指向的是SurfaceFlinger对象,
- 且ComposerService中的BpSurfaceComposer指针对象参数mComposerService和这个ComposerService实现了同生共死状态
- 最终ComposerService.getComposerService函数返回的是一个BpSurfaceComposer指针对象
ISurfaceComposer::createConnection函数做了什么
经过上述分析可知,此处会调用BpSurfaceComposer指针对象的createConnection函数
virtual sp<ISurfaceComposerClient> createConnection()
{
Parcel data, reply;
// 写入token
data.writeInterfaceToken(ISurfaceComposer::getInterfaceDescriptor());
// BpSurfaceComposer::mRemote指向了surfaceflinger进程中的SurfaceFlinger对象
// 因此,此处会调用到SurfaceFlinger指针对象的transact函数,最终调用SurfaceFlinger的onTransact函数
// 如此就实现了跨进程通信
remote()->transact(BnSurfaceComposer::CREATE_CONNECTION, data, &reply);
// 获取返回的reply数据,并生成一个ISurfaceComposerClient指针函数
return interface_cast<ISurfaceComposerClient>(reply.readStrongBinder());
}
那么此处SurfaceFlinger中返回过来的是什么呢?
status_t BnSurfaceComposer::onTransact(
uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags)
{
switch(code) {
case CREATE_CONNECTION: {
CHECK_INTERFACE(ISurfaceComposer, data, reply);
// 这边是调用到SurfaceFlinger::createConnection函数
sp<IBinder> b = IInterface::asBinder(createConnection());
reply->writeStrongBinder(b);
return NO_ERROR;
}
// ......其他case,省略代码
}
}
sp<ISurfaceComposerClient> SurfaceFlinger::createConnection() {
// OO,看到了,原来此处返回的是Client对象
const sp<Client> client = new Client(this);
return client->initCheck() == NO_ERROR ? client : nullptr;
}
因此,在ISurfaceComposer::createConnection函数最终返回的是
interface_cast<ISurfaceComposerClient>(new Client(sp<SurfaceFlinger>))
根据此前的分析,此处返回了一个BpSurfaceComposerClient指针对象,这个对象中包含一个参数名为mRemote的指针指向Client对象
那么SurfaceComposerClient::mClient就是此处的BpSurfaceComposerClient指针对象了
总结
综上分析可知,BootAnimation指针对象的创建过程中,主要是做了
- 创建一个BootAnimation指针对象,这个对象有一个mSession指针,其指向一个SurfaceComposerClient对象
- SurfaceComposerClient指针对象中包含一个mClient参数,其指向了一个BpSurfaceComposerClient对象,而这个BpSurfaceComposerClient指针对象中包含一个参数mRemote指向surfaceflinger进程中的Client对象
- SurfaceComposerClient指针对象中包含有一个ComposerService类,是一个单例类,其初始化后包含一个参数名为mSurfaceComposer指针指向初始化的一个BpSurfaceComposer对象,而BpSurfaceComposer指针对象中包含一个参数mRemote指向surfaceflinger进程中的SurfaceFlinger指针对象
BootAnimation运行
BootAnimation类继承自Thread类,因此当它的run方法被运行的时候,会先后调用readyToRun函数和threadLoop函数 readyToRun函数,主要是通过SurfaceComposerClient的createSurface函数创建图层,以及获取显示设备display,最终均会调用到SurfaceFlinger服务中,根据此前的分析,此处应该不难 threadloop函数主要是将对应的开机动画绘制并送显的过程,由于此篇不是分析这个过程,此处不做分析
总结
如上述分析,Binder机制在显示图形系统中的应用很广泛,当另一个进程需要和surfaceflinger进行交互或者数据交换的时候,需要通过Binder机制从binder驱动内核空间取出surfaceflinger进程存入的对应对象,然后通过binder驱动进行交互等