1 /*
2 * Copyright (C) 2021 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 #include "capability.h"
17 #include "hilog/log.h"
18 #include "json_helper.h"
19 #include "log_tags.h"
20 #include "plugin_common_type.h"
21
22 namespace OHOS {
23 namespace MultimediaPlugin {
24 using nlohmann::json;
25 using std::map;
26 using std::size_t;
27 using std::string;
28 using namespace OHOS::HiviewDFX;
29
30 static constexpr HiLogLabel LABEL = { LOG_CORE, LOG_TAG_DOMAIN_ID_PLUGIN, "Capability" };
31 const string Capability::CAPABILITY_BOOL_TRUE = "true";
32 const string Capability::CAPABILITY_BOOL_FALSE = "false";
33
Capability(const map<string,AttrData> & caps)34 Capability::Capability(const map<string, AttrData> &caps) : caps_(caps)
35 {}
36
Capability(map<string,AttrData> && caps)37 Capability::Capability(map<string, AttrData> &&caps) : caps_(std::move(caps))
38 {}
39
SetCapability(const json & capsInfo)40 uint32_t Capability::SetCapability(const json &capsInfo)
41 {
42 if (!capsInfo.is_array()) {
43 HiLog::Error(LABEL, "not a array type value.");
44 return ERR_INVALID_PARAMETER;
45 }
46
47 if (!caps_.empty()) {
48 caps_.clear();
49 }
50
51 size_t capNum = capsInfo.size();
52 HiLog::Debug(LABEL, "class cap num: %{public}zu.", capNum);
53 string name;
54 for (size_t i = 0; i < capNum; i++) {
55 const json &capabilityInfo = capsInfo[i];
56 if (JsonHelper::GetStringValue(capabilityInfo, "name", name) != SUCCESS) {
57 HiLog::Error(LABEL, "failed to analysis cap name.");
58 continue;
59 }
60
61 HiLog::Debug(LABEL, "get new cap, name: %{public}s.", name.c_str());
62 AttrData attrData;
63 if (AnalyzeAttrData(capabilityInfo, attrData) != SUCCESS) {
64 HiLog::Error(LABEL, "failed to analysis cap value.");
65 continue;
66 }
67
68 caps_.emplace(std::move(name), std::move(attrData));
69 }
70
71 return SUCCESS;
72 }
73
IsCompatible(const map<string,AttrData> & caps) const74 bool Capability::IsCompatible(const map<string, AttrData> &caps) const
75 {
76 for (const auto &capability : caps) {
77 auto iter = caps_.find(capability.first);
78 if (iter == caps_.end()) {
79 return false;
80 }
81
82 if (!iter->second.InRange(capability.second)) {
83 return false;
84 }
85 }
86
87 return true;
88 }
89
GetCapability(const string & key) const90 const AttrData *Capability::GetCapability(const string &key) const
91 {
92 auto iter = caps_.find(key);
93 if (iter == caps_.end()) {
94 return nullptr;
95 }
96
97 return &(iter->second);
98 }
99
GetCapability() const100 const std::map<std::string, AttrData> &Capability::GetCapability() const
101 {
102 return caps_;
103 }
104
105 // ------------------------------- private method -------------------------------
AnalyzeAttrData(const json & capInfo,AttrData & attrData)106 uint32_t Capability::AnalyzeAttrData(const json &capInfo, AttrData &attrData)
107 {
108 string type;
109 if (JsonHelper::GetStringValue(capInfo, "type", type) != SUCCESS) {
110 HiLog::Error(LABEL, "failed to analysis data type.");
111 return ERR_INVALID_PARAMETER;
112 }
113
114 std::map<string, AttrDataType> typeMap_ = {
115 { "bool", AttrDataType::ATTR_DATA_BOOL },
116 { "uint32", AttrDataType::ATTR_DATA_UINT32 },
117 { "string", AttrDataType::ATTR_DATA_STRING },
118 { "uint32Set", AttrDataType::ATTR_DATA_UINT32_SET },
119 { "stringSet", AttrDataType::ATTR_DATA_STRING_SET },
120 { "uint32Range", AttrDataType::ATTR_DATA_UINT32_RANGE }
121 };
122
123 auto iter = typeMap_.find(type);
124 if (iter == typeMap_.end()) {
125 HiLog::Error(LABEL, "unknown cap value type: %{public}s.", type.c_str());
126 return ERR_INVALID_PARAMETER;
127 }
128
129 switch (iter->second) {
130 case AttrDataType::ATTR_DATA_BOOL: {
131 return AnalyzeBool(capInfo, attrData);
132 }
133 case AttrDataType::ATTR_DATA_UINT32: {
134 return AnalyzeUint32(capInfo, attrData);
135 }
136 case AttrDataType::ATTR_DATA_STRING: {
137 return AnalyzeString(capInfo, attrData);
138 }
139 case AttrDataType::ATTR_DATA_UINT32_SET: {
140 return AnalyzeUint32Set(capInfo, attrData);
141 }
142 case AttrDataType::ATTR_DATA_STRING_SET: {
143 return AnalyzeStringSet(capInfo, attrData);
144 }
145 case AttrDataType::ATTR_DATA_UINT32_RANGE: {
146 return AnalyzeUint32Range(capInfo, attrData);
147 }
148 default: {
149 HiLog::Error(LABEL, "unexpected cap value type: %{public}d.", iter->second);
150 return ERR_INTERNAL;
151 }
152 }
153
154 return SUCCESS;
155 }
156
AnalyzeBool(const json & capInfo,AttrData & attrData)157 uint32_t Capability::AnalyzeBool(const json &capInfo, AttrData &attrData)
158 {
159 string value;
160 if (JsonHelper::GetStringValue(capInfo, "value", value) != SUCCESS) {
161 HiLog::Error(LABEL, "failed to analysis bool value.");
162 return ERR_INVALID_PARAMETER;
163 }
164
165 bool attrValue = false;
166 if (value == CAPABILITY_BOOL_TRUE) {
167 attrValue = true;
168 } else if (value == CAPABILITY_BOOL_FALSE) {
169 attrValue = false;
170 } else {
171 HiLog::Error(LABEL, "failed to analyze bool value: %{public}s.", value.c_str());
172 return ERR_INVALID_PARAMETER;
173 }
174
175 HiLog::Debug(LABEL, "get bool AttrData: %{public}s.", value.c_str());
176 attrData.SetData(attrValue);
177
178 return SUCCESS;
179 }
180
AnalyzeUint32(const json & capInfo,AttrData & attrData)181 uint32_t Capability::AnalyzeUint32(const json &capInfo, AttrData &attrData)
182 {
183 uint32_t value;
184 if (JsonHelper::GetUint32Value(capInfo, "value", value) != SUCCESS) {
185 HiLog::Error(LABEL, "failed to analysis uint32 value.");
186 return ERR_INVALID_PARAMETER;
187 }
188
189 HiLog::Debug(LABEL, "get uint32 AttrData: %{public}u.", value);
190 attrData.SetData(value);
191
192 return SUCCESS;
193 }
194
AnalyzeString(const json & capInfo,AttrData & attrData)195 uint32_t Capability::AnalyzeString(const json &capInfo, AttrData &attrData)
196 {
197 string value;
198 if (JsonHelper::GetStringValue(capInfo, "value", value) != SUCCESS) {
199 HiLog::Error(LABEL, "failed to analysis string value.");
200 return ERR_INVALID_PARAMETER;
201 }
202
203 if (value.empty()) {
204 HiLog::Error(LABEL, "failed to analyze string value.");
205 return ERR_INVALID_PARAMETER;
206 }
207
208 HiLog::Debug(LABEL, "get string AttrData: %{public}s.", value.c_str());
209 if (attrData.SetData(std::move(value)) != SUCCESS) {
210 HiLog::Error(LABEL, "AnalyzeString: failed to call SetData for string type.");
211 return ERR_INTERNAL;
212 }
213
214 return SUCCESS;
215 }
216
AnalyzeUint32Set(const json & capInfo,AttrData & attrData)217 uint32_t Capability::AnalyzeUint32Set(const json &capInfo, AttrData &attrData)
218 {
219 size_t arraySize;
220 if (JsonHelper::GetArraySize(capInfo, "value", arraySize) != SUCCESS) {
221 HiLog::Error(LABEL, "failed to analysis uint32Set value.");
222 return ERR_INVALID_PARAMETER;
223 }
224 HiLog::Debug(LABEL, "uint32Set size: %{public}zu.", arraySize);
225
226 if (arraySize < SET_MIN_VALUE_NUM) {
227 HiLog::Error(LABEL, "invalid uint32Set size: %{public}zu.", arraySize);
228 return ERR_INVALID_PARAMETER;
229 }
230
231 uint32_t value;
232 const json &valueArray = capInfo["value"];
233 for (size_t i = 0; i < arraySize; i++) {
234 if (JsonHelper::GetUint32Value(valueArray[i], value) != SUCCESS) {
235 HiLog::Error(LABEL, "fail to analyze uint32Set[%{public}zu]: %{public}u.", i, value);
236 attrData.ClearData();
237 return ERR_INVALID_PARAMETER;
238 }
239 HiLog::Debug(LABEL, "get uint32Set[%{public}zu]: %{public}u.", i, value);
240 if (attrData.InsertSet(value) != SUCCESS) {
241 HiLog::Error(LABEL, "AnalyzeUint32Set: failed to call InsertSet.");
242 attrData.ClearData();
243 return ERR_INTERNAL;
244 }
245 }
246
247 return SUCCESS;
248 }
249
AnalyzeUint32Range(const json & capInfo,AttrData & attrData)250 uint32_t Capability::AnalyzeUint32Range(const json &capInfo, AttrData &attrData)
251 {
252 size_t arraySize;
253 if (JsonHelper::GetArraySize(capInfo, "value", arraySize) != SUCCESS) {
254 HiLog::Error(LABEL, "failed to analysis uint32Range value.");
255 return ERR_INVALID_PARAMETER;
256 }
257 HiLog::Debug(LABEL, "uint32Range size: %{public}zu.", arraySize);
258
259 if (arraySize != AttrData::RANGE_ARRAY_SIZE) {
260 HiLog::Error(LABEL, "invalid uint32Range size: %{public}zu.", arraySize);
261 return ERR_INVALID_PARAMETER;
262 }
263
264 const json &valueArray = capInfo["value"];
265 uint32_t lowerBound = 0;
266 if (JsonHelper::GetUint32Value(valueArray[AttrData::LOWER_BOUND_INDEX], lowerBound) != SUCCESS) {
267 HiLog::Error(LABEL, "fail to analyze uint32 value of lowerBound: %{public}u.", lowerBound);
268 return ERR_INVALID_PARAMETER;
269 }
270
271 uint32_t upperBound = 0;
272 if (JsonHelper::GetUint32Value(valueArray[AttrData::UPPER_BOUND_INDEX], upperBound) != SUCCESS) {
273 HiLog::Error(LABEL, "fail to analyze uint32 value of upperBound: %{public}u.", upperBound);
274 return ERR_INVALID_PARAMETER;
275 }
276
277 HiLog::Debug(LABEL, "AnalyzeUint32Range: get lowerBound: %{public}u, upperBound: %{public}u.", lowerBound,
278 upperBound);
279 if (attrData.SetData(lowerBound, upperBound) != SUCCESS) {
280 HiLog::Error(LABEL, "AnalyzeUint32Range: failed to call SetData.");
281 return ERR_INTERNAL;
282 }
283
284 return SUCCESS;
285 }
286
AnalyzeStringSet(const json & capInfo,AttrData & attrData)287 uint32_t Capability::AnalyzeStringSet(const json &capInfo, AttrData &attrData)
288 {
289 size_t arraySize;
290 if (JsonHelper::GetArraySize(capInfo, "value", arraySize) != SUCCESS) {
291 HiLog::Error(LABEL, "failed to analysis stringSet value.");
292 return ERR_INVALID_PARAMETER;
293 }
294 HiLog::Debug(LABEL, "stringSet size: %{public}zu.", arraySize);
295
296 if (arraySize < SET_MIN_VALUE_NUM) {
297 HiLog::Error(LABEL, "invalid stringSet size: %{public}zu.", arraySize);
298 return ERR_INVALID_PARAMETER;
299 }
300
301 const json &valueArray = capInfo["value"];
302 string value;
303 for (size_t i = 0; i < arraySize; i++) {
304 if (JsonHelper::GetStringValue(valueArray[i], value) != SUCCESS) {
305 HiLog::Error(LABEL, "failed to analyze string value in stringSet[%{public}zu].", i);
306 attrData.ClearData();
307 return ERR_INVALID_PARAMETER;
308 }
309
310 HiLog::Debug(LABEL, "AnalyzeStringSet: get stringSet[%{public}zu]: %{public}s.", i, value.c_str());
311 if (attrData.InsertSet(std::move(value)) != SUCCESS) {
312 HiLog::Error(LABEL, "AnalyzeStringSet: failed to call InsertSet.");
313 attrData.ClearData();
314 return ERR_INTERNAL;
315 }
316 }
317
318 return SUCCESS;
319 }
320 } // namespace MultimediaPlugin
321 } // namespace OHOS
322