6

由浅入深学习新模块之Window_manager(二)

 1 year ago
source link: https://www.51cto.com/article/749323.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

由浅入深学习新模块之Window_manager(二)

作者:王清 2023-03-15 16:16:07
本文开始介绍OpenHarmony的Window_manager的具体实现相关。
a8687f4809be7f54822618d7e0dab9cedb1bfa.png

​想了解更多关于开源的内容,请访问:​

​51CTO 开源基础软件社区​

​https://ost.51cto.com​

在​​上一篇​​文章中,主要介绍了window_manager的发展史和功能介绍,本文开始介绍OpenHarmony的window_manager的具体实现相关。

window_manager在OpenHarmony中的代码目录:

foundation/window/window_manager/
├── dm                              # Dislplay Manager Client实现代码    
│   ├── BUILD.gn                    
│   ├── include                      
│   ├── src                          
│   └── test                         
├── dmserver                        # Dislplay Manager Service实现代码  
│   ├── BUILD.gn                      
│   ├── include                       
│   ├── src                           
│   └── test                          
├── extension                       # Ability Component 窗口相关代码实现目录  
│   ├── extension_connection        # Ability Component 嵌入部分 
│   └── window_extension            # Ability Component 被嵌入部分                                                  
├── interfaces                      # 对外接口存放目录   
│   ├── innerkits                   # native接口存放目录   
│   └── kits                        # js/napi接口存放目录  
├── previewer                       # IDE轻量模拟器窗口代码实现目录   
│   ├── BUILD.gn                      
│   ├── include                       
│   ├── mock                          
│   └── src                           
├── resources                       # 框架使用资源文件存放目录   
│   ├── BUILD.gn                      
│   ├── config                        
│   ├── dialog_ui                     
│   └── media                       
├── sa_profile                      # 系统服务配置文件
│   ├── 4606.xml                   
│   ├── 4607.xml                   
│   └── BUILD.gn                   
├── snapshot                        # 截屏命令行工具实现代码 
│   ├── BUILD.gn                     
│   ├── include                      
│   ├── src                          
│   └── test                         
├── test                            # Fuzz测试和系统测试用例存放目录 
│   ├── BUILD.gn                    
│   ├── common                      
│   ├── demo                        
│   ├── fuzztest                    
│   └── systemtest                                                      
├── utils                           # 工具类存放目录  
│   ├── BUILD.gn                      
│   ├── include                       
│   ├── src                           
│   └── test                                              
├── wm                              # Window Manager Client实现代码  
│   ├── BUILD.gn                      
│   ├── include                       
│   ├── src                           
│   └── test                          
└── wmserver                        # Window Manager Service实现代码  
    ├── BUILD.gn                      
    ├── include                       
    ├── src                           
    └── test

比较核心的文件夹是两个使用Client-Server模型的wm/wmserver,dm/dmserver文件夹,其中Client端提供模块对外的接口,Server端提供具体的实现。下面我们以wm/wmserver为例讲解下windowmanager的实现。

window_manager的代码实现:

小Tip:当学习一个新的模块的时候,如果不知道如何下手,可以在这个模块中选择一个具体的功能(最好是具有代表性的),找到相关的接口(流程里的任何阶段的都可以),然后去通过不断的查询调用者和接口本身的实现又调用了谁来梳理下流程,画出时序图,然后根据定义接口的头文件来确定类图。这两个图确定后,整体的代码结构和流程就会变得清晰。

我们先回顾下窗口管理的相关功能:

窗口管理:窗口提供管理窗口的一些基础能力,包括对当前窗口的创建、销毁、各属性设置,以及对各窗口间的管理调度。

我们很容易可以在window_impl.h文件中找到这些基础能力的对应接口:

\foundation\window\window_manager\wm\include\window_impl.h。

WMError Create(uint32_t parentId,   //创建
        const std::shared_ptr<AbilityRuntime::Context>& context = nullptr);
    virtual WMError Destroy() override; //销毁
    
    //窗口的管理调度
    virtual WMError Show(uint32_t reason = 0, bool withAnimation = false) override;
    virtual WMError Hide(uint32_t reason = 0, bool withAnimation = false) override;
    virtual WMError MoveTo(int32_t x, int32_t y) override;
    virtual WMError Resize(uint32_t width, uint32_t height) override;
    virtual WMError SetKeepScreenOn(bool keepScreenOn) override;
    virtual bool IsKeepScreenOn() const override;
    virtual WMError SetTurnScreenOn(bool turnScreenOn) override;
    virtual bool IsTurnScreenOn() const override;
    virtual WMError SetBackgroundColor(const std::string& color) override;
    virtual WMError SetTransparent(bool isTransparent) override;
    virtual bool IsTransparent() const override;
    virtual WMError SetBrightness(float brightness) override;
    virtual float GetBrightness() const override;
    virtual WMError SetCallingWindow(uint32_t windowId) override;
    virtual void SetPrivacyMode(bool isPrivacyMode) override;
    virtual bool IsPrivacyMode() const override;
    virtual void SetSystemPrivacyMode(bool isSystemPrivacyMode) override;
    virtual void DisableAppWindowDecor() override;
    virtual WMError BindDialogTarget(sptr<IRemoteObject> targetToken) override;
    virtual void SetSnapshotSkip(bool isSkip) override;

    // window effect  属性设置
    virtual WMError SetCornerRadius(float cornerRadius) override;
    virtual WMError SetShadowRadius(float radius) override;
    virtual WMError SetShadowColor(std::string color) override;
    virtual void SetShadowOffsetX(float offsetX) override;
    virtual void SetShadowOffsetY(float offsetY) override;
    virtual WMError SetBlur(float radius) override;
    virtual WMError SetBackdropBlur(float radius) override;
    virtual WMError SetBackdropBlurStyle(WindowBlurStyle blurStyle) override;

我们再以窗口的创建函数为例梳理下流程:

Create函数的实现:

\foundation\window\window_manager\wm\src\window_impl.cpp。

WMError WindowImpl::Create(uint32_t parentId, const std::shared_ptr<AbilityRuntime::Context>& context)
{
    //此处省略若干代码
        WMError ret = SingletonContainer::Get<WindowAdapter>().CreateWindow(windowAgent, property_, surfaceNode_,
        windowId, token);
    RecordLifeCycleExceptionEvent(LifeCycleEvent::CREATE_EVENT, ret);
    //此处省略若干代码
    return ret;
}

可以再代码里面看到调用了WindowAdapter中的CreateWindow函数,而本身WindowImpl::Create的调用者可以通过IDE工具搜到:

\foundation\window\window_manager\wm\src\window.cpp。

sptr<Window> Window::Create(const std::string& windowName, sptr<WindowOption>& option,
    const std::shared_ptr<OHOS::AbilityRuntime::Context>& context)
{
    //此处省略若干代码
    WMError error = windowImpl->Create(option->GetParentId(), context);//调用windowImpl->Create
    if (error != WMError::WM_OK) {
        return nullptr;
    }
    return windowImpl;
}

通过不断的寻找调用者和调用的接口,可以获得一个时序图(图1):

由浅入深学习新模块之window_manager(二)-开源基础软件社区

图1 开机动画窗口创建时序图

  1. 这个是开机动画创建窗口流程时序图。
  2. rs_surface_node.cpp这个类负责窗口的绘制,属于graphic模块的内容,和window_manager模块的关系就是window_manager的窗口最终还是要依赖graphic模块去进行绘制的。
  3. window_adapter.cpp与window_manager_service.cpp之间使用IPC进行跨进程通讯,详细的IPC实现说明会在下篇文章介绍。

代码的文件结构清晰了,大致的代码流程也熟悉了,可以绘制类图了(现在很多工具可以自动绘制类图,但是建议自己亲手绘制下,对理清代码结构和思路很有帮助)。

由浅入深学习新模块之window_manager(二)-开源基础软件社区
由浅入深学习新模块之window_manager(二)-开源基础软件社区

图2 windowmanager类图

  1. window_manager_service是窗口管理的服务端类,窗口管理功能的具体实现是在服务端实现。
  2. window_manager_service和window_adapter属于不同线程,他们通过IPC进行通讯。
  3. 窗口管理服务,提供窗口布局、Z序控制、窗口树结构、窗口拖拽、窗口快照等能力,并提供窗口布局和焦点窗口给多模输入,这些功能在各个类的中的对应:
    窗口布局:WindowLayOutPolicy
    Z序控制:WindowZorderPolicy
    窗口树结构:WindowRoot
    窗口拖拽:DragController
    窗口快照:SnapshotController
    提供多模输入:InputWindowMonitor

具体的代码实现有兴趣的同学可以自行研究,更有兴趣的同学可以考虑绘制下DisplayManager的时序图和类图。

参考文献:

https://gitee.com/openharmony/window_window_manager 《window_manger仓源码》

​想了解更多关于开源的内容,请访问:​

​51CTO 开源基础软件社区​

​https://ost.51cto.com​

责任编辑:jianghua 来源: 51CTO 开源基础软件社区

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK