blob: 689f151aaa1b23b3ccf1e06442bcb40103f971cd [file] [log] [blame]
[email protected]71c0eb92012-01-03 17:57:301// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]5c9587c2008-12-09 21:20:162// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
[email protected]e6b5bc22011-09-08 22:01:565#include "chrome/browser/chrome_browser_main_mac.h"
[email protected]1152b7e2009-09-14 03:26:036
[email protected]ce8c16ad2009-08-12 19:00:427#import <Cocoa/Cocoa.h>
[email protected]1152b7e2009-09-14 03:26:038
[email protected]5c9587c2008-12-09 21:20:169#include "base/command_line.h"
[email protected]57999812013-02-24 05:40:5210#include "base/files/file_path.h"
calamityc95d7822015-05-04 02:10:1611#include "base/files/file_util.h"
[email protected]2f1804c2012-01-19 14:59:0712#include "base/mac/bundle_locations.h"
tapted676995d2016-04-18 11:32:2913#import "base/mac/foundation_util.h"
[email protected]0378bf42011-01-01 18:20:1414#include "base/mac/mac_util.h"
[email protected]a8522032013-06-24 22:51:4615#include "base/mac/scoped_nsobject.h"
thakis17c246d12016-07-01 22:28:0916#include "base/mac/sdk_forward_declarations.h"
[email protected]e1cb0e92010-06-15 07:23:5917#include "base/path_service.h"
Gabriel Charette44db1422018-08-06 11:19:3318#include "base/task/post_task.h"
19#include "base/task/task_traits.h"
gabb15e19072016-05-11 20:45:4120#include "base/threading/thread_task_runner_handle.h"
[email protected]3b6aa8b62009-09-15 21:36:1121#import "chrome/browser/app_controller_mac.h"
tapted63829f72014-09-24 23:50:5022#include "chrome/browser/apps/app_shim/app_shim_host_manager_mac.h"
[email protected]e8b6ca02013-07-10 18:00:5123#include "chrome/browser/browser_process.h"
[email protected]aaa47ee2009-11-05 21:53:0124#import "chrome/browser/chrome_browser_application_mac.h"
Christopher Lam32c684522017-07-28 03:05:0225#include "chrome/browser/first_run/first_run.h"
[email protected]c4d501e2012-03-27 20:08:0226#include "chrome/browser/mac/install_from_dmg.h"
kerrnel26eeef02017-03-10 19:03:4327#include "chrome/browser/mac/keychain_reauthorize.h"
[email protected]5950f5712011-06-20 22:15:5228#import "chrome/browser/mac/keystone_glue.h"
[email protected]7d1aaa62014-07-18 02:21:3029#include "chrome/browser/mac/mac_startup_profiler.h"
Robert Sesek124f80f92018-07-24 20:31:2930#include "chrome/browser/ui/cocoa/main_menu_builder.h"
[email protected]e1cb0e92010-06-15 07:23:5931#include "chrome/common/chrome_paths.h"
[email protected]d7dbe28c2010-07-29 04:33:4732#include "chrome/common/chrome_switches.h"
scottmgcfa5b01b2015-11-30 23:13:4633#include "components/crash/content/app/crashpad.h"
[email protected]d6147bd2014-06-11 01:58:1934#include "components/metrics/metrics_service.h"
[email protected]4573fbd2011-10-31 20:25:1835#include "content/public/common/main_function_params.h"
[email protected]b39ef1cb2011-10-25 04:46:5536#include "content/public/common/result_codes.h"
[email protected]c051a1b2011-01-21 23:30:1737#include "ui/base/l10n/l10n_util_mac.h"
[email protected]42ce29d2011-01-20 23:19:4638#include "ui/base/resource/resource_bundle.h"
[email protected]63942f22012-05-01 06:11:5239#include "ui/base/resource/resource_handle.h"
[email protected]5c9587c2008-12-09 21:20:1640
calamityc95d7822015-05-04 02:10:1641namespace {
42
43// Writes an undocumented sentinel file that prevents Spotlight from indexing
44// below a particular path in order to reap some power savings.
45void EnsureMetadataNeverIndexFileOnFileThread(
46 const base::FilePath& user_data_dir) {
47 const char kMetadataNeverIndexFilename[] = ".metadata_never_index";
48 base::FilePath metadata_file_path =
49 user_data_dir.Append(kMetadataNeverIndexFilename);
50 if (base::PathExists(metadata_file_path))
51 return;
52
53 if (base::WriteFile(metadata_file_path, nullptr, 0) == -1)
54 DLOG(FATAL) << "Could not write .metadata_never_index file.";
55}
56
57void EnsureMetadataNeverIndexFile(const base::FilePath& user_data_dir) {
Christopher Lam32c684522017-07-28 03:05:0258 base::PostTaskWithTraits(
59 FROM_HERE,
Gabriel Charetteb10aeebc2018-07-26 20:15:0060 {base::MayBlock(), base::TaskPriority::BEST_EFFORT,
Christopher Lam32c684522017-07-28 03:05:0261 base::TaskShutdownBehavior::BLOCK_SHUTDOWN},
calamityc95d7822015-05-04 02:10:1662 base::Bind(&EnsureMetadataNeverIndexFileOnFileThread, user_data_dir));
63}
64
65} // namespace
66
[email protected]e6b5bc22011-09-08 22:01:5667// ChromeBrowserMainPartsMac ---------------------------------------------------
[email protected]1fec64352010-07-27 13:55:2168
[email protected]e6b5bc22011-09-08 22:01:5669ChromeBrowserMainPartsMac::ChromeBrowserMainPartsMac(
Ran Jia96d43d42018-05-02 17:14:5370 const content::MainFunctionParams& parameters,
71 std::unique_ptr<ui::DataPack> data_pack)
72 : ChromeBrowserMainPartsPosix(parameters, std::move(data_pack)) {}
[email protected]1fec64352010-07-27 13:55:2173
[email protected]39fc5d322012-09-15 10:54:5574ChromeBrowserMainPartsMac::~ChromeBrowserMainPartsMac() {
75}
76
Scott Violet9068b4df2018-01-12 16:44:2177int ChromeBrowserMainPartsMac::PreEarlyInitialization() {
[email protected]769ddfe2014-06-13 23:13:2078 if (base::mac::WasLaunchedAsLoginItemRestoreState()) {
avi3ef9ec9e2014-12-22 22:50:1779 base::CommandLine* singleton_command_line =
80 base::CommandLine::ForCurrentProcess();
[email protected]769ddfe2014-06-13 23:13:2081 singleton_command_line->AppendSwitch(switches::kRestoreLastSession);
82 } else if (base::mac::WasLaunchedAsHiddenLoginItem()) {
avi3ef9ec9e2014-12-22 22:50:1783 base::CommandLine* singleton_command_line =
84 base::CommandLine::ForCurrentProcess();
[email protected]f967b722011-09-07 00:58:0485 singleton_command_line->AppendSwitch(switches::kNoStartupWindow);
86 }
Scott Violet9068b4df2018-01-12 16:44:2187
[email protected]a88f6362014-03-18 04:25:3588 // If ui_task is not NULL, the app is actually a browser_test.
[email protected]716476c2011-12-29 00:07:0389 if (!parameters().ui_task) {
[email protected]f967b722011-09-07 00:58:0490 // The browser process only wants to support the language Cocoa will use,
Scott Violet740c2632018-03-09 04:11:4291 // so force the app locale to be overriden with that value. This must
92 // happen before the ResourceBundle is loaded, which happens in
93 // ChromeBrowserMainParts::PreEarlyInitialization().
[email protected]f967b722011-09-07 00:58:0494 l10n_util::OverrideLocaleWithCocoaLocale();
[email protected]91484af2010-08-27 17:55:5495 }
96
Scott Violet740c2632018-03-09 04:11:4297 return ChromeBrowserMainPartsPosix::PreEarlyInitialization();
Scott Violet875789e2018-02-02 07:46:4898}
[email protected]a88f6362014-03-18 04:25:3599
Scott Violet875789e2018-02-02 07:46:48100void ChromeBrowserMainPartsMac::PreMainMessageLoopStart() {
101 MacStartupProfiler::GetInstance()->Profile(
102 MacStartupProfiler::PRE_MAIN_MESSAGE_LOOP_START);
103 ChromeBrowserMainPartsPosix::PreMainMessageLoopStart();
104
105 // ChromeBrowserMainParts should have loaded the resource bundle by this
106 // point (needed to load the nib).
107 CHECK(ui::ResourceBundle::HasSharedInstance());
[email protected]a88f6362014-03-18 04:25:35108
[email protected]c4d501e2012-03-27 20:08:02109 // This is a no-op if the KeystoneRegistration framework is not present.
110 // The framework is only distributed with branded Google Chrome builds.
111 [[KeystoneGlue defaultKeystoneGlue] registerWithKeystone];
112
113 // Disk image installation is sort of a first-run task, so it shares the
[email protected]0a160a1b2013-08-08 22:20:00114 // no first run switches.
[email protected]c4d501e2012-03-27 20:08:02115 //
116 // This needs to be done after the resource bundle is initialized (for
117 // access to localizations in the UI) and after Keystone is initialized
118 // (because the installation may need to promote Keystone) but before the
119 // app controller is set up (and thus before MainMenu.nib is loaded, because
120 // the app controller assumes that a browser has been set up and will crash
121 // upon receipt of certain notifications if no browser exists), before
122 // anyone tries doing anything silly like firing off an import job, and
123 // before anything creating preferences like Local State in order for the
124 // relaunched installed application to still consider itself as first-run.
[email protected]0a160a1b2013-08-08 22:20:00125 if (!first_run::IsFirstRunSuppressed(parsed_command_line())) {
[email protected]c4d501e2012-03-27 20:08:02126 if (MaybeInstallFromDiskImage()) {
127 // The application was installed and the installed copy has been
128 // launched. This process is now obsolete. Exit.
129 exit(0);
130 }
131 }
132
Robert Sesek124f80f92018-07-24 20:31:29133 // Create the app delegate. This object is intentionally leaked as a global
134 // singleton. It is accessed through -[NSApp delegate].
135 AppController* app_controller = [[AppController alloc] init];
136 [NSApp setDelegate:app_controller];
137
138 chrome::BuildMainMenu(NSApp, app_controller);
139 [app_controller mainMenuCreated];
kerrnel26eeef02017-03-10 19:03:43140
141 // Do Keychain reauthorization. This gets two chances to run. If the first
142 // try doesn't complete successfully (crashes or is interrupted for any
143 // reason), there will be a second chance. Once this step completes
144 // successfully, it should never have to run again.
145 NSString* const keychain_reauthorize_pref =
146 @"KeychainReauthorizeInAppSpring2017";
147 const int kKeychainReauthorizeMaxTries = 2;
148
149 chrome::KeychainReauthorizeIfNeeded(keychain_reauthorize_pref,
150 kKeychainReauthorizeMaxTries);
[email protected]f967b722011-09-07 00:58:04151}
[email protected]03d8d3e92011-09-20 06:07:11152
[email protected]7d1aaa62014-07-18 02:21:30153void ChromeBrowserMainPartsMac::PostMainMessageLoopStart() {
154 MacStartupProfiler::GetInstance()->Profile(
155 MacStartupProfiler::POST_MAIN_MESSAGE_LOOP_START);
[email protected]6ddc10972014-07-29 07:53:33156 ChromeBrowserMainPartsPosix::PostMainMessageLoopStart();
[email protected]7d1aaa62014-07-18 02:21:30157}
158
[email protected]bdad6e62014-05-06 08:47:37159void ChromeBrowserMainPartsMac::PreProfileInit() {
[email protected]7d1aaa62014-07-18 02:21:30160 MacStartupProfiler::GetInstance()->Profile(
161 MacStartupProfiler::PRE_PROFILE_INIT);
[email protected]bdad6e62014-05-06 08:47:37162 ChromeBrowserMainPartsPosix::PreProfileInit();
mlermana312cec2015-01-28 21:13:33163
[email protected]bdad6e62014-05-06 08:47:37164 // This is called here so that the app shim socket is only created after
165 // taking the singleton lock.
166 g_browser_process->platform_part()->app_shim_host_manager()->Init();
[email protected]bdad6e62014-05-06 08:47:37167}
168
[email protected]e8b6ca02013-07-10 18:00:51169void ChromeBrowserMainPartsMac::PostProfileInit() {
[email protected]7d1aaa62014-07-18 02:21:30170 MacStartupProfiler::GetInstance()->Profile(
171 MacStartupProfiler::POST_PROFILE_INIT);
[email protected]e8b6ca02013-07-10 18:00:51172 ChromeBrowserMainPartsPosix::PostProfileInit();
markd413b2d2015-03-13 07:45:40173
[email protected]e8b6ca02013-07-10 18:00:51174 g_browser_process->metrics_service()->RecordBreakpadRegistration(
markd413b2d2015-03-13 07:45:40175 crash_reporter::GetUploadsEnabled());
calamityc95d7822015-05-04 02:10:16176
Christopher Lam32c684522017-07-28 03:05:02177 if (first_run::IsChromeFirstRun())
178 EnsureMetadataNeverIndexFile(user_data_dir());
bcwhitee9301292015-06-22 15:31:58179
borisv957d52d2016-04-13 18:35:43180 // Activation of Keystone is not automatic but done in response to the
181 // counting and reporting of profiles.
182 KeystoneGlue* glue = [KeystoneGlue defaultKeystoneGlue];
183 if (glue && ![glue isRegisteredAndActive]) {
184 // If profile loading has failed, we still need to handle other tasks
185 // like marking of the product as active.
186 [glue updateProfileCountsWithNumProfiles:0
187 numSignedInProfiles:0];
188 }
[email protected]e8b6ca02013-07-10 18:00:51189}
190
[email protected]03d8d3e92011-09-20 06:07:11191void ChromeBrowserMainPartsMac::DidEndMainMessageLoop() {
tapted676995d2016-04-18 11:32:29192 AppController* appController =
193 base::mac::ObjCCastStrict<AppController>([NSApp delegate]);
[email protected]03d8d3e92011-09-20 06:07:11194 [appController didEndMainMessageLoop];
195}