/* * Copyright (c) 2023-2023 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "picture_in_picture_manager.h" #include "picture_in_picture_controller.h" #include "window_manager_hilog.h" #include "window_scene_session_impl.h" #include "scene_board_judgement.h" namespace OHOS { namespace Rosen { namespace { const std::string ACTION_CLOSE = "close"; const std::string ACTION_PRE_RESTORE = "pre_restore"; const std::string ACTION_RESTORE = "restore"; const std::string ACTION_DESTROY = "destroy"; const std::string ACTION_PREPARE_SOURCE = "prepare_source"; const std::string ACTION_LOCATE_SOURCE = "locate_source"; const std::string ACTION_BACKGROUND_AUTO_START = "background_auto_start"; const std::map> PIP_ACTION_MAP { {ACTION_CLOSE, PictureInPictureManager::DoActionClose}, {ACTION_PRE_RESTORE, PictureInPictureManager::DoPreRestore}, {ACTION_RESTORE, PictureInPictureManager::DoRestore}, {ACTION_PREPARE_SOURCE, PictureInPictureManager::DoPrepareSource}, {ACTION_LOCATE_SOURCE, PictureInPictureManager::DoLocateSource}, {ACTION_DESTROY, PictureInPictureManager::DoDestroy}, {ACTION_BACKGROUND_AUTO_START, PictureInPictureManager::AutoStartPipWindow}, }; } sptr PictureInPictureManager::activeController_ = nullptr; wptr PictureInPictureManager::autoStartController_ = nullptr; std::map> PictureInPictureManager::autoStartControllerMap_ = {}; std::map> PictureInPictureManager::windowToControllerMap_ = {}; std::shared_ptr PictureInPictureManager::innerCallbackRef_ = nullptr; PictureInPictureManager::PictureInPictureManager() { } PictureInPictureManager::~PictureInPictureManager() { } bool PictureInPictureManager::IsSupportPiP() { return SceneBoardJudgement::IsSceneBoardEnabled(); } bool PictureInPictureManager::ShouldAbortPipStart() { return activeController_ != nullptr && activeController_->GetControllerState() == PiPWindowState::STATE_STARTING; } void PictureInPictureManager::PutPipControllerInfo(int32_t windowId, sptr pipController) { TLOGI(WmsLogTag::WMS_PIP, "windowId %{public}u", windowId); windowToControllerMap_.insert(std::make_pair(windowId, pipController)); } void PictureInPictureManager::RemovePipControllerInfo(int32_t windowId) { TLOGI(WmsLogTag::WMS_PIP, "windowId %{public}u", windowId); windowToControllerMap_.erase(windowId); } sptr PictureInPictureManager::GetPipControllerInfo(int32_t windowId) { if (windowToControllerMap_.empty() || windowToControllerMap_.find(windowId) == windowToControllerMap_.end()) { TLOGE(WmsLogTag::WMS_PIP, "error, windowId: %{public}d not registered!", windowId); return nullptr; } TLOGI(WmsLogTag::WMS_PIP, "windowId: %{public}d", windowId); return windowToControllerMap_[windowId]; } bool PictureInPictureManager::HasActiveController() { return activeController_ != nullptr; } bool PictureInPictureManager::IsActiveController(wptr pipController) { if (!HasActiveController()) { return false; } bool res = pipController.GetRefPtr() == activeController_.GetRefPtr(); TLOGD(WmsLogTag::WMS_PIP, "res: %{public}u", res); return res; } void PictureInPictureManager::SetActiveController(sptr pipController) { TLOGD(WmsLogTag::WMS_PIP, "in"); activeController_ = pipController; } void PictureInPictureManager::RemoveActiveController(wptr pipController) { TLOGD(WmsLogTag::WMS_PIP, "in"); if (HasActiveController() && pipController.GetRefPtr() == activeController_.GetRefPtr()) { activeController_ = nullptr; } } void PictureInPictureManager::AttachAutoStartController(int32_t handleId, wptr pipController) { TLOGD(WmsLogTag::WMS_PIP, "handleId: %{public}u", handleId); if (pipController == nullptr) { return; } autoStartController_ = pipController; autoStartControllerMap_[handleId] = pipController; } void PictureInPictureManager::DetachAutoStartController(int32_t handleId, wptr pipController) { TLOGI(WmsLogTag::WMS_PIP, "handleId: %{public}u", handleId); if (autoStartController_ == nullptr) { TLOGW(WmsLogTag::WMS_PIP, "detach failed as none autoStartController exist"); return; } if (pipController != nullptr && pipController.GetRefPtr() != autoStartController_.GetRefPtr()) { TLOGW(WmsLogTag::WMS_PIP, "not same pip controller"); return; } autoStartController_ = nullptr; autoStartControllerMap_.erase(handleId); } bool PictureInPictureManager::IsAttachedToSameWindow(uint32_t windowId) { TLOGI(WmsLogTag::WMS_PIP, "windowId: %{public}u", windowId); if (!HasActiveController()) { return false; } return activeController_->GetMainWindowId() == windowId; } sptr PictureInPictureManager::GetCurrentWindow() { if (!HasActiveController()) { return nullptr; } return activeController_->GetPipWindow(); } void PictureInPictureManager::DoPreRestore() { TLOGI(WmsLogTag::WMS_PIP, "in"); if (!HasActiveController()) { return; } activeController_->PreRestorePictureInPicture(); } void PictureInPictureManager::DoRestore() { TLOGI(WmsLogTag::WMS_PIP, "in"); if (!HasActiveController()) { return; } activeController_->RestorePictureInPictureWindow(); } void PictureInPictureManager::DoPrepareSource() { TLOGI(WmsLogTag::WMS_PIP, "in"); if (!HasActiveController()) { return; } activeController_->PrepareSource(); } void PictureInPictureManager::DoLocateSource() { TLOGI(WmsLogTag::WMS_PIP, "in"); if (!HasActiveController()) { return; } activeController_->LocateSource(); } void PictureInPictureManager::DoClose(bool destroyWindow, bool byPriority) { TLOGI(WmsLogTag::WMS_PIP, "destroyWindow:%{public}d, byPriority:%{public}d", destroyWindow, byPriority); if (!HasActiveController()) { return; } StopPipType currentStopType = StopPipType::NULL_STOP; if (!byPriority) { currentStopType = StopPipType::USER_STOP; } else { currentStopType = StopPipType::OTHER_PACKAGE_STOP; } activeController_->StopPictureInPicture(destroyWindow, currentStopType, !byPriority); } void PictureInPictureManager::DoActionClose() { TLOGI(WmsLogTag::WMS_PIP, "in"); DoClose(true, false); } void PictureInPictureManager::DoDestroy() { TLOGI(WmsLogTag::WMS_PIP, "in"); if (!HasActiveController()) { return; } activeController_->DestroyPictureInPictureWindow(); } void PictureInPictureManager::DoActionEvent(const std::string& actionName, int32_t status) { TLOGI(WmsLogTag::WMS_PIP, "in"); auto func = PIP_ACTION_MAP.find(actionName); if (func == PIP_ACTION_MAP.end()) { TLOGI(WmsLogTag::WMS_PIP, "through pass"); if (auto controller = GetActiveController()) { controller->DoActionEvent(actionName, status); } return; } func->second(); } void PictureInPictureManager::DoControlEvent(PiPControlType controlType, PiPControlStatus status) { TLOGI(WmsLogTag::WMS_PIP, "controlType:%{public}u, enabled:%{public}d", controlType, status); if (auto controller = GetActiveController()) { controller->DoControlEvent(controlType, status); } } void PictureInPictureManager::AutoStartPipWindow() { TLOGI(WmsLogTag::WMS_PIP, "in"); if (autoStartController_ == nullptr) { TLOGE(WmsLogTag::WMS_PIP, "autoStartController is null"); return; } if (autoStartController_->GetPiPNavigationId().empty() || autoStartController_->IsTypeNodeEnabled()) { TLOGI(WmsLogTag::WMS_PIP, "No use navigation for auto start"); autoStartController_->StartPictureInPicture(StartPipType::AUTO_START); return; } sptr mainWindow = WindowSceneSessionImpl::GetMainWindowWithId( autoStartController_->GetMainWindowId()); if (mainWindow) { auto navController = NavigationController::GetNavigationController(mainWindow->GetUIContent(), autoStartController_->GetPiPNavigationId()); if (!navController) { TLOGE(WmsLogTag::WMS_PIP, "navController is nullptr"); return; } if (navController->IsNavDestinationInTopStack()) { int handleId = navController->GetTopHandle(); if (autoStartControllerMap_.empty() || autoStartControllerMap_.find(handleId) == autoStartControllerMap_.end()) { TLOGE(WmsLogTag::WMS_PIP, "GetNavController info error, %{public}d not registered", handleId); return; } auto pipController = autoStartControllerMap_[handleId]; pipController->StartPictureInPicture(StartPipType::AUTO_START); } else { TLOGE(WmsLogTag::WMS_PIP, "Top is not navDestination"); } } } } }