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 "session/host/include/root_scene_session.h"
17
18 #include "display_manager.h"
19
20 namespace OHOS::Rosen {
SetLoadContentFunc(const LoadContentFunc & loadContentFunc)21 void RootSceneSession::SetLoadContentFunc(const LoadContentFunc& loadContentFunc)
22 {
23 loadContentFunc_ = loadContentFunc;
24 }
25
LoadContent(const std::string & contentUrl,napi_env env,napi_value storage,AbilityRuntime::Context * context)26 void RootSceneSession::LoadContent(
27 const std::string& contentUrl, napi_env env, napi_value storage, AbilityRuntime::Context* context)
28 {
29 if (loadContentFunc_) {
30 loadContentFunc_(contentUrl, env, storage, context);
31 }
32 }
33
GetSystemAvoidAreaForRoot(const WSRect & rect,AvoidArea & avoidArea)34 void RootSceneSession::GetSystemAvoidAreaForRoot(const WSRect& rect, AvoidArea& avoidArea)
35 {
36 std::vector<sptr<SceneSession>> statusBarVector;
37 DisplayId displayId = GetSessionProperty()->GetDisplayId();
38 if (specificCallback_ != nullptr && specificCallback_->onGetSceneSessionVectorByTypeAndDisplayId_) {
39 statusBarVector = specificCallback_->onGetSceneSessionVectorByTypeAndDisplayId_(
40 WindowType::WINDOW_TYPE_STATUS_BAR, displayId);
41 }
42 for (auto& statusBar : statusBarVector) {
43 bool isVisible = statusBar->IsVisible();
44 if (onGetStatusBarConstantlyShowFunc_) {
45 onGetStatusBarConstantlyShowFunc_(displayId, isVisible);
46 TLOGD(WmsLogTag::WMS_IMMS, "displayId %{public}" PRIu64 " constantly isVisible %{public}d",
47 displayId, isVisible);
48 }
49 if (!isVisible) {
50 TLOGI(WmsLogTag::WMS_IMMS, "invisible");
51 continue;
52 }
53 WSRect statusBarRect = statusBar->GetSessionRect();
54 if (onGetStatusBarAvoidHeightFunc_) {
55 onGetStatusBarAvoidHeightFunc_(displayId, statusBarRect);
56 }
57 CalculateAvoidAreaByType(AvoidAreaType::TYPE_SYSTEM, rect, statusBarRect, avoidArea);
58 }
59 }
60
GetKeyboardAvoidAreaForRoot(const WSRect & rect,AvoidArea & avoidArea)61 void RootSceneSession::GetKeyboardAvoidAreaForRoot(const WSRect& rect, AvoidArea& avoidArea)
62 {
63 std::vector<sptr<SceneSession>> inputMethodVector;
64 if (specificCallback_ != nullptr && specificCallback_->onGetSceneSessionVectorByType_) {
65 inputMethodVector = specificCallback_->onGetSceneSessionVectorByType_(
66 WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT);
67 }
68 for (auto& inputMethod : inputMethodVector) {
69 if (inputMethod == nullptr || (inputMethod->GetSessionState() != SessionState::STATE_FOREGROUND &&
70 inputMethod->GetSessionState() != SessionState::STATE_ACTIVE)) {
71 continue;
72 }
73 SessionGravity gravity = inputMethod->GetKeyboardGravity();
74 if (gravity == SessionGravity::SESSION_GRAVITY_FLOAT || !inputMethod->IsKeyboardAvoidAreaActive()) {
75 continue;
76 }
77 if (isKeyboardPanelEnabled_) {
78 WSRect keyboardRect;
79 if (inputMethod && inputMethod->GetKeyboardPanelSession()) {
80 keyboardRect = inputMethod->GetKeyboardPanelSession()->GetSessionRect();
81 inputMethod->RecalculatePanelRectForAvoidArea(keyboardRect);
82 }
83 CalculateAvoidAreaByType(AvoidAreaType::TYPE_KEYBOARD, rect, keyboardRect, avoidArea);
84 } else {
85 WSRect inputMethodRect = inputMethod->GetSessionRect();
86 CalculateAvoidAreaByType(AvoidAreaType::TYPE_KEYBOARD, rect, inputMethodRect, avoidArea);
87 }
88 }
89 }
90
GetCutoutAvoidAreaForRoot(const WSRect & rect,AvoidArea & avoidArea)91 void RootSceneSession::GetCutoutAvoidAreaForRoot(const WSRect& rect, AvoidArea& avoidArea)
92 {
93 auto display = DisplayManager::GetInstance().GetDisplayById(GetSessionProperty()->GetDisplayId());
94 if (display == nullptr) {
95 TLOGE(WmsLogTag::WMS_IMMS, "Failed to get display");
96 return;
97 }
98 sptr<CutoutInfo> cutoutInfo = display->GetCutoutInfo();
99 if (cutoutInfo == nullptr) {
100 TLOGI(WmsLogTag::WMS_IMMS, "There is no CutoutInfo");
101 return;
102 }
103 std::vector<DMRect> cutoutAreas = cutoutInfo->GetBoundingRects();
104 if (cutoutAreas.empty()) {
105 TLOGI(WmsLogTag::WMS_IMMS, "There is no cutoutAreas");
106 return;
107 }
108 for (auto& cutoutArea : cutoutAreas) {
109 WSRect cutoutAreaRect = {
110 cutoutArea.posX_, cutoutArea.posY_,
111 cutoutArea.width_, cutoutArea.height_
112 };
113 CalculateAvoidAreaByType(AvoidAreaType::TYPE_CUTOUT, rect, cutoutAreaRect, avoidArea);
114 }
115 }
116
GetAINavigationBarAreaForRoot(const WSRect & rect,AvoidArea & avoidArea)117 void RootSceneSession::GetAINavigationBarAreaForRoot(const WSRect& rect, AvoidArea& avoidArea)
118 {
119 WSRect barArea;
120 if (specificCallback_ != nullptr && specificCallback_->onGetAINavigationBarArea_) {
121 barArea = specificCallback_->onGetAINavigationBarArea_(GetSessionProperty()->GetDisplayId());
122 }
123 CalculateAvoidAreaByType(AvoidAreaType::TYPE_NAVIGATION_INDICATOR, rect, barArea, avoidArea);
124 }
125
GetAvoidAreaByType(AvoidAreaType type,const WSRect & rect,int32_t apiVersion)126 AvoidArea RootSceneSession::GetAvoidAreaByType(AvoidAreaType type, const WSRect& rect, int32_t apiVersion)
127 {
128 auto task = [weakThis = wptr(this), type]() -> AvoidArea {
129 auto session = weakThis.promote();
130 if (!session) {
131 TLOGNE(WmsLogTag::WMS_IMMS, "session is null");
132 return {};
133 }
134
135 AvoidArea avoidArea;
136 WSRect sessionRect = session->GetSessionRect();
137 switch (type) {
138 case AvoidAreaType::TYPE_SYSTEM: {
139 session->GetSystemAvoidAreaForRoot(sessionRect, avoidArea);
140 return avoidArea;
141 }
142 case AvoidAreaType::TYPE_CUTOUT: {
143 session->GetCutoutAvoidAreaForRoot(sessionRect, avoidArea);
144 return avoidArea;
145 }
146 case AvoidAreaType::TYPE_SYSTEM_GESTURE: {
147 return avoidArea;
148 }
149 case AvoidAreaType::TYPE_KEYBOARD: {
150 session->GetKeyboardAvoidAreaForRoot(sessionRect, avoidArea);
151 return avoidArea;
152 }
153 case AvoidAreaType::TYPE_NAVIGATION_INDICATOR: {
154 session->GetAINavigationBarAreaForRoot(sessionRect, avoidArea);
155 return avoidArea;
156 }
157 default: {
158 TLOGNE(WmsLogTag::WMS_IMMS, "cannot find type %{public}u, id %{public}d",
159 type, session->GetPersistentId());
160 return avoidArea;
161 }
162 }
163 };
164 return PostSyncTask(task, __func__);
165 }
166
SetRootSessionRect(const WSRect & rect)167 void RootSceneSession::SetRootSessionRect(const WSRect& rect)
168 {
169 if (!rect.IsInvalid() && GetSessionRect() != rect) {
170 layoutController_->SetSessionRect(rect);
171 TLOGI(WmsLogTag::WMS_IMMS, "update rect: %{public}s", GetSessionRect().ToString().c_str());
172 if (specificCallback_ != nullptr && specificCallback_->onUpdateAvoidArea_) {
173 specificCallback_->onUpdateAvoidArea_(GetPersistentId());
174 }
175 }
176 }
177
UpdateAvoidArea(const sptr<AvoidArea> & avoidArea,AvoidAreaType type)178 WSError RootSceneSession::UpdateAvoidArea(const sptr<AvoidArea>& avoidArea, AvoidAreaType type)
179 {
180 if (specificCallback_ == nullptr || specificCallback_->onNotifyAvoidAreaChange_ == nullptr) {
181 TLOGE(WmsLogTag::WMS_IMMS, "callback is nullptr");
182 return WSError::WS_ERROR_NULLPTR;
183 }
184 specificCallback_->onNotifyAvoidAreaChange_(avoidArea, type);
185 return WSError::WS_OK;
186 }
187 } // namespace OHOS::Rosen
188