[M120 Migration]Fix for crash during chrome exit
[platform/framework/web/chromium-efl.git] / chrome / browser / chrome_browser_main_mac.mm
1 // Copyright 2012 The Chromium Authors
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/chrome_browser_main_mac.h"
6
7 #import <Cocoa/Cocoa.h>
8
9 #include "base/apple/bundle_locations.h"
10 #import "base/apple/foundation_util.h"
11 #include "base/check_op.h"
12 #include "base/command_line.h"
13 #include "base/feature_list.h"
14 #include "base/functional/bind.h"
15 #include "base/mac/mac_util.h"
16 #include "base/metrics/histogram_functions.h"
17 #include "base/path_service.h"
18 #include "base/strings/sys_string_conversions.h"
19 #include "build/branding_buildflags.h"
20 #import "chrome/browser/app_controller_mac.h"
21 #include "chrome/browser/apps/app_shim/app_shim_listener.h"
22 #include "chrome/browser/browser_process.h"
23 #include "chrome/browser/browser_process_platform_part.h"
24 #include "chrome/browser/buildflags.h"
25 #import "chrome/browser/chrome_browser_application_mac.h"
26 #include "chrome/browser/first_run/first_run.h"
27 #include "chrome/browser/mac/install_from_dmg.h"
28 #import "chrome/browser/mac/keystone_glue.h"
29 #include "chrome/browser/mac/mac_startup_profiler.h"
30 #include "chrome/browser/ui/cocoa/main_menu_builder.h"
31 #include "chrome/browser/updater/browser_updater_client_util.h"
32 #include "chrome/browser/updater/scheduler.h"
33 #include "chrome/common/channel_info.h"
34 #include "chrome/common/chrome_features.h"
35 #include "chrome/common/chrome_paths.h"
36 #include "chrome/common/chrome_switches.h"
37 #include "chrome/common/pref_names.h"
38 #include "chrome/grit/branded_strings.h"
39 #include "components/metrics/metrics_service.h"
40 #include "components/os_crypt/sync/os_crypt.h"
41 #include "components/version_info/channel.h"
42 #include "content/public/common/main_function_params.h"
43 #include "content/public/common/result_codes.h"
44 #include "net/cert/internal/system_trust_store.h"
45 #include "services/network/public/cpp/features.h"
46 #include "ui/base/cocoa/permissions_utils.h"
47 #include "ui/base/l10n/l10n_util.h"
48 #include "ui/base/resource/resource_bundle.h"
49 #include "ui/base/resource/resource_handle.h"
50 #include "ui/native_theme/native_theme_mac.h"
51
52 // ChromeBrowserMainPartsMac ---------------------------------------------------
53
54 ChromeBrowserMainPartsMac::ChromeBrowserMainPartsMac(bool is_integration_test,
55                                                      StartupData* startup_data)
56     : ChromeBrowserMainPartsPosix(is_integration_test, startup_data) {}
57
58 ChromeBrowserMainPartsMac::~ChromeBrowserMainPartsMac() = default;
59
60 int ChromeBrowserMainPartsMac::PreEarlyInitialization() {
61   if (base::mac::WasLaunchedAsLoginItemRestoreState()) {
62     base::CommandLine* singleton_command_line =
63         base::CommandLine::ForCurrentProcess();
64     singleton_command_line->AppendSwitch(switches::kRestoreLastSession);
65   } else if (base::mac::WasLaunchedAsHiddenLoginItem()) {
66     base::CommandLine* singleton_command_line =
67         base::CommandLine::ForCurrentProcess();
68     singleton_command_line->AppendSwitch(switches::kNoStartupWindow);
69   }
70   return ChromeBrowserMainPartsPosix::PreEarlyInitialization();
71 }
72
73 void ChromeBrowserMainPartsMac::PreCreateMainMessageLoop() {
74   MacStartupProfiler::GetInstance()->Profile(
75       MacStartupProfiler::PRE_MAIN_MESSAGE_LOOP_START);
76   ChromeBrowserMainPartsPosix::PreCreateMainMessageLoop();
77
78   // ChromeBrowserMainParts should have loaded the resource bundle by this
79   // point (needed to load the nib).
80   CHECK(ui::ResourceBundle::HasSharedInstance());
81
82 #if BUILDFLAG(ENABLE_UPDATER)
83   if (base::FeatureList::IsEnabled(features::kUseChromiumUpdater)) {
84     EnsureUpdater(base::DoNothing(), base::DoNothing());
85   } else {
86     // This is a no-op if the KeystoneRegistration framework is not present.
87     // The framework is only distributed with branded Google Chrome builds.
88     [[KeystoneGlue defaultKeystoneGlue] registerWithKeystone];
89   }
90   updater::SchedulePeriodicTasks();
91 #endif  // BUILDFLAG(ENABLE_UPDATER)
92
93 #if !BUILDFLAG(CHROME_FOR_TESTING)
94   // Disk image installation is sort of a first-run task, so it shares the
95   // no first run switches.
96   //
97   // This needs to be done after the resource bundle is initialized (for
98   // access to localizations in the UI) and after Keystone is initialized
99   // (because the installation may need to promote Keystone) but before the
100   // app controller is set up (and thus before MainMenu.nib is loaded, because
101   // the app controller assumes that a browser has been set up and will crash
102   // upon receipt of certain notifications if no browser exists), before
103   // anyone tries doing anything silly like firing off an import job, and
104   // before anything creating preferences like Local State in order for the
105   // relaunched installed application to still consider itself as first-run.
106   if (!first_run::IsFirstRunSuppressed(
107           *base::CommandLine::ForCurrentProcess())) {
108     if (MaybeInstallFromDiskImage()) {
109       // The application was installed and the installed copy has been
110       // launched.  This process is now obsolete.  Exit.
111       exit(0);
112     }
113   }
114 #endif  // !BUILDFLAG(CHROME_FOR_TESTING)
115
116   // Create the app delegate by requesting the shared AppController.
117   CHECK_EQ(nil, NSApp.delegate);
118   AppController* app_controller = AppController.sharedController;
119   CHECK_NE(nil, NSApp.delegate);
120
121   chrome::BuildMainMenu(NSApp, app_controller,
122                         l10n_util::GetStringUTF16(IDS_PRODUCT_NAME), false);
123   [app_controller mainMenuCreated];
124
125   ui::WarmScreenCapture();
126
127   PrefService* local_state = g_browser_process->local_state();
128   DCHECK(local_state);
129
130   // AppKit only restores windows to their original spaces when relaunching
131   // apps after a restart, and puts them all on the current space when an app
132   // is manually quit and relaunched. If Chrome restarted itself, ask AppKit to
133   // treat this launch like a system restart and restore everything.
134   if (local_state->GetBoolean(prefs::kWasRestarted)) {
135     [NSUserDefaults.standardUserDefaults registerDefaults:@{
136       @"NSWindowRestoresWorkspaceAtLaunch" : @YES
137     }];
138   }
139 }
140
141 void ChromeBrowserMainPartsMac::PostCreateMainMessageLoop() {
142   MacStartupProfiler::GetInstance()->Profile(
143       MacStartupProfiler::POST_MAIN_MESSAGE_LOOP_START);
144   ChromeBrowserMainPartsPosix::PostCreateMainMessageLoop();
145
146   net::InitializeTrustStoreMacCache();
147 }
148
149 void ChromeBrowserMainPartsMac::PreProfileInit() {
150   MacStartupProfiler::GetInstance()->Profile(
151       MacStartupProfiler::PRE_PROFILE_INIT);
152   ChromeBrowserMainPartsPosix::PreProfileInit();
153
154   // This is called here so that the app shim socket is only created after
155   // taking the singleton lock.
156   g_browser_process->platform_part()->app_shim_listener()->Init();
157 }
158
159 void ChromeBrowserMainPartsMac::PostProfileInit(Profile* profile,
160                                                 bool is_initial_profile) {
161   if (is_initial_profile) {
162     MacStartupProfiler::GetInstance()->Profile(
163         MacStartupProfiler::POST_PROFILE_INIT);
164   }
165
166   ChromeBrowserMainPartsPosix::PostProfileInit(profile, is_initial_profile);
167
168   if (!is_initial_profile)
169     return;
170
171   // Activation of Keystone is not automatic but done in response to the
172   // counting and reporting of profiles.
173   KeystoneGlue* glue = [KeystoneGlue defaultKeystoneGlue];
174   if (glue && ![glue isRegisteredAndActive]) {
175     // If profile loading has failed, we still need to handle other tasks
176     // like marking of the product as active.
177     [glue setRegistrationActive];
178   }
179 }
180
181 void ChromeBrowserMainPartsMac::DidEndMainMessageLoop() {
182   [AppController.sharedController didEndMainMessageLoop];
183 }