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