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
26 extern "C" {
27 #endif
28 
29 static std::map<uint64_t *, uint32_t> g_addrPidMap;
30 static std::map<uint32_t, std::set<uint32_t>> g_pidCompsMap;
31 static std::mutex g_mutex;
32 
RegisterService(struct CodecCallbackType * callbacks,uint32_t componentId,struct CodecComponentNode * codecNode)33 bool 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 
CleanMapperOfDiedService(struct HdfRemoteService * remote,uint32_t * compIds,uint32_t * size)57 int32_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 
RemoveDestoryedComponent(uint32_t componentId)88 void 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