Initialize Tizen 2.3
[framework/system/deviced.git] / src / display / smartstay.c
1 /*
2  * deviced
3  *
4  * Copyright (c) 2012 - 2013 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 <stdbool.h>
21 #include <stdio.h>
22 #include <stdlib.h>
23 #include <dlfcn.h>
24
25 #include "util.h"
26 #include "core.h"
27 #include "display-ops.h"
28 #include "core/common.h"
29 #include "core/device-handler.h"
30
31 #define SMART_STAY      2
32 #define SMART_DETECTION_LIB "/usr/lib/sensor_framework/libsmart_detection.so"
33 #define CB_TIMEOUT      3 /* seconds */
34 #define OCCUPIED_FAIL   -2
35
36 typedef void (*detection_cb)(int result, void *data);
37
38 static void *detect_handle = NULL;
39 static int (*get_detection)(detection_cb callback, int type, void* user_data1, void* user_data2);
40 static bool block_state = EINA_FALSE;
41 static bool cb_state = EINA_FALSE;
42 static Ecore_Timer *cb_timeout_id = NULL;
43
44 static void init_smart_lib(void)
45 {
46         detect_handle = dlopen(SMART_DETECTION_LIB, RTLD_LAZY);
47
48         if (!detect_handle) {
49                 _E("dlopen error");
50         } else {
51                 get_detection = (int (*)(detection_cb, int, void *, void *))
52                     dlsym(detect_handle, "get_smart_detection");
53
54                 if (!get_detection) {
55                         _E("dl_sym fail");
56                         dlclose(detect_handle);
57                         detect_handle = NULL;
58                 }
59         }
60 }
61
62 static Eina_Bool check_cb_state(void *data)
63 {
64         struct state *st;
65         int next_state;
66         int user_data = (int)(data);
67
68         cb_timeout_id = NULL;
69
70         if (cb_state) {
71                 _I("smart detection cb is already working!");
72                 return ECORE_CALLBACK_CANCEL;
73         }
74
75         if (block_state) {
76                 _I("input event occur, smart detection is ignored!");
77                 block_state = EINA_FALSE;
78                 return ECORE_CALLBACK_CANCEL;
79         }
80
81         if (user_data < S_START || user_data > S_LCDOFF) {
82                 _E("next state is wrong [%d], set to [%d]",
83                     user_data, S_NORMAL);
84                 user_data = S_NORMAL;
85         }
86
87         _I("smart detection cb is failed, goes to [%d]", user_data);
88
89         next_state = user_data;
90         pm_old_state = pm_cur_state;
91         pm_cur_state = next_state;
92
93         st = &states[pm_cur_state];
94         if (st->action)
95                 st->action(st->timeout);
96
97         if (pm_cur_state == S_LCDOFF)
98                 update_lcdoff_source(VCONFKEY_PM_LCDOFF_BY_TIMEOUT);
99
100         return ECORE_CALLBACK_CANCEL;
101 }
102
103 static void detection_callback(int degree, void *data)
104 {
105         struct state *st;
106         int next_state;
107         int user_data = (int)(data);
108
109         cb_state = EINA_TRUE;
110
111         if (block_state) {
112                 _I("input event occur, face detection is ignored!");
113                 block_state = EINA_FALSE;
114                 return;
115         }
116
117         if (!get_hallic_open()) {
118                 _I("hallic is closed! Skip detection logic!");
119                 return;
120         }
121
122         _I("degree = [%d], user_data = [%d]", degree, user_data);
123
124         switch (degree)
125         {
126         case 270:
127         case 90:
128         case 180:
129         case 0:
130                 _I("face detection success, goes to [%d]",
131                     S_NORMAL);
132                 pm_old_state = pm_cur_state;
133                 pm_cur_state = S_NORMAL;
134                 break;
135         case OCCUPIED_FAIL:
136                 _I("camera is occupied, stay current state");
137                 break;
138         default:
139                 if (user_data < S_START || user_data > S_LCDOFF) {
140                         _E("next state is wrong [%d], set to [%d]",
141                             user_data, S_NORMAL);
142                         user_data = S_NORMAL;
143                 }
144
145                 next_state = user_data;
146
147                 pm_old_state = pm_cur_state;
148                 pm_cur_state = next_state;
149
150                 if (check_lcdoff_direct() == true)
151                         pm_cur_state = S_LCDOFF;
152
153                 _I("smart detection is failed, goto [%d]state", pm_cur_state);
154
155                 break;
156         }
157
158         st = &states[pm_cur_state];
159         if (st->action)
160                 st->action(st->timeout);
161
162         if (pm_cur_state == S_LCDOFF)
163                 update_lcdoff_source(VCONFKEY_PM_LCDOFF_BY_TIMEOUT);
164 }
165
166 static int check_face_detection(int evt, int pm_cur_state, int next_state)
167 {
168         int lock_state = EINA_FALSE;
169         int state;
170
171         if (cb_timeout_id) {
172                 ecore_timer_del(cb_timeout_id);
173                 cb_timeout_id = NULL;
174         }
175
176         if (evt == EVENT_INPUT) {
177                 block_state = EINA_TRUE;
178                 return EINA_FALSE;
179         }
180         block_state = EINA_FALSE;
181
182         if (evt != EVENT_TIMEOUT)
183                 return EINA_FALSE;
184
185         if (pm_cur_state != S_NORMAL)
186                 return EINA_FALSE;
187
188         if (!get_detection) {
189                 init_smart_lib();
190                 if (!get_detection) {
191                         _E("%s load failed!", SMART_DETECTION_LIB);
192                         return EINA_FALSE;
193                 }
194         }
195
196         state = get_detection(detection_callback, SMART_STAY, NULL, (void*)next_state);
197
198         if (state != 0)
199                 _E("get detection FAIL [%d]", state);
200         else
201                 _I("get detection success");
202
203         cb_state = EINA_FALSE;
204         cb_timeout_id = ecore_timer_add(CB_TIMEOUT,
205                             (Ecore_Task_Cb)check_cb_state, (void*)next_state);
206         return EINA_TRUE;
207 }
208
209 static void smartstay_init(void *data)
210 {
211         display_info.face_detection = check_face_detection;
212 }
213
214 static void smartstay_exit(void *data)
215 {
216         if (detect_handle) {
217                 dlclose(detect_handle);
218                 detect_handle = NULL;
219                 _D("detect handle is closed!");
220         }
221         get_detection = NULL;
222         display_info.face_detection = NULL;
223 }
224
225 static const struct display_ops display_smartstay_ops = {
226         .name     = "smartstay",
227         .init     = smartstay_init,
228         .exit     = smartstay_exit,
229 };
230
231 DISPLAY_OPS_REGISTER(&display_smartstay_ops)
232