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

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: Addressing comments and nits. 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/file_util.h"
8 #include "base/files/file_path_watcher.h"
9 #include "content/public/browser/browser_thread.h"
10
11 namespace athena {
12
13 namespace {
14
15 // Path of the socket which the sensor daemon creates.
16 const char kSocketPath[] = "/dev/sensors/orientation";
17
18 // Threshold after which to rotate in a given direction.
19 const int kGravityThreshold = 6.0f;
20
21 // Minimum delay before triggering another orientation change.
22 const int kOrientationChangeDelayNS = 500000000;
23
24 enum {
25 SENSOR_ACCELEROMETER,
26 SENSOR_LIGHT,
27 SENSOR_PROXIMITY
28 };
29
30 // A sensor event from the device.
31 struct DeviceSensorEvent {
32 // The type of event from the enum above.
33 int32_t type;
34
35 // The time in nanoseconds at which the event happened.
36 int64_t timestamp;
37
38 union {
39 // Accelerometer X,Y,Z values in SI units (m/s^2) including gravity.
40 // The orientation is described at
41 // http://www.html5rocks.com/en/tutorials/device/orientation/.
42 float data[3];
43
44 // Ambient (room) temperature in degrees Celcius.
45 float temperature;
46
47 // Proximity sensor distance in centimeters.
48 float distance;
49
50 // Ambient light level in SI lux units.
51 float light;
52 };
53 };
54
55 } // namespace
56
57 OrientationController::OrientationController()
58 : DeviceSocketListener(kSocketPath, sizeof(DeviceSensorEvent)),
59 last_orientation_change_time_(0),
60 weak_factory_(this) {
61 base::FilePath socket_path(kSocketPath);
62 if (base::PathExists(socket_path)) {
63 StartListening();
64 } else {
65 // Watch for socket to be created if it doesn't already exist.
66 watcher_.reset(new base::FilePathWatcher);
67 watcher_->Watch(socket_path, false,
68 base::Bind(&OrientationController::OnFilePathChanged,
69 weak_factory_.GetWeakPtr()));
70 }
71 }
72
73 OrientationController::~OrientationController() {
74 }
75
76 void OrientationController::OnDataAvailableOnIO(const void* data) {
77 const DeviceSensorEvent* event =
78 static_cast<const DeviceSensorEvent*>(data);
79 if (event->type != SENSOR_ACCELEROMETER)
80 return;
81
82 float gravity_x = event->data[0];
83 float gravity_y = event->data[1];
84 gfx::Display::Rotation rotation;
85 if (gravity_x < -kGravityThreshold) {
86 rotation = gfx::Display::ROTATE_270;
87 } else if (gravity_x > kGravityThreshold) {
88 rotation = gfx::Display::ROTATE_90;
89 } else if (gravity_y < -kGravityThreshold) {
90 rotation = gfx::Display::ROTATE_180;
91 } else if (gravity_y > kGravityThreshold) {
92 rotation = gfx::Display::ROTATE_0;
93 } else {
94 // No rotation as gravity threshold was not hit.
95 return;
96 }
97
98 if (rotation == current_rotation_ ||
99 event->timestamp - last_orientation_change_time_ <
100 kOrientationChangeDelayNS) {
101 return;
102 }
103
104 last_orientation_change_time_ = event->timestamp;
105 current_rotation_ = rotation;
106
107 // TODO(flackr): Avoid callbacks using unretained pointers. This could
108 // technically call RotateOnUI after OrientationController has destructed. We
109 // should instead use callbacks with weak pointers similar to
110 // chromeos/accelerometer/accelerometer_reader.cc.
111 content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
112 base::Bind(&OrientationController::RotateOnUI,
113 base::Unretained(this), rotation));
114 }
115
116 void OrientationController::RotateOnUI(gfx::Display::Rotation rotation) {
117 ScreenManager::Get()->SetRotation(rotation);
118 }
119
120 void OrientationController::OnFilePathChanged(const base::FilePath& path,
121 bool error) {
122 if (error)
123 return;
124
125 StartListening();
126 watcher_.reset();
127 }
128
129 } // namespace athena
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698