• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "starting_window.h"
17 #include <ability_manager_client.h>
18 #include <common/rs_common_def.h>
19 #include <display_manager_service_inner.h>
20 #include <hitrace_meter.h>
21 #include <transaction/rs_transaction.h>
22 #include "remote_animation.h"
23 #include "window_helper.h"
24 #include "window_inner_manager.h"
25 #include "window_manager_hilog.h"
26 #include "window_manager_service.h"
27 
28 namespace OHOS {
29 namespace Rosen {
30 namespace {
31     constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WINDOW, "StartingWindow"};
32 }
33 
34 std::recursive_mutex StartingWindow::mutex_;
35 WindowMode StartingWindow::defaultMode_ = WindowMode::WINDOW_MODE_FULLSCREEN;
36 
CreateWindowNode(const sptr<WindowTransitionInfo> & info,uint32_t winId)37 sptr<WindowNode> StartingWindow::CreateWindowNode(const sptr<WindowTransitionInfo>& info, uint32_t winId)
38 {
39     sptr<WindowProperty> property = new(std::nothrow) WindowProperty();
40     if (property == nullptr || info == nullptr) {
41         return nullptr;
42     }
43 
44     property->SetRequestRect(info->GetWindowRect());
45     if (WindowHelper::IsValidWindowMode(info->GetWindowMode())) {
46         property->SetWindowMode(info->GetWindowMode());
47     } else {
48         property->SetWindowMode(defaultMode_);
49     }
50 
51     property->SetDisplayId(info->GetDisplayId());
52     property->SetWindowType(info->GetWindowType());
53     property->AddWindowFlag(WindowFlag::WINDOW_FLAG_NEED_AVOID);
54     if (info->GetShowFlagWhenLocked()) {
55         property->AddWindowFlag(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED);
56     }
57     property->SetWindowId(winId);
58     sptr<WindowNode> node = new(std::nothrow) WindowNode(property);
59     if (node == nullptr) {
60         return nullptr;
61     }
62     // test
63     node->stateMachine_.SetWindowId(winId);
64     node->abilityToken_ = info->GetAbilityToken();
65     node->SetWindowSizeLimits(info->GetWindowSizeLimits());
66     node->abilityInfo_.missionId_ = info->GetMissionId();
67     node->abilityInfo_.bundleName_ = info->GetBundleName();
68     node->abilityInfo_.abilityName_ = info->GetAbilityName();
69     uint32_t modeSupportInfo = WindowHelper::ConvertSupportModesToSupportInfo(info->GetWindowSupportModes());
70     node->SetModeSupportInfo(modeSupportInfo);
71 
72     if (CreateLeashAndStartingSurfaceNode(node) != WMError::WM_OK) {
73         return nullptr;
74     }
75     node->stateMachine_.TransitionTo(WindowNodeState::STARTING_CREATED);
76     return node;
77 }
78 
CreateLeashAndStartingSurfaceNode(sptr<WindowNode> & node)79 WMError StartingWindow::CreateLeashAndStartingSurfaceNode(sptr<WindowNode>& node)
80 {
81     struct RSSurfaceNodeConfig rsSurfaceNodeConfig;
82     rsSurfaceNodeConfig.SurfaceNodeName = "leashWindow" + std::to_string(node->GetWindowId());
83     node->leashWinSurfaceNode_ = RSSurfaceNode::Create(rsSurfaceNodeConfig, RSSurfaceNodeType::LEASH_WINDOW_NODE);
84     if (node->leashWinSurfaceNode_ == nullptr) {
85         WLOGFE("create leashWinSurfaceNode failed");
86         return WMError::WM_ERROR_NULLPTR;
87     }
88 
89     rsSurfaceNodeConfig.SurfaceNodeName = "startingWindow" + std::to_string(node->GetWindowId());
90     node->startingWinSurfaceNode_ = RSSurfaceNode::Create(rsSurfaceNodeConfig, RSSurfaceNodeType::STARTING_WINDOW_NODE);
91     if (node->startingWinSurfaceNode_ == nullptr) {
92         WLOGFE("create startingWinSurfaceNode failed");
93         node->leashWinSurfaceNode_ = nullptr;
94         return WMError::WM_ERROR_NULLPTR;
95     }
96     WLOGFI("Create leashWinSurfaceNode and startingWinSurfaceNode success with id:%{public}u!", node->GetWindowId());
97     return WMError::WM_OK;
98 }
99 
DrawStartingWindow(sptr<WindowNode> & node,std::shared_ptr<Media::PixelMap> pixelMap,uint32_t bkgColor,bool isColdStart)100 WMError StartingWindow::DrawStartingWindow(sptr<WindowNode>& node,
101     std::shared_ptr<Media::PixelMap> pixelMap, uint32_t bkgColor, bool isColdStart)
102 {
103     if (node == nullptr) {
104         return WMError::WM_ERROR_NULLPTR;
105     }
106     // using snapshot to support hot start since node destroy when hide
107     HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "wms:DrawStartingWindow(%u)", node->GetWindowId());
108     Rect rect = node->GetWindowRect();
109     if (RemoteAnimation::CheckRemoteAnimationEnabled(node->GetDisplayId()) && node->leashWinSurfaceNode_) {
110         // hides this node until RSProxyNode send valid context alpha/matrix
111         node->leashWinSurfaceNode_->ResetContextAlpha();
112     }
113     if (!isColdStart) {
114         return WMError::WM_OK;
115     }
116     if (node->startingWinSurfaceNode_ == nullptr) {
117         WLOGFE("no starting Window SurfaceNode!");
118         return WMError::WM_ERROR_NULLPTR;
119     }
120     if (pixelMap == nullptr) {
121         SurfaceDraw::DrawColor(node->startingWinSurfaceNode_, rect.width_, rect.height_, bkgColor);
122         return WMError::WM_OK;
123     }
124 
125     WLOGFD("draw background in sperate");
126     SurfaceDraw::DrawImageRect(node->startingWinSurfaceNode_, rect, pixelMap, bkgColor);
127     return WMError::WM_OK;
128 }
129 
HandleClientWindowCreate(sptr<WindowNode> & node,sptr<IWindow> & window,uint32_t & windowId,const std::shared_ptr<RSSurfaceNode> & surfaceNode,sptr<WindowProperty> & property,int32_t pid,int32_t uid)130 void StartingWindow::HandleClientWindowCreate(sptr<WindowNode>& node, sptr<IWindow>& window,
131     uint32_t& windowId, const std::shared_ptr<RSSurfaceNode>& surfaceNode, sptr<WindowProperty>& property,
132     int32_t pid, int32_t uid)
133 {
134     if (node == nullptr) {
135         WLOGFE("node is nullptr");
136         return;
137     }
138     node->surfaceNode_ = surfaceNode;
139     node->SetWindowToken(window);
140     node->SetCallingPid(pid);
141     node->SetCallingUid(uid);
142     windowId = node->GetWindowId();
143     // test
144     node->stateMachine_.SetWindowId(windowId);
145     node->stateMachine_.SetWindowType(property->GetWindowType());
146     WLOGFI("after set Id:%{public}u, requestRect:[%{public}d, %{public}d, %{public}u, %{public}u]",
147         node->GetWindowId(), node->GetRequestRect().posX_, node->GetRequestRect().posY_,
148         node->GetRequestRect().width_, node->GetRequestRect().height_);
149     // Register FirstFrame Callback to rs, replace startwin
150     wptr<WindowNode> weak = node;
151     auto firstFrameCompleteCallback = [weak]() {
152         WindowManagerService::GetInstance().PostAsyncTask([weak]() {
153             FinishAsyncTraceArgs(HITRACE_TAG_WINDOW_MANAGER, static_cast<int32_t>(TraceTaskId::STARTING_WINDOW),
154                 "wms:async:ShowStartingWindow");
155             auto weakNode = weak.promote();
156             if (weakNode == nullptr || weakNode->leashWinSurfaceNode_ == nullptr) {
157                 WLOGFE("windowNode or leashWinSurfaceNode_ is nullptr");
158                 return;
159             }
160             WLOGFI("StartingWindow::Replace surfaceNode, id: %{public}u", weakNode->GetWindowId());
161             weakNode->leashWinSurfaceNode_->RemoveChild(weakNode->startingWinSurfaceNode_);
162             WindowInnerManager::GetInstance().CompleteFirstFrameDrawing(weakNode);
163             RSTransaction::FlushImplicitTransaction();
164             weakNode->firstFrameAvaliable_ = true;
165             weakNode->startingWinSurfaceNode_ = nullptr;
166         });
167     };
168     node->surfaceNode_->SetBufferAvailableCallback(firstFrameCompleteCallback);
169     RSTransaction::FlushImplicitTransaction();
170 }
171 
ReleaseStartWinSurfaceNode(sptr<WindowNode> & node)172 void StartingWindow::ReleaseStartWinSurfaceNode(sptr<WindowNode>& node)
173 {
174     std::lock_guard<std::recursive_mutex> lock(mutex_);
175     if (!node->leashWinSurfaceNode_) {
176         WLOGFI("cannot release leashwindow since leash is null, id:%{public}u", node->GetWindowId());
177         return;
178     }
179     node->leashWinSurfaceNode_->RemoveChild(node->startingWinSurfaceNode_);
180     node->leashWinSurfaceNode_->RemoveChild(node->surfaceNode_);
181     node->leashWinSurfaceNode_ = nullptr;
182     node->startingWinSurfaceNode_ = nullptr;
183     WLOGFI("Release startwindow surfaceNode end id: %{public}u, [leashWinSurface]: use_count: %{public}ld, \
184         [startWinSurface]: use_count: %{public}ld ", node->GetWindowId(),
185         node->leashWinSurfaceNode_.use_count(), node->startingWinSurfaceNode_.use_count());
186     RSTransaction::FlushImplicitTransaction();
187 }
188 
AddNodeOnRSTree(sptr<WindowNode> & node,const AnimationConfig & animationConfig,bool isMultiDisplay)189 void StartingWindow::AddNodeOnRSTree(sptr<WindowNode>& node, const AnimationConfig& animationConfig,
190     bool isMultiDisplay)
191 {
192     auto updateRSTreeFunc = [&]() {
193         auto& dms = DisplayManagerServiceInner::GetInstance();
194         DisplayId displayId = node->GetDisplayId();
195         if (!node->surfaceNode_) { // cold start
196             if (!WindowHelper::IsMainWindow(node->GetWindowType())) {
197                 WLOGFE("window id:%{public}d type: %{public}u is not Main Window!",
198                     node->GetWindowId(), static_cast<uint32_t>(node->GetWindowType()));
199             }
200             dms.UpdateRSTree(displayId, displayId, node->leashWinSurfaceNode_, true, isMultiDisplay);
201             node->leashWinSurfaceNode_->AddChild(node->startingWinSurfaceNode_, -1);
202         } else { // hot start
203             const auto& displayIdVec = node->GetShowingDisplays();
204             for (auto& shownDisplayId : displayIdVec) {
205                 if (node->leashWinSurfaceNode_) { // to app
206                     dms.UpdateRSTree(shownDisplayId, shownDisplayId, node->leashWinSurfaceNode_, true, isMultiDisplay);
207                 } else { // to launcher
208                     dms.UpdateRSTree(shownDisplayId, shownDisplayId, node->surfaceNode_, true, isMultiDisplay);
209                 }
210                 for (auto& child : node->children_) {
211                     if (child->currentVisibility_) {
212                         dms.UpdateRSTree(shownDisplayId, shownDisplayId, child->surfaceNode_, true, isMultiDisplay);
213                     }
214                 }
215             }
216         }
217     };
218     wptr<WindowNode> weakNode = node;
219     auto finishCallBack = [weakNode]() {
220         auto weak = weakNode.promote();
221         if (weak == nullptr) {
222             return;
223         }
224         auto winRect = weak->GetWindowRect();
225         WLOGFI("before setBounds windowRect: %{public}d, %{public}d, %{public}d, %{public}d",
226             winRect.posX_, winRect.posY_, winRect.width_, winRect.height_);
227         if (weak->leashWinSurfaceNode_) {
228             weak->leashWinSurfaceNode_->SetBounds(winRect.posX_, winRect.posY_, winRect.width_, winRect.height_);
229             weak->leashWinSurfaceNode_->SetAnimationFinished();
230         }
231         RSTransaction::FlushImplicitTransaction();
232     };
233     if (!RemoteAnimation::CheckAnimationController()) {
234         RSNode::Animate(animationConfig.windowAnimationConfig_.animationTiming_.timingProtocol_,
235             animationConfig.windowAnimationConfig_.animationTiming_.timingCurve_, updateRSTreeFunc, finishCallBack);
236     } else {
237         // add or remove window without animation
238         updateRSTreeFunc();
239     }
240 }
241 
SetDefaultWindowMode(WindowMode defaultMode)242 void StartingWindow::SetDefaultWindowMode(WindowMode defaultMode)
243 {
244     defaultMode_ = defaultMode;
245 }
246 } // Rosen
247 } // OHOS
248