1 // Copyright 2016 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_LIST_BASE_H_
6 #define CHROME_BROWSER_MEDIA_WEBRTC_DESKTOP_MEDIA_LIST_BASE_H_
7 
8 #include "chrome/browser/media/webrtc/desktop_media_list.h"
9 #include "chrome/browser/media/webrtc/desktop_media_list_observer.h"
10 #include "content/public/browser/desktop_media_id.h"
11 
12 namespace gfx {
13 class Image;
14 }
15 
16 // Thumbnail size is 100*100 pixels
17 static const int kDefaultThumbnailSize = 100;
18 
19 // Base class for DesktopMediaList implementations. Implements logic shared
20 // between implementations. Specifically it's responsible for keeping current
21 // list of sources and calling the observer when the list changes.
22 //
23 // TODO(crbug.com/987001): Consider renaming this class.
24 class DesktopMediaListBase : public DesktopMediaList {
25  public:
26   explicit DesktopMediaListBase(base::TimeDelta update_period);
27   ~DesktopMediaListBase() override;
28 
29   // DesktopMediaList interface.
30   void SetUpdatePeriod(base::TimeDelta period) override;
31   void SetThumbnailSize(const gfx::Size& thumbnail_size) override;
32   void SetViewDialogWindowId(content::DesktopMediaID dialog_id) override;
33   void StartUpdating(DesktopMediaListObserver* observer) override;
34   void Update(UpdateCallback callback) override;
35   int GetSourceCount() const override;
36   const Source& GetSource(int index) const override;
37   content::DesktopMediaID::Type GetMediaListType() const override;
38 
39   static uint32_t GetImageHash(const gfx::Image& image);
40 
41  protected:
42   using RefreshCallback = UpdateCallback;
43 
44   struct SourceDescription {
45     SourceDescription(content::DesktopMediaID id, const base::string16& name);
46 
47     content::DesktopMediaID id;
48     base::string16 name;
49   };
50 
51   // Before this method is called, |refresh_callback_| must be non-null, and
52   // after it completes (usually asychnonrously), |refresh_callback_| must be
53   // null.  Since |refresh_callback_| is private, subclasses can check this
54   // condition by calling can_refresh().
55   virtual void Refresh(bool update_thumnails) = 0;
56 
57   // Update source media list to observer.
58   void UpdateSourcesList(const std::vector<SourceDescription>& new_sources);
59 
60   // Update a thumbnail to observer.
61   void UpdateSourceThumbnail(content::DesktopMediaID id,
62                              const gfx::ImageSkia& image);
63 
64   // Called when a refresh is complete.  Invokes |refresh_callback_| unless it
65   // is null.  Postcondition: |refresh_callback_| is null.
66   void OnRefreshComplete();
67 
can_refresh()68   bool can_refresh() const { return !refresh_callback_.is_null(); }
69 
70   // Size of thumbnails generated by the model.
71   gfx::Size thumbnail_size_ =
72       gfx::Size(kDefaultThumbnailSize, kDefaultThumbnailSize);
73 
74   // ID of the hosting dialog.
75   content::DesktopMediaID view_dialog_id_ =
76       content::DesktopMediaID(content::DesktopMediaID::TYPE_NONE, -1);
77 
78   // Desktop media type of the list.
79   content::DesktopMediaID::Type type_ = content::DesktopMediaID::TYPE_NONE;
80 
81  private:
82   // Post a task for next list update.
83   void ScheduleNextRefresh();
84 
85   // Time interval between mode updates.
86   base::TimeDelta update_period_;
87 
88   // Current list of sources.
89   std::vector<Source> sources_;
90 
91   // The observer passed to StartUpdating().
92   DesktopMediaListObserver* observer_ = nullptr;
93 
94   // Called when a refresh operation completes.
95   RefreshCallback refresh_callback_;
96 
97   base::WeakPtrFactory<DesktopMediaListBase> weak_factory_{this};
98 
99   DISALLOW_COPY_AND_ASSIGN(DesktopMediaListBase);
100 };
101 
102 #endif  // CHROME_BROWSER_MEDIA_WEBRTC_DESKTOP_MEDIA_LIST_BASE_H_
103