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::File
DuplicatePlatformFile(base::File file
) {
21 base::PlatformFile result
;
23 if (!DuplicateHandle(GetCurrentProcess(),
24 file
.TakePlatformFile(),
29 DUPLICATE_CLOSE_SOURCE
| DUPLICATE_SAME_ACCESS
)) {
30 PLOG(ERROR
) << "Failed to duplicate handle " << file
.GetPlatformFile();
33 return base::File(result
);
34 #elif defined(OS_POSIX)
35 result
= dup(file
.GetPlatformFile());
36 return base::File(result
);
38 #error Not implemented.
46 NativeMessagingChannel::NativeMessagingChannel(
49 : native_messaging_reader_(DuplicatePlatformFile(input
.Pass())),
50 native_messaging_writer_(new NativeMessagingWriter(
51 DuplicatePlatformFile(output
.Pass()))),
53 weak_ptr_
= weak_factory_
.GetWeakPtr();
56 NativeMessagingChannel::~NativeMessagingChannel() {
59 void NativeMessagingChannel::Start(const SendMessageCallback
& received_message
,
60 const base::Closure
& quit_closure
) {
61 DCHECK(CalledOnValidThread());
62 DCHECK(received_message_
.is_null());
63 DCHECK(quit_closure_
.is_null());
65 received_message_
= received_message
;
66 quit_closure_
= quit_closure
;
68 native_messaging_reader_
.Start(
69 base::Bind(&NativeMessagingChannel::ProcessMessage
, weak_ptr_
),
70 base::Bind(&NativeMessagingChannel::Shutdown
, weak_ptr_
));
73 void NativeMessagingChannel::ProcessMessage(scoped_ptr
<base::Value
> message
) {
74 DCHECK(CalledOnValidThread());
76 if (message
->GetType() != base::Value::TYPE_DICTIONARY
) {
77 LOG(ERROR
) << "Expected DictionaryValue";
82 scoped_ptr
<base::DictionaryValue
> message_dict(
83 static_cast<base::DictionaryValue
*>(message
.release()));
84 received_message_
.Run(message_dict
.Pass());
87 void NativeMessagingChannel::SendMessage(
88 scoped_ptr
<base::DictionaryValue
> message
) {
89 DCHECK(CalledOnValidThread());
91 bool success
= message
&& native_messaging_writer_
;
93 success
= native_messaging_writer_
->WriteMessage(*message
);
96 // Close the write pipe so no more responses will be sent.
97 native_messaging_writer_
.reset();
102 void NativeMessagingChannel::Shutdown() {
103 DCHECK(CalledOnValidThread());
105 if (!quit_closure_
.is_null())
106 base::ResetAndReturn(&quit_closure_
).Run();
109 } // namespace remoting