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