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 |