merge with master
[platform/core/system/system-server.git] / ss_vibrator.c
1 /*
2  * Copyright (c) 2012 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17
18 #include <glib.h>
19 #include <device-node.h>
20
21 #include "ss_log.h"
22 #include "ss_predefine.h"
23 #include "include/ss_data.h"
24
25 enum {
26         PLAY_HAPTIC = 0,
27         STOP_HAPTIC,
28         LEVEL_HAPTIC,
29 };
30
31 struct haptic_node {
32         int pid;
33         int level;
34         int play;
35 };
36
37 static GList *haptic_head;
38
39 static int add_node(struct haptic_node *node)
40 {
41         haptic_head = g_list_append(haptic_head, node);
42 }
43
44 static int delete_node(struct haptic_node *node)
45 {
46         haptic_head = g_list_remove(haptic_head, node);
47 }
48
49 static struct haptic_node *find_node(int pid)
50 {
51         GList *elem;
52         struct haptic_node *node = NULL;
53
54         for (elem = haptic_head; elem; elem = elem->next) {
55                 node = elem->data;
56                 if (node->pid == pid)
57                         break;
58         }
59
60         return node;
61 }
62
63 static int haptic_play(int pid)
64 {
65         struct haptic_node *node;
66         int r;
67
68         node = malloc(sizeof(struct haptic_node));
69         if (node == NULL) {
70                 PRT_TRACE_ERR("malloc fail");
71                 return -1;
72         }
73
74         node->pid = pid;
75         node->level = 0;
76         node->play = 1;
77
78         add_node(node);
79
80         r = device_set_property(DEVICE_TYPE_VIBRATOR, PROP_VIBRATOR_ENABLE, 1);
81         if (r < 0) {
82                 PRT_TRACE_ERR("set enable fail");
83                 return -1;
84         }
85
86         return 0;
87 }
88
89 static void check_play_state(gpointer data, gpointer user_data)
90 {
91         struct haptic_node *node = (struct haptic_node*)data;
92         int *play = (int*)user_data;
93
94         *play += node->play;
95         PRT_TRACE_ERR("node pid : %d, level : %d, play : %d", node->pid, node->level, node->play);
96 }
97
98 static int haptic_stop(int pid)
99 {
100         struct haptic_node *node;
101         int play = 0;
102         int r;
103
104         node = find_node(pid);
105         if (node == NULL) {
106                 PRT_TRACE_ERR("find_node(%d) fail", pid);
107                 return -1;
108         }
109
110         node->play = 0;
111         delete_node(node);
112         free(node);
113
114         g_list_foreach(haptic_head, check_play_state, &play);
115         PRT_TRACE_ERR("play state : %d", play);
116
117         if (!play) {
118                 PRT_TRACE_ERR("not playing anymore, will be stop");
119                 r = device_set_property(DEVICE_TYPE_VIBRATOR, PROP_VIBRATOR_ENABLE, 0);
120                 if (r < 0) {
121                         PRT_TRACE_ERR("set enable fail");
122                         return -1;
123                 }
124         }
125
126         return 0;
127 }
128
129 static void get_current_level(gpointer data, gpointer user_data)
130 {
131         struct haptic_node *node = (struct haptic_node*)data;
132         int *sum = (int*)user_data;
133
134         PRT_TRACE_ERR("node pid : %d, level : %d, play : %d", node->pid, node->level, node->play);
135         if (node->play == 1) {
136                 PRT_TRACE_ERR("node->play : %d, sum : %d", node->play, *sum);
137                 *sum += node->level;
138         }
139 }
140
141 static int haptic_change_level(int pid, int level)
142 {
143         struct haptic_node *node;
144         int sum = 0;
145         int r;
146
147         PRT_TRACE_ERR("pid : %d, level : %d", pid, level);
148
149         node = find_node(pid);
150         if (node == NULL) {
151                 PRT_TRACE_ERR("find_node(%d) fail", pid);
152                 return -1;
153         }
154
155         node->level = level;
156
157         g_list_foreach(haptic_head, get_current_level, &sum);
158         PRT_TRACE_ERR("current sum level : %d", sum);
159
160         r = device_set_property(DEVICE_TYPE_VIBRATOR, PROP_VIBRATOR_LEVEL, sum);
161         if (r < 0) {
162                 PRT_TRACE_ERR("set level fail");
163                 return -1;
164         }
165
166         return 0;
167 }
168
169 int haptic_def_predefine_action(int argc, char **argv)
170 {
171         int i;
172         int pid;
173         int mode;
174
175         PRT_TRACE_ERR("argc : %d", argc);
176         for (i = 0; i < argc; ++i)
177                 PRT_TRACE_ERR("[%2d] %s", i, argv[i]);
178
179         if (argc != 3) {
180                 PRT_TRACE_ERR("Haptic predefine action failed");
181                 return -1;
182         }
183
184         pid = atoi(argv[0]);
185         mode = atoi(argv[1]);
186         PRT_TRACE_ERR("pid : %d, mode : %d", pid, mode);
187
188         switch(mode) {
189         case PLAY_HAPTIC:
190                 haptic_play(pid);
191                 break;
192         case STOP_HAPTIC:
193                 haptic_stop(pid);
194                 break;
195         case LEVEL_HAPTIC:
196                 haptic_change_level(pid, atoi(argv[2]));
197                 break;
198         default:
199                 break;
200         }
201
202         return 0;
203 }