• 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 "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