diff --git a/OAT.xml b/OAT.xml index 03bcd02b..1f2feceb 100644 --- a/OAT.xml +++ b/OAT.xml @@ -62,6 +62,7 @@ Note:If the text contains special characters, please escape them according to th + diff --git a/README.md b/README.md deleted file mode 100644 index 622d01ba..00000000 --- a/README.md +++ /dev/null @@ -1,715 +0,0 @@ -# WidnowManager - -- [Introduction](#section1333751883213) -- [Directory Structure](#section1882912343) -- [Constraints](#section68982123611) -- [Compilation and Building](#section671864110372) -- [Available APIs](#section197399520386) - - [WindowManager](#section5851104093816) - - [Window](#section3483122273912) - - [SubWindow](#section96481249183913) - - [Surface](#section12366161544010) - - [SurfaceBuffer](#section12001640184711) - - [VsyncHelper](#section1392116294211) - -- [Usage](#section18359134910422) - - [Transferring a Producer Surface](#section193464304411) - - [Creating a Producer Surface](#section1276823075112) - - [Producing a SurfaceBuffer](#section614545716513) - - [Consuming a SurfaceBuffer](#section315285412535) - - [Adding Custom Data to a SurfaceBuffer](#section612412125616) - - [Registering a Vsync Callback Listener](#section1148115214576) - -- [\#EN-US\_TOPIC\_0000001105482134/section1939493174420](#section1939493174420) -- [Repositories Involved](#section6488145313) - -## Introduction - -The Graphics subsystem provides graphics and window management capabilities, which can be invoked by using Java or JS APIs. It can be used for UI development for all standard-system devices. - -The following figure shows the architecture of the Graphics subsystem. - -![](figures/graphic.png) - -- Surface - - Provides APIs for managing the graphics buffer and the efficient and convenient rotation buffer. - -- Vsync - - Provides APIs for managing registration and response of all vertical sync signals. - -- WindowManager - - Provides APIs for creating and managing windows. - -- WaylandProtocols - - Provides the communication protocols between the window manager and synthesizer. - -- Compositor - - Implements synthesis of layers. - -- Renderer - - Functions as the back-end rendering module of the synthesizer. - -- Wayland protocols - - Provides Wayland inter-process communication protocols. - -- Shell - - Provides multi-window capabilities. - -- Input Manger - - Functions as the multimodal input module that receives input events. - - -## Directory Structure - -``` -foundation/graphic/standard/ -├── frameworks # Framework code -│ ├── bootanimation # Boot Animation code -│ ├── surface # Surface code -│ ├── vsync # Vsync code -│ └── wm # WindowManager code -├── interfaces # External APIs -│ ├── innerkits # Native APIs -│ └── kits # JS APIs and NAPIs -└── utils # Utilities -``` - -## Constraints - -- Language version: C++ 11 or later - -## Compilation and Building - -The dependent APIs include the following: - -- graphic\_standard:libwms\_client -- graphic\_standard:libsurface -- graphic\_standard:libvsync\_client - -## Available APIs - -### WindowManager - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

API

-

Description

-

GetInstance

-

Obtains the pointer to a singleton WindowManager instance.

-

GetMaxWidth

-

Obtains the width of the screen.

-

GetMaxHeight

-

Obtains the height of the screen.

-

CreateWindow

-

Creates a standard window.

-

CreateSubWindow

-

Creates a child window.

-

StartShotScreen

-

Takes a screenshot.

-

StartShotWindow

-

Captures a window.

-

SwitchTop

-

Moves the specified window to the top.

-
- -### Window - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

API

-

Description

-

Show

-

Displays the current window.

-

Hide

-

Hides the current window.

-

Move

-

Moves the current window to a specified position.

-

SwitchTop

-

Moves the current window to the top.

-

ChangeWindowType

-

Changes the type of the current window.

-

ReSize

-

Resizes the current window.

-

Rotate

-

Rotates the current window.

-

RegistPointerButtonCb

-

Registers the callback for Button events of the mouse.

-

RegistPointerEnterCb

-

Registers the callback for Enter events of the mouse.

-

RegistPointerLeaveCb

-

Registers the callback for Leave events of the mouse.

-

RegistPointerMotionCb

-

Registers the callback for Motion events of the mouse.

-

RegistPointerAxisDiscreteCb

-

Registers the callback for AxisDiscrete events of the mouse.

-

RegistPointerAxisSourceCb

-

Registers the callback for AxisSource events of the mouse.

-

RegistPointerAxisStopCb

-

Registers the callback for AxisStop events of the mouse.

-

RegistPointerAxisCb

-

Registers the callback for Axis events of the mouse.

-

RegistTouchUpCb

-

Registers the callback for TouchUp events.

-

RegistTouchDownCb

-

Registers the callback for TouchDown events.

-

RegistTouchEmotionCb

-

Registers the callback for TouchEmotion events.

-

RegistTouchFrameCb

-

Registers the callback for TouchFrame events.

-

RegistTouchCancelCb

-

Registers the callback for TouchCancel events.

-

RegistTouchShapeCb

-

Registers the callback for TouchShape events.

-

RegistTouchOrientationCb

-

Registers the callback for TouchOrientation events.

-

RegistKeyboardKeyCb

-

Registers the callback for Key events of the keyboard.

-

RegistKeyboardKeyMapCb

-

Registers the callback for KeyMap events of the keyboard.

-

RegistKeyboardLeaveCb

-

Registers the callback for Leave events of the keyboard.

-

RegistKeyboardEnterCb

-

Registers the callback for Enter events of the keyboard.

-

RegistKeyboardRepeatInfoCb

-

Registers the callback for RepeatInfo events of the keyboard.

-
- -### SubWindow - - - - - - - - - - - - - -

API

-

Description

-

Move

-

Moves the current child window.

-

SetSubWindowSize

-

Sets the size of the current child window.

-
- -### Surface - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

API

-

Description

-

CreateSurfaceAsConsumer

-

Creates a surface for the buffer consumer.

-

CreateSurfaceAsProducer

-

Creates a surface for the buffer producer. Only production-related APIs can be used.

-

GetProducer

-

Obtains an internal IBufferProducer object of Surface.

-

RequestBuffer

-

Requests a SurfaceBuffer object to be produced.

-

CancelBuffer

-

Cancels a SurfaceBuffer object to be produced.

-

FlushBuffer

-

Flushes a produced SurfaceBuffer object with certain information.

-

AcquireBuffer

-

Requests a SurfaceBuffer object to be consumed.

-

ReleaseBuffer

-

Returns a consumed SurfaceBuffer object.

-

GetQueueSize

-

Obtains the number of concurrent buffers.

-

SetQueueSize

-

Sets the number of concurrent buffers.

-

SetDefaultWidthAndHeight

-

Sets the default width and height.

-

GetDefaultWidth

-

Obtains the default width.

-

GetDefaultHeight

-

Obtains the default height.

-

SetUserData

-

Stores string data, which will not be transferred through IPC.

-

GetUserData

-

Obtains string data.

-

RegisterConsumerListener

-

Registers a consumer listener to listen for buffer flush events.

-

UnregisterConsumerListener

-

Unregiseters a consumer listener.

-
- -### SurfaceBuffer - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -

API

-

Description

-

GetBufferHandle

-

Obtains the BufferHandle pointer to the SurfaceBuffer object.

-

GetWidth

-

Obtains the width of the SurfaceBuffer object.

-

GetHeight

-

Obtains the height of the SurfaceBuffer object.

-

GetFormat

-

Obtains the color format of the SurfaceBuffer object.

-

GetUsage

-

Obtains the usage of the SurfaceBuffer object.

-

GetPhyAddr

-

Obtains the physical address of the SurfaceBuffer object.

-

GetKey

-

Obtains the key of the SurfaceBuffer object.

-

GetVirAddr

-

Obtains the virtual address of the SurfaceBuffer object.

-

GetSize

-

Obtains the size of the SurfaceBuffer object.

-

SetInt32

-

Sets the 32-bit integer for the SurfaceBuffer object.

-

GetInt32

-

Obtains the 32-bit integer for the SurfaceBuffer object.

-

SetInt64

-

Sets the 64-bit integer for the SurfaceBuffer object.

-

GetInt64

-

Obtains the 64-bit integer for the SurfaceBuffer object.

-
- -### VsyncHelper - - - - - - - - - - - - - - - - -

API

-

Description

-

Current

-

Obtains the VsyncHelper object of the current runner.

-

VsyncHelper

-

Constructs a VsyncHelper object using an EventHandler object.

-

RequestFrameCallback

-

Registers a frame callback.

-
- -## Usage - -### Transferring a Producer Surface - -1. Named service - - Service registration: - - ``` - // Obtain a consumer surface. - sptr surface = Surface::CreateSurfaceAsConsumer(); - // Extract the producer object. - sptr producer = surface->GetProducer(); - // Register the service. - auto sm = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); - sm->AddSystemAbility(IPC_SA_ID, producer->AsObject()); - ``` - - - Construction of a producer surface: - - ``` - // Obtain a producer object. - auto sm = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); - sptr robj = sm->GetSystemAbility(IPC_SA_ID); - // Construct a surface. - sptr bp = iface_cast(robj); - sptr surface = Surface::CreateSurfaceAsProducer(bp); - ``` - - -2. Anonymous service - - Sending of a surface: - - ``` - // Obtain a consumer surface. - sptr surface = CreateSurfaceAsConsumer(); - // Extract the producer object. - sptr producer = surface->GetProducer(); - // Return the producer object to the client. - parcel.WriteRemoteObject(producer); - ``` - - - -### Creating a Producer Surface - -``` -// Obtain a producer object. -sptr remoteObject = parcel.ReadRemoteObject(); -// Construct a surface. -sptr bp = iface_cast(robj); -sptr surface = Surface::CreateSurfaceAsProducer(bp); -``` - -### Producing a SurfaceBuffer - -``` -// Prerequisite: a producer surface -BufferRequestConfig requestConfig = { - .width = 1920, // Screen width - .height = 1080, // Screen height - .strideAlignment = 8, // Stride alignment byte - .format = PIXEL_FMT_RGBA_8888, // Color format - .usage = HBM_USE_CPU_READ | HBM_USE_CPU_WRITE | HBM_USE_MEM_DMA, // Usage - .timeout = 0, // Delay -}; - -sptr buffer; -int32_t releaseFence; - -SurfaceError ret = surface->RequestBuffer(buffer, releaseFence, requestConfig); -if (ret != SURFACE_ERROR_OK) { - // failed -} - -BufferFlushConfig flushConfig = { - .damage = { // Redrawing buffer zone - .x = 0, // Horizontal coordinate of the start point - .y = 0, // Vertical coordinate of the start point - .w = buffer->GetWidth(), // Width of the buffer zone - .h = buffer->GetHeight(), // Height of the buffer zone - }, - .timestamp = 0 // Time displayed to consumers. Value 0 indicates the current time. -}; - -ret = surface->FlushBuffer(buffer, -1, flushConfig); -if (ret != SURFACE_ERROR_OK) { - // failed -} -``` - -### Consuming a SurfaceBuffer - -``` -// Prerequisite: a consumer surface -class TestConsumerListener : public IBufferConsumerListener { -public: - void OnBufferAvailable() override { - sptr buffer; - int32_t flushFence; - SurfaceError ret = surface->AcquireBuffer(buffer, flushFence, timestamp, damage); - if (ret != SURFACE_ERROR_OK) { - // failed - } - // ... - ret = surface->ReleaseBuffer(buffer, -1); - if (ret != SURFACE_ERROR_OK) { - // failed - } - } -}; - -sptr listener = new TestConsumerListener(); -SurfaceError ret = surface->RegisterConsumerListener(listener); -if (ret != SURFACE_ERROR_OK) { - // failed -} -``` - -### Adding Custom Data to a SurfaceBuffer - -``` -sptr buffer; -SurfaceError ret = buffer->SetInt32(1, 3); -if (ret != SURFACE_ERROR_OK) { -// failed -} - -int32_t val; -ret = buffer->GetInt32(1, val); -if (ret != SURFACE_ERROR_OK) { -// failed -} -``` - -### Registering a Vsync Callback Listener - -1. Construct a **VsyncHelper** object using **handler**. - - ``` - auto runner = AppExecFwk::EventRunner::Create(true); - auto handler = std::make_shared(runner); - auto helper = new VsyncHelper(handler); - runner->Run(); - - struct FrameCallback cb = { - .timestamp_ = 0, - .userdata_ = nullptr, - .callback_ = [](int64_t timestamp, void* userdata) { - }, - }; - - VsyncError ret = helper->RequestFrameCallback(cb); - if (ret != VSYNC_ERROR_OK) { - // failed - } - ``` - -2. Use **Current** in **handler**. - - ``` - auto runner = AppExecFwk::EventRunner::Create(true); - auto handler = std::make_shared(runner); - handler->PostTask([]() { - auto helper = VsyncHelper::Current(); - struct FrameCallback cb = { - .timestamp_ = 0, - .userdata_ = nullptr, - .callback_ = [](int64_t timestamp, void* userdata) { - }, - }; - VsyncError ret = helper->RequestFrameCallback(cb); - if (ret != VSYNC_ERROR_OK) { - // failed - } - }); - - runner->Run(); - ``` - - -## Repositories Involved - -Graphics subsystem - -**graphic\_standard** - -ace\_ace\_engine - -aafwk\_L2 - -multimedia\_media\_standard - -multimedia\_camera\_standard - diff --git a/README_zh.md b/README_zh.md index 87d4811f..77182df5 100644 --- a/README_zh.md +++ b/README_zh.md @@ -3,359 +3,60 @@ - [简介](#简介) - [目录](#目录) - [约束](#约束) -- [编译构建](#编译构建) - [接口说明](#接口说明) -- [使用说明](#使用说明) - [相关仓](#相关仓) ## 简介 -**Graphic子系统** 提供了图形接口能力和窗口管理接口能力, +**窗口子系统** 提供窗口管理和Display管理的基础能力,是系统图形界面显示所需的基础子系统 其主要的结构如下图所示: -![Graphic子系统架构图](./figures/graphic.png) +![窗口子系统架构图](./figures/WindowManager.png) -- **Surface** +- **Window Manager Client** - 图形缓冲区管理接口,负责管理图形缓冲区和高效便捷的轮转缓冲区。 + 应用进程窗口管理接口层,提供窗口对对象抽象和窗口管理接口,对接原能力和UI框架。 -- **Vsync** +- **Display Manager Client** - 垂直同步信号管理接口,负责管理所有垂直同步信号注册和响应。 + 应用进程Display管理接口层,提供Display信息抽象和Display管理接口。 -- **WindowManager** +- **Window Manager Server** - 窗口管理器接口,负责创建和管理窗口。 + 窗口管理服务,提供窗口布局、Z序控制、窗口树结构、窗口拖拽、窗口快照等能力,并提供窗口布局和焦点窗口给多模输入 -- **WaylandProtocols** - - 窗口管理器和合成器的通信协议。 - -- **Compositor** - - 合成器,负责合成各个图层。 - -- **Renderer** - - 合成器的后端渲染模块。 - -- **Wayland protocols** - - Wayland 进程间通信协议 - -- **Shell** - - 提供多窗口能力 - -- **Input Manger** - - 多模输入模块,负责接收事件输入 +- **Display Manager Server** + Display管理服务,提供Display信息、屏幕截图、屏幕亮灭和亮度处理控制,并处理Display与Screen映射关系 ## 目录 ``` -foundation/graphic/standard/ -├── frameworks # 框架代码目录 -│ ├── bootanimation # 开机动画目录 -│   ├── surface # Surface代码 -│   ├── vsync # Vsync代码 -│   └── wm # WindowManager代码 +foundation/windowmanager/ +├── dm # Dislplay Manager Client实现代码 +├── dmserver # Dislplay Manager Service实现代码 ├── interfaces # 对外接口存放目录 │   ├── innerkits # native接口存放目录 │   └── kits # js/napi接口存放目录 -└── utils # 小部件存放目录 +├── resources # 框架使用资源文件存放目录 +├── sa_profile # 系统服务配置文件 +├── snapshot # 截屏命令行工具实现代码 +├── utils # 工具类存放目录 +├── wm # Window Manager Client实现代码 +├── wmserver # Window Manager Service实现代码 ``` ## 约束 - 语言版本 - C++11或以上 -## 编译构建 -可以依赖的接口有: -- graphic_standard:libwms_client -- graphic_standard:libsurface -- graphic_standard:libvsync_client - ## 接口说明 -### WindowManager - -| 接口名 | 职责 | -|-----------------|-----------------------------| -| GetInstance | 获取WindowManager的单例指针 | -| GetMaxWidth | 获取当前屏幕宽度 | -| GetMaxHeight | 获取当前屏幕高度 | -| CreateWindow | 创建一个标准窗口 | -| CreateSubWindow | 创建一个子窗口 | -| StartShotScreen | 截屏操作 | -| StartShotWindow | 截取窗口操作 | -| SwitchTop | 将指定窗口调整至最上层显示 | - -### Window -| 接口名 | 职责 | -|-----------------------------|------------------------------| -| Show | 显示当前窗口 | -| Hide | 隐藏当前窗口 | -| Move | 移动当前窗口至指定位置 | -| SwitchTop | 将当前窗口调整到最上层显示 | -| ChangeWindowType | 更改当前窗口类型 | -| ReSize | 调整当前窗口至指定大小 | -| Rotate | 旋转当前窗口 | -| RegistPointerButtonCb | 注册鼠标Button事件回调 | -| RegistPointerEnterCb | 注册鼠标Enter事件回调 | -| RegistPointerLeaveCb | 注册鼠标Leave事件回调 | -| RegistPointerMotionCb | 注册鼠标Motion事件回调 | -| RegistPointerAxisDiscreteCb | 注册鼠标AxisDiscrete事件回调 | -| RegistPointerAxisSourceCb | 注册鼠标AxisSource事件回调 | -| RegistPointerAxisStopCb | 注册鼠标AxisStop事件回调 | -| RegistPointerAxisCb | 注册鼠标Axis事件回调 | -| RegistTouchUpCb | 注册TouchUp事件回调 | -| RegistTouchDownCb | 注册TouchDown事件回调 | -| RegistTouchEmotionCb | 注册TouchEmotion事件回调 | -| RegistTouchFrameCb | 注册TouchFrame事件回调 | -| RegistTouchCancelCb | 注册TouchCancel事件回调 | -| RegistTouchShapeCb | 注册TouchShape事件回调 | -| RegistTouchOrientationCb | 注册TouchOrientation事件回调 | -| RegistKeyboardKeyCb | 注册键盘Key事件回调 | -| RegistKeyboardKeyMapCb | 注册键盘KeyMap事件回调 | -| RegistKeyboardLeaveCb | 注册键盘Leave事件回调 | -| RegistKeyboardEnterCb | 注册键盘Enter事件回调 | -| RegistKeyboardRepeatInfoCb | 注册键盘RepeatInfo事件回调 | - -### SubWindow -| 接口名 | 职责 | -|------------------|--------------------| -| Move | 移动当前子窗口 | -| SetSubWindowSize | 调整当前子窗口位置 | - -### Surface -| 接口名 | 职责 | -|----------------------------|-------------------------------------------------------------------| -| CreateSurfaceAsConsumer | Buffer的消费者来使用该函数创建一个Surface | -| CreateSurfaceAsProducer | Buffer的生产者使用该函数创建一个Surface,只能使用与生产相关的接口 | -| GetProducer | 获得一个Surface内部的IBufferProducer对象 | -| RequestBuffer | 请求一个待生产的SurfaceBuffer对象 | -| CancelBuffer | 取消、归还一个待生产的SurfaceBuffer对象 | -| FlushBuffer | 归还一个生产好的SurfaceBuffer对象并携带一些信息 | -| AcquireBuffer | 请求一个待消费的SurfaceBuffer对象 | -| ReleaseBuffer | 归还一个已消费的SurfaceBuffer对象 | -| GetQueueSize | 获得当前同时能并存buffer的数量 | -| SetQueueSize | 设置当前同时能并存buffer的数量 | -| SetDefaultWidthAndHeight | 设置默认宽和高 | -| GetDefaultWidth | 获得默认宽度 | -| GetDefaultHeight | 获得默认高度 | -| SetUserData | 存贮字符串数据,不随着IPC传递 | -| GetUserData | 取出字符串数据 | -| RegisterConsumerListener | 注册一个消费监听器,监听Buffer的Flush事件 | -| UnregisterConsumerListener | 取消监听 | - -### SurfaceBuffer -| 接口名 | 职责 | -|-----------------|-------------------------------------| -| GetBufferHandle | 获得SurfaceBuffer的BufferHandle指针 | -| GetWidth | 获得SurfaceBuffer的宽度 | -| GetHeight | 获得SurfaceBuffer的高度 | -| GetFormat | 获得SurfaceBuffer的颜色格式 | -| GetUsage | 获得SurfaceBuffer的用途 | -| GetPhyAddr | 获得SurfaceBuffer的物理地址 | -| GetKey | 获得SurfaceBuffer的key | -| GetVirAddr | 获得SurfaceBuffer的虚拟地址 | -| GetSize | 获得SurfaceBuffer的文件句柄 | -| SetInt32 | 获得SurfaceBuffer的缓冲区大小 | -| GetInt32 | 设置SurfaceBuffer的32位整数 | -| SetInt64 | 获得SurfaceBuffer的32位整数 | -| GetInt64 | 设置SurfaceBuffer的64位整数 | - -### VsyncHelper -| 接口名 | 职责 | -|----------------------|-----------------------------------| -| Current | 获取当前runner对应的VsyncHelper | -| VsyncHelper | 用EventHandler对象构造VsyncHelper | -| RequestFrameCallback | 注册一个帧回调 | - -## 使用说明 - -### 具名服务-传递一个生产型Surface - -#### 注册 -```cpp -// 拿到一个消费型Surface -sptr surface = Surface::CreateSurfaceAsConsumer(); - -// 拿出里面的生产者对象 -sptr producer = surface->GetProducer(); - -// 注册服务 -auto sm = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); -sm->AddSystemAbility(IPC_SA_ID, producer->AsObject()); -``` - -#### 客户端获得生产型Surface -```cpp -// 获得远程对象 -auto sm = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); -sptr robj = sm->GetSystemAbility(IPC_SA_ID); - -// 构造Surface -sptr bp = iface_cast(robj); -sptr surface = Surface::CreateSurfaceAsProducer(bp); -``` - -### 匿名服务-传递一个生产型Surface -场景: 在一次IPC过程中 - -#### 发送 -```cpp -// 拿到一个消费型Surface -sptr surface = CreateSurfaceAsConsumer(); - -// 拿出里面的生产者对象 -sptr producer = surface->GetProducer(); - -// 返回给客户端 -parcel.WriteRemoteObject(producer); -``` - -#### 接受并获得生产型Surface -```cpp -// 获得远程对象 -sptr remoteObject = parcel.ReadRemoteObject(); - -// 构造Surface -sptr bp = iface_cast(robj); -sptr surface = Surface::CreateSurfaceAsProducer(bp); -``` - -### 生产一个SurfaceBuffer -条件: 一个生产型Surface - -```cpp -BufferRequestConfig requestConfig = { - .width = 1920, // 屏幕宽度 - .height = 1080, // 屏幕高度 - .strideAlignment = 8, // stride对齐字节 - .format = PIXEL_FMT_RGBA_8888, // 颜色格式 - .usage = HBM_USE_CPU_READ | HBM_USE_CPU_WRITE | HBM_USE_MEM_DMA, // 用法 - .timeout = 0, // 时延 -}; - -sptr buffer; -int32_t releaseFence; - -SurfaceError ret = surface->RequestBuffer(buffer, releaseFence, requestConfig); -if (ret != SURFACE_ERROR_OK) { - // failed -} - -BufferFlushConfig flushConfig = { - .damage = { // 重绘区域 - .x = 0, // 起点横坐标 - .y = 0, // 起点纵坐标 - .w = buffer->GetWidth(), // 区域宽度 - .h = buffer->GetHeight(), // 区域高度 - }, - .timestamp = 0 // 给消费者看的时间,0为使用当前时间 -}; - -ret = surface->FlushBuffer(buffer, -1, flushConfig); -if (ret != SURFACE_ERROR_OK) { - // failed -} -``` - -### 消费一个SurfaceBuffer -条件: 一个消费型Surface - -```cpp -class TestConsumerListener : public IBufferConsumerListener { -public: - void OnBufferAvailable() override { - sptr buffer; - int32_t flushFence; - - SurfaceError ret = surface->AcquireBuffer(buffer, flushFence, timestamp, damage); - if (ret != SURFACE_ERROR_OK) { - // failed - } - - // ... - - ret = surface->ReleaseBuffer(buffer, -1); - if (ret != SURFACE_ERROR_OK) { - // failed - } - } -}; - -sptr listener = new TestConsumerListener(); -SurfaceError ret = surface->RegisterConsumerListener(listener); -if (ret != SURFACE_ERROR_OK) { - // failed -} -``` - -### 给SurfaceBuffer带上自定义数据 -```cpp -sptr buffer; -SurfaceError ret = buffer->SetInt32(1, 3); -if (ret != SURFACE_ERROR_OK) { - // failed -} - -int32_t val; -ret = buffer->GetInt32(1, val); -if (ret != SURFACE_ERROR_OK) { - // failed -} -``` - -### 注册一个Vsync回调事件 -#### 用handler构造VsyncHelper -```cpp -auto runner = AppExecFwk::EventRunner::Create(true); -auto handler = std::make_shared(runner); -auto helper = new VsyncHelper(handler); -runner->Run(); - -struct FrameCallback cb = { - .timestamp_ = 0, - .userdata_ = nullptr, - .callback_ = [](int64_t timestamp, void* userdata) { - }, -}; - -VsyncError ret = helper->RequestFrameCallback(cb); -if (ret != VSYNC_ERROR_OK) { - // failed -} -``` - -#### 在handler里用Current -```cpp -auto runner = AppExecFwk::EventRunner::Create(true); -auto handler = std::make_shared(runner); -handler->PostTask([]() { - auto helper = VsyncHelper::Current(); - struct FrameCallback cb = { - .timestamp_ = 0, - .userdata_ = nullptr, - .callback_ = [](int64_t timestamp, void* userdata) { - }, - }; - - VsyncError ret = helper->RequestFrameCallback(cb); - if (ret != VSYNC_ERROR_OK) { - // failed - } -}); - -runner->Run(); -``` +- [Window](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis/js-apis-window.md) +- [Display](https://gitee.com/openharmony/docs/blob/master/zh-cn/application-dev/reference/apis/js-apis-display.md) ## 相关仓 -- **graphic_standard** +- graphic_standard - ace_ace_engine - aafwk_standard -- multimedia_media_standard -- multimedia_camera_standard +- multimodalinput_input \ No newline at end of file diff --git a/bundle.json b/bundle.json index 404b2c76..8f5e3f60 100644 --- a/bundle.json +++ b/bundle.json @@ -17,6 +17,9 @@ "adapted_system_type": [ "standard" ], "rom": "8000KB", "ram": "8000KB", + "hisysevent_config": [ + "//foundation/windowmanager/hisysevent.yaml" + ], "deps": { "components": [ "ability_base", @@ -90,7 +93,8 @@ ], "test": [ "//foundation/windowmanager/wm:test", - "//foundation/windowmanager/dm:test" + "//foundation/windowmanager/dm:test", + "//foundation/windowmanager/wmserver:test" ] } } diff --git a/dm/BUILD.gn b/dm/BUILD.gn index a7a9caf5..b0ee459b 100644 --- a/dm/BUILD.gn +++ b/dm/BUILD.gn @@ -18,12 +18,6 @@ config("libdm_private_config") { "include", "../dmserver/include", ] - - if (defined(product_name) && - (product_name == "rk3566" || product_name == "rk3568" || - product_name == "Hi3516DV300" || product_name == "watchos")) { - defines = [ "PRODUCT_RK" ] - } } config("libdm_public_config") { @@ -40,7 +34,6 @@ ohos_shared_library("libdm") { "src/display.cpp", "src/display_manager.cpp", "src/display_manager_adapter.cpp", - "src/display_manager_agent.cpp", "src/screen.cpp", "src/screen_group.cpp", "src/screen_manager.cpp", diff --git a/dm/include/display_manager_adapter.h b/dm/include/display_manager_adapter.h index bc1e6377..ed76222e 100644 --- a/dm/include/display_manager_adapter.h +++ b/dm/include/display_manager_adapter.h @@ -28,35 +28,36 @@ #include "singleton_delegator.h" namespace OHOS::Rosen { -class DMSDeathRecipient : public IRemoteObject::DeathRecipient { +class BaseAdapter { public: - virtual void OnRemoteDied(const wptr& wptrDeath) override; -}; - -class DisplayManagerAdapter { -WM_DECLARE_SINGLE_INSTANCE(DisplayManagerAdapter); -public: - virtual DisplayId GetDefaultDisplayId(); - virtual sptr GetDisplayById(DisplayId displayId); - - virtual ScreenId CreateVirtualScreen(VirtualScreenOption option); - virtual DMError DestroyVirtualScreen(ScreenId screenId); - virtual DMError SetVirtualScreenSurface(ScreenId screenId, sptr surface); - virtual bool RequestRotation(ScreenId screenId, Rotation rotation); - virtual std::shared_ptr GetDisplaySnapshot(DisplayId displayId); - - // colorspace, gamut - virtual DMError GetScreenSupportedColorGamuts(ScreenId screenId, std::vector& colorGamuts); - virtual DMError GetScreenColorGamut(ScreenId screenId, ScreenColorGamut& colorGamut); - virtual DMError SetScreenColorGamut(ScreenId screenId, int32_t colorGamutIdx); - virtual DMError GetScreenGamutMap(ScreenId screenId, ScreenGamutMap& gamutMap); - virtual DMError SetScreenGamutMap(ScreenId screenId, ScreenGamutMap gamutMap); - virtual DMError SetScreenColorTransform(ScreenId screenId); - virtual bool RegisterDisplayManagerAgent(const sptr& displayManagerAgent, DisplayManagerAgentType type); virtual bool UnregisterDisplayManagerAgent(const sptr& displayManagerAgent, DisplayManagerAgentType type); + virtual void Clear(); +protected: + bool InitDMSProxy(); + std::recursive_mutex mutex_; + sptr displayManagerServiceProxy_ = nullptr; + sptr dmsDeath_ = nullptr; + bool isProxyValid_ { false }; +}; + +class DMSDeathRecipient : public IRemoteObject::DeathRecipient { +public: + DMSDeathRecipient(BaseAdapter& adapter); + virtual void OnRemoteDied(const wptr& wptrDeath) override; +private: + BaseAdapter& adapter_; +}; + +class DisplayManagerAdapter : public BaseAdapter { +WM_DECLARE_SINGLE_INSTANCE(DisplayManagerAdapter); +public: + virtual DisplayId GetDefaultDisplayId(); + virtual sptr GetDisplayInfoByScreenId(ScreenId screenId); + virtual std::vector GetAllDisplayIds(); + virtual std::shared_ptr GetDisplaySnapshot(DisplayId displayId); virtual bool WakeUpBegin(PowerStateChangeReason reason); virtual bool WakeUpEnd(); virtual bool SuspendBegin(PowerStateChangeReason reason); @@ -65,26 +66,35 @@ public: virtual bool SetDisplayState(DisplayState state); virtual DisplayState GetDisplayState(DisplayId displayId); virtual void NotifyDisplayEvent(DisplayEvent event); - virtual DMError MakeMirror(ScreenId mainScreenId, std::vector mirrorScreenId); - virtual void Clear(); - virtual sptr GetScreenById(ScreenId screenId); - virtual sptr GetScreenGroupById(ScreenId screenId); - virtual std::vector> GetAllScreens(); - virtual DMError MakeExpand(std::vector screenId, std::vector startPoint); - virtual bool SetScreenActiveMode(ScreenId screenId, uint32_t modeId); - + virtual sptr GetDisplayInfo(DisplayId displayId); private: - bool InitDMSProxyLocked(); - static inline SingletonDelegator delegator; +}; - std::recursive_mutex mutex_; - sptr displayManagerServiceProxy_ = nullptr; - sptr dmsDeath_ = nullptr; - std::map> displayMap_; - std::map> screenMap_; - std::map> screenGroupMap_; - DisplayId defaultDisplayId_; +class ScreenManagerAdapter : public BaseAdapter { +WM_DECLARE_SINGLE_INSTANCE(ScreenManagerAdapter); +public: + virtual ScreenId CreateVirtualScreen(VirtualScreenOption option); + virtual DMError DestroyVirtualScreen(ScreenId screenId); + virtual DMError SetVirtualScreenSurface(ScreenId screenId, sptr surface); + virtual bool SetOrientation(ScreenId screenId, Orientation orientation); + virtual sptr GetScreenGroupInfoById(ScreenId screenId); + virtual std::vector> GetAllScreenInfos(); + virtual ScreenId MakeMirror(ScreenId mainScreenId, std::vector mirrorScreenId); + virtual ScreenId MakeExpand(std::vector screenId, std::vector startPoint); + virtual void RemoveVirtualScreenFromGroup(std::vector); + virtual bool SetScreenActiveMode(ScreenId screenId, uint32_t modeId); + virtual sptr GetScreenInfo(ScreenId screenId); + + // colorspace, gamut + virtual DMError GetScreenSupportedColorGamuts(ScreenId screenId, std::vector& colorGamuts); + virtual DMError GetScreenColorGamut(ScreenId screenId, ScreenColorGamut& colorGamut); + virtual DMError SetScreenColorGamut(ScreenId screenId, int32_t colorGamutIdx); + virtual DMError GetScreenGamutMap(ScreenId screenId, ScreenGamutMap& gamutMap); + virtual DMError SetScreenGamutMap(ScreenId screenId, ScreenGamutMap gamutMap); + virtual DMError SetScreenColorTransform(ScreenId screenId); +private: + static inline SingletonDelegator delegator; }; } // namespace OHOS::Rosen #endif // FOUNDATION_DM_DISPLAY_MANAGER_ADAPTER_H diff --git a/dm/include/display_manager_agent_default.h b/dm/include/display_manager_agent_default.h index 20f0af6d..79c62ff2 100644 --- a/dm/include/display_manager_agent_default.h +++ b/dm/include/display_manager_agent_default.h @@ -29,7 +29,8 @@ public: void NotifyDisplayStateChanged(DisplayId id, DisplayState state) override {}; void OnScreenConnect(sptr) override {}; void OnScreenDisconnect(ScreenId) override {}; - void OnScreenChange(const std::vector>&, ScreenChangeEvent) override {}; + void OnScreenChange(const sptr&, ScreenChangeEvent) override {}; + void OnScreenGroupChange(const std::vector>&, ScreenGroupChangeEvent) override {}; void OnDisplayCreate(sptr) override {}; void OnDisplayDestroy(DisplayId) override {}; void OnDisplayChange(const sptr, DisplayChangeEvent) override {}; diff --git a/dm/include/zidl/display_manager_agent_interface.h b/dm/include/zidl/display_manager_agent_interface.h index 6090cbcc..452a066f 100644 --- a/dm/include/zidl/display_manager_agent_interface.h +++ b/dm/include/zidl/display_manager_agent_interface.h @@ -40,6 +40,7 @@ public: TRANS_ID_ON_SCREEN_CONNECT, TRANS_ID_ON_SCREEN_DISCONNECT, TRANS_ID_ON_SCREEN_CHANGED, + TRANS_ID_ON_SCREENGROUP_CHANGED, TRANS_ID_ON_DISPLAY_CONNECT, TRANS_ID_ON_DISPLAY_DISCONNECT, TRANS_ID_ON_DISPLAY_CHANGED, @@ -48,7 +49,8 @@ public: virtual void NotifyDisplayStateChanged(DisplayId id, DisplayState state) = 0; virtual void OnScreenConnect(sptr) = 0; virtual void OnScreenDisconnect(ScreenId) = 0; - virtual void OnScreenChange(const std::vector>&, ScreenChangeEvent) = 0; + virtual void OnScreenChange(const sptr&, ScreenChangeEvent) = 0; + virtual void OnScreenGroupChange(const std::vector>&, ScreenGroupChangeEvent) = 0; virtual void OnDisplayCreate(sptr) = 0; virtual void OnDisplayDestroy(DisplayId) = 0; virtual void OnDisplayChange(sptr, DisplayChangeEvent) = 0; diff --git a/dm/include/zidl/display_manager_agent_proxy.h b/dm/include/zidl/display_manager_agent_proxy.h index 8e72bdfb..b55c5926 100644 --- a/dm/include/zidl/display_manager_agent_proxy.h +++ b/dm/include/zidl/display_manager_agent_proxy.h @@ -30,7 +30,8 @@ public: virtual void NotifyDisplayStateChanged(DisplayId id, DisplayState state) override; virtual void OnScreenConnect(sptr) override; virtual void OnScreenDisconnect(ScreenId) override; - virtual void OnScreenChange(const std::vector>&, ScreenChangeEvent) override; + virtual void OnScreenChange(const sptr&, ScreenChangeEvent) override; + virtual void OnScreenGroupChange(const std::vector>&, ScreenGroupChangeEvent) override; virtual void OnDisplayCreate(sptr) override; virtual void OnDisplayDestroy(DisplayId) override; virtual void OnDisplayChange(sptr, DisplayChangeEvent) override; diff --git a/dm/src/display.cpp b/dm/src/display.cpp index 503d1d41..6f970bda 100644 --- a/dm/src/display.cpp +++ b/dm/src/display.cpp @@ -15,82 +15,99 @@ #include "display.h" #include "display_info.h" +#include "display_manager_adapter.h" +#include "window_manager_hilog.h" namespace OHOS::Rosen { +namespace { + constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_DISPLAY, "Display"}; + constexpr int32_t LARGE_SCREEN_WIDTH = 2560; +} class Display::Impl : public RefBase { -friend class Display; -private: - std::string name_; - DisplayId id_ { DISPLAY_ID_INVALD }; - int32_t width_ { 0 }; - int32_t height_ { 0 }; - uint32_t freshRate_ { 0 }; - ScreenId screenId_ {SCREEN_ID_INVALID}; +public: + Impl(const std::string& name, sptr info) + { + name_= name; + displayInfo_ = info; + } + ~Impl() = default; + DEFINE_VAR_FUNC_GET_SET(std::string, Name, name); + DEFINE_VAR_FUNC_GET_SET(sptr, DisplayInfo, displayInfo); }; -Display::Display(const std::string& name, DisplayInfo* info) - : pImpl_(new Impl()) +Display::Display(const std::string& name, sptr info) + : pImpl_(new Impl(name, info)) +{ +} + +Display::~Display() { - pImpl_->name_ = name; - pImpl_->id_ = info->id_; - pImpl_->width_ = info->width_; - pImpl_->height_ = info->height_; - pImpl_->freshRate_ = info->freshRate_; - pImpl_->screenId_ = info->screenId_; } DisplayId Display::GetId() const { - return pImpl_->id_; + return pImpl_->GetDisplayInfo()->GetDisplayId(); } int32_t Display::GetWidth() const { - return pImpl_->width_; + UpdateDisplayInfo(); + return pImpl_->GetDisplayInfo()->GetWidth(); } int32_t Display::GetHeight() const { - return pImpl_->height_; + UpdateDisplayInfo(); + return pImpl_->GetDisplayInfo()->GetHeight(); } uint32_t Display::GetFreshRate() const { - return pImpl_->freshRate_; + UpdateDisplayInfo(); + return pImpl_->GetDisplayInfo()->GetFreshRate(); } ScreenId Display::GetScreenId() const { - return pImpl_->screenId_; + UpdateDisplayInfo(); + return pImpl_->GetDisplayInfo()->GetScreenId(); } -void Display::SetWidth(int32_t width) +Rotation Display::GetRotation() const { - pImpl_->width_ = width; + UpdateDisplayInfo(); + return pImpl_->GetDisplayInfo()->GetRotation(); } -void Display::SetHeight(int32_t height) +Orientation Display::GetOrientation() const { - pImpl_->height_ = height; + UpdateDisplayInfo(); + return pImpl_->GetDisplayInfo()->GetOrientation(); } -void Display::SetFreshRate(uint32_t freshRate) +void Display::UpdateDisplayInfo(sptr displayInfo) const { - pImpl_->freshRate_ = freshRate; + if (displayInfo == nullptr) { + WLOGFE("displayInfo is invalid"); + return; + } + pImpl_->SetDisplayInfo(displayInfo); +} + +void Display::UpdateDisplayInfo() const +{ + auto displayInfo = SingletonContainer::Get().GetDisplayInfo(GetId()); + UpdateDisplayInfo(displayInfo); } float Display::GetVirtualPixelRatio() const { // TODO: Should get from DMS -#ifdef PRODUCT_RK - return 1.0f; -#else - return 2.0f; -#endif -} - -void Display::SetId(DisplayId id) -{ - pImpl_->id_ = id; + if ((pImpl_->GetDisplayInfo()->GetWidth() == LARGE_SCREEN_WIDTH) + || (pImpl_->GetDisplayInfo()->GetHeight() == LARGE_SCREEN_WIDTH)) { + return 2.0f; + } else { + return 1.0f; + } } } // namespace OHOS::Rosen \ No newline at end of file diff --git a/dm/src/display_manager.cpp b/dm/src/display_manager.cpp index 6933497f..b5aff3b1 100644 --- a/dm/src/display_manager.cpp +++ b/dm/src/display_manager.cpp @@ -19,7 +19,7 @@ #include #include "display_manager_adapter.h" -#include "display_manager_agent.h" +#include "display_manager_agent_default.h" #include "dm_common.h" #include "singleton_delegator.h" #include "window_manager_hilog.h" @@ -33,20 +33,38 @@ WM_IMPLEMENT_SINGLE_INSTANCE(DisplayManager) class DisplayManager::Impl : public RefBase { public: static inline SingletonDelegator delegator; - std::recursive_mutex mutex_; - std::vector> powerEventListeners_; - sptr powerEventListenerAgent_; - sptr displayStateAgent_; - DisplayStateCallback displayStateCallback_; - - std::vector> displayListeners_; - bool CheckRectValid(const Media::Rect& rect, int32_t oriHeight, int32_t oriWidth) const; bool CheckSizeValid(const Media::Size& size, int32_t oriHeight, int32_t oriWidth) const; + sptr GetDisplayById(DisplayId displayId); + bool RegisterDisplayListener(sptr listener); + bool UnregisterDisplayListener(sptr listener); + bool SetDisplayState(DisplayState state, DisplayStateCallback callback); + bool RegisterDisplayPowerEventListener(sptr listener); + bool UnregisterDisplayPowerEventListener(sptr listener); + sptr GetDisplayByScreenId(ScreenId screenId); +private: void ClearDisplayStateCallback(); + void NotifyDisplayPowerEvent(DisplayPowerEvent event, EventStatus status); + void NotifyDisplayStateChanged(DisplayId id, DisplayState state); + void NotifyDisplayChangedEvent(sptr info, DisplayChangeEvent event); + void NotifyDisplayCreate(sptr info); + void NotifyDisplayDestroy(DisplayId); + void NotifyDisplayChange(sptr displayInfo); + bool UpdateDisplayInfoLocked(sptr); + + class DisplayManagerListener; + sptr displayManagerListener_; + std::map> displayMap_; + DisplayStateCallback displayStateCallback_; + std::recursive_mutex mutex_; + std::vector> powerEventListeners_; + class DisplayManagerAgent; + sptr powerEventListenerAgent_; + sptr displayStateAgent_; + std::vector> displayListeners_; }; -class DisplayManager::DisplayManagerListener : public DisplayManagerAgentDefault { +class DisplayManager::Impl::DisplayManagerListener : public DisplayManagerAgentDefault { public: DisplayManagerListener(sptr impl) : pImpl_(impl) { @@ -54,7 +72,7 @@ public: void OnDisplayCreate(sptr displayInfo) override { - if (displayInfo == nullptr || displayInfo->id_ == DISPLAY_ID_INVALD) { + if (displayInfo == nullptr || displayInfo->GetDisplayId() == DISPLAY_ID_INVALD) { WLOGFE("OnDisplayCreate, displayInfo is invalid."); return; } @@ -62,8 +80,9 @@ public: WLOGFE("OnDisplayCreate, impl is nullptr."); return; } + pImpl_->NotifyDisplayCreate(displayInfo); for (auto listener : pImpl_->displayListeners_) { - listener->OnCreate(displayInfo->id_); + listener->OnCreate(displayInfo->GetDisplayId()); } }; @@ -77,14 +96,15 @@ public: WLOGFE("OnDisplayDestroy, impl is nullptr."); return; } + pImpl_->NotifyDisplayDestroy(displayId); for (auto listener : pImpl_->displayListeners_) { listener->OnDestroy(displayId); } }; - void OnDisplayChange(const sptr displayInfo, DisplayChangeEvent event) override + void OnDisplayChange(sptr displayInfo, DisplayChangeEvent event) override { - if (displayInfo == nullptr || displayInfo->id_ == DISPLAY_ID_INVALD) { + if (displayInfo == nullptr || displayInfo->GetDisplayId() == DISPLAY_ID_INVALD) { WLOGFE("OnDisplayChange, displayInfo is invalid."); return; } @@ -92,15 +112,36 @@ public: WLOGFE("OnDisplayChange, impl is nullptr."); return; } - WLOGD("OnDisplayChange. display %{public}" PRIu64", event %{public}u", displayInfo->id_, event); + WLOGD("OnDisplayChange. display %{public}" PRIu64", event %{public}u", displayInfo->GetDisplayId(), event); + pImpl_->NotifyDisplayChange(displayInfo); for (auto listener : pImpl_->displayListeners_) { - listener->OnChange(displayInfo->id_, event); + listener->OnChange(displayInfo->GetDisplayId()); } }; private: sptr pImpl_; }; +class DisplayManager::Impl::DisplayManagerAgent : public DisplayManagerAgentDefault { +public: + DisplayManagerAgent(sptr impl) : pImpl_(impl) + { + } + ~DisplayManagerAgent() = default; + + virtual void NotifyDisplayPowerEvent(DisplayPowerEvent event, EventStatus status) override + { + pImpl_->NotifyDisplayPowerEvent(event, status); + } + + virtual void NotifyDisplayStateChanged(DisplayId id, DisplayState state) override + { + pImpl_->NotifyDisplayStateChanged(id, state); + } +private: + sptr pImpl_; +}; + bool DisplayManager::Impl::CheckRectValid(const Media::Rect& rect, int32_t oriHeight, int32_t oriWidth) const { if (!((rect.left >= 0) and (rect.left < oriWidth) and (rect.top >= 0) and (rect.top < oriHeight))) { @@ -136,6 +177,7 @@ bool DisplayManager::Impl::CheckSizeValid(const Media::Size& size, int32_t oriHe void DisplayManager::Impl::ClearDisplayStateCallback() { + std::lock_guard lock(mutex_); displayStateCallback_ = nullptr; if (displayStateAgent_ != nullptr) { SingletonContainer::Get().UnregisterDisplayManagerAgent(displayStateAgent_, @@ -157,16 +199,56 @@ DisplayId DisplayManager::GetDefaultDisplayId() return SingletonContainer::Get().GetDefaultDisplayId(); } -const sptr DisplayManager::GetDisplayById(DisplayId displayId) +sptr DisplayManager::Impl::GetDisplayById(DisplayId displayId) { - sptr display = SingletonContainer::Get().GetDisplayById(displayId); - if (display == nullptr) { - WLOGFE("DisplayManager::GetDisplayById failed!\n"); + auto displayInfo = SingletonContainer::Get().GetDisplayInfo(displayId); + std::lock_guard lock(mutex_); + if (!UpdateDisplayInfoLocked(displayInfo)) { + displayMap_.erase(displayId); return nullptr; } + return displayMap_[displayId]; +} + +sptr DisplayManager::GetDisplayById(DisplayId displayId) +{ + return pImpl_->GetDisplayById(displayId); +} + +sptr DisplayManager::GetDisplayByScreen(ScreenId screenId) +{ + if (screenId == SCREEN_ID_INVALID) { + WLOGFE("screenId is invalid."); + return nullptr; + } + sptr display = pImpl_->GetDisplayByScreenId(screenId); + if (display == nullptr) { + WLOGFE("get display by screenId failed. screen %{public}" PRIu64"", screenId); + } return display; } +sptr DisplayManager::Impl::GetDisplayByScreenId(ScreenId screenId) +{ + sptr displayInfo = SingletonContainer::Get().GetDisplayInfoByScreenId(screenId); + if (displayInfo == nullptr) { + WLOGFE("get display by screenId: displayInfo is null"); + return nullptr; + } + DisplayId displayId = displayInfo->GetDisplayId(); + if (displayId == DISPLAY_ID_INVALD) { + WLOGFE("get display by screenId: invalid displayInfo"); + return nullptr; + } + + std::lock_guard lock(mutex_); + if (!UpdateDisplayInfoLocked(displayInfo)) { + displayMap_.erase(displayId); + return nullptr; + } + return displayMap_[displayId]; +} + std::shared_ptr DisplayManager::GetScreenshot(DisplayId displayId) { if (displayId == DISPLAY_ID_INVALD) { @@ -227,27 +309,24 @@ std::shared_ptr DisplayManager::GetScreenshot(DisplayId display return dstScreenshot; } -const sptr DisplayManager::GetDefaultDisplay() +sptr DisplayManager::GetDefaultDisplay() { return GetDisplayById(GetDefaultDisplayId()); } std::vector DisplayManager::GetAllDisplayIds() { - std::vector res; - res.push_back(GetDefaultDisplayId()); - // 获取所有displayIds - return res; + return SingletonContainer::Get().GetAllDisplayIds(); } -std::vector> DisplayManager::GetAllDisplays() +std::vector> DisplayManager::GetAllDisplays() { - std::vector> res; + std::vector> res; auto displayIds = GetAllDisplayIds(); for (auto displayId: displayIds) { const sptr display = GetDisplayById(displayId); if (display != nullptr) { - res.push_back(display); + res.emplace_back(display); } else { WLOGFE("DisplayManager::GetAllDisplays display %" PRIu64" nullptr!", displayId); } @@ -255,24 +334,48 @@ std::vector> DisplayManager::GetAllDisplays() return res; } +bool DisplayManager::Impl::RegisterDisplayListener(sptr listener) +{ + std::lock_guard lock(mutex_); + displayListeners_.push_back(listener); + bool ret = true; + if (displayManagerListener_ == nullptr) { + displayManagerListener_ = new DisplayManagerListener(this); + ret = SingletonContainer::Get().RegisterDisplayManagerAgent( + displayManagerListener_, + DisplayManagerAgentType::DISPLAY_EVENT_LISTENER); + if (!ret) { + WLOGFW("RegisterDisplayManagerAgent failed ! remove listener!"); + displayListeners_.pop_back(); + } + } + return ret; +} + bool DisplayManager::RegisterDisplayListener(sptr listener) { if (listener == nullptr) { WLOGFE("RegisterDisplayListener listener is nullptr."); return false; } - std::lock_guard lock(pImpl_->mutex_); - pImpl_->displayListeners_.push_back(listener); + return pImpl_->RegisterDisplayListener(listener); +} + +bool DisplayManager::Impl::UnregisterDisplayListener(sptr listener) +{ + std::lock_guard lock(mutex_); + auto iter = std::find(displayListeners_.begin(), displayListeners_.end(), listener); + if (iter == displayListeners_.end()) { + WLOGFE("could not find this listener"); + return false; + } + displayListeners_.erase(iter); bool ret = true; - if (displayManagerListener_ == nullptr) { - displayManagerListener_ = new DisplayManagerListener(pImpl_); - ret = SingletonContainer::Get().RegisterDisplayManagerAgent( + if (displayListeners_.empty() && displayManagerListener_ != nullptr) { + ret = SingletonContainer::Get().UnregisterDisplayManagerAgent( displayManagerListener_, DisplayManagerAgentType::DISPLAY_EVENT_LISTENER); - if (!ret) { - WLOGFW("RegisterDisplayManagerAgent failed ! remove listener!"); - pImpl_->displayListeners_.pop_back(); - } + displayManagerListener_ = nullptr; } return ret; } @@ -283,20 +386,25 @@ bool DisplayManager::UnregisterDisplayListener(sptr listener) WLOGFE("UnregisterDisplayListener listener is nullptr."); return false; } - std::lock_guard lock(pImpl_->mutex_); - auto iter = std::find(pImpl_->displayListeners_.begin(), pImpl_->displayListeners_.end(), listener); - if (iter == pImpl_->displayListeners_.end()) { - WLOGFE("could not find this listener"); - return false; - } - pImpl_->displayListeners_.erase(iter); + return pImpl_->UnregisterDisplayListener(listener); +} + +bool DisplayManager::Impl::RegisterDisplayPowerEventListener(sptr listener) +{ + std::lock_guard lock(mutex_); + powerEventListeners_.push_back(listener); bool ret = true; - if (pImpl_->displayListeners_.empty() && displayManagerListener_ != nullptr) { - ret = SingletonContainer::Get().UnregisterDisplayManagerAgent( - displayManagerListener_, - DisplayManagerAgentType::DISPLAY_EVENT_LISTENER); - displayManagerListener_ = nullptr; + if (powerEventListenerAgent_ == nullptr) { + powerEventListenerAgent_ = new DisplayManagerAgent(this); + ret = SingletonContainer::Get().RegisterDisplayManagerAgent( + powerEventListenerAgent_, + DisplayManagerAgentType::DISPLAY_POWER_EVENT_LISTENER); + if (!ret) { + WLOGFW("RegisterDisplayManagerAgent failed ! remove listener!"); + powerEventListeners_.pop_back(); + } } + WLOGFI("RegisterDisplayPowerEventListener end"); return ret; } @@ -306,20 +414,26 @@ bool DisplayManager::RegisterDisplayPowerEventListener(sptr lock(pImpl_->mutex_); - pImpl_->powerEventListeners_.push_back(listener); - bool ret = true; - if (pImpl_->powerEventListenerAgent_ == nullptr) { - pImpl_->powerEventListenerAgent_ = new DisplayManagerAgent(); - ret = SingletonContainer::Get().RegisterDisplayManagerAgent( - pImpl_->powerEventListenerAgent_, - DisplayManagerAgentType::DISPLAY_POWER_EVENT_LISTENER); - if (!ret) { - WLOGFW("RegisterDisplayManagerAgent failed ! remove listener!"); - pImpl_->powerEventListeners_.pop_back(); - } + return pImpl_->RegisterDisplayPowerEventListener(listener); +} + +bool DisplayManager::Impl::UnregisterDisplayPowerEventListener(sptr listener) +{ + std::lock_guard lock(mutex_); + auto iter = std::find(powerEventListeners_.begin(), powerEventListeners_.end(), listener); + if (iter == powerEventListeners_.end()) { + WLOGFE("could not find this listener"); + return false; } - WLOGFI("RegisterDisplayPowerEventListener end"); + powerEventListeners_.erase(iter); + bool ret = true; + if (powerEventListeners_.empty() && powerEventListenerAgent_ != nullptr) { + ret = SingletonContainer::Get().UnregisterDisplayManagerAgent( + powerEventListenerAgent_, + DisplayManagerAgentType::DISPLAY_POWER_EVENT_LISTENER); + powerEventListenerAgent_ = nullptr; + } + WLOGFI("UnregisterDisplayPowerEventListener end"); return ret; } @@ -329,54 +443,71 @@ bool DisplayManager::UnregisterDisplayPowerEventListener(sptr lock(pImpl_->mutex_); - auto iter = std::find(pImpl_->powerEventListeners_.begin(), pImpl_->powerEventListeners_.end(), listener); - if (iter == pImpl_->powerEventListeners_.end()) { - WLOGFE("could not find this listener"); - return false; - } - pImpl_->powerEventListeners_.erase(iter); - bool ret = true; - if (pImpl_->powerEventListeners_.empty() && pImpl_->powerEventListenerAgent_ != nullptr) { - ret = SingletonContainer::Get().UnregisterDisplayManagerAgent( - pImpl_->powerEventListenerAgent_, - DisplayManagerAgentType::DISPLAY_POWER_EVENT_LISTENER); - pImpl_->powerEventListenerAgent_ = nullptr; - } - WLOGFI("UnregisterDisplayPowerEventListener end"); - return ret; + return pImpl_->UnregisterDisplayPowerEventListener(listener); } -void DisplayManager::NotifyDisplayPowerEvent(DisplayPowerEvent event, EventStatus status) +void DisplayManager::Impl::NotifyDisplayPowerEvent(DisplayPowerEvent event, EventStatus status) { WLOGFI("NotifyDisplayPowerEvent event:%{public}u, status:%{public}u, size:%{public}zu", event, status, - pImpl_->powerEventListeners_.size()); - std::lock_guard lock(pImpl_->mutex_); - for (auto& listener : pImpl_->powerEventListeners_) { + powerEventListeners_.size()); + std::lock_guard lock(mutex_); + for (auto& listener : powerEventListeners_) { listener->OnDisplayPowerEvent(event, status); } } -void DisplayManager::NotifyDisplayStateChanged(DisplayId id, DisplayState state) +void DisplayManager::Impl::NotifyDisplayStateChanged(DisplayId id, DisplayState state) { WLOGFI("state:%{public}u", state); - std::lock_guard lock(pImpl_->mutex_); - if (pImpl_->displayStateCallback_) { - pImpl_->displayStateCallback_(state); - pImpl_->ClearDisplayStateCallback(); + std::lock_guard lock(mutex_); + if (displayStateCallback_) { + displayStateCallback_(state); + ClearDisplayStateCallback(); return; } WLOGFW("callback_ target is not set!"); } -void DisplayManager::NotifyDisplayChangedEvent(const sptr info, DisplayChangeEvent event) +void DisplayManager::Impl::NotifyDisplayCreate(sptr info) { - WLOGI("NotifyDisplayChangedEvent event:%{public}u, size:%{public}zu", event, pImpl_->displayListeners_.size()); - std::lock_guard lock(pImpl_->mutex_); - for (auto& listener : pImpl_->displayListeners_) { - listener->OnChange(info->id_, event); + std::lock_guard lock(mutex_); + UpdateDisplayInfoLocked(info); +} + +void DisplayManager::Impl::NotifyDisplayDestroy(DisplayId displayId) +{ + WLOGFI("displayId:%{public}" PRIu64".", displayId); + std::lock_guard lock(mutex_); + displayMap_.erase(displayId); +} + +void DisplayManager::Impl::NotifyDisplayChange(sptr displayInfo) +{ + std::lock_guard lock(mutex_); + UpdateDisplayInfoLocked(displayInfo); +} + +bool DisplayManager::Impl::UpdateDisplayInfoLocked(sptr displayInfo) +{ + if (displayInfo == nullptr) { + WLOGFE("displayInfo is null"); + return false; } + DisplayId displayId = displayInfo->GetDisplayId(); + WLOGFI("displayId:%{public}" PRIu64".", displayId); + if (displayId == DISPLAY_ID_INVALD) { + WLOGFE("displayId is invalid."); + return false; + } + auto iter = displayMap_.find(displayId); + if (iter != displayMap_.end() && iter->second != nullptr) { + WLOGFI("get screen in screen map"); + iter->second->UpdateDisplayInfo(displayInfo); + return true; + } + sptr display = new Display("", displayInfo); + displayMap_[displayId] = display; + return true; } bool DisplayManager::WakeUpBegin(PowerStateChangeReason reason) @@ -440,30 +571,37 @@ DisplayPowerState DisplayManager::GetScreenPower(uint64_t screenId) return res; } -bool DisplayManager::SetDisplayState(DisplayState state, DisplayStateCallback callback) +bool DisplayManager::Impl::SetDisplayState(DisplayState state, DisplayStateCallback callback) { WLOGFI("state:%{public}u", state); - std::lock_guard lock(pImpl_->mutex_); - if (pImpl_->displayStateCallback_ != nullptr || callback == nullptr) { - WLOGFI("previous callback not called or callback invalid"); - return false; - } - pImpl_->displayStateCallback_ = callback; bool ret = true; - if (pImpl_->displayStateAgent_ == nullptr) { - pImpl_->displayStateAgent_ = new DisplayManagerAgent(); - ret = SingletonContainer::Get().RegisterDisplayManagerAgent( - pImpl_->displayStateAgent_, - DisplayManagerAgentType::DISPLAY_STATE_LISTENER); - } + { + std::lock_guard lock(mutex_); + if (displayStateCallback_ != nullptr || callback == nullptr) { + WLOGFI("previous callback not called or callback invalid"); + return false; + } + displayStateCallback_ = callback; - ret &= SingletonContainer::Get().SetDisplayState(state); + if (displayStateAgent_ == nullptr) { + displayStateAgent_ = new DisplayManagerAgent(this); + ret = SingletonContainer::Get().RegisterDisplayManagerAgent( + displayStateAgent_, + DisplayManagerAgentType::DISPLAY_STATE_LISTENER); + } + } + ret = ret && SingletonContainer::Get().SetDisplayState(state); if (!ret) { - pImpl_->ClearDisplayStateCallback(); + ClearDisplayStateCallback(); } return ret; } +bool DisplayManager::SetDisplayState(DisplayState state, DisplayStateCallback callback) +{ + return pImpl_->SetDisplayState(state, callback); +} + DisplayState DisplayManager::GetDisplayState(DisplayId displayId) { return SingletonContainer::Get().GetDisplayState(displayId); @@ -479,7 +617,7 @@ bool DisplayManager::SetScreenBrightness(uint64_t screenId, uint32_t level) uint32_t DisplayManager::GetScreenBrightness(uint64_t screenId) const { uint32_t level = static_cast(RSInterfaces::GetInstance().GetScreenBacklight(screenId)); - WLOGFI("screenId:%{public}" PRIu64", level:%{public}u,", screenId, level); + WLOGFD("screenId:%{public}" PRIu64", level:%{public}u,", screenId, level); return level; } diff --git a/dm/src/display_manager_adapter.cpp b/dm/src/display_manager_adapter.cpp index 9e2151b2..b2d5f2df 100644 --- a/dm/src/display_manager_adapter.cpp +++ b/dm/src/display_manager_adapter.cpp @@ -26,210 +26,146 @@ namespace { constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_DISPLAY, "DisplayManagerAdapter"}; } WM_IMPLEMENT_SINGLE_INSTANCE(DisplayManagerAdapter) +WM_IMPLEMENT_SINGLE_INSTANCE(ScreenManagerAdapter) DisplayId DisplayManagerAdapter::GetDefaultDisplayId() { - std::lock_guard lock(mutex_); - - if (defaultDisplayId_ != DISPLAY_ID_INVALD) { - return defaultDisplayId_; - } - - if (!InitDMSProxyLocked()) { - WLOGFE("displayManagerAdapter::GetDefaultDisplayId: InitDMSProxyLocked failed!"); + if (!InitDMSProxy()) { + WLOGFE("displayManagerAdapter::GetDefaultDisplayId: InitDMSProxy failed!"); return DISPLAY_ID_INVALD; } - defaultDisplayId_ = displayManagerServiceProxy_->GetDefaultDisplayId(); - return defaultDisplayId_; + return displayManagerServiceProxy_->GetDefaultDisplayId(); } -sptr DisplayManagerAdapter::GetDisplayById(DisplayId displayId) +sptr DisplayManagerAdapter::GetDisplayInfoByScreenId(ScreenId screenId) { - std::lock_guard lock(mutex_); - - if (!InitDMSProxyLocked()) { - WLOGFE("GetDisplayById: InitDMSProxyLocked failed!"); + if (!InitDMSProxy()) { + WLOGFE("get display by screenId: init dms proxy failed!"); return nullptr; } - - auto iter = displayMap_.find(displayId); - if (iter != displayMap_.end()) { - // Update display in map - // should be updated automatically - DisplayInfo displayInfo = displayManagerServiceProxy_->GetDisplayInfoById(displayId); - if (displayInfo.id_ == DISPLAY_ID_INVALD) { - WLOGFE("GetDisplayById: Get invalid displayInfo!"); - return nullptr; - } - sptr display = iter->second; - if (displayInfo.width_ != display->GetWidth()) { - display->SetWidth(displayInfo.width_); - WLOGFI("GetDisplayById: set new width %{public}d", display->GetWidth()); - } - if (displayInfo.height_ != display->GetHeight()) { - display->SetHeight(displayInfo.height_); - WLOGFI("GetDisplayById: set new height %{public}d", display->GetHeight()); - } - if (displayInfo.freshRate_ != display->GetFreshRate()) { - display->SetFreshRate(displayInfo.freshRate_); - WLOGFI("GetDisplayById: set new freshRate %{public}ud", display->GetFreshRate()); - } - return iter->second; - } - DisplayInfo displayInfo = displayManagerServiceProxy_->GetDisplayInfoById(displayId); - sptr display = new Display("", &displayInfo); - if (display->GetId() != DISPLAY_ID_INVALD) { - displayMap_[display->GetId()] = display; - } - return display; -} - -bool DisplayManagerAdapter::RequestRotation(ScreenId screenId, Rotation rotation) -{ - std::lock_guard lock(mutex_); - if (!InitDMSProxyLocked()) { - WLOGFE("fail to request rotation: InitDMSProxyLocked failed!"); - return false; - } - - return displayManagerServiceProxy_->RequestRotation(screenId, rotation); + return displayManagerServiceProxy_->GetDisplayInfoByScreen(screenId); } std::shared_ptr DisplayManagerAdapter::GetDisplaySnapshot(DisplayId displayId) { - std::lock_guard lock(mutex_); - - if (!InitDMSProxyLocked()) { - WLOGFE("displayManagerAdapter::GetDisplaySnapshot: InitDMSProxyLocked failed!"); + if (!InitDMSProxy()) { + WLOGFE("GetDisplaySnapshot: init dms proxy failed!"); return nullptr; } - std::shared_ptr dispalySnapshot = displayManagerServiceProxy_->GetDispalySnapshot(displayId); - - return dispalySnapshot; + return displayManagerServiceProxy_->GetDisplaySnapshot(displayId); } -DMError DisplayManagerAdapter::GetScreenSupportedColorGamuts(ScreenId screenId, +DMError ScreenManagerAdapter::GetScreenSupportedColorGamuts(ScreenId screenId, std::vector& colorGamuts) { - std::lock_guard lock(mutex_); - - if (!InitDMSProxyLocked()) { - WLOGFE("displayManagerAdapter::GetScreenSupportedColorGamuts: InitDMSProxyLocked failed!"); + if (!InitDMSProxy()) { + WLOGFE("displayManagerAdapter::GetScreenSupportedColorGamuts: InitDMSProxy failed!"); return DMError::DM_ERROR_INIT_DMS_PROXY_LOCKED; } - DMError ret = displayManagerServiceProxy_->GetScreenSupportedColorGamuts(screenId, colorGamuts); - return ret; + return displayManagerServiceProxy_->GetScreenSupportedColorGamuts(screenId, colorGamuts); } -DMError DisplayManagerAdapter::GetScreenColorGamut(ScreenId screenId, ScreenColorGamut& colorGamut) +DMError ScreenManagerAdapter::GetScreenColorGamut(ScreenId screenId, ScreenColorGamut& colorGamut) { - std::lock_guard lock(mutex_); - - if (!InitDMSProxyLocked()) { - WLOGFE("displayManagerAdapter::GetScreenColorGamut: InitDMSProxyLocked failed!"); + if (!InitDMSProxy()) { + WLOGFE("displayManagerAdapter::GetScreenColorGamut: InitDMSProxy failed!"); return DMError::DM_ERROR_INIT_DMS_PROXY_LOCKED; } - DMError ret = displayManagerServiceProxy_->GetScreenColorGamut(screenId, colorGamut); - return ret; + return displayManagerServiceProxy_->GetScreenColorGamut(screenId, colorGamut); } -DMError DisplayManagerAdapter::SetScreenColorGamut(ScreenId screenId, int32_t colorGamutIdx) +DMError ScreenManagerAdapter::SetScreenColorGamut(ScreenId screenId, int32_t colorGamutIdx) { - std::lock_guard lock(mutex_); - - if (!InitDMSProxyLocked()) { - WLOGFE("displayManagerAdapter::SetScreenColorGamut: InitDMSProxyLocked failed!"); + if (!InitDMSProxy()) { + WLOGFE("displayManagerAdapter::SetScreenColorGamut: InitDMSProxy failed!"); return DMError::DM_ERROR_INIT_DMS_PROXY_LOCKED; } - DMError ret = displayManagerServiceProxy_->SetScreenColorGamut(screenId, colorGamutIdx); - return ret; + return displayManagerServiceProxy_->SetScreenColorGamut(screenId, colorGamutIdx); } -DMError DisplayManagerAdapter::GetScreenGamutMap(ScreenId screenId, ScreenGamutMap& gamutMap) +DMError ScreenManagerAdapter::GetScreenGamutMap(ScreenId screenId, ScreenGamutMap& gamutMap) { - std::lock_guard lock(mutex_); - - if (!InitDMSProxyLocked()) { - WLOGFE("displayManagerAdapter::GetScreenGamutMap: InitDMSProxyLocked failed!"); + if (!InitDMSProxy()) { + WLOGFE("displayManagerAdapter::GetScreenGamutMap: InitDMSProxy failed!"); return DMError::DM_ERROR_INIT_DMS_PROXY_LOCKED; } - DMError ret = displayManagerServiceProxy_->GetScreenGamutMap(screenId, gamutMap); - return ret; + return displayManagerServiceProxy_->GetScreenGamutMap(screenId, gamutMap); } -DMError DisplayManagerAdapter::SetScreenGamutMap(ScreenId screenId, ScreenGamutMap gamutMap) +DMError ScreenManagerAdapter::SetScreenGamutMap(ScreenId screenId, ScreenGamutMap gamutMap) { - std::lock_guard lock(mutex_); - - if (!InitDMSProxyLocked()) { - WLOGFE("displayManagerAdapter::SetScreenGamutMap: InitDMSProxyLocked failed!"); + if (!InitDMSProxy()) { + WLOGFE("displayManagerAdapter::SetScreenGamutMap: InitDMSProxy failed!"); return DMError::DM_ERROR_INIT_DMS_PROXY_LOCKED; } - DMError ret = displayManagerServiceProxy_->SetScreenGamutMap(screenId, gamutMap); - return ret; + return displayManagerServiceProxy_->SetScreenGamutMap(screenId, gamutMap); } -DMError DisplayManagerAdapter::SetScreenColorTransform(ScreenId screenId) +DMError ScreenManagerAdapter::SetScreenColorTransform(ScreenId screenId) { - std::lock_guard lock(mutex_); - - if (!InitDMSProxyLocked()) { - WLOGFE("displayManagerAdapter::SetScreenColorTransform: InitDMSProxyLocked failed!"); + if (!InitDMSProxy()) { + WLOGFE("displayManagerAdapter::SetScreenColorTransform: InitDMSProxy failed!"); return DMError::DM_ERROR_INIT_DMS_PROXY_LOCKED; } - DMError ret = displayManagerServiceProxy_->SetScreenColorTransform(screenId); - return ret; + return displayManagerServiceProxy_->SetScreenColorTransform(screenId); } -ScreenId DisplayManagerAdapter::CreateVirtualScreen(VirtualScreenOption option) +ScreenId ScreenManagerAdapter::CreateVirtualScreen(VirtualScreenOption option) { - if (!InitDMSProxyLocked()) { + if (!InitDMSProxy()) { return SCREEN_ID_INVALID; } WLOGFI("DisplayManagerAdapter::CreateVirtualScreen"); return displayManagerServiceProxy_->CreateVirtualScreen(option); } -DMError DisplayManagerAdapter::DestroyVirtualScreen(ScreenId screenId) +DMError ScreenManagerAdapter::DestroyVirtualScreen(ScreenId screenId) { - if (!InitDMSProxyLocked()) { + if (!InitDMSProxy()) { return DMError::DM_ERROR_INIT_DMS_PROXY_LOCKED; } WLOGFI("DisplayManagerAdapter::DestroyVirtualScreen"); return displayManagerServiceProxy_->DestroyVirtualScreen(screenId); } -DMError DisplayManagerAdapter::SetVirtualScreenSurface(ScreenId screenId, sptr surface) +DMError ScreenManagerAdapter::SetVirtualScreenSurface(ScreenId screenId, sptr surface) { - if (!InitDMSProxyLocked()) { + if (!InitDMSProxy()) { return DMError::DM_ERROR_INIT_DMS_PROXY_LOCKED; } WLOGFI("DisplayManagerAdapter::SetVirtualScreenSurface"); return displayManagerServiceProxy_->SetVirtualScreenSurface(screenId, surface); } -bool DisplayManagerAdapter::RegisterDisplayManagerAgent(const sptr& displayManagerAgent, +bool ScreenManagerAdapter::SetOrientation(ScreenId screenId, Orientation orientation) +{ + if (!InitDMSProxy()) { + WLOGFE("fail to set orientation: InitDMSProxy failed!"); + return false; + } + return displayManagerServiceProxy_->SetOrientation(screenId, orientation); +} + +bool BaseAdapter::RegisterDisplayManagerAgent(const sptr& displayManagerAgent, DisplayManagerAgentType type) { - std::lock_guard lock(mutex_); - if (!InitDMSProxyLocked()) { + if (!InitDMSProxy()) { return false; } return displayManagerServiceProxy_->RegisterDisplayManagerAgent(displayManagerAgent, type); } -bool DisplayManagerAdapter::UnregisterDisplayManagerAgent(const sptr& displayManagerAgent, +bool BaseAdapter::UnregisterDisplayManagerAgent(const sptr& displayManagerAgent, DisplayManagerAgentType type) { - std::lock_guard lock(mutex_); - if (!InitDMSProxyLocked()) { + if (!InitDMSProxy()) { return false; } return displayManagerServiceProxy_->UnregisterDisplayManagerAgent(displayManagerAgent, type); @@ -237,8 +173,7 @@ bool DisplayManagerAdapter::UnregisterDisplayManagerAgent(const sptr lock(mutex_); - if (!InitDMSProxyLocked()) { + if (!InitDMSProxy()) { return false; } return displayManagerServiceProxy_->WakeUpBegin(reason); @@ -246,8 +181,7 @@ bool DisplayManagerAdapter::WakeUpBegin(PowerStateChangeReason reason) bool DisplayManagerAdapter::WakeUpEnd() { - std::lock_guard lock(mutex_); - if (!InitDMSProxyLocked()) { + if (!InitDMSProxy()) { return false; } return displayManagerServiceProxy_->WakeUpEnd(); @@ -255,8 +189,7 @@ bool DisplayManagerAdapter::WakeUpEnd() bool DisplayManagerAdapter::SuspendBegin(PowerStateChangeReason reason) { - std::lock_guard lock(mutex_); - if (!InitDMSProxyLocked()) { + if (!InitDMSProxy()) { return false; } return displayManagerServiceProxy_->SuspendBegin(reason); @@ -264,8 +197,7 @@ bool DisplayManagerAdapter::SuspendBegin(PowerStateChangeReason reason) bool DisplayManagerAdapter::SuspendEnd() { - std::lock_guard lock(mutex_); - if (!InitDMSProxyLocked()) { + if (!InitDMSProxy()) { return false; } return displayManagerServiceProxy_->SuspendEnd(); @@ -273,8 +205,7 @@ bool DisplayManagerAdapter::SuspendEnd() bool DisplayManagerAdapter::SetScreenPowerForAll(DisplayPowerState state, PowerStateChangeReason reason) { - std::lock_guard lock(mutex_); - if (!InitDMSProxyLocked()) { + if (!InitDMSProxy()) { return false; } return displayManagerServiceProxy_->SetScreenPowerForAll(state, reason); @@ -283,8 +214,7 @@ bool DisplayManagerAdapter::SetScreenPowerForAll(DisplayPowerState state, PowerS bool DisplayManagerAdapter::SetDisplayState(DisplayState state) { - std::lock_guard lock(mutex_); - if (!InitDMSProxyLocked()) { + if (!InitDMSProxy()) { return false; } return displayManagerServiceProxy_->SetDisplayState(state); @@ -292,8 +222,7 @@ bool DisplayManagerAdapter::SetDisplayState(DisplayState state) DisplayState DisplayManagerAdapter::GetDisplayState(DisplayId displayId) { - std::lock_guard lock(mutex_); - if (!InitDMSProxyLocked()) { + if (!InitDMSProxy()) { return DisplayState::UNKNOWN; } return displayManagerServiceProxy_->GetDisplayState(displayId); @@ -301,16 +230,16 @@ DisplayState DisplayManagerAdapter::GetDisplayState(DisplayId displayId) void DisplayManagerAdapter::NotifyDisplayEvent(DisplayEvent event) { - std::lock_guard lock(mutex_); - if (!InitDMSProxyLocked()) { + if (!InitDMSProxy()) { return; } displayManagerServiceProxy_->NotifyDisplayEvent(event); } -bool DisplayManagerAdapter::InitDMSProxyLocked() +bool BaseAdapter::InitDMSProxy() { - if (!displayManagerServiceProxy_) { + std::lock_guard lock(mutex_); + if (!isProxyValid_) { sptr systemAbilityManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); if (!systemAbilityManager) { @@ -331,7 +260,7 @@ bool DisplayManagerAdapter::InitDMSProxyLocked() return false; } - dmsDeath_ = new DMSDeathRecipient(); + dmsDeath_ = new DMSDeathRecipient(*this); if (!dmsDeath_) { WLOGFE("Failed to create death Recipient ptr DMSDeathRecipient"); return false; @@ -340,10 +269,15 @@ bool DisplayManagerAdapter::InitDMSProxyLocked() WLOGFE("Failed to add death recipient"); return false; } + isProxyValid_ = true; } return true; } +DMSDeathRecipient::DMSDeathRecipient(BaseAdapter& adapter) : adapter_(adapter) +{ +} + void DMSDeathRecipient::OnRemoteDied(const wptr& wptrDeath) { if (wptrDeath == nullptr) { @@ -356,114 +290,105 @@ void DMSDeathRecipient::OnRemoteDied(const wptr& wptrDeath) WLOGFE("object is null"); return; } - SingletonContainer::Get().Clear(); + adapter_.Clear(); return; } -void DisplayManagerAdapter::Clear() +void BaseAdapter::Clear() { - std::lock_guard lock(mutex_); if ((displayManagerServiceProxy_ != nullptr) && (displayManagerServiceProxy_->AsObject() != nullptr)) { displayManagerServiceProxy_->AsObject()->RemoveDeathRecipient(dmsDeath_); } - displayManagerServiceProxy_ = nullptr; + std::lock_guard lock(mutex_); + isProxyValid_ = false; } -DMError DisplayManagerAdapter::MakeMirror(ScreenId mainScreenId, std::vector mirrorScreenId) +ScreenId ScreenManagerAdapter::MakeMirror(ScreenId mainScreenId, std::vector mirrorScreenId) { - std::lock_guard lock(mutex_); - if (!InitDMSProxyLocked()) { - return DMError::DM_ERROR_INIT_DMS_PROXY_LOCKED; + if (!InitDMSProxy()) { + return SCREEN_ID_INVALID; } return displayManagerServiceProxy_->MakeMirror(mainScreenId, mirrorScreenId); } -sptr DisplayManagerAdapter::GetScreenById(ScreenId screenId) +sptr ScreenManagerAdapter::GetScreenInfo(ScreenId screenId) { - std::lock_guard lock(mutex_); if (screenId == SCREEN_ID_INVALID) { WLOGFE("screen id is invalid"); return nullptr; } - auto iter = screenMap_.find(screenId); - if (iter != screenMap_.end()) { - WLOGFI("get screen in screen map"); - return iter->second; - } - - if (!InitDMSProxyLocked()) { - WLOGFE("InitDMSProxyLocked failed!"); + if (!InitDMSProxy()) { + WLOGFE("InitDMSProxy failed!"); return nullptr; } sptr screenInfo = displayManagerServiceProxy_->GetScreenInfoById(screenId); - if (screenInfo == nullptr) { - WLOGFE("screenInfo is null"); - return nullptr; - } - sptr screen = new Screen(screenInfo.GetRefPtr()); - screenMap_.insert(std::make_pair(screenId, screen)); - return screen; + return screenInfo; } -sptr DisplayManagerAdapter::GetScreenGroupById(ScreenId screenId) +std::vector DisplayManagerAdapter::GetAllDisplayIds() +{ + if (!InitDMSProxy()) { + WLOGFE("InitDMSProxyLocked failed!"); + return {}; + } + return displayManagerServiceProxy_->GetAllDisplayIds(); +} + +sptr DisplayManagerAdapter::GetDisplayInfo(DisplayId displayId) +{ + if (displayId == DISPLAY_ID_INVALD) { + WLOGFE("screen id is invalid"); + return nullptr; + } + if (!InitDMSProxy()) { + WLOGFE("InitDMSProxy failed!"); + return nullptr; + } + return displayManagerServiceProxy_->GetDisplayInfoById(displayId); +} + +sptr ScreenManagerAdapter::GetScreenGroupInfoById(ScreenId screenId) { - std::lock_guard lock(mutex_); if (screenId == SCREEN_ID_INVALID) { WLOGFE("screenGroup id is invalid"); return nullptr; } - auto iter = screenGroupMap_.find(screenId); - if (iter != screenGroupMap_.end()) { - WLOGFI("get screenGroup in screenGroup map"); - return iter->second; - } - - if (!InitDMSProxyLocked()) { - WLOGFE("InitDMSProxyLocked failed!"); + if (!InitDMSProxy()) { + WLOGFE("InitDMSProxy failed!"); return nullptr; } - sptr screenGroupInfo = displayManagerServiceProxy_->GetScreenGroupInfoById(screenId); - if (screenGroupInfo == nullptr) { - WLOGFE("screenGroupInfo is null"); - return nullptr; - } - sptr screenGroup = new ScreenGroup(screenGroupInfo.GetRefPtr()); - screenGroupMap_.insert(std::make_pair(screenId, screenGroup)); - return screenGroup; + return displayManagerServiceProxy_->GetScreenGroupInfoById(screenId); } -std::vector> DisplayManagerAdapter::GetAllScreens() +std::vector> ScreenManagerAdapter::GetAllScreenInfos() { - std::lock_guard lock(mutex_); - std::vector> screens; - if (!InitDMSProxyLocked()) { - WLOGFE("InitDMSProxyLocked failed!"); - return screens; + if (!InitDMSProxy()) { + WLOGFE("InitDMSProxy failed!"); + std::vector> result; + return result; } - std::vector> screenInfos = displayManagerServiceProxy_->GetAllScreenInfos(); - for (auto info: screenInfos) { - if (info == nullptr) { - WLOGFE("screenInfo is null"); - continue; - } - screens.emplace_back(new Screen(info.GetRefPtr())); - } - return screens; + return displayManagerServiceProxy_->GetAllScreenInfos(); } -DMError DisplayManagerAdapter::MakeExpand(std::vector screenId, std::vector startPoint) +ScreenId ScreenManagerAdapter::MakeExpand(std::vector screenId, std::vector startPoint) { - std::lock_guard lock(mutex_); - if (!InitDMSProxyLocked()) { - return DMError::DM_ERROR_INIT_DMS_PROXY_LOCKED; + if (!InitDMSProxy()) { + return SCREEN_ID_INVALID; } return displayManagerServiceProxy_->MakeExpand(screenId, startPoint); } -bool DisplayManagerAdapter::SetScreenActiveMode(ScreenId screenId, uint32_t modeId) +void ScreenManagerAdapter::RemoveVirtualScreenFromGroup(std::vector screens) { - std::lock_guard lock(mutex_); - if (!InitDMSProxyLocked()) { + if (!InitDMSProxy()) { + return; + } + displayManagerServiceProxy_->RemoveVirtualScreenFromGroup(screens); +} + +bool ScreenManagerAdapter::SetScreenActiveMode(ScreenId screenId, uint32_t modeId) +{ + if (!InitDMSProxy()) { return false; } return displayManagerServiceProxy_->SetScreenActiveMode(screenId, modeId); diff --git a/dm/src/screen.cpp b/dm/src/screen.cpp index 61875599..d82b920c 100644 --- a/dm/src/screen.cpp +++ b/dm/src/screen.cpp @@ -16,7 +16,6 @@ #include "screen.h" #include "display_manager_adapter.h" -#include "screen_group.h" #include "screen_info.h" #include "window_manager_hilog.h" @@ -25,37 +24,18 @@ namespace { constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, 0, "Screen"}; } class Screen::Impl : public RefBase { -friend class Screen; public: - Impl() = default; + Impl(sptr info) + { + screenInfo_ = info; + } ~Impl() = default; - - ScreenId id_ { SCREEN_ID_INVALID }; - uint32_t virtualWidth_ { 0 }; - uint32_t virtualHeight_ { 0 }; - float virtualPixelRatio_ { 0.0 }; - ScreenId parent_ { SCREEN_ID_INVALID }; - bool canHasChild_ { false }; - uint32_t modeId_ { 0 }; - std::vector> modes_ {}; - Rotation rotation_ { Rotation::ROTATION_0 }; + DEFINE_VAR_FUNC_GET_SET(sptr, ScreenInfo, screenInfo); }; -Screen::Screen(const ScreenInfo* info) - : pImpl_(new Impl()) +Screen::Screen(sptr info) + : pImpl_(new Impl(info)) { - if (info == nullptr) { - WLOGFE("info is nullptr."); - return; - } - pImpl_->id_ = info->id_; - pImpl_->virtualWidth_ = info->virtualWidth_; - pImpl_->virtualHeight_ = info->virtualHeight_; - pImpl_->virtualPixelRatio_ = info->virtualPixelRatio_; - pImpl_->parent_ = info->parent_; - pImpl_->canHasChild_ = info->canHasChild_; - pImpl_->modeId_ = info->modeId_; - pImpl_->modes_ = info->modes_; } Screen::~Screen() @@ -64,18 +44,25 @@ Screen::~Screen() bool Screen::IsGroup() const { - return pImpl_->canHasChild_; + UpdateScreenInfo(); + return pImpl_->GetScreenInfo()->GetCanHasChild(); +} + +const std::string& Screen::GetName() const +{ + return pImpl_->GetScreenInfo()->GetName(); } ScreenId Screen::GetId() const { - return pImpl_->id_; + return pImpl_->GetScreenInfo()->GetScreenId(); } uint32_t Screen::GetWidth() const { - auto modeId = pImpl_->modeId_; - auto modes = pImpl_->modes_; + UpdateScreenInfo(); + auto modeId = GetModeId(); + auto modes = GetSupportedModes(); if (modeId < 0 || modeId >= modes.size()) { return 0; } @@ -84,8 +71,9 @@ uint32_t Screen::GetWidth() const uint32_t Screen::GetHeight() const { - auto modeId = pImpl_->modeId_; - auto modes = pImpl_->modes_; + UpdateScreenInfo(); + auto modeId = GetModeId(); + auto modes = GetSupportedModes(); if (modeId < 0 || modeId >= modes.size()) { return 0; } @@ -94,85 +82,116 @@ uint32_t Screen::GetHeight() const uint32_t Screen::GetVirtualWidth() const { - return pImpl_->virtualWidth_; + UpdateScreenInfo(); + return pImpl_->GetScreenInfo()->GetVirtualWidth(); } uint32_t Screen::GetVirtualHeight() const { - return pImpl_->virtualHeight_; + UpdateScreenInfo(); + return pImpl_->GetScreenInfo()->GetVirtualHeight(); } float Screen::GetVirtualPixelRatio() const { - return pImpl_->virtualPixelRatio_; + UpdateScreenInfo(); + return pImpl_->GetScreenInfo()->GetVirtualPixelRatio(); } -Rotation Screen::GetRotation() +Rotation Screen::GetRotation() const { - return pImpl_->rotation_; + UpdateScreenInfo(); + return pImpl_->GetScreenInfo()->GetRotation(); } -bool Screen::RequestRotation(Rotation rotation) +Orientation Screen::GetOrientation() const { - WLOGFD("rotation the screen"); - return SingletonContainer::Get().RequestRotation(pImpl_->id_, rotation); + UpdateScreenInfo(); + return pImpl_->GetScreenInfo()->GetOrientation(); +} + +bool Screen::IsReal() const +{ + UpdateScreenInfo(); + return pImpl_->GetScreenInfo()->GetType() == ScreenType::REAL; +} + +bool Screen::SetOrientation(Orientation orientation) const +{ + WLOGFD("set orientation %{public}u", orientation); + return SingletonContainer::Get().SetOrientation(GetId(), orientation); } DMError Screen::GetScreenSupportedColorGamuts(std::vector& colorGamuts) const { - return SingletonContainer::Get().GetScreenSupportedColorGamuts(pImpl_->id_, colorGamuts); + return SingletonContainer::Get().GetScreenSupportedColorGamuts(GetId(), colorGamuts); } DMError Screen::GetScreenColorGamut(ScreenColorGamut& colorGamut) const { - return SingletonContainer::Get().GetScreenColorGamut(pImpl_->id_, colorGamut); + return SingletonContainer::Get().GetScreenColorGamut(GetId(), colorGamut); } DMError Screen::SetScreenColorGamut(int32_t colorGamutIdx) { - return SingletonContainer::Get().SetScreenColorGamut(pImpl_->id_, colorGamutIdx); + return SingletonContainer::Get().SetScreenColorGamut(GetId(), colorGamutIdx); } DMError Screen::GetScreenGamutMap(ScreenGamutMap& gamutMap) const { - return SingletonContainer::Get().GetScreenGamutMap(pImpl_->id_, gamutMap); + return SingletonContainer::Get().GetScreenGamutMap(GetId(), gamutMap); } DMError Screen::SetScreenGamutMap(ScreenGamutMap gamutMap) { - return SingletonContainer::Get().SetScreenGamutMap(pImpl_->id_, gamutMap); + return SingletonContainer::Get().SetScreenGamutMap(GetId(), gamutMap); } DMError Screen::SetScreenColorTransform() { - return SingletonContainer::Get().SetScreenColorTransform(pImpl_->id_); + return SingletonContainer::Get().SetScreenColorTransform(GetId()); } ScreenId Screen::GetParentId() const { - return pImpl_->parent_; + return pImpl_->GetScreenInfo()->GetParentId(); } uint32_t Screen::GetModeId() const { - return pImpl_->modeId_; + return pImpl_->GetScreenInfo()->GetModeId(); } std::vector> Screen::GetSupportedModes() const { - return pImpl_->modes_; + return pImpl_->GetScreenInfo()->GetModes(); } bool Screen::SetScreenActiveMode(uint32_t modeId) { - ScreenId screenId = pImpl_->id_; - if (modeId < 0 || modeId >= pImpl_->modes_.size()) { + ScreenId screenId = GetId(); + if (modeId >= GetSupportedModes().size()) { return false; } - if (SingletonContainer::Get().SetScreenActiveMode(screenId, modeId)) { - pImpl_->modeId_ = modeId; + if (SingletonContainer::Get().SetScreenActiveMode(screenId, modeId)) { + pImpl_->GetScreenInfo()->SetModeId(modeId); return true; } return false; } + +void Screen::UpdateScreenInfo(sptr info) const +{ + if (info == nullptr) { + WLOGFE("ScreenInfo is invalid"); + return; + } + pImpl_->SetScreenInfo(info); +} + +void Screen::UpdateScreenInfo() const +{ + auto screenInfo = SingletonContainer::Get().GetScreenInfo(GetId()); + UpdateScreenInfo(screenInfo); +} } // namespace OHOS::Rosen \ No newline at end of file diff --git a/dm/src/screen_group.cpp b/dm/src/screen_group.cpp index 262da22d..aa4e4924 100644 --- a/dm/src/screen_group.cpp +++ b/dm/src/screen_group.cpp @@ -23,26 +23,28 @@ namespace { constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, 0, "ScreenGroup"}; } class ScreenGroup::Impl : public RefBase { -friend class ScreenGroup; -private: - Impl() = default; +public: + Impl(sptr info) + { + screenGroupInfo_ = info; + } ~Impl() = default; - std::vector children_; - std::vector position_; - ScreenCombination combination_ { ScreenCombination::SCREEN_ALONE }; + DEFINE_VAR_FUNC_GET_SET(sptr, ScreenGroupInfo, screenGroupInfo); }; -ScreenGroup::ScreenGroup(const ScreenGroupInfo* info) - : Screen(info), pImpl_(new Impl()) +ScreenGroup::ScreenGroup(sptr info) + : Screen(info), pImpl_(new Impl(info)) +{ +} + +void ScreenGroup::UpdateScreenGroupInfo(sptr info) { if (info == nullptr) { - WLOGFE("info is nullptr."); + WLOGFE("ScreenGroupInfo is nullptr."); return; } - pImpl_->children_ = info->children_; - pImpl_->position_ = info->position_; - pImpl_->combination_ = info->combination_; + pImpl_->SetScreenGroupInfo(info); } ScreenGroup::~ScreenGroup() @@ -51,11 +53,16 @@ ScreenGroup::~ScreenGroup() ScreenCombination ScreenGroup::GetCombination() const { - return pImpl_->combination_; + return pImpl_->GetScreenGroupInfo()->GetCombination(); } -std::vector ScreenGroup::GetChildrenIds() const +std::vector ScreenGroup::GetChildIds() const { - return pImpl_->children_; + return pImpl_->GetScreenGroupInfo()->GetChildren(); +} + +std::vector ScreenGroup::GetChildPositions() const +{ + return pImpl_->GetScreenGroupInfo()->GetPosition(); } } // namespace OHOS::Rosen \ No newline at end of file diff --git a/dm/src/screen_manager.cpp b/dm/src/screen_manager.cpp index abbbee9d..e0b020af 100644 --- a/dm/src/screen_manager.cpp +++ b/dm/src/screen_manager.cpp @@ -30,12 +30,31 @@ public: Impl() = default; ~Impl() = default; static inline SingletonDelegator delegator; + bool RegisterScreenListener(sptr listener); + bool UnregisterScreenListener(sptr listener); + bool RegisterScreenGroupListener(sptr listener); + bool UnregisterScreenGroupListener(sptr listener); + sptr GetScreen(ScreenId screenId); + sptr GetScreenGroup(ScreenId screenId); + std::vector> GetAllScreens(); +private: + void NotifyScreenConnect(sptr info); + void NotifyScreenDisconnect(ScreenId); + void NotifyScreenChange(const sptr& screenInfo); + void NotifyScreenChange(const std::vector>& screenInfos); + bool UpdateScreenInfoLocked(sptr); + + class ScreenManagerListener; + sptr screenManagerListener_; + std::map> screenMap_; + std::map> screenGroupMap_; std::recursive_mutex mutex_; std::vector> screenListeners_; + std::vector> screenGroupListeners_; }; -class ScreenManager::ScreenManagerListener : public DisplayManagerAgentDefault { +class ScreenManager::Impl::ScreenManagerListener : public DisplayManagerAgentDefault { public: ScreenManagerListener(sptr impl) : pImpl_(impl) { @@ -43,7 +62,7 @@ public: void OnScreenConnect(sptr screenInfo) { - if (screenInfo == nullptr || screenInfo->id_ == SCREEN_ID_INVALID) { + if (screenInfo == nullptr || screenInfo->GetScreenId() == SCREEN_ID_INVALID) { WLOGFE("OnScreenConnect, screenInfo is invalid."); return; } @@ -51,8 +70,9 @@ public: WLOGFE("OnScreenConnect, impl is nullptr."); return; } + pImpl_->NotifyScreenConnect(screenInfo); for (auto listener : pImpl_->screenListeners_) { - listener->OnConnect(screenInfo->id_); + listener->OnConnect(screenInfo->GetScreenId()); } }; @@ -66,15 +86,16 @@ public: WLOGFE("OnScreenDisconnect, impl is nullptr."); return; } + pImpl_->NotifyScreenDisconnect(screenId); for (auto listener : pImpl_->screenListeners_) { listener->OnDisconnect(screenId); } }; - void OnScreenChange(const std::vector>& screenInfos, ScreenChangeEvent event) + void OnScreenChange(const sptr& screenInfo, ScreenChangeEvent event) { - if (screenInfos.empty()) { - WLOGFE("OnScreenChange, screenInfos is empty."); + if (screenInfo == nullptr) { + WLOGFE("OnScreenChange, screenInfo is null."); return; } if (pImpl_ == nullptr) { @@ -82,14 +103,32 @@ public: return; } WLOGFD("OnScreenChange. event %{public}u", event); + pImpl_->NotifyScreenChange(screenInfo); + for (auto listener: pImpl_->screenListeners_) { + listener->OnChange(screenInfo->GetScreenId()); + } + }; + + void OnScreenGroupChange(const std::vector>& screenInfos, ScreenGroupChangeEvent groupEvent) + { + if (screenInfos.empty()) { + WLOGFE("OnScreenGroupChange, screenInfos is empty."); + return; + } + if (pImpl_ == nullptr) { + WLOGFE("OnScreenGroupChange, impl is nullptr."); + return; + } + WLOGFD("OnScreenGroupChange. event %{public}u", groupEvent); + pImpl_->NotifyScreenChange(screenInfos); std::vector screenIds; for (auto screenInfo : screenInfos) { - if (screenInfo->id_ != SCREEN_ID_INVALID) { - screenIds.push_back(screenInfo->id_); + if (screenInfo->GetScreenId() != SCREEN_ID_INVALID) { + screenIds.push_back(screenInfo->GetScreenId()); } } - for (auto listener: pImpl_->screenListeners_) { - listener->OnChange(screenIds, event); + for (auto listener: pImpl_->screenGroupListeners_) { + listener->OnChange(screenIds, groupEvent); } }; private: @@ -106,19 +145,80 @@ ScreenManager::~ScreenManager() { } -sptr ScreenManager::GetScreenById(ScreenId screenId) +sptr ScreenManager::Impl::GetScreen(ScreenId screenId) { - return SingletonContainer::Get().GetScreenById(screenId); + auto screenInfo = SingletonContainer::Get().GetScreenInfo(screenId); + std::lock_guard lock(mutex_); + if (!UpdateScreenInfoLocked(screenInfo)) { + screenMap_.erase(screenId); + return nullptr; + } + return screenMap_[screenId]; } -sptr ScreenManager::GetScreenGroupById(ScreenId screenId) +sptr ScreenManager::GetScreenById(ScreenId screenId) { - return SingletonContainer::Get().GetScreenGroupById(screenId); + return pImpl_->GetScreen(screenId); +} + +sptr ScreenManager::Impl::GetScreenGroup(ScreenId screenId) +{ + auto screenGroupInfo = SingletonContainer::Get().GetScreenGroupInfoById(screenId); + std::lock_guard lock(mutex_); + if (screenGroupInfo == nullptr) { + WLOGFE("screenGroupInfo is null"); + screenGroupMap_.erase(screenId); + return nullptr; + } + auto iter = screenGroupMap_.find(screenId); + if (iter != screenGroupMap_.end() && iter->second != nullptr) { + WLOGFI("get screenGroup in screenGroup map"); + iter->second->UpdateScreenGroupInfo(screenGroupInfo); + return iter->second; + } + sptr screenGroup = new ScreenGroup(screenGroupInfo); + screenGroupMap_[screenId] = screenGroup; + return screenGroup; +} + +sptr ScreenManager::GetScreenGroup(ScreenId screenId) +{ + return pImpl_->GetScreenGroup(screenId); +} + +std::vector> ScreenManager::Impl::GetAllScreens() +{ + auto screenInfos = SingletonContainer::Get().GetAllScreenInfos(); + std::vector> screens; + std::lock_guard lock(mutex_); + for (auto info: screenInfos) { + if (UpdateScreenInfoLocked(info)) { + screens.emplace_back(screenMap_[info->GetScreenId()]); + } + } + screenMap_.clear(); + for (auto screen: screens) { + screenMap_.insert(std::make_pair(screen->GetId(), screen)); + } + return screens; } std::vector> ScreenManager::GetAllScreens() { - return SingletonContainer::Get().GetAllScreens(); + return pImpl_->GetAllScreens(); +} + +bool ScreenManager::Impl::RegisterScreenListener(sptr listener) +{ + std::lock_guard lock(mutex_); + screenListeners_.push_back(listener); + if (screenManagerListener_ == nullptr) { + screenManagerListener_ = new ScreenManagerListener(this); + SingletonContainer::Get().RegisterDisplayManagerAgent( + screenManagerListener_, + DisplayManagerAgentType::SCREEN_EVENT_LISTENER); + } + return true; } bool ScreenManager::RegisterScreenListener(sptr listener) @@ -127,13 +227,23 @@ bool ScreenManager::RegisterScreenListener(sptr listener) WLOGFE("RegisterScreenListener listener is nullptr."); return false; } - std::lock_guard lock(pImpl_->mutex_); - pImpl_->screenListeners_.push_back(listener); - if (screenManagerListener_ == nullptr) { - screenManagerListener_ = new ScreenManagerListener(pImpl_); - SingletonContainer::Get().RegisterDisplayManagerAgent( + return pImpl_->RegisterScreenListener(listener); +} + +bool ScreenManager::Impl::UnregisterScreenListener(sptr listener) +{ + std::lock_guard lock(mutex_); + auto iter = std::find(screenListeners_.begin(), screenListeners_.end(), listener); + if (iter == screenListeners_.end()) { + WLOGFE("could not find this listener"); + return false; + } + screenListeners_.erase(iter); + if (screenListeners_.empty() && screenManagerListener_ != nullptr) { + SingletonContainer::Get().UnregisterDisplayManagerAgent( screenManagerListener_, DisplayManagerAgentType::SCREEN_EVENT_LISTENER); + screenManagerListener_ = nullptr; } return true; } @@ -144,15 +254,42 @@ bool ScreenManager::UnregisterScreenListener(sptr listener) WLOGFE("UnregisterScreenListener listener is nullptr."); return false; } - std::lock_guard lock(pImpl_->mutex_); - auto iter = std::find(pImpl_->screenListeners_.begin(), pImpl_->screenListeners_.end(), listener); - if (iter == pImpl_->screenListeners_.end()) { + return pImpl_->UnregisterScreenListener(listener); +} + +bool ScreenManager::Impl::RegisterScreenGroupListener(sptr listener) +{ + std::lock_guard lock(mutex_); + screenGroupListeners_.push_back(listener); + if (screenManagerListener_ == nullptr) { + screenManagerListener_ = new ScreenManagerListener(this); + SingletonContainer::Get().RegisterDisplayManagerAgent( + screenManagerListener_, + DisplayManagerAgentType::SCREEN_EVENT_LISTENER); + } + return true; +} + +bool ScreenManager::RegisterScreenGroupListener(sptr listener) +{ + if (listener == nullptr) { + WLOGFE("RegisterScreenGroupListener listener is nullptr."); + return false; + } + return pImpl_->RegisterScreenGroupListener(listener); +} + +bool ScreenManager::Impl::UnregisterScreenGroupListener(sptr listener) +{ + std::lock_guard lock(mutex_); + auto iter = std::find(screenGroupListeners_.begin(), screenGroupListeners_.end(), listener); + if (iter == screenGroupListeners_.end()) { WLOGFE("could not find this listener"); return false; } - pImpl_->screenListeners_.erase(iter); - if (pImpl_->screenListeners_.empty() && screenManagerListener_ != nullptr) { - SingletonContainer::Get().UnregisterDisplayManagerAgent( + screenGroupListeners_.erase(iter); + if (screenGroupListeners_.empty() && screenManagerListener_ != nullptr) { + SingletonContainer::Get().UnregisterDisplayManagerAgent( screenManagerListener_, DisplayManagerAgentType::SCREEN_EVENT_LISTENER); screenManagerListener_ = nullptr; @@ -160,6 +297,15 @@ bool ScreenManager::UnregisterScreenListener(sptr listener) return true; } +bool ScreenManager::UnregisterScreenGroupListener(sptr listener) +{ + if (listener == nullptr) { + WLOGFE("UnregisterScreenGroupListener listener is nullptr."); + return false; + } + return pImpl_->UnregisterScreenGroupListener(listener); +} + ScreenId ScreenManager::MakeExpand(const std::vector& options) { WLOGFI("make expand"); @@ -172,37 +318,96 @@ ScreenId ScreenManager::MakeExpand(const std::vector& options) screenIds.emplace_back(option.screenId_); startPoints.emplace_back(Point(option.startX_, option.startY_)); } - DMError result = SingletonContainer::Get().MakeExpand(screenIds, startPoints); - if (result != DMError::DM_OK) { - return SCREEN_ID_INVALID; + ScreenId group = SingletonContainer::Get().MakeExpand(screenIds, startPoints); + if (group == SCREEN_ID_INVALID) { + WLOGFI("make expand failed"); } - WLOGFI("make expand success"); - return screenIds.front(); // default main screenId is the first element of screenIds + return group; } ScreenId ScreenManager::MakeMirror(ScreenId mainScreenId, std::vector mirrorScreenId) { WLOGFI("create mirror for screen: %{public}" PRIu64"", mainScreenId); // TODO: "record screen" should use another function, "MakeMirror" should return group id. - DMError result = SingletonContainer::Get().MakeMirror(mainScreenId, mirrorScreenId); - if (result == DMError::DM_OK) { - WLOGFI("create mirror success"); + ScreenId group = SingletonContainer::Get().MakeMirror(mainScreenId, mirrorScreenId); + if (group == SCREEN_ID_INVALID) { + WLOGFI("create mirror failed"); } - return SCREEN_ID_INVALID; + return group; +} + +void ScreenManager::RemoveVirtualScreenFromGroup(std::vector screens) +{ + SingletonContainer::Get().RemoveVirtualScreenFromGroup(screens); +} + +void ScreenManager::CancelMakeMirrorOrExpand(std::vector screens) +{ + RemoveVirtualScreenFromGroup(screens); } ScreenId ScreenManager::CreateVirtualScreen(VirtualScreenOption option) { - return SingletonContainer::Get().CreateVirtualScreen(option); + return SingletonContainer::Get().CreateVirtualScreen(option); } DMError ScreenManager::DestroyVirtualScreen(ScreenId screenId) { - return SingletonContainer::Get().DestroyVirtualScreen(screenId); + return SingletonContainer::Get().DestroyVirtualScreen(screenId); } DMError ScreenManager::SetVirtualScreenSurface(ScreenId screenId, sptr surface) { - return SingletonContainer::Get().SetVirtualScreenSurface(screenId, surface); + return SingletonContainer::Get().SetVirtualScreenSurface(screenId, surface); +} + +void ScreenManager::Impl::NotifyScreenConnect(sptr info) +{ + std::lock_guard lock(mutex_); + UpdateScreenInfoLocked(info); +} + +void ScreenManager::Impl::NotifyScreenDisconnect(ScreenId screenId) +{ + WLOGFI("screenId:%{public}" PRIu64".", screenId); + std::lock_guard lock(mutex_); + screenMap_.erase(screenId); +} + +void ScreenManager::Impl::NotifyScreenChange(const sptr& screenInfo) +{ + std::lock_guard lock(mutex_); + UpdateScreenInfoLocked(screenInfo); +} + +void ScreenManager::Impl::NotifyScreenChange(const std::vector>& screenInfos) +{ + std::lock_guard lock(mutex_); + for (auto screenInfo : screenInfos) { + UpdateScreenInfoLocked(screenInfo); + } +} + +bool ScreenManager::Impl::UpdateScreenInfoLocked(sptr screenInfo) +{ + if (screenInfo == nullptr) { + WLOGFE("displayInfo is null"); + return false; + } + ScreenId screenId = screenInfo->GetScreenId(); + WLOGFI("screenId:%{public}" PRIu64".", screenId); + if (screenId == SCREEN_ID_INVALID) { + WLOGFE("displayId is invalid."); + return false; + } + auto iter = screenMap_.find(screenId); + if (iter != screenMap_.end() && iter->second != nullptr) { + WLOGFI("get screen in screen map"); + iter->second->UpdateScreenInfo(screenInfo); + return true; + } + sptr screen = new Screen(screenInfo); + screenMap_[screenId] = screen; + return true; } } // namespace OHOS::Rosen \ No newline at end of file diff --git a/dm/src/zidl/display_manager_agent_proxy.cpp b/dm/src/zidl/display_manager_agent_proxy.cpp index 6e71bc27..0fc9940e 100644 --- a/dm/src/zidl/display_manager_agent_proxy.cpp +++ b/dm/src/zidl/display_manager_agent_proxy.cpp @@ -113,8 +113,33 @@ void DisplayManagerAgentProxy::OnScreenDisconnect(ScreenId screenId) } } -void DisplayManagerAgentProxy::OnScreenChange( - const std::vector>& screenInfos, ScreenChangeEvent event) +void DisplayManagerAgentProxy::OnScreenChange(const sptr& screenInfo, ScreenChangeEvent event) +{ + MessageParcel data; + MessageParcel reply; + MessageOption option(MessageOption::TF_ASYNC); + if (!data.WriteInterfaceToken(GetDescriptor())) { + WLOGFE("WriteInterfaceToken failed"); + return; + } + + if (!data.WriteParcelable(screenInfo.GetRefPtr())) { + WLOGFE("Write screenInfo failed"); + return; + } + + if (!data.WriteUint32(static_cast(event))) { + WLOGFE("Write ScreenChangeEvent failed"); + return; + } + + if (Remote()->SendRequest(TRANS_ID_ON_SCREEN_CHANGED, data, reply, option) != ERR_NONE) { + WLOGFE("SendRequest failed"); + } +} + +void DisplayManagerAgentProxy::OnScreenGroupChange( + const std::vector>& screenInfos, ScreenGroupChangeEvent event) { MessageParcel data; MessageParcel reply; @@ -130,19 +155,19 @@ void DisplayManagerAgentProxy::OnScreenChange( return; } - for (int i = 0; i < size; i++) { + for (size_t i = 0; i < size; i++) { if (!data.WriteParcelable(screenInfos[i].GetRefPtr())) { - WLOGFE("Write screenInfos[%{public}d] size failed", i); + WLOGFE("Write screenInfos[%{public}zu] size failed", i); return; } } if (!data.WriteUint32(static_cast(event))) { - WLOGFE("Write ScreenChangeEvent failed"); + WLOGFE("Write ScreenGroupChangeEvent failed"); return; } - if (Remote()->SendRequest(TRANS_ID_ON_SCREEN_CHANGED, data, reply, option) != ERR_NONE) { + if (Remote()->SendRequest(TRANS_ID_ON_SCREENGROUP_CHANGED, data, reply, option) != ERR_NONE) { WLOGFE("SendRequest failed"); } } diff --git a/dm/src/zidl/display_manager_agent_stub.cpp b/dm/src/zidl/display_manager_agent_stub.cpp index 1c528a14..ae767a3c 100644 --- a/dm/src/zidl/display_manager_agent_stub.cpp +++ b/dm/src/zidl/display_manager_agent_stub.cpp @@ -59,7 +59,17 @@ int32_t DisplayManagerAgentStub::OnRemoteRequest(uint32_t code, MessageParcel& d break; } case TRANS_ID_ON_SCREEN_CHANGED: { - std::vector> screenInfos; + sptr screenInfo = data.ReadParcelable(); + uint32_t event; + if (!data.ReadUint32(event)) { + WLOGFE("Read ScreenChangeEvent failed"); + return -1; + } + OnScreenChange(screenInfo, static_cast(event)); + break; + } + case TRANS_ID_ON_SCREENGROUP_CHANGED: { + std::vector> screenInfos; uint32_t size; if (!data.ReadUint32(size)) { WLOGFE("Read ScreenChangeEvent failed"); @@ -75,7 +85,7 @@ int32_t DisplayManagerAgentStub::OnRemoteRequest(uint32_t code, MessageParcel& d WLOGFE("Read ScreenChangeEvent failed"); return -1; } - OnScreenChange(screenInfos, static_cast(event)); + OnScreenGroupChange(screenInfos, static_cast(event)); break; } case TRANS_ID_ON_DISPLAY_CONNECT: { diff --git a/dm/test/systemtest/BUILD.gn b/dm/test/systemtest/BUILD.gn index 45afe26c..1e4fc883 100644 --- a/dm/test/systemtest/BUILD.gn +++ b/dm/test/systemtest/BUILD.gn @@ -75,7 +75,12 @@ ohos_systemtest("dm_screenshot_test") { ohos_systemtest("dm_screenshot_cmd_test") { module_out_path = module_out_path - sources = [ "screenshot_cmd_test.cpp" ] + include_dirs = [ "//foundation/windowmanager/snapshot" ] + + sources = [ + "//foundation/windowmanager/snapshot/snapshot_utils.cpp", + "screenshot_cmd_test.cpp", + ] deps = [ ":dm_systemtest_common" ] } diff --git a/dm/test/systemtest/display_change_test.cpp b/dm/test/systemtest/display_change_test.cpp index 70822726..1f8c974c 100644 --- a/dm/test/systemtest/display_change_test.cpp +++ b/dm/test/systemtest/display_change_test.cpp @@ -44,15 +44,13 @@ public: WLOGI("DisplayChangeEventListener::OnDestroy displayId=%{public}" PRIu64"", displayId); } - virtual void OnChange(DisplayId displayId, DisplayChangeEvent event) + virtual void OnChange(DisplayId displayId) { WLOGI("DisplayChangeEventListener::OnChange displayId=%{public}" PRIu64"", displayId); isCallbackCalled_ = true; - event_ = event; displayId_ = displayId; } bool isCallbackCalled_ { false }; - DisplayChangeEvent event_ { DisplayChangeEvent::UNKNOWN }; DisplayId displayId_ { DISPLAY_ID_INVALD }; }; @@ -105,7 +103,6 @@ void DisplayChangeTest::TearDown() void DisplayChangeTest::ResetDisplayChangeListener() { listener_->isCallbackCalled_ = false; - listener_->event_ = DisplayChangeEvent::UNKNOWN; listener_->displayId_ = DISPLAY_ID_INVALD; } diff --git a/dm/test/systemtest/display_power_test.cpp b/dm/test/systemtest/display_power_test.cpp index a3fdc252..31f477e4 100644 --- a/dm/test/systemtest/display_power_test.cpp +++ b/dm/test/systemtest/display_power_test.cpp @@ -15,6 +15,7 @@ #include #include "display_manager.h" +#include "window.h" #include "window_manager_hilog.h" using namespace testing; @@ -53,7 +54,7 @@ public: static inline DisplayId defaultId_; static inline uint32_t brightnessLevel_ = 80; - static inline uint32_t invalidBrightnessLevel_ = 10000000; + static inline uint32_t invalidBrightnessLevel_ = 1000000000; static inline uint32_t times_ = 0; static inline bool isDisplayStateCallbackCalled_ = false; static sptr listener_; @@ -433,6 +434,28 @@ HWTEST_F(DisplayPowerTest, set_screen_brightness_002, Function | MediumTest | Le uint32_t level = DisplayManager::GetInstance().GetScreenBrightness(defaultId_); ASSERT_NE(level, invalidBrightnessLevel_); } + +/** +* @tc.name: window_life_cycle_001 +* @tc.desc: Add a window and then call SuspendEnd and check window state; Notify unlock and check window state +* @tc.type: FUNC +*/ +HWTEST_F(DisplayPowerTest, window_life_cycle_001, Function | MediumTest | Level2) +{ + sptr option = new WindowOption(); + sptr window = Window::Create("window1", option, nullptr); + EXPECT_EQ(WMError::WM_OK, window->Show()); + + DisplayManager::GetInstance().SuspendBegin(PowerStateChangeReason::POWER_BUTTON); + usleep(SLEEP_TIME_IN_US); + ASSERT_EQ(false, window->GetShowState()); + + DisplayManager::GetInstance().NotifyDisplayEvent(DisplayEvent::UNLOCK); + usleep(SLEEP_TIME_IN_US); + ASSERT_EQ(true, window->GetShowState()); + + window->Destroy(); +} } // namespace } // namespace Rosen } // namespace OHOS \ No newline at end of file diff --git a/dm/test/systemtest/display_test_utils.cpp b/dm/test/systemtest/display_test_utils.cpp index 92709c18..d962a00e 100644 --- a/dm/test/systemtest/display_test_utils.cpp +++ b/dm/test/systemtest/display_test_utils.cpp @@ -31,6 +31,9 @@ DisplayTestUtils::~DisplayTestUtils() } WLOGFI("prevBuffer_ release success"); } + if (csurface_ != nullptr) { + csurface_->UnregisterConsumerListener(); + } csurface_ = nullptr; psurface_ = nullptr; listener_ = nullptr; @@ -86,7 +89,7 @@ bool DisplayTestUtils::CreateSurface() void DisplayTestUtils::OnVsync() { std::lock_guard lock(mutex_); - WLOGFI("DisplayTestUtils::OnVsyn"); + WLOGFI("DisplayTestUtils::OnVsync"); sptr cbuffer = nullptr; int32_t fence = -1; int64_t timestamp = 0; diff --git a/dm/test/systemtest/screen_gamut_test.cpp b/dm/test/systemtest/screen_gamut_test.cpp index e4959dd2..f014cb41 100644 --- a/dm/test/systemtest/screen_gamut_test.cpp +++ b/dm/test/systemtest/screen_gamut_test.cpp @@ -56,36 +56,135 @@ void ScreenGamutTest::TearDown() namespace { /** - * @tc.name: ScreenGamut01 - * @tc.desc: gamut + * @tc.name: GetScreenSupportedColorGamuts01 + * @tc.desc: gamut GetScreenSupportedColorGamuts * @tc.type: FUNC */ -HWTEST_F(ScreenGamutTest, ScreenGamut01, Function | MediumTest | Level1) +HWTEST_F(ScreenGamutTest, GetScreenSupportedColorGamuts01, Function | MediumTest | Level3) { ASSERT_NE(defaultScreen_, nullptr); DMError ret; std::vector colorGamuts; ret = defaultScreen_->GetScreenSupportedColorGamuts(colorGamuts); ASSERT_EQ(ret, DMError::DM_OK); - - ScreenColorGamut colorGamut; - ret = defaultScreen_->GetScreenColorGamut(colorGamut); - ASSERT_EQ(ret, DMError::DM_OK); - - ret = defaultScreen_->SetScreenColorGamut(0); - ASSERT_EQ(ret, DMError::DM_OK); - - const int32_t invalidColorGamutIndex = -1; - ret = defaultScreen_->SetScreenColorGamut(invalidColorGamutIndex); - ASSERT_NE(ret, DMError::DM_OK); + ASSERT_GT(colorGamuts.size(), 0); } /** - * @tc.name: ScreenGamut02 - * @tc.desc: gamut + * @tc.name: GetScreenColorGamut01 + * @tc.desc: gamut GetScreenColorGamut * @tc.type: FUNC */ -HWTEST_F(ScreenGamutTest, ScreenGamut02, Function | MediumTest | Level1) +HWTEST_F(ScreenGamutTest, GetScreenColorGamut01, Function | MediumTest | Level3) +{ + ASSERT_NE(defaultScreen_, nullptr); + DMError ret; + ScreenColorGamut colorGamut; + ret = defaultScreen_->GetScreenColorGamut(colorGamut); + ASSERT_EQ(ret, DMError::DM_OK); + ASSERT_NE(COLOR_GAMUT_INVALID, colorGamut); +} + +/** + * @tc.name: SetScreenColorGamut01 + * @tc.desc: gamut SetScreenColorGamut, valid index + * @tc.type: FUNC + */ +HWTEST_F(ScreenGamutTest, SetScreenColorGamut01, Function | MediumTest | Level3) +{ + ASSERT_NE(defaultScreen_, nullptr); + DMError ret; + ScreenColorGamut colorGamutBackup; + int32_t colorGamutBackupIdx = -1; + ScreenColorGamut colorGamut; + std::vector colorGamuts; + + ret = defaultScreen_->GetScreenColorGamut(colorGamutBackup); // backup origin + ASSERT_EQ(ret, DMError::DM_OK); + + ret = defaultScreen_->GetScreenSupportedColorGamuts(colorGamuts); + ASSERT_EQ(ret, DMError::DM_OK); + + for (int32_t i = 0; i < static_cast(colorGamuts.size()); i++) { + ret = defaultScreen_->SetScreenColorGamut(i); + ASSERT_EQ(ret, DMError::DM_OK); + + ret = defaultScreen_->GetScreenColorGamut(colorGamut); + ASSERT_EQ(ret, DMError::DM_OK); + +#ifdef SCREEN_GAMUT_SET_GET_OK + ASSERT_EQ(colorGamut, colorGamuts[i]); +#endif + if (colorGamutBackup == colorGamuts[i]) { + colorGamutBackupIdx = i; + } + } + + ASSERT_GE(colorGamutBackupIdx, 0); + ret = defaultScreen_->SetScreenColorGamut(colorGamutBackupIdx); // restore + ASSERT_EQ(ret, DMError::DM_OK); +} + +/** + * @tc.name: SetScreenColorGamut02 + * @tc.desc: gamut SetScreenColorGamut, invalid index < 0 + * @tc.type: FUNC + */ +HWTEST_F(ScreenGamutTest, SetScreenColorGamut02, Function | MediumTest | Level3) +{ + ASSERT_NE(defaultScreen_, nullptr); + DMError ret; + ScreenColorGamut colorGamutBefore; + ScreenColorGamut colorGamutAfter; + + ret = defaultScreen_->GetScreenColorGamut(colorGamutBefore); + ASSERT_EQ(ret, DMError::DM_OK); + + constexpr int32_t invalidColorGamutIndex = -1; // index < 0 + ret = defaultScreen_->SetScreenColorGamut(invalidColorGamutIndex); + ASSERT_NE(ret, DMError::DM_OK); + + ret = defaultScreen_->GetScreenColorGamut(colorGamutAfter); + ASSERT_EQ(ret, DMError::DM_OK); + + ASSERT_EQ(colorGamutBefore, colorGamutAfter); // don't change colorgamut after invalid set +} + +/** + * @tc.name: SetScreenColorGamut03 + * @tc.desc: gamut SetScreenColorGamut, invalid index >= size + * @tc.type: FUNC + */ +HWTEST_F(ScreenGamutTest, SetScreenColorGamut03, Function | MediumTest | Level3) +{ + ASSERT_NE(defaultScreen_, nullptr); + DMError ret; + ScreenColorGamut colorGamutBefore; + ScreenColorGamut colorGamutAfter; + + ret = defaultScreen_->GetScreenColorGamut(colorGamutBefore); + ASSERT_EQ(ret, DMError::DM_OK); + + std::vector colorGamuts; + ret = defaultScreen_->GetScreenSupportedColorGamuts(colorGamuts); + ASSERT_EQ(ret, DMError::DM_OK); + + const int32_t invalidColorGamutIndex = static_cast(colorGamuts.size()); // index >= size + ret = defaultScreen_->SetScreenColorGamut(invalidColorGamutIndex); + ASSERT_NE(ret, DMError::DM_OK); + + ret = defaultScreen_->GetScreenColorGamut(colorGamutAfter); + ASSERT_EQ(ret, DMError::DM_OK); + + ASSERT_EQ(colorGamutBefore, colorGamutAfter); // don't change colorgamut after invalid set +} + +/** + * @tc.name: GetScreenGamutMap01 + * @tc.desc: gamut GetScreenGamutMap + * @tc.type: FUNC + */ +HWTEST_F(ScreenGamutTest, GetScreenGamutMap01, Function | MediumTest | Level3) { ASSERT_NE(defaultScreen_, nullptr); DMError ret; @@ -93,21 +192,76 @@ HWTEST_F(ScreenGamutTest, ScreenGamut02, Function | MediumTest | Level1) ret = defaultScreen_->GetScreenGamutMap(gamutMap); ASSERT_EQ(ret, DMError::DM_OK); +} - ret = defaultScreen_->SetScreenGamutMap(gamutMap); +/** + * @tc.name: SetScreenGamutMap01 + * @tc.desc: gamut SetScreenGamutMap, valid param + * @tc.type: FUNC + */ +HWTEST_F(ScreenGamutTest, SetScreenGamutMap01, Function | MediumTest | Level3) +{ + ASSERT_NE(defaultScreen_, nullptr); + DMError ret; + const ScreenGamutMap gamutMaps[] = { + GAMUT_MAP_CONSTANT, + GAMUT_MAP_EXTENSION, + GAMUT_MAP_HDR_CONSTANT, + GAMUT_MAP_HDR_EXTENSION, + }; + ScreenGamutMap gamutMap; + ScreenGamutMap gamutMapBackup; + + ret = defaultScreen_->GetScreenGamutMap(gamutMapBackup); // backup origin + ASSERT_EQ(ret, DMError::DM_OK); + + for (uint32_t i = 0; i < sizeof(gamutMaps) / sizeof(ScreenGamutMap); i++) { + ret = defaultScreen_->SetScreenGamutMap(gamutMaps[i]); + ASSERT_EQ(ret, DMError::DM_OK); + + ret = defaultScreen_->GetScreenGamutMap(gamutMap); + ASSERT_EQ(ret, DMError::DM_OK); +#ifdef SCREEN_GAMUT_SET_GET_OK + ASSERT_EQ(gamutMaps[i], gamutMap); +#endif + } + + ret = defaultScreen_->SetScreenGamutMap(gamutMapBackup); // restore + ASSERT_EQ(ret, DMError::DM_OK); +} + +/** + * @tc.name: SetScreenGamutMap02 + * @tc.desc: gamut SetScreenGamutMap, invalid param + * @tc.type: FUNC + */ +HWTEST_F(ScreenGamutTest, SetScreenGamutMap02, Function | MediumTest | Level3) +{ + ASSERT_NE(defaultScreen_, nullptr); + DMError ret; + ScreenGamutMap gamutMap; + ScreenGamutMap gamutMapBefore; + ScreenGamutMap gamutMapAfter; + + ret = defaultScreen_->GetScreenGamutMap(gamutMapBefore); ASSERT_EQ(ret, DMError::DM_OK); gamutMap = static_cast(static_cast(ScreenGamutMap::GAMUT_MAP_HDR_EXTENSION) + 1); ret = defaultScreen_->SetScreenGamutMap(gamutMap); ASSERT_NE(ret, DMError::DM_OK); + + ret = defaultScreen_->GetScreenGamutMap(gamutMapAfter); + ASSERT_EQ(ret, DMError::DM_OK); + + ASSERT_EQ(gamutMapBefore, gamutMapAfter); } /** - * @tc.name: ScreenGamut03 - * @tc.desc: gamut + * @tc.name: SetScreenColorTransform01 + * @tc.desc: gamut SetScreenColorTransform * @tc.type: FUNC */ -HWTEST_F(ScreenGamutTest, ScreenGamut03, Function | MediumTest | Level1) +HWTEST_F(ScreenGamutTest, SetScreenColorTransform01, Function | MediumTest | Level3) { ASSERT_NE(defaultScreen_, nullptr); DMError ret; diff --git a/dm/test/systemtest/screen_manager_test.cpp b/dm/test/systemtest/screen_manager_test.cpp index f78c3e36..f40717c6 100644 --- a/dm/test/systemtest/screen_manager_test.cpp +++ b/dm/test/systemtest/screen_manager_test.cpp @@ -15,14 +15,21 @@ // gtest #include + #include "display_test_utils.h" +#include "future.h" +#include "screen.h" #include "window.h" #include "window_option.h" +#include "window_manager_hilog.h" using namespace testing; using namespace testing::ext; namespace OHOS { namespace Rosen { +namespace { + constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_DISPLAY, "ScreenManagerTest"}; +} class ScreenManagerTest : public testing::Test { public: static void SetUpTestCase(); @@ -38,13 +45,48 @@ public: static uint32_t defaultHeight_; static float defaultDensity_; static int32_t defaultFlags_; - static VirtualScreenOption defaultoption_; + static VirtualScreenOption defaultOption_; static uint32_t waitCount_; const uint32_t sleepUs_ = 10 * 1000; const uint32_t maxWaitCount_ = 2000; const uint32_t execTimes_ = 10; const uint32_t acquireFrames_ = 1; static constexpr uint32_t TEST_SPEEP_S = 1; // test spleep time + static constexpr long TIME_OUT = 1000; +}; + +class ScreenChangeListener : public ScreenManager::IScreenListener { +public: + virtual void OnConnect(ScreenId screenId) override + { + WLOGFI("OnConnect, screenId:%{public}" PRIu64"", screenId); + connectFuture_.SetValue(screenId); + } + virtual void OnDisconnect(ScreenId screenId) override + { + WLOGFI("OnDisconnect, screenId:%{public}" PRIu64"", screenId); + disconnectFuture_.SetValue(screenId); + } + virtual void OnChange(ScreenId screenId) override + { + WLOGFI("OnChange, screenId:%{public}" PRIu64"", screenId); + changeFuture_.SetValue(screenId); + } + RunnableFuture connectFuture_; + RunnableFuture disconnectFuture_; + RunnableFuture changeFuture_; +}; + +class ScreenGroupChangeListener : public ScreenManager::IScreenGroupListener { +public: + virtual void OnChange(const std::vector& screenIds, ScreenGroupChangeEvent event) override + { + for (auto screenId : screenIds) { + changeFuture_.SetValue(std::make_pair(screenId, event)); + usleep(10 * 1000); // wait 10000 us + } + } + RunnableFuture> changeFuture_; }; sptr ScreenManagerTest::defaultDisplay_ = nullptr; @@ -55,7 +97,7 @@ uint32_t ScreenManagerTest::defaultWidth_ = 480; uint32_t ScreenManagerTest::defaultHeight_ = 320; float ScreenManagerTest::defaultDensity_ = 2.0; int32_t ScreenManagerTest::defaultFlags_ = 0; -VirtualScreenOption ScreenManagerTest::defaultoption_ = { +VirtualScreenOption ScreenManagerTest::defaultOption_ = { defaultName_, defaultWidth_, defaultHeight_, defaultDensity_, nullptr, defaultFlags_ }; uint32_t ScreenManagerTest::waitCount_ = 0; @@ -67,8 +109,8 @@ void ScreenManagerTest::SetUpTestCase() defaultScreenId_ = defaultDisplay_->GetScreenId(); defaultWidth_ = defaultDisplay_->GetWidth(); defaultHeight_ = defaultDisplay_->GetHeight(); - defaultoption_.width_ = defaultWidth_; - defaultoption_.height_ = defaultHeight_; + defaultOption_.width_ = defaultWidth_; + defaultOption_.height_ = defaultHeight_; } void ScreenManagerTest::TearDownTestCase() @@ -112,8 +154,8 @@ HWTEST_F(ScreenManagerTest, ScreenManager01, Function | MediumTest | Level2) { DisplayTestUtils utils; ASSERT_TRUE(utils.CreateSurface()); - defaultoption_.surface_ = utils.psurface_; - ScreenId virtualScreenId = ScreenManager::GetInstance().CreateVirtualScreen(defaultoption_); + defaultOption_.surface_ = utils.psurface_; + ScreenId virtualScreenId = ScreenManager::GetInstance().CreateVirtualScreen(defaultOption_); ASSERT_NE(SCREEN_ID_INVALID, virtualScreenId); ASSERT_EQ(DMError::DM_OK, ScreenManager::GetInstance().DestroyVirtualScreen(virtualScreenId)); } @@ -127,8 +169,8 @@ HWTEST_F(ScreenManagerTest, ScreenManager02, Function | MediumTest | Level2) { DisplayTestUtils utils; ASSERT_TRUE(utils.CreateSurface()); - defaultoption_.surface_ = utils.psurface_; - ScreenId virtualScreenId = ScreenManager::GetInstance().CreateVirtualScreen(defaultoption_); + defaultOption_.surface_ = utils.psurface_; + ScreenId virtualScreenId = ScreenManager::GetInstance().CreateVirtualScreen(defaultOption_); std::vector mirrorIds; mirrorIds.push_back(virtualScreenId); ScreenManager::GetInstance().MakeMirror(defaultScreenId_, mirrorIds); @@ -145,9 +187,9 @@ HWTEST_F(ScreenManagerTest, ScreenManager03, Function | MediumTest | Level2) { DisplayTestUtils utils; ASSERT_TRUE(utils.CreateSurface()); - defaultoption_.surface_ = utils.psurface_; + defaultOption_.surface_ = utils.psurface_; for (uint32_t i = 0; i < execTimes_; i++) { - ScreenId virtualScreenId = ScreenManager::GetInstance().CreateVirtualScreen(defaultoption_); + ScreenId virtualScreenId = ScreenManager::GetInstance().CreateVirtualScreen(defaultOption_); ASSERT_NE(SCREEN_ID_INVALID, virtualScreenId); ASSERT_EQ(DMError::DM_OK, ScreenManager::GetInstance().DestroyVirtualScreen(virtualScreenId)); } @@ -162,9 +204,9 @@ HWTEST_F(ScreenManagerTest, ScreenManager04, Function | MediumTest | Level2) { DisplayTestUtils utils; ASSERT_TRUE(utils.CreateSurface()); - defaultoption_.surface_ = utils.psurface_; + defaultOption_.surface_ = utils.psurface_; for (uint32_t i = 0; i < execTimes_; i++) { - ScreenId virtualScreenId = ScreenManager::GetInstance().CreateVirtualScreen(defaultoption_); + ScreenId virtualScreenId = ScreenManager::GetInstance().CreateVirtualScreen(defaultOption_); std::vector mirrorIds; mirrorIds.push_back(virtualScreenId); ScreenManager::GetInstance().MakeMirror(defaultScreenId_, mirrorIds); @@ -183,8 +225,8 @@ HWTEST_F(ScreenManagerTest, ScreenManager05, Function | MediumTest | Level2) DisplayTestUtils utils; utils.SetDefaultWH(defaultDisplay_); ASSERT_TRUE(utils.CreateSurface()); - defaultoption_.surface_ = utils.psurface_; - ScreenId virtualScreenId = ScreenManager::GetInstance().CreateVirtualScreen(defaultoption_); + defaultOption_.surface_ = utils.psurface_; + ScreenId virtualScreenId = ScreenManager::GetInstance().CreateVirtualScreen(defaultOption_); ASSERT_NE(SCREEN_ID_INVALID, virtualScreenId); uint32_t lastCount = -1u; @@ -203,59 +245,125 @@ HWTEST_F(ScreenManagerTest, ScreenManager05, Function | MediumTest | Level2) ASSERT_EQ(DMError::DM_OK, ScreenManager::GetInstance().DestroyVirtualScreen(virtualScreenId)); ASSERT_GT(utils.successCount_, 0); ASSERT_GT(maxWaitCount_, waitCount_); + waitCount_ = 0; } /** * @tc.name: ScreenManager06 - * @tc.desc: Get and set screenMode + * @tc.desc: Compare the length and width for recording screen, set VirtualScreen Surface before make mirror. * @tc.type: FUNC */ HWTEST_F(ScreenManagerTest, ScreenManager06, Function | MediumTest | Level2) { - sptr screen = ScreenManager::GetInstance().GetScreenById(defaultScreenId_); - auto modes = screen->GetSupportedModes(); - ASSERT_GT(modes.size(), 0); - for (uint32_t modeIdx = 0; modeIdx < modes.size(); modeIdx++) { - ASSERT_EQ(true, screen->SetScreenActiveMode(modeIdx)); - ASSERT_EQ(modeIdx, screen->GetModeId()); + DisplayTestUtils utils; + utils.SetDefaultWH(defaultDisplay_); + defaultOption_.surface_ = nullptr; + ScreenId virtualScreenId = ScreenManager::GetInstance().CreateVirtualScreen(defaultOption_); + ASSERT_NE(SCREEN_ID_INVALID, virtualScreenId); + + ASSERT_TRUE(utils.CreateSurface()); + ASSERT_EQ(DMError::DM_OK, ScreenManager::GetInstance().SetVirtualScreenSurface(virtualScreenId, utils.psurface_)); + + uint32_t lastCount = -1u; + std::vector mirrorIds; + mirrorIds.push_back(virtualScreenId); + ScreenManager::GetInstance().MakeMirror(defaultScreenId_, mirrorIds); + + while (utils.successCount_ < acquireFrames_ && waitCount_ <= maxWaitCount_) { + if (lastCount != utils.successCount_) { + lastCount = utils.successCount_; + } + ASSERT_EQ(0, utils.failCount_); + waitCount_++; + usleep(sleepUs_); } + DMError res = ScreenManager::GetInstance().DestroyVirtualScreen(virtualScreenId); + ASSERT_EQ(DMError::DM_OK, res); + ASSERT_GT(utils.successCount_, 0); + ASSERT_GT(maxWaitCount_, waitCount_); + waitCount_ = 0; } /** * @tc.name: ScreenManager07 - * @tc.desc: Create a virtual screen as expansion of default screen, and destroy virtual screen + * @tc.desc: Get and set screenMode * @tc.type: FUNC */ HWTEST_F(ScreenManagerTest, ScreenManager07, Function | MediumTest | Level2) { - DisplayTestUtils utils; - ASSERT_TRUE(utils.CreateSurface()); - defaultoption_.surface_ = utils.psurface_; - defaultoption_.isForShot_ = false; - ScreenId virtualScreenId = ScreenManager::GetInstance().CreateVirtualScreen(defaultoption_); - ASSERT_NE(SCREEN_ID_INVALID, virtualScreenId); - std::vector> screens = ScreenManager::GetInstance().GetAllScreens(); - sptr DefaultScreen = screens.front(); - std::vector options = {{DefaultScreen->GetId(), 0, 0}, {virtualScreenId, defaultWidth_, 0}}; - ScreenId expansionId = ScreenManager::GetInstance().MakeExpand(options); - ASSERT_NE(SCREEN_ID_INVALID, expansionId); - ASSERT_EQ(DMError::DM_OK, ScreenManager::GetInstance().DestroyVirtualScreen(virtualScreenId)); + sptr screen = ScreenManager::GetInstance().GetScreenById(defaultScreenId_); + auto modes = screen->GetSupportedModes(); + auto defaultModeId = screen->GetModeId(); + ASSERT_GT(modes.size(), 0); + for (uint32_t modeIdx = 0; modeIdx < modes.size(); modeIdx++) { + ASSERT_EQ(true, screen->SetScreenActiveMode(modeIdx)); + sleep(TEST_SPEEP_S); + ASSERT_EQ(modeIdx, screen->GetModeId()); + } + ASSERT_EQ(true, screen->SetScreenActiveMode(defaultModeId)); + sleep(TEST_SPEEP_S); } /** * @tc.name: ScreenManager08 - * @tc.desc: Create a virtual screen as expansion of default screen, create windowNode on virtual screen, - * and destroy virtual screen + * @tc.desc: Create a virtual screen as expansion of default screen, and destroy virtual screen * @tc.type: FUNC */ HWTEST_F(ScreenManagerTest, ScreenManager08, Function | MediumTest | Level2) { DisplayTestUtils utils; ASSERT_TRUE(utils.CreateSurface()); - defaultoption_.surface_ = utils.psurface_; - defaultoption_.isForShot_ = false; - ScreenId virtualScreenId = ScreenManager::GetInstance().CreateVirtualScreen(defaultoption_); - ASSERT_NE(SCREEN_ID_INVALID, virtualScreenId); + defaultOption_.surface_ = utils.psurface_; + defaultOption_.isForShot_ = false; + sptr screenListener = new ScreenChangeListener(); + sptr screenGroupChangeListener = new ScreenGroupChangeListener(); + ScreenManager::GetInstance().RegisterScreenListener(screenListener); + ScreenManager::GetInstance().RegisterScreenGroupListener(screenGroupChangeListener); + ScreenId virtualScreenId = ScreenManager::GetInstance().CreateVirtualScreen(defaultOption_); + ScreenId screenId = screenListener->connectFuture_.GetResult(TIME_OUT); + screenListener->connectFuture_.Reset(); + ASSERT_EQ(virtualScreenId, screenId); + std::vector> screens = ScreenManager::GetInstance().GetAllScreens(); + sptr DefaultScreen = screens.front(); + std::vector options = {{DefaultScreen->GetId(), 0, 0}, {virtualScreenId, defaultWidth_, 0}}; + ScreenId expansionId = ScreenManager::GetInstance().MakeExpand(options); + ASSERT_NE(SCREEN_ID_INVALID, expansionId); + auto pair = screenGroupChangeListener->changeFuture_.GetResult(TIME_OUT); + screenGroupChangeListener->changeFuture_.Reset(); + ASSERT_EQ(virtualScreenId, pair.first); + ASSERT_EQ(ScreenGroupChangeEvent::ADD_TO_GROUP, pair.second); + ASSERT_EQ(DMError::DM_OK, ScreenManager::GetInstance().DestroyVirtualScreen(virtualScreenId)); + screenId = screenListener->disconnectFuture_.GetResult(TIME_OUT); + screenListener->disconnectFuture_.Reset(); + ASSERT_EQ(virtualScreenId, screenId); + pair = screenGroupChangeListener->changeFuture_.GetResult(TIME_OUT); + screenGroupChangeListener->changeFuture_.Reset(); + ASSERT_EQ(virtualScreenId, pair.first); + ASSERT_EQ(ScreenGroupChangeEvent::REMOVE_FROM_GROUP, pair.second); + ScreenManager::GetInstance().UnregisterScreenListener(screenListener); + ScreenManager::GetInstance().UnregisterScreenGroupListener(screenGroupChangeListener); +} + +/** + * @tc.name: ScreenManager09 + * @tc.desc: Create a virtual screen as expansion of default screen, create windowNode on virtual screen, + * and destroy virtual screen + * @tc.type: FUNC + */ +HWTEST_F(ScreenManagerTest, ScreenManager09, Function | MediumTest | Level2) +{ + DisplayTestUtils utils; + ASSERT_TRUE(utils.CreateSurface()); + defaultOption_.surface_ = utils.psurface_; + defaultOption_.isForShot_ = false; + sptr screenListener = new ScreenChangeListener(); + sptr screenGroupChangeListener = new ScreenGroupChangeListener(); + ScreenManager::GetInstance().RegisterScreenListener(screenListener); + ScreenManager::GetInstance().RegisterScreenGroupListener(screenGroupChangeListener); + ScreenId virtualScreenId = ScreenManager::GetInstance().CreateVirtualScreen(defaultOption_); + ScreenId screenId = screenListener->connectFuture_.GetResult(TIME_OUT); + screenListener->connectFuture_.Reset(); + ASSERT_EQ(virtualScreenId, screenId); std::vector> screens = ScreenManager::GetInstance().GetAllScreens(); sptr DefaultScreen = screens.front(); DisplayId virtualDisplayId = DISPLAY_ID_INVALD; @@ -265,64 +373,311 @@ HWTEST_F(ScreenManagerTest, ScreenManager08, Function | MediumTest | Level2) virtualDisplayId = id; // find the display id of virtual screen } } - ASSERT_NE(DISPLAY_ID_INVALD, virtualDisplayId); sptr window = CreateWindowByDisplayId(virtualDisplayId); ASSERT_NE(nullptr, window); sleep(TEST_SPEEP_S); std::vector options = {{DefaultScreen->GetId(), 0, 0}, {virtualScreenId, defaultWidth_, 0}}; ScreenId expansionId = ScreenManager::GetInstance().MakeExpand(options); + auto pair = screenGroupChangeListener->changeFuture_.GetResult(TIME_OUT); + screenGroupChangeListener->changeFuture_.Reset(); + ASSERT_EQ(virtualScreenId, pair.first); + ASSERT_EQ(ScreenGroupChangeEvent::ADD_TO_GROUP, pair.second); sleep(TEST_SPEEP_S); ASSERT_NE(SCREEN_ID_INVALID, expansionId); ASSERT_EQ(DMError::DM_OK, ScreenManager::GetInstance().DestroyVirtualScreen(virtualScreenId)); + screenId = screenListener->disconnectFuture_.GetResult(TIME_OUT); + screenListener->disconnectFuture_.Reset(); + ASSERT_EQ(virtualScreenId, screenId); + pair = screenGroupChangeListener->changeFuture_.GetResult(TIME_OUT); + screenGroupChangeListener->changeFuture_.Reset(); + ASSERT_EQ(virtualScreenId, pair.first); + ASSERT_EQ(ScreenGroupChangeEvent::REMOVE_FROM_GROUP, pair.second); + ScreenManager::GetInstance().UnregisterScreenListener(screenListener); + ScreenManager::GetInstance().UnregisterScreenGroupListener(screenGroupChangeListener); sleep(TEST_SPEEP_S); window->Destroy(); // will add NotifyExpandDisconnect check logic. } -/** - * @tc.name: ScreenManager09 - * @tc.desc: Create a virtual screen and destroy it for 10 times, it's not for shot. - * @tc.type: FUNC - */ -HWTEST_F(ScreenManagerTest, ScreenManager09, Function | MediumTest | Level2) -{ - DisplayTestUtils utils; - ASSERT_TRUE(utils.CreateSurface()); - defaultoption_.surface_ = utils.psurface_; - defaultoption_.isForShot_ = false; - for (uint32_t i = 0; i < execTimes_; i++) { - ScreenId virtualScreenId = ScreenManager::GetInstance().CreateVirtualScreen(defaultoption_); - ASSERT_NE(SCREEN_ID_INVALID, virtualScreenId); - auto screen = ScreenManager::GetInstance().GetScreenById(virtualScreenId); - ASSERT_EQ(virtualScreenId, screen->GetId()); - ASSERT_EQ(SCREEN_ID_INVALID, screen->GetParentId()); - ASSERT_EQ(DMError::DM_OK, ScreenManager::GetInstance().DestroyVirtualScreen(virtualScreenId)); - } -} - /** * @tc.name: ScreenManager10 - * @tc.desc: Create a virtual screen , mirror and destroy it for 10 times, it's not for shot. + * @tc.desc: Create a virtual screen and destroy it for 10 times, it's not for shot. * @tc.type: FUNC */ HWTEST_F(ScreenManagerTest, ScreenManager10, Function | MediumTest | Level2) { DisplayTestUtils utils; ASSERT_TRUE(utils.CreateSurface()); - defaultoption_.surface_ = utils.psurface_; - defaultoption_.isForShot_ = false; + defaultOption_.surface_ = utils.psurface_; + defaultOption_.isForShot_ = false; + sptr screenListener = new ScreenChangeListener(); + for (uint32_t i = 0; i < execTimes_; i++) { + ScreenManager::GetInstance().RegisterScreenListener(screenListener); + ScreenId virtualScreenId = ScreenManager::GetInstance().CreateVirtualScreen(defaultOption_); + ASSERT_NE(SCREEN_ID_INVALID, virtualScreenId); + ScreenId screenId = screenListener->connectFuture_.GetResult(TIME_OUT); + screenListener->connectFuture_.Reset(); + ASSERT_EQ(virtualScreenId, screenId); + auto screen = ScreenManager::GetInstance().GetScreenById(virtualScreenId); + ASSERT_EQ(virtualScreenId, screen->GetId()); + ASSERT_EQ(SCREEN_ID_INVALID, screen->GetParentId()); + ASSERT_EQ(DMError::DM_OK, ScreenManager::GetInstance().DestroyVirtualScreen(virtualScreenId)); + screenId = screenListener->disconnectFuture_.GetResult(TIME_OUT); + screenListener->disconnectFuture_.Reset(); + ASSERT_EQ(virtualScreenId, screenId); + ScreenManager::GetInstance().UnregisterScreenListener(screenListener); + } +} + +/** + * @tc.name: ScreenManager11 + * @tc.desc: Create a virtual screen , mirror and destroy it for 10 times, it's not for shot. + * @tc.type: FUNC + */ +HWTEST_F(ScreenManagerTest, ScreenManager11, Function | MediumTest | Level2) +{ + DisplayTestUtils utils; + ASSERT_TRUE(utils.CreateSurface()); + defaultOption_.surface_ = utils.psurface_; + defaultOption_.isForShot_ = false; + sptr screenListener = new ScreenChangeListener(); + sptr screenGroupChangeListener = new ScreenGroupChangeListener(); for (uint32_t i = 0; i < 10; i++) { - ScreenId virtualScreenId = ScreenManager::GetInstance().CreateVirtualScreen(defaultoption_); + ScreenManager::GetInstance().RegisterScreenListener(screenListener); + ScreenManager::GetInstance().RegisterScreenGroupListener(screenGroupChangeListener); + ScreenId virtualScreenId = ScreenManager::GetInstance().CreateVirtualScreen(defaultOption_); + ASSERT_NE(SCREEN_ID_INVALID, virtualScreenId); + ScreenId screenId = screenListener->connectFuture_.GetResult(TIME_OUT); + screenListener->connectFuture_.Reset(); + ASSERT_EQ(virtualScreenId, screenId); std::vector mirrorIds; mirrorIds.push_back(virtualScreenId); ScreenManager::GetInstance().MakeMirror(defaultScreenId_, mirrorIds); - ASSERT_NE(SCREEN_ID_INVALID, virtualScreenId); + auto pair = screenGroupChangeListener->changeFuture_.GetResult(TIME_OUT); + screenGroupChangeListener->changeFuture_.Reset(); + ASSERT_EQ(virtualScreenId, pair.first); + ASSERT_EQ(ScreenGroupChangeEvent::ADD_TO_GROUP, pair.second); auto screen = ScreenManager::GetInstance().GetScreenById(virtualScreenId); ASSERT_EQ(virtualScreenId, screen->GetId()); ASSERT_NE(SCREEN_ID_INVALID, screen->GetParentId()); ASSERT_EQ(DMError::DM_OK, ScreenManager::GetInstance().DestroyVirtualScreen(virtualScreenId)); + screenId = screenListener->disconnectFuture_.GetResult(TIME_OUT); + screenListener->disconnectFuture_.Reset(); + ASSERT_EQ(virtualScreenId, screenId); + pair = screenGroupChangeListener->changeFuture_.GetResult(TIME_OUT); + screenGroupChangeListener->changeFuture_.Reset(); + ASSERT_EQ(virtualScreenId, pair.first); + ASSERT_EQ(ScreenGroupChangeEvent::REMOVE_FROM_GROUP, pair.second); + ScreenManager::GetInstance().UnregisterScreenListener(screenListener); + ScreenManager::GetInstance().UnregisterScreenGroupListener(screenGroupChangeListener); } } + +/** + * @tc.name: ScreenManager12 + * @tc.desc: Create a virtual screen as expansion of default screen cancel Make mirror, and destroy virtual screen + * @tc.type: FUNC + */ +HWTEST_F(ScreenManagerTest, ScreenManager12, Function | MediumTest | Level2) +{ + DisplayTestUtils utils; + ASSERT_TRUE(utils.CreateSurface()); + defaultOption_.surface_ = utils.psurface_; + defaultOption_.isForShot_ = false; + sptr screenListener = new ScreenChangeListener(); + sptr screenGroupChangeListener = new ScreenGroupChangeListener(); + ScreenManager::GetInstance().RegisterScreenListener(screenListener); + ScreenManager::GetInstance().RegisterScreenGroupListener(screenGroupChangeListener); + ScreenId virtualScreenId = ScreenManager::GetInstance().CreateVirtualScreen(defaultOption_); + ASSERT_NE(SCREEN_ID_INVALID, virtualScreenId); + ScreenId screenId = screenListener->connectFuture_.GetResult(TIME_OUT); + screenListener->connectFuture_.Reset(); + ASSERT_EQ(virtualScreenId, screenId); + + std::vector mirrorIds; + mirrorIds.push_back(virtualScreenId); + ScreenManager::GetInstance().MakeMirror(defaultScreenId_, mirrorIds); + auto pair = screenGroupChangeListener->changeFuture_.GetResult(TIME_OUT); + screenGroupChangeListener->changeFuture_.Reset(); + ASSERT_EQ(virtualScreenId, pair.first); + ASSERT_EQ(ScreenGroupChangeEvent::ADD_TO_GROUP, pair.second); + auto screen = ScreenManager::GetInstance().GetScreenById(virtualScreenId); + ASSERT_EQ(virtualScreenId, screen->GetId()); + ASSERT_NE(SCREEN_ID_INVALID, screen->GetParentId()); + + ScreenManager::GetInstance().RemoveVirtualScreenFromGroup(mirrorIds); + pair = screenGroupChangeListener->changeFuture_.GetResult(TIME_OUT); + screenGroupChangeListener->changeFuture_.Reset(); + ASSERT_EQ(virtualScreenId, pair.first); + ASSERT_EQ(ScreenGroupChangeEvent::REMOVE_FROM_GROUP, pair.second); + + ASSERT_EQ(DMError::DM_OK, ScreenManager::GetInstance().DestroyVirtualScreen(virtualScreenId)); + screenId = screenListener->disconnectFuture_.GetResult(TIME_OUT); + screenListener->disconnectFuture_.Reset(); + ASSERT_EQ(virtualScreenId, screenId); + ScreenManager::GetInstance().UnregisterScreenListener(screenListener); + ScreenManager::GetInstance().UnregisterScreenGroupListener(screenGroupChangeListener); +} + +/** + * @tc.name: ScreenManager13 + * @tc.desc: Create a virtual screen as expansion of default screen cancel MakeExpand, and destroy virtual screen + * @tc.type: FUNC + */ +HWTEST_F(ScreenManagerTest, ScreenManager13, Function | MediumTest | Level2) +{ + DisplayTestUtils utils; + ASSERT_TRUE(utils.CreateSurface()); + defaultOption_.surface_ = utils.psurface_; + defaultOption_.isForShot_ = false; + sptr screenListener = new ScreenChangeListener(); + sptr screenGroupChangeListener = new ScreenGroupChangeListener(); + ScreenManager::GetInstance().RegisterScreenListener(screenListener); + ScreenManager::GetInstance().RegisterScreenGroupListener(screenGroupChangeListener); + ScreenId virtualScreenId = ScreenManager::GetInstance().CreateVirtualScreen(defaultOption_); + ScreenId screenId = screenListener->connectFuture_.GetResult(TIME_OUT); + screenListener->connectFuture_.Reset(); + ASSERT_EQ(virtualScreenId, screenId); + + std::vector> screens = ScreenManager::GetInstance().GetAllScreens(); + sptr DefaultScreen = screens.front(); + std::vector options = {{DefaultScreen->GetId(), 0, 0}, {virtualScreenId, defaultWidth_, 0}}; + ScreenId expansionId = ScreenManager::GetInstance().MakeExpand(options); + ASSERT_NE(SCREEN_ID_INVALID, expansionId); + auto pair = screenGroupChangeListener->changeFuture_.GetResult(TIME_OUT); + screenGroupChangeListener->changeFuture_.Reset(); + ASSERT_EQ(virtualScreenId, pair.first); + ASSERT_EQ(ScreenGroupChangeEvent::ADD_TO_GROUP, pair.second); + + std::vector cancelScreens; + cancelScreens.emplace_back(virtualScreenId); + ScreenManager::GetInstance().RemoveVirtualScreenFromGroup(cancelScreens); + pair = screenGroupChangeListener->changeFuture_.GetResult(TIME_OUT); + screenGroupChangeListener->changeFuture_.Reset(); + ASSERT_EQ(virtualScreenId, pair.first); + ASSERT_EQ(ScreenGroupChangeEvent::REMOVE_FROM_GROUP, pair.second); + + ASSERT_EQ(DMError::DM_OK, ScreenManager::GetInstance().DestroyVirtualScreen(virtualScreenId)); + screenId = screenListener->disconnectFuture_.GetResult(TIME_OUT); + screenListener->disconnectFuture_.Reset(); + ASSERT_EQ(virtualScreenId, screenId); + ScreenManager::GetInstance().UnregisterScreenListener(screenListener); + ScreenManager::GetInstance().UnregisterScreenGroupListener(screenGroupChangeListener); +} + +/** + * @tc.name: ScreenManager14 + * @tc.desc: Create a virtual screen, make expand to make mirror, and destroy virtual screen + * @tc.type: FUNC + */ +HWTEST_F(ScreenManagerTest, ScreenManager14, Function | MediumTest | Level2) +{ + DisplayTestUtils utils; + ASSERT_TRUE(utils.CreateSurface()); + defaultOption_.surface_ = utils.psurface_; + defaultOption_.isForShot_ = false; + sptr screenListener = new ScreenChangeListener(); + sptr screenGroupChangeListener = new ScreenGroupChangeListener(); + ScreenManager::GetInstance().RegisterScreenListener(screenListener); + ScreenManager::GetInstance().RegisterScreenGroupListener(screenGroupChangeListener); + ScreenId virtualScreenId = ScreenManager::GetInstance().CreateVirtualScreen(defaultOption_); + ScreenId screenId = screenListener->connectFuture_.GetResult(TIME_OUT); + screenListener->connectFuture_.Reset(); + ASSERT_EQ(virtualScreenId, screenId); + + std::vector> screens = ScreenManager::GetInstance().GetAllScreens(); + sptr DefaultScreen = screens.front(); + std::vector options = {{DefaultScreen->GetId(), 0, 0}, {virtualScreenId, defaultWidth_, 0}}; + ScreenId expansionId = ScreenManager::GetInstance().MakeExpand(options); + ASSERT_NE(SCREEN_ID_INVALID, expansionId); + auto pair = screenGroupChangeListener->changeFuture_.GetResult(TIME_OUT); + screenGroupChangeListener->changeFuture_.Reset(); + ASSERT_EQ(virtualScreenId, pair.first); + ASSERT_EQ(ScreenGroupChangeEvent::ADD_TO_GROUP, pair.second); + + std::vector mirrorScreens; + mirrorScreens.emplace_back(virtualScreenId); + ScreenManager::GetInstance().MakeMirror(defaultScreenId_, mirrorScreens); + pair = screenGroupChangeListener->changeFuture_.GetResult(TIME_OUT); + screenGroupChangeListener->changeFuture_.Reset(); + ASSERT_EQ(virtualScreenId, pair.first); + ASSERT_EQ(ScreenGroupChangeEvent::CHANGE_GROUP, pair.second); + + ASSERT_EQ(DMError::DM_OK, ScreenManager::GetInstance().DestroyVirtualScreen(virtualScreenId)); + screenId = screenListener->disconnectFuture_.GetResult(TIME_OUT); + screenListener->disconnectFuture_.Reset(); + ASSERT_EQ(virtualScreenId, screenId); + ScreenManager::GetInstance().UnregisterScreenListener(screenListener); + ScreenManager::GetInstance().UnregisterScreenGroupListener(screenGroupChangeListener); +} + +/** + * @tc.name: ScreenManager15 + * @tc.desc: Create a virtual screen, make mirror to make expand, and destroy virtual screen + * @tc.type: FUNC + */ +HWTEST_F(ScreenManagerTest, ScreenManager15, Function | MediumTest | Level2) +{ + DisplayTestUtils utils; + ASSERT_TRUE(utils.CreateSurface()); + defaultOption_.surface_ = utils.psurface_; + defaultOption_.isForShot_ = false; + sptr screenListener = new ScreenChangeListener(); + sptr screenGroupChangeListener = new ScreenGroupChangeListener(); + ScreenManager::GetInstance().RegisterScreenListener(screenListener); + ScreenManager::GetInstance().RegisterScreenGroupListener(screenGroupChangeListener); + ScreenId virtualScreenId = ScreenManager::GetInstance().CreateVirtualScreen(defaultOption_); + ScreenId screenId = screenListener->connectFuture_.GetResult(TIME_OUT); + screenListener->connectFuture_.Reset(); + ASSERT_EQ(virtualScreenId, screenId); + + std::vector mirrorScreens; + mirrorScreens.emplace_back(virtualScreenId); + ScreenManager::GetInstance().MakeMirror(defaultScreenId_, mirrorScreens); + auto pair = screenGroupChangeListener->changeFuture_.GetResult(TIME_OUT); + screenGroupChangeListener->changeFuture_.Reset(); + ASSERT_EQ(virtualScreenId, pair.first); + ASSERT_EQ(ScreenGroupChangeEvent::ADD_TO_GROUP, pair.second); + + std::vector> screens = ScreenManager::GetInstance().GetAllScreens(); + sptr DefaultScreen = screens.front(); + std::vector options = {{DefaultScreen->GetId(), 0, 0}, {virtualScreenId, defaultWidth_, 0}}; + ScreenId expansionId = ScreenManager::GetInstance().MakeExpand(options); + ASSERT_NE(SCREEN_ID_INVALID, expansionId); + pair = screenGroupChangeListener->changeFuture_.GetResult(TIME_OUT); + screenGroupChangeListener->changeFuture_.Reset(); + ASSERT_EQ(virtualScreenId, pair.first); + ASSERT_EQ(ScreenGroupChangeEvent::CHANGE_GROUP, pair.second); + + ASSERT_EQ(DMError::DM_OK, ScreenManager::GetInstance().DestroyVirtualScreen(virtualScreenId)); + screenId = screenListener->disconnectFuture_.GetResult(TIME_OUT); + screenListener->disconnectFuture_.Reset(); + ASSERT_EQ(virtualScreenId, screenId); + ScreenManager::GetInstance().UnregisterScreenListener(screenListener); + ScreenManager::GetInstance().UnregisterScreenGroupListener(screenGroupChangeListener); +} + +/** + * @tc.name: ScreenManager16 + * @tc.desc: Screen orientation. + * @tc.type: FUNC + */ +HWTEST_F(ScreenManagerTest, ScreenManager16, Function | MediumTest | Level2) +{ + auto screens = ScreenManager::GetInstance().GetAllScreens(); + auto display = DisplayManager::GetInstance().GetDefaultDisplay(); + uint32_t orientation = static_cast(Orientation::VERTICAL); + uint32_t end = static_cast(Orientation::REVERSE_HORIZONTAL); + for (; orientation <= end; ++orientation) { + screens[0]->SetOrientation(static_cast(orientation)); + usleep(1E6); + ASSERT_EQ(static_cast(screens[0]->GetOrientation()), orientation); + ASSERT_EQ(static_cast(display->GetOrientation()), orientation); + } + screens[0]->SetOrientation(Orientation::UNSPECIFIED); + ASSERT_EQ(static_cast(screens[0]->GetOrientation()), static_cast(Orientation::UNSPECIFIED)); + ASSERT_EQ(static_cast(display->GetOrientation()), static_cast(Orientation::UNSPECIFIED)); +} } } // namespace Rosen } // namespace OHOS diff --git a/dm/test/systemtest/screenshot_cmd_test.cpp b/dm/test/systemtest/screenshot_cmd_test.cpp index 8031aa09..b4822e6d 100644 --- a/dm/test/systemtest/screenshot_cmd_test.cpp +++ b/dm/test/systemtest/screenshot_cmd_test.cpp @@ -19,6 +19,8 @@ #include "display_test_utils.h" #include "pixel_map.h" +#include "snapshot_utils.h" + using namespace testing; using namespace testing::ext; @@ -37,7 +39,7 @@ public: static DisplayId defaultId_; DisplayId invalidId_ = DISPLAY_ID_INVALD; const std::string defaultCmd_ = "/system/bin/snapshot_display"; - const std::string defaultImg_ = "/data/snapshot_display_1.png"; + const int testTimeCount_ = 2; }; DisplayId ScreenshotCmdTest::defaultId_ = DISPLAY_ID_INVALD; @@ -87,15 +89,26 @@ namespace { */ HWTEST_F(ScreenshotCmdTest, ScreenShotCmdValid01, Function | MediumTest | Level2) { - if (CheckFileExist(defaultImg_)) { - remove(defaultImg_.c_str()); + std::string imgPath[testTimeCount_]; + int i; + + for (i = 0; i < testTimeCount_; i++) { + imgPath[i] = SnapShotUtils::GenerateFileName(i); + if (CheckFileExist(imgPath[i])) { + remove(imgPath[i].c_str()); + } } + (void)system(defaultCmd_.c_str()); - bool isExist = CheckFileExist(defaultImg_); - if (isExist) { - remove(defaultImg_.c_str()); + + for (i = 0; i < testTimeCount_; i++) { + if (CheckFileExist(imgPath[i])) { // ok + remove(imgPath[i].c_str()); + ASSERT_TRUE(true); + return; + } } - ASSERT_EQ(true, isExist); + ADD_FAILURE(); // fail, can't find snapshot file } /** @@ -105,16 +118,27 @@ HWTEST_F(ScreenshotCmdTest, ScreenShotCmdValid01, Function | MediumTest | Level2 */ HWTEST_F(ScreenshotCmdTest, ScreenShotCmdValid02, Function | MediumTest | Level2) { - if (CheckFileExist(defaultImg_)) { - remove(defaultImg_.c_str()); + std::string imgPath[testTimeCount_]; + int i; + + for (i = 0; i < testTimeCount_; i++) { + imgPath[i] = SnapShotUtils::GenerateFileName(i); + if (CheckFileExist(imgPath[i])) { + remove(imgPath[i].c_str()); + } } + const std::string cmd = defaultCmd_ + " -i " + std::to_string(defaultId_); (void)system(cmd.c_str()); - bool isExist = CheckFileExist(defaultImg_); - if (isExist) { - remove(defaultImg_.c_str()); + + for (i = 0; i < testTimeCount_; i++) { + if (CheckFileExist(imgPath[i])) { // ok + remove(imgPath[i].c_str()); + ASSERT_TRUE(true); + return; + } } - ASSERT_EQ(true, isExist); + ADD_FAILURE(); // fail, can't find snapshot file } /** diff --git a/dm/test/unittest/display_change_unit_test.cpp b/dm/test/unittest/display_change_unit_test.cpp index 88dbfc08..bb6eb5b6 100644 --- a/dm/test/unittest/display_change_unit_test.cpp +++ b/dm/test/unittest/display_change_unit_test.cpp @@ -37,7 +37,7 @@ public: virtual void OnDestroy(DisplayId displayId) {} - virtual void OnChange(DisplayId displayId, DisplayChangeEvent event) {} + virtual void OnChange(DisplayId displayId) {} }; class DisplayChangeUnitTest : public testing::Test { diff --git a/dm/test/unittest/display_power_unit_test.cpp b/dm/test/unittest/display_power_unit_test.cpp index 6ecca2c4..fdabe9fc 100644 --- a/dm/test/unittest/display_power_unit_test.cpp +++ b/dm/test/unittest/display_power_unit_test.cpp @@ -39,7 +39,7 @@ public: static inline sptr listener_ = new DisplayPowerEventListener(); static inline DisplayId defaultId_ = 0; static inline uint32_t brightnessLevel_ = 80; - static inline uint32_t invalidBrightnessLevel_ = 10000000; + static inline uint32_t invalidBrightnessLevel_ = 1000000000; static inline DisplayPowerState initialPowerState_; static inline DisplayState initialState_; }; diff --git a/dm/test/unittest/mock_display_manager_adapter.h b/dm/test/unittest/mock_display_manager_adapter.h index 97dbef49..d83cfaeb 100644 --- a/dm/test/unittest/mock_display_manager_adapter.h +++ b/dm/test/unittest/mock_display_manager_adapter.h @@ -23,25 +23,44 @@ namespace OHOS { namespace Rosen { class MockDisplayManagerAdapter : public DisplayManagerAdapter { public: - MOCK_METHOD0(GetDefaultDisplayId, DisplayId()); - MOCK_METHOD1(GetDisplayById, sptr(DisplayId displayId)); - MOCK_METHOD1(CreateVirtualScreen, ScreenId(VirtualScreenOption option)); - MOCK_METHOD1(DestroyVirtualScreen, DMError(ScreenId screenId)); - MOCK_METHOD1(GetDisplaySnapshot, std::shared_ptr(DisplayId displayId)); MOCK_METHOD0(Clear, void()); MOCK_METHOD2(RegisterDisplayManagerAgent, bool(const sptr& displayManagerAgent, DisplayManagerAgentType type)); MOCK_METHOD2(UnregisterDisplayManagerAgent, bool(const sptr& displayManagerAgent, DisplayManagerAgentType type)); + MOCK_METHOD0(GetDefaultDisplayId, DisplayId()); + MOCK_METHOD1(GetDisplayInfoByScreenId, sptr(ScreenId screenId)); + MOCK_METHOD1(GetDisplaySnapshot, std::shared_ptr(DisplayId displayId)); + MOCK_METHOD1(WakeUpBegin, bool(PowerStateChangeReason reason)); MOCK_METHOD0(WakeUpEnd, bool()); MOCK_METHOD1(SuspendBegin, bool(PowerStateChangeReason reason)); MOCK_METHOD0(SuspendEnd, bool()); MOCK_METHOD2(SetScreenPowerForAll, bool(DisplayPowerState state, PowerStateChangeReason reason)); MOCK_METHOD1(SetDisplayState, bool(DisplayState state)); - MOCK_METHOD1(GetDisplayState, DisplayState(uint64_t displayId)); + MOCK_METHOD1(GetDisplayState, DisplayState(DisplayId displayId)); + MOCK_METHOD1(NotifyDisplayEvent, void(DisplayEvent event)); + MOCK_METHOD1(GetDisplayInfo, sptr(DisplayId displayId)); +}; + +class MockScreenManagerAdapter : public ScreenManagerAdapter { +public: + MOCK_METHOD0(Clear, void()); + MOCK_METHOD2(RegisterDisplayManagerAgent, bool(const sptr& displayManagerAgent, + DisplayManagerAgentType type)); + MOCK_METHOD2(UnregisterDisplayManagerAgent, bool(const sptr& displayManagerAgent, + DisplayManagerAgentType type)); + MOCK_METHOD2(RequestRotation, bool(ScreenId screenId, Rotation rotation)); + MOCK_METHOD1(CreateVirtualScreen, ScreenId(VirtualScreenOption option)); + MOCK_METHOD1(DestroyVirtualScreen, DMError(ScreenId screenId)); + MOCK_METHOD2(SetVirtualScreenSurface, DMError(ScreenId screenId, sptr surface)); + MOCK_METHOD1(GetScreenGroupInfoById, sptr(ScreenId screenId)); + MOCK_METHOD0(GetAllScreenInfos, std::vector>()); + MOCK_METHOD2(MakeMirror, ScreenId(ScreenId mainScreenId, std::vector mirrorScreenId)); + MOCK_METHOD2(MakeExpand, ScreenId(std::vector screenId, std::vector startPoint)); MOCK_METHOD2(SetScreenActiveMode, bool(ScreenId screenId, uint32_t modeId)); - MOCK_METHOD2(MakeExpand, DMError(std::vector screenId, std::vector startPoint)); + MOCK_METHOD1(GetScreenInfo, sptr(ScreenId screenId)); + MOCK_METHOD2(GetScreenSupportedColorGamuts, DMError(ScreenId screenId, std::vector& colorGamuts)); MOCK_METHOD2(GetScreenColorGamut, DMError(ScreenId screenId, ScreenColorGamut& colorGamut)); MOCK_METHOD2(SetScreenColorGamut, DMError(ScreenId screenId, int32_t colorGamutIdx)); diff --git a/dm/test/unittest/screen_manager_test.cpp b/dm/test/unittest/screen_manager_test.cpp index a84cce9b..ab74bfce 100644 --- a/dm/test/unittest/screen_manager_test.cpp +++ b/dm/test/unittest/screen_manager_test.cpp @@ -22,7 +22,7 @@ using namespace testing::ext; namespace OHOS { namespace Rosen { -using Mocker = SingletonMocker; +using Mocker = SingletonMocker; sptr ScreenManagerTest::defaultDisplay_ = nullptr; DisplayId ScreenManagerTest::defaultDisplayId_ = DISPLAY_ID_INVALD; @@ -105,7 +105,7 @@ HWTEST_F(ScreenManagerTest, MakeExpand_001, Function | SmallTest | Level1) std::unique_ptr m = std::make_unique(); EXPECT_CALL(m->Mock(), CreateVirtualScreen(_)).Times(1).WillOnce(Return(virtualScreenId)); EXPECT_CALL(m->Mock(), DestroyVirtualScreen(_)).Times(1).WillOnce(Return(DMError::DM_OK)); - EXPECT_CALL(m->Mock(), MakeExpand(_, _)).Times(1).WillOnce(Return(DMError::DM_OK)); + EXPECT_CALL(m->Mock(), MakeExpand(_, _)).Times(1).WillOnce(Return(0)); ScreenId vScreenId = ScreenManager::GetInstance().CreateVirtualScreen(defaultOption); std::vector options = {{validId, 0, 0}, {vScreenId, defaultWidth_, 0}}; ScreenId expansionId = ScreenManager::GetInstance().MakeExpand(options); @@ -123,12 +123,57 @@ HWTEST_F(ScreenManagerTest, MakeExpand_001, Function | SmallTest | Level1) HWTEST_F(ScreenManagerTest, MakeExpand_002, Function | SmallTest | Level1) { ScreenId invalidId = SCREEN_ID_INVALID; - std::unique_ptr m = std::make_unique(); - EXPECT_CALL(m->Mock(), MakeExpand(_, _)).Times(1).WillOnce(Return(DMError::DM_ERROR_INVALID_PARAM)); std::vector options = {}; ScreenId expansionId = ScreenManager::GetInstance().MakeExpand(options); ASSERT_EQ(expansionId, invalidId); } + +/** + * @tc.name: SetSurface01 + * @tc.desc: SetVirtualScreenSurface with valid option and return success + * @tc.type: FUNC + */ +HWTEST_F(ScreenManagerTest, SetSurface01, Function | SmallTest | Level1) +{ + ScreenManagerUtils utils; + ASSERT_TRUE(utils.CreateSurface()); + VirtualScreenOption defaultOption = {defaultName_, defaultWidth_, defaultHeight_, + defaultDensity_, nullptr, defaultFlags_}; + ScreenId validId = 0; + std::unique_ptr m = std::make_unique(); + EXPECT_CALL(m->Mock(), CreateVirtualScreen(_)).Times(1).WillOnce(Return(validId)); + EXPECT_CALL(m->Mock(), SetVirtualScreenSurface(_, _)).Times(1).WillOnce(Return(DMError::DM_OK)); + EXPECT_CALL(m->Mock(), DestroyVirtualScreen(_)).Times(1).WillOnce(Return(DMError::DM_OK)); + ScreenId id = ScreenManager::GetInstance().CreateVirtualScreen(defaultOption); + DMError surfaceRes = ScreenManager::GetInstance().SetVirtualScreenSurface(id, utils.psurface_); + DMError destroyRes = ScreenManager::GetInstance().DestroyVirtualScreen(id); + ASSERT_EQ(validId, id); + ASSERT_EQ(DMError::DM_OK, surfaceRes); + ASSERT_EQ(DMError::DM_OK, destroyRes); +} + +/** + * @tc.name: SetSurface02 + * @tc.desc: SetVirtualScreenSurface with invalid option and return failed + * @tc.type: FUNC + */ +HWTEST_F(ScreenManagerTest, SetSurface02, Function | SmallTest | Level1) +{ + ScreenManagerUtils utils; + ASSERT_TRUE(utils.CreateSurface()); + VirtualScreenOption defaultOption = {defaultName_, defaultWidth_, defaultHeight_, + defaultDensity_, nullptr, defaultFlags_}; + std::unique_ptr m = std::make_unique(); + EXPECT_CALL(m->Mock(), CreateVirtualScreen(_)).Times(1).WillOnce(Return(SCREEN_ID_INVALID)); + EXPECT_CALL(m->Mock(), SetVirtualScreenSurface(_, _)).Times(1).WillOnce(Return(DMError::DM_ERROR_INVALID_PARAM)); + EXPECT_CALL(m->Mock(), DestroyVirtualScreen(_)).Times(1).WillOnce(Return(DMError::DM_ERROR_INVALID_PARAM)); + ScreenId id = ScreenManager::GetInstance().CreateVirtualScreen(defaultOption); + DMError surfaceRes = ScreenManager::GetInstance().SetVirtualScreenSurface(id, utils.psurface_); + DMError destroyRes = ScreenManager::GetInstance().DestroyVirtualScreen(id); + ASSERT_EQ(SCREEN_ID_INVALID, id); + ASSERT_EQ(DMError::DM_ERROR_INVALID_PARAM, surfaceRes); + ASSERT_EQ(DMError::DM_ERROR_INVALID_PARAM, destroyRes); +} } } // namespace Rosen } // namespace OHOS \ No newline at end of file diff --git a/dm/test/unittest/screen_test.cpp b/dm/test/unittest/screen_test.cpp index 23086993..e6aebea0 100644 --- a/dm/test/unittest/screen_test.cpp +++ b/dm/test/unittest/screen_test.cpp @@ -22,7 +22,7 @@ using namespace testing::ext; namespace OHOS { namespace Rosen { -using Mocker = SingletonMocker; +using Mocker = SingletonMocker; sptr ScreenTest::defaultDisplay_ = nullptr; ScreenId ScreenTest::defaultScreenId_ = SCREEN_ID_INVALID; diff --git a/dmserver/include/abstract_display.h b/dmserver/include/abstract_display.h index bfd4e03c..dd809596 100644 --- a/dmserver/include/abstract_display.h +++ b/dmserver/include/abstract_display.h @@ -28,7 +28,7 @@ public: constexpr static int32_t DEFAULT_HIGHT = 1280; constexpr static float DEFAULT_VIRTUAL_PIXEL_RATIO = 1.0; constexpr static uint32_t DEFAULT_FRESH_RATE = 60; - AbstractDisplay(const DisplayInfo& info); + AbstractDisplay(const DisplayInfo* info); AbstractDisplay(DisplayId id, ScreenId screenId, int32_t width, int32_t height, uint32_t freshRate); ~AbstractDisplay() = default; static inline bool IsVertical(Rotation rotation) @@ -43,14 +43,16 @@ public: ScreenId GetAbstractScreenId() const; bool BindAbstractScreen(ScreenId dmsScreenId); bool BindAbstractScreen(sptr abstractDisplay); - const sptr ConvertToDisplayInfo() const; + sptr ConvertToDisplayInfo() const; void SetId(DisplayId displayId); void SetWidth(int32_t width); void SetHeight(int32_t height); void SetFreshRate(uint32_t freshRate); void SetVirtualPixelRatio(float virtualPixelRatio); + void SetOrientation(Orientation orientation); bool RequestRotation(Rotation rotation); + Rotation GetRotation(); private: DisplayId id_ { DISPLAY_ID_INVALD }; @@ -60,6 +62,7 @@ private: uint32_t freshRate_ { 0 }; float virtualPixelRatio_ { 1.0 }; Rotation rotation_ { Rotation::ROTATION_0 }; + Orientation orientation_ { Orientation::UNSPECIFIED }; }; } // namespace OHOS::Rosen #endif // FOUNDATION_DMSERVER_ABSTRACT_DISPLAY_H \ No newline at end of file diff --git a/dmserver/include/abstract_display_controller.h b/dmserver/include/abstract_display_controller.h index f57fb987..5f664170 100644 --- a/dmserver/include/abstract_display_controller.h +++ b/dmserver/include/abstract_display_controller.h @@ -40,19 +40,21 @@ public: std::shared_ptr GetScreenSnapshot(DisplayId displayId); sptr GetAbstractDisplay(DisplayId displayId) const; + sptr GetAbstractDisplayByScreen(ScreenId screenId) const; + std::vector GetAllDisplayIds() const; void AddDisplayForExpandScreen(sptr absScreen); private: void OnAbstractScreenConnect(sptr absScreen); void OnAbstractScreenDisconnect(sptr absScreen); void OnAbstractScreenChange(sptr absScreen, DisplayChangeEvent event); - void ProcessDisplayUpdateRotation(sptr absScreen); + void ProcessDisplayUpdateOrientation(sptr absScreen); void ProcessDisplaySizeChange(sptr absScreen); void BindAloneScreenLocked(sptr absScreen); void AddScreenToMirrorLocked(sptr absScreen); void AddScreenToExpandLocked(sptr absScreen); - void ProcessNormalScreenDisconnected(sptr absScreen, sptr screenGroup); - void ProcessExpandScreenDisconnected(sptr absScreen, sptr screenGroup); + DisplayId ProcessNormalScreenDisconnected(sptr absScreen, sptr screenGroup); + DisplayId ProcessExpandScreenDisconnected(sptr absScreen, sptr screenGroup); bool UpdateDisplaySize(sptr absDisplay, sptr info); std::recursive_mutex& mutex_; diff --git a/dmserver/include/abstract_screen.h b/dmserver/include/abstract_screen.h index c89d392d..5a821818 100644 --- a/dmserver/include/abstract_screen.h +++ b/dmserver/include/abstract_screen.h @@ -30,25 +30,19 @@ #include "screen_info.h" namespace OHOS::Rosen { -enum class ScreenType : uint32_t { - UNDEFINE, - REAL, - VIRTUAL -}; - class AbstractScreenGroup; class AbstractScreenController; class AbstractScreen : public RefBase { public: - AbstractScreen(ScreenId dmsId, ScreenId rsId); + AbstractScreen(const std::string& name, ScreenId dmsId, ScreenId rsId); AbstractScreen() = delete; ~AbstractScreen(); sptr GetActiveScreenMode() const; std::vector> GetAbstractScreenModes() const; sptr GetGroup() const; - const sptr ConvertToScreenInfo() const; - void RequestRotation(Rotation rotation); - Rotation GetRotation() const; + sptr ConvertToScreenInfo() const; + bool SetOrientation(Orientation orientation); + Rotation CalcRotation(Orientation orientation) const; void UpdateRSTree(std::shared_ptr& surfaceNode, bool isAdd); void InitRSDisplayNode(RSDisplayNodeConfig& config); @@ -61,16 +55,18 @@ public: DMError SetScreenGamutMap(ScreenGamutMap gamutMap); DMError SetScreenColorTransform(); + const std::string name_; ScreenId dmsId_; ScreenId rsId_; bool canHasChild_ { false }; std::shared_ptr rsDisplayNode_; RSDisplayNodeConfig rSDisplayNodeConfig_; - ScreenId groupDmsId_ {INVALID_SCREEN_ID}; + ScreenId groupDmsId_ { SCREEN_ID_INVALID }; ScreenType type_ { ScreenType::REAL }; int32_t activeIdx_ { 0 }; - float virtualPixelRatio = { 1.0 }; std::vector> modes_ = {}; + float virtualPixelRatio = { 1.0 }; + Orientation orientation_ { Orientation::UNSPECIFIED }; Rotation rotation_ { Rotation::ROTATION_0 }; protected: void FillScreenInfo(sptr) const; @@ -90,11 +86,11 @@ public: std::vector> GetChildren() const; std::vector GetChildrenPosition() const; size_t GetChildCount() const; - const sptr ConvertToScreenGroupInfo() const; + sptr ConvertToScreenGroupInfo() const; bool SetRSDisplayNodeConfig(sptr& dmsScreen, struct RSDisplayNodeConfig& config); ScreenCombination combination_ { ScreenCombination::SCREEN_ALONE }; - ScreenId mirrorScreenId_ {INVALID_SCREEN_ID}; + ScreenId mirrorScreenId_ { SCREEN_ID_INVALID }; private: std::map, Point>> abstractScreenMap_; diff --git a/dmserver/include/abstract_screen_controller.h b/dmserver/include/abstract_screen_controller.h index 4de2b39f..937c238c 100644 --- a/dmserver/include/abstract_screen_controller.h +++ b/dmserver/include/abstract_screen_controller.h @@ -49,21 +49,22 @@ public: std::vector GetAllExpandOrMirrorScreenIds(std::vector) const; sptr GetAbstractScreenGroup(ScreenId dmsScreenId); ScreenId GetDefaultAbstractScreenId(); + ScreenId GetDefaultScreenId() const; // save default screenID got by GetDefaultAbstractScreenId as cache ScreenId ConvertToRsScreenId(ScreenId dmsScreenId); ScreenId ConvertToDmsScreenId(ScreenId rsScreenId); void RegisterAbstractScreenCallback(sptr cb); ScreenId CreateVirtualScreen(VirtualScreenOption option); DMError DestroyVirtualScreen(ScreenId screenId); DMError SetVirtualScreenSurface(ScreenId screenId, sptr surface); - bool RequestRotation(ScreenId screenId, Rotation rotation); + bool SetOrientation(ScreenId screenId, Orientation orientation); - void OnScreenRotate(ScreenId dmsScreenId, Rotation before, Rotation after); bool IsScreenGroup(ScreenId screenId) const; bool SetScreenActiveMode(ScreenId screenId, uint32_t modeId); std::shared_ptr GetRSDisplayNodeByScreenId(ScreenId dmsScreenId) const; void UpdateRSTree(ScreenId dmsScreenId, std::shared_ptr& surfaceNode, bool isAdd); bool MakeMirror(ScreenId, std::vector screens); bool MakeExpand(std::vector screenIds, std::vector startPoints); + void RemoveVirtualScreenFromGroup(std::vector screens); void DumpScreenInfo() const; void DumpScreenGroupInfo() const; @@ -81,10 +82,15 @@ private: bool FillAbstractScreen(sptr& absScreen, ScreenId rsScreenId); sptr AddToGroupLocked(sptr newScreen); sptr RemoveFromGroupLocked(sptr newScreen); + bool RemoveChildFromGroup(sptr, sptr); bool CheckScreenInScreenGroup(sptr newScreen) const; sptr AddAsFirstScreenLocked(sptr newScreen); sptr AddAsSuccedentScreenLocked(sptr newScreen); - void ProcessScreenModeChanged(ScreenId rsScreenId); + void ProcessScreenModeChanged(ScreenId dmsScreenId); + void ChangeScreenGroup(sptr group, const std::vector& screens, + const std::vector& startPoints, bool filterScreen, ScreenCombination combination); + void AddScreenToGroup(sptr, const std::vector&, + const std::vector&, std::map&); std::recursive_mutex& mutex_; OHOS::Rosen::RSInterfaces& rsInterface_; @@ -95,6 +101,7 @@ private: std::map> dmsScreenMap_; std::map> dmsScreenGroupMap_; sptr abstractScreenCallback_; + ScreenId defaultScreenId = INVALID_SCREEN_ID; }; } // namespace OHOS::Rosen #endif // FOUNDATION_DMSERVER_ABSTRACT_SCREEN_CONTROLLER_H \ No newline at end of file diff --git a/dmserver/include/display_manager_agent_controller.h b/dmserver/include/display_manager_agent_controller.h index 07ad87b1..862695dc 100644 --- a/dmserver/include/display_manager_agent_controller.h +++ b/dmserver/include/display_manager_agent_controller.h @@ -36,8 +36,9 @@ public: void OnScreenConnect(sptr screenInfo); void OnScreenDisconnect(ScreenId); - void OnScreenChange(const std::vector>&, ScreenChangeEvent); - void OnScreenChange(sptr, ScreenChangeEvent); + void OnScreenChange(const sptr, ScreenChangeEvent); + void OnScreenGroupChange(const sptr&, ScreenGroupChangeEvent); + void OnScreenGroupChange(const std::vector>&, ScreenGroupChangeEvent); void OnDisplayCreate(sptr); void OnDisplayDestroy(DisplayId); void OnDisplayChange(sptr, DisplayChangeEvent); diff --git a/dmserver/include/display_manager_interface.h b/dmserver/include/display_manager_interface.h index c4cb521b..620c40e3 100644 --- a/dmserver/include/display_manager_interface.h +++ b/dmserver/include/display_manager_interface.h @@ -35,6 +35,7 @@ public: enum { TRANS_ID_GET_DEFAULT_DISPLAY_ID = 0, TRANS_ID_GET_DISPLAY_BY_ID, + TRANS_ID_GET_DISPLAY_BY_SCREEN, TRANS_ID_GET_DISPLAY_SNAPSHOT, TRANS_ID_REGISTER_DISPLAY_MANAGER_AGENT, TRANS_ID_UNREGISTER_DISPLAY_MANAGER_AGENT, @@ -45,6 +46,7 @@ public: TRANS_ID_SET_SCREEN_POWER_FOR_ALL, TRANS_ID_SET_DISPLAY_STATE, TRANS_ID_GET_DISPLAY_STATE, + TRANS_ID_GET_ALL_DISPLAYIDS, TRANS_ID_NOTIFY_DISPLAY_EVENT, TRANS_ID_SCREEN_BASE = 1000, TRANS_ID_CREATE_VIRTUAL_SCREEN = TRANS_ID_SCREEN_BASE, @@ -54,10 +56,11 @@ public: TRANS_ID_GET_SCREEN_GROUP_INFO_BY_ID, TRANS_ID_SET_SCREEN_ACTIVE_MODE, TRANS_ID_GET_ALL_SCREEN_INFOS, - TRANS_ID_REQUEST_ROTATION, + TRANS_ID_SET_ORIENTATION, TRANS_ID_SCREENGROUP_BASE = 1100, TRANS_ID_SCREEN_MAKE_MIRROR = TRANS_ID_SCREENGROUP_BASE, TRANS_ID_SCREEN_MAKE_EXPAND, + TRANS_ID_SCREEN_MAKE_MIRROR_OR_EXPAND_CANCELED, TRANS_ID_SCREEN_GAMUT_BASE = 1200, TRANS_ID_SCREEN_GET_SUPPORTED_COLOR_GAMUTS = TRANS_ID_SCREEN_GAMUT_BASE, TRANS_ID_SCREEN_GET_COLOR_GAMUT, @@ -68,13 +71,14 @@ public: }; virtual DisplayId GetDefaultDisplayId() = 0; - virtual DisplayInfo GetDisplayInfoById(DisplayId displayId) = 0; + virtual sptr GetDisplayInfoById(DisplayId displayId) = 0; + virtual sptr GetDisplayInfoByScreen(ScreenId screenId) = 0; virtual ScreenId CreateVirtualScreen(VirtualScreenOption option) = 0; virtual DMError DestroyVirtualScreen(ScreenId screenId) = 0; virtual DMError SetVirtualScreenSurface(ScreenId screenId, sptr surface) = 0; - virtual bool RequestRotation(ScreenId screenId, Rotation rotation) = 0; - virtual std::shared_ptr GetDispalySnapshot(DisplayId displayId) = 0; + virtual bool SetOrientation(ScreenId screenId, Orientation orientation) = 0; + virtual std::shared_ptr GetDisplaySnapshot(DisplayId displayId) = 0; // colorspace, gamut virtual DMError GetScreenSupportedColorGamuts(ScreenId screenId, std::vector& colorGamuts) = 0; @@ -95,12 +99,14 @@ public: virtual bool SetScreenPowerForAll(DisplayPowerState state, PowerStateChangeReason reason) = 0; virtual bool SetDisplayState(DisplayState state) = 0; virtual DisplayState GetDisplayState(DisplayId displayId) = 0; + virtual std::vector GetAllDisplayIds() = 0; virtual void NotifyDisplayEvent(DisplayEvent event) = 0; virtual sptr GetScreenInfoById(ScreenId screenId) = 0; virtual sptr GetScreenGroupInfoById(ScreenId screenId) = 0; virtual std::vector> GetAllScreenInfos() = 0; - virtual DMError MakeMirror(ScreenId mainScreenId, std::vector mirrorScreenId) = 0; - virtual DMError MakeExpand(std::vector screenId, std::vector startPoint) = 0; + virtual ScreenId MakeMirror(ScreenId mainScreenId, std::vector mirrorScreenId) = 0; + virtual ScreenId MakeExpand(std::vector screenId, std::vector startPoint) = 0; + virtual void RemoveVirtualScreenFromGroup(std::vector screens) = 0; virtual bool SetScreenActiveMode(ScreenId screenId, uint32_t modeId) = 0; }; } // namespace OHOS::Rosen diff --git a/dmserver/include/display_manager_proxy.h b/dmserver/include/display_manager_proxy.h index 0d30ce4c..6db4a7a4 100644 --- a/dmserver/include/display_manager_proxy.h +++ b/dmserver/include/display_manager_proxy.h @@ -32,13 +32,14 @@ public: ~DisplayManagerProxy() {}; DisplayId GetDefaultDisplayId() override; - DisplayInfo GetDisplayInfoById(DisplayId displayId) override; + sptr GetDisplayInfoById(DisplayId displayId) override; + sptr GetDisplayInfoByScreen(ScreenId screenId) override; ScreenId CreateVirtualScreen(VirtualScreenOption option) override; DMError DestroyVirtualScreen(ScreenId screenId) override; DMError SetVirtualScreenSurface(ScreenId screenId, sptr surface) override; - bool RequestRotation(ScreenId screenId, Rotation rotation) override; - std::shared_ptr GetDispalySnapshot(DisplayId displayId) override; + bool SetOrientation(ScreenId screenId, Orientation orientation) override; + std::shared_ptr GetDisplaySnapshot(DisplayId displayId) override; // colorspace, gamut DMError GetScreenSupportedColorGamuts(ScreenId screenId, std::vector& colorGamuts) override; @@ -58,13 +59,15 @@ public: bool SuspendEnd() override; bool SetScreenPowerForAll(DisplayPowerState state, PowerStateChangeReason reason) override; bool SetDisplayState(DisplayState state) override; + std::vector GetAllDisplayIds() override; DisplayState GetDisplayState(DisplayId displayId) override; void NotifyDisplayEvent(DisplayEvent event) override; - DMError MakeMirror(ScreenId mainScreenId, std::vector mirrorScreenId) override; + ScreenId MakeMirror(ScreenId mainScreenId, std::vector mirrorScreenId) override; sptr GetScreenInfoById(ScreenId screenId) override; sptr GetScreenGroupInfoById(ScreenId screenId) override; std::vector> GetAllScreenInfos() override; - DMError MakeExpand(std::vector screenId, std::vector startPoint) override; + ScreenId MakeExpand(std::vector screenId, std::vector startPoint) override; + void RemoveVirtualScreenFromGroup(std::vector screens) override; bool SetScreenActiveMode(ScreenId screenId, uint32_t modeId) override; private: diff --git a/dmserver/include/display_manager_service.h b/dmserver/include/display_manager_service.h index ee3dc6d9..9b77df95 100644 --- a/dmserver/include/display_manager_service.h +++ b/dmserver/include/display_manager_service.h @@ -51,9 +51,10 @@ public: DMError SetVirtualScreenSurface(ScreenId screenId, sptr surface) override; DisplayId GetDefaultDisplayId() override; - DisplayInfo GetDisplayInfoById(DisplayId displayId) override; - bool RequestRotation(ScreenId screenId, Rotation rotation) override; - std::shared_ptr GetDispalySnapshot(DisplayId displayId) override; + sptr GetDisplayInfoById(DisplayId displayId) override; + sptr GetDisplayInfoByScreen(ScreenId screenId) override; + bool SetOrientation(ScreenId screenId, Orientation orientation) override; + std::shared_ptr GetDisplaySnapshot(DisplayId displayId) override; ScreenId GetRSScreenId(DisplayId displayId) const; // colorspace, gamut @@ -82,11 +83,15 @@ public: sptr GetAbstractDisplay(DisplayId displayId); sptr GetAbstractScreenController(); sptr GetDisplayByDisplayId(DisplayId displayId) const; - DMError MakeMirror(ScreenId mainScreenId, std::vector mirrorScreenId) override; + sptr GetDisplayByScreen(ScreenId screenId) const; + ScreenId MakeMirror(ScreenId mainScreenId, std::vector mirrorScreenId) override; + ScreenId MakeExpand(std::vector screenId, std::vector startPoint) override; + void RemoveVirtualScreenFromGroup(std::vector screens) override; sptr GetScreenInfoById(ScreenId screenId) override; sptr GetScreenGroupInfoById(ScreenId screenId) override; std::vector> GetAllScreenInfos() override; - DMError MakeExpand(std::vector screenId, std::vector startPoint) override; + + std::vector GetAllDisplayIds() override; bool SetScreenActiveMode(ScreenId screenId, uint32_t modeId) override; private: @@ -105,7 +110,7 @@ private: static inline SingletonDelegator delegator_; sptr abstractDisplayController_; sptr abstractScreenController_; - DisplayPowerController displayPowerController_; + sptr displayPowerController_; std::map> displayNodeMap_; sptr displayChangeListener_; }; diff --git a/dmserver/include/display_manager_service_inner.h b/dmserver/include/display_manager_service_inner.h index b537d11d..5558e6ff 100644 --- a/dmserver/include/display_manager_service_inner.h +++ b/dmserver/include/display_manager_service_inner.h @@ -36,6 +36,7 @@ public: std::vector GetAllDisplayIds(); ScreenId GetRSScreenId(DisplayId displayId) const; const sptr GetScreenInfoByDisplayId(DisplayId displayId) const; + const sptr GetScreenModesByDisplayId(DisplayId displayId); void UpdateRSTree(DisplayId displayId, std::shared_ptr& surfaceNode, bool isAdd); void RegisterDisplayChangeListener(sptr listener); }; diff --git a/dmserver/include/display_power_controller.h b/dmserver/include/display_power_controller.h index 6da20ef7..e8359e1e 100644 --- a/dmserver/include/display_power_controller.h +++ b/dmserver/include/display_power_controller.h @@ -18,14 +18,15 @@ #include #include +#include #include "display.h" #include "dm_common.h" namespace OHOS { namespace Rosen { -class DisplayPowerController { +class DisplayPowerController : public RefBase { public: - DisplayPowerController() = default; + DisplayPowerController(std::recursive_mutex& mutex) : mutex_(mutex) {} virtual ~DisplayPowerController() = default; bool SuspendBegin(PowerStateChangeReason reason); @@ -36,6 +37,7 @@ public: private: DisplayState displayState_ { DisplayState::UNKNOWN }; bool isKeyguardDrawn_ { false }; + std::recursive_mutex& mutex_; }; } } diff --git a/dmserver/src/abstract_display.cpp b/dmserver/src/abstract_display.cpp index 7f8334a9..0b85b332 100644 --- a/dmserver/src/abstract_display.cpp +++ b/dmserver/src/abstract_display.cpp @@ -24,12 +24,16 @@ namespace { constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_DISPLAY, "AbstractDisplay"}; } -AbstractDisplay::AbstractDisplay(const DisplayInfo& info) - : id_(info.id_), - width_(info.width_), - height_(info.height_), - freshRate_(info.freshRate_) +AbstractDisplay::AbstractDisplay(const DisplayInfo* info) { + if (info == nullptr) { + WLOGFE("DisplayInfo is nullptr"); + return; + } + id_ = info->GetDisplayId(); + width_ = info->GetWidth(); + height_ = info->GetHeight(); + freshRate_ = info->GetFreshRate(); } AbstractDisplay::AbstractDisplay(DisplayId id, ScreenId screenId, int32_t width, int32_t height, uint32_t freshRate) @@ -91,6 +95,11 @@ void AbstractDisplay::SetId(DisplayId id) id_ = id; } +void AbstractDisplay::SetOrientation(Orientation orientation) +{ + orientation_ = orientation; +} + bool AbstractDisplay::RequestRotation(Rotation rotation) { WLOGD("request rotation from %{public}u to %{public}u, display %{public}" PRIu64"", rotation_, rotation, id_); @@ -107,6 +116,11 @@ bool AbstractDisplay::RequestRotation(Rotation rotation) return true; } +Rotation AbstractDisplay::GetRotation() +{ + return rotation_; +} + bool AbstractDisplay::BindAbstractScreen(ScreenId dmsScreenId) { sptr screenController @@ -128,8 +142,8 @@ bool AbstractDisplay::BindAbstractScreen(sptr abstractScreen) id_, dmsScreenId); return false; } - width_ = info->width_; - height_ = info->height_; + width_ = static_cast(info->width_); + height_ = static_cast(info->height_); freshRate_ = info->freshRate_; screenId_ = dmsScreenId; WLOGD("display bound to screen. display:%{public}" PRIu64", screen:%{public}" PRIu64"", id_, dmsScreenId); @@ -141,7 +155,7 @@ ScreenId AbstractDisplay::GetAbstractScreenId() const return screenId_; } -const sptr AbstractDisplay::ConvertToDisplayInfo() const +sptr AbstractDisplay::ConvertToDisplayInfo() const { sptr displayInfo = new DisplayInfo(); displayInfo->width_ = width_; @@ -149,6 +163,8 @@ const sptr AbstractDisplay::ConvertToDisplayInfo() const displayInfo->id_ = id_; displayInfo->freshRate_ = freshRate_; displayInfo->screenId_ = screenId_; + displayInfo->rotation_ = rotation_; + displayInfo->orientation_ = orientation_; return displayInfo; } } // namespace OHOS::Rosen \ No newline at end of file diff --git a/dmserver/src/abstract_display_controller.cpp b/dmserver/src/abstract_display_controller.cpp index aa9899e8..e520b0ad 100644 --- a/dmserver/src/abstract_display_controller.cpp +++ b/dmserver/src/abstract_display_controller.cpp @@ -86,6 +86,29 @@ sptr AbstractDisplayController::GetAbstractDisplay(DisplayId di return iter->second; } +sptr AbstractDisplayController::GetAbstractDisplayByScreen(ScreenId screenId) const +{ + std::lock_guard lock(mutex_); + for (auto iter : abstractDisplayMap_) { + sptr display = iter.second; + if (display->GetAbstractScreenId() == screenId) { + return display; + } + } + WLOGFE("fail to get AbstractDisplay %{public}" PRIu64"", screenId); + return nullptr; +} + +std::vector AbstractDisplayController::GetAllDisplayIds() const +{ + std::lock_guard lock(mutex_); + std::vector res; + for (auto iter = abstractDisplayMap_.begin(); iter != abstractDisplayMap_.end(); ++iter) { + res.push_back(iter->first); + } + return res; +} + std::shared_ptr AbstractDisplayController::GetScreenSnapshot(DisplayId displayId) { sptr abstractDisplay = GetAbstractDisplay(displayId); @@ -129,67 +152,82 @@ void AbstractDisplayController::OnAbstractScreenConnect(sptr abs void AbstractDisplayController::OnAbstractScreenDisconnect(sptr absScreen) { - WLOGI("disconnect screen. id:%{public}" PRIu64"", absScreen->dmsId_); if (absScreen == nullptr) { WLOGE("the information of the screen is wrong"); return; } - std::lock_guard lock(mutex_); - sptr screenGroup = absScreen->GetGroup(); - if (screenGroup == nullptr) { - WLOGE("the group information of the screen is wrong"); + WLOGI("disconnect screen. id:%{public}" PRIu64"", absScreen->dmsId_); + sptr screenGroup; + DisplayId absDisplayId = DISPLAY_ID_INVALD; + { + std::lock_guard lock(mutex_); + screenGroup = absScreen->GetGroup(); + if (screenGroup == nullptr) { + WLOGE("the group information of the screen is wrong"); + return; + } + if (screenGroup->combination_ == ScreenCombination::SCREEN_ALONE + || screenGroup->combination_ == ScreenCombination::SCREEN_MIRROR) { + absDisplayId = ProcessNormalScreenDisconnected(absScreen, screenGroup); + } else if (screenGroup->combination_ == ScreenCombination::SCREEN_EXPAND) { + absDisplayId = ProcessExpandScreenDisconnected(absScreen, screenGroup); + } else { + WLOGE("support in future. combination:%{public}u", screenGroup->combination_); + } + } + if (absDisplayId == DISPLAY_ID_INVALD) { + WLOGE("the displayId of the disconnected expand screen was not found"); return; } if (screenGroup->combination_ == ScreenCombination::SCREEN_ALONE || screenGroup->combination_ == ScreenCombination::SCREEN_MIRROR) { - ProcessNormalScreenDisconnected(absScreen, screenGroup); + if (screenGroup->GetChildCount() == 0) { + abstractDisplayMap_.erase(absDisplayId); + DisplayManagerAgentController::GetInstance().OnDisplayDestroy(absDisplayId); + } } else if (screenGroup->combination_ == ScreenCombination::SCREEN_EXPAND) { - ProcessExpandScreenDisconnected(absScreen, screenGroup); + DisplayManagerService::GetInstance().NotifyDisplayStateChange( + absDisplayId, DisplayStateChangeType::DESTROY); + DisplayManagerAgentController::GetInstance().OnDisplayDestroy(absDisplayId); + abstractDisplayMap_.erase(absDisplayId); } else { WLOGE("support in future. combination:%{public}u", screenGroup->combination_); } } -void AbstractDisplayController::ProcessNormalScreenDisconnected( +DisplayId AbstractDisplayController::ProcessNormalScreenDisconnected( sptr absScreen, sptr screenGroup) { WLOGI("normal screen disconnect"); ScreenId defaultScreenId = abstractScreenController_->GetDefaultAbstractScreenId(); sptr defaultScreen = abstractScreenController_->GetAbstractScreen(defaultScreenId); for (auto iter = abstractDisplayMap_.begin(); iter != abstractDisplayMap_.end(); iter++) { + DisplayId displayId = iter->first; sptr abstractDisplay = iter->second; - if (abstractDisplay->GetAbstractScreenId() != absScreen->dmsId_) { - continue; - } - abstractDisplay->BindAbstractScreen(defaultScreen); - if (screenGroup->GetChildCount() == 0) { - abstractDisplayMap_.erase(iter); - DisplayManagerAgentController::GetInstance().OnDisplayDestroy(abstractDisplay->GetId()); + if (abstractDisplay->GetAbstractScreenId() == absScreen->dmsId_) { + WLOGI("normal screen disconnect, displayId: %{public}" PRIu64", screenId: %{public}" PRIu64"", + displayId, abstractDisplay->GetAbstractScreenId()); + abstractDisplay->BindAbstractScreen(defaultScreen); + return displayId; } } + return DISPLAY_ID_INVALD; } -void AbstractDisplayController::ProcessExpandScreenDisconnected( +DisplayId AbstractDisplayController::ProcessExpandScreenDisconnected( sptr absScreen, sptr screenGroup) { WLOGI("expand screen disconnect"); - ScreenId defaultScreenId = abstractScreenController_->GetDefaultAbstractScreenId(); - sptr defaultScreen = abstractScreenController_->GetAbstractScreen(defaultScreenId); for (auto iter = abstractDisplayMap_.begin(); iter != abstractDisplayMap_.end(); iter++) { DisplayId displayId = iter->first; sptr abstractDisplay = iter->second; - if (abstractDisplay->GetAbstractScreenId() != absScreen->dmsId_) { - continue; + if (abstractDisplay->GetAbstractScreenId() == absScreen->dmsId_) { + WLOGI("expand screen disconnect, displayId: %{public}" PRIu64", screenId: %{public}" PRIu64"", + displayId, abstractDisplay->GetAbstractScreenId()); + return displayId; } - WLOGI("notify wms and dm which expand screen disconnect, displayId: %{public}" PRIu64"" - ", screenId: %{public}" PRIu64"", displayId, abstractDisplay->GetAbstractScreenId()); - // Notify disconnect event to WMS - DisplayManagerService::GetInstance().NotifyDisplayStateChange(displayId, DisplayStateChangeType::DESTROY); - // Notify disconnect event to DisplayManager - DisplayManagerAgentController::GetInstance().OnDisplayDestroy(abstractDisplay->GetId()); - abstractDisplayMap_.erase(iter); - break; } + return DISPLAY_ID_INVALD; } void AbstractDisplayController::OnAbstractScreenChange(sptr absScreen, DisplayChangeEvent event) @@ -199,57 +237,60 @@ void AbstractDisplayController::OnAbstractScreenChange(sptr absS return; } WLOGI("screen changes. id:%{public}" PRIu64"", absScreen->dmsId_); - - if (event == DisplayChangeEvent::UPDATE_ROTATION) { - ProcessDisplayUpdateRotation(absScreen); - } - if (event == DisplayChangeEvent::DISPLAY_SIZE_CHANGED) { + if (event == DisplayChangeEvent::UPDATE_ORIENTATION) { + ProcessDisplayUpdateOrientation(absScreen); + } else if (event == DisplayChangeEvent::DISPLAY_SIZE_CHANGED) { ProcessDisplaySizeChange(absScreen); + } else { + WLOGE("unknow screen change event. id:%{public}" PRIu64" event %{public}u", absScreen->dmsId_, event); } } -void AbstractDisplayController::ProcessDisplayUpdateRotation(sptr absScreen) +void AbstractDisplayController::ProcessDisplayUpdateOrientation(sptr absScreen) { sptr abstractDisplay = nullptr; - std::lock_guard lock(mutex_); - auto iter = abstractDisplayMap_.begin(); - for (; iter != abstractDisplayMap_.end(); iter++) { - abstractDisplay = iter->second; - if (abstractDisplay->GetAbstractScreenId() == absScreen->dmsId_) { - WLOGFD("find abstract display of the screen. display %{public}" PRIu64", screen %{public}" PRIu64"", - abstractDisplay->GetId(), absScreen->dmsId_); - break; + { + std::lock_guard lock(mutex_); + auto iter = abstractDisplayMap_.begin(); + for (; iter != abstractDisplayMap_.end(); iter++) { + abstractDisplay = iter->second; + if (abstractDisplay->GetAbstractScreenId() == absScreen->dmsId_) { + WLOGFD("find abstract display of the screen. display %{public}" PRIu64", screen %{public}" PRIu64"", + abstractDisplay->GetId(), absScreen->dmsId_); + break; + } } - } - sptr group = absScreen->GetGroup(); - if (group == nullptr) { - WLOGFE("cannot get screen group"); - return; - } - if (iter == abstractDisplayMap_.end()) { - if (group->combination_ == ScreenCombination::SCREEN_ALONE - || group->combination_ == ScreenCombination::SCREEN_EXPAND) { - WLOGFE("cannot find abstract display of the screen %{public}" PRIu64"", absScreen->dmsId_); - return; - } else if (group->combination_ == ScreenCombination::SCREEN_MIRROR) { - // If the 'absScreen' cannot be found in 'abstractDisplayMap_', it means that the screen is the secondary. - WLOGFI("It's the secondary screen of the mirrored."); - return; - } else { - WLOGFE("Unknow combination"); + sptr group = absScreen->GetGroup(); + if (group == nullptr) { + WLOGFE("cannot get screen group"); return; } + if (iter == abstractDisplayMap_.end()) { + if (group->combination_ == ScreenCombination::SCREEN_ALONE + || group->combination_ == ScreenCombination::SCREEN_EXPAND) { + WLOGFE("cannot find abstract display of the screen %{public}" PRIu64"", absScreen->dmsId_); + return; + } else if (group->combination_ == ScreenCombination::SCREEN_MIRROR) { + // If the screen cannot be found in 'abstractDisplayMap_', it means that the screen is the secondary + WLOGFI("It's the secondary screen of the mirrored."); + return; + } else { + WLOGFE("Unknow combination"); + return; + } + } } + abstractDisplay->SetOrientation(absScreen->orientation_); if (abstractDisplay->RequestRotation(absScreen->rotation_)) { // Notify rotation event to WMS DisplayManagerService::GetInstance().NotifyDisplayStateChange(abstractDisplay->GetId(), DisplayStateChangeType::UPDATE_ROTATION); - // Notify rotation event to DisplayManager - sptr displayInfo = abstractDisplay->ConvertToDisplayInfo(); - DisplayManagerAgentController::GetInstance().OnDisplayChange(displayInfo, - DisplayChangeEvent::UPDATE_ROTATION); } + // Notify orientation event to DisplayManager + sptr displayInfo = abstractDisplay->ConvertToDisplayInfo(); + DisplayManagerAgentController::GetInstance().OnDisplayChange(displayInfo, + DisplayChangeEvent::UPDATE_ORIENTATION); } void AbstractDisplayController::ProcessDisplaySizeChange(sptr absScreen) @@ -279,7 +320,8 @@ void AbstractDisplayController::ProcessDisplaySizeChange(sptr ab bool AbstractDisplayController::UpdateDisplaySize(sptr absDisplay, sptr info) { - if (info->height_ == absDisplay->GetHeight() && info->width_ == absDisplay->GetWidth()) { + if (info->height_ == static_cast(absDisplay->GetHeight()) && + info->width_ == static_cast(absDisplay->GetWidth())) { WLOGI("keep display size. display:%{public}" PRIu64"", absDisplay->GetId()); return false; } diff --git a/dmserver/src/abstract_screen.cpp b/dmserver/src/abstract_screen.cpp index 2c6d0581..8350aece 100644 --- a/dmserver/src/abstract_screen.cpp +++ b/dmserver/src/abstract_screen.cpp @@ -25,8 +25,9 @@ namespace { constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_DISPLAY, "AbstractScreenGroup"}; } -AbstractScreen::AbstractScreen(ScreenId dmsId, ScreenId rsId) - : dmsId_(dmsId), rsId_(rsId), screenController_(DisplayManagerService::GetInstance().abstractScreenController_) +AbstractScreen::AbstractScreen(const std::string& name, ScreenId dmsId, ScreenId rsId) + : name_(name), dmsId_(dmsId), rsId_(rsId), + screenController_(DisplayManagerService::GetInstance().abstractScreenController_) { } @@ -53,7 +54,7 @@ sptr AbstractScreen::GetGroup() const return DisplayManagerService::GetInstance().GetAbstractScreenController()->GetAbstractScreenGroup(groupDmsId_); } -const sptr AbstractScreen::ConvertToScreenInfo() const +sptr AbstractScreen::ConvertToScreenInfo() const { sptr info = new ScreenInfo(); FillScreenInfo(info); @@ -68,18 +69,11 @@ void AbstractScreen::UpdateRSTree(std::shared_ptr& surfaceNode, b } WLOGFI("AbstractScreen::UpdateRSTree"); - // default duration 350ms - static const RSAnimationTimingProtocol timingProtocol(350); - // default curve EASE OUT - static const Rosen::RSAnimationTimingCurve curve = Rosen::RSAnimationTimingCurve::EASE_OUT; - // add or remove window with transition animation - RSNode::Animate(timingProtocol, curve, [=]() { - if (isAdd) { - rsDisplayNode_->AddChild(surfaceNode, -1); - } else { - rsDisplayNode_->RemoveChild(surfaceNode); - } - }); + if (isAdd) { + rsDisplayNode_->AddChild(surfaceNode, -1); + } else { + rsDisplayNode_->RemoveChild(surfaceNode); + } } void AbstractScreen::InitRSDisplayNode(RSDisplayNodeConfig& config) @@ -91,6 +85,10 @@ void AbstractScreen::InitRSDisplayNode(RSDisplayNodeConfig& config) } rsDisplayNode_ = rsDisplayNode; rSDisplayNodeConfig_ = config; + auto transactionProxy = RSTransactionProxy::GetInstance(); + if (transactionProxy != nullptr) { + transactionProxy->FlushImplicitTransaction(); + } } DMError AbstractScreen::GetScreenSupportedColorGamuts(std::vector& colorGamuts) @@ -195,22 +193,52 @@ void AbstractScreen::FillScreenInfo(sptr info) const info->parent_ = groupDmsId_; info->canHasChild_ = canHasChild_; info->rotation_ = rotation_; + info->orientation_ = orientation_; + info->type_ = type_; info->modeId_ = activeIdx_; info->modes_ = modes_; } -Rotation AbstractScreen::GetRotation() const +bool AbstractScreen::SetOrientation(Orientation orientation) { - return rotation_; + orientation_ = orientation; + return true; } -void AbstractScreen::RequestRotation(Rotation rotation) +Rotation AbstractScreen::CalcRotation(Orientation orientation) const { - rotation_ = rotation; + if (activeIdx_ < 0 || activeIdx_ >= modes_.size()) { + WLOGE("active mode index is wrong: %{public}d", activeIdx_); + return Rotation::ROTATION_0; + } + sptr info = modes_[activeIdx_]; + // virtical: phone(Plugin screen); horizontal: pad & external screen + bool isVerticalScreen = info->width_ < info->height_; + switch (orientation) { + case Orientation::UNSPECIFIED: { + return Rotation::ROTATION_0; + } + case Orientation::VERTICAL: { + return isVerticalScreen ? Rotation::ROTATION_0 : Rotation::ROTATION_90; + } + case Orientation::HORIZONTAL: { + return isVerticalScreen ? Rotation::ROTATION_90 : Rotation::ROTATION_0; + } + case Orientation::REVERSE_VERTICAL: { + return isVerticalScreen ? Rotation::ROTATION_180 : Rotation::ROTATION_270; + } + case Orientation::REVERSE_HORIZONTAL: { + return isVerticalScreen ? Rotation::ROTATION_270 : Rotation::ROTATION_180; + } + default: { + WLOGE("unknown orientation %{public}u", orientation); + return Rotation::ROTATION_0; + } + } } AbstractScreenGroup::AbstractScreenGroup(ScreenId dmsId, ScreenId rsId, ScreenCombination combination) - : AbstractScreen(dmsId, rsId), combination_(combination) + : AbstractScreen("", dmsId, rsId), combination_(combination) { type_ = ScreenType::UNDEFINE; canHasChild_ = true; @@ -222,7 +250,7 @@ AbstractScreenGroup::~AbstractScreenGroup() abstractScreenMap_.clear(); } -const sptr AbstractScreenGroup::ConvertToScreenGroupInfo() const +sptr AbstractScreenGroup::ConvertToScreenGroupInfo() const { sptr screenGroupInfo = new ScreenGroupInfo(); FillScreenInfo(screenGroupInfo); @@ -303,7 +331,7 @@ bool AbstractScreenGroup::AddChildren(std::vector>& dmsScre } bool res = true; for (size_t i = 0; i < size; i++) { - res &= AddChild(dmsScreens[i], startPoints[i]); + res = AddChild(dmsScreens[i], startPoints[i]) && res; } return res; } @@ -347,4 +375,4 @@ size_t AbstractScreenGroup::GetChildCount() const { return abstractScreenMap_.size(); } -} // namespace OHOS::Rosen \ No newline at end of file +} // namespace OHOS::Rosen diff --git a/dmserver/src/abstract_screen_controller.cpp b/dmserver/src/abstract_screen_controller.cpp index 3f86298e..6e1d2889 100644 --- a/dmserver/src/abstract_screen_controller.cpp +++ b/dmserver/src/abstract_screen_controller.cpp @@ -107,7 +107,7 @@ std::shared_ptr AbstractScreenController::GetRSDisplayNodeByScree if (screen == nullptr) { return nullptr; } - WLOGI("GetAbstractScreen: screen: %{public}" PRIu64", nodeId: %{public}" PRIu64" ", + WLOGI("GetRSDisplayNodeByScreenId: screen: %{public}" PRIu64", nodeId: %{public}" PRIu64" ", screen->dmsId_, screen->rsDisplayNode_->GetId()); return screen->rsDisplayNode_; } @@ -159,11 +159,12 @@ ScreenId AbstractScreenController::GetDefaultAbstractScreenId() auto iter = rs2DmsScreenIdMap_.find(rsDefaultId); if (iter != rs2DmsScreenIdMap_.end()) { WLOGI("GetDefaultAbstractScreenId, screen:%{public}" PRIu64"", iter->second); + defaultScreenId = iter->second; return iter->second; } WLOGFI("GetDefaultAbstractScreenId, default screen is null, try to get."); ScreenId dmsScreenId = dmsScreenCount_; - sptr absScreen = new AbstractScreen(dmsScreenId, rsDefaultId); + sptr absScreen = new AbstractScreen(DEFAULT_SCREEN_NAME, dmsScreenId, rsDefaultId); if (!FillAbstractScreen(absScreen, rsDefaultId)) { WLOGFW("GetDefaultAbstractScreenId, FillAbstractScreen failed."); return INVALID_SCREEN_ID; @@ -172,9 +173,15 @@ ScreenId AbstractScreenController::GetDefaultAbstractScreenId() dms2RsScreenIdMap_.insert(std::make_pair(dmsScreenId, rsDefaultId)); dmsScreenMap_.insert(std::make_pair(dmsScreenId, absScreen)); dmsScreenCount_++; + defaultScreenId = dmsScreenId; return dmsScreenId; } +ScreenId AbstractScreenController::GetDefaultScreenId() const +{ + return defaultScreenId; +} + ScreenId AbstractScreenController::ConvertToRsScreenId(ScreenId dmsScreenId) { std::lock_guard lock(mutex_); @@ -211,7 +218,7 @@ void AbstractScreenController::OnRsScreenConnectionChange(ScreenId rsScreenId, S if (iter == rs2DmsScreenIdMap_.end()) { WLOGFD("connect new screen"); dmsScreenId = dmsScreenCount_; - sptr absScreen = new AbstractScreen(dmsScreenId, rsScreenId); + sptr absScreen = new AbstractScreen(DEFAULT_SCREEN_NAME, dmsScreenId, rsScreenId); if (!FillAbstractScreen(absScreen, rsScreenId)) { return; } @@ -248,32 +255,6 @@ void AbstractScreenController::ScreenConnectionInDisplayInit(sptrsecond; - auto dmsScreenMapIter = dmsScreenMap_.find(dmsScreenId); - if (dmsScreenMapIter == dmsScreenMap_.end()) { - WLOGE("ProcessScreenModeChanged: no dms screen is found, rsscreenId=%{public}" PRIu64"", rsScreenId); - return; - } - // should be called by OnRsScreenConnectionChange - // if not, the recursive_mutex should be added - std::lock_guard lock(mutex_); - sptr absScreen = dmsScreenMapIter->second; - if (abstractScreenCallback_ != nullptr) { - abstractScreenCallback_->onChange_(absScreen, DisplayChangeEvent::DISPLAY_SIZE_CHANGED); - } - DisplayManagerAgentController::GetInstance().OnScreenChange( - absScreen->ConvertToScreenInfo(), ScreenChangeEvent::CHANGE_MODE); -} - void AbstractScreenController::ProcessScreenDisconnected(ScreenId rsScreenId) { WLOGI("disconnect screen, screenId=%{public}" PRIu64"", rsScreenId); @@ -312,8 +293,8 @@ bool AbstractScreenController::FillAbstractScreen(sptr& absScree } for (RSScreenModeInfo rsScreenModeInfo : allModes) { sptr info = new SupportedScreenModes(); - info->width_ = rsScreenModeInfo.GetScreenWidth(); - info->height_ = rsScreenModeInfo.GetScreenHeight(); + info->width_ = static_cast(rsScreenModeInfo.GetScreenWidth()); + info->height_ = static_cast(rsScreenModeInfo.GetScreenHeight()); info->freshRate_ = rsScreenModeInfo.GetScreenFreshRate(); absScreen->modes_.push_back(info); WLOGD("fill screen w/h:%{public}d/%{public}d", info->width_, info->height_); @@ -339,8 +320,8 @@ sptr AbstractScreenController::AddToGroupLocked(sptrConvertToScreenInfo(), ScreenChangeEvent::ADD_TO_GROUP); + DisplayManagerAgentController::GetInstance().OnScreenGroupChange( + newScreen->ConvertToScreenInfo(), ScreenGroupChangeEvent::ADD_TO_GROUP); } return res; } @@ -355,11 +336,21 @@ sptr AbstractScreenController::RemoveFromGroupLocked(sptr screenGroup = iter->second; + if (!RemoveChildFromGroup(screen, screenGroup)) { + return nullptr; + } + DisplayManagerAgentController::GetInstance().OnScreenGroupChange( + screen->ConvertToScreenInfo(), ScreenGroupChangeEvent::REMOVE_FROM_GROUP); + return screenGroup; +} + +bool AbstractScreenController::RemoveChildFromGroup(sptr screen, sptr screenGroup) +{ bool res = screenGroup->RemoveChild(screen); if (!res) { WLOGE("RemoveFromGroupLocked. remove screen:%{public}" PRIu64" failed from screenGroup:%{public}" PRIu64".", - screen->dmsId_, groupDmsId); - return nullptr; + screen->dmsId_, screen->groupDmsId_); + return false; } if (screen->dmsId_ == screenGroup->mirrorScreenId_) { // Todo: if mirror screen removed and it is SCREEN_MIRROR type, then should make mirror in this group. @@ -370,9 +361,7 @@ sptr AbstractScreenController::RemoveFromGroupLocked(sptrdmsId_); dmsScreenMap_.erase(screenGroup->dmsId_); } - DisplayManagerAgentController::GetInstance().OnScreenChange( - screen->ConvertToScreenInfo(), ScreenChangeEvent::REMOVE_FROM_GROUP); - return screenGroup; + return true; } bool AbstractScreenController::CheckScreenInScreenGroup(sptr screen) const @@ -436,31 +425,40 @@ sptr AbstractScreenController::AddAsSuccedentScreenLocked(s ScreenId AbstractScreenController::CreateVirtualScreen(VirtualScreenOption option) { - ScreenId result = rsInterface_.CreateVirtualScreen(option.name_, option.width_, + ScreenId rsId = rsInterface_.CreateVirtualScreen(option.name_, option.width_, option.height_, option.surface_, INVALID_SCREEN_ID, option.flags_); - WLOGFI("AbstractScreenController::CreateVirtualScreen id: %{public}" PRIu64"", result); - if (result == SCREEN_ID_INVALID) { + WLOGFI("CreateVirtualScreen id: %{public}" PRIu64"", rsId); + if (rsId == SCREEN_ID_INVALID) { return SCREEN_ID_INVALID; } std::lock_guard lock(mutex_); ScreenId dmsScreenId = SCREEN_ID_INVALID; - auto iter = rs2DmsScreenIdMap_.find(result); + auto iter = rs2DmsScreenIdMap_.find(rsId); if (iter == rs2DmsScreenIdMap_.end()) { if (!option.isForShot_) { WLOGI("CreateVirtualScreen is not shot"); dmsScreenId = dmsScreenCount_; - sptr absScreen = new AbstractScreen(dmsScreenId, result); + sptr absScreen = new AbstractScreen(option.name_, dmsScreenId, rsId); + sptr info = new SupportedScreenModes(); + info->width_ = option.width_; + info->height_ = option.height_; + auto defaultScreen = GetAbstractScreen(GetDefaultAbstractScreenId()); + if (defaultScreen != nullptr && defaultScreen->GetActiveScreenMode() != nullptr) { + info->freshRate_ = defaultScreen->GetActiveScreenMode()->freshRate_; + } + absScreen->modes_.push_back(info); + absScreen->activeIdx_ = 0; absScreen->type_ = ScreenType::VIRTUAL; dmsScreenCount_++; - rs2DmsScreenIdMap_.insert(std::make_pair(result, dmsScreenId)); - dms2RsScreenIdMap_.insert(std::make_pair(dmsScreenId, result)); + rs2DmsScreenIdMap_.insert(std::make_pair(rsId, dmsScreenId)); + dms2RsScreenIdMap_.insert(std::make_pair(dmsScreenId, rsId)); dmsScreenMap_.insert(std::make_pair(dmsScreenId, absScreen)); DisplayManagerAgentController::GetInstance().OnScreenConnect(absScreen->ConvertToScreenInfo()); } else { WLOGI("CreateVirtualScreen is shot"); dmsScreenId = dmsScreenCount_++; - rs2DmsScreenIdMap_.insert(std::make_pair(result, dmsScreenId)); - dms2RsScreenIdMap_.insert(std::make_pair(dmsScreenId, result)); + rs2DmsScreenIdMap_.insert(std::make_pair(rsId, dmsScreenId)); + dms2RsScreenIdMap_.insert(std::make_pair(dmsScreenId, rsId)); } } else { return iter->second; @@ -470,8 +468,6 @@ ScreenId AbstractScreenController::CreateVirtualScreen(VirtualScreenOption optio DMError AbstractScreenController::DestroyVirtualScreen(ScreenId screenId) { - WLOGFI("DumpScreenInfo before Destroy VirtualScreen"); - DumpScreenInfo(); WLOGFI("AbstractScreenController::DestroyVirtualScreen"); std::lock_guard lock(mutex_); ScreenId rsScreenId = SCREEN_ID_INVALID; @@ -495,7 +491,11 @@ DMError AbstractScreenController::DestroyVirtualScreen(ScreenId screenId) DMError AbstractScreenController::SetVirtualScreenSurface(ScreenId screenId, sptr surface) { WLOGFI("AbstractScreenController::SetVirtualScreenSurface"); - int32_t res = rsInterface_.SetVirtualScreenSurface(screenId, surface); + int32_t res = -1; + auto iter = dms2RsScreenIdMap_.find(screenId); + if (iter != dms2RsScreenIdMap_.end()) { + res = rsInterface_.SetVirtualScreenSurface(iter->second, surface); + } if (res != 0) { WLOGE("SetVirtualScreenSurface failed in RenderService"); return DMError::DM_ERROR_RENDER_SERVICE_FAILED; @@ -503,43 +503,47 @@ DMError AbstractScreenController::SetVirtualScreenSurface(ScreenId screenId, spt return DMError::DM_OK; } -bool AbstractScreenController::RequestRotation(ScreenId screenId, Rotation rotation) +bool AbstractScreenController::SetOrientation(ScreenId screenId, Orientation newOrientation) { - WLOGD("request rotation: screen %{public}" PRIu64"", screenId); + WLOGD("set orientation. screen %{public}" PRIu64" orientation %{public}u", screenId, newOrientation); auto screen = GetAbstractScreen(screenId); if (screen == nullptr) { - WLOGFE("fail to request rotation, cannot find screen %{public}" PRIu64"", screenId); + WLOGFE("fail to set orientation, cannot find screen %{public}" PRIu64"", screenId); return false; } if (screen->canHasChild_) { - WLOGE("cannot rotate the combination screen: %{public}" PRIu64"", screenId); + WLOGE("cannot set orientation to the combination. screen: %{public}" PRIu64"", screenId); return false; } - if (!rsInterface_.RequestRotation(screenId, static_cast(rotation))) { - WLOGE("rotate screen fail: %{public}" PRIu64"", screenId); - return false; + if (screen->orientation_ == newOrientation) { + WLOGI("skip setting orientation. screen %{public}" PRIu64" orientation %{public}u", screenId, newOrientation); + return true; } - Rotation before = screen->rotation_; - screen->RequestRotation(rotation); - OnScreenRotate(screenId, before, rotation); - return true; -} -void AbstractScreenController::OnScreenRotate(ScreenId dmsId, Rotation before, Rotation after) -{ - auto iter = dmsScreenMap_.find(dmsId); - if (iter == dmsScreenMap_.end()) { - WLOGE("rotate screen fail, not found abstract screen %{public}" PRIu64"", dmsId); - return; + Rotation rotationAfter = screen->CalcRotation(newOrientation); + if (rotationAfter != screen->rotation_) { + WLOGI("set orientation. roatiton %{public}u", rotationAfter); + if (!rsInterface_.RequestRotation(screenId, static_cast(rotationAfter))) { + WLOGE("rotate screen fail. %{public}" PRIu64"", screenId); + return false; + } + } else { + WLOGI("rotation not changed. screen %{public}" PRIu64" rotation %{public}u", screenId, rotationAfter); } - sptr abstractScreen = iter->second; + if (!screen->SetOrientation(newOrientation)) { + WLOGE("fail to set orientation, screen %{public}" PRIu64"", screenId); + return false; + } + screen->rotation_ = rotationAfter; + // Notify rotation event to ScreenManager DisplayManagerAgentController::GetInstance().OnScreenChange( - abstractScreen->ConvertToScreenInfo(), ScreenChangeEvent::UPDATE_ROTATION); + screen->ConvertToScreenInfo(), ScreenChangeEvent::UPDATE_ORIENTATION); // Notify rotation event to AbstractDisplayController if (abstractScreenCallback_ != nullptr) { - abstractScreenCallback_->onChange_(abstractScreen, DisplayChangeEvent::UPDATE_ROTATION); + abstractScreenCallback_->onChange_(screen, DisplayChangeEvent::UPDATE_ORIENTATION); } + return true; } DMError AbstractScreenController::GetScreenSupportedColorGamuts(ScreenId screenId, @@ -605,18 +609,29 @@ bool AbstractScreenController::IsScreenGroup(ScreenId screenId) const bool AbstractScreenController::SetScreenActiveMode(ScreenId screenId, uint32_t modeId) { - WLOGI("SetScreenActiveMode: screenId: %{public}" PRIu64", modeId: %{public}u", screenId, modeId); - rsInterface_.SetScreenActiveMode(screenId, modeId); - auto screen = GetAbstractScreen(screenId); - if (screen == nullptr) { - WLOGFE("SetScreenActiveMode: Get AbstractScreen failed"); + WLOGI("SetScreenActiveMode: RsScreenId: %{public}" PRIu64", modeId: %{public}u", screenId, modeId); + if (screenId == SCREEN_ID_INVALID) { + WLOGFE("SetScreenActiveMode: invalid screenId"); return false; } - std::lock_guard lock(mutex_); - uint32_t usedModeId = screen->activeIdx_; - screen->activeIdx_ = modeId; + uint32_t usedModeId = 0; + { + std::lock_guard lock(mutex_); + auto iter = dms2RsScreenIdMap_.find(screenId); + if (iter == dms2RsScreenIdMap_.end()) { + WLOGFE("SetScreenActiveMode: No corresponding rsId"); + return false; + } + rsInterface_.SetScreenActiveMode(iter->second, modeId); + auto screen = GetAbstractScreen(screenId); + if (screen == nullptr) { + WLOGFE("SetScreenActiveMode: Get AbstractScreen failed"); + return false; + } + usedModeId = static_cast(screen->activeIdx_); + screen->activeIdx_ = static_cast(modeId); + } // add thread to process mode change sync event - // should be called by OnRsScreenChange if rs implement corresponding event callback if (usedModeId != modeId) { WLOGI("SetScreenActiveMode: modeId: %{public}u -> %{public}u", usedModeId, modeId); auto func = [=]() { @@ -629,9 +644,36 @@ bool AbstractScreenController::SetScreenActiveMode(ScreenId screenId, uint32_t m return true; } +void AbstractScreenController::ProcessScreenModeChanged(ScreenId dmsScreenId) +{ + WM_SCOPED_TRACE("dms:ProcessScreenModeChanged(%" PRIu64")", dmsScreenId); + sptr absScreen = nullptr; + sptr absScreenCallback = nullptr; + { + std::lock_guard lock(mutex_); + auto dmsScreenMapIter = dmsScreenMap_.find(dmsScreenId); + if (dmsScreenMapIter == dmsScreenMap_.end()) { + WLOGFE("dmsScreenId=%{public}" PRIu64" is not in dmsScreenMap", dmsScreenId); + return; + } + absScreen = GetAbstractScreen(dmsScreenId); + if (absScreen == nullptr) { + WLOGFE("screen is nullptr. dmsScreenId=%{public}" PRIu64"", dmsScreenId); + return; + } + absScreenCallback = abstractScreenCallback_; + } + + if (absScreenCallback != nullptr) { + absScreenCallback->onChange_(absScreen, DisplayChangeEvent::DISPLAY_SIZE_CHANGED); + } + DisplayManagerAgentController::GetInstance().OnScreenChange( + absScreen->ConvertToScreenInfo(), ScreenChangeEvent::CHANGE_MODE); +} + bool AbstractScreenController::MakeMirror(ScreenId screenId, std::vector screens) { - WLOGI("AbstractScreenController::MakeMirror, screenId:%{public}" PRIu64"", screenId); + WLOGI("MakeMirror, screenId:%{public}" PRIu64"", screenId); sptr screen = GetAbstractScreen(screenId); if (screen == nullptr || screen->type_ != ScreenType::REAL) { WLOGFE("screen is nullptr, or screenType is not real."); @@ -654,27 +696,87 @@ bool AbstractScreenController::MakeMirror(ScreenId screenId, std::vectorcombination_ = ScreenCombination::SCREEN_MIRROR; - group->mirrorScreenId_ = screen->dmsId_; Point point; - for (ScreenId mirrorScreenId : screens) { - WLOGI("GetAbstractScreen: mirrorScreenId: %{public}" PRIu64"", mirrorScreenId); - auto mirrorScreen = GetAbstractScreen(mirrorScreenId); - if (mirrorScreen == nullptr) { - WLOGFE("mirrorScreen:%{public}" PRIu64" is nullptr", mirrorScreenId); - continue; - } - WLOGI("GetAbstractScreen: mirrorScreen->groupDmsId_: %{public}" PRIu64"", mirrorScreen->groupDmsId_); - auto originGroup = GetAbstractScreenGroup(mirrorScreen->groupDmsId_); - if (originGroup != nullptr) { - originGroup->RemoveChild(mirrorScreen); - } - group->AddChild(mirrorScreen, point); - } + std::vector startPoints; + startPoints.insert(startPoints.begin(), screens.size(), point); + bool filterMirroredScreen = + group->combination_ == ScreenCombination::SCREEN_MIRROR && group->mirrorScreenId_ == screen->dmsId_; + ChangeScreenGroup(group, screens, startPoints, filterMirroredScreen, ScreenCombination::SCREEN_MIRROR); WLOGFI("MakeMirror success"); return true; } +void AbstractScreenController::ChangeScreenGroup(sptr group, const std::vector& screens, + const std::vector& startPoints, bool filterScreen, ScreenCombination combination) +{ + std::map removeChildResMap; + std::vector addScreens; + std::vector addChildPos; + for (uint64_t i = 0; i != screens.size(); i++) { + ScreenId screenId = screens[i]; + WLOGFI("ChangeScreenGroup: screenId: %{public}" PRIu64"", screenId); + auto screen = GetAbstractScreen(screenId); + if (screen == nullptr) { + WLOGFE("screen:%{public}" PRIu64" is nullptr", screenId); + continue; + } + WLOGFI("ChangeScreenGroup: screen->groupDmsId_: %{public}" PRIu64"", screen->groupDmsId_); + if (filterScreen && screen->groupDmsId_ == group->dmsId_ && group->HasChild(screen->dmsId_)) { + continue; + } + auto originGroup = GetAbstractScreenGroup(screen->groupDmsId_); + bool removeChildRes = false; + if (originGroup != nullptr) { + removeChildRes = RemoveChildFromGroup(screen, originGroup); + abstractScreenCallback_->onDisconnect_(screen); + } + addChildPos.emplace_back(startPoints[i]); + removeChildResMap[screenId] = removeChildRes; + addScreens.emplace_back(screenId); + } + group->combination_ = combination; + AddScreenToGroup(group, addScreens, addChildPos, removeChildResMap); +} + +void AbstractScreenController::AddScreenToGroup(sptr group, + const std::vector& addScreens, const std::vector& addChildPos, + std::map& removeChildResMap) +{ + std::vector> addToGroup; + std::vector> removeFromGroup; + std::vector> changeGroup; + for (uint64_t i = 0; i != addScreens.size(); i++) { + ScreenId screenId = addScreens[i]; + sptr screen = GetAbstractScreen(screenId); + if (screen == nullptr) { + continue; + } + Point expandPoint = addChildPos[i]; + WLOGFI("screenId: %{public}" PRIu64", Point: %{public}d, %{public}d", + screen->dmsId_, expandPoint.posX_, expandPoint.posY_); + bool addChildRes = group->AddChild(screen, expandPoint); + if (removeChildResMap[screenId] && addChildRes) { + changeGroup.emplace_back(screen->ConvertToScreenInfo()); + WLOGFI("changeGroup"); + } else if (removeChildResMap[screenId]) { + WLOGFI("removeChild"); + removeFromGroup.emplace_back(screen->ConvertToScreenInfo()); + } else if (addChildRes) { + WLOGFI("AddChild"); + addToGroup.emplace_back(screen->ConvertToScreenInfo()); + } else { + WLOGFI("default, AddChild failed"); + } + abstractScreenCallback_->onConnect_(screen); + } + DisplayManagerAgentController::GetInstance(). + OnScreenGroupChange(removeFromGroup, ScreenGroupChangeEvent::REMOVE_FROM_GROUP); + DisplayManagerAgentController::GetInstance(). + OnScreenGroupChange(changeGroup, ScreenGroupChangeEvent::CHANGE_GROUP); + DisplayManagerAgentController::GetInstance(). + OnScreenGroupChange(addToGroup, ScreenGroupChangeEvent::ADD_TO_GROUP); +} + bool AbstractScreenController::MakeExpand(std::vector screenIds, std::vector startPoints) { ScreenId defaultScreenId = GetDefaultAbstractScreenId(); @@ -687,26 +789,36 @@ bool AbstractScreenController::MakeExpand(std::vector screenIds, std:: if (group == nullptr) { return false; } - group->combination_ = ScreenCombination::SCREEN_EXPAND; - for (uint64_t i = 0; i != screenIds.size(); i++) { - ScreenId expandScreenId = screenIds[i]; - Point expandPoint = startPoints[i]; - WLOGFI("expandScreenId: %{public}" PRIu64", Point: %{public}d, %{public}d", - expandScreenId, expandPoint.posX_, expandPoint.posY_); - auto expandScreen = GetAbstractScreen(expandScreenId); - if (expandScreen == nullptr) { - WLOGFE("expandScreen:%{public}" PRIu64" is nullptr", expandScreenId); + bool filterExpandScreen = group->combination_ == ScreenCombination::SCREEN_EXPAND; + ChangeScreenGroup(group, screenIds, startPoints, filterExpandScreen, ScreenCombination::SCREEN_EXPAND); + WLOGFI("MakeExpand success"); + return true; +} + +void AbstractScreenController::RemoveVirtualScreenFromGroup(std::vector screens) +{ + if (screens.empty()) { + return; + } + std::vector> removeFromGroup; + for (ScreenId screenId : screens) { + auto screen = GetAbstractScreen(screenId); + if (screen->type_ != ScreenType::VIRTUAL) { continue; } - WLOGI("expandScreen->groupDmsId_: %{public}" PRIu64"", expandScreen->groupDmsId_); - auto originGroup = GetAbstractScreenGroup(expandScreen->groupDmsId_); - if (originGroup != nullptr) { - originGroup->RemoveChild(expandScreen); + auto originGroup = GetAbstractScreenGroup(screen->groupDmsId_); + if (originGroup == nullptr) { + continue; } - group->AddChild(expandScreen, expandPoint); + if (!originGroup->HasChild(screenId)) { + continue; + } + removeFromGroup.emplace_back(screen->ConvertToScreenInfo()); + RemoveChildFromGroup(screen, originGroup); + abstractScreenCallback_->onDisconnect_(screen); } - WLOGI("MakeExpand success"); - return true; + DisplayManagerAgentController::GetInstance(). + OnScreenGroupChange(removeFromGroup, ScreenGroupChangeEvent::REMOVE_FROM_GROUP); } void AbstractScreenController::DumpScreenInfo() const @@ -752,12 +864,13 @@ void AbstractScreenController::DumpScreenGroupInfo() const std::string screenType = "UNDEFINE"; NodeId nodeId = (screenGroup->rsDisplayNode_ == nullptr) ? 0 : screenGroup->rsDisplayNode_->GetId(); WLOGI("%{public}10s %{public}20" PRIu64" %{public}20" PRIu64" %{public}20" PRIu64" %{public}10s %{public}20" - PRIu64" %{public}10s %{public}20" PRIu64" ", isGroup.c_str(), screenGroup->dmsId_,screenGroup->rsId_, + PRIu64" %{public}10s %{public}20" PRIu64" ", isGroup.c_str(), screenGroup->dmsId_, screenGroup->rsId_, screenGroup->groupDmsId_, screenType.c_str(), nodeId, isMirrored.c_str(), screenGroup->rSDisplayNodeConfig_.mirrorNodeId); auto childrenScreen = screenGroup->GetChildren(); for (auto screen : childrenScreen) { - std::string isGroup = (dmsScreenGroupMap_.find(screen->dmsId_) != dmsScreenGroupMap_.end()) ? "true" : "false"; + std::string isGroup = + (dmsScreenGroupMap_.find(screen->dmsId_) != dmsScreenGroupMap_.end()) ? "true" : "false"; if (screen->type_ == ScreenType::UNDEFINE) { screenType = "UNDEFINE"; } else if (screen->type_ == ScreenType::REAL) { @@ -768,7 +881,7 @@ void AbstractScreenController::DumpScreenGroupInfo() const isMirrored = screen->rSDisplayNodeConfig_.isMirrored ? "true" : "false"; nodeId = (screen->rsDisplayNode_ == nullptr) ? 0 : screen->rsDisplayNode_->GetId(); WLOGI("%{public}10s %{public}20" PRIu64" %{public}20" PRIu64" %{public}20" PRIu64" %{public}10s %{public}20" - PRIu64" %{public}10s %{public}20" PRIu64" ", isGroup.c_str(), screen->dmsId_,screen->rsId_, + PRIu64" %{public}10s %{public}20" PRIu64" ", isGroup.c_str(), screen->dmsId_, screen->rsId_, screen->groupDmsId_, screenType.c_str(), nodeId, isMirrored.c_str(), screen->rSDisplayNodeConfig_.mirrorNodeId); } diff --git a/dmserver/src/display_manager_agent_controller.cpp b/dmserver/src/display_manager_agent_controller.cpp index 0f666e86..7fbbcd16 100644 --- a/dmserver/src/display_manager_agent_controller.cpp +++ b/dmserver/src/display_manager_agent_controller.cpp @@ -88,26 +88,43 @@ void DisplayManagerAgentController::OnScreenDisconnect(ScreenId screenId) } } -void DisplayManagerAgentController::OnScreenChange(sptr screenInfo, ScreenChangeEvent screenChangeEvent) +void DisplayManagerAgentController::OnScreenChange(const sptr screenInfo, + ScreenChangeEvent screenChangeEvent) { if (screenInfo == nullptr) { return; } - std::vector> screenInfos; - screenInfos.push_back(screenInfo); - OnScreenChange(screenInfos, screenChangeEvent); + auto agents = dmAgentContainer_.GetAgentsByType(DisplayManagerAgentType::SCREEN_EVENT_LISTENER); + if (agents.empty()) { + return; + } + WLOGFI("OnScreenChange"); + for (auto& agent : agents) { + agent->OnScreenChange(screenInfo, screenChangeEvent); + } } -void DisplayManagerAgentController::OnScreenChange( - const std::vector>& screenInfos, ScreenChangeEvent screenChangeEvent) +void DisplayManagerAgentController::OnScreenGroupChange(const sptr& screenInfo, + ScreenGroupChangeEvent groupEvent) +{ + if (screenInfo == nullptr) { + return; + } + std::vector> screenInfos; + screenInfos.push_back(screenInfo); + OnScreenGroupChange(screenInfos, groupEvent); +} + +void DisplayManagerAgentController::OnScreenGroupChange( + const std::vector>& screenInfos, ScreenGroupChangeEvent groupEvent) { auto agents = dmAgentContainer_.GetAgentsByType(DisplayManagerAgentType::SCREEN_EVENT_LISTENER); if (agents.empty() || screenInfos.empty()) { return; } - WLOGFI("OnScreenChange"); + WLOGFI("OnScreenGroupChange"); for (auto& agent : agents) { - agent->OnScreenChange(screenInfos, screenChangeEvent); + agent->OnScreenGroupChange(screenInfos, groupEvent); } } diff --git a/dmserver/src/display_manager_proxy.cpp b/dmserver/src/display_manager_proxy.cpp index 180dc4a4..d2f60c2f 100644 --- a/dmserver/src/display_manager_proxy.cpp +++ b/dmserver/src/display_manager_proxy.cpp @@ -52,12 +52,12 @@ DisplayId DisplayManagerProxy::GetDefaultDisplayId() return displayId; } -DisplayInfo DisplayManagerProxy::GetDisplayInfoById(DisplayId displayId) +sptr DisplayManagerProxy::GetDisplayInfoById(DisplayId displayId) { sptr remote = Remote(); if (remote == nullptr) { WLOGFW("GetDisplayInfoById: remote is nullptr"); - return DisplayInfo(); + return nullptr; } MessageParcel data; @@ -65,30 +65,62 @@ DisplayInfo DisplayManagerProxy::GetDisplayInfoById(DisplayId displayId) MessageOption option; if (!data.WriteInterfaceToken(GetDescriptor())) { WLOGFE("GetDisplayInfoById: WriteInterfaceToken failed"); - return DisplayInfo(); + return nullptr; } if (!data.WriteUint64(displayId)) { WLOGFW("GetDisplayInfoById: WriteUint64 displayId failed"); - return DisplayInfo(); + return nullptr; } if (remote->SendRequest(TRANS_ID_GET_DISPLAY_BY_ID, data, reply, option) != ERR_NONE) { WLOGFW("GetDisplayInfoById: SendRequest failed"); - return DisplayInfo(); + return nullptr; } sptr info = reply.ReadParcelable(); if (info == nullptr) { WLOGFW("DisplayManagerProxy::GetDisplayInfoById SendRequest nullptr."); - return DisplayInfo(); + return nullptr; } - return *info; + return info; +} + +sptr DisplayManagerProxy::GetDisplayInfoByScreen(ScreenId screenId) +{ + sptr remote = Remote(); + if (remote == nullptr) { + WLOGFE("fail to get displayInfo by screenId: remote is null"); + return nullptr; + } + + MessageParcel data; + MessageParcel reply; + MessageOption option; + if (!data.WriteInterfaceToken(GetDescriptor())) { + WLOGFE("fail to get displayInfo by screenId: WriteInterfaceToken failed"); + return nullptr; + } + if (!data.WriteUint64(screenId)) { + WLOGFW("fail to get displayInfo by screenId: WriteUint64 displayId failed"); + return nullptr; + } + if (remote->SendRequest(TRANS_ID_GET_DISPLAY_BY_SCREEN, data, reply, option) != ERR_NONE) { + WLOGFW("fail to get displayInfo by screenId: SendRequest failed"); + return nullptr; + } + + sptr info = reply.ReadParcelable(); + if (info == nullptr) { + WLOGFW("fail to get displayInfo by screenId: SendRequest null"); + return nullptr; + } + return info; } ScreenId DisplayManagerProxy::CreateVirtualScreen(VirtualScreenOption virtualOption) { sptr remote = Remote(); if (remote == nullptr) { - WLOGFW("DisplayManagerProxy::CreateVirtualScreen: remote is nullptr"); + WLOGFW("CreateVirtualScreen: remote is nullptr"); return SCREEN_ID_INVALID; } @@ -96,24 +128,31 @@ ScreenId DisplayManagerProxy::CreateVirtualScreen(VirtualScreenOption virtualOpt MessageParcel reply; MessageOption option; if (!data.WriteInterfaceToken(GetDescriptor())) { - WLOGFE("DisplayManagerProxy::CreateVirtualScreen: WriteInterfaceToken failed"); + WLOGFE("CreateVirtualScreen: WriteInterfaceToken failed"); return SCREEN_ID_INVALID; } bool res = data.WriteString(virtualOption.name_) && data.WriteUint32(virtualOption.width_) && data.WriteUint32(virtualOption.height_) && data.WriteFloat(virtualOption.density_) && - data.WriteRemoteObject(virtualOption.surface_->GetProducer()->AsObject()) && data.WriteInt32(virtualOption.flags_) && data.WriteBool(virtualOption.isForShot_); + if (virtualOption.surface_ != nullptr && virtualOption.surface_->GetProducer() != nullptr) { + res = res && + data.WriteBool(true) && + data.WriteRemoteObject(virtualOption.surface_->GetProducer()->AsObject()); + } else { + WLOGFW("CreateVirtualScreen: surface is nullptr"); + res = res && data.WriteBool(false); + } if (!res) { - WLOGFE("DisplayManagerProxy::Write data failed"); + WLOGFE("Write data failed"); return SCREEN_ID_INVALID; } if (remote->SendRequest(TRANS_ID_CREATE_VIRTUAL_SCREEN, data, reply, option) != ERR_NONE) { - WLOGFW("DisplayManagerProxy::CreateVirtualScreen: SendRequest failed"); + WLOGFW("CreateVirtualScreen: SendRequest failed"); return SCREEN_ID_INVALID; } ScreenId screenId = static_cast(reply.ReadUint64()); - WLOGFI("DisplayManagerProxy::CreateVirtualScreen %" PRIu64"", screenId); + WLOGFI("CreateVirtualScreen %" PRIu64"", screenId); return screenId; } @@ -121,7 +160,7 @@ DMError DisplayManagerProxy::DestroyVirtualScreen(ScreenId screenId) { sptr remote = Remote(); if (remote == nullptr) { - WLOGFW("DisplayManagerProxy::DestroyVirtualScreen: remote is nullptr"); + WLOGFW("DestroyVirtualScreen: remote is nullptr"); return DMError::DM_ERROR_REMOTE_CREATE_FAILED; } @@ -129,15 +168,15 @@ DMError DisplayManagerProxy::DestroyVirtualScreen(ScreenId screenId) MessageParcel reply; MessageOption option; if (!data.WriteInterfaceToken(GetDescriptor())) { - WLOGFE("DisplayManagerProxy::DestroyVirtualScreen: WriteInterfaceToken failed"); + WLOGFE("DestroyVirtualScreen: WriteInterfaceToken failed"); return DMError::DM_ERROR_WRITE_INTERFACE_TOKEN_FAILED; } if (!data.WriteUint64(static_cast(screenId))) { - WLOGFW("DisplayManagerProxy::DestroyVirtualScreen: WriteUint64 screenId failed"); + WLOGFW("DestroyVirtualScreen: WriteUint64 screenId failed"); return DMError::DM_ERROR_IPC_FAILED; } if (remote->SendRequest(TRANS_ID_DESTROY_VIRTUAL_SCREEN, data, reply, option) != ERR_NONE) { - WLOGFW("DisplayManagerProxy::DestroyVirtualScreen: SendRequest failed"); + WLOGFW("DestroyVirtualScreen: SendRequest failed"); return DMError::DM_ERROR_IPC_FAILED; } return static_cast(reply.ReadInt32()); @@ -158,8 +197,16 @@ DMError DisplayManagerProxy::SetVirtualScreenSurface(ScreenId screenId, sptr(screenId)) || - !data.WriteRemoteObject(surface->GetProducer()->AsObject())) { + bool res = data.WriteUint64(static_cast(screenId)); + if (surface != nullptr && surface->GetProducer() != nullptr) { + res = res && + data.WriteBool(true) && + data.WriteRemoteObject(surface->GetProducer()->AsObject()); + } else { + WLOGFW("SetVirtualScreenSurface: surface is nullptr"); + res = res && data.WriteBool(false); + } + if (!res) { WLOGFW("SetVirtualScreenSurface: Write screenId/surface failed"); return DMError::DM_ERROR_IPC_FAILED; } @@ -170,11 +217,11 @@ DMError DisplayManagerProxy::SetVirtualScreenSurface(ScreenId screenId, sptr(reply.ReadInt32()); } -bool DisplayManagerProxy::RequestRotation(ScreenId screenId, Rotation rotation) +bool DisplayManagerProxy::SetOrientation(ScreenId screenId, Orientation orientation) { sptr remote = Remote(); if (remote == nullptr) { - WLOGFW("fail to request rotation: remote is null"); + WLOGFW("fail to set orientation: remote is null"); return false; } @@ -182,29 +229,29 @@ bool DisplayManagerProxy::RequestRotation(ScreenId screenId, Rotation rotation) MessageParcel reply; MessageOption option; if (!data.WriteInterfaceToken(GetDescriptor())) { - WLOGFE("fail to request rotation: WriteInterfaceToken failed"); + WLOGFE("fail to set orientation: WriteInterfaceToken failed"); return false; } if (!data.WriteUint64(static_cast(screenId))) { - WLOGFW("fail to request rotation: Write screenId failed"); + WLOGFW("fail to set orientation: Write screenId failed"); return false; } - if (!data.WriteUint32(static_cast(rotation))) { - WLOGFW("fail to request rotation: Write rotation failed"); + if (!data.WriteUint32(static_cast(orientation))) { + WLOGFW("fail to set orientation: Write orientation failed"); return false; } - if (remote->SendRequest(TRANS_ID_REQUEST_ROTATION, data, reply, option) != ERR_NONE) { - WLOGFW("fail to request rotation: SendRequest failed"); + if (remote->SendRequest(TRANS_ID_SET_ORIENTATION, data, reply, option) != ERR_NONE) { + WLOGFW("fail to set orientation: SendRequest failed"); return false; } return reply.ReadBool(); } -std::shared_ptr DisplayManagerProxy::GetDispalySnapshot(DisplayId displayId) +std::shared_ptr DisplayManagerProxy::GetDisplaySnapshot(DisplayId displayId) { sptr remote = Remote(); if (remote == nullptr) { - WLOGFW("GetDispalySnapshot: remote is nullptr"); + WLOGFW("GetDisplaySnapshot: remote is nullptr"); return nullptr; } @@ -212,7 +259,7 @@ std::shared_ptr DisplayManagerProxy::GetDispalySnapshot(Display MessageParcel reply; MessageOption option; if (!data.WriteInterfaceToken(GetDescriptor())) { - WLOGFE("GetDispalySnapshot: WriteInterfaceToken failed"); + WLOGFE("GetDisplaySnapshot: WriteInterfaceToken failed"); return nullptr; } @@ -222,13 +269,13 @@ std::shared_ptr DisplayManagerProxy::GetDispalySnapshot(Display } if (remote->SendRequest(TRANS_ID_GET_DISPLAY_SNAPSHOT, data, reply, option) != ERR_NONE) { - WLOGFW("GetDispalySnapshot: SendRequest failed"); + WLOGFW("GetDisplaySnapshot: SendRequest failed"); return nullptr; } std::shared_ptr pixelMap(reply.ReadParcelable()); if (pixelMap == nullptr) { - WLOGFW("DisplayManagerProxy::GetDispalySnapshot SendRequest nullptr."); + WLOGFW("DisplayManagerProxy::GetDisplaySnapshot SendRequest nullptr."); return nullptr; } return pixelMap; @@ -606,6 +653,24 @@ DisplayState DisplayManagerProxy::GetDisplayState(DisplayId displayId) return static_cast(reply.ReadUint32()); } +std::vector DisplayManagerProxy::GetAllDisplayIds() +{ + std::vector allDisplayIds; + MessageParcel data; + MessageParcel reply; + MessageOption option; + if (!data.WriteInterfaceToken(GetDescriptor())) { + WLOGFE("WriteInterfaceToken failed"); + return allDisplayIds; + } + if (Remote()->SendRequest(TRANS_ID_GET_ALL_DISPLAYIDS, data, reply, option) != ERR_NONE) { + WLOGFW("SendRequest failed"); + return allDisplayIds; + } + reply.ReadUInt64Vector(&allDisplayIds); + return allDisplayIds; +} + void DisplayManagerProxy::NotifyDisplayEvent(DisplayEvent event) { MessageParcel data; @@ -625,12 +690,12 @@ void DisplayManagerProxy::NotifyDisplayEvent(DisplayEvent event) } } -DMError DisplayManagerProxy::MakeMirror(ScreenId mainScreenId, std::vector mirrorScreenId) +ScreenId DisplayManagerProxy::MakeMirror(ScreenId mainScreenId, std::vector mirrorScreenId) { sptr remote = Remote(); if (remote == nullptr) { WLOGFW("create mirror fail: remote is null"); - return DMError::DM_ERROR_REMOTE_CREATE_FAILED; + return SCREEN_ID_INVALID; } MessageParcel data; @@ -638,19 +703,19 @@ DMError DisplayManagerProxy::MakeMirror(ScreenId mainScreenId, std::vector(mainScreenId)) && data.WriteUInt64Vector(mirrorScreenId); if (!res) { WLOGFE("create mirror fail: data write failed"); - return DMError::DM_ERROR_WRITE_DATA_FAILED; + return SCREEN_ID_INVALID; } if (remote->SendRequest(TRANS_ID_SCREEN_MAKE_MIRROR, data, reply, option) != ERR_NONE) { WLOGFW("create mirror fail: SendRequest failed"); - return DMError::DM_ERROR_IPC_FAILED; + return SCREEN_ID_INVALID; } - return static_cast(reply.ReadInt32()); + return static_cast(reply.ReadUint64()); } sptr DisplayManagerProxy::GetScreenInfoById(ScreenId screenId) @@ -682,9 +747,9 @@ sptr DisplayManagerProxy::GetScreenInfoById(ScreenId screenId) WLOGFW("GetScreenInfoById SendRequest nullptr."); return nullptr; } - for (int i = 0; i < info->modes_.size(); i++) { + for (auto& mode : info->GetModes()) { WLOGFI("info modes is width: %{public}u, height: %{public}u, freshRate: %{public}u", - info->modes_[i]->width_, info->modes_[i]->height_, info->modes_[i]->freshRate_); + mode->width_, mode->height_, mode->freshRate_); } return info; } @@ -750,12 +815,12 @@ std::vector> DisplayManagerProxy::GetAllScreenInfos() return screenInfos; } -DMError DisplayManagerProxy::MakeExpand(std::vector screenId, std::vector startPoint) +ScreenId DisplayManagerProxy::MakeExpand(std::vector screenId, std::vector startPoint) { sptr remote = Remote(); if (remote == nullptr) { WLOGFW("MakeExpand: remote is null"); - return DMError::DM_ERROR_REMOTE_CREATE_FAILED; + return SCREEN_ID_INVALID; } MessageParcel data; @@ -763,28 +828,53 @@ DMError DisplayManagerProxy::MakeExpand(std::vector screenId, std::vec MessageOption option; if (!data.WriteInterfaceToken(GetDescriptor())) { WLOGFE("MakeExpand: WriteInterfaceToken failed"); - return DMError::DM_ERROR_WRITE_INTERFACE_TOKEN_FAILED; + return SCREEN_ID_INVALID; } if (!data.WriteUInt64Vector(screenId)) { WLOGFE("MakeExpand: write screenId failed"); - return DMError::DM_ERROR_WRITE_DATA_FAILED; + return SCREEN_ID_INVALID; } uint32_t num = startPoint.size(); if (!data.WriteUint32(num)) { WLOGFE("MakeExpand: write startPoint size failed"); - return DMError::DM_ERROR_WRITE_DATA_FAILED; + return SCREEN_ID_INVALID; } for (auto point: startPoint) { if (!(data.WriteInt32(point.posX_) && data.WriteInt32(point.posY_))) { WLOGFE("MakeExpand: write startPoint failed"); - return DMError::DM_ERROR_WRITE_DATA_FAILED; + return SCREEN_ID_INVALID; } } if (remote->SendRequest(TRANS_ID_SCREEN_MAKE_EXPAND, data, reply, option) != ERR_NONE) { WLOGFE("MakeExpand: SendRequest failed"); - return DMError::DM_ERROR_IPC_FAILED; + return SCREEN_ID_INVALID; + } + return static_cast(reply.ReadUint64()); +} + +void DisplayManagerProxy::RemoveVirtualScreenFromGroup(std::vector screens) +{ + sptr remote = Remote(); + if (remote == nullptr) { + WLOGFW("cancel make mirror or expand fail: remote is null"); + return; + } + + MessageParcel data; + MessageParcel reply; + MessageOption option; + if (!data.WriteInterfaceToken(GetDescriptor())) { + WLOGFE("cancel make mirror or expand fail: WriteInterfaceToken failed"); + return; + } + bool res = data.WriteUInt64Vector(screens); + if (!res) { + WLOGFE("cancel make mirror or expand fail: write screens failed."); + return; + } + if (remote->SendRequest(TRANS_ID_SCREEN_MAKE_MIRROR_OR_EXPAND_CANCELED, data, reply, option) != ERR_NONE) { + WLOGFW("cancel make mirror or expand fail: SendRequest failed"); } - return static_cast(reply.ReadInt32()); } bool DisplayManagerProxy::SetScreenActiveMode(ScreenId screenId, uint32_t modeId) diff --git a/dmserver/src/display_manager_service.cpp b/dmserver/src/display_manager_service.cpp index b2c9b499..0df7222e 100644 --- a/dmserver/src/display_manager_service.cpp +++ b/dmserver/src/display_manager_service.cpp @@ -33,7 +33,8 @@ const bool REGISTER_RESULT = SystemAbility::MakeAndRegisterAbility(&SingletonCon DisplayManagerService::DisplayManagerService() : SystemAbility(DISPLAY_MANAGER_SERVICE_SA_ID, true), abstractDisplayController_(new AbstractDisplayController(mutex_)), - abstractScreenController_(new AbstractScreenController(mutex_)) + abstractScreenController_(new AbstractScreenController(mutex_)), + displayPowerController_(new DisplayPowerController(mutex_)) { } @@ -84,25 +85,34 @@ ScreenId DisplayManagerService::GetScreenIdFromDisplayId(DisplayId displayId) DisplayId DisplayManagerService::GetDefaultDisplayId() { - ScreenId screenId = abstractDisplayController_->GetDefaultScreenId(); - WLOGFI("GetDefaultDisplayId %{public}" PRIu64"", screenId); - return GetDisplayIdFromScreenId(screenId); + ScreenId dmsScreenId = abstractScreenController_->GetDefaultScreenId(); + WLOGFI("GetDefaultDisplayId %{public}" PRIu64"", dmsScreenId); + sptr display = GetDisplayByScreen(dmsScreenId); + if (display == nullptr) { + WLOGFE("fail to get displayInfo by id: invalid display"); + return DISPLAY_ID_INVALD; + } + return display->GetId(); } -DisplayInfo DisplayManagerService::GetDisplayInfoById(DisplayId displayId) +sptr DisplayManagerService::GetDisplayInfoById(DisplayId displayId) { - DisplayInfo displayInfo; sptr display = GetDisplayByDisplayId(displayId); if (display == nullptr) { - WLOGFE("GetDisplayById: Get invalid display!"); - return displayInfo; + WLOGFE("fail to get displayInfo by id: invalid display"); + return nullptr; } - displayInfo.id_ = displayId; - displayInfo.width_ = display->GetWidth(); - displayInfo.height_ = display->GetHeight(); - displayInfo.freshRate_ = display->GetFreshRate(); - displayInfo.screenId_ = display->GetAbstractScreenId(); - return displayInfo; + return display->ConvertToDisplayInfo(); +} + +sptr DisplayManagerService::GetDisplayInfoByScreen(ScreenId screenId) +{ + sptr display = GetDisplayByScreen(screenId); + if (display == nullptr) { + WLOGFE("fail to get displayInfo by screenId: invalid display"); + return nullptr; + } + return display->ConvertToDisplayInfo(); } sptr DisplayManagerService::GetAbstractDisplay(DisplayId displayId) @@ -113,8 +123,6 @@ sptr DisplayManagerService::GetAbstractDisplay(DisplayId displa ScreenId DisplayManagerService::CreateVirtualScreen(VirtualScreenOption option) { WM_SCOPED_TRACE("dms:CreateVirtualScreen(%s)", option.name_.c_str()); - WLOGFI("DumpScreenInfo before Create VirtualScreen"); - abstractScreenController_->DumpScreenInfo(); ScreenId screenId = abstractScreenController_->CreateVirtualScreen(option); if (screenId == SCREEN_ID_INVALID) { WLOGFE("DisplayManagerService::CreateVirtualScreen: Get virtualScreenId failed"); @@ -160,15 +168,15 @@ DMError DisplayManagerService::SetVirtualScreenSurface(ScreenId screenId, sptrSetVirtualScreenSurface(screenId, surface); } -bool DisplayManagerService::RequestRotation(ScreenId screenId, Rotation rotation) +bool DisplayManagerService::SetOrientation(ScreenId screenId, Orientation orientation) { - WM_SCOPED_TRACE("dms:RequestRotation(%" PRIu64")", screenId); - return abstractScreenController_->RequestRotation(screenId, rotation); + WM_SCOPED_TRACE("dms:SetOrientation(%" PRIu64")", screenId); + return abstractScreenController_->SetOrientation(screenId, orientation); } -std::shared_ptr DisplayManagerService::GetDispalySnapshot(DisplayId displayId) +std::shared_ptr DisplayManagerService::GetDisplaySnapshot(DisplayId displayId) { - WM_SCOPED_TRACE("dms:GetDispalySnapshot(%" PRIu64")", displayId); + WM_SCOPED_TRACE("dms:GetDisplaySnapshot(%" PRIu64")", displayId); std::shared_ptr screenSnapshot = abstractDisplayController_->GetScreenSnapshot(displayId); return screenSnapshot; @@ -296,7 +304,7 @@ bool DisplayManagerService::WakeUpEnd() bool DisplayManagerService::SuspendBegin(PowerStateChangeReason reason) { WM_SCOPED_TRACE("dms:SuspendBegin(%u)", reason); - displayPowerController_.SuspendBegin(reason); + displayPowerController_->SuspendBegin(reason); return DisplayManagerAgentController::GetInstance().NotifyDisplayPowerEvent(DisplayPowerEvent::SLEEP, EventStatus::BEGIN); } @@ -317,8 +325,7 @@ bool DisplayManagerService::SetScreenPowerForAll(DisplayPowerState state, PowerS bool DisplayManagerService::SetDisplayState(DisplayState state) { - std::lock_guard lock(mutex_); - return displayPowerController_.SetDisplayState(state); + return displayPowerController_->SetDisplayState(state); } ScreenId DisplayManagerService::GetScreenIdByDisplayId(DisplayId displayId) const @@ -336,6 +343,11 @@ sptr DisplayManagerService::GetDisplayByDisplayId(DisplayId dis return abstractDisplayController_->GetAbstractDisplay(displayId); } +sptr DisplayManagerService::GetDisplayByScreen(ScreenId screenId) const +{ + return abstractDisplayController_->GetAbstractDisplayByScreen(screenId); +} + sptr DisplayManagerService::GetAbstractScreenController() { return abstractScreenController_; @@ -344,13 +356,12 @@ sptr DisplayManagerService::GetAbstractScreenControlle DisplayState DisplayManagerService::GetDisplayState(DisplayId displayId) { std::lock_guard lock(mutex_); - return displayPowerController_.GetDisplayState(displayId); + return displayPowerController_->GetDisplayState(displayId); } void DisplayManagerService::NotifyDisplayEvent(DisplayEvent event) { - std::lock_guard lock(mutex_); - displayPowerController_.NotifyDisplayEvent(event); + displayPowerController_->NotifyDisplayEvent(event); } @@ -367,6 +378,10 @@ std::shared_ptr DisplayManagerService::GetRSDisplayNodeByDisplayI void DisplayManagerService::SetShotScreen(ScreenId mainScreenId, std::vector shotScreenIds) { WLOGFI("SetShotScreen. mainScreenId: %{public}" PRIu64"", mainScreenId); + if (shotScreenIds.empty()) { + WLOGFI("shotScreenIds is empty"); + return; + } std::shared_ptr displayNode = abstractScreenController_->GetRSDisplayNodeByScreenId(mainScreenId); if (displayNode == nullptr) { WLOGFE("SetShotScreen error, cannot get DisplayNode"); @@ -386,10 +401,9 @@ void DisplayManagerService::SetShotScreen(ScreenId mainScreenId, std::vectorFlushImplicitTransaction(); } -DMError DisplayManagerService::MakeMirror(ScreenId mainScreenId, std::vector mirrorScreenIds) +ScreenId DisplayManagerService::MakeMirror(ScreenId mainScreenId, std::vector mirrorScreenIds) { WLOGFI("MakeMirror. mainScreenId :%{public}" PRIu64"", mainScreenId); - abstractScreenController_->DumpScreenInfo(); auto shotScreenIds = abstractScreenController_->GetShotScreenIds(mirrorScreenIds); auto iter = std::find(shotScreenIds.begin(), shotScreenIds.end(), mainScreenId); if (iter != shotScreenIds.end()) { @@ -402,16 +416,26 @@ DMError DisplayManagerService::MakeMirror(ScreenId mainScreenId, std::vectorMakeMirror(mainScreenId, allMirrorScreenIds)) { WLOGFE("make mirror failed."); - return DMError::DM_ERROR_NULLPTR; + return SCREEN_ID_INVALID; } abstractScreenController_->DumpScreenInfo(); - return DMError::DM_OK; + auto screen = abstractScreenController_->GetAbstractScreen(mainScreenId); + if (screen == nullptr || abstractScreenController_->GetAbstractScreenGroup(screen->groupDmsId_) == nullptr) { + WLOGFE("get screen group failed."); + return SCREEN_ID_INVALID; + } + return screen->groupDmsId_; +} + +void DisplayManagerService::RemoveVirtualScreenFromGroup(std::vector screens) +{ + abstractScreenController_->RemoveVirtualScreenFromGroup(screens); } void DisplayManagerService::UpdateRSTree(DisplayId displayId, std::shared_ptr& surfaceNode, @@ -445,6 +469,11 @@ sptr DisplayManagerService::GetScreenGroupInfoById(ScreenId scr return screenGroup->ConvertToScreenGroupInfo(); } +std::vector DisplayManagerService::GetAllDisplayIds() +{ + return abstractDisplayController_->GetAllDisplayIds(); +} + std::vector> DisplayManagerService::GetAllScreenInfos() { std::vector screenIds = abstractScreenController_->GetAllScreenIds(); @@ -460,16 +489,15 @@ std::vector> DisplayManagerService::GetAllScreenInfos() return screenInfos; } -DMError DisplayManagerService::MakeExpand(std::vector expandScreenIds, std::vector startPoints) +ScreenId DisplayManagerService::MakeExpand(std::vector expandScreenIds, std::vector startPoints) { WLOGI("MakeExpand"); if (expandScreenIds.empty() || startPoints.empty() || expandScreenIds.size() != startPoints.size()) { WLOGFI("create expand fail, input params is invalid. " "screenId vector size :%{public}ud, startPoint vector size :%{public}ud", static_cast(expandScreenIds.size()), static_cast(startPoints.size())); - return DMError::DM_ERROR_INVALID_PARAM; + return SCREEN_ID_INVALID; } - abstractScreenController_->DumpScreenInfo(); ScreenId defaultScreenId = abstractScreenController_->GetDefaultAbstractScreenId(); WLOGI("MakeExpand, defaultScreenId:%{public}" PRIu64"", defaultScreenId); auto shotScreenIds = abstractScreenController_->GetShotScreenIds(expandScreenIds); @@ -490,10 +518,15 @@ DMError DisplayManagerService::MakeExpand(std::vector expandScreenIds, WM_SCOPED_TRACE("dms:MakeExpand"); if (!allExpandScreenIds.empty() && !abstractScreenController_->MakeExpand(allExpandScreenIds, startPoints)) { WLOGFE("make expand failed."); - return DMError::DM_ERROR_NULLPTR; + return SCREEN_ID_INVALID; } abstractScreenController_->DumpScreenInfo(); - return DMError::DM_OK; + auto screen = abstractScreenController_->GetAbstractScreen(allExpandScreenIds[0]); + if (screen == nullptr || abstractScreenController_->GetAbstractScreenGroup(screen->groupDmsId_) == nullptr) { + WLOGFE("get screen group failed."); + return SCREEN_ID_INVALID; + } + return screen->groupDmsId_; } bool DisplayManagerService::SetScreenActiveMode(ScreenId screenId, uint32_t modeId) diff --git a/dmserver/src/display_manager_service_inner.cpp b/dmserver/src/display_manager_service_inner.cpp index a53ccf8a..0c97b615 100644 --- a/dmserver/src/display_manager_service_inner.cpp +++ b/dmserver/src/display_manager_service_inner.cpp @@ -41,23 +41,24 @@ const sptr DisplayManagerServiceInner::GetDisplayById(DisplayId { sptr display = DisplayManagerService::GetInstance().GetAbstractDisplay(displayId); if (display == nullptr) { - DisplayInfo displayInfo = DisplayManagerService::GetInstance().GetDisplayInfoById(displayId); - display = new AbstractDisplay(displayInfo); - WLOGFE("GetDisplayById create new!\n"); + WLOGFE("GetDisplayById can not find corresponding display!\n"); } return display; } const sptr DisplayManagerServiceInner::GetDefaultDisplay() { + DisplayId defaultDisplayId = GetDefaultDisplayId(); + if (defaultDisplayId == DISPLAY_ID_INVALD) { + WLOGFE("Fail to get default displayId"); + return nullptr; + } return GetDisplayById(GetDefaultDisplayId()); } std::vector DisplayManagerServiceInner::GetAllDisplayIds() { - std::vector res; - res.push_back(GetDefaultDisplayId()); - return res; + return DisplayManagerService::GetInstance().GetAllDisplayIds(); } std::vector> DisplayManagerServiceInner::GetAllDisplays() @@ -92,6 +93,23 @@ const sptr DisplayManagerServiceInner::GetScreenInfoByDisplayId(Disp DisplayManagerService::GetInstance().GetScreenIdByDisplayId(displayId)); } +const sptr DisplayManagerServiceInner::GetScreenModesByDisplayId(DisplayId displayId) +{ + const sptr display = GetDisplayById(displayId); + if (display == nullptr) { + WLOGFE("can not get display."); + return nullptr; + } + ScreenId dmsScreenId = display->GetAbstractScreenId(); + sptr abstractScreen = + DisplayManagerService::GetInstance().abstractScreenController_->GetAbstractScreen(dmsScreenId); + if (abstractScreen == nullptr) { + WLOGFE("can not get screenMode."); + return nullptr; + } + return abstractScreen->GetActiveScreenMode(); +} + void DisplayManagerServiceInner::RegisterDisplayChangeListener(sptr listener) { DisplayManagerService::GetInstance().RegisterDisplayChangeListener(listener); diff --git a/dmserver/src/display_manager_stub.cpp b/dmserver/src/display_manager_stub.cpp index 2504aef4..243e4fe2 100644 --- a/dmserver/src/display_manager_stub.cpp +++ b/dmserver/src/display_manager_stub.cpp @@ -45,7 +45,13 @@ int32_t DisplayManagerStub::OnRemoteRequest(uint32_t code, MessageParcel &data, case TRANS_ID_GET_DISPLAY_BY_ID: { DisplayId displayId = data.ReadUint64(); auto info = GetDisplayInfoById(displayId); - reply.WriteParcelable(&info); + reply.WriteParcelable(info); + break; + } + case TRANS_ID_GET_DISPLAY_BY_SCREEN: { + ScreenId screenId = data.ReadUint64(); + auto info = GetDisplayInfoByScreen(screenId); + reply.WriteParcelable(info); break; } case TRANS_ID_CREATE_VIRTUAL_SCREEN: { @@ -53,11 +59,15 @@ int32_t DisplayManagerStub::OnRemoteRequest(uint32_t code, MessageParcel &data, uint32_t width = data.ReadUint32(); uint32_t height = data.ReadUint32(); float density = data.ReadFloat(); - sptr surfaceObject = data.ReadRemoteObject(); - sptr bp = iface_cast(surfaceObject); - sptr surface = Surface::CreateSurfaceAsProducer(bp); int32_t flags = data.ReadInt32(); bool isForShot = data.ReadBool(); + bool isSurfaceValid = data.ReadBool(); + sptr surface = nullptr; + if (isSurfaceValid) { + sptr surfaceObject = data.ReadRemoteObject(); + sptr bp = iface_cast(surfaceObject); + surface = Surface::CreateSurfaceAsProducer(bp); + } VirtualScreenOption option = { .name_ = name, .width_ = width, @@ -79,22 +89,26 @@ int32_t DisplayManagerStub::OnRemoteRequest(uint32_t code, MessageParcel &data, } case TRANS_ID_SET_VIRTUAL_SCREEN_SURFACE: { ScreenId screenId = static_cast(data.ReadUint64()); - sptr surfaceObject = data.ReadRemoteObject(); - sptr bp = iface_cast(surfaceObject); - sptr surface = Surface::CreateSurfaceAsProducer(bp); + bool isSurfaceValid = data.ReadBool(); + sptr surface = nullptr; + if (isSurfaceValid) { + sptr surfaceObject = data.ReadRemoteObject(); + sptr bp = iface_cast(surfaceObject); + surface = Surface::CreateSurfaceAsProducer(bp); + } DMError result = SetVirtualScreenSurface(screenId, surface); reply.WriteInt32(static_cast(result)); break; } - case TRANS_ID_REQUEST_ROTATION: { + case TRANS_ID_SET_ORIENTATION: { ScreenId screenId = static_cast(data.ReadUint64()); - Rotation rotation = static_cast(data.ReadUint32()); - reply.WriteBool(RequestRotation(screenId, rotation)); + Orientation orientation = static_cast(data.ReadUint32()); + reply.WriteBool(SetOrientation(screenId, orientation)); break; } case TRANS_ID_GET_DISPLAY_SNAPSHOT: { DisplayId displayId = data.ReadUint64(); - std::shared_ptr dispalySnapshot = GetDispalySnapshot(displayId); + std::shared_ptr dispalySnapshot = GetDisplaySnapshot(displayId); if (dispalySnapshot == nullptr) { reply.WriteParcelable(nullptr); break; @@ -159,16 +173,16 @@ int32_t DisplayManagerStub::OnRemoteRequest(uint32_t code, MessageParcel &data, WLOGE("fail to receive mirror screen in stub. screen:%{public}" PRIu64"", mainScreenId); break; } - DMError result = MakeMirror(mainScreenId, mirrorScreenId); - reply.WriteInt32(static_cast(result)); + ScreenId result = MakeMirror(mainScreenId, mirrorScreenId); + reply.WriteUint64(static_cast(result)); break; } case TRANS_ID_GET_SCREEN_INFO_BY_ID: { ScreenId screenId = static_cast(data.ReadUint64()); auto screenInfo = GetScreenInfoById(screenId); - for (int i = 0; i < screenInfo->modes_.size(); i++) { + for (auto& mode : screenInfo->GetModes()) { WLOGFI("info modes is width: %{public}u, height: %{public}u, freshRate: %{public}u", - screenInfo->modes_[i]->width_, screenInfo->modes_[i]->height_, screenInfo->modes_[i]->freshRate_); + mode->width_, mode->height_, mode->freshRate_); } reply.WriteStrongParcelable(screenInfo); break; @@ -188,6 +202,11 @@ int32_t DisplayManagerStub::OnRemoteRequest(uint32_t code, MessageParcel &data, } break; } + case TRANS_ID_GET_ALL_DISPLAYIDS: { + std::vector allDisplayIds = GetAllDisplayIds(); + reply.WriteUInt64Vector(allDisplayIds); + break; + } case TRANS_ID_SCREEN_MAKE_EXPAND: { std::vector screenId; if (!data.ReadUInt64Vector(&screenId)) { @@ -200,8 +219,17 @@ int32_t DisplayManagerStub::OnRemoteRequest(uint32_t code, MessageParcel &data, Point point { data.ReadInt32(), data.ReadInt32() }; startPoint.push_back(point); } - DMError result = MakeExpand(screenId, startPoint); - reply.WriteInt32(static_cast(result)); + ScreenId result = MakeExpand(screenId, startPoint); + reply.WriteUint64(static_cast(result)); + break; + } + case TRANS_ID_SCREEN_MAKE_MIRROR_OR_EXPAND_CANCELED: { + std::vector screenId; + if (!data.ReadUInt64Vector(&screenId)) { + WLOGE("fail to receive screens in stub."); + break; + } + RemoveVirtualScreenFromGroup(screenId); break; } case TRANS_ID_SET_SCREEN_ACTIVE_MODE: { diff --git a/dmserver/src/display_power_controller.cpp b/dmserver/src/display_power_controller.cpp index ac3e5cb2..350ca52c 100644 --- a/dmserver/src/display_power_controller.cpp +++ b/dmserver/src/display_power_controller.cpp @@ -35,14 +35,22 @@ bool DisplayPowerController::SuspendBegin(PowerStateChangeReason reason) bool DisplayPowerController::SetDisplayState(DisplayState state) { WLOGFI("state:%{public}u", state); - if (displayState_ == state) { - WLOGFE("state is already set"); - return false; + { + std::lock_guard lock(mutex_); + if (displayState_ == state) { + WLOGFE("state is already set"); + return false; + } } switch (state) { case DisplayState::ON: { - displayState_ = state; - if (!isKeyguardDrawn_) { + bool isKeyguardDrawn; + { + std::lock_guard lock(mutex_); + displayState_ = state; + isKeyguardDrawn = isKeyguardDrawn_; + } + if (!isKeyguardDrawn) { DisplayManagerService::GetInstance().NotifyDisplayStateChange(DISPLAY_ID_INVALD, DisplayStateChangeType::BEFORE_UNLOCK); } @@ -51,7 +59,10 @@ bool DisplayPowerController::SetDisplayState(DisplayState state) break; } case DisplayState::OFF: { - displayState_ = state; + { + std::lock_guard lock(mutex_); + displayState_ = state; + } DisplayManagerAgentController::GetInstance().NotifyDisplayPowerEvent(DisplayPowerEvent::DISPLAY_OFF, EventStatus::BEGIN); break; @@ -78,10 +89,12 @@ void DisplayPowerController::NotifyDisplayEvent(DisplayEvent event) DisplayStateChangeType::BEFORE_UNLOCK); DisplayManagerAgentController::GetInstance().NotifyDisplayPowerEvent(DisplayPowerEvent::DESKTOP_READY, EventStatus::BEGIN); + std::lock_guard lock(mutex_); isKeyguardDrawn_ = false; return; } if (event == DisplayEvent::KEYGUARD_DRAWN) { + std::lock_guard lock(mutex_); isKeyguardDrawn_ = true; } } diff --git a/figures/WindowManager.png b/figures/WindowManager.png new file mode 100644 index 00000000..f4f96ea5 Binary files /dev/null and b/figures/WindowManager.png differ diff --git a/figures/graphic.png b/figures/graphic.png deleted file mode 100644 index b72003f5..00000000 Binary files a/figures/graphic.png and /dev/null differ diff --git a/hisysevent.yaml b/hisysevent.yaml new file mode 100644 index 00000000..147fbfde --- /dev/null +++ b/hisysevent.yaml @@ -0,0 +1,48 @@ +# Copyright (c) 2022 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +##################################################### +# below is the format of defining event # +##################################################### +#domain: domain name. [Only one domain name can be defined at the top] +# +#author: the author name who defined this event. +#date: the date when this event was defined, format is YYYY-MM-DD. +#logged: source file which refer to this event. +#usage: the usage of this event. +#//Define event name and event properties. +#@EVENT_NAME: the event definition part begin. +# // __BASE is used for defining the basic info of the event. +# // "type" optional values are: FAULT, STATISTICS, SECURITY, BEHAVIOR. +# // "level" optional values are: CRITICAL, MINOR. +# // "tag" set tags with may used by subscriber of this event, multiple tags devided by space. +# // "desc" full description of this event. +# @PARAMETER: {type: parameter type, arrsize: array length(optional), desc: parameter description}. +# // follow the __BASE block, each line defines a parameter of this event. +# // "type" optional values are: INT8, UINT8, INT16, UINT16, INT32, UINT32, INT64, UINT64, FLOAT, DOUBLE, STRING. +# // "arrsize" of the parameter is an array, set a non-zero value. +# // "desc" full description of this parameter. + +##################################################### +# Example of some hiviewdfx events definition # +##################################################### + +domain: WINDOWMANAGER + +NO_FOCUS_WINDOW: + __BASE: {type: FAULT, level: CRITICAL, desc: The event is not consumed } + PID: {type: INT32, desc: session pid} + UID: {type: INT32, desc: session uid} + PACKAGE_NAME: {type: STRING, desc: package name} + PROCESS_NAME: {type: STRING, desc: process name} + MSG: {type: STRING, desc: windowmanager event message} \ No newline at end of file diff --git a/interfaces/innerkits/dm/display.h b/interfaces/innerkits/dm/display.h index a71df544..d28e5c72 100644 --- a/interfaces/innerkits/dm/display.h +++ b/interfaces/innerkits/dm/display.h @@ -27,23 +27,29 @@ typedef enum DisplayType { } DisplayType; class Display : public RefBase { +friend class DisplayManager; public: - Display(const std::string& name, DisplayInfo* info); - ~Display() = default; - + ~Display(); + Display(const Display&) = delete; + Display(Display&&) = delete; + Display& operator=(const Display&) = delete; + Display& operator=(Display&&) = delete; DisplayId GetId() const; int32_t GetWidth() const; int32_t GetHeight() const; uint32_t GetFreshRate() const; ScreenId GetScreenId() const; float GetVirtualPixelRatio() const; + Rotation GetRotation() const; + Orientation GetOrientation() const; - void SetId(DisplayId displayId); - void SetWidth(int32_t width); - void SetHeight(int32_t height); - void SetFreshRate(uint32_t freshRate); - +protected: + // No more methods or variables can be defined here. + Display(const std::string& name, sptr info); private: + // No more methods or variables can be defined here. + void UpdateDisplayInfo(sptr) const; + void UpdateDisplayInfo() const; class Impl; sptr pImpl_; }; diff --git a/interfaces/innerkits/dm/display_manager.h b/interfaces/innerkits/dm/display_manager.h index 9bc7384b..7df68703 100644 --- a/interfaces/innerkits/dm/display_manager.h +++ b/interfaces/innerkits/dm/display_manager.h @@ -26,22 +26,21 @@ #include "wm_single_instance.h" namespace OHOS::Rosen { -class DisplayManagerAgent; class DisplayManager { -friend class DisplayManagerAgent; WM_DECLARE_SINGLE_INSTANCE_BASE(DisplayManager); public: class IDisplayListener : public virtual RefBase { public: virtual void OnCreate(DisplayId) = 0; virtual void OnDestroy(DisplayId) = 0; - virtual void OnChange(DisplayId, DisplayChangeEvent) = 0; + virtual void OnChange(DisplayId) = 0; }; - std::vector> GetAllDisplays(); + std::vector> GetAllDisplays(); DisplayId GetDefaultDisplayId(); - const sptr GetDefaultDisplay(); - const sptr GetDisplayById(DisplayId displayId); + sptr GetDefaultDisplay(); + sptr GetDisplayById(DisplayId displayId); + sptr GetDisplayByScreen(ScreenId screenId); std::vector GetAllDisplayIds(); bool RegisterDisplayListener(sptr listener); bool UnregisterDisplayListener(sptr listener); @@ -69,14 +68,8 @@ private: DisplayManager(); ~DisplayManager(); - class DisplayManagerListener; - sptr displayManagerListener_; class Impl; sptr pImpl_; - - void NotifyDisplayPowerEvent(DisplayPowerEvent event, EventStatus status); - void NotifyDisplayStateChanged(DisplayId id, DisplayState state); - void NotifyDisplayChangedEvent(const sptr info, DisplayChangeEvent event); }; } // namespace OHOS::Rosen diff --git a/interfaces/innerkits/dm/dm_common.h b/interfaces/innerkits/dm/dm_common.h index 08180577..20b26f36 100644 --- a/interfaces/innerkits/dm/dm_common.h +++ b/interfaces/innerkits/dm/dm_common.h @@ -22,8 +22,11 @@ namespace OHOS { namespace Rosen { using DisplayId = uint64_t; using ScreenId = uint64_t; -static constexpr DisplayId DISPLAY_ID_INVALD = -1ULL; -static constexpr ScreenId SCREEN_ID_INVALID = -1ULL; +namespace { + constexpr DisplayId DISPLAY_ID_INVALD = -1ULL; + constexpr ScreenId SCREEN_ID_INVALID = -1ULL; + const static std::string DEFAULT_SCREEN_NAME = "buildIn"; +} enum class PowerStateChangeReason : uint32_t { POWER_BUTTON, @@ -84,11 +87,14 @@ public: }; enum class ScreenChangeEvent : uint32_t { + UPDATE_ORIENTATION, + CHANGE_MODE, +}; + +enum class ScreenGroupChangeEvent : uint32_t { ADD_TO_GROUP, REMOVE_FROM_GROUP, CHANGE_GROUP, - UPDATE_ROTATION, - CHANGE_MODE, }; enum class Rotation : uint32_t { @@ -98,8 +104,21 @@ enum class Rotation : uint32_t { ROTATION_270, }; +enum class Orientation : uint32_t { + BEGIN = 0, + UNSPECIFIED = BEGIN, + VERTICAL = 1, + HORIZONTAL = 2, + REVERSE_VERTICAL = 3, + REVERSE_HORIZONTAL = 4, + SENSOR = 5, + SENSOR_VERTICAL = 6, + SENSOR_HORIZONTAL = 7, + END = SENSOR_HORIZONTAL, +}; + enum class DisplayChangeEvent : uint32_t { - UPDATE_ROTATION, + UPDATE_ORIENTATION, DISPLAY_SIZE_CHANGED, UNKNOWN, }; diff --git a/interfaces/innerkits/dm/screen.h b/interfaces/innerkits/dm/screen.h index 8c71c4f9..27ddbd33 100644 --- a/interfaces/innerkits/dm/screen.h +++ b/interfaces/innerkits/dm/screen.h @@ -30,7 +30,7 @@ class ScreenInfo; struct Point { int32_t posX_; int32_t posY_; - Point() {}; + Point() : posX_(0), posY_(0) {}; Point(int32_t posX, int32_t posY) : posX_(posX), posY_(posY) {}; }; @@ -57,22 +57,29 @@ struct ExpandOption { }; class Screen : public RefBase { +friend class ScreenManager; public: - Screen(const ScreenInfo* info); ~Screen(); + Screen(const Screen&) = delete; + Screen(Screen&&) = delete; + Screen& operator=(const Screen&) = delete; + Screen& operator=(Screen&&) = delete; bool IsGroup() const; + const std::string& GetName() const; ScreenId GetId() const; uint32_t GetWidth() const; uint32_t GetHeight() const; uint32_t GetVirtualWidth() const; uint32_t GetVirtualHeight() const; float GetVirtualPixelRatio() const; - bool RequestRotation(Rotation rotation); - Rotation GetRotation(); + Rotation GetRotation() const; + Orientation GetOrientation() const; + bool IsReal() const; ScreenId GetParentId() const; uint32_t GetModeId() const; std::vector> GetSupportedModes() const; bool SetScreenActiveMode(uint32_t modeId); + bool SetOrientation(Orientation orientation) const; // colorspace, gamut DMError GetScreenSupportedColorGamuts(std::vector& colorGamuts) const; @@ -81,8 +88,13 @@ public: DMError GetScreenGamutMap(ScreenGamutMap& gamutMap) const; DMError SetScreenGamutMap(ScreenGamutMap gamutMap); DMError SetScreenColorTransform(); - +protected: + // No more methods or variables can be defined here. + Screen(sptr info); + void UpdateScreenInfo() const; + void UpdateScreenInfo(sptr info) const; private: + // No more methods or variables can be defined here. class Impl; sptr pImpl_; }; diff --git a/interfaces/innerkits/dm/screen_group.h b/interfaces/innerkits/dm/screen_group.h index fd64740d..43e9b61d 100644 --- a/interfaces/innerkits/dm/screen_group.h +++ b/interfaces/innerkits/dm/screen_group.h @@ -29,13 +29,21 @@ enum class ScreenCombination : uint32_t { }; class ScreenGroup : public Screen { +friend class ScreenManager; public: - ScreenGroup(const ScreenGroupInfo* info); ~ScreenGroup(); + ScreenGroup(const ScreenGroup&) = delete; + ScreenGroup(ScreenGroup&&) = delete; + ScreenGroup& operator=(const ScreenGroup&) = delete; + ScreenGroup& operator=(ScreenGroup&&) = delete; ScreenCombination GetCombination() const; - std::vector GetChildrenIds() const; + std::vector GetChildIds() const; + std::vector GetChildPositions() const; private: + // No more methods or variables can be defined here. + ScreenGroup(sptr info); + void UpdateScreenGroupInfo(sptr info); class Impl; sptr pImpl_; }; diff --git a/interfaces/innerkits/dm/screen_manager.h b/interfaces/innerkits/dm/screen_manager.h index d83c36b7..57ac01eb 100644 --- a/interfaces/innerkits/dm/screen_manager.h +++ b/interfaces/innerkits/dm/screen_manager.h @@ -31,17 +31,26 @@ public: public: virtual void OnConnect(ScreenId) = 0; virtual void OnDisconnect(ScreenId) = 0; - virtual void OnChange(const std::vector&, ScreenChangeEvent) = 0; + virtual void OnChange(ScreenId) = 0; + }; + + class IScreenGroupListener : public virtual RefBase { + public: + virtual void OnChange(const std::vector&, ScreenGroupChangeEvent) = 0; }; sptr GetScreenById(ScreenId screenId); - sptr GetScreenGroupById(ScreenId screenId); + sptr GetScreenGroup(ScreenId groupId); std::vector> GetAllScreens(); bool RegisterScreenListener(sptr listener); bool UnregisterScreenListener(sptr listener); + bool RegisterScreenGroupListener(sptr listener); + bool UnregisterScreenGroupListener(sptr listener); ScreenId MakeExpand(const std::vector& options); ScreenId MakeMirror(ScreenId mainScreenId, std::vector mirrorScreenId); + void RemoveVirtualScreenFromGroup(std::vector screens); + void CancelMakeMirrorOrExpand(std::vector screens); ScreenId CreateVirtualScreen(VirtualScreenOption option); DMError DestroyVirtualScreen(ScreenId screenId); DMError SetVirtualScreenSurface(ScreenId screenId, sptr surface); @@ -50,8 +59,6 @@ private: ScreenManager(); ~ScreenManager(); - class ScreenManagerListener; - sptr screenManagerListener_; class Impl; sptr pImpl_; }; diff --git a/interfaces/innerkits/wm/window.h b/interfaces/innerkits/wm/window.h index 7e4b18fc..75f425e6 100644 --- a/interfaces/innerkits/wm/window.h +++ b/interfaces/innerkits/wm/window.h @@ -38,6 +38,10 @@ namespace OHOS::AbilityRuntime { class Context; } +namespace OHOS::Ace { + class UIContent; +} + namespace OHOS { namespace Rosen { class RSSurfaceNode; @@ -57,6 +61,12 @@ public: virtual void OnDrag(int32_t x, int32_t y, DragEvent event) = 0; }; +class IDisplayMoveListener : virtual public RefBase { +public: + virtual void OnDisplayMove(DisplayId from, DisplayId to) = 0; +}; + + class Window : public RefBase { public: static sptr Create(const std::string& windowName, @@ -114,9 +124,12 @@ public: virtual void UnregisterAvoidAreaChangeListener() = 0; virtual void RegisterDragListener(sptr& listener) = 0; virtual void UnregisterDragListener(sptr& listener) = 0; + virtual void RegisterDisplayMoveListener(sptr& listener) = 0; + virtual void UnregisterDisplayMoveListener(sptr& listener) = 0; virtual WMError SetUIContent(const std::string& contentInfo, NativeEngine* engine, NativeValue* storage, bool isdistributed = false) = 0; virtual std::string GetContentInfo() = 0; + virtual Ace::UIContent* GetUIContent() const = 0; virtual bool IsDecorEnable() const = 0; virtual WMError Maximize() = 0; diff --git a/interfaces/innerkits/wm/window_manager.h b/interfaces/innerkits/wm/window_manager.h index 931d6ef0..769de08f 100644 --- a/interfaces/innerkits/wm/window_manager.h +++ b/interfaces/innerkits/wm/window_manager.h @@ -49,6 +49,27 @@ public: virtual void OnSystemBarPropertyChange(DisplayId displayId, const SystemBarRegionTints& tints) = 0; }; +class WindowVisibilityInfo : public Parcelable { +public: + WindowVisibilityInfo() = default; + WindowVisibilityInfo(uint32_t winId, int32_t pid, int32_t uid, bool visibility) + : windowId_(winId), pid_(pid), uid_(uid), isVisible_(visibility) {}; + ~WindowVisibilityInfo() = default; + + virtual bool Marshalling(Parcel& parcel) const override; + static WindowVisibilityInfo* Unmarshalling(Parcel& parcel); + + uint32_t windowId_ { INVALID_WINDOW_ID }; + int32_t pid_ { 0 }; + int32_t uid_ { 0 }; + bool isVisible_ { false }; +}; + +class IVisibilityChangedListener : public RefBase { +public: + virtual void OnWindowVisibilityChanged(const std::vector>& windowVisibilityInfo) = 0; +}; + class WindowInfo : public Parcelable { public: WindowInfo() = default; @@ -78,8 +99,10 @@ public: void UnregisterSystemBarChangedListener(const sptr& listener); void RegisterWindowUpdateListener(const sptr& listener); void UnregisterWindowUpdateListener(const sptr& listener); + void RegisterVisibilityChangedListener(const sptr& listener); + void UnregisterVisibilityChangedListener(const sptr& listener); void MinimizeAllAppWindows(DisplayId displayId); - void SetWindowLayoutMode(WindowLayoutMode mode, DisplayId displayId); + WMError SetWindowLayoutMode(WindowLayoutMode mode, DisplayId displayId); private: WindowManager(); @@ -91,6 +114,8 @@ private: DisplayId displayId, bool focused) const; void UpdateSystemBarRegionTints(DisplayId displayId, const SystemBarRegionTints& tints) const; void UpdateWindowStatus(const sptr& windowInfo, WindowUpdateType type); + void UpdateWindowVisibilityInfo( + const std::vector>& windowVisibilityInfos) const; }; } // namespace Rosen } // namespace OHOS diff --git a/interfaces/innerkits/wm/wm_common.h b/interfaces/innerkits/wm/wm_common.h index 1f38b34e..308561b1 100644 --- a/interfaces/innerkits/wm/wm_common.h +++ b/interfaces/innerkits/wm/wm_common.h @@ -23,19 +23,19 @@ enum class WindowType : uint32_t { APP_WINDOW_BASE = 1, APP_MAIN_WINDOW_BASE = APP_WINDOW_BASE, WINDOW_TYPE_APP_MAIN_WINDOW = APP_MAIN_WINDOW_BASE, - APP_MAIN_WINDOW_END = WINDOW_TYPE_APP_MAIN_WINDOW, // equals last window type + APP_MAIN_WINDOW_END, APP_SUB_WINDOW_BASE = 1000, WINDOW_TYPE_MEDIA = APP_SUB_WINDOW_BASE, WINDOW_TYPE_APP_SUB_WINDOW, - APP_SUB_WINDOW_END = WINDOW_TYPE_APP_SUB_WINDOW, // equals last window type + APP_SUB_WINDOW_END, APP_WINDOW_END = APP_SUB_WINDOW_END, SYSTEM_WINDOW_BASE = 2000, BELOW_APP_SYSTEM_WINDOW_BASE = SYSTEM_WINDOW_BASE, WINDOW_TYPE_WALLPAPER = SYSTEM_WINDOW_BASE, WINDOW_TYPE_DESKTOP, - BELOW_APP_SYSTEM_WINDOW_END = WINDOW_TYPE_DESKTOP, // equals last window type + BELOW_APP_SYSTEM_WINDOW_END, ABOVE_APP_SYSTEM_WINDOW_BASE = 2100, WINDOW_TYPE_APP_LAUNCHING = ABOVE_APP_SYSTEM_WINDOW_BASE, @@ -55,7 +55,9 @@ enum class WindowType : uint32_t { WINDOW_TYPE_POINTER, WINDOW_TYPE_LAUNCHER_RECENT, WINDOW_TYPE_LAUNCHER_DOCK, - ABOVE_APP_SYSTEM_WINDOW_END = WINDOW_TYPE_LAUNCHER_DOCK, // equals last window type + WINDOW_TYPE_BOOT_ANIMATION, + ABOVE_APP_SYSTEM_WINDOW_END, + SYSTEM_WINDOW_END = ABOVE_APP_SYSTEM_WINDOW_END, }; @@ -125,10 +127,17 @@ struct Rect { int32_t posY_; uint32_t width_; uint32_t height_; - bool operator == (const Rect& a) const + + bool operator==(const Rect& a) const { return (posX_ == a.posX_ && posY_ == a.posY_ && width_ == a.width_ && height_ == a.height_); } + + bool IsInsideOf(const Rect& a) const + { + return (posX_ >= a.posX_ && posY_ >= a.posY_ && + posX_ + width_ <= a.posX_ + a.width_ && posY_ + height_ <= a.posY_ + a.height_); + } }; struct PointInfo { @@ -139,21 +148,14 @@ struct PointInfo { namespace { constexpr uint32_t SYSTEM_COLOR_WHITE = 0xE5FFFFFF; constexpr uint32_t SYSTEM_COLOR_BLACK = 0x66000000; - constexpr float DEFAULT_SPLIT_RATIO = 0.5; - constexpr uint32_t DIVIDER_WIDTH = 8; constexpr uint32_t INVALID_WINDOW_ID = 0; - constexpr uint32_t HOTZONE = 40; - constexpr uint32_t MIN_VERTICAL_FLOATING_WIDTH = 240; - constexpr uint32_t MIN_VERTICAL_FLOATING_HEIGHT = 426; - constexpr uint32_t MIN_VERTICAL_SPLIT_HEIGHT = 426; - constexpr uint32_t MIN_HORIZONTAL_SPLIT_WIDTH = 426; } struct SystemBarProperty { bool enable_; uint32_t backgroundColor_; uint32_t contentColor_; - SystemBarProperty() : enable_(true), backgroundColor_(SYSTEM_COLOR_WHITE), contentColor_(SYSTEM_COLOR_BLACK) {} + SystemBarProperty() : enable_(true), backgroundColor_(SYSTEM_COLOR_BLACK), contentColor_(SYSTEM_COLOR_WHITE) {} SystemBarProperty(bool enable, uint32_t background, uint32_t content) : enable_(enable), backgroundColor_(background), contentColor_(content) {} bool operator == (const SystemBarProperty& a) const diff --git a/interfaces/kits/js/declaration/api/@ohos.display.d.ts b/interfaces/kits/js/declaration/api/@ohos.display.d.ts index 17ac54ae..b0c1f75d 100644 --- a/interfaces/kits/js/declaration/api/@ohos.display.d.ts +++ b/interfaces/kits/js/declaration/api/@ohos.display.d.ts @@ -13,20 +13,58 @@ * limitations under the License. */ +import { AsyncCallback, Callback } from './basic'; + /** * interface of display manager + * @syscap SystemCapability.WindowManager.WindowManager.Core * @devices tv, phone, tablet, wearable */ declare namespace display { + + /** + * get the default display + * @devices tv, phone, tablet, wearable + */ + function getDefaultDisplay(callback: AsyncCallback): void; + /** * get the default display * @devices tv, phone, tablet, wearable */ function getDefaultDisplay(): Promise; + /** + * get all displays + * @devices tv, phone, tablet, wearable + * @param callback + */ + function getAllDisplay(callback: AsyncCallback>): void; + + /** + * get all displays + * @devices tv, phone, tablet, wearable + */ + function getAllDisplay() : Promise>; + + /** + * register the callback of display change + * @param type: type of callback + * @devices tv, phone, tablet, wearable, car + */ + function on(type: 'add' | 'remove' | 'change', callback: Callback): void; + + /** + * unregister the callback of display change + * @param type: type of callback + * #devices tv, phone, tablet, wearable, car + */ + function off(type: 'add' | 'remove' | 'change', callback?: Callback): void; + /** /** * the state of display + * @syscap SystemCapability.WindowManager.WindowManager.Core * @devices tv, phone, tablet, wearable */ enum DisplayState { @@ -62,6 +100,7 @@ declare namespace display { /** * Properties of display, it couldn't update automatically + * @syscap SystemCapability.WindowManager.WindowManager.Core * @devices tv, phone, tablet, wearable */ interface Display { diff --git a/interfaces/kits/napi/BUILD.gn b/interfaces/kits/napi/BUILD.gn index acf61db4..acc6f77a 100644 --- a/interfaces/kits/napi/BUILD.gn +++ b/interfaces/kits/napi/BUILD.gn @@ -16,7 +16,7 @@ import("//build/ohos.gni") group("napi_packages") { deps = [ - "display:display", + "display:display_napi", "display_runtime:screen_napi", "screenshot:screenshot", "window_runtime:window_napi", diff --git a/interfaces/kits/napi/display/BUILD.gn b/interfaces/kits/napi/display/BUILD.gn index 26840d26..73e68386 100644 --- a/interfaces/kits/napi/display/BUILD.gn +++ b/interfaces/kits/napi/display/BUILD.gn @@ -13,22 +13,47 @@ import("//build/ohos.gni") -## Build display.so {{{ -ohos_shared_library("display") { - sources = [ "native_display_module.cpp" ] +config("display_config") { + visibility = [ ":*" ] + + include_dirs = [ + "//foundation/windowmanager/interfaces/kits/napi/display", + "//foundation/windowmanager/utils/include", + ] +} + +## Build display_napi.so {{{ +ohos_shared_library("display_napi") { + sources = [ + "js_display.cpp", + "js_display_listener.cpp", + "js_display_manager.cpp", + "js_display_module.cpp", + ] + + configs = [ ":display_config" ] deps = [ "../common:wm_napi_common", + "//foundation/aafwk/standard/frameworks/kits/ability/native:abilitykit_native", + "//foundation/aafwk/standard/frameworks/kits/appkit:app_context", + "//foundation/aafwk/standard/frameworks/kits/appkit:appkit_native", + "//foundation/aafwk/standard/interfaces/innerkits/want:want", + "//foundation/graphic/standard/rosen/modules/render_service_client:librender_service_client", "//foundation/windowmanager/dm:libdm", "//foundation/windowmanager/utils:libwmutil", - "//foundation/windowmanager/wm:libwm", - "//foundation/windowmanager/wmserver:libwms", ] - external_deps = [ "multimedia_image_standard:image_native" ] + external_deps = [ + "ability_runtime:ability_manager", + "ability_runtime:runtime", + "hiviewdfx_hilog_native:libhilog", + "multimedia_image_standard:image_native", + "napi:ace_napi", + ] relative_install_dir = "module" part_name = "window_manager" subsystem_name = "window" } -## Build display.so }}} +## Build display_napi.so }}} diff --git a/interfaces/kits/napi/display/js_display.cpp b/interfaces/kits/napi/display/js_display.cpp new file mode 100644 index 00000000..0b008353 --- /dev/null +++ b/interfaces/kits/napi/display/js_display.cpp @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "js_display.h" + +#include +#include +#include "display.h" +#include "window_manager_hilog.h" + +namespace OHOS { +namespace Rosen { +using namespace AbilityRuntime; +namespace { + constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, 0, "JsDisplay"}; +} + +static std::map> g_JsDisplayMap; +std::recursive_mutex g_mutex; + +JsDisplay::JsDisplay(const sptr& display) : display_(display) +{ +} + +JsDisplay::~JsDisplay() +{ + WLOGFI("JsDisplay::~JsDisplay is called"); +} + +void JsDisplay::Finalizer(NativeEngine* engine, void* data, void* hint) +{ + WLOGFI("JsDisplay::Finalizer is called"); + auto jsDisplay = std::unique_ptr(static_cast(data)); + if (jsDisplay == nullptr) { + WLOGFE("JsDisplay::Finalizer jsDisplay is null"); + return; + } + sptr display = jsDisplay->display_; + if (display == nullptr) { + WLOGFE("JsDisplay::Finalizer display is null"); + return; + } + DisplayId displayId = display->GetId(); + WLOGFI("JsDisplay::Finalizer displayId : %{public}" PRIu64"", displayId); + std::lock_guard lock(g_mutex); + if (g_JsDisplayMap.find(displayId) != g_JsDisplayMap.end()) { + WLOGFI("JsDisplay::Finalizer Display is destroyed: %{public}" PRIu64"", displayId); + g_JsDisplayMap.erase(displayId); + } +} + +NativeValue* CreateJsDisplayObject(NativeEngine& engine, sptr& display) +{ + WLOGFI("JsDisplay::CreateJsDisplay is called"); + NativeValue* objValue = engine.CreateObject(); + NativeObject* object = ConvertNativeValueTo(objValue); + if (object == nullptr) { + WLOGFE("Failed to convert prop to jsObject"); + return engine.CreateUndefined(); + } + std::unique_ptr jsDisplay = std::make_unique(display); + object->SetNativePointer(jsDisplay.release(), JsDisplay::Finalizer, nullptr); + + object->SetProperty("id", CreateJsValue(engine, static_cast(display->GetId()))); + object->SetProperty("width", CreateJsValue(engine, display->GetWidth())); + object->SetProperty("height", CreateJsValue(engine, display->GetHeight())); + object->SetProperty("refreshRate", CreateJsValue(engine, display->GetFreshRate())); + object->SetProperty("name", engine.CreateUndefined()); + object->SetProperty("alive", engine.CreateUndefined()); + object->SetProperty("state", engine.CreateUndefined()); + object->SetProperty("rotation", engine.CreateUndefined()); + object->SetProperty("densityDPI", engine.CreateUndefined()); + object->SetProperty("densityPixels", engine.CreateUndefined()); + object->SetProperty("scaledDensity", engine.CreateUndefined()); + object->SetProperty("xDPI", engine.CreateUndefined()); + object->SetProperty("yDPI", engine.CreateUndefined()); + + std::shared_ptr jsDisplayRef; + jsDisplayRef.reset(engine.CreateReference(objValue, 1)); + DisplayId displayId = display->GetId(); + std::lock_guard lock(g_mutex); + g_JsDisplayMap[displayId] = jsDisplayRef; + return objValue; +} +} // namespace Rosen +} // namespace OHOS diff --git a/interfaces/kits/napi/display/js_display.h b/interfaces/kits/napi/display/js_display.h new file mode 100644 index 00000000..837fb3b9 --- /dev/null +++ b/interfaces/kits/napi/display/js_display.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_JS_DISPLAY_H +#define OHOS_JS_DISPLAY_H +#include "js_runtime_utils.h" +#include "native_engine/native_engine.h" +#include "native_engine/native_value.h" +#include "display.h" + +namespace OHOS { +namespace Rosen { +NativeValue* CreateJsDisplayObject(NativeEngine& engine, sptr& Display); +class JsDisplay final { +public: + explicit JsDisplay(const sptr& Display); + ~JsDisplay(); + static void Finalizer(NativeEngine* engine, void* data, void* hint); + +private: + sptr display_ = nullptr; +}; +} // namespace Rosen +} // namespace OHOS +#endif \ No newline at end of file diff --git a/interfaces/kits/napi/display/js_display_listener.cpp b/interfaces/kits/napi/display/js_display_listener.cpp new file mode 100644 index 00000000..706dde0c --- /dev/null +++ b/interfaces/kits/napi/display/js_display_listener.cpp @@ -0,0 +1,143 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +#include "js_display_listener.h" +#include "js_runtime_utils.h" +#include "window_manager_hilog.h" +namespace OHOS { +namespace Rosen { +using namespace AbilityRuntime; +namespace { + constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, 0, "JsDisplayListener"}; +} + +void JsDisplayListener::AddCallback(NativeValue* jsListenerObject) +{ + WLOGFI("JsDisplayListener::AddCallback is called"); + std::unique_ptr callbackRef; + if (engine_ == nullptr) { + WLOGFE("engine_ nullptr"); + return; + } + callbackRef.reset(engine_->CreateReference(jsListenerObject, 1)); + std::lock_guard lock(mtx_); + jsCallBack_.push_back(std::move(callbackRef)); + WLOGFI("JsDisplayListener::AddCallback success jsCallBack_ size: %{public}u!", + static_cast(jsCallBack_.size())); +} + +void JsDisplayListener::RemoveAllCallback() +{ + std::lock_guard lock(mtx_); + jsCallBack_.clear(); +} + +void JsDisplayListener::RemoveCallback(NativeValue* jsListenerObject) +{ + std::lock_guard lock(mtx_); + for (auto iter = jsCallBack_.begin(); iter != jsCallBack_.end();) { + if (jsListenerObject->StrictEquals((*iter)->Get())) { + jsCallBack_.erase(iter); + } else { + iter++; + } + } + WLOGFI("JsDisplayListener::RemoveCallback success jsCallBack_ size: %{public}u!", + static_cast(jsCallBack_.size())); +} + +void JsDisplayListener::CallJsMethod(const char* methodName, NativeValue* const* argv, size_t argc) +{ + WLOGFI("CallJsMethod methodName = %{public}s", methodName); + if (engine_ == nullptr) { + WLOGFE("engine_ nullptr"); + return; + } + for (auto& callback : jsCallBack_) { + NativeValue* method = callback->Get(); + if (method == nullptr) { + WLOGFE("Failed to get method callback from object"); + continue; + } + engine_->CallFunction(engine_->CreateUndefined(), method, argv, argc); + } +} + +void JsDisplayListener::OnCreate(DisplayId id) +{ + std::lock_guard lock(mtx_); + WLOGFI("JsDisplayListener::OnCreate is called, displayId: %{public}d", static_cast(id)); + if (jsCallBack_.empty()) { + WLOGFE("JsDisplayListener::OnCreate not register!"); + return; + } + + std::unique_ptr complete = std::make_unique ( + [=] (NativeEngine &engine, AsyncTask &task, int32_t status) { + NativeValue* argv[] = {CreateJsValue(*engine_, static_cast(id))}; + CallJsMethod("add", argv, ArraySize(argv)); + } + ); + + NativeReference* callback = nullptr; + std::unique_ptr execute = nullptr; + AsyncTask::Schedule(*engine_, std::make_unique( + callback, std::move(execute), std::move(complete))); +} + +void JsDisplayListener::OnDestroy(DisplayId id) +{ + std::lock_guard lock(mtx_); + WLOGFI("JsDisplayListener::OnDestroy is called, displayId: %{public}d", static_cast(id)); + if (jsCallBack_.empty()) { + WLOGFE("JsDisplayListener::OnDestroy not register!"); + return; + } + + std::unique_ptr complete = std::make_unique ( + [=] (NativeEngine &engine, AsyncTask &task, int32_t status) { + NativeValue* argv[] = {CreateJsValue(*engine_, static_cast(id))}; + CallJsMethod("remove", argv, ArraySize(argv)); + } + ); + + NativeReference* callback = nullptr; + std::unique_ptr execute = nullptr; + AsyncTask::Schedule(*engine_, std::make_unique( + callback, std::move(execute), std::move(complete))); +} + +void JsDisplayListener::OnChange(DisplayId id) +{ + std::lock_guard lock(mtx_); + WLOGFI("JsDisplayListener::OnChange is called, displayId: %{public}d", static_cast(id)); + if (jsCallBack_.empty()) { + WLOGFE("JsDisplayListener::OnChange not register!"); + return; + } + + std::unique_ptr complete = std::make_unique ( + [=] (NativeEngine &engine, AsyncTask &task, int32_t status) { + NativeValue* argv[] = {CreateJsValue(*engine_, static_cast(id))}; + CallJsMethod("change", argv, ArraySize(argv)); + } + ); + + NativeReference* callback = nullptr; + std::unique_ptr execute = nullptr; + AsyncTask::Schedule(*engine_, std::make_unique( + callback, std::move(execute), std::move(complete))); +} +} // namespace Rosen +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/kits/napi/display/js_display_listener.h b/interfaces/kits/napi/display/js_display_listener.h new file mode 100644 index 00000000..000e2401 --- /dev/null +++ b/interfaces/kits/napi/display/js_display_listener.h @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_JS_DISPLAY_LISTENER_H +#define OHOS_JS_DISPLAY_LISTENER_H + +#include +#include "native_engine/native_engine.h" +#include "native_engine/native_value.h" +#include "refbase.h" +#include "display_manager.h" + +namespace OHOS { +namespace Rosen { +class JsDisplayListener : public DisplayManager::IDisplayListener { +public: + explicit JsDisplayListener(NativeEngine* engine) : engine_(engine) {} + ~JsDisplayListener() override = default; + void AddCallback(NativeValue* jsListenerObject); + void RemoveAllCallback(); + void RemoveCallback(NativeValue* jsListenerObject); + void OnCreate(DisplayId id) override; + void OnDestroy(DisplayId id) override; + void OnChange(DisplayId id) override; + +private: + void CallJsMethod(const char* methodName, NativeValue* const* argv = nullptr, size_t argc = 0); + NativeEngine* engine_ = nullptr; + std::mutex mtx_; + std::vector> jsCallBack_; + NativeValue* CreateDisplayIdArray(NativeEngine& engine, const std::vector& data); +}; +} // namespace Rosen +} // namespace OHOS +#endif /* OHOS_JS_DISPLAY_LISTENER_H */ \ No newline at end of file diff --git a/interfaces/kits/napi/display/js_display_manager.cpp b/interfaces/kits/napi/display/js_display_manager.cpp new file mode 100644 index 00000000..a8afaad0 --- /dev/null +++ b/interfaces/kits/napi/display/js_display_manager.cpp @@ -0,0 +1,328 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include + +#include "js_runtime_utils.h" +#include "native_engine/native_reference.h" +#include "display_manager.h" +#include "window_manager_hilog.h" +#include "singleton_container.h" +#include "js_display_listener.h" +#include "js_display.h" +#include "js_display_manager.h" + +namespace OHOS { +namespace Rosen { +using namespace AbilityRuntime; +constexpr size_t ARGC_ONE = 1; +constexpr size_t ARGC_TWO = 2; +constexpr int32_t INDEX_ONE = 1; +namespace { + constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, 0, "JsDisplayManager"}; +} + +class JsDisplayManager { +public: +explicit JsDisplayManager(NativeEngine* engine) { +} + +~JsDisplayManager() = default; + +static void Finalizer(NativeEngine* engine, void* data, void* hint) +{ + WLOGFI("JsDisplayManager::Finalizer is called"); + std::unique_ptr(static_cast(data)); +} + +static NativeValue* GetDefaultDisplay(NativeEngine* engine, NativeCallbackInfo* info) +{ + JsDisplayManager* me = CheckParamsAndGetThis(engine, info); + return (me != nullptr) ? me->OnGetDefaultDisplay(*engine, *info) : nullptr; +} + +static NativeValue* GetAllDisplay(NativeEngine* engine, NativeCallbackInfo* info) +{ + JsDisplayManager* me = CheckParamsAndGetThis(engine, info); + return (me != nullptr) ? me->OnGetAllDisplay(*engine, *info) : nullptr; +} + +static NativeValue* RegisterDisplayManagerCallback(NativeEngine* engine, NativeCallbackInfo* info) +{ + JsDisplayManager* me = CheckParamsAndGetThis(engine, info); + return (me != nullptr) ? me->OnRegisterDisplayManagerCallback(*engine, *info) : nullptr; +} + +static NativeValue* UnregisterDisplayManagerCallback(NativeEngine* engine, NativeCallbackInfo* info) +{ + JsDisplayManager* me = CheckParamsAndGetThis(engine, info); + return (me != nullptr) ? me->OnUnregisterDisplayManagerCallback(*engine, *info) : nullptr; +} + +private: +std::map, sptr>> jsCbMap_; +std::mutex mtx_; + +NativeValue* OnGetDefaultDisplay(NativeEngine& engine, NativeCallbackInfo& info) +{ + WLOGFI("JsDisplayManager::OnGetDefaultDisplay is called"); + DMError errCode = DMError::DM_OK; + if (info.argc != 0 && info.argc != ARGC_ONE) { + WLOGFE("JsDisplayManager::OnGetDefaultDisplay params not match"); + errCode = DMError::DM_ERROR_INVALID_PARAM; + } + + AsyncTask::CompleteCallback complete = + [=](NativeEngine& engine, AsyncTask& task, int32_t status) { + if (errCode != DMError::DM_OK) { + task.Reject(engine, CreateJsError(engine, + static_cast(errCode), "JsDisplayManager::OnGetDefaultDisplay failed.")); + } + sptr display = SingletonContainer::Get().GetDefaultDisplay(); + if (display != nullptr) { + task.Resolve(engine, CreateJsDisplayObject(engine, display)); + WLOGFI("JsDisplayManager::OnGetDefaultDisplay success"); + } else { + task.Reject(engine, CreateJsError(engine, + static_cast(DMError::DM_ERROR_NULLPTR), "JsDisplayManager::OnGetDefaultDisplay failed.")); + } + }; + NativeValue* lastParam = nullptr; + if (info.argc == ARGC_ONE && info.argv[0]->TypeOf() == NATIVE_FUNCTION) { + lastParam = info.argv[0]; + } + NativeValue* result = nullptr; + AsyncTask::Schedule( + engine, CreateAsyncTaskWithLastParam(engine, lastParam, nullptr, std::move(complete), &result)); + return result; +} + +NativeValue* OnGetAllDisplay(NativeEngine& engine, NativeCallbackInfo& info) +{ + WLOGFI("JsDisplayManager::OnGetAllDisplay is called"); + DMError errCode = DMError::DM_OK; + if (info.argc != 0 && info.argc != ARGC_ONE) { + WLOGFE("JsDisplayManager::OnGetAllDisplay params not match"); + errCode = DMError::DM_ERROR_INVALID_PARAM; + } + + AsyncTask::CompleteCallback complete = + [=](NativeEngine& engine, AsyncTask& task, int32_t status) { + if (errCode != DMError::DM_OK) { + task.Reject(engine, CreateJsError(engine, + static_cast(errCode), "JsDisplayManager::OnGetAllDisplay failed.")); + } + std::vector> displays = SingletonContainer::Get().GetAllDisplays(); + if (!displays.empty()) { + task.Resolve(engine, CreateJsDisplayArrayObject(engine, displays)); + WLOGFI("JsDisplayManager::GetAllDisplays success"); + } else { + task.Reject(engine, CreateJsError(engine, + static_cast(DMError::DM_ERROR_NULLPTR), "JsDisplayManager::OnGetAllDisplay failed.")); + } + }; + + NativeValue* lastParam = nullptr; + if (info.argc == ARGC_ONE && info.argv[0]->TypeOf() == NATIVE_FUNCTION) { + lastParam = info.argv[0]; + } + NativeValue* result = nullptr; + AsyncTask::Schedule( + engine, CreateAsyncTaskWithLastParam(engine, lastParam, nullptr, std::move(complete), &result)); + return result; +} + +void RegisterDisplayListenerWithType(NativeEngine& engine, const std::string& type, NativeValue* value) +{ + if (IfCallbackRegistered(type, value)) { + WLOGFE("JsDisplayManager::RegisterDisplayListenerWithType callback already registered!"); + return; + } + std::unique_ptr callbackRef; + callbackRef.reset(engine.CreateReference(value, 1)); + sptr displayListener = new(std::nothrow) JsDisplayListener(&engine); + if (displayListener == nullptr) { + WLOGFE("displayListener is nullptr"); + return; + } + if (type == "add" || type == "remove" || type == "change") { + SingletonContainer::Get().RegisterDisplayListener(displayListener); + WLOGFI("JsDisplayManager::RegisterDisplayListenerWithType success"); + } else { + WLOGFE("JsDisplayManager::RegisterDisplayListenerWithType failed method: %{public}s not support!", + type.c_str()); + return; + } + displayListener->AddCallback(value); + jsCbMap_[type][std::move(callbackRef)] = displayListener; +} + +bool IfCallbackRegistered(const std::string& type, NativeValue* jsListenerObject) +{ + if (jsCbMap_.empty() || jsCbMap_.find(type) == jsCbMap_.end()) { + WLOGFI("JsDisplayManager::IfCallbackRegistered methodName %{public}s not registered!", type.c_str()); + return false; + } + + for (auto& iter : jsCbMap_[type]) { + if (jsListenerObject->StrictEquals(iter.first->Get())) { + WLOGFE("JsDisplayManager::IfCallbackRegistered callback already registered!"); + return true; + } + } + return false; +} + +void UnregisterAllDisplayListenerWithType(const std::string& type) +{ + if (jsCbMap_.empty() || jsCbMap_.find(type) == jsCbMap_.end()) { + WLOGFI("JsDisplayManager::UnregisterAllDisplayListenerWithType methodName %{public}s not registered!", + type.c_str()); + return; + } + for (auto it = jsCbMap_[type].begin(); it != jsCbMap_[type].end();) { + it->second->RemoveAllCallback(); + if (type == "add" || type == "remove" || type == "change") { + sptr thisListener(it->second); + SingletonContainer::Get().UnregisterDisplayListener(thisListener); + WLOGFI("JsDisplayManager::UnregisterAllDisplayListenerWithType success"); + } + jsCbMap_[type].erase(it++); + } + jsCbMap_.erase(type); +} + +void UnRegisterDisplayListenerWithType(const std::string& type, NativeValue* value) +{ + if (jsCbMap_.empty() || jsCbMap_.find(type) == jsCbMap_.end()) { + WLOGFI("JsDisplayManager::UnRegisterDisplayListenerWithType methodName %{public}s not registered!", + type.c_str()); + return; + } + for (auto it = jsCbMap_[type].begin(); it != jsCbMap_[type].end();) { + if (value->StrictEquals(it->first->Get())) { + it->second->RemoveCallback(value); + if (type == "add" || type == "remove" || type == "change") { + sptr thisListener(it->second); + SingletonContainer::Get().UnregisterDisplayListener(thisListener); + WLOGFI("JsDisplayManager::UnRegisterDisplayListenerWithType success"); + } + jsCbMap_[type].erase(it++); + break; + } else { + it++; + } + } + if (jsCbMap_[type].empty()) { + jsCbMap_.erase(type); + } +} + +NativeValue* OnRegisterDisplayManagerCallback(NativeEngine& engine, NativeCallbackInfo& info) +{ + WLOGFI("JsDisplayManager::OnRegisterDisplayManagerCallback is called"); + if (info.argc != ARGC_TWO) { + WLOGFE("JsDisplayManager Params not match: %{public}zu", info.argc); + return engine.CreateUndefined(); + } + std::string cbType; + if (!ConvertFromJsValue(engine, info.argv[0], cbType)) { + WLOGFE("Failed to convert parameter to callbackType"); + return engine.CreateUndefined(); + } + NativeValue* value = info.argv[INDEX_ONE]; + if (value == nullptr) { + WLOGFI("JsDisplayManager::OnRegisterDisplayManagerCallback info->argv[1] is nullptr"); + return engine.CreateUndefined(); + } + if (!value->IsCallable()) { + WLOGFI("JsDisplayManager::OnRegisterDisplayManagerCallback info->argv[1] is not callable"); + return engine.CreateUndefined(); + } + std::lock_guard lock(mtx_); + RegisterDisplayListenerWithType(engine, cbType, value); + return engine.CreateUndefined(); +} + +NativeValue* OnUnregisterDisplayManagerCallback(NativeEngine& engine, NativeCallbackInfo& info) +{ + WLOGFI("JsDisplayManager::OnUnregisterDisplayCallback is called"); + if (info.argc == 0) { + WLOGFE("JsDisplayManager Params not match %{public}zu", info.argc); + return engine.CreateUndefined(); + } + std::string cbType; + if (!ConvertFromJsValue(engine, info.argv[0], cbType)) { + WLOGFE("Failed to convert parameter to callbackType"); + return engine.CreateUndefined(); + } + std::lock_guard lock(mtx_); + if (info.argc == ARGC_ONE) { + UnregisterAllDisplayListenerWithType(cbType); + } else { + NativeValue* value = info.argv[INDEX_ONE]; + if (value == nullptr) { + WLOGFI("JsDisplayManager::OnUnregisterDisplayManagerCallback info->argv[1] is nullptr"); + return engine.CreateUndefined(); + } + if (!value->IsCallable()) { + WLOGFI("JsDisplayManager::OnUnregisterDisplayManagerCallback info->argv[1] is not callable"); + return engine.CreateUndefined(); + } + UnRegisterDisplayListenerWithType(cbType, value); + } + return engine.CreateUndefined(); +} + +NativeValue* CreateJsDisplayArrayObject(NativeEngine& engine, std::vector>& displays) +{ + WLOGFI("JsDisplayManager::CreateJsDisplayArrayObject is called"); + NativeValue* arrayValue = engine.CreateArray(displays.size()); + NativeArray* array = ConvertNativeValueTo(arrayValue); + int32_t i = 0; + for (auto& display : displays) { + array->SetElement(i++, CreateJsDisplayObject(engine, display)); + } + return arrayValue; +} +}; + +NativeValue* JsDisplayManagerInit(NativeEngine* engine, NativeValue* exportObj) +{ + WLOGFI("JsDisplayManagerInit is called"); + + if (engine == nullptr || exportObj == nullptr) { + WLOGFE("JsDisplayManagerInit engine or exportObj is nullptr"); + return nullptr; + } + + NativeObject* object = ConvertNativeValueTo(exportObj); + if (object == nullptr) { + WLOGFE("JsDisplayManagerInit object is nullptr"); + return nullptr; + } + + std::unique_ptr jsDisplayManager = std::make_unique(engine); + object->SetNativePointer(jsDisplayManager.release(), JsDisplayManager::Finalizer, nullptr); + + BindNativeFunction(*engine, *object, "getDefaultDisplay", JsDisplayManager::GetDefaultDisplay); + BindNativeFunction(*engine, *object, "getAllDisplay", JsDisplayManager::GetAllDisplay); + BindNativeFunction(*engine, *object, "on", JsDisplayManager::RegisterDisplayManagerCallback); + BindNativeFunction(*engine, *object, "off", JsDisplayManager::UnregisterDisplayManagerCallback); + return engine->CreateUndefined(); +} +} // namespace Rosen +} // namespace OHOS \ No newline at end of file diff --git a/interfaces/kits/napi/display/native_display_module.h b/interfaces/kits/napi/display/js_display_manager.h similarity index 59% rename from interfaces/kits/napi/display/native_display_module.h rename to interfaces/kits/napi/display/js_display_manager.h index a24c7026..30f19812 100644 --- a/interfaces/kits/napi/display/native_display_module.h +++ b/interfaces/kits/napi/display/js_display_manager.h @@ -1,19 +1,28 @@ -/* - * Copyright (c) 2021 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef INTERFACES_KITS_NAPI_GRAPHIC_DISPLAY_NATIVE_MODULE_H -#define INTERFACES_KITS_NAPI_GRAPHIC_DISPLAY_NATIVE_MODULE_H - -#endif // INTERFACES_KITS_NAPI_GRAPHIC_DISPLAY_NATIVE_MODULE_H +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef OHOS_JS_DISPLAY_MANAGER_H +#define OHOS_JS_DISPLAY_MANAGER_H + +#include "native_engine/native_engine.h" +#include "native_engine/native_value.h" + +namespace OHOS { +namespace Rosen { +NativeValue* JsDisplayManagerInit(NativeEngine* engine, NativeValue* exportObj); +} // namespace Rosen +} // namespace OHOS + +#endif diff --git a/interfaces/kits/napi/display/js_display_module.cpp b/interfaces/kits/napi/display/js_display_module.cpp new file mode 100644 index 00000000..83e7418a --- /dev/null +++ b/interfaces/kits/napi/display/js_display_module.cpp @@ -0,0 +1,29 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "js_display_manager.h" +#include "native_engine/native_engine.h" + +extern "C" __attribute__((constructor)) void NAPI_application_displaymanager_AutoRegister() +{ + auto moduleManager = NativeModuleManager::GetInstance(); + NativeModule newModuleInfo = { + .name = "display", + .fileName = "module/libdisplay_napi.so/display.js", + .registerCallback = OHOS::Rosen::JsDisplayManagerInit, + }; + + moduleManager->Register(&newModuleInfo); +} diff --git a/interfaces/kits/napi/display/native_display_module.cpp b/interfaces/kits/napi/display/native_display_module.cpp deleted file mode 100644 index 3f6db473..00000000 --- a/interfaces/kits/napi/display/native_display_module.cpp +++ /dev/null @@ -1,113 +0,0 @@ -/* - * Copyright (c) 2021 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "display_manager.h" - -#include - -#include "native_display_module.h" -#include "wm_common.h" -#include "wm_napi_common.h" - -namespace OHOS { -namespace Rosen { -namespace getDefaultDisplay { -struct Param { - WMError wret; - sptr display; -}; - -void Async(napi_env env, std::unique_ptr ¶m) -{ - param->display = DisplayManager::GetInstance().GetDefaultDisplay(); - if (param->display == nullptr) { - GNAPI_LOG("Get display failed!"); - param->wret = WMError::WM_ERROR_NULLPTR; - return; - } - GNAPI_LOG("GetDefaultDisplay: id %{public}" PRIu64", w %{public}d, h %{public}d", - param->display->GetId(), param->display->GetWidth(), param->display->GetHeight()); - param->wret = WMError::WM_OK; -} - -napi_value Resolve(napi_env env, std::unique_ptr ¶m) -{ - napi_value result; - if (param->wret != WMError::WM_OK) { - NAPI_CALL(env, napi_get_undefined(env, &result)); - return result; - } - - DisplayId id = param->display->GetId(); - int32_t width = param->display->GetWidth(); - int32_t height = param->display->GetHeight(); - GNAPI_LOG("id : %{public}" PRIu64"", id); - GNAPI_LOG("width : %{public}d", width); - GNAPI_LOG("height : %{public}d", height); - - NAPI_CALL(env, napi_create_object(env, &result)); - NAPI_CALL(env, SetMemberInt32(env, result, "id", id)); - NAPI_CALL(env, SetMemberUndefined(env, result, "name")); - NAPI_CALL(env, SetMemberUndefined(env, result, "alive")); - NAPI_CALL(env, SetMemberUndefined(env, result, "state")); - NAPI_CALL(env, SetMemberUndefined(env, result, "refreshRate")); - NAPI_CALL(env, SetMemberUndefined(env, result, "rotation")); - NAPI_CALL(env, SetMemberUint32(env, result, "width", width)); - NAPI_CALL(env, SetMemberUint32(env, result, "height", height)); - NAPI_CALL(env, SetMemberUndefined(env, result, "densityDPI")); - NAPI_CALL(env, SetMemberUndefined(env, result, "densityPixels")); - NAPI_CALL(env, SetMemberUndefined(env, result, "scaledDensity")); - NAPI_CALL(env, SetMemberUndefined(env, result, "xDPI")); - NAPI_CALL(env, SetMemberUndefined(env, result, "yDPI")); - - return result; -} - -napi_value MainFunc(napi_env env, napi_callback_info info) -{ - GNAPI_LOG("Display Interface: getDefaultDisplay()"); - GNAPI_LOG("%{public}s called", __PRETTY_FUNCTION__); - auto param = std::make_unique(); - return CreatePromise(env, __PRETTY_FUNCTION__, Async, Resolve, param); -} -} // namespace getDefaultDisplay - -napi_value DisplayModuleInit(napi_env env, napi_value exports) -{ - GNAPI_LOG("%{public}s called", __PRETTY_FUNCTION__); - - napi_property_descriptor properties[] = { - DECLARE_NAPI_FUNCTION("getDefaultDisplay", getDefaultDisplay::MainFunc), - }; - - NAPI_CALL(env, napi_define_properties(env, - exports, sizeof(properties) / sizeof(properties[0]), properties)); - return exports; -} -} // namespace Rosen -} // namespace OHOS - -extern "C" __attribute__((constructor)) void RegisterModule(void) -{ - napi_module displayModule = { - .nm_version = 1, // NAPI v1 - .nm_flags = 0, // normal - .nm_filename = nullptr, - .nm_register_func = OHOS::Rosen::DisplayModuleInit, - .nm_modname = "display", - .nm_priv = nullptr, - }; - napi_module_register(&displayModule); -} diff --git a/interfaces/kits/napi/display_runtime/api/@ohos.screen.d.ts b/interfaces/kits/napi/display_runtime/api/@ohos.screen.d.ts index 0f6c6060..b7558ed2 100644 --- a/interfaces/kits/napi/display_runtime/api/@ohos.screen.d.ts +++ b/interfaces/kits/napi/display_runtime/api/@ohos.screen.d.ts @@ -30,8 +30,8 @@ declare namespace screen { function getAllScreen(): Promise>; // Screen plug-in event; Screen resolution ratio and other parameters, combination relationship changes - function on(eventType: 'screenConnectEvent' | 'screenChangeEvent', callback: Callback): void; - function off(eventType: 'screenConnectEvent' | 'screenChangeEvent', callback?: Callback): void; + function on(eventType: 'connect' | 'disconnect' | 'change', callback: Callback): void; + function off(eventType: 'connect' | 'disconnect' | 'change', callback?: Callback): void; /** * make screens as expand-screen @@ -89,14 +89,14 @@ declare namespace screen { readonly activeModeIndex: number; + readonly orientation: Orientation; + /** - * get the rotation of the screen + * set the orientation of the screen * @devices tv, phone, tablet, wearable * @since 8 */ - readonly rotation: Rotation; - - requestRotation(rotation: Rotation): Promise; + setOrientation(orientation: Orientation): Promise; setScreenActiveMode(modeIndex: number): Promise; } @@ -128,52 +128,15 @@ declare namespace screen { mirrorScreenId: Array; } - /** - * screen connect or disconnect event - * @devices tv, phone, tablet, wearable - * @since 8 - */ - type ScreenEvent = { - screenId: number; - type: ScreenConnectEventType; - } | { - screenId: Array; - type: ScreenChangeEventType; - } - - enum ScreenConnectEventType { - DISCONNECT = 0, - CONNECT = 1, - } - - enum ScreenChangeEventType { - ADD_TO_GROUP = 0, - REMOVE_FROM_GROUP = 1, - CHANGE_GROUP = 2, - } - - /** - * rotation degree of screen - * @devices tv, phone, tablet, wearable - * @since 8 - */ - enum Rotation { - /** - * 0 degree - */ - ROTATION_0 = 0, - /** - * 90 degree - */ - ROTATION_90 = 1, - /** - * 180 degree - */ - ROTATION_180 = 2, - /** - * 270 degree - */ - ROTATION_270 = 3, + enum Orientation { + UNSPECIFIED = 0, + VERTICAL = 1, + HORIZONTAL = 2, + REVERSE_VERTICAL = 3, + REVERSE_HORIZONTAL = 4, + SENSOR = 5, + SENSOR_VERTICAL = 6, + SENSOR_HORIZONTAL = 7, } interface ScreenModeInfo { diff --git a/interfaces/kits/napi/display_runtime/napi/js_screen.cpp b/interfaces/kits/napi/display_runtime/napi/js_screen.cpp index e977b597..56dc4811 100644 --- a/interfaces/kits/napi/display_runtime/napi/js_screen.cpp +++ b/interfaces/kits/napi/display_runtime/napi/js_screen.cpp @@ -43,6 +43,10 @@ void JsScreen::Finalizer(NativeEngine* engine, void* data, void* hint) { WLOGFI("JsScreen::Finalizer is called"); auto jsScreen = std::unique_ptr(static_cast(data)); + if (jsScreen == nullptr) { + WLOGFE("jsScreen::Finalizer jsScreen is null"); + return; + } sptr screen = jsScreen->screen_; if (screen == nullptr) { WLOGFE("JsScreen::Finalizer screen is null"); @@ -57,52 +61,49 @@ void JsScreen::Finalizer(NativeEngine* engine, void* data, void* hint) } } -NativeValue* JsScreen::RequestRotation(NativeEngine* engine, NativeCallbackInfo* info) +NativeValue* JsScreen::SetOrientation(NativeEngine* engine, NativeCallbackInfo* info) { JsScreen* me = CheckParamsAndGetThis(engine, info); - return (me != nullptr) ? me->OnRequestRotation(*engine, *info) : nullptr; + return (me != nullptr) ? me->OnSetOrientation(*engine, *info) : nullptr; } -NativeValue* JsScreen::OnRequestRotation(NativeEngine& engine, NativeCallbackInfo& info) +NativeValue* JsScreen::OnSetOrientation(NativeEngine& engine, NativeCallbackInfo& info) { - WLOGFI("JsScreen::OnRequestRotation is called"); + WLOGFI("JsScreen::OnSetOrientation is called"); bool paramValidFlag = true; - Rotation rotation = Rotation::ROTATION_0; + Orientation orientation = Orientation::UNSPECIFIED; if (info.argc != ARGC_ONE) { - WLOGFE("OnRequestRotation Params not match, info argc: %{public}zu", info.argc); + WLOGFE("OnSetOrientation Params not match, info argc: %{public}zu", info.argc); paramValidFlag = false; } else { - if (!ConvertFromJsValue(engine, info.argv[0], rotation)) { + if (!ConvertFromJsValue(engine, info.argv[0], orientation)) { paramValidFlag = false; - WLOGFE("Failed to convert parameter to rotation"); + WLOGFE("Failed to convert parameter to orientation"); } } AsyncTask::CompleteCallback complete = [=](NativeEngine& engine, AsyncTask& task, int32_t status) { if (!paramValidFlag) { - WLOGE("JsScreen::OnRequestRotation paramValidFlag error"); + WLOGE("JsScreen::OnSetOrientation paramValidFlag error"); task.Reject(engine, CreateJsError(engine, static_cast(DMError::DM_ERROR_INVALID_PARAM), - "JsScreen::OnRequestRotation failed.")); + "JsScreen::OnSetOrientation failed.")); return; } - if (rotation != Rotation::ROTATION_0 && - rotation != Rotation::ROTATION_90 && - rotation != Rotation::ROTATION_180 && - rotation != Rotation::ROTATION_270) { - WLOGE("Rotation param error! rotation value must from enum Rotation"); + if (orientation < Orientation::BEGIN || orientation > Orientation::END) { + WLOGE("Orientation param error! orientation value must from enum Orientation"); task.Reject(engine, CreateJsError(engine, static_cast(DMError::DM_ERROR_INVALID_PARAM), - "JsScreen::OnRequestRotation failed.")); + "JsScreen::OnSetOrientation failed.")); return; } - bool res = screen_->RequestRotation(rotation); + bool res = screen_->SetOrientation(orientation); if (res) { task.Resolve(engine, CreateJsValue(engine, true)); - WLOGFI("JsScreen::OnRequestRotation success"); + WLOGFI("JsScreen::OnSetOrientation success"); } else { - task.Resolve(engine, CreateJsError(engine, false, "JsScreen::OnRequestRotation failed.")); - WLOGFE("JsScreen::OnRequestRotation failed"); + task.Resolve(engine, CreateJsError(engine, false, "JsScreen::OnSetOrientation failed.")); + WLOGFE("JsScreen::OnSetOrientation failed"); } }; NativeValue* lastParam = nullptr; @@ -174,7 +175,7 @@ NativeValue* CreateJsScreenObject(NativeEngine& engine, sptr& screen) object->SetProperty("id", CreateJsValue(engine, static_cast(screen->GetId()))); object->SetProperty("parent", CreateJsValue(engine, static_cast(screen->GetParentId()))); - object->SetProperty("rotation", CreateJsValue(engine, screen->GetRotation())); + object->SetProperty("orientation", CreateJsValue(engine, screen->GetOrientation())); object->SetProperty("activeModeIndex", CreateJsValue(engine, screen->GetModeId())); object->SetProperty("supportedModeInfo", CreateJsScreenModeArrayObject(engine, screen->GetSupportedModes())); @@ -184,7 +185,7 @@ NativeValue* CreateJsScreenObject(NativeEngine& engine, sptr& screen) std::lock_guard lock(g_mutex); g_JsScreenMap[screenId] = JsScreenRef; BindNativeFunction(engine, *object, "setScreenActiveMode", JsScreen::SetScreenActiveMode); - BindNativeFunction(engine, *object, "requestRotation", JsScreen::RequestRotation); + BindNativeFunction(engine, *object, "setOrientation", JsScreen::SetOrientation); return objValue; } diff --git a/interfaces/kits/napi/display_runtime/napi/js_screen.h b/interfaces/kits/napi/display_runtime/napi/js_screen.h index eb05edbe..ee5bd4a6 100644 --- a/interfaces/kits/napi/display_runtime/napi/js_screen.h +++ b/interfaces/kits/napi/display_runtime/napi/js_screen.h @@ -31,11 +31,11 @@ public: ~JsScreen(); static void Finalizer(NativeEngine* engine, void* data, void* hint); static NativeValue* SetScreenActiveMode(NativeEngine* engine, NativeCallbackInfo* info); - static NativeValue* RequestRotation(NativeEngine* engine, NativeCallbackInfo* info); + static NativeValue* SetOrientation(NativeEngine* engine, NativeCallbackInfo* info); private: sptr screen_ = nullptr; - NativeValue* OnRequestRotation(NativeEngine& engine, NativeCallbackInfo& info); + NativeValue* OnSetOrientation(NativeEngine& engine, NativeCallbackInfo& info); NativeValue* OnSetScreenActiveMode(NativeEngine& engine, NativeCallbackInfo& info); }; } // namespace Rosen diff --git a/interfaces/kits/napi/display_runtime/napi/js_screen_listener.cpp b/interfaces/kits/napi/display_runtime/napi/js_screen_listener.cpp index 2f225be9..7e0f3a84 100644 --- a/interfaces/kits/napi/display_runtime/napi/js_screen_listener.cpp +++ b/interfaces/kits/napi/display_runtime/napi/js_screen_listener.cpp @@ -80,16 +80,18 @@ void JsScreenListener::OnConnect(ScreenId id) WLOGFE("JsScreenListener::OnConnect not register!"); return; } - NativeValue* propertyValue = engine_->CreateObject(); - NativeObject* object = ConvertNativeValueTo(propertyValue); - if (object == nullptr) { - WLOGFE("Failed to convert prop to jsObject"); - return; - } - object->SetProperty("screenId", CreateJsValue(*engine_, static_cast(id))); - object->SetProperty("type", CreateJsValue(*engine_, SCREEN_CONNECT_TYPE)); - NativeValue* argv[] = {propertyValue}; - CallJsMethod("screenConnectEvent", argv, ArraySize(argv)); + + std::unique_ptr complete = std::make_unique ( + [=] (NativeEngine &engine, AsyncTask &task, int32_t status) { + NativeValue* argv[] = {CreateJsValue(*engine_, static_cast(id))}; + CallJsMethod("connect", argv, ArraySize(argv)); + } + ); + + NativeReference* callback = nullptr; + std::unique_ptr execute = nullptr; + AsyncTask::Schedule(*engine_, std::make_unique( + callback, std::move(execute), std::move(complete))); } void JsScreenListener::OnDisconnect(ScreenId id) @@ -100,19 +102,21 @@ void JsScreenListener::OnDisconnect(ScreenId id) WLOGFE("JsScreenListener::OnDisconnect not register!"); return; } - NativeValue* propertyValue = engine_->CreateObject(); - NativeObject* object = ConvertNativeValueTo(propertyValue); - if (object == nullptr) { - WLOGFE("Failed to convert prop to jsObject"); - return; - } - object->SetProperty("screenId", CreateJsValue(*engine_, static_cast(id))); - object->SetProperty("type", CreateJsValue(*engine_, SCREEN_DISCONNECT_TYPE)); - NativeValue* argv[] = {propertyValue}; - CallJsMethod("screenConnectEvent", argv, ArraySize(argv)); + + std::unique_ptr complete = std::make_unique ( + [=] (NativeEngine &engine, AsyncTask &task, int32_t status) { + NativeValue* argv[] = {CreateJsValue(*engine_, static_cast(id))}; + CallJsMethod("disconnect", argv, ArraySize(argv)); + } + ); + + NativeReference* callback = nullptr; + std::unique_ptr execute = nullptr; + AsyncTask::Schedule(*engine_, std::make_unique( + callback, std::move(execute), std::move(complete))); } -void JsScreenListener::OnChange(const std::vector &vector, ScreenChangeEvent event) +void JsScreenListener::OnChange(ScreenId id) { std::lock_guard lock(mtx_); WLOGFI("JsScreenListener::OnChange is called"); @@ -120,16 +124,18 @@ void JsScreenListener::OnChange(const std::vector &vector, ScreenChang WLOGFE("JsScreenListener::OnChange not register!"); return; } - NativeValue* propertyValue = engine_->CreateObject(); - NativeObject* object = ConvertNativeValueTo(propertyValue); - if (object == nullptr) { - WLOGFE("Failed to convert prop to jsObject"); - return; - } - object->SetProperty("screenId", CreateScreenIdArray(*engine_, vector)); - object->SetProperty("type", CreateJsValue(*engine_, event)); - NativeValue* argv[] = {propertyValue}; - CallJsMethod("screenChangeEvent", argv, ArraySize(argv)); + + std::unique_ptr complete = std::make_unique ( + [=] (NativeEngine &engine, AsyncTask &task, int32_t status) { + NativeValue* argv[] = {CreateJsValue(*engine_, static_cast(id))}; + CallJsMethod("change", argv, ArraySize(argv)); + } + ); + + NativeReference* callback = nullptr; + std::unique_ptr execute = nullptr; + AsyncTask::Schedule(*engine_, std::make_unique( + callback, std::move(execute), std::move(complete))); } NativeValue* JsScreenListener::CreateScreenIdArray(NativeEngine& engine, const std::vector& data) diff --git a/interfaces/kits/napi/display_runtime/napi/js_screen_listener.h b/interfaces/kits/napi/display_runtime/napi/js_screen_listener.h index db074137..ab4255df 100644 --- a/interfaces/kits/napi/display_runtime/napi/js_screen_listener.h +++ b/interfaces/kits/napi/display_runtime/napi/js_screen_listener.h @@ -33,7 +33,7 @@ public: void RemoveCallback(NativeValue* jsListenerObject); void OnConnect(ScreenId id) override; void OnDisconnect(ScreenId id) override; - void OnChange(const std::vector &vector, ScreenChangeEvent event) override; + void OnChange(ScreenId id) override; private: void CallJsMethod(const char* methodName, NativeValue* const* argv = nullptr, size_t argc = 0); diff --git a/interfaces/kits/napi/display_runtime/napi/js_screen_manager.cpp b/interfaces/kits/napi/display_runtime/napi/js_screen_manager.cpp index f70e49fa..8f74813a 100644 --- a/interfaces/kits/napi/display_runtime/napi/js_screen_manager.cpp +++ b/interfaces/kits/napi/display_runtime/napi/js_screen_manager.cpp @@ -12,10 +12,11 @@ * See the License for the specific language governing permissions and * limitations under the License. */ + #include "js_screen_manager.h" #include - +#include #include #include "js_runtime_utils.h" #include "js_screen_listener.h" @@ -138,8 +139,12 @@ void RegisterScreenListenerWithType(NativeEngine& engine, const std::string& typ } std::unique_ptr callbackRef; callbackRef.reset(engine.CreateReference(value, 1)); - sptr screenListener = new JsScreenListener(&engine); - if (type == "screenConnectEvent" || type == "screenChangeEvent") { + sptr screenListener = new(std::nothrow) JsScreenListener(&engine); + if (screenListener == nullptr) { + WLOGFE("screenListener is nullptr"); + return; + } + if (type == "connect" || type == "disconnect" || type == "change") { SingletonContainer::Get().RegisterScreenListener(screenListener); WLOGFI("JsScreenManager::RegisterScreenListenerWithType success"); } else { @@ -209,6 +214,10 @@ NativeValue* OnRegisterScreenMangerCallback(NativeEngine& engine, NativeCallback return engine.CreateUndefined(); } NativeValue* value = info.argv[INDEX_ONE]; + if (value == nullptr) { + WLOGFI("JsScreenManager::OnRegisterScreenMangerCallback info->argv[1] is nullptr"); + return engine.CreateUndefined(); + } if (!value->IsCallable()) { WLOGFI("JsScreenManager::OnRegisterScreenMangerCallback info->argv[1] is not callable"); return engine.CreateUndefined(); @@ -235,6 +244,10 @@ NativeValue* OnUnregisterScreenManagerCallback(NativeEngine& engine, NativeCallb UnregisterAllScreenListenerWithType(cbType); } else { NativeValue* value = info.argv[INDEX_ONE]; + if (value == nullptr) { + WLOGFI("JsScreenManager::OnUnregisterScreenManagerCallback info->argv[1] is nullptr"); + return engine.CreateUndefined(); + } if (!value->IsCallable()) { WLOGFI("JsScreenManager::OnUnregisterScreenManagerCallback info->argv[1] is not callable"); return engine.CreateUndefined(); @@ -308,7 +321,7 @@ NativeValue* OnMakeExpand(NativeEngine& engine, NativeCallbackInfo& info) } uint32_t size = array->GetLength(); std::vector options; - for (auto i = 0; i < size; ++i) { + for (uint32_t i = 0; i < size; ++i) { NativeObject* object = ConvertNativeValueTo(array->GetElement(i)); ExpandOption expandOption; int32_t res = GetExpandOptionFromJs(engine, object, expandOption); diff --git a/interfaces/kits/napi/window_runtime/window_manager_napi/js_window_manager.cpp b/interfaces/kits/napi/window_runtime/window_manager_napi/js_window_manager.cpp index 06093687..28f94120 100644 --- a/interfaces/kits/napi/window_runtime/window_manager_napi/js_window_manager.cpp +++ b/interfaces/kits/napi/window_runtime/window_manager_napi/js_window_manager.cpp @@ -605,10 +605,14 @@ NativeValue* JsWindowManager::OnSetWindowLayoutMode(NativeEngine& engine, Native task.Reject(engine, CreateJsError(engine, static_cast(errCode), "Invalidate params.")); return; } - SingletonContainer::Get().SetWindowLayoutMode(winLayoutMode, + WMError ret = SingletonContainer::Get().SetWindowLayoutMode(winLayoutMode, static_cast(displayId)); - task.Resolve(engine, engine.CreateUndefined()); - WLOGFI("JsWindowManager::OnSetWindowLayoutMode success"); + if (ret == WMError::WM_OK) { + task.Resolve(engine, engine.CreateUndefined()); + WLOGFI("JsWindowManager::OnSetWindowLayoutMode success"); + } else { + task.Reject(engine, CreateJsError(engine, static_cast(ret), "do failed")); + } }; NativeValue* lastParam = (info.argc < ARGC_THREE) ? nullptr : (info.argv[INDEX_TWO]->TypeOf() == NATIVE_FUNCTION ? info.argv[INDEX_TWO] : nullptr); diff --git a/interfaces/kits/napi/window_runtime/window_napi/js_window.cpp b/interfaces/kits/napi/window_runtime/window_napi/js_window.cpp index f975eae6..061b77f4 100644 --- a/interfaces/kits/napi/window_runtime/window_napi/js_window.cpp +++ b/interfaces/kits/napi/window_runtime/window_napi/js_window.cpp @@ -49,6 +49,10 @@ void JsWindow::Finalizer(NativeEngine* engine, void* data, void* hint) { WLOGFI("JsWindow::Finalizer is called"); auto jsWin = std::unique_ptr(static_cast(data)); + if (jsWin == nullptr) { + WLOGFE("JsWindow::Finalizer JsWindow is null"); + return; + } std::string windowName = jsWin->GetWindowName(); WLOGFI("JsWindow::Finalizer windowName : %{public}s", windowName.c_str()); std::lock_guard lock(g_mutex); diff --git a/interfaces/kits/napi/window_runtime/window_napi/js_window_utils.cpp b/interfaces/kits/napi/window_runtime/window_napi/js_window_utils.cpp index e1271c0a..5c23afc5 100644 --- a/interfaces/kits/napi/window_runtime/window_napi/js_window_utils.cpp +++ b/interfaces/kits/napi/window_runtime/window_napi/js_window_utils.cpp @@ -78,7 +78,7 @@ static std::string GetHexColor(uint32_t color) std::string temp; ioss << std::setiosflags(std::ios::uppercase) << std::hex << color; ioss >> temp; - int count = RGBA_LENGTH - temp.length(); + int count = RGBA_LENGTH - static_cast(temp.length()); std::string tmpColor(count, '0'); tmpColor += temp; std::string finalColor("#"); diff --git a/snapshot/BUILD.gn b/snapshot/BUILD.gn index 859799ef..cbbddd66 100644 --- a/snapshot/BUILD.gn +++ b/snapshot/BUILD.gn @@ -43,6 +43,32 @@ ohos_executable("snapshot_display") { subsystem_name = "window" } +ohos_executable("snapshot_virtual_screen") { + install_enable = false + sources = [ + "snapshot_utils.cpp", + "snapshot_virtual_screen.cpp", + ] + + configs = [ ":snapshot_config" ] + + deps = [ + "//foundation/graphic/standard/rosen/modules/render_service_client:librender_service_client", + "//foundation/windowmanager/dm:libdm", + "//foundation/windowmanager/utils:libwmutil", + "//foundation/windowmanager/wm:libwm", + "//third_party/libpng:libpng", # png + ] + + external_deps = [ + "multimedia_image_standard:image_native", + "utils_base:utils", + ] + + part_name = "window_manager" + subsystem_name = "window" +} + ## Build snapshot }}} group("test") { diff --git a/snapshot/snapshot_display.cpp b/snapshot/snapshot_display.cpp index f71010fd..a9504e5b 100644 --- a/snapshot/snapshot_display.cpp +++ b/snapshot/snapshot_display.cpp @@ -24,7 +24,7 @@ using namespace OHOS::Rosen; int main(int argc, char *argv[]) { CmdArgments cmdArgments; - cmdArgments.fileName = "/data/snapshot_display_1.png"; + cmdArgments.fileName = ""; if (!SnapShotUtils::ProcessArgs(argc, argv, cmdArgments)) { return 0; diff --git a/snapshot/snapshot_utils.cpp b/snapshot/snapshot_utils.cpp index af4f77ee..ca5a8fd3 100644 --- a/snapshot/snapshot_utils.cpp +++ b/snapshot/snapshot_utils.cpp @@ -16,7 +16,9 @@ #include "snapshot_utils.h" #include +#include #include +#include #include #include "wm_trace.h" @@ -26,8 +28,11 @@ using namespace OHOS::Rosen; namespace OHOS { constexpr int BITMAP_DEPTH = 8; constexpr int BPP = 4; +constexpr int MAX_TIME_STR_LEN = 40; +constexpr int YEAR_SINCE = 1900; const char *VALID_SNAPSHOT_PATH = "/data"; +const char *DEFAULT_SNAPSHOT_PREFIX = "/snapshot"; const char *VALID_SNAPSHOT_SUFFIX = ".png"; void SnapShotUtils::PrintUsage(const std::string &cmdLine) @@ -35,6 +40,28 @@ void SnapShotUtils::PrintUsage(const std::string &cmdLine) printf("usage: %s [-i displayId] [-f output_file] [-w width] [-h height] [-m]\n", cmdLine.c_str()); } +std::string SnapShotUtils::GenerateFileName(int offset) +{ + timeval tv; + std::string fileName = VALID_SNAPSHOT_PATH; + char timeStr[MAX_TIME_STR_LEN] = { 0 }; + + fileName += DEFAULT_SNAPSHOT_PREFIX; + if (gettimeofday(&tv, nullptr) == 0) { + tv.tv_sec += offset; // add offset second + struct tm *tmVal = localtime(&tv.tv_sec); + if (tmVal != nullptr) { + snprintf_s(timeStr, sizeof(timeStr), sizeof(timeStr) - 1, + "_%04d-%02d-%02d_%02d-%02d-%02d", + tmVal->tm_year + YEAR_SINCE, tmVal->tm_mon + 1, tmVal->tm_mday, + tmVal->tm_hour, tmVal->tm_min, tmVal->tm_sec); + fileName += timeStr; + } + } + fileName += VALID_SNAPSHOT_SUFFIX; + return fileName; +} + bool SnapShotUtils::CheckFileNameValid(const std::string &fileName) { WM_SCOPED_TRACE("snapshot:CheckFileNameValid(%s)", fileName.c_str()); @@ -237,6 +264,11 @@ bool SnapShotUtils::ProcessArgs(int argc, char * const argv[], CmdArgments &cmdA return false; } + if (cmdArgments.fileName == "") { + cmdArgments.fileName = GenerateFileName(); + printf("process: set filename to %s\n", cmdArgments.fileName.c_str()); + } + // check fileName if (!SnapShotUtils::CheckFileNameValid(cmdArgments.fileName)) { printf("error: filename %s invalid!\n", cmdArgments.fileName.c_str()); diff --git a/snapshot/snapshot_utils.h b/snapshot/snapshot_utils.h index 27d3b857..722e7ca7 100644 --- a/snapshot/snapshot_utils.h +++ b/snapshot/snapshot_utils.h @@ -47,6 +47,7 @@ public: static void PrintUsage(const std::string &cmdLine); static bool CheckFileNameValid(const std::string &fileName); + static std::string GenerateFileName(int offset = 0); static bool CheckWidthAndHeightValid(const CmdArgments& cmdArgments); static bool WriteToPng(const std::string &fileName, const WriteToPngParam ¶m); static bool WriteToPngWithPixelMap(const std::string &fileName, Media::PixelMap &pixelMap); diff --git a/snapshot/snapshot_virtual_screen.cpp b/snapshot/snapshot_virtual_screen.cpp new file mode 100644 index 00000000..8d0e0b5b --- /dev/null +++ b/snapshot/snapshot_virtual_screen.cpp @@ -0,0 +1,97 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include +#include + +#include "snapshot_utils.h" +#include "screen_manager.h" +#include "surface_reader.h" +#include "surface_reader_handler_impl.h" + +using namespace OHOS; +using namespace OHOS::Rosen; +using namespace OHOS::Media; + +namespace { +const int SLEEP_US = 10 * 1000; // 10ms +const int MAX_SNAPSHOT_COUNT = 10; +const int MAX_WAIT_COUNT = 200; +const float DEFAULT_DENSITY = 2.0; +const std::string FILE_NAME = "/data/snapshot_virtual_screen"; +} + +static VirtualScreenOption InitOption(ScreenId mainId, SurfaceReader& surfaceReader) +{ + auto defaultScreen = ScreenManager::GetInstance().GetScreenById(mainId); + VirtualScreenOption option = { + .name_ = "virtualScreen", + .width_ = defaultScreen->GetWidth(), + .height_ = defaultScreen->GetHeight(), + .density_ = DEFAULT_DENSITY, + .surface_ = surfaceReader.GetSurface(), + .flags_ = 0, + .isForShot_ = true, + }; + return option; +} + +int main(int argc, char *argv[]) +{ + SurfaceReader surfaceReader; + sptr surfaceReaderHandler = new SurfaceReaderHandlerImpl(); + if (!surfaceReader.Init()) { + printf("surfaceReader init failed!\n"); + return 0; + } + surfaceReader.SetHandler(surfaceReaderHandler); + ScreenId mainId = static_cast(DisplayManager::GetInstance().GetDefaultDisplayId()); + VirtualScreenOption option = InitOption(mainId, surfaceReader); + ScreenId virtualScreenId = ScreenManager::GetInstance().CreateVirtualScreen(option); + std::vector mirrorIds; + mirrorIds.push_back(virtualScreenId); + ScreenManager::GetInstance().MakeMirror(mainId, mirrorIds); + int fileIndex = 1; + auto startTime = time(nullptr); + while (time(nullptr) - startTime < MAX_SNAPSHOT_COUNT) { + int waitCount = 0; + while (!surfaceReaderHandler->IsImageOk()) { + waitCount++; + if (waitCount >= MAX_WAIT_COUNT) { + printf("wait image overtime\n"); + break; + } + usleep(SLEEP_US); + } + if (waitCount >= MAX_WAIT_COUNT) { + continue; + } + auto pixelMap = surfaceReaderHandler->GetPixelMap(); + bool ret = SnapShotUtils::WriteToPngWithPixelMap(FILE_NAME + std::to_string(fileIndex) + ".png", *pixelMap); + if (ret) { + printf("snapshot %" PRIu64 ", write to %s as png\n", + mainId, (FILE_NAME + std::to_string(fileIndex)).c_str()); + } else { + printf("snapshot %" PRIu64 " write to %s failed!\n", + mainId, (FILE_NAME + std::to_string(fileIndex)).c_str()); + } + surfaceReaderHandler->ResetFlag(); + fileIndex++; + } + ScreenManager::GetInstance().DestroyVirtualScreen(virtualScreenId); + printf("DestroyVirtualScreen %" PRIu64 "\n", virtualScreenId); + return 0; +} \ No newline at end of file diff --git a/utils/BUILD.gn b/utils/BUILD.gn index cd42616a..d18856c9 100644 --- a/utils/BUILD.gn +++ b/utils/BUILD.gn @@ -34,6 +34,8 @@ ohos_shared_library("libwmutil") { "src/screen_group_info.cpp", "src/screen_info.cpp", "src/singleton_container.cpp", + "src/surface_reader.cpp", + "src/surface_reader_handler_impl.cpp", "src/window_property.cpp", "src/wm_trace.cpp", ] @@ -49,6 +51,7 @@ ohos_shared_library("libwmutil") { "graphic_standard:surface", "hilog_native:libhilog", "ipc:ipc_core", + "multimedia_image_standard:image_native", "utils_base:utils", ] diff --git a/utils/include/class_var_defination.h b/utils/include/class_var_defination.h new file mode 100644 index 00000000..27bce64e --- /dev/null +++ b/utils/include/class_var_defination.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing p ermissions and + * limitations under the License. + */ + +#ifndef OHOS_ROSEN_CLASS_VAR_DEFINATION_H +#define OHOS_ROSEN_CLASS_VAR_DEFINATION_H +namespace OHOS::Rosen { +#define DEFINE_VAR(type, memberName) \ +private: \ + type memberName##_; + +#define DEFINE_VAR_DEFAULT(type, memberName, defaultValue) \ +private: \ + type memberName##_ {defaultValue}; + +#define DEFINE_FUNC_GET(type, funcName, memberName) \ +public: \ + type Get##funcName() const \ + { \ + return memberName##_; \ + } + +#define DEFINE_FUNC_SET(type, funcName, memberName) \ +public: \ + void Set##funcName(type value) \ + { \ + memberName##_ = value; \ + } + +#define DEFINE_VAR_FUNC_GET(type, funcName, memberName) \ + DEFINE_VAR(type, memberName) \ + DEFINE_FUNC_GET(type, funcName, memberName) + +#define DEFINE_VAR_DEFAULT_FUNC_GET(type, funcName, memberName, defaultValue) \ + DEFINE_VAR_DEFAULT(type, memberName, defaultValue) \ + DEFINE_FUNC_GET(type, funcName, memberName) + +#define DEFINE_VAR_FUNC_GET_SET(type, funcName, memberName) \ + DEFINE_VAR(type, memberName) \ + DEFINE_FUNC_GET(type, funcName, memberName) \ + DEFINE_FUNC_SET(type, funcName, memberName) + +#define DEFINE_VAR_DEFAULT_FUNC_GET_SET(type, funcName, memberName, defaultValue) \ + DEFINE_VAR_DEFAULT(type, memberName, defaultValue) \ + DEFINE_FUNC_GET(type, funcName, memberName) \ + DEFINE_FUNC_SET(type, funcName, memberName) +} // namespace OHOS::Rosen +#endif // OHOS_ROSEN_CLASS_VAR_DEFINATION_H diff --git a/utils/include/class_var_definition.h b/utils/include/class_var_definition.h new file mode 100644 index 00000000..c69794d2 --- /dev/null +++ b/utils/include/class_var_definition.h @@ -0,0 +1,59 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing p ermissions and + * limitations under the License. + */ + +#ifndef OHOS_ROSEN_CLASS_VAR_DEFINITION_H +#define OHOS_ROSEN_CLASS_VAR_DEFINITION_H +namespace OHOS::Rosen { +#define DEFINE_VAR(type, memberName) \ +private: \ + type memberName##_; + +#define DEFINE_VAR_DEFAULT(type, memberName, defaultValue) \ +private: \ + type memberName##_ {defaultValue}; + +#define DEFINE_FUNC_GET(type, funcName, memberName) \ +public: \ + type Get##funcName() const \ + { \ + return memberName##_; \ + } + +#define DEFINE_FUNC_SET(type, funcName, memberName) \ +public: \ + void Set##funcName(type value) \ + { \ + memberName##_ = value; \ + } + +#define DEFINE_VAR_FUNC_GET(type, funcName, memberName) \ + DEFINE_VAR(type, memberName) \ + DEFINE_FUNC_GET(type, funcName, memberName) + +#define DEFINE_VAR_DEFAULT_FUNC_GET(type, funcName, memberName, defaultValue) \ + DEFINE_VAR_DEFAULT(type, memberName, defaultValue) \ + DEFINE_FUNC_GET(type, funcName, memberName) + +#define DEFINE_VAR_FUNC_GET_SET(type, funcName, memberName) \ + DEFINE_VAR(type, memberName) \ + DEFINE_FUNC_GET(type, funcName, memberName) \ + DEFINE_FUNC_SET(type, funcName, memberName) + +#define DEFINE_VAR_DEFAULT_FUNC_GET_SET(type, funcName, memberName, defaultValue) \ + DEFINE_VAR_DEFAULT(type, memberName, defaultValue) \ + DEFINE_FUNC_GET(type, funcName, memberName) \ + DEFINE_FUNC_SET(type, funcName, memberName) +} // namespace OHOS::Rosen +#endif // OHOS_ROSEN_CLASS_VAR_DEFINITION_H diff --git a/utils/include/display_info.h b/utils/include/display_info.h index 0aab1010..e406cade 100644 --- a/utils/include/display_info.h +++ b/utils/include/display_info.h @@ -18,29 +18,35 @@ #include +#include "class_var_definition.h" #include "display.h" #include "dm_common.h" namespace OHOS::Rosen { class DisplayInfo : public Parcelable { +friend class AbstractDisplay; public: - DisplayInfo() = default; ~DisplayInfo() = default; - - void Update(DisplayInfo* info); + DisplayInfo(const DisplayInfo&) = delete; + DisplayInfo(DisplayInfo&&) = delete; + DisplayInfo& operator=(const DisplayInfo&) = delete; + DisplayInfo& operator=(DisplayInfo&&) = delete; virtual bool Marshalling(Parcel& parcel) const override; static DisplayInfo *Unmarshalling(Parcel& parcel); - DisplayId id_ { DISPLAY_ID_INVALD }; - DisplayType type_ {DisplayType::DEFAULT }; - int32_t width_ { 0 }; - int32_t height_ { 0 }; - uint32_t freshRate_ { 0 }; - ScreenId screenId_ { SCREEN_ID_INVALID }; - float xDpi_ { 0.0 }; - float yDpi_ { 0.0 }; - Rotation rotation_ { Rotation::ROTATION_0 }; + DEFINE_VAR_DEFAULT_FUNC_GET(DisplayId, DisplayId, id, DISPLAY_ID_INVALD); + DEFINE_VAR_DEFAULT_FUNC_GET(DisplayType, DisplayType, type, DisplayType::DEFAULT); + DEFINE_VAR_DEFAULT_FUNC_GET(int32_t, Width, width, 0); + DEFINE_VAR_DEFAULT_FUNC_GET(int32_t, Height, height, 0); + DEFINE_VAR_DEFAULT_FUNC_GET(uint32_t, FreshRate, freshRate, 0); + DEFINE_VAR_DEFAULT_FUNC_GET(ScreenId, ScreenId, screenId, SCREEN_ID_INVALID); + DEFINE_VAR_DEFAULT_FUNC_GET(float, XDpi, xDpi, 0.0f); + DEFINE_VAR_DEFAULT_FUNC_GET(float, YDpi, yDpi, 0.0f); + DEFINE_VAR_DEFAULT_FUNC_GET(Rotation, Rotation, rotation, Rotation::ROTATION_0); + DEFINE_VAR_DEFAULT_FUNC_GET(Orientation, Orientation, orientation, Orientation::UNSPECIFIED); +protected: + DisplayInfo() = default; }; } // namespace OHOS::Rosen #endif // FOUNDATION_DMSERVER_DISPLAY_INFO_H \ No newline at end of file diff --git a/utils/include/future.h b/utils/include/future.h index 62b006e3..b8c3584e 100644 --- a/utils/include/future.h +++ b/utils/include/future.h @@ -50,5 +50,37 @@ private: std::condition_variable conditionVariable_; std::mutex mutex_; }; + +template +class RunnableFuture : public Future { +public: + void SetValue(T res) + { + Future::FutureCall(res); + } + void Reset() + { + flag_ = false; + } +protected: + void Call(T res) override + { + if (!flag_) { + flag_ = true; + result_ = res; + } + } + bool IsReady() override + { + return flag_; + } + T FetchResult() override + { + return result_; + } +private: + bool flag_ {false}; + T result_; +}; } // namespace OHOS::Rosen #endif // OHOS_WM_INCLUDE_FUTURE_H diff --git a/utils/include/screen_group_info.h b/utils/include/screen_group_info.h index 6a9addbf..c1980182 100644 --- a/utils/include/screen_group_info.h +++ b/utils/include/screen_group_info.h @@ -23,20 +23,23 @@ namespace OHOS::Rosen { class ScreenGroupInfo : public ScreenInfo { +friend class AbstractScreenGroup; public: - ScreenGroupInfo() = default; ~ScreenGroupInfo() = default; - - void Update(sptr info); + ScreenGroupInfo(const ScreenGroupInfo&) = delete; + ScreenGroupInfo(ScreenGroupInfo&&) = delete; + ScreenGroupInfo& operator=(const ScreenGroupInfo&) = delete; + ScreenGroupInfo& operator=(ScreenGroupInfo&&) = delete; virtual bool Marshalling(Parcel& parcel) const override; static ScreenGroupInfo* Unmarshalling(Parcel& parcel); - std::vector children_; - std::vector position_; - ScreenCombination combination_ { ScreenCombination::SCREEN_ALONE }; -protected: - ScreenGroupInfo* InnerUnmarshalling(Parcel& parcel); + DEFINE_VAR_FUNC_GET(std::vector, Children, children); + DEFINE_VAR_FUNC_GET(std::vector, Position, position); + DEFINE_VAR_DEFAULT_FUNC_GET(ScreenCombination, Combination, combination, ScreenCombination::SCREEN_ALONE); +private: + ScreenGroupInfo() = default; + bool InnerUnmarshalling(Parcel& parcel); }; } // namespace OHOS::Rosen #endif // FOUNDATION_DMSERVER_SCREEN_GROUP_INFO_H \ No newline at end of file diff --git a/utils/include/screen_info.h b/utils/include/screen_info.h index c39fad9d..a3965dda 100644 --- a/utils/include/screen_info.h +++ b/utils/include/screen_info.h @@ -18,30 +18,42 @@ #include +#include "class_var_definition.h" #include "screen.h" namespace OHOS::Rosen { +enum class ScreenType : uint32_t { + UNDEFINE, + REAL, + VIRTUAL +}; class ScreenInfo : public Parcelable { +friend class AbstractScreen; public: - ScreenInfo() = default; ~ScreenInfo() = default; - - void Update(sptr info); + ScreenInfo(const ScreenInfo&) = delete; + ScreenInfo(ScreenInfo&&) = delete; + ScreenInfo& operator=(const ScreenInfo&) = delete; + ScreenInfo& operator= (ScreenInfo&&) = delete; virtual bool Marshalling(Parcel& parcel) const override; static ScreenInfo* Unmarshalling(Parcel& parcel); - ScreenId id_ { SCREEN_ID_INVALID }; - uint32_t virtualWidth_ { 0 }; - uint32_t virtualHeight_ { 0 }; - float virtualPixelRatio_ { 0.0 }; - ScreenId parent_ { 0 }; - bool canHasChild_ { false }; - Rotation rotation_ { Rotation::ROTATION_0 }; - uint32_t modeId_ { 0 }; - std::vector> modes_ {}; + DEFINE_VAR_FUNC_GET(std::string, Name, name); + DEFINE_VAR_DEFAULT_FUNC_GET(ScreenId, ScreenId, id, SCREEN_ID_INVALID); + DEFINE_VAR_DEFAULT_FUNC_GET(uint32_t, VirtualWidth, virtualWidth, 0); + DEFINE_VAR_DEFAULT_FUNC_GET(uint32_t, VirtualHeight, virtualHeight, 0); + DEFINE_VAR_DEFAULT_FUNC_GET(float, VirtualPixelRatio, virtualPixelRatio, 0.0f); + DEFINE_VAR_DEFAULT_FUNC_GET(ScreenId, ParentId, parent, 0); + DEFINE_VAR_DEFAULT_FUNC_GET(bool, CanHasChild, canHasChild, false); + DEFINE_VAR_DEFAULT_FUNC_GET(Rotation, Rotation, rotation, Rotation::ROTATION_0); + DEFINE_VAR_DEFAULT_FUNC_GET(Orientation, Orientation, orientation, Orientation::UNSPECIFIED); + DEFINE_VAR_DEFAULT_FUNC_GET(ScreenType, Type, type, ScreenType::REAL); + DEFINE_VAR_DEFAULT_FUNC_GET_SET(uint32_t, ModeId, modeId, 0); + DEFINE_VAR_FUNC_GET(std::vector>, Modes, modes); protected: - ScreenInfo* InnerUnmarshalling(Parcel& parcel); + ScreenInfo() = default; + bool InnerUnmarshalling(Parcel& parcel); }; } // namespace OHOS::Rosen #endif // FOUNDATION_DMSERVER_DISPLAY_INFO_H diff --git a/utils/include/surface_reader.h b/utils/include/surface_reader.h new file mode 100644 index 00000000..49ea386c --- /dev/null +++ b/utils/include/surface_reader.h @@ -0,0 +1,66 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef SURFACE_READER_H +#define SURFACE_READER_H + +#include "refbase.h" + +#include + +#include "surface_reader_handler.h" + +namespace OHOS { +namespace Rosen { +class SurfaceReader { +public: + SurfaceReader(); + virtual ~SurfaceReader(); + + bool Init(); + void DeInit(); + + sptr GetSurface() const; + void SetHandler(sptr handler); +private: + class BufferListener : public IBufferConsumerListener { + public: + explicit BufferListener(SurfaceReader &surfaceReader): surfaceReader_(surfaceReader) + { + } + ~BufferListener() noexcept override = default; + void OnBufferAvailable() override + { + surfaceReader_.OnVsync(); + } + + private: + SurfaceReader &surfaceReader_; + }; + friend class BufferListener; + + void OnVsync(); + bool ProcessBuffer(const sptr &buf); + + sptr listener_ = nullptr; + sptr csurface_ = nullptr; // cosumer surface + sptr psurface_ = nullptr; // producer surface + sptr prevBuffer_ = nullptr; + sptr handler_ = nullptr; +}; +} +} + +#endif // SURFACE_READER_H diff --git a/dm/src/display_manager_agent.cpp b/utils/include/surface_reader_handler.h similarity index 55% rename from dm/src/display_manager_agent.cpp rename to utils/include/surface_reader_handler.h index 2a928fc7..016b356f 100644 --- a/dm/src/display_manager_agent.cpp +++ b/utils/include/surface_reader_handler.h @@ -13,20 +13,22 @@ * limitations under the License. */ -#include "display_manager_agent.h" -#include "display_manager.h" -#include "singleton_container.h" +#ifndef SURFACE_READER_HANDLER_H +#define SURFACE_READER_HANDLER_H + +#include "pixel_map.h" namespace OHOS { namespace Rosen { -void DisplayManagerAgent::NotifyDisplayPowerEvent(DisplayPowerEvent event, EventStatus status) -{ - SingletonContainer::Get().NotifyDisplayPowerEvent(event, status); +class SurfaceReaderHandler : public RefBase { +public: + SurfaceReaderHandler() {} + virtual ~SurfaceReaderHandler() noexcept + { + } + virtual bool OnImageAvalible(sptr pixleMap) = 0; +}; +} } -void DisplayManagerAgent::NotifyDisplayStateChanged(DisplayId id, DisplayState state) -{ - SingletonContainer::Get().NotifyDisplayStateChanged(id, state); -} -} // namespace Rosen -} // namespace OHOS \ No newline at end of file +#endif // IMAGE_READER_HANDLER_H diff --git a/dm/include/display_manager_agent.h b/utils/include/surface_reader_handler_impl.h similarity index 50% rename from dm/include/display_manager_agent.h rename to utils/include/surface_reader_handler_impl.h index 0d46fde2..359d6c8a 100644 --- a/dm/include/display_manager_agent.h +++ b/utils/include/surface_reader_handler_impl.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Huawei Device Co., Ltd. + * Copyright (c) 2022 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -13,22 +13,27 @@ * limitations under the License. */ -#ifndef OHOS_ROSEN_DISPLAY_MANAGER_AGENT_H -#define OHOS_ROSEN_DISPLAY_MANAGER_AGENT_H +#ifndef SURFACE_READER_HANDLER_IMPL_H +#define SURFACE_READER_HANDLER_IMPL_H -#include -#include +#include +#include "surface_reader_handler.h" namespace OHOS { namespace Rosen { -class DisplayManagerAgent : public DisplayManagerAgentDefault { +class SurfaceReaderHandlerImpl : public SurfaceReaderHandler { public: - DisplayManagerAgent() = default; - ~DisplayManagerAgent() = default; + bool OnImageAvalible(sptr pixleMap) override; + bool IsImageOk(); + void ResetFlag(); + sptr GetPixelMap(); - virtual void NotifyDisplayPowerEvent(DisplayPowerEvent event, EventStatus status) override; - virtual void NotifyDisplayStateChanged(DisplayId id, DisplayState state) override; +private: + bool flag_ = false; + sptr pixleMap_ = nullptr; + std::recursive_mutex mutex_; }; } } -#endif // OHOS_ROSEN_DISPLAY_MANAGER_AGENT_H + +#endif // SURFACE_READER_HANDLER_IMPL_H diff --git a/utils/include/window_helper.h b/utils/include/window_helper.h index f521d3be..a8091862 100644 --- a/utils/include/window_helper.h +++ b/utils/include/window_helper.h @@ -17,6 +17,7 @@ #define OHOS_WM_INCLUDE_WM_HELPER_H #include +#include namespace OHOS { namespace Rosen { @@ -24,12 +25,12 @@ class WindowHelper { public: static inline bool IsMainWindow(WindowType type) { - return (type >= WindowType::APP_MAIN_WINDOW_BASE && type <= WindowType::APP_MAIN_WINDOW_END); + return (type >= WindowType::APP_MAIN_WINDOW_BASE && type < WindowType::APP_MAIN_WINDOW_END); } static inline bool IsSubWindow(WindowType type) { - return (type >= WindowType::APP_SUB_WINDOW_BASE && type <= WindowType::APP_SUB_WINDOW_END); + return (type >= WindowType::APP_SUB_WINDOW_BASE && type < WindowType::APP_SUB_WINDOW_END); } static inline bool IsAppWindow(WindowType type) @@ -39,12 +40,12 @@ public: static inline bool IsBelowSystemWindow(WindowType type) { - return (type >= WindowType::BELOW_APP_SYSTEM_WINDOW_BASE && type <= WindowType::BELOW_APP_SYSTEM_WINDOW_END); + return (type >= WindowType::BELOW_APP_SYSTEM_WINDOW_BASE && type < WindowType::BELOW_APP_SYSTEM_WINDOW_END); } static inline bool IsAboveSystemWindow(WindowType type) { - return (type >= WindowType::ABOVE_APP_SYSTEM_WINDOW_BASE && type <= WindowType::ABOVE_APP_SYSTEM_WINDOW_END); + return (type >= WindowType::ABOVE_APP_SYSTEM_WINDOW_BASE && type < WindowType::ABOVE_APP_SYSTEM_WINDOW_END); } static inline bool IsSystemWindow(WindowType type) @@ -57,6 +58,11 @@ public: return ((IsMainWindow(type)) && (mode == WindowMode::WINDOW_MODE_FLOATING)); } + static inline bool IsAvoidAreaWindow(WindowType type) + { + return (type == WindowType::WINDOW_TYPE_STATUS_BAR || type == WindowType::WINDOW_TYPE_NAVIGATION_BAR); + } + static inline bool IsSplitWindowMode(WindowMode mode) { return mode == WindowMode::WINDOW_MODE_SPLIT_PRIMARY || mode == WindowMode::WINDOW_MODE_SPLIT_SECONDARY; @@ -79,23 +85,28 @@ public: return (r.posX_ == 0 && r.posY_ == 0 && r.width_ == 0 && r.height_ == 0); } - static Rect GetFixedWindowRectByMinRect(const Rect& oriDstRect, const Rect& lastRect, bool isVertical) + static Rect GetFixedWindowRectByMinRect(const Rect& oriDstRect, const Rect& lastRect, bool isVertical, + float virtualPixelRatio) { + uint32_t minVerticalFloatingW = static_cast(MIN_VERTICAL_FLOATING_WIDTH * virtualPixelRatio); + uint32_t minVerticalFloatingH = static_cast(MIN_VERTICAL_FLOATING_HEIGHT * virtualPixelRatio); Rect dstRect = oriDstRect; if (isVertical) { - dstRect.width_ = std::max(MIN_VERTICAL_FLOATING_WIDTH, oriDstRect.width_); - dstRect.height_ = std::max(MIN_VERTICAL_FLOATING_HEIGHT, oriDstRect.height_); + dstRect.width_ = std::max(minVerticalFloatingW, oriDstRect.width_); + dstRect.height_ = std::max(minVerticalFloatingH, oriDstRect.height_); } else { - dstRect.width_ = std::max(MIN_VERTICAL_FLOATING_HEIGHT, oriDstRect.width_); - dstRect.height_ = std::max(MIN_VERTICAL_FLOATING_WIDTH, oriDstRect.height_); + dstRect.width_ = std::max(minVerticalFloatingH, oriDstRect.width_); + dstRect.height_ = std::max(minVerticalFloatingW, oriDstRect.height_); } // limit position by fixed width or height if (oriDstRect.posX_ != lastRect.posX_) { - dstRect.posX_ = oriDstRect.posX_ + oriDstRect.width_ - dstRect.width_; + dstRect.posX_ = oriDstRect.posX_ + static_cast(oriDstRect.width_) - + static_cast(dstRect.width_); } if (oriDstRect.posY_ != lastRect.posY_) { - dstRect.posY_ = oriDstRect.posY_ + oriDstRect.height_ - dstRect.height_; + dstRect.posY_ = oriDstRect.posY_ + static_cast(oriDstRect.height_) - + static_cast(dstRect.height_); } return dstRect; } @@ -103,9 +114,9 @@ public: static bool IsPointInWindow(int32_t pointPosX, int32_t pointPosY, Rect pointRect) { if ((pointPosX > pointRect.posX_) && - (pointPosX < static_cast(pointRect.posX_ + pointRect.width_)) && + (pointPosX < (pointRect.posX_ + static_cast(pointRect.width_))) && (pointPosY > pointRect.posY_) && - (pointPosY < static_cast(pointRect.posY_ + pointRect.height_))) { + (pointPosY < (pointRect.posY_ + static_cast(pointRect.height_)))) { return true; } return false; diff --git a/utils/include/wm_common_inner.h b/utils/include/wm_common_inner.h index d967fcad..369fd40d 100644 --- a/utils/include/wm_common_inner.h +++ b/utils/include/wm_common_inner.h @@ -35,6 +35,27 @@ enum class WindowStateChangeReason : uint32_t { NORMAL, KEYGUARD, }; + +enum class WindowUpdateReason : uint32_t { + UPDATE_ALL, + UPDATE_MODE, + UPDATE_RECT, + UPDATE_FLAGS, + UPDATE_TYPE, + UPDATE_OTHER_PROPS, +}; +namespace { + constexpr float DEFAULT_SPLIT_RATIO = 0.5; + constexpr uint32_t DIVIDER_WIDTH = 8; + constexpr uint32_t WINDOW_TITLE_BAR_HEIGHT = 48; + constexpr uint32_t WINDOW_FRAME_WIDTH = 4; + constexpr uint32_t HOTZONE = 40; + constexpr uint32_t DIV_HOTZONE = 20; + constexpr uint32_t MIN_VERTICAL_FLOATING_WIDTH = 240; + constexpr uint32_t MIN_VERTICAL_FLOATING_HEIGHT = 426; + constexpr uint32_t MIN_VERTICAL_SPLIT_HEIGHT = 426; + constexpr uint32_t MIN_HORIZONTAL_SPLIT_WIDTH = 426; +} } } #endif // OHOS_ROSEN_WM_COMMON_INNER_H \ No newline at end of file diff --git a/utils/src/display_info.cpp b/utils/src/display_info.cpp index 0ff79f31..e31a1981 100644 --- a/utils/src/display_info.cpp +++ b/utils/src/display_info.cpp @@ -16,47 +16,34 @@ #include "display_info.h" namespace OHOS::Rosen { -void DisplayInfo::Update(DisplayInfo* info) -{ - id_ = info->id_; - type_ = info->type_; - width_ = info->width_; - height_ = info->height_; - freshRate_ = info->freshRate_; - screenId_ = info->screenId_; - xDpi_ = info->xDpi_; - yDpi_ = info->yDpi_; - rotation_ = info->rotation_; -} - bool DisplayInfo::Marshalling(Parcel &parcel) const { return parcel.WriteUint64(id_) && parcel.WriteUint32(type_) && parcel.WriteInt32(width_) && parcel.WriteInt32(height_) && parcel.WriteUint32(freshRate_) && parcel.WriteUint64(screenId_) && parcel.WriteFloat(xDpi_) && parcel.WriteFloat(yDpi_) && - parcel.WriteUint32(static_cast(rotation_)); + parcel.WriteUint32(static_cast(rotation_)) && + parcel.WriteUint32(static_cast(orientation_)); } DisplayInfo *DisplayInfo::Unmarshalling(Parcel &parcel) { DisplayInfo *displayInfo = new DisplayInfo(); - if (displayInfo == nullptr) { - return nullptr; - } uint32_t type = (uint32_t)DisplayType::DEFAULT; uint32_t rotation; + uint32_t orientation; bool res = parcel.ReadUint64(displayInfo->id_) && parcel.ReadUint32(type) && parcel.ReadInt32(displayInfo->width_) && parcel.ReadInt32(displayInfo->height_) && parcel.ReadUint32(displayInfo->freshRate_) && parcel.ReadUint64(displayInfo->screenId_) && parcel.ReadFloat(displayInfo->xDpi_) && parcel.ReadFloat(displayInfo->yDpi_) && - parcel.ReadUint32(rotation); + parcel.ReadUint32(rotation) && parcel.ReadUint32(orientation); if (!res) { - displayInfo = nullptr; - } else { - displayInfo->type_ = (DisplayType)type; - displayInfo->rotation_ = static_cast(rotation); + delete displayInfo; + return nullptr; } + displayInfo->type_ = (DisplayType)type; + displayInfo->rotation_ = static_cast(rotation); + displayInfo->orientation_ = static_cast(orientation); return displayInfo; } } // namespace OHOS::Rosen \ No newline at end of file diff --git a/utils/src/screen_group_info.cpp b/utils/src/screen_group_info.cpp index 56268c74..ed4e4122 100644 --- a/utils/src/screen_group_info.cpp +++ b/utils/src/screen_group_info.cpp @@ -16,16 +16,6 @@ #include "screen_group_info.h" namespace OHOS::Rosen { -void ScreenGroupInfo::Update(sptr info) -{ - ScreenInfo::Update(info); - children_.clear(); - children_.insert(children_.begin(), info->children_.begin(), info->children_.end()); - position_.clear(); - position_.insert(position_.begin(), info->position_.begin(), info->position_.end()); - combination_ = info->combination_; -} - bool ScreenGroupInfo::Marshalling(Parcel &parcel) const { bool res = ScreenInfo::Marshalling(parcel) && parcel.WriteUint32((uint32_t)combination_) && @@ -48,29 +38,34 @@ bool ScreenGroupInfo::Marshalling(Parcel &parcel) const ScreenGroupInfo* ScreenGroupInfo::Unmarshalling(Parcel &parcel) { ScreenGroupInfo* screenGroupInfo = new ScreenGroupInfo(); - return screenGroupInfo->InnerUnmarshalling(parcel); + bool res = screenGroupInfo->InnerUnmarshalling(parcel); + if (res) { + return screenGroupInfo; + } + delete screenGroupInfo; + return nullptr; } -ScreenGroupInfo* ScreenGroupInfo::InnerUnmarshalling(Parcel& parcel) +bool ScreenGroupInfo::InnerUnmarshalling(Parcel& parcel) { uint32_t combination; if (!ScreenInfo::InnerUnmarshalling(parcel) || !parcel.ReadUint32(combination) || !parcel.ReadUInt64Vector(&children_)) { - return nullptr; + return false; } combination_ = (ScreenCombination) combination; uint32_t size; if (!parcel.ReadUint32(size)) { - return nullptr; + return false; } for (size_t i = 0; i < size; i++) { Point point; if (parcel.ReadInt32(point.posX_) && parcel.ReadInt32(point.posY_)) { position_.push_back(point); } else { - return nullptr; + return false; } } - return this; + return true; } } // namespace OHOS::Rosen \ No newline at end of file diff --git a/utils/src/screen_info.cpp b/utils/src/screen_info.cpp index a3df26fe..84e649cc 100644 --- a/utils/src/screen_info.cpp +++ b/utils/src/screen_info.cpp @@ -16,25 +16,14 @@ #include "screen_info.h" namespace OHOS::Rosen { -void ScreenInfo::Update(sptr info) -{ - id_ = info->id_; - virtualWidth_ = info->virtualWidth_; - virtualHeight_ = info->virtualHeight_; - virtualPixelRatio_ = info->virtualPixelRatio_; - parent_ = info->parent_; - canHasChild_ = info->canHasChild_; - rotation_ = info->rotation_; - modeId_ = info->modeId_; - modes_ = info->modes_; -} - bool ScreenInfo::Marshalling(Parcel &parcel) const { - bool res = parcel.WriteUint64(id_) && + bool res = parcel.WriteString(name_) && parcel.WriteUint64(id_) && parcel.WriteUint32(virtualWidth_) && parcel.WriteUint32(virtualHeight_) && parcel.WriteFloat(virtualPixelRatio_) && parcel.WriteUint64(parent_) && parcel.WriteBool(canHasChild_) && parcel.WriteUint32(static_cast(rotation_)) && + parcel.WriteUint32(static_cast(orientation_)) && + parcel.WriteUint32(static_cast(type_)) && parcel.WriteUint32(modeId_) && parcel.WriteUint32(static_cast(modes_.size())); if (!res) { return false; @@ -53,20 +42,29 @@ bool ScreenInfo::Marshalling(Parcel &parcel) const ScreenInfo* ScreenInfo::Unmarshalling(Parcel &parcel) { ScreenInfo* info = new ScreenInfo(); - return info->InnerUnmarshalling(parcel); + bool res = info->InnerUnmarshalling(parcel); + if (res) { + return info; + } + delete info; + return nullptr; } -ScreenInfo* ScreenInfo::InnerUnmarshalling(Parcel& parcel) +bool ScreenInfo::InnerUnmarshalling(Parcel& parcel) { uint32_t size = 0; uint32_t rotation; + uint32_t orientation; + uint32_t type; + name_ = parcel.ReadString(); bool res1 = parcel.ReadUint64(id_) && parcel.ReadUint32(virtualWidth_) && parcel.ReadUint32(virtualHeight_) && parcel.ReadFloat(virtualPixelRatio_) && parcel.ReadUint64(parent_) && parcel.ReadBool(canHasChild_) && parcel.ReadUint32(rotation) && + parcel.ReadUint32(orientation) && parcel.ReadUint32(type) && parcel.ReadUint32(modeId_) && parcel.ReadUint32(size); if (!res1) { - return nullptr; + return false; } modes_.clear(); for (uint32_t modeIndex = 0; modeIndex < size; modeIndex++) { @@ -76,10 +74,12 @@ ScreenInfo* ScreenInfo::InnerUnmarshalling(Parcel& parcel) parcel.ReadUint32(mode->freshRate_)) { modes_.push_back(mode); } else { - return nullptr; + return false; } } rotation_ = static_cast(rotation); - return this; + orientation_ = static_cast(orientation); + type_ = static_cast(type); + return true; } } // namespace OHOS::Rosen \ No newline at end of file diff --git a/utils/src/surface_reader.cpp b/utils/src/surface_reader.cpp new file mode 100644 index 00000000..0ed3e689 --- /dev/null +++ b/utils/src/surface_reader.cpp @@ -0,0 +1,152 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "surface_reader.h" +#include "window_manager_hilog.h" +#include "unique_fd.h" + +#include + +using namespace OHOS::Media; + +namespace OHOS { +namespace Rosen { +namespace { + constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_DISPLAY, "SurfaceReader"}; +} // namespace +const int BPP = 4; // bytes per pixel + +SurfaceReader::SurfaceReader() +{ +} + +SurfaceReader::~SurfaceReader() +{ + if (csurface_ != nullptr) { + csurface_->UnregisterConsumerListener(); + } + psurface_ = nullptr; + csurface_ = nullptr; +} + +bool SurfaceReader::Init() +{ + csurface_ = Surface::CreateSurfaceAsConsumer(); + if (csurface_ == nullptr) { + return false; + } + + auto producer = csurface_->GetProducer(); + psurface_ = Surface::CreateSurfaceAsProducer(producer); + if (psurface_ == nullptr) { + return false; + } + + listener_ = new BufferListener(*this); + SurfaceError ret = csurface_->RegisterConsumerListener(listener_); + if (ret != SURFACE_ERROR_OK) { + return false; + } + return true; +} + +void SurfaceReader::OnVsync() +{ + WLOGFI("SurfaceReader::OnVsync"); + + sptr cbuffer = nullptr; + int32_t fence = -1; + int64_t timestamp = 0; + Rect damage; + auto sret = csurface_->AcquireBuffer(cbuffer, fence, timestamp, damage); + if (cbuffer == nullptr || sret != OHOS::SURFACE_ERROR_OK) { + WLOGFE("SurfaceReader::OnVsync: surface buffer is null"); + return; + } + + if (!ProcessBuffer(cbuffer)) { + WLOGFE("SurfaceReader::OnVsync: ProcessBuffer failed"); + return; + } + + if (cbuffer != prevBuffer_) { + if (prevBuffer_ != nullptr) { + SurfaceError ret = csurface_->ReleaseBuffer(prevBuffer_, -1); + if (ret != SURFACE_ERROR_OK) { + WLOGFE("SurfaceReader::OnVsync: release buffer error"); + return; + } + } + + prevBuffer_ = cbuffer; + } +} + +sptr SurfaceReader::GetSurface() const +{ + return psurface_; +} + +void SurfaceReader::SetHandler(sptr handler) +{ + handler_ = handler; +} + +bool SurfaceReader::ProcessBuffer(const sptr &buf) +{ + if (handler_ == nullptr) { + WLOGFE("SurfaceReaderHandler not set"); + return false; + } + + BufferHandle *bufferHandle = buf->GetBufferHandle(); + if (bufferHandle == nullptr) { + WLOGFE("bufferHandle nullptr"); + return false; + } + + uint32_t width = static_cast(bufferHandle->width); + uint32_t height = static_cast(bufferHandle->height); + uint32_t stride = static_cast(bufferHandle->stride); + uint8_t *addr = (uint8_t *)buf->GetVirAddr(); + + auto data = (uint8_t *)malloc(width * height * BPP); + if (data == nullptr) { + WLOGFE("data malloc failed"); + return false; + } + for (uint32_t i = 0; i < height; i++) { + errno_t ret = memcpy_s(data + width * i * BPP, width * BPP, addr + stride * i, width * BPP); + if (ret != EOK) { + WLOGFE("memcpy failed"); + return false; + } + } + + sptr pixelMap = new PixelMap(); + ImageInfo info; + info.size.width = static_cast(width); + info.size.height = static_cast(height); + info.pixelFormat = PixelFormat::RGBA_8888; + info.colorSpace = ColorSpace::SRGB; + pixelMap->SetImageInfo(info); + + pixelMap->SetPixelsAddr(data, nullptr, width * height, AllocatorType::HEAP_ALLOC, nullptr); + + handler_->OnImageAvalible(pixelMap); + return true; +} +} +} \ No newline at end of file diff --git a/utils/src/surface_reader_handler_impl.cpp b/utils/src/surface_reader_handler_impl.cpp new file mode 100644 index 00000000..534c5fab --- /dev/null +++ b/utils/src/surface_reader_handler_impl.cpp @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "surface_reader_handler_impl.h" +#include "window_manager_hilog.h" + +namespace OHOS { +namespace Rosen { +namespace { + constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_DISPLAY, "SurfaceReaderHandlerImpl"}; +} // namespace +bool SurfaceReaderHandlerImpl::OnImageAvalible(sptr pixleMap) +{ + std::lock_guard locl(mutex_); + if (!flag_) { + flag_ = true; + pixleMap_ = pixleMap; + WLOGFI("Get an Image!"); + } + return true; +} + +bool SurfaceReaderHandlerImpl::IsImageOk() +{ + std::lock_guard lock(mutex_); + return flag_; +} + +void SurfaceReaderHandlerImpl::ResetFlag() +{ + std::lock_guard lock(mutex_); + if (flag_) { + flag_ = false; + } +} + +sptr SurfaceReaderHandlerImpl::GetPixelMap() +{ + return pixleMap_; +} +} +} \ No newline at end of file diff --git a/wm/BUILD.gn b/wm/BUILD.gn index 42f9ce64..8f8e1d4c 100644 --- a/wm/BUILD.gn +++ b/wm/BUILD.gn @@ -27,12 +27,6 @@ config("libwm_private_config") { "//third_party/jsoncpp/include", "//third_party/json/include", ] - - if (defined(product_name) && - (product_name == "rk3566" || product_name == "rk3568" || - product_name == "Hi3516DV300" || product_name == "watchos")) { - defines = [ "PRODUCT_RK" ] - } } config("libwm_public_config") { @@ -72,7 +66,7 @@ ohos_shared_library("libwm") { "//foundation/windowmanager/utils:libwmutil", # vsync - "//foundation/graphic/standard:libvsync_client", + "//foundation/graphic/standard/rosen/modules/composer:libcomposer", ] external_deps = [ diff --git a/wm/include/vsync_station.h b/wm/include/vsync_station.h index 1c362f74..25a5c65b 100644 --- a/wm/include/vsync_station.h +++ b/wm/include/vsync_station.h @@ -23,7 +23,8 @@ #include #include -#include +#include +#include #include "wm_single_instance.h" @@ -44,7 +45,6 @@ public: void RequestVsync(CallbackType type, std::shared_ptr vsyncCallback); private: - FrameCallback callback_; VsyncStation() = default; static void OnVsync(int64_t nanoTimestamp, void* client); void VsyncCallbackInner(int64_t nanoTimestamp); @@ -56,6 +56,7 @@ private: {CallbackType::CALLBACK_INPUT, {}}, {CallbackType::CALLBACK_FRAME, {}}, }; + std::shared_ptr receiver_ = nullptr; }; } // namespace Rosen } // namespace OHOS diff --git a/wm/include/window_adapter.h b/wm/include/window_adapter.h index 5369a4b0..5f69e22d 100644 --- a/wm/include/window_adapter.h +++ b/wm/include/window_adapter.h @@ -52,13 +52,9 @@ public: virtual WMError GetTopWindowId(uint32_t mainWinId, uint32_t& topWinId); virtual void ProcessWindowTouchedEvent(uint32_t windowId); virtual void MinimizeAllAppWindows(DisplayId displayId); + virtual WMError MaxmizeWindow(uint32_t windowId); virtual WMError SetWindowLayoutMode(DisplayId displayId, WindowLayoutMode mode); - // colorspace, gamut - virtual bool IsSupportWideGamut(uint32_t windowId); - virtual void SetColorSpace(uint32_t windowId, ColorSpace colorSpace); - virtual ColorSpace GetColorSpace(uint32_t windowId); - virtual void RegisterWindowManagerAgent(WindowManagerAgentType type, const sptr& windowManagerAgent); virtual void UnregisterWindowManagerAgent(WindowManagerAgentType type, @@ -67,11 +63,12 @@ public: virtual void ClearWindowAdapter(); private: static inline SingletonDelegator delegator; - bool InitWMSProxyLocked(); + bool InitWMSProxy(); std::recursive_mutex mutex_; sptr windowManagerServiceProxy_ = nullptr; sptr wmsDeath_ = nullptr; + bool isProxyValid_ { false }; }; } // namespace Rosen } // namespace OHOS diff --git a/wm/include/window_agent.h b/wm/include/window_agent.h index 90cbe567..fe3efeb4 100644 --- a/wm/include/window_agent.h +++ b/wm/include/window_agent.h @@ -27,13 +27,13 @@ class WindowAgent : public WindowStub { public: WindowAgent(sptr& window); ~WindowAgent() = default; - void UpdateWindowProperty(const WindowProperty& windowProperty) override; void UpdateWindowRect(const struct Rect& rect, WindowSizeChangeReason reason) override; void UpdateWindowMode(WindowMode mode) override; void UpdateFocusStatus(bool focused) override; void UpdateAvoidArea(const std::vector& avoidAreas) override; void UpdateWindowState(WindowState state) override; void UpdateWindowDragInfo(const PointInfo& point, DragEvent event) override; + void UpdateDisplayId(DisplayId from, DisplayId to) override; private: sptr window_; }; diff --git a/wm/include/window_impl.h b/wm/include/window_impl.h index fec55b2b..30c5c63d 100644 --- a/wm/include/window_impl.h +++ b/wm/include/window_impl.h @@ -23,6 +23,7 @@ #include #include #include +#include #include "input_transfer_station.h" #include "vsync_station.h" @@ -107,6 +108,8 @@ public: virtual void UnregisterAvoidAreaChangeListener() override; virtual void RegisterDragListener(sptr& listener) override; virtual void UnregisterDragListener(sptr& listener) override; + virtual void RegisterDisplayMoveListener(sptr& listener) override; + virtual void UnregisterDisplayMoveListener(sptr& listener) override; void UpdateRect(const struct Rect& rect, WindowSizeChangeReason reason); void UpdateMode(WindowMode mode); @@ -118,11 +121,13 @@ public: void UpdateAvoidArea(const std::vector& avoidAreas); void UpdateWindowState(WindowState state); void UpdateDragEvent(const PointInfo& point, DragEvent event); + void UpdateDisplayId(DisplayId from, DisplayId to); virtual WMError SetUIContent(const std::string& contentInfo, NativeEngine* engine, NativeValue* storage, bool isdistributed) override; virtual std::string GetContentInfo() override; virtual const std::shared_ptr GetContext() const override; + virtual Ace::UIContent* GetUIContent() const override; // colorspace, gamut virtual bool IsSupportWideGamut() override; @@ -154,6 +159,13 @@ private: uiContent_->Destroy(); } } + inline void NotifyBeforeSubWindowDestroy(sptr& window) const + { + auto uiContent = window->GetUIContent(); + if (uiContent != nullptr) { + uiContent->Destroy(); + } + } void SetDefaultOption(); // for api7 bool IsWindowValid() const; void OnVsync(int64_t timeStamp); @@ -167,6 +179,14 @@ private: bool IsPointerEventConsumed(); void AdjustWindowAnimationFlag(); void MapFloatingWindowToAppIfNeeded(); + // colorspace, gamut + using ColorSpaceConvertMap = struct { + ColorSpace colorSpace; + SurfaceColorGamut sufaceColorGamut; + }; + static const ColorSpaceConvertMap colorSpaceConvertMap[]; + static ColorSpace GetColorSpaceFromSurfaceGamut(SurfaceColorGamut surfaceColorGamut); + static SurfaceColorGamut GetSurfaceGamutFromColorSpace(ColorSpace colorSpace); std::shared_ptr callback_ = std::make_shared(VsyncStation::VsyncCallback()); @@ -179,6 +199,7 @@ private: std::vector> windowChangeListeners_; sptr avoidAreaChangeListener_; std::vector> windowDragListeners_; + std::vector> displayMoveListeners_; std::shared_ptr surfaceNode_; std::string name_; std::unique_ptr uiContent_; diff --git a/wm/include/window_interface.h b/wm/include/window_interface.h index 5e54f1b7..9e75e0f6 100644 --- a/wm/include/window_interface.h +++ b/wm/include/window_interface.h @@ -28,22 +28,22 @@ public: DECLARE_INTERFACE_DESCRIPTOR(u"OHOS.IWindow"); enum { - TRANS_ID_UPDATE_WINDOW_PROPERTY = 1, TRANS_ID_UPDATE_WINDOW_RECT, TRANS_ID_UPDATE_WINDOW_MODE, TRANS_ID_UPDATE_FOCUS_STATUS, TRANS_ID_UPDATE_AVOID_AREA, TRANS_ID_UPDATE_WINDOW_STATE, TRANS_ID_UPDATE_DRAG_EVENT, + TRANS_ID_UPDATE_DISPLAY_ID, }; - virtual void UpdateWindowProperty(const WindowProperty& windowProperty) = 0; virtual void UpdateWindowRect(const struct Rect& rect, WindowSizeChangeReason reason) = 0; virtual void UpdateWindowMode(WindowMode mode) = 0; virtual void UpdateFocusStatus(bool focused) = 0; virtual void UpdateAvoidArea(const std::vector& avoidAreas) = 0; virtual void UpdateWindowState(WindowState state) = 0; virtual void UpdateWindowDragInfo(const PointInfo& point, DragEvent event) = 0; + virtual void UpdateDisplayId(DisplayId from, DisplayId to) = 0; }; } // namespace Rosen } // namespace OHOS diff --git a/wm/include/window_manager_agent.h b/wm/include/window_manager_agent.h index b4325742..d3d1de42 100644 --- a/wm/include/window_manager_agent.h +++ b/wm/include/window_manager_agent.h @@ -30,6 +30,7 @@ public: DisplayId displayId, bool focused) override; void UpdateSystemBarRegionTints(DisplayId displayId, const SystemBarRegionTints& props) override; void UpdateWindowStatus(const sptr& windowInfo, WindowUpdateType type) override; + void UpdateWindowVisibilityInfo(const std::vector>& visibilityInfos) override; }; } // namespace Rosen } // namespace OHOS diff --git a/wm/include/window_proxy.h b/wm/include/window_proxy.h index 85278dad..222562e5 100644 --- a/wm/include/window_proxy.h +++ b/wm/include/window_proxy.h @@ -28,13 +28,13 @@ public: ~WindowProxy() {}; - void UpdateWindowProperty(const WindowProperty& windowProperty) override; void UpdateWindowRect(const struct Rect& rect, WindowSizeChangeReason reason) override; void UpdateWindowMode(WindowMode mode) override; void UpdateFocusStatus(bool focused) override; void UpdateAvoidArea(const std::vector& avoidAreas) override; void UpdateWindowState(WindowState state) override; void UpdateWindowDragInfo(const PointInfo& point, DragEvent event) override; + void UpdateDisplayId(DisplayId from, DisplayId to) override; private: static inline BrokerDelegator delegator_; }; diff --git a/wm/include/zidl/window_manager_agent_interface.h b/wm/include/zidl/window_manager_agent_interface.h index 57746aea..2c1daff8 100644 --- a/wm/include/zidl/window_manager_agent_interface.h +++ b/wm/include/zidl/window_manager_agent_interface.h @@ -26,6 +26,7 @@ enum class WindowManagerAgentType : uint32_t { WINDOW_MANAGER_AGENT_TYPE_FOCUS, WINDOW_MANAGER_AGENT_TYPE_SYSTEM_BAR, WINDOW_MANAGER_AGENT_TYPE_WINDOW_UPDATE, + WINDOW_MANAGER_AGENT_TYPE_WINDOW_VISIBILITY, }; class IWindowManagerAgent : public IRemoteBroker { @@ -36,12 +37,14 @@ public: TRANS_ID_UPDATE_FOCUS_STATUS = 1, TRANS_ID_UPDATE_SYSTEM_BAR_PROPS, TRANS_ID_UPDATE_WINDOW_STATUS, + TRANS_ID_UPDATE_WINDOW_VISIBILITY, }; virtual void UpdateFocusStatus(uint32_t windowId, const sptr& abilityToken, WindowType windowType, DisplayId displayId, bool focused) = 0; virtual void UpdateSystemBarRegionTints(DisplayId displayId, const SystemBarRegionTints& tints) = 0; virtual void UpdateWindowStatus(const sptr& windowInfo, WindowUpdateType type) = 0; + virtual void UpdateWindowVisibilityInfo(const std::vector>& visibilityInfos) = 0; }; } // namespace Rosen } // namespace OHOS diff --git a/wm/include/zidl/window_manager_agent_proxy.h b/wm/include/zidl/window_manager_agent_proxy.h index 7531213d..fd1b114d 100644 --- a/wm/include/zidl/window_manager_agent_proxy.h +++ b/wm/include/zidl/window_manager_agent_proxy.h @@ -31,6 +31,7 @@ public: DisplayId displayId, bool focused) override; void UpdateSystemBarRegionTints(DisplayId displayId, const SystemBarRegionTints& tints) override; void UpdateWindowStatus(const sptr& windowInfo, WindowUpdateType type) override; + void UpdateWindowVisibilityInfo(const std::vector>& visibilityInfos) override; private: static inline BrokerDelegator delegator_; diff --git a/wm/src/input_transfer_station.cpp b/wm/src/input_transfer_station.cpp index 947eb949..f9d9e5c7 100644 --- a/wm/src/input_transfer_station.cpp +++ b/wm/src/input_transfer_station.cpp @@ -56,7 +56,7 @@ void InputEventListener::OnInputEvent(std::shared_ptr pointer WLOGE("OnInputEvent receive pointerEvent is nullptr"); return; } - uint32_t windowId = pointerEvent->GetAgentWindowId(); + uint32_t windowId = static_cast(pointerEvent->GetAgentWindowId()); auto channel = InputTransferStation::GetInstance().GetInputChannel(windowId); if (channel == nullptr) { WLOGE("OnInputEvent channel is nullptr"); diff --git a/wm/src/vsync_station.cpp b/wm/src/vsync_station.cpp index 832d6172..a28b9378 100644 --- a/wm/src/vsync_station.cpp +++ b/wm/src/vsync_station.cpp @@ -14,6 +14,7 @@ */ #include +#include "transaction/rs_interfaces.h" #include "window_manager_hilog.h" @@ -33,21 +34,24 @@ void VsyncStation::RequestVsync(CallbackType type, std::shared_ptrsecond.insert(vsyncCallback); + if (mainHandler_ == nullptr) { auto runner = AppExecFwk::EventRunner::Create(VSYNC_THREAD_ID); mainHandler_ = std::make_shared(runner); + + auto& rsClient = OHOS::Rosen::RSInterfaces::GetInstance(); + while (receiver_ == nullptr) { + receiver_ = rsClient.CreateVSyncReceiver("WM_" + std::to_string(::getpid()), mainHandler_); + } + receiver_->Init(); } - if (!hasRequestedVsync_) { - mainHandler_->PostTask([this]() { - callback_.timestamp_ = 0; - callback_.userdata_ = this; - callback_.callback_ = OnVsync; - WLOGFI("request vsync start."); - VsyncError ret = VsyncHelper::Current()->RequestFrameCallback(callback_); - if (ret != VSYNC_ERROR_OK) { - WLOGFE("VsyncStation::RequestNextVsync fail: %{public}s", VsyncErrorStr(ret).c_str()); - } - }); + + if (!hasRequestedVsync_.load()) { + OHOS::Rosen::VSyncReceiver::FrameCallback fcb = { + .userData_ = this, + .callback_ = OnVsync, + }; + receiver_->RequestNextVSync(fcb); hasRequestedVsync_.store(true); } } diff --git a/wm/src/window_adapter.cpp b/wm/src/window_adapter.cpp index c0155b50..f1b33251 100644 --- a/wm/src/window_adapter.cpp +++ b/wm/src/window_adapter.cpp @@ -28,9 +28,7 @@ WM_IMPLEMENT_SINGLE_INSTANCE(WindowAdapter) WMError WindowAdapter::SaveAbilityToken(const sptr& abilityToken, uint32_t windowId) { - std::lock_guard lock(mutex_); - - if (!InitWMSProxyLocked()) { + if (!InitWMSProxy()) { return WMError::WM_ERROR_SAMGR; } return windowManagerServiceProxy_->SaveAbilityToken(abilityToken, windowId); @@ -39,9 +37,7 @@ WMError WindowAdapter::SaveAbilityToken(const sptr& abilityToken, WMError WindowAdapter::CreateWindow(sptr& window, sptr& windowProperty, std::shared_ptr surfaceNode, uint32_t& windowId) { - std::lock_guard lock(mutex_); - - if (!InitWMSProxyLocked()) { + if (!InitWMSProxy()) { return WMError::WM_ERROR_SAMGR; } return windowManagerServiceProxy_->CreateWindow(window, windowProperty, surfaceNode, windowId); @@ -49,9 +45,7 @@ WMError WindowAdapter::CreateWindow(sptr& window, sptr& WMError WindowAdapter::AddWindow(sptr& windowProperty) { - std::lock_guard lock(mutex_); - - if (!InitWMSProxyLocked()) { + if (!InitWMSProxy()) { return WMError::WM_ERROR_SAMGR; } return windowManagerServiceProxy_->AddWindow(windowProperty); @@ -59,9 +53,7 @@ WMError WindowAdapter::AddWindow(sptr& windowProperty) WMError WindowAdapter::RemoveWindow(uint32_t windowId) { - std::lock_guard lock(mutex_); - - if (!InitWMSProxyLocked()) { + if (!InitWMSProxy()) { return WMError::WM_ERROR_SAMGR; } return windowManagerServiceProxy_->RemoveWindow(windowId); @@ -69,9 +61,7 @@ WMError WindowAdapter::RemoveWindow(uint32_t windowId) WMError WindowAdapter::DestroyWindow(uint32_t windowId) { - std::lock_guard lock(mutex_); - - if (!InitWMSProxyLocked()) { + if (!InitWMSProxy()) { return WMError::WM_ERROR_SAMGR; } return windowManagerServiceProxy_->DestroyWindow(windowId); @@ -79,9 +69,7 @@ WMError WindowAdapter::DestroyWindow(uint32_t windowId) WMError WindowAdapter::ResizeRect(uint32_t windowId, const Rect& rect, WindowSizeChangeReason reason) { - std::lock_guard lock(mutex_); - - if (!InitWMSProxyLocked()) { + if (!InitWMSProxy()) { return WMError::WM_ERROR_SAMGR; } return windowManagerServiceProxy_->ResizeRect(windowId, rect, reason); @@ -89,9 +77,7 @@ WMError WindowAdapter::ResizeRect(uint32_t windowId, const Rect& rect, WindowSiz WMError WindowAdapter::RequestFocus(uint32_t windowId) { - std::lock_guard lock(mutex_); - - if (!InitWMSProxyLocked()) { + if (!InitWMSProxy()) { return WMError::WM_ERROR_SAMGR; } return windowManagerServiceProxy_->RequestFocus(windowId); @@ -99,9 +85,7 @@ WMError WindowAdapter::RequestFocus(uint32_t windowId) WMError WindowAdapter::SetWindowFlags(uint32_t windowId, uint32_t flags) { - std::lock_guard lock(mutex_); - - if (!InitWMSProxyLocked()) { + if (!InitWMSProxy()) { return WMError::WM_ERROR_SAMGR; } return windowManagerServiceProxy_->SetWindowFlags(windowId, flags); @@ -109,9 +93,7 @@ WMError WindowAdapter::SetWindowFlags(uint32_t windowId, uint32_t flags) WMError WindowAdapter::SetSystemBarProperty(uint32_t windowId, WindowType type, const SystemBarProperty& property) { - std::lock_guard lock(mutex_); - - if (!InitWMSProxyLocked()) { + if (!InitWMSProxy()) { return WMError::WM_ERROR_SAMGR; } return windowManagerServiceProxy_->SetSystemBarProperty(windowId, type, property); @@ -120,9 +102,7 @@ WMError WindowAdapter::SetSystemBarProperty(uint32_t windowId, WindowType type, void WindowAdapter::RegisterWindowManagerAgent(WindowManagerAgentType type, const sptr& windowManagerAgent) { - std::lock_guard lock(mutex_); - - if (!InitWMSProxyLocked()) { + if (!InitWMSProxy()) { return; } return windowManagerServiceProxy_->RegisterWindowManagerAgent(type, windowManagerAgent); @@ -131,9 +111,7 @@ void WindowAdapter::RegisterWindowManagerAgent(WindowManagerAgentType type, void WindowAdapter::UnregisterWindowManagerAgent(WindowManagerAgentType type, const sptr& windowManagerAgent) { - std::lock_guard lock(mutex_); - - if (!InitWMSProxyLocked()) { + if (!InitWMSProxy()) { return; } return windowManagerServiceProxy_->UnregisterWindowManagerAgent(type, windowManagerAgent); @@ -141,9 +119,7 @@ void WindowAdapter::UnregisterWindowManagerAgent(WindowManagerAgentType type, WMError WindowAdapter::GetAvoidAreaByType(uint32_t windowId, AvoidAreaType type, std::vector& avoidRect) { - std::lock_guard lock(mutex_); - - if (!InitWMSProxyLocked()) { + if (!InitWMSProxy()) { return WMError::WM_ERROR_SAMGR; } avoidRect = windowManagerServiceProxy_->GetAvoidAreaByType(windowId, type); @@ -152,8 +128,7 @@ WMError WindowAdapter::GetAvoidAreaByType(uint32_t windowId, AvoidAreaType type, WMError WindowAdapter::SetWindowMode(uint32_t windowId, WindowMode mode) { - std::lock_guard lock(mutex_); - if (!InitWMSProxyLocked()) { + if (!InitWMSProxy()) { return WMError::WM_ERROR_SAMGR; } return windowManagerServiceProxy_->SetWindowMode(windowId, mode); @@ -161,8 +136,7 @@ WMError WindowAdapter::SetWindowMode(uint32_t windowId, WindowMode mode) WMError WindowAdapter::SetWindowBackgroundBlur(uint32_t windowId, WindowBlurLevel level) { - std::lock_guard lock(mutex_); - if (!InitWMSProxyLocked()) { + if (!InitWMSProxy()) { return WMError::WM_ERROR_SAMGR; } return windowManagerServiceProxy_->SetWindowBackgroundBlur(windowId, level); @@ -170,8 +144,7 @@ WMError WindowAdapter::SetWindowBackgroundBlur(uint32_t windowId, WindowBlurLeve WMError WindowAdapter::SetAlpha(uint32_t windowId, float alpha) { - std::lock_guard lock(mutex_); - if (!InitWMSProxyLocked()) { + if (!InitWMSProxy()) { return WMError::WM_ERROR_SAMGR; } return windowManagerServiceProxy_->SetAlpha(windowId, alpha); @@ -179,8 +152,7 @@ WMError WindowAdapter::SetAlpha(uint32_t windowId, float alpha) void WindowAdapter::ProcessWindowTouchedEvent(uint32_t windowId) { - std::lock_guard lock(mutex_); - if (!InitWMSProxyLocked()) { + if (!InitWMSProxy()) { return; } return windowManagerServiceProxy_->ProcessWindowTouchedEvent(windowId); @@ -188,44 +160,24 @@ void WindowAdapter::ProcessWindowTouchedEvent(uint32_t windowId) void WindowAdapter::MinimizeAllAppWindows(DisplayId displayId) { - std::lock_guard lock(mutex_); - if (!InitWMSProxyLocked()) { + if (!InitWMSProxy()) { return; } windowManagerServiceProxy_->MinimizeAllAppWindows(displayId); } -bool WindowAdapter::IsSupportWideGamut(uint32_t windowId) +WMError WindowAdapter::MaxmizeWindow(uint32_t windowId) { - std::lock_guard lock(mutex_); - if (!InitWMSProxyLocked()) { - return false; + if (!InitWMSProxy()) { + return WMError::WM_ERROR_SAMGR; } - return windowManagerServiceProxy_->IsSupportWideGamut(windowId); + return windowManagerServiceProxy_->MaxmizeWindow(windowId); } -void WindowAdapter::SetColorSpace(uint32_t windowId, ColorSpace colorSpace) +bool WindowAdapter::InitWMSProxy() { std::lock_guard lock(mutex_); - if (!InitWMSProxyLocked()) { - return; - } - return windowManagerServiceProxy_->SetColorSpace(windowId, colorSpace); -} - -ColorSpace WindowAdapter::GetColorSpace(uint32_t windowId) -{ - std::lock_guard lock(mutex_); - if (!InitWMSProxyLocked()) { - return ColorSpace::COLOR_SPACE_DEFAULT; - } - return windowManagerServiceProxy_->GetColorSpace(windowId); -} - - -bool WindowAdapter::InitWMSProxyLocked() -{ - if (!windowManagerServiceProxy_) { + if (!isProxyValid_) { sptr systemAbilityManager = SystemAbilityManagerClient::GetInstance().GetSystemAbilityManager(); if (!systemAbilityManager) { @@ -254,17 +206,18 @@ bool WindowAdapter::InitWMSProxyLocked() WLOGFE("Failed to add death recipient"); return false; } + isProxyValid_ = true; } return true; } void WindowAdapter::ClearWindowAdapter() { - std::lock_guard lock(mutex_); if ((windowManagerServiceProxy_ != nullptr) && (windowManagerServiceProxy_->AsObject() != nullptr)) { windowManagerServiceProxy_->AsObject()->RemoveDeathRecipient(wmsDeath_); } - windowManagerServiceProxy_ = nullptr; + std::lock_guard lock(mutex_); + isProxyValid_ = false; } void WMSDeathRecipient::OnRemoteDied(const wptr& wptrDeath) @@ -285,9 +238,7 @@ void WMSDeathRecipient::OnRemoteDied(const wptr& wptrDeath) WMError WindowAdapter::GetTopWindowId(uint32_t mainWinId, uint32_t& topWinId) { - std::lock_guard lock(mutex_); - - if (!InitWMSProxyLocked()) { + if (!InitWMSProxy()) { return WMError::WM_ERROR_SAMGR; } return windowManagerServiceProxy_->GetTopWindowId(mainWinId, topWinId); @@ -295,8 +246,7 @@ WMError WindowAdapter::GetTopWindowId(uint32_t mainWinId, uint32_t& topWinId) WMError WindowAdapter::SetWindowLayoutMode(DisplayId displayId, WindowLayoutMode mode) { - std::lock_guard lock(mutex_); - if (!InitWMSProxyLocked()) { + if (!InitWMSProxy()) { return WMError::WM_ERROR_SAMGR; } return windowManagerServiceProxy_->SetWindowLayoutMode(displayId, mode); diff --git a/wm/src/window_agent.cpp b/wm/src/window_agent.cpp index b5143c14..c0199e5c 100644 --- a/wm/src/window_agent.cpp +++ b/wm/src/window_agent.cpp @@ -28,10 +28,6 @@ WindowAgent::WindowAgent(sptr& windowImpl) window_ = windowImpl; } -void WindowAgent::UpdateWindowProperty(const WindowProperty& windowProperty) -{ -} - void WindowAgent::UpdateWindowRect(const struct Rect& rect, WindowSizeChangeReason reason) { if (window_ == nullptr) { @@ -77,13 +73,22 @@ void WindowAgent::UpdateWindowState(WindowState state) window_->UpdateWindowState(state); } -void WindowAgent::UpdateWindowDragInfo(const PointInfo& piont, DragEvent event) +void WindowAgent::UpdateWindowDragInfo(const PointInfo& point, DragEvent event) { if (window_ == nullptr) { - WLOGFE("window is nullptr"); + WLOGFE("window is null"); return; } - window_->UpdateDragEvent(piont, event); + window_->UpdateDragEvent(point, event); +} + +void WindowAgent::UpdateDisplayId(DisplayId from, DisplayId to) +{ + if (window_ == nullptr) { + WLOGFE("window is null"); + return; + } + window_->UpdateDisplayId(from, to); } } // namespace Rosen } // namespace OHOS diff --git a/wm/src/window_impl.cpp b/wm/src/window_impl.cpp index a41e2f75..2c1f9664 100644 --- a/wm/src/window_impl.cpp +++ b/wm/src/window_impl.cpp @@ -1,5 +1,5 @@ /* - * Copyright (c) 2021 Huawei Device Co., Ltd. + * Copyright (c) 2021-2022 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at @@ -16,7 +16,6 @@ #include "window_impl.h" #include -#include #include "display_manager.h" #include "singleton_container.h" @@ -34,6 +33,11 @@ namespace { constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WINDOW, "WindowImpl"}; } +const WindowImpl::ColorSpaceConvertMap WindowImpl::colorSpaceConvertMap[] = { + { ColorSpace::COLOR_SPACE_DEFAULT, COLOR_GAMUT_SRGB }, + { ColorSpace::COLOR_SPACE_WIDE_GAMUT, COLOR_GAMUT_DCI_P3 }, +}; + std::map>> WindowImpl::windowMap_; std::map>> WindowImpl::subWindowMap_; std::map>> WindowImpl::appFloatingWindowMap_; @@ -265,12 +269,16 @@ WMError WindowImpl::SetWindowMode(WindowMode mode) property_->SetWindowMode(mode); WMError ret = SingletonContainer::Get().SetWindowMode(property_->GetWindowId(), mode); if (ret == WMError::WM_OK) { - WLOGFD("notify window mode changed"); + WLOGFI("notify window mode changed"); for (auto& listener : windowChangeListeners_) { if (listener != nullptr) { listener->OnModeChange(mode); } } + if (uiContent_ != nullptr) { + uiContent_->UpdateWindowMode(mode); + WLOGFI("notify uiContent window mode change end"); + } } return ret; } @@ -357,6 +365,11 @@ WMError WindowImpl::SetUIContent(const std::string& contentInfo, return WMError::WM_OK; } +Ace::UIContent* WindowImpl::GetUIContent() const +{ + return uiContent_.get(); +} + std::string WindowImpl::GetContentInfo() { WLOGFI("GetContentInfo"); @@ -367,19 +380,41 @@ std::string WindowImpl::GetContentInfo() return uiContent_->GetContentInfo(); } +ColorSpace WindowImpl::GetColorSpaceFromSurfaceGamut(SurfaceColorGamut surfaceColorGamut) +{ + for (auto item: colorSpaceConvertMap) { + if (item.sufaceColorGamut == surfaceColorGamut) { + return item.colorSpace; + } + } + return ColorSpace::COLOR_SPACE_DEFAULT; +} + +SurfaceColorGamut WindowImpl::GetSurfaceGamutFromColorSpace(ColorSpace colorSpace) +{ + for (auto item: colorSpaceConvertMap) { + if (item.colorSpace == colorSpace) { + return item.sufaceColorGamut; + } + } + return SurfaceColorGamut::COLOR_GAMUT_SRGB; +} + bool WindowImpl::IsSupportWideGamut() { - return SingletonContainer::Get().IsSupportWideGamut(property_->GetWindowId()); + return true; } void WindowImpl::SetColorSpace(ColorSpace colorSpace) { - SingletonContainer::Get().SetColorSpace(property_->GetWindowId(), colorSpace); + auto surfaceGamut = GetSurfaceGamutFromColorSpace(colorSpace); + surfaceNode_->SetColorSpace(surfaceGamut); } ColorSpace WindowImpl::GetColorSpace() { - return SingletonContainer::Get().GetColorSpace(property_->GetWindowId()); + auto surfaceGamut = surfaceNode_->GetColorSpace(); + return GetColorSpaceFromSurfaceGamut(surfaceGamut); } void WindowImpl::DumpInfo(const std::vector& params, std::vector& info) @@ -556,8 +591,18 @@ WMError WindowImpl::Destroy() WLOGFI("[Client] Window %{public}d Destroy", property_->GetWindowId()); - // FixMe: Remove "NotifyBeforeDestroy()" because of ACE bug, add when fixed + NotifyBeforeDestroy(); + if (subWindowMap_.count(GetWindowId()) > 0) { + for (auto& subWindow : subWindowMap_.at(GetWindowId())) { + NotifyBeforeSubWindowDestroy(subWindow); + } + } + WMError ret = SingletonContainer::Get().DestroyWindow(property_->GetWindowId()); + if (ret != WMError::WM_OK) { + WLOGFE("destroy window failed with errCode:%{public}d", static_cast(ret)); + return ret; + } windowMap_.erase(GetWindowName()); if (subWindowMap_.count(property_->GetParentId()) > 0) { // remove from subWindowMap_ std::vector>& subWindows = subWindowMap_.at(property_->GetParentId()); @@ -573,6 +618,7 @@ WMError WindowImpl::Destroy() // Destroy app floating window if exist if (appFloatingWindowMap_.count(GetWindowId()) > 0) { for (auto& floatingWindow : appFloatingWindowMap_.at(GetWindowId())) { + NotifyBeforeSubWindowDestroy(floatingWindow); WMError fltRet = SingletonContainer::Get().DestroyWindow(floatingWindow->GetWindowId()); if (fltRet == WMError::WM_OK) { WLOGFI("Destroy App %{public}d FltWindow %{public}d", GetWindowId(), floatingWindow->GetWindowId()); @@ -594,18 +640,19 @@ WMError WindowImpl::Show() if (!IsWindowValid()) { return WMError::WM_ERROR_INVALID_WINDOW; } - if (state_ == WindowState::STATE_SHOWN && property_->GetWindowType() == WindowType::WINDOW_TYPE_WALLPAPER) { - WLOGFI("Minimize all app windows"); - SingletonContainer::Get().MinimizeAllAppWindows(property_->GetDisplayId()); - for (auto& listener : lifecycleListeners_) { - if (listener != nullptr) { - listener->AfterForeground(); - } - } - return WMError::WM_OK; - } if (state_ == WindowState::STATE_SHOWN) { - WLOGFI("window is already shown id: %{public}d", property_->GetWindowId()); + if (property_->GetWindowType() == WindowType::WINDOW_TYPE_DESKTOP) { + WLOGFI("desktop window [id:%{public}d] is shown, minimize all app windows", property_->GetWindowId()); + SingletonContainer::Get().MinimizeAllAppWindows(property_->GetDisplayId()); + for (auto& listener : lifecycleListeners_) { + if (listener != nullptr) { + listener->AfterForeground(); + } + } + } else { + WLOGFI("window is already shown id: %{public}d, raise to top", property_->GetWindowId()); + SingletonContainer::Get().ProcessWindowTouchedEvent(property_->GetWindowId()); + } return WMError::WM_OK; } SetDefaultOption(); @@ -697,9 +744,15 @@ WMError WindowImpl::Maximize() return WMError::WM_ERROR_INVALID_WINDOW; } if (WindowHelper::IsMainWindow(property_->GetWindowType())) { - SetFullScreen(true); + WMError ret = SingletonContainer::Get().MaxmizeWindow(property_->GetWindowId()); + if (ret == WMError::WM_OK) { + UpdateMode(WindowMode::WINDOW_MODE_FULLSCREEN); + } + return ret; + } else { + WLOGFI("Maximize Window failed. The window is not main window"); + return WMError::WM_ERROR_INVALID_PARAM; } - return WMError::WM_OK; } WMError WindowImpl::Minimize() @@ -844,6 +897,26 @@ void WindowImpl::UnregisterDragListener(sptr& listener) windowDragListeners_.erase(iter); } +void WindowImpl::RegisterDisplayMoveListener(sptr& listener) +{ + if (listener == nullptr) { + return; + } + std::lock_guard lock(mutex_); + displayMoveListeners_.emplace_back(listener); +} + +void WindowImpl::UnregisterDisplayMoveListener(sptr& listener) +{ + std::lock_guard lock(mutex_); + auto iter = std::find(displayMoveListeners_.begin(), displayMoveListeners_.end(), listener); + if (iter == displayMoveListeners_.end()) { + WLOGFE("could not find the listener"); + return; + } + displayMoveListeners_.erase(iter); +} + void WindowImpl::UpdateRect(const struct Rect& rect, WindowSizeChangeReason reason) { auto display = DisplayManager::GetInstance().GetDisplayById(property_->GetDisplayId()); @@ -865,6 +938,7 @@ void WindowImpl::UpdateRect(const struct Rect& rect, WindowSizeChangeReason reas if (uiContent_ != nullptr) { Ace::ViewportConfig config; config.SetSize(rect.width_, rect.height_); + config.SetPosition(rect.posX_, rect.posY_); config.SetDensity(virtualPixelRatio); uiContent_->UpdateViewportConfig(config, reason); WLOGFI("notify uiContent window size change end"); @@ -880,6 +954,11 @@ void WindowImpl::UpdateMode(WindowMode mode) listener->OnModeChange(mode); } } + + if (uiContent_ != nullptr) { + uiContent_->UpdateWindowMode(mode); + WLOGFI("notify uiContent window mode change end"); + } } void WindowImpl::ConsumeKeyEvent(std::shared_ptr& keyEvent) @@ -937,27 +1016,27 @@ void WindowImpl::HandleDragEvent(int32_t posX, int32_t posY, int32_t pointId) Rect newRect = startPointRect_; if (startPointPosX_ <= startPointRect_.posX_) { if (diffX > static_cast(startPointRect_.width_)) { - diffX = startPointRect_.width_; + diffX = static_cast(startPointRect_.width_); } - newRect.posX_ += diffX; - newRect.width_ -= diffX; - } else if (startPointPosX_ >= static_cast(startPointRect_.posX_ + startPointRect_.width_)) { + newRect.posX_ += diffX; + newRect.width_ = static_cast(static_cast(newRect.width_) - diffX); + } else if (startPointPosX_ >= startPointRect_.posX_ + static_cast(startPointRect_.width_)) { if (diffX < 0 && (-diffX > static_cast(startPointRect_.width_))) { - diffX = -startPointRect_.width_; + diffX = -(static_cast(startPointRect_.width_)); } - newRect.width_ += diffX; + newRect.width_ = static_cast(static_cast(newRect.width_) + diffX); } if (startPointPosY_ <= startPointRect_.posY_) { if (diffY > static_cast(startPointRect_.height_)) { - diffY = startPointRect_.height_; + diffY = static_cast(startPointRect_.height_); } - newRect.posY_ += diffY; - newRect.height_ -= diffY; - } else if (startPointPosY_ >= static_cast(startPointRect_.posY_ + startPointRect_.height_)) { + newRect.posY_ += diffY; + newRect.height_ = static_cast(static_cast(newRect.height_) - diffY); + } else if (startPointPosY_ >= startPointRect_.posY_ + static_cast(startPointRect_.height_)) { if (diffY < 0 && (-diffY > static_cast(startPointRect_.height_))) { - diffY = -startPointRect_.height_; + diffY = -(static_cast(startPointRect_.height_)); } - newRect.height_ += diffY; + newRect.height_ = static_cast(static_cast(newRect.height_) + diffY); } auto res = Drag(newRect); if (res != WMError::WM_OK) { @@ -1125,26 +1204,22 @@ void WindowImpl::UpdateWindowState(WindowState state) switch (state) { case WindowState::STATE_FROZEN: { state_ = WindowState::STATE_HIDDEN; - if (uiContent_ != nullptr) { - uiContent_->Background(); - } if (abilityContext_ != nullptr) { WLOGFD("DoAbilityBackground KEYGUARD, id: %{public}d", GetWindowId()); AAFwk::AbilityManagerClient::GetInstance()->DoAbilityBackground(abilityContext_->GetToken(), static_cast(WindowStateChangeReason::KEYGUARD)); } + NotifyAfterBackground(); break; } case WindowState::STATE_UNFROZEN: { state_ = WindowState::STATE_SHOWN; - if (uiContent_ != nullptr) { - uiContent_->Foreground(); - } if (abilityContext_ != nullptr) { WLOGFD("DoAbilityForeground KEYGUARD, id: %{public}d", GetWindowId()); AAFwk::AbilityManagerClient::GetInstance()->DoAbilityForeground(abilityContext_->GetToken(), static_cast(WindowStateChangeReason::KEYGUARD)); } + NotifyAfterForeground(); break; } default: { @@ -1162,6 +1237,16 @@ void WindowImpl::UpdateDragEvent(const PointInfo& point, DragEvent event) } } +void WindowImpl::UpdateDisplayId(DisplayId from, DisplayId to) +{ + WLOGFD("update displayId. win %{public}d", GetWindowId()); + for (auto& listener : displayMoveListeners_) { + if (listener != nullptr) { + listener->OnDisplayMove(from, to); + } + } +} + void WindowImpl::SetDefaultOption() { auto display = DisplayManager::GetInstance().GetDisplayById(property_->GetDisplayId()); @@ -1208,6 +1293,8 @@ void WindowImpl::SetDefaultOption() property_->SetWindowFlags(0); break; } + case WindowType::WINDOW_TYPE_TOAST: + case WindowType::WINDOW_TYPE_SEARCHING_BAR: case WindowType::WINDOW_TYPE_VOLUME_OVERLAY: { property_->SetWindowMode(WindowMode::WINDOW_MODE_FLOATING); property_->SetFocusable(false); @@ -1217,6 +1304,7 @@ void WindowImpl::SetDefaultOption() property_->SetWindowMode(WindowMode::WINDOW_MODE_FLOATING); break; } + case WindowType::WINDOW_TYPE_BOOT_ANIMATION: case WindowType::WINDOW_TYPE_POINTER: { property_->SetFocusable(false); break; diff --git a/wm/src/window_manager.cpp b/wm/src/window_manager.cpp index b2ab5c63..da13194c 100644 --- a/wm/src/window_manager.cpp +++ b/wm/src/window_manager.cpp @@ -14,6 +14,7 @@ */ #include "foundation/windowmanager/interfaces/innerkits/wm/window_manager.h" + #include #include @@ -28,6 +29,24 @@ namespace { constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WINDOW, "WindowManager"}; } +bool WindowVisibilityInfo::Marshalling(Parcel &parcel) const +{ + return parcel.WriteUint32(windowId_) && parcel.WriteInt32(pid_) && + parcel.WriteInt32(uid_) && parcel.WriteBool(isVisible_); +} + +WindowVisibilityInfo* WindowVisibilityInfo::Unmarshalling(Parcel &parcel) +{ + WindowVisibilityInfo* windowVisibilityInfo = new WindowVisibilityInfo(); + bool res = parcel.ReadUint32(windowVisibilityInfo->windowId_) && parcel.ReadInt32(windowVisibilityInfo->pid_) && + parcel.ReadInt32(windowVisibilityInfo->uid_) && parcel.ReadBool(windowVisibilityInfo->isVisible_); + if (!res) { + delete windowVisibilityInfo; + return nullptr; + } + return windowVisibilityInfo; +} + bool WindowInfo::Marshalling(Parcel &parcel) const { return parcel.WriteInt32(wid_) && parcel.WriteUint32(windowRect_.width_) && @@ -39,13 +58,11 @@ bool WindowInfo::Marshalling(Parcel &parcel) const WindowInfo* WindowInfo::Unmarshalling(Parcel &parcel) { WindowInfo* windowInfo = new WindowInfo(); - if (windowInfo == nullptr) { - return nullptr; - } bool res = parcel.ReadInt32(windowInfo->wid_) && parcel.ReadUint32(windowInfo->windowRect_.width_) && parcel.ReadUint32(windowInfo->windowRect_.height_) && parcel.ReadInt32(windowInfo->windowRect_.posX_) && parcel.ReadInt32(windowInfo->windowRect_.posY_) && parcel.ReadBool(windowInfo->focused_); if (!res) { + delete windowInfo; return nullptr; } windowInfo->mode_ = static_cast(parcel.ReadUint32()); @@ -63,6 +80,7 @@ public: WindowType windowType, DisplayId displayId) const; void NotifySystemBarChanged(DisplayId displayId, const SystemBarRegionTints& tints) const; void NotifyWindowUpdate(const sptr& windowInfo, WindowUpdateType type) const; + void NotifyWindowVisibilityInfoChanged(const std::vector>& windowVisibilityInfos) const; static inline SingletonDelegator delegator_; std::recursive_mutex mutex_; @@ -72,6 +90,8 @@ public: sptr systemBarChangedListenerAgent_; std::vector> windowUpdateListeners_; sptr windowUpdateListenerAgent_; + std::vector> windowVisibilityListeners_; + sptr windowVisibilityListenerAgent_; }; void WindowManager::Impl::NotifyFocused(uint32_t windowId, const sptr& abilityToken, @@ -121,6 +141,14 @@ void WindowManager::Impl::NotifyWindowUpdate(const sptr& windowInfo, } } +void WindowManager::Impl::NotifyWindowVisibilityInfoChanged( + const std::vector>& windowVisibilityInfos) const +{ + for (auto& listener : windowVisibilityListeners_) { + listener->OnWindowVisibilityChanged(windowVisibilityInfos); + } +} + WindowManager::WindowManager() : pImpl_(std::make_unique()) { } @@ -210,14 +238,14 @@ void WindowManager::MinimizeAllAppWindows(DisplayId displayId) SingletonContainer::Get().MinimizeAllAppWindows(displayId); } -void WindowManager::SetWindowLayoutMode(WindowLayoutMode mode, DisplayId displayId) +WMError WindowManager::SetWindowLayoutMode(WindowLayoutMode mode, DisplayId displayId) { WLOGFI("set window layout mode: %{public}d, displayId %{public}" PRIu64"", mode, displayId); WMError ret = SingletonContainer::Get().SetWindowLayoutMode(displayId, mode); if (ret != WMError::WM_OK) { WLOGFE("set layout mode failed"); } - return; + return ret; } void WindowManager::RegisterWindowUpdateListener(const sptr &listener) @@ -256,6 +284,41 @@ void WindowManager::UnregisterWindowUpdateListener(const sptr& listener) +{ + if (listener == nullptr) { + WLOGFE("listener could not be null"); + return; + } + std::lock_guard lock(pImpl_->mutex_); + pImpl_->windowVisibilityListeners_.emplace_back(listener); + if (pImpl_->windowVisibilityListenerAgent_ == nullptr) { + pImpl_->windowVisibilityListenerAgent_ = new WindowManagerAgent(); + SingletonContainer::Get().RegisterWindowManagerAgent( + WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WINDOW_VISIBILITY, + pImpl_->windowVisibilityListenerAgent_); + } +} + +void WindowManager::UnregisterVisibilityChangedListener(const sptr& listener) +{ + if (listener == nullptr) { + return; + } + std::lock_guard lock(pImpl_->mutex_); + pImpl_->windowVisibilityListeners_.erase(std::remove_if(pImpl_->windowVisibilityListeners_.begin(), + pImpl_->windowVisibilityListeners_.end(), [listener](sptr registeredListener) { + return registeredListener == listener; + }), pImpl_->windowVisibilityListeners_.end()); + + if (pImpl_->windowVisibilityListeners_.empty() && pImpl_->windowVisibilityListenerAgent_ != nullptr) { + SingletonContainer::Get().UnregisterWindowManagerAgent( + WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WINDOW_VISIBILITY, + pImpl_->windowVisibilityListenerAgent_); + pImpl_->windowVisibilityListenerAgent_ = nullptr; + } +} + void WindowManager::UpdateFocusStatus(uint32_t windowId, const sptr& abilityToken, WindowType windowType, DisplayId displayId, bool focused) const { @@ -277,5 +340,11 @@ void WindowManager::UpdateWindowStatus(const sptr& windowInfo, Windo { pImpl_->NotifyWindowUpdate(windowInfo, type); } + +void WindowManager::UpdateWindowVisibilityInfo( + const std::vector>& windowVisibilityInfos) const +{ + pImpl_->NotifyWindowVisibilityInfoChanged(windowVisibilityInfos); +} } // namespace Rosen -} // namespace OHOS \ No newline at end of file +} // namespace OHOS diff --git a/wm/src/window_manager_agent.cpp b/wm/src/window_manager_agent.cpp index b501c181..d3e7e7c6 100644 --- a/wm/src/window_manager_agent.cpp +++ b/wm/src/window_manager_agent.cpp @@ -35,5 +35,10 @@ void WindowManagerAgent::UpdateWindowStatus(const sptr& windowInfo, { SingletonContainer::Get().UpdateWindowStatus(windowInfo, type); } + +void WindowManagerAgent::UpdateWindowVisibilityInfo(const std::vector>& visibilityInfos) +{ + SingletonContainer::Get().UpdateWindowVisibilityInfo(visibilityInfos); +} } // namespace Rosen } // namespace OHOS diff --git a/wm/src/window_proxy.cpp b/wm/src/window_proxy.cpp index 34fbc8d6..149a3efb 100644 --- a/wm/src/window_proxy.cpp +++ b/wm/src/window_proxy.cpp @@ -25,20 +25,11 @@ namespace { constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WINDOW, "WindowProxy"}; } -void WindowProxy::UpdateWindowProperty(const WindowProperty& windowProperty) -{ - sptr remote = Remote(); - if (remote == nullptr) { - WLOGFW("remote is nullptr"); - return; - } -} - void WindowProxy::UpdateWindowRect(const struct Rect& rect, WindowSizeChangeReason reason) { MessageParcel data; MessageParcel reply; - MessageOption option; + MessageOption option(MessageOption::TF_ASYNC); if (!data.WriteInterfaceToken(GetDescriptor())) { WLOGFE("WriteInterfaceToken failed"); return; @@ -64,7 +55,7 @@ void WindowProxy::UpdateWindowMode(WindowMode mode) { MessageParcel data; MessageParcel reply; - MessageOption option; + MessageOption option(MessageOption::TF_ASYNC); if (!data.WriteInterfaceToken(GetDescriptor())) { WLOGFE("WriteInterfaceToken failed"); return; @@ -84,7 +75,7 @@ void WindowProxy::UpdateFocusStatus(bool focused) { MessageParcel data; MessageParcel reply; - MessageOption option; + MessageOption option(MessageOption::TF_ASYNC); if (!data.WriteInterfaceToken(GetDescriptor())) { WLOGFE("WriteInterfaceToken failed"); return; @@ -105,7 +96,7 @@ void WindowProxy::UpdateAvoidArea(const std::vector& avoidArea) { MessageParcel data; MessageParcel reply; - MessageOption option; + MessageOption option(MessageOption::TF_ASYNC); if (!data.WriteInterfaceToken(GetDescriptor())) { WLOGFE("WriteInterfaceToken failed"); return; @@ -135,7 +126,7 @@ void WindowProxy::UpdateWindowState(WindowState state) { MessageParcel data; MessageParcel reply; - MessageOption option; + MessageOption option(MessageOption::TF_ASYNC); if (!data.WriteInterfaceToken(GetDescriptor())) { WLOGFE("WriteInterfaceToken failed"); return; @@ -172,6 +163,24 @@ void WindowProxy::UpdateWindowDragInfo(const PointInfo& point, DragEvent event) WLOGFE("SendRequest TRANS_ID_UPDATE_DRAG_EVENT failed"); } } + +void WindowProxy::UpdateDisplayId(DisplayId from, DisplayId to) +{ + MessageParcel data; + MessageParcel reply; + MessageOption option(MessageOption::TF_ASYNC); + if (!data.WriteInterfaceToken(GetDescriptor())) { + WLOGFE("WriteInterfaceToken failed"); + return; + } + if (!(data.WriteUint64(from) and data.WriteUint64(to))) { + WLOGFE("Write displayid failed"); + return; + } + if (Remote()->SendRequest(TRANS_ID_UPDATE_DISPLAY_ID, data, reply, option) != ERR_NONE) { + WLOGFE("SendRequest TRANS_ID_UPDATE_DISPLAY_ID failed"); + } +} } // namespace Rosen } // namespace OHOS diff --git a/wm/src/window_stub.cpp b/wm/src/window_stub.cpp index f0ffda5c..10dff0c9 100644 --- a/wm/src/window_stub.cpp +++ b/wm/src/window_stub.cpp @@ -32,9 +32,6 @@ int WindowStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParce return -1; } switch (code) { - case TRANS_ID_UPDATE_WINDOW_PROPERTY: { - break; - } case TRANS_ID_UPDATE_WINDOW_RECT: { struct Rect rect { data.ReadInt32(), data.ReadInt32(), data.ReadUint32(), data.ReadUint32() }; WindowSizeChangeReason reason = static_cast(data.ReadUint32()); @@ -73,6 +70,10 @@ int WindowStub::OnRemoteRequest(uint32_t code, MessageParcel &data, MessageParce UpdateWindowDragInfo(point, event); break; } + case TRANS_ID_UPDATE_DISPLAY_ID: { + UpdateDisplayId(data.ReadUint64(), data.ReadUint64()); + break; + } default: break; } diff --git a/wm/src/zidl/window_manager_agent_proxy.cpp b/wm/src/zidl/window_manager_agent_proxy.cpp index 80da77d8..b3ebe956 100644 --- a/wm/src/zidl/window_manager_agent_proxy.cpp +++ b/wm/src/zidl/window_manager_agent_proxy.cpp @@ -131,6 +131,32 @@ void WindowManagerAgentProxy::UpdateWindowStatus(const sptr& windowI WLOGFE("SendRequest failed"); } } + +void WindowManagerAgentProxy::UpdateWindowVisibilityInfo( + const std::vector>& visibilityInfos) +{ + MessageParcel data; + MessageParcel reply; + MessageOption option(MessageOption::TF_ASYNC); + if (!data.WriteInterfaceToken(GetDescriptor())) { + WLOGFE("WriteInterfaceToken failed"); + return; + } + if (!data.WriteUint32(static_cast(visibilityInfos.size()))) { + WLOGFE("write windowVisibilityInfos size failed"); + return; + } + for (auto& info : visibilityInfos) { + if (!data.WriteParcelable(info)) { + WLOGFE("Write windowVisibilityInfo failed"); + return; + } + } + + if (Remote()->SendRequest(TRANS_ID_UPDATE_WINDOW_VISIBILITY, data, reply, option) != ERR_NONE) { + WLOGFE("SendRequest failed"); + } +} } // namespace Rosen } // namespace OHOS diff --git a/wm/src/zidl/window_manager_agent_stub.cpp b/wm/src/zidl/window_manager_agent_stub.cpp index 0a1fd55b..83e10486 100644 --- a/wm/src/zidl/window_manager_agent_stub.cpp +++ b/wm/src/zidl/window_manager_agent_stub.cpp @@ -62,6 +62,16 @@ int WindowManagerAgentStub::OnRemoteRequest(uint32_t code, MessageParcel& data, UpdateWindowStatus(windowInfo, type); break; } + case TRANS_ID_UPDATE_WINDOW_VISIBILITY: { + uint32_t size = data.ReadUint32(); + std::vector> windowVisibilityInfos; + for (uint32_t i = 0; i < size; ++i) { + sptr info = data.ReadParcelable(); + windowVisibilityInfos.emplace_back(info); + } + UpdateWindowVisibilityInfo(windowVisibilityInfos); + break; + } default: break; } diff --git a/wm/test/systemtest/BUILD.gn b/wm/test/systemtest/BUILD.gn index b5b193f7..4aa3d3a2 100644 --- a/wm/test/systemtest/BUILD.gn +++ b/wm/test/systemtest/BUILD.gn @@ -30,6 +30,7 @@ group("systemtest") { ":wm_window_split_immersive_test", ":wm_window_split_test", ":wm_window_subwindow_test", + ":wm_window_visibility_info_test", ] } @@ -154,6 +155,17 @@ ohos_systemtest("wm_window_gamut_test") { ## SystemTest window_gamut_test }}} +## SystemTest wm_window_visibility_info_test {{{ +ohos_systemtest("wm_window_visibility_info_test") { + module_out_path = module_out_path + + sources = [ "window_visibility_info_test.cpp" ] + + deps = [ ":wm_systemtest_common" ] +} + +## SystemTest wm_window_visibility_info_test }}} + ## Build wm_systemtest_common.a {{{ config("wm_systemtest_common_public_config") { include_dirs = [ diff --git a/wm/test/systemtest/window_gamut_test.cpp b/wm/test/systemtest/window_gamut_test.cpp index 2d94f4d9..27d88bce 100644 --- a/wm/test/systemtest/window_gamut_test.cpp +++ b/wm/test/systemtest/window_gamut_test.cpp @@ -22,6 +22,9 @@ using namespace testing::ext; namespace OHOS { namespace Rosen { using utils = WindowTestUtils; +constexpr uint32_t MAX_WAIT_COUNT = 100; +constexpr uint32_t WAIT_DUR = 10 * 1000; + class WindowGamutTest : public testing::Test { public: static void SetUpTestCase(); @@ -73,20 +76,76 @@ HWTEST_F(WindowGamutTest, IsSupportWideGamut01, Function | MediumTest | Level3) } /** - * @tc.name: SetGetColorSpace01 - * @tc.desc: Set and Get ColorSpace + * @tc.name: GetColorSpace01 + * @tc.desc: Get ColorSpace * @tc.type: FUNC * @tc.require: */ -HWTEST_F(WindowGamutTest, SetGetColorSpace01, Function | MediumTest | Level3) +HWTEST_F(WindowGamutTest, GetColorSpace01, Function | MediumTest | Level3) { const sptr& window = utils::CreateTestWindow(fullScreenAppInfo_); - window->SetColorSpace(ColorSpace::COLOR_SPACE_DEFAULT); ASSERT_EQ(ColorSpace::COLOR_SPACE_DEFAULT, window->GetColorSpace()); window->Destroy(); } + +/** + * @tc.name: SetColorSpace01 + * @tc.desc: Set ColorSpace, valid param + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(WindowGamutTest, SetColorSpace01, Function | MediumTest | Level3) +{ + uint32_t i, j; + const ColorSpace colorSpacesToTest[] = { + ColorSpace::COLOR_SPACE_DEFAULT, + ColorSpace::COLOR_SPACE_WIDE_GAMUT + }; + ColorSpace colorSpace; + const sptr& window = utils::CreateTestWindow(fullScreenAppInfo_); + + ColorSpace colorSpaceBackup = window->GetColorSpace(); // backup origin + + for (j = 0; j < sizeof(colorSpacesToTest) / sizeof(ColorSpace); j++) { + window->SetColorSpace(colorSpacesToTest[j]); // async func + for (i = 0; i < MAX_WAIT_COUNT; i++) { // wait some time for async set ok + colorSpace = window->GetColorSpace(); + if (colorSpace != colorSpacesToTest[j]) { + usleep(WAIT_DUR); + } else { + break; + } + } + ASSERT_EQ(colorSpacesToTest[j], window->GetColorSpace()); + } + + window->SetColorSpace(colorSpaceBackup); // restore + + window->Destroy(); +} + +/** + * @tc.name: SetColorSpace02 + * @tc.desc: Set ColorSpace, invalid param + * @tc.type: FUNC + * @tc.require: + */ +HWTEST_F(WindowGamutTest, SetColorSpace02, Function | MediumTest | Level3) +{ + const sptr& window = utils::CreateTestWindow(fullScreenAppInfo_); + + ColorSpace colorSpaceBackup = window->GetColorSpace(); + + ColorSpace invalidColorSpace = + static_cast(static_cast(ColorSpace::COLOR_SPACE_WIDE_GAMUT) + 1); + window->SetColorSpace(invalidColorSpace); // invalid param + + ASSERT_EQ(colorSpaceBackup, window->GetColorSpace()); + + window->Destroy(); +} } // namespace } // namespace Rosen } // namespace OHOS diff --git a/wm/test/systemtest/window_immersive_test.cpp b/wm/test/systemtest/window_immersive_test.cpp index cd69ec50..fad36989 100644 --- a/wm/test/systemtest/window_immersive_test.cpp +++ b/wm/test/systemtest/window_immersive_test.cpp @@ -332,6 +332,27 @@ HWTEST_F(WindowImmersiveTest, ImmersiveTest05, Function | MediumTest | Level3) ASSERT_TRUE(SystemBarPropsEqualsTo(TEST_PROPS_DEFAULT)); } +/** + * @tc.name: ImmersiveNegativeTest01 + * @tc.desc: set systembar props with wrong window type + * @tc.type: FUNC + * @tc.require: AR000GGTVD + */ +HWTEST_F(WindowImmersiveTest, ImmersiveNegativeTest01, Function | MediumTest | Level3) +{ + const SystemBarRegionTints TEST_PROPS_NEGATIVE = { + { WindowType::WINDOW_TYPE_KEYGUARD, SYS_BAR_PROP_1, SYS_BAR_REGION_NULL }, + { WindowType::WINDOW_TYPE_POINTER, SYS_BAR_PROP_2, SYS_BAR_REGION_NULL }, + }; + const sptr& window = utils::CreateTestWindow(fullScreenAppinfo_); + activeWindows_.push_back(window); + SetWindowSystemProps(window, TEST_PROPS_NEGATIVE); + ASSERT_EQ(WMError::WM_OK, window->Show()); + ASSERT_TRUE(SystemBarPropsEqualsTo(TEST_PROPS_DEFAULT)); + ASSERT_EQ(WMError::WM_OK, window->Hide()); + ASSERT_TRUE(SystemBarPropsEqualsTo(TEST_PROPS_DEFAULT)); +} + /** * @tc.name: GetAvoidAreaByTypeTest01 * @tc.desc: Test GetAvoidArea use unsupport Type(TYPE_CUTOUT). diff --git a/wm/test/systemtest/window_layout_test.cpp b/wm/test/systemtest/window_layout_test.cpp index 9b5b381e..a27e2f93 100644 --- a/wm/test/systemtest/window_layout_test.cpp +++ b/wm/test/systemtest/window_layout_test.cpp @@ -32,6 +32,7 @@ public: DisplayId displayId_ = 0; std::vector> activeWindows_; static vector fullScreenExpecteds_; + static inline float virtualPixelRatio_ = 0.0; }; vector WindowLayoutTest::fullScreenExpecteds_; @@ -47,6 +48,9 @@ void WindowLayoutTest::SetUpTestCase() } Rect displayRect = {0, 0, display->GetWidth(), display->GetHeight()}; utils::InitByDisplayRect(displayRect); + + virtualPixelRatio_ = WindowTestUtils::GetVirtualPixelRatio(0); + // calc expected rects Rect expected = { // 0. only statusBar 0, @@ -110,7 +114,7 @@ HWTEST_F(WindowLayoutTest, LayoutWindow02, Function | MediumTest | Level3) activeWindows_.push_back(window); ASSERT_EQ(WMError::WM_OK, window->Show()); - ASSERT_TRUE(utils::RectEqualTo(window, utils::GetFloatingLimitedRect(utils::customAppRect_))); + ASSERT_TRUE(utils::RectEqualTo(window, utils::GetFloatingLimitedRect(utils::customAppRect_, virtualPixelRatio_))); ASSERT_EQ(WMError::WM_OK, window->Hide()); } @@ -140,12 +144,12 @@ HWTEST_F(WindowLayoutTest, LayoutWindow04, Function | MediumTest | Level3) activeWindows_.push_back(statBar); ASSERT_EQ(WMError::WM_OK, appWin->Show()); - ASSERT_TRUE(utils::RectEqualTo(appWin, utils::GetFloatingLimitedRect(utils::customAppRect_))); + ASSERT_TRUE(utils::RectEqualTo(appWin, utils::GetFloatingLimitedRect(utils::customAppRect_, virtualPixelRatio_))); ASSERT_EQ(WMError::WM_OK, statBar->Show()); - ASSERT_TRUE(utils::RectEqualTo(appWin, utils::GetFloatingLimitedRect(utils::customAppRect_))); + ASSERT_TRUE(utils::RectEqualTo(appWin, utils::GetFloatingLimitedRect(utils::customAppRect_, virtualPixelRatio_))); ASSERT_TRUE(utils::RectEqualTo(statBar, utils::statusBarRect_)); ASSERT_EQ(WMError::WM_OK, statBar->Hide()); - ASSERT_TRUE(utils::RectEqualTo(appWin, utils::GetFloatingLimitedRect(utils::customAppRect_))); + ASSERT_TRUE(utils::RectEqualTo(appWin, utils::GetFloatingLimitedRect(utils::customAppRect_, virtualPixelRatio_))); } /** @@ -277,7 +281,7 @@ HWTEST_F(WindowLayoutTest, LayoutWindow09, Function | MediumTest | Level3) ASSERT_EQ(WMError::WM_OK, window->Resize(2u, 2u)); // 2: custom min size Rect finalExcept = { expect.posX_, expect.posY_, 2u, 2u}; // 2: custom min size - finalExcept = utils::GetFloatingLimitedRect(finalExcept); + finalExcept = utils::GetFloatingLimitedRect(finalExcept, virtualPixelRatio_); ASSERT_TRUE(utils::RectEqualTo(window, finalExcept)); ASSERT_EQ(WMError::WM_OK, window->Hide()); } @@ -350,6 +354,7 @@ HWTEST_F(WindowLayoutTest, LayoutTile01, Function | MediumTest | Level3) if (utils::isVerticalDisplay_) { ASSERT_TRUE(utils::RectEqualTo(test1, utils::doubleTileRects_[0])); ASSERT_TRUE(utils::RectEqualTo(test2, utils::doubleTileRects_[1])); + WindowManager::GetInstance().SetWindowLayoutMode(WindowLayoutMode::CASCADE, displayId_); return; } else { ASSERT_TRUE(utils::RectEqualTo(window, utils::tripleTileRects_[0])); @@ -363,6 +368,120 @@ HWTEST_F(WindowLayoutTest, LayoutTile01, Function | MediumTest | Level3) ASSERT_TRUE(utils::RectEqualTo(test1, utils::tripleTileRects_[0])); ASSERT_TRUE(utils::RectEqualTo(test2, utils::tripleTileRects_[1])); ASSERT_TRUE(utils::RectEqualTo(test3, utils::tripleTileRects_[2])); // 2 is second rect idx + WindowManager::GetInstance().SetWindowLayoutMode(WindowLayoutMode::CASCADE, displayId_); +} + +/** + * @tc.name: LayoutTileNegative01 + * @tc.desc: negative test for tile window + * @tc.type: FUNC + * @tc.require: AR000GGTVJ + */ +HWTEST_F(WindowLayoutTest, LayoutTileNegative01, Function | MediumTest | Level3) +{ + utils::TestWindowInfo info = { + .name = "main", + .rect = {-1, -100, -1, -100}, // -1, -100, -1, -100 is typical negative case nums + .type = WindowType::WINDOW_TYPE_APP_MAIN_WINDOW, + .mode = WindowMode::WINDOW_MODE_FLOATING, + .needAvoid = true, + .parentLimit = false, + .parentName = "", + }; + const sptr& window = utils::CreateTestWindow(info); + activeWindows_.push_back(window); + ASSERT_EQ(WMError::WM_OK, window->Show()); + utils::InitTileWindowRects(window); + WindowManager::GetInstance().SetWindowLayoutMode(WindowLayoutMode::TILE, displayId_); + ASSERT_TRUE(utils::RectEqualTo(window, utils::singleTileRect_)); + info.name = "test1"; + const sptr& test1 = utils::CreateTestWindow(info); + activeWindows_.push_back(test1); + ASSERT_EQ(WMError::WM_OK, test1->Show()); + ASSERT_TRUE(utils::RectEqualTo(window, utils::doubleTileRects_[0])); + ASSERT_TRUE(utils::RectEqualTo(test1, utils::doubleTileRects_[1])); + info.name = "test2"; + const sptr& test2 = utils::CreateTestWindow(info); + activeWindows_.push_back(test2); + ASSERT_EQ(WMError::WM_OK, test2->Show()); + if (utils::isVerticalDisplay_) { + ASSERT_TRUE(utils::RectEqualTo(test1, utils::doubleTileRects_[0])); + ASSERT_TRUE(utils::RectEqualTo(test2, utils::doubleTileRects_[1])); + WindowManager::GetInstance().SetWindowLayoutMode(WindowLayoutMode::CASCADE, displayId_); + return; + } else { + ASSERT_TRUE(utils::RectEqualTo(window, utils::tripleTileRects_[0])); + ASSERT_TRUE(utils::RectEqualTo(test1, utils::tripleTileRects_[1])); + ASSERT_TRUE(utils::RectEqualTo(test2, utils::tripleTileRects_[2])); // 2 is second rect idx + } + info.name = "test3"; + const sptr& test3 = utils::CreateTestWindow(info); + activeWindows_.push_back(test3); + ASSERT_EQ(WMError::WM_OK, test3->Show()); + ASSERT_TRUE(utils::RectEqualTo(test1, utils::tripleTileRects_[0])); + ASSERT_TRUE(utils::RectEqualTo(test2, utils::tripleTileRects_[1])); + ASSERT_TRUE(utils::RectEqualTo(test3, utils::tripleTileRects_[2])); // 2 is second rect idx + WindowManager::GetInstance().SetWindowLayoutMode(WindowLayoutMode::CASCADE, displayId_); +} + +/** + * @tc.name: LayoutTileNegative01 + * @tc.desc: move window out of the display + * @tc.type: FUNC + * @tc.require: AR000GGTVJ + */ +HWTEST_F(WindowLayoutTest, LayoutNegative01, Function | MediumTest | Level3) +{ + utils::TestWindowInfo info = { + .name = "main", + .rect = {0, 0, 0, 0}, + .type = WindowType::WINDOW_TYPE_APP_MAIN_WINDOW, + .mode = WindowMode::WINDOW_MODE_FLOATING, + .needAvoid = true, + .parentLimit = false, + .parentName = "", + }; + const sptr& window = utils::CreateTestWindow(info); + activeWindows_.push_back(window); + Rect expect = utils::GetDefaultFoatingRect(window); + ASSERT_EQ(WMError::WM_OK, window->Show()); + ASSERT_TRUE(utils::RectEqualTo(window, expect)); + window->MoveTo(INT_MIN, INT_MIN); + AvoidArea avoidArea; + auto res = window->GetAvoidAreaByType(AvoidAreaType::TYPE_SYSTEM, avoidArea); + ASSERT_EQ(WMError::WM_OK, res); + Rect expect2 = {INT_MIN, avoidArea.topRect.height_, expect.width_, expect.height_}; + ASSERT_TRUE(utils::RectEqualTo(window, expect2)); +} + +/** + * @tc.name: LayoutNegative02 + * @tc.desc: resize window to negative size + * @tc.type: FUNC + * @tc.require: AR000GGTVJ + */ +HWTEST_F(WindowLayoutTest, LayoutNegative02, Function | MediumTest | Level3) +{ + const uint32_t negativeW = UINT32_MAX; + const uint32_t negativeH = 0; + utils::TestWindowInfo info = { + .name = "main", + .rect = {0, 0, 0, 0}, + .type = WindowType::WINDOW_TYPE_APP_MAIN_WINDOW, + .mode = WindowMode::WINDOW_MODE_FLOATING, + .needAvoid = true, + .parentLimit = false, + .parentName = "", + }; + const sptr& window = utils::CreateTestWindow(info); + activeWindows_.push_back(window); + Rect expect = utils::GetDefaultFoatingRect(window); + ASSERT_EQ(WMError::WM_OK, window->Show()); + ASSERT_TRUE(utils::RectEqualTo(window, expect)); + window->Resize(negativeW, negativeH); + Rect expect2 = {expect.posX_, expect.posY_, negativeW, negativeH}; + expect2 = utils::CalcLimitedRect(expect2, virtualPixelRatio_); + ASSERT_TRUE(utils::RectEqualTo(window, expect2)); } } } // namespace Rosen diff --git a/wm/test/systemtest/window_move_drag_test.cpp b/wm/test/systemtest/window_move_drag_test.cpp index 38783803..15834d4b 100644 --- a/wm/test/systemtest/window_move_drag_test.cpp +++ b/wm/test/systemtest/window_move_drag_test.cpp @@ -17,7 +17,9 @@ #include #include "pointer_event.h" #include "window_helper.h" +#include "window_impl.h" #include "window_test_utils.h" +#include "wm_common_inner.h" using namespace testing; using namespace testing::ext; @@ -42,9 +44,8 @@ private: uint32_t pointerId, int32_t pointerAction); void CalExpectRects(); - void DoMoveOrDrag(); + void DoMoveOrDrag(bool isMove, bool isDrag); static inline std::vector> activeWindows_; - static inline utils::TestWindowInfo winInfo_; static inline uint32_t pointerId_ = 0; static inline int32_t pointX_ = 0; static inline int32_t pointY_ = 0; @@ -53,7 +54,9 @@ private: static inline bool hasStartMove_ = false; static inline Rect startPointRect_ = {0, 0, 0, 0}; static inline Rect expectRect_ = {0, 0, 0, 0}; - static inline sptr window_ = nullptr; + static inline sptr window_ = nullptr; + static inline float virtualPixelRatio_ = 0.0; + static inline uint32_t hotZone_ = 0; }; void WindowMoveDragTest::SetUpTestCase() @@ -62,9 +65,8 @@ void WindowMoveDragTest::SetUpTestCase() startPointY_ = 0; pointX_ = 0; pointY_ = 0; - startPointRect_ = {0, 0, 0, 0}; - expectRect_ = {0, 0, 0, 0}; - winInfo_.rect = {0, 0, 0, 0}; + startPointRect_ = {0, 0, 0, 0}; + expectRect_ = {0, 0, 0, 0}; } void WindowMoveDragTest::TearDownTestCase() @@ -83,16 +85,15 @@ void WindowMoveDragTest::SetUp() Rect displayRect = {0, 0, display->GetWidth(), display->GetHeight()}; utils::InitByDisplayRect(displayRect); - winInfo_ = { - .name = "Floating", - .rect = {0, 0, 0, 0}, - .type = WindowType::WINDOW_TYPE_APP_MAIN_WINDOW, - .mode = WindowMode::WINDOW_MODE_FLOATING, - .needAvoid = true, - .parentLimit = false, - .parentName = "", - }; - window_ = utils::CreateTestWindow(winInfo_); + virtualPixelRatio_ = WindowTestUtils::GetVirtualPixelRatio(0); + hotZone_ = static_cast(HOTZONE * virtualPixelRatio_); + + sptr option = new WindowOption(); + option->SetWindowName("WindowMoveDragTest"); + option->SetWindowMode(WindowMode::WINDOW_MODE_FLOATING); + option->SetWindowType(WindowType::WINDOW_TYPE_APP_MAIN_WINDOW); + window_ = new WindowImpl(option); + window_->Create(""); ASSERT_TRUE((window_ != nullptr)); } @@ -119,7 +120,7 @@ std::shared_ptr WindowMoveDragTest::CreatePointerEvent(int32_ return pointerEvent; } -void WindowMoveDragTest::DoMoveOrDrag() +void WindowMoveDragTest::DoMoveOrDrag(bool isMove, bool isDrag) { pointerId_++; std::shared_ptr pointerEvent = @@ -131,6 +132,8 @@ void WindowMoveDragTest::DoMoveOrDrag() window_->ConsumePointerEvent(pointerEvent); CalExpectRects(); ASSERT_TRUE(utils::RectEqualToRect(window_->GetRect(), expectRect_)); + ASSERT_EQ(isMove, window_->startMoveFlag_); + ASSERT_EQ(isDrag, window_->startDragFlag_); pointerEvent = CreatePointerEvent(pointX_, pointY_, pointerId_, MMI::PointerEvent::POINTER_ACTION_UP); window_->ConsumePointerEvent(pointerEvent); @@ -174,7 +177,7 @@ void WindowMoveDragTest::CalExpectRects() } } bool isVertical = (utils::displayRect_.width_ < utils::displayRect_.height_) ? true : false; - expectRect_ = WindowHelper::GetFixedWindowRectByMinRect(oriRect, startPointRect_, isVertical); + expectRect_ = WindowHelper::GetFixedWindowRectByMinRect(oriRect, startPointRect_, isVertical, virtualPixelRatio_); } namespace { @@ -188,11 +191,11 @@ HWTEST_F(WindowMoveDragTest, DragWindow01, Function | MediumTest | Level3) { ASSERT_EQ(WMError::WM_OK, window_->Show()); startPointRect_ = window_->GetRect(); - startPointX_ = startPointRect_.posX_ - HOTZONE * POINT_HOTZONE_RATIO; + startPointX_ = startPointRect_.posX_ - hotZone_ * POINT_HOTZONE_RATIO; startPointY_ = startPointRect_.posY_ + startPointRect_.height_ * POINT_HOTZONE_RATIO; - pointX_ = startPointRect_.posX_ + HOTZONE * DRAG_HOTZONE_RATIO; - pointY_ = startPointRect_.posY_ + HOTZONE * DRAG_HOTZONE_RATIO; - DoMoveOrDrag(); + pointX_ = startPointRect_.posX_ + hotZone_ * DRAG_HOTZONE_RATIO; + pointY_ = startPointRect_.posY_ + hotZone_ * DRAG_HOTZONE_RATIO; + DoMoveOrDrag(false, true); ASSERT_EQ(WMError::WM_OK, window_->Hide()); } @@ -206,12 +209,12 @@ HWTEST_F(WindowMoveDragTest, DragWindow02, Function | MediumTest | Level3) { ASSERT_EQ(WMError::WM_OK, window_->Show()); startPointRect_ = window_->GetRect(); - startPointX_ = startPointRect_.posX_ - HOTZONE * POINT_HOTZONE_RATIO; - startPointY_ = startPointRect_.posY_ - HOTZONE * POINT_HOTZONE_RATIO; + startPointX_ = startPointRect_.posX_ - hotZone_ * POINT_HOTZONE_RATIO; + startPointY_ = startPointRect_.posY_ - hotZone_ * POINT_HOTZONE_RATIO; - pointX_ = startPointRect_.posX_ + HOTZONE * DRAG_HOTZONE_RATIO; - pointY_ = startPointRect_.posY_ + HOTZONE * DRAG_HOTZONE_RATIO; - DoMoveOrDrag(); + pointX_ = startPointRect_.posX_ + hotZone_ * DRAG_HOTZONE_RATIO; + pointY_ = startPointRect_.posY_ + hotZone_ * DRAG_HOTZONE_RATIO; + DoMoveOrDrag(false, true); ASSERT_EQ(WMError::WM_OK, window_->Hide()); } @@ -225,12 +228,12 @@ HWTEST_F(WindowMoveDragTest, DragWindow03, Function | MediumTest | Level3) { ASSERT_EQ(WMError::WM_OK, window_->Show()); startPointRect_ = window_->GetRect(); - startPointX_ = startPointRect_.posX_ - HOTZONE * POINT_HOTZONE_RATIO; - startPointY_ = startPointRect_.posY_ + startPointRect_.height_ + HOTZONE * POINT_HOTZONE_RATIO; + startPointX_ = startPointRect_.posX_ - hotZone_ * POINT_HOTZONE_RATIO; + startPointY_ = startPointRect_.posY_ + startPointRect_.height_ + hotZone_ * POINT_HOTZONE_RATIO; - pointX_ = startPointRect_.posX_ + HOTZONE * DRAG_HOTZONE_RATIO; - pointY_ = startPointRect_.posY_ + startPointRect_.height_ + HOTZONE * DRAG_HOTZONE_RATIO; - DoMoveOrDrag(); + pointX_ = startPointRect_.posX_ + hotZone_ * DRAG_HOTZONE_RATIO; + pointY_ = startPointRect_.posY_ + startPointRect_.height_ + hotZone_ * DRAG_HOTZONE_RATIO; + DoMoveOrDrag(false, true); ASSERT_EQ(WMError::WM_OK, window_->Hide()); } @@ -244,12 +247,12 @@ HWTEST_F(WindowMoveDragTest, DragWindow04, Function | MediumTest | Level3) { ASSERT_EQ(WMError::WM_OK, window_->Show()); startPointRect_ = window_->GetRect(); - startPointX_ = startPointRect_.posX_ + startPointRect_.width_ + HOTZONE * POINT_HOTZONE_RATIO; + startPointX_ = startPointRect_.posX_ + startPointRect_.width_ + hotZone_ * POINT_HOTZONE_RATIO; startPointY_ = startPointRect_.posY_ + startPointRect_.height_ * POINT_HOTZONE_RATIO; - pointX_ = startPointRect_.posX_ + startPointRect_.width_ + HOTZONE * DRAG_HOTZONE_RATIO; + pointX_ = startPointRect_.posX_ + startPointRect_.width_ + hotZone_ * DRAG_HOTZONE_RATIO; pointY_ = startPointRect_.posY_ + startPointRect_.height_ * DRAG_HOTZONE_RATIO; - DoMoveOrDrag(); + DoMoveOrDrag(false, true); ASSERT_EQ(WMError::WM_OK, window_->Hide()); } @@ -263,12 +266,12 @@ HWTEST_F(WindowMoveDragTest, DragWindow05, Function | MediumTest | Level3) { ASSERT_EQ(WMError::WM_OK, window_->Show()); startPointRect_ = window_->GetRect(); - startPointX_ = startPointRect_.posX_ + startPointRect_.width_ + HOTZONE * POINT_HOTZONE_RATIO; - startPointY_ = startPointRect_.posY_ - HOTZONE * POINT_HOTZONE_RATIO; + startPointX_ = startPointRect_.posX_ + startPointRect_.width_ + hotZone_ * POINT_HOTZONE_RATIO; + startPointY_ = startPointRect_.posY_ - hotZone_ * POINT_HOTZONE_RATIO; - pointX_ = startPointRect_.posX_ + startPointRect_.width_ + HOTZONE * DRAG_HOTZONE_RATIO; - pointY_ = startPointRect_.posY_ + HOTZONE * DRAG_HOTZONE_RATIO; - DoMoveOrDrag(); + pointX_ = startPointRect_.posX_ + startPointRect_.width_ + hotZone_ * DRAG_HOTZONE_RATIO; + pointY_ = startPointRect_.posY_ + hotZone_ * DRAG_HOTZONE_RATIO; + DoMoveOrDrag(false, true); ASSERT_EQ(WMError::WM_OK, window_->Hide()); } @@ -282,12 +285,12 @@ HWTEST_F(WindowMoveDragTest, DragWindow06, Function | MediumTest | Level3) { ASSERT_EQ(WMError::WM_OK, window_->Show()); startPointRect_ = window_->GetRect(); - startPointX_ = startPointRect_.posX_ + startPointRect_.width_ + HOTZONE * POINT_HOTZONE_RATIO; - startPointY_ = startPointRect_.posY_ + startPointRect_.height_ + HOTZONE * POINT_HOTZONE_RATIO; + startPointX_ = startPointRect_.posX_ + startPointRect_.width_ + hotZone_ * POINT_HOTZONE_RATIO; + startPointY_ = startPointRect_.posY_ + startPointRect_.height_ + hotZone_ * POINT_HOTZONE_RATIO; - pointX_ = startPointRect_.posX_ + startPointRect_.width_ + HOTZONE * DRAG_HOTZONE_RATIO; - pointY_ = startPointRect_.posY_ + startPointRect_.height_ + HOTZONE * DRAG_HOTZONE_RATIO; - DoMoveOrDrag(); + pointX_ = startPointRect_.posX_ + startPointRect_.width_ + hotZone_ * DRAG_HOTZONE_RATIO; + pointY_ = startPointRect_.posY_ + startPointRect_.height_ + hotZone_ * DRAG_HOTZONE_RATIO; + DoMoveOrDrag(false, true); ASSERT_EQ(WMError::WM_OK, window_->Hide()); } @@ -302,11 +305,11 @@ HWTEST_F(WindowMoveDragTest, DragWindow07, Function | MediumTest | Level3) ASSERT_EQ(WMError::WM_OK, window_->Show()); startPointRect_ = window_->GetRect(); startPointX_ = startPointRect_.posX_ + startPointRect_.width_ * POINT_HOTZONE_RATIO; - startPointY_ = startPointRect_.posY_ - HOTZONE * POINT_HOTZONE_RATIO; + startPointY_ = startPointRect_.posY_ - hotZone_ * POINT_HOTZONE_RATIO; pointX_ = startPointRect_.posX_ + startPointRect_.width_ * DRAG_HOTZONE_RATIO; - pointY_ = startPointRect_.posY_ - HOTZONE * DRAG_HOTZONE_RATIO; - DoMoveOrDrag(); + pointY_ = startPointRect_.posY_ - hotZone_ * DRAG_HOTZONE_RATIO; + DoMoveOrDrag(false, true); ASSERT_EQ(WMError::WM_OK, window_->Hide()); } @@ -321,11 +324,11 @@ HWTEST_F(WindowMoveDragTest, DragWindow08, Function | MediumTest | Level3) ASSERT_EQ(WMError::WM_OK, window_->Show()); startPointRect_ = window_->GetRect(); startPointX_ = startPointRect_.posX_ + startPointRect_.width_ * POINT_HOTZONE_RATIO; - startPointY_ = startPointRect_.posY_ + startPointRect_.height_ + HOTZONE * POINT_HOTZONE_RATIO; + startPointY_ = startPointRect_.posY_ + startPointRect_.height_ + hotZone_ * POINT_HOTZONE_RATIO; pointX_ = startPointRect_.posX_ + startPointRect_.width_ * DRAG_HOTZONE_RATIO; - pointY_ = startPointRect_.posY_ + startPointRect_.height_ + HOTZONE * DRAG_HOTZONE_RATIO; - DoMoveOrDrag(); + pointY_ = startPointRect_.posY_ + startPointRect_.height_ + hotZone_ * DRAG_HOTZONE_RATIO; + DoMoveOrDrag(false, true); ASSERT_EQ(WMError::WM_OK, window_->Hide()); } @@ -343,8 +346,8 @@ HWTEST_F(WindowMoveDragTest, DragWindow09, Function | MediumTest | Level3) startPointY_ = startPointRect_.posY_ + 1; pointX_ = startPointRect_.posX_ + startPointRect_.width_ * DRAG_HOTZONE_RATIO; - pointY_ = startPointRect_.posY_ + startPointRect_.height_ + HOTZONE * DRAG_HOTZONE_RATIO; - DoMoveOrDrag(); + pointY_ = startPointRect_.posY_ + startPointRect_.height_ + hotZone_ * DRAG_HOTZONE_RATIO; + DoMoveOrDrag(false, false); ASSERT_EQ(WMError::WM_OK, window_->Hide()); } @@ -362,10 +365,29 @@ HWTEST_F(WindowMoveDragTest, DragWindow10, Function | MediumTest | Level3) startPointY_ = startPointRect_.posY_ + 1; pointX_ = startPointRect_.posX_ + startPointRect_.width_ * DRAG_HOTZONE_RATIO; - pointY_ = startPointRect_.posY_ + HOTZONE * DRAG_HOTZONE_RATIO; + pointY_ = startPointRect_.posY_ + hotZone_ * DRAG_HOTZONE_RATIO; window_->StartMove(); hasStartMove_ = true; - DoMoveOrDrag(); + DoMoveOrDrag(true, false); + ASSERT_EQ(WMError::WM_OK, window_->Hide()); +} + +/** + * @tc.name: DragWindow11 + * @tc.desc: drag inner + * @tc.type: FUNC + * @tc.require: AR000GGTV8 + */ +HWTEST_F(WindowMoveDragTest, DragWindow11, Function | MediumTest | Level3) +{ + ASSERT_EQ(WMError::WM_OK, window_->Show()); + startPointRect_ = window_->GetRect(); + startPointX_ = startPointRect_.posX_ + startPointRect_.width_ * POINT_HOTZONE_RATIO; + startPointY_ = startPointRect_.posY_ + startPointRect_.height_ * POINT_HOTZONE_RATIO; + + pointX_ = startPointRect_.posX_ + startPointRect_.width_ * DRAG_HOTZONE_RATIO; + pointY_ = startPointRect_.posY_ + startPointRect_.height_ * DRAG_HOTZONE_RATIO; + DoMoveOrDrag(false, false); ASSERT_EQ(WMError::WM_OK, window_->Hide()); } } diff --git a/wm/test/systemtest/window_split_immersive_test.cpp b/wm/test/systemtest/window_split_immersive_test.cpp index e6fbea0b..6c08e0ea 100644 --- a/wm/test/systemtest/window_split_immersive_test.cpp +++ b/wm/test/systemtest/window_split_immersive_test.cpp @@ -39,7 +39,7 @@ public: utils::TestWindowInfo splitInfo_; private: - static constexpr uint32_t SPLIT_TEST_SPEEP_S = 1; // split test spleep time + static constexpr uint32_t SPLIT_TEST_SLEEP_S = 1; // split test sleep time }; void WindowSplitImmersiveTest::SetUpTestCase() @@ -96,14 +96,14 @@ HWTEST_F(WindowSplitImmersiveTest, SplitImmersive01, Function | MediumTest | Lev const sptr& fullWindow = utils::CreateTestWindow(fullInfo_); activeWindows_.push_back(fullWindow); ASSERT_EQ(WMError::WM_OK, fullWindow->Show()); - sleep(SPLIT_TEST_SPEEP_S); + sleep(SPLIT_TEST_SLEEP_S); // enter split mode splitInfo_.mode = WindowMode::WINDOW_MODE_SPLIT_PRIMARY; const sptr& priWindow = utils::CreateTestWindow(splitInfo_); activeWindows_.push_back(priWindow); ASSERT_EQ(WMError::WM_OK, priWindow->Show()); - sleep(SPLIT_TEST_SPEEP_S); + sleep(SPLIT_TEST_SLEEP_S); // check is enter split Immersive ASSERT_EQ(WindowMode::WINDOW_MODE_SPLIT_PRIMARY, priWindow->GetMode()); @@ -111,11 +111,11 @@ HWTEST_F(WindowSplitImmersiveTest, SplitImmersive01, Function | MediumTest | Lev Rect immersivePriRect = priWindow->GetRect(); ASSERT_EQ(0, immersivePriRect.posX_); ASSERT_EQ(0, immersivePriRect.posY_); - sleep(SPLIT_TEST_SPEEP_S); + sleep(SPLIT_TEST_SLEEP_S); // Exit split Mode. ASSERT_EQ(WMError::WM_OK, priWindow->Hide()); - sleep(SPLIT_TEST_SPEEP_S); + sleep(SPLIT_TEST_SLEEP_S); // check is out split Immersive ASSERT_EQ(WindowMode::WINDOW_MODE_FULLSCREEN, fullWindow->GetMode()); @@ -125,9 +125,9 @@ HWTEST_F(WindowSplitImmersiveTest, SplitImmersive01, Function | MediumTest | Lev ASSERT_EQ(avoidArea.topRect.height_, curFullScreenRect.posY_); ASSERT_EQ(WMError::WM_OK, fullWindow->Hide()); - sleep(SPLIT_TEST_SPEEP_S); + sleep(SPLIT_TEST_SLEEP_S); ASSERT_EQ(WMError::WM_OK, priWindow->Hide()); - sleep(SPLIT_TEST_SPEEP_S); + sleep(SPLIT_TEST_SLEEP_S); } } } // namespace Rosen diff --git a/wm/test/systemtest/window_split_test.cpp b/wm/test/systemtest/window_split_test.cpp index 1f503bd4..10594bb7 100644 --- a/wm/test/systemtest/window_split_test.cpp +++ b/wm/test/systemtest/window_split_test.cpp @@ -33,7 +33,7 @@ public: utils::TestWindowInfo splitInfo_; private: - static constexpr uint32_t SPLIT_TEST_SPEEP_S = 1; // split test spleep time + static constexpr uint32_t SPLIT_TEST_SLEEP_S = 1; // split test sleep time }; void WindowSplitTest::SetUpTestCase() @@ -93,21 +93,21 @@ HWTEST_F(WindowSplitTest, SplitWindow01, Function | MediumTest | Level3) const sptr& fullWindow = utils::CreateTestWindow(fullInfo_); activeWindows_.push_back(fullWindow); ASSERT_EQ(WMError::WM_OK, fullWindow->Show()); - sleep(SPLIT_TEST_SPEEP_S); + sleep(SPLIT_TEST_SLEEP_S); const sptr& priWindow = utils::CreateTestWindow(splitInfo_); activeWindows_.push_back(priWindow); ASSERT_EQ(WMError::WM_OK, priWindow->Show()); - sleep(SPLIT_TEST_SPEEP_S); + sleep(SPLIT_TEST_SLEEP_S); ASSERT_EQ(WindowMode::WINDOW_MODE_SPLIT_PRIMARY, priWindow->GetMode()); ASSERT_EQ(WindowMode::WINDOW_MODE_SPLIT_SECONDARY, fullWindow->GetMode()); ASSERT_EQ(WMError::WM_OK, priWindow->Hide()); - sleep(SPLIT_TEST_SPEEP_S); + sleep(SPLIT_TEST_SLEEP_S); ASSERT_EQ(WindowMode::WINDOW_MODE_FULLSCREEN, fullWindow->GetMode()); ASSERT_EQ(WMError::WM_OK, fullWindow->Hide()); - sleep(SPLIT_TEST_SPEEP_S); + sleep(SPLIT_TEST_SLEEP_S); } /** @@ -125,20 +125,20 @@ HWTEST_F(WindowSplitTest, SplitWindow02, Function | MediumTest | Level3) const sptr& fullWindow = utils::CreateTestWindow(fullInfo_); activeWindows_.push_back(fullWindow); ASSERT_EQ(WMError::WM_OK, fullWindow->Show()); - sleep(SPLIT_TEST_SPEEP_S); + sleep(SPLIT_TEST_SLEEP_S); const sptr& secWindow = utils::CreateTestWindow(splitInfo_); activeWindows_.push_back(secWindow); ASSERT_EQ(WMError::WM_OK, secWindow->Show()); - sleep(SPLIT_TEST_SPEEP_S); + sleep(SPLIT_TEST_SLEEP_S); ASSERT_EQ(WindowMode::WINDOW_MODE_SPLIT_SECONDARY, secWindow->GetMode()); ASSERT_EQ(WindowMode::WINDOW_MODE_SPLIT_PRIMARY, fullWindow->GetMode()); ASSERT_EQ(WMError::WM_OK, fullWindow->Hide()); - sleep(SPLIT_TEST_SPEEP_S); + sleep(SPLIT_TEST_SLEEP_S); ASSERT_EQ(WindowMode::WINDOW_MODE_FULLSCREEN, secWindow->GetMode()); ASSERT_EQ(WMError::WM_OK, secWindow->Hide()); - sleep(SPLIT_TEST_SPEEP_S); + sleep(SPLIT_TEST_SLEEP_S); } /** @@ -158,11 +158,11 @@ HWTEST_F(WindowSplitTest, SplitCreen03, Function | MediumTest | Level3) const sptr& fullWindow = utils::CreateTestWindow(fullInfo_); activeWindows_.push_back(fullWindow); ASSERT_EQ(WMError::WM_OK, fullWindow->Show()); - sleep(SPLIT_TEST_SPEEP_S); + sleep(SPLIT_TEST_SLEEP_S); const sptr& priWindow = utils::CreateTestWindow(splitInfo_); activeWindows_.push_back(priWindow); ASSERT_EQ(WMError::WM_OK, priWindow->Show()); - sleep(SPLIT_TEST_SPEEP_S); + sleep(SPLIT_TEST_SLEEP_S); utils::UpdateSplitRects(fullWindow); @@ -170,9 +170,9 @@ HWTEST_F(WindowSplitTest, SplitCreen03, Function | MediumTest | Level3) ASSERT_TRUE(utils::RectEqualTo(priWindow, utils::splitRects_.primaryRect)); ASSERT_EQ(WMError::WM_OK, fullWindow->Hide()); - sleep(SPLIT_TEST_SPEEP_S); + sleep(SPLIT_TEST_SLEEP_S); ASSERT_EQ(WMError::WM_OK, priWindow->Hide()); - sleep(SPLIT_TEST_SPEEP_S); + sleep(SPLIT_TEST_SLEEP_S); } /** @@ -192,11 +192,11 @@ HWTEST_F(WindowSplitTest, SplitCreen04, Function | MediumTest | Level3) const sptr& fullWindow = utils::CreateTestWindow(fullInfo_); activeWindows_.push_back(fullWindow); ASSERT_EQ(WMError::WM_OK, fullWindow->Show()); - sleep(SPLIT_TEST_SPEEP_S); + sleep(SPLIT_TEST_SLEEP_S); const sptr& secWindow = utils::CreateTestWindow(splitInfo_); activeWindows_.push_back(secWindow); ASSERT_EQ(WMError::WM_OK, secWindow->Show()); - sleep(SPLIT_TEST_SPEEP_S); + sleep(SPLIT_TEST_SLEEP_S); utils::UpdateSplitRects(fullWindow); @@ -204,9 +204,9 @@ HWTEST_F(WindowSplitTest, SplitCreen04, Function | MediumTest | Level3) ASSERT_TRUE(utils::RectEqualTo(secWindow, utils::splitRects_.secondaryRect)); ASSERT_EQ(WMError::WM_OK, fullWindow->Hide()); - sleep(SPLIT_TEST_SPEEP_S); + sleep(SPLIT_TEST_SLEEP_S); ASSERT_EQ(WMError::WM_OK, secWindow->Hide()); - sleep(SPLIT_TEST_SPEEP_S); + sleep(SPLIT_TEST_SLEEP_S); } } } // namespace Rosen diff --git a/wm/test/systemtest/window_test_utils.cpp b/wm/test/systemtest/window_test_utils.cpp index 23fa2b83..5e3f9dfe 100644 --- a/wm/test/systemtest/window_test_utils.cpp +++ b/wm/test/systemtest/window_test_utils.cpp @@ -15,6 +15,7 @@ #include "window_test_utils.h" #include +#include "wm_common_inner.h" namespace OHOS { namespace Rosen { namespace { @@ -123,13 +124,18 @@ Rect WindowTestUtils::GetDefaultFoatingRect(const sptr& window) return resRect; } -Rect WindowTestUtils::GetLimitedDecoRect(const Rect& rect) +Rect WindowTestUtils::GetLimitedDecoRect(const Rect& rect, float virtualPixelRatio) { - constexpr uint32_t winFrameH = 52u; - constexpr uint32_t winFrameW = 8u; + constexpr uint32_t windowTitleBarHeight = 48; + constexpr uint32_t windowFrameWidth = 4; + uint32_t winFrameH = static_cast((windowTitleBarHeight + windowFrameWidth) * virtualPixelRatio); + uint32_t winFrameW = static_cast((windowFrameWidth + windowFrameWidth) * virtualPixelRatio); + uint32_t minVerticalFloatingW = static_cast(MIN_VERTICAL_FLOATING_WIDTH * virtualPixelRatio); + uint32_t minVerticalFloatingH = static_cast(MIN_VERTICAL_FLOATING_HEIGHT * virtualPixelRatio); + bool vertical = displayRect_.width_ < displayRect_.height_; - uint32_t minFloatingW = vertical ? MIN_VERTICAL_FLOATING_WIDTH : MIN_VERTICAL_FLOATING_HEIGHT; - uint32_t minFloatingH = vertical ? MIN_VERTICAL_FLOATING_HEIGHT : MIN_VERTICAL_FLOATING_WIDTH; + uint32_t minFloatingW = vertical ? minVerticalFloatingW : minVerticalFloatingH; + uint32_t minFloatingH = vertical ? minVerticalFloatingH : minVerticalFloatingW; Rect resRect = { rect.posX_, rect.posY_, @@ -139,11 +145,31 @@ Rect WindowTestUtils::GetLimitedDecoRect(const Rect& rect) return resRect; } -Rect WindowTestUtils::GetFloatingLimitedRect(const Rect& rect) +Rect WindowTestUtils::CalcLimitedRect(const Rect& rect, float virtualPixelRatio) { + uint32_t minVerticalFloatingW = static_cast(MIN_VERTICAL_FLOATING_WIDTH * virtualPixelRatio); + uint32_t minVerticalFloatingH = static_cast(MIN_VERTICAL_FLOATING_HEIGHT * virtualPixelRatio); + bool vertical = displayRect_.width_ < displayRect_.height_; - uint32_t minFloatingW = vertical ? MIN_VERTICAL_FLOATING_WIDTH : MIN_VERTICAL_FLOATING_HEIGHT; - uint32_t minFloatingH = vertical ? MIN_VERTICAL_FLOATING_HEIGHT : MIN_VERTICAL_FLOATING_WIDTH; + uint32_t minFloatingW = vertical ? minVerticalFloatingW : minVerticalFloatingH; + uint32_t minFloatingH = vertical ? minVerticalFloatingH : minVerticalFloatingW; + Rect resRect = { + rect.posX_, + rect.posY_, + std::max(minFloatingW, rect.width_), + std::max(minFloatingH, rect.height_), + }; + return resRect; +} + +Rect WindowTestUtils::GetFloatingLimitedRect(const Rect& rect, float virtualPixelRatio) +{ + uint32_t minVerticalFloatingW = static_cast(MIN_VERTICAL_FLOATING_WIDTH * virtualPixelRatio); + uint32_t minVerticalFloatingH = static_cast(MIN_VERTICAL_FLOATING_HEIGHT * virtualPixelRatio); + bool vertical = displayRect_.width_ < displayRect_.height_; + + uint32_t minFloatingW = vertical ? minVerticalFloatingW : minVerticalFloatingH; + uint32_t minFloatingH = vertical ? minVerticalFloatingH : minVerticalFloatingW; Rect resRect = { rect.posX_, rect.posY_, @@ -204,6 +230,7 @@ void WindowTestUtils::InitTileWindowRects(const sptr& window) bool WindowTestUtils::RectEqualTo(const sptr& window, const Rect& r) { + usleep(100000); // 100000us Rect l = window->GetRect(); bool res = ((l.posX_ == r.posX_) && (l.posY_ == r.posY_) && (l.width_ == r.width_) && (l.height_ == r.height_)); if (!res) { @@ -257,18 +284,21 @@ void WindowTestUtils::InitSplitRects() displayRect_ = displayRect; limitDisplayRect_ = displayRect; + float virtualPixelRatio = WindowTestUtils::GetVirtualPixelRatio(0); + uint32_t dividerWidth = static_cast(DIVIDER_WIDTH * virtualPixelRatio); + if (displayRect_.width_ < displayRect_.height_) { isVerticalDisplay_ = true; } if (isVerticalDisplay_) { splitRects_.dividerRect = { 0, - static_cast((displayRect_.height_ - DIVIDER_WIDTH) * DEFAULT_SPLIT_RATIO), + static_cast((displayRect_.height_ - dividerWidth) * DEFAULT_SPLIT_RATIO), displayRect_.width_, - DIVIDER_WIDTH, }; + dividerWidth, }; } else { - splitRects_.dividerRect = { static_cast((displayRect_.width_ - DIVIDER_WIDTH) * DEFAULT_SPLIT_RATIO), + splitRects_.dividerRect = { static_cast((displayRect_.width_ - dividerWidth) * DEFAULT_SPLIT_RATIO), 0, - DIVIDER_WIDTH, + dividerWidth, displayRect_.height_ }; } } @@ -374,5 +404,23 @@ void WindowTestUtils::UpdateLimitSplitRect(Rect& limitSplitRect) curLimitRect.posY_ + curLimitRect.height_) - limitSplitRect.posY_; } + +float WindowTestUtils::GetVirtualPixelRatio(DisplayId displayId) +{ + auto display = DisplayManager::GetInstance().GetDisplayById(displayId); + if (display == nullptr) { + WLOGFE("GetVirtualPixel fail. Get display fail. displayId:%{public}" PRIu64", use Default vpr:1.0", displayId); + return 1.0; // Use DefaultVPR 1.0 + } + + float virtualPixelRatio = display->GetVirtualPixelRatio(); + if (virtualPixelRatio == 0.0) { + WLOGFE("GetVirtualPixel fail. vpr is 0.0. displayId:%{public}" PRIu64", use Default vpr:1.0", displayId); + return 1.0; // Use DefaultVPR 1.0 + } + + WLOGFI("GetVirtualPixel success. displayId:%{public}" PRIu64", vpr:%{public}f", displayId, virtualPixelRatio); + return virtualPixelRatio; +} } // namespace ROSEN } // namespace OHOS diff --git a/wm/test/systemtest/window_test_utils.h b/wm/test/systemtest/window_test_utils.h index 2742aa30..30ad3d0b 100644 --- a/wm/test/systemtest/window_test_utils.h +++ b/wm/test/systemtest/window_test_utils.h @@ -66,9 +66,11 @@ public: static void UpdateSplitRects(const sptr& window); static bool RectEqualToRect(const Rect& l, const Rect& r); static Rect GetDefaultFoatingRect(const sptr& window); - static Rect GetLimitedDecoRect(const Rect& rect); - static Rect GetFloatingLimitedRect(const Rect& rect); + static Rect GetLimitedDecoRect(const Rect& rect, float virtualPixelRatio); + static Rect CalcLimitedRect(const Rect& rect, float virtualPixelRatio); + static Rect GetFloatingLimitedRect(const Rect& rect, float virtualPixelRatio); static void InitTileWindowRects(const sptr& window); + static float GetVirtualPixelRatio(DisplayId displayId); private: void UpdateLimitDisplayRect(Rect& avoidRect); diff --git a/wm/test/systemtest/window_visibility_info_test.cpp b/wm/test/systemtest/window_visibility_info_test.cpp new file mode 100644 index 00000000..668deab2 --- /dev/null +++ b/wm/test/systemtest/window_visibility_info_test.cpp @@ -0,0 +1,245 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// gtest +#include +#include "wm_common.h" +#include "window_manager.h" +#include "window_test_utils.h" + +using namespace testing; +using namespace testing::ext; + +namespace OHOS { +namespace Rosen { +namespace { + constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WINDOW, "WindowVisibilityInfoTest"}; +} + +using utils = WindowTestUtils; +constexpr int WAIT_ASYNC_US = 200000; // 200ms + +class VisibilityChangedListenerImpl : public IVisibilityChangedListener { +public: + void OnWindowVisibilityChanged(const std::vector>& windowVisibilityInfo) override; + std::vector> windowVisibilityInfos_; +}; + +void VisibilityChangedListenerImpl::OnWindowVisibilityChanged( + const std::vector>& windowVisibilityInfo) +{ + WLOGFI("size:%{public}zu", windowVisibilityInfo.size()); + windowVisibilityInfos_ = std::move(windowVisibilityInfo); + for (auto& info : windowVisibilityInfos_) { + WLOGFI("windowId:%{public}u, covered:%{public}d, pid:%{public}d, uid:%{public}d", info->windowId_, + info->isVisible_, info->pid_, info->uid_); + } +} + +class WindowVisibilityInfoTest : public testing::Test { +public: + static void SetUpTestCase(); + + static void TearDownTestCase(); + + virtual void SetUp() override; + + virtual void TearDown() override; + + static inline sptr visibilityChangedListener_ = new VisibilityChangedListenerImpl(); + utils::TestWindowInfo fullScreenAppInfo_; + utils::TestWindowInfo floatAppInfo_; + utils::TestWindowInfo subAppInfo_; +}; + +void WindowVisibilityInfoTest::SetUpTestCase() +{ + auto display = DisplayManager::GetInstance().GetDisplayById(0); + if (display == nullptr) { + WLOGFE("GetDefaultDisplay: failed!"); + } else { + WLOGFI("GetDefaultDisplay: id %{public}" PRIu64", w %{public}d, h %{public}d, fps %{public}u", + display->GetId(), display->GetWidth(), display->GetHeight(), display->GetFreshRate()); + } + Rect displayRect = {0, 0, + static_cast(display->GetWidth()), static_cast(display->GetHeight())}; + utils::InitByDisplayRect(displayRect); + WindowManager::GetInstance().RegisterVisibilityChangedListener(visibilityChangedListener_); +} + +void WindowVisibilityInfoTest::TearDownTestCase() +{ + WindowManager::GetInstance().UnregisterVisibilityChangedListener(visibilityChangedListener_); +} + +void WindowVisibilityInfoTest::SetUp() +{ + fullScreenAppInfo_ = { + .name = "FullWindow", + .rect = utils::customAppRect_, + .type = WindowType::WINDOW_TYPE_APP_MAIN_WINDOW, + .mode = WindowMode::WINDOW_MODE_FULLSCREEN, + .needAvoid = false, + .parentLimit = false, + .parentName = "", + }; + floatAppInfo_ = { + .name = "ParentWindow", + .rect = utils::customAppRect_, + .type = WindowType::WINDOW_TYPE_APP_MAIN_WINDOW, + .mode = WindowMode::WINDOW_MODE_FLOATING, + .needAvoid = false, + .parentLimit = false, + .parentName = "", + }; + subAppInfo_ = { + .name = "SubWindow", + .rect = utils::customAppRect_, + .type = WindowType::WINDOW_TYPE_APP_SUB_WINDOW, + .mode = WindowMode::WINDOW_MODE_FLOATING, + .needAvoid = false, + .parentLimit = false, + .parentName = "", + }; +} + +void WindowVisibilityInfoTest::TearDown() +{ +} + +namespace { +/** +* @tc.name: WindowVisibilityInfoTest01 +* @tc.desc: add main window and sub window, show and hide and test callback +* @tc.type: FUNC +*/ +HWTEST_F(WindowVisibilityInfoTest, WindowVisibilityInfoTest01, Function | MediumTest | Level1) +{ + floatAppInfo_.name = "window1"; + floatAppInfo_.rect = {250, 150, 300, 500}; + sptr window1 = utils::CreateTestWindow(floatAppInfo_); + + subAppInfo_.name = "subWindow1"; + subAppInfo_.rect = {400, 200, 100, 100}; + subAppInfo_.parentName = window1->GetWindowName(); + sptr subWindow1 = utils::CreateTestWindow(subAppInfo_); + + ASSERT_EQ(WMError::WM_OK, window1->Show()); + usleep(WAIT_ASYNC_US); + ASSERT_EQ(1, visibilityChangedListener_->windowVisibilityInfos_.size()); + + ASSERT_EQ(WMError::WM_OK, subWindow1->Show()); + usleep(WAIT_ASYNC_US); + ASSERT_EQ(1, visibilityChangedListener_->windowVisibilityInfos_.size()); + + ASSERT_EQ(WMError::WM_OK, window1->Hide()); + usleep(WAIT_ASYNC_US); + ASSERT_EQ(2, visibilityChangedListener_->windowVisibilityInfos_.size()); + + ASSERT_EQ(WMError::WM_OK, window1->Show()); + usleep(WAIT_ASYNC_US); + ASSERT_EQ(2, visibilityChangedListener_->windowVisibilityInfos_.size()); + + ASSERT_EQ(WMError::WM_OK, subWindow1->Hide()); + usleep(WAIT_ASYNC_US); + ASSERT_EQ(1, visibilityChangedListener_->windowVisibilityInfos_.size()); + + ASSERT_EQ(WMError::WM_OK, window1->Hide()); + usleep(WAIT_ASYNC_US); + ASSERT_EQ(1, visibilityChangedListener_->windowVisibilityInfos_.size()); + + ASSERT_EQ(WMError::WM_OK, window1->Show()); + usleep(WAIT_ASYNC_US); + ASSERT_EQ(1, visibilityChangedListener_->windowVisibilityInfos_.size()); + + window1->Destroy(); + subWindow1->Destroy(); +} + +/** +* @tc.name: WindowVisibilityInfoTest02 +* @tc.desc: add two fullscreen main window, test callback +* @tc.type: FUNC +*/ +HWTEST_F(WindowVisibilityInfoTest, WindowVisibilityInfoTest02, Function | MediumTest | Level1) +{ + fullScreenAppInfo_.name = "window1"; + sptr window1 = utils::CreateTestWindow(fullScreenAppInfo_); + + fullScreenAppInfo_.name = "window2"; + sptr window2 = utils::CreateTestWindow(fullScreenAppInfo_); + + ASSERT_EQ(WMError::WM_OK, window1->Show()); + usleep(WAIT_ASYNC_US); + ASSERT_EQ(2, visibilityChangedListener_->windowVisibilityInfos_.size()); + + ASSERT_EQ(WMError::WM_OK, window2->Show()); + usleep(WAIT_ASYNC_US); + ASSERT_EQ(2, visibilityChangedListener_->windowVisibilityInfos_.size()); + + window1->Destroy(); + window2->Destroy(); +} + +/** +* @tc.name: WindowVisibilityInfoTest03 +* @tc.desc: add two main window and sub windows and test callback +* @tc.type: FUNC +*/ +HWTEST_F(WindowVisibilityInfoTest, WindowVisibilityInfoTest03, Function | MediumTest | Level1) +{ + floatAppInfo_.name = "window1"; + floatAppInfo_.rect = {0, 0, 300, 600}; + sptr window1 = utils::CreateTestWindow(floatAppInfo_); + + subAppInfo_.name = "subWindow1"; + subAppInfo_.rect = {400, 200, 100, 100}; + subAppInfo_.parentName = window1->GetWindowName(); + sptr subWindow1 = utils::CreateTestWindow(subAppInfo_); + + floatAppInfo_.name = "window2"; + floatAppInfo_.rect = {50, 150, 240, 426}; + sptr window2 = utils::CreateTestWindow(floatAppInfo_); + + subAppInfo_.name = "subWindow2"; + subAppInfo_.type = WindowType::WINDOW_TYPE_MEDIA; + subAppInfo_.parentName = window2->GetWindowName(); + sptr subWindow2 = utils::CreateTestWindow(subAppInfo_); + + ASSERT_EQ(WMError::WM_OK, window2->Show()); + usleep(WAIT_ASYNC_US); + ASSERT_EQ(1, visibilityChangedListener_->windowVisibilityInfos_.size()); + + ASSERT_EQ(WMError::WM_OK, subWindow2->Show()); + usleep(WAIT_ASYNC_US); + ASSERT_EQ(1, visibilityChangedListener_->windowVisibilityInfos_.size()); + + ASSERT_EQ(WMError::WM_OK, window1->Show()); + usleep(WAIT_ASYNC_US); + ASSERT_EQ(2, visibilityChangedListener_->windowVisibilityInfos_.size()); + + ASSERT_EQ(WMError::WM_OK, subWindow1->Show()); + usleep(WAIT_ASYNC_US); + ASSERT_EQ(2, visibilityChangedListener_->windowVisibilityInfos_.size()); + + window1->Destroy(); + subWindow1->Destroy(); + window2->Destroy(); + subWindow2->Destroy(); +} +} +} // namespace Rosen +} // namespace OHOS + diff --git a/wm/test/unittest/avoid_area_controller_test.cpp b/wm/test/unittest/avoid_area_controller_test.cpp index 220d895d..2ab190ab 100644 --- a/wm/test/unittest/avoid_area_controller_test.cpp +++ b/wm/test/unittest/avoid_area_controller_test.cpp @@ -123,6 +123,37 @@ HWTEST_F(AvoidAreaControllerTest, IsAvoidAreaNode02, Function | SmallTest | Leve ASSERT_TRUE(avoidAreaController->IsAvoidAreaNode(node)); } +/** + * @tc.name: IsAvoidAreaNode03 + * @tc.desc: Create a Dock_Slice Window. Test IsAvoidAreaNode + * @tc.type: FUNC + * @tc.require: AR000GGTVD + */ +HWTEST_F(AvoidAreaControllerTest, IsAvoidAreaNode03, Function | SmallTest | Level2) +{ + auto avoidAreaController = new AvoidAreaController(nullptr); + + sptr node = new WindowNode(); + sptr property = new WindowProperty(); + property->SetWindowType(WindowType::WINDOW_TYPE_DOCK_SLICE); + node->SetWindowProperty(property); + + ASSERT_EQ(false, avoidAreaController->IsAvoidAreaNode(node)); +} + +/** + * @tc.name: IsAvoidAreaNode04 + * @tc.desc: Create a Dock_Slice Window. Test IsAvoidAreaNode + * @tc.type: FUNC + * @tc.require: AR000GGTVD + */ +HWTEST_F(AvoidAreaControllerTest, IsAvoidAreaNode04, Function | SmallTest | Level2) +{ + auto avoidAreaController = new AvoidAreaController(nullptr); + + ASSERT_EQ(false, avoidAreaController->IsAvoidAreaNode(nullptr)); +} + /** * @tc.name: AddAvoidAreaNode01 * @tc.desc: Add a new avoid area Node @@ -198,6 +229,18 @@ HWTEST_F(AvoidAreaControllerTest, AddAvoidAreaNode03, Function | SmallTest | Lev ASSERT_EQ(WMError::WM_OK, avoidAreaController->AddAvoidAreaNode(node2)); } +/** + * @tc.name: AddAvoidAreaNode04 + * @tc.desc: Add nullptr + * @tc.type: FUNC + * @tc.require: AR000GGTVD + */ +HWTEST_F(AvoidAreaControllerTest, AddAvoidAreaNode04, Function | SmallTest | Level2) +{ + sptr avoidAreaController = new AvoidAreaController(nullptr); + ASSERT_EQ(WMError::WM_ERROR_INVALID_PARAM, avoidAreaController->AddAvoidAreaNode(nullptr)); +} + /** * @tc.name: RemoveAvoidAreaNode01 * @tc.desc: Add a new avoid area. And Remove this. @@ -238,6 +281,18 @@ HWTEST_F(AvoidAreaControllerTest, RemoveAvoidAreaNode02, Function | SmallTest | ASSERT_EQ(WMError::WM_ERROR_INVALID_PARAM, avoidAreaController->RemoveAvoidAreaNode(node)); } +/** + * @tc.name: RemoveAvoidAreaNode03 + * @tc.desc: Remove nullptr + * @tc.type: FUNC + * @tc.require: AR000GGTVD + */ +HWTEST_F(AvoidAreaControllerTest, RemoveAvoidAreaNode03, Function | SmallTest | Level2) +{ + sptr avoidAreaController = new AvoidAreaController(nullptr); + ASSERT_EQ(WMError::WM_ERROR_INVALID_PARAM, avoidAreaController->RemoveAvoidAreaNode(nullptr)); +} + /** * @tc.name: UpdateAvoidAreaNode01 * @tc.desc: Add a new avoid area node and update this @@ -280,6 +335,18 @@ HWTEST_F(AvoidAreaControllerTest, UpdateAvoidAreaNode02, Function | SmallTest | ASSERT_EQ(WMError::WM_ERROR_INVALID_PARAM, avoidAreaController->UpdateAvoidAreaNode(node)); } +/** + * @tc.name: UpdateAvoidAreaNode03 + * @tc.desc: Update nullptr + * @tc.type: FUNC + * @tc.require: AR000GGTVD + */ +HWTEST_F(AvoidAreaControllerTest, UpdateAvoidAreaNode03, Function | SmallTest | Level2) +{ + sptr avoidAreaController = new AvoidAreaController(nullptr); + ASSERT_EQ(WMError::WM_ERROR_INVALID_PARAM, avoidAreaController->UpdateAvoidAreaNode(nullptr)); +} + /** * @tc.name: GetAvoidArea01 * @tc.desc: GetAvoidArea @@ -362,7 +429,6 @@ HWTEST_F(AvoidAreaControllerTest, GetAvoidArea03, Function | SmallTest | Level2) HWTEST_F(AvoidAreaControllerTest, GetAvoidAreaByType01, Function | SmallTest | Level2) { sptr avoidAreaController = new AvoidAreaController(nullptr); - std::vector avoidArea = avoidAreaController->GetAvoidAreaByType(AvoidAreaType::TYPE_CUTOUT); ASSERT_EQ(4u, static_cast(avoidArea.size())); @@ -374,7 +440,7 @@ HWTEST_F(AvoidAreaControllerTest, GetAvoidAreaByType01, Function | SmallTest | L /** * @tc.name: GetAvoidAreaByType02 - * @tc.desc: Search a unexist AvoidAreaType. And GetAvoidAreaByType + * @tc.desc: Add a new node. And GetAvoidAreaByType * @tc.type: FUNC * @tc.require: AR000GGTVD */ diff --git a/wm/test/unittest/mock_window_adapter.h b/wm/test/unittest/mock_window_adapter.h index 3535378f..8fb21504 100644 --- a/wm/test/unittest/mock_window_adapter.h +++ b/wm/test/unittest/mock_window_adapter.h @@ -33,6 +33,7 @@ public: MOCK_METHOD2(SetAlpha, WMError(uint32_t windowId, float alpha)); MOCK_METHOD2(SaveAbilityToken, WMError(const sptr& abilityToken, uint32_t windowId)); MOCK_METHOD3(SetSystemBarProperty, WMError(uint32_t windowId, WindowType type, const SystemBarProperty& property)); + MOCK_METHOD3(ResizeRect, WMError(uint32_t windowId, const Rect& rect, WindowSizeChangeReason reason)); }; } } // namespace OHOS diff --git a/wm/test/unittest/window_impl_test.cpp b/wm/test/unittest/window_impl_test.cpp index 3d0a3725..5b352be8 100644 --- a/wm/test/unittest/window_impl_test.cpp +++ b/wm/test/unittest/window_impl_test.cpp @@ -636,7 +636,7 @@ HWTEST_F(WindowImplTest, Recover01, Function | SmallTest | Level3) option->SetWindowName("WindowImplTest_Recover01"); auto window = new WindowImpl(option); std::unique_ptr m = std::make_unique(); - EXPECT_CALL(m_->Mock(), CreateWindow(_, _, _, _)).Times(1).WillOnce(Return(WMError::WM_OK)); + EXPECT_CALL(m->Mock(), CreateWindow(_, _, _, _)).Times(1).WillOnce(Return(WMError::WM_OK)); window->Create(""); EXPECT_CALL(m->Mock(), AddWindow(_)).Times(1).WillOnce(Return(WMError::WM_OK)); window->SetWindowType(WindowType::WINDOW_TYPE_APP_MAIN_WINDOW); @@ -718,6 +718,241 @@ HWTEST_F(WindowImplTest, Minimize02, Function | SmallTest | Level3) window->Minimize(); ASSERT_TRUE(window->GetShowState()); } + +/** + * @tc.name: IsSupportWideGamut01 + * @tc.desc: IsSupportWideGamut + * @tc.type: FUNC + */ +HWTEST_F(WindowImplTest, IsSupportWideGamut01, Function | SmallTest | Level3) +{ + auto option = new WindowOption(); + option->SetWindowName("WindowImplTest_IsSupportWideGamut01"); + auto window = new WindowImpl(option); + std::unique_ptr m = std::make_unique(); + EXPECT_CALL(m->Mock(), CreateWindow(_, _, _, _)).Times(1).WillOnce(Return(WMError::WM_OK)); + window->Create(""); + window->SetWindowType(WindowType::WINDOW_TYPE_APP_SUB_WINDOW); + window->SetWindowMode(WindowMode::WINDOW_MODE_FULLSCREEN); + ASSERT_TRUE(window->IsSupportWideGamut()); +} + +/** + * @tc.name: SetColorSpace01 + * @tc.desc: SetColorSpace + * @tc.type: FUNC + */ +HWTEST_F(WindowImplTest, SetColorSpace01, Function | SmallTest | Level3) +{ + auto option = new WindowOption(); + option->SetWindowName("WindowImplTest_SetColorSpace01"); + auto window = new WindowImpl(option); + std::unique_ptr m = std::make_unique(); + EXPECT_CALL(m->Mock(), CreateWindow(_, _, _, _)).Times(1).WillOnce(Return(WMError::WM_OK)); + window->Create(""); + window->SetWindowType(WindowType::WINDOW_TYPE_APP_SUB_WINDOW); + window->SetWindowMode(WindowMode::WINDOW_MODE_FULLSCREEN); + window->SetColorSpace(ColorSpace::COLOR_SPACE_WIDE_GAMUT); +} + +/** + * @tc.name: GetColorSpace01 + * @tc.desc: GetColorSpace + * @tc.type: FUNC + */ +HWTEST_F(WindowImplTest, GetColorSpace01, Function | SmallTest | Level3) +{ + auto option = new WindowOption(); + option->SetWindowName("WindowImplTest_GetColorSpace01"); + auto window = new WindowImpl(option); + std::unique_ptr m = std::make_unique(); + EXPECT_CALL(m->Mock(), CreateWindow(_, _, _, _)).Times(1).WillOnce(Return(WMError::WM_OK)); + window->Create(""); + window->SetWindowType(WindowType::WINDOW_TYPE_APP_SUB_WINDOW); + window->SetWindowMode(WindowMode::WINDOW_MODE_FULLSCREEN); + window->SetColorSpace(ColorSpace::COLOR_SPACE_DEFAULT); + ASSERT_EQ(ColorSpace::COLOR_SPACE_DEFAULT, window->GetColorSpace()); + window->SetColorSpace(ColorSpace::COLOR_SPACE_WIDE_GAMUT); + ASSERT_EQ(ColorSpace::COLOR_SPACE_WIDE_GAMUT, window->GetColorSpace()); +} + +/** + * @tc.name: MoveTo01 + * @tc.desc: create window but not show, move window, test rect + * @tc.type: FUNC + */ +HWTEST_F(WindowImplTest, MoveTo01, Function | SmallTest | Level3) +{ + sptr option = new WindowOption(); + option->SetWindowName("WindowImplTest_MoveTo01"); + option->SetWindowMode(WindowMode::WINDOW_MODE_FLOATING); + Rect winRect = {10, 20, 30u, 40u}; // set window rect: 10, 20, 30, 40 + option->SetWindowRect(winRect); + sptr window = new WindowImpl(option); + std::unique_ptr m = std::make_unique(); + + EXPECT_CALL(m->Mock(), CreateWindow(_, _, _, _)).Times(1).WillOnce(Return(WMError::WM_OK)); + ASSERT_EQ(WMError::WM_OK, window->Create("")); + ASSERT_EQ(WindowMode::WINDOW_MODE_FLOATING, window->GetMode()); + ASSERT_FALSE(window->GetShowState()); + const float moveRatio = 0.5; + Rect newRect = {winRect.posX_ * moveRatio, winRect.posY_ * moveRatio, winRect.width_, winRect.height_}; + window->MoveTo(newRect.posX_, newRect.posY_); + ASSERT_EQ(newRect, window->GetRect()); + EXPECT_CALL(m->Mock(), DestroyWindow(_)).Times(1).WillOnce(Return(WMError::WM_OK)); + ASSERT_EQ(WMError::WM_OK, window->Destroy()); +} + +/** + * @tc.name: MoveTo02 + * @tc.desc: create and show window, move mvoe window return WM_ERROR_SAMGR, test rect + * @tc.type: FUNC + */ +HWTEST_F(WindowImplTest, MoveTo02, Function | SmallTest | Level3) +{ + sptr option = new WindowOption(); + option->SetWindowName("WindowImplTest_MoveTo02"); + option->SetWindowMode(WindowMode::WINDOW_MODE_FLOATING); + Rect winRect = {10, 20, 30u, 40u}; // set window rect: 10, 20, 30, 40 + option->SetWindowRect(winRect); + sptr window = new WindowImpl(option); + std::unique_ptr m = std::make_unique(); + + EXPECT_CALL(m->Mock(), CreateWindow(_, _, _, _)).Times(1).WillOnce(Return(WMError::WM_OK)); + ASSERT_EQ(WMError::WM_OK, window->Create("")); + EXPECT_CALL(m->Mock(), AddWindow(_)).Times(1).WillOnce(Return(WMError::WM_OK)); + window->Show(); + ASSERT_TRUE(window->GetShowState()); + EXPECT_CALL(m->Mock(), ResizeRect(_, _, _)).Times(1).WillOnce(Return(WMError::WM_ERROR_SAMGR)); + const float moveRatio = 0.5; + Rect newRect = {winRect.posX_ * moveRatio, winRect.posY_ * moveRatio, winRect.width_, winRect.height_}; + window->MoveTo(newRect.posX_, newRect.posY_); + ASSERT_EQ(winRect, window->GetRect()); + EXPECT_CALL(m->Mock(), DestroyWindow(_)).Times(1).WillOnce(Return(WMError::WM_OK)); + ASSERT_EQ(WMError::WM_OK, window->Destroy()); +} + +/** + * @tc.name: Resize01 + * @tc.desc: create window but not show, resize window, test rect + * @tc.type: FUNC + */ +HWTEST_F(WindowImplTest, Resize01, Function | SmallTest | Level3) +{ + sptr option = new WindowOption(); + option->SetWindowName("WindowImplTest_Resize01"); + option->SetWindowMode(WindowMode::WINDOW_MODE_FLOATING); + Rect winRect = {10, 20, 30u, 40u}; // set window rect: 10, 20, 30, 40 + option->SetWindowRect(winRect); + sptr window = new WindowImpl(option); + std::unique_ptr m = std::make_unique(); + + EXPECT_CALL(m->Mock(), CreateWindow(_, _, _, _)).Times(1).WillOnce(Return(WMError::WM_OK)); + ASSERT_EQ(WMError::WM_OK, window->Create("")); + ASSERT_EQ(WindowMode::WINDOW_MODE_FLOATING, window->GetMode()); + ASSERT_FALSE(window->GetShowState()); + const float resizeRatio = 0.5; + Rect newRect = {winRect.posX_, winRect.posY_, winRect.width_ * resizeRatio, winRect.height_ * resizeRatio}; + window->Resize(newRect.width_, newRect.height_); + ASSERT_EQ(newRect, window->GetRect()); + EXPECT_CALL(m->Mock(), DestroyWindow(_)).Times(1).WillOnce(Return(WMError::WM_OK)); + ASSERT_EQ(WMError::WM_OK, window->Destroy()); +} + +/** + * @tc.name: Resize02 + * @tc.desc: create and show window, mock resize window return WM_ERROR_SAMGR, test rect + * @tc.type: FUNC + */ +HWTEST_F(WindowImplTest, Resize02, Function | SmallTest | Level3) +{ + sptr option = new WindowOption(); + option->SetWindowName("WindowImplTest_Resize02"); + option->SetWindowMode(WindowMode::WINDOW_MODE_FLOATING); + Rect winRect = {10, 20, 30u, 40u}; // set window rect: 10, 20, 30, 40 + option->SetWindowRect(winRect); + sptr window = new WindowImpl(option); + std::unique_ptr m = std::make_unique(); + + EXPECT_CALL(m->Mock(), CreateWindow(_, _, _, _)).Times(1).WillOnce(Return(WMError::WM_OK)); + ASSERT_EQ(WMError::WM_OK, window->Create("")); + EXPECT_CALL(m->Mock(), AddWindow(_)).Times(1).WillOnce(Return(WMError::WM_OK)); + window->Show(); + ASSERT_TRUE(window->GetShowState()); + EXPECT_CALL(m->Mock(), ResizeRect(_, _, _)).Times(1).WillOnce(Return(WMError::WM_ERROR_SAMGR)); + const float resizeRatio = 0.5; + Rect newRect = {winRect.posX_, winRect.posY_, winRect.width_ * resizeRatio, winRect.height_ * resizeRatio}; + window->Resize(newRect.width_, newRect.height_); + ASSERT_EQ(winRect, window->GetRect()); + EXPECT_CALL(m->Mock(), DestroyWindow(_)).Times(1).WillOnce(Return(WMError::WM_OK)); + ASSERT_EQ(WMError::WM_OK, window->Destroy()); +} + +/** + * @tc.name: StartMove01 + * @tc.desc: start move main fullscreen window, test startMoveFlag + * @tc.type: FUNC + */ +HWTEST_F(WindowImplTest, StartMove01, Function | SmallTest | Level3) +{ + sptr option = new WindowOption(); + option->SetWindowName("WindowImplTest_StartMove01"); + option->SetWindowMode(WindowMode::WINDOW_MODE_FULLSCREEN); + sptr window = new WindowImpl(option); + std::unique_ptr m = std::make_unique(); + + EXPECT_CALL(m->Mock(), CreateWindow(_, _, _, _)).Times(1).WillOnce(Return(WMError::WM_OK)); + ASSERT_EQ(WMError::WM_OK, window->Create("")); + EXPECT_CALL(m->Mock(), AddWindow(_)).Times(1).WillOnce(Return(WMError::WM_OK)); + window->Show(); + window->StartMove(); + ASSERT_FALSE(window->startMoveFlag_); +} + +/** + * @tc.name: StartMove02 + * @tc.desc: start move main fullscreen window, test startMoveFlag + * @tc.type: FUNC + */ +HWTEST_F(WindowImplTest, StartMove02, Function | SmallTest | Level3) +{ + sptr option = new WindowOption(); + option->SetWindowName("WindowImplTest_StartMove02"); + option->SetWindowMode(WindowMode::WINDOW_MODE_FLOATING); + option->SetWindowType(WindowType::WINDOW_TYPE_APP_MAIN_WINDOW); + sptr window = new WindowImpl(option); + std::unique_ptr m = std::make_unique(); + + EXPECT_CALL(m->Mock(), CreateWindow(_, _, _, _)).Times(1).WillOnce(Return(WMError::WM_OK)); + ASSERT_EQ(WMError::WM_OK, window->Create("")); + EXPECT_CALL(m->Mock(), AddWindow(_)).Times(1).WillOnce(Return(WMError::WM_OK)); + window->Show(); + + window->StartMove(); + ASSERT_TRUE(window->startMoveFlag_); +} + +/** + * @tc.name: StartMove03 + * @tc.desc: start move divider, test startMoveFlag + * @tc.type: FUNC + */ +HWTEST_F(WindowImplTest, StartMove03, Function | SmallTest | Level3) +{ + sptr option = new WindowOption(); + option->SetWindowName("WindowImplTest_StartMove03"); + option->SetWindowMode(WindowMode::WINDOW_MODE_FLOATING); + option->SetWindowType(WindowType::WINDOW_TYPE_DOCK_SLICE); + sptr window = new WindowImpl(option); + std::unique_ptr m = std::make_unique(); + + EXPECT_CALL(m->Mock(), CreateWindow(_, _, _, _)).Times(1).WillOnce(Return(WMError::WM_OK)); + ASSERT_EQ(WMError::WM_OK, window->Create("")); + EXPECT_CALL(m->Mock(), AddWindow(_)).Times(1).WillOnce(Return(WMError::WM_OK)); + window->Show(); + window->StartMove(); + ASSERT_FALSE(window->startMoveFlag_); +} } } // namespace Rosen } // namespace OHOS diff --git a/wmserver/BUILD.gn b/wmserver/BUILD.gn index 1f438fb3..06b7514c 100644 --- a/wmserver/BUILD.gn +++ b/wmserver/BUILD.gn @@ -12,6 +12,7 @@ # limitations under the License. import("//build/ohos.gni") +import("//foundation/graphic/standard/graphic_config.gni") ## Build libwms.so config("libwms_config") { @@ -28,14 +29,10 @@ config("libwms_config") { "//foundation/windowmanager/dm/include", "//foundation/windowmanager/dmserver/include", ] + defines = [] - if ("${product_name}" == "rk3566" || "${product_name}" == "rk3568" || - "${product_name}" == "Hi3516DV300" || "${product_name}" == "ohos-arm64" || - "${product_name}" == "watchos") { - defines = [ "ACE_DISABLE_GL" ] - } else { - defines = [ "ACE_ENABLE_GL" ] - } + # Get gpu defines + defines += gpu_defines } ohos_prebuilt_etc("window_divider_image") { @@ -75,6 +72,7 @@ ohos_shared_library("libwms") { ":window_divider_image", "//foundation/ace/ace_engine/build/external_config/flutter/skia:ace_skia_ohos", "//foundation/graphic/standard/rosen/modules/render_service_client:librender_service_client", + "//foundation/windowmanager/dm:libdm", "//foundation/windowmanager/dmserver:libdms", "//foundation/windowmanager/utils:libwmutil", "//foundation/windowmanager/wm:libwm", @@ -92,6 +90,7 @@ ohos_shared_library("libwms") { "ces_standard:cesfwk_innerkits", "graphic_standard:surface", "hilog_native:libhilog", + "hisysevent_native:libhisysevent", "ipc:ipc_core", "multimodalinput_base:libmmi-client", "safwk:system_ability_fwk", @@ -108,3 +107,8 @@ ohos_shared_library("libwms") { part_name = "window_manager" subsystem_name = "window" } + +group("test") { + testonly = true + deps = [ "test:test" ] +} diff --git a/wmserver/include/avoid_area_controller.h b/wmserver/include/avoid_area_controller.h index 375570bb..a5c9d4e4 100644 --- a/wmserver/include/avoid_area_controller.h +++ b/wmserver/include/avoid_area_controller.h @@ -51,10 +51,6 @@ public: private: std::map> avoidNodes_; // key: windowId - const std::set avoidType_ { - WindowType::WINDOW_TYPE_STATUS_BAR, - WindowType::WINDOW_TYPE_NAVIGATION_BAR, - }; UpdateAvoidAreaFunc updateAvoidAreaCallBack_; void UseCallbackNotifyAvoidAreaChanged(std::vector& avoidArea) const; void DumpAvoidArea(const std::vector& avoidArea) const; diff --git a/wmserver/include/drag_controller.h b/wmserver/include/drag_controller.h index f0a94f26..5b463438 100644 --- a/wmserver/include/drag_controller.h +++ b/wmserver/include/drag_controller.h @@ -31,7 +31,7 @@ public: void UpdateDragInfo(uint32_t windowId); void FinishDrag(uint32_t windowId); private: - sptr GetHitWindow(PointInfo point); + sptr GetHitWindow(DisplayId id, const PointInfo point); bool GetHitPoint(uint32_t windowId, PointInfo& point); sptr windowRoot_; uint64_t hitWindowId_ = 0; diff --git a/wmserver/include/window_controller.h b/wmserver/include/window_controller.h index 79e3d2c6..0217a4d2 100644 --- a/wmserver/include/window_controller.h +++ b/wmserver/include/window_controller.h @@ -49,7 +49,9 @@ public: void NotifyDisplayStateChange(DisplayId id, DisplayStateChangeType type); WMError ProcessWindowTouchedEvent(uint32_t windowId); void MinimizeAllAppWindows(DisplayId displayId); + WMError MaxmizeWindow(uint32_t windowId); WMError SetWindowLayoutMode(DisplayId displayId, WindowLayoutMode mode); + void NotifySystemBarTints(); private: uint32_t GenWindowId(); @@ -57,6 +59,7 @@ private: void FlushWindowInfoWithDisplayId(DisplayId displayId); void UpdateWindowAnimation(const sptr& node); void ProcessDisplayChange(DisplayId displayId, DisplayStateChangeType type); + void StopBootAnimationIfNeed(WindowType type) const; sptr windowRoot_; sptr inputWindowMonitor_; diff --git a/wmserver/include/window_inner_manager.h b/wmserver/include/window_inner_manager.h index 43335f9a..83ecbf39 100644 --- a/wmserver/include/window_inner_manager.h +++ b/wmserver/include/window_inner_manager.h @@ -27,7 +27,7 @@ #endif #include "transaction/rs_transaction.h" #include "ui/rs_surface_extractor.h" -#include "single_instance.h" +#include "wm_single_instance.h" #include "singleton_delegator.h" #include "window.h" #include "wm_common.h" @@ -51,10 +51,10 @@ WM_DECLARE_SINGLE_INSTANCE(WindowInnerManager); public: void Init(); void SendMessage(InnerWMCmd cmdType, DisplayId displayId = 0); - void HandleMessage(); private: static inline SingletonDelegator delegator; + void HandleMessage(); sptr CreateWindow(DisplayId displayId, const WindowType& type, const Rect& rect); void CreateAndShowDivider(std::unique_ptr msg); void HideAndDestroyDivider(std::unique_ptr msg); diff --git a/wmserver/include/window_layout_policy.h b/wmserver/include/window_layout_policy.h index d2b0fc7a..20738683 100644 --- a/wmserver/include/window_layout_policy.h +++ b/wmserver/include/window_layout_policy.h @@ -50,6 +50,7 @@ public: virtual void UpdateWindowNode(sptr& node); virtual void UpdateLayoutRect(sptr& node) = 0; void UpdateDefaultFoatingRect(); + float GetVirtualPixelRatio() const; protected: const Rect& displayRect_; @@ -66,6 +67,7 @@ protected: void UpdateLimitRect(const sptr& node, Rect& limitRect); virtual void LayoutWindowNode(sptr& node); AvoidPosType GetAvoidPosType(const Rect& rect); + void CalcAndSetNodeHotZone(Rect layoutOutRect, sptr& node); void LimitWindowSize(const sptr& node, const Rect& displayRect, Rect& winRect); void SetRectForFloating(const sptr& node); Rect ComputeDecoratedWindowRect(const Rect& winRect); diff --git a/wmserver/include/window_layout_policy_tile.h b/wmserver/include/window_layout_policy_tile.h index 37e02e1b..87995989 100644 --- a/wmserver/include/window_layout_policy_tile.h +++ b/wmserver/include/window_layout_policy_tile.h @@ -17,6 +17,7 @@ #define OHOS_ROSEN_WINDOW_LAYOUT_POLICY_TILE_H #include +#include #include #include @@ -34,20 +35,21 @@ public: ~WindowLayoutPolicyTile() = default; void Launch() override; void AddWindowNode(sptr& node) override; + void RemoveWindowNode(sptr& node) override; void UpdateLayoutRect(sptr& node) override; private: Rect singleRect_ = { 0, 0, 0, 0 }; std::vector doubleRects_ = std::vector(2); std::vector tripleRects_ = std::vector(3); - std::vector> foregroundNodes_; - uint32_t lastForegroundNodeId_ = 0; + std::deque> foregroundNodes_; void UpdateDisplayInfo() override; void InitTileWindowRects(); void AssignNodePropertyForTileWindows(); void LayoutForegroundNodeQueue(); void InitForegroundNodeQueue(); - void UpdateForegroundNodeQueue(sptr& node); + void ForegroundNodeQueuePushBack(sptr& node); + void ForegroundNodeQueueRemove(sptr& node); }; } } diff --git a/wmserver/include/window_manager_agent_controller.h b/wmserver/include/window_manager_agent_controller.h index 9f99bf31..1f6204ac 100644 --- a/wmserver/include/window_manager_agent_controller.h +++ b/wmserver/include/window_manager_agent_controller.h @@ -35,6 +35,7 @@ public: DisplayId displayId, bool focused); void UpdateSystemBarRegionTints(DisplayId displayId, const SystemBarRegionTints& tints); void UpdateWindowStatus(const sptr& windowInfo, WindowUpdateType type); + void UpdateWindowVisibilityInfo(const std::vector>& windowVisibilityInfos); private: WindowManagerAgentController() {} diff --git a/wmserver/include/window_manager_interface.h b/wmserver/include/window_manager_interface.h index 146534b5..5e063d3e 100644 --- a/wmserver/include/window_manager_interface.h +++ b/wmserver/include/window_manager_interface.h @@ -48,12 +48,10 @@ public: TRANS_ID_GET_TOP_WINDOW_ID, TRANS_ID_PROCESS_WINDOW_TOUCHED_EVENT, TRANS_ID_MINIMIZE_ALL_APP_WINDOWS, - TRANS_ID_IS_SUPPORT_WIDE_GAMUT, // wide gamut - TRANS_ID_SET_COLOR_SPACE, // set color space - TRANS_ID_GET_COLOR_SPACE, // get color space TRANS_ID_SET_BACKGROUND_BLUR, TRANS_ID_SET_APLPHA, TRANS_ID_UPDATE_LAYOUT_MODE, + TRANS_ID_MAXMIZE_WINDOW, }; virtual WMError CreateWindow(sptr& window, sptr& property, const std::shared_ptr& surfaceNode, uint32_t& windowId) = 0; @@ -75,13 +73,9 @@ public: virtual WMError GetTopWindowId(uint32_t mainWinId, uint32_t& topWinId) = 0; virtual void ProcessWindowTouchedEvent(uint32_t windowId) = 0; virtual void MinimizeAllAppWindows(DisplayId displayId) = 0; + virtual WMError MaxmizeWindow(uint32_t windowId) = 0; virtual WMError SetWindowLayoutMode(DisplayId displayId, WindowLayoutMode mode) = 0; - // colorspace, gamut - virtual bool IsSupportWideGamut(uint32_t windowId) = 0; - virtual void SetColorSpace(uint32_t windowId, ColorSpace colorSpace) = 0; - virtual ColorSpace GetColorSpace(uint32_t windowId) = 0; - virtual void RegisterWindowManagerAgent(WindowManagerAgentType type, const sptr& windowManagerAgent) = 0; virtual void UnregisterWindowManagerAgent(WindowManagerAgentType type, diff --git a/wmserver/include/window_manager_proxy.h b/wmserver/include/window_manager_proxy.h index 0687b07a..00590c5b 100644 --- a/wmserver/include/window_manager_proxy.h +++ b/wmserver/include/window_manager_proxy.h @@ -47,13 +47,9 @@ public: WMError GetTopWindowId(uint32_t mainWinId, uint32_t& topWinId) override; void ProcessWindowTouchedEvent(uint32_t windowId) override; void MinimizeAllAppWindows(DisplayId displayId) override; + WMError MaxmizeWindow(uint32_t windowId) override; WMError SetWindowLayoutMode(DisplayId displayId, WindowLayoutMode mode) override; - // colorspace, gamut - virtual bool IsSupportWideGamut(uint32_t windowId) override; - virtual void SetColorSpace(uint32_t windowId, ColorSpace colorSpace) override; - virtual ColorSpace GetColorSpace(uint32_t windowId) override; - void RegisterWindowManagerAgent(WindowManagerAgentType type, const sptr& windowManagerAgent) override; void UnregisterWindowManagerAgent(WindowManagerAgentType type, diff --git a/wmserver/include/window_manager_service.h b/wmserver/include/window_manager_service.h index 0f671929..5fe7ac3f 100644 --- a/wmserver/include/window_manager_service.h +++ b/wmserver/include/window_manager_service.h @@ -21,7 +21,6 @@ #include #include -#include #include #include "display_change_listener.h" #include "drag_controller.h" @@ -67,13 +66,9 @@ public: void ProcessWindowTouchedEvent(uint32_t windowId) override; WMError GetTopWindowId(uint32_t mainWinId, uint32_t& topWinId) override; void MinimizeAllAppWindows(DisplayId displayId) override; + WMError MaxmizeWindow(uint32_t windowId) override; WMError SetWindowLayoutMode(DisplayId displayId, WindowLayoutMode mode) override; - // colorspace, gamut - virtual bool IsSupportWideGamut(uint32_t windowId) override; - virtual void SetColorSpace(uint32_t windowId, ColorSpace colorSpace) override; - virtual ColorSpace GetColorSpace(uint32_t windowId) override; - void RegisterWindowManagerAgent(WindowManagerAgentType type, const sptr& windowManagerAgent) override; void UnregisterWindowManagerAgent(WindowManagerAgentType type, diff --git a/wmserver/include/window_node.h b/wmserver/include/window_node.h index 863b89eb..dad5f132 100644 --- a/wmserver/include/window_node.h +++ b/wmserver/include/window_node.h @@ -42,6 +42,7 @@ public: void SetDisplayId(DisplayId displayId); void SetLayoutRect(const Rect& rect); + void SetHotZoneRect(const Rect& rect); void SetWindowRect(const Rect& rect); void SetWindowProperty(const sptr& property); void SetSystemBarProperty(WindowType type, const SystemBarProperty& property); @@ -75,12 +76,14 @@ public: int32_t priority_ { 0 }; bool requestedVisibility_ { false }; bool currentVisibility_ { false }; - bool hasDecorated_ = false; + bool hasDecorated_ { false }; + bool isCovered_ { true }; // initial value true to ensure notification when this window is shown private: sptr property_; sptr windowToken_; Rect layoutRect_ { 0, 0, 0, 0 }; + Rect hotZoneRect_ { 0, 0, 0, 0 }; int32_t callingPid_; int32_t callingUid_; WindowSizeChangeReason windowSizeChangeReason_ {WindowSizeChangeReason::UNDEFINED}; diff --git a/wmserver/include/window_node_container.h b/wmserver/include/window_node_container.h index 298f3cff..bf5cd5fe 100644 --- a/wmserver/include/window_node_container.h +++ b/wmserver/include/window_node_container.h @@ -27,13 +27,14 @@ namespace OHOS { namespace Rosen { +using WindowNodeOperationFunc = std::function)>; // return true indicates to stop traverse class WindowNodeContainer : public RefBase { public: WindowNodeContainer(DisplayId displayId, uint32_t width, uint32_t height); ~WindowNodeContainer(); WMError AddWindowNode(sptr& node, sptr& parentNode); WMError RemoveWindowNode(sptr& node); - WMError UpdateWindowNode(sptr& node); + WMError UpdateWindowNode(sptr& node, WindowUpdateReason reason); WMError DestroyWindowNode(sptr& node, std::vector& windowIds); const std::vector& Destroy(); void AssignZOrder(); @@ -50,24 +51,24 @@ public: void UpdateDisplayRect(uint32_t width, uint32_t height); void OnAvoidAreaChange(const std::vector& avoidAreas); - void LayoutDividerWindow(sptr& node); bool isVerticalDisplay() const; WMError RaiseZOrderForAppWindow(sptr& node, sptr& parentNode); sptr GetNextFocusableWindow(uint32_t windowId) const; void MinimizeAllAppWindows(); void NotifyWindowStateChange(WindowState state, WindowStateChangeReason reason); + void NotifySystemBarTints(); + void NotifySystemBarDismiss(sptr& node); WMError MinimizeAppNodeExceptOptions(const std::vector &exceptionalIds = {}, const std::vector &exceptionalModes = {}); WMError EnterSplitWindowMode(sptr& node); WMError ExitSplitWindowMode(sptr& node); WMError SwitchLayoutPolicy(WindowLayoutMode mode, bool reorder = false); + void RaiseSplitRelatedWindowToTop(sptr& node); void MoveWindowNode(sptr& container); - sptr GetBelowAppWindowNode() const; - sptr GetAppWindowNode() const; - sptr GetAboveAppWindowNode() const; + float GetVirtualPixelRatio() const; + void TraverseWindowTree(const WindowNodeOperationFunc& func, bool isFromTopToBottom = true) const; private: - void AssignZOrder(sptr& node); void TraverseWindowNode(sptr& root, std::vector>& windowNodes) const; sptr FindRoot(WindowType type) const; sptr FindWindowNodeById(uint32_t id) const; @@ -85,11 +86,16 @@ private: bool IsTopAppWindow(uint32_t windowId) const; sptr FindDividerNode() const; void RaiseWindowToTop(uint32_t windowId, std::vector>& windowNodes); - void RaiseZOrderForSplitWindow(sptr& node); void MinimizeWindowFromAbility(const sptr& node); void ResetLayoutPolicy(); bool IsFullImmersiveNode(sptr node) const; bool IsSplitImmersiveNode(sptr node) const; + bool TraverseFromTopToBottom(sptr node, const WindowNodeOperationFunc& func) const; + bool TraverseFromBottomToTop(sptr node, const WindowNodeOperationFunc& func) const; + + // cannot determine in case of a window covered by union of several windows or with transparent value + void UpdateWindowVisibilityInfos(std::vector>& infos); + void RaiseOrderedWindowToTop(std::vector orderedIds, std::vector>& windowNodes); sptr avoidController_; sptr zorderPolicy_ = new WindowZorderPolicy(); @@ -99,6 +105,7 @@ private: std::vector removedIds_; DisplayId displayId_ = 0; Rect displayRect_; + std::vector currentCoveredArea_; std::unordered_map> sysBarNodeMap_ { { WindowType::WINDOW_TYPE_STATUS_BAR, nullptr }, { WindowType::WINDOW_TYPE_NAVIGATION_BAR, nullptr }, @@ -121,7 +128,9 @@ private: std::unordered_map pairedWindowMap_; void RaiseInputMethodWindowPriorityIfNeeded(const sptr& node) const; const int32_t WINDOW_TYPE_RAISED_INPUT_METHOD = 115; + + static bool ReadIsWindowAnimationEnabledProperty(); }; -} -} +} // namespace Rosen +} // namespace OHOS #endif // OHOS_ROSEN_WINDOW_NODE_CONTAINER_H diff --git a/wmserver/include/window_root.h b/wmserver/include/window_root.h index b784adf3..7abcee06 100644 --- a/wmserver/include/window_root.h +++ b/wmserver/include/window_root.h @@ -44,7 +44,7 @@ public: WMError AddWindowNode(uint32_t parentId, sptr& node); WMError RemoveWindowNode(uint32_t windowId); WMError DestroyWindow(uint32_t windowId, bool onlySelf); - WMError UpdateWindowNode(uint32_t windowId); + WMError UpdateWindowNode(uint32_t windowId, WindowUpdateReason reason); bool isVerticalDisplay(sptr& node) const; WMError RequestFocus(uint32_t windowId); @@ -55,24 +55,30 @@ public: std::shared_ptr GetSurfaceNodeByAbilityToken(const sptr& abilityToken) const; WMError GetTopWindowId(uint32_t mainWinId, uint32_t& topWinId); void MinimizeAllAppWindows(DisplayId displayId); + WMError MaxmizeWindow(uint32_t windowId); WMError SetWindowLayoutMode(DisplayId displayId, WindowLayoutMode mode); void NotifyWindowStateChange(WindowState state, WindowStateChangeReason reason); void NotifyDisplayChange(sptr abstractDisplay); - void NotifyDisplayDestory(DisplayId displayId); + void NotifyDisplayDestroy(DisplayId displayId); + void NotifySystemBarTints(); WMError RaiseZOrderForAppWindow(sptr& node); + void FocusFaultDetection() const; + float GetVirtualPixelRatio(DisplayId displayId) const; private: void OnRemoteDied(const sptr& remoteObject); WMError DestroyWindowInner(sptr& node); void UpdateFocusWindowWithWindowRemoved(const sptr& node, const sptr& container) const; + std::string GenAllWindowsLogInfo() const; bool CheckDisplayInfo(const sptr& display); std::recursive_mutex& mutex_; std::map> windowNodeContainerMap_; std::map> windowNodeMap_; std::map, uint32_t> windowIdMap_; + bool needCheckFocusWindow = false; std::map>> windowManagerAgents_; diff --git a/wmserver/include/window_snapshot/snapshot_controller.h b/wmserver/include/window_snapshot/snapshot_controller.h index 2f5ce9ad..7fc60fd3 100644 --- a/wmserver/include/window_snapshot/snapshot_controller.h +++ b/wmserver/include/window_snapshot/snapshot_controller.h @@ -46,8 +46,8 @@ private: void OnSurfaceCapture(std::shared_ptr pixelmap) override { if (flag_ == false) { - flag_ = true; pixelMap_ = pixelmap; + flag_ = true; } } bool IsPixelMapOk() diff --git a/wmserver/include/window_zorder_policy.h b/wmserver/include/window_zorder_policy.h index 59647549..17e87476 100644 --- a/wmserver/include/window_zorder_policy.h +++ b/wmserver/include/window_zorder_policy.h @@ -59,6 +59,7 @@ private: { WindowType::WINDOW_TYPE_KEYGUARD, 114 }, { WindowType::WINDOW_TYPE_DRAGGING_EFFECT, 115 }, { WindowType::WINDOW_TYPE_POINTER, 116 }, + { WindowType::WINDOW_TYPE_BOOT_ANIMATION, 117 }, }; }; } diff --git a/wmserver/src/avoid_area_controller.cpp b/wmserver/src/avoid_area_controller.cpp index b56d28d1..eb3a4456 100644 --- a/wmserver/src/avoid_area_controller.cpp +++ b/wmserver/src/avoid_area_controller.cpp @@ -14,6 +14,7 @@ */ #include "avoid_area_controller.h" +#include "window_helper.h" #include "window_manager_hilog.h" #include "wm_trace.h" @@ -27,10 +28,17 @@ const int32_t AVOID_NUM = 4; bool AvoidAreaController::IsAvoidAreaNode(const sptr& node) const { - if (avoidType_.find(node->GetWindowType()) != avoidType_.end()) { - return true; + if (node == nullptr) { + WLOGFE("IsAvoidAreaNode Failed, node is nullprt"); + return false; } - return false; + + if (!WindowHelper::IsAvoidAreaWindow(node->GetWindowType())) { + WLOGFE("IsAvoidAreaNode Failed, node type is not avoid type"); + return false; + } + + return true; } static AvoidPos GetAvoidPosType(const Rect& rect) @@ -54,6 +62,11 @@ static AvoidPos GetAvoidPosType(const Rect& rect) WMError AvoidAreaController::AddAvoidAreaNode(const sptr& node) { WM_FUNCTION_TRACE(); + if (!IsAvoidAreaNode(node)) { + WLOGFE("AddAvoidAreaNode check param Failed."); + return WMError::WM_ERROR_INVALID_PARAM; + } + uint32_t windowId = node->GetWindowId(); auto iter = avoidNodes_.find(windowId); if (iter != avoidNodes_.end()) { @@ -75,6 +88,11 @@ WMError AvoidAreaController::AddAvoidAreaNode(const sptr& node) WMError AvoidAreaController::RemoveAvoidAreaNode(const sptr& node) { WM_FUNCTION_TRACE(); + if (!IsAvoidAreaNode(node)) { + WLOGFE("RemoveAvoidAreaNode check param Failed."); + return WMError::WM_ERROR_INVALID_PARAM; + } + uint32_t windowId = node->GetWindowId(); auto iter = avoidNodes_.find(windowId); if (iter == avoidNodes_.end()) { @@ -96,6 +114,11 @@ WMError AvoidAreaController::RemoveAvoidAreaNode(const sptr& node) WMError AvoidAreaController::UpdateAvoidAreaNode(const sptr& node) { WM_FUNCTION_TRACE(); + if (!IsAvoidAreaNode(node)) { + WLOGFE("UpdateAvoidAreaNode check param Failed."); + return WMError::WM_ERROR_INVALID_PARAM; + } + uint32_t windowId = node->GetWindowId(); auto iter = avoidNodes_.find(windowId); if (iter == avoidNodes_.end()) { diff --git a/wmserver/src/drag_controller.cpp b/wmserver/src/drag_controller.cpp index 37e95d28..927cfb5e 100644 --- a/wmserver/src/drag_controller.cpp +++ b/wmserver/src/drag_controller.cpp @@ -17,7 +17,6 @@ #include #include "display.h" -#include "display_manager_service_inner.h" #include "window_helper.h" #include "window_manager_hilog.h" #include "window_node.h" @@ -37,7 +36,11 @@ void DragController::UpdateDragInfo(uint32_t windowId) if (!GetHitPoint(windowId, point)) { return; } - sptr hitWindowNode = GetHitWindow(point); + sptr dragNode = windowRoot_->GetWindowNode(windowId); + if (dragNode == nullptr) { + return; + } + sptr hitWindowNode = GetHitWindow(dragNode->GetDisplayId(), point); if (hitWindowNode == nullptr) { WLOGFE("Get point failed %{public}d %{public}d", point.x, point.y); return; @@ -61,7 +64,11 @@ void DragController::StartDrag(uint32_t windowId) WLOGFE("Get hit point failed"); return; } - sptr hitWindow = GetHitWindow(point); + sptr dragNode = windowRoot_->GetWindowNode(windowId); + if (dragNode == nullptr) { + return; + } + sptr hitWindow = GetHitWindow(dragNode->GetDisplayId(), point); if (hitWindow == nullptr) { WLOGFE("Get point failed %{public}d %{public}d", point.x, point.y); return; @@ -92,15 +99,13 @@ void DragController::FinishDrag(uint32_t windowId) WLOGFI("end drag"); } -sptr DragController::GetHitWindow(PointInfo point) +sptr DragController::GetHitWindow(DisplayId id, PointInfo point) { // TODO get display by point - DisplayId id = DisplayManagerServiceInner::GetInstance().GetDefaultDisplayId(); if (id == DISPLAY_ID_INVALD) { - WLOGFE("get invalid display"); + WLOGFE("Get invalid display"); return nullptr; } - sptr container = windowRoot_->GetOrCreateWindowNodeContainer(id); if (container == nullptr) { WLOGFE("get container failed %{public}" PRIu64"", id); diff --git a/wmserver/src/input_window_monitor.cpp b/wmserver/src/input_window_monitor.cpp index 4b921aa4..393659c4 100644 --- a/wmserver/src/input_window_monitor.cpp +++ b/wmserver/src/input_window_monitor.cpp @@ -79,19 +79,24 @@ void InputWindowMonitor::UpdateInputWindowByDisplayId(DisplayId displayId) void InputWindowMonitor::UpdateDisplaysInfo(const sptr& container, DisplayId displayId) { + sptr screenMode = + DisplayManagerServiceInner::GetInstance().GetScreenModesByDisplayId(displayId); + if (screenMode == nullptr) { + return; + } MMI::PhysicalDisplayInfo physicalDisplayInfo = { .id = static_cast(container->GetScreenId()), .leftDisplayId = static_cast(DISPLAY_ID_INVALD), .upDisplayId = static_cast(DISPLAY_ID_INVALD), - .topLeftX = container->GetDisplayRect().posX_, - .topLeftY = container->GetDisplayRect().posY_, - .width = static_cast(container->GetDisplayRect().width_), - .height = static_cast(container->GetDisplayRect().height_), + .topLeftX = 0, + .topLeftY = 0, + .width = static_cast(screenMode->width_), + .height = static_cast(screenMode->height_), .name = "physical_display0", .seatId = "seat0", .seatName = "default0", - .logicWidth = static_cast(container->GetDisplayRect().width_), - .logicHeight = static_cast(container->GetDisplayRect().height_), + .logicWidth = static_cast(screenMode->width_), + .logicHeight = static_cast(screenMode->height_), }; UpdateDisplayDirection(physicalDisplayInfo, displayId); auto physicalDisplayIter = std::find_if(physicalDisplays_.begin(), physicalDisplays_.end(), @@ -158,7 +163,7 @@ void InputWindowMonitor::TraverseWindowNodes(const std::vector> void InputWindowMonitor::UpdateDisplayDirection(MMI::PhysicalDisplayInfo& physicalDisplayInfo, DisplayId displayId) { - Rotation rotation = DisplayManagerServiceInner::GetInstance().GetScreenInfoByDisplayId(displayId)->rotation_; + Rotation rotation = DisplayManagerServiceInner::GetInstance().GetScreenInfoByDisplayId(displayId)->GetRotation(); switch (rotation) { case Rotation::ROTATION_0: physicalDisplayInfo.direction = MMI::Direction0; diff --git a/wmserver/src/window_controller.cpp b/wmserver/src/window_controller.cpp index d6550219..692fc579 100644 --- a/wmserver/src/window_controller.cpp +++ b/wmserver/src/window_controller.cpp @@ -14,9 +14,11 @@ */ #include "window_controller.h" +#include #include #include "window_manager_hilog.h" #include "window_helper.h" +#include "wm_common.h" #include "wm_trace.h" namespace OHOS { @@ -70,6 +72,7 @@ WMError WindowController::AddWindowNode(sptr& property) if (res != WMError::WM_OK) { return res; } + windowRoot_->FocusFaultDetection(); FlushWindowInfo(property->GetWindowId()); if (node->GetWindowType() == WindowType::WINDOW_TYPE_STATUS_BAR || @@ -84,9 +87,11 @@ WMError WindowController::AddWindowNode(sptr& property) WM_SCOPED_TRACE_END(); if (res != WMError::WM_OK) { WLOGFE("Minimize other structured window failed"); + return res; } } - return res; + StopBootAnimationIfNeed(node->GetWindowType()); + return WMError::WM_OK; } WMError WindowController::RemoveWindowNode(uint32_t windowId) @@ -95,6 +100,7 @@ WMError WindowController::RemoveWindowNode(uint32_t windowId) if (res != WMError::WM_OK) { return res; } + windowRoot_->FocusFaultDetection(); FlushWindowInfo(windowId); return res; } @@ -110,6 +116,7 @@ WMError WindowController::DestroyWindow(uint32_t windowId, bool onlySelf) if (res != WMError::WM_OK) { return res; } + windowRoot_->FocusFaultDetection(); FlushWindowInfoWithDisplayId(displayId); return res; } @@ -140,15 +147,16 @@ WMError WindowController::ResizeRect(uint32_t windowId, const Rect& rect, Window } else if (reason == WindowSizeChangeReason::DRAG) { if (WindowHelper::IsMainFloatingWindow(node->GetWindowType(), node->GetWindowMode())) { // fix rect in case of moving window when dragging - newRect = WindowHelper::GetFixedWindowRectByMinRect(rect, - property->GetWindowRect(), windowRoot_->isVerticalDisplay(node)); + float virtualPixelRatio = windowRoot_->GetVirtualPixelRatio(node->GetDisplayId()); + newRect = WindowHelper::GetFixedWindowRectByMinRect(rect, property->GetWindowRect(), + windowRoot_->isVerticalDisplay(node), virtualPixelRatio); } else { newRect = rect; } } property->SetWindowRect(newRect); - WMError res = windowRoot_->UpdateWindowNode(windowId); + WMError res = windowRoot_->UpdateWindowNode(windowId, WindowUpdateReason::UPDATE_RECT); if (res != WMError::WM_OK) { return res; } @@ -174,7 +182,6 @@ WMError WindowController::SetWindowMode(uint32_t windowId, WindowMode dstMode) return WMError::WM_OK; } WMError res = WMError::WM_OK; - node->SetWindowMode(dstMode); if ((srcMode == WindowMode::WINDOW_MODE_FULLSCREEN) && (dstMode == WindowMode::WINDOW_MODE_FLOATING)) { node->SetWindowSizeChangeReason(WindowSizeChangeReason::RECOVER); } else if (dstMode == WindowMode::WINDOW_MODE_FULLSCREEN) { @@ -185,9 +192,13 @@ WMError WindowController::SetWindowMode(uint32_t windowId, WindowMode dstMode) if (WindowHelper::IsSplitWindowMode(srcMode)) { // change split mode to other res = windowRoot_->ExitSplitWindowMode(node); + node->SetWindowMode(dstMode); } else if (!WindowHelper::IsSplitWindowMode(srcMode) && WindowHelper::IsSplitWindowMode(dstMode)) { // change other mode to split + node->SetWindowMode(dstMode); res = windowRoot_->EnterSplitWindowMode(node); + } else { + node->SetWindowMode(dstMode); } if (res != WMError::WM_OK) { node->GetWindowProperty()->ResumeLastWindowMode(); @@ -201,7 +212,7 @@ WMError WindowController::SetWindowMode(uint32_t windowId, WindowMode dstMode) return res; } } - res = windowRoot_->UpdateWindowNode(windowId); + res = windowRoot_->UpdateWindowNode(windowId, WindowUpdateReason::UPDATE_MODE); if (res != WMError::WM_OK) { WLOGFE("Set window mode failed, update node failed"); return res; @@ -257,7 +268,7 @@ void WindowController::NotifyDisplayStateChange(DisplayId displayId, DisplayStat break; } case DisplayStateChangeType::DESTROY: { - windowRoot_->NotifyDisplayDestory(displayId); + windowRoot_->NotifyDisplayDestroy(displayId); break; } default: { @@ -274,13 +285,13 @@ void WindowController::ProcessDisplayChange(DisplayId displayId, DisplayStateCha WLOGFE("get display failed displayId:%{public}" PRId64 "", displayId); return; } - + switch (type) { case DisplayStateChangeType::UPDATE_ROTATION: { windowRoot_->NotifyDisplayChange(abstractDisplay); // TODO: Remove 'sysBarWinId_' after SystemUI resize 'systembar' - uint32_t width = abstractDisplay->GetWidth(); + uint32_t width = static_cast(abstractDisplay->GetWidth()); uint32_t height = abstractDisplay->GetHeight() * SYSTEM_BAR_HEIGHT_RATIO; Rect newRect = { 0, 0, width, height }; ResizeRect(sysBarWinId_[WindowType::WINDOW_TYPE_STATUS_BAR], newRect, WindowSizeChangeReason::DRAG); @@ -304,6 +315,14 @@ void WindowController::ProcessDisplayChange(DisplayId displayId, DisplayStateCha WLOGFI("Finish ProcessDisplayChange"); } +void WindowController::StopBootAnimationIfNeed(WindowType type) const +{ + if (WindowType::WINDOW_TYPE_DESKTOP == type) { + WLOGFD("stop boot animation"); + system::SetParameter("persist.window.boot.inited", "1"); + } +} + WMError WindowController::SetWindowType(uint32_t windowId, WindowType type) { auto node = windowRoot_->GetWindowNode(windowId); @@ -314,7 +333,7 @@ WMError WindowController::SetWindowType(uint32_t windowId, WindowType type) auto property = node->GetWindowProperty(); property->SetWindowType(type); UpdateWindowAnimation(node); - WMError res = windowRoot_->UpdateWindowNode(windowId); + WMError res = windowRoot_->UpdateWindowNode(windowId, WindowUpdateReason::UPDATE_TYPE); if (res != WMError::WM_OK) { return res; } @@ -332,7 +351,7 @@ WMError WindowController::SetWindowFlags(uint32_t windowId, uint32_t flags) } auto property = node->GetWindowProperty(); property->SetWindowFlags(flags); - WMError res = windowRoot_->UpdateWindowNode(windowId); + WMError res = windowRoot_->UpdateWindowNode(windowId, WindowUpdateReason::UPDATE_FLAGS); if (res != WMError::WM_OK) { return res; } @@ -349,7 +368,7 @@ WMError WindowController::SetSystemBarProperty(uint32_t windowId, WindowType typ return WMError::WM_ERROR_NULLPTR; } node->SetSystemBarProperty(type, property); - WMError res = windowRoot_->UpdateWindowNode(windowId); + WMError res = windowRoot_->UpdateWindowNode(windowId, WindowUpdateReason::UPDATE_OTHER_PROPS); if (res != WMError::WM_OK) { return res; } @@ -358,6 +377,11 @@ WMError WindowController::SetSystemBarProperty(uint32_t windowId, WindowType typ return res; } +void WindowController::NotifySystemBarTints() +{ + windowRoot_->NotifySystemBarTints(); +} + std::vector WindowController::GetAvoidAreaByType(uint32_t windowId, AvoidAreaType avoidAreaType) { std::vector avoidArea = windowRoot_->GetAvoidAreaByType(windowId, avoidAreaType); @@ -378,6 +402,7 @@ WMError WindowController::ProcessWindowTouchedEvent(uint32_t windowId) WLOGFI("ProcessWindowTouchedEvent end"); return WMError::WM_OK; } + windowRoot_->FocusFaultDetection(); return WMError::WM_ERROR_INVALID_OPERATION; } @@ -386,6 +411,17 @@ void WindowController::MinimizeAllAppWindows(DisplayId displayId) windowRoot_->MinimizeAllAppWindows(displayId); } +WMError WindowController::MaxmizeWindow(uint32_t windowId) +{ + WMError ret = SetWindowMode(windowId, WindowMode::WINDOW_MODE_FULLSCREEN); + if (ret != WMError::WM_OK) { + return ret; + } + ret = windowRoot_->MaxmizeWindow(windowId); + FlushWindowInfo(windowId); + return ret; +} + WMError WindowController::GetTopWindowId(uint32_t mainWinId, uint32_t& topWinId) { return windowRoot_->GetTopWindowId(mainWinId, topWinId); diff --git a/wmserver/src/window_inner_manager.cpp b/wmserver/src/window_inner_manager.cpp index 1526e986..341ee4de 100644 --- a/wmserver/src/window_inner_manager.cpp +++ b/wmserver/src/window_inner_manager.cpp @@ -215,7 +215,12 @@ void WindowInnerManager::HideAndDestroyDivider(std::unique_ptr ms WLOGFE("Window is nullptr"); return; } - WMError res = window->Destroy(); + WMError res = window->Hide(); + if (res != WMError::WM_OK) { + WLOGFE("Hide window failed"); + return; + } + res = window->Destroy(); if (res != WMError::WM_OK) { WLOGFE("Destroy window failed"); return; diff --git a/wmserver/src/window_layout_policy.cpp b/wmserver/src/window_layout_policy.cpp index 7b973e97..6f3c98fb 100644 --- a/wmserver/src/window_layout_policy.cpp +++ b/wmserver/src/window_layout_policy.cpp @@ -14,16 +14,16 @@ */ #include "window_layout_policy.h" +#include "display_manager.h" #include "window_helper.h" #include "window_manager_hilog.h" +#include "wm_common_inner.h" #include "wm_trace.h" namespace OHOS { namespace Rosen { namespace { constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WINDOW, "WindowLayoutPolicy"}; - constexpr uint32_t WINDOW_TITLE_BAR_HEIGHT = 48; - constexpr uint32_t WINDOW_FRAME_WIDTH = 4; } WindowLayoutPolicy::WindowLayoutPolicy(const Rect& displayRect, const uint64_t& screenId, sptr& belowAppNode, sptr& appNode, sptr& aboveAppNode) @@ -115,11 +115,14 @@ void WindowLayoutPolicy::UpdateDefaultFoatingRect() void WindowLayoutPolicy::SetRectForFloating(const sptr& node) { + float virtualPixelRatio = GetVirtualPixelRatio(); + uint32_t winFrameW = static_cast(WINDOW_FRAME_WIDTH * virtualPixelRatio); + uint32_t winTitleBarH = static_cast(WINDOW_TITLE_BAR_HEIGHT * virtualPixelRatio); // deduct decor size Rect rect = defaultFloatingRect_; if (node->GetWindowProperty()->GetDecorEnable()) { - rect.width_ -= (WINDOW_FRAME_WIDTH + WINDOW_FRAME_WIDTH); - rect.height_ -= (WINDOW_TITLE_BAR_HEIGHT + WINDOW_FRAME_WIDTH); + rect.width_ -= (winFrameW + winFrameW); + rect.height_ -= (winTitleBarH + winFrameW); } node->SetWindowRect(rect); @@ -140,6 +143,9 @@ void WindowLayoutPolicy::RemoveWindowNode(sptr& node) } else if (type == WindowType::WINDOW_TYPE_DOCK_SLICE) { // split screen mode LayoutWindowTree(); } + Rect winRect = node->GetWindowProperty()->GetWindowRect(); + node->SetLayoutRect(winRect); + node->GetWindowToken()->UpdateWindowRect(winRect, node->GetWindowSizeChangeReason()); } void WindowLayoutPolicy::UpdateWindowNode(sptr& node) @@ -172,11 +178,15 @@ void WindowLayoutPolicy::UpdateFloatingLayoutRect(Rect& limitRect, Rect& winRect Rect WindowLayoutPolicy::ComputeDecoratedWindowRect(const Rect& winRect) { + float virtualPixelRatio = GetVirtualPixelRatio(); + uint32_t winFrameW = static_cast(WINDOW_FRAME_WIDTH * virtualPixelRatio); + uint32_t winTitleBarH = static_cast(WINDOW_TITLE_BAR_HEIGHT * virtualPixelRatio); + Rect rect; rect.posX_ = winRect.posX_; rect.posY_ = winRect.posY_; - rect.width_ = winRect.width_ + WINDOW_FRAME_WIDTH + WINDOW_FRAME_WIDTH; - rect.height_ = winRect.height_ + WINDOW_TITLE_BAR_HEIGHT + WINDOW_FRAME_WIDTH; + rect.width_ = winRect.width_ + winFrameW + winFrameW; + rect.height_ = winRect.height_ + winTitleBarH + winFrameW; return rect; } @@ -219,14 +229,44 @@ void WindowLayoutPolicy::UpdateLayoutRect(sptr& node) LimitWindowSize(node, displayRect, winRect); node->SetLayoutRect(winRect); + CalcAndSetNodeHotZone(winRect, node); if (!(lastRect == winRect)) { node->GetWindowToken()->UpdateWindowRect(winRect, node->GetWindowSizeChangeReason()); node->surfaceNode_->SetBounds(winRect.posX_, winRect.posY_, winRect.width_, winRect.height_); } } +void WindowLayoutPolicy::CalcAndSetNodeHotZone(Rect layoutOutRect, sptr& node) +{ + Rect rect = layoutOutRect; + float virtualPixelRatio = GetVirtualPixelRatio(); + uint32_t hotZone = static_cast(HOTZONE * virtualPixelRatio); + uint32_t divHotZone = static_cast(DIV_HOTZONE * virtualPixelRatio); + + if (node->GetWindowType() == WindowType::WINDOW_TYPE_DOCK_SLICE) { + if (rect.width_ < rect.height_) { + rect.posX_ -= divHotZone; + rect.width_ += (divHotZone + divHotZone); + } else { + rect.posY_ -= divHotZone; + rect.height_ += (divHotZone + divHotZone); + } + } else if (WindowHelper::IsMainFloatingWindow(node->GetWindowType(), node->GetWindowMode())) { + rect.posX_ -= hotZone; + rect.posY_ -= hotZone; + rect.width_ += (hotZone + hotZone); + rect.height_ += (hotZone + hotZone); + } + node->SetHotZoneRect(rect); +} + void WindowLayoutPolicy::LimitWindowSize(const sptr& node, const Rect& displayRect, Rect& winRect) { + float virtualPixelRatio = GetVirtualPixelRatio(); + uint32_t minVerticalFloatingW = static_cast(MIN_VERTICAL_FLOATING_WIDTH * virtualPixelRatio); + uint32_t minVerticalFloatingH = static_cast(MIN_VERTICAL_FLOATING_HEIGHT * virtualPixelRatio); + uint32_t windowTitleBarH = static_cast(WINDOW_TITLE_BAR_HEIGHT * virtualPixelRatio); + WindowType windowType = node->GetWindowType(); WindowMode windowMode = node->GetWindowMode(); bool isVertical = (displayRect.height_ > displayRect.width_) ? true : false; @@ -236,16 +276,16 @@ void WindowLayoutPolicy::LimitWindowSize(const sptr& node, const Rec } if ((windowMode == WindowMode::WINDOW_MODE_FLOATING) && !WindowHelper::IsSystemWindow(windowType)) { if (isVertical) { - winRect.width_ = std::max(MIN_VERTICAL_FLOATING_WIDTH, winRect.width_); - winRect.height_ = std::max(MIN_VERTICAL_FLOATING_HEIGHT, winRect.height_); + winRect.width_ = std::max(minVerticalFloatingW, winRect.width_); + winRect.height_ = std::max(minVerticalFloatingH, winRect.height_); } else { - winRect.width_ = std::max(MIN_VERTICAL_FLOATING_HEIGHT, winRect.width_); - winRect.height_ = std::max(MIN_VERTICAL_FLOATING_WIDTH, winRect.height_); + winRect.width_ = std::max(minVerticalFloatingH, winRect.width_); + winRect.height_ = std::max(minVerticalFloatingW, winRect.height_); } } if (WindowHelper::IsMainFloatingWindow(windowType, windowMode)) { winRect.posY_ = std::max(limitRect_.posY_, winRect.posY_); - winRect.posY_ = std::min(limitRect_.posY_ + static_cast(limitRect_.height_ - WINDOW_TITLE_BAR_HEIGHT), + winRect.posY_ = std::min(limitRect_.posY_ + static_cast(limitRect_.height_ - windowTitleBarH), winRect.posY_); } } @@ -312,5 +352,23 @@ void WindowLayoutPolicy::UpdateLimitRect(const sptr& node, Rect& lim void WindowLayoutPolicy::Reset() { } + +float WindowLayoutPolicy::GetVirtualPixelRatio() const +{ + auto display = DisplayManager::GetInstance().GetDisplayById(screenId_); + if (display == nullptr) { + WLOGFE("GetVirtualPixel fail. Get display fail. displayId:%{public}" PRIu64", use Default vpr:1.0", screenId_); + return 1.0; // Use DefaultVPR 1.0 + } + + float virtualPixelRatio = display->GetVirtualPixelRatio(); + if (virtualPixelRatio == 0.0) { + WLOGFE("GetVirtualPixel fail. vpr is 0.0. displayId:%{public}" PRIu64", use Default vpr:1.0", screenId_); + return 1.0; // Use DefaultVPR 1.0 + } + + WLOGFI("GetVirtualPixel success. displayId:%{public}" PRIu64", vpr:%{public}f", screenId_, virtualPixelRatio); + return virtualPixelRatio; +} } } diff --git a/wmserver/src/window_layout_policy_cascade.cpp b/wmserver/src/window_layout_policy_cascade.cpp index 490449df..8faa6d61 100644 --- a/wmserver/src/window_layout_policy_cascade.cpp +++ b/wmserver/src/window_layout_policy_cascade.cpp @@ -17,6 +17,7 @@ #include "window_helper.h" #include "window_inner_manager.h" #include "window_manager_hilog.h" +#include "wm_common_inner.h" #include "wm_trace.h" namespace OHOS { @@ -130,21 +131,27 @@ static bool IsLayoutChanged(const Rect& l, const Rect& r) void WindowLayoutPolicyCascade::LimitMoveBounds(Rect& rect) { + float virtualPixelRatio = GetVirtualPixelRatio(); + uint32_t minHorizontalSplitW = static_cast(MIN_HORIZONTAL_SPLIT_WIDTH * virtualPixelRatio); + uint32_t minVerticalSplitH = static_cast(MIN_VERTICAL_SPLIT_HEIGHT * virtualPixelRatio); + if (rect.width_ < rect.height_) { - if (rect.posX_ < (limitRect_.posX_ + static_cast(MIN_HORIZONTAL_SPLIT_WIDTH))) { - rect.posX_ = limitRect_.posX_ + static_cast(MIN_HORIZONTAL_SPLIT_WIDTH); + if (rect.posX_ < (limitRect_.posX_ + static_cast(minHorizontalSplitW))) { + rect.posX_ = limitRect_.posX_ + static_cast(minHorizontalSplitW); } else if (rect.posX_ > - (limitRect_.posX_ + limitRect_.width_ - static_cast(MIN_HORIZONTAL_SPLIT_WIDTH))) { - rect.posX_ = limitRect_.posX_ + static_cast(limitRect_.width_ - MIN_HORIZONTAL_SPLIT_WIDTH); + (limitRect_.posX_ + limitRect_.width_ - static_cast(minHorizontalSplitW))) { + rect.posX_ = limitRect_.posX_ + static_cast(limitRect_.width_ - minHorizontalSplitW); } } else { - if (rect.posY_ < (limitRect_.posY_ + static_cast(MIN_VERTICAL_SPLIT_HEIGHT))) { - rect.posY_ = limitRect_.posY_ + static_cast(MIN_VERTICAL_SPLIT_HEIGHT); + if (rect.posY_ < (limitRect_.posY_ + static_cast(minVerticalSplitH))) { + rect.posY_ = limitRect_.posY_ + static_cast(minVerticalSplitH); } else if (rect.posY_ > - (limitRect_.posY_ + static_cast(limitRect_.height_ - MIN_VERTICAL_SPLIT_HEIGHT))) { - rect.posY_ = limitRect_.posY_ + static_cast(limitRect_.height_ - MIN_VERTICAL_SPLIT_HEIGHT); + (limitRect_.posY_ + static_cast(limitRect_.height_ - minVerticalSplitH))) { + rect.posY_ = limitRect_.posY_ + static_cast(limitRect_.height_ - minVerticalSplitH); } } + WLOGFI("limit divider move bounds:[%{public}d, %{public}d, %{public}u, %{public}u]", + rect.posX_, rect.posY_, rect.width_, rect.height_); } void WindowLayoutPolicyCascade::InitCascadeRect() @@ -207,15 +214,14 @@ void WindowLayoutPolicyCascade::UpdateLayoutRect(sptr& node) UpdateFloatingLayoutRect(limitRect, winRect); } } + if (node->GetWindowType() == WindowType::WINDOW_TYPE_DOCK_SLICE) { + LimitMoveBounds(winRect); // limit divider pos first + } // Limit window to the maximum window size LimitWindowSize(node, displayRect_, winRect); - - if (node->GetWindowType() == WindowType::WINDOW_TYPE_DOCK_SLICE) { - LimitMoveBounds(winRect); - } - node->SetLayoutRect(winRect); - if (IsLayoutChanged(lastRect, winRect)) { + CalcAndSetNodeHotZone(winRect, node); + if (IsLayoutChanged(lastRect, winRect) || node->GetWindowType() == WindowType::WINDOW_TYPE_DOCK_SLICE) { node->GetWindowToken()->UpdateWindowRect(winRect, node->GetWindowSizeChangeReason()); node->surfaceNode_->SetBounds(winRect.posX_, winRect.posY_, winRect.width_, winRect.height_); } @@ -265,12 +271,15 @@ void WindowLayoutPolicyCascade::UpdateSplitLimitRect(const Rect& limitRect, Rect void WindowLayoutPolicyCascade::InitSplitRects() { + float virtualPixelRatio = GetVirtualPixelRatio(); + uint32_t dividerWidth = static_cast(DIVIDER_WIDTH * virtualPixelRatio); + if (!IsVertical()) { - dividerRect_ = { static_cast((displayRect_.width_ - DIVIDER_WIDTH) * DEFAULT_SPLIT_RATIO), 0, - DIVIDER_WIDTH, displayRect_.height_ }; + dividerRect_ = { static_cast((displayRect_.width_ - dividerWidth) * DEFAULT_SPLIT_RATIO), 0, + dividerWidth, displayRect_.height_ }; } else { - dividerRect_ = { 0, static_cast((displayRect_.height_ - DIVIDER_WIDTH) * DEFAULT_SPLIT_RATIO), - displayRect_.width_, DIVIDER_WIDTH }; + dividerRect_ = { 0, static_cast((displayRect_.height_ - dividerWidth) * DEFAULT_SPLIT_RATIO), + displayRect_.width_, dividerWidth }; } WLOGFI("init dividerRect :[%{public}d, %{public}d, %{public}u, %{public}u]", dividerRect_.posX_, dividerRect_.posY_, dividerRect_.width_, dividerRect_.height_); diff --git a/wmserver/src/window_layout_policy_tile.cpp b/wmserver/src/window_layout_policy_tile.cpp index 073ada6a..500d34d9 100644 --- a/wmserver/src/window_layout_policy_tile.cpp +++ b/wmserver/src/window_layout_policy_tile.cpp @@ -23,7 +23,7 @@ namespace OHOS { namespace Rosen { namespace { - constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, 0, "WindowLayoutPolicyTile"}; + constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WINDOW, "WindowLayoutPolicyTile"}; constexpr uint32_t MAX_WIN_NUM_VERTICAL = 2; constexpr uint32_t MAX_WIN_NUM_HORIZONTAL = 3; } @@ -85,7 +85,7 @@ void WindowLayoutPolicyTile::AddWindowNode(sptr& node) { WM_FUNCTION_TRACE(); if (WindowHelper::IsMainWindow(node->GetWindowType())) { - UpdateForegroundNodeQueue(node); + ForegroundNodeQueuePushBack(node); AssignNodePropertyForTileWindows(); LayoutForegroundNodeQueue(); } else { @@ -93,12 +93,30 @@ void WindowLayoutPolicyTile::AddWindowNode(sptr& node) } } +void WindowLayoutPolicyTile::RemoveWindowNode(sptr& node) +{ + WM_FUNCTION_TRACE(); + WLOGFI("RemoveWindowNode %{public}d in tile", node->GetWindowId()); + auto type = node->GetWindowType(); + // affect other windows, trigger off global layout + if (avoidTypes_.find(type) != avoidTypes_.end()) { + LayoutWindowTree(); + } else { + ForegroundNodeQueueRemove(node); + AssignNodePropertyForTileWindows(); + LayoutForegroundNodeQueue(); + } + Rect winRect = node->GetWindowProperty()->GetWindowRect(); + node->GetWindowToken()->UpdateWindowRect(winRect, node->GetWindowSizeChangeReason()); +} + void WindowLayoutPolicyTile::LayoutForegroundNodeQueue() { for (auto& node : foregroundNodes_) { Rect lastRect = node->GetLayoutRect(); Rect winRect = node->GetWindowProperty()->GetWindowRect(); node->SetLayoutRect(winRect); + CalcAndSetNodeHotZone(winRect, node); if (!(lastRect == winRect)) { node->GetWindowToken()->UpdateWindowRect(winRect, node->GetWindowSizeChangeReason()); node->surfaceNode_->SetBounds(winRect.posX_, winRect.posY_, winRect.width_, winRect.height_); @@ -112,30 +130,41 @@ void WindowLayoutPolicyTile::LayoutForegroundNodeQueue() void WindowLayoutPolicyTile::InitForegroundNodeQueue() { foregroundNodes_.clear(); - lastForegroundNodeId_ = 0; for (auto& node : appWindowNode_->children_) { if (WindowHelper::IsMainWindow(node->GetWindowType())) { - UpdateForegroundNodeQueue(node); + ForegroundNodeQueuePushBack(node); } } } -void WindowLayoutPolicyTile::UpdateForegroundNodeQueue(sptr& node) +void WindowLayoutPolicyTile::ForegroundNodeQueuePushBack(sptr& node) { if (node == nullptr) { return; } WLOGFI("add win in tile for win id: %{public}d", node->GetWindowId()); uint32_t maxTileWinNum = IsVertical() ? MAX_WIN_NUM_VERTICAL : MAX_WIN_NUM_HORIZONTAL; - if (foregroundNodes_.size() < maxTileWinNum) { - foregroundNodes_.push_back(node); - lastForegroundNodeId_ = ((++lastForegroundNodeId_) % maxTileWinNum); - } else { - WLOGFI("minimize win %{public}d in tile", foregroundNodes_[lastForegroundNodeId_]->GetWindowId()); - AAFwk::AbilityManagerClient::GetInstance()-> - MinimizeAbility(foregroundNodes_[lastForegroundNodeId_]->abilityToken_); - foregroundNodes_[lastForegroundNodeId_] = node; - lastForegroundNodeId_ = ((++lastForegroundNodeId_) % maxTileWinNum); + while (foregroundNodes_.size() >= maxTileWinNum) { + auto removeNode = foregroundNodes_.front(); + foregroundNodes_.pop_front(); + WLOGFI("pop win in queue head id: %{public}d, for add new win", removeNode->GetWindowId()); + if (removeNode->abilityToken_ != nullptr) { + WLOGFI("minimize win %{public}d in tile", removeNode->GetWindowId()); + AAFwk::AbilityManagerClient::GetInstance()->MinimizeAbility(removeNode->abilityToken_); + } + } + foregroundNodes_.push_back(node); +} + +void WindowLayoutPolicyTile::ForegroundNodeQueueRemove(sptr& node) +{ + if (node == nullptr) { + return; + } + auto iter = std::find(foregroundNodes_.begin(), foregroundNodes_.end(), node); + if (iter != foregroundNodes_.end()) { + WLOGFI("remove win in tile for win id: %{public}d", node->GetWindowId()); + foregroundNodes_.erase(iter); } } @@ -144,26 +173,28 @@ void WindowLayoutPolicyTile::AssignNodePropertyForTileWindows() // set rect for foreground windows int num = foregroundNodes_.size(); if (num == 1) { - WLOGFI("set rect for win id: %{public}d", foregroundNodes_[0]->GetWindowMode()); - foregroundNodes_[0]->SetWindowMode(WindowMode::WINDOW_MODE_FLOATING); - foregroundNodes_[0]->GetWindowToken()->UpdateWindowMode(WindowMode::WINDOW_MODE_FLOATING); - foregroundNodes_[0]->SetWindowRect(singleRect_); - foregroundNodes_[0]->hasDecorated_ = true; + WLOGFI("set rect for win id: %{public}d", foregroundNodes_.front()->GetWindowMode()); + foregroundNodes_.front()->SetWindowMode(WindowMode::WINDOW_MODE_FLOATING); + foregroundNodes_.front()->GetWindowToken()->UpdateWindowMode(WindowMode::WINDOW_MODE_FLOATING); + foregroundNodes_.front()->SetWindowRect(singleRect_); + foregroundNodes_.front()->hasDecorated_ = true; WLOGFI("set rect for win id: %{public}d [%{public}d %{public}d %{public}d %{public}d]", - foregroundNodes_[0]->GetWindowId(), + foregroundNodes_.front()->GetWindowId(), singleRect_.posX_, singleRect_.posY_, singleRect_.width_, singleRect_.height_); - } else { - auto& rects = (num == MAX_WIN_NUM_HORIZONTAL) ? tripleRects_ : doubleRects_; - for (uint32_t i = 0; i < foregroundNodes_.size(); i++) { - foregroundNodes_[(lastForegroundNodeId_ + i) % num]->SetWindowMode(WindowMode::WINDOW_MODE_FLOATING); - foregroundNodes_[(lastForegroundNodeId_ + i) % num]->GetWindowToken()-> - UpdateWindowMode(WindowMode::WINDOW_MODE_FLOATING); - foregroundNodes_[(lastForegroundNodeId_ + i) % num]->SetWindowRect(rects[i]); - foregroundNodes_[(lastForegroundNodeId_ + i) % num]->hasDecorated_ = true; + } else if (num <= MAX_WIN_NUM_HORIZONTAL) { + auto rit = (num == MAX_WIN_NUM_HORIZONTAL) ? tripleRects_.begin() : doubleRects_.begin(); + for (auto it : foregroundNodes_) { + auto& rect = (*rit); + it->SetWindowMode(WindowMode::WINDOW_MODE_FLOATING); + it->GetWindowToken()->UpdateWindowMode(WindowMode::WINDOW_MODE_FLOATING); + it->SetWindowRect(rect); + it->hasDecorated_ = true; WLOGFI("set rect for qwin id: %{public}d [%{public}d %{public}d %{public}d %{public}d]", - foregroundNodes_[(lastForegroundNodeId_ + i) % num]->GetWindowId(), - rects[i].posX_, rects[i].posY_, rects[i].width_, rects[i].height_); + it->GetWindowId(), rect.posX_, rect.posY_, rect.width_, rect.height_); + rit++; } + } else { + WLOGE("too many window node in tile queue"); } } @@ -204,6 +235,7 @@ void WindowLayoutPolicyTile::UpdateLayoutRect(sptr& node) } LimitWindowSize(node, displayRect, winRect); node->SetLayoutRect(winRect); + CalcAndSetNodeHotZone(winRect, node); if (!(lastRect == winRect)) { node->GetWindowToken()->UpdateWindowRect(winRect, node->GetWindowSizeChangeReason()); node->surfaceNode_->SetBounds(winRect.posX_, winRect.posY_, winRect.width_, winRect.height_); diff --git a/wmserver/src/window_manager_agent_controller.cpp b/wmserver/src/window_manager_agent_controller.cpp index d0ffad1c..d976b03c 100644 --- a/wmserver/src/window_manager_agent_controller.cpp +++ b/wmserver/src/window_manager_agent_controller.cpp @@ -65,5 +65,15 @@ void WindowManagerAgentController::UpdateWindowStatus(const sptr& wi agent->UpdateWindowStatus(windowInfo, type); } } + +void WindowManagerAgentController::UpdateWindowVisibilityInfo( + const std::vector>& windowVisibilityInfos) +{ + WLOGFD("UpdateWindowVisibilityInfo size:%{public}zu", windowVisibilityInfos.size()); + for (auto& agent : wmAgentContainer_.GetAgentsByType( + WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_WINDOW_VISIBILITY)) { + agent->UpdateWindowVisibilityInfo(windowVisibilityInfos); + } +} } } \ No newline at end of file diff --git a/wmserver/src/window_manager_proxy.cpp b/wmserver/src/window_manager_proxy.cpp index ac2a8773..626f7246 100644 --- a/wmserver/src/window_manager_proxy.cpp +++ b/wmserver/src/window_manager_proxy.cpp @@ -492,71 +492,25 @@ void WindowManagerProxy::MinimizeAllAppWindows(DisplayId displayId) } } -bool WindowManagerProxy::IsSupportWideGamut(uint32_t windowId) +WMError WindowManagerProxy::MaxmizeWindow(uint32_t windowId) { MessageParcel data; MessageParcel reply; MessageOption option; if (!data.WriteInterfaceToken(GetDescriptor())) { WLOGFE("WriteInterfaceToken failed"); - return false; + return WMError::WM_ERROR_IPC_FAILED; } if (!data.WriteUint32(windowId)) { WLOGFE("Write windowId failed"); - return false; + return WMError::WM_ERROR_IPC_FAILED; } - if (Remote()->SendRequest(TRANS_ID_IS_SUPPORT_WIDE_GAMUT, data, reply, option) != ERR_NONE) { - WLOGFE("SendRequest failed"); - return false; + if (Remote()->SendRequest(TRANS_ID_MAXMIZE_WINDOW, data, reply, option) != ERR_NONE) { + return WMError::WM_ERROR_IPC_FAILED; } - int32_t ret = reply.ReadUint32(); - return static_cast(ret); -} - -void WindowManagerProxy::SetColorSpace(uint32_t windowId, ColorSpace colorSpace) -{ - MessageParcel data; - MessageParcel reply; - MessageOption option; - if (!data.WriteInterfaceToken(GetDescriptor())) { - WLOGFE("WriteInterfaceToken failed"); - return; - } - if (!data.WriteUint32(windowId)) { - WLOGFE("Write windowId failed"); - return; - } - if (!data.WriteUint32(static_cast(colorSpace))) { - WLOGFE("Write colorSpace failed"); - return; - } - if (Remote()->SendRequest(TRANS_ID_SET_COLOR_SPACE, data, reply, option) != ERR_NONE) { - WLOGFE("SendRequest failed"); - return; - } -} - -ColorSpace WindowManagerProxy::GetColorSpace(uint32_t windowId) -{ - MessageParcel data; - MessageParcel reply; - MessageOption option; - if (!data.WriteInterfaceToken(GetDescriptor())) { - WLOGFE("WriteInterfaceToken failed"); - return ColorSpace::COLOR_SPACE_DEFAULT; - } - if (!data.WriteUint32(windowId)) { - WLOGFE("Write windowId failed"); - return ColorSpace::COLOR_SPACE_DEFAULT; - } - if (Remote()->SendRequest(TRANS_ID_GET_COLOR_SPACE, data, reply, option) != ERR_NONE) { - WLOGFE("SendRequest failed"); - return ColorSpace::COLOR_SPACE_DEFAULT; - } - - int32_t ret = reply.ReadUint32(); - return static_cast(ret); + int32_t ret = reply.ReadInt32(); + return static_cast(ret); } WMError WindowManagerProxy::SetWindowLayoutMode(DisplayId displayId, WindowLayoutMode mode) diff --git a/wmserver/src/window_manager_service.cpp b/wmserver/src/window_manager_service.cpp index 1d9a9af0..176cf281 100644 --- a/wmserver/src/window_manager_service.cpp +++ b/wmserver/src/window_manager_service.cpp @@ -135,7 +135,6 @@ WMError WindowManagerService::AddWindow(sptr& property) WM_SCOPED_TRACE("wms:AddWindow(%d)", windowId); std::lock_guard lock(mutex_); WMError res = windowController_->AddWindowNode(property); - system::SetParameter("persist.window.boot.inited", "1"); if (property->GetWindowType() == WindowType::WINDOW_TYPE_DRAGGING_EFFECT) { dragController_->StartDrag(windowId); } @@ -249,6 +248,9 @@ void WindowManagerService::RegisterWindowManagerAgent(WindowManagerAgentType typ } std::lock_guard lock(mutex_); WindowManagerAgentController::GetInstance().RegisterWindowManagerAgent(windowManagerAgent, type); + if (type == WindowManagerAgentType::WINDOW_MANAGER_AGENT_TYPE_SYSTEM_BAR) { // if system bar, notify once + windowController_->NotifySystemBarTints(); + } } void WindowManagerService::UnregisterWindowManagerAgent(WindowManagerAgentType type, @@ -298,23 +300,11 @@ void WindowManagerService::MinimizeAllAppWindows(DisplayId displayId) windowController_->MinimizeAllAppWindows(displayId); } -bool WindowManagerService::IsSupportWideGamut(uint32_t windowId) +WMError WindowManagerService::MaxmizeWindow(uint32_t windowId) { - bool ret = true; - WLOGFI("IsSupportWideGamut %{public}d", ret); - return ret; -} - -void WindowManagerService::SetColorSpace(uint32_t windowId, ColorSpace colorSpace) -{ - WLOGFI("SetColorSpace windowId %{public}u, ColorSpace %{public}u", windowId, colorSpace); -} - -ColorSpace WindowManagerService::GetColorSpace(uint32_t windowId) -{ - ColorSpace colorSpace = ColorSpace::COLOR_SPACE_DEFAULT; - WLOGFI("GetColorSpace windowId %{public}u, ColorSpace %{public}u", windowId, colorSpace); - return colorSpace; + WM_SCOPED_TRACE("wms:MaxmizeWindow"); + std::lock_guard lock(mutex_); + return windowController_->MaxmizeWindow(windowId); } WMError WindowManagerService::GetTopWindowId(uint32_t mainWinId, uint32_t& topWinId) diff --git a/wmserver/src/window_manager_stub.cpp b/wmserver/src/window_manager_stub.cpp index a804a9ec..3f4ca1d1 100644 --- a/wmserver/src/window_manager_stub.cpp +++ b/wmserver/src/window_manager_stub.cpp @@ -173,22 +173,8 @@ int32_t WindowManagerStub::OnRemoteRequest(uint32_t code, MessageParcel &data, M MinimizeAllAppWindows(data.ReadUint64()); break; } - case TRANS_ID_IS_SUPPORT_WIDE_GAMUT: { - uint32_t windowId = data.ReadUint32(); - bool ret = IsSupportWideGamut(windowId); - reply.WriteUint32(static_cast(ret)); - break; - } - case TRANS_ID_SET_COLOR_SPACE: { - uint32_t windowId = data.ReadUint32(); - ColorSpace colorSpace = static_cast(data.ReadUint32()); - SetColorSpace(windowId, colorSpace); - break; - } - case TRANS_ID_GET_COLOR_SPACE: { - uint32_t windowId = data.ReadUint32(); - ColorSpace colorSpace = GetColorSpace(windowId); - reply.WriteUint32(static_cast(colorSpace)); + case TRANS_ID_MAXMIZE_WINDOW: { + MaxmizeWindow(data.ReadUint32()); break; } case TRANS_ID_UPDATE_LAYOUT_MODE: { diff --git a/wmserver/src/window_node.cpp b/wmserver/src/window_node.cpp index 44d6ef9d..bc1f37ac 100644 --- a/wmserver/src/window_node.cpp +++ b/wmserver/src/window_node.cpp @@ -22,6 +22,7 @@ namespace Rosen { namespace { constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, 0, "WindowNode"}; } + void WindowNode::SetDisplayId(DisplayId displayId) { property_->SetDisplayId(displayId); @@ -32,6 +33,11 @@ void WindowNode::SetLayoutRect(const Rect& rect) layoutRect_ = rect; } +void WindowNode::SetHotZoneRect(const Rect& rect) +{ + hotZoneRect_ = rect; +} + void WindowNode::SetWindowRect(const Rect& rect) { property_->SetWindowRect(rect); @@ -128,23 +134,7 @@ const Rect& WindowNode::GetLayoutRect() const Rect WindowNode::GetHotZoneRect() const { - Rect rect = layoutRect_; - if (GetWindowType() == WindowType::WINDOW_TYPE_DOCK_SLICE) { - const int32_t divHotZone = 20; - if (rect.width_ < rect.height_) { - rect.posX_ -= divHotZone; - rect.width_ += (divHotZone + divHotZone); - } else { - rect.posY_ -= divHotZone; - rect.height_ += (divHotZone + divHotZone); - } - } else if (WindowHelper::IsMainFloatingWindow(GetWindowType(), GetWindowMode())) { - rect.posX_ -= HOTZONE; - rect.posY_ -= HOTZONE; - rect.width_ += (HOTZONE + HOTZONE); - rect.height_ += (HOTZONE + HOTZONE); - } - return rect; + return hotZoneRect_; } WindowType WindowNode::GetWindowType() const diff --git a/wmserver/src/window_node_container.cpp b/wmserver/src/window_node_container.cpp index 3ed3ef63..6427e32e 100644 --- a/wmserver/src/window_node_container.cpp +++ b/wmserver/src/window_node_container.cpp @@ -15,27 +15,30 @@ #include "window_node_container.h" -#include #include +#include #include +#include +#include "common_event_manager.h" #include "display_manager_service_inner.h" #include "dm_common.h" #include "window_helper.h" +#include "window_inner_manager.h" #include "window_layout_policy_cascade.h" #include "window_layout_policy_tile.h" #include "window_manager_agent_controller.h" -#include "window_inner_manager.h" #include "window_manager_hilog.h" #include "wm_common.h" +#include "wm_common_inner.h" #include "wm_trace.h" -#include "common_event_manager.h" namespace OHOS { namespace Rosen { namespace { constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WINDOW, "WindowNodeContainer"}; constexpr int WINDOW_NAME_MAX_LENGTH = 10; + const std::string SPLIT_SCREEN_EVENT_NAME = "common.event.SPLIT_SCREEN"; } WindowNodeContainer::WindowNodeContainer(DisplayId displayId, uint32_t width, uint32_t height) : displayId_(displayId) @@ -106,8 +109,7 @@ WMError WindowNodeContainer::AddWindowNode(sptr& node, sptrchildren_) { child->currentVisibility_ = child->requestedVisibility_; } - if (node->GetWindowType() == WindowType::WINDOW_TYPE_STATUS_BAR || - node->GetWindowType() == WindowType::WINDOW_TYPE_NAVIGATION_BAR) { + if (WindowHelper::IsAvoidAreaWindow(node->GetWindowType())) { sysBarNodeMap_[node->GetWindowType()] = node; } } @@ -121,31 +123,37 @@ WMError WindowNodeContainer::AddWindowNode(sptr& node, sptrIsSplitMode() || node->GetWindowType() == WindowType::WINDOW_TYPE_DOCK_SLICE) { + RaiseSplitRelatedWindowToTop(node); + } UpdateRSTree(node, true); AssignZOrder(); layoutPolicy_->AddWindowNode(node); - if (avoidController_->IsAvoidAreaNode(node)) { + if (WindowHelper::IsAvoidAreaWindow(node->GetWindowType())) { avoidController_->AddAvoidAreaNode(node); NotifyIfSystemBarRegionChanged(); } else { NotifyIfSystemBarTintChanged(); } + std::vector> infos; + UpdateWindowVisibilityInfos(infos); DumpScreenWindowTree(); UpdateWindowStatus(node, WindowUpdateType::WINDOW_UPDATE_ADDED); WLOGFI("AddWindowNode windowId: %{public}d end", node->GetWindowId()); return WMError::WM_OK; } -WMError WindowNodeContainer::UpdateWindowNode(sptr& node) +WMError WindowNodeContainer::UpdateWindowNode(sptr& node, WindowUpdateReason reason) { if (!node->surfaceNode_) { WLOGFE("surface node is nullptr!"); return WMError::WM_ERROR_NULLPTR; } - SwitchLayoutPolicy(WindowLayoutMode::CASCADE); + if (WindowHelper::IsMainWindow(node->GetWindowType()) && reason != WindowUpdateReason::UPDATE_OTHER_PROPS) { + SwitchLayoutPolicy(WindowLayoutMode::CASCADE); + } layoutPolicy_->UpdateWindowNode(node); - if (avoidController_->IsAvoidAreaNode(node)) { + if (WindowHelper::IsAvoidAreaWindow(node->GetWindowType())) { avoidController_->UpdateAvoidAreaNode(node); NotifyIfSystemBarRegionChanged(); } else { @@ -175,19 +183,38 @@ void WindowNodeContainer::UpdateWindowTree(sptr& node) bool WindowNodeContainer::UpdateRSTree(sptr& node, bool isAdd) { WM_FUNCTION_TRACE(); - if (isAdd) { - DisplayManagerServiceInner::GetInstance().UpdateRSTree(displayId_, node->surfaceNode_, true); - for (auto& child : node->children_) { - if (child->currentVisibility_) { - DisplayManagerServiceInner::GetInstance().UpdateRSTree(displayId_, child->surfaceNode_, true); + static const bool IsWindowAnimationEnabled = ReadIsWindowAnimationEnabledProperty(); + + auto updateRSTreeFunc = [&]() { + auto& dms = DisplayManagerServiceInner::GetInstance(); + if (isAdd) { + dms.UpdateRSTree(displayId_, node->surfaceNode_, true); + for (auto& child : node->children_) { + if (child->currentVisibility_) { + dms.UpdateRSTree(displayId_, child->surfaceNode_, true); + } + } + } else { + dms.UpdateRSTree(displayId_, node->surfaceNode_, false); + for (auto& child : node->children_) { + dms.UpdateRSTree(displayId_, child->surfaceNode_, false); } } + }; + + if (IsWindowAnimationEnabled) { + // default transition duration: 350ms + static const RSAnimationTimingProtocol timingProtocol(350); + // default transition curve: EASE OUT + static const Rosen::RSAnimationTimingCurve curve = Rosen::RSAnimationTimingCurve::EASE_OUT; + + // add or remove window with transition animation + RSNode::Animate(timingProtocol, curve, updateRSTreeFunc); } else { - DisplayManagerServiceInner::GetInstance().UpdateRSTree(displayId_, node->surfaceNode_, false); - for (auto& child : node->children_) { - DisplayManagerServiceInner::GetInstance().UpdateRSTree(displayId_, child->surfaceNode_, false); - } + // add or remove window without animation + updateRSTreeFunc(); } + return true; } @@ -234,8 +261,16 @@ WMError WindowNodeContainer::RemoveWindowNode(sptr& node) node->requestedVisibility_ = false; node->currentVisibility_ = false; node->hasDecorated_ = false; + node->isCovered_ = true; + std::vector> infos = {new WindowVisibilityInfo(node->GetWindowId(), + node->GetCallingPid(), node->GetCallingUid(), false)}; for (auto& child : node->children_) { - child->currentVisibility_ = false; + if (child->currentVisibility_) { + child->currentVisibility_ = false; + child->isCovered_ = true; + infos.emplace_back(new WindowVisibilityInfo(child->GetWindowId(), child->GetCallingPid(), + child->GetCallingUid(), false)); + } } if (node->IsSplitMode()) { @@ -248,12 +283,13 @@ WMError WindowNodeContainer::RemoveWindowNode(sptr& node) UpdateRSTree(node, false); layoutPolicy_->RemoveWindowNode(node); - if (avoidController_->IsAvoidAreaNode(node)) { + if (WindowHelper::IsAvoidAreaWindow(node->GetWindowType())) { avoidController_->RemoveAvoidAreaNode(node); NotifyIfSystemBarRegionChanged(); } else { NotifyIfSystemBarTintChanged(); } + UpdateWindowVisibilityInfos(infos); DumpScreenWindowTree(); UpdateWindowStatus(node, WindowUpdateType::WINDOW_UPDATE_REMOVED); WLOGFI("RemoveWindowNode windowId: %{public}d end", node->GetWindowId()); @@ -325,43 +361,16 @@ void WindowNodeContainer::UpdateFocusStatus(uint32_t id, bool focused) const void WindowNodeContainer::AssignZOrder() { zOrder_ = 0; - for (auto& node : belowAppWindowNode_->children_) { - AssignZOrder(node); - } - for (auto& node : appWindowNode_->children_) { - AssignZOrder(node); - } - for (auto& node : aboveAppWindowNode_->children_) { - AssignZOrder(node); - } -} - -void WindowNodeContainer::AssignZOrder(sptr& node) -{ - if (node == nullptr) { - return; - } - auto iter = node->children_.begin(); - for (; iter < node->children_.end(); ++iter) { - if ((*iter)->priority_ < 0) { - if ((*iter)->surfaceNode_) { - (*iter)->surfaceNode_->SetPositionZ(zOrder_); - ++zOrder_; - } - } else { - break; + WindowNodeOperationFunc func = [this](sptr node) { + if (node->surfaceNode_ == nullptr) { + WLOGE("AssignZOrder: surfaceNode is nullptr, window Id:%{public}u", node->GetWindowId()); + return false; } - } - if (node->surfaceNode_) { node->surfaceNode_->SetPositionZ(zOrder_); ++zOrder_; - } - for (; iter < node->children_.end(); ++iter) { - if ((*iter)->surfaceNode_) { - (*iter)->surfaceNode_->SetPositionZ(zOrder_); - ++zOrder_; - } - } + return false; + }; + TraverseWindowTree(func, false); } WMError WindowNodeContainer::SetFocusWindow(uint32_t windowId) @@ -471,6 +480,44 @@ void WindowNodeContainer::NotifyIfSystemBarRegionChanged() WindowManagerAgentController::GetInstance().UpdateSystemBarRegionTints(displayId_, tints); } +void WindowNodeContainer::NotifySystemBarDismiss(sptr& node) +{ + WM_FUNCTION_TRACE(); + SystemBarRegionTints tints; + bool isChanged = false; + auto& sysBarPropMapNode = node->GetSystemBarProperty(); + for (auto it : sysBarPropMapNode) { + it.second.enable_ = false; + if (sysBarTintMap_[it.first].prop_.enable_) { + sysBarTintMap_[it.first].prop_.enable_ = false; + isChanged = true; + tints.emplace_back(sysBarTintMap_[it.first]); + WLOGFI("system bar dismiss, type: %{public}d", static_cast(it.first)); + } + } + if (isChanged) { + WindowManagerAgentController::GetInstance().UpdateSystemBarRegionTints(displayId_, tints); + } +} + +void WindowNodeContainer::NotifySystemBarTints() +{ + WM_FUNCTION_TRACE(); + SystemBarRegionTints tints; + for (auto it : sysBarTintMap_) { + WLOGFD("system bar cur notify, type: %{public}d, " \ + "visible: %{public}d, color: %{public}x | %{public}x, " \ + "region: [%{public}d, %{public}d, %{public}d, %{public}d]", + static_cast(it.first), + sysBarTintMap_[it.first].region_.posX_, sysBarTintMap_[it.first].region_.posY_, + sysBarTintMap_[it.first].region_.width_, sysBarTintMap_[it.first].region_.height_, + sysBarTintMap_[it.first].prop_.enable_, + sysBarTintMap_[it.first].prop_.backgroundColor_, sysBarTintMap_[it.first].prop_.contentColor_); + tints.push_back(sysBarTintMap_[it.first]); + } + WindowManagerAgentController::GetInstance().UpdateSystemBarRegionTints(displayId_, tints); +} + bool WindowNodeContainer::IsTopAppWindow(uint32_t windowId) const { if (appWindowNode_->children_.empty()) { @@ -493,6 +540,26 @@ bool WindowNodeContainer::IsTopAppWindow(uint32_t windowId) const return node->GetWindowId() == windowId; } +void WindowNodeContainer::RaiseOrderedWindowToTop(std::vector orderedIds, + std::vector>& windowNodes) +{ + for (auto iter = appWindowNode_->children_.begin(); iter != appWindowNode_->children_.end();) { + uint32_t wid = (*iter)->GetWindowId(); + auto idIter = std::find_if(orderedIds.begin(), orderedIds.end(), + [wid] (uint32_t id) { return id == wid; }); + if (idIter != orderedIds.end()) { + orderedIds.erase(idIter); + sptr node = *iter; + iter = windowNodes.erase(iter); + UpdateWindowTree(node); + WLOGFI("raise group window to top %{public}d", node->GetWindowId()); + } else { + iter++; + } + } + return; +} + void WindowNodeContainer::RaiseWindowToTop(uint32_t windowId, std::vector>& windowNodes) { auto iter = std::find_if(windowNodes.begin(), windowNodes.end(), @@ -534,7 +601,7 @@ void WindowNodeContainer::UpdateWindowStatus(const sptr& node, Windo } if (isNeedNotify) { sptr windowInfo = new WindowInfo(); - windowInfo->wid_ = node->GetWindowId(); + windowInfo->wid_ = static_cast(node->GetWindowId()); windowInfo->windowRect_ = node->GetLayoutRect(); windowInfo->focused_ = node->GetWindowId() == focusedWindow_; windowInfo->mode_ = node->GetWindowMode(); @@ -596,18 +663,18 @@ void WindowNodeContainer::DumpScreenWindowTree() { WLOGFI("-------- display %{public}" PRIu64" dump window info begin---------", displayId_); WLOGFI("WindowName WinId Type Mode Flag ZOrd [ x y w h]"); - std::vector> windowNodes; - TraverseContainer(windowNodes); - int32_t zOrder = static_cast(windowNodes.size()); - for (auto node : windowNodes) { + uint32_t zOrder = zOrder_; + WindowNodeOperationFunc func = [&zOrder](sptr node) { Rect rect = node->GetLayoutRect(); const std::string& windowName = node->GetWindowName().size() < WINDOW_NAME_MAX_LENGTH ? node->GetWindowName() : node->GetWindowName().substr(0, WINDOW_NAME_MAX_LENGTH); - WLOGFI("%{public}10s %{public}5d %{public}4d %{public}4d %{public}4d %{public}4d [%{public}4d %{public}4d " \ - "%{public}4d %{public}4d]", windowName.c_str(), node->GetWindowId(), node->GetWindowType(), - node->GetWindowMode(), node->GetWindowFlags(), - --zOrder, rect.posX_, rect.posY_, rect.width_, rect.height_); - } + WLOGI("DumpScreenWindowTree: %{public}10s %{public}5d %{public}4d %{public}4d %{public}4d %{public}4d " \ + "[%{public}4d %{public}4d %{public}4d %{public}4d]", + windowName.c_str(), node->GetWindowId(), node->GetWindowType(), node->GetWindowMode(), + node->GetWindowFlags(), --zOrder, rect.posX_, rect.posY_, rect.width_, rect.height_); + return false; + }; + TraverseWindowTree(func, true); WLOGFI("-------- display %{public}" PRIu64" dump window info end ---------", displayId_); } @@ -677,30 +744,36 @@ sptr WindowNodeContainer::FindDividerNode() const return nullptr; } -void WindowNodeContainer::RaiseZOrderForSplitWindow(sptr& node) +void WindowNodeContainer::RaiseSplitRelatedWindowToTop(sptr& node) { - auto divider = FindDividerNode(); - WLOGFI("start raise split window zorder id: %{public}d", node->GetWindowId()); - if (pairedWindowMap_.count(node->GetWindowId()) != 0 && (divider != nullptr)) { - auto pairNode = pairedWindowMap_.at(node->GetWindowId()).pairNode_; - // remove split related node from tree - for (auto iter = appWindowNode_->children_.begin(); iter != appWindowNode_->children_.end();) { - uint32_t wid = (*iter)->GetWindowId(); - if (wid == node->GetWindowId() || - wid == pairNode->GetWindowId() || - wid == divider->GetWindowId()) { - iter = appWindowNode_->children_.erase(iter); - } else { - iter++; - } + sptr deviderNode = nullptr; + sptr primaryNode = nullptr; + sptr secondaryNode = nullptr; + if (node->GetWindowType() == WindowType::WINDOW_TYPE_DOCK_SLICE && !pairedWindowMap_.empty()) { + deviderNode = node; + primaryNode = pairedWindowMap_.begin()->second.pairNode_; + secondaryNode = pairedWindowMap_[primaryNode->GetWindowId()].pairNode_; + std::vector raiseNodeIds = {secondaryNode->GetWindowId(), primaryNode->GetWindowId()}; + // raise primary and secondary window to top, keep raw zorder + RaiseOrderedWindowToTop(raiseNodeIds, appWindowNode_->children_); + // raise divider final, keep divider on top + RaiseWindowToTop(deviderNode->GetWindowId(), appWindowNode_->children_); + } else if (!pairedWindowMap_.empty()) { + deviderNode = FindDividerNode(); + primaryNode = node; + secondaryNode = pairedWindowMap_.at(primaryNode->GetWindowId()).pairNode_; + RaiseWindowToTop(secondaryNode->GetWindowId(), appWindowNode_->children_); + RaiseWindowToTop(primaryNode->GetWindowId(), appWindowNode_->children_); + if (deviderNode != nullptr) { + // raise divider final, keep divider on top + RaiseWindowToTop(deviderNode->GetWindowId(), appWindowNode_->children_); } - UpdateWindowTree(pairNode); // raise pair node - UpdateWindowTree(node); // raise self - UpdateWindowTree(divider); // devider } else { // raise self if not paired RaiseWindowToTop(node->GetWindowId(), appWindowNode_->children_); } + AssignZOrder(); + return; } WMError WindowNodeContainer::RaiseZOrderForAppWindow(sptr& node, sptr& parentNode) @@ -719,13 +792,13 @@ WMError WindowNodeContainer::RaiseZOrderForAppWindow(sptr& node, spt } RaiseWindowToTop(node->GetWindowId(), parentNode->children_); // raise itself if (parentNode->IsSplitMode()) { - RaiseZOrderForSplitWindow(parentNode); + RaiseSplitRelatedWindowToTop(parentNode); } else { RaiseWindowToTop(node->GetParentId(), appWindowNode_->children_); // raise parent window } } else if (WindowHelper::IsMainWindow(node->GetWindowType())) { if (node->IsSplitMode()) { - RaiseZOrderForSplitWindow(node); + RaiseSplitRelatedWindowToTop(node); } else { RaiseWindowToTop(node->GetWindowId(), appWindowNode_->children_); } @@ -740,22 +813,21 @@ WMError WindowNodeContainer::RaiseZOrderForAppWindow(sptr& node, spt sptr WindowNodeContainer::GetNextFocusableWindow(uint32_t windowId) const { - std::vector> windowNodes; - TraverseContainer(windowNodes); - auto iter = std::find_if(windowNodes.begin(), windowNodes.end(), - [windowId](sptr& node) { - return node->GetWindowId() == windowId; - }); - if (iter != windowNodes.end()) { - int index = std::distance(windowNodes.begin(), iter); - for (int i = index + 1; i < windowNodes.size(); i++) { - if (windowNodes[i]->GetWindowProperty()->GetFocusable()) { - return windowNodes[i]; - } + sptr nextFocusableWindow; + bool previousFocusedWindowFound = false; + WindowNodeOperationFunc func = [windowId, &nextFocusableWindow, &previousFocusedWindowFound]( + sptr node) { + if (previousFocusedWindowFound && node->GetWindowProperty()->GetFocusable()) { + nextFocusableWindow = node; + return true; } - } - WLOGFI("could not get next focusable window"); - return nullptr; + if (node->GetWindowId() == windowId) { + previousFocusedWindowFound = true; + } + return false; + }; + TraverseWindowTree(func, true); + return nextFocusableWindow; } void WindowNodeContainer::MinimizeAllAppWindows() @@ -770,19 +842,18 @@ void WindowNodeContainer::MinimizeAllAppWindows() void WindowNodeContainer::SendSplitScreenEvent(WindowMode mode) { - // should define in common_event_support.h and @ohos.commonEvent.d.ts - WLOGFI("send split sceen event , trigger mode is %{public}d", mode); - const std::string eventName = "common.event.SPLIT_SCREEN"; + // reset ipc identity + std::string identity = IPCSkeleton::ResetCallingIdentity(); AAFwk::Want want; - want.SetAction(eventName); + want.SetAction(SPLIT_SCREEN_EVENT_NAME); EventFwk::CommonEventData commonEventData; commonEventData.SetWant(want); - if (mode == WindowMode::WINDOW_MODE_SPLIT_PRIMARY) { - commonEventData.SetData("Secondary"); - } else { - commonEventData.SetData("Primary"); - } + std::string eventData = (mode == WindowMode::WINDOW_MODE_SPLIT_PRIMARY) ? "Secondary" : "Primary"; + commonEventData.SetData(eventData); EventFwk::CommonEventManager::PublishCommonEvent(commonEventData); + // set ipc identity to raw + IPCSkeleton::SetCallingIdentity(identity); + WLOGFI("send split sceen event finish."); } sptr WindowNodeContainer::FindSplitPairNode(sptr& triggerNode) const @@ -873,23 +944,19 @@ WMError WindowNodeContainer::ExitSplitWindowMode(sptr& node) { WM_FUNCTION_TRACE(); WLOGFI("exit split window mode %{public}d", node->GetWindowId()); - if (pairedWindowMap_.find(node->GetWindowId()) != pairedWindowMap_.end()) { - WindowPairInfo info = pairedWindowMap_.at(node->GetWindowId()); - auto pairNode = info.pairNode_; + node->GetWindowProperty()->ResumeLastWindowMode(); + node->GetWindowToken()->UpdateWindowMode(node->GetWindowMode()); + if (pairedWindowMap_.count(node->GetWindowId()) != 0) { + auto pairNode = pairedWindowMap_.at(node->GetWindowId()).pairNode_; pairNode->GetWindowProperty()->ResumeLastWindowMode(); pairNode->GetWindowToken()->UpdateWindowMode(pairNode->GetWindowMode()); - node->GetWindowProperty()->ResumeLastWindowMode(); - node->GetWindowToken()->UpdateWindowMode(node->GetWindowMode()); pairedWindowMap_.erase(pairNode->GetWindowId()); pairedWindowMap_.erase(node->GetWindowId()); - WLOGFI("Split out, Id[%{public}d, %{public}d], Mode[%{public}d, %{public}d]", - node->GetWindowId(), pairNode->GetWindowId(), - node->GetWindowMode(), pairNode->GetWindowMode()); - } else { - WLOGFE("Split out, but can not find pair in map %{public}d", node->GetWindowId()); - return WMError::WM_OK; + WLOGFI("resume pair node mode, Id[%{public}d, %{public}d], Mode[%{public}d, %{public}d]", node->GetWindowId(), + pairNode->GetWindowId(), node->GetWindowMode(), pairNode->GetWindowMode()); } if (pairedWindowMap_.empty()) { + WLOGFI("send destroy msg to divider, Id: %{public}d", node->GetWindowId()); SingletonContainer::Get().SendMessage(INNER_WM_DESTROY_DIVIDER, displayId_); } ResetLayoutPolicy(); @@ -906,7 +973,7 @@ WMError WindowNodeContainer::UpdateWindowPairInfo(sptr& triggerNode, WindowMode::WINDOW_MODE_SPLIT_SECONDARY : WindowMode::WINDOW_MODE_SPLIT_PRIMARY; pairNode->SetWindowMode(pairDstMode); pairNode->GetWindowToken()->UpdateWindowMode(pairDstMode); - WMError ret = UpdateWindowNode(pairNode); + WMError ret = UpdateWindowNode(pairNode, WindowUpdateReason::UPDATE_MODE); if (ret != WMError::WM_OK) { WLOGFE("Update window pair info failed"); return ret; @@ -985,41 +1052,156 @@ void WindowNodeContainer::RaiseInputMethodWindowPriorityIfNeeded(const sptr& container) { - WLOGFI("MoveWindowNode: disconnect expand display: %{public}" PRId64 ", move window node to display: " - "%{public}" PRId64 "", container->GetDisplayId(), displayId_); - sptr belowAppNode = container->GetBelowAppWindowNode(); - sptr appNode = container->GetAppWindowNode(); - sptr aboveAppNode = container->GetAboveAppWindowNode(); - for (auto& node : belowAppNode->children_) { - WLOGFI("belowAppWindowNode_: move windowNode: {public}%d", node->GetWindowId()); - node->SetDisplayId(displayId_); - belowAppWindowNode_->children_.push_back(node); - } - for (auto& node : appNode->children_) { - WLOGFI("appWindowNode_: move windowNode: {public}%d", node->GetWindowId()); - node->SetDisplayId(displayId_); - appWindowNode_->children_.push_back(node); - } - for (auto& node : aboveAppNode->children_) { - WLOGFI("aboveAppWindowNode_: move windowNode: {public}%d", node->GetWindowId()); - node->SetDisplayId(displayId_); + DisplayId from = container->GetDisplayId(); + WLOGFI("disconnect expand display: %{public}" PRId64 ", move window node to display: " + "%{public}" PRId64 "", from, displayId_); + for (auto& node : container->aboveAppWindowNode_->children_) { + WLOGFI("aboveAppWindowNode_: move windowNode: %{public}d", node->GetWindowId()); aboveAppWindowNode_->children_.push_back(node); + layoutPolicy_->AddWindowNode(node); + } + for (auto& node : container->appWindowNode_->children_) { + WLOGFI("appWindowNode_: move windowNode: %{public}d", node->GetWindowId()); + appWindowNode_->children_.push_back(node); + layoutPolicy_->AddWindowNode(node); + } + for (auto& node : container->belowAppWindowNode_->children_) { + WLOGFI("belowAppWindowNode_: move windowNode: %{public}d", node->GetWindowId()); + belowAppWindowNode_->children_.push_back(node); + layoutPolicy_->AddWindowNode(node); } } -sptr WindowNodeContainer::GetBelowAppWindowNode() const +void WindowNodeContainer::TraverseWindowTree(const WindowNodeOperationFunc& func, bool isFromTopToBottom) const { - return belowAppWindowNode_; + std::vector> rootNodes = { belowAppWindowNode_, appWindowNode_, aboveAppWindowNode_ }; + if (isFromTopToBottom) { + std::reverse(rootNodes.begin(), rootNodes.end()); + } + + for (auto& node : rootNodes) { + if (isFromTopToBottom) { + for (auto iter = node->children_.rbegin(); iter != node->children_.rend(); ++iter) { + if (TraverseFromTopToBottom(*iter, func)) { + return; + } + } + } else { + for (auto iter = node->children_.begin(); iter != node->children_.end(); ++iter) { + if (TraverseFromBottomToTop(*iter, func)) { + return; + } + } + } + } } -sptr WindowNodeContainer::GetAppWindowNode() const +bool WindowNodeContainer::TraverseFromTopToBottom(sptr node, const WindowNodeOperationFunc& func) const { - return appWindowNode_; + if (node == nullptr) { + return false; + } + auto iterBegin = node->children_.rbegin(); + for (; iterBegin != node->children_.rend(); ++iterBegin) { + if ((*iterBegin)->priority_ <= 0) { + break; + } + if (func(*iterBegin)) { + return true; + } + } + if (func(node)) { + return true; + } + for (; iterBegin != node->children_.rend(); ++iterBegin) { + if (func(*iterBegin)) { + return true; + } + } + return false; } -sptr WindowNodeContainer::GetAboveAppWindowNode() const +bool WindowNodeContainer::TraverseFromBottomToTop(sptr node, const WindowNodeOperationFunc& func) const { - return aboveAppWindowNode_; + if (node == nullptr) { + return false; + } + auto iterBegin = node->children_.begin(); + for (; iterBegin != node->children_.end(); ++iterBegin) { + if ((*iterBegin)->priority_ >= 0) { + break; + } + if (func(*iterBegin)) { + return true; + } + } + if (func(node)) { + return true; + } + for (; iterBegin != node->children_.end(); ++iterBegin) { + if (func(*iterBegin)) { + return true; + } + } + return false; } + +void WindowNodeContainer::UpdateWindowVisibilityInfos(std::vector>& infos) +{ + currentCoveredArea_.clear(); + WindowNodeOperationFunc func = [this, &infos](sptr node) { + if (node == nullptr) { + return false; + } + Rect layoutRect = node->GetLayoutRect(); + int32_t nodeX = std::max(0, layoutRect.posX_); + int32_t nodeY = std::max(0, layoutRect.posY_); + int32_t nodeXEnd = std::min(displayRect_.posX_ + static_cast(displayRect_.width_), + layoutRect.posX_ + static_cast(layoutRect.width_)); + int32_t nodeYEnd = std::min(displayRect_.posY_ + static_cast(displayRect_.height_), + layoutRect.posY_ + static_cast(layoutRect.height_)); + + Rect rectInDisplay = {nodeX, nodeY, + static_cast(nodeXEnd - nodeX), static_cast(nodeYEnd - nodeY)}; + bool isCovered = false; + for (auto& rect : currentCoveredArea_) { + if (rectInDisplay.IsInsideOf(rect)) { + isCovered = true; + WLOGD("UpdateWindowVisibilityInfos: find covered window:%{public}u", node->GetWindowId()); + break; + } + } + if (!isCovered) { + currentCoveredArea_.emplace_back(rectInDisplay); + } + if (isCovered != node->isCovered_) { + node->isCovered_ = isCovered; + infos.emplace_back(new WindowVisibilityInfo(node->GetWindowId(), node->GetCallingPid(), + node->GetCallingUid(), !isCovered)); + WLOGD("UpdateWindowVisibilityInfos: covered status changed window:%{public}u, covered:%{public}d", + node->GetWindowId(), isCovered); + } + return false; + }; + TraverseWindowTree(func, true); + WindowManagerAgentController::GetInstance().UpdateWindowVisibilityInfo(infos); } -} \ No newline at end of file + +float WindowNodeContainer::GetVirtualPixelRatio() const +{ + return layoutPolicy_->GetVirtualPixelRatio(); +} + +namespace { + const char DISABLE_WINDOW_ANIMATION_PATH[] = "/etc/disable_window_animation"; +} + +bool WindowNodeContainer::ReadIsWindowAnimationEnabledProperty() +{ + if (access(DISABLE_WINDOW_ANIMATION_PATH, F_OK) == 0) { + return false; + } + return true; +} +} // namespace Rosen +} // namespace OHOS diff --git a/wmserver/src/window_root.cpp b/wmserver/src/window_root.cpp index 25e7a38e..bfa1588e 100644 --- a/wmserver/src/window_root.cpp +++ b/wmserver/src/window_root.cpp @@ -16,6 +16,7 @@ #include "window_root.h" #include +#include #include "display_manager_service_inner.h" #include "window_helper.h" @@ -146,6 +147,22 @@ void WindowRoot::MinimizeAllAppWindows(DisplayId displayId) return container->MinimizeAllAppWindows(); } +WMError WindowRoot::MaxmizeWindow(uint32_t windowId) +{ + auto node = GetWindowNode(windowId); + if (node == nullptr) { + WLOGFE("could not find window"); + return WMError::WM_ERROR_NULLPTR; + } + auto container = GetOrCreateWindowNodeContainer(node->GetDisplayId()); + if (container == nullptr) { + WLOGFE("add window failed, window container could not be found"); + return WMError::WM_ERROR_NULLPTR; + } + container->NotifySystemBarDismiss(node); + return WMError::WM_OK; +} + WMError WindowRoot::AddWindowNode(uint32_t parentId, sptr& node) { if (node == nullptr) { @@ -171,6 +188,7 @@ WMError WindowRoot::AddWindowNode(uint32_t parentId, sptr& node) } if (res == WMError::WM_OK && node->GetWindowProperty()->GetFocusable()) { container->SetFocusWindow(node->GetWindowId()); + needCheckFocusWindow = true; } return res; } @@ -191,7 +209,7 @@ WMError WindowRoot::RemoveWindowNode(uint32_t windowId) return container->RemoveWindowNode(node); } -WMError WindowRoot::UpdateWindowNode(uint32_t windowId) +WMError WindowRoot::UpdateWindowNode(uint32_t windowId, WindowUpdateReason reason) { auto node = GetWindowNode(windowId); if (node == nullptr) { @@ -203,7 +221,7 @@ WMError WindowRoot::UpdateWindowNode(uint32_t windowId) WLOGFE("add window failed, window container could not be found"); return WMError::WM_ERROR_NULLPTR; } - return container->UpdateWindowNode(node); + return container->UpdateWindowNode(node, reason); } WMError WindowRoot::EnterSplitWindowMode(sptr& node) @@ -391,12 +409,32 @@ void WindowRoot::NotifyDisplayChange(sptr abstractDisplay) container->UpdateDisplayRect(abstractDisplay->GetWidth(), abstractDisplay->GetHeight()); } +void WindowRoot::NotifySystemBarTints() +{ + WLOGFD("notify current system bar tints"); + for (auto& it : windowNodeContainerMap_) { + if (it.second != nullptr) { + it.second->NotifySystemBarTints(); + } + } +} + WMError WindowRoot::RaiseZOrderForAppWindow(sptr& node) { if (node == nullptr) { WLOGFW("add window failed, node is nullptr"); return WMError::WM_ERROR_NULLPTR; } + if (node->GetWindowType() == WindowType::WINDOW_TYPE_DOCK_SLICE) { + auto container = GetOrCreateWindowNodeContainer(node->GetDisplayId()); + if (container == nullptr) { + WLOGFW("window container could not be found"); + return WMError::WM_ERROR_NULLPTR; + } + container->RaiseSplitRelatedWindowToTop(node); + return WMError::WM_OK; + } + if (!WindowHelper::IsAppWindow(node->GetWindowType())) { WLOGFW("window is not app window"); return WMError::WM_ERROR_INVALID_TYPE; @@ -457,15 +495,97 @@ WMError WindowRoot::SetWindowLayoutMode(DisplayId displayId, WindowLayoutMode mo return ret; } -void WindowRoot::NotifyDisplayDestory(DisplayId expandDisplayId) +std::string WindowRoot::GenAllWindowsLogInfo() const { - WLOGFW("disconnect expand display, get default and expand display container"); - DisplayId defaultDisplayId = DisplayManagerServiceInner::GetInstance().GetDefaultDisplayId(); - auto expandDisplaycontainer = GetOrCreateWindowNodeContainer(expandDisplayId); - auto defaultDisplaycontainer = GetOrCreateWindowNodeContainer(defaultDisplayId); + std::ostringstream os; + WindowNodeOperationFunc func = [&os](sptr node) { + if (node == nullptr) { + WLOGE("WindowNode is nullptr"); + return false; + } + os<<"window_name:"<GetWindowName()<<",id:"<GetWindowId()<< + ",focusable:"<GetWindowProperty()->GetFocusable()<<";"; + return false; + }; - defaultDisplaycontainer->MoveWindowNode(expandDisplaycontainer); - NotifyDisplayRemoved(expandDisplayId); + for (auto& elem : windowNodeContainerMap_) { + if (elem.second == nullptr) { + continue; + } + os<<"Display "<GetDisplayId()<<":"; + elem.second->TraverseWindowTree(func, true); + } + return os.str(); +} + +void WindowRoot::FocusFaultDetection() const +{ + if (!needCheckFocusWindow) { + return; + } + bool needReport = true; + uint32_t focusWinId = INVALID_WINDOW_ID; + for (auto& elem : windowNodeContainerMap_) { + if (elem.second == nullptr) { + continue; + } + focusWinId = elem.second->GetFocusWindow(); + if (focusWinId != INVALID_WINDOW_ID) { + needReport = false; + sptr windowNode = GetWindowNode(focusWinId); + if (windowNode == nullptr || !windowNode->currentVisibility_) { + needReport = true; + WLOGFE("The focus windowNode is nullptr or is invisible, focusWinId: %{public}u", focusWinId); + break; + } + } + } + if (needReport) { + std::string windowLog(GenAllWindowsLogInfo()); + WLOGFE("The focus window is faulty, focusWinId:%{public}u, %{public}s", focusWinId, windowLog.c_str()); + int32_t ret = OHOS::HiviewDFX::HiSysEvent::Write( + OHOS::HiviewDFX::HiSysEvent::Domain::WINDOW_MANAGER, + "NO_FOCUS_WINDOW", + OHOS::HiviewDFX::HiSysEvent::EventType::FAULT, + "PID", getpid(), + "UID", getuid(), + "PACKAGE_NAME", "foundation", + "PROCESS_NAME", "foundation", + "MSG", windowLog); + if (ret != 0) { + WLOGFE("Write HiSysEvent error, ret:%{public}d", ret); + } + } +} + +void WindowRoot::NotifyDisplayDestroy(DisplayId expandDisplayId) +{ + WLOGFD("disconnect expand display, get default and expand display container"); + DisplayId defaultDisplayId = DisplayManagerServiceInner::GetInstance().GetDefaultDisplayId(); + // get all windowNode below expand display, and reset its displayId + for (auto iter = windowNodeMap_.begin(); iter != windowNodeMap_.end(); iter++) { + auto node = iter->second; + if (node->GetDisplayId() != expandDisplayId) { + continue; + } + node->SetDisplayId(defaultDisplayId); + node->GetWindowToken()->UpdateDisplayId(expandDisplayId, defaultDisplayId); + } + // move windowNode from expand display container to default display container + auto expandDisplayContainer = GetOrCreateWindowNodeContainer(expandDisplayId); + auto defaultDisplayContainer = GetOrCreateWindowNodeContainer(defaultDisplayId); + if (expandDisplayContainer == nullptr || defaultDisplayContainer == nullptr) { + WLOGFE("window node container is nullptr!"); + return; + } + defaultDisplayContainer->MoveWindowNode(expandDisplayContainer); + windowNodeContainerMap_.erase(expandDisplayId); +} + +float WindowRoot::GetVirtualPixelRatio(DisplayId displayId) const +{ + auto container = const_cast(this)->GetOrCreateWindowNodeContainer(displayId); + return container->GetVirtualPixelRatio(); } } } diff --git a/wmserver/test/BUILD.gn b/wmserver/test/BUILD.gn new file mode 100644 index 00000000..a29ddb1b --- /dev/null +++ b/wmserver/test/BUILD.gn @@ -0,0 +1,17 @@ +# Copyright (c) 2022 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +group("test") { + testonly = true + deps = [ "unittest:unittest" ] +} diff --git a/wmserver/test/unittest/BUILD.gn b/wmserver/test/unittest/BUILD.gn new file mode 100644 index 00000000..bea11e84 --- /dev/null +++ b/wmserver/test/unittest/BUILD.gn @@ -0,0 +1,100 @@ +# Copyright (c) 2022 Huawei Device Co., Ltd. +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +import("//build/test.gni") +module_out_path = "window_manager/wms" + +group("unittest") { + testonly = true + + deps = [ ":wms_window_inner_manager_test" ] +} + +## UnitTest wms_window_inner_manager_test {{{ +ohos_unittest("wms_window_inner_manager_test") { + module_out_path = module_out_path + + sources = [ "window_inner_manager_test.cpp" ] + + deps = [ ":wms_unittest_common" ] +} + +## UnitTest wms_window_inner_manager_test }}} + +## Build wms_unittest_common.a {{{ +config("wms_unittest_common_public_config") { + include_dirs = [ + "//foundation/windowmanager/wm/include", + "//foundation/windowmanager/wm/test/unittest", + "//foundation/windowmanager/wmserver/include", + "//foundation/windowmanager/wmserver/include/window_snapshot", + "//foundation/windowmanager/interfaces/innerkits/wm", + "//foundation/windowmanager/utils/include", + "//utils/native/base/include", + "//foundation/communication/ipc/interfaces/innerkits/ipc_core/include", + "//base/hiviewdfx/hilog/interfaces/native/innerkits/include", + "//third_party/googletest/googlemock/include", + + # for abilityContext + "//foundation/aafwk/standard/frameworks/kits/ability/ability_runtime/include", + "//foundation/appexecfwk/standard/interfaces/innerkits/appexecfwk_base/include", + "//foundation/aafwk/standard/frameworks/kits/appkit/native/ability_runtime/context", + "//base/global/resmgr_standard/interfaces/innerkits/include", + "//third_party/node/deps/icu-small/source/common", + "//foundation/aafwk/standard/interfaces/innerkits/ability_manager/include", + "//foundation/aafwk/standard/interfaces/innerkits/want/include/ohos/aafwk/content", + "//foundation/distributedschedule/dmsfwk/services/dtbschedmgr/include", + "//foundation/aafwk/standard/interfaces/innerkits/base/include", + "//third_party/jsoncpp/include", + "//third_party/json/include", + + # abilityContext end + ] + + cflags = [ + "-Wall", + "-Werror", + "-g3", + "-Dprivate=public", + "-Dprotected=public", + ] +} + +ohos_static_library("wms_unittest_common") { + visibility = [ ":*" ] + testonly = true + + public_configs = [ ":wms_unittest_common_public_config" ] + + public_deps = [ + "//foundation/ace/ace_engine/interfaces/innerkits/ace:ace_uicontent", + + # todo need delete it for abilitycontext + "//foundation/aafwk/standard/interfaces/innerkits/ability_manager:ability_manager", + "//foundation/ace/ace_engine/build/external_config/flutter/skia:ace_skia_ohos", + "//foundation/ace/napi:ace_napi", + "//foundation/distributedschedule/safwk/interfaces/innerkits/safwk:system_ability_fwk", + "//foundation/graphic/standard/rosen/modules/render_service_client:librender_service_client", + "//foundation/windowmanager/dm:libdm", + "//foundation/windowmanager/dmserver:libdms", + "//foundation/windowmanager/utils:libwmutil", + "//foundation/windowmanager/wm:libwm", + "//foundation/windowmanager/wmserver:libwms", + "//third_party/googletest:gmock", + "//third_party/googletest:gtest_main", + "//utils/native/base:utils", + ] + + external_deps = [ "ability_runtime:ability_context_native" ] +} +## Build wms_unittest_common.a }}} diff --git a/wmserver/test/unittest/window_inner_manager_test.cpp b/wmserver/test/unittest/window_inner_manager_test.cpp new file mode 100644 index 00000000..3232b1f5 --- /dev/null +++ b/wmserver/test/unittest/window_inner_manager_test.cpp @@ -0,0 +1,149 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include "window_inner_manager_test.h" + +#include "mock_window_adapter.h" +#include "singleton_mocker.h" + +using namespace testing; +using namespace testing::ext; + +namespace OHOS { +namespace Rosen { +using Mocker = SingletonMocker; +WindowInnerManager& WindowInnerManagerTest::innerManager_ = SingletonContainer::Get(); + +void WindowInnerManagerTest::SetUpTestCase() +{ + innerManager_.Init(); + ASSERT_TRUE(innerManager_.hasInitThread_); + ASSERT_FALSE(innerManager_.needDestroyThread_); +} + +void WindowInnerManagerTest::TearDownTestCase() +{ + innerManager_.SendMessage(INNER_WM_DESTROY_THREAD); + sleep(SEND_MSG_SLEEP_S); + ASSERT_FALSE(innerManager_.hasInitThread_); + ASSERT_TRUE(innerManager_.needDestroyThread_); +} + +void WindowInnerManagerTest::SetUp() +{ +} + +void WindowInnerManagerTest::TearDown() +{ +} + +namespace { +/** + * @tc.name: SendMessage01 + * @tc.desc: Init thread, wait for message, test dividerMap + * @tc.type: FUNC + */ +HWTEST_F(WindowInnerManagerTest, InitThread01, Function | SmallTest | Level3) +{ + ASSERT_TRUE(innerManager_.GetDividerWindow(displayId_) == nullptr); +} + +/** + * @tc.name: SendMessage01 + * @tc.desc: create and show divider, mock create window return nullptr + * @tc.type: FUNC + */ +HWTEST_F(WindowInnerManagerTest, SendMessage01, Function | SmallTest | Level3) +{ + std::unique_ptr m = std::make_unique(); + EXPECT_CALL(m->Mock(), CreateWindow(_, _, _, _)).Times(1).WillOnce(Return(WMError::WM_ERROR_SAMGR)); + innerManager_.SendMessage(INNER_WM_CREATE_DIVIDER, displayId_); + sleep(SEND_MSG_SLEEP_S); + ASSERT_TRUE(innerManager_.GetDividerWindow(displayId_) == nullptr); +} + +/** + * @tc.name: SendMessage02 + * @tc.desc: create and show divider, mock create window return new window, hide and destroy success + * @tc.type: FUNC + */ +HWTEST_F(WindowInnerManagerTest, SendMessage02, Function | SmallTest | Level3) +{ + std::unique_ptr m = std::make_unique(); + EXPECT_CALL(m->Mock(), CreateWindow(_, _, _, _)).Times(1).WillOnce(Return(WMError::WM_OK)); + EXPECT_CALL(m->Mock(), AddWindow(_)).Times(1).WillOnce(Return(WMError::WM_OK)); + innerManager_.SendMessage(INNER_WM_CREATE_DIVIDER, displayId_); + sleep(SEND_MSG_SLEEP_S); + ASSERT_TRUE(innerManager_.GetDividerWindow(displayId_) != nullptr); + + EXPECT_CALL(m->Mock(), RemoveWindow(_)).Times(1).WillOnce(Return(WMError::WM_OK)); + EXPECT_CALL(m->Mock(), DestroyWindow(_)).Times(1).WillOnce(Return(WMError::WM_OK)); + innerManager_.SendMessage(INNER_WM_DESTROY_DIVIDER, displayId_); + sleep(SEND_MSG_SLEEP_S); + ASSERT_TRUE(innerManager_.GetDividerWindow(displayId_) == nullptr); +} + +/** + * @tc.name: SendMessage03 + * @tc.desc: create and show divider, mock hide return error + * @tc.type: FUNC + */ +HWTEST_F(WindowInnerManagerTest, SendMessage03, Function | SmallTest | Level3) +{ + std::unique_ptr m = std::make_unique(); + EXPECT_CALL(m->Mock(), CreateWindow(_, _, _, _)).Times(1).WillOnce(Return(WMError::WM_OK)); + EXPECT_CALL(m->Mock(), AddWindow(_)).Times(1).WillOnce(Return(WMError::WM_OK)); + innerManager_.SendMessage(INNER_WM_CREATE_DIVIDER, displayId_); + sleep(SEND_MSG_SLEEP_S); + ASSERT_TRUE(innerManager_.GetDividerWindow(displayId_) != nullptr); + + EXPECT_CALL(m->Mock(), RemoveWindow(_)).Times(1).WillOnce(Return(WMError::WM_ERROR_SAMGR)); + innerManager_.SendMessage(INNER_WM_DESTROY_DIVIDER, displayId_); + sleep(SEND_MSG_SLEEP_S); + ASSERT_TRUE(innerManager_.GetDividerWindow(displayId_) != nullptr); + + EXPECT_CALL(m->Mock(), RemoveWindow(_)).Times(1).WillOnce(Return(WMError::WM_OK)); + EXPECT_CALL(m->Mock(), DestroyWindow(_)).Times(1).WillOnce(Return(WMError::WM_OK)); + innerManager_.SendMessage(INNER_WM_DESTROY_DIVIDER, displayId_); + sleep(SEND_MSG_SLEEP_S); +} + +/** + * @tc.name: SendMessage04 + * @tc.desc: create and show divider, mock destroy return error + * @tc.type: FUNC + */ +HWTEST_F(WindowInnerManagerTest, SendMessage04, Function | SmallTest | Level3) +{ + std::unique_ptr m = std::make_unique(); + EXPECT_CALL(m->Mock(), CreateWindow(_, _, _, _)).Times(1).WillOnce(Return(WMError::WM_OK)); + EXPECT_CALL(m->Mock(), AddWindow(_)).Times(1).WillOnce(Return(WMError::WM_OK)); + innerManager_.SendMessage(INNER_WM_CREATE_DIVIDER, displayId_); + sleep(SEND_MSG_SLEEP_S); + ASSERT_TRUE(innerManager_.GetDividerWindow(displayId_) != nullptr); + + EXPECT_CALL(m->Mock(), RemoveWindow(_)).Times(1).WillOnce(Return(WMError::WM_OK)); + EXPECT_CALL(m->Mock(), DestroyWindow(_)).Times(1).WillOnce(Return(WMError::WM_ERROR_SAMGR)); + innerManager_.SendMessage(INNER_WM_DESTROY_DIVIDER, displayId_); + sleep(SEND_MSG_SLEEP_S); + ASSERT_TRUE(innerManager_.GetDividerWindow(displayId_) != nullptr); + + EXPECT_CALL(m->Mock(), DestroyWindow(_)).Times(1).WillOnce(Return(WMError::WM_OK)); + innerManager_.SendMessage(INNER_WM_DESTROY_DIVIDER, displayId_); + sleep(SEND_MSG_SLEEP_S); +} +} +} // namespace Rosen +} // namespace OHOS \ No newline at end of file diff --git a/wmserver/test/unittest/window_inner_manager_test.h b/wmserver/test/unittest/window_inner_manager_test.h new file mode 100644 index 00000000..44863ed6 --- /dev/null +++ b/wmserver/test/unittest/window_inner_manager_test.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2022 Huawei Device Co., Ltd. + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#ifndef FRAMEWORKS_WM_TEST_UT_WINDOW_INNER_MANAGER_TEST_H +#define FRAMEWORKS_WM_TEST_UT_WINDOW_INNER_MANAGER_TEST_H + +#include + +#include "window_inner_manager.h" + +namespace OHOS { +namespace Rosen { +class WindowInnerManagerTest : public testing::Test { +public: + static void SetUpTestCase(); + static void TearDownTestCase(); + virtual void SetUp() override; + virtual void TearDown() override; + DisplayId displayId_ = 0; + static WindowInnerManager& innerManager_; + static constexpr uint32_t SEND_MSG_SLEEP_S = 1; // send message sleep time +}; +} // namespace ROSEN +} // namespace OHOS + +#endif // FRAMEWORKS_WM_TEST_UT_WINDOW_INNER_MANAGER_TEST_H \ No newline at end of file diff --git a/wmtest/BUILD.gn b/wmtest/BUILD.gn deleted file mode 100644 index f91fd2eb..00000000 --- a/wmtest/BUILD.gn +++ /dev/null @@ -1,84 +0,0 @@ -# Copyright (c) 2021 Huawei Device Co., Ltd. -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import("//build/ohos.gni") - -## Build rosenwmtest {{{ -config("rosenwmtest_config") { - visibility = [ ":*" ] - - include_dirs = [ - "frameworks", - - # for abilityContext - "//foundation/aafwk/standard/frameworks/kits/ability/ability_runtime/include", - "//foundation/appexecfwk/standard/interfaces/innerkits/appexecfwk_base/include", - "//base/global/resmgr_standard/interfaces/innerkits/include", - "//third_party/node/deps/icu-small/source/common", - "//foundation/aafwk/standard/interfaces/innerkits/ability_manager/include", - "//foundation/aafwk/standard/interfaces/innerkits/want/include/ohos/aafwk/content", - "//foundation/distributedschedule/dmsfwk/services/dtbschedmgr/include", - "//foundation/aafwk/standard/interfaces/innerkits/base/include", - - # RSSurface - "//foundation/graphic/standard/rosen/modules/render_service_client:librender_service_client", - "//foundation/graphic/standard/rosen/modules/render_service_base:librender_service_base", - ] - - cflags = [ - "-Wall", - "-Werror", - "-g3", - ] -} - -ohos_executable("rosenwmtest") { - install_enable = false - - sources = [ - "frameworks/inative_test.cpp", - "frameworks/main.cpp", - "test/dm_native_test.cpp", - "test/wm_native_test.cpp", - ] - - configs = [ ":rosenwmtest_config" ] - - deps = [ - "//foundation/graphic/standard:libvsync_client", - "//foundation/graphic/standard:libwmclient", - "//foundation/graphic/standard:libwmservice", - "//foundation/windowmanager/utils:libwmutil", - "//foundation/windowmanager/wm:libwm", - "//foundation/windowmanager/wmserver:libwms", - "//third_party/zlib:libz", - - # ace - # native value - "//foundation/ace/ace_engine/interfaces/innerkits/ace:ace_uicontent", - "//foundation/ace/napi:ace_napi", - ] - - external_deps = [ "samgr_standard:samgr_proxy" ] - - part_name = "window_manager" - subsystem_name = "window" -} - -## Build rosenwmtest }}} - -group("test") { - testonly = true - - deps = [ "unittest:unittest" ] -} diff --git a/wmtest/frameworks/main.cpp b/wmtest/frameworks/main.cpp deleted file mode 100644 index 70e78401..00000000 --- a/wmtest/frameworks/main.cpp +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright (c) 2021 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include -#include -#include -#include -#include -#include - -#include - -#include "inative_test.h" - -using namespace OHOS::Rosen; - -namespace { -void Usage(const char *argv0) -{ - printf("Usage: %s type id\n", argv0); - auto visitFunc = [](const INativeTest *test) { - std::stringstream ss; - ss << test->GetDomain() << ", id="; - ss << test->GetID() << ": "; - ss << test->GetDescription(); - if (test->GetLastTime() != INativeTest::LAST_TIME_FOREVER) { - constexpr double msecToSec = 1000.0; - ss << " (last " << std::setprecision(1) << test->GetLastTime() / msecToSec << "s)"; - } - std::cout << ss.str() << std::endl; - }; - INativeTest::VisitTests(visitFunc); -} -} // namespace - -int32_t main(int32_t argc, const char **argv) -{ - constexpr int32_t argNumber = 2; - if (argc <= argNumber) { - Usage(argv[0]); - return 0; - } - - int32_t testcase = -1; - constexpr int32_t domainIndex = 1; - constexpr int32_t idIndex = 2; - std::stringstream ss(argv[idIndex]); - ss >> testcase; - if (ss.fail() == true || testcase == -1) { - Usage(argv[0]); - return 1; - } - - INativeTest *found = nullptr; - auto visitFunc = [argv, testcase, &found](INativeTest *test) { - if (test->GetDomain() == argv[domainIndex] && test->GetID() == testcase) { - found = test; - } - }; - INativeTest::VisitTests(visitFunc); - if (found == nullptr) { - printf("not found test %d\n", testcase); - return 1; - } - - auto runner = OHOS::AppExecFwk::EventRunner::Create(false); - auto handler = std::make_shared(runner); - handler->PostTask(std::bind(&INativeTest::Run, found, argc - 1, argv + 1)); - if (found->GetLastTime() != INativeTest::LAST_TIME_FOREVER) { - handler->PostTask(std::bind(&OHOS::AppExecFwk::EventRunner::Stop, runner), found->GetLastTime()); - } - - printf("%d %s run! pid=%d\n", found->GetID(), found->GetDescription().c_str(), getpid()); - runner->Run(); - return 0; -} diff --git a/wmtest/test/dm_native_test.cpp b/wmtest/test/dm_native_test.cpp deleted file mode 100644 index 3c1a9711..00000000 --- a/wmtest/test/dm_native_test.cpp +++ /dev/null @@ -1,97 +0,0 @@ -/* - * Copyright (c) 2021 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "dm_native_test.h" - -#include -#include -#include -#include "display_manager.h" -#include "singleton_container.h" -#include "wm_common.h" - -using namespace OHOS::Rosen; - -namespace { -DMNativeTest g_autoload; -} // namespace - -std::string DMNativeTest::GetDescription() const -{ - constexpr const char *desc = "normal display"; - return desc; -} - -std::string DMNativeTest::GetDomain() const -{ - constexpr const char *desc = "dmclient"; - return desc; -} - -int32_t DMNativeTest::GetID() const -{ - constexpr int32_t id = 1; - return id; -} - -uint32_t DMNativeTest::GetLastTime() const -{ - constexpr uint32_t lastTime = LAST_TIME_FOREVER; - return lastTime; -} - -void DMNativeTest::Run(int32_t argc, const char **argv) -{ - printf("DMNativeTest run begin\n"); - sptr dms = DisplayManager::GetInstance(); - if (dms == nullptr) { - printf("dms error!\n"); - return; - } - - DisplayId displayId = dms->GetDefaultDisplayId(); - printf("defaultDisplayId: %" PRIu64"\n", displayId); - - auto display = dms->GetDefaultDisplay(); - if (display == nullptr) { - printf("GetDefaultDisplay: failed!\n"); - } else { - printf("GetDefaultDisplay: id %" PRIu64", w %d, h %d, fps %u\n", display->GetId(), display->GetWidth(), - display->GetHeight(), display->GetFreshRate()); - } - - auto ids = dms->GetAllDisplayIds(); - for (auto id: ids) { - display = dms->GetDisplayById(displayId); - if (display == nullptr) { - printf("GetDisplayById(%" PRIu64"): failed!\n", id); - } else { - printf("GetDisplayById(%" PRIu64"): id %" PRIu64", w %d, h %d, fps %u\n", id, display->GetId(), - display->GetWidth(), display->GetHeight(), display->GetFreshRate()); - } - } - - auto displays = dms->GetAllDisplays(); - for (auto disp: displays) { - if (disp == nullptr) { - printf("GetAllDisplays: failed!\n"); - } else { - printf("GetAllDisplays: id %" PRIu64", w %d, h %d, fps %u\n", disp->GetId(), disp->GetWidth(), - disp->GetHeight(), disp->GetFreshRate()); - } - } - - printf("DMNativeTest run finish\n"); -} diff --git a/wmtest/test/dm_native_test.h b/wmtest/test/dm_native_test.h deleted file mode 100644 index 7b325bf8..00000000 --- a/wmtest/test/dm_native_test.h +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2021 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef OHOS_ROSEN_DM_NATIVE_TEST_H -#define OHOS_ROSEN_DM_NATIVE_TEST_H - -#include -#include "inative_test.h" - -namespace OHOS::Rosen { -class DMNativeTest : public INativeTest { -public: - virtual ~DMNativeTest() = default; - virtual std::string GetDescription() const override; - virtual std::string GetDomain() const override; - virtual int32_t GetID() const override; - virtual uint32_t GetLastTime() const override; - - virtual void Run(int32_t argc, const char **argv) override; - -private: - void PostTask(std::function func, uint32_t delayTime = 0); - void ExitTest(); - int64_t GetNowTime(); -}; -} - -#endif // OHOS_ROSEN_DM_NATIVE_TEST_H diff --git a/wmtest/test/wm_native_test.cpp b/wmtest/test/wm_native_test.cpp deleted file mode 100644 index f5749e97..00000000 --- a/wmtest/test/wm_native_test.cpp +++ /dev/null @@ -1,74 +0,0 @@ -/* - * Copyright (c) 2021 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#include "wm_native_test.h" - -#include -#include -#include -#include "window.h" -#include "window_life_cycle_interface.h" -#include "window_option.h" -#include "window_scene.h" -#include "wm_common.h" - -using namespace OHOS::Rosen; - -namespace { -WMNativeTest g_autoload; -} // namespace - -std::string WMNativeTest::GetDescription() const -{ - constexpr const char *desc = "normal window"; - return desc; -} - -std::string WMNativeTest::GetDomain() const -{ - constexpr const char *desc = "wmclient"; - return desc; -} - -int32_t WMNativeTest::GetID() const -{ - constexpr int32_t id = 1; - return id; -} - -uint32_t WMNativeTest::GetLastTime() const -{ - constexpr uint32_t lastTime = LAST_TIME_FOREVER; - return lastTime; -} - -void WMNativeTest::Run(int32_t argc, const char **argv) -{ - DisplayId displayId = 0; - sptr listener = nullptr; - sptr scene = new WindowScene(); - std::shared_ptr abilityContext = nullptr; - WMError rtn = scene->Init(displayId, abilityContext, listener); - if (rtn != OHOS::Rosen::WMError::WM_OK) { - return; - } - - while (true) { - scene->GoForeground(); - sleep(3); // Sleep for 3 seconds - scene->GoBackground(); - sleep(3); // Sleep for 3 seconds - } -} diff --git a/wmtest/test/wm_native_test.h b/wmtest/test/wm_native_test.h deleted file mode 100644 index 6b978531..00000000 --- a/wmtest/test/wm_native_test.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright (c) 2021 Huawei Device Co., Ltd. - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -#ifndef OHOS_ROSEN_WM_NATIVE_TEST_H -#define OHOS_ROSEN_WM_NATIVE_TEST_H - -#include "inative_test.h" - -namespace OHOS::Rosen { -class WMNativeTest : public INativeTest { -public: - virtual ~WMNativeTest() = default; - virtual std::string GetDescription() const override; - virtual std::string GetDomain() const override; - virtual int32_t GetID() const override; - virtual uint32_t GetLastTime() const override; - - virtual void Run(int32_t argc, const char **argv) override; - -private: - void PostTask(std::function func, uint32_t delayTime = 0); - void ExitTest(); - int64_t GetNowTime(); -}; -} - -#endif // OHOS_ROSEN_WM_NATIVE_TEST_H