• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 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 
16 #ifndef LOG_TAG
17 #define LOG_TAG "IdHandler"
18 #endif
19 
20 #include "util/id_handler.h"
21 #include "audio_hdi_log.h"
22 #include "audio_errors.h"
23 
24 namespace OHOS {
25 namespace AudioStandard {
GetInstance(void)26 IdHandler &IdHandler::GetInstance(void)
27 {
28     static IdHandler instance;
29     return instance;
30 }
31 
GetId(HdiIdBase base,HdiIdType type,const std::string & info)32 uint32_t IdHandler::GetId(HdiIdBase base, HdiIdType type, const std::string &info)
33 {
34     CHECK_AND_RETURN_RET_LOG(base < HDI_ID_BASE_NUM, HDI_INVALID_ID, "invalid id base %{public}u", base);
35     CHECK_AND_RETURN_RET_LOG(type < HDI_ID_TYPE_NUM, HDI_INVALID_ID, "invalid id type %{public}u", type);
36 
37     uint32_t id = (base << HDI_ID_BASE_OFFSET) | (type << HDI_ID_TYPE_OFFSET);
38     std::lock_guard<std::mutex> lock(infoIdMtx_);
39     for (auto &attr : infoIdMap_) {
40         if (attr.second.info_ == info) {
41             id |= attr.first;
42             return id;
43         }
44     }
45     uint32_t infoId = CreateInfoId();
46     infoIdMap_[infoId].info_ = info;
47     id |= infoId;
48     return id;
49 }
50 
GetRenderIdByDeviceClass(const std::string & deviceClass,const std::string & info)51 uint32_t IdHandler::GetRenderIdByDeviceClass(const std::string &deviceClass, const std::string &info)
52 {
53     CHECK_AND_RETURN_RET_LOG(!deviceClass.empty(), HDI_INVALID_ID, "invalid device class");
54 
55     if (deviceClass == "primary") {
56         return GetId(HDI_ID_BASE_RENDER, HDI_ID_TYPE_PRIMARY, HDI_ID_INFO_DEFAULT);
57     } else if (deviceClass == "usb") {
58         return GetId(HDI_ID_BASE_RENDER, HDI_ID_TYPE_PRIMARY, HDI_ID_INFO_USB);
59     } else if (deviceClass == "dp") {
60         return GetId(HDI_ID_BASE_RENDER, HDI_ID_TYPE_PRIMARY, HDI_ID_INFO_DP);
61     } else if (deviceClass == "a2dp") {
62         return GetId(HDI_ID_BASE_RENDER, HDI_ID_TYPE_BLUETOOTH, HDI_ID_INFO_DEFAULT);
63     } else if (deviceClass == "a2dp_fast") {
64         return GetId(HDI_ID_BASE_RENDER, HDI_ID_TYPE_BLUETOOTH, HDI_ID_INFO_MMAP);
65     } else if (deviceClass == "hearing_aid") {
66         return GetId(HDI_ID_BASE_RENDER, HDI_ID_TYPE_BLUETOOTH, HDI_ID_INFO_HEARING_AID);
67 #ifdef FEATURE_FILE_IO
68     } else if (deviceClass == "file_io") {
69         return GetId(HDI_ID_BASE_RENDER, HDI_ID_TYPE_FILE, HDI_ID_INFO_DEFAULT);
70 #endif
71 #ifdef FEATURE_DISTRIBUTE_AUDIO
72     } else if (deviceClass == "remote") {
73         return GetId(HDI_ID_BASE_RENDER, HDI_ID_TYPE_REMOTE, info);
74     } else if (deviceClass == "remote_offload") {
75         return GetId(HDI_ID_BASE_RENDER, HDI_ID_TYPE_REMOTE_OFFLOAD, info);
76 #endif
77     } else if (deviceClass == "offload") {
78         return GetId(HDI_ID_BASE_RENDER, HDI_ID_TYPE_OFFLOAD, HDI_ID_INFO_DEFAULT);
79     } else if (deviceClass == "multichannel") {
80         return GetId(HDI_ID_BASE_RENDER, HDI_ID_TYPE_MULTICHANNEL, HDI_ID_INFO_DEFAULT);
81     } else if (deviceClass == "dp_multichannel") {
82         return GetId(HDI_ID_BASE_RENDER, HDI_ID_TYPE_MULTICHANNEL, HDI_ID_INFO_DP);
83     } else if (deviceClass == "primary_direct_voip") {
84         return GetId(HDI_ID_BASE_RENDER, HDI_ID_TYPE_PRIMARY, HDI_ID_INFO_VOIP);
85     } else if (deviceClass == "primary_mmap_voip") {
86         return GetId(HDI_ID_BASE_RENDER, HDI_ID_TYPE_FAST, HDI_ID_INFO_VOIP);
87     }
88 
89     AUDIO_ERR_LOG("invalid param, deviceClass: %{public}s, info: %{public}s", deviceClass.c_str(), info.c_str());
90     return HDI_INVALID_ID;
91 }
92 
GetCaptureIdByDeviceClass(const std::string & deviceClass,const SourceType sourceType,const std::string & info)93 uint32_t IdHandler::GetCaptureIdByDeviceClass(const std::string &deviceClass, const SourceType sourceType,
94     const std::string &info)
95 {
96     CHECK_AND_RETURN_RET_LOG(!deviceClass.empty(), HDI_INVALID_ID, "invalid device class");
97     AUDIO_INFO_LOG("deviceClass: %{public}s, sourceType: %{public}d, info: %{public}s", deviceClass.c_str(), sourceType,
98         info.c_str());
99 
100     if (deviceClass == "primary") {
101         if (sourceType == SOURCE_TYPE_WAKEUP) {
102             return GetId(HDI_ID_BASE_CAPTURE, HDI_ID_TYPE_WAKEUP, info);
103         }
104         if (info == HDI_ID_INFO_EC || info == HDI_ID_INFO_MIC_REF) {
105             return GetId(HDI_ID_BASE_CAPTURE, HDI_ID_TYPE_PRIMARY, info);
106         }
107         return GetId(HDI_ID_BASE_CAPTURE, HDI_ID_TYPE_PRIMARY, HDI_ID_INFO_DEFAULT);
108     } else if (deviceClass == "usb") {
109         return GetId(HDI_ID_BASE_CAPTURE, HDI_ID_TYPE_PRIMARY, HDI_ID_INFO_USB);
110     } else if (deviceClass == "a2dp") {
111         return GetId(HDI_ID_BASE_CAPTURE, HDI_ID_TYPE_BLUETOOTH, HDI_ID_INFO_DEFAULT);
112 #ifdef FEATURE_FILE_IO
113     } else if (deviceClass == "file_io") {
114         return GetId(HDI_ID_BASE_CAPTURE, HDI_ID_TYPE_FILE, HDI_ID_INFO_DEFAULT);
115 #endif
116 #ifdef FEATURE_DISTRIBUTE_AUDIO
117     } else if (deviceClass == "remote") {
118         return GetId(HDI_ID_BASE_CAPTURE, HDI_ID_TYPE_REMOTE, info);
119 #endif
120     } else if (deviceClass == "accessory") {
121         return GetId(HDI_ID_BASE_CAPTURE, HDI_ID_TYPE_ACCESSORY, HDI_ID_INFO_ACCESSORY);
122     }
123 
124     AUDIO_ERR_LOG("invalid param, deviceClass: %{public}s, sourceType: %{public}d, info: %{public}s",
125         deviceClass.c_str(), sourceType, info.c_str());
126     return HDI_INVALID_ID;
127 }
128 
IncInfoIdUseCount(uint32_t id)129 void IdHandler::IncInfoIdUseCount(uint32_t id)
130 {
131     uint32_t infoId = id & HDI_ID_INFO_MASK;
132     std::lock_guard<std::mutex> lock(infoIdMtx_);
133     CHECK_AND_RETURN_LOG(infoIdMap_.count(infoId) != 0, "invalid id %{public}u", id);
134     infoIdMap_[infoId].useCount_++;
135     AUDIO_DEBUG_LOG("info: %{public}s, useCount: %{public}u", infoIdMap_[infoId].info_.c_str(),
136         infoIdMap_[infoId].useCount_.load());
137 }
138 
DecInfoIdUseCount(uint32_t id)139 void IdHandler::DecInfoIdUseCount(uint32_t id)
140 {
141     uint32_t infoId = id & HDI_ID_INFO_MASK;
142     std::lock_guard<std::mutex> lock(infoIdMtx_);
143     CHECK_AND_RETURN_LOG(infoIdMap_.count(infoId) != 0, "invalid id %{public}u", id);
144     if (infoIdMap_[infoId].useCount_.load() > 0) {
145         infoIdMap_[infoId].useCount_--;
146         AUDIO_DEBUG_LOG("info: %{public}s, useCount: %{public}u", infoIdMap_[infoId].info_.c_str(),
147             infoIdMap_[infoId].useCount_.load());
148         if (infoIdMap_[infoId].useCount_.load() > 0) {
149             return;
150         }
151     }
152     infoIdMap_.erase(infoId);
153     std::lock_guard<std::mutex> freeLock(freeInfoIdMtx_);
154     freeInfoIdSet_.emplace(infoId);
155 }
156 
CheckId(uint32_t id,HdiIdBase requireBase)157 bool IdHandler::CheckId(uint32_t id, HdiIdBase requireBase)
158 {
159     CHECK_AND_RETURN_RET_LOG(ParseBase(id) == requireBase, false, "invalid id base, id: %{public}u, "
160         "requireBase: %{public}u", id, requireBase);
161     CHECK_AND_RETURN_RET_LOG(ParseType(id) < HDI_ID_TYPE_NUM, false, "invalid id type");
162     CHECK_AND_RETURN_RET_LOG(!ParseInfo(id).empty(), false, "invalid id info");
163     return true;
164 }
165 
ParseBase(uint32_t id)166 uint32_t IdHandler::ParseBase(uint32_t id)
167 {
168     return (id & HDI_ID_BASE_MASK) >> HDI_ID_BASE_OFFSET;
169 }
170 
ParseType(uint32_t id)171 uint32_t IdHandler::ParseType(uint32_t id)
172 {
173     return (id & HDI_ID_TYPE_MASK) >> HDI_ID_TYPE_OFFSET;
174 }
175 
ParseInfo(uint32_t id)176 std::string IdHandler::ParseInfo(uint32_t id)
177 {
178     std::lock_guard<std::mutex> lock(infoIdMtx_);
179     uint32_t infoId = id & HDI_ID_INFO_MASK;
180     CHECK_AND_RETURN_RET_LOG(infoIdMap_.count(infoId) != 0, "", "invalid id %{public}u", id);
181     return infoIdMap_[infoId].info_;
182 }
183 
CreateInfoId(void)184 uint32_t IdHandler::CreateInfoId(void)
185 {
186     std::lock_guard<std::mutex> lock(freeInfoIdMtx_);
187 
188     if (freeInfoIdSet_.empty()) {
189         return infoIdMap_.size();
190     }
191 
192     uint32_t infoId = *freeInfoIdSet_.begin();
193     freeInfoIdSet_.erase(infoId);
194     return infoId;
195 }
196 
197 } // namespace AudioStandard
198 } // namespace OHOS
199