1094332d3Sopenharmony_ci/*
2094332d3Sopenharmony_ci * Copyright (c) 2023 Shenzhen Kaihong DID Co., Ltd.
3094332d3Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
4094332d3Sopenharmony_ci * you may not use this file except in compliance with the License.
5094332d3Sopenharmony_ci * You may obtain a copy of the License at
6094332d3Sopenharmony_ci *
7094332d3Sopenharmony_ci * 		http://www.apache.org/licenses/LICENSE-2.0
8094332d3Sopenharmony_ci *
9094332d3Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
10094332d3Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
11094332d3Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12094332d3Sopenharmony_ci * See the License for the specific language governing permissions and
13094332d3Sopenharmony_ci * limitations under the License.
14094332d3Sopenharmony_ci */
15094332d3Sopenharmony_ci
16094332d3Sopenharmony_ci#include "codec_death_recipient.h"
17094332d3Sopenharmony_ci#include <hdf_remote_service.h>
18094332d3Sopenharmony_ci#include <map>
19094332d3Sopenharmony_ci#include <mutex>
20094332d3Sopenharmony_ci#include <securec.h>
21094332d3Sopenharmony_ci#include <set>
22094332d3Sopenharmony_ci#include <unistd.h>
23094332d3Sopenharmony_ci#include "codec_log_wrapper.h"
24094332d3Sopenharmony_ci
25094332d3Sopenharmony_ci#ifdef __cplusplus
26094332d3Sopenharmony_ciextern "C" {
27094332d3Sopenharmony_ci#endif
28094332d3Sopenharmony_ci
29094332d3Sopenharmony_cistatic std::map<uint64_t *, uint32_t> g_addrPidMap;
30094332d3Sopenharmony_cistatic std::map<uint32_t, std::set<uint32_t>> g_pidCompsMap;
31094332d3Sopenharmony_cistatic std::mutex g_mutex;
32094332d3Sopenharmony_ci
33094332d3Sopenharmony_cibool RegisterService(struct CodecCallbackType *callbacks, uint32_t componentId,
34094332d3Sopenharmony_ci                     struct CodecComponentNode *codecNode)
35094332d3Sopenharmony_ci{
36094332d3Sopenharmony_ci    std::lock_guard<std::mutex> lk(g_mutex);
37094332d3Sopenharmony_ci    if (callbacks == nullptr) {
38094332d3Sopenharmony_ci        CODEC_LOGE("invalid parameter");
39094332d3Sopenharmony_ci        return false;
40094332d3Sopenharmony_ci    }
41094332d3Sopenharmony_ci    uint32_t remotePid =  static_cast<uint32_t>(HdfRemoteGetCallingPid());
42094332d3Sopenharmony_ci    auto comps = g_pidCompsMap.find(remotePid);
43094332d3Sopenharmony_ci    if (comps != g_pidCompsMap.end()) {
44094332d3Sopenharmony_ci        CODEC_LOGE("RemoteService had been added deathRecipient!");
45094332d3Sopenharmony_ci        comps->second.insert(componentId);
46094332d3Sopenharmony_ci        return false;
47094332d3Sopenharmony_ci    }
48094332d3Sopenharmony_ci
49094332d3Sopenharmony_ci    uint64_t *addr = reinterpret_cast<uint64_t *>(callbacks->remote);
50094332d3Sopenharmony_ci    std::set<uint32_t> compIds;
51094332d3Sopenharmony_ci    compIds.insert(componentId);
52094332d3Sopenharmony_ci    g_pidCompsMap.emplace(std::make_pair(remotePid, compIds));
53094332d3Sopenharmony_ci    g_addrPidMap.emplace(std::make_pair(addr, remotePid));
54094332d3Sopenharmony_ci    return true;
55094332d3Sopenharmony_ci}
56094332d3Sopenharmony_ci
57094332d3Sopenharmony_ciint32_t CleanMapperOfDiedService(struct HdfRemoteService *remote, uint32_t *compIds, uint32_t *size)
58094332d3Sopenharmony_ci{
59094332d3Sopenharmony_ci    std::lock_guard<std::mutex> lk(g_mutex);
60094332d3Sopenharmony_ci
61094332d3Sopenharmony_ci    uint64_t *addr = reinterpret_cast<uint64_t *>(remote);
62094332d3Sopenharmony_ci    auto addrPid = g_addrPidMap.find(addr);
63094332d3Sopenharmony_ci    if (addrPid == g_addrPidMap.end()) {
64094332d3Sopenharmony_ci        CODEC_LOGE("RemoteService no mapper in g_addrPidMap!");
65094332d3Sopenharmony_ci        return HDF_FAILURE;
66094332d3Sopenharmony_ci    }
67094332d3Sopenharmony_ci
68094332d3Sopenharmony_ci    uint32_t remotePid = addrPid->second;
69094332d3Sopenharmony_ci    auto comps = g_pidCompsMap.find(remotePid);
70094332d3Sopenharmony_ci    if (comps == g_pidCompsMap.end()) {
71094332d3Sopenharmony_ci        CODEC_LOGE("RemoteService no mapper in g_pidCompsMap!");
72094332d3Sopenharmony_ci        return HDF_FAILURE;
73094332d3Sopenharmony_ci    }
74094332d3Sopenharmony_ci
75094332d3Sopenharmony_ci    std::set<uint32_t> ids = comps->second;
76094332d3Sopenharmony_ci    uint32_t index = 0;
77094332d3Sopenharmony_ci    *size = ids.size();
78094332d3Sopenharmony_ci    for (auto id = ids.begin(); id != ids.end(); id++) {
79094332d3Sopenharmony_ci        compIds[index++] = *id;
80094332d3Sopenharmony_ci    }
81094332d3Sopenharmony_ci
82094332d3Sopenharmony_ci    g_addrPidMap.erase(addrPid);
83094332d3Sopenharmony_ci    g_pidCompsMap.erase(comps);
84094332d3Sopenharmony_ci    CODEC_LOGE("clean service mapper success!");
85094332d3Sopenharmony_ci    return HDF_SUCCESS;
86094332d3Sopenharmony_ci}
87094332d3Sopenharmony_ci
88094332d3Sopenharmony_civoid RemoveDestoryedComponent(uint32_t componentId)
89094332d3Sopenharmony_ci{
90094332d3Sopenharmony_ci    std::lock_guard<std::mutex> lk(g_mutex);
91094332d3Sopenharmony_ci
92094332d3Sopenharmony_ci    uint32_t remotePid =  static_cast<uint32_t>(HdfRemoteGetCallingPid());
93094332d3Sopenharmony_ci    auto comps = g_pidCompsMap.find(remotePid);
94094332d3Sopenharmony_ci    if (comps != g_pidCompsMap.end()) {
95094332d3Sopenharmony_ci        comps->second.erase(componentId);
96094332d3Sopenharmony_ci    }
97094332d3Sopenharmony_ci}
98094332d3Sopenharmony_ci#ifdef __cplusplus
99094332d3Sopenharmony_ci};
100094332d3Sopenharmony_ci#endif
101