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