From 6adea4e6ef94ba6a5cb4a9d0800e2207df5a2415 Mon Sep 17 00:00:00 2001 From: jiangxiaofeng20 Date: Fri, 10 Jan 2025 09:33:45 +0800 Subject: [PATCH 01/13] pip Signed-off-by: jiangxiaofeng20 --- .../inner/js_pip_manager.cpp | 92 +- .../inner/js_pip_manager.h | 2 + .../js_pip_controller.cpp | 33 + .../js_pip_controller.h | 2 + .../js_pip_window_listener.cpp | 4 - patch | 986 ++++++++++++++++++ resources/abc/pip/interface/PiPContent.js | 114 +- resources/abc/pip/source/PiPContent.ets | 91 +- utils/include/pip_report.h | 1 + utils/src/pip_report.cpp | 14 + wm/include/picture_in_picture_controller.h | 6 + wm/include/picture_in_picture_option.h | 5 + wm/src/picture_in_picture_controller.cpp | 108 ++ wm/src/picture_in_picture_option.cpp | 21 + .../picture_in_picture_controller_test.cpp | 79 ++ .../picture_in_picture_option_test.cpp | 12 + 16 files changed, 1525 insertions(+), 45 deletions(-) create mode 100644 patch diff --git a/interfaces/kits/napi/picture_in_picture_napi/inner/js_pip_manager.cpp b/interfaces/kits/napi/picture_in_picture_napi/inner/js_pip_manager.cpp index 1a2583b075..a0a62dc332 100644 --- a/interfaces/kits/napi/picture_in_picture_napi/inner/js_pip_manager.cpp +++ b/interfaces/kits/napi/picture_in_picture_napi/inner/js_pip_manager.cpp @@ -25,6 +25,14 @@ using namespace Ace; namespace { constexpr int32_t NUMBER_ONE = 1; constexpr int32_t NUMBER_TWO = 2; + const std::set PIP_CONTENT_CALLBACK {"stateChange", "nodeUpdate"}; +} + +napi_valuetype GetType(napi_env env, napi_value value) +{ + napi_valuetype res = napi_undefined; + napi_typeof(env, value, &res); + return res; } napi_value NapiGetUndefined(napi_env env) @@ -179,6 +187,36 @@ napi_value JsPipManager::OnSetTypeNodeEnabled(napi_env env, napi_callback_info i return NapiGetUndefined(env); } +napi_value JsPipManager::SetPipNodeType(napi_env env, napi_callback_info info) +{ + JsPipManager* me = CheckParamsAndGetThis(env, info); + return (me != nullptr) ? me->OnSetPipNodeType(env, info) : nullptr; +} + +napi_value JsPipManager::OnSetPipNodeType(napi_env env, napi_callback_info info) +{ + TLOGD(WmsLogTag::WMS_PIP, "[NAPI]"); + size_t argc = 4; // 4: arg number + napi_value argv[4] = { nullptr }; + napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr); + if (argc != NUMBER_TWO) { + TLOGE(WmsLogTag::WMS_PIP, "[NAPI]Argc count is invalid: %{public}zu", argc); + return NapiGetUndefined(env); + } + napi_value typeNode = argv[0]; + bool markPip = false; + if (!ConvertFromJsValue(env, argv[1], markPip)) { + TLOGW(WmsLogTag::WMS_PIP, "Failed to convert param to bool"); + } + if (typeNode != nullptr && GetType(env, typeNode) != napi_undefined) { + XComponentControllerErrorCode ret = XComponentController::SetSurfaceCallbackMode(env, typeNode, markPip ? + SurfaceCallbackMode::PIP: SurfaceCallbackMode::DEFAULT); + TLOGI(WmsLogTag::WMS_PIP, "set surface mode, ret: %{public}u, isPip: %{public}d", + static_cast(ret), static_cast(markPip)); + } + return NapiGetUndefined(env); +} + napi_value JsPipManager::RegisterCallback(napi_env env, napi_callback_info info) { JsPipManager* me = CheckParamsAndGetThis(env, info); @@ -207,6 +245,11 @@ napi_value JsPipManager::OnRegisterCallback(napi_env env, napi_callback_info inf TLOGE(WmsLogTag::WMS_PIP, "Failed to convert param to cbType"); return NapiThrowInvalidParam(env); } + auto iter = std::find(PIP_CONTENT_CALLBACK.begin(), PIP_CONTENT_CALLBACK.end(), cbType); + if (iter == PIP_CONTENT_CALLBACK.end()) { + TLOGE(WmsLogTag::WMS_PIP, "Callback is null or not callable"); + return NapiThrowInvalidParam(env); + } napi_value value = argv[1]; if (value == nullptr || !NapiIsCallable(env, value)) { TLOGE(WmsLogTag::WMS_PIP, "Callback is null or not callable"); @@ -215,8 +258,20 @@ napi_value JsPipManager::OnRegisterCallback(napi_env env, napi_callback_info inf std::shared_ptr callbackRef; napi_ref result = nullptr; napi_create_reference(env, value, 1, &result); - callbackRef.reset(reinterpret_cast(result)); - PictureInPictureManager::innerCallbackRef_ = callbackRef; + callbackRef.reset(reinterpret_cast(result)); + sptr pipWindow = Window::Find(PIP_WINDOW_NAME); + int32_t windowId = static_cast(pipWindow->GetWindowId()); + sptr pipController = PictureInPictureManager::GetPipControllerInfo(windowId); + if (pipController == nullptr) { + TLOGE(WmsLogTag::WMS_PIP, "Failed to get pictureInPictureController"); + return NapiGetUndefined(env); + } + TLOGI(WmsLogTag::WMS_PIP, "OnRegisterCallback to window: %{public}u", windowId); + WMError errCode = pipController->RegisterPipContentListenerWithType(cbType, callbackRef); + if (errCode != WMError::WM_OK) { + TLOGE(WmsLogTag::WMS_PIP, "Failed to registerCallback"); + return NapiGetUndefined(env); + } TLOGI(WmsLogTag::WMS_PIP, "Register type %{public}s success!", cbType.c_str()); return NapiGetUndefined(env); } @@ -230,7 +285,37 @@ napi_value JsPipManager::UnregisterCallback(napi_env env, napi_callback_info inf napi_value JsPipManager::OnUnregisterCallback(napi_env env, napi_callback_info info) { TLOGI(WmsLogTag::WMS_PIP, "[NAPI]"); - PictureInPictureManager::innerCallbackRef_ = nullptr; + size_t argc = 4; + napi_value argv[4] = {nullptr}; + napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr); + if (argc != NUMBER_ONE) { + TLOGE(WmsLogTag::WMS_PIP, "Params count not match: %{public}zu", argc); + return NapiThrowInvalidParam(env); + } + std::string cbType; + if (!ConvertFromJsValue(env, argv[0], cbType)) { + TLOGE(WmsLogTag::WMS_PIP, "Failed to convert param to cbType"); + return NapiThrowInvalidParam(env); + } + auto iter = std::find(PIP_CONTENT_CALLBACK.begin(), PIP_CONTENT_CALLBACK.end(), cbType); + if (iter == PIP_CONTENT_CALLBACK.end()) { + TLOGE(WmsLogTag::WMS_PIP, "Callback is null or not callable"); + return NapiThrowInvalidParam(env); + } + sptr pipWindow = Window::Find(PIP_WINDOW_NAME); + int32_t windowId = static_cast(pipWindow->GetWindowId()); + sptr pipController = PictureInPictureManager::GetPipControllerInfo(windowId); + if (pipController == nullptr) { + TLOGE(WmsLogTag::WMS_PIP, "Failed to get pictureInPictureController"); + return NapiGetUndefined(env); + } + TLOGI(WmsLogTag::WMS_PIP, "UnRegisterPipContentListenerWithType to window: %{public}u", windowId); + WMError errCode = pipController->UnRegisterPipContentListenerWithType(cbType); + if (errCode != WMError::WM_OK) { + TLOGE(WmsLogTag::WMS_PIP, "Failed to set UnRegisterPipContentListenerWithType"); + return NapiGetUndefined(env); + } + TLOGI(WmsLogTag::WMS_PIP, "unregister type %{public}s success!", cbType.c_str()); return NapiGetUndefined(env); } @@ -250,6 +335,7 @@ napi_value JsPipManagerInit(napi_env env, napi_value exportObj) BindNativeFunction(env, exportObj, "on", moduleName, JsPipManager::RegisterCallback); BindNativeFunction(env, exportObj, "off", moduleName, JsPipManager::UnregisterCallback); BindNativeFunction(env, exportObj, "setTypeNodeEnabled", moduleName, JsPipManager::SetTypeNodeEnabled); + BindNativeFunction(env, exportObj, "setPipNodeType", moduleName, JsPipManager::SetPipNodeType); return NapiGetUndefined(env); } } // namespace Rosen diff --git a/interfaces/kits/napi/picture_in_picture_napi/inner/js_pip_manager.h b/interfaces/kits/napi/picture_in_picture_napi/inner/js_pip_manager.h index 90ae2aa865..a926cbcaf6 100644 --- a/interfaces/kits/napi/picture_in_picture_napi/inner/js_pip_manager.h +++ b/interfaces/kits/napi/picture_in_picture_napi/inner/js_pip_manager.h @@ -32,6 +32,7 @@ public: static napi_value RegisterCallback(napi_env env, napi_callback_info info); static napi_value UnregisterCallback(napi_env env, napi_callback_info info); static napi_value SetTypeNodeEnabled(napi_env env, napi_callback_info info); + static napi_value SetPipNodeType(napi_env env, napi_callback_info info); private: napi_value OnInitXComponentController(napi_env env, napi_callback_info info); napi_value OnGetCustomUIController(napi_env env, napi_callback_info info); @@ -39,6 +40,7 @@ private: napi_value OnRegisterCallback(napi_env env, napi_callback_info info); napi_value OnUnregisterCallback(napi_env env, napi_callback_info info); napi_value OnSetTypeNodeEnabled(napi_env env, napi_callback_info info); + napi_value OnSetPipNodeType(napi_env env, napi_callback_info info); }; } // namespace Rosen } // namespace OHOS diff --git a/interfaces/kits/napi/picture_in_picture_napi/js_pip_controller.cpp b/interfaces/kits/napi/picture_in_picture_napi/js_pip_controller.cpp index ef816c55da..68045a1ebb 100644 --- a/interfaces/kits/napi/picture_in_picture_napi/js_pip_controller.cpp +++ b/interfaces/kits/napi/picture_in_picture_napi/js_pip_controller.cpp @@ -36,6 +36,7 @@ void BindFunctions(napi_env env, napi_value object, const char* moduleName) { BindNativeFunction(env, object, "startPiP", moduleName, JsPipController::StartPictureInPicture); BindNativeFunction(env, object, "stopPiP", moduleName, JsPipController::StopPictureInPicture); + BindNativeFunction(env, object, "updateContentNode", moduleName, JsPipController::UpdateContentNode); BindNativeFunction(env, object, "updateContentSize", moduleName, JsPipController::UpdateContentSize); BindNativeFunction(env, object, "updatePiPControlStatus", moduleName, JsPipController::UpdatePiPControlStatus); BindNativeFunction(env, object, "setAutoStartEnabled", moduleName, JsPipController::SetAutoStartEnabled); @@ -186,6 +187,38 @@ napi_value JsPipController::OnSetAutoStartEnabled(napi_env env, napi_callback_in return NapiGetUndefined(env); } +napi_value JsPipController::UpdateContentNode(napi_env env, napi_callback_info info) +{ + JsPipController *me = CheckParamsAndGetThis(env, info); + return (me != nullptr) ? me->OnUpdateContentNode(env, info) : nullptr; +} + +napi_value JsPipController::OnUpdateContentNode(napi_env env, napi_callback_info info) +{ + TLOGI(WmsLogTag::WMS_PIP, "OnUpdateContentNode is called"); + size_t argc = 4; + napi_value argv[4] = {nullptr}; + napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr); + if (argc != NUMBER_ONE) { + TLOGE(WmsLogTag::WMS_PIP, "[NAPI]Argc count is invalid: %{public}zu", argc); + return NapiThrowInvalidParam(env, "Invalid args count, 1 arg is needed."); + } + napi_value typeNode = argv[0]; + if (typeNode == nullptr || GetType(env, typeNode) == napi_undefined) { + TLOGE(WmsLogTag::WMS_PIP, "[NAPI] invalid typeNode"); + return NapiThrowInvalidParam(env, "invalid typeNode."); + } + if (pipController_ == nullptr) { + std::string errMsg = "OnUpdateNode error, controller is nullptr"; + TLOGE(WmsLogTag::WMS_PIP, "%{public}s", errMsg.c_str()); + return NapiThrowInvalidParam(env, errMsg); + } + napi_ref typeNodeRef = nullptr; + napi_create_reference(env, typeNode, 1, &typeNodeRef); + pipController_->UpdateContentNodeRef(typeNodeRef); + return NapiGetUndefined(env); +} + napi_value JsPipController::UpdateContentSize(napi_env env, napi_callback_info info) { JsPipController* me = CheckParamsAndGetThis(env, info); diff --git a/interfaces/kits/napi/picture_in_picture_napi/js_pip_controller.h b/interfaces/kits/napi/picture_in_picture_napi/js_pip_controller.h index 166f9c8f7b..b81ed1d642 100644 --- a/interfaces/kits/napi/picture_in_picture_napi/js_pip_controller.h +++ b/interfaces/kits/napi/picture_in_picture_napi/js_pip_controller.h @@ -34,6 +34,7 @@ public: static napi_value StartPictureInPicture(napi_env env, napi_callback_info info); static napi_value StopPictureInPicture(napi_env env, napi_callback_info info); static napi_value SetAutoStartEnabled(napi_env env, napi_callback_info info); + static napi_value UpdateContentNode(napi_env env, napi_callback_info info); static napi_value UpdateContentSize(napi_env env, napi_callback_info info); static napi_value UpdatePiPControlStatus(napi_env env, napi_callback_info info); static napi_value SetPiPControlEnabled(napi_env env, napi_callback_info info); @@ -49,6 +50,7 @@ private: napi_value OnStartPictureInPicture(napi_env env, napi_callback_info info); napi_value OnStopPictureInPicture(napi_env env, napi_callback_info info); napi_value OnSetAutoStartEnabled(napi_env env, napi_callback_info info); + napi_value OnUpdateContentNode(napi_env env, napi_callback_info info); napi_value OnUpdateContentSize(napi_env env, napi_callback_info info); napi_value OnUpdatePiPControlStatus(napi_env env, napi_callback_info info); napi_value OnSetPiPControlEnabled(napi_env env, napi_callback_info info); diff --git a/interfaces/kits/napi/picture_in_picture_napi/js_pip_window_listener.cpp b/interfaces/kits/napi/picture_in_picture_napi/js_pip_window_listener.cpp index 1889d31b67..b2442b0b5e 100644 --- a/interfaces/kits/napi/picture_in_picture_napi/js_pip_window_listener.cpp +++ b/interfaces/kits/napi/picture_in_picture_napi/js_pip_window_listener.cpp @@ -81,10 +81,6 @@ void JsPiPWindowListener::OnPictureInPictureOperationError(int32_t errorCode) void JsPiPWindowListener::OnPipListenerCallback(PiPState state, int32_t errorCode) { TLOGI(WmsLogTag::WMS_PIP, "state: %{public}d", static_cast(state)); - if (PictureInPictureManager::innerCallbackRef_ != nullptr) { - napi_value value[] = { CreateJsValue(env_, static_cast(state))}; - CallJsFunction(env_, PictureInPictureManager::innerCallbackRef_->GetNapiValue(), value, ArraySize(value)); - } auto napiTask = [jsCallback = jsCallBack_, state, errorCode, env = env_]() { napi_value argv[] = {CreateJsValue(env, static_cast(state)), CreateJsValue(env, errorCode)}; CallJsFunction(env, jsCallback->GetNapiValue(), argv, ArraySize(argv)); diff --git a/patch b/patch new file mode 100644 index 0000000000..9aac2d9a8b --- /dev/null +++ b/patch @@ -0,0 +1,986 @@ +diff --git a/interfaces/kits/napi/picture_in_picture_napi/inner/js_pip_manager.cpp b/interfaces/kits/napi/picture_in_picture_napi/inner/js_pip_manager.cpp +index 1a2583b07..a0a62dc33 100644 +--- a/interfaces/kits/napi/picture_in_picture_napi/inner/js_pip_manager.cpp ++++ b/interfaces/kits/napi/picture_in_picture_napi/inner/js_pip_manager.cpp +@@ -25,6 +25,14 @@ using namespace Ace; + namespace { + constexpr int32_t NUMBER_ONE = 1; + constexpr int32_t NUMBER_TWO = 2; ++ const std::set PIP_CONTENT_CALLBACK {"stateChange", "nodeUpdate"}; ++} ++ ++napi_valuetype GetType(napi_env env, napi_value value) ++{ ++ napi_valuetype res = napi_undefined; ++ napi_typeof(env, value, &res); ++ return res; + } + + napi_value NapiGetUndefined(napi_env env) +@@ -179,6 +187,36 @@ napi_value JsPipManager::OnSetTypeNodeEnabled(napi_env env, napi_callback_info i + return NapiGetUndefined(env); + } + ++napi_value JsPipManager::SetPipNodeType(napi_env env, napi_callback_info info) ++{ ++ JsPipManager* me = CheckParamsAndGetThis(env, info); ++ return (me != nullptr) ? me->OnSetPipNodeType(env, info) : nullptr; ++} ++ ++napi_value JsPipManager::OnSetPipNodeType(napi_env env, napi_callback_info info) ++{ ++ TLOGD(WmsLogTag::WMS_PIP, "[NAPI]"); ++ size_t argc = 4; // 4: arg number ++ napi_value argv[4] = { nullptr }; ++ napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr); ++ if (argc != NUMBER_TWO) { ++ TLOGE(WmsLogTag::WMS_PIP, "[NAPI]Argc count is invalid: %{public}zu", argc); ++ return NapiGetUndefined(env); ++ } ++ napi_value typeNode = argv[0]; ++ bool markPip = false; ++ if (!ConvertFromJsValue(env, argv[1], markPip)) { ++ TLOGW(WmsLogTag::WMS_PIP, "Failed to convert param to bool"); ++ } ++ if (typeNode != nullptr && GetType(env, typeNode) != napi_undefined) { ++ XComponentControllerErrorCode ret = XComponentController::SetSurfaceCallbackMode(env, typeNode, markPip ? ++ SurfaceCallbackMode::PIP: SurfaceCallbackMode::DEFAULT); ++ TLOGI(WmsLogTag::WMS_PIP, "set surface mode, ret: %{public}u, isPip: %{public}d", ++ static_cast(ret), static_cast(markPip)); ++ } ++ return NapiGetUndefined(env); ++} ++ + napi_value JsPipManager::RegisterCallback(napi_env env, napi_callback_info info) + { + JsPipManager* me = CheckParamsAndGetThis(env, info); +@@ -207,6 +245,11 @@ napi_value JsPipManager::OnRegisterCallback(napi_env env, napi_callback_info inf + TLOGE(WmsLogTag::WMS_PIP, "Failed to convert param to cbType"); + return NapiThrowInvalidParam(env); + } ++ auto iter = std::find(PIP_CONTENT_CALLBACK.begin(), PIP_CONTENT_CALLBACK.end(), cbType); ++ if (iter == PIP_CONTENT_CALLBACK.end()) { ++ TLOGE(WmsLogTag::WMS_PIP, "Callback is null or not callable"); ++ return NapiThrowInvalidParam(env); ++ } + napi_value value = argv[1]; + if (value == nullptr || !NapiIsCallable(env, value)) { + TLOGE(WmsLogTag::WMS_PIP, "Callback is null or not callable"); +@@ -215,8 +258,20 @@ napi_value JsPipManager::OnRegisterCallback(napi_env env, napi_callback_info inf + std::shared_ptr callbackRef; + napi_ref result = nullptr; + napi_create_reference(env, value, 1, &result); +- callbackRef.reset(reinterpret_cast(result)); +- PictureInPictureManager::innerCallbackRef_ = callbackRef; ++ callbackRef.reset(reinterpret_cast(result)); ++ sptr pipWindow = Window::Find(PIP_WINDOW_NAME); ++ int32_t windowId = static_cast(pipWindow->GetWindowId()); ++ sptr pipController = PictureInPictureManager::GetPipControllerInfo(windowId); ++ if (pipController == nullptr) { ++ TLOGE(WmsLogTag::WMS_PIP, "Failed to get pictureInPictureController"); ++ return NapiGetUndefined(env); ++ } ++ TLOGI(WmsLogTag::WMS_PIP, "OnRegisterCallback to window: %{public}u", windowId); ++ WMError errCode = pipController->RegisterPipContentListenerWithType(cbType, callbackRef); ++ if (errCode != WMError::WM_OK) { ++ TLOGE(WmsLogTag::WMS_PIP, "Failed to registerCallback"); ++ return NapiGetUndefined(env); ++ } + TLOGI(WmsLogTag::WMS_PIP, "Register type %{public}s success!", cbType.c_str()); + return NapiGetUndefined(env); + } +@@ -230,7 +285,37 @@ napi_value JsPipManager::UnregisterCallback(napi_env env, napi_callback_info inf + napi_value JsPipManager::OnUnregisterCallback(napi_env env, napi_callback_info info) + { + TLOGI(WmsLogTag::WMS_PIP, "[NAPI]"); +- PictureInPictureManager::innerCallbackRef_ = nullptr; ++ size_t argc = 4; ++ napi_value argv[4] = {nullptr}; ++ napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr); ++ if (argc != NUMBER_ONE) { ++ TLOGE(WmsLogTag::WMS_PIP, "Params count not match: %{public}zu", argc); ++ return NapiThrowInvalidParam(env); ++ } ++ std::string cbType; ++ if (!ConvertFromJsValue(env, argv[0], cbType)) { ++ TLOGE(WmsLogTag::WMS_PIP, "Failed to convert param to cbType"); ++ return NapiThrowInvalidParam(env); ++ } ++ auto iter = std::find(PIP_CONTENT_CALLBACK.begin(), PIP_CONTENT_CALLBACK.end(), cbType); ++ if (iter == PIP_CONTENT_CALLBACK.end()) { ++ TLOGE(WmsLogTag::WMS_PIP, "Callback is null or not callable"); ++ return NapiThrowInvalidParam(env); ++ } ++ sptr pipWindow = Window::Find(PIP_WINDOW_NAME); ++ int32_t windowId = static_cast(pipWindow->GetWindowId()); ++ sptr pipController = PictureInPictureManager::GetPipControllerInfo(windowId); ++ if (pipController == nullptr) { ++ TLOGE(WmsLogTag::WMS_PIP, "Failed to get pictureInPictureController"); ++ return NapiGetUndefined(env); ++ } ++ TLOGI(WmsLogTag::WMS_PIP, "UnRegisterPipContentListenerWithType to window: %{public}u", windowId); ++ WMError errCode = pipController->UnRegisterPipContentListenerWithType(cbType); ++ if (errCode != WMError::WM_OK) { ++ TLOGE(WmsLogTag::WMS_PIP, "Failed to set UnRegisterPipContentListenerWithType"); ++ return NapiGetUndefined(env); ++ } ++ TLOGI(WmsLogTag::WMS_PIP, "unregister type %{public}s success!", cbType.c_str()); + return NapiGetUndefined(env); + } + +@@ -250,6 +335,7 @@ napi_value JsPipManagerInit(napi_env env, napi_value exportObj) + BindNativeFunction(env, exportObj, "on", moduleName, JsPipManager::RegisterCallback); + BindNativeFunction(env, exportObj, "off", moduleName, JsPipManager::UnregisterCallback); + BindNativeFunction(env, exportObj, "setTypeNodeEnabled", moduleName, JsPipManager::SetTypeNodeEnabled); ++ BindNativeFunction(env, exportObj, "setPipNodeType", moduleName, JsPipManager::SetPipNodeType); + return NapiGetUndefined(env); + } + } // namespace Rosen +diff --git a/interfaces/kits/napi/picture_in_picture_napi/inner/js_pip_manager.h b/interfaces/kits/napi/picture_in_picture_napi/inner/js_pip_manager.h +index 90ae2aa86..a926cbcaf 100644 +--- a/interfaces/kits/napi/picture_in_picture_napi/inner/js_pip_manager.h ++++ b/interfaces/kits/napi/picture_in_picture_napi/inner/js_pip_manager.h +@@ -32,6 +32,7 @@ public: + static napi_value RegisterCallback(napi_env env, napi_callback_info info); + static napi_value UnregisterCallback(napi_env env, napi_callback_info info); + static napi_value SetTypeNodeEnabled(napi_env env, napi_callback_info info); ++ static napi_value SetPipNodeType(napi_env env, napi_callback_info info); + private: + napi_value OnInitXComponentController(napi_env env, napi_callback_info info); + napi_value OnGetCustomUIController(napi_env env, napi_callback_info info); +@@ -39,6 +40,7 @@ private: + napi_value OnRegisterCallback(napi_env env, napi_callback_info info); + napi_value OnUnregisterCallback(napi_env env, napi_callback_info info); + napi_value OnSetTypeNodeEnabled(napi_env env, napi_callback_info info); ++ napi_value OnSetPipNodeType(napi_env env, napi_callback_info info); + }; + } // namespace Rosen + } // namespace OHOS +diff --git a/interfaces/kits/napi/picture_in_picture_napi/js_pip_controller.cpp b/interfaces/kits/napi/picture_in_picture_napi/js_pip_controller.cpp +index ef816c55d..68045a1eb 100644 +--- a/interfaces/kits/napi/picture_in_picture_napi/js_pip_controller.cpp ++++ b/interfaces/kits/napi/picture_in_picture_napi/js_pip_controller.cpp +@@ -36,6 +36,7 @@ void BindFunctions(napi_env env, napi_value object, const char* moduleName) + { + BindNativeFunction(env, object, "startPiP", moduleName, JsPipController::StartPictureInPicture); + BindNativeFunction(env, object, "stopPiP", moduleName, JsPipController::StopPictureInPicture); ++ BindNativeFunction(env, object, "updateContentNode", moduleName, JsPipController::UpdateContentNode); + BindNativeFunction(env, object, "updateContentSize", moduleName, JsPipController::UpdateContentSize); + BindNativeFunction(env, object, "updatePiPControlStatus", moduleName, JsPipController::UpdatePiPControlStatus); + BindNativeFunction(env, object, "setAutoStartEnabled", moduleName, JsPipController::SetAutoStartEnabled); +@@ -186,6 +187,38 @@ napi_value JsPipController::OnSetAutoStartEnabled(napi_env env, napi_callback_in + return NapiGetUndefined(env); + } + ++napi_value JsPipController::UpdateContentNode(napi_env env, napi_callback_info info) ++{ ++ JsPipController *me = CheckParamsAndGetThis(env, info); ++ return (me != nullptr) ? me->OnUpdateContentNode(env, info) : nullptr; ++} ++ ++napi_value JsPipController::OnUpdateContentNode(napi_env env, napi_callback_info info) ++{ ++ TLOGI(WmsLogTag::WMS_PIP, "OnUpdateContentNode is called"); ++ size_t argc = 4; ++ napi_value argv[4] = {nullptr}; ++ napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr); ++ if (argc != NUMBER_ONE) { ++ TLOGE(WmsLogTag::WMS_PIP, "[NAPI]Argc count is invalid: %{public}zu", argc); ++ return NapiThrowInvalidParam(env, "Invalid args count, 1 arg is needed."); ++ } ++ napi_value typeNode = argv[0]; ++ if (typeNode == nullptr || GetType(env, typeNode) == napi_undefined) { ++ TLOGE(WmsLogTag::WMS_PIP, "[NAPI] invalid typeNode"); ++ return NapiThrowInvalidParam(env, "invalid typeNode."); ++ } ++ if (pipController_ == nullptr) { ++ std::string errMsg = "OnUpdateNode error, controller is nullptr"; ++ TLOGE(WmsLogTag::WMS_PIP, "%{public}s", errMsg.c_str()); ++ return NapiThrowInvalidParam(env, errMsg); ++ } ++ napi_ref typeNodeRef = nullptr; ++ napi_create_reference(env, typeNode, 1, &typeNodeRef); ++ pipController_->UpdateContentNodeRef(typeNodeRef); ++ return NapiGetUndefined(env); ++} ++ + napi_value JsPipController::UpdateContentSize(napi_env env, napi_callback_info info) + { + JsPipController* me = CheckParamsAndGetThis(env, info); +diff --git a/interfaces/kits/napi/picture_in_picture_napi/js_pip_controller.h b/interfaces/kits/napi/picture_in_picture_napi/js_pip_controller.h +index 166f9c8f7..b81ed1d64 100644 +--- a/interfaces/kits/napi/picture_in_picture_napi/js_pip_controller.h ++++ b/interfaces/kits/napi/picture_in_picture_napi/js_pip_controller.h +@@ -34,6 +34,7 @@ public: + static napi_value StartPictureInPicture(napi_env env, napi_callback_info info); + static napi_value StopPictureInPicture(napi_env env, napi_callback_info info); + static napi_value SetAutoStartEnabled(napi_env env, napi_callback_info info); ++ static napi_value UpdateContentNode(napi_env env, napi_callback_info info); + static napi_value UpdateContentSize(napi_env env, napi_callback_info info); + static napi_value UpdatePiPControlStatus(napi_env env, napi_callback_info info); + static napi_value SetPiPControlEnabled(napi_env env, napi_callback_info info); +@@ -49,6 +50,7 @@ private: + napi_value OnStartPictureInPicture(napi_env env, napi_callback_info info); + napi_value OnStopPictureInPicture(napi_env env, napi_callback_info info); + napi_value OnSetAutoStartEnabled(napi_env env, napi_callback_info info); ++ napi_value OnUpdateContentNode(napi_env env, napi_callback_info info); + napi_value OnUpdateContentSize(napi_env env, napi_callback_info info); + napi_value OnUpdatePiPControlStatus(napi_env env, napi_callback_info info); + napi_value OnSetPiPControlEnabled(napi_env env, napi_callback_info info); +diff --git a/interfaces/kits/napi/picture_in_picture_napi/js_pip_window_listener.cpp b/interfaces/kits/napi/picture_in_picture_napi/js_pip_window_listener.cpp +index 1889d31b6..b2442b0b5 100644 +--- a/interfaces/kits/napi/picture_in_picture_napi/js_pip_window_listener.cpp ++++ b/interfaces/kits/napi/picture_in_picture_napi/js_pip_window_listener.cpp +@@ -81,10 +81,6 @@ void JsPiPWindowListener::OnPictureInPictureOperationError(int32_t errorCode) + void JsPiPWindowListener::OnPipListenerCallback(PiPState state, int32_t errorCode) + { + TLOGI(WmsLogTag::WMS_PIP, "state: %{public}d", static_cast(state)); +- if (PictureInPictureManager::innerCallbackRef_ != nullptr) { +- napi_value value[] = { CreateJsValue(env_, static_cast(state))}; +- CallJsFunction(env_, PictureInPictureManager::innerCallbackRef_->GetNapiValue(), value, ArraySize(value)); +- } + auto napiTask = [jsCallback = jsCallBack_, state, errorCode, env = env_]() { + napi_value argv[] = {CreateJsValue(env, static_cast(state)), CreateJsValue(env, errorCode)}; + CallJsFunction(env, jsCallback->GetNapiValue(), argv, ArraySize(argv)); +diff --git a/resources/abc/pip/interface/PiPContent.js b/resources/abc/pip/interface/PiPContent.js +index 66cf09c12..6320b7e29 100644 +--- a/resources/abc/pip/interface/PiPContent.js ++++ b/resources/abc/pip/interface/PiPContent.js +@@ -34,6 +34,14 @@ class XCNodeController extends NodeController { + return this.node; + } + ++ replaceNode(r2) { ++ let s2; ++ let t2; ++ (s2 = this.node) === null || s2 === void 0 ? void 0 : s2.removeChild(this.mXComponent); ++ this.mXComponent = r2; ++ (t2 = this.node) === null || t2 === void 0 ? void 0 : t2.appendChild(this.mXComponent); ++ } ++ + removeNode() { + let h2; + (h2 = this.node) === null || h2 === void 0 ? void 0 : h2.removeChild(this.mXComponent); +@@ -49,7 +57,8 @@ class PiPContent extends ViewPU { + this.xComponentController = new XComponentController; + this.nodeController = null; + this.mXCNodeController = null; +- this.useNode = false; ++ this.__useNode = new ObservedPropertySimplePU(false, this, 'useNode'); ++ this.__nodeChange = new ObservedPropertySimplePU(false, this, 'nodeChange'); + this.xComponentId = 'pipContent'; + this.xComponentType = 'surface'; + this.xComponent = null; +@@ -69,6 +78,9 @@ class PiPContent extends ViewPU { + if (a2.useNode !== undefined) { + this.useNode = a2.useNode; + } ++ if (a2.nodeChange !== undefined) { ++ this.nodeChange = a2.nodeChange; ++ } + if (a2.xComponentId !== undefined) { + this.xComponentId = a2.xComponentId; + } +@@ -83,41 +95,107 @@ class PiPContent extends ViewPU { + updateStateVars(z1) { + } + +- purgeVariableDependenciesOnElmtId(y1) { ++ purgeVariableDependenciesOnElmtId(h2) { ++ this.__useNode.purgeDependencyOnElmtId(h2); ++ this.__nodeChange.purgeDependencyOnElmtId(h2); ++ } ++ ++ aboutToBeDeleted() { ++ this.__useNode.aboutToBeDeleted(); ++ this.__nodeChange.aboutToBeDeleted(); ++ SubscriberManager.Get().delete(this.id__()); ++ this.aboutToBeDeletedInternal(); ++ } ++ ++ get useNode() { ++ return this.__useNode.get(); ++ } ++ ++ set useNode(b) { ++ this.__useNode.set(b); ++ } ++ ++ get nodeChange() { ++ return this.__nodeChange.get(); ++ } ++ ++ set nodeChange(a) { ++ this.__nodeChange.set(a); ++ } ++ ++ validateNode(f2) { ++ if (f2 === null || f2 === undefined) { ++ console.error(TAG, `validateNode node is null`); ++ return false; ++ } ++ let g2 = f2.getNodeType(); ++ if (g2 !== 'XComponent') { ++ console.error(TAG, `node type mismatch: ${g2}`); ++ return false; ++ } ++ return true; + } + + aboutToAppear() { + this.nodeController = pip.getCustomUIController(); ++ this.registerUpdateNodeListener(); + this.xComponent = pip.getTypeNode(); +- if (this.xComponent === null || this.xComponent === undefined) { +- console.error(TAG, `xComponent node is null`); +- return; +- } +- let u1 = this.xComponent.getNodeType(); +- if (u1 !== 'XComponent') { +- console.error(`xComponent type mismatch: ${u1}`); ++ if (!this.validateNode(this.xComponent)) { + return; + } ++ this.updatePipNodeType(this.xComponent); + this.useNode = true; + pip.setTypeNodeEnabled(); + this.mXCNodeController = new XCNodeController(this.xComponent); + console.info(TAG, 'use Node Controller'); +- pip.on('stateChange', (w1) => { +- let x1; +- console.info(TAG, `stateChange state: ${w1}`); +- if (w1 === ABOUT_TO_STOP) { +- (x1 = this.mXCNodeController) === null || x1 === void 0 ? void 0 : x1.removeNode(); ++ this.registerStateChangeListener(); ++ } ++ ++ registerStateChangeListener() { ++ pip.on('stateChange', (y1) => { ++ let z1; ++ console.info(TAG, `stateChange state:${y1}`); ++ if (y1 === ABOUT_TO_STOP) { ++ (z1 = this.mXCNodeController) === null || z1 === void 0 ? void 0 : z1.removeNode(); + } + }); + } + +- aboutToBeDeleted() { +- SubscriberManager.Get().delete(this.id__()); +- this.aboutToBeDeletedInternal(); ++ registerUpdateNodeListener() { ++ pip.on('nodeUpdate', (d2) => { ++ let e2; ++ console.info(TAG, `nodeUpdate`); ++ if (!this.validateNode(d2)) { ++ return; ++ } ++ if (this.useNode) { ++ this.updatePipNodeType(d2); ++ (e2 = this.mXCNodeController) === null || e2 === void 0 ? void 0 : e2.replaceNode(d2); ++ this.nodeChange = true; ++ } else { ++ this.updatePipNodeType(d2); ++ this.mXCNodeController = new XCNodeController(d2); ++ console.info(TAG, 'update to Node Controller'); ++ this.registerStateChangeListener(); ++ this.useNode = true; ++ } ++ }); + } + ++ updatePipNodeType(a2) { ++ let b2 = a2.getParent(); ++ if (b2 === null || b2 === undefined) { ++ pip.setPipNodeType(a2, false); ++ } else { ++ pip.setPipNodeType(a2, true); ++ b2.removeChild(a2); ++ } ++ } ++ ++ + aboutToDisappear() { + pip.off('stateChange'); ++ pip.off('nodeUpdate'); + } + + initialRender() { +@@ -127,7 +205,7 @@ class PiPContent extends ViewPU { + }, Stack); + this.observeComponentCreation2((h1, i1) => { + If.create(); +- if (this.useNode) { ++ if (this.useNode || this.nodeChange) { + this.ifElseBranchUpdateFunction(0, () => { + this.buildNode.bind(this)(); + }); +diff --git a/resources/abc/pip/source/PiPContent.ets b/resources/abc/pip/source/PiPContent.ets +index 47ab75216..bd715e5dc 100644 +--- a/resources/abc/pip/source/PiPContent.ets ++++ b/resources/abc/pip/source/PiPContent.ets +@@ -20,10 +20,10 @@ const TAG: string = 'PiPContent'; + const ABOUT_TO_STOP = 3; + + class XCNodeController extends NodeController { +- private mXComponent: TypedFrameNode; ++ private mXComponent: typeNode.XComponent; + private node: FrameNode | null = null; + +- constructor(xComponent: TypedFrameNode) { ++ constructor(xComponent: typeNode.XComponent) { + super(); + this.mXComponent = xComponent; + } +@@ -34,6 +34,12 @@ class XCNodeController extends NodeController { + return this.node; + } + ++ replaceNode(newNode: typeNode.XComponent): void { ++ this.node?.removeChild(this.mXComponent); ++ this.mXComponent = newNode; ++ this.node?.appendChild(this.mXComponent); ++ } ++ + removeNode() { + this.node?.removeChild(this.mXComponent); + } +@@ -45,46 +51,91 @@ struct PiPContent { + private xComponentController: XComponentController = new XComponentController(); + private nodeController: NodeController | null = null; + private mXCNodeController: XCNodeController | null = null; +- private useNode: boolean = false; +- private xComponent: TypedFrameNode | null = null; ++ @State useNode: boolean = false; ++ @State nodeChange: boolean = false; ++ private xComponent: typeNode.XComponent | null = null; + xComponentId: string = 'pipContent'; + xComponentType: string = 'surface'; + ++ validateNode(node: typeNode.XComponent | null): boolean { ++ if (node === null || node === undefined) { ++ console.error(TAG, `validateNode node is null`); ++ return false; ++ } ++ let type: string = node.getNodeType(); ++ if (type !== 'XComponent') { ++ console.error(TAG, `node type mismatch: ${type}`); ++ return false; ++ } ++ return true; ++ } ++ ++ private registerUpdateNodeListener() { ++ pip.on('nodeUpdate', (newNode: typeNode.XComponent) => { ++ console.info(TAG, `nodeUpdate`); ++ if (!this.validateNode(newNode)) { ++ return; ++ } ++ if (this.useNode) { ++ pip.setPipNodeType(this.xComponent, false); ++ this.updatePipNodeType(newNode); ++ this.mXCNodeController?.replaceNode(newNode); ++ this.nodeChange = true; ++ } else { ++ this.updatePipNodeType(newNode); ++ this.mXCNodeController = new XCNodeController(newNode); ++ console.info(TAG, 'update to Node Controller'); ++ this.registerStateChangeListener(); ++ this.useNode = true; ++ } ++ }); ++ } ++ ++ private updatePipNodeType(newNode: typeNode.XComponent) { ++ let parent: FrameNode | null = newNode.getParent(); ++ if (parent === null || parent === undefined) { ++ pip.setPipNodeType(newNode, false); ++ } else { ++ pip.setPipNodeType(newNode, true); ++ parent.removeChild(newNode); ++ } ++ } ++ ++ private registerStateChangeListener() { ++ pip.on('stateChange', (state: number) => { ++ console.info(TAG, `stateChange state:${state}`); ++ if (state === ABOUT_TO_STOP) { ++ this.mXCNodeController?.removeNode(); ++ } ++ }) ++ } ++ + aboutToAppear(): void { + this.nodeController = pip.getCustomUIController(); ++ this.registerUpdateNodeListener(); + this.xComponent = pip.getTypeNode(); +- if (this.xComponent === null || this.xComponent === undefined) { +- console.error(TAG, `xComponent node is null`); +- return; +- } +- let type: string = this.xComponent.getNodeType(); +- if (type !== 'XComponent') { +- console.error(TAG, `xComponent type mismatch: ${type}`); ++ if (!this.validateNode(this.xComponent)) { + return; + } + this.useNode = true; ++ this.updatePipNodeType(this.xComponent); + pip.setTypeNodeEnabled(); + this.mXCNodeController = new XCNodeController(this.xComponent); + console.info(TAG, 'use Node Controller'); +- +- pip.on('stateChange', (state: number) => { +- console.info(TAG, `stateChange state:${state}`); +- if (state === ABOUT_TO_STOP) { +- this.mXCNodeController?.removeNode(); +- } +- }) ++ this.registerStateChangeListener(); + } + + aboutToDisappear(): void { + pip.off('stateChange'); ++ pip.off('nodeUpdate'); + } + + build() { + Stack() { +- if (this.useNode) { ++ if (this.useNode || this.nodeChange) { + this.buildNode(); + } else { +- this.buildXComponent(); ++ this.buildXComponent(); + } + if (this.nodeController !== null) { + this.buildCustomUI(); +diff --git a/utils/include/pip_report.h b/utils/include/pip_report.h +index 967fcecf0..ab4a1ef55 100644 +--- a/utils/include/pip_report.h ++++ b/utils/include/pip_report.h +@@ -32,6 +32,7 @@ public: + void ReportPiPControlEvent(int32_t templateType, PiPControlType controlType); + void ReportPiPRatio(int32_t windowWidth, int32_t windowHeight); + void ReportPiPRestore(); ++ void ReportPiPUpdateContent(); + private: + std::string GetPackageName() const; + std::string packageName_ = ""; +diff --git a/utils/src/pip_report.cpp b/utils/src/pip_report.cpp +index 4a8bc2f63..4536a5ec8 100644 +--- a/utils/src/pip_report.cpp ++++ b/utils/src/pip_report.cpp +@@ -174,5 +174,19 @@ void PiPReporter::ReportPiPRestore() + EVENT_KEY_OPERATION_PACKAGE_NAME, GetPackageName()); + LOG_WHEN_ERROR(ret); + } ++ ++void PiPReporter::ReportPiPUpdateContent() ++{ ++ TLOGI(WmsLogTag::WMS_PIP, "Report pip widow update typeNode"); ++ std::string eventName = "updateContent_PIP"; ++ int32_t ret = HiSysEventWrite( ++ OHOS::HiviewDFX::HiSysEvent::Domain::MULTIWINDOW_UE, eventName, ++ OHOS::HiviewDFX::HiSysEvent::EventType::BEHAVIOR, ++ EVENT_KEY_PNAMEID, PNAMEID, ++ EVENT_KEY_PVERSION, PVERSION, ++ EVENT_KEY_OPERATION_PACKAGE_NAME, GetPackageName()); ++ LOG_WHEN_ERROR(ret); ++} ++ + } // namespace Rosen + } // namespace OHOS +diff --git a/wm/include/picture_in_picture_controller.h b/wm/include/picture_in_picture_controller.h +index 3c11014e8..ea7944840 100644 +--- a/wm/include/picture_in_picture_controller.h ++++ b/wm/include/picture_in_picture_controller.h +@@ -72,6 +72,7 @@ public: + void SetAutoStartEnabled(bool enable); + void IsAutoStartEnabled(bool& enable) const; + void UpdateContentSize(int32_t width, int32_t height); ++ void UpdateContentNodeRef(napi_ref nodeRef); + void UpdatePiPControlStatus(PiPControlType controlType, PiPControlStatus status); + bool IsContentSizeChanged(float width, float height, float posX, float posY); + void DoActionEvent(const std::string& actionName, int32_t status); +@@ -89,6 +90,9 @@ public: + sptr GetPictureInPictureLifecycle() const; + sptr GetPictureInPictureActionObserver() const; + sptr GetPictureInPictureControlObserver() const; ++ std::shared_ptr GetPipContentCallbackRef(std::string); ++ WMError RegisterPipContentListenerWithType(std::string, std::shared_ptr updateNodeCallbackRef); ++ WMError UnRegisterPipContentListenerWithType(std::string); + WMError SetXComponentController(std::shared_ptr xComponentController); + PiPWindowState GetControllerState(); + std::string GetPiPNavigationId(); +@@ -113,6 +117,8 @@ private: + void UpdatePiPSourceRect() const; + void ResetExtController(); + bool IsPullPiPAndHandleNavigation(); ++ void NotifyNodeUpdate(napi_ref nodeRef); ++ void NotifyStateChangeInner(napi_env env, PiPState state); + template WMError RegisterListener(std::vector>& holder, const sptr& listener); + template WMError UnregisterListener(std::vector>& holder, const sptr& listener); + wptr weakRef_ = nullptr; +diff --git a/wm/include/picture_in_picture_option.h b/wm/include/picture_in_picture_option.h +index c4db609fd..13cfeb90b 100644 +--- a/wm/include/picture_in_picture_option.h ++++ b/wm/include/picture_in_picture_option.h +@@ -20,6 +20,7 @@ + #include "xcomponent_controller.h" + #include "napi/native_api.h" + #include "wm_common.h" ++#include "js_runtime_utils.h" + + namespace OHOS { + namespace Rosen { +@@ -35,6 +36,7 @@ public: + void SetPiPControlStatus(PiPControlType controlType, PiPControlStatus status); + void SetPiPControlEnabled(PiPControlType controlType, PiPControlStatus enabled); + void SetXComponentController(std::shared_ptr xComponentController); ++ void RegisterPipContentListenerWithType(std::string, std::shared_ptr updateNodeCallbackRef); + void SetControlGroup(std::vector controlGroup); + void* GetContext() const; + std::string GetNavigationId() const; +@@ -44,6 +46,8 @@ public: + std::vector GetControlEnable(); + void GetContentSize(uint32_t& width, uint32_t& height); + std::shared_ptr GetXComponentController(); ++ std::shared_ptr GetPipContentCallbackRef(std::string); ++ void UnRegisterPipContentListenerWithType(std::string); + void SetNodeControllerRef(napi_ref ref); + napi_ref GetNodeControllerRef() const; + void SetTypeNodeRef(napi_ref ref); +@@ -60,6 +64,7 @@ private: + std::vector pipControlEnableInfoList_; + std::vector controlGroup_; + std::shared_ptr xComponentController_ = nullptr; ++ std::map> pipContentlistenerMap_; + napi_ref customNodeController_ = nullptr; + napi_ref typeNode_ = nullptr; + bool useTypeNode_ = false; +diff --git a/wm/src/picture_in_picture_controller.cpp b/wm/src/picture_in_picture_controller.cpp +index f75184799..da55e93a9 100644 +--- a/wm/src/picture_in_picture_controller.cpp ++++ b/wm/src/picture_in_picture_controller.cpp +@@ -31,9 +31,26 @@ namespace { + constexpr uint32_t PIP_HIGH_PRIORITY = 1; + const std::string PIP_CONTENT_PATH = "/system/etc/window/resources/pip_content.abc"; + const std::string DESTROY_TIMEOUT_TASK = "PipDestroyTimeout"; ++ const std::string STATE_CHANGE = "stateChange"; ++ const std::string UPDATE_NODE = "nodeUpdate"; + const int DEFAULT_ASPECT_RATIO[] = {16, 9}; + } + ++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; ++} ++ + uint32_t PictureInPictureController::GetPipPriority(uint32_t pipTemplateType) + { + if (pipTemplateType >= static_cast(PiPTemplateType::END)) { +@@ -125,6 +142,7 @@ WMError PictureInPictureController::ShowPictureInPictureWindow(StartPipType star + pipOption_->GetPipTemplate(), FAILED, "window is nullptr"); + return WMError::WM_ERROR_PIP_STATE_ABNORMALLY; + } ++ NotifyStateChangeInner(env_, PiPState::ABOUT_TO_START); + for (auto& listener : pipLifeCycleListeners_) { + listener->OnPreparePictureInPictureStart(); + } +@@ -279,12 +297,14 @@ WMError PictureInPictureController::StopPictureInPicture(bool destroyWindow, Sto + return WMError::WM_ERROR_PIP_STATE_ABNORMALLY; + } + curState_ = PiPWindowState::STATE_STOPPING; ++ NotifyStateChangeInner(env_, PiPState::ABOUT_TO_STOP); + for (auto& listener : pipLifeCycleListeners_) { + listener->OnPreparePictureInPictureStop(); + } + if (!destroyWindow) { + ResetExtController(); + curState_ = PiPWindowState::STATE_STOPPED; ++ NotifyStateChangeInner(env_, PiPState::STOPPED); + for (auto& listener : pipLifeCycleListeners_) { + listener->OnPictureInPictureStop(); + } +@@ -360,6 +380,7 @@ WMError PictureInPictureController::DestroyPictureInPictureWindow() + mainWindowLifeCycleListener_ = nullptr; + PictureInPictureManager::RemovePipControllerInfo(window_->GetWindowId()); + window_ = nullptr; ++ NotifyStateChangeInner(env_, PiPState::STOPPED); + PictureInPictureManager::RemoveActiveController(this); + return WMError::WM_OK; + } +@@ -462,6 +483,53 @@ void PictureInPictureController::UpdateContentSize(int32_t width, int32_t height + SingletonContainer::Get().ReportPiPRatio(width, height); + } + ++void PictureInPictureController::UpdateContentNodeRef(napi_ref nodeRef) ++{ ++ TLOGI(WmsLogTag::WMS_PIP, "in"); ++ SingletonContainer::Get().ReportPiPUpdateContent(); ++ if (pipOption_ == nullptr) { ++ TLOGE(WmsLogTag::WMS_PIP, "Get PictureInPicture option failed"); ++ return; ++ } ++ pipOption_->SetTypeNodeRef(nodeRef); ++ if (IsTypeNodeEnabled()) { ++ NotifyNodeUpdate(nodeRef); ++ return; ++ } ++ ResetExtController(); ++ NotifyNodeUpdate(nodeRef); ++ if (isAutoStartEnabled_) { ++ std::string navId = pipOption_->GetNavigationId(); ++ if (!navId.empty()) { ++ auto navController = NavigationController::GetNavigationController(mainWindow_->GetUIContent(), navId); ++ if (navController) { ++ navController->DeletePIPMode(handleId_); ++ TLOGI(WmsLogTag::WMS_PIP, "Delete pip mode id: %{public}d", handleId_); ++ } ++ } ++ } ++ pipOption_->SetTypeNodeEnabled(true); ++} ++ ++void PictureInPictureController::NotifyNodeUpdate(napi_ref nodeRef) ++{ ++ TLOGI(WmsLogTag::WMS_PIP, "in"); ++ if (nodeRef == nullptr) { ++ TLOGE(WmsLogTag::WMS_PIP, "invalid nodeRef"); ++ return; ++ } ++ if (PictureInPictureManager::IsActiveController(weakRef_)) { ++ std::shared_ptr updateNodeCallbackRef = GetPipContentCallbackRef(UPDATE_NODE); ++ if (updateNodeCallbackRef == nullptr) { ++ TLOGE(WmsLogTag::WMS_PIP, "updateNodeCallbackRef is null"); ++ return; ++ } ++ napi_value typeNode = nullptr; ++ napi_get_reference_value(env_, nodeRef, &typeNode); ++ napi_value value[] = {typeNode}; ++ CallJsFunction(env_, updateNodeCallbackRef->GetNapiValue(), value, 1); ++ } ++} + + void PictureInPictureController::UpdatePiPControlStatus(PiPControlType controlType, PiPControlStatus status) + { +@@ -507,6 +575,7 @@ void PictureInPictureController::PreRestorePictureInPicture() + { + TLOGI(WmsLogTag::WMS_PIP, "called"); + curState_ = PiPWindowState::STATE_RESTORING; ++ NotifyStateChangeInner(env_, PiPState::ABOUT_TO_RESTORE); + for (auto& listener : pipLifeCycleListeners_) { + listener->OnRestoreUserInterface(); + } +@@ -676,8 +745,47 @@ WMError PictureInPictureController::SetXComponentController(std::shared_ptr callbackRef) ++{ ++ TLOGI(WmsLogTag::WMS_PIP, "called"); ++ if (pipOption_ == nullptr) { ++ TLOGE(WmsLogTag::WMS_PIP, "Get PictureInPicture option failed"); ++ return WMError::WM_ERROR_PIP_STATE_ABNORMALLY; ++ } ++ pipOption_->RegisterPipContentListenerWithType(type, callbackRef); ++ return WMError::WM_OK; ++} ++ ++WMError PictureInPictureController::UnRegisterPipContentListenerWithType(std::string type) ++{ ++ TLOGI(WmsLogTag::WMS_PIP, "called"); ++ if (pipOption_ == nullptr) { ++ TLOGE(WmsLogTag::WMS_PIP, "Get PictureInPicture option failed"); ++ return WMError::WM_ERROR_PIP_STATE_ABNORMALLY; ++ } ++ pipOption_->UnRegisterPipContentListenerWithType(type); ++ return WMError::WM_OK; ++} ++ ++std::shared_ptr PictureInPictureController::GetPipContentCallbackRef(std::string type) ++{ ++ return pipOption_ == nullptr ? nullptr : pipOption_->GetPipContentCallbackRef(type); ++} ++ ++void PictureInPictureController::NotifyStateChangeInner(napi_env env, PiPState state) ++{ ++ std::shared_ptr innerCallbackRef = GetPipContentCallbackRef(STATE_CHANGE); ++ if (innerCallbackRef == nullptr) { ++ return; ++ } ++ napi_value value[] = { AbilityRuntime::CreateJsValue(env, static_cast(state))}; ++ CallJsFunction(env, innerCallbackRef->GetNapiValue(), value, 1); ++} ++ + void PictureInPictureController::OnPictureInPictureStart() + { ++ NotifyStateChangeInner(env_, PiPState::STARTED); + for (auto& listener : pipLifeCycleListeners_) { + listener->OnPictureInPictureStart(); + } +diff --git a/wm/src/picture_in_picture_option.cpp b/wm/src/picture_in_picture_option.cpp +index 29bad7685..725163e0f 100644 +--- a/wm/src/picture_in_picture_option.cpp ++++ b/wm/src/picture_in_picture_option.cpp +@@ -14,6 +14,7 @@ + */ + + #include "picture_in_picture_option.h" ++#include "js_runtime_utils.h" + + namespace OHOS { + namespace Rosen { +@@ -91,6 +92,26 @@ napi_ref PipOption::GetTypeNodeRef() const + return typeNode_; + } + ++void PipOption::RegisterPipContentListenerWithType(std::string type, ++ std::shared_ptr updateNodeCallbackRef) ++{ ++ pipContentlistenerMap_[type] = updateNodeCallbackRef; ++} ++ ++void PipOption::UnRegisterPipContentListenerWithType(std::string type) ++{ ++ pipContentlistenerMap_.erase(type); ++} ++ ++std::shared_ptr PipOption::GetPipContentCallbackRef(std::string type) ++{ ++ auto iter = pipContentlistenerMap_.find(type); ++ if (iter == pipContentlistenerMap_.end()) { ++ return nullptr; ++ } ++ return iter->second; ++} ++ + void* PipOption::GetContext() const + { + return contextPtr_; +diff --git a/wm/test/unittest/picture_in_picture_controller_test.cpp b/wm/test/unittest/picture_in_picture_controller_test.cpp +index 58f40d73d..fe45ff1fa 100644 +--- a/wm/test/unittest/picture_in_picture_controller_test.cpp ++++ b/wm/test/unittest/picture_in_picture_controller_test.cpp +@@ -1108,6 +1108,85 @@ HWTEST_F(PictureInPictureControllerTest, StopPictureInPictureInner, Function | S + ASSERT_EQ(WMError::WM_OK, pipControl->StopPictureInPictureInner(StopPipType::NULL_STOP, true)); + ASSERT_EQ(WMError::WM_OK, pipControl->StopPictureInPictureInner(StopPipType::NULL_STOP, false)); + } ++ ++/** ++@tc.name: RegisterPipContentListenerWithType ++@tc.desc: RegisterPipContentListenerWithType ++@tc.type: FUNC ++*/ ++HWTEST_F(PictureInPictureControllerTest, RegisterPipContentListenerWithType, Function | SmallTest | Level2) ++{ ++ sptr mw = new MockWindow(); ++ sptr option = new PipOption(); ++ sptr pipControl = new PictureInPictureController(option, mw, 100, nullptr); ++ pipControl->pipOption_ = nullptr; ++ std::shared_ptr callBack = nullptr; ++ ASSERT_EQ(WMError::WM_ERROR_PIP_STATE_ABNORMALLY, ++ pipControl->RegisterPipContentListenerWithType("nodeUpdate",callBack)); ++ pipControl->pipOption_ = option; ++ ASSERT_EQ(WMError::WM_OK, pipControl->RegisterPipContentListenerWithType("nodeUpdate",callBack)); ++} ++/** ++ ++@tc.name: UnRegisterPipContentListenerWithType ++@tc.desc: UnRegisterPipContentListenerWithType ++@tc.type: FUNC ++*/ ++HWTEST_F(PictureInPictureControllerTest, UnRegisterPipContentListenerWithType, Function | SmallTest | Level2) ++{ ++ sptr mw = new MockWindow(); ++ sptr option = new PipOption(); ++ sptr pipControl = new PictureInPictureController(option, mw, 100, nullptr); ++ pipControl->pipOption_ = nullptr; ++ std::shared_ptr callBack = nullptr; ++ ASSERT_EQ(WMError::WM_ERROR_PIP_STATE_ABNORMALLY, pipControl->UnRegisterPipContentListenerWithType("nodeUpdate")); ++ pipControl->pipOption_ = option; ++ ASSERT_EQ(WMError::WM_OK, pipControl->UnRegisterPipContentListenerWithType("nodeUpdate")); ++} ++/** ++ ++@tc.name: GetPipContentCallbackRef ++@tc.desc: GetPipContentCallbackRef ++@tc.type: FUNC ++*/ ++HWTEST_F(PictureInPictureControllerTest, GetPipContentCallbackRef, Function | SmallTest | Level2) ++{ ++ sptr mw = new MockWindow(); ++ sptr option = new PipOption(); ++ sptr pipControl = new PictureInPictureController(option, mw, 100, nullptr); ++ pipControl->pipOption_ = nullptr; ++ std::shared_ptr callBack = nullptr; ++ pipControl->RegisterPipContentListenerWithType("nodeUpdate",callBack); ++ ASSERT_EQ(nullptr, pipControl->GetPipContentCallbackRef("nodeUpdate")); ++ pipControl->pipOption_ = option; ++ pipControl->RegisterPipContentListenerWithType("nodeUpdate",callBack); ++ ASSERT_EQ(nullptr, pipControl->GetPipContentCallbackRef("nodeUpdate")); ++} ++/** ++ ++@tc.name: UpdateContentNodeRef ++@tc.desc: UpdateContentNodeRef ++@tc.type: FUNC ++*/ ++HWTEST_F(PictureInPictureControllerTest, UpdateContentNodeRef, Function | SmallTest | Level2) ++{ ++ sptr mw = new MockWindow(); ++ sptr option = new PipOption(); ++ sptr pipControl = new PictureInPictureController(option, mw, 100, nullptr); ++ pipControl->pipOption_ = nullptr; ++ napi_ref nodeRef = nullptr; ++ std::shared_ptr callBack = nullptr; ++ pipControl->UpdateContentNodeRef(nodeRef); ++ pipControl->pipOption_ = option; ++ pipControl->pipOption_->SetTypeNodeEnabled(true); ++ pipControl->UpdateContentNodeRef(nodeRef); ++ pipControl->pipOption_->SetTypeNodeEnabled(false); ++ pipControl->UpdateContentNodeRef(nodeRef); ++ pipControl->isAutoStartEnabled_ = true; ++ pipControl->UpdateContentNodeRef(nodeRef); ++ pipControl->isAutoStartEnabled_ = false; ++ ASSERT_EQ(true, pipControl->IsTypeNodeEnabled()); ++} + } // namespace + } // namespace Rosen + } // namespace OHOS +\ No newline at end of file +diff --git a/wm/test/unittest/picture_in_picture_option_test.cpp b/wm/test/unittest/picture_in_picture_option_test.cpp +index 54935909b..99595da50 100644 +--- a/wm/test/unittest/picture_in_picture_option_test.cpp ++++ b/wm/test/unittest/picture_in_picture_option_test.cpp +@@ -185,6 +185,18 @@ HWTEST_F(PictureInPictureOptionTest, TypeNodeEnabled, Function | SmallTest | Lev + option->SetTypeNodeEnabled(false); + ASSERT_TRUE(!option->IsTypeNodeEnabled()); + } ++ ++/** ++@tc.name: GetPipContentCallbackRef ++@tc.desc: RegisterPipContentListenerWithType/GetPipContentCallbackRef ++@tc.type: FUNC ++*/ ++HWTEST_F(PictureInPictureOptionTest, GetPipContentCallbackRef, Function | SmallTest | Level2) ++{ ++ sptr option = sptr::MakeSptr(); ++ option->RegisterPipContentListenerWithType("nodeUpdate",nullptr); ++ ASSERT_EQ(option->GetPipContentCallbackRef("nodeUpdate"), nullptr); ++} + } // namespace + } // namespace Rosen + } // namespace OHOS +\ No newline at end of file diff --git a/resources/abc/pip/interface/PiPContent.js b/resources/abc/pip/interface/PiPContent.js index 66cf09c12b..6320b7e29f 100644 --- a/resources/abc/pip/interface/PiPContent.js +++ b/resources/abc/pip/interface/PiPContent.js @@ -34,6 +34,14 @@ class XCNodeController extends NodeController { return this.node; } + replaceNode(r2) { + let s2; + let t2; + (s2 = this.node) === null || s2 === void 0 ? void 0 : s2.removeChild(this.mXComponent); + this.mXComponent = r2; + (t2 = this.node) === null || t2 === void 0 ? void 0 : t2.appendChild(this.mXComponent); + } + removeNode() { let h2; (h2 = this.node) === null || h2 === void 0 ? void 0 : h2.removeChild(this.mXComponent); @@ -49,7 +57,8 @@ class PiPContent extends ViewPU { this.xComponentController = new XComponentController; this.nodeController = null; this.mXCNodeController = null; - this.useNode = false; + this.__useNode = new ObservedPropertySimplePU(false, this, 'useNode'); + this.__nodeChange = new ObservedPropertySimplePU(false, this, 'nodeChange'); this.xComponentId = 'pipContent'; this.xComponentType = 'surface'; this.xComponent = null; @@ -69,6 +78,9 @@ class PiPContent extends ViewPU { if (a2.useNode !== undefined) { this.useNode = a2.useNode; } + if (a2.nodeChange !== undefined) { + this.nodeChange = a2.nodeChange; + } if (a2.xComponentId !== undefined) { this.xComponentId = a2.xComponentId; } @@ -83,41 +95,107 @@ class PiPContent extends ViewPU { updateStateVars(z1) { } - purgeVariableDependenciesOnElmtId(y1) { + purgeVariableDependenciesOnElmtId(h2) { + this.__useNode.purgeDependencyOnElmtId(h2); + this.__nodeChange.purgeDependencyOnElmtId(h2); + } + + aboutToBeDeleted() { + this.__useNode.aboutToBeDeleted(); + this.__nodeChange.aboutToBeDeleted(); + SubscriberManager.Get().delete(this.id__()); + this.aboutToBeDeletedInternal(); + } + + get useNode() { + return this.__useNode.get(); + } + + set useNode(b) { + this.__useNode.set(b); + } + + get nodeChange() { + return this.__nodeChange.get(); + } + + set nodeChange(a) { + this.__nodeChange.set(a); + } + + validateNode(f2) { + if (f2 === null || f2 === undefined) { + console.error(TAG, `validateNode node is null`); + return false; + } + let g2 = f2.getNodeType(); + if (g2 !== 'XComponent') { + console.error(TAG, `node type mismatch: ${g2}`); + return false; + } + return true; } aboutToAppear() { this.nodeController = pip.getCustomUIController(); + this.registerUpdateNodeListener(); this.xComponent = pip.getTypeNode(); - if (this.xComponent === null || this.xComponent === undefined) { - console.error(TAG, `xComponent node is null`); - return; - } - let u1 = this.xComponent.getNodeType(); - if (u1 !== 'XComponent') { - console.error(`xComponent type mismatch: ${u1}`); + if (!this.validateNode(this.xComponent)) { return; } + this.updatePipNodeType(this.xComponent); this.useNode = true; pip.setTypeNodeEnabled(); this.mXCNodeController = new XCNodeController(this.xComponent); console.info(TAG, 'use Node Controller'); - pip.on('stateChange', (w1) => { - let x1; - console.info(TAG, `stateChange state: ${w1}`); - if (w1 === ABOUT_TO_STOP) { - (x1 = this.mXCNodeController) === null || x1 === void 0 ? void 0 : x1.removeNode(); + this.registerStateChangeListener(); + } + + registerStateChangeListener() { + pip.on('stateChange', (y1) => { + let z1; + console.info(TAG, `stateChange state:${y1}`); + if (y1 === ABOUT_TO_STOP) { + (z1 = this.mXCNodeController) === null || z1 === void 0 ? void 0 : z1.removeNode(); } }); } - aboutToBeDeleted() { - SubscriberManager.Get().delete(this.id__()); - this.aboutToBeDeletedInternal(); + registerUpdateNodeListener() { + pip.on('nodeUpdate', (d2) => { + let e2; + console.info(TAG, `nodeUpdate`); + if (!this.validateNode(d2)) { + return; + } + if (this.useNode) { + this.updatePipNodeType(d2); + (e2 = this.mXCNodeController) === null || e2 === void 0 ? void 0 : e2.replaceNode(d2); + this.nodeChange = true; + } else { + this.updatePipNodeType(d2); + this.mXCNodeController = new XCNodeController(d2); + console.info(TAG, 'update to Node Controller'); + this.registerStateChangeListener(); + this.useNode = true; + } + }); } + updatePipNodeType(a2) { + let b2 = a2.getParent(); + if (b2 === null || b2 === undefined) { + pip.setPipNodeType(a2, false); + } else { + pip.setPipNodeType(a2, true); + b2.removeChild(a2); + } + } + + aboutToDisappear() { pip.off('stateChange'); + pip.off('nodeUpdate'); } initialRender() { @@ -127,7 +205,7 @@ class PiPContent extends ViewPU { }, Stack); this.observeComponentCreation2((h1, i1) => { If.create(); - if (this.useNode) { + if (this.useNode || this.nodeChange) { this.ifElseBranchUpdateFunction(0, () => { this.buildNode.bind(this)(); }); diff --git a/resources/abc/pip/source/PiPContent.ets b/resources/abc/pip/source/PiPContent.ets index 47ab752165..bd715e5dc5 100644 --- a/resources/abc/pip/source/PiPContent.ets +++ b/resources/abc/pip/source/PiPContent.ets @@ -20,10 +20,10 @@ const TAG: string = 'PiPContent'; const ABOUT_TO_STOP = 3; class XCNodeController extends NodeController { - private mXComponent: TypedFrameNode; + private mXComponent: typeNode.XComponent; private node: FrameNode | null = null; - constructor(xComponent: TypedFrameNode) { + constructor(xComponent: typeNode.XComponent) { super(); this.mXComponent = xComponent; } @@ -34,6 +34,12 @@ class XCNodeController extends NodeController { return this.node; } + replaceNode(newNode: typeNode.XComponent): void { + this.node?.removeChild(this.mXComponent); + this.mXComponent = newNode; + this.node?.appendChild(this.mXComponent); + } + removeNode() { this.node?.removeChild(this.mXComponent); } @@ -45,46 +51,91 @@ struct PiPContent { private xComponentController: XComponentController = new XComponentController(); private nodeController: NodeController | null = null; private mXCNodeController: XCNodeController | null = null; - private useNode: boolean = false; - private xComponent: TypedFrameNode | null = null; + @State useNode: boolean = false; + @State nodeChange: boolean = false; + private xComponent: typeNode.XComponent | null = null; xComponentId: string = 'pipContent'; xComponentType: string = 'surface'; + validateNode(node: typeNode.XComponent | null): boolean { + if (node === null || node === undefined) { + console.error(TAG, `validateNode node is null`); + return false; + } + let type: string = node.getNodeType(); + if (type !== 'XComponent') { + console.error(TAG, `node type mismatch: ${type}`); + return false; + } + return true; + } + + private registerUpdateNodeListener() { + pip.on('nodeUpdate', (newNode: typeNode.XComponent) => { + console.info(TAG, `nodeUpdate`); + if (!this.validateNode(newNode)) { + return; + } + if (this.useNode) { + pip.setPipNodeType(this.xComponent, false); + this.updatePipNodeType(newNode); + this.mXCNodeController?.replaceNode(newNode); + this.nodeChange = true; + } else { + this.updatePipNodeType(newNode); + this.mXCNodeController = new XCNodeController(newNode); + console.info(TAG, 'update to Node Controller'); + this.registerStateChangeListener(); + this.useNode = true; + } + }); + } + + private updatePipNodeType(newNode: typeNode.XComponent) { + let parent: FrameNode | null = newNode.getParent(); + if (parent === null || parent === undefined) { + pip.setPipNodeType(newNode, false); + } else { + pip.setPipNodeType(newNode, true); + parent.removeChild(newNode); + } + } + + private registerStateChangeListener() { + pip.on('stateChange', (state: number) => { + console.info(TAG, `stateChange state:${state}`); + if (state === ABOUT_TO_STOP) { + this.mXCNodeController?.removeNode(); + } + }) + } + aboutToAppear(): void { this.nodeController = pip.getCustomUIController(); + this.registerUpdateNodeListener(); this.xComponent = pip.getTypeNode(); - if (this.xComponent === null || this.xComponent === undefined) { - console.error(TAG, `xComponent node is null`); - return; - } - let type: string = this.xComponent.getNodeType(); - if (type !== 'XComponent') { - console.error(TAG, `xComponent type mismatch: ${type}`); + if (!this.validateNode(this.xComponent)) { return; } this.useNode = true; + this.updatePipNodeType(this.xComponent); pip.setTypeNodeEnabled(); this.mXCNodeController = new XCNodeController(this.xComponent); console.info(TAG, 'use Node Controller'); - - pip.on('stateChange', (state: number) => { - console.info(TAG, `stateChange state:${state}`); - if (state === ABOUT_TO_STOP) { - this.mXCNodeController?.removeNode(); - } - }) + this.registerStateChangeListener(); } aboutToDisappear(): void { pip.off('stateChange'); + pip.off('nodeUpdate'); } build() { Stack() { - if (this.useNode) { + if (this.useNode || this.nodeChange) { this.buildNode(); } else { - this.buildXComponent(); + this.buildXComponent(); } if (this.nodeController !== null) { this.buildCustomUI(); diff --git a/utils/include/pip_report.h b/utils/include/pip_report.h index 967fcecf06..ab4a1ef55e 100644 --- a/utils/include/pip_report.h +++ b/utils/include/pip_report.h @@ -32,6 +32,7 @@ public: void ReportPiPControlEvent(int32_t templateType, PiPControlType controlType); void ReportPiPRatio(int32_t windowWidth, int32_t windowHeight); void ReportPiPRestore(); + void ReportPiPUpdateContent(); private: std::string GetPackageName() const; std::string packageName_ = ""; diff --git a/utils/src/pip_report.cpp b/utils/src/pip_report.cpp index 4a8bc2f635..4536a5ec83 100644 --- a/utils/src/pip_report.cpp +++ b/utils/src/pip_report.cpp @@ -174,5 +174,19 @@ void PiPReporter::ReportPiPRestore() EVENT_KEY_OPERATION_PACKAGE_NAME, GetPackageName()); LOG_WHEN_ERROR(ret); } + +void PiPReporter::ReportPiPUpdateContent() +{ + TLOGI(WmsLogTag::WMS_PIP, "Report pip widow update typeNode"); + std::string eventName = "updateContent_PIP"; + int32_t ret = HiSysEventWrite( + OHOS::HiviewDFX::HiSysEvent::Domain::MULTIWINDOW_UE, eventName, + OHOS::HiviewDFX::HiSysEvent::EventType::BEHAVIOR, + EVENT_KEY_PNAMEID, PNAMEID, + EVENT_KEY_PVERSION, PVERSION, + EVENT_KEY_OPERATION_PACKAGE_NAME, GetPackageName()); + LOG_WHEN_ERROR(ret); +} + } // namespace Rosen } // namespace OHOS diff --git a/wm/include/picture_in_picture_controller.h b/wm/include/picture_in_picture_controller.h index 3c11014e83..ea7944840b 100644 --- a/wm/include/picture_in_picture_controller.h +++ b/wm/include/picture_in_picture_controller.h @@ -72,6 +72,7 @@ public: void SetAutoStartEnabled(bool enable); void IsAutoStartEnabled(bool& enable) const; void UpdateContentSize(int32_t width, int32_t height); + void UpdateContentNodeRef(napi_ref nodeRef); void UpdatePiPControlStatus(PiPControlType controlType, PiPControlStatus status); bool IsContentSizeChanged(float width, float height, float posX, float posY); void DoActionEvent(const std::string& actionName, int32_t status); @@ -89,6 +90,9 @@ public: sptr GetPictureInPictureLifecycle() const; sptr GetPictureInPictureActionObserver() const; sptr GetPictureInPictureControlObserver() const; + std::shared_ptr GetPipContentCallbackRef(std::string); + WMError RegisterPipContentListenerWithType(std::string, std::shared_ptr updateNodeCallbackRef); + WMError UnRegisterPipContentListenerWithType(std::string); WMError SetXComponentController(std::shared_ptr xComponentController); PiPWindowState GetControllerState(); std::string GetPiPNavigationId(); @@ -113,6 +117,8 @@ private: void UpdatePiPSourceRect() const; void ResetExtController(); bool IsPullPiPAndHandleNavigation(); + void NotifyNodeUpdate(napi_ref nodeRef); + void NotifyStateChangeInner(napi_env env, PiPState state); template WMError RegisterListener(std::vector>& holder, const sptr& listener); template WMError UnregisterListener(std::vector>& holder, const sptr& listener); wptr weakRef_ = nullptr; diff --git a/wm/include/picture_in_picture_option.h b/wm/include/picture_in_picture_option.h index c4db609fd2..13cfeb90b8 100644 --- a/wm/include/picture_in_picture_option.h +++ b/wm/include/picture_in_picture_option.h @@ -20,6 +20,7 @@ #include "xcomponent_controller.h" #include "napi/native_api.h" #include "wm_common.h" +#include "js_runtime_utils.h" namespace OHOS { namespace Rosen { @@ -35,6 +36,7 @@ public: void SetPiPControlStatus(PiPControlType controlType, PiPControlStatus status); void SetPiPControlEnabled(PiPControlType controlType, PiPControlStatus enabled); void SetXComponentController(std::shared_ptr xComponentController); + void RegisterPipContentListenerWithType(std::string, std::shared_ptr updateNodeCallbackRef); void SetControlGroup(std::vector controlGroup); void* GetContext() const; std::string GetNavigationId() const; @@ -44,6 +46,8 @@ public: std::vector GetControlEnable(); void GetContentSize(uint32_t& width, uint32_t& height); std::shared_ptr GetXComponentController(); + std::shared_ptr GetPipContentCallbackRef(std::string); + void UnRegisterPipContentListenerWithType(std::string); void SetNodeControllerRef(napi_ref ref); napi_ref GetNodeControllerRef() const; void SetTypeNodeRef(napi_ref ref); @@ -60,6 +64,7 @@ private: std::vector pipControlEnableInfoList_; std::vector controlGroup_; std::shared_ptr xComponentController_ = nullptr; + std::map> pipContentlistenerMap_; napi_ref customNodeController_ = nullptr; napi_ref typeNode_ = nullptr; bool useTypeNode_ = false; diff --git a/wm/src/picture_in_picture_controller.cpp b/wm/src/picture_in_picture_controller.cpp index f751847999..da55e93a9c 100644 --- a/wm/src/picture_in_picture_controller.cpp +++ b/wm/src/picture_in_picture_controller.cpp @@ -31,9 +31,26 @@ namespace { constexpr uint32_t PIP_HIGH_PRIORITY = 1; const std::string PIP_CONTENT_PATH = "/system/etc/window/resources/pip_content.abc"; const std::string DESTROY_TIMEOUT_TASK = "PipDestroyTimeout"; + const std::string STATE_CHANGE = "stateChange"; + const std::string UPDATE_NODE = "nodeUpdate"; const int DEFAULT_ASPECT_RATIO[] = {16, 9}; } +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; +} + uint32_t PictureInPictureController::GetPipPriority(uint32_t pipTemplateType) { if (pipTemplateType >= static_cast(PiPTemplateType::END)) { @@ -125,6 +142,7 @@ WMError PictureInPictureController::ShowPictureInPictureWindow(StartPipType star pipOption_->GetPipTemplate(), FAILED, "window is nullptr"); return WMError::WM_ERROR_PIP_STATE_ABNORMALLY; } + NotifyStateChangeInner(env_, PiPState::ABOUT_TO_START); for (auto& listener : pipLifeCycleListeners_) { listener->OnPreparePictureInPictureStart(); } @@ -279,12 +297,14 @@ WMError PictureInPictureController::StopPictureInPicture(bool destroyWindow, Sto return WMError::WM_ERROR_PIP_STATE_ABNORMALLY; } curState_ = PiPWindowState::STATE_STOPPING; + NotifyStateChangeInner(env_, PiPState::ABOUT_TO_STOP); for (auto& listener : pipLifeCycleListeners_) { listener->OnPreparePictureInPictureStop(); } if (!destroyWindow) { ResetExtController(); curState_ = PiPWindowState::STATE_STOPPED; + NotifyStateChangeInner(env_, PiPState::STOPPED); for (auto& listener : pipLifeCycleListeners_) { listener->OnPictureInPictureStop(); } @@ -360,6 +380,7 @@ WMError PictureInPictureController::DestroyPictureInPictureWindow() mainWindowLifeCycleListener_ = nullptr; PictureInPictureManager::RemovePipControllerInfo(window_->GetWindowId()); window_ = nullptr; + NotifyStateChangeInner(env_, PiPState::STOPPED); PictureInPictureManager::RemoveActiveController(this); return WMError::WM_OK; } @@ -462,6 +483,53 @@ void PictureInPictureController::UpdateContentSize(int32_t width, int32_t height SingletonContainer::Get().ReportPiPRatio(width, height); } +void PictureInPictureController::UpdateContentNodeRef(napi_ref nodeRef) +{ + TLOGI(WmsLogTag::WMS_PIP, "in"); + SingletonContainer::Get().ReportPiPUpdateContent(); + if (pipOption_ == nullptr) { + TLOGE(WmsLogTag::WMS_PIP, "Get PictureInPicture option failed"); + return; + } + pipOption_->SetTypeNodeRef(nodeRef); + if (IsTypeNodeEnabled()) { + NotifyNodeUpdate(nodeRef); + return; + } + ResetExtController(); + NotifyNodeUpdate(nodeRef); + if (isAutoStartEnabled_) { + std::string navId = pipOption_->GetNavigationId(); + if (!navId.empty()) { + auto navController = NavigationController::GetNavigationController(mainWindow_->GetUIContent(), navId); + if (navController) { + navController->DeletePIPMode(handleId_); + TLOGI(WmsLogTag::WMS_PIP, "Delete pip mode id: %{public}d", handleId_); + } + } + } + pipOption_->SetTypeNodeEnabled(true); +} + +void PictureInPictureController::NotifyNodeUpdate(napi_ref nodeRef) +{ + TLOGI(WmsLogTag::WMS_PIP, "in"); + if (nodeRef == nullptr) { + TLOGE(WmsLogTag::WMS_PIP, "invalid nodeRef"); + return; + } + if (PictureInPictureManager::IsActiveController(weakRef_)) { + std::shared_ptr updateNodeCallbackRef = GetPipContentCallbackRef(UPDATE_NODE); + if (updateNodeCallbackRef == nullptr) { + TLOGE(WmsLogTag::WMS_PIP, "updateNodeCallbackRef is null"); + return; + } + napi_value typeNode = nullptr; + napi_get_reference_value(env_, nodeRef, &typeNode); + napi_value value[] = {typeNode}; + CallJsFunction(env_, updateNodeCallbackRef->GetNapiValue(), value, 1); + } +} void PictureInPictureController::UpdatePiPControlStatus(PiPControlType controlType, PiPControlStatus status) { @@ -507,6 +575,7 @@ void PictureInPictureController::PreRestorePictureInPicture() { TLOGI(WmsLogTag::WMS_PIP, "called"); curState_ = PiPWindowState::STATE_RESTORING; + NotifyStateChangeInner(env_, PiPState::ABOUT_TO_RESTORE); for (auto& listener : pipLifeCycleListeners_) { listener->OnRestoreUserInterface(); } @@ -676,8 +745,47 @@ WMError PictureInPictureController::SetXComponentController(std::shared_ptr callbackRef) +{ + TLOGI(WmsLogTag::WMS_PIP, "called"); + if (pipOption_ == nullptr) { + TLOGE(WmsLogTag::WMS_PIP, "Get PictureInPicture option failed"); + return WMError::WM_ERROR_PIP_STATE_ABNORMALLY; + } + pipOption_->RegisterPipContentListenerWithType(type, callbackRef); + return WMError::WM_OK; +} + +WMError PictureInPictureController::UnRegisterPipContentListenerWithType(std::string type) +{ + TLOGI(WmsLogTag::WMS_PIP, "called"); + if (pipOption_ == nullptr) { + TLOGE(WmsLogTag::WMS_PIP, "Get PictureInPicture option failed"); + return WMError::WM_ERROR_PIP_STATE_ABNORMALLY; + } + pipOption_->UnRegisterPipContentListenerWithType(type); + return WMError::WM_OK; +} + +std::shared_ptr PictureInPictureController::GetPipContentCallbackRef(std::string type) +{ + return pipOption_ == nullptr ? nullptr : pipOption_->GetPipContentCallbackRef(type); +} + +void PictureInPictureController::NotifyStateChangeInner(napi_env env, PiPState state) +{ + std::shared_ptr innerCallbackRef = GetPipContentCallbackRef(STATE_CHANGE); + if (innerCallbackRef == nullptr) { + return; + } + napi_value value[] = { AbilityRuntime::CreateJsValue(env, static_cast(state))}; + CallJsFunction(env, innerCallbackRef->GetNapiValue(), value, 1); +} + void PictureInPictureController::OnPictureInPictureStart() { + NotifyStateChangeInner(env_, PiPState::STARTED); for (auto& listener : pipLifeCycleListeners_) { listener->OnPictureInPictureStart(); } diff --git a/wm/src/picture_in_picture_option.cpp b/wm/src/picture_in_picture_option.cpp index 29bad76850..725163e0f0 100644 --- a/wm/src/picture_in_picture_option.cpp +++ b/wm/src/picture_in_picture_option.cpp @@ -14,6 +14,7 @@ */ #include "picture_in_picture_option.h" +#include "js_runtime_utils.h" namespace OHOS { namespace Rosen { @@ -91,6 +92,26 @@ napi_ref PipOption::GetTypeNodeRef() const return typeNode_; } +void PipOption::RegisterPipContentListenerWithType(std::string type, + std::shared_ptr updateNodeCallbackRef) +{ + pipContentlistenerMap_[type] = updateNodeCallbackRef; +} + +void PipOption::UnRegisterPipContentListenerWithType(std::string type) +{ + pipContentlistenerMap_.erase(type); +} + +std::shared_ptr PipOption::GetPipContentCallbackRef(std::string type) +{ + auto iter = pipContentlistenerMap_.find(type); + if (iter == pipContentlistenerMap_.end()) { + return nullptr; + } + return iter->second; +} + void* PipOption::GetContext() const { return contextPtr_; diff --git a/wm/test/unittest/picture_in_picture_controller_test.cpp b/wm/test/unittest/picture_in_picture_controller_test.cpp index 58f40d73d8..fe45ff1fa2 100644 --- a/wm/test/unittest/picture_in_picture_controller_test.cpp +++ b/wm/test/unittest/picture_in_picture_controller_test.cpp @@ -1108,6 +1108,85 @@ HWTEST_F(PictureInPictureControllerTest, StopPictureInPictureInner, Function | S ASSERT_EQ(WMError::WM_OK, pipControl->StopPictureInPictureInner(StopPipType::NULL_STOP, true)); ASSERT_EQ(WMError::WM_OK, pipControl->StopPictureInPictureInner(StopPipType::NULL_STOP, false)); } + +/** +@tc.name: RegisterPipContentListenerWithType +@tc.desc: RegisterPipContentListenerWithType +@tc.type: FUNC +*/ +HWTEST_F(PictureInPictureControllerTest, RegisterPipContentListenerWithType, Function | SmallTest | Level2) +{ + sptr mw = new MockWindow(); + sptr option = new PipOption(); + sptr pipControl = new PictureInPictureController(option, mw, 100, nullptr); + pipControl->pipOption_ = nullptr; + std::shared_ptr callBack = nullptr; + ASSERT_EQ(WMError::WM_ERROR_PIP_STATE_ABNORMALLY, + pipControl->RegisterPipContentListenerWithType("nodeUpdate",callBack)); + pipControl->pipOption_ = option; + ASSERT_EQ(WMError::WM_OK, pipControl->RegisterPipContentListenerWithType("nodeUpdate",callBack)); +} +/** + +@tc.name: UnRegisterPipContentListenerWithType +@tc.desc: UnRegisterPipContentListenerWithType +@tc.type: FUNC +*/ +HWTEST_F(PictureInPictureControllerTest, UnRegisterPipContentListenerWithType, Function | SmallTest | Level2) +{ + sptr mw = new MockWindow(); + sptr option = new PipOption(); + sptr pipControl = new PictureInPictureController(option, mw, 100, nullptr); + pipControl->pipOption_ = nullptr; + std::shared_ptr callBack = nullptr; + ASSERT_EQ(WMError::WM_ERROR_PIP_STATE_ABNORMALLY, pipControl->UnRegisterPipContentListenerWithType("nodeUpdate")); + pipControl->pipOption_ = option; + ASSERT_EQ(WMError::WM_OK, pipControl->UnRegisterPipContentListenerWithType("nodeUpdate")); +} +/** + +@tc.name: GetPipContentCallbackRef +@tc.desc: GetPipContentCallbackRef +@tc.type: FUNC +*/ +HWTEST_F(PictureInPictureControllerTest, GetPipContentCallbackRef, Function | SmallTest | Level2) +{ + sptr mw = new MockWindow(); + sptr option = new PipOption(); + sptr pipControl = new PictureInPictureController(option, mw, 100, nullptr); + pipControl->pipOption_ = nullptr; + std::shared_ptr callBack = nullptr; + pipControl->RegisterPipContentListenerWithType("nodeUpdate",callBack); + ASSERT_EQ(nullptr, pipControl->GetPipContentCallbackRef("nodeUpdate")); + pipControl->pipOption_ = option; + pipControl->RegisterPipContentListenerWithType("nodeUpdate",callBack); + ASSERT_EQ(nullptr, pipControl->GetPipContentCallbackRef("nodeUpdate")); +} +/** + +@tc.name: UpdateContentNodeRef +@tc.desc: UpdateContentNodeRef +@tc.type: FUNC +*/ +HWTEST_F(PictureInPictureControllerTest, UpdateContentNodeRef, Function | SmallTest | Level2) +{ + sptr mw = new MockWindow(); + sptr option = new PipOption(); + sptr pipControl = new PictureInPictureController(option, mw, 100, nullptr); + pipControl->pipOption_ = nullptr; + napi_ref nodeRef = nullptr; + std::shared_ptr callBack = nullptr; + pipControl->UpdateContentNodeRef(nodeRef); + pipControl->pipOption_ = option; + pipControl->pipOption_->SetTypeNodeEnabled(true); + pipControl->UpdateContentNodeRef(nodeRef); + pipControl->pipOption_->SetTypeNodeEnabled(false); + pipControl->UpdateContentNodeRef(nodeRef); + pipControl->isAutoStartEnabled_ = true; + pipControl->UpdateContentNodeRef(nodeRef); + pipControl->isAutoStartEnabled_ = false; + ASSERT_EQ(true, pipControl->IsTypeNodeEnabled()); +} } // namespace } // namespace Rosen } // namespace OHOS \ No newline at end of file diff --git a/wm/test/unittest/picture_in_picture_option_test.cpp b/wm/test/unittest/picture_in_picture_option_test.cpp index 54935909ba..4540d2b1fd 100644 --- a/wm/test/unittest/picture_in_picture_option_test.cpp +++ b/wm/test/unittest/picture_in_picture_option_test.cpp @@ -185,6 +185,18 @@ HWTEST_F(PictureInPictureOptionTest, TypeNodeEnabled, Function | SmallTest | Lev option->SetTypeNodeEnabled(false); ASSERT_TRUE(!option->IsTypeNodeEnabled()); } + +/** +@tc.name: GetPipContentCallbackRef +@tc.desc: RegisterPipContentListenerWithType/GetPipContentCallbackRef +@tc.type: FUNC +*/ +HWTEST_F(PictureInPictureOptionTest, GetPipContentCallbackRef, Function | SmallTest | Level2) +{ + sptr option = sptr::MakeSptr(); + option->RegisterPipContentListenerWithType("nodeUpdate",nullptr); + ASSERT_EQ(option->GetPipContentCallbackRef("nodeUpdate"), nullptr); +} } // namespace } // namespace Rosen } // namespace OHOS \ No newline at end of file -- Gitee From 2157a70eb55441e32581c2ca3d098abdbd44e310 Mon Sep 17 00:00:00 2001 From: jiangxiaofeng20 Date: Fri, 10 Jan 2025 09:45:03 +0800 Subject: [PATCH 02/13] pip Signed-off-by: jiangxiaofeng20 --- patch | 986 ---------------------------------------------------------- 1 file changed, 986 deletions(-) delete mode 100644 patch diff --git a/patch b/patch deleted file mode 100644 index 9aac2d9a8b..0000000000 --- a/patch +++ /dev/null @@ -1,986 +0,0 @@ -diff --git a/interfaces/kits/napi/picture_in_picture_napi/inner/js_pip_manager.cpp b/interfaces/kits/napi/picture_in_picture_napi/inner/js_pip_manager.cpp -index 1a2583b07..a0a62dc33 100644 ---- a/interfaces/kits/napi/picture_in_picture_napi/inner/js_pip_manager.cpp -+++ b/interfaces/kits/napi/picture_in_picture_napi/inner/js_pip_manager.cpp -@@ -25,6 +25,14 @@ using namespace Ace; - namespace { - constexpr int32_t NUMBER_ONE = 1; - constexpr int32_t NUMBER_TWO = 2; -+ const std::set PIP_CONTENT_CALLBACK {"stateChange", "nodeUpdate"}; -+} -+ -+napi_valuetype GetType(napi_env env, napi_value value) -+{ -+ napi_valuetype res = napi_undefined; -+ napi_typeof(env, value, &res); -+ return res; - } - - napi_value NapiGetUndefined(napi_env env) -@@ -179,6 +187,36 @@ napi_value JsPipManager::OnSetTypeNodeEnabled(napi_env env, napi_callback_info i - return NapiGetUndefined(env); - } - -+napi_value JsPipManager::SetPipNodeType(napi_env env, napi_callback_info info) -+{ -+ JsPipManager* me = CheckParamsAndGetThis(env, info); -+ return (me != nullptr) ? me->OnSetPipNodeType(env, info) : nullptr; -+} -+ -+napi_value JsPipManager::OnSetPipNodeType(napi_env env, napi_callback_info info) -+{ -+ TLOGD(WmsLogTag::WMS_PIP, "[NAPI]"); -+ size_t argc = 4; // 4: arg number -+ napi_value argv[4] = { nullptr }; -+ napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr); -+ if (argc != NUMBER_TWO) { -+ TLOGE(WmsLogTag::WMS_PIP, "[NAPI]Argc count is invalid: %{public}zu", argc); -+ return NapiGetUndefined(env); -+ } -+ napi_value typeNode = argv[0]; -+ bool markPip = false; -+ if (!ConvertFromJsValue(env, argv[1], markPip)) { -+ TLOGW(WmsLogTag::WMS_PIP, "Failed to convert param to bool"); -+ } -+ if (typeNode != nullptr && GetType(env, typeNode) != napi_undefined) { -+ XComponentControllerErrorCode ret = XComponentController::SetSurfaceCallbackMode(env, typeNode, markPip ? -+ SurfaceCallbackMode::PIP: SurfaceCallbackMode::DEFAULT); -+ TLOGI(WmsLogTag::WMS_PIP, "set surface mode, ret: %{public}u, isPip: %{public}d", -+ static_cast(ret), static_cast(markPip)); -+ } -+ return NapiGetUndefined(env); -+} -+ - napi_value JsPipManager::RegisterCallback(napi_env env, napi_callback_info info) - { - JsPipManager* me = CheckParamsAndGetThis(env, info); -@@ -207,6 +245,11 @@ napi_value JsPipManager::OnRegisterCallback(napi_env env, napi_callback_info inf - TLOGE(WmsLogTag::WMS_PIP, "Failed to convert param to cbType"); - return NapiThrowInvalidParam(env); - } -+ auto iter = std::find(PIP_CONTENT_CALLBACK.begin(), PIP_CONTENT_CALLBACK.end(), cbType); -+ if (iter == PIP_CONTENT_CALLBACK.end()) { -+ TLOGE(WmsLogTag::WMS_PIP, "Callback is null or not callable"); -+ return NapiThrowInvalidParam(env); -+ } - napi_value value = argv[1]; - if (value == nullptr || !NapiIsCallable(env, value)) { - TLOGE(WmsLogTag::WMS_PIP, "Callback is null or not callable"); -@@ -215,8 +258,20 @@ napi_value JsPipManager::OnRegisterCallback(napi_env env, napi_callback_info inf - std::shared_ptr callbackRef; - napi_ref result = nullptr; - napi_create_reference(env, value, 1, &result); -- callbackRef.reset(reinterpret_cast(result)); -- PictureInPictureManager::innerCallbackRef_ = callbackRef; -+ callbackRef.reset(reinterpret_cast(result)); -+ sptr pipWindow = Window::Find(PIP_WINDOW_NAME); -+ int32_t windowId = static_cast(pipWindow->GetWindowId()); -+ sptr pipController = PictureInPictureManager::GetPipControllerInfo(windowId); -+ if (pipController == nullptr) { -+ TLOGE(WmsLogTag::WMS_PIP, "Failed to get pictureInPictureController"); -+ return NapiGetUndefined(env); -+ } -+ TLOGI(WmsLogTag::WMS_PIP, "OnRegisterCallback to window: %{public}u", windowId); -+ WMError errCode = pipController->RegisterPipContentListenerWithType(cbType, callbackRef); -+ if (errCode != WMError::WM_OK) { -+ TLOGE(WmsLogTag::WMS_PIP, "Failed to registerCallback"); -+ return NapiGetUndefined(env); -+ } - TLOGI(WmsLogTag::WMS_PIP, "Register type %{public}s success!", cbType.c_str()); - return NapiGetUndefined(env); - } -@@ -230,7 +285,37 @@ napi_value JsPipManager::UnregisterCallback(napi_env env, napi_callback_info inf - napi_value JsPipManager::OnUnregisterCallback(napi_env env, napi_callback_info info) - { - TLOGI(WmsLogTag::WMS_PIP, "[NAPI]"); -- PictureInPictureManager::innerCallbackRef_ = nullptr; -+ size_t argc = 4; -+ napi_value argv[4] = {nullptr}; -+ napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr); -+ if (argc != NUMBER_ONE) { -+ TLOGE(WmsLogTag::WMS_PIP, "Params count not match: %{public}zu", argc); -+ return NapiThrowInvalidParam(env); -+ } -+ std::string cbType; -+ if (!ConvertFromJsValue(env, argv[0], cbType)) { -+ TLOGE(WmsLogTag::WMS_PIP, "Failed to convert param to cbType"); -+ return NapiThrowInvalidParam(env); -+ } -+ auto iter = std::find(PIP_CONTENT_CALLBACK.begin(), PIP_CONTENT_CALLBACK.end(), cbType); -+ if (iter == PIP_CONTENT_CALLBACK.end()) { -+ TLOGE(WmsLogTag::WMS_PIP, "Callback is null or not callable"); -+ return NapiThrowInvalidParam(env); -+ } -+ sptr pipWindow = Window::Find(PIP_WINDOW_NAME); -+ int32_t windowId = static_cast(pipWindow->GetWindowId()); -+ sptr pipController = PictureInPictureManager::GetPipControllerInfo(windowId); -+ if (pipController == nullptr) { -+ TLOGE(WmsLogTag::WMS_PIP, "Failed to get pictureInPictureController"); -+ return NapiGetUndefined(env); -+ } -+ TLOGI(WmsLogTag::WMS_PIP, "UnRegisterPipContentListenerWithType to window: %{public}u", windowId); -+ WMError errCode = pipController->UnRegisterPipContentListenerWithType(cbType); -+ if (errCode != WMError::WM_OK) { -+ TLOGE(WmsLogTag::WMS_PIP, "Failed to set UnRegisterPipContentListenerWithType"); -+ return NapiGetUndefined(env); -+ } -+ TLOGI(WmsLogTag::WMS_PIP, "unregister type %{public}s success!", cbType.c_str()); - return NapiGetUndefined(env); - } - -@@ -250,6 +335,7 @@ napi_value JsPipManagerInit(napi_env env, napi_value exportObj) - BindNativeFunction(env, exportObj, "on", moduleName, JsPipManager::RegisterCallback); - BindNativeFunction(env, exportObj, "off", moduleName, JsPipManager::UnregisterCallback); - BindNativeFunction(env, exportObj, "setTypeNodeEnabled", moduleName, JsPipManager::SetTypeNodeEnabled); -+ BindNativeFunction(env, exportObj, "setPipNodeType", moduleName, JsPipManager::SetPipNodeType); - return NapiGetUndefined(env); - } - } // namespace Rosen -diff --git a/interfaces/kits/napi/picture_in_picture_napi/inner/js_pip_manager.h b/interfaces/kits/napi/picture_in_picture_napi/inner/js_pip_manager.h -index 90ae2aa86..a926cbcaf 100644 ---- a/interfaces/kits/napi/picture_in_picture_napi/inner/js_pip_manager.h -+++ b/interfaces/kits/napi/picture_in_picture_napi/inner/js_pip_manager.h -@@ -32,6 +32,7 @@ public: - static napi_value RegisterCallback(napi_env env, napi_callback_info info); - static napi_value UnregisterCallback(napi_env env, napi_callback_info info); - static napi_value SetTypeNodeEnabled(napi_env env, napi_callback_info info); -+ static napi_value SetPipNodeType(napi_env env, napi_callback_info info); - private: - napi_value OnInitXComponentController(napi_env env, napi_callback_info info); - napi_value OnGetCustomUIController(napi_env env, napi_callback_info info); -@@ -39,6 +40,7 @@ private: - napi_value OnRegisterCallback(napi_env env, napi_callback_info info); - napi_value OnUnregisterCallback(napi_env env, napi_callback_info info); - napi_value OnSetTypeNodeEnabled(napi_env env, napi_callback_info info); -+ napi_value OnSetPipNodeType(napi_env env, napi_callback_info info); - }; - } // namespace Rosen - } // namespace OHOS -diff --git a/interfaces/kits/napi/picture_in_picture_napi/js_pip_controller.cpp b/interfaces/kits/napi/picture_in_picture_napi/js_pip_controller.cpp -index ef816c55d..68045a1eb 100644 ---- a/interfaces/kits/napi/picture_in_picture_napi/js_pip_controller.cpp -+++ b/interfaces/kits/napi/picture_in_picture_napi/js_pip_controller.cpp -@@ -36,6 +36,7 @@ void BindFunctions(napi_env env, napi_value object, const char* moduleName) - { - BindNativeFunction(env, object, "startPiP", moduleName, JsPipController::StartPictureInPicture); - BindNativeFunction(env, object, "stopPiP", moduleName, JsPipController::StopPictureInPicture); -+ BindNativeFunction(env, object, "updateContentNode", moduleName, JsPipController::UpdateContentNode); - BindNativeFunction(env, object, "updateContentSize", moduleName, JsPipController::UpdateContentSize); - BindNativeFunction(env, object, "updatePiPControlStatus", moduleName, JsPipController::UpdatePiPControlStatus); - BindNativeFunction(env, object, "setAutoStartEnabled", moduleName, JsPipController::SetAutoStartEnabled); -@@ -186,6 +187,38 @@ napi_value JsPipController::OnSetAutoStartEnabled(napi_env env, napi_callback_in - return NapiGetUndefined(env); - } - -+napi_value JsPipController::UpdateContentNode(napi_env env, napi_callback_info info) -+{ -+ JsPipController *me = CheckParamsAndGetThis(env, info); -+ return (me != nullptr) ? me->OnUpdateContentNode(env, info) : nullptr; -+} -+ -+napi_value JsPipController::OnUpdateContentNode(napi_env env, napi_callback_info info) -+{ -+ TLOGI(WmsLogTag::WMS_PIP, "OnUpdateContentNode is called"); -+ size_t argc = 4; -+ napi_value argv[4] = {nullptr}; -+ napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr); -+ if (argc != NUMBER_ONE) { -+ TLOGE(WmsLogTag::WMS_PIP, "[NAPI]Argc count is invalid: %{public}zu", argc); -+ return NapiThrowInvalidParam(env, "Invalid args count, 1 arg is needed."); -+ } -+ napi_value typeNode = argv[0]; -+ if (typeNode == nullptr || GetType(env, typeNode) == napi_undefined) { -+ TLOGE(WmsLogTag::WMS_PIP, "[NAPI] invalid typeNode"); -+ return NapiThrowInvalidParam(env, "invalid typeNode."); -+ } -+ if (pipController_ == nullptr) { -+ std::string errMsg = "OnUpdateNode error, controller is nullptr"; -+ TLOGE(WmsLogTag::WMS_PIP, "%{public}s", errMsg.c_str()); -+ return NapiThrowInvalidParam(env, errMsg); -+ } -+ napi_ref typeNodeRef = nullptr; -+ napi_create_reference(env, typeNode, 1, &typeNodeRef); -+ pipController_->UpdateContentNodeRef(typeNodeRef); -+ return NapiGetUndefined(env); -+} -+ - napi_value JsPipController::UpdateContentSize(napi_env env, napi_callback_info info) - { - JsPipController* me = CheckParamsAndGetThis(env, info); -diff --git a/interfaces/kits/napi/picture_in_picture_napi/js_pip_controller.h b/interfaces/kits/napi/picture_in_picture_napi/js_pip_controller.h -index 166f9c8f7..b81ed1d64 100644 ---- a/interfaces/kits/napi/picture_in_picture_napi/js_pip_controller.h -+++ b/interfaces/kits/napi/picture_in_picture_napi/js_pip_controller.h -@@ -34,6 +34,7 @@ public: - static napi_value StartPictureInPicture(napi_env env, napi_callback_info info); - static napi_value StopPictureInPicture(napi_env env, napi_callback_info info); - static napi_value SetAutoStartEnabled(napi_env env, napi_callback_info info); -+ static napi_value UpdateContentNode(napi_env env, napi_callback_info info); - static napi_value UpdateContentSize(napi_env env, napi_callback_info info); - static napi_value UpdatePiPControlStatus(napi_env env, napi_callback_info info); - static napi_value SetPiPControlEnabled(napi_env env, napi_callback_info info); -@@ -49,6 +50,7 @@ private: - napi_value OnStartPictureInPicture(napi_env env, napi_callback_info info); - napi_value OnStopPictureInPicture(napi_env env, napi_callback_info info); - napi_value OnSetAutoStartEnabled(napi_env env, napi_callback_info info); -+ napi_value OnUpdateContentNode(napi_env env, napi_callback_info info); - napi_value OnUpdateContentSize(napi_env env, napi_callback_info info); - napi_value OnUpdatePiPControlStatus(napi_env env, napi_callback_info info); - napi_value OnSetPiPControlEnabled(napi_env env, napi_callback_info info); -diff --git a/interfaces/kits/napi/picture_in_picture_napi/js_pip_window_listener.cpp b/interfaces/kits/napi/picture_in_picture_napi/js_pip_window_listener.cpp -index 1889d31b6..b2442b0b5 100644 ---- a/interfaces/kits/napi/picture_in_picture_napi/js_pip_window_listener.cpp -+++ b/interfaces/kits/napi/picture_in_picture_napi/js_pip_window_listener.cpp -@@ -81,10 +81,6 @@ void JsPiPWindowListener::OnPictureInPictureOperationError(int32_t errorCode) - void JsPiPWindowListener::OnPipListenerCallback(PiPState state, int32_t errorCode) - { - TLOGI(WmsLogTag::WMS_PIP, "state: %{public}d", static_cast(state)); -- if (PictureInPictureManager::innerCallbackRef_ != nullptr) { -- napi_value value[] = { CreateJsValue(env_, static_cast(state))}; -- CallJsFunction(env_, PictureInPictureManager::innerCallbackRef_->GetNapiValue(), value, ArraySize(value)); -- } - auto napiTask = [jsCallback = jsCallBack_, state, errorCode, env = env_]() { - napi_value argv[] = {CreateJsValue(env, static_cast(state)), CreateJsValue(env, errorCode)}; - CallJsFunction(env, jsCallback->GetNapiValue(), argv, ArraySize(argv)); -diff --git a/resources/abc/pip/interface/PiPContent.js b/resources/abc/pip/interface/PiPContent.js -index 66cf09c12..6320b7e29 100644 ---- a/resources/abc/pip/interface/PiPContent.js -+++ b/resources/abc/pip/interface/PiPContent.js -@@ -34,6 +34,14 @@ class XCNodeController extends NodeController { - return this.node; - } - -+ replaceNode(r2) { -+ let s2; -+ let t2; -+ (s2 = this.node) === null || s2 === void 0 ? void 0 : s2.removeChild(this.mXComponent); -+ this.mXComponent = r2; -+ (t2 = this.node) === null || t2 === void 0 ? void 0 : t2.appendChild(this.mXComponent); -+ } -+ - removeNode() { - let h2; - (h2 = this.node) === null || h2 === void 0 ? void 0 : h2.removeChild(this.mXComponent); -@@ -49,7 +57,8 @@ class PiPContent extends ViewPU { - this.xComponentController = new XComponentController; - this.nodeController = null; - this.mXCNodeController = null; -- this.useNode = false; -+ this.__useNode = new ObservedPropertySimplePU(false, this, 'useNode'); -+ this.__nodeChange = new ObservedPropertySimplePU(false, this, 'nodeChange'); - this.xComponentId = 'pipContent'; - this.xComponentType = 'surface'; - this.xComponent = null; -@@ -69,6 +78,9 @@ class PiPContent extends ViewPU { - if (a2.useNode !== undefined) { - this.useNode = a2.useNode; - } -+ if (a2.nodeChange !== undefined) { -+ this.nodeChange = a2.nodeChange; -+ } - if (a2.xComponentId !== undefined) { - this.xComponentId = a2.xComponentId; - } -@@ -83,41 +95,107 @@ class PiPContent extends ViewPU { - updateStateVars(z1) { - } - -- purgeVariableDependenciesOnElmtId(y1) { -+ purgeVariableDependenciesOnElmtId(h2) { -+ this.__useNode.purgeDependencyOnElmtId(h2); -+ this.__nodeChange.purgeDependencyOnElmtId(h2); -+ } -+ -+ aboutToBeDeleted() { -+ this.__useNode.aboutToBeDeleted(); -+ this.__nodeChange.aboutToBeDeleted(); -+ SubscriberManager.Get().delete(this.id__()); -+ this.aboutToBeDeletedInternal(); -+ } -+ -+ get useNode() { -+ return this.__useNode.get(); -+ } -+ -+ set useNode(b) { -+ this.__useNode.set(b); -+ } -+ -+ get nodeChange() { -+ return this.__nodeChange.get(); -+ } -+ -+ set nodeChange(a) { -+ this.__nodeChange.set(a); -+ } -+ -+ validateNode(f2) { -+ if (f2 === null || f2 === undefined) { -+ console.error(TAG, `validateNode node is null`); -+ return false; -+ } -+ let g2 = f2.getNodeType(); -+ if (g2 !== 'XComponent') { -+ console.error(TAG, `node type mismatch: ${g2}`); -+ return false; -+ } -+ return true; - } - - aboutToAppear() { - this.nodeController = pip.getCustomUIController(); -+ this.registerUpdateNodeListener(); - this.xComponent = pip.getTypeNode(); -- if (this.xComponent === null || this.xComponent === undefined) { -- console.error(TAG, `xComponent node is null`); -- return; -- } -- let u1 = this.xComponent.getNodeType(); -- if (u1 !== 'XComponent') { -- console.error(`xComponent type mismatch: ${u1}`); -+ if (!this.validateNode(this.xComponent)) { - return; - } -+ this.updatePipNodeType(this.xComponent); - this.useNode = true; - pip.setTypeNodeEnabled(); - this.mXCNodeController = new XCNodeController(this.xComponent); - console.info(TAG, 'use Node Controller'); -- pip.on('stateChange', (w1) => { -- let x1; -- console.info(TAG, `stateChange state: ${w1}`); -- if (w1 === ABOUT_TO_STOP) { -- (x1 = this.mXCNodeController) === null || x1 === void 0 ? void 0 : x1.removeNode(); -+ this.registerStateChangeListener(); -+ } -+ -+ registerStateChangeListener() { -+ pip.on('stateChange', (y1) => { -+ let z1; -+ console.info(TAG, `stateChange state:${y1}`); -+ if (y1 === ABOUT_TO_STOP) { -+ (z1 = this.mXCNodeController) === null || z1 === void 0 ? void 0 : z1.removeNode(); - } - }); - } - -- aboutToBeDeleted() { -- SubscriberManager.Get().delete(this.id__()); -- this.aboutToBeDeletedInternal(); -+ registerUpdateNodeListener() { -+ pip.on('nodeUpdate', (d2) => { -+ let e2; -+ console.info(TAG, `nodeUpdate`); -+ if (!this.validateNode(d2)) { -+ return; -+ } -+ if (this.useNode) { -+ this.updatePipNodeType(d2); -+ (e2 = this.mXCNodeController) === null || e2 === void 0 ? void 0 : e2.replaceNode(d2); -+ this.nodeChange = true; -+ } else { -+ this.updatePipNodeType(d2); -+ this.mXCNodeController = new XCNodeController(d2); -+ console.info(TAG, 'update to Node Controller'); -+ this.registerStateChangeListener(); -+ this.useNode = true; -+ } -+ }); - } - -+ updatePipNodeType(a2) { -+ let b2 = a2.getParent(); -+ if (b2 === null || b2 === undefined) { -+ pip.setPipNodeType(a2, false); -+ } else { -+ pip.setPipNodeType(a2, true); -+ b2.removeChild(a2); -+ } -+ } -+ -+ - aboutToDisappear() { - pip.off('stateChange'); -+ pip.off('nodeUpdate'); - } - - initialRender() { -@@ -127,7 +205,7 @@ class PiPContent extends ViewPU { - }, Stack); - this.observeComponentCreation2((h1, i1) => { - If.create(); -- if (this.useNode) { -+ if (this.useNode || this.nodeChange) { - this.ifElseBranchUpdateFunction(0, () => { - this.buildNode.bind(this)(); - }); -diff --git a/resources/abc/pip/source/PiPContent.ets b/resources/abc/pip/source/PiPContent.ets -index 47ab75216..bd715e5dc 100644 ---- a/resources/abc/pip/source/PiPContent.ets -+++ b/resources/abc/pip/source/PiPContent.ets -@@ -20,10 +20,10 @@ const TAG: string = 'PiPContent'; - const ABOUT_TO_STOP = 3; - - class XCNodeController extends NodeController { -- private mXComponent: TypedFrameNode; -+ private mXComponent: typeNode.XComponent; - private node: FrameNode | null = null; - -- constructor(xComponent: TypedFrameNode) { -+ constructor(xComponent: typeNode.XComponent) { - super(); - this.mXComponent = xComponent; - } -@@ -34,6 +34,12 @@ class XCNodeController extends NodeController { - return this.node; - } - -+ replaceNode(newNode: typeNode.XComponent): void { -+ this.node?.removeChild(this.mXComponent); -+ this.mXComponent = newNode; -+ this.node?.appendChild(this.mXComponent); -+ } -+ - removeNode() { - this.node?.removeChild(this.mXComponent); - } -@@ -45,46 +51,91 @@ struct PiPContent { - private xComponentController: XComponentController = new XComponentController(); - private nodeController: NodeController | null = null; - private mXCNodeController: XCNodeController | null = null; -- private useNode: boolean = false; -- private xComponent: TypedFrameNode | null = null; -+ @State useNode: boolean = false; -+ @State nodeChange: boolean = false; -+ private xComponent: typeNode.XComponent | null = null; - xComponentId: string = 'pipContent'; - xComponentType: string = 'surface'; - -+ validateNode(node: typeNode.XComponent | null): boolean { -+ if (node === null || node === undefined) { -+ console.error(TAG, `validateNode node is null`); -+ return false; -+ } -+ let type: string = node.getNodeType(); -+ if (type !== 'XComponent') { -+ console.error(TAG, `node type mismatch: ${type}`); -+ return false; -+ } -+ return true; -+ } -+ -+ private registerUpdateNodeListener() { -+ pip.on('nodeUpdate', (newNode: typeNode.XComponent) => { -+ console.info(TAG, `nodeUpdate`); -+ if (!this.validateNode(newNode)) { -+ return; -+ } -+ if (this.useNode) { -+ pip.setPipNodeType(this.xComponent, false); -+ this.updatePipNodeType(newNode); -+ this.mXCNodeController?.replaceNode(newNode); -+ this.nodeChange = true; -+ } else { -+ this.updatePipNodeType(newNode); -+ this.mXCNodeController = new XCNodeController(newNode); -+ console.info(TAG, 'update to Node Controller'); -+ this.registerStateChangeListener(); -+ this.useNode = true; -+ } -+ }); -+ } -+ -+ private updatePipNodeType(newNode: typeNode.XComponent) { -+ let parent: FrameNode | null = newNode.getParent(); -+ if (parent === null || parent === undefined) { -+ pip.setPipNodeType(newNode, false); -+ } else { -+ pip.setPipNodeType(newNode, true); -+ parent.removeChild(newNode); -+ } -+ } -+ -+ private registerStateChangeListener() { -+ pip.on('stateChange', (state: number) => { -+ console.info(TAG, `stateChange state:${state}`); -+ if (state === ABOUT_TO_STOP) { -+ this.mXCNodeController?.removeNode(); -+ } -+ }) -+ } -+ - aboutToAppear(): void { - this.nodeController = pip.getCustomUIController(); -+ this.registerUpdateNodeListener(); - this.xComponent = pip.getTypeNode(); -- if (this.xComponent === null || this.xComponent === undefined) { -- console.error(TAG, `xComponent node is null`); -- return; -- } -- let type: string = this.xComponent.getNodeType(); -- if (type !== 'XComponent') { -- console.error(TAG, `xComponent type mismatch: ${type}`); -+ if (!this.validateNode(this.xComponent)) { - return; - } - this.useNode = true; -+ this.updatePipNodeType(this.xComponent); - pip.setTypeNodeEnabled(); - this.mXCNodeController = new XCNodeController(this.xComponent); - console.info(TAG, 'use Node Controller'); -- -- pip.on('stateChange', (state: number) => { -- console.info(TAG, `stateChange state:${state}`); -- if (state === ABOUT_TO_STOP) { -- this.mXCNodeController?.removeNode(); -- } -- }) -+ this.registerStateChangeListener(); - } - - aboutToDisappear(): void { - pip.off('stateChange'); -+ pip.off('nodeUpdate'); - } - - build() { - Stack() { -- if (this.useNode) { -+ if (this.useNode || this.nodeChange) { - this.buildNode(); - } else { -- this.buildXComponent(); -+ this.buildXComponent(); - } - if (this.nodeController !== null) { - this.buildCustomUI(); -diff --git a/utils/include/pip_report.h b/utils/include/pip_report.h -index 967fcecf0..ab4a1ef55 100644 ---- a/utils/include/pip_report.h -+++ b/utils/include/pip_report.h -@@ -32,6 +32,7 @@ public: - void ReportPiPControlEvent(int32_t templateType, PiPControlType controlType); - void ReportPiPRatio(int32_t windowWidth, int32_t windowHeight); - void ReportPiPRestore(); -+ void ReportPiPUpdateContent(); - private: - std::string GetPackageName() const; - std::string packageName_ = ""; -diff --git a/utils/src/pip_report.cpp b/utils/src/pip_report.cpp -index 4a8bc2f63..4536a5ec8 100644 ---- a/utils/src/pip_report.cpp -+++ b/utils/src/pip_report.cpp -@@ -174,5 +174,19 @@ void PiPReporter::ReportPiPRestore() - EVENT_KEY_OPERATION_PACKAGE_NAME, GetPackageName()); - LOG_WHEN_ERROR(ret); - } -+ -+void PiPReporter::ReportPiPUpdateContent() -+{ -+ TLOGI(WmsLogTag::WMS_PIP, "Report pip widow update typeNode"); -+ std::string eventName = "updateContent_PIP"; -+ int32_t ret = HiSysEventWrite( -+ OHOS::HiviewDFX::HiSysEvent::Domain::MULTIWINDOW_UE, eventName, -+ OHOS::HiviewDFX::HiSysEvent::EventType::BEHAVIOR, -+ EVENT_KEY_PNAMEID, PNAMEID, -+ EVENT_KEY_PVERSION, PVERSION, -+ EVENT_KEY_OPERATION_PACKAGE_NAME, GetPackageName()); -+ LOG_WHEN_ERROR(ret); -+} -+ - } // namespace Rosen - } // namespace OHOS -diff --git a/wm/include/picture_in_picture_controller.h b/wm/include/picture_in_picture_controller.h -index 3c11014e8..ea7944840 100644 ---- a/wm/include/picture_in_picture_controller.h -+++ b/wm/include/picture_in_picture_controller.h -@@ -72,6 +72,7 @@ public: - void SetAutoStartEnabled(bool enable); - void IsAutoStartEnabled(bool& enable) const; - void UpdateContentSize(int32_t width, int32_t height); -+ void UpdateContentNodeRef(napi_ref nodeRef); - void UpdatePiPControlStatus(PiPControlType controlType, PiPControlStatus status); - bool IsContentSizeChanged(float width, float height, float posX, float posY); - void DoActionEvent(const std::string& actionName, int32_t status); -@@ -89,6 +90,9 @@ public: - sptr GetPictureInPictureLifecycle() const; - sptr GetPictureInPictureActionObserver() const; - sptr GetPictureInPictureControlObserver() const; -+ std::shared_ptr GetPipContentCallbackRef(std::string); -+ WMError RegisterPipContentListenerWithType(std::string, std::shared_ptr updateNodeCallbackRef); -+ WMError UnRegisterPipContentListenerWithType(std::string); - WMError SetXComponentController(std::shared_ptr xComponentController); - PiPWindowState GetControllerState(); - std::string GetPiPNavigationId(); -@@ -113,6 +117,8 @@ private: - void UpdatePiPSourceRect() const; - void ResetExtController(); - bool IsPullPiPAndHandleNavigation(); -+ void NotifyNodeUpdate(napi_ref nodeRef); -+ void NotifyStateChangeInner(napi_env env, PiPState state); - template WMError RegisterListener(std::vector>& holder, const sptr& listener); - template WMError UnregisterListener(std::vector>& holder, const sptr& listener); - wptr weakRef_ = nullptr; -diff --git a/wm/include/picture_in_picture_option.h b/wm/include/picture_in_picture_option.h -index c4db609fd..13cfeb90b 100644 ---- a/wm/include/picture_in_picture_option.h -+++ b/wm/include/picture_in_picture_option.h -@@ -20,6 +20,7 @@ - #include "xcomponent_controller.h" - #include "napi/native_api.h" - #include "wm_common.h" -+#include "js_runtime_utils.h" - - namespace OHOS { - namespace Rosen { -@@ -35,6 +36,7 @@ public: - void SetPiPControlStatus(PiPControlType controlType, PiPControlStatus status); - void SetPiPControlEnabled(PiPControlType controlType, PiPControlStatus enabled); - void SetXComponentController(std::shared_ptr xComponentController); -+ void RegisterPipContentListenerWithType(std::string, std::shared_ptr updateNodeCallbackRef); - void SetControlGroup(std::vector controlGroup); - void* GetContext() const; - std::string GetNavigationId() const; -@@ -44,6 +46,8 @@ public: - std::vector GetControlEnable(); - void GetContentSize(uint32_t& width, uint32_t& height); - std::shared_ptr GetXComponentController(); -+ std::shared_ptr GetPipContentCallbackRef(std::string); -+ void UnRegisterPipContentListenerWithType(std::string); - void SetNodeControllerRef(napi_ref ref); - napi_ref GetNodeControllerRef() const; - void SetTypeNodeRef(napi_ref ref); -@@ -60,6 +64,7 @@ private: - std::vector pipControlEnableInfoList_; - std::vector controlGroup_; - std::shared_ptr xComponentController_ = nullptr; -+ std::map> pipContentlistenerMap_; - napi_ref customNodeController_ = nullptr; - napi_ref typeNode_ = nullptr; - bool useTypeNode_ = false; -diff --git a/wm/src/picture_in_picture_controller.cpp b/wm/src/picture_in_picture_controller.cpp -index f75184799..da55e93a9 100644 ---- a/wm/src/picture_in_picture_controller.cpp -+++ b/wm/src/picture_in_picture_controller.cpp -@@ -31,9 +31,26 @@ namespace { - constexpr uint32_t PIP_HIGH_PRIORITY = 1; - const std::string PIP_CONTENT_PATH = "/system/etc/window/resources/pip_content.abc"; - const std::string DESTROY_TIMEOUT_TASK = "PipDestroyTimeout"; -+ const std::string STATE_CHANGE = "stateChange"; -+ const std::string UPDATE_NODE = "nodeUpdate"; - const int DEFAULT_ASPECT_RATIO[] = {16, 9}; - } - -+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; -+} -+ - uint32_t PictureInPictureController::GetPipPriority(uint32_t pipTemplateType) - { - if (pipTemplateType >= static_cast(PiPTemplateType::END)) { -@@ -125,6 +142,7 @@ WMError PictureInPictureController::ShowPictureInPictureWindow(StartPipType star - pipOption_->GetPipTemplate(), FAILED, "window is nullptr"); - return WMError::WM_ERROR_PIP_STATE_ABNORMALLY; - } -+ NotifyStateChangeInner(env_, PiPState::ABOUT_TO_START); - for (auto& listener : pipLifeCycleListeners_) { - listener->OnPreparePictureInPictureStart(); - } -@@ -279,12 +297,14 @@ WMError PictureInPictureController::StopPictureInPicture(bool destroyWindow, Sto - return WMError::WM_ERROR_PIP_STATE_ABNORMALLY; - } - curState_ = PiPWindowState::STATE_STOPPING; -+ NotifyStateChangeInner(env_, PiPState::ABOUT_TO_STOP); - for (auto& listener : pipLifeCycleListeners_) { - listener->OnPreparePictureInPictureStop(); - } - if (!destroyWindow) { - ResetExtController(); - curState_ = PiPWindowState::STATE_STOPPED; -+ NotifyStateChangeInner(env_, PiPState::STOPPED); - for (auto& listener : pipLifeCycleListeners_) { - listener->OnPictureInPictureStop(); - } -@@ -360,6 +380,7 @@ WMError PictureInPictureController::DestroyPictureInPictureWindow() - mainWindowLifeCycleListener_ = nullptr; - PictureInPictureManager::RemovePipControllerInfo(window_->GetWindowId()); - window_ = nullptr; -+ NotifyStateChangeInner(env_, PiPState::STOPPED); - PictureInPictureManager::RemoveActiveController(this); - return WMError::WM_OK; - } -@@ -462,6 +483,53 @@ void PictureInPictureController::UpdateContentSize(int32_t width, int32_t height - SingletonContainer::Get().ReportPiPRatio(width, height); - } - -+void PictureInPictureController::UpdateContentNodeRef(napi_ref nodeRef) -+{ -+ TLOGI(WmsLogTag::WMS_PIP, "in"); -+ SingletonContainer::Get().ReportPiPUpdateContent(); -+ if (pipOption_ == nullptr) { -+ TLOGE(WmsLogTag::WMS_PIP, "Get PictureInPicture option failed"); -+ return; -+ } -+ pipOption_->SetTypeNodeRef(nodeRef); -+ if (IsTypeNodeEnabled()) { -+ NotifyNodeUpdate(nodeRef); -+ return; -+ } -+ ResetExtController(); -+ NotifyNodeUpdate(nodeRef); -+ if (isAutoStartEnabled_) { -+ std::string navId = pipOption_->GetNavigationId(); -+ if (!navId.empty()) { -+ auto navController = NavigationController::GetNavigationController(mainWindow_->GetUIContent(), navId); -+ if (navController) { -+ navController->DeletePIPMode(handleId_); -+ TLOGI(WmsLogTag::WMS_PIP, "Delete pip mode id: %{public}d", handleId_); -+ } -+ } -+ } -+ pipOption_->SetTypeNodeEnabled(true); -+} -+ -+void PictureInPictureController::NotifyNodeUpdate(napi_ref nodeRef) -+{ -+ TLOGI(WmsLogTag::WMS_PIP, "in"); -+ if (nodeRef == nullptr) { -+ TLOGE(WmsLogTag::WMS_PIP, "invalid nodeRef"); -+ return; -+ } -+ if (PictureInPictureManager::IsActiveController(weakRef_)) { -+ std::shared_ptr updateNodeCallbackRef = GetPipContentCallbackRef(UPDATE_NODE); -+ if (updateNodeCallbackRef == nullptr) { -+ TLOGE(WmsLogTag::WMS_PIP, "updateNodeCallbackRef is null"); -+ return; -+ } -+ napi_value typeNode = nullptr; -+ napi_get_reference_value(env_, nodeRef, &typeNode); -+ napi_value value[] = {typeNode}; -+ CallJsFunction(env_, updateNodeCallbackRef->GetNapiValue(), value, 1); -+ } -+} - - void PictureInPictureController::UpdatePiPControlStatus(PiPControlType controlType, PiPControlStatus status) - { -@@ -507,6 +575,7 @@ void PictureInPictureController::PreRestorePictureInPicture() - { - TLOGI(WmsLogTag::WMS_PIP, "called"); - curState_ = PiPWindowState::STATE_RESTORING; -+ NotifyStateChangeInner(env_, PiPState::ABOUT_TO_RESTORE); - for (auto& listener : pipLifeCycleListeners_) { - listener->OnRestoreUserInterface(); - } -@@ -676,8 +745,47 @@ WMError PictureInPictureController::SetXComponentController(std::shared_ptr callbackRef) -+{ -+ TLOGI(WmsLogTag::WMS_PIP, "called"); -+ if (pipOption_ == nullptr) { -+ TLOGE(WmsLogTag::WMS_PIP, "Get PictureInPicture option failed"); -+ return WMError::WM_ERROR_PIP_STATE_ABNORMALLY; -+ } -+ pipOption_->RegisterPipContentListenerWithType(type, callbackRef); -+ return WMError::WM_OK; -+} -+ -+WMError PictureInPictureController::UnRegisterPipContentListenerWithType(std::string type) -+{ -+ TLOGI(WmsLogTag::WMS_PIP, "called"); -+ if (pipOption_ == nullptr) { -+ TLOGE(WmsLogTag::WMS_PIP, "Get PictureInPicture option failed"); -+ return WMError::WM_ERROR_PIP_STATE_ABNORMALLY; -+ } -+ pipOption_->UnRegisterPipContentListenerWithType(type); -+ return WMError::WM_OK; -+} -+ -+std::shared_ptr PictureInPictureController::GetPipContentCallbackRef(std::string type) -+{ -+ return pipOption_ == nullptr ? nullptr : pipOption_->GetPipContentCallbackRef(type); -+} -+ -+void PictureInPictureController::NotifyStateChangeInner(napi_env env, PiPState state) -+{ -+ std::shared_ptr innerCallbackRef = GetPipContentCallbackRef(STATE_CHANGE); -+ if (innerCallbackRef == nullptr) { -+ return; -+ } -+ napi_value value[] = { AbilityRuntime::CreateJsValue(env, static_cast(state))}; -+ CallJsFunction(env, innerCallbackRef->GetNapiValue(), value, 1); -+} -+ - void PictureInPictureController::OnPictureInPictureStart() - { -+ NotifyStateChangeInner(env_, PiPState::STARTED); - for (auto& listener : pipLifeCycleListeners_) { - listener->OnPictureInPictureStart(); - } -diff --git a/wm/src/picture_in_picture_option.cpp b/wm/src/picture_in_picture_option.cpp -index 29bad7685..725163e0f 100644 ---- a/wm/src/picture_in_picture_option.cpp -+++ b/wm/src/picture_in_picture_option.cpp -@@ -14,6 +14,7 @@ - */ - - #include "picture_in_picture_option.h" -+#include "js_runtime_utils.h" - - namespace OHOS { - namespace Rosen { -@@ -91,6 +92,26 @@ napi_ref PipOption::GetTypeNodeRef() const - return typeNode_; - } - -+void PipOption::RegisterPipContentListenerWithType(std::string type, -+ std::shared_ptr updateNodeCallbackRef) -+{ -+ pipContentlistenerMap_[type] = updateNodeCallbackRef; -+} -+ -+void PipOption::UnRegisterPipContentListenerWithType(std::string type) -+{ -+ pipContentlistenerMap_.erase(type); -+} -+ -+std::shared_ptr PipOption::GetPipContentCallbackRef(std::string type) -+{ -+ auto iter = pipContentlistenerMap_.find(type); -+ if (iter == pipContentlistenerMap_.end()) { -+ return nullptr; -+ } -+ return iter->second; -+} -+ - void* PipOption::GetContext() const - { - return contextPtr_; -diff --git a/wm/test/unittest/picture_in_picture_controller_test.cpp b/wm/test/unittest/picture_in_picture_controller_test.cpp -index 58f40d73d..fe45ff1fa 100644 ---- a/wm/test/unittest/picture_in_picture_controller_test.cpp -+++ b/wm/test/unittest/picture_in_picture_controller_test.cpp -@@ -1108,6 +1108,85 @@ HWTEST_F(PictureInPictureControllerTest, StopPictureInPictureInner, Function | S - ASSERT_EQ(WMError::WM_OK, pipControl->StopPictureInPictureInner(StopPipType::NULL_STOP, true)); - ASSERT_EQ(WMError::WM_OK, pipControl->StopPictureInPictureInner(StopPipType::NULL_STOP, false)); - } -+ -+/** -+@tc.name: RegisterPipContentListenerWithType -+@tc.desc: RegisterPipContentListenerWithType -+@tc.type: FUNC -+*/ -+HWTEST_F(PictureInPictureControllerTest, RegisterPipContentListenerWithType, Function | SmallTest | Level2) -+{ -+ sptr mw = new MockWindow(); -+ sptr option = new PipOption(); -+ sptr pipControl = new PictureInPictureController(option, mw, 100, nullptr); -+ pipControl->pipOption_ = nullptr; -+ std::shared_ptr callBack = nullptr; -+ ASSERT_EQ(WMError::WM_ERROR_PIP_STATE_ABNORMALLY, -+ pipControl->RegisterPipContentListenerWithType("nodeUpdate",callBack)); -+ pipControl->pipOption_ = option; -+ ASSERT_EQ(WMError::WM_OK, pipControl->RegisterPipContentListenerWithType("nodeUpdate",callBack)); -+} -+/** -+ -+@tc.name: UnRegisterPipContentListenerWithType -+@tc.desc: UnRegisterPipContentListenerWithType -+@tc.type: FUNC -+*/ -+HWTEST_F(PictureInPictureControllerTest, UnRegisterPipContentListenerWithType, Function | SmallTest | Level2) -+{ -+ sptr mw = new MockWindow(); -+ sptr option = new PipOption(); -+ sptr pipControl = new PictureInPictureController(option, mw, 100, nullptr); -+ pipControl->pipOption_ = nullptr; -+ std::shared_ptr callBack = nullptr; -+ ASSERT_EQ(WMError::WM_ERROR_PIP_STATE_ABNORMALLY, pipControl->UnRegisterPipContentListenerWithType("nodeUpdate")); -+ pipControl->pipOption_ = option; -+ ASSERT_EQ(WMError::WM_OK, pipControl->UnRegisterPipContentListenerWithType("nodeUpdate")); -+} -+/** -+ -+@tc.name: GetPipContentCallbackRef -+@tc.desc: GetPipContentCallbackRef -+@tc.type: FUNC -+*/ -+HWTEST_F(PictureInPictureControllerTest, GetPipContentCallbackRef, Function | SmallTest | Level2) -+{ -+ sptr mw = new MockWindow(); -+ sptr option = new PipOption(); -+ sptr pipControl = new PictureInPictureController(option, mw, 100, nullptr); -+ pipControl->pipOption_ = nullptr; -+ std::shared_ptr callBack = nullptr; -+ pipControl->RegisterPipContentListenerWithType("nodeUpdate",callBack); -+ ASSERT_EQ(nullptr, pipControl->GetPipContentCallbackRef("nodeUpdate")); -+ pipControl->pipOption_ = option; -+ pipControl->RegisterPipContentListenerWithType("nodeUpdate",callBack); -+ ASSERT_EQ(nullptr, pipControl->GetPipContentCallbackRef("nodeUpdate")); -+} -+/** -+ -+@tc.name: UpdateContentNodeRef -+@tc.desc: UpdateContentNodeRef -+@tc.type: FUNC -+*/ -+HWTEST_F(PictureInPictureControllerTest, UpdateContentNodeRef, Function | SmallTest | Level2) -+{ -+ sptr mw = new MockWindow(); -+ sptr option = new PipOption(); -+ sptr pipControl = new PictureInPictureController(option, mw, 100, nullptr); -+ pipControl->pipOption_ = nullptr; -+ napi_ref nodeRef = nullptr; -+ std::shared_ptr callBack = nullptr; -+ pipControl->UpdateContentNodeRef(nodeRef); -+ pipControl->pipOption_ = option; -+ pipControl->pipOption_->SetTypeNodeEnabled(true); -+ pipControl->UpdateContentNodeRef(nodeRef); -+ pipControl->pipOption_->SetTypeNodeEnabled(false); -+ pipControl->UpdateContentNodeRef(nodeRef); -+ pipControl->isAutoStartEnabled_ = true; -+ pipControl->UpdateContentNodeRef(nodeRef); -+ pipControl->isAutoStartEnabled_ = false; -+ ASSERT_EQ(true, pipControl->IsTypeNodeEnabled()); -+} - } // namespace - } // namespace Rosen - } // namespace OHOS -\ No newline at end of file -diff --git a/wm/test/unittest/picture_in_picture_option_test.cpp b/wm/test/unittest/picture_in_picture_option_test.cpp -index 54935909b..99595da50 100644 ---- a/wm/test/unittest/picture_in_picture_option_test.cpp -+++ b/wm/test/unittest/picture_in_picture_option_test.cpp -@@ -185,6 +185,18 @@ HWTEST_F(PictureInPictureOptionTest, TypeNodeEnabled, Function | SmallTest | Lev - option->SetTypeNodeEnabled(false); - ASSERT_TRUE(!option->IsTypeNodeEnabled()); - } -+ -+/** -+@tc.name: GetPipContentCallbackRef -+@tc.desc: RegisterPipContentListenerWithType/GetPipContentCallbackRef -+@tc.type: FUNC -+*/ -+HWTEST_F(PictureInPictureOptionTest, GetPipContentCallbackRef, Function | SmallTest | Level2) -+{ -+ sptr option = sptr::MakeSptr(); -+ option->RegisterPipContentListenerWithType("nodeUpdate",nullptr); -+ ASSERT_EQ(option->GetPipContentCallbackRef("nodeUpdate"), nullptr); -+} - } // namespace - } // namespace Rosen - } // namespace OHOS -\ No newline at end of file -- Gitee From d1a5e310a53040f8e9e70ebe3c59e9d121881c7b Mon Sep 17 00:00:00 2001 From: jiangxiaofeng20 Date: Fri, 10 Jan 2025 11:10:58 +0800 Subject: [PATCH 03/13] pip Signed-off-by: jiangxiaofeng20 --- .../unittest/picture_in_picture_controller_test.cpp | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) diff --git a/wm/test/unittest/picture_in_picture_controller_test.cpp b/wm/test/unittest/picture_in_picture_controller_test.cpp index fe45ff1fa2..7d07bab591 100644 --- a/wm/test/unittest/picture_in_picture_controller_test.cpp +++ b/wm/test/unittest/picture_in_picture_controller_test.cpp @@ -1120,9 +1120,8 @@ HWTEST_F(PictureInPictureControllerTest, RegisterPipContentListenerWithType, Fun sptr option = new PipOption(); sptr pipControl = new PictureInPictureController(option, mw, 100, nullptr); pipControl->pipOption_ = nullptr; - std::shared_ptr callBack = nullptr; ASSERT_EQ(WMError::WM_ERROR_PIP_STATE_ABNORMALLY, - pipControl->RegisterPipContentListenerWithType("nodeUpdate",callBack)); + pipControl->RegisterPipContentListenerWithType("nodeUpdate", nullptr)); pipControl->pipOption_ = option; ASSERT_EQ(WMError::WM_OK, pipControl->RegisterPipContentListenerWithType("nodeUpdate",callBack)); } @@ -1138,7 +1137,6 @@ HWTEST_F(PictureInPictureControllerTest, UnRegisterPipContentListenerWithType, F sptr option = new PipOption(); sptr pipControl = new PictureInPictureController(option, mw, 100, nullptr); pipControl->pipOption_ = nullptr; - std::shared_ptr callBack = nullptr; ASSERT_EQ(WMError::WM_ERROR_PIP_STATE_ABNORMALLY, pipControl->UnRegisterPipContentListenerWithType("nodeUpdate")); pipControl->pipOption_ = option; ASSERT_EQ(WMError::WM_OK, pipControl->UnRegisterPipContentListenerWithType("nodeUpdate")); @@ -1155,11 +1153,10 @@ HWTEST_F(PictureInPictureControllerTest, GetPipContentCallbackRef, Function | Sm sptr option = new PipOption(); sptr pipControl = new PictureInPictureController(option, mw, 100, nullptr); pipControl->pipOption_ = nullptr; - std::shared_ptr callBack = nullptr; - pipControl->RegisterPipContentListenerWithType("nodeUpdate",callBack); + pipControl->RegisterPipContentListenerWithType("nodeUpdate", nullptr); ASSERT_EQ(nullptr, pipControl->GetPipContentCallbackRef("nodeUpdate")); pipControl->pipOption_ = option; - pipControl->RegisterPipContentListenerWithType("nodeUpdate",callBack); + pipControl->RegisterPipContentListenerWithType("nodeUpdate", nullptr); ASSERT_EQ(nullptr, pipControl->GetPipContentCallbackRef("nodeUpdate")); } /** @@ -1175,7 +1172,6 @@ HWTEST_F(PictureInPictureControllerTest, UpdateContentNodeRef, Function | SmallT sptr pipControl = new PictureInPictureController(option, mw, 100, nullptr); pipControl->pipOption_ = nullptr; napi_ref nodeRef = nullptr; - std::shared_ptr callBack = nullptr; pipControl->UpdateContentNodeRef(nodeRef); pipControl->pipOption_ = option; pipControl->pipOption_->SetTypeNodeEnabled(true); -- Gitee From d7d70bbb7b68645506733dbcb62b957ef825843d Mon Sep 17 00:00:00 2001 From: jiangxiaofeng20 Date: Fri, 10 Jan 2025 12:58:21 +0800 Subject: [PATCH 04/13] pip Signed-off-by: jiangxiaofeng20 --- wm/test/unittest/picture_in_picture_controller_test.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/wm/test/unittest/picture_in_picture_controller_test.cpp b/wm/test/unittest/picture_in_picture_controller_test.cpp index 7d07bab591..3ad4a125c0 100644 --- a/wm/test/unittest/picture_in_picture_controller_test.cpp +++ b/wm/test/unittest/picture_in_picture_controller_test.cpp @@ -1120,10 +1120,9 @@ HWTEST_F(PictureInPictureControllerTest, RegisterPipContentListenerWithType, Fun sptr option = new PipOption(); sptr pipControl = new PictureInPictureController(option, mw, 100, nullptr); pipControl->pipOption_ = nullptr; - ASSERT_EQ(WMError::WM_ERROR_PIP_STATE_ABNORMALLY, - pipControl->RegisterPipContentListenerWithType("nodeUpdate", nullptr)); + ASSERT_EQ(WMError::WM_ERROR_PIP_STATE_ABNORMALLY, pipControl->RegisterPipContentListenerWithType("nodeUpdate")); pipControl->pipOption_ = option; - ASSERT_EQ(WMError::WM_OK, pipControl->RegisterPipContentListenerWithType("nodeUpdate",callBack)); + ASSERT_EQ(WMError::WM_OK, pipControl->RegisterPipContentListenerWithType("nodeUpdate")); } /** -- Gitee From 6366fbda401620176d17f0a7cda58c3ab823bdcf Mon Sep 17 00:00:00 2001 From: jiangxiaofeng20 Date: Fri, 10 Jan 2025 14:11:11 +0800 Subject: [PATCH 05/13] pip Signed-off-by: jiangxiaofeng20 --- wm/test/unittest/picture_in_picture_controller_test.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wm/test/unittest/picture_in_picture_controller_test.cpp b/wm/test/unittest/picture_in_picture_controller_test.cpp index 3ad4a125c0..751bae13b3 100644 --- a/wm/test/unittest/picture_in_picture_controller_test.cpp +++ b/wm/test/unittest/picture_in_picture_controller_test.cpp @@ -1120,9 +1120,9 @@ HWTEST_F(PictureInPictureControllerTest, RegisterPipContentListenerWithType, Fun sptr option = new PipOption(); sptr pipControl = new PictureInPictureController(option, mw, 100, nullptr); pipControl->pipOption_ = nullptr; - ASSERT_EQ(WMError::WM_ERROR_PIP_STATE_ABNORMALLY, pipControl->RegisterPipContentListenerWithType("nodeUpdate")); + ASSERT_EQ(WMError::WM_ERROR_PIP_STATE_ABNORMALLY, pipControl->RegisterPipContentListenerWithType("nodeUpdate", nullptr)); pipControl->pipOption_ = option; - ASSERT_EQ(WMError::WM_OK, pipControl->RegisterPipContentListenerWithType("nodeUpdate")); + ASSERT_EQ(WMError::WM_OK, pipControl->RegisterPipContentListenerWithType("nodeUpdate", nullptr)); } /** -- Gitee From bcf7c469d92b1524e2bbf260f4a2ec81a2244b70 Mon Sep 17 00:00:00 2001 From: jiangxiaofeng20 Date: Fri, 10 Jan 2025 14:44:26 +0800 Subject: [PATCH 06/13] pip Signed-off-by: jiangxiaofeng20 --- wm/test/unittest/picture_in_picture_controller_test.cpp | 6 ++++-- wm/test/unittest/picture_in_picture_option_test.cpp | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/wm/test/unittest/picture_in_picture_controller_test.cpp b/wm/test/unittest/picture_in_picture_controller_test.cpp index 751bae13b3..540d1b0474 100644 --- a/wm/test/unittest/picture_in_picture_controller_test.cpp +++ b/wm/test/unittest/picture_in_picture_controller_test.cpp @@ -1120,7 +1120,8 @@ HWTEST_F(PictureInPictureControllerTest, RegisterPipContentListenerWithType, Fun sptr option = new PipOption(); sptr pipControl = new PictureInPictureController(option, mw, 100, nullptr); pipControl->pipOption_ = nullptr; - ASSERT_EQ(WMError::WM_ERROR_PIP_STATE_ABNORMALLY, pipControl->RegisterPipContentListenerWithType("nodeUpdate", nullptr)); + ASSERT_EQ(WMError::WM_ERROR_PIP_STATE_ABNORMALLY, + pipControl->RegisterPipContentListenerWithType("nodeUpdate", nullptr)); pipControl->pipOption_ = option; ASSERT_EQ(WMError::WM_OK, pipControl->RegisterPipContentListenerWithType("nodeUpdate", nullptr)); } @@ -1136,7 +1137,8 @@ HWTEST_F(PictureInPictureControllerTest, UnRegisterPipContentListenerWithType, F sptr option = new PipOption(); sptr pipControl = new PictureInPictureController(option, mw, 100, nullptr); pipControl->pipOption_ = nullptr; - ASSERT_EQ(WMError::WM_ERROR_PIP_STATE_ABNORMALLY, pipControl->UnRegisterPipContentListenerWithType("nodeUpdate")); + ASSERT_EQ(WMError::WM_ERROR_PIP_STATE_ABNORMALLY, + pipControl->UnRegisterPipContentListenerWithType("nodeUpdate")); pipControl->pipOption_ = option; ASSERT_EQ(WMError::WM_OK, pipControl->UnRegisterPipContentListenerWithType("nodeUpdate")); } diff --git a/wm/test/unittest/picture_in_picture_option_test.cpp b/wm/test/unittest/picture_in_picture_option_test.cpp index 4540d2b1fd..78c8f49dd1 100644 --- a/wm/test/unittest/picture_in_picture_option_test.cpp +++ b/wm/test/unittest/picture_in_picture_option_test.cpp @@ -194,7 +194,7 @@ HWTEST_F(PictureInPictureOptionTest, TypeNodeEnabled, Function | SmallTest | Lev HWTEST_F(PictureInPictureOptionTest, GetPipContentCallbackRef, Function | SmallTest | Level2) { sptr option = sptr::MakeSptr(); - option->RegisterPipContentListenerWithType("nodeUpdate",nullptr); + option->RegisterPipContentListenerWithType("nodeUpdate", nullptr); ASSERT_EQ(option->GetPipContentCallbackRef("nodeUpdate"), nullptr); } } // namespace -- Gitee From 714518d87e3db0b9d0486727b88069a00427389b Mon Sep 17 00:00:00 2001 From: jiangxiaofeng20 Date: Fri, 10 Jan 2025 15:20:00 +0800 Subject: [PATCH 07/13] pip Signed-off-by: jiangxiaofeng20 --- wm/test/unittest/picture_in_picture_controller_test.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wm/test/unittest/picture_in_picture_controller_test.cpp b/wm/test/unittest/picture_in_picture_controller_test.cpp index 540d1b0474..4728133bb5 100644 --- a/wm/test/unittest/picture_in_picture_controller_test.cpp +++ b/wm/test/unittest/picture_in_picture_controller_test.cpp @@ -1120,7 +1120,7 @@ HWTEST_F(PictureInPictureControllerTest, RegisterPipContentListenerWithType, Fun sptr option = new PipOption(); sptr pipControl = new PictureInPictureController(option, mw, 100, nullptr); pipControl->pipOption_ = nullptr; - ASSERT_EQ(WMError::WM_ERROR_PIP_STATE_ABNORMALLY, + ASSERT_EQ(WMError::WM_ERROR_PIP_STATE_ABNORMALLY, pipControl->RegisterPipContentListenerWithType("nodeUpdate", nullptr)); pipControl->pipOption_ = option; ASSERT_EQ(WMError::WM_OK, pipControl->RegisterPipContentListenerWithType("nodeUpdate", nullptr)); @@ -1137,7 +1137,7 @@ HWTEST_F(PictureInPictureControllerTest, UnRegisterPipContentListenerWithType, F sptr option = new PipOption(); sptr pipControl = new PictureInPictureController(option, mw, 100, nullptr); pipControl->pipOption_ = nullptr; - ASSERT_EQ(WMError::WM_ERROR_PIP_STATE_ABNORMALLY, + ASSERT_EQ(WMError::WM_ERROR_PIP_STATE_ABNORMALLY, pipControl->UnRegisterPipContentListenerWithType("nodeUpdate")); pipControl->pipOption_ = option; ASSERT_EQ(WMError::WM_OK, pipControl->UnRegisterPipContentListenerWithType("nodeUpdate")); -- Gitee From 2ff18fb7ab597248582d83ee8a905ce4f0bdf3b3 Mon Sep 17 00:00:00 2001 From: jiangxiaofeng20 Date: Mon, 13 Jan 2025 15:45:09 +0800 Subject: [PATCH 08/13] pip Signed-off-by: jiangxiaofeng20 --- .../inner/js_pip_manager.cpp | 91 +------------------ utils/include/pip_report.h | 3 +- utils/src/pip_report.cpp | 10 +- wm/include/picture_in_picture_controller.h | 7 +- wm/include/picture_in_picture_option.h | 6 +- wm/src/picture_in_picture_controller.cpp | 17 +++- wm/src/picture_in_picture_option.cpp | 6 +- .../picture_in_picture_controller_test.cpp | 75 +++++++++++++++ .../picture_in_picture_option_test.cpp | 12 +++ 9 files changed, 122 insertions(+), 105 deletions(-) diff --git a/interfaces/kits/napi/picture_in_picture_napi/inner/js_pip_manager.cpp b/interfaces/kits/napi/picture_in_picture_napi/inner/js_pip_manager.cpp index a0a62dc332..ea471035a1 100644 --- a/interfaces/kits/napi/picture_in_picture_napi/inner/js_pip_manager.cpp +++ b/interfaces/kits/napi/picture_in_picture_napi/inner/js_pip_manager.cpp @@ -25,14 +25,6 @@ using namespace Ace; namespace { constexpr int32_t NUMBER_ONE = 1; constexpr int32_t NUMBER_TWO = 2; - const std::set PIP_CONTENT_CALLBACK {"stateChange", "nodeUpdate"}; -} - -napi_valuetype GetType(napi_env env, napi_value value) -{ - napi_valuetype res = napi_undefined; - napi_typeof(env, value, &res); - return res; } napi_value NapiGetUndefined(napi_env env) @@ -187,36 +179,6 @@ napi_value JsPipManager::OnSetTypeNodeEnabled(napi_env env, napi_callback_info i return NapiGetUndefined(env); } -napi_value JsPipManager::SetPipNodeType(napi_env env, napi_callback_info info) -{ - JsPipManager* me = CheckParamsAndGetThis(env, info); - return (me != nullptr) ? me->OnSetPipNodeType(env, info) : nullptr; -} - -napi_value JsPipManager::OnSetPipNodeType(napi_env env, napi_callback_info info) -{ - TLOGD(WmsLogTag::WMS_PIP, "[NAPI]"); - size_t argc = 4; // 4: arg number - napi_value argv[4] = { nullptr }; - napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr); - if (argc != NUMBER_TWO) { - TLOGE(WmsLogTag::WMS_PIP, "[NAPI]Argc count is invalid: %{public}zu", argc); - return NapiGetUndefined(env); - } - napi_value typeNode = argv[0]; - bool markPip = false; - if (!ConvertFromJsValue(env, argv[1], markPip)) { - TLOGW(WmsLogTag::WMS_PIP, "Failed to convert param to bool"); - } - if (typeNode != nullptr && GetType(env, typeNode) != napi_undefined) { - XComponentControllerErrorCode ret = XComponentController::SetSurfaceCallbackMode(env, typeNode, markPip ? - SurfaceCallbackMode::PIP: SurfaceCallbackMode::DEFAULT); - TLOGI(WmsLogTag::WMS_PIP, "set surface mode, ret: %{public}u, isPip: %{public}d", - static_cast(ret), static_cast(markPip)); - } - return NapiGetUndefined(env); -} - napi_value JsPipManager::RegisterCallback(napi_env env, napi_callback_info info) { JsPipManager* me = CheckParamsAndGetThis(env, info); @@ -245,11 +207,6 @@ napi_value JsPipManager::OnRegisterCallback(napi_env env, napi_callback_info inf TLOGE(WmsLogTag::WMS_PIP, "Failed to convert param to cbType"); return NapiThrowInvalidParam(env); } - auto iter = std::find(PIP_CONTENT_CALLBACK.begin(), PIP_CONTENT_CALLBACK.end(), cbType); - if (iter == PIP_CONTENT_CALLBACK.end()) { - TLOGE(WmsLogTag::WMS_PIP, "Callback is null or not callable"); - return NapiThrowInvalidParam(env); - } napi_value value = argv[1]; if (value == nullptr || !NapiIsCallable(env, value)) { TLOGE(WmsLogTag::WMS_PIP, "Callback is null or not callable"); @@ -258,20 +215,8 @@ napi_value JsPipManager::OnRegisterCallback(napi_env env, napi_callback_info inf std::shared_ptr callbackRef; napi_ref result = nullptr; napi_create_reference(env, value, 1, &result); - callbackRef.reset(reinterpret_cast(result)); - sptr pipWindow = Window::Find(PIP_WINDOW_NAME); - int32_t windowId = static_cast(pipWindow->GetWindowId()); - sptr pipController = PictureInPictureManager::GetPipControllerInfo(windowId); - if (pipController == nullptr) { - TLOGE(WmsLogTag::WMS_PIP, "Failed to get pictureInPictureController"); - return NapiGetUndefined(env); - } - TLOGI(WmsLogTag::WMS_PIP, "OnRegisterCallback to window: %{public}u", windowId); - WMError errCode = pipController->RegisterPipContentListenerWithType(cbType, callbackRef); - if (errCode != WMError::WM_OK) { - TLOGE(WmsLogTag::WMS_PIP, "Failed to registerCallback"); - return NapiGetUndefined(env); - } + callbackRef.reset(reinterpret_cast(result)); + PictureInPictureManager::innerCallbackRef_ = callbackRef; TLOGI(WmsLogTag::WMS_PIP, "Register type %{public}s success!", cbType.c_str()); return NapiGetUndefined(env); } @@ -285,37 +230,7 @@ napi_value JsPipManager::UnregisterCallback(napi_env env, napi_callback_info inf napi_value JsPipManager::OnUnregisterCallback(napi_env env, napi_callback_info info) { TLOGI(WmsLogTag::WMS_PIP, "[NAPI]"); - size_t argc = 4; - napi_value argv[4] = {nullptr}; - napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr); - if (argc != NUMBER_ONE) { - TLOGE(WmsLogTag::WMS_PIP, "Params count not match: %{public}zu", argc); - return NapiThrowInvalidParam(env); - } - std::string cbType; - if (!ConvertFromJsValue(env, argv[0], cbType)) { - TLOGE(WmsLogTag::WMS_PIP, "Failed to convert param to cbType"); - return NapiThrowInvalidParam(env); - } - auto iter = std::find(PIP_CONTENT_CALLBACK.begin(), PIP_CONTENT_CALLBACK.end(), cbType); - if (iter == PIP_CONTENT_CALLBACK.end()) { - TLOGE(WmsLogTag::WMS_PIP, "Callback is null or not callable"); - return NapiThrowInvalidParam(env); - } - sptr pipWindow = Window::Find(PIP_WINDOW_NAME); - int32_t windowId = static_cast(pipWindow->GetWindowId()); - sptr pipController = PictureInPictureManager::GetPipControllerInfo(windowId); - if (pipController == nullptr) { - TLOGE(WmsLogTag::WMS_PIP, "Failed to get pictureInPictureController"); - return NapiGetUndefined(env); - } - TLOGI(WmsLogTag::WMS_PIP, "UnRegisterPipContentListenerWithType to window: %{public}u", windowId); - WMError errCode = pipController->UnRegisterPipContentListenerWithType(cbType); - if (errCode != WMError::WM_OK) { - TLOGE(WmsLogTag::WMS_PIP, "Failed to set UnRegisterPipContentListenerWithType"); - return NapiGetUndefined(env); - } - TLOGI(WmsLogTag::WMS_PIP, "unregister type %{public}s success!", cbType.c_str()); + PictureInPictureManager::innerCallbackRef_ = nullptr; return NapiGetUndefined(env); } diff --git a/utils/include/pip_report.h b/utils/include/pip_report.h index ab4a1ef55e..ede97f6446 100644 --- a/utils/include/pip_report.h +++ b/utils/include/pip_report.h @@ -32,7 +32,8 @@ public: void ReportPiPControlEvent(int32_t templateType, PiPControlType controlType); void ReportPiPRatio(int32_t windowWidth, int32_t windowHeight); void ReportPiPRestore(); - void ReportPiPUpdateContent(); + void ReportPiPUpdateContent(int32_t originType, int32_t templateType, int32_t isSuccess, + const std::string &errorReason); private: std::string GetPackageName() const; std::string packageName_ = ""; diff --git a/utils/src/pip_report.cpp b/utils/src/pip_report.cpp index 4536a5ec83..8db481b3b3 100644 --- a/utils/src/pip_report.cpp +++ b/utils/src/pip_report.cpp @@ -56,6 +56,8 @@ constexpr char EVENT_KEY_OPERATION_ERROR_REASON[] = "OPERATION_ERROR_REASON"; constexpr char EVENT_KEY_ACTION_EVENT[] = "ACTION_EVENT"; constexpr char EVENT_KEY_WINDOW_WIDTH[] = "WINDOW_WIDTH"; constexpr char EVENT_KEY_WINDOW_HEIGHT[] = "WINDOW_HEIGHT"; +constexpr char TEMPLATE_TYPE[] = "TEMPLATE_TYPE"; +constexpr char ORIGIN_CONTENT_TYPE[] = "ORIGIN_CONTENT_TYPE"; void PiPReporter::SetCurrentPackageName(const std::string& packageName) { @@ -175,7 +177,8 @@ void PiPReporter::ReportPiPRestore() LOG_WHEN_ERROR(ret); } -void PiPReporter::ReportPiPUpdateContent() +void PiPReporter::ReportPiPUpdateContent(int32_t originType, int32_t templateType, + int32_t isSuccess, const std::string &errorReason) { TLOGI(WmsLogTag::WMS_PIP, "Report pip widow update typeNode"); std::string eventName = "updateContent_PIP"; @@ -184,9 +187,12 @@ void PiPReporter::ReportPiPUpdateContent() OHOS::HiviewDFX::HiSysEvent::EventType::BEHAVIOR, EVENT_KEY_PNAMEID, PNAMEID, EVENT_KEY_PVERSION, PVERSION, + ORIGIN_CONTENT_TYPE, originType, + TEMPLATE_TYPE, templateType, + EVENT_KEY_OPERATION_CODE, isSuccess, + EVENT_KEY_OPERATION_ERROR_REASON, errorReason, EVENT_KEY_OPERATION_PACKAGE_NAME, GetPackageName()); LOG_WHEN_ERROR(ret); } - } // namespace Rosen } // namespace OHOS diff --git a/wm/include/picture_in_picture_controller.h b/wm/include/picture_in_picture_controller.h index ea7944840b..6d16c5d564 100644 --- a/wm/include/picture_in_picture_controller.h +++ b/wm/include/picture_in_picture_controller.h @@ -90,9 +90,10 @@ public: sptr GetPictureInPictureLifecycle() const; sptr GetPictureInPictureActionObserver() const; sptr GetPictureInPictureControlObserver() const; - std::shared_ptr GetPipContentCallbackRef(std::string); - WMError RegisterPipContentListenerWithType(std::string, std::shared_ptr updateNodeCallbackRef); - WMError UnRegisterPipContentListenerWithType(std::string); + std::shared_ptr GetPipContentCallbackRef(const std::string&); + WMError RegisterPipContentListenerWithType(const std::string&, + std::shared_ptr updateNodeCallbackRef); + WMError UnRegisterPipContentListenerWithType(const std::string&); WMError SetXComponentController(std::shared_ptr xComponentController); PiPWindowState GetControllerState(); std::string GetPiPNavigationId(); diff --git a/wm/include/picture_in_picture_option.h b/wm/include/picture_in_picture_option.h index 13cfeb90b8..c08204ab58 100644 --- a/wm/include/picture_in_picture_option.h +++ b/wm/include/picture_in_picture_option.h @@ -36,7 +36,7 @@ public: void SetPiPControlStatus(PiPControlType controlType, PiPControlStatus status); void SetPiPControlEnabled(PiPControlType controlType, PiPControlStatus enabled); void SetXComponentController(std::shared_ptr xComponentController); - void RegisterPipContentListenerWithType(std::string, std::shared_ptr updateNodeCallbackRef); + void RegisterPipContentListenerWithType(const std::string&, std::shared_ptr updateNodeCallbackRef); void SetControlGroup(std::vector controlGroup); void* GetContext() const; std::string GetNavigationId() const; @@ -46,8 +46,8 @@ public: std::vector GetControlEnable(); void GetContentSize(uint32_t& width, uint32_t& height); std::shared_ptr GetXComponentController(); - std::shared_ptr GetPipContentCallbackRef(std::string); - void UnRegisterPipContentListenerWithType(std::string); + std::shared_ptr GetPipContentCallbackRef(const std::string&); + void UnRegisterPipContentListenerWithType(const std::string&); void SetNodeControllerRef(napi_ref ref); napi_ref GetNodeControllerRef() const; void SetTypeNodeRef(napi_ref ref); diff --git a/wm/src/picture_in_picture_controller.cpp b/wm/src/picture_in_picture_controller.cpp index da55e93a9c..4194be4d29 100644 --- a/wm/src/picture_in_picture_controller.cpp +++ b/wm/src/picture_in_picture_controller.cpp @@ -486,9 +486,10 @@ void PictureInPictureController::UpdateContentSize(int32_t width, int32_t height void PictureInPictureController::UpdateContentNodeRef(napi_ref nodeRef) { TLOGI(WmsLogTag::WMS_PIP, "in"); - SingletonContainer::Get().ReportPiPUpdateContent(); if (pipOption_ == nullptr) { - TLOGE(WmsLogTag::WMS_PIP, "Get PictureInPicture option failed"); + TLOGE(WmsLogTag::WMS_PIP, "option is null"); + SingletonContainer::Get().ReportPiPUpdateContent(static_cast(IsTypeNodeEnabled()), + pipOption_->GetPipTemplate(), FAILED, "option is null"); return; } pipOption_->SetTypeNodeRef(nodeRef); @@ -516,18 +517,24 @@ void PictureInPictureController::NotifyNodeUpdate(napi_ref nodeRef) TLOGI(WmsLogTag::WMS_PIP, "in"); if (nodeRef == nullptr) { TLOGE(WmsLogTag::WMS_PIP, "invalid nodeRef"); + SingletonContainer::Get().ReportPiPUpdateContent(static_cast(IsTypeNodeEnabled()), + pipOption_->GetPipTemplate(), FAILED, "invalid nodeRef"); return; } if (PictureInPictureManager::IsActiveController(weakRef_)) { std::shared_ptr updateNodeCallbackRef = GetPipContentCallbackRef(UPDATE_NODE); if (updateNodeCallbackRef == nullptr) { TLOGE(WmsLogTag::WMS_PIP, "updateNodeCallbackRef is null"); + SingletonContainer::Get().ReportPiPUpdateContent(static_cast(IsTypeNodeEnabled()), + pipOption_->GetPipTemplate(), FAILED, "updateNodeCallbackRef is null"); return; } napi_value typeNode = nullptr; napi_get_reference_value(env_, nodeRef, &typeNode); napi_value value[] = {typeNode}; CallJsFunction(env_, updateNodeCallbackRef->GetNapiValue(), value, 1); + SingletonContainer::Get().ReportPiPUpdateContent(static_cast(IsTypeNodeEnabled()), + pipOption_->GetPipTemplate(), PIP_SUCCESS, "updateNode success"); } } @@ -745,7 +752,7 @@ WMError PictureInPictureController::SetXComponentController(std::shared_ptr callbackRef) { TLOGI(WmsLogTag::WMS_PIP, "called"); @@ -757,7 +764,7 @@ WMError PictureInPictureController::RegisterPipContentListenerWithType(std::stri return WMError::WM_OK; } -WMError PictureInPictureController::UnRegisterPipContentListenerWithType(std::string type) +WMError PictureInPictureController::UnRegisterPipContentListenerWithType(const std::string& type) { TLOGI(WmsLogTag::WMS_PIP, "called"); if (pipOption_ == nullptr) { @@ -768,7 +775,7 @@ WMError PictureInPictureController::UnRegisterPipContentListenerWithType(std::st return WMError::WM_OK; } -std::shared_ptr PictureInPictureController::GetPipContentCallbackRef(std::string type) +std::shared_ptr PictureInPictureController::GetPipContentCallbackRef(const std::string& type) { return pipOption_ == nullptr ? nullptr : pipOption_->GetPipContentCallbackRef(type); } diff --git a/wm/src/picture_in_picture_option.cpp b/wm/src/picture_in_picture_option.cpp index 725163e0f0..03e9eb0a37 100644 --- a/wm/src/picture_in_picture_option.cpp +++ b/wm/src/picture_in_picture_option.cpp @@ -92,18 +92,18 @@ napi_ref PipOption::GetTypeNodeRef() const return typeNode_; } -void PipOption::RegisterPipContentListenerWithType(std::string type, +void PipOption::RegisterPipContentListenerWithType(const std::string& type, std::shared_ptr updateNodeCallbackRef) { pipContentlistenerMap_[type] = updateNodeCallbackRef; } -void PipOption::UnRegisterPipContentListenerWithType(std::string type) +void PipOption::UnRegisterPipContentListenerWithType(const std::string& type) { pipContentlistenerMap_.erase(type); } -std::shared_ptr PipOption::GetPipContentCallbackRef(std::string type) +std::shared_ptr PipOption::GetPipContentCallbackRef(const std::string& type) { auto iter = pipContentlistenerMap_.find(type); if (iter == pipContentlistenerMap_.end()) { diff --git a/wm/test/unittest/picture_in_picture_controller_test.cpp b/wm/test/unittest/picture_in_picture_controller_test.cpp index 4728133bb5..dae7f069e4 100644 --- a/wm/test/unittest/picture_in_picture_controller_test.cpp +++ b/wm/test/unittest/picture_in_picture_controller_test.cpp @@ -955,6 +955,81 @@ HWTEST_F(PictureInPictureControllerTest, SetXComponentController, Function | Sma ASSERT_EQ(WMError::WM_OK, pipControl->SetXComponentController(xComponentController)); } +/** + * @tc.name: RegisterPipContentListenerWithType + * @tc.desc: RegisterPipContentListenerWithType + * @tc.type: FUNC + */ +HWTEST_F(PictureInPictureControllerTest, RegisterPipContentListenerWithType, Function | SmallTest | Level2) +{ +sptr mw = new MockWindow(); +sptr option = new PipOption(); +sptr pipControl = new PictureInPictureController(option, mw, 100, nullptr); +pipControl->pipOption_ = nullptr; +ASSERT_EQ(WMError::WM_ERROR_PIP_STATE_ABNORMALLY, + pipControl->RegisterPipContentListenerWithType("nodeUpdate", nullptr)); +pipControl->pipOption_ = option; +ASSERT_EQ(WMError::WM_OK, pipControl->RegisterPipContentListenerWithType("nodeUpdate", nullptr)); +} + +/** + * @tc.name: UnRegisterPipContentListenerWithType + * @tc.desc: UnRegisterPipContentListenerWithType + * @tc.type: FUNC + */ +HWTEST_F(PictureInPictureControllerTest, UnRegisterPipContentListenerWithType, Function | SmallTest | Level2) +{ +sptr mw = new MockWindow(); +sptr option = new PipOption(); +sptr pipControl = new PictureInPictureController(option, mw, 100, nullptr); +pipControl->pipOption_ = nullptr; +ASSERT_EQ(WMError::WM_ERROR_PIP_STATE_ABNORMALLY, pipControl->UnRegisterPipContentListenerWithType("nodeUpdate")); +pipControl->pipOption_ = option; +ASSERT_EQ(WMError::WM_OK, pipControl->UnRegisterPipContentListenerWithType("nodeUpdate")); +} + +/** + * @tc.name: GetPipContentCallbackRef + * @tc.desc: GetPipContentCallbackRef + * @tc.type: FUNC + */ +HWTEST_F(PictureInPictureControllerTest, GetPipContentCallbackRef, Function | SmallTest | Level2) +{ +sptr mw = new MockWindow(); +sptr option = new PipOption(); +sptr pipControl = new PictureInPictureController(option, mw, 100, nullptr); +pipControl->pipOption_ = nullptr; +pipControl->RegisterPipContentListenerWithType("nodeUpdate", nullptr); +ASSERT_EQ(nullptr, pipControl->GetPipContentCallbackRef("nodeUpdate")); +pipControl->pipOption_ = option; +pipControl->RegisterPipContentListenerWithType("nodeUpdate", nullptr); +ASSERT_EQ(nullptr, pipControl->GetPipContentCallbackRef("nodeUpdate")); +} + +/** + * @tc.name: UpdateContentNodeRef + * @tc.desc: UpdateContentNodeRef + * @tc.type: FUNC + */ +HWTEST_F(PictureInPictureControllerTest, UpdateContentNodeRef, Function | SmallTest | Level2) +{ +sptr mw = new MockWindow(); +sptr option = new PipOption(); +sptr pipControl = new PictureInPictureController(option, mw, 100, nullptr); +pipControl->pipOption_ = nullptr; +napi_ref nodeRef = nullptr; +pipControl->UpdateContentNodeRef(nodeRef); +pipControl->pipOption_ = option; +pipControl->pipOption_->SetTypeNodeEnabled(true); +pipControl->UpdateContentNodeRef(nodeRef); +pipControl->pipOption_->SetTypeNodeEnabled(false); +pipControl->UpdateContentNodeRef(nodeRef); +pipControl->isAutoStartEnabled_ = true; +pipControl->UpdateContentNodeRef(nodeRef); +pipControl->isAutoStartEnabled_ = false; +ASSERT_EQ(true, pipControl->IsTypeNodeEnabled()); +} + /** * @tc.name: UpdatePiPSourceRect * @tc.desc: UpdatePiPSourceRect diff --git a/wm/test/unittest/picture_in_picture_option_test.cpp b/wm/test/unittest/picture_in_picture_option_test.cpp index 78c8f49dd1..20c435c84d 100644 --- a/wm/test/unittest/picture_in_picture_option_test.cpp +++ b/wm/test/unittest/picture_in_picture_option_test.cpp @@ -172,6 +172,18 @@ HWTEST_F(PictureInPictureOptionTest, TypeNodeRef, Function | SmallTest | Level2) ASSERT_EQ(option->GetTypeNodeRef(), nullptr); } +/** + * @tc.name: GetPipContentCallbackRef + * @tc.desc: RegisterPipContentListenerWithType/GetPipContentCallbackRef + * @tc.type: FUNC + */ +HWTEST_F(PictureInPictureOptionTest, GetPipContentCallbackRef, Function | SmallTest | Level2) +{ + sptr option = sptr::MakeSptr(); + option->RegisterPipContentListenerWithType("nodeUpdate", nullptr); + ASSERT_EQ(option->GetPipContentCallbackRef("nodeUpdate"), nullptr); +} + /** * @tc.name: TypeNodeEnabled * @tc.desc: SetTypeNodeEnabled/IsTypeNodeEnabled -- Gitee From bd7497ad8801d749c8e31185682194c868cd0030 Mon Sep 17 00:00:00 2001 From: jiangxiaofeng20 Date: Mon, 13 Jan 2025 15:54:30 +0800 Subject: [PATCH 09/13] pip Signed-off-by: jiangxiaofeng20 --- .../inner/js_pip_manager.cpp | 91 ++++++++++++++++++- .../picture_in_picture_controller_test.cpp | 76 ---------------- .../picture_in_picture_option_test.cpp | 12 --- 3 files changed, 89 insertions(+), 90 deletions(-) diff --git a/interfaces/kits/napi/picture_in_picture_napi/inner/js_pip_manager.cpp b/interfaces/kits/napi/picture_in_picture_napi/inner/js_pip_manager.cpp index ea471035a1..bcd0ab6995 100644 --- a/interfaces/kits/napi/picture_in_picture_napi/inner/js_pip_manager.cpp +++ b/interfaces/kits/napi/picture_in_picture_napi/inner/js_pip_manager.cpp @@ -25,6 +25,15 @@ using namespace Ace; namespace { constexpr int32_t NUMBER_ONE = 1; constexpr int32_t NUMBER_TWO = 2; + constexpr int32_t NUMBER_FOUR = 4; + const std::unordered_set PIP_CONTENT_CALLBACK {"stateChange", "nodeUpdate"}; +} + +napi_valuetype GetType(napi_env env, napi_value value) +{ + napi_valuetype res = napi_undefined; + napi_typeof(env, value, &res); + return res; } napi_value NapiGetUndefined(napi_env env) @@ -179,6 +188,39 @@ napi_value JsPipManager::OnSetTypeNodeEnabled(napi_env env, napi_callback_info i return NapiGetUndefined(env); } +napi_value JsPipManager::SetPipNodeType(napi_env env, napi_callback_info info) +{ + JsPipManager* me = CheckParamsAndGetThis(env, info); + return (me != nullptr) ? me->OnSetPipNodeType(env, info) : nullptr; +} + +napi_value JsPipManager::OnSetPipNodeType(napi_env env, napi_callback_info info) +{ + TLOGD(WmsLogTag::WMS_PIP, "[NAPI]"); + size_t argc = NUMBER_FOUR; // 4: arg number + napi_value argv[NUMBER_FOUR] = { nullptr }; + napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr); + return NapiGetUndefined(env); + + if (argc != NUMBER_TWO) { + TLOGE(WmsLogTag::WMS_PIP, "[NAPI]Argc count is invalid: %{public}zu", argc); + return NapiGetUndefined(env); + } + napi_value typeNode = argv[0]; + bool markPip = false; + if (!ConvertFromJsValue(env, argv[NUMBER_ONE], markPip)) { + TLOGW(WmsLogTag::WMS_PIP, "Failed to convert param to bool"); + } + if (typeNode != nullptr && GetType(env, typeNode) != napi_undefined) { + XComponentControllerErrorCode ret = + XComponentController::SetSurfaceCallbackMode(env, typeNode, markPip ? + SurfaceCallbackMode::PIP: SurfaceCallbackMode::DEFAULT); + TLOGI(WmsLogTag::WMS_PIP, "set surface mode, ret: %{public}u, isPip: %{public}d", + static_cast(ret), static_cast(markPip)); + } + return NapiGetUndefined(env); +} + napi_value JsPipManager::RegisterCallback(napi_env env, napi_callback_info info) { JsPipManager* me = CheckParamsAndGetThis(env, info); @@ -207,6 +249,11 @@ napi_value JsPipManager::OnRegisterCallback(napi_env env, napi_callback_info inf TLOGE(WmsLogTag::WMS_PIP, "Failed to convert param to cbType"); return NapiThrowInvalidParam(env); } + auto iter = find(PIP_CONTENT_CALLBACK.begin(), PIP_CONTENT_CALLBACK.end(), cbType); + if (iter == PIP_CONTENT_CALLBACK.end()) { + TLOGE(WmsLogTag::WMS_PIP, "Callback is null or not callable"); + return NapiThrowInvalidParam(env); + } napi_value value = argv[1]; if (value == nullptr || !NapiIsCallable(env, value)) { TLOGE(WmsLogTag::WMS_PIP, "Callback is null or not callable"); @@ -216,7 +263,18 @@ napi_value JsPipManager::OnRegisterCallback(napi_env env, napi_callback_info inf napi_ref result = nullptr; napi_create_reference(env, value, 1, &result); callbackRef.reset(reinterpret_cast(result)); - PictureInPictureManager::innerCallbackRef_ = callbackRef; + sptr pipWindow = Window::Find(PIP_WINDOW_NAME); + int32_t windowId = static_cast(pipWindow->GetWindowId()); + sptr pipController = PictureInPictureManager::GetPipControllerInfo(windowId); + if (pipController == nullptr) { + TLOGE(WmsLogTag::WMS_PIP, "Failed to get pictureInPictureController"); + return NapiGetUndefined(env); + } + TLOGI(WmsLogTag::WMS_PIP, "OnRegisterCallback to window: %{public}u", windowId); + WMError errCode = pipController->RegisterPipContentListenerWithType(cbType, callbackRef); + if (errCode != WMError::WM_OK) { + TLOGE(WmsLogTag::WMS_PIP, "Failed to registerCallback"); + } TLOGI(WmsLogTag::WMS_PIP, "Register type %{public}s success!", cbType.c_str()); return NapiGetUndefined(env); } @@ -230,7 +288,36 @@ napi_value JsPipManager::UnregisterCallback(napi_env env, napi_callback_info inf napi_value JsPipManager::OnUnregisterCallback(napi_env env, napi_callback_info info) { TLOGI(WmsLogTag::WMS_PIP, "[NAPI]"); - PictureInPictureManager::innerCallbackRef_ = nullptr; + size_t argc = 4; + napi_value argv[4] = {nullptr}; + napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr); + if (argc != NUMBER_ONE) { + TLOGE(WmsLogTag::WMS_PIP, "Params count not match: %{public}zu", argc); + return NapiThrowInvalidParam(env); + } + std::string cbType; + if (!ConvertFromJsValue(env, argv[0], cbType)) { + TLOGE(WmsLogTag::WMS_PIP, "Failed to convert param to cbType"); + return NapiThrowInvalidParam(env); + } + auto iter = find(PIP_CONTENT_CALLBACK.begin(), PIP_CONTENT_CALLBACK.end(), cbType); + if (iter == PIP_CONTENT_CALLBACK.end()) { + TLOGE(WmsLogTag::WMS_PIP, "Callback is null or not callable"); + return NapiThrowInvalidParam(env); + } + sptr pipWindow = Window::Find(PIP_WINDOW_NAME); + int32_t windowId = static_cast(pipWindow->GetWindowId()); + sptr pipController = PictureInPictureManager::GetPipControllerInfo(windowId); + if (pipController == nullptr) { + TLOGE(WmsLogTag::WMS_PIP, "Failed to get pictureInPictureController"); + return NapiGetUndefined(env); + } + TLOGI(WmsLogTag::WMS_PIP, "UnRegisterPipContentListenerWithType to window: %{public}u", windowId); + WMError errCode = pipController->UnRegisterPipContentListenerWithType(cbType); + if (errCode != WMError::WM_OK) { + TLOGE(WmsLogTag::WMS_PIP, "Failed to set UnRegisterPipContentListenerWithType"); + } + TLOGI(WmsLogTag::WMS_PIP, "unregister type %{public}s success!", cbType.c_str()); return NapiGetUndefined(env); } diff --git a/wm/test/unittest/picture_in_picture_controller_test.cpp b/wm/test/unittest/picture_in_picture_controller_test.cpp index dae7f069e4..787c515b4a 100644 --- a/wm/test/unittest/picture_in_picture_controller_test.cpp +++ b/wm/test/unittest/picture_in_picture_controller_test.cpp @@ -1183,82 +1183,6 @@ HWTEST_F(PictureInPictureControllerTest, StopPictureInPictureInner, Function | S ASSERT_EQ(WMError::WM_OK, pipControl->StopPictureInPictureInner(StopPipType::NULL_STOP, true)); ASSERT_EQ(WMError::WM_OK, pipControl->StopPictureInPictureInner(StopPipType::NULL_STOP, false)); } - -/** -@tc.name: RegisterPipContentListenerWithType -@tc.desc: RegisterPipContentListenerWithType -@tc.type: FUNC -*/ -HWTEST_F(PictureInPictureControllerTest, RegisterPipContentListenerWithType, Function | SmallTest | Level2) -{ - sptr mw = new MockWindow(); - sptr option = new PipOption(); - sptr pipControl = new PictureInPictureController(option, mw, 100, nullptr); - pipControl->pipOption_ = nullptr; - ASSERT_EQ(WMError::WM_ERROR_PIP_STATE_ABNORMALLY, - pipControl->RegisterPipContentListenerWithType("nodeUpdate", nullptr)); - pipControl->pipOption_ = option; - ASSERT_EQ(WMError::WM_OK, pipControl->RegisterPipContentListenerWithType("nodeUpdate", nullptr)); -} -/** - -@tc.name: UnRegisterPipContentListenerWithType -@tc.desc: UnRegisterPipContentListenerWithType -@tc.type: FUNC -*/ -HWTEST_F(PictureInPictureControllerTest, UnRegisterPipContentListenerWithType, Function | SmallTest | Level2) -{ - sptr mw = new MockWindow(); - sptr option = new PipOption(); - sptr pipControl = new PictureInPictureController(option, mw, 100, nullptr); - pipControl->pipOption_ = nullptr; - ASSERT_EQ(WMError::WM_ERROR_PIP_STATE_ABNORMALLY, - pipControl->UnRegisterPipContentListenerWithType("nodeUpdate")); - pipControl->pipOption_ = option; - ASSERT_EQ(WMError::WM_OK, pipControl->UnRegisterPipContentListenerWithType("nodeUpdate")); -} -/** - -@tc.name: GetPipContentCallbackRef -@tc.desc: GetPipContentCallbackRef -@tc.type: FUNC -*/ -HWTEST_F(PictureInPictureControllerTest, GetPipContentCallbackRef, Function | SmallTest | Level2) -{ - sptr mw = new MockWindow(); - sptr option = new PipOption(); - sptr pipControl = new PictureInPictureController(option, mw, 100, nullptr); - pipControl->pipOption_ = nullptr; - pipControl->RegisterPipContentListenerWithType("nodeUpdate", nullptr); - ASSERT_EQ(nullptr, pipControl->GetPipContentCallbackRef("nodeUpdate")); - pipControl->pipOption_ = option; - pipControl->RegisterPipContentListenerWithType("nodeUpdate", nullptr); - ASSERT_EQ(nullptr, pipControl->GetPipContentCallbackRef("nodeUpdate")); -} -/** - -@tc.name: UpdateContentNodeRef -@tc.desc: UpdateContentNodeRef -@tc.type: FUNC -*/ -HWTEST_F(PictureInPictureControllerTest, UpdateContentNodeRef, Function | SmallTest | Level2) -{ - sptr mw = new MockWindow(); - sptr option = new PipOption(); - sptr pipControl = new PictureInPictureController(option, mw, 100, nullptr); - pipControl->pipOption_ = nullptr; - napi_ref nodeRef = nullptr; - pipControl->UpdateContentNodeRef(nodeRef); - pipControl->pipOption_ = option; - pipControl->pipOption_->SetTypeNodeEnabled(true); - pipControl->UpdateContentNodeRef(nodeRef); - pipControl->pipOption_->SetTypeNodeEnabled(false); - pipControl->UpdateContentNodeRef(nodeRef); - pipControl->isAutoStartEnabled_ = true; - pipControl->UpdateContentNodeRef(nodeRef); - pipControl->isAutoStartEnabled_ = false; - ASSERT_EQ(true, pipControl->IsTypeNodeEnabled()); -} } // namespace } // namespace Rosen } // namespace OHOS \ No newline at end of file diff --git a/wm/test/unittest/picture_in_picture_option_test.cpp b/wm/test/unittest/picture_in_picture_option_test.cpp index 20c435c84d..18d3511ba4 100644 --- a/wm/test/unittest/picture_in_picture_option_test.cpp +++ b/wm/test/unittest/picture_in_picture_option_test.cpp @@ -197,18 +197,6 @@ HWTEST_F(PictureInPictureOptionTest, TypeNodeEnabled, Function | SmallTest | Lev option->SetTypeNodeEnabled(false); ASSERT_TRUE(!option->IsTypeNodeEnabled()); } - -/** -@tc.name: GetPipContentCallbackRef -@tc.desc: RegisterPipContentListenerWithType/GetPipContentCallbackRef -@tc.type: FUNC -*/ -HWTEST_F(PictureInPictureOptionTest, GetPipContentCallbackRef, Function | SmallTest | Level2) -{ - sptr option = sptr::MakeSptr(); - option->RegisterPipContentListenerWithType("nodeUpdate", nullptr); - ASSERT_EQ(option->GetPipContentCallbackRef("nodeUpdate"), nullptr); -} } // namespace } // namespace Rosen } // namespace OHOS \ No newline at end of file -- Gitee From 176213c55880be04984091d3ee9ef713fd9ed61a Mon Sep 17 00:00:00 2001 From: jiangxiaofeng20 Date: Thu, 16 Jan 2025 16:20:09 +0800 Subject: [PATCH 10/13] pip Signed-off-by: jiangxiaofeng20 --- .../inner/js_pip_manager.cpp | 51 ++--- .../js_pip_controller.cpp | 13 +- resources/abc/pip/interface/PiPContent.js | 184 +++++++++--------- resources/abc/pip/source/PiPContent.ets | 16 +- wm/include/picture_in_picture_controller.h | 8 +- wm/include/picture_in_picture_option.h | 4 +- wm/src/picture_in_picture_controller.cpp | 4 +- wm/src/picture_in_picture_option.cpp | 2 +- .../picture_in_picture_controller_test.cpp | 78 ++++---- 9 files changed, 184 insertions(+), 176 deletions(-) diff --git a/interfaces/kits/napi/picture_in_picture_napi/inner/js_pip_manager.cpp b/interfaces/kits/napi/picture_in_picture_napi/inner/js_pip_manager.cpp index bcd0ab6995..0f70bc7a93 100644 --- a/interfaces/kits/napi/picture_in_picture_napi/inner/js_pip_manager.cpp +++ b/interfaces/kits/napi/picture_in_picture_napi/inner/js_pip_manager.cpp @@ -197,26 +197,25 @@ napi_value JsPipManager::SetPipNodeType(napi_env env, napi_callback_info info) napi_value JsPipManager::OnSetPipNodeType(napi_env env, napi_callback_info info) { TLOGD(WmsLogTag::WMS_PIP, "[NAPI]"); - size_t argc = NUMBER_FOUR; // 4: arg number + size_t argc = NUMBER_FOUR; napi_value argv[NUMBER_FOUR] = { nullptr }; napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr); - return NapiGetUndefined(env); - if (argc != NUMBER_TWO) { - TLOGE(WmsLogTag::WMS_PIP, "[NAPI]Argc count is invalid: %{public}zu", argc); + TLOGE(WmsLogTag::WMS_PIP, "Argc count is invalid:%{public}zu", argc); return NapiGetUndefined(env); } napi_value typeNode = argv[0]; bool markPip = false; if (!ConvertFromJsValue(env, argv[NUMBER_ONE], markPip)) { TLOGW(WmsLogTag::WMS_PIP, "Failed to convert param to bool"); + return NapiGetUndefined(env); } if (typeNode != nullptr && GetType(env, typeNode) != napi_undefined) { XComponentControllerErrorCode ret = - XComponentController::SetSurfaceCallbackMode(env, typeNode, markPip ? - SurfaceCallbackMode::PIP: SurfaceCallbackMode::DEFAULT); - TLOGI(WmsLogTag::WMS_PIP, "set surface mode, ret: %{public}u, isPip: %{public}d", - static_cast(ret), static_cast(markPip)); + XComponentController::SetSurfaceCallbackMode(env, typeNode, markPip ? + SurfaceCallbackMode::PIP: SurfaceCallbackMode::DEFAULT); + TLOGI(WmsLogTag::WMS_PIP, "set surface mode, ret:%{public}u, isPip:%{public}d", + static_cast(ret), static_cast(markPip)); } return NapiGetUndefined(env); } @@ -237,8 +236,8 @@ bool NapiIsCallable(napi_env env, napi_value value) napi_value JsPipManager::OnRegisterCallback(napi_env env, napi_callback_info info) { TLOGI(WmsLogTag::WMS_PIP, "[NAPI]"); - size_t argc = 4; - napi_value argv[4] = {nullptr}; + size_t argc = NUMBER_FOUR; + napi_value argv[NUMBER_FOUR] = {nullptr}; napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr); if (argc < NUMBER_TWO) { TLOGE(WmsLogTag::WMS_PIP, "Params count not match: %{public}zu", argc); @@ -249,9 +248,8 @@ napi_value JsPipManager::OnRegisterCallback(napi_env env, napi_callback_info inf TLOGE(WmsLogTag::WMS_PIP, "Failed to convert param to cbType"); return NapiThrowInvalidParam(env); } - auto iter = find(PIP_CONTENT_CALLBACK.begin(), PIP_CONTENT_CALLBACK.end(), cbType); - if (iter == PIP_CONTENT_CALLBACK.end()) { - TLOGE(WmsLogTag::WMS_PIP, "Callback is null or not callable"); + if (PIP_CONTENT_CALLBACK.count(cbType) == 0) { + TLOGE(WmsLogTag::WMS_PIP, "cbType is not in PIP_CONTENT_CALLBACK"); return NapiThrowInvalidParam(env); } napi_value value = argv[1]; @@ -264,16 +262,21 @@ napi_value JsPipManager::OnRegisterCallback(napi_env env, napi_callback_info inf napi_create_reference(env, value, 1, &result); callbackRef.reset(reinterpret_cast(result)); sptr pipWindow = Window::Find(PIP_WINDOW_NAME); + if (pipWindow == nullptr) { + TLOGE(WmsLogTag::WMS_PIP, "Failed to find pip window"); + return NapiGetUndefined(env); + } int32_t windowId = static_cast(pipWindow->GetWindowId()); sptr pipController = PictureInPictureManager::GetPipControllerInfo(windowId); if (pipController == nullptr) { TLOGE(WmsLogTag::WMS_PIP, "Failed to get pictureInPictureController"); return NapiGetUndefined(env); } - TLOGI(WmsLogTag::WMS_PIP, "OnRegisterCallback to window: %{public}u", windowId); + TLOGI(WmsLogTag::WMS_PIP, "OnRegisterCallback to window:%{public}d", windowId); WMError errCode = pipController->RegisterPipContentListenerWithType(cbType, callbackRef); if (errCode != WMError::WM_OK) { TLOGE(WmsLogTag::WMS_PIP, "Failed to registerCallback"); + return NapiGetUndefined(env); } TLOGI(WmsLogTag::WMS_PIP, "Register type %{public}s success!", cbType.c_str()); return NapiGetUndefined(env); @@ -288,11 +291,11 @@ napi_value JsPipManager::UnregisterCallback(napi_env env, napi_callback_info inf napi_value JsPipManager::OnUnregisterCallback(napi_env env, napi_callback_info info) { TLOGI(WmsLogTag::WMS_PIP, "[NAPI]"); - size_t argc = 4; - napi_value argv[4] = {nullptr}; + size_t argc = NUMBER_FOUR; + napi_value argv[NUMBER_FOUR] = {nullptr}; napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr); if (argc != NUMBER_ONE) { - TLOGE(WmsLogTag::WMS_PIP, "Params count not match: %{public}zu", argc); + TLOGE(WmsLogTag::WMS_PIP, "Params count not match:%{public}zu", argc); return NapiThrowInvalidParam(env); } std::string cbType; @@ -300,24 +303,28 @@ napi_value JsPipManager::OnUnregisterCallback(napi_env env, napi_callback_info i TLOGE(WmsLogTag::WMS_PIP, "Failed to convert param to cbType"); return NapiThrowInvalidParam(env); } - auto iter = find(PIP_CONTENT_CALLBACK.begin(), PIP_CONTENT_CALLBACK.end(), cbType); - if (iter == PIP_CONTENT_CALLBACK.end()) { - TLOGE(WmsLogTag::WMS_PIP, "Callback is null or not callable"); + if (PIP_CONTENT_CALLBACK.count(cbType) == 0) { + TLOGE(WmsLogTag::WMS_PIP, "cbType is not in PIP_CONTENT_CALLBACK"); return NapiThrowInvalidParam(env); } sptr pipWindow = Window::Find(PIP_WINDOW_NAME); + if (pipWindow == nullptr) { + TLOGE(WmsLogTag::WMS_PIP, "Failed to find pip window"); + return NapiGetUndefined(env); + } int32_t windowId = static_cast(pipWindow->GetWindowId()); sptr pipController = PictureInPictureManager::GetPipControllerInfo(windowId); if (pipController == nullptr) { TLOGE(WmsLogTag::WMS_PIP, "Failed to get pictureInPictureController"); return NapiGetUndefined(env); } - TLOGI(WmsLogTag::WMS_PIP, "UnRegisterPipContentListenerWithType to window: %{public}u", windowId); + TLOGI(WmsLogTag::WMS_PIP, "UnRegisterPipContentListenerWithType to window:%{public}d", windowId); WMError errCode = pipController->UnRegisterPipContentListenerWithType(cbType); if (errCode != WMError::WM_OK) { TLOGE(WmsLogTag::WMS_PIP, "Failed to set UnRegisterPipContentListenerWithType"); + return NapiGetUndefined(env); } - TLOGI(WmsLogTag::WMS_PIP, "unregister type %{public}s success!", cbType.c_str()); + TLOGI(WmsLogTag::WMS_PIP, "unregister type:%{public}s success!", cbType.c_str()); return NapiGetUndefined(env); } diff --git a/interfaces/kits/napi/picture_in_picture_napi/js_pip_controller.cpp b/interfaces/kits/napi/picture_in_picture_napi/js_pip_controller.cpp index 68045a1ebb..f3501295a0 100644 --- a/interfaces/kits/napi/picture_in_picture_napi/js_pip_controller.cpp +++ b/interfaces/kits/napi/picture_in_picture_napi/js_pip_controller.cpp @@ -14,7 +14,6 @@ */ #include "js_pip_controller.h" - #include "js_pip_utils.h" #include "picture_in_picture_manager.h" #include "window_manager_hilog.h" @@ -196,17 +195,17 @@ napi_value JsPipController::UpdateContentNode(napi_env env, napi_callback_info i napi_value JsPipController::OnUpdateContentNode(napi_env env, napi_callback_info info) { TLOGI(WmsLogTag::WMS_PIP, "OnUpdateContentNode is called"); - size_t argc = 4; - napi_value argv[4] = {nullptr}; + size_t argc = NUMBER_FOUR; + napi_value argv[NUMBER_FOUR] = {nullptr}; napi_get_cb_info(env, info, &argc, argv, nullptr, nullptr); if (argc != NUMBER_ONE) { - TLOGE(WmsLogTag::WMS_PIP, "[NAPI]Argc count is invalid: %{public}zu", argc); + TLOGE(WmsLogTag::WMS_PIP, "Argc count is invalid:%{public}zu", argc); return NapiThrowInvalidParam(env, "Invalid args count, 1 arg is needed."); } napi_value typeNode = argv[0]; if (typeNode == nullptr || GetType(env, typeNode) == napi_undefined) { - TLOGE(WmsLogTag::WMS_PIP, "[NAPI] invalid typeNode"); - return NapiThrowInvalidParam(env, "invalid typeNode."); + TLOGE(WmsLogTag::WMS_PIP, "Invalid typeNode"); + return NapiThrowInvalidParam(env, "Invalid typeNode."); } if (pipController_ == nullptr) { std::string errMsg = "OnUpdateNode error, controller is nullptr"; @@ -214,7 +213,7 @@ napi_value JsPipController::OnUpdateContentNode(napi_env env, napi_callback_info return NapiThrowInvalidParam(env, errMsg); } napi_ref typeNodeRef = nullptr; - napi_create_reference(env, typeNode, 1, &typeNodeRef); + napi_create_reference(env, typeNode, NUMBER_ONE, &typeNodeRef); pipController_->UpdateContentNodeRef(typeNodeRef); return NapiGetUndefined(env); } diff --git a/resources/abc/pip/interface/PiPContent.js b/resources/abc/pip/interface/PiPContent.js index 6320b7e29f..80569ecd78 100644 --- a/resources/abc/pip/interface/PiPContent.js +++ b/resources/abc/pip/interface/PiPContent.js @@ -21,121 +21,144 @@ const TAG = 'PiPContent'; const ABOUT_TO_STOP = 3; class XCNodeController extends NodeController { - constructor(k2) { + constructor(m2) { super(); this.node = null; - this.mXComponent = k2; + this.mXComponent = m2; } - - makeNode(i2) { - let j2; - this.node = new FrameNode(i2); + makeNode(l2) { + this.node = new FrameNode(l2); this.node.appendChild(this.mXComponent); return this.node; } - - replaceNode(r2) { - let s2; - let t2; - (s2 = this.node) === null || s2 === void 0 ? void 0 : s2.removeChild(this.mXComponent); - this.mXComponent = r2; - (t2 = this.node) === null || t2 === void 0 ? void 0 : t2.appendChild(this.mXComponent); + replaceNode(k) { + this.node?.removeChild(this.mXComponent); + this.mXComponent = k; + this.node?.appendChild(this.mXComponent); } - removeNode() { - let h2; - (h2 = this.node) === null || h2 === void 0 ? void 0 : h2.removeChild(this.mXComponent); + this.node?.removeChild(this.mXComponent); } } class PiPContent extends ViewPU { - constructor(b2, c2, d2, e2 = -1, f2 = undefined, g2) { - super(b2, d2, e2, g2); + constructor(f2, g2, h2, i2 = -1, j2 = undefined, k2) { + super(f2, h2, i2, k2); if (typeof f2 === 'function') { - this.paramsGenerator_ = f2; + this.paramsGenerator_ = j2; } - this.xComponentController = new XComponentController; + this.xComponentController = new XComponentController(); this.nodeController = null; this.mXCNodeController = null; this.__useNode = new ObservedPropertySimplePU(false, this, 'useNode'); this.__nodeChange = new ObservedPropertySimplePU(false, this, 'nodeChange'); + this.xComponent = null; this.xComponentId = 'pipContent'; this.xComponentType = 'surface'; - this.xComponent = null; - this.setInitiallyProvidedValue(c2); + this.setInitiallyProvidedValue(g2); + this.finalizeConstruction(); } - - setInitiallyProvidedValue(a2) { - if (a2.xComponentController !== undefined) { - this.xComponentController = a2.xComponentController; + setInitiallyProvidedValue(e2) { + if (e2.xComponentController !== undefined) { + this.xComponentController = e2.xComponentController; } - if (a2.nodeController !== undefined) { - this.nodeController = a2.nodeController; + if (e2.nodeController !== undefined) { + this.nodeController = e2.nodeController; } - if (a2.mXCNodeController !== undefined) { - this.mXCNodeController = a2.mXCNodeController; + if (e2.mXCNodeController !== undefined) { + this.mXCNodeController = e2.mXCNodeController; } - if (a2.useNode !== undefined) { - this.useNode = a2.useNode; + if (e2.useNode !== undefined) { + this.useNode = e2.useNode; } - if (a2.nodeChange !== undefined) { - this.nodeChange = a2.nodeChange; + if (e2.nodeChange !== undefined) { + this.nodeChange = e2.nodeChange; } - if (a2.xComponentId !== undefined) { - this.xComponentId = a2.xComponentId; + if (e2.xComponent !== undefined) { + this.xComponent = e2.xComponent; } - if (a2.xComponentType !== undefined) { - this.xComponentType = a2.xComponentType; + if (e2.xComponentId !== undefined) { + this.xComponentId = e2.xComponentId; } - if (a2.xComponent !== undefined) { - this.xComponent = a2.xComponent; + if (e2.xComponentType !== undefined) { + this.xComponentType = e2.xComponentType; } } - - updateStateVars(z1) { + updateStateVars(d2) { } - - purgeVariableDependenciesOnElmtId(h2) { - this.__useNode.purgeDependencyOnElmtId(h2); - this.__nodeChange.purgeDependencyOnElmtId(h2); + purgeVariableDependenciesOnElmtId(c2) { + this.__useNode.purgeDependencyOnElmtId(c2); + this.__nodeChange.purgeDependencyOnElmtId(c2); } - aboutToBeDeleted() { this.__useNode.aboutToBeDeleted(); this.__nodeChange.aboutToBeDeleted(); SubscriberManager.Get().delete(this.id__()); this.aboutToBeDeletedInternal(); } - get useNode() { return this.__useNode.get(); } - - set useNode(b) { - this.__useNode.set(b); + set useNode(j) { + this.__useNode.set(j); } - get nodeChange() { return this.__nodeChange.get(); } - - set nodeChange(a) { - this.__nodeChange.set(a); + set nodeChange(i) { + this.__nodeChange.set(i); } - - validateNode(f2) { - if (f2 === null || f2 === undefined) { + validateNode(g) { + if (g === null || g === undefined) { console.error(TAG, `validateNode node is null`); return false; } - let g2 = f2.getNodeType(); - if (g2 !== 'XComponent') { - console.error(TAG, `node type mismatch: ${g2}`); + let h = g.getNodeType(); + if (h !== 'XComponent') { + console.error(TAG, `node type mismatch: ${h}`); return false; } return true; } - + registerUpdateNodeListener() { + pip.on('nodeUpdate', (f) => { + console.info(TAG, `nodeUpdate`); + if (!this.validateNode(f)) { + return; + } + if (this.useNode) { + pip.setPipNodeType(this.xComponent, false); + this.updatePipNodeType(f); + this.mXCNodeController?.replaceNode(f); + this.nodeChange = true; + } + else { + this.updatePipNodeType(f); + this.mXCNodeController = new XCNodeController(f); + console.info(TAG, 'update to Node Controller'); + this.registerStateChangeListener(); + this.useNode = true; + } + }); + } + updatePipNodeType(c) { + let d = c.getParent(); + if (d === null || d === undefined) { + pip.setPipNodeType(c, false); + } + else { + pip.setPipNodeType(c, true); + d.removeChild(c); + } + } + registerStateChangeListener() { + pip.on('stateChange', (b) => { + console.info(TAG, `stateChange state:${b}`); + if (b === ABOUT_TO_STOP) { + this.mXCNodeController?.removeNode(); + } + }); + } aboutToAppear() { this.nodeController = pip.getCustomUIController(); this.registerUpdateNodeListener(); @@ -143,45 +166,18 @@ class PiPContent extends ViewPU { if (!this.validateNode(this.xComponent)) { return; } - this.updatePipNodeType(this.xComponent); + if (this.xComponent === null) { + console.error(TAG, `validateNode node is null`); + return; + } this.useNode = true; + this.updatePipNodeType(this.xComponent); pip.setTypeNodeEnabled(); this.mXCNodeController = new XCNodeController(this.xComponent); console.info(TAG, 'use Node Controller'); this.registerStateChangeListener(); } - registerStateChangeListener() { - pip.on('stateChange', (y1) => { - let z1; - console.info(TAG, `stateChange state:${y1}`); - if (y1 === ABOUT_TO_STOP) { - (z1 = this.mXCNodeController) === null || z1 === void 0 ? void 0 : z1.removeNode(); - } - }); - } - - registerUpdateNodeListener() { - pip.on('nodeUpdate', (d2) => { - let e2; - console.info(TAG, `nodeUpdate`); - if (!this.validateNode(d2)) { - return; - } - if (this.useNode) { - this.updatePipNodeType(d2); - (e2 = this.mXCNodeController) === null || e2 === void 0 ? void 0 : e2.replaceNode(d2); - this.nodeChange = true; - } else { - this.updatePipNodeType(d2); - this.mXCNodeController = new XCNodeController(d2); - console.info(TAG, 'update to Node Controller'); - this.registerStateChangeListener(); - this.useNode = true; - } - }); - } - updatePipNodeType(a2) { let b2 = a2.getParent(); if (b2 === null || b2 === undefined) { diff --git a/resources/abc/pip/source/PiPContent.ets b/resources/abc/pip/source/PiPContent.ets index bd715e5dc5..05e28a5108 100644 --- a/resources/abc/pip/source/PiPContent.ets +++ b/resources/abc/pip/source/PiPContent.ets @@ -14,7 +14,7 @@ */ import pip from '@ohos.pip'; -import { NodeController, FrameNode, TypedFrameNode, UIContext } from '@kit.ArkUI'; +import { NodeController, FrameNode, UIContext, typeNode } from '@kit.ArkUI'; const TAG: string = 'PiPContent'; const ABOUT_TO_STOP = 3; @@ -102,11 +102,11 @@ struct PiPContent { } private registerStateChangeListener() { - pip.on('stateChange', (state: number) => { - console.info(TAG, `stateChange state:${state}`); - if (state === ABOUT_TO_STOP) { - this.mXCNodeController?.removeNode(); - } + pip.on('stateChange', (state: number) => { + console.info(TAG, `stateChange state:${state}`); + if (state === ABOUT_TO_STOP) { + this.mXCNodeController?.removeNode(); + } }) } @@ -117,6 +117,10 @@ struct PiPContent { if (!this.validateNode(this.xComponent)) { return; } + if (this.xComponent === null) { + console.error(TAG, `validateNode node is null`); + return; + } this.useNode = true; this.updatePipNodeType(this.xComponent); pip.setTypeNodeEnabled(); diff --git a/wm/include/picture_in_picture_controller.h b/wm/include/picture_in_picture_controller.h index 6d16c5d564..5ca71da36f 100644 --- a/wm/include/picture_in_picture_controller.h +++ b/wm/include/picture_in_picture_controller.h @@ -84,16 +84,16 @@ public: WMError RegisterPiPLifecycle(const sptr& listener); WMError RegisterPiPActionObserver(const sptr& listener); WMError RegisterPiPControlObserver(const sptr& listener); + WMError RegisterPipContentListenerWithType(const std::string&, + std::shared_ptr updateNodeCallbackRef); WMError UnregisterPiPLifecycle(const sptr& listener); WMError UnregisterPiPActionObserver(const sptr& listener); WMError UnregisterPiPControlObserver(const sptr& listener); + WMError UnRegisterPipContentListenerWithType(const std::string&); sptr GetPictureInPictureLifecycle() const; sptr GetPictureInPictureActionObserver() const; sptr GetPictureInPictureControlObserver() const; std::shared_ptr GetPipContentCallbackRef(const std::string&); - WMError RegisterPipContentListenerWithType(const std::string&, - std::shared_ptr updateNodeCallbackRef); - WMError UnRegisterPipContentListenerWithType(const std::string&); WMError SetXComponentController(std::shared_ptr xComponentController); PiPWindowState GetControllerState(); std::string GetPiPNavigationId(); @@ -122,6 +122,8 @@ private: void NotifyStateChangeInner(napi_env env, PiPState state); template WMError RegisterListener(std::vector>& holder, const sptr& listener); template WMError UnregisterListener(std::vector>& holder, const sptr& listener); + void NotifyNodeUpdate(napi_ref nodeRef); + void NotifyStateChangeInner(napi_env env, PiPState state); wptr weakRef_ = nullptr; sptr pipOption_ = nullptr; std::vector> pipLifeCycleListeners_; diff --git a/wm/include/picture_in_picture_option.h b/wm/include/picture_in_picture_option.h index c08204ab58..753964fbf3 100644 --- a/wm/include/picture_in_picture_option.h +++ b/wm/include/picture_in_picture_option.h @@ -17,10 +17,10 @@ #define OHOS_PIP_OPTION_H #include #include +#include "js_runtime_utils.h" #include "xcomponent_controller.h" #include "napi/native_api.h" #include "wm_common.h" -#include "js_runtime_utils.h" namespace OHOS { namespace Rosen { @@ -37,6 +37,7 @@ public: void SetPiPControlEnabled(PiPControlType controlType, PiPControlStatus enabled); void SetXComponentController(std::shared_ptr xComponentController); void RegisterPipContentListenerWithType(const std::string&, std::shared_ptr updateNodeCallbackRef); + void UnRegisterPipContentListenerWithType(const std::string&); void SetControlGroup(std::vector controlGroup); void* GetContext() const; std::string GetNavigationId() const; @@ -47,7 +48,6 @@ public: void GetContentSize(uint32_t& width, uint32_t& height); std::shared_ptr GetXComponentController(); std::shared_ptr GetPipContentCallbackRef(const std::string&); - void UnRegisterPipContentListenerWithType(const std::string&); void SetNodeControllerRef(napi_ref ref); napi_ref GetNodeControllerRef() const; void SetTypeNodeRef(napi_ref ref); diff --git a/wm/src/picture_in_picture_controller.cpp b/wm/src/picture_in_picture_controller.cpp index 4194be4d29..562a083dd1 100644 --- a/wm/src/picture_in_picture_controller.cpp +++ b/wm/src/picture_in_picture_controller.cpp @@ -38,6 +38,7 @@ namespace { static napi_value CallJsFunction(napi_env env, napi_value method, napi_value const * argv, size_t argc) { + TLOGD(WmsLogTag::WMS_PIP, "called."); if (env == nullptr || method == nullptr) { TLOGE(WmsLogTag::WMS_PIP, "env nullptr or method is nullptr"); return nullptr; @@ -47,7 +48,6 @@ static napi_value CallJsFunction(napi_env env, napi_value method, napi_value con 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; } @@ -786,7 +786,7 @@ void PictureInPictureController::NotifyStateChangeInner(napi_env env, PiPState s if (innerCallbackRef == nullptr) { return; } - napi_value value[] = { AbilityRuntime::CreateJsValue(env, static_cast(state))}; + napi_value value[] = {AbilityRuntime::CreateJsValue(env, static_cast(state))}; CallJsFunction(env, innerCallbackRef->GetNapiValue(), value, 1); } diff --git a/wm/src/picture_in_picture_option.cpp b/wm/src/picture_in_picture_option.cpp index 03e9eb0a37..17b8796544 100644 --- a/wm/src/picture_in_picture_option.cpp +++ b/wm/src/picture_in_picture_option.cpp @@ -13,8 +13,8 @@ * limitations under the License. */ -#include "picture_in_picture_option.h" #include "js_runtime_utils.h" +#include "picture_in_picture_option.h" namespace OHOS { namespace Rosen { diff --git a/wm/test/unittest/picture_in_picture_controller_test.cpp b/wm/test/unittest/picture_in_picture_controller_test.cpp index 787c515b4a..ad21fbcadf 100644 --- a/wm/test/unittest/picture_in_picture_controller_test.cpp +++ b/wm/test/unittest/picture_in_picture_controller_test.cpp @@ -962,14 +962,14 @@ HWTEST_F(PictureInPictureControllerTest, SetXComponentController, Function | Sma */ HWTEST_F(PictureInPictureControllerTest, RegisterPipContentListenerWithType, Function | SmallTest | Level2) { -sptr mw = new MockWindow(); -sptr option = new PipOption(); -sptr pipControl = new PictureInPictureController(option, mw, 100, nullptr); -pipControl->pipOption_ = nullptr; -ASSERT_EQ(WMError::WM_ERROR_PIP_STATE_ABNORMALLY, - pipControl->RegisterPipContentListenerWithType("nodeUpdate", nullptr)); -pipControl->pipOption_ = option; -ASSERT_EQ(WMError::WM_OK, pipControl->RegisterPipContentListenerWithType("nodeUpdate", nullptr)); + sptr mw = new MockWindow(); + sptr option = new PipOption(); + sptr pipControl = new PictureInPictureController(option, mw, 100, nullptr); + pipControl->pipOption_ = nullptr; + ASSERT_EQ(WMError::WM_ERROR_PIP_STATE_ABNORMALLY, + pipControl->RegisterPipContentListenerWithType("nodeUpdate", nullptr)); + pipControl->pipOption_ = option; + ASSERT_EQ(WMError::WM_OK, pipControl->RegisterPipContentListenerWithType("nodeUpdate", nullptr)); } /** @@ -979,13 +979,13 @@ ASSERT_EQ(WMError::WM_OK, pipControl->RegisterPipContentListenerWithType("nodeUp */ HWTEST_F(PictureInPictureControllerTest, UnRegisterPipContentListenerWithType, Function | SmallTest | Level2) { -sptr mw = new MockWindow(); -sptr option = new PipOption(); -sptr pipControl = new PictureInPictureController(option, mw, 100, nullptr); -pipControl->pipOption_ = nullptr; -ASSERT_EQ(WMError::WM_ERROR_PIP_STATE_ABNORMALLY, pipControl->UnRegisterPipContentListenerWithType("nodeUpdate")); -pipControl->pipOption_ = option; -ASSERT_EQ(WMError::WM_OK, pipControl->UnRegisterPipContentListenerWithType("nodeUpdate")); + sptr mw = new MockWindow(); + sptr option = new PipOption(); + sptr pipControl = new PictureInPictureController(option, mw, 100, nullptr); + pipControl->pipOption_ = nullptr; + ASSERT_EQ(WMError::WM_ERROR_PIP_STATE_ABNORMALLY, pipControl->UnRegisterPipContentListenerWithType("nodeUpdate")); + pipControl->pipOption_ = option; + ASSERT_EQ(WMError::WM_OK, pipControl->UnRegisterPipContentListenerWithType("nodeUpdate")); } /** @@ -995,15 +995,15 @@ ASSERT_EQ(WMError::WM_OK, pipControl->UnRegisterPipContentListenerWithType("node */ HWTEST_F(PictureInPictureControllerTest, GetPipContentCallbackRef, Function | SmallTest | Level2) { -sptr mw = new MockWindow(); -sptr option = new PipOption(); -sptr pipControl = new PictureInPictureController(option, mw, 100, nullptr); -pipControl->pipOption_ = nullptr; -pipControl->RegisterPipContentListenerWithType("nodeUpdate", nullptr); -ASSERT_EQ(nullptr, pipControl->GetPipContentCallbackRef("nodeUpdate")); -pipControl->pipOption_ = option; -pipControl->RegisterPipContentListenerWithType("nodeUpdate", nullptr); -ASSERT_EQ(nullptr, pipControl->GetPipContentCallbackRef("nodeUpdate")); + sptr mw = new MockWindow(); + sptr option = new PipOption(); + sptr pipControl = new PictureInPictureController(option, mw, 100, nullptr); + pipControl->pipOption_ = nullptr; + pipControl->RegisterPipContentListenerWithType("nodeUpdate", nullptr); + ASSERT_EQ(nullptr, pipControl->GetPipContentCallbackRef("nodeUpdate")); + pipControl->pipOption_ = option; + pipControl->RegisterPipContentListenerWithType("nodeUpdate", nullptr); + ASSERT_EQ(nullptr, pipControl->GetPipContentCallbackRef("nodeUpdate")); } /** @@ -1013,21 +1013,21 @@ ASSERT_EQ(nullptr, pipControl->GetPipContentCallbackRef("nodeUpdate")); */ HWTEST_F(PictureInPictureControllerTest, UpdateContentNodeRef, Function | SmallTest | Level2) { -sptr mw = new MockWindow(); -sptr option = new PipOption(); -sptr pipControl = new PictureInPictureController(option, mw, 100, nullptr); -pipControl->pipOption_ = nullptr; -napi_ref nodeRef = nullptr; -pipControl->UpdateContentNodeRef(nodeRef); -pipControl->pipOption_ = option; -pipControl->pipOption_->SetTypeNodeEnabled(true); -pipControl->UpdateContentNodeRef(nodeRef); -pipControl->pipOption_->SetTypeNodeEnabled(false); -pipControl->UpdateContentNodeRef(nodeRef); -pipControl->isAutoStartEnabled_ = true; -pipControl->UpdateContentNodeRef(nodeRef); -pipControl->isAutoStartEnabled_ = false; -ASSERT_EQ(true, pipControl->IsTypeNodeEnabled()); + sptr mw = new MockWindow(); + sptr option = new PipOption(); + sptr pipControl = new PictureInPictureController(option, mw, 100, nullptr); + pipControl->pipOption_ = nullptr; + napi_ref nodeRef = nullptr; + pipControl->UpdateContentNodeRef(nodeRef); + pipControl->pipOption_ = option; + pipControl->pipOption_->SetTypeNodeEnabled(true); + pipControl->UpdateContentNodeRef(nodeRef); + pipControl->pipOption_->SetTypeNodeEnabled(false); + pipControl->UpdateContentNodeRef(nodeRef); + pipControl->isAutoStartEnabled_ = true; + pipControl->UpdateContentNodeRef(nodeRef); + pipControl->isAutoStartEnabled_ = false; + ASSERT_EQ(true, pipControl->IsTypeNodeEnabled()); } /** -- Gitee From c31b3bba2fc5c87e633c29a07a893609f82b588b Mon Sep 17 00:00:00 2001 From: jiangxiaofeng20 Date: Thu, 16 Jan 2025 11:33:39 +0000 Subject: [PATCH 11/13] update wm/include/picture_in_picture_controller.h. Signed-off-by: jiangxiaofeng20 --- wm/include/picture_in_picture_controller.h | 2 -- 1 file changed, 2 deletions(-) diff --git a/wm/include/picture_in_picture_controller.h b/wm/include/picture_in_picture_controller.h index 5ca71da36f..1516c9868a 100644 --- a/wm/include/picture_in_picture_controller.h +++ b/wm/include/picture_in_picture_controller.h @@ -118,8 +118,6 @@ private: void UpdatePiPSourceRect() const; void ResetExtController(); bool IsPullPiPAndHandleNavigation(); - void NotifyNodeUpdate(napi_ref nodeRef); - void NotifyStateChangeInner(napi_env env, PiPState state); template WMError RegisterListener(std::vector>& holder, const sptr& listener); template WMError UnregisterListener(std::vector>& holder, const sptr& listener); void NotifyNodeUpdate(napi_ref nodeRef); -- Gitee From 1fde262a05db4dddd61d3453ac38642b9ff3f176 Mon Sep 17 00:00:00 2001 From: jiangxiaofeng20 Date: Thu, 16 Jan 2025 21:04:44 +0800 Subject: [PATCH 12/13] pip Signed-off-by: jiangxiaofeng20 --- wm/include/picture_in_picture_option.h | 2 +- wm/src/picture_in_picture_controller.cpp | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/wm/include/picture_in_picture_option.h b/wm/include/picture_in_picture_option.h index 753964fbf3..0b54929ad5 100644 --- a/wm/include/picture_in_picture_option.h +++ b/wm/include/picture_in_picture_option.h @@ -18,8 +18,8 @@ #include #include #include "js_runtime_utils.h" -#include "xcomponent_controller.h" #include "napi/native_api.h" +#include "xcomponent_controller.h" #include "wm_common.h" namespace OHOS { diff --git a/wm/src/picture_in_picture_controller.cpp b/wm/src/picture_in_picture_controller.cpp index 562a083dd1..2d8f6f65f5 100644 --- a/wm/src/picture_in_picture_controller.cpp +++ b/wm/src/picture_in_picture_controller.cpp @@ -531,7 +531,7 @@ void PictureInPictureController::NotifyNodeUpdate(napi_ref nodeRef) } napi_value typeNode = nullptr; napi_get_reference_value(env_, nodeRef, &typeNode); - napi_value value[] = {typeNode}; + napi_value value[] = { typeNode }; CallJsFunction(env_, updateNodeCallbackRef->GetNapiValue(), value, 1); SingletonContainer::Get().ReportPiPUpdateContent(static_cast(IsTypeNodeEnabled()), pipOption_->GetPipTemplate(), PIP_SUCCESS, "updateNode success"); @@ -755,7 +755,7 @@ WMError PictureInPictureController::SetXComponentController(std::shared_ptr callbackRef) { - TLOGI(WmsLogTag::WMS_PIP, "called"); + TLOGI(WmsLogTag::WMS_PIP, "Register type:%{public}s", type.c_str()); if (pipOption_ == nullptr) { TLOGE(WmsLogTag::WMS_PIP, "Get PictureInPicture option failed"); return WMError::WM_ERROR_PIP_STATE_ABNORMALLY; @@ -766,7 +766,7 @@ WMError PictureInPictureController::RegisterPipContentListenerWithType(const std WMError PictureInPictureController::UnRegisterPipContentListenerWithType(const std::string& type) { - TLOGI(WmsLogTag::WMS_PIP, "called"); + TLOGI(WmsLogTag::WMS_PIP, "Unregister type:%{public}s", type.c_str()); if (pipOption_ == nullptr) { TLOGE(WmsLogTag::WMS_PIP, "Get PictureInPicture option failed"); return WMError::WM_ERROR_PIP_STATE_ABNORMALLY; -- Gitee From ed03633a2aa3cd3a95886dd5f32705077286d27b Mon Sep 17 00:00:00 2001 From: jiangxiaofeng20 Date: Thu, 16 Jan 2025 21:09:17 +0800 Subject: [PATCH 13/13] pip Signed-off-by: jiangxiaofeng20 --- wm/include/picture_in_picture_option.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wm/include/picture_in_picture_option.h b/wm/include/picture_in_picture_option.h index 0b54929ad5..13f25750df 100644 --- a/wm/include/picture_in_picture_option.h +++ b/wm/include/picture_in_picture_option.h @@ -19,8 +19,8 @@ #include #include "js_runtime_utils.h" #include "napi/native_api.h" -#include "xcomponent_controller.h" #include "wm_common.h" +#include "xcomponent_controller.h" namespace OHOS { namespace Rosen { -- Gitee