• 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 constexpr uint64_t FLOATING_BALL_CLICK_INTERVAL = 5000;
32 const std::string FB_CLICK_EVENT = "click";
33 
SystemSession(const SessionInfo & info,const sptr<SpecificSessionCallback> & specificCallback)34 SystemSession::SystemSession(const SessionInfo& info, const sptr<SpecificSessionCallback>& specificCallback)
35     : SceneSession(info, specificCallback)
36 {
37     TLOGD(WmsLogTag::WMS_LIFE, "Create");
38     pcFoldScreenController_ = sptr<PcFoldScreenController>::MakeSptr(wptr(this), GetPersistentId());
39     moveDragController_ = sptr<MoveDragController>::MakeSptr(GetPersistentId(), GetWindowType());
40     if (specificCallback != nullptr &&
41         specificCallback->onWindowInputPidChangeCallback_ != nullptr) {
42         moveDragController_->SetNotifyWindowPidChangeCallback(specificCallback_->onWindowInputPidChangeCallback_);
43     }
44     SetMoveDragCallback();
45 }
46 
~SystemSession()47 SystemSession::~SystemSession()
48 {
49     TLOGD(WmsLogTag::WMS_LIFE, "id: %{public}d", GetPersistentId());
50 }
51 
UpdateCameraWindowStatus(bool isShowing)52 void SystemSession::UpdateCameraWindowStatus(bool isShowing)
53 {
54     if (specificCallback_ == nullptr) {
55         return;
56     }
57     if (GetWindowType() == WindowType::WINDOW_TYPE_FLOAT_CAMERA) {
58         if (!specificCallback_->onCameraFloatSessionChange_) {
59             return;
60         }
61         TLOGI(WmsLogTag::WMS_SYSTEM, "CameraFloat status: %{public}d, id: %{public}d", isShowing, GetPersistentId());
62         specificCallback_->onCameraFloatSessionChange_(GetSessionProperty()->GetAccessTokenId(), isShowing);
63     } else if (GetWindowType() == WindowType::WINDOW_TYPE_PIP && GetWindowMode() == WindowMode::WINDOW_MODE_PIP) {
64         if (!specificCallback_->onCameraSessionChange_) {
65             return;
66         }
67         auto pipType = GetPiPTemplateInfo().pipTemplateType;
68         if (pipType == static_cast<uint32_t>(PiPTemplateType::VIDEO_CALL) ||
69             pipType == static_cast<uint32_t>(PiPTemplateType::VIDEO_MEETING)) {
70             TLOGI(WmsLogTag::WMS_SYSTEM, "PiPWindow status: %{public}d, id: %{public}d", isShowing, GetPersistentId());
71             specificCallback_->onCameraSessionChange_(GetSessionProperty()->GetAccessTokenId(), isShowing);
72         }
73     } else {
74         TLOGI(WmsLogTag::WMS_SYSTEM, "Skip window type, isShowing: %{public}d", isShowing);
75     }
76 }
77 
Show(sptr<WindowSessionProperty> property)78 WSError SystemSession::Show(sptr<WindowSessionProperty> property)
79 {
80     if (!CheckPermissionWithPropertyAnimation(property)) {
81         return WSError::WS_ERROR_NOT_SYSTEM_APP;
82     }
83     auto type = GetWindowType();
84     if (((type == WindowType::WINDOW_TYPE_TOAST) || (type == WindowType::WINDOW_TYPE_FLOAT)) &&
85         !SessionPermission::IsSystemCalling()) {
86         auto parentSession = GetParentSession();
87         if (parentSession == nullptr) {
88             WLOGFW("parent session is null");
89             return WSError::WS_ERROR_INVALID_PARENT;
90         }
91         if ((type == WindowType::WINDOW_TYPE_TOAST) && !parentSession->IsSessionForeground()) {
92             WLOGFW("parent session is not in foreground");
93             return WSError::WS_ERROR_INVALID_OPERATION;
94         }
95     }
96     PostTask([weakThis = wptr(this), property]() {
97         auto session = weakThis.promote();
98         if (!session) {
99             WLOGFE("session is null");
100             return WSError::WS_ERROR_DESTROYED_OBJECT;
101         }
102         TLOGI(WmsLogTag::WMS_LIFE, "Show session, id: %{public}d", session->GetPersistentId());
103         // use property from client
104         if (property && property->GetAnimationFlag() == static_cast<uint32_t>(WindowAnimation::CUSTOM)) {
105             session->GetSessionProperty()->SetAnimationFlag(static_cast<uint32_t>(WindowAnimation::CUSTOM));
106             session->NotifyIsCustomAnimationPlaying(true);
107         }
108         session->UpdateCameraWindowStatus(true);
109         session->UpdatePiPWindowStateChanged(true);
110         auto ret = session->SceneSession::Foreground(property);
111         return ret;
112     }, "Show");
113     return WSError::WS_OK;
114 }
115 
Hide()116 WSError SystemSession::Hide()
117 {
118     if (!CheckPermissionWithPropertyAnimation(GetSessionProperty())) {
119         return WSError::WS_ERROR_NOT_SYSTEM_APP;
120     }
121     auto type = GetWindowType();
122     if (NeedSystemPermission(type)) {
123         // Do not need to verify the permission to hide the input method status bar.
124         if (!SessionPermission::IsSystemCalling() && type != WindowType::WINDOW_TYPE_INPUT_METHOD_STATUS_BAR) {
125             TLOGE(WmsLogTag::WMS_LIFE, "Hide permission denied id: %{public}d type:%{public}u",
126                 GetPersistentId(), type);
127             return WSError::WS_ERROR_INVALID_PERMISSION;
128         }
129     }
130     PostTask([weakThis = wptr(this)]() {
131         auto session = weakThis.promote();
132         if (!session) {
133             TLOGE(WmsLogTag::WMS_LIFE, "session is null");
134             return WSError::WS_ERROR_DESTROYED_OBJECT;
135         }
136         TLOGI(WmsLogTag::WMS_LIFE, "Hide session, id: %{public}d", session->GetPersistentId());
137         auto ret = session->SetActive(false);
138         if (ret != WSError::WS_OK) {
139             return ret;
140         }
141         // background will remove surfaceNode, custom not execute
142         // not animation playing when already background; inactive may be animation playing
143         auto sessionProperty = session->GetSessionProperty();
144         if (sessionProperty &&
145             sessionProperty->GetAnimationFlag() == static_cast<uint32_t>(WindowAnimation::CUSTOM)) {
146             session->NotifyIsCustomAnimationPlaying(true);
147             return WSError::WS_OK;
148         }
149         session->UpdateCameraWindowStatus(false);
150         session->UpdatePiPWindowStateChanged(false);
151         ret = session->SceneSession::Background();
152         return ret;
153     }, "Hide");
154     return WSError::WS_OK;
155 }
156 
Disconnect(bool isFromClient,const std::string & identityToken)157 WSError SystemSession::Disconnect(bool isFromClient, const std::string& identityToken)
158 {
159     PostTask([weakThis = wptr(this), isFromClient]() {
160         auto session = weakThis.promote();
161         if (!session) {
162             TLOGE(WmsLogTag::WMS_LIFE, "session is null");
163             return WSError::WS_ERROR_DESTROYED_OBJECT;
164         }
165         TLOGI(WmsLogTag::WMS_LIFE, "Disconnect session, id: %{public}d", session->GetPersistentId());
166         session->SceneSession::Disconnect(isFromClient);
167         session->UpdateCameraWindowStatus(false);
168         session->UpdatePiPWindowStateChanged(false);
169         return WSError::WS_OK;
170     }, "Disconnect");
171     return WSError::WS_OK;
172 }
173 
ProcessPointDownSession(int32_t posX,int32_t posY)174 WSError SystemSession::ProcessPointDownSession(int32_t posX, int32_t posY)
175 {
176     const auto& id = GetPersistentId();
177     const auto& type = GetWindowType();
178     auto parentSession = GetParentSession();
179     if (parentSession && parentSession->CheckDialogOnForeground()) {
180         WLOGFI("Parent has dialog foreground, id: %{public}d, type: %{public}d", id, type);
181         parentSession->HandlePointDownDialog();
182         if (!IsTopDialog()) {
183             return WSError::WS_OK;
184         }
185     }
186     if (type == WindowType::WINDOW_TYPE_DIALOG) {
187         Session::ProcessClickModalWindowOutside(posX, posY);
188         auto sessionProperty = GetSessionProperty();
189         if (sessionProperty && sessionProperty->GetRaiseEnabled()) {
190             RaiseToAppTopForPointDown();
191         }
192     }
193     TLOGD(WmsLogTag::WMS_EVENT, "id:%{public}d, type:%{public}d", id, type);
194     auto ret = SceneSession::ProcessPointDownSession(posX, posY);
195     PresentFocusIfPointDown();
196     return ret;
197 }
198 
GetMissionId() const199 int32_t SystemSession::GetMissionId() const
200 {
201     auto parentSession = GetParentSession();
202     return parentSession != nullptr ? parentSession->GetPersistentId() : SceneSession::GetMissionId();
203 }
204 
TransferKeyEvent(const std::shared_ptr<MMI::KeyEvent> & keyEvent)205 WSError SystemSession::TransferKeyEvent(const std::shared_ptr<MMI::KeyEvent>& keyEvent)
206 {
207     if (!IsSessionValid()) {
208         return WSError::WS_ERROR_INVALID_SESSION;
209     }
210     if (keyEvent == nullptr) {
211         WLOGFE("KeyEvent is nullptr");
212         return WSError::WS_ERROR_NULLPTR;
213     }
214     if (GetWindowType() == WindowType::WINDOW_TYPE_DIALOG) {
215         if (keyEvent->GetKeyCode() == MMI::KeyEvent::KEYCODE_BACK) {
216             return WSError::WS_ERROR_INVALID_PERMISSION;
217         }
218         auto parentSession = GetParentSession();
219         if (parentSession && parentSession->CheckDialogOnForeground() &&
220             !IsTopDialog()) {
221             return WSError::WS_ERROR_INVALID_PERMISSION;
222         }
223         if (!CheckKeyEventDispatch(keyEvent)) {
224             WLOGFW("Do not dispatch the key event.");
225             return WSError::WS_DO_NOTHING;
226         }
227     }
228 
229     WSError ret = Session::TransferKeyEvent(keyEvent);
230     return ret;
231 }
232 
ProcessBackEvent()233 WSError SystemSession::ProcessBackEvent()
234 {
235     if (GetWindowType() == WindowType::WINDOW_TYPE_DIALOG && !dialogSessionBackGestureEnabled_) {
236         TLOGI(WmsLogTag::WMS_DIALOG, "this is dialog, id: %{public}d", GetPersistentId());
237         return WSError::WS_OK;
238     }
239     return Session::ProcessBackEvent();
240 }
241 
NotifyClientToUpdateRect(const std::string & updateReason,std::shared_ptr<RSTransaction> rsTransaction)242 WSError SystemSession::NotifyClientToUpdateRect(const std::string& updateReason,
243     std::shared_ptr<RSTransaction> rsTransaction)
244 {
245     PostTask([weakThis = wptr(this), rsTransaction, updateReason]() {
246         auto session = weakThis.promote();
247         if (!session) {
248             WLOGFE("session is null");
249             return WSError::WS_ERROR_DESTROYED_OBJECT;
250         }
251         WSError ret = session->NotifyClientToUpdateRectTask(updateReason, rsTransaction);
252         if (ret != WSError::WS_OK) {
253             return ret;
254         }
255         if (session->specificCallback_ != nullptr && session->specificCallback_->onUpdateAvoidArea_ != nullptr) {
256             if (Session::IsScbCoreEnabled()) {
257                 session->dirtyFlags_ |= static_cast<uint32_t>(SessionUIDirtyFlag::AVOID_AREA);
258             } else {
259                 session->specificCallback_->onUpdateAvoidArea_(session->GetPersistentId());
260             }
261         }
262         return ret;
263     }, "NotifyClientToUpdateRect");
264     return WSError::WS_OK;
265 }
266 
CheckKeyEventDispatch(const std::shared_ptr<MMI::KeyEvent> & keyEvent) const267 bool SystemSession::CheckKeyEventDispatch(const std::shared_ptr<MMI::KeyEvent>& keyEvent) const
268 {
269     auto currentRect = GetSessionRect();
270     if (!GetRSVisible() || currentRect.width_ == 0 || currentRect.height_ == 0) {
271         WLOGE("Error size: [width: %{public}d, height: %{public}d], isRSVisible_: %{public}d,"
272             " persistentId: %{public}d",
273             currentRect.width_, currentRect.height_, GetRSVisible(), GetPersistentId());
274         return false;
275     }
276 
277     auto parentSession = GetParentSession();
278     if (parentSession == nullptr) {
279         WLOGFW("Dialog parent is null");
280         return false;
281     }
282     auto parentSessionState = parentSession->GetSessionState();
283     if ((parentSessionState != SessionState::STATE_FOREGROUND &&
284         parentSessionState != SessionState::STATE_ACTIVE) ||
285         (state_ != SessionState::STATE_FOREGROUND &&
286         state_ != SessionState::STATE_ACTIVE)) {
287         TLOGE(WmsLogTag::WMS_DIALOG, "Dialog's parent info : [persistentId: %{publicd}d, state:%{public}d];"
288             "Dialog info:[persistentId: %{publicd}d, state:%{public}d]",
289             parentSession->GetPersistentId(), parentSessionState, GetPersistentId(), GetSessionState());
290         return false;
291     }
292     return true;
293 }
294 
NeedSystemPermission(WindowType type)295 bool SystemSession::NeedSystemPermission(WindowType type)
296 {
297     return !(type == WindowType::WINDOW_TYPE_SCENE_BOARD || type == WindowType::WINDOW_TYPE_SYSTEM_FLOAT ||
298         type == WindowType::WINDOW_TYPE_SYSTEM_SUB_WINDOW || type == WindowType::WINDOW_TYPE_TOAST ||
299         type == WindowType::WINDOW_TYPE_DRAGGING_EFFECT || type == WindowType::WINDOW_TYPE_APP_LAUNCHING ||
300         type == WindowType::WINDOW_TYPE_PIP || type == WindowType::WINDOW_TYPE_FLOAT ||
301         type == WindowType::WINDOW_TYPE_FB);
302 }
303 
CheckPointerEventDispatch(const std::shared_ptr<MMI::PointerEvent> & pointerEvent) const304 bool SystemSession::CheckPointerEventDispatch(const std::shared_ptr<MMI::PointerEvent>& pointerEvent) const
305 {
306     auto sessionState = GetSessionState();
307     int32_t action = pointerEvent->GetPointerAction();
308     auto isPC = systemConfig_.IsPcWindow();
309     bool isDialog = WindowHelper::IsDialogWindow(GetWindowType());
310     if (isPC && isDialog && sessionState != SessionState::STATE_FOREGROUND &&
311         sessionState != SessionState::STATE_ACTIVE &&
312         action != MMI::PointerEvent::POINTER_ACTION_LEAVE_WINDOW) {
313         WLOGFW("false, Current Session Info: [persistentId: %{public}d, "
314             "state: %{public}d, action:%{public}d]", GetPersistentId(), GetSessionState(), action);
315         return false;
316     }
317     return true;
318 }
319 
UpdatePointerArea(const WSRect & rect)320 void SystemSession::UpdatePointerArea(const WSRect& rect)
321 {
322     auto property = GetSessionProperty();
323     if (!(property->IsDecorEnable() && GetWindowMode() == WindowMode::WINDOW_MODE_FLOATING)) {
324         return;
325     }
326     Session::UpdatePointerArea(rect);
327 }
328 
RectCheck(uint32_t curWidth,uint32_t curHeight)329 void SystemSession::RectCheck(uint32_t curWidth, uint32_t curHeight)
330 {
331     uint32_t minWidth = MIN_SYSTEM_WINDOW_WIDTH;
332     uint32_t minHeight = MIN_SYSTEM_WINDOW_HEIGHT;
333     uint32_t maxFloatingWindowSize = GetSystemConfig().maxFloatingWindowSize_;
334     RectSizeCheckProcess(curWidth, curHeight, minWidth, minHeight, maxFloatingWindowSize);
335 }
336 
IsVisibleForeground() const337 bool SystemSession::IsVisibleForeground() const
338 {
339     if (GetWindowType() == WindowType::WINDOW_TYPE_DIALOG &&
340         parentSession_ && WindowHelper::IsMainWindow(parentSession_->GetWindowType())) {
341         return parentSession_->IsVisibleForeground() && Session::IsVisibleForeground();
342     }
343     return Session::IsVisibleForeground();
344 }
345 
IsVisibleNotBackground() const346 bool SystemSession::IsVisibleNotBackground() const
347 {
348     if (GetWindowType() == WindowType::WINDOW_TYPE_DIALOG &&
349         parentSession_ && WindowHelper::IsMainWindow(parentSession_->GetWindowType())) {
350         return parentSession_->IsVisibleNotBackground() && Session::IsVisibleNotBackground();
351     }
352     return Session::IsVisibleNotBackground();
353 }
354 
SetDialogSessionBackGestureEnabled(bool isEnabled)355 WSError SystemSession::SetDialogSessionBackGestureEnabled(bool isEnabled)
356 {
357     return PostSyncTask([weakThis = wptr(this), isEnabled]() {
358         auto session = weakThis.promote();
359         if (!session) {
360             WLOGFE("session is null");
361             return WSError::WS_ERROR_DESTROYED_OBJECT;
362         }
363         WindowType windowType = session->GetWindowType();
364         if (windowType != WindowType::WINDOW_TYPE_DIALOG) {
365             TLOGE(WmsLogTag::WMS_DIALOG, "windowType not support. WinId:%{public}u, WindowType:%{public}u",
366                 session->GetWindowId(), static_cast<uint32_t>(windowType));
367             return WSError::WS_ERROR_INVALID_CALLING;
368         }
369         session->dialogSessionBackGestureEnabled_ = isEnabled;
370         return WSError::WS_OK;
371     });
372 }
373 
UpdatePiPWindowStateChanged(bool isForeground)374 void SystemSession::UpdatePiPWindowStateChanged(bool isForeground)
375 {
376     if (specificCallback_ == nullptr || !specificCallback_->onPiPStateChange_) {
377         return;
378     }
379     if (GetWindowType() == WindowType::WINDOW_TYPE_PIP) {
380         TLOGI(WmsLogTag::WMS_PIP, "pip state changed, bundleName:%{public}s, state:%{public}d",
381             GetSessionInfo().bundleName_.c_str(), isForeground);
382         specificCallback_->onPiPStateChange_(GetSessionInfo().bundleName_, isForeground);
383     } else {
384         TLOGD(WmsLogTag::WMS_PIP, "skip type");
385     }
386 }
387 
GetSubWindowZLevel() const388 int32_t SystemSession::GetSubWindowZLevel() const
389 {
390     int32_t zLevel = 0;
391     auto sessionProperty = GetSessionProperty();
392     zLevel = sessionProperty->GetSubWindowZLevel();
393     return zLevel;
394 }
395 
UpdateFloatingBall(const FloatingBallTemplateInfo & fbTemplateInfo)396 WMError SystemSession::UpdateFloatingBall(const FloatingBallTemplateInfo& fbTemplateInfo)
397 {
398     if (!WindowHelper::IsFbWindow(GetWindowType())) {
399         return WMError::WM_DO_NOTHING;
400     }
401 
402     if (GetFbTemplateInfo().template_ == static_cast<uint32_t>(FloatingBallTemplate::STATIC)) {
403         TLOGE(WmsLogTag::WMS_SYSTEM, "Fb static template can't update");
404         return WMError::WM_ERROR_FB_UPDATE_STATIC_TEMPLATE_DENIED;
405     }
406 
407     if (GetFbTemplateInfo().template_ != 0 && GetFbTemplateInfo().template_ != fbTemplateInfo.template_) {
408         TLOGE(WmsLogTag::WMS_SYSTEM, "Fb template type can't update %{public}d, %{public}d",
409             GetFbTemplateInfo().template_, fbTemplateInfo.template_);
410         return WMError::WM_ERROR_FB_UPDATE_TEMPLATE_TYPE_DENIED;
411     }
412 
413     int32_t callingPid = IPCSkeleton::GetCallingPid();
414     auto task = [weakThis = wptr(this), fbTemplateInfo, callingPid, where = __func__] {
415         auto session = weakThis.promote();
416         if (!session) {
417             TLOGNE(WmsLogTag::WMS_SYSTEM, "%{public}s session is null", where);
418             return WMError::WM_ERROR_INVALID_OPERATION;
419         }
420         if (callingPid != session->GetCallingPid()) {
421             TLOGNW(WmsLogTag::WMS_SYSTEM, "%{public}s permission denied, not call by the same process", where);
422             return WMError::WM_ERROR_INVALID_CALLING;
423         }
424         TLOGNI(WmsLogTag::WMS_SYSTEM, "update template %{public}d", fbTemplateInfo.template_);
425         session->NotifyUpdateFloatingBall(fbTemplateInfo);
426         return WMError::WM_OK;
427     };
428     PostTask(std::move(task), __func__);
429     return WMError::WM_OK;
430 }
431 
StopFloatingBall()432 WSError SystemSession::StopFloatingBall()
433 {
434     TLOGI(WmsLogTag::WMS_SYSTEM, "session StopFloatingBall");
435     if (!WindowHelper::IsFbWindow(GetWindowType())) {
436         return WSError::WS_DO_NOTHING;
437     }
438     int32_t callingPid = IPCSkeleton::GetCallingPid();
439     auto task = [weakThis = wptr(this), callingPid, where = __func__] {
440         auto session = weakThis.promote();
441         if (!session) {
442             TLOGNE(WmsLogTag::WMS_SYSTEM, "%{public}s session is null", where);
443             return WSError::WS_ERROR_INVALID_OPERATION;
444         }
445         if (callingPid != session->GetCallingPid()) {
446             TLOGNW(WmsLogTag::WMS_SYSTEM, "%{public}s permission denied, not call by the same process", where);
447             return WSError::WS_ERROR_INVALID_CALLING;
448         }
449         session->NotifyStopFloatingBall();
450         return WSError::WS_OK;
451     };
452     PostTask(std::move(task), __func__);
453     return WSError::WS_OK;
454 }
455 
GetFloatingBallWindowId(uint32_t & windowId)456 WMError SystemSession::GetFloatingBallWindowId(uint32_t& windowId)
457 {
458     TLOGI(WmsLogTag::WMS_SYSTEM, "session GetFloatingBallWindowId");
459     if (!WindowHelper::IsFbWindow(GetWindowType())) {
460         return WMError::WM_DO_NOTHING;
461     }
462     int32_t callingPid = IPCSkeleton::GetCallingPid();
463     return PostSyncTask([weakThis = wptr(this), callingPid, &windowId, where = __func__] {
464         auto session = weakThis.promote();
465         if (!session) {
466             TLOGNE(WmsLogTag::WMS_SYSTEM, "%{public}s session is null", where);
467             return WMError::WM_ERROR_INVALID_OPERATION;
468         }
469         if (callingPid != session->GetCallingPid()) {
470             TLOGNW(WmsLogTag::WMS_SYSTEM, "%{public}s permission denied, not call by the same process", where);
471             return WMError::WM_ERROR_INVALID_CALLING;
472         }
473         windowId = session->GetFbWindowId();
474         TLOGND(WmsLogTag::WMS_SYSTEM, "%{public}s mode: %{public}u", where, windowId);
475         return WMError::WM_OK;
476     }, __func__);
477 }
478 
RestoreFbMainWindow(const std::shared_ptr<AAFwk::Want> & want)479 WMError SystemSession::RestoreFbMainWindow(const std::shared_ptr<AAFwk::Want>& want)
480 {
481     if (!WindowHelper::IsFbWindow(GetWindowType())) {
482         return WMError::WM_DO_NOTHING;
483     }
484     if (!SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_FLOATING_BALL)) {
485         TLOGNE(WmsLogTag::WMS_SYSTEM, "Check floating ball permission failed");
486         return WMError::WM_ERROR_INVALID_PERMISSION;
487     }
488     int32_t callingPid = IPCSkeleton::GetCallingPid();
489     return PostSyncTask([weakThis = wptr(this), &want, callingPid, where = __func__]() {
490         auto session = weakThis.promote();
491         if (!session) {
492             TLOGNE(WmsLogTag::WMS_SYSTEM, "%{public}s session is null", where);
493             return WMError::WM_ERROR_INVALID_OPERATION;
494         }
495         if (callingPid != session->GetCallingPid()) {
496             TLOGNE(WmsLogTag::WMS_SYSTEM, "%{public}s permission denied, not call by the same process", where);
497             return WMError::WM_ERROR_INVALID_CALLING;
498         }
499         if (session->GetSessionInfo().bundleName_ != want->GetBundle()) {
500             TLOGNE(WmsLogTag::WMS_SYSTEM, "Session bundle %{public}s is not want bundle %{public}s",
501                 session->GetSessionInfo().bundleName_.c_str(), want->GetBundle().c_str());
502             return WMError::WM_ERROR_FB_RESTORE_MAIN_WINDOW_FAILED;
503         }
504         uint64_t nowTime = static_cast<uint64_t>(std::chrono::duration_cast<std::chrono::milliseconds>(
505             std::chrono::system_clock::now().time_since_epoch()).count());
506         {
507             std::lock_guard<std::mutex> lock(session->fbClickMutex_);
508             if (nowTime - session->fbClickTime_ >= FLOATING_BALL_CLICK_INTERVAL) {
509                 TLOGNW(WmsLogTag::WMS_SYSTEM, "%{public}s Start time is too long from click, deny", where);
510                 return WMError::WM_ERROR_FB_RESTORE_MAIN_WINDOW_FAILED;
511             }
512             session->fbClickTime_ = 0;
513         }
514         TLOGNI(WmsLogTag::WMS_SYSTEM,
515             "%{public}s restore window, bundle %{public}s, ability %{public}s, session bundle %{public}s",
516             where, want->GetBundle().c_str(), want->GetElement().GetAbilityName().c_str(),
517             session->GetSessionInfo().bundleName_.c_str());
518         session->NotifyRestoreFloatingBallMainWindow(want);
519         return WMError::WM_OK;
520     });
521 }
522 
NotifyUpdateFloatingBall(const FloatingBallTemplateInfo & fbTemplateInfo)523 void SystemSession::NotifyUpdateFloatingBall(const FloatingBallTemplateInfo& fbTemplateInfo)
524 {
525     PostTask([weakThis = wptr(this), fbTemplateInfo, where = __func__] {
526         auto session = weakThis.promote();
527         if (!session) {
528             TLOGNE(WmsLogTag::WMS_LAYOUT, "%{public}s session is null", where);
529             return;
530         }
531         session->SetFbTemplateInfo(fbTemplateInfo);
532         if (session->updateFloatingBallFunc_) {
533             session->updateFloatingBallFunc_(fbTemplateInfo);
534         }
535     }, __func__);
536 }
537 
NotifyStopFloatingBall()538 void SystemSession::NotifyStopFloatingBall()
539 {
540     TLOGI(WmsLogTag::DEFAULT, "Notify StopFloatingBall");
541     PostTask([weakThis = wptr(this), where = __func__] {
542         auto session = weakThis.promote();
543         if (!session) {
544             TLOGNE(WmsLogTag::WMS_SYSTEM, "%{public}s session is null", where);
545             return;
546         }
547         if (session->stopFloatingBallFunc_) {
548             TLOGI(WmsLogTag::WMS_SYSTEM, "StopFloatingBall Func");
549             session->stopFloatingBallFunc_();
550         } else {
551             TLOGW(WmsLogTag::WMS_SYSTEM, "%{public}s StopFloatingBall Func is null", where);
552             session->needStopFb_ = true;
553         }
554     }, __func__);
555 }
556 
NotifyRestoreFloatingBallMainWindow(const std::shared_ptr<AAFwk::Want> & want)557 void SystemSession::NotifyRestoreFloatingBallMainWindow(const std::shared_ptr<AAFwk::Want>& want)
558 {
559     TLOGI(WmsLogTag::WMS_SYSTEM, "Notify RestoreFloatingBallMainwindow");
560     PostTask([weakThis = wptr(this), want, where = __func__] {
561         auto session = weakThis.promote();
562         if (!session) {
563             TLOGNE(WmsLogTag::WMS_SYSTEM, "%{public}s session is null", where);
564             return;
565         }
566         if (session->restoreFloatingBallMainWindowFunc_) {
567             TLOGI(WmsLogTag::WMS_SYSTEM, "restoreFlotingBallMainwindowFunc");
568             session->restoreFloatingBallMainWindowFunc_(want);
569         }  else {
570             TLOGW(WmsLogTag::WMS_SYSTEM, "%{public}s restoreFlotingBallMainwindowFunc Func is null", where);
571             session->fbWant_= want;
572         }
573     }, __func__);
574 }
575 
SendFbActionEvent(const std::string & action)576 WSError SystemSession::SendFbActionEvent(const std::string& action)
577 {
578     TLOGI(WmsLogTag::WMS_SYSTEM, "action: %{public}s", action.c_str());
579     if (!sessionStage_) {
580         return WSError::WS_ERROR_NULLPTR;
581     }
582     if (action == FB_CLICK_EVENT) {
583         fbClickTime_ = static_cast<uint64_t>(std::chrono::duration_cast<std::chrono::milliseconds>(
584             std::chrono::system_clock::now().time_since_epoch()).count());
585     }
586     return sessionStage_->SendFbActionEvent(action);
587 }
588 
GetFbTemplateInfo() const589 FloatingBallTemplateInfo SystemSession::GetFbTemplateInfo() const
590 {
591     return fbTemplateInfo_;
592 }
593 
SetFbTemplateInfo(const FloatingBallTemplateInfo & fbTemplateInfo)594 void SystemSession::SetFbTemplateInfo(const FloatingBallTemplateInfo& fbTemplateInfo)
595 {
596     fbTemplateInfo_ = fbTemplateInfo;
597 }
598 
GetFbWindowId() const599 uint32_t SystemSession::GetFbWindowId() const
600 {
601     uint32_t windowId = 0;
602     if (getFbPanelWindowIdFunc_) {
603         getFbPanelWindowIdFunc_(windowId);
604     }
605     TLOGI(WmsLogTag::WMS_SYSTEM, "Get fb window Id %{public}d", windowId);
606     return windowId;
607 }
608 
SetFloatingBallUpdateCallback(NotifyUpdateFloatingBallFunc && func)609 void SystemSession::SetFloatingBallUpdateCallback(NotifyUpdateFloatingBallFunc&& func)
610 {
611     PostTask([weakThis = wptr(this), func = std::move(func), where = __func__] {
612         auto session = weakThis.promote();
613         if (!session || !func) {
614             TLOGNE(WmsLogTag::WMS_SYSTEM, "%{public}s update floating ball id is null", where);
615             return;
616         }
617         session->updateFloatingBallFunc_ = std::move(func);
618         session->updateFloatingBallFunc_(session->GetFbTemplateInfo());
619     }, __func__);
620 }
621 
SetFloatingBallStopCallback(NotifyStopFloatingBallFunc && func)622 void SystemSession::SetFloatingBallStopCallback(NotifyStopFloatingBallFunc&& func)
623 {
624     PostTask([weakThis = wptr(this), func = std::move(func), where = __func__] {
625         TLOGI(WmsLogTag::WMS_SYSTEM, "Register Callback StopFloatingBall");
626         auto session = weakThis.promote();
627         if (!session || !func) {
628             TLOGNE(WmsLogTag::WMS_SYSTEM, "%{public}s stop floating ball id is null", where);
629             return;
630         }
631         session->stopFloatingBallFunc_ = std::move(func);
632         if (session->needStopFb_) {
633             TLOGW(WmsLogTag::WMS_SYSTEM, "StopFloatingBall when register callBack");
634             session->stopFloatingBallFunc_();
635             session->needStopFb_ = false;
636         }
637     }, __func__);
638 }
639 
SetFloatingBallRestoreMainWindowCallback(NotifyRestoreFloatingBallMainWindowFunc && func)640 void SystemSession::SetFloatingBallRestoreMainWindowCallback(NotifyRestoreFloatingBallMainWindowFunc&& func)
641 {
642     PostTask([weakThis = wptr(this), func = std::move(func), where = __func__] {
643         TLOGI(WmsLogTag::WMS_SYSTEM, "Register Callback RestoreFloatingBallMainWindow");
644         auto session = weakThis.promote();
645         if (!session || !func) {
646             TLOGNE(WmsLogTag::WMS_SYSTEM, "%{public}s stop floating ball id is null", where);
647             return;
648         }
649         session->restoreFloatingBallMainWindowFunc_ = std::move(func);
650         if (session->fbWant_ != nullptr) {
651             TLOGW(WmsLogTag::WMS_SYSTEM, "RestoreFbMainWindow when register callBack");
652             session->restoreFloatingBallMainWindowFunc_(session->fbWant_);
653             session->fbWant_ = nullptr;
654         }
655     }, __func__);
656 }
657 
RegisterGetFbPanelWindowIdFunc(GetFbPanelWindowIdFunc && callback)658 void SystemSession::RegisterGetFbPanelWindowIdFunc(GetFbPanelWindowIdFunc&& callback)
659 {
660     getFbPanelWindowIdFunc_ = std::move(callback);
661 }
662 } // namespace OHOS::Rosen
663