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 <refbase.h>
19 #include "picture_in_picture_controller.h"
20 #include "window.h"
21 #include "window_manager_hilog.h"
22 #include "window_scene_session_impl.h"
23 #include "wm_common.h"
24
25 namespace OHOS {
26 namespace Rosen {
27 namespace {
28 constexpr HiviewDFX::HiLogLabel LABEL = {LOG_CORE, HILOG_DOMAIN_WINDOW, "PictureInPictureManager"};
29 }
30
31 sptr<PictureInPictureController> PictureInPictureManager::activeController_ = nullptr;
32 wptr<PictureInPictureController> PictureInPictureManager::autoStartController_ = nullptr;
33 std::map<int32_t, wptr<PictureInPictureController>> PictureInPictureManager::autoStartControllerMap_ = {};
34 std::map<int32_t, sptr<PictureInPictureController>> PictureInPictureManager::windowToControllerMap_ = {};
35 sptr<IWindowLifeCycle> PictureInPictureManager::mainWindowLifeCycleImpl_;
36
PictureInPictureManager()37 PictureInPictureManager::PictureInPictureManager()
38 {
39 }
40
~PictureInPictureManager()41 PictureInPictureManager::~PictureInPictureManager()
42 {
43 }
44
ShouldAbortPipStart()45 bool PictureInPictureManager::ShouldAbortPipStart()
46 {
47 return activeController_ != nullptr && activeController_->GetControllerState() == PipWindowState::STATE_STARTING;
48 }
49
PutPipControllerInfo(int32_t windowId,sptr<PictureInPictureController> pipController)50 void PictureInPictureManager::PutPipControllerInfo(int32_t windowId, sptr<PictureInPictureController> pipController)
51 {
52 WLOGD("PutPipControllerInfo called, windowId %{public}u", windowId);
53 windowToControllerMap_.insert(std::make_pair(windowId, pipController));
54 }
55
RemovePipControllerInfo(int32_t windowId)56 void PictureInPictureManager::RemovePipControllerInfo(int32_t windowId)
57 {
58 WLOGD("RemovePipControllerInfo called, windowId %{public}u", windowId);
59 windowToControllerMap_.erase(windowId);
60 }
61
GetPipControllerInfo(int32_t windowId)62 sptr<PictureInPictureController> PictureInPictureManager::GetPipControllerInfo(int32_t windowId)
63 {
64 if (windowToControllerMap_.empty() || windowToControllerMap_.find(windowId) == windowToControllerMap_.end()) {
65 WLOGE("GetPipControllerInfo error, %{public}d not registered!", windowId);
66 return nullptr;
67 }
68 return windowToControllerMap_[windowId];
69 }
70
HasActiveController()71 bool PictureInPictureManager::HasActiveController()
72 {
73 return activeController_ != nullptr;
74 }
75
IsActiveController(wptr<PictureInPictureController> pipController)76 bool PictureInPictureManager::IsActiveController(wptr<PictureInPictureController> pipController)
77 {
78 if (!HasActiveController()) {
79 return false;
80 }
81 bool res = pipController.GetRefPtr() == activeController_.GetRefPtr();
82 WLOGD("IsActiveController %{public}u", res);
83 return res;
84 }
85
SetActiveController(sptr<PictureInPictureController> pipController)86 void PictureInPictureManager::SetActiveController(sptr<PictureInPictureController> pipController)
87 {
88 WLOGD("SetActiveController called");
89 activeController_ = pipController;
90 }
91
RemoveActiveController(wptr<PictureInPictureController> pipController)92 void PictureInPictureManager::RemoveActiveController(wptr<PictureInPictureController> pipController)
93 {
94 WLOGD("RemoveActiveController called");
95 if (!IsActiveController(pipController)) {
96 return;
97 }
98 activeController_ = nullptr;
99 }
100
AttachAutoStartController(int32_t handleId,wptr<PictureInPictureController> pipController)101 void PictureInPictureManager::AttachAutoStartController(int32_t handleId,
102 wptr<PictureInPictureController> pipController)
103 {
104 WLOGD("AttachAutoStartController, %{public}u", handleId);
105 if (pipController == nullptr) {
106 return;
107 }
108 if (autoStartController_ != nullptr && mainWindowLifeCycleImpl_ != nullptr) {
109 sptr<WindowSessionImpl> previousMainWindow = WindowSceneSessionImpl::GetMainWindowWithId(
110 autoStartController_->GetMainWindowId());
111 if (previousMainWindow != nullptr) {
112 previousMainWindow->UnregisterLifeCycleListener(mainWindowLifeCycleImpl_);
113 }
114 }
115 autoStartController_ = pipController;
116 sptr<WindowSessionImpl> mainWindow = WindowSceneSessionImpl::GetMainWindowWithId(
117 autoStartController_->GetMainWindowId());
118 if (mainWindow != nullptr) {
119 mainWindowLifeCycleImpl_ = new PictureInPictureController::PipMainWindowLifeCycleImpl(
120 pipController->GetPiPNavigationId());
121 mainWindow->RegisterLifeCycleListener(mainWindowLifeCycleImpl_);
122 }
123 autoStartControllerMap_[handleId] = pipController;
124 }
125
DetachAutoStartController(int32_t handleId,wptr<PictureInPictureController> pipController)126 void PictureInPictureManager::DetachAutoStartController(int32_t handleId,
127 wptr<PictureInPictureController> pipController)
128 {
129 WLOGD("Detach active pipController, %{public}u", handleId);
130 autoStartControllerMap_.erase(handleId);
131 if (autoStartController_ == nullptr) {
132 return;
133 }
134 if (pipController != nullptr &&
135 pipController.GetRefPtr() != autoStartController_.GetRefPtr()) {
136 WLOGFE("not same pip controller or no active pip controller");
137 return;
138 }
139 sptr<WindowSessionImpl> mainWindow = WindowSceneSessionImpl::GetMainWindowWithId(
140 autoStartController_->GetMainWindowId());
141 if (mainWindow != nullptr && mainWindowLifeCycleImpl_ != nullptr) {
142 mainWindow->UnregisterLifeCycleListener(mainWindowLifeCycleImpl_);
143 }
144 autoStartController_ = nullptr;
145 }
146
IsAttachedToSameWindow(uint32_t windowId)147 bool PictureInPictureManager::IsAttachedToSameWindow(uint32_t windowId)
148 {
149 WLOGD("IsAttachedToSameWindow called %{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
DoRestore()164 void PictureInPictureManager::DoRestore()
165 {
166 WLOGD("DoRestore is called");
167 if (!HasActiveController()) {
168 return;
169 }
170 activeController_->RestorePictureInPictureWindow();
171 }
172
DoClose(bool destroyWindow,bool needAnim)173 void PictureInPictureManager::DoClose(bool destroyWindow, bool needAnim)
174 {
175 WLOGD("DoClose is called");
176 if (!HasActiveController()) {
177 return;
178 }
179 StopPipType currentStopType = StopPipType::NULL_STOP;
180 if (needAnim) {
181 currentStopType = StopPipType::USER_STOP;
182 } else {
183 currentStopType = StopPipType::OTHER_PACKAGE_STOP;
184 }
185 activeController_->StopPictureInPicture(destroyWindow, needAnim, currentStopType);
186 }
187
DoStartMove()188 void PictureInPictureManager::DoStartMove()
189 {
190 WLOGD("DoStartMove is called");
191 if (!HasActiveController()) {
192 return;
193 }
194 activeController_->StartMove();
195 }
196
DoScale()197 void PictureInPictureManager::DoScale()
198 {
199 WLOGD("DoScale is called");
200 if (!HasActiveController()) {
201 return;
202 }
203 activeController_->DoScale();
204 }
205
DoActionEvent(std::string actionName)206 void PictureInPictureManager::DoActionEvent(std::string actionName)
207 {
208 WLOGD("DoActionEvent is called");
209 if (!HasActiveController()) {
210 return;
211 }
212 activeController_->DoActionEvent(actionName);
213 }
214
AutoStartPipWindow(std::string navigationId)215 void PictureInPictureManager::AutoStartPipWindow(std::string navigationId)
216 {
217 WLOGD("AutoStartPipWindow is called, navId: %{public}s", navigationId.c_str());
218 if (autoStartController_ == nullptr) {
219 WLOGFE("autoStartController_ is null");
220 return;
221 }
222 if (navigationId == "") {
223 WLOGFI("No use navigationId for auto start");
224 autoStartController_->StartPictureInPicture(StartPipType::AUTO_START);
225 return;
226 }
227 sptr<WindowSessionImpl> mainWindow = WindowSceneSessionImpl::GetMainWindowWithId(
228 autoStartController_->GetMainWindowId());
229 if (mainWindow) {
230 auto navController = NavigationController::GetNavigationController(mainWindow->GetUIContent(), navigationId);
231 if (!navController) {
232 WLOGFE("navController is nullptr");
233 return;
234 }
235 if (navController->IsNavDestinationInTopStack()) {
236 int handleId = navController->GetTopHandle();
237 if (autoStartControllerMap_.empty() ||
238 autoStartControllerMap_.find(handleId) == autoStartControllerMap_.end()) {
239 WLOGFE("GetNAvController info error, %{public}d not registered", handleId);
240 return;
241 }
242 auto pipController = autoStartControllerMap_[handleId];
243 pipController->StartPictureInPicture(StartPipType::AUTO_START);
244 } else {
245 WLOGFE("Top is not navDestination");
246 }
247 }
248 }
249 }
250 }
251