Home | History | Annotate | Download | only in browser
      1 // Copyright (c) 2011 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_main_posix.h"
      6 
      7 #import <Cocoa/Cocoa.h>
      8 
      9 #include "base/command_line.h"
     10 #include "base/debug/debugger.h"
     11 #include "base/file_path.h"
     12 #include "base/mac/mac_util.h"
     13 #include "base/memory/scoped_nsobject.h"
     14 #include "base/path_service.h"
     15 #include "crypto/nss_util.h"
     16 #include "chrome/app/breakpad_mac.h"
     17 #import "chrome/browser/app_controller_mac.h"
     18 #include "chrome/browser/browser_main_win.h"
     19 #import "chrome/browser/chrome_browser_application_mac.h"
     20 #import "chrome/browser/cocoa/keystone_glue.h"
     21 #include "chrome/browser/metrics/metrics_service.h"
     22 #include "chrome/common/chrome_paths.h"
     23 #include "chrome/common/chrome_switches.h"
     24 #include "content/common/main_function_params.h"
     25 #include "content/common/result_codes.h"
     26 #include "net/socket/client_socket_factory.h"
     27 #include "ui/base/l10n/l10n_util_mac.h"
     28 #include "ui/base/resource/resource_bundle.h"
     29 
     30 void DidEndMainMessageLoop() {
     31   AppController* appController = [NSApp delegate];
     32   [appController didEndMainMessageLoop];
     33 }
     34 
     35 void RecordBreakpadStatusUMA(MetricsService* metrics) {
     36   metrics->RecordBreakpadRegistration(IsCrashReporterEnabled());
     37   metrics->RecordBreakpadHasDebugger(base::debug::BeingDebugged());
     38 }
     39 
     40 void RecordBrowserStartupTime() {
     41   // Not implemented on Mac for now.
     42 }
     43 
     44 void WarnAboutMinimumSystemRequirements() {
     45   // Nothing to check for on Mac right now.
     46 }
     47 
     48 // From browser_main_win.h, stubs until we figure out the right thing...
     49 
     50 int DoUninstallTasks(bool chrome_still_running) {
     51   return ResultCodes::NORMAL_EXIT;
     52 }
     53 
     54 int HandleIconsCommands(const CommandLine& parsed_command_line) {
     55   return 0;
     56 }
     57 
     58 bool CheckMachineLevelInstall() {
     59   return false;
     60 }
     61 
     62 void PrepareRestartOnCrashEnviroment(const CommandLine& parsed_command_line) {
     63 }
     64 
     65 // BrowserMainPartsMac ---------------------------------------------------------
     66 
     67 class BrowserMainPartsMac : public BrowserMainPartsPosix {
     68  public:
     69   explicit BrowserMainPartsMac(const MainFunctionParams& parameters)
     70       : BrowserMainPartsPosix(parameters) {}
     71 
     72  protected:
     73   virtual void PreEarlyInitialization() {
     74     BrowserMainPartsPosix::PreEarlyInitialization();
     75 
     76     if (base::mac::WasLaunchedAsHiddenLoginItem()) {
     77       CommandLine* singleton_command_line = CommandLine::ForCurrentProcess();
     78       singleton_command_line->AppendSwitch(switches::kNoStartupWindow);
     79     }
     80   }
     81 
     82   virtual void PreMainMessageLoopStart() {
     83     BrowserMainPartsPosix::PreMainMessageLoopStart();
     84 
     85     // Tell Cooca to finish its initalization, which we want to do manually
     86     // instead of calling NSApplicationMain(). The primary reason is that NSAM()
     87     // never returns, which would leave all the objects currently on the stack
     88     // in scoped_ptrs hanging and never cleaned up. We then load the main nib
     89     // directly. The main event loop is run from common code using the
     90     // MessageLoop API, which works out ok for us because it's a wrapper around
     91     // CFRunLoop.
     92 
     93     // Initialize NSApplication using the custom subclass.
     94     [BrowserCrApplication sharedApplication];
     95 
     96     // If ui_task is not NULL, the app is actually a browser_test, so startup is
     97     // handled outside of BrowserMain (which is what called this).
     98     if (!parameters().ui_task) {
     99       // The browser process only wants to support the language Cocoa will use,
    100       // so force the app locale to be overriden with that value.
    101       l10n_util::OverrideLocaleWithCocoaLocale();
    102 
    103       // Before we load the nib, we need to start up the resource bundle so we
    104       // have the strings avaiable for localization.
    105       // TODO(markusheintz): Read preference pref::kApplicationLocale in order
    106       // to enforce the application locale.
    107       const std::string loaded_locale =
    108           ResourceBundle::InitSharedInstance(std::string());
    109       CHECK(!loaded_locale.empty()) << "Default locale could not be found";
    110 
    111       FilePath resources_pack_path;
    112       PathService::Get(chrome::FILE_RESOURCES_PACK, &resources_pack_path);
    113       ResourceBundle::AddDataPackToSharedInstance(resources_pack_path);
    114     }
    115 
    116     // Now load the nib (from the right bundle).
    117     scoped_nsobject<NSNib>
    118         nib([[NSNib alloc] initWithNibNamed:@"MainMenu"
    119                                      bundle:base::mac::MainAppBundle()]);
    120     // TODO(viettrungluu): crbug.com/20504 - This currently leaks, so if you
    121     // change this, you'll probably need to change the Valgrind suppression.
    122     [nib instantiateNibWithOwner:NSApp topLevelObjects:nil];
    123     // Make sure the app controller has been created.
    124     DCHECK([NSApp delegate]);
    125 
    126     // This is a no-op if the KeystoneRegistration framework is not present.
    127     // The framework is only distributed with branded Google Chrome builds.
    128     [[KeystoneGlue defaultKeystoneGlue] registerWithKeystone];
    129 
    130     // Prevent Cocoa from turning command-line arguments into
    131     // |-application:openFiles:|, since we already handle them directly.
    132     [[NSUserDefaults standardUserDefaults]
    133         setObject:@"NO" forKey:@"NSTreatUnknownArgumentsAsOpen"];
    134   }
    135 
    136  private:
    137   virtual void InitializeSSL() {
    138     // Use NSS for SSL by default.
    139     // The default client socket factory uses NSS for SSL by default on Mac.
    140     if (parsed_command_line().HasSwitch(switches::kUseSystemSSL)) {
    141       net::ClientSocketFactory::UseSystemSSL();
    142     } else {
    143       // We want to be sure to init NSPR on the main thread.
    144       crypto::EnsureNSPRInit();
    145     }
    146   }
    147 };
    148 
    149 // static
    150 BrowserMainParts* BrowserMainParts::CreateBrowserMainParts(
    151     const MainFunctionParams& parameters) {
    152   return new BrowserMainPartsMac(parameters);
    153 }
    154