[M120 Migration]Fix for crash during chrome exit
[platform/framework/web/chromium-efl.git] / chrome / browser / browser_process_platform_part_chromeos.cc
1 // Copyright 2022 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/browser_process_platform_part_chromeos.h"
6
7 #include "chrome/browser/custom_handlers/protocol_handler_registry_factory.h"
8 #include "chrome/browser/prefs/session_startup_pref.h"
9 #include "chrome/browser/profiles/profile.h"
10 #include "chrome/browser/profiles/profile_io_data.h"
11 #include "chrome/browser/sessions/session_restore.h"
12 #include "chrome/browser/sessions/session_service_utils.h"
13 #include "chrome/browser/ui/browser.h"
14 #include "chrome/browser/ui/browser_finder.h"
15 #include "chrome/browser/ui/browser_list.h"
16 #include "chrome/browser/ui/browser_navigator.h"
17 #include "chrome/browser/ui/browser_navigator_params.h"
18 #include "chrome/browser/ui/browser_window.h"
19 #include "chrome/browser/ui/startup/startup_browser_creator.h"
20 #include "chrome/browser/ui/tabs/tab_strip_model.h"
21 #include "components/custom_handlers/protocol_handler_registry.h"
22 #include "ui/base/page_transition_types.h"
23 #include "ui/base/window_open_disposition.h"
24
25 BrowserProcessPlatformPartChromeOS::BrowserProcessPlatformPartChromeOS()
26     : browser_restore_observer_(this) {}
27
28 BrowserProcessPlatformPartChromeOS::~BrowserProcessPlatformPartChromeOS() =
29     default;
30
31 bool BrowserProcessPlatformPartChromeOS::CanRestoreUrlsForProfile(
32     const Profile* profile) const {
33   return profile->IsRegularProfile();
34 }
35
36 BrowserProcessPlatformPartChromeOS::BrowserRestoreObserver::
37     BrowserRestoreObserver(
38         const BrowserProcessPlatformPartChromeOS* browser_process_platform_part)
39     : browser_process_platform_part_(browser_process_platform_part) {
40   BrowserList::AddObserver(this);
41 }
42
43 BrowserProcessPlatformPartChromeOS::BrowserRestoreObserver::
44     ~BrowserRestoreObserver() {
45   BrowserList::RemoveObserver(this);
46 }
47
48 void BrowserProcessPlatformPartChromeOS::BrowserRestoreObserver::OnBrowserAdded(
49     Browser* browser) {
50   // If |browser| is the only browser, restores urls based on the on startup
51   // setting.
52   if (chrome::GetBrowserCount(browser->profile()) == 1 &&
53       ShouldRestoreUrls(browser)) {
54     if (ShouldOpenUrlsInNewBrowser(browser)) {
55       // Delay creating a new browser until |browser| is activated.
56       on_session_restored_callback_subscription_ =
57           SessionRestore::RegisterOnSessionRestoredCallback(base::BindRepeating(
58               &BrowserProcessPlatformPartChromeOS::BrowserRestoreObserver::
59                   OnSessionRestoreDone,
60               base::Unretained(this)));
61     } else {
62       RestoreUrls(browser);
63     }
64   }
65
66   // If the startup urls from LAST_AND_URLS pref are already opened in a new
67   // browser, skip opening the same browser.
68   if (browser->creation_source() ==
69       Browser::CreationSource::kLastAndUrlsStartupPref) {
70     DCHECK(on_session_restored_callback_subscription_);
71     on_session_restored_callback_subscription_ = {};
72   }
73 }
74
75 void BrowserProcessPlatformPartChromeOS::BrowserRestoreObserver::
76     OnSessionRestoreDone(Profile* profile, int num_tabs_restored) {
77   // Ensure this callback to be called exactly once.
78   on_session_restored_callback_subscription_ = {};
79
80   // All browser windows are created. Open startup urls in a new browser.
81   auto create_params = Browser::CreateParams(profile, /*user_gesture*/ false);
82   Browser* browser = Browser::Create(create_params);
83   RestoreUrls(browser);
84   browser->window()->Show();
85   browser->window()->Activate();
86 }
87
88 bool BrowserProcessPlatformPartChromeOS::BrowserRestoreObserver::
89     ShouldRestoreUrls(Browser* browser) const {
90   Profile* profile = browser->profile();
91
92   // Only open urls for regular sign in users.
93   DCHECK(profile);
94   if (!browser_process_platform_part_->CanRestoreUrlsForProfile(profile))
95     return false;
96
97   // If during the restore process, or restore from a crash, don't launch urls.
98   // However, in case of LAST_AND_URLS startup setting, urls should be opened
99   // even when the restore session is in progress.
100   SessionStartupPref pref =
101       SessionStartupPref::GetStartupPref(browser->profile()->GetPrefs());
102   if ((SessionRestore::IsRestoring(profile) &&
103        pref.type != SessionStartupPref::LAST_AND_URLS) ||
104       HasPendingUncleanExit(profile)) {
105     return false;
106   }
107
108   // App windows should not be restored.
109   auto window_type = WindowTypeForBrowserType(browser->type());
110   if (window_type == sessions::SessionWindow::TYPE_APP ||
111       window_type == sessions::SessionWindow::TYPE_APP_POPUP) {
112     return false;
113   }
114
115   // If the browser is created by StartupBrowserCreator,
116   // StartupBrowserCreatorImpl::OpenTabsInBrowser can open tabs, so don't
117   // restore urls here.
118   if (browser->creation_source() == Browser::CreationSource::kStartupCreator)
119     return false;
120
121   // If the startup setting is not open urls, don't launch urls.
122   if (!pref.ShouldOpenUrls() || pref.urls.empty())
123     return false;
124
125   return true;
126 }
127
128 // If the startup setting is both the restore last session and the open urls,
129 // those should be opened in a new browser.
130 bool BrowserProcessPlatformPartChromeOS::BrowserRestoreObserver::
131     ShouldOpenUrlsInNewBrowser(Browser* browser) const {
132   SessionStartupPref pref =
133       SessionStartupPref::GetStartupPref(browser->profile()->GetPrefs());
134   return pref.type == SessionStartupPref::LAST_AND_URLS;
135 }
136
137 void BrowserProcessPlatformPartChromeOS::BrowserRestoreObserver::RestoreUrls(
138     Browser* browser) {
139   DCHECK(browser);
140
141   SessionStartupPref pref =
142       SessionStartupPref::GetStartupPref(browser->profile()->GetPrefs());
143   std::vector<GURL> urls;
144   for (const auto& url : pref.urls)
145     urls.push_back(url);
146
147   custom_handlers::ProtocolHandlerRegistry* registry =
148       ProtocolHandlerRegistryFactory::GetForBrowserContext(browser->profile());
149   for (const GURL& url : urls) {
150     // We skip URLs that we'd have to launch an external protocol handler for.
151     // This avoids us getting into an infinite loop asking ourselves to open
152     // a URL, should the handler be (incorrectly) configured to be us. Anyone
153     // asking us to open such a URL should really ask the handler directly.
154     bool handled_by_chrome =
155         ProfileIOData::IsHandledURL(url) ||
156         (registry && registry->IsHandledProtocol(url.scheme()));
157     if (!handled_by_chrome)
158       continue;
159
160     int add_types = AddTabTypes::ADD_NONE | AddTabTypes::ADD_FORCE_INDEX;
161     NavigateParams params(browser, url, ui::PAGE_TRANSITION_AUTO_TOPLEVEL);
162     params.disposition = WindowOpenDisposition::NEW_BACKGROUND_TAB;
163     params.tabstrip_add_types = add_types;
164     Navigate(&params);
165   }
166 }