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 "session/host/include/scene_persistent_storage.h"
20
21 namespace OHOS::Rosen {
22 namespace {
23 constexpr HiviewDFX::HiLogLabel LABEL = { LOG_CORE, HILOG_DOMAIN_WINDOW, "MainSession" };
24 } // namespace
25
MainSession(const SessionInfo & info,const sptr<SpecificSessionCallback> & specificCallback)26 MainSession::MainSession(const SessionInfo& info, const sptr<SpecificSessionCallback>& specificCallback)
27 : SceneSession(info, specificCallback)
28 {
29 scenePersistence_ = new ScenePersistence(info.bundleName_, GetPersistentId());
30 if (info.persistentId_ != 0 && info.persistentId_ != GetPersistentId()) {
31 // persistentId changed due to id conflicts. Need to rename the old snapshot if exists
32 scenePersistence_->RenameSnapshotFromOldPersistentId(info.persistentId_);
33 }
34 moveDragController_ = new (std::nothrow) MoveDragController(GetPersistentId());
35 if (moveDragController_ != nullptr && specificCallback != nullptr &&
36 specificCallback->onWindowInputPidChangeCallback_ != nullptr) {
37 moveDragController_->SetNotifyWindowPidChangeCallback(specificCallback->onWindowInputPidChangeCallback_);
38 }
39 SetMoveDragCallback();
40 std::string key = GetRatioPreferenceKey();
41 if (!key.empty()) {
42 if (ScenePersistentStorage::HasKey(key, ScenePersistentStorageType::ASPECT_RATIO)) {
43 ScenePersistentStorage::Get(key, aspectRatio_, ScenePersistentStorageType::ASPECT_RATIO);
44 WLOGD("SceneSession init aspectRatio , key %{public}s, value: %{public}f", key.c_str(), aspectRatio_);
45 if (moveDragController_) {
46 moveDragController_->SetAspectRatio(aspectRatio_);
47 }
48 }
49 }
50
51 WLOGFD("Create MainSession");
52 }
53
~MainSession()54 MainSession::~MainSession()
55 {
56 WLOGD("~MainSession, id: %{public}d", GetPersistentId());
57 }
58
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)59 WSError MainSession::Reconnect(const sptr<ISessionStage>& sessionStage, const sptr<IWindowEventChannel>& eventChannel,
60 const std::shared_ptr<RSSurfaceNode>& surfaceNode, sptr<WindowSessionProperty> property, sptr<IRemoteObject> token,
61 int32_t pid, int32_t uid)
62 {
63 return PostSyncTask([weakThis = wptr(this), sessionStage, eventChannel, surfaceNode, property, token, pid, uid]() {
64 auto session = weakThis.promote();
65 if (!session) {
66 WLOGFE("session is null");
67 return WSError::WS_ERROR_DESTROYED_OBJECT;
68 }
69 WSError ret = session->Session::Reconnect(sessionStage, eventChannel, surfaceNode, property, token, pid, uid);
70 if (ret != WSError::WS_OK) {
71 return ret;
72 }
73 WindowState windowState = property->GetWindowState();
74 if (windowState == WindowState::STATE_SHOWN) {
75 session->isActive_ = true;
76 session->UpdateSessionState(SessionState::STATE_ACTIVE);
77 } else {
78 session->isActive_ = false;
79 session->UpdateSessionState(SessionState::STATE_BACKGROUND);
80 if (session->scenePersistence_) {
81 session->scenePersistence_->SetHasSnapshot(true);
82 }
83 }
84 return ret;
85 });
86 }
87
ProcessPointDownSession(int32_t posX,int32_t posY)88 WSError MainSession::ProcessPointDownSession(int32_t posX, int32_t posY)
89 {
90 const auto& id = GetPersistentId();
91 WLOGFI("id: %{public}d, type: %{public}d", id, GetWindowType());
92 if (CheckDialogOnForeground()) {
93 HandlePointDownDialog();
94 return WSError::WS_OK;
95 }
96 PresentFocusIfPointDown();
97 return SceneSession::ProcessPointDownSession(posX, posY);
98 }
99
NotifyForegroundInteractiveStatus(bool interactive)100 void MainSession::NotifyForegroundInteractiveStatus(bool interactive)
101 {
102 SetForegroundInteractiveStatus(interactive);
103 if (!IsSessionValid() || !sessionStage_) {
104 TLOGW(WmsLogTag::WMS_MAIN, "Session or sessionStage is invalid, id: %{public}d state: %{public}u",
105 GetPersistentId(), GetSessionState());
106 return;
107 }
108 const auto& state = GetSessionState();
109 if (isVisible_ || state == SessionState::STATE_ACTIVE || state == SessionState::STATE_FOREGROUND) {
110 WLOGFI("NotifyForegroundInteractiveStatus %{public}d", interactive);
111 sessionStage_->NotifyForegroundInteractiveStatus(interactive);
112 }
113 }
114
TransferKeyEvent(const std::shared_ptr<MMI::KeyEvent> & keyEvent)115 WSError MainSession::TransferKeyEvent(const std::shared_ptr<MMI::KeyEvent>& keyEvent)
116 {
117 if (!IsSessionValid()) {
118 return WSError::WS_ERROR_INVALID_SESSION;
119 }
120 if (keyEvent == nullptr) {
121 WLOGFE("KeyEvent is nullptr");
122 return WSError::WS_ERROR_NULLPTR;
123 }
124 if (CheckDialogOnForeground()) {
125 TLOGD(WmsLogTag::WMS_DIALOG, "Has dialog on foreground, not transfer pointer event");
126 return WSError::WS_ERROR_INVALID_PERMISSION;
127 }
128
129 WSError ret = Session::TransferKeyEvent(keyEvent);
130 return ret;
131 }
132
UpdatePointerArea(const WSRect & rect)133 void MainSession::UpdatePointerArea(const WSRect& rect)
134 {
135 if (GetWindowMode() != WindowMode::WINDOW_MODE_FLOATING) {
136 return;
137 }
138 Session::UpdatePointerArea(rect);
139 }
140
CheckPointerEventDispatch(const std::shared_ptr<MMI::PointerEvent> & pointerEvent) const141 bool MainSession::CheckPointerEventDispatch(const std::shared_ptr<MMI::PointerEvent>& pointerEvent) const
142 {
143 auto sessionState = GetSessionState();
144 int32_t action = pointerEvent->GetPointerAction();
145 if (sessionState != SessionState::STATE_FOREGROUND &&
146 sessionState != SessionState::STATE_ACTIVE &&
147 action != MMI::PointerEvent::POINTER_ACTION_LEAVE_WINDOW) {
148 WLOGFW("Current Session Info: [persistentId: %{public}d, "
149 "state: %{public}d, action:%{public}d]", GetPersistentId(), GetSessionState(), action);
150 return false;
151 }
152 return true;
153 }
154
SetTopmost(bool topmost)155 WSError MainSession::SetTopmost(bool topmost)
156 {
157 TLOGI(WmsLogTag::WMS_LAYOUT, "SetTopmost id: %{public}d, topmost: %{public}d", GetPersistentId(), topmost);
158 auto task = [weakThis = wptr(this), topmost]() {
159 auto session = weakThis.promote();
160 if (!session) {
161 TLOGE(WmsLogTag::WMS_LAYOUT, "session is null");
162 return;
163 }
164 auto property = session->GetSessionProperty();
165 if (property) {
166 TLOGI(WmsLogTag::WMS_LAYOUT, "Notify session topmost change, id: %{public}d, topmost: %{public}u",
167 session->GetPersistentId(), topmost);
168 property->SetTopmost(topmost);
169 if (session->sessionChangeCallback_ && session->sessionChangeCallback_->onSessionTopmostChange_) {
170 session->sessionChangeCallback_->onSessionTopmostChange_(topmost);
171 }
172 }
173 };
174 PostTask(task, "SetTopmost");
175 return WSError::WS_OK;
176 }
177
IsTopmost() const178 bool MainSession::IsTopmost() const
179 {
180 return GetSessionProperty()->IsTopmost();
181 }
182
RectCheck(uint32_t curWidth,uint32_t curHeight)183 void MainSession::RectCheck(uint32_t curWidth, uint32_t curHeight)
184 {
185 uint32_t minWidth = GetSystemConfig().miniWidthOfMainWindow_;
186 uint32_t minHeight = GetSystemConfig().miniHeightOfMainWindow_;
187 uint32_t maxFloatingWindowSize = GetSystemConfig().maxFloatingWindowSize_;
188 RectSizeCheckProcess(curWidth, curHeight, minWidth, minHeight, maxFloatingWindowSize);
189 }
190
SetExitSplitOnBackground(bool isExitSplitOnBackground)191 void MainSession::SetExitSplitOnBackground(bool isExitSplitOnBackground)
192 {
193 TLOGI(WmsLogTag::WMS_MULTI_WINDOW, "id: %{public}d, isExitSplitOnBackground: %{public}d", persistentId_,
194 isExitSplitOnBackground);
195 isExitSplitOnBackground_ = isExitSplitOnBackground;
196 }
197
IsExitSplitOnBackground() const198 bool MainSession::IsExitSplitOnBackground() const
199 {
200 return isExitSplitOnBackground_;
201 }
202
NotifyClientToUpdateInteractive(bool interactive)203 void MainSession::NotifyClientToUpdateInteractive(bool interactive)
204 {
205 if (!sessionStage_) {
206 return;
207 }
208 const auto state = GetSessionState();
209 if (state == SessionState::STATE_ACTIVE || state == SessionState::STATE_FOREGROUND) {
210 WLOGFI("%{public}d", interactive);
211 sessionStage_->NotifyForegroundInteractiveStatus(interactive);
212 isClientInteractive_ = interactive;
213 }
214 }
215 } // namespace OHOS::Rosen
216