1// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "chrome/browser/ui/aura/chrome_browser_main_extra_parts_aura.h"
6
7#include "base/command_line.h"
8#include "base/run_loop.h"
9#include "chrome/browser/chrome_browser_main.h"
10#include "chrome/browser/ui/aura/active_desktop_monitor.h"
11#include "chrome/browser/ui/host_desktop.h"
12#include "chrome/browser/ui/simple_message_box.h"
13#include "chrome/common/chrome_switches.h"
14#include "chrome/grit/chromium_strings.h"
15#include "chrome/grit/generated_resources.h"
16#include "ui/aura/env.h"
17#include "ui/base/l10n/l10n_util.h"
18#include "ui/base/ui_base_switches.h"
19#include "ui/gfx/screen.h"
20#include "ui/views/widget/native_widget_aura.h"
21
22#if defined(USE_X11) && !defined(OS_CHROMEOS)
23#include "base/prefs/pref_service.h"
24#include "chrome/browser/profiles/profile.h"
25#include "chrome/browser/ui/libgtk2ui/gtk2_ui.h"
26#include "chrome/common/pref_names.h"
27#include "ui/aura/window.h"
28#include "ui/base/ime/input_method_initializer.h"
29#include "ui/native_theme/native_theme_aura.h"
30#include "ui/views/linux_ui/linux_ui.h"
31#endif
32
33#if defined(USE_ASH)
34#include "chrome/browser/ui/ash/ash_init.h"
35#endif  // defined(USE_ASH)
36
37#if !defined(OS_CHROMEOS)
38#include "ui/views/widget/desktop_aura/desktop_screen.h"
39#endif
40
41namespace {
42
43#if defined(USE_X11) && !defined(OS_CHROMEOS)
44ui::NativeTheme* GetNativeThemeForWindow(aura::Window* window) {
45  if (!window)
46    return NULL;
47
48  Profile* profile = NULL;
49  if (window->type() == ui::wm::WINDOW_TYPE_NORMAL ||
50      window->type() == ui::wm::WINDOW_TYPE_POPUP) {
51    profile = reinterpret_cast<Profile*>(
52        window->GetNativeWindowProperty(Profile::kProfileKey));
53  }
54
55  if (profile && !profile->GetPrefs()->GetBoolean(prefs::kUsesSystemTheme))
56    return ui::NativeThemeAura::instance();
57
58  return NULL;
59}
60#endif
61
62#if !defined(OS_CHROMEOS) && defined(USE_ASH)
63// Returns the desktop this process was initially launched in.
64chrome::HostDesktopType GetInitialDesktop() {
65#if defined(OS_WIN) && defined(USE_ASH)
66  const CommandLine* command_line = CommandLine::ForCurrentProcess();
67  if (command_line->HasSwitch(switches::kViewerConnect) ||
68      command_line->HasSwitch(switches::kViewerLaunchViaAppId)) {
69    return chrome::HOST_DESKTOP_TYPE_ASH;
70  }
71#elif defined(OS_LINUX)
72  const CommandLine* command_line = CommandLine::ForCurrentProcess();
73  if (command_line->HasSwitch(switches::kOpenAsh))
74    return chrome::HOST_DESKTOP_TYPE_ASH;
75#endif
76
77  return chrome::HOST_DESKTOP_TYPE_NATIVE;
78}
79#endif  // !defined(OS_CHROMEOS) && defined(USE_ASH)
80
81}  // namespace
82
83ChromeBrowserMainExtraPartsAura::ChromeBrowserMainExtraPartsAura() {
84}
85
86ChromeBrowserMainExtraPartsAura::~ChromeBrowserMainExtraPartsAura() {
87}
88
89void ChromeBrowserMainExtraPartsAura::PreEarlyInitialization() {
90#if defined(USE_X11) && !defined(OS_CHROMEOS)
91  if (GetInitialDesktop() != chrome::HOST_DESKTOP_TYPE_ASH) {
92    // TODO(erg): Refactor this into a dlopen call when we add a GTK3 port.
93    views::LinuxUI* gtk2_ui = BuildGtk2UI();
94    gtk2_ui->SetNativeThemeOverride(base::Bind(&GetNativeThemeForWindow));
95    views::LinuxUI::SetInstance(gtk2_ui);
96  } else {
97    // TODO(erg): Eventually, we'll need to somehow support IMEs in ash on
98    // Linux.
99    ui::InitializeInputMethodForTesting();
100  }
101#endif
102}
103
104void ChromeBrowserMainExtraPartsAura::ToolkitInitialized() {
105#if !defined(OS_CHROMEOS)
106#if defined(USE_ASH)
107  CHECK(aura::Env::GetInstance());
108  active_desktop_monitor_.reset(new ActiveDesktopMonitor(GetInitialDesktop()));
109#endif
110#endif
111
112#if defined(USE_X11) && !defined(OS_CHROMEOS)
113  if (GetInitialDesktop() != chrome::HOST_DESKTOP_TYPE_ASH)
114    views::LinuxUI::instance()->Initialize();
115#endif
116}
117
118void ChromeBrowserMainExtraPartsAura::PreCreateThreads() {
119#if !defined(OS_CHROMEOS)
120#if defined(USE_ASH)
121  if (!chrome::ShouldOpenAshOnStartup())
122#endif
123  {
124    gfx::Screen::SetScreenInstance(gfx::SCREEN_TYPE_NATIVE,
125                                   views::CreateDesktopScreen());
126  }
127#endif
128}
129
130void ChromeBrowserMainExtraPartsAura::PreProfileInit() {
131#if defined(OS_LINUX) && !defined(OS_CHROMEOS)
132  // Now that we have some minimal ui initialized, check to see if we're
133  // running as root and bail if we are.
134  DetectRunningAsRoot();
135#endif
136}
137
138void ChromeBrowserMainExtraPartsAura::PostMainMessageLoopRun() {
139  active_desktop_monitor_.reset();
140
141  // aura::Env instance is deleted in BrowserProcessImpl::StartTearDown
142  // after the metrics service is deleted.
143}
144
145#if defined(OS_LINUX) && !defined(OS_CHROMEOS)
146void ChromeBrowserMainExtraPartsAura::DetectRunningAsRoot() {
147  if (getuid() == 0) {
148    const CommandLine& command_line = *CommandLine::ForCurrentProcess();
149    if (command_line.HasSwitch(switches::kUserDataDir))
150      return;
151
152    base::string16 title = l10n_util::GetStringFUTF16(
153        IDS_REFUSE_TO_RUN_AS_ROOT,
154        l10n_util::GetStringUTF16(IDS_PRODUCT_NAME));
155    base::string16 message = l10n_util::GetStringFUTF16(
156        IDS_REFUSE_TO_RUN_AS_ROOT_2,
157        l10n_util::GetStringUTF16(IDS_PRODUCT_NAME));
158
159    chrome::ShowMessageBox(NULL,
160                           title,
161                           message,
162                           chrome::MESSAGE_BOX_TYPE_WARNING);
163
164    // Avoids gpu_process_transport_factory.cc(153)] Check failed:
165    // per_compositor_data_.empty() when quit is chosen.
166    base::RunLoop().RunUntilIdle();
167
168    exit(EXIT_FAILURE);
169  }
170}
171#endif
172