1/*
2 * Copyright (c) 2023 Shenzhen Kaihong DID 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
16#include "codec_death_recipient.h"
17#include <hdf_remote_service.h>
18#include <map>
19#include <mutex>
20#include <securec.h>
21#include <set>
22#include <unistd.h>
23#include "codec_log_wrapper.h"
24
25#ifdef __cplusplus
26extern "C" {
27#endif
28
29static std::map<uint64_t *, uint32_t> g_addrPidMap;
30static std::map<uint32_t, std::set<uint32_t>> g_pidCompsMap;
31static std::mutex g_mutex;
32
33bool RegisterService(struct CodecCallbackType *callbacks, uint32_t componentId,
34                     struct CodecComponentNode *codecNode)
35{
36    std::lock_guard<std::mutex> lk(g_mutex);
37    if (callbacks == nullptr) {
38        CODEC_LOGE("invalid parameter");
39        return false;
40    }
41    uint32_t remotePid =  static_cast<uint32_t>(HdfRemoteGetCallingPid());
42    auto comps = g_pidCompsMap.find(remotePid);
43    if (comps != g_pidCompsMap.end()) {
44        CODEC_LOGE("RemoteService had been added deathRecipient!");
45        comps->second.insert(componentId);
46        return false;
47    }
48
49    uint64_t *addr = reinterpret_cast<uint64_t *>(callbacks->remote);
50    std::set<uint32_t> compIds;
51    compIds.insert(componentId);
52    g_pidCompsMap.emplace(std::make_pair(remotePid, compIds));
53    g_addrPidMap.emplace(std::make_pair(addr, remotePid));
54    return true;
55}
56
57int32_t CleanMapperOfDiedService(struct HdfRemoteService *remote, uint32_t *compIds, uint32_t *size)
58{
59    std::lock_guard<std::mutex> lk(g_mutex);
60
61    uint64_t *addr = reinterpret_cast<uint64_t *>(remote);
62    auto addrPid = g_addrPidMap.find(addr);
63    if (addrPid == g_addrPidMap.end()) {
64        CODEC_LOGE("RemoteService no mapper in g_addrPidMap!");
65        return HDF_FAILURE;
66    }
67
68    uint32_t remotePid = addrPid->second;
69    auto comps = g_pidCompsMap.find(remotePid);
70    if (comps == g_pidCompsMap.end()) {
71        CODEC_LOGE("RemoteService no mapper in g_pidCompsMap!");
72        return HDF_FAILURE;
73    }
74
75    std::set<uint32_t> ids = comps->second;
76    uint32_t index = 0;
77    *size = ids.size();
78    for (auto id = ids.begin(); id != ids.end(); id++) {
79        compIds[index++] = *id;
80    }
81
82    g_addrPidMap.erase(addrPid);
83    g_pidCompsMap.erase(comps);
84    CODEC_LOGE("clean service mapper success!");
85    return HDF_SUCCESS;
86}
87
88void RemoveDestoryedComponent(uint32_t componentId)
89{
90    std::lock_guard<std::mutex> lk(g_mutex);
91
92    uint32_t remotePid =  static_cast<uint32_t>(HdfRemoteGetCallingPid());
93    auto comps = g_pidCompsMap.find(remotePid);
94    if (comps != g_pidCompsMap.end()) {
95        comps->second.erase(componentId);
96    }
97}
98#ifdef __cplusplus
99};
100#endif
101