XxiazhiqiPART3
688bef73创建于 2025年7月2日历史提交
/*
 * 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<IUIEffectControllerClient>& controllerClient,
    sptr<IUIEffectController>& controller, int32_t& controllerId)
{
    if (!onUIEffectSetParams_ || !onUIEffectAnimateTo_) {
        TLOGE(WmsLogTag::WMS_ANIMATION, "scb not register animation func!");
        return WMError::WM_ERROR_NULLPTR;
    }
    static std::atomic<int32_t> globalControllerId = 0;
    globalControllerId++;
    controllerId = globalControllerId;
    sptr<UIEffectControllerClientDeath> controllerDeath = sptr<UIEffectControllerClientDeath>::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<UIEffectController> newController =
        sptr<UIEffectController>::MakeSptr(controllerId, onUIEffectSetParams_, onUIEffectAnimateTo_);
    std::unique_lock<std::mutex> 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<CONTROLLER_INDEX>(list) != nullptr && std::get<CONTROLLER_CLIENT_INDEX>(list) != nullptr &&
        std::get<CONTROLLER_CLIENT_DEATH>(list) != nullptr) {
        return true;
    } else {
        return false;
    }
}

void UIEffectManager::SetUIEffectControllerAliveState(int32_t id, bool isAlive)
{
    std::unique_lock<std::mutex> 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<UIEffectController> controller = std::get<CONTROLLER_INDEX>(controllerList);
        controller->SetIsAliveInUI(isAlive);
    } else {
        TLOGE(WmsLogTag::WMS_ANIMATION, "can not find current controller");
    }
}

void UIEffectManager::EraseUIEffectController(int32_t id)
{
    std::unique_lock<std::mutex> 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<IUIEffectControllerClient> controllerClient = std::get<CONTROLLER_CLIENT_INDEX>(controllerList);
        sptr<UIEffectControllerClientDeath> clientDeath = std::get<CONTROLLER_CLIENT_DEATH>(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);
}
}