1/*
2 * Copyright (c) 2023 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 *     http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15#include <map>
16#include <set>
17#include <mutex>
18#include <iproxy_broker.h>
19#include <codec_death_recipient.h>
20#include "codec_log_wrapper.h"
21
22namespace OHOS {
23namespace HDI {
24namespace Codec {
25namespace V3_0 {
26
27static std::map<IRemoteObject *, std::set<uint32_t>> g_remoteCompsMap;
28static std::map<IRemoteObject *, sptr<CodecDeathRecipient>> g_deathReciMap;
29static std::map<uint32_t, IRemoteObject *> g_compRemoteMap;
30static std::mutex g_mutex;
31
32void CleanResourceOfDiedService(sptr<IRemoteObject> object, wptr<CodecComponentManagerService> managerService)
33{
34    std::set<uint32_t> compIds {};
35    {
36        std::lock_guard<std::mutex> lk(g_mutex);
37        auto remoteComps = g_remoteCompsMap.find(object.GetRefPtr());
38        if (remoteComps == g_remoteCompsMap.end()) {
39            CODEC_LOGE("can not find remote service in g_remoteCompsMap!");
40            return;
41        }
42        compIds = remoteComps->second;
43        g_remoteCompsMap.erase(remoteComps);
44    }
45
46    for (auto id = compIds.begin(); id != compIds.end(); id++) {
47        managerService->DestroyComponent(*id);
48    }
49    CODEC_LOGI("Clean died remoteService resource success!");
50}
51
52void RegisterDeathRecipientService(const sptr<ICodecCallback> callbacks, uint32_t componentId,
53                                   wptr<CodecComponentManagerService> service)
54{
55    std::unique_lock<std::mutex> lk(g_mutex);
56
57    const sptr<OHOS::IRemoteObject> &remote = OHOS::HDI::hdi_objcast<ICodecCallback>(callbacks);
58    g_compRemoteMap.emplace(std::make_pair(componentId, remote.GetRefPtr()));
59
60    auto remoteComps = g_remoteCompsMap.find(remote.GetRefPtr());
61    if (remoteComps != g_remoteCompsMap.end()) {
62        CODEC_LOGI("RemoteService had been added deathRecipient!");
63        remoteComps->second.insert(componentId);
64        return;
65    }
66
67    const sptr<CodecDeathRecipient> deathCallBack(new CodecDeathRecipient(service));
68    bool ret = remote->AddDeathRecipient(deathCallBack);
69    if (!ret) {
70        CODEC_LOGE("RemoteService add deathRecipient fail!");
71        return ;
72    }
73
74    std::set<uint32_t> compIds;
75    compIds.insert(componentId);
76    g_remoteCompsMap.emplace(std::make_pair(remote.GetRefPtr(), compIds));
77    g_deathReciMap[remote.GetRefPtr()] = deathCallBack;
78    CODEC_LOGI("Add deathRecipient success!");
79}
80
81void RemoveMapperOfDestoryedComponent(uint32_t componentId)
82{
83    std::unique_lock<std::mutex> lk(g_mutex);
84
85    auto compRemote = g_compRemoteMap.find(componentId);
86    if (compRemote == g_compRemoteMap.end()) {
87        return;
88    }
89
90    IRemoteObject *remote = compRemote->second;
91    auto remoteComps = g_remoteCompsMap.find(remote);
92    if (remoteComps == g_remoteCompsMap.end()) {
93        return;
94    }
95    remoteComps->second.erase(componentId);
96    if (remoteComps->second.empty()) {
97        g_remoteCompsMap.erase(remoteComps);
98    }
99    g_compRemoteMap.erase(compRemote);
100
101    auto deathReci = g_deathReciMap.find(remote);
102    if (deathReci == g_deathReciMap.end()) {
103        CODEC_LOGE("%{public}s: not find recipient", __func__);
104        return;
105    }
106    bool result = remote->RemoveDeathRecipient(deathReci->second);
107    g_deathReciMap.erase(deathReci);
108    if (!result) {
109        CODEC_LOGE("%{public}s: removeDeathRecipient fail", __func__);
110        return;
111    }
112    CODEC_LOGI("Remove mapper destoryedComponent success!");
113}
114}  // namespace V3_0
115}  // namespace Codec
116}  // namespace HDI
117}  // namespace OHOS
118