首页 最新 热门 推荐

  • 首页
  • 最新
  • 热门
  • 推荐

SurfaceFlinger02-surfaceflinger跨进程交互

  • 25-04-23 10:20
  • 2515
  • 5986
juejin.cn

前言

surfaceflinger既是一个独立进程,也是一个公共服务,它可以跟system_server交互,也可以直接和应用进程交互,还能跟底层HW Composer交互。这些操作都是通过Binder实现IPC(跟HWC是通过Aidl HAL)。

在surfaceflinger进程内部,提供了两个IPC服务来支撑和system_server/APP进程的交互。

整个交互架构上,提供了统一的接口层——SurfaceComposerClient,从而避免应用进程直接获取服务接口和交互实现。

本篇文章中,将对surfaceflinger进程进行跨进程通信(IPC)的接口服务、以及跨进程交互组件进行说明总结。

一、surfaceflinger进程IPC接口服务

1.1、IPC接口定义和注册

在surfaceflinger启动时,创建并注册了两个Binder 服务,用于和其他进程间进行交互:

cpp
代码解读
复制代码
// frameworks/native/services/surfaceflinger/main_surfaceflinger.cpp int main(int, char**) { // 注册ISurfaceComposer到servicemanager sp sm(defaultServiceManager()); sm->addService(String16(SurfaceFlinger::getServiceName()), flinger, false, IServiceManager::DUMP_FLAG_PRIORITY_CRITICAL | IServiceManager::DUMP_FLAG_PROTO); // 注册gui::ISurfaceComposer到servicemanager sp composerAIDL = sp::make(flinger); sm->addService(String16("SurfaceFlingerAIDL"), composerAIDL, false, IServiceManager::DUMP_FLAG_PRIORITY_CRITICAL | IServiceManager::DUMP_FLAG_PROTO); return 0; }

1.1.1、ISurfaceComposer接口

SurfaceFlinger类继承于BnSurfaceComposer,而BnSurfaceComposer是ISurfaceComposer接口的实现:

cpp
代码解读
复制代码
// frameworks/native/services/surfaceflinger/SurfaceFlinger.h class SurfaceFlinger : public BnSurfaceComposer { ...... } // frameworks/native/libs/gui/include/gui/ISurfaceComposer.h class BnSurfaceComposer: public BnInterface { ...... }

因此,SurfaceFlinger类在完成向ServiceManager的注册后便具有IPC能力。

1.1.2、gui::ISurfaceComposer接口

gui::ISurfaceComposer是Android T上通过AIDL的方式生成的服务接口,aidl文件位于如下位置中:

cpp
代码解读
复制代码
// frameworks/native/libs/gui/aidl/android/gui/ISurfaceComposer.aidl interface ISurfaceComposer { ....... }

surfaceflinger进程中,让SurfaceComposerAIDL继承了gui::BnSurfaceComposer:

cpp
代码解读
复制代码
// frameworks/native/services/surfaceflinger/SurfaceFlinger.h class SurfaceComposerAIDL : public gui::BnSurfaceComposer { ... }

如果需要在SurfaceComposerAIDL中新增接口,就必须要修改ISurfaceComposer.aidl文件。

通过SurfaceComposerAIDL,可以分担一部分SurfaceFlinger的跨进程压力。

SurfaceFlinger和SurfaceComposerAIDL的类关系如下图所示:

1.2、IPC服务获取方式

在完成向ServiceManager的注册后,就可以直接获取对应的IPC服务句柄了,Java层通过如下方式可获取SurfaceFlinger(ISurfaceComposer)服务:

cpp
代码解读
复制代码
// 获取ISurfaceComposer服务 IBinder sf = ServiceManager.getService("SurfaceFlinger"); if (sf != null) { reply = Parcel.obtain(); data = Parcel.obtain(); data.writeInterfaceToken("android.ui.ISurfaceComposer"); sf.transact(/* LAYER_TRACE_STATUS_CODE */ 1026, data, reply, 0 /* flags */); return reply.readBoolean(); }

C++层通过如下方式获取SurfaceFlinger(ISurfaceComposer)服务和SurfaceComposerAIDL(gui::ISurfaceComposer)服务:

cpp
代码解读
复制代码
// 获取SurfaceFlinger服务 const String16 name("SurfaceFlinger"); sp mComposerService = waitForService(name); // 获取SurfaceComposerAIDL服务 const String16 name("SurfaceFlingerAIDL"); sp mComposerService = waitForService(name);

不过,应用进程跟surfaceflinger进程的通信,更多地是通过一个“中间层”SurfaceComposerClient来进行,SurfaceComposerClient中通过以上方法获取surfaceflinger进程IPC服务,并将应用进程参数传递给surfaceflinger。

1.3、surfaceflinger服务端的响应

当客户端直接通过IPC服务的方式或通过SurfaceComposerClient发起跟surfaceflinger的交互后,surfaceflinger作为服务端进行响应,执行各自的onTransact()方法。

1.3.1、ISurfaceComposer::onTransact()

如果是ISurfaceComposer服务调用,会执行ISurfaceComposer::onTransact()方法:

cpp
代码解读
复制代码
// frameworks/native/libs/gui/ISurfaceComposer.cpp status_t BnSurfaceComposer::onTransact( uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) { switch (code) { case SET_TRANSACTION_STATE: { ...... } } ...... }

SurfaceFlinger类重写了该方法,因此,在收到来自其他进程的调用后,会优先执行父类方法,当父类方法没法满足时,执行子类中的逻辑:

cpp
代码解读
复制代码
// frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp status_t SurfaceFlinger::onTransact(uint32_t code, const Parcel& data, Parcel* reply, uint32_t flags) { if (const status_t error = CheckTransactCodeCredentials(code); error != OK) { return error; } // 优先执行父类方法 status_t err = BnSurfaceComposer::onTransact(code, data, reply, flags); if (err == UNKNOWN_TRANSACTION || err == PERMISSION_DENIED) { ..... int n; switch (code) { case 1000: // Unused. ...... } } }

1.3.2、gui::ISurfaceComposer::onTransact()

如果是来自gui::ISurfaceComposer服务的调用,由于它是通过aidl生成,因此直接会执行到对应方法,这些方法基本都被SurfaceComposerAIDL类进行了重写,如设置亮度接口:

cpp
代码解读
复制代码
// frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp binder::Status SurfaceComposerAIDL::setDisplayBrightness(const sp& displayToken, const gui::DisplayBrightness& brightness) { status_t status = checkControlDisplayBrightnessPermission(); if (status == OK) { status = mFlinger->setDisplayBrightness(displayToken, brightness); } return binderStatusFromStatusT(status); }

二、IPC相关组件

这里对应用进程和surfaceflinger进程在View内容更新过程中进行IPC时,涉及到的三个类进行下介绍:SurfaceComposerClient、SurfaceControl、SurfaceControl.Transaction。

2.1、SurfaceComposerClient

应用进程与surfaceflinger交互过程中,除特殊场景外,并不会直接获取服务接口进行通信,也不推荐这种方式。系统提供了统一的接口层——SurfaceComposerClient,作为surfaceflinger进程和应用进程间的“中间件”,进行IPC交互。此外,从SurfaceComposerClient命名看,就是SurfaceComposer的客户端,相对应的服务端正是SurfaceFlinger。

流程图1.jpg

SurfaceComposerClient中,获取SurfaceComposerAIDL服务实例如下:

arduino
代码解读
复制代码
// frameworks/native/libs/gui/SurfaceComposerClient.cpp // 获取SurfaceComposerAIDL服务实例 /*static*/ sp ComposerServiceAIDL::getComposerService() { ComposerServiceAIDL& instance = ComposerServiceAIDL::getInstance(); std::scoped_lock lock(instance.mMutex); if (instance.mComposerService == nullptr) { if (ComposerServiceAIDL::getInstance().connectLocked()) { WindowInfosListenerReporter::getInstance()->reconnect(instance.mComposerService); } } return instance.mComposerService; } bool ComposerServiceAIDL::connectLocked() { const String16 name("SurfaceFlingerAIDL"); mComposerService = waitForService(name); if (mComposerService == nullptr) { return false; // fatal error or permission problem } // Create the death listener. class DeathObserver : public IBinder::DeathRecipient { ComposerServiceAIDL& mComposerService; virtual void binderDied(const wp& who) { mComposerService.composerServiceDied(); } public: explicit DeathObserver(ComposerServiceAIDL& mgr) : mComposerService(mgr) {} }; mDeathObserver = new DeathObserver(*const_cast(this)); IInterface::asBinder(mComposerService)->linkToDeath(mDeathObserver); return true; }

获取SurfaceFlinger服务实例如下:

arduino
代码解读
复制代码
// frameworks/native/libs/gui/SurfaceComposerClient.cpp // 获取SurfaceFlinger服务实例 /*static*/ sp ComposerService::getComposerService() { ComposerService& instance = ComposerService::getInstance(); Mutex::Autolock _l(instance.mLock); if (instance.mComposerService == nullptr) { if (ComposerService::getInstance().connectLocked()) { ALOGD("ComposerService reconnected"); } } return instance.mComposerService; } bool ComposerService::connectLocked() { const String16 name("SurfaceFlinger"); mComposerService = waitForService(name); if (mComposerService == nullptr) { return false; // fatal error or permission problem } // Create the death listener. class DeathObserver : public IBinder::DeathRecipient { ComposerService& mComposerService; virtual void binderDied(const wp& who) { mComposerService.composerServiceDied(); } public: explicit DeathObserver(ComposerService& mgr) : mComposerService(mgr) { } }; mDeathObserver = new DeathObserver(*const_cast(this)); IInterface::asBinder(mComposerService)->linkToDeath(mDeathObserver); return true; }

2.2、SurfaceControl

SurfaceControl是暴露给外部进程用于操作surfaceflinger进程中Layer的句柄,它定义了图形缓冲数据、元数据、大小等多个属性,来描述如何显示一个Layer。当实例化一个SurfaceControl时,便会创建一个对应的Layer,并且将持有这个Layer的句柄(LayerHandle),通过LayerHandle管理Layer的保留和销毁。

应用进程的View在绘制过程中,就是将各类图形属性设置给SurfaceControl,并最终同步给surfaceflinger进行合成。

关于SurfaceControl的创建及更多细节,见《[SurfaceFlinger-07-Layer创建流程]) 》。

2.3、SurfaceControl.Transaction

SurfaceControl.Transaction是SurfaceControl中的静态内部类(以下简称Transaction),它作为一个“事务”,负责将设置给SurfaceControl的属性在同一帧内提交给surfaceflinger进行操作。

当应用进程进行View内容更新时,大致步骤如下:

  1. 第一步:应用进程将图形数据设置给SurfaceControl:
arduino
代码解读
复制代码
// frameworks/base/core/java/com/android/internal/policy/TransitionAnimation.java public static void configureScreenshotLayer(SurfaceControl.Transaction t, SurfaceControl layer, ScreenCapture.ScreenshotHardwareBuffer buffer) { // 为SurfaceControl对象设置一个Buffer t.setBuffer(layer, buffer.getHardwareBuffer()); // 设置DataSpace t.setDataSpace(layer, buffer.getColorSpace().getDataSpace()); // Avoid showing dimming effect for HDR content when running animation. if (buffer.containsHdrLayers()) { t.setDimmingEnabled(layer, false); } t.show(mAnimLeash); // 设置mSurfaceControl的区域 t.setCrop(mSurfaceControl, new Rect(0, 0, mEndWidth, mEndHeight)); }

2. 第二步:完成设置后,通过Transaction.apply()一次性将数据传递给SurfaceComposerClient:

ini
代码解读
复制代码
Transaction t = new Transaction(); ...... // 开始提交 t.apply();
  1. 第三步:收到apply()后,SurfaceComposerClient中向SurfaceFlinger发起调用:
arduino
代码解读
复制代码
// frameworks/native/libs/gui/SurfaceComposerClient.cpp status_t SurfaceComposerClient::Transaction::apply(bool synchronous, bool oneWay) { ...... sp sf(ComposerService::getComposerService()); sf->setTransactionState(mFrameTimelineInfo, composerStates, displayStates, flags, applyToken, mInputWindowCommands, mDesiredPresentTime, mIsAutoTimestamp, mUncacheBuffers, hasListenerCallbacks, listenerCallbacks, mId, mMergedTransactionIds); return NO_ERROR; }

除View的绘制和刷新之外,system_server和surfaceflinger之间屏幕状态的更新也是通过Transaction进行设置,这部分具体细节,见《SurfaceFlinger03-Transaction基础 》。

注:本文转载自juejin.cn的Android采码蜂的文章"https://juejin.cn/post/7455877073766678540"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接
复制链接
相关推荐
发表评论
登录后才能发表评论和回复 注册

/ 登录

评论记录:

未查询到任何数据!
回复评论:

分类栏目

后端 (14832) 前端 (14280) 移动开发 (3760) 编程语言 (3851) Java (3904) Python (3298) 人工智能 (10119) AIGC (2810) 大数据 (3499) 数据库 (3945) 数据结构与算法 (3757) 音视频 (2669) 云原生 (3145) 云平台 (2965) 前沿技术 (2993) 开源 (2160) 小程序 (2860) 运维 (2533) 服务器 (2698) 操作系统 (2325) 硬件开发 (2492) 嵌入式 (2955) 微软技术 (2769) 软件工程 (2056) 测试 (2865) 网络空间安全 (2948) 网络与通信 (2797) 用户体验设计 (2592) 学习和成长 (2593) 搜索 (2744) 开发工具 (7108) 游戏 (2829) HarmonyOS (2935) 区块链 (2782) 数学 (3112) 3C硬件 (2759) 资讯 (2909) Android (4709) iOS (1850) 代码人生 (3043) 阅读 (2841)

热门文章

101
推荐
关于我们 隐私政策 免责声明 联系我们
Copyright © 2020-2025 蚁人论坛 (iYenn.com) All Rights Reserved.
Scroll to Top