Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/media/native_desktop_media_list.h" | 5 #include "chrome/browser/media/native_desktop_media_list.h" |
| 6 | 6 |
| 7 #include "base/hash.h" | 7 #include "base/hash.h" |
| 8 #include "base/strings/utf_string_conversions.h" | 8 #include "base/strings/utf_string_conversions.h" |
| 9 #include "base/threading/sequenced_worker_pool.h" | 9 #include "base/threading/sequenced_worker_pool.h" |
| 10 #include "chrome/browser/media/desktop_media_list_observer.h" | 10 #include "chrome/browser/media/desktop_media_list_observer.h" |
| 11 #include "chrome/browser/ui/browser.h" | |
| 12 #include "chrome/browser/ui/browser_list.h" | |
| 13 #include "chrome/browser/ui/browser_window.h" | |
| 11 #include "chrome/grit/generated_resources.h" | 14 #include "chrome/grit/generated_resources.h" |
| 12 #include "content/public/browser/browser_thread.h" | 15 #include "content/public/browser/browser_thread.h" |
| 13 #include "media/base/video_util.h" | 16 #include "media/base/video_util.h" |
| 14 #include "third_party/libyuv/include/libyuv/scale_argb.h" | 17 #include "third_party/libyuv/include/libyuv/scale_argb.h" |
| 15 #include "third_party/skia/include/core/SkBitmap.h" | 18 #include "third_party/skia/include/core/SkBitmap.h" |
| 16 #include "third_party/webrtc/modules/desktop_capture/desktop_frame.h" | 19 #include "third_party/webrtc/modules/desktop_capture/desktop_frame.h" |
| 17 #include "third_party/webrtc/modules/desktop_capture/screen_capturer.h" | 20 #include "third_party/webrtc/modules/desktop_capture/screen_capturer.h" |
| 18 #include "third_party/webrtc/modules/desktop_capture/window_capturer.h" | 21 #include "third_party/webrtc/modules/desktop_capture/window_capturer.h" |
| 22 #include "ui/aura/window.h" | |
| 23 #include "ui/aura/window_tree_host.h" | |
| 19 #include "ui/base/l10n/l10n_util.h" | 24 #include "ui/base/l10n/l10n_util.h" |
| 25 #include "ui/gfx/native_widget_types.h" | |
| 26 #include "ui/snapshot/snapshot.h" | |
| 20 | 27 |
| 21 using content::BrowserThread; | 28 using content::BrowserThread; |
| 22 using content::DesktopMediaID; | |
| 23 | 29 |
| 24 namespace { | 30 namespace { |
| 25 | 31 |
| 26 // Update the list every second. | 32 // Update the list every second. |
| 27 const int kDefaultUpdatePeriod = 1000; | 33 const int kDefaultUpdatePeriod = 1000; |
| 28 | 34 |
| 29 // Returns a hash of a DesktopFrame content to detect when image for a desktop | 35 // Returns a hash of a DesktopFrame content to detect when image for a desktop |
| 30 // media source has changed. | 36 // media source has changed. |
| 31 uint32_t GetFrameHash(webrtc::DesktopFrame* frame) { | 37 uint32_t GetFrameHash(webrtc::DesktopFrame* frame) { |
| 32 int data_size = frame->stride() * frame->size().height(); | 38 int data_size = frame->stride() * frame->size().height(); |
| 33 return base::SuperFastHash(reinterpret_cast<char*>(frame->data()), data_size); | 39 return base::Hash(reinterpret_cast<char*>(frame->data()), data_size); |
| 34 } | 40 } |
| 35 | 41 |
| 36 gfx::ImageSkia ScaleDesktopFrame(scoped_ptr<webrtc::DesktopFrame> frame, | 42 gfx::ImageSkia ScaleDesktopFrame(scoped_ptr<webrtc::DesktopFrame> frame, |
| 37 gfx::Size size) { | 43 gfx::Size size) { |
| 38 gfx::Rect scaled_rect = media::ComputeLetterboxRegion( | 44 gfx::Rect scaled_rect = media::ComputeLetterboxRegion( |
| 39 gfx::Rect(0, 0, size.width(), size.height()), | 45 gfx::Rect(0, 0, size.width(), size.height()), |
| 40 gfx::Size(frame->size().width(), frame->size().height())); | 46 gfx::Size(frame->size().width(), frame->size().height())); |
| 41 | 47 |
| 42 SkBitmap result; | 48 SkBitmap result; |
| 43 result.allocN32Pixels(scaled_rect.width(), scaled_rect.height(), true); | 49 result.allocN32Pixels(scaled_rect.width(), scaled_rect.height(), true); |
| (...skipping 27 matching lines...) Expand all Loading... | |
| 71 | 77 |
| 72 class NativeDesktopMediaList::Worker | 78 class NativeDesktopMediaList::Worker |
| 73 : public webrtc::DesktopCapturer::Callback { | 79 : public webrtc::DesktopCapturer::Callback { |
| 74 public: | 80 public: |
| 75 Worker(base::WeakPtr<NativeDesktopMediaList> media_list, | 81 Worker(base::WeakPtr<NativeDesktopMediaList> media_list, |
| 76 scoped_ptr<webrtc::ScreenCapturer> screen_capturer, | 82 scoped_ptr<webrtc::ScreenCapturer> screen_capturer, |
| 77 scoped_ptr<webrtc::WindowCapturer> window_capturer); | 83 scoped_ptr<webrtc::WindowCapturer> window_capturer); |
| 78 ~Worker() override; | 84 ~Worker() override; |
| 79 | 85 |
| 80 void Refresh(const gfx::Size& thumbnail_size, | 86 void Refresh(const gfx::Size& thumbnail_size, |
| 81 content::DesktopMediaID::Id view_dialog_id); | 87 DesktopMediaID::Id view_dialog_id, |
| 88 NativeAuraIdMap native_aura_id_map); | |
| 82 | 89 |
| 83 private: | 90 private: |
| 84 typedef std::map<DesktopMediaID, uint32_t> ImageHashesMap; | 91 typedef std::map<DesktopMediaID, uint32_t> ImageHashesMap; |
| 85 | 92 |
| 86 // webrtc::DesktopCapturer::Callback interface. | 93 // webrtc::DesktopCapturer::Callback interface. |
| 87 void OnCaptureCompleted(webrtc::DesktopFrame* frame) override; | 94 void OnCaptureCompleted(webrtc::DesktopFrame* frame) override; |
| 88 | 95 |
| 89 base::WeakPtr<NativeDesktopMediaList> media_list_; | 96 base::WeakPtr<NativeDesktopMediaList> media_list_; |
| 90 | 97 |
| 91 scoped_ptr<webrtc::ScreenCapturer> screen_capturer_; | 98 scoped_ptr<webrtc::ScreenCapturer> screen_capturer_; |
| (...skipping 16 matching lines...) Expand all Loading... | |
| 108 if (screen_capturer_) | 115 if (screen_capturer_) |
| 109 screen_capturer_->Start(this); | 116 screen_capturer_->Start(this); |
| 110 if (window_capturer_) | 117 if (window_capturer_) |
| 111 window_capturer_->Start(this); | 118 window_capturer_->Start(this); |
| 112 } | 119 } |
| 113 | 120 |
| 114 NativeDesktopMediaList::Worker::~Worker() {} | 121 NativeDesktopMediaList::Worker::~Worker() {} |
| 115 | 122 |
| 116 void NativeDesktopMediaList::Worker::Refresh( | 123 void NativeDesktopMediaList::Worker::Refresh( |
| 117 const gfx::Size& thumbnail_size, | 124 const gfx::Size& thumbnail_size, |
| 118 content::DesktopMediaID::Id view_dialog_id) { | 125 DesktopMediaID::Id view_dialog_id, |
| 126 NativeAuraIdMap native_aura_id_map) { | |
| 119 std::vector<SourceDescription> sources; | 127 std::vector<SourceDescription> sources; |
| 128 std::vector<DesktopMediaID> aura_media_ids; | |
| 120 | 129 |
| 121 if (screen_capturer_) { | 130 if (screen_capturer_) { |
| 122 webrtc::ScreenCapturer::ScreenList screens; | 131 webrtc::ScreenCapturer::ScreenList screens; |
| 123 if (screen_capturer_->GetScreenList(&screens)) { | 132 if (screen_capturer_->GetScreenList(&screens)) { |
| 124 bool mutiple_screens = screens.size() > 1; | 133 bool mutiple_screens = screens.size() > 1; |
| 125 base::string16 title; | 134 base::string16 title; |
| 126 for (size_t i = 0; i < screens.size(); ++i) { | 135 for (size_t i = 0; i < screens.size(); ++i) { |
| 127 if (mutiple_screens) { | 136 if (mutiple_screens) { |
| 128 title = l10n_util::GetStringFUTF16Int( | 137 title = l10n_util::GetStringFUTF16Int( |
| 129 IDS_DESKTOP_MEDIA_PICKER_MULTIPLE_SCREEN_NAME, | 138 IDS_DESKTOP_MEDIA_PICKER_MULTIPLE_SCREEN_NAME, |
| 130 static_cast<int>(i + 1)); | 139 static_cast<int>(i + 1)); |
| 131 } else { | 140 } else { |
| 132 title = l10n_util::GetStringUTF16( | 141 title = l10n_util::GetStringUTF16( |
| 133 IDS_DESKTOP_MEDIA_PICKER_SINGLE_SCREEN_NAME); | 142 IDS_DESKTOP_MEDIA_PICKER_SINGLE_SCREEN_NAME); |
| 134 } | 143 } |
| 135 sources.push_back(SourceDescription(DesktopMediaID( | 144 sources.push_back(SourceDescription(DesktopMediaID( |
| 136 DesktopMediaID::TYPE_SCREEN, screens[i].id), title)); | 145 DesktopMediaID::TYPE_SCREEN, screens[i].id), title)); |
| 137 } | 146 } |
| 138 } | 147 } |
| 139 } | 148 } |
| 140 | 149 |
| 141 if (window_capturer_) { | 150 if (window_capturer_) { |
| 142 webrtc::WindowCapturer::WindowList windows; | 151 webrtc::WindowCapturer::WindowList windows; |
| 143 if (window_capturer_->GetWindowList(&windows)) { | 152 if (window_capturer_->GetWindowList(&windows)) { |
| 144 for (webrtc::WindowCapturer::WindowList::iterator it = windows.begin(); | 153 for (webrtc::WindowCapturer::WindowList::iterator it = windows.begin(); |
| 145 it != windows.end(); ++it) { | 154 it != windows.end(); ++it) { |
| 146 // Skip the picker dialog window. | 155 // Skip the picker dialog window. |
| 147 if (it->id != view_dialog_id) { | 156 if (it->id != view_dialog_id) { |
| 148 sources.push_back(SourceDescription( | 157 DesktopMediaID media_id(DesktopMediaID::TYPE_WINDOW, it->id); |
| 149 DesktopMediaID(DesktopMediaID::TYPE_WINDOW, it->id), | 158 #if defined(USE_AURA) |
| 150 base::UTF8ToUTF16(it->title))); | 159 // Associate aura id with native id. |
| 160 if (native_aura_id_map.count(media_id.id)) { | |
| 161 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.
| |
| 162 aura_media_ids.push_back(media_id); | |
| 163 } | |
| 164 #endif | |
| 165 sources.push_back( | |
| 166 SourceDescription(media_id, base::UTF8ToUTF16(it->title))); | |
| 151 } | 167 } |
| 152 } | 168 } |
| 153 } | 169 } |
| 154 } | 170 } |
| 171 | |
| 155 // Update list of windows before updating thumbnails. | 172 // Update list of windows before updating thumbnails. |
| 156 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, | 173 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, |
| 157 base::Bind(&NativeDesktopMediaList::UpdateSourcesList, | 174 base::Bind(&NativeDesktopMediaList::UpdateSourcesList, |
| 158 media_list_, sources)); | 175 media_list_, sources)); |
| 159 | 176 |
| 160 ImageHashesMap new_image_hashes; | 177 ImageHashesMap new_image_hashes; |
| 161 | 178 |
| 162 // Get a thumbnail for each source. | 179 // Get a thumbnail for each source. |
| 163 for (size_t i = 0; i < sources.size(); ++i) { | 180 for (size_t i = 0; i < sources.size(); ++i) { |
| 164 SourceDescription& source = sources[i]; | 181 SourceDescription& source = sources[i]; |
| 182 | |
| 165 switch (source.id.type) { | 183 switch (source.id.type) { |
| 166 case DesktopMediaID::TYPE_SCREEN: | 184 case DesktopMediaID::TYPE_SCREEN: |
| 167 if (!screen_capturer_->SelectScreen(source.id.id)) | 185 if (!screen_capturer_->SelectScreen(source.id.id)) |
| 168 continue; | 186 continue; |
| 169 screen_capturer_->Capture(webrtc::DesktopRegion()); | 187 screen_capturer_->Capture(webrtc::DesktopRegion()); |
| 170 break; | 188 break; |
| 171 | 189 |
| 172 case DesktopMediaID::TYPE_WINDOW: | 190 case DesktopMediaID::TYPE_WINDOW: |
| 191 #if defined(USE_AURA) | |
| 192 // 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
| |
| 193 if (source.id.aura_id > DesktopMediaID::kNullId) | |
| 194 continue; | |
| 195 #endif | |
| 173 if (!window_capturer_->SelectWindow(source.id.id)) | 196 if (!window_capturer_->SelectWindow(source.id.id)) |
| 174 continue; | 197 continue; |
| 175 window_capturer_->Capture(webrtc::DesktopRegion()); | 198 window_capturer_->Capture(webrtc::DesktopRegion()); |
| 176 break; | 199 break; |
| 177 | 200 |
| 178 default: | 201 default: |
| 179 NOTREACHED(); | 202 NOTREACHED(); |
| 180 } | 203 } |
| 181 | 204 |
| 182 // Expect that DesktopCapturer to always captures frames synchronously. | 205 // Expect that DesktopCapturer to always captures frames synchronously. |
| 183 // |current_frame_| may be NULL if capture failed (e.g. because window has | 206 // |current_frame_| may be NULL if capture failed (e.g. because window has |
| 184 // been closed). | 207 // been closed). |
| 185 if (current_frame_) { | 208 if (current_frame_) { |
| 186 uint32_t frame_hash = GetFrameHash(current_frame_.get()); | 209 uint32_t frame_hash = GetFrameHash(current_frame_.get()); |
| 187 new_image_hashes[source.id] = frame_hash; | 210 new_image_hashes[source.id] = frame_hash; |
| 188 | 211 |
| 189 // Scale the image only if it has changed. | 212 // Scale the image only if it has changed. |
| 190 ImageHashesMap::iterator it = image_hashes_.find(source.id); | 213 ImageHashesMap::iterator it = image_hashes_.find(source.id); |
| 191 if (it == image_hashes_.end() || it->second != frame_hash) { | 214 if (it == image_hashes_.end() || it->second != frame_hash) { |
| 192 gfx::ImageSkia thumbnail = | 215 gfx::ImageSkia thumbnail = |
| 193 ScaleDesktopFrame(std::move(current_frame_), thumbnail_size); | 216 ScaleDesktopFrame(std::move(current_frame_), thumbnail_size); |
| 194 BrowserThread::PostTask( | 217 BrowserThread::PostTask( |
| 195 BrowserThread::UI, FROM_HERE, | 218 BrowserThread::UI, FROM_HERE, |
| 196 base::Bind(&NativeDesktopMediaList::OnSourceThumbnail, media_list_, | 219 base::Bind(&NativeDesktopMediaList::OnSourceThumbnailCaptured, |
| 197 i, thumbnail)); | 220 media_list_, i, thumbnail)); |
| 198 } | 221 } |
| 199 } | 222 } |
| 200 } | 223 } |
| 201 | 224 |
| 202 image_hashes_.swap(new_image_hashes); | 225 image_hashes_.swap(new_image_hashes); |
| 203 | 226 |
| 227 // Aura thumbnail captures have to be done in UI thread. After they are done, | |
| 228 // a refresh will be scheduled. | |
| 204 BrowserThread::PostTask( | 229 BrowserThread::PostTask( |
| 205 BrowserThread::UI, FROM_HERE, | 230 BrowserThread::UI, FROM_HERE, |
| 206 base::Bind(&NativeDesktopMediaList::ScheduleNextRefresh, media_list_)); | 231 base::Bind( |
| 232 &NativeDesktopMediaList::FinishRefreshOnUiThreadAndScheduleNext, | |
| 233 media_list_, aura_media_ids)); | |
| 207 } | 234 } |
| 208 | 235 |
| 209 void NativeDesktopMediaList::Worker::OnCaptureCompleted( | 236 void NativeDesktopMediaList::Worker::OnCaptureCompleted( |
| 210 webrtc::DesktopFrame* frame) { | 237 webrtc::DesktopFrame* frame) { |
| 211 current_frame_.reset(frame); | 238 current_frame_.reset(frame); |
| 212 } | 239 } |
| 213 | 240 |
| 214 NativeDesktopMediaList::NativeDesktopMediaList( | 241 NativeDesktopMediaList::NativeDesktopMediaList( |
| 215 scoped_ptr<webrtc::ScreenCapturer> screen_capturer, | 242 scoped_ptr<webrtc::ScreenCapturer> screen_capturer, |
| 216 scoped_ptr<webrtc::WindowCapturer> window_capturer) | 243 scoped_ptr<webrtc::WindowCapturer> window_capturer) |
| 217 : DesktopMediaListBase( | 244 : DesktopMediaListBase( |
| 218 base::TimeDelta::FromMilliseconds(kDefaultUpdatePeriod)), | 245 base::TimeDelta::FromMilliseconds(kDefaultUpdatePeriod)), |
| 219 weak_factory_(this) { | 246 weak_factory_(this) { |
| 220 base::SequencedWorkerPool* worker_pool = BrowserThread::GetBlockingPool(); | 247 base::SequencedWorkerPool* worker_pool = BrowserThread::GetBlockingPool(); |
| 221 capture_task_runner_ = worker_pool->GetSequencedTaskRunner( | 248 capture_task_runner_ = worker_pool->GetSequencedTaskRunner( |
| 222 worker_pool->GetSequenceToken()); | 249 worker_pool->GetSequenceToken()); |
| 223 | 250 |
| 224 worker_.reset(new Worker(weak_factory_.GetWeakPtr(), | 251 worker_.reset(new Worker(weak_factory_.GetWeakPtr(), |
| 225 std::move(screen_capturer), | 252 std::move(screen_capturer), |
| 226 std::move(window_capturer))); | 253 std::move(window_capturer))); |
| 227 } | 254 } |
| 228 | 255 |
| 229 NativeDesktopMediaList::~NativeDesktopMediaList() { | 256 NativeDesktopMediaList::~NativeDesktopMediaList() { |
| 230 capture_task_runner_->DeleteSoon(FROM_HERE, worker_.release()); | 257 capture_task_runner_->DeleteSoon(FROM_HERE, worker_.release()); |
| 231 } | 258 } |
| 232 | 259 |
| 233 void NativeDesktopMediaList::Refresh() { | 260 void NativeDesktopMediaList::Refresh() { |
| 261 NativeAuraIdMap native_aura_id_map; | |
| 262 #if defined(USE_AURA) | |
| 263 native_aura_id_map = GetBrowserNativeAuraIdMap(); | |
| 264 #endif | |
| 265 processed_aura_window_count_ = 0; | |
| 266 new_aura_thumbnail_hashes_.clear(); | |
| 267 | |
| 234 capture_task_runner_->PostTask( | 268 capture_task_runner_->PostTask( |
| 235 FROM_HERE, base::Bind(&Worker::Refresh, base::Unretained(worker_.get()), | 269 FROM_HERE, |
| 236 thumbnail_size_, view_dialog_id_.id)); | 270 base::Bind(&Worker::Refresh, base::Unretained(worker_.get()), |
| 271 thumbnail_size_, view_dialog_id_.id, native_aura_id_map)); | |
| 237 } | 272 } |
| 238 | 273 |
| 239 void NativeDesktopMediaList::OnSourceThumbnail(int index, | 274 void NativeDesktopMediaList::OnSourceThumbnailCaptured( |
| 240 const gfx::ImageSkia& image) { | 275 int index, |
| 276 const gfx::ImageSkia& image) { | |
| 241 UpdateSourceThumbnail(GetSource(index).id, image); | 277 UpdateSourceThumbnail(GetSource(index).id, image); |
| 242 } | 278 } |
| 279 | |
| 280 void NativeDesktopMediaList::FinishRefreshOnUiThreadAndScheduleNext( | |
| 281 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.
| |
| 282 // Schedule a refresh here when there is no aura thumbanil capture or schedule | |
| 283 // a refresh in OnAuraThumbnailCaptured() after all aura thumbnails are | |
| 284 // captured. | |
| 285 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.
| |
| 286 if (total_aura_windows_ == 0) { | |
| 287 ScheduleNextRefresh(); | |
| 288 return; | |
| 289 } | |
| 290 | |
| 291 for (const auto& aura_id : aura_ids) { | |
| 292 CaptureAuraWindowThumbnail(aura_id); | |
| 293 } | |
| 294 } | |
| 295 | |
| 296 void NativeDesktopMediaList::OnAuraThumbnailCaptured(DesktopMediaID id, | |
| 297 const gfx::Image& image) { | |
| 298 if (!image.IsEmpty()) { | |
| 299 // Only new or changed thumbnail need update. | |
| 300 new_aura_thumbnail_hashes_[id] = DesktopMediaListBase::GetImageHash(image); | |
| 301 if (!previous_aura_thumbnail_hashes_.count(id) || | |
| 302 previous_aura_thumbnail_hashes_[id] != new_aura_thumbnail_hashes_[id]) { | |
| 303 UpdateSourceThumbnail(id, image.AsImageSkia()); | |
| 304 } | |
| 305 } | |
| 306 | |
| 307 // After all aura windows are processed, schedule next refresh; | |
| 308 processed_aura_window_count_++; | |
| 309 if (processed_aura_window_count_ == total_aura_windows_) { | |
| 310 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.
| |
| 311 ScheduleNextRefresh(); | |
| 312 } | |
| 313 } | |
| 314 | |
| 315 #if defined(USE_AURA) | |
| 316 | |
| 317 NativeDesktopMediaList::NativeAuraIdMap | |
| 318 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.
| |
| 319 NativeAuraIdMap id_map; | |
| 320 for (auto* browser : *BrowserList::GetInstance()) { | |
| 321 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.
| |
| 322 if (!browser_window) | |
| 323 continue; | |
| 324 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.
| |
| 325 if (!native_window) | |
| 326 continue; | |
| 327 aura::WindowTreeHost* host = native_window->GetHost(); | |
| 328 if (!host) | |
| 329 continue; | |
| 330 gfx::AcceleratedWidget widget = host->GetAcceleratedWidget(); | |
| 331 #if defined(OS_WIN) | |
| 332 DesktopMediaID::Id native_id = reinterpret_cast<DesktopMediaID::Id>(widget); | |
| 333 #else | |
| 334 DesktopMediaID::Id native_id = widget; | |
| 335 #endif | |
| 336 DesktopMediaID media_id = DesktopMediaID::RegisterAuraWindow( | |
| 337 DesktopMediaID::TYPE_WINDOW, native_window); | |
| 338 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.
| |
| 339 } | |
| 340 | |
| 341 return id_map; | |
| 342 } | |
| 343 | |
| 344 void NativeDesktopMediaList::CaptureAuraWindowThumbnail(DesktopMediaID id) { | |
| 345 gfx::NativeWindow window = DesktopMediaID::GetAuraWindowById(id); | |
| 346 if (!window) { | |
| 347 OnAuraThumbnailCaptured(id, gfx::Image()); | |
| 348 return; | |
| 349 } | |
| 350 | |
| 351 gfx::Rect window_rect(window->bounds().width(), window->bounds().height()); | |
| 352 gfx::Rect scaled_rect = media::ComputeLetterboxRegion( | |
| 353 gfx::Rect(thumbnail_size_), window_rect.size()); | |
| 354 | |
| 355 ui::GrabWindowSnapshotAndScaleAsync( | |
| 356 window, window_rect, scaled_rect.size(), BrowserThread::GetBlockingPool(), | |
| 357 base::Bind(&NativeDesktopMediaList::OnAuraThumbnailCaptured, | |
| 358 weak_factory_.GetWeakPtr(), id)); | |
| 359 } | |
| 360 | |
| 361 #endif // defined(USE_AURA) | |
| OLD | NEW |