2 * Copyright (c) 2013 Samsung Electronics Co., Ltd. All rights reserved.
4 * This file is a modified version of BSD licensed file and
5 * licensed under the Flora License, Version 1.1 (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://floralicense.org/license/
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.
17 * Please, see the COPYING file for the original copyright owner and
27 #include <sensor_internal_deprecated.h>
28 #include <sensor_auto_rotation.h>
31 #include "e_devicemgr_privates.h"
32 #include "rotation_devicemgr.h"
36 #define LOG_TAG "E17_EXTRA_MODULES"
38 typedef struct _E_DM_Sensor_Rotation E_DM_Sensor_Rotation;
40 struct _E_DM_Sensor_Rotation
44 enum auto_rotation_state state;
45 Ecore_Timer *retry_timer;
51 /* static global variables */
52 static E_DM_Sensor_Rotation rot;
53 static Ecore_X_Atom ATOM_DEVICE_ROTATION_ANGLE = 0;
55 /* local subsystem functions */
56 static Eina_Bool _sensor_connect(void);
57 static Eina_Bool _sensor_disconnect(void);
58 static Eina_Bool _sensor_connect_retry_timeout(void *data);
59 static void _sensor_rotation_changed_cb(unsigned int event_type, sensor_event_data_t *event, void *data);
60 static void _vconf_cb_lock_change(keynode_t *node, void *data);
61 static void _sensor_rotation_set(int ang);
62 static int _ang_get(enum auto_rotation_state state);
64 /* externally accessible functions */
66 e_mod_sf_rotation_init(void)
69 Eina_Bool res = EINA_FALSE;
71 rot.connected = EINA_FALSE;
73 res = _sensor_connect();
76 r = vconf_get_bool(VCONFKEY_SETAPPL_AUTO_ROTATE_SCREEN_BOOL, &lock);
80 "ERR! AUTO_ROTATE_SCREEN_BOOL get failed. "
81 "r:%d lock:%d", r, lock);
86 vconf_notify_key_changed(VCONFKEY_SETAPPL_AUTO_ROTATE_SCREEN_BOOL,
87 _vconf_cb_lock_change,
90 "AUTO_ROTATE_SCREEN_BOOL get succeeded. "
91 "lock:%d rot.locK%d", lock, rot.lock);
94 _sensor_rotation_set(0);
99 e_mod_sf_rotation_deinit(void)
101 vconf_ignore_key_changed(VCONFKEY_SETAPPL_AUTO_ROTATE_SCREEN_BOOL, _vconf_cb_lock_change);
102 _sensor_disconnect();
106 /* local subsystem functions */
108 _sensor_connect(void)
111 if (rot.connected) return EINA_TRUE;
115 ecore_timer_del(rot.retry_timer);
116 rot.retry_timer = NULL;
120 rot.started = EINA_FALSE;
122 h = sf_connect(AUTO_ROTATION_SENSOR);
125 ELB(ELBT_ROT, "ERR! sf_connect failed", h);
129 r = sf_register_event(h, AUTO_ROTATION_EVENT_CHANGE_STATE,
130 NULL, _sensor_rotation_changed_cb, NULL);
133 ELB(ELBT_ROT, "ERR! sf_register_event failed", r);
141 ELB(ELBT_ROT, "ERR! sf_start failed", r);
142 sf_unregister_event(h, AUTO_ROTATION_EVENT_CHANGE_STATE);
148 rot.started = EINA_TRUE;
150 rot.lock = EINA_FALSE;
151 rot.connected = EINA_TRUE;
153 ELB(ELBT_ROT, "sf_connect succeeded", h);
157 if (rot.retry_count <= 20)
159 rot.retry_timer = ecore_timer_add(10.0f,
160 _sensor_connect_retry_timeout,
167 _sensor_disconnect(void)
170 if (!rot.connected) return EINA_TRUE;
172 rot.lock = EINA_FALSE;
176 ecore_timer_del(rot.retry_timer);
177 rot.retry_timer = NULL;
184 ELB(ELBT_ROT, "ERR! invalid handle", rot.handle);
190 r = sf_unregister_event(rot.handle,
191 AUTO_ROTATION_EVENT_CHANGE_STATE);
194 ELB(ELBT_ROT, "ERR! sf_unregister_event failed", r);
197 r = sf_stop(rot.handle);
200 ELB(ELBT_ROT, "ERR! sf_stop failed", r);
203 rot.started = EINA_TRUE;
206 r = sf_disconnect(rot.handle);
209 ELB(ELBT_ROT, "ERR! sf_disconnect failed", r);
214 rot.connected = EINA_FALSE;
215 ELB(ELBT_ROT, "sf_disconnect succeeded", NULL);
222 _sensor_connect_retry_timeout(void *data)
225 Eina_Bool res = EINA_FALSE;
229 ecore_timer_del(rot.retry_timer);
230 rot.retry_timer = NULL;
233 ELB(ELBT_ROT, "retrying to connect sensor", rot.retry_count);
234 res = _sensor_connect();
237 r = vconf_get_bool(VCONFKEY_SETAPPL_AUTO_ROTATE_SCREEN_BOOL, &lock);
241 "ERR! AUTO_ROTATE_SCREEN_BOOL get failed. "
242 "r:%d lock:%d", r, lock);
247 vconf_notify_key_changed(VCONFKEY_SETAPPL_AUTO_ROTATE_SCREEN_BOOL,
248 _vconf_cb_lock_change,
251 "AUTO_ROTATE_SCREEN_BOOL get succeeded. "
252 "lock:%d rot.locK%d", lock, rot.lock);
256 return ECORE_CALLBACK_CANCEL;
260 _ang_get(enum auto_rotation_state state)
262 E_Devicemgr_Config_Rotation *cr = NULL;
264 int ang = -1, res = -1;
266 /* change CW (SensorFW) to CCW(EFL) */
269 case AUTO_ROTATION_DEGREE_0: ang = 0; break;
270 case AUTO_ROTATION_DEGREE_90: ang = 270; break;
271 case AUTO_ROTATION_DEGREE_180: ang = 180; break;
272 case AUTO_ROTATION_DEGREE_270: ang = 90; break;
274 ELB(ELBT_ROT, "Unknown state", state);
278 EINA_LIST_FOREACH(_e_devicemgr_cfg->rotation, l, cr)
281 if (cr->angle == ang)
292 enum auto_rotation_state
298 return AUTO_ROTATION_DEGREE_0;
300 return AUTO_ROTATION_DEGREE_90;
302 return AUTO_ROTATION_DEGREE_180;
304 return AUTO_ROTATION_DEGREE_270;
306 return AUTO_ROTATION_DEGREE_UNKNOWN;
311 _sensor_rotation_changed_cb(unsigned int event_type,
312 sensor_event_data_t *event,
315 enum auto_rotation_state state;
316 E_Manager *m = e_manager_current_get();
317 E_Zone *zone = e_util_zone_current_get(m);
320 if (rot.lock) return;
322 if (event_type != AUTO_ROTATION_EVENT_CHANGE_STATE) return;
325 state = *((enum auto_rotation_state*)(event->event_data));
327 ang = _ang_get(state);
329 SECURE_SLOGD("[ROTATION] SENSOR ROT_CHANGE, state:%d angle:%d", state, ang);
330 ELBF(ELBT_ROT, 0, 0, "ROT_EV state:%d angle:%d", state, ang);
332 e_zone_rotation_set(zone, ang);
335 _sensor_rotation_set(ang);
339 _vconf_cb_lock_change(keynode_t *node,
344 int lock = 0, z_ang = -1, ang = -1;
345 Eina_Bool res = EINA_FALSE;
348 ELB(ELBT_ROT, "ERR! node is NULL", 0);
352 m = e_manager_current_get();
353 if (m) zone = e_util_zone_current_get(m);
355 lock = !vconf_keynode_get_bool(node);
356 ELBF(ELBT_ROT, 0, 0, "ROT LOCK: %d->%d", rot.lock, lock);
360 // disconnect sensor for reducing the current sinking.
361 _sensor_disconnect();
362 if (zone) e_zone_rotation_set(zone, 0);
363 rot.state = AUTO_ROTATION_DEGREE_0;
367 // connect sensor for auto rotation.
368 res = _sensor_connect();
369 ELB(ELBT_ROT, "_sensor_connect() res", res);
373 if (sf_get_data(rot.handle, AUTO_ROTATION_BASE_DATA_SET, &data) < 0)
375 ELB(ELBT_ROT, "ERR! getting rotation failed", NULL);
379 ang = _ang_get(data.values[0]);
380 if (zone) z_ang = e_zone_rotation_get(zone);
381 if ((ang != -1) && (ang != z_ang))
383 if (zone) e_zone_rotation_set(zone, ang);
384 rot.state = _state_get(ang);
385 _sensor_rotation_set(ang);
395 _sensor_rotation_set(int ang)
397 Ecore_X_Window root = ecore_x_window_root_first_get();
398 unsigned int val = (unsigned int)ang;
400 if (!ATOM_DEVICE_ROTATION_ANGLE)
401 ATOM_DEVICE_ROTATION_ANGLE = ecore_x_atom_get("_E_DEVICE_ROTATION_ANGLE");
403 ecore_x_window_prop_card32_set(root,
404 ATOM_DEVICE_ROTATION_ANGLE,