diff options
author | willchan@chromium.org <willchan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-10-12 07:05:18 +0000 |
---|---|---|
committer | willchan@chromium.org <willchan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-10-12 07:05:18 +0000 |
commit | de95f929772cb7214efb747f9a5a115b27561336 (patch) | |
tree | 3f376123413c93b064eb65baf2643a407f6dfc7e /chrome/browser/net | |
parent | 817925aaf716cb623c56e21030650f075e510157 (diff) | |
download | chromium_src-de95f929772cb7214efb747f9a5a115b27561336.zip chromium_src-de95f929772cb7214efb747f9a5a115b27561336.tar.gz chromium_src-de95f929772cb7214efb747f9a5a115b27561336.tar.bz2 |
Persist Alternate-Protocol.
Record Alternate-Protocol servers in spdy.alternate_protocol. Don't persist broken Alternate-Protocol so they will retry on next browser session.
Also fix listening to notifications when we're the ones setting them. This was leading to unnecessary double updates, where we'd update the cache on the IO thread, and then propagate to the UI thread, where we'd set the prefs, and then observe that change and propagate back to the IO thread to update the cache.
BUG=98472
TEST=Observe that spdy.alternate_protocol is empty in your Preferences file. Confirm that there is no alternate-protocol mapping in chrome://net-internals/#spdy. Browse to www.strangeloopnetworks.com. Check chrome://net-internals/#spdy again and notice that it populates with the mapping. Wait some seconds and then check the Preferences file again and note that it got persisted to disk. Restart Chrome and check chrome://net-internals/#spdy and note that the same alternate-protocol mappings reappear.
Review URL: http://codereview.chromium.org/8221030
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@105028 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/net')
3 files changed, 556 insertions, 133 deletions
diff --git a/chrome/browser/net/http_server_properties_manager.cc b/chrome/browser/net/http_server_properties_manager.cc index 9bcab3c..48c2adc 100644 --- a/chrome/browser/net/http_server_properties_manager.cc +++ b/chrome/browser/net/http_server_properties_manager.cc @@ -54,15 +54,21 @@ StringVector* ListValueToStringVector(const base::ListValue* list) { HttpServerPropertiesManager::HttpServerPropertiesManager( PrefService* pref_service) - : ALLOW_THIS_IN_INITIALIZER_LIST(ui_method_factory_(this)), - pref_service_(pref_service) { + : pref_service_(pref_service), + setting_spdy_servers_(false), + setting_alternate_protocol_servers_(false) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); DCHECK(pref_service); ui_weak_ptr_factory_.reset( new base::WeakPtrFactory<HttpServerPropertiesManager>(this)); ui_weak_ptr_ = ui_weak_ptr_factory_->GetWeakPtr(); + ui_spdy_cache_update_timer_.reset( + new base::OneShotTimer<HttpServerPropertiesManager>); + ui_alternate_protocol_cache_update_timer_.reset( + new base::OneShotTimer<HttpServerPropertiesManager>); pref_change_registrar_.Init(pref_service_); pref_change_registrar_.Add(prefs::kSpdyServers, this); + pref_change_registrar_.Add(prefs::kAlternateProtocolServers, this); } HttpServerPropertiesManager::~HttpServerPropertiesManager() { @@ -72,20 +78,29 @@ void HttpServerPropertiesManager::InitializeOnIOThread() { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); http_server_properties_impl_.reset(new net::HttpServerPropertiesImpl()); - io_method_factory_.reset( - new ScopedRunnableMethodFactory<HttpServerPropertiesManager>(this)); + io_spdy_prefs_update_timer_.reset( + new base::OneShotTimer<HttpServerPropertiesManager>); + io_alternate_protocol_prefs_update_timer_.reset( + new base::OneShotTimer<HttpServerPropertiesManager>); BrowserThread::PostTask( BrowserThread::UI, FROM_HERE, - base::Bind(&HttpServerPropertiesManager::UpdateCacheFromPrefs, + base::Bind(&HttpServerPropertiesManager::UpdateSpdyCacheFromPrefs, ui_weak_ptr_)); + BrowserThread::PostTask( + BrowserThread::UI, + FROM_HERE, + base::Bind( + &HttpServerPropertiesManager::UpdateAlternateProtocolCacheFromPrefs, + ui_weak_ptr_)); } void HttpServerPropertiesManager::ShutdownOnUIThread() { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); // Cancel any pending updates, and stop listening for pref change updates. - ui_method_factory_.RevokeAll(); + ui_spdy_cache_update_timer_->Stop(); + ui_alternate_protocol_cache_update_timer_->Stop(); ui_weak_ptr_factory_.reset(); pref_change_registrar_.RemoveAll(); } @@ -93,13 +108,16 @@ void HttpServerPropertiesManager::ShutdownOnUIThread() { // static void HttpServerPropertiesManager::RegisterPrefs(PrefService* prefs) { prefs->RegisterListPref(prefs::kSpdyServers, PrefService::UNSYNCABLE_PREF); + prefs->RegisterDictionaryPref(prefs::kAlternateProtocolServers, + PrefService::UNSYNCABLE_PREF); } -void HttpServerPropertiesManager::DeleteAll() { +void HttpServerPropertiesManager::Clear() { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); - http_server_properties_impl_->DeleteAll(); - ScheduleUpdatePrefsOnIO(); + http_server_properties_impl_->Clear(); + ScheduleUpdateSpdyPrefsOnIO(); + ScheduleUpdateAlternateProtocolPrefsOnIO(); } bool HttpServerPropertiesManager::SupportsSpdy( @@ -114,7 +132,7 @@ void HttpServerPropertiesManager::SetSupportsSpdy( DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); http_server_properties_impl_->SetSupportsSpdy(server, support_spdy); - ScheduleUpdatePrefsOnIO(); + ScheduleUpdateSpdyPrefsOnIO(); } bool HttpServerPropertiesManager::HasAlternateProtocol( @@ -137,12 +155,14 @@ void HttpServerPropertiesManager::SetAlternateProtocol( DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); http_server_properties_impl_->SetAlternateProtocol( server, alternate_port, alternate_protocol); + ScheduleUpdateAlternateProtocolPrefsOnIO(); } void HttpServerPropertiesManager::SetBrokenAlternateProtocol( const net::HostPortPair& server) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); http_server_properties_impl_->SetBrokenAlternateProtocol(server); + ScheduleUpdateAlternateProtocolPrefsOnIO(); } const net::AlternateProtocolMap& @@ -154,22 +174,15 @@ HttpServerPropertiesManager::alternate_protocol_map() const { // // Update spdy_servers (the cached data) with data from preferences. // -void HttpServerPropertiesManager::ScheduleUpdateCacheOnUI() { +void HttpServerPropertiesManager::ScheduleUpdateSpdyCacheOnUI() { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); // Cancel pending updates, if any. - ui_method_factory_.RevokeAll(); - PostUpdateTaskOnUI( - ui_method_factory_.NewRunnableMethod( - &HttpServerPropertiesManager::UpdateCacheFromPrefs)); + ui_spdy_cache_update_timer_->Stop(); + StartSpdyCacheUpdateTimerOnUI( + base::TimeDelta::FromMilliseconds(kUpdateCacheDelayMs)); } -void HttpServerPropertiesManager::PostUpdateTaskOnUI(Task* task) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - // This is overridden in tests to post the task without the delay. - MessageLoop::current()->PostDelayedTask(FROM_HERE, task, kUpdateCacheDelayMs); -} - -void HttpServerPropertiesManager::UpdateCacheFromPrefs() { +void HttpServerPropertiesManager::UpdateSpdyCacheFromPrefs() { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); if (!pref_service_->HasPrefPath(prefs::kSpdyServers)) @@ -179,17 +192,14 @@ void HttpServerPropertiesManager::UpdateCacheFromPrefs() { StringVector* spdy_servers = ListValueToStringVector(pref_service_->GetList(prefs::kSpdyServers)); - // Go through the IO thread to grab a WeakPtr to |this|. This is safe from - // here, since this task will always execute before a potential deletion of - // ProfileIOData on IO. BrowserThread::PostTask( BrowserThread::IO, FROM_HERE, - base::Bind(&HttpServerPropertiesManager::UpdateCacheFromPrefsOnIO, + base::Bind(&HttpServerPropertiesManager::UpdateSpdyCacheFromPrefsOnIO, base::Unretained(this), spdy_servers, true)); } -void HttpServerPropertiesManager::UpdateCacheFromPrefsOnIO( +void HttpServerPropertiesManager::UpdateSpdyCacheFromPrefsOnIO( StringVector* spdy_servers, bool support_spdy) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); @@ -204,22 +214,15 @@ void HttpServerPropertiesManager::UpdateCacheFromPrefsOnIO( // // Update Preferences with data from spdy_servers (the cached data). // -void HttpServerPropertiesManager::ScheduleUpdatePrefsOnIO() { +void HttpServerPropertiesManager::ScheduleUpdateSpdyPrefsOnIO() { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); // Cancel pending updates, if any. - io_method_factory_->RevokeAll(); - PostUpdateTaskOnIO( - io_method_factory_->NewRunnableMethod( - &HttpServerPropertiesManager::UpdatePrefsFromCache)); + io_spdy_prefs_update_timer_->Stop(); + StartSpdyPrefsUpdateTimerOnIO( + base::TimeDelta::FromMilliseconds(kUpdatePrefsDelayMs)); } -void HttpServerPropertiesManager::PostUpdateTaskOnIO(Task* task) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); - // This is overridden in tests to post the task without the delay. - MessageLoop::current()->PostDelayedTask(FROM_HERE, task, kUpdatePrefsDelayMs); -} - -void HttpServerPropertiesManager::UpdatePrefsFromCache() { +void HttpServerPropertiesManager::UpdateSpdyPrefsFromCache() { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); scoped_refptr<RefCountedListValue> spdy_server_list = @@ -237,7 +240,185 @@ void HttpServerPropertiesManager::UpdatePrefsFromCache() { void HttpServerPropertiesManager::SetSpdyServersInPrefsOnUI( scoped_refptr<RefCountedListValue> spdy_server_list) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + setting_spdy_servers_ = true; pref_service_->Set(prefs::kSpdyServers, spdy_server_list->data); + setting_spdy_servers_ = false; +} + +void HttpServerPropertiesManager::ScheduleUpdateAlternateProtocolCacheOnUI() { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + // Cancel pending updates, if any. + ui_alternate_protocol_cache_update_timer_->Stop(); + StartAlternateProtocolCacheUpdateTimerOnUI( + base::TimeDelta::FromMilliseconds(kUpdateCacheDelayMs)); +} + +void HttpServerPropertiesManager::UpdateAlternateProtocolCacheFromPrefs() { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + + if (!pref_service_->HasPrefPath(prefs::kAlternateProtocolServers)) + return; + + // Parse the preferences into a AlternateProtocolMap. + net::AlternateProtocolMap alternate_protocol_map; + const base::DictionaryValue& alternate_protocol_servers = + *pref_service_->GetDictionary(prefs::kAlternateProtocolServers); + for (base::DictionaryValue::key_iterator it = + alternate_protocol_servers.begin_keys(); + it != alternate_protocol_servers.end_keys(); ++it) { + const std::string& server_str = *it; + net::HostPortPair server = net::HostPortPair::FromString(server_str); + if (server.host().empty()) { + VLOG(1) << "Malformed Alternate-Protocol server: " << server_str; + NOTREACHED(); + continue; + } + DCHECK(!ContainsKey(alternate_protocol_map, server)); + + base::DictionaryValue* port_alternate_protocol_dict = NULL; + if (!alternate_protocol_servers.GetDictionaryWithoutPathExpansion( + server_str, &port_alternate_protocol_dict)) { + VLOG(1) << "Malformed Alternate-Protocol server: " << server_str; + NOTREACHED(); + continue; + } + + int port = 0; + if (!port_alternate_protocol_dict->GetIntegerWithoutPathExpansion( + "port", &port) || (port > (1 << 16))) { + VLOG(1) << "Malformed Alternate-Protocol server: " << server_str; + NOTREACHED(); + continue; + } + int protocol = 0; + if (!port_alternate_protocol_dict->GetIntegerWithoutPathExpansion( + "protocol", &protocol) || (protocol < 0) || + (protocol > net::NUM_ALTERNATE_PROTOCOLS)) { + VLOG(1) << "Malformed Alternate-Protocol server: " << server_str; + NOTREACHED(); + continue; + } + + net::PortAlternateProtocolPair port_alternate_protocol; + port_alternate_protocol.port = port; + port_alternate_protocol.protocol = static_cast<net::AlternateProtocol>( + protocol); + + alternate_protocol_map[server] = port_alternate_protocol; + } + + scoped_refptr<RefCountedAlternateProtocolMap> alternate_protocol_map_arg = + new RefCountedAlternateProtocolMap; + alternate_protocol_map_arg->data.swap(alternate_protocol_map); + + BrowserThread::PostTask( + BrowserThread::IO, + FROM_HERE, + base::Bind(&HttpServerPropertiesManager:: + UpdateAlternateProtocolCacheFromPrefsOnIO, + base::Unretained(this), alternate_protocol_map_arg)); +} + +void HttpServerPropertiesManager::UpdateAlternateProtocolCacheFromPrefsOnIO( + RefCountedAlternateProtocolMap* alternate_protocol_map) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); + // Preferences have the master data because admins might have pushed new + // preferences. Clear the cached data and use the new spdy server list from + // preferences. + http_server_properties_impl_->InitializeAlternateProtocolServers( + &alternate_protocol_map->data); +} + +// +// Update Preferences with data from alternate_protocol_servers (the cached +// data). +// +void HttpServerPropertiesManager::ScheduleUpdateAlternateProtocolPrefsOnIO() { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); + // Cancel pending updates, if any. + io_alternate_protocol_prefs_update_timer_->Stop(); + StartAlternateProtocolPrefsUpdateTimerOnIO( + base::TimeDelta::FromMilliseconds(kUpdatePrefsDelayMs)); +} + +void HttpServerPropertiesManager::UpdateAlternateProtocolPrefsFromCache() { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); + + scoped_refptr<RefCountedAlternateProtocolMap> alternate_protocol_map = + new RefCountedAlternateProtocolMap; + alternate_protocol_map->data = + http_server_properties_impl_->alternate_protocol_map(); + + // Update the preferences on the UI thread. + BrowserThread::PostTask( + BrowserThread::UI, + FROM_HERE, + base::Bind(&HttpServerPropertiesManager:: + SetAlternateProtocolServersInPrefsOnUI, + ui_weak_ptr_, alternate_protocol_map)); +} + +void HttpServerPropertiesManager::SetAlternateProtocolServersInPrefsOnUI( + RefCountedAlternateProtocolMap* alternate_protocol_map) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + base::DictionaryValue alternate_protocol_dict; + for (net::AlternateProtocolMap::const_iterator it = + alternate_protocol_map->data.begin(); + it != alternate_protocol_map->data.end(); ++it) { + const net::HostPortPair& server = it->first; + const net::PortAlternateProtocolPair& port_alternate_protocol = + it->second; + if (port_alternate_protocol.protocol < 0 || + port_alternate_protocol.protocol >= net::NUM_ALTERNATE_PROTOCOLS) { + continue; + } + base::DictionaryValue* port_alternate_protocol_dict = + new base::DictionaryValue; + port_alternate_protocol_dict->SetInteger( + "port", port_alternate_protocol.port); + port_alternate_protocol_dict->SetInteger( + "protocol", port_alternate_protocol.protocol); + alternate_protocol_dict.SetWithoutPathExpansion( + server.ToString(), port_alternate_protocol_dict); + } + setting_alternate_protocol_servers_ = true; + pref_service_->Set(prefs::kAlternateProtocolServers, + alternate_protocol_dict); + setting_alternate_protocol_servers_ = false; +} + +void HttpServerPropertiesManager::StartSpdyCacheUpdateTimerOnUI( + base::TimeDelta delay) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + ui_spdy_cache_update_timer_->Start( + FROM_HERE, delay, this, + &HttpServerPropertiesManager::UpdateSpdyCacheFromPrefs); +} + +void HttpServerPropertiesManager::StartSpdyPrefsUpdateTimerOnIO( + base::TimeDelta delay) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); + // This is overridden in tests to post the task without the delay. + io_spdy_prefs_update_timer_->Start( + FROM_HERE, delay, this, + &HttpServerPropertiesManager::UpdateSpdyPrefsFromCache); +} + +void HttpServerPropertiesManager::StartAlternateProtocolCacheUpdateTimerOnUI( + base::TimeDelta delay) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); + ui_alternate_protocol_cache_update_timer_->Start( + FROM_HERE, delay, this, + &HttpServerPropertiesManager::UpdateAlternateProtocolCacheFromPrefs); +} + +void HttpServerPropertiesManager::StartAlternateProtocolPrefsUpdateTimerOnIO( + base::TimeDelta delay) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); + // This is overridden in tests to post the task without the delay. + io_alternate_protocol_prefs_update_timer_->Start( + FROM_HERE, delay, this, + &HttpServerPropertiesManager::UpdateAlternateProtocolPrefsFromCache); } void HttpServerPropertiesManager::Observe(int type, @@ -248,8 +429,15 @@ void HttpServerPropertiesManager::Observe(int type, PrefService* prefs = Source<PrefService>(source).ptr(); DCHECK(prefs == pref_service_); std::string* pref_name = Details<std::string>(details).ptr(); - DCHECK(*pref_name == prefs::kSpdyServers); - ScheduleUpdateCacheOnUI(); + if (*pref_name == prefs::kSpdyServers) { + if (!setting_spdy_servers_) + ScheduleUpdateSpdyCacheOnUI(); + } else if (*pref_name == prefs::kAlternateProtocolServers) { + if (!setting_alternate_protocol_servers_) + ScheduleUpdateAlternateProtocolCacheOnUI(); + } else { + NOTREACHED(); + } } } // namespace chrome_browser_net diff --git a/chrome/browser/net/http_server_properties_manager.h b/chrome/browser/net/http_server_properties_manager.h index 572922e..b7d6bf0 100644 --- a/chrome/browser/net/http_server_properties_manager.h +++ b/chrome/browser/net/http_server_properties_manager.h @@ -13,7 +13,7 @@ #include "base/memory/ref_counted.h" #include "base/memory/scoped_ptr.h" #include "base/memory/weak_ptr.h" -#include "base/task.h" +#include "base/timer.h" #include "base/values.h" #include "chrome/browser/prefs/pref_change_registrar.h" #include "content/common/notification_observer.h" @@ -75,7 +75,7 @@ class HttpServerPropertiesManager // ---------------------------------- // Deletes all data. - virtual void DeleteAll() OVERRIDE; + virtual void Clear() OVERRIDE; // Returns true if |server| supports SPDY. Should only be called from IO // thread. @@ -111,39 +111,83 @@ class HttpServerPropertiesManager protected: typedef base::RefCountedData<base::ListValue> RefCountedListValue; + typedef base::RefCountedData<net::AlternateProtocolMap> + RefCountedAlternateProtocolMap; + + // -------------------- + // SPDY related methods // These are used to delay updating the spdy servers in // |http_server_properties_impl_| while the preferences are changing, and // execute only one update per simultaneous prefs changes. - void ScheduleUpdateCacheOnUI(); + void ScheduleUpdateSpdyCacheOnUI(); // Update spdy servers (the cached data in |http_server_properties_impl_|) // with data from preferences. Virtual for testing. - virtual void UpdateCacheFromPrefs(); + virtual void UpdateSpdyCacheFromPrefs(); // Starts the |spdy_servers| update on the IO thread. Protected for testing. - void UpdateCacheFromPrefsOnIO(std::vector<std::string>* spdy_servers, - bool support_spdy); + void UpdateSpdyCacheFromPrefsOnIO(std::vector<std::string>* spdy_servers, + bool support_spdy); // These are used to delay updating the preferences when spdy servers_ are // changing, and execute only one update per simultaneous spdy server changes. - void ScheduleUpdatePrefsOnIO(); + void ScheduleUpdateSpdyPrefsOnIO(); // Update spdy servers in preferences with the cached data from // |http_server_properties_impl_|. Virtual for testing. - virtual void UpdatePrefsFromCache(); // Virtual for testing. + virtual void UpdateSpdyPrefsFromCache(); // Virtual for testing. // Update |prefs::kSpdyServers| preferences with |spdy_server_list| on UI // thread. Protected for testing. void SetSpdyServersInPrefsOnUI( scoped_refptr<RefCountedListValue> spdy_server_list); - private: - // Post the tasks with the delay. These are overridden in tests to post the - // task without the delay. - virtual void PostUpdateTaskOnUI(Task* task); // Virtual for testing. - virtual void PostUpdateTaskOnIO(Task* task); // Virtual for testing. + // Starts the timers to update the cache/prefs. This are overridden in tests + // to prevent the delay. + virtual void StartSpdyCacheUpdateTimerOnUI(base::TimeDelta delay); + virtual void StartSpdyPrefsUpdateTimerOnIO(base::TimeDelta delay); + + // ---------------------------------- + // Alternate-Protocol related methods + + // These are used to delay updating the Alternate-Protocol servers in + // |http_server_properties_impl_| while the preferences are changing, and + // execute only one update per simultaneous prefs changes. + void ScheduleUpdateAlternateProtocolCacheOnUI(); + + // Update Alternate-Protocol servers (the cached data in + // |http_server_properties_impl_|) with data from preferences. Virtual for + // testing. + virtual void UpdateAlternateProtocolCacheFromPrefs(); + + // Starts the |alternate_protocol_servers| update on the IO thread. Protected + // for testing. + void UpdateAlternateProtocolCacheFromPrefsOnIO( + RefCountedAlternateProtocolMap* alternate_protocol_map); + + // These are used to delay updating the preferences when Alternate-Protocol + // servers_ are changing, and execute only one update per simultaneous + // Alternate-Protocol server changes. + void ScheduleUpdateAlternateProtocolPrefsOnIO(); + // Update Alternate-Protocol servers in preferences with the cached data from + // |http_server_properties_impl_|. Virtual for testing. + virtual void UpdateAlternateProtocolPrefsFromCache(); // Virtual for testing. + + // Update |prefs::kAlternateProtocolServers| preferences with + // |alternate_protocol_server_list| on UI thread. Protected for testing. + void SetAlternateProtocolServersInPrefsOnUI( + RefCountedAlternateProtocolMap* alternate_protocol_map); + + // Starts the timers to update the cache/prefs. This are overridden in tests + // to prevent the delay. + virtual void StartAlternateProtocolCacheUpdateTimerOnUI( + base::TimeDelta delay); + virtual void StartAlternateProtocolPrefsUpdateTimerOnIO( + base::TimeDelta delay); + + private: // Callback for preference changes. virtual void Observe(int type, const NotificationSource& source, @@ -153,26 +197,37 @@ class HttpServerPropertiesManager // UI thread // --------- - // Used to post update tasks to the UI thread. - ScopedRunnableMethodFactory<HttpServerPropertiesManager> ui_method_factory_; - // Used to get |weak_ptr_| to self on the UI thread. scoped_ptr<base::WeakPtrFactory<HttpServerPropertiesManager> > ui_weak_ptr_factory_; base::WeakPtr<HttpServerPropertiesManager> ui_weak_ptr_; + // Used to post SPDY cache update tasks. + scoped_ptr<base::OneShotTimer<HttpServerPropertiesManager> > + ui_spdy_cache_update_timer_; + + // Used to post Alternate-Protocol cache update tasks. + scoped_ptr<base::OneShotTimer<HttpServerPropertiesManager> > + ui_alternate_protocol_cache_update_timer_; + // Used to track the spdy servers changes. PrefChangeRegistrar pref_change_registrar_; PrefService* pref_service_; // Weak. + bool setting_spdy_servers_; + bool setting_alternate_protocol_servers_; // --------- // IO thread // --------- - // Used to post update tasks to the IO thread. - scoped_ptr<ScopedRunnableMethodFactory<HttpServerPropertiesManager> > - io_method_factory_; + // Used to post SPDY pref update tasks. + scoped_ptr<base::OneShotTimer<HttpServerPropertiesManager> > + io_spdy_prefs_update_timer_; + + // Used to post Alternate-Protocol pref update tasks. + scoped_ptr<base::OneShotTimer<HttpServerPropertiesManager> > + io_alternate_protocol_prefs_update_timer_; scoped_ptr<net::HttpServerPropertiesImpl> http_server_properties_impl_; diff --git a/chrome/browser/net/http_server_properties_manager_unittest.cc b/chrome/browser/net/http_server_properties_manager_unittest.cc index 1c95eab..6c23ac3 100644 --- a/chrome/browser/net/http_server_properties_manager_unittest.cc +++ b/chrome/browser/net/http_server_properties_manager_unittest.cc @@ -22,6 +22,7 @@ namespace { using ::testing::_; using ::testing::Invoke; using ::testing::Mock; +using ::testing::StrictMock; class TestingHttpServerPropertiesManager : public HttpServerPropertiesManager { public: @@ -33,55 +34,68 @@ class TestingHttpServerPropertiesManager : public HttpServerPropertiesManager { virtual ~TestingHttpServerPropertiesManager() { } - // Make this method public for testing. - using HttpServerPropertiesManager::ScheduleUpdateCacheOnUI; - using HttpServerPropertiesManager::ScheduleUpdatePrefsOnIO; + // Make these method public for testing. + using HttpServerPropertiesManager::ScheduleUpdateSpdyCacheOnUI; + using HttpServerPropertiesManager::ScheduleUpdateSpdyPrefsOnIO; + using HttpServerPropertiesManager::ScheduleUpdateAlternateProtocolCacheOnUI; + using HttpServerPropertiesManager::ScheduleUpdateAlternateProtocolPrefsOnIO; // Post tasks without a delay during tests. - virtual void PostUpdateTaskOnUI(Task* task) OVERRIDE { - MessageLoop::current()->PostTask(FROM_HERE, task); + virtual void StartSpdyPrefsUpdateTimerOnIO(base::TimeDelta delay) OVERRIDE { + HttpServerPropertiesManager::StartSpdyPrefsUpdateTimerOnIO( + base::TimeDelta()); } - // Makes a direct call to UpdateCacheFromPrefsOnIO during tests. - void UpdateCacheFromPrefsOnIO() { - std::vector<std::string>* spdy_servers = new std::vector<std::string>; - spdy_servers->push_back("www.google.com:443"); - HttpServerPropertiesManager::UpdateCacheFromPrefsOnIO(spdy_servers, true); + // Post tasks without a delay during tests. + virtual void StartAlternateProtocolPrefsUpdateTimerOnIO( + base::TimeDelta delay) OVERRIDE { + HttpServerPropertiesManager::StartAlternateProtocolPrefsUpdateTimerOnIO( + base::TimeDelta()); } - void UpdateCacheFromPrefsConcrete() { - HttpServerPropertiesManager::UpdateCacheFromPrefs(); + void UpdateSpdyCacheFromPrefsConcrete() { + HttpServerPropertiesManager::UpdateSpdyCacheFromPrefs(); } - // Post tasks without a delay during tests. - virtual void PostUpdateTaskOnIO(Task* task) OVERRIDE { - MessageLoop::current()->PostTask(FROM_HERE, task); + void UpdateAlternateProtocolCacheFromPrefsConcrete() { + HttpServerPropertiesManager::UpdateAlternateProtocolCacheFromPrefs(); } - // Makes a direct call to SetSpdyServersInPrefsOnUI during tests. - void SetSpdyServersInPrefsOnUI() { - net::HostPortPair spdy_server_mail("mail.google.com", 443); - std::string spdy_server_m = - net::HttpServerPropertiesImpl::GetFlattenedSpdyServer(spdy_server_mail); + // Post tasks without a delay during tests. + virtual void StartSpdyCacheUpdateTimerOnUI(base::TimeDelta delay) OVERRIDE { + HttpServerPropertiesManager::StartSpdyCacheUpdateTimerOnUI( + base::TimeDelta()); + } - scoped_refptr<RefCountedListValue> spdy_server_list = - new RefCountedListValue(); - spdy_server_list->data.Append(new StringValue(spdy_server_m)); + // Post tasks without a delay during tests. + virtual void StartAlternateProtocolCacheUpdateTimerOnUI( + base::TimeDelta delay) OVERRIDE { + HttpServerPropertiesManager::StartAlternateProtocolCacheUpdateTimerOnUI( + base::TimeDelta()); + } - HttpServerPropertiesManager::SetSpdyServersInPrefsOnUI(spdy_server_list); + void UpdateSpdyPrefsFromCacheConcrete() { + HttpServerPropertiesManager::UpdateSpdyPrefsFromCache(); } - void UpdatePrefsFromCacheConcrete() { - HttpServerPropertiesManager::UpdatePrefsFromCache(); + void UpdateAlternateProtocolPrefsFromCacheConcrete() { + HttpServerPropertiesManager::UpdateAlternateProtocolPrefsFromCache(); } - MOCK_METHOD0(UpdateCacheFromPrefs, void()); - MOCK_METHOD0(UpdatePrefsFromCache, void()); - MOCK_METHOD2(UpdateCacheFromPrefsOnIO, + MOCK_METHOD0(UpdateSpdyCacheFromPrefs, void()); + MOCK_METHOD0(UpdateSpdyPrefsFromCache, void()); + MOCK_METHOD2(UpdateSpdyCacheFromPrefsOnIO, void(std::vector<std::string>* spdy_servers, bool support_spdy)); MOCK_METHOD1(SetSpdyServersInPrefsOnUI, void(scoped_refptr<RefCountedListValue> spdy_server_list)); + MOCK_METHOD0(UpdateAlternateProtocolCacheFromPrefs, void()); + MOCK_METHOD0(UpdateAlternateProtocolPrefsFromCache, void()); + MOCK_METHOD1(UpdateAlternateProtocolCacheFromPrefsOnIO, + void(RefCountedAlternateProtocolMap*)); + MOCK_METHOD1(SetAlternateProtocolServersInPrefsOnUI, + void(RefCountedAlternateProtocolMap*)); + private: DISALLOW_COPY_AND_ASSIGN(TestingHttpServerPropertiesManager); }; @@ -95,8 +109,11 @@ class HttpServerPropertiesManagerTest : public testing::Test { virtual void SetUp() OVERRIDE { pref_service_.RegisterListPref(prefs::kSpdyServers); + pref_service_.RegisterDictionaryPref(prefs::kAlternateProtocolServers); http_server_props_manager_.reset( - new TestingHttpServerPropertiesManager(&pref_service_)); + new StrictMock<TestingHttpServerPropertiesManager>(&pref_service_)); + ExpectSpdyCacheUpdate(); + ExpectAlternateProtocolCacheUpdate(); loop_.RunAllPending(); } @@ -109,18 +126,38 @@ class HttpServerPropertiesManagerTest : public testing::Test { http_server_props_manager_.reset(); } - void ExpectCacheUpdate() { - EXPECT_CALL(*http_server_props_manager_, UpdateCacheFromPrefs()) + void ExpectSpdyCacheUpdate() { + EXPECT_CALL(*http_server_props_manager_, UpdateSpdyCacheFromPrefs()) + .WillOnce( + Invoke(http_server_props_manager_.get(), + &TestingHttpServerPropertiesManager:: + UpdateSpdyCacheFromPrefsConcrete)); + } + + void ExpectSpdyPrefsUpdate() { + EXPECT_CALL(*http_server_props_manager_, UpdateSpdyPrefsFromCache()) .WillOnce( Invoke(http_server_props_manager_.get(), - &TestingHttpServerPropertiesManager::UpdateCacheFromPrefsConcrete)); + &TestingHttpServerPropertiesManager:: + UpdateSpdyPrefsFromCacheConcrete)); } - void ExpectPrefsUpdate() { - EXPECT_CALL(*http_server_props_manager_, UpdatePrefsFromCache()) + void ExpectAlternateProtocolCacheUpdate() { + EXPECT_CALL(*http_server_props_manager_, + UpdateAlternateProtocolCacheFromPrefs()) .WillOnce( Invoke(http_server_props_manager_.get(), - &TestingHttpServerPropertiesManager::UpdatePrefsFromCacheConcrete)); + &TestingHttpServerPropertiesManager:: + UpdateAlternateProtocolCacheFromPrefsConcrete)); + } + + void ExpectAlternateProtocolPrefsUpdate() { + EXPECT_CALL(*http_server_props_manager_, + UpdateAlternateProtocolPrefsFromCache()) + .WillOnce( + Invoke(http_server_props_manager_.get(), + &TestingHttpServerPropertiesManager:: + UpdateAlternateProtocolPrefsFromCacheConcrete)); } MessageLoop loop_; @@ -134,23 +171,32 @@ class HttpServerPropertiesManagerTest : public testing::Test { DISALLOW_COPY_AND_ASSIGN(HttpServerPropertiesManagerTest); }; -TEST_F(HttpServerPropertiesManagerTest, SingleUpdateForTwoPrefChanges) { - ExpectCacheUpdate(); +TEST_F(HttpServerPropertiesManagerTest, SingleUpdateForTwoSpdyPrefChanges) { + ExpectSpdyCacheUpdate(); - ListValue* http_server_props = new ListValue; - http_server_props->Append(new StringValue("www.google.com:443")); - http_server_props->Append(new StringValue("mail.google.com:443")); + // Set up the pref and then set it twice. Only expect a single cache update. + base::ListValue* http_server_props = new base::ListValue; + http_server_props->Append(new base::StringValue("www.google.com:443")); + pref_service_.SetManagedPref(prefs::kSpdyServers, http_server_props); + http_server_props = http_server_props->DeepCopy(); + http_server_props->Append(new base::StringValue("mail.google.com:443")); pref_service_.SetManagedPref(prefs::kSpdyServers, http_server_props); loop_.RunAllPending(); - Mock::VerifyAndClearExpectations(http_server_props_manager_.get()); + + EXPECT_TRUE(http_server_props_manager_->SupportsSpdy( + net::HostPortPair::FromString("www.google.com:443"))); + EXPECT_TRUE(http_server_props_manager_->SupportsSpdy( + net::HostPortPair::FromString("mail.google.com:443"))); + EXPECT_FALSE(http_server_props_manager_->SupportsSpdy( + net::HostPortPair::FromString("foo.google.com:1337"))); } TEST_F(HttpServerPropertiesManagerTest, SupportsSpdy) { - ExpectPrefsUpdate(); + ExpectSpdyPrefsUpdate(); // Post an update task to the IO thread. SetSupportsSpdy calls - // ScheduleUpdatePrefsOnIO. + // ScheduleUpdateSpdyPrefsOnIO. // Add mail.google.com:443 as a supporting spdy server. net::HostPortPair spdy_server_mail("mail.google.com", 443); @@ -164,37 +210,174 @@ TEST_F(HttpServerPropertiesManagerTest, SupportsSpdy) { Mock::VerifyAndClearExpectations(http_server_props_manager_.get()); } -TEST_F(HttpServerPropertiesManagerTest, DeleteAll) { - ExpectPrefsUpdate(); +TEST_F(HttpServerPropertiesManagerTest, Clear) { + ExpectSpdyPrefsUpdate(); + ExpectAlternateProtocolPrefsUpdate(); - // Add mail.google.com:443 as a supporting spdy server. net::HostPortPair spdy_server_mail("mail.google.com", 443); http_server_props_manager_->SetSupportsSpdy(spdy_server_mail, true); + http_server_props_manager_->SetAlternateProtocol( + spdy_server_mail, 443, net::NPN_SPDY_2); // Run the task. loop_.RunAllPending(); EXPECT_TRUE(http_server_props_manager_->SupportsSpdy(spdy_server_mail)); + EXPECT_TRUE( + http_server_props_manager_->HasAlternateProtocol(spdy_server_mail)); Mock::VerifyAndClearExpectations(http_server_props_manager_.get()); - // DeleteAll http server data. - http_server_props_manager_->DeleteAll(); + ExpectSpdyPrefsUpdate(); + ExpectAlternateProtocolPrefsUpdate(); + // Clear http server data. + http_server_props_manager_->Clear(); // Run the task. loop_.RunAllPending(); EXPECT_FALSE(http_server_props_manager_->SupportsSpdy(spdy_server_mail)); + EXPECT_FALSE( + http_server_props_manager_->HasAlternateProtocol(spdy_server_mail)); Mock::VerifyAndClearExpectations(http_server_props_manager_.get()); } +TEST_F(HttpServerPropertiesManagerTest, ShutdownWithPendingUpdateSpdyCache0) { + // Post an update task to the UI thread. + http_server_props_manager_->ScheduleUpdateSpdyCacheOnUI(); + // Shutdown comes before the task is executed. + http_server_props_manager_->ShutdownOnUIThread(); + http_server_props_manager_.reset(); + // Run the task after shutdown and deletion. + loop_.RunAllPending(); +} + +TEST_F(HttpServerPropertiesManagerTest, ShutdownWithPendingUpdateSpdyCache1) { + // Post an update task. + http_server_props_manager_->ScheduleUpdateSpdyCacheOnUI(); + // Shutdown comes before the task is executed. + http_server_props_manager_->ShutdownOnUIThread(); + // Run the task after shutdown, but before deletion. + loop_.RunAllPending(); + Mock::VerifyAndClearExpectations(http_server_props_manager_.get()); + http_server_props_manager_.reset(); + loop_.RunAllPending(); +} + +TEST_F(HttpServerPropertiesManagerTest, ShutdownWithPendingUpdateSpdyCache2) { + http_server_props_manager_->UpdateSpdyCacheFromPrefsConcrete(); + // Shutdown comes before the task is executed. + http_server_props_manager_->ShutdownOnUIThread(); + // Run the task after shutdown, but before deletion. + loop_.RunAllPending(); + Mock::VerifyAndClearExpectations(http_server_props_manager_.get()); + http_server_props_manager_.reset(); + loop_.RunAllPending(); +} + // -// Tests for shutdown when updating cache. +// Tests for shutdown when updating prefs. // -TEST_F(HttpServerPropertiesManagerTest, ShutdownWithPendingUpdateCache0) { - EXPECT_CALL(*http_server_props_manager_, - UpdateCacheFromPrefsOnIO(_, _)).Times(0); +TEST_F(HttpServerPropertiesManagerTest, ShutdownWithPendingUpdateSpdyPrefs0) { + // Post an update task to the IO thread. + http_server_props_manager_->ScheduleUpdateSpdyPrefsOnIO(); + // Shutdown comes before the task is executed. + http_server_props_manager_->ShutdownOnUIThread(); + http_server_props_manager_.reset(); + // Run the task after shutdown and deletion. + loop_.RunAllPending(); +} + +TEST_F(HttpServerPropertiesManagerTest, ShutdownWithPendingUpdateSpdyPrefs1) { + ExpectSpdyPrefsUpdate(); + // Post an update task. + http_server_props_manager_->ScheduleUpdateSpdyPrefsOnIO(); + // Shutdown comes before the task is executed. + http_server_props_manager_->ShutdownOnUIThread(); + // Run the task after shutdown, but before deletion. + loop_.RunAllPending(); + Mock::VerifyAndClearExpectations(http_server_props_manager_.get()); + http_server_props_manager_.reset(); + loop_.RunAllPending(); +} + +TEST_F(HttpServerPropertiesManagerTest, ShutdownWithPendingUpdateSpdyPrefs2) { + // This posts a task to the UI thread. + http_server_props_manager_->UpdateSpdyPrefsFromCacheConcrete(); + // Shutdown comes before the task is executed. + http_server_props_manager_->ShutdownOnUIThread(); + // Run the task after shutdown, but before deletion. + loop_.RunAllPending(); + Mock::VerifyAndClearExpectations(http_server_props_manager_.get()); + http_server_props_manager_.reset(); + loop_.RunAllPending(); +} + +TEST_F(HttpServerPropertiesManagerTest, + SingleUpdateForTwoAlternateProtocolPrefChanges) { + ExpectAlternateProtocolCacheUpdate(); + + // Set up the pref and then set it twice. Only expect a single cache update. + base::DictionaryValue* alternate_protocol_servers = new base::DictionaryValue; + base::DictionaryValue* alternate_protocol = new base::DictionaryValue; + alternate_protocol->SetInteger("port", 443); + alternate_protocol->SetInteger("protocol", static_cast<int>(net::NPN_SPDY_1)); + alternate_protocol_servers->SetWithoutPathExpansion( + "www.google.com:80", alternate_protocol); + alternate_protocol = new base::DictionaryValue; + alternate_protocol->SetInteger("port", 444); + alternate_protocol->SetInteger("protocol", static_cast<int>(net::NPN_SPDY_2)); + alternate_protocol_servers->SetWithoutPathExpansion( + "mail.google.com:80", alternate_protocol); + pref_service_.SetManagedPref(prefs::kAlternateProtocolServers, + alternate_protocol_servers); + alternate_protocol_servers = alternate_protocol_servers->DeepCopy(); + pref_service_.SetManagedPref(prefs::kAlternateProtocolServers, + alternate_protocol_servers); + loop_.RunAllPending(); + + Mock::VerifyAndClearExpectations(http_server_props_manager_.get()); + + ASSERT_TRUE(http_server_props_manager_->HasAlternateProtocol( + net::HostPortPair::FromString("www.google.com:80"))); + ASSERT_TRUE(http_server_props_manager_->HasAlternateProtocol( + net::HostPortPair::FromString("mail.google.com:80"))); + net::PortAlternateProtocolPair port_alternate_protocol = + http_server_props_manager_->GetAlternateProtocol( + net::HostPortPair::FromString("www.google.com:80")); + EXPECT_EQ(443, port_alternate_protocol.port); + EXPECT_EQ(net::NPN_SPDY_1, port_alternate_protocol.protocol); + port_alternate_protocol = + http_server_props_manager_->GetAlternateProtocol( + net::HostPortPair::FromString("mail.google.com:80")); + EXPECT_EQ(444, port_alternate_protocol.port); + EXPECT_EQ(net::NPN_SPDY_2, port_alternate_protocol.protocol); +} + +TEST_F(HttpServerPropertiesManagerTest, HasAlternateProtocol) { + ExpectAlternateProtocolPrefsUpdate(); + + net::HostPortPair spdy_server_mail("mail.google.com", 80); + EXPECT_FALSE( + http_server_props_manager_->HasAlternateProtocol(spdy_server_mail)); + http_server_props_manager_->SetAlternateProtocol( + spdy_server_mail, 443, net::NPN_SPDY_2); + + // Run the task. + loop_.RunAllPending(); + Mock::VerifyAndClearExpectations(http_server_props_manager_.get()); + + ASSERT_TRUE( + http_server_props_manager_->HasAlternateProtocol(spdy_server_mail)); + net::PortAlternateProtocolPair port_alternate_protocol = + http_server_props_manager_->GetAlternateProtocol(spdy_server_mail); + EXPECT_EQ(443, port_alternate_protocol.port); + EXPECT_EQ(net::NPN_SPDY_2, port_alternate_protocol.protocol); +} + +TEST_F(HttpServerPropertiesManagerTest, + ShutdownWithPendingUpdateAlternateProtocolCache0) { // Post an update task to the UI thread. - http_server_props_manager_->ScheduleUpdateCacheOnUI(); + http_server_props_manager_->ScheduleUpdateAlternateProtocolCacheOnUI(); // Shutdown comes before the task is executed. http_server_props_manager_->ShutdownOnUIThread(); http_server_props_manager_.reset(); @@ -202,10 +385,10 @@ TEST_F(HttpServerPropertiesManagerTest, ShutdownWithPendingUpdateCache0) { loop_.RunAllPending(); } -TEST_F(HttpServerPropertiesManagerTest, ShutdownWithPendingUpdateCache1) { - EXPECT_CALL(*http_server_props_manager_, UpdateCacheFromPrefs()).Times(0); +TEST_F(HttpServerPropertiesManagerTest, + ShutdownWithPendingUpdateAlternateProtocolCache1) { // Post an update task. - http_server_props_manager_->ScheduleUpdateCacheOnUI(); + http_server_props_manager_->ScheduleUpdateAlternateProtocolCacheOnUI(); // Shutdown comes before the task is executed. http_server_props_manager_->ShutdownOnUIThread(); // Run the task after shutdown, but before deletion. @@ -215,10 +398,9 @@ TEST_F(HttpServerPropertiesManagerTest, ShutdownWithPendingUpdateCache1) { loop_.RunAllPending(); } -TEST_F(HttpServerPropertiesManagerTest, ShutdownWithPendingUpdateCache2) { - EXPECT_CALL(*http_server_props_manager_, - UpdateCacheFromPrefsOnIO(_, _)).Times(0); - http_server_props_manager_->UpdateCacheFromPrefsConcrete(); +TEST_F(HttpServerPropertiesManagerTest, + ShutdownWithPendingUpdateAlternateProtocolCache2) { + http_server_props_manager_->UpdateAlternateProtocolCacheFromPrefsConcrete(); // Shutdown comes before the task is executed. http_server_props_manager_->ShutdownOnUIThread(); // Run the task after shutdown, but before deletion. @@ -231,11 +413,10 @@ TEST_F(HttpServerPropertiesManagerTest, ShutdownWithPendingUpdateCache2) { // // Tests for shutdown when updating prefs. // -TEST_F(HttpServerPropertiesManagerTest, ShutdownWithPendingUpdatePrefs0) { - EXPECT_CALL(*http_server_props_manager_, - SetSpdyServersInPrefsOnUI(_)).Times(0); +TEST_F(HttpServerPropertiesManagerTest, + ShutdownWithPendingUpdateAlternateProtocolPrefs0) { // Post an update task to the IO thread. - http_server_props_manager_->ScheduleUpdatePrefsOnIO(); + http_server_props_manager_->ScheduleUpdateAlternateProtocolPrefsOnIO(); // Shutdown comes before the task is executed. http_server_props_manager_->ShutdownOnUIThread(); http_server_props_manager_.reset(); @@ -243,11 +424,11 @@ TEST_F(HttpServerPropertiesManagerTest, ShutdownWithPendingUpdatePrefs0) { loop_.RunAllPending(); } -TEST_F(HttpServerPropertiesManagerTest, ShutdownWithPendingUpdatePrefs1) { - EXPECT_CALL(*http_server_props_manager_, - SetSpdyServersInPrefsOnUI(_)).Times(0); +TEST_F(HttpServerPropertiesManagerTest, + ShutdownWithPendingUpdateAlternateProtocolPrefs1) { + ExpectAlternateProtocolPrefsUpdate(); // Post an update task. - http_server_props_manager_->ScheduleUpdatePrefsOnIO(); + http_server_props_manager_->ScheduleUpdateAlternateProtocolPrefsOnIO(); // Shutdown comes before the task is executed. http_server_props_manager_->ShutdownOnUIThread(); // Run the task after shutdown, but before deletion. @@ -257,11 +438,10 @@ TEST_F(HttpServerPropertiesManagerTest, ShutdownWithPendingUpdatePrefs1) { loop_.RunAllPending(); } -TEST_F(HttpServerPropertiesManagerTest, ShutdownWithPendingUpdatePrefs2) { - EXPECT_CALL(*http_server_props_manager_, - SetSpdyServersInPrefsOnUI(_)).Times(0); +TEST_F(HttpServerPropertiesManagerTest, + ShutdownWithPendingUpdateAlternateProtocolPrefs2) { // This posts a task to the UI thread. - http_server_props_manager_->UpdatePrefsFromCacheConcrete(); + http_server_props_manager_->UpdateAlternateProtocolPrefsFromCacheConcrete(); // Shutdown comes before the task is executed. http_server_props_manager_->ShutdownOnUIThread(); // Run the task after shutdown, but before deletion. |