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

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

Issue 1763753003: Capture chrome browser windows from internal rendering procedure for windows and linux (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 9 months 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 48c76f974e7342447080de9c5436ebe4d6a371a0..e42daa47c50b6901093b88ba0258a4dad0db2939 100644
--- a/chrome/browser/media/native_desktop_media_list.cc
+++ b/chrome/browser/media/native_desktop_media_list.cc
@@ -8,6 +8,9 @@
#include "base/strings/utf_string_conversions.h"
#include "base/threading/sequenced_worker_pool.h"
#include "chrome/browser/media/desktop_media_list_observer.h"
+#include "chrome/browser/ui/browser.h"
+#include "chrome/browser/ui/browser_list.h"
+#include "chrome/browser/ui/browser_window.h"
#include "chrome/grit/generated_resources.h"
#include "content/public/browser/browser_thread.h"
#include "media/base/video_util.h"
@@ -16,10 +19,13 @@
#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/aura/window_tree_host.h"
#include "ui/base/l10n/l10n_util.h"
+#include "ui/gfx/native_widget_types.h"
+#include "ui/snapshot/snapshot.h"
using content::BrowserThread;
-using content::DesktopMediaID;
namespace {
@@ -30,7 +36,7 @@ const int kDefaultUpdatePeriod = 1000;
// media source has changed.
uint32_t GetFrameHash(webrtc::DesktopFrame* frame) {
int data_size = frame->stride() * frame->size().height();
- return base::SuperFastHash(reinterpret_cast<char*>(frame->data()), data_size);
+ return base::Hash(reinterpret_cast<char*>(frame->data()), data_size);
}
gfx::ImageSkia ScaleDesktopFrame(scoped_ptr<webrtc::DesktopFrame> frame,
@@ -78,7 +84,8 @@ class NativeDesktopMediaList::Worker
~Worker() override;
void Refresh(const gfx::Size& thumbnail_size,
- content::DesktopMediaID::Id view_dialog_id);
+ DesktopMediaID::Id view_dialog_id,
+ NativeAuraIdMap native_aura_id_map);
private:
typedef std::map<DesktopMediaID, uint32_t> ImageHashesMap;
@@ -115,8 +122,10 @@ NativeDesktopMediaList::Worker::~Worker() {}
void NativeDesktopMediaList::Worker::Refresh(
const gfx::Size& thumbnail_size,
- content::DesktopMediaID::Id view_dialog_id) {
+ DesktopMediaID::Id view_dialog_id,
+ NativeAuraIdMap native_aura_id_map) {
std::vector<SourceDescription> sources;
+ std::vector<DesktopMediaID> aura_media_ids;
if (screen_capturer_) {
webrtc::ScreenCapturer::ScreenList screens;
@@ -145,13 +154,21 @@ void NativeDesktopMediaList::Worker::Refresh(
it != windows.end(); ++it) {
// Skip the picker dialog window.
if (it->id != view_dialog_id) {
- sources.push_back(SourceDescription(
- DesktopMediaID(DesktopMediaID::TYPE_WINDOW, it->id),
- base::UTF8ToUTF16(it->title)));
+ DesktopMediaID media_id(DesktopMediaID::TYPE_WINDOW, it->id);
+#if defined(USE_AURA)
+ // Associate aura id with native id.
+ if (native_aura_id_map.count(media_id.id)) {
+ media_id.aura_id = native_aura_id_map[media_id.id];
Sergey Ulanov 2016/03/10 00:46:07 nit: here you search the map twice, which can be a
GeorgeZ 2016/03/10 21:18:46 good point.
+ aura_media_ids.push_back(media_id);
+ }
+#endif
+ sources.push_back(
+ SourceDescription(media_id, base::UTF8ToUTF16(it->title)));
}
}
}
}
+
// Update list of windows before updating thumbnails.
BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
base::Bind(&NativeDesktopMediaList::UpdateSourcesList,
@@ -162,6 +179,7 @@ void NativeDesktopMediaList::Worker::Refresh(
// Get a thumbnail for each source.
for (size_t i = 0; i < sources.size(); ++i) {
SourceDescription& source = sources[i];
+
switch (source.id.type) {
case DesktopMediaID::TYPE_SCREEN:
if (!screen_capturer_->SelectScreen(source.id.id))
@@ -170,6 +188,11 @@ void NativeDesktopMediaList::Worker::Refresh(
break;
case DesktopMediaID::TYPE_WINDOW:
+#if defined(USE_AURA)
+ // Aura window thumbmail capture is skipped here. It will be done later.
Sergey Ulanov 2016/03/10 00:46:07 maybe also mention the UI thread. Otherwise it's n
GeorgeZ 2016/03/10 21:18:46 I will also mention it will be done asynchronously
+ if (source.id.aura_id > DesktopMediaID::kNullId)
+ continue;
+#endif
if (!window_capturer_->SelectWindow(source.id.id))
continue;
window_capturer_->Capture(webrtc::DesktopRegion());
@@ -193,17 +216,21 @@ void NativeDesktopMediaList::Worker::Refresh(
ScaleDesktopFrame(std::move(current_frame_), thumbnail_size);
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
- base::Bind(&NativeDesktopMediaList::OnSourceThumbnail, media_list_,
- i, thumbnail));
+ base::Bind(&NativeDesktopMediaList::OnSourceThumbnailCaptured,
+ media_list_, i, thumbnail));
}
}
}
image_hashes_.swap(new_image_hashes);
+ // Aura thumbnail captures have to be done in UI thread. After they are done,
+ // a refresh will be scheduled.
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
- base::Bind(&NativeDesktopMediaList::ScheduleNextRefresh, media_list_));
+ base::Bind(
+ &NativeDesktopMediaList::FinishRefreshOnUiThreadAndScheduleNext,
+ media_list_, aura_media_ids));
}
void NativeDesktopMediaList::Worker::OnCaptureCompleted(
@@ -231,12 +258,104 @@ NativeDesktopMediaList::~NativeDesktopMediaList() {
}
void NativeDesktopMediaList::Refresh() {
+ NativeAuraIdMap native_aura_id_map;
+#if defined(USE_AURA)
+ native_aura_id_map = GetBrowserNativeAuraIdMap();
+#endif
+ processed_aura_window_count_ = 0;
+ new_aura_thumbnail_hashes_.clear();
+
capture_task_runner_->PostTask(
- FROM_HERE, base::Bind(&Worker::Refresh, base::Unretained(worker_.get()),
- thumbnail_size_, view_dialog_id_.id));
+ FROM_HERE,
+ base::Bind(&Worker::Refresh, base::Unretained(worker_.get()),
+ thumbnail_size_, view_dialog_id_.id, native_aura_id_map));
}
-void NativeDesktopMediaList::OnSourceThumbnail(int index,
- const gfx::ImageSkia& image) {
+void NativeDesktopMediaList::OnSourceThumbnailCaptured(
+ int index,
+ const gfx::ImageSkia& image) {
UpdateSourceThumbnail(GetSource(index).id, image);
}
+
+void NativeDesktopMediaList::FinishRefreshOnUiThreadAndScheduleNext(
+ std::vector<DesktopMediaID> aura_ids) {
Sergey Ulanov 2016/03/10 00:46:07 use const reference for the parameter
GeorgeZ 2016/03/10 21:18:46 Done.
+ // Schedule a refresh here when there is no aura thumbanil capture or schedule
+ // a refresh in OnAuraThumbnailCaptured() after all aura thumbnails are
+ // captured.
+ total_aura_windows_ = aura_ids.size();
Sergey Ulanov 2016/03/10 00:46:07 Instead of having both processed_aura_window_count
Sergey Ulanov 2016/03/10 00:46:07 Add a DCHECK here to verify there are no pending c
GeorgeZ 2016/03/10 21:18:46 Done.
GeorgeZ 2016/03/10 21:18:46 Done.
+ if (total_aura_windows_ == 0) {
+ ScheduleNextRefresh();
+ return;
+ }
+
+ for (const auto& aura_id : aura_ids) {
+ CaptureAuraWindowThumbnail(aura_id);
+ }
+}
+
+void NativeDesktopMediaList::OnAuraThumbnailCaptured(DesktopMediaID id,
+ const gfx::Image& image) {
+ if (!image.IsEmpty()) {
+ // Only new or changed thumbnail need update.
+ new_aura_thumbnail_hashes_[id] = DesktopMediaListBase::GetImageHash(image);
+ if (!previous_aura_thumbnail_hashes_.count(id) ||
+ previous_aura_thumbnail_hashes_[id] != new_aura_thumbnail_hashes_[id]) {
+ UpdateSourceThumbnail(id, image.AsImageSkia());
+ }
+ }
+
+ // After all aura windows are processed, schedule next refresh;
+ processed_aura_window_count_++;
+ if (processed_aura_window_count_ == total_aura_windows_) {
+ swap(previous_aura_thumbnail_hashes_, new_aura_thumbnail_hashes_);
Sergey Ulanov 2016/03/10 00:46:07 nit: previous_aura_thumbnail_hashes_ = std::move
GeorgeZ 2016/03/10 21:18:46 good point.
+ ScheduleNextRefresh();
+ }
+}
+
+#if defined(USE_AURA)
+
+NativeDesktopMediaList::NativeAuraIdMap
+NativeDesktopMediaList::GetBrowserNativeAuraIdMap() {
Sergey Ulanov 2016/03/10 00:46:07 This function doesn't need to be a class member. M
GeorgeZ 2016/03/10 21:18:46 Done.
+ NativeAuraIdMap id_map;
+ for (auto* browser : *BrowserList::GetInstance()) {
+ const BrowserWindow* browser_window = browser->window();
Sergey Ulanov 2016/03/10 00:46:07 nit: I don't think you need this variable. Just us
GeorgeZ 2016/03/10 21:18:46 Done.
+ if (!browser_window)
+ continue;
+ const gfx::NativeWindow native_window = browser_window->GetNativeWindow();
Sergey Ulanov 2016/03/10 00:46:08 Suggest changing this to: aura::Window* aura_win
GeorgeZ 2016/03/10 21:18:46 Done.
+ if (!native_window)
+ continue;
+ aura::WindowTreeHost* host = native_window->GetHost();
+ if (!host)
+ continue;
+ gfx::AcceleratedWidget widget = host->GetAcceleratedWidget();
+#if defined(OS_WIN)
+ DesktopMediaID::Id native_id = reinterpret_cast<DesktopMediaID::Id>(widget);
+#else
+ DesktopMediaID::Id native_id = widget;
+#endif
+ DesktopMediaID media_id = DesktopMediaID::RegisterAuraWindow(
+ DesktopMediaID::TYPE_WINDOW, native_window);
+ id_map.insert(std::make_pair(native_id, media_id.aura_id));
Sergey Ulanov 2016/03/10 00:46:07 nit: id_map[native_id] = media_id.aura_id; That wo
GeorgeZ 2016/03/10 21:18:46 Done.
+ }
+
+ return id_map;
+}
+
+void NativeDesktopMediaList::CaptureAuraWindowThumbnail(DesktopMediaID id) {
+ gfx::NativeWindow window = DesktopMediaID::GetAuraWindowById(id);
+ if (!window) {
+ OnAuraThumbnailCaptured(id, gfx::Image());
+ return;
+ }
+
+ gfx::Rect window_rect(window->bounds().width(), window->bounds().height());
+ gfx::Rect scaled_rect = media::ComputeLetterboxRegion(
+ gfx::Rect(thumbnail_size_), window_rect.size());
+
+ ui::GrabWindowSnapshotAndScaleAsync(
+ window, window_rect, scaled_rect.size(), BrowserThread::GetBlockingPool(),
+ base::Bind(&NativeDesktopMediaList::OnAuraThumbnailCaptured,
+ weak_factory_.GetWeakPtr(), id));
+}
+
+#endif // defined(USE_AURA)

Powered by Google App Engine
This is Rietveld 408576698