| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 // See network_change_notifier_android.h for design explanations. | 5 // See network_change_notifier_android.h for design explanations. |
| 6 | 6 |
| 7 #include "base/basictypes.h" | 7 #include "base/basictypes.h" |
| 8 #include "base/bind.h" | 8 #include "base/bind.h" |
| 9 #include "base/callback.h" | 9 #include "base/callback.h" |
| 10 #include "base/compiler_specific.h" | 10 #include "base/compiler_specific.h" |
| 11 #include "base/message_loop.h" | 11 #include "base/message_loop.h" |
| 12 #include "net/android/network_change_notifier_android.h" | 12 #include "net/android/network_change_notifier_android.h" |
| 13 #include "net/android/network_change_notifier_delegate_android.h" | 13 #include "net/android/network_change_notifier_delegate_android.h" |
| 14 #include "net/base/network_change_notifier.h" | 14 #include "net/base/network_change_notifier.h" |
| 15 #include "testing/gtest/include/gtest/gtest.h" | 15 #include "testing/gtest/include/gtest/gtest.h" |
| 16 | 16 |
| 17 namespace net { | 17 namespace net { |
| 18 | 18 |
| 19 namespace { | 19 namespace { |
| 20 | 20 |
| 21 // Template used to generate both the NetworkChangeNotifierDelegateAndroid and | 21 class NetworkChangeNotifierDelegateAndroidObserver |
| 22 // NetworkChangeNotifier::ConnectionTypeObserver implementations which have the | 22 : public NetworkChangeNotifierDelegateAndroid::Observer { |
| 23 // same interface. | |
| 24 template <typename BaseObserver> | |
| 25 class ObserverImpl : public BaseObserver { | |
| 26 public: | 23 public: |
| 27 ObserverImpl() | 24 NetworkChangeNotifierDelegateAndroidObserver() : notifications_count_(0) {} |
| 28 : times_connection_type_changed_(0), | 25 |
| 29 current_connection_(NetworkChangeNotifier::CONNECTION_UNKNOWN) { | 26 // NetworkChangeNotifierDelegateAndroid::Observer: |
| 27 virtual void OnConnectionTypeChanged() OVERRIDE { |
| 28 notifications_count_++; |
| 30 } | 29 } |
| 31 | 30 |
| 32 // BaseObserver: | 31 int notifications_count() const { |
| 33 virtual void OnConnectionTypeChanged( | 32 return notifications_count_; |
| 34 NetworkChangeNotifier::ConnectionType type) OVERRIDE { | |
| 35 times_connection_type_changed_++; | |
| 36 current_connection_ = type; | |
| 37 } | |
| 38 | |
| 39 int times_connection_type_changed() const { | |
| 40 return times_connection_type_changed_; | |
| 41 } | |
| 42 | |
| 43 NetworkChangeNotifier::ConnectionType current_connection() const { | |
| 44 return current_connection_; | |
| 45 } | 33 } |
| 46 | 34 |
| 47 private: | 35 private: |
| 48 int times_connection_type_changed_; | 36 int notifications_count_; |
| 49 NetworkChangeNotifier::ConnectionType current_connection_; | 37 }; |
| 50 | 38 |
| 51 DISALLOW_COPY_AND_ASSIGN(ObserverImpl); | 39 class NetworkChangeNotifierObserver |
| 40 : public NetworkChangeNotifier::ConnectionTypeObserver { |
| 41 public: |
| 42 NetworkChangeNotifierObserver() : notifications_count_(0) {} |
| 43 |
| 44 // NetworkChangeNotifier::Observer: |
| 45 virtual void OnConnectionTypeChanged( |
| 46 NetworkChangeNotifier::ConnectionType connection_type) OVERRIDE { |
| 47 notifications_count_++; |
| 48 } |
| 49 |
| 50 int notifications_count() const { |
| 51 return notifications_count_; |
| 52 } |
| 53 |
| 54 private: |
| 55 int notifications_count_; |
| 52 }; | 56 }; |
| 53 | 57 |
| 54 } // namespace | 58 } // namespace |
| 55 | 59 |
| 56 class BaseNetworkChangeNotifierAndroidTest : public testing::Test { | 60 class BaseNetworkChangeNotifierAndroidTest : public testing::Test { |
| 57 protected: | 61 protected: |
| 58 typedef NetworkChangeNotifier::ConnectionType ConnectionType; | 62 typedef NetworkChangeNotifier::ConnectionType ConnectionType; |
| 59 | 63 |
| 60 virtual ~BaseNetworkChangeNotifierAndroidTest() {} | 64 virtual ~BaseNetworkChangeNotifierAndroidTest() {} |
| 61 | 65 |
| 62 void RunTest( | 66 void RunTest( |
| 63 const base::Callback<int(void)>& times_connection_type_changed_callback, | 67 const base::Callback<int(void)>& notifications_count_getter, |
| 64 const base::Callback<ConnectionType(void)>& connection_type_getter) { | 68 const base::Callback<ConnectionType(void)>& connection_type_getter) { |
| 65 EXPECT_EQ(0, times_connection_type_changed_callback.Run()); | 69 EXPECT_EQ(0, notifications_count_getter.Run()); |
| 66 EXPECT_EQ(NetworkChangeNotifier::CONNECTION_UNKNOWN, | 70 EXPECT_EQ(NetworkChangeNotifier::CONNECTION_UNKNOWN, |
| 67 connection_type_getter.Run()); | 71 connection_type_getter.Run()); |
| 68 | 72 |
| 69 ForceConnectivityState(NetworkChangeNotifierDelegateAndroid::OFFLINE); | 73 // Changing from online to offline should trigger a notification. |
| 70 EXPECT_EQ(1, times_connection_type_changed_callback.Run()); | 74 SetOffline(); |
| 75 EXPECT_EQ(1, notifications_count_getter.Run()); |
| 71 EXPECT_EQ(NetworkChangeNotifier::CONNECTION_NONE, | 76 EXPECT_EQ(NetworkChangeNotifier::CONNECTION_NONE, |
| 72 connection_type_getter.Run()); | 77 connection_type_getter.Run()); |
| 73 | 78 |
| 74 ForceConnectivityState(NetworkChangeNotifierDelegateAndroid::OFFLINE); | 79 // No notification should be triggered when the offline state hasn't |
| 75 EXPECT_EQ(1, times_connection_type_changed_callback.Run()); | 80 // changed. |
| 81 SetOffline(); |
| 82 EXPECT_EQ(1, notifications_count_getter.Run()); |
| 76 EXPECT_EQ(NetworkChangeNotifier::CONNECTION_NONE, | 83 EXPECT_EQ(NetworkChangeNotifier::CONNECTION_NONE, |
| 77 connection_type_getter.Run()); | 84 connection_type_getter.Run()); |
| 78 | 85 |
| 79 ForceConnectivityState(NetworkChangeNotifierDelegateAndroid::ONLINE); | 86 // Going from offline to online should trigger a notification. |
| 80 EXPECT_EQ(2, times_connection_type_changed_callback.Run()); | 87 SetOnline(); |
| 88 EXPECT_EQ(2, notifications_count_getter.Run()); |
| 81 EXPECT_EQ(NetworkChangeNotifier::CONNECTION_UNKNOWN, | 89 EXPECT_EQ(NetworkChangeNotifier::CONNECTION_UNKNOWN, |
| 82 connection_type_getter.Run()); | 90 connection_type_getter.Run()); |
| 83 } | 91 } |
| 84 | 92 |
| 85 void ForceConnectivityState( | 93 void SetOnline() { |
| 86 NetworkChangeNotifierDelegateAndroid::ConnectivityState state) { | 94 delegate_.SetOnline(); |
| 87 delegate_.ForceConnectivityState(state); | |
| 88 // Note that this is needed because ObserverListThreadSafe uses PostTask(). | 95 // Note that this is needed because ObserverListThreadSafe uses PostTask(). |
| 89 MessageLoop::current()->RunUntilIdle(); | 96 MessageLoop::current()->RunUntilIdle(); |
| 90 } | 97 } |
| 91 | 98 |
| 99 void SetOffline() { |
| 100 delegate_.SetOffline(); |
| 101 // See comment above. |
| 102 MessageLoop::current()->RunUntilIdle(); |
| 103 } |
| 104 |
| 92 NetworkChangeNotifierDelegateAndroid delegate_; | 105 NetworkChangeNotifierDelegateAndroid delegate_; |
| 93 }; | 106 }; |
| 94 | 107 |
| 108 // Tests that NetworkChangeNotifierDelegateAndroid is initialized with the |
| 109 // actual connection type rather than a hardcoded one (e.g. |
| 110 // CONNECTION_UNKNOWN). Initializing the connection type to CONNECTION_UNKNOWN |
| 111 // and relying on the first network change notification to set it correctly can |
| 112 // be problematic in case there is a long delay between the delegate's |
| 113 // construction and the notification. |
| 114 TEST_F(BaseNetworkChangeNotifierAndroidTest, |
| 115 DelegateIsInitializedWithCurrentConnectionType) { |
| 116 SetOffline(); |
| 117 ASSERT_EQ(NetworkChangeNotifier::CONNECTION_NONE, |
| 118 delegate_.GetCurrentConnectionType()); |
| 119 // Instantiate another delegate to validate that it uses the actual |
| 120 // connection type at construction. |
| 121 scoped_ptr<NetworkChangeNotifierDelegateAndroid> other_delegate( |
| 122 new NetworkChangeNotifierDelegateAndroid()); |
| 123 EXPECT_EQ(NetworkChangeNotifier::CONNECTION_NONE, |
| 124 other_delegate->GetCurrentConnectionType()); |
| 125 |
| 126 // Toggle the global connectivity state and instantiate another delegate |
| 127 // again. |
| 128 SetOnline(); |
| 129 ASSERT_EQ(NetworkChangeNotifier::CONNECTION_UNKNOWN, |
| 130 delegate_.GetCurrentConnectionType()); |
| 131 other_delegate.reset(new NetworkChangeNotifierDelegateAndroid()); |
| 132 EXPECT_EQ(NetworkChangeNotifier::CONNECTION_UNKNOWN, |
| 133 other_delegate->GetCurrentConnectionType()); |
| 134 } |
| 135 |
| 95 class NetworkChangeNotifierDelegateAndroidTest | 136 class NetworkChangeNotifierDelegateAndroidTest |
| 96 : public BaseNetworkChangeNotifierAndroidTest { | 137 : public BaseNetworkChangeNotifierAndroidTest { |
| 97 protected: | 138 protected: |
| 98 typedef ObserverImpl< | |
| 99 NetworkChangeNotifierDelegateAndroid::Observer> TestDelegateObserver; | |
| 100 | |
| 101 NetworkChangeNotifierDelegateAndroidTest() { | 139 NetworkChangeNotifierDelegateAndroidTest() { |
| 102 delegate_.AddObserver(&delegate_observer_); | 140 delegate_.AddObserver(&delegate_observer_); |
| 103 delegate_.AddObserver(&other_delegate_observer_); | 141 delegate_.AddObserver(&other_delegate_observer_); |
| 104 } | 142 } |
| 105 | 143 |
| 106 virtual ~NetworkChangeNotifierDelegateAndroidTest() { | 144 virtual ~NetworkChangeNotifierDelegateAndroidTest() { |
| 107 delegate_.RemoveObserver(&delegate_observer_); | 145 delegate_.RemoveObserver(&delegate_observer_); |
| 108 delegate_.RemoveObserver(&other_delegate_observer_); | 146 delegate_.RemoveObserver(&other_delegate_observer_); |
| 109 } | 147 } |
| 110 | 148 |
| 111 TestDelegateObserver delegate_observer_; | 149 NetworkChangeNotifierDelegateAndroidObserver delegate_observer_; |
| 112 TestDelegateObserver other_delegate_observer_; | 150 NetworkChangeNotifierDelegateAndroidObserver other_delegate_observer_; |
| 113 }; | 151 }; |
| 114 | 152 |
| 115 // Tests that the NetworkChangeNotifierDelegateAndroid's observers are notified. | 153 // Tests that the NetworkChangeNotifierDelegateAndroid's observers are notified. |
| 116 // A testing-only observer is used here for testing. In production the | 154 // A testing-only observer is used here for testing. In production the |
| 117 // delegate's observers are instances of NetworkChangeNotifierAndroid. | 155 // delegate's observers are instances of NetworkChangeNotifierAndroid. |
| 118 TEST_F(NetworkChangeNotifierDelegateAndroidTest, DelegateObserverNotified) { | 156 TEST_F(NetworkChangeNotifierDelegateAndroidTest, DelegateObserverNotified) { |
| 119 // Test the logic with a single observer. | 157 // Test the logic with a single observer. |
| 120 RunTest( | 158 RunTest( |
| 121 base::Bind( | 159 base::Bind( |
| 122 &TestDelegateObserver::times_connection_type_changed, | 160 &NetworkChangeNotifierDelegateAndroidObserver::notifications_count, |
| 123 base::Unretained(&delegate_observer_)), | 161 base::Unretained(&delegate_observer_)), |
| 124 base::Bind( | 162 base::Bind( |
| 125 &TestDelegateObserver::current_connection, | 163 &NetworkChangeNotifierDelegateAndroid::GetCurrentConnectionType, |
| 126 base::Unretained(&delegate_observer_))); | 164 base::Unretained(&delegate_))); |
| 127 // Check that *all* the observers are notified. Both observers should have the | 165 // Check that *all* the observers are notified. Both observers should have the |
| 128 // same state. | 166 // same state. |
| 129 EXPECT_EQ(delegate_observer_.times_connection_type_changed(), | 167 EXPECT_EQ(delegate_observer_.notifications_count(), |
| 130 other_delegate_observer_.times_connection_type_changed()); | 168 other_delegate_observer_.notifications_count()); |
| 131 EXPECT_EQ(delegate_observer_.current_connection(), | |
| 132 other_delegate_observer_.current_connection()); | |
| 133 } | 169 } |
| 134 | 170 |
| 135 class NetworkChangeNotifierAndroidTest | 171 class NetworkChangeNotifierAndroidTest |
| 136 : public BaseNetworkChangeNotifierAndroidTest { | 172 : public BaseNetworkChangeNotifierAndroidTest { |
| 137 protected: | 173 protected: |
| 138 typedef ObserverImpl< | |
| 139 NetworkChangeNotifier::ConnectionTypeObserver> TestConnectionTypeObserver; | |
| 140 | |
| 141 NetworkChangeNotifierAndroidTest() : notifier_(&delegate_) { | 174 NetworkChangeNotifierAndroidTest() : notifier_(&delegate_) { |
| 142 NetworkChangeNotifier::AddConnectionTypeObserver( | 175 NetworkChangeNotifier::AddConnectionTypeObserver( |
| 143 &connection_type_observer_); | 176 &connection_type_observer_); |
| 144 NetworkChangeNotifier::AddConnectionTypeObserver( | 177 NetworkChangeNotifier::AddConnectionTypeObserver( |
| 145 &other_connection_type_observer_); | 178 &other_connection_type_observer_); |
| 146 } | 179 } |
| 147 | 180 |
| 148 TestConnectionTypeObserver connection_type_observer_; | 181 NetworkChangeNotifierObserver connection_type_observer_; |
| 149 TestConnectionTypeObserver other_connection_type_observer_; | 182 NetworkChangeNotifierObserver other_connection_type_observer_; |
| 150 NetworkChangeNotifier::DisableForTest disable_for_test_; | 183 NetworkChangeNotifier::DisableForTest disable_for_test_; |
| 151 NetworkChangeNotifierAndroid notifier_; | 184 NetworkChangeNotifierAndroid notifier_; |
| 152 }; | 185 }; |
| 153 | 186 |
| 154 // When a NetworkChangeNotifierAndroid is observing a | 187 // When a NetworkChangeNotifierAndroid is observing a |
| 155 // NetworkChangeNotifierDelegateAndroid for network state changes, and the | 188 // NetworkChangeNotifierDelegateAndroid for network state changes, and the |
| 156 // NetworkChangeNotifierDelegateAndroid's connectivity state changes, the | 189 // NetworkChangeNotifierDelegateAndroid's connectivity state changes, the |
| 157 // NetworkChangeNotifierAndroid should reflect that state. | 190 // NetworkChangeNotifierAndroid should reflect that state. |
| 158 TEST_F(NetworkChangeNotifierAndroidTest, | 191 TEST_F(NetworkChangeNotifierAndroidTest, |
| 159 NotificationsSentToNetworkChangeNotifierAndroid) { | 192 NotificationsSentToNetworkChangeNotifierAndroid) { |
| 160 RunTest( | 193 RunTest( |
| 161 base::Bind( | 194 base::Bind( |
| 162 &TestConnectionTypeObserver::times_connection_type_changed, | 195 &NetworkChangeNotifierObserver::notifications_count, |
| 163 base::Unretained(&connection_type_observer_)), | 196 base::Unretained(&connection_type_observer_)), |
| 164 base::Bind( | 197 base::Bind( |
| 165 &NetworkChangeNotifierAndroid::GetCurrentConnectionType, | 198 &NetworkChangeNotifierAndroid::GetCurrentConnectionType, |
| 166 base::Unretained(¬ifier_))); | 199 base::Unretained(¬ifier_))); |
| 167 } | 200 } |
| 168 | 201 |
| 169 // When a NetworkChangeNotifierAndroid's connection state changes, it should | 202 // When a NetworkChangeNotifierAndroid's connection state changes, it should |
| 170 // notify all of its observers. | 203 // notify all of its observers. |
| 171 TEST_F(NetworkChangeNotifierAndroidTest, | 204 TEST_F(NetworkChangeNotifierAndroidTest, |
| 172 NotificationsSentToClientsOfNetworkChangeNotifier) { | 205 NotificationsSentToClientsOfNetworkChangeNotifier) { |
| 173 RunTest( | 206 RunTest( |
| 174 base::Bind( | 207 base::Bind( |
| 175 &TestConnectionTypeObserver::times_connection_type_changed, | 208 &NetworkChangeNotifierObserver::notifications_count, |
| 176 base::Unretained(&connection_type_observer_)), | 209 base::Unretained(&connection_type_observer_)), |
| 177 base::Bind( | 210 base::Bind(&NetworkChangeNotifier::GetConnectionType)); |
| 178 &TestConnectionTypeObserver::current_connection, | |
| 179 base::Unretained(&connection_type_observer_))); | |
| 180 // Check that *all* the observers are notified. | 211 // Check that *all* the observers are notified. |
| 181 EXPECT_EQ(connection_type_observer_.times_connection_type_changed(), | 212 EXPECT_EQ(connection_type_observer_.notifications_count(), |
| 182 other_connection_type_observer_.times_connection_type_changed()); | 213 other_connection_type_observer_.notifications_count()); |
| 183 EXPECT_EQ(connection_type_observer_.current_connection(), | |
| 184 other_connection_type_observer_.current_connection()); | |
| 185 } | 214 } |
| 186 | 215 |
| 187 } // namespace net | 216 } // namespace net |
| OLD | NEW |