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 "window_extension_session_impl.h"
17
18 #include <transaction/rs_transaction.h>
19 #include "window_manager_hilog.h"
20 #include "parameters.h"
21 #include "anr_handler.h"
22
23 namespace OHOS {
24 namespace Rosen {
25 namespace {
26 constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WINDOW, "WindowExtensionSessionImpl"};
27 }
28
29 std::set<sptr<WindowSessionImpl>> WindowExtensionSessionImpl::windowExtensionSessionSet_;
30 std::shared_mutex WindowExtensionSessionImpl::windowExtensionSessionMutex_;
31
WindowExtensionSessionImpl(const sptr<WindowOption> & option)32 WindowExtensionSessionImpl::WindowExtensionSessionImpl(const sptr<WindowOption>& option) : WindowSessionImpl(option)
33 {
34 }
35
~WindowExtensionSessionImpl()36 WindowExtensionSessionImpl::~WindowExtensionSessionImpl()
37 {
38 }
39
Create(const std::shared_ptr<AbilityRuntime::Context> & context,const sptr<Rosen::ISession> & iSession)40 WMError WindowExtensionSessionImpl::Create(const std::shared_ptr<AbilityRuntime::Context>& context,
41 const sptr<Rosen::ISession>& iSession)
42 {
43 WLOGFI("In");
44 if (!context || !iSession) {
45 WLOGFE("context is nullptr: %{public}u or sessionToken is nullptr: %{public}u",
46 context == nullptr, iSession == nullptr);
47 return WMError::WM_ERROR_NULLPTR;
48 }
49 SetDefaultDisplayIdIfNeed();
50 hostSession_ = iSession;
51 context_ = context;
52 WMError ret = Connect();
53 if (ret == WMError::WM_OK) {
54 std::unique_lock<std::shared_mutex> lock(windowExtensionSessionMutex_);
55 windowExtensionSessionSet_.insert(this);
56 }
57 state_ = WindowState::STATE_CREATED;
58 return WMError::WM_OK;
59 }
60
UpdateConfiguration(const std::shared_ptr<AppExecFwk::Configuration> & configuration)61 void WindowExtensionSessionImpl::UpdateConfiguration(const std::shared_ptr<AppExecFwk::Configuration>& configuration)
62 {
63 if (uiContent_ != nullptr) {
64 WLOGFD("notify ace winId:%{public}u", GetWindowId());
65 uiContent_->UpdateConfiguration(configuration);
66 }
67 }
68
UpdateConfigurationForAll(const std::shared_ptr<AppExecFwk::Configuration> & configuration)69 void WindowExtensionSessionImpl::UpdateConfigurationForAll(const std::shared_ptr<AppExecFwk::Configuration>& configuration)
70 {
71 WLOGD("notify scene ace update config");
72 std::unique_lock<std::shared_mutex> lock(windowExtensionSessionMutex_);
73 for (const auto& window : windowExtensionSessionSet_) {
74 window->UpdateConfiguration(configuration);
75 }
76 }
77
Destroy(bool needNotifyServer,bool needClearListener)78 WMError WindowExtensionSessionImpl::Destroy(bool needNotifyServer, bool needClearListener)
79 {
80 WLOGFI("[WMSLife]Id: %{public}d Destroy, state_:%{public}u, needNotifyServer: %{public}d, "
81 "needClearListener: %{public}d", GetPersistentId(), state_, needNotifyServer, needClearListener);
82 if (IsWindowSessionInvalid()) {
83 WLOGFE("[WMSLife]session is invalid");
84 return WMError::WM_ERROR_INVALID_WINDOW;
85 }
86 if (hostSession_ != nullptr) {
87 hostSession_->Disconnect();
88 }
89 NotifyBeforeDestroy(GetWindowName());
90 {
91 std::lock_guard<std::recursive_mutex> lock(mutex_);
92 state_ = WindowState::STATE_DESTROYED;
93 requestState_ = WindowState::STATE_DESTROYED;
94 }
95 hostSession_ = nullptr;
96 {
97 std::unique_lock<std::shared_mutex> lock(windowExtensionSessionMutex_);
98 windowExtensionSessionSet_.erase(this);
99 }
100 DelayedSingleton<ANRHandler>::GetInstance()->OnWindowDestroyed(GetPersistentId());
101 NotifyAfterDestroy();
102 if (needClearListener) {
103 ClearListenersById(GetPersistentId());
104 }
105 return WMError::WM_OK;
106 }
107
MoveTo(int32_t x,int32_t y)108 WMError WindowExtensionSessionImpl::MoveTo(int32_t x, int32_t y)
109 {
110 WLOGFD("Id:%{public}d MoveTo %{public}d %{public}d", property_->GetPersistentId(), x, y);
111 if (IsWindowSessionInvalid()) {
112 WLOGFE("Window session invalid.");
113 return WMError::WM_ERROR_INVALID_WINDOW;
114 }
115 const auto& rect = property_->GetWindowRect();
116 WSRect wsRect = { x, y, rect.width_, rect.height_ };
117 WSError error = UpdateRect(wsRect, SizeChangeReason::MOVE);
118 return static_cast<WMError>(error);
119 }
120
Resize(uint32_t width,uint32_t height)121 WMError WindowExtensionSessionImpl::Resize(uint32_t width, uint32_t height)
122 {
123 WLOGFD("Id:%{public}d Resize %{public}u %{public}u", property_->GetPersistentId(), width, height);
124 if (IsWindowSessionInvalid()) {
125 WLOGFE("Window session invalid.");
126 return WMError::WM_ERROR_INVALID_WINDOW;
127 }
128 const auto& rect = property_->GetWindowRect();
129 WSRect wsRect = { rect.posX_, rect.posY_, width, height };
130 WSError error = UpdateRect(wsRect, SizeChangeReason::RESIZE);
131 return static_cast<WMError>(error);
132 }
133
TransferAbilityResult(uint32_t resultCode,const AAFwk::Want & want)134 WMError WindowExtensionSessionImpl::TransferAbilityResult(uint32_t resultCode, const AAFwk::Want& want)
135 {
136 if (IsWindowSessionInvalid()) {
137 WLOGFE("Window session invalid.");
138 return WMError::WM_ERROR_REPEAT_OPERATION;
139 }
140 return static_cast<WMError>(hostSession_->TransferAbilityResult(resultCode, want));
141 }
142
TransferExtensionData(const AAFwk::WantParams & wantParams)143 WMError WindowExtensionSessionImpl::TransferExtensionData(const AAFwk::WantParams& wantParams)
144 {
145 if (IsWindowSessionInvalid()) {
146 WLOGFE("Window session invalid.");
147 return WMError::WM_ERROR_REPEAT_OPERATION;
148 }
149 return static_cast<WMError>(hostSession_->TransferExtensionData(wantParams));
150 }
151
RegisterTransferComponentDataListener(const NotifyTransferComponentDataFunc & func)152 void WindowExtensionSessionImpl::RegisterTransferComponentDataListener(const NotifyTransferComponentDataFunc& func)
153 {
154 if (IsWindowSessionInvalid()) {
155 WLOGFE("Window session invalid.");
156 return;
157 }
158 notifyTransferComponentDataFunc_ = std::move(func);
159 hostSession_->NotifyAsyncOn();
160 }
161
NotifyTransferComponentData(const AAFwk::WantParams & wantParams)162 WSError WindowExtensionSessionImpl::NotifyTransferComponentData(const AAFwk::WantParams& wantParams)
163 {
164 if (notifyTransferComponentDataFunc_) {
165 notifyTransferComponentDataFunc_(wantParams);
166 }
167 return WSError::WS_OK;
168 }
169
NotifyTransferComponentDataSync(const AAFwk::WantParams & wantParams,AAFwk::WantParams & reWantParams)170 WSErrorCode WindowExtensionSessionImpl::NotifyTransferComponentDataSync(
171 const AAFwk::WantParams& wantParams, AAFwk::WantParams& reWantParams)
172 {
173 if (notifyTransferComponentDataForResultFunc_) {
174 reWantParams = notifyTransferComponentDataForResultFunc_(wantParams);
175 return WSErrorCode::WS_OK;
176 }
177 return WSErrorCode::WS_ERROR_NOT_REGISTER_SYNC_CALLBACK;
178 }
179
RegisterTransferComponentDataForResultListener(const NotifyTransferComponentDataForResultFunc & func)180 void WindowExtensionSessionImpl::RegisterTransferComponentDataForResultListener(
181 const NotifyTransferComponentDataForResultFunc& func)
182 {
183 if (IsWindowSessionInvalid()) {
184 WLOGFE("Window session invalid.");
185 return;
186 }
187 notifyTransferComponentDataForResultFunc_ = std::move(func);
188 hostSession_->NotifySyncOn();
189 }
190
TriggerBindModalUIExtension()191 void WindowExtensionSessionImpl::TriggerBindModalUIExtension()
192 {
193 WLOGFD("called");
194 if (hostSession_ == nullptr) {
195 WLOGFE("hostSession_ is nullptr");
196 return;
197 }
198 hostSession_->TriggerBindModalUIExtension();
199 }
200
SetPrivacyMode(bool isPrivacyMode)201 WMError WindowExtensionSessionImpl::SetPrivacyMode(bool isPrivacyMode)
202 {
203 WLOGFD("id : %{public}u, SetPrivacyMode, %{public}u", GetWindowId(), isPrivacyMode);
204 if (surfaceNode_ == nullptr) {
205 WLOGFE("surfaceNode_ is nullptr");
206 return WMError::WM_ERROR_NULLPTR;
207 }
208 surfaceNode_->SetSecurityLayer(isPrivacyMode);
209 RSTransaction::FlushImplicitTransaction();
210 return WMError::WM_OK;
211 }
212
NotifyFocusStateEvent(bool focusState)213 void WindowExtensionSessionImpl::NotifyFocusStateEvent(bool focusState)
214 {
215 if (uiContent_) {
216 focusState ? uiContent_->Focus() : uiContent_->UnFocus();
217 }
218 focusState_ = focusState;
219 }
220
NotifyFocusActiveEvent(bool isFocusActive)221 void WindowExtensionSessionImpl::NotifyFocusActiveEvent(bool isFocusActive)
222 {
223 if (uiContent_) {
224 uiContent_->SetIsFocusActive(isFocusActive);
225 }
226 }
227
NotifyBackpressedEvent(bool & isConsumed)228 void WindowExtensionSessionImpl::NotifyBackpressedEvent(bool& isConsumed)
229 {
230 if (uiContent_) {
231 WLOGFD("Transfer backpressed event to uiContent");
232 isConsumed = uiContent_->ProcessBackPressed();
233 }
234 WLOGFD("Backpressed event is not cosumed");
235 }
236
NapiSetUIContent(const std::string & contentInfo,napi_env env,napi_value storage,bool isdistributed,sptr<IRemoteObject> token,AppExecFwk::Ability * ability)237 WMError WindowExtensionSessionImpl::NapiSetUIContent(const std::string& contentInfo,
238 napi_env env, napi_value storage, bool isdistributed, sptr<IRemoteObject> token, AppExecFwk::Ability* ability)
239 {
240 WLOGFD("WindowExtensionSessionImpl NapiSetUIContent: %{public}s state:%{public}u", contentInfo.c_str(), state_);
241 if (uiContent_) {
242 uiContent_->Destroy();
243 }
244 std::unique_ptr<Ace::UIContent> uiContent;
245 if (ability != nullptr) {
246 uiContent = Ace::UIContent::Create(ability);
247 } else {
248 uiContent = Ace::UIContent::Create(context_.get(), reinterpret_cast<NativeEngine*>(env));
249 }
250 if (uiContent == nullptr) {
251 WLOGFE("fail to NapiSetUIContent id: %{public}d", GetPersistentId());
252 return WMError::WM_ERROR_NULLPTR;
253 }
254 uiContent->SetParentToken(token);
255 uiContent->Initialize(this, contentInfo, storage, property_->GetParentId());
256 // make uiContent available after Initialize/Restore
257 uiContent_ = std::move(uiContent);
258
259 if (focusState_ != std::nullopt) {
260 focusState_.value() ? uiContent_->Focus() : uiContent_->UnFocus();
261 }
262
263 uint32_t version = 0;
264 if ((context_ != nullptr) && (context_->GetApplicationInfo() != nullptr)) {
265 version = context_->GetApplicationInfo()->apiCompatibleVersion;
266 }
267 // 10 ArkUI new framework support after API10
268 if (version < 10) {
269 SetLayoutFullScreenByApiVersion(isIgnoreSafeArea_);
270 if (!isSystembarPropertiesSet_) {
271 SetSystemBarProperty(WindowType::WINDOW_TYPE_STATUS_BAR, SystemBarProperty());
272 }
273 } else if (isIgnoreSafeAreaNeedNotify_) {
274 SetLayoutFullScreenByApiVersion(isIgnoreSafeArea_);
275 }
276
277 UpdateDecorEnable(true);
278 if (state_ == WindowState::STATE_SHOWN) {
279 // UIContent may be nullptr when show window, need to notify again when window is shown
280 uiContent_->Foreground();
281 UpdateTitleButtonVisibility();
282 }
283 UpdateViewportConfig(GetRect(), WindowSizeChangeReason::UNDEFINED);
284 WLOGFD("notify uiContent window size change end");
285 return WMError::WM_OK;
286 }
287
UpdateRect(const WSRect & rect,SizeChangeReason reason,const std::shared_ptr<RSTransaction> & rsTransaction)288 WSError WindowExtensionSessionImpl::UpdateRect(const WSRect& rect, SizeChangeReason reason,
289 const std::shared_ptr<RSTransaction>& rsTransaction)
290 {
291 WLOGFI("WindowExtensionSessionImpl Update rect [%{public}d, %{public}d, reason: %{public}d]", rect.width_,
292 rect.height_, static_cast<int>(reason));
293 auto wmReason = static_cast<WindowSizeChangeReason>(reason);
294 Rect wmRect = {rect.posX_, rect.posY_, rect.width_, rect.height_};
295 property_->SetWindowRect(wmRect);
296 NotifySizeChange(wmRect, wmReason);
297 UpdateViewportConfig(wmRect, wmReason);
298 return WSError::WS_OK;
299 }
300
NotifySearchElementInfoByAccessibilityId(int64_t elementId,int32_t mode,int64_t baseParent,std::list<Accessibility::AccessibilityElementInfo> & infos)301 WSError WindowExtensionSessionImpl::NotifySearchElementInfoByAccessibilityId(int64_t elementId, int32_t mode,
302 int64_t baseParent, std::list<Accessibility::AccessibilityElementInfo>& infos)
303 {
304 if (uiContent_ == nullptr) {
305 WLOGFE("NotifySearchElementInfoByAccessibilityId error, no uiContent_");
306 return WSError::WS_ERROR_NO_UI_CONTENT_ERROR;
307 }
308 uiContent_->SearchElementInfoByAccessibilityId(elementId, mode, baseParent, infos);
309 return WSError::WS_OK;
310 }
311
NotifySearchElementInfosByText(int64_t elementId,const std::string & text,int64_t baseParent,std::list<Accessibility::AccessibilityElementInfo> & infos)312 WSError WindowExtensionSessionImpl::NotifySearchElementInfosByText(int64_t elementId, const std::string& text,
313 int64_t baseParent, std::list<Accessibility::AccessibilityElementInfo>& infos)
314 {
315 if (uiContent_ == nullptr) {
316 WLOGFE("NotifySearchElementInfosByText error, no uiContent_");
317 return WSError::WS_ERROR_NO_UI_CONTENT_ERROR;
318 }
319 uiContent_->SearchElementInfosByText(elementId, text, baseParent, infos);
320 return WSError::WS_OK;
321 }
322
NotifyFindFocusedElementInfo(int64_t elementId,int32_t focusType,int64_t baseParent,Accessibility::AccessibilityElementInfo & info)323 WSError WindowExtensionSessionImpl::NotifyFindFocusedElementInfo(int64_t elementId, int32_t focusType,
324 int64_t baseParent, Accessibility::AccessibilityElementInfo& info)
325 {
326 if (uiContent_ == nullptr) {
327 WLOGFE("NotifyFindFocusedElementInfo error, no uiContent_");
328 return WSError::WS_ERROR_NO_UI_CONTENT_ERROR;
329 }
330 uiContent_->FindFocusedElementInfo(elementId, focusType, baseParent, info);
331 return WSError::WS_OK;
332 }
333
NotifyFocusMoveSearch(int64_t elementId,int32_t direction,int64_t baseParent,Accessibility::AccessibilityElementInfo & info)334 WSError WindowExtensionSessionImpl::NotifyFocusMoveSearch(int64_t elementId, int32_t direction, int64_t baseParent,
335 Accessibility::AccessibilityElementInfo& info)
336 {
337 if (uiContent_ == nullptr) {
338 WLOGFE("NotifyFocusMoveSearch error, no uiContent_");
339 return WSError::WS_ERROR_NO_UI_CONTENT_ERROR;
340 }
341 uiContent_->FocusMoveSearch(elementId, direction, baseParent, info);
342 return WSError::WS_OK;
343 }
344
NotifyExecuteAction(int64_t elementId,const std::map<std::string,std::string> & actionAguments,int32_t action,int64_t baseParent)345 WSError WindowExtensionSessionImpl::NotifyExecuteAction(int64_t elementId,
346 const std::map<std::string, std::string>& actionAguments, int32_t action,
347 int64_t baseParent)
348 {
349 if (uiContent_ == nullptr) {
350 WLOGFE("NotifyExecuteAction error, no uiContent_");
351 return WSError::WS_ERROR_NO_UI_CONTENT_ERROR;
352 }
353 bool ret = uiContent_->NotifyExecuteAction(elementId, actionAguments, action, baseParent);
354 if (!ret) {
355 WLOGFE("NotifyExecuteAction fail");
356 return WSError::WS_ERROR_INTERNAL_ERROR;
357 }
358 return WSError::WS_OK;
359 }
360
TransferAccessibilityEvent(const Accessibility::AccessibilityEventInfo & info,int64_t uiExtensionIdLevel)361 WMError WindowExtensionSessionImpl::TransferAccessibilityEvent(const Accessibility::AccessibilityEventInfo& info,
362 int64_t uiExtensionIdLevel)
363 {
364 if (IsWindowSessionInvalid()) {
365 WLOGFE("Window session invalid.");
366 return WMError::WM_ERROR_INVALID_WINDOW;
367 }
368 return static_cast<WMError>(hostSession_->TransferAccessibilityEvent(info, uiExtensionIdLevel));
369 }
370
NotifySessionForeground(uint32_t reason,bool withAnimation)371 void WindowExtensionSessionImpl::NotifySessionForeground(uint32_t reason, bool withAnimation)
372 {
373 }
374
NotifySessionBackground(uint32_t reason,bool withAnimation,bool isFromInnerkits)375 void WindowExtensionSessionImpl::NotifySessionBackground(uint32_t reason, bool withAnimation, bool isFromInnerkits)
376 {
377 }
378
NotifyOccupiedAreaChangeInfo(sptr<OccupiedAreaChangeInfo> info)379 void WindowExtensionSessionImpl::NotifyOccupiedAreaChangeInfo(sptr<OccupiedAreaChangeInfo> info)
380 {
381 WLOGD("TextFieldPosY = %{public}lf, KeyBoardHeight = %{public}d", info->textFieldPositionY_, info->rect_.height_);
382 if (occupiedAreaChangeListener_) {
383 occupiedAreaChangeListener_->OnSizeChange(info);
384 }
385 }
386
RegisterOccupiedAreaChangeListener(const sptr<IOccupiedAreaChangeListener> & listener)387 WMError WindowExtensionSessionImpl::RegisterOccupiedAreaChangeListener(
388 const sptr<IOccupiedAreaChangeListener>& listener)
389 {
390 occupiedAreaChangeListener_ = listener;
391 return WMError::WM_OK;
392 }
393
UnregisterOccupiedAreaChangeListener(const sptr<IOccupiedAreaChangeListener> & listener)394 WMError WindowExtensionSessionImpl::UnregisterOccupiedAreaChangeListener(
395 const sptr<IOccupiedAreaChangeListener>& listener)
396 {
397 occupiedAreaChangeListener_ = nullptr;
398 return WMError::WM_OK;
399 }
400
GetAvoidAreaByType(AvoidAreaType type,AvoidArea & avoidArea)401 WMError WindowExtensionSessionImpl::GetAvoidAreaByType(AvoidAreaType type, AvoidArea& avoidArea)
402 {
403 WLOGFI("Window Extension Session Get Avoid Area Type");
404 if (hostSession_ == nullptr) {
405 return WMError::WM_ERROR_NULLPTR;
406 }
407 avoidArea = hostSession_->GetAvoidAreaByType(type);
408 return WMError::WM_OK;
409 }
410
RegisterAvoidAreaChangeListener(sptr<IAvoidAreaChangedListener> & listener)411 WMError WindowExtensionSessionImpl::RegisterAvoidAreaChangeListener(sptr<IAvoidAreaChangedListener>& listener)
412 {
413 return RegisterExtensionAvoidAreaChangeListener(listener);
414 }
415
UnregisterAvoidAreaChangeListener(sptr<IAvoidAreaChangedListener> & listener)416 WMError WindowExtensionSessionImpl::UnregisterAvoidAreaChangeListener(sptr<IAvoidAreaChangedListener>& listener)
417 {
418 return UnregisterExtensionAvoidAreaChangeListener(listener);
419 }
420
Hide(uint32_t reason,bool withAnimation,bool isFromInnerkits)421 WMError WindowExtensionSessionImpl::Hide(uint32_t reason, bool withAnimation, bool isFromInnerkits)
422 {
423 WLOGFI("[WMSLife]id:%{public}d WindowExtensionSessionImpl Hide, reason:%{public}u, state:%{public}u",
424 GetPersistentId(), reason, state_);
425 if (IsWindowSessionInvalid()) {
426 WLOGFE("session is invalid");
427 return WMError::WM_ERROR_INVALID_WINDOW;
428 }
429 if (state_ == WindowState::STATE_HIDDEN || state_ == WindowState::STATE_CREATED) {
430 WLOGFD("[WMSLife]window extension session is already hidden [name:%{public}s,id:%{public}d,type: %{public}u]",
431 property_->GetWindowName().c_str(), GetPersistentId(), property_->GetWindowType());
432 NotifyBackgroundFailed(WMError::WM_DO_NOTHING);
433 return WMError::WM_OK;
434 }
435 WSError ret = hostSession_->Background();
436 WMError res = static_cast<WMError>(ret);
437 if (res == WMError::WM_OK) {
438 state_ = WindowState::STATE_HIDDEN;
439 requestState_ = WindowState::STATE_HIDDEN;
440 NotifyAfterBackground();
441 } else {
442 WLOGFD("[WMSLife]window extension session Hide to Background is error");
443 }
444 return WMError::WM_OK;
445 }
446 } // namespace Rosen
447 } // namespace OHOS
448