1// Copyright 2013 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_DESKTOP_MEDIA_PICKER_MODEL_H_
6#define CHROME_BROWSER_MEDIA_DESKTOP_MEDIA_PICKER_MODEL_H_
7
8#include "base/basictypes.h"
9#include "base/memory/scoped_ptr.h"
10#include "base/memory/weak_ptr.h"
11#include "base/sequenced_task_runner.h"
12#include "content/public/common/desktop_media_id.h"
13#include "ui/gfx/image/image_skia.h"
14
15namespace webrtc {
16class ScreenCapturer;
17class WindowCapturer;
18}
19
20// DesktopMediaPickerModel provides the list of desktop media source (screens,
21// windows, tabs), and their thumbnails, to the desktop media picker dialog. It
22// transparently updates the list in the background, and notifies the desktop
23// media picker when something changes.
24class DesktopMediaPickerModel {
25 public:
26  // Interface implemented by the picker dialog to receive notifications when
27  // the model's contents change.
28  class Observer {
29   public:
30    virtual ~Observer() {}
31
32    virtual void OnSourceAdded(int index) = 0;
33    virtual void OnSourceRemoved(int index) = 0;
34    virtual void OnSourceNameChanged(int index) = 0;
35    virtual void OnSourceThumbnailChanged(int index) = 0;
36  };
37
38  // Struct used to represent each entry in the model.
39  struct Source {
40    Source(content::DesktopMediaID id, const string16& name);
41
42    // Id of the source.
43    content::DesktopMediaID id;
44
45    // Name of the source that should be shown to the user.
46    string16 name;
47
48    // The thumbnail for the source.
49    gfx::ImageSkia thumbnail;
50  };
51
52  DesktopMediaPickerModel();
53  virtual ~DesktopMediaPickerModel();
54
55  // Sets screen/window capturer implementations to use (e.g. for tests). Caller
56  // may pass NULL for either of the arguments in case when only some types of
57  // sources the model should be populated with (e.g. it will only contain
58  // windows, if |screen_capturer| is NULL). Must be called before
59  // StartUpdating().
60  void SetCapturers(scoped_ptr<webrtc::ScreenCapturer> screen_capturer,
61                    scoped_ptr<webrtc::WindowCapturer> window_capturer);
62
63  // Sets time interval between updates. By default list of sources and their
64  // thumbnail are updated once per second. If called after StartUpdating() then
65  // it will take effect only after the next update.
66  void SetUpdatePeriod(base::TimeDelta period);
67
68  // Sets size to which the thumbnails should be scaled. If called after
69  // StartUpdating() then some thumbnails may be still scaled to the old size
70  // until they are updated.
71  void SetThumbnailSize(const gfx::Size& thumbnail_size);
72
73  // Starts updating the model. The model is initially empty, so OnSourceAdded()
74  // notifications will be generated for each existing source as it is
75  // enumerated. After the initial enumeration the model will be refreshed based
76  // on the update period, and notifications generated only for changes in the
77  // model.
78  void StartUpdating(Observer* observer);
79
80  int source_count() const { return sources_.size(); }
81  const Source& source(int index) const { return sources_.at(index); }
82
83 private:
84  class Worker;
85  friend class Worker;
86
87  // Struct used to represent sources list the model gets from the Worker.
88  struct SourceDescription {
89    SourceDescription(content::DesktopMediaID id, const string16& name);
90
91    content::DesktopMediaID id;
92    string16 name;
93  };
94
95  // Order comparator for sources. Used to sort list of sources.
96  static bool CompareSources(const SourceDescription& a,
97                             const SourceDescription& b);
98
99  // Post a task for the |worker_| to update list of windows and get thumbnails.
100  void Refresh();
101
102  // Called by |worker_| to refresh the model. First it posts tasks for
103  // OnSourcesList() with the fresh list of sources, then follows with
104  // OnSourceThumbnail() for each changed thumbnail and then calls
105  // OnRefreshFinished() at the end.
106  void OnSourcesList(const std::vector<SourceDescription>& sources);
107  void OnSourceThumbnail(int index, const gfx::ImageSkia& thumbnail);
108  void OnRefreshFinished();
109
110  // Flags passed to the constructor.
111  int flags_;
112
113  // Capturers specified in SetCapturers() and passed to the |worker_| later.
114  scoped_ptr<webrtc::ScreenCapturer> screen_capturer_;
115  scoped_ptr<webrtc::WindowCapturer> window_capturer_;
116
117  // Time interval between mode updates.
118  base::TimeDelta update_period_;
119
120  // Size of thumbnails generated by the model.
121  gfx::Size thumbnail_size_;
122
123  // The observer passed to StartUpdating().
124  Observer* observer_;
125
126  // Task runner used for the |worker_|.
127  scoped_refptr<base::SequencedTaskRunner> capture_task_runner_;
128
129  // An object that does all the work of getting list of sources on a background
130  // thread (see |capture_task_runner_|). Destroyed on |capture_task_runner_|
131  // after the model is destroyed.
132  scoped_ptr<Worker> worker_;
133
134  // Current list of sources.
135  std::vector<Source> sources_;
136
137  base::WeakPtrFactory<DesktopMediaPickerModel> weak_factory_;
138
139  DISALLOW_COPY_AND_ASSIGN(DesktopMediaPickerModel);
140};
141
142#endif  // CHROME_BROWSER_MEDIA_DESKTOP_MEDIA_PICKER_MODEL_H_
143