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