1 /*
2 * Copyright (c) 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
16 #include "vibrator_ffi.h"
17
18 #include <map>
19 #include <set>
20 #include <string>
21
22 #include "file_utils.h"
23 #include "miscdevice_log.h"
24 #include "sensors_errors.h"
25 #include "vibrator_agent.h"
26
27 #undef LOG_TAG
28 #define LOG_TAG "Vibrator-Cj"
29
30 namespace OHOS {
31 namespace Sensors {
32 static std::map<std::string, int32_t> g_usageType = {
33 {"unknown", USAGE_UNKNOWN},
34 {"alarm", USAGE_ALARM},
35 {"ring", USAGE_RING},
36 {"notification", USAGE_NOTIFICATION},
37 {"communication", USAGE_COMMUNICATION},
38 {"touch", USAGE_TOUCH},
39 {"media", USAGE_MEDIA},
40 {"physicalFeedback", USAGE_PHYSICAL_FEEDBACK},
41 {"simulateReality", USAGE_SIMULATE_REALITY},
42 };
43
44 static std::set<std::string> g_allowedTypes = {"time", "preset", "file", "pattern"};
45 struct CJVibrateInfo {
46 std::string type;
47 std::string usage;
48 bool systemUsage;
49 int32_t duration = 0;
50 std::string effectId;
51 int32_t count = 0;
52 int32_t fd = -1;
53 int64_t offset = 0;
54 int64_t length = -1;
55 int32_t intensity = 0;
56 VibratorPattern vibratorPattern;
57 };
58
SetUsage(const std::string &usage, bool systemUsage)59 bool SetUsage(const std::string &usage, bool systemUsage)
60 {
61 if (auto iter = g_usageType.find(usage); iter == g_usageType.end()) {
62 MISC_HILOGE("Wrong usage type");
63 return false;
64 }
65 return SetUsage(g_usageType[usage], systemUsage);
66 }
67
StartVibrate(const CJVibrateInfo &info)68 int32_t StartVibrate(const CJVibrateInfo &info)
69 {
70 CALL_LOG_ENTER;
71 if (!SetUsage(info.usage, info.systemUsage)) {
72 MISC_HILOGE("SetUsage fail");
73 return PARAMETER_ERROR;
74 }
75 if (g_allowedTypes.find(info.type) == g_allowedTypes.end()) {
76 MISC_HILOGE("Invalid vibrate type, type:%{public}s", info.type.c_str());
77 return PARAMETER_ERROR;
78 }
79 if (info.type == "preset") {
80 if (!SetLoopCount(info.count)) {
81 MISC_HILOGE("SetLoopCount fail");
82 return PARAMETER_ERROR;
83 }
84 return PlayPrimitiveEffect(info.effectId.c_str(), info.intensity);
85 } else if (info.type == "file") {
86 return PlayVibratorCustom(info.fd, info.offset, info.length);
87 } else if (info.type == "pattern") {
88 return PlayPattern(info.vibratorPattern);
89 }
90 return StartVibratorOnce(info.duration);
91 }
92
93 extern "C" {
FfiVibratorStartVibrationTime(RetVibrateTime effect, RetVibrateAttribute attribute, int32_t &code)94 void FfiVibratorStartVibrationTime(RetVibrateTime effect, RetVibrateAttribute attribute, int32_t &code)
95 {
96 CJVibrateInfo info;
97 std::string strType(effect.timeType);
98 info.type = strType;
99 info.duration = effect.duration;
100 std::string strUsage(attribute.usage);
101 info.usage = strUsage;
102 info.systemUsage = false;
103 code = StartVibrate(info);
104 };
105
FfiVibratorStartVibrationPreset(RetVibratePreset effect, RetVibrateAttribute attribute, int32_t &code)106 void FfiVibratorStartVibrationPreset(RetVibratePreset effect, RetVibrateAttribute attribute, int32_t &code)
107 {
108 CJVibrateInfo info;
109 std::string strType(effect.presetType);
110 info.type = strType;
111 std::string strEffectId(effect.effectId);
112 info.effectId = strEffectId;
113 info.count = effect.count;
114 info.intensity = effect.intensity;
115 std::string strUsage(attribute.usage);
116 info.usage = strUsage;
117 info.systemUsage = false;
118 code = StartVibrate(info);
119 };
120
FfiVibratorStartVibrationFile(RetVibrateFromFile effect, RetVibrateAttribute attribute, int32_t &code)121 void FfiVibratorStartVibrationFile(RetVibrateFromFile effect, RetVibrateAttribute attribute, int32_t &code)
122 {
123 CJVibrateInfo info;
124 std::string strType(effect.fileType);
125 info.type = strType;
126 info.fd = effect.hapticFd.fd;
127 info.offset = effect.hapticFd.offSet;
128 info.length = effect.hapticFd.length;
129 std::string strUsage(attribute.usage);
130 info.usage = strUsage;
131 info.systemUsage = false;
132 code = StartVibrate(info);
133 };
134
FfiVibratorStopVibration(int32_t &code)135 void FfiVibratorStopVibration(int32_t &code)
136 {
137 code = Cancel();
138 }
139
FfiVibratorStopVibrationMode(char* vibMode, int32_t &code)140 void FfiVibratorStopVibrationMode(char* vibMode, int32_t &code)
141 {
142 if (vibMode == nullptr) {
143 code = PARAMETER_ERROR;
144 return;
145 }
146 if (strcmp(vibMode, "time") != 0 && strcmp(vibMode, "preset") != 0) {
147 code = PARAMETER_ERROR;
148 return;
149 }
150 std::string mode(vibMode);
151 code = StopVibrator(mode.c_str());
152 }
153
FfiVibratorSupportEffect(char* id, int32_t &code)154 bool FfiVibratorSupportEffect(char* id, int32_t &code)
155 {
156 bool isSupportEffect = false;
157 if (id == nullptr) {
158 code = PARAMETER_ERROR;
159 return isSupportEffect;
160 }
161 if (strcmp(id, "haptic.clock.timer") != 0) {
162 code = PARAMETER_ERROR;
163 return isSupportEffect;
164 }
165 std::string effectId(id);
166 code = IsSupportEffect(effectId.c_str(), &isSupportEffect);
167 return isSupportEffect;
168 }
169
FfiVibratorIsHdHapticSupported()170 bool FfiVibratorIsHdHapticSupported()
171 {
172 return IsHdHapticSupported();
173 }
174 }
175 }
176 }