1 /*
2  * Copyright (c) 2021-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_agent.h"
16 
17 #include "parameters.h"
18 
19 #include "sensors_errors.h"
20 #include "vibrator_service_client.h"
21 
22 #undef LOG_TAG
23 #define LOG_TAG "VibratorNDK"
24 
25 namespace OHOS {
26 namespace Sensors {
27 using OHOS::Sensors::VibratorServiceClient;
28 
29 namespace {
30 constexpr int32_t DEFAULT_VIBRATOR_ID = 123;
31 int32_t g_loopCount = 1;
32 int32_t g_usage = USAGE_UNKNOWN;
33 bool g_systemUsage = false;
34 VibratorParameter g_vibratorParameter;
35 const std::string PHONE_TYPE = "phone";
36 const int32_t INTENSITY_ADJUST_MIN = 0;
37 const int32_t INTENSITY_ADJUST_MAX = 100;
38 const int32_t FREQUENCY_ADJUST_MIN = -100;
39 const int32_t FREQUENCY_ADJUST_MAX = 100;
40 } // namespace
41 
NormalizeErrCode(int32_t code)42 static int32_t NormalizeErrCode(int32_t code)
43 {
44     switch (code) {
45         case PERMISSION_DENIED: {
46             return PERMISSION_DENIED;
47         }
48         case PARAMETER_ERROR: {
49             return PARAMETER_ERROR;
50         }
51         case IS_NOT_SUPPORTED: {
52             return IS_NOT_SUPPORTED;
53         }
54         default: {
55             return DEVICE_OPERATION_FAILED;
56         }
57     }
58 }
59 
SetLoopCount(int32_t count)60 bool SetLoopCount(int32_t count)
61 {
62     if (count <= 0) {
63         MISC_HILOGE("Input invalid, count is %{public}d", count);
64         return false;
65     }
66     g_loopCount = count;
67     return true;
68 }
69 
StartVibrator(const char * effectId)70 int32_t StartVibrator(const char *effectId)
71 {
72     MISC_HILOGD("Time delay measurement:start time");
73     CHKPR(effectId, PARAMETER_ERROR);
74     auto &client = VibratorServiceClient::GetInstance();
75     int32_t ret = client.Vibrate(DEFAULT_VIBRATOR_ID, effectId, g_loopCount, g_usage, g_systemUsage);
76     g_loopCount = 1;
77     g_usage = USAGE_UNKNOWN;
78     g_systemUsage = false;
79     if (ret != ERR_OK) {
80         MISC_HILOGD("Vibrate effectId failed, ret:%{public}d", ret);
81         return NormalizeErrCode(ret);
82     }
83     return SUCCESS;
84 }
85 
StartVibratorOnce(int32_t duration)86 int32_t StartVibratorOnce(int32_t duration)
87 {
88     if (duration <= 0) {
89         MISC_HILOGE("duration is invalid");
90         return PARAMETER_ERROR;
91     }
92     auto &client = VibratorServiceClient::GetInstance();
93     int32_t ret = client.Vibrate(DEFAULT_VIBRATOR_ID, duration, g_usage, g_systemUsage);
94     g_usage = USAGE_UNKNOWN;
95     g_systemUsage = false;
96     if (ret != ERR_OK) {
97         MISC_HILOGD("Vibrate duration failed, ret:%{public}d", ret);
98         return NormalizeErrCode(ret);
99     }
100     return SUCCESS;
101 }
102 
IsSupportVibratorCustom()103 bool IsSupportVibratorCustom()
104 {
105     auto &client = VibratorServiceClient::GetInstance();
106     return client.IsSupportVibratorCustom();
107 }
108 
PlayVibratorCustom(int32_t fd,int64_t offset,int64_t length)109 int32_t PlayVibratorCustom(int32_t fd, int64_t offset, int64_t length)
110 {
111 #ifdef OHOS_BUILD_ENABLE_VIBRATOR_CUSTOM
112     MISC_HILOGD("Time delay measurement:start time");
113     if (fd < 0 || offset < 0 || length <= 0) {
114         MISC_HILOGE("Input parameter invalid, fd:%{public}d, offset:%{public}lld, length:%{public}lld",
115             fd, static_cast<long long>(offset), static_cast<long long>(length));
116         return PARAMETER_ERROR;
117     }
118     auto &client = VibratorServiceClient::GetInstance();
119     RawFileDescriptor rawFd = {
120         .fd = fd,
121         .offset = offset,
122         .length = length
123     };
124     int32_t ret = client.PlayVibratorCustom(DEFAULT_VIBRATOR_ID, rawFd, g_usage, g_systemUsage, g_vibratorParameter);
125     g_usage = USAGE_UNKNOWN;
126     g_systemUsage = false;
127     g_vibratorParameter.intensity = INTENSITY_ADJUST_MAX;
128     g_vibratorParameter.frequency = 0;
129     if (ret != ERR_OK) {
130         MISC_HILOGD("PlayVibratorCustom failed, ret:%{public}d", ret);
131         return NormalizeErrCode(ret);
132     }
133     return SUCCESS;
134 #else
135     MISC_HILOGE("The device does not support this operation");
136     return IS_NOT_SUPPORTED;
137 #endif // OHOS_BUILD_ENABLE_VIBRATOR_CUSTOM
138 }
139 
StopVibrator(const char * mode)140 int32_t StopVibrator(const char *mode)
141 {
142     CHKPR(mode, PARAMETER_ERROR);
143     if (strcmp(mode, "time") != 0 && strcmp(mode, "preset") != 0) {
144         MISC_HILOGE("Input parameter invalid, mode is %{public}s", mode);
145         return PARAMETER_ERROR;
146     }
147     auto &client = VibratorServiceClient::GetInstance();
148     int32_t ret = client.StopVibrator(DEFAULT_VIBRATOR_ID, mode);
149     if (ret != ERR_OK) {
150         MISC_HILOGD("StopVibrator by mode failed, ret:%{public}d, mode:%{public}s", ret, mode);
151         return NormalizeErrCode(ret);
152     }
153     return SUCCESS;
154 }
155 
Cancel()156 int32_t Cancel()
157 {
158     auto &client = VibratorServiceClient::GetInstance();
159     int32_t ret = client.StopVibrator(DEFAULT_VIBRATOR_ID);
160     if (ret != ERR_OK) {
161         MISC_HILOGD("StopVibrator failed, ret:%{public}d", ret);
162         return NormalizeErrCode(ret);
163     }
164     return SUCCESS;
165 }
166 
SetUsage(int32_t usage,bool systemUsage)167 bool SetUsage(int32_t usage, bool systemUsage)
168 {
169     if ((usage < 0) || (usage >= USAGE_MAX)) {
170         MISC_HILOGE("Input invalid, usage is %{public}d", usage);
171         return false;
172     }
173     g_usage = usage;
174     g_systemUsage = systemUsage;
175     return true;
176 }
177 
IsHdHapticSupported()178 bool IsHdHapticSupported()
179 {
180     auto &client = VibratorServiceClient::GetInstance();
181     return client.IsHdHapticSupported();
182 }
183 
IsSupportEffect(const char * effectId,bool * state)184 int32_t IsSupportEffect(const char *effectId, bool *state)
185 {
186     CHKPR(effectId, PARAMETER_ERROR);
187     auto &client = VibratorServiceClient::GetInstance();
188     int32_t ret = client.IsSupportEffect(effectId, *state);
189     if (ret != ERR_OK) {
190         MISC_HILOGD("Query effect support failed, ret:%{public}d, effectId:%{public}s", ret, effectId);
191         return NormalizeErrCode(ret);
192     }
193     return SUCCESS;
194 }
195 
PreProcess(const VibratorFileDescription & fd,VibratorPackage & package)196 int32_t PreProcess(const VibratorFileDescription &fd, VibratorPackage &package)
197 {
198     auto &client = VibratorServiceClient::GetInstance();
199     int32_t ret = client.PreProcess(fd, package);
200     if (ret != ERR_OK) {
201         MISC_HILOGD("DecodeVibratorFile failed, ret:%{public}d", ret);
202         return NormalizeErrCode(ret);
203     }
204     return SUCCESS;
205 }
206 
GetDelayTime(int32_t & delayTime)207 int32_t GetDelayTime(int32_t &delayTime)
208 {
209     auto &client = VibratorServiceClient::GetInstance();
210     int32_t ret = client.GetDelayTime(delayTime);
211     if (ret != ERR_OK) {
212         MISC_HILOGD("GetDelayTime failed, ret:%{public}d", ret);
213         return NormalizeErrCode(ret);
214     }
215     return SUCCESS;
216 }
217 
PlayPattern(const VibratorPattern & pattern)218 int32_t PlayPattern(const VibratorPattern &pattern)
219 {
220     auto &client = VibratorServiceClient::GetInstance();
221     int32_t ret = client.PlayPattern(pattern, g_usage, g_systemUsage, g_vibratorParameter);
222     g_usage = USAGE_UNKNOWN;
223     g_systemUsage = false;
224     g_vibratorParameter.intensity = INTENSITY_ADJUST_MAX;
225     g_vibratorParameter.frequency = 0;
226     if (ret != ERR_OK) {
227         MISC_HILOGD("PlayPattern failed, ret:%{public}d", ret);
228         return NormalizeErrCode(ret);
229     }
230     return SUCCESS;
231 }
232 
FreeVibratorPackage(VibratorPackage & package)233 int32_t FreeVibratorPackage(VibratorPackage &package)
234 {
235     auto &client = VibratorServiceClient::GetInstance();
236     int32_t ret = client.FreeVibratorPackage(package);
237     if (ret != ERR_OK) {
238         MISC_HILOGD("FreeVibratorPackage failed, ret:%{public}d", ret);
239         return NormalizeErrCode(ret);
240     }
241     return SUCCESS;
242 }
243 
SetParameters(const VibratorParameter & parameter)244 bool SetParameters(const VibratorParameter &parameter)
245 {
246     if ((parameter.intensity < INTENSITY_ADJUST_MIN) || (parameter.intensity > INTENSITY_ADJUST_MAX) ||
247         (parameter.frequency < FREQUENCY_ADJUST_MIN) || (parameter.frequency > FREQUENCY_ADJUST_MAX)) {
248         MISC_HILOGE("Input invalid, intensity parameter is %{public}d, frequency parameter is %{public}d",
249             parameter.intensity, parameter.frequency);
250         return false;
251     }
252     g_vibratorParameter = parameter;
253     return true;
254 }
255 
PlayPrimitiveEffect(const char * effectId,int32_t intensity)256 int32_t PlayPrimitiveEffect(const char *effectId, int32_t intensity)
257 {
258     MISC_HILOGD("Time delay measurement:start time");
259     CHKPR(effectId, PARAMETER_ERROR);
260     auto &client = VibratorServiceClient::GetInstance();
261     int32_t ret = client.PlayPrimitiveEffect(DEFAULT_VIBRATOR_ID, effectId, intensity,
262         g_usage, g_systemUsage, g_loopCount);
263     g_loopCount = 1;
264     g_usage = USAGE_UNKNOWN;
265     g_systemUsage = false;
266     if (ret != ERR_OK) {
267         MISC_HILOGD("Play primitive effect failed, ret:%{public}d", ret);
268         return NormalizeErrCode(ret);
269     }
270     return SUCCESS;
271 }
272 }  // namespace Sensors
273 }  // namespace OHOS