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_system_effect.h" 17 18#include <common/rs_common_def.h> 19#include "color_parser.h" 20#include "display_group_info.h" 21#include "remote_animation.h" 22#include "window_helper.h" 23#include "window_inner_manager.h" 24#include "window_manager_hilog.h" 25 26namespace OHOS { 27namespace Rosen { 28namespace { 29constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WINDOW, "WindowSystemEffect"}; 30} 31 32AppWindowEffectConfig WindowSystemEffect::windowSystemEffectConfig_; 33wptr<WindowRoot> WindowSystemEffect::windowRoot_; 34 35void WindowSystemEffect::SetWindowSystemEffectConfig(AppWindowEffectConfig config) 36{ 37 windowSystemEffectConfig_ = config; 38} 39 40void WindowSystemEffect::SetWindowRoot(const sptr<WindowRoot>& windowRoot) 41{ 42 windowRoot_ = windowRoot; 43} 44 45WMError WindowSystemEffect::SetCornerRadius(const sptr<WindowNode>& node, bool needCheckAnimation) 46{ 47 auto winRoot = windowRoot_.promote(); 48 if (winRoot == nullptr || node == nullptr) { 49 WLOGFE("window root is null"); 50 return WMError::WM_ERROR_NULLPTR; 51 } 52 // if change mode during animation, not set radius until animationFinish 53 if (needCheckAnimation && RemoteAnimation::IsRemoteAnimationEnabledAndFirst(node->GetDisplayId()) && 54 node->stateMachine_.IsShowAnimationPlaying()) { 55 WLOGFW("not set radius during animation"); 56 return WMError::WM_DO_NOTHING; 57 } 58 59 if (!IsAppMainOrSubOrFloatingWindow(node)) { 60 return WMError::WM_DO_NOTHING; 61 } 62 auto vpr = DisplayGroupInfo::GetInstance().GetDisplayVirtualPixelRatio(node->GetDisplayId()); 63 auto fullscreenRadius = windowSystemEffectConfig_.fullScreenCornerRadius_ * vpr; 64 auto splitRadius = windowSystemEffectConfig_.splitCornerRadius_ * vpr; 65 auto floatRadius = windowSystemEffectConfig_.floatCornerRadius_ * vpr; 66 67 WLOGFD("[WEffect] [id:%{public}d] mode: %{public}u, vpr: %{public}f, [%{public}f, %{public}f, %{public}f]", 68 node->GetWindowId(), node->GetWindowMode(), vpr, fullscreenRadius, splitRadius, floatRadius); 69 if (MathHelper::NearZero(fullscreenRadius) && MathHelper::NearZero(splitRadius) && 70 MathHelper::NearZero(floatRadius)) { 71 return WMError::WM_DO_NOTHING; 72 } 73 auto surfaceNode = node->leashWinSurfaceNode_ != nullptr ? node->leashWinSurfaceNode_ : node->surfaceNode_; 74 if (surfaceNode == nullptr) { 75 WLOGFE("window surfaceNode is null"); 76 return WMError::WM_ERROR_NULLPTR; 77 } 78 if (WindowHelper::IsFullScreenWindow(node->GetWindowMode())) { 79 surfaceNode->SetCornerRadius(fullscreenRadius); 80 } else if (WindowHelper::IsSplitWindowMode(node->GetWindowMode())) { 81 surfaceNode->SetCornerRadius(splitRadius); 82 } else if (WindowHelper::IsFloatingWindow(node->GetWindowMode())) { 83 surfaceNode->SetCornerRadius(floatRadius); 84 } 85 return WMError::WM_OK; 86} 87 88bool WindowSystemEffect::IsAppMainOrSubOrFloatingWindow(const sptr<WindowNode>& node) 89{ 90 if (WindowHelper::IsAppWindow(node->GetWindowType())) { 91 return true; 92 } 93 auto winRoot = windowRoot_.promote(); 94 if (winRoot == nullptr) { 95 return false; 96 } 97 // Type float has main window 98 if (WindowHelper::IsAppFloatingWindow(node->GetWindowType()) && 99 winRoot->FindMainWindowWithToken(node->abilityToken_)) { 100 return true; 101 } 102 WLOGFD("not appWindow or app floating window, id: %{public}u!", node->GetWindowId()); 103 return false; 104} 105 106WMError WindowSystemEffect::SetWindowShadow(const sptr<WindowNode>& node) 107{ 108 auto winRoot = windowRoot_.promote(); 109 if (winRoot == nullptr || node == nullptr) { 110 return WMError::WM_ERROR_NULLPTR; 111 } 112 113 if (!IsAppMainOrSubOrFloatingWindow(node)) { 114 return WMError::WM_DO_NOTHING; 115 } 116 117 if (MathHelper::NearZero(windowSystemEffectConfig_.focusedShadow_.elevation_) && 118 MathHelper::NearZero(windowSystemEffectConfig_.unfocusedShadow_.elevation_) && 119 MathHelper::NearZero(windowSystemEffectConfig_.focusedShadow_.radius_) && 120 MathHelper::NearZero(windowSystemEffectConfig_.unfocusedShadow_.radius_)) { 121 WLOGFD("shadow elevation and radius are both 0.0, id: %{public}u", node->GetWindowId()); 122 return WMError::WM_DO_NOTHING; 123 } 124 125 auto surfaceNode = node->leashWinSurfaceNode_ != nullptr ? node->leashWinSurfaceNode_ : node->surfaceNode_; 126 if (surfaceNode == nullptr) { 127 WLOGFE("window surfaceNode is null"); 128 return WMError::WM_ERROR_NULLPTR; 129 } 130 131 auto& shadow = node->isFocused_ ? windowSystemEffectConfig_.focusedShadow_ : 132 windowSystemEffectConfig_.unfocusedShadow_; 133 134 // when float mode change to fullscreen/split mode 135 if (!WindowHelper::IsFloatingWindow(node->GetWindowMode())) { 136 if (MathHelper::GreatNotEqual(shadow.elevation_, 0.f)) { 137 surfaceNode->SetShadowElevation(0.f); 138 } else { 139 surfaceNode->SetShadowRadius(0.f); 140 } 141 surfaceNode->SetShadowAlpha(0.f); 142 WLOGFD("[WEffect]close shadow id: %{public}u", node->GetWindowId()); 143 return WMError::WM_OK; 144 } 145 146 uint32_t colorValue; 147 if (!ColorParser::Parse(shadow.color_, colorValue)) { 148 WLOGFE("[WEffect]invalid color string: %{public}s", shadow.color_.c_str()); 149 return WMError::WM_ERROR_INVALID_PARAM; 150 } 151 152 WLOGFI("[WEffect]id: %{public}u focused: %{public}d elevation: %{public}f", 153 node->GetWindowId(), static_cast<int32_t>(node->isFocused_), shadow.elevation_); 154 WLOGFI("[WEffect]color: %{public}s offsetX: %{public}f offsetY: %{public}f alpha: %{public}f radius: %{public}f", 155 shadow.color_.c_str(), shadow.offsetX_, shadow.offsetY_, shadow.alpha_, shadow.radius_); 156 auto vpr = DisplayGroupInfo::GetInstance().GetDisplayVirtualPixelRatio(node->GetDisplayId()); 157 if (MathHelper::GreatNotEqual(shadow.elevation_, 0.f)) { 158 surfaceNode->SetShadowElevation(shadow.elevation_ * vpr); 159 } else { 160 surfaceNode->SetShadowRadius(ConvertRadiusToSigma(shadow.radius_ * vpr)); 161 } 162 surfaceNode->SetShadowColor(colorValue); 163 surfaceNode->SetShadowOffsetX(shadow.offsetX_ * vpr); 164 surfaceNode->SetShadowOffsetY(shadow.offsetY_ * vpr); 165 surfaceNode->SetShadowAlpha(shadow.alpha_); 166 return WMError::WM_OK; 167} 168 169WMError WindowSystemEffect::SetWindowEffect(const sptr<WindowNode>& node, bool needCheckAnimation) 170{ 171 auto winRoot = windowRoot_.promote(); 172 if (node == nullptr) { 173 WLOGFE("window node is null"); 174 return WMError::WM_ERROR_NULLPTR; 175 } 176 SetCornerRadius(node, needCheckAnimation); 177 SetWindowShadow(node); 178 return WMError::WM_OK; 179} 180} // Rosen 181} // OHOS 182