Commit 63f4e4ef authored by Vincent Palatin's avatar Vincent Palatin Committed by Commit Bot

Mojo bridge interface for the USB Host

Define the bridge interface to connect the machine USB devices to the
Android USB host API.
Implement the API using /device/usb.

The permission request for the USB devices is currently stubbed and
fails closed. So until the Permission UI and settings are submitted, the
API basically rejects all the requests.

Bug: 24572867
Test: Manual, run with ARC++ app using android.hardware.usb to use USB
devices.

Change-Id: Ibce0a45e4359a97ee06d8d49981169bd5f18176f
Reviewed-on: https://chromium-review.googlesource.com/731284Reviewed-by: default avatarMattias Nissler <mnissler@chromium.org>
Reviewed-by: default avatarLuis Hector Chavez <lhchavez@chromium.org>
Reviewed-by: default avatarReilly Grant <reillyg@chromium.org>
Commit-Queue: Vincent Palatin <vpalatin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#523790}
parent f4d4f30b
...@@ -55,6 +55,7 @@ ...@@ -55,6 +55,7 @@
#include "components/arc/power/arc_power_bridge.h" #include "components/arc/power/arc_power_bridge.h"
#include "components/arc/rotation_lock/arc_rotation_lock_bridge.h" #include "components/arc/rotation_lock/arc_rotation_lock_bridge.h"
#include "components/arc/storage_manager/arc_storage_manager.h" #include "components/arc/storage_manager/arc_storage_manager.h"
#include "components/arc/usb/usb_host_bridge.h"
#include "components/arc/volume_mounter/arc_volume_mounter_bridge.h" #include "components/arc/volume_mounter/arc_volume_mounter_bridge.h"
#include "components/prefs/pref_member.h" #include "components/prefs/pref_member.h"
#include "ui/arc/notification/arc_notification_manager.h" #include "ui/arc/notification/arc_notification_manager.h"
...@@ -163,6 +164,7 @@ void ArcServiceLauncher::OnPrimaryUserProfilePrepared(Profile* profile) { ...@@ -163,6 +164,7 @@ void ArcServiceLauncher::OnPrimaryUserProfilePrepared(Profile* profile) {
ArcSettingsService::GetForBrowserContext(profile); ArcSettingsService::GetForBrowserContext(profile);
ArcTracingBridge::GetForBrowserContext(profile); ArcTracingBridge::GetForBrowserContext(profile);
ArcTtsService::GetForBrowserContext(profile); ArcTtsService::GetForBrowserContext(profile);
ArcUsbHostBridge::GetForBrowserContext(profile);
ArcUserSessionService::GetForBrowserContext(profile); ArcUserSessionService::GetForBrowserContext(profile);
ArcVoiceInteractionArcHomeService::GetForBrowserContext(profile); ArcVoiceInteractionArcHomeService::GetForBrowserContext(profile);
ArcVoiceInteractionFrameworkService::GetForBrowserContext(profile); ArcVoiceInteractionFrameworkService::GetForBrowserContext(profile);
......
...@@ -50,6 +50,8 @@ static_library("arc") { ...@@ -50,6 +50,8 @@ static_library("arc") {
"rotation_lock/arc_rotation_lock_bridge.h", "rotation_lock/arc_rotation_lock_bridge.h",
"storage_manager/arc_storage_manager.cc", "storage_manager/arc_storage_manager.cc",
"storage_manager/arc_storage_manager.h", "storage_manager/arc_storage_manager.h",
"usb/usb_host_bridge.cc",
"usb/usb_host_bridge.h",
"volume_mounter/arc_volume_mounter_bridge.cc", "volume_mounter/arc_volume_mounter_bridge.cc",
"volume_mounter/arc_volume_mounter_bridge.h", "volume_mounter/arc_volume_mounter_bridge.h",
] ]
...@@ -75,7 +77,11 @@ static_library("arc") { ...@@ -75,7 +77,11 @@ static_library("arc") {
"//components/url_formatter", "//components/url_formatter",
"//components/user_manager", "//components/user_manager",
"//content/public/common", "//content/public/common",
"//device/base",
"//device/bluetooth", "//device/bluetooth",
"//device/usb",
"//device/usb/mojo",
"//device/usb/public/interfaces",
"//google_apis", "//google_apis",
"//mojo/edk/system", "//mojo/edk/system",
"//services/device/public/interfaces", "//services/device/public/interfaces",
......
...@@ -248,6 +248,11 @@ void ArcBridgeHostImpl::OnTtsInstanceReady(mojom::TtsInstancePtr tts_ptr) { ...@@ -248,6 +248,11 @@ void ArcBridgeHostImpl::OnTtsInstanceReady(mojom::TtsInstancePtr tts_ptr) {
OnInstanceReady(arc_bridge_service_->tts(), std::move(tts_ptr)); OnInstanceReady(arc_bridge_service_->tts(), std::move(tts_ptr));
} }
void ArcBridgeHostImpl::OnUsbHostInstanceReady(
mojom::UsbHostInstancePtr usb_host_ptr) {
OnInstanceReady(arc_bridge_service_->usb_host(), std::move(usb_host_ptr));
}
void ArcBridgeHostImpl::OnVideoInstanceReady( void ArcBridgeHostImpl::OnVideoInstanceReady(
mojom::VideoInstancePtr video_ptr) { mojom::VideoInstancePtr video_ptr) {
OnInstanceReady(arc_bridge_service_->video(), std::move(video_ptr)); OnInstanceReady(arc_bridge_service_->video(), std::move(video_ptr));
......
...@@ -86,6 +86,7 @@ class ArcBridgeHostImpl : public mojom::ArcBridgeHost { ...@@ -86,6 +86,7 @@ class ArcBridgeHostImpl : public mojom::ArcBridgeHost {
mojom::StorageManagerInstancePtr storage_manager_ptr) override; mojom::StorageManagerInstancePtr storage_manager_ptr) override;
void OnTracingInstanceReady(mojom::TracingInstancePtr trace_ptr) override; void OnTracingInstanceReady(mojom::TracingInstancePtr trace_ptr) override;
void OnTtsInstanceReady(mojom::TtsInstancePtr tts_ptr) override; void OnTtsInstanceReady(mojom::TtsInstancePtr tts_ptr) override;
void OnUsbHostInstanceReady(mojom::UsbHostInstancePtr usb_host_ptr) override;
void OnVideoInstanceReady(mojom::VideoInstancePtr video_ptr) override; void OnVideoInstanceReady(mojom::VideoInstancePtr video_ptr) override;
void OnVoiceInteractionArcHomeInstanceReady( void OnVoiceInteractionArcHomeInstanceReady(
mojom::VoiceInteractionArcHomeInstancePtr home_ptr) override; mojom::VoiceInteractionArcHomeInstancePtr home_ptr) override;
......
...@@ -69,6 +69,8 @@ class StorageManagerInstance; ...@@ -69,6 +69,8 @@ class StorageManagerInstance;
class TracingInstance; class TracingInstance;
class TtsHost; class TtsHost;
class TtsInstance; class TtsInstance;
class UsbHostHost;
class UsbHostInstance;
class VideoHost; class VideoHost;
class VideoInstance; class VideoInstance;
class VoiceInteractionArcHomeHost; class VoiceInteractionArcHomeHost;
...@@ -184,6 +186,9 @@ class ArcBridgeService { ...@@ -184,6 +186,9 @@ class ArcBridgeService {
} }
ConnectionHolder<mojom::TracingInstance>* tracing() { return &tracing_; } ConnectionHolder<mojom::TracingInstance>* tracing() { return &tracing_; }
ConnectionHolder<mojom::TtsInstance, mojom::TtsHost>* tts() { return &tts_; } ConnectionHolder<mojom::TtsInstance, mojom::TtsHost>* tts() { return &tts_; }
ConnectionHolder<mojom::UsbHostInstance, mojom::UsbHostHost>* usb_host() {
return &usb_host_;
}
ConnectionHolder<mojom::VideoInstance, mojom::VideoHost>* video() { ConnectionHolder<mojom::VideoInstance, mojom::VideoHost>* video() {
return &video_; return &video_;
} }
...@@ -247,6 +252,7 @@ class ArcBridgeService { ...@@ -247,6 +252,7 @@ class ArcBridgeService {
ConnectionHolder<mojom::StorageManagerInstance> storage_manager_; ConnectionHolder<mojom::StorageManagerInstance> storage_manager_;
ConnectionHolder<mojom::TracingInstance> tracing_; ConnectionHolder<mojom::TracingInstance> tracing_;
ConnectionHolder<mojom::TtsInstance, mojom::TtsHost> tts_; ConnectionHolder<mojom::TtsInstance, mojom::TtsHost> tts_;
ConnectionHolder<mojom::UsbHostInstance, mojom::UsbHostHost> usb_host_;
ConnectionHolder<mojom::VideoInstance, mojom::VideoHost> video_; ConnectionHolder<mojom::VideoInstance, mojom::VideoHost> video_;
ConnectionHolder<mojom::VoiceInteractionArcHomeInstance, ConnectionHolder<mojom::VoiceInteractionArcHomeInstance,
mojom::VoiceInteractionArcHomeHost> mojom::VoiceInteractionArcHomeHost>
......
...@@ -46,6 +46,7 @@ if (is_chromeos) { ...@@ -46,6 +46,7 @@ if (is_chromeos) {
"storage_manager.mojom", "storage_manager.mojom",
"tracing.mojom", "tracing.mojom",
"tts.mojom", "tts.mojom",
"usb_host.mojom",
"voice_interaction_arc_home.mojom", "voice_interaction_arc_home.mojom",
"voice_interaction_framework.mojom", "voice_interaction_framework.mojom",
"volume_mounter.mojom", "volume_mounter.mojom",
......
...@@ -35,15 +35,16 @@ import "rotation_lock.mojom"; ...@@ -35,15 +35,16 @@ import "rotation_lock.mojom";
import "storage_manager.mojom"; import "storage_manager.mojom";
import "tracing.mojom"; import "tracing.mojom";
import "tts.mojom"; import "tts.mojom";
import "usb_host.mojom";
import "video.mojom"; import "video.mojom";
import "voice_interaction_arc_home.mojom"; import "voice_interaction_arc_home.mojom";
import "voice_interaction_framework.mojom"; import "voice_interaction_framework.mojom";
import "volume_mounter.mojom"; import "volume_mounter.mojom";
import "wallpaper.mojom"; import "wallpaper.mojom";
// Next MinVersion: 34 // Next MinVersion: 35
// Deprecated method IDs: 101, 105 // Deprecated method IDs: 101, 105
// Next method ID: 139 // Next method ID: 140
interface ArcBridgeHost { interface ArcBridgeHost {
// Keep the entries alphabetical. In order to do so without breaking // Keep the entries alphabetical. In order to do so without breaking
// compatibility with the ARC instance, explicitly assign each interface a // compatibility with the ARC instance, explicitly assign each interface a
...@@ -150,6 +151,9 @@ interface ArcBridgeHost { ...@@ -150,6 +151,9 @@ interface ArcBridgeHost {
// Notifies Chrome that the TtsInstance interface is ready. // Notifies Chrome that the TtsInstance interface is ready.
[MinVersion=17] OnTtsInstanceReady@123(TtsInstance instance_ptr); [MinVersion=17] OnTtsInstanceReady@123(TtsInstance instance_ptr);
// Notifies Chrome that the UsbHostInstance interface is ready.
[MinVersion=34] OnUsbHostInstanceReady@139(UsbHostInstance instance_ptr);
// Notifies Chrome that the VideoInstance interface is ready. // Notifies Chrome that the VideoInstance interface is ready.
[MinVersion=6] OnVideoInstanceReady@107(VideoInstance instance_ptr); [MinVersion=6] OnVideoInstanceReady@107(VideoInstance instance_ptr);
......
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Next MinVersion: 1
module arc.mojom;
// re-use device.mojom.UsbDeviceInfo
import "device/usb/public/interfaces/device.mojom";
// Next method ID: 3
interface UsbHostHost {
// Tries the open the USB device node for the device named 'guid'
// and returns an open file descriptor to this node.
// You need to have previously called RequestPermission for this 'guid'
// else this call will fail.
OpenDevice@0(string guid) => (handle usb_fd);
// Returns the USB device descriptors for the device named 'guid'.
GetDeviceInfo@1(string guid) => (string device_name,
device.mojom.UsbDeviceInfo info);
// Asks for the permission to access the USB device called 'guid',
// if 'guid' is an empty string, requests the permission to list USB devices
// instead.
// if the permission hasn't successfully obtained in the past, this will
// trigger a UI pop-up requesting the user authorization on the behalf of
// the package 'pkg_name' if 'interactive' is set to true, or fail
// immediately.
RequestPermission@2(string guid, string pkg_name, bool interactive)
=> (bool authorized);
};
// Next method ID: 3
interface UsbHostInstance {
// Establishes full-duplex communication with the host.
Init@0(UsbHostHost host_ptr) => ();
// Notifies the instance of a new USB device.
OnDeviceAdded@1(string guid);
// Notifies the instance of the removal of a USB device.
OnDeviceRemoved@2(string guid);
};
...@@ -98,6 +98,9 @@ void FakeArcBridgeHost::OnTracingInstanceReady( ...@@ -98,6 +98,9 @@ void FakeArcBridgeHost::OnTracingInstanceReady(
void FakeArcBridgeHost::OnTtsInstanceReady(mojom::TtsInstancePtr tts_ptr) {} void FakeArcBridgeHost::OnTtsInstanceReady(mojom::TtsInstancePtr tts_ptr) {}
void FakeArcBridgeHost::OnUsbHostInstanceReady(
mojom::UsbHostInstancePtr usb_ptr) {}
void FakeArcBridgeHost::OnVideoInstanceReady( void FakeArcBridgeHost::OnVideoInstanceReady(
mojom::VideoInstancePtr video_ptr) {} mojom::VideoInstancePtr video_ptr) {}
......
...@@ -64,6 +64,7 @@ class FakeArcBridgeHost : public mojom::ArcBridgeHost { ...@@ -64,6 +64,7 @@ class FakeArcBridgeHost : public mojom::ArcBridgeHost {
mojom::StorageManagerInstancePtr storage_manager_ptr) override; mojom::StorageManagerInstancePtr storage_manager_ptr) override;
void OnTracingInstanceReady(mojom::TracingInstancePtr trace_ptr) override; void OnTracingInstanceReady(mojom::TracingInstancePtr trace_ptr) override;
void OnTtsInstanceReady(mojom::TtsInstancePtr tts_ptr) override; void OnTtsInstanceReady(mojom::TtsInstancePtr tts_ptr) override;
void OnUsbHostInstanceReady(mojom::UsbHostInstancePtr usb_ptr) override;
void OnVideoInstanceReady(mojom::VideoInstancePtr video_ptr) override; void OnVideoInstanceReady(mojom::VideoInstancePtr video_ptr) override;
void OnVoiceInteractionArcHomeInstanceReady( void OnVoiceInteractionArcHomeInstanceReady(
mojom::VoiceInteractionArcHomeInstancePtr home_ptr) override; mojom::VoiceInteractionArcHomeInstancePtr home_ptr) override;
......
include_rules = [
"+device/base",
"+device/usb",
]
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "components/arc/usb/usb_host_bridge.h"
#include "base/bind.h"
#include "base/logging.h"
#include "base/memory/singleton.h"
#include "chromeos/dbus/dbus_thread_manager.h"
#include "chromeos/dbus/permission_broker_client.h"
#include "components/arc/arc_bridge_service.h"
#include "components/arc/arc_browser_context_keyed_service_factory_base.h"
#include "device/base/device_client.h"
#include "device/usb/mojo/type_converters.h"
#include "device/usb/usb_device_handle.h"
#include "device/usb/usb_device_linux.h"
#include "mojo/edk/embedder/embedder.h"
#include "mojo/edk/embedder/scoped_platform_handle.h"
namespace arc {
namespace {
// Singleton factory for ArcUsbHostBridge
class ArcUsbHostBridgeFactory
: public internal::ArcBrowserContextKeyedServiceFactoryBase<
ArcUsbHostBridge,
ArcUsbHostBridgeFactory> {
public:
// Factory name used by ArcBrowserContextKeyedServiceFactoryBase.
static constexpr const char* kName = "ArcUsbHostBridgeFactory";
static ArcUsbHostBridgeFactory* GetInstance() {
return base::Singleton<ArcUsbHostBridgeFactory>::get();
}
private:
friend base::DefaultSingletonTraits<ArcUsbHostBridgeFactory>;
ArcUsbHostBridgeFactory() = default;
~ArcUsbHostBridgeFactory() override = default;
};
void OnDeviceOpened(mojom::UsbHostHost::OpenDeviceCallback callback,
base::ScopedFD fd) {
if (!fd.is_valid()) {
LOG(ERROR) << "Invalid USB device FD";
std::move(callback).Run(mojo::ScopedHandle());
return;
}
mojo::edk::ScopedPlatformHandle platform_handle{
mojo::edk::PlatformHandle(fd.release())};
MojoHandle wrapped_handle;
MojoResult wrap_result = mojo::edk::CreatePlatformHandleWrapper(
std::move(platform_handle), &wrapped_handle);
if (wrap_result != MOJO_RESULT_OK) {
LOG(ERROR) << "Failed to wrap device FD. Closing: " << wrap_result;
std::move(callback).Run(mojo::ScopedHandle());
return;
}
mojo::ScopedHandle scoped_handle{mojo::Handle(wrapped_handle)};
std::move(callback).Run(std::move(scoped_handle));
}
void OnDeviceOpenError(mojom::UsbHostHost::OpenDeviceCallback callback,
const std::string& error_name,
const std::string& error_message) {
LOG(WARNING) << "Cannot open USB device: " << error_name << ": "
<< error_message;
std::move(callback).Run(mojo::ScopedHandle());
}
using CheckedCallback =
base::RepeatingCallback<void(const std::string& guid, bool success)>;
void OnGetDevicesComplete(
const CheckedCallback& callback,
const std::vector<scoped_refptr<device::UsbDevice>>& devices) {
for (const scoped_refptr<device::UsbDevice>& device : devices)
device->CheckUsbAccess(base::BindOnce(callback, device.get()->guid()));
}
} // namespace
ArcUsbHostBridge* ArcUsbHostBridge::GetForBrowserContext(
content::BrowserContext* context) {
return ArcUsbHostBridgeFactory::GetForBrowserContext(context);
}
ArcUsbHostBridge::ArcUsbHostBridge(content::BrowserContext* context,
ArcBridgeService* bridge_service)
: arc_bridge_service_(bridge_service),
usb_observer_(this),
weak_factory_(this) {
arc_bridge_service_->usb_host()->SetHost(this);
arc_bridge_service_->usb_host()->AddObserver(this);
usb_service_ = device::DeviceClient::Get()->GetUsbService();
if (usb_service_)
usb_observer_.Add(usb_service_);
}
ArcUsbHostBridge::~ArcUsbHostBridge() {
if (usb_service_)
usb_service_->RemoveObserver(this);
arc_bridge_service_->usb_host()->RemoveObserver(this);
arc_bridge_service_->usb_host()->SetHost(nullptr);
}
void ArcUsbHostBridge::RequestPermission(const std::string& guid,
const std::string& package,
bool interactive,
RequestPermissionCallback callback) {
VLOG(2) << "USB RequestPermission " << guid << " package " << package;
// Permission already requested.
if (HasPermissionForDevice(guid)) {
std::move(callback).Run(true);
return;
}
// The other side was just checking, fail without asking the user.
if (!interactive) {
std::move(callback).Run(false);
return;
}
// Ask the authorization from the user.
DoRequestUserAuthorization(guid, package, std::move(callback));
}
void ArcUsbHostBridge::OpenDevice(const std::string& guid,
OpenDeviceCallback callback) {
if (!usb_service_) {
std::move(callback).Run(mojo::ScopedHandle());
return;
}
device::UsbDeviceLinux* device =
static_cast<device::UsbDeviceLinux*>(usb_service_->GetDevice(guid).get());
if (!device) {
std::move(callback).Run(mojo::ScopedHandle());
return;
}
// The RequestPermission was never done, abort.
if (!HasPermissionForDevice(guid)) {
std::move(callback).Run(mojo::ScopedHandle());
return;
}
chromeos::PermissionBrokerClient* client =
chromeos::DBusThreadManager::Get()->GetPermissionBrokerClient();
DCHECK(client) << "Could not get permission broker client.";
auto repeating_callback =
base::AdaptCallbackForRepeating(std::move(callback));
client->OpenPath(device->device_path(),
base::Bind(&OnDeviceOpened, repeating_callback),
base::Bind(&OnDeviceOpenError, repeating_callback));
}
void ArcUsbHostBridge::GetDeviceInfo(const std::string& guid,
GetDeviceInfoCallback callback) {
if (!usb_service_) {
std::move(callback).Run(std::string(), nullptr);
return;
}
scoped_refptr<device::UsbDevice> device = usb_service_->GetDevice(guid);
if (!device.get()) {
LOG(WARNING) << "Unknown USB device " << guid;
std::move(callback).Run(std::string(), nullptr);
return;
}
device::mojom::UsbDeviceInfoPtr info =
device::mojom::UsbDeviceInfo::From(*device);
// b/69295049 the other side doesn't like optional strings.
for (const device::mojom::UsbConfigurationInfoPtr& cfg :
info->configurations) {
cfg->configuration_name =
cfg->configuration_name.value_or(base::string16());
for (const device::mojom::UsbInterfaceInfoPtr& iface : cfg->interfaces) {
for (const device::mojom::UsbAlternateInterfaceInfoPtr& alt :
iface->alternates) {
alt->interface_name = alt->interface_name.value_or(base::string16());
}
}
}
std::string path =
static_cast<device::UsbDeviceLinux*>(device.get())->device_path();
std::move(callback).Run(path, std::move(info));
}
// device::UsbService::Observer callbacks.
void ArcUsbHostBridge::OnDeviceAdded(scoped_refptr<device::UsbDevice> device) {
device->CheckUsbAccess(base::BindOnce(&ArcUsbHostBridge::OnDeviceChecked,
weak_factory_.GetWeakPtr(),
device.get()->guid()));
}
void ArcUsbHostBridge::OnDeviceRemoved(
scoped_refptr<device::UsbDevice> device) {
mojom::UsbHostInstance* usb_host_instance = ARC_GET_INSTANCE_FOR_METHOD(
arc_bridge_service_->usb_host(), OnDeviceAdded);
if (!usb_host_instance) {
VLOG(2) << "UsbInstance not ready yet";
return;
}
usb_host_instance->OnDeviceRemoved(device.get()->guid());
}
// Notifies the observer that the UsbService it depends on is shutting down.
void ArcUsbHostBridge::WillDestroyUsbService() {
// Disconnect.
arc_bridge_service_->usb_host()->SetHost(nullptr);
}
void ArcUsbHostBridge::OnConnectionReady() {
if (!usb_service_)
return;
// Send the (filtered) list of already existing USB devices to the other side.
usb_service_->GetDevices(
base::Bind(&OnGetDevicesComplete,
base::BindRepeating(&ArcUsbHostBridge::OnDeviceChecked,
weak_factory_.GetWeakPtr())));
}
void ArcUsbHostBridge::OnDeviceChecked(const std::string& guid, bool allowed) {
if (!allowed)
return;
mojom::UsbHostInstance* usb_host_instance = ARC_GET_INSTANCE_FOR_METHOD(
arc_bridge_service_->usb_host(), OnDeviceAdded);
if (!usb_host_instance)
return;
usb_host_instance->OnDeviceAdded(guid);
}
void ArcUsbHostBridge::DoRequestUserAuthorization(
const std::string& guid,
const std::string& package,
RequestPermissionCallback callback) {
// TODO: implement the UI dialog
// fail close for now
std::move(callback).Run(false);
}
bool ArcUsbHostBridge::HasPermissionForDevice(const std::string& guid) {
// TODO: implement permission settings
// fail close for now
return false;
}
} // namespace arc
// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef COMPONENTS_ARC_USB_USB_HOST_BRIDGE_H_
#define COMPONENTS_ARC_USB_USB_HOST_BRIDGE_H_
#include <string>
#include <vector>
#include "base/callback_forward.h"
#include "base/files/scoped_file.h"
#include "base/macros.h"
#include "base/scoped_observer.h"
#include "components/arc/common/usb_host.mojom.h"
#include "components/arc/connection_observer.h"
#include "components/keyed_service/core/keyed_service.h"
#include "device/usb/public/interfaces/device_manager.mojom.h"
#include "device/usb/usb_device.h"
#include "device/usb/usb_service.h"
namespace content {
class BrowserContext;
} // namespace content
namespace arc {
class ArcBridgeService;
// Private implementation of UsbHostHost.
class ArcUsbHostBridge : public KeyedService,
public ConnectionObserver<mojom::UsbHostInstance>,
public device::UsbService::Observer,
public mojom::UsbHostHost {
public:
// Returns singleton instance for the given BrowserContext,
// or nullptr if the browser |context| is not allowed to use ARC.
static ArcUsbHostBridge* GetForBrowserContext(
content::BrowserContext* context);
// The constructor will register an Observer with ArcBridgeService.
explicit ArcUsbHostBridge(content::BrowserContext* context,
ArcBridgeService* bridge_service);
~ArcUsbHostBridge() override;
// mojom::UsbHostHost overrides:
void RequestPermission(const std::string& guid,
const std::string& package,
bool interactive,
RequestPermissionCallback callback) override;
void OpenDevice(const std::string& guid,
OpenDeviceCallback callback) override;
void GetDeviceInfo(const std::string& guid,
GetDeviceInfoCallback callback) override;
// device::UsbService::Observer overrides:
void OnDeviceAdded(scoped_refptr<device::UsbDevice> device) override;
void OnDeviceRemoved(scoped_refptr<device::UsbDevice> device) override;
void WillDestroyUsbService() override;
// ConnectionObserver<mojom::UsbHostInstance> overrides:
void OnConnectionReady() override;
private:
void OnDeviceChecked(const std::string& guid, bool allowed);
void DoRequestUserAuthorization(const std::string& guid,
const std::string& package,
RequestPermissionCallback callback);
bool HasPermissionForDevice(const std::string& guid);
ArcBridgeService* const arc_bridge_service_; // Owned by ArcServiceManager.
mojom::UsbHostHostPtr usb_host_ptr_;
ScopedObserver<device::UsbService, device::UsbService::Observer>
usb_observer_;
device::UsbService* usb_service_;
// WeakPtrFactory to use for callbacks.
base::WeakPtrFactory<ArcUsbHostBridge> weak_factory_;
DISALLOW_COPY_AND_ASSIGN(ArcUsbHostBridge);
};
} // namespace arc
#endif // COMPONENTS_ARC_USB_USB_HOST_BRIDGE_H_
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment