• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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