1 // Copyright (c) 2012 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_MEDIA_WEBRTC_MEDIA_CAPTURE_DEVICES_DISPATCHER_H_
6 #define CHROME_BROWSER_MEDIA_WEBRTC_MEDIA_CAPTURE_DEVICES_DISPATCHER_H_
7 
8 #include <list>
9 #include <map>
10 #include <memory>
11 #include <string>
12 #include <vector>
13 
14 #include "base/callback.h"
15 #include "base/macros.h"
16 #include "base/memory/singleton.h"
17 #include "base/observer_list.h"
18 #include "components/webrtc/media_stream_device_enumerator_impl.h"
19 #include "content/public/browser/media_observer.h"
20 #include "content/public/browser/media_stream_request.h"
21 #include "content/public/browser/web_contents_delegate.h"
22 #include "third_party/blink/public/common/mediastream/media_stream_request.h"
23 
24 class MediaAccessHandler;
25 class MediaStreamCaptureIndicator;
26 class Profile;
27 
28 namespace extensions {
29 class Extension;
30 }
31 
32 namespace user_prefs {
33 class PrefRegistrySyncable;
34 }
35 
36 // This singleton is used to receive updates about media events from the content
37 // layer.
38 class MediaCaptureDevicesDispatcher
39     : public content::MediaObserver,
40       public webrtc::MediaStreamDeviceEnumeratorImpl {
41  public:
42   class Observer {
43    public:
44     // Handle an information update consisting of a up-to-date audio capture
45     // device lists. This happens when a microphone is plugged in or unplugged.
OnUpdateAudioDevices(const blink::MediaStreamDevices & devices)46     virtual void OnUpdateAudioDevices(
47         const blink::MediaStreamDevices& devices) {}
48 
49     // Handle an information update consisting of a up-to-date video capture
50     // device lists. This happens when a camera is plugged in or unplugged.
OnUpdateVideoDevices(const blink::MediaStreamDevices & devices)51     virtual void OnUpdateVideoDevices(
52         const blink::MediaStreamDevices& devices) {}
53 
54     // Handle an information update related to a media stream request.
OnRequestUpdate(int render_process_id,int render_frame_id,blink::mojom::MediaStreamType stream_type,const content::MediaRequestState state)55     virtual void OnRequestUpdate(int render_process_id,
56                                  int render_frame_id,
57                                  blink::mojom::MediaStreamType stream_type,
58                                  const content::MediaRequestState state) {}
59 
60     // Handle an information update that a new stream is being created.
OnCreatingAudioStream(int render_process_id,int render_frame_id)61     virtual void OnCreatingAudioStream(int render_process_id,
62                                        int render_frame_id) {}
63 
~Observer()64     virtual ~Observer() {}
65   };
66 
67   static MediaCaptureDevicesDispatcher* GetInstance();
68 
69   // Registers the preferences related to Media Stream default devices.
70   static void RegisterProfilePrefs(user_prefs::PrefRegistrySyncable* registry);
71 
72   // Returns true if the security origin is associated with casting.
73   static bool IsOriginForCasting(const GURL& origin);
74 
75   // Methods for observers. Called on UI thread.
76   // Observers should add themselves on construction and remove themselves
77   // on destruction.
78   void AddObserver(Observer* observer);
79   void RemoveObserver(Observer* observer);
80 
81   // Method called from WebCapturerDelegate implementations to process access
82   // requests. |extension| is set to NULL if request was made from a drive-by
83   // page.
84   void ProcessMediaAccessRequest(content::WebContents* web_contents,
85                                  const content::MediaStreamRequest& request,
86                                  content::MediaResponseCallback callback,
87                                  const extensions::Extension* extension);
88 
89   // Method called from WebCapturerDelegate implementations to check media
90   // access permission. Note that this does not query the user.
91   bool CheckMediaAccessPermission(content::RenderFrameHost* render_frame_host,
92                                   const GURL& security_origin,
93                                   blink::mojom::MediaStreamType type);
94 
95   // Same as above but for an |extension|, which may not be NULL.
96   bool CheckMediaAccessPermission(content::RenderFrameHost* render_frame_host,
97                                   const GURL& security_origin,
98                                   blink::mojom::MediaStreamType type,
99                                   const extensions::Extension* extension);
100 
101   // Unittests that do not require actual device enumeration should call this
102   // API on the singleton. It is safe to call this multiple times on the
103   // signleton.
104   void DisableDeviceEnumerationForTesting();
105 
106   // Helper to get default device IDs. If the returned value is an empty string,
107   // it means that there is no default device for the given device |type|. The
108   // only supported |type| values are
109   // blink::mojom::MediaStreamType::DEVICE_AUDIO_CAPTURE and
110   // blink::mojom::MediaStreamType::DEVICE_VIDEO_CAPTURE.
111   // Must be called on the UI thread.
112   std::string GetDefaultDeviceIDForProfile(Profile* profile,
113                                            blink::mojom::MediaStreamType type);
114 
115   // webrtc::MediaStreamDeviceEnumeratorImpl:
116   const blink::MediaStreamDevices& GetAudioCaptureDevices() const override;
117   const blink::MediaStreamDevices& GetVideoCaptureDevices() const override;
118   void GetDefaultDevicesForBrowserContext(
119       content::BrowserContext* context,
120       bool audio,
121       bool video,
122       blink::MediaStreamDevices* devices) override;
123 
124   // content::MediaObserver:
125   void OnAudioCaptureDevicesChanged() override;
126   void OnVideoCaptureDevicesChanged() override;
127   void OnMediaRequestStateChanged(int render_process_id,
128                                   int render_frame_id,
129                                   int page_request_id,
130                                   const GURL& security_origin,
131                                   blink::mojom::MediaStreamType stream_type,
132                                   content::MediaRequestState state) override;
133   void OnCreatingAudioStream(int render_process_id,
134                              int render_frame_id) override;
135   void OnSetCapturingLinkSecured(int render_process_id,
136                                  int render_frame_id,
137                                  int page_request_id,
138                                  blink::mojom::MediaStreamType stream_type,
139                                  bool is_secure) override;
140 
141   scoped_refptr<MediaStreamCaptureIndicator> GetMediaStreamCaptureIndicator();
142 
143   // Return true if there is any ongoing insecured capturing. The capturing is
144   // deemed secure if all connected video sinks are reported secure and the
145   // extension is trusted.
146   bool IsInsecureCapturingInProgress(int render_process_id,
147                                      int render_frame_id);
148 
149   // Only for testing.
150   void SetTestAudioCaptureDevices(const blink::MediaStreamDevices& devices);
151   void SetTestVideoCaptureDevices(const blink::MediaStreamDevices& devices);
152 
153  private:
154   friend class MediaCaptureDevicesDispatcherTest;
155 
156   friend struct base::DefaultSingletonTraits<MediaCaptureDevicesDispatcher>;
157 
158   MediaCaptureDevicesDispatcher();
159   ~MediaCaptureDevicesDispatcher() override;
160 
161   // Called by the MediaObserver() functions, executed on UI thread.
162   void NotifyAudioDevicesChangedOnUIThread();
163   void NotifyVideoDevicesChangedOnUIThread();
164   void UpdateMediaRequestStateOnUIThread(
165       int render_process_id,
166       int render_frame_id,
167       int page_request_id,
168       const GURL& security_origin,
169       blink::mojom::MediaStreamType stream_type,
170       content::MediaRequestState state);
171   void OnCreatingAudioStreamOnUIThread(int render_process_id,
172                                        int render_frame_id);
173   void UpdateVideoScreenCaptureStatus(int render_process_id,
174                                       int render_frame_id,
175                                       int page_request_id,
176                                       blink::mojom::MediaStreamType stream_type,
177                                       bool is_secure);
178 
179   // Only for testing, a list of cached audio capture devices.
180   blink::MediaStreamDevices test_audio_devices_;
181 
182   // Only for testing, a list of cached video capture devices.
183   blink::MediaStreamDevices test_video_devices_;
184 
185   // A list of observers for the device update notifications.
186   base::ObserverList<Observer>::Unchecked observers_;
187 
188   // Flag used by unittests to disable device enumeration.
189   bool is_device_enumeration_disabled_;
190 
191   scoped_refptr<MediaStreamCaptureIndicator> media_stream_capture_indicator_;
192 
193   // Handlers for processing media access requests.
194   std::vector<std::unique_ptr<MediaAccessHandler>> media_access_handlers_;
195 
196   DISALLOW_COPY_AND_ASSIGN(MediaCaptureDevicesDispatcher);
197 };
198 
199 #endif  // CHROME_BROWSER_MEDIA_WEBRTC_MEDIA_CAPTURE_DEVICES_DISPATCHER_H_
200