• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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     bool cond = arraySize < SET_MIN_VALUE_NUM;
229     CHECK_ERROR_RETURN_RET_LOG(cond, ERR_INVALID_PARAMETER, "invalid uint32Set size: %{public}zu.", arraySize);
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             IMAGE_LOGE("fail to analyze uint32Set[%{public}zu]: %{public}u.", i, value);
236             attrData.ClearData();
237             return ERR_INVALID_PARAMETER;
238         }
239         IMAGE_LOGD("get uint32Set[%{public}zu]: %{public}u.", i, value);
240         if (attrData.InsertSet(value) != SUCCESS) {
241             IMAGE_LOGE("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         IMAGE_LOGE("failed to analysis uint32Range value.");
255         return ERR_INVALID_PARAMETER;
256     }
257     IMAGE_LOGD("uint32Range size: %{public}zu.", arraySize);
258 
259     bool cond = arraySize != AttrData::RANGE_ARRAY_SIZE;
260     CHECK_ERROR_RETURN_RET_LOG(cond, ERR_INVALID_PARAMETER, "invalid uint32Range size: %{public}zu.", arraySize);
261 
262     const json &valueArray = capInfo["value"];
263     uint32_t lowerBound = 0;
264     if (JsonHelper::GetUint32Value(valueArray[AttrData::LOWER_BOUND_INDEX], lowerBound) != SUCCESS) {
265         IMAGE_LOGE("fail to analyze uint32 value of lowerBound: %{public}u.", lowerBound);
266         return ERR_INVALID_PARAMETER;
267     }
268 
269     uint32_t upperBound = 0;
270     if (JsonHelper::GetUint32Value(valueArray[AttrData::UPPER_BOUND_INDEX], upperBound) != SUCCESS) {
271         IMAGE_LOGE("fail to analyze uint32 value of upperBound: %{public}u.", upperBound);
272         return ERR_INVALID_PARAMETER;
273     }
274 
275     IMAGE_LOGD("AnalyzeUint32Range: get lowerBound: %{public}u, upperBound: %{public}u.", lowerBound, upperBound);
276     cond = attrData.SetData(lowerBound, upperBound) != SUCCESS;
277     CHECK_ERROR_RETURN_RET_LOG(cond, ERR_INTERNAL, "AnalyzeUint32Range: failed to call SetData.");
278 
279     return SUCCESS;
280 }
281 
AnalyzeStringSet(const json & capInfo,AttrData & attrData)282 uint32_t Capability::AnalyzeStringSet(const json &capInfo, AttrData &attrData)
283 {
284     size_t arraySize;
285     if (JsonHelper::GetArraySize(capInfo, "value", arraySize) != SUCCESS) {
286         IMAGE_LOGE("failed to analysis stringSet value.");
287         return ERR_INVALID_PARAMETER;
288     }
289     IMAGE_LOGD("stringSet size: %{public}zu.", arraySize);
290 
291     bool cond = arraySize < SET_MIN_VALUE_NUM;
292     CHECK_ERROR_RETURN_RET_LOG(cond, ERR_INVALID_PARAMETER, "invalid stringSet size: %{public}zu.", arraySize);
293 
294     const json &valueArray = capInfo["value"];
295     string value;
296     for (size_t i = 0; i < arraySize; i++) {
297         if (JsonHelper::GetStringValue(valueArray[i], value) != SUCCESS) {
298             IMAGE_LOGE("failed to analyze string value in stringSet[%{public}zu].", i);
299             attrData.ClearData();
300             return ERR_INVALID_PARAMETER;
301         }
302 
303         IMAGE_LOGD("AnalyzeStringSet: get stringSet[%{public}zu]: %{public}s.", i, value.c_str());
304         if (attrData.InsertSet(std::move(value)) != SUCCESS) {
305             IMAGE_LOGE("AnalyzeStringSet: failed to call InsertSet.");
306             attrData.ClearData();
307             return ERR_INTERNAL;
308         }
309     }
310 
311     return SUCCESS;
312 }
313 } // namespace MultimediaPlugin
314 } // namespace OHOS
315