Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / content / browser / browser_main_loop.cc
index eecb65c..a73c630 100644 (file)
@@ -24,7 +24,7 @@
 #include "base/threading/thread_restrictions.h"
 #include "base/timer/hi_res_timer_manager.h"
 #include "content/browser/browser_thread_impl.h"
-#include "content/browser/device_orientation/device_inertial_sensor_service.h"
+#include "content/browser/device_sensors/device_inertial_sensor_service.h"
 #include "content/browser/download/save_file_manager.h"
 #include "content/browser/gamepad/gamepad_service.h"
 #include "content/browser/gpu/browser_gpu_channel_host_factory.h"
@@ -39,9 +39,9 @@
 #include "content/browser/net/browser_online_state_observer.h"
 #include "content/browser/plugin_service_impl.h"
 #include "content/browser/renderer_host/media/media_stream_manager.h"
-#include "content/browser/renderer_host/render_process_host_impl.h"
 #include "content/browser/speech/speech_recognition_manager_impl.h"
 #include "content/browser/startup_task_runner.h"
+#include "content/browser/time_zone_monitor.h"
 #include "content/browser/webui/content_web_ui_controller_factory.h"
 #include "content/browser/webui/url_data_manager.h"
 #include "content/public/browser/browser_main_parts.h"
 #include "net/ssl/ssl_config_service.h"
 #include "ui/base/clipboard/clipboard.h"
 
-#if defined(USE_AURA)
+#if defined(USE_AURA) || (defined(OS_MACOSX) && !defined(OS_IOS))
 #include "content/browser/compositor/image_transport_factory.h"
 #endif
 
+#if defined(USE_AURA)
+#include "ui/aura/env.h"
+#endif
+
+#if !defined(OS_IOS)
+#include "content/browser/renderer_host/render_process_host_impl.h"
+#endif
+
 #if defined(OS_ANDROID)
 #include "base/android/jni_android.h"
 #include "content/browser/android/browser_startup_controller.h"
 #include "content/browser/android/surface_texture_peer_browser_impl.h"
+#include "content/browser/android/tracing_controller_android.h"
 #include "ui/gl/gl_surface.h"
 #endif
 
 #include "content/browser/device_monitor_mac.h"
 #endif
 
-#if defined(TOOLKIT_GTK)
-#include "ui/gfx/gtk_util.h"
-#endif
-
 #if defined(OS_POSIX) && !defined(OS_MACOSX)
-#include <sys/stat.h>
-
 #include "content/browser/renderer_host/render_sandbox_host_linux.h"
 #include "content/browser/zygote_host/zygote_host_impl_linux.h"
+#include "sandbox/linux/suid/client/setuid_sandbox_client.h"
 #endif
 
 #if defined(TCMALLOC_TRACE_MEMORY_SUPPORTED)
 #endif
 
 #if defined(USE_X11)
-#include <X11/Xlib.h>
+#include "ui/gfx/x/x11_connection.h"
+#include "ui/gfx/x/x11_types.h"
 #endif
 
 #if defined(USE_OZONE)
 #include "ui/ozone/ozone_platform.h"
+#include "ui/events/ozone/event_factory_ozone.h"
 #include "ozone/content/ozone_channel_host_factory.h"
 #endif
 
@@ -133,51 +139,29 @@ namespace {
 #if defined(OS_POSIX) && !defined(OS_MACOSX) && !defined(OS_ANDROID)
 void SetupSandbox(const CommandLine& parsed_command_line) {
   TRACE_EVENT0("startup", "SetupSandbox");
-  // TODO(evanm): move this into SandboxWrapper; I'm just trying to move this
-  // code en masse out of chrome_main for now.
   base::FilePath sandbox_binary;
-  bool env_chrome_devel_sandbox_set = false;
-  struct stat st;
+
+  scoped_ptr<sandbox::SetuidSandboxClient> setuid_sandbox_client(
+      sandbox::SetuidSandboxClient::Create());
 
   const bool want_setuid_sandbox =
       !parsed_command_line.HasSwitch(switches::kNoSandbox) &&
-      !parsed_command_line.HasSwitch(switches::kDisableSetuidSandbox);
+      !parsed_command_line.HasSwitch(switches::kDisableSetuidSandbox) &&
+      !setuid_sandbox_client->IsDisabledViaEnvironment();
 
+  static const char no_suid_error[] =
+      "Running without the SUID sandbox! See "
+      "https://code.google.com/p/chromium/wiki/LinuxSUIDSandboxDevelopment "
+      "for more information on developing with the sandbox on.";
   if (want_setuid_sandbox) {
-    base::FilePath exe_dir;
-    if (PathService::Get(base::DIR_EXE, &exe_dir)) {
-      base::FilePath sandbox_candidate = exe_dir.AppendASCII("chrome-sandbox");
-      if (base::PathExists(sandbox_candidate))
-        sandbox_binary = sandbox_candidate;
-    }
-
-    // In user-managed builds, including development builds, an environment
-    // variable is required to enable the sandbox. See
-    // http://code.google.com/p/chromium/wiki/LinuxSUIDSandboxDevelopment
-    if (sandbox_binary.empty() &&
-        stat(base::kProcSelfExe, &st) == 0 && st.st_uid == getuid()) {
-      const char* devel_sandbox_path = getenv("CHROME_DEVEL_SANDBOX");
-      if (devel_sandbox_path) {
-        env_chrome_devel_sandbox_set = true;
-        sandbox_binary = base::FilePath(devel_sandbox_path);
-      }
-    }
-
-    static const char no_suid_error[] = "Running without the SUID sandbox! See "
-        "https://code.google.com/p/chromium/wiki/LinuxSUIDSandboxDevelopment "
-        "for more information on developing with the sandbox on.";
+    sandbox_binary = setuid_sandbox_client->GetSandboxBinaryPath();
     if (sandbox_binary.empty()) {
-      if (!env_chrome_devel_sandbox_set) {
-        // This needs to be fatal. Talk to security@chromium.org if you feel
-        // otherwise.
-        LOG(FATAL) << no_suid_error;
-      }
-
-      // TODO(jln): an empty CHROME_DEVEL_SANDBOX environment variable (as
-      // opposed to a non existing one) is not fatal yet. This is needed
-      // because of existing bots and scripts. Fix it (crbug.com/245376).
-      LOG(ERROR) << no_suid_error;
+      // This needs to be fatal. Talk to security@chromium.org if you feel
+      // otherwise.
+      LOG(FATAL) << no_suid_error;
     }
+  } else {
+    LOG(ERROR) << no_suid_error;
   }
 
   // Tickle the sandbox host and zygote host so they fork now.
@@ -196,18 +180,7 @@ static void GLibLogHandler(const gchar* log_domain,
   if (!message)
     message = "<no message>";
 
-  if (strstr(message, "Loading IM context type") ||
-      strstr(message, "wrong ELF class: ELFCLASS64")) {
-    // http://crbug.com/9643
-    // Until we have a real 64-bit build or all of these 32-bit package issues
-    // are sorted out, don't fatal on ELF 32/64-bit mismatch warnings and don't
-    // spam the user with more than one of them.
-    static bool alerted = false;
-    if (!alerted) {
-      LOG(ERROR) << "Bug 9643: " << log_domain << ": " << message;
-      alerted = true;
-    }
-  } else if (strstr(message, "Unable to retrieve the file info for")) {
+  if (strstr(message, "Unable to retrieve the file info for")) {
     LOG(ERROR) << "GTK File code error: " << message;
   } else if (strstr(message, "Could not find the icon") &&
              strstr(log_domain, "Gtk")) {
@@ -220,8 +193,6 @@ static void GLibLogHandler(const gchar* log_domain,
   } else if (strstr(message, "Unable to create Ubuntu Menu Proxy") &&
              strstr(log_domain, "<unknown>")) {
     LOG(ERROR) << "GTK menu proxy create failed";
-  } else if (strstr(message, "gtk_drag_dest_leave: assertion")) {
-    LOG(ERROR) << "Drag destination deleted: http://crbug.com/18557";
   } else if (strstr(message, "Out of memory") &&
              strstr(log_domain, "<unknown>")) {
     LOG(ERROR) << "DBus call timeout or out of memory: "
@@ -230,8 +201,6 @@ static void GLibLogHandler(const gchar* log_domain,
              strstr(log_domain, "<unknown>")) {
     LOG(ERROR) << "DConf settings backend could not connect to session bus: "
                << "http://crbug.com/179797";
-  } else if (strstr(message, "XDG_RUNTIME_DIR variable not set")) {
-    LOG(ERROR) << message << " (http://bugs.chromium.org/97293)";
   } else if (strstr(message, "Attempting to store changes into") ||
              strstr(message, "Attempting to set the permissions of")) {
     LOG(ERROR) << message << " (http://bugs.chromium.org/161366)";
@@ -258,6 +227,20 @@ static void SetUpGLibLogHandler() {
 }
 #endif
 
+void OnStoppedStartupTracing(const base::FilePath& trace_file) {
+  VLOG(0) << "Completed startup tracing to " << trace_file.value();
+}
+
+#if defined(USE_AURA)
+bool ShouldInitializeBrowserGpuChannelAndTransportSurface() {
+  return true;
+}
+#elif defined(OS_MACOSX) && !defined(OS_IOS)
+bool ShouldInitializeBrowserGpuChannelAndTransportSurface() {
+  return IsDelegatedRendererEnabled();
+}
+#endif
+
 }  // namespace
 
 // The currently-running BrowserMainLoop.  There can be one or zero.
@@ -344,7 +327,7 @@ BrowserMainLoop::~BrowserMainLoop() {
 }
 
 void BrowserMainLoop::Init() {
-  TRACE_EVENT0("startup", "BrowserMainLoop::Init")
+  TRACE_EVENT0("startup", "BrowserMainLoop::Init");
   parts_.reset(
       GetContentClient()->browser()->CreateBrowserMainParts(parameters_));
 }
@@ -363,7 +346,7 @@ void BrowserMainLoop::EarlyInitialization() {
 #if defined(USE_X11)
   if (parsed_command_line_.HasSwitch(switches::kSingleProcess) ||
       parsed_command_line_.HasSwitch(switches::kInProcessGPU)) {
-    if (!XInitThreads()) {
+    if (!gfx::InitializeThreadedX11()) {
       LOG(ERROR) << "Failed to put Xlib into threaded mode.";
     }
   }
@@ -385,10 +368,6 @@ void BrowserMainLoop::EarlyInitialization() {
   g_type_init();
 #endif
 
-#if !defined(USE_AURA)
-  gfx::GtkInitFromCommandLine(parsed_command_line_);
-#endif
-
   SetUpGLibLogHandler();
 #endif
 
@@ -420,7 +399,7 @@ void BrowserMainLoop::EarlyInitialization() {
 }
 
 void BrowserMainLoop::MainMessageLoopStart() {
-  TRACE_EVENT0("startup", "BrowserMainLoop::MainMessageLoopStart")
+  TRACE_EVENT0("startup", "BrowserMainLoop::MainMessageLoopStart");
   if (parts_) {
     TRACE_EVENT0("startup",
         "BrowserMainLoop::MainMessageLoopStart:PreMainMessageLoopStart");
@@ -443,50 +422,51 @@ void BrowserMainLoop::MainMessageLoopStart() {
   InitializeMainThread();
 
   {
-    TRACE_EVENT0("startup", "BrowserMainLoop::Subsystem:SystemMonitor")
+    TRACE_EVENT0("startup", "BrowserMainLoop::Subsystem:SystemMonitor");
     system_monitor_.reset(new base::SystemMonitor);
   }
   {
-    TRACE_EVENT0("startup", "BrowserMainLoop::Subsystem:PowerMonitor")
+    TRACE_EVENT0("startup", "BrowserMainLoop::Subsystem:PowerMonitor");
     scoped_ptr<base::PowerMonitorSource> power_monitor_source(
       new base::PowerMonitorDeviceSource());
     power_monitor_.reset(new base::PowerMonitor(power_monitor_source.Pass()));
   }
   {
-    TRACE_EVENT0("startup", "BrowserMainLoop::Subsystem:HighResTimerManager")
+    TRACE_EVENT0("startup", "BrowserMainLoop::Subsystem:HighResTimerManager");
     hi_res_timer_manager_.reset(new base::HighResolutionTimerManager);
   }
   {
-    TRACE_EVENT0("startup", "BrowserMainLoop::Subsystem:NetworkChangeNotifier")
+    TRACE_EVENT0("startup", "BrowserMainLoop::Subsystem:NetworkChangeNotifier");
     network_change_notifier_.reset(net::NetworkChangeNotifier::Create());
   }
 
 #if !defined(OS_IOS)
   {
-    TRACE_EVENT0("startup", "BrowserMainLoop::Subsystem:MediaFeatures")
+    TRACE_EVENT0("startup", "BrowserMainLoop::Subsystem:MediaFeatures");
     media::InitializeCPUSpecificMediaFeatures();
   }
   {
-    TRACE_EVENT0("startup", "BrowserMainLoop::Subsystem:AudioMan")
+    TRACE_EVENT0("startup", "BrowserMainLoop::Subsystem:AudioMan");
     audio_manager_.reset(media::AudioManager::Create(
         MediaInternals::GetInstance()));
   }
   {
-    TRACE_EVENT0("startup", "BrowserMainLoop::Subsystem:MidiManager")
+    TRACE_EVENT0("startup", "BrowserMainLoop::Subsystem:MidiManager");
     midi_manager_.reset(media::MidiManager::Create());
   }
   {
-    TRACE_EVENT0("startup", "BrowserMainLoop::Subsystem:ContentWebUIController")
+    TRACE_EVENT0("startup",
+                 "BrowserMainLoop::Subsystem:ContentWebUIController");
     WebUIControllerFactory::RegisterFactory(
         ContentWebUIControllerFactory::GetInstance());
   }
 
   {
-    TRACE_EVENT0("startup", "BrowserMainLoop::Subsystem:AudioMirroringManager")
+    TRACE_EVENT0("startup", "BrowserMainLoop::Subsystem:AudioMirroringManager");
     audio_mirroring_manager_.reset(new AudioMirroringManager());
   }
   {
-    TRACE_EVENT0("startup", "BrowserMainLoop::Subsystem:OnlineStateObserver")
+    TRACE_EVENT0("startup", "BrowserMainLoop::Subsystem:OnlineStateObserver");
     online_state_observer_.reset(new BrowserOnlineStateObserver);
   }
 
@@ -508,20 +488,20 @@ void BrowserMainLoop::MainMessageLoopStart() {
   // message loop to avoid calling MessagePumpForUI::ScheduleWork() before
   // MessagePumpForUI::Start() as it will crash the browser.
   if (is_tracing_startup_) {
-    TRACE_EVENT0("startup", "BrowserMainLoop::InitStartupTracing")
+    TRACE_EVENT0("startup", "BrowserMainLoop::InitStartupTracing");
     InitStartupTracing(parsed_command_line_);
   }
 #endif  // !defined(OS_IOS)
 
 #if defined(OS_ANDROID)
   {
-    TRACE_EVENT0("startup", "BrowserMainLoop::Subsystem:SurfaceTexturePeer")
+    TRACE_EVENT0("startup", "BrowserMainLoop::Subsystem:SurfaceTexturePeer");
     SurfaceTexturePeer::InitInstance(new SurfaceTexturePeerBrowserImpl());
   }
 #endif
 
   if (parsed_command_line_.HasSwitch(switches::kMemoryMetrics)) {
-    TRACE_EVENT0("startup", "BrowserMainLoop::Subsystem:MemoryObserver")
+    TRACE_EVENT0("startup", "BrowserMainLoop::Subsystem:MemoryObserver");
     memory_observer_.reset(new MemoryObserver());
     base::MessageLoop::current()->AddTaskObserver(memory_observer_.get());
   }
@@ -549,7 +529,7 @@ int BrowserMainLoop::PreCreateThreads() {
   // but must be created on the main thread. The service ctor is
   // inexpensive and does not invoke the io_thread() accessor.
   {
-    TRACE_EVENT0("startup", "BrowserMainLoop::CreateThreads:PluginService")
+    TRACE_EVENT0("startup", "BrowserMainLoop::CreateThreads:PluginService");
     PluginService::GetInstance()->Init();
   }
 #endif
@@ -735,7 +715,7 @@ void BrowserMainLoop::ShutdownThreadsAndCleanUp() {
     // Called early, nothing to do
     return;
   }
-  TRACE_EVENT0("shutdown", "BrowserMainLoop::ShutdownThreadsAndCleanUp")
+  TRACE_EVENT0("shutdown", "BrowserMainLoop::ShutdownThreadsAndCleanUp");
 
   // Teardown may start in PostMainMessageLoopRun, and during teardown we
   // need to be able to perform IO.
@@ -745,8 +725,10 @@ void BrowserMainLoop::ShutdownThreadsAndCleanUp() {
       base::Bind(base::IgnoreResult(&base::ThreadRestrictions::SetIOAllowed),
                  true));
 
+#if !defined(OS_IOS)
   if (RenderProcessHost::run_renderer_in_process())
     RenderProcessHostImpl::ShutDownInProcessRenderer();
+#endif
 
   if (parts_) {
     TRACE_EVENT0("shutdown",
@@ -918,7 +900,7 @@ void BrowserMainLoop::ShutdownThreadsAndCleanUp() {
 }
 
 void BrowserMainLoop::InitializeMainThread() {
-  TRACE_EVENT0("startup", "BrowserMainLoop::InitializeMainThread")
+  TRACE_EVENT0("startup", "BrowserMainLoop::InitializeMainThread");
   const char* kThreadName = "CrBrowserMain";
   base::PlatformThread::SetName(kThreadName);
   if (main_message_loop_)
@@ -930,7 +912,7 @@ void BrowserMainLoop::InitializeMainThread() {
 }
 
 int BrowserMainLoop::BrowserThreadsStarted() {
-  TRACE_EVENT0("startup", "BrowserMainLoop::BrowserThreadsStarted")
+  TRACE_EVENT0("startup", "BrowserMainLoop::BrowserThreadsStarted");
 
 #if !defined(OS_IOS)
   indexed_db_thread_.reset(new base::Thread("IndexedDB"));
@@ -960,23 +942,21 @@ int BrowserMainLoop::BrowserThreadsStarted() {
   // otherwise we'll trigger the assertion about doing IO on the UI thread.
   GpuDataManagerImpl::GetInstance()->Initialize();
 
-  bool always_uses_gpu = IsForceCompositingModeEnabled();
+  bool always_uses_gpu = true;
   bool established_gpu_channel = false;
-#if defined(USE_AURA) || defined(OS_ANDROID)
-  established_gpu_channel =
-      !parsed_command_line_.HasSwitch(switches::kDisableGpuProcessPrelaunch) ||
-      parsed_command_line_.HasSwitch(switches::kSingleProcess) ||
-      parsed_command_line_.HasSwitch(switches::kInProcessGPU);
-#if defined(USE_AURA)
-  if (!GpuDataManagerImpl::GetInstance()->CanUseGpuBrowserCompositor()) {
-    established_gpu_channel = always_uses_gpu = false;
+#if defined(USE_AURA) || defined(OS_MACOSX)
+  if (ShouldInitializeBrowserGpuChannelAndTransportSurface()) {
+    established_gpu_channel = true;
+    if (!GpuDataManagerImpl::GetInstance()->CanUseGpuBrowserCompositor()) {
+      established_gpu_channel = always_uses_gpu = false;
+    }
+    BrowserGpuChannelHostFactory::Initialize(established_gpu_channel);
+    ImageTransportFactory::Initialize();
   }
-  BrowserGpuChannelHostFactory::Initialize(established_gpu_channel);
-  ImageTransportFactory::Initialize();
 #elif defined(OS_ANDROID)
+  established_gpu_channel = true;
   BrowserGpuChannelHostFactory::Initialize(established_gpu_channel);
 #endif
-#endif
 
 #if defined(OS_LINUX) && defined(USE_UDEV)
   device_monitor_linux_.reset(new DeviceMonitorLinux());
@@ -1019,6 +999,12 @@ int BrowserMainLoop::BrowserThreadsStarted() {
         io_thread_->message_loop_proxy(), main_thread_->message_loop_proxy());
   }
 
+  {
+    TRACE_EVENT0("startup",
+                 "BrowserMainLoop::BrowserThreadsStarted::TimeZoneMonitor");
+    time_zone_monitor_ = TimeZoneMonitor::Create();
+  }
+
   // Alert the clipboard class to which threads are allowed to access the
   // clipboard:
   std::vector<base::PlatformThreadId> allowed_clipboard_threads;
@@ -1037,7 +1023,6 @@ int BrowserMainLoop::BrowserThreadsStarted() {
   if (GpuDataManagerImpl::GetInstance()->GpuAccessAllowed(NULL) &&
       !established_gpu_channel &&
       always_uses_gpu &&
-      !parsed_command_line_.HasSwitch(switches::kDisableGpuProcessPrelaunch) &&
       !parsed_command_line_.HasSwitch(switches::kSingleProcess) &&
       !parsed_command_line_.HasSwitch(switches::kInProcessGPU)) {
     TRACE_EVENT_INSTANT0("gpu", "Post task to launch GPU process",
@@ -1065,8 +1050,8 @@ int BrowserMainLoop::BrowserThreadsStarted() {
   return result_code_;
 }
 
-void BrowserMainLoop::InitializeToolkit() {
-  TRACE_EVENT0("startup", "BrowserMainLoop::InitializeToolkit")
+bool BrowserMainLoop::InitializeToolkit() {
+  TRACE_EVENT0("startup", "BrowserMainLoop::InitializeToolkit");
   // TODO(evan): this function is rather subtle, due to the variety
   // of intersecting ifdefs we have.  To keep it easy to follow, there
   // are no #else branches on any #ifs.
@@ -1089,8 +1074,22 @@ void BrowserMainLoop::InitializeToolkit() {
     LOG_GETLASTERROR(FATAL);
 #endif
 
+#if defined(USE_AURA)
+
+#if defined(USE_X11)
+  if (!gfx::GetXDisplay())
+    return false;
+#endif
+
+  // Env creates the compositor. Aura widgets need the compositor to be created
+  // before they can be initialized by the browser.
+  aura::Env::CreateInstance(true);
+#endif  // defined(USE_AURA)
+
   if (parts_)
     parts_->ToolkitInitialized();
+
+  return true;
 }
 
 void BrowserMainLoop::MainMessageLoopRun() {
@@ -1120,8 +1119,12 @@ void BrowserMainLoop::InitStartupTracing(const CommandLine& command_line) {
     return;
 
   if (trace_file.empty()) {
+#if defined(OS_ANDROID)
+    TracingControllerAndroid::GenerateTracingFilePath(&trace_file);
+#else
     // Default to saving the startup trace into the current dir.
     trace_file = base::FilePath().AppendASCII("chrometrace.log");
+#endif
   }
 
   std::string delay_str = command_line.GetSwitchValueASCII(
@@ -1143,7 +1146,7 @@ void BrowserMainLoop::InitStartupTracing(const CommandLine& command_line) {
 void BrowserMainLoop::EndStartupTracing(const base::FilePath& trace_file) {
   is_tracing_startup_ = false;
   TracingController::GetInstance()->DisableRecording(
-      trace_file, TracingController::TracingFileResultCallback());
+      trace_file, base::Bind(&OnStoppedStartupTracing));
 }
 
 }  // namespace content