Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / media / native_desktop_media_list.cc
index 7f5128b..0c7104b 100644 (file)
@@ -5,6 +5,8 @@
 #include "chrome/browser/media/native_desktop_media_list.h"
 
 #include <map>
+#include <set>
+#include <sstream>
 
 #include "base/hash.h"
 #include "base/logging.h"
@@ -134,10 +136,23 @@ void NativeDesktopMediaList::Worker::Refresh(
   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_) {
@@ -154,10 +169,6 @@ void NativeDesktopMediaList::Worker::Refresh(
       }
     }
   }
-
-  // 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,
@@ -171,8 +182,9 @@ void NativeDesktopMediaList::Worker::Refresh(
     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:
@@ -276,12 +288,6 @@ const DesktopMediaList::Source& NativeDesktopMediaList::GetSource(
   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()),
@@ -290,33 +296,64 @@ void NativeDesktopMediaList::Refresh() {
 
 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(