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_interfaces.h>
19 #include <transaction/rs_transaction.h>
20 #ifdef IMF_ENABLE
21 #include <input_method_controller.h>
22 #endif
23 #include "window_manager_hilog.h"
24 #include "display_info.h"
25 #include "parameters.h"
26 #include "anr_handler.h"
27 #include "hitrace_meter.h"
28 #include "perform_reporter.h"
29 #include "session_permission.h"
30 #include "singleton_container.h"
31 #include "window_adapter.h"
32 #include "input_transfer_station.h"
33
34 namespace OHOS {
35 namespace Rosen {
36 namespace {
37 constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WINDOW, "WindowExtensionSessionImpl"};
38 constexpr int64_t DISPATCH_KEY_EVENT_TIMEOUT_TIME_MS = 1000;
39 constexpr int32_t UIEXTENTION_ROTATION_ANIMATION_TIME = 400;
40 }
41
42 #define CHECK_HOST_SESSION_RETURN_IF_NULL(hostSession) \
43 do { \
44 if ((hostSession) == nullptr) { \
45 TLOGE(WmsLogTag::DEFAULT, "hostSession is null"); \
46 return; \
47 } \
48 } while (false)
49
50 #define CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, ret) \
51 do { \
52 if ((hostSession) == nullptr) { \
53 TLOGE(WmsLogTag::DEFAULT, "hostSession is null"); \
54 return ret; \
55 } \
56 } while (false)
57
WindowExtensionSessionImpl(const sptr<WindowOption> & option)58 WindowExtensionSessionImpl::WindowExtensionSessionImpl(const sptr<WindowOption>& option) : WindowSessionImpl(option)
59 {
60 if (property_ == nullptr) {
61 return;
62 }
63 if (property_->GetUIExtensionUsage() == UIExtensionUsage::MODAL ||
64 property_->GetUIExtensionUsage() == UIExtensionUsage::CONSTRAINED_EMBEDDED) {
65 extensionWindowFlags_.hideNonSecureWindowsFlag = true;
66 }
67 TLOGI(WmsLogTag::WMS_UIEXT, "UIExtension usage=%{public}u, the default state of hideNonSecureWindows is %{public}d",
68 property_->GetUIExtensionUsage(), extensionWindowFlags_.hideNonSecureWindowsFlag);
69 }
70
~WindowExtensionSessionImpl()71 WindowExtensionSessionImpl::~WindowExtensionSessionImpl()
72 {
73 }
74
Create(const std::shared_ptr<AbilityRuntime::Context> & context,const sptr<Rosen::ISession> & iSession,const std::string & identityToken)75 WMError WindowExtensionSessionImpl::Create(const std::shared_ptr<AbilityRuntime::Context>& context,
76 const sptr<Rosen::ISession>& iSession, const std::string& identityToken)
77 {
78 TLOGD(WmsLogTag::WMS_LIFE, "Called.");
79 if (!context || !iSession) {
80 TLOGE(WmsLogTag::WMS_LIFE, "context is nullptr: %{public}u or sessionToken is nullptr: %{public}u",
81 context == nullptr, iSession == nullptr);
82 return WMError::WM_ERROR_NULLPTR;
83 }
84 if (vsyncStation_ == nullptr || !vsyncStation_->IsVsyncReceiverCreated()) {
85 return WMError::WM_ERROR_NULLPTR;
86 }
87 SetDefaultDisplayIdIfNeed();
88 {
89 std::lock_guard<std::mutex> lock(hostSessionMutex_);
90 hostSession_ = iSession;
91 }
92 context_ = context;
93 if (context_) {
94 abilityToken_ = context_->GetToken();
95 }
96 AddExtensionWindowStageToSCB();
97 WMError ret = Connect();
98 if (ret != WMError::WM_OK) {
99 TLOGE(WmsLogTag::WMS_LIFE, "name:%{public}s %{public}d connect fail. ret:%{public}d",
100 property_->GetWindowName().c_str(), GetPersistentId(), ret);
101 return ret;
102 }
103 MakeSubOrDialogWindowDragableAndMoveble();
104 {
105 std::unique_lock<std::shared_mutex> lock(windowExtensionSessionMutex_);
106 windowExtensionSessionSet_.insert(this);
107 }
108 InputTransferStation::GetInstance().AddInputWindow(this);
109 state_ = WindowState::STATE_CREATED;
110 isUIExtensionAbilityProcess_ = true;
111 property_->SetIsUIExtensionAbilityProcess(true);
112 TLOGI(WmsLogTag::WMS_LIFE, "Created name:%{public}s %{public}d successfully.",
113 property_->GetWindowName().c_str(), GetPersistentId());
114 AddSetUIContentTimeoutCheck();
115 return WMError::WM_OK;
116 }
117
AddExtensionWindowStageToSCB()118 void WindowExtensionSessionImpl::AddExtensionWindowStageToSCB()
119 {
120 if (!abilityToken_) {
121 TLOGE(WmsLogTag::WMS_UIEXT, "token is nullptr");
122 return;
123 }
124 if (surfaceNode_ == nullptr) {
125 TLOGE(WmsLogTag::WMS_UIEXT, "surfaceNode_ is nullptr");
126 return;
127 }
128
129 SingletonContainer::Get<WindowAdapter>().AddExtensionWindowStageToSCB(sptr<ISessionStage>(this), abilityToken_,
130 surfaceNode_->GetId());
131 }
132
RemoveExtensionWindowStageFromSCB()133 void WindowExtensionSessionImpl::RemoveExtensionWindowStageFromSCB()
134 {
135 if (!abilityToken_) {
136 TLOGE(WmsLogTag::WMS_UIEXT, "token is nullptr");
137 return;
138 }
139
140 SingletonContainer::Get<WindowAdapter>().RemoveExtensionWindowStageFromSCB(sptr<ISessionStage>(this),
141 abilityToken_);
142 }
143
UpdateConfiguration(const std::shared_ptr<AppExecFwk::Configuration> & configuration)144 void WindowExtensionSessionImpl::UpdateConfiguration(const std::shared_ptr<AppExecFwk::Configuration>& configuration)
145 {
146 std::shared_ptr<Ace::UIContent> uiContent = GetUIContentSharedPtr();
147 if (uiContent != nullptr) {
148 WLOGFD("notify ace winId:%{public}u", GetWindowId());
149 uiContent->UpdateConfiguration(configuration);
150 }
151 }
152
UpdateConfigurationForAll(const std::shared_ptr<AppExecFwk::Configuration> & configuration)153 void WindowExtensionSessionImpl::UpdateConfigurationForAll(const std::shared_ptr<AppExecFwk::Configuration>& configuration)
154 {
155 WLOGD("notify scene ace update config");
156 std::unique_lock<std::shared_mutex> lock(windowExtensionSessionMutex_);
157 for (const auto& window : windowExtensionSessionSet_) {
158 window->UpdateConfiguration(configuration);
159 }
160 }
161
UpdateConfigurationSync(const std::shared_ptr<AppExecFwk::Configuration> & configuration)162 void WindowExtensionSessionImpl::UpdateConfigurationSync(
163 const std::shared_ptr<AppExecFwk::Configuration>& configuration)
164 {
165 if (auto uiContent = GetUIContentSharedPtr()) {
166 TLOGI(WmsLogTag::WMS_IMMS, "winId: %{public}d", GetWindowId());
167 uiContent->UpdateConfigurationSyncForAll(configuration);
168 } else {
169 TLOGE(WmsLogTag::WMS_IMMS, "uiContent is null, winId: %{public}d", GetWindowId());
170 }
171 }
172
UpdateConfigurationSyncForAll(const std::shared_ptr<AppExecFwk::Configuration> & configuration)173 void WindowExtensionSessionImpl::UpdateConfigurationSyncForAll(
174 const std::shared_ptr<AppExecFwk::Configuration>& configuration)
175 {
176 std::unique_lock<std::shared_mutex> lock(windowExtensionSessionMutex_);
177 for (const auto& window : windowExtensionSessionSet_) {
178 window->UpdateConfigurationSync(configuration);
179 }
180 }
181
Destroy(bool needNotifyServer,bool needClearListener)182 WMError WindowExtensionSessionImpl::Destroy(bool needNotifyServer, bool needClearListener)
183 {
184 TLOGI(WmsLogTag::WMS_LIFE, "Id: %{public}d Destroy, state_:%{public}u, needNotifyServer: %{public}d, "
185 "needClearListener: %{public}d", GetPersistentId(), state_, needNotifyServer, needClearListener);
186 InputTransferStation::GetInstance().RemoveInputWindow(GetPersistentId());
187 if (IsWindowSessionInvalid()) {
188 TLOGE(WmsLogTag::WMS_LIFE, "session is invalid");
189 return WMError::WM_ERROR_INVALID_WINDOW;
190 }
191 {
192 auto hostSession = GetHostSession();
193 if (hostSession != nullptr) {
194 hostSession->Disconnect();
195 TLOGI(WmsLogTag::WMS_LIFE, "Disconnected with host session, id: %{public}d.", GetPersistentId());
196 }
197 }
198 NotifyBeforeDestroy(GetWindowName());
199 if (needClearListener) {
200 ClearListenersById(GetPersistentId());
201 }
202 {
203 std::lock_guard<std::recursive_mutex> lock(mutex_);
204 state_ = WindowState::STATE_DESTROYED;
205 requestState_ = WindowState::STATE_DESTROYED;
206 }
207 DestroySubWindow();
208 {
209 TLOGI(WmsLogTag::WMS_LIFE, "Reset state, id: %{public}d.", GetPersistentId());
210 std::lock_guard<std::mutex> lock(hostSessionMutex_);
211 hostSession_ = nullptr;
212 }
213 {
214 std::unique_lock<std::shared_mutex> lock(windowExtensionSessionMutex_);
215 windowExtensionSessionSet_.erase(this);
216 }
217 TLOGI(WmsLogTag::WMS_LIFE, "Erase windowExtensionSession in set, id: %{public}d.", GetPersistentId());
218 if (context_) {
219 context_.reset();
220 }
221 ClearVsyncStation();
222 SetUIContentComplete();
223 SetUIExtensionDestroyComplete();
224 RemoveExtensionWindowStageFromSCB();
225 TLOGI(WmsLogTag::WMS_LIFE, "Destroyed successfully, id: %{public}d.", GetPersistentId());
226 return WMError::WM_OK;
227 }
228
MoveTo(int32_t x,int32_t y,bool isMoveToGlobal)229 WMError WindowExtensionSessionImpl::MoveTo(int32_t x, int32_t y, bool isMoveToGlobal)
230 {
231 WLOGFD("Id:%{public}d MoveTo %{public}d %{public}d", property_->GetPersistentId(), x, y);
232 if (IsWindowSessionInvalid()) {
233 WLOGFE("Window session invalid.");
234 return WMError::WM_ERROR_INVALID_WINDOW;
235 }
236 const auto& rect = property_->GetWindowRect();
237 WSRect wsRect = { x, y, rect.width_, rect.height_ };
238 WSError error = UpdateRect(wsRect, SizeChangeReason::MOVE);
239 return static_cast<WMError>(error);
240 }
241
Resize(uint32_t width,uint32_t height)242 WMError WindowExtensionSessionImpl::Resize(uint32_t width, uint32_t height)
243 {
244 WLOGFD("Id:%{public}d Resize %{public}u %{public}u", property_->GetPersistentId(), width, height);
245 if (IsWindowSessionInvalid()) {
246 WLOGFE("Window session invalid.");
247 return WMError::WM_ERROR_INVALID_WINDOW;
248 }
249 const auto& rect = property_->GetWindowRect();
250 WSRect wsRect = { rect.posX_, rect.posY_, width, height };
251 WSError error = UpdateRect(wsRect, SizeChangeReason::RESIZE);
252 return static_cast<WMError>(error);
253 }
254
TransferAbilityResult(uint32_t resultCode,const AAFwk::Want & want)255 WMError WindowExtensionSessionImpl::TransferAbilityResult(uint32_t resultCode, const AAFwk::Want& want)
256 {
257 if (IsWindowSessionInvalid()) {
258 WLOGFE("Window session invalid.");
259 return WMError::WM_ERROR_REPEAT_OPERATION;
260 }
261 auto hostSession = GetHostSession();
262 CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_INVALID_WINDOW);
263 return static_cast<WMError>(hostSession->TransferAbilityResult(resultCode, want));
264 }
265
TransferExtensionData(const AAFwk::WantParams & wantParams)266 WMError WindowExtensionSessionImpl::TransferExtensionData(const AAFwk::WantParams& wantParams)
267 {
268 if (IsWindowSessionInvalid()) {
269 WLOGFE("Window session invalid.");
270 return WMError::WM_ERROR_REPEAT_OPERATION;
271 }
272 auto hostSession = GetHostSession();
273 CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_INVALID_WINDOW);
274 return static_cast<WMError>(hostSession->TransferExtensionData(wantParams));
275 }
276
RegisterTransferComponentDataListener(const NotifyTransferComponentDataFunc & func)277 void WindowExtensionSessionImpl::RegisterTransferComponentDataListener(const NotifyTransferComponentDataFunc& func)
278 {
279 if (IsWindowSessionInvalid()) {
280 WLOGFE("Window session invalid.");
281 return;
282 }
283 notifyTransferComponentDataFunc_ = std::move(func);
284 auto hostSession = GetHostSession();
285 CHECK_HOST_SESSION_RETURN_IF_NULL(hostSession);
286 hostSession->NotifyAsyncOn();
287 }
288
NotifyTransferComponentData(const AAFwk::WantParams & wantParams)289 WSError WindowExtensionSessionImpl::NotifyTransferComponentData(const AAFwk::WantParams& wantParams)
290 {
291 TLOGD(WmsLogTag::WMS_UIEXT, "Called.");
292 if (notifyTransferComponentDataFunc_) {
293 notifyTransferComponentDataFunc_(wantParams);
294 }
295 return WSError::WS_OK;
296 }
297
NotifyTransferComponentDataSync(const AAFwk::WantParams & wantParams,AAFwk::WantParams & reWantParams)298 WSErrorCode WindowExtensionSessionImpl::NotifyTransferComponentDataSync(
299 const AAFwk::WantParams& wantParams, AAFwk::WantParams& reWantParams)
300 {
301 TLOGI(WmsLogTag::WMS_UIEXT, "called");
302 if (notifyTransferComponentDataForResultFunc_) {
303 reWantParams = notifyTransferComponentDataForResultFunc_(wantParams);
304 return WSErrorCode::WS_OK;
305 }
306 return WSErrorCode::WS_ERROR_NOT_REGISTER_SYNC_CALLBACK;
307 }
308
RegisterTransferComponentDataForResultListener(const NotifyTransferComponentDataForResultFunc & func)309 void WindowExtensionSessionImpl::RegisterTransferComponentDataForResultListener(
310 const NotifyTransferComponentDataForResultFunc& func)
311 {
312 if (IsWindowSessionInvalid()) {
313 WLOGFE("Window session invalid.");
314 return;
315 }
316 notifyTransferComponentDataForResultFunc_ = std::move(func);
317 auto hostSession = GetHostSession();
318 CHECK_HOST_SESSION_RETURN_IF_NULL(hostSession);
319 hostSession->NotifySyncOn();
320 }
321
TriggerBindModalUIExtension()322 void WindowExtensionSessionImpl::TriggerBindModalUIExtension()
323 {
324 WLOGFD("called");
325 auto hostSession = GetHostSession();
326 CHECK_HOST_SESSION_RETURN_IF_NULL(hostSession);
327 hostSession->TriggerBindModalUIExtension();
328 }
329
SetPrivacyMode(bool isPrivacyMode)330 WMError WindowExtensionSessionImpl::SetPrivacyMode(bool isPrivacyMode)
331 {
332 TLOGI(WmsLogTag::WMS_UIEXT, "Id: %{public}u, isPrivacyMode: %{public}u", GetPersistentId(),
333 isPrivacyMode);
334 if (surfaceNode_ == nullptr) {
335 TLOGE(WmsLogTag::WMS_UIEXT, "surfaceNode_ is nullptr");
336 return WMError::WM_ERROR_NULLPTR;
337 }
338 surfaceNode_->SetSecurityLayer(isPrivacyMode);
339 RSTransaction::FlushImplicitTransaction();
340
341 if (state_ != WindowState::STATE_SHOWN) {
342 extensionWindowFlags_.privacyModeFlag = isPrivacyMode;
343 return WMError::WM_OK;
344 }
345 if (isPrivacyMode == extensionWindowFlags_.privacyModeFlag) {
346 return WMError::WM_OK;
347 }
348
349 auto updateFlags = extensionWindowFlags_;
350 updateFlags.privacyModeFlag = isPrivacyMode;
351 ExtensionWindowFlags actions(0);
352 actions.privacyModeFlag = true;
353 auto ret = UpdateExtWindowFlags(updateFlags, actions);
354 if (ret == WMError::WM_OK) {
355 extensionWindowFlags_ = updateFlags;
356 }
357 return ret;
358 }
359
HidePrivacyContentForHost(bool needHide)360 WMError WindowExtensionSessionImpl::HidePrivacyContentForHost(bool needHide)
361 {
362 auto persistentId = GetPersistentId();
363 std::stringstream ss;
364 ss << "ID: " << persistentId << ", needHide: " << needHide;
365
366 if (surfaceNode_ == nullptr) {
367 TLOGE(WmsLogTag::WMS_UIEXT, "surfaceNode is null, %{public}s", ss.str().c_str());
368 return WMError::WM_ERROR_NULLPTR;
369 }
370
371 // Let rs guarantee the security and permissions of the interface
372 auto errCode = surfaceNode_->SetHidePrivacyContent(needHide);
373 TLOGI(WmsLogTag::WMS_UIEXT,
374 "Notify Render Service client finished, %{public}s, err: %{public}u", ss.str().c_str(), errCode);
375 if (errCode == RSInterfaceErrorCode::NONSYSTEM_CALLING) { // not system app calling
376 return WMError::WM_ERROR_NOT_SYSTEM_APP;
377 } else if (errCode != RSInterfaceErrorCode::NO_ERROR) { // other error
378 return WMError::WM_ERROR_SYSTEM_ABNORMALLY;
379 }
380
381 return WMError::WM_OK;
382 }
383
NotifyFocusStateEvent(bool focusState)384 void WindowExtensionSessionImpl::NotifyFocusStateEvent(bool focusState)
385 {
386 std::shared_ptr<Ace::UIContent> uiContent = GetUIContentSharedPtr();
387 if (uiContent) {
388 focusState ? uiContent->Focus() : uiContent->UnFocus();
389 }
390 if (focusState) {
391 NotifyWindowAfterFocused();
392 } else {
393 NotifyWindowAfterUnfocused();
394 }
395 focusState_ = focusState;
396 if (focusState_ != std::nullopt) {
397 TLOGI(WmsLogTag::WMS_FOCUS, "persistentId:%{public}d focusState:%{public}d",
398 GetPersistentId(), static_cast<int32_t>(focusState_.value()));
399 }
400 }
401
NotifyFocusActiveEvent(bool isFocusActive)402 void WindowExtensionSessionImpl::NotifyFocusActiveEvent(bool isFocusActive)
403 {
404 std::shared_ptr<Ace::UIContent> uiContent = GetUIContentSharedPtr();
405 if (uiContent) {
406 uiContent->SetIsFocusActive(isFocusActive);
407 }
408 }
409
NotifyBackpressedEvent(bool & isConsumed)410 void WindowExtensionSessionImpl::NotifyBackpressedEvent(bool& isConsumed)
411 {
412 std::shared_ptr<Ace::UIContent> uiContent = GetUIContentSharedPtr();
413 if (uiContent) {
414 WLOGFD("Transfer backpressed event to uiContent");
415 isConsumed = uiContent->ProcessBackPressed();
416 }
417 WLOGFD("Backpressed event is not cosumed");
418 }
419
InputMethodKeyEventResultCallback(const std::shared_ptr<MMI::KeyEvent> & keyEvent,bool consumed,std::shared_ptr<std::promise<bool>> isConsumedPromise,std::shared_ptr<bool> isTimeout)420 void WindowExtensionSessionImpl::InputMethodKeyEventResultCallback(const std::shared_ptr<MMI::KeyEvent>& keyEvent,
421 bool consumed, std::shared_ptr<std::promise<bool>> isConsumedPromise, std::shared_ptr<bool> isTimeout)
422 {
423 if (keyEvent == nullptr) {
424 WLOGFW("keyEvent is null, consumed:%{public}" PRId32, consumed);
425 if (isConsumedPromise != nullptr) {
426 isConsumedPromise->set_value(consumed);
427 }
428 return;
429 }
430
431 auto id = keyEvent->GetId();
432 if (isConsumedPromise == nullptr || isTimeout == nullptr) {
433 WLOGFW("Shared point isConsumedPromise or isTimeout is null, id:%{public}" PRId32, id);
434 keyEvent->MarkProcessed();
435 return;
436 }
437
438 if (*isTimeout) {
439 WLOGFW("DispatchKeyEvent timeout id:%{public}" PRId32, id);
440 keyEvent->MarkProcessed();
441 return;
442 }
443
444 if (consumed) {
445 isConsumedPromise->set_value(consumed);
446 WLOGD("Input method has processed key event, id:%{public}" PRId32, id);
447 return;
448 }
449
450 bool isConsumed = false;
451 DispatchKeyEventCallback(const_cast<std::shared_ptr<MMI::KeyEvent>&>(keyEvent), isConsumed);
452 isConsumedPromise->set_value(isConsumed);
453 }
454
NotifyKeyEvent(const std::shared_ptr<MMI::KeyEvent> & keyEvent,bool & isConsumed,bool notifyInputMethod)455 void WindowExtensionSessionImpl::NotifyKeyEvent(const std::shared_ptr<MMI::KeyEvent>& keyEvent, bool& isConsumed,
456 bool notifyInputMethod)
457 {
458 if (keyEvent == nullptr) {
459 WLOGFE("keyEvent is nullptr");
460 return;
461 }
462
463 #ifdef IMF_ENABLE
464 bool isKeyboardEvent = IsKeyboardEvent(keyEvent);
465 if (isKeyboardEvent && notifyInputMethod) {
466 WLOGD("Async dispatch keyEvent to input method, id:%{public}" PRId32, keyEvent->GetId());
467 auto isConsumedPromise = std::make_shared<std::promise<bool>>();
468 auto isConsumedFuture = isConsumedPromise->get_future().share();
469 auto isTimeout = std::make_shared<bool>(false);
470 auto ret = MiscServices::InputMethodController::GetInstance()->DispatchKeyEvent(keyEvent,
471 [weakThis = wptr(this), isConsumedPromise, isTimeout](const std::shared_ptr<MMI::KeyEvent>& keyEvent,
472 bool consumed) {
473 auto window = weakThis.promote();
474 if (window == nullptr) {
475 TLOGNE(WmsLogTag::WMS_UIEXT, "window is nullptr");
476 return;
477 }
478 window->InputMethodKeyEventResultCallback(keyEvent, consumed, isConsumedPromise, isTimeout);
479 });
480 if (ret != 0) {
481 WLOGFW("DispatchKeyEvent failed, ret:%{public}" PRId32 ", id:%{public}" PRId32, ret, keyEvent->GetId());
482 DispatchKeyEventCallback(keyEvent, isConsumed);
483 return;
484 }
485 if (isConsumedFuture.wait_for(std::chrono::milliseconds(DISPATCH_KEY_EVENT_TIMEOUT_TIME_MS)) ==
486 std::future_status::timeout) {
487 *isTimeout = true;
488 isConsumed = true;
489 WLOGFE("DispatchKeyEvent timeout, id:%{public}" PRId32, keyEvent->GetId());
490 } else {
491 isConsumed = isConsumedFuture.get();
492 }
493 WLOGFD("Input Method DispatchKeyEvent isConsumed:%{public}" PRId32, isConsumed);
494 return;
495 }
496 #endif // IMF_ENABLE
497 DispatchKeyEventCallback(keyEvent, isConsumed);
498 }
499
ArkUIFrameworkSupport()500 void WindowExtensionSessionImpl::ArkUIFrameworkSupport()
501 {
502 uint32_t version = 0;
503 if ((context_ != nullptr) && (context_->GetApplicationInfo() != nullptr)) {
504 version = context_->GetApplicationInfo()->apiCompatibleVersion;
505 }
506 // 10 ArkUI new framework support after API10
507 if (version < 10) {
508 SetLayoutFullScreenByApiVersion(isIgnoreSafeArea_);
509 if (!isSystembarPropertiesSet_) {
510 SetSystemBarProperty(WindowType::WINDOW_TYPE_STATUS_BAR, SystemBarProperty());
511 }
512 } else if (isIgnoreSafeAreaNeedNotify_) {
513 SetLayoutFullScreenByApiVersion(isIgnoreSafeArea_);
514 }
515 }
516
NapiSetUIContent(const std::string & contentInfo,napi_env env,napi_value storage,BackupAndRestoreType type,sptr<IRemoteObject> token,AppExecFwk::Ability * ability)517 WMError WindowExtensionSessionImpl::NapiSetUIContent(const std::string& contentInfo, napi_env env, napi_value storage,
518 BackupAndRestoreType type, sptr<IRemoteObject> token, AppExecFwk::Ability* ability)
519 {
520 WLOGFD("WindowExtensionSessionImpl NapiSetUIContent: %{public}s state:%{public}u", contentInfo.c_str(), state_);
521 {
522 std::shared_ptr<Ace::UIContent> uiContent = GetUIContentSharedPtr();
523 if (uiContent) {
524 uiContent->Destroy();
525 }
526 }
527 {
528 std::unique_ptr<Ace::UIContent> uiContent;
529 if (ability != nullptr) {
530 uiContent = Ace::UIContent::Create(ability);
531 } else {
532 uiContent = Ace::UIContent::Create(context_.get(), reinterpret_cast<NativeEngine*>(env));
533 }
534 if (uiContent == nullptr) {
535 WLOGFE("fail to NapiSetUIContent id: %{public}d", GetPersistentId());
536 return WMError::WM_ERROR_NULLPTR;
537 }
538 uiContent->SetParentToken(token);
539 if (property_->GetUIExtensionUsage() == UIExtensionUsage::CONSTRAINED_EMBEDDED) {
540 uiContent->SetUIContentType(Ace::UIContentType::SECURITY_UI_EXTENSION);
541 }
542 uiContent->Initialize(this, contentInfo, storage, property_->GetParentId());
543 // make uiContent available after Initialize/Restore
544 std::unique_lock<std::shared_mutex> lock(uiContentMutex_);
545 uiContent_ = std::move(uiContent);
546 }
547 SetUIContentComplete();
548 NotifyModalUIExtensionMayBeCovered(true);
549
550 UpdateAccessibilityTreeInfo();
551 std::shared_ptr<Ace::UIContent> uiContent = GetUIContentSharedPtr();
552 if (focusState_ != std::nullopt) {
553 focusState_.value() ? uiContent->Focus() : uiContent->UnFocus();
554 }
555 ArkUIFrameworkSupport();
556 UpdateDecorEnable(true);
557 if (state_ == WindowState::STATE_SHOWN) {
558 // UIContent may be nullptr when show window, need to notify again when window is shown
559 uiContent->Foreground();
560 UpdateTitleButtonVisibility();
561 }
562 UpdateViewportConfig(GetRect(), WindowSizeChangeReason::UNDEFINED);
563 WLOGFD("notify uiContent window size change end");
564 return WMError::WM_OK;
565 }
566
UpdateRect(const WSRect & rect,SizeChangeReason reason,const SceneAnimationConfig & config)567 WSError WindowExtensionSessionImpl::UpdateRect(const WSRect& rect, SizeChangeReason reason,
568 const SceneAnimationConfig& config)
569 {
570 auto wmReason = static_cast<WindowSizeChangeReason>(reason);
571 Rect wmRect = {rect.posX_, rect.posY_, rect.width_, rect.height_};
572 auto preRect = GetRect();
573 if (rect.width_ == static_cast<int>(preRect.width_) && rect.height_ == static_cast<int>(preRect.height_)) {
574 WLOGFD("WindowExtensionSessionImpl Update rect [%{public}d, %{public}d, reason: %{public}d]", rect.width_,
575 rect.height_, static_cast<int>(reason));
576 } else {
577 WLOGFI("WindowExtensionSessionImpl Update rect [%{public}d, %{public}d, reason: %{public}d]", rect.width_,
578 rect.height_, static_cast<int>(reason));
579 }
580 property_->SetWindowRect(wmRect);
581
582 if (property_->GetUIExtensionUsage() == UIExtensionUsage::MODAL) {
583 if (!abilityToken_) {
584 TLOGE(WmsLogTag::WMS_UIEXT, "token is nullptr");
585 return WSError::WS_ERROR_NULLPTR;
586 }
587 SingletonContainer::Get<WindowAdapter>().UpdateModalExtensionRect(abilityToken_, wmRect);
588 }
589
590 if (wmReason == WindowSizeChangeReason::ROTATION) {
591 const std::shared_ptr<RSTransaction>& rsTransaction = config.rsTransaction_;
592 UpdateRectForRotation(wmRect, preRect, wmReason, rsTransaction);
593 } else if (handler_ != nullptr) {
594 UpdateRectForOtherReason(wmRect, wmReason);
595 } else {
596 NotifySizeChange(wmRect, wmReason);
597 UpdateViewportConfig(wmRect, wmReason);
598 }
599 return WSError::WS_OK;
600 }
601
UpdateRectForRotation(const Rect & wmRect,const Rect & preRect,WindowSizeChangeReason wmReason,const std::shared_ptr<RSTransaction> & rsTransaction)602 void WindowExtensionSessionImpl::UpdateRectForRotation(const Rect& wmRect, const Rect& preRect,
603 WindowSizeChangeReason wmReason, const std::shared_ptr<RSTransaction>& rsTransaction)
604 {
605 if (!handler_) {
606 return;
607 }
608 auto task = [weak = wptr(this), wmReason, wmRect, preRect, rsTransaction]() mutable {
609 HITRACE_METER_NAME(HITRACE_TAG_WINDOW_MANAGER, "WindowExtensionSessionImpl::UpdateRectForRotation");
610 auto window = weak.promote();
611 if (!window) {
612 return;
613 }
614 int32_t duration = UIEXTENTION_ROTATION_ANIMATION_TIME;
615 bool needSync = false;
616 if (rsTransaction && rsTransaction->GetSyncId() > 0) {
617 // extract high 32 bits of SyncId as pid
618 auto SyncTransactionPid = static_cast<int32_t>(rsTransaction->GetSyncId() >> 32);
619 if (rsTransaction->IsOpenSyncTransaction() || SyncTransactionPid != rsTransaction->GetParentPid()) {
620 needSync = true;
621 }
622 }
623
624 if (needSync) {
625 duration = rsTransaction->GetDuration() ? rsTransaction->GetDuration() : duration;
626 RSTransaction::FlushImplicitTransaction();
627 rsTransaction->Begin();
628 }
629 RSAnimationTimingProtocol protocol;
630 protocol.SetDuration(duration);
631 // animation curve: cubic [0.2, 0.0, 0.2, 1.0]
632 auto curve = RSAnimationTimingCurve::CreateCubicCurve(0.2, 0.0, 0.2, 1.0);
633 RSNode::OpenImplicitAnimation(protocol, curve);
634 if (wmRect != preRect) {
635 window->NotifySizeChange(wmRect, wmReason);
636 }
637 window->UpdateViewportConfig(wmRect, wmReason, rsTransaction);
638 RSNode::CloseImplicitAnimation();
639 if (needSync) {
640 rsTransaction->Commit();
641 } else {
642 RSTransaction::FlushImplicitTransaction();
643 }
644 };
645 handler_->PostTask(task, "WMS_WindowExtensionSessionImpl_UpdateRectForRotation");
646 }
647
UpdateRectForOtherReason(const Rect & wmRect,WindowSizeChangeReason wmReason)648 void WindowExtensionSessionImpl::UpdateRectForOtherReason(const Rect& wmRect, WindowSizeChangeReason wmReason)
649 {
650 auto task = [weak = wptr(this), wmReason, wmRect] {
651 auto window = weak.promote();
652 if (!window) {
653 TLOGE(WmsLogTag::WMS_LAYOUT, "window is null, updateViewPortConfig failed");
654 return;
655 }
656 window->NotifySizeChange(wmRect, wmReason);
657 window->UpdateViewportConfig(wmRect, wmReason);
658 };
659 if (handler_) {
660 handler_->PostTask(task, "WMS_WindowExtensionSessionImpl_UpdateRectForOtherReason");
661 }
662 }
663
NotifyAccessibilityHoverEvent(float pointX,float pointY,int32_t sourceType,int32_t eventType,int64_t timeMs)664 WSError WindowExtensionSessionImpl::NotifyAccessibilityHoverEvent(float pointX, float pointY, int32_t sourceType,
665 int32_t eventType, int64_t timeMs)
666 {
667 std::shared_ptr<Ace::UIContent> uiContent = GetUIContentSharedPtr();
668 if (uiContent == nullptr) {
669 WLOGFE("NotifyAccessibilityHoverEvent error, no uiContent");
670 return WSError::WS_ERROR_NO_UI_CONTENT_ERROR;
671 }
672 uiContent->HandleAccessibilityHoverEvent(pointX, pointY, sourceType, eventType, timeMs);
673 return WSError::WS_OK;
674 }
675
TransferAccessibilityEvent(const Accessibility::AccessibilityEventInfo & info,int64_t uiExtensionIdLevel)676 WMError WindowExtensionSessionImpl::TransferAccessibilityEvent(const Accessibility::AccessibilityEventInfo& info,
677 int64_t uiExtensionIdLevel)
678 {
679 if (IsWindowSessionInvalid()) {
680 WLOGFE("Window session invalid.");
681 return WMError::WM_ERROR_INVALID_WINDOW;
682 }
683 auto hostSession = GetHostSession();
684 CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_INVALID_WINDOW);
685 return static_cast<WMError>(hostSession->TransferAccessibilityEvent(info, uiExtensionIdLevel));
686 }
687
NotifySessionForeground(uint32_t reason,bool withAnimation)688 void WindowExtensionSessionImpl::NotifySessionForeground(uint32_t reason, bool withAnimation)
689 {
690 }
691
NotifySessionBackground(uint32_t reason,bool withAnimation,bool isFromInnerkits)692 void WindowExtensionSessionImpl::NotifySessionBackground(uint32_t reason, bool withAnimation, bool isFromInnerkits)
693 {
694 }
695
NotifyOccupiedAreaChangeInfo(sptr<OccupiedAreaChangeInfo> info,const std::shared_ptr<RSTransaction> & rsTransaction)696 void WindowExtensionSessionImpl::NotifyOccupiedAreaChangeInfo(sptr<OccupiedAreaChangeInfo> info,
697 const std::shared_ptr<RSTransaction>& rsTransaction)
698 {
699 TLOGI(WmsLogTag::WMS_KEYBOARD, "TextFieldPosY = %{public}f, KeyBoardHeight = %{public}d",
700 info->textFieldPositionY_, info->rect_.height_);
701 if (occupiedAreaChangeListener_) {
702 occupiedAreaChangeListener_->OnSizeChange(info, rsTransaction);
703 }
704 }
705
RegisterOccupiedAreaChangeListener(const sptr<IOccupiedAreaChangeListener> & listener)706 WMError WindowExtensionSessionImpl::RegisterOccupiedAreaChangeListener(
707 const sptr<IOccupiedAreaChangeListener>& listener)
708 {
709 occupiedAreaChangeListener_ = listener;
710 return WMError::WM_OK;
711 }
712
UnregisterOccupiedAreaChangeListener(const sptr<IOccupiedAreaChangeListener> & listener)713 WMError WindowExtensionSessionImpl::UnregisterOccupiedAreaChangeListener(
714 const sptr<IOccupiedAreaChangeListener>& listener)
715 {
716 occupiedAreaChangeListener_ = nullptr;
717 return WMError::WM_OK;
718 }
719
GetAvoidAreaByType(AvoidAreaType type,AvoidArea & avoidArea)720 WMError WindowExtensionSessionImpl::GetAvoidAreaByType(AvoidAreaType type, AvoidArea& avoidArea)
721 {
722 WLOGFI("Window Extension Session Get Avoid Area Type");
723 auto hostSession = GetHostSession();
724 CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_NULLPTR);
725 avoidArea = hostSession->GetAvoidAreaByType(type);
726 return WMError::WM_OK;
727 }
728
RegisterAvoidAreaChangeListener(sptr<IAvoidAreaChangedListener> & listener)729 WMError WindowExtensionSessionImpl::RegisterAvoidAreaChangeListener(sptr<IAvoidAreaChangedListener>& listener)
730 {
731 return RegisterExtensionAvoidAreaChangeListener(listener);
732 }
733
UnregisterAvoidAreaChangeListener(sptr<IAvoidAreaChangedListener> & listener)734 WMError WindowExtensionSessionImpl::UnregisterAvoidAreaChangeListener(sptr<IAvoidAreaChangedListener>& listener)
735 {
736 return UnregisterExtensionAvoidAreaChangeListener(listener);
737 }
738
Show(uint32_t reason,bool withAnimation,bool withFocus)739 WMError WindowExtensionSessionImpl::Show(uint32_t reason, bool withAnimation, bool withFocus)
740 {
741 CheckAndAddExtWindowFlags();
742
743 auto display = SingletonContainer::Get<DisplayManager>().GetDisplayById(property_->GetDisplayId());
744 if (display == nullptr) {
745 TLOGE(WmsLogTag::WMS_LIFE, "display is null!");
746 return WMError::WM_ERROR_NULLPTR;
747 }
748 auto displayInfo = display->GetDisplayInfo();
749 if (displayInfo == nullptr) {
750 TLOGE(WmsLogTag::WMS_LIFE, "display info is null!");
751 return WMError::WM_ERROR_NULLPTR;
752 }
753 float density = GetVirtualPixelRatio(displayInfo);
754 if (!MathHelper::NearZero(virtualPixelRatio_ - density)) {
755 UpdateDensity();
756 }
757
758 return this->WindowSessionImpl::Show(reason, withAnimation, withFocus);
759 }
760
Hide(uint32_t reason,bool withAnimation,bool isFromInnerkits)761 WMError WindowExtensionSessionImpl::Hide(uint32_t reason, bool withAnimation, bool isFromInnerkits)
762 {
763 TLOGI(WmsLogTag::WMS_LIFE, "id:%{public}d WindowExtensionSessionImpl Hide, reason:%{public}u, state:%{public}u",
764 GetPersistentId(), reason, state_);
765 if (IsWindowSessionInvalid()) {
766 WLOGFE("session is invalid");
767 return WMError::WM_ERROR_INVALID_WINDOW;
768 }
769 auto hostSession = GetHostSession();
770 CHECK_HOST_SESSION_RETURN_ERROR_IF_NULL(hostSession, WMError::WM_ERROR_INVALID_WINDOW);
771 CheckAndRemoveExtWindowFlags();
772 if (state_ == WindowState::STATE_HIDDEN || state_ == WindowState::STATE_CREATED) {
773 TLOGD(WmsLogTag::WMS_LIFE, "window extension session is already hidden \
774 [name:%{public}s, id:%{public}d, type: %{public}u]",
775 property_->GetWindowName().c_str(), GetPersistentId(), property_->GetWindowType());
776 NotifyBackgroundFailed(WMError::WM_DO_NOTHING);
777 return WMError::WM_OK;
778 }
779 WSError ret = hostSession->Background();
780 WMError res = static_cast<WMError>(ret);
781 if (res == WMError::WM_OK) {
782 UpdateSubWindowStateAndNotify(GetPersistentId(), WindowState::STATE_HIDDEN);
783 state_ = WindowState::STATE_HIDDEN;
784 requestState_ = WindowState::STATE_HIDDEN;
785 NotifyAfterBackground();
786 } else {
787 TLOGD(WmsLogTag::WMS_LIFE, "window extension session Hide to Background is error");
788 }
789 return WMError::WM_OK;
790 }
791
NotifyDensityFollowHost(bool isFollowHost,float densityValue)792 WSError WindowExtensionSessionImpl::NotifyDensityFollowHost(bool isFollowHost, float densityValue)
793 {
794 TLOGI(WmsLogTag::WMS_UIEXT, "isFollowHost:%{public}d densityValue:%{public}f", isFollowHost, densityValue);
795
796 if (!isFollowHost && !isDensityFollowHost_) {
797 TLOGI(WmsLogTag::WMS_UIEXT, "isFollowHost is false and not change");
798 return WSError::WS_OK;
799 }
800
801 if (isFollowHost) {
802 if (std::islessequal(densityValue, 0.0f)) {
803 TLOGE(WmsLogTag::WMS_UIEXT, "densityValue is invalid");
804 return WSError::WS_ERROR_INVALID_PARAM;
805 }
806 if (hostDensityValue_ != std::nullopt &&
807 std::abs(hostDensityValue_->load() - densityValue) < std::numeric_limits<float>::epsilon()) {
808 TLOGI(WmsLogTag::WMS_UIEXT, "densityValue not change");
809 return WSError::WS_OK;
810 }
811 hostDensityValue_ = densityValue;
812 }
813
814 isDensityFollowHost_ = isFollowHost;
815
816 UpdateViewportConfig(GetRect(), WindowSizeChangeReason::UNDEFINED);
817 return WSError::WS_OK;
818 }
819
GetVirtualPixelRatio(sptr<DisplayInfo> displayInfo)820 float WindowExtensionSessionImpl::GetVirtualPixelRatio(sptr<DisplayInfo> displayInfo)
821 {
822 float vpr = 1.0f;
823 if (displayInfo == nullptr) {
824 TLOGE(WmsLogTag::WMS_UIEXT, "displayInfo is nullptr");
825 return vpr;
826 }
827 if (isDensityFollowHost_ && hostDensityValue_ != std::nullopt) {
828 vpr = hostDensityValue_->load();
829 } else {
830 vpr = displayInfo->GetVirtualPixelRatio();
831 }
832 return vpr;
833 }
834
CheckHideNonSecureWindowsPermission(bool shouldHide)835 WMError WindowExtensionSessionImpl::CheckHideNonSecureWindowsPermission(bool shouldHide)
836 {
837 if ((property_->GetUIExtensionUsage() == UIExtensionUsage::MODAL ||
838 property_->GetUIExtensionUsage() == UIExtensionUsage::CONSTRAINED_EMBEDDED) && !shouldHide) {
839 if (!SessionPermission::VerifyCallingPermission("ohos.permission.ALLOW_SHOW_NON_SECURE_WINDOWS")) {
840 extensionWindowFlags_.hideNonSecureWindowsFlag = true;
841 TLOGE(WmsLogTag::WMS_UIEXT, "Permission denied in %{public}s UIExtension.",
842 property_->GetUIExtensionUsage() == UIExtensionUsage::MODAL ? "modal" : "constrained embedded");
843 return WMError::WM_ERROR_INVALID_OPERATION;
844 }
845 if (modalUIExtensionMayBeCovered_) {
846 ReportModalUIExtensionMayBeCovered(modalUIExtensionSelfLoadContent_);
847 }
848 }
849 return WMError::WM_OK;
850 }
851
HideNonSecureWindows(bool shouldHide)852 WMError WindowExtensionSessionImpl::HideNonSecureWindows(bool shouldHide)
853 {
854 TLOGI(WmsLogTag::WMS_UIEXT, "Id: %{public}u, shouldHide: %{public}u", GetPersistentId(), shouldHide);
855 WMError checkRet = CheckHideNonSecureWindowsPermission(shouldHide);
856 if (checkRet != WMError::WM_OK) {
857 return checkRet;
858 }
859
860 if (state_ != WindowState::STATE_SHOWN) {
861 extensionWindowFlags_.hideNonSecureWindowsFlag = shouldHide;
862 return WMError::WM_OK;
863 }
864 if (shouldHide == extensionWindowFlags_.hideNonSecureWindowsFlag) {
865 return WMError::WM_OK;
866 }
867
868 auto updateFlags = extensionWindowFlags_;
869 updateFlags.hideNonSecureWindowsFlag = shouldHide;
870 ExtensionWindowFlags actions(0);
871 actions.hideNonSecureWindowsFlag = true;
872 auto ret = UpdateExtWindowFlags(updateFlags, actions);
873 if (ret == WMError::WM_OK) {
874 extensionWindowFlags_ = updateFlags;
875 }
876 return ret;
877 }
878
SetWaterMarkFlag(bool isEnable)879 WMError WindowExtensionSessionImpl::SetWaterMarkFlag(bool isEnable)
880 {
881 TLOGI(WmsLogTag::WMS_UIEXT, "Id: %{public}u, isEnable: %{public}u", GetPersistentId(), isEnable);
882 if (state_ != WindowState::STATE_SHOWN) {
883 extensionWindowFlags_.waterMarkFlag = isEnable;
884 return WMError::WM_OK;
885 }
886 if (isEnable == extensionWindowFlags_.waterMarkFlag) {
887 return WMError::WM_OK;
888 }
889
890 auto updateFlags = extensionWindowFlags_;
891 updateFlags.waterMarkFlag = isEnable;
892 ExtensionWindowFlags actions(0);
893 actions.waterMarkFlag = true;
894 auto ret = UpdateExtWindowFlags(updateFlags, actions);
895 if (ret == WMError::WM_OK) {
896 extensionWindowFlags_ = updateFlags;
897 }
898 return ret;
899 }
900
CheckAndAddExtWindowFlags()901 void WindowExtensionSessionImpl::CheckAndAddExtWindowFlags()
902 {
903 if (extensionWindowFlags_.bitData != 0) {
904 // If flag is true, make it active when foreground
905 UpdateExtWindowFlags(extensionWindowFlags_, extensionWindowFlags_);
906 }
907 }
908
CheckAndRemoveExtWindowFlags()909 void WindowExtensionSessionImpl::CheckAndRemoveExtWindowFlags()
910 {
911 if (extensionWindowFlags_.bitData != 0) {
912 // If flag is true, make it inactive when background
913 UpdateExtWindowFlags(ExtensionWindowFlags(), extensionWindowFlags_);
914 }
915 }
916
NotifyAccessibilityChildTreeRegister(uint32_t windowId,int32_t treeId,int64_t accessibilityId)917 WSError WindowExtensionSessionImpl::NotifyAccessibilityChildTreeRegister(
918 uint32_t windowId, int32_t treeId, int64_t accessibilityId)
919 {
920 if (!handler_) {
921 return WSError::WS_ERROR_INTERNAL_ERROR;
922 }
923 auto uiContentSharedPtr = GetUIContentSharedPtr();
924 if (uiContentSharedPtr == nullptr) {
925 accessibilityChildTreeInfo_ = {
926 .windowId = windowId,
927 .treeId = treeId,
928 .accessibilityId = accessibilityId
929 };
930 TLOGD(WmsLogTag::WMS_UIEXT, "uiContent is null, save the accessibility child tree info.");
931 return WSError::WS_OK;
932 }
933
934 handler_->PostTask([uiContent = GetUIContentSharedPtr(), windowId, treeId, accessibilityId]() {
935 if (uiContent == nullptr) {
936 TLOGE(WmsLogTag::WMS_UIEXT, "NotifyAccessibilityChildTreeRegister error, no uiContent");
937 return;
938 }
939 TLOGI(WmsLogTag::WMS_UIEXT,
940 "NotifyAccessibilityChildTreeRegister: %{public}d %{public}" PRId64, treeId, accessibilityId);
941 uiContent->RegisterAccessibilityChildTree(windowId, treeId, accessibilityId);
942 });
943 return WSError::WS_OK;
944 }
945
NotifyAccessibilityChildTreeUnregister()946 WSError WindowExtensionSessionImpl::NotifyAccessibilityChildTreeUnregister()
947 {
948 if (!handler_) {
949 return WSError::WS_ERROR_INTERNAL_ERROR;
950 }
951 handler_->PostTask([uiContent = GetUIContentSharedPtr()]() {
952 if (uiContent == nullptr) {
953 TLOGE(WmsLogTag::WMS_UIEXT, "NotifyAccessibilityChildTreeUnregister error, no uiContent");
954 return;
955 }
956 uiContent->DeregisterAccessibilityChildTree();
957 });
958 return WSError::WS_OK;
959 }
960
NotifyAccessibilityDumpChildInfo(const std::vector<std::string> & params,std::vector<std::string> & info)961 WSError WindowExtensionSessionImpl::NotifyAccessibilityDumpChildInfo(
962 const std::vector<std::string>& params, std::vector<std::string>& info)
963 {
964 if (!handler_) {
965 return WSError::WS_ERROR_INTERNAL_ERROR;
966 }
967 handler_->PostSyncTask([uiContent = GetUIContentSharedPtr(), params, &info]() {
968 if (uiContent == nullptr) {
969 TLOGE(WmsLogTag::WMS_UIEXT, "NotifyAccessibilityDumpChildInfo error, no uiContent");
970 return;
971 }
972 uiContent->AccessibilityDumpChildInfo(params, info);
973 });
974 return WSError::WS_OK;
975 }
976
UpdateAccessibilityTreeInfo()977 void WindowExtensionSessionImpl::UpdateAccessibilityTreeInfo()
978 {
979 if (accessibilityChildTreeInfo_ == std::nullopt) {
980 return;
981 }
982 std::shared_ptr<Ace::UIContent> uiContent = GetUIContentSharedPtr();
983 if (uiContent == nullptr) {
984 return;
985 }
986 uiContent->RegisterAccessibilityChildTree(accessibilityChildTreeInfo_->windowId,
987 accessibilityChildTreeInfo_->treeId, accessibilityChildTreeInfo_->accessibilityId);
988 accessibilityChildTreeInfo_.reset();
989 }
990
UpdateExtWindowFlags(const ExtensionWindowFlags & flags,const ExtensionWindowFlags & actions)991 WMError WindowExtensionSessionImpl::UpdateExtWindowFlags(const ExtensionWindowFlags& flags,
992 const ExtensionWindowFlags& actions)
993 {
994 // action is true when the corresponding flag should be updated
995 if (IsWindowSessionInvalid()) {
996 TLOGI(WmsLogTag::WMS_UIEXT, "session is invalid");
997 return WMError::WM_ERROR_INVALID_WINDOW;
998 }
999
1000 if (!abilityToken_) {
1001 TLOGE(WmsLogTag::WMS_UIEXT, "token is nullptr");
1002 return WMError::WM_ERROR_NULLPTR;
1003 }
1004
1005 return SingletonContainer::Get<WindowAdapter>().UpdateExtWindowFlags(abilityToken_, flags.bitData, actions.bitData);
1006 }
1007
GetHostWindowRect(int32_t hostWindowId)1008 Rect WindowExtensionSessionImpl::GetHostWindowRect(int32_t hostWindowId)
1009 {
1010 Rect rect;
1011 if (hostWindowId != property_->GetParentId()) {
1012 TLOGE(WmsLogTag::WMS_UIEXT, "hostWindowId is invalid");
1013 return rect;
1014 }
1015 SingletonContainer::Get<WindowAdapter>().GetHostWindowRect(hostWindowId, rect);
1016 return rect;
1017 }
1018
ConsumePointerEvent(const std::shared_ptr<MMI::PointerEvent> & pointerEvent)1019 void WindowExtensionSessionImpl::ConsumePointerEvent(const std::shared_ptr<MMI::PointerEvent>& pointerEvent)
1020 {
1021 if (pointerEvent == nullptr) {
1022 TLOGE(WmsLogTag::WMS_EVENT, "PointerEvent is nullptr, windowId: %{public}d", GetWindowId());
1023 return;
1024 }
1025 if (hostSession_ == nullptr) {
1026 TLOGE(WmsLogTag::WMS_EVENT, "hostSession is nullptr, windowId: %{public}d", GetWindowId());
1027 pointerEvent->MarkProcessed();
1028 return;
1029 }
1030
1031 MMI::PointerEvent::PointerItem pointerItem;
1032 if (!pointerEvent->GetPointerItem(pointerEvent->GetPointerId(), pointerItem)) {
1033 TLOGW(WmsLogTag::WMS_EVENT, "invalid pointerEvent, windowId: %{public}d", GetWindowId());
1034 pointerEvent->MarkProcessed();
1035 return;
1036 }
1037 auto action = pointerEvent->GetPointerAction();
1038 bool isPointDown = (action == MMI::PointerEvent::POINTER_ACTION_DOWN ||
1039 action == MMI::PointerEvent::POINTER_ACTION_BUTTON_DOWN);
1040 if (property_ && (property_->GetUIExtensionUsage() == UIExtensionUsage::MODAL) && isPointDown) {
1041 if (!abilityToken_) {
1042 TLOGE(WmsLogTag::WMS_UIEXT, "token is nullptr");
1043 return;
1044 }
1045 SingletonContainer::Get<WindowAdapter>().ProcessModalExtensionPointDown(abilityToken_,
1046 pointerItem.GetDisplayX(), pointerItem.GetDisplayY());
1047 }
1048 if (action != MMI::PointerEvent::POINTER_ACTION_MOVE) {
1049 TLOGI(WmsLogTag::WMS_EVENT, "InputTracking id:%{public}d,windowId:%{public}u,"
1050 "pointId:%{public}d,sourceType:%{public}d", pointerEvent->GetId(), GetWindowId(),
1051 pointerEvent->GetPointerId(), pointerEvent->GetSourceType());
1052 }
1053 NotifyPointerEvent(pointerEvent);
1054 }
1055
PreNotifyKeyEvent(const std::shared_ptr<MMI::KeyEvent> & keyEvent)1056 bool WindowExtensionSessionImpl::PreNotifyKeyEvent(const std::shared_ptr<MMI::KeyEvent>& keyEvent)
1057 {
1058 if (keyEvent == nullptr) {
1059 TLOGE(WmsLogTag::WMS_EVENT, "keyEvent is nullptr");
1060 return false;
1061 }
1062 RefreshNoInteractionTimeoutMonitor();
1063 if (property_->GetUIExtensionUsage() == UIExtensionUsage::CONSTRAINED_EMBEDDED) {
1064 if (focusState_ == std::nullopt) {
1065 TLOGW(WmsLogTag::WMS_EVENT, "focusState is null");
1066 keyEvent->MarkProcessed();
1067 return true;
1068 }
1069 if (!focusState_.value()) {
1070 keyEvent->MarkProcessed();
1071 return true;
1072 }
1073 TLOGI(WmsLogTag::WMS_EVENT, "InputTracking:%{public}d wid:%{public}d",
1074 keyEvent->GetId(), keyEvent->GetAgentWindowId());
1075 }
1076 std::shared_ptr<Ace::UIContent> uiContent = GetUIContentSharedPtr();
1077 if (uiContent != nullptr) {
1078 return uiContent->ProcessKeyEvent(keyEvent, true);
1079 }
1080 return false;
1081 }
1082
GetFreeMultiWindowModeEnabledState()1083 bool WindowExtensionSessionImpl::GetFreeMultiWindowModeEnabledState()
1084 {
1085 bool enable = false;
1086 SingletonContainer::Get<WindowAdapter>().GetFreeMultiWindowEnableState(enable);
1087 TLOGI(WmsLogTag::WMS_MULTI_WINDOW, "GetFreeMultiWindowEnableState = %{public}u", enable);
1088 return enable;
1089 }
1090
NotifyExtensionTimeout(int32_t errorCode)1091 void WindowExtensionSessionImpl::NotifyExtensionTimeout(int32_t errorCode)
1092 {
1093 auto hostSession = GetHostSession();
1094 CHECK_HOST_SESSION_RETURN_IF_NULL(hostSession);
1095 hostSession->NotifyExtensionTimeout(errorCode);
1096 }
1097
GetRealParentId() const1098 int32_t WindowExtensionSessionImpl::GetRealParentId() const
1099 {
1100 return property_->GetRealParentId();
1101 }
1102
GetParentWindowType() const1103 WindowType WindowExtensionSessionImpl::GetParentWindowType() const
1104 {
1105 return property_->GetParentWindowType();
1106 }
1107
NotifyModalUIExtensionMayBeCovered(bool byLoadContent)1108 void WindowExtensionSessionImpl::NotifyModalUIExtensionMayBeCovered(bool byLoadContent)
1109 {
1110 if (property_->GetUIExtensionUsage() != UIExtensionUsage::MODAL &&
1111 property_->GetUIExtensionUsage() != UIExtensionUsage::CONSTRAINED_EMBEDDED) {
1112 return;
1113 }
1114
1115 modalUIExtensionMayBeCovered_ = true;
1116 if (byLoadContent) {
1117 modalUIExtensionSelfLoadContent_ = true;
1118 }
1119 if (extensionWindowFlags_.hideNonSecureWindowsFlag) {
1120 return;
1121 }
1122 ReportModalUIExtensionMayBeCovered(byLoadContent);
1123 }
1124
ReportModalUIExtensionMayBeCovered(bool byLoadContent) const1125 void WindowExtensionSessionImpl::ReportModalUIExtensionMayBeCovered(bool byLoadContent) const
1126 {
1127 TLOGW(WmsLogTag::WMS_UIEXT, "Id=%{public}d", GetPersistentId());
1128 std::ostringstream oss;
1129 oss << "Modal UIExtension may be covered uid: " << getuid();
1130 oss << ", windowName: " << property_->GetWindowName();
1131 if (context_) {
1132 oss << ", bundleName: " << context_->GetBundleName();
1133 }
1134 auto type = byLoadContent ? WindowDFXHelperType::WINDOW_MODAL_UIEXTENSION_UICONTENT_CHECK :
1135 WindowDFXHelperType::WINDOW_MODAL_UIEXTENSION_SUBWINDOW_CHECK;
1136 SingletonContainer::Get<WindowInfoReporter>().ReportWindowException(static_cast<int32_t>(type), getpid(),
1137 oss.str());
1138 }
1139
NotifyExtensionEventAsync(uint32_t notifyEvent)1140 void WindowExtensionSessionImpl::NotifyExtensionEventAsync(uint32_t notifyEvent)
1141 {
1142 TLOGI(WmsLogTag::WMS_UIEXT, "notifyEvent:%{public}d", notifyEvent);
1143 if (IsWindowSessionInvalid()) {
1144 TLOGE(WmsLogTag::WMS_UIEXT, "Window session invalid.");
1145 return;
1146 }
1147 auto hostSession = GetHostSession();
1148 CHECK_HOST_SESSION_RETURN_IF_NULL(hostSession);
1149 hostSession->NotifyExtensionEventAsync(notifyEvent);
1150 }
1151
NotifyDumpInfo(const std::vector<std::string> & params,std::vector<std::string> & info)1152 WSError WindowExtensionSessionImpl::NotifyDumpInfo(const std::vector<std::string>& params,
1153 std::vector<std::string>& info)
1154 {
1155 TLOGI(WmsLogTag::WMS_UIEXT, "persistentId=%{public}d", GetPersistentId());
1156 auto uiContentSharedPtr = GetUIContentSharedPtr();
1157 if (uiContentSharedPtr == nullptr) {
1158 TLOGE(WmsLogTag::WMS_UIEXT, "uiContent is nullptr");
1159 return WSError::WS_ERROR_NULLPTR;
1160 }
1161 uiContentSharedPtr->DumpInfo(params, info);
1162 if (!SessionPermission::IsBetaVersion()) {
1163 TLOGW(WmsLogTag::WMS_UIEXT, "is not beta version, persistentId: %{public}d", GetPersistentId());
1164 info.clear();
1165 }
1166 return WSError::WS_OK;
1167 }
1168
IsPcWindow() const1169 bool WindowExtensionSessionImpl::IsPcWindow() const
1170 {
1171 bool isPcWindow = false;
1172 WMError ret = SingletonContainer::Get<WindowAdapter>().IsPcWindow(isPcWindow);
1173 if (ret != WMError::WM_OK) {
1174 TLOGE(WmsLogTag::WMS_UIEXT, "can't find isPcWindow, err: %{public}u",
1175 static_cast<uint32_t>(ret));
1176 }
1177 return isPcWindow;
1178 }
1179
IsPcOrPadFreeMultiWindowMode() const1180 bool WindowExtensionSessionImpl::IsPcOrPadFreeMultiWindowMode() const
1181 {
1182 bool isPcOrPadFreeMultiWindowMode = false;
1183 WMError ret = SingletonContainer::Get<WindowAdapter>().IsPcOrPadFreeMultiWindowMode(isPcOrPadFreeMultiWindowMode);
1184 if (ret != WMError::WM_OK) {
1185 TLOGE(WmsLogTag::WMS_UIEXT, "cant't find isPcOrPadFreeMultiWindowMode, err: %{public}u",
1186 static_cast<uint32_t>(ret));
1187 }
1188 return isPcOrPadFreeMultiWindowMode;
1189 }
1190 } // namespace Rosen
1191 } // namespace OHOS
1192