Skip to content

Commit

Permalink
Remove dependency on content from remoting_host.
Browse files Browse the repository at this point in the history
The host was depending on content just to access content::BrowserThread.
It's cleaner to just pass the references to the threads explicitly.

BUG=458581

Committed: https://crrev.com/d5197934178ef0da1b630792cfbda8ddb6b34388
Cr-Commit-Position: refs/heads/master@{#316648}

Review URL: https://codereview.chromium.org/929493002

Cr-Commit-Position: refs/heads/master@{#316746}
  • Loading branch information
SergeyUlanov authored and Commit bot committed Feb 18, 2015
1 parent 42a2538 commit f87c35d
Show file tree
Hide file tree
Showing 10 changed files with 85 additions and 132 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
#include "chrome/browser/browser_process.h"
#include "chrome/browser/extensions/api/messaging/native_messaging_test_util.h"
#include "components/policy/core/common/policy_service.h"
#include "content/public/browser/browser_thread.h"
#include "extensions/common/constants.h"
#include "extensions/common/url_pattern.h"
#include "net/url_request/url_request_context_getter.h"
Expand Down Expand Up @@ -96,7 +97,13 @@ scoped_ptr<NativeMessageHost> CreateIt2MeHost() {
host_factory->set_policy_service(g_browser_process->policy_service());
scoped_ptr<remoting::ChromotingHostContext> context =
remoting::ChromotingHostContext::CreateForChromeOS(
make_scoped_refptr(g_browser_process->system_request_context()));
make_scoped_refptr(g_browser_process->system_request_context()),
content::BrowserThread::GetMessageLoopProxyForThread(
content::BrowserThread::IO),
content::BrowserThread::GetMessageLoopProxyForThread(
content::BrowserThread::UI),
content::BrowserThread::GetMessageLoopProxyForThread(
content::BrowserThread::FILE));
scoped_ptr<NativeMessageHost> host(new remoting::It2MeNativeMessagingHost(
context.Pass(), host_factory.Pass()));
return host.Pass();
Expand Down
1 change: 0 additions & 1 deletion remoting/host/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,6 @@ static_library("host") {
if (is_chromeos) {
deps += [
"//cc",
"//content",
"//ppapi/host",
"//skia",
"//ui/aura",
Expand Down
1 change: 0 additions & 1 deletion remoting/host/DEPS
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
include_rules = [
"+ash",
"+cc/output",
"+content/public/browser",
"+components/policy/core/common",
"+extensions/browser/api/messaging",
"+jingle/glue",
Expand Down
96 changes: 23 additions & 73 deletions remoting/host/chromeos/clipboard_aura.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@
#include "remoting/host/chromeos/clipboard_aura.h"

#include "base/strings/utf_string_conversions.h"
#include "base/timer/timer.h"
#include "content/public/browser/browser_thread.h"
#include "remoting/base/constants.h"
#include "remoting/proto/event.pb.h"
#include "remoting/protocol/clipboard_stub.h"
Expand All @@ -22,83 +20,31 @@ const int64 kClipboardPollingIntervalMs = 500;

namespace remoting {

class ClipboardAura::Core {
public:
Core();

// Mirror the public interface.
void Start(scoped_ptr<protocol::ClipboardStub> client_clipboard);
void InjectClipboardEvent(const protocol::ClipboardEvent& event);
void Stop();

// Overrides the clipboard polling interval for unit test.
void SetPollingIntervalForTesting(base::TimeDelta polling_interval);

private:
void CheckClipboardForChanges();

scoped_ptr<protocol::ClipboardStub> client_clipboard_;
scoped_ptr<base::RepeatingTimer<Core>> clipboard_polling_timer_;
uint64 current_change_count_;
base::TimeDelta polling_interval_;

DISALLOW_COPY_AND_ASSIGN(Core);
};

ClipboardAura::ClipboardAura(
scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner)
: core_(new Core()),
ui_task_runner_(ui_task_runner) {
ClipboardAura::ClipboardAura()
: current_change_count_(0),
polling_interval_(
base::TimeDelta::FromMilliseconds(kClipboardPollingIntervalMs)) {
}

ClipboardAura::~ClipboardAura() {
ui_task_runner_->DeleteSoon(FROM_HERE, core_.release());
}

void ClipboardAura::Start(
scoped_ptr<protocol::ClipboardStub> client_clipboard) {
ui_task_runner_->PostTask(
FROM_HERE, base::Bind(&Core::Start, base::Unretained(core_.get()),
base::Passed(&client_clipboard)));
}
DCHECK(thread_checker_.CalledOnValidThread());

void ClipboardAura::InjectClipboardEvent(
const protocol::ClipboardEvent& event) {
ui_task_runner_->PostTask(FROM_HERE,
base::Bind(&Core::InjectClipboardEvent,
base::Unretained(core_.get()), event));
}

void ClipboardAura::Stop() {
ui_task_runner_->PostTask(
FROM_HERE, base::Bind(&Core::Stop, base::Unretained(core_.get())));
};

void ClipboardAura::SetPollingIntervalForTesting(
base::TimeDelta polling_interval) {
core_->SetPollingIntervalForTesting(polling_interval);
}

ClipboardAura::Core::Core()
: current_change_count_(0),
polling_interval_(
base::TimeDelta::FromMilliseconds(kClipboardPollingIntervalMs)) {
}

void ClipboardAura::Core::Start(
scoped_ptr<protocol::ClipboardStub> client_clipboard) {
client_clipboard_.reset(client_clipboard.release());
client_clipboard_ = client_clipboard.Pass();

// Aura doesn't provide a clipboard-changed notification. The only way to
// detect clipboard changes is by polling.
clipboard_polling_timer_.reset(new base::RepeatingTimer<Core>());
clipboard_polling_timer_->Start(
FROM_HERE, polling_interval_, this,
&ClipboardAura::Core::CheckClipboardForChanges);
clipboard_polling_timer_.Start(FROM_HERE, polling_interval_, this,
&ClipboardAura::CheckClipboardForChanges);
}

void ClipboardAura::Core::InjectClipboardEvent(
void ClipboardAura::InjectClipboardEvent(
const protocol::ClipboardEvent& event) {
DCHECK(thread_checker_.CalledOnValidThread());

// Currently we only handle UTF-8 text.
if (event.mime_type().compare(kMimeTypeTextUtf8) != 0) {
return;
Expand All @@ -112,17 +58,23 @@ void ClipboardAura::Core::InjectClipboardEvent(
current_change_count_++;
}

void ClipboardAura::Core::Stop() {
clipboard_polling_timer_.reset();
void ClipboardAura::Stop() {
DCHECK(thread_checker_.CalledOnValidThread());

clipboard_polling_timer_.Stop();
client_clipboard_.reset();
}
};

void ClipboardAura::Core::SetPollingIntervalForTesting(
void ClipboardAura::SetPollingIntervalForTesting(
base::TimeDelta polling_interval) {
DCHECK(thread_checker_.CalledOnValidThread());

polling_interval_ = polling_interval;
}

void ClipboardAura::Core::CheckClipboardForChanges() {
void ClipboardAura::CheckClipboardForChanges() {
DCHECK(thread_checker_.CalledOnValidThread());

ui::Clipboard* clipboard = ui::Clipboard::GetForCurrentThread();
uint64 change_count =
clipboard->GetSequenceNumber(ui::CLIPBOARD_TYPE_COPY_PASTE);
Expand All @@ -144,9 +96,7 @@ void ClipboardAura::Core::CheckClipboardForChanges() {
}

scoped_ptr<Clipboard> Clipboard::Create() {
return make_scoped_ptr(
new ClipboardAura(content::BrowserThread::GetMessageLoopProxyForThread(
content::BrowserThread::UI)));
return make_scoped_ptr(new ClipboardAura());
}

} // namespace remoting
16 changes: 9 additions & 7 deletions remoting/host/chromeos/clipboard_aura.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@
#define REMOTING_HOST_CLIPBOARD_AURA_H_

#include "base/memory/scoped_ptr.h"
#include "base/single_thread_task_runner.h"
#include "base/threading/thread_checker.h"
#include "base/timer/timer.h"
#include "remoting/host/clipboard.h"

namespace remoting {
Expand All @@ -25,11 +26,9 @@ class ClipboardStub;
// The public API of this class can be called in any thread as internally it
// always posts the call to the |ui_task_runner|. On ChromeOS, that should
// be the UI thread of the browser process.
//
class ClipboardAura : public Clipboard {
public:
explicit ClipboardAura(
scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner);
explicit ClipboardAura();
~ClipboardAura() override;

// Clipboard interface.
Expand All @@ -41,10 +40,13 @@ class ClipboardAura : public Clipboard {
void SetPollingIntervalForTesting(base::TimeDelta polling_interval);

private:
class Core;
void CheckClipboardForChanges();

scoped_ptr<Core> core_;
scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner_;
base::ThreadChecker thread_checker_;
scoped_ptr<protocol::ClipboardStub> client_clipboard_;
base::RepeatingTimer<ClipboardAura> clipboard_polling_timer_;
uint64 current_change_count_;
base::TimeDelta polling_interval_;

DISALLOW_COPY_AND_ASSIGN(ClipboardAura);
};
Expand Down
15 changes: 9 additions & 6 deletions remoting/host/chromeos/clipboard_aura_unittest.cc
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,6 @@ class ClipboardAuraTest : public testing::Test {
void StopAndResetClipboard();

base::MessageLoopForUI message_loop_;
base::RunLoop run_loop_;
ClientClipboard* client_clipboard_;
scoped_ptr<ClipboardAura> clipboard_;
};
Expand All @@ -71,12 +70,13 @@ void ClipboardAuraTest::SetUp() {
scoped_refptr<base::SingleThreadTaskRunner> task_runner =
message_loop_.message_loop_proxy();
client_clipboard_ = new ClientClipboard();
clipboard_.reset(new ClipboardAura(task_runner));
clipboard_->Start(make_scoped_ptr(client_clipboard_));
clipboard_.reset(new ClipboardAura());

EXPECT_GT(TestTimeouts::tiny_timeout(), kTestOverridePollingInterval * 10)
<< "The test timeout should be greater than the polling interval";
clipboard_->SetPollingIntervalForTesting(kTestOverridePollingInterval);

clipboard_->Start(make_scoped_ptr(client_clipboard_));
}

void ClipboardAuraTest::TearDown() {
Expand All @@ -95,7 +95,7 @@ TEST_F(ClipboardAuraTest, WriteToClipboard) {

clipboard_->InjectClipboardEvent(event);
StopAndResetClipboard();
run_loop_.RunUntilIdle();
base::RunLoop().RunUntilIdle();

std::string clipboard_data;
ui::Clipboard* aura_clipboard = ui::Clipboard::GetForCurrentThread();
Expand All @@ -106,6 +106,8 @@ TEST_F(ClipboardAuraTest, WriteToClipboard) {
}

TEST_F(ClipboardAuraTest, MonitorClipboardChanges) {
base::RunLoop().RunUntilIdle();

{
// |clipboard_writer| will write to the clipboard when it goes out of scope.
ui::ScopedClipboardWriter clipboard_writer(ui::CLIPBOARD_TYPE_COPY_PASTE);
Expand All @@ -116,14 +118,15 @@ TEST_F(ClipboardAuraTest, MonitorClipboardChanges) {
InjectClipboardEvent(Property(&protocol::ClipboardEvent::data,
Eq("Test data.")))).Times(1);

base::RunLoop run_loop;
message_loop_.PostDelayedTask(
FROM_HERE, base::Bind(&ClipboardAuraTest_MonitorClipboardChanges_Test::
StopAndResetClipboard,
base::Unretained(this)),
TestTimeouts::tiny_timeout());
message_loop_.PostDelayedTask(FROM_HERE, base::MessageLoop::QuitClosure(),
message_loop_.PostDelayedTask(FROM_HERE, run_loop.QuitClosure(),
TestTimeouts::tiny_timeout());
message_loop_.Run();
run_loop.Run();
}

} // namespace remoting
65 changes: 27 additions & 38 deletions remoting/host/chromoting_host_context.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@

#include "remoting/host/chromoting_host_context.h"

#include "base/bind.h"
#include "base/threading/thread_restrictions.h"
#include "content/public/browser/browser_thread.h"
#include "remoting/base/auto_thread.h"
#include "remoting/base/url_request_context_getter.h"

Expand Down Expand Up @@ -127,50 +127,39 @@ scoped_ptr<ChromotingHostContext> ChromotingHostContext::Create(
}

#if defined(OS_CHROMEOS)
namespace {
// Retrieves the task_runner from the browser thread with |id|.
scoped_refptr<AutoThreadTaskRunner> WrapBrowserThread(
content::BrowserThread::ID id) {
// AutoThreadTaskRunner is a TaskRunner with the special property that it will
// continue to process tasks until no references remain, at least. The
// QuitClosure we usually pass does the simple thing of stopping the
// underlying TaskRunner. Since we are re-using the ui_task_runner of the
// browser thread, we cannot stop it explicitly. Therefore, base::DoNothing
// is passed in as the quit closure.
// TODO(kelvinp): Fix this (See crbug.com/428187).
return new AutoThreadTaskRunner(
content::BrowserThread::GetMessageLoopProxyForThread(id).get(),
base::Bind(&base::DoNothing));
}

} // namespace

// static
scoped_ptr<ChromotingHostContext> ChromotingHostContext::CreateForChromeOS(
scoped_refptr<net::URLRequestContextGetter> url_request_context_getter) {
scoped_refptr<net::URLRequestContextGetter> url_request_context_getter,
scoped_refptr<base::SingleThreadTaskRunner> io_task_runner,
scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner,
scoped_refptr<base::SingleThreadTaskRunner> file_task_runner) {
DCHECK(url_request_context_getter.get());

// Use BrowserThread::FILE as the joiner as it is the only browser-thread
// that allows blocking I/O, which is required by thread joining.
// TODO(kelvinp): Fix AutoThread so that it can be joinable on task runners
// that disallow I/O (crbug.com/428466).
scoped_refptr<AutoThreadTaskRunner> file_task_runner =
WrapBrowserThread(content::BrowserThread::FILE);

scoped_refptr<AutoThreadTaskRunner> ui_task_runner =
WrapBrowserThread(content::BrowserThread::UI);

// AutoThreadTaskRunner is a TaskRunner with the special property that it will
// continue to process tasks until no references remain, at least. The
// QuitClosure we usually pass does the simple thing of stopping the
// underlying TaskRunner. Since we are re-using browser's threads, we cannot
// stop them explicitly. Therefore, base::DoNothing is passed in as the quit
// closure.
scoped_refptr<AutoThreadTaskRunner> io_auto_task_runner =
new AutoThreadTaskRunner(io_task_runner, base::Bind(&base::DoNothing));
scoped_refptr<AutoThreadTaskRunner> file_auto_task_runner =
new AutoThreadTaskRunner(file_task_runner, base::Bind(&base::DoNothing));
scoped_refptr<AutoThreadTaskRunner> ui_auto_task_runner =
new AutoThreadTaskRunner(ui_task_runner, base::Bind(&base::DoNothing));

// Use browser's file thread as the joiner as it is the only browser-thread
// that allows blocking I/O, which is required by thread joining.
return make_scoped_ptr(new ChromotingHostContext(
ui_task_runner,
AutoThread::CreateWithType("ChromotingAudioThread", file_task_runner,
base::MessageLoop::TYPE_IO),
file_task_runner,
AutoThread::CreateWithType("ChromotingInputThread", file_task_runner,
base::MessageLoop::TYPE_IO),
WrapBrowserThread(content::BrowserThread::IO), // network_task_runner
ui_task_runner, // video_capture_task_runner
AutoThread::CreateWithType("ChromotingEncodeThread", file_task_runner,
base::MessageLoop::TYPE_IO),
ui_auto_task_runner,
AutoThread::Create("ChromotingAudioThread", file_auto_task_runner),
file_auto_task_runner,
ui_auto_task_runner, // input_task_runner
io_auto_task_runner, // network_task_runner
ui_auto_task_runner, // video_capture_task_runner
AutoThread::Create("ChromotingEncodeThread", file_auto_task_runner),
url_request_context_getter));
}
#endif // defined(OS_CHROMEOS)
Expand Down
9 changes: 8 additions & 1 deletion remoting/host/chromoting_host_context.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,10 @@
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"

namespace base {
class SingleThreadTaskRunner;
} // namespace base

namespace net {
class URLRequestContextGetter;
} // namespace net
Expand Down Expand Up @@ -39,7 +43,10 @@ class ChromotingHostContext {
// the IO Thread of the browser process).
// Instead, we re-use the |url_request_context_getter| in the browser process.
static scoped_ptr<ChromotingHostContext> CreateForChromeOS(
scoped_refptr<net::URLRequestContextGetter> url_request_context_getter);
scoped_refptr<net::URLRequestContextGetter> url_request_context_getter,
scoped_refptr<base::SingleThreadTaskRunner> io_task_runner,
scoped_refptr<base::SingleThreadTaskRunner> ui_task_runner,
scoped_refptr<base::SingleThreadTaskRunner> file_task_runner);
#endif // defined(OS_CHROMEOS)

~ChromotingHostContext();
Expand Down
Loading

0 comments on commit f87c35d

Please sign in to comment.