summaryrefslogtreecommitdiffstats
path: root/device
diff options
context:
space:
mode:
authorjorgelo <jorgelo@chromium.org>2014-10-20 15:42:36 -0700
committerCommit bot <commit-bot@chromium.org>2014-10-20 22:43:47 +0000
commit2aa4e40e4bac2c708c0e91c9a7c03fb9539323fd (patch)
treeace1b85d15e3a367700ea6360d749a57f0e08438 /device
parentf937604c661f75a423b6e1c0a285eff9a8556577 (diff)
downloadchromium_src-2aa4e40e4bac2c708c0e91c9a7c03fb9539323fd.zip
chromium_src-2aa4e40e4bac2c708c0e91c9a7c03fb9539323fd.tar.gz
chromium_src-2aa4e40e4bac2c708c0e91c9a7c03fb9539323fd.tar.bz2
Implement permission_broker for serial devices.
This change makes Chrome on Chrome OS ask permission_broker for access to serial devices. BUG=173548 TEST=Chrome can access serial devices on Linux, chromeos=1, full Chrome OS. Review URL: https://codereview.chromium.org/646053002 Cr-Commit-Position: refs/heads/master@{#300364}
Diffstat (limited to 'device')
-rw-r--r--device/serial/serial_io_handler.cc42
-rw-r--r--device/serial/serial_io_handler.h19
-rw-r--r--device/serial/serial_io_handler_posix.cc50
-rw-r--r--device/serial/serial_io_handler_posix.h7
-rw-r--r--device/serial/serial_io_handler_win.cc11
-rw-r--r--device/serial/serial_io_handler_win.h3
-rw-r--r--device/serial/serial_service_impl.cc14
-rw-r--r--device/serial/serial_service_impl.h2
-rw-r--r--device/serial/serial_service_unittest.cc2
-rw-r--r--device/serial/test_serial_io_handler.cc2
10 files changed, 123 insertions, 29 deletions
diff --git a/device/serial/serial_io_handler.cc b/device/serial/serial_io_handler.cc
index 341df29..a9cb52f 100644
--- a/device/serial/serial_io_handler.cc
+++ b/device/serial/serial_io_handler.cc
@@ -12,8 +12,10 @@
namespace device {
SerialIoHandler::SerialIoHandler(
- scoped_refptr<base::MessageLoopProxy> file_thread_message_loop)
- : file_thread_message_loop_(file_thread_message_loop) {
+ scoped_refptr<base::MessageLoopProxy> file_thread_message_loop,
+ scoped_refptr<base::MessageLoopProxy> ui_thread_message_loop)
+ : file_thread_message_loop_(file_thread_message_loop),
+ ui_thread_message_loop_(ui_thread_message_loop) {
}
SerialIoHandler::~SerialIoHandler() {
@@ -27,12 +29,36 @@ void SerialIoHandler::Open(const std::string& port,
DCHECK(open_complete_.is_null());
open_complete_ = callback;
DCHECK(file_thread_message_loop_.get());
- file_thread_message_loop_->PostTask(
- FROM_HERE,
- base::Bind(&SerialIoHandler::StartOpen,
- this,
- port,
- base::MessageLoopProxy::current()));
+ DCHECK(ui_thread_message_loop_.get());
+ RequestAccess(port, file_thread_message_loop_, ui_thread_message_loop_);
+}
+
+void SerialIoHandler::RequestAccess(
+ const std::string& port,
+ scoped_refptr<base::MessageLoopProxy> file_message_loop,
+ scoped_refptr<base::MessageLoopProxy> ui_message_loop) {
+ OnRequestAccessComplete(port, true /* success */);
+}
+
+void SerialIoHandler::OnRequestAccessComplete(const std::string& port,
+ bool success) {
+ DCHECK(CalledOnValidThread());
+ if (success) {
+ DCHECK(file_thread_message_loop_.get());
+ file_thread_message_loop_->PostTask(
+ FROM_HERE,
+ base::Bind(&SerialIoHandler::StartOpen,
+ this,
+ port,
+ base::MessageLoopProxy::current()));
+ return;
+ } else {
+ DCHECK(!open_complete_.is_null());
+ OpenCompleteCallback callback = open_complete_;
+ open_complete_.Reset();
+ callback.Run(false);
+ return;
+ }
}
void SerialIoHandler::StartOpen(
diff --git a/device/serial/serial_io_handler.h b/device/serial/serial_io_handler.h
index 5b2d059..46e0ed0 100644
--- a/device/serial/serial_io_handler.h
+++ b/device/serial/serial_io_handler.h
@@ -24,7 +24,8 @@ class SerialIoHandler : public base::NonThreadSafe,
public:
// Constructs an instance of some platform-specific subclass.
static scoped_refptr<SerialIoHandler> Create(
- scoped_refptr<base::MessageLoopProxy> file_thread_message_loop);
+ scoped_refptr<base::MessageLoopProxy> file_thread_message_loop,
+ scoped_refptr<base::MessageLoopProxy> ui_thread_message_loop);
typedef base::Callback<void(bool success)> OpenCompleteCallback;
@@ -32,6 +33,9 @@ class SerialIoHandler : public base::NonThreadSafe,
virtual void Open(const std::string& port,
const OpenCompleteCallback& callback);
+ // Signals that the access request for |port| is complete.
+ void OnRequestAccessComplete(const std::string& port, bool success);
+
// Performs an async Read operation. Behavior is undefined if this is called
// while a Read is already pending. Otherwise, the Done or DoneWithError
// method on |buffer| will eventually be called with a result.
@@ -79,7 +83,8 @@ class SerialIoHandler : public base::NonThreadSafe,
protected:
explicit SerialIoHandler(
- scoped_refptr<base::MessageLoopProxy> file_thread_message_loop);
+ scoped_refptr<base::MessageLoopProxy> file_thread_message_loop,
+ scoped_refptr<base::MessageLoopProxy> ui_thread_message_loop);
virtual ~SerialIoHandler();
// Performs a platform-specific read operation. This must guarantee that
@@ -92,7 +97,7 @@ class SerialIoHandler : public base::NonThreadSafe,
// Performs a platform-specific write operation. This must guarantee that
// WriteCompleted is called when the underlying async operation is completed
// or the SerialIoHandler instance will leak.
- // NOTE: Implementations of Writempl should never call WriteCompleted
+ // NOTE: Implementations of WriteImpl should never call WriteCompleted
// directly. Use QueueWriteCompleted instead to avoid reentrancy.
virtual void WriteImpl() = 0;
@@ -102,6 +107,12 @@ class SerialIoHandler : public base::NonThreadSafe,
// Platform-specific write cancelation.
virtual void CancelWriteImpl() = 0;
+ // Requests access to the underlying serial device, if needed.
+ virtual void RequestAccess(
+ const std::string& port,
+ scoped_refptr<base::MessageLoopProxy> file_message_loop,
+ scoped_refptr<base::MessageLoopProxy> ui_message_loop);
+
// Performs platform-specific, one-time port configuration on open.
virtual bool PostOpen();
@@ -187,6 +198,8 @@ class SerialIoHandler : public base::NonThreadSafe,
OpenCompleteCallback open_complete_;
scoped_refptr<base::MessageLoopProxy> file_thread_message_loop_;
+ // On Chrome OS, PermissionBrokerClient should be called on the UI thread.
+ scoped_refptr<base::MessageLoopProxy> ui_thread_message_loop_;
DISALLOW_COPY_AND_ASSIGN(SerialIoHandler);
};
diff --git a/device/serial/serial_io_handler_posix.cc b/device/serial/serial_io_handler_posix.cc
index a215661..020ee4c 100644
--- a/device/serial/serial_io_handler_posix.cc
+++ b/device/serial/serial_io_handler_posix.cc
@@ -11,7 +11,13 @@
#if defined(OS_LINUX)
#include <linux/serial.h>
-#endif
+#if defined(OS_CHROMEOS)
+#include "base/bind.h"
+#include "base/sys_info.h"
+#include "chromeos/dbus/dbus_thread_manager.h"
+#include "chromeos/dbus/permission_broker_client.h"
+#endif // defined(OS_CHROMEOS)
+#endif // defined(OS_LINUX)
namespace {
@@ -123,8 +129,41 @@ namespace device {
// static
scoped_refptr<SerialIoHandler> SerialIoHandler::Create(
- scoped_refptr<base::MessageLoopProxy> file_thread_message_loop) {
- return new SerialIoHandlerPosix(file_thread_message_loop);
+ scoped_refptr<base::MessageLoopProxy> file_thread_message_loop,
+ scoped_refptr<base::MessageLoopProxy> ui_thread_message_loop) {
+ return new SerialIoHandlerPosix(file_thread_message_loop,
+ ui_thread_message_loop);
+}
+
+void SerialIoHandlerPosix::RequestAccess(
+ const std::string& port,
+ scoped_refptr<base::MessageLoopProxy> file_message_loop,
+ scoped_refptr<base::MessageLoopProxy> ui_message_loop) {
+#if defined(OS_LINUX) && defined(OS_CHROMEOS)
+ if (base::SysInfo::IsRunningOnChromeOS()) {
+ chromeos::PermissionBrokerClient* client =
+ chromeos::DBusThreadManager::Get()->GetPermissionBrokerClient();
+ if (!client) {
+ DVLOG(1) << "Could not get permission_broker client.";
+ OnRequestAccessComplete(port, false /* failure */);
+ return;
+ }
+ // PermissionBrokerClient should be called on the UI thread.
+ ui_message_loop->PostTask(
+ FROM_HERE,
+ base::Bind(
+ &chromeos::PermissionBrokerClient::RequestPathAccess,
+ base::Unretained(client),
+ port,
+ -1,
+ base::Bind(&SerialIoHandler::OnRequestAccessComplete, this, port)));
+ } else {
+ OnRequestAccessComplete(port, true /* success */);
+ return;
+ }
+#else
+ OnRequestAccessComplete(port, true /* success */);
+#endif // defined(OS_LINUX) && defined(OS_CHROMEOS)
}
void SerialIoHandlerPosix::ReadImpl() {
@@ -158,8 +197,9 @@ void SerialIoHandlerPosix::CancelWriteImpl() {
}
SerialIoHandlerPosix::SerialIoHandlerPosix(
- scoped_refptr<base::MessageLoopProxy> file_thread_message_loop)
- : SerialIoHandler(file_thread_message_loop),
+ scoped_refptr<base::MessageLoopProxy> file_thread_message_loop,
+ scoped_refptr<base::MessageLoopProxy> ui_thread_message_loop)
+ : SerialIoHandler(file_thread_message_loop, ui_thread_message_loop),
is_watching_reads_(false),
is_watching_writes_(false) {
}
diff --git a/device/serial/serial_io_handler_posix.h b/device/serial/serial_io_handler_posix.h
index ef4bd37..7a6d97c 100644
--- a/device/serial/serial_io_handler_posix.h
+++ b/device/serial/serial_io_handler_posix.h
@@ -24,13 +24,18 @@ class SerialIoHandlerPosix : public SerialIoHandler,
const serial::HostControlSignals& control_signals) override;
virtual bool ConfigurePort(const serial::ConnectionOptions& options) override;
virtual serial::ConnectionInfoPtr GetPortInfo() const override;
+ virtual void RequestAccess(
+ const std::string& port,
+ scoped_refptr<base::MessageLoopProxy> file_message_loop,
+ scoped_refptr<base::MessageLoopProxy> ui_message_loop) override;
virtual bool PostOpen() override;
private:
friend class SerialIoHandler;
SerialIoHandlerPosix(
- scoped_refptr<base::MessageLoopProxy> file_thread_message_loop);
+ scoped_refptr<base::MessageLoopProxy> file_thread_message_loop,
+ scoped_refptr<base::MessageLoopProxy> ui_thread_message_loop);
virtual ~SerialIoHandlerPosix();
// base::MessageLoopForIO::Watcher implementation.
diff --git a/device/serial/serial_io_handler_win.cc b/device/serial/serial_io_handler_win.cc
index ac669ad..17d7db1 100644
--- a/device/serial/serial_io_handler_win.cc
+++ b/device/serial/serial_io_handler_win.cc
@@ -134,8 +134,10 @@ serial::StopBits StopBitsConstantToEnum(int stop_bits) {
// static
scoped_refptr<SerialIoHandler> SerialIoHandler::Create(
- scoped_refptr<base::MessageLoopProxy> file_thread_message_loop) {
- return new SerialIoHandlerWin(file_thread_message_loop);
+ scoped_refptr<base::MessageLoopProxy> file_thread_message_loop,
+ scoped_refptr<base::MessageLoopProxy> ui_thread_message_loop) {
+ return new SerialIoHandlerWin(file_thread_message_loop,
+ ui_thread_message_loop);
}
bool SerialIoHandlerWin::PostOpen() {
@@ -239,8 +241,9 @@ void SerialIoHandlerWin::CancelWriteImpl() {
}
SerialIoHandlerWin::SerialIoHandlerWin(
- scoped_refptr<base::MessageLoopProxy> file_thread_message_loop)
- : SerialIoHandler(file_thread_message_loop),
+ scoped_refptr<base::MessageLoopProxy> file_thread_message_loop,
+ scoped_refptr<base::MessageLoopProxy> ui_thread_message_loop)
+ : SerialIoHandler(file_thread_message_loop, ui_thread_message_loop),
event_mask_(0),
is_comm_pending_(false) {
}
diff --git a/device/serial/serial_io_handler_win.h b/device/serial/serial_io_handler_win.h
index ed45f5b..6ffaea3 100644
--- a/device/serial/serial_io_handler_win.h
+++ b/device/serial/serial_io_handler_win.h
@@ -31,7 +31,8 @@ class SerialIoHandlerWin : public SerialIoHandler,
friend class SerialIoHandler;
explicit SerialIoHandlerWin(
- scoped_refptr<base::MessageLoopProxy> file_thread_message_loop);
+ scoped_refptr<base::MessageLoopProxy> file_thread_message_loop,
+ scoped_refptr<base::MessageLoopProxy> ui_thread_message_loop);
virtual ~SerialIoHandlerWin();
// base::MessageLoopForIO::IOHandler implementation.
diff --git a/device/serial/serial_service_impl.cc b/device/serial/serial_service_impl.cc
index 0f87695..fceb448 100644
--- a/device/serial/serial_service_impl.cc
+++ b/device/serial/serial_service_impl.cc
@@ -28,10 +28,12 @@ SerialServiceImpl::~SerialServiceImpl() {
// static
void SerialServiceImpl::Create(
scoped_refptr<base::MessageLoopProxy> io_message_loop,
+ scoped_refptr<base::MessageLoopProxy> ui_message_loop,
mojo::InterfaceRequest<serial::SerialService> request) {
mojo::BindToRequest(new SerialServiceImpl(new SerialConnectionFactory(
base::Bind(SerialIoHandler::Create,
- base::MessageLoopProxy::current()),
+ base::MessageLoopProxy::current(),
+ ui_message_loop),
io_message_loop)),
&request);
}
@@ -40,11 +42,13 @@ void SerialServiceImpl::Create(
void SerialServiceImpl::CreateOnMessageLoop(
scoped_refptr<base::MessageLoopProxy> message_loop,
scoped_refptr<base::MessageLoopProxy> io_message_loop,
+ scoped_refptr<base::MessageLoopProxy> ui_message_loop,
mojo::InterfaceRequest<serial::SerialService> request) {
- message_loop->PostTask(
- FROM_HERE,
- base::Bind(
- &SerialServiceImpl::Create, io_message_loop, base::Passed(&request)));
+ message_loop->PostTask(FROM_HERE,
+ base::Bind(&SerialServiceImpl::Create,
+ io_message_loop,
+ ui_message_loop,
+ base::Passed(&request)));
}
void SerialServiceImpl::GetDevices(
diff --git a/device/serial/serial_service_impl.h b/device/serial/serial_service_impl.h
index b1c6612..796a1d4 100644
--- a/device/serial/serial_service_impl.h
+++ b/device/serial/serial_service_impl.h
@@ -24,10 +24,12 @@ class SerialServiceImpl : public mojo::InterfaceImpl<serial::SerialService> {
virtual ~SerialServiceImpl();
static void Create(scoped_refptr<base::MessageLoopProxy> io_message_loop,
+ scoped_refptr<base::MessageLoopProxy> ui_message_loop,
mojo::InterfaceRequest<serial::SerialService> request);
static void CreateOnMessageLoop(
scoped_refptr<base::MessageLoopProxy> message_loop,
scoped_refptr<base::MessageLoopProxy> io_message_loop,
+ scoped_refptr<base::MessageLoopProxy> ui_message_loop,
mojo::InterfaceRequest<serial::SerialService> request);
// mojo::InterfaceImpl<SerialService> overrides.
diff --git a/device/serial/serial_service_unittest.cc b/device/serial/serial_service_unittest.cc
index 20ebe3a..24558ae 100644
--- a/device/serial/serial_service_unittest.cc
+++ b/device/serial/serial_service_unittest.cc
@@ -113,7 +113,7 @@ class SerialServiceTest : public testing::Test, public mojo::ErrorHandler {
TEST_F(SerialServiceTest, GetDevices) {
mojo::InterfacePtr<serial::SerialService> service;
- SerialServiceImpl::Create(NULL, mojo::GetProxy(&service));
+ SerialServiceImpl::Create(NULL, NULL, mojo::GetProxy(&service));
service.set_error_handler(this);
mojo::Array<serial::DeviceInfoPtr> result;
service->GetDevices(
diff --git a/device/serial/test_serial_io_handler.cc b/device/serial/test_serial_io_handler.cc
index f4cc3bd..8ec5648 100644
--- a/device/serial/test_serial_io_handler.cc
+++ b/device/serial/test_serial_io_handler.cc
@@ -12,7 +12,7 @@
namespace device {
TestSerialIoHandler::TestSerialIoHandler()
- : SerialIoHandler(NULL),
+ : SerialIoHandler(NULL, NULL),
opened_(false),
dtr_(false),
rts_(false),