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 "rs_adapter.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 const std::unordered_map<std::string, SurfaceWindowType> surfaceWindowTypeMap = {
28 { "SCBDesktop", SurfaceWindowType::SCB_DESKTOP },
29 { "SCBWallpaper", SurfaceWindowType::SCB_WALLPAPER },
30 { "SCBScreenLock", SurfaceWindowType::SCB_SCREEN_LOCK },
31 { "SCBNegativeScreen", SurfaceWindowType::SCB_NEGATIVE_SCREEN },
32 { "SCBDropdownPanel", SurfaceWindowType::SCB_DROPDOWN_PANEL },
33 { "SCBVolumePanel", SurfaceWindowType::SCB_VOLUME_PANEL },
34 { "SCBBannerNotification", SurfaceWindowType::SCB_BANNER_NOTIFICATION },
35 { "SCBGestureBack", SurfaceWindowType::SCB_GESTURE_BACK }
36 };
37 } // namespace
38
SCBSystemSession(const SessionInfo & info,const sptr<SpecificSessionCallback> & specificCallback)39 SCBSystemSession::SCBSystemSession(const SessionInfo& info, const sptr<SpecificSessionCallback>& specificCallback)
40 : SceneSession(info, specificCallback)
41 {
42 auto name = sessionInfo_.bundleName_;
43 auto pos = name.find_last_of('.');
44 name = (pos == std::string::npos) ? name : name.substr(pos + 1); // skip '.'
45 if (sessionInfo_.isSystem_) {
46 RSSurfaceNodeConfig config;
47 config.SurfaceNodeName = name;
48 config.surfaceWindowType = SurfaceWindowType::SYSTEM_SCB_WINDOW;
49 for (const auto& iter : surfaceWindowTypeMap) {
50 if (name.find(iter.first) != std::string::npos) {
51 config.surfaceWindowType = iter.second;
52 break;
53 }
54 }
55 surfaceNode_ = Rosen::RSSurfaceNode::Create(config, Rosen::RSSurfaceNodeType::APP_WINDOW_NODE);
56 RSAdapterUtil::SetRSUIContext(surfaceNode_, GetRSUIContext(), true);
57 TLOGD(WmsLogTag::WMS_SCB, "Create RSSurfaceNode: %{public}s, name: %{public}s",
58 RSAdapterUtil::RSNodeToStr(surfaceNode_).c_str(), name.c_str());
59 SetIsUseControlSession(info.isUseControlSession);
60 }
61 WLOGFD("Create SCBSystemSession");
62 }
63
~SCBSystemSession()64 SCBSystemSession::~SCBSystemSession()
65 {
66 WLOGD("~SCBSystemSession, id: %{public}d", GetPersistentId());
67 }
68
ProcessPointDownSession(int32_t posX,int32_t posY)69 WSError SCBSystemSession::ProcessPointDownSession(int32_t posX, int32_t posY)
70 {
71 const auto id = GetPersistentId();
72 const auto type = GetWindowType();
73 TLOGD(WmsLogTag::WMS_INPUT_KEY_FLOW, "id: %{public}d, type: %{public}d", id, type);
74 auto ret = SceneSession::ProcessPointDownSession(posX, posY);
75 PresentFocusIfPointDown();
76 return ret;
77 }
78
NotifyClientToUpdateRect(const std::string & updateReason,std::shared_ptr<RSTransaction> rsTransaction)79 WSError SCBSystemSession::NotifyClientToUpdateRect(const std::string& updateReason,
80 std::shared_ptr<RSTransaction> rsTransaction)
81 {
82 PostTask([weakThis = wptr(this), rsTransaction, updateReason]() {
83 auto session = weakThis.promote();
84 if (!session) {
85 WLOGFE("session is null");
86 return WSError::WS_ERROR_DESTROYED_OBJECT;
87 }
88 WSError ret = session->NotifyClientToUpdateRectTask(updateReason, rsTransaction);
89 if (session->specificCallback_ != nullptr && session->specificCallback_->onUpdateAvoidArea_ != nullptr &&
90 session->specificCallback_->onClearDisplayStatusBarTemporarilyFlags_ != nullptr) {
91 if (Session::IsScbCoreEnabled()) {
92 session->dirtyFlags_ |= static_cast<uint32_t>(SessionUIDirtyFlag::AVOID_AREA);
93 } else {
94 session->specificCallback_->onUpdateAvoidArea_(session->GetPersistentId());
95 }
96 session->specificCallback_->onClearDisplayStatusBarTemporarilyFlags_();
97 }
98 return ret;
99 }, "NotifyClientToUpdateRect");
100 return WSError::WS_OK;
101 }
102
BindKeyboardSession(sptr<SceneSession> session)103 void SCBSystemSession::BindKeyboardSession(sptr<SceneSession> session)
104 {
105 if (session == nullptr) {
106 TLOGE(WmsLogTag::WMS_KEYBOARD, "session is nullptr");
107 return;
108 }
109 keyboardSession_ = session;
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 TLOGI(WmsLogTag::WMS_FOCUS, "Id:%{public}d,type:%{public}d", GetPersistentId(), GetWindowType());
121 if (!isFocused_ && GetFocusable()) {
122 FocusChangeReason reason = FocusChangeReason::CLICK;
123 NotifyRequestFocusStatusNotifyManager(true, false, reason);
124 }
125 NotifyClick();
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
UpdateFocus(bool isFocused)139 WSError SCBSystemSession::UpdateFocus(bool isFocused)
140 {
141 if (isFocused_ == isFocused) {
142 TLOGD(WmsLogTag::WMS_FOCUS, "Session focus do not change");
143 return WSError::WS_DO_NOTHING;
144 }
145 isFocused_ = isFocused;
146 // notify scb arkui focus
147 if (isFocused) {
148 HiSysEventWrite(
149 OHOS::HiviewDFX::HiSysEvent::Domain::WINDOW_MANAGER,
150 "FOCUS_WINDOW",
151 OHOS::HiviewDFX::HiSysEvent::EventType::BEHAVIOR,
152 "PID", getpid(),
153 "UID", getuid(),
154 "BUNDLE_NAME", sessionInfo_.bundleName_,
155 "WINDOW_TYPE", static_cast<uint32_t>(GetWindowType()));
156 NotifyUIRequestFocus();
157 } else {
158 NotifyUILostFocus();
159 }
160 return WSError::WS_OK;
161 }
162
UpdateWindowMode(WindowMode mode)163 WSError SCBSystemSession::UpdateWindowMode(WindowMode mode)
164 {
165 WLOGFD("session is system, id: %{public}d, mode: %{public}d, name: %{public}s, state: %{public}u",
166 GetPersistentId(), static_cast<int32_t>(mode), sessionInfo_.bundleName_.c_str(), GetSessionState());
167 return WSError::WS_ERROR_INVALID_SESSION;
168 }
169
SetSystemSceneBlockingFocus(bool blocking)170 WSError SCBSystemSession::SetSystemSceneBlockingFocus(bool blocking)
171 {
172 TLOGD(WmsLogTag::WMS_FOCUS, "Session set blocking focus, id: %{public}d, mode: %{public}d",
173 GetPersistentId(), blocking);
174 blockingFocus_ = blocking;
175 return WSError::WS_OK;
176 }
177
UpdatePointerArea(const WSRect & rect)178 void SCBSystemSession::UpdatePointerArea(const WSRect& rect)
179 {
180 // scb system session do nothing
181 return;
182 }
183
SetSkipSelfWhenShowOnVirtualScreen(bool isSkip)184 void SCBSystemSession::SetSkipSelfWhenShowOnVirtualScreen(bool isSkip)
185 {
186 TLOGD(WmsLogTag::WMS_SCB, "Set skip Self, isSkip: %{public}d", isSkip);
187 PostTask([weakThis = wptr(this), isSkip, where = __func__]() {
188 auto session = weakThis.promote();
189 if (!session) {
190 TLOGNE(WmsLogTag::WMS_SCB, "%{public}s session is null", where);
191 return;
192 }
193 std::shared_ptr<RSSurfaceNode> surfaceNode = session->GetSurfaceNode();
194 if (!surfaceNode) {
195 TLOGNE(WmsLogTag::WMS_SCB, "%{public}s surfaceNode_ is null", where);
196 return;
197 }
198 if (session->specificCallback_ != nullptr &&
199 session->specificCallback_->onSetSkipSelfWhenShowOnVirtualScreen_ != nullptr) {
200 session->specificCallback_->onSetSkipSelfWhenShowOnVirtualScreen_(surfaceNode->GetId(), isSkip);
201 }
202 return;
203 }, __func__);
204 }
205
SetSkipEventOnCastPlus(bool isSkip)206 void SCBSystemSession::SetSkipEventOnCastPlus(bool isSkip)
207 {
208 TLOGD(WmsLogTag::WMS_SCB, "Set skip event on cast plus, wid: %{public}d, isSkip: %{public}d",
209 GetPersistentId(), isSkip);
210 PostTask([weakThis = wptr(this), isSkip, where = __func__]() {
211 auto session = weakThis.promote();
212 if (!session) {
213 TLOGNE(WmsLogTag::WMS_SCB, "%{public}s session is null", where);
214 return;
215 }
216 if (session->specificCallback_ != nullptr &&
217 session->specificCallback_->onSetSkipEventOnCastPlus_ != nullptr) {
218 session->specificCallback_->onSetSkipEventOnCastPlus_(session->GetPersistentId(), isSkip);
219 }
220 return;
221 }, __func__);
222 }
223
IsVisibleForeground() const224 bool SCBSystemSession::IsVisibleForeground() const
225 {
226 return isVisible_;
227 }
228
IsVisibleNotBackground() const229 bool SCBSystemSession::IsVisibleNotBackground() const
230 {
231 return isVisible_;
232 }
233
NotifyClientToUpdateAvoidArea()234 void SCBSystemSession::NotifyClientToUpdateAvoidArea()
235 {
236 SceneSession::NotifyClientToUpdateAvoidArea();
237 }
238
SyncScenePanelGlobalPosition(bool needSync)239 void SCBSystemSession::SyncScenePanelGlobalPosition(bool needSync)
240 {
241 TLOGI(WmsLogTag::WMS_PIPELINE, "change isNeedSyncGlobalPos from %{public}d to %{public}d",
242 isNeedSyncGlobalPos_, needSync);
243 isNeedSyncGlobalPos_ = needSync;
244 }
245
GetIsUseControlSession() const246 bool SCBSystemSession::GetIsUseControlSession() const
247 {
248 return isUseControlSession_;
249 }
250
SetIsUseControlSession(bool isUseControlSession)251 void SCBSystemSession::SetIsUseControlSession(bool isUseControlSession)
252 {
253 isUseControlSession_ = isUseControlSession;
254 }
255 } // namespace OHOS::Rosen
256