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