/* * Copyright (c) 2025 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "ui_effect_manager.h" #include "window_manager_hilog.h" #include "ui_effect_controller_client_proxy.h" constexpr int CONTROLLER_INDEX = 0; constexpr int CONTROLLER_CLIENT_INDEX = 1; constexpr int CONTROLLER_CLIENT_DEATH = 2; namespace OHOS::Rosen { WM_IMPLEMENT_SINGLE_INSTANCE(UIEffectManager); void UIEffectManager::RegisterUIEffectSetParamsCallback(NotifyUIEffectSetParamFunc func) { onUIEffectSetParams_ = func; } void UIEffectManager::RegisterUIEffectAnimateToCallback(NotifyUIEffectAnimateToFunc func) { onUIEffectAnimateTo_ = func; } WMError UIEffectManager::CreateUIEffectController(const sptr& controllerClient, sptr& controller, int32_t& controllerId) { if (!onUIEffectSetParams_ || !onUIEffectAnimateTo_) { TLOGE(WmsLogTag::WMS_ANIMATION, "scb not register animation func!"); return WMError::WM_ERROR_NULLPTR; } static std::atomic globalControllerId = 0; globalControllerId++; controllerId = globalControllerId; sptr controllerDeath = sptr::MakeSptr( [controllerId, this] () { EraseUIEffectController(controllerId); } ); if (!controllerClient->AsObject() || !controllerClient->AsObject()->AddDeathRecipient(controllerDeath)) { TLOGE(WmsLogTag::WMS_ANIMATION, "Failed to add death recipient"); return WMError::WM_ERROR_NULLPTR; } sptr newController = sptr::MakeSptr(controllerId, onUIEffectSetParams_, onUIEffectAnimateTo_); std::unique_lock lock(UIEffectControllerMapMutex_); UIEffectControllerMap_[controllerId] = std::make_tuple(newController, controllerClient, controllerDeath); controller = newController; TLOGI(WmsLogTag::WMS_ANIMATION, "create ui effect success, id: %{public}d, map size %{public}zu", controllerId, UIEffectControllerMap_.size()); return WMError::WM_OK; } bool UIEffectManager::IsControllerListValid(const ControllerList& list) const { if (std::get(list) != nullptr && std::get(list) != nullptr && std::get(list) != nullptr) { return true; } else { return false; } } void UIEffectManager::SetUIEffectControllerAliveState(int32_t id, bool isAlive) { std::unique_lock lock(UIEffectControllerMapMutex_); if (auto it = UIEffectControllerMap_.find(id); it != UIEffectControllerMap_.end()) { auto& controllerList = it->second; if (!IsControllerListValid(controllerList)) { TLOGE(WmsLogTag::WMS_ANIMATION, "controller invalid"); return; } sptr controller = std::get(controllerList); controller->SetIsAliveInUI(isAlive); } else { TLOGE(WmsLogTag::WMS_ANIMATION, "can not find current controller"); } } void UIEffectManager::EraseUIEffectController(int32_t id) { std::unique_lock lock(UIEffectControllerMapMutex_); if (auto it = UIEffectControllerMap_.find(id); it != UIEffectControllerMap_.end()) { auto& controllerList = it->second; if (!IsControllerListValid(controllerList)) { TLOGE(WmsLogTag::WMS_ANIMATION, "controller invalid"); UIEffectControllerMap_.erase(id); return; } sptr controllerClient = std::get(controllerList); sptr clientDeath = std::get(controllerList); if (!controllerClient->AsObject()) { TLOGE(WmsLogTag::WMS_ANIMATION, "controllerClient is nullptr or not proxy"); UIEffectControllerMap_.erase(id); return; } controllerClient->AsObject()->RemoveDeathRecipient(clientDeath); } UIEffectControllerMap_.erase(id); } }