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/callback_helpers.h"
11 #include "base/location.h"
12 #include "base/values.h"
20 base::PlatformFile
DuplicatePlatformFile(base::PlatformFile handle
) {
21 base::PlatformFile result
;
23 if (!DuplicateHandle(GetCurrentProcess(),
29 DUPLICATE_CLOSE_SOURCE
| DUPLICATE_SAME_ACCESS
)) {
30 PLOG(ERROR
) << "Failed to duplicate handle " << handle
;
31 return base::kInvalidPlatformFileValue
;
34 #elif defined(OS_POSIX)
36 base::ClosePlatformFile(handle
);
39 #error Not implemented.
47 NativeMessagingChannel::NativeMessagingChannel(
48 base::PlatformFile input
,
49 base::PlatformFile output
)
50 : native_messaging_reader_(DuplicatePlatformFile(input
)),
51 native_messaging_writer_(new NativeMessagingWriter(
52 DuplicatePlatformFile(output
))),
54 weak_ptr_
= weak_factory_
.GetWeakPtr();
57 NativeMessagingChannel::~NativeMessagingChannel() {
60 void NativeMessagingChannel::Start(const SendMessageCallback
& received_message
,
61 const base::Closure
& quit_closure
) {
62 DCHECK(CalledOnValidThread());
63 DCHECK(received_message_
.is_null());
64 DCHECK(quit_closure_
.is_null());
66 received_message_
= received_message
;
67 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 if (message
->GetType() != base::Value::TYPE_DICTIONARY
) {
78 LOG(ERROR
) << "Expected DictionaryValue";
83 scoped_ptr
<base::DictionaryValue
> message_dict(
84 static_cast<base::DictionaryValue
*>(message
.release()));
85 received_message_
.Run(message_dict
.Pass());
88 void NativeMessagingChannel::SendMessage(
89 scoped_ptr
<base::DictionaryValue
> message
) {
90 DCHECK(CalledOnValidThread());
92 bool success
= message
&& native_messaging_writer_
;
94 success
= native_messaging_writer_
->WriteMessage(*message
);
97 // Close the write pipe so no more responses will be sent.
98 native_messaging_writer_
.reset();
103 void NativeMessagingChannel::Shutdown() {
104 DCHECK(CalledOnValidThread());
106 if (!quit_closure_
.is_null())
107 base::ResetAndReturn(&quit_closure_
).Run();
110 } // namespace remoting