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 "sensors_errors.h"
19
20 namespace OHOS {
21 namespace Sensors {
22 using namespace OHOS::HiviewDFX;
23 namespace {
24 constexpr int32_t STARTTMIE_MIN = 0;
25 constexpr int32_t STARTTMIE_MAX = 1800000;
26 constexpr int32_t CONTINUOUS_VIBRATION_DURATION_MIN = 10;
27 constexpr int32_t CONTINUOUS_VIBRATION_DURATION_MAX = 1600;
28 constexpr int32_t TRANSIENT_VIBRATION_DURATION = 30;
29 constexpr int32_t INTENSITY_MIN = 0;
30 constexpr int32_t INTENSITY_MAX = 100;
31 constexpr int32_t FREQUENCY_MIN = 0;
32 constexpr int32_t FREQUENCY_MAX = 100;
33 constexpr int32_t EVENT_NUM_MAX = 128;
34 constexpr double SUPPORT_JSON_VERSION = 1.0;
35 constexpr int32_t SUPPORT_CHANNEL_NUMBER = 1;
36 constexpr HiLogLabel LABEL = { LOG_CORE, MISC_LOG_DOMAIN, "DefaultVibratorDecoder" };
37 } // namespace
38
DecodeEffect(const RawFileDescriptor & rawFd)39 std::set<VibrateEvent> DefaultVibratorDecoder::DecodeEffect(const RawFileDescriptor &rawFd)
40 {
41 JsonParser parser(rawFd);
42 int32_t ret = CheckMetadata(parser);
43 if (ret != SUCCESS) {
44 MISC_HILOGE("Check metadata fail");
45 return {};
46 }
47 std::set<VibrateEvent> vibrateSet;
48 ret = ParseChannel(parser, vibrateSet);
49 if (ret != SUCCESS) {
50 MISC_HILOGE("Parse channel fail");
51 return {};
52 }
53 return vibrateSet;
54 }
55
CheckMetadata(const JsonParser & parser)56 int32_t DefaultVibratorDecoder::CheckMetadata(const JsonParser &parser)
57 {
58 cJSON* metadata = parser.GetObjectItem("MetaData");
59 CHKPR(metadata, ERROR);
60 cJSON* version = parser.GetObjectItem(metadata, "Version");
61 CHKPR(version, ERROR);
62 version_ = version->valuedouble;
63 if (version_ != SUPPORT_JSON_VERSION) {
64 MISC_HILOGE("Json file version is not supported, version:%{public}f", version_);
65 return ERROR;
66 }
67 cJSON* channelNumber = parser.GetObjectItem(metadata, "ChannelNumber");
68 CHKPR(channelNumber, ERROR);
69 channelNumber_ = channelNumber->valueint;
70 if (channelNumber_ != SUPPORT_CHANNEL_NUMBER) {
71 MISC_HILOGE("Json file channelNumber is not supported, channelNumber:%{public}d", channelNumber_);
72 return ERROR;
73 }
74 return SUCCESS;
75 }
76
ParseChannel(const JsonParser & parser,std::set<VibrateEvent> & vibrateSet)77 int32_t DefaultVibratorDecoder::ParseChannel(const JsonParser &parser, std::set<VibrateEvent> &vibrateSet)
78 {
79 cJSON *channels = parser.GetObjectItem("Channels");
80 CHKPR(channels, ERROR);
81 if (!parser.IsArray(channels)) {
82 MISC_HILOGE("The value of channels is not array");
83 return ERROR;
84 }
85 int32_t size = parser.GetArraySize(channels);
86 if (size != channelNumber_) {
87 MISC_HILOGE("The size of channels conflicts with channelNumber, size:%{public}d", size);
88 return ERROR;
89 }
90 for (int32_t i = 0; i < size; i++) {
91 cJSON* channel = parser.GetArrayItem(channels, i);
92 CHKPR(channel, ERROR);
93 cJSON* channelParameters = parser.GetObjectItem(channel, "Parameters");
94 CHKPR(channelParameters, ERROR);
95 int32_t ret = ParseChannelParameters(parser, channelParameters);
96 CHKCR((ret == SUCCESS), ERROR, "parse channel parameters fail");
97 cJSON* pattern = parser.GetObjectItem(channel, "Pattern");
98 CHKPR(pattern, ERROR);
99 ret = ParsePattern(parser, pattern, vibrateSet);
100 CHKCR((ret == SUCCESS), ERROR, "parse pattern fail");
101 }
102 return SUCCESS;
103 }
104
ParseChannelParameters(const JsonParser & parser,cJSON * channelParameters)105 int32_t DefaultVibratorDecoder::ParseChannelParameters(const JsonParser &parser, cJSON *channelParameters)
106 {
107 cJSON* index = parser.GetObjectItem(channelParameters, "Index");
108 CHKPR(index, ERROR);
109 int32_t indexVal = index->valueint;
110 CHKCR((indexVal == SUPPORT_CHANNEL_NUMBER), ERROR, "invalid channel index");
111 return SUCCESS;
112 }
113
ParsePattern(const JsonParser & parser,cJSON * pattern,std::set<VibrateEvent> & vibrateSet)114 int32_t DefaultVibratorDecoder::ParsePattern(const JsonParser &parser, cJSON *pattern,
115 std::set<VibrateEvent> &vibrateSet)
116 {
117 if (!parser.IsArray(pattern)) {
118 MISC_HILOGE("The value of pattern is not array");
119 return ERROR;
120 }
121 int32_t size = parser.GetArraySize(pattern);
122 if (size > EVENT_NUM_MAX) {
123 MISC_HILOGE("The size of pattern is out of bounds, size:%{public}d", size);
124 return ERROR;
125 }
126 for (int32_t i = 0; i < size; i++) {
127 cJSON* item = parser.GetArrayItem(pattern, i);
128 CHKPR(item, ERROR);
129 cJSON* event = parser.GetObjectItem(item, "Event");
130 CHKPR(event, ERROR);
131 int32_t ret = ParseEvent(parser, event, vibrateSet);
132 CHKCR((ret == SUCCESS), ERROR, "parse event fail");
133 }
134 return SUCCESS;
135 }
136
ParseEvent(const JsonParser & parser,cJSON * event,std::set<VibrateEvent> & vibrateSet)137 int32_t DefaultVibratorDecoder::ParseEvent(const JsonParser &parser, cJSON *event,
138 std::set<VibrateEvent> &vibrateSet)
139 {
140 VibrateEvent vibrateEvent;
141 cJSON* type = parser.GetObjectItem(event, "Type");
142 CHKPR(type, ERROR);
143 std::string curType = type->valuestring;
144 if (curType == "continuous") {
145 vibrateEvent.tag = EVENT_TAG_CONTINUOUS;
146 cJSON* duration = parser.GetObjectItem(event, "Duration");
147 CHKPR(duration, ERROR);
148 vibrateEvent.duration = duration->valueint;
149 } else if (curType == "transient") {
150 vibrateEvent.tag = EVENT_TAG_TRANSIENT;
151 vibrateEvent.duration = TRANSIENT_VIBRATION_DURATION;
152 } else {
153 MISC_HILOGE("Unknown event type, curType:%{public}s", curType.c_str());
154 return ERROR;
155 }
156 cJSON* startTime = parser.GetObjectItem(event, "StartTime");
157 CHKPR(startTime, ERROR);
158 vibrateEvent.startTime = startTime->valueint;
159 cJSON* eventParameters = parser.GetObjectItem(event, "Parameters");
160 CHKPR(eventParameters, ERROR);
161 cJSON* intensity = parser.GetObjectItem(eventParameters, "Intensity");
162 CHKPR(intensity, ERROR);
163 vibrateEvent.intensity = intensity->valueint;
164 cJSON* frequency = parser.GetObjectItem(eventParameters, "Frequency");
165 CHKPR(frequency, ERROR);
166 vibrateEvent.frequency = frequency->valueint;
167 if (!CheckParameters(vibrateEvent)) {
168 MISC_HILOGE("Parameter check of vibration event failed, startTime:%{public}d", vibrateEvent.startTime);
169 return ERROR;
170 }
171 if (vibrateEvent.intensity == INTENSITY_MIN) {
172 MISC_HILOGI("The event intensity is 0, startTime:%{public}d", vibrateEvent.startTime);
173 return SUCCESS;
174 }
175 auto ret = vibrateSet.insert(vibrateEvent);
176 if (!ret.second) {
177 MISC_HILOGE("Vibration event is duplicated, startTime:%{public}d", vibrateEvent.startTime);
178 return ERROR;
179 }
180 return SUCCESS;
181 }
182
CheckParameters(const VibrateEvent & vibrateEvent)183 bool DefaultVibratorDecoder::CheckParameters(const VibrateEvent &vibrateEvent)
184 {
185 if (vibrateEvent.startTime < STARTTMIE_MIN || vibrateEvent.startTime > STARTTMIE_MAX) {
186 MISC_HILOGE("The event startTime is out of range, startTime:%{public}d", vibrateEvent.startTime);
187 return false;
188 }
189 if (vibrateEvent.duration <= CONTINUOUS_VIBRATION_DURATION_MIN ||
190 vibrateEvent.duration >= CONTINUOUS_VIBRATION_DURATION_MAX) {
191 MISC_HILOGE("The event duration is out of range, duration:%{public}d", vibrateEvent.duration);
192 return false;
193 }
194 if (vibrateEvent.intensity < INTENSITY_MIN || vibrateEvent.intensity > INTENSITY_MAX) {
195 MISC_HILOGE("The event intensity is out of range, intensity:%{public}d", vibrateEvent.intensity);
196 return false;
197 }
198 if (vibrateEvent.frequency < FREQUENCY_MIN || vibrateEvent.frequency > FREQUENCY_MAX) {
199 MISC_HILOGE("The event frequency is out of range, frequency:%{public}d", vibrateEvent.frequency);
200 return false;
201 }
202 return true;
203 }
204 } // namespace Sensors
205 } // namespace OHOS