DevTools: Parallel DiscoveryRequest

BUG=

Committed: https://src.chromium.org/viewvc/chrome?view=rev&revision=275206

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

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@275459 0039d316-1c4b-4281-b951-d872f2087c98
parent e273fc52
...@@ -146,82 +146,84 @@ static const int kAdbPort = 5037; ...@@ -146,82 +146,84 @@ static const int kAdbPort = 5037;
static const int kAdbMessageHeaderSize = 4; static const int kAdbMessageHeaderSize = 4;
class SimpleHttpServer : base::NonThreadSafe {
class SingleConnectionServer : base::NonThreadSafe {
public: public:
class Parser { class Parser {
public: public:
virtual int Consume(const char* data, int size) = 0; virtual int Consume(const char* data, int size) = 0;
virtual void Reset() = 0;
protected:
virtual ~Parser() {} virtual ~Parser() {}
}; };
SingleConnectionServer( typedef base::Callback<void(const std::string&)> SendCallback;
Parser* parser, net::IPEndPoint endpoint, int buffer_size); typedef base::Callback<Parser*(const SendCallback&)> ParserFactory;
virtual ~SingleConnectionServer();
void Send(const std::string& message); SimpleHttpServer(const ParserFactory& factory, net::IPEndPoint endpoint);
virtual ~SimpleHttpServer();
private: private:
void SendData(const char* data, int size); class Connection : base::NonThreadSafe {
public:
Connection(net::StreamSocket* socket, const ParserFactory& factory);
virtual ~Connection();
private:
void Send(const std::string& message);
void ReadData();
void OnDataRead(int count);
void WriteData();
void OnDataWritten(int count);
scoped_ptr<net::StreamSocket> socket_;
scoped_ptr<Parser> parser_;
scoped_refptr<net::GrowableIOBuffer> input_buffer_;
scoped_refptr<net::GrowableIOBuffer> output_buffer_;
int bytes_to_write_;
bool read_closed_;
DISALLOW_COPY_AND_ASSIGN(Connection);
};
void AcceptConnection(); void AcceptConnection();
void OnAccepted(int result); void OnAccepted(int result);
void ReadData(); ParserFactory factory_;
void OnDataRead(int count); scoped_ptr<net::TCPServerSocket> socket_;
void WriteData();
void OnDataWritten(int count);
Parser* parser_;
int bytes_to_write_;
scoped_ptr<net::TCPServerSocket> server_socket_;
scoped_ptr<net::StreamSocket> client_socket_; scoped_ptr<net::StreamSocket> client_socket_;
scoped_refptr<net::GrowableIOBuffer> input_buffer_;
scoped_refptr<net::GrowableIOBuffer> output_buffer_;
DISALLOW_COPY_AND_ASSIGN(SingleConnectionServer); DISALLOW_COPY_AND_ASSIGN(SimpleHttpServer);
}; };
SingleConnectionServer::SingleConnectionServer(Parser* parser, SimpleHttpServer::SimpleHttpServer(const ParserFactory& factory,
net::IPEndPoint endpoint, net::IPEndPoint endpoint)
int buffer_size) : factory_(factory),
: parser_(parser), socket_(new net::TCPServerSocket(NULL, net::NetLog::Source())) {
bytes_to_write_(0) { socket_->Listen(endpoint, 5);
CHECK(CalledOnValidThread());
input_buffer_ = new net::GrowableIOBuffer();
input_buffer_->SetCapacity(buffer_size);
output_buffer_ = new net::GrowableIOBuffer();
server_socket_.reset(new net::TCPServerSocket(NULL, net::NetLog::Source()));
server_socket_->Listen(endpoint, 1);
AcceptConnection(); AcceptConnection();
} }
SingleConnectionServer::~SingleConnectionServer() { SimpleHttpServer::~SimpleHttpServer() {
CHECK(CalledOnValidThread()); }
server_socket_.reset();
if (client_socket_) { SimpleHttpServer::Connection::Connection(net::StreamSocket* socket,
client_socket_->Disconnect(); const ParserFactory& factory)
client_socket_.reset(); : socket_(socket),
} parser_(factory.Run(base::Bind(&Connection::Send,
base::Unretained(this)))),
input_buffer_(new net::GrowableIOBuffer()),
output_buffer_(new net::GrowableIOBuffer()),
bytes_to_write_(0),
read_closed_(false) {
input_buffer_->SetCapacity(kBufferSize);
ReadData();
} }
void SingleConnectionServer::Send(const std::string& message) { SimpleHttpServer::Connection::~Connection() {
SendData(message.c_str(), message.size());
} }
void SingleConnectionServer::SendData(const char* data, int size) { void SimpleHttpServer::Connection::Send(const std::string& message) {
CHECK(CalledOnValidThread()); CHECK(CalledOnValidThread());
const char* data = message.c_str();
int size = message.size();
if ((output_buffer_->offset() + bytes_to_write_ + size) > if ((output_buffer_->offset() + bytes_to_write_ + size) >
output_buffer_->capacity()) { output_buffer_->capacity()) {
...@@ -245,64 +247,36 @@ void SingleConnectionServer::SendData(const char* data, int size) { ...@@ -245,64 +247,36 @@ void SingleConnectionServer::SendData(const char* data, int size) {
WriteData(); WriteData();
} }
void SingleConnectionServer::AcceptConnection() { void SimpleHttpServer::Connection::ReadData() {
CHECK(CalledOnValidThread());
if (client_socket_) {
client_socket_->Disconnect();
client_socket_.reset();
}
int accept_result = server_socket_->Accept(&client_socket_,
base::Bind(&SingleConnectionServer::OnAccepted, base::Unretained(this)));
if (accept_result != net::ERR_IO_PENDING)
base::MessageLoop::current()->PostTask(
FROM_HERE,
base::Bind(&SingleConnectionServer::OnAccepted,
base::Unretained(this),
accept_result));
}
void SingleConnectionServer::OnAccepted(int result) {
CHECK(CalledOnValidThread());
ASSERT_EQ(result, 0); // Fails if the socket is already in use.
parser_->Reset();
ReadData();
}
void SingleConnectionServer::ReadData() {
CHECK(CalledOnValidThread()); CHECK(CalledOnValidThread());
if (input_buffer_->RemainingCapacity() == 0) if (input_buffer_->RemainingCapacity() == 0)
input_buffer_->SetCapacity(input_buffer_->capacity() * 2); input_buffer_->SetCapacity(input_buffer_->capacity() * 2);
int read_result = client_socket_->Read( int read_result = socket_->Read(
input_buffer_.get(), input_buffer_.get(),
input_buffer_->RemainingCapacity(), input_buffer_->RemainingCapacity(),
base::Bind(&SingleConnectionServer::OnDataRead, base::Unretained(this))); base::Bind(&Connection::OnDataRead, base::Unretained(this)));
if (read_result != net::ERR_IO_PENDING) if (read_result != net::ERR_IO_PENDING)
OnDataRead(read_result); OnDataRead(read_result);
} }
void SingleConnectionServer::OnDataRead(int count) { void SimpleHttpServer::Connection::OnDataRead(int count) {
CHECK(CalledOnValidThread()); CHECK(CalledOnValidThread());
if (count <= 0) { if (count <= 0) {
AcceptConnection(); if (bytes_to_write_ == 0)
delete this;
else
read_closed_ = true;
return; return;
} }
input_buffer_->set_offset(input_buffer_->offset() + count); input_buffer_->set_offset(input_buffer_->offset() + count);
int bytes_processed; int bytes_processed;
do { do {
char* data = input_buffer_->StartOfBuffer(); char* data = input_buffer_->StartOfBuffer();
int data_size = input_buffer_->offset(); int data_size = input_buffer_->offset();
bytes_processed = parser_->Consume(data, data_size); bytes_processed = parser_->Consume(data, data_size);
if (bytes_processed) { if (bytes_processed) {
...@@ -310,36 +284,32 @@ void SingleConnectionServer::OnDataRead(int count) { ...@@ -310,36 +284,32 @@ void SingleConnectionServer::OnDataRead(int count) {
input_buffer_->set_offset(data_size - bytes_processed); input_buffer_->set_offset(data_size - bytes_processed);
} }
} while (bytes_processed); } while (bytes_processed);
// Posting to avoid deep recursion in case of synchronous IO
// Posting is needed not to enter deep recursion in case too synchronous IO
base::MessageLoop::current()->PostTask( base::MessageLoop::current()->PostTask(
FROM_HERE, FROM_HERE,
base::Bind(&SingleConnectionServer::ReadData, base::Unretained(this))); base::Bind(&Connection::ReadData, base::Unretained(this)));
} }
void SingleConnectionServer::WriteData() { void SimpleHttpServer::Connection::WriteData() {
CHECK(CalledOnValidThread()); CHECK(CalledOnValidThread());
CHECK_GE(output_buffer_->capacity(), CHECK_GE(output_buffer_->capacity(),
output_buffer_->offset() + bytes_to_write_) << "Overflow"; output_buffer_->offset() + bytes_to_write_) << "Overflow";
int write_result = client_socket_->Write( int write_result = socket_->Write(
output_buffer_, output_buffer_,
bytes_to_write_, bytes_to_write_,
base::Bind(&SingleConnectionServer::OnDataWritten, base::Bind(&Connection::OnDataWritten, base::Unretained(this)));
base::Unretained(this)));
if (write_result != net::ERR_IO_PENDING) if (write_result != net::ERR_IO_PENDING)
OnDataWritten(write_result); OnDataWritten(write_result);
} }
void SingleConnectionServer::OnDataWritten(int count) { void SimpleHttpServer::Connection::OnDataWritten(int count) {
CHECK(CalledOnValidThread()); CHECK(CalledOnValidThread());
if (count < 0) { if (count < 0) {
AcceptConnection(); delete this;
return; return;
} }
CHECK_GT(count, 0); CHECK_GT(count, 0);
CHECK_GE(output_buffer_->capacity(), CHECK_GE(output_buffer_->capacity(),
output_buffer_->offset() + bytes_to_write_) << "Overflow"; output_buffer_->offset() + bytes_to_write_) << "Overflow";
...@@ -348,26 +318,46 @@ void SingleConnectionServer::OnDataWritten(int count) { ...@@ -348,26 +318,46 @@ void SingleConnectionServer::OnDataWritten(int count) {
output_buffer_->set_offset(output_buffer_->offset() + count); output_buffer_->set_offset(output_buffer_->offset() + count);
if (bytes_to_write_ != 0) if (bytes_to_write_ != 0)
// Posting is needed not to enter deep recursion in case too synchronous IO // Posting to avoid deep recursion in case of synchronous IO
base::MessageLoop::current()->PostTask(
FROM_HERE,
base::Bind(&Connection::WriteData, base::Unretained(this)));
else if (read_closed_)
delete this;
}
void SimpleHttpServer::AcceptConnection() {
CHECK(CalledOnValidThread());
int accept_result = socket_->Accept(&client_socket_,
base::Bind(&SimpleHttpServer::OnAccepted, base::Unretained(this)));
if (accept_result != net::ERR_IO_PENDING)
base::MessageLoop::current()->PostTask( base::MessageLoop::current()->PostTask(
FROM_HERE, FROM_HERE,
base::Bind(&SingleConnectionServer::WriteData, base::Unretained(this))); base::Bind(&SimpleHttpServer::OnAccepted,
base::Unretained(this),
accept_result));
} }
void SimpleHttpServer::OnAccepted(int result) {
CHECK(CalledOnValidThread());
ASSERT_EQ(result, 0); // Fails if the socket is already in use.
new Connection(client_socket_.release(), factory_);
AcceptConnection();
}
class MockAdbServer : SingleConnectionServer::Parser, class AdbParser : SimpleHttpServer::Parser, base::NonThreadSafe {
base::NonThreadSafe {
public: public:
MockAdbServer() { static Parser* Create(const SimpleHttpServer::SendCallback& callback) {
CHECK(CalledOnValidThread()); return new AdbParser(callback);
net::IPAddressNumber address;
net::ParseIPLiteralToNumber("127.0.0.1", &address);
net::IPEndPoint endpoint(address, kAdbPort);
server_.reset(new SingleConnectionServer(this, endpoint, kBufferSize));
} }
virtual ~MockAdbServer() { explicit AdbParser(const SimpleHttpServer::SendCallback& callback)
CHECK(CalledOnValidThread()); : callback_(callback) {
}
virtual ~AdbParser() {
} }
private: private:
...@@ -382,7 +372,6 @@ class MockAdbServer : SingleConnectionServer::Parser, ...@@ -382,7 +372,6 @@ class MockAdbServer : SingleConnectionServer::Parser,
} }
return 0; return 0;
} }
if (size >= kAdbMessageHeaderSize) { if (size >= kAdbMessageHeaderSize) {
std::string message_header(data, kAdbMessageHeaderSize); std::string message_header(data, kAdbMessageHeaderSize);
int message_size; int message_size;
...@@ -390,23 +379,14 @@ class MockAdbServer : SingleConnectionServer::Parser, ...@@ -390,23 +379,14 @@ class MockAdbServer : SingleConnectionServer::Parser,
EXPECT_TRUE(base::HexStringToInt(message_header, &message_size)); EXPECT_TRUE(base::HexStringToInt(message_header, &message_size));
if (size >= message_size + kAdbMessageHeaderSize) { if (size >= message_size + kAdbMessageHeaderSize) {
std::string message_body(data + kAdbMessageHeaderSize, message_size ); std::string message_body(data + kAdbMessageHeaderSize, message_size);
ProcessCommand(message_body); ProcessCommand(message_body);
return kAdbMessageHeaderSize + message_size; return kAdbMessageHeaderSize + message_size;
} }
} }
return 0; return 0;
} }
virtual void Reset() OVERRIDE {
CHECK(CalledOnValidThread());
selected_device_ = std::string();
selected_socket_ = std::string();
}
void ProcessHTTPRequest(const std::string& request) { void ProcessHTTPRequest(const std::string& request) {
CHECK(CalledOnValidThread()); CHECK(CalledOnValidThread());
std::vector<std::string> tokens; std::vector<std::string> tokens;
...@@ -416,7 +396,6 @@ class MockAdbServer : SingleConnectionServer::Parser, ...@@ -416,7 +396,6 @@ class MockAdbServer : SingleConnectionServer::Parser,
CHECK_EQ("HTTP/1.1", tokens[2]); CHECK_EQ("HTTP/1.1", tokens[2]);
std::string path(tokens[1]); std::string path(tokens[1]);
if (path == kJsonPath) if (path == kJsonPath)
path = kJsonListPath; path = kJsonListPath;
...@@ -480,7 +459,9 @@ class MockAdbServer : SingleConnectionServer::Parser, ...@@ -480,7 +459,9 @@ class MockAdbServer : SingleConnectionServer::Parser,
} }
} }
void SendResponse(const std::string& response) { Send("OKAY", response); } void SendResponse(const std::string& response) {
Send("OKAY", response);
}
void Send(const std::string& status, const std::string& response) { void Send(const std::string& status, const std::string& response) {
CHECK(CalledOnValidThread()); CHECK(CalledOnValidThread());
...@@ -496,8 +477,7 @@ class MockAdbServer : SingleConnectionServer::Parser, ...@@ -496,8 +477,7 @@ class MockAdbServer : SingleConnectionServer::Parser,
response_stream << kHexChars[ (size >> 4*i) & 0x0f ]; response_stream << kHexChars[ (size >> 4*i) & 0x0f ];
response_stream << response; response_stream << response;
} }
callback_.Run(response_stream.str());
server_->Send(response_stream.str());
} }
void SendHTTPResponse(const std::string& body) { void SendHTTPResponse(const std::string& body) {
...@@ -505,21 +485,24 @@ class MockAdbServer : SingleConnectionServer::Parser, ...@@ -505,21 +485,24 @@ class MockAdbServer : SingleConnectionServer::Parser,
std::string response_data(base::StringPrintf(kHttpResponse, std::string response_data(base::StringPrintf(kHttpResponse,
static_cast<int>(body.size()), static_cast<int>(body.size()),
body.c_str())); body.c_str()));
server_->Send(response_data); callback_.Run(response_data);
} }
std::string selected_device_; std::string selected_device_;
std::string selected_socket_; std::string selected_socket_;
SimpleHttpServer::SendCallback callback_;
scoped_ptr<SingleConnectionServer> server_;
}; };
static MockAdbServer* mock_adb_server_ = NULL; static SimpleHttpServer* mock_adb_server_ = NULL;
void StartMockAdbServerOnIOThread() { void StartMockAdbServerOnIOThread() {
CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); CHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
CHECK(mock_adb_server_ == NULL); CHECK(mock_adb_server_ == NULL);
mock_adb_server_ = new MockAdbServer(); net::IPAddressNumber address;
net::ParseIPLiteralToNumber("127.0.0.1", &address);
net::IPEndPoint endpoint(address, kAdbPort);
mock_adb_server_ =
new SimpleHttpServer(base::Bind(&AdbParser::Create), endpoint);
} }
void StopMockAdbServerOnIOThread() { void StopMockAdbServerOnIOThread() {
......
...@@ -63,43 +63,34 @@ class DiscoveryRequest : public base::RefCountedThreadSafe< ...@@ -63,43 +63,34 @@ class DiscoveryRequest : public base::RefCountedThreadSafe<
DiscoveryRequest, DiscoveryRequest,
BrowserThread::DeleteOnUIThread> { BrowserThread::DeleteOnUIThread> {
public: public:
typedef base::Callback<void(const DevToolsAndroidBridge::RemoteDevices&)>
DiscoveryCallback;
typedef AndroidDeviceManager::Device Device; typedef AndroidDeviceManager::Device Device;
typedef AndroidDeviceManager::Devices Devices; typedef AndroidDeviceManager::Devices Devices;
typedef AndroidDeviceManager::DeviceInfo DeviceInfo;
DiscoveryRequest( typedef DevToolsAndroidBridge::RemoteDevice RemoteDevice;
AndroidDeviceManager* device_manager, typedef DevToolsAndroidBridge::RemoteDevices RemoteDevices;
const DiscoveryCallback& callback); typedef DevToolsAndroidBridge::RemoteBrowser RemoteBrowser;
typedef DevToolsAndroidBridge::RemoteBrowsers RemoteBrowsers;
typedef base::Callback<void(const RemoteDevices&)> DiscoveryCallback;
DiscoveryRequest(AndroidDeviceManager* device_manager,
const DiscoveryCallback& callback);
private: private:
friend struct BrowserThread::DeleteOnThread<BrowserThread::UI>; friend struct BrowserThread::DeleteOnThread<BrowserThread::UI>;
friend class base::DeleteHelper<DiscoveryRequest>; friend class base::DeleteHelper<DiscoveryRequest>;
virtual ~DiscoveryRequest(); virtual ~DiscoveryRequest();
void ReceivedDevices(const Devices& devices); void ReceivedDevices(const Devices& devices);
void ProcessDevices(); void ReceivedDeviceInfo(scoped_refptr<Device> device,
void ReceivedDeviceInfo(const AndroidDeviceManager::DeviceInfo& device_info); const DeviceInfo& device_info);
void ProcessSockets(); void ReceivedVersion(scoped_refptr<RemoteBrowser>,
void ReceivedVersion(int result, const std::string& response); int result,
void ReceivedPages(int result, const std::string& response); const std::string& response);
void ReceivedPages(scoped_refptr<RemoteBrowser>,
scoped_refptr<Device> current_device() { return devices_.back(); } int result,
const std::string& response);
scoped_refptr<DevToolsAndroidBridge::RemoteBrowser> current_browser() const {
return browsers_.back();
}
void NextBrowser();
void NextDevice();
void Respond();
DiscoveryCallback callback_; DiscoveryCallback callback_;
Devices devices_; RemoteDevices remote_devices_;
DevToolsAndroidBridge::RemoteBrowsers browsers_;
DevToolsAndroidBridge::RemoteDevices remote_devices_;
}; };
DiscoveryRequest::DiscoveryRequest( DiscoveryRequest::DiscoveryRequest(
...@@ -107,111 +98,78 @@ DiscoveryRequest::DiscoveryRequest( ...@@ -107,111 +98,78 @@ DiscoveryRequest::DiscoveryRequest(
const DiscoveryCallback& callback) const DiscoveryCallback& callback)
: callback_(callback) { : callback_(callback) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
device_manager->QueryDevices( device_manager->QueryDevices(
base::Bind(&DiscoveryRequest::ReceivedDevices, this)); base::Bind(&DiscoveryRequest::ReceivedDevices, this));
} }
DiscoveryRequest::~DiscoveryRequest() { DiscoveryRequest::~DiscoveryRequest() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
callback_.Run(remote_devices_);
} }
void DiscoveryRequest::ReceivedDevices(const Devices& devices) { void DiscoveryRequest::ReceivedDevices(const Devices& devices) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
devices_ = devices; for (Devices::const_iterator it = devices.begin();
ProcessDevices(); it != devices.end(); ++it) {
} (*it)->QueryDeviceInfo(
base::Bind(&DiscoveryRequest::ReceivedDeviceInfo, this, *it));
void DiscoveryRequest::ProcessDevices() {
if (devices_.size() == 0) {
Respond();
return;
} }
current_device()->QueryDeviceInfo(
base::Bind(&DiscoveryRequest::ReceivedDeviceInfo, this));
} }
void DiscoveryRequest::ReceivedDeviceInfo( void DiscoveryRequest::ReceivedDeviceInfo(scoped_refptr<Device> device,
const AndroidDeviceManager::DeviceInfo& device_info) { const DeviceInfo& device_info) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
remote_devices_.push_back( scoped_refptr<RemoteDevice> remote_device =
new DevToolsAndroidBridge::RemoteDevice(current_device(), device_info)); new RemoteDevice(device, device_info);
browsers_ = remote_devices_.back()->browsers(); remote_devices_.push_back(remote_device);
ProcessSockets(); for (RemoteBrowsers::iterator it = remote_device->browsers().begin();
} it != remote_device->browsers().end(); ++it) {
(*it)->SendJsonRequest(
void DiscoveryRequest::ProcessSockets() { kVersionRequest,
if (browsers_.size() == 0) { base::Bind(&DiscoveryRequest::ReceivedVersion, this, *it));
NextDevice(); (*it)->SendJsonRequest(
return; kPageListRequest,
base::Bind(&DiscoveryRequest::ReceivedPages, this, *it));
} }
current_device()->SendJsonRequest(
current_browser()->socket(),
kVersionRequest,
base::Bind(&DiscoveryRequest::ReceivedVersion, this));
} }
void DiscoveryRequest::ReceivedVersion(int result, void DiscoveryRequest::ReceivedVersion(scoped_refptr<RemoteBrowser> browser,
int result,
const std::string& response) { const std::string& response) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
if (result < 0) { if (result < 0)
NextBrowser();
return; return;
}
// Parse version, append to package name if available, // Parse version, append to package name if available,
scoped_ptr<base::Value> value(base::JSONReader::Read(response)); scoped_ptr<base::Value> value(base::JSONReader::Read(response));
base::DictionaryValue* dict; base::DictionaryValue* dict;
if (value && value->GetAsDictionary(&dict)) { if (value && value->GetAsDictionary(&dict)) {
std::string browser; std::string browser_name;
if (dict->GetString("Browser", &browser)) { if (dict->GetString("Browser", &browser_name)) {
std::vector<std::string> parts; std::vector<std::string> parts;
Tokenize(browser, "/", &parts); Tokenize(browser_name, "/", &parts);
if (parts.size() == 2) if (parts.size() == 2)
current_browser()->set_version(parts[1]); browser->set_version(parts[1]);
else else
current_browser()->set_version(browser); browser->set_version(browser_name);
} }
std::string package; std::string package;
if (dict->GetString("Android-Package", &package)) { if (dict->GetString("Android-Package", &package)) {
current_browser()->set_display_name( browser->set_display_name(
AdbDeviceInfoQuery::GetDisplayName(current_browser()->socket(), AdbDeviceInfoQuery::GetDisplayName(browser->socket(), package));
package));
} }
} }
current_device()->SendJsonRequest(
current_browser()->socket(),
kPageListRequest,
base::Bind(&DiscoveryRequest::ReceivedPages, this));
} }
void DiscoveryRequest::ReceivedPages(int result, void DiscoveryRequest::ReceivedPages(scoped_refptr<RemoteBrowser> browser,
int result,
const std::string& response) { const std::string& response) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
if (result >= 0) { if (result < 0)
scoped_ptr<base::Value> value(base::JSONReader::Read(response)); return;
base::ListValue* list_value; scoped_ptr<base::Value> value(base::JSONReader::Read(response));
if (value && value->GetAsList(&list_value)) base::ListValue* list_value;
current_browser()->SetPageDescriptors(*list_value); if (value && value->GetAsList(&list_value))
} browser->SetPageDescriptors(*list_value);
NextBrowser();
}
void DiscoveryRequest::NextBrowser() {
browsers_.pop_back();
ProcessSockets();
}
void DiscoveryRequest::NextDevice() {
devices_.pop_back();
ProcessDevices();
}
void DiscoveryRequest::Respond() {
callback_.Run(remote_devices_);
} }
// ProtocolCommand ------------------------------------------------------------ // ProtocolCommand ------------------------------------------------------------
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment