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