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 
22 namespace OHOS {
23 namespace HDI {
24 namespace Codec {
25 namespace V3_0 {
26 
27 static std::map<IRemoteObject *, std::set<uint32_t>> g_remoteCompsMap;
28 static std::map<IRemoteObject *, sptr<CodecDeathRecipient>> g_deathReciMap;
29 static std::map<uint32_t, IRemoteObject *> g_compRemoteMap;
30 static std::mutex g_mutex;
31 
CleanResourceOfDiedService(sptr<IRemoteObject> object,wptr<CodecComponentManagerService> managerService)32 void 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 
RegisterDeathRecipientService(const sptr<ICodecCallback> callbacks,uint32_t componentId,wptr<CodecComponentManagerService> service)52 void 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 
RemoveMapperOfDestoryedComponent(uint32_t componentId)81 void 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