// 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 <stdlib.h>

#if defined(OS_WIN)
#include <windows.h>
#endif

#include "base/debug/trace_event.h"
#include "base/message_loop.h"
#include "base/rand_util.h"
#include "base/string_number_conversions.h"
#include "base/stringprintf.h"
#include "base/threading/platform_thread.h"
#include "base/win/scoped_com_initializer.h"
#include "build/build_config.h"
#include "content/common/gpu/gpu_config.h"
#include "content/gpu/gpu_child_thread.h"
#include "content/gpu/gpu_info_collector.h"
#include "content/gpu/gpu_process.h"
#include "content/public/common/content_client.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/main_function_params.h"
#include "crypto/hmac.h"
#include "ui/gl/gl_surface.h"
#include "ui/gl/gl_switches.h"

#if defined(OS_WIN)
#include "content/common/gpu/media/dxva_video_decode_accelerator.h"
#include "sandbox/win/src/sandbox.h"
#endif

#if defined(USE_X11)
#include "ui/base/x/x11_util.h"
#endif

#if defined(OS_LINUX)
#include "content/public/common/sandbox_init.h"
#endif

// Main function for starting the Gpu process.
int GpuMain(const content::MainFunctionParams& parameters) {
  TRACE_EVENT0("gpu", "GpuMain");

  base::Time start_time = base::Time::Now();

  const CommandLine& command_line = parameters.command_line;
  if (command_line.HasSwitch(switches::kGpuStartupDialog)) {
    ChildProcess::WaitForDebugger("Gpu");
  }

  if (!command_line.HasSwitch(switches::kSingleProcess)) {
#if defined(OS_WIN)
    // Prevent Windows from displaying a modal dialog on failures like not being
    // able to load a DLL.
    SetErrorMode(
        SEM_FAILCRITICALERRORS |
        SEM_NOGPFAULTERRORBOX |
        SEM_NOOPENFILEERRORBOX);
#elif defined(USE_X11)
    ui::SetDefaultX11ErrorHandlers();
#endif
  }

  // Initialization of the OpenGL bindings may fail, in which case we
  // will need to tear down this process. However, we can not do so
  // safely until the IPC channel is set up, because the detection of
  // early return of a child process is implemented using an IPC
  // channel error. If the IPC channel is not fully set up between the
  // browser and GPU process, and the GPU process crashes or exits
  // early, the browser process will never detect it.  For this reason
  // we defer tearing down the GPU process until receiving the
  // GpuMsg_Initialize message from the browser.
  bool dead_on_arrival = false;

  content::GPUInfo gpu_info;
  // Get vendor_id, device_id, driver_version from browser process through
  // commandline switches.
  DCHECK(command_line.HasSwitch(switches::kGpuVendorID) &&
         command_line.HasSwitch(switches::kGpuDeviceID) &&
         command_line.HasSwitch(switches::kGpuDriverVersion));
  bool success = base::HexStringToInt(
      command_line.GetSwitchValueASCII(switches::kGpuVendorID),
      reinterpret_cast<int*>(&(gpu_info.gpu.vendor_id)));
  DCHECK(success);
  success = base::HexStringToInt(
      command_line.GetSwitchValueASCII(switches::kGpuDeviceID),
      reinterpret_cast<int*>(&(gpu_info.gpu.device_id)));
  DCHECK(success);
  gpu_info.driver_vendor =
      command_line.GetSwitchValueASCII(switches::kGpuDriverVendor);
  gpu_info.driver_version =
      command_line.GetSwitchValueASCII(switches::kGpuDriverVersion);
  content::GetContentClient()->SetGpuInfo(gpu_info);

  // Load and initialize the GL implementation and locate the GL entry points.
  if (gfx::GLSurface::InitializeOneOff()) {
#if defined(OS_LINUX)
    // We collect full GPU info on demand in Win/Mac, i.e., when about:gpu
    // page opens.  This is because we can make blacklist decisions based on
    // preliminary GPU info.
    // However, on Linux, we may not have enough info for blacklisting.
    if (!gpu_info.gpu.vendor_id || !gpu_info.gpu.device_id ||
        gpu_info.driver_vendor.empty() || gpu_info.driver_version.empty()) {
      if (!gpu_info_collector::CollectGraphicsInfo(&gpu_info))
        VLOG(1) << "gpu_info_collector::CollectGraphicsInfo failed";
      content::GetContentClient()->SetGpuInfo(gpu_info);
    }

#if !defined(OS_CHROMEOS)
    if (gpu_info.gpu.vendor_id == 0x10de &&  // NVIDIA
        gpu_info.driver_vendor == "NVIDIA") {
      base::ThreadRestrictions::AssertIOAllowed();
      if (access("/dev/nvidiactl", R_OK) != 0) {
        VLOG(1) << "NVIDIA device file /dev/nvidiactl access denied";
        gpu_info.gpu_accessible = false;
        dead_on_arrival = true;
      }
    }
#endif  // OS_CHROMEOS
#endif  // OS_LINUX
  } else {
    VLOG(1) << "gfx::GLSurface::InitializeOneOff failed";
    gpu_info.gpu_accessible = false;
    gpu_info.finalized = true;
    dead_on_arrival = true;
  }

  {
    TRACE_EVENT0("gpu", "Warm up rand");
    // Warm up the random subsystem, which needs to be done pre-sandbox on all
    // platforms.
    (void) base::RandUint64();
  }
  {
    TRACE_EVENT0("gpu", "Warm up HMAC");
    // Warm up the crypto subsystem, which needs to done pre-sandbox on all
    // platforms.
    crypto::HMAC hmac(crypto::HMAC::SHA256);
    unsigned char key = '\0';
    bool ret = hmac.Init(&key, sizeof(key));
    (void) ret;
  }

#if defined(OS_LINUX)
  {
    TRACE_EVENT0("gpu", "Initialize sandbox");
    bool do_init_sandbox = true;

#if defined(OS_CHROMEOS) && defined(NDEBUG)
    // On Chrome OS and when not on a debug build, initialize
    // the GPU process' sandbox only for Intel GPUs.
    do_init_sandbox = gpu_info.gpu.vendor_id == 0x8086;   // Intel GPU.
#endif

    if (do_init_sandbox) {
      content::InitializeSandbox();
    }
  }
#endif

  {
    TRACE_EVENT0("gpu", "Initialize COM");
    base::win::ScopedCOMInitializer com_initializer;
  }

#if defined(OS_WIN)
  {
    TRACE_EVENT0("gpu", "Preload setupapi.dll");
    // Preload this DLL because the sandbox prevents it from loading.
    LoadLibrary(L"setupapi.dll");
  }

  {
    TRACE_EVENT0("gpu", "Initialize DXVA");
    // Initialize H/W video decoding stuff which fails in the sandbox.
    DXVAVideoDecodeAccelerator::PreSandboxInitialization();
  }

  {
    TRACE_EVENT0("gpu", "Lower token");
    // For windows, if the target_services interface is not zero, the process
    // is sandboxed and we must call LowerToken() before rendering untrusted
    // content.
    sandbox::TargetServices* target_services =
        parameters.sandbox_info->target_services;
    if (target_services)
      target_services->LowerToken();
  }
#endif

  MessageLoop::Type message_loop_type = MessageLoop::TYPE_IO;
#if defined(OS_WIN)
  // Unless we're running on desktop GL, we don't need a UI message
  // loop, so avoid its use to work around apparent problems with some
  // third-party software.
  if (command_line.HasSwitch(switches::kUseGL) &&
      command_line.GetSwitchValueASCII(switches::kUseGL) ==
          gfx::kGLImplementationDesktopName) {
      message_loop_type = MessageLoop::TYPE_UI;
  }
#elif defined(OS_LINUX)
  message_loop_type = MessageLoop::TYPE_DEFAULT;
#endif

  MessageLoop main_message_loop(message_loop_type);
  base::PlatformThread::SetName("CrGpuMain");

  GpuProcess gpu_process;

  GpuChildThread* child_thread = new GpuChildThread(dead_on_arrival, gpu_info);

  child_thread->Init(start_time);

  gpu_process.set_main_thread(child_thread);

  {
    TRACE_EVENT0("gpu", "Run Message Loop");
    main_message_loop.Run();
  }

  child_thread->StopWatchdog();

  return 0;
}
