[email protected] | 5535123 | 2013-10-17 12:05:12 | [diff] [blame] | 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. |
| 4 | |
kelvinp | 3a76af7 | 2014-09-20 02:45:27 | [diff] [blame] | 5 | #include "remoting/host/native_messaging/pipe_messaging_channel.h" |
[email protected] | 5535123 | 2013-10-17 12:05:12 | [diff] [blame] | 6 | |
sergeyu | 1417e013 | 2015-12-23 19:01:22 | [diff] [blame^] | 7 | #include <utility> |
| 8 | |
[email protected] | 5535123 | 2013-10-17 12:05:12 | [diff] [blame] | 9 | #include "base/bind.h" |
| 10 | #include "base/callback.h" |
[email protected] | 8e02232 | 2013-11-28 03:49:06 | [diff] [blame] | 11 | #include "base/callback_helpers.h" |
[email protected] | 5535123 | 2013-10-17 12:05:12 | [diff] [blame] | 12 | #include "base/location.h" |
| 13 | #include "base/values.h" |
avi | c5960f3 | 2015-12-22 22:49:48 | [diff] [blame] | 14 | #include "build/build_config.h" |
[email protected] | 5535123 | 2013-10-17 12:05:12 | [diff] [blame] | 15 | |
| 16 | #if defined(OS_POSIX) |
| 17 | #include <unistd.h> |
| 18 | #endif |
| 19 | |
| 20 | namespace { |
| 21 | |
[email protected] | 0fa0bbf | 2014-05-02 04:28:00 | [diff] [blame] | 22 | base::File DuplicatePlatformFile(base::File file) { |
[email protected] | 5535123 | 2013-10-17 12:05:12 | [diff] [blame] | 23 | base::PlatformFile result; |
| 24 | #if defined(OS_WIN) |
| 25 | if (!DuplicateHandle(GetCurrentProcess(), |
[email protected] | 0fa0bbf | 2014-05-02 04:28:00 | [diff] [blame] | 26 | file.TakePlatformFile(), |
[email protected] | 5535123 | 2013-10-17 12:05:12 | [diff] [blame] | 27 | GetCurrentProcess(), |
| 28 | &result, |
| 29 | 0, |
| 30 | FALSE, |
| 31 | DUPLICATE_CLOSE_SOURCE | DUPLICATE_SAME_ACCESS)) { |
[email protected] | 0fa0bbf | 2014-05-02 04:28:00 | [diff] [blame] | 32 | PLOG(ERROR) << "Failed to duplicate handle " << file.GetPlatformFile(); |
| 33 | return base::File(); |
[email protected] | 5535123 | 2013-10-17 12:05:12 | [diff] [blame] | 34 | } |
[email protected] | 0fa0bbf | 2014-05-02 04:28:00 | [diff] [blame] | 35 | return base::File(result); |
[email protected] | 5535123 | 2013-10-17 12:05:12 | [diff] [blame] | 36 | #elif defined(OS_POSIX) |
[email protected] | 0fa0bbf | 2014-05-02 04:28:00 | [diff] [blame] | 37 | result = dup(file.GetPlatformFile()); |
| 38 | return base::File(result); |
[email protected] | 5535123 | 2013-10-17 12:05:12 | [diff] [blame] | 39 | #else |
| 40 | #error Not implemented. |
| 41 | #endif |
| 42 | } |
| 43 | |
| 44 | } // namespace |
| 45 | |
| 46 | namespace remoting { |
| 47 | |
sergeyu | 1417e013 | 2015-12-23 19:01:22 | [diff] [blame^] | 48 | PipeMessagingChannel::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)))), |
sergeyu | c5f104b | 2015-01-09 19:33:24 | [diff] [blame] | 52 | event_handler_(nullptr), |
[email protected] | 5535123 | 2013-10-17 12:05:12 | [diff] [blame] | 53 | weak_factory_(this) { |
| 54 | weak_ptr_ = weak_factory_.GetWeakPtr(); |
| 55 | } |
| 56 | |
sergeyu | 1417e013 | 2015-12-23 19:01:22 | [diff] [blame^] | 57 | PipeMessagingChannel::~PipeMessagingChannel() {} |
[email protected] | 5535123 | 2013-10-17 12:05:12 | [diff] [blame] | 58 | |
kelvinp | 3a76af7 | 2014-09-20 02:45:27 | [diff] [blame] | 59 | void PipeMessagingChannel::Start(EventHandler* event_handler) { |
[email protected] | 5535123 | 2013-10-17 12:05:12 | [diff] [blame] | 60 | DCHECK(CalledOnValidThread()); |
kelvinp | 3a76af7 | 2014-09-20 02:45:27 | [diff] [blame] | 61 | DCHECK(!event_handler_); |
[email protected] | 5535123 | 2013-10-17 12:05:12 | [diff] [blame] | 62 | |
kelvinp | 3a76af7 | 2014-09-20 02:45:27 | [diff] [blame] | 63 | event_handler_ = event_handler; |
| 64 | DCHECK(event_handler_); |
[email protected] | f2be940 | 2013-12-13 09:15:35 | [diff] [blame] | 65 | |
[email protected] | 5535123 | 2013-10-17 12:05:12 | [diff] [blame] | 66 | native_messaging_reader_.Start( |
kelvinp | 3a76af7 | 2014-09-20 02:45:27 | [diff] [blame] | 67 | base::Bind(&PipeMessagingChannel::ProcessMessage, weak_ptr_), |
| 68 | base::Bind(&PipeMessagingChannel::Shutdown, weak_ptr_)); |
[email protected] | 5535123 | 2013-10-17 12:05:12 | [diff] [blame] | 69 | } |
| 70 | |
kelvinp | 3a76af7 | 2014-09-20 02:45:27 | [diff] [blame] | 71 | void PipeMessagingChannel::ProcessMessage(scoped_ptr<base::Value> message) { |
[email protected] | 5535123 | 2013-10-17 12:05:12 | [diff] [blame] | 72 | DCHECK(CalledOnValidThread()); |
| 73 | |
kelvinp | 3a76af7 | 2014-09-20 02:45:27 | [diff] [blame] | 74 | if (event_handler_) |
sergeyu | 1417e013 | 2015-12-23 19:01:22 | [diff] [blame^] | 75 | event_handler_->OnMessage(std::move(message)); |
[email protected] | 5535123 | 2013-10-17 12:05:12 | [diff] [blame] | 76 | } |
| 77 | |
sergeyu | 1417e013 | 2015-12-23 19:01:22 | [diff] [blame^] | 78 | void PipeMessagingChannel::SendMessage(scoped_ptr<base::Value> message) { |
[email protected] | 5535123 | 2013-10-17 12:05:12 | [diff] [blame] | 79 | DCHECK(CalledOnValidThread()); |
| 80 | |
[email protected] | 8e02232 | 2013-11-28 03:49:06 | [diff] [blame] | 81 | bool success = message && native_messaging_writer_; |
[email protected] | 5535123 | 2013-10-17 12:05:12 | [diff] [blame] | 82 | if (success) |
[email protected] | 8e02232 | 2013-11-28 03:49:06 | [diff] [blame] | 83 | success = native_messaging_writer_->WriteMessage(*message); |
[email protected] | 5535123 | 2013-10-17 12:05:12 | [diff] [blame] | 84 | |
| 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] | 5535123 | 2013-10-17 12:05:12 | [diff] [blame] | 90 | } |
| 91 | |
kelvinp | 3a76af7 | 2014-09-20 02:45:27 | [diff] [blame] | 92 | void PipeMessagingChannel::Shutdown() { |
[email protected] | 5535123 | 2013-10-17 12:05:12 | [diff] [blame] | 93 | DCHECK(CalledOnValidThread()); |
| 94 | |
kelvinp | 3a76af7 | 2014-09-20 02:45:27 | [diff] [blame] | 95 | if (event_handler_) { |
sergeyu | c5f104b | 2015-01-09 19:33:24 | [diff] [blame] | 96 | // 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. |
kelvinp | 3a76af7 | 2014-09-20 02:45:27 | [diff] [blame] | 101 | EventHandler* handler = event_handler_; |
sergeyu | c5f104b | 2015-01-09 19:33:24 | [diff] [blame] | 102 | event_handler_ = nullptr; |
kelvinp | 3a76af7 | 2014-09-20 02:45:27 | [diff] [blame] | 103 | handler->OnDisconnect(); |
| 104 | } |
[email protected] | 5535123 | 2013-10-17 12:05:12 | [diff] [blame] | 105 | } |
| 106 | |
| 107 | } // namespace remoting |