summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authorakalin@chromium.org <akalin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-05-05 23:44:06 +0000
committerakalin@chromium.org <akalin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-05-05 23:44:06 +0000
commitec140301a87ecf1ba9e70e8031ee521c002b0f32 (patch)
tree2775b581338244c0ed49633d53def838cc703755 /chrome
parent079786397d052c14a2b1886dfb494c4bd4a9335c (diff)
downloadchromium_src-ec140301a87ecf1ba9e70e8031ee521c002b0f32.zip
chromium_src-ec140301a87ecf1ba9e70e8031ee521c002b0f32.tar.gz
chromium_src-ec140301a87ecf1ba9e70e8031ee521c002b0f32.tar.bz2
Added NetworkChangeNotifierThread interface.
Also made NetworkChange{Observer,Notifier}Proxy use it instead of managing the source message loop and NetworkChangeNotifier themselves. BUG=42606 TEST=unit tests Review URL: http://codereview.chromium.org/1973001 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@46524 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r--chrome/browser/sync/net/fake_network_change_notifier_thread.cc80
-rw-r--r--chrome/browser/sync/net/fake_network_change_notifier_thread.h64
-rw-r--r--chrome/browser/sync/net/fake_network_change_notifier_thread_unittest.cc121
-rw-r--r--chrome/browser/sync/net/network_change_notifier_proxy.cc6
-rw-r--r--chrome/browser/sync/net/network_change_notifier_proxy.h9
-rw-r--r--chrome/browser/sync/net/network_change_notifier_proxy_unittest.cc65
-rw-r--r--chrome/browser/sync/net/network_change_notifier_thread.h37
-rw-r--r--chrome/browser/sync/net/network_change_observer_proxy.cc37
-rw-r--r--chrome/browser/sync/net/network_change_observer_proxy.h14
-rw-r--r--chrome/browser/sync/net/network_change_observer_proxy_unittest.cc96
-rw-r--r--chrome/chrome.gyp1
-rw-r--r--chrome/chrome_tests.gypi3
12 files changed, 381 insertions, 152 deletions
diff --git a/chrome/browser/sync/net/fake_network_change_notifier_thread.cc b/chrome/browser/sync/net/fake_network_change_notifier_thread.cc
new file mode 100644
index 0000000..f0d9c25
--- /dev/null
+++ b/chrome/browser/sync/net/fake_network_change_notifier_thread.cc
@@ -0,0 +1,80 @@
+// 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/browser/sync/net/fake_network_change_notifier_thread.h"
+
+#include "base/logging.h"
+#include "base/message_loop.h"
+#include "chrome/browser/sync/net/thread_blocker.h"
+#include "net/base/mock_network_change_notifier.h"
+
+// We manage the lifetime of
+// browser_sync::FakeNetworkChangeNotifierThread ourselves.
+template <>
+struct RunnableMethodTraits<browser_sync::FakeNetworkChangeNotifierThread> {
+ void RetainCallee(browser_sync::FakeNetworkChangeNotifierThread*) {}
+ void ReleaseCallee(browser_sync::FakeNetworkChangeNotifierThread*) {}
+};
+
+namespace browser_sync {
+
+FakeNetworkChangeNotifierThread::FakeNetworkChangeNotifierThread()
+ : thread_("FakeNetworkChangeNotifierThread") {}
+
+FakeNetworkChangeNotifierThread::~FakeNetworkChangeNotifierThread() {
+ CHECK(!network_change_notifier_.get());
+ CHECK(!thread_blocker_.get());
+ CHECK(!thread_.IsRunning());
+}
+
+void FakeNetworkChangeNotifierThread::Start() {
+ CHECK(thread_.Start());
+ thread_blocker_.reset(new ThreadBlocker(&thread_));
+ network_change_notifier_.reset(new net::MockNetworkChangeNotifier());
+ thread_blocker_->Block();
+}
+
+void FakeNetworkChangeNotifierThread::Pump() {
+ thread_blocker_->Unblock();
+ thread_blocker_->Block();
+}
+
+void FakeNetworkChangeNotifierThread::Stop() {
+ thread_blocker_->Unblock();
+ network_change_notifier_.reset();
+ thread_blocker_.reset();
+ thread_.Stop();
+}
+
+void FakeNetworkChangeNotifierThread::NotifyIPAddressChange() {
+ CHECK(thread_.IsRunning());
+ GetMessageLoop()->PostTask(
+ FROM_HERE,
+ NewRunnableMethod(
+ this,
+ &FakeNetworkChangeNotifierThread::
+ NotifyIPAddressChangeOnSourceThread));
+}
+
+void FakeNetworkChangeNotifierThread::NotifyIPAddressChangeOnSourceThread() {
+ CHECK_EQ(MessageLoop::current(), GetMessageLoop());
+ CHECK(network_change_notifier_.get());
+ network_change_notifier_->NotifyIPAddressChange();
+}
+
+MessageLoop* FakeNetworkChangeNotifierThread::GetMessageLoop() const {
+ CHECK(thread_.IsRunning());
+ MessageLoop* message_loop = thread_.message_loop();
+ CHECK(message_loop);
+ return message_loop;
+}
+
+net::NetworkChangeNotifier*
+FakeNetworkChangeNotifierThread::GetNetworkChangeNotifier() const {
+ CHECK_EQ(MessageLoop::current(), GetMessageLoop());
+ CHECK(network_change_notifier_.get());
+ return network_change_notifier_.get();
+}
+
+} // namespace browser_sync
diff --git a/chrome/browser/sync/net/fake_network_change_notifier_thread.h b/chrome/browser/sync/net/fake_network_change_notifier_thread.h
new file mode 100644
index 0000000..ccc3225
--- /dev/null
+++ b/chrome/browser/sync/net/fake_network_change_notifier_thread.h
@@ -0,0 +1,64 @@
+// 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.
+
+#ifndef CHROME_BROWSER_SYNC_NET_FAKE_NETWORK_CHANGE_NOTIFIER_THREAD_H_
+#define CHROME_BROWSER_SYNC_NET_FAKE_NETWORK_CHANGE_NOTIFIER_THREAD_H_
+
+// A fake implementation of NetworkChangeNotifierThread used for
+// unit-testing.
+
+#include "base/basictypes.h"
+#include "base/scoped_ptr.h"
+#include "base/thread.h"
+#include "chrome/browser/sync/net/network_change_notifier_thread.h"
+
+namespace net {
+class MockNetworkChangeNotifier;
+} // namespace net
+
+namespace browser_sync {
+
+class ThreadBlocker;
+
+class FakeNetworkChangeNotifierThread : public NetworkChangeNotifierThread {
+ public:
+ FakeNetworkChangeNotifierThread();
+
+ virtual ~FakeNetworkChangeNotifierThread();
+
+ // Starts the thread in a blocked state and initializes the network
+ // change notifier.
+ void Start();
+
+ // Runs the tasks that are currently blocked. After this call,
+ // thread remains in a blocked state. A call to this function is a
+ // memory barrier.
+ void Pump();
+
+ // Stops the thread.
+ void Stop();
+
+ // Trigger an IP address change notification on the owned network
+ // change notifier on the owned thread.
+ void NotifyIPAddressChange();
+
+ // Implementation of NetworkChangeNotifierThread.
+
+ virtual MessageLoop* GetMessageLoop() const;
+
+ virtual net::NetworkChangeNotifier* GetNetworkChangeNotifier() const;
+
+ private:
+ void NotifyIPAddressChangeOnSourceThread();
+
+ base::Thread thread_;
+ scoped_ptr<ThreadBlocker> thread_blocker_;
+ scoped_ptr<net::MockNetworkChangeNotifier> network_change_notifier_;
+
+ DISALLOW_COPY_AND_ASSIGN(FakeNetworkChangeNotifierThread);
+};
+
+} // namespace browser_sync
+
+#endif // CHROME_BROWSER_SYNC_NET_FAKE_NETWORK_CHANGE_NOTIFIER_THREAD_H_
diff --git a/chrome/browser/sync/net/fake_network_change_notifier_thread_unittest.cc b/chrome/browser/sync/net/fake_network_change_notifier_thread_unittest.cc
new file mode 100644
index 0000000..02828ce
--- /dev/null
+++ b/chrome/browser/sync/net/fake_network_change_notifier_thread_unittest.cc
@@ -0,0 +1,121 @@
+// 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/browser/sync/net/fake_network_change_notifier_thread.h"
+
+#include "base/basictypes.h"
+#include "base/logging.h"
+#include "base/message_loop.h"
+#include "base/task.h"
+#include "net/base/network_change_notifier.h"
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace browser_sync {
+class FlagToggler;
+} // namespace browser_sync
+
+// We manage the lifetime of browser_sync::FlagToggler ourselves.
+template <>
+struct RunnableMethodTraits<browser_sync::FlagToggler> {
+ void RetainCallee(browser_sync::FlagToggler*) {}
+ void ReleaseCallee(browser_sync::FlagToggler*) {}
+};
+
+namespace browser_sync {
+
+// Utility class that toggles a flag every time it receives an IP
+// address change notification.
+class FlagToggler : public net::NetworkChangeNotifier::Observer {
+ public:
+ FlagToggler() : flag_(false) {}
+
+ virtual ~FlagToggler() {}
+
+ bool flag() const { return flag_; }
+
+ void ToggleFlag() {
+ flag_ = !flag_;
+ }
+
+ void Observe(NetworkChangeNotifierThread* thread) {
+ thread->GetNetworkChangeNotifier()->AddObserver(this);
+ }
+
+ void Unobserve(NetworkChangeNotifierThread* thread) {
+ thread->GetNetworkChangeNotifier()->RemoveObserver(this);
+ }
+
+ // net::NetworkChangeNotifier::Observer implementation.
+ virtual void OnIPAddressChanged() {
+ ToggleFlag();
+ }
+
+ private:
+ bool flag_;
+
+ DISALLOW_COPY_AND_ASSIGN(FlagToggler);
+};
+
+namespace {
+
+class FakeNetworkChangeNotifierTest : public testing::Test {
+ protected:
+ FakeNetworkChangeNotifierTest() {}
+
+ virtual ~FakeNetworkChangeNotifierTest() {}
+
+ virtual void SetUp() {
+ thread_.Start();
+ }
+
+ virtual void TearDown() {
+ thread_.Stop();
+ }
+
+ FakeNetworkChangeNotifierThread thread_;
+ FlagToggler flag_toggler_;
+
+ private:
+ DISALLOW_COPY_AND_ASSIGN(FakeNetworkChangeNotifierTest);
+};
+
+TEST_F(FakeNetworkChangeNotifierTest, Pump) {
+ thread_.GetMessageLoop()->PostTask(
+ FROM_HERE, NewRunnableMethod(&flag_toggler_, &FlagToggler::ToggleFlag));
+ EXPECT_FALSE(flag_toggler_.flag());
+ thread_.Pump();
+ EXPECT_TRUE(flag_toggler_.flag());
+}
+
+TEST_F(FakeNetworkChangeNotifierTest, Basic) {
+ thread_.GetMessageLoop()->PostTask(
+ FROM_HERE,
+ NewRunnableMethod(&flag_toggler_, &FlagToggler::Observe, &thread_));
+ thread_.NotifyIPAddressChange();
+ thread_.GetMessageLoop()->PostTask(
+ FROM_HERE,
+ NewRunnableMethod(&flag_toggler_, &FlagToggler::Unobserve, &thread_));
+ EXPECT_FALSE(flag_toggler_.flag());
+ thread_.Pump();
+ EXPECT_TRUE(flag_toggler_.flag());
+}
+
+TEST_F(FakeNetworkChangeNotifierTest, Multiple) {
+ FlagToggler observer;
+ thread_.GetMessageLoop()->PostTask(
+ FROM_HERE,
+ NewRunnableMethod(&flag_toggler_, &FlagToggler::Observe, &thread_));
+ thread_.NotifyIPAddressChange();
+ thread_.NotifyIPAddressChange();
+ thread_.GetMessageLoop()->PostTask(
+ FROM_HERE,
+ NewRunnableMethod(&flag_toggler_, &FlagToggler::Unobserve, &thread_));
+ EXPECT_FALSE(flag_toggler_.flag());
+ thread_.Pump();
+ EXPECT_FALSE(flag_toggler_.flag());
+}
+
+} // namespace
+
+} // namespace browser_sync
diff --git a/chrome/browser/sync/net/network_change_notifier_proxy.cc b/chrome/browser/sync/net/network_change_notifier_proxy.cc
index 7176da3..e1b3797 100644
--- a/chrome/browser/sync/net/network_change_notifier_proxy.cc
+++ b/chrome/browser/sync/net/network_change_notifier_proxy.cc
@@ -11,11 +11,9 @@
namespace browser_sync {
NetworkChangeNotifierProxy::NetworkChangeNotifierProxy(
- MessageLoop* source_message_loop,
- net::NetworkChangeNotifier* source_network_change_notifier)
+ NetworkChangeNotifierThread* source_thread)
: observer_proxy_(new NetworkChangeObserverProxy(
- source_message_loop, source_network_change_notifier,
- MessageLoop::current())),
+ source_thread, MessageLoop::current())),
observer_repeater_(&observers_) {
// TODO(akalin): We get this from NonThreadSafe, which
// net::NetworkChangeNotifier inherits from. Interface classes
diff --git a/chrome/browser/sync/net/network_change_notifier_proxy.h b/chrome/browser/sync/net/network_change_notifier_proxy.h
index 517d705..2789abc 100644
--- a/chrome/browser/sync/net/network_change_notifier_proxy.h
+++ b/chrome/browser/sync/net/network_change_notifier_proxy.h
@@ -18,16 +18,15 @@ class MessageLoop;
namespace browser_sync {
+class NetworkChangeNotifierThread;
class NetworkChangeObserverProxy;
class NetworkChangeNotifierProxy : public net::NetworkChangeNotifier {
public:
- // Both source_thread and source_network_change_notifier must be
- // guaranteed to outlive the current thread. Does not take
- // ownership of any arguments.
+ // |source_thread| must be guaranteed to outlive the current thread.
+ // Does not take ownership of any arguments.
NetworkChangeNotifierProxy(
- MessageLoop* source_message_loop,
- net::NetworkChangeNotifier* source_network_change_notifier);
+ NetworkChangeNotifierThread* source_thread);
virtual ~NetworkChangeNotifierProxy();
diff --git a/chrome/browser/sync/net/network_change_notifier_proxy_unittest.cc b/chrome/browser/sync/net/network_change_notifier_proxy_unittest.cc
index 5e095fd7..d92e078 100644
--- a/chrome/browser/sync/net/network_change_notifier_proxy_unittest.cc
+++ b/chrome/browser/sync/net/network_change_notifier_proxy_unittest.cc
@@ -6,83 +6,44 @@
#include "base/basictypes.h"
#include "base/logging.h"
-#include "base/message_loop.h"
#include "base/ref_counted.h"
#include "base/scoped_ptr.h"
-#include "base/task.h"
-#include "base/thread.h"
+#include "chrome/browser/sync/net/fake_network_change_notifier_thread.h"
#include "chrome/browser/sync/net/mock_network_change_observer.h"
-#include "chrome/browser/sync/net/thread_blocker.h"
-#include "net/base/mock_network_change_notifier.h"
#include "net/base/network_change_notifier.h"
-#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
-// We manage the lifetime of net::MockNetworkChangeNotifier ourselves.
-template <>
-struct RunnableMethodTraits<net::MockNetworkChangeNotifier> {
- void RetainCallee(net::MockNetworkChangeNotifier*) {}
- void ReleaseCallee(net::MockNetworkChangeNotifier*) {}
-};
-
namespace browser_sync {
namespace {
class NetworkChangeNotifierProxyTest : public testing::Test {
protected:
- NetworkChangeNotifierProxyTest()
- : source_thread_("Source Thread"),
- source_message_loop_(NULL) {}
+ NetworkChangeNotifierProxyTest() {}
- virtual ~NetworkChangeNotifierProxyTest() {
- CHECK(!source_thread_blocker_.get());
- CHECK(!source_message_loop_);
- }
+ virtual ~NetworkChangeNotifierProxyTest() {}
virtual void SetUp() {
- CHECK(source_thread_.Start());
- source_message_loop_ = source_thread_.message_loop();
- source_thread_blocker_.reset(new ThreadBlocker(&source_thread_));
- source_thread_blocker_->Block();
-
- notifier_proxy_.reset(new NetworkChangeNotifierProxy(
- source_message_loop_, &source_network_change_notifier_));
+ source_thread_.Start();
+ notifier_proxy_.reset(new NetworkChangeNotifierProxy(&source_thread_));
}
virtual void TearDown() {
// Posts a task to the source thread.
notifier_proxy_.reset();
- source_thread_blocker_->Unblock();
- source_thread_blocker_.reset();
- source_message_loop_ = NULL;
source_thread_.Stop();
}
// Trigger an "IP address changed" event on the source network
// change notifier on the source thread and propagate any generated
// notifications to the target thread.
- void OnIPAddressChanged() {
- source_message_loop_->PostTask(
- FROM_HERE,
- NewRunnableMethod(
- &source_network_change_notifier_,
- &net::MockNetworkChangeNotifier::NotifyIPAddressChange));
- // Pump source thread.
- source_thread_blocker_->Unblock();
- source_thread_blocker_->Block();
- // Pump target thread.
+ void NotifyIPAddressChange() {
+ source_thread_.NotifyIPAddressChange();
+ source_thread_.Pump();
target_message_loop_.RunAllPending();
}
- // This lives on |source_thread_| but is created/destroyed in the
- // main thread. As long as we make sure to not modify it from the
- // main thread while |source_thread_| is running, we shouldn't need
- // any special synchronization.
- net::MockNetworkChangeNotifier source_network_change_notifier_;
- base::Thread source_thread_;
- MessageLoop* source_message_loop_;
- scoped_ptr<ThreadBlocker> source_thread_blocker_;
+ FakeNetworkChangeNotifierThread source_thread_;
MessageLoop target_message_loop_;
MockNetworkChangeObserver target_observer_;
@@ -97,7 +58,7 @@ TEST_F(NetworkChangeNotifierProxyTest, Basic) {
EXPECT_CALL(target_observer_, OnIPAddressChanged()).Times(1);
notifier_proxy_->AddObserver(&target_observer_);
- OnIPAddressChanged();
+ NotifyIPAddressChange();
notifier_proxy_->RemoveObserver(&target_observer_);
}
@@ -106,13 +67,13 @@ TEST_F(NetworkChangeNotifierProxyTest, IgnoresEventAfterRemoveObserver) {
notifier_proxy_->AddObserver(&target_observer_);
notifier_proxy_->RemoveObserver(&target_observer_);
- OnIPAddressChanged();
+ NotifyIPAddressChange();
}
TEST_F(NetworkChangeNotifierProxyTest, IgnoresEventBeforeRemoveObserver) {
EXPECT_CALL(target_observer_, OnIPAddressChanged()).Times(0);
- OnIPAddressChanged();
+ NotifyIPAddressChange();
notifier_proxy_->AddObserver(&target_observer_);
notifier_proxy_->RemoveObserver(&target_observer_);
}
@@ -129,7 +90,7 @@ TEST_F(NetworkChangeNotifierProxyTest, Multiple) {
for (int i = 0; i < kNumObservers; ++i) {
notifier_proxy_->AddObserver(&extra_observers[i]);
}
- OnIPAddressChanged();
+ NotifyIPAddressChange();
for (int i = 0; i < kNumObservers; ++i) {
notifier_proxy_->RemoveObserver(&extra_observers[i]);
}
diff --git a/chrome/browser/sync/net/network_change_notifier_thread.h b/chrome/browser/sync/net/network_change_notifier_thread.h
new file mode 100644
index 0000000..e7fe375
--- /dev/null
+++ b/chrome/browser/sync/net/network_change_notifier_thread.h
@@ -0,0 +1,37 @@
+// 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.
+
+#ifndef CHROME_BROWSER_SYNC_NET_NETWORK_CHANGE_NOTIFIER_THREAD_H_
+#define CHROME_BROWSER_SYNC_NET_NETWORK_CHANGE_NOTIFIER_THREAD_H_
+
+// A simple interface that represents a thread which owns a
+// NetworkChangeNotifier.
+
+class MessageLoop;
+
+namespace net {
+class NetworkChangeNotifier;
+} // namespace net
+
+namespace browser_sync {
+
+// An instance of this interface must live no longer than the thread
+// it represents and its message loop and network change notifier.
+class NetworkChangeNotifierThread {
+ public:
+ virtual ~NetworkChangeNotifierThread() {}
+
+ // Returns the message loop for the thread that owns the
+ // NetworkChangeNotifier. Can be called on any thread.
+ virtual MessageLoop* GetMessageLoop() const = 0;
+
+ // Returns the NetworkChangeNotifier of the thread. This method
+ // must be called only from the owning thread (i.e., by posting a
+ // task onto the message loop returned by GetMessageLoop()).
+ virtual net::NetworkChangeNotifier* GetNetworkChangeNotifier() const = 0;
+};
+
+} // namespace browser_sync
+
+#endif // CHROME_BROWSER_SYNC_NET_NETWORK_CHANGE_NOTIFIER_THREAD_H_
diff --git a/chrome/browser/sync/net/network_change_observer_proxy.cc b/chrome/browser/sync/net/network_change_observer_proxy.cc
index b40a530..490ba5423 100644
--- a/chrome/browser/sync/net/network_change_observer_proxy.cc
+++ b/chrome/browser/sync/net/network_change_observer_proxy.cc
@@ -44,21 +44,22 @@
#include "base/logging.h"
#include "base/message_loop.h"
#include "base/task.h"
+#include "chrome/browser/sync/net/network_change_notifier_thread.h"
+#include "net/base/network_change_notifier.h"
namespace browser_sync {
NetworkChangeObserverProxy::NetworkChangeObserverProxy(
- MessageLoop* source_message_loop,
- net::NetworkChangeNotifier* source_network_change_notifier,
+ const NetworkChangeNotifierThread* source_thread,
MessageLoop* target_message_loop)
- : source_message_loop_(source_message_loop),
- source_network_change_notifier_(source_network_change_notifier),
+ : source_thread_(source_thread),
target_message_loop_(target_message_loop),
target_observer_(NULL) {
- DCHECK(source_message_loop_);
- DCHECK(source_network_change_notifier_);
+ DCHECK(source_thread_);
+ MessageLoop* source_message_loop = source_thread_->GetMessageLoop();
+ DCHECK(source_message_loop);
DCHECK(target_message_loop_);
- DCHECK_NE(source_message_loop_, target_message_loop_);
+ DCHECK_NE(source_message_loop, target_message_loop_);
DCHECK_EQ(MessageLoop::current(), target_message_loop_);
}
@@ -66,7 +67,7 @@ NetworkChangeObserverProxy::~NetworkChangeObserverProxy() {
MessageLoop* current_message_loop = MessageLoop::current();
// We can be deleted on either the source or target thread, so the
// best we can do is check that we're on either.
- DCHECK((current_message_loop == source_message_loop_) ||
+ DCHECK((current_message_loop == source_thread_->GetMessageLoop()) ||
(current_message_loop == target_message_loop_));
// Even though only the target thread uses target_observer_, it
// should still be unset even if we're on the source thread; posting
@@ -75,15 +76,21 @@ NetworkChangeObserverProxy::~NetworkChangeObserverProxy() {
}
void NetworkChangeObserverProxy::Observe() {
- DCHECK_EQ(MessageLoop::current(), source_message_loop_);
- source_network_change_notifier_->AddObserver(this);
+ DCHECK_EQ(MessageLoop::current(), source_thread_->GetMessageLoop());
+ net::NetworkChangeNotifier* source_network_change_notifier =
+ source_thread_->GetNetworkChangeNotifier();
+ DCHECK(source_network_change_notifier);
+ source_network_change_notifier->AddObserver(this);
}
// The Task from which this was called may hold the last reference to
// us (this is how we can get deleted on the source thread).
void NetworkChangeObserverProxy::Unobserve() {
- DCHECK_EQ(MessageLoop::current(), source_message_loop_);
- source_network_change_notifier_->RemoveObserver(this);
+ DCHECK_EQ(MessageLoop::current(), source_thread_->GetMessageLoop());
+ net::NetworkChangeNotifier* source_network_change_notifier =
+ source_thread_->GetNetworkChangeNotifier();
+ DCHECK(source_network_change_notifier);
+ source_network_change_notifier->RemoveObserver(this);
}
void NetworkChangeObserverProxy::Attach(
@@ -92,7 +99,7 @@ void NetworkChangeObserverProxy::Attach(
DCHECK(!target_observer_);
target_observer_ = target_observer;
DCHECK(target_observer_);
- source_message_loop_->PostTask(
+ source_thread_->GetMessageLoop()->PostTask(
FROM_HERE,
NewRunnableMethod(this, &NetworkChangeObserverProxy::Observe));
}
@@ -101,7 +108,7 @@ void NetworkChangeObserverProxy::Detach() {
DCHECK_EQ(MessageLoop::current(), target_message_loop_);
DCHECK(target_observer_);
target_observer_ = NULL;
- source_message_loop_->PostTask(
+ source_thread_->GetMessageLoop()->PostTask(
FROM_HERE,
NewRunnableMethod(this, &NetworkChangeObserverProxy::Unobserve));
}
@@ -111,7 +118,7 @@ void NetworkChangeObserverProxy::Detach() {
// But we know that it has been posted, so it at least holds a
// reference to us.
void NetworkChangeObserverProxy::OnIPAddressChanged() {
- DCHECK_EQ(MessageLoop::current(), source_message_loop_);
+ DCHECK_EQ(MessageLoop::current(), source_thread_->GetMessageLoop());
target_message_loop_->PostTask(
FROM_HERE,
NewRunnableMethod(
diff --git a/chrome/browser/sync/net/network_change_observer_proxy.h b/chrome/browser/sync/net/network_change_observer_proxy.h
index 184f5cb..34374e5 100644
--- a/chrome/browser/sync/net/network_change_observer_proxy.h
+++ b/chrome/browser/sync/net/network_change_observer_proxy.h
@@ -14,12 +14,12 @@
//
// In the target thread, create the observer proxy:
//
+// NetworkChangeNotifierThread* source_thread = ...;
// NetworkChangeObserverProxy* proxy =
-// new NetworkChangeObserverProxy(source_thread->message_loop(),
-// source_network_change_notifier,
+// new NetworkChangeObserverProxy(source_thread,
// MessageLoop::current());
//
-// Both source_thread and source_network_change_notifier must be
+// Both source_thread and its owned NetworkChangeNotifier must be
// guaranteed to outlive the target (current) thread.
//
// Then, attach the target observer:
@@ -45,6 +45,8 @@
namespace browser_sync {
+class NetworkChangeNotifierThread;
+
// TODO(akalin): Remove use of private inheritance.
class NetworkChangeObserverProxy
: public base::RefCountedThreadSafe<NetworkChangeObserverProxy>,
@@ -55,8 +57,7 @@ class NetworkChangeObserverProxy
// Does not take ownership of any arguments.
NetworkChangeObserverProxy(
- MessageLoop* source_message_loop,
- net::NetworkChangeNotifier* source_network_change_notifier,
+ const NetworkChangeNotifierThread* source_thread,
MessageLoop* target_message_loop);
// After this method is called, |target_observer| will start
@@ -100,8 +101,7 @@ class NetworkChangeObserverProxy
// |target_observer_|.
void TargetObserverOnIPAddressChanged();
- MessageLoop* const source_message_loop_;
- net::NetworkChangeNotifier* const source_network_change_notifier_;
+ const NetworkChangeNotifierThread* source_thread_;
MessageLoop* const target_message_loop_;
// |target_observer_| is used only by the target thread.
net::NetworkChangeNotifier::Observer* target_observer_;
diff --git a/chrome/browser/sync/net/network_change_observer_proxy_unittest.cc b/chrome/browser/sync/net/network_change_observer_proxy_unittest.cc
index ba78e89..c39184b 100644
--- a/chrome/browser/sync/net/network_change_observer_proxy_unittest.cc
+++ b/chrome/browser/sync/net/network_change_observer_proxy_unittest.cc
@@ -6,25 +6,11 @@
#include "base/basictypes.h"
#include "base/logging.h"
-#include "base/message_loop.h"
#include "base/ref_counted.h"
-#include "base/scoped_ptr.h"
-#include "base/task.h"
-#include "base/thread.h"
+#include "chrome/browser/sync/net/fake_network_change_notifier_thread.h"
#include "chrome/browser/sync/net/mock_network_change_observer.h"
-#include "chrome/browser/sync/net/thread_blocker.h"
-#include "net/base/mock_network_change_notifier.h"
-#include "net/base/network_change_notifier.h"
-#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
-// We manage the lifetime of net::MockNetworkChangeNotifier ourselves.
-template <>
-struct RunnableMethodTraits<net::MockNetworkChangeNotifier> {
- void RetainCallee(net::MockNetworkChangeNotifier*) {}
- void ReleaseCallee(net::MockNetworkChangeNotifier*) {}
-};
-
namespace browser_sync {
namespace {
@@ -37,13 +23,10 @@ class DeleteCheckingNetworkChangeObserverProxy
// *deleting_message_loop_ must be NULL. It is set to a non-NULL
// *value when this object is deleted.
DeleteCheckingNetworkChangeObserverProxy(
- MessageLoop* source_message_loop,
- net::NetworkChangeNotifier* source_network_change_notifier,
+ NetworkChangeNotifierThread* source_thread,
MessageLoop* target_message_loop,
MessageLoop** deleting_message_loop)
- : NetworkChangeObserverProxy(source_message_loop,
- source_network_change_notifier,
- target_message_loop),
+ : NetworkChangeObserverProxy(source_thread, target_message_loop),
deleting_message_loop_(deleting_message_loop) {
CHECK(deleting_message_loop_);
EXPECT_TRUE(*deleting_message_loop_ == NULL);
@@ -61,26 +44,16 @@ class DeleteCheckingNetworkChangeObserverProxy
class NetworkChangeObserverProxyTest : public testing::Test {
protected:
- NetworkChangeObserverProxyTest()
- : source_thread_("Source Thread"),
- source_message_loop_(NULL),
- proxy_deleting_message_loop_(NULL) {}
-
- virtual ~NetworkChangeObserverProxyTest() {
- CHECK(!source_thread_blocker_.get());
- CHECK(!source_message_loop_);
- }
+ NetworkChangeObserverProxyTest() : proxy_deleting_message_loop_(NULL) {}
- virtual void SetUp() {
- CHECK(source_thread_.Start());
- source_message_loop_ = source_thread_.message_loop();
- source_thread_blocker_.reset(new ThreadBlocker(&source_thread_));
- source_thread_blocker_->Block();
+ virtual ~NetworkChangeObserverProxyTest() {}
+ virtual void SetUp() {
+ source_thread_.Start();
proxy_deleting_message_loop_ = NULL;
proxy_ = new DeleteCheckingNetworkChangeObserverProxy(
- source_message_loop_, &source_network_change_notifier_,
- &target_message_loop_, &proxy_deleting_message_loop_);
+ &source_thread_, &target_message_loop_,
+ &proxy_deleting_message_loop_);
}
// On TearDown, |proxy_| must be released and both source and target
@@ -88,16 +61,12 @@ class NetworkChangeObserverProxyTest : public testing::Test {
virtual void TearDown() {
EXPECT_TRUE(proxy_ == NULL);
EXPECT_TRUE(proxy_deleting_message_loop_ != NULL);
- source_thread_blocker_->Unblock();
- source_thread_blocker_.reset();
- source_message_loop_ = NULL;
source_thread_.Stop();
}
// Pump any events posted on the source thread.
void PumpSource() {
- source_thread_blocker_->Unblock();
- source_thread_blocker_->Block();
+ source_thread_.Pump();
}
// Pump any events posted on the target thread (which is just the
@@ -108,22 +77,11 @@ class NetworkChangeObserverProxyTest : public testing::Test {
// Trigger an "IP address changed" event on the source network
// change notifier on the source thread.
- void OnIPAddressChanged() {
- source_message_loop_->PostTask(
- FROM_HERE,
- NewRunnableMethod(
- &source_network_change_notifier_,
- &net::MockNetworkChangeNotifier::NotifyIPAddressChange));
+ void NotifyIPAddressChange() {
+ source_thread_.NotifyIPAddressChange();
}
- // This lives on |source_thread_| but is created/destroyed in the
- // main thread. As long as we make sure to not modify it from the
- // main thread while |source_thread_| is running, we shouldn't need
- // any special synchronization.
- net::MockNetworkChangeNotifier source_network_change_notifier_;
- base::Thread source_thread_;
- MessageLoop* source_message_loop_;
- scoped_ptr<ThreadBlocker> source_thread_blocker_;
+ FakeNetworkChangeNotifierThread source_thread_;
MessageLoop target_message_loop_;
MockNetworkChangeObserver target_observer_;
@@ -153,7 +111,7 @@ TEST_F(NetworkChangeObserverProxyTest, AttachDetach) {
proxy_ = NULL;
PumpSource();
- EXPECT_EQ(proxy_deleting_message_loop_, source_message_loop_);
+ EXPECT_EQ(proxy_deleting_message_loop_, source_thread_.GetMessageLoop());
}
TEST_F(NetworkChangeObserverProxyTest, AttachDetachReleaseAfterPump) {
@@ -171,14 +129,14 @@ TEST_F(NetworkChangeObserverProxyTest, Basic) {
EXPECT_CALL(target_observer_, OnIPAddressChanged()).Times(1);
proxy_->Attach(&target_observer_);
- OnIPAddressChanged();
+ NotifyIPAddressChange();
PumpSource();
PumpTarget();
proxy_->Detach();
proxy_ = NULL;
PumpSource();
- EXPECT_EQ(proxy_deleting_message_loop_, source_message_loop_);
+ EXPECT_EQ(proxy_deleting_message_loop_, source_thread_.GetMessageLoop());
}
TEST_F(NetworkChangeObserverProxyTest, Multiple) {
@@ -187,7 +145,7 @@ TEST_F(NetworkChangeObserverProxyTest, Multiple) {
proxy_->Attach(&target_observer_);
for (int i = 0; i < kTimes; ++i) {
- OnIPAddressChanged();
+ NotifyIPAddressChange();
}
PumpSource();
PumpTarget();
@@ -195,7 +153,7 @@ TEST_F(NetworkChangeObserverProxyTest, Multiple) {
proxy_ = NULL;
PumpSource();
- EXPECT_EQ(proxy_deleting_message_loop_, source_message_loop_);
+ EXPECT_EQ(proxy_deleting_message_loop_, source_thread_.GetMessageLoop());
}
TEST_F(NetworkChangeObserverProxyTest, MultipleAttachDetach) {
@@ -204,7 +162,7 @@ TEST_F(NetworkChangeObserverProxyTest, MultipleAttachDetach) {
for (int i = 0; i < kTimes; ++i) {
proxy_->Attach(&target_observer_);
- OnIPAddressChanged();
+ NotifyIPAddressChange();
PumpSource();
PumpTarget();
proxy_->Detach();
@@ -212,14 +170,14 @@ TEST_F(NetworkChangeObserverProxyTest, MultipleAttachDetach) {
proxy_ = NULL;
PumpSource();
- EXPECT_EQ(proxy_deleting_message_loop_, source_message_loop_);
+ EXPECT_EQ(proxy_deleting_message_loop_, source_thread_.GetMessageLoop());
}
TEST_F(NetworkChangeObserverProxyTest, IgnoresEventPostedAfterDetach) {
EXPECT_CALL(target_observer_, OnIPAddressChanged()).Times(0);
proxy_->Attach(&target_observer_);
- OnIPAddressChanged();
+ NotifyIPAddressChange();
proxy_->Detach();
proxy_ = NULL;
PumpSource();
@@ -232,14 +190,14 @@ TEST_F(NetworkChangeObserverProxyTest, IgnoresEventPostedBeforeDetach) {
EXPECT_CALL(target_observer_, OnIPAddressChanged()).Times(0);
proxy_->Attach(&target_observer_);
- OnIPAddressChanged();
+ NotifyIPAddressChange();
PumpSource();
proxy_->Detach();
proxy_ = NULL;
PumpTarget();
PumpSource();
- EXPECT_EQ(proxy_deleting_message_loop_, source_message_loop_);
+ EXPECT_EQ(proxy_deleting_message_loop_, source_thread_.GetMessageLoop());
}
TEST_F(NetworkChangeObserverProxyTest, IgnoresEventAfterDetach) {
@@ -248,23 +206,23 @@ TEST_F(NetworkChangeObserverProxyTest, IgnoresEventAfterDetach) {
proxy_->Attach(&target_observer_);
proxy_->Detach();
proxy_ = NULL;
- OnIPAddressChanged();
+ NotifyIPAddressChange();
PumpSource();
- EXPECT_EQ(proxy_deleting_message_loop_, source_message_loop_);
+ EXPECT_EQ(proxy_deleting_message_loop_, source_thread_.GetMessageLoop());
}
TEST_F(NetworkChangeObserverProxyTest, IgnoresEventBeforeAttach) {
EXPECT_CALL(target_observer_, OnIPAddressChanged()).Times(0);
- OnIPAddressChanged();
+ NotifyIPAddressChange();
PumpSource();
proxy_->Attach(&target_observer_);
proxy_->Detach();
proxy_ = NULL;
PumpSource();
- EXPECT_EQ(proxy_deleting_message_loop_, source_message_loop_);
+ EXPECT_EQ(proxy_deleting_message_loop_, source_thread_.GetMessageLoop());
}
} // namespace
diff --git a/chrome/chrome.gyp b/chrome/chrome.gyp
index 48ef083..265a336 100644
--- a/chrome/chrome.gyp
+++ b/chrome/chrome.gyp
@@ -981,6 +981,7 @@
'sources': [
'browser/sync/net/network_change_notifier_proxy.cc',
'browser/sync/net/network_change_notifier_proxy.h',
+ 'browser/sync/net/network_change_notifier_thread.h',
'browser/sync/net/network_change_observer_proxy.cc',
'browser/sync/net/network_change_observer_proxy.h',
],
diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi
index 1f601b3..1450cce 100644
--- a/chrome/chrome_tests.gypi
+++ b/chrome/chrome_tests.gypi
@@ -1841,6 +1841,9 @@
# TODO(akalin): Write our own test suite and runner.
'../base/test/run_all_unittests.cc',
'../base/test/test_suite.h',
+ 'browser/sync/net/fake_network_change_notifier_thread_unittest.cc',
+ 'browser/sync/net/fake_network_change_notifier_thread.cc',
+ 'browser/sync/net/fake_network_change_notifier_thread.h',
'browser/sync/net/mock_network_change_observer.h',
'browser/sync/net/network_change_notifier_proxy_unittest.cc',
'browser/sync/net/network_change_observer_proxy_unittest.cc',