Chromium Code Reviews| Index: ui/snapshot/snapshot_aura.cc |
| diff --git a/ui/snapshot/snapshot_aura.cc b/ui/snapshot/snapshot_aura.cc |
| index 3e4339299a6c00345d1115d0a5e53fbc1ed42ea3..13c83dcde4e552d88113bbf6605c2f7a84061eab 100644 |
| --- a/ui/snapshot/snapshot_aura.cc |
| +++ b/ui/snapshot/snapshot_aura.cc |
| @@ -12,6 +12,7 @@ |
| #include "cc/output/copy_output_request.h" |
| #include "third_party/skia/include/core/SkBitmap.h" |
| #include "ui/aura/window.h" |
| +#include "ui/aura/window_observer.h" |
| #include "ui/compositor/compositor.h" |
| #include "ui/compositor/dip_util.h" |
| #include "ui/compositor/layer.h" |
| @@ -19,6 +20,27 @@ |
| namespace ui { |
| +namespace { |
| + |
| +class WindowCapturer : public aura::WindowObserver { |
| + public: |
| + WindowCapturer(aura::Window* window) : window_(window) { |
|
sadrul
2016/09/29 04:45:09
explicit
|
| + window_->AddObserver(this); |
| + } |
| + ~WindowCapturer() override { |
| + if (window_) |
| + window_->RemoveObserver(this); |
| + } |
| + |
| + void OnWindowDestroyed(aura::Window* window) override { window_ = nullptr; } |
| + aura::Window* window() const { return window_; } |
| + |
| + private: |
| + aura::Window* window_; |
|
sadrul
2016/09/29 04:45:09
DISALLOW_COPY_AND_ASSIGN
|
| +}; |
| + |
| +} // namespace |
| + |
| bool GrabViewSnapshot(gfx::NativeView view, |
| std::vector<unsigned char>* png_representation, |
| const gfx::Rect& snapshot_bounds) { |
| @@ -42,18 +64,49 @@ static void MakeAsyncCopyRequest( |
| window->layer()->RequestCopyOfOutput(std::move(request)); |
| } |
| +static void FinishedAsyncCopyRequest( |
| + std::unique_ptr<WindowCapturer> capturer, |
| + const gfx::Rect& source_rect, |
| + const cc::CopyOutputRequest::CopyOutputRequestCallback& callback, |
| + int retry_count, |
| + std::unique_ptr<cc::CopyOutputResult> result) { |
| + static const int kMaxRetries = 5; |
| + aura::Window* window = capturer->window(); |
| + |
| + // Retry the copy request if the previous one failed for some reason. |
| + if (window && (retry_count < kMaxRetries) && result->IsEmpty()) { |
| + MakeAsyncCopyRequest( |
|
sadrul
2016/09/29 04:45:09
Do we want to delay this request? Does the failure
|
| + window, source_rect, |
| + base::Bind(&FinishedAsyncCopyRequest, base::Passed(&capturer), |
| + source_rect, callback, retry_count + 1)); |
| + return; |
| + } |
| + |
| + callback.Run(std::move(result)); |
| +} |
| + |
| +static void MakeInitialAsyncCopyRequest( |
| + gfx::NativeWindow window, |
| + const gfx::Rect& source_rect, |
| + const cc::CopyOutputRequest::CopyOutputRequestCallback& callback) { |
| + std::unique_ptr<WindowCapturer> capturer = |
| + base::MakeUnique<WindowCapturer>(window); |
|
sadrul
2016/09/29 04:45:09
You can use aura::WindowTracker if you want instea
|
| + MakeAsyncCopyRequest( |
| + window, source_rect, |
| + base::Bind(&FinishedAsyncCopyRequest, base::Passed(&capturer), |
| + source_rect, callback, 0)); |
| +} |
| + |
| void GrabWindowSnapshotAndScaleAsync( |
| gfx::NativeWindow window, |
| const gfx::Rect& source_rect, |
| const gfx::Size& target_size, |
| scoped_refptr<base::TaskRunner> background_task_runner, |
| const GrabWindowSnapshotAsyncCallback& callback) { |
| - MakeAsyncCopyRequest(window, |
| - source_rect, |
| - base::Bind(&SnapshotAsync::ScaleCopyOutputResult, |
| - callback, |
| - target_size, |
| - background_task_runner)); |
| + MakeInitialAsyncCopyRequest( |
| + window, source_rect, |
| + base::Bind(&SnapshotAsync::ScaleCopyOutputResult, callback, target_size, |
| + background_task_runner)); |
| } |
| void GrabWindowSnapshotAsync( |
| @@ -61,11 +114,9 @@ void GrabWindowSnapshotAsync( |
| const gfx::Rect& source_rect, |
| scoped_refptr<base::TaskRunner> background_task_runner, |
| const GrabWindowSnapshotAsyncPNGCallback& callback) { |
| - MakeAsyncCopyRequest(window, |
| - source_rect, |
| - base::Bind(&SnapshotAsync::EncodeCopyOutputResult, |
| - callback, |
| - background_task_runner)); |
| + MakeInitialAsyncCopyRequest(window, source_rect, |
| + base::Bind(&SnapshotAsync::EncodeCopyOutputResult, |
| + callback, background_task_runner)); |
| } |
| void GrabViewSnapshotAsync( |