Disable view source for Developer Tools.
[chromium-blink-merge.git] / chrome / browser / chromeos / login / chrome_restart_request.cc
blobcac98ce1ff8a94ff1c212a6c371a5a5d18564da9
1 // Copyright 2013 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.
5 #include "chrome/browser/chromeos/login/chrome_restart_request.h"
7 #include <vector>
9 #include "ash/ash_switches.h"
10 #include "base/command_line.h"
11 #include "base/memory/weak_ptr.h"
12 #include "base/message_loop/message_loop.h"
13 #include "base/path_service.h"
14 #include "base/prefs/json_pref_store.h"
15 #include "base/prefs/pref_service.h"
16 #include "base/process/launch.h"
17 #include "base/strings/string_split.h"
18 #include "base/strings/stringprintf.h"
19 #include "base/sys_info.h"
20 #include "base/timer/timer.h"
21 #include "base/values.h"
22 #include "cc/base/switches.h"
23 #include "chrome/browser/browser_process.h"
24 #include "chrome/browser/chromeos/login/user_manager.h"
25 #include "chrome/browser/lifetime/application_lifetime.h"
26 #include "chrome/common/chrome_constants.h"
27 #include "chrome/common/chrome_paths.h"
28 #include "chrome/common/chrome_switches.h"
29 #include "chrome/common/url_constants.h"
30 #include "chromeos/chromeos_switches.h"
31 #include "chromeos/dbus/dbus_thread_manager.h"
32 #include "chromeos/dbus/session_manager_client.h"
33 #include "content/public/browser/browser_thread.h"
34 #include "content/public/common/content_switches.h"
35 #include "gpu/command_buffer/service/gpu_switches.h"
36 #include "media/base/media_switches.h"
37 #include "ui/base/ui_base_switches.h"
38 #include "ui/compositor/compositor_switches.h"
39 #include "ui/events/event_switches.h"
40 #include "ui/gfx/switches.h"
41 #include "ui/gl/gl_switches.h"
42 #include "ui/views/corewm/corewm_switches.h"
43 #include "url/gurl.h"
45 using content::BrowserThread;
47 namespace chromeos {
49 namespace {
51 // Increase logging level for Guest mode to avoid INFO messages in logs.
52 const char kGuestModeLoggingLevel[] = "1";
54 // Format of command line switch.
55 const char kSwitchFormatString[] = " --%s=\"%s\"";
57 // Derives the new command line from |base_command_line| by doing the following:
58 // - Forward a given switches list to new command;
59 // - Set start url if given;
60 // - Append/override switches using |new_switches|;
61 std::string DeriveCommandLine(const GURL& start_url,
62 const CommandLine& base_command_line,
63 const base::DictionaryValue& new_switches,
64 CommandLine* command_line) {
65 DCHECK_NE(&base_command_line, command_line);
67 static const char* kForwardSwitches[] = {
68 ::switches::kAllowWebUICompositing,
69 ::switches::kDeviceManagementUrl,
70 ::switches::kDisableAccelerated2dCanvas,
71 ::switches::kDisableAcceleratedOverflowScroll,
72 ::switches::kDisableAcceleratedPlugins,
73 ::switches::kDisableAcceleratedVideoDecode,
74 ::switches::kDisableBrowserPluginCompositing,
75 ::switches::kDisableDeadlineScheduling,
76 ::switches::kDisableDelegatedRenderer,
77 ::switches::kDisableFiltersOverIPC,
78 ::switches::kDisableForceCompositingMode,
79 ::switches::kDisableGpuShaderDiskCache,
80 ::switches::kDisableGpuWatchdog,
81 ::switches::kDisableGpuCompositing,
82 ::switches::kDisablePrefixedEncryptedMedia,
83 ::switches::kDisablePanelFitting,
84 ::switches::kDisableSeccompFilterSandbox,
85 ::switches::kDisableSetuidSandbox,
86 ::switches::kDisableThreadedCompositing,
87 ::switches::kDisableTouchDragDrop,
88 ::switches::kDisableTouchEditing,
89 ::switches::kDisableUniversalAcceleratedOverflowScroll,
90 ::switches::kDisableUnprefixedMediaSource,
91 ::switches::kDisableWebKitMediaSource,
92 ::switches::kDisableAcceleratedFixedRootBackground,
93 ::switches::kEnableAcceleratedFixedRootBackground,
94 ::switches::kEnableAcceleratedOverflowScroll,
95 ::switches::kEnableBeginFrameScheduling,
96 ::switches::kEnableCompositingForFixedPosition,
97 ::switches::kEnableDeadlineScheduling,
98 ::switches::kEnableDelegatedRenderer,
99 ::switches::kEnableEncryptedMedia,
100 ::switches::kEnableGestureTapHighlight,
101 ::switches::kDisableGestureTapHighlight,
102 ::switches::kDisableGpuSandbox,
103 ::switches::kEnableLogging,
104 ::switches::kEnablePinch,
105 ::switches::kEnableRepaintAfterLayout,
106 ::switches::kEnableThreadedCompositing,
107 ::switches::kEnableTouchDragDrop,
108 ::switches::kEnableTouchEditing,
109 ::switches::kEnableUniversalAcceleratedOverflowScroll,
110 ::switches::kEnableViewport,
111 ::switches::kEnableViewportMeta,
112 ::switches::kMainFrameResizesAreOrientationChanges,
113 ::switches::kForceDeviceScaleFactor,
114 ::switches::kGpuStartupDialog,
115 ::switches::kGpuSandboxAllowSysVShm,
116 ::switches::kMultiProfiles,
117 ::switches::kNoSandbox,
118 ::switches::kPpapiFlashArgs,
119 ::switches::kPpapiFlashInProcess,
120 ::switches::kPpapiFlashPath,
121 ::switches::kPpapiFlashVersion,
122 ::switches::kPpapiInProcess,
123 ::switches::kRendererStartupDialog,
124 ::switches::kEnableShareGroupAsyncTextureUpload,
125 ::switches::kTabCaptureUpscaleQuality,
126 ::switches::kTabCaptureDownscaleQuality,
127 #if defined(USE_XI2_MT)
128 ::switches::kTouchCalibration,
129 #endif
130 ::switches::kTouchDevices,
131 ::switches::kTouchEvents,
132 ::switches::kTouchOptimizedUI,
133 ::switches::kUIDisableDeadlineScheduling,
134 ::switches::kUIDisableThreadedCompositing,
135 ::switches::kUIEnableDeadlineScheduling,
136 ::switches::kUIMaxFramesPending,
137 ::switches::kUIPrioritizeInGpuProcess,
138 #if defined(USE_CRAS)
139 ::switches::kUseCras,
140 #endif
141 ::switches::kUseDiscardableMemory,
142 ::switches::kUseGL,
143 ::switches::kUserDataDir,
144 ::switches::kV,
145 ::switches::kVModule,
146 ::switches::kWebGLCommandBufferSizeKb,
147 ::switches::kEnableWebGLDraftExtensions,
148 #if defined(ENABLE_WEBRTC)
149 ::switches::kDisableWebRtcHWDecoding,
150 ::switches::kDisableWebRtcHWEncoding,
151 ::switches::kEnableAudioTrackProcessing,
152 ::switches::kEnableWebRtcHWVp8Encoding,
153 #endif
154 ash::switches::kAshDefaultWallpaperLarge,
155 ash::switches::kAshDefaultWallpaperSmall,
156 #if defined(OS_CHROMEOS)
157 ash::switches::kAshDisableAudioDeviceMenu,
158 #endif
159 ash::switches::kAshGuestWallpaperLarge,
160 ash::switches::kAshGuestWallpaperSmall,
161 ash::switches::kAshHostWindowBounds,
162 ash::switches::kAshTouchHud,
163 ash::switches::kAuraLegacyPowerButton,
164 // Please keep these in alphabetical order. Non-UI Compositor switches
165 // here should also be added to
166 // content/browser/renderer_host/render_process_host_impl.cc.
167 cc::switches::kBackgroundColorInsteadOfCheckerboard,
168 cc::switches::kCompositeToMailbox,
169 cc::switches::kDisableCompositedAntialiasing,
170 cc::switches::kDisableCompositorTouchHitTesting,
171 cc::switches::kDisableGPURasterization,
172 cc::switches::kDisableImplSidePainting,
173 cc::switches::kDisableMapImage,
174 cc::switches::kDisableThreadedAnimation,
175 cc::switches::kEnableGPURasterization,
176 cc::switches::kEnableImplSidePainting,
177 cc::switches::kEnableMapImage,
178 cc::switches::kEnablePartialSwap,
179 cc::switches::kEnablePerTilePainting,
180 cc::switches::kEnablePinchVirtualViewport,
181 cc::switches::kEnableTopControlsPositionCalculation,
182 cc::switches::kMaxTilesForInterestArea,
183 cc::switches::kMaxUnusedResourceMemoryUsagePercentage,
184 cc::switches::kNumRasterThreads,
185 cc::switches::kShowCompositedLayerBorders,
186 cc::switches::kShowFPSCounter,
187 cc::switches::kShowLayerAnimationBounds,
188 cc::switches::kShowNonOccludingRects,
189 cc::switches::kShowOccludingRects,
190 cc::switches::kShowPropertyChangedRects,
191 cc::switches::kShowReplicaScreenSpaceRects,
192 cc::switches::kShowScreenSpaceRects,
193 cc::switches::kShowSurfaceDamageRects,
194 cc::switches::kSlowDownRasterScaleFactor,
195 cc::switches::kTraceOverdraw,
196 cc::switches::kUIDisablePartialSwap,
197 cc::switches::kUIEnablePerTilePainting,
198 chromeos::switches::kDbusStub,
199 chromeos::switches::kDisableLoginAnimations,
200 chromeos::switches::kDisableOobeAnimation,
201 chromeos::switches::kGpuSandboxFailuresNonfatal,
202 chromeos::switches::kHasChromeOSDiamondKey,
203 chromeos::switches::kHasChromeOSKeyboard,
204 chromeos::switches::kLoginProfile,
205 chromeos::switches::kNaturalScrollDefault,
206 ::switches::kEnableBrowserTextSubpixelPositioning,
207 ::switches::kEnableWebkitTextSubpixelPositioning,
208 views::corewm::switches::kNoDropShadows,
209 views::corewm::switches::kWindowAnimationsDisabled,
211 command_line->CopySwitchesFrom(base_command_line,
212 kForwardSwitches,
213 arraysize(kForwardSwitches));
215 if (start_url.is_valid())
216 command_line->AppendArg(start_url.spec());
218 for (base::DictionaryValue::Iterator it(new_switches);
219 !it.IsAtEnd();
220 it.Advance()) {
221 std::string value;
222 CHECK(it.value().GetAsString(&value));
223 command_line->AppendSwitchASCII(it.key(), value);
226 std::string cmd_line_str = command_line->GetCommandLineString();
227 // Special workaround for the arguments that should be quoted.
228 // Copying switches won't be needed when Guest mode won't need restart
229 // http://crosbug.com/6924
230 if (base_command_line.HasSwitch(::switches::kRegisterPepperPlugins)) {
231 cmd_line_str += base::StringPrintf(
232 kSwitchFormatString,
233 ::switches::kRegisterPepperPlugins,
234 base_command_line.GetSwitchValueNative(
235 ::switches::kRegisterPepperPlugins).c_str());
238 // TODO(zelidrag): Remove this hack that get us around compositing bug from
239 // http://crbug.com/179256 once that bug is resolved.
240 if (command_line->HasSwitch(::switches::kForceAppMode)) {
241 std::string switch_to_remove("--");
242 switch_to_remove.append(cc::switches::kEnablePartialSwap);
243 cmd_line_str = cmd_line_str.replace(cmd_line_str.find(switch_to_remove),
244 switch_to_remove.length(), "");
247 return cmd_line_str;
250 // Simulates a session manager restart by launching give command line
251 // and exit current process.
252 void ReLaunch(const std::string& command_line) {
253 std::vector<std::string> argv;
255 // This is not a proper way to get |argv| but it's good enough for debugging.
256 base::SplitString(command_line, ' ', &argv);
258 base::LaunchProcess(argv, base::LaunchOptions(), NULL);
259 chrome::AttemptUserExit();
262 // Empty function that run by the local state task runner to ensure last
263 // commit goes through.
264 void EnsureLocalStateIsWritten() {}
266 // Wraps the work of sending chrome restart request to session manager.
267 // If local state is present, try to commit it first. The request is fired when
268 // the commit goes through or some time (3 seconds) has elapsed.
269 class ChromeRestartRequest
270 : public base::SupportsWeakPtr<ChromeRestartRequest> {
271 public:
272 explicit ChromeRestartRequest(const std::string& command_line);
273 ~ChromeRestartRequest();
275 // Starts the request.
276 void Start();
278 private:
279 // Fires job restart request to session manager.
280 void RestartJob();
282 const int pid_;
283 const std::string command_line_;
284 base::OneShotTimer<ChromeRestartRequest> timer_;
286 DISALLOW_COPY_AND_ASSIGN(ChromeRestartRequest);
289 ChromeRestartRequest::ChromeRestartRequest(const std::string& command_line)
290 : pid_(getpid()),
291 command_line_(command_line) {}
293 ChromeRestartRequest::~ChromeRestartRequest() {}
295 void ChromeRestartRequest::Start() {
296 VLOG(1) << "Requesting a restart with PID " << pid_
297 << " and command line: " << command_line_;
299 // Session Manager may kill the chrome anytime after this point.
300 // Write exit_cleanly and other stuff to the disk here.
301 g_browser_process->EndSession();
303 PrefService* local_state = g_browser_process->local_state();
304 if (!local_state) {
305 RestartJob();
306 return;
309 // XXX: normally this call must not be needed, however RestartJob
310 // just kills us so settings may be lost. See http://crosbug.com/13102
311 local_state->CommitPendingWrite();
312 timer_.Start(
313 FROM_HERE, base::TimeDelta::FromSeconds(3), this,
314 &ChromeRestartRequest::RestartJob);
316 // Post a task to local state task runner thus it occurs last on the task
317 // queue, so it would be executed after committing pending write on that
318 // thread.
319 scoped_refptr<base::SequencedTaskRunner> local_state_task_runner =
320 JsonPrefStore::GetTaskRunnerForFile(
321 base::FilePath(chrome::kLocalStorePoolName),
322 BrowserThread::GetBlockingPool());
323 local_state_task_runner->PostTaskAndReply(
324 FROM_HERE,
325 base::Bind(&EnsureLocalStateIsWritten),
326 base::Bind(&ChromeRestartRequest::RestartJob, AsWeakPtr()));
329 void ChromeRestartRequest::RestartJob() {
330 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
332 DBusThreadManager::Get()->GetSessionManagerClient()->RestartJob(
333 pid_, command_line_);
335 delete this;
338 } // namespace
340 std::string GetOffTheRecordCommandLine(
341 const GURL& start_url,
342 const CommandLine& base_command_line,
343 CommandLine* command_line) {
344 base::DictionaryValue otr_switches;
345 otr_switches.SetString(switches::kGuestSession, std::string());
346 otr_switches.SetString(::switches::kIncognito, std::string());
347 otr_switches.SetString(::switches::kLoggingLevel, kGuestModeLoggingLevel);
348 otr_switches.SetString(switches::kLoginUser, UserManager::kGuestUserName);
350 // Override the home page.
351 otr_switches.SetString(::switches::kHomePage,
352 GURL(chrome::kChromeUINewTabURL).spec());
354 return DeriveCommandLine(start_url,
355 base_command_line,
356 otr_switches,
357 command_line);
360 void RestartChrome(const std::string& command_line) {
361 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
363 static bool restart_requested = false;
364 if (restart_requested) {
365 NOTREACHED() << "Request chrome restart for more than once.";
367 restart_requested = true;
369 if (!base::SysInfo::IsRunningOnChromeOS()) {
370 // Relaunch chrome without session manager on dev box.
371 ReLaunch(command_line);
372 return;
375 // ChromeRestartRequest deletes itself after request sent to session manager.
376 (new ChromeRestartRequest(command_line))->Start();
379 } // namespace chromeos