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 <ui/rs_surface_node.h>
19
20 #include "key_event.h"
21 #include "pointer_event.h"
22 #include "session_helper.h"
23 #include "session/host/include/scene_persistent_storage.h"
24 #include "window_manager_hilog.h"
25
26 namespace OHOS::Rosen {
27 namespace {
28 constexpr HiviewDFX::HiLogLabel LABEL = { LOG_CORE, HILOG_DOMAIN_WINDOW, "MainSession" };
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_ = sptr<ScenePersistence>::MakeSptr(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_ = sptr<MoveDragController>::MakeSptr(GetPersistentId());
40 if (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 WLOGFD("init aspectRatio, key %{public}s, value: %{public}f", key.c_str(), aspectRatio_);
50 moveDragController_->SetAspectRatio(aspectRatio_);
51 }
52 }
53
54 WLOGFD("Create MainSession");
55 }
56
~MainSession()57 MainSession::~MainSession()
58 {
59 WLOGD("~MainSession, id: %{public}d", GetPersistentId());
60 }
61
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)62 WSError MainSession::Reconnect(const sptr<ISessionStage>& sessionStage, const sptr<IWindowEventChannel>& eventChannel,
63 const std::shared_ptr<RSSurfaceNode>& surfaceNode, sptr<WindowSessionProperty> property, sptr<IRemoteObject> token,
64 int32_t pid, int32_t uid)
65 {
66 return PostSyncTask([weakThis = wptr(this), sessionStage, eventChannel, surfaceNode, property, token, pid, uid]() {
67 auto session = weakThis.promote();
68 if (!session) {
69 WLOGFE("session is null");
70 return WSError::WS_ERROR_DESTROYED_OBJECT;
71 }
72 WSError ret = session->Session::Reconnect(sessionStage, eventChannel, surfaceNode, property, token, pid, uid);
73 if (ret != WSError::WS_OK) {
74 return ret;
75 }
76 WindowState windowState = property->GetWindowState();
77 if (windowState == WindowState::STATE_SHOWN) {
78 session->isActive_ = true;
79 session->UpdateSessionState(SessionState::STATE_ACTIVE);
80 } else {
81 session->isActive_ = false;
82 session->UpdateSessionState(SessionState::STATE_BACKGROUND);
83 if (session->scenePersistence_) {
84 session->scenePersistence_->SetHasSnapshot(true);
85 }
86 }
87 return ret;
88 });
89 }
90
ProcessPointDownSession(int32_t posX, int32_t posY)91 WSError MainSession::ProcessPointDownSession(int32_t posX, int32_t posY)
92 {
93 const auto& id = GetPersistentId();
94 WLOGFI("id: %{public}d, type: %{public}d", id, GetWindowType());
95 if (CheckDialogOnForeground()) {
96 HandlePointDownDialog();
97 return WSError::WS_OK;
98 }
99 PresentFocusIfPointDown();
100 return SceneSession::ProcessPointDownSession(posX, posY);
101 }
102
NotifyForegroundInteractiveStatus(bool interactive)103 void MainSession::NotifyForegroundInteractiveStatus(bool interactive)
104 {
105 SetForegroundInteractiveStatus(interactive);
106 if (!IsSessionValid() || !sessionStage_) {
107 TLOGW(WmsLogTag::WMS_MAIN, "Session or sessionStage is invalid, id: %{public}d state: %{public}u",
108 GetPersistentId(), GetSessionState());
109 return;
110 }
111 const auto& state = GetSessionState();
112 if (isVisible_ || state == SessionState::STATE_ACTIVE || state == SessionState::STATE_FOREGROUND) {
113 WLOGFI("NotifyForegroundInteractiveStatus %{public}d", interactive);
114 sessionStage_->NotifyForegroundInteractiveStatus(interactive);
115 }
116 }
117
TransferKeyEvent(const std::shared_ptr<MMI::KeyEvent>& keyEvent)118 WSError MainSession::TransferKeyEvent(const std::shared_ptr<MMI::KeyEvent>& keyEvent)
119 {
120 if (!IsSessionValid()) {
121 return WSError::WS_ERROR_INVALID_SESSION;
122 }
123 if (keyEvent == nullptr) {
124 WLOGFE("KeyEvent is nullptr");
125 return WSError::WS_ERROR_NULLPTR;
126 }
127 if (CheckDialogOnForeground()) {
128 TLOGD(WmsLogTag::WMS_DIALOG, "Has dialog on foreground, not transfer pointer event");
129 return WSError::WS_ERROR_INVALID_PERMISSION;
130 }
131
132 WSError ret = Session::TransferKeyEvent(keyEvent);
133 return ret;
134 }
135
UpdatePointerArea(const WSRect& rect)136 void MainSession::UpdatePointerArea(const WSRect& rect)
137 {
138 if (GetWindowMode() != WindowMode::WINDOW_MODE_FLOATING) {
139 return;
140 }
141 Session::UpdatePointerArea(rect);
142 }
143
CheckPointerEventDispatch(const std::shared_ptr<MMI::PointerEvent>& pointerEvent) const144 bool MainSession::CheckPointerEventDispatch(const std::shared_ptr<MMI::PointerEvent>& pointerEvent) const
145 {
146 auto sessionState = GetSessionState();
147 int32_t action = pointerEvent->GetPointerAction();
148 if (sessionState != SessionState::STATE_FOREGROUND &&
149 sessionState != SessionState::STATE_ACTIVE &&
150 action != MMI::PointerEvent::POINTER_ACTION_LEAVE_WINDOW) {
151 WLOGFW("Current Session Info: [persistentId: %{public}d, "
152 "state: %{public}d, action:%{public}d]", GetPersistentId(), GetSessionState(), action);
153 return false;
154 }
155 return true;
156 }
157
SetTopmost(bool topmost)158 WSError MainSession::SetTopmost(bool topmost)
159 {
160 TLOGI(WmsLogTag::WMS_HIERARCHY, "SetTopmost id: %{public}d, topmost: %{public}d", GetPersistentId(), topmost);
161 auto task = [weakThis = wptr(this), topmost]() {
162 auto session = weakThis.promote();
163 if (!session) {
164 TLOGE(WmsLogTag::WMS_HIERARCHY, "session is null");
165 return;
166 }
167 auto property = session->GetSessionProperty();
168 if (property) {
169 TLOGI(WmsLogTag::WMS_HIERARCHY, "Notify session topmost change, id: %{public}d, topmost: %{public}u",
170 session->GetPersistentId(), topmost);
171 property->SetTopmost(topmost);
172 if (session->sessionChangeCallback_ && session->sessionChangeCallback_->onSessionTopmostChange_) {
173 session->sessionChangeCallback_->onSessionTopmostChange_(topmost);
174 }
175 }
176 };
177 PostTask(task, "SetTopmost");
178 return WSError::WS_OK;
179 }
180
IsTopmost() const181 bool MainSession::IsTopmost() const
182 {
183 return GetSessionProperty()->IsTopmost();
184 }
185
SetMainWindowTopmost(bool isTopmost)186 WSError MainSession::SetMainWindowTopmost(bool isTopmost)
187 {
188 auto property = GetSessionProperty();
189 if (property) {
190 property->SetMainWindowTopmost(isTopmost);
191 TLOGD(WmsLogTag::WMS_HIERARCHY,
192 "Notify session topmost change, id: %{public}d, isTopmost: %{public}u",
193 GetPersistentId(), isTopmost);
194 if (mainWindowTopmostChangeFunc_) {
195 mainWindowTopmostChangeFunc_(isTopmost);
196 }
197 }
198 return WSError::WS_OK;
199 }
200
IsMainWindowTopmost() const201 bool MainSession::IsMainWindowTopmost() const
202 {
203 return GetSessionProperty()->IsMainWindowTopmost();
204 }
205
RectCheck(uint32_t curWidth, uint32_t curHeight)206 void MainSession::RectCheck(uint32_t curWidth, uint32_t curHeight)
207 {
208 uint32_t minWidth = GetSystemConfig().miniWidthOfMainWindow_;
209 uint32_t minHeight = GetSystemConfig().miniHeightOfMainWindow_;
210 uint32_t maxFloatingWindowSize = GetSystemConfig().maxFloatingWindowSize_;
211 RectSizeCheckProcess(curWidth, curHeight, minWidth, minHeight, maxFloatingWindowSize);
212 }
213
SetExitSplitOnBackground(bool isExitSplitOnBackground)214 void MainSession::SetExitSplitOnBackground(bool isExitSplitOnBackground)
215 {
216 TLOGI(WmsLogTag::WMS_MULTI_WINDOW, "id: %{public}d, isExitSplitOnBackground: %{public}d", persistentId_,
217 isExitSplitOnBackground);
218 isExitSplitOnBackground_ = isExitSplitOnBackground;
219 }
220
IsExitSplitOnBackground() const221 bool MainSession::IsExitSplitOnBackground() const
222 {
223 return isExitSplitOnBackground_;
224 }
225
NotifyClientToUpdateInteractive(bool interactive)226 void MainSession::NotifyClientToUpdateInteractive(bool interactive)
227 {
228 if (!sessionStage_) {
229 return;
230 }
231 const auto state = GetSessionState();
232 if (state == SessionState::STATE_ACTIVE || state == SessionState::STATE_FOREGROUND) {
233 WLOGFI("%{public}d", interactive);
234 sessionStage_->NotifyForegroundInteractiveStatus(interactive);
235 isClientInteractive_ = interactive;
236 }
237 }
238
OnRestoreMainWindow()239 WSError MainSession::OnRestoreMainWindow()
240 {
241 auto task = [weakThis = wptr(this)]() {
242 auto session = weakThis.promote();
243 if (!session) {
244 TLOGNE(WmsLogTag::WMS_LIFE, "session is null");
245 return WSError::WS_ERROR_DESTROYED_OBJECT;
246 }
247 if (session->sessionChangeCallback_ && session->sessionChangeCallback_->onRestoreMainWindowFunc_) {
248 session->sessionChangeCallback_->onRestoreMainWindowFunc_();
249 }
250 return WSError::WS_OK;
251 };
252 PostTask(task, "OnRestoreMainWindow");
253 return WSError::WS_OK;
254 }
255
256 } // namespace OHOS::Rosen
257