device_manager.cc revision eb525c5499e34cc9c4b825d6d9e75bb07cc06ace
1// Copyright (c) 2013 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "chrome/test/chromedriver/chrome/device_manager.h"
6
7#include <algorithm>
8#include <vector>
9
10#include "base/bind.h"
11#include "base/bind_helpers.h"
12#include "base/callback.h"
13#include "base/logging.h"
14#include "chrome/test/chromedriver/chrome/adb.h"
15#include "chrome/test/chromedriver/chrome/status.h"
16
17namespace {
18
19std::string GetActivityForPackage(const std::string& package) {
20  if (package == "org.chromium.chrome.testshell")
21    return ".ChromiumTestShellActivity";
22  return "com.google.android.apps.chrome.Main";
23}
24
25std::string GetDevtoolsSocket(const std::string& package) {
26  if (package == "org.chromium.chrome.testshell")
27    return "chromium_testshell_devtools_remote";
28  return "chrome_devtools_remote";
29}
30
31}  // namespace
32
33Device::Device(
34    const std::string& device_serial, Adb* adb,
35    base::Callback<void()> release_callback)
36    : serial_(device_serial),
37      adb_(adb),
38      release_callback_(release_callback) {}
39
40Device::~Device() {
41  release_callback_.Run();
42}
43
44Status Device::StartChrome(const std::string& package,
45                           int port,
46                           const std::string& args) {
47  if (!active_package_.empty())
48    return Status(kUnknownError,
49        active_package_ + " was launched and has not been quit");
50  Status status = adb_->CheckAppInstalled(serial_, package);
51  if (!status.IsOk())
52    return status;
53  status = adb_->ClearAppData(serial_, package);
54  if (!status.IsOk())
55    return status;
56  status = adb_->SetChromeArgs(serial_, args);
57  if (!status.IsOk())
58    return status;
59  status = adb_->Launch(serial_, package, GetActivityForPackage(package));
60  if (!status.IsOk())
61    return status;
62  active_package_ = package;
63  return adb_->ForwardPort(serial_, port, GetDevtoolsSocket(package));
64}
65
66Status Device::StopChrome() {
67  if (active_package_.empty())
68    return Status(kUnknownError, "No package has been launched");
69  std::string response;
70  Status status = adb_->ForceStop(serial_, active_package_);
71  if (!status.IsOk())
72    return status;
73  active_package_ = "";
74  return Status(kOk);
75}
76
77DeviceManager::DeviceManager(Adb* adb) : adb_(adb) {
78  CHECK(adb_);
79}
80
81DeviceManager::~DeviceManager() {}
82
83Status DeviceManager::AcquireDevice(scoped_ptr<Device>* device) {
84  std::vector<std::string> devices;
85  Status status = adb_->GetDevices(&devices);
86  if (!status.IsOk())
87    return status;
88
89  base::AutoLock lock(devices_lock_);
90  status = Status(kUnknownError, "No device avaliable");
91  std::vector<std::string>::iterator iter;
92  for (iter = devices.begin(); iter != devices.end(); iter++) {
93    if (!IsDeviceLocked(*iter)) {
94      device->reset(LockDevice(*iter));
95      status = Status(kOk);
96      break;
97    }
98  }
99  return status;
100}
101
102Status DeviceManager::AcquireSpecificDevice(
103    const std::string& device_serial, scoped_ptr<Device>* device) {
104  std::vector<std::string> devices;
105  Status status = adb_->GetDevices(&devices);
106  if (!status.IsOk())
107    return status;
108
109  if (std::find(devices.begin(), devices.end(), device_serial) == devices.end())
110    return Status(kUnknownError,
111        "Device " + device_serial + " is not avaliable");
112
113  base::AutoLock lock(devices_lock_);
114  if (IsDeviceLocked(device_serial)) {
115    status = Status(kUnknownError,
116        "Device " + device_serial + " already has an active session");
117  } else {
118    device->reset(LockDevice(device_serial));
119    status = Status(kOk);
120  }
121  return status;
122}
123
124void DeviceManager::ReleaseDevice(const std::string& device_serial) {
125  base::AutoLock lock(devices_lock_);
126  active_devices_.remove(device_serial);
127}
128
129Device* DeviceManager::LockDevice(const std::string& device_serial) {
130  active_devices_.push_back(device_serial);
131  return new Device(device_serial, adb_,
132      base::Bind(&DeviceManager::ReleaseDevice, base::Unretained(this),
133                 device_serial));
134}
135
136bool DeviceManager::IsDeviceLocked(const std::string& device_serial) {
137  return std::find(active_devices_.begin(), active_devices_.end(),
138                   device_serial) != active_devices_.end();
139}
140
141