1 // Copyright 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.
5 #include "remoting/host/native_messaging/native_messaging_channel.h"
7 #include "base/basictypes.h"
9 #include "base/callback.h"
10 #include "base/location.h"
11 #include "base/values.h"
19 base::PlatformFile DuplicatePlatformFile(base::PlatformFile handle) {
20 base::PlatformFile result;
22 if (!DuplicateHandle(GetCurrentProcess(),
28 DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS)) {
29 PLOG(ERROR) << "Failed to duplicate handle " << handle;
30 return base::kInvalidPlatformFileValue;
33 #elif defined(OS_POSIX)
35 base::ClosePlatformFile(handle);
38 #error Not implemented.
46 NativeMessagingChannel::NativeMessagingChannel(
47 scoped_ptr<Delegate> delegate,
48 base::PlatformFile input,
49 base::PlatformFile output)
50 : native_messaging_reader_(DuplicatePlatformFile(input)),
51 native_messaging_writer_(new NativeMessagingWriter(
52 DuplicatePlatformFile(output))),
53 delegate_(delegate.Pass()),
57 weak_ptr_ = weak_factory_.GetWeakPtr();
60 NativeMessagingChannel::~NativeMessagingChannel() {
63 void NativeMessagingChannel::Start(const base::Closure& quit_closure) {
64 DCHECK(CalledOnValidThread());
65 DCHECK(quit_closure_.is_null());
66 DCHECK(!quit_closure.is_null());
68 quit_closure_ = quit_closure;
69 native_messaging_reader_.Start(
70 base::Bind(&NativeMessagingChannel::ProcessMessage, weak_ptr_),
71 base::Bind(&NativeMessagingChannel::Shutdown, weak_ptr_));
74 void NativeMessagingChannel::ProcessMessage(scoped_ptr<base::Value> message) {
75 DCHECK(CalledOnValidThread());
77 // Don't process any more messages if Shutdown() has been called.
81 if (message->GetType() != base::Value::TYPE_DICTIONARY) {
82 LOG(ERROR) << "Expected DictionaryValue";
87 DCHECK_GE(pending_requests_, 0);
90 scoped_ptr<base::DictionaryValue> message_dict(
91 static_cast<base::DictionaryValue*>(message.release()));
92 delegate_->ProcessMessage(
94 base::Bind(&NativeMessagingChannel::SendResponse, weak_ptr_));
97 void NativeMessagingChannel::SendResponse(
98 scoped_ptr<base::DictionaryValue> response) {
99 DCHECK(CalledOnValidThread());
101 bool success = response && native_messaging_writer_;
103 success = native_messaging_writer_->WriteMessage(*response);
106 // Close the write pipe so no more responses will be sent.
107 native_messaging_writer_.reset();
112 DCHECK_GE(pending_requests_, 0);
114 if (shutdown_ && !pending_requests_)
118 void NativeMessagingChannel::Shutdown() {
119 DCHECK(CalledOnValidThread());
125 if (!pending_requests_)
129 } // namespace remoting