• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "session/host/include/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