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