• 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     AUDIO_INFO_LOG("deviceClass: %{public}s, info: %{public}s", deviceClass.c_str(), info.c_str());
55 
56     if (deviceClass == "primary") {
57         return GetId(HDI_ID_BASE_RENDER, HDI_ID_TYPE_PRIMARY, HDI_ID_INFO_DEFAULT);
58     } else if (deviceClass == "usb") {
59         return GetId(HDI_ID_BASE_RENDER, HDI_ID_TYPE_PRIMARY, HDI_ID_INFO_USB);
60     } else if (deviceClass == "dp") {
61         return GetId(HDI_ID_BASE_RENDER, HDI_ID_TYPE_PRIMARY, HDI_ID_INFO_DP);
62     } else if (deviceClass == "a2dp") {
63         return GetId(HDI_ID_BASE_RENDER, HDI_ID_TYPE_BLUETOOTH, HDI_ID_INFO_DEFAULT);
64     } else if (deviceClass == "a2dp_fast") {
65         return GetId(HDI_ID_BASE_RENDER, HDI_ID_TYPE_BLUETOOTH, HDI_ID_INFO_MMAP);
66 #ifdef FEATURE_FILE_IO
67     } else if (deviceClass == "file_io") {
68         return GetId(HDI_ID_BASE_RENDER, HDI_ID_TYPE_FILE, HDI_ID_INFO_DEFAULT);
69 #endif
70 #ifdef FEATURE_DISTRIBUTE_AUDIO
71     } else if (deviceClass == "remote") {
72         return GetId(HDI_ID_BASE_RENDER, HDI_ID_TYPE_REMOTE, info);
73 #endif
74     } else if (deviceClass == "offload") {
75         return GetId(HDI_ID_BASE_RENDER, HDI_ID_TYPE_OFFLOAD, HDI_ID_INFO_DEFAULT);
76     } else if (deviceClass == "multichannel") {
77         return GetId(HDI_ID_BASE_RENDER, HDI_ID_TYPE_MULTICHANNEL, HDI_ID_INFO_DEFAULT);
78     } else if (deviceClass == "primary_direct_voip") {
79         return GetId(HDI_ID_BASE_RENDER, HDI_ID_TYPE_PRIMARY, HDI_ID_INFO_VOIP);
80     } else if (deviceClass == "primary_mmap_voip") {
81         return GetId(HDI_ID_BASE_RENDER, HDI_ID_TYPE_FAST, HDI_ID_INFO_VOIP);
82     }
83 
84     AUDIO_ERR_LOG("invalid param, deviceClass: %{public}s, info: %{public}s", deviceClass.c_str(), info.c_str());
85     return HDI_INVALID_ID;
86 }
87 
GetCaptureIdByDeviceClass(const std::string & deviceClass,const SourceType sourceType,const std::string & info)88 uint32_t IdHandler::GetCaptureIdByDeviceClass(const std::string &deviceClass, const SourceType sourceType,
89     const std::string &info)
90 {
91     CHECK_AND_RETURN_RET_LOG(!deviceClass.empty(), HDI_INVALID_ID, "invalid device class");
92     AUDIO_INFO_LOG("deviceClass: %{public}s, sourceType: %{public}d, info: %{public}s", deviceClass.c_str(), sourceType,
93         info.c_str());
94 
95     if (deviceClass == "primary") {
96         if (sourceType == SOURCE_TYPE_WAKEUP) {
97             return GetId(HDI_ID_BASE_CAPTURE, HDI_ID_TYPE_WAKEUP, info);
98         }
99         if (info == HDI_ID_INFO_EC || info == HDI_ID_INFO_MIC_REF) {
100             return GetId(HDI_ID_BASE_CAPTURE, HDI_ID_TYPE_PRIMARY, info);
101         }
102         return GetId(HDI_ID_BASE_CAPTURE, HDI_ID_TYPE_PRIMARY, HDI_ID_INFO_DEFAULT);
103     } else if (deviceClass == "usb") {
104         return GetId(HDI_ID_BASE_CAPTURE, HDI_ID_TYPE_PRIMARY, HDI_ID_INFO_USB);
105     } else if (deviceClass == "a2dp") {
106         return GetId(HDI_ID_BASE_CAPTURE, HDI_ID_TYPE_BLUETOOTH, HDI_ID_INFO_DEFAULT);
107 #ifdef FEATURE_FILE_IO
108     } else if (deviceClass == "file_io") {
109         return GetId(HDI_ID_BASE_CAPTURE, HDI_ID_TYPE_FILE, HDI_ID_INFO_DEFAULT);
110 #endif
111 #ifdef FEATURE_DISTRIBUTE_AUDIO
112     } else if (deviceClass == "remote") {
113         return GetId(HDI_ID_BASE_CAPTURE, HDI_ID_TYPE_REMOTE, info);
114 #endif
115     }
116 
117     AUDIO_ERR_LOG("invalid param, deviceClass: %{public}s, sourceType: %{public}d, info: %{public}s",
118         deviceClass.c_str(), sourceType, info.c_str());
119     return HDI_INVALID_ID;
120 }
121 
IncInfoIdUseCount(uint32_t id)122 void IdHandler::IncInfoIdUseCount(uint32_t id)
123 {
124     uint32_t infoId = id & HDI_ID_INFO_MASK;
125     CHECK_AND_RETURN_LOG(infoIdMap_.count(infoId) != 0, "invalid id %{public}u", id);
126     std::lock_guard<std::mutex> lock(infoIdMtx_);
127     infoIdMap_[infoId].useCount_++;
128 }
129 
DecInfoIdUseCount(uint32_t id)130 void IdHandler::DecInfoIdUseCount(uint32_t id)
131 {
132     uint32_t infoId = id & HDI_ID_INFO_MASK;
133     CHECK_AND_RETURN_LOG(infoIdMap_.count(infoId) != 0, "invalid id %{public}u", id);
134     std::lock_guard<std::mutex> lock(infoIdMtx_);
135     if (infoIdMap_[infoId].useCount_.load() > 0) {
136         infoIdMap_[infoId].useCount_--;
137         if (infoIdMap_[infoId].useCount_.load() > 0) {
138             AUDIO_DEBUG_LOG("info: %{public}s, useCount: %{public}u", infoIdMap_[infoId].info_.c_str(),
139                 infoIdMap_[infoId].useCount_.load());
140             return;
141         }
142     }
143     infoIdMap_.erase(infoId);
144     std::lock_guard<std::mutex> freeLock(freeInfoIdMtx_);
145     freeInfoIdSet_.emplace(infoId);
146 }
147 
CheckId(uint32_t id,HdiIdBase requireBase)148 bool IdHandler::CheckId(uint32_t id, HdiIdBase requireBase)
149 {
150     CHECK_AND_RETURN_RET_LOG(ParseBase(id) == requireBase, false, "invalid id base, id: %{public}u, "
151         "requireBase: %{public}u", id, requireBase);
152     CHECK_AND_RETURN_RET_LOG(ParseType(id) < HDI_ID_TYPE_NUM, false, "invalid id type");
153     CHECK_AND_RETURN_RET_LOG(!ParseInfo(id).empty(), false, "invalid id info");
154     return true;
155 }
156 
ParseBase(uint32_t id)157 uint32_t IdHandler::ParseBase(uint32_t id)
158 {
159     return (id & HDI_ID_BASE_MASK) >> HDI_ID_BASE_OFFSET;
160 }
161 
ParseType(uint32_t id)162 uint32_t IdHandler::ParseType(uint32_t id)
163 {
164     return (id & HDI_ID_TYPE_MASK) >> HDI_ID_TYPE_OFFSET;
165 }
166 
ParseInfo(uint32_t id)167 std::string IdHandler::ParseInfo(uint32_t id)
168 {
169     std::lock_guard<std::mutex> lock(infoIdMtx_);
170     uint32_t infoId = id & HDI_ID_INFO_MASK;
171     CHECK_AND_RETURN_RET_LOG(infoIdMap_.count(infoId) != 0, "", "invalid id %{public}u", id);
172     return infoIdMap_[infoId].info_;
173 }
174 
CreateInfoId(void)175 uint32_t IdHandler::CreateInfoId(void)
176 {
177     if (freeInfoIdSet_.empty()) {
178         return infoIdMap_.size();
179     }
180     std::lock_guard<std::mutex> lock(freeInfoIdMtx_);
181     uint32_t infoId = *freeInfoIdSet_.begin();
182     freeInfoIdSet_.erase(infoId);
183     return infoId;
184 }
185 
186 } // namespace AudioStandard
187 } // namespace OHOS
188