1// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "ui/snapshot/snapshot.h"
6
7#include "base/bind.h"
8#include "cc/output/copy_output_request.h"
9#include "third_party/skia/include/core/SkBitmap.h"
10#include "ui/base/android/view_android.h"
11#include "ui/base/android/window_android.h"
12#include "ui/base/android/window_android_compositor.h"
13#include "ui/gfx/display.h"
14#include "ui/gfx/geometry/point_conversions.h"
15#include "ui/gfx/geometry/rect_conversions.h"
16#include "ui/gfx/screen.h"
17#include "ui/snapshot/snapshot_async.h"
18
19namespace ui {
20
21bool GrabViewSnapshot(gfx::NativeView view,
22                      std::vector<unsigned char>* png_representation,
23                      const gfx::Rect& snapshot_bounds) {
24  return GrabWindowSnapshot(
25      view->GetWindowAndroid(), png_representation, snapshot_bounds);
26}
27
28bool GrabWindowSnapshot(gfx::NativeWindow window,
29                        std::vector<unsigned char>* png_representation,
30                        const gfx::Rect& snapshot_bounds) {
31  // Not supported in Android.  Callers should fall back to the async version.
32  return false;
33}
34
35static void MakeAsyncCopyRequest(
36    gfx::NativeWindow window,
37    const gfx::Rect& source_rect,
38    const cc::CopyOutputRequest::CopyOutputRequestCallback& callback) {
39  scoped_ptr<cc::CopyOutputRequest> request =
40      cc::CopyOutputRequest::CreateBitmapRequest(callback);
41
42  const gfx::Display& display =
43      gfx::Screen::GetNativeScreen()->GetPrimaryDisplay();
44  float device_scale_factor = display.device_scale_factor();
45  gfx::Rect source_rect_in_pixel =
46      gfx::ToEnclosingRect(gfx::ScaleRect(source_rect, device_scale_factor));
47
48  // Account for the toolbar offset.
49  gfx::Vector2dF offset = window->content_offset();
50  gfx::Rect adjusted_source_rect(gfx::ToRoundedPoint(
51      gfx::PointF(source_rect_in_pixel.x() + offset.x(),
52                  source_rect_in_pixel.y() + offset.y())),
53      source_rect_in_pixel.size());
54
55  request->set_area(adjusted_source_rect);
56  window->GetCompositor()->RequestCopyOfOutputOnRootLayer(request.Pass());
57}
58
59void GrabWindowSnapshotAndScaleAsync(
60    gfx::NativeWindow window,
61    const gfx::Rect& source_rect,
62    const gfx::Size& target_size,
63    scoped_refptr<base::TaskRunner> background_task_runner,
64    const GrabWindowSnapshotAsyncCallback& callback) {
65  MakeAsyncCopyRequest(window,
66                       source_rect,
67                       base::Bind(&SnapshotAsync::ScaleCopyOutputResult,
68                                  callback,
69                                  target_size,
70                                  background_task_runner));
71}
72
73void GrabWindowSnapshotAsync(
74    gfx::NativeWindow window,
75    const gfx::Rect& source_rect,
76    scoped_refptr<base::TaskRunner> background_task_runner,
77    const GrabWindowSnapshotAsyncPNGCallback& callback) {
78  MakeAsyncCopyRequest(window,
79                       source_rect,
80                       base::Bind(&SnapshotAsync::EncodeCopyOutputResult,
81                                  callback,
82                                  background_task_runner));
83}
84
85void GrabViewSnapshotAsync(
86    gfx::NativeView view,
87    const gfx::Rect& source_rect,
88    scoped_refptr<base::TaskRunner> background_task_runner,
89    const GrabWindowSnapshotAsyncPNGCallback& callback) {
90  GrabWindowSnapshotAsync(
91      view->GetWindowAndroid(), source_rect, background_task_runner, callback);
92}
93
94}  // namespace ui
95