1 /*
2 * Copyright (c) 2023 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 "window_scene_session_impl.h"
17
18 #include <ability_manager_client.h>
19 #include <parameters.h>
20 #include <transaction/rs_transaction.h>
21
22 #include "anr_handler.h"
23 #include "color_parser.h"
24 #include "singleton_container.h"
25 #include "display_manager.h"
26 #include "perform_reporter.h"
27 #include "session_permission.h"
28 #include "session/container/include/window_event_channel.h"
29 #include "session_manager/include/session_manager.h"
30 #include "singleton_container.h"
31 #include "window_adapter.h"
32 #include "window_helper.h"
33 #include "window_manager_hilog.h"
34 #include "window_prepare_terminate.h"
35 #include "wm_common.h"
36 #include "wm_math.h"
37 #include "session_manager_agent_controller.h"
38 #include <transaction/rs_interfaces.h>
39 #include "surface_capture_future.h"
40
41 #include "window_session_impl.h"
42
43 namespace OHOS {
44 namespace Rosen {
45 union WSColorParam {
46 #if defined(BIG_ENDIANNESS) && BIG_ENDIANNESS
47 struct {
48 uint8_t alpha;
49 uint8_t red;
50 uint8_t green;
51 uint8_t blue;
52 } argb;
53 #else
54 struct {
55 uint8_t blue;
56 uint8_t green;
57 uint8_t red;
58 uint8_t alpha;
59 } argb;
60 #endif
61 uint32_t value;
62 };
63 namespace {
64 constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WINDOW, "WindowSceneSessionImpl"};
65 const std::string PARAM_DUMP_HELP = "-h";
66 }
67 uint32_t WindowSceneSessionImpl::maxFloatingWindowSize_ = 1920;
68
WindowSceneSessionImpl(const sptr<WindowOption> & option)69 WindowSceneSessionImpl::WindowSceneSessionImpl(const sptr<WindowOption>& option) : WindowSessionImpl(option)
70 {
71 }
72
~WindowSceneSessionImpl()73 WindowSceneSessionImpl::~WindowSceneSessionImpl()
74 {
75 }
76
IsValidSystemWindowType(const WindowType & type)77 bool WindowSceneSessionImpl::IsValidSystemWindowType(const WindowType& type)
78 {
79 if (!(type == WindowType::WINDOW_TYPE_SYSTEM_ALARM_WINDOW || type == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT ||
80 type == WindowType::WINDOW_TYPE_FLOAT_CAMERA || type == WindowType::WINDOW_TYPE_DIALOG ||
81 type == WindowType::WINDOW_TYPE_FLOAT || type == WindowType::WINDOW_TYPE_SCREENSHOT ||
82 type == WindowType::WINDOW_TYPE_VOICE_INTERACTION || type == WindowType::WINDOW_TYPE_POINTER ||
83 type == WindowType::WINDOW_TYPE_TOAST || type == WindowType::WINDOW_TYPE_DRAGGING_EFFECT ||
84 type == WindowType::WINDOW_TYPE_SEARCHING_BAR || type == WindowType::WINDOW_TYPE_PANEL ||
85 type == WindowType::WINDOW_TYPE_VOLUME_OVERLAY || type == WindowType::WINDOW_TYPE_INPUT_METHOD_STATUS_BAR)) {
86 WLOGFW("Invalid type: %{public}u", GetType());
87 return false;
88 }
89 return true;
90 }
91
FindParentSessionByParentId(uint32_t parentId)92 sptr<WindowSessionImpl> WindowSceneSessionImpl::FindParentSessionByParentId(uint32_t parentId)
93 {
94 for (const auto& item : windowSessionMap_) {
95 if (item.second.second && item.second.second->GetProperty() &&
96 item.second.second->GetWindowId() == parentId &&
97 WindowHelper::IsMainWindow(item.second.second->GetType())) {
98 WLOGFD("Find parent, [parentName: %{public}s, parentId:%{public}u, selfPersistentId: %{public}d]",
99 item.second.second->GetProperty()->GetWindowName().c_str(), parentId, GetProperty()->GetPersistentId());
100 return item.second.second;
101 }
102 }
103 WLOGFD("Can not find parent window");
104 return nullptr;
105 }
106
FindMainWindowWithContext()107 sptr<WindowSessionImpl> WindowSceneSessionImpl::FindMainWindowWithContext()
108 {
109 for (const auto& winPair : windowSessionMap_) {
110 auto win = winPair.second.second;
111 if (win && win->GetType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW &&
112 context_.get() == win->GetContext().get()) {
113 return win;
114 }
115 }
116 WLOGFI("Can not find main window, not app type");
117 return nullptr;
118 }
119
CreateAndConnectSpecificSession()120 WMError WindowSceneSessionImpl::CreateAndConnectSpecificSession()
121 {
122 sptr<ISessionStage> iSessionStage(this);
123 sptr<WindowEventChannel> channel = new (std::nothrow) WindowEventChannel(iSessionStage);
124 if (channel == nullptr || property_ == nullptr) {
125 return WMError::WM_ERROR_NULLPTR;
126 }
127 sptr<IWindowEventChannel> eventChannel(channel);
128 auto persistentId = INVALID_SESSION_ID;
129 sptr<Rosen::ISession> session;
130 sptr<IRemoteObject> token = context_ ? context_->GetToken() : nullptr;
131 if (token) {
132 property_->SetTokenState(true);
133 }
134 const WindowType type = GetType();
135 if (WindowHelper::IsSubWindow(type)) { // sub window
136 auto parentSession = FindParentSessionByParentId(property_->GetParentId());
137 if (parentSession == nullptr || parentSession->GetHostSession() == nullptr) {
138 return WMError::WM_ERROR_NULLPTR;
139 }
140 // set parent persistentId
141 property_->SetParentPersistentId(parentSession->GetPersistentId());
142 windowSystemConfig_ = parentSession->GetSystemSessionConfig();
143 // creat sub session by parent session
144 parentSession->GetHostSession()->CreateAndConnectSpecificSession(iSessionStage, eventChannel, surfaceNode_,
145 property_, persistentId, session, token);
146 // update subWindowSessionMap_
147 subWindowSessionMap_[parentSession->GetPersistentId()].push_back(this);
148 } else { // system window
149 if (WindowHelper::IsAppFloatingWindow(type)) {
150 property_->SetParentPersistentId(GetFloatingWindowParentId());
151 WLOGFI("property set parentPersistentId: %{public}d", property_->GetParentPersistentId());
152 auto mainWindow = FindMainWindowWithContext();
153 property_->SetFloatingWindowAppType(mainWindow != nullptr ? true : false);
154 } else if (type == WindowType::WINDOW_TYPE_DIALOG) {
155 auto mainWindow = FindMainWindowWithContext();
156 if (mainWindow != nullptr) {
157 property_->SetParentPersistentId(mainWindow->GetPersistentId());
158 WLOGFD("Bind dialog to main window");
159 }
160 }
161 PreProcessCreate();
162 SessionManager::GetInstance().CreateAndConnectSpecificSession(iSessionStage, eventChannel, surfaceNode_,
163 property_, persistentId, session, token);
164 }
165 property_->SetPersistentId(persistentId);
166 if (session == nullptr) {
167 return WMError::WM_ERROR_NULLPTR;
168 }
169 hostSession_ = session;
170 WLOGFI("CreateAndConnectSpecificSession [name:%{public}s, id:%{public}d, type: %{public}u]",
171 property_->GetWindowName().c_str(), property_->GetPersistentId(), GetType());
172 return WMError::WM_OK;
173 }
174
UpdateWindowState()175 void WindowSceneSessionImpl::UpdateWindowState()
176 {
177 windowSessionMap_.insert(std::make_pair(property_->GetWindowName(),
178 std::pair<uint64_t, sptr<WindowSessionImpl>>(property_->GetPersistentId(), this)));
179 state_ = WindowState::STATE_CREATED;
180 requestState_ = WindowState::STATE_CREATED;
181 if (WindowHelper::IsMainWindow(GetType())) {
182 maxFloatingWindowSize_ = windowSystemConfig_.maxFloatingWindowSize_;
183 SetWindowMode(windowSystemConfig_.defaultWindowMode_);
184 GetConfigurationFromAbilityInfo();
185 } else {
186 UpdateWindowSizeLimits();
187 }
188 }
189
Create(const std::shared_ptr<AbilityRuntime::Context> & context,const sptr<Rosen::ISession> & iSession)190 WMError WindowSceneSessionImpl::Create(const std::shared_ptr<AbilityRuntime::Context>& context,
191 const sptr<Rosen::ISession>& iSession)
192 {
193 // allow iSession is nullptr when create window by innerkits
194 if (!context) {
195 WLOGFW("context is nullptr!");
196 }
197 WMError ret = WindowSessionCreateCheck();
198 if (ret != WMError::WM_OK) {
199 return ret;
200 }
201 hostSession_ = iSession;
202 context_ = context;
203 AdjustWindowAnimationFlag();
204 if (hostSession_) { // main window
205 ret = Connect();
206 } else { // system or sub window
207 if (WindowHelper::IsSystemWindow(GetType())) {
208 // Not valid system window type for session should return WMError::WM_OK;
209 if (!IsValidSystemWindowType(GetType())) {
210 return WMError::WM_OK;
211 }
212 } else if (!WindowHelper::IsSubWindow(GetType())) {
213 return WMError::WM_ERROR_INVALID_TYPE;
214 }
215 if (GetType() == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT) {
216 WLOGFI("Create input method and sleep 3s");
217 sleep(3); // sleep 3s
218 }
219 ret = CreateAndConnectSpecificSession();
220 }
221 if (ret == WMError::WM_OK) {
222 UpdateWindowState();
223 }
224 WLOGFD("Window Create [name:%{public}s, id:%{public}d], state:%{pubic}u, windowmode:%{public}u",
225 property_->GetWindowName().c_str(), property_->GetPersistentId(), state_, GetMode());
226 return ret;
227 }
228
GetConfigurationFromAbilityInfo()229 void WindowSceneSessionImpl::GetConfigurationFromAbilityInfo()
230 {
231 auto abilityContext = AbilityRuntime::Context::ConvertTo<AbilityRuntime::AbilityContext>(context_);
232 if (abilityContext != nullptr) {
233 auto abilityInfo = abilityContext->GetAbilityInfo();
234 if (abilityInfo != nullptr) {
235 property_->SetWindowLimits({
236 abilityInfo->maxWindowWidth, abilityInfo->maxWindowHeight,
237 abilityInfo->minWindowWidth, abilityInfo->minWindowHeight,
238 static_cast<float>(abilityInfo->maxWindowRatio), static_cast<float>(abilityInfo->minWindowRatio)
239 });
240 UpdateWindowSizeLimits();
241 UpdateProperty(WSPropertyChangeAction::ACTION_UPDATE_WINDOW_LIMITS);
242 // get support modes configuration
243 uint32_t modeSupportInfo = WindowHelper::ConvertSupportModesToSupportInfo(abilityInfo->windowModes);
244 if (modeSupportInfo == 0) {
245 WLOGFI("mode config param is 0, all modes is supported");
246 modeSupportInfo = WindowModeSupport::WINDOW_MODE_SUPPORT_ALL;
247 }
248 WLOGFI("winId: %{public}u, modeSupportInfo: %{public}u", GetWindowId(), modeSupportInfo);
249 property_->SetModeSupportInfo(modeSupportInfo);
250 auto isPhone = system::GetParameter("const.product.devicetype", "unknown") == "phone";
251 if (modeSupportInfo == WindowModeSupport::WINDOW_MODE_SUPPORT_FULLSCREEN && !isPhone) {
252 SetFullScreen(true);
253 }
254 // get orientation configuration
255 OHOS::AppExecFwk::DisplayOrientation displayOrientation =
256 static_cast<OHOS::AppExecFwk::DisplayOrientation>(
257 static_cast<uint32_t>(abilityInfo->orientation));
258 if (ABILITY_TO_SESSION_ORIENTATION_MAP.count(displayOrientation) == 0) {
259 WLOGFE("id:%{public}u Do not support this Orientation type", GetWindowId());
260 return;
261 }
262 Orientation orientation = ABILITY_TO_SESSION_ORIENTATION_MAP.at(displayOrientation);
263 if (orientation < Orientation::BEGIN || orientation > Orientation::END) {
264 WLOGFE("Set orientation from ability failed");
265 return;
266 }
267 property_->SetRequestedOrientation(orientation);
268 }
269 }
270 }
271
UpdateConfigVal(uint32_t minVal,uint32_t maxVal,uint32_t configVal,uint32_t defaultVal,float vpr)272 uint32_t WindowSceneSessionImpl::UpdateConfigVal(uint32_t minVal, uint32_t maxVal, uint32_t configVal,
273 uint32_t defaultVal, float vpr)
274 {
275 bool validConfig = minVal < (configVal * vpr) && (configVal * vpr) < maxVal;
276 return validConfig ? static_cast<uint32_t>(configVal * vpr) : static_cast<uint32_t>(defaultVal * vpr);
277 }
278
GetSystemSizeLimits(uint32_t displayWidth,uint32_t displayHeight,float vpr)279 WindowLimits WindowSceneSessionImpl::GetSystemSizeLimits(uint32_t displayWidth,
280 uint32_t displayHeight, float vpr)
281 {
282 WindowLimits systemLimits;
283 systemLimits.maxWidth_ = static_cast<uint32_t>(maxFloatingWindowSize_ * vpr);
284 systemLimits.maxHeight_ = static_cast<uint32_t>(maxFloatingWindowSize_ * vpr);
285
286 if (WindowHelper::IsMainWindow(GetType())) {
287 systemLimits.minWidth_ = UpdateConfigVal(0, displayWidth, windowSystemConfig_.miniWidthOfMainWindow_,
288 MIN_FLOATING_WIDTH, vpr);
289 systemLimits.minHeight_ = UpdateConfigVal(0, displayHeight, windowSystemConfig_.miniHeightOfMainWindow_,
290 MIN_FLOATING_HEIGHT, vpr);
291 } else if (WindowHelper::IsSubWindow(GetType())) {
292 systemLimits.minWidth_ = UpdateConfigVal(0, displayWidth, windowSystemConfig_.miniWidthOfSubWindow_,
293 MIN_FLOATING_WIDTH, vpr);
294 systemLimits.minHeight_ = UpdateConfigVal(0, displayHeight, windowSystemConfig_.miniHeightOfSubWindow_,
295 MIN_FLOATING_HEIGHT, vpr);
296 } else {
297 systemLimits.minWidth_ = static_cast<uint32_t>(MIN_FLOATING_WIDTH * vpr);
298 systemLimits.minHeight_ = static_cast<uint32_t>(MIN_FLOATING_HEIGHT * vpr);
299 }
300 WLOGFI("[System SizeLimits] [maxWidth: %{public}u, minWidth: %{public}u, maxHeight: %{public}u, "
301 "minHeight: %{public}u]", systemLimits.maxWidth_, systemLimits.minWidth_,
302 systemLimits.maxHeight_, systemLimits.minHeight_);
303 return systemLimits;
304 }
305
UpdateWindowSizeLimits()306 void WindowSceneSessionImpl::UpdateWindowSizeLimits()
307 {
308 auto display = SingletonContainer::Get<DisplayManager>().GetDisplayById(property_->GetDisplayId());
309 if (display == nullptr || display->GetDisplayInfo() == nullptr) {
310 return;
311 }
312 uint32_t displayWidth = static_cast<uint32_t>(display->GetWidth());
313 uint32_t displayHeight = static_cast<uint32_t>(display->GetHeight());
314 if (displayWidth == 0 || displayHeight == 0) {
315 return;
316 }
317
318 float virtualPixelRatio = display->GetDisplayInfo()->GetVirtualPixelRatio();
319 const auto& systemLimits = GetSystemSizeLimits(displayWidth, displayHeight, virtualPixelRatio);
320 const auto& customizedLimits = property_->GetWindowLimits();
321
322 WindowLimits newLimits = systemLimits;
323
324 // configured limits of floating window
325 uint32_t configuredMaxWidth = static_cast<uint32_t>(customizedLimits.maxWidth_ * virtualPixelRatio);
326 uint32_t configuredMaxHeight = static_cast<uint32_t>(customizedLimits.maxHeight_ * virtualPixelRatio);
327 uint32_t configuredMinWidth = static_cast<uint32_t>(customizedLimits.minWidth_ * virtualPixelRatio);
328 uint32_t configuredMinHeight = static_cast<uint32_t>(customizedLimits.minHeight_ * virtualPixelRatio);
329
330 // calculate new limit size
331 if (systemLimits.minWidth_ <= configuredMaxWidth && configuredMaxWidth <= systemLimits.maxWidth_) {
332 newLimits.maxWidth_ = configuredMaxWidth;
333 }
334 if (systemLimits.minHeight_ <= configuredMaxHeight && configuredMaxHeight <= systemLimits.maxHeight_) {
335 newLimits.maxHeight_ = configuredMaxHeight;
336 }
337 if (systemLimits.minWidth_ <= configuredMinWidth && configuredMinWidth <= newLimits.maxWidth_) {
338 newLimits.minWidth_ = configuredMinWidth;
339 }
340 if (systemLimits.minHeight_ <= configuredMinHeight && configuredMinHeight <= newLimits.maxHeight_) {
341 newLimits.minHeight_ = configuredMinHeight;
342 }
343
344 // calculate new limit ratio
345 newLimits.maxRatio_ = static_cast<float>(newLimits.maxWidth_) / static_cast<float>(newLimits.minHeight_);
346 newLimits.minRatio_ = static_cast<float>(newLimits.minWidth_) / static_cast<float>(newLimits.maxHeight_);
347 if (!MathHelper::GreatNotEqual(newLimits.minRatio_, customizedLimits.maxRatio_) &&
348 !MathHelper::GreatNotEqual(customizedLimits.maxRatio_, newLimits.maxRatio_)) {
349 newLimits.maxRatio_ = customizedLimits.maxRatio_;
350 }
351 if (!MathHelper::GreatNotEqual(newLimits.minRatio_, customizedLimits.minRatio_) &&
352 !MathHelper::GreatNotEqual(customizedLimits.minRatio_, newLimits.maxRatio_)) {
353 newLimits.minRatio_ = customizedLimits.minRatio_;
354 }
355
356 // recalculate limit size by new ratio
357 uint32_t newMaxWidth = static_cast<uint32_t>(static_cast<float>(newLimits.maxHeight_) * newLimits.maxRatio_);
358 newLimits.maxWidth_ = std::min(newMaxWidth, newLimits.maxWidth_);
359 uint32_t newMinWidth = static_cast<uint32_t>(static_cast<float>(newLimits.minHeight_) * newLimits.minRatio_);
360 newLimits.minWidth_ = std::max(newMinWidth, newLimits.minWidth_);
361 uint32_t newMaxHeight = static_cast<uint32_t>(static_cast<float>(newLimits.maxWidth_) / newLimits.minRatio_);
362 newLimits.maxHeight_ = std::min(newMaxHeight, newLimits.maxHeight_);
363 uint32_t newMinHeight = static_cast<uint32_t>(static_cast<float>(newLimits.minWidth_) / newLimits.maxRatio_);
364 newLimits.minHeight_ = std::max(newMinHeight, newLimits.minHeight_);
365
366 property_->SetWindowLimits(newLimits);
367 }
368
UpdateSubWindowStateAndNotify(int32_t parentPersistentId,const WindowState & newState)369 void WindowSceneSessionImpl::UpdateSubWindowStateAndNotify(int32_t parentPersistentId, const WindowState& newState)
370 {
371 auto iter = subWindowSessionMap_.find(parentPersistentId);
372 if (iter == subWindowSessionMap_.end()) {
373 WLOGFD("main window: %{public}d has no child node", parentPersistentId);
374 return;
375 }
376 const auto& subWindows = iter->second;
377 if (subWindows.empty()) {
378 WLOGFD("main window: %{public}d, its subWindowMap is empty", parentPersistentId);
379 return;
380 }
381
382 // when main window hide and subwindow whose state is shown should hide and notify user
383 if (newState == WindowState::STATE_HIDDEN) {
384 for (auto subwindow : subWindows) {
385 if (subwindow != nullptr && subwindow->GetWindowState() == WindowState::STATE_SHOWN) {
386 subwindow->NotifyAfterBackground();
387 subwindow->state_ = WindowState::STATE_HIDDEN;
388 }
389 }
390 // when main window show and subwindow whose state is shown should show and notify user
391 } else if (newState == WindowState::STATE_SHOWN) {
392 for (auto subwindow : subWindows) {
393 if (subwindow != nullptr && subwindow->GetWindowState() == WindowState::STATE_HIDDEN &&
394 subwindow->GetRequestWindowState() == WindowState::STATE_SHOWN) {
395 subwindow->NotifyAfterForeground();
396 subwindow->state_ = WindowState::STATE_SHOWN;
397 }
398 }
399 }
400 }
401
Show(uint32_t reason,bool withAnimation)402 WMError WindowSceneSessionImpl::Show(uint32_t reason, bool withAnimation)
403 {
404 WLOGFI("Window Show [name:%{public}s, id:%{public}d, type:%{public}u], reason:%{public}u state:%{pubic}u",
405 property_->GetWindowName().c_str(), property_->GetPersistentId(), GetType(), reason, state_);
406 if (IsWindowSessionInvalid()) {
407 WLOGFE("session is invalid");
408 return WMError::WM_ERROR_INVALID_WINDOW;
409 }
410 UpdateDecorEnable(true);
411 if (state_ == WindowState::STATE_SHOWN) {
412 WLOGFD("window session is alreay shown [name:%{public}s, id:%{public}d, type: %{public}u]",
413 property_->GetWindowName().c_str(), property_->GetPersistentId(), GetType());
414 return WMError::WM_OK;
415 }
416 if (hostSession_ == nullptr) {
417 return WMError::WM_ERROR_NULLPTR;
418 }
419 WMError ret = UpdateAnimationFlagProperty(withAnimation);
420 if (ret != WMError::WM_OK) {
421 WLOGFE("UpdateProperty failed with errCode:%{public}d", static_cast<int32_t>(ret));
422 return ret;
423 }
424 UpdateTitleButtonVisibility();
425 ret = static_cast<WMError>(hostSession_->Foreground(property_));
426 if (ret == WMError::WM_OK) {
427 // update sub window state if this is main window
428 if (WindowHelper::IsMainWindow(GetType())) {
429 UpdateSubWindowStateAndNotify(GetPersistentId(), WindowState::STATE_SHOWN);
430 }
431 NotifyAfterForeground();
432 state_ = WindowState::STATE_SHOWN;
433 requestState_ = WindowState::STATE_SHOWN;
434 } else {
435 NotifyForegroundFailed(ret);
436 }
437 return ret;
438 }
439
Hide(uint32_t reason,bool withAnimation,bool isFromInnerkits)440 WMError WindowSceneSessionImpl::Hide(uint32_t reason, bool withAnimation, bool isFromInnerkits)
441 {
442 WLOGFI("id:%{public}d Hide, reason:%{public}u, state:%{public}u",
443 property_->GetPersistentId(), reason, state_);
444 if (IsWindowSessionInvalid()) {
445 WLOGFE("session is invalid");
446 return WMError::WM_ERROR_INVALID_WINDOW;
447 }
448 if (state_ == WindowState::STATE_HIDDEN || state_ == WindowState::STATE_CREATED) {
449 WLOGFD("window session is alreay hidden [name:%{public}s, id:%{public}d, type: %{public}u]",
450 property_->GetWindowName().c_str(), property_->GetPersistentId(), GetType());
451 return WMError::WM_OK;
452 }
453
454 WMError res = UpdateAnimationFlagProperty(withAnimation);
455 if (res != WMError::WM_OK) {
456 WLOGFE("UpdateProperty failed with errCode:%{public}d", static_cast<int32_t>(res));
457 return res;
458 }
459
460 uint32_t animationFlag = property_->GetAnimationFlag();
461 if (animationFlag == static_cast<uint32_t>(WindowAnimation::CUSTOM)) {
462 animationTransitionController_->AnimationForHidden();
463 RSTransaction::FlushImplicitTransaction();
464 }
465
466 // delete after replace WSError with WMError
467 if (!WindowHelper::IsMainWindow(GetType())) {
468 // main window no need to notify host, since host knows hide first
469 // need to SetActive(false) for host session before background
470 res = static_cast<WMError>(SetActive(false));
471 if (res != WMError::WM_OK) {
472 return res;
473 }
474 res = static_cast<WMError>(hostSession_->Background());
475 }
476
477 if (res == WMError::WM_OK) {
478 // update sub window state if this is main window
479 if (WindowHelper::IsMainWindow(GetType())) {
480 UpdateSubWindowStateAndNotify(GetPersistentId(), WindowState::STATE_HIDDEN);
481 }
482 NotifyAfterBackground();
483 state_ = WindowState::STATE_HIDDEN;
484 requestState_ = WindowState::STATE_HIDDEN;
485 }
486 return res;
487 }
488
PreProcessCreate()489 void WindowSceneSessionImpl::PreProcessCreate()
490 {
491 SetDefaultProperty();
492 }
493
SetDefaultProperty()494 void WindowSceneSessionImpl::SetDefaultProperty()
495 {
496 switch (property_->GetWindowType()) {
497 case WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT:{
498 property_->SetFocusable(false);
499 break;
500 }
501 case WindowType::WINDOW_TYPE_INPUT_METHOD_STATUS_BAR:{
502 property_->SetFocusable(false);
503 break;
504 }
505 default:
506 break;
507 }
508 }
509
SetActive(bool active)510 WSError WindowSceneSessionImpl::SetActive(bool active)
511 {
512 WLOGFD("active status: %{public}d", active);
513 if (!WindowHelper::IsMainWindow(GetType())) {
514 WSError ret = hostSession_->UpdateActiveStatus(active);
515 if (ret != WSError::WS_OK) {
516 return ret;
517 }
518 }
519 if (active) {
520 NotifyAfterActive();
521 } else {
522 NotifyAfterInactive();
523 }
524 return WSError::WS_OK;
525 }
526
DestroySubWindow()527 void WindowSceneSessionImpl::DestroySubWindow()
528 {
529 for (auto elem : subWindowSessionMap_) {
530 WLOGFE("Id: %{public}d, size: %{public}zu", elem.first, subWindowSessionMap_.size());
531 }
532
533 const int32_t& parentPersistentId = property_->GetParentPersistentId();
534 const int32_t& persistentId = GetPersistentId();
535
536 WLOGFD("Id: %{public}d, parentId: %{public}d", persistentId, parentPersistentId);
537
538 // remove from subWindowMap_ when destroy sub window
539 auto subIter = subWindowSessionMap_.find(parentPersistentId);
540 if (subIter != subWindowSessionMap_.end()) {
541 auto& subWindows = subIter->second;
542 for (auto iter = subWindows.begin(); iter != subWindows.end();) {
543 if ((*iter) == nullptr) {
544 iter++;
545 continue;
546 }
547 if ((*iter)->GetPersistentId() == persistentId) {
548 WLOGFD("Destroy sub window, persistentId: %{public}d", persistentId);
549 subWindows.erase(iter);
550 break;
551 } else {
552 WLOGFD("Exists other sub window, persistentId: %{public}d", persistentId);
553 iter++;
554 }
555 }
556 }
557
558 // remove from subWindowMap_ when destroy main window
559 auto mainIter = subWindowSessionMap_.find(persistentId);
560 if (mainIter != subWindowSessionMap_.end()) {
561 auto& subWindows = mainIter->second;
562 for (auto iter = subWindows.begin(); iter != subWindows.end(); iter = subWindows.begin()) {
563 if ((*iter) == nullptr) {
564 WLOGFD("Destroy sub window which is nullptr");
565 subWindows.erase(iter);
566 continue;
567 }
568 WLOGFD("Destroy sub window, persistentId: %{public}d", (*iter)->GetPersistentId());
569 (*iter)->Destroy(false);
570 }
571 mainIter->second.clear();
572 subWindowSessionMap_.erase(mainIter);
573 }
574 }
575
Destroy(bool needClearListener)576 WMError WindowSceneSessionImpl::Destroy(bool needClearListener)
577 {
578 WLOGFI("Id:%{public}d Destroy, state_:%{public}u", property_->GetPersistentId(), state_);
579 if (IsWindowSessionInvalid()) {
580 WLOGFE("session is invalid");
581 return WMError::WM_OK;
582 }
583 WSError ret = WSError::WS_OK;
584 if (!WindowHelper::IsMainWindow(GetType())) {
585 if (WindowHelper::IsSystemWindow(GetType())) {
586 // main window no need to notify host, since host knows hide first
587 SessionManager::GetInstance().DestroyAndDisconnectSpecificSession(property_->GetPersistentId());
588 } else if (WindowHelper::IsSubWindow(GetType())) {
589 auto parentSession = FindParentSessionByParentId(GetParentId());
590 if (parentSession == nullptr || parentSession->GetHostSession() == nullptr) {
591 return WMError::WM_ERROR_NULLPTR;
592 }
593 parentSession->GetHostSession()->DestroyAndDisconnectSpecificSession(property_->GetPersistentId());
594 }
595 }
596 // delete after replace WSError with WMError
597 WMError res = static_cast<WMError>(ret);
598 NotifyBeforeDestroy(GetWindowName());
599 if (needClearListener) {
600 ClearListenersById(GetPersistentId());
601 }
602 {
603 std::lock_guard<std::recursive_mutex> lock(mutex_);
604 state_ = WindowState::STATE_DESTROYED;
605 requestState_ = WindowState::STATE_DESTROYED;
606 }
607
608 DestroySubWindow();
609 windowSessionMap_.erase(property_->GetWindowName());
610 DelayedSingleton<ANRHandler>::GetInstance()->ClearDestroyedPersistentId(property_->GetPersistentId());
611 hostSession_ = nullptr;
612 return res;
613 }
614
MoveTo(int32_t x,int32_t y)615 WMError WindowSceneSessionImpl::MoveTo(int32_t x, int32_t y)
616 {
617 WLOGFD("Id:%{public}d MoveTo %{public}d %{public}d", property_->GetPersistentId(), x, y);
618 if (IsWindowSessionInvalid()) {
619 return WMError::WM_ERROR_INVALID_WINDOW;
620 }
621
622 const auto& windowRect = GetRect();
623 const auto& requestRect = GetRequestRect();
624 Rect newRect = { x, y, requestRect.width_, requestRect.height_ }; // must keep x/y
625 WLOGFD("Id:%{public}d, state: %{public}d, type: %{public}d, mode: %{public}d, requestRect: "
626 "[%{public}d, %{public}d, %{public}d, %{public}d], windowRect: [%{public}d, %{public}d, "
627 "%{public}d, %{public}d], newRect: [%{public}d, %{public}d, %{public}d, %{public}d]",
628 property_->GetPersistentId(), state_, GetType(), GetMode(), requestRect.posX_, requestRect.posY_,
629 requestRect.width_, requestRect.height_, windowRect.posX_, windowRect.posY_,
630 windowRect.width_, windowRect.height_, newRect.posX_, newRect.posY_,
631 newRect.width_, newRect.height_);
632
633 property_->SetRequestRect(newRect);
634 WSRect wsRect = { newRect.posX_, newRect.posY_, newRect.width_, newRect.height_ };
635 auto ret = hostSession_->UpdateSessionRect(wsRect, SizeChangeReason::MOVE);
636 return static_cast<WMError>(ret);
637 }
638
LimitCameraFloatWindowMininumSize(uint32_t & width,uint32_t & height)639 void WindowSceneSessionImpl::LimitCameraFloatWindowMininumSize(uint32_t& width, uint32_t& height)
640 {
641 // Float camera window has a special limit:
642 // if display sw <= 600dp, portrait: min width = display sw * 30%, landscape: min width = sw * 50%
643 // if display sw > 600dp, portrait: min width = display sw * 12%, landscape: min width = sw * 30%
644 if (property_->GetWindowType() != WindowType::WINDOW_TYPE_FLOAT_CAMERA) {
645 return;
646 }
647
648 auto display = SingletonContainer::Get<DisplayManager>().GetDisplayById(property_->GetDisplayId());
649 if (display == nullptr) {
650 WLOGFE("get display failed displayId:%{public}" PRIu64"", property_->GetDisplayId());
651 return;
652 }
653 uint32_t displayWidth = static_cast<uint32_t>(display->GetWidth());
654 uint32_t displayHeight = static_cast<uint32_t>(display->GetHeight());
655 if (displayWidth == 0 || displayHeight == 0) {
656 return;
657 }
658 float vpr = display->GetVirtualPixelRatio();
659 uint32_t smallWidth = displayHeight <= displayWidth ? displayHeight : displayWidth;
660 float hwRatio = static_cast<float>(displayHeight) / static_cast<float>(displayWidth);
661 uint32_t minWidth;
662 if (smallWidth <= static_cast<uint32_t>(600 * vpr)) { // sw <= 600dp
663 if (displayWidth <= displayHeight) {
664 minWidth = static_cast<uint32_t>(smallWidth * 0.3); // ratio : 0.3
665 } else {
666 minWidth = static_cast<uint32_t>(smallWidth * 0.5); // ratio : 0.5
667 }
668 } else {
669 if (displayWidth <= displayHeight) {
670 minWidth = static_cast<uint32_t>(smallWidth * 0.12); // ratio : 0.12
671 } else {
672 minWidth = static_cast<uint32_t>(smallWidth * 0.3); // ratio : 0.3
673 }
674 }
675 width = (width < minWidth) ? minWidth : width;
676 height = static_cast<uint32_t>(width * hwRatio);
677 }
678
UpdateFloatingWindowSizeBySizeLimits(uint32_t & width,uint32_t & height) const679 void WindowSceneSessionImpl::UpdateFloatingWindowSizeBySizeLimits(uint32_t& width, uint32_t& height) const
680 {
681 if (property_->GetWindowType() == WindowType::WINDOW_TYPE_FLOAT_CAMERA) {
682 return;
683 }
684 // get new limit config with the settings of system and app
685 const auto& sizeLimits = property_->GetWindowLimits();
686 // limit minimum size of floating (not system type) window
687 if (!WindowHelper::IsSystemWindow(property_->GetWindowType())) {
688 width = std::max(sizeLimits.minWidth_, width);
689 height = std::max(sizeLimits.minHeight_, height);
690 }
691 width = std::min(sizeLimits.maxWidth_, width);
692 height = std::min(sizeLimits.maxHeight_, height);
693 if (height == 0) {
694 return;
695 }
696 float curRatio = static_cast<float>(width) / static_cast<float>(height);
697 // there is no need to fix size by ratio if this is not main floating window
698 if (!WindowHelper::IsMainFloatingWindow(property_->GetWindowType(), GetMode()) ||
699 (!MathHelper::GreatNotEqual(sizeLimits.minRatio_, curRatio) &&
700 !MathHelper::GreatNotEqual(curRatio, sizeLimits.maxRatio_))) {
701 return;
702 }
703
704 float newRatio = curRatio < sizeLimits.minRatio_ ? sizeLimits.minRatio_ : sizeLimits.maxRatio_;
705 if (MathHelper::NearZero(newRatio)) {
706 return;
707 }
708 if (sizeLimits.maxWidth_ == sizeLimits.minWidth_) {
709 height = static_cast<uint32_t>(static_cast<float>(width) / newRatio);
710 return;
711 }
712 if (sizeLimits.maxHeight_ == sizeLimits.minHeight_) {
713 width = static_cast<uint32_t>(static_cast<float>(height) * newRatio);
714 return;
715 }
716 WLOGFD("After limit by customize config: %{public}u %{public}u", width, height);
717 }
718
Resize(uint32_t width,uint32_t height)719 WMError WindowSceneSessionImpl::Resize(uint32_t width, uint32_t height)
720 {
721 WLOGFD("Id:%{public}d Resize %{public}u %{public}u", property_->GetPersistentId(), width, height);
722 if (IsWindowSessionInvalid()) {
723 return WMError::WM_ERROR_INVALID_WINDOW;
724 }
725 // Float camera window has special limits
726 LimitCameraFloatWindowMininumSize(width, height);
727
728 UpdateFloatingWindowSizeBySizeLimits(width, height);
729
730 const auto& windowRect = GetRect();
731 const auto& requestRect = GetRequestRect();
732 Rect newRect = { requestRect.posX_, requestRect.posY_, width, height }; // must keep w/h
733 WLOGFD("Id:%{public}d, state: %{public}d, type: %{public}d, mode: %{public}d, requestRect: "
734 "[%{public}d, %{public}d, %{public}d, %{public}d], windowRect: [%{public}d, %{public}d, "
735 "%{public}d, %{public}d], newRect: [%{public}d, %{public}d, %{public}d, %{public}d]",
736 property_->GetPersistentId(), state_, GetType(), GetMode(), requestRect.posX_, requestRect.posY_,
737 requestRect.width_, requestRect.height_, windowRect.posX_, windowRect.posY_,
738 windowRect.width_, windowRect.height_, newRect.posX_, newRect.posY_,
739 newRect.width_, newRect.height_);
740
741 property_->SetRequestRect(newRect);
742 WSRect wsRect = { newRect.posX_, newRect.posY_, newRect.width_, newRect.height_ };
743 auto ret = hostSession_->UpdateSessionRect(wsRect, SizeChangeReason::RESIZE);
744 return static_cast<WMError>(ret);
745 }
746
SetAspectRatio(float ratio)747 WMError WindowSceneSessionImpl::SetAspectRatio(float ratio)
748 {
749 if (property_ == nullptr || hostSession_ == nullptr) {
750 WLOGFE("SetAspectRatio failed because of nullptr");
751 return WMError::WM_ERROR_NULLPTR;
752 }
753 if (ratio == MathHelper::INF || ratio == MathHelper::NAG_INF || std::isnan(ratio) || MathHelper::NearZero(ratio)) {
754 WLOGFE("SetAspectRatio failed, because of wrong value: %{public}f", ratio);
755 return WMError::WM_ERROR_INVALID_PARAM;
756 }
757 if (hostSession_->SetAspectRatio(ratio) != WSError::WS_OK) {
758 return WMError::WM_ERROR_INVALID_PARAM;
759 }
760 return WMError::WM_OK;
761 }
762
ResetAspectRatio()763 WMError WindowSceneSessionImpl::ResetAspectRatio()
764 {
765 if (!hostSession_) {
766 WLOGFE("no host session found");
767 return WMError::WM_ERROR_NULLPTR;
768 }
769 return static_cast<WMError>(hostSession_->SetAspectRatio(0.0f));
770 }
771
RaiseToAppTop()772 WmErrorCode WindowSceneSessionImpl::RaiseToAppTop()
773 {
774 auto parentId = GetParentId();
775 if (parentId == INVALID_SESSION_ID) {
776 WLOGFE("Only the children of the main window can be raised!");
777 return WmErrorCode::WM_ERROR_INVALID_PARENT;
778 }
779
780 if (!WindowHelper::IsSubWindow(GetType())) {
781 WLOGFE("Must be app sub window window!");
782 return WmErrorCode::WM_ERROR_INVALID_CALLING;
783 }
784
785 if (state_ != WindowState::STATE_SHOWN) {
786 WLOGFE("The sub window must be shown!");
787 return WmErrorCode::WM_ERROR_STATE_ABNORMALLY;
788 }
789 if (!hostSession_) {
790 return WmErrorCode::WM_ERROR_STATE_ABNORMALLY;
791 }
792 const WSError& ret = hostSession_->RaiseToAppTop();
793 return static_cast<WmErrorCode>(ret);
794 }
795
RaiseAboveTarget(int32_t subWindowId)796 WmErrorCode WindowSceneSessionImpl::RaiseAboveTarget(int32_t subWindowId)
797 {
798 auto parentId = GetParentId();
799 auto currentWindowId = GetWindowId();
800
801 if (parentId == INVALID_SESSION_ID) {
802 WLOGFE("Only the children of the main window can be raised!");
803 return WmErrorCode::WM_ERROR_INVALID_PARENT;
804 }
805
806 auto subWindows = Window::GetSubWindow(parentId);
807 auto targetWindow = find_if(subWindows.begin(), subWindows.end(), [subWindowId](sptr<Window>& window) {
808 return static_cast<uint32_t>(subWindowId) == window->GetWindowId();
809 });
810 if (targetWindow == subWindows.end()) {
811 return WmErrorCode::WM_ERROR_INVALID_PARAM;
812 }
813
814 if (!WindowHelper::IsSubWindow(GetType())) {
815 WLOGFE("Must be app sub window window!");
816 return WmErrorCode::WM_ERROR_INVALID_CALLING;
817 }
818
819 if ((state_ != WindowState::STATE_SHOWN) ||
820 ((*targetWindow)->GetWindowState() != WindowState::STATE_SHOWN)) {
821 WLOGFE("The sub window must be shown!");
822 return WmErrorCode::WM_ERROR_STATE_ABNORMALLY;
823 }
824 if (!hostSession_) {
825 return WmErrorCode::WM_ERROR_STATE_ABNORMALLY;
826 }
827 if (currentWindowId == static_cast<uint32_t>(subWindowId)) {
828 return WmErrorCode::WM_OK;
829 }
830 WSError ret = hostSession_->RaiseAboveTarget(subWindowId);
831 return WM_JS_TO_ERROR_CODE_MAP.at(static_cast<WMError>(ret));
832 }
833
GetAvoidAreaByType(AvoidAreaType type,AvoidArea & avoidArea)834 WMError WindowSceneSessionImpl::GetAvoidAreaByType(AvoidAreaType type, AvoidArea& avoidArea)
835 {
836 uint32_t windowId = GetWindowId();
837 WLOGFI("GetAvoidAreaByType windowId:%{public}u type:%{public}u", windowId, static_cast<uint32_t>(type));
838 WindowMode mode = GetMode();
839 if (type != AvoidAreaType::TYPE_KEYBOARD &&
840 mode != WindowMode::WINDOW_MODE_FULLSCREEN &&
841 mode != WindowMode::WINDOW_MODE_SPLIT_PRIMARY &&
842 mode != WindowMode::WINDOW_MODE_SPLIT_SECONDARY) {
843 WLOGI("avoidAreaType:%{public}u, windowMode:%{public}u, return default avoid area.",
844 static_cast<uint32_t>(type), static_cast<uint32_t>(mode));
845 return WMError::WM_OK;
846 }
847 if (hostSession_ == nullptr) {
848 return WMError::WM_ERROR_NULLPTR;
849 }
850 avoidArea = hostSession_->GetAvoidAreaByType(type);
851 return WMError::WM_OK;
852 }
853
NotifyWindowNeedAvoid(bool status)854 WMError WindowSceneSessionImpl::NotifyWindowNeedAvoid(bool status)
855 {
856 WLOGFD("NotifyWindowNeedAvoid called windowId:%{public}u status:%{public}d",
857 GetWindowId(), static_cast<int32_t>(status));
858 if (IsWindowSessionInvalid()) {
859 WLOGFE("session is invalid");
860 return WMError::WM_ERROR_INVALID_WINDOW;
861 }
862 if (hostSession_ == nullptr) {
863 return WMError::WM_ERROR_NULLPTR;
864 }
865 hostSession_->OnNeedAvoid(status);
866 return WMError::WM_OK;
867 }
868
SetLayoutFullScreenByApiVersion(bool status)869 WMError WindowSceneSessionImpl::SetLayoutFullScreenByApiVersion(bool status)
870 {
871 if (IsWindowSessionInvalid()) {
872 WLOGFE("session is invalid");
873 return WMError::WM_ERROR_INVALID_WINDOW;
874 }
875
876 uint32_t version = 0;
877 if ((context_ != nullptr) && (context_->GetApplicationInfo() != nullptr)) {
878 version = context_->GetApplicationInfo()->apiCompatibleVersion;
879 }
880 isIgnoreSafeArea_ = status;
881 // 10 ArkUI new framework support after API10
882 if (version >= 10) {
883 if (uiContent_ != nullptr) {
884 uiContent_->SetIgnoreViewSafeArea(status);
885 } else {
886 isIgnoreSafeAreaNeedNotify_ = true;
887 }
888 } else {
889 WMError ret = WMError::WM_OK;
890 if (status) {
891 RemoveWindowFlag(WindowFlag::WINDOW_FLAG_NEED_AVOID);
892 if (ret != WMError::WM_OK) {
893 WLOGFE("RemoveWindowFlag errCode:%{public}d winId:%{public}u",
894 static_cast<int32_t>(ret), GetWindowId());
895 return ret;
896 }
897 } else {
898 AddWindowFlag(WindowFlag::WINDOW_FLAG_NEED_AVOID);
899 if (ret != WMError::WM_OK) {
900 WLOGFE("RemoveWindowFlag errCode:%{public}d winId:%{public}u",
901 static_cast<int32_t>(ret), GetWindowId());
902 return ret;
903 }
904 }
905 ret = NotifyWindowNeedAvoid(!status);
906 if (ret != WMError::WM_OK) {
907 WLOGFE("NotifyWindowNeedAvoid errCode:%{public}d winId:%{public}u",
908 static_cast<int32_t>(ret), GetWindowId());
909 return ret;
910 }
911 }
912 return WMError::WM_OK;
913 }
914
SetLayoutFullScreen(bool status)915 WMError WindowSceneSessionImpl::SetLayoutFullScreen(bool status)
916 {
917 WLOGFI("winId:%{public}u status:%{public}d", GetWindowId(), static_cast<int32_t>(status));
918 if (hostSession_ == nullptr) {
919 return WMError::WM_ERROR_NULLPTR;
920 }
921 if (!WindowHelper::IsWindowModeSupported(property_->GetModeSupportInfo(), WindowMode::WINDOW_MODE_FULLSCREEN)) {
922 return WMError::WM_ERROR_INVALID_WINDOW;
923 }
924 hostSession_->OnSessionEvent(SessionEvent::EVENT_MAXIMIZE);
925 SetWindowMode(WindowMode::WINDOW_MODE_FULLSCREEN);
926 WMError ret = SetLayoutFullScreenByApiVersion(status);
927 if (ret != WMError::WM_OK) {
928 WLOGFE("SetLayoutFullScreenByApiVersion errCode:%{public}d winId:%{public}u",
929 static_cast<int32_t>(ret), GetWindowId());
930 }
931 return ret;
932 }
933
IsLayoutFullScreen() const934 bool WindowSceneSessionImpl::IsLayoutFullScreen() const
935 {
936 WindowMode mode = GetMode();
937 return (mode == WindowMode::WINDOW_MODE_FULLSCREEN && isIgnoreSafeArea_);
938 }
939
GetSystemBarPropertyByType(WindowType type) const940 SystemBarProperty WindowSceneSessionImpl::GetSystemBarPropertyByType(WindowType type) const
941 {
942 WLOGFI("GetSystemBarPropertyByType windowId:%{public}u type:%{public}u",
943 GetWindowId(), static_cast<uint32_t>(type));
944 if (property_ == nullptr) {
945 return SystemBarProperty();
946 }
947 auto curProperties = property_->GetSystemBarProperty();
948 return curProperties[type];
949 }
950
NotifyWindowSessionProperty()951 WMError WindowSceneSessionImpl::NotifyWindowSessionProperty()
952 {
953 WLOGFD("NotifyWindowSessionProperty called windowId:%{public}u", GetWindowId());
954 if (IsWindowSessionInvalid()) {
955 WLOGFE("session is invalid");
956 return WMError::WM_ERROR_INVALID_WINDOW;
957 }
958 if ((state_ == WindowState::STATE_CREATED &&
959 property_->GetModeSupportInfo() != WindowModeSupport::WINDOW_MODE_SUPPORT_FULLSCREEN) ||
960 state_ == WindowState::STATE_HIDDEN) {
961 return WMError::WM_OK;
962 }
963 UpdateProperty(WSPropertyChangeAction::ACTION_UPDATE_OTHER_PROPS);
964 return WMError::WM_OK;
965 }
966
SetSystemBarProperty(WindowType type,const SystemBarProperty & property)967 WMError WindowSceneSessionImpl::SetSystemBarProperty(WindowType type, const SystemBarProperty& property)
968 {
969 WLOGFI("SetSystemBarProperty windowId:%{public}u type:%{public}u"
970 "enable:%{public}u bgColor:%{public}x Color:%{public}x",
971 GetWindowId(), static_cast<uint32_t>(type),
972 property.enable_, property.backgroundColor_, property.contentColor_);
973 if (!((state_ > WindowState::STATE_INITIAL) && (state_ < WindowState::STATE_BOTTOM))) {
974 return WMError::WM_ERROR_INVALID_WINDOW;
975 } else if (GetSystemBarPropertyByType(type) == property) {
976 return WMError::WM_OK;
977 }
978
979 if (property_ == nullptr) {
980 return WMError::WM_ERROR_NULLPTR;
981 }
982 isSystembarPropertiesSet_ = true;
983 property_->SetSystemBarProperty(type, property);
984 WMError ret = NotifyWindowSessionProperty();
985 if (ret != WMError::WM_OK) {
986 WLOGFE("NotifyWindowSessionProperty winId:%{public}u errCode:%{public}d",
987 GetWindowId(), static_cast<int32_t>(ret));
988 }
989 return ret;
990 }
991
SetFullScreen(bool status)992 WMError WindowSceneSessionImpl::SetFullScreen(bool status)
993 {
994 WLOGFI("winId:%{public}u status:%{public}d", GetWindowId(), static_cast<int32_t>(status));
995 if (hostSession_ == nullptr) {
996 return WMError::WM_ERROR_NULLPTR;
997 }
998 if (!WindowHelper::IsWindowModeSupported(property_->GetModeSupportInfo(), WindowMode::WINDOW_MODE_FULLSCREEN)) {
999 return WMError::WM_ERROR_INVALID_WINDOW;
1000 }
1001 hostSession_->OnSessionEvent(SessionEvent::EVENT_MAXIMIZE);
1002 SetWindowMode(WindowMode::WINDOW_MODE_FULLSCREEN);
1003 WMError ret = SetLayoutFullScreenByApiVersion(status);
1004 if (ret != WMError::WM_OK) {
1005 WLOGFE("SetLayoutFullScreenByApiVersion errCode:%{public}d winId:%{public}u",
1006 static_cast<int32_t>(ret), GetWindowId());
1007 }
1008 SystemBarProperty statusProperty = GetSystemBarPropertyByType(WindowType::WINDOW_TYPE_STATUS_BAR);
1009 UpdateDecorEnable(true);
1010 statusProperty.enable_ = !status;
1011 ret = SetSystemBarProperty(WindowType::WINDOW_TYPE_STATUS_BAR, statusProperty);
1012 if (ret != WMError::WM_OK) {
1013 WLOGFE("SetSystemBarProperty errCode:%{public}d winId:%{public}u",
1014 static_cast<int32_t>(ret), GetWindowId());
1015 }
1016 return ret;
1017 }
1018
IsFullScreen() const1019 bool WindowSceneSessionImpl::IsFullScreen() const
1020 {
1021 SystemBarProperty statusProperty = GetSystemBarPropertyByType(WindowType::WINDOW_TYPE_STATUS_BAR);
1022 return (IsLayoutFullScreen() && !statusProperty.enable_);
1023 }
1024
IsDecorEnable() const1025 bool WindowSceneSessionImpl::IsDecorEnable() const
1026 {
1027 bool enable = WindowHelper::IsMainWindow(GetType()) &&
1028 windowSystemConfig_.isSystemDecorEnable_ &&
1029 WindowHelper::IsWindowModeSupported(windowSystemConfig_.decorModeSupportInfo_, GetMode());
1030 WLOGFD("get decor enable %{public}d", enable);
1031 return enable;
1032 }
1033
Minimize()1034 WMError WindowSceneSessionImpl::Minimize()
1035 {
1036 WLOGFD("WindowSceneSessionImpl::Minimize called");
1037 if (IsWindowSessionInvalid()) {
1038 WLOGFE("session is invalid");
1039 return WMError::WM_ERROR_INVALID_WINDOW;
1040 }
1041 if (WindowHelper::IsMainWindow(GetType()) && hostSession_) {
1042 hostSession_->OnSessionEvent(SessionEvent::EVENT_MINIMIZE);
1043 }
1044 return WMError::WM_OK;
1045 }
1046
Maximize()1047 WMError WindowSceneSessionImpl::Maximize()
1048 {
1049 WLOGFD("WindowSceneSessionImpl::Maximize called");
1050 if (IsWindowSessionInvalid()) {
1051 WLOGFE("session is invalid");
1052 return WMError::WM_ERROR_INVALID_WINDOW;
1053 }
1054 if (WindowHelper::IsMainWindow(GetType())) {
1055 SetFullScreen(true);
1056 }
1057 return WMError::WM_OK;
1058 }
1059
MaximizeFloating()1060 WMError WindowSceneSessionImpl::MaximizeFloating()
1061 {
1062 WLOGFD("WindowSceneSessionImpl::MaximizeFloating called");
1063 if (IsWindowSessionInvalid()) {
1064 WLOGFE("session is invalid");
1065 return WMError::WM_ERROR_INVALID_WINDOW;
1066 }
1067 if (!WindowHelper::IsMainWindow(property_->GetWindowType())) {
1068 WLOGFW("SetGlobalMaximizeMode fail, not main window");
1069 return WMError::WM_ERROR_INVALID_WINDOW;
1070 }
1071 if (GetGlobalMaximizeMode() != MaximizeMode::MODE_AVOID_SYSTEM_BAR) {
1072 SetFullScreen(true);
1073 property_->SetMaximizeMode(MaximizeMode::MODE_FULL_FILL);
1074 } else {
1075 hostSession_->OnSessionEvent(SessionEvent::EVENT_MAXIMIZE_FLOATING);
1076 SetWindowMode(WindowMode::WINDOW_MODE_FLOATING);
1077 property_->SetMaximizeMode(MaximizeMode::MODE_AVOID_SYSTEM_BAR);
1078 UpdateDecorEnable(true);
1079 }
1080 UpdateProperty(WSPropertyChangeAction::ACTION_UPDATE_MAXIMIZE_STATE);
1081
1082 return WMError::WM_OK;
1083 }
1084
Recover()1085 WMError WindowSceneSessionImpl::Recover()
1086 {
1087 WLOGFD("WindowSceneSessionImpl::Recover called");
1088 if (IsWindowSessionInvalid()) {
1089 WLOGFE("session is invalid");
1090 return WMError::WM_ERROR_INVALID_WINDOW;
1091 }
1092 if (WindowHelper::IsMainWindow(GetType()) && hostSession_) {
1093 hostSession_->OnSessionEvent(SessionEvent::EVENT_RECOVER);
1094 SetWindowMode(WindowMode::WINDOW_MODE_FLOATING);
1095 property_->SetMaximizeMode(MaximizeMode::MODE_RECOVER);
1096 UpdateDecorEnable(true);
1097 UpdateProperty(WSPropertyChangeAction::ACTION_UPDATE_MAXIMIZE_STATE);
1098 }
1099 return WMError::WM_OK;
1100 }
1101
StartMove()1102 void WindowSceneSessionImpl::StartMove()
1103 {
1104 WLOGFD("WindowSceneSessionImpl::StartMove called");
1105 if (IsWindowSessionInvalid()) {
1106 WLOGFE("session is invalid");
1107 return;
1108 }
1109 if (WindowHelper::IsMainWindow(GetType()) && hostSession_) {
1110 hostSession_->OnSessionEvent(SessionEvent::EVENT_START_MOVE);
1111 }
1112 return;
1113 }
1114
Close()1115 WMError WindowSceneSessionImpl::Close()
1116 {
1117 WLOGFD("WindowSceneSessionImpl::Close called");
1118 if (IsWindowSessionInvalid()) {
1119 WLOGFE("session is invalid");
1120 return WMError::WM_ERROR_INVALID_WINDOW;
1121 }
1122 if (WindowHelper::IsMainWindow(GetType())) {
1123 auto abilityContext = AbilityRuntime::Context::ConvertTo<AbilityRuntime::AbilityContext>(context_);
1124 if (!abilityContext) {
1125 return Destroy(true);
1126 }
1127 WindowPrepareTerminateHandler* handler = new(std::nothrow) WindowPrepareTerminateHandler();
1128 if (handler == nullptr) {
1129 WLOGFW("new WindowPrepareTerminateHandler failed, do close window");
1130 hostSession_->OnSessionEvent(SessionEvent::EVENT_CLOSE);
1131 return WMError::WM_OK;
1132 }
1133 wptr<ISession> hostSessionWptr = hostSession_;
1134 PrepareTerminateFunc func = [hostSessionWptr]() {
1135 auto weakSession = hostSessionWptr.promote();
1136 if (weakSession == nullptr) {
1137 WLOGFW("this session wptr is nullptr");
1138 return;
1139 }
1140 weakSession->OnSessionEvent(SessionEvent::EVENT_CLOSE);
1141 };
1142 handler->SetPrepareTerminateFun(func);
1143 sptr<AAFwk::IPrepareTerminateCallback> callback = handler;
1144 if (AAFwk::AbilityManagerClient::GetInstance()->PrepareTerminateAbility(abilityContext->GetToken(),
1145 callback) != ERR_OK) {
1146 WLOGFW("RegisterWindowManagerServiceHandler failed, do close window");
1147 hostSession_->OnSessionEvent(SessionEvent::EVENT_CLOSE);
1148 return WMError::WM_OK;
1149 }
1150 }
1151
1152 return WMError::WM_OK;
1153 }
1154
DisableAppWindowDecor()1155 WMError WindowSceneSessionImpl::DisableAppWindowDecor()
1156 {
1157 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
1158 WLOGFE("disable app window decor permission denied!");
1159 return WMError::WM_ERROR_NOT_SYSTEM_APP;
1160 }
1161 if (!WindowHelper::IsMainWindow(GetType())) {
1162 WLOGFE("window decoration is invalid on sub window");
1163 return WMError::WM_ERROR_INVALID_OPERATION;
1164 }
1165 WLOGI("disable app window decoration.");
1166 windowSystemConfig_.isSystemDecorEnable_ = false;
1167 UpdateDecorEnable(true);
1168 return WMError::WM_OK;
1169 }
1170
HandleBackEvent()1171 WSError WindowSceneSessionImpl::HandleBackEvent()
1172 {
1173 bool isConsumed = false;
1174 if (uiContent_) {
1175 WLOGFD("Transfer back event to uiContent");
1176 isConsumed = uiContent_->ProcessBackPressed();
1177 } else {
1178 WLOGFE("There is no back event consumer");
1179 }
1180 if (isConsumed) {
1181 WLOGD("Back key event is consumed");
1182 return WSError::WS_OK;
1183 }
1184 WLOGFD("report Back");
1185 SingletonContainer::Get<WindowInfoReporter>().ReportBackButtonInfoImmediately();
1186 // notify back event to host session
1187 PerformBack();
1188 return WSError::WS_OK;
1189 }
1190
PerformBack()1191 void WindowSceneSessionImpl::PerformBack()
1192 {
1193 if (hostSession_) {
1194 WLOGFD("Transfer back event to host session");
1195 hostSession_->RequestSessionBack();
1196 }
1197 }
1198
SetGlobalMaximizeMode(MaximizeMode mode)1199 WMError WindowSceneSessionImpl::SetGlobalMaximizeMode(MaximizeMode mode)
1200 {
1201 WLOGFD("WindowSceneSessionImpl::SetGlobalMaximizeMode %{public}u", static_cast<uint32_t>(mode));
1202 if (IsWindowSessionInvalid()) {
1203 WLOGFE("session is invalid");
1204 return WMError::WM_ERROR_INVALID_WINDOW;
1205 }
1206 if (WindowHelper::IsMainWindow(GetType()) && hostSession_) {
1207 hostSession_->SetGlobalMaximizeMode(mode);
1208 return WMError::WM_OK;
1209 } else {
1210 WLOGFW("SetGlobalMaximizeMode fail, not main window");
1211 return WMError::WM_ERROR_INVALID_PARAM;
1212 }
1213 }
1214
GetGlobalMaximizeMode() const1215 MaximizeMode WindowSceneSessionImpl::GetGlobalMaximizeMode() const
1216 {
1217 WLOGFD("WindowSceneSessionImpl::GetGlobalMaximizeMode");
1218 MaximizeMode mode = MaximizeMode::MODE_RECOVER;
1219 hostSession_->GetGlobalMaximizeMode(mode);
1220 return mode;
1221 }
1222
SetWindowMode(WindowMode mode)1223 WMError WindowSceneSessionImpl::SetWindowMode(WindowMode mode)
1224 {
1225 WLOGFI("SetWindowMode %{public}u mode %{public}u", GetWindowId(), static_cast<uint32_t>(mode));
1226 if (IsWindowSessionInvalid()) {
1227 return WMError::WM_ERROR_INVALID_WINDOW;
1228 }
1229 if (!WindowHelper::IsWindowModeSupported(property_->GetModeSupportInfo(), mode)) {
1230 WLOGFE("window %{public}u do not support mode: %{public}u",
1231 GetWindowId(), static_cast<uint32_t>(mode));
1232 return WMError::WM_ERROR_INVALID_WINDOW_MODE_OR_SIZE;
1233 }
1234 WMError ret = UpdateWindowModeImmediately(mode);
1235 if (ret != WMError::WM_OK) {
1236 return ret;
1237 }
1238
1239 if ((mode == WindowMode::WINDOW_MODE_SPLIT_PRIMARY || mode == WindowMode::WINDOW_MODE_SPLIT_SECONDARY) &&
1240 hostSession_) {
1241 if (mode == WindowMode::WINDOW_MODE_SPLIT_PRIMARY) {
1242 hostSession_->OnSessionEvent(SessionEvent::EVENT_SPLIT_PRIMARY);
1243 } else if (mode == WindowMode::WINDOW_MODE_SPLIT_SECONDARY) {
1244 hostSession_->OnSessionEvent(SessionEvent::EVENT_SPLIT_SECONDARY);
1245 }
1246
1247 ret = SetLayoutFullScreenByApiVersion(true);
1248 if (ret != WMError::WM_OK) {
1249 WLOGFE("SetLayoutFullScreenByApiVersion errCode:%{public}d winId:%{public}u",
1250 static_cast<int32_t>(ret), GetWindowId());
1251 return ret;
1252 }
1253 SystemBarProperty statusProperty = GetSystemBarPropertyByType(WindowType::WINDOW_TYPE_STATUS_BAR);
1254 statusProperty.enable_ = false;
1255 ret = SetSystemBarProperty(WindowType::WINDOW_TYPE_STATUS_BAR, statusProperty);
1256 if (ret != WMError::WM_OK) {
1257 WLOGFE("SetSystemBarProperty errCode:%{public}d winId:%{public}u",
1258 static_cast<int32_t>(ret), GetWindowId());
1259 return ret;
1260 }
1261 }
1262 return WMError::WM_OK;
1263 }
1264
GetMode() const1265 WindowMode WindowSceneSessionImpl::GetMode() const
1266 {
1267 return property_->GetWindowMode();
1268 }
1269
IsTransparent() const1270 bool WindowSceneSessionImpl::IsTransparent() const
1271 {
1272 WSColorParam backgroundColor;
1273 backgroundColor.value = GetBackgroundColor();
1274 WLOGFD("color: %{public}u, alpha: %{public}u", backgroundColor.value, backgroundColor.argb.alpha);
1275 return backgroundColor.argb.alpha == 0x00; // 0x00: completely transparent
1276 }
1277
SetTransparent(bool isTransparent)1278 WMError WindowSceneSessionImpl::SetTransparent(bool isTransparent)
1279 {
1280 if (IsWindowSessionInvalid()) {
1281 WLOGFE("session is invalid");
1282 return WMError::WM_ERROR_INVALID_WINDOW;
1283 }
1284 WSColorParam backgroundColor;
1285 backgroundColor.value = GetBackgroundColor();
1286 if (isTransparent) {
1287 backgroundColor.argb.alpha = 0x00; // 0x00: completely transparent
1288 return SetBackgroundColor(backgroundColor.value);
1289 } else {
1290 backgroundColor.value = GetBackgroundColor();
1291 if (backgroundColor.argb.alpha == 0x00) {
1292 backgroundColor.argb.alpha = 0xff; // 0xff: completely opaque
1293 return SetBackgroundColor(backgroundColor.value);
1294 }
1295 }
1296 return WMError::WM_OK;
1297 }
1298
AddWindowFlag(WindowFlag flag)1299 WMError WindowSceneSessionImpl::AddWindowFlag(WindowFlag flag)
1300 {
1301 uint32_t updateFlags = property_->GetWindowFlags() | (static_cast<uint32_t>(flag));
1302 return SetWindowFlags(updateFlags);
1303 }
1304
RemoveWindowFlag(WindowFlag flag)1305 WMError WindowSceneSessionImpl::RemoveWindowFlag(WindowFlag flag)
1306 {
1307 uint32_t updateFlags = property_->GetWindowFlags() & (~(static_cast<uint32_t>(flag)));
1308 return SetWindowFlags(updateFlags);
1309 }
1310
SetWindowFlags(uint32_t flags)1311 WMError WindowSceneSessionImpl::SetWindowFlags(uint32_t flags)
1312 {
1313 WLOGI("Session %{public}u flags %{public}u", GetWindowId(), flags);
1314 if (IsWindowSessionInvalid()) {
1315 return WMError::WM_ERROR_INVALID_WINDOW;
1316 }
1317 if (property_->GetWindowFlags() == flags) {
1318 return WMError::WM_OK;
1319 }
1320 auto oriFlags = property_->GetWindowFlags();
1321 property_->SetWindowFlags(flags);
1322 WMError ret = UpdateProperty(WSPropertyChangeAction::ACTION_UPDATE_FLAGS);
1323 if (ret != WMError::WM_OK) {
1324 WLOGFE("SetWindowFlags errCode:%{public}d winId:%{public}u",
1325 static_cast<int32_t>(ret), GetWindowId());
1326 property_->SetWindowFlags(oriFlags);
1327 }
1328 return ret;
1329 }
1330
GetWindowFlags() const1331 uint32_t WindowSceneSessionImpl::GetWindowFlags() const
1332 {
1333 return property_->GetWindowFlags();
1334 }
1335
ConvertRadiusToSigma(float radius)1336 static float ConvertRadiusToSigma(float radius)
1337 {
1338 return radius > 0.0f ? 0.57735f * radius + SK_ScalarHalf : 0.0f; // 0.57735f is blur sigma scale
1339 }
1340
CheckParmAndPermission()1341 WMError WindowSceneSessionImpl::CheckParmAndPermission()
1342 {
1343 if (surfaceNode_ == nullptr) {
1344 WLOGFE("RSSurface node is null");
1345 return WMError::WM_ERROR_NULLPTR;
1346 }
1347
1348 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
1349 WLOGFE("Check failed, permission denied");
1350 return WMError::WM_ERROR_NOT_SYSTEM_APP;
1351 }
1352
1353 return WMError::WM_OK;
1354 }
1355
UpdateConfiguration(const std::shared_ptr<AppExecFwk::Configuration> & configuration)1356 void WindowSceneSessionImpl::UpdateConfiguration(const std::shared_ptr<AppExecFwk::Configuration>& configuration)
1357 {
1358 if (uiContent_ != nullptr) {
1359 WLOGFD("notify ace winId:%{public}u", GetWindowId());
1360 uiContent_->UpdateConfiguration(configuration);
1361 }
1362 if (subWindowSessionMap_.count(GetPersistentId()) == 0) {
1363 return;
1364 }
1365 for (auto& subWindowSession : subWindowSessionMap_.at(GetPersistentId())) {
1366 subWindowSession->UpdateConfiguration(configuration);
1367 }
1368
1369 }
1370
UpdateConfigurationForAll(const std::shared_ptr<AppExecFwk::Configuration> & configuration)1371 void WindowSceneSessionImpl::UpdateConfigurationForAll(const std::shared_ptr<AppExecFwk::Configuration>& configuration)
1372 {
1373 WLOGD("notify scene ace update config");
1374 for (const auto& winPair : windowSessionMap_) {
1375 auto window = winPair.second.second;
1376 window->UpdateConfiguration(configuration);
1377 }
1378 }
1379
GetTopWindowWithContext(const std::shared_ptr<AbilityRuntime::Context> & context)1380 sptr<Window> WindowSceneSessionImpl::GetTopWindowWithContext(const std::shared_ptr<AbilityRuntime::Context>& context)
1381 {
1382 if (windowSessionMap_.empty()) {
1383 WLOGFE("Please create mainWindow First!");
1384 return nullptr;
1385 }
1386 uint32_t mainWinId = INVALID_WINDOW_ID;
1387 for (const auto& winPair : windowSessionMap_) {
1388 auto win = winPair.second.second;
1389 if (win && WindowHelper::IsMainWindow(win->GetType()) && context.get() == win->GetContext().get()) {
1390 mainWinId = win->GetWindowId();
1391 WLOGI("GetTopWindow Find MainWinId:%{public}u.", mainWinId);
1392 return win;
1393 }
1394 }
1395 WLOGFE("Cannot find topWindow!");
1396 return nullptr;
1397 }
1398
GetTopWindowWithId(uint32_t mainWinId)1399 sptr<Window> WindowSceneSessionImpl::GetTopWindowWithId(uint32_t mainWinId)
1400 {
1401 if (windowSessionMap_.empty()) {
1402 WLOGFE("Please create mainWindow First!");
1403 return nullptr;
1404 }
1405 for (const auto& winPair : windowSessionMap_) {
1406 auto win = winPair.second.second;
1407 if (win && WindowHelper::IsMainWindow(win->GetType()) && mainWinId == win->GetWindowId()) {
1408 WLOGI("GetTopWindow Find MainWinId:%{public}u.", mainWinId);
1409 return win;
1410 }
1411 }
1412 WLOGFE("Cannot find Window!");
1413 return nullptr;
1414 }
1415
SetCornerRadius(float cornerRadius)1416 WMError WindowSceneSessionImpl::SetCornerRadius(float cornerRadius)
1417 {
1418 if (surfaceNode_ == nullptr) {
1419 WLOGFE("RSSurface node is null");
1420 return WMError::WM_ERROR_NULLPTR;
1421 }
1422
1423 WLOGFI("Set window %{public}s corner radius %{public}f", GetWindowName().c_str(), cornerRadius);
1424 surfaceNode_->SetCornerRadius(cornerRadius);
1425 RSTransaction::FlushImplicitTransaction();
1426 return WMError::WM_OK;
1427 }
1428
SetShadowRadius(float radius)1429 WMError WindowSceneSessionImpl::SetShadowRadius(float radius)
1430 {
1431 WMError ret = CheckParmAndPermission();
1432 if (ret != WMError::WM_OK) {
1433 return ret;
1434 }
1435
1436 WLOGFI("Set window %{public}s shadow radius %{public}f", GetWindowName().c_str(), radius);
1437 if (MathHelper::LessNotEqual(radius, 0.0)) {
1438 return WMError::WM_ERROR_INVALID_PARAM;
1439 }
1440
1441 surfaceNode_->SetShadowRadius(radius);
1442 RSTransaction::FlushImplicitTransaction();
1443 return WMError::WM_OK;
1444 }
1445
SetShadowColor(std::string color)1446 WMError WindowSceneSessionImpl::SetShadowColor(std::string color)
1447 {
1448 WMError ret = CheckParmAndPermission();
1449 if (ret != WMError::WM_OK) {
1450 return ret;
1451 }
1452
1453 WLOGFI("Set window %{public}s shadow color %{public}s", GetWindowName().c_str(), color.c_str());
1454 uint32_t colorValue = 0;
1455 if (!ColorParser::Parse(color, colorValue)) {
1456 return WMError::WM_ERROR_INVALID_PARAM;
1457 }
1458
1459 surfaceNode_->SetShadowColor(colorValue);
1460 RSTransaction::FlushImplicitTransaction();
1461 return WMError::WM_OK;
1462 }
1463
SetShadowOffsetX(float offsetX)1464 WMError WindowSceneSessionImpl::SetShadowOffsetX(float offsetX)
1465 {
1466 WMError ret = CheckParmAndPermission();
1467 if (ret != WMError::WM_OK) {
1468 return ret;
1469 }
1470
1471 WLOGFI("Set window %{public}s shadow offsetX %{public}f", GetWindowName().c_str(), offsetX);
1472 surfaceNode_->SetShadowOffsetX(offsetX);
1473 RSTransaction::FlushImplicitTransaction();
1474 return WMError::WM_OK;
1475 }
1476
SetShadowOffsetY(float offsetY)1477 WMError WindowSceneSessionImpl::SetShadowOffsetY(float offsetY)
1478 {
1479 WMError ret = CheckParmAndPermission();
1480 if (ret != WMError::WM_OK) {
1481 return ret;
1482 }
1483
1484 WLOGFI("Set window %{public}s shadow offsetY %{public}f", GetWindowName().c_str(), offsetY);
1485 surfaceNode_->SetShadowOffsetY(offsetY);
1486 RSTransaction::FlushImplicitTransaction();
1487 return WMError::WM_OK;
1488 }
1489
SetBlur(float radius)1490 WMError WindowSceneSessionImpl::SetBlur(float radius)
1491 {
1492 WMError ret = CheckParmAndPermission();
1493 if (ret != WMError::WM_OK) {
1494 return ret;
1495 }
1496
1497 WLOGFI("Set window %{public}s blur radius %{public}f", GetWindowName().c_str(), radius);
1498 if (MathHelper::LessNotEqual(radius, 0.0)) {
1499 return WMError::WM_ERROR_INVALID_PARAM;
1500 }
1501
1502 radius = ConvertRadiusToSigma(radius);
1503 WLOGFI("Set window %{public}s blur radius after conversion %{public}f", GetWindowName().c_str(), radius);
1504 surfaceNode_->SetFilter(RSFilter::CreateBlurFilter(radius, radius));
1505 RSTransaction::FlushImplicitTransaction();
1506 return WMError::WM_OK;
1507 }
1508
SetBackdropBlur(float radius)1509 WMError WindowSceneSessionImpl::SetBackdropBlur(float radius)
1510 {
1511 WMError ret = CheckParmAndPermission();
1512 if (ret != WMError::WM_OK) {
1513 return ret;
1514 }
1515
1516 WLOGFI("Set window %{public}s backdrop blur radius %{public}f", GetWindowName().c_str(), radius);
1517 if (MathHelper::LessNotEqual(radius, 0.0)) {
1518 return WMError::WM_ERROR_INVALID_PARAM;
1519 }
1520
1521 radius = ConvertRadiusToSigma(radius);
1522 WLOGFI("Set window %{public}s backdrop blur radius after conversion %{public}f", GetWindowName().c_str(), radius);
1523 surfaceNode_->SetBackgroundFilter(RSFilter::CreateBlurFilter(radius, radius));
1524 RSTransaction::FlushImplicitTransaction();
1525 return WMError::WM_OK;
1526 }
1527
SetBackdropBlurStyle(WindowBlurStyle blurStyle)1528 WMError WindowSceneSessionImpl::SetBackdropBlurStyle(WindowBlurStyle blurStyle)
1529 {
1530 WMError ret = CheckParmAndPermission();
1531 if (ret != WMError::WM_OK) {
1532 return ret;
1533 }
1534
1535 WLOGFI("Set window %{public}s backdrop blur style %{public}u", GetWindowName().c_str(), blurStyle);
1536 if (blurStyle < WindowBlurStyle::WINDOW_BLUR_OFF || blurStyle > WindowBlurStyle::WINDOW_BLUR_THICK) {
1537 return WMError::WM_ERROR_INVALID_PARAM;
1538 }
1539
1540 if (blurStyle == WindowBlurStyle::WINDOW_BLUR_OFF) {
1541 surfaceNode_->SetBackgroundFilter(nullptr);
1542 } else {
1543 auto display = SingletonContainer::IsDestroyed() ? nullptr :
1544 SingletonContainer::Get<DisplayManager>().GetDisplayById(property_->GetDisplayId());
1545 if (display == nullptr) {
1546 WLOGFE("get display failed displayId:%{public}" PRIu64"", property_->GetDisplayId());
1547 return WMError::WM_ERROR_INVALID_PARAM;
1548 }
1549 surfaceNode_->SetBackgroundFilter(RSFilter::CreateMaterialFilter(static_cast<int>(blurStyle),
1550 display->GetVirtualPixelRatio()));
1551 }
1552
1553 RSTransaction::FlushImplicitTransaction();
1554 return WMError::WM_OK;
1555 }
1556
1557
SetPrivacyMode(bool isPrivacyMode)1558 WMError WindowSceneSessionImpl::SetPrivacyMode(bool isPrivacyMode)
1559 {
1560 WLOGFD("id : %{public}u, SetPrivacyMode, %{public}u", GetWindowId(), isPrivacyMode);
1561 property_->SetPrivacyMode(isPrivacyMode);
1562 return UpdateProperty(WSPropertyChangeAction::ACTION_UPDATE_PRIVACY_MODE);
1563 }
1564
IsPrivacyMode() const1565 bool WindowSceneSessionImpl::IsPrivacyMode() const
1566 {
1567 return property_->GetPrivacyMode();
1568 }
1569
SetSystemPrivacyMode(bool isSystemPrivacyMode)1570 void WindowSceneSessionImpl::SetSystemPrivacyMode(bool isSystemPrivacyMode)
1571 {
1572 WLOGFD("id : %{public}u, SetSystemPrivacyMode, %{public}u", GetWindowId(), isSystemPrivacyMode);
1573 property_->SetSystemPrivacyMode(isSystemPrivacyMode);
1574 UpdateProperty(WSPropertyChangeAction::ACTION_UPDATE_PRIVACY_MODE);
1575 }
1576
SetSnapshotSkip(bool isSkip)1577 WMError WindowSceneSessionImpl::SetSnapshotSkip(bool isSkip)
1578 {
1579 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
1580 WLOGFE("set snapshot skip permission denied!");
1581 return WMError::WM_ERROR_NOT_SYSTEM_APP;
1582 }
1583 surfaceNode_->SetSecurityLayer(isSkip || property_->GetSystemPrivacyMode());
1584 RSTransaction::FlushImplicitTransaction();
1585 return WMError::WM_OK;
1586 }
1587
Snapshot()1588 std::shared_ptr<Media::PixelMap> WindowSceneSessionImpl::Snapshot()
1589 {
1590 std::shared_ptr<SurfaceCaptureFuture> callback = std::make_shared<SurfaceCaptureFuture>();
1591 auto isSucceeded = RSInterfaces::GetInstance().TakeSurfaceCapture(surfaceNode_, callback);
1592 std::shared_ptr<Media::PixelMap> pixelMap;
1593 if (!isSucceeded) {
1594 WLOGFE("Failed to TakeSurfaceCapture!");
1595 return nullptr;
1596 }
1597 pixelMap = callback->GetResult(2000); // wait for <= 2000ms
1598 if (pixelMap != nullptr) {
1599 WLOGFD("Snapshot succeed, save WxH = %{public}dx%{public}d", pixelMap->GetWidth(), pixelMap->GetHeight());
1600 } else {
1601 WLOGFE("Failed to get pixelmap, return nullptr!");
1602 }
1603 return pixelMap;
1604 }
1605
NotifyMemoryLevel(int32_t level)1606 WMError WindowSceneSessionImpl::NotifyMemoryLevel(int32_t level)
1607 {
1608 WLOGFD("id: %{public}u, notify memory level: %{public}d", GetWindowId(), level);
1609 std::lock_guard<std::recursive_mutex> lock(mutex_);
1610 if (uiContent_ == nullptr) {
1611 WLOGFE("Window %{public}s notify memory level failed, ace is null.", GetWindowName().c_str());
1612 return WMError::WM_ERROR_NULLPTR;
1613 }
1614 // notify memory level
1615 uiContent_->NotifyMemoryLevel(level);
1616 WLOGFD("WindowSceneSessionImpl::NotifyMemoryLevel End!");
1617 return WMError::WM_OK;
1618 }
SetTurnScreenOn(bool turnScreenOn)1619 WMError WindowSceneSessionImpl::SetTurnScreenOn(bool turnScreenOn)
1620 {
1621 if (IsWindowSessionInvalid()) {
1622 return WMError::WM_ERROR_INVALID_WINDOW;
1623 }
1624 property_->SetTurnScreenOn(turnScreenOn);
1625 if (state_ == WindowState::STATE_SHOWN) {
1626 return UpdateProperty(WSPropertyChangeAction::ACTION_UPDATE_TURN_SCREEN_ON);
1627 }
1628 return WMError::WM_OK;
1629 }
1630
IsTurnScreenOn() const1631 bool WindowSceneSessionImpl::IsTurnScreenOn() const
1632 {
1633 return property_->IsTurnScreenOn();
1634 }
1635
SetKeepScreenOn(bool keepScreenOn)1636 WMError WindowSceneSessionImpl::SetKeepScreenOn(bool keepScreenOn)
1637 {
1638 if (IsWindowSessionInvalid()) {
1639 WLOGFE("session is invalid");
1640 return WMError::WM_ERROR_INVALID_WINDOW;
1641 }
1642 property_->SetKeepScreenOn(keepScreenOn);
1643 if (state_ == WindowState::STATE_SHOWN) {
1644 return UpdateProperty(WSPropertyChangeAction::ACTION_UPDATE_KEEP_SCREEN_ON);
1645 }
1646 return WMError::WM_OK;
1647 }
1648
IsKeepScreenOn() const1649 bool WindowSceneSessionImpl::IsKeepScreenOn() const
1650 {
1651 return property_->IsKeepScreenOn();
1652 }
1653
SetNeedDefaultAnimation(bool needDefaultAnimation)1654 void WindowSceneSessionImpl::SetNeedDefaultAnimation(bool needDefaultAnimation)
1655 {
1656 enableDefaultAnimation_= needDefaultAnimation;
1657 hostSession_->UpdateWindowAnimationFlag(needDefaultAnimation);
1658 return;
1659 }
1660
SetTransform(const Transform & trans)1661 WMError WindowSceneSessionImpl::SetTransform(const Transform& trans)
1662 {
1663 WLOGFI("property_ persistentId: %{public}d", property_->GetPersistentId());
1664 if (IsWindowSessionInvalid()) {
1665 return WMError::WM_ERROR_INVALID_WINDOW;
1666 }
1667 Transform oriTrans = property_->GetTransform();
1668 property_->SetTransform(trans);
1669 TransformSurfaceNode(trans);
1670 return WMError::WM_OK;
1671 }
1672
GetTransform() const1673 const Transform& WindowSceneSessionImpl::GetTransform() const
1674 {
1675 return property_->GetTransform();
1676 }
1677
TransformSurfaceNode(const Transform & trans)1678 void WindowSceneSessionImpl::TransformSurfaceNode(const Transform& trans)
1679 {
1680 if (surfaceNode_ == nullptr) {
1681 return;
1682 }
1683 surfaceNode_->SetPivotX(trans.pivotX_);
1684 surfaceNode_->SetPivotY(trans.pivotY_);
1685 surfaceNode_->SetScaleX(trans.scaleX_);
1686 surfaceNode_->SetScaleY(trans.scaleY_);
1687 surfaceNode_->SetTranslateX(trans.translateX_);
1688 surfaceNode_->SetTranslateY(trans.translateY_);
1689 surfaceNode_->SetTranslateZ(trans.translateZ_);
1690 surfaceNode_->SetRotationX(trans.rotationX_);
1691 surfaceNode_->SetRotationY(trans.rotationY_);
1692 surfaceNode_->SetRotation(trans.rotationZ_);
1693 uint32_t animationFlag = property_->GetAnimationFlag();
1694 if (animationFlag != static_cast<uint32_t>(WindowAnimation::CUSTOM)) {
1695 RSTransaction::FlushImplicitTransaction();
1696 }
1697 }
1698
RegisterAnimationTransitionController(const sptr<IAnimationTransitionController> & listener)1699 WMError WindowSceneSessionImpl::RegisterAnimationTransitionController(
1700 const sptr<IAnimationTransitionController>& listener)
1701 {
1702 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
1703 WLOGFE("register animation transition controller permission denied!");
1704 return WMError::WM_ERROR_NOT_SYSTEM_APP;
1705 }
1706 if (listener == nullptr) {
1707 WLOGFE("listener is nullptr");
1708 return WMError::WM_ERROR_NULLPTR;
1709 }
1710 animationTransitionController_ = listener;
1711 wptr<WindowSessionProperty> propertyToken(property_);
1712 wptr<IAnimationTransitionController> animationTransitionControllerToken(animationTransitionController_);
1713 if (uiContent_) {
1714 uiContent_->SetNextFrameLayoutCallback([propertyToken, animationTransitionControllerToken]() {
1715 auto property = propertyToken.promote();
1716 auto animationTransitionController = animationTransitionControllerToken.promote();
1717 if (!property || !animationTransitionController) {
1718 return;
1719 }
1720 uint32_t animationFlag = property->GetAnimationFlag();
1721 if (animationFlag == static_cast<uint32_t>(WindowAnimation::CUSTOM)) {
1722 // CustomAnimation is enabled when animationTransitionController_ exists
1723 animationTransitionController->AnimationForShown();
1724 }
1725 WLOGFI("AnimationForShown excute sucess %{public}d!", property->GetPersistentId());
1726 });
1727 }
1728 WLOGI("RegisterAnimationTransitionController %{public}d!", property_->GetPersistentId());
1729 return WMError::WM_OK;
1730 }
1731
UpdateSurfaceNodeAfterCustomAnimation(bool isAdd)1732 WMError WindowSceneSessionImpl::UpdateSurfaceNodeAfterCustomAnimation(bool isAdd)
1733 {
1734 WLOGFI("id: %{public}d , isAdd:%{public}u", property_->GetPersistentId(), isAdd);
1735 if (IsWindowSessionInvalid()) {
1736 return WMError::WM_ERROR_INVALID_WINDOW;
1737 }
1738 if (!WindowHelper::IsSystemWindow(property_->GetWindowType())) {
1739 WLOGFE("only system window can set");
1740 return WMError::WM_ERROR_INVALID_OPERATION;
1741 }
1742 // set no custom after customAnimation
1743 WMError ret = UpdateAnimationFlagProperty(false);
1744 if (ret != WMError::WM_OK) {
1745 WLOGFE("UpdateAnimationFlagProperty failed!");
1746 return ret;
1747 }
1748 ret = static_cast<WMError>(hostSession_->UpdateWindowSceneAfterCustomAnimation(isAdd));
1749 return ret;
1750 }
1751
AdjustWindowAnimationFlag(bool withAnimation)1752 void WindowSceneSessionImpl::AdjustWindowAnimationFlag(bool withAnimation)
1753 {
1754 if (IsWindowSessionInvalid()) {
1755 WLOGE("AdjustWindowAnimationFlag failed since session ivalid!");
1756 return;
1757 }
1758 // when show/hide with animation
1759 // use custom animation when transitionController exists; else use default animation
1760 WindowType winType = property_->GetWindowType();
1761 bool isAppWindow = WindowHelper::IsAppWindow(winType);
1762 if (withAnimation && !isAppWindow && animationTransitionController_) {
1763 // use custom animation
1764 property_->SetAnimationFlag(static_cast<uint32_t>(WindowAnimation::CUSTOM));
1765 } else if ((isAppWindow && enableDefaultAnimation_) || (withAnimation && !animationTransitionController_)) {
1766 // use default animation
1767 property_->SetAnimationFlag(static_cast<uint32_t>(WindowAnimation::DEFAULT));
1768 } else {
1769 // with no animation
1770 property_->SetAnimationFlag(static_cast<uint32_t>(WindowAnimation::NONE));
1771 }
1772 }
1773
UpdateAnimationFlagProperty(bool withAnimation)1774 WMError WindowSceneSessionImpl::UpdateAnimationFlagProperty(bool withAnimation)
1775 {
1776 if (!WindowHelper::IsSystemWindow(GetType())) {
1777 return WMError::WM_OK;
1778 }
1779 AdjustWindowAnimationFlag(withAnimation);
1780 // when show(true) with default, hide() with None, to adjust animationFlag to disabled default animation
1781 return UpdateProperty(WSPropertyChangeAction::ACTION_UPDATE_ANIMATION_FLAG);
1782 }
1783
SetAlpha(float alpha)1784 WMError WindowSceneSessionImpl::SetAlpha(float alpha)
1785 {
1786 WLOGI("Window %{public}d alpha %{public}f", property_->GetPersistentId(), alpha);
1787 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
1788 WLOGFE("set alpha permission denied!");
1789 return WMError::WM_ERROR_NOT_SYSTEM_APP;
1790 }
1791 if (IsWindowSessionInvalid()) {
1792 return WMError::WM_ERROR_INVALID_WINDOW;
1793 }
1794 surfaceNode_->SetAlpha(alpha);
1795 RSTransaction::FlushImplicitTransaction();
1796 return WMError::WM_OK;
1797 }
1798
BindDialogTarget(sptr<IRemoteObject> targetToken)1799 WMError WindowSceneSessionImpl::BindDialogTarget(sptr<IRemoteObject> targetToken)
1800 {
1801 auto persistentId = property_->GetPersistentId();
1802 WMError ret = SessionManager::GetInstance().BindDialogTarget(persistentId, targetToken);
1803 if (ret != WMError::WM_OK) {
1804 WLOGFE("bind window failed with errCode:%{public}d", static_cast<int32_t>(ret));
1805 }
1806 return ret;
1807 }
1808
SetTouchHotAreas(const std::vector<Rect> & rects)1809 WMError WindowSceneSessionImpl::SetTouchHotAreas(const std::vector<Rect>& rects)
1810 {
1811 if (property_ == nullptr) {
1812 return WMError::WM_ERROR_NULLPTR;
1813 }
1814 std::vector<Rect> lastTouchHotAreas;
1815 property_->GetTouchHotAreas(lastTouchHotAreas);
1816 property_->SetTouchHotAreas(rects);
1817 WMError result = UpdateProperty(WSPropertyChangeAction::ACTION_UPDATE_TOUCH_HOT_AREA);
1818 if (result != WMError::WM_OK) {
1819 property_->SetTouchHotAreas(lastTouchHotAreas);
1820 WLOGFE("SetTouchHotAreas with errCode:%{public}d", static_cast<int32_t>(result));
1821 return result;
1822 }
1823 for (uint32_t i = 0; i < rects.size(); i++) {
1824 WLOGFI("Set areas: %{public}u [x: %{public}d y:%{public}d w:%{public}u h:%{public}u]",
1825 i, rects[i].posX_, rects[i].posY_, rects[i].width_, rects[i].height_);
1826 }
1827 return result;
1828 }
1829
DumpSessionElementInfo(const std::vector<std::string> & params)1830 void WindowSceneSessionImpl::DumpSessionElementInfo(const std::vector<std::string>& params)
1831 {
1832 WLOGFD("DumpSessionElementInfo");
1833 std::vector<std::string> info;
1834 if (params.size() == 1 && params[0] == PARAM_DUMP_HELP) { // 1: params num
1835 WLOGFD("Dump ArkUI help Info");
1836 Ace::UIContent::ShowDumpHelp(info);
1837 SingletonContainer::Get<WindowAdapter>().NotifyDumpInfoResult(info);
1838 return;
1839 }
1840 WLOGFD("ArkUI:DumpInfo");
1841 if (uiContent_ != nullptr) {
1842 uiContent_->DumpInfo(params, info);
1843 }
1844 SingletonContainer::Get<WindowAdapter>().NotifyDumpInfoResult(info);
1845 }
1846
UpdateWindowMode(WindowMode mode)1847 WSError WindowSceneSessionImpl::UpdateWindowMode(WindowMode mode)
1848 {
1849 WLOGFI("UpdateWindowMode %{public}u mode %{public}u", GetWindowId(), static_cast<uint32_t>(mode));
1850 if (IsWindowSessionInvalid()) {
1851 return WSError::WS_ERROR_INVALID_WINDOW;
1852 }
1853 if (!WindowHelper::IsWindowModeSupported(property_->GetModeSupportInfo(), mode)) {
1854 WLOGFE("window %{public}u do not support mode: %{public}u",
1855 GetWindowId(), static_cast<uint32_t>(mode));
1856 return WSError::WS_ERROR_INVALID_WINDOW_MODE_OR_SIZE;
1857 }
1858 WMError ret = UpdateWindowModeImmediately(mode);
1859 return static_cast<WSError>(ret);
1860 }
1861
UpdateWindowModeImmediately(WindowMode mode)1862 WMError WindowSceneSessionImpl::UpdateWindowModeImmediately(WindowMode mode)
1863 {
1864 if (state_ == WindowState::STATE_CREATED || state_ == WindowState::STATE_HIDDEN) {
1865 property_->SetWindowMode(mode);
1866 UpdateTitleButtonVisibility();
1867 UpdateDecorEnable(true);
1868 } else if (state_ == WindowState::STATE_SHOWN) {
1869 WMError ret = UpdateProperty(WSPropertyChangeAction::ACTION_UPDATE_MODE);
1870 if (ret != WMError::WM_OK) {
1871 WLOGFE("update window mode filed! id: %{public}u, mode: %{public}u.", GetWindowId(),
1872 static_cast<uint32_t>(mode));
1873 return ret;
1874 }
1875 // set client window mode if success.
1876 property_->SetWindowMode(mode);
1877 UpdateTitleButtonVisibility();
1878 UpdateDecorEnable(true);
1879 }
1880 return WMError::WM_OK;
1881 }
1882 } // namespace Rosen
1883 } // namespace OHOS
1884