// Copyright 2022 The Chromium Authors. All rights reserved.
// 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/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);
  }

 private:
  // 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);
  }

  // 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 : public BrowserChildProcessHostDelegate {
 public:
  static base::WeakPtr<TestProcessHost> Create() {
    auto* instance = new TestProcessHost();
    return instance->GetWeakPtr();
  }

  TestProcessHost()
      : process_(BrowserChildProcessHost::Create(
            PROCESS_TYPE_UTILITY,
            this,
            ChildProcessHost::IpcMode::kNormal)) {}
  ~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.
  void LaunchProcess() {
    process_->SetName(u"Test utility process");

    auto sandboxed_process_launcher_delegate =
        std::make_unique<TestSandboxedProcessLauncherDelegate>(sandbox_type_);
    auto command_line = GetChildCommandLine();
    bool terminate_on_shutdown = true;

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

    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(https://crbug.com/1363257): 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(https://crbug.com/1363257): 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(https://crbug.com/1368044): Times out on Android tests.
#if BUILDFLAG(IS_ANDROID)
#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)

}  // namespace content
