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 "session_helper.h"
19 #include "window_helper.h"
20 #include "session/host/include/scene_persistent_storage.h"
21
22 namespace OHOS::Rosen {
23 namespace {
24 constexpr HiviewDFX::HiLogLabel LABEL = { LOG_CORE, HILOG_DOMAIN_WINDOW, "MainSession" };
25 } // namespace
26
MainSession(const SessionInfo & info,const sptr<SpecificSessionCallback> & specificCallback)27 MainSession::MainSession(const SessionInfo& info, const sptr<SpecificSessionCallback>& specificCallback)
28 : SceneSession(info, specificCallback)
29 {
30 scenePersistence_ = new ScenePersistence(info.bundleName_, GetPersistentId());
31 if (info.persistentId_ != 0 && info.persistentId_ != GetPersistentId()) {
32 // persistentId changed due to id conflicts. Need to rename the old snapshot if exists
33 scenePersistence_->RenameSnapshotFromOldPersistentId(info.persistentId_);
34 }
35 moveDragController_ = new (std::nothrow) MoveDragController(GetPersistentId());
36 if (moveDragController_ != nullptr && specificCallback != nullptr &&
37 specificCallback->onWindowInputPidChangeCallback_ != nullptr) {
38 moveDragController_->SetNotifyWindowPidChangeCallback(specificCallback->onWindowInputPidChangeCallback_);
39 }
40 SetMoveDragCallback();
41 std::string key = GetRatioPreferenceKey();
42 if (!key.empty()) {
43 if (ScenePersistentStorage::HasKey(key, ScenePersistentStorageType::ASPECT_RATIO)) {
44 ScenePersistentStorage::Get(key, aspectRatio_, ScenePersistentStorageType::ASPECT_RATIO);
45 WLOGD("SceneSession init aspectRatio , key %{public}s, value: %{public}f", key.c_str(), aspectRatio_);
46 if (moveDragController_) {
47 moveDragController_->SetAspectRatio(aspectRatio_);
48 }
49 }
50 }
51
52 WLOGFD("Create MainSession");
53 }
54
~MainSession()55 MainSession::~MainSession()
56 {
57 WLOGD("~MainSession, id: %{public}d", GetPersistentId());
58 }
59
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)60 WSError MainSession::Reconnect(const sptr<ISessionStage>& sessionStage, const sptr<IWindowEventChannel>& eventChannel,
61 const std::shared_ptr<RSSurfaceNode>& surfaceNode, sptr<WindowSessionProperty> property, sptr<IRemoteObject> token,
62 int32_t pid, int32_t uid)
63 {
64 return PostSyncTask([weakThis = wptr(this), sessionStage, eventChannel, surfaceNode, property, token, pid, uid]() {
65 auto session = weakThis.promote();
66 if (!session) {
67 WLOGFE("session is null");
68 return WSError::WS_ERROR_DESTROYED_OBJECT;
69 }
70 WSError ret = session->Session::Reconnect(sessionStage, eventChannel, surfaceNode, property, token, pid, uid);
71 if (ret != WSError::WS_OK) {
72 return ret;
73 }
74 WindowState windowState = property->GetWindowState();
75 if (windowState == WindowState::STATE_SHOWN) {
76 session->isActive_ = true;
77 session->UpdateSessionState(SessionState::STATE_ACTIVE);
78 } else {
79 session->isActive_ = false;
80 session->UpdateSessionState(SessionState::STATE_BACKGROUND);
81 if (session->scenePersistence_) {
82 session->scenePersistence_->SetHasSnapshot(true);
83 }
84 }
85 return ret;
86 });
87 }
88
ProcessPointDownSession(int32_t posX,int32_t posY)89 WSError MainSession::ProcessPointDownSession(int32_t posX, int32_t posY)
90 {
91 const auto& id = GetPersistentId();
92 WLOGFI("id: %{public}d, type: %{public}d", id, GetWindowType());
93 auto isModal = IsModal();
94 if (!isModal && CheckDialogOnForeground()) {
95 HandlePointDownDialog();
96 return WSError::WS_OK;
97 }
98 PresentFocusIfPointDown();
99 return SceneSession::ProcessPointDownSession(posX, posY);
100 }
101
NotifyForegroundInteractiveStatus(bool interactive)102 void MainSession::NotifyForegroundInteractiveStatus(bool interactive)
103 {
104 SetForegroundInteractiveStatus(interactive);
105 if (!IsSessionValid() || !sessionStage_) {
106 TLOGW(WmsLogTag::WMS_MAIN, "Session or sessionStage is invalid, id: %{public}d state: %{public}u",
107 GetPersistentId(), GetSessionState());
108 return;
109 }
110 const auto& state = GetSessionState();
111 if (isVisible_ || state == SessionState::STATE_ACTIVE || state == SessionState::STATE_FOREGROUND) {
112 WLOGFI("NotifyForegroundInteractiveStatus %{public}d", interactive);
113 sessionStage_->NotifyForegroundInteractiveStatus(interactive);
114 }
115 }
116
TransferKeyEvent(const std::shared_ptr<MMI::KeyEvent> & keyEvent)117 WSError MainSession::TransferKeyEvent(const std::shared_ptr<MMI::KeyEvent>& keyEvent)
118 {
119 if (!IsSessionValid()) {
120 return WSError::WS_ERROR_INVALID_SESSION;
121 }
122 if (keyEvent == nullptr) {
123 WLOGFE("KeyEvent is nullptr");
124 return WSError::WS_ERROR_NULLPTR;
125 }
126 if (CheckDialogOnForeground()) {
127 TLOGD(WmsLogTag::WMS_DIALOG, "Has dialog on foreground, not transfer pointer event");
128 return WSError::WS_ERROR_INVALID_PERMISSION;
129 }
130
131 WSError ret = Session::TransferKeyEvent(keyEvent);
132 return ret;
133 }
134
UpdatePointerArea(const WSRect & rect)135 void MainSession::UpdatePointerArea(const WSRect& rect)
136 {
137 if (GetWindowMode() != WindowMode::WINDOW_MODE_FLOATING) {
138 return;
139 }
140 Session::UpdatePointerArea(rect);
141 }
142
CheckPointerEventDispatch(const std::shared_ptr<MMI::PointerEvent> & pointerEvent) const143 bool MainSession::CheckPointerEventDispatch(const std::shared_ptr<MMI::PointerEvent>& pointerEvent) const
144 {
145 auto sessionState = GetSessionState();
146 int32_t action = pointerEvent->GetPointerAction();
147 if (sessionState != SessionState::STATE_FOREGROUND &&
148 sessionState != SessionState::STATE_ACTIVE &&
149 action != MMI::PointerEvent::POINTER_ACTION_LEAVE_WINDOW) {
150 WLOGFW("Current Session Info: [persistentId: %{public}d, "
151 "state: %{public}d, action:%{public}d]", GetPersistentId(), GetSessionState(), action);
152 return false;
153 }
154 return true;
155 }
156
SetTopmost(bool topmost)157 WSError MainSession::SetTopmost(bool topmost)
158 {
159 TLOGI(WmsLogTag::WMS_LAYOUT, "SetTopmost id: %{public}d, topmost: %{public}d", GetPersistentId(), topmost);
160 auto task = [weakThis = wptr(this), topmost]() {
161 auto session = weakThis.promote();
162 if (!session) {
163 TLOGE(WmsLogTag::WMS_LAYOUT, "session is null");
164 return;
165 }
166 auto property = session->GetSessionProperty();
167 if (property) {
168 TLOGI(WmsLogTag::WMS_LAYOUT, "Notify session topmost change, id: %{public}d, topmost: %{public}u",
169 session->GetPersistentId(), topmost);
170 property->SetTopmost(topmost);
171 if (session->sessionChangeCallback_ && session->sessionChangeCallback_->onSessionTopmostChange_) {
172 session->sessionChangeCallback_->onSessionTopmostChange_(topmost);
173 }
174 }
175 };
176 PostTask(task, "SetTopmost");
177 return WSError::WS_OK;
178 }
179
IsTopmost() const180 bool MainSession::IsTopmost() const
181 {
182 return GetSessionProperty()->IsTopmost();
183 }
184
SetMainWindowTopmost(bool isTopmost)185 WSError MainSession::SetMainWindowTopmost(bool isTopmost)
186 {
187 GetSessionProperty()->SetMainWindowTopmost(isTopmost);
188 TLOGD(WmsLogTag::WMS_HIERARCHY, "id: %{public}d, isTopmost: %{public}u",
189 GetPersistentId(), isTopmost);
190 if (mainWindowTopmostChangeFunc_) {
191 mainWindowTopmostChangeFunc_(isTopmost);
192 }
193 return WSError::WS_OK;
194 }
195
IsMainWindowTopmost() const196 bool MainSession::IsMainWindowTopmost() const
197 {
198 return GetSessionProperty()->IsMainWindowTopmost();
199 }
200
RectCheck(uint32_t curWidth,uint32_t curHeight)201 void MainSession::RectCheck(uint32_t curWidth, uint32_t curHeight)
202 {
203 uint32_t minWidth = GetSystemConfig().miniWidthOfMainWindow_;
204 uint32_t minHeight = GetSystemConfig().miniHeightOfMainWindow_;
205 uint32_t maxFloatingWindowSize = GetSystemConfig().maxFloatingWindowSize_;
206 RectSizeCheckProcess(curWidth, curHeight, minWidth, minHeight, maxFloatingWindowSize);
207 }
208
SetExitSplitOnBackground(bool isExitSplitOnBackground)209 void MainSession::SetExitSplitOnBackground(bool isExitSplitOnBackground)
210 {
211 TLOGI(WmsLogTag::WMS_MULTI_WINDOW, "id: %{public}d, isExitSplitOnBackground: %{public}d", persistentId_,
212 isExitSplitOnBackground);
213 isExitSplitOnBackground_ = isExitSplitOnBackground;
214 }
215
IsExitSplitOnBackground() const216 bool MainSession::IsExitSplitOnBackground() const
217 {
218 return isExitSplitOnBackground_;
219 }
220
NotifyClientToUpdateInteractive(bool interactive)221 void MainSession::NotifyClientToUpdateInteractive(bool interactive)
222 {
223 if (!sessionStage_) {
224 return;
225 }
226 const auto state = GetSessionState();
227 if (state == SessionState::STATE_ACTIVE || state == SessionState::STATE_FOREGROUND) {
228 WLOGFI("%{public}d", interactive);
229 sessionStage_->NotifyForegroundInteractiveStatus(interactive);
230 isClientInteractive_ = interactive;
231 }
232 }
233
OnTitleAndDockHoverShowChange(bool isTitleHoverShown,bool isDockHoverShown)234 WSError MainSession::OnTitleAndDockHoverShowChange(bool isTitleHoverShown, bool isDockHoverShown)
235 {
236 const char* const funcName = __func__;
237 auto task = [weakThis = wptr(this), isTitleHoverShown, isDockHoverShown, funcName] {
238 auto session = weakThis.promote();
239 if (!session) {
240 TLOGNE(WmsLogTag::WMS_IMMS, "%{public}s session is null", funcName);
241 return;
242 }
243 TLOGNI(WmsLogTag::WMS_IMMS, "%{public}s isTitleHoverShown: %{public}d, isDockHoverShown: %{public}d", funcName,
244 isTitleHoverShown, isDockHoverShown);
245 if (session->onTitleAndDockHoverShowChangeFunc_) {
246 session->onTitleAndDockHoverShowChangeFunc_(isTitleHoverShown, isDockHoverShown);
247 }
248 };
249 PostTask(task, funcName);
250 return WSError::WS_OK;
251 }
252
OnRestoreMainWindow()253 WSError MainSession::OnRestoreMainWindow()
254 {
255 auto task = [weakThis = wptr(this)] {
256 auto session = weakThis.promote();
257 if (!session) {
258 TLOGNE(WmsLogTag::WMS_LIFE, "session is null");
259 return;
260 }
261 if (session->onRestoreMainWindowFunc_) {
262 session->onRestoreMainWindowFunc_();
263 }
264 };
265 PostTask(task, __func__);
266 return WSError::WS_OK;
267 }
268
OnSetWindowRectAutoSave(bool enabled)269 WSError MainSession::OnSetWindowRectAutoSave(bool enabled)
270 {
271 auto task = [weakThis = wptr(this), enabled] {
272 auto session = weakThis.promote();
273 if (!session) {
274 TLOGNE(WmsLogTag::WMS_MAIN, "session is null");
275 return;
276 }
277 if (session->onSetWindowRectAutoSaveFunc_) {
278 session->onSetWindowRectAutoSaveFunc_(enabled);
279 }
280 };
281 PostTask(task, __func__);
282 return WSError::WS_OK;
283 }
284
NotifyMainModalTypeChange(bool isModal)285 WSError MainSession::NotifyMainModalTypeChange(bool isModal)
286 {
287 const char* const where = __func__;
288 PostTask([weakThis = wptr(this), isModal, where] {
289 auto session = weakThis.promote();
290 if (!session) {
291 TLOGNE(WmsLogTag::WMS_LIFE, "%{public}s session is null", where);
292 return;
293 }
294 TLOGNI(WmsLogTag::WMS_HIERARCHY, "%{public}s main window isModal:%{public}d", where, isModal);
295 if (session->onMainModalTypeChange_) {
296 session->onMainModalTypeChange_(isModal);
297 }
298 }, __func__);
299 return WSError::WS_OK;
300 }
301
IsModal() const302 bool MainSession::IsModal() const
303 {
304 return WindowHelper::IsModalMainWindow(GetSessionProperty()->GetWindowType(),
305 GetSessionProperty()->GetWindowFlags());
306 }
307
IsApplicationModal() const308 bool MainSession::IsApplicationModal() const
309 {
310 return IsModal();
311 }
312 } // namespace OHOS::Rosen
313