6f06d44616b6d58e135fb126df9e94c0c01e09f7
[platform/core/system/libsvi.git] / mobile / src / check.c
1 /*
2  * libfeedback
3  * Copyright (c) 2015 Samsung Electronics Co., Ltd.
4  *
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
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
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.
16  */
17
18
19 #include <stdio.h>
20 #include <vconf.h>
21
22 #include "feedback.h"
23 #include "feedback-ids-mobile.h"
24 #include "profiles.h"
25 #include "log.h"
26
27 /* Temporary keys */
28 #ifndef VCONFKEY_SETAPPL_VIBRATE_WHEN_NOTIFICATION_BOOL
29 #define VCONFKEY_SETAPPL_VIBRATE_WHEN_NOTIFICATION_BOOL "db/setting/sound/vibrate_when_notification"
30 #endif
31 #ifndef VCONFKEY_SETAPPL_HAPTIC_FEEDBACK_STATUS_BOOL
32 #define VCONFKEY_SETAPPL_HAPTIC_FEEDBACK_STATUS_BOOL "db/setting/sound/haptic_feedback_on"
33 #endif
34
35
36 static const char *mobile_str_type[] = {
37         "FEEDBACK_TYPE_NONE",
38         "FEEDBACK_TYPE_SOUND",
39         "FEEDBACK_TYPE_VIBRATION",
40         "FEEDBACK_TYPE_MOBILE_LED",
41 };
42
43 static const char *mobile_str_pattern[] = {
44         "FEEDBACK_PATTERN_TAP",
45         "FEEDBACK_PATTERN_SIP",
46         "FEEDBACK_PATTERN_MOBILE_SIP_BACKSPACE",
47         "FEEDBACK_PATTERN_MOBILE_SIP_FUNCTION",
48         "FEEDBACK_PATTERN_MOBILE_SIP_FJKEY",
49         "FEEDBACK_PATTERN_MOBILE_MAX_CHARACTER",
50         "FEEDBACK_PATTERN_KEY0",
51         "FEEDBACK_PATTERN_KEY1",
52         "FEEDBACK_PATTERN_KEY2",
53         "FEEDBACK_PATTERN_KEY3",
54         "FEEDBACK_PATTERN_KEY4",
55         "FEEDBACK_PATTERN_KEY5",
56         "FEEDBACK_PATTERN_KEY6",
57         "FEEDBACK_PATTERN_KEY7",
58         "FEEDBACK_PATTERN_KEY8",
59         "FEEDBACK_PATTERN_KEY9",
60         "FEEDBACK_PATTERN_KEY_STAR",
61         "FEEDBACK_PATTERN_KEY_SHARP",
62         "FEEDBACK_PATTERN_KEY_BACK",
63         "FEEDBACK_PATTERN_HOLD",
64         "FEEDBACK_PATTERN_MOBILE_MULTI_TAP",
65         "FEEDBACK_PATTERN_HW_TAP",
66         "FEEDBACK_PATTERN_HW_HOLD",
67
68         "FEEDBACK_PATTERN_MESSAGE",
69         "FEEDBACK_PATTERN_MOBILE_MESSAGE_ON_CALL",
70         "FEEDBACK_PATTERN_EMAIL",
71         "FEEDBACK_PATTERN_MOBILE_EMAIL_ON_CALL",
72         "FEEDBACK_PATTERN_WAKEUP",
73         "FEEDBACK_PATTERN_MOBILE_WAKEUP_ON_CALL",
74         "FEEDBACK_PATTERN_SCHEDULE",
75         "FEEDBACK_PATTERN_MOBILE_SCHEDULE_ON_CALL",
76         "FEEDBACK_PATTERN_TIMER",
77         "FEEDBACK_PATTERN_MOBILE_TIMER_ON_CALL",
78         "FEEDBACK_PATTERN_GENERAL",
79         "FEEDBACK_PATTERN_MOBILE_GENERAL_ON_CALL",
80         "FEEDBACK_PATTERN_MOBILE_SMART_ALERT",
81
82         "FEEDBACK_PATTERN_POWERON",
83         "FEEDBACK_PATTERN_POWEROFF",
84         "FEEDBACK_PATTERN_CHARGERCONN",
85         "FEEDBACK_PATTERN_MOBILE_CHARGERCONN_ON_CALL",
86         "FEEDBACK_PATTERN_CHARGING_ERROR",
87         "FEEDBACK_PATTERN_MOBILE_CHARGING_ERROR_ON_CALL",
88         "FEEDBACK_PATTERN_FULLCHARGED",
89         "FEEDBACK_PATTERN_MOBILE_FULLCHARGED_ON_CALL",
90         "FEEDBACK_PATTERN_LOWBATT",
91         "FEEDBACK_PATTERN_MOBILE_LOWBATT_ON_CALL",
92         "FEEDBACK_PATTERN_LOCK",
93         "FEEDBACK_PATTERN_UNLOCK",
94         "FEEDBACK_PATTERN_MOBILE_LOCK_SWIPE",
95         "FEEDBACK_PATTERN_MOBILE_UNLOCK_SWIPE",
96         "FEEDBACK_PATTERN_MOBILE_GEOMETRIC_LOCK",
97         "FEEDBACK_PATTERN_MOBILE_CALLCONNECT",
98         "FEEDBACK_PATTERN_MOBILE_DISCALLCONNECT",
99         "FEEDBACK_PATTERN_MOBILE_OUTGOING_CALL",
100         "FEEDBACK_PATTERN_MOBILE_MINUTEMINDER",
101         "FEEDBACK_PATTERN_VIBRATION_ON",
102         "FEEDBACK_PATTERN_SILENT_OFF",
103         "FEEDBACK_PATTERN_BT_CONNECTED",
104         "FEEDBACK_PATTERN_BT_DISCONNECTED",
105         "FEEDBACK_PATTERN_MOBILE_BT_PAIRING",
106         "FEEDBACK_PATTERN_MOBILE_BT_WAITING",
107         "FEEDBACK_PATTERN_MOBILE_SCREEN_CAPTURE",
108         "FEEDBACK_PATTERN_LIST_REORDER",
109         "FEEDBACK_PATTERN_LIST_SLIDER",
110         "FEEDBACK_PATTERN_VOLUME_KEY",
111         "FEEDBACK_PATTERN_MOBILE_MMS",
112         "FEEDBACK_PATTERN_MOBILE_HOURLY_ALERT",
113
114         "FEEDBACK_PATTERN_MOBILE_SAFETY_ALERT",
115         "FEEDBACK_PATTERN_MOBILE_ACCIDENT_DETECT",
116         "FEEDBACK_PATTERN_MOBILE_SEND_SOS_MESSAGE",
117         "FEEDBACK_PATTERN_MOBILE_END_SOS_MESSAGE",
118         "FEEDBACK_PATTERN_MOBILE_EMERGENCY_BUZZER",
119         "FEEDBACK_PATTERN_MOBILE_SAFETY_LOW_POWER",
120         "FEEDBACK_PATTERN_MOBILE_CMAS",
121 };
122
123 static int callstatus;
124 static int lock_sndstatus;
125 static int camerastatus;
126 static int shutter_sndstatus;
127 static int noti_vibstatus;
128 static int vib_level;
129 static int noti_level;
130 static int feedbackstatus;
131
132 static void feedback_callstatus_cb(keynode_t *key, void* data)
133 {
134         callstatus = vconf_keynode_get_int(key);
135 }
136
137 static void feedback_lock_sndstatus_cb(keynode_t *key, void* data)
138 {
139         lock_sndstatus = vconf_keynode_get_bool(key);
140 }
141
142 static void feedback_camerastatus_cb(keynode_t *key, void* data)
143 {
144         camerastatus = vconf_keynode_get_int(key);
145 }
146
147 static void feedback_noti_vibstatus_cb(keynode_t *key, void* data)
148 {
149         noti_vibstatus = vconf_keynode_get_bool(key);
150 }
151
152 static void feedback_vib_cb(keynode_t *key, void* data)
153 {
154         vib_level = vconf_keynode_get_int(key);
155 }
156
157 static void feedback_noti_cb(keynode_t *key, void* data)
158 {
159         noti_level = vconf_keynode_get_int(key);
160 }
161
162 static void feedback_feedbackstatus_cb(keynode_t *key, void* data)
163 {
164         feedbackstatus = vconf_keynode_get_bool(key);
165 }
166
167 static void mobile_init(void)
168 {
169         /* check call status */
170         if (vconf_get_int(VCONFKEY_CALL_STATE, &callstatus) < 0)
171                 _W("VCONFKEY_CALL_STATE ==> FAIL!!");
172
173         if (vconf_get_bool(VCONFKEY_SETAPPL_SOUND_LOCK_BOOL, &lock_sndstatus) < 0)
174                 _W("VCONFKEY_SETAPPL_SOUND_LOCK_BOOL ==> FAIL!!");
175
176         /* check camera status */
177         if (vconf_get_int(VCONFKEY_CAMERA_STATE, &camerastatus) < 0)
178                 _W("VCONFKEY_CAMERA_STATE ==> FAIL!!");
179
180         /* shutter sound policy */
181         /* This vconf is read just once, because this value is not changed in running time. */
182         if (vconf_get_int(VCONFKEY_CAMERA_SHUTTER_SOUND_POLICY, &shutter_sndstatus) < 0)
183                 _W("VCONFKEY_CAMERA_SHUTTER_SOUND_POLICY ==> FAIL!!");
184
185         /* check vibration status */
186         if (vconf_get_bool(VCONFKEY_SETAPPL_VIBRATE_WHEN_NOTIFICATION_BOOL, &noti_vibstatus) < 0)
187                 _W("VCONFKEY_SETAPPL_VIBRATION_STATUS_BOOL ==> FAIL!!");
188
189         /* check vib_level */
190         if (vconf_get_int(VCONFKEY_SETAPPL_TOUCH_FEEDBACK_VIBRATION_LEVEL_INT, &vib_level) < 0)
191                 _W("VCONFKEY_FEEDBACK_VIBRATION_LEVEL_INT ==> FAIL!!");
192
193         /* check noti_level */
194         if (vconf_get_int(VCONFKEY_SETAPPL_NOTI_VIBRATION_LEVEL_INT, &noti_level) < 0)
195                 _W("VCONFKEY_SETAPPL_NOTI_VIBRATION_LEVEL_INT ==> FAIL!!");
196
197         /* feedback Init */
198         if (vconf_get_bool(VCONFKEY_SETAPPL_HAPTIC_FEEDBACK_STATUS_BOOL, &feedbackstatus) < 0)
199                 _W("VCONFKEY_SETAPPL_HAPTIC_FEEDBACK_STATUS_BOOL ==> FAIL!!");
200
201         /* add watch for status value */
202         vconf_notify_key_changed(VCONFKEY_CALL_STATE, feedback_callstatus_cb, NULL);
203         vconf_notify_key_changed(VCONFKEY_SETAPPL_SOUND_LOCK_BOOL, feedback_lock_sndstatus_cb, NULL);
204         vconf_notify_key_changed(VCONFKEY_CAMERA_STATE, feedback_camerastatus_cb, NULL);
205         vconf_notify_key_changed(VCONFKEY_SETAPPL_VIBRATE_WHEN_NOTIFICATION_BOOL, feedback_noti_vibstatus_cb, NULL);
206         vconf_notify_key_changed(VCONFKEY_SETAPPL_TOUCH_FEEDBACK_VIBRATION_LEVEL_INT, feedback_vib_cb, NULL);
207         vconf_notify_key_changed(VCONFKEY_SETAPPL_NOTI_VIBRATION_LEVEL_INT, feedback_noti_cb, NULL);
208         vconf_notify_key_changed(VCONFKEY_SETAPPL_HAPTIC_FEEDBACK_STATUS_BOOL, feedback_feedbackstatus_cb, NULL);
209 }
210
211 static void mobile_exit(void)
212 {
213         /* remove watch */
214         vconf_ignore_key_changed(VCONFKEY_CALL_STATE, feedback_callstatus_cb);
215         vconf_ignore_key_changed(VCONFKEY_SETAPPL_SOUND_LOCK_BOOL, feedback_lock_sndstatus_cb);
216         vconf_ignore_key_changed(VCONFKEY_CAMERA_STATE, feedback_camerastatus_cb);
217         vconf_ignore_key_changed(VCONFKEY_SETAPPL_VIBRATE_WHEN_NOTIFICATION_BOOL, feedback_noti_vibstatus_cb);
218         vconf_ignore_key_changed(VCONFKEY_SETAPPL_TOUCH_FEEDBACK_VIBRATION_LEVEL_INT, feedback_vib_cb);
219         vconf_ignore_key_changed(VCONFKEY_SETAPPL_NOTI_VIBRATION_LEVEL_INT, feedback_noti_cb);
220         vconf_ignore_key_changed(VCONFKEY_SETAPPL_HAPTIC_FEEDBACK_STATUS_BOOL, feedback_feedbackstatus_cb);
221 }
222
223 static bool mobile_get_switched_pattern(int pattern, int *switched)
224 {
225         if (!switched)
226                 return false;
227
228         if (callstatus == VCONFKEY_CALL_OFF)
229                 return false;
230
231         /* in case of call connected or connecting */
232         _D("Call status is connected or connecting.");
233         if (pattern == FEEDBACK_PATTERN_MESSAGE)
234                 *switched = FEEDBACK_PATTERN_MOBILE_MESSAGE_ON_CALL;
235         else if (pattern == FEEDBACK_PATTERN_EMAIL)
236                 *switched = FEEDBACK_PATTERN_MOBILE_EMAIL_ON_CALL;
237         else if (pattern == FEEDBACK_PATTERN_WAKEUP)
238                 *switched = FEEDBACK_PATTERN_MOBILE_WAKEUP_ON_CALL;
239         else if (pattern == FEEDBACK_PATTERN_SCHEDULE)
240                 *switched = FEEDBACK_PATTERN_MOBILE_SCHEDULE_ON_CALL;
241         else if (pattern == FEEDBACK_PATTERN_TIMER)
242                 *switched = FEEDBACK_PATTERN_MOBILE_TIMER_ON_CALL;
243         else if (pattern == FEEDBACK_PATTERN_GENERAL)
244                 *switched = FEEDBACK_PATTERN_MOBILE_GENERAL_ON_CALL;
245         else if (pattern == FEEDBACK_PATTERN_CHARGERCONN)
246                 *switched = FEEDBACK_PATTERN_MOBILE_CHARGERCONN_ON_CALL;
247         else if (pattern == FEEDBACK_PATTERN_CHARGING_ERROR)
248                 *switched = FEEDBACK_PATTERN_MOBILE_CHARGING_ERROR_ON_CALL;
249         else if (pattern == FEEDBACK_PATTERN_FULLCHARGED)
250                 *switched = FEEDBACK_PATTERN_MOBILE_FULLCHARGED_ON_CALL;
251         else if (pattern == FEEDBACK_PATTERN_LOWBATT)
252                 *switched = FEEDBACK_PATTERN_MOBILE_LOWBATT_ON_CALL;
253         else
254                 return false;
255
256         return true;
257 }
258
259 static bool mobile_get_always_alert_case(int type, int pattern)
260 {
261         switch (pattern) {
262         case FEEDBACK_PATTERN_KEY0 ... FEEDBACK_PATTERN_KEY_BACK:
263         case FEEDBACK_PATTERN_HOLD:
264                 if (CHECK_VIBRATION(type) && feedbackstatus)
265                         return true;
266                 break;
267         case FEEDBACK_PATTERN_SIP:
268         case FEEDBACK_PATTERN_MOBILE_SIP_BACKSPACE:
269         case FEEDBACK_PATTERN_MOBILE_SIP_FUNCTION:
270         case FEEDBACK_PATTERN_MOBILE_SIP_FJKEY:
271                 if (CHECK_VIBRATION(type))
272                         return true;
273                 break;
274         case FEEDBACK_PATTERN_MESSAGE:
275         case FEEDBACK_PATTERN_EMAIL:
276                 if (CHECK_VIBRATION(type) && noti_vibstatus)
277                         return true;
278                 break;
279         case FEEDBACK_PATTERN_TIMER:
280         case FEEDBACK_PATTERN_MOBILE_TIMER_ON_CALL:
281                 if (CHECK_VIBRATION(type))
282                         return true;
283                 break;
284         case FEEDBACK_PATTERN_WAKEUP:
285         case FEEDBACK_PATTERN_MOBILE_WAKEUP_ON_CALL:
286                 return true;
287         case FEEDBACK_PATTERN_MOBILE_MESSAGE_ON_CALL:
288         case FEEDBACK_PATTERN_MOBILE_EMAIL_ON_CALL:
289         case FEEDBACK_PATTERN_MOBILE_GENERAL_ON_CALL:
290                 break;
291         case FEEDBACK_PATTERN_MOBILE_CHARGERCONN_ON_CALL:
292         case FEEDBACK_PATTERN_MOBILE_CHARGING_ERROR_ON_CALL:
293         case FEEDBACK_PATTERN_MOBILE_LOWBATT_ON_CALL:
294         case FEEDBACK_PATTERN_MOBILE_MMS:
295         case FEEDBACK_PATTERN_MOBILE_HOURLY_ALERT:
296                 /* no matter sound profile */
297                 if (CHECK_VIBRATION(type))
298                         return true;
299                 break;
300         case FEEDBACK_PATTERN_MOBILE_SMART_ALERT:
301         case FEEDBACK_PATTERN_MOBILE_SEND_SOS_MESSAGE:
302         case FEEDBACK_PATTERN_MOBILE_END_SOS_MESSAGE:
303         case FEEDBACK_PATTERN_MOBILE_CMAS:
304         case FEEDBACK_PATTERN_MOBILE_OUTGOING_CALL:
305                 return true;
306         case FEEDBACK_PATTERN_MOBILE_SCREEN_CAPTURE:
307                 if (CHECK_SOUND(type) && camerastatus && shutter_sndstatus)
308                         return true;
309                 break;
310         default:
311                 break;
312         }
313         return false;
314 }
315
316 static bool mobile_get_always_off_case(int type, int pattern)
317 {
318         int ret;
319
320         /* check if the state of voice recorder is recording */
321         if (vconf_get_int(VCONFKEY_RECORDER_STATE, &ret) < 0) {
322                 _W("fail to get media sound status, status will be zero");
323                 ret = 0;
324         }
325
326         if (CHECK_SOUND(type) && ret == VCONFKEY_RECORDER_STATE_RECORDING) {
327                 _D("voice recording status is RECORDING");
328                 return true;
329         }
330
331         switch (pattern) {
332         case FEEDBACK_PATTERN_TAP:
333         case FEEDBACK_PATTERN_HOLD ... FEEDBACK_PATTERN_HW_HOLD:
334                 if (CHECK_SOUND(type) && !is_touch_sndstatus())
335                         return true;
336                 break;
337         case FEEDBACK_PATTERN_KEY0 ... FEEDBACK_PATTERN_KEY_BACK:
338                 if (CHECK_SOUND(type) && !is_keytone_sndstatus())
339                         return true;
340                 else if (CHECK_VIBRATION(type) && !feedbackstatus)
341                         return true;
342                 break;
343         case FEEDBACK_PATTERN_LOCK:
344         case FEEDBACK_PATTERN_UNLOCK:
345         case FEEDBACK_PATTERN_MOBILE_LOCK_SWIPE:
346         case FEEDBACK_PATTERN_MOBILE_UNLOCK_SWIPE:
347                 if (CHECK_SOUND(type) && !lock_sndstatus)
348                         return true;
349                 break;
350         default:
351                 break;
352         }
353         return false;
354 }
355
356 static int mobile_get_strength_type(int type, int pattern)
357 {
358         if (CHECK_SOUND(type)) {
359                 if (pattern == FEEDBACK_PATTERN_TAP)
360                         return VOLUME_TYPE_SYSTEM|VOLUME_GAIN_TOUCH;
361                 else if (pattern >= FEEDBACK_PATTERN_KEY0 && pattern <= FEEDBACK_PATTERN_KEY_BACK)
362                         return VOLUME_TYPE_SYSTEM|VOLUME_GAIN_DIALER;
363                 else if (pattern == FEEDBACK_PATTERN_VOLUME_KEY)
364                         return VOLUME_TYPE_RINGTONE;
365                 else if (camerastatus && shutter_sndstatus && pattern == FEEDBACK_PATTERN_MOBILE_SCREEN_CAPTURE)
366                         return VOLUME_TYPE_FIXED;
367                 else
368                         return VOLUME_TYPE_SYSTEM;
369         } else if (CHECK_VIBRATION(type)) {
370                 if (pattern >= FEEDBACK_PATTERN_MESSAGE &&
371                     pattern <= FEEDBACK_PATTERN_GENERAL)
372                         return noti_level * HAPTIC_FEEDBACK_STEP;
373                 else
374                         return vib_level * HAPTIC_FEEDBACK_STEP;
375         }
376
377         return -EINVAL;
378 }
379
380 static const struct profile_ops mobile_profile_ops = {
381         .profile               = "mobile",
382         .init                  = mobile_init,
383         .exit                  = mobile_exit,
384         .get_switched_pattern  = mobile_get_switched_pattern,
385         .get_always_alert_case = mobile_get_always_alert_case,
386         .get_always_off_case   = mobile_get_always_off_case,
387         .get_strength_type     = mobile_get_strength_type,
388         .max_type              = FEEDBACK_TYPE_MOBILE_END,
389         .max_pattern           = FEEDBACK_PATTERN_MOBILE_END,
390         .str_type              = mobile_str_type,
391         .str_pattern           = mobile_str_pattern,
392 };
393
394 PROFILE_OPS_REGISTER(&mobile_profile_ops);