#ifndef CHROME_BROWSER_EXTENSIONS_API_MESSAGING_NATIVE_MESSAGE_PROCESS_HOST_H_
#define CHROME_BROWSER_EXTENSIONS_API_MESSAGING_NATIVE_MESSAGE_PROCESS_HOST_H_
#include <memory>
#include <string>
#include "base/containers/queue.h"
#include "base/files/platform_file.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/process/process.h"
#include "base/task/single_thread_task_runner.h"
#include "build/build_config.h"
#include "chrome/browser/extensions/api/messaging/native_process_launcher.h"
#include "extensions/browser/api/messaging/native_message_host.h"
#if BUILDFLAG(IS_POSIX)
#include "base/files/file_descriptor_watcher_posix.h"
#endif
namespace net {
class DrainableIOBuffer;
class FileStream;
class IOBuffer;
class IOBufferWithSize;
}
namespace extensions {
class NativeMessageProcessHost : public NativeMessageHost {
public:
NativeMessageProcessHost(const NativeMessageProcessHost&) = delete;
NativeMessageProcessHost& operator=(const NativeMessageProcessHost&) = delete;
~NativeMessageProcessHost() override;
static std::unique_ptr<NativeMessageHost> CreateWithLauncher(
const std::string& source_extension_id,
const std::string& native_host_name,
std::unique_ptr<NativeProcessLauncher> launcher);
void OnMessage(const std::string& message) override;
void Start(Client* client) override;
scoped_refptr<base::SingleThreadTaskRunner> task_runner() const override;
private:
NativeMessageProcessHost(const std::string& source_extension_id,
const std::string& native_host_name,
std::unique_ptr<NativeProcessLauncher> launcher);
void LaunchHostProcess();
void OnHostProcessLaunched(NativeProcessLauncher::LaunchResult result,
base::Process process,
base::PlatformFile read_file,
std::unique_ptr<net::FileStream> read_stream,
std::unique_ptr<net::FileStream> write_stream);
void WaitRead();
void DoRead();
void OnRead(int result);
void HandleReadResult(int result);
void ProcessIncomingData(const char* data, int data_size);
void DoWrite();
void HandleWriteResult(int result);
void OnWritten(int result);
void Close(const std::string& error_message);
raw_ptr<Client> client_;
std::string source_extension_id_;
std::string native_host_name_;
std::unique_ptr<NativeProcessLauncher> launcher_;
bool closed_;
base::Process process_;
std::unique_ptr<net::FileStream> read_stream_;
#if BUILDFLAG(IS_POSIX)
base::PlatformFile read_file_;
std::unique_ptr<base::FileDescriptorWatcher::Controller> read_controller_;
#endif
std::unique_ptr<net::FileStream> write_stream_;
scoped_refptr<net::IOBuffer> read_buffer_;
bool read_pending_;
std::string incoming_data_;
base::queue<scoped_refptr<net::IOBufferWithSize>> write_queue_;
scoped_refptr<net::DrainableIOBuffer> current_write_buffer_;
bool write_pending_;
scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
base::WeakPtrFactory<NativeMessageProcessHost> weak_factory_{this};
};
}
#endif