blob: a1e8831ee8919eb004a37f63d93d4f5faa6e1fc3 [file] [log] [blame]
[email protected]55351232013-10-17 12:05:121// 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.
4
kelvinp3a76af72014-09-20 02:45:275#include "remoting/host/native_messaging/pipe_messaging_channel.h"
[email protected]55351232013-10-17 12:05:126
sergeyu1417e0132015-12-23 19:01:227#include <utility>
8
[email protected]55351232013-10-17 12:05:129#include "base/bind.h"
10#include "base/callback.h"
[email protected]8e022322013-11-28 03:49:0611#include "base/callback_helpers.h"
[email protected]55351232013-10-17 12:05:1212#include "base/location.h"
13#include "base/values.h"
avic5960f32015-12-22 22:49:4814#include "build/build_config.h"
[email protected]55351232013-10-17 12:05:1215
16#if defined(OS_POSIX)
17#include <unistd.h>
18#endif
19
20namespace {
21
[email protected]0fa0bbf2014-05-02 04:28:0022base::File DuplicatePlatformFile(base::File file) {
[email protected]55351232013-10-17 12:05:1223 base::PlatformFile result;
24#if defined(OS_WIN)
25 if (!DuplicateHandle(GetCurrentProcess(),
[email protected]0fa0bbf2014-05-02 04:28:0026 file.TakePlatformFile(),
[email protected]55351232013-10-17 12:05:1227 GetCurrentProcess(),
28 &result,
29 0,
30 FALSE,
31 DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS)) {
[email protected]0fa0bbf2014-05-02 04:28:0032 PLOG(ERROR) << "Failed to duplicate handle " << file.GetPlatformFile();
33 return base::File();
[email protected]55351232013-10-17 12:05:1234 }
[email protected]0fa0bbf2014-05-02 04:28:0035 return base::File(result);
[email protected]55351232013-10-17 12:05:1236#elif defined(OS_POSIX)
[email protected]0fa0bbf2014-05-02 04:28:0037 result = dup(file.GetPlatformFile());
38 return base::File(result);
[email protected]55351232013-10-17 12:05:1239#else
40#error Not implemented.
41#endif
42}
43
44} // namespace
45
46namespace remoting {
47
sergeyu1417e0132015-12-23 19:01:2248PipeMessagingChannel::PipeMessagingChannel(base::File input, base::File output)
49 : native_messaging_reader_(DuplicatePlatformFile(std::move(input))),
50 native_messaging_writer_(
51 new NativeMessagingWriter(DuplicatePlatformFile(std::move(output)))),
sergeyuc5f104b2015-01-09 19:33:2452 event_handler_(nullptr),
[email protected]55351232013-10-17 12:05:1253 weak_factory_(this) {
54 weak_ptr_ = weak_factory_.GetWeakPtr();
55}
56
sergeyu1417e0132015-12-23 19:01:2257PipeMessagingChannel::~PipeMessagingChannel() {}
[email protected]55351232013-10-17 12:05:1258
kelvinp3a76af72014-09-20 02:45:2759void PipeMessagingChannel::Start(EventHandler* event_handler) {
[email protected]55351232013-10-17 12:05:1260 DCHECK(CalledOnValidThread());
kelvinp3a76af72014-09-20 02:45:2761 DCHECK(!event_handler_);
[email protected]55351232013-10-17 12:05:1262
kelvinp3a76af72014-09-20 02:45:2763 event_handler_ = event_handler;
64 DCHECK(event_handler_);
[email protected]f2be9402013-12-13 09:15:3565
[email protected]55351232013-10-17 12:05:1266 native_messaging_reader_.Start(
kelvinp3a76af72014-09-20 02:45:2767 base::Bind(&PipeMessagingChannel::ProcessMessage, weak_ptr_),
68 base::Bind(&PipeMessagingChannel::Shutdown, weak_ptr_));
[email protected]55351232013-10-17 12:05:1269}
70
kelvinp3a76af72014-09-20 02:45:2771void PipeMessagingChannel::ProcessMessage(scoped_ptr<base::Value> message) {
[email protected]55351232013-10-17 12:05:1272 DCHECK(CalledOnValidThread());
73
kelvinp3a76af72014-09-20 02:45:2774 if (event_handler_)
sergeyu1417e0132015-12-23 19:01:2275 event_handler_->OnMessage(std::move(message));
[email protected]55351232013-10-17 12:05:1276}
77
sergeyu1417e0132015-12-23 19:01:2278void PipeMessagingChannel::SendMessage(scoped_ptr<base::Value> message) {
[email protected]55351232013-10-17 12:05:1279 DCHECK(CalledOnValidThread());
80
[email protected]8e022322013-11-28 03:49:0681 bool success = message && native_messaging_writer_;
[email protected]55351232013-10-17 12:05:1282 if (success)
[email protected]8e022322013-11-28 03:49:0683 success = native_messaging_writer_->WriteMessage(*message);
[email protected]55351232013-10-17 12:05:1284
85 if (!success) {
86 // Close the write pipe so no more responses will be sent.
87 native_messaging_writer_.reset();
88 Shutdown();
89 }
[email protected]55351232013-10-17 12:05:1290}
91
kelvinp3a76af72014-09-20 02:45:2792void PipeMessagingChannel::Shutdown() {
[email protected]55351232013-10-17 12:05:1293 DCHECK(CalledOnValidThread());
94
kelvinp3a76af72014-09-20 02:45:2795 if (event_handler_) {
sergeyuc5f104b2015-01-09 19:33:2496 // Set |event_handler_| to nullptr to indicate the object is in a shutdown
97 // cycle. Since event_handler->OnDisconnect() will destroy the current
98 // object, |event_handler_| will become a dangling pointer after
99 // OnDisconnect() returns. Therefore, we set |event_handler_| to nullptr
100 // beforehand.
kelvinp3a76af72014-09-20 02:45:27101 EventHandler* handler = event_handler_;
sergeyuc5f104b2015-01-09 19:33:24102 event_handler_ = nullptr;
kelvinp3a76af72014-09-20 02:45:27103 handler->OnDisconnect();
104 }
[email protected]55351232013-10-17 12:05:12105}
106
107} // namespace remoting