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