blob: d2a4bcd79b9ff62ce955ec9e55080a7234f77e37 [file] [log] [blame]
// Copyright (c) 2011 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 "content/public/test/test_browser_thread.h"
#include "base/macros.h"
#include "base/memory/ptr_util.h"
#include "base/message_loop/message_loop.h"
#include "base/threading/thread.h"
#include "build/build_config.h"
#include "content/browser/browser_thread_impl.h"
#include "content/browser/notification_service_impl.h"
#if defined(OS_WIN)
#include "base/win/scoped_com_initializer.h"
#endif
namespace content {
class TestBrowserThreadImpl : public BrowserThreadImpl {
public:
explicit TestBrowserThreadImpl(BrowserThread::ID identifier)
: BrowserThreadImpl(identifier) {}
TestBrowserThreadImpl(BrowserThread::ID identifier,
base::MessageLoop* message_loop)
: BrowserThreadImpl(identifier, message_loop) {}
~TestBrowserThreadImpl() override { Stop(); }
void Init() override {
#if defined(OS_WIN)
com_initializer_ = std::make_unique<base::win::ScopedCOMInitializer>();
#endif
notification_service_ = std::make_unique<NotificationServiceImpl>();
BrowserThreadImpl::Init();
}
void CleanUp() override {
BrowserThreadImpl::CleanUp();
notification_service_.reset();
#if defined(OS_WIN)
com_initializer_.reset();
#endif
}
private:
#if defined(OS_WIN)
std::unique_ptr<base::win::ScopedCOMInitializer> com_initializer_;
#endif
std::unique_ptr<NotificationService> notification_service_;
DISALLOW_COPY_AND_ASSIGN(TestBrowserThreadImpl);
};
TestBrowserThread::TestBrowserThread(BrowserThread::ID identifier)
: impl_(new TestBrowserThreadImpl(identifier)), identifier_(identifier) {}
TestBrowserThread::TestBrowserThread(BrowserThread::ID identifier,
base::MessageLoop* message_loop)
: impl_(new TestBrowserThreadImpl(identifier, message_loop)),
identifier_(identifier) {}
TestBrowserThread::~TestBrowserThread() {
// The upcoming BrowserThreadImpl::ResetGlobalsForTesting() call requires that
// |impl_| have triggered the shutdown phase for its BrowserThread::ID. This
// either happens when the thread is stopped (if real) or destroyed (when fake
// -- i.e. using an externally provided MessageLoop).
impl_.reset();
// Resets BrowserThreadImpl's globals so that |impl_| is no longer bound to
// |identifier_|. This is fine since the underlying MessageLoop has already
// been flushed and deleted in Stop(). In the case of an externally provided
// MessageLoop however, this means that TaskRunners obtained through
// |BrowserThreadImpl::GetTaskRunnerForThread(identifier_)| will no longer
// recognize their BrowserThreadImpl for RunsTasksInCurrentSequence(). This
// happens most often when such verifications are made from
// MessageLoop::DestructionObservers. Callers that care to work around that
// should instead use this shutdown sequence:
// 1) TestBrowserThread::Stop()
// 2) ~MessageLoop()
// 3) ~TestBrowserThread()
// (~TestBrowserThreadBundle() does this).
BrowserThreadImpl::ResetGlobalsForTesting(identifier_);
}
bool TestBrowserThread::Start() {
return impl_->Start();
}
bool TestBrowserThread::StartAndWaitForTesting() {
return impl_->StartAndWaitForTesting();
}
bool TestBrowserThread::StartIOThread() {
base::Thread::Options options;
options.message_loop_type = base::MessageLoop::TYPE_IO;
return impl_->StartWithOptions(options);
}
void TestBrowserThread::InitIOThreadDelegate() {
impl_->InitIOThreadDelegate();
}
void TestBrowserThread::Stop() {
impl_->Stop();
}
bool TestBrowserThread::IsRunning() {
return impl_->IsRunning();
}
} // namespace content