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