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/main_session.h"
17
18 #include <ipc_skeleton.h>
19
20 #include "common/include/fold_screen_state_internel.h"
21 #include "common/include/session_permission.h"
22 #include "window_helper.h"
23 #include "session_helper.h"
24 #include "session/host/include/scene_persistent_storage.h"
25
26 namespace OHOS::Rosen {
27 namespace {
28 constexpr HiviewDFX::HiLogLabel LABEL = { LOG_CORE, HILOG_DOMAIN_WINDOW, "MainSession" };
29 constexpr int32_t MAX_LABEL_SIZE = 1024;
30 } // namespace
31
MainSession(const SessionInfo & info,const sptr<SpecificSessionCallback> & specificCallback)32 MainSession::MainSession(const SessionInfo& info, const sptr<SpecificSessionCallback>& specificCallback)
33 : SceneSession(info, specificCallback)
34 {
35 scenePersistence_ = sptr<ScenePersistence>::MakeSptr(info.bundleName_, GetPersistentId());
36 if (info.persistentId_ != 0 && info.persistentId_ != GetPersistentId()) {
37 // persistentId changed due to id conflicts. Need to rename the old snapshot if exists
38 scenePersistence_->RenameSnapshotFromOldPersistentId(info.persistentId_);
39 }
40 pcFoldScreenController_ = sptr<PcFoldScreenController>::MakeSptr(wptr(this), GetPersistentId());
41 moveDragController_ = sptr<MoveDragController>::MakeSptr(GetPersistentId(), GetWindowType());
42 if (specificCallback != nullptr &&
43 specificCallback->onWindowInputPidChangeCallback_ != nullptr) {
44 moveDragController_->SetNotifyWindowPidChangeCallback(specificCallback->onWindowInputPidChangeCallback_);
45 }
46 SetMoveDragCallback();
47 std::string key = GetRatioPreferenceKey();
48 if (!key.empty()) {
49 if (ScenePersistentStorage::HasKey(key, ScenePersistentStorageType::ASPECT_RATIO)) {
50 ScenePersistentStorage::Get(key, aspectRatio_, ScenePersistentStorageType::ASPECT_RATIO);
51 WLOGFD("init aspectRatio, key %{public}s, value: %{public}f", key.c_str(), aspectRatio_);
52 moveDragController_->SetAspectRatio(aspectRatio_);
53 }
54 }
55
56 WLOGFD("Create MainSession");
57 }
58
~MainSession()59 MainSession::~MainSession()
60 {
61 WLOGD("~MainSession, id: %{public}d", GetPersistentId());
62 }
63
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)64 WSError MainSession::Reconnect(const sptr<ISessionStage>& sessionStage, const sptr<IWindowEventChannel>& eventChannel,
65 const std::shared_ptr<RSSurfaceNode>& surfaceNode, sptr<WindowSessionProperty> property, sptr<IRemoteObject> token,
66 int32_t pid, int32_t uid)
67 {
68 return PostSyncTask([weakThis = wptr(this), sessionStage, eventChannel, surfaceNode, property, token, pid, uid]() {
69 auto session = weakThis.promote();
70 if (!session) {
71 WLOGFE("session is null");
72 return WSError::WS_ERROR_DESTROYED_OBJECT;
73 }
74 WSError ret = LOCK_GUARD_EXPR(SCENE_GUARD,
75 session->Session::Reconnect(sessionStage, eventChannel, surfaceNode, property, token, pid, uid));
76 if (ret != WSError::WS_OK) {
77 return ret;
78 }
79 WindowState windowState = property->GetWindowState();
80 if (windowState == WindowState::STATE_SHOWN) {
81 session->isActive_ = true;
82 session->UpdateSessionState(SessionState::STATE_ACTIVE);
83 } else {
84 session->isActive_ = false;
85 session->UpdateSessionState(SessionState::STATE_BACKGROUND);
86 if (session->scenePersistence_) {
87 session->scenePersistence_->SetHasSnapshot(true);
88 }
89 }
90 return ret;
91 });
92 }
93
ProcessPointDownSession(int32_t posX,int32_t posY)94 WSError MainSession::ProcessPointDownSession(int32_t posX, int32_t posY)
95 {
96 const auto& id = GetPersistentId();
97 TLOGD(WmsLogTag::WMS_INPUT_KEY_FLOW, "id:%{public}d, type:%{public}d", id, GetWindowType());
98 auto isModal = IsModal();
99 if (!isModal && CheckDialogOnForeground()) {
100 HandlePointDownDialog();
101 return WSError::WS_OK;
102 }
103 if (isModal) {
104 Session::ProcessClickModalWindowOutside(posX, posY);
105 }
106 PresentFocusIfPointDown();
107 return SceneSession::ProcessPointDownSession(posX, posY);
108 }
109
NotifyForegroundInteractiveStatus(bool interactive)110 void MainSession::NotifyForegroundInteractiveStatus(bool interactive)
111 {
112 SetForegroundInteractiveStatus(interactive);
113 if (!IsSessionValid() || !sessionStage_) {
114 TLOGW(WmsLogTag::WMS_MAIN, "Session or sessionStage is invalid, id: %{public}d state: %{public}u",
115 GetPersistentId(), GetSessionState());
116 return;
117 }
118 const auto& state = GetSessionState();
119 if (isVisible_ || state == SessionState::STATE_ACTIVE || state == SessionState::STATE_FOREGROUND) {
120 WLOGFI("NotifyForegroundInteractiveStatus %{public}d", interactive);
121 sessionStage_->NotifyForegroundInteractiveStatus(interactive);
122 }
123 }
124
TransferKeyEvent(const std::shared_ptr<MMI::KeyEvent> & keyEvent)125 WSError MainSession::TransferKeyEvent(const std::shared_ptr<MMI::KeyEvent>& keyEvent)
126 {
127 if (!IsSessionValid()) {
128 return WSError::WS_ERROR_INVALID_SESSION;
129 }
130 if (keyEvent == nullptr) {
131 WLOGFE("KeyEvent is nullptr");
132 return WSError::WS_ERROR_NULLPTR;
133 }
134 if (CheckDialogOnForeground()) {
135 TLOGD(WmsLogTag::WMS_DIALOG, "Has dialog on foreground, not transfer pointer event");
136 return WSError::WS_ERROR_INVALID_PERMISSION;
137 }
138
139 WSError ret = Session::TransferKeyEvent(keyEvent);
140 return ret;
141 }
142
UpdatePointerArea(const WSRect & rect)143 void MainSession::UpdatePointerArea(const WSRect& rect)
144 {
145 if (GetWindowMode() != WindowMode::WINDOW_MODE_FLOATING) {
146 return;
147 }
148 Session::UpdatePointerArea(rect);
149 }
150
CheckPointerEventDispatch(const std::shared_ptr<MMI::PointerEvent> & pointerEvent) const151 bool MainSession::CheckPointerEventDispatch(const std::shared_ptr<MMI::PointerEvent>& pointerEvent) const
152 {
153 auto sessionState = GetSessionState();
154 int32_t action = pointerEvent->GetPointerAction();
155 if (sessionState != SessionState::STATE_FOREGROUND &&
156 sessionState != SessionState::STATE_ACTIVE &&
157 action != MMI::PointerEvent::POINTER_ACTION_LEAVE_WINDOW) {
158 WLOGFW("Current Session Info: [persistentId: %{public}d, "
159 "state: %{public}d, action:%{public}d]", GetPersistentId(), GetSessionState(), action);
160 return false;
161 }
162 return true;
163 }
164
SetTopmost(bool topmost)165 WSError MainSession::SetTopmost(bool topmost)
166 {
167 TLOGI(WmsLogTag::WMS_HIERARCHY, "SetTopmost id: %{public}d, topmost: %{public}d", GetPersistentId(), topmost);
168 PostTask([weakThis = wptr(this), topmost]() {
169 auto session = weakThis.promote();
170 if (!session) {
171 TLOGE(WmsLogTag::WMS_HIERARCHY, "session is null");
172 return;
173 }
174 auto property = session->GetSessionProperty();
175 if (property) {
176 TLOGI(WmsLogTag::WMS_HIERARCHY, "Notify session topmost change, id: %{public}d, topmost: %{public}u",
177 session->GetPersistentId(), topmost);
178 property->SetTopmost(topmost);
179 if (session->onSessionTopmostChange_) {
180 session->onSessionTopmostChange_(topmost);
181 }
182 }
183 }, "SetTopmost");
184 return WSError::WS_OK;
185 }
186
IsTopmost() const187 bool MainSession::IsTopmost() const
188 {
189 return GetSessionProperty()->IsTopmost();
190 }
191
SetMainWindowTopmost(bool isTopmost)192 WSError MainSession::SetMainWindowTopmost(bool isTopmost)
193 {
194 GetSessionProperty()->SetMainWindowTopmost(isTopmost);
195 TLOGD(WmsLogTag::WMS_HIERARCHY, "id: %{public}d, isTopmost: %{public}u",
196 GetPersistentId(), isTopmost);
197 if (mainWindowTopmostChangeFunc_) {
198 mainWindowTopmostChangeFunc_(isTopmost);
199 }
200 return WSError::WS_OK;
201 }
202
IsMainWindowTopmost() const203 bool MainSession::IsMainWindowTopmost() const
204 {
205 return GetSessionProperty()->IsMainWindowTopmost();
206 }
207
RectCheck(uint32_t curWidth,uint32_t curHeight)208 void MainSession::RectCheck(uint32_t curWidth, uint32_t curHeight)
209 {
210 uint32_t minWidth = GetSystemConfig().miniWidthOfMainWindow_;
211 uint32_t minHeight = GetSystemConfig().miniHeightOfMainWindow_;
212 uint32_t maxFloatingWindowSize = GetSystemConfig().maxFloatingWindowSize_;
213 RectSizeCheckProcess(curWidth, curHeight, minWidth, minHeight, maxFloatingWindowSize);
214 }
215
SetExitSplitOnBackground(bool isExitSplitOnBackground)216 void MainSession::SetExitSplitOnBackground(bool isExitSplitOnBackground)
217 {
218 TLOGD(WmsLogTag::WMS_MULTI_WINDOW, "id:%{public}d, isExitSplitOnBackground:%{public}d", persistentId_,
219 isExitSplitOnBackground);
220 isExitSplitOnBackground_ = isExitSplitOnBackground;
221 }
222
IsExitSplitOnBackground() const223 bool MainSession::IsExitSplitOnBackground() const
224 {
225 return isExitSplitOnBackground_;
226 }
227
NotifyClientToUpdateInteractive(bool interactive)228 void MainSession::NotifyClientToUpdateInteractive(bool interactive)
229 {
230 if (!sessionStage_) {
231 return;
232 }
233 const auto state = GetSessionState();
234 if (state == SessionState::STATE_ACTIVE || state == SessionState::STATE_FOREGROUND) {
235 WLOGFI("%{public}d", interactive);
236 sessionStage_->NotifyForegroundInteractiveStatus(interactive);
237 isClientInteractive_ = interactive;
238 }
239 }
240
241 /*
242 * Notify when updating highlight instead after hightlight functionality enabled
243 */
UpdateFocus(bool isFocused)244 WSError MainSession::UpdateFocus(bool isFocused)
245 {
246 if (FoldScreenStateInternel::IsSuperFoldDisplayDevice() && !IsFocused() && isFocused && pcFoldScreenController_) {
247 pcFoldScreenController_->UpdateSupportEnterWaterfallMode();
248 }
249 return Session::UpdateFocus(isFocused);
250 }
251
OnTitleAndDockHoverShowChange(bool isTitleHoverShown,bool isDockHoverShown)252 WSError MainSession::OnTitleAndDockHoverShowChange(bool isTitleHoverShown, bool isDockHoverShown)
253 {
254 const char* const funcName = __func__;
255 PostTask([weakThis = wptr(this), isTitleHoverShown, isDockHoverShown, funcName] {
256 auto session = weakThis.promote();
257 if (!session) {
258 TLOGNE(WmsLogTag::WMS_LAYOUT_PC, "%{public}s session is null", funcName);
259 return;
260 }
261 TLOGND(WmsLogTag::WMS_LAYOUT_PC, "%{public}s isTitleHoverShown: %{public}d, isDockHoverShown: %{public}d",
262 funcName, isTitleHoverShown, isDockHoverShown);
263 if (session->onTitleAndDockHoverShowChangeFunc_) {
264 session->onTitleAndDockHoverShowChangeFunc_(isTitleHoverShown, isDockHoverShown);
265 }
266 }, funcName);
267 return WSError::WS_OK;
268 }
269
OnRestoreMainWindow()270 WSError MainSession::OnRestoreMainWindow()
271 {
272 PostTask([weakThis = wptr(this)] {
273 auto session = weakThis.promote();
274 if (!session) {
275 TLOGNE(WmsLogTag::WMS_LAYOUT_PC, "session is null");
276 return;
277 }
278 if (session->onRestoreMainWindowFunc_) {
279 session->onRestoreMainWindowFunc_();
280 }
281 }, __func__);
282 return WSError::WS_OK;
283 }
284
OnSetWindowRectAutoSave(bool enabled,bool isSaveBySpecifiedFlag)285 WSError MainSession::OnSetWindowRectAutoSave(bool enabled, bool isSaveBySpecifiedFlag)
286 {
287 const char* const where = __func__;
288 PostTask([weakThis = wptr(this), enabled, isSaveBySpecifiedFlag, where] {
289 auto session = weakThis.promote();
290 if (!session) {
291 TLOGNE(WmsLogTag::WMS_MAIN, "session is null");
292 return;
293 }
294 session->GetSessionProperty()->SetIsSaveBySpecifiedFlag(isSaveBySpecifiedFlag);
295 if (session->onSetWindowRectAutoSaveFunc_) {
296 session->onSetWindowRectAutoSaveFunc_(enabled, isSaveBySpecifiedFlag);
297 TLOGNI(WmsLogTag::WMS_MAIN, "%{public}s id %{public}d isSaveBySpecifiedFlag: %{public}d "
298 "enable:%{public}d", where, session->GetPersistentId(), isSaveBySpecifiedFlag, enabled);
299 }
300 }, __func__);
301 return WSError::WS_OK;
302 }
303
NotifySupportWindowModesChange(const std::vector<AppExecFwk::SupportWindowMode> & supportedWindowModes)304 WSError MainSession::NotifySupportWindowModesChange(
305 const std::vector<AppExecFwk::SupportWindowMode>& supportedWindowModes)
306 {
307 const char* const where = __func__;
308 PostTask([weakThis = wptr(this), supportedWindowModes = supportedWindowModes, where]() mutable {
309 auto session = weakThis.promote();
310 if (!session) {
311 TLOGNE(WmsLogTag::WMS_LAYOUT_PC, "%{public}s session is null", where);
312 return;
313 }
314 if (session->onSetSupportedWindowModesFunc_) {
315 session->onSetSupportedWindowModesFunc_(std::move(supportedWindowModes));
316 }
317 }, __func__);
318 return WSError::WS_OK;
319 }
320
NotifyMainModalTypeChange(bool isModal)321 WSError MainSession::NotifyMainModalTypeChange(bool isModal)
322 {
323 const char* const where = __func__;
324 PostTask([weakThis = wptr(this), isModal, where] {
325 auto session = weakThis.promote();
326 if (!session) {
327 TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s session is null", where);
328 return;
329 }
330 TLOGNI(WmsLogTag::WMS_HIERARCHY, "%{public}s main window isModal:%{public}d", where, isModal);
331 if (session->onMainModalTypeChange_) {
332 session->onMainModalTypeChange_(isModal);
333 }
334 }, __func__);
335 return WSError::WS_OK;
336 }
337
IsModal() const338 bool MainSession::IsModal() const
339 {
340 return WindowHelper::IsModalMainWindow(GetSessionProperty()->GetWindowType(),
341 GetSessionProperty()->GetWindowFlags());
342 }
343
IsApplicationModal() const344 bool MainSession::IsApplicationModal() const
345 {
346 return IsModal();
347 }
348
RegisterSessionLockStateChangeCallback(NotifySessionLockStateChangeCallback && callback)349 void MainSession::RegisterSessionLockStateChangeCallback(NotifySessionLockStateChangeCallback&& callback)
350 {
351 PostTask([weakThis = wptr(this), callback = std::move(callback)] {
352 auto session = weakThis.promote();
353 if (!session) {
354 TLOGNE(WmsLogTag::WMS_MAIN, "session is null");
355 return;
356 }
357 session->onSessionLockStateChangeCallback_ = std::move(callback);
358 if (session->onSessionLockStateChangeCallback_ && session->GetSessionLockState()) {
359 session->onSessionLockStateChangeCallback_(session->GetSessionLockState());
360 }
361 }, __func__);
362 }
363
NotifySubAndDialogFollowRectChange(const WSRect & rect,bool isGlobal,bool needFlush)364 void MainSession::NotifySubAndDialogFollowRectChange(const WSRect& rect, bool isGlobal, bool needFlush)
365 {
366 std::unordered_map<int32_t, NotifySurfaceBoundsChangeFunc> funcMap;
367 {
368 std::lock_guard lock(registerNotifySurfaceBoundsChangeMutex_);
369 funcMap = notifySurfaceBoundsChangeFuncMap_;
370 }
371 for (const auto& [sessionId, func] : funcMap) {
372 auto subSession = GetSceneSessionById(sessionId);
373 if (subSession && subSession->GetIsFollowParentLayout() && func) {
374 func(rect, isGlobal, needFlush);
375 }
376 }
377 }
378
NotifySessionLockStateChange(bool isLockedState)379 void MainSession::NotifySessionLockStateChange(bool isLockedState)
380 {
381 PostTask([weakThis = wptr(this), isLockedState] {
382 auto session = weakThis.promote();
383 if (!session) {
384 TLOGNE(WmsLogTag::WMS_MAIN, "session is null");
385 return;
386 }
387 if (session->GetSessionLockState() == isLockedState) {
388 TLOGNW(WmsLogTag::WMS_MAIN, "isLockedState is already %{public}d", isLockedState);
389 return;
390 }
391 session->SetSessionLockState(isLockedState);
392 if (session->onSessionLockStateChangeCallback_) {
393 TLOGNI(WmsLogTag::WMS_MAIN, "onSessionLockStageChange to:%{public}d", isLockedState);
394 session->onSessionLockStateChangeCallback_(isLockedState);
395 }
396 }, __func__);
397 }
398
SetSessionLockState(bool isLockedState)399 void MainSession::SetSessionLockState(bool isLockedState)
400 {
401 isLockedState_ = isLockedState;
402 }
403
GetSessionLockState() const404 bool MainSession::GetSessionLockState() const
405 {
406 return isLockedState_;
407 }
408
SetSessionLabelAndIcon(const std::string & label,const std::shared_ptr<Media::PixelMap> & icon)409 WSError MainSession::SetSessionLabelAndIcon(const std::string& label,
410 const std::shared_ptr<Media::PixelMap>& icon)
411 {
412 TLOGI(WmsLogTag::WMS_MAIN, "id: %{public}d", persistentId_);
413 int32_t callingPid = IPCSkeleton::GetCallingPid();
414 const bool pidCheck = (callingPid != -1) && (callingPid == GetCallingPid());
415 if (!pidCheck ||
416 !SessionPermission::VerifyCallingPermission(PermissionConstants::PERMISSION_SET_ABILITY_INSTANCE_INFO)) {
417 TLOGE(WmsLogTag::WMS_MAIN,
418 "The caller has not permission granted or not the same processs, "
419 "callingPid_: %{public}d, callingPid: %{public}d, bundleName: %{public}s",
420 GetCallingPid(), callingPid, GetSessionInfo().bundleName_.c_str());
421 return WSError::WS_ERROR_INVALID_PERMISSION;
422 }
423 if (!systemConfig_.IsPcWindow()) {
424 TLOGE(WmsLogTag::WMS_MAIN, "device not support");
425 return WSError::WS_ERROR_DEVICE_NOT_SUPPORT;
426 }
427 if (label.empty() || label.length() > MAX_LABEL_SIZE) {
428 TLOGE(WmsLogTag::WMS_MAIN, "invalid label");
429 return WSError::WS_ERROR_SET_SESSION_LABEL_FAILED;
430 }
431 return SetSessionLabelAndIconInner(label, icon);
432 }
433
SetSessionLabelAndIconInner(const std::string & label,const std::shared_ptr<Media::PixelMap> & icon)434 WSError MainSession::SetSessionLabelAndIconInner(const std::string& label,
435 const std::shared_ptr<Media::PixelMap>& icon)
436 {
437 const char* const where = __func__;
438 PostTask([weakThis = wptr(this), where, label, icon] {
439 auto session = weakThis.promote();
440 if (session == nullptr) {
441 TLOGNE(WmsLogTag::WMS_MAIN, "%{public}s session is nullptr", where);
442 return WSError::WS_ERROR_NULLPTR;
443 }
444 if (session->updateSessionLabelAndIconFunc_) {
445 session->updateSessionLabelAndIconFunc_(label, icon);
446 }
447 return WSError::WS_OK;
448 }, __func__);
449 return WSError::WS_OK;
450 }
451
SetUpdateSessionLabelAndIconListener(NofitySessionLabelAndIconUpdatedFunc && func)452 void MainSession::SetUpdateSessionLabelAndIconListener(NofitySessionLabelAndIconUpdatedFunc&& func)
453 {
454 const char* const where = __func__;
455 PostTask([weakThis = wptr(this), func = std::move(func), where] {
456 auto session = weakThis.promote();
457 if (!session) {
458 TLOGNE(WmsLogTag::WMS_MAIN, "%{public}s session is null", where);
459 return;
460 }
461 session->updateSessionLabelAndIconFunc_ = std::move(func);
462 }, __func__);
463 }
464
UpdateFlag(const std::string & flag)465 WSError MainSession::UpdateFlag(const std::string& flag)
466 {
467 const char* const where = __func__;
468 PostTask([weakThis = wptr(this), flag, where] {
469 auto session = weakThis.promote();
470 if (!session) {
471 TLOGNE(WmsLogTag::WMS_MAIN, "session is null");
472 return;
473 }
474 session->sessionInfo_.specifiedFlag_ = flag;
475 if (session->onUpdateFlagFunc_) {
476 session->onUpdateFlagFunc_(flag);
477 TLOGND(WmsLogTag::WMS_MAIN, "%{public}s id %{public}d flag: %{public}s",
478 where, session->GetPersistentId(), flag.c_str());
479 }
480 }, __func__);
481 return WSError::WS_OK;
482 }
483 } // namespace OHOS::Rosen
484