Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / xwalk / tizen / mobile / sensor / tizen_platform_sensor.cc
1 // Copyright (c) 2013 Intel Corporation. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "xwalk/tizen/mobile/sensor/tizen_platform_sensor.h"
6
7 #include <math.h>
8 #include <string>
9
10 #include "base/files/file_path.h"
11 #include "base/logging.h"
12
13 namespace  {
14
15 // Make the class depend on gfx::Display to avoid the hack below:
16
17 #if defined(OS_TIZEN_MOBILE)
18 int rotation_start = 0;  // Default is portrait primary.
19 #else
20 int rotation_start = -1;  // Default is landscape primary.
21 #endif
22
23 blink::WebScreenOrientationType ToScreenOrientation(
24     int rotation) {
25   rotation = (rotation + rotation_start) % 4;
26
27   blink::WebScreenOrientationType r = blink::WebScreenOrientationUndefined;
28   switch (rotation) {
29     case ROTATION_EVENT_0:
30       r = blink::WebScreenOrientationPortraitPrimary;
31       break;
32     case ROTATION_EVENT_90:
33       r = blink::WebScreenOrientationLandscapeSecondary;
34       break;
35     case ROTATION_EVENT_180:
36       r = blink::WebScreenOrientationPortraitSecondary;
37       break;
38     case ROTATION_EVENT_270:
39       r = blink::WebScreenOrientationLandscapePrimary;
40       break;
41   }
42   return r;
43 }
44
45 }  // namespace
46
47 namespace xwalk {
48
49 TizenPlatformSensor::TizenPlatformSensor()
50     : auto_rotation_enabled_(true),
51       accel_handle_(-1),
52       gyro_handle_(-1) {
53 }
54
55 TizenPlatformSensor::~TizenPlatformSensor() {
56 }
57
58 bool TizenPlatformSensor::Initialize() {
59   // If the sensors couldn't be able to connect normally for the first time,
60   // it indicates that the platform doesn't support these sensors.
61   // Set |initialized_| true to make this function is called only
62   // once and avoid connecting to platform sensors repeatedly.
63   initialized_ = true;
64
65   unsigned long rotation;  // NOLINT
66   if (!sf_check_rotation(&rotation)) {
67     last_orientation_ = ToScreenOrientation(static_cast<int>(rotation));
68   }
69
70   int value;
71   if (!vconf_get_bool(VCONFKEY_SETAPPL_AUTO_ROTATE_SCREEN_BOOL, &value)) {
72     auto_rotation_enabled_ = (value != 0);
73     vconf_notify_key_changed(VCONFKEY_SETAPPL_AUTO_ROTATE_SCREEN_BOOL,
74                              OnAutoRotationEnabledChanged, this);
75   }
76
77   accel_handle_ = sf_connect(ACCELEROMETER_SENSOR);
78   if (accel_handle_ >= 0) {
79     if (sf_register_event(accel_handle_,
80             ACCELEROMETER_EVENT_ROTATION_CHECK, NULL,
81             OnEventReceived, this) < 0 ||
82         sf_register_event(accel_handle_,
83             ACCELEROMETER_EVENT_RAW_DATA_REPORT_ON_TIME, NULL,
84             OnEventReceived, this) < 0 ||
85         sf_start(accel_handle_, 0) < 0) {
86       LOG(ERROR) << "Register accelerometer sensor event failed";
87
88       sf_unregister_event(accel_handle_, ACCELEROMETER_EVENT_ROTATION_CHECK);
89       sf_unregister_event(accel_handle_,
90                           ACCELEROMETER_EVENT_RAW_DATA_REPORT_ON_TIME);
91       sf_disconnect(accel_handle_);
92       accel_handle_ = -1;
93     }
94   } else {
95     LOG(ERROR) << "Connection to accelerometer sensor failed";
96   }
97
98   gyro_handle_ = sf_connect(GYROSCOPE_SENSOR);
99   if (gyro_handle_ >= 0) {
100     if (sf_register_event(gyro_handle_, GYROSCOPE_EVENT_RAW_DATA_REPORT_ON_TIME,
101             NULL, OnEventReceived, this) < 0 || sf_start(gyro_handle_, 0) < 0) {
102       LOG(ERROR) << "Register gyroscope sensor event failed";
103       sf_unregister_event(gyro_handle_,
104           GYROSCOPE_EVENT_RAW_DATA_REPORT_ON_TIME);
105       sf_disconnect(gyro_handle_);
106       gyro_handle_ = -1;
107     }
108   } else {
109     LOG(ERROR) << "Connection to gyroscope sensor failed";
110   }
111
112   return (accel_handle_ >= 0 || gyro_handle_ >= 0);
113 }
114
115 void TizenPlatformSensor::Finish() {
116   if (accel_handle_ >= 0) {
117     sf_stop(accel_handle_);
118     sf_unregister_event(accel_handle_, ACCELEROMETER_EVENT_ROTATION_CHECK);
119     sf_unregister_event(accel_handle_,
120         ACCELEROMETER_EVENT_RAW_DATA_REPORT_ON_TIME);
121     sf_disconnect(accel_handle_);
122     accel_handle_ = -1;
123   }
124
125   if (gyro_handle_ >=0) {
126     sf_stop(gyro_handle_);
127     sf_unregister_event(gyro_handle_, GYROSCOPE_EVENT_RAW_DATA_REPORT_ON_TIME);
128     sf_disconnect(gyro_handle_);
129     gyro_handle_ = -1;
130   }
131
132   vconf_ignore_key_changed(VCONFKEY_SETAPPL_AUTO_ROTATE_SCREEN_BOOL,
133       OnAutoRotationEnabledChanged);
134 }
135
136 void TizenPlatformSensor::OnEventReceived(unsigned int event_type,
137                                           sensor_event_data_t* event_data,
138                                           void* udata) {
139   TizenPlatformSensor* self = reinterpret_cast<TizenPlatformSensor*>(udata);
140
141   sensor_data_t* data =
142       reinterpret_cast<sensor_data_t*>(event_data->event_data);
143   size_t last = event_data->event_data_size / sizeof(sensor_data_t) - 1;
144
145   switch (event_type) {
146     case ACCELEROMETER_EVENT_ROTATION_CHECK: {
147       if (!self->auto_rotation_enabled_)
148         return;
149       int value = *reinterpret_cast<int*>(event_data->event_data);
150       self->OnScreenOrientationChanged(ToScreenOrientation(value));
151       break;
152     }
153     case ACCELEROMETER_EVENT_RAW_DATA_REPORT_ON_TIME: {
154       sensor_data_t linear;
155       linear.values[0] = linear.values[1] = linear.values[2] = FP_NAN;
156       sf_get_data(self->accel_handle_,
157           ACCELEROMETER_LINEAR_ACCELERATION_DATA_SET, &linear);
158       self->OnAccelerationChanged(
159           data[last].values[0], data[last].values[1], data[last].values[2],
160           linear.values[0], linear.values[1], linear.values[2]);
161
162       sensor_data_t orient;
163       if (sf_get_data(self->accel_handle_,
164               ACCELEROMETER_ORIENTATION_DATA_SET, &orient) >= 0) {
165         self->OnOrientationChanged(
166             orient.values[0], orient.values[1], orient.values[2]);
167       }
168       break;
169     }
170     case GYROSCOPE_EVENT_RAW_DATA_REPORT_ON_TIME: {
171       self->OnRotationRateChanged(
172           data[last].values[0], data[last].values[1], data[last].values[2]);
173     }
174   }
175 }
176
177 void TizenPlatformSensor::OnAutoRotationEnabledChanged(
178     keynode_t* node, void* udata) {
179   TizenPlatformSensor* self = reinterpret_cast<TizenPlatformSensor*>(udata);
180
181   self->auto_rotation_enabled_ = (vconf_keynode_get_bool(node) != 0);
182
183   unsigned long value;  // NOLINT
184   if (!self->auto_rotation_enabled_) {
185     // Change orientation to initial platform orientation when disabled.
186     self->OnScreenOrientationChanged(
187         ToScreenOrientation(ROTATION_EVENT_0));
188   } else if (self->auto_rotation_enabled_ && !sf_check_rotation(&value)) {
189     self->OnScreenOrientationChanged(
190         ToScreenOrientation(static_cast<int>(value)));
191   }
192 }
193
194 }  // namespace xwalk