!7290 画中画回调整改

Merge pull request !7290 from mapengfei/master
This commit is contained in:
openharmony_ci 2024-07-12 03:42:36 +00:00 committed by Gitee
commit 7b1e1d1d73
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
8 changed files with 360 additions and 135 deletions

View File

@ -30,6 +30,7 @@ ohos_shared_library("pipwindow_napi") {
sources = [
"js_pip_controller.cpp",
"js_pip_utils.cpp",
"js_pip_window_listener.cpp",
"js_pip_window_manager.cpp",
"js_pipwindow_module.cpp",
]

View File

@ -15,19 +15,20 @@
#include "js_pip_controller.h"
#include <refbase.h>
#include "js_pip_utils.h"
#include "js_pip_window_listener.h"
#include "js_runtime_utils.h"
#include "picture_in_picture_controller.h"
#include "picture_in_picture_interface.h"
#include "picture_in_picture_manager.h"
#include "window_manager_hilog.h"
#include "wm_common.h"
#include "picture_in_picture_interface.h"
namespace OHOS {
namespace Rosen {
using namespace AbilityRuntime;
namespace {
constexpr int32_t NUMBER_ONE = 1;
constexpr int32_t NUMBER_TWO = 2;
constexpr int32_t NUMBER_FOUR = 4;
const std::string STATE_CHANGE_CB = "stateChange";
@ -53,15 +54,15 @@ napi_value CreateJsPipControllerObject(napi_env env, sptr<PictureInPictureContro
napi_create_object(env, &objValue);
TLOGI(WmsLogTag::WMS_PIP, "CreateJsPipController");
std::unique_ptr<JsPipController> jsPipController = std::make_unique<JsPipController>(pipController, env);
std::unique_ptr<JsPipController> jsPipController = std::make_unique<JsPipController>(pipController);
napi_wrap(env, objValue, jsPipController.release(), JsPipController::Finalizer, nullptr, nullptr);
BindFunctions(env, objValue, "JsPipController");
return objValue;
}
JsPipController::JsPipController(const sptr<PictureInPictureController>& pipController, napi_env env)
: pipController_(pipController), env_(env)
JsPipController::JsPipController(const sptr<PictureInPictureController>& pipController)
: pipController_(pipController)
{
listenerCodeMap_ = {
{STATE_CHANGE_CB, ListenerType::STATE_CHANGE_CB},
@ -348,21 +349,28 @@ WmErrorCode JsPipController::RegisterListenerWithType(napi_env env, const std::s
napi_ref result = nullptr;
napi_create_reference(env, value, 1, &result);
callbackRef.reset(reinterpret_cast<NativeReference*>(result));
jsCbMap_[type] = callbackRef;
auto pipWindowListener = sptr<JsPiPWindowListener>::MakeSptr(env, callbackRef);
if (pipWindowListener == nullptr) {
TLOGE(WmsLogTag::WMS_PIP, "New JsPiPWindowListener failed");
return WmErrorCode::WM_ERROR_STATE_ABNORMALLY;
}
jsCbMap_[type][callbackRef] = pipWindowListener;
switch (listenerCodeMap_[type]) {
case ListenerType::STATE_CHANGE_CB:
ProcessStateChangeRegister();
ProcessStateChangeRegister(pipWindowListener);
break;
case ListenerType::CONTROL_PANEL_ACTION_EVENT_CB:
ProcessActionEventRegister();
ProcessActionEventRegister(pipWindowListener);
break;
case ListenerType::CONTROL_EVENT_CB:
ProcessControlEventRegister();
ProcessControlEventRegister(pipWindowListener);
break;
default:
break;
}
TLOGI(WmsLogTag::WMS_PIP, "Register type %{public}s success! callback map size: %{public}zu",
type.c_str(), jsCbMap_[type].size());
return WmErrorCode::WM_OK;
}
@ -372,10 +380,9 @@ bool JsPipController::IfCallbackRegistered(napi_env env, const std::string& type
TLOGI(WmsLogTag::WMS_PIP, "methodName %{public}s not registered!", type.c_str());
return false;
}
for (auto iter = jsCbMap_.begin(); iter != jsCbMap_.end(); ++iter) {
for (auto iter = jsCbMap_[type].begin(); iter != jsCbMap_[type].end(); ++iter) {
bool isEquals = false;
napi_strict_equals(env, jsListenerObject, iter->second->GetNapiValue(), &isEquals);
napi_strict_equals(env, jsListenerObject, iter->first->GetNapiValue(), &isEquals);
if (isEquals) {
TLOGE(WmsLogTag::WMS_PIP, "Callback already registered!");
return true;
@ -384,80 +391,64 @@ bool JsPipController::IfCallbackRegistered(napi_env env, const std::string& type
return false;
}
void JsPipController::ProcessStateChangeRegister()
void JsPipController::ProcessStateChangeRegister(const sptr<JsPiPWindowListener>& listener)
{
if (jsCbMap_.empty() || jsCbMap_.find(STATE_CHANGE_CB) == jsCbMap_.end()) {
TLOGE(WmsLogTag::WMS_PIP, "Register state change error");
return;
}
if (pipController_ == nullptr) {
TLOGE(WmsLogTag::WMS_PIP, "controller is nullptr");
return;
}
sptr<IPiPLifeCycle> lifeCycle = new JsPipController::PiPLifeCycleImpl(env_, jsCbMap_[STATE_CHANGE_CB]);
pipController_->SetPictureInPictureLifecycle(lifeCycle);
sptr<IPiPLifeCycle> thisListener(listener);
pipController_->RegisterPiPLifecycle(thisListener);
}
void JsPipController::ProcessActionEventRegister()
void JsPipController::ProcessActionEventRegister(const sptr<JsPiPWindowListener>& listener)
{
if (jsCbMap_.empty() || jsCbMap_.find(CONTROL_PANEL_ACTION_EVENT_CB) == jsCbMap_.end()) {
TLOGE(WmsLogTag::WMS_PIP, "Register action event error");
return;
}
if (pipController_ == nullptr) {
TLOGE(WmsLogTag::WMS_PIP, "controller is nullptr");
return;
}
sptr<IPiPActionObserver> actionObserver =
new JsPipController::PiPActionObserverImpl(env_, jsCbMap_[CONTROL_PANEL_ACTION_EVENT_CB]);
pipController_->SetPictureInPictureActionObserver(actionObserver);
sptr<IPiPActionObserver> thisListener(listener);
pipController_->RegisterPiPActionObserver(listener);
}
void JsPipController::ProcessControlEventRegister()
void JsPipController::ProcessControlEventRegister(const sptr<JsPiPWindowListener>& listener)
{
if (jsCbMap_.empty() || jsCbMap_.find(CONTROL_EVENT_CB) == jsCbMap_.end()) {
TLOGE(WmsLogTag::WMS_PIP, "Register control event error");
return;
}
if (pipController_ == nullptr) {
TLOGE(WmsLogTag::WMS_PIP, "controller is nullptr");
return;
}
auto controlObserver = sptr<JsPipController::PiPControlObserverImpl>::MakeSptr(env_, jsCbMap_[CONTROL_EVENT_CB]);
if (controlObserver == nullptr) {
TLOGE(WmsLogTag::WMS_PIP, "controlObserver is nullptr");
return;
}
pipController_->SetPictureInPictureControlObserver(controlObserver);
TLOGI(WmsLogTag::WMS_PIP, "Register control event success");
sptr<IPiPControlObserver> thisListener(listener);
pipController_->RegisterPiPControlObserver(thisListener);
}
void JsPipController::ProcessStateChangeUnRegister()
void JsPipController::ProcessStateChangeUnRegister(const sptr<JsPiPWindowListener>& listener)
{
if (pipController_ == nullptr) {
TLOGE(WmsLogTag::WMS_PIP, "controller is nullptr");
return;
}
pipController_->SetPictureInPictureLifecycle(nullptr);
sptr<IPiPLifeCycle> thisListener(listener);
pipController_->UnregisterPiPLifecycle(thisListener);
}
void JsPipController::ProcessActionEventUnRegister()
void JsPipController::ProcessActionEventUnRegister(const sptr<JsPiPWindowListener>& listener)
{
if (pipController_ == nullptr) {
TLOGE(WmsLogTag::WMS_PIP, "controller is nullptr");
return;
}
pipController_->SetPictureInPictureActionObserver(nullptr);
sptr<IPiPActionObserver> thisListener(listener);
pipController_->UnregisterPiPActionObserver(thisListener);
}
void JsPipController::ProcessControlEventUnRegister()
void JsPipController::ProcessControlEventUnRegister(const sptr<JsPiPWindowListener>& listener)
{
if (pipController_ == nullptr) {
TLOGE(WmsLogTag::WMS_PIP, "controller is nullptr");
return;
}
pipController_->SetPictureInPictureControlObserver(nullptr);
TLOGI(WmsLogTag::WMS_PIP, "UnRegister control event success");
sptr<IPiPControlObserver> thisListener(listener);
pipController_->UnregisterPiPControlObserver(thisListener);
}
napi_value JsPipController::UnregisterCallback(napi_env env, napi_callback_info info)
@ -471,7 +462,7 @@ napi_value JsPipController::OnUnregisterCallback(napi_env env, napi_callback_inf
size_t argc = NUMBER_FOUR;
napi_value argv[NUMBER_FOUR] = {nullptr};
napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr);
if (argc != 1) {
if (argc > NUMBER_TWO) {
TLOGE(WmsLogTag::WMS_PIP, "JsPipController Params not match: %{public}zu", argc);
return NapiThrowInvalidParam(env);
}
@ -480,31 +471,75 @@ napi_value JsPipController::OnUnregisterCallback(napi_env env, napi_callback_inf
TLOGE(WmsLogTag::WMS_PIP, "Failed to convert parameter to string");
return NapiThrowInvalidParam(env);
}
WmErrorCode ret = UnRegisterListenerWithType(env, cbType);
if (ret != WmErrorCode::WM_OK) {
TLOGE(WmsLogTag::WMS_PIP, "OnUnregisterCallback failed");
napi_throw(env, CreateJsError(env, static_cast<int32_t>(ret)));
if (argc == NUMBER_ONE) {
UnRegisterListenerWithType(env, cbType, nullptr);
return NapiGetUndefined(env);
}
napi_value value = argv[NUMBER_ONE];
if (value != nullptr && NapiIsCallable(env, value)) {
UnRegisterListenerWithType(env, cbType, value);
}
return NapiGetUndefined(env);
}
WmErrorCode JsPipController::UnRegisterListenerWithType(napi_env env, const std::string& type)
WmErrorCode JsPipController::UnRegisterListenerWithType(napi_env env, const std::string& type, napi_value value)
{
if (jsCbMap_.empty() || jsCbMap_.find(type) == jsCbMap_.end()) {
TLOGI(WmsLogTag::WMS_PIP, "methodName %{public}s not registered!", type.c_str());
return WmErrorCode::WM_ERROR_INVALID_CALLING;
}
jsCbMap_.erase(type);
if (value == nullptr) {
for (auto it = jsCbMap_[type].begin(); it != jsCbMap_[type].end();) {
WmErrorCode ret = UnRegisterListener(type, it->second);
if (ret != WmErrorCode::WM_OK) {
TLOGE(WmsLogTag::WMS_PIP, "Unregister type %{public}s failed, no value", type.c_str());
return ret;
}
jsCbMap_[type].erase(it++);
}
} else {
bool foundCallbackValue = false;
for (auto it = jsCbMap_[type].begin(); it != jsCbMap_[type].end();) {
bool isEquals = false;
napi_strict_equals(env, value, it->first->GetNapiValue(), &isEquals);
if (!isEquals) {
++it;
continue;
}
foundCallbackValue = true;
WmErrorCode ret = UnRegisterListener(type, it->second);
if (ret != WmErrorCode::WM_OK) {
TLOGE(WmsLogTag::WMS_PIP, "Unregister type %{public}s failed", type.c_str());
return ret;
}
it = jsCbMap_[type].erase(it);
break;
}
if (!foundCallbackValue) {
TLOGE(WmsLogTag::WMS_PIP, "Unregister type %{public}s failed because not found callback!", type.c_str());
return WmErrorCode::WM_OK;
}
}
TLOGI(WmsLogTag::WMS_PIP, "Unregister type %{public}s success! callback map size: %{public}zu",
type.c_str(), jsCbMap_[type].size());
if (jsCbMap_[type].empty()) {
jsCbMap_.erase(type);
}
return WmErrorCode::WM_OK;
}
WmErrorCode JsPipController::UnRegisterListener(const std::string& type,
const sptr<JsPiPWindowListener>& pipWindowListener)
{
switch (listenerCodeMap_[type]) {
case ListenerType::STATE_CHANGE_CB:
ProcessStateChangeUnRegister();
ProcessStateChangeUnRegister(pipWindowListener);
break;
case ListenerType::CONTROL_PANEL_ACTION_EVENT_CB:
ProcessActionEventUnRegister();
ProcessActionEventUnRegister(pipWindowListener);
break;
case ListenerType::CONTROL_EVENT_CB:
ProcessControlEventUnRegister();
ProcessControlEventUnRegister(pipWindowListener);
break;
default:
break;
@ -565,7 +600,6 @@ void JsPipController::PiPLifeCycleImpl::OnPipListenerCallback(PiPState state, in
CallJsMethod(env, jsCallback->GetNapiValue(), argv, ArraySize(argv));
}
);
napi_ref callback = nullptr;
std::unique_ptr<NapiAsyncTask::ExecuteCallback> execute = nullptr;
NapiAsyncTask::Schedule("JsPipController::PiPLifeCycleImpl::OnPipListenerCallback",
@ -582,7 +616,6 @@ void JsPipController::PiPActionObserverImpl::OnActionEvent(const std::string& ac
CallJsMethod(env, jsCallback->GetNapiValue(), argv, ArraySize(argv));
}
);
napi_ref callback = nullptr;
std::unique_ptr<NapiAsyncTask::ExecuteCallback> execute = nullptr;
NapiAsyncTask::Schedule("JsPipController::PiPActionObserverImpl::OnActionEvent",

View File

@ -21,13 +21,14 @@
#include "js_runtime_utils.h"
#include "picture_in_picture_controller.h"
#include "wm_common.h"
#include "js_pip_window_listener.h"
namespace OHOS {
namespace Rosen {
napi_value CreateJsPipControllerObject(napi_env env, sptr<PictureInPictureController>& pipController);
class JsPipController {
public:
explicit JsPipController(const sptr<PictureInPictureController>& pipController, napi_env env);
explicit JsPipController(const sptr<PictureInPictureController>& pipController);
~JsPipController();
static void Finalizer(napi_env env, void* data, void* hint);
static napi_value StartPictureInPicture(napi_env env, napi_callback_info info);
@ -56,19 +57,19 @@ private:
bool IfCallbackRegistered(napi_env env, const std::string& type, napi_value jsListenerObject);
WmErrorCode RegisterListenerWithType(napi_env env, const std::string& type, napi_value value);
WmErrorCode UnRegisterListenerWithType(napi_env env, const std::string& type);
WmErrorCode UnRegisterListenerWithType(napi_env env, const std::string& type, napi_value value);
WmErrorCode UnRegisterListener(const std::string& type, const sptr<JsPiPWindowListener>& pipWindowListener);
void ProcessStateChangeRegister();
void ProcessActionEventRegister();
void ProcessControlEventRegister();
void ProcessStateChangeUnRegister();
void ProcessActionEventUnRegister();
void ProcessControlEventUnRegister();
void ProcessStateChangeRegister(const sptr<JsPiPWindowListener>& listener);
void ProcessActionEventRegister(const sptr<JsPiPWindowListener>& listener);
void ProcessControlEventRegister(const sptr<JsPiPWindowListener>& listener);
void ProcessStateChangeUnRegister(const sptr<JsPiPWindowListener>& listener);
void ProcessActionEventUnRegister(const sptr<JsPiPWindowListener>& listener);
void ProcessControlEventUnRegister(const sptr<JsPiPWindowListener>& listener);
sptr<PictureInPictureController> pipController_;
napi_env env_;
std::map<std::string, ListenerType> listenerCodeMap_;
std::map<std::string, std::shared_ptr<NativeReference>> jsCbMap_;
std::map<std::string, std::map<std::shared_ptr<NativeReference>, sptr<JsPiPWindowListener>>> jsCbMap_;
public:
class PiPLifeCycleImpl : public IPiPLifeCycle {

View File

@ -0,0 +1,126 @@
/*
* Copyright (c) 2024-2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "js_pip_window_listener.h"
#include "js_pip_controller.h"
#include "window_manager_hilog.h"
namespace OHOS {
namespace Rosen {
using namespace AbilityRuntime;
static napi_value CallJsFunction(napi_env env, napi_value method, napi_value const * argv, size_t argc)
{
if (env == nullptr || method == nullptr) {
TLOGE(WmsLogTag::WMS_PIP, "env nullptr or method is nullptr");
return nullptr;
}
napi_value result = nullptr;
napi_value callResult = nullptr;
napi_get_undefined(env, &result);
napi_get_undefined(env, &callResult);
napi_call_function(env, result, method, argc, argv, &callResult);
TLOGD(WmsLogTag::WMS_PIP, "called.");
return callResult;
}
JsPiPWindowListener::~JsPiPWindowListener()
{
TLOGI(WmsLogTag::WMS_PIP, "~JsWindowListener");
}
void JsPiPWindowListener::OnPreparePictureInPictureStart()
{
OnPipListenerCallback(PiPState::ABOUT_TO_START, 0);
}
void JsPiPWindowListener::OnPictureInPictureStart()
{
OnPipListenerCallback(PiPState::STARTED, 0);
}
void JsPiPWindowListener::OnPreparePictureInPictureStop()
{
OnPipListenerCallback(PiPState::ABOUT_TO_STOP, 0);
}
void JsPiPWindowListener::OnPictureInPictureStop()
{
OnPipListenerCallback(PiPState::STOPPED, 0);
}
void JsPiPWindowListener::OnRestoreUserInterface()
{
OnPipListenerCallback(PiPState::ABOUT_TO_RESTORE, 0);
}
void JsPiPWindowListener::OnPictureInPictureOperationError(int32_t errorCode)
{
OnPipListenerCallback(PiPState::ERROR, errorCode);
}
void JsPiPWindowListener::OnPipListenerCallback(PiPState state, int32_t errorCode)
{
TLOGI(WmsLogTag::WMS_PIP, "state: %{public}d", static_cast<int32_t>(state));
auto napiTask = [jsCallback = jsCallBack_, state, errorCode, env = env_]() {
napi_value argv[] = {CreateJsValue(env, static_cast<uint32_t>(state)), CreateJsValue(env, errorCode)};
CallJsFunction(env, jsCallback->GetNapiValue(), argv, ArraySize(argv));
};
if (env_ != nullptr) {
napi_status ret = napi_send_event(env_, napiTask, napi_eprio_immediate);
if (ret != napi_status::napi_ok) {
TLOGE(WmsLogTag::WMS_PIP, "Failed to SendEvent");
}
} else {
TLOGE(WmsLogTag::WMS_PIP, "env is nullptr");
}
}
void JsPiPWindowListener::OnActionEvent(const std::string& actionEvent, int32_t statusCode)
{
TLOGI(WmsLogTag::WMS_PIP, "called, actionEvent: %{public}s", actionEvent.c_str());
auto napiTask = [jsCallback = jsCallBack_, actionEvent, statusCode, env = env_]() {
napi_value argv[] = {CreateJsValue(env, actionEvent), CreateJsValue(env, statusCode)};
CallJsFunction(env, jsCallback->GetNapiValue(), argv, ArraySize(argv));
};
if (env_ != nullptr) {
napi_status ret = napi_send_event(env_, napiTask, napi_eprio_immediate);
if (ret != napi_status::napi_ok) {
TLOGE(WmsLogTag::WMS_PIP, "Failed to SendEvent");
}
} else {
TLOGE(WmsLogTag::WMS_PIP, "env is nullptr");
}
}
void JsPiPWindowListener::OnControlEvent(PiPControlType controlType, PiPControlStatus statusCode)
{
TLOGI(WmsLogTag::WMS_PIP, "controlType:%{public}u, statusCode:%{public}d", controlType, statusCode);
auto napiTask = [jsCallback = jsCallBack_, controlType, statusCode, env = env_]() {
napi_value argv[] = {CreateJsValue(env, controlType), CreateJsValue(env, statusCode)};
CallJsFunction(env, jsCallback->GetNapiValue(), argv, ArraySize(argv));
};
if (env_ != nullptr) {
napi_status ret = napi_send_event(env_, napiTask, napi_eprio_immediate);
if (ret != napi_status::napi_ok) {
TLOGE(WmsLogTag::WMS_PIP, "Failed to SendEvent");
}
} else {
TLOGE(WmsLogTag::WMS_PIP, "env is nullptr");
}
}
} // namespace Rosen
} // namespace OHOS

View File

@ -0,0 +1,48 @@
/*
* Copyright (c) 2024-2024 Huawei Device Co., Ltd.
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef OHOS_JS_PIP_WINDOW_LISTENER_H
#define OHOS_JS_PIP_WINDOW_LISTENER_H
#include "native_engine/native_value.h"
#include "picture_in_picture_interface.h"
#include "refbase.h"
namespace OHOS {
namespace Rosen {
class JsPiPWindowListener : public IPiPLifeCycle,
public IPiPActionObserver,
public IPiPControlObserver {
public:
JsPiPWindowListener(napi_env env, const std::shared_ptr<NativeReference>& callback)
: env_(env), jsCallBack_(callback) {}
~JsPiPWindowListener();
void OnPreparePictureInPictureStart() override;
void OnPictureInPictureStart() override;
void OnPreparePictureInPictureStop() override;
void OnPictureInPictureStop() override;
void OnPictureInPictureOperationError(int32_t errorCode) override;
void OnRestoreUserInterface() override;
void OnActionEvent(const std::string& actionEvent, int32_t statusCode) override;
void OnControlEvent(PiPControlType controlType, PiPControlStatus statusCode) override;
private:
void OnPipListenerCallback(PiPState state, int32_t errorCode);
napi_env env_ = nullptr;
std::shared_ptr<NativeReference> jsCallBack_ = nullptr;
};
} // namespace Rosen
} // namespace OHOS
#endif /* OHOS_JS_PIP_WINDOW_LISTENER_H */

View File

@ -83,9 +83,12 @@ public:
void PreRestorePictureInPicture();
void RestorePictureInPictureWindow();
void LocateSource();
void SetPictureInPictureLifecycle(sptr<IPiPLifeCycle> listener);
void SetPictureInPictureActionObserver(sptr<IPiPActionObserver> listener);
void SetPictureInPictureControlObserver(sptr<IPiPControlObserver> listener);
WMError RegisterPiPLifecycle(const sptr<IPiPLifeCycle>& listener);
WMError RegisterPiPActionObserver(const sptr<IPiPActionObserver>& listener);
WMError RegisterPiPControlObserver(const sptr<IPiPControlObserver>& listener);
WMError UnregisterPiPLifecycle(const sptr<IPiPLifeCycle>& listener);
WMError UnregisterPiPActionObserver(const sptr<IPiPActionObserver>& listener);
WMError UnregisterPiPControlObserver(const sptr<IPiPControlObserver>& listener);
sptr<IPiPLifeCycle> GetPictureInPictureLifecycle() const;
sptr<IPiPActionObserver> GetPictureInPictureActionObserver() const;
sptr<IPiPControlObserver> GetPictureInPictureControlObserver() const;
@ -147,11 +150,13 @@ private:
void UpdatePiPSourceRect() const;
void ResetExtController();
bool IsPullPiPAndHandleNavigation();
template<typename T> WMError RegisterListener(std::vector<sptr<T>>& holder, const sptr<T>& listener);
template<typename T> WMError UnregisterListener(std::vector<sptr<T>>& holder, const sptr<T>& listener);
wptr<PictureInPictureController> weakRef_ = nullptr;
sptr<PipOption> pipOption_;
sptr<IPiPLifeCycle> pipLifeCycleListener_;
sptr<IPiPActionObserver> pipActionObserver_;
sptr<IPiPControlObserver> pipControlObserver_;
std::vector<sptr<IPiPLifeCycle>> pipLifeCycleListeners_;
std::vector<sptr<IPiPActionObserver>> pipActionObservers_;
std::vector<sptr<IPiPControlObserver>> pipControlObservers_;
sptr<Window> window_;
sptr<Window> mainWindow_;
uint32_t mainWindowId_;

View File

@ -51,6 +51,7 @@ namespace {
"settingsdata/SETTINGSDATA?Proxy=true";
constexpr const char *SETTINGS_DATA_EXT_URI = "datashare:///com.ohos.settingsdata.DataAbility";
}
uint32_t PictureInPictureController::GetPipPriority(uint32_t pipTemplateType)
{
if (pipTemplateType >= static_cast<uint32_t>(PiPTemplateType::END)) {
@ -154,16 +155,15 @@ WMError PictureInPictureController::ShowPictureInPictureWindow(StartPipType star
pipOption_->GetPipTemplate(), FAILED, "window is nullptr");
return WMError::WM_ERROR_PIP_STATE_ABNORMALLY;
}
if (pipLifeCycleListener_ != nullptr) {
pipLifeCycleListener_->OnPreparePictureInPictureStart();
for (auto& listener : pipLifeCycleListeners_) {
listener->OnPreparePictureInPictureStart();
}
window_->SetUIContentByAbc(PIP_CONTENT_PATH, env_, nullptr, nullptr);
WMError errCode = window_->Show(0, false);
if (errCode != WMError::WM_OK) {
TLOGE(WmsLogTag::WMS_PIP, "window show failed, err: %{public}u", errCode);
int32_t err = static_cast<int32_t>(errCode);
if (pipLifeCycleListener_ != nullptr) {
pipLifeCycleListener_->OnPictureInPictureOperationError(err);
for (auto& listener : pipLifeCycleListeners_) {
listener->OnPictureInPictureOperationError(static_cast<int32_t>(errCode));
}
SingletonContainer::Get<PiPReporter>().ReportPiPStartWindow(static_cast<int32_t>(startType),
pipOption_->GetPipTemplate(), FAILED, "window show failed");
@ -307,14 +307,14 @@ WMError PictureInPictureController::StopPictureInPicture(bool destroyWindow, Sto
return WMError::WM_ERROR_PIP_STATE_ABNORMALLY;
}
curState_ = PiPWindowState::STATE_STOPPING;
if (pipLifeCycleListener_ != nullptr) {
pipLifeCycleListener_->OnPreparePictureInPictureStop();
for (auto& listener : pipLifeCycleListeners_) {
listener->OnPreparePictureInPictureStop();
}
if (!destroyWindow) {
ResetExtController();
curState_ = PiPWindowState::STATE_STOPPED;
if (pipLifeCycleListener_) {
pipLifeCycleListener_->OnPictureInPictureStop();
for (auto& listener : pipLifeCycleListeners_) {
listener->OnPictureInPictureStop();
}
PictureInPictureManager::RemoveActiveController(weakRef_);
PictureInPictureManager::RemovePipControllerInfo(window_->GetWindowId());
@ -344,8 +344,8 @@ WMError PictureInPictureController::StopPictureInPictureInner(StopPipType stopTy
if (syncTransactionController) {
syncTransactionController->CloseSyncTransaction();
}
if (pipLifeCycleListener_ != nullptr) {
pipLifeCycleListener_->OnPictureInPictureStop();
for (auto& listener : pipLifeCycleListeners_) {
listener->OnPictureInPictureStop();
}
curState_ = PiPWindowState::STATE_STOPPED;
std::string navId = pipOption_ == nullptr ? "" : pipOption_->GetNavigationId();
@ -373,8 +373,8 @@ WMError PictureInPictureController::DestroyPictureInPictureWindow()
if (ret != WmErrorCode::WM_OK) {
curState_ = PiPWindowState::STATE_UNDEFINED;
TLOGE(WmsLogTag::WMS_PIP, "window destroy failed, err:%{public}u", ret);
if (pipLifeCycleListener_ != nullptr) {
pipLifeCycleListener_->OnPictureInPictureOperationError(static_cast<int32_t>(ret));
for (auto& listener : pipLifeCycleListeners_) {
listener->OnPictureInPictureOperationError(static_cast<int32_t>(ret));
}
return WMError::WM_ERROR_PIP_DESTROY_FAILED;
}
@ -533,13 +533,11 @@ void PictureInPictureController::PipMainWindowLifeCycleImpl::BackgroundFailed(in
void PictureInPictureController::DoActionEvent(const std::string& actionName, int32_t status)
{
TLOGD(WmsLogTag::WMS_PIP, "actionName: %{public}s", actionName.c_str());
if (pipActionObserver_ == nullptr) {
TLOGE(WmsLogTag::WMS_PIP, "pipActionObserver is not registered");
return;
}
TLOGI(WmsLogTag::WMS_PIP, "actionName: %{public}s", actionName.c_str());
SingletonContainer::Get<PiPReporter>().ReportPiPActionEvent(pipOption_->GetPipTemplate(), actionName);
pipActionObserver_->OnActionEvent(actionName, status);
for (auto& listener : pipActionObservers_) {
listener->OnActionEvent(actionName, status);
}
if (CONTROL_TYPE_MAP.find(actionName) != CONTROL_TYPE_MAP.end()) {
pipOption_->SetPiPControlStatus(CONTROL_TYPE_MAP[actionName], static_cast<PiPControlStatus>(status));
}
@ -549,24 +547,22 @@ void PictureInPictureController::PreRestorePictureInPicture()
{
TLOGI(WmsLogTag::WMS_PIP, "called");
curState_ = PiPWindowState::STATE_RESTORING;
if (pipLifeCycleListener_) {
pipLifeCycleListener_->OnRestoreUserInterface();
for (auto& listener : pipLifeCycleListeners_) {
listener->OnRestoreUserInterface();
}
}
void PictureInPictureController::DoControlEvent(PiPControlType controlType, PiPControlStatus status)
{
TLOGI(WmsLogTag::WMS_PIP, "controlType:%{public}u, enabled:%{public}d", controlType, status);
if (pipControlObserver_ == nullptr) {
TLOGE(WmsLogTag::WMS_PIP, "pipControlObserver is not registered");
return;
}
if (pipOption_ == nullptr) {
TLOGE(WmsLogTag::WMS_PIP, "pipOption_ is nullptr");
return;
}
SingletonContainer::Get<PiPReporter>().ReportPiPControlEvent(pipOption_->GetPipTemplate(), controlType);
pipControlObserver_->OnControlEvent(controlType, status);
for (auto& listener : pipControlObservers_) {
listener->OnControlEvent(controlType, status);
}
pipOption_->SetPiPControlStatus(controlType, status);
}
@ -675,40 +671,69 @@ WMError PictureInPictureController::SetXComponentController(std::shared_ptr<XCom
TLOGE(WmsLogTag::WMS_PIP, "swap xComponent failed, errorCode: %{public}u", errorCode);
return WMError::WM_ERROR_PIP_INTERNAL_ERROR;
}
if (pipLifeCycleListener_ != nullptr) {
pipLifeCycleListener_->OnPictureInPictureStart();
for (auto& listener : pipLifeCycleListeners_) {
listener->OnPictureInPictureStart();
}
return WMError::WM_OK;
}
void PictureInPictureController::SetPictureInPictureLifecycle(sptr<IPiPLifeCycle> listener)
WMError PictureInPictureController::RegisterPiPLifecycle(const sptr<IPiPLifeCycle>& listener)
{
pipLifeCycleListener_ = listener;
return RegisterListener(pipLifeCycleListeners_, listener);
}
void PictureInPictureController::SetPictureInPictureActionObserver(sptr<IPiPActionObserver> listener)
WMError PictureInPictureController::RegisterPiPActionObserver(const sptr<IPiPActionObserver>& listener)
{
pipActionObserver_ = listener;
return RegisterListener(pipActionObservers_, listener);
}
void PictureInPictureController::SetPictureInPictureControlObserver(sptr<IPiPControlObserver> listener)
WMError PictureInPictureController::RegisterPiPControlObserver(const sptr<IPiPControlObserver>& listener)
{
pipControlObserver_ = listener;
return RegisterListener(pipControlObservers_, listener);
}
sptr<IPiPLifeCycle> PictureInPictureController::GetPictureInPictureLifecycle() const
WMError PictureInPictureController::UnregisterPiPLifecycle(const sptr<IPiPLifeCycle>& listener)
{
return pipLifeCycleListener_;
return UnregisterListener(pipLifeCycleListeners_, listener);
}
sptr<IPiPActionObserver> PictureInPictureController::GetPictureInPictureActionObserver() const
WMError PictureInPictureController::UnregisterPiPActionObserver(const sptr<IPiPActionObserver>& listener)
{
return pipActionObserver_;
return UnregisterListener(pipActionObservers_, listener);
}
sptr<IPiPControlObserver> PictureInPictureController::GetPictureInPictureControlObserver() const
WMError PictureInPictureController::UnregisterPiPControlObserver(const sptr<IPiPControlObserver>& listener)
{
return pipControlObserver_;
return UnregisterListener(pipControlObservers_, listener);
}
template<typename T>
WMError PictureInPictureController::RegisterListener(std::vector<sptr<T>>& holder, const sptr<T>& listener)
{
if (listener == nullptr) {
TLOGE(WmsLogTag::WMS_PIP, "listener is nullptr");
return WMError::WM_ERROR_NULLPTR;
}
if (std::find(holder.begin(), holder.end(), listener) != holder.end()) {
TLOGE(WmsLogTag::WMS_PIP, "Listener already registered");
return WMError::WM_OK;
}
holder.emplace_back(listener);
return WMError::WM_OK;
}
template<typename T>
WMError PictureInPictureController::UnregisterListener(std::vector<sptr<T>>& holder, const sptr<T>& listener)
{
if (listener == nullptr) {
TLOGE(WmsLogTag::WMS_PIP, "listener could not be null");
return WMError::WM_ERROR_NULLPTR;
}
holder.erase(std::remove_if(holder.begin(), holder.end(),
[listener](const sptr<T>& registeredListener) {
return registeredListener == listener;
}), holder.end());
return WMError::WM_OK;
}
bool PictureInPictureController::IsPullPiPAndHandleNavigation()

View File

@ -135,11 +135,9 @@ HWTEST_F(PictureInPictureControllerTest, ShowPictureInPictureWindow01, Function
ASSERT_EQ(WMError::WM_ERROR_PIP_STATE_ABNORMALLY, pipControl->ShowPictureInPictureWindow(startType));
pipControl->window_ = mw;
pipControl->pipLifeCycleListener_ = nullptr;
ASSERT_EQ(WMError::WM_OK, pipControl->ShowPictureInPictureWindow(startType));
sptr<IPiPLifeCycle> listener = nullptr;
pipControl->SetPictureInPictureLifecycle(listener);
auto listener = sptr<IPiPLifeCycle>::MakeSptr();
ASSERT_NE(nullptr, listener);
pipControl->RegisterPiPLifecycle(listener);
EXPECT_CALL(*(mw), Show(_, _)).Times(1).WillOnce(Return(WMError::WM_DO_NOTHING));
ASSERT_EQ(WMError::WM_ERROR_PIP_INTERNAL_ERROR, pipControl->ShowPictureInPictureWindow(startType));
}
@ -583,9 +581,7 @@ HWTEST_F(PictureInPictureControllerTest, DoActionEvent, Function | SmallTest | L
auto pipControl = sptr<PictureInPictureController>::MakeSptr(option, mw, 100, nullptr);
sptr<IPiPActionObserver> listener = nullptr;
pipControl->pipActionObserver_ = nullptr;
pipControl->DoActionEvent(actionName, status);
pipControl->SetPictureInPictureActionObserver(listener);
pipControl->RegisterPiPActionObserver(listener);
pipControl->DoActionEvent(actionName, status);
}
@ -605,9 +601,7 @@ HWTEST_F(PictureInPictureControllerTest, DoControlEvent, Function | SmallTest |
auto pipControl = sptr<PictureInPictureController>::MakeSptr(option, mw, 100, nullptr);
sptr<IPiPControlObserver> listener = nullptr;
pipControl->pipControlObserver_ = nullptr;
pipControl->DoControlEvent(controlType, status);
pipControl->SetPictureInPictureControlObserver(listener);
pipControl->RegisterPiPControlObserver(listener);
pipControl->DoControlEvent(controlType, status);
}
@ -625,9 +619,7 @@ HWTEST_F(PictureInPictureControllerTest, PreRestorePictureInPicture, Function |
ASSERT_NE(nullptr, option);
auto pipControl = sptr<PictureInPictureController>::MakeSptr(option, mw, 100, nullptr);
pipControl->pipLifeCycleListener_ = nullptr;
pipControl->PreRestorePictureInPicture();
pipControl->SetPictureInPictureLifecycle(listener);
pipControl->RegisterPiPLifecycle(listener);
pipControl->PreRestorePictureInPicture();
}
@ -757,12 +749,6 @@ HWTEST_F(PictureInPictureControllerTest, SetXComponentController, Function | Sma
ASSERT_EQ(WMError::WM_ERROR_PIP_STATE_ABNORMALLY, pipControl->SetXComponentController(xComponentController));
pipControl->mainWindowXComponentController_ = xComponentController1;
pipControl->pipXComponentController_ = xComponentController;
EXPECT_CALL(*(xComponentController1), SetExtController(_)).Times(1)
.WillOnce(Return(XComponentControllerErrorCode::XCOMPONENT_CONTROLLER_NO_ERROR));
pipControl->SetPictureInPictureLifecycle(listener);
ASSERT_EQ(WMError::WM_OK, pipControl->SetXComponentController(xComponentController));
}
/**