1 /*
2 * Copyright (c) 2025 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 "picture_in_picture_controller_base.h"
17
18 #include <transaction/rs_sync_transaction_controller.h>
19 #include "parameters.h"
20 #include "picture_in_picture_manager.h"
21 #include "rs_adapter.h"
22 #include "singleton_container.h"
23 #include "window_adapter.h"
24 #include "window_manager_hilog.h"
25 #include "window_session_impl.h"
26
27 namespace OHOS {
28 namespace Rosen {
29
30 static const std::map<std::string, PiPControlType> CONTROL_TYPE_MAP = {
31 {"playbackStateChanged", PiPControlType::VIDEO_PLAY_PAUSE},
32 {"nextVideo", PiPControlType::VIDEO_NEXT},
33 {"previousVideo", PiPControlType::VIDEO_PREVIOUS},
34 {"hangUp", PiPControlType::HANG_UP_BUTTON},
35 {"micStateChanged", PiPControlType::MICROPHONE_SWITCH},
36 {"videoStateChanged", PiPControlType::CAMERA_SWITCH},
37 {"voiceStateChanged", PiPControlType::MUTE_SWITCH},
38 {"fastForward", PiPControlType::FAST_FORWARD},
39 {"fastBackward", PiPControlType::FAST_BACKWARD}
40 };
41
PictureInPictureControllerBase(sptr<PipOption> pipOption,sptr<Window> mainWindow,uint32_t windowId,napi_env env)42 PictureInPictureControllerBase::PictureInPictureControllerBase(sptr<PipOption> pipOption, sptr<Window> mainWindow,
43 uint32_t windowId, napi_env env)
44 : pipOption_(pipOption), mainWindow_(mainWindow), mainWindowId_(windowId), env_(env), weakRef_(this)
45 {
46 curState_ = PiPWindowState::STATE_UNDEFINED;
47 }
48
~PictureInPictureControllerBase()49 PictureInPictureControllerBase::~PictureInPictureControllerBase()
50 {
51 if (pipOption_) {
52 pipOption_->ClearNapiRefs(env_);
53 }
54 TLOGI(WmsLogTag::WMS_PIP, "Destruction");
55 }
56
57 // LCOV_EXCL_START
NotifyOpretationError(WMError errCode,StartPipType startType)58 void PictureInPictureControllerBase::NotifyOpretationError(WMError errCode, StartPipType startType)
59 {
60 TLOGE(WmsLogTag::WMS_PIP, "window show failed, err: %{public}u", errCode);
61 for (auto& listener : pipLifeCycleListeners_) {
62 if (listener == nullptr) {
63 TLOGE(WmsLogTag::WMS_PIP, "one lifecycle listener is nullptr");
64 continue;
65 }
66 listener->OnPictureInPictureOperationError(static_cast<int32_t>(errCode));
67 listener->OnPictureInPictureOperationError(controllerId_, static_cast<int32_t>(errCode));
68 }
69 SingletonContainer::Get<PiPReporter>().ReportPiPStartWindow(static_cast<int32_t>(startType),
70 pipOption_->GetPipTemplate(), PipConst::FAILED, "window show failed");
71 }
72
SetControllerId(uint32_t controllerId)73 void PictureInPictureControllerBase::SetControllerId(uint32_t controllerId)
74 {
75 controllerId_ = controllerId;
76 }
77
GetControllerId() const78 uint32_t PictureInPictureControllerBase::GetControllerId() const
79 {
80 return controllerId_;
81 }
82
ShowPictureInPictureWindow(StartPipType startType)83 WMError PictureInPictureControllerBase::ShowPictureInPictureWindow(StartPipType startType)
84 {
85 TLOGI(WmsLogTag::WMS_PIP, "startType:%{public}u", startType);
86 if (pipOption_ == nullptr) {
87 TLOGE(WmsLogTag::WMS_PIP, "Get PictureInPicture option failed");
88 return WMError::WM_ERROR_PIP_CREATE_FAILED;
89 }
90 if (window_ == nullptr) {
91 TLOGE(WmsLogTag::WMS_PIP, "window is null when show pip");
92 SingletonContainer::Get<PiPReporter>().ReportPiPStartWindow(static_cast<int32_t>(startType),
93 pipOption_->GetPipTemplate(), PipConst::FAILED, "window is nullptr");
94 return WMError::WM_ERROR_PIP_STATE_ABNORMALLY;
95 }
96 for (auto& listener : pipLifeCycleListeners_) {
97 if (listener == nullptr) {
98 TLOGE(WmsLogTag::WMS_PIP, "one lifecycle listener is nullptr");
99 continue;
100 }
101 listener->OnPreparePictureInPictureStart();
102 listener->OnPreparePictureInPictureStart(controllerId_);
103 }
104 SetUIContent();
105 WMError errCode = window_->Show(0, false);
106 if (errCode != WMError::WM_OK) {
107 NotifyOpretationError(errCode, startType);
108 return WMError::WM_ERROR_PIP_INTERNAL_ERROR;
109 }
110 uint32_t requestWidth = 0;
111 uint32_t requestHeight = 0;
112 pipOption_->GetContentSize(requestWidth, requestHeight);
113 WindowSizeChangeReason reason = WindowSizeChangeReason::PIP_SHOW;
114 if (startType == StartPipType::AUTO_START) {
115 reason = WindowSizeChangeReason::PIP_AUTO_START;
116 }
117 if (requestWidth > 0 && requestHeight > 0) {
118 Rect requestRect = {0, 0, requestWidth, requestHeight};
119 window_->UpdatePiPRect(requestRect, reason);
120 } else {
121 window_->UpdatePiPRect(windowRect_, reason);
122 }
123 PictureInPictureManager::SetActiveController(this);
124 SingletonContainer::Get<PiPReporter>().ReportPiPStartWindow(static_cast<int32_t>(startType),
125 pipOption_->GetPipTemplate(), PipConst::PIP_SUCCESS, "show pip success");
126 isStoppedFromClient_ = false;
127 return WMError::WM_OK;
128 }
129
StartPictureInPictureInner(StartPipType startType)130 WMError PictureInPictureControllerBase::StartPictureInPictureInner(StartPipType startType)
131 {
132 WMError errCode = CreatePictureInPictureWindow(startType);
133 if (errCode != WMError::WM_OK) {
134 curState_ = PiPWindowState::STATE_UNDEFINED;
135 TLOGE(WmsLogTag::WMS_PIP, "Create pip window failed, err: %{public}u", errCode);
136 SingletonContainer::Get<PiPReporter>().ReportPiPStartWindow(static_cast<int32_t>(startType),
137 pipOption_->GetPipTemplate(), PipConst::FAILED, "Create pip window failed");
138 return errCode;
139 }
140 StartPipType type = startType;
141 if (IsTypeNodeEnabled() && startType != StartPipType::AUTO_START) {
142 type = StartPipType::AUTO_START;
143 }
144 errCode = ShowPictureInPictureWindow(type);
145 if (errCode != WMError::WM_OK) {
146 curState_ = PiPWindowState::STATE_UNDEFINED;
147 TLOGE(WmsLogTag::WMS_PIP, "Show pip window failed, err: %{public}u", errCode);
148 SingletonContainer::Get<PiPReporter>().ReportPiPStartWindow(static_cast<int32_t>(type),
149 pipOption_->GetPipTemplate(), PipConst::FAILED, "Show pip window failed");
150 return errCode;
151 }
152 curState_ = PiPWindowState::STATE_STARTED;
153 SingletonContainer::Get<PiPReporter>().ReportPiPStartWindow(static_cast<int32_t>(type),
154 pipOption_->GetPipTemplate(), PipConst::PIP_SUCCESS, "start pip success");
155 return WMError::WM_OK;
156 }
157
StopPictureInPictureFromClient()158 WMError PictureInPictureControllerBase::StopPictureInPictureFromClient()
159 {
160 if (!window_) {
161 TLOGE(WmsLogTag::WMS_PIP, "window is null");
162 SingletonContainer::Get<PiPReporter>().ReportPiPStopWindow(static_cast<int32_t>(StopPipType::USER_STOP),
163 pipOption_->GetPipTemplate(), PipConst::FAILED, "window is null");
164 return WMError::WM_ERROR_PIP_STATE_ABNORMALLY;
165 }
166 if (curState_ == PiPWindowState::STATE_STOPPING || curState_ == PiPWindowState::STATE_STOPPED ||
167 curState_ == PiPWindowState::STATE_RESTORING) {
168 TLOGE(WmsLogTag::WMS_PIP, "Repeat stop request, curState: %{public}u", curState_);
169 SingletonContainer::Get<PiPReporter>().ReportPiPStopWindow(static_cast<int32_t>(StopPipType::USER_STOP),
170 pipOption_->GetPipTemplate(), PipConst::FAILED, "Repeat stop request");
171 return WMError::WM_ERROR_PIP_REPEAT_OPERATION;
172 }
173 isStoppedFromClient_ = true;
174 WMError res = window_->NotifyPrepareClosePiPWindow();
175 if (res != WMError::WM_OK) {
176 SingletonContainer::Get<PiPReporter>().ReportPiPStopWindow(static_cast<int32_t>(StopPipType::USER_STOP),
177 pipOption_->GetPipTemplate(), PipConst::FAILED, "window destroy failed");
178 return WMError::WM_ERROR_PIP_DESTROY_FAILED;
179 }
180 curState_ = PiPWindowState::STATE_STOPPING;
181 return res;
182 }
183
StopPictureInPicture(bool destroyWindow,StopPipType stopPipType,bool withAnim)184 WMError PictureInPictureControllerBase::StopPictureInPicture(bool destroyWindow, StopPipType stopPipType, bool withAnim)
185 {
186 TLOGI(WmsLogTag::WMS_PIP, "destroyWindow: %{public}u anim: %{public}d", destroyWindow, withAnim);
187 if ((!isStoppedFromClient_ && curState_ == PiPWindowState::STATE_STOPPING) ||
188 curState_ == PiPWindowState::STATE_STOPPED) {
189 TLOGE(WmsLogTag::WMS_PIP, "Repeat stop request, curState: %{public}u", curState_);
190 SingletonContainer::Get<PiPReporter>().ReportPiPStopWindow(static_cast<int32_t>(stopPipType),
191 pipOption_->GetPipTemplate(), PipConst::FAILED, "Repeat stop request");
192 return WMError::WM_ERROR_PIP_REPEAT_OPERATION;
193 }
194 if (window_ == nullptr) {
195 TLOGE(WmsLogTag::WMS_PIP, "window is nullptr when stop pip");
196 SingletonContainer::Get<PiPReporter>().ReportPiPStopWindow(static_cast<int32_t>(stopPipType),
197 pipOption_->GetPipTemplate(), PipConst::FAILED, "window_ is nullptr");
198 return WMError::WM_ERROR_PIP_STATE_ABNORMALLY;
199 }
200 curState_ = PiPWindowState::STATE_STOPPING;
201 for (auto& listener : pipLifeCycleListeners_) {
202 if (listener == nullptr) {
203 TLOGE(WmsLogTag::WMS_PIP, "one lifecycle listener is nullptr");
204 continue;
205 }
206 listener->OnPreparePictureInPictureStop();
207 listener->OnPreparePictureInPictureStop(controllerId_);
208 }
209 if (!destroyWindow) {
210 ResetExtController();
211 curState_ = PiPWindowState::STATE_STOPPED;
212 for (auto& listener : pipLifeCycleListeners_) {
213 if (listener == nullptr) {
214 TLOGE(WmsLogTag::WMS_PIP, "one lifecycle listener is nullptr");
215 continue;
216 }
217 listener->OnPictureInPictureStop();
218 listener->OnPictureInPictureStop(controllerId_);
219 }
220 PictureInPictureManager::RemoveActiveController(weakRef_);
221 PictureInPictureManager::RemovePipControllerInfo(window_->GetWindowId());
222 return WMError::WM_OK;
223 }
224 return StopPictureInPictureInner(stopPipType, withAnim);
225 }
226
StopPictureInPictureInner(StopPipType stopType,bool withAnim)227 WMError PictureInPictureControllerBase::StopPictureInPictureInner(StopPipType stopType, bool withAnim)
228 {
229 uint32_t templateType = 0;
230 if (pipOption_ != nullptr) {
231 templateType = pipOption_->GetPipTemplate();
232 }
233 if (window_ == nullptr) {
234 TLOGE(WmsLogTag::WMS_PIP, "window is nullptr in stop pip inner");
235 SingletonContainer::Get<PiPReporter>().ReportPiPStopWindow(static_cast<int32_t>(stopType),
236 templateType, PipConst::FAILED, "pipController is null");
237 return WMError::WM_ERROR_PIP_INTERNAL_ERROR;
238 }
239 {
240 AutoRSSyncTransaction syncTrans(window_->GetRSUIContext(), false);
241 ResetExtController();
242 if (!withAnim) {
243 TLOGI(WmsLogTag::WMS_PIP, "DestroyPictureInPictureWindow without animation");
244 DestroyPictureInPictureWindow();
245 }
246 }
247 SingletonContainer::Get<PiPReporter>().ReportPiPStopWindow(static_cast<int32_t>(stopType),
248 templateType, PipConst::PIP_SUCCESS, "pip window stop success");
249 return WMError::WM_OK;
250 }
251
DestroyPictureInPictureWindow()252 WMError PictureInPictureControllerBase::DestroyPictureInPictureWindow()
253 {
254 TLOGI(WmsLogTag::WMS_PIP, "called");
255 if (window_ == nullptr) {
256 TLOGE(WmsLogTag::WMS_PIP, "window is nullptr when destroy pip");
257 return WMError::WM_ERROR_PIP_INTERNAL_ERROR;
258 }
259 WmErrorCode ret = WM_JS_TO_ERROR_CODE_MAP.at(window_->Destroy());
260 if (ret != WmErrorCode::WM_OK) {
261 curState_ = PiPWindowState::STATE_UNDEFINED;
262 TLOGE(WmsLogTag::WMS_PIP, "window destroy failed, err:%{public}u", ret);
263 for (auto& listener : pipLifeCycleListeners_) {
264 if (listener == nullptr) {
265 TLOGE(WmsLogTag::WMS_PIP, "one lifecycle listener is nullptr");
266 continue;
267 }
268 listener->OnPictureInPictureOperationError(static_cast<int32_t>(ret));
269 listener->OnPictureInPictureOperationError(controllerId_, static_cast<int32_t>(ret));
270 }
271 return WMError::WM_ERROR_PIP_DESTROY_FAILED;
272 }
273
274 for (auto& listener : pipLifeCycleListeners_) {
275 if (listener == nullptr) {
276 TLOGE(WmsLogTag::WMS_PIP, "one lifecycle listener is nullptr");
277 continue;
278 }
279 listener->OnPictureInPictureStop();
280 listener->OnPictureInPictureStop(controllerId_);
281 }
282 curState_ = PiPWindowState::STATE_STOPPED;
283 std::string navId = pipOption_ == nullptr ? "" : pipOption_->GetNavigationId();
284 if (!navId.empty() && mainWindow_ && !IsTypeNodeEnabled()) {
285 auto navController = NavigationController::GetNavigationController(mainWindow_->GetUIContent(), navId);
286 if (navController) {
287 navController->DeletePIPMode(handleId_);
288 TLOGI(WmsLogTag::WMS_PIP, "Delete pip mode id: %{public}d", handleId_);
289 }
290 }
291 if (mainWindow_ != nullptr) {
292 mainWindow_->UnregisterLifeCycleListener(mainWindowLifeCycleListener_);
293 }
294 mainWindowLifeCycleListener_ = nullptr;
295 PictureInPictureManager::RemovePipControllerInfo(window_->GetWindowId());
296 window_ = nullptr;
297 PictureInPictureManager::RemoveActiveController(this);
298 return WMError::WM_OK;
299 }
300
GetPipWindow() const301 sptr<Window> PictureInPictureControllerBase::GetPipWindow() const
302 {
303 return window_;
304 }
305
GetMainWindowId() const306 uint32_t PictureInPictureControllerBase::GetMainWindowId() const
307 {
308 return mainWindowId_;
309 }
310
SetPipWindow(sptr<Window> window)311 void PictureInPictureControllerBase::SetPipWindow(sptr<Window> window)
312 {
313 window_ = window;
314 }
315
GetControllerState() const316 PiPWindowState PictureInPictureControllerBase::GetControllerState() const
317 {
318 return curState_;
319 }
320
UpdatePiPControlStatus(PiPControlType controlType,PiPControlStatus status)321 void PictureInPictureControllerBase::UpdatePiPControlStatus(PiPControlType controlType, PiPControlStatus status)
322 {
323 TLOGI(WmsLogTag::WMS_PIP, "controlType:%{public}u, status:%{public}d", controlType, status);
324 if (static_cast<int32_t>(status) < -1) {
325 pipOption_->SetPiPControlEnabled(controlType, status);
326 } else {
327 pipOption_->SetPiPControlStatus(controlType, status);
328 }
329 if (window_ == nullptr) {
330 TLOGE(WmsLogTag::WMS_PIP, "pipWindow not exist");
331 return;
332 }
333 window_->UpdatePiPControlStatus(controlType, status);
334 }
335
IsContentSizeChanged(float width,float height,float posX,float posY)336 bool PictureInPictureControllerBase::IsContentSizeChanged(float width, float height, float posX, float posY)
337 {
338 return windowRect_.width_ != static_cast<uint32_t>(width) ||
339 windowRect_.height_ != static_cast<uint32_t>(height) ||
340 windowRect_.posX_ != static_cast<int32_t>(posX) || windowRect_.posY_ != static_cast<int32_t>(posY);
341 }
342
AfterDestroyed()343 void PictureInPictureControllerBase::WindowLifeCycleListener::AfterDestroyed()
344 {
345 TLOGI(WmsLogTag::WMS_PIP, "stop picture_in_picture when attached window destroy");
346 PictureInPictureManager::DoClose(true, true);
347 }
348
DoActionEvent(const std::string & actionName,int32_t status)349 void PictureInPictureControllerBase::DoActionEvent(const std::string& actionName, int32_t status)
350 {
351 TLOGI(WmsLogTag::WMS_PIP, "actionName: %{public}s", actionName.c_str());
352 SingletonContainer::Get<PiPReporter>().ReportPiPActionEvent(pipOption_->GetPipTemplate(), actionName);
353 for (auto& listener : pipActionObservers_) {
354 if (listener == nullptr) {
355 TLOGE(WmsLogTag::WMS_PIP, "one action observer is nullptr");
356 continue;
357 }
358 listener->OnActionEvent(actionName, status);
359 }
360 if (CONTROL_TYPE_MAP.find(actionName) != CONTROL_TYPE_MAP.end()) {
361 pipOption_->SetPiPControlStatus(CONTROL_TYPE_MAP.at(actionName), static_cast<PiPControlStatus>(status));
362 }
363 }
364
DoControlEvent(PiPControlType controlType,PiPControlStatus status)365 void PictureInPictureControllerBase::DoControlEvent(PiPControlType controlType, PiPControlStatus status)
366 {
367 TLOGI(WmsLogTag::WMS_PIP, "controlType:%{public}u, enabled:%{public}d", controlType, status);
368 if (pipOption_ == nullptr) {
369 TLOGE(WmsLogTag::WMS_PIP, "pipOption_ is nullptr");
370 return;
371 }
372 SingletonContainer::Get<PiPReporter>().ReportPiPControlEvent(pipOption_->GetPipTemplate(), controlType);
373 for (auto& listener : pipControlObservers_) {
374 if (listener == nullptr) {
375 TLOGE(WmsLogTag::WMS_PIP, "one control observer is nullptr");
376 continue;
377 }
378 listener->OnControlEvent(controlType, status);
379 listener->OnControlEvent(controllerId_, controlType, status);
380 }
381 pipOption_->SetPiPControlStatus(controlType, status);
382 }
383
PreRestorePictureInPicture()384 void PictureInPictureControllerBase::PreRestorePictureInPicture()
385 {
386 TLOGI(WmsLogTag::WMS_PIP, "called");
387 curState_ = PiPWindowState::STATE_RESTORING;
388 for (auto& listener : pipLifeCycleListeners_) {
389 if (listener == nullptr) {
390 TLOGE(WmsLogTag::WMS_PIP, "one lifecycle listener is nullptr");
391 continue;
392 }
393 listener->OnRestoreUserInterface();
394 listener->OnRestoreUserInterface(controllerId_);
395 }
396 }
397
LocateSource()398 void PictureInPictureControllerBase::LocateSource()
399 {
400 TLOGI(WmsLogTag::WMS_PIP, "in");
401 if (window_ == nullptr) {
402 TLOGE(WmsLogTag::WMS_PIP, "window is nullptr");
403 return;
404 }
405 window_->SetTransparent(true);
406 UpdatePiPSourceRect();
407 }
408
PipSizeChange(double width,double height,double scale)409 void PictureInPictureControllerBase::PipSizeChange(double width, double height, double scale)
410 {
411 PiPWindowSize windowSize;
412 windowSize.width = std::round(width);
413 windowSize.height = std::round(height);
414 windowSize.scale = scale;
415 TLOGI(WmsLogTag::WMS_PIP, "notify size info width: %{public}u, height: %{public}u scale: %{public}f",
416 windowSize.width, windowSize.height, scale);
417 for (auto& listener : pipWindowSizeListeners_) {
418 if (listener == nullptr) {
419 TLOGE(WmsLogTag::WMS_PIP, "one resize listener is nullptr");
420 continue;
421 }
422 listener->OnPipSizeChange(windowSize);
423 listener->OnPipSizeChange(controllerId_, windowSize);
424 }
425 }
426
SetSurfaceId(uint64_t surfaceId)427 void PictureInPictureControllerBase::SetSurfaceId(uint64_t surfaceId)
428 {
429 surfaceId_ = surfaceId;
430 }
431
GetSurfaceId() const432 uint64_t PictureInPictureControllerBase::GetSurfaceId() const
433 {
434 return surfaceId_;
435 }
436
OnPictureInPictureStart()437 void PictureInPictureControllerBase::OnPictureInPictureStart()
438 {
439 for (auto& listener : pipLifeCycleListeners_) {
440 if (listener == nullptr) {
441 TLOGE(WmsLogTag::WMS_PIP, "one lifecycle listener is nullptr");
442 continue;
443 }
444 listener->OnPictureInPictureStart();
445 listener->OnPictureInPictureStart(controllerId_);
446 }
447 }
448
RegisterPiPLifecycle(const sptr<IPiPLifeCycle> & listener)449 WMError PictureInPictureControllerBase::RegisterPiPLifecycle(const sptr<IPiPLifeCycle>& listener)
450 {
451 return RegisterListener(pipLifeCycleListeners_, listener);
452 }
453
RegisterPiPActionObserver(const sptr<IPiPActionObserver> & listener)454 WMError PictureInPictureControllerBase::RegisterPiPActionObserver(const sptr<IPiPActionObserver>& listener)
455 {
456 return RegisterListener(pipActionObservers_, listener);
457 }
458
RegisterPiPControlObserver(const sptr<IPiPControlObserver> & listener)459 WMError PictureInPictureControllerBase::RegisterPiPControlObserver(const sptr<IPiPControlObserver>& listener)
460 {
461 return RegisterListener(pipControlObservers_, listener);
462 }
463
RegisterPiPWindowSize(const sptr<IPiPWindowSize> & listener)464 WMError PictureInPictureControllerBase::RegisterPiPWindowSize(const sptr<IPiPWindowSize>& listener)
465 {
466 return RegisterListener(pipWindowSizeListeners_, listener);
467 }
468
RegisterPiPTypeNodeChange(const sptr<IPiPTypeNodeObserver> & listener)469 WMError PictureInPictureControllerBase::RegisterPiPTypeNodeChange(const sptr<IPiPTypeNodeObserver>& listener)
470 {
471 return RegisterListener(pipTypeNodeObserver_, listener);
472 }
473
RegisterPiPStart(const sptr<IPiPStartObserver> & listener)474 WMError PictureInPictureControllerBase::RegisterPiPStart(const sptr<IPiPStartObserver>& listener)
475 {
476 return RegisterListener(pipStartListeners_, listener);
477 }
478
UnregisterPiPLifecycle(const sptr<IPiPLifeCycle> & listener)479 WMError PictureInPictureControllerBase::UnregisterPiPLifecycle(const sptr<IPiPLifeCycle>& listener)
480 {
481 return UnregisterListener(pipLifeCycleListeners_, listener);
482 }
483
UnregisterPiPActionObserver(const sptr<IPiPActionObserver> & listener)484 WMError PictureInPictureControllerBase::UnregisterPiPActionObserver(const sptr<IPiPActionObserver>& listener)
485 {
486 return UnregisterListener(pipActionObservers_, listener);
487 }
488
UnregisterPiPControlObserver(const sptr<IPiPControlObserver> & listener)489 WMError PictureInPictureControllerBase::UnregisterPiPControlObserver(const sptr<IPiPControlObserver>& listener)
490 {
491 return UnregisterListener(pipControlObservers_, listener);
492 }
493
UnregisterPiPWindowSize(const sptr<IPiPWindowSize> & listener)494 WMError PictureInPictureControllerBase::UnregisterPiPWindowSize(const sptr<IPiPWindowSize>& listener)
495 {
496 return UnregisterListener(pipWindowSizeListeners_, listener);
497 }
498
UnRegisterPiPTypeNodeChange(const sptr<IPiPTypeNodeObserver> & listener)499 WMError PictureInPictureControllerBase::UnRegisterPiPTypeNodeChange(const sptr<IPiPTypeNodeObserver>& listener)
500 {
501 return UnregisterListener(pipTypeNodeObserver_, listener);
502 }
503
UnregisterPiPStart(const sptr<IPiPStartObserver> & listener)504 WMError PictureInPictureControllerBase::UnregisterPiPStart(const sptr<IPiPStartObserver>& listener)
505 {
506 return UnregisterListener(pipStartListeners_, listener);
507 }
508
UnregisterAllPiPLifecycle()509 void PictureInPictureControllerBase::UnregisterAllPiPLifecycle()
510 {
511 pipLifeCycleListeners_.clear();
512 }
513
UnregisterAllPiPControlObserver()514 void PictureInPictureControllerBase::UnregisterAllPiPControlObserver()
515 {
516 pipControlObservers_.clear();
517 }
518
UnregisterAllPiPWindowSize()519 void PictureInPictureControllerBase::UnregisterAllPiPWindowSize()
520 {
521 pipWindowSizeListeners_.clear();
522 }
523
UnregisterAllPiPStart()524 void PictureInPictureControllerBase::UnregisterAllPiPStart()
525 {
526 pipStartListeners_.clear();
527 }
528
GetPictureInPictureLifecycle() const529 std::vector<sptr<IPiPLifeCycle>> PictureInPictureControllerBase::GetPictureInPictureLifecycle() const
530 {
531 return pipLifeCycleListeners_;
532 }
533
GetPictureInPictureActionObserver() const534 std::vector<sptr<IPiPActionObserver>> PictureInPictureControllerBase::GetPictureInPictureActionObserver() const
535 {
536 return pipActionObservers_;
537 }
538
GetPictureInPictureControlObserver() const539 std::vector<sptr<IPiPControlObserver>> PictureInPictureControllerBase::GetPictureInPictureControlObserver() const
540 {
541 return pipControlObservers_;
542 }
543
GetPictureInPictureSizeObserver() const544 std::vector<sptr<IPiPWindowSize>> PictureInPictureControllerBase::GetPictureInPictureSizeObserver() const
545 {
546 return pipWindowSizeListeners_;
547 }
548
GetPictureInPictureStartObserver() const549 std::vector<sptr<IPiPStartObserver>> PictureInPictureControllerBase::GetPictureInPictureStartObserver() const
550 {
551 return pipStartListeners_;
552 }
553
554 template<typename T>
RegisterListener(std::vector<sptr<T>> & holder,const sptr<T> & listener)555 WMError PictureInPictureControllerBase::RegisterListener(std::vector<sptr<T>>& holder, const sptr<T>& listener)
556 {
557 if (listener == nullptr) {
558 TLOGE(WmsLogTag::WMS_PIP, "listener is nullptr");
559 return WMError::WM_ERROR_NULLPTR;
560 }
561 if (std::find(holder.begin(), holder.end(), listener) != holder.end()) {
562 TLOGE(WmsLogTag::WMS_PIP, "Listener already registered");
563 return WMError::WM_OK;
564 }
565 holder.emplace_back(listener);
566 return WMError::WM_OK;
567 }
568
569 template<typename T>
UnregisterListener(std::vector<sptr<T>> & holder,const sptr<T> & listener)570 WMError PictureInPictureControllerBase::UnregisterListener(std::vector<sptr<T>>& holder, const sptr<T>& listener)
571 {
572 if (listener == nullptr) {
573 TLOGE(WmsLogTag::WMS_PIP, "listener could not be null");
574 return WMError::WM_ERROR_NULLPTR;
575 }
576 holder.erase(std::remove_if(holder.begin(), holder.end(),
577 [listener](const sptr<T>& registeredListener) {
578 return registeredListener == listener;
579 }), holder.end());
580 return WMError::WM_OK;
581 }
582
GetPipPossible(bool & pipPossible)583 void PictureInPictureControllerBase::GetPipPossible(bool& pipPossible)
584 {
585 const std::string multiWindowUIType = system::GetParameter("const.window.multiWindowUIType", "");
586 pipPossible = multiWindowUIType == "HandsetSmartWindow" || multiWindowUIType == "TabletSmartWindow";
587 return;
588 }
589
GetPipEnabled()590 bool PictureInPictureControllerBase::GetPipEnabled()
591 {
592 const std::string multiWindowUIType = system::GetParameter("const.window.multiWindowUIType", "");
593 return multiWindowUIType == "HandsetSmartWindow" || multiWindowUIType == "FreeFormMultiWindow" ||
594 multiWindowUIType == "TabletSmartWindow";
595 }
596
GetPipSettingSwitchStatusEnabled()597 bool PictureInPictureControllerBase::GetPipSettingSwitchStatusEnabled()
598 {
599 const std::string multiWindowUIType = system::GetParameter("const.window.multiWindowUIType", "");
600 return multiWindowUIType == "HandsetSmartWindow" || multiWindowUIType == "TabletSmartWindow";
601 }
602
GetPiPSettingSwitchStatus()603 bool PictureInPictureControllerBase::GetPiPSettingSwitchStatus()
604 {
605 sptr<WindowSessionImpl> windowSessionImpl = WindowSessionImpl::GetWindowWithId(mainWindowId_);
606 if (windowSessionImpl == nullptr) {
607 TLOGE(WmsLogTag::WMS_PIP, "windowId not found.");
608 return false;
609 }
610 bool switchStatus = false;
611 WMError errcode = windowSessionImpl->GetPiPSettingSwitchStatus(switchStatus);
612 if (errcode != WMError::WM_OK) {
613 TLOGE(WmsLogTag::WMS_PIP, "get switch error.");
614 return false;
615 }
616 TLOGI(WmsLogTag::WMS_PIP, "switchStatus: %{public}d", switchStatus);
617 return switchStatus;
618 }
619 // LCOV_EXCL_STOP
620 } // namespace Rosen
621 } // namespace OHOS