| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/extensions/api/serial/serial_api.h" | 5 #include "chrome/browser/extensions/api/serial/serial_api.h" |
| 6 | 6 |
| 7 #include <string> | 7 #include "base/string_util.h" |
| 8 | |
| 9 #include "base/values.h" | 8 #include "base/values.h" |
| 10 #include "chrome/browser/extensions/api/api_resource_controller.h" | 9 #include "chrome/browser/extensions/api/api_resource_controller.h" |
| 11 #include "chrome/browser/extensions/api/serial/serial_connection.h" | 10 #include "chrome/browser/extensions/api/serial/serial_connection.h" |
| 12 #include "chrome/browser/extensions/api/serial/serial_port_enumerator.h" | 11 #include "chrome/browser/extensions/api/serial/serial_port_enumerator.h" |
| 13 #include "content/public/browser/browser_thread.h" | 12 #include "content/public/browser/browser_thread.h" |
| 14 | 13 |
| 15 using content::BrowserThread; | 14 using content::BrowserThread; |
| 16 | 15 |
| 17 namespace extensions { | 16 namespace extensions { |
| 18 | 17 |
| (...skipping 30 matching lines...) Expand all Loading... |
| 49 | 48 |
| 50 SerialOpenFunction::SerialOpenFunction() | 49 SerialOpenFunction::SerialOpenFunction() |
| 51 : src_id_(-1), | 50 : src_id_(-1), |
| 52 event_notifier_(NULL) {} | 51 event_notifier_(NULL) {} |
| 53 | 52 |
| 54 bool SerialOpenFunction::Prepare() { | 53 bool SerialOpenFunction::Prepare() { |
| 55 set_work_thread_id(BrowserThread::FILE); | 54 set_work_thread_id(BrowserThread::FILE); |
| 56 | 55 |
| 57 size_t argument_position = 0; | 56 size_t argument_position = 0; |
| 58 EXTENSION_FUNCTION_VALIDATE(args_->GetString(argument_position++, &port_)); | 57 EXTENSION_FUNCTION_VALIDATE(args_->GetString(argument_position++, &port_)); |
| 58 EXTENSION_FUNCTION_VALIDATE(IsStringASCII(port_)); |
| 59 |
| 59 src_id_ = ExtractSrcId(argument_position); | 60 src_id_ = ExtractSrcId(argument_position); |
| 60 event_notifier_ = CreateEventNotifier(src_id_); | 61 event_notifier_ = CreateEventNotifier(src_id_); |
| 61 | 62 |
| 62 return true; | 63 return true; |
| 63 } | 64 } |
| 64 | 65 |
| 65 void SerialOpenFunction::AsyncWorkStart() { | 66 void SerialOpenFunction::AsyncWorkStart() { |
| 66 Work(); | 67 Work(); |
| 67 } | 68 } |
| 68 | 69 |
| 69 void SerialOpenFunction::Work() { | 70 void SerialOpenFunction::Work() { |
| 70 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); | 71 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::FILE)); |
| 72 |
| 73 DictionaryValue* result = new DictionaryValue(); |
| 71 const SerialPortEnumerator::StringSet name_set( | 74 const SerialPortEnumerator::StringSet name_set( |
| 72 SerialPortEnumerator::GenerateValidSerialPortNames()); | 75 SerialPortEnumerator::GenerateValidSerialPortNames()); |
| 76 |
| 73 if (SerialPortEnumerator::DoesPortExist(name_set, port_)) { | 77 if (SerialPortEnumerator::DoesPortExist(name_set, port_)) { |
| 74 bool rv = BrowserThread::PostTask( | 78 SerialConnection* serial_connection = new SerialConnection( |
| 75 BrowserThread::IO, FROM_HERE, | |
| 76 base::Bind(&SerialOpenFunction::OpenPortOnIOThread, this)); | |
| 77 DCHECK(rv); | |
| 78 } else { | |
| 79 DictionaryValue* result = new DictionaryValue(); | |
| 80 result->SetInteger(kConnectionIdKey, -1); | |
| 81 result_.reset(result); | |
| 82 AsyncWorkCompleted(); | |
| 83 } | |
| 84 } | |
| 85 | |
| 86 void SerialOpenFunction::OpenPortOnIOThread() { | |
| 87 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); | |
| 88 SerialConnection* serial_connection = new SerialConnection( | |
| 89 port_, | 79 port_, |
| 90 event_notifier_); | 80 event_notifier_); |
| 91 CHECK(serial_connection); | 81 CHECK(serial_connection); |
| 92 int id = controller()->AddAPIResource(serial_connection); | 82 int id = controller()->AddAPIResource(serial_connection); |
| 93 CHECK(id); | 83 CHECK(id); |
| 94 | 84 |
| 95 bool open_result = serial_connection->Open(); | 85 bool open_result = serial_connection->Open(); |
| 96 if (!open_result) { | 86 if (!open_result) { |
| 97 serial_connection->Close(); | 87 serial_connection->Close(); |
| 98 controller()->RemoveAPIResource(id); | 88 controller()->RemoveSerialConnection(id); |
| 99 id = -1; | 89 id = -1; |
| 90 } |
| 91 result->SetInteger(kConnectionIdKey, id); |
| 92 } else { |
| 93 result->SetInteger(kConnectionIdKey, -1); |
| 100 } | 94 } |
| 101 | 95 |
| 102 DictionaryValue* result = new DictionaryValue(); | |
| 103 result->SetInteger(kConnectionIdKey, id); | |
| 104 result_.reset(result); | 96 result_.reset(result); |
| 105 AsyncWorkCompleted(); | 97 AsyncWorkCompleted(); |
| 106 } | 98 } |
| 107 | 99 |
| 108 bool SerialOpenFunction::Respond() { | 100 bool SerialOpenFunction::Respond() { |
| 109 return true; | 101 return true; |
| 110 } | 102 } |
| 111 | 103 |
| 112 bool SerialCloseFunction::Prepare() { | 104 bool SerialCloseFunction::Prepare() { |
| 105 set_work_thread_id(BrowserThread::FILE); |
| 106 |
| 113 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &connection_id_)); | 107 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &connection_id_)); |
| 114 return true; | 108 return true; |
| 115 } | 109 } |
| 116 | 110 |
| 117 void SerialCloseFunction::Work() { | 111 void SerialCloseFunction::Work() { |
| 118 bool close_result = false; | 112 bool close_result = false; |
| 119 SerialConnection* serial_connection = | 113 SerialConnection* serial_connection = |
| 120 controller()->GetSerialConnection(connection_id_); | 114 controller()->GetSerialConnection(connection_id_); |
| 121 if (serial_connection) { | 115 if (serial_connection) { |
| 122 serial_connection->Close(); | 116 serial_connection->Close(); |
| 123 controller()->RemoveAPIResource(connection_id_); | 117 controller()->RemoveSerialConnection(connection_id_); |
| 124 close_result = true; | 118 close_result = true; |
| 125 } | 119 } |
| 126 | 120 |
| 127 result_.reset(Value::CreateBooleanValue(close_result)); | 121 result_.reset(Value::CreateBooleanValue(close_result)); |
| 128 } | 122 } |
| 129 | 123 |
| 130 bool SerialCloseFunction::Respond() { | 124 bool SerialCloseFunction::Respond() { |
| 131 return true; | 125 return true; |
| 132 } | 126 } |
| 133 | 127 |
| 134 bool SerialReadFunction::Prepare() { | 128 bool SerialReadFunction::Prepare() { |
| 129 set_work_thread_id(BrowserThread::FILE); |
| 130 |
| 135 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &connection_id_)); | 131 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &connection_id_)); |
| 136 return true; | 132 return true; |
| 137 } | 133 } |
| 138 | 134 |
| 139 void SerialReadFunction::Work() { | 135 void SerialReadFunction::Work() { |
| 136 uint8 byte = '\0'; |
| 140 int bytes_read = -1; | 137 int bytes_read = -1; |
| 141 std::string data; | |
| 142 SerialConnection* serial_connection = | 138 SerialConnection* serial_connection = |
| 143 controller()->GetSerialConnection(connection_id_); | 139 controller()->GetSerialConnection(connection_id_); |
| 144 if (serial_connection) { | 140 if (serial_connection) |
| 145 unsigned char byte = '\0'; | |
| 146 bytes_read = serial_connection->Read(&byte); | 141 bytes_read = serial_connection->Read(&byte); |
| 147 if (bytes_read == 1) | |
| 148 data = byte; | |
| 149 } | |
| 150 | 142 |
| 151 DictionaryValue* result = new DictionaryValue(); | 143 DictionaryValue* result = new DictionaryValue(); |
| 144 |
| 145 // The API is defined to require a 'data' value, so we will always |
| 146 // create a BinaryValue, even if it's zero-length. |
| 147 if (bytes_read < 0) |
| 148 bytes_read = 0; |
| 152 result->SetInteger(kBytesReadKey, bytes_read); | 149 result->SetInteger(kBytesReadKey, bytes_read); |
| 153 result->SetString(kDataKey, data); | 150 result->Set(kDataKey, base::BinaryValue::CreateWithCopiedBuffer( |
| 151 reinterpret_cast<char*>(&byte), bytes_read)); |
| 154 result_.reset(result); | 152 result_.reset(result); |
| 155 } | 153 } |
| 156 | 154 |
| 157 bool SerialReadFunction::Respond() { | 155 bool SerialReadFunction::Respond() { |
| 158 return true; | 156 return true; |
| 159 } | 157 } |
| 160 | 158 |
| 161 SerialWriteFunction::SerialWriteFunction() | 159 SerialWriteFunction::SerialWriteFunction() |
| 162 : connection_id_(-1), io_buffer_(NULL) { | 160 : connection_id_(-1), io_buffer_(NULL) { |
| 163 } | 161 } |
| 164 | 162 |
| 165 SerialWriteFunction::~SerialWriteFunction() {} | 163 SerialWriteFunction::~SerialWriteFunction() {} |
| 166 | 164 |
| 167 bool SerialWriteFunction::Prepare() { | 165 bool SerialWriteFunction::Prepare() { |
| 166 set_work_thread_id(BrowserThread::FILE); |
| 167 |
| 168 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &connection_id_)); | 168 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &connection_id_)); |
| 169 base::ListValue* data_list_value = NULL; | 169 base::BinaryValue *data = NULL; |
| 170 EXTENSION_FUNCTION_VALIDATE(args_->GetList(1, &data_list_value)); | 170 EXTENSION_FUNCTION_VALIDATE(args_->GetBinary(1, &data)); |
| 171 size_t size = data_list_value->GetSize(); | 171 |
| 172 if (size != 0) { | 172 io_buffer_size_ = data->GetSize(); |
| 173 io_buffer_ = new net::IOBufferWithSize(size); | 173 io_buffer_ = new net::WrappedIOBuffer(data->GetBuffer()); |
| 174 uint8* data_buffer = | 174 |
| 175 reinterpret_cast<uint8*>(io_buffer_->data()); | |
| 176 for (size_t i = 0; i < size; ++i) { | |
| 177 int int_value = -1; | |
| 178 data_list_value->GetInteger(i, &int_value); | |
| 179 DCHECK(int_value < 256); | |
| 180 DCHECK(int_value >= 0); | |
| 181 uint8 truncated_int = static_cast<uint8>(int_value); | |
| 182 *data_buffer++ = truncated_int; | |
| 183 } | |
| 184 } | |
| 185 return true; | 175 return true; |
| 186 } | 176 } |
| 187 | 177 |
| 188 void SerialWriteFunction::Work() { | 178 void SerialWriteFunction::Work() { |
| 189 int bytes_written = -1; | 179 int bytes_written = -1; |
| 190 SerialConnection* serial_connection = | 180 SerialConnection* serial_connection = |
| 191 controller()->GetSerialConnection(connection_id_); | 181 controller()->GetSerialConnection(connection_id_); |
| 192 if (serial_connection) | 182 if (serial_connection) |
| 193 bytes_written = serial_connection->Write(io_buffer_, io_buffer_->size()); | 183 bytes_written = serial_connection->Write(io_buffer_, io_buffer_size_); |
| 194 else | 184 else |
| 195 error_ = kSerialConnectionNotFoundError; | 185 error_ = kSerialConnectionNotFoundError; |
| 196 | 186 |
| 197 DictionaryValue* result = new DictionaryValue(); | 187 DictionaryValue* result = new DictionaryValue(); |
| 198 result->SetInteger(kBytesWrittenKey, bytes_written); | 188 result->SetInteger(kBytesWrittenKey, bytes_written); |
| 199 result_.reset(result); | 189 result_.reset(result); |
| 200 } | 190 } |
| 201 | 191 |
| 202 bool SerialWriteFunction::Respond() { | 192 bool SerialWriteFunction::Respond() { |
| 203 return true; | 193 return true; |
| 204 } | 194 } |
| 205 | 195 |
| 206 } // namespace extensions | 196 } // namespace extensions |
| OLD | NEW |