// Copyright 2015 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.

#ifndef COMPONENTS_CRASH_CONTENT_BROWSER_CHILD_EXIT_OBSERVER_ANDROID_H_
#define COMPONENTS_CRASH_CONTENT_BROWSER_CHILD_EXIT_OBSERVER_ANDROID_H_

#include <map>
#include <memory>
#include <vector>

#include "base/android/application_status_listener.h"
#include "base/android/child_process_binding_types.h"
#include "base/lazy_instance.h"
#include "base/memory/ref_counted.h"
#include "base/process/process.h"
#include "base/scoped_observer.h"
#include "base/synchronization/lock.h"
#include "components/crash/content/browser/crash_handler_host_linux.h"
#include "content/public/browser/browser_child_process_observer.h"
#include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_registrar.h"
#include "content/public/browser/posix_file_descriptor_info.h"
#include "content/public/common/child_process_host.h"
#include "content/public/common/process_type.h"
#include "third_party/blink/public/common/oom_intervention/oom_intervention_types.h"

namespace content {
struct ChildProcessTerminationInfo;
}

namespace crash_reporter {

// This class centralises the observation of child processes for the
// purpose of reacting to child process crashes.
// The ChildExitObserver instance exists on the browser main thread.
class ChildExitObserver : public content::BrowserChildProcessObserver,
                          public content::NotificationObserver,
                          public crashpad::CrashHandlerHost::Observer {
 public:
  struct TerminationInfo {
    // Used to indicate the child did not receive a crash signal.
    static constexpr int kInvalidSigno = -1;

    TerminationInfo();
    TerminationInfo(const TerminationInfo& other);
    TerminationInfo& operator=(const TerminationInfo& other);

    // TODO(jperaza): Not valid until Crashpad is enabled.
    bool is_crashed() const { return crash_signo != kInvalidSigno; }

    int process_host_id = content::ChildProcessHost::kInvalidUniqueID;
    base::ProcessHandle pid = base::kNullProcessHandle;
    content::ProcessType process_type = content::PROCESS_TYPE_UNKNOWN;
    base::android::ApplicationState app_state =
        base::android::APPLICATION_STATE_UNKNOWN;

    // TODO(jperaza): Not valid until Crashpad is enabled.
    // The crash signal the child process received before it exited.
    int crash_signo = kInvalidSigno;

    // True if this is intentional shutdown of the child process, e.g. when a
    // tab is closed. Some fields below may not be populated if this is true.
    bool normal_termination = false;

    // Values from ChildProcessTerminationInfo.
    // Note base::TerminationStatus and exit_code are missing intentionally
    // because those fields hold no useful information on Android.
    base::android::ChildBindingState binding_state =
        base::android::ChildBindingState::UNBOUND;
    bool was_killed_intentionally_by_browser = false;
    int remaining_process_with_strong_binding = 0;
    int remaining_process_with_moderate_binding = 0;
    int remaining_process_with_waived_binding = 0;

    // Note this is slightly different |has_oom_protection_bindings|.
    // This is equivalent to status == TERMINATION_STATUS_NORMAL_TERMINATION,
    // which historically also checked whether app is in foreground, using
    // a slightly different implementation than
    // ApplicationStatusListener::GetState.
    bool was_oom_protected_status = false;

    // Applies to renderer process only. Generally means renderer is hosting
    // one or more visible tabs.
    bool renderer_has_visible_clients = false;

    // Applies to renderer process only. Generally true indicates that there
    // is no main frame being hosted in this renderer process. Note there are
    // edge cases, eg if an invisible main frame and a visible sub frame from
    // different tabs are sharing the same renderer, then this is false.
    bool renderer_was_subframe = false;

    // Applies to renderer process only. This metrics contains the information
    // about virtual address space OOM situation, private memory footprint,
    // swap size, vm size and the estimation of blink memory usage.
    blink::OomInterventionMetrics blink_oom_metrics;
  };

  // ChildExitObserver client interface.
  // Client methods will be called synchronously in the order in which
  // clients were registered. It is the implementer's responsibility
  // to post tasks to the appropriate threads if required (and be
  // aware that this may break ordering guarantees).
  //
  // Note, callbacks are generated for both "child processes" which are hosted
  // by BrowserChildProcessHosts, and "render processes" which are hosted by
  // RenderProcessHosts. The unique ids correspond to either the
  // ChildProcessData::id, or the RenderProcessHost::ID, depending on the
  // process type.
  class Client {
   public:
    // OnChildStart is called on the launcher thread.
    virtual void OnChildStart(int process_host_id,
                              content::PosixFileDescriptorInfo* mappings) = 0;
    // OnChildExit is called on the UI thread.
    // OnChildExit may be called twice for the same process.
    virtual void OnChildExit(const TerminationInfo& info) = 0;

    virtual ~Client() {}
  };

  // The global ChildExitObserver instance is created by calling
  // Create (on the UI thread), and lives until process exit. Tests
  // making use of this class should register an AtExitManager.
  static void Create();

  // Fetch a pointer to the global ChildExitObserver instance. The
  // global instance must have been created by the time GetInstance is
  // called.
  static ChildExitObserver* GetInstance();

  void RegisterClient(std::unique_ptr<Client> client);

  // crashpad::CrashHandlerHost::Observer
  void ChildReceivedCrashSignal(base::ProcessId pid, int signo) override;

  // BrowserChildProcessStarted must be called from
  // ContentBrowserClient::GetAdditionalMappedFilesForChildProcess
  // overrides, to notify the ChildExitObserver of child process
  // creation, and to allow clients to register any fd mappings they
  // need.
  void BrowserChildProcessStarted(int process_host_id,
                                  content::PosixFileDescriptorInfo* mappings);

 private:
  friend struct base::LazyInstanceTraitsBase<ChildExitObserver>;

  ChildExitObserver();
  ~ChildExitObserver() override;

  // content::BrowserChildProcessObserver implementation:
  void BrowserChildProcessHostDisconnected(
      const content::ChildProcessData& data) override;
  void BrowserChildProcessKilled(
      const content::ChildProcessData& data,
      const content::ChildProcessTerminationInfo& info) override;

  // NotificationObserver implementation:
  void Observe(int type,
               const content::NotificationSource& source,
               const content::NotificationDetails& details) override;

  // Called on child process exit (including crash).
  void OnChildExit(TerminationInfo* info);

  content::NotificationRegistrar notification_registrar_;

  base::Lock registered_clients_lock_;
  std::vector<std::unique_ptr<Client>> registered_clients_;

  // process_host_id to process id. Only accessed on the UI thread.
  std::map<int, base::ProcessHandle> process_host_id_to_pid_;

  // Key is process_host_id. Only used for BrowserChildProcessHost. Only
  // accessed on the UI thread.
  std::map<int, TerminationInfo> browser_child_process_info_;

  base::Lock crash_signals_lock_;
  std::map<base::ProcessId, int> child_pid_to_crash_signal_;
  ScopedObserver<crashpad::CrashHandlerHost,
                 crashpad::CrashHandlerHost::Observer>
      scoped_observer_;

  DISALLOW_COPY_AND_ASSIGN(ChildExitObserver);
};

}  // namespace crash_reporter

#endif  // COMPONENTS_CRASH_CONTENT_BROWSER_CHILD_EXIT_OBSERVER_ANDROID_H_
