mirror of
https://gitee.com/openharmony/window_window_manager
synced 2024-11-23 23:10:54 +00:00
commit
7b1e1d1d73
@ -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",
|
||||
]
|
||||
|
@ -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",
|
||||
|
@ -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 {
|
||||
|
@ -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
|
@ -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 */
|
@ -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_;
|
||||
|
@ -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()
|
||||
|
@ -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));
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user