1 // Copyright 2019 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_MEDIA_PICKER_CONTROLLER_H_
6 #define CHROME_BROWSER_MEDIA_WEBRTC_DESKTOP_MEDIA_PICKER_CONTROLLER_H_
7 
8 #include <memory>
9 #include <string>
10 #include <utility>
11 
12 #include "base/macros.h"
13 #include "base/memory/weak_ptr.h"
14 #include "chrome/browser/media/webrtc/desktop_media_picker.h"
15 #include "content/public/browser/desktop_media_id.h"
16 #include "content/public/browser/web_contents_observer.h"
17 #include "ui/base/ui_base_types.h"
18 
19 class DesktopMediaList;
20 class DesktopMediaPickerFactory;
21 
22 // The main entry point for the desktop picker dialog box, which prompts the
23 // user to select a desktop or an application window whose content will be made
24 // available as a video stream.
25 //
26 // TODO(crbug.com/987001): Rename this class.  Consider merging with
27 // DesktopMediaPickerViews and naming the merged class just DesktopMediaPicker.
28 class DesktopMediaPickerController : private content::WebContentsObserver {
29  public:
30   using Params = DesktopMediaPicker::Params;
31 
32   // Callback for desktop selection results.  There are three possible cases:
33   //
34   // - If |err| is non-empty, it contains an error message regarding why the
35   //   dialog could not be displayed, and the value of |id| should not be used.
36   //
37   // - If |err| is empty and id.is_null() is true, the user canceled the dialog.
38   //
39   // - Otherwise, |id| represents the user's selection.
40   using DoneCallback = base::OnceCallback<void(const std::string& err,
41                                                content::DesktopMediaID id)>;
42 
43   explicit DesktopMediaPickerController(
44       DesktopMediaPickerFactory* picker_factory = nullptr);
45   DesktopMediaPickerController(const DesktopMediaPickerController&) = delete;
46   DesktopMediaPickerController& operator=(const DesktopMediaPickerController&) =
47       delete;
48   ~DesktopMediaPickerController() override;
49 
50   // Show the desktop picker dialog using the parameters specified by |params|,
51   // with the possible selections restricted to those included in |sources|.  If
52   // an error is detected synchronously, it is reported by returning an error
53   // string.  Otherwise, the return value is nullopt, and the closure passed as
54   // |done_callback| is called when the dialog is closed.  If the dialog is
55   // canceled, the argument to |done_callback| will be an instance of
56   // DesktopMediaID whose is_null() method returns true.
57   //
58   // As a special case, if |params.select_only_screen| is true, and the only
59   // selection type is TYPE_SCREEN, and there is only one screen,
60   // |done_callback| is called immediately with the screen's ID, and the dialog
61   // is not shown.  This option must be used with care, because even when the
62   // dialog has only one option to select, the dialog itself helps prevent the
63   // user for accidentally sharing their screen and gives them the option to
64   // prevent their screen from being shared.
65   //
66   // Note that |done_callback| is called only if the dialog completes normally.
67   // If an instance of this class is destroyed while the dialog is visible, the
68   // dialog will be cleaned up, but |done_callback| will not be invoked.
69   void Show(const Params& params,
70             const std::vector<content::DesktopMediaID::Type>& sources,
71             DoneCallback done_callback);
72 
73   // content::WebContentsObserver overrides.
74   void WebContentsDestroyed() override;
75 
76  private:
77   void OnInitialMediaListFound();
78   void ShowPickerDialog();
79   // This function is responsible to call |done_callback_| and after running the
80   // callback |this| might be destroyed. Do **not** access fields after calling
81   // this function.
82   void OnPickerDialogResults(const std::string& err,
83                              content::DesktopMediaID source);
84 
85   Params params_;
86   DoneCallback done_callback_;
87   std::vector<std::unique_ptr<DesktopMediaList>> source_lists_;
88   std::unique_ptr<DesktopMediaPicker> picker_;
89   DesktopMediaPickerFactory* picker_factory_;
90   base::WeakPtrFactory<DesktopMediaPickerController> weak_factory_{this};
91 };
92 
93 #endif  // CHROME_BROWSER_MEDIA_WEBRTC_DESKTOP_MEDIA_PICKER_CONTROLLER_H_
94