1 // Copyright (c) 2012 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 "content/public/browser/browser_main_runner.h" 6 7 #include "base/allocator/allocator_shim.h" 8 #include "base/base_switches.h" 9 #include "base/command_line.h" 10 #include "base/debug/trace_event.h" 11 #include "base/logging.h" 12 #include "base/metrics/histogram.h" 13 #include "base/metrics/statistics_recorder.h" 14 #include "content/browser/browser_main_loop.h" 15 #include "content/browser/notification_service_impl.h" 16 #include "content/public/common/content_switches.h" 17 #include "content/public/common/main_function_params.h" 18 #include "ui/base/ime/input_method_initializer.h" 19 20 #if defined(OS_WIN) 21 #include "base/win/metro.h" 22 #include "base/win/windows_version.h" 23 #include "ui/base/win/scoped_ole_initializer.h" 24 #endif 25 26 bool g_exited_main_message_loop = false; 27 28 namespace content { 29 30 class BrowserMainRunnerImpl : public BrowserMainRunner { 31 public: 32 BrowserMainRunnerImpl() : is_initialized_(false), is_shutdown_(false) {} 33 34 virtual ~BrowserMainRunnerImpl() { 35 if (is_initialized_ && !is_shutdown_) 36 Shutdown(); 37 } 38 39 virtual int Initialize(const MainFunctionParams& parameters) 40 OVERRIDE { 41 TRACE_EVENT0("startup", "BrowserMainRunnerImpl::Initialize") 42 is_initialized_ = true; 43 44 #if !defined(OS_IOS) 45 if (parameters.command_line.HasSwitch(switches::kWaitForDebugger)) 46 base::debug::WaitForDebugger(60, true); 47 #endif 48 49 #if defined(OS_WIN) 50 if (parameters.command_line.HasSwitch( 51 switches::kEnableTextServicesFramework)) { 52 base::win::SetForceToUseTSF(); 53 } else if (base::win::GetVersion() < base::win::VERSION_VISTA) { 54 // When "Extend support of advanced text services to all programs" 55 // (a.k.a. Cicero Unaware Application Support; CUAS) is enabled on 56 // Windows XP and handwriting modules shipped with Office 2003 are 57 // installed, "penjpn.dll" and "skchui.dll" will be loaded and then crash 58 // unless a user installs Office 2003 SP3. To prevent these modules from 59 // being loaded, disable TSF entirely. crbug/160914. 60 // TODO(yukawa): Add a high-level wrapper for this instead of calling 61 // Win32 API here directly. 62 ImmDisableTextFrameService(static_cast<DWORD>(-1)); 63 } 64 #endif // OS_WIN 65 66 base::StatisticsRecorder::Initialize(); 67 68 notification_service_.reset(new NotificationServiceImpl); 69 70 #if defined(OS_WIN) 71 // Ole must be initialized before starting message pump, so that TSF 72 // (Text Services Framework) module can interact with the message pump 73 // on Windows 8 Metro mode. 74 ole_initializer_.reset(new ui::ScopedOleInitializer); 75 #endif // OS_WIN 76 77 main_loop_.reset(new BrowserMainLoop(parameters)); 78 79 main_loop_->Init(); 80 81 main_loop_->EarlyInitialization(); 82 83 // Must happen before we try to use a message loop or display any UI. 84 main_loop_->InitializeToolkit(); 85 86 main_loop_->MainMessageLoopStart(); 87 88 // WARNING: If we get a WM_ENDSESSION, objects created on the stack here 89 // are NOT deleted. If you need something to run during WM_ENDSESSION add it 90 // to browser_shutdown::Shutdown or BrowserProcess::EndSession. 91 92 #if defined(OS_WIN) && !defined(NO_TCMALLOC) 93 // When linking shared libraries, NO_TCMALLOC is defined, and dynamic 94 // allocator selection is not supported. 95 96 // Make this call before going multithreaded, or spawning any subprocesses. 97 base::allocator::SetupSubprocessAllocator(); 98 #endif 99 ui::InitializeInputMethod(); 100 101 main_loop_->CreateStartupTasks(); 102 int result_code = main_loop_->GetResultCode(); 103 if (result_code > 0) 104 return result_code; 105 106 // Return -1 to indicate no early termination. 107 return -1; 108 } 109 110 virtual int Run() OVERRIDE { 111 DCHECK(is_initialized_); 112 DCHECK(!is_shutdown_); 113 main_loop_->RunMainMessageLoopParts(); 114 return main_loop_->GetResultCode(); 115 } 116 117 virtual void Shutdown() OVERRIDE { 118 DCHECK(is_initialized_); 119 DCHECK(!is_shutdown_); 120 g_exited_main_message_loop = true; 121 122 main_loop_->ShutdownThreadsAndCleanUp(); 123 124 ui::ShutdownInputMethod(); 125 #if defined(OS_WIN) 126 ole_initializer_.reset(NULL); 127 #endif 128 129 main_loop_.reset(NULL); 130 131 notification_service_.reset(NULL); 132 133 is_shutdown_ = true; 134 } 135 136 protected: 137 // True if the runner has been initialized. 138 bool is_initialized_; 139 140 // True if the runner has been shut down. 141 bool is_shutdown_; 142 143 scoped_ptr<NotificationServiceImpl> notification_service_; 144 scoped_ptr<BrowserMainLoop> main_loop_; 145 #if defined(OS_WIN) 146 scoped_ptr<ui::ScopedOleInitializer> ole_initializer_; 147 #endif 148 149 DISALLOW_COPY_AND_ASSIGN(BrowserMainRunnerImpl); 150 }; 151 152 // static 153 BrowserMainRunner* BrowserMainRunner::Create() { 154 return new BrowserMainRunnerImpl(); 155 } 156 157 } // namespace content 158