Commit b34f096d authored by flackr's avatar flackr Committed by Commit bot

Reland "Use chromeos accelerometer reader and support only lid accelerometer....

Reland "Use chromeos accelerometer reader and support only lid accelerometer. (patchset #3 id:60001 of https://codereview.chromium.org/574113002/)"

Relands commit and fixes compiler error.

TBR=oshima,derat

BUG=380831
TEST=Glimmer/clapper still work, manually tested not having a base accelerometer.

Review URL: https://codereview.chromium.org/576113002

Cr-Commit-Position: refs/heads/master@{#295285}
parent 4264d2c4
...@@ -18,7 +18,7 @@ void AccelerometerController::Initialize( ...@@ -18,7 +18,7 @@ void AccelerometerController::Initialize(
scoped_refptr<base::TaskRunner> blocking_task_runner) { scoped_refptr<base::TaskRunner> blocking_task_runner) {
#if defined(OS_CHROMEOS) #if defined(OS_CHROMEOS)
reader_.reset( reader_.reset(
new chromeos::AccelerometerReader(blocking_task_runner.get(), this)); new chromeos::AccelerometerReader(blocking_task_runner, this));
#endif #endif
} }
......
...@@ -88,8 +88,6 @@ ...@@ -88,8 +88,6 @@
'screen/screen_manager_impl.cc', 'screen/screen_manager_impl.cc',
'system/background_controller.cc', 'system/background_controller.cc',
'system/background_controller.h', 'system/background_controller.h',
'system/device_socket_listener.cc',
'system/device_socket_listener.h',
'system/network_selector.cc', 'system/network_selector.cc',
'system/network_selector.h', 'system/network_selector.h',
'system/orientation_controller.cc', 'system/orientation_controller.cc',
......
...@@ -83,7 +83,7 @@ class VirtualKeyboardObserver : public keyboard::KeyboardControllerObserver { ...@@ -83,7 +83,7 @@ class VirtualKeyboardObserver : public keyboard::KeyboardControllerObserver {
DISALLOW_COPY_AND_ASSIGN(VirtualKeyboardObserver); DISALLOW_COPY_AND_ASSIGN(VirtualKeyboardObserver);
}; };
void StartAthenaEnv(scoped_refptr<base::TaskRunner> file_runner) { void StartAthenaEnv(scoped_refptr<base::TaskRunner> blocking_task_runner) {
athena::AthenaEnv::Create(); athena::AthenaEnv::Create();
base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
...@@ -109,7 +109,7 @@ void StartAthenaEnv(scoped_refptr<base::TaskRunner> file_runner) { ...@@ -109,7 +109,7 @@ void StartAthenaEnv(scoped_refptr<base::TaskRunner> file_runner) {
athena::InputManager::Create()->OnRootWindowCreated(root_window); athena::InputManager::Create()->OnRootWindowCreated(root_window);
athena::ScreenManager::Create(root_window); athena::ScreenManager::Create(root_window);
athena::SystemUI::Create(file_runner); athena::SystemUI::Create(blocking_task_runner);
athena::WindowManager::Create(); athena::WindowManager::Create();
athena::AppRegistry::Create(); athena::AppRegistry::Create();
SetupBackgroundImage(); SetupBackgroundImage();
......
...@@ -142,8 +142,9 @@ class AthenaBrowserMainDelegate : public extensions::ShellBrowserMainDelegate { ...@@ -142,8 +142,9 @@ class AthenaBrowserMainDelegate : public extensions::ShellBrowserMainDelegate {
extension_system->LoadApp(app_absolute_dir); extension_system->LoadApp(app_absolute_dir);
} }
athena::StartAthenaEnv(content::BrowserThread::GetMessageLoopProxyForThread( athena::StartAthenaEnv(content::BrowserThread::GetBlockingPool()->
content::BrowserThread::FILE)); GetTaskRunnerWithShutdownBehavior(
base::SequencedWorkerPool::SKIP_ON_SHUTDOWN));
athena::ExtensionsDelegate::CreateExtensionsDelegateForShell(context); athena::ExtensionsDelegate::CreateExtensionsDelegateForShell(context);
athena::CreateVirtualKeyboardWithContext(context); athena::CreateVirtualKeyboardWithContext(context);
athena::StartAthenaSessionWithContext(context); athena::StartAthenaSessionWithContext(context);
......
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "athena/system/device_socket_listener.h"
#include <errno.h>
#include <map>
#include <sys/socket.h>
#include <sys/types.h>
#include <vector>
#include "base/bind.h"
#include "base/files/file_path.h"
#include "base/message_loop/message_loop.h"
#include "base/observer_list.h"
#include "base/stl_util.h"
#include "ipc/unix_domain_socket_util.h"
namespace athena {
namespace {
typedef ObserverList<DeviceSocketListener> DeviceSocketListeners;
// Reads from a device socket blocks of a particular size. When that amount of
// data is read DeviceSocketManager::OnDataAvailable is called on the singleton
// instance which then informs all of the listeners on that socket.
class DeviceSocketReader : public base::MessagePumpLibevent::Watcher {
public:
DeviceSocketReader(const std::string& socket_path,
size_t data_size)
: socket_path_(socket_path),
data_size_(data_size),
data_(new char[data_size]) {
}
virtual ~DeviceSocketReader() {}
private:
// Overidden from base::MessagePumpLibevent::Watcher.
virtual void OnFileCanReadWithoutBlocking(int fd) OVERRIDE;
virtual void OnFileCanWriteWithoutBlocking(int fd) OVERRIDE;
std::string socket_path_;
size_t data_size_;
scoped_ptr<char[]> data_;
DISALLOW_COPY_AND_ASSIGN(DeviceSocketReader);
};
class DeviceSocketManager;
DeviceSocketManager* device_socket_manager_instance_ = NULL;
// A singleton instance for managing all connections to sockets.
class DeviceSocketManager {
public:
static void Create(scoped_refptr<base::TaskRunner> file_task_runner) {
device_socket_manager_instance_ = new DeviceSocketManager(file_task_runner);
}
static void Shutdown() {
CHECK(device_socket_manager_instance_);
device_socket_manager_instance_->ScheduleDelete();
// Once scheduled to be deleted, no-one should be
// able to access it.
device_socket_manager_instance_ = NULL;
}
static DeviceSocketManager* GetInstanceUnsafe() {
return device_socket_manager_instance_;
}
static DeviceSocketManager* GetInstance() {
CHECK(device_socket_manager_instance_);
return device_socket_manager_instance_;
}
// If there isn't an existing connection to |socket_path|, then opens a
// connection to |socket_path| and starts listening for data. All listeners
// for |socket_path| receives data when data is available on the socket.
void StartListening(const std::string& socket_path,
size_t data_size,
DeviceSocketListener* listener);
// Removes |listener| from the list of listeners that receive data from
// |socket_path|. If this is the last listener, then this closes the
// connection to the socket.
void StopListening(const std::string& socket_path,
DeviceSocketListener* listener);
// Sends data to all the listeners registered to receive data from
// |socket_path|.
void OnDataAvailable(const std::string& socket_path,
const void* data);
// Notifies listeners of errors reading from the socket and closes it.
void OnError(const std::string& socket_path, int err);
void OnEOF(const std::string& socket_path);
private:
struct SocketData {
SocketData()
: fd(-1) {
}
int fd;
DeviceSocketListeners observers;
scoped_ptr<base::MessagePumpLibevent::FileDescriptorWatcher> controller;
scoped_ptr<DeviceSocketReader> watcher;
};
static void DeleteOnFILE(DeviceSocketManager* manager) { delete manager; }
DeviceSocketManager(scoped_refptr<base::TaskRunner> file_task_runner)
: file_task_runner_(file_task_runner) {}
~DeviceSocketManager() {
STLDeleteContainerPairSecondPointers(socket_data_.begin(),
socket_data_.end());
}
void ScheduleDelete();
void StartListeningOnFILE(const std::string& socket_path,
size_t data_size,
DeviceSocketListener* listener);
void StopListeningOnFILE(const std::string& socket_path,
DeviceSocketListener* listener);
void CloseSocket(const std::string& socket_path);
std::map<std::string, SocketData*> socket_data_;
scoped_refptr<base::TaskRunner> file_task_runner_;
DISALLOW_COPY_AND_ASSIGN(DeviceSocketManager);
};
////////////////////////////////////////////////////////////////////////////////
// DeviceSocketReader
void DeviceSocketReader::OnFileCanReadWithoutBlocking(int fd) {
ssize_t read_size = recv(fd, data_.get(), data_size_, 0);
if (read_size < 0) {
if (errno == EINTR)
return;
DeviceSocketManager::GetInstance()->OnError(socket_path_, errno);
return;
}
if (read_size == 0) {
DeviceSocketManager::GetInstance()->OnEOF(socket_path_);
return;
}
if (read_size != static_cast<ssize_t>(data_size_))
return;
DeviceSocketManager::GetInstance()->OnDataAvailable(socket_path_,
data_.get());
}
void DeviceSocketReader::OnFileCanWriteWithoutBlocking(int fd) {
NOTREACHED();
}
////////////////////////////////////////////////////////////////////////////////
// DeviceSocketManager
void DeviceSocketManager::StartListening(const std::string& socket_path,
size_t data_size,
DeviceSocketListener* listener) {
file_task_runner_->PostTask(
FROM_HERE,
base::Bind(&DeviceSocketManager::StartListeningOnFILE,
base::Unretained(this),
socket_path,
data_size,
listener));
}
void DeviceSocketManager::StopListening(const std::string& socket_path,
DeviceSocketListener* listener) {
file_task_runner_->PostTask(
FROM_HERE,
base::Bind(&DeviceSocketManager::StopListeningOnFILE,
base::Unretained(this),
socket_path,
listener));
}
void DeviceSocketManager::OnDataAvailable(const std::string& socket_path,
const void* data) {
CHECK_GT(socket_data_.count(socket_path), 0UL);
DeviceSocketListeners& listeners = socket_data_[socket_path]->observers;
FOR_EACH_OBSERVER(
DeviceSocketListener, listeners, OnDataAvailableOnFILE(data));
}
void DeviceSocketManager::CloseSocket(const std::string& socket_path) {
if (!socket_data_.count(socket_path))
return;
SocketData* socket_data = socket_data_[socket_path];
close(socket_data->fd);
delete socket_data;
socket_data_.erase(socket_path);
}
void DeviceSocketManager::OnError(const std::string& socket_path, int err) {
LOG(ERROR) << "Error reading from socket: " << socket_path << ": "
<< strerror(err);
CloseSocket(socket_path);
// TODO(flackr): Notify listeners that the socket was closed unexpectedly.
}
void DeviceSocketManager::OnEOF(const std::string& socket_path) {
LOG(ERROR) << "EOF reading from socket: " << socket_path;
CloseSocket(socket_path);
}
void DeviceSocketManager::StartListeningOnFILE(const std::string& socket_path,
size_t data_size,
DeviceSocketListener* listener) {
CHECK(file_task_runner_->RunsTasksOnCurrentThread());
SocketData* socket_data = NULL;
if (!socket_data_.count(socket_path)) {
int socket_fd = -1;
if (!IPC::CreateClientUnixDomainSocket(base::FilePath(socket_path),
&socket_fd)) {
LOG(ERROR) << "Error connecting to socket: " << socket_path;
return;
}
socket_data = new SocketData;
socket_data_[socket_path] = socket_data;
socket_data->fd = socket_fd;
socket_data->controller.reset(
new base::MessagePumpLibevent::FileDescriptorWatcher());
socket_data->watcher.reset(
new DeviceSocketReader(socket_path, data_size));
base::MessageLoopForIO::current()->WatchFileDescriptor(
socket_fd,
true,
base::MessageLoopForIO::WATCH_READ,
socket_data->controller.get(),
socket_data->watcher.get());
} else {
socket_data = socket_data_[socket_path];
}
socket_data->observers.AddObserver(listener);
}
void DeviceSocketManager::StopListeningOnFILE(const std::string& socket_path,
DeviceSocketListener* listener) {
if (!socket_data_.count(socket_path))
return; // Happens if unable to create a socket.
CHECK(file_task_runner_->RunsTasksOnCurrentThread());
DeviceSocketListeners& listeners = socket_data_[socket_path]->observers;
listeners.RemoveObserver(listener);
if (!listeners.might_have_observers()) {
// All listeners for this socket has been removed. Close the socket.
CloseSocket(socket_path);
}
}
void DeviceSocketManager::ScheduleDelete() {
// Schedule a task to delete on FILE thread because
// there may be a task scheduled on |file_task_runner_|.
file_task_runner_->PostTask(
FROM_HERE,
base::Bind(&DeleteOnFILE, base::Unretained(this)));
}
} // namespace
DeviceSocketListener::DeviceSocketListener(const std::string& socket_path,
size_t data_size)
: socket_path_(socket_path),
data_size_(data_size) {
}
DeviceSocketListener::~DeviceSocketListener() {
StopListening();
}
// static
void DeviceSocketListener::CreateSocketManager(
scoped_refptr<base::TaskRunner> file_task_runner) {
DeviceSocketManager::Create(file_task_runner);
}
// static
void DeviceSocketListener::ShutdownSocketManager() {
DeviceSocketManager::Shutdown();
}
void DeviceSocketListener::StartListening() {
DeviceSocketManager::GetInstance()->StartListening(socket_path_,
data_size_,
this);
}
void DeviceSocketListener::StopListening() {
DeviceSocketManager* instance = DeviceSocketManager::GetInstanceUnsafe();
if (instance)
instance->StopListening(socket_path_, this);
}
} // namespace athena
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef ATHENA_SYSTEM_DEVICE_SOCKET_LISTENER_H_
#define ATHENA_SYSTEM_DEVICE_SOCKET_LISTENER_H_
#include <string>
#include "base/basictypes.h"
#include "base/memory/ref_counted.h"
namespace base {
class TaskRunner;
}
namespace athena {
// This class reads device-data from a socket.
class DeviceSocketListener {
public:
DeviceSocketListener(const std::string& socket_parth,
size_t data_size);
virtual ~DeviceSocketListener();
static void CreateSocketManager(
scoped_refptr<base::TaskRunner> io_task_runner);
static void ShutdownSocketManager();
// This is called on the FILE thread when data is available on the socket.
// |data| is guaranteed to be of exactly |data_size| length. Note that the
// implementation must not mutate or free the data.
virtual void OnDataAvailableOnFILE(const void* data) = 0;
protected:
void StartListening();
void StopListening();
private:
const std::string socket_path_;
size_t data_size_;
DISALLOW_COPY_AND_ASSIGN(DeviceSocketListener);
};
} // namespace athena
#endif // ATHENA_SYSTEM_DEVICE_SOCKET_LISTENER_H_
...@@ -14,112 +14,34 @@ namespace athena { ...@@ -14,112 +14,34 @@ namespace athena {
namespace { namespace {
// Path of the socket which the sensor daemon creates.
const char kSocketPath[] = "/dev/sensors/orientation";
// Threshold after which to rotate in a given direction. // Threshold after which to rotate in a given direction.
const int kGravityThreshold = 6.0f; const int kGravityThreshold = 6.0f;
// Minimum delay before triggering another orientation change.
const int kOrientationChangeDelayNS = 500000000;
enum SensorType {
SENSOR_ACCELEROMETER,
SENSOR_LIGHT,
SENSOR_PROXIMITY
};
// A sensor event from the device.
struct DeviceSensorEvent {
// The type of event from the SensorType enum above.
int32_t type;
// The time in nanoseconds at which the event happened.
int64_t timestamp;
union {
// Accelerometer X,Y,Z values in SI units (m/s^2) including gravity.
// The orientation is described at
// http://www.html5rocks.com/en/tutorials/device/orientation/.
float data[3];
// Ambient (room) temperature in degrees Celcius.
float temperature;
// Proximity sensor distance in centimeters.
float distance;
// Ambient light level in SI lux units.
float light;
};
};
} // namespace } // namespace
OrientationController::OrientationController() OrientationController::OrientationController() {
: DeviceSocketListener(kSocketPath, sizeof(DeviceSensorEvent)),
last_orientation_change_time_(0),
shutdown_(false) {
CHECK(base::MessageLoopForUI::current());
ui_task_runner_ = base::MessageLoopForUI::current()->task_runner();
} }
void OrientationController::InitWith( void OrientationController::InitWith(
scoped_refptr<base::TaskRunner> file_task_runner) { scoped_refptr<base::TaskRunner> blocking_task_runner) {
file_task_runner_ = file_task_runner; accelerometer_reader_.reset(
file_task_runner->PostTask( new chromeos::AccelerometerReader(blocking_task_runner, this));
FROM_HERE,
base::Bind(&OrientationController::WatchForSocketPathOnFILE, this));
} }
OrientationController::~OrientationController() { OrientationController::~OrientationController() {
} }
void OrientationController::Shutdown() { void OrientationController::Shutdown() {
CHECK(file_task_runner_.get()); accelerometer_reader_.reset();
StopListening();
file_task_runner_->PostTask(
FROM_HERE,
base::Bind(&OrientationController::ShutdownOnFILE, this));
}
void OrientationController::ShutdownOnFILE() {
shutdown_ = true;
watcher_.reset();
} }
void OrientationController::WatchForSocketPathOnFILE() { void OrientationController::HandleAccelerometerUpdate(
CHECK(base::MessageLoopForIO::current()); const ui::AccelerometerUpdate& update) {
if (base::PathExists(base::FilePath(kSocketPath))) { if (!update.has(ui::ACCELEROMETER_SOURCE_SCREEN))
ui_task_runner_->PostTask(FROM_HERE,
base::Bind(&OrientationController::StartListening, this));
} else {
watcher_.reset(new base::FilePathWatcher);
watcher_->Watch(
base::FilePath(kSocketPath),
false,
base::Bind(&OrientationController::OnFilePathChangedOnFILE, this));
}
}
void OrientationController::OnFilePathChangedOnFILE(const base::FilePath& path,
bool error) {
watcher_.reset();
if (error || shutdown_)
return; return;
ui_task_runner_->PostTask(FROM_HERE, float gravity_x = update.get(ui::ACCELEROMETER_SOURCE_SCREEN).x();
base::Bind(&OrientationController::StartListening, this)); float gravity_y = update.get(ui::ACCELEROMETER_SOURCE_SCREEN).y();
}
void OrientationController::OnDataAvailableOnFILE(const void* data) {
const DeviceSensorEvent* event =
static_cast<const DeviceSensorEvent*>(data);
if (event->type != SENSOR_ACCELEROMETER)
return;
float gravity_x = event->data[0];
float gravity_y = event->data[1];
gfx::Display::Rotation rotation; gfx::Display::Rotation rotation;
if (gravity_x < -kGravityThreshold) { if (gravity_x < -kGravityThreshold) {
rotation = gfx::Display::ROTATE_270; rotation = gfx::Display::ROTATE_270;
...@@ -134,24 +56,11 @@ void OrientationController::OnDataAvailableOnFILE(const void* data) { ...@@ -134,24 +56,11 @@ void OrientationController::OnDataAvailableOnFILE(const void* data) {
return; return;
} }
if (rotation == current_rotation_ || if (rotation == current_rotation_)
event->timestamp - last_orientation_change_time_ <
kOrientationChangeDelayNS) {
return; return;
}
last_orientation_change_time_ = event->timestamp;
current_rotation_ = rotation; current_rotation_ = rotation;
ui_task_runner_->PostTask(FROM_HERE, ScreenManager::Get()->SetRotation(rotation);
base::Bind(&OrientationController::RotateOnUI, this, rotation));
}
void OrientationController::RotateOnUI(gfx::Display::Rotation rotation) {
ScreenManager* screen_manager = ScreenManager::Get();
// Since this is called from the FILE thread, the screen manager may no longer
// exist.
if (screen_manager)
screen_manager->SetRotation(rotation);
} }
} // namespace athena } // namespace athena
...@@ -5,16 +5,14 @@ ...@@ -5,16 +5,14 @@
#ifndef ATHENA_SYSTEM_ORIENTATION_CONTROLLER_H_ #ifndef ATHENA_SYSTEM_ORIENTATION_CONTROLLER_H_
#define ATHENA_SYSTEM_ORIENTATION_CONTROLLER_H_ #define ATHENA_SYSTEM_ORIENTATION_CONTROLLER_H_
#include "athena/system/device_socket_listener.h"
#include "base/macros.h" #include "base/macros.h"
#include "base/memory/ref_counted.h" #include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h" #include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h" #include "base/memory/weak_ptr.h"
#include "chromeos/accelerometer/accelerometer_reader.h"
#include "ui/gfx/display.h" #include "ui/gfx/display.h"
namespace base { namespace base {
class FilePath;
class FilePathWatcher;
class TaskRunner; class TaskRunner;
} }
...@@ -23,50 +21,23 @@ namespace athena { ...@@ -23,50 +21,23 @@ namespace athena {
// Monitors accelerometers, detecting orientation changes. When a change is // Monitors accelerometers, detecting orientation changes. When a change is
// detected rotates the root window to match. // detected rotates the root window to match.
class OrientationController class OrientationController
: public DeviceSocketListener, : public chromeos::AccelerometerReader::Delegate {
public base::RefCountedThreadSafe<OrientationController> {
public: public:
OrientationController(); OrientationController();
void InitWith(scoped_refptr<base::TaskRunner> file_task_runner);
void Shutdown();
private:
friend class base::RefCountedThreadSafe<OrientationController>;
virtual ~OrientationController(); virtual ~OrientationController();
void ShutdownOnFILE(); void InitWith(scoped_refptr<base::TaskRunner> blocking_task_runner);
// Watch for the socket path to be created, called on the FILE thread. void Shutdown();
void WatchForSocketPathOnFILE();
void OnFilePathChangedOnFILE(const base::FilePath& path, bool error);
// Overridden from device::DeviceSocketListener:
virtual void OnDataAvailableOnFILE(const void* data) OVERRIDE;
// Rotates the display to |rotation|, called on the UI thread. // chromeos::AccelerometerReader::Delegate
void RotateOnUI(gfx::Display::Rotation rotation); virtual void HandleAccelerometerUpdate(
const ui::AccelerometerUpdate& update) OVERRIDE;
private:
// The last configured rotation. // The last configured rotation.
gfx::Display::Rotation current_rotation_; gfx::Display::Rotation current_rotation_;
// The timestamp of the last applied orientation change. scoped_ptr<chromeos::AccelerometerReader> accelerometer_reader_;
int64_t last_orientation_change_time_;
// True if the OrientaionController has already been shutdown.
// This is initialized on UI thread, but must be accessed / modified
// only on FILE thread.
bool shutdown_;
// A task runner for the UI thread.
scoped_refptr<base::TaskRunner> ui_task_runner_;
// A task runner for the FILE thread.
scoped_refptr<base::TaskRunner> file_task_runner_;
// File path watcher used to detect when sensors are present.
scoped_ptr<base::FilePathWatcher> watcher_;
DISALLOW_COPY_AND_ASSIGN(OrientationController); DISALLOW_COPY_AND_ASSIGN(OrientationController);
}; };
......
...@@ -6,7 +6,6 @@ ...@@ -6,7 +6,6 @@
#include "athena/screen/public/screen_manager.h" #include "athena/screen/public/screen_manager.h"
#include "athena/system/background_controller.h" #include "athena/system/background_controller.h"
#include "athena/system/device_socket_listener.h"
#include "athena/system/orientation_controller.h" #include "athena/system/orientation_controller.h"
#include "athena/system/power_button_controller.h" #include "athena/system/power_button_controller.h"
#include "athena/system/status_icon_container_view.h" #include "athena/system/status_icon_container_view.h"
...@@ -75,12 +74,12 @@ class SystemInfoView : public views::View { ...@@ -75,12 +74,12 @@ class SystemInfoView : public views::View {
class SystemUIImpl : public SystemUI { class SystemUIImpl : public SystemUI {
public: public:
SystemUIImpl(scoped_refptr<base::TaskRunner> file_task_runner) SystemUIImpl(scoped_refptr<base::TaskRunner> blocking_task_runner)
: orientation_controller_(new OrientationController()), : orientation_controller_(new OrientationController()),
power_button_controller_(new PowerButtonController), power_button_controller_(new PowerButtonController),
background_container_(NULL), background_container_(NULL),
system_modal_container_(NULL) { system_modal_container_(NULL) {
orientation_controller_->InitWith(file_task_runner); orientation_controller_->InitWith(blocking_task_runner);
} }
virtual ~SystemUIImpl() { virtual ~SystemUIImpl() {
...@@ -113,7 +112,7 @@ class SystemUIImpl : public SystemUI { ...@@ -113,7 +112,7 @@ class SystemUIImpl : public SystemUI {
} }
private: private:
scoped_refptr<OrientationController> orientation_controller_; scoped_ptr<OrientationController> orientation_controller_;
scoped_ptr<PowerButtonController> power_button_controller_; scoped_ptr<PowerButtonController> power_button_controller_;
scoped_ptr<BackgroundController> background_controller_; scoped_ptr<BackgroundController> background_controller_;
...@@ -129,9 +128,9 @@ class SystemUIImpl : public SystemUI { ...@@ -129,9 +128,9 @@ class SystemUIImpl : public SystemUI {
} // namespace } // namespace
// static // static
SystemUI* SystemUI::Create(scoped_refptr<base::TaskRunner> file_task_runner) { SystemUI* SystemUI::Create(
DeviceSocketListener::CreateSocketManager(file_task_runner); scoped_refptr<base::TaskRunner> blocking_task_runner) {
SystemUIImpl* system_ui = new SystemUIImpl(file_task_runner); SystemUIImpl* system_ui = new SystemUIImpl(blocking_task_runner);
instance = system_ui; instance = system_ui;
system_ui->Init(); system_ui->Init();
return instance; return instance;
...@@ -148,7 +147,6 @@ void SystemUI::Shutdown() { ...@@ -148,7 +147,6 @@ void SystemUI::Shutdown() {
CHECK(instance); CHECK(instance);
delete instance; delete instance;
instance = NULL; instance = NULL;
DeviceSocketListener::ShutdownSocketManager();
} }
} // namespace athena } // namespace athena
...@@ -60,6 +60,7 @@ void AthenaTestHelper::SetUp(ui::ContextFactory* context_factory) { ...@@ -60,6 +60,7 @@ void AthenaTestHelper::SetUp(ui::ContextFactory* context_factory) {
aura::test::EnvTestHelper(aura::Env::GetInstance()) aura::test::EnvTestHelper(aura::Env::GetInstance())
.SetInputStateLookup(scoped_ptr<aura::InputStateLookup>()); .SetInputStateLookup(scoped_ptr<aura::InputStateLookup>());
// TODO(oshima): Use a BlockingPool task runner.
athena::StartAthenaEnv(file_thread_->message_loop_proxy()); athena::StartAthenaEnv(file_thread_->message_loop_proxy());
athena::ExtensionsDelegate::CreateExtensionsDelegateForTest(); athena::ExtensionsDelegate::CreateExtensionsDelegateForTest();
athena::StartAthenaSession(new SampleActivityFactory(), athena::StartAthenaSession(new SampleActivityFactory(),
......
...@@ -38,8 +38,9 @@ class ChromeBrowserMainExtraPartsAthena : public ChromeBrowserMainExtraParts, ...@@ -38,8 +38,9 @@ class ChromeBrowserMainExtraPartsAthena : public ChromeBrowserMainExtraParts,
private: private:
// Overridden from ChromeBrowserMainExtraParts: // Overridden from ChromeBrowserMainExtraParts:
virtual void PreProfileInit() OVERRIDE { virtual void PreProfileInit() OVERRIDE {
athena::StartAthenaEnv(content::BrowserThread::GetMessageLoopProxyForThread( athena::StartAthenaEnv(content::BrowserThread::GetBlockingPool()->
content::BrowserThread::FILE)); GetTaskRunnerWithShutdownBehavior(
base::SequencedWorkerPool::SKIP_ON_SHUTDOWN));
} }
virtual void PostProfileInit() OVERRIDE { virtual void PostProfileInit() OVERRIDE {
if (!CommandLine::ForCurrentProcess()->HasSwitch( if (!CommandLine::ForCurrentProcess()->HasSwitch(
......
...@@ -27,28 +27,29 @@ const base::FilePath::CharType kAccelerometerDevicePath[] = ...@@ -27,28 +27,29 @@ const base::FilePath::CharType kAccelerometerDevicePath[] =
const base::FilePath::CharType kAccelerometerIioBasePath[] = const base::FilePath::CharType kAccelerometerIioBasePath[] =
FILE_PATH_LITERAL("/sys/bus/iio/devices/"); FILE_PATH_LITERAL("/sys/bus/iio/devices/");
// Files within the device in kAccelerometerIioBasePath containing the scales of // File within the device in kAccelerometerIioBasePath containing the scale of
// the accelerometers. // the accelerometers.
const base::FilePath::CharType kAccelerometerBaseScaleName[] = const base::FilePath::CharType kScaleNameFormatString[] = "in_accel_%s_scale";
FILE_PATH_LITERAL("in_accel_base_scale");
const base::FilePath::CharType kAccelerometerLidScaleName[] =
FILE_PATH_LITERAL("in_accel_lid_scale");
// The filename giving the path to read the scan index of each accelerometer // The filename giving the path to read the scan index of each accelerometer
// axis. // axis.
const char kAccelerometerScanIndexPath[] = const char kAccelerometerScanIndexPath[] =
"scan_elements/in_accel_%s_%s_index"; "scan_elements/in_accel_%s_%s_index";
// The names of the accelerometers and axes in the order we want to read them. // The names of the accelerometers. Matches up with the enum AccelerometerSource
const char kAccelerometerNames[][5] = {"base", "lid"}; // in ui/accelerometer/accelerometer_types.h.
const char kAccelerometerAxes[][2] = {"x", "y", "z"}; const char kAccelerometerNames[ui::ACCELEROMETER_SOURCE_COUNT][5] = {
const size_t kTriggerDataValues = "lid", "base"};
arraysize(kAccelerometerNames) * arraysize(kAccelerometerAxes);
const size_t kTriggerDataLength = kTriggerDataValues * 2; // The axes on each accelerometer.
const char kAccelerometerAxes[][2] = {"y", "x", "z"};
// The length required to read uint values from configuration files. // The length required to read uint values from configuration files.
const size_t kMaxAsciiUintLength = 21; const size_t kMaxAsciiUintLength = 21;
// The size of individual values.
const size_t kDataSize = 2;
// The time to wait between reading the accelerometer. // The time to wait between reading the accelerometer.
const int kDelayBetweenReadsMs = 100; const int kDelayBetweenReadsMs = 100;
...@@ -57,15 +58,14 @@ const float kMeanGravity = 9.80665f; ...@@ -57,15 +58,14 @@ const float kMeanGravity = 9.80665f;
// Reads |path| to the unsigned int pointed to by |value|. Returns true on // Reads |path| to the unsigned int pointed to by |value|. Returns true on
// success or false on failure. // success or false on failure.
bool ReadFileToUint(const base::FilePath& path, unsigned int* value) { bool ReadFileToInt(const base::FilePath& path, int* value) {
std::string s; std::string s;
DCHECK(value); DCHECK(value);
if (!base::ReadFileToString(path, &s, kMaxAsciiUintLength)) { if (!base::ReadFileToString(path, &s, kMaxAsciiUintLength)) {
LOG(ERROR) << "Failed to read " << path.value();
return false; return false;
} }
base::TrimWhitespaceASCII(s, base::TRIM_ALL, &s); base::TrimWhitespaceASCII(s, base::TRIM_ALL, &s);
if (!base::StringToUint(s, value)) { if (!base::StringToInt(s, value)) {
LOG(ERROR) << "Failed to parse \"" << s << "\" from " << path.value(); LOG(ERROR) << "Failed to parse \"" << s << "\" from " << path.value();
return false; return false;
} }
...@@ -90,41 +90,62 @@ bool DetectAndReadAccelerometerConfiguration( ...@@ -90,41 +90,62 @@ bool DetectAndReadAccelerometerConfiguration(
base::FilePath iio_path(base::FilePath(kAccelerometerIioBasePath).Append( base::FilePath iio_path(base::FilePath(kAccelerometerIioBasePath).Append(
device)); device));
// Read accelerometer scales // Read configuration of each accelerometer axis from each accelerometer from
if (!ReadFileToUint(iio_path.Append(kAccelerometerBaseScaleName), // /sys/bus/iio/devices/iio:deviceX/.
&(configuration->data.base_scale))) {
return false;
}
if (!ReadFileToUint(iio_path.Append(kAccelerometerLidScaleName),
&(configuration->data.lid_scale))) {
return false;
}
// Read indices of each accelerometer axis from each accelerometer from
// /sys/bus/iio/devices/iio:deviceX/scan_elements/in_accel_{x,y,z}_%s_index
for (size_t i = 0; i < arraysize(kAccelerometerNames); ++i) { for (size_t i = 0; i < arraysize(kAccelerometerNames); ++i) {
// Read scale of accelerometer.
std::string accelerometer_scale_path = base::StringPrintf(
kScaleNameFormatString, kAccelerometerNames[i]);
int scale_divisor;
if (!ReadFileToInt(iio_path.Append(accelerometer_scale_path.c_str()),
&scale_divisor)) {
configuration->data.has[i] = false;
continue;
}
configuration->data.has[i] = true;
configuration->data.count++;
for (size_t j = 0; j < arraysize(kAccelerometerAxes); ++j) { for (size_t j = 0; j < arraysize(kAccelerometerAxes); ++j) {
configuration->data.scale[i][j] = kMeanGravity / scale_divisor;
std::string accelerometer_index_path = base::StringPrintf( std::string accelerometer_index_path = base::StringPrintf(
kAccelerometerScanIndexPath, kAccelerometerAxes[j], kAccelerometerScanIndexPath, kAccelerometerAxes[j],
kAccelerometerNames[i]); kAccelerometerNames[i]);
unsigned int index = 0; if (!ReadFileToInt(iio_path.Append(accelerometer_index_path.c_str()),
if (!ReadFileToUint(iio_path.Append(accelerometer_index_path.c_str()), &(configuration->data.index[i][j]))) {
&index)) {
return false; return false;
} }
if (index >= kTriggerDataValues) { }
LOG(ERROR) << "Field index from " << accelerometer_index_path }
<< " out of bounds: " << index;
// Adjust the directions of accelerometers to match the AccelerometerUpdate
// type specified in ui/accelerometer/accelerometer_types.h.
configuration->data.scale[ui::ACCELEROMETER_SOURCE_SCREEN][0] *= -1.0f;
for (int i = 0; i < 3; ++i) {
configuration->data.scale[ui::ACCELEROMETER_SOURCE_ATTACHED_KEYBOARD][i] *=
-1.0f;
}
// Verify indices are within bounds.
for (int i = 0; i < ui::ACCELEROMETER_SOURCE_COUNT; ++i) {
if (!configuration->data.has[i])
continue;
for (int j = 0; j < 3; ++j) {
if (configuration->data.index[i][j] < 0 ||
configuration->data.index[i][j] >=
3 * static_cast<int>(configuration->data.count)) {
LOG(ERROR) << "Field index for " << kAccelerometerNames[i] << " "
<< kAccelerometerAxes[j] << " axis out of bounds.";
return false; return false;
} }
configuration->data.index.push_back(index);
} }
} }
configuration->data.length = kDataSize * 3 * configuration->data.count;
return true; return true;
} }
bool ReadAccelerometer( bool ReadAccelerometer(
scoped_refptr<AccelerometerReader::Reading> reading) { scoped_refptr<AccelerometerReader::Reading> reading,
size_t length) {
// Initiate the trigger to read accelerometers simultaneously // Initiate the trigger to read accelerometers simultaneously
int bytes_written = base::WriteFile( int bytes_written = base::WriteFile(
base::FilePath(kAccelerometerTriggerPath), "1\n", 2); base::FilePath(kAccelerometerTriggerPath), "1\n", 2);
...@@ -135,10 +156,10 @@ bool ReadAccelerometer( ...@@ -135,10 +156,10 @@ bool ReadAccelerometer(
// Read resulting sample from /dev/cros-ec-accel. // Read resulting sample from /dev/cros-ec-accel.
int bytes_read = base::ReadFile(base::FilePath(kAccelerometerDevicePath), int bytes_read = base::ReadFile(base::FilePath(kAccelerometerDevicePath),
reading->data, kTriggerDataLength); reading->data, length);
if (bytes_read < static_cast<int>(kTriggerDataLength)) { if (bytes_read < static_cast<int>(length)) {
LOG(ERROR) << "Read " << bytes_read << " byte(s), expected " LOG(ERROR) << "Read " << bytes_read << " byte(s), expected "
<< kTriggerDataLength << " bytes from accelerometer"; << length << " bytes from accelerometer";
return false; return false;
} }
return true; return true;
...@@ -146,16 +167,24 @@ bool ReadAccelerometer( ...@@ -146,16 +167,24 @@ bool ReadAccelerometer(
} // namespace } // namespace
AccelerometerReader::ConfigurationData::ConfigurationData() { AccelerometerReader::ConfigurationData::ConfigurationData()
: count(0) {
for (int i = 0; i < ui::ACCELEROMETER_SOURCE_COUNT; ++i) {
has[i] = false;
for (int j = 0; j < 3; ++j) {
scale[i][j] = 0;
index[i][j] = -1;
}
}
} }
AccelerometerReader::ConfigurationData::~ConfigurationData() { AccelerometerReader::ConfigurationData::~ConfigurationData() {
} }
AccelerometerReader::AccelerometerReader( AccelerometerReader::AccelerometerReader(
base::TaskRunner* task_runner, scoped_refptr<base::TaskRunner> blocking_task_runner,
AccelerometerReader::Delegate* delegate) AccelerometerReader::Delegate* delegate)
: task_runner_(task_runner), : task_runner_(blocking_task_runner),
delegate_(delegate), delegate_(delegate),
configuration_(new AccelerometerReader::Configuration()), configuration_(new AccelerometerReader::Configuration()),
weak_factory_(this) { weak_factory_(this) {
...@@ -186,7 +215,8 @@ void AccelerometerReader::TriggerRead() { ...@@ -186,7 +215,8 @@ void AccelerometerReader::TriggerRead() {
new AccelerometerReader::Reading()); new AccelerometerReader::Reading());
base::PostTaskAndReplyWithResult(task_runner_.get(), base::PostTaskAndReplyWithResult(task_runner_.get(),
FROM_HERE, FROM_HERE,
base::Bind(&ReadAccelerometer, reading), base::Bind(&ReadAccelerometer, reading,
configuration_->data.length),
base::Bind(&AccelerometerReader::OnDataRead, base::Bind(&AccelerometerReader::OnDataRead,
weak_factory_.GetWeakPtr(), weak_factory_.GetWeakPtr(),
reading)); reading));
...@@ -198,17 +228,19 @@ void AccelerometerReader::OnDataRead( ...@@ -198,17 +228,19 @@ void AccelerometerReader::OnDataRead(
DCHECK(!task_runner_->RunsTasksOnCurrentThread()); DCHECK(!task_runner_->RunsTasksOnCurrentThread());
if (success) { if (success) {
int16* values = reinterpret_cast<int16*>(reading->data); for (int i = 0; i < ui::ACCELEROMETER_SOURCE_COUNT; ++i) {
float lid_scale = kMeanGravity / configuration_->data.lid_scale; if (!configuration_->data.has[i])
update_.Set(ui::ACCELEROMETER_SOURCE_SCREEN, continue;
-values[configuration_->data.index[4]] * lid_scale,
values[configuration_->data.index[3]] * lid_scale, int16* values = reinterpret_cast<int16*>(reading->data);
values[configuration_->data.index[5]] * lid_scale); update_.Set(static_cast<ui::AccelerometerSource>(i),
float base_scale = kMeanGravity / configuration_->data.base_scale; values[configuration_->data.index[i][0]] *
update_.Set(ui::ACCELEROMETER_SOURCE_ATTACHED_KEYBOARD, configuration_->data.scale[i][0],
-values[configuration_->data.index[1]] * base_scale, values[configuration_->data.index[i][1]] *
-values[configuration_->data.index[0]] * base_scale, configuration_->data.scale[i][1],
-values[configuration_->data.index[2]] * base_scale); values[configuration_->data.index[i][2]] *
configuration_->data.scale[i][2]);
}
delegate_->HandleAccelerometerUpdate(update_); delegate_->HandleAccelerometerUpdate(update_);
} }
......
...@@ -5,8 +5,6 @@ ...@@ -5,8 +5,6 @@
#ifndef CHROMEOS_ACCELEROMETER_ACCELEROMETER_READER_H_ #ifndef CHROMEOS_ACCELEROMETER_ACCELEROMETER_READER_H_
#define CHROMEOS_ACCELEROMETER_ACCELEROMETER_READER_H_ #define CHROMEOS_ACCELEROMETER_ACCELEROMETER_READER_H_
#include <vector>
#include "base/memory/ref_counted.h" #include "base/memory/ref_counted.h"
#include "base/memory/weak_ptr.h" #include "base/memory/weak_ptr.h"
#include "base/observer_list.h" #include "base/observer_list.h"
...@@ -28,12 +26,20 @@ class CHROMEOS_EXPORT AccelerometerReader { ...@@ -28,12 +26,20 @@ class CHROMEOS_EXPORT AccelerometerReader {
ConfigurationData(); ConfigurationData();
~ConfigurationData(); ~ConfigurationData();
// Scale of accelerometers (i.e. raw value * 1.0f / scale = G's). // Number of accelerometers on device.
unsigned int base_scale; size_t count;
unsigned int lid_scale;
// Length of accelerometer updates.
size_t length;
// Which accelerometers are present on device.
bool has[ui::ACCELEROMETER_SOURCE_COUNT];
// Scale of accelerometers (i.e. raw value * scale = m/s^2).
float scale[ui::ACCELEROMETER_SOURCE_COUNT][3];
// Index of each accelerometer axis in data stream. // Index of each accelerometer axis in data stream.
std::vector<unsigned int> index; int index[ui::ACCELEROMETER_SOURCE_COUNT][3];
}; };
typedef base::RefCountedData<ConfigurationData> Configuration; typedef base::RefCountedData<ConfigurationData> Configuration;
typedef base::RefCountedData<char[12]> Reading; typedef base::RefCountedData<char[12]> Reading;
...@@ -45,7 +51,7 @@ class CHROMEOS_EXPORT AccelerometerReader { ...@@ -45,7 +51,7 @@ class CHROMEOS_EXPORT AccelerometerReader {
const ui::AccelerometerUpdate& update) = 0; const ui::AccelerometerUpdate& update) = 0;
}; };
AccelerometerReader(base::TaskRunner* blocking_task_runner, AccelerometerReader(scoped_refptr<base::TaskRunner> blocking_task_runner,
Delegate* delegate); Delegate* delegate);
~AccelerometerReader(); ~AccelerometerReader();
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment