• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include "window_extension_session_impl.h"
17 
18 #include <transaction/rs_transaction.h>
19 #include "window_manager_hilog.h"
20 #include "parameters.h"
21 #include "anr_handler.h"
22 
23 namespace OHOS {
24 namespace Rosen {
25 namespace {
26 constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WINDOW, "WindowExtensionSessionImpl"};
27 }
28 
29 std::set<sptr<WindowSessionImpl>> WindowExtensionSessionImpl::windowExtensionSessionSet_;
30 std::shared_mutex WindowExtensionSessionImpl::windowExtensionSessionMutex_;
31 
WindowExtensionSessionImpl(const sptr<WindowOption> & option)32 WindowExtensionSessionImpl::WindowExtensionSessionImpl(const sptr<WindowOption>& option) : WindowSessionImpl(option)
33 {
34 }
35 
~WindowExtensionSessionImpl()36 WindowExtensionSessionImpl::~WindowExtensionSessionImpl()
37 {
38 }
39 
Create(const std::shared_ptr<AbilityRuntime::Context> & context,const sptr<Rosen::ISession> & iSession)40 WMError WindowExtensionSessionImpl::Create(const std::shared_ptr<AbilityRuntime::Context>& context,
41     const sptr<Rosen::ISession>& iSession)
42 {
43     WLOGFI("In");
44     if (!context || !iSession) {
45         WLOGFE("context is nullptr: %{public}u or sessionToken is nullptr: %{public}u",
46             context == nullptr, iSession == nullptr);
47         return WMError::WM_ERROR_NULLPTR;
48     }
49     SetDefaultDisplayIdIfNeed();
50     hostSession_ = iSession;
51     context_ = context;
52     WMError ret = Connect();
53     if (ret == WMError::WM_OK) {
54         std::unique_lock<std::shared_mutex> lock(windowExtensionSessionMutex_);
55         windowExtensionSessionSet_.insert(this);
56     }
57     state_ = WindowState::STATE_CREATED;
58     return WMError::WM_OK;
59 }
60 
UpdateConfiguration(const std::shared_ptr<AppExecFwk::Configuration> & configuration)61 void WindowExtensionSessionImpl::UpdateConfiguration(const std::shared_ptr<AppExecFwk::Configuration>& configuration)
62 {
63     if (uiContent_ != nullptr) {
64         WLOGFD("notify ace winId:%{public}u", GetWindowId());
65         uiContent_->UpdateConfiguration(configuration);
66     }
67 }
68 
UpdateConfigurationForAll(const std::shared_ptr<AppExecFwk::Configuration> & configuration)69 void WindowExtensionSessionImpl::UpdateConfigurationForAll(const std::shared_ptr<AppExecFwk::Configuration>& configuration)
70 {
71     WLOGD("notify scene ace update config");
72     std::unique_lock<std::shared_mutex> lock(windowExtensionSessionMutex_);
73     for (const auto& window : windowExtensionSessionSet_) {
74         window->UpdateConfiguration(configuration);
75     }
76 }
77 
Destroy(bool needNotifyServer,bool needClearListener)78 WMError WindowExtensionSessionImpl::Destroy(bool needNotifyServer, bool needClearListener)
79 {
80     WLOGFI("[WMSLife]Id: %{public}d Destroy, state_:%{public}u, needNotifyServer: %{public}d, "
81         "needClearListener: %{public}d", GetPersistentId(), state_, needNotifyServer, needClearListener);
82     if (IsWindowSessionInvalid()) {
83         WLOGFE("[WMSLife]session is invalid");
84         return WMError::WM_ERROR_INVALID_WINDOW;
85     }
86     if (hostSession_ != nullptr) {
87         hostSession_->Disconnect();
88     }
89     NotifyBeforeDestroy(GetWindowName());
90     {
91         std::lock_guard<std::recursive_mutex> lock(mutex_);
92         state_ = WindowState::STATE_DESTROYED;
93         requestState_ = WindowState::STATE_DESTROYED;
94     }
95     hostSession_ = nullptr;
96     {
97         std::unique_lock<std::shared_mutex> lock(windowExtensionSessionMutex_);
98         windowExtensionSessionSet_.erase(this);
99     }
100     DelayedSingleton<ANRHandler>::GetInstance()->OnWindowDestroyed(GetPersistentId());
101     NotifyAfterDestroy();
102     if (needClearListener) {
103         ClearListenersById(GetPersistentId());
104     }
105     return WMError::WM_OK;
106 }
107 
MoveTo(int32_t x,int32_t y)108 WMError WindowExtensionSessionImpl::MoveTo(int32_t x, int32_t y)
109 {
110     WLOGFD("Id:%{public}d MoveTo %{public}d %{public}d", property_->GetPersistentId(), x, y);
111     if (IsWindowSessionInvalid()) {
112         WLOGFE("Window session invalid.");
113         return WMError::WM_ERROR_INVALID_WINDOW;
114     }
115     const auto& rect = property_->GetWindowRect();
116     WSRect wsRect = { x, y, rect.width_, rect.height_ };
117     WSError error = UpdateRect(wsRect, SizeChangeReason::MOVE);
118     return static_cast<WMError>(error);
119 }
120 
Resize(uint32_t width,uint32_t height)121 WMError WindowExtensionSessionImpl::Resize(uint32_t width, uint32_t height)
122 {
123     WLOGFD("Id:%{public}d Resize %{public}u %{public}u", property_->GetPersistentId(), width, height);
124     if (IsWindowSessionInvalid()) {
125         WLOGFE("Window session invalid.");
126         return WMError::WM_ERROR_INVALID_WINDOW;
127     }
128     const auto& rect = property_->GetWindowRect();
129     WSRect wsRect = { rect.posX_, rect.posY_, width, height };
130     WSError error = UpdateRect(wsRect, SizeChangeReason::RESIZE);
131     return static_cast<WMError>(error);
132 }
133 
TransferAbilityResult(uint32_t resultCode,const AAFwk::Want & want)134 WMError WindowExtensionSessionImpl::TransferAbilityResult(uint32_t resultCode, const AAFwk::Want& want)
135 {
136     if (IsWindowSessionInvalid()) {
137         WLOGFE("Window session invalid.");
138         return WMError::WM_ERROR_REPEAT_OPERATION;
139     }
140     return static_cast<WMError>(hostSession_->TransferAbilityResult(resultCode, want));
141 }
142 
TransferExtensionData(const AAFwk::WantParams & wantParams)143 WMError WindowExtensionSessionImpl::TransferExtensionData(const AAFwk::WantParams& wantParams)
144 {
145     if (IsWindowSessionInvalid()) {
146         WLOGFE("Window session invalid.");
147         return WMError::WM_ERROR_REPEAT_OPERATION;
148     }
149     return static_cast<WMError>(hostSession_->TransferExtensionData(wantParams));
150 }
151 
RegisterTransferComponentDataListener(const NotifyTransferComponentDataFunc & func)152 void WindowExtensionSessionImpl::RegisterTransferComponentDataListener(const NotifyTransferComponentDataFunc& func)
153 {
154     if (IsWindowSessionInvalid()) {
155         WLOGFE("Window session invalid.");
156         return;
157     }
158     notifyTransferComponentDataFunc_ = std::move(func);
159     hostSession_->NotifyAsyncOn();
160 }
161 
NotifyTransferComponentData(const AAFwk::WantParams & wantParams)162 WSError WindowExtensionSessionImpl::NotifyTransferComponentData(const AAFwk::WantParams& wantParams)
163 {
164     if (notifyTransferComponentDataFunc_) {
165         notifyTransferComponentDataFunc_(wantParams);
166     }
167     return WSError::WS_OK;
168 }
169 
NotifyTransferComponentDataSync(const AAFwk::WantParams & wantParams,AAFwk::WantParams & reWantParams)170 WSErrorCode WindowExtensionSessionImpl::NotifyTransferComponentDataSync(
171     const AAFwk::WantParams& wantParams, AAFwk::WantParams& reWantParams)
172 {
173     if (notifyTransferComponentDataForResultFunc_) {
174         reWantParams = notifyTransferComponentDataForResultFunc_(wantParams);
175         return WSErrorCode::WS_OK;
176     }
177     return WSErrorCode::WS_ERROR_NOT_REGISTER_SYNC_CALLBACK;
178 }
179 
RegisterTransferComponentDataForResultListener(const NotifyTransferComponentDataForResultFunc & func)180 void WindowExtensionSessionImpl::RegisterTransferComponentDataForResultListener(
181     const NotifyTransferComponentDataForResultFunc& func)
182 {
183     if (IsWindowSessionInvalid()) {
184         WLOGFE("Window session invalid.");
185         return;
186     }
187     notifyTransferComponentDataForResultFunc_ = std::move(func);
188     hostSession_->NotifySyncOn();
189 }
190 
TriggerBindModalUIExtension()191 void WindowExtensionSessionImpl::TriggerBindModalUIExtension()
192 {
193     WLOGFD("called");
194     if (hostSession_ == nullptr) {
195         WLOGFE("hostSession_ is nullptr");
196         return;
197     }
198     hostSession_->TriggerBindModalUIExtension();
199 }
200 
SetPrivacyMode(bool isPrivacyMode)201 WMError WindowExtensionSessionImpl::SetPrivacyMode(bool isPrivacyMode)
202 {
203     WLOGFD("id : %{public}u, SetPrivacyMode, %{public}u", GetWindowId(), isPrivacyMode);
204     if (surfaceNode_ == nullptr) {
205         WLOGFE("surfaceNode_ is nullptr");
206         return WMError::WM_ERROR_NULLPTR;
207     }
208     surfaceNode_->SetSecurityLayer(isPrivacyMode);
209     RSTransaction::FlushImplicitTransaction();
210     return WMError::WM_OK;
211 }
212 
NotifyFocusStateEvent(bool focusState)213 void WindowExtensionSessionImpl::NotifyFocusStateEvent(bool focusState)
214 {
215     if (uiContent_) {
216         focusState ? uiContent_->Focus() : uiContent_->UnFocus();
217     }
218     focusState_ = focusState;
219 }
220 
NotifyFocusActiveEvent(bool isFocusActive)221 void WindowExtensionSessionImpl::NotifyFocusActiveEvent(bool isFocusActive)
222 {
223     if (uiContent_) {
224         uiContent_->SetIsFocusActive(isFocusActive);
225     }
226 }
227 
NotifyBackpressedEvent(bool & isConsumed)228 void WindowExtensionSessionImpl::NotifyBackpressedEvent(bool& isConsumed)
229 {
230     if (uiContent_) {
231         WLOGFD("Transfer backpressed event to uiContent");
232         isConsumed = uiContent_->ProcessBackPressed();
233     }
234     WLOGFD("Backpressed event is not cosumed");
235 }
236 
NapiSetUIContent(const std::string & contentInfo,napi_env env,napi_value storage,bool isdistributed,sptr<IRemoteObject> token,AppExecFwk::Ability * ability)237 WMError WindowExtensionSessionImpl::NapiSetUIContent(const std::string& contentInfo,
238     napi_env env, napi_value storage, bool isdistributed, sptr<IRemoteObject> token, AppExecFwk::Ability* ability)
239 {
240     WLOGFD("WindowExtensionSessionImpl NapiSetUIContent: %{public}s state:%{public}u", contentInfo.c_str(), state_);
241     if (uiContent_) {
242         uiContent_->Destroy();
243     }
244     std::unique_ptr<Ace::UIContent> uiContent;
245     if (ability != nullptr) {
246         uiContent = Ace::UIContent::Create(ability);
247     } else {
248         uiContent = Ace::UIContent::Create(context_.get(), reinterpret_cast<NativeEngine*>(env));
249     }
250     if (uiContent == nullptr) {
251         WLOGFE("fail to NapiSetUIContent id: %{public}d", GetPersistentId());
252         return WMError::WM_ERROR_NULLPTR;
253     }
254     uiContent->SetParentToken(token);
255     uiContent->Initialize(this, contentInfo, storage, property_->GetParentId());
256     // make uiContent available after Initialize/Restore
257     uiContent_ = std::move(uiContent);
258 
259     if (focusState_ != std::nullopt) {
260         focusState_.value() ? uiContent_->Focus() : uiContent_->UnFocus();
261     }
262 
263     uint32_t version = 0;
264     if ((context_ != nullptr) && (context_->GetApplicationInfo() != nullptr)) {
265         version = context_->GetApplicationInfo()->apiCompatibleVersion;
266     }
267     // 10 ArkUI new framework support after API10
268     if (version < 10) {
269         SetLayoutFullScreenByApiVersion(isIgnoreSafeArea_);
270         if (!isSystembarPropertiesSet_) {
271             SetSystemBarProperty(WindowType::WINDOW_TYPE_STATUS_BAR, SystemBarProperty());
272         }
273     } else if (isIgnoreSafeAreaNeedNotify_) {
274         SetLayoutFullScreenByApiVersion(isIgnoreSafeArea_);
275     }
276 
277     UpdateDecorEnable(true);
278     if (state_ == WindowState::STATE_SHOWN) {
279         // UIContent may be nullptr when show window, need to notify again when window is shown
280         uiContent_->Foreground();
281         UpdateTitleButtonVisibility();
282     }
283     UpdateViewportConfig(GetRect(), WindowSizeChangeReason::UNDEFINED);
284     WLOGFD("notify uiContent window size change end");
285     return WMError::WM_OK;
286 }
287 
UpdateRect(const WSRect & rect,SizeChangeReason reason,const std::shared_ptr<RSTransaction> & rsTransaction)288 WSError WindowExtensionSessionImpl::UpdateRect(const WSRect& rect, SizeChangeReason reason,
289     const std::shared_ptr<RSTransaction>& rsTransaction)
290 {
291     WLOGFI("WindowExtensionSessionImpl Update rect [%{public}d, %{public}d, reason: %{public}d]", rect.width_,
292         rect.height_, static_cast<int>(reason));
293     auto wmReason = static_cast<WindowSizeChangeReason>(reason);
294     Rect wmRect = {rect.posX_, rect.posY_, rect.width_, rect.height_};
295     property_->SetWindowRect(wmRect);
296     NotifySizeChange(wmRect, wmReason);
297     UpdateViewportConfig(wmRect, wmReason);
298     return WSError::WS_OK;
299 }
300 
NotifySearchElementInfoByAccessibilityId(int64_t elementId,int32_t mode,int64_t baseParent,std::list<Accessibility::AccessibilityElementInfo> & infos)301 WSError WindowExtensionSessionImpl::NotifySearchElementInfoByAccessibilityId(int64_t elementId, int32_t mode,
302     int64_t baseParent, std::list<Accessibility::AccessibilityElementInfo>& infos)
303 {
304     if (uiContent_ == nullptr) {
305         WLOGFE("NotifySearchElementInfoByAccessibilityId error, no uiContent_");
306         return WSError::WS_ERROR_NO_UI_CONTENT_ERROR;
307     }
308     uiContent_->SearchElementInfoByAccessibilityId(elementId, mode, baseParent, infos);
309     return WSError::WS_OK;
310 }
311 
NotifySearchElementInfosByText(int64_t elementId,const std::string & text,int64_t baseParent,std::list<Accessibility::AccessibilityElementInfo> & infos)312 WSError WindowExtensionSessionImpl::NotifySearchElementInfosByText(int64_t elementId, const std::string& text,
313     int64_t baseParent, std::list<Accessibility::AccessibilityElementInfo>& infos)
314 {
315     if (uiContent_ == nullptr) {
316         WLOGFE("NotifySearchElementInfosByText error, no uiContent_");
317         return WSError::WS_ERROR_NO_UI_CONTENT_ERROR;
318     }
319     uiContent_->SearchElementInfosByText(elementId, text, baseParent, infos);
320     return WSError::WS_OK;
321 }
322 
NotifyFindFocusedElementInfo(int64_t elementId,int32_t focusType,int64_t baseParent,Accessibility::AccessibilityElementInfo & info)323 WSError WindowExtensionSessionImpl::NotifyFindFocusedElementInfo(int64_t elementId, int32_t focusType,
324     int64_t baseParent, Accessibility::AccessibilityElementInfo& info)
325 {
326     if (uiContent_ == nullptr) {
327         WLOGFE("NotifyFindFocusedElementInfo error, no uiContent_");
328         return WSError::WS_ERROR_NO_UI_CONTENT_ERROR;
329     }
330     uiContent_->FindFocusedElementInfo(elementId, focusType, baseParent, info);
331     return WSError::WS_OK;
332 }
333 
NotifyFocusMoveSearch(int64_t elementId,int32_t direction,int64_t baseParent,Accessibility::AccessibilityElementInfo & info)334 WSError WindowExtensionSessionImpl::NotifyFocusMoveSearch(int64_t elementId, int32_t direction, int64_t baseParent,
335     Accessibility::AccessibilityElementInfo& info)
336 {
337     if (uiContent_ == nullptr) {
338         WLOGFE("NotifyFocusMoveSearch error, no uiContent_");
339         return WSError::WS_ERROR_NO_UI_CONTENT_ERROR;
340     }
341     uiContent_->FocusMoveSearch(elementId, direction, baseParent, info);
342     return WSError::WS_OK;
343 }
344 
NotifyExecuteAction(int64_t elementId,const std::map<std::string,std::string> & actionAguments,int32_t action,int64_t baseParent)345 WSError WindowExtensionSessionImpl::NotifyExecuteAction(int64_t elementId,
346     const std::map<std::string, std::string>& actionAguments, int32_t action,
347     int64_t baseParent)
348 {
349     if (uiContent_ == nullptr) {
350         WLOGFE("NotifyExecuteAction error, no uiContent_");
351         return WSError::WS_ERROR_NO_UI_CONTENT_ERROR;
352     }
353     bool ret = uiContent_->NotifyExecuteAction(elementId, actionAguments, action, baseParent);
354     if (!ret) {
355         WLOGFE("NotifyExecuteAction fail");
356         return WSError::WS_ERROR_INTERNAL_ERROR;
357     }
358     return WSError::WS_OK;
359 }
360 
TransferAccessibilityEvent(const Accessibility::AccessibilityEventInfo & info,int64_t uiExtensionIdLevel)361 WMError WindowExtensionSessionImpl::TransferAccessibilityEvent(const Accessibility::AccessibilityEventInfo& info,
362     int64_t uiExtensionIdLevel)
363 {
364     if (IsWindowSessionInvalid()) {
365         WLOGFE("Window session invalid.");
366         return WMError::WM_ERROR_INVALID_WINDOW;
367     }
368     return static_cast<WMError>(hostSession_->TransferAccessibilityEvent(info, uiExtensionIdLevel));
369 }
370 
NotifySessionForeground(uint32_t reason,bool withAnimation)371 void WindowExtensionSessionImpl::NotifySessionForeground(uint32_t reason, bool withAnimation)
372 {
373 }
374 
NotifySessionBackground(uint32_t reason,bool withAnimation,bool isFromInnerkits)375 void WindowExtensionSessionImpl::NotifySessionBackground(uint32_t reason, bool withAnimation, bool isFromInnerkits)
376 {
377 }
378 
NotifyOccupiedAreaChangeInfo(sptr<OccupiedAreaChangeInfo> info)379 void WindowExtensionSessionImpl::NotifyOccupiedAreaChangeInfo(sptr<OccupiedAreaChangeInfo> info)
380 {
381     WLOGD("TextFieldPosY = %{public}lf, KeyBoardHeight = %{public}d", info->textFieldPositionY_, info->rect_.height_);
382     if (occupiedAreaChangeListener_) {
383         occupiedAreaChangeListener_->OnSizeChange(info);
384     }
385 }
386 
RegisterOccupiedAreaChangeListener(const sptr<IOccupiedAreaChangeListener> & listener)387 WMError WindowExtensionSessionImpl::RegisterOccupiedAreaChangeListener(
388     const sptr<IOccupiedAreaChangeListener>& listener)
389 {
390     occupiedAreaChangeListener_ = listener;
391     return WMError::WM_OK;
392 }
393 
UnregisterOccupiedAreaChangeListener(const sptr<IOccupiedAreaChangeListener> & listener)394 WMError WindowExtensionSessionImpl::UnregisterOccupiedAreaChangeListener(
395     const sptr<IOccupiedAreaChangeListener>& listener)
396 {
397     occupiedAreaChangeListener_ = nullptr;
398     return WMError::WM_OK;
399 }
400 
GetAvoidAreaByType(AvoidAreaType type,AvoidArea & avoidArea)401 WMError WindowExtensionSessionImpl::GetAvoidAreaByType(AvoidAreaType type, AvoidArea& avoidArea)
402 {
403     WLOGFI("Window Extension Session Get Avoid Area Type");
404     if (hostSession_ == nullptr) {
405         return WMError::WM_ERROR_NULLPTR;
406     }
407     avoidArea = hostSession_->GetAvoidAreaByType(type);
408     return WMError::WM_OK;
409 }
410 
RegisterAvoidAreaChangeListener(sptr<IAvoidAreaChangedListener> & listener)411 WMError WindowExtensionSessionImpl::RegisterAvoidAreaChangeListener(sptr<IAvoidAreaChangedListener>& listener)
412 {
413     return RegisterExtensionAvoidAreaChangeListener(listener);
414 }
415 
UnregisterAvoidAreaChangeListener(sptr<IAvoidAreaChangedListener> & listener)416 WMError WindowExtensionSessionImpl::UnregisterAvoidAreaChangeListener(sptr<IAvoidAreaChangedListener>& listener)
417 {
418     return UnregisterExtensionAvoidAreaChangeListener(listener);
419 }
420 
Hide(uint32_t reason,bool withAnimation,bool isFromInnerkits)421 WMError WindowExtensionSessionImpl::Hide(uint32_t reason, bool withAnimation, bool isFromInnerkits)
422 {
423     WLOGFI("[WMSLife]id:%{public}d WindowExtensionSessionImpl Hide, reason:%{public}u, state:%{public}u",
424            GetPersistentId(), reason, state_);
425     if (IsWindowSessionInvalid()) {
426         WLOGFE("session is invalid");
427         return WMError::WM_ERROR_INVALID_WINDOW;
428     }
429     if (state_ == WindowState::STATE_HIDDEN || state_ == WindowState::STATE_CREATED) {
430         WLOGFD("[WMSLife]window extension session is already hidden [name:%{public}s,id:%{public}d,type: %{public}u]",
431                property_->GetWindowName().c_str(), GetPersistentId(), property_->GetWindowType());
432         NotifyBackgroundFailed(WMError::WM_DO_NOTHING);
433         return WMError::WM_OK;
434     }
435     WSError ret = hostSession_->Background();
436     WMError res = static_cast<WMError>(ret);
437     if (res == WMError::WM_OK) {
438         state_ = WindowState::STATE_HIDDEN;
439         requestState_ = WindowState::STATE_HIDDEN;
440         NotifyAfterBackground();
441     } else {
442         WLOGFD("[WMSLife]window extension session Hide to Background is error");
443     }
444     return WMError::WM_OK;
445 }
446 } // namespace Rosen
447 } // namespace OHOS
448