• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 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 "default_vibrator_decoder.h"
17 
18 #include <algorithm>
19 #include <cinttypes>
20 
21 #include "sensors_errors.h"
22 
23 #undef LOG_TAG
24 #define LOG_TAG "DefaultVibratorDecoder"
25 
26 namespace OHOS {
27 namespace Sensors {
28 namespace {
29 constexpr int32_t STARTTMIE_MIN = 0;
30 constexpr int32_t STARTTMIE_MAX = 1800000;
31 constexpr int32_t CONTINUOUS_VIBRATION_DURATION_MIN = 0;
32 constexpr int32_t CONTINUOUS_VIBRATION_DURATION_MAX = 5000;
33 constexpr int32_t TRANSIENT_VIBRATION_DURATION = 48;
34 constexpr int32_t INTENSITY_MIN = 0;
35 constexpr int32_t INTENSITY_MAX = 100;
36 constexpr int32_t FREQUENCY_MIN = 0;
37 constexpr int32_t FREQUENCY_MAX = 100;
38 constexpr int32_t EVENT_NUM_MAX = 128;
39 constexpr double SUPPORT_JSON_VERSION = 1.0;
40 constexpr int32_t SUPPORT_CHANNEL_NUMBER = 3;
41 constexpr uint32_t PATTERN_CAPACITY = 16;
42 constexpr uint32_t CURVE_POINT_MIN = 4;
43 constexpr uint32_t CURVE_POINT_MAX = 16;
44 constexpr int32_t CURVE_INTENSITY_MIN = 0;
45 constexpr int32_t CURVE_INTENSITY_MAX = 100;
46 constexpr int32_t CURVE_INTENSITY_SCALE = 100;
47 constexpr int32_t CURVE_FREQUENCY_MIN = -100;
48 constexpr int32_t CURVE_FREQUENCY_MAX = 100;
49 constexpr int32_t MAX_JSON_FILE_SIZE = 64 * 1024;
50 } // namespace
51 
DecodeEffect(const RawFileDescriptor & rawFd,VibratePackage & patternPackage)52 int32_t DefaultVibratorDecoder::DecodeEffect(const RawFileDescriptor &rawFd, VibratePackage &patternPackage)
53 {
54     if ((rawFd.fd < 0) || (rawFd.offset < 0) || (rawFd.length <= 0) || (rawFd.length > MAX_JSON_FILE_SIZE)) {
55         MISC_HILOGE("Invalid file descriptor, fd:%{public}d, offset:%{public}" PRId64 ", length:%{public}" PRId64,
56             rawFd.fd, rawFd.offset, rawFd.length);
57         return PARAMETER_ERROR;
58     }
59     JsonParser parser(rawFd);
60     int32_t ret = CheckMetadata(parser);
61     if (ret != SUCCESS) {
62         MISC_HILOGE("Check metadata fail");
63         return ret;
64     }
65     VibratePattern originPattern;
66     ret = ParseChannel(parser, originPattern);
67     if (ret != SUCCESS) {
68         MISC_HILOGE("Parse channel fail");
69         return ret;
70     }
71     PatternSplit(originPattern, patternPackage);
72     return SUCCESS;
73 }
74 
CheckMetadata(const JsonParser & parser)75 int32_t DefaultVibratorDecoder::CheckMetadata(const JsonParser &parser)
76 {
77     cJSON *metadataItem = parser.GetObjectItem("MetaData");
78     CHKPR(metadataItem, ERROR);
79     cJSON *versionItem = parser.GetObjectItem(metadataItem, "Version");
80     CHKPR(versionItem, ERROR);
81     version_ = parser.GetDoubleValue(versionItem);
82     if (version_ != SUPPORT_JSON_VERSION) {
83         MISC_HILOGE("Json file version is not supported, version:%{public}f", version_);
84         return ERROR;
85     }
86     cJSON *channelNumberItem = parser.GetObjectItem(metadataItem, "ChannelNumber");
87     CHKPR(channelNumberItem, ERROR);
88     channelNumber_ = parser.GetIntValue(channelNumberItem);
89     if ((channelNumber_ <= 0)|| (channelNumber_ >= SUPPORT_CHANNEL_NUMBER)) {
90         MISC_HILOGE("Json file channelNumber is not supported, channelNumber:%{public}d", channelNumber_);
91         return ERROR;
92     }
93     return SUCCESS;
94 }
95 
ParseChannel(const JsonParser & parser,VibratePattern & originPattern)96 int32_t DefaultVibratorDecoder::ParseChannel(const JsonParser &parser, VibratePattern &originPattern)
97 {
98     cJSON *channelsItem = parser.GetObjectItem("Channels");
99     CHKPR(channelsItem, ERROR);
100     if (!parser.IsArray(channelsItem)) {
101         MISC_HILOGE("The value of channels is not array");
102         return ERROR;
103     }
104     int32_t size = parser.GetArraySize(channelsItem);
105     if (size != channelNumber_) {
106         MISC_HILOGE("The size of channels conflicts with channelNumber, size:%{public}d", size);
107         return ERROR;
108     }
109     for (int32_t i = 0; i < size; i++) {
110         cJSON *channelItem = parser.GetArrayItem(channelsItem, i);
111         CHKPR(channelItem, ERROR);
112         cJSON *channelParametersItem = parser.GetObjectItem(channelItem, "Parameters");
113         CHKPR(channelParametersItem, ERROR);
114         int32_t ret = ParseChannelParameters(parser, channelParametersItem);
115         CHKCR((ret == SUCCESS), ERROR, "parse channel parameters fail");
116         cJSON *patternItem = parser.GetObjectItem(channelItem, "Pattern");
117         CHKPR(patternItem, ERROR);
118         ret = ParsePattern(parser, patternItem, originPattern);
119         CHKCR((ret == SUCCESS), ERROR, "parse pattern fail");
120     }
121     std::sort(originPattern.events.begin(), originPattern.events.end());
122     return SUCCESS;
123 }
124 
ParseChannelParameters(const JsonParser & parser,cJSON * channelParametersItem)125 int32_t DefaultVibratorDecoder::ParseChannelParameters(const JsonParser &parser, cJSON *channelParametersItem)
126 {
127     cJSON *indexItem = parser.GetObjectItem(channelParametersItem, "Index");
128     CHKPR(indexItem, ERROR);
129     int32_t indexVal = parser.GetIntValue(indexItem);
130     CHKCR((indexVal >= 0) && (indexVal < SUPPORT_CHANNEL_NUMBER), ERROR, "invalid channel index");
131     return SUCCESS;
132 }
133 
ParsePattern(const JsonParser & parser,cJSON * patternItem,VibratePattern & originPattern)134 int32_t DefaultVibratorDecoder::ParsePattern(const JsonParser &parser, cJSON *patternItem,
135     VibratePattern &originPattern)
136 {
137     if (!parser.IsArray(patternItem)) {
138         MISC_HILOGE("The value of pattern is not array");
139         return ERROR;
140     }
141     int32_t size = parser.GetArraySize(patternItem);
142     if (size > EVENT_NUM_MAX) {
143         MISC_HILOGE("The size of pattern is out of bounds, size:%{public}d", size);
144         return ERROR;
145     }
146     for (int32_t i = 0; i < size; i++) {
147         cJSON *item = parser.GetArrayItem(patternItem, i);
148         CHKPR(item, ERROR);
149         cJSON *eventItem = parser.GetObjectItem(item, "Event");
150         CHKPR(eventItem, ERROR);
151         VibrateEvent event;
152         int32_t ret = ParseEvent(parser, eventItem, event);
153         CHKCR((ret == SUCCESS), ERROR, "parse event fail");
154         originPattern.events.emplace_back(event);
155     }
156     return SUCCESS;
157 }
158 
ParseEvent(const JsonParser & parser,cJSON * eventItem,VibrateEvent & event)159 int32_t DefaultVibratorDecoder::ParseEvent(const JsonParser &parser, cJSON *eventItem, VibrateEvent &event)
160 {
161     cJSON *typeItem = parser.GetObjectItem(eventItem, "Type");
162     CHKPR(typeItem, ERROR);
163     std::string curType = parser.GetStringValue(typeItem);
164     if (curType == "continuous") {
165         event.tag = EVENT_TAG_CONTINUOUS;
166         cJSON *durationItem = parser.GetObjectItem(eventItem, "Duration");
167         CHKPR(durationItem, ERROR);
168         event.duration = parser.GetIntValue(durationItem);
169     } else if (curType == "transient") {
170         event.tag = EVENT_TAG_TRANSIENT;
171         event.duration = TRANSIENT_VIBRATION_DURATION;
172     } else {
173         MISC_HILOGE("Unknown event type, curType:%{public}s", curType.c_str());
174         return ERROR;
175     }
176     cJSON *startTimeItem = parser.GetObjectItem(eventItem, "StartTime");
177     CHKPR(startTimeItem, ERROR);
178     event.time = parser.GetIntValue(startTimeItem);
179     cJSON *eventParametersItem = parser.GetObjectItem(eventItem, "Parameters");
180     CHKPR(eventParametersItem, ERROR);
181     cJSON *intensityItem = parser.GetObjectItem(eventParametersItem, "Intensity");
182     CHKPR(intensityItem, ERROR);
183     event.intensity = parser.GetIntValue(intensityItem);
184     cJSON *frequencyItem = parser.GetObjectItem(eventParametersItem, "Frequency");
185     CHKPR(frequencyItem, ERROR);
186     event.frequency = parser.GetIntValue(frequencyItem);
187     if (!CheckEventParameters(event)) {
188         MISC_HILOGE("Parameter check of vibration event failed, startTime:%{public}d", event.time);
189         return ERROR;
190     }
191     if ((curType == "continuous") && parser.HasObjectItem(eventParametersItem, "Curve")) {
192         cJSON *curveItem = parser.GetObjectItem(eventParametersItem, "Curve");
193         CHKPR(curveItem, ERROR);
194         int32_t ret = ParseCurve(parser, curveItem, event);
195         if (ret != SUCCESS) {
196             MISC_HILOGE("Parse curve fail, startTime:%{public}d", event.time);
197             return ERROR;
198         }
199     }
200     return SUCCESS;
201 }
202 
CheckEventParameters(const VibrateEvent & event)203 bool DefaultVibratorDecoder::CheckEventParameters(const VibrateEvent &event)
204 {
205     if (event.time < STARTTMIE_MIN || event.time > STARTTMIE_MAX) {
206         MISC_HILOGE("The event startTime is out of range, startTime:%{public}d", event.time);
207         return false;
208     }
209     if (event.duration < CONTINUOUS_VIBRATION_DURATION_MIN ||
210         event.duration > CONTINUOUS_VIBRATION_DURATION_MAX) {
211         MISC_HILOGE("The event duration is out of range, duration:%{public}d", event.duration);
212         return false;
213     }
214     if (event.intensity < INTENSITY_MIN || event.intensity > INTENSITY_MAX) {
215         MISC_HILOGE("The event intensity is out of range, intensity:%{public}d", event.intensity);
216         return false;
217     }
218     if (event.frequency < FREQUENCY_MIN || event.frequency > FREQUENCY_MAX) {
219         MISC_HILOGE("The event frequency is out of range, frequency:%{public}d", event.frequency);
220         return false;
221     }
222     return true;
223 }
224 
ParseCurve(const JsonParser & parser,cJSON * curveItem,VibrateEvent & event)225 int32_t DefaultVibratorDecoder::ParseCurve(const JsonParser &parser, cJSON *curveItem, VibrateEvent &event)
226 {
227     if (!parser.IsArray(curveItem)) {
228         MISC_HILOGE("The value of curve is not array");
229         return ERROR;
230     }
231     size_t size = static_cast<size_t>(parser.GetArraySize(curveItem));
232     if ((size < CURVE_POINT_MIN) || (size > CURVE_POINT_MAX)) {
233         MISC_HILOGE("The size of curve point is out of bounds, size:%{public}zu", size);
234         return ERROR;
235     }
236     for (size_t i = 0; i < size; i++) {
237         VibrateCurvePoint point;
238         cJSON *item = parser.GetArrayItem(curveItem, i);
239         CHKPR(item, ERROR);
240         cJSON *timeItem = parser.GetObjectItem(item, "Time");
241         CHKPR(timeItem, ERROR);
242         point.time = parser.GetIntValue(timeItem);
243         if ((point.time < 0) || (point.time > event.duration)) {
244             MISC_HILOGE("The time of curve point is out of bounds, time:%{public}d", point.time);
245             return ERROR;
246         }
247         cJSON *intensityItem = parser.GetObjectItem(item, "Intensity");
248         CHKPR(intensityItem, ERROR);
249         point.intensity = (parser.GetDoubleValue(intensityItem)) * CURVE_INTENSITY_SCALE;
250         if ((point.intensity < CURVE_INTENSITY_MIN) || (point.intensity > CURVE_INTENSITY_MAX)) {
251             MISC_HILOGE("The intensity of curve point is out of bounds, intensity:%{public}d", point.intensity);
252             return ERROR;
253         }
254         cJSON *frequencyItem = parser.GetObjectItem(item, "Frequency");
255         CHKPR(frequencyItem, ERROR);
256         point.frequency = parser.GetIntValue(frequencyItem);
257         if ((point.frequency < CURVE_FREQUENCY_MIN) || (point.frequency > CURVE_FREQUENCY_MAX)) {
258             MISC_HILOGE("The frequency of curve point is out of bounds, frequency:%{public}d", point.frequency);
259             return ERROR;
260         }
261         event.points.emplace_back(point);
262     }
263     std::sort(event.points.begin(), event.points.end());
264     return SUCCESS;
265 }
266 
PatternSplit(VibratePattern & originPattern,VibratePackage & patternPackage)267 void DefaultVibratorDecoder::PatternSplit(VibratePattern &originPattern, VibratePackage &patternPackage)
268 {
269     if (originPattern.events.empty()) {
270         MISC_HILOGI("The origin pattern is empty");
271         return;
272     }
273     VibratePattern slicePattern;
274     slicePattern.startTime = originPattern.events[0].time;
275     size_t size = originPattern.events.size();
276     for (size_t i = 0; i < size; ++i) {
277         originPattern.events[i].time -= slicePattern.startTime;
278         slicePattern.events.emplace_back(originPattern.events[i]);
279         if ((slicePattern.events.size() >= PATTERN_CAPACITY) || (i == (size - 1))) {
280             patternPackage.patterns.emplace_back(slicePattern);
281             slicePattern.events.clear();
282             slicePattern.startTime = ((i < size - 1) ? originPattern.events[i + 1].time : 0);
283         }
284     }
285 }
286 }  // namespace Sensors
287 }  // namespace OHOS