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/sub_session.h"
17 #include "screen_session_manager_client/include/screen_session_manager_client.h"
18
19 #include "common/include/session_permission.h"
20 #include "key_event.h"
21 #include "window_helper.h"
22 #include "parameters.h"
23 #include "pointer_event.h"
24 #include "window_manager_hilog.h"
25
26
27 namespace OHOS::Rosen {
28 namespace {
29 constexpr HiviewDFX::HiLogLabel LABEL = { LOG_CORE, HILOG_DOMAIN_WINDOW, "SubSession" };
30 } // namespace
31
SubSession(const SessionInfo& info, const sptr<SpecificSessionCallback>& specificCallback)32 SubSession::SubSession(const SessionInfo& info, const sptr<SpecificSessionCallback>& specificCallback)
33 : SceneSession(info, specificCallback)
34 {
35 moveDragController_ = sptr<MoveDragController>::MakeSptr(GetPersistentId());
36 if (specificCallback != nullptr &&
37 specificCallback->onWindowInputPidChangeCallback_ != nullptr) {
38 moveDragController_->SetNotifyWindowPidChangeCallback(specificCallback->onWindowInputPidChangeCallback_);
39 }
40 SetMoveDragCallback();
41 TLOGD(WmsLogTag::WMS_LIFE, "Create SubSession");
42 }
43
~SubSession()44 SubSession::~SubSession()
45 {
46 TLOGD(WmsLogTag::WMS_LIFE, "~SubSession, id: %{public}d", GetPersistentId());
47 }
48
Show(sptr<WindowSessionProperty> property)49 WSError SubSession::Show(sptr<WindowSessionProperty> property)
50 {
51 if (!CheckPermissionWithPropertyAnimation(property)) {
52 return WSError::WS_ERROR_NOT_SYSTEM_APP;
53 }
54 auto task = [weakThis = wptr(this), property]() {
55 auto session = weakThis.promote();
56 if (!session) {
57 TLOGE(WmsLogTag::WMS_SUB, "session is null");
58 return WSError::WS_ERROR_DESTROYED_OBJECT;
59 }
60 TLOGI(WmsLogTag::WMS_LIFE, "Show session, id: %{public}d", session->GetPersistentId());
61
62 // use property from client
63 auto sessionProperty = session->GetSessionProperty();
64 if (property && property->GetAnimationFlag() == static_cast<uint32_t>(WindowAnimation::CUSTOM) &&
65 sessionProperty) {
66 sessionProperty->SetAnimationFlag(static_cast<uint32_t>(WindowAnimation::CUSTOM));
67 session->NotifyIsCustomAnimationPlaying(true);
68 }
69 auto ret = session->SceneSession::Foreground(property);
70 return ret;
71 };
72 PostTask(task, "Show");
73 return WSError::WS_OK;
74 }
75
Hide()76 WSError SubSession::Hide()
77 {
78 if (!CheckPermissionWithPropertyAnimation(GetSessionProperty())) {
79 return WSError::WS_ERROR_NOT_SYSTEM_APP;
80 }
81 auto task = [weakThis = wptr(this)]() {
82 auto session = weakThis.promote();
83 if (!session) {
84 TLOGE(WmsLogTag::WMS_SUB, "session is null");
85 return WSError::WS_ERROR_DESTROYED_OBJECT;
86 }
87 TLOGI(WmsLogTag::WMS_LIFE, "Hide session, id: %{public}d", session->GetPersistentId());
88 auto ret = session->SetActive(false);
89 if (ret != WSError::WS_OK) {
90 return ret;
91 }
92 // background will remove surfaceNode, custom not execute
93 // not animation playing when already background; inactive may be animation playing
94 auto sessionProperty = session->GetSessionProperty();
95 if (sessionProperty &&
96 sessionProperty->GetAnimationFlag() == static_cast<uint32_t>(WindowAnimation::CUSTOM)) {
97 session->NotifyIsCustomAnimationPlaying(true);
98 return WSError::WS_OK;
99 }
100 ret = session->SceneSession::Background();
101 return ret;
102 };
103 PostTask(task, "Hide");
104 return WSError::WS_OK;
105 }
106
ProcessPointDownSession(int32_t posX, int32_t posY)107 WSError SubSession::ProcessPointDownSession(int32_t posX, int32_t posY)
108 {
109 const auto& id = GetPersistentId();
110 WLOGFI("id: %{public}d, type: %{public}d", id, GetWindowType());
111 auto isModal = IsModal();
112 auto parentSession = GetParentSession();
113 if (!isModal && parentSession && parentSession->CheckDialogOnForeground()) {
114 WLOGFI("Has dialog foreground, id: %{public}d, type: %{public}d", id, GetWindowType());
115 return WSError::WS_OK;
116 }
117 if (isModal) {
118 Session::ProcessClickModalSpecificWindowOutside(posX, posY);
119 }
120 auto sessionProperty = GetSessionProperty();
121 if (sessionProperty && sessionProperty->GetRaiseEnabled()) {
122 RaiseToAppTopForPointDown();
123 }
124 PresentFocusIfPointDown();
125 return SceneSession::ProcessPointDownSession(posX, posY);
126 }
127
GetMissionId() const128 int32_t SubSession::GetMissionId() const
129 {
130 auto parentSession = GetParentSession();
131 return parentSession != nullptr ? parentSession->GetPersistentId() : SceneSession::GetMissionId();
132 }
133
TransferKeyEvent(const std::shared_ptr<MMI::KeyEvent>& keyEvent)134 WSError SubSession::TransferKeyEvent(const std::shared_ptr<MMI::KeyEvent>& keyEvent)
135 {
136 if (!IsSessionValid()) {
137 return WSError::WS_ERROR_INVALID_SESSION;
138 }
139 if (keyEvent == nullptr) {
140 WLOGFE("KeyEvent is nullptr");
141 return WSError::WS_ERROR_NULLPTR;
142 }
143 auto parentSession = GetParentSession();
144 if (parentSession && parentSession->CheckDialogOnForeground()) {
145 TLOGD(WmsLogTag::WMS_DIALOG, "Its main window has dialog on foreground, not transfer pointer event");
146 return WSError::WS_ERROR_INVALID_PERMISSION;
147 }
148
149 WSError ret = Session::TransferKeyEvent(keyEvent);
150 return ret;
151 }
152
UpdatePointerArea(const WSRect& rect)153 void SubSession::UpdatePointerArea(const WSRect& rect)
154 {
155 auto property = GetSessionProperty();
156 if (!(property->IsDecorEnable() && GetWindowMode() == WindowMode::WINDOW_MODE_FLOATING)) {
157 return;
158 }
159 Session::UpdatePointerArea(rect);
160 }
161
CheckPointerEventDispatch(const std::shared_ptr<MMI::PointerEvent>& pointerEvent) const162 bool SubSession::CheckPointerEventDispatch(const std::shared_ptr<MMI::PointerEvent>& pointerEvent) const
163 {
164 auto sessionState = GetSessionState();
165 int32_t action = pointerEvent->GetPointerAction();
166 auto isPC = systemConfig_.IsPcWindow();
167 if (isPC && sessionState != SessionState::STATE_FOREGROUND &&
168 sessionState != SessionState::STATE_ACTIVE &&
169 action != MMI::PointerEvent::POINTER_ACTION_LEAVE_WINDOW) {
170 WLOGFW("Current Session Info: [persistentId: %{public}d, "
171 "state: %{public}d, action:%{public}d]", GetPersistentId(), GetSessionState(), action);
172 return false;
173 }
174 return true;
175 }
176
RectCheck(uint32_t curWidth, uint32_t curHeight)177 void SubSession::RectCheck(uint32_t curWidth, uint32_t curHeight)
178 {
179 uint32_t minWidth = GetSystemConfig().miniWidthOfSubWindow_;
180 uint32_t minHeight = GetSystemConfig().miniHeightOfSubWindow_;
181 uint32_t maxFloatingWindowSize = GetSystemConfig().maxFloatingWindowSize_;
182 RectSizeCheckProcess(curWidth, curHeight, minWidth, minHeight, maxFloatingWindowSize);
183 }
184
IsTopmost() const185 bool SubSession::IsTopmost() const
186 {
187 bool isTopmost = false;
188 auto sessionProperty = GetSessionProperty();
189 if (sessionProperty) {
190 isTopmost = sessionProperty->IsTopmost();
191 }
192 TLOGI(WmsLogTag::WMS_SUB, "isTopmost: %{public}d", isTopmost);
193 return isTopmost;
194 }
195
IsModal() const196 bool SubSession::IsModal() const
197 {
198 bool isModal = false;
199 auto property = GetSessionProperty();
200 if (property != nullptr) {
201 isModal = WindowHelper::IsModalSubWindow(property->GetWindowType(), property->GetWindowFlags());
202 }
203 return isModal;
204 }
205
IsVisibleForeground() const206 bool SubSession::IsVisibleForeground() const
207 {
208 if (parentSession_ && WindowHelper::IsMainWindow(parentSession_->GetWindowType())) {
209 return parentSession_->IsVisibleForeground() && Session::IsVisibleForeground();
210 }
211 return Session::IsVisibleForeground();
212 }
213 } // namespace OHOS::Rosen
214