1 // Copyright (c) 2012 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 
5 #ifndef CHROME_BROWSER_EXTENSIONS_API_MESSAGING_NATIVE_MESSAGE_PROCESS_HOST_H_
6 #define CHROME_BROWSER_EXTENSIONS_API_MESSAGING_NATIVE_MESSAGE_PROCESS_HOST_H_
7 
8 #include <memory>
9 #include <string>
10 
11 #include "base/containers/queue.h"
12 #include "base/files/file.h"
13 #include "base/macros.h"
14 #include "base/memory/weak_ptr.h"
15 #include "base/process/process.h"
16 #include "base/single_thread_task_runner.h"
17 #include "build/build_config.h"
18 #include "chrome/browser/extensions/api/messaging/native_process_launcher.h"
19 #include "extensions/browser/api/messaging/native_message_host.h"
20 #include "ui/gfx/native_widget_types.h"
21 
22 #if defined(OS_POSIX)
23 #include "base/files/file_descriptor_watcher_posix.h"
24 #endif
25 
26 namespace net {
27 
28 class DrainableIOBuffer;
29 class FileStream;
30 class IOBuffer;
31 class IOBufferWithSize;
32 
33 }  // namespace net
34 
35 namespace extensions {
36 
37 // Manages the native side of a connection between an extension and a native
38 // process.
39 //
40 // This class must only be created, called, and deleted on the IO thread.
41 // Public methods typically accept callbacks which will be invoked on the UI
42 // thread.
43 class NativeMessageProcessHost : public NativeMessageHost {
44  public:
45   ~NativeMessageProcessHost() override;
46 
47   // Create using specified |launcher|. Used in tests.
48   static std::unique_ptr<NativeMessageHost> CreateWithLauncher(
49       const std::string& source_extension_id,
50       const std::string& native_host_name,
51       std::unique_ptr<NativeProcessLauncher> launcher);
52 
53   // extensions::NativeMessageHost implementation.
54   void OnMessage(const std::string& message) override;
55   void Start(Client* client) override;
56   scoped_refptr<base::SingleThreadTaskRunner> task_runner() const override;
57 
58  private:
59   NativeMessageProcessHost(const std::string& source_extension_id,
60                            const std::string& native_host_name,
61                            std::unique_ptr<NativeProcessLauncher> launcher);
62 
63   // Starts the host process.
64   void LaunchHostProcess();
65 
66   // Callback for NativeProcessLauncher::Launch().
67   void OnHostProcessLaunched(NativeProcessLauncher::LaunchResult result,
68                              base::Process process,
69                              base::File read_file,
70                              base::File write_file);
71 
72   // Helper methods to read incoming messages.
73   void WaitRead();
74   void DoRead();
75   void OnRead(int result);
76   void HandleReadResult(int result);
77   void ProcessIncomingData(const char* data, int data_size);
78 
79   // Helper methods to write outgoing messages.
80   void DoWrite();
81   void HandleWriteResult(int result);
82   void OnWritten(int result);
83 
84   // Closes the connection and reports the |error_message| to the client.
85   void Close(const std::string& error_message);
86 
87   // The Client messages will be posted to. Should only be accessed from the
88   // UI thread.
89   Client* client_;
90 
91   // ID of the calling extension.
92   std::string source_extension_id_;
93 
94   // Name of the native messaging host.
95   std::string native_host_name_;
96 
97   // Launcher used to launch the native process.
98   std::unique_ptr<NativeProcessLauncher> launcher_;
99 
100   // Set to true after the native messaging connection has been stopped, e.g.
101   // due to an error.
102   bool closed_;
103 
104   base::Process process_;
105 
106   // Input stream reader.
107   std::unique_ptr<net::FileStream> read_stream_;
108 
109 #if defined(OS_POSIX)
110   base::PlatformFile read_file_;
111   std::unique_ptr<base::FileDescriptorWatcher::Controller> read_controller_;
112 #endif  // !defined(OS_POSIX)
113 
114   // Write stream.
115   std::unique_ptr<net::FileStream> write_stream_;
116 
117   // Read buffer passed to FileStream::Read().
118   scoped_refptr<net::IOBuffer> read_buffer_;
119 
120   // Set to true when a read is pending.
121   bool read_pending_;
122 
123   // Buffer for incomplete incoming messages.
124   std::string incoming_data_;
125 
126   // Queue for outgoing messages.
127   base::queue<scoped_refptr<net::IOBufferWithSize>> write_queue_;
128 
129   // The message that's currently being sent.
130   scoped_refptr<net::DrainableIOBuffer> current_write_buffer_;
131 
132   // Set to true when a write is pending.
133   bool write_pending_;
134 
135   scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
136 
137   base::WeakPtrFactory<NativeMessageProcessHost> weak_factory_{this};
138 
139   DISALLOW_COPY_AND_ASSIGN(NativeMessageProcessHost);
140 };
141 
142 }  // namespace extensions
143 
144 #endif  // CHROME_BROWSER_EXTENSIONS_API_MESSAGING_NATIVE_MESSAGE_PROCESS_HOST_H_
145