// 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/utility_process_host.h"

#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/command_line.h"
#include "base/message_loop.h"
#include "base/utf_string_conversions.h"
#include "content/browser/browser_child_process_host_impl.h"
#include "content/common/child_process_host_impl.h"
#include "content/common/utility_messages.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/common/content_switches.h"
#include "ipc/ipc_switches.h"
#include "ui/base/ui_base_switches.h"
#include "webkit/plugins/plugin_switches.h"

using content::BrowserThread;
using content::ChildProcessHost;

UtilityProcessHost::Client::Client() {
}

UtilityProcessHost::Client::~Client() {
}

void UtilityProcessHost::Client::OnProcessCrashed(int exit_code) {
}

bool UtilityProcessHost::Client::OnMessageReceived(
    const IPC::Message& message) {
  return false;
}

UtilityProcessHost::UtilityProcessHost(Client* client,
                                       BrowserThread::ID client_thread_id)
    : client_(client),
      client_thread_id_(client_thread_id),
      is_batch_mode_(false),
      no_sandbox_(false),
#if defined(OS_LINUX)
      child_flags_(ChildProcessHost::CHILD_ALLOW_SELF),
#else
      child_flags_(ChildProcessHost::CHILD_NORMAL),
#endif
      use_linux_zygote_(false),
      started_(false) {
  process_.reset(
      new BrowserChildProcessHostImpl(content::PROCESS_TYPE_UTILITY, this));
}

UtilityProcessHost::~UtilityProcessHost() {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
  DCHECK(!is_batch_mode_);
}

bool UtilityProcessHost::Send(IPC::Message* message) {
  if (!StartProcess())
    return false;

  return process_->Send(message);
}

bool UtilityProcessHost::StartBatchMode()  {
  CHECK(!is_batch_mode_);
  is_batch_mode_ = StartProcess();
  Send(new UtilityMsg_BatchMode_Started());
  return is_batch_mode_;
}

void UtilityProcessHost::EndBatchMode()  {
  CHECK(is_batch_mode_);
  is_batch_mode_ = false;
  Send(new UtilityMsg_BatchMode_Finished());
}

FilePath UtilityProcessHost::GetUtilityProcessCmd() {
  return ChildProcessHost::GetChildPath(child_flags_);
}

bool UtilityProcessHost::StartProcess() {
  if (started_)
    return true;
  started_ = true;

  if (is_batch_mode_)
    return true;
  // Name must be set or metrics_service will crash in any test which
  // launches a UtilityProcessHost.
  process_->SetName(ASCIIToUTF16("utility process"));

  std::string channel_id = process_->GetHost()->CreateChannel();
  if (channel_id.empty())
    return false;

  FilePath exe_path = GetUtilityProcessCmd();
  if (exe_path.empty()) {
    NOTREACHED() << "Unable to get utility process binary name.";
    return false;
  }

  CommandLine* cmd_line = new CommandLine(exe_path);
  cmd_line->AppendSwitchASCII(switches::kProcessType,
                              switches::kUtilityProcess);
  cmd_line->AppendSwitchASCII(switches::kProcessChannelID, channel_id);
  std::string locale =
      content::GetContentClient()->browser()->GetApplicationLocale();
  cmd_line->AppendSwitchASCII(switches::kLang, locale);

  const CommandLine& browser_command_line = *CommandLine::ForCurrentProcess();
  if (browser_command_line.HasSwitch(switches::kChromeFrame))
    cmd_line->AppendSwitch(switches::kChromeFrame);
  if (no_sandbox_ || browser_command_line.HasSwitch(switches::kNoSandbox))
    cmd_line->AppendSwitch(switches::kNoSandbox);
  if (browser_command_line.HasSwitch(switches::kDebugPluginLoading))
    cmd_line->AppendSwitch(switches::kDebugPluginLoading);

#if defined(OS_POSIX)
  // TODO(port): Sandbox this on Linux.  Also, zygote this to work with
  // Linux updating.
  bool has_cmd_prefix = browser_command_line.HasSwitch(
      switches::kUtilityCmdPrefix);
  if (has_cmd_prefix) {
    // launch the utility child process with some prefix (usually "xterm -e gdb
    // --args").
    cmd_line->PrependWrapper(browser_command_line.GetSwitchValueNative(
        switches::kUtilityCmdPrefix));
  }

  cmd_line->AppendSwitchPath(switches::kUtilityProcessAllowedDir, exposed_dir_);
#endif

  bool use_zygote = false;

#if defined(OS_LINUX)
  use_zygote = !no_sandbox_ && use_linux_zygote_;
#endif

  process_->Launch(
#if defined(OS_WIN)
      exposed_dir_,
#elif defined(OS_POSIX)
      use_zygote,
      env_,
#endif
      cmd_line);

  return true;
}

bool UtilityProcessHost::OnMessageReceived(const IPC::Message& message) {
  BrowserThread::PostTask(
      client_thread_id_, FROM_HERE,
      base::Bind(base::IgnoreResult(&Client::OnMessageReceived),
                 client_.get(), message));
  return true;
}

void UtilityProcessHost::OnProcessCrashed(int exit_code) {
  BrowserThread::PostTask(
      client_thread_id_, FROM_HERE,
      base::Bind(&Client::OnProcessCrashed, client_.get(), exit_code));
}
