| 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/messaging/native_message_process_host.h" | 5 #include "chrome/browser/extensions/api/messaging/native_message_process_host.h" |
| 6 | 6 |
| 7 #include "base/bind.h" | 7 #include "base/bind.h" |
| 8 #include "base/files/file_path.h" | 8 #include "base/files/file_path.h" |
| 9 #include "base/logging.h" | 9 #include "base/logging.h" |
| 10 #include "base/platform_file.h" | |
| 11 #include "base/prefs/pref_service.h" | 10 #include "base/prefs/pref_service.h" |
| 12 #include "base/process/kill.h" | 11 #include "base/process/kill.h" |
| 13 #include "base/threading/sequenced_worker_pool.h" | 12 #include "base/threading/sequenced_worker_pool.h" |
| 14 #include "base/values.h" | 13 #include "base/values.h" |
| 15 #include "chrome/browser/extensions/api/messaging/native_messaging_host_manifest
.h" | 14 #include "chrome/browser/extensions/api/messaging/native_messaging_host_manifest
.h" |
| 16 #include "chrome/browser/extensions/api/messaging/native_process_launcher.h" | 15 #include "chrome/browser/extensions/api/messaging/native_process_launcher.h" |
| 17 #include "chrome/common/chrome_version_info.h" | 16 #include "chrome/common/chrome_version_info.h" |
| 18 #include "content/public/browser/browser_thread.h" | 17 #include "content/public/browser/browser_thread.h" |
| 19 #include "extensions/browser/pref_names.h" | 18 #include "extensions/browser/pref_names.h" |
| 20 #include "extensions/common/constants.h" | 19 #include "extensions/common/constants.h" |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 95 base::WeakPtr<Client> weak_client_ui, | 94 base::WeakPtr<Client> weak_client_ui, |
| 96 const std::string& source_extension_id, | 95 const std::string& source_extension_id, |
| 97 const std::string& native_host_name, | 96 const std::string& native_host_name, |
| 98 int destination_port, | 97 int destination_port, |
| 99 scoped_ptr<NativeProcessLauncher> launcher) | 98 scoped_ptr<NativeProcessLauncher> launcher) |
| 100 : weak_client_ui_(weak_client_ui), | 99 : weak_client_ui_(weak_client_ui), |
| 101 source_extension_id_(source_extension_id), | 100 source_extension_id_(source_extension_id), |
| 102 native_host_name_(native_host_name), | 101 native_host_name_(native_host_name), |
| 103 destination_port_(destination_port), | 102 destination_port_(destination_port), |
| 104 launcher_(launcher.Pass()), | 103 launcher_(launcher.Pass()), |
| 104 process_handle_(base::kNullProcessHandle), |
| 105 closed_(false), | 105 closed_(false), |
| 106 process_handle_(base::kNullProcessHandle), | |
| 107 #if defined(OS_POSIX) | |
| 108 read_file_(base::kInvalidPlatformFileValue), | |
| 109 #endif | |
| 110 read_pending_(false), | 106 read_pending_(false), |
| 111 write_pending_(false) { | 107 write_pending_(false), |
| 108 direct_read_for_test_(false) { |
| 112 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 109 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| 113 | 110 |
| 114 // It's safe to use base::Unretained() here because NativeMessagePort always | 111 // It's safe to use base::Unretained() here because NativeMessagePort always |
| 115 // deletes us on the IO thread. | 112 // deletes us on the IO thread. |
| 116 content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE, | 113 content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE, |
| 117 base::Bind(&NativeMessageProcessHost::LaunchHostProcess, | 114 base::Bind(&NativeMessageProcessHost::LaunchHostProcess, |
| 118 base::Unretained(this))); | 115 base::Unretained(this))); |
| 119 } | 116 } |
| 120 | 117 |
| 121 NativeMessageProcessHost::~NativeMessageProcessHost() { | 118 NativeMessageProcessHost::~NativeMessageProcessHost() { |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 181 Close(kForbiddenError); | 178 Close(kForbiddenError); |
| 182 return; | 179 return; |
| 183 case NativeProcessLauncher::RESULT_FAILED_TO_START: | 180 case NativeProcessLauncher::RESULT_FAILED_TO_START: |
| 184 Close(kFailedToStartError); | 181 Close(kFailedToStartError); |
| 185 return; | 182 return; |
| 186 case NativeProcessLauncher::RESULT_SUCCESS: | 183 case NativeProcessLauncher::RESULT_SUCCESS: |
| 187 break; | 184 break; |
| 188 } | 185 } |
| 189 | 186 |
| 190 process_handle_ = process_handle; | 187 process_handle_ = process_handle; |
| 191 #if defined(OS_POSIX) | |
| 192 // This object is not the owner of the file so it should not keep an fd. | |
| 193 read_file_ = read_file.GetPlatformFile(); | |
| 194 #endif | |
| 195 | 188 |
| 196 scoped_refptr<base::TaskRunner> task_runner( | 189 scoped_refptr<base::TaskRunner> task_runner( |
| 197 content::BrowserThread::GetBlockingPool()-> | 190 content::BrowserThread::GetBlockingPool()-> |
| 198 GetTaskRunnerWithShutdownBehavior( | 191 GetTaskRunnerWithShutdownBehavior( |
| 199 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN)); | 192 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN)); |
| 200 | 193 |
| 201 read_stream_.reset(new net::FileStream(read_file.Pass(), task_runner)); | 194 read_stream_.reset(new net::FileStream(read_file.Pass(), task_runner)); |
| 202 write_stream_.reset(new net::FileStream(write_file.Pass(), task_runner)); | 195 write_stream_.reset(new net::FileStream(write_file.Pass(), task_runner)); |
| 203 | 196 |
| 204 WaitRead(); | 197 WaitRead(); |
| (...skipping 18 matching lines...) Expand all Loading... |
| 223 // Push new message to the write queue. | 216 // Push new message to the write queue. |
| 224 write_queue_.push(buffer); | 217 write_queue_.push(buffer); |
| 225 | 218 |
| 226 // Send() may be called before the host process is started. In that case the | 219 // Send() may be called before the host process is started. In that case the |
| 227 // message will be written when OnHostProcessLaunched() is called. If it's | 220 // message will be written when OnHostProcessLaunched() is called. If it's |
| 228 // already started then write the message now. | 221 // already started then write the message now. |
| 229 if (write_stream_) | 222 if (write_stream_) |
| 230 DoWrite(); | 223 DoWrite(); |
| 231 } | 224 } |
| 232 | 225 |
| 233 #if defined(OS_POSIX) | 226 void NativeMessageProcessHost::DontWaitToReadForTesting() { |
| 234 void NativeMessageProcessHost::OnFileCanReadWithoutBlocking(int fd) { | 227 direct_read_for_test_ = true; |
| 235 DCHECK_EQ(fd, read_file_); | |
| 236 DoRead(); | |
| 237 } | |
| 238 | |
| 239 void NativeMessageProcessHost::OnFileCanWriteWithoutBlocking(int fd) { | |
| 240 NOTREACHED(); | |
| 241 } | |
| 242 #endif // !defined(OS_POSIX) | |
| 243 | |
| 244 void NativeMessageProcessHost::ReadNowForTesting() { | |
| 245 DoRead(); | |
| 246 } | 228 } |
| 247 | 229 |
| 248 void NativeMessageProcessHost::WaitRead() { | 230 void NativeMessageProcessHost::WaitRead() { |
| 249 if (closed_) | 231 if (closed_) |
| 250 return; | 232 return; |
| 251 | 233 |
| 252 DCHECK(!read_pending_); | 234 DCHECK(!read_pending_); |
| 253 | |
| 254 // On POSIX FileStream::Read() uses blocking thread pool, so it's better to | |
| 255 // wait for the file to become readable before calling DoRead(). Otherwise it | |
| 256 // would always be consuming one thread in the thread pool. On Windows | |
| 257 // FileStream uses overlapped IO, so that optimization isn't necessary there. | |
| 258 #if defined(OS_POSIX) | |
| 259 base::MessageLoopForIO::current()->WatchFileDescriptor( | |
| 260 read_file_, false /* persistent */, | |
| 261 base::MessageLoopForIO::WATCH_READ, &read_watcher_, this); | |
| 262 #else // defined(OS_POSIX) | |
| 263 DoRead(); | 235 DoRead(); |
| 264 #endif // defined(!OS_POSIX) | |
| 265 } | 236 } |
| 266 | 237 |
| 267 void NativeMessageProcessHost::DoRead() { | 238 void NativeMessageProcessHost::DoRead() { |
| 268 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); | 239 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); |
| 269 | 240 |
| 270 while (!closed_ && !read_pending_) { | 241 while (!closed_ && !read_pending_) { |
| 271 read_buffer_ = new net::IOBuffer(kReadBufferSize); | 242 read_buffer_ = new net::IOBuffer(kReadBufferSize); |
| 272 int result = read_stream_->Read( | 243 int result; |
| 273 read_buffer_.get(), | 244 if (direct_read_for_test_) { |
| 274 kReadBufferSize, | 245 result = read_stream_->Read( |
| 275 base::Bind(&NativeMessageProcessHost::OnRead, base::Unretained(this))); | 246 read_buffer_.get(), |
| 247 kReadBufferSize, |
| 248 base::Bind(&NativeMessageProcessHost::OnRead, |
| 249 base::Unretained(this))); |
| 250 } else { |
| 251 result = read_stream_->ReadNonBlocking( |
| 252 read_buffer_.get(), |
| 253 kReadBufferSize, |
| 254 base::Bind(&NativeMessageProcessHost::OnRead, |
| 255 base::Unretained(this))); |
| 256 } |
| 276 HandleReadResult(result); | 257 HandleReadResult(result); |
| 277 } | 258 } |
| 278 } | 259 } |
| 279 | 260 |
| 280 void NativeMessageProcessHost::OnRead(int result) { | 261 void NativeMessageProcessHost::OnRead(int result) { |
| 281 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); | 262 DCHECK_CURRENTLY_ON(content::BrowserThread::IO); |
| 282 DCHECK(read_pending_); | 263 DCHECK(read_pending_); |
| 283 read_pending_ = false; | 264 read_pending_ = false; |
| 284 | 265 |
| 285 HandleReadResult(result); | 266 HandleReadResult(result); |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 406 content::BrowserThread::PostBlockingPoolTask( | 387 content::BrowserThread::PostBlockingPoolTask( |
| 407 FROM_HERE, base::Bind(&base::EnsureProcessTerminated, process_handle_)); | 388 FROM_HERE, base::Bind(&base::EnsureProcessTerminated, process_handle_)); |
| 408 #else | 389 #else |
| 409 base::EnsureProcessTerminated(process_handle_); | 390 base::EnsureProcessTerminated(process_handle_); |
| 410 #endif | 391 #endif |
| 411 process_handle_ = base::kNullProcessHandle; | 392 process_handle_ = base::kNullProcessHandle; |
| 412 } | 393 } |
| 413 } | 394 } |
| 414 | 395 |
| 415 } // namespace extensions | 396 } // namespace extensions |
| OLD | NEW |