3 * Copyright (c) 2012 Samsung Electronics Co., Ltd.
5 * Licensed under the Apache License, Version 2.0 (the License);
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
29 #include "feedback-ids.h"
36 #include "feedback-ids-mobile.h"
39 #include "feedback-ids-wearable.h"
42 #define HAPTIC_DEVICE 0
44 enum haptic_priority {
45 HAPTIC_PRIORITY_MIN = 0,
46 HAPTIC_PRIORITY_MIDDLE,
50 enum haptic_iteration {
51 HAPTIC_ITERATION_ONCE = 1,
52 HAPTIC_ITERATION_INFINITE = 256,
55 #define VIBRATION_CONF_FILE "/usr/share/feedback/vibration.conf"
57 #define METHOD_OPEN "OpenDevice"
58 #define METHOD_CLOSE "CloseDevice"
59 #define METHOD_VIBRATE_MONOTONE "VibrateMonotone"
60 #define METHOD_VIBRATE_BUFFER "VibrateBuffer"
61 #define METHOD_STOP "StopDevice"
63 #define DEFAULT_DURATION 100
64 #define SIP_DURATION 60
67 static unsigned int v_handle;
68 static struct feedback_config_info vib_info = {
72 static char *get_data(feedback_pattern_e pattern)
76 if (pattern <= FEEDBACK_PATTERN_NONE ||
77 pattern >= profile->max_pattern)
80 if (vib_info.data[pattern].changed)
81 data = vib_info.data[pattern].changed;
83 data = vib_info.data[pattern].origin;
88 inline int is_vibration_mode(void)
93 static int haptic_open(void)
98 snprintf(buf_index, sizeof(buf_index), "%d", HAPTIC_DEVICE);
101 return dbus_method_sync(DEVICED_BUS_NAME, DEVICED_PATH_HAPTIC,
102 DEVICED_INTERFACE_HAPTIC, METHOD_OPEN,
106 static int haptic_close(unsigned int handle)
111 snprintf(buf_handle, sizeof(buf_handle), "%u", handle);
114 return dbus_method_sync(DEVICED_BUS_NAME, DEVICED_PATH_HAPTIC,
115 DEVICED_INTERFACE_HAPTIC, METHOD_CLOSE,
119 static int haptic_vibrate_buffer(unsigned int handle,
120 const unsigned char *buffer,
128 char buf_iteration[32];
129 char buf_feedback[32];
130 char buf_priority[32];
131 struct dbus_byte bytes;
133 snprintf(buf_handle, sizeof(buf_handle), "%u", handle);
137 arr[2] = (char *)&bytes;
138 snprintf(buf_iteration, sizeof(buf_iteration), "%d", iteration);
139 arr[3] = buf_iteration;
140 snprintf(buf_feedback, sizeof(buf_feedback), "%d", feedback);
141 arr[4] = buf_feedback;
142 snprintf(buf_priority, sizeof(buf_priority), "%d", priority);
143 arr[5] = buf_priority;
145 return dbus_method_sync(DEVICED_BUS_NAME, DEVICED_PATH_HAPTIC,
146 DEVICED_INTERFACE_HAPTIC, METHOD_VIBRATE_BUFFER,
150 static int haptic_vibrate_monotone(unsigned int handle,
157 char buf_duration[32];
158 char buf_feedback[32];
159 char buf_priority[32];
161 snprintf(buf_handle, sizeof(buf_handle), "%u", handle);
163 snprintf(buf_duration, sizeof(buf_duration), "%d", duration);
164 arr[1] = buf_duration;
165 snprintf(buf_feedback, sizeof(buf_feedback), "%d", feedback);
166 arr[2] = buf_feedback;
167 snprintf(buf_priority, sizeof(buf_priority), "%d", priority);
168 arr[3] = buf_priority;
170 return dbus_method_sync(DEVICED_BUS_NAME, DEVICED_PATH_HAPTIC,
171 DEVICED_INTERFACE_HAPTIC, METHOD_VIBRATE_MONOTONE,
175 static int haptic_vibrate_stop(unsigned int handle)
180 snprintf(buf_handle, sizeof(buf_handle), "%u", handle);
183 return dbus_method_sync(DEVICED_BUS_NAME, DEVICED_PATH_HAPTIC,
184 DEVICED_INTERFACE_HAPTIC, METHOD_STOP,
188 static unsigned char *convert_file_to_buffer(const char *file_name, int *size)
192 unsigned char *pdata = NULL;
197 /* Get File Stream Pointer */
198 pf = fopen(file_name, "rb");
200 _E("fopen failed : %s", strerror(errno));
204 if (fseek(pf, 0, SEEK_END))
207 file_size = ftell(pf);
208 if (fseek(pf, 0, SEEK_SET))
214 pdata = (unsigned char *)malloc(file_size);
218 if (fread(pdata, 1, file_size, pf) != file_size)
231 _E("failed to convert file to buffer (%s)", strerror(errno));
235 static int get_priority(feedback_pattern_e pattern)
237 if (pattern >= FEEDBACK_PATTERN_TAP && pattern <= FEEDBACK_PATTERN_HW_HOLD)
238 return HAPTIC_PRIORITY_MIN;
240 return HAPTIC_PRIORITY_MIDDLE;
243 static int get_duration(feedback_pattern_e pattern)
245 if (pattern == FEEDBACK_PATTERN_SIP)
248 if (pattern == (feedback_pattern_e)FEEDBACK_PATTERN_MOBILE_SIP_BACKSPACE)
252 if (pattern == (feedback_pattern_e)FEEDBACK_PATTERN_WEARABLE_SIP_BACKSPACE)
255 return DEFAULT_DURATION;
258 static void vibrator_init(void)
265 _E("haptic_open ==> FAIL!! : %d", ret);
270 /* Set vibration handle */
271 v_handle = (unsigned int)ret;
273 /* get vibration data */
274 feedback_load_config(VIBRATION_CONF_FILE, &vib_info);
277 static void vibrator_exit(void)
282 ret = haptic_close(v_handle);
284 _E("haptic_close is failed : %d", ret);
288 /* free vibration data */
289 feedback_free_config(&vib_info);
292 static int vibrator_play(feedback_pattern_e pattern)
303 _E("Not initialize");
307 if (v_handle == -ENOTSUP) {
308 _E("Not supported vibration");
312 if (vconf_get_bool(VCONFKEY_SETAPPL_VIBRATION_STATUS_BOOL, &vibstatus) < 0) {
313 _D("fail to get vibration status, will work as turning off");
317 if (vibstatus == 0 && profile->get_always_alert_case &&
318 !profile->get_always_alert_case(FEEDBACK_TYPE_VIBRATION, pattern)) {
319 _D("Vibration condition is OFF (vibstatus : %d)", vibstatus);
323 if (vibstatus && profile->get_always_off_case &&
324 profile->get_always_off_case(FEEDBACK_TYPE_VIBRATION, pattern)) {
325 _D("Vibration always off condition");
329 if (profile->get_strength_type)
330 level = profile->get_strength_type(FEEDBACK_TYPE_VIBRATION, pattern);
332 level = DEFAULT_VIB_LEVEL * HAPTIC_FEEDBACK_STEP;
334 /* get vibration data */
335 data = get_data(pattern);
337 _E("Not supported vibration pattern");
341 /* if it has a file path */
342 if (!stat(data, &buf)) {
343 pbuf = convert_file_to_buffer(data, &size);
345 _E("fail to convert file to buffer");
349 ret = haptic_vibrate_buffer(v_handle, pbuf, size,
350 HAPTIC_ITERATION_ONCE,
351 level, get_priority(pattern));
354 duration = get_duration(pattern);
355 ret = haptic_vibrate_monotone(v_handle, duration,
356 level, get_priority(pattern));
360 _E("fail to play vibration");
366 _D("Play success! Data is %s", data);
370 static int vibrator_stop(void)
375 _E("Not initialize");
379 if (v_handle == -ENOTSUP) {
380 _E("Not supported vibration");
384 /* stop haptic device */
385 ret = haptic_vibrate_stop(v_handle);
387 _E("haptic_vibrate_stop is failed");
396 static int vibrator_is_supported(int pattern, bool *supported)
402 _E("Invalid parameter : supported(NULL)");
407 _E("Not initialize");
411 if (v_handle == -ENOTSUP) {
412 _E("Not supported vibration");
417 /* get vibration data */
418 data = get_data(pattern);
420 _E("Not supported vibration pattern");
428 static int vibrator_get_path(feedback_pattern_e pattern, char *buf, unsigned int buflen)
433 if (!buf || buflen <= 0)
436 /* get vibration data */
437 data = get_data(pattern);
439 _E("This pattern(%s) in vibrator type is not supported to play",
440 profile->str_pattern[pattern]);
445 snprintf(buf, buflen, "%s", data);
449 static int vibrator_set_path(feedback_pattern_e pattern, char *path)
454 * check the path is valid
455 * if path is null, reset vibration path
458 if (vib_info.data[pattern].changed) {
459 free(vib_info.data[pattern].changed);
460 vib_info.data[pattern].changed = NULL;
465 if (path && stat(path, &buf)) {
466 _E("%s is not presents", path);
470 if (vib_info.data[pattern].changed) {
471 free(vib_info.data[pattern].changed);
472 vib_info.data[pattern].changed = NULL;
475 /* if path is NULL, this pattern set to default file */
477 vib_info.data[pattern].changed = strdup(path);
479 _D("The file of pattern(%s) is changed to [%s]",
480 profile->str_pattern[pattern], path);
484 static const struct device_ops vibrator_device_ops = {
485 .type = FEEDBACK_TYPE_VIBRATION,
487 .init = vibrator_init,
488 .exit = vibrator_exit,
489 .play = vibrator_play,
490 .stop = vibrator_stop,
491 .is_supported = vibrator_is_supported,
492 .get_path = vibrator_get_path,
493 .set_path = vibrator_set_path,
496 DEVICE_OPS_REGISTER(&vibrator_device_ops);