summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorakalin@chromium.org <akalin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-12-15 19:20:08 +0000
committerakalin@chromium.org <akalin@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-12-15 19:20:08 +0000
commit84c106d7a463a00b1522cda0cb8e92c021ff13c3 (patch)
treef2bf124305c8938475e596e02fbcefa3745eb1ae
parent6638395119900baf70f5c9dac2921d5a1b7aff17 (diff)
downloadchromium_src-84c106d7a463a00b1522cda0cb8e92c021ff13c3.zip
chromium_src-84c106d7a463a00b1522cda0cb8e92c021ff13c3.tar.gz
chromium_src-84c106d7a463a00b1522cda0cb8e92c021ff13c3.tar.bz2
Implemented OS X version of NetworkStatusDetectorTaskMac.
BUG=none TEST=trybots,manual testing Review URL: http://codereview.chromium.org/485004 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@34578 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/sync/notifier/base/mac/network_status_detector_task_mac.cc252
-rw-r--r--chrome/browser/sync/notifier/base/mac/network_status_detector_task_mac.h154
-rw-r--r--chrome/browser/sync/notifier/base/mac/network_status_detector_task_mac_unittest.cc111
-rwxr-xr-xchrome/chrome.gyp1
-rwxr-xr-xchrome/chrome_tests.gypi1
5 files changed, 516 insertions, 3 deletions
diff --git a/chrome/browser/sync/notifier/base/mac/network_status_detector_task_mac.cc b/chrome/browser/sync/notifier/base/mac/network_status_detector_task_mac.cc
index 527df79..fe2faa2 100644
--- a/chrome/browser/sync/notifier/base/mac/network_status_detector_task_mac.cc
+++ b/chrome/browser/sync/notifier/base/mac/network_status_detector_task_mac.cc
@@ -2,14 +2,260 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-#include "chrome/browser/sync/notifier/base/network_status_detector_task.h"
+#include "chrome/browser/sync/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) {
- // TODO(sync): No implementation for OS X.
- return NULL;
+ 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/browser/sync/notifier/base/mac/network_status_detector_task_mac.h b/chrome/browser/sync/notifier/base/mac/network_status_detector_task_mac.h
new file mode 100644
index 0000000..bf10c60
--- /dev/null
+++ b/chrome/browser/sync/notifier/base/mac/network_status_detector_task_mac.h
@@ -0,0 +1,154 @@
+// 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_BROWSER_SYNC_NOTIFIER_BASE_MAC_NETWORK_STATUS_DETECTOR_TASK_MAC_H_
+#define CHROME_BROWSER_SYNC_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/browser/sync/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_BROWSER_SYNC_NOTIFIER_BASE_MAC_NETWORK_STATUS_DETECTOR_TASK_MAC_H_
+
diff --git a/chrome/browser/sync/notifier/base/mac/network_status_detector_task_mac_unittest.cc b/chrome/browser/sync/notifier/base/mac/network_status_detector_task_mac_unittest.cc
new file mode 100644
index 0000000..351d5eb
--- /dev/null
+++ b/chrome/browser/sync/notifier/base/mac/network_status_detector_task_mac_unittest.cc
@@ -0,0 +1,111 @@
+// 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/browser/sync/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/chrome.gyp b/chrome/chrome.gyp
index 8e909cf..031020e 100755
--- a/chrome/chrome.gyp
+++ b/chrome/chrome.gyp
@@ -1424,6 +1424,7 @@
'browser/sync/notifier/base/async_network_alive.h',
'browser/sync/notifier/base/fastalloc.h',
'browser/sync/notifier/base/linux/network_status_detector_task_linux.cc',
+ 'browser/sync/notifier/base/mac/network_status_detector_task_mac.h',
'browser/sync/notifier/base/mac/network_status_detector_task_mac.cc',
'browser/sync/notifier/base/nethelpers.cc',
'browser/sync/notifier/base/nethelpers.h',
diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi
index 495ba3d..feb4fbf 100755
--- a/chrome/chrome_tests.gypi
+++ b/chrome/chrome_tests.gypi
@@ -1412,6 +1412,7 @@
'browser/sync/engine/syncer_thread_unittest.cc',
'browser/sync/engine/syncer_unittest.cc',
'browser/sync/engine/syncproto_unittest.cc',
+ 'browser/sync/notifier/base/mac/network_status_detector_task_mac_unittest.cc',
'browser/sync/notifier/listener/talk_mediator_unittest.cc',
'browser/sync/sessions/status_controller_unittest.cc',
'browser/sync/sessions/sync_session_unittest.cc',