• 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 "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