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

Side by Side Diff: device/devices_app/devices_app.cc

Issue 1183443002: Reland: Introduce the devices Mojo app (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: gn check... Created 5 years, 6 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 unified diff | Download patch
« no previous file with comments | « device/devices_app/devices_app.h ('k') | device/devices_app/devices_app.gyp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2015 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 "device/devices_app/devices_app.h"
6
7 #include "base/bind.h"
8 #include "base/callback.h"
9 #include "base/macros.h"
10 #include "base/sequenced_task_runner.h"
11 #include "base/thread_task_runner_handle.h"
12 #include "base/threading/thread.h"
13 #include "base/time/time.h"
14 #include "device/core/device_client.h"
15 #include "device/devices_app/usb/device_manager_impl.h"
16 #include "device/devices_app/usb/public/cpp/device_manager_delegate.h"
17 #include "device/usb/usb_service.h"
18 #include "mojo/application/public/cpp/application_connection.h"
19 #include "mojo/application/public/cpp/application_impl.h"
20 #include "third_party/mojo/src/mojo/public/cpp/bindings/error_handler.h"
21 #include "third_party/mojo/src/mojo/public/cpp/bindings/interface_request.h"
22 #include "url/gurl.h"
23
24 namespace device {
25
26 const char kDevicesMojoAppUrl[] = "system:devices";
27
28 namespace {
29
30 // The number of seconds to wait without any bound DeviceManagers before
31 // exiting the app.
32 const int64 kIdleTimeoutInSeconds = 10;
33
34 // A usb::DeviceManagerDelegate implementation which provides origin-based
35 // device access control.
36 class USBDeviceManagerDelegate : public usb::DeviceManagerDelegate {
37 public:
38 explicit USBDeviceManagerDelegate(const GURL& remote_url)
39 : remote_url_(remote_url) {}
40 ~USBDeviceManagerDelegate() override {}
41
42 private:
43 // usb::DeviceManagerDelegate:
44 bool IsDeviceAllowed(const usb::DeviceInfo& device) override {
45 // Limited set of conditions to allow localhost connection for testing. This
46 // does not presume to catch all common local host strings.
47 if (remote_url_.host() == "127.0.0.1" || remote_url_.host() == "localhost")
48 return true;
49
50 // Also let browser apps and mojo apptests talk to all devices.
51 if (remote_url_.SchemeIs("system") ||
52 remote_url_ == GURL("mojo://devices_apptests/"))
53 return true;
54
55 // TODO(rockot/reillyg): Implement origin-based device access control.
56 return false;
57 }
58
59 GURL remote_url_;
60
61 DISALLOW_COPY_AND_ASSIGN(USBDeviceManagerDelegate);
62 };
63
64 // A DeviceClient implementation to be constructed iff the app is not running
65 // in an embedder that provides a DeviceClient (i.e. running as a standalone
66 // Mojo app, not in Chrome).
67 class AppDeviceClient : public DeviceClient {
68 public:
69 explicit AppDeviceClient(
70 scoped_refptr<base::SequencedTaskRunner> blocking_task_runner)
71 : usb_service_(UsbService::GetInstance(blocking_task_runner)) {}
72 ~AppDeviceClient() override {}
73
74 private:
75 // DeviceClient:
76 UsbService* GetUsbService() override { return usb_service_; }
77
78 UsbService* usb_service_;
79 };
80
81 } // namespace
82
83 // This class insures that a UsbService has been initialized and is accessible
84 // via the DeviceClient interface.
85 class DevicesApp::USBServiceInitializer {
86 public:
87 USBServiceInitializer()
88 : blocking_thread_("USB service blocking I/O thread") {
89 blocking_thread_.Start();
90 app_device_client_.reset(
91 new AppDeviceClient(blocking_thread_.task_runner()));
92 }
93
94 ~USBServiceInitializer() {}
95
96 private:
97 scoped_ptr<AppDeviceClient> app_device_client_;
98 base::Thread blocking_thread_;
99
100 DISALLOW_COPY_AND_ASSIGN(USBServiceInitializer);
101 };
102
103 DevicesApp::~DevicesApp() {
104 }
105
106 // static
107 scoped_ptr<mojo::ApplicationDelegate> DevicesApp::CreateDelegate(
108 scoped_refptr<base::SequencedTaskRunner> service_task_runner) {
109 return scoped_ptr<mojo::ApplicationDelegate>(
110 new DevicesApp(service_task_runner));
111 }
112
113 DevicesApp::DevicesApp(
114 scoped_refptr<base::SequencedTaskRunner> service_task_runner)
115 : app_impl_(nullptr),
116 service_task_runner_(service_task_runner),
117 active_device_manager_count_(0) {
118 }
119
120 void DevicesApp::Initialize(mojo::ApplicationImpl* app) {
121 app_impl_ = app;
122 if (!service_task_runner_) {
123 service_initializer_.reset(new USBServiceInitializer);
124 service_task_runner_ = base::ThreadTaskRunnerHandle::Get();
125 }
126 StartIdleTimer();
127 }
128
129 bool DevicesApp::ConfigureIncomingConnection(
130 mojo::ApplicationConnection* connection) {
131 connection->AddService<usb::DeviceManager>(this);
132 return true;
133 }
134
135 void DevicesApp::Quit() {
136 service_initializer_.reset();
137 app_impl_ = nullptr;
138 }
139
140 void DevicesApp::Create(mojo::ApplicationConnection* connection,
141 mojo::InterfaceRequest<usb::DeviceManager> request) {
142 scoped_ptr<usb::DeviceManagerDelegate> delegate(new USBDeviceManagerDelegate(
143 GURL(connection->GetRemoteApplicationURL())));
144
145 // Owned by its message pipe.
146 usb::DeviceManagerImpl* device_manager = new usb::DeviceManagerImpl(
147 request.Pass(), delegate.Pass(), service_task_runner_);
148 device_manager->set_error_handler(this);
149
150 active_device_manager_count_++;
151 idle_timeout_callback_.Cancel();
152 }
153
154 void DevicesApp::OnConnectionError() {
155 DCHECK_GE(active_device_manager_count_, 0u);
156 active_device_manager_count_--;
157 if (active_device_manager_count_ == 0) {
158 // If the last DeviceManager connection has been dropped, kick off an idle
159 // timeout to shut ourselves down.
160 StartIdleTimer();
161 }
162 }
163
164 void DevicesApp::StartIdleTimer() {
165 // Passing unretained |app_impl_| is safe here because |app_impl_| is
166 // guaranteed to outlive |this|, and the callback is canceled if |this| is
167 // destroyed.
168 idle_timeout_callback_.Reset(base::Bind(&mojo::ApplicationImpl::Terminate,
169 base::Unretained(app_impl_)));
170 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
171 FROM_HERE, idle_timeout_callback_.callback(),
172 base::TimeDelta::FromSeconds(kIdleTimeoutInSeconds));
173 }
174
175 } // namespace device
OLDNEW
« no previous file with comments | « device/devices_app/devices_app.h ('k') | device/devices_app/devices_app.gyp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698