Change function name
[platform/core/system/feedbackd.git] / src / haptic / haptic.c
1 /*
2  * feedbackd
3  *
4  * Copyright (c) 2012 - 2017 Samsung Electronics Co., Ltd.
5  *
6  * Licensed under the Apache License, Version 2.0 (the License);
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18
19
20 #include <stdio.h>
21 #include <stdbool.h>
22 #include <dlfcn.h>
23 #include <assert.h>
24 #include <vconf.h>
25 #include <time.h>
26 #include <string.h>
27 #include <libsyscommon/dbus-system.h>
28
29 #include "core/log.h"
30 #include "core/list.h"
31 #include "core/common.h"
32 #include "core/device-idler.h"
33 #include "core/config-parser.h"
34 #include "haptic.h"
35
36 #define FEEDBACK_BASE_PATH         "/usr/share/feedback/"
37 #define STANDARD_FILE_PATH         FEEDBACK_BASE_PATH"vibration/"
38 #define VIBRATION_CONF_PATH        FEEDBACK_BASE_PATH"vibration.conf"
39
40 #define HAPTIC_CONF_PATH                "/etc/feedbackd/haptic.conf"
41 #define SIGNAL_POWEROFF_STATE           "ChangeState"
42 #define SIGNAL_VIBRATOR_INITIATED       "InitiateVibrator"
43
44 /* hardkey vibration variable */
45 #define HARDKEY_VIB_ITERATION           1
46 #define HARDKEY_VIB_FEEDBACK            3
47 #define HARDKEY_VIB_DURATION            30
48 #define HAPTIC_FEEDBACK_STEP            20
49 #define DEFAULT_FEEDBACK_LEVEL          3
50 #define HIGH_FEEDBACK_LEVEL             100
51 #define LOW_FEEDBACK_LEVEL              0
52
53 /* power on, power off vibration variable */
54 #define POWER_ON_VIB_DURATION                   300
55 #define POWER_OFF_VIB_DURATION                  300
56 #define POWER_VIB_FEEDBACK                      100
57
58 #define MAX_EFFECT_BUFFER                       (64*1024)
59
60 #ifndef VCONFKEY_RECORDER_STATE
61 #define VCONFKEY_RECORDER_STATE "memory/recorder/state"
62 #define VCONFKEY_RECORDER_STATE_RECORDING       2
63 #endif
64
65 #define CHECK_VALID_OPS(ops, r)         ((ops) ? true : !(r = -ENODEV))
66 #define RETRY_CNT       3
67
68 #define INTENSITY_BASE_RATE        (10000)
69 #define VALUE_MAX_LEN              10
70 #define VIB_LOCK_TIMEOUT_MAX       (300000) /* 5minutes */
71
72 /*
73                 1,A_W or A,A_W or 250D250W250D750W
74
75                 85,10000,
76                 90,0,
77                 105,10000,
78                 0,end
79 */
80 struct vibration_config {
81         char *pattern; /* pattern name */
82         char *standard; /* assigned standard pattern name */
83         dd_list *data; /* duration_data list */
84         unsigned int pattern_duration;
85         int unlimit;
86 };
87
88 struct duration_data {
89         int duration;
90         int intensity;
91         int frequency;
92         int overdrive;
93         int wait;
94 };
95
96 enum poweroff_type {
97         POWER_OFF_NONE = 0,
98         POWER_OFF_POPUP,
99         POWER_OFF_DIRECT,
100         POWER_OFF_RESTART,
101 };
102
103 struct haptic_info {
104         char *sender;
105         dd_list *handle_list;
106         guint id_watch;
107 };
108
109 struct vibrate_pattern_info {
110         unsigned int handle;
111         char *pattern;
112         int level;
113         int priority;
114 };
115
116 struct vibrate_monotone_info {
117         unsigned int handle;
118         int duration;
119         int level;
120         int intensity;
121         int priority;
122 };
123
124 /* for playing */
125 static int g_handle;
126
127 /* pattern configuration list */
128 static dd_list *vib_conf_list;
129
130 static guint duration_timer;
131
132 /* haptic operation variable */
133 static dd_list *h_head;
134 static dd_list *haptic_handle_list;
135 static const struct haptic_plugin_ops *h_ops;
136 static enum haptic_type h_type;
137 static bool haptic_disabled;
138
139 struct haptic_config {
140         int level;
141         int *level_arr;
142         int sound_capture;
143 };
144
145 static struct haptic_config haptic_conf;
146
147 static int haptic_start(void);
148 static int haptic_stop(void);
149 static int haptic_internal_init(void);
150 static int remove_haptic_info(struct haptic_info *info);
151
152 struct haptic_data cur_h_data;
153
154 void add_haptic(const struct haptic_ops *ops)
155 {
156         DD_LIST_APPEND(h_head, (void *)ops);
157 }
158
159 void remove_haptic(const struct haptic_ops *ops)
160 {
161         DD_LIST_REMOVE(h_head, (void *)ops);
162 }
163
164 static int insert_conf_data(dd_list **conf_data, struct duration_data *update)
165 {
166         struct duration_data *data;
167
168         data = (struct duration_data *)calloc(1, sizeof(struct duration_data));
169         if (!data) {
170                 _E("Not enough memory.");
171                 return -ENOMEM;
172         }
173         memcpy(data, update, sizeof(struct duration_data));
174         /* insert vibration pattern data */
175         // to debug :
176         // _D("%dD%dI%dF%dO%dW", data->duration, data->intensity, data->frequency, data->overdrive, data->wait);
177         DD_LIST_APPEND(*conf_data, data);
178         return 0;
179 }
180
181 static void get_pattern_property(char **iter, char property, int *value)
182 {
183         char *check;
184         unsigned long int val;
185
186         check = strchr(*iter, property);
187         if (!check)
188                 return;
189
190         *check = '\0';
191         val = strtoul(*iter, NULL, 10);
192         if (errno == EINVAL || errno == ERANGE) {
193                 val = 0;
194                 _E("Failed to get value of %s: %d", *iter, errno);
195         }
196         if (val > VIB_LOCK_TIMEOUT_MAX)
197                 val = VIB_LOCK_TIMEOUT_MAX;
198
199         *value = (int)val;
200
201         *iter = check + 1;
202 }
203
204 /* [A]xxxDxxxIxxxFxxxOxxxW format */
205 static int insert_raw_data_format(dd_list **conf_data, char *value)
206 {
207         struct duration_data update = {0, };
208         char *iter;
209         char *end;
210         int pattern_duration = 0;
211
212         if (!value)
213                 return insert_conf_data(conf_data, &update);
214         if (!conf_data) {
215                 _E("Invalid parameter: Configuration list is null");
216                 return -EINVAL;
217         }
218
219         iter = value;
220         end = iter + strlen(iter);
221         while (iter < end) {
222                 memset(&update, 0, sizeof(struct duration_data));
223
224                 get_pattern_property(&iter, 'D', &update.duration);
225                 get_pattern_property(&iter, 'I', &update.intensity);
226                 if (update.intensity > INTENSITY_BASE_RATE)
227                         update.intensity = INTENSITY_BASE_RATE;
228                 get_pattern_property(&iter, 'F', &update.frequency);
229                 get_pattern_property(&iter, 'W', &update.wait);
230
231                 if (update.duration == 0 && update.wait == 0) {
232                         _D("Pattern duration is zero.");
233                         break;
234                 }
235
236                 pattern_duration += (update.duration + update.wait);
237                 if (pattern_duration > VIB_LOCK_TIMEOUT_MAX) {
238                         _D("Max pattern duration.");
239                         pattern_duration = VIB_LOCK_TIMEOUT_MAX;
240                 }
241
242                 if (insert_conf_data(conf_data, &update) < 0)
243                         return -EINVAL;
244         }
245
246         return pattern_duration;
247 }
248
249 static int get_config_data(int count, bool *packed, char *val, unsigned int *pattern_duration, struct duration_data *update)
250 {
251         static int duration = 0;
252         static int intensity = 0;
253         int value;
254         int ret;
255
256         if (count > 4 || count <= 0) {
257                 _E("Invalid parameter: count is invalid");
258                 return -EINVAL;
259         }
260
261         if (!packed || !val || !pattern_duration || !update) {
262                 _E("Invalid parameter: %p %p %p %p", packed, val, pattern_duration, update);
263                 return -EINVAL;
264         }
265
266         get_pattern_property(&val, 'C', &value);
267
268         ret = count;
269         switch (count) {
270         case 1: /* D */
271                 duration = value;
272                 *pattern_duration += duration;
273                 if (*pattern_duration > VIB_LOCK_TIMEOUT_MAX) {
274                         _D("Max pattern duration.");
275                         *pattern_duration = VIB_LOCK_TIMEOUT_MAX;
276                 }
277                 break;
278         case 2: /* I or W */
279                 if (value > INTENSITY_BASE_RATE)
280                         value = INTENSITY_BASE_RATE;
281                 intensity = value;
282                 if (*packed == false) {
283                         update->duration = duration;
284                         update->intensity = intensity;
285                         break;
286                 }
287                  /* if intensity is 0, duration use for wait(off) time */
288                 if (intensity == 0)
289                         update->wait = duration;
290                 else
291                         update->wait = 0;
292                 *packed = false;
293                 duration = 0;
294                 intensity = 0;
295                 ret = -1;
296                 break;
297         case 3: /* F */
298                 if (intensity != 0)
299                         update->frequency = value;
300                 break;
301         case 4:  /* O */
302                 if (intensity != 0) {
303                         update->overdrive = value;
304                         *packed = true;
305                 }
306                 ret = 0;
307                 break;
308         default:
309                 break;
310         }
311         return ret;
312 }
313
314 /*
315         duration, intensity, frequency, overdrive
316         waiting duration, intensity=0, frequency, overdrive
317         85,10000,
318         90,0,
319         105,10000,
320         0,end
321 */
322 static int load_standard_format(const char *pattern)
323 {
324         struct duration_data update = {0, };
325         bool packed = false;
326         struct vibration_config *conf;
327         int ret = 0, count = 0, end = 2;
328         int index = 0;
329         int fd;
330         char path[PATH_MAX], elem, val[VALUE_MAX_LEN] = {0, };
331
332         snprintf(path, sizeof(path), STANDARD_FILE_PATH"%s", pattern);
333         fd = open(path, O_RDONLY);
334         if (fd < 0)
335                 return -ENOENT;
336
337         conf = (struct vibration_config *)calloc(1, sizeof(struct vibration_config));
338         if (!conf) {
339                 _E("Failed to alloc.");
340                 ret = -errno;
341                 goto error_out;
342         }
343
344         conf->pattern = strdup(pattern);
345         if (!conf->pattern) {
346                 _E("Failed to copy pattern data(%s).", pattern);
347                 ret = -errno;
348                 goto error_out;
349         }
350
351         /* make feedback pattern(xDxIxFxOxW) format from d,i,f,o, */
352         while (read(fd, &elem, 1) != 0) {
353                 if (end == 0) {
354                         if (insert_conf_data(&conf->data, &update) < 0)
355                                 goto error_out;
356                         break;
357                 }
358                 if (elem == 'e' || elem == 'n' || elem == 'd') {
359                         end--;
360                         continue;
361                 }
362                 if (elem == '\n') {
363                         count = 0;
364                         continue;
365                 }
366                 if (elem == ',') {
367                         count++;
368                         val[index] = 'C';
369                         index = 0;
370
371                         ret = get_config_data(count, &packed, val, &(conf->pattern_duration), &update);
372                         if (ret < 0) {
373                                 if (ret == -EINVAL)
374                                         break;
375                                 if (insert_conf_data(&conf->data, &update) < 0)
376                                         goto error_out;
377                                 memset(&update, 0, sizeof(struct duration_data));
378                         } else
379                                 count = ret;
380                 } else {
381                         if (index < (VALUE_MAX_LEN - 2)) /* Temporal limit */
382                                 val[index++] = elem;
383                         else
384                                 _E("Pattern(%s) is out of bound: %s", pattern, val);
385                 }
386         }
387         close(fd);
388         DD_LIST_APPEND(vib_conf_list, conf);
389         return ret;
390
391 error_out:
392         if (fd >= 0)
393                 close(fd);
394         if (conf) {
395                 if (conf->pattern)
396                         free(conf->pattern);
397                 free(conf);
398         }
399         return -ENOENT;
400 }
401
402 static int vibration_load_config(struct parse_result *result, void *user_data)
403 {
404         struct vibration_config *conf;
405         char *value;
406         char *check;
407         int len;
408         int duration;
409
410         if (!result)
411                 return 0;
412
413         if (!MATCH(result->section, "Vibration"))
414                 return 0;
415
416
417         if (!result->name || !result->value)
418                 return 0;
419
420         conf = (struct vibration_config *)calloc(1, sizeof(struct vibration_config));
421         if (!conf) {
422                 _E("Failed to alloc.");
423                 return -ENOMEM;
424         }
425
426         conf->pattern_duration = 0;
427         conf->pattern = strdup(result->name);
428         if (!conf->pattern) {
429                 _E("Failed to copy pattern data(%s).", result->name);
430                 goto error_out;
431         }
432
433         value = result->value;
434         len = strlen(value);
435
436         if (len == 0) {
437                 if (insert_raw_data_format(&conf->data, NULL) < 0)
438                         goto error_out;
439                 DD_LIST_APPEND(vib_conf_list, conf);
440                 return 0;
441         }
442
443         /* Load Standard Pattern Name */
444         /* value: 1,A_W or A,A_W */
445         if ((check = strchr(value, ','))) {
446                 *check = '\0';
447                 if (strncmp(value, "A", 1) == 0)
448                         conf->unlimit = 1;
449                 value = check + 1;
450                 conf->standard = strdup(value);
451                 if (!conf->standard) {
452                         _E("Failed to copy standard name.");
453                         goto error_out;
454                 }
455                 DD_LIST_APPEND(vib_conf_list, conf);
456                 return 0;
457         }
458
459         /* value : A100D or 100D0W or 250D250W250D750W */
460         /* Load Vibration Pattern Data */
461         check = strchr(value, 'A');
462         if (check) {
463                 *check = '\0';
464                 conf->unlimit = 1;
465                 if (!value)
466                         len = len - 1;
467                 else
468                         len = len - strlen(value) - 1;
469                 value = check + 1;
470         }
471         duration = insert_raw_data_format(&conf->data, value);
472         if (duration < 0) {
473                 conf->pattern_duration = 0;
474                 goto error_out;
475         } else
476                 conf->pattern_duration = duration;
477         DD_LIST_APPEND(vib_conf_list, conf);
478
479         return 0;
480
481 error_out:
482         if (conf) {
483                 if (conf->pattern)
484                         free(conf->pattern);
485                 if (conf->standard)
486                         free(conf->standard);
487         }
488         return -ENOMEM;
489 }
490
491 static void load_standard_vibration_patterns(void)
492 {
493         DIR *dir;
494         struct dirent *dent;
495         int ret;
496
497         dir = opendir(STANDARD_FILE_PATH);
498         if (!dir) {
499                 _E("Failed to load '%s' Use default value.", STANDARD_FILE_PATH);
500                 return;
501         }
502         while ((dent = readdir(dir))) {
503                 if (dent->d_type == DT_DIR)
504                         continue;
505                 ret = load_standard_format(dent->d_name);
506                 if (ret < 0)
507                         _E("Failed to parse %s: %d", dent->d_name, ret);
508         }
509         closedir(dir);
510         _D("Success to load '%s'", STANDARD_FILE_PATH);
511 }
512
513 void pattern_config_parse(void)
514 {
515         int ret;
516
517         ret = config_parse(VIBRATION_CONF_PATH, vibration_load_config, NULL);
518         if (ret < 0)
519                 _E("Failed to load '%s'. Use default value: %d", VIBRATION_CONF_PATH, ret);
520
521         load_standard_vibration_patterns();
522 }
523
524 static int haptic_module_load(void)
525 {
526         struct haptic_ops *ops;
527         dd_list *elem;
528         int r;
529
530         pattern_config_parse();
531         /* find valid plugin */
532         DD_LIST_FOREACH(h_head, elem, ops) {
533                 if (ops->is_valid && ops->is_valid()) {
534                         if (ops->load)
535                                 h_ops = ops->load();
536                         h_type = ops->type;
537                         break;
538                 }
539         }
540
541         if (!CHECK_VALID_OPS(h_ops, r)) {
542                 _E("Can't find the valid haptic device.");
543                 return r;
544         }
545
546         /* solution bug
547          * we do not use internal vibration except power off.
548          * if the last handle is closed during the playing of vibration,
549          * solution makes unlimited vibration.
550          * so we need at least one handle. */
551         haptic_internal_init();
552
553         return 0;
554 }
555
556 /*
557 static int convert_magnitude_by_conf(int level)
558 {
559         int i, step;
560
561         if (level < LOW_FEEDBACK_LEVEL)
562                 level = LOW_FEEDBACK_LEVEL;
563         else if (level > HIGH_FEEDBACK_LEVEL)
564                 level = HIGH_FEEDBACK_LEVEL;
565
566         step = 100 / (haptic_conf.level-1);
567         for (i = 0; i < haptic_conf.level; ++i) {
568                 if (level <= i*step) {
569                         _D("Level changed. %d -> %d", level, haptic_conf.level_arr[i]);
570                         return haptic_conf.level_arr[i];
571                 }
572         }
573
574         _D("Play default level.");
575         return DEFAULT_FEEDBACK_LEVEL * HAPTIC_FEEDBACK_STEP;
576 }
577 */
578 GVariant *hdbus_get_count(GDBusConnection *conn,
579         const gchar *sender, const gchar *path, const gchar *iface, const gchar *name,
580         GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data)
581 {
582         int ret, val;
583
584         if (!CHECK_VALID_OPS(h_ops, ret))
585                 goto exit;
586
587         ret = h_ops->get_device_count(&val);
588         if (ret >= 0)
589                 ret = val;
590
591 exit:
592         return g_variant_new("(i)", ret);
593 }
594
595 void haptic_name_owner_changed(GDBusConnection *connection,
596         const gchar     *name,
597         gpointer         user_data)
598 {
599         dd_list *n;
600         struct haptic_info *info = user_data;
601         int handle;
602
603         _I("%s (sender=%s)", __func__, name);
604
605         if (!info)
606                 return;
607
608         for (n = info->handle_list; n; n = n->next) {
609                 handle = (int)(long)n->data;
610                 h_ops->stop_device(handle);
611                 h_ops->close_device(handle);
612         }
613
614         remove_haptic_info(info);
615 }
616
617 static struct haptic_info *add_haptic_info(const char *sender)
618 {
619         struct haptic_info *info;
620
621         assert(sender);
622
623         info = calloc(1, sizeof(struct haptic_info));
624         if (!info)
625                 return NULL;
626
627         info->sender = strdup(sender);
628         if (!info->sender) {
629                 free(info);
630                 return NULL;
631         }
632
633         DD_LIST_APPEND(haptic_handle_list, info);
634
635         info->id_watch = dbus_handle_watch_name(sender, NULL, haptic_name_owner_changed, info, NULL);
636
637         return info;
638 }
639
640 static int remove_haptic_info(struct haptic_info *info)
641 {
642         assert(info);
643
644         dbus_handle_unwatch_name(info->id_watch);
645
646         DD_LIST_REMOVE(haptic_handle_list, info);
647         DD_LIST_FREE_LIST(info->handle_list);
648         if (info->sender) {
649                 free(info->sender);
650         }
651         free(info);
652
653         return 0;
654 }
655
656 static struct haptic_info *get_matched_haptic_info(const char *sender)
657 {
658         dd_list *n;
659         struct haptic_info *info;
660         int len;
661
662         assert(sender);
663
664         len = strlen(sender) + 1;
665         DD_LIST_FOREACH(haptic_handle_list, n, info) {
666                 if (!strncmp(info->sender, sender, len))
667                         return info;
668         }
669
670         return NULL;
671 }
672
673 GVariant *hdbus_open_device(GDBusConnection *conn,
674                                                         const gchar *sender, const gchar *path, const gchar *iface, const gchar *name,
675                                                         GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data)
676
677 {
678         int index, handle, ret;
679         struct haptic_info *info;
680
681         /* Load haptic module before booting done */
682         if (!CHECK_VALID_OPS(h_ops, ret)) {
683                 ret = haptic_module_load();
684                 if (ret < 0)
685                         goto exit;
686         }
687
688         g_variant_get(param, "(i)", &index);
689
690         ret = h_ops->open_device(index, &handle);
691         if (ret < 0)
692                 goto exit;
693
694         if (!sender) {
695                 ret = -EPERM;
696                 h_ops->close_device(handle);
697                 goto exit;
698         }
699
700         info = get_matched_haptic_info(sender);
701         if (!info) {
702                 info = add_haptic_info(sender);
703                 if (!info) {
704                         _E("Failed to create haptic information.");
705                         ret = -EPERM;
706                         h_ops->close_device(handle);
707                         goto exit;
708                 }
709         }
710
711         DD_LIST_APPEND(info->handle_list, (gpointer)(long)handle);
712
713         ret = handle;
714
715 exit:
716         return g_variant_new("(i)", ret);
717 }
718
719 int clear_current_data(void)
720 {
721         cur_h_data.handle = INVALID_HANDLE;
722         cur_h_data.priority = PRIORITY_MIN;
723
724         if (duration_timer) {
725                 _I("Remove duration_timer.");
726                 g_source_remove(duration_timer);
727                 duration_timer = 0;
728         }
729
730         return 0;
731 }
732
733 GVariant *hdbus_close_device(GDBusConnection *conn,
734         const gchar *sender, const gchar *path, const gchar *iface, const gchar *name,
735         GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data)
736 {
737         unsigned int handle;
738         int ret;
739         struct haptic_info *info;
740         int cnt;
741
742         if (!CHECK_VALID_OPS(h_ops, ret))
743                 goto exit;
744
745         g_variant_get(param, "(u)", &handle);
746
747         if (!sender) {
748                 _E("Failed to get sender from dbus message.");
749                 ret = -EPERM;
750                 goto exit;
751         }
752
753         ret = h_ops->close_device(handle);
754         if (ret < 0)
755                 goto exit;
756
757         if (cur_h_data.handle == handle) {
758                 /* Remove duration_timer for vibrate_effect */
759                 clear_current_data();
760         }
761
762         info = get_matched_haptic_info(sender);
763         if (!info) {
764                 _E("Failed to find the matched haptic info.");
765                 goto exit;
766         }
767
768         DD_LIST_REMOVE(info->handle_list, (gpointer)(long)handle);
769         cnt = DD_LIST_LENGTH(info->handle_list);
770         if (cnt == 0)
771                 remove_haptic_info(info);
772
773 exit:
774         return g_variant_new("(i)", ret);
775 }
776
777 static gboolean _cb(void *data)
778 {
779         if (duration_timer) {
780                 g_source_remove(duration_timer);
781                 duration_timer = 0;
782         }
783
784         cur_h_data.handle = INVALID_HANDLE;
785         cur_h_data.priority = PRIORITY_MIN;
786
787         return G_SOURCE_REMOVE;
788 }
789
790 static void vibrate_monotone_idler_cb(void *data)
791 {
792         struct vibrate_monotone_info *vibrate_info;
793         int ret;
794
795         if (!data)
796                 return;
797
798         vibrate_info = (struct vibrate_monotone_info *)data;
799
800         if (vibrate_info->priority < cur_h_data.priority) {
801                 _I("Handle(%d) skip low priority. pre=%d now=%d", vibrate_info->handle, cur_h_data.priority, vibrate_info->priority);
802                 free(vibrate_info);
803                 return;
804         }
805
806         if (duration_timer) {
807                 g_source_remove(duration_timer);
808                 duration_timer = 0;
809         }
810
811         cur_h_data.vibration_data = NULL;
812         cur_h_data.handle = vibrate_info->handle;
813         cur_h_data.level = vibrate_info->level;
814         cur_h_data.priority = vibrate_info->priority;
815         cur_h_data.stop = false;
816         cur_h_data.unlimit = false;
817
818         ret = device_power_request_lock(POWER_LOCK_CPU, vibrate_info->duration);
819         if (ret != DEVICE_ERROR_NONE)
820                 _E("Failed to request power lock.");
821
822         _D("Handle(%d) play=%dms, level=%d, intensity=%d, frequency=0)",
823                         cur_h_data.handle, vibrate_info->duration, cur_h_data.level,
824                         vibrate_info->intensity);
825
826         duration_timer = g_timeout_add(vibrate_info->duration, _cb, NULL);
827         h_ops->vibrate_monotone(cur_h_data.handle, vibrate_info->duration, 0, 0, cur_h_data.level, vibrate_info->intensity, cur_h_data.priority);
828
829         free(vibrate_info);
830 }
831
832 GVariant *hdbus_vibrate_monotone(GDBusConnection *conn,
833         const gchar *sender, const gchar *path, const gchar *iface, const gchar *name,
834         GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data)
835 {
836         struct vibrate_monotone_info *vibrate_info;
837         unsigned int handle;
838         int duration, level, intensity, priority, ret = 0;
839
840         if (!CHECK_VALID_OPS(h_ops, ret))
841                 goto exit;
842
843         if (haptic_disabled)
844                 goto exit;
845
846         g_variant_get(param, "(uiii)", &handle, &duration, &intensity, &priority);
847         _D("param (uiii): handle=%u, duration=%d, intensity=%d, priority=%d", handle, duration, intensity, priority);
848
849         if (intensity < 0) {
850                 ret = -EINVAL;
851                 goto exit;
852         }
853
854         if (priority < PRIORITY_MIN)
855                 priority = PRIORITY_MIN;
856         else if (priority > PRIORITY_TOP)
857                 priority = PRIORITY_TOP;
858
859         if (duration <= 0) {
860                 _E("Skip vibrate handle(%d) requested less than 0.", handle);
861                 ret = -EINVAL;
862                 goto exit;
863         }
864
865         if (vconf_get_int(VCONFKEY_SETAPPL_NOTI_VIBRATION_LEVEL_INT, &level) < 0) {
866                 _E("Failed to get '"VCONFKEY_SETAPPL_NOTI_VIBRATION_LEVEL_INT"' value.");
867                 ret = -EINVAL;
868                 goto exit;
869         }
870
871         vibrate_info = calloc(1, sizeof(struct vibrate_monotone_info));
872         if (!vibrate_info) {
873                 _E("Failed to allocate memory for vibrate_info.");
874                 ret = -errno;
875                 goto exit;
876         }
877
878         vibrate_info->handle = handle;
879         vibrate_info->duration = duration;
880         vibrate_info->level = (level/2) + 1;
881         vibrate_info->intensity = intensity * 100; // 1~100 (API spec)
882         vibrate_info->priority = priority;
883
884         ret = add_idle_request(vibrate_monotone_idler_cb, (void *)vibrate_info);
885 exit:
886         return g_variant_new("(i)", ret);
887 }
888
889 static gboolean haptic_duration_play(void *data)
890 {
891         dd_list *head, *n, *next;
892         struct duration_data *node;
893         int ret = 0;
894
895         if (duration_timer) {
896                 g_source_remove(duration_timer);
897                 duration_timer = 0;
898         }
899
900         if (!data) {
901                 if (cur_h_data.unlimit) /* In case of unlimit pattern, do not stop */
902                         head = cur_h_data.vibration_data;
903                 else {
904                         cur_h_data.handle = INVALID_HANDLE;
905                         cur_h_data.priority = PRIORITY_MIN;
906                         goto out;
907                 }
908         } else
909                 head = (dd_list *)data;
910
911         if (cur_h_data.stop) {
912                 _I("Stop currunt vibration.");
913                 cur_h_data.stop = false;
914                 cur_h_data.handle = INVALID_HANDLE;
915                 cur_h_data.priority = PRIORITY_MIN;
916                 goto out;
917         }
918
919         DD_LIST_FOREACH_SAFE(head, n, next, node) {
920                 _I("Handle(%d) play=%dms and Wait=%dms %s type. (level=%d, intensity=%d, frequency=%d)",
921                         cur_h_data.handle, node->duration, node->wait,
922                         cur_h_data.unlimit ? "Unlimit" : "Once", cur_h_data.level, node->intensity, node->frequency);
923                 if ((node->duration + node->wait) <= 0) {
924                         if (!cur_h_data.unlimit) {
925                                 cur_h_data.handle = INVALID_HANDLE;
926                                 cur_h_data.priority = PRIORITY_MIN;
927                                 break;
928                         } else {
929                                 next = cur_h_data.vibration_data;
930                                 continue;
931                         }
932                 }
933
934                 duration_timer = g_timeout_add((node->duration + node->wait), haptic_duration_play, (void *)next);
935
936                 ret = h_ops->vibrate_monotone(cur_h_data.handle, node->duration, node->frequency, node->overdrive, cur_h_data.level, node->intensity, cur_h_data.priority);
937
938                 break;
939         }
940         if (ret != 0) {
941                 _D("Auto stop vibration.");
942                 cur_h_data.stop = true;
943         }
944 out:
945         return G_SOURCE_REMOVE;
946 }
947
948 static void vibrate_pattern_idler_cb(void *data)
949 {
950         struct vibrate_pattern_info *vibrate_info;
951         dd_list *elem;
952         struct vibration_config *conf;
953         char pattern[PATH_MAX];
954         int ret;
955         int unlimit = 0;
956
957         if (!data)
958                 return;
959
960         vibrate_info = (struct vibrate_pattern_info *)data;
961
962         if (!(vibrate_info->pattern)) {
963                 free(vibrate_info);
964                 return;
965         }
966
967         /* Same or higher priority pattern should be played */
968         if (vibrate_info->priority < cur_h_data.priority) {
969                 _I("Handle(%d) skip low priority. pre=%d now=%d", vibrate_info->handle, cur_h_data.priority, vibrate_info->priority);
970                 goto out;
971         }
972
973         snprintf(pattern, sizeof(pattern), "%s", vibrate_info->pattern);
974         DD_LIST_FOREACH(vib_conf_list, elem, conf) {
975                 if (!conf->pattern)
976                         continue;
977                 if (strcmp(conf->pattern, pattern))
978                         continue;
979                 if (conf->standard) {
980                         unlimit = conf->unlimit;
981                         snprintf(pattern, sizeof(pattern), "%s", conf->standard);
982                         continue;
983                 }
984
985                 if (unlimit)
986                         cur_h_data.unlimit = unlimit;
987                 else
988                         cur_h_data.unlimit = conf->unlimit;
989                 cur_h_data.vibration_data = conf->data;
990                 cur_h_data.handle = vibrate_info->handle;
991                 cur_h_data.level = vibrate_info->level;
992                 cur_h_data.priority = vibrate_info->priority;
993                 cur_h_data.stop = false;
994                 _I("Handle(%d) play=%s pri=%d %s", cur_h_data.handle, conf->pattern, cur_h_data.priority,
995                                 cur_h_data.unlimit ? "Unlimit" : "Once");
996
997                 if (conf->pattern_duration <= 0)
998                         break;
999
1000                 if (!cur_h_data.unlimit && conf->pattern_duration > 0) {
1001                         ret = device_power_request_lock(POWER_LOCK_CPU, (int)conf->pattern_duration);
1002                         if (ret != DEVICE_ERROR_NONE)
1003                                 _E("Failed to request power lock.");
1004                 }
1005                 haptic_duration_play((void *)cur_h_data.vibration_data);
1006                 goto out;
1007         }
1008         _E("Handle(%d) %s is not supported.", vibrate_info->handle, pattern);
1009
1010 out:
1011         free(vibrate_info->pattern);
1012         free(vibrate_info);
1013 }
1014
1015 GVariant *hdbus_vibrate_pattern(GDBusConnection *conn,
1016         const gchar *sender, const gchar *path, const gchar *iface, const gchar *name,
1017         GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data)
1018 {
1019         struct vibrate_pattern_info *vibrate_info;
1020         unsigned int handle;
1021         char *pattern = NULL;
1022         int level, priority, ret = 0;
1023
1024         if (!CHECK_VALID_OPS(h_ops, ret))
1025                 goto exit;
1026
1027         if (haptic_disabled)
1028                 goto exit;
1029
1030         g_variant_get(param, "(usii)",  &handle, &pattern, &level, &priority);
1031
1032         if (level < 0) {
1033                 ret = -EINVAL;
1034                 goto exit;
1035         }
1036
1037         if (priority < PRIORITY_MIN)
1038                 priority = PRIORITY_MIN;
1039         else if (priority > PRIORITY_TOP)
1040                 priority = PRIORITY_TOP;
1041
1042         vibrate_info = calloc(1, sizeof(struct vibrate_pattern_info));
1043         if (!vibrate_info) {
1044                 _E("Failed to allocate memory for vibrate_info.");
1045                 ret = -errno;
1046                 goto exit;
1047         }
1048         vibrate_info->handle = handle;
1049         vibrate_info->pattern = pattern;
1050         pattern = NULL;
1051         if (!vibrate_info->pattern) {
1052                 _E("Failed to allocate memory for pattern.");
1053                 ret = -errno;
1054                 free(vibrate_info);
1055                 goto exit;
1056         }
1057         vibrate_info->level = level;
1058         vibrate_info->priority = priority;
1059
1060         ret = add_idle_request(vibrate_pattern_idler_cb, (void *)vibrate_info);
1061
1062 exit:
1063         g_free(pattern);
1064         return g_variant_new("(i)", ret);
1065 }
1066
1067 GVariant *hdbus_stop_device(GDBusConnection *conn,
1068         const gchar *sender, const gchar *path, const gchar *iface, const gchar *name,
1069         GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data)
1070 {
1071         unsigned int handle;
1072         int ret = 0;
1073
1074         if (!CHECK_VALID_OPS(h_ops, ret))
1075                 goto exit;
1076
1077         if (haptic_disabled) {
1078                 _I("Haptic disabled.");
1079                 goto exit;
1080         }
1081
1082         g_variant_get(param, "(u)", &handle);
1083
1084         if (cur_h_data.handle != handle) {
1085                 _D("Not the request from current vibration handle(%d). Skip.", handle);
1086                 goto exit;
1087         }
1088
1089         ret = h_ops->stop_device(handle);
1090         _I("Stop the device(handle=%u) :%d", handle, ret);
1091
1092         /* Remove duration_timer for vibrate_effect */
1093         clear_current_data();
1094
1095 exit:
1096         return g_variant_new("(i)", ret);
1097 }
1098
1099 GVariant *hdbus_show_handle_list(GDBusConnection *conn,
1100         const gchar *sender, const gchar *path, const gchar *iface, const gchar *name,
1101         GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data)
1102 {
1103         dd_list *n;
1104         dd_list *elem;
1105         struct haptic_info *info;
1106
1107         _D("Sender Handle");
1108         DD_LIST_FOREACH(haptic_handle_list, n, info) {
1109                 for (elem = info->handle_list; elem; elem = elem->next)
1110                         _D("%s %d", info->sender, (int)(long)elem->data);
1111         }
1112
1113         return g_variant_new_tuple(NULL, 0);
1114 }
1115
1116 int pattern_is_supported(const char *pattern)
1117 {
1118         dd_list *elem;
1119         struct vibration_config *conf;
1120         int ret;
1121
1122         if (!pattern)
1123                 return -EINVAL;
1124
1125         ret = 0;
1126         DD_LIST_FOREACH(vib_conf_list, elem, conf) {
1127                 if (!conf->pattern)
1128                         continue;
1129                 if (!strcmp(conf->pattern, pattern)) {
1130                         ret = true;
1131                         break;
1132                 }
1133         }
1134
1135         return ret;
1136 }
1137
1138 GVariant *hdbus_pattern_is_supported(GDBusConnection *conn,
1139         const gchar *sender, const gchar *path, const gchar *iface, const gchar *name,
1140         GVariant *param, GDBusMethodInvocation *invocation, gpointer user_data)
1141
1142 {
1143         char *data = NULL;
1144         int ret = 0;
1145
1146         if (!CHECK_VALID_OPS(h_ops, ret))
1147                 goto exit;
1148
1149         if (haptic_disabled)
1150                 goto exit;
1151
1152         g_variant_get(param, "(s)", &data);
1153
1154         ret = pattern_is_supported(data);
1155
1156         _I("%s is supported: %d", data, ret);
1157
1158 exit:
1159         g_free(data);
1160         return g_variant_new("(i)", ret);
1161 }
1162
1163 static int haptic_internal_init(void)
1164 {
1165         int r;
1166         if (!CHECK_VALID_OPS(h_ops, r))
1167                 return r;
1168         return h_ops->open_device(HAPTIC_MODULE_DEVICE_ALL, &g_handle);
1169 }
1170
1171 static int haptic_internal_exit(void)
1172 {
1173         int r;
1174         if (!CHECK_VALID_OPS(h_ops, r))
1175                 return r;
1176         return h_ops->close_device(g_handle);
1177 }
1178
1179 static void haptic_poweroff_cb(GDBusConnection  *conn,
1180         const gchar      *sender,
1181         const gchar      *path,
1182         const gchar      *iface,
1183         const gchar      *name,
1184         GVariant         *param,
1185         gpointer          data)
1186 {
1187         int type = POWER_OFF_NONE;
1188         int ret, level;
1189         struct timespec time = {0,};
1190
1191         if (!g_variant_get_safe(param, "(i)", &type)) {
1192                 _E("Failed to get params from gvariant. expected:%s, type:%s", "(i)", g_variant_get_type_string(param));
1193                 return;
1194         }
1195
1196         if (type != POWER_OFF_DIRECT && type != POWER_OFF_RESTART)
1197                 return;
1198
1199         _D("Poweroff: %d", type);
1200
1201         if (!CHECK_VALID_OPS(h_ops, ret)) {
1202                 ret = haptic_module_load();
1203                 if (ret < 0)
1204                         return;
1205         }
1206
1207         if (!g_handle)
1208                 haptic_internal_init();
1209
1210         if (vconf_get_int(VCONFKEY_SETAPPL_NOTI_VIBRATION_LEVEL_INT, &level) < 0) {
1211                 _E("Failed to get '"VCONFKEY_SETAPPL_NOTI_VIBRATION_LEVEL_INT"' vconf value.");
1212                 return;
1213         }
1214         level = (level/2) + 1;
1215
1216         /* power off vibration */
1217         _I("Handle=%d dur=%dms pri=%d level=%d intensity=%d frequency=0",
1218                 g_handle, POWER_OFF_VIB_DURATION, PRIORITY_HIGH, level,
1219                 POWER_VIB_FEEDBACK * 100);
1220         ret = h_ops->vibrate_monotone(g_handle, POWER_OFF_VIB_DURATION, 0, 0,
1221                         level, POWER_VIB_FEEDBACK * 100, PRIORITY_HIGH);
1222         if (ret < 0) {
1223                 _E("Failed to vibrate_monotone: %d", ret);
1224                 return;
1225         }
1226
1227         /* sleep for vibration */
1228         time.tv_nsec = POWER_OFF_VIB_DURATION * NANO_SECOND_MULTIPLIER;
1229         nanosleep(&time, NULL);
1230         return;
1231 }
1232
1233 static void sound_capturing_cb(keynode_t *key, void *data)
1234 {
1235         int status;
1236
1237         status = vconf_keynode_get_int(key);
1238
1239         /* if sound capture is in use, this value is 1(true). */
1240         if (status == VCONFKEY_RECORDER_STATE_RECORDING)
1241                 haptic_stop();
1242         else
1243                 haptic_start();
1244 }
1245
1246 static int parse_section(struct parse_result *result, void *user_data, int index)
1247 {
1248         struct haptic_config *conf = (struct haptic_config *)user_data;
1249
1250         if (!result)
1251                 return 0;
1252
1253         if (!result->section || !result->name || !result->value)
1254                 return 0;
1255
1256         if (MATCH(result->name, "sound_capture")) {
1257                 conf->sound_capture = atoi(result->value);
1258         } else if (MATCH(result->name, "level")) {
1259                 conf->level = atoi(result->value);
1260                 if (conf->level < 0 || conf->level >= INT_MAX - 1) {
1261                         _E("You must set level with positive number in integer range.");
1262                         return -EINVAL;
1263                 }
1264                 conf->level_arr = calloc(sizeof(int), conf->level);
1265                 if (!conf->level_arr) {
1266                         _E("Failed to allocate memory for level.");
1267                         return -errno;
1268                 }
1269         } else if (MATCH(result->name, "value")) {
1270                 if (index < 0)
1271                         return -EINVAL;
1272                 conf->level_arr[index] = atoi(result->value);
1273         }
1274
1275         return 0;
1276 }
1277
1278 static int haptic_load_config(struct parse_result *result, void *user_data)
1279 {
1280         struct haptic_config *conf = (struct haptic_config *)user_data;
1281         char name[NAME_MAX];
1282         int ret;
1283         static int index;
1284
1285         if (!result)
1286                 return 0;
1287
1288         if (!result->section || !result->name || !result->value)
1289                 return 0;
1290
1291         // Parsing 'Haptic' section
1292         if (MATCH(result->section, "Haptic")) {
1293                 ret = parse_section(result, user_data, -1);
1294                 if (ret < 0) {
1295                         _E("Failed to parse 'Haptic' section: %d", ret);
1296                         return ret;
1297                 }
1298                 goto out;
1299         }
1300
1301         // Parsing 'level' section
1302         for (index = 0; index < conf->level; ++index) {
1303                 snprintf(name, sizeof(name), "level%d", index);
1304                 if (MATCH(result->section, name)) {
1305                         ret = parse_section(result, user_data, index);
1306                         if (ret < 0) {
1307                                 _E("Failed to parse 'level' section: %d", ret);
1308                                 return ret;
1309                         }
1310                         goto out;
1311                 }
1312         }
1313
1314 out:
1315         return 0;
1316 }
1317
1318 static const dbus_method_s hdbus_methods[] = {
1319         { "GetCount",          NULL,   "i", hdbus_get_count },            // device_haptic_get_count
1320         { "OpenDevice",         "i",   "i", hdbus_open_device },          // device_haptic_open, feedback_initialize
1321         { "CloseDevice",        "u",   "i", hdbus_close_device },         // device_haptic_close, feedback_deinitialize
1322         { "StopDevice",         "u",   "i", hdbus_stop_device },          // device_haptic_stop, feedback_stop
1323         { "VibrateMonotone", "uiii",   "i", hdbus_vibrate_monotone },     // device_haptic_vibrate
1324         { "VibratePattern",  "usii",   "i", hdbus_vibrate_pattern },      // feedback_play*
1325         { "ShowHandleList",    NULL,  NULL, hdbus_show_handle_list },
1326         { "IsSupported",        "s",   "i", hdbus_pattern_is_supported }, // feedback_is_supported_pattern
1327         /* Add methods here */
1328 };
1329
1330 static const dbus_interface_u dbus_interface = {
1331         .name = VIBRATOR_INTERFACE_HAPTIC,
1332         .methods = hdbus_methods,
1333         .nr_methods = ARRAY_SIZE(hdbus_methods),
1334 };
1335
1336 int haptic_probe(void)
1337 {
1338         /**
1339          * load haptic module.
1340          * if there is no haptic module,
1341          * feedbackd does not activate a haptic interface.
1342          */
1343         return haptic_module_load();
1344 }
1345
1346 static guint id_sig_pwr_off_state;
1347
1348 void haptic_init(void)
1349 {
1350         int r;
1351
1352         /* get haptic data from configuration file */
1353         r = config_parse(HAPTIC_CONF_PATH, haptic_load_config, &haptic_conf);
1354         if (r < 0) {
1355                 _E("Failed to load configuration file(%s): %d", HAPTIC_CONF_PATH, r);
1356                 safe_free(haptic_conf.level_arr);
1357         }
1358
1359         /* init dbus interface */
1360         r = dbus_handle_register_dbus_object(NULL, VIBRATOR_PATH_HAPTIC, &dbus_interface);
1361         if (r < 0)
1362                 _E("Failed to init hdbus interface and method: %d", r);
1363
1364         id_sig_pwr_off_state = subscribe_dbus_signal(NULL,
1365                         DEVICED_PATH_POWEROFF,
1366                         DEVICED_INTERFACE_POWEROFF,
1367                         SIGNAL_POWEROFF_STATE,
1368                         haptic_poweroff_cb,
1369                         NULL,
1370                         NULL);
1371         if (id_sig_pwr_off_state <= 0) {
1372                 _E("Failed to register signal handler: %d", r);
1373                 return;
1374         }
1375
1376         dbus_handle_emit_dbus_signal(NULL,
1377                         VIBRATOR_PATH_HAPTIC,
1378                         VIBRATOR_INTERFACE_HAPTIC,
1379                         SIGNAL_VIBRATOR_INITIATED,
1380                         NULL);
1381
1382         /* add watch for sound capturing value */
1383         if (haptic_conf.sound_capture) {
1384                 r = vconf_notify_key_changed(VCONFKEY_RECORDER_STATE, sound_capturing_cb, NULL);
1385                 if (r != 0)
1386                         _W("Add watch for VCONFKEY_RECORDER_STATE failed.");
1387         }
1388
1389         /* Initialize vibration_handle (Use vibration now) */
1390         cur_h_data.handle = INVALID_HANDLE;
1391         cur_h_data.priority = PRIORITY_MIN;
1392 }
1393
1394 void haptic_exit(void)
1395 {
1396         struct haptic_ops *ops;
1397         dd_list *elem;
1398         int r;
1399
1400         /* remove watch */
1401         if (haptic_conf.sound_capture) {
1402                 r = vconf_ignore_key_changed(VCONFKEY_RECORDER_STATE, sound_capturing_cb);
1403                 if (r != 0)
1404                         _W("Remove watch for VCONFKEY_RECORDER_STATE failed.");
1405         }
1406
1407         /* unregister notifier for below each event */
1408         unsubscribe_dbus_signal(NULL, id_sig_pwr_off_state);
1409
1410         /* release haptic data memory */
1411         safe_free(haptic_conf.level_arr);
1412
1413         if (!CHECK_VALID_OPS(h_ops, r))
1414                 return;
1415
1416         /* haptic exit for feedbackd */
1417         haptic_internal_exit();
1418
1419         /* release plugin */
1420         DD_LIST_FOREACH(h_head, elem, ops) {
1421                 if (ops->is_valid && ops->is_valid()) {
1422                         if (ops->release)
1423                                 ops->release();
1424                         h_ops = NULL;
1425                         break;
1426                 }
1427         }
1428 }
1429
1430 static int haptic_start(void)
1431 {
1432         _I("Start");
1433         haptic_disabled = false;
1434         return 0;
1435 }
1436
1437 static int haptic_stop(void)
1438 {
1439         _I("Stop");
1440         haptic_disabled = true;
1441         return 0;
1442 }