当前位置: 首页 > news >正文

图像显示框架四——应用与SurfaceFlinger构建桥梁(基于Android 15源码分析)

1.前言

上一篇介绍了如何创建Native的示例应用,从应用开发使用的角度去调用了相关api,从这篇来详细介绍如何调用到系统层,系统内部如何实现的

本篇主要介绍应用与SurfaceFlinger的交互,即如何与SurfaceFlinger进行通信的。

ps:本篇涉及到的代码位置如下:

/frameworks/native/libs/gui/

/frameworks/native/libs/gui/include/gui/

/frameworks/native/libs/gui/include/private/gui/

/frameworks/native/libs/gui/aidl/android/gui/

/frameworks/native/services/surfaceflinger/

2.应用与SurfaceFlinger通信

类图关系

首先我们看一下SurfaceFlinger RPC架构有哪些类,以及这些类是什么关系,如下是Android 15中的类图关系

应用层 (Application Layer)

SurfaceComposerClient (客户端包装器)
↓ 持有
ISurfaceComposer.aidl (AIDL生成接口)
├── BpSurfaceComposer (自动生成代理)
└── BnSurfaceComposer (自动生成桩)
↓ 实现
SurfaceFlingerAIDL (服务实现)
↓ 管理
ClientAIDL (客户端会话)
↓ 持有
ISurfaceComposerClient.aidl (AIDL生成客户端接口)
├── BpSurfaceComposerClient (自动生成代理)  
└── BnSurfaceComposerClient (自动生成桩)
↓ 实现
SurfaceControlAIDL (Surface控制)
↓ 管理
BLASTBufferQueue (现代缓冲区队列)
↓ 提供
IGraphicBufferProducer.aidl (AIDL生成生产者接口)

上述可以看出来在Android 15中基本都将原始的binder通信改成跨进程通信了,这个是在Android 14中进行改动的,如下是Android 13与Android 14对比

接口层映射

Android 13组件

Android 14等价组件

生成方式变化

ISurfaceComposer

gui::ISurfaceComposer

手动声明 → AIDL定义

BpSurfaceComposer

BpSurfaceComposer

手动实现 → 自动生成

BnSurfaceComposer

BnSurfaceComposer

手动实现 → 自动生成

ISurfaceComposerClient

gui::ISurfaceComposerClient

手动声明 → AIDL定义

IGraphicBufferProducer

gui::IGraphicBufferProducer

手动声明 → AIDL定义

在Android 15上面上述就是进行aidl通信的,用法比较简单,没有冗余的代码

主要类:

客户端:ISurfaceComposer、ISurfaceComposerClient

服务端:SurfaceFlinger、Client

重点内容:

1. ComposerServiceAIDL中有成员mComposerService,它代表了SurfaceFlinger服务的代理客户端;

2. SurfaceComposerClient中有成员mClient,它代表了SurfaceFlinger服务进程中的Client的代理客户端

源码解析

应用层创建SurfaceComposerClient对象,并且后续就是通过这个对象与SurfaceFlinger建立连接以及进行后续的交互

如下就是在上一篇中的代码,创建SurfaceComposerClient对象

// 创建SurfaceComposerClient,建立与SurfaceFlinger服务的连接sp<SurfaceComposerClient> surfaceComposerClient = new SurfaceComposerClient;status_t err = surfaceComposerClient->initCheck();if (err != NO_ERROR) {ALOGD("SurfaceComposerClient::initCheck error: %#x\n", err);return;}

然后我们来看下/frameworks/native/libs/gui/SurfaceComposerClient.cpp中的代码

SurfaceComposerClient::SurfaceComposerClient() : mStatus(NO_INIT) {}SurfaceComposerClient::SurfaceComposerClient(const sp<ISurfaceComposerClient>& client): mStatus(NO_ERROR), mClient(client) {}

可以看出来构造方法中并没有做什么操作,进行mStatus初始化操作,其中mClient也可以外部传入,这个mClient是SurfaceFlinger服务进程中的Client的代理客户端,关注下

然后我们看一下SurfaceComposerClient中的onFirstRef方法

void SurfaceComposerClient::onFirstRef() {sp<gui::ISurfaceComposer> sf(ComposerServiceAIDL::getComposerService());if (sf != nullptr && mStatus == NO_INIT) {sp<ISurfaceComposerClient> conn;binder::Status status = sf->createConnection(&conn);if (status.isOk() && conn != nullptr) {mClient = conn;mStatus = NO_ERROR;}}
}

然后我们先看下ComposerServiceAIDL的定义,目前来看此处是通过aidl进行跨进程通信的,然后ComposerServiceAIDL.h代码如下:

class ComposerServiceAIDL : public Singleton<ComposerServiceAIDL> {sp<gui::ISurfaceComposer> mComposerService;sp<IBinder::DeathRecipient> mDeathObserver;mutable std::mutex mMutex;ComposerServiceAIDL();bool connectLocked();void composerServiceDied();friend class Singleton<ComposerServiceAIDL>;

上述可以看出来是单例模式,然后mComposerService是SurfaceFlinger的客户端代理,connectlocked()方法是重点,后面有介绍
然后来看下ComposerServiceAIDL的实现,如下:

ComposerServiceAIDL::ComposerServiceAIDL() : Singleton<ComposerServiceAIDL>() {std::scoped_lock lock(mMutex);connectLocked();
}bool ComposerServiceAIDL::connectLocked() {const String16 name("SurfaceFlingerAIDL");mComposerService = waitForService<gui::ISurfaceComposer>(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<IBinder>& who) {ALOGW("ComposerService aidl remote (surfaceflinger) died [%p]", who.unsafe_get());mComposerService.composerServiceDied();}public:explicit DeathObserver(ComposerServiceAIDL& mgr) : mComposerService(mgr) {}};mDeathObserver = new DeathObserver(*const_cast<ComposerServiceAIDL*>(this));IInterface::asBinder(mComposerService)->linkToDeath(mDeathObserver);return true;
}

上述代码可以看出来ComposerServiceAIDL在调用connectLocked中获取到SurfaceFlinger服务的客户端代理,此处可以看出来是通过aidl的方式进行通信的

然后在回到SurfaceComposerClient::onFirstRef方法中,通过ComposerService::getComposerService()获取到SurfaceFlinger服务的代理客户端后,接下来就是去初始化mClient

void SurfaceComposerClient::onFirstRef() {sp<gui::ISurfaceComposer> sf(ComposerServiceAIDL::getComposerService());if (sf != nullptr && mStatus == NO_INIT) {sp<ISurfaceComposerClient> conn;binder::Status status = sf->createConnection(&conn);if (status.isOk() && conn != nullptr) {mClient = conn;mStatus = NO_ERROR;}}
}

通过aidl跨进程通信调用到SurfaceFlinger的createConnection()方法中,如下:

在frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp中

binder::Status SurfaceComposerAIDL::createConnection(sp<gui::ISurfaceComposerClient>* outClient) {const sp<Client> client = sp<Client>::make(mFlinger);if (client->initCheck() == NO_ERROR) {*outClient = client;if (FlagManager::getInstance().misc1()) {const int policy = SCHED_FIFO;client->setMinSchedulerPolicy(policy, sched_get_priority_min(policy));}return binder::Status::ok();} else {*outClient = nullptr;return binderStatusFromStatusT(BAD_VALUE);}
}

SurfaceFlinger::createConnection方法中创建一个Client对象,Client对象是通过aidl实现的跨进程通信,是客户端代理,这样SurfaceComposerClient::mClient就和SurfaceFlinger建立了连接。

时序图

应用进程 (Application)          ServiceManager           SurfaceFlingerAIDL进程
|                               |                           |
|---1. new SurfaceComposerClient()------------------------>|
|   (应用进程内部创建)            |                           |
|                               |                           |
|<--2. onFirstRef()回调-------------------------------------|
|   (应用进程内部回调)            |                           |
|                               |                           |
|---3. ComposerServiceAIDL.getComposerService()----------->|
|                               |                           |
|---4. ServiceManager.getService("SurfaceFlingerAIDL")--->|
|                               |---5. 查询服务注册表------>|
|<--6. 返回ISurfaceComposer代理----------------------------|
|   (应用进程内部)                |                           |
|                               |                           |
|---7. ISurfaceComposer.createConnection()---------------->|
|                               |                           |
|                               |---8. SurfaceFlingerAIDL.createConnection()|
|                               |                           |
|                               |---9. new ClientAIDL()---->|
|                               |   (SurfaceFlinger进程内部) |
|<--10. 返回ISurfaceComposerClient代理---------------------|
|   (应用进程内部)                |                           |
|                               |                           |
|---11. 保存到mClient成员--------------------------------->|
|   (应用进程内部)                |                           |
|                               |                           |

http://www.dtcms.com/a/573586.html

相关文章:

  • 设计网站首页1农村自建房设计图纸及效果图大全
  • Git 同一个文件多次修改的 revert 的顺序
  • RFSOC29DR教程:iberf光口自环模块测试
  • (未完)超超超详版Sentinel2-L1C 数据获取及预处理 | hello,GEE!
  • wordpress企业网站入门嘉兴网站建设多少钱
  • 国外网站为啥速度慢为企业规划网络促销方案
  • 25微软MOS认证考试|时间 + 科目 + 备考攻略全梳理
  • 数控直流电流源设计指南:基于MCU+FPGA的精密控制与低功耗优化
  • mlir 编译器学习笔记之五 -- 开发避坑
  • 对接网站建设是什么意思网站的实用性
  • 深圳网站优化页面全功能多国语言企业网站
  • web开发之前后端分离的优势
  • 外贸网站推广平台有哪些网站建设公司南京
  • Linux 常用命令大全:从入门到精通
  • Linux-通过端口转发访问数据库
  • IPD PDT 团队月例会
  • 网站如何被百度收录之探索笔记
  • 番茄小说畅听红果短剧提示“低版本不安全“解决方案 【巨魔篇】
  • 付网站建设服务费什么科目查关键词排名软件
  • k8s——service详解
  • 【高阶数据结构】map,set,multiset,multimap的使用和介绍
  • Spring Boot + Spring Security ACL实现对特定领域对象的细粒度权限控制
  • 大模型应用03 || 函数调用 Function Calling || 概念、思想、流程
  • 从 Spring Boot 到 NestJS:模块化设计的哲学差异
  • WebSocket 使用
  • 郑州网络营销网站app上架应用市场需要什么条件
  • 百度网站官方认证怎么做郑州网站建设贴吧
  • Spring定时任务cron表达式解析
  • 做网站通过什么赚钱wordpress 主题 下载
  • MATLAB视觉检测系统详细介绍