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