15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/browser/browser_main_runner.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/allocator/allocator_shim.h" 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/base_switches.h" 95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/command_line.h" 10f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#include "base/debug/leak_annotations.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/debug/trace_event.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/logging.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/metrics/histogram.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/metrics/statistics_recorder.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/browser/browser_main_loop.h" 1658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles)#include "content/browser/browser_shutdown_profile_dumper.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/browser/notification_service_impl.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/common/content_switches.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "content/public/common/main_function_params.h" 207d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "ui/base/ime/input_method_initializer.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) 231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "base/win/win_util.h" 242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/win/windows_version.h" 251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "net/cert/sha256_legacy_support_win.h" 261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "sandbox/win/src/sidestep/preamble_patcher.h" 27868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)#include "ui/base/win/scoped_ole_initializer.h" 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool g_exited_main_message_loop = false; 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace content { 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#if defined(OS_WIN) 351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccinamespace { 361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Pointer to the original CryptVerifyCertificateSignatureEx function. 381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccinet::sha256_interception::CryptVerifyCertificateSignatureExFunc 391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci g_real_crypt_verify_signature_stub = NULL; 401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Stub function that is called whenever the Crypt32 function 421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// CryptVerifyCertificateSignatureEx is called. It just defers to net to perform 431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// the actual verification. 441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano TucciBOOL WINAPI CryptVerifyCertificateSignatureExStub( 451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci HCRYPTPROV_LEGACY provider, 461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DWORD encoding_type, 471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DWORD subject_type, 481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci void* subject_data, 491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DWORD issuer_type, 501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci void* issuer_data, 511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DWORD flags, 521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci void* extra) { 531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return net::sha256_interception::CryptVerifyCertificateSignatureExHook( 541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci g_real_crypt_verify_signature_stub, provider, encoding_type, subject_type, 551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci subject_data, issuer_type, issuer_data, flags, extra); 561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// If necessary, install an interception 591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid InstallSha256LegacyHooks() { 601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#if defined(_WIN64) 611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Interception on x64 is not supported. 621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#else 641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (base::win::MaybeHasSHA256Support()) 651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci net::sha256_interception::CryptVerifyCertificateSignatureExFunc 681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci cert_verify_signature_ptr = reinterpret_cast< 691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci net::sha256_interception::CryptVerifyCertificateSignatureExFunc>( 701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ::GetProcAddress(::GetModuleHandle(L"crypt32.dll"), 711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci "CryptVerifyCertificateSignatureEx")); 721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci CHECK(cert_verify_signature_ptr); 731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DWORD old_protect = 0; 751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (!::VirtualProtect(cert_verify_signature_ptr, 5, PAGE_EXECUTE_READWRITE, 761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci &old_protect)) { 771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci g_real_crypt_verify_signature_stub = 811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci reinterpret_cast< 821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci net::sha256_interception::CryptVerifyCertificateSignatureExFunc>( 831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci VirtualAllocEx(::GetCurrentProcess(), NULL, 841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci sidestep::kMaxPreambleStubSize, MEM_COMMIT, 851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci PAGE_EXECUTE_READWRITE)); 861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (g_real_crypt_verify_signature_stub == NULL) { 871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci CHECK(::VirtualProtect(cert_verify_signature_ptr, 5, old_protect, 881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci &old_protect)); 891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci sidestep::SideStepError patch_result = 931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci sidestep::PreamblePatcher::Patch( 941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci cert_verify_signature_ptr, CryptVerifyCertificateSignatureExStub, 951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci g_real_crypt_verify_signature_stub, sidestep::kMaxPreambleStubSize); 961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci if (patch_result != sidestep::SIDESTEP_SUCCESS) { 971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci CHECK(::VirtualFreeEx(::GetCurrentProcess(), 981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci g_real_crypt_verify_signature_stub, 0, 991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci MEM_RELEASE)); 1001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci CHECK(::VirtualProtect(cert_verify_signature_ptr, 5, old_protect, 1011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci &old_protect)); 1021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return; 1031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci } 1041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci DWORD dummy = 0; 1061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci CHECK(::VirtualProtect(cert_verify_signature_ptr, 5, old_protect, &dummy)); 1071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci CHECK(::VirtualProtect(g_real_crypt_verify_signature_stub, 1081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci sidestep::kMaxPreambleStubSize, old_protect, 1091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci &old_protect)); 1101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#endif // _WIN64 1111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 1121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} // namespace 1141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#endif // OS_WIN 1161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class BrowserMainRunnerImpl : public BrowserMainRunner { 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public: 119424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) BrowserMainRunnerImpl() 120424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) : initialization_started_(false), is_shutdown_(false) {} 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1222a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) virtual ~BrowserMainRunnerImpl() { 123424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (initialization_started_ && !is_shutdown_) 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Shutdown(); 1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 127424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) virtual int Initialize(const MainFunctionParams& parameters) OVERRIDE { 128424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) TRACE_EVENT0("startup", "BrowserMainRunnerImpl::Initialize"); 129424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // On Android we normally initialize the browser in a series of UI thread 130424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // tasks. While this is happening a second request can come from the OS or 131424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // another application to start the browser. If this happens then we must 132424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // not run these parts of initialization twice. 133424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (!initialization_started_) { 134424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) initialization_started_ = true; 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#if !defined(OS_IOS) 137424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) if (parameters.command_line.HasSwitch(switches::kWaitForDebugger)) 138424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) base::debug::WaitForDebugger(60, true); 1397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#endif 1407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) 1425d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) if (base::win::GetVersion() < base::win::VERSION_VISTA) { 143424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // When "Extend support of advanced text services to all programs" 144424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // (a.k.a. Cicero Unaware Application Support; CUAS) is enabled on 145424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Windows XP and handwriting modules shipped with Office 2003 are 146424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // installed, "penjpn.dll" and "skchui.dll" will be loaded and then 1475d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // crash unless a user installs Office 2003 SP3. To prevent these 1485d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles) // modules from being loaded, disable TSF entirely. crbug.com/160914. 149424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // TODO(yukawa): Add a high-level wrapper for this instead of calling 150424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Win32 API here directly. 151424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ImmDisableTextFrameService(static_cast<DWORD>(-1)); 152424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 1531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci InstallSha256LegacyHooks(); 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif // OS_WIN 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 156424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) base::StatisticsRecorder::Initialize(); 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 158424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) notification_service_.reset(new NotificationServiceImpl); 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#if defined(OS_WIN) 161424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Ole must be initialized before starting message pump, so that TSF 162424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // (Text Services Framework) module can interact with the message pump 163424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // on Windows 8 Metro mode. 164424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ole_initializer_.reset(new ui::ScopedOleInitializer); 1652a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif // OS_WIN 1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 167424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) main_loop_.reset(new BrowserMainLoop(parameters)); 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 169424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) main_loop_->Init(); 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 171424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) main_loop_->EarlyInitialization(); 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 173424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Must happen before we try to use a message loop or display any UI. 1745c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu if (!main_loop_->InitializeToolkit()) 1755c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu return 1; 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 177424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) main_loop_->MainMessageLoopStart(); 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 179424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// WARNING: If we get a WM_ENDSESSION, objects created on the stack here 180424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// are NOT deleted. If you need something to run during WM_ENDSESSION add it 181424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles)// to browser_shutdown::Shutdown or BrowserProcess::EndSession. 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#if defined(OS_WIN) && !defined(NO_TCMALLOC) 184424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // When linking shared libraries, NO_TCMALLOC is defined, and dynamic 185424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // allocator selection is not supported. 1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 187424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // Make this call before going multithreaded, or spawning any 188424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // subprocesses. 189424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) base::allocator::SetupSubprocessAllocator(); 1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 191424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) ui::InitializeInputMethod(); 192424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) } 193a36e5920737c6adbddd3e43b760e5de8431db6e0Torne (Richard Coles) main_loop_->CreateStartupTasks(); 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int result_code = main_loop_->GetResultCode(); 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result_code > 0) 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result_code; 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Return -1 to indicate no early termination. 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return -1; 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual int Run() OVERRIDE { 203424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) DCHECK(initialization_started_); 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!is_shutdown_); 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) main_loop_->RunMainMessageLoopParts(); 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return main_loop_->GetResultCode(); 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) virtual void Shutdown() OVERRIDE { 210424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) DCHECK(initialization_started_); 2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(!is_shutdown_); 212f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#ifdef LEAK_SANITIZER 213f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Invoke leak detection now, to avoid dealing with shutdown-only leaks. 214f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // Normally this will have already happened in 215f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // BroserProcessImpl::ReleaseModule(), so this call has no effect. This is 216f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // only for processes which do not instantiate a BrowserProcess. 217f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) // If leaks are found, the process will exit here. 218f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles) __lsan_do_leak_check(); 219f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)#endif 220116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // If startup tracing has not been finished yet, replace it's dumper 221116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // with special version, which would save trace file on exit (i.e. 222116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch // startup tracing becomes a version of shutdown tracing). 223116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch scoped_ptr<BrowserShutdownProfileDumper> startup_profiler; 224116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (main_loop_->is_tracing_startup()) { 225116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch main_loop_->StopStartupTracingTimer(); 226116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (main_loop_->startup_trace_file() != 227116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch base::FilePath().AppendASCII("none")) { 228116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch startup_profiler.reset( 229116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch new BrowserShutdownProfileDumper(main_loop_->startup_trace_file())); 230116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 231116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 232116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch 23358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // The shutdown tracing got enabled in AttemptUserExit earlier, but someone 23458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // needs to write the result to disc. For that a dumper needs to get created 23558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // which will dump the traces to disc when it gets destroyed. 2366e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) const base::CommandLine& command_line = 2376e8cce623b6e4fe0c9e4af605d675dd9d0338c38Torne (Richard Coles) *base::CommandLine::ForCurrentProcess(); 238116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch scoped_ptr<BrowserShutdownProfileDumper> shutdown_profiler; 239116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch if (command_line.HasSwitch(switches::kTraceShutdown)) { 240116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch shutdown_profiler.reset(new BrowserShutdownProfileDumper( 241116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch BrowserShutdownProfileDumper::GetShutdownProfileFileName())); 242116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch } 2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 24458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) { 24558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) // The trace event has to stay between profiler creation and destruction. 24658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) TRACE_EVENT0("shutdown", "BrowserMainRunner"); 24758537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) g_exited_main_message_loop = true; 2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 24958537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) main_loop_->ShutdownThreadsAndCleanUp(); 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 25158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) ui::ShutdownInputMethod(); 25258537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) #if defined(OS_WIN) 25358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) ole_initializer_.reset(NULL); 25458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) #endif 255f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) #if defined(OS_ANDROID) 256f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // Forcefully terminates the RunLoop inside MessagePumpForUI, ensuring 257f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // proper shutdown for content_browsertests. Shutdown() is not used by 258f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) // the actual browser. 259f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) base::MessageLoop::current()->QuitNow(); 260f8ee788a64d60abd8f2d742a5fdedde054ecd910Torne (Richard Coles) #endif 26158537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) main_loop_.reset(NULL); 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 26358537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) notification_service_.reset(NULL); 26458537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) 26558537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) is_shutdown_ = true; 26658537e28ecd584eab876aee8be7156509866d23aTorne (Richard Coles) } 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected: 270424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) // True if we have started to initialize the runner. 271424c4d7b64af9d0d8fd9624f381f469654d5e3d2Torne (Richard Coles) bool initialization_started_; 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // True if the runner has been shut down. 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool is_shutdown_; 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<NotificationServiceImpl> notification_service_; 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<BrowserMainLoop> main_loop_; 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#if defined(OS_WIN) 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) scoped_ptr<ui::ScopedOleInitializer> ole_initializer_; 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#endif 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DISALLOW_COPY_AND_ASSIGN(BrowserMainRunnerImpl); 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}; 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// static 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)BrowserMainRunner* BrowserMainRunner::Create() { 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return new BrowserMainRunnerImpl(); 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace content 291