blob: 94bd1b5c4c5805c249b614d077297e070ab0a900 [file] [log] [blame]
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +00001// 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.
4
5#include "chrome/browser/chromeos/login/chrome_restart_request.h"
6
7#include <vector>
8
9#include "ash/ash_switches.h"
10#include "base/chromeos/chromeos_version.h"
11#include "base/command_line.h"
12#include "base/memory/weak_ptr.h"
Ben Murdoch9ab55632013-07-18 11:57:30 +010013#include "base/message_loop/message_loop.h"
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000014#include "base/path_service.h"
15#include "base/prefs/json_pref_store.h"
16#include "base/prefs/pref_service.h"
Ben Murdochbbcdd452013-07-25 10:06:34 +010017#include "base/process/launch.h"
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000018#include "base/strings/string_split.h"
Torne (Richard Coles)5e3f23d2013-06-11 16:24:11 +010019#include "base/strings/stringprintf.h"
Ben Murdocheb525c52013-07-10 11:40:50 +010020#include "base/timer/timer.h"
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000021#include "base/values.h"
22#include "cc/base/switches.h"
23#include "chrome/browser/browser_process.h"
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +010024#include "chrome/browser/chromeos/login/user_manager.h"
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000025#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"
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000035#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/gfx/switches.h"
40#include "ui/gl/gl_switches.h"
41#include "ui/views/corewm/corewm_switches.h"
Ben Murdoch7dbb3d52013-07-17 14:55:54 +010042#include "url/gurl.h"
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000043#include "webkit/plugins/plugin_switches.h"
44
45using content::BrowserThread;
46
47namespace chromeos {
48
49namespace {
50
51// Increase logging level for Guest mode to avoid LOG(INFO) messages in logs.
52const char kGuestModeLoggingLevel[] = "1";
53
54// Format of command line switch.
55const char kSwitchFormatString[] = " --%s=\"%s\"";
56
57// User name which is used in the Guest session.
58const char kGuestUserName[] = "";
59
60// Derives the new command line from |base_command_line| by doing the following:
61// - Forward a given switches list to new command;
62// - Set start url if given;
63// - Append/override switches using |new_switches|;
64std::string DeriveCommandLine(const GURL& start_url,
65 const CommandLine& base_command_line,
66 const base::DictionaryValue& new_switches,
67 CommandLine* command_line) {
68 DCHECK_NE(&base_command_line, command_line);
69
70 static const char* kForwardSwitches[] = {
71 ::switches::kAllowWebUICompositing,
72 ::switches::kDeviceManagementUrl,
73 ::switches::kDisableAccelerated2dCanvas,
74 ::switches::kDisableAcceleratedOverflowScroll,
75 ::switches::kDisableAcceleratedPlugins,
76 ::switches::kDisableAcceleratedVideoDecode,
77 ::switches::kDisableBrowserPluginCompositing,
Ben Murdoch7dbb3d52013-07-17 14:55:54 +010078 ::switches::kDisableDelegatedRenderer,
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000079 ::switches::kDisableForceCompositingMode,
80 ::switches::kDisableGpuShaderDiskCache,
81 ::switches::kDisableGpuWatchdog,
Torne (Richard Coles)a36e5922013-08-05 13:57:33 +010082 ::switches::kDisableGpuCompositing,
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +010083 ::switches::kDisableLegacyEncryptedMedia,
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000084 ::switches::kDisablePanelFitting,
85 ::switches::kDisableSeccompFilterSandbox,
Torne (Richard Coles)7d4cd472013-06-19 11:58:07 +010086 ::switches::kDisableSetuidSandbox,
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000087 ::switches::kDisableThreadedCompositing,
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +010088 ::switches::kDisableTouchDragDrop,
89 ::switches::kDisableTouchEditing,
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +010090 ::switches::kDisableWebKitMediaSource,
Ben Murdoch7dbb3d52013-07-17 14:55:54 +010091 ::switches::kDisableAcceleratedFixedRootBackground,
92 ::switches::kEnableAcceleratedFixedRootBackground,
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000093 ::switches::kEnableAcceleratedOverflowScroll,
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +010094 ::switches::kEnableBeginFrameScheduling,
95 ::switches::kEnableBrowserInputController,
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000096 ::switches::kEnableCompositingForFixedPosition,
Ben Murdoch7dbb3d52013-07-17 14:55:54 +010097 ::switches::kEnableDelegatedRenderer,
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +010098 ::switches::kEnableEncryptedMedia,
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +000099 ::switches::kEnableGestureTapHighlight,
100 ::switches::kDisableGestureTapHighlight,
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100101 ::switches::kDisableGpuSandbox,
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000102 ::switches::kEnableLogging,
103 ::switches::kEnablePinch,
104 ::switches::kEnableThreadedCompositing,
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100105 ::switches::kEnableTouchDragDrop,
106 ::switches::kEnableTouchEditing,
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000107 ::switches::kEnableViewport,
108 ::switches::kForceDeviceScaleFactor,
109 ::switches::kGpuStartupDialog,
Torne (Richard Coles)a36e5922013-08-05 13:57:33 +0100110 ::switches::kGpuSandboxAllowSysVShm,
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +0100111 ::switches::kMultiProfiles,
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000112 ::switches::kNoSandbox,
113 ::switches::kPpapiFlashArgs,
114 ::switches::kPpapiFlashInProcess,
115 ::switches::kPpapiFlashPath,
116 ::switches::kPpapiFlashVersion,
117 ::switches::kPpapiInProcess,
118 ::switches::kRendererStartupDialog,
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +0100119 ::switches::kEnableShareGroupAsyncTextureUpload,
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +0100120 ::switches::kTabCaptureUpscaleQuality,
121 ::switches::kTabCaptureDownscaleQuality,
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000122#if defined(USE_XI2_MT)
123 ::switches::kTouchCalibration,
124#endif
125 ::switches::kTouchDevices,
126 ::switches::kTouchEvents,
127 ::switches::kTouchOptimizedUI,
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100128 ::switches::kUIDisableThreadedCompositing,
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000129 ::switches::kUIMaxFramesPending,
130 ::switches::kUIPrioritizeInGpuProcess,
131#if defined(USE_CRAS)
132 ::switches::kUseCras,
133#endif
134 ::switches::kUseGL,
135 ::switches::kUserDataDir,
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000136 ::switches::kV,
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +0100137 ::switches::kEnableWebGLDraftExtensions,
Ben Murdocheb525c52013-07-10 11:40:50 +0100138 ash::switches::kAshDefaultGuestWallpaperLarge,
139 ash::switches::kAshDefaultGuestWallpaperSmall,
140 ash::switches::kAshDefaultWallpaperLarge,
141 ash::switches::kAshDefaultWallpaperSmall,
Ben Murdochca12bfa2013-07-23 11:17:05 +0100142#if defined(OS_CHROMEOS)
143 ash::switches::kAshDisableAudioDeviceMenu,
Ben Murdochca12bfa2013-07-23 11:17:05 +0100144#endif
Ben Murdocheb525c52013-07-10 11:40:50 +0100145 ash::switches::kAshHostWindowBounds,
146 ash::switches::kAshTouchHud,
147 ash::switches::kAuraLegacyPowerButton,
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000148 // Please keep these in alphabetical order. Non-UI Compositor switches
149 // here should also be added to
150 // content/browser/renderer_host/render_process_host_impl.cc.
151 cc::switches::kBackgroundColorInsteadOfCheckerboard,
152 cc::switches::kCompositeToMailbox,
Ben Murdochca12bfa2013-07-23 11:17:05 +0100153 cc::switches::kDisableCompositedAntialiasing,
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000154 cc::switches::kDisableImplSidePainting,
155 cc::switches::kDisableThreadedAnimation,
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000156 cc::switches::kEnableImplSidePainting,
157 cc::switches::kEnablePartialSwap,
158 cc::switches::kEnablePerTilePainting,
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +0100159 cc::switches::kEnablePinchVirtualViewport,
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000160 cc::switches::kEnableTopControlsPositionCalculation,
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +0100161 cc::switches::kForceDirectLayerDrawing,
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000162 cc::switches::kLowResolutionContentsScaleFactor,
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100163 cc::switches::kMaxTilesForInterestArea,
164 cc::switches::kMaxUnusedResourceMemoryUsagePercentage,
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000165 cc::switches::kNumRasterThreads,
166 cc::switches::kShowCompositedLayerBorders,
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000167 cc::switches::kShowFPSCounter,
168 cc::switches::kShowNonOccludingRects,
169 cc::switches::kShowOccludingRects,
170 cc::switches::kShowPropertyChangedRects,
171 cc::switches::kShowReplicaScreenSpaceRects,
172 cc::switches::kShowScreenSpaceRects,
173 cc::switches::kShowSurfaceDamageRects,
174 cc::switches::kSlowDownRasterScaleFactor,
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000175 cc::switches::kTraceOverdraw,
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100176 cc::switches::kUIDisablePartialSwap,
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000177 cc::switches::kUIEnablePerTilePainting,
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +0100178 cc::switches::kUseMapImage,
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000179 chromeos::switches::kDbusStub,
Torne (Richard Coles)b2df76e2013-05-13 16:52:09 +0100180 chromeos::switches::kDisableLoginAnimations,
181 chromeos::switches::kDisableOobeAnimation,
182 chromeos::switches::kHasChromeOSDiamondKey,
183 chromeos::switches::kHasChromeOSKeyboard,
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100184 chromeos::switches::kLoginProfile,
Torne (Richard Coles)b2df76e2013-05-13 16:52:09 +0100185 chromeos::switches::kNaturalScrollDefault,
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +0100186 chromeos::switches::kUseNewNetworkConfigurationHandlers,
Torne (Richard Coles)868fa2f2013-06-11 10:57:03 +0100187 chromeos::switches::kUseNewNetworkConnectionHandler,
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000188 gfx::switches::kEnableBrowserTextSubpixelPositioning,
189 gfx::switches::kEnableWebkitTextSubpixelPositioning,
190 views::corewm::switches::kNoDropShadows,
191 views::corewm::switches::kWindowAnimationsDisabled,
192 };
193 command_line->CopySwitchesFrom(base_command_line,
194 kForwardSwitches,
195 arraysize(kForwardSwitches));
196
197 if (start_url.is_valid())
198 command_line->AppendArg(start_url.spec());
199
200 for (base::DictionaryValue::Iterator it(new_switches);
201 !it.IsAtEnd();
202 it.Advance()) {
203 std::string value;
204 CHECK(it.value().GetAsString(&value));
205 command_line->AppendSwitchASCII(it.key(), value);
206 }
207
208 std::string cmd_line_str = command_line->GetCommandLineString();
209 // Special workaround for the arguments that should be quoted.
210 // Copying switches won't be needed when Guest mode won't need restart
211 // http://crosbug.com/6924
212 if (base_command_line.HasSwitch(::switches::kRegisterPepperPlugins)) {
213 cmd_line_str += base::StringPrintf(
214 kSwitchFormatString,
215 ::switches::kRegisterPepperPlugins,
216 base_command_line.GetSwitchValueNative(
217 ::switches::kRegisterPepperPlugins).c_str());
218 }
219
220 // TODO(zelidrag): Remove this hack that get us around compositing bug from
221 // http://crbug.com/179256 once that bug is resolved.
222 if (command_line->HasSwitch(::switches::kForceAppMode)) {
223 std::string switch_to_remove("--");
224 switch_to_remove.append(cc::switches::kEnablePartialSwap);
225 cmd_line_str = cmd_line_str.replace(cmd_line_str.find(switch_to_remove),
226 switch_to_remove.length(), "");
227 }
228
229 return cmd_line_str;
230}
231
232// Simulates a session manager restart by launching give command line
233// and exit current process.
234void ReLaunch(const std::string& command_line) {
235 std::vector<std::string> argv;
236
237 // This is not a proper way to get |argv| but it's good enough for debugging.
238 base::SplitString(command_line, ' ', &argv);
239
240 base::LaunchProcess(argv, base::LaunchOptions(), NULL);
241 chrome::AttemptUserExit();
242}
243
244// Empty function that run by the local state task runner to ensure last
245// commit goes through.
246void EnsureLocalStateIsWritten() {}
247
248// Wraps the work of sending chrome restart request to session manager.
249// If local state is present, try to commit it first. The request is fired when
250// the commit goes through or some time (3 seconds) has elapsed.
251class ChromeRestartRequest
252 : public base::SupportsWeakPtr<ChromeRestartRequest> {
253 public:
254 explicit ChromeRestartRequest(const std::string& command_line);
255 ~ChromeRestartRequest();
256
257 // Starts the request.
258 void Start();
259
260 private:
261 // Fires job restart request to session manager.
262 void RestartJob();
263
264 const int pid_;
265 const std::string command_line_;
266 base::OneShotTimer<ChromeRestartRequest> timer_;
267
268 DISALLOW_COPY_AND_ASSIGN(ChromeRestartRequest);
269};
270
271ChromeRestartRequest::ChromeRestartRequest(const std::string& command_line)
272 : pid_(getpid()),
273 command_line_(command_line) {}
274
275ChromeRestartRequest::~ChromeRestartRequest() {}
276
277void ChromeRestartRequest::Start() {
278 VLOG(1) << "Requesting a restart with PID " << pid_
279 << " and command line: " << command_line_;
280
281 // Session Manager may kill the chrome anytime after this point.
282 // Write exit_cleanly and other stuff to the disk here.
283 g_browser_process->EndSession();
284
285 PrefService* local_state = g_browser_process->local_state();
286 if (!local_state) {
287 RestartJob();
288 return;
289 }
290
291 // XXX: normally this call must not be needed, however RestartJob
292 // just kills us so settings may be lost. See http://crosbug.com/13102
293 local_state->CommitPendingWrite();
294 timer_.Start(
295 FROM_HERE, base::TimeDelta::FromSeconds(3), this,
296 &ChromeRestartRequest::RestartJob);
297
298 // Post a task to local state task runner thus it occurs last on the task
299 // queue, so it would be executed after committing pending write on that
300 // thread.
301 scoped_refptr<base::SequencedTaskRunner> local_state_task_runner =
302 JsonPrefStore::GetTaskRunnerForFile(
303 base::FilePath(chrome::kLocalStorePoolName),
304 BrowserThread::GetBlockingPool());
305 local_state_task_runner->PostTaskAndReply(
306 FROM_HERE,
307 base::Bind(&EnsureLocalStateIsWritten),
308 base::Bind(&ChromeRestartRequest::RestartJob, AsWeakPtr()));
309}
310
311void ChromeRestartRequest::RestartJob() {
312 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
313
314 DBusThreadManager::Get()->GetSessionManagerClient()->RestartJob(
315 pid_, command_line_);
316
317 delete this;
318}
319
320} // namespace
321
322std::string GetOffTheRecordCommandLine(
323 const GURL& start_url,
324 const CommandLine& base_command_line,
325 CommandLine* command_line) {
326 base::DictionaryValue otr_switches;
Torne (Richard Coles)c2e0dbd2013-05-09 18:35:53 +0100327 otr_switches.SetString(switches::kGuestSession, std::string());
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000328 otr_switches.SetString(::switches::kIncognito, std::string());
329 otr_switches.SetString(::switches::kLoggingLevel, kGuestModeLoggingLevel);
Torne (Richard Coles)90dce4d2013-05-29 14:40:03 +0100330 otr_switches.SetString(switches::kLoginUser, UserManager::kGuestUserName);
Torne (Richard Coles)2a99a7e2013-03-28 15:31:22 +0000331
332 // Override the home page.
333 otr_switches.SetString(::switches::kHomePage,
334 GURL(chrome::kChromeUINewTabURL).spec());
335
336 return DeriveCommandLine(start_url,
337 base_command_line,
338 otr_switches,
339 command_line);
340}
341
342void RestartChrome(const std::string& command_line) {
343 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
344
345 static bool restart_requested = false;
346 if (restart_requested) {
347 NOTREACHED() << "Request chrome restart for more than once.";
348 }
349 restart_requested = true;
350
351 if (!base::chromeos::IsRunningOnChromeOS()) {
352 // Relaunch chrome without session manager on dev box.
353 ReLaunch(command_line);
354 return;
355 }
356
357 // ChromeRestartRequest deletes itself after request sent to session manager.
358 (new ChromeRestartRequest(command_line))->Start();
359}
360
361} // namespace chromeos