
??想了解更多關于開源的內容,請訪問:??
??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):


圖1 開機動畫窗口創建時序圖
說明:
- 這個是開機動畫創建窗口流程時序圖。
- rs_surface_node.cpp這個類負責窗口的繪制,屬于graphic模塊的內容,和window_manager模塊的關系就是window_manager的窗口最終還是要依賴graphic模塊去進行繪制的。
- window_adapter.cpp與window_manager_service.cpp之間使用IPC進行跨進程通訊,詳細的IPC實現說明會在下篇文章介紹。
代碼的文件結構清晰了,大致的代碼流程也熟悉了,可以繪制類圖了(現在很多工具可以自動繪制類圖,但是建議自己親手繪制下,對理清代碼結構和思路很有幫助)。


圖2 windowmanager類圖
說明:
- window_manager_service是窗口管理的服務端類,窗口管理功能的具體實現是在服務端實現。
- window_manager_service和window_adapter屬于不同線程,他們通過IPC進行通訊。
- 窗口管理服務,提供窗口布局、Z序控制、窗口樹結構、窗口拖拽、窗口快照等能力,并提供窗口布局和焦點窗口給多模輸入,這些功能在各個類的中的對應:
窗口布局:WindowLayOutPolicy
Z序控制:WindowZorderPolicy
窗口樹結構:WindowRoot
窗口拖拽:DragController
窗口快照:SnapshotController
提供多模輸入:InputWindowMonitor
具體的代碼實現有興趣的同學可以自行研究,更有興趣的同學可以考慮繪制下DisplayManager的時序圖和類圖。
參考文獻:
https://gitee.com/openharmony/window_window_manager 《window_manger倉源碼》
??想了解更多關于開源的內容,請訪問:??
??51CTO 開源基礎軟件社區??
??https://ost.51cto.com??