• 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/system_session.h"
17 
18 #include "common/include/session_permission.h"
19 #include "key_event.h"
20 #include "window_helper.h"
21 #include "window_manager_hilog.h"
22 #include "pointer_event.h"
23 
24 namespace OHOS::Rosen {
25 namespace {
26 constexpr HiviewDFX::HiLogLabel LABEL = { LOG_CORE, HILOG_DOMAIN_WINDOW, "SystemSession" };
27 } // namespace
28 
29 constexpr uint32_t MIN_SYSTEM_WINDOW_WIDTH = 5;
30 constexpr uint32_t MIN_SYSTEM_WINDOW_HEIGHT = 5;
31 
SystemSession(const SessionInfo & info,const sptr<SpecificSessionCallback> & specificCallback)32 SystemSession::SystemSession(const SessionInfo& info, const sptr<SpecificSessionCallback>& specificCallback)
33     : SceneSession(info, specificCallback)
34 {
35     TLOGD(WmsLogTag::WMS_LIFE, "Create");
36     pcFoldScreenController_ = sptr<PcFoldScreenController>::MakeSptr(wptr(this), GetPersistentId());
37     moveDragController_ = sptr<MoveDragController>::MakeSptr(GetPersistentId(), GetWindowType());
38     if (specificCallback != nullptr &&
39         specificCallback->onWindowInputPidChangeCallback_ != nullptr) {
40         moveDragController_->SetNotifyWindowPidChangeCallback(specificCallback_->onWindowInputPidChangeCallback_);
41     }
42     SetMoveDragCallback();
43 }
44 
~SystemSession()45 SystemSession::~SystemSession()
46 {
47     TLOGD(WmsLogTag::WMS_LIFE, "id: %{public}d", GetPersistentId());
48 }
49 
UpdateCameraWindowStatus(bool isShowing)50 void SystemSession::UpdateCameraWindowStatus(bool isShowing)
51 {
52     if (specificCallback_ == nullptr) {
53         return;
54     }
55     if (GetWindowType() == WindowType::WINDOW_TYPE_FLOAT_CAMERA) {
56         if (!specificCallback_->onCameraFloatSessionChange_) {
57             return;
58         }
59         TLOGI(WmsLogTag::WMS_SYSTEM, "CameraFloat status: %{public}d, id: %{public}d", isShowing, GetPersistentId());
60         specificCallback_->onCameraFloatSessionChange_(GetSessionProperty()->GetAccessTokenId(), isShowing);
61     } else if (GetWindowType() == WindowType::WINDOW_TYPE_PIP && GetWindowMode() == WindowMode::WINDOW_MODE_PIP) {
62         if (!specificCallback_->onCameraSessionChange_) {
63             return;
64         }
65         auto pipType = GetPiPTemplateInfo().pipTemplateType;
66         if (pipType == static_cast<uint32_t>(PiPTemplateType::VIDEO_CALL) ||
67             pipType == static_cast<uint32_t>(PiPTemplateType::VIDEO_MEETING)) {
68             TLOGI(WmsLogTag::WMS_SYSTEM, "PiPWindow status: %{public}d, id: %{public}d", isShowing, GetPersistentId());
69             specificCallback_->onCameraSessionChange_(GetSessionProperty()->GetAccessTokenId(), isShowing);
70         }
71     } else {
72         TLOGI(WmsLogTag::WMS_SYSTEM, "Skip window type, isShowing: %{public}d", isShowing);
73     }
74 }
75 
Show(sptr<WindowSessionProperty> property)76 WSError SystemSession::Show(sptr<WindowSessionProperty> property)
77 {
78     if (!CheckPermissionWithPropertyAnimation(property)) {
79         return WSError::WS_ERROR_NOT_SYSTEM_APP;
80     }
81     auto type = GetWindowType();
82     if (((type == WindowType::WINDOW_TYPE_TOAST) || (type == WindowType::WINDOW_TYPE_FLOAT)) &&
83         !SessionPermission::IsSystemCalling()) {
84         auto parentSession = GetParentSession();
85         if (parentSession == nullptr) {
86             WLOGFW("parent session is null");
87             return WSError::WS_ERROR_INVALID_PARENT;
88         }
89         if ((type == WindowType::WINDOW_TYPE_TOAST) && !parentSession->IsSessionForeground()) {
90             WLOGFW("parent session is not in foreground");
91             return WSError::WS_ERROR_INVALID_OPERATION;
92         }
93     }
94     PostTask([weakThis = wptr(this), property]() {
95         auto session = weakThis.promote();
96         if (!session) {
97             WLOGFE("session is null");
98             return WSError::WS_ERROR_DESTROYED_OBJECT;
99         }
100         TLOGI(WmsLogTag::WMS_LIFE, "Show session, id: %{public}d", session->GetPersistentId());
101         // use property from client
102         if (property && property->GetAnimationFlag() == static_cast<uint32_t>(WindowAnimation::CUSTOM)) {
103             session->GetSessionProperty()->SetAnimationFlag(static_cast<uint32_t>(WindowAnimation::CUSTOM));
104             session->NotifyIsCustomAnimationPlaying(true);
105         }
106         session->UpdateCameraWindowStatus(true);
107         session->UpdatePiPWindowStateChanged(true);
108         auto ret = session->SceneSession::Foreground(property);
109         return ret;
110     }, "Show");
111     return WSError::WS_OK;
112 }
113 
Hide()114 WSError SystemSession::Hide()
115 {
116     if (!CheckPermissionWithPropertyAnimation(GetSessionProperty())) {
117         return WSError::WS_ERROR_NOT_SYSTEM_APP;
118     }
119     auto type = GetWindowType();
120     if (NeedSystemPermission(type)) {
121         // Do not need to verify the permission to hide the input method status bar.
122         if (!SessionPermission::IsSystemCalling() && type != WindowType::WINDOW_TYPE_INPUT_METHOD_STATUS_BAR) {
123             TLOGE(WmsLogTag::WMS_LIFE, "Hide permission denied id: %{public}d type:%{public}u",
124                 GetPersistentId(), type);
125             return WSError::WS_ERROR_INVALID_PERMISSION;
126         }
127     }
128     PostTask([weakThis = wptr(this)]() {
129         auto session = weakThis.promote();
130         if (!session) {
131             TLOGE(WmsLogTag::WMS_LIFE, "session is null");
132             return WSError::WS_ERROR_DESTROYED_OBJECT;
133         }
134         TLOGI(WmsLogTag::WMS_LIFE, "Hide session, id: %{public}d", session->GetPersistentId());
135         auto ret = session->SetActive(false);
136         if (ret != WSError::WS_OK) {
137             return ret;
138         }
139         // background will remove surfaceNode, custom not execute
140         // not animation playing when already background; inactive may be animation playing
141         auto sessionProperty = session->GetSessionProperty();
142         if (sessionProperty &&
143             sessionProperty->GetAnimationFlag() == static_cast<uint32_t>(WindowAnimation::CUSTOM)) {
144             session->NotifyIsCustomAnimationPlaying(true);
145             return WSError::WS_OK;
146         }
147         session->UpdateCameraWindowStatus(false);
148         session->UpdatePiPWindowStateChanged(false);
149         ret = session->SceneSession::Background();
150         return ret;
151     }, "Hide");
152     return WSError::WS_OK;
153 }
154 
Disconnect(bool isFromClient,const std::string & identityToken)155 WSError SystemSession::Disconnect(bool isFromClient, const std::string& identityToken)
156 {
157     PostTask([weakThis = wptr(this), isFromClient]() {
158         auto session = weakThis.promote();
159         if (!session) {
160             TLOGE(WmsLogTag::WMS_LIFE, "session is null");
161             return WSError::WS_ERROR_DESTROYED_OBJECT;
162         }
163         TLOGI(WmsLogTag::WMS_LIFE, "Disconnect session, id: %{public}d", session->GetPersistentId());
164         session->SceneSession::Disconnect(isFromClient);
165         session->UpdateCameraWindowStatus(false);
166         session->UpdatePiPWindowStateChanged(false);
167         return WSError::WS_OK;
168     }, "Disconnect");
169     return WSError::WS_OK;
170 }
171 
ProcessPointDownSession(int32_t posX,int32_t posY)172 WSError SystemSession::ProcessPointDownSession(int32_t posX, int32_t posY)
173 {
174     const auto& id = GetPersistentId();
175     const auto& type = GetWindowType();
176     auto parentSession = GetParentSession();
177     if (parentSession && parentSession->CheckDialogOnForeground()) {
178         WLOGFI("Parent has dialog foreground, id: %{public}d, type: %{public}d", id, type);
179         parentSession->HandlePointDownDialog();
180         if (!IsTopDialog()) {
181             return WSError::WS_OK;
182         }
183     }
184     if (type == WindowType::WINDOW_TYPE_DIALOG) {
185         Session::ProcessClickModalWindowOutside(posX, posY);
186         auto sessionProperty = GetSessionProperty();
187         if (sessionProperty && sessionProperty->GetRaiseEnabled()) {
188             RaiseToAppTopForPointDown();
189         }
190     }
191     TLOGD(WmsLogTag::WMS_EVENT, "id:%{public}d, type:%{public}d", id, type);
192     PresentFocusIfPointDown();
193     return SceneSession::ProcessPointDownSession(posX, posY);
194 }
195 
GetMissionId() const196 int32_t SystemSession::GetMissionId() const
197 {
198     auto parentSession = GetParentSession();
199     return parentSession != nullptr ? parentSession->GetPersistentId() : SceneSession::GetMissionId();
200 }
201 
TransferKeyEvent(const std::shared_ptr<MMI::KeyEvent> & keyEvent)202 WSError SystemSession::TransferKeyEvent(const std::shared_ptr<MMI::KeyEvent>& keyEvent)
203 {
204     if (!IsSessionValid()) {
205         return WSError::WS_ERROR_INVALID_SESSION;
206     }
207     if (keyEvent == nullptr) {
208         WLOGFE("KeyEvent is nullptr");
209         return WSError::WS_ERROR_NULLPTR;
210     }
211     if (GetWindowType() == WindowType::WINDOW_TYPE_DIALOG) {
212         if (keyEvent->GetKeyCode() == MMI::KeyEvent::KEYCODE_BACK) {
213             return WSError::WS_ERROR_INVALID_PERMISSION;
214         }
215         auto parentSession = GetParentSession();
216         if (parentSession && parentSession->CheckDialogOnForeground() &&
217             !IsTopDialog()) {
218             return WSError::WS_ERROR_INVALID_PERMISSION;
219         }
220         if (!CheckKeyEventDispatch(keyEvent)) {
221             WLOGFW("Do not dispatch the key event.");
222             return WSError::WS_DO_NOTHING;
223         }
224     }
225 
226     WSError ret = Session::TransferKeyEvent(keyEvent);
227     return ret;
228 }
229 
ProcessBackEvent()230 WSError SystemSession::ProcessBackEvent()
231 {
232     if (GetWindowType() == WindowType::WINDOW_TYPE_DIALOG && !dialogSessionBackGestureEnabled_) {
233         TLOGI(WmsLogTag::WMS_DIALOG, "this is dialog, id: %{public}d", GetPersistentId());
234         return WSError::WS_OK;
235     }
236     return Session::ProcessBackEvent();
237 }
238 
NotifyClientToUpdateRect(const std::string & updateReason,std::shared_ptr<RSTransaction> rsTransaction)239 WSError SystemSession::NotifyClientToUpdateRect(const std::string& updateReason,
240     std::shared_ptr<RSTransaction> rsTransaction)
241 {
242     PostTask([weakThis = wptr(this), rsTransaction, updateReason]() {
243         auto session = weakThis.promote();
244         if (!session) {
245             WLOGFE("session is null");
246             return WSError::WS_ERROR_DESTROYED_OBJECT;
247         }
248         WSError ret = session->NotifyClientToUpdateRectTask(updateReason, rsTransaction);
249         if (ret != WSError::WS_OK) {
250             return ret;
251         }
252         if (session->specificCallback_ != nullptr && session->specificCallback_->onUpdateAvoidArea_ != nullptr) {
253             if (Session::IsScbCoreEnabled()) {
254                 session->dirtyFlags_ |= static_cast<uint32_t>(SessionUIDirtyFlag::AVOID_AREA);
255             } else {
256                 session->specificCallback_->onUpdateAvoidArea_(session->GetPersistentId());
257             }
258         }
259         return ret;
260     }, "NotifyClientToUpdateRect");
261     return WSError::WS_OK;
262 }
263 
CheckKeyEventDispatch(const std::shared_ptr<MMI::KeyEvent> & keyEvent) const264 bool SystemSession::CheckKeyEventDispatch(const std::shared_ptr<MMI::KeyEvent>& keyEvent) const
265 {
266     auto currentRect = winRect_;
267     if (!GetRSVisible() || currentRect.width_ == 0 || currentRect.height_ == 0) {
268         WLOGE("Error size: [width: %{public}d, height: %{public}d], isRSVisible_: %{public}d,"
269             " persistentId: %{public}d",
270             currentRect.width_, currentRect.height_, GetRSVisible(), GetPersistentId());
271         return false;
272     }
273 
274     auto parentSession = GetParentSession();
275     if (parentSession == nullptr) {
276         WLOGFW("Dialog parent is null");
277         return false;
278     }
279     auto parentSessionState = parentSession->GetSessionState();
280     if ((parentSessionState != SessionState::STATE_FOREGROUND &&
281         parentSessionState != SessionState::STATE_ACTIVE) ||
282         (state_ != SessionState::STATE_FOREGROUND &&
283         state_ != SessionState::STATE_ACTIVE)) {
284         TLOGE(WmsLogTag::WMS_DIALOG, "Dialog's parent info : [persistentId: %{publicd}d, state:%{public}d];"
285             "Dialog info:[persistentId: %{publicd}d, state:%{public}d]",
286             parentSession->GetPersistentId(), parentSessionState, GetPersistentId(), GetSessionState());
287         return false;
288     }
289     return true;
290 }
291 
NeedSystemPermission(WindowType type)292 bool SystemSession::NeedSystemPermission(WindowType type)
293 {
294     return !(type == WindowType::WINDOW_TYPE_SCENE_BOARD || type == WindowType::WINDOW_TYPE_SYSTEM_FLOAT ||
295         type == WindowType::WINDOW_TYPE_SYSTEM_SUB_WINDOW || type == WindowType::WINDOW_TYPE_TOAST ||
296         type == WindowType::WINDOW_TYPE_DRAGGING_EFFECT || type == WindowType::WINDOW_TYPE_APP_LAUNCHING ||
297         type == WindowType::WINDOW_TYPE_PIP || type == WindowType::WINDOW_TYPE_FLOAT);
298 }
299 
CheckPointerEventDispatch(const std::shared_ptr<MMI::PointerEvent> & pointerEvent) const300 bool SystemSession::CheckPointerEventDispatch(const std::shared_ptr<MMI::PointerEvent>& pointerEvent) const
301 {
302     auto sessionState = GetSessionState();
303     int32_t action = pointerEvent->GetPointerAction();
304     auto isPC = systemConfig_.IsPcWindow();
305     bool isDialog = WindowHelper::IsDialogWindow(GetWindowType());
306     if (isPC && isDialog && sessionState != SessionState::STATE_FOREGROUND &&
307         sessionState != SessionState::STATE_ACTIVE &&
308         action != MMI::PointerEvent::POINTER_ACTION_LEAVE_WINDOW) {
309         WLOGFW("false, Current Session Info: [persistentId: %{public}d, "
310             "state: %{public}d, action:%{public}d]", GetPersistentId(), GetSessionState(), action);
311         return false;
312     }
313     return true;
314 }
315 
UpdatePointerArea(const WSRect & rect)316 void SystemSession::UpdatePointerArea(const WSRect& rect)
317 {
318     auto property = GetSessionProperty();
319     if (!(property->IsDecorEnable() && GetWindowMode() == WindowMode::WINDOW_MODE_FLOATING)) {
320         return;
321     }
322     Session::UpdatePointerArea(rect);
323 }
324 
RectCheck(uint32_t curWidth,uint32_t curHeight)325 void SystemSession::RectCheck(uint32_t curWidth, uint32_t curHeight)
326 {
327     uint32_t minWidth = MIN_SYSTEM_WINDOW_WIDTH;
328     uint32_t minHeight = MIN_SYSTEM_WINDOW_HEIGHT;
329     uint32_t maxFloatingWindowSize = GetSystemConfig().maxFloatingWindowSize_;
330     RectSizeCheckProcess(curWidth, curHeight, minWidth, minHeight, maxFloatingWindowSize);
331 }
332 
IsVisibleForeground() const333 bool SystemSession::IsVisibleForeground() const
334 {
335     if (GetWindowType() == WindowType::WINDOW_TYPE_DIALOG &&
336         parentSession_ && WindowHelper::IsMainWindow(parentSession_->GetWindowType())) {
337         return parentSession_->IsVisibleForeground() && Session::IsVisibleForeground();
338     }
339     return Session::IsVisibleForeground();
340 }
341 
SetDialogSessionBackGestureEnabled(bool isEnabled)342 WSError SystemSession::SetDialogSessionBackGestureEnabled(bool isEnabled)
343 {
344     return PostSyncTask([weakThis = wptr(this), isEnabled]() {
345         auto session = weakThis.promote();
346         if (!session) {
347             WLOGFE("session is null");
348             return WSError::WS_ERROR_DESTROYED_OBJECT;
349         }
350         WindowType windowType = session->GetWindowType();
351         if (windowType != WindowType::WINDOW_TYPE_DIALOG) {
352             TLOGE(WmsLogTag::WMS_DIALOG, "windowType not support. WinId:%{public}u, WindowType:%{public}u",
353                 session->GetWindowId(), static_cast<uint32_t>(windowType));
354             return WSError::WS_ERROR_INVALID_CALLING;
355         }
356         session->dialogSessionBackGestureEnabled_ = isEnabled;
357         return WSError::WS_OK;
358     });
359 }
360 
UpdatePiPWindowStateChanged(bool isForeground)361 void SystemSession::UpdatePiPWindowStateChanged(bool isForeground)
362 {
363     if (specificCallback_ == nullptr || !specificCallback_->onPiPStateChange_) {
364         return;
365     }
366     if (GetWindowType() == WindowType::WINDOW_TYPE_PIP) {
367         TLOGI(WmsLogTag::WMS_PIP, "pip state changed, bundleName:%{public}s, state:%{public}d",
368             GetSessionInfo().bundleName_.c_str(), isForeground);
369         specificCallback_->onPiPStateChange_(GetSessionInfo().bundleName_, isForeground);
370     } else {
371         TLOGD(WmsLogTag::WMS_PIP, "skip type");
372     }
373 }
374 
GetSubWindowZLevel() const375 int32_t SystemSession::GetSubWindowZLevel() const
376 {
377     int32_t zLevel = 0;
378     auto sessionProperty = GetSessionProperty();
379     zLevel = sessionProperty->GetSubWindowZLevel();
380     return zLevel;
381 }
382 } // namespace OHOS::Rosen
383