// Copyright 2022 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "content/public/browser/browser_child_process_observer.h"

#include "base/functional/bind.h"
#include "base/run_loop.h"
#include "build/build_config.h"
#include "content/browser/browser_child_process_host_impl.h"
#include "content/browser/child_process_host_impl.h"
#include "content/browser/service_host/utility_process_host.h"
#include "content/public/browser/browser_child_process_host.h"
#include "content/public/browser/browser_child_process_host_delegate.h"
#include "content/public/browser/child_process_data.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/process_type.h"
#include "content/public/common/sandboxed_process_launcher_delegate.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/content_browser_test.h"
#include "content/public/test/test_service.mojom.h"
#include "sandbox/policy/sandbox_type.h"
#include "testing/gmock/include/gmock/gmock.h"

namespace content {

namespace {

// An enum that represent the different type of notitifcations that exist in
// BrowserChildProcessObserver.
enum class Notification {
  kLaunchedAndConnected,
  kDisconnected,
  kCrashed,
  kKilled,
  kLaunchFailed,
  kExitedNormally,
};

// Nicer test output.
std::ostream& operator<<(std::ostream& os, Notification notification) {
  switch (notification) {
    case Notification::kLaunchedAndConnected:
      os << "LaunchedAndConnected";
      break;
    case Notification::kDisconnected:
      os << "Disconnected";
      break;
    case Notification::kCrashed:
      os << "Crashed";
      break;
    case Notification::kKilled:
      os << "Killed";
      break;
    case Notification::kLaunchFailed:
      os << "LaunchFailed";
      break;
    case Notification::kExitedNormally:
      os << "ExitedNormally";
      break;
  }
  return os;
}

// Returns true if a child process whose ID is |child_id| is still alive.
bool IsHostAlive(int child_id) {
  return BrowserChildProcessHost::FromID(child_id) != nullptr;
}

}  // namespace

// A test BrowserChildProcessObserver that transforms every call to one of the
// observer's method to a call to the notification callback.
class BrowserChildProcessNotificationObserver
    : public BrowserChildProcessObserver {
 public:
  using OnNotificationCallback =
      base::RepeatingCallback<void(Notification notification)>;

  BrowserChildProcessNotificationObserver(
      int child_id,
      OnNotificationCallback on_notification_callback)
      : child_id_(child_id),
        on_notification_callback_(std::move(on_notification_callback)) {
    BrowserChildProcessObserver::Add(this);
  }

  ~BrowserChildProcessNotificationObserver() override {
    BrowserChildProcessObserver::Remove(this);
  }

 protected:
  // BrowserChildProcessObserver:
  void BrowserChildProcessLaunchedAndConnected(
      const ChildProcessData& data) override {
    OnNotification(data, Notification::kLaunchedAndConnected);
  }
  void BrowserChildProcessHostDisconnected(
      const ChildProcessData& data) override {
    OnNotification(data, Notification::kDisconnected);
  }
  void BrowserChildProcessCrashed(
      const ChildProcessData& data,
      const ChildProcessTerminationInfo& info) override {
    OnNotification(data, Notification::kCrashed);
  }
  void BrowserChildProcessKilled(
      const ChildProcessData& data,
      const ChildProcessTerminationInfo& info) override {
    OnNotification(data, Notification::kKilled);
  }
  void BrowserChildProcessLaunchFailed(
      const ChildProcessData& data,
      const ChildProcessTerminationInfo& info) override {
    OnNotification(data, Notification::kLaunchFailed);
  }
  void BrowserChildProcessExitedNormally(
      const ChildProcessData& data,
      const ChildProcessTerminationInfo& info) override {
    OnNotification(data, Notification::kExitedNormally);
  }

  void OnNotification(const ChildProcessData& data, Notification notification) {
    if (data.id == child_id_)
      on_notification_callback_.Run(notification);
  }

 private:
  // Every notification coming for a child with a different ID will be ignored.
  int child_id_;

  // The callback to invoke every time a method of the observer is called.
  OnNotificationCallback on_notification_callback_;
};

// A helper class that allows the user to wait until a specific |notification|
// is sent for a child process whose ID matches |child_id|.
class WaitForNotificationObserver {
 public:
  WaitForNotificationObserver(int child_id, Notification notification)
      : inner_observer_(
            child_id,
            base::BindRepeating(&WaitForNotificationObserver::OnNotification,
                                base::Unretained(this))),
        notification_(notification) {}

  ~WaitForNotificationObserver() = default;

  // Waits until the notification is received. Returns immediately if it was
  // already received.
  void Wait() {
    if (notification_received_)
      return;

    DCHECK(!run_loop_.running());
    run_loop_.Run();
  }

 private:
  void OnNotification(Notification notification) {
    if (notification != notification_)
      return;

    notification_received_ = true;
    if (run_loop_.running())
      run_loop_.Quit();
  }

  BrowserChildProcessNotificationObserver inner_observer_;
  Notification notification_;
  base::RunLoop run_loop_;
  bool notification_received_ = false;
};

class TestSandboxedProcessLauncherDelegate
    : public SandboxedProcessLauncherDelegate {
 public:
  explicit TestSandboxedProcessLauncherDelegate(
      sandbox::mojom::Sandbox sandbox_type)
      : sandbox_type_(sandbox_type) {}
  ~TestSandboxedProcessLauncherDelegate() override = default;

  // SandboxedProcessLauncherDelegate:
  sandbox::mojom::Sandbox GetSandboxType() override { return sandbox_type_; }

 private:
  sandbox::mojom::Sandbox sandbox_type_;
};

// A test-specific type of process host. Self-owned.
class TestProcessHost final : public BrowserChildProcessHostDelegate {
 public:
  static base::WeakPtr<TestProcessHost> Create() {
    auto* instance = new TestProcessHost();
    return instance->GetWeakPtr();
  }

  TestProcessHost()
      : process_(BrowserChildProcessHost::Create(PROCESS_TYPE_UTILITY, this)) {}
  ~TestProcessHost() override = default;

  // Returns the ID of the child process.
  int GetID() { return process_->GetData().id; }

  // Binds to the test service on the child process and returns the bound
  // remote.
  mojo::Remote<mojom::TestService> BindTestService() {
    mojo::Remote<mojom::TestService> test_service;

    static_cast<ChildProcessHostImpl*>(process_->GetHost())
        ->child_process()
        ->BindServiceInterface(test_service.BindNewPipeAndPassReceiver());

    return test_service;
  }

  // Returns the command line used to launch the child process.
  std::unique_ptr<base::CommandLine> GetChildCommandLine() {
    base::FilePath child_path =
        ChildProcessHost::GetChildPath(ChildProcessHost::CHILD_NORMAL);
    auto command_line = std::make_unique<base::CommandLine>(child_path);

    command_line->AppendSwitchASCII(switches::kProcessType,
                                    switches::kUtilityProcess);
    command_line->AppendSwitchASCII(switches::kUtilitySubType,
                                    "Test Utility Process");
    sandbox::policy::SetCommandLineFlagsForSandboxType(command_line.get(),
                                                       sandbox_type_);

    return command_line;
  }

  // Launches the child process using the default test launcher delegate.
  void LaunchProcess() {
    LaunchProcessWithDelegate(
        std::make_unique<TestSandboxedProcessLauncherDelegate>(sandbox_type_));
  }

  // Launches the child process using a supplied sandbox delegate.
  void LaunchProcessWithDelegate(
      std::unique_ptr<SandboxedProcessLauncherDelegate>
          sandboxed_process_launcher_delegate) {
    process_->SetName(u"Test utility process");

    auto command_line = GetChildCommandLine();

    process_->Launch(std::move(sandboxed_process_launcher_delegate),
                     std::move(command_line));

    test_service_ = BindTestService();
  }

  // Requests the child process to shutdown.
  void ForceShutdown() { process_->GetHost()->ForceShutdown(); }

  // Disconnects the bound remote from the test service.
  void Disconnect() { test_service_.reset(); }

  // Sets the sandbox type to use for the child process.
  void SetSandboxType(sandbox::mojom::Sandbox sandbox_type) {
    sandbox_type_ = sandbox_type;
  }

  mojom::TestService* service() const { return test_service_.get(); }

  base::WeakPtr<TestProcessHost> GetWeakPtr() {
    return weak_ptr_factory_.GetWeakPtr();
  }

 private:
  sandbox::mojom::Sandbox sandbox_type_ = sandbox::mojom::Sandbox::kUtility;

  std::unique_ptr<BrowserChildProcessHost> process_;

  mojo::Remote<mojom::TestService> test_service_;

  base::WeakPtrFactory<TestProcessHost> weak_ptr_factory_{this};
};

// A helper class that exposes which notifications were sent for a specific
// child process.
class TestBrowserChildProcessObserver {
 public:
  explicit TestBrowserChildProcessObserver(int child_id)
      : inner_observer_(child_id,
                        base::BindRepeating(
                            &TestBrowserChildProcessObserver::OnNotification,
                            base::Unretained(this))) {}

  ~TestBrowserChildProcessObserver() = default;

  // Returns the notifications received for |child_id|.
  const std::vector<Notification>& notifications() const {
    return notifications_;
  }

 private:
  void OnNotification(Notification notification) {
    notifications_.push_back(notification);
  }

  BrowserChildProcessNotificationObserver inner_observer_;

  std::vector<Notification> notifications_;
};

class BrowserChildProcessObserverBrowserTest : public ContentBrowserTest {};

// Tests that launching and then using ForceShutdown() results in a normal
// termination.
#if defined(ADDRESS_SANITIZER)
// TODO(crbug.com/40238612): Fix ASAN failures on trybot.
#define MAYBE_LaunchAndForceShutdown DISABLED_LaunchAndForceShutdown
#else
#define MAYBE_LaunchAndForceShutdown LaunchAndForceShutdown
#endif
IN_PROC_BROWSER_TEST_F(BrowserChildProcessObserverBrowserTest,
                       MAYBE_LaunchAndForceShutdown) {
  base::WeakPtr<TestProcessHost> host = TestProcessHost::Create();
  int child_id = host->GetID();

  TestBrowserChildProcessObserver observer(child_id);

  {
    WaitForNotificationObserver waiter(child_id,
                                       Notification::kLaunchedAndConnected);
    host->LaunchProcess();
    waiter.Wait();
  }

  {
    WaitForNotificationObserver waiter(child_id, Notification::kDisconnected);
    host->ForceShutdown();
    waiter.Wait();
  }

  Notification kExitNotification =
#if BUILDFLAG(IS_ANDROID)
      // TODO(pmonette): On Android, this currently causes a killed
      // notification. Consider fixing.
      Notification::kKilled;
#else
      Notification::kExitedNormally;
#endif  // BUILDFLAG(IS_ANDROID)

  // The host should be deleted now.
  EXPECT_FALSE(host);
  EXPECT_FALSE(IsHostAlive(child_id));
  EXPECT_THAT(observer.notifications(),
              testing::ElementsAreArray({Notification::kLaunchedAndConnected,
                                         kExitNotification,
                                         Notification::kDisconnected}));
}

// Tests that launching and then deleting the host results in a normal
// termination.
IN_PROC_BROWSER_TEST_F(BrowserChildProcessObserverBrowserTest,
                       LaunchAndDelete) {
  base::WeakPtr<TestProcessHost> host = TestProcessHost::Create();
  int child_id = host->GetID();

  TestBrowserChildProcessObserver observer(child_id);

  {
    WaitForNotificationObserver waiter(child_id,
                                       Notification::kLaunchedAndConnected);
    host->LaunchProcess();
    waiter.Wait();
  }

  {
    WaitForNotificationObserver waiter(child_id, Notification::kDisconnected);
    delete host.get();
    waiter.Wait();
  }

  // The host should be deleted now.
  EXPECT_FALSE(host);
  EXPECT_FALSE(IsHostAlive(child_id));
  EXPECT_THAT(observer.notifications(),
              testing::ElementsAreArray({Notification::kLaunchedAndConnected,
                                         Notification::kExitedNormally,
                                         Notification::kDisconnected}));
}

// Tests that launching and then disconnecting the service channel results in a
// normal termination.
// Note: This only works for services bound using BindServiceInterface(), not
// BindReceiver().
#if defined(ADDRESS_SANITIZER)
// TODO(crbug.com/40238612): Fix ASAN failures on trybot.
#define MAYBE_LaunchAndDisconnect DISABLED_LaunchAndDisconnect
#else
#define MAYBE_LaunchAndDisconnect LaunchAndDisconnect
#endif
IN_PROC_BROWSER_TEST_F(BrowserChildProcessObserverBrowserTest,
                       MAYBE_LaunchAndDisconnect) {
  base::WeakPtr<TestProcessHost> host = TestProcessHost::Create();
  int child_id = host->GetID();

  TestBrowserChildProcessObserver observer(child_id);

  {
    WaitForNotificationObserver waiter(child_id,
                                       Notification::kLaunchedAndConnected);
    host->LaunchProcess();
    waiter.Wait();
  }

  {
    WaitForNotificationObserver waiter(child_id, Notification::kDisconnected);
    host->Disconnect();
    waiter.Wait();
  }

  Notification kExitNotification =
#if BUILDFLAG(IS_ANDROID)
      // On Android, kKilled is always sent in the case of a crash.
      Notification::kKilled;
#else
      Notification::kExitedNormally;
#endif  // BUILDFLAG(IS_ANDROID)

  // The host should be deleted now.
  EXPECT_FALSE(host);
  EXPECT_FALSE(IsHostAlive(child_id));
  EXPECT_THAT(observer.notifications(), testing::ElementsAreArray({
                                            Notification::kLaunchedAndConnected,
                                            kExitNotification,
                                            Notification::kDisconnected,
                                        }));
}

// Tests that launching and then causing a crash the host results in a crashed
// notification.
// TODO(crbug.com/40868150): Times out on Android tests.
// TODO(crbug.com/440535492): Flaky on Win dbg. Re-enable this test.
#if BUILDFLAG(IS_ANDROID) || (BUILDFLAG(IS_WIN) && !defined(NDEBUG))
#define MAYBE_LaunchAndCrash DISABLED_LaunchAndCrash
#else
#define MAYBE_LaunchAndCrash LaunchAndCrash
#endif
IN_PROC_BROWSER_TEST_F(BrowserChildProcessObserverBrowserTest,
                       MAYBE_LaunchAndCrash) {
  base::WeakPtr<TestProcessHost> host = TestProcessHost::Create();
  int child_id = host->GetID();

  TestBrowserChildProcessObserver observer(child_id);

  {
    WaitForNotificationObserver waiter(child_id,
                                       Notification::kLaunchedAndConnected);
    host->LaunchProcess();
    waiter.Wait();
  }

  {
    WaitForNotificationObserver waiter(child_id, Notification::kDisconnected);
    host->service()->DoCrashImmediately(base::DoNothing());
    waiter.Wait();
  }

  Notification kCrashedNotification =
#if BUILDFLAG(IS_ANDROID)
      // On Android, kKilled is always sent in the case of a crash.
      Notification::kKilled;
#else
      Notification::kCrashed;
#endif  // BUILDFLAG(IS_ANDROID)

  // The host should be deleted now.
  EXPECT_FALSE(host);
  EXPECT_FALSE(IsHostAlive(child_id));
  EXPECT_THAT(observer.notifications(),
              testing::ElementsAreArray({Notification::kLaunchedAndConnected,
                                         kCrashedNotification,
                                         Notification::kDisconnected}));
}

// Tests that kLaunchFailed is correctly sent when the child process fails to
// launch.
//
// This test won't work as-is on POSIX platforms, where fork()+exec() is used to
// launch child processes, failure does not happen until exec(), therefore the
// test will see a valid child process followed by a
// TERMINATION_STATUS_ABNORMAL_TERMINATION of the forked process. However,
// posix_spawn() is used on macOS.
// See also ServiceProcessLauncherTest.FailToLaunchProcess.
#if !BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_MAC)
IN_PROC_BROWSER_TEST_F(BrowserChildProcessObserverBrowserTest, LaunchFailed) {
  base::WeakPtr<TestProcessHost> host = TestProcessHost::Create();
  int child_id = host->GetID();

#if BUILDFLAG(IS_WIN)
  // The Windows sandbox does not like the child process being a different
  // process, so launch unsandboxed for the purpose of this test.
  host->SetSandboxType(sandbox::mojom::Sandbox::kNoSandbox);
#endif

  // Simulate a catastrophic launch failure for all child processes by
  // making the path to the process non-existent.
  base::CommandLine::ForCurrentProcess()->AppendSwitchPath(
      switches::kBrowserSubprocessPath,
      base::FilePath(FILE_PATH_LITERAL("non_existent_path")));

  TestBrowserChildProcessObserver observer(child_id);

  {
    WaitForNotificationObserver waiter(child_id, Notification::kLaunchFailed);
    host->LaunchProcess();
    waiter.Wait();
  }

  // The host should be deleted now.
  EXPECT_FALSE(host);
  EXPECT_FALSE(IsHostAlive(child_id));
  EXPECT_THAT(observer.notifications(),
              testing::ElementsAreArray({Notification::kLaunchFailed}));
}
#endif  // !BUILDFLAG(IS_POSIX) || BUILDFLAG(IS_MAC)

#if BUILDFLAG(IS_WIN)
class TestPreSpawnTargetFailureSandboxedProcessLauncherDelegate
    : public TestSandboxedProcessLauncherDelegate {
 public:
  using TestSandboxedProcessLauncherDelegate::
      TestSandboxedProcessLauncherDelegate;

  // SandboxedProcessLauncherDelegate:
  bool PreSpawnTarget(sandbox::TargetPolicy* policy) override {
    // Force a failure in PreSpawnTarget().
    return false;
  }
};

// Override the observer to verify the error occurred in PreSpawnTarget().
class TestPreSpawnTargetFailureBrowserChildProcessNotificationObserver
    : public BrowserChildProcessNotificationObserver {
 public:
  using BrowserChildProcessNotificationObserver::
      BrowserChildProcessNotificationObserver;

  // BrowserChildProcessObserver:
  void BrowserChildProcessLaunchFailed(
      const ChildProcessData& data,
      const ChildProcessTerminationInfo& info) override {
    EXPECT_EQ(info.exit_code, sandbox::SBOX_ERROR_DELEGATE_PRE_SPAWN);
    BrowserChildProcessNotificationObserver::OnNotification(
        data, Notification::kLaunchFailed);
  }
};

// Tests that a pre spawn failure results in a failed launch.
IN_PROC_BROWSER_TEST_F(BrowserChildProcessObserverBrowserTest,
                       LaunchPreSpawnFailed) {
  base::WeakPtr<TestProcessHost> host = TestProcessHost::Create();
  int child_id = host->GetID();

  TestBrowserChildProcessObserver observer(child_id);

  {
    WaitForNotificationObserver waiter(child_id, Notification::kLaunchFailed);
    host->LaunchProcessWithDelegate(
        std::make_unique<
            TestPreSpawnTargetFailureSandboxedProcessLauncherDelegate>(
            sandbox::mojom::Sandbox::kUtility));
    waiter.Wait();
  }

  // The host should be deleted now.
  EXPECT_FALSE(host);
  EXPECT_FALSE(IsHostAlive(child_id));
  EXPECT_THAT(observer.notifications(),
              testing::ElementsAreArray({Notification::kLaunchFailed}));
}
#endif  // BUILDFLAG(IS_WIN)

}  // namespace content
