- add sources.
[platform/framework/web/crosswalk.git] / src / chrome / test / chromedriver / chrome / device_manager.cc
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 "base/strings/string_number_conversions.h"
15 #include "base/strings/stringprintf.h"
16 #include "chrome/test/chromedriver/chrome/adb.h"
17 #include "chrome/test/chromedriver/chrome/status.h"
18
19 Device::Device(
20     const std::string& device_serial, Adb* adb,
21     base::Callback<void()> release_callback)
22     : serial_(device_serial),
23       adb_(adb),
24       release_callback_(release_callback) {}
25
26 Device::~Device() {
27   release_callback_.Run();
28 }
29
30 Status Device::StartApp(const std::string& package,
31                         const std::string& activity,
32                         const std::string& process,
33                         const std::string& args,
34                         int port) {
35   if (!active_package_.empty())
36     return Status(kUnknownError,
37         active_package_ + " was launched and has not been quit");
38
39   Status status = adb_->CheckAppInstalled(serial_, package);
40   if (!status.IsOk())
41     return status;
42
43   status = adb_->ClearAppData(serial_, package);
44   if (!status.IsOk())
45     return status;
46
47   std::string known_activity;
48   std::string device_socket;
49   std::string command_line_file;
50   std::string exec_name;
51   if (package.compare("org.chromium.content_shell_apk") == 0) {
52     known_activity = ".ContentShellActivity";
53     device_socket = "content_shell_devtools_remote";
54     command_line_file = "/data/local/tmp/content-shell-command-line";
55     exec_name = "content_shell";
56   } else if (package.compare("org.chromium.chrome.testshell") == 0) {
57     known_activity = ".ChromiumTestShellActivity";
58     device_socket = "chromium_testshell_devtools_remote";
59     command_line_file = "/data/local/tmp/chromium-testshell-command-line";
60     exec_name = "chromium_testshell";
61   } else if (package.find("chrome") != std::string::npos) {
62     known_activity = "com.google.android.apps.chrome.Main";
63     device_socket = "chrome_devtools_remote";
64     command_line_file = "/data/local/chrome-command-line";
65     exec_name = "chrome";
66   }
67
68   if (!known_activity.empty()) {
69     if (!activity.empty() || !process.empty())
70       return Status(kUnknownError, "known package " + package +
71                     " does not accept activity/process");
72   } else if (activity.empty()) {
73     return Status(kUnknownError, "WebView apps require activity name");
74   }
75
76   if (!command_line_file.empty()) {
77     status = adb_->SetCommandLineFile(serial_, command_line_file, exec_name,
78                                       args);
79     if (!status.IsOk())
80       return status;
81   }
82
83   status = adb_->Launch(serial_, package,
84                         known_activity.empty() ? activity : known_activity);
85   if (!status.IsOk())
86     return status;
87   active_package_ = package;
88
89   if (device_socket.empty()) {
90     // Assume this is a WebView app.
91     int pid;
92     status = adb_->GetPidByName(serial_, process.empty() ? package : process,
93                                 &pid);
94     if (!status.IsOk()) {
95       if (process.empty())
96         status.AddDetails(
97             "process name must be specified if not equal to package name");
98       return status;
99     }
100     device_socket = base::StringPrintf("webview_devtools_remote_%d", pid);
101   }
102
103   return adb_->ForwardPort(serial_, port, device_socket);
104 }
105
106 Status Device::StopApp() {
107   if (!active_package_.empty()) {
108     std::string response;
109     Status status = adb_->ForceStop(serial_, active_package_);
110     if (!status.IsOk())
111       return status;
112     active_package_ = "";
113   }
114   return Status(kOk);
115 }
116
117 DeviceManager::DeviceManager(Adb* adb) : adb_(adb) {
118   CHECK(adb_);
119 }
120
121 DeviceManager::~DeviceManager() {}
122
123 Status DeviceManager::AcquireDevice(scoped_ptr<Device>* device) {
124   std::vector<std::string> devices;
125   Status status = adb_->GetDevices(&devices);
126   if (!status.IsOk())
127     return status;
128
129   if (devices.empty())
130     return Status(kUnknownError, "There are no devices online");
131
132   base::AutoLock lock(devices_lock_);
133   status = Status(kUnknownError, "All devices are in use (" +
134                   base::IntToString(devices.size()) + " online)");
135   std::vector<std::string>::iterator iter;
136   for (iter = devices.begin(); iter != devices.end(); iter++) {
137     if (!IsDeviceLocked(*iter)) {
138       device->reset(LockDevice(*iter));
139       status = Status(kOk);
140       break;
141     }
142   }
143   return status;
144 }
145
146 Status DeviceManager::AcquireSpecificDevice(
147     const std::string& device_serial, scoped_ptr<Device>* device) {
148   std::vector<std::string> devices;
149   Status status = adb_->GetDevices(&devices);
150   if (!status.IsOk())
151     return status;
152
153   if (std::find(devices.begin(), devices.end(), device_serial) == devices.end())
154     return Status(kUnknownError,
155         "Device " + device_serial + " is not online");
156
157   base::AutoLock lock(devices_lock_);
158   if (IsDeviceLocked(device_serial)) {
159     status = Status(kUnknownError,
160         "Device " + device_serial + " is already in use");
161   } else {
162     device->reset(LockDevice(device_serial));
163     status = Status(kOk);
164   }
165   return status;
166 }
167
168 void DeviceManager::ReleaseDevice(const std::string& device_serial) {
169   base::AutoLock lock(devices_lock_);
170   active_devices_.remove(device_serial);
171 }
172
173 Device* DeviceManager::LockDevice(const std::string& device_serial) {
174   active_devices_.push_back(device_serial);
175   return new Device(device_serial, adb_,
176       base::Bind(&DeviceManager::ReleaseDevice, base::Unretained(this),
177                  device_serial));
178 }
179
180 bool DeviceManager::IsDeviceLocked(const std::string& device_serial) {
181   return std::find(active_devices_.begin(), active_devices_.end(),
182                    device_serial) != active_devices_.end();
183 }
184