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