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