Home | History | Annotate | Download | only in browser
      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