Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(2112)

Unified Diff: chrome/browser/media/native_desktop_media_list.cc

Issue 1503563004: Desktop chrome tab capture-chooseDesktopMedia() (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/media/native_desktop_media_list.cc
diff --git a/chrome/browser/media/native_desktop_media_list.cc b/chrome/browser/media/native_desktop_media_list.cc
index 32a8c0d923a27c2763ea907874af45ac7147f445..da7003c7866e0022b5367bc801871ac58f573c88 100644
--- a/chrome/browser/media/native_desktop_media_list.cc
+++ b/chrome/browser/media/native_desktop_media_list.cc
@@ -12,17 +12,27 @@
#include "base/logging.h"
#include "base/strings/utf_string_conversions.h"
#include "base/threading/sequenced_worker_pool.h"
+#include "chrome/browser/mac/bluetooth_utility.h"
#include "chrome/browser/media/desktop_media_list_observer.h"
+#include "chrome/browser/profiles/profile_manager.h"
+#include "chrome/browser/ui/browser_finder.h"
+#include "chrome/browser/ui/host_desktop.h"
+#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "chrome/grit/generated_resources.h"
+#include "components/favicon/content/content_favicon_driver.h"
#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/render_frame_host.h"
+#include "content/public/browser/render_process_host.h"
#include "media/base/video_util.h"
#include "third_party/libyuv/include/libyuv/scale_argb.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "third_party/webrtc/modules/desktop_capture/desktop_frame.h"
#include "third_party/webrtc/modules/desktop_capture/screen_capturer.h"
#include "third_party/webrtc/modules/desktop_capture/window_capturer.h"
+#include "ui/aura/window.h"
#include "ui/base/l10n/l10n_util.h"
#include "ui/gfx/skia_util.h"
+#include "ui/snapshot/snapshot.h"
using content::BrowserThread;
using content::DesktopMediaID;
@@ -78,9 +88,7 @@ gfx::ImageSkia ScaleDesktopFrame(scoped_ptr<webrtc::DesktopFrame> frame,
NativeDesktopMediaList::SourceDescription::SourceDescription(
DesktopMediaID id,
const base::string16& name)
- : id(id),
- name(name) {
-}
+ : id(id), name(name) {}
class NativeDesktopMediaList::Worker
: public webrtc::DesktopCapturer::Callback {
@@ -91,7 +99,8 @@ class NativeDesktopMediaList::Worker
~Worker() override;
void Refresh(const gfx::Size& thumbnail_size,
- content::DesktopMediaID::Id view_dialog_id);
+ content::DesktopMediaID::Id view_dialog_id,
+ std::vector<SourceDescription> tab_sources);
private:
typedef std::map<DesktopMediaID, uint32> ImageHashesMap;
@@ -129,7 +138,8 @@ NativeDesktopMediaList::Worker::~Worker() {}
void NativeDesktopMediaList::Worker::Refresh(
const gfx::Size& thumbnail_size,
- content::DesktopMediaID::Id view_dialog_id) {
+ content::DesktopMediaID::Id view_dialog_id,
+ std::vector<SourceDescription> tab_sources) {
std::vector<SourceDescription> sources;
if (screen_capturer_) {
@@ -166,6 +176,10 @@ void NativeDesktopMediaList::Worker::Refresh(
}
}
}
+
+ // Add tab sources to all media sources
+ sources.insert(sources.end(), tab_sources.begin(), tab_sources.end());
+
// Update list of windows before updating thumbnails.
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
@@ -189,11 +203,23 @@ void NativeDesktopMediaList::Worker::Refresh(
continue;
window_capturer_->Capture(webrtc::DesktopRegion());
break;
+ case DesktopMediaID::TYPE_TAB:
+ // Favicon has already captured for tabs.
qiangchen 2015/12/07 22:45:56 Consider moving the Favicon "capturing" here.
miu 2015/12/08 01:54:38 IIUC, I think that has to be done on the UI thread
GeorgeZ 2015/12/09 19:36:37 This is a no UI thread. Favicon capture has to to
+ break;
default:
NOTREACHED();
}
+ // Use captured tab favicon as thumbnail.
+ if (source.id.type == DesktopMediaID::TYPE_TAB) {
+ BrowserThread::PostTask(
+ BrowserThread::UI, FROM_HERE,
+ base::Bind(&NativeDesktopMediaList::OnSourceTabThumbnail, media_list_,
+ source));
+ continue;
+ }
+
// Expect that DesktopCapturer to always captures frames synchronously.
// |current_frame_| may be NULL if capture failed (e.g. because window has
// been closed).
@@ -208,8 +234,8 @@ void NativeDesktopMediaList::Worker::Refresh(
ScaleDesktopFrame(current_frame_.Pass(), thumbnail_size);
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
- base::Bind(&NativeDesktopMediaList::OnSourceThumbnail,
- media_list_, i, thumbnail));
+ base::Bind(&NativeDesktopMediaList::OnSourceThumbnail, media_list_,
+ i, thumbnail));
}
}
}
@@ -233,9 +259,11 @@ void NativeDesktopMediaList::Worker::OnCaptureCompleted(
NativeDesktopMediaList::NativeDesktopMediaList(
scoped_ptr<webrtc::ScreenCapturer> screen_capturer,
- scoped_ptr<webrtc::WindowCapturer> window_capturer)
+ scoped_ptr<webrtc::WindowCapturer> window_capturer,
+ bool tab_capture_enabled)
: screen_capturer_(screen_capturer.Pass()),
window_capturer_(window_capturer.Pass()),
+ tab_capture_enabled_(tab_capture_enabled),
update_period_(base::TimeDelta::FromMilliseconds(kDefaultUpdatePeriod)),
thumbnail_size_(100, 100),
view_dialog_id_(content::DesktopMediaID::TYPE_NONE, -1),
@@ -267,7 +295,7 @@ void NativeDesktopMediaList::SetViewDialogWindowId(
void NativeDesktopMediaList::StartUpdating(DesktopMediaListObserver* observer) {
DCHECK(!observer_);
- DCHECK(screen_capturer_ || window_capturer_);
+ DCHECK(screen_capturer_ || window_capturer_ || tab_capture_enabled_);
observer_ = observer;
@@ -286,9 +314,78 @@ const DesktopMediaList::Source& NativeDesktopMediaList::GetSource(
}
void NativeDesktopMediaList::Refresh() {
+ // Get tab source list
qiangchen 2015/12/07 22:45:56 Consider moving this block to Worker::Refresh.
GeorgeZ 2015/12/09 19:36:37 Many work has to be done in UI thread here. worker
+ std::vector<SourceDescription> tab_sources;
+ if (tab_capture_enabled_) {
+ if (!GetTabSourceDescription(tab_sources)) {
+ tab_sources.clear();
+ LOG(ERROR) << "Failed to get tab sources description";
miu 2015/12/08 01:54:38 Please remove this logging statement. This operat
GeorgeZ 2015/12/09 19:36:37 Done.
+ }
+ }
+
capture_task_runner_->PostTask(
FROM_HERE, base::Bind(&Worker::Refresh, base::Unretained(worker_.get()),
- thumbnail_size_, view_dialog_id_.id));
+ thumbnail_size_, view_dialog_id_.id, tab_sources));
+}
+
+bool NativeDesktopMediaList::GetTabSourceDescription(
qiangchen 2015/12/07 22:45:56 GetTabSourceDescriptions is better.
miu 2015/12/08 01:54:38 This method should not return anything because it
GeorgeZ 2015/12/09 19:36:37 Done.
GeorgeZ 2015/12/09 19:36:37 Done.
+ std::vector<SourceDescription>& tab_sources) {
+// Only support mac, linux, windows and chrome OS, the last three use aura.
+#if !defined(OS_MACOSX) && !defined(USE_AURA)
+ return true;
+#endif
+ // Clear old favicon map.
+ tab_icon_map_.clear();
+
+ // Use to sort tabs based on their last active time stamps.
+ std::map<base::TimeTicks, SourceDescription> tab_map;
+
+ Profile* profile = ProfileManager::GetLastUsedProfileAllowedByPolicy();
+ std::vector<Browser*> browsers = FindAllTabbedBrowsersWithProfile(
+ profile, chrome::HOST_DESKTOP_TYPE_NATIVE);
+
+ for (auto browser : browsers) {
+ TabStripModel* tab_strip_model = browser->tab_strip_model();
+ DCHECK(tab_strip_model);
+
+ for (int i = 0; i < tab_strip_model->count(); i++) {
+ // Get DesktopMediaID.
+ content::WebContents* contents = tab_strip_model->GetWebContentsAt(i);
+ DesktopMediaID media_id;
+ media_id.type = DesktopMediaID::TYPE_TAB;
+ content::RenderFrameHost* const main_frame = contents->GetMainFrame();
+ DCHECK(main_frame);
+ media_id.render_process_id = main_frame->GetProcess()->GetID();
+ media_id.main_render_frame_id = main_frame->GetRoutingID();
+
+ // Get tab title.
+ base::string16 title =
+ base::UTF8ToUTF16("Chrome tab_") + contents->GetTitle();
miu 2015/12/08 01:54:38 ditto: Make this a string resource.
GeorgeZ 2015/12/09 19:36:37 Done.
+
+ // Get tab favicon.
+ favicon::FaviconDriver* favicon_driver =
+ favicon::ContentFaviconDriver::FromWebContents(contents);
+ if (favicon_driver) {
+ gfx::Image tab_icon = favicon_driver->GetFavicon();
+ int window_id =
+ (media_id.main_render_frame_id << 12) + media_id.render_process_id;
+ tab_icon_map_[window_id] =
+ CreateImageEncloseFavicon(thumbnail_size_, tab_icon);
+ }
+
+ // Get tab's last active time stamp.
+ base::TimeTicks t = contents->GetLastActiveTime();
+ tab_map.insert(std::make_pair(t, SourceDescription(media_id, title)));
+ }
+ }
+
+ // Add timely sorted tab sources into vector. Most recent one first.
+ tab_sources.clear();
+ for (auto it = tab_map.rbegin(); it != tab_map.rend(); ++it) {
+ tab_sources.push_back(it->second);
+ }
+
+ return true;
}
void NativeDesktopMediaList::OnSourcesList(
@@ -361,6 +458,27 @@ void NativeDesktopMediaList::OnSourceThumbnail(
observer_->OnSourceThumbnailChanged(index);
}
+void NativeDesktopMediaList::OnSourceTabThumbnail(SourceDescription source) {
qiangchen 2015/12/07 22:45:56 Is it possible to remove this function, and merge
GeorgeZ 2015/12/09 19:36:37 Favicon is capture and stored in a UI thead. While
+ DCHECK(source.id.type == DesktopMediaID::TYPE_TAB);
+
+ for (size_t i = 0; i < sources_.size(); ++i) {
+ if (sources_[i].id == source.id) {
+ int window_id =
+ (source.id.main_render_frame_id << 12) + source.id.render_process_id;
+ // Use favicon as thumbnail for tab.
+ if (tab_icon_map_.count(window_id)) {
+ // Only do update when there is a change to avoid flickering.
+ if (sources_[i].thumbnail.size() != tab_icon_map_[window_id].size() ||
+ sources_[i].name != source.name) {
+ sources_[i].thumbnail = tab_icon_map_[window_id];
+ observer_->OnSourceThumbnailChanged(i);
+ }
+ }
+ break;
+ }
+ }
+}
+
void NativeDesktopMediaList::OnRefreshFinished() {
BrowserThread::PostDelayedTask(
BrowserThread::UI, FROM_HERE,

Powered by Google App Engine
This is Rietveld 408576698