diff --git a/interfaces/innerkits/wm/window_manager.h b/interfaces/innerkits/wm/window_manager.h index 1db684ff1f220748ce05812d5b205d2551d5fcca..b29999c253482bc1354e722a8da8cc3a3f4b36d4 100644 --- a/interfaces/innerkits/wm/window_manager.h +++ b/interfaces/innerkits/wm/window_manager.h @@ -1254,6 +1254,15 @@ public: */ WMError MinimizeByWindowId(const std::vector& windowIds); + /** + * @brief Set the animation speed multiplier for a specific process. + * + * @param pid process id. + * @param multiplier The animation speed multiplier. + * @return WM_OK means set success, others means set failed. + */ + WMError UpdateAnimationSpeedMultiplerForPid(pid_t pid, float multiplier); + /** * @brief Set foreground window number. Only main window. Only support freeMultiWindow. * diff --git a/window_scene/session/container/include/zidl/session_stage_interface.h b/window_scene/session/container/include/zidl/session_stage_interface.h index c08cbf3016335d083ac1d8a4f50e11a7991269c6..3f296bbaaa2f5e2c3a71f308340f62e59e61a0a1 100644 --- a/window_scene/session/container/include/zidl/session_stage_interface.h +++ b/window_scene/session/container/include/zidl/session_stage_interface.h @@ -206,6 +206,7 @@ public: return WSError::WS_OK; } virtual void SetUniqueVirtualPixelRatio(bool useUniqueDensity, float virtualPixelRatio) = 0; + virtual void ApplyAnimationSpeedMultiplier(float multiplier) = 0; virtual void NotifySessionFullScreen(bool fullScreen) {} // **Non** IPC interface diff --git a/window_scene/session/container/include/zidl/session_stage_ipc_interface_code.h b/window_scene/session/container/include/zidl/session_stage_ipc_interface_code.h index 99cacaf6c490f3bb030bd27935740f7ab74ecac0..4e906ec676d267065ff5635dd61c62ace7e563ca 100644 --- a/window_scene/session/container/include/zidl/session_stage_ipc_interface_code.h +++ b/window_scene/session/container/include/zidl/session_stage_ipc_interface_code.h @@ -97,6 +97,8 @@ enum class SessionStageInterfaceCode { TRANS_ID_UPDATE_GLOBAL_DISPLAY_RECT, // Floating ball TRANS_ID_SEND_FB_ACTION_EVENT, + + TRANS_ID_APPLY_ANIMATION_SPEED_MULTIPLIER, }; } // namespace Rosen } // namespace OHOS diff --git a/window_scene/session/container/include/zidl/session_stage_proxy.h b/window_scene/session/container/include/zidl/session_stage_proxy.h index 700cc196d965c970f8d0e2e742a4af4e7a6874a0..2ce7923c17abdce37cba768271fee31b87f3161c 100644 --- a/window_scene/session/container/include/zidl/session_stage_proxy.h +++ b/window_scene/session/container/include/zidl/session_stage_proxy.h @@ -80,6 +80,7 @@ public: WSError PcAppInPadNormalClose() override; WSError NotifyCompatibleModePropertyChange(const sptr property) override; void SetUniqueVirtualPixelRatio(bool useUniqueDensity, float virtualPixelRatio) override; + void ApplyAnimationSpeedMultiplier(float multiplier) override; void NotifySessionFullScreen(bool fullScreen) override; WSError NotifyTargetRotationInfo(OrientationInfo& Info) override; RotationChangeResult NotifyRotationChange(const RotationChangeInfo& rotationChangeInfo) override; diff --git a/window_scene/session/container/include/zidl/session_stage_stub.h b/window_scene/session/container/include/zidl/session_stage_stub.h index 79e0024968fbfcdf562f74a446c8781adc971718..e76c785b86a4a08e42c2b93309c4193c99887e58 100644 --- a/window_scene/session/container/include/zidl/session_stage_stub.h +++ b/window_scene/session/container/include/zidl/session_stage_stub.h @@ -80,6 +80,7 @@ private: int HandlePcAppInPadNormalClose(MessageParcel& data, MessageParcel& reply); int HandleNotifyCompatibleModePropertyChange(MessageParcel& data, MessageParcel& reply); int HandleSetUniqueVirtualPixelRatio(MessageParcel& data, MessageParcel& reply); + int HandleApplyAnimationSpeedMultiplier(MessageParcel& data, MessageParcel& reply); int HandleNotifySessionFullScreen(MessageParcel& data, MessageParcel& reply); int HandleNotifyDumpInfo(MessageParcel& data, MessageParcel& reply); int HandleExtensionHostData(MessageParcel& data, MessageParcel& reply, MessageOption& option); diff --git a/window_scene/session/container/src/zidl/session_stage_proxy.cpp b/window_scene/session/container/src/zidl/session_stage_proxy.cpp index 05c8b318be2b10b958b37cc411ed1ee5c0919f41..73ee13514f84221b260e41af0a11c6ddb6fc36bc 100644 --- a/window_scene/session/container/src/zidl/session_stage_proxy.cpp +++ b/window_scene/session/container/src/zidl/session_stage_proxy.cpp @@ -1590,6 +1590,34 @@ void SessionStageProxy::SetUniqueVirtualPixelRatio(bool useUniqueDensity, float } } +void SessionStageProxy::ApplyAnimationSpeedMultiplier(float multiplier) +{ + sptr remote = Remote(); + if (remote == nullptr) { + TLOGE(WmsLogTag::WMS_ANIMATION, "remote is nullptr"); + return; + } + + MessageParcel data; + MessageParcel reply; + MessageOption option(MessageOption::TF_ASYNC); + if (!data.WriteInterfaceToken(GetDescriptor())) { + TLOGE(WmsLogTag::WMS_ANIMATION, "WriteInterfaceToken failed"); + return; + } + + if (!data.WriteFloat(multiplier)) { + TLOGE(WmsLogTag::WMS_ANIMATION, "Write multiplier failed"); + return; + } + + if (remote->SendRequest(static_cast(SessionStageInterfaceCode::TRANS_ID_APPLY_ANIMATION_SPEED_MULTIPLIER), + data, reply, option) != ERR_NONE) { + TLOGE(WmsLogTag::WMS_ANIMATION, "SendRequest failed"); + return; + } +} + WSError SessionStageProxy::NotifyDumpInfo(const std::vector& params, std::vector& info) { sptr remote = Remote(); diff --git a/window_scene/session/container/src/zidl/session_stage_stub.cpp b/window_scene/session/container/src/zidl/session_stage_stub.cpp index c52c1d096969366b77b1ef28dec01ff4212bce64..e9b5b02694565d0f78fb601dedb468bf6e8e413f 100644 --- a/window_scene/session/container/src/zidl/session_stage_stub.cpp +++ b/window_scene/session/container/src/zidl/session_stage_stub.cpp @@ -236,6 +236,8 @@ int SessionStageStub::OnRemoteRequest(uint32_t code, MessageParcel& data, Messag return HandleUpdateGlobalDisplayRectFromServer(data, reply); case static_cast(SessionStageInterfaceCode::TRANS_ID_SEND_FB_ACTION_EVENT): return HandleSendFbActionEvent(data, reply); + case static_cast(SessionStageInterfaceCode::TRANS_ID_APPLY_ANIMATION_SPEED_MULTIPLIER): + return HandleApplyAnimationSpeedMultiplier(data, reply); default: WLOGFE("Failed to find function handler!"); return IPCObjectStub::OnRemoteRequest(code, data, reply, option); @@ -863,6 +865,18 @@ int SessionStageStub::HandleSetUniqueVirtualPixelRatio(MessageParcel& data, Mess return ERR_NONE; } +int SessionStageStub::HandleApplyAnimationSpeedMultiplier(MessageParcel& data, MessageParcel& reply) +{ + TLOGD(WmsLogTag::WMS_ANIMATION, "HandleApplyAnimationSpeedMultiplier!"); + float multiplier; + if (!data.ReadFloat(multiplier)) { + TLOGE(WmsLogTag::WMS_ANIMATION, "Read multiplier failed."); + return ERR_INVALID_DATA; + } + ApplyAnimationSpeedMultiplier(multiplier); + return ERR_NONE; +} + int SessionStageStub::HandleSetSplitButtonVisible(MessageParcel& data, MessageParcel& reply) { TLOGD(WmsLogTag::WMS_LAYOUT, "in"); diff --git a/window_scene/session/host/include/scene_session.h b/window_scene/session/host/include/scene_session.h index 9d327a9443fa3d6d00dac83ef09b00f5ebb3d281..9b9e0fb5d71ef441bbfdbf42614c3f355d65e90b 100644 --- a/window_scene/session/host/include/scene_session.h +++ b/window_scene/session/host/include/scene_session.h @@ -489,6 +489,7 @@ public: virtual void SetSkipSelfWhenShowOnVirtualScreen(bool isSkip); virtual void SetSkipEventOnCastPlus(bool isSkip); WMError SetUniqueDensityDpi(bool useUnique, float dpi); + WMErroe ApplyAnimationSpeedMultiplier(float multiplier); bool IsAnco() const override; void SetBlank(bool isAddBlank) override; diff --git a/window_scene/session/host/src/scene_session.cpp b/window_scene/session/host/src/scene_session.cpp index 932968ca909a7b7512d33b613608b83fac76769a..2000cddaf66626060cf70fed6b35b9dacc6f1c0b 100644 --- a/window_scene/session/host/src/scene_session.cpp +++ b/window_scene/session/host/src/scene_session.cpp @@ -7368,6 +7368,21 @@ WMError SceneSession::SetUniqueDensityDpi(bool useUnique, float dpi) return WMError::WM_OK; } +WMError SceneSession::ApplyAnimationSpeedMultiplier(float multiplier) +{ + if (!IsSessionValid()) { + TLOGE(WmsLogTag::WMS_ANIMATION, "Session is invalid"); + return WMError::WM_ERROR_INVALID_SESSION; + } + + if (!sessionStage_) { + TLOGE(WmsLogTag::WMS_ANIMATION, "sessionStage_ is nullptr"); + return WMError::WM_ERROR_NULLPTR; + } + sessionStage_->ApplyAnimationSpeedMultiplier(multiplier); + return WMError::WM_OK; +} + WMError SceneSession::SetSystemWindowEnableDrag(bool enableDrag) { if (!WindowHelper::IsSubWindow(GetWindowType()) && !WindowHelper::IsSystemWindow(GetWindowType())) { diff --git a/window_scene/session_manager/include/scene_session_manager.h b/window_scene/session_manager/include/scene_session_manager.h index e9ba28d36e9419f77a6d73291193d00a6c457dbc..b06288018416d6f92493898bfe5097b75eaae9a5 100644 --- a/window_scene/session_manager/include/scene_session_manager.h +++ b/window_scene/session_manager/include/scene_session_manager.h @@ -742,6 +742,7 @@ public: bool IsMainWindowByPersistentId(int32_t persistentId); WMError MinimizeByWindowId(const std::vector& windowIds) override; void RegisterMinimizeByWindowIdCallback(MinimizeByWindowIdFunc&& func); + WMError UpdateAnimationSpeedMultiplierForPid(pid_t pid, float multiplier) override; void RegisterSceneSessionDestructCallback(NotifySceneSessionDestructFunc&& func); void RegisterTransferSessionToTargetScreenCallback(NotifyTransferSessionToTargetScreenFunc&& func); WMError NotifyTransferSessionToTargetScreen(const TransferSessionInfo& info); diff --git a/window_scene/session_manager/include/zidl/scene_session_manager_interface.h b/window_scene/session_manager/include/zidl/scene_session_manager_interface.h index 4b9ffc7271ad8c09fc6d48df46aabe9cd1241be8..c11fbbc95f5901249aa26014b44409cafb8db2dc 100644 --- a/window_scene/session_manager/include/zidl/scene_session_manager_interface.h +++ b/window_scene/session_manager/include/zidl/scene_session_manager_interface.h @@ -154,6 +154,7 @@ public: TRANS_ID_REMOVE_SESSION_BLACK_LIST, TRANS_ID_GET_PIP_SWITCH_STATUS, TRANS_ID_RECOVER_WINDOW_PROPERTY_CHANGE_FLAG, + TRANS_ID_UPDATE_ANIMATION_SPEED_MULTIPLIER_FOR_PID, }; virtual WSError SetSessionLabel(const sptr& token, const std::string& label) = 0; diff --git a/window_scene/session_manager/include/zidl/scene_session_manager_proxy.h b/window_scene/session_manager/include/zidl/scene_session_manager_proxy.h index 7e97bb0fd9d84065f9c5315399a79176c344812a..6d60abd7c372492c74008340470595c9f6d6dd1a 100644 --- a/window_scene/session_manager/include/zidl/scene_session_manager_proxy.h +++ b/window_scene/session_manager/include/zidl/scene_session_manager_proxy.h @@ -163,6 +163,7 @@ public: WMError SetStartWindowBackgroundColor( const std::string& moduleName, const std::string& abilityName, uint32_t color, int32_t uid) override; WMError MinimizeByWindowId(const std::vector& windowIds) override; + WMError UpdateAnimationSpeedMultiplierForPid(pid_t pid, float multiplier) override; WMError SetForegroundWindowNum(uint32_t windowNum) override; WSError UseImplicitAnimation(int32_t hostWindowId, bool useImplicit) override; WMError RegisterWindowPropertyChangeAgent(WindowInfoKey windowInfoKey, uint32_t interestInfo, diff --git a/window_scene/session_manager/include/zidl/scene_session_manager_stub.h b/window_scene/session_manager/include/zidl/scene_session_manager_stub.h index 99c01df2d2bcce85a3eed9990ad83ad7c6bc25df..dd49349eabab6d592e8b8950c815eabcf45598a6 100644 --- a/window_scene/session_manager/include/zidl/scene_session_manager_stub.h +++ b/window_scene/session_manager/include/zidl/scene_session_manager_stub.h @@ -142,6 +142,7 @@ private: int ProcessRemoteRequest(uint32_t code, MessageParcel& data, MessageParcel& reply, MessageOption& option); int HandleMinimizeByWindowId(MessageParcel& data, MessageParcel& reply); + int HandleUpdateAnimationSpeedMultiplierForPid(MessageParcel& data, MessageParcel& reply); int HandleSetForegroundWindowNum(MessageParcel& data, MessageParcel& reply); int HandleUseImplicitAnimation(MessageParcel& data, MessageParcel& reply); int HandleCreateUIEffectController(MessageParcel& data, MessageParcel& reply); diff --git a/window_scene/session_manager/src/scene_session_manager.cpp b/window_scene/session_manager/src/scene_session_manager.cpp index c48cdaca156217c5a71665a2f612af80e2a60e32..07377681fc571bc8026b0fca13c26541fbf78e29 100644 --- a/window_scene/session_manager/src/scene_session_manager.cpp +++ b/window_scene/session_manager/src/scene_session_manager.cpp @@ -16698,6 +16698,22 @@ void SceneSessionManager::RegisterMinimizeByWindowIdCallback(MinimizeByWindowIdF minimizeByWindowIdFunc_ = std::move(func); } +WMError SceneSessionManager::UpdateAnimationSpeedMultiplierForPid(pid_t pid, float multiplier) +{ + if (!SessionPermission::IsSystemServiceCalling()) { + TLOGE(WmsLogTag::WMS_ANIMATION, "The caller is not system service."); + return WMError::WM_ERROR_INVALID_PERMISSION; + } + + for (const auto& [_, session] : sceneSessionMap_) { + if (session && session->GetCallingPid() == pid && session->IsVisible()) { + session->ApplyAnimationSpeedMultiplier(multiplier); + return WMError::WM_OK; + } + } + return WMError::WM_OK; +} + const std::vector> SceneSessionManager::GetActiveSceneSessionCopy() { std::map> sceneSessionMapCopy; diff --git a/window_scene/session_manager/src/zidl/scene_session_manager_proxy.cpp b/window_scene/session_manager/src/zidl/scene_session_manager_proxy.cpp index cae8eb38fac14ca0cf0983e4d9bfffb1001e9a3b..3803bb5d7df59d087f76d503b9cee633d6a452b7 100644 --- a/window_scene/session_manager/src/zidl/scene_session_manager_proxy.cpp +++ b/window_scene/session_manager/src/zidl/scene_session_manager_proxy.cpp @@ -3570,6 +3570,41 @@ WMError SceneSessionManagerProxy::MinimizeByWindowId(const std::vector& return static_cast(reply.ReadInt32()); } +WMError SceneSessionManagerProxy::UpdateAnimationSpeedMultiplierForPid(pid_t pid, float multiplier) +{ + MessageParcel data; + MessageParcel reply; + MessageOption option; + if (!data.WriteInterfaceToken(GetDescriptor())) { + TLOGE(WmsLogTag::WMS_ANIMATION, "Write interfaceToken failed"); + return WMError::WM_ERROR_IPC_FAILED; + } + if (!data.WriteInt32(pid)) { + TLOGE(WmsLogTag::WMS_ANIMATION, "Write pid failed"); + return WMError::WM_ERROR_IPC_FAILED; + } + if (!data.WriteFloat(multiplier)) { + TLOGE(WmsLogTag::WMS_ANIMATION, "Write multiplier failed"); + return WMError::WM_ERROR_IPC_FAILED; + } + sptr remote = Remote(); + if (remote == nullptr) { + TLOGE(WmsLogTag::WMS_ANIMATION, "Remote is null"); + return WMError::WM_ERROR_IPC_FAILED; + } + if (remote->SendRequest(static_cast(SceneSessionManagerMessage::TRANS_ID_UPDATE_ANIMATION_SPEED_MULTIPLIER_FOR_PID), + data, reply, option) != ERR_NONE) { + TLOGE(WmsLogTag::WMS_ANIMATION, "SendRequest failed"); + return WMError::WM_ERROR_IPC_FAILED; + } + int32_t ret = 0; + if (!reply.ReadInt32(ret)) { + TLOGE(WmsLogTag::WMS_ANIMATION, "Read ret failed"); + return WMError::WM_ERROR_IPC_FAILED; + } + return static_cast(ret); +} + WMError SceneSessionManagerProxy::SetForegroundWindowNum(uint32_t windowNum) { MessageParcel data; diff --git a/window_scene/session_manager/src/zidl/scene_session_manager_stub.cpp b/window_scene/session_manager/src/zidl/scene_session_manager_stub.cpp index aab739f17e2ebaf1204c7296904c84dcd9715bb1..d41b369350950ed1b0650a736765078e9648c749 100644 --- a/window_scene/session_manager/src/zidl/scene_session_manager_stub.cpp +++ b/window_scene/session_manager/src/zidl/scene_session_manager_stub.cpp @@ -258,6 +258,8 @@ int SceneSessionManagerStub::ProcessRemoteRequest(uint32_t code, MessageParcel& return HandleGetPiPSettingSwitchStatus(data, reply); case static_cast(SceneSessionManagerMessage::TRANS_ID_RECOVER_WINDOW_PROPERTY_CHANGE_FLAG): return HandleRecoverWindowPropertyChangeFlag(data, reply); + case static_cast(SceneSessionManageerMessage::TRANS_ID_UPDATE_ANIMATION_SPEED_MULTIPLIER_FOR_PID): + return HandleUpdateAnimationSpeedMultiplierForPid(data, reply); default: WLOGFE("Failed to find function handler!"); return IPCObjectStub::OnRemoteRequest(code, data, reply, option); @@ -2228,6 +2230,26 @@ int SceneSessionManagerStub::HandleMinimizeByWindowId(MessageParcel& data, Messa return ERR_NONE; } +int SceneSessionManagerStub::HandleUpdateAnimationSpeedMultiplierForPid(MessageParcel& data, MessageParcel& reply) +{ + int32_t pid = 0; + float multiplier = 1.0f; + if (!data.ReadInt32(pid)) { + TLOGE(WmsLogTag::WMS_ANIMATION, "read pid failed"); + return ERR_INVALID_DATA; + } + if (!data.ReadFloat(multiplier)) { + TLOGE(WmsLogTag::WMS_ANIMATION, "read multiplier failed"); + return ERR_INVALID_DATA; + } + WMError errCode = UpdateAnimationSpeedMultiplierForPid(pid, multiplier); + if (!reply.WriteInt32(static_cast(errCode))) { + TLOGE(WmsLogTag::WMS_ANIMATION, "Write errCode failed."); + return ERR_INVALID_DATA; + } + return ERR_NONE; +} + int SceneSessionManagerStub::HandleSetForegroundWindowNum(MessageParcel& data, MessageParcel& reply) { uint32_t windowNum = 0; diff --git a/window_scene/test/mock/mock_session_stage.h b/window_scene/test/mock/mock_session_stage.h index 08d8e3442007781fed564e538c6ca66362605198..e39816c4fbfeb881f2539febe49072b2aac46f9c 100644 --- a/window_scene/test/mock/mock_session_stage.h +++ b/window_scene/test/mock/mock_session_stage.h @@ -68,6 +68,7 @@ public: MOCK_METHOD2(NotifyDisplayMove, void(DisplayId from, DisplayId to)); MOCK_METHOD1(SwitchFreeMultiWindow, WSError(bool enable)); MOCK_METHOD2(SetUniqueVirtualPixelRatio, void(bool useUniqueDensity, float virtualPixelRatio)); + MOCK_METHOD1(ApplyAnimationSpeedMultiplier, void(float multiplier)); MOCK_METHOD0(PcAppInPadNormalClose, WSError(void)); MOCK_METHOD1(NotifyCompatibleModePropertyChange, WSError(const sptr property)); MOCK_METHOD1(NotifySessionFullScreen, void(bool fullScreen)); diff --git a/window_scene/test/unittest/scene_session_manager_proxy_test.cpp b/window_scene/test/unittest/scene_session_manager_proxy_test.cpp index 8b314386af1000f73e69b55bf4da81d7cc2e905c..3eaadfde8dfb64f53ddad5342d6454ea3053419a 100644 --- a/window_scene/test/unittest/scene_session_manager_proxy_test.cpp +++ b/window_scene/test/unittest/scene_session_manager_proxy_test.cpp @@ -621,6 +621,22 @@ HWTEST_F(sceneSessionManagerProxyTest, SetStartWindowBackgroundColor, TestSize.L sceneSessionManagerProxy->SetStartWindowBackgroundColor("moduleName", "abilityName", 0xffffffff, 100)); } +/** + * @tc.name: UpdateAnimationSpeedMultiplierForPid + * @tc.desc: normal function + * @tc.type: FUNC + */ +HWTEST_F(sceneSessionManagerProxyTest, UpdateAnimationSpeedMultiplierForPid, TestSize.Level1) +{ + sptr iRemoteObjectMocker = sptr::MakeSptr(); + ASSERT_NE(iRemoteObjectMocker, nullptr); + sptr sceneSessionManagerProxy = + sptr::MakeSptr(iRemoteObjectMocker); + ASSERT_NE(sceneSessionManagerProxy, nullptr); + + EXPECT_EQ(WMError::WM_OK, sceneSessionManagerProxy->UpdateAnimationSpeedMultiplierForPid(10000, 2.0f)); +} + /** * @tc.name: RemoveExtensionWindowStageFromSCB * @tc.desc: normal function diff --git a/window_scene/test/unittest/scene_session_manager_stub_test.cpp b/window_scene/test/unittest/scene_session_manager_stub_test.cpp index 4f901b1675d806e223f1e042e7a4380a8aba752e..d491545b282ebfdb420f6daaec5b52d080582bf7 100644 --- a/window_scene/test/unittest/scene_session_manager_stub_test.cpp +++ b/window_scene/test/unittest/scene_session_manager_stub_test.cpp @@ -2039,6 +2039,30 @@ HWTEST_F(SceneSessionManagerStubTest, HandleSetStartWindowBackgroundColor, TestS EXPECT_EQ(res, ERR_NONE); } +/** + * @tc.name: HandleUpdateAnimationSpeedMultiplierForPid + * @tc.desc: test HandleUpdateAnimationSpeedMultiplierForPid + * @tc.type: FUNC + */ +HWTEST_F(SceneSessionManagerStubTest, HandleUpdateAnimationSpeedMultiplierForPid, TestSize.Level1) +{ + ASSERT_NE(stub_, nullptr); + MessageParcel data; + MessageParcel reply; + + int res = stub_->HandleUpdateAnimationSpeedMultiplierForPid(data, reply); + EXPECT_EQ(res, ERR_INVALID_DATA); + + data.WriteInt32(10000); + res = stub_->HandleUpdateAnimationSpeedMultiplierForPid(data, reply); + EXPECT_EQ(res, ERR_INVALID_DATA); + + data.WriteInt32(10000); + data.WriteFloat(2.0f); + res = stub_->HandleUpdateAnimationSpeedMultiplierForPid(data, reply); + EXPECT_EQ(res, ERR_NONE); +} + /** * @tc.name: HandleNotifyScreenshotEvent * @tc.desc: test HandleNotifyScreenshotEvent diff --git a/window_scene/test/unittest/scene_session_manager_test7.cpp b/window_scene/test/unittest/scene_session_manager_test7.cpp index 2a9360f66b71ad8c886c92f8eb1ac428a3a81209..95e349db00f882b57057192d6a64b486e6f45148 100644 --- a/window_scene/test/unittest/scene_session_manager_test7.cpp +++ b/window_scene/test/unittest/scene_session_manager_test7.cpp @@ -2123,6 +2123,57 @@ HWTEST_F(SceneSessionManagerTest7, MinimizeByWindowId, TestSize.Level1) EXPECT_EQ(WMError::WM_ERROR_INVALID_PARAM, res); } +/** + * @tc.name: UpdateAnimationSpeedMultiplierForPid + * @tc.desc: test function : UpdateAnimationSpeedMultiplierForPid + * @tc.type: FUNC + */ +HWTEST_F(SceneSessionManagerTest7, UpdateAnimationSpeedMultiplierForPid, TestSize.Level1) +{ + ASSERT_NE(nullptr, ssm_); + + MockAccesstokenKit::MockIsSACalling(false); + + float multiplier = 2.0f; + int32_t pid = 1; + + auto result = ssm_->UpdateAnimationSpeedMultiplierForPid(pid, multiplier); + EXPECT_EQ(result, WMError::WM_ERROR_INVALID_PERMISSION); + + MockAccesstokenKit::MockIsSACalling(true); + SessionInfo info; + info.bundleName_ = "SceneSessionManagerTest7"; + info.abilityName_ = "UpdateAnimationSpeedMultiplierForPid"; + sptr sceneSession01 = sptr::MakeSptr(info, nullptr); + sptr sceneSession02 = sptr::MakeSptr(info, nullptr); + sptr sceneSession03 = sptr::MakeSptr(info, nullptr); + sptr sceneSession04 = sptr::MakeSptr(info, nullptr); + ASSERT_NE(sceneSession01, nullptr); + ASSERT_NE(sceneSession02, nullptr); + ASSERT_NE(sceneSession03, nullptr); + ASSERT_NE(sceneSession04, nullptr); + sceneSession01->isVisible_ = false; + sceneSession01->SetCallingPid(2); + ssm_->sceneSessionMap_.insert(std::make_pair(1, sceneSession01)); + result = ssm_->UpdateAnimationSpeedMultiplierForPid(pid, multiplier); + EXPECT_EQ(result, WMError::WM_OK); + sceneSession02->isVisible_ = true; + sceneSession02->SetCallingPid(3); + ssm_->sceneSessionMap_.insert(std::make_pair(2, sceneSession02)); + result = ssm_->UpdateAnimationSpeedMultiplierForPid(pid, multiplier); + EXPECT_EQ(result, WMError::WM_OK); + sceneSession03->isVisible_ = false; + sceneSession03->SetCallingPid(pid); + ssm_->sceneSessionMap_.insert(std::make_pair(3, sceneSession03)); + result = ssm_->UpdateAnimationSpeedMultiplierForPid(pid, multiplier); + EXPECT_EQ(result, WMError::WM_OK); + sceneSession04->isVisible_ = true; + sceneSession04->SetCallingPid(pid); + ssm_->sceneSessionMap_.insert(std::make_pair(4, sceneSession04)); + result = ssm_->UpdateAnimationSpeedMultiplierForPid(pid, multiplier); + EXPECT_EQ(result, WMError::WM_OK); +} + /** * @tc.name: SetForegroundWindowNum * @tc.desc: test function : SetForegroundWindowNum diff --git a/window_scene/test/unittest/scene_session_test5.cpp b/window_scene/test/unittest/scene_session_test5.cpp index 36b9cc8d434dd18b6277322ecc48f3fda8e166e9..cb1de5b0adbcc3878d2093f74147e35b05d7aecf 100644 --- a/window_scene/test/unittest/scene_session_test5.cpp +++ b/window_scene/test/unittest/scene_session_test5.cpp @@ -1518,6 +1518,31 @@ HWTEST_F(SceneSessionTest5, SetUniqueDensityDpi, TestSize.Level1) EXPECT_NE(nullptr, session->sessionStage_); } +/** + * @tc.name: ApplyAnimationSpeedMultiplier + * @tc.desc: ApplyAnimationSpeedMultiplier function01 + * @tc.type: FUNC + */ +HWTEST_F(SceneSessionTest5, ApplyAnimationSpeedMultiplier, TestSize.Level1) +{ + SessionInfo info; + info.abilityName_ = "ApplyAnimationSpeedMultiplier"; + info.bundleName_ = "ApplyAnimationSpeedMultiplier"; + sptr session = sptr::MakeSptr(info, nullptr); + EXPECT_NE(session, nullptr); + session->sessionStage_ = nullptr; + EXPECT_EQ(WMError::WM_ERROR_INVALID_SESSION, session->ApplyAnimationSpeedMultiplier(2.0f)); + session->sessionInfo_.isSystem_ = false; + session->state_ = SessionState::STATE_DISCONNECT; + EXPECT_EQ(WMError::WM_ERROR_INVALID_SESSION, session->ApplyAnimationSpeedMultiplier(2.0f)); + session->state_ = SessionState::STATE_CONNECT; + EXPECT_EQ(WMError::WM_ERROR_NULLPTR, session->ApplyAnimationSpeedMultiplier(2.0f)); + + session->sessionStage_ = sptr::MakeSptr(); + EXPECT_NE(nullptr, session->sessionStage_); + EXPECT_EQ(WMError::WM_OK, session->ApplyAnimationSpeedMultiplier(2.0f)); +} + /** * @tc.name: HandleActionUpdateWindowModeSupportType * @tc.desc: HandleActionUpdateWindowModeSupportType function01 diff --git a/window_scene/test/unittest/session_stage_proxy_test.cpp b/window_scene/test/unittest/session_stage_proxy_test.cpp index 270ff05d8c3122501894b5be915e9272d247b5b1..9996f53965a72c92c403fd8a6894c172b7d2cb30 100755 --- a/window_scene/test/unittest/session_stage_proxy_test.cpp +++ b/window_scene/test/unittest/session_stage_proxy_test.cpp @@ -286,6 +286,18 @@ HWTEST_F(SessionStageProxyTest, NotifyOccupiedAreaChangeInfo, TestSize.Level1) sessionStage_->NotifyOccupiedAreaChangeInfo(info, nullptr, {}, {}); } +/** + * @tc.name: ApplyAnimationSpeedMultiplier + * @tc.desc: test function : ApplyAnimationSpeedMultiplier + * @tc.type: FUNC + */ +HWTEST_F(SessionStageProxyTest, ApplyAnimationSpeedMultiplier, TestSize.Level1) +{ + float multiplier = 2.0f; + ASSERT_TRUE((sessionStage_ != nullptr)); + sessionStage_->ApplyAnimationSpeedMultiplier(multiplier); +} + /** * @tc.name: NotifyKeyboardAnimationCompleted * @tc.desc: test function : NotifyKeyboardAnimationCompleted diff --git a/window_scene/test/unittest/session_stage_stub_test.cpp b/window_scene/test/unittest/session_stage_stub_test.cpp index dd2777cac68842596d8a817320b3cea2a53132ce..c98fa38eb271f813713ecb3478864f0176f59252 100644 --- a/window_scene/test/unittest/session_stage_stub_test.cpp +++ b/window_scene/test/unittest/session_stage_stub_test.cpp @@ -811,6 +811,21 @@ HWTEST_F(SessionStageStubTest, HandleSetUniqueVirtualPixelRatio, TestSize.Level1 ASSERT_EQ(0, sessionStageStub_->OnRemoteRequest(code, data, reply, option)); } +/** + * @tc.name: HandleApplyAnimationSpeedMultiplier + * @tc.desc: test function : HandleApplyAnimationSpeedMultiplier + * @tc.type: FUNC + */ +HWTEST_F(SessionStageStubTest, HandleApplyAnimationSpeedMultiplier, TestSize.Level1) +{ + MessageParcel data; + MessageParcel reply; + ASSERT_TRUE(sessionStageStub_ != nullptr); + ASSERT_EQ(ERR_INVALID_DATA, sessionStageStub_->HandleApplyAnimationSpeedMultiplier(data, reply)); + data.WriteFloat(2.0f); + ASSERT_EQ(0, sessionStageStub_->HandleApplyAnimationSpeedMultiplier(data, reply)); +} + /** * @tc.name: HandleNotifySessionFullScreen * @tc.desc: test function : HandleNotifySessionFullScreen diff --git a/wm/include/window_adapter.h b/wm/include/window_adapter.h index 4f511464dd06b7a721398996fa8f857913983e22..7f7180123105f934fddde52b7d45846e0fa28c89 100644 --- a/wm/include/window_adapter.h +++ b/wm/include/window_adapter.h @@ -148,6 +148,7 @@ public: virtual WMError NotifyWatchGestureConsumeResult(int32_t keyCode, bool isConsumed); virtual WMError NotifyWatchFocusActiveChange(bool isActive); virtual WMError MinimizeByWindowId(const std::vector& windowIds); + virtual WMError UpdateAnimationSpeedMultiplierForPid(pid_t pid, float multiplier); virtual WMError SetForegroundWindowNum(uint32_t windowNum); virtual WMError SetStartWindowBackgroundColor( const std::string& moduleName, const std::string& abilityName, uint32_t color, int32_t uid); diff --git a/wm/include/window_session_impl.h b/wm/include/window_session_impl.h index 47924c35df19a33833f829490ba28d804d29d206..570aa2936433a23dd7056f9b9640b82e0486f2e7 100644 --- a/wm/include/window_session_impl.h +++ b/wm/include/window_session_impl.h @@ -57,6 +57,8 @@ using EnableIfSame = typename std::enable_if, Ret>::type; const std::string SET_UICONTENT_TIMEOUT_LISTENER_TASK_NAME = "SetUIContentTimeoutListener"; constexpr int64_t SET_UICONTENT_TIMEOUT_TIME_MS = 4000; constexpr int64_t SET_UICONTENT_TIMEOUT_TIME_AFTER_FREEZE_MS = 5000; +static std::atomic animationSpeedMultiplier = 1.0f; +static std::atomic isEnableAnimationSpeedMultiplier = false; } struct WindowTitleVisibleFlags { @@ -221,6 +223,7 @@ public: const std::map& avoidAreas = {}) override; void UpdateDensity() override; void SetUniqueVirtualPixelRatio(bool useUniqueDensity, float virtualPixelRatio) override; + void ApplyAnimationSpeedMultiplier(float multiplier) override; WSError UpdateOrientation() override; WSError UpdateDisplayId(uint64_t displayId) override; WSError UpdateFocus(bool focus) override; diff --git a/wm/src/window_adapter.cpp b/wm/src/window_adapter.cpp index 7af0715572464da15914331f4db715545e4912c6..7e88040ff7b3155d9be5bb36a13d5263866e1337 100644 --- a/wm/src/window_adapter.cpp +++ b/wm/src/window_adapter.cpp @@ -1284,6 +1284,14 @@ WMError WindowAdapter::MinimizeByWindowId(const std::vector& windowIds) return wmsProxy->MinimizeByWindowId(windowIds); } +WMError WindowAdapter::UpdateAnimationSpeedMultiplierForPid(pid_t pid, float multiplier) +{ + INIT_PROXY_CHECK_RETURN(WMError::WM_ERROR_SAMGR); + auto wmsProxy = GetWindowManagerServiceProxy(); + CHECK_PROXY_RETURN_ERROR_IF_NULL(wmsProxy, WMError::WM_ERROR_SAMGR); + return wmsProxy->UpdateAnimationSpeedMultiplierForPid(pid, multiplier); +} + WMError WindowAdapter::SetForegroundWindowNum(uint32_t windowNum) { INIT_PROXY_CHECK_RETURN(WMError::WM_ERROR_SAMGR); diff --git a/wm/src/window_manager.cpp b/wm/src/window_manager.cpp index e37e59d04f758c913f1abc68069921f2840814f7..1f68e49c31eb72ce020e40ff8f2adadc71b487ac 100644 --- a/wm/src/window_manager.cpp +++ b/wm/src/window_manager.cpp @@ -2206,6 +2206,15 @@ WMError WindowManager::MinimizeByWindowId(const std::vector& windowIds) return ret; } +WMError WindowManager::UpdateAnimationSpeedMultiplerForPid(pid_t pid, float multiplier) +{ + WMError ret = SingletonContainer::Get().UpdateAnimationSpeedMultiplerForPid(pid, multiplier); + if (ret != WMError::WM_OK) { + TLOGE(WmsLogTag::WMS_ANIMATION, "failed"); + } + return ret; +} + WMError WindowManager::SetForegroundWindowNum(uint32_t windowNum) { WMError ret = SingletonContainer::Get().SetForegroundWindowNum(windowNum); diff --git a/wm/src/window_scene_session_impl.cpp b/wm/src/window_scene_session_impl.cpp index ae00ed918b70304a5267cc7a43d049bf14578501..bd575574900afe5de9d73c2296cb048c5f981838 100644 --- a/wm/src/window_scene_session_impl.cpp +++ b/wm/src/window_scene_session_impl.cpp @@ -662,6 +662,13 @@ WMError WindowSceneSessionImpl::Create(const std::shared_ptrGetImplicitAnimator() : nullptr; + if (implicitAnimator != nullptr) { + implicitAnimator->ApplyAnimationSpeedMultiplier(animationSpeedMultiplier.load()); + } + } TLOGD(WmsLogTag::WMS_LIFE, "Window Create success [name:%{public}s, id:%{public}d], state:%{public}u, " "mode:%{public}u, enableDefaultDensity:%{public}d, displayId:%{public}" PRIu64, property_->GetWindowName().c_str(), property_->GetPersistentId(), state_, GetWindowMode(), diff --git a/wm/src/window_session_impl.cpp b/wm/src/window_session_impl.cpp index be49ecbbda44664058243a790548bf6075c8bcc0..2ca28e6d36b6db809f996b7bb0f7ee8d8a3b2369 100644 --- a/wm/src/window_session_impl.cpp +++ b/wm/src/window_session_impl.cpp @@ -1483,6 +1483,33 @@ void WindowSessionImpl::SetUniqueVirtualPixelRatio(bool useUniqueDensity, float } } +void WindowSessionImpl::ApplyAnimationSpeedMultiplier(float multiplier) +{ + const char* const where = __func__; + auto task = [weakThis = wptr(this), multiplier, where, this] { + auto window = weakThis.promote(); + if (window == nullptr) { + TLOGW(WmsLogTag::WMS_ANIMATION, "%{public}s: window is nullptr", where); + return; + } + for (const auto& [_, pair] : windowSessionMap_) { + auto& WindowSession = pair.second; + if (WindowSession) { + auto rsUIContext = WindowSession->GetRSUIContext(); + auto implicitAnimator = rsUIContext ? rsUIContext->GetImplicitAnimator() : nullptr; + if (implicitAnimator == nullptr) { + TLOGE(WmsLogTag::WMS_ANIMATION, "Failed to open implicit animtion"); + continue; + } + implicitAnimator->ApplyAnimationSpeedMultiplier(multiplier); + } + } + isEnableAnimationSpeedMultiplier.store(!FoldScreenStateInternel::FloatEqualAbs(multiplier, 1.0f)); + animationSpeedMultiplier.store(multiplier); + }; + handler_->PostTask(task, where, 0, AppExecFwk::EventQueue::Priority::HIGH); +} + void WindowSessionImpl::CopyUniqueDensityParameter(sptr parentWindow) { if (parentWindow) { diff --git a/wm/test/unittest/window_adapter_test.cpp b/wm/test/unittest/window_adapter_test.cpp index 9196a00c87a4b6074c978e04e8721cd8e7f304e8..26a7e11edb55a7f587f0733327b6c5c365073a46 100644 --- a/wm/test/unittest/window_adapter_test.cpp +++ b/wm/test/unittest/window_adapter_test.cpp @@ -1104,6 +1104,18 @@ HWTEST_F(WindowAdapterTest, MinimizeByWindowId, TestSize.Level1) ASSERT_EQ(ret, true); } +/** + * @tc.name: UpdateAnimationSpeedMultiplierForPid + * @tc.desc: WindowAdapter/UpdateAnimationSpeedMultiplierForPid + * @tc.type: FUNC + */ +HWTEST_F(WindowAdapterTest, UpdateAnimationSpeedMultiplierForPid, TestSize.Level1) +{ + WindowAdapter windowAdapter; + auto err = windowAdapter.UpdateAnimationSpeedMultiplierForPid(10000, 2.0f); + ASSERT_EQ(WMError::WM_OK, err); +} + /** * @tc.name: ListWindowInfo01 * @tc.desc: WindowAdapter/ListWindowInfo diff --git a/wm/test/unittest/window_manager_test.cpp b/wm/test/unittest/window_manager_test.cpp index 12e7f6e3d997116fdd22a5df5b94da0b31f182f4..28a07edcebb9548695ebbf0afee7d347b0fbffc7 100644 --- a/wm/test/unittest/window_manager_test.cpp +++ b/wm/test/unittest/window_manager_test.cpp @@ -1791,6 +1791,23 @@ HWTEST_F(WindowManagerTest, MinimizeByWindowId, TestSize.Level1) ASSERT_EQ(WMError::WM_OK, ret_2); } +/** + * @tc.name: UpdateAnimationSpeedMultiplierForPid + * @tc.desc: Check UpdateAnimationSpeedMultiplierForPid + * @tc.type: FUNC + */ +HWTEST_F(WindowManagerTest, UpdateAnimationSpeedMultiplierForPid, TestSize.Level1) +{ + auto& windowManager = WindowManager::GetInstance(); + pid_t pid = 15234; + float multiplier = 2.0f; + WMError ret_1 = windowManager.UpdateAnimationSpeedMultiplierForPid(pid, multiplier); + ASSERT_EQ(WMError::WM_OK, ret_1); + multiplier = 1.0f; + WMError ret_2 = windowManager.UpdateAnimationSpeedMultiplierForPid(pid, multiplier); + ASSERT_EQ(WMError::WM_OK, ret_2); +} + /** * @tc.name: ProcessRegisterWindowInfoChangeCallback01 * @tc.desc: Check ProcessRegisterWindowInfoChangeCallback diff --git a/wm/test/unittest/window_session_impl_test.cpp b/wm/test/unittest/window_session_impl_test.cpp index 151e4d3b3d8685c235aafe561f5bfd31693fac16..435779aa9ed333f409994a3453160e29f5708540 100644 --- a/wm/test/unittest/window_session_impl_test.cpp +++ b/wm/test/unittest/window_session_impl_test.cpp @@ -1958,6 +1958,22 @@ HWTEST_F(WindowSessionImplTest, SetUniqueVirtualPixelRatio, TestSize.Level1) window->SetUniqueVirtualPixelRatio(false, 3.25f); } +/** + * @tc.name: ApplyAnimationSpeedMultiplier + * @tc.desc: ApplyAnimationSpeedMultiplier + * @tc.type: FUNC + */ +HWTEST_F(WindowSessionImplTest, ApplyAnimationSpeedMultiplier, TestSize.Level1) +{ + sptr option = new (std::nothrow) WindowOption(); + ASSERT_NE(option, nullptr); + option->SetWindowName("ApplyAnimationSpeedMultiplier"); + sptr window = new (std::nothrow) WindowSessionImpl(option); + ASSERT_NE(window, nullptr); + window->ApplyAnimationSpeedMultiplier(1.0f); + window->ApplyAnimationSpeedMultiplier(2.0f); +} + /** * @tc.name: EnableDrag * @tc.desc: EnableDrag Test diff --git a/wmserver/include/zidl/window_manager_interface.h b/wmserver/include/zidl/window_manager_interface.h index b3ae63912f4c152a0b05a7a6cf2d39ff950e7ba1..ac900dc362cdb676fce9b9f51c8dd3113e2d0726 100644 --- a/wmserver/include/zidl/window_manager_interface.h +++ b/wmserver/include/zidl/window_manager_interface.h @@ -311,6 +311,7 @@ public: virtual WMError HasFloatingWindowForeground(const sptr& abilityToken, bool& hasOrNot) { return WMError::WM_OK; } virtual WMError MinimizeByWindowId(const std::vector& windowIds) { return WMError::WM_OK; } + virtual WMError UpdateAnimationSpeedMultiplierForPid(pid_t pid, float multiplier) { return WMError::WM_OK; } virtual WMError SetForegroundWindowNum(uint32_t windowNum) { return WMError::WM_OK; } virtual WSError UseImplicitAnimation(int32_t hostWindowId, bool useImplicit) { return WSError::WS_OK; } virtual WMError AnimateTo(int32_t windowId, const WindowAnimationProperty& animationProperty,