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