| // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "chrome/browser/chrome_browser_main_mac.h" |
| |
| #import <Cocoa/Cocoa.h> |
| |
| #include "base/bind.h" |
| #include "base/command_line.h" |
| #include "base/mac/bundle_locations.h" |
| #import "base/mac/foundation_util.h" |
| #include "base/mac/mac_util.h" |
| #include "base/mac/scoped_nsobject.h" |
| #include "base/metrics/histogram_functions.h" |
| #include "base/path_service.h" |
| #include "base/strings/sys_string_conversions.h" |
| #include "build/branding_buildflags.h" |
| #import "chrome/browser/app_controller_mac.h" |
| #include "chrome/browser/apps/app_shim/app_shim_listener.h" |
| #include "chrome/browser/browser_process.h" |
| #include "chrome/browser/browser_process_platform_part.h" |
| #include "chrome/browser/buildflags.h" |
| #import "chrome/browser/chrome_browser_application_mac.h" |
| #include "chrome/browser/first_run/first_run.h" |
| #include "chrome/browser/mac/install_from_dmg.h" |
| #import "chrome/browser/mac/keystone_glue.h" |
| #include "chrome/browser/mac/mac_startup_profiler.h" |
| #include "chrome/browser/ui/cocoa/main_menu_builder.h" |
| #include "chrome/common/channel_info.h" |
| #include "chrome/common/chrome_paths.h" |
| #include "chrome/common/chrome_switches.h" |
| #include "chrome/common/pref_names.h" |
| #include "chrome/grit/chromium_strings.h" |
| #include "components/metrics/metrics_service.h" |
| #include "components/os_crypt/os_crypt.h" |
| #include "components/version_info/channel.h" |
| #include "content/public/common/main_function_params.h" |
| #include "content/public/common/result_codes.h" |
| #include "net/base/features.h" |
| #include "net/cert/internal/system_trust_store.h" |
| #include "services/network/public/cpp/features.h" |
| #include "ui/base/l10n/l10n_util.h" |
| #include "ui/base/resource/resource_bundle.h" |
| #include "ui/base/resource/resource_handle.h" |
| #include "ui/native_theme/native_theme_mac.h" |
| |
| #if BUILDFLAG(ENABLE_CHROMIUM_UPDATER) |
| #include "chrome/browser/mac/install_updater.h" |
| #endif // BUILDFLAG(ENABLE_CHROMIUM_UPDATER) |
| |
| // ChromeBrowserMainPartsMac --------------------------------------------------- |
| |
| ChromeBrowserMainPartsMac::ChromeBrowserMainPartsMac( |
| content::MainFunctionParams parameters, |
| StartupData* startup_data) |
| : ChromeBrowserMainPartsPosix(std::move(parameters), startup_data) {} |
| |
| ChromeBrowserMainPartsMac::~ChromeBrowserMainPartsMac() { |
| } |
| |
| int ChromeBrowserMainPartsMac::PreEarlyInitialization() { |
| if (base::mac::WasLaunchedAsLoginItemRestoreState()) { |
| base::CommandLine* singleton_command_line = |
| base::CommandLine::ForCurrentProcess(); |
| singleton_command_line->AppendSwitch(switches::kRestoreLastSession); |
| } else if (base::mac::WasLaunchedAsHiddenLoginItem()) { |
| base::CommandLine* singleton_command_line = |
| base::CommandLine::ForCurrentProcess(); |
| singleton_command_line->AppendSwitch(switches::kNoStartupWindow); |
| } |
| |
| return ChromeBrowserMainPartsPosix::PreEarlyInitialization(); |
| } |
| |
| void ChromeBrowserMainPartsMac::PreCreateMainMessageLoop() { |
| MacStartupProfiler::GetInstance()->Profile( |
| MacStartupProfiler::PRE_MAIN_MESSAGE_LOOP_START); |
| ChromeBrowserMainPartsPosix::PreCreateMainMessageLoop(); |
| |
| // ChromeBrowserMainParts should have loaded the resource bundle by this |
| // point (needed to load the nib). |
| CHECK(ui::ResourceBundle::HasSharedInstance()); |
| |
| #if BUILDFLAG(ENABLE_CHROMIUM_UPDATER) |
| InstallUpdaterAndRegisterBrowser(); |
| #else |
| // This is a no-op if the KeystoneRegistration framework is not present. |
| // The framework is only distributed with branded Google Chrome builds. |
| [[KeystoneGlue defaultKeystoneGlue] registerWithKeystone]; |
| #endif // BUILDFLAG(ENABLE_CHROMIUM_UPDATER) |
| |
| // Disk image installation is sort of a first-run task, so it shares the |
| // no first run switches. |
| // |
| // This needs to be done after the resource bundle is initialized (for |
| // access to localizations in the UI) and after Keystone is initialized |
| // (because the installation may need to promote Keystone) but before the |
| // app controller is set up (and thus before MainMenu.nib is loaded, because |
| // the app controller assumes that a browser has been set up and will crash |
| // upon receipt of certain notifications if no browser exists), before |
| // anyone tries doing anything silly like firing off an import job, and |
| // before anything creating preferences like Local State in order for the |
| // relaunched installed application to still consider itself as first-run. |
| if (!first_run::IsFirstRunSuppressed(parsed_command_line())) { |
| if (MaybeInstallFromDiskImage()) { |
| // The application was installed and the installed copy has been |
| // launched. This process is now obsolete. Exit. |
| exit(0); |
| } |
| } |
| |
| // Create the app delegate. This object is intentionally leaked as a global |
| // singleton. It is accessed through -[NSApp delegate]. |
| AppController* app_controller = [[AppController alloc] init]; |
| [NSApp setDelegate:app_controller]; |
| |
| chrome::BuildMainMenu(NSApp, app_controller, |
| l10n_util::GetStringUTF16(IDS_PRODUCT_NAME), false); |
| [app_controller mainMenuCreated]; |
| |
| PrefService* local_state = g_browser_process->local_state(); |
| DCHECK(local_state); |
| |
| // AppKit only restores windows to their original spaces when relaunching |
| // apps after a restart, and puts them all on the current space when an app |
| // is manually quit and relaunched. If Chrome restarted itself, ask AppKit to |
| // treat this launch like a system restart and restore everything. |
| if (local_state->GetBoolean(prefs::kWasRestarted)) { |
| [NSUserDefaults.standardUserDefaults registerDefaults:@{ |
| @"NSWindowRestoresWorkspaceAtLaunch" : @YES |
| }]; |
| } |
| } |
| |
| void ChromeBrowserMainPartsMac::PostCreateMainMessageLoop() { |
| MacStartupProfiler::GetInstance()->Profile( |
| MacStartupProfiler::POST_MAIN_MESSAGE_LOOP_START); |
| ChromeBrowserMainPartsPosix::PostCreateMainMessageLoop(); |
| |
| if (base::FeatureList::IsEnabled( |
| net::features::kCertVerifierBuiltinFeature)) { |
| net::InitializeTrustStoreMacCache(); |
| } |
| } |
| |
| void ChromeBrowserMainPartsMac::PreProfileInit() { |
| MacStartupProfiler::GetInstance()->Profile( |
| MacStartupProfiler::PRE_PROFILE_INIT); |
| ChromeBrowserMainPartsPosix::PreProfileInit(); |
| |
| // This is called here so that the app shim socket is only created after |
| // taking the singleton lock. |
| g_browser_process->platform_part()->app_shim_listener()->Init(); |
| } |
| |
| void ChromeBrowserMainPartsMac::PostProfileInit(Profile* profile, |
| bool is_initial_profile) { |
| if (is_initial_profile) { |
| MacStartupProfiler::GetInstance()->Profile( |
| MacStartupProfiler::POST_PROFILE_INIT); |
| } |
| |
| ChromeBrowserMainPartsPosix::PostProfileInit(profile, is_initial_profile); |
| |
| if (!is_initial_profile) |
| return; |
| |
| // Activation of Keystone is not automatic but done in response to the |
| // counting and reporting of profiles. |
| KeystoneGlue* glue = [KeystoneGlue defaultKeystoneGlue]; |
| if (glue && ![glue isRegisteredAndActive]) { |
| // If profile loading has failed, we still need to handle other tasks |
| // like marking of the product as active. |
| [glue setRegistrationActive]; |
| } |
| } |
| |
| void ChromeBrowserMainPartsMac::DidEndMainMessageLoop() { |
| AppController* appController = |
| base::mac::ObjCCastStrict<AppController>([NSApp delegate]); |
| [appController didEndMainMessageLoop]; |
| } |