• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023-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 "picture_in_picture_manager.h"
17 
18 #include "parameters.h"
19 #include "picture_in_picture_controller.h"
20 #include "window_manager_hilog.h"
21 #include "window_scene_session_impl.h"
22 #include "scene_board_judgement.h"
23 
24 namespace OHOS {
25 namespace Rosen {
26 namespace {
27 const std::string ACTION_CLOSE = "close";
28 const std::string ACTION_PRE_RESTORE = "pre_restore";
29 const std::string ACTION_RESTORE = "restore";
30 const std::string ACTION_DESTROY = "destroy";
31 const std::string ACTION_PREPARE_SOURCE = "prepare_source";
32 const std::string ACTION_LOCATE_SOURCE = "locate_source";
33 const std::string ACTION_BACKGROUND_AUTO_START = "background_auto_start";
34 
35 const std::map<std::string, std::function<void()>> PIP_ACTION_MAP {
36     {ACTION_CLOSE, PictureInPictureManager::DoActionClose},
37     {ACTION_PRE_RESTORE, PictureInPictureManager::DoPreRestore},
38     {ACTION_RESTORE, PictureInPictureManager::DoRestore},
39     {ACTION_PREPARE_SOURCE, PictureInPictureManager::DoPrepareSource},
40     {ACTION_LOCATE_SOURCE, PictureInPictureManager::DoLocateSource},
41     {ACTION_DESTROY, PictureInPictureManager::DoDestroy},
42     {ACTION_BACKGROUND_AUTO_START, PictureInPictureManager::AutoStartPipWindow},
43 };
44 }
45 
46 sptr<PictureInPictureControllerBase> PictureInPictureManager::activeController_ = nullptr;
47 wptr<PictureInPictureController> PictureInPictureManager::autoStartController_ = nullptr;
48 std::map<int32_t, wptr<PictureInPictureController>> PictureInPictureManager::autoStartControllerMap_ = {};
49 std::map<int32_t, sptr<PictureInPictureControllerBase>> PictureInPictureManager::windowToControllerMap_ = {};
50 std::shared_ptr<NativeReference> PictureInPictureManager::innerCallbackRef_ = nullptr;
51 
PictureInPictureManager()52 PictureInPictureManager::PictureInPictureManager()
53 {
54 }
55 
~PictureInPictureManager()56 PictureInPictureManager::~PictureInPictureManager()
57 {
58 }
59 
IsSupportPiP()60 bool PictureInPictureManager::IsSupportPiP()
61 {
62     return SceneBoardJudgement::IsSceneBoardEnabled();
63 }
64 
ShouldAbortPipStart()65 bool PictureInPictureManager::ShouldAbortPipStart()
66 {
67     return activeController_ != nullptr && activeController_->GetControllerState() == PiPWindowState::STATE_STARTING;
68 }
69 
PutPipControllerInfo(int32_t windowId,sptr<PictureInPictureControllerBase> pipController)70 void PictureInPictureManager::PutPipControllerInfo(int32_t windowId, sptr<PictureInPictureControllerBase> pipController)
71 {
72     TLOGI(WmsLogTag::WMS_PIP, "windowId %{public}u", windowId);
73     windowToControllerMap_.insert(std::make_pair(windowId, pipController));
74 }
75 
RemovePipControllerInfo(int32_t windowId)76 void PictureInPictureManager::RemovePipControllerInfo(int32_t windowId)
77 {
78     TLOGI(WmsLogTag::WMS_PIP, "windowId %{public}u", windowId);
79     windowToControllerMap_.erase(windowId);
80 }
81 
GetPipControllerInfo(int32_t windowId)82 sptr<PictureInPictureControllerBase> PictureInPictureManager::GetPipControllerInfo(int32_t windowId)
83 {
84     if (windowToControllerMap_.empty() || windowToControllerMap_.find(windowId) == windowToControllerMap_.end()) {
85         TLOGE(WmsLogTag::WMS_PIP, "error, windowId: %{public}d not registered!", windowId);
86         return nullptr;
87     }
88     TLOGI(WmsLogTag::WMS_PIP, "windowId: %{public}d", windowId);
89     return windowToControllerMap_[windowId];
90 }
91 
HasActiveController()92 bool PictureInPictureManager::HasActiveController()
93 {
94     return activeController_ != nullptr;
95 }
96 
IsActiveController(wptr<PictureInPictureControllerBase> pipController)97 bool PictureInPictureManager::IsActiveController(wptr<PictureInPictureControllerBase> pipController)
98 {
99     if (!HasActiveController()) {
100         return false;
101     }
102     bool res = pipController.GetRefPtr() == activeController_.GetRefPtr();
103     TLOGD(WmsLogTag::WMS_PIP, "res: %{public}u", res);
104     return res;
105 }
106 
SetActiveController(sptr<PictureInPictureControllerBase> pipController)107 void PictureInPictureManager::SetActiveController(sptr<PictureInPictureControllerBase> pipController)
108 {
109     TLOGD(WmsLogTag::WMS_PIP, "in");
110     activeController_ = pipController;
111 }
112 
RemoveActiveController(wptr<PictureInPictureControllerBase> pipController)113 void PictureInPictureManager::RemoveActiveController(wptr<PictureInPictureControllerBase> pipController)
114 {
115     TLOGD(WmsLogTag::WMS_PIP, "in");
116     if (HasActiveController() && pipController.GetRefPtr() == activeController_.GetRefPtr()) {
117         activeController_ = nullptr;
118     }
119 }
120 
AttachAutoStartController(int32_t handleId,wptr<PictureInPictureController> pipController)121 void PictureInPictureManager::AttachAutoStartController(int32_t handleId,
122     wptr<PictureInPictureController> pipController)
123 {
124     TLOGD(WmsLogTag::WMS_PIP, "handleId: %{public}u", handleId);
125     if (pipController == nullptr) {
126         return;
127     }
128     autoStartController_ = pipController;
129     autoStartControllerMap_[handleId] = pipController;
130 }
131 
DetachAutoStartController(int32_t handleId,wptr<PictureInPictureController> pipController)132 void PictureInPictureManager::DetachAutoStartController(int32_t handleId,
133     wptr<PictureInPictureController> pipController)
134 {
135     TLOGI(WmsLogTag::WMS_PIP, "handleId: %{public}u", handleId);
136     if (autoStartController_ == nullptr) {
137         TLOGW(WmsLogTag::WMS_PIP, "detach failed as none autoStartController exist");
138         return;
139     }
140     if (pipController != nullptr && pipController.GetRefPtr() != autoStartController_.GetRefPtr()) {
141         TLOGW(WmsLogTag::WMS_PIP, "not same pip controller");
142         return;
143     }
144     autoStartController_ = nullptr;
145     autoStartControllerMap_.erase(handleId);
146 }
147 
IsAttachedToSameWindow(uint32_t windowId)148 bool PictureInPictureManager::IsAttachedToSameWindow(uint32_t windowId)
149 {
150     TLOGI(WmsLogTag::WMS_PIP, "windowId: %{public}u", windowId);
151     if (!HasActiveController()) {
152         return false;
153     }
154     return activeController_->GetMainWindowId() == windowId;
155 }
156 
GetCurrentWindow()157 sptr<Window> PictureInPictureManager::GetCurrentWindow()
158 {
159     if (!HasActiveController()) {
160         return nullptr;
161     }
162     return activeController_->GetPipWindow();
163 }
164 
DoPreRestore()165 void PictureInPictureManager::DoPreRestore()
166 {
167     TLOGI(WmsLogTag::WMS_PIP, "in");
168     if (auto controller = GetActiveController()) {
169         controller->PreRestorePictureInPicture();
170     }
171 }
172 
DoRestore()173 void PictureInPictureManager::DoRestore()
174 {
175     TLOGI(WmsLogTag::WMS_PIP, "in");
176     if (auto controller = GetActiveController()) {
177         controller->RestorePictureInPictureWindow();
178     }
179 }
180 
DoPrepareSource()181 void PictureInPictureManager::DoPrepareSource()
182 {
183     TLOGI(WmsLogTag::WMS_PIP, "in");
184     if (auto controller = GetActiveController()) {
185         controller->PrepareSource();
186     }
187 }
188 
DoLocateSource()189 void PictureInPictureManager::DoLocateSource()
190 {
191     TLOGI(WmsLogTag::WMS_PIP, "in");
192     if (auto controller = GetActiveController()) {
193         controller->LocateSource();
194     }
195 }
196 
DoClose(bool destroyWindow,bool byPriority)197 void PictureInPictureManager::DoClose(bool destroyWindow, bool byPriority)
198 {
199     TLOGI(WmsLogTag::WMS_PIP, "destroyWindow:%{public}d, byPriority:%{public}d", destroyWindow, byPriority);
200     if (auto controller = GetActiveController()) {
201         StopPipType currentStopType = StopPipType::NULL_STOP;
202         if (!byPriority) {
203             currentStopType = StopPipType::USER_STOP;
204         } else {
205             currentStopType = StopPipType::OTHER_PACKAGE_STOP;
206         }
207         controller->StopPictureInPicture(destroyWindow, currentStopType, !byPriority);
208     }
209 }
210 
DoActionClose()211 void PictureInPictureManager::DoActionClose()
212 {
213     TLOGI(WmsLogTag::WMS_PIP, "in");
214     DoClose(true, false);
215 }
216 
DoDestroy()217 void PictureInPictureManager::DoDestroy()
218 {
219     TLOGI(WmsLogTag::WMS_PIP, "in");
220     if (auto controller = GetActiveController()) {
221         controller->DestroyPictureInPictureWindow();
222     }
223 }
224 
DoActionEvent(const std::string & actionName,int32_t status)225 void PictureInPictureManager::DoActionEvent(const std::string& actionName, int32_t status)
226 {
227     TLOGI(WmsLogTag::WMS_PIP, "in");
228     auto func = PIP_ACTION_MAP.find(actionName);
229     if (func == PIP_ACTION_MAP.end()) {
230         TLOGI(WmsLogTag::WMS_PIP, "through pass");
231         if (auto controller = GetActiveController()) {
232             controller->DoActionEvent(actionName, status);
233         }
234         return;
235     }
236     func->second();
237 }
238 
DoControlEvent(PiPControlType controlType,PiPControlStatus status)239 void PictureInPictureManager::DoControlEvent(PiPControlType controlType, PiPControlStatus status)
240 {
241     TLOGI(WmsLogTag::WMS_PIP, "controlType:%{public}u, enabled:%{public}d", controlType, status);
242     if (auto controller = GetActiveController()) {
243         controller->DoControlEvent(controlType, status);
244     }
245 }
246 
AutoStartPipWindow()247 void PictureInPictureManager::AutoStartPipWindow()
248 {
249     TLOGI(WmsLogTag::WMS_PIP, "in");
250     if (autoStartController_ == nullptr) {
251         TLOGE(WmsLogTag::WMS_PIP, "autoStartController_ is null");
252         return;
253     }
254     auto autoStartController = autoStartController_.promote();
255     if (autoStartController == nullptr) {
256         TLOGE(WmsLogTag::WMS_PIP, "autoStartController is null");
257         return;
258     }
259     if (autoStartController->GetPiPNavigationId().empty() || autoStartController->IsTypeNodeEnabled()) {
260         TLOGI(WmsLogTag::WMS_PIP, "No use navigation for auto start");
261         autoStartController->StartPictureInPicture(StartPipType::AUTO_START);
262         return;
263     }
264     sptr<WindowSessionImpl> mainWindow = WindowSceneSessionImpl::GetMainWindowWithId(
265         autoStartController->GetMainWindowId());
266     if (mainWindow) {
267         auto navController = NavigationController::GetNavigationController(mainWindow->GetUIContent(),
268             autoStartController->GetPiPNavigationId());
269         if (!navController) {
270             TLOGE(WmsLogTag::WMS_PIP, "navController is nullptr");
271             return;
272         }
273         if (navController->IsNavDestinationInTopStack()) {
274             int handleId = navController->GetTopHandle();
275             if (autoStartControllerMap_.empty() ||
276                 autoStartControllerMap_.find(handleId) == autoStartControllerMap_.end()) {
277                 TLOGE(WmsLogTag::WMS_PIP, "GetNavController info error, %{public}d not registered", handleId);
278                 return;
279             }
280             auto wptrPipController = autoStartControllerMap_[handleId];
281             if (wptrPipController == nullptr) {
282                 TLOGE(WmsLogTag::WMS_PIP, "wptrPipController is nullptr");
283                 return;
284             }
285             auto pipController = wptrPipController.promote();
286             if (!pipController) {
287                 TLOGE(WmsLogTag::WMS_PIP, "pipController is nullptr");
288                 return;
289             }
290             pipController->StartPictureInPicture(StartPipType::AUTO_START);
291         } else {
292             TLOGE(WmsLogTag::WMS_PIP, "Top is not navDestination");
293         }
294     }
295 }
296 
PipSizeChange(double width,double height,double scale)297 void PictureInPictureManager::PipSizeChange(double width, double height, double scale)
298 {
299     TLOGI(WmsLogTag::WMS_PIP, "in");
300     if (auto controller = GetActiveController()) {
301         controller->PipSizeChange(width, height, scale);
302     }
303 }
304 
GetPipEnabled()305 bool PictureInPictureManager::GetPipEnabled()
306 {
307     return true;
308 }
309 
310 }
311 }
312