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 #ifndef CHROME_BROWSER_USB_USB_CHOOSER_CONTEXT_H_
6 #define CHROME_BROWSER_USB_USB_CHOOSER_CONTEXT_H_
7 
8 #include <map>
9 #include <memory>
10 #include <set>
11 #include <string>
12 #include <utility>
13 #include <vector>
14 
15 #include "base/containers/queue.h"
16 #include "base/macros.h"
17 #include "base/observer_list.h"
18 #include "base/values.h"
19 #include "build/build_config.h"
20 #include "chrome/browser/usb/usb_policy_allowed_devices.h"
21 #include "components/permissions/chooser_context_base.h"
22 #include "mojo/public/cpp/bindings/associated_receiver.h"
23 #include "mojo/public/cpp/bindings/pending_receiver.h"
24 #include "mojo/public/cpp/bindings/pending_remote.h"
25 #include "mojo/public/cpp/bindings/remote.h"
26 #include "services/device/public/mojom/usb_manager.mojom.h"
27 #include "services/device/public/mojom/usb_manager_client.mojom.h"
28 #include "url/origin.h"
29 
30 class Profile;
31 
32 class UsbChooserContext : public permissions::ChooserContextBase,
33                           public device::mojom::UsbDeviceManagerClient {
34  public:
35   explicit UsbChooserContext(Profile* profile);
36   ~UsbChooserContext() override;
37 
38   // This observer can be used to be notified of changes to USB devices that are
39   // connected.
40   class DeviceObserver : public base::CheckedObserver {
41    public:
42     virtual void OnDeviceAdded(const device::mojom::UsbDeviceInfo&);
43     virtual void OnDeviceRemoved(const device::mojom::UsbDeviceInfo&);
44     virtual void OnDeviceManagerConnectionError();
45   };
46 
47   static base::Value DeviceInfoToValue(
48       const device::mojom::UsbDeviceInfo& device_info);
49 
50   // ChooserContextBase:
51   std::vector<std::unique_ptr<permissions::ChooserContextBase::Object>>
52   GetGrantedObjects(const url::Origin& requesting_origin,
53                     const url::Origin& embedding_origin) override;
54   std::vector<std::unique_ptr<permissions::ChooserContextBase::Object>>
55   GetAllGrantedObjects() override;
56   void RevokeObjectPermission(const url::Origin& requesting_origin,
57                               const url::Origin& embedding_origin,
58                               const base::Value& object) override;
59   bool IsValidObject(const base::Value& object) override;
60   base::string16 GetObjectDisplayName(const base::Value& object) override;
61 
62   // Grants |requesting_origin| access to the USB device.
63   void GrantDevicePermission(const url::Origin& requesting_origin,
64                              const url::Origin& embedding_origin,
65                              const device::mojom::UsbDeviceInfo& device_info);
66 
67   // Checks if |requesting_origin| (when embedded within |embedding_origin| has
68   // access to a device with |device_info|.
69   bool HasDevicePermission(const url::Origin& requesting_origin,
70                            const url::Origin& embedding_origin,
71                            const device::mojom::UsbDeviceInfo& device_info);
72 
73   void AddObserver(DeviceObserver* observer);
74   void RemoveObserver(DeviceObserver* observer);
75 
76   // Forward UsbDeviceManager methods.
77   void GetDevices(device::mojom::UsbDeviceManager::GetDevicesCallback callback);
78   void GetDevice(
79       const std::string& guid,
80       mojo::PendingReceiver<device::mojom::UsbDevice> device_receiver,
81       mojo::PendingRemote<device::mojom::UsbDeviceClient> device_client);
82 #if defined(OS_ANDROID)
83   void RefreshDeviceInfo(
84       const std::string& guid,
85       device::mojom::UsbDeviceManager::RefreshDeviceInfoCallback callback);
86 #endif
87 
88   // This method should only be called when you are sure that |devices_| has
89   // been initialized. It will return nullptr if the guid cannot be found.
90   const device::mojom::UsbDeviceInfo* GetDeviceInfo(const std::string& guid);
91 
92   base::WeakPtr<UsbChooserContext> AsWeakPtr();
93 
94   void SetDeviceManagerForTesting(
95       mojo::PendingRemote<device::mojom::UsbDeviceManager> fake_device_manager);
96 
97   void InitDeviceList(std::vector<::device::mojom::UsbDeviceInfoPtr> devices);
98 
99  private:
100   // device::mojom::UsbDeviceManagerClient implementation.
101   void OnDeviceAdded(device::mojom::UsbDeviceInfoPtr device_info) override;
102   void OnDeviceRemoved(device::mojom::UsbDeviceInfoPtr device_info) override;
103 
104   void OnDeviceManagerConnectionError();
105   void EnsureConnectionWithDeviceManager();
106   void SetUpDeviceManagerConnection();
107 #if defined(OS_ANDROID)
108   void OnDeviceInfoRefreshed(
109       device::mojom::UsbDeviceManager::RefreshDeviceInfoCallback callback,
110       device::mojom::UsbDeviceInfoPtr device_info);
111 #endif
112 
113   bool is_incognito_;
114   bool is_initialized_ = false;
115   base::queue<device::mojom::UsbDeviceManager::GetDevicesCallback>
116       pending_get_devices_requests_;
117 
118   std::map<std::pair<url::Origin, url::Origin>, std::set<std::string>>
119       ephemeral_devices_;
120   std::map<std::string, device::mojom::UsbDeviceInfoPtr> devices_;
121 
122   std::unique_ptr<UsbPolicyAllowedDevices> usb_policy_allowed_devices_;
123 
124   // Connection to |device_manager_instance_|.
125   mojo::Remote<device::mojom::UsbDeviceManager> device_manager_;
126   mojo::AssociatedReceiver<device::mojom::UsbDeviceManagerClient>
127       client_receiver_{this};
128   base::ObserverList<DeviceObserver> device_observer_list_;
129 
130   base::WeakPtrFactory<UsbChooserContext> weak_factory_{this};
131 
132   DISALLOW_COPY_AND_ASSIGN(UsbChooserContext);
133 };
134 
135 #endif  // CHROME_BROWSER_USB_USB_CHOOSER_CONTEXT_H_
136