• 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/system_session.h"
17 #include "common/include/session_permission.h"
18 #include "session/host/include/session.h"
19 #include "window_helper.h"
20 #include "window_manager_hilog.h"
21 
22 namespace OHOS::Rosen {
23 namespace {
24 constexpr HiviewDFX::HiLogLabel LABEL = { LOG_CORE, HILOG_DOMAIN_WINDOW, "SystemSession" };
25 } // namespace
26 
SystemSession(const SessionInfo & info,const sptr<SpecificSessionCallback> & specificCallback)27 SystemSession::SystemSession(const SessionInfo& info, const sptr<SpecificSessionCallback>& specificCallback)
28     : SceneSession(info, specificCallback)
29 {
30     WLOGFD("[WMSLife] Create SystemSession");
31     if (info.windowType_ == static_cast<uint32_t>(WindowType::WINDOW_TYPE_PIP)) {
32         // moveDragController for WINDOW_TYPE_PIP
33         moveDragController_ = new (std::nothrow) MoveDragController(GetPersistentId());
34         if (specificCallback != nullptr && specificCallback->onWindowInputPidChangeCallback_ != nullptr) {
35             moveDragController_->SetNotifyWindowPidChangeCallback(specificCallback_->onWindowInputPidChangeCallback_);
36         }
37     }
38     SetMoveDragCallback();
39 }
40 
~SystemSession()41 SystemSession::~SystemSession()
42 {
43     WLOGD("[WMSLife] ~SystemSession, id: %{public}d", GetPersistentId());
44 }
45 
UpdateCameraFloatWindowStatus(bool isShowing)46 void SystemSession::UpdateCameraFloatWindowStatus(bool isShowing)
47 {
48     if (GetWindowType() == WindowType::WINDOW_TYPE_FLOAT_CAMERA && specificCallback_ != nullptr) {
49         WLOGFD("[WMSSystem] CameraFloat status: %{public}d, id: %{public}d", isShowing, GetPersistentId());
50         specificCallback_->onCameraFloatSessionChange_(GetSessionProperty()->GetAccessTokenId(), isShowing);
51     }
52 }
53 
Show(sptr<WindowSessionProperty> property)54 WSError SystemSession::Show(sptr<WindowSessionProperty> property)
55 {
56     auto type = GetWindowType();
57     if (((type == WindowType::WINDOW_TYPE_TOAST) || (type == WindowType::WINDOW_TYPE_FLOAT)) &&
58         !SessionPermission::IsSystemCalling()) {
59         auto parentSession = GetParentSession();
60         if (parentSession == nullptr) {
61             WLOGFW("parent session is null");
62             return WSError::WS_ERROR_INVALID_PARENT;
63         }
64         if (parentSession->IsSessionForeground()) {
65             WLOGFW("parent session is not in foreground");
66             return WSError::WS_ERROR_INVALID_OPERATION;
67         }
68     }
69     auto task = [weakThis = wptr(this), property]() {
70         auto session = weakThis.promote();
71         if (!session) {
72             WLOGFE("session is null");
73             return WSError::WS_ERROR_DESTROYED_OBJECT;
74         }
75         WLOGFI("[WMSLife] Show session, id: %{public}d", session->GetPersistentId());
76 
77         // use property from client
78         if (property && property->GetAnimationFlag() == static_cast<uint32_t>(WindowAnimation::CUSTOM)) {
79             session->GetSessionProperty()->SetAnimationFlag(static_cast<uint32_t>(WindowAnimation::CUSTOM));
80             session->NotifyIsCustomAnimationPlaying(true);
81         }
82         session->UpdateCameraFloatWindowStatus(true);
83         auto ret = session->SceneSession::Foreground(property);
84         return ret;
85     };
86     PostTask(task, "Show");
87     return WSError::WS_OK;
88 }
89 
Hide()90 WSError SystemSession::Hide()
91 {
92     auto type = GetWindowType();
93     if (WindowHelper::IsSystemWindow(type) && Session::NeedSystemPermission(type)) {
94         if (type == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT) {
95             if (!SessionPermission::IsStartedByInputMethod()) {
96                 WLOGFE("[WMSLife]Hide permission denied, keyboard is not hidden by current input method");
97                 return WSError::WS_ERROR_INVALID_PERMISSION;
98             }
99         } else if (!SessionPermission::IsSystemCalling()) {
100             WLOGFE("[WMSLife]Hide permission denied id: %{public}d type:%{public}u", GetPersistentId(), type);
101             return WSError::WS_ERROR_INVALID_PERMISSION;
102         }
103     }
104     auto task = [weakThis = wptr(this)]() {
105         auto session = weakThis.promote();
106         if (!session) {
107             WLOGFE("[WMSLife] session is null");
108             return WSError::WS_ERROR_DESTROYED_OBJECT;
109         }
110         WLOGFI("[WMSLife] Hide session, id: %{public}d", session->GetPersistentId());
111 
112         auto ret = session->SetActive(false);
113         if (ret != WSError::WS_OK) {
114             return ret;
115         }
116         // background will remove surfaceNode, custom not execute
117         // not animation playing when already background; inactive may be animation playing
118         if (session->GetSessionProperty() &&
119             session->GetSessionProperty()->GetAnimationFlag() == static_cast<uint32_t>(WindowAnimation::CUSTOM)) {
120             session->NotifyIsCustomAnimationPlaying(true);
121             return WSError::WS_OK;
122         }
123         session->UpdateCameraFloatWindowStatus(false);
124         ret = session->SceneSession::Background();
125         return ret;
126     };
127     PostTask(task, "Hide");
128     return WSError::WS_OK;
129 }
130 
Disconnect(bool isFromClient)131 WSError SystemSession::Disconnect(bool isFromClient)
132 {
133     auto task = [weakThis = wptr(this), isFromClient]() {
134         auto session = weakThis.promote();
135         if (!session) {
136             WLOGFE("[WMSLife] session is null");
137             return WSError::WS_ERROR_DESTROYED_OBJECT;
138         }
139         WLOGFI("[WMSLife] Disconnect session, id: %{public}d", session->GetPersistentId());
140         session->SceneSession::Disconnect(isFromClient);
141         if (session->GetWindowType() == WindowType::WINDOW_TYPE_INPUT_METHOD_FLOAT) {
142             session->NotifyCallingSessionBackground();
143         }
144         session->UpdateCameraFloatWindowStatus(false);
145         return WSError::WS_OK;
146     };
147     PostTask(task, "Disconnect");
148     return WSError::WS_OK;
149 }
150 
ProcessPointDownSession(int32_t posX,int32_t posY)151 WSError SystemSession::ProcessPointDownSession(int32_t posX, int32_t posY)
152 {
153     const auto& id = GetPersistentId();
154     const auto& type = GetWindowType();
155     WLOGFI("id: %{public}d, type: %{public}d", id, type);
156     if (parentSession_ && parentSession_->CheckDialogOnForeground()) {
157         WLOGFI("Parent has dialog foreground, id: %{public}d, type: %{public}d", id, type);
158         parentSession_->HandlePointDownDialog();
159         if (!IsTopDialog()) {
160             return WSError::WS_OK;
161         }
162     }
163     if (type == WindowType::WINDOW_TYPE_DIALOG && GetSessionProperty() && GetSessionProperty()->GetRaiseEnabled()) {
164         RaiseToAppTopForPointDown();
165     }
166     PresentFocusIfPointDown();
167     return SceneSession::ProcessPointDownSession(posX, posY);
168 }
169 } // namespace OHOS::Rosen
170