| Index: chrome/browser/chrome_browser_main.cc
|
| diff --git a/chrome/browser/chrome_browser_main.cc b/chrome/browser/chrome_browser_main.cc
|
| index fb5034032e2085bdb551bd929c5420f4eb78b692..a0aa6621d59ea3066e3c34766bfbe92a6499e4ba 100644
|
| --- a/chrome/browser/chrome_browser_main.cc
|
| +++ b/chrome/browser/chrome_browser_main.cc
|
| @@ -31,6 +31,7 @@
|
| #include "base/strings/string_split.h"
|
| #include "base/strings/sys_string_conversions.h"
|
| #include "base/strings/utf_string_conversions.h"
|
| +#include "base/synchronization/cancellation_flag.h"
|
| #include "base/sys_info.h"
|
| #include "base/threading/platform_thread.h"
|
| #include "base/time/time.h"
|
| @@ -85,10 +86,12 @@
|
| #include "chrome/browser/ui/app_list/app_list_service.h"
|
| #include "chrome/browser/ui/browser.h"
|
| #include "chrome/browser/ui/browser_finder.h"
|
| +#include "chrome/browser/ui/browser_iterator.h"
|
| #include "chrome/browser/ui/host_desktop.h"
|
| #include "chrome/browser/ui/startup/bad_flags_prompt.h"
|
| #include "chrome/browser/ui/startup/default_browser_prompt.h"
|
| #include "chrome/browser/ui/startup/startup_browser_creator.h"
|
| +#include "chrome/browser/ui/tabs/tab_strip_model.h"
|
| #include "chrome/browser/ui/uma_browsing_activity_observer.h"
|
| #include "chrome/browser/ui/webui/chrome_web_ui_controller_factory.h"
|
| #include "chrome/common/chrome_constants.h"
|
| @@ -124,6 +127,7 @@
|
| #include "content/public/browser/notification_service.h"
|
| #include "content/public/browser/notification_types.h"
|
| #include "content/public/browser/power_usage_monitor.h"
|
| +#include "content/public/browser/render_frame_host.h"
|
| #include "content/public/browser/site_instance.h"
|
| #include "content/public/common/content_client.h"
|
| #include "content/public/common/content_switches.h"
|
| @@ -221,9 +225,85 @@
|
| #endif // defined(USE_AURA)
|
|
|
| using content::BrowserThread;
|
| +using content::WebContents;
|
| +using content::WebContentsObserver;
|
|
|
| namespace {
|
|
|
| +// The basis for when tasks posted via PostAfterStartupTasks begin running.
|
| +using StartupCompleteFlag = base::CancellationFlag;
|
| +base::LazyInstance<StartupCompleteFlag>::Leaky g_startup_complete_flag;
|
| +
|
| +void SetBrowserStartupIsComplete() {
|
| + g_startup_complete_flag.Get().Set();
|
| +}
|
| +
|
| +// Observes the first page load and set the startup complete flag accordingly.
|
| +class StartupObserver : public WebContentsObserver {
|
| + public:
|
| + StartupObserver() : weak_factory_(this) {}
|
| + ~StartupObserver() override { DCHECK(IsBrowserStartupComplete()); }
|
| +
|
| + void Start();
|
| +
|
| + private:
|
| + void OnStartupComplete() {
|
| + SetBrowserStartupIsComplete();
|
| + delete this;
|
| + }
|
| +
|
| + void OnFailsafeTimeout() { OnStartupComplete(); }
|
| +
|
| + // WebContentsObserver overrides
|
| + void DidFinishLoad(content::RenderFrameHost* render_frame_host,
|
| + const GURL& validated_url) override {
|
| + if (!render_frame_host->GetParent())
|
| + OnStartupComplete();
|
| + }
|
| +
|
| + void DidFailLoad(content::RenderFrameHost* render_frame_host,
|
| + const GURL& validated_url,
|
| + int error_code,
|
| + const base::string16& error_description) override {
|
| + if (!render_frame_host->GetParent())
|
| + OnStartupComplete();
|
| + }
|
| +
|
| + void WebContentsDestroyed() override { OnStartupComplete(); }
|
| +
|
| + base::WeakPtrFactory<StartupObserver> weak_factory_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(StartupObserver);
|
| +};
|
| +
|
| +void StartupObserver::Start() {
|
| + // Signal completion quickly when there is no first page to load.
|
| + const int kShortDelaySecs = 3;
|
| + base::TimeDelta delay = base::TimeDelta::FromSeconds(kShortDelaySecs);
|
| +
|
| +#if !defined(OS_ANDROID)
|
| + WebContents* contents = nullptr;
|
| + for (chrome::BrowserIterator iter; !iter.done(); iter.Next()) {
|
| + contents = (*iter)->tab_strip_model()->GetActiveWebContents();
|
| + if (contents)
|
| + break;
|
| + }
|
| +
|
| + if (contents) {
|
| + // Give the page time to finish loading.
|
| + const int kLongerDelayMins = 3;
|
| + Observe(contents);
|
| + delay = base::TimeDelta::FromMinutes(kLongerDelayMins);
|
| + }
|
| +#endif // !defined(OS_ANDROID)
|
| +
|
| + BrowserThread::PostDelayedTask(
|
| + BrowserThread::UI, FROM_HERE,
|
| + base::Bind(&StartupObserver::OnFailsafeTimeout,
|
| + weak_factory_.GetWeakPtr()),
|
| + delay);
|
| +}
|
| +
|
| // This function provides some ways to test crash and assertion handling
|
| // behavior of the program.
|
| void HandleTestParameters(const base::CommandLine& command_line) {
|
| @@ -590,6 +670,9 @@ ChromeBrowserMainParts::ChromeBrowserMainParts(
|
| // cookies need to go through one of Chrome's URLRequestContexts which have
|
| // a ChromeNetworkDelegate attached that selectively allows cookies again.
|
| net::URLRequest::SetDefaultCookiePolicyToBlock();
|
| +
|
| + // Be sure to allocate the lazy instance on the main thread.
|
| + g_startup_complete_flag.Get();
|
| }
|
|
|
| ChromeBrowserMainParts::~ChromeBrowserMainParts() {
|
| @@ -1111,6 +1194,9 @@ void ChromeBrowserMainParts::PostBrowserStart() {
|
| base::Bind(&WebRtcLogUtil::DeleteOldWebRtcLogFilesForAllProfiles),
|
| base::TimeDelta::FromMinutes(1));
|
| #endif // defined(ENABLE_WEBRTC)
|
| +
|
| + // The observer is self-deleting.
|
| + (new StartupObserver)->Start();
|
| }
|
|
|
| int ChromeBrowserMainParts::PreMainMessageLoopRunImpl() {
|
| @@ -1737,3 +1823,7 @@ void ChromeBrowserMainParts::PostDestroyThreads() {
|
| void ChromeBrowserMainParts::AddParts(ChromeBrowserMainExtraParts* parts) {
|
| chrome_extra_parts_.push_back(parts);
|
| }
|
| +
|
| +bool IsBrowserStartupComplete() {
|
| + return g_startup_complete_flag.Get().IsSet();
|
| +}
|
|
|