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_MEDIA_WEBRTC_DESKTOP_CAPTURE_ACCESS_HANDLER_H_
6 #define CHROME_BROWSER_MEDIA_WEBRTC_DESKTOP_CAPTURE_ACCESS_HANDLER_H_
7 
8 #include <list>
9 #include <memory>
10 #include <string>
11 #include <utility>
12 
13 #include "base/containers/flat_map.h"
14 #include "base/macros.h"
15 #include "chrome/browser/media/capture_access_handler_base.h"
16 #include "chrome/browser/media/media_access_handler.h"
17 #include "chrome/browser/media/webrtc/desktop_media_list.h"
18 #include "chrome/browser/media/webrtc/desktop_media_picker.h"
19 #include "chrome/browser/media/webrtc/desktop_media_picker_factory.h"
20 #include "content/public/browser/desktop_media_id.h"
21 #include "content/public/browser/notification_observer.h"
22 #include "content/public/browser/notification_registrar.h"
23 
24 #if defined(OS_CHROMEOS)
25 namespace aura {
26 class Window;
27 }
28 #endif
29 
30 namespace extensions {
31 class Extension;
32 }
33 
34 // MediaAccessHandler for DesktopCapture API requests that originate from
35 // getUserMedia() calls. Note that getDisplayMedia() calls are handled in
36 // DisplayMediaAccessHandler.
37 class DesktopCaptureAccessHandler : public CaptureAccessHandlerBase,
38                                     public content::NotificationObserver {
39  public:
40   DesktopCaptureAccessHandler();
41   explicit DesktopCaptureAccessHandler(
42       std::unique_ptr<DesktopMediaPickerFactory> picker_factory);
43   ~DesktopCaptureAccessHandler() override;
44 
45   // MediaAccessHandler implementation.
46   bool SupportsStreamType(content::WebContents* web_contents,
47                           const blink::mojom::MediaStreamType type,
48                           const extensions::Extension* extension) override;
49   bool CheckMediaAccessPermission(
50       content::RenderFrameHost* render_frame_host,
51       const GURL& security_origin,
52       blink::mojom::MediaStreamType type,
53       const extensions::Extension* extension) override;
54   void HandleRequest(content::WebContents* web_contents,
55                      const content::MediaStreamRequest& request,
56                      content::MediaResponseCallback callback,
57                      const extensions::Extension* extension) override;
58   void UpdateMediaRequestState(int render_process_id,
59                                int render_frame_id,
60                                int page_request_id,
61                                blink::mojom::MediaStreamType stream_type,
62                                content::MediaRequestState state) override;
63 
64  private:
65   friend class DesktopCaptureAccessHandlerTest;
66 
67   struct PendingAccessRequest;
68   using RequestsQueue =
69       base::circular_deque<std::unique_ptr<PendingAccessRequest>>;
70   using RequestsQueues = base::flat_map<content::WebContents*, RequestsQueue>;
71 
72   void ProcessScreenCaptureAccessRequest(
73       content::WebContents* web_contents,
74       const content::MediaStreamRequest& request,
75       content::MediaResponseCallback callback,
76       const extensions::Extension* extension);
77 
78   // Returns whether desktop capture is always approved for |extension|.
79   // Currently component extensions and some external extensions are default
80   // approved.
81   static bool IsDefaultApproved(const extensions::Extension* extension);
82 
83   // content::NotificationObserver implementation.
84   void Observe(int type,
85                const content::NotificationSource& source,
86                const content::NotificationDetails& details) override;
87   void AddNotificationObserver();
88 
89   // Methods for handling source change request, e.g. bringing up the picker to
90   // select a new source within the current desktop sharing session.
91   void ProcessChangeSourceRequest(content::WebContents* web_contents,
92                                   const content::MediaStreamRequest& request,
93                                   content::MediaResponseCallback callback,
94                                   const extensions::Extension* extension);
95   void ProcessQueuedAccessRequest(const RequestsQueue& queue,
96                                   content::WebContents* web_contents);
97   void OnPickerDialogResults(content::WebContents* web_contents,
98                              content::DesktopMediaID source);
99   void DeletePendingAccessRequest(int render_process_id,
100                                   int render_frame_id,
101                                   int page_request_id);
102 
103   std::unique_ptr<DesktopMediaPickerFactory> picker_factory_;
104   bool display_notification_;
105   RequestsQueues pending_requests_;
106   content::NotificationRegistrar notifications_registrar_;
107 
108 #if defined(OS_CHROMEOS)
109   aura::Window* primary_root_window_for_testing_ = nullptr;
110 #endif
111 
112   DISALLOW_COPY_AND_ASSIGN(DesktopCaptureAccessHandler);
113 };
114 
115 #endif  // CHROME_BROWSER_MEDIA_WEBRTC_DESKTOP_CAPTURE_ACCESS_HANDLER_H_
116