Skip to content

Commit

Permalink
[chromedriver] Android device management and auto-device assignment.
Browse files Browse the repository at this point in the history
BUG=chromedriver:343
TEST=unittests

Review URL: https://chromiumcodereview.appspot.com/15851004

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@203350 0039d316-1c4b-4281-b951-d872f2087c98
  • Loading branch information
[email protected] committed May 31, 2013
1 parent b9c8032 commit a084412
Show file tree
Hide file tree
Showing 14 changed files with 521 additions and 195 deletions.
31 changes: 31 additions & 0 deletions chrome/adb.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
// Copyright 2013 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_TEST_CHROMEDRIVER_CHROME_ADB_H_
#define CHROME_TEST_CHROMEDRIVER_CHROME_ADB_H_

#include <string>
#include <vector>

class Status;

class Adb {
public:
virtual ~Adb() {}

virtual Status GetDevices(std::vector<std::string>* devices) = 0;
virtual Status ForwardPort(const std::string& device_serial,
int local_port,
const std::string& remote_abstract) = 0;
virtual Status SetChromeFlags(const std::string& device_serial) = 0;
virtual Status ClearAppData(const std::string& device_serial,
const std::string& package) = 0;
virtual Status Launch(const std::string& device_serial,
const std::string& package,
const std::string& activity) = 0;
virtual Status ForceStop(const std::string& device_serial,
const std::string& package) = 0;
};

#endif // CHROME_TEST_CHROMEDRIVER_CHROME_ADB_H_
166 changes: 166 additions & 0 deletions chrome/adb_impl.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,166 @@
// Copyright 2013 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/test/chromedriver/chrome/adb_impl.h"

#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/logging.h"
#include "base/message_loop.h"
#include "base/message_loop/message_loop_proxy.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_split.h"
#include "base/strings/string_tokenizer.h"
#include "base/synchronization/waitable_event.h"
#include "chrome/test/chromedriver/chrome/log.h"
#include "chrome/test/chromedriver/chrome/status.h"
#include "chrome/test/chromedriver/net/adb_client_socket.h"

namespace {

const int kAdbPort = 5037;

void ReceiveAdbResponse(std::string* response_out, bool* success,
base::WaitableEvent* event, int result,
const std::string& response) {
*response_out = response;
*success = (result >= 0) ? true : false;
event->Signal();
}

void ExecuteCommandOnIOThread(
const std::string& command, std::string* response, bool* success,
base::WaitableEvent* event) {
CHECK(MessageLoop::current()->IsType(MessageLoop::TYPE_IO));
AdbClientSocket::AdbQuery(kAdbPort, command,
base::Bind(&ReceiveAdbResponse, response, success, event));
}

} // namespace

AdbImpl::AdbImpl(
const scoped_refptr<base::MessageLoopProxy>& io_message_loop_proxy,
Log* log)
: io_message_loop_proxy_(io_message_loop_proxy), log_(log) {
CHECK(io_message_loop_proxy_);
}

AdbImpl::~AdbImpl() {}

Status AdbImpl::GetDevices(std::vector<std::string>* devices) {
std::string response;
Status status = ExecuteCommand("host:devices", &response);
if (!status.IsOk())
return status;
base::StringTokenizer lines(response, "\n");
while (lines.GetNext()) {
std::vector<std::string> fields;
base::SplitStringAlongWhitespace(lines.token(), &fields);
if (fields.size() == 2 && fields[1] == "device") {
devices->push_back(fields[0]);
}
}
return Status(kOk);
}

Status AdbImpl::ForwardPort(
const std::string& device_serial, int local_port,
const std::string& remote_abstract) {
std::string response;
Status status = ExecuteHostCommand(
device_serial,
"forward:tcp:" + base::IntToString(local_port) + ";localabstract:" +
remote_abstract,
&response);
if (!status.IsOk())
return status;
if (response == "OKAY")
return Status(kOk);
return Status(kUnknownError, "Failed to forward ports: " + response);
}

Status AdbImpl::SetChromeFlags(const std::string& device_serial) {
std::string response;
Status status = ExecuteHostShellCommand(
device_serial,
"echo chrome --disable-fre --metrics-recording-only "
"--enable-remote-debugging > /data/local/chrome-command-line;"
"echo $?",
&response);
if (!status.IsOk())
return status;
if (response.find("0") == std::string::npos)
return Status(kUnknownError, "Failed to set Chrome flags");
return Status(kOk);
}

Status AdbImpl::ClearAppData(
const std::string& device_serial, const std::string& package) {
std::string response;
std::string command = "pm clear " + package;
Status status = ExecuteHostShellCommand(device_serial, command, &response);
if (!status.IsOk())
return status;
if (response.find("Success") == std::string::npos)
return Status(kUnknownError, "Failed to clear app data: " + response);
return Status(kOk);
}

Status AdbImpl::Launch(
const std::string& device_serial, const std::string& package,
const std::string& activity) {
std::string response;
Status status = ExecuteHostShellCommand(
device_serial,
"am start -a android.intent.action.VIEW -S -W -n " +
package + "/" + activity + " -d \"data:text/html;charset=utf-8,\"",
&response);
if (!status.IsOk())
return status;
if (response.find("Complete") == std::string::npos)
return Status(kUnknownError,
"Failed to start " + package + ": " + response);
return Status(kOk);
}

Status AdbImpl::ForceStop(
const std::string& device_serial, const std::string& package) {
std::string response;
return ExecuteHostShellCommand(
device_serial, "am force-stop " + package, &response);
}

Status AdbImpl::ExecuteCommand(
const std::string& command, std::string* response) {
bool success;
base::WaitableEvent event(false, false);
log_->AddEntry(Log::kDebug, "Adb command: " + command);
io_message_loop_proxy_->PostTask(
FROM_HERE,
base::Bind(&ExecuteCommandOnIOThread, command, response, &success,
&event));
event.Wait();
log_->AddEntry(Log::kDebug, "Adb response: " + *response);
if (success)
return Status(kOk);
return Status(kUnknownError,
"Adb command \"" + command + "\" failed, is the Adb server running?");
}

Status AdbImpl::ExecuteHostCommand(
const std::string& device_serial,
const std::string& host_command, std::string* response) {
return ExecuteCommand(
"host-serial:" + device_serial + ":" + host_command, response);
}

Status AdbImpl::ExecuteHostShellCommand(
const std::string& device_serial,
const std::string& shell_command,
std::string* response) {
return ExecuteCommand(
"host:transport:" + device_serial + "|shell:" + shell_command,
response);
}

58 changes: 58 additions & 0 deletions chrome/adb_impl.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
// Copyright 2013 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_TEST_CHROMEDRIVER_CHROME_ADB_IMPL_H_
#define CHROME_TEST_CHROMEDRIVER_CHROME_ADB_IMPL_H_

#include <string>
#include <vector>

#include "base/compiler_specific.h"
#include "base/memory/ref_counted.h"
#include "chrome/test/chromedriver/chrome/adb.h"

namespace base {
class MessageLoopProxy;
}

class Log;
class Status;

class AdbImpl : public Adb {
public:
explicit AdbImpl(
const scoped_refptr<base::MessageLoopProxy>& io_message_loop_proxy,
Log* log);
virtual ~AdbImpl();

// Overridden from Adb:
virtual Status GetDevices(std::vector<std::string>* devices) OVERRIDE;
virtual Status ForwardPort(const std::string& device_serial,
int local_port,
const std::string& remote_abstract) OVERRIDE;
virtual Status SetChromeFlags(const std::string& device_serial) OVERRIDE;
virtual Status ClearAppData(const std::string& device_serial,
const std::string& package) OVERRIDE;
virtual Status Launch(const std::string& device_serial,
const std::string& package,
const std::string& activity) OVERRIDE;
virtual Status ForceStop(const std::string& device_serial,
const std::string& package) OVERRIDE;

private:
Status ExecuteCommand(const std::string& command,
std::string* response);
Status ExecuteHostCommand(const std::string& device_serial,
const std::string& host_command,
std::string* response);
Status ExecuteHostShellCommand(const std::string& device_serial,
const std::string& shell_command,
std::string* response);

scoped_refptr<base::MessageLoopProxy> io_message_loop_proxy_;

Log* log_;
};

#endif // CHROME_TEST_CHROMEDRIVER_CHROME_ADB_IMPL_H_
13 changes: 6 additions & 7 deletions chrome/chrome_android_impl.cc
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

#include "chrome/test/chromedriver/chrome/chrome_android_impl.h"

#include "chrome/test/chromedriver/chrome/device_manager.h"
#include "chrome/test/chromedriver/chrome/devtools_http_client.h"
#include "chrome/test/chromedriver/chrome/status.h"

Expand All @@ -12,12 +13,11 @@ ChromeAndroidImpl::ChromeAndroidImpl(
const std::string& version,
int build_no,
ScopedVector<DevToolsEventListener>& devtools_event_listeners,
scoped_ptr<Device> device,
Log* log)
: ChromeImpl(client.Pass(),
version,
build_no,
devtools_event_listeners,
log) {}
: ChromeImpl(client.Pass(), version, build_no, devtools_event_listeners,
log),
device_(device.Pass()) {}

ChromeAndroidImpl::~ChromeAndroidImpl() {}

Expand All @@ -26,7 +26,6 @@ std::string ChromeAndroidImpl::GetOperatingSystemName() {
}

Status ChromeAndroidImpl::Quit() {
// NOOP.
return Status(kOk);
return device_->StopChrome();
}

6 changes: 6 additions & 0 deletions chrome/chrome_android_impl.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,10 @@
#include <string>

#include "base/compiler_specific.h"
#include "base/memory/scoped_ptr.h"
#include "chrome/test/chromedriver/chrome/chrome_impl.h"

class Device;
class DevToolsHttpClient;

class ChromeAndroidImpl : public ChromeImpl {
Expand All @@ -19,12 +21,16 @@ class ChromeAndroidImpl : public ChromeImpl {
const std::string& version,
int build_no,
ScopedVector<DevToolsEventListener>& devtools_event_listeners,
scoped_ptr<Device> device,
Log* log);
virtual ~ChromeAndroidImpl();

// Overridden from Chrome:
virtual std::string GetOperatingSystemName() OVERRIDE;
virtual Status Quit() OVERRIDE;

private:
scoped_ptr<Device> device_;
};

#endif // CHROME_TEST_CHROMEDRIVER_CHROME_CHROME_ANDROID_IMPL_H_
Loading

0 comments on commit a084412

Please sign in to comment.