browser_main_mac.mm revision dc0f95d653279beabeb9817299e2902918ba123e
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 "base/command_line.h"
11#include "base/debug/debugger.h"
12#include "base/file_path.h"
13#include "base/mac/mac_util.h"
14#include "base/nss_util.h"
15#include "base/path_service.h"
16#include "base/scoped_nsobject.h"
17#include "chrome/app/breakpad_mac.h"
18#import "chrome/browser/app_controller_mac.h"
19#include "chrome/browser/browser_main_win.h"
20#import "chrome/browser/chrome_browser_application_mac.h"
21#import "chrome/browser/cocoa/keystone_glue.h"
22#include "chrome/browser/metrics/metrics_service.h"
23#include "chrome/common/chrome_paths.h"
24#include "chrome/common/chrome_switches.h"
25#include "chrome/common/main_function_params.h"
26#include "chrome/common/result_codes.h"
27#include "net/socket/client_socket_factory.h"
28#include "ui/base/l10n/l10n_util_mac.h"
29#include "ui/base/resource/resource_bundle.h"
30
31void DidEndMainMessageLoop() {
32  AppController* appController = [NSApp delegate];
33  [appController didEndMainMessageLoop];
34}
35
36void RecordBreakpadStatusUMA(MetricsService* metrics) {
37  metrics->RecordBreakpadRegistration(IsCrashReporterEnabled());
38  metrics->RecordBreakpadHasDebugger(base::debug::BeingDebugged());
39}
40
41void WarnAboutMinimumSystemRequirements() {
42  // Nothing to check for on Mac right now.
43}
44
45// From browser_main_win.h, stubs until we figure out the right thing...
46
47int DoUninstallTasks(bool chrome_still_running) {
48  return ResultCodes::NORMAL_EXIT;
49}
50
51int HandleIconsCommands(const CommandLine& parsed_command_line) {
52  return 0;
53}
54
55bool CheckMachineLevelInstall() {
56  return false;
57}
58
59void PrepareRestartOnCrashEnviroment(const CommandLine& parsed_command_line) {
60}
61
62// BrowserMainPartsMac ---------------------------------------------------------
63
64class BrowserMainPartsMac : public BrowserMainPartsPosix {
65 public:
66  explicit BrowserMainPartsMac(const MainFunctionParams& parameters)
67      : BrowserMainPartsPosix(parameters) {}
68
69 protected:
70  virtual void PreEarlyInitialization() {
71    BrowserMainPartsPosix::PreEarlyInitialization();
72
73    if (base::mac::WasLaunchedAsHiddenLoginItem()) {
74      CommandLine* singleton_command_line = CommandLine::ForCurrentProcess();
75      singleton_command_line->AppendSwitch(switches::kNoStartupWindow);
76    }
77  }
78
79  virtual void PreMainMessageLoopStart() {
80    BrowserMainPartsPosix::PreMainMessageLoopStart();
81
82    // Tell Cooca to finish its initalization, which we want to do manually
83    // instead of calling NSApplicationMain(). The primary reason is that NSAM()
84    // never returns, which would leave all the objects currently on the stack
85    // in scoped_ptrs hanging and never cleaned up. We then load the main nib
86    // directly. The main event loop is run from common code using the
87    // MessageLoop API, which works out ok for us because it's a wrapper around
88    // CFRunLoop.
89
90    // Initialize NSApplication using the custom subclass.
91    [BrowserCrApplication sharedApplication];
92
93    // If ui_task is not NULL, the app is actually a browser_test, so startup is
94    // handled outside of BrowserMain (which is what called this).
95    if (!parameters().ui_task) {
96      // The browser process only wants to support the language Cocoa will use,
97      // so force the app locale to be overriden with that value.
98      l10n_util::OverrideLocaleWithCocoaLocale();
99
100      // Before we load the nib, we need to start up the resource bundle so we
101      // have the strings avaiable for localization.
102      // TODO(markusheintz): Read preference pref::kApplicationLocale in order
103      // to enforce the application locale.
104      const std::string loaded_locale =
105          ResourceBundle::InitSharedInstance(std::string());
106      CHECK(!loaded_locale.empty()) << "Default locale could not be found";
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:base::mac::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::UseSystemSSL();
139    } else {
140      // We want to be sure to init NSPR on the main thread.
141      base::EnsureNSPRInit();
142    }
143  }
144};
145
146// static
147BrowserMainParts* BrowserMainParts::CreateBrowserMainParts(
148    const MainFunctionParams& parameters) {
149  return new BrowserMainPartsMac(parameters);
150}
151