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