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