Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(314)

Unified Diff: device/test/usb_test_gadget_impl.cc

Issue 980023002: Move device/usb classes from the FILE thread to UI thread. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Add more thread assertions. Created 5 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « device/test/usb_test_gadget.h ('k') | device/usb/usb_context.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: device/test/usb_test_gadget_impl.cc
diff --git a/device/test/usb_test_gadget_impl.cc b/device/test/usb_test_gadget_impl.cc
index d9371b4767b56b744c9d33f902aa44e8f10ea4b7..2eea05808acc1bc825d332df275b47e286469707 100644
--- a/device/test/usb_test_gadget_impl.cc
+++ b/device/test/usb_test_gadget_impl.cc
@@ -18,9 +18,10 @@
#include "base/path_service.h"
#include "base/process/process_handle.h"
#include "base/run_loop.h"
-#include "base/strings/string_number_conversions.h"
+#include "base/scoped_observer.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
+#include "base/thread_task_runner_handle.h"
#include "base/time/time.h"
#include "device/usb/usb_device.h"
#include "device/usb/usb_device_handle.h"
@@ -33,28 +34,35 @@
#include "net/url_request/url_request_context_getter.h"
#include "url/gurl.h"
-using ::base::PlatformThread;
-using ::base::TimeDelta;
-
namespace device {
+class UsbTestGadgetImpl : public UsbTestGadget {
+ public:
+ UsbTestGadgetImpl(
+ scoped_refptr<net::URLRequestContextGetter> request_context_getter,
+ UsbService* usb_service,
+ scoped_refptr<UsbDevice> device);
+ ~UsbTestGadgetImpl() override;
+
+ bool Unclaim() override;
+ bool Disconnect() override;
+ bool Reconnect() override;
+ bool SetType(Type type) override;
+ UsbDevice* GetDevice() const override;
+
+ private:
+ std::string device_address_;
+ scoped_refptr<UsbDevice> device_;
+ scoped_refptr<net::URLRequestContextGetter> request_context_getter_;
+ UsbService* usb_service_;
+
+ DISALLOW_COPY_AND_ASSIGN(UsbTestGadgetImpl);
+};
+
namespace {
static const char kCommandLineSwitch[] = "enable-gadget-tests";
-static const int kClaimRetries = 100; // 5 seconds
-static const int kDisconnectRetries = 100; // 5 seconds
-static const int kRetryPeriod = 50; // 0.05 seconds
-static const int kReconnectRetries = 100; // 5 seconds
-static const int kUpdateRetries = 100; // 5 seconds
-
-// Wait for the given time delta while still running the main loop. This is
-// necessary so that device add/remove events are processed by the UsbService.
-void SleepWithRunLoop(base::TimeDelta delta) {
- base::RunLoop run_loop;
- base::MessageLoop::current()->PostDelayedTask(FROM_HERE,
- run_loop.QuitClosure(), delta);
- run_loop.Run();
-}
+static const int kReenumeratePeriod = 100; // 0.1 seconds
struct UsbTestGadgetConfiguration {
UsbTestGadget::Type type;
@@ -70,131 +78,107 @@ static const struct UsbTestGadgetConfiguration kConfigurations[] = {
{UsbTestGadget::ECHO, "/echo/configure", 0x58F4},
};
-class UsbTestGadgetImpl : public UsbTestGadget {
- public:
- ~UsbTestGadgetImpl() override;
-
- bool Unclaim() override;
- bool Disconnect() override;
- bool Reconnect() override;
- bool SetType(Type type) override;
- UsbDevice* GetDevice() const override;
- const std::string& GetSerialNumber() const override;
-
- protected:
- UsbTestGadgetImpl();
-
- private:
- scoped_ptr<net::URLFetcher> CreateURLFetcher(
- const GURL& url,
- net::URLFetcher::RequestType request_type,
- net::URLFetcherDelegate* delegate);
- int SimplePOSTRequest(const GURL& url, const std::string& form_data);
- bool FindUnclaimed();
- bool GetVersion(std::string* version);
- bool Update();
- bool FindClaimed();
- bool ReadLocalVersion(std::string* version);
- bool ReadLocalPackage(std::string* package);
- bool ReadFile(const base::FilePath& file_path, std::string* content);
-
- class Delegate : public net::URLFetcherDelegate {
- public:
- Delegate() {}
- ~Delegate() override {}
-
- void WaitForCompletion() {
- run_loop_.Run();
- }
+bool ReadFile(const base::FilePath& file_path, std::string* content) {
+ base::File file(file_path, base::File::FLAG_OPEN | base::File::FLAG_READ);
+ if (!file.IsValid()) {
+ LOG(ERROR) << "Cannot open " << file_path.MaybeAsASCII() << ": "
+ << base::File::ErrorToString(file.error_details());
+ return false;
+ }
- void OnURLFetchComplete(const net::URLFetcher* source) override {
- run_loop_.Quit();
+ STLClearObject(content);
+ int rv;
+ do {
+ char buf[4096];
+ rv = file.ReadAtCurrentPos(buf, sizeof buf);
+ if (rv == -1) {
+ LOG(ERROR) << "Cannot read " << file_path.MaybeAsASCII() << ": "
+ << base::File::ErrorToString(file.error_details());
+ return false;
}
+ content->append(buf, rv);
+ } while (rv > 0);
- private:
- base::RunLoop run_loop_;
-
- DISALLOW_COPY_AND_ASSIGN(Delegate);
- };
-
- scoped_refptr<UsbDevice> device_;
- std::string device_address_;
- scoped_ptr<net::URLRequestContext> request_context_;
- std::string session_id_;
- UsbService* usb_service_;
+ return true;
+}
- friend class UsbTestGadget;
+bool ReadLocalVersion(std::string* version) {
+ base::FilePath file_path;
+ CHECK(PathService::Get(base::DIR_EXE, &file_path));
+ file_path = file_path.AppendASCII("usb_gadget.zip.md5");
- DISALLOW_COPY_AND_ASSIGN(UsbTestGadgetImpl);
-};
+ return ReadFile(file_path, version);
+}
-} // namespace
+bool ReadLocalPackage(std::string* package) {
+ base::FilePath file_path;
+ CHECK(PathService::Get(base::DIR_EXE, &file_path));
+ file_path = file_path.AppendASCII("usb_gadget.zip");
-bool UsbTestGadget::IsTestEnabled() {
- base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
- return command_line->HasSwitch(kCommandLineSwitch);
+ return ReadFile(file_path, package);
}
-scoped_ptr<UsbTestGadget> UsbTestGadget::Claim() {
- scoped_ptr<UsbTestGadgetImpl> gadget(new UsbTestGadgetImpl);
+scoped_ptr<net::URLFetcher> CreateURLFetcher(
+ scoped_refptr<net::URLRequestContextGetter> request_context_getter,
+ const GURL& url,
+ net::URLFetcher::RequestType request_type,
+ net::URLFetcherDelegate* delegate) {
+ scoped_ptr<net::URLFetcher> url_fetcher(
+ net::URLFetcher::Create(url, request_type, delegate));
- int retries = kClaimRetries;
- while (!gadget->FindUnclaimed()) {
- if (--retries == 0) {
- LOG(ERROR) << "Failed to find an unclaimed device.";
- return scoped_ptr<UsbTestGadget>();
- }
- SleepWithRunLoop(TimeDelta::FromMilliseconds(kRetryPeriod));
- }
- VLOG(1) << "It took " << (kClaimRetries - retries)
- << " retries to find an unclaimed device.";
+ url_fetcher->SetRequestContext(request_context_getter.get());
- return gadget.Pass();
+ return url_fetcher;
}
-UsbTestGadgetImpl::UsbTestGadgetImpl() {
- net::URLRequestContextBuilder context_builder;
- context_builder.set_proxy_service(net::ProxyService::CreateDirect());
- request_context_.reset(context_builder.Build());
+class URLRequestContextGetter : public net::URLRequestContextGetter {
+ public:
+ URLRequestContextGetter(
+ scoped_refptr<base::SingleThreadTaskRunner> network_task_runner)
+ : network_task_runner_(network_task_runner) {}
- base::ProcessId process_id = base::GetCurrentProcId();
- session_id_ = base::StringPrintf(
- "%s:%p", base::HexEncode(&process_id, sizeof(process_id)).c_str(), this);
+ private:
+ ~URLRequestContextGetter() override {}
- usb_service_ = UsbService::GetInstance(NULL);
-}
+ // net::URLRequestContextGetter implementation
+ net::URLRequestContext* GetURLRequestContext() override {
+ context_builder_.set_proxy_service(net::ProxyService::CreateDirect());
+ return context_builder_.Build();
+ }
-UsbTestGadgetImpl::~UsbTestGadgetImpl() {
- if (!device_address_.empty()) {
- Unclaim();
+ scoped_refptr<base::SingleThreadTaskRunner> GetNetworkTaskRunner()
+ const override {
+ return network_task_runner_;
}
-}
-UsbDevice* UsbTestGadgetImpl::GetDevice() const {
- return device_.get();
-}
+ net::URLRequestContextBuilder context_builder_;
+ scoped_refptr<base::SingleThreadTaskRunner> network_task_runner_;
+};
-const std::string& UsbTestGadgetImpl::GetSerialNumber() const {
- return device_address_;
-}
+class URLFetcherDelegate : public net::URLFetcherDelegate {
+ public:
+ URLFetcherDelegate() {}
+ ~URLFetcherDelegate() override {}
-scoped_ptr<net::URLFetcher> UsbTestGadgetImpl::CreateURLFetcher(
- const GURL& url, net::URLFetcher::RequestType request_type,
- net::URLFetcherDelegate* delegate) {
- scoped_ptr<net::URLFetcher> url_fetcher(
- net::URLFetcher::Create(url, request_type, delegate));
+ void WaitForCompletion() { run_loop_.Run(); }
- url_fetcher->SetRequestContext(new net::TrivialURLRequestContextGetter(
- request_context_.get(), base::MessageLoop::current()->task_runner()));
+ void OnURLFetchComplete(const net::URLFetcher* source) override {
+ run_loop_.Quit();
+ }
- return url_fetcher;
-}
+ private:
+ base::RunLoop run_loop_;
+
+ DISALLOW_COPY_AND_ASSIGN(URLFetcherDelegate);
+};
-int UsbTestGadgetImpl::SimplePOSTRequest(const GURL& url,
- const std::string& form_data) {
- Delegate delegate;
- scoped_ptr<net::URLFetcher> url_fetcher =
- CreateURLFetcher(url, net::URLFetcher::POST, &delegate);
+int SimplePOSTRequest(
+ scoped_refptr<net::URLRequestContextGetter> request_context_getter,
+ const GURL& url,
+ const std::string& form_data) {
+ URLFetcherDelegate delegate;
+ scoped_ptr<net::URLFetcher> url_fetcher = CreateURLFetcher(
+ request_context_getter, url, net::URLFetcher::POST, &delegate);
url_fetcher->SetUploadData("application/x-www-form-urlencoded", form_data);
url_fetcher->Start();
@@ -203,230 +187,360 @@ int UsbTestGadgetImpl::SimplePOSTRequest(const GURL& url,
return url_fetcher->GetResponseCode();
}
-bool UsbTestGadgetImpl::FindUnclaimed() {
- std::vector<scoped_refptr<UsbDevice> > devices;
- usb_service_->GetDevices(&devices);
-
- for (std::vector<scoped_refptr<UsbDevice> >::const_iterator iter =
- devices.begin(); iter != devices.end(); ++iter) {
- const scoped_refptr<UsbDevice> &device = *iter;
- if (device->vendor_id() == 0x18D1 && device->product_id() == 0x58F0) {
- base::string16 serial_utf16;
- if (!device->GetSerialNumber(&serial_utf16)) {
- continue;
- }
+class UsbGadgetFactory : public UsbService::Observer,
+ public net::URLFetcherDelegate {
+ public:
+ UsbGadgetFactory(scoped_refptr<base::SingleThreadTaskRunner> io_task_runner)
+ : observer_(this), weak_factory_(this) {
+ usb_service_ = UsbService::GetInstance(io_task_runner);
+ request_context_getter_ = new URLRequestContextGetter(io_task_runner);
- const std::string serial = base::UTF16ToUTF8(serial_utf16);
- const GURL url("http://" + serial + "/claim");
- const std::string form_data = base::StringPrintf(
- "session_id=%s",
- net::EscapeUrlEncodedData(session_id_, true).c_str());
- const int response_code = SimplePOSTRequest(url, form_data);
+ static uint32 next_session_id;
+ base::ProcessId process_id = base::GetCurrentProcId();
+ session_id_ = base::StringPrintf("%d-%d", process_id, next_session_id++);
- if (response_code == 200) {
- device_address_ = serial;
- device_ = device;
- break;
- }
+ observer_.Add(usb_service_);
+ }
- // The device is probably claimed by another process.
- if (response_code != 403) {
- LOG(WARNING) << "Unexpected HTTP " << response_code << " from /claim.";
- }
- }
+ ~UsbGadgetFactory() override {}
+
+ scoped_ptr<UsbTestGadget> WaitForDevice() {
+ EnumerateDevices();
+ run_loop_.Run();
+ return make_scoped_ptr(
+ new UsbTestGadgetImpl(request_context_getter_, usb_service_, device_));
}
- std::string local_version;
- std::string version;
- if (!ReadLocalVersion(&local_version) ||
- !GetVersion(&version)) {
- return false;
+ private:
+ void EnumerateDevices() {
+ if (!device_) {
+ usb_service_->GetDevices(base::Bind(
+ &UsbGadgetFactory::OnDevicesEnumerated, weak_factory_.GetWeakPtr()));
+ }
}
- if (version == local_version) {
- return true;
+ void OnDevicesEnumerated(
+ const std::vector<scoped_refptr<UsbDevice>>& devices) {
+ for (const scoped_refptr<UsbDevice>& device : devices) {
+ OnDeviceAdded(device);
+ }
+
+ if (!device_) {
+ // TODO(reillyg): This timer could be replaced by a way to use long-
+ // polling to wait for claimed devices to become unclaimed.
+ base::MessageLoop::current()->PostDelayedTask(
+ FROM_HERE, base::Bind(&UsbGadgetFactory::EnumerateDevices,
+ weak_factory_.GetWeakPtr()),
+ base::TimeDelta::FromMilliseconds(kReenumeratePeriod));
+ }
}
- return Update();
-}
+ void OnDeviceAdded(scoped_refptr<UsbDevice> device) override {
+ if (device_.get()) {
+ // Already trying to claim a device.
+ return;
+ }
-bool UsbTestGadgetImpl::GetVersion(std::string* version) {
- Delegate delegate;
- const GURL url("http://" + device_address_ + "/version");
- scoped_ptr<net::URLFetcher> url_fetcher =
- CreateURLFetcher(url, net::URLFetcher::GET, &delegate);
+ if (device->vendor_id() != 0x18D1 || device->product_id() != 0x58F0 ||
+ device->serial_number().empty()) {
+ return;
+ }
- url_fetcher->Start();
- delegate.WaitForCompletion();
+ std::string serial_number = base::UTF16ToUTF8(device->serial_number());
+ if (serial_number == serial_number_) {
+ // We were waiting for the device to reappear after upgrade.
+ device_ = device;
+ run_loop_.Quit();
+ return;
+ }
- const int response_code = url_fetcher->GetResponseCode();
- if (response_code != 200) {
- VLOG(2) << "Unexpected HTTP " << response_code << " from /version.";
- return false;
+ device_ = device;
+ serial_number_ = serial_number;
+ Claim();
}
- STLClearObject(version);
- if (!url_fetcher->GetResponseAsString(version)) {
- VLOG(2) << "Failed to read body from /version.";
- return false;
- }
- return true;
-}
+ void Claim() {
+ VLOG(1) << "Trying to claim " << serial_number_ << ".";
-bool UsbTestGadgetImpl::Update() {
- std::string version;
- if (!ReadLocalVersion(&version)) {
- return false;
- }
- LOG(INFO) << "Updating " << device_address_ << " to " << version << "...";
-
- Delegate delegate;
- const GURL url("http://" + device_address_ + "/update");
- scoped_ptr<net::URLFetcher> url_fetcher =
- CreateURLFetcher(url, net::URLFetcher::POST, &delegate);
-
- const std::string mime_header =
- base::StringPrintf(
- "--foo\r\n"
- "Content-Disposition: form-data; name=\"file\"; "
- "filename=\"usb_gadget-%s.zip\"\r\n"
- "Content-Type: application/octet-stream\r\n"
- "\r\n", version.c_str());
- const std::string mime_footer("\r\n--foo--\r\n");
-
- std::string package;
- if (!ReadLocalPackage(&package)) {
- return false;
+ GURL url("http://" + serial_number_ + "/claim");
+ std::string form_data = base::StringPrintf(
+ "session_id=%s", net::EscapeUrlEncodedData(session_id_, true).c_str());
+ url_fetcher_ = CreateURLFetcher(request_context_getter_, url,
+ net::URLFetcher::POST, this);
+ url_fetcher_->SetUploadData("application/x-www-form-urlencoded", form_data);
+ url_fetcher_->Start();
}
- url_fetcher->SetUploadData("multipart/form-data; boundary=foo",
- mime_header + package + mime_footer);
- url_fetcher->Start();
- delegate.WaitForCompletion();
-
- const int response_code = url_fetcher->GetResponseCode();
- if (response_code != 200) {
- LOG(ERROR) << "Unexpected HTTP " << response_code << " from /update.";
- return false;
+ void GetVersion() {
+ GURL url("http://" + serial_number_ + "/version");
+ url_fetcher_ = CreateURLFetcher(request_context_getter_, url,
+ net::URLFetcher::GET, this);
+ url_fetcher_->Start();
}
- int retries = kUpdateRetries;
- std::string new_version;
- while (!GetVersion(&new_version) || new_version != version) {
- if (--retries == 0) {
- LOG(ERROR) << "Device not responding with new version.";
+ bool Update(const std::string& version) {
+ LOG(INFO) << "Updating " << serial_number_ << " to " << version << "...";
+
+ GURL url("http://" + serial_number_ + "/update");
+ url_fetcher_ = CreateURLFetcher(request_context_getter_, url,
+ net::URLFetcher::POST, this);
+ std::string mime_header = base::StringPrintf(
+ "--foo\r\n"
+ "Content-Disposition: form-data; name=\"file\"; "
+ "filename=\"usb_gadget-%s.zip\"\r\n"
+ "Content-Type: application/octet-stream\r\n"
+ "\r\n",
+ version.c_str());
+ std::string mime_footer("\r\n--foo--\r\n");
+
+ std::string package;
+ if (!ReadLocalPackage(&package)) {
return false;
}
- SleepWithRunLoop(TimeDelta::FromMilliseconds(kRetryPeriod));
+
+ url_fetcher_->SetUploadData("multipart/form-data; boundary=foo",
+ mime_header + package + mime_footer);
+ url_fetcher_->Start();
+ device_ = nullptr;
+ return true;
}
- VLOG(1) << "It took " << (kUpdateRetries - retries)
- << " retries to see the new version.";
- // Release the old reference to the device and try to open a new one.
- device_ = NULL;
- retries = kReconnectRetries;
- while (!FindClaimed()) {
- if (--retries == 0) {
- LOG(ERROR) << "Failed to find updated device.";
- return false;
+ void OnURLFetchComplete(const net::URLFetcher* source) override {
+ DCHECK(!serial_number_.empty());
+
+ int response_code = source->GetResponseCode();
+ if (!claimed_) {
+ // Just completed a /claim request.
+ if (response_code == 200) {
+ claimed_ = true;
+ GetVersion();
+ } else {
+ if (response_code != 403) {
+ LOG(WARNING) << "Unexpected HTTP " << response_code
+ << " from /claim.";
+ }
+ Reset();
+ }
+ } else if (version_.empty()) {
+ // Just completed a /version request.
+ if (response_code != 200) {
+ LOG(WARNING) << "Unexpected HTTP " << response_code
+ << " from /version.";
+ Reset();
+ return;
+ }
+
+ if (!source->GetResponseAsString(&version_)) {
+ LOG(WARNING) << "Failed to read body from /version.";
+ Reset();
+ return;
+ }
+
+ std::string local_version;
+ if (!ReadLocalVersion(&local_version)) {
+ Reset();
+ return;
+ }
+
+ if (version_ == local_version) {
+ run_loop_.Quit();
+ } else {
+ if (!Update(local_version)) {
+ Reset();
+ }
+ }
+ } else {
+ // Just completed an /update request.
+ if (response_code != 200) {
+ LOG(WARNING) << "Unexpected HTTP " << response_code << " from /update.";
+ Reset();
+ return;
+ }
+
+ // Must wait for the device to reconnect.
}
- SleepWithRunLoop(TimeDelta::FromMilliseconds(kRetryPeriod));
}
- VLOG(1) << "It took " << (kReconnectRetries - retries)
- << " retries to find the updated device.";
- return true;
-}
+ void Reset() {
+ device_ = nullptr;
+ serial_number_.clear();
+ claimed_ = false;
+ version_.clear();
+
+ // Wait a bit and then try again to find an available device.
+ base::MessageLoop::current()->PostDelayedTask(
+ FROM_HERE, base::Bind(&UsbGadgetFactory::EnumerateDevices,
+ weak_factory_.GetWeakPtr()),
+ base::TimeDelta::FromMilliseconds(kReenumeratePeriod));
+ }
-bool UsbTestGadgetImpl::FindClaimed() {
- CHECK(!device_.get());
+ UsbService* usb_service_ = nullptr;
+ scoped_refptr<net::URLRequestContextGetter> request_context_getter_;
+ std::string session_id_;
+ scoped_ptr<net::URLFetcher> url_fetcher_;
+ scoped_refptr<UsbDevice> device_;
+ std::string serial_number_;
+ bool claimed_ = false;
+ std::string version_;
+ base::RunLoop run_loop_;
+ ScopedObserver<UsbService, UsbService::Observer> observer_;
+ base::WeakPtrFactory<UsbGadgetFactory> weak_factory_;
+};
- std::string expected_serial = GetSerialNumber();
+class DeviceAddListener : public UsbService::Observer {
+ public:
+ DeviceAddListener(UsbService* usb_service,
+ const std::string& serial_number,
+ int product_id)
+ : usb_service_(usb_service),
+ serial_number_(serial_number),
+ product_id_(product_id),
+ observer_(this),
+ weak_factory_(this) {
+ observer_.Add(usb_service_);
+ }
+ virtual ~DeviceAddListener() {}
- std::vector<scoped_refptr<UsbDevice> > devices;
- usb_service_->GetDevices(&devices);
+ scoped_refptr<UsbDevice> WaitForAdd() {
+ usb_service_->GetDevices(base::Bind(&DeviceAddListener::OnDevicesEnumerated,
+ weak_factory_.GetWeakPtr()));
+ run_loop_.Run();
+ return device_;
+ }
- for (std::vector<scoped_refptr<UsbDevice> >::iterator iter =
- devices.begin(); iter != devices.end(); ++iter) {
- scoped_refptr<UsbDevice> &device = *iter;
+ private:
+ void OnDevicesEnumerated(
+ const std::vector<scoped_refptr<UsbDevice>>& devices) {
+ for (const scoped_refptr<UsbDevice>& device : devices) {
+ OnDeviceAdded(device);
+ }
+ }
- if (device->vendor_id() == 0x18D1) {
+ void OnDeviceAdded(scoped_refptr<UsbDevice> device) override {
+ if (device->vendor_id() == 0x18D1 && !device->serial_number().empty()) {
const uint16 product_id = device->product_id();
- bool found = false;
- for (size_t i = 0; i < arraysize(kConfigurations); ++i) {
- if (product_id == kConfigurations[i].product_id) {
- found = true;
- break;
+ if (product_id_ == -1) {
+ bool found = false;
+ for (size_t i = 0; i < arraysize(kConfigurations); ++i) {
+ if (product_id == kConfigurations[i].product_id) {
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ return;
+ }
+ } else {
+ if (product_id_ != product_id) {
+ return;
}
- }
- if (!found) {
- continue;
}
- base::string16 serial_utf16;
- if (!device->GetSerialNumber(&serial_utf16)) {
- continue;
+ if (serial_number_ != base::UTF16ToUTF8(device->serial_number())) {
+ return;
}
- std::string serial = base::UTF16ToUTF8(serial_utf16);
- if (serial != expected_serial) {
- continue;
+ device_ = device;
+ run_loop_.Quit();
+ }
+ }
+
+ UsbService* usb_service_;
+ const std::string serial_number_;
+ const int product_id_;
+ base::RunLoop run_loop_;
+ scoped_refptr<UsbDevice> device_;
+ ScopedObserver<UsbService, UsbService::Observer> observer_;
+ base::WeakPtrFactory<DeviceAddListener> weak_factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(DeviceAddListener);
+};
+
+class DeviceRemoveListener : public UsbService::Observer {
+ public:
+ DeviceRemoveListener(UsbService* usb_service, scoped_refptr<UsbDevice> device)
+ : usb_service_(usb_service),
+ device_(device),
+ observer_(this),
+ weak_factory_(this) {
+ observer_.Add(usb_service_);
+ }
+ virtual ~DeviceRemoveListener() {}
+
+ void WaitForRemove() {
+ usb_service_->GetDevices(
+ base::Bind(&DeviceRemoveListener::OnDevicesEnumerated,
+ weak_factory_.GetWeakPtr()));
+ run_loop_.Run();
+ }
+
+ private:
+ void OnDevicesEnumerated(
+ const std::vector<scoped_refptr<UsbDevice>>& devices) {
+ bool found = false;
+ for (const scoped_refptr<UsbDevice>& device : devices) {
+ if (device_ == device) {
+ found = true;
}
+ }
+ if (!found) {
+ run_loop_.Quit();
+ }
+ }
- device_ = device;
- return true;
+ void OnDeviceRemoved(scoped_refptr<UsbDevice> device) override {
+ if (device_ == device) {
+ run_loop_.Quit();
}
}
- return false;
-}
+ UsbService* usb_service_;
+ base::RunLoop run_loop_;
+ scoped_refptr<UsbDevice> device_;
+ ScopedObserver<UsbService, UsbService::Observer> observer_;
+ base::WeakPtrFactory<DeviceRemoveListener> weak_factory_;
-bool UsbTestGadgetImpl::ReadLocalVersion(std::string* version) {
- base::FilePath file_path;
- CHECK(PathService::Get(base::DIR_EXE, &file_path));
- file_path = file_path.AppendASCII("usb_gadget.zip.md5");
+ DISALLOW_COPY_AND_ASSIGN(DeviceRemoveListener);
+};
- return ReadFile(file_path, version);
+} // namespace
+
+bool UsbTestGadget::IsTestEnabled() {
+ base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
+ return command_line->HasSwitch(kCommandLineSwitch);
}
-bool UsbTestGadgetImpl::ReadLocalPackage(std::string* package) {
- base::FilePath file_path;
- CHECK(PathService::Get(base::DIR_EXE, &file_path));
- file_path = file_path.AppendASCII("usb_gadget.zip");
+scoped_ptr<UsbTestGadget> UsbTestGadget::Claim(
+ scoped_refptr<base::SingleThreadTaskRunner> io_task_runner) {
+ UsbGadgetFactory gadget_factory(io_task_runner);
+ return gadget_factory.WaitForDevice().Pass();
+}
- return ReadFile(file_path, package);
+UsbTestGadgetImpl::UsbTestGadgetImpl(
+ scoped_refptr<net::URLRequestContextGetter> request_context_getter_,
+ UsbService* usb_service,
+ scoped_refptr<UsbDevice> device)
+ : device_address_(base::UTF16ToUTF8(device->serial_number())),
+ device_(device),
+ request_context_getter_(request_context_getter_),
+ usb_service_(usb_service) {
}
-bool UsbTestGadgetImpl::ReadFile(const base::FilePath& file_path,
- std::string* content) {
- base::File file(file_path, base::File::FLAG_OPEN | base::File::FLAG_READ);
- if (!file.IsValid()) {
- LOG(ERROR) << "Cannot open " << file_path.MaybeAsASCII() << ": "
- << base::File::ErrorToString(file.error_details());
- return false;
+UsbTestGadgetImpl::~UsbTestGadgetImpl() {
+ if (!device_address_.empty()) {
+ Unclaim();
}
+}
- STLClearObject(content);
- int rv;
- do {
- char buf[4096];
- rv = file.ReadAtCurrentPos(buf, sizeof buf);
- if (rv == -1) {
- LOG(ERROR) << "Cannot read " << file_path.MaybeAsASCII() << ": "
- << base::File::ErrorToString(file.error_details());
- return false;
- }
- content->append(buf, rv);
- } while (rv > 0);
-
- return true;
+UsbDevice* UsbTestGadgetImpl::GetDevice() const {
+ return device_.get();
}
bool UsbTestGadgetImpl::Unclaim() {
VLOG(1) << "Releasing the device at " << device_address_ << ".";
- const GURL url("http://" + device_address_ + "/unclaim");
- const int response_code = SimplePOSTRequest(url, "");
+ GURL url("http://" + device_address_ + "/unclaim");
+ int response_code = SimplePOSTRequest(request_context_getter_, url, "");
if (response_code != 200) {
LOG(ERROR) << "Unexpected HTTP " << response_code << " from /unclaim.";
@@ -446,8 +560,8 @@ bool UsbTestGadgetImpl::SetType(Type type) {
}
CHECK(config);
- const GURL url("http://" + device_address_ + config->http_resource);
- const int response_code = SimplePOSTRequest(url, "");
+ GURL url("http://" + device_address_ + config->http_resource);
+ int response_code = SimplePOSTRequest(request_context_getter_, url, "");
if (response_code != 200) {
LOG(ERROR) << "Unexpected HTTP " << response_code
@@ -456,75 +570,41 @@ bool UsbTestGadgetImpl::SetType(Type type) {
}
// Release the old reference to the device and try to open a new one.
- int retries = kReconnectRetries;
- while (true) {
- device_ = NULL;
- if (FindClaimed() && device_->product_id() == config->product_id) {
- break;
- }
- if (--retries == 0) {
- LOG(ERROR) << "Failed to find updated device.";
- return false;
- }
- SleepWithRunLoop(TimeDelta::FromMilliseconds(kRetryPeriod));
- }
- VLOG(1) << "It took " << (kReconnectRetries - retries)
- << " retries to find the updated device.";
-
+ DeviceAddListener add_listener(usb_service_, device_address_,
+ config->product_id);
+ device_ = add_listener.WaitForAdd();
+ DCHECK(device_.get());
return true;
}
bool UsbTestGadgetImpl::Disconnect() {
- const GURL url("http://" + device_address_ + "/disconnect");
- const int response_code = SimplePOSTRequest(url, "");
+ GURL url("http://" + device_address_ + "/disconnect");
+ int response_code = SimplePOSTRequest(request_context_getter_, url, "");
if (response_code != 200) {
- LOG(ERROR) << "Unexpected HTTP " << response_code << " from /disconnect.";
+ LOG(ERROR) << "Unexpected HTTP " << response_code << " from " << url << ".";
return false;
}
// Release the old reference to the device and wait until it can't be found.
- int retries = kDisconnectRetries;
- while (true) {
- device_ = NULL;
- if (!FindClaimed()) {
- break;
- }
- if (--retries == 0) {
- LOG(ERROR) << "Device did not disconnect.";
- return false;
- }
- SleepWithRunLoop(TimeDelta::FromMilliseconds(kRetryPeriod));
- }
- VLOG(1) << "It took " << (kDisconnectRetries - retries)
- << " retries for the device to disconnect.";
-
+ DeviceRemoveListener remove_listener(usb_service_, device_);
+ remove_listener.WaitForRemove();
+ device_ = nullptr;
return true;
}
bool UsbTestGadgetImpl::Reconnect() {
- const GURL url("http://" + device_address_ + "/reconnect");
- const int response_code = SimplePOSTRequest(url, "");
+ GURL url("http://" + device_address_ + "/reconnect");
+ int response_code = SimplePOSTRequest(request_context_getter_, url, "");
if (response_code != 200) {
- LOG(ERROR) << "Unexpected HTTP " << response_code << " from /reconnect.";
+ LOG(ERROR) << "Unexpected HTTP " << response_code << " from " << url << ".";
return false;
}
- int retries = kDisconnectRetries;
- while (true) {
- if (FindClaimed()) {
- break;
- }
- if (--retries == 0) {
- LOG(ERROR) << "Device did not reconnect.";
- return false;
- }
- SleepWithRunLoop(TimeDelta::FromMilliseconds(kRetryPeriod));
- }
- VLOG(1) << "It took " << (kDisconnectRetries - retries)
- << " retries for the device to reconnect.";
-
+ DeviceAddListener add_listener(usb_service_, device_address_, -1);
+ device_ = add_listener.WaitForAdd();
+ DCHECK(device_.get());
return true;
}
« no previous file with comments | « device/test/usb_test_gadget.h ('k') | device/usb/usb_context.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698