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/scb_system_session.h"
17
18 #include <hisysevent.h>
19 #include "key_event.h"
20 #include "pointer_event.h"
21 #include <ui/rs_surface_node.h>
22 #include "window_manager_hilog.h"
23
24 namespace OHOS::Rosen {
25 namespace {
26 constexpr HiviewDFX::HiLogLabel LABEL = { LOG_CORE, HILOG_DOMAIN_WINDOW, "SCBSystemSession" };
27 } // namespace
28
SCBSystemSession(const SessionInfo& info, const sptr<SpecificSessionCallback>& specificCallback)29 SCBSystemSession::SCBSystemSession(const SessionInfo& info, const sptr<SpecificSessionCallback>& specificCallback)
30 : SceneSession(info, specificCallback)
31 {
32 auto name = sessionInfo_.bundleName_;
33 auto pos = name.find_last_of('.');
34 name = (pos == std::string::npos) ? name : name.substr(pos + 1); // skip '.'
35 if (sessionInfo_.isSystem_) {
36 RSSurfaceNodeConfig config;
37 config.SurfaceNodeName = name;
38 config.surfaceWindowType = SurfaceWindowType::SYSTEM_SCB_WINDOW;
39 surfaceNode_ = Rosen::RSSurfaceNode::Create(config, Rosen::RSSurfaceNodeType::APP_WINDOW_NODE);
40 }
41 WLOGFD("Create SCBSystemSession");
42 }
43
~SCBSystemSession()44 SCBSystemSession::~SCBSystemSession()
45 {
46 WLOGD("~SCBSystemSession, id: %{public}d", GetPersistentId());
47 }
48
ProcessPointDownSession(int32_t posX, int32_t posY)49 WSError SCBSystemSession::ProcessPointDownSession(int32_t posX, int32_t posY)
50 {
51 const auto& id = GetPersistentId();
52 const auto& type = GetWindowType();
53 WLOGFI("id: %{public}d, type: %{public}d", id, type);
54 PresentFocusIfPointDown();
55 return SceneSession::ProcessPointDownSession(posX, posY);
56 }
57
NotifyClientToUpdateRect(const std::string& updateReason, std::shared_ptr<RSTransaction> rsTransaction)58 WSError SCBSystemSession::NotifyClientToUpdateRect(const std::string& updateReason,
59 std::shared_ptr<RSTransaction> rsTransaction)
60 {
61 auto task = [weakThis = wptr(this), rsTransaction, updateReason]() {
62 auto session = weakThis.promote();
63 if (!session) {
64 WLOGFE("session is null");
65 return WSError::WS_ERROR_DESTROYED_OBJECT;
66 }
67 WSError ret = session->NotifyClientToUpdateRectTask(updateReason, rsTransaction);
68 if (session->specificCallback_ != nullptr && session->specificCallback_->onUpdateAvoidArea_ != nullptr &&
69 session->specificCallback_->onClearDisplayStatusBarTemporarilyFlags_ != nullptr) {
70 if (Session::IsScbCoreEnabled()) {
71 session->dirtyFlags_ |= static_cast<uint32_t>(SessionUIDirtyFlag::AVOID_AREA);
72 } else {
73 session->specificCallback_->onUpdateAvoidArea_(session->GetPersistentId());
74 }
75 session->specificCallback_->onClearDisplayStatusBarTemporarilyFlags_();
76 }
77 if (session->GetWindowType() == WindowType::WINDOW_TYPE_KEYBOARD_PANEL &&
78 session->keyboardPanelRectUpdateCallback_ && session->isKeyboardPanelEnabled_) {
79 session->keyboardPanelRectUpdateCallback_();
80 }
81 // clear after use
82 if (session->reason_ != SizeChangeReason::DRAG) {
83 session->reason_ = SizeChangeReason::UNDEFINED;
84 session->dirtyFlags_ &= ~static_cast<uint32_t>(SessionUIDirtyFlag::RECT);
85 }
86 return ret;
87 };
88 PostTask(task, "NotifyClientToUpdateRect");
89 return WSError::WS_OK;
90 }
91
SetKeyboardPanelRectUpdateCallback(const KeyboardPanelRectUpdateCallback& func)92 void SCBSystemSession::SetKeyboardPanelRectUpdateCallback(const KeyboardPanelRectUpdateCallback& func)
93 {
94 keyboardPanelRectUpdateCallback_ = func;
95 }
96
BindKeyboardSession(sptr<SceneSession> session)97 void SCBSystemSession::BindKeyboardSession(sptr<SceneSession> session)
98 {
99 if (session == nullptr) {
100 TLOGE(WmsLogTag::WMS_KEYBOARD, "session is nullptr");
101 return;
102 }
103 keyboardSession_ = session;
104 KeyboardPanelRectUpdateCallback onKeyboardPanelRectUpdate = [this]() {
105 if (this->keyboardSession_ != nullptr) {
106 this->keyboardSession_->OnKeyboardPanelUpdated();
107 }
108 };
109 SetKeyboardPanelRectUpdateCallback(onKeyboardPanelRectUpdate);
110 TLOGI(WmsLogTag::WMS_KEYBOARD, "Success, id: %{public}d", keyboardSession_->GetPersistentId());
111 }
112
GetKeyboardSession() const113 sptr<SceneSession> SCBSystemSession::GetKeyboardSession() const
114 {
115 return keyboardSession_;
116 }
117
PresentFocusIfPointDown()118 void SCBSystemSession::PresentFocusIfPointDown()
119 {
120 WLOGFI("PresentFocusIfPointDown, id: %{public}d, type: %{public}d", GetPersistentId(), GetWindowType());
121 if (!isFocused_ && GetFocusable()) {
122 FocusChangeReason reason = FocusChangeReason::CLICK;
123 NotifyRequestFocusStatusNotifyManager(true, false, reason);
124 NotifyClick();
125 }
126 }
127
TransferKeyEvent(const std::shared_ptr<MMI::KeyEvent>& keyEvent)128 WSError SCBSystemSession::TransferKeyEvent(const std::shared_ptr<MMI::KeyEvent>& keyEvent)
129 {
130 if (keyEvent == nullptr) {
131 WLOGFE("KeyEvent is nullptr");
132 return WSError::WS_ERROR_NULLPTR;
133 }
134
135 WSError ret = Session::TransferKeyEvent(keyEvent);
136 return ret;
137 }
138
PresentFoucusIfNeed(int32_t pointerAction)139 void SCBSystemSession::PresentFoucusIfNeed(int32_t pointerAction)
140 {
141 WLOGFD("OnClick down, id: %{public}d", GetPersistentId());
142 if (pointerAction == MMI::PointerEvent::POINTER_ACTION_DOWN ||
143 pointerAction == MMI::PointerEvent::POINTER_ACTION_BUTTON_DOWN) {
144 if (!isFocused_ && GetFocusable()) {
145 FocusChangeReason reason = FocusChangeReason::CLICK;
146 NotifyRequestFocusStatusNotifyManager(true, false, reason);
147 NotifyClick();
148 }
149 }
150 }
151
UpdateFocus(bool isFocused)152 WSError SCBSystemSession::UpdateFocus(bool isFocused)
153 {
154 if (isFocused_ == isFocused) {
155 TLOGD(WmsLogTag::WMS_FOCUS, "Session focus do not change");
156 return WSError::WS_DO_NOTHING;
157 }
158 isFocused_ = isFocused;
159 // notify scb arkui focus
160 if (isFocused) {
161 HiSysEventWrite(
162 OHOS::HiviewDFX::HiSysEvent::Domain::WINDOW_MANAGER,
163 "FOCUS_WINDOW",
164 OHOS::HiviewDFX::HiSysEvent::EventType::BEHAVIOR,
165 "PID", getpid(),
166 "UID", getuid(),
167 "BUNDLE_NAME", sessionInfo_.bundleName_);
168 NotifyUIRequestFocus();
169 } else {
170 NotifyUILostFocus();
171 }
172 return WSError::WS_OK;
173 }
174
UpdateWindowMode(WindowMode mode)175 WSError SCBSystemSession::UpdateWindowMode(WindowMode mode)
176 {
177 WLOGFD("session is system, id: %{public}d, mode: %{public}d, name: %{public}s, state: %{public}u",
178 GetPersistentId(), static_cast<int32_t>(mode), sessionInfo_.bundleName_.c_str(), GetSessionState());
179 return WSError::WS_ERROR_INVALID_SESSION;
180 }
181
SetSystemSceneBlockingFocus(bool blocking)182 WSError SCBSystemSession::SetSystemSceneBlockingFocus(bool blocking)
183 {
184 TLOGD(WmsLogTag::WMS_FOCUS, "Session set blocking focus, id: %{public}d, mode: %{public}d",
185 GetPersistentId(), blocking);
186 blockingFocus_ = blocking;
187 return WSError::WS_OK;
188 }
189
UpdatePointerArea(const WSRect& rect)190 void SCBSystemSession::UpdatePointerArea(const WSRect& rect)
191 {
192 // scb system session do nothing
193 return;
194 }
195
SetSkipSelfWhenShowOnVirtualScreen(bool isSkip)196 void SCBSystemSession::SetSkipSelfWhenShowOnVirtualScreen(bool isSkip)
197 {
198 TLOGD(WmsLogTag::WMS_SCB, "Set Skip Self, isSkip: %{public}d", isSkip);
199 auto task = [weakThis = wptr(this), isSkip]() {
200 auto session = weakThis.promote();
201 if (!session) {
202 TLOGE(WmsLogTag::WMS_SCB, "session is null");
203 return WSError::WS_ERROR_DESTROYED_OBJECT;
204 }
205 std::shared_ptr<RSSurfaceNode> surfaceNode = session->GetSurfaceNode();
206 if (!surfaceNode) {
207 TLOGE(WmsLogTag::WMS_SCB, "surfaceNode_ is null");
208 return WSError::WS_OK;
209 }
210 if (session->specificCallback_ != nullptr
211 && session->specificCallback_->onSetSkipSelfWhenShowOnVirtualScreen_ != nullptr) {
212 session->specificCallback_->onSetSkipSelfWhenShowOnVirtualScreen_(surfaceNode->GetId(), isSkip);
213 }
214 return WSError::WS_OK;
215 };
216 PostTask(task, "SetSkipSelf");
217 }
218
GetSurfaceNode()219 std::shared_ptr<RSSurfaceNode> SCBSystemSession::GetSurfaceNode()
220 {
221 if (!surfaceNode_) {
222 TLOGE(WmsLogTag::WMS_SCB, "surfaceNode_ is null");
223 return nullptr;
224 }
225 return surfaceNode_;
226 }
227
IsVisibleForeground() const228 bool SCBSystemSession::IsVisibleForeground() const
229 {
230 return isVisible_;
231 }
232
NotifyClientToUpdateAvoidArea()233 void SCBSystemSession::NotifyClientToUpdateAvoidArea()
234 {
235 SceneSession::NotifyClientToUpdateAvoidArea();
236 if (GetWindowType() == WindowType::WINDOW_TYPE_KEYBOARD_PANEL &&
237 keyboardPanelRectUpdateCallback_ && isKeyboardPanelEnabled_) {
238 keyboardPanelRectUpdateCallback_();
239 }
240 }
241
SyncScenePanelGlobalPosition(bool needSync)242 void SCBSystemSession::SyncScenePanelGlobalPosition(bool needSync)
243 {
244 TLOGI(WmsLogTag::WMS_PIPELINE, "change isNeedSyncGlobalPos from %{public}d to %{public}d",
245 isNeedSyncGlobalPos_, needSync);
246 isNeedSyncGlobalPos_ = needSync;
247 }
248 } // namespace OHOS::Rosen
249