1 // Copyright (c) 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/browser_process_platform_part_aurawin.h" 6 7 #include "base/command_line.h" 8 #include "base/logging.h" 9 #include "base/process/kill.h" 10 #include "base/win/windows_version.h" 11 #include "chrome/browser/browser_process.h" 12 #include "chrome/browser/metro_viewer/chrome_metro_viewer_process_host_aurawin.h" 13 #include "chrome/common/chrome_switches.h" 14 15 BrowserProcessPlatformPart::BrowserProcessPlatformPart() { 16 } 17 18 BrowserProcessPlatformPart::~BrowserProcessPlatformPart() { 19 } 20 21 void BrowserProcessPlatformPart::OnMetroViewerProcessTerminated() { 22 metro_viewer_process_host_.reset(NULL); 23 } 24 25 void BrowserProcessPlatformPart::PlatformSpecificCommandLineProcessing( 26 const CommandLine& command_line) { 27 // Check for Windows 8 specific commandlines requesting that this process 28 // either connect to an existing viewer or launch a new viewer and 29 // synchronously wait for it to connect. 30 if (base::win::GetVersion() >= base::win::VERSION_WIN8) { 31 bool launch = command_line.HasSwitch(switches::kViewerLaunchViaAppId); 32 bool connect = (launch || 33 (command_line.HasSwitch(switches::kViewerConnect) && 34 !metro_viewer_process_host_.get())); 35 if (connect) { 36 // Create a host to connect to the Metro viewer process over IPC. 37 metro_viewer_process_host_.reset(new ChromeMetroViewerProcessHost()); 38 if (launch) { 39 CHECK(metro_viewer_process_host_->LaunchViewerAndWaitForConnection( 40 command_line.GetSwitchValueNative( 41 switches::kViewerLaunchViaAppId))); 42 } 43 } 44 } 45 } 46 47 void BrowserProcessPlatformPart::AttemptExit() { 48 // On WinAura, the regular exit path is fine except on Win8+, where Ash might 49 // be active in Metro and won't go away even if all browsers are closed. The 50 // viewer process, whose host holds a reference to g_browser_process, needs to 51 // be killed as well. 52 BrowserProcessPlatformPartBase::AttemptExit(); 53 54 if (base::win::GetVersion() >= base::win::VERSION_WIN8 && 55 metro_viewer_process_host_) { 56 base::ProcessId viewer_id = 57 metro_viewer_process_host_->GetViewerProcessId(); 58 if (viewer_id == base::kNullProcessId) 59 return; 60 // The viewer doesn't hold any state so it is fine to kill it before it 61 // cleanly exits. This will trigger MetroViewerProcessHost::OnChannelError() 62 // which will cleanup references to g_browser_process. 63 bool success = base::KillProcessById(viewer_id, 0, true); 64 DCHECK(success); 65 } 66 } 67