| OLD | NEW | 
| (Empty) |  | 
 |    1 // Copyright (c) 2013 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 "chrome/browser/extensions/api/braille_display_private/brlapi_connectio
     n.h" | 
 |    6  | 
 |    7 #include "base/chromeos/chromeos_version.h" | 
 |    8 #include "base/message_loop/message_loop.h" | 
 |    9  | 
 |   10 namespace extensions { | 
 |   11 using base::MessageLoopForIO; | 
 |   12 namespace api { | 
 |   13 namespace braille_display_private { | 
 |   14  | 
 |   15 namespace { | 
 |   16 // Default virtual terminal.  This can be overriden by setting the | 
 |   17 // WINDOWPATH environment variable.  This is only used when not running | 
 |   18 // under Crhome OS (that is in aura for a Linux desktop). | 
 |   19 // TODO(plundblad): Find a way to detect the controlling terminal of the | 
 |   20 // X server. | 
 |   21 static const int kDefaultTtyLinux = 7; | 
 |   22 #if defined(OS_CHROMEOS) | 
 |   23 // The GUI is always running on vt1 in Chrome OS. | 
 |   24 static const int kDefaultTtyChromeOS = 1; | 
 |   25 #endif | 
 |   26 }  // namespace | 
 |   27  | 
 |   28 class BrlapiConnectionImpl : public BrlapiConnection, | 
 |   29                              MessageLoopForIO::Watcher { | 
 |   30  public: | 
 |   31   BrlapiConnectionImpl(LibBrlapiLoader* loader) : | 
 |   32       libbrlapi_loader_(loader) {} | 
 |   33  | 
 |   34   virtual ~BrlapiConnectionImpl() { | 
 |   35     Disconnect(); | 
 |   36   } | 
 |   37  | 
 |   38   virtual bool Connect(const OnDataReadyCallback& on_data_ready) OVERRIDE; | 
 |   39   virtual void Disconnect() OVERRIDE; | 
 |   40   virtual bool Connected() OVERRIDE { return handle_; } | 
 |   41   virtual brlapi_error_t* BrlapiError() OVERRIDE; | 
 |   42   virtual std::string BrlapiStrError() OVERRIDE; | 
 |   43   virtual bool GetDisplaySize(size_t* size) OVERRIDE; | 
 |   44   virtual bool WriteDots(const unsigned char* cells) OVERRIDE; | 
 |   45   virtual int ReadKey(brlapi_keyCode_t* keyCode) OVERRIDE; | 
 |   46  | 
 |   47   // MessageLoopForIO::Watcher | 
 |   48   virtual void OnFileCanReadWithoutBlocking(int fd) OVERRIDE { | 
 |   49     on_data_ready_.Run(); | 
 |   50   } | 
 |   51  | 
 |   52   virtual void OnFileCanWriteWithoutBlocking(int fd) OVERRIDE {} | 
 |   53  | 
 |   54  private: | 
 |   55   bool CheckConnected(); | 
 |   56  | 
 |   57   LibBrlapiLoader* libbrlapi_loader_; | 
 |   58   scoped_ptr<brlapi_handle_t, base::FreeDeleter> handle_; | 
 |   59   MessageLoopForIO::FileDescriptorWatcher fd_controller_; | 
 |   60   OnDataReadyCallback on_data_ready_; | 
 |   61  | 
 |   62   DISALLOW_COPY_AND_ASSIGN(BrlapiConnectionImpl); | 
 |   63 }; | 
 |   64  | 
 |   65 BrlapiConnection::BrlapiConnection() { | 
 |   66 } | 
 |   67  | 
 |   68 BrlapiConnection::~BrlapiConnection() { | 
 |   69 } | 
 |   70  | 
 |   71 scoped_ptr<BrlapiConnection> BrlapiConnection::Create( | 
 |   72     LibBrlapiLoader* loader) { | 
 |   73   DCHECK(loader->loaded()); | 
 |   74   return scoped_ptr<BrlapiConnection>(new BrlapiConnectionImpl(loader)); | 
 |   75 } | 
 |   76  | 
 |   77 bool BrlapiConnectionImpl::Connect(const OnDataReadyCallback& on_data_ready) { | 
 |   78   DCHECK(!handle_); | 
 |   79   handle_.reset((brlapi_handle_t*) malloc( | 
 |   80       libbrlapi_loader_->brlapi_getHandleSize())); | 
 |   81   int fd = libbrlapi_loader_->brlapi__openConnection(handle_.get(), NULL, NULL); | 
 |   82   if (fd < 0) { | 
 |   83     handle_.reset(); | 
 |   84     LOG(ERROR) << "Error connecting to brlapi: " << BrlapiStrError(); | 
 |   85     return false; | 
 |   86   } | 
 |   87   int path[2] = {0, 0}; | 
 |   88   int pathElements = 0; | 
 |   89 #if defined(OS_CHROMEOS) | 
 |   90   if (base::chromeos::IsRunningOnChromeOS()) | 
 |   91     path[pathElements++] = kDefaultTtyChromeOS; | 
 |   92 #endif | 
 |   93   if (pathElements == 0 && getenv("WINDOWPATH") == NULL) | 
 |   94     path[pathElements++] = kDefaultTtyLinux; | 
 |   95   if (libbrlapi_loader_->brlapi__enterTtyModeWithPath( | 
 |   96           handle_.get(), path, pathElements, NULL) < 0) { | 
 |   97     LOG(ERROR) << "brlapi: couldn't enter tty mode: " << BrlapiStrError(); | 
 |   98     Disconnect(); | 
 |   99     return false; | 
 |  100   } | 
 |  101  | 
 |  102   const brlapi_keyCode_t extraKeys[] = { | 
 |  103     BRLAPI_KEY_TYPE_CMD | BRLAPI_KEY_CMD_OFFLINE, | 
 |  104   }; | 
 |  105   if (libbrlapi_loader_->brlapi__acceptKeys( | 
 |  106           handle_.get(), brlapi_rangeType_command, extraKeys, | 
 |  107           arraysize(extraKeys)) < 0) { | 
 |  108     LOG(ERROR) << "Couldn't acceptKeys: " << BrlapiStrError(); | 
 |  109     Disconnect(); | 
 |  110     return false; | 
 |  111   } | 
 |  112  | 
 |  113   if (!MessageLoopForIO::current()->WatchFileDescriptor( | 
 |  114           fd, true, MessageLoopForIO::WATCH_READ, &fd_controller_, this)) { | 
 |  115     LOG(ERROR) << "Couldn't watch file descriptor " << fd; | 
 |  116     Disconnect(); | 
 |  117     return false; | 
 |  118   } | 
 |  119  | 
 |  120   on_data_ready_ = on_data_ready; | 
 |  121  | 
 |  122   return true; | 
 |  123 } | 
 |  124  | 
 |  125 void BrlapiConnectionImpl::Disconnect() { | 
 |  126   if (!handle_) { | 
 |  127     return; | 
 |  128   } | 
 |  129   fd_controller_.StopWatchingFileDescriptor(); | 
 |  130   libbrlapi_loader_->brlapi__closeConnection( | 
 |  131       handle_.get()); | 
 |  132   handle_.reset(); | 
 |  133 } | 
 |  134  | 
 |  135 brlapi_error_t* BrlapiConnectionImpl::BrlapiError() { | 
 |  136   return libbrlapi_loader_->brlapi_error_location(); | 
 |  137 } | 
 |  138  | 
 |  139 std::string BrlapiConnectionImpl::BrlapiStrError() { | 
 |  140   return libbrlapi_loader_->brlapi_strerror(BrlapiError()); | 
 |  141 } | 
 |  142  | 
 |  143 bool BrlapiConnectionImpl::GetDisplaySize(size_t* size) { | 
 |  144   if (!CheckConnected()) { | 
 |  145     return false; | 
 |  146   } | 
 |  147   unsigned int columns, rows; | 
 |  148   if (libbrlapi_loader_->brlapi__getDisplaySize( | 
 |  149           handle_.get(), &columns, &rows) < 0) { | 
 |  150     LOG(ERROR) << "Couldn't get braille display size " << BrlapiStrError(); | 
 |  151     return false; | 
 |  152   } | 
 |  153   *size = columns * rows; | 
 |  154   return true; | 
 |  155 } | 
 |  156  | 
 |  157 bool BrlapiConnectionImpl::WriteDots(const unsigned char* cells) { | 
 |  158   if (!CheckConnected()) | 
 |  159     return false; | 
 |  160   if (libbrlapi_loader_->brlapi__writeDots(handle_.get(), cells) < 0) { | 
 |  161     LOG(ERROR) << "Couldn't write to brlapi: " << BrlapiStrError(); | 
 |  162     return false; | 
 |  163   } | 
 |  164   return true; | 
 |  165 } | 
 |  166  | 
 |  167 int BrlapiConnectionImpl::ReadKey(brlapi_keyCode_t* key_code) { | 
 |  168   if (!CheckConnected()) | 
 |  169     return -1; | 
 |  170   return libbrlapi_loader_->brlapi__readKey( | 
 |  171       handle_.get(), 0 /*wait*/, key_code); | 
 |  172 } | 
 |  173  | 
 |  174 bool BrlapiConnectionImpl::CheckConnected() { | 
 |  175   if (!handle_) { | 
 |  176     BrlapiError()->brlerrno = BRLAPI_ERROR_ILLEGAL_INSTRUCTION; | 
 |  177     return false; | 
 |  178   } | 
 |  179   return true; | 
 |  180 } | 
 |  181  | 
 |  182 }  // braille_display_private | 
 |  183 }  // api | 
 |  184 }  // extensions | 
| OLD | NEW |