Chromium Code Reviews| 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 CrhomeOS (that is in aura for a Linux desktop). | |
|
Jorge Lucangeli Obes
2013/09/10 20:37:36
Nit: "Chrome OS"
| |
| 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 ChromeOS. | |
| 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& onDataReady) 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 onDataReady_.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 onDataReady_; | |
|
dmazzoni
2013/09/10 19:50:08
onDataReady -> 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& onDataReady) { | |
| 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 onDataReady_ = onDataReady; | |
| 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 |