Chromium Code Reviews| Index: chrome/browser/extensions/api/braille_display_private/brlapi_connection.cc |
| diff --git a/chrome/browser/extensions/api/braille_display_private/brlapi_connection.cc b/chrome/browser/extensions/api/braille_display_private/brlapi_connection.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..ec0a9c5c56be3502caddd9e37f3aefaec5bd7b10 |
| --- /dev/null |
| +++ b/chrome/browser/extensions/api/braille_display_private/brlapi_connection.cc |
| @@ -0,0 +1,184 @@ |
| +// Copyright (c) 2013 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 "chrome/browser/extensions/api/braille_display_private/brlapi_connection.h" |
| + |
| +#include "base/chromeos/chromeos_version.h" |
| +#include "base/message_loop/message_loop.h" |
| + |
| +namespace extensions { |
| +using base::MessageLoopForIO; |
| +namespace api { |
| +namespace braille_display_private { |
| + |
| +namespace { |
| +// Default virtual terminal. This can be overriden by setting the |
| +// WINDOWPATH environment variable. This is only used when not running |
| +// under CrhomeOS (that is in aura for a Linux desktop). |
|
Jorge Lucangeli Obes
2013/09/10 20:37:36
Nit: "Chrome OS"
|
| +// TODO(plundblad): Find a way to detect the controlling terminal of the |
| +// X server. |
| +static const int kDefaultTtyLinux = 7; |
| +#if defined(OS_CHROMEOS) |
| +// The GUI is always running on vt1 in ChromeOS. |
| +static const int kDefaultTtyChromeOS = 1; |
| +#endif |
| +} // namespace |
| + |
| +class BrlapiConnectionImpl : public BrlapiConnection, |
| + MessageLoopForIO::Watcher { |
| + public: |
| + BrlapiConnectionImpl(LibBrlapiLoader* loader) : |
| + libbrlapi_loader_(loader) {} |
| + |
| + virtual ~BrlapiConnectionImpl() { |
| + Disconnect(); |
| + } |
| + |
| + virtual bool Connect(const OnDataReadyCallback& onDataReady) OVERRIDE; |
| + virtual void Disconnect() OVERRIDE; |
| + virtual bool Connected() OVERRIDE { return handle_; } |
| + virtual brlapi_error_t* BrlapiError() OVERRIDE; |
| + virtual std::string BrlapiStrError() OVERRIDE; |
| + virtual bool GetDisplaySize(size_t* size) OVERRIDE; |
| + virtual bool WriteDots(const unsigned char* cells) OVERRIDE; |
| + virtual int ReadKey(brlapi_keyCode_t* keyCode) OVERRIDE; |
| + |
| + // MessageLoopForIO::Watcher |
| + virtual void OnFileCanReadWithoutBlocking(int fd) OVERRIDE { |
| + onDataReady_.Run(); |
| + } |
| + |
| + virtual void OnFileCanWriteWithoutBlocking(int fd) OVERRIDE {} |
| + |
| + private: |
| + bool CheckConnected(); |
| + |
| + LibBrlapiLoader* libbrlapi_loader_; |
| + scoped_ptr<brlapi_handle_t, base::FreeDeleter> handle_; |
| + MessageLoopForIO::FileDescriptorWatcher fd_controller_; |
| + OnDataReadyCallback onDataReady_; |
|
dmazzoni
2013/09/10 19:50:08
onDataReady -> on_data_ready
|
| + |
| + DISALLOW_COPY_AND_ASSIGN(BrlapiConnectionImpl); |
| +}; |
| + |
| +BrlapiConnection::BrlapiConnection() { |
| +} |
| + |
| +BrlapiConnection::~BrlapiConnection() { |
| +} |
| + |
| +scoped_ptr<BrlapiConnection> BrlapiConnection::Create( |
| + LibBrlapiLoader* loader) { |
| + DCHECK(loader->loaded()); |
| + return scoped_ptr<BrlapiConnection>(new BrlapiConnectionImpl(loader)); |
| +} |
| + |
| +bool BrlapiConnectionImpl::Connect(const OnDataReadyCallback& onDataReady) { |
| + DCHECK(!handle_); |
| + handle_.reset((brlapi_handle_t*) malloc( |
| + libbrlapi_loader_->brlapi_getHandleSize())); |
| + int fd = libbrlapi_loader_->brlapi__openConnection(handle_.get(), NULL, NULL); |
| + if (fd < 0) { |
| + handle_.reset(); |
| + LOG(ERROR) << "Error connecting to brlapi: " << BrlapiStrError(); |
| + return false; |
| + } |
| + int path[2] = {0, 0}; |
| + int pathElements = 0; |
| +#if defined(OS_CHROMEOS) |
| + if (base::chromeos::IsRunningOnChromeOS()) |
| + path[pathElements++] = kDefaultTtyChromeOS; |
| +#endif |
| + if (pathElements == 0 && getenv("WINDOWPATH") == NULL) |
| + path[pathElements++] = kDefaultTtyLinux; |
| + if (libbrlapi_loader_->brlapi__enterTtyModeWithPath( |
| + handle_.get(), path, pathElements, NULL) < 0) { |
| + LOG(ERROR) << "brlapi: couldn't enter tty mode: " << BrlapiStrError(); |
| + Disconnect(); |
| + return false; |
| + } |
| + |
| + const brlapi_keyCode_t extraKeys[] = { |
| + BRLAPI_KEY_TYPE_CMD | BRLAPI_KEY_CMD_OFFLINE, |
| + }; |
| + if (libbrlapi_loader_->brlapi__acceptKeys( |
| + handle_.get(), brlapi_rangeType_command, extraKeys, |
| + arraysize(extraKeys)) < 0) { |
| + LOG(ERROR) << "Couldn't acceptKeys: " << BrlapiStrError(); |
| + Disconnect(); |
| + return false; |
| + } |
| + |
| + if (!MessageLoopForIO::current()->WatchFileDescriptor( |
| + fd, true, MessageLoopForIO::WATCH_READ, &fd_controller_, this)) { |
| + LOG(ERROR) << "Couldn't watch file descriptor " << fd; |
| + Disconnect(); |
| + return false; |
| + } |
| + |
| + onDataReady_ = onDataReady; |
| + |
| + return true; |
| +} |
| + |
| +void BrlapiConnectionImpl::Disconnect() { |
| + if (!handle_) { |
| + return; |
| + } |
| + fd_controller_.StopWatchingFileDescriptor(); |
| + libbrlapi_loader_->brlapi__closeConnection( |
| + handle_.get()); |
| + handle_.reset(); |
| +} |
| + |
| +brlapi_error_t* BrlapiConnectionImpl::BrlapiError() { |
| + return libbrlapi_loader_->brlapi_error_location(); |
| +} |
| + |
| +std::string BrlapiConnectionImpl::BrlapiStrError() { |
| + return libbrlapi_loader_->brlapi_strerror(BrlapiError()); |
| +} |
| + |
| +bool BrlapiConnectionImpl::GetDisplaySize(size_t* size) { |
| + if (!CheckConnected()) { |
| + return false; |
| + } |
| + unsigned int columns, rows; |
| + if (libbrlapi_loader_->brlapi__getDisplaySize( |
| + handle_.get(), &columns, &rows) < 0) { |
| + LOG(ERROR) << "Couldn't get braille display size " << BrlapiStrError(); |
| + return false; |
| + } |
| + *size = columns * rows; |
| + return true; |
| +} |
| + |
| +bool BrlapiConnectionImpl::WriteDots(const unsigned char* cells) { |
| + if (!CheckConnected()) |
| + return false; |
| + if (libbrlapi_loader_->brlapi__writeDots(handle_.get(), cells) < 0) { |
| + LOG(ERROR) << "Couldn't write to brlapi: " << BrlapiStrError(); |
| + return false; |
| + } |
| + return true; |
| +} |
| + |
| +int BrlapiConnectionImpl::ReadKey(brlapi_keyCode_t* key_code) { |
| + if (!CheckConnected()) |
| + return -1; |
| + return libbrlapi_loader_->brlapi__readKey( |
| + handle_.get(), 0 /*wait*/, key_code); |
| +} |
| + |
| +bool BrlapiConnectionImpl::CheckConnected() { |
| + if (!handle_) { |
| + BrlapiError()->brlerrno = BRLAPI_ERROR_ILLEGAL_INSTRUCTION; |
| + return false; |
| + } |
| + return true; |
| +} |
| + |
| +} // braille_display_private |
| +} // api |
| +} // extensions |