Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(27)

Side by Side Diff: athena/system/orientation_controller.cc

Issue 431183003: Rotate screen in response to accelerator or device orientation sensors. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Use the FILE thread for IO Created 6 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright 2014 The Chromium Authors. 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 "athena/screen/public/screen_manager.h"
6 #include "athena/system/orientation_controller.h"
7 #include "base/bind.h"
8 #include "base/file_util.h"
9 #include "base/files/file_path_watcher.h"
10 #include "base/message_loop/message_loop.h"
11 #include "base/task_runner.h"
12
13 namespace athena {
14
15 namespace {
16
17 // Path of the socket which the sensor daemon creates.
18 const char kSocketPath[] = "/dev/sensors/orientation";
19
20 // Threshold after which to rotate in a given direction.
21 const int kGravityThreshold = 6.0f;
22
23 // Minimum delay before triggering another orientation change.
24 const int kOrientationChangeDelayNS = 500000000;
25
26 enum {
oshima 2014/08/13 22:46:34 SensorType ? I know it's not necessary, but it's i
flackr 2014/08/14 17:29:51 Done.
27 SENSOR_ACCELEROMETER,
28 SENSOR_LIGHT,
29 SENSOR_PROXIMITY
30 };
31
32 // A sensor event from the device.
33 struct DeviceSensorEvent {
34 // The type of event from the enum above.
35 int32_t type;
36
37 // The time in nanoseconds at which the event happened.
38 int64_t timestamp;
39
40 union {
41 // Accelerometer X,Y,Z values in SI units (m/s^2) including gravity.
42 // The orientation is described at
43 // http://www.html5rocks.com/en/tutorials/device/orientation/.
44 float data[3];
45
46 // Ambient (room) temperature in degrees Celcius.
47 float temperature;
48
49 // Proximity sensor distance in centimeters.
50 float distance;
51
52 // Ambient light level in SI lux units.
53 float light;
54 };
55 };
56
57 } // namespace
58
59 OrientationController::OrientationController(
60 scoped_refptr<base::TaskRunner> io_task_runner)
61 : DeviceSocketListener(kSocketPath, sizeof(DeviceSensorEvent)),
62 last_orientation_change_time_(0),
63 weak_factory_(this) {
64 CHECK(base::MessageLoopForUI::current());
65 ui_task_runner_ = base::MessageLoop::current()->task_runner();
oshima 2014/08/13 22:46:34 nit: base::MessageLoopForUI::current()
flackr 2014/08/14 17:29:51 Done.
66 if (base::PathExists(base::FilePath(kSocketPath))) {
oshima 2014/08/13 22:46:34 Sorry I missed that in the previous review, but th
flackr 2014/08/14 17:29:51 Done.
67 StartListening();
68 } else {
69 io_task_runner->PostTask(FROM_HERE, base::Bind(
70 &OrientationController::WatchForSocketPathOnIO,
71 make_scoped_refptr<OrientationController>(this)));
72 }
73 }
74
75 OrientationController::~OrientationController() {
76 }
77
78 void OrientationController::WatchForSocketPathOnIO() {
79 CHECK(base::MessageLoopForIO::current());
80 watcher_.reset(new base::FilePathWatcher);
81 watcher_->Watch(base::FilePath(kSocketPath), false,
82 base::Bind(&OrientationController::OnFilePathChangedOnIO,
83 make_scoped_refptr<OrientationController>(this)));
84 }
85
86 void OrientationController::OnFilePathChangedOnIO(const base::FilePath& path,
87 bool error) {
88 watcher_.reset();
89 if (error) {
90 return;
91 }
oshima 2014/08/13 22:46:34 nuke {}
flackr 2014/08/14 17:29:51 Done.
92
93 ui_task_runner_->PostTask(FROM_HERE,
94 base::Bind(&OrientationController::StartListening,
95 make_scoped_refptr<OrientationController>(this)));
96 }
97
98 void OrientationController::OnDataAvailableOnIO(const void* data) {
99 const DeviceSensorEvent* event =
100 static_cast<const DeviceSensorEvent*>(data);
101 if (event->type != SENSOR_ACCELEROMETER)
102 return;
103
104 float gravity_x = event->data[0];
105 float gravity_y = event->data[1];
106 gfx::Display::Rotation rotation;
107 if (gravity_x < -kGravityThreshold) {
108 rotation = gfx::Display::ROTATE_270;
109 } else if (gravity_x > kGravityThreshold) {
110 rotation = gfx::Display::ROTATE_90;
111 } else if (gravity_y < -kGravityThreshold) {
112 rotation = gfx::Display::ROTATE_180;
113 } else if (gravity_y > kGravityThreshold) {
114 rotation = gfx::Display::ROTATE_0;
115 } else {
116 // No rotation as gravity threshold was not hit.
117 return;
118 }
119
120 if (rotation == current_rotation_ ||
121 event->timestamp - last_orientation_change_time_ <
122 kOrientationChangeDelayNS) {
123 return;
124 }
125
126 last_orientation_change_time_ = event->timestamp;
127 current_rotation_ = rotation;
128 ui_task_runner_->PostTask(FROM_HERE,
129 base::Bind(&OrientationController::RotateOnUI,
130 make_scoped_refptr<OrientationController>(this), rotation));
131 }
132
133 void OrientationController::RotateOnUI(gfx::Display::Rotation rotation) {
134 ScreenManager* screen_manager = ScreenManager::Get();
135 // Since this is called from the IO thread, the screen manager may no longer
136 // exist.
137 if (screen_manager)
138 screen_manager->SetRotation(rotation);
139 }
140
141 } // namespace athena
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698