1e0dac50fSopenharmony_ci/*
2e0dac50fSopenharmony_ci * Copyright (c) 2023-2023 Huawei Device Co., Ltd.
3e0dac50fSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4e0dac50fSopenharmony_ci * you may not use this file except in compliance with the License.
5e0dac50fSopenharmony_ci * You may obtain a copy of the License at
6e0dac50fSopenharmony_ci *
7e0dac50fSopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
8e0dac50fSopenharmony_ci *
9e0dac50fSopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10e0dac50fSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11e0dac50fSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12e0dac50fSopenharmony_ci * See the License for the specific language governing permissions and
13e0dac50fSopenharmony_ci * limitations under the License.
14e0dac50fSopenharmony_ci */
15e0dac50fSopenharmony_ci
16e0dac50fSopenharmony_ci#include "picture_in_picture_manager.h"
17e0dac50fSopenharmony_ci
18e0dac50fSopenharmony_ci#include <refbase.h>
19e0dac50fSopenharmony_ci#include "picture_in_picture_controller.h"
20e0dac50fSopenharmony_ci#include "window.h"
21e0dac50fSopenharmony_ci#include "window_manager_hilog.h"
22e0dac50fSopenharmony_ci#include "window_scene_session_impl.h"
23e0dac50fSopenharmony_ci#include "wm_common.h"
24e0dac50fSopenharmony_ci#include "scene_board_judgement.h"
25e0dac50fSopenharmony_ci
26e0dac50fSopenharmony_cinamespace OHOS {
27e0dac50fSopenharmony_cinamespace Rosen {
28e0dac50fSopenharmony_cinamespace {
29e0dac50fSopenharmony_ciconst std::string ACTION_CLOSE = "close";
30e0dac50fSopenharmony_ciconst std::string ACTION_PRE_RESTORE = "pre_restore";
31e0dac50fSopenharmony_ciconst std::string ACTION_RESTORE = "restore";
32e0dac50fSopenharmony_ciconst std::string ACTION_DESTROY = "destroy";
33e0dac50fSopenharmony_ciconst std::string ACTION_PREPARE_SOURCE = "prepare_source";
34e0dac50fSopenharmony_ciconst std::string ACTION_LOCATE_SOURCE = "locate_source";
35e0dac50fSopenharmony_ciconst std::string ACTION_BACKGROUND_AUTO_START = "background_auto_start";
36e0dac50fSopenharmony_ci
37e0dac50fSopenharmony_ciconst std::map<std::string, std::function<void()>> PIP_ACTION_MAP {
38e0dac50fSopenharmony_ci    {ACTION_CLOSE, PictureInPictureManager::DoActionClose},
39e0dac50fSopenharmony_ci    {ACTION_PRE_RESTORE, PictureInPictureManager::DoPreRestore},
40e0dac50fSopenharmony_ci    {ACTION_RESTORE, PictureInPictureManager::DoRestore},
41e0dac50fSopenharmony_ci    {ACTION_PREPARE_SOURCE, PictureInPictureManager::DoPrepareSource},
42e0dac50fSopenharmony_ci    {ACTION_LOCATE_SOURCE, PictureInPictureManager::DoLocateSource},
43e0dac50fSopenharmony_ci    {ACTION_DESTROY, PictureInPictureManager::DoDestroy},
44e0dac50fSopenharmony_ci    {ACTION_BACKGROUND_AUTO_START, PictureInPictureManager::AutoStartPipWindow},
45e0dac50fSopenharmony_ci};
46e0dac50fSopenharmony_ci}
47e0dac50fSopenharmony_ci
48e0dac50fSopenharmony_cisptr<PictureInPictureController> PictureInPictureManager::activeController_ = nullptr;
49e0dac50fSopenharmony_ciwptr<PictureInPictureController> PictureInPictureManager::autoStartController_ = nullptr;
50e0dac50fSopenharmony_cistd::map<int32_t, wptr<PictureInPictureController>> PictureInPictureManager::autoStartControllerMap_ = {};
51e0dac50fSopenharmony_cistd::map<int32_t, sptr<PictureInPictureController>> PictureInPictureManager::windowToControllerMap_ = {};
52e0dac50fSopenharmony_cistd::shared_ptr<NativeReference> PictureInPictureManager::innerCallbackRef_ = nullptr;
53e0dac50fSopenharmony_ci
54e0dac50fSopenharmony_ciPictureInPictureManager::PictureInPictureManager()
55e0dac50fSopenharmony_ci{
56e0dac50fSopenharmony_ci}
57e0dac50fSopenharmony_ci
58e0dac50fSopenharmony_ciPictureInPictureManager::~PictureInPictureManager()
59e0dac50fSopenharmony_ci{
60e0dac50fSopenharmony_ci}
61e0dac50fSopenharmony_ci
62e0dac50fSopenharmony_cibool PictureInPictureManager::IsSupportPiP()
63e0dac50fSopenharmony_ci{
64e0dac50fSopenharmony_ci    return SceneBoardJudgement::IsSceneBoardEnabled();
65e0dac50fSopenharmony_ci}
66e0dac50fSopenharmony_ci
67e0dac50fSopenharmony_cibool PictureInPictureManager::ShouldAbortPipStart()
68e0dac50fSopenharmony_ci{
69e0dac50fSopenharmony_ci    return activeController_ != nullptr && activeController_->GetControllerState() == PiPWindowState::STATE_STARTING;
70e0dac50fSopenharmony_ci}
71e0dac50fSopenharmony_ci
72e0dac50fSopenharmony_civoid PictureInPictureManager::PutPipControllerInfo(int32_t windowId, sptr<PictureInPictureController> pipController)
73e0dac50fSopenharmony_ci{
74e0dac50fSopenharmony_ci    TLOGI(WmsLogTag::WMS_PIP, "windowId %{public}u", windowId);
75e0dac50fSopenharmony_ci    windowToControllerMap_.insert(std::make_pair(windowId, pipController));
76e0dac50fSopenharmony_ci}
77e0dac50fSopenharmony_ci
78e0dac50fSopenharmony_civoid PictureInPictureManager::RemovePipControllerInfo(int32_t windowId)
79e0dac50fSopenharmony_ci{
80e0dac50fSopenharmony_ci    TLOGI(WmsLogTag::WMS_PIP, "windowId %{public}u", windowId);
81e0dac50fSopenharmony_ci    windowToControllerMap_.erase(windowId);
82e0dac50fSopenharmony_ci}
83e0dac50fSopenharmony_ci
84e0dac50fSopenharmony_cisptr<PictureInPictureController> PictureInPictureManager::GetPipControllerInfo(int32_t windowId)
85e0dac50fSopenharmony_ci{
86e0dac50fSopenharmony_ci    if (windowToControllerMap_.empty() || windowToControllerMap_.find(windowId) == windowToControllerMap_.end()) {
87e0dac50fSopenharmony_ci        TLOGE(WmsLogTag::WMS_PIP, "error, windowId: %{public}d not registered!", windowId);
88e0dac50fSopenharmony_ci        return nullptr;
89e0dac50fSopenharmony_ci    }
90e0dac50fSopenharmony_ci    TLOGI(WmsLogTag::WMS_PIP, "windowId: %{public}d", windowId);
91e0dac50fSopenharmony_ci    return windowToControllerMap_[windowId];
92e0dac50fSopenharmony_ci}
93e0dac50fSopenharmony_ci
94e0dac50fSopenharmony_cibool PictureInPictureManager::HasActiveController()
95e0dac50fSopenharmony_ci{
96e0dac50fSopenharmony_ci    return activeController_ != nullptr;
97e0dac50fSopenharmony_ci}
98e0dac50fSopenharmony_ci
99e0dac50fSopenharmony_cibool PictureInPictureManager::IsActiveController(wptr<PictureInPictureController> pipController)
100e0dac50fSopenharmony_ci{
101e0dac50fSopenharmony_ci    if (!HasActiveController()) {
102e0dac50fSopenharmony_ci        return false;
103e0dac50fSopenharmony_ci    }
104e0dac50fSopenharmony_ci    bool res = pipController.GetRefPtr() == activeController_.GetRefPtr();
105e0dac50fSopenharmony_ci    TLOGD(WmsLogTag::WMS_PIP, "res: %{public}u", res);
106e0dac50fSopenharmony_ci    return res;
107e0dac50fSopenharmony_ci}
108e0dac50fSopenharmony_ci
109e0dac50fSopenharmony_civoid PictureInPictureManager::SetActiveController(sptr<PictureInPictureController> pipController)
110e0dac50fSopenharmony_ci{
111e0dac50fSopenharmony_ci    TLOGD(WmsLogTag::WMS_PIP, "in");
112e0dac50fSopenharmony_ci    activeController_ = pipController;
113e0dac50fSopenharmony_ci}
114e0dac50fSopenharmony_ci
115e0dac50fSopenharmony_civoid PictureInPictureManager::RemoveActiveController(wptr<PictureInPictureController> pipController)
116e0dac50fSopenharmony_ci{
117e0dac50fSopenharmony_ci    TLOGD(WmsLogTag::WMS_PIP, "in");
118e0dac50fSopenharmony_ci    if (HasActiveController() && pipController.GetRefPtr() == activeController_.GetRefPtr()) {
119e0dac50fSopenharmony_ci        activeController_ = nullptr;
120e0dac50fSopenharmony_ci    }
121e0dac50fSopenharmony_ci}
122e0dac50fSopenharmony_ci
123e0dac50fSopenharmony_civoid PictureInPictureManager::AttachAutoStartController(int32_t handleId,
124e0dac50fSopenharmony_ci    wptr<PictureInPictureController> pipController)
125e0dac50fSopenharmony_ci{
126e0dac50fSopenharmony_ci    TLOGD(WmsLogTag::WMS_PIP, "handleId: %{public}u", handleId);
127e0dac50fSopenharmony_ci    if (pipController == nullptr) {
128e0dac50fSopenharmony_ci        return;
129e0dac50fSopenharmony_ci    }
130e0dac50fSopenharmony_ci    autoStartController_ = pipController;
131e0dac50fSopenharmony_ci    autoStartControllerMap_[handleId] = pipController;
132e0dac50fSopenharmony_ci}
133e0dac50fSopenharmony_ci
134e0dac50fSopenharmony_civoid PictureInPictureManager::DetachAutoStartController(int32_t handleId,
135e0dac50fSopenharmony_ci    wptr<PictureInPictureController> pipController)
136e0dac50fSopenharmony_ci{
137e0dac50fSopenharmony_ci    TLOGD(WmsLogTag::WMS_PIP, "handleId: %{public}u", handleId);
138e0dac50fSopenharmony_ci    autoStartControllerMap_.erase(handleId);
139e0dac50fSopenharmony_ci    if (autoStartController_ == nullptr) {
140e0dac50fSopenharmony_ci        return;
141e0dac50fSopenharmony_ci    }
142e0dac50fSopenharmony_ci    if (pipController != nullptr &&
143e0dac50fSopenharmony_ci        pipController.GetRefPtr() != autoStartController_.GetRefPtr()) {
144e0dac50fSopenharmony_ci        TLOGE(WmsLogTag::WMS_PIP, "not same pip controller or no active pip controller");
145e0dac50fSopenharmony_ci        return;
146e0dac50fSopenharmony_ci    }
147e0dac50fSopenharmony_ci    autoStartController_ = nullptr;
148e0dac50fSopenharmony_ci}
149e0dac50fSopenharmony_ci
150e0dac50fSopenharmony_cibool PictureInPictureManager::IsAttachedToSameWindow(uint32_t windowId)
151e0dac50fSopenharmony_ci{
152e0dac50fSopenharmony_ci    TLOGI(WmsLogTag::WMS_PIP, "windowId: %{public}u", windowId);
153e0dac50fSopenharmony_ci    if (!HasActiveController()) {
154e0dac50fSopenharmony_ci        return false;
155e0dac50fSopenharmony_ci    }
156e0dac50fSopenharmony_ci    return activeController_->GetMainWindowId() == windowId;
157e0dac50fSopenharmony_ci}
158e0dac50fSopenharmony_ci
159e0dac50fSopenharmony_cisptr<Window> PictureInPictureManager::GetCurrentWindow()
160e0dac50fSopenharmony_ci{
161e0dac50fSopenharmony_ci    if (!HasActiveController()) {
162e0dac50fSopenharmony_ci        return nullptr;
163e0dac50fSopenharmony_ci    }
164e0dac50fSopenharmony_ci    return activeController_->GetPipWindow();
165e0dac50fSopenharmony_ci}
166e0dac50fSopenharmony_ci
167e0dac50fSopenharmony_civoid PictureInPictureManager::DoPreRestore()
168e0dac50fSopenharmony_ci{
169e0dac50fSopenharmony_ci    TLOGI(WmsLogTag::WMS_PIP, "in");
170e0dac50fSopenharmony_ci    if (!HasActiveController()) {
171e0dac50fSopenharmony_ci        return;
172e0dac50fSopenharmony_ci    }
173e0dac50fSopenharmony_ci    activeController_->PreRestorePictureInPicture();
174e0dac50fSopenharmony_ci}
175e0dac50fSopenharmony_ci
176e0dac50fSopenharmony_civoid PictureInPictureManager::DoRestore()
177e0dac50fSopenharmony_ci{
178e0dac50fSopenharmony_ci    TLOGI(WmsLogTag::WMS_PIP, "in");
179e0dac50fSopenharmony_ci    if (!HasActiveController()) {
180e0dac50fSopenharmony_ci        return;
181e0dac50fSopenharmony_ci    }
182e0dac50fSopenharmony_ci    activeController_->RestorePictureInPictureWindow();
183e0dac50fSopenharmony_ci}
184e0dac50fSopenharmony_ci
185e0dac50fSopenharmony_civoid PictureInPictureManager::DoPrepareSource()
186e0dac50fSopenharmony_ci{
187e0dac50fSopenharmony_ci    TLOGI(WmsLogTag::WMS_PIP, "in");
188e0dac50fSopenharmony_ci    if (!HasActiveController()) {
189e0dac50fSopenharmony_ci        return;
190e0dac50fSopenharmony_ci    }
191e0dac50fSopenharmony_ci    activeController_->PrepareSource();
192e0dac50fSopenharmony_ci}
193e0dac50fSopenharmony_ci
194e0dac50fSopenharmony_civoid PictureInPictureManager::DoLocateSource()
195e0dac50fSopenharmony_ci{
196e0dac50fSopenharmony_ci    TLOGI(WmsLogTag::WMS_PIP, "in");
197e0dac50fSopenharmony_ci    if (!HasActiveController()) {
198e0dac50fSopenharmony_ci        return;
199e0dac50fSopenharmony_ci    }
200e0dac50fSopenharmony_ci    activeController_->LocateSource();
201e0dac50fSopenharmony_ci}
202e0dac50fSopenharmony_ci
203e0dac50fSopenharmony_civoid PictureInPictureManager::DoClose(bool destroyWindow, bool byPriority)
204e0dac50fSopenharmony_ci{
205e0dac50fSopenharmony_ci    TLOGI(WmsLogTag::WMS_PIP, "in");
206e0dac50fSopenharmony_ci    if (!HasActiveController()) {
207e0dac50fSopenharmony_ci        return;
208e0dac50fSopenharmony_ci    }
209e0dac50fSopenharmony_ci    StopPipType currentStopType = StopPipType::NULL_STOP;
210e0dac50fSopenharmony_ci    if (!byPriority) {
211e0dac50fSopenharmony_ci        currentStopType = StopPipType::USER_STOP;
212e0dac50fSopenharmony_ci    } else {
213e0dac50fSopenharmony_ci        currentStopType = StopPipType::OTHER_PACKAGE_STOP;
214e0dac50fSopenharmony_ci    }
215e0dac50fSopenharmony_ci    activeController_->StopPictureInPicture(destroyWindow, currentStopType, !byPriority);
216e0dac50fSopenharmony_ci}
217e0dac50fSopenharmony_ci
218e0dac50fSopenharmony_civoid PictureInPictureManager::DoActionClose()
219e0dac50fSopenharmony_ci{
220e0dac50fSopenharmony_ci    TLOGI(WmsLogTag::WMS_PIP, "in");
221e0dac50fSopenharmony_ci    DoClose(true, false);
222e0dac50fSopenharmony_ci}
223e0dac50fSopenharmony_ci
224e0dac50fSopenharmony_civoid PictureInPictureManager::DoDestroy()
225e0dac50fSopenharmony_ci{
226e0dac50fSopenharmony_ci    TLOGI(WmsLogTag::WMS_PIP, "in");
227e0dac50fSopenharmony_ci    if (!HasActiveController()) {
228e0dac50fSopenharmony_ci        return;
229e0dac50fSopenharmony_ci    }
230e0dac50fSopenharmony_ci    activeController_->DestroyPictureInPictureWindow();
231e0dac50fSopenharmony_ci}
232e0dac50fSopenharmony_ci
233e0dac50fSopenharmony_civoid PictureInPictureManager::DoActionEvent(const std::string& actionName, int32_t status)
234e0dac50fSopenharmony_ci{
235e0dac50fSopenharmony_ci    TLOGI(WmsLogTag::WMS_PIP, "in");
236e0dac50fSopenharmony_ci    auto func = PIP_ACTION_MAP.find(actionName);
237e0dac50fSopenharmony_ci    if (func == PIP_ACTION_MAP.end()) {
238e0dac50fSopenharmony_ci        TLOGI(WmsLogTag::WMS_PIP, "through pass");
239e0dac50fSopenharmony_ci        if (HasActiveController()) {
240e0dac50fSopenharmony_ci            activeController_->DoActionEvent(actionName, status);
241e0dac50fSopenharmony_ci        }
242e0dac50fSopenharmony_ci        return;
243e0dac50fSopenharmony_ci    }
244e0dac50fSopenharmony_ci    func->second();
245e0dac50fSopenharmony_ci}
246e0dac50fSopenharmony_ci
247e0dac50fSopenharmony_civoid PictureInPictureManager::DoControlEvent(PiPControlType controlType, PiPControlStatus status)
248e0dac50fSopenharmony_ci{
249e0dac50fSopenharmony_ci    TLOGI(WmsLogTag::WMS_PIP, "controlType:%{public}u, enabled:%{public}d", controlType, status);
250e0dac50fSopenharmony_ci    if (!HasActiveController()) {
251e0dac50fSopenharmony_ci        return;
252e0dac50fSopenharmony_ci    }
253e0dac50fSopenharmony_ci    activeController_->DoControlEvent(controlType, status);
254e0dac50fSopenharmony_ci}
255e0dac50fSopenharmony_ci
256e0dac50fSopenharmony_civoid PictureInPictureManager::AutoStartPipWindow()
257e0dac50fSopenharmony_ci{
258e0dac50fSopenharmony_ci    TLOGI(WmsLogTag::WMS_PIP, "in");
259e0dac50fSopenharmony_ci    if (autoStartController_ == nullptr) {
260e0dac50fSopenharmony_ci        TLOGE(WmsLogTag::WMS_PIP, "autoStartController is null");
261e0dac50fSopenharmony_ci        return;
262e0dac50fSopenharmony_ci    }
263e0dac50fSopenharmony_ci    if (autoStartController_->GetPiPNavigationId().empty() || autoStartController_->IsTypeNodeEnabled()) {
264e0dac50fSopenharmony_ci        TLOGI(WmsLogTag::WMS_PIP, "No use navigation for auto start");
265e0dac50fSopenharmony_ci        autoStartController_->StartPictureInPicture(StartPipType::AUTO_START);
266e0dac50fSopenharmony_ci        return;
267e0dac50fSopenharmony_ci    }
268e0dac50fSopenharmony_ci    sptr<WindowSessionImpl> mainWindow = WindowSceneSessionImpl::GetMainWindowWithId(
269e0dac50fSopenharmony_ci        autoStartController_->GetMainWindowId());
270e0dac50fSopenharmony_ci    if (mainWindow) {
271e0dac50fSopenharmony_ci        auto navController = NavigationController::GetNavigationController(mainWindow->GetUIContent(),
272e0dac50fSopenharmony_ci            autoStartController_->GetPiPNavigationId());
273e0dac50fSopenharmony_ci        if (!navController) {
274e0dac50fSopenharmony_ci            TLOGE(WmsLogTag::WMS_PIP, "navController is nullptr");
275e0dac50fSopenharmony_ci            return;
276e0dac50fSopenharmony_ci        }
277e0dac50fSopenharmony_ci        if (navController->IsNavDestinationInTopStack()) {
278e0dac50fSopenharmony_ci            int handleId = navController->GetTopHandle();
279e0dac50fSopenharmony_ci            if (autoStartControllerMap_.empty() ||
280e0dac50fSopenharmony_ci                autoStartControllerMap_.find(handleId) == autoStartControllerMap_.end()) {
281e0dac50fSopenharmony_ci                TLOGE(WmsLogTag::WMS_PIP, "GetNavController info error, %{public}d not registered", handleId);
282e0dac50fSopenharmony_ci                return;
283e0dac50fSopenharmony_ci            }
284e0dac50fSopenharmony_ci            auto pipController = autoStartControllerMap_[handleId];
285e0dac50fSopenharmony_ci            pipController->StartPictureInPicture(StartPipType::AUTO_START);
286e0dac50fSopenharmony_ci        } else {
287e0dac50fSopenharmony_ci            TLOGE(WmsLogTag::WMS_PIP, "Top is not navDestination");
288e0dac50fSopenharmony_ci        }
289e0dac50fSopenharmony_ci    }
290e0dac50fSopenharmony_ci}
291e0dac50fSopenharmony_ci}
292e0dac50fSopenharmony_ci}
293