#ifndef CHROME_BROWSER_EXTENSIONS_API_MESSAGING_LAUNCH_CONTEXT_H_
#define CHROME_BROWSER_EXTENSIONS_API_MESSAGING_LAUNCH_CONTEXT_H_
#include <stdint.h>
#include <memory>
#include <optional>
#include <string>
#include "base/files/file_path.h"
#include "base/files/platform_file.h"
#include "base/functional/callback.h"
#include "base/memory/scoped_refptr.h"
#include "base/memory/weak_ptr.h"
#include "base/process/process.h"
#include "base/sequence_checker.h"
#include "build/build_config.h"
#include "chrome/browser/extensions/api/messaging/native_process_launcher.h"
#include "url/gurl.h"
#if BUILDFLAG(IS_WIN)
#include "base/win/object_watcher.h"
#endif
namespace base {
class CommandLine;
class TaskRunner;
}
namespace net {
class FileStream;
}
namespace extensions {
class LaunchContext
#if BUILDFLAG(IS_WIN)
: public base::win::ObjectWatcher::Delegate
#endif
{
public:
static std::unique_ptr<LaunchContext> Start(
bool allow_user_level_hosts,
bool require_native_initiated_connections,
bool native_hosts_executables_launch_directly,
intptr_t window_handle,
base::FilePath profile_directory,
std::string connect_id,
std::string error_arg,
GURL origin,
std::string native_host_name,
scoped_refptr<base::TaskRunner> background_task_runner,
NativeProcessLauncher::LaunchedCallback callback);
#if BUILDFLAG(IS_WIN)
~LaunchContext() override;
#else
~LaunchContext();
#endif
private:
LaunchContext(scoped_refptr<base::TaskRunner> background_task_runner,
NativeProcessLauncher::LaunchedCallback callback);
base::WeakPtr<LaunchContext> GetWeakPtr() {
return weak_ptr_factory_.GetWeakPtr();
}
static base::FilePath FindManifest(const std::string& host_name,
bool allow_user_level_hosts,
std::string& error_message);
struct ProcessState {
ProcessState();
ProcessState(base::Process process,
base::ScopedPlatformFile read_file,
base::ScopedPlatformFile write_file);
ProcessState(ProcessState&& other) noexcept;
ProcessState& operator=(ProcessState&& other) noexcept;
~ProcessState();
base::Process process;
base::ScopedPlatformFile read_file;
base::ScopedPlatformFile write_file;
};
static std::optional<ProcessState> LaunchNativeProcess(
const base::CommandLine& command_line,
bool native_hosts_executables_launch_directly);
#if BUILDFLAG(ARKWEB_ARKWEB_EXTENSIONS)
static std::optional<ProcessState> LaunchConnectNative(
const std::string& native_host_name,
const GURL& origin);
#endif
struct BackgroundLaunchResult {
explicit BackgroundLaunchResult(NativeProcessLauncher::LaunchResult result);
explicit BackgroundLaunchResult(ProcessState process_state);
BackgroundLaunchResult(BackgroundLaunchResult&& other) noexcept;
BackgroundLaunchResult& operator=(BackgroundLaunchResult&& other) noexcept;
~BackgroundLaunchResult();
NativeProcessLauncher::LaunchResult result;
std::optional<ProcessState> process_state;
};
static BackgroundLaunchResult LaunchInBackground(
bool allow_user_level_hosts,
bool require_native_initiated_connections,
bool native_hosts_executables_launch_directly,
intptr_t window_handle,
const base::FilePath& profile_directory,
const std::string& connect_id,
const std::string& error_arg,
const GURL& origin,
const std::string& native_host_name);
static void OnProcessLaunched(base::WeakPtr<LaunchContext> weak_this,
BackgroundLaunchResult result);
void ConnectPipes(base::ScopedPlatformFile read_file,
base::ScopedPlatformFile write_file);
#if BUILDFLAG(IS_WIN)
void OnReadStreamConnectResult(int net_error);
void OnWriteStreamConnectResult(int net_error);
void OnPipeConnected();
void OnObjectSignaled(HANDLE object) override;
#endif
void OnSuccess(base::PlatformFile read_file,
std::unique_ptr<net::FileStream> read_stream,
std::unique_ptr<net::FileStream> write_stream);
void OnFailure(NativeProcessLauncher::LaunchResult launch_result);
scoped_refptr<base::TaskRunner> background_task_runner_;
NativeProcessLauncher::LaunchedCallback callback_;
base::Process native_process_;
#if BUILDFLAG(IS_WIN)
std::unique_ptr<net::FileStream> read_stream_;
std::unique_ptr<net::FileStream> write_stream_;
base::win::ObjectWatcher process_watcher_;
bool read_pipe_connected_ = false;
bool write_pipe_connected_ = false;
#endif
SEQUENCE_CHECKER(sequence_checker_);
base::WeakPtrFactory<LaunchContext> weak_ptr_factory_{this};
};
}
#endif