// Copyright (c) 2012 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/browser/child_process_launcher.h"

#include <utility>  // For std::pair.

#include "base/bind.h"
#include "base/command_line.h"
#include "base/file_util.h"
#include "base/logging.h"
#include "base/memory/scoped_ptr.h"
#include "base/metrics/histogram.h"
#include "base/process/process.h"
#include "base/synchronization/lock.h"
#include "base/threading/thread.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/common/content_descriptors.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/result_codes.h"

#if defined(OS_WIN)
#include "base/files/file_path.h"
#include "content/common/sandbox_win.h"
#include "content/public/common/sandbox_init.h"
#include "content/public/common/sandboxed_process_launcher_delegate.h"
#elif defined(OS_MACOSX)
#include "content/browser/mach_broker_mac.h"
#elif defined(OS_ANDROID)
#include "base/android/jni_android.h"
#include "content/browser/android/child_process_launcher_android.h"
#elif defined(OS_POSIX)
#include "base/memory/shared_memory.h"
#include "base/memory/singleton.h"
#include "content/browser/renderer_host/render_sandbox_host_linux.h"
#include "content/browser/zygote_host/zygote_host_impl_linux.h"
#include "content/common/child_process_sandbox_support_impl_linux.h"
#endif

#if defined(OS_POSIX)
#include "base/metrics/stats_table.h"
#include "base/posix/global_descriptors.h"
#endif

namespace content {

// Having the functionality of ChildProcessLauncher be in an internal
// ref counted object allows us to automatically terminate the process when the
// parent class destructs, while still holding on to state that we need.
class ChildProcessLauncher::Context
    : public base::RefCountedThreadSafe<ChildProcessLauncher::Context> {
 public:
  Context()
      : client_(NULL),
        client_thread_id_(BrowserThread::UI),
        termination_status_(base::TERMINATION_STATUS_NORMAL_TERMINATION),
        exit_code_(RESULT_CODE_NORMAL_EXIT),
        starting_(true)
#if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID)
        , zygote_(false)
#endif
        {
#if defined(OS_POSIX)
          terminate_child_on_shutdown_ = !CommandLine::ForCurrentProcess()->
              HasSwitch(switches::kChildCleanExit);
#else
          terminate_child_on_shutdown_ = true;
#endif
  }

  void Launch(
#if defined(OS_WIN)
      SandboxedProcessLauncherDelegate* delegate,
#elif defined(OS_ANDROID)
      int ipcfd,
#elif defined(OS_POSIX)
      bool use_zygote,
      const base::EnvironmentMap& environ,
      int ipcfd,
#endif
      CommandLine* cmd_line,
      int child_process_id,
      Client* client) {
    client_ = client;

    CHECK(BrowserThread::GetCurrentThreadIdentifier(&client_thread_id_));

#if defined(OS_ANDROID)
    // We need to close the client end of the IPC channel to reliably detect
    // child termination. We will close this fd after we create the child
    // process which is asynchronous on Android.
    ipcfd_ = ipcfd;
#endif
    BrowserThread::PostTask(
        BrowserThread::PROCESS_LAUNCHER, FROM_HERE,
        base::Bind(
            &Context::LaunchInternal,
            make_scoped_refptr(this),
            client_thread_id_,
            child_process_id,
#if defined(OS_WIN)
            delegate,
#elif defined(OS_ANDROID)
            ipcfd,
#elif defined(OS_POSIX)
            use_zygote,
            environ,
            ipcfd,
#endif
            cmd_line));
  }

#if defined(OS_ANDROID)
  static void OnChildProcessStarted(
      // |this_object| is NOT thread safe. Only use it to post a task back.
      scoped_refptr<Context> this_object,
      BrowserThread::ID client_thread_id,
      const base::TimeTicks begin_launch_time,
      base::ProcessHandle handle) {
    RecordHistograms(begin_launch_time);
    if (BrowserThread::CurrentlyOn(client_thread_id)) {
      // This is always invoked on the UI thread which is commonly the
      // |client_thread_id| so we can shortcut one PostTask.
      this_object->Notify(handle);
    } else {
      BrowserThread::PostTask(
          client_thread_id, FROM_HERE,
          base::Bind(
              &ChildProcessLauncher::Context::Notify,
              this_object,
              handle));
    }
  }
#endif

  void ResetClient() {
    // No need for locking as this function gets called on the same thread that
    // client_ would be used.
    CHECK(BrowserThread::CurrentlyOn(client_thread_id_));
    client_ = NULL;
  }

  void set_terminate_child_on_shutdown(bool terminate_on_shutdown) {
    terminate_child_on_shutdown_ = terminate_on_shutdown;
  }

 private:
  friend class base::RefCountedThreadSafe<ChildProcessLauncher::Context>;
  friend class ChildProcessLauncher;

  ~Context() {
    Terminate();
  }

  static void RecordHistograms(const base::TimeTicks begin_launch_time) {
    base::TimeDelta launch_time = base::TimeTicks::Now() - begin_launch_time;
    if (BrowserThread::CurrentlyOn(BrowserThread::PROCESS_LAUNCHER)) {
      RecordLaunchHistograms(launch_time);
    } else {
      BrowserThread::PostTask(
          BrowserThread::PROCESS_LAUNCHER, FROM_HERE,
          base::Bind(&ChildProcessLauncher::Context::RecordLaunchHistograms,
                     launch_time));
    }
  }

  static void RecordLaunchHistograms(const base::TimeDelta launch_time) {
    // Log the launch time, separating out the first one (which will likely be
    // slower due to the rest of the browser initializing at the same time).
    static bool done_first_launch = false;
    if (done_first_launch) {
      UMA_HISTOGRAM_TIMES("MPArch.ChildProcessLaunchSubsequent", launch_time);
    } else {
      UMA_HISTOGRAM_TIMES("MPArch.ChildProcessLaunchFirst", launch_time);
      done_first_launch = true;
    }
  }

  static void LaunchInternal(
      // |this_object| is NOT thread safe. Only use it to post a task back.
      scoped_refptr<Context> this_object,
      BrowserThread::ID client_thread_id,
      int child_process_id,
#if defined(OS_WIN)
      SandboxedProcessLauncherDelegate* delegate,
#elif defined(OS_ANDROID)
      int ipcfd,
#elif defined(OS_POSIX)
      bool use_zygote,
      const base::EnvironmentMap& env,
      int ipcfd,
#endif
      CommandLine* cmd_line) {
    scoped_ptr<CommandLine> cmd_line_deleter(cmd_line);
    base::TimeTicks begin_launch_time = base::TimeTicks::Now();

#if defined(OS_WIN)
    scoped_ptr<SandboxedProcessLauncherDelegate> delegate_deleter(delegate);
    base::ProcessHandle handle = StartSandboxedProcess(delegate, cmd_line);
#elif defined(OS_POSIX)
    std::string process_type =
        cmd_line->GetSwitchValueASCII(switches::kProcessType);
    std::vector<FileDescriptorInfo> files_to_register;
    files_to_register.push_back(
        FileDescriptorInfo(kPrimaryIPCChannel,
                           base::FileDescriptor(ipcfd, false)));
    base::StatsTable* stats_table = base::StatsTable::current();
    if (stats_table &&
        base::SharedMemory::IsHandleValid(
            stats_table->GetSharedMemoryHandle())) {
      files_to_register.push_back(
          FileDescriptorInfo(kStatsTableSharedMemFd,
                             stats_table->GetSharedMemoryHandle()));
    }
#endif

#if defined(OS_ANDROID)
    // Android WebView runs in single process, ensure that we never get here
    // when running in single process mode.
    CHECK(!cmd_line->HasSwitch(switches::kSingleProcess));

    GetContentClient()->browser()->
        GetAdditionalMappedFilesForChildProcess(*cmd_line, child_process_id,
                                                &files_to_register);

    StartChildProcess(cmd_line->argv(), files_to_register,
        base::Bind(&ChildProcessLauncher::Context::OnChildProcessStarted,
                   this_object, client_thread_id, begin_launch_time));

#elif defined(OS_POSIX)
    base::ProcessHandle handle = base::kNullProcessHandle;
    // We need to close the client end of the IPC channel to reliably detect
    // child termination.
    file_util::ScopedFD ipcfd_closer(&ipcfd);

#if !defined(OS_MACOSX)
    GetContentClient()->browser()->
        GetAdditionalMappedFilesForChildProcess(*cmd_line, child_process_id,
                                                &files_to_register);
    if (use_zygote) {
      handle = ZygoteHostImpl::GetInstance()->ForkRequest(cmd_line->argv(),
                                                          files_to_register,
                                                          process_type);
    } else
    // Fall through to the normal posix case below when we're not zygoting.
#endif  // !defined(OS_MACOSX)
    {
      // Convert FD mapping to FileHandleMappingVector
      base::FileHandleMappingVector fds_to_map;
      for (size_t i = 0; i < files_to_register.size(); ++i) {
        fds_to_map.push_back(std::make_pair(
            files_to_register[i].fd.fd,
            files_to_register[i].id +
                base::GlobalDescriptors::kBaseDescriptor));
      }

#if !defined(OS_MACOSX)
      if (process_type == switches::kRendererProcess) {
        const int sandbox_fd =
            RenderSandboxHostLinux::GetInstance()->GetRendererSocket();
        fds_to_map.push_back(std::make_pair(
            sandbox_fd,
            GetSandboxFD()));
      }
#endif  // defined(OS_MACOSX)

      // Actually launch the app.
      base::LaunchOptions options;
      options.environ = env;
      options.fds_to_remap = &fds_to_map;

#if defined(OS_MACOSX)
      // Hold the MachBroker lock for the duration of LaunchProcess. The child
      // will send its task port to the parent almost immediately after startup.
      // The Mach message will be delivered to the parent, but updating the
      // record of the launch will wait until after the placeholder PID is
      // inserted below. This ensures that while the child process may send its
      // port to the parent prior to the parent leaving LaunchProcess, the
      // order in which the record in MachBroker is updated is correct.
      MachBroker* broker = MachBroker::GetInstance();
      broker->GetLock().Acquire();

      // Make sure the MachBroker is running, and inform it to expect a
      // check-in from the new process.
      broker->EnsureRunning();
#endif  // defined(OS_MACOSX)

      bool launched = base::LaunchProcess(*cmd_line, options, &handle);

#if defined(OS_MACOSX)
      if (launched)
        broker->AddPlaceholderForPid(handle);

      // After updating the broker, release the lock and let the child's
      // messasge be processed on the broker's thread.
      broker->GetLock().Release();
#endif  // defined(OS_MACOSX)

      if (!launched)
        handle = base::kNullProcessHandle;
    }
#endif  // else defined(OS_POSIX)
#if !defined(OS_ANDROID)
  if (handle)
    RecordHistograms(begin_launch_time);
  BrowserThread::PostTask(
      client_thread_id, FROM_HERE,
      base::Bind(
          &Context::Notify,
          this_object.get(),
#if defined(OS_POSIX) && !defined(OS_MACOSX)
          use_zygote,
#endif
          handle));
#endif  // !defined(OS_ANDROID)
  }

  void Notify(
#if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID)
      bool zygote,
#endif
      base::ProcessHandle handle) {
#if defined(OS_ANDROID)
    // Finally close the ipcfd
    file_util::ScopedFD ipcfd_closer(&ipcfd_);
#endif
    starting_ = false;
    process_.set_handle(handle);
    if (!handle)
      LOG(ERROR) << "Failed to launch child process";

#if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID)
    zygote_ = zygote;
#endif
    if (client_) {
      client_->OnProcessLaunched();
    } else {
      Terminate();
    }
  }

  void Terminate() {
    if (!process_.handle())
      return;

    if (!terminate_child_on_shutdown_)
      return;

    // On Posix, EnsureProcessTerminated can lead to 2 seconds of sleep!  So
    // don't this on the UI/IO threads.
    BrowserThread::PostTask(
        BrowserThread::PROCESS_LAUNCHER, FROM_HERE,
        base::Bind(
            &Context::TerminateInternal,
#if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID)
            zygote_,
#endif
            process_.handle()));
    process_.set_handle(base::kNullProcessHandle);
  }

  static void SetProcessBackgrounded(base::ProcessHandle handle,
                                     bool background) {
    base::Process process(handle);
    process.SetProcessBackgrounded(background);
  }

  static void TerminateInternal(
#if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID)
      bool zygote,
#endif
      base::ProcessHandle handle) {
#if defined(OS_ANDROID)
    VLOG(0) << "ChromeProcess: Stopping process with handle " << handle;
    StopChildProcess(handle);
#else
    base::Process process(handle);
     // Client has gone away, so just kill the process.  Using exit code 0
    // means that UMA won't treat this as a crash.
    process.Terminate(RESULT_CODE_NORMAL_EXIT);
    // On POSIX, we must additionally reap the child.
#if defined(OS_POSIX)
#if !defined(OS_MACOSX)
    if (zygote) {
      // If the renderer was created via a zygote, we have to proxy the reaping
      // through the zygote process.
      ZygoteHostImpl::GetInstance()->EnsureProcessTerminated(handle);
    } else
#endif  // !OS_MACOSX
    {
      base::EnsureProcessTerminated(handle);
    }
#endif  // OS_POSIX
    process.Close();
#endif  // defined(OS_ANDROID)
  }

  Client* client_;
  BrowserThread::ID client_thread_id_;
  base::Process process_;
  base::TerminationStatus termination_status_;
  int exit_code_;
  bool starting_;
  // Controls whether the child process should be terminated on browser
  // shutdown. Default behavior is to terminate the child.
  bool terminate_child_on_shutdown_;
#if defined(OS_ANDROID)
  // The fd to close after creating the process.
  int ipcfd_;
#elif defined(OS_POSIX) && !defined(OS_MACOSX)
  bool zygote_;
#endif
};


ChildProcessLauncher::ChildProcessLauncher(
#if defined(OS_WIN)
    SandboxedProcessLauncherDelegate* delegate,
#elif defined(OS_POSIX)
    bool use_zygote,
    const base::EnvironmentMap& environ,
    int ipcfd,
#endif
    CommandLine* cmd_line,
    int child_process_id,
    Client* client) {
  context_ = new Context();
  context_->Launch(
#if defined(OS_WIN)
      delegate,
#elif defined(OS_ANDROID)
      ipcfd,
#elif defined(OS_POSIX)
      use_zygote,
      environ,
      ipcfd,
#endif
      cmd_line,
      child_process_id,
      client);
}

ChildProcessLauncher::~ChildProcessLauncher() {
  context_->ResetClient();
}

bool ChildProcessLauncher::IsStarting() {
  return context_->starting_;
}

base::ProcessHandle ChildProcessLauncher::GetHandle() {
  DCHECK(!context_->starting_);
  return context_->process_.handle();
}

base::TerminationStatus ChildProcessLauncher::GetChildTerminationStatus(
    bool known_dead,
    int* exit_code) {
  base::ProcessHandle handle = context_->process_.handle();
  if (handle == base::kNullProcessHandle) {
    // Process is already gone, so return the cached termination status.
    if (exit_code)
      *exit_code = context_->exit_code_;
    return context_->termination_status_;
  }
#if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID)
  if (context_->zygote_) {
    context_->termination_status_ = ZygoteHostImpl::GetInstance()->
        GetTerminationStatus(handle, known_dead, &context_->exit_code_);
  } else if (known_dead) {
    context_->termination_status_ =
        base::GetKnownDeadTerminationStatus(handle, &context_->exit_code_);
  } else {
#elif defined(OS_MACOSX)
  if (known_dead) {
    context_->termination_status_ =
        base::GetKnownDeadTerminationStatus(handle, &context_->exit_code_);
  } else {
#elif defined(OS_ANDROID)
  if (IsChildProcessOomProtected(handle)) {
      context_->termination_status_ = base::TERMINATION_STATUS_OOM_PROTECTED;
  } else {
#else
  {
#endif
    context_->termination_status_ =
        base::GetTerminationStatus(handle, &context_->exit_code_);
  }

  if (exit_code)
    *exit_code = context_->exit_code_;

  // POSIX: If the process crashed, then the kernel closed the socket
  // for it and so the child has already died by the time we get
  // here. Since GetTerminationStatus called waitpid with WNOHANG,
  // it'll reap the process.  However, if GetTerminationStatus didn't
  // reap the child (because it was still running), we'll need to
  // Terminate via ProcessWatcher. So we can't close the handle here.
  if (context_->termination_status_ != base::TERMINATION_STATUS_STILL_RUNNING)
    context_->process_.Close();

  return context_->termination_status_;
}

void ChildProcessLauncher::SetProcessBackgrounded(bool background) {
  BrowserThread::PostTask(
      BrowserThread::PROCESS_LAUNCHER, FROM_HERE,
      base::Bind(
          &ChildProcessLauncher::Context::SetProcessBackgrounded,
          GetHandle(), background));
}

void ChildProcessLauncher::SetTerminateChildOnShutdown(
  bool terminate_on_shutdown) {
  if (context_.get())
    context_->set_terminate_child_on_shutdown(terminate_on_shutdown);
}

}  // namespace content
