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