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