mirror of
https://gitee.com/openharmony/window_window_manager
synced 2024-11-23 15:00:12 +00:00
!4436 画中画支持navigation
Merge pull request !4436 from yangruixin/navigation
This commit is contained in:
commit
270e129065
@ -136,7 +136,7 @@ napi_value JsPipWindowManager::OnCreatePipController(napi_env env, napi_callback
|
||||
}
|
||||
sptr<Window> mainWindow = Window::GetTopWindowWithContext(context->lock());
|
||||
sptr<PictureInPictureController> pipController =
|
||||
new PictureInPictureController(pipOptionPtr, mainWindow->GetWindowId(), env);
|
||||
new PictureInPictureController(pipOptionPtr, mainWindow, mainWindow->GetWindowId(), env);
|
||||
task.Resolve(env, CreateJsPipControllerObject(env, pipController));
|
||||
};
|
||||
napi_value result = nullptr;
|
||||
|
@ -53,8 +53,7 @@ bool DoSomethingInterestingWithMyAPI(const uint8_t* data, size_t size)
|
||||
option->SetContext(static_cast<void*>(context));
|
||||
std::string navigationId = "nav_id";
|
||||
option->SetNavigationId(navigationId);
|
||||
std::shared_ptr<XComponentController> xComponentController;
|
||||
startPos += GetObject(xComponentController, data + startPos, size - startPos);
|
||||
std::shared_ptr<XComponentController> xComponentController = nullptr;
|
||||
option->SetXComponentController(xComponentController);
|
||||
uint32_t templateType = 0;
|
||||
startPos += GetObject<uint32_t>(templateType, data + startPos, size - startPos);
|
||||
@ -68,7 +67,8 @@ bool DoSomethingInterestingWithMyAPI(const uint8_t* data, size_t size)
|
||||
startPos += GetObject(windowId, data + startPos, size - startPos);
|
||||
napi_env env = nullptr;
|
||||
startPos += GetObject(env, data + startPos, size - startPos);
|
||||
sptr<PictureInPictureController> controller = new PictureInPictureController(option, windowId, env);
|
||||
sptr<Window> window = new Window();
|
||||
sptr<PictureInPictureController> controller = new PictureInPictureController(option, window, windowId, env);
|
||||
if (controller == nullptr) {
|
||||
return false;
|
||||
}
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include "picture_in_picture_interface.h"
|
||||
#include "xcomponent_controller.h"
|
||||
#include "pip_report.h"
|
||||
#include "navigation_controller.h"
|
||||
|
||||
namespace OHOS {
|
||||
namespace Rosen {
|
||||
@ -50,7 +51,7 @@ using namespace Ace;
|
||||
class PictureInPictureController : virtual public RefBase {
|
||||
public:
|
||||
constexpr static int32_t DEFAULT_TIME_DELAY = 400;
|
||||
PictureInPictureController(sptr<PipOption> pipOption, uint32_t mainWindowId, napi_env env);
|
||||
PictureInPictureController(sptr<PipOption> pipOption, sptr<Window> mainWindow, uint32_t mainWindowId, napi_env env);
|
||||
~PictureInPictureController();
|
||||
WMError StartPictureInPicture(StartPipType startType);
|
||||
WMError StopPictureInPicture(bool destroyWindow, bool needAnim, StopPipType stopPipType);
|
||||
@ -70,13 +71,19 @@ public:
|
||||
sptr<IPiPActionObserver> GetPictureInPictureActionObserver() const;
|
||||
WMError SetXComponentController(std::shared_ptr<XComponentController> xComponentController);
|
||||
PipWindowState GetControllerState();
|
||||
std::string GetPiPNavigationId();
|
||||
|
||||
class PipMainWindowLifeCycleImpl : public Rosen::IWindowLifeCycle {
|
||||
public:
|
||||
PipMainWindowLifeCycleImpl() {};
|
||||
PipMainWindowLifeCycleImpl(const std::string& navigationId)
|
||||
{
|
||||
navigationId_ = navigationId;
|
||||
};
|
||||
~PipMainWindowLifeCycleImpl() {};
|
||||
void AfterBackground() override;
|
||||
void BackgroundFailed(int32_t type) override;
|
||||
private:
|
||||
std::string navigationId_ = "";
|
||||
};
|
||||
private:
|
||||
WMError CreatePictureInPictureWindow();
|
||||
@ -85,6 +92,7 @@ private:
|
||||
WMError StopPictureInPictureInner(bool needAnim, StopPipType stopType);
|
||||
void UpdateXComponentPositionAndSize();
|
||||
void ResetExtController();
|
||||
bool IsPullPiPAndHandleNavigation();
|
||||
wptr<PictureInPictureController> weakRef_ = nullptr;
|
||||
sptr<PipOption> pipOption_;
|
||||
sptr<IPiPLifeCycle> pipLifeCycleListener_;
|
||||
@ -100,6 +108,7 @@ private:
|
||||
std::shared_ptr<XComponentController> mainWindowXComponentController_;
|
||||
napi_env env_;
|
||||
std::mutex mutex_;
|
||||
int32_t handleId_ = -1;
|
||||
};
|
||||
} // namespace Rosen
|
||||
} // namespace OHOS
|
||||
|
@ -39,8 +39,8 @@ public:
|
||||
static void SetActiveController(sptr<PictureInPictureController> pipController);
|
||||
static void RemoveActiveController();
|
||||
static void RemoveActiveControllerSafe();
|
||||
static void AttachAutoStartController(std::string pageName, sptr<PictureInPictureController> pipController);
|
||||
static void DetachAutoStartController(std::string pageName, sptr<PictureInPictureController> pipController);
|
||||
static void AttachAutoStartController(int32_t handleId, sptr<PictureInPictureController> pipController);
|
||||
static void DetachAutoStartController(int32_t handleId, sptr<PictureInPictureController> pipController);
|
||||
static bool IsAttachedToSameWindow(uint32_t windowId);
|
||||
static sptr<Window> GetCurrentWindow();
|
||||
|
||||
@ -49,13 +49,13 @@ public:
|
||||
static void DoStartMove();
|
||||
static void DoScale();
|
||||
static void DoActionEvent(std::string actionName);
|
||||
static void AutoStartPipWindow();
|
||||
static void AutoStartPipWindow(std::string navigationId);
|
||||
private:
|
||||
// controller in use
|
||||
static sptr<PictureInPictureController> activeController_;
|
||||
static sptr<PictureInPictureController> autoStartController_;
|
||||
// controllers enable auto start
|
||||
static std::map<std::string, sptr<PictureInPictureController>> autoStartControllerMap_;
|
||||
static std::map<int32_t, wptr<PictureInPictureController>> autoStartControllerMap_;
|
||||
|
||||
static std::map<int32_t, sptr<PictureInPictureController>> windowToControllerMap_;
|
||||
static sptr<IWindowLifeCycle> mainWindowLifeCycleImpl_;
|
||||
|
@ -39,8 +39,9 @@ namespace {
|
||||
const std::string LIVE_PAGE_PATH = "/system/etc/window/resources/pip_live.abc";
|
||||
}
|
||||
|
||||
PictureInPictureController::PictureInPictureController(sptr<PipOption> pipOption, uint32_t windowId, napi_env env)
|
||||
: weakRef_(this), pipOption_(pipOption), mainWindowId_(windowId), env_(env)
|
||||
PictureInPictureController::PictureInPictureController(sptr<PipOption> pipOption, sptr<Window> mainWindow,
|
||||
uint32_t windowId, napi_env env)
|
||||
: weakRef_(this), pipOption_(pipOption), mainWindow_(mainWindow), mainWindowId_(windowId), env_(env)
|
||||
{
|
||||
this->handler_ = std::make_shared<AppExecFwk::EventHandler>(AppExecFwk::EventRunner::GetMainEventRunner());
|
||||
curState_ = PipWindowState::STATE_UNDEFINED;
|
||||
@ -48,6 +49,7 @@ PictureInPictureController::PictureInPictureController(sptr<PipOption> pipOption
|
||||
|
||||
PictureInPictureController::~PictureInPictureController()
|
||||
{
|
||||
PictureInPictureManager::DetachAutoStartController(handleId_, this);
|
||||
}
|
||||
|
||||
WMError PictureInPictureController::CreatePictureInPictureWindow()
|
||||
@ -151,14 +153,14 @@ WMError PictureInPictureController::StartPictureInPicture(StartPipType startType
|
||||
WLOGFE("Get PictureInPictureOption failed");
|
||||
return WMError::WM_ERROR_PIP_CREATE_FAILED;
|
||||
}
|
||||
auto context = static_cast<std::weak_ptr<AbilityRuntime::Context>*>(pipOption_->GetContext());
|
||||
sptr<Window> callWindow = Window::GetTopWindowWithContext(context->lock());
|
||||
if (callWindow == nullptr) {
|
||||
WLOGFE("Get call window failed");
|
||||
if (mainWindow_ == nullptr) {
|
||||
WLOGFE("Init main window failed");
|
||||
return WMError::WM_ERROR_PIP_CREATE_FAILED;
|
||||
}
|
||||
if (!IsPullPiPAndHandleNavigation()) {
|
||||
WLOGFE("Navigation operate failed");
|
||||
return WMError::WM_ERROR_PIP_CREATE_FAILED;
|
||||
}
|
||||
mainWindowId_ = callWindow->GetWindowId();
|
||||
mainWindow_ = callWindow;
|
||||
curState_ = PipWindowState::STATE_STARTING;
|
||||
if (PictureInPictureManager::HasActiveController() && !PictureInPictureManager::IsActiveController(weakRef_)) {
|
||||
// if current controller is not the active one, but belongs to the same mainWindow, reserve pipWindow
|
||||
@ -271,6 +273,15 @@ WMError PictureInPictureController::StopPictureInPictureInner(bool needAnim, Sto
|
||||
PictureInPictureManager::RemovePipControllerInfo(session->window_->GetWindowId());
|
||||
session->window_ = nullptr;
|
||||
session->curState_ = PipWindowState::STATE_STOPPED;
|
||||
std::string navId = session->pipOption_->GetNavigationId();
|
||||
if (navId != "" && session->mainWindow_) {
|
||||
auto navController = NavigationController::GetNavigationController(
|
||||
session->mainWindow_->GetUIContent(), navId);
|
||||
if (navController) {
|
||||
navController->DeletePIPMode(session->handleId_);
|
||||
WLOGFI("Delete pip mode id: %{public}d", session->handleId_);
|
||||
}
|
||||
}
|
||||
SingletonContainer::Get<PiPReporter>().ReportPiPStopWindow(static_cast<int32_t>(currentStopType),
|
||||
currentPipOption->GetPipTemplate(), SUCCESS, "pip window stop success");
|
||||
return WMError::WM_OK;
|
||||
@ -305,9 +316,17 @@ void PictureInPictureController::SetAutoStartEnabled(bool enable)
|
||||
{
|
||||
isAutoStartEnabled_ = enable;
|
||||
if (isAutoStartEnabled_) {
|
||||
PictureInPictureManager::AttachAutoStartController(pipOption_->GetNavigationId(), this);
|
||||
if (mainWindow_ == nullptr) {
|
||||
WLOGFE("Init main window failed");
|
||||
return;
|
||||
}
|
||||
if (!IsPullPiPAndHandleNavigation()) {
|
||||
WLOGFE("Navigation operate failed");
|
||||
return;
|
||||
}
|
||||
PictureInPictureManager::AttachAutoStartController(handleId_, this);
|
||||
} else {
|
||||
PictureInPictureManager::DetachAutoStartController(pipOption_->GetNavigationId(), this);
|
||||
PictureInPictureManager::DetachAutoStartController(handleId_, this);
|
||||
}
|
||||
}
|
||||
|
||||
@ -363,7 +382,7 @@ void PictureInPictureController::PipMainWindowLifeCycleImpl::AfterBackground()
|
||||
WLOGFE("screen is off");
|
||||
return;
|
||||
}
|
||||
PictureInPictureManager::AutoStartPipWindow();
|
||||
PictureInPictureManager::AutoStartPipWindow(navigationId_);
|
||||
}
|
||||
|
||||
void PictureInPictureController::PipMainWindowLifeCycleImpl::BackgroundFailed(int32_t type)
|
||||
@ -384,11 +403,21 @@ void PictureInPictureController::DoActionEvent(std::string& actionName)
|
||||
|
||||
void PictureInPictureController::RestorePictureInPictureWindow()
|
||||
{
|
||||
if (window_ == nullptr) {
|
||||
WLOGFE("window_ is nullptr");
|
||||
if (window_ == nullptr || mainWindow_ == nullptr) {
|
||||
WLOGFE("window or main window is nullptr");
|
||||
return;
|
||||
}
|
||||
window_->RecoveryPullPiPMainWindow(windowRect_);
|
||||
std::string navId = pipOption_->GetNavigationId();
|
||||
if (navId != "") {
|
||||
auto navController = NavigationController::GetNavigationController(mainWindow_->GetUIContent(), navId);
|
||||
if (navController) {
|
||||
navController->PushInPIP(handleId_);
|
||||
WLOGFI("Push in pip handleId: %{public}d", handleId_);
|
||||
} else {
|
||||
WLOGFE("navController is nullptr");
|
||||
}
|
||||
}
|
||||
auto stopPipTask = [weakThis = wptr(this)]() {
|
||||
auto session = weakThis.promote();
|
||||
if (!session) {
|
||||
@ -490,5 +519,43 @@ sptr<IPiPActionObserver> PictureInPictureController::GetPictureInPictureActionOb
|
||||
{
|
||||
return pipActionObserver_;
|
||||
}
|
||||
|
||||
bool PictureInPictureController::IsPullPiPAndHandleNavigation()
|
||||
{
|
||||
if (pipOption_->GetNavigationId() == "") {
|
||||
WLOGFI("App not use navigation");
|
||||
return true;
|
||||
}
|
||||
if (mainWindow_ == nullptr) {
|
||||
WLOGFE("Main window init error");
|
||||
return false;
|
||||
}
|
||||
std::string navId = pipOption_->GetNavigationId();
|
||||
auto navController = NavigationController::GetNavigationController(mainWindow_->GetUIContent(), navId);
|
||||
if (navController) {
|
||||
if (navController->IsNavDestinationInTopStack()) {
|
||||
handleId_ = navController->GetTopHandle();
|
||||
if (handleId_ != -1) {
|
||||
WLOGFD("Top handle id : %{public}d", handleId_);
|
||||
navController->SetInPIPMode(handleId_);
|
||||
return true;
|
||||
} else {
|
||||
WLOGFE("Get top handle error");
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
WLOGFE("Top is not navDestination");
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
WLOGFE("Get navController error");
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string PictureInPictureController::GetPiPNavigationId()
|
||||
{
|
||||
return pipOption_? pipOption_->GetNavigationId() : "";
|
||||
}
|
||||
} // namespace Rosen
|
||||
} // namespace OHOS
|
@ -30,7 +30,7 @@ namespace {
|
||||
|
||||
sptr<PictureInPictureController> PictureInPictureManager::activeController_ = nullptr;
|
||||
sptr<PictureInPictureController> PictureInPictureManager::autoStartController_ = nullptr;
|
||||
std::map<std::string, sptr<PictureInPictureController>> PictureInPictureManager::autoStartControllerMap_ = {};
|
||||
std::map<int32_t, wptr<PictureInPictureController>> PictureInPictureManager::autoStartControllerMap_ = {};
|
||||
std::map<int32_t, sptr<PictureInPictureController>> PictureInPictureManager::windowToControllerMap_ = {};
|
||||
sptr<IWindowLifeCycle> PictureInPictureManager::mainWindowLifeCycleImpl_;
|
||||
|
||||
@ -106,7 +106,7 @@ void PictureInPictureManager::RemoveActiveControllerSafe()
|
||||
RemoveActiveController();
|
||||
}
|
||||
|
||||
void PictureInPictureManager::AttachAutoStartController(std::string pageName,
|
||||
void PictureInPictureManager::AttachAutoStartController(int32_t handleId,
|
||||
sptr<PictureInPictureController> pipController)
|
||||
{
|
||||
WLOGD("AttachAutoStartController called");
|
||||
@ -124,13 +124,14 @@ void PictureInPictureManager::AttachAutoStartController(std::string pageName,
|
||||
sptr<WindowSessionImpl> mainWindow = WindowSceneSessionImpl::GetMainWindowWithId(
|
||||
autoStartController_->GetMainWindowId());
|
||||
if (mainWindow != nullptr) {
|
||||
mainWindowLifeCycleImpl_ = new PictureInPictureController::PipMainWindowLifeCycleImpl();
|
||||
mainWindowLifeCycleImpl_ = new PictureInPictureController::PipMainWindowLifeCycleImpl(
|
||||
pipController->GetPiPNavigationId());
|
||||
mainWindow->RegisterLifeCycleListener(mainWindowLifeCycleImpl_);
|
||||
}
|
||||
autoStartControllerMap_.insert(std::make_pair(pageName, pipController));
|
||||
autoStartControllerMap_[handleId] = wptr(pipController);
|
||||
}
|
||||
|
||||
void PictureInPictureManager::DetachAutoStartController(std::string pageName,
|
||||
void PictureInPictureManager::DetachAutoStartController(int32_t handleId,
|
||||
sptr<PictureInPictureController> pipController)
|
||||
{
|
||||
WLOGD("Detach active pipController");
|
||||
@ -144,7 +145,7 @@ void PictureInPictureManager::DetachAutoStartController(std::string pageName,
|
||||
if (mainWindow != nullptr && mainWindowLifeCycleImpl_ != nullptr) {
|
||||
mainWindow->UnregisterLifeCycleListener(mainWindowLifeCycleImpl_);
|
||||
}
|
||||
autoStartControllerMap_.erase(pageName);
|
||||
autoStartControllerMap_.erase(handleId);
|
||||
autoStartController_ = nullptr;
|
||||
}
|
||||
|
||||
@ -217,14 +218,39 @@ void PictureInPictureManager::DoActionEvent(std::string actionName)
|
||||
activeController_->DoActionEvent(actionName);
|
||||
}
|
||||
|
||||
void PictureInPictureManager::AutoStartPipWindow()
|
||||
void PictureInPictureManager::AutoStartPipWindow(std::string navigationId)
|
||||
{
|
||||
WLOGD("AutoStartPipWindow is called");
|
||||
if (autoStartController_ == nullptr) {
|
||||
WLOGFE("autoStartController_ is null");
|
||||
return;
|
||||
}
|
||||
autoStartController_->StartPictureInPicture(StartPipType::AUTO_START);
|
||||
if (navigationId == "") {
|
||||
WLOGFI("No use navigationId for auto start");
|
||||
autoStartController_->StartPictureInPicture(StartPipType::AUTO_START);
|
||||
return;
|
||||
}
|
||||
sptr<WindowSessionImpl> mainWindow = WindowSceneSessionImpl::GetMainWindowWithId(
|
||||
autoStartController_->GetMainWindowId());
|
||||
if (mainWindow) {
|
||||
auto navController = NavigationController::GetNavigationController(mainWindow->GetUIContent(), navigationId);
|
||||
if (!navController) {
|
||||
WLOGFE("navController is nullptr");
|
||||
return;
|
||||
}
|
||||
if (navController->IsNavDestinationInTopStack()) {
|
||||
int handleId = navController->GetTopHandle();
|
||||
if (autoStartControllerMap_.empty() ||
|
||||
autoStartControllerMap_.find(handleId) == autoStartControllerMap_.end()) {
|
||||
WLOGFE("GetNAvController info error, %{public}d not registered", handleId);
|
||||
return;
|
||||
}
|
||||
auto pipController = autoStartControllerMap_[handleId];
|
||||
pipController->StartPictureInPicture(StartPipType::AUTO_START);
|
||||
} else {
|
||||
WLOGFE("Top is not navDestination");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -68,7 +68,7 @@ HWTEST_F(PictureInPictureControllerTest, ShowPictureInPictureWindow01, Function
|
||||
sptr<MockWindow> mw = new MockWindow();
|
||||
ASSERT_NE(nullptr, mw);
|
||||
sptr<PipOption> option = new PipOption();
|
||||
sptr<PictureInPictureController> pipControl = new PictureInPictureController(option, 100, nullptr);
|
||||
sptr<PictureInPictureController> pipControl = new PictureInPictureController(option, mw, 100, nullptr);
|
||||
ASSERT_EQ(WMError::WM_ERROR_PIP_STATE_ABNORMALLY, pipControl->ShowPictureInPictureWindow(StartPipType::NULL_START));
|
||||
pipControl->window_ = mw;
|
||||
EXPECT_CALL(*(mw), Show(_, _)).Times(1).WillOnce(Return(WMError::WM_OK));
|
||||
@ -87,7 +87,7 @@ HWTEST_F(PictureInPictureControllerTest, StopPictureInPicture01, Function | Smal
|
||||
sptr<MockWindow> mw = new MockWindow();
|
||||
ASSERT_NE(nullptr, mw);
|
||||
sptr<PipOption> option = new PipOption();
|
||||
sptr<PictureInPictureController> pipControl = new PictureInPictureController(option, 100, nullptr);
|
||||
sptr<PictureInPictureController> pipControl = new PictureInPictureController(option, mw, 100, nullptr);
|
||||
ASSERT_EQ(PipWindowState::STATE_UNDEFINED, pipControl->GetControllerState());
|
||||
ASSERT_EQ(WMError::WM_ERROR_PIP_STATE_ABNORMALLY,
|
||||
pipControl->StopPictureInPicture(true, false, StopPipType::NULL_STOP));
|
||||
|
@ -55,7 +55,7 @@ namespace {
|
||||
HWTEST_F(PictureInPictureManagerTest, PipControllerInfo, Function | SmallTest | Level2)
|
||||
{
|
||||
sptr<PipOption> option = new PipOption();
|
||||
sptr<PictureInPictureController> pipController = new PictureInPictureController(option, 100, nullptr);
|
||||
sptr<PictureInPictureController> pipController = new PictureInPictureController(option, nullptr, 100, nullptr);
|
||||
PictureInPictureManager::PutPipControllerInfo(100, pipController);
|
||||
ASSERT_EQ(1, static_cast<int>(PictureInPictureManager::windowToControllerMap_.size()));
|
||||
PictureInPictureManager::RemovePipControllerInfo(100);
|
||||
@ -71,7 +71,7 @@ HWTEST_F(PictureInPictureManagerTest, PipControllerInfo, Function | SmallTest |
|
||||
HWTEST_F(PictureInPictureManagerTest, PictureInPictureController, Function | SmallTest | Level2)
|
||||
{
|
||||
sptr<PipOption> option = new PipOption();
|
||||
sptr<PictureInPictureController> pipController = new PictureInPictureController(option, 100, nullptr);
|
||||
sptr<PictureInPictureController> pipController = new PictureInPictureController(option, nullptr, 100, nullptr);
|
||||
PictureInPictureManager::SetActiveController(pipController);
|
||||
ASSERT_TRUE(PictureInPictureManager::HasActiveController());
|
||||
ASSERT_TRUE(PictureInPictureManager::IsActiveController(pipController));
|
||||
|
Loading…
Reference in New Issue
Block a user