|  | // 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( | 
|  | const content::MainFunctionParams& parameters, | 
|  | StartupData* startup_data) | 
|  | : ChromeBrowserMainPartsPosix(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::PreMainMessageLoopStart() { | 
|  | MacStartupProfiler::GetInstance()->Profile( | 
|  | MacStartupProfiler::PRE_MAIN_MESSAGE_LOOP_START); | 
|  | ChromeBrowserMainPartsPosix::PreMainMessageLoopStart(); | 
|  |  | 
|  | // 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::PostMainMessageLoopStart() { | 
|  | MacStartupProfiler::GetInstance()->Profile( | 
|  | MacStartupProfiler::POST_MAIN_MESSAGE_LOOP_START); | 
|  | ChromeBrowserMainPartsPosix::PostMainMessageLoopStart(); | 
|  |  | 
|  | 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() { | 
|  | MacStartupProfiler::GetInstance()->Profile( | 
|  | MacStartupProfiler::POST_PROFILE_INIT); | 
|  | ChromeBrowserMainPartsPosix::PostProfileInit(); | 
|  |  | 
|  | // 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]; | 
|  | } |