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/scene_session.h"
17 #include <parameters.h>
18
19 #include <algorithm>
20 #include <hitrace_meter.h>
21 #ifdef IMF_ENABLE
22 #include <input_method_controller.h>
23 #endif // IMF_ENABLE
24 #include <ipc_skeleton.h>
25 #include <pointer_event.h>
26 #include <transaction/rs_transaction.h>
27 #include <ui/rs_surface_node.h>
28
29 #include "../../proxy/include/window_info.h"
30
31 #include "common/include/session_permission.h"
32 #include "interfaces/include/ws_common.h"
33 #include "pixel_map.h"
34 #include "pip_util.h"
35 #include "session/host/include/scene_persistent_storage.h"
36 #include "session/host/include/session_utils.h"
37 #include "display_manager.h"
38 #include "session_helper.h"
39 #include "window_helper.h"
40 #include "window_manager_hilog.h"
41 #include "wm_math.h"
42 #include <running_lock.h>
43 #include "singleton_container.h"
44 #include "pip_report.h"
45
46 namespace OHOS::Rosen {
47 namespace {
48 constexpr HiviewDFX::HiLogLabel LABEL = { LOG_CORE, HILOG_DOMAIN_WINDOW, "SceneSession" };
49 const std::string DLP_INDEX = "ohos.dlp.params.index";
50 } // namespace
51
52 MaximizeMode SceneSession::maximizeMode_ = MaximizeMode::MODE_RECOVER;
53 wptr<SceneSession> SceneSession::enterSession_ = nullptr;
54 std::mutex SceneSession::enterSessionMutex_;
55 std::map<int32_t, WSRect> SceneSession::windowDragHotAreaMap_;
56 static bool g_enableForceUIFirst = system::GetParameter("window.forceUIFirst.enabled", "1") == "1";
57
SceneSession(const SessionInfo & info,const sptr<SpecificSessionCallback> & specificCallback)58 SceneSession::SceneSession(const SessionInfo& info, const sptr<SpecificSessionCallback>& specificCallback)
59 : Session(info)
60 {
61 GeneratePersistentId(false, info.persistentId_);
62 specificCallback_ = specificCallback;
63 SetCollaboratorType(info.collaboratorType_);
64 WLOGFI("[WMSLife] Create session, id: %{public}d", GetPersistentId());
65 }
66
~SceneSession()67 SceneSession::~SceneSession()
68 {
69 WLOGI("[WMSLife] ~SceneSession, id: %{public}d", GetPersistentId());
70 }
71
Connect(const sptr<ISessionStage> & sessionStage,const sptr<IWindowEventChannel> & eventChannel,const std::shared_ptr<RSSurfaceNode> & surfaceNode,SystemSessionConfig & systemConfig,sptr<WindowSessionProperty> property,sptr<IRemoteObject> token,int32_t pid,int32_t uid)72 WSError SceneSession::Connect(const sptr<ISessionStage>& sessionStage, const sptr<IWindowEventChannel>& eventChannel,
73 const std::shared_ptr<RSSurfaceNode>& surfaceNode, SystemSessionConfig& systemConfig,
74 sptr<WindowSessionProperty> property, sptr<IRemoteObject> token, int32_t pid, int32_t uid)
75 {
76 // Get pid and uid before posting task.
77 pid = pid == -1 ? IPCSkeleton::GetCallingRealPid() : pid;
78 uid = uid == -1 ? IPCSkeleton::GetCallingUid() : uid;
79 auto task = [weakThis = wptr(this), sessionStage, eventChannel, surfaceNode, &systemConfig, property, token, pid, uid]() {
80 auto session = weakThis.promote();
81 if (!session) {
82 WLOGFE("[WMSLife] session is null");
83 return WSError::WS_ERROR_DESTROYED_OBJECT;
84 }
85 auto ret = session->Session::Connect(
86 sessionStage, eventChannel, surfaceNode, systemConfig, property, token, pid, uid);
87 if (ret != WSError::WS_OK) {
88 return ret;
89 }
90 session->NotifyPropertyWhenConnect();
91 return ret;
92 };
93 return PostSyncTask(task, "Connect");
94 }
95
Reconnect(const sptr<ISessionStage> & sessionStage,const sptr<IWindowEventChannel> & eventChannel,const std::shared_ptr<RSSurfaceNode> & surfaceNode,sptr<WindowSessionProperty> property,sptr<IRemoteObject> token,int32_t pid,int32_t uid)96 WSError SceneSession::Reconnect(const sptr<ISessionStage>& sessionStage, const sptr<IWindowEventChannel>& eventChannel,
97 const std::shared_ptr<RSSurfaceNode>& surfaceNode, sptr<WindowSessionProperty> property, sptr<IRemoteObject> token,
98 int32_t pid, int32_t uid)
99 {
100 return PostSyncTask([weakThis = wptr(this), sessionStage, eventChannel, surfaceNode, property, token, pid, uid]() {
101 auto session = weakThis.promote();
102 if (!session) {
103 WLOGFE("session is null");
104 return WSError::WS_ERROR_DESTROYED_OBJECT;
105 }
106 return session->Session::Reconnect(sessionStage, eventChannel, surfaceNode, property, token, pid, uid);
107 });
108 }
109
Foreground(sptr<WindowSessionProperty> property)110 WSError SceneSession::Foreground(sptr<WindowSessionProperty> property)
111 {
112 // return when screen is locked and show without ShowWhenLocked flag
113 if (GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW &&
114 GetStateFromManager(ManagerState::MANAGER_STATE_SCREEN_LOCKED) &&
115 !IsShowWhenLocked() &&
116 sessionInfo_.bundleName_.find("startupguide") == std::string::npos &&
117 sessionInfo_.bundleName_.find("samplemanagement") == std::string::npos) {
118 WLOGFW("[WMSLife] Foreground failed: Screen is locked, session %{public}d show without ShowWhenLocked flag",
119 GetPersistentId());
120 return WSError::WS_ERROR_INVALID_SESSION;
121 }
122
123 auto task = [weakThis = wptr(this), property]() {
124 auto session = weakThis.promote();
125 if (!session) {
126 WLOGFE("[WMSLife] session or property is null");
127 return WSError::WS_ERROR_DESTROYED_OBJECT;
128 }
129
130 if (property && session->GetSessionProperty()) {
131 session->GetSessionProperty()->SetWindowMode(property->GetWindowMode());
132 session->GetSessionProperty()->SetDecorEnable(property->IsDecorEnable());
133 }
134
135 if (property) {
136 weakThis->SetTextFieldAvoidInfo(property->GetTextFieldPositionY(), property->GetTextFieldHeight());
137 }
138 auto ret = session->Session::Foreground(property);
139 if (ret != WSError::WS_OK) {
140 return ret;
141 }
142 auto sessionProperty = session->GetSessionProperty();
143 if (session->leashWinSurfaceNode_ && sessionProperty) {
144 bool lastPrivacyMode = sessionProperty->GetPrivacyMode() || sessionProperty->GetSystemPrivacyMode();
145 session->leashWinSurfaceNode_->SetSecurityLayer(lastPrivacyMode);
146 }
147 if (session->specificCallback_ != nullptr) {
148 session->specificCallback_->onUpdateAvoidArea_(session->GetPersistentId());
149 session->specificCallback_->onWindowInfoUpdate_(
150 session->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_ADDED);
151 }
152 return WSError::WS_OK;
153 };
154 PostTask(task, "Foreground");
155 return WSError::WS_OK;
156 }
157
Background()158 WSError SceneSession::Background()
159 {
160 auto task = [weakThis = wptr(this)]() {
161 auto session = weakThis.promote();
162 if (!session) {
163 WLOGFE("[WMSLife] session is null");
164 return WSError::WS_ERROR_DESTROYED_OBJECT;
165 }
166 auto ret = session->Session::Background();
167 if (ret != WSError::WS_OK) {
168 return ret;
169 }
170 if (WindowHelper::IsMainWindow(session->GetWindowType())) {
171 session->snapshot_ = session->Snapshot();
172 if (session->scenePersistence_ && session->snapshot_) {
173 const std::function<void()> func = std::bind(&Session::ResetSnapshot, session);
174 session->scenePersistence_->SaveSnapshot(session->snapshot_, func);
175 }
176 }
177 session->snapshot_.reset();
178 if (session->specificCallback_ != nullptr) {
179 session->specificCallback_->onUpdateAvoidArea_(session->GetPersistentId());
180 session->specificCallback_->onWindowInfoUpdate_(
181 session->GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_REMOVED);
182 }
183 return WSError::WS_OK;
184 };
185 PostTask(task, "Background");
186 return WSError::WS_OK;
187 }
188
ClearSpecificSessionCbMap()189 void SceneSession::ClearSpecificSessionCbMap()
190 {
191 auto task = [weakThis = wptr(this)]() {
192 auto session = weakThis.promote();
193 if (!session) {
194 WLOGFE("[WMSSystem] session is null");
195 return;
196 }
197 if (session->sessionChangeCallback_ && session->sessionChangeCallback_->clearCallbackFunc_) {
198 session->sessionChangeCallback_->clearCallbackFunc_(true, session->GetPersistentId());
199 WLOGFD("[WMSSystem] ClearCallbackMap, id: %{public}d", session->GetPersistentId());
200 } else {
201 WLOGFE("[WMSSystem] get callback failed, id: %{public}d", session->GetPersistentId());
202 }
203 };
204 PostTask(task, "ClearSpecificSessionCbMap");
205 }
206
Disconnect(bool isFromClient)207 WSError SceneSession::Disconnect(bool isFromClient)
208 {
209 PostTask([weakThis = wptr(this), isFromClient]() {
210 auto session = weakThis.promote();
211 if (!session) {
212 WLOGFE("[WMSLife] session is null");
213 return WSError::WS_ERROR_DESTROYED_OBJECT;
214 }
215 if (isFromClient) {
216 WLOGFI("[WMSLife] Client need notify destroy session, id: %{public}d", session->GetPersistentId());
217 session->SetSessionState(SessionState::STATE_DISCONNECT);
218 return WSError::WS_OK;
219 }
220 auto state = session->GetSessionState();
221 auto isMainWindow = SessionHelper::IsMainWindow(session->GetWindowType());
222 if (session->needSnapshot_ || (state == SessionState::STATE_ACTIVE && isMainWindow)) {
223 session->snapshot_ = session->Snapshot();
224 if (session->scenePersistence_ && session->snapshot_) {
225 const std::function<void()> func = std::bind(&Session::ResetSnapshot, session);
226 session->scenePersistence_->SaveSnapshot(session->snapshot_, func);
227 }
228 }
229 if (WindowHelper::IsPipWindow(session->GetWindowType()) &&
230 session->GetWindowMode() == WindowMode::WINDOW_MODE_PIP) {
231 session->SavePiPRectInfo();
232 }
233 session->Session::Disconnect(isFromClient);
234 session->snapshot_.reset();
235 session->isTerminating = false;
236 return WSError::WS_OK;
237 },
238 "Disconnect");
239 return WSError::WS_OK;
240 }
241
UpdateActiveStatus(bool isActive)242 WSError SceneSession::UpdateActiveStatus(bool isActive)
243 {
244 auto task = [weakThis = wptr(this), isActive]() {
245 auto session = weakThis.promote();
246 if (!session) {
247 WLOGFE("[WMSCom] session is null");
248 return WSError::WS_ERROR_DESTROYED_OBJECT;
249 }
250 if (!session->IsSessionValid()) {
251 return WSError::WS_ERROR_INVALID_SESSION;
252 }
253 if (isActive == session->isActive_) {
254 WLOGFD("[WMSCom] Session active do not change: %{public}d", isActive);
255 return WSError::WS_DO_NOTHING;
256 }
257
258 WSError ret = WSError::WS_DO_NOTHING;
259 if (isActive && session->GetSessionState() == SessionState::STATE_FOREGROUND) {
260 session->UpdateSessionState(SessionState::STATE_ACTIVE);
261 session->isActive_ = isActive;
262 ret = WSError::WS_OK;
263 }
264 if (!isActive && session->GetSessionState() == SessionState::STATE_ACTIVE) {
265 session->UpdateSessionState(SessionState::STATE_INACTIVE);
266 session->isActive_ = isActive;
267 ret = WSError::WS_OK;
268 }
269 WLOGFI("[WMSCom] UpdateActiveStatus, isActive: %{public}d, state: %{public}u",
270 session->isActive_, session->GetSessionState());
271 return ret;
272 };
273 PostTask(task, "UpdateActiveStatus:" + std::to_string(isActive));
274 return WSError::WS_OK;
275 }
276
OnSessionEvent(SessionEvent event)277 WSError SceneSession::OnSessionEvent(SessionEvent event)
278 {
279 auto task = [weakThis = wptr(this), event]() {
280 auto session = weakThis.promote();
281 if (!session) {
282 WLOGFE("[WMSCom] session is null");
283 return WSError::WS_ERROR_DESTROYED_OBJECT;
284 }
285 WLOGFI("[WMSCom] SceneSession OnSessionEvent event: %{public}d", static_cast<int32_t>(event));
286 if (event == SessionEvent::EVENT_START_MOVE && session->moveDragController_ &&
287 !session->moveDragController_->GetStartDragFlag()) {
288 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "SceneSession::StartMove");
289 session->moveDragController_->InitMoveDragProperty();
290 session->moveDragController_->SetStartMoveFlag(true);
291 session->moveDragController_->ClacFirstMoveTargetRect(session->winRect_);
292 }
293 if (session->sessionChangeCallback_ && session->sessionChangeCallback_->OnSessionEvent_) {
294 session->sessionChangeCallback_->OnSessionEvent_(static_cast<uint32_t>(event));
295 }
296 return WSError::WS_OK;
297 };
298 PostTask(task, "OnSessionEvent:" + std::to_string(static_cast<int>(event)));
299 return WSError::WS_OK;
300 }
301
RegisterSessionChangeCallback(const sptr<SceneSession::SessionChangeCallback> & sessionChangeCallback)302 void SceneSession::RegisterSessionChangeCallback(const sptr<SceneSession::SessionChangeCallback>&
303 sessionChangeCallback)
304 {
305 std::lock_guard<std::mutex> guard(sessionChangeCbMutex_);
306 sessionChangeCallback_ = sessionChangeCallback;
307 }
308
SetGlobalMaximizeMode(MaximizeMode mode)309 WSError SceneSession::SetGlobalMaximizeMode(MaximizeMode mode)
310 {
311 auto task = [weakThis = wptr(this), mode]() {
312 auto session = weakThis.promote();
313 if (!session) {
314 WLOGFE("[WMSCom] session is null");
315 return WSError::WS_ERROR_DESTROYED_OBJECT;
316 }
317 WLOGFD("[WMSCom] mode: %{public}u", static_cast<uint32_t>(mode));
318 session->maximizeMode_ = mode;
319 ScenePersistentStorage::Insert("maximize_state", static_cast<int32_t>(session->maximizeMode_),
320 ScenePersistentStorageType::MAXIMIZE_STATE);
321 return WSError::WS_OK;
322 };
323 return PostSyncTask(task, "SetGlobalMaximizeMode");
324 }
325
GetGlobalMaximizeMode(MaximizeMode & mode)326 WSError SceneSession::GetGlobalMaximizeMode(MaximizeMode &mode)
327 {
328 auto task = [weakThis = wptr(this), &mode]() {
329 auto session = weakThis.promote();
330 if (!session) {
331 WLOGFE("[WMSCom] session is null");
332 return WSError::WS_ERROR_DESTROYED_OBJECT;
333 }
334 mode = maximizeMode_;
335 WLOGFD("[WMSCom] mode: %{public}u", static_cast<uint32_t>(mode));
336 return WSError::WS_OK;
337 };
338 return PostSyncTask(task, "GetGlobalMaximizeMode");
339 }
340
SetAspectRatio(float ratio)341 WSError SceneSession::SetAspectRatio(float ratio)
342 {
343 auto task = [weakThis = wptr(this), ratio]() {
344 auto session = weakThis.promote();
345 if (!session) {
346 WLOGFE("[WMSCom] session is null");
347 return WSError::WS_ERROR_DESTROYED_OBJECT;
348 }
349 if (!session->GetSessionProperty()) {
350 WLOGE("[WMSCom] SetAspectRatio failed because property is null");
351 return WSError::WS_ERROR_NULLPTR;
352 }
353 WLOGFI("[WMSCom] ratio: %{public}f", ratio);
354 float vpr = 1.5f; // 1.5f: default virtual pixel ratio
355 auto display = DisplayManager::GetInstance().GetDefaultDisplay();
356 if (display) {
357 vpr = display->GetVirtualPixelRatio();
358 WLOGD("vpr = %{public}f", vpr);
359 }
360 if (!MathHelper::NearZero(ratio)) {
361 auto limits = session->GetSessionProperty()->GetWindowLimits();
362 if (session->IsDecorEnable()) {
363 if (limits.minWidth_ && limits.maxHeight_ &&
364 MathHelper::LessNotEqual(ratio, SessionUtils::ToLayoutWidth(limits.minWidth_, vpr) /
365 SessionUtils::ToLayoutHeight(limits.maxHeight_, vpr))) {
366 WLOGE("Failed, because aspectRatio is smaller than minWidth/maxHeight");
367 return WSError::WS_ERROR_INVALID_PARAM;
368 } else if (limits.minHeight_ && limits.maxWidth_ &&
369 MathHelper::GreatNotEqual(ratio, SessionUtils::ToLayoutWidth(limits.maxWidth_, vpr) /
370 SessionUtils::ToLayoutHeight(limits.minHeight_, vpr))) {
371 WLOGE("Failed, because aspectRatio is bigger than maxWidth/minHeight");
372 return WSError::WS_ERROR_INVALID_PARAM;
373 }
374 } else {
375 if (limits.minWidth_ && limits.maxHeight_ && MathHelper::LessNotEqual(ratio,
376 static_cast<float>(limits.minWidth_) / limits.maxHeight_)) {
377 WLOGE("Failed, because aspectRatio is smaller than minWidth/maxHeight");
378 return WSError::WS_ERROR_INVALID_PARAM;
379 } else if (limits.minHeight_ && limits.maxWidth_ && MathHelper::GreatNotEqual(ratio,
380 static_cast<float>(limits.maxWidth_) / limits.minHeight_)) {
381 WLOGE("Failed, because aspectRatio is bigger than maxWidth/minHeight");
382 return WSError::WS_ERROR_INVALID_PARAM;
383 }
384 }
385 }
386 session->aspectRatio_ = ratio;
387 if (session->moveDragController_) {
388 session->moveDragController_->SetAspectRatio(ratio);
389 }
390 session->SaveAspectRatio(session->aspectRatio_);
391 WSRect fixedRect = session->winRect_;
392 WLOGFI("[WMSLayout] Before fixing, the id:%{public}d, the current rect: %{public}s",
393 session->GetPersistentId(), fixedRect.ToString().c_str());
394 if (session->FixRectByAspectRatio(fixedRect)) {
395 WLOGFI("[WMSLayout] After fixing, the id:%{public}d, the fixed rect: %{public}s",
396 session->GetPersistentId(), fixedRect.ToString().c_str());
397 session->NotifySessionRectChange(fixedRect, SizeChangeReason::RESIZE);
398 }
399 return WSError::WS_OK;
400 };
401 return PostSyncTask(task, "SetAspectRatio");
402 }
403
UpdateRect(const WSRect & rect,SizeChangeReason reason,const std::shared_ptr<RSTransaction> & rsTransaction)404 WSError SceneSession::UpdateRect(const WSRect& rect, SizeChangeReason reason,
405 const std::shared_ptr<RSTransaction>& rsTransaction)
406 {
407 auto task = [weakThis = wptr(this), rect, reason, rsTransaction]() {
408 auto session = weakThis.promote();
409 if (!session) {
410 WLOGFE("session is null");
411 return WSError::WS_ERROR_DESTROYED_OBJECT;
412 }
413 if (session->winRect_ == rect) {
414 WLOGFI("[WMSLayout] skip same rect update id:%{public}d rect:%{public}s!",
415 session->GetPersistentId(), rect.ToString().c_str());
416 return WSError::WS_OK;
417 }
418 if (rect.IsInvalid()) {
419 WLOGFE("[WMSLayout] id:%{public}d rect:%{public}s is invalid",
420 session->GetPersistentId(), rect.ToString().c_str());
421 return WSError::WS_ERROR_INVALID_PARAM;
422 }
423 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER,
424 "SceneSession::UpdateRect%d [%d, %d, %u, %u]",
425 session->GetPersistentId(), rect.posX_, rect.posY_, rect.width_, rect.height_);
426 // position change no need to notify client, since frame layout finish will notify
427 if (NearEqual(rect.width_, session->winRect_.width_) && NearEqual(rect.height_, session->winRect_.height_)) {
428 WLOGFI("[WMSLayout] position change no need notify client id:%{public}d, rect:%{public}s, \
429 preRect: %{public}s",
430 session->GetPersistentId(), rect.ToString().c_str(), session->winRect_.ToString().c_str());
431 session->winRect_ = rect;
432 session->isDirty_ = true;
433 } else {
434 session->winRect_ = rect;
435 session->NotifyClientToUpdateRect(rsTransaction);
436 }
437 WLOGFD("[WMSLayout] id:%{public}d, reason:%{public}d, rect:%{public}s",
438 session->GetPersistentId(), session->reason_, rect.ToString().c_str());
439
440 return WSError::WS_OK;
441 };
442 PostTask(task, "UpdateRect" + GetRectInfo(rect));
443 return WSError::WS_OK;
444 }
445
NotifyClientToUpdateRect(std::shared_ptr<RSTransaction> rsTransaction)446 WSError SceneSession::NotifyClientToUpdateRect(std::shared_ptr<RSTransaction> rsTransaction)
447 {
448 auto task = [weakThis = wptr(this), rsTransaction]() {
449 auto session = weakThis.promote();
450 if (!session) {
451 WLOGFE("session is null");
452 return WSError::WS_ERROR_DESTROYED_OBJECT;
453 }
454 WLOGD("[WMSLayout] NotifyClientToUpdateRect id:%{public}d, reason:%{public}d, rect:%{public}s",
455 session->GetPersistentId(), session->reason_, session->winRect_.ToString().c_str());
456 bool isMoveOrDrag = session->moveDragController_ &&
457 (session->moveDragController_->GetStartDragFlag() || session->moveDragController_->GetStartMoveFlag());
458 if (isMoveOrDrag && session->reason_ == SizeChangeReason::UNDEFINED) {
459 WLOGFD("[WMSLayout] skip redundant rect update!");
460 return WSError::WS_ERROR_REPEAT_OPERATION;
461 }
462 WSError ret = WSError::WS_OK;
463 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER,
464 "SceneSession::NotifyClientToUpdateRect%d [%d, %d, %u, %u] reason:%u",
465 session->GetPersistentId(), session->winRect_.posX_,
466 session->winRect_.posY_, session->winRect_.width_, session->winRect_.height_, session->reason_);
467 // once reason is undefined, not use rsTransaction
468 // when rotation, sync cnt++ in marshalling. Although reason is undefined caused by resize
469 if (session->reason_ == SizeChangeReason::UNDEFINED || session->reason_ == SizeChangeReason::MOVE) {
470 ret = session->Session::UpdateRect(session->winRect_, session->reason_, nullptr);
471 } else {
472 ret = session->Session::UpdateRect(session->winRect_, session->reason_, rsTransaction);
473 }
474 if ((ret == WSError::WS_OK || session->sessionInfo_.isSystem_) && session->specificCallback_ != nullptr) {
475 session->specificCallback_->onUpdateAvoidArea_(session->GetPersistentId());
476 }
477 // clear after use
478 if (ret == WSError::WS_OK || session->sessionInfo_.isSystem_) {
479 session->reason_ = SizeChangeReason::UNDEFINED;
480 session->isDirty_ = false;
481 }
482 return ret;
483 };
484 PostTask(task, "NotifyClientToUpdateRect");
485 return WSError::WS_OK;
486 }
487
UpdateInputMethodSessionRect(const WSRect & rect,WSRect & newWinRect,WSRect & newRequestRect)488 bool SceneSession::UpdateInputMethodSessionRect(const WSRect&rect, WSRect& newWinRect, WSRect& newRequestRect)
489 {
490 SessionGravity gravity;
491 uint32_t percent = 0;
492 GetSessionProperty()->GetSessionGravity(gravity, percent);
493 if (GetWindowType() == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT &&
494 (gravity == SessionGravity::SESSION_GRAVITY_BOTTOM || gravity == SessionGravity::SESSION_GRAVITY_DEFAULT)) {
495 auto defaultDisplayInfo = DisplayManager::GetInstance().GetDefaultDisplay();
496 if (defaultDisplayInfo == nullptr) {
497 WLOGFE("[WMSInput] defaultDisplayInfo is nullptr");
498 return false;
499 }
500
501 newWinRect.width_ = (gravity == SessionGravity::SESSION_GRAVITY_BOTTOM) ?
502 defaultDisplayInfo->GetWidth() : rect.width_;
503 newRequestRect.width_ = newWinRect.width_;
504 newWinRect.height_ = (gravity == SessionGravity::SESSION_GRAVITY_BOTTOM && percent != 0) ?
505 static_cast<int32_t>(defaultDisplayInfo->GetHeight()) * percent / 100u : rect.height_;
506 newRequestRect.height_ = newWinRect.height_;
507 newWinRect.posX_ = (gravity == SessionGravity::SESSION_GRAVITY_BOTTOM) ? 0 : newRequestRect.posX_;
508 newRequestRect.posX_ = newWinRect.posX_;
509 newWinRect.posY_ = defaultDisplayInfo->GetHeight() - static_cast<int32_t>(newWinRect.height_);
510 newRequestRect.posY_ = newWinRect.posY_;
511 WLOGFI("[WMSInput] rect: %{public}s, newRequestRect: %{public}s, "
512 "newWinRect: %{public}s",
513 rect.ToString().c_str(), newRequestRect.ToString().c_str(), newWinRect.ToString().c_str());
514 return true;
515 }
516 WLOGFD("There is no need to update input rect");
517 return false;
518 }
519
SetSessionRectChangeCallback(const NotifySessionRectChangeFunc & func)520 void SceneSession::SetSessionRectChangeCallback(const NotifySessionRectChangeFunc& func)
521 {
522 auto task = [weakThis = wptr(this), func]() {
523 auto session = weakThis.promote();
524 if (!session) {
525 WLOGFE("session is null");
526 return WSError::WS_ERROR_DESTROYED_OBJECT;
527 }
528 session->sessionRectChangeFunc_ = func;
529 if (session->sessionRectChangeFunc_ && session->GetWindowType() != WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
530 auto reason = SizeChangeReason::UNDEFINED;
531 auto rect = session->GetSessionRequestRect();
532 if (rect.width_ == 0 && rect.height_ == 0) {
533 reason = SizeChangeReason::MOVE;
534 }
535 session->sessionRectChangeFunc_(session->GetSessionRequestRect(), reason);
536 }
537 return WSError::WS_OK;
538 };
539 PostTask(task, "SetSessionRectChangeCallback");
540 }
541
UpdateSessionRect(const WSRect & rect,const SizeChangeReason & reason)542 WSError SceneSession::UpdateSessionRect(const WSRect& rect, const SizeChangeReason& reason)
543 {
544 auto task = [weakThis = wptr(this), rect, reason]() {
545 auto session = weakThis.promote();
546 if (!session) {
547 WLOGFE("[WMSLayout] session is null");
548 return WSError::WS_ERROR_DESTROYED_OBJECT;
549 }
550 auto newWinRect = session->winRect_;
551 auto newRequestRect = session->GetSessionRequestRect();
552 SizeChangeReason newReason = reason;
553 if (reason == SizeChangeReason::MOVE) {
554 newWinRect.posX_ = rect.posX_;
555 newWinRect.posY_ = rect.posY_;
556 newRequestRect.posX_ = rect.posX_;
557 newRequestRect.posY_ = rect.posY_;
558 session->SetSessionRect(newWinRect);
559 session->SetSessionRequestRect(newRequestRect);
560 session->NotifySessionRectChange(newRequestRect, reason);
561 } else if (reason == SizeChangeReason::RESIZE) {
562 bool needUpdateInputMethod = session->UpdateInputMethodSessionRect(rect, newWinRect, newRequestRect);
563 if (needUpdateInputMethod) {
564 newReason = SizeChangeReason::UNDEFINED;
565 WLOGFD("[WMSInput] Input rect has totally changed, need to modify reason, id: %{public}d",
566 session->GetPersistentId());
567 } else if (rect.width_ > 0 && rect.height_ > 0) {
568 newWinRect.width_ = rect.width_;
569 newWinRect.height_ = rect.height_;
570 newRequestRect.width_ = rect.width_;
571 newRequestRect.height_ = rect.height_;
572 }
573 session->SetSessionRect(newWinRect);
574 session->SetSessionRequestRect(newRequestRect);
575 session->NotifySessionRectChange(newRequestRect, newReason);
576 } else {
577 session->SetSessionRect(rect);
578 session->NotifySessionRectChange(rect, reason);
579 }
580
581 WLOGFI("[WMSLayout] Id: %{public}d, reason: %{public}d, newReason: %{public}d, rect: %{public}s, "
582 "newRequestRect: %{public}s, newWinRect: %{public}s", session->GetPersistentId(), reason,
583 newReason, rect.ToString().c_str(), newRequestRect.ToString().c_str(), newWinRect.ToString().c_str());
584 return WSError::WS_OK;
585 };
586 PostTask(task, "UpdateSessionRect" + GetRectInfo(rect));
587 return WSError::WS_OK;
588 }
589
RaiseToAppTop()590 WSError SceneSession::RaiseToAppTop()
591 {
592 if (!SessionPermission::IsSystemCalling()) {
593 WLOGFE("raise to app top permission denied!");
594 return WSError::WS_ERROR_NOT_SYSTEM_APP;
595 }
596 auto task = [weakThis = wptr(this)]() {
597 auto session = weakThis.promote();
598 if (!session) {
599 WLOGFE("session is null");
600 return WSError::WS_ERROR_DESTROYED_OBJECT;
601 }
602 if (session->sessionChangeCallback_ && session->sessionChangeCallback_->onRaiseToTop_) {
603 WLOGFI("[WMSSub] id: %{public}d", session->GetPersistentId());
604 session->sessionChangeCallback_->onRaiseToTop_();
605 }
606 return WSError::WS_OK;
607 };
608 return PostSyncTask(task, "RaiseToAppTop");
609 }
610
RaiseAboveTarget(int32_t subWindowId)611 WSError SceneSession::RaiseAboveTarget(int32_t subWindowId)
612 {
613 if (!SessionPermission::IsSystemCalling() && !SessionPermission::IsStartByHdcd()) {
614 WLOGFE("RaiseAboveTarget permission denied!");
615 return WSError::WS_ERROR_NOT_SYSTEM_APP;
616 }
617 auto task = [weakThis = wptr(this), subWindowId]() {
618 auto session = weakThis.promote();
619 if (!session) {
620 WLOGFE("session is null");
621 return WSError::WS_ERROR_DESTROYED_OBJECT;
622 }
623 if (session->sessionChangeCallback_ && session->sessionChangeCallback_->onRaiseAboveTarget_) {
624 session->sessionChangeCallback_->onRaiseAboveTarget_(subWindowId);
625 }
626 return WSError::WS_OK;
627 };
628 return PostSyncTask(task, "RaiseAboveTarget");
629 }
630
BindDialogSessionTarget(const sptr<SceneSession> & sceneSession)631 WSError SceneSession::BindDialogSessionTarget(const sptr<SceneSession>& sceneSession)
632 {
633 if (sceneSession == nullptr) {
634 WLOGFE("[WMSDialog] dialog session is null");
635 return WSError::WS_ERROR_NULLPTR;
636 }
637 if (sessionChangeCallback_ != nullptr && sessionChangeCallback_->onBindDialogTarget_) {
638 WLOGFI("[WMSDialog] id: %{public}d", sceneSession->GetPersistentId());
639 sessionChangeCallback_->onBindDialogTarget_(sceneSession);
640 }
641 return WSError::WS_OK;
642 }
643
SetSystemBarProperty(WindowType type,SystemBarProperty systemBarProperty)644 WSError SceneSession::SetSystemBarProperty(WindowType type, SystemBarProperty systemBarProperty)
645 {
646 auto property = GetSessionProperty();
647 if (property == nullptr) {
648 return WSError::WS_ERROR_NULLPTR;
649 }
650 property->SetSystemBarProperty(type, systemBarProperty);
651 WLOGFI("[WMSImms]SceneSession SetSystemBarProperty persistentId():%{public}u type:%{public}u"
652 "enable:%{public}u bgColor:%{public}x Color:%{public}x",
653 GetPersistentId(), static_cast<uint32_t>(type),
654 systemBarProperty.enable_, systemBarProperty.backgroundColor_, systemBarProperty.contentColor_);
655 if (sessionChangeCallback_ != nullptr && sessionChangeCallback_->OnSystemBarPropertyChange_) {
656 sessionChangeCallback_->OnSystemBarPropertyChange_(property->GetSystemBarProperty());
657 }
658 return WSError::WS_OK;
659 }
660
NotifyPropertyWhenConnect()661 void SceneSession::NotifyPropertyWhenConnect()
662 {
663 WLOGFI("Notify property when connect.");
664 auto property = GetSessionProperty();
665 if (property == nullptr) {
666 WLOGFD("id: %{public}d property is nullptr", persistentId_);
667 return;
668 }
669 NotifySessionFocusableChange(property->GetFocusable());
670 NotifySessionTouchableChange(property->GetTouchable());
671 OnShowWhenLocked(IsShowWhenLocked());
672 }
673
RaiseAppMainWindowToTop()674 WSError SceneSession::RaiseAppMainWindowToTop()
675 {
676 auto task = [weakThis = wptr(this)]() {
677 auto session = weakThis.promote();
678 if (!session) {
679 WLOGFE("session is null");
680 return WSError::WS_ERROR_DESTROYED_OBJECT;
681 }
682 session->NotifyRequestFocusStatusNotifyManager(true, true);
683 session->NotifyClick();
684 return WSError::WS_OK;
685 };
686 PostTask(task, "RaiseAppMainWindowToTop");
687 return WSError::WS_OK;
688 }
689
OnNeedAvoid(bool status)690 WSError SceneSession::OnNeedAvoid(bool status)
691 {
692 auto task = [weakThis = wptr(this), status]() {
693 auto session = weakThis.promote();
694 if (!session) {
695 WLOGFE("session is null");
696 return WSError::WS_ERROR_DESTROYED_OBJECT;
697 }
698 WLOGFI("[WMSImms]SceneSession OnNeedAvoid status:%{public}d", static_cast<int32_t>(status));
699 if (session->sessionChangeCallback_ && session->sessionChangeCallback_->OnNeedAvoid_) {
700 session->sessionChangeCallback_->OnNeedAvoid_(status);
701 }
702 return WSError::WS_OK;
703 };
704 PostTask(task, "OnNeedAvoid");
705 return WSError::WS_OK;
706 }
707
OnShowWhenLocked(bool showWhenLocked)708 WSError SceneSession::OnShowWhenLocked(bool showWhenLocked)
709 {
710 WLOGFD("SceneSession ShowWhenLocked status:%{public}d", static_cast<int32_t>(showWhenLocked));
711 if (sessionChangeCallback_ != nullptr && sessionChangeCallback_->OnShowWhenLocked_) {
712 sessionChangeCallback_->OnShowWhenLocked_(showWhenLocked);
713 }
714 return WSError::WS_OK;
715 }
716
IsShowWhenLocked() const717 bool SceneSession::IsShowWhenLocked() const
718 {
719 return GetSessionProperty()->GetWindowFlags() & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_SHOW_WHEN_LOCKED);
720 }
721
CalculateAvoidAreaRect(WSRect & rect,WSRect & avoidRect,AvoidArea & avoidArea) const722 void SceneSession::CalculateAvoidAreaRect(WSRect& rect, WSRect& avoidRect, AvoidArea& avoidArea) const
723 {
724 if (SessionHelper::IsEmptyRect(rect) || SessionHelper::IsEmptyRect(avoidRect)) {
725 return;
726 }
727 Rect avoidAreaRect = SessionHelper::TransferToRect(
728 SessionHelper::GetOverlap(rect, avoidRect, rect.posX_, rect.posY_));
729 if (WindowHelper::IsEmptyRect(avoidAreaRect)) {
730 return;
731 }
732
733 uint32_t avoidAreaCenterX = static_cast<uint32_t>(avoidAreaRect.posX_) + (avoidAreaRect.width_ >> 1);
734 uint32_t avoidAreaCenterY = static_cast<uint32_t>(avoidAreaRect.posY_) + (avoidAreaRect.height_ >> 1);
735 float res1 = float(avoidAreaCenterY) - float(rect.height_) / float(rect.width_) *
736 float(avoidAreaCenterX);
737 float res2 = float(avoidAreaCenterY) + float(rect.height_) / float(rect.width_) *
738 float(avoidAreaCenterX) - float(rect.height_);
739 if (res1 < 0) {
740 if (res2 < 0) {
741 avoidArea.topRect_ = avoidAreaRect;
742 } else {
743 avoidArea.rightRect_ = avoidAreaRect;
744 }
745 } else {
746 if (res2 < 0) {
747 avoidArea.leftRect_ = avoidAreaRect;
748 } else {
749 avoidArea.bottomRect_ = avoidAreaRect;
750 }
751 }
752 }
753
GetSystemAvoidArea(WSRect & rect,AvoidArea & avoidArea)754 void SceneSession::GetSystemAvoidArea(WSRect& rect, AvoidArea& avoidArea)
755 {
756 if (GetSessionProperty()->GetWindowFlags() & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_NEED_AVOID)) {
757 return;
758 }
759 if ((Session::GetWindowMode() == WindowMode::WINDOW_MODE_FLOATING ||
760 Session::GetWindowMode() == WindowMode::WINDOW_MODE_SPLIT_PRIMARY ||
761 Session::GetWindowMode() == WindowMode::WINDOW_MODE_SPLIT_SECONDARY) &&
762 WindowHelper::IsMainWindow(Session::GetWindowType()) &&
763 (system::GetParameter("const.product.devicetype", "unknown") == "phone" ||
764 system::GetParameter("const.product.devicetype", "unknown") == "tablet")) {
765 float miniScale = 0.316f; // Pressed mini floating Scale with 0.001 precision
766 if (Session::GetFloatingScale() <= miniScale) {
767 return;
768 }
769 float vpr = 3.5f; // 3.5f: default pixel ratio
770 auto display = DisplayManager::GetInstance().GetDefaultDisplay();
771 if (display) {
772 vpr = display->GetVirtualPixelRatio();
773 }
774 int32_t floatingBarHeight = 32; // 32: floating windowBar Height
775 avoidArea.topRect_.height_ = vpr * floatingBarHeight;
776 avoidArea.topRect_.width_ = display->GetWidth();
777 return;
778 }
779 std::vector<sptr<SceneSession>> statusBarVector =
780 specificCallback_->onGetSceneSessionVectorByType_(WindowType::WINDOW_TYPE_STATUS_BAR);
781 for (auto& statusBar : statusBarVector) {
782 if (!(statusBar->isVisible_)) {
783 continue;
784 }
785 WSRect statusBarRect = statusBar->GetSessionRect();
786 CalculateAvoidAreaRect(rect, statusBarRect, avoidArea);
787 }
788
789 return;
790 }
791
GetKeyboardAvoidArea(WSRect & rect,AvoidArea & avoidArea)792 void SceneSession::GetKeyboardAvoidArea(WSRect& rect, AvoidArea& avoidArea)
793 {
794 if (((Session::GetWindowMode() == WindowMode::WINDOW_MODE_FLOATING &&
795 WindowHelper::IsMainWindow(Session::GetWindowType())) ||
796 (WindowHelper::IsSubWindow(Session::GetWindowType()) && GetParentSession() != nullptr &&
797 GetParentSession()->GetWindowMode() == WindowMode::WINDOW_MODE_FLOATING)) &&
798 (system::GetParameter("const.product.devicetype", "unknown") == "phone" ||
799 system::GetParameter("const.product.devicetype", "unknown") == "tablet")) {
800 return;
801 }
802 std::vector<sptr<SceneSession>> inputMethodVector =
803 specificCallback_->onGetSceneSessionVectorByType_(WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT);
804 for (auto& inputMethod : inputMethodVector) {
805 if (inputMethod->GetSessionState() != SessionState::STATE_FOREGROUND &&
806 inputMethod->GetSessionState() != SessionState::STATE_ACTIVE) {
807 continue;
808 }
809 SessionGravity gravity;
810 uint32_t percent = 0;
811 inputMethod->GetSessionProperty()->GetSessionGravity(gravity, percent);
812 if (gravity == SessionGravity::SESSION_GRAVITY_FLOAT) {
813 continue;
814 }
815 WSRect inputMethodRect = inputMethod->GetSessionRect();
816 CalculateAvoidAreaRect(rect, inputMethodRect, avoidArea);
817 }
818
819 return;
820 }
821
GetCutoutAvoidArea(WSRect & rect,AvoidArea & avoidArea)822 void SceneSession::GetCutoutAvoidArea(WSRect& rect, AvoidArea& avoidArea)
823 {
824 auto display = DisplayManager::GetInstance().GetDisplayById(GetSessionProperty()->GetDisplayId());
825 if (display == nullptr) {
826 WLOGFE("Failed to get display manager");
827 return;
828 }
829 sptr<CutoutInfo> cutoutInfo = display->GetCutoutInfo();
830 if (cutoutInfo == nullptr) {
831 WLOGFI("GetCutoutAvoidArea There is no CutoutInfo");
832 return;
833 }
834 std::vector<DMRect> cutoutAreas = cutoutInfo->GetBoundingRects();
835 if (cutoutAreas.empty()) {
836 WLOGFI("GetCutoutAvoidArea There is no cutoutAreas");
837 return;
838 }
839 for (auto& cutoutArea : cutoutAreas) {
840 WSRect cutoutAreaRect = {
841 cutoutArea.posX_,
842 cutoutArea.posY_,
843 cutoutArea.width_,
844 cutoutArea.height_
845 };
846 CalculateAvoidAreaRect(rect, cutoutAreaRect, avoidArea);
847 }
848
849 return;
850 }
851
GetAINavigationBarArea(WSRect rect,AvoidArea & avoidArea)852 void SceneSession::GetAINavigationBarArea(WSRect rect, AvoidArea& avoidArea)
853 {
854 if (Session::GetWindowMode() == WindowMode::WINDOW_MODE_FLOATING ||
855 Session::GetWindowMode() == WindowMode::WINDOW_MODE_PIP) {
856 return;
857 }
858 WSRect barArea = specificCallback_->onGetAINavigationBarArea_();
859 CalculateAvoidAreaRect(rect, barArea, avoidArea);
860 }
861
GetAvoidAreaByType(AvoidAreaType type)862 AvoidArea SceneSession::GetAvoidAreaByType(AvoidAreaType type)
863 {
864 auto task = [weakThis = wptr(this), type]() -> AvoidArea {
865 auto session = weakThis.promote();
866 if (!session) {
867 WLOGFE("session is null");
868 return {};
869 }
870 AvoidArea avoidArea;
871 WSRect rect = session->GetSessionRect();
872 WLOGFD("[WMSImms]GetAvoidAreaByType avoidAreaType:%{public}u", type);
873 switch (type) {
874 case AvoidAreaType::TYPE_SYSTEM: {
875 session->GetSystemAvoidArea(rect, avoidArea);
876 return avoidArea;
877 }
878 case AvoidAreaType::TYPE_KEYBOARD: {
879 session->GetKeyboardAvoidArea(rect, avoidArea);
880 return avoidArea;
881 }
882 case AvoidAreaType::TYPE_CUTOUT: {
883 session->GetCutoutAvoidArea(rect, avoidArea);
884 return avoidArea;
885 }
886 case AvoidAreaType::TYPE_NAVIGATION_INDICATOR: {
887 session->GetAINavigationBarArea(rect, avoidArea);
888 return avoidArea;
889 }
890 default: {
891 WLOGFI("[WMSImms]cannot find avoidAreaType: %{public}u", type);
892 return avoidArea;
893 }
894 }
895 };
896 return PostSyncTask(task, "GetAvoidAreaByType");
897 }
898
UpdateAvoidArea(const sptr<AvoidArea> & avoidArea,AvoidAreaType type)899 WSError SceneSession::UpdateAvoidArea(const sptr<AvoidArea>& avoidArea, AvoidAreaType type)
900 {
901 if (!sessionStage_) {
902 return WSError::WS_ERROR_NULLPTR;
903 }
904 return sessionStage_->UpdateAvoidArea(avoidArea, type);
905 }
906
HandleStyleEvent(MMI::WindowArea area)907 void SceneSession::HandleStyleEvent(MMI::WindowArea area)
908 {
909 static std::pair<int32_t, MMI::WindowArea> preWindowArea =
910 std::make_pair(INVALID_WINDOW_ID, MMI::WindowArea::EXIT);
911 if (preWindowArea.first == Session::GetWindowId() && preWindowArea.second == area) {
912 return;
913 }
914 if (area != MMI::WindowArea::EXIT) {
915 if (Session::SetPointerStyle(area) != WSError::WS_OK) {
916 WLOGFE("Failed to set the cursor style, WSError:%{public}d", Session::SetPointerStyle(area));
917 }
918 }
919 preWindowArea = { Session::GetWindowId(), area };
920 }
921
HandleEnterWinwdowArea(int32_t displayX,int32_t displayY)922 WSError SceneSession::HandleEnterWinwdowArea(int32_t displayX, int32_t displayY)
923 {
924 if (displayX < 0 || displayY < 0) {
925 WLOGE("Illegal parameter, displayX:%{public}d, displayY:%{public}d", displayX, displayY);
926 return WSError::WS_ERROR_INVALID_PARAM;
927 }
928
929 auto windowType = Session::GetWindowType();
930 auto iter = Session::windowAreas_.cend();
931 if (!Session::IsSystemSession() &&
932 Session::GetWindowMode() == WindowMode::WINDOW_MODE_FLOATING &&
933 (windowType == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW || WindowHelper::IsSubWindow(windowType))) {
934 iter = Session::windowAreas_.cbegin();
935 for (;iter != Session::windowAreas_.cend(); ++iter) {
936 WSRectF rect = iter->second;
937 if (rect.IsInRegion(displayX, displayY)) {
938 break;
939 }
940 }
941 }
942
943 MMI::WindowArea area = MMI::WindowArea::EXIT;
944 if (iter == Session::windowAreas_.cend()) {
945 bool isInRegion = false;
946 WSRect rect = Session::winRect_;
947 if (Session::GetWindowMode() == WindowMode::WINDOW_MODE_FLOATING &&
948 (windowType == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW || WindowHelper::IsSubWindow(windowType))) {
949 WSRectF rectF = Session::UpdateHotRect(rect);
950 isInRegion = rectF.IsInRegion(displayX, displayY);
951 } else {
952 isInRegion = rect.IsInRegion(displayX, displayY);
953 }
954 if (!isInRegion) {
955 WLOGFE("The wrong event(%{public}d, %{public}d) could not be matched to the region:" \
956 "[%{public}d, %{public}d, %{public}d, %{public}d]",
957 displayX, displayY, rect.posX_, rect.posY_, rect.width_, rect.height_);
958 return WSError::WS_ERROR_INVALID_TYPE;
959 }
960 area = MMI::WindowArea::FOCUS_ON_INNER;
961 } else {
962 area = iter->first;
963 }
964 HandleStyleEvent(area);
965 return WSError::WS_OK;
966 }
967
HandlePointerStyle(const std::shared_ptr<MMI::PointerEvent> & pointerEvent)968 WSError SceneSession::HandlePointerStyle(const std::shared_ptr<MMI::PointerEvent>& pointerEvent)
969 {
970 if (pointerEvent == nullptr) {
971 WLOGFE("pointerEvent is nullptr");
972 return WSError::WS_ERROR_NULLPTR;
973 }
974 if (pointerEvent->GetSourceType() != MMI::PointerEvent::SOURCE_TYPE_MOUSE) {
975 return WSError::WS_DO_NOTHING;
976 }
977 if (!(pointerEvent->GetPointerAction() == MMI::PointerEvent::POINTER_ACTION_MOVE &&
978 pointerEvent->GetButtonId() == MMI::PointerEvent::BUTTON_NONE)) {
979 return WSError::WS_DO_NOTHING;
980 }
981
982 MMI::PointerEvent::PointerItem pointerItem;
983 if (!pointerEvent->GetPointerItem(pointerEvent->GetPointerId(), pointerItem)) {
984 WLOGFE("Get pointeritem failed");
985 pointerEvent->MarkProcessed();
986 return WSError::WS_ERROR_INVALID_PARAM;
987 }
988 int32_t mousePointX = pointerItem.GetDisplayX();
989 int32_t mousePointY = pointerItem.GetDisplayY();
990
991 auto displayInfo = DisplayManager::GetInstance().GetDisplayById(pointerEvent->GetTargetDisplayId());
992 if (displayInfo != nullptr) {
993 float vpr = displayInfo->GetVirtualPixelRatio();
994 if (vpr <= 0) {
995 vpr = 1.5f;
996 }
997 Session::SetVpr(vpr);
998 }
999 return HandleEnterWinwdowArea(mousePointX, mousePointY);
1000 }
1001
ProcessPointDownSession(int32_t posX,int32_t posY)1002 WSError SceneSession::ProcessPointDownSession(int32_t posX, int32_t posY)
1003 {
1004 const auto& id = GetPersistentId();
1005 WLOGFI("id: %{public}d, type: %{public}d, pos: [%{public}d, %{public}d]", id, GetWindowType(), posX, posY);
1006
1007 // notify touch outside
1008 if (specificCallback_ != nullptr && specificCallback_->onSessionTouchOutside_) {
1009 specificCallback_->onSessionTouchOutside_(id);
1010 }
1011
1012 // notify outside down event
1013 if (specificCallback_ != nullptr && specificCallback_->onOutsideDownEvent_) {
1014 specificCallback_->onOutsideDownEvent_(posX, posY);
1015 }
1016 return WSError::WS_OK;
1017 }
1018
SendPointEventForMoveDrag(const std::shared_ptr<MMI::PointerEvent> & pointerEvent)1019 WSError SceneSession::SendPointEventForMoveDrag(const std::shared_ptr<MMI::PointerEvent>& pointerEvent)
1020 {
1021 NotifyOutsideDownEvent(pointerEvent);
1022 TransferPointerEvent(pointerEvent, false);
1023 return WSError::WS_OK;
1024 }
1025
NotifyOutsideDownEvent(const std::shared_ptr<MMI::PointerEvent> & pointerEvent)1026 void SceneSession::NotifyOutsideDownEvent(const std::shared_ptr<MMI::PointerEvent>& pointerEvent)
1027 {
1028 // notify touchOutside and touchDown event
1029 int32_t action = pointerEvent->GetPointerAction();
1030 if (action != MMI::PointerEvent::POINTER_ACTION_DOWN &&
1031 action != MMI::PointerEvent::POINTER_ACTION_BUTTON_DOWN) {
1032 return;
1033 }
1034
1035 MMI::PointerEvent::PointerItem pointerItem;
1036 if (!pointerEvent->GetPointerItem(pointerEvent->GetPointerId(), pointerItem)) {
1037 return;
1038 }
1039
1040 // notify outside down event
1041 if (specificCallback_ != nullptr && specificCallback_->onOutsideDownEvent_) {
1042 specificCallback_->onOutsideDownEvent_(pointerItem.GetDisplayX(), pointerItem.GetDisplayY());
1043 }
1044 }
1045
TransferPointerEvent(const std::shared_ptr<MMI::PointerEvent> & pointerEvent,bool needNotifyClient)1046 WSError SceneSession::TransferPointerEvent(const std::shared_ptr<MMI::PointerEvent>& pointerEvent,
1047 bool needNotifyClient)
1048 {
1049 WLOGFD("[WMSCom] TransferPointEvent, id: %{public}d, type: %{public}d, needNotifyClient: %{public}d",
1050 GetPersistentId(), GetWindowType(), needNotifyClient);
1051 if (pointerEvent == nullptr) {
1052 WLOGFE("pointerEvent is null");
1053 return WSError::WS_ERROR_NULLPTR;
1054 }
1055
1056 int32_t action = pointerEvent->GetPointerAction();
1057 {
1058 bool isSystemWindow = GetSessionInfo().isSystem_;
1059 if (action == MMI::PointerEvent::POINTER_ACTION_ENTER_WINDOW) {
1060 std::lock_guard<std::mutex> guard(enterSessionMutex_);
1061 WLOGFD("Set enter session, persistentId:%{public}d", GetPersistentId());
1062 enterSession_ = wptr<SceneSession>(this);
1063 }
1064 if ((enterSession_ != nullptr) &&
1065 (isSystemWindow && (action != MMI::PointerEvent::POINTER_ACTION_ENTER_WINDOW))) {
1066 std::lock_guard<std::mutex> guard(enterSessionMutex_);
1067 WLOGFD("Remove enter session, persistentId:%{public}d", GetPersistentId());
1068 enterSession_ = nullptr;
1069 }
1070 }
1071
1072 if (!CheckPointerEventDispatch(pointerEvent)) {
1073 WLOGFI("Do not dispatch this pointer event");
1074 return WSError::WS_DO_NOTHING;
1075 }
1076 bool isPointDown = (action == MMI::PointerEvent::POINTER_ACTION_DOWN ||
1077 action == MMI::PointerEvent::POINTER_ACTION_BUTTON_DOWN);
1078 if (specificCallback_ != nullptr && specificCallback_->onSessionTouchOutside_ != nullptr && isPointDown) {
1079 specificCallback_->onSessionTouchOutside_(GetPersistentId());
1080 }
1081
1082 auto property = GetSessionProperty();
1083 if (property == nullptr) {
1084 return Session::TransferPointerEvent(pointerEvent, needNotifyClient);
1085 }
1086
1087 auto windowType = property->GetWindowType();
1088 if (property->GetWindowMode() == WindowMode::WINDOW_MODE_FLOATING &&
1089 (WindowHelper::IsMainWindow(windowType) || WindowHelper::IsSubWindow(windowType)) &&
1090 property->GetMaximizeMode() != MaximizeMode::MODE_AVOID_SYSTEM_BAR) {
1091 if (CheckDialogOnForeground() && isPointDown) {
1092 HandlePointDownDialog();
1093 pointerEvent->MarkProcessed();
1094 WLOGFI("[WMSDialog] There is dialog window foreground");
1095 return WSError::WS_OK;
1096 }
1097 if (!moveDragController_) {
1098 WLOGE("moveDragController_ is null");
1099 return Session::TransferPointerEvent(pointerEvent, needNotifyClient);
1100 }
1101 if (property->GetDragEnabled()) {
1102 auto is2in1 = system::GetParameter("const.product.devicetype", "unknown") == "2in1";
1103 if (is2in1 && moveDragController_->ConsumeDragEvent(pointerEvent, winRect_, property, systemConfig_)) {
1104 moveDragController_->UpdateGravityWhenDrag(pointerEvent, surfaceNode_);
1105 PresentFoucusIfNeed(pointerEvent->GetPointerAction());
1106 pointerEvent->MarkProcessed();
1107 return WSError::WS_OK;
1108 }
1109 }
1110 if (IsDecorEnable() && moveDragController_->ConsumeMoveEvent(pointerEvent, winRect_)) {
1111 PresentFoucusIfNeed(pointerEvent->GetPointerAction());
1112 pointerEvent->MarkProcessed();
1113 return WSError::WS_OK;
1114 }
1115 }
1116
1117 if (property->GetWindowMode() == WindowMode::WINDOW_MODE_PIP &&
1118 WindowHelper::IsPipWindow(property->GetWindowType())) {
1119 if (!moveDragController_) {
1120 WLOGFE("moveDragController is null");
1121 return Session::TransferPointerEvent(pointerEvent, needNotifyClient);
1122 }
1123 if (moveDragController_->ConsumeMoveEvent(pointerEvent, winRect_)) {
1124 pointerEvent->MarkProcessed();
1125 return WSError::WS_OK;
1126 }
1127 }
1128
1129 bool raiseEnabled = property->GetWindowType() == WindowType::WINDOW_TYPE_DIALOG && property->GetRaiseEnabled() &&
1130 (action == MMI::PointerEvent::POINTER_ACTION_DOWN || action == MMI::PointerEvent::POINTER_ACTION_BUTTON_DOWN);
1131 if (raiseEnabled) {
1132 RaiseToAppTopForPointDown();
1133 }
1134 return Session::TransferPointerEvent(pointerEvent, needNotifyClient);
1135 }
1136
RequestSessionBack(bool needMoveToBackground)1137 WSError SceneSession::RequestSessionBack(bool needMoveToBackground)
1138 {
1139 auto task = [weakThis = wptr(this), needMoveToBackground]() {
1140 auto session = weakThis.promote();
1141 if (!session) {
1142 WLOGFE("session is null");
1143 return WSError::WS_ERROR_DESTROYED_OBJECT;
1144 }
1145 if (!session->backPressedFunc_) {
1146 WLOGFW("Session didn't register back event consumer!");
1147 return WSError::WS_DO_NOTHING;
1148 }
1149 if (g_enableForceUIFirst) {
1150 auto rsTransaction = RSTransactionProxy::GetInstance();
1151 if (rsTransaction) {
1152 rsTransaction->Begin();
1153 }
1154 if (session->leashWinSurfaceNode_) {
1155 session->leashWinSurfaceNode_->SetForceUIFirst(true);
1156 WLOGFI("leashWinSurfaceNode_ SetForceUIFirst id:%{public}u!", session->GetPersistentId());
1157 } else {
1158 WLOGFI("failed, leashWinSurfaceNode_ null id:%{public}u", session->GetPersistentId());
1159 }
1160 if (rsTransaction) {
1161 rsTransaction->Commit();
1162 }
1163 }
1164 session->backPressedFunc_(needMoveToBackground);
1165 return WSError::WS_OK;
1166 };
1167 PostTask(task, "RequestSessionBack:" + std::to_string(needMoveToBackground));
1168 return WSError::WS_OK;
1169 }
1170
GetEnterWindow()1171 const wptr<SceneSession> SceneSession::GetEnterWindow()
1172 {
1173 std::lock_guard<std::mutex> guard(enterSessionMutex_);
1174 return enterSession_;
1175 }
1176
ClearEnterWindow()1177 void SceneSession::ClearEnterWindow()
1178 {
1179 std::lock_guard<std::mutex> guard(enterSessionMutex_);
1180 enterSession_ = nullptr;
1181 }
1182
NotifySessionRectChange(const WSRect & rect,const SizeChangeReason & reason)1183 void SceneSession::NotifySessionRectChange(const WSRect& rect, const SizeChangeReason& reason)
1184 {
1185 auto task = [weakThis = wptr(this), rect, reason]() {
1186 auto session = weakThis.promote();
1187 if (!session) {
1188 WLOGFE("session is null");
1189 return;
1190 }
1191 if (session->sessionRectChangeFunc_) {
1192 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER, "SceneSession::NotifySessionRectChange");
1193 session->sessionRectChangeFunc_(rect, reason);
1194 }
1195 };
1196 PostTask(task, "NotifySessionRectChange" + GetRectInfo(rect));
1197 }
1198
IsDecorEnable() const1199 bool SceneSession::IsDecorEnable() const
1200 {
1201 auto property = GetSessionProperty();
1202 if (property == nullptr) {
1203 WLOGE("property is nullptr");
1204 return false;
1205 }
1206 if (property->GetWindowMode() == WindowMode::WINDOW_MODE_FLOATING
1207 && system::GetParameter("const.product.devicetype", "unknown") == "phone") {
1208 /* FloatingWindow skip for Phone */
1209 return false;
1210 }
1211 auto windowType = property->GetWindowType();
1212 return (WindowHelper::IsMainWindow(windowType) ||
1213 (WindowHelper::IsSubWindow(windowType) && property->IsDecorEnable())) &&
1214 systemConfig_.isSystemDecorEnable_ &&
1215 WindowHelper::IsWindowModeSupported(systemConfig_.decorModeSupportInfo_, property->GetWindowMode());
1216 }
1217
GetRatioPreferenceKey()1218 std::string SceneSession::GetRatioPreferenceKey()
1219 {
1220 std::string key = sessionInfo_.bundleName_ + sessionInfo_.moduleName_ + sessionInfo_.abilityName_;
1221 if (key.length() > ScenePersistentStorage::MAX_KEY_LEN) {
1222 return key.substr(key.length() - ScenePersistentStorage::MAX_KEY_LEN);
1223 }
1224 return key;
1225 }
1226
SaveAspectRatio(float ratio)1227 bool SceneSession::SaveAspectRatio(float ratio)
1228 {
1229 std::string key = GetRatioPreferenceKey();
1230 if (!key.empty()) {
1231 ScenePersistentStorage::Insert(key, ratio, ScenePersistentStorageType::ASPECT_RATIO);
1232 WLOGD("SceneSession save aspectRatio , key %{public}s, value: %{public}f", key.c_str(), aspectRatio_);
1233 return true;
1234 }
1235 return false;
1236 }
1237
FixRectByLimits(WindowLimits limits,WSRect & rect,float ratio,bool isDecor,float vpr)1238 void SceneSession::FixRectByLimits(WindowLimits limits, WSRect& rect, float ratio, bool isDecor, float vpr)
1239 {
1240 if (isDecor) {
1241 rect.width_ = SessionUtils::ToLayoutWidth(rect.width_, vpr);
1242 rect.height_ = SessionUtils::ToLayoutHeight(rect.height_, vpr);
1243 limits.minWidth_ = SessionUtils::ToLayoutWidth(limits.minWidth_, vpr);
1244 limits.maxWidth_ = SessionUtils::ToLayoutWidth(limits.maxWidth_, vpr);
1245 limits.minHeight_ = SessionUtils::ToLayoutHeight(limits.minHeight_, vpr);
1246 limits.maxHeight_ = SessionUtils::ToLayoutHeight(limits.maxHeight_, vpr);
1247 }
1248 if (static_cast<uint32_t>(rect.height_) > limits.maxHeight_) {
1249 rect.height_ = static_cast<int32_t>(limits.maxHeight_);
1250 rect.width_ = floor(rect.height_ * ratio);
1251 } else if (static_cast<uint32_t>(rect.width_) > limits.maxWidth_) {
1252 rect.width_ = static_cast<int32_t>(limits.maxWidth_);
1253 rect.height_ = floor(rect.width_ / ratio);
1254 } else if (static_cast<uint32_t>(rect.width_) < limits.minWidth_) {
1255 rect.width_ = static_cast<int32_t>(limits.minWidth_);
1256 rect.height_ = ceil(rect.width_ / ratio);
1257 } else if (static_cast<uint32_t>(rect.height_) < limits.minHeight_) {
1258 rect.height_ = static_cast<int32_t>(limits.minHeight_);
1259 rect.width_ = ceil(rect.height_ * ratio);
1260 }
1261 if (isDecor) {
1262 rect.height_ = SessionUtils::ToWinHeight(rect.height_, vpr) ;
1263 rect.width_ = SessionUtils::ToWinWidth(rect.width_, vpr);
1264 }
1265 }
FixRectByAspectRatio(WSRect & rect)1266 bool SceneSession::FixRectByAspectRatio(WSRect& rect)
1267 {
1268 const int tolerancePx = 2; // 2: tolerance delta pixel value, unit: px
1269 WSRect originalRect = rect;
1270 auto property = GetSessionProperty();
1271 if (!property || property->GetWindowMode() != WindowMode::WINDOW_MODE_FLOATING ||
1272 !WindowHelper::IsMainWindow(GetWindowType())) {
1273 return false;
1274 }
1275
1276 if (MathHelper::NearZero(aspectRatio_)) {
1277 return false;
1278 }
1279 float vpr = 1.5f; // 1.5f: default virtual pixel ratio
1280 auto display = DisplayManager::GetInstance().GetDefaultDisplay();
1281 if (display) {
1282 vpr = display->GetVirtualPixelRatio();
1283 }
1284 int32_t minW;
1285 int32_t maxW;
1286 int32_t minH;
1287 int32_t maxH;
1288 SessionUtils::CalcFloatWindowRectLimits(property->GetWindowLimits(), systemConfig_.maxFloatingWindowSize_, vpr,
1289 minW, maxW, minH, maxH);
1290 rect.width_ = std::max(minW, static_cast<int32_t>(rect.width_));
1291 rect.width_ = std::min(maxW, static_cast<int32_t>(rect.width_));
1292 rect.height_ = std::max(minH, static_cast<int32_t>(rect.height_));
1293 rect.height_ = std::min(maxH, static_cast<int32_t>(rect.height_));
1294 if (IsDecorEnable()) {
1295 if (SessionUtils::ToLayoutWidth(rect.width_, vpr) >
1296 SessionUtils::ToLayoutHeight(rect.height_, vpr) * aspectRatio_) {
1297 rect.width_ = SessionUtils::ToWinWidth(SessionUtils::ToLayoutHeight(rect.height_, vpr)* aspectRatio_, vpr);
1298 } else {
1299 rect.height_ = SessionUtils::ToWinHeight(SessionUtils::ToLayoutWidth(rect.width_, vpr) / aspectRatio_, vpr);
1300 }
1301 } else {
1302 if (rect.width_ > rect.height_ * aspectRatio_) {
1303 rect.width_ = rect.height_ * aspectRatio_;
1304 } else {
1305 rect.height_ = rect.width_ / aspectRatio_;
1306 }
1307 }
1308 FixRectByLimits(property->GetWindowLimits(), rect, aspectRatio_, IsDecorEnable(), vpr);
1309 if (std::abs(static_cast<int32_t>(originalRect.width_) - static_cast<int32_t>(rect.width_)) <= tolerancePx &&
1310 std::abs(static_cast<int32_t>(originalRect.height_) - static_cast<int32_t>(rect.height_)) <= tolerancePx) {
1311 rect = originalRect;
1312 return false;
1313 }
1314 return true;
1315 }
1316
SetMoveDragCallback()1317 void SceneSession::SetMoveDragCallback()
1318 {
1319 if (moveDragController_) {
1320 MoveDragCallback callBack = [this](const SizeChangeReason& reason) {
1321 this->OnMoveDragCallback(reason);
1322 };
1323 moveDragController_->RegisterMoveDragCallback(callBack);
1324 }
1325 }
1326
OnMoveDragCallback(const SizeChangeReason & reason)1327 void SceneSession::OnMoveDragCallback(const SizeChangeReason& reason)
1328 {
1329 WSRect rect = moveDragController_->GetTargetRect();
1330 WLOGFD("OnMoveDragCallback rect: [%{public}d, %{public}d, %{public}u, %{public}u], reason : %{public}d",
1331 rect.posX_, rect.posY_, rect.width_, rect.height_, reason);
1332 if (reason == SizeChangeReason::DRAG || reason == SizeChangeReason::DRAG_END) {
1333 UpdateWinRectForSystemBar(rect);
1334 }
1335 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER,
1336 "SceneSession::OnMoveDragCallback [%d, %d, %u, %u]", rect.posX_, rect.posY_, rect.width_, rect.height_);
1337 SetSurfaceBounds(rect);
1338 OnPiPMoveCallback(rect, reason);
1339 if (reason != SizeChangeReason::MOVE) {
1340 UpdateSizeChangeReason(reason);
1341 UpdateRect(rect, reason);
1342 }
1343 if (reason == SizeChangeReason::DRAG_END) {
1344 NotifySessionRectChange(rect, reason);
1345 OnSessionEvent(SessionEvent::EVENT_END_MOVE);
1346 }
1347 if (reason == SizeChangeReason::DRAG_START) {
1348 OnSessionEvent(SessionEvent::EVENT_DRAG_START);
1349 }
1350 }
1351
UpdateWinRectForSystemBar(WSRect & rect)1352 void SceneSession::UpdateWinRectForSystemBar(WSRect& rect)
1353 {
1354 if (!specificCallback_) {
1355 WLOGFE("specificCallback_ is null!");
1356 return;
1357 }
1358 float tmpPosY = 0.0;
1359 std::vector<sptr<SceneSession>> statusBarVector =
1360 specificCallback_->onGetSceneSessionVectorByType_(WindowType::WINDOW_TYPE_STATUS_BAR);
1361 for (auto& statusBar : statusBarVector) {
1362 if (!(statusBar->isVisible_)) {
1363 continue;
1364 }
1365 WSRect statusBarRect = statusBar->GetSessionRect();
1366 if ((rect.posY_ < statusBarRect.posY_ + static_cast<int32_t>(statusBarRect.height_)) &&
1367 (rect.height_ != winRect_.height_ || rect.width_ != winRect_.width_)) {
1368 tmpPosY = rect.posY_ + rect.height_;
1369 rect.posY_ = statusBarRect.posY_ + statusBarRect.height_;
1370 rect.height_ = tmpPosY - rect.posY_;
1371 }
1372 }
1373 WLOGFD("after UpdateWinRectForSystemBar rect: [%{public}d, %{public}d, %{public}u, %{public}u]",
1374 rect.posX_, rect.posY_, rect.width_, rect.height_);
1375 }
1376
SetSurfaceBounds(const WSRect & rect)1377 void SceneSession::SetSurfaceBounds(const WSRect& rect)
1378 {
1379 auto rsTransaction = RSTransactionProxy::GetInstance();
1380 if (rsTransaction) {
1381 rsTransaction->Begin();
1382 }
1383 if (surfaceNode_ && leashWinSurfaceNode_) {
1384 leashWinSurfaceNode_->SetBounds(rect.posX_, rect.posY_, rect.width_, rect.height_);
1385 leashWinSurfaceNode_->SetFrame(rect.posX_, rect.posY_, rect.width_, rect.height_);
1386 surfaceNode_->SetBounds(0, 0, rect.width_, rect.height_);
1387 surfaceNode_->SetFrame(0, 0, rect.width_, rect.height_);
1388 } else if (WindowHelper::IsPipWindow(GetWindowType()) && surfaceNode_) {
1389 WLOGFD("PipWindow setSurfaceBounds");
1390 surfaceNode_->SetBounds(rect.posX_, rect.posY_, rect.width_, rect.height_);
1391 surfaceNode_->SetFrame(rect.posX_, rect.posY_, rect.width_, rect.height_);
1392 } else if (WindowHelper::IsSubWindow(GetWindowType()) && surfaceNode_) {
1393 WLOGFD("subwindow setSurfaceBounds");
1394 surfaceNode_->SetBounds(rect.posX_, rect.posY_, rect.width_, rect.height_);
1395 surfaceNode_->SetFrame(rect.posX_, rect.posY_, rect.width_, rect.height_);
1396 } else {
1397 WLOGE("SetSurfaceBounds surfaceNode is null!");
1398 }
1399 if (rsTransaction) {
1400 rsTransaction->Commit();
1401 }
1402 }
1403
SetZOrder(uint32_t zOrder)1404 void SceneSession::SetZOrder(uint32_t zOrder)
1405 {
1406 auto task = [weakThis = wptr(this), zOrder]() {
1407 auto session = weakThis.promote();
1408 if (session == nullptr) {
1409 WLOGFE("session is null");
1410 return;
1411 }
1412 if (session->zOrder_ != zOrder) {
1413 session->Session::SetZOrder(zOrder);
1414 if (session->specificCallback_ != nullptr) {
1415 session->specificCallback_->onWindowInfoUpdate_(session->GetPersistentId(),
1416 WindowUpdateType::WINDOW_UPDATE_PROPERTY);
1417 }
1418 }
1419 };
1420 PostTask(task, "SetZOrder");
1421 }
1422
SetFloatingScale(float floatingScale)1423 void SceneSession::SetFloatingScale(float floatingScale)
1424 {
1425 if (floatingScale_ != floatingScale) {
1426 Session::SetFloatingScale(floatingScale);
1427 if (specificCallback_ != nullptr) {
1428 specificCallback_->onWindowInfoUpdate_(GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_PROPERTY);
1429 specificCallback_->onUpdateAvoidArea_(GetPersistentId());
1430 }
1431 }
1432 }
1433
SetParentPersistentId(int32_t parentId)1434 void SceneSession::SetParentPersistentId(int32_t parentId)
1435 {
1436 auto property = GetSessionProperty();
1437 if (property) {
1438 property->SetParentPersistentId(parentId);
1439 }
1440 }
1441
GetParentPersistentId() const1442 int32_t SceneSession::GetParentPersistentId() const
1443 {
1444 auto property = GetSessionProperty();
1445 if (property) {
1446 return property->GetParentPersistentId();
1447 }
1448 return INVALID_SESSION_ID;
1449 }
1450
GetWindowName() const1451 const std::string& SceneSession::GetWindowName() const
1452 {
1453 return GetSessionProperty()->GetWindowName();
1454 }
1455
GetWindowNameAllType() const1456 const std::string& SceneSession::GetWindowNameAllType() const
1457 {
1458 if (GetSessionInfo().isSystem_) {
1459 return GetSessionInfo().abilityName_;
1460 } else {
1461 return GetWindowName();
1462 }
1463 }
1464
SetTurnScreenOn(bool turnScreenOn)1465 WSError SceneSession::SetTurnScreenOn(bool turnScreenOn)
1466 {
1467 GetSessionProperty()->SetTurnScreenOn(turnScreenOn);
1468 return WSError::WS_OK;
1469 }
1470
IsTurnScreenOn() const1471 bool SceneSession::IsTurnScreenOn() const
1472 {
1473 return GetSessionProperty()->IsTurnScreenOn();
1474 }
1475
SetKeepScreenOn(bool keepScreenOn)1476 WSError SceneSession::SetKeepScreenOn(bool keepScreenOn)
1477 {
1478 GetSessionProperty()->SetKeepScreenOn(keepScreenOn);
1479 return WSError::WS_OK;
1480 }
1481
IsKeepScreenOn() const1482 bool SceneSession::IsKeepScreenOn() const
1483 {
1484 return GetSessionProperty()->IsKeepScreenOn();
1485 }
1486
GetSessionSnapshotFilePath() const1487 std::string SceneSession::GetSessionSnapshotFilePath() const
1488 {
1489 WLOGFI("GetSessionSnapshotFilePath id %{public}d", GetPersistentId());
1490 if (Session::GetSessionState() < SessionState::STATE_BACKGROUND) {
1491 WLOGFI("GetSessionSnapshotFilePath UpdateSnapshot");
1492 auto snapshot = Snapshot();
1493 if (scenePersistence_ != nullptr) {
1494 scenePersistence_->SaveSnapshot(snapshot);
1495 }
1496 }
1497 if (scenePersistence_ != nullptr) {
1498 return scenePersistence_->GetSnapshotFilePath();
1499 }
1500 return "";
1501 }
1502
SaveUpdatedIcon(const std::shared_ptr<Media::PixelMap> & icon)1503 void SceneSession::SaveUpdatedIcon(const std::shared_ptr<Media::PixelMap> &icon)
1504 {
1505 WLOGFI("run SaveUpdatedIcon");
1506 if (scenePersistence_ != nullptr) {
1507 scenePersistence_->SaveUpdatedIcon(icon);
1508 }
1509 }
1510
GetUpdatedIconPath() const1511 std::string SceneSession::GetUpdatedIconPath() const
1512 {
1513 WLOGFI("run GetUpdatedIconPath");
1514 if (scenePersistence_ != nullptr) {
1515 return scenePersistence_->GetUpdatedIconPath();
1516 }
1517 return "";
1518 }
1519
UpdateNativeVisibility(bool visible)1520 void SceneSession::UpdateNativeVisibility(bool visible)
1521 {
1522 WLOGFI("[WMSSCB] name: %{public}s, id: %{public}u, visible: %{public}u",
1523 sessionInfo_.bundleName_.c_str(), GetPersistentId(), visible);
1524 isVisible_ = visible;
1525 if (specificCallback_ == nullptr) {
1526 WLOGFW("specific callback is null.");
1527 return;
1528 }
1529
1530 if (visible) {
1531 specificCallback_->onWindowInfoUpdate_(GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_ADDED);
1532 } else {
1533 specificCallback_->onWindowInfoUpdate_(GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_REMOVED);
1534 }
1535 NotifyAccessibilityVisibilityChange();
1536 specificCallback_->onUpdateAvoidArea_(GetPersistentId());
1537 // update private state
1538 if (!GetSessionProperty()) {
1539 WLOGFE("UpdateNativeVisibility property is null");
1540 return;
1541 }
1542 }
1543
IsVisible() const1544 bool SceneSession::IsVisible() const
1545 {
1546 return isVisible_;
1547 }
1548
UpdateRotationAvoidArea()1549 void SceneSession::UpdateRotationAvoidArea()
1550 {
1551 if (specificCallback_) {
1552 specificCallback_->onUpdateAvoidArea_(GetPersistentId());
1553 }
1554 }
1555
SetPrivacyMode(bool isPrivacy)1556 void SceneSession::SetPrivacyMode(bool isPrivacy)
1557 {
1558 auto property = GetSessionProperty();
1559 if (!property) {
1560 WLOGFE("SetPrivacyMode property is null");
1561 return;
1562 }
1563 if (!surfaceNode_) {
1564 WLOGFE("surfaceNode_ is null");
1565 return;
1566 }
1567 bool lastPrivacyMode = property->GetPrivacyMode() || property->GetSystemPrivacyMode();
1568 if (lastPrivacyMode == isPrivacy) {
1569 WLOGFW("privacy mode is not change, do nothing, isPrivacy:%{public}d", isPrivacy);
1570 return;
1571 }
1572 property->SetPrivacyMode(isPrivacy);
1573 property->SetSystemPrivacyMode(isPrivacy);
1574 surfaceNode_->SetSecurityLayer(isPrivacy);
1575 if (leashWinSurfaceNode_ != nullptr) {
1576 leashWinSurfaceNode_->SetSecurityLayer(isPrivacy);
1577 }
1578 RSTransaction::FlushImplicitTransaction();
1579 }
1580
SetSystemSceneOcclusionAlpha(double alpha)1581 void SceneSession::SetSystemSceneOcclusionAlpha(double alpha)
1582 {
1583 if (alpha < 0 || alpha > 1.0) {
1584 WLOGFE("OnSetSystemSceneOcclusionAlpha property is null");
1585 return;
1586 }
1587 if (!surfaceNode_) {
1588 WLOGFE("surfaceNode_ is null");
1589 return;
1590 }
1591 uint8_t alpha8bit = static_cast<uint8_t>(alpha * 255);
1592 WLOGFI("surfaceNode SetAbilityBGAlpha=%{public}u.", alpha8bit);
1593 surfaceNode_->SetAbilityBGAlpha(alpha8bit);
1594 if (leashWinSurfaceNode_ != nullptr) {
1595 leashWinSurfaceNode_->SetAbilityBGAlpha(alpha8bit);
1596 }
1597 RSTransaction::FlushImplicitTransaction();
1598 }
1599
UpdateWindowAnimationFlag(bool needDefaultAnimationFlag)1600 WSError SceneSession::UpdateWindowAnimationFlag(bool needDefaultAnimationFlag)
1601 {
1602 auto task = [weakThis = wptr(this), needDefaultAnimationFlag]() {
1603 auto session = weakThis.promote();
1604 if (!session) {
1605 WLOGFE("session is null");
1606 return WSError::WS_ERROR_DESTROYED_OBJECT;
1607 }
1608 session->needDefaultAnimationFlag_ = needDefaultAnimationFlag;
1609 if (session->sessionChangeCallback_ && session->sessionChangeCallback_->onWindowAnimationFlagChange_) {
1610 session->sessionChangeCallback_->onWindowAnimationFlagChange_(needDefaultAnimationFlag);
1611 }
1612 return WSError::WS_OK;
1613 };
1614 return PostSyncTask(task, "UpdateWindowAnimationFlag");
1615 }
1616
SetWindowAnimationFlag(bool needDefaultAnimationFlag)1617 void SceneSession::SetWindowAnimationFlag(bool needDefaultAnimationFlag)
1618 {
1619 needDefaultAnimationFlag_ = needDefaultAnimationFlag;
1620 if (sessionChangeCallback_ && sessionChangeCallback_->onWindowAnimationFlagChange_) {
1621 sessionChangeCallback_->onWindowAnimationFlagChange_(needDefaultAnimationFlag);
1622 }
1623 return;
1624 }
1625
IsNeedDefaultAnimation() const1626 bool SceneSession::IsNeedDefaultAnimation() const
1627 {
1628 return needDefaultAnimationFlag_;
1629 }
1630
IsAppSession() const1631 bool SceneSession::IsAppSession() const
1632 {
1633 if (GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
1634 return true;
1635 }
1636 if (GetParentSession() && GetParentSession()->GetWindowType() == WindowType::WINDOW_TYPE_APP_MAIN_WINDOW) {
1637 return true;
1638 }
1639 return false;
1640 }
1641
NotifyIsCustomAnimationPlaying(bool isPlaying)1642 void SceneSession::NotifyIsCustomAnimationPlaying(bool isPlaying)
1643 {
1644 WLOGFI("id %{public}d %{public}u", GetPersistentId(), isPlaying);
1645 if (sessionChangeCallback_ != nullptr && sessionChangeCallback_->onIsCustomAnimationPlaying_) {
1646 sessionChangeCallback_->onIsCustomAnimationPlaying_(isPlaying);
1647 }
1648 }
1649
UpdateWindowSceneAfterCustomAnimation(bool isAdd)1650 WSError SceneSession::UpdateWindowSceneAfterCustomAnimation(bool isAdd)
1651 {
1652 if (!SessionPermission::IsSystemCalling()) {
1653 WLOGFE("[WMSSystem]failed to update with id:%{public}u!", GetPersistentId());
1654 return WSError::WS_ERROR_NOT_SYSTEM_APP;
1655 }
1656 auto task = [weakThis = wptr(this), isAdd]() {
1657 auto session = weakThis.promote();
1658 if (!session) {
1659 WLOGFE("session is null");
1660 return WSError::WS_ERROR_DESTROYED_OBJECT;
1661 }
1662 WLOGFI("UpdateWindowSceneAfterCustomAnimation, id %{public}d, isAdd: %{public}d",
1663 session->GetPersistentId(), isAdd);
1664 if (isAdd) {
1665 WLOGFE("SetOpacityFunc not register %{public}d", session->GetPersistentId());
1666 return WSError::WS_ERROR_INVALID_OPERATION;
1667 } else {
1668 WLOGFI("background after custom animation id %{public}d", session->GetPersistentId());
1669 // since background will remove surfaceNode
1670 session->Background();
1671 session->NotifyIsCustomAnimationPlaying(false);
1672 }
1673 return WSError::WS_OK;
1674 };
1675 PostTask(task, "UpdateWindowSceneAfterCustomAnimation:" + std::to_string(isAdd));
1676 return WSError::WS_OK;
1677 }
1678
IsFloatingWindowAppType() const1679 bool SceneSession::IsFloatingWindowAppType() const
1680 {
1681 auto property = GetSessionProperty();
1682 if (property == nullptr) {
1683 return false;
1684 }
1685 return property->IsFloatingWindowAppType();
1686 }
1687
GetTouchHotAreas() const1688 std::vector<Rect> SceneSession::GetTouchHotAreas() const
1689 {
1690 std::vector<Rect> touchHotAreas;
1691 auto property = GetSessionProperty();
1692 if (property) {
1693 property->GetTouchHotAreas(touchHotAreas);
1694 }
1695 return touchHotAreas;
1696 }
1697
DumpSessionElementInfo(const std::vector<std::string> & params)1698 void SceneSession::DumpSessionElementInfo(const std::vector<std::string>& params)
1699 {
1700 if (!sessionStage_) {
1701 return;
1702 }
1703 return sessionStage_->DumpSessionElementInfo(params);
1704 }
1705
NotifyTouchOutside()1706 void SceneSession::NotifyTouchOutside()
1707 {
1708 WLOGFI("id: %{public}d, type: %{public}d", GetPersistentId(), GetWindowType());
1709 if (sessionStage_) {
1710 WLOGFD("Notify sessionStage TouchOutside");
1711 sessionStage_->NotifyTouchOutside();
1712 }
1713 if (sessionChangeCallback_ && sessionChangeCallback_->OnTouchOutside_) {
1714 WLOGFD("Notify sessionChangeCallback TouchOutside");
1715 sessionChangeCallback_->OnTouchOutside_();
1716 }
1717 }
1718
NotifyWindowVisibility()1719 void SceneSession::NotifyWindowVisibility()
1720 {
1721 if (sessionStage_) {
1722 sessionStage_->NotifyWindowVisibility(GetVisible());
1723 } else {
1724 WLOGFE("Notify window(id:%{public}d) visibility failed, for this session stage is nullptr", GetPersistentId());
1725 }
1726 }
1727
CheckOutTouchOutsideRegister()1728 bool SceneSession::CheckOutTouchOutsideRegister()
1729 {
1730 if (sessionChangeCallback_ && sessionChangeCallback_->OnTouchOutside_) {
1731 return true;
1732 }
1733 return false;
1734 }
1735
SetRequestedOrientation(Orientation orientation)1736 void SceneSession::SetRequestedOrientation(Orientation orientation)
1737 {
1738 WLOGFI("id: %{public}d orientation: %{public}u", GetPersistentId(), static_cast<uint32_t>(orientation));
1739 GetSessionProperty()->SetRequestedOrientation(orientation);
1740 if (sessionChangeCallback_ && sessionChangeCallback_->OnRequestedOrientationChange_) {
1741 sessionChangeCallback_->OnRequestedOrientationChange_(static_cast<uint32_t>(orientation));
1742 }
1743 }
1744
NotifyForceHideChange(bool hide)1745 void SceneSession::NotifyForceHideChange(bool hide)
1746 {
1747 WLOGFI("id: %{public}d forceHide: %{public}u", persistentId_, hide);
1748 auto property = GetSessionProperty();
1749 if (property == nullptr) {
1750 WLOGFD("id: %{public}d property is nullptr", persistentId_);
1751 return;
1752 }
1753 property->SetForceHide(hide);
1754 if (sessionChangeCallback_ && sessionChangeCallback_->OnForceHideChange_) {
1755 sessionChangeCallback_->OnForceHideChange_(hide);
1756 }
1757 }
1758
GetRequestedOrientation() const1759 Orientation SceneSession::GetRequestedOrientation() const
1760 {
1761 return GetSessionProperty()->GetRequestedOrientation();
1762 }
1763
GetCollaboratorType() const1764 int32_t SceneSession::GetCollaboratorType() const
1765 {
1766 return collaboratorType_;
1767 }
1768
SetCollaboratorType(int32_t collaboratorType)1769 void SceneSession::SetCollaboratorType(int32_t collaboratorType)
1770 {
1771 collaboratorType_ = collaboratorType;
1772 sessionInfo_.collaboratorType_ = collaboratorType;
1773 }
1774
DumpSessionInfo(std::vector<std::string> & info) const1775 void SceneSession::DumpSessionInfo(std::vector<std::string> &info) const
1776 {
1777 std::string dumpInfo = " Session ID #" + std::to_string(persistentId_);
1778 info.push_back(dumpInfo);
1779 dumpInfo = " session name [" + SessionUtils::ConvertSessionName(sessionInfo_.bundleName_,
1780 sessionInfo_.abilityName_, sessionInfo_.moduleName_, sessionInfo_.appIndex_) + "]";
1781 info.push_back(dumpInfo);
1782 dumpInfo = " runningState [" + std::string(isActive_ ? "FOREGROUND" : "BACKGROUND") + "]";
1783 info.push_back(dumpInfo);
1784 dumpInfo = " lockedState [" + std::to_string(sessionInfo_.lockedState) + "]";
1785 info.push_back(dumpInfo);
1786 auto abilityInfo = sessionInfo_.abilityInfo;
1787 dumpInfo = " continuable [" + (abilityInfo ? std::to_string(abilityInfo->continuable) : " ") + "]";
1788 info.push_back(dumpInfo);
1789 dumpInfo = " timeStamp [" + sessionInfo_.time + "]";
1790 info.push_back(dumpInfo);
1791 dumpInfo = " label [" + (abilityInfo ? abilityInfo->label : " ") + "]";
1792 info.push_back(dumpInfo);
1793 dumpInfo = " iconPath [" + (abilityInfo ? abilityInfo->iconPath : " ") + "]";
1794 info.push_back(dumpInfo);
1795 dumpInfo = " want [" + (sessionInfo_.want ? sessionInfo_.want->ToUri() : " ") + "]";
1796 info.push_back(dumpInfo);
1797 }
1798
GetAbilityInfo() const1799 std::shared_ptr<AppExecFwk::AbilityInfo> SceneSession::GetAbilityInfo() const
1800 {
1801 const SessionInfo& sessionInfo = GetSessionInfo();
1802 return sessionInfo.abilityInfo;
1803 }
1804
SetAbilitySessionInfo(std::shared_ptr<AppExecFwk::AbilityInfo> abilityInfo)1805 void SceneSession::SetAbilitySessionInfo(std::shared_ptr<AppExecFwk::AbilityInfo> abilityInfo)
1806 {
1807 SetSessionInfoAbilityInfo(abilityInfo);
1808 }
1809
SetSelfToken(sptr<IRemoteObject> selfToken)1810 void SceneSession::SetSelfToken(sptr<IRemoteObject> selfToken)
1811 {
1812 selfToken_ = selfToken;
1813 }
1814
GetSelfToken() const1815 sptr<IRemoteObject> SceneSession::GetSelfToken() const
1816 {
1817 return selfToken_;
1818 }
1819
SetSessionState(SessionState state)1820 void SceneSession::SetSessionState(SessionState state)
1821 {
1822 Session::SetSessionState(state);
1823 NotifyAccessibilityVisibilityChange();
1824 }
1825
UpdateSessionState(SessionState state)1826 void SceneSession::UpdateSessionState(SessionState state)
1827 {
1828 Session::UpdateSessionState(state);
1829 NotifyAccessibilityVisibilityChange();
1830 }
1831
IsVisibleForAccessibility() const1832 bool SceneSession::IsVisibleForAccessibility() const
1833 {
1834 return GetSystemTouchable() && GetForegroundInteractiveStatus() &&
1835 (IsVisible() || state_ == SessionState::STATE_ACTIVE || state_ == SessionState::STATE_FOREGROUND);
1836 }
1837
SetForegroundInteractiveStatus(bool interactive)1838 void SceneSession::SetForegroundInteractiveStatus(bool interactive)
1839 {
1840 Session::SetForegroundInteractiveStatus(interactive);
1841 NotifyAccessibilityVisibilityChange();
1842 }
1843
NotifyAccessibilityVisibilityChange()1844 void SceneSession::NotifyAccessibilityVisibilityChange()
1845 {
1846 bool isVisibleForAccessibilityNew = IsVisibleForAccessibility();
1847 if (isVisibleForAccessibilityNew == isVisibleForAccessibility_.load()) {
1848 return;
1849 }
1850 WLOGFD("[WMSAccess] NotifyAccessibilityVisibilityChange id: %{public}d, visible: %{public}d",
1851 GetPersistentId(), isVisibleForAccessibilityNew);
1852 isVisibleForAccessibility_.store(isVisibleForAccessibilityNew);
1853 if (specificCallback_ && specificCallback_->onWindowInfoUpdate_) {
1854 if (isVisibleForAccessibilityNew) {
1855 specificCallback_->onWindowInfoUpdate_(GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_ADDED);
1856 } else {
1857 specificCallback_->onWindowInfoUpdate_(GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_REMOVED);
1858 }
1859 } else {
1860 WLOGFD("specificCallback_->onWindowInfoUpdate_ not exist, persistent id: %{public}d", GetPersistentId());
1861 }
1862 }
1863
SetSystemTouchable(bool touchable)1864 void SceneSession::SetSystemTouchable(bool touchable)
1865 {
1866 Session::SetSystemTouchable(touchable);
1867 NotifyAccessibilityVisibilityChange();
1868 }
1869
PendingSessionActivation(const sptr<AAFwk::SessionInfo> abilitySessionInfo)1870 WSError SceneSession::PendingSessionActivation(const sptr<AAFwk::SessionInfo> abilitySessionInfo)
1871 {
1872 if (!SessionPermission::VerifySessionPermission()) {
1873 WLOGFE("The interface permission failed.");
1874 return WSError::WS_ERROR_INVALID_PERMISSION;
1875 }
1876 auto task = [weakThis = wptr(this), abilitySessionInfo]() {
1877 auto session = weakThis.promote();
1878 if (!session) {
1879 WLOGFE("session is null");
1880 return WSError::WS_ERROR_DESTROYED_OBJECT;
1881 }
1882 if (abilitySessionInfo == nullptr) {
1883 WLOGFE("abilitySessionInfo is null");
1884 return WSError::WS_ERROR_NULLPTR;
1885 }
1886 session->sessionInfo_.startMethod = StartMethod::START_CALL;
1887
1888 SessionInfo info;
1889 info.abilityName_ = abilitySessionInfo->want.GetElement().GetAbilityName();
1890 info.bundleName_ = abilitySessionInfo->want.GetElement().GetBundleName();
1891 info.moduleName_ = abilitySessionInfo->want.GetModuleName();
1892 info.appIndex_ = abilitySessionInfo->want.GetIntParam(DLP_INDEX, 0);
1893 info.persistentId_ = abilitySessionInfo->persistentId;
1894 info.callerPersistentId_ = session->GetPersistentId();
1895 info.callState_ = static_cast<uint32_t>(abilitySessionInfo->state);
1896 info.uiAbilityId_ = abilitySessionInfo->uiAbilityId;
1897 info.want = std::make_shared<AAFwk::Want>(abilitySessionInfo->want);
1898 info.requestCode = abilitySessionInfo->requestCode;
1899 info.callerToken_ = abilitySessionInfo->callerToken;
1900 info.startSetting = abilitySessionInfo->startSetting;
1901 info.callingTokenId_ = abilitySessionInfo->callingTokenId;
1902 info.reuse = abilitySessionInfo->reuse;
1903 if (info.want != nullptr) {
1904 info.windowMode = info.want->GetIntParam(AAFwk::Want::PARAM_RESV_WINDOW_MODE, 0);
1905 info.sessionAffinity = info.want->GetStringParam(Rosen::PARAM_KEY::PARAM_MISSION_AFFINITY_KEY);
1906 info.screenId_ = info.want->GetIntParam(AAFwk::Want::PARAM_RESV_DISPLAY_ID, -1);
1907 WLOGFI("[WMSLife]PendingSessionActivation: want screenId %{public}" PRIu64 " uri: %{public}s",
1908 info.screenId_, info.want->GetElement().GetURI().c_str());
1909 }
1910
1911 WLOGFI("PendingSessionActivation:bundleName %{public}s, moduleName:%{public}s, abilityName:%{public}s, \
1912 appIndex:%{public}d, affinity:%{public}s", info.bundleName_.c_str(), info.moduleName_.c_str(),
1913 info.abilityName_.c_str(), info.appIndex_, info.sessionAffinity.c_str());
1914 WLOGFI("PendingSessionActivation callState:%{public}d, want persistentId: %{public}d, "
1915 "callingTokenId:%{public}d, uiAbilityId: %{public}" PRIu64
1916 ", windowMode: %{public}d, caller persistentId: %{public}d",
1917 info.callState_, info.persistentId_, info.callingTokenId_, info.uiAbilityId_,
1918 info.windowMode, info.callerPersistentId_);
1919 if (session->pendingSessionActivationFunc_) {
1920 session->pendingSessionActivationFunc_(info);
1921 }
1922 return WSError::WS_OK;
1923 };
1924 PostTask(task, "PendingSessionActivation");
1925 return WSError::WS_OK;
1926 }
1927
TerminateSession(const sptr<AAFwk::SessionInfo> abilitySessionInfo)1928 WSError SceneSession::TerminateSession(const sptr<AAFwk::SessionInfo> abilitySessionInfo)
1929 {
1930 auto task = [weakThis = wptr(this), abilitySessionInfo]() {
1931 auto session = weakThis.promote();
1932 if (!session) {
1933 WLOGFE("session is null");
1934 return WSError::WS_ERROR_DESTROYED_OBJECT;
1935 }
1936 if (abilitySessionInfo == nullptr) {
1937 WLOGFE("abilitySessionInfo is null");
1938 return WSError::WS_ERROR_NULLPTR;
1939 }
1940 if (session->isTerminating) {
1941 WLOGFE("TerminateSession isTerminating, return!");
1942 return WSError::WS_ERROR_INVALID_OPERATION;
1943 }
1944 session->isTerminating = true;
1945 SessionInfo info;
1946 info.abilityName_ = abilitySessionInfo->want.GetElement().GetAbilityName();
1947 info.bundleName_ = abilitySessionInfo->want.GetElement().GetBundleName();
1948 info.callerToken_ = abilitySessionInfo->callerToken;
1949 info.persistentId_ = static_cast<int32_t>(abilitySessionInfo->persistentId);
1950 {
1951 std::lock_guard<std::recursive_mutex> lock(session->sessionInfoMutex_);
1952 session->sessionInfo_.closeAbilityWant = std::make_shared<AAFwk::Want>(abilitySessionInfo->want);
1953 session->sessionInfo_.resultCode = abilitySessionInfo->resultCode;
1954 }
1955 if (session->terminateSessionFunc_) {
1956 session->terminateSessionFunc_(info);
1957 }
1958 return WSError::WS_OK;
1959 };
1960 PostLifeCycleTask(task, "TerminateSession", LifeCycleTaskType::STOP);
1961 return WSError::WS_OK;
1962 }
1963
NotifySessionException(const sptr<AAFwk::SessionInfo> abilitySessionInfo,bool needRemoveSession)1964 WSError SceneSession::NotifySessionException(const sptr<AAFwk::SessionInfo> abilitySessionInfo, bool needRemoveSession)
1965 {
1966 if (!SessionPermission::VerifySessionPermission()) {
1967 WLOGFE("The interface permission failed.");
1968 return WSError::WS_ERROR_INVALID_PERMISSION;
1969 }
1970 auto task = [weakThis = wptr(this), abilitySessionInfo, needRemoveSession]() {
1971 auto session = weakThis.promote();
1972 if (!session) {
1973 WLOGFE("session is null");
1974 return WSError::WS_ERROR_DESTROYED_OBJECT;
1975 }
1976 if (abilitySessionInfo == nullptr) {
1977 WLOGFE("abilitySessionInfo is null");
1978 return WSError::WS_ERROR_NULLPTR;
1979 }
1980 if (session->isTerminating) {
1981 WLOGFE("NotifySessionException isTerminating, return!");
1982 return WSError::WS_ERROR_INVALID_OPERATION;
1983 }
1984 session->isTerminating = true;
1985 SessionInfo info;
1986 info.abilityName_ = abilitySessionInfo->want.GetElement().GetAbilityName();
1987 info.bundleName_ = abilitySessionInfo->want.GetElement().GetBundleName();
1988 info.callerToken_ = abilitySessionInfo->callerToken;
1989 info.errorCode = abilitySessionInfo->errorCode;
1990 info.errorReason = abilitySessionInfo->errorReason;
1991 info.persistentId_ = static_cast<int32_t>(abilitySessionInfo->persistentId);
1992 {
1993 std::lock_guard<std::recursive_mutex> lock(session->sessionInfoMutex_);
1994 session->sessionInfo_.closeAbilityWant = std::make_shared<AAFwk::Want>(abilitySessionInfo->want);
1995 session->sessionInfo_.errorCode = abilitySessionInfo->errorCode;
1996 session->sessionInfo_.errorReason = abilitySessionInfo->errorReason;
1997 }
1998 if (session->sessionExceptionFunc_) {
1999 auto exceptionFunc = *(session->sessionExceptionFunc_);
2000 exceptionFunc(info, needRemoveSession);
2001 }
2002 if (session->jsSceneSessionExceptionFunc_) {
2003 auto exceptionFunc = *(session->jsSceneSessionExceptionFunc_);
2004 exceptionFunc(info, needRemoveSession);
2005 }
2006 return WSError::WS_OK;
2007 };
2008 PostLifeCycleTask(task, "NotifySessionException", LifeCycleTaskType::STOP);
2009 return WSError::WS_OK;
2010 }
2011
GetLastSafeRect() const2012 WSRect SceneSession::GetLastSafeRect() const
2013 {
2014 return lastSafeRect;
2015 }
2016
SetLastSafeRect(WSRect rect)2017 void SceneSession::SetLastSafeRect(WSRect rect)
2018 {
2019 lastSafeRect.posX_ = rect.posX_;
2020 lastSafeRect.posY_ = rect.posY_;
2021 lastSafeRect.width_ = rect.width_;
2022 lastSafeRect.height_ = rect.height_;
2023 return;
2024 }
2025
AddSubSession(const sptr<SceneSession> & subSession)2026 bool SceneSession::AddSubSession(const sptr<SceneSession>& subSession)
2027 {
2028 if (subSession == nullptr) {
2029 WLOGFE("[WMSSub] subSession is nullptr");
2030 return false;
2031 }
2032 const auto& persistentId = subSession->GetPersistentId();
2033 auto iter = std::find_if(subSession_.begin(), subSession_.end(),
2034 [persistentId](sptr<SceneSession> session) {
2035 bool res = (session != nullptr && session->GetPersistentId() == persistentId) ? true : false;
2036 return res;
2037 });
2038 if (iter != subSession_.end()) {
2039 WLOGFE("[WMSSub] Sub ession is already exists, id: %{public}d, parentId: %{public}d",
2040 subSession->GetPersistentId(), GetPersistentId());
2041 return false;
2042 }
2043 WLOGFD("[WMSSub] Success, id: %{public}d, parentId: %{public}d", subSession->GetPersistentId(), GetPersistentId());
2044 subSession_.push_back(subSession);
2045 return true;
2046 }
2047
RemoveSubSession(int32_t persistentId)2048 bool SceneSession::RemoveSubSession(int32_t persistentId)
2049 {
2050 auto iter = std::find_if(subSession_.begin(), subSession_.end(),
2051 [persistentId](sptr<SceneSession> session) {
2052 bool res = (session != nullptr && session->GetPersistentId() == persistentId) ? true : false;
2053 return res;
2054 });
2055 if (iter == subSession_.end()) {
2056 WLOGFE("[WMSSub] Could not find subsession, id: %{public}d, parentId: %{public}d",
2057 persistentId, GetPersistentId());
2058 return false;
2059 }
2060 WLOGFD("[WMSSub] Success, id: %{public}d, parentId: %{public}d", persistentId, GetPersistentId());
2061 subSession_.erase(iter);
2062 return true;
2063 }
2064
NotifyPiPWindowPrepareClose()2065 void SceneSession::NotifyPiPWindowPrepareClose()
2066 {
2067 WLOGFD("NotifyPiPWindowPrepareClose");
2068 auto task = [weakThis = wptr(this)]() {
2069 auto session = weakThis.promote();
2070 if (!session) {
2071 WLOGFE("session is null");
2072 return;
2073 }
2074 if (session->sessionChangeCallback_ && session->sessionChangeCallback_->onPrepareClosePiPSession_) {
2075 session->sessionChangeCallback_->onPrepareClosePiPSession_();
2076 }
2077 WLOGFD("NotifyPiPWindowPrepareClose, id: %{public}d", session->GetPersistentId());
2078 return;
2079 };
2080 PostTask(task, "NotifyPiPWindowPrepareClose");
2081 }
2082
RecoveryPullPiPMainWindow(int32_t persistentId,const Rect & rect)2083 WSError SceneSession::RecoveryPullPiPMainWindow(int32_t persistentId, const Rect& rect)
2084 {
2085 WLOGFD("NotifyRecoveryPullPiPMainWindow");
2086 auto task = [weakThis = wptr(this), persistentId, rect]() {
2087 auto session = weakThis.promote();
2088 if (!session) {
2089 WLOGFE("session is null");
2090 return WSError::WS_ERROR_DESTROYED_OBJECT;
2091 }
2092 if (session->specificCallback_ != nullptr) {
2093 session->specificCallback_->onRecoveryPullPiPMainWindow_(persistentId, rect);
2094 }
2095 return WSError::WS_OK;
2096 };
2097 PostTask(task, "RecoveryPullPiPMainWindow");
2098 return WSError::WS_OK;
2099 }
2100
GetSubSession() const2101 std::vector<sptr<SceneSession>> SceneSession::GetSubSession() const
2102 {
2103 return subSession_;
2104 }
2105
GetSessionTargetRect() const2106 WSRect SceneSession::GetSessionTargetRect() const
2107 {
2108 WSRect rect;
2109 if (moveDragController_) {
2110 rect = moveDragController_->GetTargetRect();
2111 } else {
2112 WLOGFI("moveDragController_ is null");
2113 }
2114 return rect;
2115 }
2116
SetWindowDragHotAreaListener(const NotifyWindowDragHotAreaFunc & func)2117 void SceneSession::SetWindowDragHotAreaListener(const NotifyWindowDragHotAreaFunc& func)
2118 {
2119 if (moveDragController_) {
2120 moveDragController_->SetWindowDragHotAreaFunc(func);
2121 }
2122 }
2123
NotifySessionForeground(uint32_t reason,bool withAnimation)2124 void SceneSession::NotifySessionForeground(uint32_t reason, bool withAnimation)
2125 {
2126 if (!sessionStage_) {
2127 return;
2128 }
2129 return sessionStage_->NotifySessionForeground(reason, withAnimation);
2130 }
2131
NotifySessionBackground(uint32_t reason,bool withAnimation,bool isFromInnerkits)2132 void SceneSession::NotifySessionBackground(uint32_t reason, bool withAnimation, bool isFromInnerkits)
2133 {
2134 if (!sessionStage_) {
2135 return;
2136 }
2137 return sessionStage_->NotifySessionBackground(reason, withAnimation, isFromInnerkits);
2138 }
2139
SetTextFieldAvoidInfo(double textFieldPositionY,double textFieldHeight)2140 WSError SceneSession::SetTextFieldAvoidInfo(double textFieldPositionY, double textFieldHeight)
2141 {
2142 textFieldPositionY_ = textFieldPositionY;
2143 textFieldHeight_ = textFieldHeight;
2144 return WSError::WS_OK;
2145 }
2146
OnPiPMoveCallback(const WSRect & rect,const SizeChangeReason & reason)2147 void SceneSession::OnPiPMoveCallback(const WSRect& rect, const SizeChangeReason& reason)
2148 {
2149 if (!WindowHelper::IsPipWindow(GetWindowType())) {
2150 return;
2151 }
2152 if (reason == SizeChangeReason::MOVE) {
2153 NotifySessionRectChange(rect, reason);
2154 }
2155 if (reason == SizeChangeReason::DRAG_END) {
2156 ClearPiPRectPivotInfo();
2157 ScenePersistentStorage::Insert("pip_window_pos_x", rect.posX_, ScenePersistentStorageType::PIP_INFO);
2158 ScenePersistentStorage::Insert("pip_window_pos_y", rect.posY_, ScenePersistentStorageType::PIP_INFO);
2159 }
2160 }
2161
InitPiPRectInfo()2162 bool SceneSession::InitPiPRectInfo()
2163 {
2164 auto requestRect = GetSessionRequestRect();
2165 if (requestRect.width_ == 0 || requestRect.height_ == 0) {
2166 return false;
2167 }
2168 ClearPiPRectPivotInfo();
2169 pipRectInfo_.originWidth_ = requestRect.width_;
2170 pipRectInfo_.originHeight_ = requestRect.height_;
2171 int32_t level = 0;
2172 ScenePersistentStorage::Get("pip_window_level", level, ScenePersistentStorageType::PIP_INFO);
2173 pipRectInfo_.level_ = static_cast<PiPScaleLevel>(level);
2174 return true;
2175 }
2176
ClearPiPRectPivotInfo()2177 void SceneSession::ClearPiPRectPivotInfo()
2178 {
2179 pipRectInfo_.xPivot_ = PiPScalePivot::UNDEFINED;
2180 pipRectInfo_.yPivot_ = PiPScalePivot::UNDEFINED;
2181 }
2182
SavePiPRectInfo()2183 void SceneSession::SavePiPRectInfo()
2184 {
2185 ScenePersistentStorage::Insert("pip_window_level", static_cast<int32_t>(pipRectInfo_.level_),
2186 ScenePersistentStorageType::PIP_INFO);
2187 }
2188
GetNewPiPRect(const uint32_t displayWidth,const uint32_t displayHeight,Rect & rect)2189 void SceneSession::GetNewPiPRect(const uint32_t displayWidth, const uint32_t displayHeight, Rect& rect)
2190 {
2191 auto display = DisplayManager::GetInstance().GetDefaultDisplay();
2192 if (!display) {
2193 WLOGFE("cannot find display");
2194 return;
2195 }
2196 Rotation rotation = display->GetRotation();
2197 bool isLandscape = rotation == Rotation::ROTATION_90 || rotation == Rotation::ROTATION_270;
2198 PiPUtil::GetRectByScale(displayWidth, displayHeight, pipRectInfo_.level_, rect, isLandscape);
2199 WLOGFD("scale rect = (%{public}d, %{public}d, %{public}d, %{public}d)",
2200 rect.posX_, rect.posY_, rect.width_, rect.height_);
2201 auto sessionRect = GetSessionRect();
2202 WLOGFD("session rect = (%{public}d, %{public}d, %{public}d, %{public}d)",
2203 sessionRect.posX_, sessionRect.posY_, sessionRect.width_, sessionRect.height_);
2204 bool isMoveOrDrag = moveDragController_ &&
2205 (moveDragController_->GetStartDragFlag() || moveDragController_->GetStartMoveFlag());
2206 if (sessionRect.width_ != 0 && sessionRect.height_ != 0 && !isMoveOrDrag) {
2207 if (pipRectInfo_.xPivot_ == PiPScalePivot::UNDEFINED || pipRectInfo_.yPivot_ == PiPScalePivot::UNDEFINED) {
2208 // If no anchor, create anchor
2209 PiPUtil::UpdateRectPivot(sessionRect.posX_, sessionRect.width_, displayWidth, pipRectInfo_.xPivot_);
2210 PiPUtil::UpdateRectPivot(sessionRect.posY_, sessionRect.height_, displayHeight, pipRectInfo_.yPivot_);
2211 }
2212 PiPUtil::GetRectByPivot(rect.posX_, sessionRect.width_, rect.width_, displayWidth, pipRectInfo_.xPivot_);
2213 PiPUtil::GetRectByPivot(rect.posY_, sessionRect.height_, rect.height_, displayHeight, pipRectInfo_.yPivot_);
2214 WLOGFD("pivot rect = (%{public}d, %{public}d, %{public}d, %{public}d)",
2215 rect.posX_, rect.posY_, rect.width_, rect.height_);
2216 }
2217 PiPUtil::GetValidRect(displayWidth, displayHeight, rect);
2218 WLOGFD("valid rect = (%{public}d, %{public}d, %{public}d, %{public}d)",
2219 rect.posX_, rect.posY_, rect.width_, rect.height_);
2220 }
2221
ProcessUpdatePiPRect(SizeChangeReason reason)2222 void SceneSession::ProcessUpdatePiPRect(SizeChangeReason reason)
2223 {
2224 if (!WindowHelper::IsPipWindow(GetWindowType())) {
2225 WLOGFW("Session is not PiP type!");
2226 return;
2227 }
2228 auto display = DisplayManager::GetInstance().GetDefaultDisplay();
2229 if (!display) {
2230 WLOGFE("can't find display info");
2231 return;
2232 }
2233 uint32_t displayWidth = static_cast<uint32_t>(display->GetWidth());
2234 uint32_t displayHeight = static_cast<uint32_t>(display->GetHeight());
2235 float displayVpr = display->GetVirtualPixelRatio();
2236 if (displayVpr < 0.0f) {
2237 displayVpr = 1.5f;
2238 }
2239 PiPUtil::SetDisplayVpr(displayVpr);
2240
2241 // default pos of phone is the right top
2242 Rect rect = { 0, 0, pipRectInfo_.originWidth_, pipRectInfo_.originHeight_ };
2243 if (reason != SizeChangeReason::ROTATION) {
2244 ScenePersistentStorage::Get("pip_window_pos_x", rect.posX_, ScenePersistentStorageType::PIP_INFO);
2245 ScenePersistentStorage::Get("pip_window_pos_y", rect.posY_, ScenePersistentStorageType::PIP_INFO);
2246 }
2247 if (rect.posX_ == 0) {
2248 rect.posX_ = displayWidth;
2249 }
2250 WLOGFD("window rect: (%{public}d, %{public}d, %{public}u, %{public}u)",
2251 rect.posX_, rect.posY_, rect.width_, rect.height_);
2252
2253 GetNewPiPRect(displayWidth, displayHeight, rect);
2254 WLOGFD("window new rect: (%{public}d, %{public}d, %{public}u, %{public}u)",
2255 rect.posX_, rect.posY_, rect.width_, rect.height_);
2256 ScenePersistentStorage::Insert("pip_window_pos_x", rect.posX_, ScenePersistentStorageType::PIP_INFO);
2257 ScenePersistentStorage::Insert("pip_window_pos_y", rect.posY_, ScenePersistentStorageType::PIP_INFO);
2258
2259 WSRect newRect = SessionHelper::TransferToWSRect(rect);
2260 SetSessionRect(newRect);
2261 SetSessionRequestRect(newRect);
2262 Session::UpdateRect(newRect, reason);
2263 NotifySessionRectChange(newRect, reason);
2264 SingletonContainer::Get<PiPReporter>()
2265 .ReportPiPResize(static_cast<int32_t>(pipRectInfo_.level_), newRect.width_, newRect.height_);
2266 }
2267
UpdatePiPRect(uint32_t width,uint32_t height,PiPRectUpdateReason reason)2268 WSError SceneSession::UpdatePiPRect(uint32_t width, uint32_t height, PiPRectUpdateReason reason)
2269 {
2270 if (!WindowHelper::IsPipWindow(GetWindowType())) {
2271 return WSError::WS_DO_NOTHING;
2272 }
2273 auto task = [weakThis = wptr(this), width, height, reason]() {
2274 auto session = weakThis.promote();
2275 if (!session || session->isTerminating) {
2276 WLOGE("SceneSession::UpdatePiPRect session is null or is terminating");
2277 return WSError::WS_ERROR_INVALID_OPERATION;
2278 }
2279 switch (reason) {
2280 case PiPRectUpdateReason::REASON_PIP_START_WINDOW:
2281 session->InitPiPRectInfo();
2282 session->ProcessUpdatePiPRect(SizeChangeReason::CUSTOM_ANIMATION_SHOW);
2283 break;
2284 case PiPRectUpdateReason::REASON_PIP_SCALE_CHANGE:
2285 session->pipRectInfo_.level_ = static_cast<PiPScaleLevel>((static_cast<int32_t>(
2286 session->pipRectInfo_.level_) + 1) % static_cast<int32_t>(PiPScaleLevel::COUNT));
2287 session->ProcessUpdatePiPRect(SizeChangeReason::TRANSFORM);
2288 break;
2289 case PiPRectUpdateReason::REASON_PIP_VIDEO_RATIO_CHANGE:
2290 session->ClearPiPRectPivotInfo();
2291 session->pipRectInfo_.originWidth_ = width;
2292 session->pipRectInfo_.originHeight_ = height;
2293 if (session->moveDragController_ && (session->moveDragController_->GetStartDragFlag() ||
2294 session->moveDragController_->GetStartMoveFlag())) {
2295 WSRect rect = session->moveDragController_->GetTargetRect();
2296 ScenePersistentStorage::Insert(
2297 "pip_window_pos_x", rect.posX_, ScenePersistentStorageType::PIP_INFO);
2298 ScenePersistentStorage::Insert(
2299 "pip_window_pos_y", rect.posY_, ScenePersistentStorageType::PIP_INFO);
2300 }
2301 session->ProcessUpdatePiPRect(SizeChangeReason::UNDEFINED);
2302 SingletonContainer::Get<PiPReporter>().ReportPiPRatio(width, height);
2303 break;
2304 case PiPRectUpdateReason::REASON_DISPLAY_ROTATION_CHANGE:
2305 session->ProcessUpdatePiPRect(SizeChangeReason::ROTATION);
2306 session->ClearPiPRectPivotInfo();
2307 break;
2308 default:
2309 return WSError::WS_DO_NOTHING;
2310 }
2311 return WSError::WS_OK;
2312 };
2313 PostTask(task, "UpdatePiPRect");
2314 return WSError::WS_OK;
2315 }
2316
SendPointerEventToUI(std::shared_ptr<MMI::PointerEvent> pointerEvent)2317 void SceneSession::SendPointerEventToUI(std::shared_ptr<MMI::PointerEvent> pointerEvent)
2318 {
2319 std::lock_guard<std::mutex> lock(pointerEventMutex_);
2320 if (systemSessionPointerEventFunc_ != nullptr) {
2321 systemSessionPointerEventFunc_(pointerEvent);
2322 }
2323 }
2324
SendKeyEventToUI(std::shared_ptr<MMI::KeyEvent> keyEvent)2325 void SceneSession::SendKeyEventToUI(std::shared_ptr<MMI::KeyEvent> keyEvent)
2326 {
2327 std::lock_guard<std::mutex> lock(keyEventMutex_);
2328 if (systemSessionKeyEventFunc_ != nullptr) {
2329 systemSessionKeyEventFunc_(keyEvent);
2330 }
2331 }
2332
UpdateSizeChangeReason(SizeChangeReason reason)2333 WSError SceneSession::UpdateSizeChangeReason(SizeChangeReason reason)
2334 {
2335 auto task = [weakThis = wptr(this), reason]() {
2336 auto session = weakThis.promote();
2337 if (!session) {
2338 WLOGFE("session is null");
2339 return WSError::WS_ERROR_DESTROYED_OBJECT;
2340 }
2341 if (session->sessionInfo_.isSystem_) {
2342 // system scene no need to update reason
2343 return WSError::WS_DO_NOTHING;
2344 }
2345 session->reason_ = reason;
2346 if (reason != SizeChangeReason::UNDEFINED) {
2347 HITRACE_METER_FMT(HITRACE_TAG_WINDOW_MANAGER,
2348 "SceneSession::UpdateSizeChangeReason%d reason:%d",
2349 session->GetPersistentId(), static_cast<uint32_t>(reason));
2350 WLOGFD("[WMSLayout]UpdateSizeChangeReason Id: %{public}d, reason: %{public}d",
2351 session->GetPersistentId(), reason);
2352 }
2353 return WSError::WS_OK;
2354 };
2355 PostTask(task, "UpdateSizeChangeReason");
2356 return WSError::WS_OK;
2357 }
2358
IsDirtyWindow()2359 bool SceneSession::IsDirtyWindow()
2360 {
2361 return isDirty_;
2362 }
2363
NotifyUILostFocus()2364 void SceneSession::NotifyUILostFocus()
2365 {
2366 if (moveDragController_) {
2367 moveDragController_->OnLostFocus();
2368 }
2369 Session::NotifyUILostFocus();
2370 }
2371
SetScale(float scaleX,float scaleY,float pivotX,float pivotY)2372 void SceneSession::SetScale(float scaleX, float scaleY, float pivotX, float pivotY)
2373 {
2374 if (scaleX_ != scaleX || scaleY_ != scaleY || pivotX_ != pivotX || pivotY_ != pivotY) {
2375 Session::SetScale(scaleX, scaleY, pivotX, pivotY);
2376 if (specificCallback_ != nullptr) {
2377 specificCallback_->onWindowInfoUpdate_(GetPersistentId(), WindowUpdateType::WINDOW_UPDATE_PROPERTY);
2378 }
2379 if (sessionStage_ != nullptr) {
2380 Transform transform;
2381 transform.scaleX_ = scaleX;
2382 transform.scaleY_ = scaleY;
2383 transform.pivotX_ = pivotX;
2384 transform.pivotY_ = pivotY;
2385 sessionStage_->NotifyTransformChange(transform);
2386 } else {
2387 WLOGFE("sessionStage_ is nullptr");
2388 }
2389 }
2390 }
2391
RequestHideKeyboard(bool isAppColdStart)2392 void SceneSession::RequestHideKeyboard(bool isAppColdStart)
2393 {
2394 #ifdef IMF_ENABLE
2395 auto task = [weakThis = wptr(this), isAppColdStart]() {
2396 auto session = weakThis.promote();
2397 if (!session) {
2398 WLOGFE("[WMSInput] Session is null, notify inputMethod framework hide keyboard failed!");
2399 return;
2400 }
2401 WLOGFI("[WMSInput] Notify inputMethod framework hide keyboard start, id: %{public}d,"
2402 "isAppColdStart: %{public}d", session->GetPersistentId(), isAppColdStart);
2403 if (MiscServices::InputMethodController::GetInstance()) {
2404 MiscServices::InputMethodController::GetInstance()->RequestHideInput();
2405 WLOGFI("[WMSInput] Notify inputMethod framework hide keyboard end, id: %{public}d",
2406 session->GetPersistentId());
2407 }
2408 };
2409 PostExportTask(task, "RequestHideKeyboard");
2410 #endif
2411 }
2412
IsStartMoving() const2413 bool SceneSession::IsStartMoving() const
2414 {
2415 return isStartMoving_.load();
2416 }
2417
SetIsStartMoving(const bool startMoving)2418 void SceneSession::SetIsStartMoving(const bool startMoving)
2419 {
2420 isStartMoving_.store(startMoving);
2421 }
2422 } // namespace OHOS::Rosen
2423