blob: 014e67de4c486dfeb12d5b5e6ac7ef1ceb097e6e [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
dcheng0765c492016-04-06 22:41:5371void PipeMessagingChannel::ProcessMessage(
72 std::unique_ptr<base::Value> message) {
[email protected]55351232013-10-17 12:05:1273 DCHECK(CalledOnValidThread());
74
kelvinp3a76af72014-09-20 02:45:2775 if (event_handler_)
sergeyu1417e0132015-12-23 19:01:2276 event_handler_->OnMessage(std::move(message));
[email protected]55351232013-10-17 12:05:1277}
78
dcheng0765c492016-04-06 22:41:5379void PipeMessagingChannel::SendMessage(std::unique_ptr<base::Value> message) {
[email protected]55351232013-10-17 12:05:1280 DCHECK(CalledOnValidThread());
81
[email protected]8e022322013-11-28 03:49:0682 bool success = message && native_messaging_writer_;
[email protected]55351232013-10-17 12:05:1283 if (success)
[email protected]8e022322013-11-28 03:49:0684 success = native_messaging_writer_->WriteMessage(*message);
[email protected]55351232013-10-17 12:05:1285
86 if (!success) {
87 // Close the write pipe so no more responses will be sent.
88 native_messaging_writer_.reset();
89 Shutdown();
90 }
[email protected]55351232013-10-17 12:05:1291}
92
kelvinp3a76af72014-09-20 02:45:2793void PipeMessagingChannel::Shutdown() {
[email protected]55351232013-10-17 12:05:1294 DCHECK(CalledOnValidThread());
95
kelvinp3a76af72014-09-20 02:45:2796 if (event_handler_) {
sergeyuc5f104b2015-01-09 19:33:2497 // Set |event_handler_| to nullptr to indicate the object is in a shutdown
98 // cycle. Since event_handler->OnDisconnect() will destroy the current
99 // object, |event_handler_| will become a dangling pointer after
100 // OnDisconnect() returns. Therefore, we set |event_handler_| to nullptr
101 // beforehand.
kelvinp3a76af72014-09-20 02:45:27102 EventHandler* handler = event_handler_;
sergeyuc5f104b2015-01-09 19:33:24103 event_handler_ = nullptr;
kelvinp3a76af72014-09-20 02:45:27104 handler->OnDisconnect();
105 }
[email protected]55351232013-10-17 12:05:12106}
107
108} // namespace remoting