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