Index: chrome/browser/chrome_content_browser_client.cc |
diff --git a/chrome/browser/chrome_content_browser_client.cc b/chrome/browser/chrome_content_browser_client.cc |
index f3d767f5790f955d8df52b54a1ce038bf0a7c366..9fdf0b026fe5b946e6eaf090590dab78577c88dd 100644 |
--- a/chrome/browser/chrome_content_browser_client.cc |
+++ b/chrome/browser/chrome_content_browser_client.cc |
@@ -16,15 +16,18 @@ |
#include "base/path_service.h" |
#include "base/prefs/pref_service.h" |
#include "base/prefs/scoped_user_pref_update.h" |
+#include "base/rand_util.h" |
#include "base/strings/string_number_conversions.h" |
#include "base/strings/utf_string_conversions.h" |
#include "base/threading/sequenced_worker_pool.h" |
+#include "base/time/time.h" |
#include "chrome/browser/browser_about_handler.h" |
#include "chrome/browser/browser_process.h" |
#include "chrome/browser/browser_shutdown.h" |
#include "chrome/browser/browsing_data/browsing_data_helper.h" |
#include "chrome/browser/browsing_data/browsing_data_remover.h" |
#include "chrome/browser/character_encoding.h" |
+#include "chrome/browser/chrome_browser_main.h" |
#include "chrome/browser/chrome_content_browser_client_parts.h" |
#include "chrome/browser/chrome_net_benchmarking_message_filter.h" |
#include "chrome/browser/chrome_quota_permission_context.h" |
@@ -695,6 +698,8 @@ ChromeContentBrowserClient::ChromeContentBrowserClient() |
#if defined(ENABLE_EXTENSIONS) |
extra_parts_.push_back(new ChromeContentBrowserClientExtensionsPart); |
#endif |
+ |
+ weak_this_ = weak_factory_.GetWeakPtr(); |
} |
ChromeContentBrowserClient::~ChromeContentBrowserClient() { |
@@ -786,6 +791,20 @@ content::BrowserMainParts* ChromeContentBrowserClient::CreateBrowserMainParts( |
return main_parts; |
} |
+void ChromeContentBrowserClient::PostAfterStartupTask( |
+ const tracked_objects::Location& from_here, |
+ const scoped_refptr<base::TaskRunner>& task_runner, |
+ const base::Closure& task) { |
+ if (IsBrowserStartupComplete()) { |
+ task_runner->PostTask(from_here, task); |
+ return; |
+ } |
+ |
+ scoped_ptr<AfterStartupTask> queued_task( |
+ new AfterStartupTask(from_here, task_runner, task)); |
+ QueueAfterStartupTask(queued_task.Pass()); |
+} |
+ |
std::string ChromeContentBrowserClient::GetStoragePartitionIdForSite( |
content::BrowserContext* browser_context, |
const GURL& site) { |
@@ -2556,6 +2575,70 @@ void ChromeContentBrowserClient::OverridePageVisibilityState( |
} |
} |
+void ChromeContentBrowserClient::QueueAfterStartupTask( |
+ scoped_ptr<AfterStartupTask> queued_task) { |
+ if (!BrowserThread::CurrentlyOn(BrowserThread::UI)) { |
+ BrowserThread::PostTask( |
+ BrowserThread::UI, |
+ FROM_HERE, |
+ base::Bind(&ChromeContentBrowserClient::QueueAfterStartupTask, |
+ weak_this_, base::Passed(queued_task.Pass()))); |
+ return; |
+ } |
+ |
+ if (IsBrowserStartupComplete()) { |
+ ScheduleRunAfterStartupTask(queued_task.Pass()); |
+ return; |
+ } |
+ |
+ if (after_startup_tasks_.empty()) { |
+ BrowserThread::PostDelayedTask( |
+ BrowserThread::UI, |
+ FROM_HERE, |
+ base::Bind(&ChromeContentBrowserClient::OnAfterStartupTasksTimer, |
+ weak_this_), |
+ base::TimeDelta::FromSeconds(5)); |
+ } |
+ |
+ after_startup_tasks_.push_back(queued_task.release()); |
+} |
+ |
+void ChromeContentBrowserClient::OnAfterStartupTasksTimer() { |
+ if (!IsBrowserStartupComplete()) { |
+ BrowserThread::PostDelayedTask( |
+ BrowserThread::UI, |
+ FROM_HERE, |
+ base::Bind(&ChromeContentBrowserClient::OnAfterStartupTasksTimer, |
+ weak_this_), |
+ base::TimeDelta::FromSeconds(5)); |
+ return; |
+ } |
+ for (AfterStartupTask* queued_task : after_startup_tasks_) |
+ ScheduleRunAfterStartupTask(make_scoped_ptr(queued_task)); |
+ after_startup_tasks_.clear(); |
+} |
+ |
+void ChromeContentBrowserClient::ScheduleRunAfterStartupTask( |
+ scoped_ptr<AfterStartupTask> queued_task) { |
+ // Spread their execution over 30 seconds. |
+ const int kMinDelay = 0; |
+ const int kMaxDelay = 30; |
jam
2015/03/26 15:38:58
What is the purpose of this random delay?
michaeln
2015/03/26 19:52:33
To avoid initiating a bunch of work at the same ti
michaeln
2015/03/26 20:17:52
I'll compute the delay more directly instead of ra
jam
2015/03/26 20:22:08
hmm, I understand the motivation but it's not clea
michaeln
2015/03/26 21:39:36
And if the list were very large, what would your g
jam
2015/03/27 15:50:29
ok that seems fair.
|
+ scoped_refptr<base::TaskRunner> target_runner = queued_task->task_runner; |
+ tracked_objects::Location from_here = queued_task->from_here; |
+ target_runner->PostDelayedTask( |
+ from_here, |
+ base::Bind(&ChromeContentBrowserClient::RunAfterStartupTask, |
+ weak_this_, base::Passed(queued_task.Pass())), |
+ base::TimeDelta::FromSeconds(base::RandInt(kMinDelay, kMaxDelay))); |
+} |
+ |
+void ChromeContentBrowserClient::RunAfterStartupTask( |
+ scoped_ptr<AfterStartupTask> queued_task) { |
+ // We're careful to delete the caller's |task| on the target runner's thread. |
+ DCHECK(queued_task->task_runner->RunsTasksOnCurrentThread()); |
+ queued_task->task.Run(); |
+} |
+ |
#if defined(ENABLE_WEBRTC) |
void ChromeContentBrowserClient::MaybeCopyDisableWebRtcEncryptionSwitch( |
base::CommandLine* to_command_line, |