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