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