1/*
2 * Copyright (c) 2022-2024 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#include "vibrator_infos.h"
16
17#include <cerrno>
18#include <cinttypes>
19
20#include <sys/stat.h>
21#include <unistd.h>
22
23#include "sensors_errors.h"
24
25#undef LOG_TAG
26#define LOG_TAG "MiscdeviceVibratorInfos"
27
28namespace OHOS {
29namespace Sensors {
30void VibratePattern::Dump() const
31{
32    int32_t size = static_cast<int32_t>(events.size());
33    MISC_HILOGD("Pattern startTime:%{public}d, eventSize:%{public}d", startTime, size);
34    for (int32_t i = 0; i < size; ++i) {
35        std::string tag = (events[i].tag == EVENT_TAG_CONTINUOUS) ? "continuous" : "transient";
36        int32_t pointSize = static_cast<int32_t>(events[i].points.size());
37        MISC_HILOGD("Event tag:%{public}s, time:%{public}d, duration:%{public}d,"
38            "intensity:%{public}d, frequency:%{public}d, index:%{public}d, curve pointSize:%{public}d",
39            tag.c_str(), events[i].time, events[i].duration, events[i].intensity,
40            events[i].frequency, events[i].index, pointSize);
41        for (int32_t j = 0; j < pointSize; ++j) {
42            MISC_HILOGD("Curve point time:%{public}d, intensity:%{public}d, frequency:%{public}d",
43                events[i].points[j].time, events[i].points[j].intensity, events[i].points[j].frequency);
44        }
45    }
46}
47
48void VibratePackage::Dump() const
49{
50    int32_t size = static_cast<int32_t>(patterns.size());
51    MISC_HILOGD("Vibrate package pattern size:%{public}d", size);
52    for (int32_t i = 0; i < size; ++i) {
53        patterns[i].Dump();
54    }
55}
56
57void VibratorCapacity::Dump() const
58{
59    std::string isSupportHdHapticStr = isSupportHdHaptic ? "true" : "false";
60    std::string isSupportPresetMappingStr = isSupportPresetMapping ? "true" : "false";
61    std::string isSupportTimeDelayStr = isSupportTimeDelay ? "true" : "false";
62    MISC_HILOGD("SupportHdHaptic:%{public}s, SupportPresetMapping:%{public}s, "
63        "SupportTimeDelayStr:%{public}s", isSupportHdHapticStr.c_str(),
64        isSupportPresetMappingStr.c_str(), isSupportTimeDelayStr.c_str());
65}
66
67int32_t VibratorCapacity::GetVibrateMode()
68{
69    if (isSupportHdHaptic) {
70        return VIBRATE_MODE_HD;
71    }
72    if (isSupportPresetMapping) {
73        return VIBRATE_MODE_MAPPING;
74    }
75    if (isSupportTimeDelay) {
76        return VIBRATE_MODE_TIMES;
77    }
78    return -1;
79}
80
81bool VibratorCapacity::Marshalling(Parcel &parcel) const
82{
83    if (!parcel.WriteBool(isSupportHdHaptic)) {
84        MISC_HILOGE("Write isSupportHdHaptic failed");
85        return false;
86    }
87    if (!parcel.WriteBool(isSupportPresetMapping)) {
88        MISC_HILOGE("Write isSupportPresetMapping failed");
89        return false;
90    }
91    if (!parcel.WriteBool(isSupportTimeDelay)) {
92        MISC_HILOGE("Write isSupportTimeDelay failed");
93        return false;
94    }
95    return true;
96}
97
98std::optional<VibratorCapacity> VibratorCapacity::Unmarshalling(Parcel &data)
99{
100    VibratorCapacity capacity;
101    if (!(data.ReadBool(capacity.isSupportHdHaptic))) {
102        MISC_HILOGE("Read isSupportHdHaptic failed");
103        return std::nullopt;
104    }
105    if (!(data.ReadBool(capacity.isSupportPresetMapping))) {
106        MISC_HILOGE("Read isSupportPresetMapping failed");
107        return std::nullopt;
108    }
109    if (!(data.ReadBool(capacity.isSupportTimeDelay))) {
110        MISC_HILOGE("Read isSupportTimeDelay failed");
111        return std::nullopt;
112    }
113    return capacity;
114}
115
116bool VibratePattern::Marshalling(Parcel &parcel) const
117{
118    if (!parcel.WriteInt32(startTime)) {
119        MISC_HILOGE("Write pattern's startTime failed");
120        return false;
121    }
122    if (!parcel.WriteInt32(patternDuration)) {
123        MISC_HILOGE("Write patternDuration failed");
124        return false;
125    }
126    if (!parcel.WriteInt32(static_cast<int32_t>(events.size()))) {
127        MISC_HILOGE("Write events's size failed");
128        return false;
129    }
130    for (size_t i = 0; i < events.size(); ++i) {
131        if (!parcel.WriteInt32(static_cast<int32_t>(events[i].tag))) {
132            MISC_HILOGE("Write tag failed");
133            return false;
134        }
135        if (!parcel.WriteInt32(events[i].time)) {
136            MISC_HILOGE("Write events's time failed");
137            return false;
138        }
139        if (!parcel.WriteInt32(events[i].duration)) {
140            MISC_HILOGE("Write duration failed");
141            return false;
142        }
143        if (!parcel.WriteInt32(events[i].intensity)) {
144            MISC_HILOGE("Write intensity failed");
145            return false;
146        }
147        if (!parcel.WriteInt32(events[i].frequency)) {
148            MISC_HILOGE("Write frequency failed");
149            return false;
150        }
151        if (!parcel.WriteInt32(events[i].index)) {
152            MISC_HILOGE("Write index failed");
153            return false;
154        }
155        if (!parcel.WriteInt32(static_cast<int32_t>(events[i].points.size()))) {
156            MISC_HILOGE("Write points's size failed");
157            return false;
158        }
159        for (size_t j = 0; j < events[i].points.size(); ++j) {
160            if (!parcel.WriteInt32(events[i].points[j].time)) {
161                MISC_HILOGE("Write points's time failed");
162                return false;
163            }
164            if (!parcel.WriteInt32(events[i].points[j].intensity)) {
165                MISC_HILOGE("Write points's intensity failed");
166                return false;
167            }
168            if (!parcel.WriteInt32(events[i].points[j].frequency)) {
169                MISC_HILOGE("Write points's frequency failed");
170                return false;
171            }
172        }
173    }
174    return true;
175}
176
177std::optional<VibratePattern> VibratePattern::Unmarshalling(Parcel &data)
178{
179    VibratePattern pattern;
180    if (!(data.ReadInt32(pattern.startTime))) {
181        MISC_HILOGE("Read time failed");
182        return std::nullopt;
183    }
184    if (!(data.ReadInt32(pattern.patternDuration))) {
185        MISC_HILOGE("Read duration failed");
186        return std::nullopt;
187    }
188    int32_t eventSize { 0 };
189    if (!(data.ReadInt32(eventSize))) {
190        MISC_HILOGE("Read eventSize failed");
191        return std::nullopt;
192    }
193    if (eventSize > MAX_EVENT_SIZE) {
194        MISC_HILOGE("eventSize exceed the maximum");
195        return std::nullopt;
196    }
197    for (int32_t i = 0; i < eventSize; ++i) {
198        VibrateEvent event;
199        int32_t tag { -1 };
200        if (!data.ReadInt32(tag)) {
201            MISC_HILOGE("Read type failed");
202            return std::nullopt;
203        }
204        event.tag = static_cast<VibrateTag>(tag);
205        if (!data.ReadInt32(event.time)) {
206            MISC_HILOGE("Read events's time failed");
207            return std::nullopt;
208        }
209        if (!data.ReadInt32(event.duration)) {
210            MISC_HILOGE("Read duration failed");
211            return std::nullopt;
212        }
213        if (!data.ReadInt32(event.intensity)) {
214            MISC_HILOGE("Read intensity failed");
215            return std::nullopt;
216        }
217        if (!data.ReadInt32(event.frequency)) {
218            MISC_HILOGE("Read frequency failed");
219            return std::nullopt;
220        }
221        if (!data.ReadInt32(event.index)) {
222            MISC_HILOGE("Read index failed");
223            return std::nullopt;
224        }
225        int32_t pointSize { 0 };
226        if (!data.ReadInt32(pointSize)) {
227            MISC_HILOGE("Read pointSize failed");
228            return std::nullopt;
229        }
230        if (pointSize > MAX_POINT_SIZE) {
231            MISC_HILOGE("pointSize exceed the maximum");
232            return std::nullopt;
233        }
234        pattern.events.emplace_back(event);
235        for (int32_t j = 0; j < pointSize; ++j) {
236            VibrateCurvePoint point;
237            if (!data.ReadInt32(point.time)) {
238                MISC_HILOGE("Read points's time failed");
239                return std::nullopt;
240            }
241            if (!data.ReadInt32(point.intensity)) {
242                MISC_HILOGE("Read points's intensity failed");
243                return std::nullopt;
244            }
245            if (!data.ReadInt32(point.frequency)) {
246                MISC_HILOGE("Read points's frequency failed");
247                return std::nullopt;
248            }
249            pattern.events[i].points.emplace_back(point);
250        }
251    }
252    return pattern;
253}
254
255void VibrateParameter::Dump() const
256{
257    MISC_HILOGI("intensity:%{public}d, frequency:%{public}d", intensity, frequency);
258}
259
260bool VibrateParameter::Marshalling(Parcel &parcel) const
261{
262    if (!parcel.WriteInt32(intensity)) {
263        MISC_HILOGE("Write parameter's intensity failed");
264        return false;
265    }
266    if (!parcel.WriteInt32(frequency)) {
267        MISC_HILOGE("Write parameter's frequency failed");
268        return false;
269    }
270    return true;
271}
272
273std::optional<VibrateParameter> VibrateParameter::Unmarshalling(Parcel &data)
274{
275    VibrateParameter parameter;
276    if (!(data.ReadInt32(parameter.intensity))) {
277        MISC_HILOGE("Read parameter's intensity failed");
278        return std::nullopt;
279    }
280    if (!(data.ReadInt32(parameter.frequency))) {
281        MISC_HILOGE("Read parameter's frequency failed");
282        return std::nullopt;
283    }
284    return parameter;
285}
286} // namespace Sensors
287} // namespace OHOS
288