• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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