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, "root scene status bar not visible");
51 continue;
52 }
53 WSRect statusBarRect = statusBar->GetSessionRect();
54 if (onGetStatusBarAvoidHeightFunc_) {
55 onGetStatusBarAvoidHeightFunc_(statusBarRect);
56 TLOGD(WmsLogTag::WMS_IMMS, "status bar height %{public}d", statusBarRect.height_);
57 }
58 CalculateAvoidAreaRect(rect, statusBarRect, avoidArea);
59 TLOGI(WmsLogTag::WMS_IMMS, "root scene %{public}s status bar %{public}s area %{public}s",
60 rect.ToString().c_str(), statusBarRect.ToString().c_str(), avoidArea.ToString().c_str());
61 }
62 }
63
GetKeyboardAvoidAreaForRoot(const WSRect & rect,AvoidArea & avoidArea)64 void RootSceneSession::GetKeyboardAvoidAreaForRoot(const WSRect& rect, AvoidArea& avoidArea)
65 {
66 std::vector<sptr<SceneSession>> inputMethodVector;
67 if (specificCallback_ != nullptr && specificCallback_->onGetSceneSessionVectorByType_) {
68 inputMethodVector = specificCallback_->onGetSceneSessionVectorByType_(
69 WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT);
70 }
71 for (auto& inputMethod : inputMethodVector) {
72 if (!inputMethod->IsVisible()) {
73 continue;
74 }
75 SessionGravity gravity = inputMethod->GetKeyboardGravity();
76 if (gravity == SessionGravity::SESSION_GRAVITY_FLOAT || !inputMethod->IsKeyboardAvoidAreaActive()) {
77 continue;
78 }
79 if (isKeyboardPanelEnabled_) {
80 WSRect keyboardRect;
81 if (inputMethod && inputMethod->GetKeyboardPanelSession()) {
82 keyboardRect = inputMethod->GetKeyboardPanelSession()->GetSessionRect();
83 inputMethod->RecalculatePanelRectForAvoidArea(keyboardRect);
84 }
85 CalculateAvoidAreaRect(rect, keyboardRect, avoidArea);
86 TLOGI(WmsLogTag::WMS_IMMS, "root scene %{public}s keyboard %{public}s area %{public}s",
87 rect.ToString().c_str(), keyboardRect.ToString().c_str(), avoidArea.ToString().c_str());
88 } else {
89 WSRect inputMethodRect = inputMethod->GetSessionRect();
90 CalculateAvoidAreaRect(rect, inputMethodRect, avoidArea);
91 TLOGI(WmsLogTag::WMS_IMMS, "root scene %{public}s input method %{public}s area %{public}s",
92 rect.ToString().c_str(), inputMethodRect.ToString().c_str(), avoidArea.ToString().c_str());
93 }
94 }
95 }
96
GetCutoutAvoidAreaForRoot(const WSRect & rect,AvoidArea & avoidArea)97 void RootSceneSession::GetCutoutAvoidAreaForRoot(const WSRect& rect, AvoidArea& avoidArea)
98 {
99 auto display = DisplayManager::GetInstance().GetDisplayById(GetSessionProperty()->GetDisplayId());
100 if (display == nullptr) {
101 TLOGE(WmsLogTag::WMS_IMMS, "Failed to get display");
102 return;
103 }
104 sptr<CutoutInfo> cutoutInfo = display->GetCutoutInfo();
105 if (cutoutInfo == nullptr) {
106 TLOGI(WmsLogTag::WMS_IMMS, "There is no CutoutInfo");
107 return;
108 }
109 std::vector<DMRect> cutoutAreas = cutoutInfo->GetBoundingRects();
110 if (cutoutAreas.empty()) {
111 TLOGI(WmsLogTag::WMS_IMMS, "There is no cutoutAreas");
112 return;
113 }
114 for (auto& cutoutArea : cutoutAreas) {
115 WSRect cutoutAreaRect = {
116 cutoutArea.posX_, cutoutArea.posY_,
117 cutoutArea.width_, cutoutArea.height_
118 };
119 CalculateAvoidAreaRect(rect, cutoutAreaRect, avoidArea);
120 TLOGI(WmsLogTag::WMS_IMMS, "root scene %{public}s cutout %{public}s area %{public}s",
121 rect.ToString().c_str(), cutoutAreaRect.ToString().c_str(), avoidArea.ToString().c_str());
122 }
123 }
124
GetAINavigationBarAreaForRoot(const WSRect & rect,AvoidArea & avoidArea)125 void RootSceneSession::GetAINavigationBarAreaForRoot(const WSRect& rect, AvoidArea& avoidArea)
126 {
127 WSRect barArea;
128 if (specificCallback_ != nullptr && specificCallback_->onGetAINavigationBarArea_) {
129 barArea = specificCallback_->onGetAINavigationBarArea_(GetSessionProperty()->GetDisplayId());
130 }
131 CalculateAvoidAreaRect(rect, barArea, avoidArea);
132 TLOGI(WmsLogTag::WMS_IMMS, "root scene %{public}s AI bar %{public}s area %{public}s",
133 rect.ToString().c_str(), barArea.ToString().c_str(), avoidArea.ToString().c_str());
134 }
135
GetAvoidAreaByType(AvoidAreaType type,const WSRect & rect,int32_t apiVersion)136 AvoidArea RootSceneSession::GetAvoidAreaByType(AvoidAreaType type, const WSRect& rect, int32_t apiVersion)
137 {
138 auto task = [weakThis = wptr(this), type]() -> AvoidArea {
139 auto session = weakThis.promote();
140 if (!session) {
141 TLOGNE(WmsLogTag::WMS_IMMS, "session is null");
142 return {};
143 }
144
145 AvoidArea avoidArea;
146 WSRect sessionRect = session->GetSessionRect();
147 switch (type) {
148 case AvoidAreaType::TYPE_SYSTEM: {
149 session->GetSystemAvoidAreaForRoot(sessionRect, avoidArea);
150 return avoidArea;
151 }
152 case AvoidAreaType::TYPE_CUTOUT: {
153 session->GetCutoutAvoidAreaForRoot(sessionRect, avoidArea);
154 return avoidArea;
155 }
156 case AvoidAreaType::TYPE_SYSTEM_GESTURE: {
157 return avoidArea;
158 }
159 case AvoidAreaType::TYPE_KEYBOARD: {
160 session->GetKeyboardAvoidAreaForRoot(sessionRect, avoidArea);
161 return avoidArea;
162 }
163 case AvoidAreaType::TYPE_NAVIGATION_INDICATOR: {
164 session->GetAINavigationBarAreaForRoot(sessionRect, avoidArea);
165 return avoidArea;
166 }
167 default: {
168 TLOGNE(WmsLogTag::WMS_IMMS, "cannot find type %{public}u, id %{public}d",
169 type, session->GetPersistentId());
170 return avoidArea;
171 }
172 }
173 };
174 return PostSyncTask(task, __func__);
175 }
176
SetRootSessionRect(const WSRect & rect)177 void RootSceneSession::SetRootSessionRect(const WSRect& rect)
178 {
179 if (!rect.IsInvalid() && winRect_ != rect) {
180 winRect_ = rect;
181 TLOGI(WmsLogTag::WMS_IMMS, "root session update rect: %{public}s", winRect_.ToString().c_str());
182 if (specificCallback_ != nullptr && specificCallback_->onUpdateAvoidArea_) {
183 specificCallback_->onUpdateAvoidArea_(GetPersistentId());
184 }
185 }
186 }
187
UpdateAvoidArea(const sptr<AvoidArea> & avoidArea,AvoidAreaType type)188 WSError RootSceneSession::UpdateAvoidArea(const sptr<AvoidArea>& avoidArea, AvoidAreaType type)
189 {
190 if (specificCallback_ == nullptr || specificCallback_->onNotifyAvoidAreaChange_ == nullptr) {
191 TLOGE(WmsLogTag::WMS_IMMS, "callback is nullptr");
192 return WSError::WS_ERROR_NULLPTR;
193 }
194 specificCallback_->onNotifyAvoidAreaChange_(avoidArea, type);
195 return WSError::WS_OK;
196 }
197 } // namespace OHOS::Rosen
198