Commit ff8208db authored by thakis@chromium.org's avatar thakis@chromium.org

Revert of Rotate screen in response to accelerator or device orientation...

Revert of Rotate screen in response to accelerator or device orientation sensors. (patchset #12 of https://codereview.chromium.org/431183003/)

Reason for revert:
Speculative, athena_unittests and ui_unittests started failing in this build:http://build.chromium.org/p/chromium.memory/builders/Linux%20Chromium%20OS%20ASan%20LSan%20Tests%20%283%29/builds/2771

==6568==ERROR: AddressSanitizer: heap-use-after-free on address 0x60700000ba10 at pc 0x00000167d52a bp 0x7fff95f266f0 sp 0x7fff95f266e8
READ of size 8 at 0x60700000ba10 thread T0
    #0 0x167d529 in DeleteInternal base/memory/ref_counted.h:190:44
    #1 0x167d529 in Destruct base/memory/ref_counted.h:153
    #2 0x167d529 in Release base/memory/ref_counted.h:181
    #3 0x167d529 in ~scoped_refptr base/memory/ref_counted.h:289
    #4 0x167d529 in ~SystemUIImpl athena/system/system_ui_impl.cc:27
    #5 0x167d529 in athena::(anonymous namespace)::SystemUIImpl::~SystemUIImpl() athena/system/system_ui_impl.cc:26
    #6 0x167d257 in athena::SystemUI::Shutdown() athena/system/system_ui_impl.cc:49:3
    #7 0x577fa6 in athena::ShutdownAthena() athena/main/athena_launcher.cc:92:3
    #8 0x57645f in athena::test::AthenaTestHelper::TearDown() athena/test/athena_test_helper.cc:98:3
    #9 0x575266 in athena::test::AthenaTestBase::TearDown() athena/test/athena_test_base.cc:53:3
    #10 0x505bc8 in testing::TestInfo::Run() testing/gtest/src/gtest.cc:2610:5
    #11 0x506906 in testing::TestCase::Run() testing/gtest/src/gtest.cc:2728:5
    #12 0x51cb85 in testing::internal::UnitTestImpl::RunAllTests() testing/gtest/src/gtest.cc:4591:11
    #13 0x51c176 in HandleExceptionsInMethodIfSupported\u003Ctesting::internal::UnitTestImpl, bool> testing/gtest/src/gtest.cc:2418:12
    #14 0x51c176 in testing::UnitTest::Run() testing/gtest/src/gtest.cc:4209
    #15 0xac6fb4 in RUN_ALL_TESTS testing/gtest/include/gtest/gtest.h:2304:10
    #16 0xac6fb4 in base::TestSuite::Run() base/test/test_suite.cc:227
    #17 0xabe39d in Run base/callback.h:401:12
    #18 0xabe39d in base::(anonymous namespace)::LaunchUnitTestsInternal(base::Callback\u003Cint ()> const&, int, bool, base::Callback\u003Cvoid ()> const&) base/test/launcher/unit_test_launcher.cc:498
    #19 0xabf0de in base::LaunchUnitTestsSerially(int, char**, base::Callback\u003Cint ()> const&) base/test/launcher/unit_test_launcher.cc:564:10
    #20 0x4d7bba in main athena/test/athena_unittests.cc:51:10
    #21 0x7fd394e3476c in __libc_start_main /build/buildd/eglibc-2.15/csu/libc-start.c:226
    #22 0x4d795c in _start (/mnt/data/b/build/slave/Linux_Chromium_OS_ASan_LSan_Tests__3_/build/src/out/Release/athena_unittests+0x4d795c)

0x60700000ba10 is located 0 bytes inside of 72-byte region [0x60700000ba10,0x60700000ba58)
freed by thread T0 here:
    #0 0x452fcb in operator delete(void*) (/mnt/data/b/build/slave/Linux_Chromium_OS_ASan_LSan_Tests__3_/build/src/out/Release/athena_unittests+0x452fcb)
    #1 0x168323d in DeleteInternal base/memory/ref_counted.h:190:44
    #2 0x168323d in Destruct base/memory/ref_counted.h:153
    #3 0x168323d in Release base/memory/ref_counted.h:181
    #4 0x168323d in ~scoped_refptr base/memory/ref_counted.h:289
    #5 0x168323d in athena::OrientationController::OrientationController(scoped_refptr\u003Cbase::TaskRunner>) athena/system/orientation_controller.cc:66
    #6 0x167cfea in SystemUIImpl athena/system/system_ui_impl.cc:23:61
    #7 0x167cfea in athena::SystemUI::Create(scoped_refptr\u003Cbase::TaskRunner>) athena/system/system_ui_impl.cc:42
    #8 0x577db0 in athena::StartAthena(aura::Window*, athena::ActivityFactory*, athena::AppModelBuilder*) athena/main/athena_launcher.cc:73:3
    #9 0x576159 in athena::test::AthenaTestHelper::SetUp(ui::ContextFactory*) athena/test/athena_test_helper.cc:90:3
    #10 0x503eb1 in HandleExceptionsInMethodIfSupported\u003Ctesting::Test, void> testing/gtest/src/gtest.cc:2418:12
    #11 0x503eb1 in testing::Test::Run() testing/gtest/src/gtest.cc:2430
    #12 0x505bc8 in testing::TestInfo::Run() testing/gtest/src/gtest.cc:2610:5
    #13 0x506906 in testing::TestCase::Run() testing/gtest/src/gtest.cc:2728:5
    #14 0x51cb85 in testing::internal::UnitTestImpl::RunAllTests() testing/gtest/src/gtest.cc:4591:11
    #15 0x51c176 in HandleExceptionsInMethodIfSupported\u003Ctesting::internal::UnitTestImpl, bool> testing/gtest/src/gtest.cc:2418:12
    #16 0x51c176 in testing::UnitTest::Run() testing/gtest/src/gtest.cc:4209
    #17 0xac6fb4 in RUN_ALL_TESTS testing/gtest/include/gtest/gtest.h:2304:10
    #18 0xac6fb4 in base::TestSuite::Run() base/test/test_suite.cc:227
    #19 0xabe39d in Run base/callback.h:401:12
    #20 0xabe39d in base::(anonymous namespace)::LaunchUnitTestsInternal(base::Callback\u003Cint ()> const&, int, bool, base::Callback\u003Cvoid ()> const&) base/test/launcher/unit_test_launcher.cc:498
    #21 0xabf0de in base::LaunchUnitTestsSerially(int, char**, base::Callback\u003Cint ()> const&) base/test/launcher/unit_test_launcher.cc:564:10
    #22 0x4d7bba in main athena/test/athena_unittests.cc:51:10
    #23 0x7fd394e3476c in __libc_start_main /build/buildd/eglibc-2.15/csu/libc-start.c:226

previously allocated by thread T0 here:
    #0 0x452a8b in operator new(unsigned long) (/mnt/data/b/build/slave/Linux_Chromium_OS_ASan_LSan_Tests__3_/build/src/out/Release/athena_unittests+0x452a8b)
    #1 0x167cfb5 in SystemUIImpl athena/system/system_ui_impl.cc:23:61
    #2 0x167cfb5 in athena::SystemUI::Create(scoped_refptr\u003Cbase::TaskRunner>) athena/system/system_ui_impl.cc:42
    #3 0x577db0 in athena::StartAthena(aura::Window*, athena::ActivityFactory*, athena::AppModelBuilder*) athena/main/athena_launcher.cc:73:3
    #4 0x576159 in athena::test::AthenaTestHelper::SetUp(ui::ContextFactory*) athena/test/athena_test_helper.cc:90:3
    #5 0x503eb1 in HandleExceptionsInMethodIfSupported\u003Ctesting::Test, void> testing/gtest/src/gtest.cc:2418:12
    #6 0x503eb1 in testing::Test::Run() testing/gtest/src/gtest.cc:2430
    #7 0x505bc8 in testing::TestInfo::Run() testing/gtest/src/gtest.cc:2610:5
    #8 0x506906 in testing::TestCase::Run() testing/gtest/src/gtest.cc:2728:5
    #9 0x51cb85 in testing::internal::UnitTestImpl::RunAllTests() testing/gtest/src/gtest.cc:4591:11
    #10 0x51c176 in HandleExceptionsInMethodIfSupported\u003Ctesting::internal::UnitTestImpl, bool> testing/gtest/src/gtest.cc:2418:12
    #11 0x51c176 in testing::UnitTest::Run() testing/gtest/src/gtest.cc:4209
    #12 0xac6fb4 in RUN_ALL_TESTS testing/gtest/include/gtest/gtest.h:2304:10
    #13 0xac6fb4 in base::TestSuite::Run() base/test/test_suite.cc:227
    #14 0xabe39d in Run base/callback.h:401:12
    #15 0xabe39d in base::(anonymous namespace)::LaunchUnitTestsInternal(base::Callback\u003Cint ()> const&, int, bool, base::Callback\u003Cvoid ()> const&) base/test/launcher/unit_test_launcher.cc:498
    #16 0xabf0de in base::LaunchUnitTestsSerially(int, char**, base::Callback\u003Cint ()> const&) base/test/launcher/unit_test_launcher.cc:564:10
    #17 0x4d7bba in main athena/test/athena_unittests.cc:51:10
    #18 0x7fd394e3476c in __libc_start_main /build/buildd/eglibc-2.15/csu/libc-start.c:226

TBR=oshima
NOTRY=true
NOTREECHECKS=true

Original issue's description:
> Rotate screen in response to accelerator or device orientation sensors.
> 
> BUG=385295
> TEST=Press Ctrl+Shift+F3, screen rotates.
> 
> Committed: https://src.chromium.org/viewvc/chrome?view=rev&revision=290007

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

Cr-Commit-Position: refs/heads/master@{#290089}
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@290089 0039d316-1c4b-4281-b951-d872f2087c98
parent 565399e4
......@@ -11,14 +11,11 @@
'target_name': 'athena_lib',
'type': '<(component)',
'dependencies': [
'../base/base.gyp:test_support_base',
'../extensions/shell/app_shell.gyp:app_shell_version_header',
'../ipc/ipc.gyp:ipc',
'../skia/skia.gyp:skia',
'../ui/accessibility/accessibility.gyp:ax_gen',
'../ui/app_list/app_list.gyp:app_list',
'../ui/aura/aura.gyp:aura',
'../ui/aura/aura.gyp:aura_test_support',
'../ui/events/events.gyp:events_base',
'../ui/strings/ui_strings.gyp:ui_strings',
'../ui/views/views.gyp:views',
......@@ -68,10 +65,6 @@
'screen/screen_accelerator_handler.cc',
'screen/screen_accelerator_handler.h',
'screen/screen_manager_impl.cc',
'system/device_socket_listener.cc',
'system/device_socket_listener.h',
'system/orientation_controller.cc',
'system/orientation_controller.h',
'system/power_button_controller.cc',
'system/power_button_controller.h',
'system/public/system_ui.h',
......@@ -146,7 +139,6 @@
'../ui/views/views.gyp:views',
'../ui/wm/wm.gyp:wm',
'../url/url.gyp:url_lib',
'athena_content_lib',
'athena_lib',
'resources/athena_resources.gyp:athena_resources',
],
......
......@@ -13,7 +13,6 @@
#include "athena/system/public/system_ui.h"
#include "athena/wm/public/window_manager.h"
#include "base/memory/scoped_ptr.h"
#include "content/public/browser/browser_thread.h"
#include "ui/aura/window_property.h"
#include "ui/views/views_delegate.h"
#include "ui/wm/core/visibility_controller.h"
......@@ -70,9 +69,7 @@ void StartAthena(aura::Window* root_window,
aura::client::SetVisibilityClient(root_window,
root_window_state->visibility_client.get());
athena::SystemUI::Create(
content::BrowserThread::GetMessageLoopProxyForThread(
content::BrowserThread::FILE));
athena::SystemUI::Create();
athena::InputManager::Create()->OnRootWindowCreated(root_window);
athena::ScreenManager::Create(root_window);
athena::WindowManager::Create();
......
......@@ -8,7 +8,6 @@
#include <string>
#include "athena/athena_export.h"
#include "ui/gfx/display.h"
namespace aura {
class Window;
......@@ -69,11 +68,6 @@ class ATHENA_EXPORT ScreenManager {
// Sets the background image.
virtual void SetBackgroundImage(const gfx::ImageSkia& image) = 0;
// Set screen rotation.
// TODO(flackr): Extract and use ash DisplayManager to set rotation
// instead: http://crbug.com/401044.
virtual void SetRotation(gfx::Display::Rotation rotation) = 0;
// Returns the LayerAnimator to use to animate the entire screen (e.g. fade
// screen to white).
virtual ui::LayerAnimator* GetScreenAnimator() = 0;
......
......@@ -5,13 +5,10 @@
#include "athena/screen/screen_accelerator_handler.h"
#include "athena/input/public/accelerator_manager.h"
#include "athena/screen/public/screen_manager.h"
#include "ui/aura/window.h"
#include "ui/aura/window_event_dispatcher.h"
#include "ui/aura/window_tree_host.h"
#include "ui/compositor/debug_utils.h"
#include "ui/gfx/display.h"
#include "ui/gfx/screen.h"
#include "ui/wm/public/activation_client.h"
namespace athena {
......@@ -20,7 +17,6 @@ namespace {
enum Command {
CMD_PRINT_LAYER_HIERARCHY,
CMD_PRINT_WINDOW_HIERARCHY,
CMD_ROTATE_SCREEN,
};
const int EF_ALL_DOWN =
......@@ -31,9 +27,6 @@ const AcceleratorData accelerator_data[] = {
AF_DEBUG},
{TRIGGER_ON_PRESS, ui::VKEY_W, EF_ALL_DOWN, CMD_PRINT_WINDOW_HIERARCHY,
AF_DEBUG},
{TRIGGER_ON_PRESS, ui::VKEY_F3,
ui::EF_CONTROL_DOWN | ui::EF_SHIFT_DOWN,
CMD_ROTATE_SCREEN, AF_NONE},
};
void PrintLayerHierarchy(aura::Window* root_window) {
......@@ -70,20 +63,6 @@ void HandlePrintWindowHierarchy(aura::Window* root_window) {
LOG(ERROR) << out.str();
}
void HandleRotateScreen() {
ScreenManager* screen_manager = ScreenManager::Get();
gfx::Display::Rotation current_rotation =
gfx::Screen::GetNativeScreen()->GetPrimaryDisplay().rotation();
if (current_rotation == gfx::Display::ROTATE_0)
screen_manager->SetRotation(gfx::Display::ROTATE_90);
else if (current_rotation == gfx::Display::ROTATE_90)
screen_manager->SetRotation(gfx::Display::ROTATE_180);
else if (current_rotation == gfx::Display::ROTATE_180)
screen_manager->SetRotation(gfx::Display::ROTATE_270);
else if (current_rotation == gfx::Display::ROTATE_270)
screen_manager->SetRotation(gfx::Display::ROTATE_0);
}
} // namespace
// static
......@@ -110,9 +89,6 @@ bool ScreenAcceleratorHandler::OnAcceleratorFired(
case CMD_PRINT_WINDOW_HIERARCHY:
HandlePrintWindowHierarchy(root_window_);
return true;
case CMD_ROTATE_SCREEN:
HandleRotateScreen();
return true;
}
return false;
}
......
......@@ -14,14 +14,11 @@
#include "ui/aura/client/screen_position_client.h"
#include "ui/aura/client/window_tree_client.h"
#include "ui/aura/layout_manager.h"
#include "ui/aura/test/test_screen.h"
#include "ui/aura/window.h"
#include "ui/aura/window_property.h"
#include "ui/aura/window_targeter.h"
#include "ui/aura/window_tree_host.h"
#include "ui/compositor/layer.h"
#include "ui/gfx/display.h"
#include "ui/gfx/screen.h"
#include "ui/wm/core/base_focus_rules.h"
#include "ui/wm/core/capture_controller.h"
......@@ -203,7 +200,6 @@ class ScreenManagerImpl : public ScreenManager {
virtual aura::Window* CreateContainer(const ContainerParams& params) OVERRIDE;
virtual aura::Window* GetContext() OVERRIDE { return root_window_; }
virtual void SetBackgroundImage(const gfx::ImageSkia& image) OVERRIDE;
virtual void SetRotation(gfx::Display::Rotation rotation) OVERRIDE;
virtual ui::LayerAnimator* GetScreenAnimator() OVERRIDE;
aura::Window* root_window_;
......@@ -328,18 +324,6 @@ void ScreenManagerImpl::SetBackgroundImage(const gfx::ImageSkia& image) {
background_controller_->SetImage(image);
}
void ScreenManagerImpl::SetRotation(gfx::Display::Rotation rotation) {
if (rotation ==
gfx::Screen::GetNativeScreen()->GetPrimaryDisplay().rotation()) {
return;
}
// TODO(flackr): Use display manager to update display rotation:
// http://crbug.com/401044.
static_cast<aura::TestScreen*>(gfx::Screen::GetNativeScreen())->
SetDisplayRotation(rotation);
}
ui::LayerAnimator* ScreenManagerImpl::GetScreenAnimator() {
return root_window_->layer()->GetAnimator();
}
......
// 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/memory/singleton.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> io_task_runner) {
device_socket_manager_instance_ =
new DeviceSocketManager(io_task_runner);
}
static void Shutdown() {
CHECK(device_socket_manager_instance_);
delete device_socket_manager_instance_;
device_socket_manager_instance_ = NULL;
}
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:
friend struct DefaultSingletonTraits<DeviceSocketManager>;
struct SocketData {
SocketData()
: fd(-1) {
}
int fd;
DeviceSocketListeners observers;
scoped_ptr<base::MessagePumpLibevent::FileDescriptorWatcher> controller;
scoped_ptr<DeviceSocketReader> watcher;
};
DeviceSocketManager(scoped_refptr<base::TaskRunner> io_task_runner)
: io_task_runner_(io_task_runner) {
}
~DeviceSocketManager() {
STLDeleteContainerPairSecondPointers(socket_data_.begin(),
socket_data_.end());
}
void StartListeningOnIO(const std::string& socket_path,
size_t data_size,
DeviceSocketListener* listener);
void StopListeningOnIO(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> io_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) {
io_task_runner_->PostTask(FROM_HERE,
base::Bind(&DeviceSocketManager::StartListeningOnIO,
base::Unretained(this), socket_path, data_size, listener));
}
void DeviceSocketManager::StopListening(const std::string& socket_path,
DeviceSocketListener* listener) {
io_task_runner_->PostTask(FROM_HERE,
base::Bind(&DeviceSocketManager::StopListeningOnIO,
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, OnDataAvailableOnIO(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::StartListeningOnIO(const std::string& socket_path,
size_t data_size,
DeviceSocketListener* listener) {
CHECK(io_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::StopListeningOnIO(const std::string& socket_path,
DeviceSocketListener* listener) {
if (!socket_data_.count(socket_path))
return; // Happens if unable to create a socket.
CHECK(io_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);
}
}
} // 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> io_task_runner) {
DeviceSocketManager::Create(io_task_runner);
}
// static
void DeviceSocketListener::ShutdownSocketManager() {
DeviceSocketManager::Shutdown();
}
void DeviceSocketListener::StartListening() {
DeviceSocketManager::GetInstance()->StartListening(socket_path_,
data_size_,
this);
}
void DeviceSocketListener::StopListening() {
DeviceSocketManager::GetInstance()->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 IO 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 OnDataAvailableOnIO(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_
// 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/screen/public/screen_manager.h"
#include "athena/system/orientation_controller.h"
#include "base/bind.h"
#include "base/file_util.h"
#include "base/files/file_path_watcher.h"
#include "base/message_loop/message_loop.h"
#include "base/task_runner.h"
namespace athena {
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.
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
OrientationController::OrientationController(
scoped_refptr<base::TaskRunner> io_task_runner)
: DeviceSocketListener(kSocketPath, sizeof(DeviceSensorEvent)),
last_orientation_change_time_(0),
weak_factory_(this) {
CHECK(base::MessageLoopForUI::current());
ui_task_runner_ = base::MessageLoopForUI::current()->task_runner();
io_task_runner->PostTask(FROM_HERE, base::Bind(
&OrientationController::WatchForSocketPathOnIO,
make_scoped_refptr<OrientationController>(this)));
}
OrientationController::~OrientationController() {
}
void OrientationController::WatchForSocketPathOnIO() {
CHECK(base::MessageLoopForIO::current());
if (base::PathExists(base::FilePath(kSocketPath))) {
ui_task_runner_->PostTask(FROM_HERE,
base::Bind(&OrientationController::StartListening,
make_scoped_refptr<OrientationController>(this)));
} else {
watcher_.reset(new base::FilePathWatcher);
watcher_->Watch(
base::FilePath(kSocketPath), false,
base::Bind(&OrientationController::OnFilePathChangedOnIO,
make_scoped_refptr<OrientationController>(this)));
}
}
void OrientationController::OnFilePathChangedOnIO(const base::FilePath& path,
bool error) {
watcher_.reset();
if (error)
return;
ui_task_runner_->PostTask(FROM_HERE,
base::Bind(&OrientationController::StartListening,
make_scoped_refptr<OrientationController>(this)));
}
void OrientationController::OnDataAvailableOnIO(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;
if (gravity_x < -kGravityThreshold) {
rotation = gfx::Display::ROTATE_270;
} else if (gravity_x > kGravityThreshold) {
rotation = gfx::Display::ROTATE_90;
} else if (gravity_y < -kGravityThreshold) {
rotation = gfx::Display::ROTATE_180;
} else if (gravity_y > kGravityThreshold) {
rotation = gfx::Display::ROTATE_0;
} else {
// No rotation as gravity threshold was not hit.
return;
}
if (rotation == current_rotation_ ||
event->timestamp - last_orientation_change_time_ <
kOrientationChangeDelayNS) {
return;
}
last_orientation_change_time_ = event->timestamp;
current_rotation_ = rotation;
ui_task_runner_->PostTask(FROM_HERE,
base::Bind(&OrientationController::RotateOnUI,
make_scoped_refptr<OrientationController>(this), rotation));
}
void OrientationController::RotateOnUI(gfx::Display::Rotation rotation) {
ScreenManager* screen_manager = ScreenManager::Get();
// Since this is called from the IO thread, the screen manager may no longer
// exist.
if (screen_manager)
screen_manager->SetRotation(rotation);
}
} // 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_ORIENTATION_CONTROLLER_H_
#define ATHENA_SYSTEM_ORIENTATION_CONTROLLER_H_
#include "athena/system/device_socket_listener.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
#include "ui/gfx/display.h"
namespace base {
class FilePath;
class FilePathWatcher;
class TaskRunner;
}
namespace athena {
// Monitors accelerometers, detecting orientation changes. When a change is
// detected rotates the root window to match.
class OrientationController
: public DeviceSocketListener,
public base::RefCountedThreadSafe<OrientationController> {
public:
OrientationController(scoped_refptr<base::TaskRunner> io_task_runner);
private:
friend class base::RefCountedThreadSafe<OrientationController>;
virtual ~OrientationController();
// Watch for the socket path to be created, called on the IO thread.
void WatchForSocketPathOnIO();
void OnFilePathChangedOnIO(const base::FilePath& path, bool error);
// Overridden from device::DeviceSocketListener:
virtual void OnDataAvailableOnIO(const void* data) OVERRIDE;
// Rotates the display to |rotation|, called on the UI thread.
void RotateOnUI(gfx::Display::Rotation rotation);
// The last configured rotation.
gfx::Display::Rotation current_rotation_;
// The timestamp of the last applied orientation change.
int64_t last_orientation_change_time_;
// A task runner for the UI thread.
scoped_refptr<base::TaskRunner> ui_task_runner_;
// File path watcher used to detect when sensors are present.
scoped_ptr<base::FilePathWatcher> watcher_;
base::WeakPtrFactory<OrientationController> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(OrientationController);
};
} // namespace athena
#endif // ATHENA_SYSTEM_ORIENTATION_CONTROLLER_H_
......@@ -6,18 +6,13 @@
#define ATHENA_SYSTEM_PUBLIC_SYSTEM_UI_H_
#include "athena/athena_export.h"
#include "base/memory/ref_counted.h"
namespace base {
class TaskRunner;
}
namespace athena {
class ATHENA_EXPORT SystemUI {
public:
// Creates and deletes the singleton object of the SystemUI implementation.
static SystemUI* Create(scoped_refptr<base::TaskRunner> io_task_runner);
static SystemUI* Create();
static void Shutdown();
virtual ~SystemUI() {}
......
......@@ -4,11 +4,8 @@
#include "athena/system/public/system_ui.h"
#include "athena/system/device_socket_listener.h"
#include "athena/system/orientation_controller.h"
#include "athena/system/power_button_controller.h"
#include "base/logging.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
namespace athena {
......@@ -18,16 +15,13 @@ SystemUI* instance = NULL;
class SystemUIImpl : public SystemUI {
public:
SystemUIImpl(scoped_refptr<base::TaskRunner> io_task_runner)
: orientation_controller_(new OrientationController(io_task_runner)),
power_button_controller_(new PowerButtonController) {
SystemUIImpl() : power_button_controller_(new PowerButtonController) {
}
virtual ~SystemUIImpl() {
}
private:
scoped_refptr<OrientationController> orientation_controller_;
scoped_ptr<PowerButtonController> power_button_controller_;
DISALLOW_COPY_AND_ASSIGN(SystemUIImpl);
......@@ -36,10 +30,8 @@ class SystemUIImpl : public SystemUI {
} // namespace
// static
SystemUI* SystemUI::Create(
scoped_refptr<base::TaskRunner> io_task_runner) {
DeviceSocketListener::CreateSocketManager(io_task_runner);
instance = new SystemUIImpl(io_task_runner);
SystemUI* SystemUI::Create() {
instance = new SystemUIImpl;
return instance;
}
......@@ -48,7 +40,6 @@ void SystemUI::Shutdown() {
CHECK(instance);
delete instance;
instance = NULL;
DeviceSocketListener::ShutdownSocketManager();
}
} // namespace athena
......@@ -16,15 +16,6 @@
namespace aura {
namespace {
bool IsRotationPortrait(gfx::Display::Rotation rotation) {
return rotation == gfx::Display::ROTATE_90 ||
rotation == gfx::Display::ROTATE_270;
}
} // namespace
// static
TestScreen* TestScreen::Create(const gfx::Size& size) {
const gfx::Size kDefaultSize(800, 600);
......@@ -56,14 +47,8 @@ void TestScreen::SetDeviceScaleFactor(float device_scale_factor) {
}
void TestScreen::SetDisplayRotation(gfx::Display::Rotation rotation) {
gfx::Rect bounds_in_pixel(display_.GetSizeInPixel());
gfx::Rect new_bounds(bounds_in_pixel);
if (IsRotationPortrait(rotation) != IsRotationPortrait(display_.rotation())) {
new_bounds.set_width(bounds_in_pixel.height());
new_bounds.set_height(bounds_in_pixel.width());
}
display_.set_rotation(rotation);
display_.SetScaleAndBounds(display_.device_scale_factor(), new_bounds);
// TODO(oshima|mukai): Update the display_ as well.
host_->SetRootTransform(GetRotationTransform() * GetUIScaleTransform());
}
......@@ -78,20 +63,21 @@ void TestScreen::SetUIScale(float ui_scale) {
gfx::Transform TestScreen::GetRotationTransform() const {
gfx::Transform rotate;
float one_pixel = 1.0f / display_.device_scale_factor();
switch (display_.rotation()) {
case gfx::Display::ROTATE_0:
break;
case gfx::Display::ROTATE_90:
rotate.Translate(display_.bounds().height(), 0);
rotate.Translate(display_.bounds().height() - one_pixel, 0);
rotate.Rotate(90);
break;
case gfx::Display::ROTATE_270:
rotate.Translate(0, display_.bounds().width());
rotate.Translate(0, display_.bounds().width() - one_pixel);
rotate.Rotate(270);
break;
case gfx::Display::ROTATE_180:
rotate.Translate(display_.bounds().width(),
display_.bounds().height());
rotate.Translate(display_.bounds().width() - one_pixel,
display_.bounds().height() - one_pixel);
rotate.Rotate(180);
break;
}
......
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