Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(189)

Side by Side Diff: chrome/browser/extensions/api/messaging/native_message_process_host.cc

Issue 637463002: Revert "Remote Assistance on Chrome OS Part III - NativeMessageHost" (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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/prefs/pref_service.h"
10 #include "base/process/kill.h" 11 #include "base/process/kill.h"
11 #include "base/threading/sequenced_worker_pool.h" 12 #include "base/threading/sequenced_worker_pool.h"
13 #include "base/values.h"
12 #include "chrome/browser/extensions/api/messaging/native_messaging_host_manifest .h" 14 #include "chrome/browser/extensions/api/messaging/native_messaging_host_manifest .h"
13 #include "chrome/browser/extensions/api/messaging/native_process_launcher.h" 15 #include "chrome/browser/extensions/api/messaging/native_process_launcher.h"
14 #include "chrome/common/chrome_version_info.h" 16 #include "chrome/common/chrome_version_info.h"
15 #include "content/public/browser/browser_thread.h" 17 #include "content/public/browser/browser_thread.h"
18 #include "extensions/browser/pref_names.h"
16 #include "extensions/common/constants.h" 19 #include "extensions/common/constants.h"
17 #include "extensions/common/features/feature.h" 20 #include "extensions/common/features/feature.h"
18 #include "net/base/file_stream.h" 21 #include "net/base/file_stream.h"
19 #include "net/base/io_buffer.h" 22 #include "net/base/io_buffer.h"
20 #include "net/base/net_errors.h" 23 #include "net/base/net_errors.h"
21 #include "net/base/net_util.h" 24 #include "net/base/net_util.h"
22 #include "url/gurl.h" 25 #include "url/gurl.h"
23 26
24 namespace { 27 namespace {
25 28
26 // Maximum message size in bytes for messages received from Native Messaging 29 // Maximum message size in bytes for messages received from Native Messaging
27 // hosts. Message size is limited mainly to prevent Chrome from crashing when 30 // hosts. Message size is limited mainly to prevent Chrome from crashing when
28 // native application misbehaves (e.g. starts writing garbage to the pipe). 31 // native application misbehaves (e.g. starts writing garbage to the pipe).
29 const size_t kMaximumMessageSize = 1024 * 1024; 32 const size_t kMaximumMessageSize = 1024 * 1024;
30 33
31 // Message header contains 4-byte integer size of the message. 34 // Message header contains 4-byte integer size of the message.
32 const size_t kMessageHeaderSize = 4; 35 const size_t kMessageHeaderSize = 4;
33 36
34 // Size of the buffer to be allocated for each read. 37 // Size of the buffer to be allocated for each read.
35 const size_t kReadBufferSize = 4096; 38 const size_t kReadBufferSize = 4096;
36 39
40 const char kFailedToStartError[] = "Failed to start native messaging host.";
41 const char kInvalidNameError[] =
42 "Invalid native messaging host name specified.";
43 const char kNativeHostExited[] = "Native host has exited.";
44 const char kNotFoundError[] = "Specified native messaging host not found.";
45 const char kForbiddenError[] =
46 "Access to the specified native messaging host is forbidden.";
47 const char kHostInputOuputError[] =
48 "Error when communicating with the native messaging host.";
49
37 } // namespace 50 } // namespace
38 51
39 namespace extensions { 52 namespace extensions {
40 53
54 // static
55 NativeMessageProcessHost::PolicyPermission
56 NativeMessageProcessHost::IsHostAllowed(const PrefService* pref_service,
57 const std::string& native_host_name) {
58 NativeMessageProcessHost::PolicyPermission allow_result = ALLOW_ALL;
59 if (pref_service->IsManagedPreference(
60 pref_names::kNativeMessagingUserLevelHosts)) {
61 if (!pref_service->GetBoolean(pref_names::kNativeMessagingUserLevelHosts))
62 allow_result = ALLOW_SYSTEM_ONLY;
63 }
64
65 // All native messaging hosts are allowed if there is no blacklist.
66 if (!pref_service->IsManagedPreference(pref_names::kNativeMessagingBlacklist))
67 return allow_result;
68 const base::ListValue* blacklist =
69 pref_service->GetList(pref_names::kNativeMessagingBlacklist);
70 if (!blacklist)
71 return allow_result;
72
73 // Check if the name or the wildcard is in the blacklist.
74 base::StringValue name_value(native_host_name);
75 base::StringValue wildcard_value("*");
76 if (blacklist->Find(name_value) == blacklist->end() &&
77 blacklist->Find(wildcard_value) == blacklist->end()) {
78 return allow_result;
79 }
80
81 // The native messaging host is blacklisted. Check the whitelist.
82 if (pref_service->IsManagedPreference(
83 pref_names::kNativeMessagingWhitelist)) {
84 const base::ListValue* whitelist =
85 pref_service->GetList(pref_names::kNativeMessagingWhitelist);
86 if (whitelist && whitelist->Find(name_value) != whitelist->end())
87 return allow_result;
88 }
89
90 return DISALLOW;
91 }
92
41 NativeMessageProcessHost::NativeMessageProcessHost( 93 NativeMessageProcessHost::NativeMessageProcessHost(
94 base::WeakPtr<Client> weak_client_ui,
42 const std::string& source_extension_id, 95 const std::string& source_extension_id,
43 const std::string& native_host_name, 96 const std::string& native_host_name,
97 int destination_port,
44 scoped_ptr<NativeProcessLauncher> launcher) 98 scoped_ptr<NativeProcessLauncher> launcher)
45 : source_extension_id_(source_extension_id), 99 : weak_client_ui_(weak_client_ui),
100 source_extension_id_(source_extension_id),
46 native_host_name_(native_host_name), 101 native_host_name_(native_host_name),
102 destination_port_(destination_port),
47 launcher_(launcher.Pass()), 103 launcher_(launcher.Pass()),
48 closed_(false), 104 closed_(false),
49 process_handle_(base::kNullProcessHandle), 105 process_handle_(base::kNullProcessHandle),
50 #if defined(OS_POSIX) 106 #if defined(OS_POSIX)
51 read_file_(-1), 107 read_file_(-1),
52 #endif 108 #endif
53 read_pending_(false), 109 read_pending_(false),
54 write_pending_(false) { 110 write_pending_(false) {
55 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); 111 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
56 112
57 task_runner_ = content::BrowserThread::GetMessageLoopProxyForThread(
58 content::BrowserThread::IO);
59 // It's safe to use base::Unretained() here because NativeMessagePort always 113 // It's safe to use base::Unretained() here because NativeMessagePort always
60 // deletes us on the IO thread. 114 // deletes us on the IO thread.
61 task_runner_->PostTask( 115 content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE,
62 FROM_HERE,
63 base::Bind(&NativeMessageProcessHost::LaunchHostProcess, 116 base::Bind(&NativeMessageProcessHost::LaunchHostProcess,
64 base::Unretained(this))); 117 base::Unretained(this)));
65 } 118 }
66 119
67 NativeMessageProcessHost::~NativeMessageProcessHost() { 120 NativeMessageProcessHost::~NativeMessageProcessHost() {
68 DCHECK(task_runner_->BelongsToCurrentThread()); 121 DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
122 Close(std::string());
69 } 123 }
70 124
71 // static 125 // static
72 scoped_ptr<NativeMessageHost> NativeMessageHost::Create( 126 scoped_ptr<NativeMessageProcessHost> NativeMessageProcessHost::Create(
73 gfx::NativeView native_view, 127 gfx::NativeView native_view,
128 base::WeakPtr<Client> weak_client_ui,
74 const std::string& source_extension_id, 129 const std::string& source_extension_id,
75 const std::string& native_host_name, 130 const std::string& native_host_name,
76 bool allow_user_level, 131 int destination_port,
77 std::string* error_message) { 132 bool allow_user_level) {
78 return NativeMessageProcessHost::CreateWithLauncher( 133 return CreateWithLauncher(weak_client_ui, source_extension_id,
79 source_extension_id, 134 native_host_name, destination_port,
80 native_host_name, 135 NativeProcessLauncher::CreateDefault(
81 NativeProcessLauncher::CreateDefault(allow_user_level, native_view)); 136 allow_user_level, native_view));
82 } 137 }
83 138
84 // static 139 // static
85 scoped_ptr<NativeMessageHost> NativeMessageProcessHost::CreateWithLauncher( 140 scoped_ptr<NativeMessageProcessHost>
141 NativeMessageProcessHost::CreateWithLauncher(
142 base::WeakPtr<Client> weak_client_ui,
86 const std::string& source_extension_id, 143 const std::string& source_extension_id,
87 const std::string& native_host_name, 144 const std::string& native_host_name,
145 int destination_port,
88 scoped_ptr<NativeProcessLauncher> launcher) { 146 scoped_ptr<NativeProcessLauncher> launcher) {
89 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); 147 DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
90 148
91 scoped_ptr<NativeMessageHost> process( 149 scoped_ptr<NativeMessageProcessHost> process(new NativeMessageProcessHost(
92 new NativeMessageProcessHost(source_extension_id, 150 weak_client_ui, source_extension_id, native_host_name,
93 native_host_name, 151 destination_port, launcher.Pass()));
94 launcher.Pass()));
95 152
96 return process.Pass(); 153 return process.Pass();
97 } 154 }
98 155
99 void NativeMessageProcessHost::LaunchHostProcess() { 156 void NativeMessageProcessHost::LaunchHostProcess() {
100 DCHECK(task_runner_->BelongsToCurrentThread()); 157 DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
101 158
102 GURL origin(std::string(kExtensionScheme) + "://" + source_extension_id_); 159 GURL origin(std::string(kExtensionScheme) + "://" + source_extension_id_);
103 launcher_->Launch(origin, native_host_name_, 160 launcher_->Launch(origin, native_host_name_,
104 base::Bind(&NativeMessageProcessHost::OnHostProcessLaunched, 161 base::Bind(&NativeMessageProcessHost::OnHostProcessLaunched,
105 base::Unretained(this))); 162 base::Unretained(this)));
106 } 163 }
107 164
108 void NativeMessageProcessHost::OnHostProcessLaunched( 165 void NativeMessageProcessHost::OnHostProcessLaunched(
109 NativeProcessLauncher::LaunchResult result, 166 NativeProcessLauncher::LaunchResult result,
110 base::ProcessHandle process_handle, 167 base::ProcessHandle process_handle,
111 base::File read_file, 168 base::File read_file,
112 base::File write_file) { 169 base::File write_file) {
113 DCHECK(task_runner_->BelongsToCurrentThread()); 170 DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
114 171
115 switch (result) { 172 switch (result) {
116 case NativeProcessLauncher::RESULT_INVALID_NAME: 173 case NativeProcessLauncher::RESULT_INVALID_NAME:
117 Close(kInvalidNameError); 174 Close(kInvalidNameError);
118 return; 175 return;
119 case NativeProcessLauncher::RESULT_NOT_FOUND: 176 case NativeProcessLauncher::RESULT_NOT_FOUND:
120 Close(kNotFoundError); 177 Close(kNotFoundError);
121 return; 178 return;
122 case NativeProcessLauncher::RESULT_FORBIDDEN: 179 case NativeProcessLauncher::RESULT_FORBIDDEN:
123 Close(kForbiddenError); 180 Close(kForbiddenError);
(...skipping 16 matching lines...) Expand all
140 GetTaskRunnerWithShutdownBehavior( 197 GetTaskRunnerWithShutdownBehavior(
141 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN)); 198 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN));
142 199
143 read_stream_.reset(new net::FileStream(read_file.Pass(), task_runner)); 200 read_stream_.reset(new net::FileStream(read_file.Pass(), task_runner));
144 write_stream_.reset(new net::FileStream(write_file.Pass(), task_runner)); 201 write_stream_.reset(new net::FileStream(write_file.Pass(), task_runner));
145 202
146 WaitRead(); 203 WaitRead();
147 DoWrite(); 204 DoWrite();
148 } 205 }
149 206
150 void NativeMessageProcessHost::OnMessage(const std::string& json) { 207 void NativeMessageProcessHost::Send(const std::string& json) {
151 DCHECK(task_runner_->BelongsToCurrentThread()); 208 DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
152 209
153 if (closed_) 210 if (closed_)
154 return; 211 return;
155 212
156 // Allocate new buffer for the message. 213 // Allocate new buffer for the message.
157 scoped_refptr<net::IOBufferWithSize> buffer = 214 scoped_refptr<net::IOBufferWithSize> buffer =
158 new net::IOBufferWithSize(json.size() + kMessageHeaderSize); 215 new net::IOBufferWithSize(json.size() + kMessageHeaderSize);
159 216
160 // Copy size and content of the message to the buffer. 217 // Copy size and content of the message to the buffer.
161 COMPILE_ASSERT(sizeof(uint32) == kMessageHeaderSize, incorrect_header_size); 218 COMPILE_ASSERT(sizeof(uint32) == kMessageHeaderSize, incorrect_header_size);
162 *reinterpret_cast<uint32*>(buffer->data()) = json.size(); 219 *reinterpret_cast<uint32*>(buffer->data()) = json.size();
163 memcpy(buffer->data() + kMessageHeaderSize, json.data(), json.size()); 220 memcpy(buffer->data() + kMessageHeaderSize, json.data(), json.size());
164 221
165 // Push new message to the write queue. 222 // Push new message to the write queue.
166 write_queue_.push(buffer); 223 write_queue_.push(buffer);
167 224
168 // Send() may be called before the host process is started. In that case the 225 // Send() may be called before the host process is started. In that case the
169 // message will be written when OnHostProcessLaunched() is called. If it's 226 // message will be written when OnHostProcessLaunched() is called. If it's
170 // already started then write the message now. 227 // already started then write the message now.
171 if (write_stream_) 228 if (write_stream_)
172 DoWrite(); 229 DoWrite();
173 } 230 }
174 231
175 void NativeMessageProcessHost::Start(Client* client) {
176 DCHECK(task_runner_->BelongsToCurrentThread());
177 client_ = client;
178 }
179
180 scoped_refptr<base::SingleThreadTaskRunner>
181 NativeMessageProcessHost::task_runner() const {
182 return task_runner_;
183 }
184
185 #if defined(OS_POSIX) 232 #if defined(OS_POSIX)
186 void NativeMessageProcessHost::OnFileCanReadWithoutBlocking(int fd) { 233 void NativeMessageProcessHost::OnFileCanReadWithoutBlocking(int fd) {
187 DCHECK_EQ(fd, read_file_); 234 DCHECK_EQ(fd, read_file_);
188 DoRead(); 235 DoRead();
189 } 236 }
190 237
191 void NativeMessageProcessHost::OnFileCanWriteWithoutBlocking(int fd) { 238 void NativeMessageProcessHost::OnFileCanWriteWithoutBlocking(int fd) {
192 NOTREACHED(); 239 NOTREACHED();
193 } 240 }
194 #endif // !defined(OS_POSIX) 241 #endif // !defined(OS_POSIX)
(...skipping 15 matching lines...) Expand all
210 #if defined(OS_POSIX) 257 #if defined(OS_POSIX)
211 base::MessageLoopForIO::current()->WatchFileDescriptor( 258 base::MessageLoopForIO::current()->WatchFileDescriptor(
212 read_file_, false /* persistent */, 259 read_file_, false /* persistent */,
213 base::MessageLoopForIO::WATCH_READ, &read_watcher_, this); 260 base::MessageLoopForIO::WATCH_READ, &read_watcher_, this);
214 #else // defined(OS_POSIX) 261 #else // defined(OS_POSIX)
215 DoRead(); 262 DoRead();
216 #endif // defined(!OS_POSIX) 263 #endif // defined(!OS_POSIX)
217 } 264 }
218 265
219 void NativeMessageProcessHost::DoRead() { 266 void NativeMessageProcessHost::DoRead() {
220 DCHECK(task_runner_->BelongsToCurrentThread()); 267 DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
221 268
222 while (!closed_ && !read_pending_) { 269 while (!closed_ && !read_pending_) {
223 read_buffer_ = new net::IOBuffer(kReadBufferSize); 270 read_buffer_ = new net::IOBuffer(kReadBufferSize);
224 int result = read_stream_->Read( 271 int result = read_stream_->Read(
225 read_buffer_.get(), 272 read_buffer_.get(),
226 kReadBufferSize, 273 kReadBufferSize,
227 base::Bind(&NativeMessageProcessHost::OnRead, base::Unretained(this))); 274 base::Bind(&NativeMessageProcessHost::OnRead, base::Unretained(this)));
228 HandleReadResult(result); 275 HandleReadResult(result);
229 } 276 }
230 } 277 }
231 278
232 void NativeMessageProcessHost::OnRead(int result) { 279 void NativeMessageProcessHost::OnRead(int result) {
233 DCHECK(task_runner_->BelongsToCurrentThread()); 280 DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
234 DCHECK(read_pending_); 281 DCHECK(read_pending_);
235 read_pending_ = false; 282 read_pending_ = false;
236 283
237 HandleReadResult(result); 284 HandleReadResult(result);
238 WaitRead(); 285 WaitRead();
239 } 286 }
240 287
241 void NativeMessageProcessHost::HandleReadResult(int result) { 288 void NativeMessageProcessHost::HandleReadResult(int result) {
242 DCHECK(task_runner_->BelongsToCurrentThread()); 289 DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
243 290
244 if (closed_) 291 if (closed_)
245 return; 292 return;
246 293
247 if (result > 0) { 294 if (result > 0) {
248 ProcessIncomingData(read_buffer_->data(), result); 295 ProcessIncomingData(read_buffer_->data(), result);
249 } else if (result == net::ERR_IO_PENDING) { 296 } else if (result == net::ERR_IO_PENDING) {
250 read_pending_ = true; 297 read_pending_ = true;
251 } else if (result == 0 || result == net::ERR_CONNECTION_RESET) { 298 } else if (result == 0 || result == net::ERR_CONNECTION_RESET) {
252 // On Windows we get net::ERR_CONNECTION_RESET for a broken pipe, while on 299 // On Windows we get net::ERR_CONNECTION_RESET for a broken pipe, while on
253 // Posix read() returns 0 in that case. 300 // Posix read() returns 0 in that case.
254 Close(kNativeHostExited); 301 Close(kNativeHostExited);
255 } else { 302 } else {
256 LOG(ERROR) << "Error when reading from Native Messaging host: " << result; 303 LOG(ERROR) << "Error when reading from Native Messaging host: " << result;
257 Close(kHostInputOuputError); 304 Close(kHostInputOuputError);
258 } 305 }
259 } 306 }
260 307
261 void NativeMessageProcessHost::ProcessIncomingData( 308 void NativeMessageProcessHost::ProcessIncomingData(
262 const char* data, int data_size) { 309 const char* data, int data_size) {
263 DCHECK(task_runner_->BelongsToCurrentThread()); 310 DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
264 311
265 incoming_data_.append(data, data_size); 312 incoming_data_.append(data, data_size);
266 313
267 while (true) { 314 while (true) {
268 if (incoming_data_.size() < kMessageHeaderSize) 315 if (incoming_data_.size() < kMessageHeaderSize)
269 return; 316 return;
270 317
271 size_t message_size = 318 size_t message_size =
272 *reinterpret_cast<const uint32*>(incoming_data_.data()); 319 *reinterpret_cast<const uint32*>(incoming_data_.data());
273 320
274 if (message_size > kMaximumMessageSize) { 321 if (message_size > kMaximumMessageSize) {
275 LOG(ERROR) << "Native Messaging host tried sending a message that is " 322 LOG(ERROR) << "Native Messaging host tried sending a message that is "
276 << message_size << " bytes long."; 323 << message_size << " bytes long.";
277 Close(kHostInputOuputError); 324 Close(kHostInputOuputError);
278 return; 325 return;
279 } 326 }
280 327
281 if (incoming_data_.size() < message_size + kMessageHeaderSize) 328 if (incoming_data_.size() < message_size + kMessageHeaderSize)
282 return; 329 return;
283 330
284 client_->PostMessageFromNativeHost( 331 content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
285 incoming_data_.substr(kMessageHeaderSize, message_size)); 332 base::Bind(&Client::PostMessageFromNativeProcess, weak_client_ui_,
333 destination_port_,
334 incoming_data_.substr(kMessageHeaderSize, message_size)));
286 335
287 incoming_data_.erase(0, kMessageHeaderSize + message_size); 336 incoming_data_.erase(0, kMessageHeaderSize + message_size);
288 } 337 }
289 } 338 }
290 339
291 void NativeMessageProcessHost::DoWrite() { 340 void NativeMessageProcessHost::DoWrite() {
292 DCHECK(task_runner_->BelongsToCurrentThread()); 341 DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
293 342
294 while (!write_pending_ && !closed_) { 343 while (!write_pending_ && !closed_) {
295 if (!current_write_buffer_.get() || 344 if (!current_write_buffer_.get() ||
296 !current_write_buffer_->BytesRemaining()) { 345 !current_write_buffer_->BytesRemaining()) {
297 if (write_queue_.empty()) 346 if (write_queue_.empty())
298 return; 347 return;
299 current_write_buffer_ = new net::DrainableIOBuffer( 348 current_write_buffer_ = new net::DrainableIOBuffer(
300 write_queue_.front().get(), write_queue_.front()->size()); 349 write_queue_.front().get(), write_queue_.front()->size());
301 write_queue_.pop(); 350 write_queue_.pop();
302 } 351 }
303 352
304 int result = 353 int result =
305 write_stream_->Write(current_write_buffer_.get(), 354 write_stream_->Write(current_write_buffer_.get(),
306 current_write_buffer_->BytesRemaining(), 355 current_write_buffer_->BytesRemaining(),
307 base::Bind(&NativeMessageProcessHost::OnWritten, 356 base::Bind(&NativeMessageProcessHost::OnWritten,
308 base::Unretained(this))); 357 base::Unretained(this)));
309 HandleWriteResult(result); 358 HandleWriteResult(result);
310 } 359 }
311 } 360 }
312 361
313 void NativeMessageProcessHost::HandleWriteResult(int result) { 362 void NativeMessageProcessHost::HandleWriteResult(int result) {
314 DCHECK(task_runner_->BelongsToCurrentThread()); 363 DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
315 364
316 if (result <= 0) { 365 if (result <= 0) {
317 if (result == net::ERR_IO_PENDING) { 366 if (result == net::ERR_IO_PENDING) {
318 write_pending_ = true; 367 write_pending_ = true;
319 } else { 368 } else {
320 LOG(ERROR) << "Error when writing to Native Messaging host: " << result; 369 LOG(ERROR) << "Error when writing to Native Messaging host: " << result;
321 Close(kHostInputOuputError); 370 Close(kHostInputOuputError);
322 } 371 }
323 return; 372 return;
324 } 373 }
325 374
326 current_write_buffer_->DidConsume(result); 375 current_write_buffer_->DidConsume(result);
327 } 376 }
328 377
329 void NativeMessageProcessHost::OnWritten(int result) { 378 void NativeMessageProcessHost::OnWritten(int result) {
330 DCHECK(task_runner_->BelongsToCurrentThread()); 379 DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
331 380
332 DCHECK(write_pending_); 381 DCHECK(write_pending_);
333 write_pending_ = false; 382 write_pending_ = false;
334 383
335 HandleWriteResult(result); 384 HandleWriteResult(result);
336 DoWrite(); 385 DoWrite();
337 } 386 }
338 387
339 void NativeMessageProcessHost::Close(const std::string& error_message) { 388 void NativeMessageProcessHost::Close(const std::string& error_message) {
340 DCHECK(task_runner_->BelongsToCurrentThread()); 389 DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
341 390
342 if (!closed_) { 391 if (!closed_) {
343 closed_ = true; 392 closed_ = true;
344 read_stream_.reset(); 393 read_stream_.reset();
345 write_stream_.reset(); 394 write_stream_.reset();
346 client_->CloseChannel(error_message); 395 content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
396 base::Bind(&Client::CloseChannel, weak_client_ui_,
397 destination_port_, error_message));
347 } 398 }
348 399
349 if (process_handle_ != base::kNullProcessHandle) { 400 if (process_handle_ != base::kNullProcessHandle) {
350 // Kill the host process if necessary to make sure we don't leave zombies. 401 // Kill the host process if necessary to make sure we don't leave zombies.
351 // On OSX base::EnsureProcessTerminated() may block, so we have to post a 402 // On OSX base::EnsureProcessTerminated() may block, so we have to post a
352 // task on the blocking pool. 403 // task on the blocking pool.
353 #if defined(OS_MACOSX) 404 #if defined(OS_MACOSX)
354 content::BrowserThread::PostBlockingPoolTask( 405 content::BrowserThread::PostBlockingPoolTask(
355 FROM_HERE, base::Bind(&base::EnsureProcessTerminated, process_handle_)); 406 FROM_HERE, base::Bind(&base::EnsureProcessTerminated, process_handle_));
356 #else 407 #else
357 base::EnsureProcessTerminated(process_handle_); 408 base::EnsureProcessTerminated(process_handle_);
358 #endif 409 #endif
359 process_handle_ = base::kNullProcessHandle; 410 process_handle_ = base::kNullProcessHandle;
360 } 411 }
361 } 412 }
362 413
363 } // namespace extensions 414 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698