diff options
author | akalin@chromium.org <akalin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-05-15 00:36:16 +0000 |
---|---|---|
committer | akalin@chromium.org <akalin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-05-15 00:36:16 +0000 |
commit | 82d9d295c3201f484710e9f519f98b02ebfe7b61 (patch) | |
tree | affec3d1e5ad4702fda0c5ca4b06cb569359e9ea /chrome | |
parent | bd33ed7ac21b7c7fbee5b716092092434f62a469 (diff) | |
download | chromium_src-82d9d295c3201f484710e9f519f98b02ebfe7b61.zip chromium_src-82d9d295c3201f484710e9f519f98b02ebfe7b61.tar.gz chromium_src-82d9d295c3201f484710e9f519f98b02ebfe7b61.tar.bz2 |
Replaced NetworkStatusDetector with use of NetworkChangeNotifier
from net/.
Removed NetworkStatusDetector files and related.
Cleaned up some test-related code.
BUG=19784
TEST=manually
Review URL: http://codereview.chromium.org/1451001
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@47344 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
37 files changed, 267 insertions, 1245 deletions
diff --git a/chrome/browser/profile.cc b/chrome/browser/profile.cc index 84f6b44..83c8ba7 100644 --- a/chrome/browser/profile.cc +++ b/chrome/browser/profile.cc @@ -54,6 +54,7 @@ #include "chrome/browser/sessions/session_service.h" #include "chrome/browser/sessions/tab_restore_service.h" #include "chrome/browser/ssl/ssl_host_state.h" +#include "chrome/browser/sync/net/network_change_notifier_io_thread.h" #include "chrome/browser/sync/profile_sync_service.h" #include "chrome/browser/sync/profile_sync_factory_impl.h" #include "chrome/browser/tabs/pinned_tab_service.h" @@ -1495,8 +1496,11 @@ CloudPrintProxyService* ProfileImpl::GetCloudPrintProxyService() { } void ProfileImpl::InitSyncService() { + network_change_notifier_thread_.reset( + new NetworkChangeNotifierIOThread(g_browser_process->io_thread())); profile_sync_factory_.reset( new ProfileSyncFactoryImpl(this, + network_change_notifier_thread_.get(), CommandLine::ForCurrentProcess())); sync_service_.reset( profile_sync_factory_->CreateProfileSyncService()); diff --git a/chrome/browser/profile.h b/chrome/browser/profile.h index b7d5c24..9871d77 100644 --- a/chrome/browser/profile.h +++ b/chrome/browser/profile.h @@ -21,6 +21,10 @@ #include "chrome/browser/chromeos/preferences.h" #endif +namespace chrome_common_net { +class NetworkChangeNotifierThread; +} + namespace net { class TransportSecurityState; class SSLConfigService; @@ -580,6 +584,9 @@ class ProfileImpl : public Profile, scoped_refptr<WebResourceService> web_resource_service_; scoped_ptr<NTPResourceCache> ntp_resource_cache_; + // Used by |profile_sync_factory_|. + scoped_ptr<chrome_common_net::NetworkChangeNotifierThread> + network_change_notifier_thread_; scoped_ptr<ProfileSyncFactory> profile_sync_factory_; scoped_ptr<ProfileSyncService> sync_service_; scoped_ptr<CloudPrintProxyService> cloud_print_proxy_service_; diff --git a/chrome/browser/sync/engine/auth_watcher_unittest.cc b/chrome/browser/sync/engine/auth_watcher_unittest.cc index f314155..6a0e3dc 100644 --- a/chrome/browser/sync/engine/auth_watcher_unittest.cc +++ b/chrome/browser/sync/engine/auth_watcher_unittest.cc @@ -10,6 +10,7 @@ #include "chrome/browser/sync/engine/auth_watcher.h" #include "chrome/browser/sync/util/user_settings.h" #include "chrome/common/deprecated/event_sys-inl.h" +#include "chrome/common/net/fake_network_change_notifier_thread.h" #include "chrome/common/net/http_return.h" #include "chrome/common/net/notifier/listener/talk_mediator_impl.h" #include "chrome/common/net/gaia/gaia_authenticator.h" @@ -103,7 +104,9 @@ class AuthWatcherTest : public testing::Test { FilePath user_settings_path = temp_dir_.path().Append(kUserSettingsDB); user_settings_->Init(user_settings_path); gaia_auth_ = new GaiaAuthMockForAuthWatcher(); - talk_mediator_.reset(new notifier::TalkMediatorImpl(false)); + fake_network_change_notifier_thread_.Start(); + talk_mediator_.reset(new notifier::TalkMediatorImpl( + &fake_network_change_notifier_thread_, false)); auth_watcher_ = new AuthWatcher(metadb_.manager(), connection_.get(), allstatus_.get(), kTestUserAgent, kTestServiceId, kTestGaiaURL, user_settings_.get(), gaia_auth_, talk_mediator_.get()); @@ -115,6 +118,8 @@ class AuthWatcherTest : public testing::Test { metadb_.TearDown(); auth_watcher_->Shutdown(); EXPECT_FALSE(auth_watcher()->message_loop()); + talk_mediator_.reset(); + fake_network_change_notifier_thread_.Stop(); } void HandleAuthWatcherEvent(const AuthWatcherEvent& event) { @@ -154,6 +159,9 @@ class AuthWatcherTest : public testing::Test { scoped_ptr<UserSettings> user_settings_; GaiaAuthMockForAuthWatcher* gaia_auth_; // Owned by auth_watcher_. scoped_ptr<notifier::TalkMediator> talk_mediator_; + // Needed by talk_mediator_. + chrome_common_net::FakeNetworkChangeNotifierThread + fake_network_change_notifier_thread_; scoped_refptr<AuthWatcher> auth_watcher_; // This is used to block the AuthWatcherThread when it raises events until we diff --git a/chrome/browser/sync/engine/syncapi.cc b/chrome/browser/sync/engine/syncapi.cc index bace7c4..e3e8fc5 100644 --- a/chrome/browser/sync/engine/syncapi.cc +++ b/chrome/browser/sync/engine/syncapi.cc @@ -31,12 +31,14 @@ #include "base/basictypes.h" #include "base/base64.h" #include "base/lock.h" +#include "base/logging.h" #include "base/platform_thread.h" #include "base/scoped_ptr.h" #include "base/sha1.h" #include "base/string_util.h" #include "base/task.h" #include "base/utf_string_conversions.h" +#include "chrome/browser/browser_process.h" #include "chrome/browser/sync/sync_constants.h" #include "chrome/browser/sync/engine/all_status.h" #include "chrome/browser/sync/engine/auth_watcher.h" @@ -1039,6 +1041,8 @@ class SyncManager::SyncInternal { const char* gaia_service_id, const char* gaia_source, bool use_ssl, + chrome_common_net::NetworkChangeNotifierThread* + network_change_notifier_thread, HttpPostProviderFactory* post_factory, HttpPostProviderFactory* auth_post_factory, ModelSafeWorkerRegistrar* model_safe_worker_registrar, @@ -1334,6 +1338,8 @@ bool SyncManager::Init(const FilePath& database_location, const char* gaia_service_id, const char* gaia_source, bool use_ssl, + chrome_common_net::NetworkChangeNotifierThread* + network_change_notifier_thread, HttpPostProviderFactory* post_factory, HttpPostProviderFactory* auth_post_factory, ModelSafeWorkerRegistrar* registrar, @@ -1352,6 +1358,7 @@ bool SyncManager::Init(const FilePath& database_location, gaia_service_id, gaia_source, use_ssl, + network_change_notifier_thread, post_factory, auth_post_factory, registrar, @@ -1392,7 +1399,10 @@ bool SyncManager::SyncInternal::Init( int port, const char* gaia_service_id, const char* gaia_source, - bool use_ssl, HttpPostProviderFactory* post_factory, + bool use_ssl, + chrome_common_net::NetworkChangeNotifierThread* + network_change_notifier_thread, + HttpPostProviderFactory* post_factory, HttpPostProviderFactory* auth_post_factory, ModelSafeWorkerRegistrar* model_safe_worker_registrar, bool attempt_last_user_authentication, @@ -1455,7 +1465,8 @@ bool SyncManager::SyncInternal::Init( const char* service_id = gaia_service_id ? gaia_service_id : SYNC_SERVICE_NAME; - talk_mediator_.reset(new TalkMediatorImpl(invalidate_xmpp_auth_token)); + talk_mediator_.reset(new TalkMediatorImpl( + network_change_notifier_thread, invalidate_xmpp_auth_token)); if (notification_method != browser_sync::NOTIFICATION_LEGACY) { if (notification_method == browser_sync::NOTIFICATION_TRANSITIONAL) { talk_mediator_->AddSubscribedServiceUrl( diff --git a/chrome/browser/sync/engine/syncapi.h b/chrome/browser/sync/engine/syncapi.h index edfd70f..6dc9501 100644 --- a/chrome/browser/sync/engine/syncapi.h +++ b/chrome/browser/sync/engine/syncapi.h @@ -59,6 +59,10 @@ struct SyncSessionSnapshot; } } +namespace chrome_common_net { +class NetworkChangeNotifierThread; +} + // Forward declarations of internal class types so that sync API objects // may have opaque pointers to these types. namespace syncable { @@ -649,6 +653,9 @@ class SyncManager { // the default is false. // |gaia_service_id| is the service id used for GAIA authentication. If it's // null then default will be used. + // |network_change_notifier_thread| (which we don't own) is the + // thread from which we get notifications regarding changes to the + // network state. // |post_factory| will be owned internally and used to create // instances of an HttpPostProvider. // |auth_post_factory| will be owned internally and used to create @@ -681,6 +688,8 @@ class SyncManager { const char* gaia_service_id, const char* gaia_source, bool use_ssl, + chrome_common_net::NetworkChangeNotifierThread* + network_change_notifier_thread, HttpPostProviderFactory* post_factory, HttpPostProviderFactory* auth_post_factory, browser_sync::ModelSafeWorkerRegistrar* registrar, diff --git a/chrome/browser/sync/glue/sync_backend_host.cc b/chrome/browser/sync/glue/sync_backend_host.cc index 647dbb1..5ae9366 100644 --- a/chrome/browser/sync/glue/sync_backend_host.cc +++ b/chrome/browser/sync/glue/sync_backend_host.cc @@ -65,6 +65,8 @@ SyncBackendHost::~SyncBackendHost() { void SyncBackendHost::Initialize( const GURL& sync_service_url, const syncable::ModelTypeSet& types, + chrome_common_net::NetworkChangeNotifierThread* + network_change_notifier_thread, URLRequestContextGetter* baseline_context_getter, const std::string& lsid, bool delete_sync_data_folder, @@ -99,6 +101,7 @@ void SyncBackendHost::Initialize( NewRunnableMethod(core_.get(), &SyncBackendHost::Core::DoInitialize, Core::DoInitializeOptions( sync_service_url, true, + network_change_notifier_thread, new HttpBridgeFactory(baseline_context_getter), new HttpBridgeFactory(baseline_context_getter), lsid, @@ -356,6 +359,7 @@ void SyncBackendHost::Core::DoInitialize(const DoInitializeOptions& options) { kGaiaServiceId, kGaiaSourceForChrome, options.service_url.SchemeIsSecure(), + options.network_change_notifier_thread, options.http_bridge_factory, options.auth_http_bridge_factory, host_, // ModelSafeWorkerRegistrar. diff --git a/chrome/browser/sync/glue/sync_backend_host.h b/chrome/browser/sync/glue/sync_backend_host.h index 1f44df9..7294acd 100644 --- a/chrome/browser/sync/glue/sync_backend_host.h +++ b/chrome/browser/sync/glue/sync_backend_host.h @@ -29,6 +29,10 @@ class CancelableTask; class Profile; +namespace chrome_common_net { +class NetworkChangeNotifierThread; +} + namespace browser_sync { namespace sessions { @@ -96,6 +100,8 @@ class SyncBackendHost : public browser_sync::ModelSafeWorkerRegistrar { // Optionally delete the Sync Data folder (if it's corrupt). void Initialize(const GURL& service_url, const syncable::ModelTypeSet& types, + chrome_common_net::NetworkChangeNotifierThread* + network_change_notifier_thread, URLRequestContextGetter* baseline_context_getter, const std::string& lsid, bool delete_sync_data_folder, @@ -168,6 +174,8 @@ class SyncBackendHost : public browser_sync::ModelSafeWorkerRegistrar { // Called from unit test to bypass authentication and initialize the syncapi // to a state suitable for testing but not production. void InitializeForTestMode(const std::wstring& test_user, + chrome_common_net::NetworkChangeNotifierThread* + network_change_notifier_thread, sync_api::HttpPostProviderFactory* factory, sync_api::HttpPostProviderFactory* auth_factory, bool delete_sync_data_folder, @@ -185,6 +193,7 @@ class SyncBackendHost : public browser_sync::ModelSafeWorkerRegistrar { NewRunnableMethod(core_.get(), &SyncBackendHost::Core::DoInitializeForTest, test_user, + network_change_notifier_thread, factory, auth_factory, delete_sync_data_folder, @@ -218,6 +227,8 @@ class SyncBackendHost : public browser_sync::ModelSafeWorkerRegistrar { DoInitializeOptions( const GURL& service_url, bool attempt_last_user_authentication, + chrome_common_net::NetworkChangeNotifierThread* + network_change_notifier_thread, sync_api::HttpPostProviderFactory* http_bridge_factory, sync_api::HttpPostProviderFactory* auth_http_bridge_factory, const std::string& lsid, @@ -227,6 +238,7 @@ class SyncBackendHost : public browser_sync::ModelSafeWorkerRegistrar { NotificationMethod notification_method) : service_url(service_url), attempt_last_user_authentication(attempt_last_user_authentication), + network_change_notifier_thread(network_change_notifier_thread), http_bridge_factory(http_bridge_factory), auth_http_bridge_factory(auth_http_bridge_factory), lsid(lsid), @@ -237,6 +249,8 @@ class SyncBackendHost : public browser_sync::ModelSafeWorkerRegistrar { GURL service_url; bool attempt_last_user_authentication; + chrome_common_net::NetworkChangeNotifierThread* + network_change_notifier_thread; sync_api::HttpPostProviderFactory* http_bridge_factory; sync_api::HttpPostProviderFactory* auth_http_bridge_factory; std::string lsid; @@ -289,12 +303,16 @@ class SyncBackendHost : public browser_sync::ModelSafeWorkerRegistrar { // last known user (since it will fail in test mode) and does some extra // setup to nudge the syncapi into a useable state. void DoInitializeForTest(const std::wstring& test_user, + chrome_common_net::NetworkChangeNotifierThread* + network_change_notifier_thread, sync_api::HttpPostProviderFactory* factory, sync_api::HttpPostProviderFactory* auth_factory, bool delete_sync_data_folder, NotificationMethod notification_method) { DoInitialize( - DoInitializeOptions(GURL(), false, factory, auth_factory, + DoInitializeOptions(GURL(), false, + network_change_notifier_thread, + factory, auth_factory, std::string(), delete_sync_data_folder, false, false, notification_method)); diff --git a/chrome/browser/sync/profile_sync_factory_impl.cc b/chrome/browser/sync/profile_sync_factory_impl.cc index b65b58c..3efbc76 100644 --- a/chrome/browser/sync/profile_sync_factory_impl.cc +++ b/chrome/browser/sync/profile_sync_factory_impl.cc @@ -3,6 +3,7 @@ // found in the LICENSE file. #include "base/command_line.h" +#include "base/logging.h" #include "chrome/browser/defaults.h" #include "chrome/browser/profile.h" #include "chrome/browser/sync/glue/autofill_change_processor.h" @@ -50,14 +51,20 @@ using browser_sync::UnrecoverableErrorHandler; ProfileSyncFactoryImpl::ProfileSyncFactoryImpl( Profile* profile, + chrome_common_net::NetworkChangeNotifierThread* + network_change_notifier_thread, CommandLine* command_line) - : profile_(profile), command_line_(command_line) { + : profile_(profile), + network_change_notifier_thread_(network_change_notifier_thread), + command_line_(command_line) { + DCHECK(network_change_notifier_thread_); } ProfileSyncService* ProfileSyncFactoryImpl::CreateProfileSyncService() { ProfileSyncService* pss = new ProfileSyncService(this, profile_, + network_change_notifier_thread_, browser_defaults::kBootstrapSyncAuthentication); // Autofill sync is disabled by default. diff --git a/chrome/browser/sync/profile_sync_factory_impl.h b/chrome/browser/sync/profile_sync_factory_impl.h index 68539b9..db8dba7 100644 --- a/chrome/browser/sync/profile_sync_factory_impl.h +++ b/chrome/browser/sync/profile_sync_factory_impl.h @@ -11,9 +11,17 @@ class CommandLine; class Profile; +namespace chrome_common_net { +class NetworkChangeNotifierThread; +} + class ProfileSyncFactoryImpl : public ProfileSyncFactory { public: - ProfileSyncFactoryImpl(Profile* profile, CommandLine* command_line); + ProfileSyncFactoryImpl( + Profile* profile, + chrome_common_net::NetworkChangeNotifierThread* + network_change_notifier_thread, + CommandLine* command_line); virtual ~ProfileSyncFactoryImpl() {} // ProfileSyncFactory interface. @@ -48,6 +56,8 @@ class ProfileSyncFactoryImpl : public ProfileSyncFactory { private: Profile* profile_; + chrome_common_net::NetworkChangeNotifierThread* + network_change_notifier_thread_; CommandLine* command_line_; DISALLOW_COPY_AND_ASSIGN(ProfileSyncFactoryImpl); diff --git a/chrome/browser/sync/profile_sync_factory_impl_unittest.cc b/chrome/browser/sync/profile_sync_factory_impl_unittest.cc index 55d3a05..a483438 100644 --- a/chrome/browser/sync/profile_sync_factory_impl_unittest.cc +++ b/chrome/browser/sync/profile_sync_factory_impl_unittest.cc @@ -13,6 +13,7 @@ #include "chrome/browser/sync/profile_sync_service.h" #include "chrome/browser/sync/profile_sync_factory_impl.h" #include "chrome/common/chrome_switches.h" +#include "chrome/common/net/fake_network_change_notifier_thread.h" #include "chrome/test/testing_profile.h" using browser_sync::DataTypeController; @@ -27,13 +28,17 @@ class ProfileSyncFactoryImplTest : public testing::Test { FilePath program_path(FILE_PATH_LITERAL("chrome.exe")); command_line_.reset(new CommandLine(program_path)); profile_sync_service_factory_.reset( - new ProfileSyncFactoryImpl(profile_.get(), command_line_.get())); + new ProfileSyncFactoryImpl(profile_.get(), + &fake_network_change_notifier_thread_, + command_line_.get())); } MessageLoop message_loop_; ChromeThread ui_thread_; scoped_ptr<Profile> profile_; scoped_ptr<CommandLine> command_line_; + chrome_common_net::FakeNetworkChangeNotifierThread + fake_network_change_notifier_thread_; scoped_ptr<ProfileSyncFactoryImpl> profile_sync_service_factory_; }; diff --git a/chrome/browser/sync/profile_sync_service.cc b/chrome/browser/sync/profile_sync_service.cc index a3672c0..5562211 100644 --- a/chrome/browser/sync/profile_sync_service.cc +++ b/chrome/browser/sync/profile_sync_service.cc @@ -13,6 +13,7 @@ #include "base/file_path.h" #include "base/file_util.h" #include "base/histogram.h" +#include "base/logging.h" #include "base/stl_util-inl.h" #include "base/string_util.h" #include "base/task.h" @@ -45,12 +46,16 @@ typedef GoogleServiceAuthError AuthError; // Default sync server URL. static const char kSyncServerUrl[] = "https://clients4.google.com/chrome-sync"; -ProfileSyncService::ProfileSyncService(ProfileSyncFactory* factory, - Profile* profile, - bool bootstrap_sync_authentication) +ProfileSyncService::ProfileSyncService( + ProfileSyncFactory* factory, + Profile* profile, + chrome_common_net::NetworkChangeNotifierThread* + network_change_notifier_thread, + bool bootstrap_sync_authentication) : last_auth_error_(AuthError::None()), factory_(factory), profile_(profile), + network_change_notifier_thread_(network_change_notifier_thread), bootstrap_sync_authentication_(bootstrap_sync_authentication), sync_service_url_(kSyncServerUrl), backend_initialized_(false), @@ -60,6 +65,9 @@ ProfileSyncService::ProfileSyncService(ProfileSyncFactory* factory, unrecoverable_error_detected_(false), notification_method_(browser_sync::kDefaultNotificationMethod), ALLOW_THIS_IN_INITIALIZER_LIST(scoped_runnable_method_factory_(this)) { + DCHECK(factory); + DCHECK(profile); + DCHECK(network_change_notifier_thread_); registrar_.Add(this, NotificationType::SYNC_CONFIGURE_START, NotificationService::AllSources()); @@ -68,6 +76,22 @@ ProfileSyncService::ProfileSyncService(ProfileSyncFactory* factory, NotificationService::AllSources()); } +ProfileSyncService::ProfileSyncService() + : last_auth_error_(AuthError::None()), + factory_(NULL), + profile_(NULL), + network_change_notifier_thread_(NULL), + bootstrap_sync_authentication_(false), + sync_service_url_(kSyncServerUrl), + backend_initialized_(false), + expecting_first_run_auth_needed_event_(false), + is_auth_in_progress_(false), + ALLOW_THIS_IN_INITIALIZER_LIST(wizard_(this)), + unrecoverable_error_detected_(false), + notification_method_(browser_sync::kDefaultNotificationMethod), + ALLOW_THIS_IN_INITIALIZER_LIST(scoped_runnable_method_factory_(this)) { +} + ProfileSyncService::~ProfileSyncService() { Shutdown(false); } @@ -221,6 +245,7 @@ void ProfileSyncService::InitializeBackend(bool delete_sync_data_folder) { GetPreferredDataTypes(&types); backend_->Initialize(sync_service_url_, types, + network_change_notifier_thread_, profile_->GetRequestContext(), GetLsidForAuthBootstraping(), delete_sync_data_folder, diff --git a/chrome/browser/sync/profile_sync_service.h b/chrome/browser/sync/profile_sync_service.h index 86e3673..58ee746 100644 --- a/chrome/browser/sync/profile_sync_service.h +++ b/chrome/browser/sync/profile_sync_service.h @@ -31,6 +31,10 @@ class NotificationType; class Profile; class ProfileSyncFactory; +namespace chrome_common_net { +class NetworkChangeNotifierThread; +} + // Various UI components such as the New Tab page can be driven by observing // the ProfileSyncService through this interface. class ProfileSyncServiceObserver { @@ -119,6 +123,8 @@ class ProfileSyncService : public browser_sync::SyncFrontend, ProfileSyncService(ProfileSyncFactory* factory_, Profile* profile, + chrome_common_net::NetworkChangeNotifierThread* + network_change_notifier_thread, bool bootstrap_sync_authentication); virtual ~ProfileSyncService(); @@ -272,6 +278,13 @@ class ProfileSyncService : public browser_sync::SyncFrontend, syncable::ModelTypeSet* registered_types) const; protected: + // Used by ProfileSyncServiceMock only. + // + // TODO(akalin): Separate this class out into an abstract + // ProfileSyncService interface and a ProfileSyncServiceImpl class + // so we don't need this hack anymore. + ProfileSyncService(); + // Call this after any of the subsystems being synced (the bookmark // model and the sync backend) finishes its initialization. When everything // is ready, this function will bootstrap the subsystems so that they are @@ -336,6 +349,9 @@ class ProfileSyncService : public browser_sync::SyncFrontend, // The profile whose data we are synchronizing. Profile* profile_; + chrome_common_net::NetworkChangeNotifierThread* + network_change_notifier_thread_; + // True if the profile sync service should attempt to use an LSID // cookie for authentication. This is typically set to true in // ChromiumOS since we want to use the system level authentication diff --git a/chrome/browser/sync/profile_sync_service_autofill_unittest.cc b/chrome/browser/sync/profile_sync_service_autofill_unittest.cc index 7679732..25225fa 100644 --- a/chrome/browser/sync/profile_sync_service_autofill_unittest.cc +++ b/chrome/browser/sync/profile_sync_service_autofill_unittest.cc @@ -24,6 +24,7 @@ #include "chrome/browser/sync/profile_sync_factory_mock.h" #include "chrome/browser/sync/profile_sync_service.h" #include "chrome/browser/sync/profile_sync_test_util.h" +#include "chrome/browser/sync/test_profile_sync_service.h" #include "chrome/browser/sync/protocol/autofill_specifics.pb.h" #include "chrome/browser/sync/syncable/directory_manager.h" #include "chrome/browser/sync/test_profile_sync_service.h" diff --git a/chrome/browser/sync/profile_sync_service_mock.h b/chrome/browser/sync/profile_sync_service_mock.h index 13791a8..539c275 100644 --- a/chrome/browser/sync/profile_sync_service_mock.h +++ b/chrome/browser/sync/profile_sync_service_mock.h @@ -16,7 +16,7 @@ class ProfileSyncServiceMock : public ProfileSyncService { public: - ProfileSyncServiceMock() : ProfileSyncService(NULL, NULL, false) {} + ProfileSyncServiceMock() {} virtual ~ProfileSyncServiceMock() {} MOCK_METHOD0(EnableForUser, void()); diff --git a/chrome/browser/sync/sync_setup_wizard_unittest.cc b/chrome/browser/sync/sync_setup_wizard_unittest.cc index 895ab3c..ca63f97 100644 --- a/chrome/browser/sync/sync_setup_wizard_unittest.cc +++ b/chrome/browser/sync/sync_setup_wizard_unittest.cc @@ -14,6 +14,7 @@ #include "chrome/browser/sync/profile_sync_factory_mock.h" #include "chrome/browser/sync/profile_sync_service.h" #include "chrome/browser/sync/sync_setup_flow.h" +#include "chrome/common/net/fake_network_change_notifier_thread.h" #include "chrome/common/pref_names.h" #include "chrome/test/browser_with_test_window_test.h" #include "chrome/test/testing_profile.h" @@ -31,7 +32,9 @@ typedef GoogleServiceAuthError AuthError; class ProfileSyncServiceForWizardTest : public ProfileSyncService { public: ProfileSyncServiceForWizardTest(ProfileSyncFactory* factory, Profile* profile) - : ProfileSyncService(factory, profile, false), + : ProfileSyncService(factory, profile, + &fake_network_change_notifier_thread_, + false), user_accepted_merge_and_sync_(false), user_cancelled_dialog_(false) { RegisterPreferences(); @@ -78,6 +81,9 @@ class ProfileSyncServiceForWizardTest : public ProfileSyncService { bool user_cancelled_dialog_; private: + chrome_common_net::FakeNetworkChangeNotifierThread + fake_network_change_notifier_thread_; + DISALLOW_COPY_AND_ASSIGN(ProfileSyncServiceForWizardTest); }; diff --git a/chrome/browser/sync/test_profile_sync_service.h b/chrome/browser/sync/test_profile_sync_service.h index d8c7a1e..43be463 100644 --- a/chrome/browser/sync/test_profile_sync_service.h +++ b/chrome/browser/sync/test_profile_sync_service.h @@ -11,6 +11,7 @@ #include "chrome/browser/profile.h" #include "chrome/browser/sync/profile_sync_factory.h" #include "chrome/browser/sync/profile_sync_service.h" +#include "chrome/common/net/fake_network_change_notifier_thread.h" #include "chrome/test/sync/test_http_bridge_factory.h" class TestProfileSyncService : public ProfileSyncService { @@ -19,7 +20,9 @@ class TestProfileSyncService : public ProfileSyncService { Profile* profile, bool bootstrap_sync_authentication, bool synchronous_backend_initialization) - : ProfileSyncService(factory, profile, bootstrap_sync_authentication), + : ProfileSyncService(factory, profile, + &fake_network_change_notifier_thread_, + bootstrap_sync_authentication), synchronous_backend_initialization_( synchronous_backend_initialization) { RegisterPreferences(); @@ -33,8 +36,10 @@ class TestProfileSyncService : public ProfileSyncService { new browser_sync::TestHttpBridgeFactory(); browser_sync::TestHttpBridgeFactory* factory2 = new browser_sync::TestHttpBridgeFactory(); - backend()->InitializeForTestMode(L"testuser", factory, factory2, - delete_sync_data_folder, browser_sync::kDefaultNotificationMethod); + backend()->InitializeForTestMode( + L"testuser", &fake_network_change_notifier_thread_, + factory, factory2, delete_sync_data_folder, + browser_sync::kDefaultNotificationMethod); // TODO(akalin): Figure out a better way to do this. if (synchronous_backend_initialization_) { // The SyncBackend posts a task to the current loop when @@ -62,6 +67,8 @@ class TestProfileSyncService : public ProfileSyncService { } bool synchronous_backend_initialization_; + chrome_common_net::FakeNetworkChangeNotifierThread + fake_network_change_notifier_thread_; }; #endif // CHROME_BROWSER_SYNC_TEST_PROFILE_SYNC_SERVICE_H_ diff --git a/chrome/chrome.gyp b/chrome/chrome.gyp index c216d41..d05dd8a 100644 --- a/chrome/chrome.gyp +++ b/chrome/chrome.gyp @@ -704,17 +704,9 @@ 'sources': [ 'common/net/notifier/base/async_dns_lookup.cc', 'common/net/notifier/base/async_dns_lookup.h', - 'common/net/notifier/base/async_network_alive.h', 'common/net/notifier/base/fastalloc.h', - 'common/net/notifier/base/linux/async_network_alive_linux.cc', - 'common/net/notifier/base/mac/network_status_detector_task_mac.h', - 'common/net/notifier/base/mac/network_status_detector_task_mac.cc', 'common/net/notifier/base/nethelpers.cc', 'common/net/notifier/base/nethelpers.h', - 'common/net/notifier/base/network_status_detector_task.cc', - 'common/net/notifier/base/network_status_detector_task.h', - 'common/net/notifier/base/network_status_detector_task_mt.cc', - 'common/net/notifier/base/network_status_detector_task_mt.h', 'common/net/notifier/base/posix/time_posix.cc', 'common/net/notifier/base/signal_thread_task.h', 'common/net/notifier/base/ssl_adapter.h', @@ -727,7 +719,6 @@ 'common/net/notifier/base/timer.cc', 'common/net/notifier/base/timer.h', 'common/net/notifier/base/utils.h', - 'common/net/notifier/base/win/async_network_alive_win32.cc', 'common/net/notifier/base/win/time_win32.cc', 'common/net/notifier/communicator/auto_reconnect.cc', 'common/net/notifier/communicator/auto_reconnect.h', @@ -788,6 +779,7 @@ '../net/net.gyp:net', '../third_party/expat/expat.gyp:expat', '../third_party/libjingle/libjingle.gyp:libjingle', + 'common_net', ], 'conditions': [ ['OS=="linux" or OS=="freebsd" or OS=="openbsd" or OS=="solaris"', { diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi index 62bda72..ceaa7e2 100644 --- a/chrome/chrome_tests.gypi +++ b/chrome/chrome_tests.gypi @@ -1784,7 +1784,6 @@ # TODO(akalin): Write our own test suite and runner. '../base/test/run_all_unittests.cc', '../base/test/test_suite.h', - 'common/net/notifier/base/mac/network_status_detector_task_mac_unittest.cc', 'common/net/notifier/listener/talk_mediator_unittest.cc', 'common/net/notifier/listener/send_update_task_unittest.cc', 'common/net/notifier/listener/subscribe_task_unittest.cc', @@ -1794,6 +1793,7 @@ '..', ], 'dependencies': [ + 'common_net_test_support', 'notifier', '../base/base.gyp:base', '../testing/gmock.gyp:gmock', @@ -1867,6 +1867,7 @@ 'dependencies': [ 'browser/sync/protocol/sync_proto.gyp:sync_proto_cpp', 'common', + 'common_net_test_support', 'debugger', '../skia/skia.gyp:skia', '../testing/gmock.gyp:gmock', diff --git a/chrome/common/net/notifier/base/async_network_alive.h b/chrome/common/net/notifier/base/async_network_alive.h deleted file mode 100644 index 5a2c707..0000000 --- a/chrome/common/net/notifier/base/async_network_alive.h +++ /dev/null @@ -1,53 +0,0 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_COMMON_NET_NOTIFIER_BASE_ASYNC_NETWORK_ALIVE_H_ -#define CHROME_COMMON_NET_NOTIFIER_BASE_ASYNC_NETWORK_ALIVE_H_ - -#include "talk/base/signalthread.h" - -namespace notifier { - -// System specific info needed for changes. -class PlatformNetworkInfo; - -class AsyncNetworkAlive : public talk_base::SignalThread { - public: - static AsyncNetworkAlive* Create(); - - virtual ~AsyncNetworkAlive() {} - - bool alive() const { - return alive_; - } - - bool error() const { - return error_; - } - - void SetWaitForNetworkChange(PlatformNetworkInfo* previous_info) { - network_info_ = previous_info; - } - - PlatformNetworkInfo* ReleaseInfo() { - PlatformNetworkInfo* info = network_info_; - network_info_ = NULL; - return info; - } - - protected: - AsyncNetworkAlive() : network_info_(NULL), alive_(false), error_(false) { - } - - PlatformNetworkInfo* network_info_; - bool alive_; - bool error_; - - private: - DISALLOW_COPY_AND_ASSIGN(AsyncNetworkAlive); -}; - -} // namespace notifier - -#endif // CHROME_COMMON_NET_NOTIFIER_BASE_ASYNC_NETWORK_ALIVE_H_ diff --git a/chrome/common/net/notifier/base/linux/async_network_alive_linux.cc b/chrome/common/net/notifier/base/linux/async_network_alive_linux.cc deleted file mode 100644 index 4accbf3..0000000 --- a/chrome/common/net/notifier/base/linux/async_network_alive_linux.cc +++ /dev/null @@ -1,144 +0,0 @@ -// Copyright (c) 2010 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/common/net/notifier/base/async_network_alive.h" - -#include <sys/socket.h> -#include <asm/types.h> -#include <linux/netlink.h> -#include <linux/rtnetlink.h> - -#include "base/logging.h" -#include "base/platform_file.h" -#include "talk/base/physicalsocketserver.h" - -using base::kInvalidPlatformFileValue; - -namespace notifier { - -class AsyncNetworkAliveLinux : public AsyncNetworkAlive { - public: - AsyncNetworkAliveLinux() { - if (pipe(exit_pipe_) == -1) { - PLOG(ERROR) << "Could not create pipe for exit signal."; - exit_pipe_[0] = kInvalidPlatformFileValue; - exit_pipe_[1] = kInvalidPlatformFileValue; - } - } - - virtual ~AsyncNetworkAliveLinux() { - if (exit_pipe_[1] != kInvalidPlatformFileValue) { - // Ensure that we've signalled the thread to quit. - char data = 0; - if (write(exit_pipe_[1], &data, 1) == -1) { - PLOG(WARNING) << "Error sending error signal to AsyncNetworkAliveLinux"; - } - close(exit_pipe_[1]); - exit_pipe_[1] = kInvalidPlatformFileValue; - } - if (exit_pipe_[0] != kInvalidPlatformFileValue) { - close(exit_pipe_[0]); - exit_pipe_[0] = kInvalidPlatformFileValue; - } - } - - protected: - // SignalThread Interface - virtual void DoWork() { - if (exit_pipe_[0] == kInvalidPlatformFileValue) { - PLOG(ERROR) << "No exit flag to listen for."; - // If we don't have an exit flag to listen for, set the error flag and - // abort. - error_ = true; - return; - } - - // This function listens for changes to network interfaces, and link state. - // It's copied from syncapi.cc. - struct sockaddr_nl socket_address; - - memset(&socket_address, 0, sizeof(socket_address)); - socket_address.nl_family = AF_NETLINK; - socket_address.nl_groups = RTMGRP_LINK | RTMGRP_IPV4_IFADDR; - - // NETLINK_ROUTE is the protocol used to update the kernel routing table. - int fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE); - bind(fd, (struct sockaddr *) &socket_address, sizeof(socket_address)); - - fd_set rdfs; - FD_ZERO(&rdfs); - FD_SET(fd, &rdfs); - FD_SET(exit_pipe_[0], &rdfs); - - int max_fd = fd > exit_pipe_[0] ? fd : exit_pipe_[0]; - - int result = select(max_fd + 1, &rdfs, NULL, NULL, NULL); - - if (result <= 0) { - error_ = true; - PLOG(ERROR) << "select() returned unexpected result " << result; - close(fd); - close(exit_pipe_[0]); - exit_pipe_[0] = kInvalidPlatformFileValue; - return; - } - - // Since we received a change from the socket, read the change in. - if (FD_ISSET(fd, &rdfs)) { - char buf[4096]; - struct iovec iov = { buf, sizeof(buf) }; - struct sockaddr_nl sa; - - struct msghdr msg = { (void *)&sa, sizeof(sa), &iov, 1, NULL, 0, 0 }; - recvmsg(fd, &msg, 0); - } - - close(fd); - - // If exit_pipe was written to, we must be shutting down. - if (exit_pipe_[0] == kInvalidPlatformFileValue || - FD_ISSET(exit_pipe_[0], &rdfs)) { - alive_ = false; - error_ = true; - close(exit_pipe_[0]); - exit_pipe_[0] = kInvalidPlatformFileValue; - return; - } - - // If there is an active connection, check that talk.google.com:5222 - // is reachable. - talk_base::PhysicalSocketServer physical; - scoped_ptr<talk_base::Socket> socket(physical.CreateSocket(SOCK_STREAM)); - if (socket->Connect(talk_base::SocketAddress("talk.google.com", 5222))) { - alive_ = false; - } else { - alive_ = true; - } - - close(exit_pipe_[0]); - exit_pipe_[0] = kInvalidPlatformFileValue; - } - - virtual void OnWorkStop() { - if (exit_pipe_[1] != kInvalidPlatformFileValue) { - char data = 0; - // We can't ignore the return value on write(), since that generates a - // compile warning. However, since we're exiting, there's nothing we can - // do if this fails except to log it. - if (write(exit_pipe_[1], &data, 1) == -1) { - PLOG(WARNING) << "Error sending error signal to AsyncNetworkAliveLinux"; - } - } - } - - private: - int exit_pipe_[2]; - DISALLOW_COPY_AND_ASSIGN(AsyncNetworkAliveLinux); -}; - -AsyncNetworkAlive* AsyncNetworkAlive::Create() { - return new AsyncNetworkAliveLinux(); -} - -} // namespace notifier diff --git a/chrome/common/net/notifier/base/mac/network_status_detector_task_mac.cc b/chrome/common/net/notifier/base/mac/network_status_detector_task_mac.cc deleted file mode 100644 index acebcd3..0000000 --- a/chrome/common/net/notifier/base/mac/network_status_detector_task_mac.cc +++ /dev/null @@ -1,262 +0,0 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/common/net/notifier/base/mac/network_status_detector_task_mac.h" - -#include <SystemConfiguration/SCNetworkReachability.h> - -#include "base/logging.h" -#include "base/scoped_cftyperef.h" -#include "base/scoped_ptr.h" -#include "base/string_util.h" -#include "base/sys_string_conversions.h" -#include "talk/base/physicalsocketserver.h" -#include "talk/base/socket.h" -#include "talk/base/thread.h" - -namespace notifier { - -NetworkStatusDetectorTaskMac::WorkerInfo::WorkerInfo( - PlatformThreadId thread_id) - : thread_state(WORKER_THREAD_STOPPED), - thread_id(thread_id), - thread_run_loop(NULL) {} - -NetworkStatusDetectorTaskMac::WorkerInfo::WorkerInfo( - WorkerThreadState thread_state, - PlatformThreadId thread_id, - CFRunLoopRef thread_run_loop) - : thread_state(thread_state), - thread_id(thread_id), - thread_run_loop(thread_run_loop) { - DCHECK_EQ(thread_state == WORKER_THREAD_RUNNING, thread_run_loop != NULL); -} - -NetworkStatusDetectorTaskMac::NetworkStatusDetectorTaskMac( - talk_base::Task* parent) - : NetworkStatusDetectorTask(parent), - parent_thread_id_(PlatformThread::CurrentId()), - parent_thread_(talk_base::Thread::Current()), - worker_thread_(kNullThreadHandle), - worker_thread_not_stopped_(&worker_lock_), - worker_shared_info_(parent_thread_id_) { - DCHECK(parent_thread_); - DCHECK(IsOnParentThread()); -} - -NetworkStatusDetectorTaskMac::~NetworkStatusDetectorTaskMac() { - ClearWorker(); -} - -void NetworkStatusDetectorTaskMac::ClearWorker() { - DCHECK(IsOnParentThread()); - // Sadly, there's no Lock::AssertNotAcquired(). - WorkerThreadState worker_thread_state; - CFRunLoopRef worker_thread_run_loop; - { - AutoLock auto_lock(worker_lock_); - worker_thread_state = worker_shared_info_.thread_state; - worker_thread_run_loop = worker_shared_info_.thread_run_loop; - } - if (worker_thread_state == WORKER_THREAD_RUNNING) { - CFRunLoopStop(worker_thread_run_loop); - } - if (worker_thread_ != kNullThreadHandle) { - DCHECK_NE(worker_thread_state, WORKER_THREAD_STOPPED); - PlatformThread::Join(worker_thread_); - } - - worker_thread_ = kNullThreadHandle; - worker_shared_info_ = WorkerInfo(parent_thread_id_); -} - -bool NetworkStatusDetectorTaskMac::IsOnParentThread() const { - return PlatformThread::CurrentId() == parent_thread_id_; -} - -bool NetworkStatusDetectorTaskMac::IsOnWorkerThread() { - PlatformThreadId current_thread_id = PlatformThread::CurrentId(); - AutoLock auto_lock(worker_lock_); - return - (worker_shared_info_.thread_id != parent_thread_id_) && - (current_thread_id == worker_shared_info_.thread_id); -} - -int NetworkStatusDetectorTaskMac::ProcessStart() { - DCHECK(IsOnParentThread()); - if (logging::DEBUG_MODE) { - AutoLock auto_lock(worker_lock_); - DCHECK_EQ(worker_shared_info_.thread_state, WORKER_THREAD_STOPPED); - DCHECK(!worker_shared_info_.thread_run_loop); - DCHECK_EQ(worker_shared_info_.thread_id, parent_thread_id_); - } - - if (!PlatformThread::Create(0, this, &worker_thread_)) { - LOG(WARNING) << "Could not create network reachability thread"; - ClearWorker(); - return STATE_ERROR; - } - - // Wait for the just-created worker thread to start up and - // initialize itself. - WorkerThreadState worker_thread_state; - { - AutoLock auto_lock(worker_lock_); - while (worker_shared_info_.thread_state == WORKER_THREAD_STOPPED) { - worker_thread_not_stopped_.Wait(); - } - worker_thread_state = worker_shared_info_.thread_state; - } - - if (worker_thread_state == WORKER_THREAD_ERROR) { - ClearWorker(); - return STATE_ERROR; - } - - if (logging::DEBUG_MODE) { - AutoLock auto_lock(worker_lock_); - DCHECK_EQ(worker_shared_info_.thread_state, WORKER_THREAD_RUNNING); - DCHECK(worker_shared_info_.thread_run_loop); - DCHECK_NE(worker_shared_info_.thread_id, parent_thread_id_); - } - - return STATE_RESPONSE; -} - -void NetworkStatusDetectorTaskMac::Stop() { - ClearWorker(); - NetworkStatusDetectorTask::Stop(); -} - -void NetworkStatusDetectorTaskMac::OnMessage(talk_base::Message* message) { - DCHECK(IsOnParentThread()); - bool alive = message->message_id; - SetNetworkAlive(alive); -} - -NetworkStatusDetectorTask* NetworkStatusDetectorTask::Create( - talk_base::Task* parent) { - return new NetworkStatusDetectorTaskMac(parent); -} - -// Everything below is run in the worker thread. - -namespace { - -// TODO(akalin): Use these constants across all platform -// implementations. -const char kTalkHost[] = "talk.google.com"; -const int kTalkPort = 5222; - -CFStringRef NetworkReachabilityCopyDescription(const void *info) { - return base::SysUTF8ToCFStringRef( - StringPrintf("NetworkStatusDetectorTaskMac(0x%p)", info)); -} - -void NetworkReachabilityChangedCallback(SCNetworkReachabilityRef target, - SCNetworkConnectionFlags flags, - void* info) { - bool network_active = ((flags & (kSCNetworkFlagsReachable | - kSCNetworkFlagsConnectionRequired | - kSCNetworkFlagsConnectionAutomatic | - kSCNetworkFlagsInterventionRequired)) == - kSCNetworkFlagsReachable); - NetworkStatusDetectorTaskMac* network_status_detector_task_mac = - static_cast<NetworkStatusDetectorTaskMac*>(info); - network_status_detector_task_mac->NetworkReachabilityChanged( - network_active); -} - - -SCNetworkReachabilityRef CreateAndScheduleNetworkReachability( - SCNetworkReachabilityContext* network_reachability_context) { - scoped_cftyperef<SCNetworkReachabilityRef> network_reachability( - SCNetworkReachabilityCreateWithName(kCFAllocatorDefault, kTalkHost)); - if (!network_reachability.get()) { - LOG(WARNING) << "Could not create network reachability object"; - return NULL; - } - - if (!SCNetworkReachabilitySetCallback(network_reachability.get(), - &NetworkReachabilityChangedCallback, - network_reachability_context)) { - LOG(WARNING) << "Could not set network reachability callback"; - return NULL; - } - - if (!SCNetworkReachabilityScheduleWithRunLoop(network_reachability.get(), - CFRunLoopGetCurrent(), - kCFRunLoopDefaultMode)) { - LOG(WARNING) << "Could not schedule network reachability with run loop"; - return NULL; - } - - return network_reachability.release(); -} - -} // namespace - -void NetworkStatusDetectorTaskMac::ThreadMain() { - DCHECK(!IsOnParentThread()); - PlatformThread::SetName("NetworkStatusDetectorTaskMac worker thread"); - - SCNetworkReachabilityContext network_reachability_context; - network_reachability_context.version = 0; - network_reachability_context.info = static_cast<void *>(this); - network_reachability_context.retain = NULL; - network_reachability_context.release = NULL; - network_reachability_context.copyDescription = - &NetworkReachabilityCopyDescription; - - PlatformThreadId worker_thread_id = PlatformThread::CurrentId(); - - scoped_cftyperef<SCNetworkReachabilityRef> network_reachability( - CreateAndScheduleNetworkReachability(&network_reachability_context)); - if (!network_reachability.get()) { - { - AutoLock auto_lock(worker_lock_); - worker_shared_info_ = - WorkerInfo(WORKER_THREAD_ERROR, worker_thread_id, NULL); - } - worker_thread_not_stopped_.Signal(); - return; - } - - CFRunLoopRef run_loop = CFRunLoopGetCurrent(); - { - AutoLock auto_lock(worker_lock_); - worker_shared_info_ = - WorkerInfo(WORKER_THREAD_RUNNING, worker_thread_id, run_loop); - } - worker_thread_not_stopped_.Signal(); - - DCHECK(IsOnWorkerThread()); - CFRunLoopRun(); - - // We reach here only when our run loop is stopped (usually by the - // parent thread). The parent thread is responsible for resetting - // worker_thread_shared_info_, et al. to appropriate values. -} - -void NetworkStatusDetectorTaskMac::NetworkReachabilityChanged( - bool network_active) { - DCHECK(IsOnWorkerThread()); - - bool alive = network_active; - if (alive) { - talk_base::PhysicalSocketServer physical; - scoped_ptr<talk_base::Socket> socket(physical.CreateSocket(SOCK_STREAM)); - alive = - (socket->Connect(talk_base::SocketAddress(kTalkHost, kTalkPort)) == 0); - LOG(INFO) << "network is " << (alive ? "alive" : "not alive") - << " based on connecting to " << kTalkHost << ":" << kTalkPort; - } else { - LOG(INFO) << "network is not alive"; - } - - parent_thread_->Send(this, alive); -} - -} // namespace notifier - diff --git a/chrome/common/net/notifier/base/mac/network_status_detector_task_mac.h b/chrome/common/net/notifier/base/mac/network_status_detector_task_mac.h deleted file mode 100644 index c844a33..0000000 --- a/chrome/common/net/notifier/base/mac/network_status_detector_task_mac.h +++ /dev/null @@ -1,154 +0,0 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_COMMON_NET_NOTIFIER_BASE_MAC_NETWORK_STATUS_DETECTOR_TASK_MAC_H_ -#define CHROME_COMMON_NET_NOTIFIER_BASE_MAC_NETWORK_STATUS_DETECTOR_TASK_MAC_H_ - -#include <CoreFoundation/CoreFoundation.h> - -#include "base/basictypes.h" -#include "base/condition_variable.h" -#include "base/lock.h" -#include "base/platform_thread.h" -#include "chrome/common/net/notifier/base/network_status_detector_task.h" -#include "talk/base/messagequeue.h" -#include "testing/gtest/include/gtest/gtest_prod.h" - -namespace talk_base { -class Message; -class Task; -class Thread; -} // namespace talk_base - -namespace notifier { - -// The Mac OS X network status detector works as follows: a worker -// (Chrome platform) thread is spawned which simply sets up a Cocoa -// run loop and attaches the network reachability monitor to it. -// Whenever the network reachability changes, (e.g., changed wireless -// networks, unplugged ethernet cable) a callback on the worker -// thread is triggered which then tries to connect to a Google talk -// host (if the network is indicated to be up) and sends a message -// with the result to the parent thread. - -class NetworkStatusDetectorTaskMac : public NetworkStatusDetectorTask, - public PlatformThread::Delegate, - public talk_base::MessageHandler { - public: - explicit NetworkStatusDetectorTaskMac(talk_base::Task* parent); - - virtual ~NetworkStatusDetectorTaskMac(); - - // talk_base::Task functions (via NetworkStatusDetectorTask). - virtual int ProcessStart(); - virtual void Stop(); - - // talk_base::MessageHandler functions. - // Currently OnMessage() simply calls SetNetworkAlive() with alive - // set to true iff message->message_id is non-zero. - virtual void OnMessage(talk_base::Message* message); - - // Only the following public functions are called from the worker - // thread. - - // PlatformThread::Delegate functions. - virtual void ThreadMain(); - - // Called when network reachability changes. network_active should - // be set only when the network is currently active and connecting - // to a host won't require any user intervention or create a network - // connection (e.g., prompting for a password, causing a modem to - // dial). - void NetworkReachabilityChanged(bool network_active); - - private: - enum WorkerThreadState { - WORKER_THREAD_STOPPED = 1, - WORKER_THREAD_RUNNING, - WORKER_THREAD_ERROR, - }; - - // If thread_state => WORKER_THREAD_STOPPED: - // - // thread_id => parent_thread_id_ - // thread_run_loop => NULL - // possible successor states => - // { WORKER_THREAD_RUNNING, WORKER_THREAD_ERROR } - // - // If thread_state => WORKER_THREAD_RUNNING, the worker thread is - // successfully running and will continue to run until Stop() is - // called. - // - // thread_id => id of worker thread (!= parent_thread_id_) - // thread_run_loop => reference to the worker thread's run loop - // possible successor states => { WORKER_THREAD_STOPPED } - // - // If thread_state => WORKER_THREAD_ERROR, the worker thread has - // failed to start running and has stopped. Join() must be still - // called on the worker thread. - // - // thread_id => id of worker thread (!= parent_thread_id_) - // thread_run_loop => NULL - // possible successor states => { WORKER_THREAD_STOPPED } - // - // Only the worker thread can change the state from - // WORKER_THREAD_STOPPED to any other state and only the main thread - // can change the state to WORKER_THREAD_STOPPED. - struct WorkerInfo { - WorkerThreadState thread_state; - PlatformThreadId thread_id; - CFRunLoopRef thread_run_loop; - - // This constructor sets thread_state to WORKER_THREAD_STOPPED - // and thread_run_loop to NULL. - explicit WorkerInfo(PlatformThreadId thread_id); - - WorkerInfo(WorkerThreadState thread_state, - PlatformThreadId thread_id, - CFRunLoopRef thread_run_loop); - }; - - // After this function is called, worker_shared_info_.thread_state - // is guaranteed to be WORKER_THREAD_STOPPED and - // network_reachability_ is guaranteed to be NULL. Must be called - // only from the parent thread without worker_lock_ being held. - void ClearWorker(); - - bool IsOnParentThread() const; - // Acquires and releases worker_lock_. - bool IsOnWorkerThread(); - - // The thread ID of the thread that constructed this object. - PlatformThreadId parent_thread_id_; - // The libjingle thread object of the thread that constructed this - // object. - talk_base::Thread* parent_thread_; - - // The handle to the worker thread, or kNullThreadHandle if a worker - // thread doesn't exist. - PlatformThreadHandle worker_thread_; - - // This lock protects worker_shared_info_ when the worker - // thread is running. - Lock worker_lock_; - - // Signalled by the worker thread when - // worker_shared_info_.thread_state moves from WORKER_THREAD_STOPPED - // to another state. - ConditionVariable worker_thread_not_stopped_; - - // Struct for everything that is shared between the parent and the - // worker thread. - WorkerInfo worker_shared_info_; - - FRIEND_TEST(NetworkStatusDetectorTaskMacTest, StartNoStopTest); - FRIEND_TEST(NetworkStatusDetectorTaskMacTest, StartStopTest); - - DISALLOW_COPY_AND_ASSIGN(NetworkStatusDetectorTaskMac); -}; - -} // namespace notifier - -#endif // CHROME_COMMON_NET_NOTIFIER_BASE_MAC_NETWORK_STATUS_DETECTOR_TASK_MAC_H_ - diff --git a/chrome/common/net/notifier/base/mac/network_status_detector_task_mac_unittest.cc b/chrome/common/net/notifier/base/mac/network_status_detector_task_mac_unittest.cc deleted file mode 100644 index 9e75b42..0000000 --- a/chrome/common/net/notifier/base/mac/network_status_detector_task_mac_unittest.cc +++ /dev/null @@ -1,111 +0,0 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/common/net/notifier/base/mac/network_status_detector_task_mac.h" - -#include <CoreFoundation/CoreFoundation.h> - -#include "talk/base/messagequeue.h" -#include "talk/base/sigslot.h" -#include "talk/base/taskrunner.h" -#include "talk/base/thread.h" -#include "testing/gtest/include/gtest/gtest.h" - -namespace notifier { - -// No anonymous namespace because we use FRIEND_TESTs. - -class NetworkStatusDetectorTaskMacTest : public testing::Test { -}; - -// TODO(akalin): We can't test much with the current interface. -// Extend it so we're able to inject mock network events and then add -// more tests. - -// Some basic sanity checks to make sure the object is destroyed -// cleanly with various configurations. - -TEST_F(NetworkStatusDetectorTaskMacTest, InitTest) { - NetworkStatusDetectorTaskMac network_status_detector_mac(NULL); -} - -TEST_F(NetworkStatusDetectorTaskMacTest, StartNoStopTest) { - NetworkStatusDetectorTaskMac network_status_detector_mac(NULL); - EXPECT_EQ(NetworkStatusDetectorTaskMac::STATE_RESPONSE, - network_status_detector_mac.ProcessStart()); -} - -class DummyTaskRunner : public talk_base::TaskRunner { - public: - virtual void WakeTasks() {} - virtual int64 CurrentTime() { return 0; } -}; - -TEST_F(NetworkStatusDetectorTaskMacTest, StartStopTest) { - DummyTaskRunner task_runner; - NetworkStatusDetectorTaskMac network_status_detector_mac(&task_runner); - EXPECT_EQ(NetworkStatusDetectorTaskMac::STATE_RESPONSE, - network_status_detector_mac.ProcessStart()); - network_status_detector_mac.Stop(); -} - -// Some miscellaneous tests. - -class AliveListener : public sigslot::has_slots<> { - public: - AliveListener() - : was_alive_(false), - is_alive_(false), - set_alive_called_(false) {} - - void SetAlive(bool was_alive, bool is_alive) { - was_alive_ = was_alive; - is_alive_ = is_alive; - set_alive_called_ = true; - } - - void ResetSetAliveCalled() { - set_alive_called_ = false; - } - - bool was_alive() const { return was_alive_; } - bool is_alive() const { return is_alive_; } - bool set_alive_called() const { return set_alive_called_; } - - private: - bool was_alive_, is_alive_, set_alive_called_; -}; - -TEST_F(NetworkStatusDetectorTaskMacTest, OnMessageTest) { - NetworkStatusDetectorTaskMac network_status_detector_mac(NULL); - AliveListener alive_listener; - network_status_detector_mac.SignalNetworkStateDetected.connect( - &alive_listener, &AliveListener::SetAlive); - - talk_base::Message message; - - alive_listener.ResetSetAliveCalled(); - message.message_id = 0; - network_status_detector_mac.OnMessage(&message); - EXPECT_TRUE(alive_listener.set_alive_called()); - EXPECT_FALSE(alive_listener.was_alive()); - EXPECT_FALSE(alive_listener.is_alive()); - - alive_listener.ResetSetAliveCalled(); - message.message_id = 5; - network_status_detector_mac.OnMessage(&message); - EXPECT_TRUE(alive_listener.set_alive_called()); - EXPECT_FALSE(alive_listener.was_alive()); - EXPECT_TRUE(alive_listener.is_alive()); - - alive_listener.ResetSetAliveCalled(); - message.message_id = 0; - network_status_detector_mac.OnMessage(&message); - EXPECT_TRUE(alive_listener.set_alive_called()); - EXPECT_TRUE(alive_listener.was_alive()); - EXPECT_FALSE(alive_listener.is_alive()); -} - -} // namespace notifier - diff --git a/chrome/common/net/notifier/base/network_status_detector_task.cc b/chrome/common/net/notifier/base/network_status_detector_task.cc deleted file mode 100644 index 12be088..0000000 --- a/chrome/common/net/notifier/base/network_status_detector_task.cc +++ /dev/null @@ -1,30 +0,0 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/common/net/notifier/base/network_status_detector_task.h" - -namespace notifier { - -void NetworkStatusDetectorTask::DetectNetworkState() { - // If the detection has been finished, then just broadcast the current state. - // Otherwise, allow the signal to be sent when the initial detection is - // finished. - if (initial_detection_done_) { - SignalNetworkStateDetected(is_alive_, is_alive_); - } -} - -void NetworkStatusDetectorTask::SetNetworkAlive(bool is_alive) { - bool was_alive = is_alive_; - is_alive_ = is_alive; - - if (!initial_detection_done_ || was_alive != is_alive_) { - initial_detection_done_ = true; - - // Tell everyone about the network state change. - SignalNetworkStateDetected(was_alive, is_alive_); - } -} - -} // namespace notifier diff --git a/chrome/common/net/notifier/base/network_status_detector_task.h b/chrome/common/net/notifier/base/network_status_detector_task.h deleted file mode 100644 index 4b24a24..0000000 --- a/chrome/common/net/notifier/base/network_status_detector_task.h +++ /dev/null @@ -1,58 +0,0 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_COMMON_NET_NOTIFIER_BASE_NETWORK_STATUS_DETECTOR_TASK_H_ -#define CHROME_COMMON_NET_NOTIFIER_BASE_NETWORK_STATUS_DETECTOR_TASK_H_ - -#include "chrome/common/net/notifier/base/time.h" -#include "talk/base/sigslot.h" -#include "talk/base/task.h" - -namespace notifier { - -class AsyncNetworkAlive; - -// Detects the current network state and any changes to that. -class NetworkStatusDetectorTask : public talk_base::Task, - public sigslot::has_slots<> { - public: - // Create an instance of (a subclass of) this class. - static NetworkStatusDetectorTask* Create(talk_base::Task* parent); - - // Determines the current network state and then calls - // SignalNetworkStateDetected. - void DetectNetworkState(); - - // Fires whenever the network state is detected. - // SignalNetworkStateDetected(was_alive, is_alive); - sigslot::signal2<bool, bool> SignalNetworkStateDetected; - - protected: - explicit NetworkStatusDetectorTask(talk_base::Task* parent) - : talk_base::Task(parent), - initial_detection_done_(false), - is_alive_(false) { - } - - virtual ~NetworkStatusDetectorTask() { } - - virtual int ProcessStart() = 0; - - // Stay around until aborted. - virtual int ProcessResponse() { - return STATE_BLOCKED; - } - - void SetNetworkAlive(bool is_alive); - - private: - bool initial_detection_done_; - bool is_alive_; - - DISALLOW_COPY_AND_ASSIGN(NetworkStatusDetectorTask); -}; - -} // namespace notifier - -#endif // CHROME_COMMON_NET_NOTIFIER_BASE_NETWORK_STATUS_DETECTOR_TASK_H_ diff --git a/chrome/common/net/notifier/base/network_status_detector_task_mt.cc b/chrome/common/net/notifier/base/network_status_detector_task_mt.cc deleted file mode 100644 index c45e1e1..0000000 --- a/chrome/common/net/notifier/base/network_status_detector_task_mt.cc +++ /dev/null @@ -1,49 +0,0 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/common/net/notifier/base/network_status_detector_task_mt.h" - -#include "base/logging.h" -#include "chrome/common/net/notifier/base/async_network_alive.h" -#include "chrome/common/net/notifier/base/signal_thread_task.h" - -#include "talk/base/common.h" - -namespace notifier { - -void NetworkStatusDetectorTaskMT::OnNetworkAliveDone( - AsyncNetworkAlive* network_alive) { - DCHECK(network_alive); - SetNetworkAlive(network_alive->alive()); - // If we got an error from detecting the network alive state, then stop - // retrying the detection. - if (network_alive->error()) { - return; - } - StartAsyncDetection(network_alive->ReleaseInfo()); -} - -void NetworkStatusDetectorTaskMT::StartAsyncDetection( - PlatformNetworkInfo* previous_info) { - // Use the AsyncNetworkAlive to determine the network state (and changes in - // the network state). - AsyncNetworkAlive* network_alive = AsyncNetworkAlive::Create(); - - if (previous_info) { - network_alive->SetWaitForNetworkChange(previous_info); - } - SignalThreadTask<AsyncNetworkAlive>* task = - new SignalThreadTask<AsyncNetworkAlive>(this, &network_alive); - task->SignalWorkDone.connect( - this, &NetworkStatusDetectorTaskMT::OnNetworkAliveDone); - task->Start(); -} - -NetworkStatusDetectorTask* NetworkStatusDetectorTask::Create( - talk_base::Task* parent) { - DCHECK(parent); - return new NetworkStatusDetectorTaskMT(parent); -} - -} // namespace notifier diff --git a/chrome/common/net/notifier/base/network_status_detector_task_mt.h b/chrome/common/net/notifier/base/network_status_detector_task_mt.h deleted file mode 100644 index ba55cd8..0000000 --- a/chrome/common/net/notifier/base/network_status_detector_task_mt.h +++ /dev/null @@ -1,34 +0,0 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#ifndef CHROME_COMMON_NET_NOTIFIER_BASE_NETWORK_STATUS_DETECTOR_TASK_MT_H_ -#define CHROME_COMMON_NET_NOTIFIER_BASE_NETWORK_STATUS_DETECTOR_TASK_MT_H_ - -#include "chrome/common/net/notifier/base/network_status_detector_task.h" - -namespace notifier { - -class AsyncNetworkAlive; -class PlatformNetworkInfo; - -class NetworkStatusDetectorTaskMT : public NetworkStatusDetectorTask { - public: - explicit NetworkStatusDetectorTaskMT(talk_base::Task* parent) - : NetworkStatusDetectorTask(parent) { - } - - protected: - virtual int ProcessStart() { - StartAsyncDetection(NULL); - return STATE_RESPONSE; - } - - private: - void OnNetworkAliveDone(AsyncNetworkAlive* network_alive); - void StartAsyncDetection(PlatformNetworkInfo* network_info); -}; - -} // namespace notifier - -#endif // CHROME_COMMON_NET_NOTIFIER_BASE_NETWORK_STATUS_DETECTOR_TASK_MT_H_ diff --git a/chrome/common/net/notifier/base/win/async_network_alive_win32.cc b/chrome/common/net/notifier/base/win/async_network_alive_win32.cc deleted file mode 100644 index d20f027..0000000 --- a/chrome/common/net/notifier/base/win/async_network_alive_win32.cc +++ /dev/null @@ -1,252 +0,0 @@ -// Copyright (c) 2009 The Chromium Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - -#include "chrome/common/net/notifier/base/async_network_alive.h" - -#include <winsock2.h> - -#include "base/logging.h" -#include "base/scoped_handle_win.h" -#include "chrome/common/net/notifier/base/utils.h" -#include "talk/base/common.h" -#include "talk/base/criticalsection.h" -#include "talk/base/logging.h" -#include "talk/base/physicalsocketserver.h" -#include "talk/base/scoped_ptr.h" - -namespace notifier { - -class PlatformNetworkInfo { - public: - PlatformNetworkInfo() : ws_handle_(NULL), event_handle_(NULL) { - } - - ~PlatformNetworkInfo() { - Close(); - } - - void Close() { - talk_base::CritScope crit_scope(&crit_sect_); - if (ws_handle_) { - if (event_handle_.IsValid()) // Unblock any waiting for network changes. - SetEvent(event_handle_.Get()); - // finishes the iteration. - VERIFY(WSALookupServiceEnd(ws_handle_) == 0); - ws_handle_ = NULL; - LOG(INFO) << "WSACleanup 1"; - ::WSACleanup(); - } - } - - bool IsAlive(bool* error) { - DCHECK(error); - *error = false; - - // If IsAlive was previously called, we need a new handle. - // Why? If we use the same handle, we only get diffs on what changed - // which isn't what we want. - Close(); - int result = Initialize(); - if (result != 0) { - LOG(ERROR) << "failed:" << result; - // Default to alive on error. - *error = true; - return true; - } - - bool alive = false; - - // Retrieve network info and move to next one. In this function, we only - // need to know whether or not there is network connection. - // allocate 256 bytes for name, it should be enough for most cases. - // If the name is longer, it is OK as we will check the code returned and - // set correct network status. - char result_buffer[sizeof(WSAQUERYSET) + 256] = {0}; - bool flush_previous_result = false; - do { - DWORD control_flags = LUP_RETURN_NAME; - if (flush_previous_result) { - control_flags |= LUP_FLUSHPREVIOUS; - } - DWORD length = sizeof(result_buffer); - reinterpret_cast<WSAQUERYSET*>(&result_buffer[0])->dwSize = - sizeof(WSAQUERYSET); - // ws_handle_ may be NULL (if exiting), but the call will simply fail - int result = ::WSALookupServiceNext( - ws_handle_, - control_flags, - &length, - reinterpret_cast<WSAQUERYSET*>(&result_buffer[0])); - - if (result == 0) { - // get at least one connection, return "connected". - alive = true; - } else { - DCHECK_EQ(result, SOCKET_ERROR); - result = ::WSAGetLastError(); - if (result == WSA_E_NO_MORE || result == WSAENOMORE) { - break; - } - - // Error code WSAEFAULT means there is a network connection but the - // result_buffer size is too small to contain the results. The - // variable "length" returned from WSALookupServiceNext is the minimum - // number of bytes required. We do not need to retrieve detail info. - // Return "alive" in this case. - if (result == WSAEFAULT) { - alive = true; - flush_previous_result = true; - } else { - LOG(WARNING) << "failed:" << result; - *error = true; - break; - } - } - } while (true); - - LOG(INFO) << "alive: " << alive; - return alive; - } - - bool WaitForChange() { - // IsAlive must be called first. - int junk1 = 0, junk2 = 0; - DWORD bytes_returned = 0; - int result = SOCKET_ERROR; - { - talk_base::CritScope crit_scope(&crit_sect_); - if (!ws_handle_) - return false; - DCHECK(!event_handle_.IsValid()); - event_handle_.Set(CreateEvent(NULL, FALSE, FALSE, NULL)); - if (!event_handle_.IsValid()) { - LOG(WARNING) << "failed to CreateEvent"; - return false; - } - WSAOVERLAPPED overlapped = {0}; - overlapped.hEvent = event_handle_.Get(); - WSACOMPLETION completion; - ::SetZero(completion); - completion.Type = NSP_NOTIFY_EVENT; - completion.Parameters.Event.lpOverlapped = &overlapped; - - LOG(INFO) << "calling WSANSPIoctl"; - // Do a non-blocking request for change notification. event_handle_ - // will get signaled when there is a change, so we wait on it later. - // It can also be signaled by Close() in order allow clean termination. - result = ::WSANSPIoctl(ws_handle_, - SIO_NSP_NOTIFY_CHANGE, - &junk1, - 0, - &junk2, - 0, - &bytes_returned, - &completion); - } - if (NO_ERROR != result) { - result = ::WSAGetLastError(); - if (WSA_IO_PENDING != result) { - LOG(WARNING) << "failed: " << result; - event_handle_.Close(); - return false; - } - } - LOG(INFO) << "waiting"; - WaitForSingleObject(event_handle_.Get(), INFINITE); - event_handle_.Close(); - LOG(INFO) << "changed"; - return true; - } - - private: - int Initialize() { - WSADATA wsa_data; - LOG(INFO) << "calling WSAStartup"; - int result = ::WSAStartup(MAKEWORD(2, 2), &wsa_data); - if (result != ERROR_SUCCESS) { - LOG(ERROR) << "failed:" << result; - return result; - } - - WSAQUERYSET query_set = {0}; - query_set.dwSize = sizeof(WSAQUERYSET); - query_set.dwNameSpace = NS_NLA; - // Initiate a client query to iterate through the - // currently connected networks. - if (0 != ::WSALookupServiceBegin(&query_set, LUP_RETURN_ALL, - &ws_handle_)) { - result = ::WSAGetLastError(); - LOG(INFO) << "WSACleanup 2"; - ::WSACleanup(); - DCHECK(!ws_handle_); - ws_handle_ = NULL; - return result; - } - return 0; - } - talk_base::CriticalSection crit_sect_; - HANDLE ws_handle_; - ScopedHandle event_handle_; - DISALLOW_COPY_AND_ASSIGN(PlatformNetworkInfo); -}; - -class AsyncNetworkAliveWin32 : public AsyncNetworkAlive { - public: - AsyncNetworkAliveWin32() { - } - - virtual ~AsyncNetworkAliveWin32() { - if (network_info_) { - delete network_info_; - network_info_ = NULL; - } - } - - protected: - // SignalThread Interface - virtual void DoWork() { - if (!network_info_) { - network_info_ = new PlatformNetworkInfo(); - } else { - // Since network_info is set, it means that - // we are suppose to wait for network state changes. - if (!network_info_->WaitForChange()) { - // The wait was aborted so we must be shutting down. - alive_ = false; - error_ = true; - return; - } - } - - if (network_info_->IsAlive(&error_)) { - // If there is an active connection, check that www.google.com:80 - // is reachable. - talk_base::PhysicalSocketServer physical; - scoped_ptr<talk_base::Socket> socket(physical.CreateSocket(SOCK_STREAM)); - if (socket->Connect(talk_base::SocketAddress("talk.google.com", 5222))) { - alive_ = false; - } else { - alive_ = true; - } - } else { - // If there are no available connections, then we aren't alive. - alive_ = false; - } - } - - virtual void OnWorkStop() { - if (network_info_) { - network_info_->Close(); - } - } - - private: - DISALLOW_COPY_AND_ASSIGN(AsyncNetworkAliveWin32); -}; - -AsyncNetworkAlive* AsyncNetworkAlive::Create() { - return new AsyncNetworkAliveWin32(); -} - -} // namespace notifier diff --git a/chrome/common/net/notifier/communicator/auto_reconnect.cc b/chrome/common/net/notifier/communicator/auto_reconnect.cc index 35ff386..393866b 100644 --- a/chrome/common/net/notifier/communicator/auto_reconnect.cc +++ b/chrome/common/net/notifier/communicator/auto_reconnect.cc @@ -4,7 +4,6 @@ #include "chrome/common/net/notifier/communicator/auto_reconnect.h" -#include "chrome/common/net/notifier/base/network_status_detector_task.h" #include "chrome/common/net/notifier/base/time.h" #include "chrome/common/net/notifier/base/timer.h" #include "talk/base/common.h" @@ -13,22 +12,17 @@ namespace notifier { const int kResetReconnectInfoDelaySec = 2; -AutoReconnect::AutoReconnect(talk_base::Task* parent, - NetworkStatusDetectorTask* network_status) +AutoReconnect::AutoReconnect(talk_base::Task* parent) : reconnect_interval_ns_(0), reconnect_timer_(NULL), delayed_reset_timer_(NULL), parent_(parent), is_idle_(false) { SetupReconnectInterval(); - if (network_status) { - network_status->SignalNetworkStateDetected.connect( - this, &AutoReconnect::OnNetworkStateDetected); - } } -void AutoReconnect::OnNetworkStateDetected(bool was_alive, bool is_alive) { - if (is_retrying() && !was_alive && is_alive) { +void AutoReconnect::NetworkStateChanged(bool is_alive) { + if (is_retrying() && is_alive) { // Reconnect in 1 to 9 seconds (vary the time a little to try to avoid // spikey behavior on network hiccups). StartReconnectTimerWithInterval((rand() % 9 + 1) * kSecsTo100ns); diff --git a/chrome/common/net/notifier/communicator/auto_reconnect.h b/chrome/common/net/notifier/communicator/auto_reconnect.h index 549f322..f7e3582 100644 --- a/chrome/common/net/notifier/communicator/auto_reconnect.h +++ b/chrome/common/net/notifier/communicator/auto_reconnect.h @@ -17,17 +17,17 @@ class Task; namespace notifier { -class NetworkStatusDetectorTask; class Timer; class AutoReconnect : public sigslot::has_slots<> { public: - AutoReconnect(talk_base::Task* parent, - NetworkStatusDetectorTask* network_status); + explicit AutoReconnect(talk_base::Task* parent); void StartReconnectTimer(); void StopReconnectTimer(); void OnClientStateChange(Login::ConnectionState state); + void NetworkStateChanged(bool is_alive); + // Callback when power is suspended. void OnPowerSuspend(bool suspended); @@ -51,8 +51,6 @@ class AutoReconnect : public sigslot::has_slots<> { void SetupReconnectInterval(); void StopDelayedResetTimer(); - void OnNetworkStateDetected(bool was_alive, bool is_alive); - time64 reconnect_interval_ns_; Timer* reconnect_timer_; Timer* delayed_reset_timer_; diff --git a/chrome/common/net/notifier/communicator/login.cc b/chrome/common/net/notifier/communicator/login.cc index f8fb9b1..0e55eef 100644 --- a/chrome/common/net/notifier/communicator/login.cc +++ b/chrome/common/net/notifier/communicator/login.cc @@ -7,8 +7,6 @@ #include "chrome/common/net/notifier/communicator/login.h" #include "base/logging.h" - -#include "chrome/common/net/notifier/base/network_status_detector_task.h" #include "chrome/common/net/notifier/base/time.h" #include "chrome/common/net/notifier/base/timer.h" #include "chrome/common/net/notifier/communicator/auto_reconnect.h" @@ -16,9 +14,11 @@ #include "chrome/common/net/notifier/communicator/login_settings.h" #include "chrome/common/net/notifier/communicator/product_info.h" #include "chrome/common/net/notifier/communicator/single_login_attempt.h" +#include "net/base/network_change_notifier.h" #include "talk/base/common.h" #include "talk/base/firewallsocketserver.h" #include "talk/base/logging.h" +#include "talk/base/physicalsocketserver.h" #include "talk/base/taskrunner.h" #include "talk/xmllite/xmlelement.h" #include "talk/xmpp/asyncsocket.h" @@ -41,20 +41,22 @@ Login::Login(talk_base::Task* parent, std::string lang, ServerInformation* server_list, int server_count, - NetworkStatusDetectorTask* network_status, + net::NetworkChangeNotifier* network_change_notifier, talk_base::FirewallManager* firewall, bool proxy_only, bool previous_login_successful) - : login_settings_(new LoginSettings(user_settings, + : parent_(parent), + login_settings_(new LoginSettings(user_settings, options, lang, server_list, server_count, firewall, proxy_only)), + network_change_notifier_(network_change_notifier), + auto_reconnect_(new AutoReconnect(parent)), single_attempt_(NULL), successful_connection_(previous_login_successful), - parent_(parent), state_(STATE_OPENING), redirect_time_ns_(0), redirect_port_(0), @@ -63,30 +65,23 @@ Login::Login(talk_base::Task* parent, google_host_(user_settings.host()), google_user_(user_settings.user()), disconnect_timer_(NULL) { - if (!network_status) { - network_status = NetworkStatusDetectorTask::Create(parent_); - if (network_status) { - // On linux we don't have an implementation of NetworkStatusDetectorTask. - network_status->Start(); - } - } - - if (network_status) { - network_status->SignalNetworkStateDetected.connect( - this, &Login::OnNetworkStateDetected); - auto_reconnect_.reset(new AutoReconnect(parent_, network_status)); - auto_reconnect_->SignalStartConnection.connect(this, - &Login::StartConnection); - auto_reconnect_->SignalTimerStartStop.connect( - this, - &Login::OnAutoReconnectTimerChange); - SignalClientStateChange.connect(auto_reconnect_.get(), - &AutoReconnect::OnClientStateChange); - SignalIdleChange.connect(auto_reconnect_.get(), - &AutoReconnect::set_idle); - SignalPowerSuspended.connect(auto_reconnect_.get(), - &AutoReconnect::OnPowerSuspend); - } + DCHECK(network_change_notifier_); + // Hook up all the signals and observers. + network_change_notifier_->AddObserver(this); + auto_reconnect_->SignalStartConnection.connect(this, + &Login::StartConnection); + auto_reconnect_->SignalTimerStartStop.connect( + this, + &Login::OnAutoReconnectTimerChange); + SignalClientStateChange.connect(auto_reconnect_.get(), + &AutoReconnect::OnClientStateChange); + SignalIdleChange.connect(auto_reconnect_.get(), + &AutoReconnect::set_idle); + SignalPowerSuspended.connect(auto_reconnect_.get(), + &AutoReconnect::OnPowerSuspend); + + // Then check the initial state of the connection. + CheckConnection(); } // Defined so that the destructors are executed here (and the corresponding @@ -96,6 +91,7 @@ Login::~Login() { single_attempt_->Abort(); single_attempt_ = NULL; } + network_change_notifier_->RemoveObserver(this); } void Login::StartConnection() { @@ -322,16 +318,19 @@ void Login::DoAutoReconnect() { } } -void Login::OnNetworkStateDetected(bool was_alive, bool is_alive) { - if (was_alive && !is_alive) { - // Our network connection just went down. Setup a timer to disconnect. - // Don't disconnect immediately to avoid constant - // connection/disconnection due to flaky network interfaces. - DCHECK(!disconnect_timer_); - disconnect_timer_ = new Timer(parent_, kDisconnectionDelaySecs, false); - disconnect_timer_->SignalTimeout.connect(this, - &Login::OnDisconnectTimeout); - } else if (!was_alive && is_alive) { +void Login::OnIPAddressChanged() { + LOG(INFO) << "IP address change detected"; + CheckConnection(); +} + +void Login::CheckConnection() { + LOG(INFO) << "Checking connection"; + talk_base::PhysicalSocketServer physical; + scoped_ptr<talk_base::Socket> socket(physical.CreateSocket(SOCK_STREAM)); + bool alive = + !socket->Connect(talk_base::SocketAddress("talk.google.com", 5222)); + LOG(INFO) << "Network is " << (alive ? "alive" : "not alive"); + if (alive) { // Our connection has come back up. If we have a disconnect timer going, // abort it so we don't disconnect. if (disconnect_timer_) { @@ -339,7 +338,16 @@ void Login::OnNetworkStateDetected(bool was_alive, bool is_alive) { // It will free itself. disconnect_timer_ = NULL; } + } else { + // Our network connection just went down. Setup a timer to disconnect. + // Don't disconnect immediately to avoid constant + // connection/disconnection due to flaky network interfaces. + DCHECK(disconnect_timer_ == NULL); + disconnect_timer_ = new Timer(parent_, kDisconnectionDelaySecs, false); + disconnect_timer_->SignalTimeout.connect(this, + &Login::OnDisconnectTimeout); } + auto_reconnect_->NetworkStateChanged(alive); } void Login::OnDisconnectTimeout() { diff --git a/chrome/common/net/notifier/communicator/login.h b/chrome/common/net/notifier/communicator/login.h index 6ee8008..b0e841a 100644 --- a/chrome/common/net/notifier/communicator/login.h +++ b/chrome/common/net/notifier/communicator/login.h @@ -9,6 +9,7 @@ #include "chrome/common/net/notifier/base/sigslotrepeater.h" #include "chrome/common/net/notifier/base/time.h" +#include "net/base/network_change_notifier.h" #include "talk/base/proxyinfo.h" #include "talk/base/scoped_ptr.h" #include "talk/base/sigslot.h" @@ -32,7 +33,6 @@ class AutoReconnect; class ConnectionOptions; class LoginFailure; class LoginSettings; -class NetworkStatusDetectorTask; struct ServerInformation; class SingleLoginAttempt; class Timer; @@ -40,7 +40,8 @@ class Timer; // Does the login, keeps it alive (with refreshing cookies and reattempting // login when disconnected), figures out what actions to take on the various // errors that may occur. -class Login : public sigslot::has_slots<> { +class Login : public net::NetworkChangeNotifier::Observer, + public sigslot::has_slots<> { public: // network_status and firewall may be NULL. Login(talk_base::Task* parent, @@ -49,11 +50,11 @@ class Login : public sigslot::has_slots<> { std::string lang, ServerInformation* server_list, int server_count, - NetworkStatusDetectorTask* network_status, + net::NetworkChangeNotifier* network_change_notifier, talk_base::FirewallManager* firewall, bool proxy_only, bool previous_login_successful); - ~Login(); + virtual ~Login(); enum ConnectionState { STATE_CLOSED, @@ -100,6 +101,8 @@ class Login : public sigslot::has_slots<> { int seconds_until_reconnect() const; + virtual void OnIPAddressChanged(); + // SignalClientStateChange(ConnectionState new_state); sigslot::signal1<ConnectionState> SignalClientStateChange; @@ -113,6 +116,8 @@ class Login : public sigslot::has_slots<> { sigslot::repeater1<bool> SignalPowerSuspended; private: + void CheckConnection(); + void OnRedirect(const std::string& redirect_server, int redirect_port); void OnUnexpectedDisconnect(); void OnClientStateChange(buzz::XmppEngine::State state); @@ -123,14 +128,14 @@ class Login : public sigslot::has_slots<> { void HandleClientStateChange(ConnectionState new_state); void ResetUnexpectedDisconnect(); - void OnNetworkStateDetected(bool was_alive, bool is_alive); void OnDisconnectTimeout(); + talk_base::Task* parent_; scoped_ptr<LoginSettings> login_settings_; + net::NetworkChangeNotifier* network_change_notifier_; scoped_ptr<AutoReconnect> auto_reconnect_; SingleLoginAttempt* single_attempt_; bool successful_connection_; - talk_base::Task* parent_; ConnectionState state_; diff --git a/chrome/common/net/notifier/listener/mediator_thread_impl.cc b/chrome/common/net/notifier/listener/mediator_thread_impl.cc index 7ab5150..4ce5a97 100644 --- a/chrome/common/net/notifier/listener/mediator_thread_impl.cc +++ b/chrome/common/net/notifier/listener/mediator_thread_impl.cc @@ -7,6 +7,7 @@ #include "base/logging.h" #include "base/message_loop.h" #include "base/platform_thread.h" +#include "chrome/common/net/network_change_notifier_proxy.h" #include "chrome/common/net/notifier/base/async_dns_lookup.h" #include "chrome/common/net/notifier/base/task_pump.h" #include "chrome/common/net/notifier/communicator/connection_options.h" @@ -23,7 +24,12 @@ using std::string; namespace notifier { -MediatorThreadImpl::MediatorThreadImpl() {} +MediatorThreadImpl::MediatorThreadImpl( + chrome_common_net::NetworkChangeNotifierThread* + network_change_notifier_thread) + : network_change_notifier_thread_(network_change_notifier_thread) { + DCHECK(network_change_notifier_thread_); +} MediatorThreadImpl::~MediatorThreadImpl() { } @@ -59,8 +65,8 @@ void MediatorThreadImpl::Login(const buzz::XmppClientSettings& settings) { void MediatorThreadImpl::Stop() { Thread::Stop(); - CHECK(!login_.get() && !pump_.get()) << "Logout should be called prior to" - << "message queue exit."; + CHECK(!login_.get() && !network_change_notifier_.get() && !pump_.get()) + << "Logout should be called prior to message queue exit."; } void MediatorThreadImpl::Logout() { @@ -132,6 +138,9 @@ void MediatorThreadImpl::DoLogin(LoginData* login_data) { // Start a new pump for the login. login_.reset(); + network_change_notifier_.reset( + new chrome_common_net::NetworkChangeNotifierProxy( + network_change_notifier_thread_)); pump_.reset(new notifier::TaskPump()); notifier::ServerInformation server_list[2]; @@ -158,12 +167,7 @@ void MediatorThreadImpl::DoLogin(LoginData* login_data) { lang, server_list, server_list_count, - // NetworkStatusDetectionTask will be - // created for you if NULL is passed in. - // It helps shorten the autoreconnect - // time after going offline and coming - // back online. - NULL, + network_change_notifier_.get(), // talk_base::FirewallManager* is NULL. NULL, // Both the proxy and a non-proxy route @@ -195,6 +199,7 @@ void MediatorThreadImpl::OnOutputDebug(const char* msg, int length) { void MediatorThreadImpl::DoDisconnect() { LOG(INFO) << "P2P: Thread logging out of talk network."; login_.reset(); + network_change_notifier_.reset(); // Delete the old pump while on the thread to ensure that everything is // cleaned-up in a predicatable manner. pump_.reset(); diff --git a/chrome/common/net/notifier/listener/mediator_thread_impl.h b/chrome/common/net/notifier/listener/mediator_thread_impl.h index 5517529..fb660da 100644 --- a/chrome/common/net/notifier/listener/mediator_thread_impl.h +++ b/chrome/common/net/notifier/listener/mediator_thread_impl.h @@ -32,6 +32,14 @@ #include "talk/base/thread.h" #include "talk/xmpp/xmppclientsettings.h" +namespace chrome_common_net { +class NetworkChangeNotifierThread; +} // namespace chrome_common_net + +namespace net { +class NetworkChangeNotifier; +} // namespace net + namespace notifier { class TaskPump; } // namespace notifier @@ -95,7 +103,9 @@ class MediatorThreadImpl public talk_base::MessageHandler, public talk_base::Thread { public: - explicit MediatorThreadImpl(); + explicit MediatorThreadImpl( + chrome_common_net::NetworkChangeNotifierThread* + network_change_notifier_thread); virtual ~MediatorThreadImpl(); // Start the thread. @@ -143,6 +153,9 @@ class MediatorThreadImpl // owned by the TaskPump. They are destroyed either when processing is // complete or the pump shuts down. scoped_ptr<notifier::TaskPump> pump_; + chrome_common_net::NetworkChangeNotifierThread* + network_change_notifier_thread_; + scoped_ptr<net::NetworkChangeNotifier> network_change_notifier_; scoped_ptr<notifier::Login> login_; DISALLOW_COPY_AND_ASSIGN(MediatorThreadImpl); }; diff --git a/chrome/common/net/notifier/listener/talk_mediator_impl.cc b/chrome/common/net/notifier/listener/talk_mediator_impl.cc index 55eb815..f2e3d2e 100644 --- a/chrome/common/net/notifier/listener/talk_mediator_impl.cc +++ b/chrome/common/net/notifier/listener/talk_mediator_impl.cc @@ -39,8 +39,12 @@ class SslInitializationSingleton { DISALLOW_COPY_AND_ASSIGN(SslInitializationSingleton); }; -TalkMediatorImpl::TalkMediatorImpl(bool invalidate_xmpp_auth_token) - : mediator_thread_(new MediatorThreadImpl()), +TalkMediatorImpl::TalkMediatorImpl( + chrome_common_net::NetworkChangeNotifierThread* + network_change_notifier_thread, + bool invalidate_xmpp_auth_token) + : mediator_thread_( + new MediatorThreadImpl(network_change_notifier_thread)), invalidate_xmpp_auth_token_(invalidate_xmpp_auth_token) { // Ensure the SSL library is initialized. SslInitializationSingleton::GetInstance()->RegisterClient(); diff --git a/chrome/common/net/notifier/listener/talk_mediator_impl.h b/chrome/common/net/notifier/listener/talk_mediator_impl.h index 7c701ed..cb965b7 100644 --- a/chrome/common/net/notifier/listener/talk_mediator_impl.h +++ b/chrome/common/net/notifier/listener/talk_mediator_impl.h @@ -22,13 +22,20 @@ class EventListenerHookup; +namespace chrome_common_net { +class NetworkChangeNotifierThread; +} // namespace chrome_common_net + namespace notifier { class TalkMediatorImpl : public TalkMediator, public sigslot::has_slots<> { public: - explicit TalkMediatorImpl(bool invalidate_xmpp_auth_token); + TalkMediatorImpl( + chrome_common_net::NetworkChangeNotifierThread* + network_change_notifier_thread, + bool invalidate_xmpp_auth_token); explicit TalkMediatorImpl(MediatorThread* thread); virtual ~TalkMediatorImpl(); diff --git a/chrome/common/net/notifier/listener/talk_mediator_unittest.cc b/chrome/common/net/notifier/listener/talk_mediator_unittest.cc index dd50d64..3bdac80 100644 --- a/chrome/common/net/notifier/listener/talk_mediator_unittest.cc +++ b/chrome/common/net/notifier/listener/talk_mediator_unittest.cc @@ -5,6 +5,7 @@ #include <string> #include "base/logging.h" +#include "chrome/common/net/fake_network_change_notifier_thread.h" #include "chrome/common/net/notifier/listener/mediator_thread_mock.h" #include "chrome/common/net/notifier/listener/talk_mediator_impl.h" #include "chrome/common/deprecated/event_sys-inl.h" @@ -31,12 +32,15 @@ class TalkMediatorImplTest : public testing::Test { virtual void TearDown() { } + chrome_common_net::FakeNetworkChangeNotifierThread + fake_network_change_notifier_thread_; int last_message_; }; TEST_F(TalkMediatorImplTest, ConstructionOfTheClass) { // Constructing a single talk mediator enables SSL through the singleton. - scoped_ptr<TalkMediatorImpl> talk1(new TalkMediatorImpl(false)); + scoped_ptr<TalkMediatorImpl> talk1( + new TalkMediatorImpl(&fake_network_change_notifier_thread_, false)); talk1.reset(NULL); } |