• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "window_helper.h"
18 #include "pointer_event.h"
19 #include "window_manager_hilog.h"
20 
21 
22 namespace OHOS::Rosen {
23 namespace {
24 constexpr HiviewDFX::HiLogLabel LABEL = { LOG_CORE, HILOG_DOMAIN_WINDOW, "SubSession" };
25 } // namespace
26 
SubSession(const SessionInfo & info,const sptr<SpecificSessionCallback> & specificCallback)27 SubSession::SubSession(const SessionInfo& info, const sptr<SpecificSessionCallback>& specificCallback)
28     : SceneSession(info, specificCallback)
29 {
30     pcFoldScreenController_ = sptr<PcFoldScreenController>::MakeSptr(wptr(this), GetPersistentId());
31     moveDragController_ = sptr<MoveDragController>::MakeSptr(GetPersistentId(), GetWindowType());
32     if (specificCallback != nullptr &&
33         specificCallback->onWindowInputPidChangeCallback_ != nullptr) {
34         moveDragController_->SetNotifyWindowPidChangeCallback(specificCallback->onWindowInputPidChangeCallback_);
35     }
36     SetMoveDragCallback();
37     TLOGD(WmsLogTag::WMS_LIFE, "Create");
38 }
39 
~SubSession()40 SubSession::~SubSession()
41 {
42     TLOGD(WmsLogTag::WMS_LIFE, "id: %{public}d", GetPersistentId());
43 }
44 
Show(sptr<WindowSessionProperty> property)45 WSError SubSession::Show(sptr<WindowSessionProperty> property)
46 {
47     if (!CheckPermissionWithPropertyAnimation(property)) {
48         return WSError::WS_ERROR_NOT_SYSTEM_APP;
49     }
50     if (property->GetWindowFlags() & static_cast<uint32_t>(WindowFlag::WINDOW_FLAG_IS_TEXT_MENU) &&
51         GetForceHideState() != ForceHideState::NOT_HIDDEN) {
52         TLOGI(WmsLogTag::WMS_SUB, "UEC force hide, id: %{public}d forceHideState: %{public}d",
53             GetPersistentId(), GetForceHideState());
54         return WSError::WS_ERROR_INVALID_OPERATION;
55     }
56     PostTask([weakThis = wptr(this), property]() {
57         auto session = weakThis.promote();
58         if (!session) {
59             TLOGE(WmsLogTag::WMS_SUB, "session is null");
60             return WSError::WS_ERROR_DESTROYED_OBJECT;
61         }
62         TLOGI(WmsLogTag::WMS_LIFE, "Show session, id: %{public}d", session->GetPersistentId());
63 
64         auto parentSession = session->GetParentSession();
65         if (parentSession && session->GetShouldFollowParentWhenShow()) {
66             session->CheckAndMoveDisplayIdRecursively(parentSession->GetSessionProperty()->GetDisplayId());
67         } else {
68             TLOGNE(WmsLogTag::WMS_SUB, "session has no parent, id: %{public}d", session->GetPersistentId());
69         }
70         // use property from client
71         auto sessionProperty = session->GetSessionProperty();
72         if (property && property->GetAnimationFlag() == static_cast<uint32_t>(WindowAnimation::CUSTOM) &&
73             sessionProperty) {
74             sessionProperty->SetAnimationFlag(static_cast<uint32_t>(WindowAnimation::CUSTOM));
75             session->NotifyIsCustomAnimationPlaying(true);
76         }
77         auto ret = session->SceneSession::Foreground(property);
78         return ret;
79     }, "Show");
80     return WSError::WS_OK;
81 }
82 
NotifySessionRectChange(const WSRect & rect,SizeChangeReason reason,DisplayId displayId,const RectAnimationConfig & rectAnimationConfig)83 void SubSession::NotifySessionRectChange(const WSRect& rect, SizeChangeReason reason, DisplayId displayId,
84     const RectAnimationConfig& rectAnimationConfig)
85 {
86     if (reason == SizeChangeReason::DRAG_END) {
87         SetShouldFollowParentWhenShow(false);
88     }
89     SceneSession::NotifySessionRectChange(rect, reason, displayId, rectAnimationConfig);
90 }
91 
UpdateSessionRectInner(const WSRect & rect,SizeChangeReason reason,const MoveConfiguration & moveConfiguration,const RectAnimationConfig & rectAnimationConfig)92 void SubSession::UpdateSessionRectInner(const WSRect& rect, SizeChangeReason reason,
93     const MoveConfiguration& moveConfiguration, const RectAnimationConfig& rectAnimationConfig)
94 {
95     if (moveConfiguration.displayId != DISPLAY_ID_INVALID) {
96         SetShouldFollowParentWhenShow(false);
97     }
98     SceneSession::UpdateSessionRectInner(rect, reason, moveConfiguration, rectAnimationConfig);
99 }
100 
Hide()101 WSError SubSession::Hide()
102 {
103     return Hide(false);  // async mode
104 }
105 
HideSync()106 WSError SubSession::HideSync()
107 {
108     return Hide(true);  // sync mode
109 }
110 
Hide(bool needSyncHide)111 WSError SubSession::Hide(bool needSyncHide)
112 {
113     if (!CheckPermissionWithPropertyAnimation(GetSessionProperty())) {
114         return WSError::WS_ERROR_NOT_SYSTEM_APP;
115     }
116     auto task = [weakThis = wptr(this)]() {
117         auto session = weakThis.promote();
118         if (!session) {
119             TLOGNE(WmsLogTag::WMS_SUB, "session is null");
120             return WSError::WS_ERROR_DESTROYED_OBJECT;
121         }
122         TLOGNI(WmsLogTag::WMS_LIFE, "Hide session, id: %{public}d", session->GetPersistentId());
123         auto ret = session->SetActive(false);
124         if (ret != WSError::WS_OK) {
125             return ret;
126         }
127         // background will remove surfaceNode, custom not execute
128         // not animation playing when already background; inactive may be animation playing
129         auto sessionProperty = session->GetSessionProperty();
130         if (sessionProperty &&
131             sessionProperty->GetAnimationFlag() == static_cast<uint32_t>(WindowAnimation::CUSTOM)) {
132             session->NotifyIsCustomAnimationPlaying(true);
133             return WSError::WS_OK;
134         }
135         ret = session->SceneSession::Background();
136         return ret;
137     };
138 
139     if (needSyncHide) {
140         return PostSyncTask(task, "HideSync");
141     }
142 
143     PostTask(task, "HideAsync");
144     return WSError::WS_OK;
145 }
146 
ProcessPointDownSession(int32_t posX,int32_t posY)147 WSError SubSession::ProcessPointDownSession(int32_t posX, int32_t posY)
148 {
149     const auto& id = GetPersistentId();
150     TLOGD(WmsLogTag::WMS_INPUT_KEY_FLOW, "id:%{public}d, type:%{public}d", id, GetWindowType());
151     auto isModal = IsModal();
152     auto parentSession = GetParentSession();
153     if (!isModal && parentSession && parentSession->CheckDialogOnForeground()) {
154         WLOGFI("Has dialog foreground, id: %{public}d, type: %{public}d", id, GetWindowType());
155         return WSError::WS_OK;
156     }
157     if (isModal) {
158         Session::ProcessClickModalWindowOutside(posX, posY);
159     }
160     auto sessionProperty = GetSessionProperty();
161     if (sessionProperty && sessionProperty->GetRaiseEnabled()) {
162         RaiseToAppTopForPointDown();
163     }
164     PresentFocusIfPointDown();
165     return SceneSession::ProcessPointDownSession(posX, posY);
166 }
167 
GetMissionId() const168 int32_t SubSession::GetMissionId() const
169 {
170     auto parentSession = GetParentSession();
171     return parentSession != nullptr ? parentSession->GetPersistentId() : SceneSession::GetMissionId();
172 }
173 
TransferKeyEvent(const std::shared_ptr<MMI::KeyEvent> & keyEvent)174 WSError SubSession::TransferKeyEvent(const std::shared_ptr<MMI::KeyEvent>& keyEvent)
175 {
176     if (!IsSessionValid()) {
177         return WSError::WS_ERROR_INVALID_SESSION;
178     }
179     if (keyEvent == nullptr) {
180         WLOGFE("KeyEvent is nullptr");
181         return WSError::WS_ERROR_NULLPTR;
182     }
183     auto parentSession = GetParentSession();
184     if (parentSession && parentSession->CheckDialogOnForeground()) {
185         TLOGD(WmsLogTag::WMS_DIALOG, "Its main window has dialog on foreground, not transfer pointer event");
186         return WSError::WS_ERROR_INVALID_PERMISSION;
187     }
188 
189     WSError ret = Session::TransferKeyEvent(keyEvent);
190     return ret;
191 }
192 
UpdatePointerArea(const WSRect & rect)193 void SubSession::UpdatePointerArea(const WSRect& rect)
194 {
195     auto property = GetSessionProperty();
196     if (!(property->IsDecorEnable() && GetWindowMode() == WindowMode::WINDOW_MODE_FLOATING)) {
197         return;
198     }
199     Session::UpdatePointerArea(rect);
200 }
201 
CheckPointerEventDispatch(const std::shared_ptr<MMI::PointerEvent> & pointerEvent) const202 bool SubSession::CheckPointerEventDispatch(const std::shared_ptr<MMI::PointerEvent>& pointerEvent) const
203 {
204     auto sessionState = GetSessionState();
205     int32_t action = pointerEvent->GetPointerAction();
206     auto isPC = systemConfig_.IsPcWindow();
207     if (isPC && sessionState != SessionState::STATE_FOREGROUND &&
208         sessionState != SessionState::STATE_ACTIVE &&
209         action != MMI::PointerEvent::POINTER_ACTION_LEAVE_WINDOW) {
210         WLOGFW("Current Session Info: [persistentId: %{public}d, "
211             "state: %{public}d, action:%{public}d]", GetPersistentId(), GetSessionState(), action);
212         return false;
213     }
214     return true;
215 }
216 
RectCheck(uint32_t curWidth,uint32_t curHeight)217 void SubSession::RectCheck(uint32_t curWidth, uint32_t curHeight)
218 {
219     uint32_t minWidth = GetSystemConfig().miniWidthOfSubWindow_;
220     uint32_t minHeight = GetSystemConfig().miniHeightOfSubWindow_;
221     uint32_t maxFloatingWindowSize = GetSystemConfig().maxFloatingWindowSize_;
222     RectSizeCheckProcess(curWidth, curHeight, minWidth, minHeight, maxFloatingWindowSize);
223 }
224 
IsTopmost() const225 bool SubSession::IsTopmost() const
226 {
227     bool isTopmost = false;
228     auto sessionProperty = GetSessionProperty();
229     if (sessionProperty) {
230         isTopmost = sessionProperty->IsTopmost();
231     }
232     TLOGI(WmsLogTag::WMS_SUB, "isTopmost: %{public}d", isTopmost);
233     return isTopmost;
234 }
235 
IsModal() const236 bool SubSession::IsModal() const
237 {
238     return WindowHelper::IsModalSubWindow(GetSessionProperty()->GetWindowType(),
239                                           GetSessionProperty()->GetWindowFlags());
240 }
241 
IsApplicationModal() const242 bool SubSession::IsApplicationModal() const
243 {
244     return WindowHelper::IsApplicationModalSubWindow(GetSessionProperty()->GetWindowType(),
245                                                      GetSessionProperty()->GetWindowFlags());
246 }
247 
IsVisibleForeground() const248 bool SubSession::IsVisibleForeground() const
249 {
250     const auto& mainOrFloatSession = GetMainOrFloatSession();
251     if (mainOrFloatSession) {
252         return mainOrFloatSession->IsVisibleForeground() && Session::IsVisibleForeground();
253     }
254     return Session::IsVisibleForeground();
255 }
256 
SetParentSessionCallback(NotifySetParentSessionFunc && func)257 void SubSession::SetParentSessionCallback(NotifySetParentSessionFunc&& func)
258 {
259     const char* const where = __func__;
260     PostTask([weakThis = wptr(this), where, func = std::move(func)] {
261         auto session = weakThis.promote();
262         if (!session || !func) {
263             TLOGNE(WmsLogTag::WMS_SUB, "%{public}s session or func is nullptr", where);
264             return;
265         }
266         session->setParentSessionFunc_ = std::move(func);
267         TLOGND(WmsLogTag::WMS_SUB, "%{public}s id: %{public}d", where,
268             session->GetPersistentId());
269     }, __func__);
270 }
271 
NotifySetParentSession(int32_t oldParentWindowId,int32_t newParentWindowId)272 WMError SubSession::NotifySetParentSession(int32_t oldParentWindowId, int32_t newParentWindowId)
273 {
274     return PostSyncTask([weakThis = wptr(this), oldParentWindowId, newParentWindowId, where = __func__] {
275         auto session = weakThis.promote();
276         if (!session) {
277             TLOGNE(WmsLogTag::WMS_SUB, "%{public}s session is nullptr", where);
278             return WMError::WM_ERROR_INVALID_WINDOW;
279         }
280         if (session->setParentSessionFunc_) {
281             session->setParentSessionFunc_(oldParentWindowId, newParentWindowId);
282             TLOGND(WmsLogTag::WMS_SUB, "%{public}s id: %{public}d oldParentWindowId: %{public}d "
283                 "newParentWindowId: %{public}d", where, session->GetPersistentId(), oldParentWindowId,
284                 newParentWindowId);
285         }
286         return WMError::WM_OK;
287     }, __func__);
288 }
289 
NotifyFollowParentMultiScreenPolicy(bool enabled)290 WSError SubSession::NotifyFollowParentMultiScreenPolicy(bool enabled)
291 {
292     PostTask([weakThis = wptr(this), enabled, funcName = __func__] {
293         auto session = weakThis.promote();
294         if (!session) {
295             TLOGNE(WmsLogTag::WMS_SUB, "%{public}s: session is null", funcName);
296             return;
297         }
298         TLOGNI(WmsLogTag::WMS_SUB, "%{public}s: enabled:%{public}d", funcName, enabled);
299         session->isFollowParentMultiScreenPolicy_ = enabled;
300     }, __func__);
301     return WSError::WS_OK;
302 }
303 
IsFollowParentMultiScreenPolicy() const304 bool SubSession::IsFollowParentMultiScreenPolicy() const
305 {
306     return isFollowParentMultiScreenPolicy_;
307 }
308 
SetSubWindowZLevel(int32_t zLevel)309 WSError SubSession::SetSubWindowZLevel(int32_t zLevel)
310 {
311     PostTask([weakThis = wptr(this), zLevel]() {
312         auto session = weakThis.promote();
313         if (!session) {
314             TLOGE(WmsLogTag::WMS_HIERARCHY, "session is null");
315             return;
316         }
317         auto property = session->GetSessionProperty();
318         TLOGI(WmsLogTag::WMS_HIERARCHY, "Notify session zLevel change, id: %{public}d, zLevel: %{public}d",
319             session->GetPersistentId(), zLevel);
320         property->SetSubWindowZLevel(zLevel);
321         if (session->onSubSessionZLevelChange_) {
322             session->onSubSessionZLevelChange_(zLevel);
323         }
324     }, "SetSubWindowZLevel");
325     return WSError::WS_OK;
326 }
327 
GetSubWindowZLevel() const328 int32_t SubSession::GetSubWindowZLevel() const
329 {
330     int32_t zLevel = 0;
331     auto sessionProperty = GetSessionProperty();
332     zLevel = sessionProperty->GetSubWindowZLevel();
333     TLOGI(WmsLogTag::WMS_HIERARCHY, "zLevel: %{public}d", zLevel);
334     return zLevel;
335 }
336 } // namespace OHOS::Rosen
337