#include "chrome/browser/media/native_desktop_media_list.h"
#include <map>
+#include <set>
+#include <sstream>
#include "base/hash.h"
#include "base/logging.h"
std::vector<SourceDescription> sources;
if (screen_capturer_) {
- // TODO(sergeyu): Enumerate each screen when ScreenCapturer supports it.
- sources.push_back(SourceDescription(DesktopMediaID(
- DesktopMediaID::TYPE_SCREEN, 0),
- l10n_util::GetStringUTF16(IDS_DESKTOP_MEDIA_PICKER_SCREEN_NAME)));
+ webrtc::ScreenCapturer::ScreenList screens;
+ if (screen_capturer_->GetScreenList(&screens)) {
+ bool mutiple_screens = screens.size() > 1;
+ base::string16 title;
+ for (size_t i = 0; i < screens.size(); ++i) {
+ if (mutiple_screens) {
+ title = l10n_util::GetStringFUTF16Int(
+ IDS_DESKTOP_MEDIA_PICKER_MULTIPLE_SCREEN_NAME,
+ static_cast<int>(i + 1));
+ } else {
+ title = l10n_util::GetStringUTF16(
+ IDS_DESKTOP_MEDIA_PICKER_SINGLE_SCREEN_NAME);
+ }
+ sources.push_back(SourceDescription(DesktopMediaID(
+ DesktopMediaID::TYPE_SCREEN, screens[i].id), title));
+ }
+ }
}
if (window_capturer_) {
}
}
}
-
- // Sort the list of sources so that they appear in a predictable order.
- std::sort(sources.begin(), sources.end(), CompareSources);
-
// Update list of windows before updating thumbnails.
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
SourceDescription& source = sources[i];
switch (source.id.type) {
case DesktopMediaID::TYPE_SCREEN:
+ if (!screen_capturer_->SelectScreen(source.id.id))
+ continue;
screen_capturer_->Capture(webrtc::DesktopRegion());
- DCHECK(current_frame_);
break;
case DesktopMediaID::TYPE_WINDOW:
return sources_[index];
}
-// static
-bool NativeDesktopMediaList::CompareSources(const SourceDescription& a,
- const SourceDescription& b) {
- return a.id < b.id;
-}
-
void NativeDesktopMediaList::Refresh() {
capture_task_runner_->PostTask(
FROM_HERE, base::Bind(&Worker::Refresh, base::Unretained(worker_.get()),
void NativeDesktopMediaList::OnSourcesList(
const std::vector<SourceDescription>& new_sources) {
- // Step through |new_sources| adding and removing entries from |sources_|, and
- // notifying the |observer_|, until two match. Requires that |sources| and
- // |sources_| have the same ordering.
+ typedef std::set<content::DesktopMediaID> SourceSet;
+ SourceSet new_source_set;
+ for (size_t i = 0; i < new_sources.size(); ++i) {
+ new_source_set.insert(new_sources[i].id);
+ }
+ // Iterate through the old sources to find the removed sources.
+ for (size_t i = 0; i < sources_.size(); ++i) {
+ if (new_source_set.find(sources_[i].id) == new_source_set.end()) {
+ sources_.erase(sources_.begin() + i);
+ observer_->OnSourceRemoved(i);
+ --i;
+ }
+ }
+ // Iterate through the new sources to find the added sources.
+ if (new_sources.size() > sources_.size()) {
+ SourceSet old_source_set;
+ for (size_t i = 0; i < sources_.size(); ++i) {
+ old_source_set.insert(sources_[i].id);
+ }
+
+ for (size_t i = 0; i < new_sources.size(); ++i) {
+ if (old_source_set.find(new_sources[i].id) == old_source_set.end()) {
+ sources_.insert(sources_.begin() + i, Source());
+ sources_[i].id = new_sources[i].id;
+ sources_[i].name = new_sources[i].name;
+ observer_->OnSourceAdded(i);
+ }
+ }
+ }
+ DCHECK_EQ(new_sources.size(), sources_.size());
+
+ // Find the moved/changed sources.
size_t pos = 0;
- while (pos < sources_.size() || pos < new_sources.size()) {
- // If |sources_[pos]| is not in |new_sources| then remove it.
- if (pos < sources_.size() &&
- (pos == new_sources.size() || sources_[pos].id < new_sources[pos].id)) {
- sources_.erase(sources_.begin() + pos);
- observer_->OnSourceRemoved(pos);
- continue;
+ while (pos < sources_.size()) {
+ if (!(sources_[pos].id == new_sources[pos].id)) {
+ // Find the source that should be moved to |pos|, starting from |pos + 1|
+ // of |sources_|, because entries before |pos| should have been sorted.
+ size_t old_pos = pos + 1;
+ for (; old_pos < sources_.size(); ++old_pos) {
+ if (sources_[old_pos].id == new_sources[pos].id)
+ break;
+ }
+ DCHECK(sources_[old_pos].id == new_sources[pos].id);
+
+ // Move the source from |old_pos| to |pos|.
+ Source temp = sources_[old_pos];
+ sources_.erase(sources_.begin() + old_pos);
+ sources_.insert(sources_.begin() + pos, temp);
+
+ observer_->OnSourceMoved(old_pos, pos);
}
- if (pos == sources_.size() || !(sources_[pos].id == new_sources[pos].id)) {
- sources_.insert(sources_.begin() + pos, Source());
- sources_[pos].id = new_sources[pos].id;
- sources_[pos].name = new_sources[pos].name;
- observer_->OnSourceAdded(pos);
- } else if (sources_[pos].name != new_sources[pos].name) {
+ if (sources_[pos].name != new_sources[pos].name) {
sources_[pos].name = new_sources[pos].name;
observer_->OnSourceNameChanged(pos);
}
-
++pos;
}
-
- DCHECK_EQ(new_sources.size(), sources_.size());
}
void NativeDesktopMediaList::OnSourceThumbnail(