From c9bc8f1104914818e054b7f9f2b928ce78bc9dd8 Mon Sep 17 00:00:00 2001 From: "bajones@chromium.org" Date: Sat, 15 Dec 2012 22:20:09 +0000 Subject: [PATCH] Implemented GetWindowSnapshot on RenderViewImpl This necessitated the relocation of the previous chrome::GrabWindowSnapshot code to ui/snapshot, which has been turned into it's own component to avoid circular dependencies with aura. A new variant of GrabWindowSnapshot, GrabViewSnapshot, has been added as well to facilitate easier usage by views. chrome::GrabWindowSnapshotForUser was left in place to accomodate existing calls to the API, but now calls up to the ui/snapshot code. This is a subset of the prior CL 11362023, which has been broken apart to facilitate easier reviews BUG=157479 Review URL: https://chromiumcodereview.appspot.com/11399002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@173329 0039d316-1c4b-4281-b951-d872f2087c98 --- .../ui/window_snapshot/window_snapshot.cc | 7 +- .../ui/window_snapshot/window_snapshot.h | 14 +--- chrome/chrome_browser_ui.gypi | 6 +- chrome/chrome_tests_unit.gypi | 1 - chrome/test/base/ui_test_utils.cc | 4 +- content/DEPS | 1 + .../renderer_host/render_view_host_impl.cc | 25 +++++++ .../renderer_host/render_view_host_impl.h | 1 + content/common/view_messages.h | 10 +++ content/content_browser.gypi | 1 + content/renderer/render_view_impl.cc | 17 +++++ content/renderer/render_view_impl.h | 16 +++++ ui/snapshot/DEPS | 7 ++ ui/snapshot/snapshot.gyp | 65 +++++++++++++++++++ ui/snapshot/snapshot.h | 34 ++++++++++ ui/snapshot/snapshot_android.cc | 25 +++++++ .../snapshot/snapshot_aura.cc | 14 ++-- ui/snapshot/snapshot_export.h | 32 +++++++++ .../snapshot/snapshot_gtk.cc | 19 ++++-- ui/snapshot/snapshot_ios.mm | 25 +++++++ .../snapshot/snapshot_mac.mm | 47 +++++++++----- .../snapshot/snapshot_mac_unittest.mm | 8 +-- .../snapshot/snapshot_win.cc | 14 ++-- 23 files changed, 330 insertions(+), 63 deletions(-) create mode 100644 ui/snapshot/DEPS create mode 100644 ui/snapshot/snapshot.gyp create mode 100644 ui/snapshot/snapshot.h create mode 100644 ui/snapshot/snapshot_android.cc rename chrome/browser/ui/window_snapshot/window_snapshot_aura.cc => ui/snapshot/snapshot_aura.cc (85%) create mode 100644 ui/snapshot/snapshot_export.h rename chrome/browser/ui/window_snapshot/window_snapshot_gtk.cc => ui/snapshot/snapshot_gtk.cc (84%) create mode 100644 ui/snapshot/snapshot_ios.mm rename chrome/browser/ui/window_snapshot/window_snapshot_mac.mm => ui/snapshot/snapshot_mac.mm (62%) rename chrome/browser/ui/window_snapshot/window_snapshot_mac_unittest.mm => ui/snapshot/snapshot_mac_unittest.mm (92%) rename chrome/browser/ui/window_snapshot/window_snapshot_win.cc => ui/snapshot/snapshot_win.cc (92%) diff --git a/chrome/browser/ui/window_snapshot/window_snapshot.cc b/chrome/browser/ui/window_snapshot/window_snapshot.cc index ed0419745fa222..2b338f4178b7c6 100644 --- a/chrome/browser/ui/window_snapshot/window_snapshot.cc +++ b/chrome/browser/ui/window_snapshot/window_snapshot.cc @@ -7,6 +7,7 @@ #include "chrome/browser/browser_process.h" #include "chrome/browser/prefs/pref_service.h" #include "chrome/common/pref_names.h" +#include "ui/snapshot/snapshot.h" namespace chrome { @@ -16,12 +17,12 @@ bool GrabWindowSnapshotForUser( const gfx::Rect& snapshot_bounds) { if (g_browser_process->local_state()->GetBoolean(prefs::kDisableScreenshots)) return false; - return internal::GrabWindowSnapshot(window, png_representation, - snapshot_bounds); + return ui::GrabWindowSnapshot(window, png_representation, + snapshot_bounds); } void RegisterScreenshotPrefs(PrefService* service) { service->RegisterBooleanPref(prefs::kDisableScreenshots, false); } -} // namespace browser +} // namespace chrome diff --git a/chrome/browser/ui/window_snapshot/window_snapshot.h b/chrome/browser/ui/window_snapshot/window_snapshot.h index f4f6f893c65e0d..3259983cfcdd27 100644 --- a/chrome/browser/ui/window_snapshot/window_snapshot.h +++ b/chrome/browser/ui/window_snapshot/window_snapshot.h @@ -25,25 +25,13 @@ void RegisterScreenshotPrefs(PrefService* service); // the primary monitor. This takes into account calling user context (ie. checks // policy settings if taking screenshots is allowed), and is intended to be used // by browser code. If you need to take a screenshot for debugging purposes, -// consider using GrabWindowSnapshot. +// consider using ui::GrabWindowSnapshot. // Returns true if the operation is successful (ie. permitted). bool GrabWindowSnapshotForUser( gfx::NativeWindow window, std::vector* png_representation, const gfx::Rect& snapshot_bounds); -namespace internal { - -// Like GrabWindowSnapshotForUser, but does not perform additional security -// checks - just grabs a snapshot. This is intended to be used for debugging -// purposes where no BrowserProcess instance is available (ie. tests). -// DO NOT use in a result of user action. -bool GrabWindowSnapshot( - gfx::NativeWindow window, - std::vector* png_representation, - const gfx::Rect& snapshot_bounds); - -} // namespace internal } // namespace chrome #endif // CHROME_BROWSER_UI_WINDOW_SNAPSHOT_WINDOW_SNAPSHOT_H_ diff --git a/chrome/chrome_browser_ui.gypi b/chrome/chrome_browser_ui.gypi index 712073f6e87f3c..e1a3c330b1b8c7 100644 --- a/chrome/chrome_browser_ui.gypi +++ b/chrome/chrome_browser_ui.gypi @@ -50,6 +50,7 @@ '../third_party/zlib/zlib.gyp:zlib', '../ui/base/strings/ui_strings.gyp:ui_strings', '../ui/native_theme/native_theme.gyp:native_theme', + '../ui/snapshot/snapshot.gyp:snapshot', '../ui/ui.gyp:ui', '../ui/ui.gyp:ui_resources', '../webkit/support/webkit_support.gyp:user_agent', @@ -2104,10 +2105,6 @@ 'browser/ui/window_sizer/window_sizer_win.cc', 'browser/ui/window_snapshot/window_snapshot.cc', 'browser/ui/window_snapshot/window_snapshot.h', - 'browser/ui/window_snapshot/window_snapshot_aura.cc', - 'browser/ui/window_snapshot/window_snapshot_gtk.cc', - 'browser/ui/window_snapshot/window_snapshot_mac.mm', - 'browser/ui/window_snapshot/window_snapshot_win.cc', 'browser/ui/zoom/zoom_controller.cc', 'browser/ui/zoom/zoom_controller.h', 'browser/ui/zoom/zoom_observer.h', @@ -2351,7 +2348,6 @@ ['exclude', '^browser/ui/views/user_data_dir_dialog_view.cc'], ['exclude', '^browser/ui/webui/help/version_updater_win.cc'], ['exclude', '^browser/ui/window_sizer/window_sizer_win.cc'], - ['exclude', '^browser/ui/window_snapshot/window_snapshot_win.cc'], # TODO: (stevenjb/beng): Find a home for these. ['include', '^browser/ui/views/simple_message_box_views.cc'], ['include', '^browser/ui/webui/certificate_viewer_webui.cc'], diff --git a/chrome/chrome_tests_unit.gypi b/chrome/chrome_tests_unit.gypi index 4d00cac5bf3c19..88e2e7c2ea04f0 100644 --- a/chrome/chrome_tests_unit.gypi +++ b/chrome/chrome_tests_unit.gypi @@ -1407,7 +1407,6 @@ 'browser/ui/window_sizer/window_sizer_ash_unittest.cc', 'browser/ui/window_sizer/window_sizer_common_unittest.cc', 'browser/ui/window_sizer/window_sizer_unittest.cc', - 'browser/ui/window_snapshot/window_snapshot_mac_unittest.mm', 'browser/ui/zoom/zoom_controller_unittest.cc', 'browser/chrome_to_mobile_service_unittest.cc', 'browser/user_style_sheet_watcher_unittest.cc', diff --git a/chrome/test/base/ui_test_utils.cc b/chrome/test/base/ui_test_utils.cc index d2d6d5301d1ffc..932cafa9b734c9 100644 --- a/chrome/test/base/ui_test_utils.cc +++ b/chrome/test/base/ui_test_utils.cc @@ -45,7 +45,6 @@ #include "chrome/browser/ui/host_desktop.h" #include "chrome/browser/ui/omnibox/location_bar.h" #include "chrome/browser/ui/omnibox/omnibox_view.h" -#include "chrome/browser/ui/window_snapshot/window_snapshot.h" #include "chrome/common/chrome_notification_types.h" #include "chrome/common/chrome_paths.h" #include "chrome/common/pref_names.h" @@ -73,6 +72,7 @@ #include "third_party/skia/include/core/SkBitmap.h" #include "third_party/skia/include/core/SkColor.h" #include "ui/gfx/size.h" +#include "ui/snapshot/snapshot.h" #include "ui/ui_controls/ui_controls.h" #if defined(USE_AURA) @@ -634,7 +634,7 @@ bool SaveScreenSnapshotToDirectory(const FilePath& directory, std::vector png_data; gfx::Rect bounds( gfx::Size(rect.right - rect.left, rect.bottom - rect.top)); - if (chrome::internal::GrabWindowSnapshot(NULL, &png_data, bounds) && + if (ui::GrabWindowSnapshot(NULL, &png_data, bounds) && png_data.size() <= INT_MAX) { int bytes = static_cast(png_data.size()); int written = file_util::WriteFile( diff --git a/content/DEPS b/content/DEPS index 09dd65b01dab4e..0362df1fd7aeed 100644 --- a/content/DEPS +++ b/content/DEPS @@ -57,6 +57,7 @@ include_rules = [ "+ui/gfx", "+ui/gl", "+ui/native_theme", + "+ui/snapshot", "+ui/surface", # Content knows about grd files, but the specifics of how to get a resource # given its id is left to the embedder. diff --git a/content/browser/renderer_host/render_view_host_impl.cc b/content/browser/renderer_host/render_view_host_impl.cc index a578297c1c388c..b49410c1bcf7b4 100644 --- a/content/browser/renderer_host/render_view_host_impl.cc +++ b/content/browser/renderer_host/render_view_host_impl.cc @@ -65,6 +65,7 @@ #include "ui/base/dialogs/selected_file_info.h" #include "ui/gfx/image/image_skia.h" #include "ui/gfx/native_widget_types.h" +#include "ui/snapshot/snapshot.h" #include "webkit/fileapi/isolated_context.h" #include "webkit/glue/webdropdata.h" #include "webkit/glue/webkit_glue.h" @@ -1020,6 +1021,7 @@ bool RenderViewHostImpl::OnMessageReceived(const IPC::Message& msg) { IPC_MESSAGE_HANDLER(ViewHostMsg_ScriptEvalResponse, OnScriptEvalResponse) IPC_MESSAGE_HANDLER(ViewHostMsg_DidZoomURL, OnDidZoomURL) IPC_MESSAGE_HANDLER(ViewHostMsg_MediaNotification, OnMediaNotification) + IPC_MESSAGE_HANDLER(ViewHostMsg_GetWindowSnapshot, OnGetWindowSnapshot) #if defined(OS_ANDROID) IPC_MESSAGE_HANDLER(ViewHostMsg_StartContentIntent, OnStartContentIntent) IPC_MESSAGE_HANDLER(ViewHostMsg_DidChangeBodyBackgroundColor, @@ -2058,4 +2060,27 @@ void RenderViewHostImpl::ClearPowerSaveBlockers() { STLDeleteValues(&power_save_blockers_); } +void RenderViewHostImpl::OnGetWindowSnapshot(const int snapshot_id) { + std::vector png; + + // This feature is behind the kEnableGpuBenchmarking command line switch + // because it poses security concerns and should only be used for testing. + const CommandLine& command_line = *CommandLine::ForCurrentProcess(); + if (command_line.HasSwitch(switches::kEnableGpuBenchmarking)) { + gfx::Rect view_bounds = GetView()->GetViewBounds(); + gfx::Rect snapshot_bounds(view_bounds.size()); + gfx::Size snapshot_size = snapshot_bounds.size(); + + if (ui::GrabViewSnapshot(GetView()->GetNativeView(), + &png, snapshot_bounds)) { + Send(new ViewMsg_WindowSnapshotCompleted( + GetRoutingID(), snapshot_id, snapshot_size, png)); + return; + } + } + + Send(new ViewMsg_WindowSnapshotCompleted( + GetRoutingID(), snapshot_id, gfx::Size(), png)); +} + } // namespace content diff --git a/content/browser/renderer_host/render_view_host_impl.h b/content/browser/renderer_host/render_view_host_impl.h index 76942f2523d2ee..6aee5890ebe41c 100644 --- a/content/browser/renderer_host/render_view_host_impl.h +++ b/content/browser/renderer_host/render_view_host_impl.h @@ -571,6 +571,7 @@ class CONTENT_EXPORT RenderViewHostImpl void OnDomOperationResponse(const std::string& json_string, int automation_id); void OnFrameTreeUpdated(const std::string& frame_tree); + void OnGetWindowSnapshot(const int snapshot_id); #if defined(OS_MACOSX) || defined(OS_ANDROID) void OnMsgShowPopup(const ViewHostMsg_ShowPopup_Params& params); diff --git a/content/common/view_messages.h b/content/common/view_messages.h index d1e322e9efe091..d2464e991c7e77 100644 --- a/content/common/view_messages.h +++ b/content/common/view_messages.h @@ -1447,6 +1447,12 @@ IPC_MESSAGE_ROUTED1(ViewMsg_SelectPopupMenuItem, IPC_MESSAGE_ROUTED1(ViewMsg_ReleaseDisambiguationPopupDIB, TransportDIB::Handle /* DIB handle */) +// Notifies the renderer that a snapshot has been retrieved. +IPC_MESSAGE_ROUTED3(ViewMsg_WindowSnapshotCompleted, + int /* snapshot_id */, + gfx::Size /* size */, + std::vector /* png */) + // ----------------------------------------------------------------------------- // Messages sent from the renderer to the browser. @@ -1946,6 +1952,10 @@ IPC_MESSAGE_ROUTED3(ViewHostMsg_WebUISend, std::string /* message */, base::ListValue /* args */) +// Requests a snapshot of the given window. +IPC_MESSAGE_ROUTED1(ViewHostMsg_GetWindowSnapshot, + int /* snapshot_id */) + // A renderer sends this to the browser process when it wants to create a ppapi // plugin. The browser will create the plugin process if necessary, and will // return a handle to the channel on success. diff --git a/content/content_browser.gypi b/content/content_browser.gypi index 68177664a73595..b2a7aa83b9b5dc 100644 --- a/content/content_browser.gypi +++ b/content/content_browser.gypi @@ -22,6 +22,7 @@ '../net/net.gyp:net', '../skia/skia.gyp:skia', '../third_party/zlib/zlib.gyp:zlib', + '../ui/snapshot/snapshot.gyp:snapshot', '../ui/ui.gyp:ui', '../ui/ui.gyp:ui_resources', ], diff --git a/content/renderer/render_view_impl.cc b/content/renderer/render_view_impl.cc index bb8bd794ca92a2..fd18ad12f38bd5 100644 --- a/content/renderer/render_view_impl.cc +++ b/content/renderer/render_view_impl.cc @@ -600,6 +600,7 @@ RenderViewImpl::RenderViewImpl(RenderViewImplParams* params) #endif session_storage_namespace_id_(params->session_storage_namespace_id), handling_select_range_(false), + next_snapshot_id_(0), #if defined(OS_WIN) focused_plugin_id_(-1), #endif @@ -1043,6 +1044,8 @@ bool RenderViewImpl::OnMessageReceived(const IPC::Message& message) { #endif IPC_MESSAGE_HANDLER(ViewMsg_ReleaseDisambiguationPopupDIB, OnReleaseDisambiguationPopupDIB) + IPC_MESSAGE_HANDLER(ViewMsg_WindowSnapshotCompleted, + OnWindowSnapshotCompleted) // Have the super handle all other messages. IPC_MESSAGE_UNHANDLED(handled = RenderWidget::OnMessageReceived(message)) @@ -1766,6 +1769,20 @@ bool RenderViewImpl::SendAndRunNestedMessageLoop(IPC::SyncMessage* message) { return Send(message); } +void RenderViewImpl::GetWindowSnapshot(const WindowSnapshotCallback& callback) { + int id = next_snapshot_id_++; + pending_snapshots_.insert(std::make_pair(id, callback)); + Send(new ViewHostMsg_GetWindowSnapshot(routing_id_, id)); +} + +void RenderViewImpl::OnWindowSnapshotCompleted(const int snapshot_id, + const gfx::Size& size, const std::vector& png) { + PendingSnapshotMap::iterator it = pending_snapshots_.find(snapshot_id); + DCHECK(it != pending_snapshots_.end()); + it->second.Run(size, png); + pending_snapshots_.erase(it); +} + // WebKit::WebViewClient ------------------------------------------------------ WebView* RenderViewImpl::createView( diff --git a/content/renderer/render_view_impl.h b/content/renderer/render_view_impl.h index 63be6821ddf64f..e0d13f1dc8d79f 100644 --- a/content/renderer/render_view_impl.h +++ b/content/renderer/render_view_impl.h @@ -379,6 +379,13 @@ class CONTENT_EXPORT RenderViewImpl // supported PPAPI plug-ins. bool HasIMETextFocus(); + // Callback for use with GetWindowSnapshot. + typedef base::Callback&)> + WindowSnapshotCallback; + + void GetWindowSnapshot(const WindowSnapshotCallback& callback); + // IPC::Listener implementation ---------------------------------------------- virtual bool OnMessageReceived(const IPC::Message& msg) OVERRIDE; @@ -1032,6 +1039,9 @@ class CONTENT_EXPORT RenderViewImpl const gfx::Rect& view_frame); #endif + void OnWindowSnapshotCompleted(const int snapshot_id, + const gfx::Size& size, const std::vector& png); + // Adding a new message handler? Please add it in alphabetical order above // and put it in the same position in the .cc file. @@ -1500,6 +1510,12 @@ class CONTENT_EXPORT RenderViewImpl // Wraps the |webwidget_| as a MouseLockDispatcher::LockTarget interface. scoped_ptr webwidget_mouse_lock_target_; + // State associated with the GetWindowSnapshot function. + int next_snapshot_id_; + typedef std::map + PendingSnapshotMap; + PendingSnapshotMap pending_snapshots_; + // Plugins ------------------------------------------------------------------- // All the currently active plugin delegates for this RenderView; kept so diff --git a/ui/snapshot/DEPS b/ui/snapshot/DEPS new file mode 100644 index 00000000000000..13c975df22382d --- /dev/null +++ b/ui/snapshot/DEPS @@ -0,0 +1,7 @@ +include_rules = [ + "+skia", + "+ui/aura", + "+ui/base", + "+ui/compositor", + "+ui/gfx", +] \ No newline at end of file diff --git a/ui/snapshot/snapshot.gyp b/ui/snapshot/snapshot.gyp new file mode 100644 index 00000000000000..40744bfc768359 --- /dev/null +++ b/ui/snapshot/snapshot.gyp @@ -0,0 +1,65 @@ +# Copyright (c) 2012 The Chromium Authors. All rights reserved. +# Use of this source code is governed by a BSD-style license that can be +# found in the LICENSE file. + +{ + 'variables': { + 'chromium_code': 1, + }, + 'targets': [ + { + 'target_name': 'snapshot', + 'type': '<(component)', + 'dependencies': [ + '../../skia/skia.gyp:skia', + '../../base/base.gyp:base', + '../ui.gyp:ui', + ], + 'defines': [ + 'SNAPSHOT_IMPLEMENTATION', + ], + 'sources': [ + 'snapshot.h', + 'snapshot_android.cc', + 'snapshot_aura.cc', + 'snapshot_export.h', + 'snapshot_gtk.cc', + 'snapshot_ios.mm', + 'snapshot_mac.mm', + 'snapshot_win.cc', + ], + 'include_dirs': [ + '..', + ], + 'conditions': [ + ['use_aura==1', { + 'dependencies': [ + '../aura/aura.gyp:aura', + '../compositor/compositor.gyp:compositor', + ], + }], + ['use_aura==1 and OS=="win"', { + 'sources/': [ + ['exclude', 'snapshot_win.cc'], + ], + }], + ], + }, + { + 'target_name': 'snapshot_unittests', + 'type': '<(gtest_target_type)', + 'dependencies': [ + '../../skia/skia.gyp:skia', + '../../base/base.gyp:base', + '../../testing/gtest.gyp:gtest', + '../../testing/gmock.gyp:gmock', + '../../testing/gtest.gyp:gtest', + '../ui.gyp:ui', + 'snapshot' + ], + 'sources': [ + 'snapshot_mac_unittest.mm', + ] + }, + ], +} diff --git a/ui/snapshot/snapshot.h b/ui/snapshot/snapshot.h new file mode 100644 index 00000000000000..356309d86ac6cc --- /dev/null +++ b/ui/snapshot/snapshot.h @@ -0,0 +1,34 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef UI_SNAPSHOT_SNAPSHOT_H_ +#define UI_SNAPSHOT_SNAPSHOT_H_ + +#include + +#include "ui/gfx/native_widget_types.h" +#include "ui/snapshot/snapshot_export.h" + +namespace gfx { +class Rect; +} + +namespace ui { + +// Grabs a snapshot of the window/view. No security checks are done. +// This is intended to be used for debugging purposes where no BrowserProcess +// instance is available (ie. tests). DO NOT use in a result of user action. +SNAPSHOT_EXPORT bool GrabWindowSnapshot( + gfx::NativeWindow window, + std::vector* png_representation, + const gfx::Rect& snapshot_bounds); + +SNAPSHOT_EXPORT bool GrabViewSnapshot( + gfx::NativeView view, + std::vector* png_representation, + const gfx::Rect& snapshot_bounds); + +} // namespace ui + +#endif // UI_SNAPSHOT_SNAPSHOT_H_ diff --git a/ui/snapshot/snapshot_android.cc b/ui/snapshot/snapshot_android.cc new file mode 100644 index 00000000000000..4e89c9da1cabc8 --- /dev/null +++ b/ui/snapshot/snapshot_android.cc @@ -0,0 +1,25 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ui/snapshot/snapshot.h" + +#include "ui/gfx/rect.h" + +namespace ui { + +bool GrabViewSnapshot(gfx::NativeView view, + std::vector* png_representation, + const gfx::Rect& snapshot_bounds) { + // TODO(bajones): Implement Android snapshot functionality + return false; +} + +bool GrabWindowSnapshot(gfx::NativeWindow window, + std::vector* png_representation, + const gfx::Rect& snapshot_bounds) { + // TODO(bajones): Implement Android snapshot functionality + return false; +} + +} // namespace ui diff --git a/chrome/browser/ui/window_snapshot/window_snapshot_aura.cc b/ui/snapshot/snapshot_aura.cc similarity index 85% rename from chrome/browser/ui/window_snapshot/window_snapshot_aura.cc rename to ui/snapshot/snapshot_aura.cc index 4ca3b63e0fe2b2..1eca6d573b4c03 100644 --- a/chrome/browser/ui/window_snapshot/window_snapshot_aura.cc +++ b/ui/snapshot/snapshot_aura.cc @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/ui/window_snapshot/window_snapshot.h" +#include "ui/snapshot/snapshot.h" #include "base/logging.h" #include "third_party/skia/include/core/SkBitmap.h" @@ -13,8 +13,13 @@ #include "ui/gfx/codec/png_codec.h" #include "ui/gfx/rect.h" -namespace chrome { -namespace internal { +namespace ui { + +bool GrabViewSnapshot(gfx::NativeView view, + std::vector* png_representation, + const gfx::Rect& snapshot_bounds) { + return GrabWindowSnapshot(view, png_representation, snapshot_bounds); +} bool GrabWindowSnapshot(gfx::NativeWindow window, std::vector* png_representation, @@ -50,5 +55,4 @@ bool GrabWindowSnapshot(gfx::NativeWindow window, return true; } -} // namespace internal -} // namespace chrome +} // namespace ui diff --git a/ui/snapshot/snapshot_export.h b/ui/snapshot/snapshot_export.h new file mode 100644 index 00000000000000..9e27370e7a9069 --- /dev/null +++ b/ui/snapshot/snapshot_export.h @@ -0,0 +1,32 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef UI_SNAPSHOT_SNAPSHOT_EXPORT_H +#define UI_SNAPSHOT_SNAPSHOT_EXPORT_H + +// Defines SNAPSHOT_EXPORT so that functionality implemented by the snapshot +// module can be exported to consumers. + +#if defined(COMPONENT_BUILD) +#if defined(WIN32) + +#if defined(SNAPSHOT_IMPLEMENTATION) +#define SNAPSHOT_EXPORT __declspec(dllexport) +#else +#define SNAPSHOT_EXPORT __declspec(dllimport) +#endif // defined(SNAPSHOT_IMPLEMENTATION) + +#else // defined(WIN32) +#if defined(SNAPSHOT_IMPLEMENTATION) +#define SNAPSHOT_EXPORT __attribute__((visibility("default"))) +#else +#define SNAPSHOT_EXPORT +#endif +#endif + +#else // defined(COMPONENT_BUILD) +#define SNAPSHOT_EXPORT +#endif + +#endif // UI_SNAPSHOT_SNAPSHOT_EXPORT_H diff --git a/chrome/browser/ui/window_snapshot/window_snapshot_gtk.cc b/ui/snapshot/snapshot_gtk.cc similarity index 84% rename from chrome/browser/ui/window_snapshot/window_snapshot_gtk.cc rename to ui/snapshot/snapshot_gtk.cc index 8c255ba851ed2e..8a2f8c1edd7003 100644 --- a/chrome/browser/ui/window_snapshot/window_snapshot_gtk.cc +++ b/ui/snapshot/snapshot_gtk.cc @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/ui/window_snapshot/window_snapshot.h" +#include "ui/snapshot/snapshot.h" #include #include @@ -27,13 +27,12 @@ cairo_status_t SnapshotCallback(void* closure, } // namespace -namespace chrome { -namespace internal { +namespace ui { -bool GrabWindowSnapshot(gfx::NativeWindow window_handle, +bool GrabViewSnapshot(gfx::NativeView view_handle, std::vector* png_representation, const gfx::Rect& snapshot_bounds) { - GdkWindow* gdk_window = gtk_widget_get_window(GTK_WIDGET(window_handle)); + GdkWindow* gdk_window = gtk_widget_get_window(view_handle); Display* display = GDK_WINDOW_XDISPLAY(gdk_window); XID win = GDK_WINDOW_XID(gdk_window); @@ -76,5 +75,11 @@ bool GrabWindowSnapshot(gfx::NativeWindow window_handle, return true; } -} // namespace internal -} // namespace chrome +bool GrabWindowSnapshot(gfx::NativeWindow window_handle, + std::vector* png_representation, + const gfx::Rect& snapshot_bounds) { + return GrabViewSnapshot(GTK_WIDGET(window_handle), png_representation, + snapshot_bounds); +} + +} // namespace ui diff --git a/ui/snapshot/snapshot_ios.mm b/ui/snapshot/snapshot_ios.mm new file mode 100644 index 00000000000000..b373a0367b538c --- /dev/null +++ b/ui/snapshot/snapshot_ios.mm @@ -0,0 +1,25 @@ +// Copyright (c) 2012 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "ui/snapshot/snapshot.h" + +#include "ui/gfx/rect.h" + +namespace ui { + +bool GrabViewSnapshot(gfx::NativeView view, + std::vector* png_representation, + const gfx::Rect& snapshot_bounds) { + // TODO(bajones): Implement iOS snapshot functionality + return false; +} + +bool GrabWindowSnapshot(gfx::NativeWindow window, + std::vector* png_representation, + const gfx::Rect& snapshot_bounds) { + // TODO(bajones): Implement iOS snapshot functionality + return false; +} + +} // namespace ui diff --git a/chrome/browser/ui/window_snapshot/window_snapshot_mac.mm b/ui/snapshot/snapshot_mac.mm similarity index 62% rename from chrome/browser/ui/window_snapshot/window_snapshot_mac.mm rename to ui/snapshot/snapshot_mac.mm index be3497241ea098..58337046fb83dc 100644 --- a/chrome/browser/ui/window_snapshot/window_snapshot_mac.mm +++ b/ui/snapshot/snapshot_mac.mm @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/ui/window_snapshot/window_snapshot.h" +#include "ui/snapshot/snapshot.h" #import @@ -11,36 +11,39 @@ #include "base/memory/scoped_nsobject.h" #include "ui/gfx/rect.h" -namespace chrome { -namespace internal { +namespace ui { -bool GrabWindowSnapshot(gfx::NativeWindow window, - std::vector* png_representation, - const gfx::Rect& snapshot_bounds) { +bool GrabViewSnapshot(gfx::NativeView view, + std::vector* png_representation, + const gfx::Rect& snapshot_bounds) { + NSWindow* window = [view window]; NSScreen* screen = [[NSScreen screens] objectAtIndex:0]; gfx::Rect screen_bounds = gfx::Rect(NSRectToCGRect([screen frame])); - gfx::Rect window_bounds = gfx::Rect(NSRectToCGRect([window frame])); + + + // Get the view bounds relative to the screen + NSRect frame = [view convertRect:[view bounds] toView:nil]; + frame.origin = [window convertBaseToScreen:frame.origin]; + + gfx::Rect view_bounds = gfx::Rect(NSRectToCGRect(frame)); // Flip window coordinates based on the primary screen. - window_bounds.set_y( - screen_bounds.height() - window_bounds.y() - window_bounds.height()); + view_bounds.set_y( + screen_bounds.height() - view_bounds.y() - view_bounds.height()); // Convert snapshot bounds relative to window into bounds relative to // screen. gfx::Rect screen_snapshot_bounds = snapshot_bounds; - screen_snapshot_bounds.Offset(window_bounds.OffsetFromOrigin()); + screen_snapshot_bounds.Offset(view_bounds.OffsetFromOrigin()); - DCHECK_LE(screen_snapshot_bounds.right(), window_bounds.right()); - DCHECK_LE(screen_snapshot_bounds.bottom(), window_bounds.bottom()); + DCHECK_LE(screen_snapshot_bounds.right(), view_bounds.right()); + DCHECK_LE(screen_snapshot_bounds.bottom(), view_bounds.bottom()); png_representation->clear(); - // Make sure to grab the "window frame" view so we get current tab + - // tabstrip. - NSView* view = [[window contentView] superview]; base::mac::ScopedCFTypeRef windowSnapshot(CGWindowListCreateImage( screen_snapshot_bounds.ToCGRect(), kCGWindowListOptionIncludingWindow, - [[view window] windowNumber], kCGWindowImageBoundsIgnoreFraming)); + [window windowNumber], kCGWindowImageBoundsIgnoreFraming)); if (CGImageGetWidth(windowSnapshot) <= 0) return false; @@ -58,5 +61,13 @@ bool GrabWindowSnapshot(gfx::NativeWindow window, return true; } -} // namespace internal -} // namespace chrome +bool GrabWindowSnapshot(gfx::NativeWindow window, + std::vector* png_representation, + const gfx::Rect& snapshot_bounds) { + // Make sure to grab the "window frame" view so we get current tab + + // tabstrip. + return GrabViewSnapshot([[window contentView] superview], png_representation, + snapshot_bounds); +} + +} // namespace ui diff --git a/chrome/browser/ui/window_snapshot/window_snapshot_mac_unittest.mm b/ui/snapshot/snapshot_mac_unittest.mm similarity index 92% rename from chrome/browser/ui/window_snapshot/window_snapshot_mac_unittest.mm rename to ui/snapshot/snapshot_mac_unittest.mm index c42ffba573f950..900617335a820c 100644 --- a/chrome/browser/ui/window_snapshot/window_snapshot_mac_unittest.mm +++ b/ui/snapshot/snapshot_mac_unittest.mm @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/ui/window_snapshot/window_snapshot.h" +#include "ui/snapshot/snapshot.h" #import @@ -20,7 +20,7 @@ - (CGFloat)backingScaleFactor; #endif // 10.7 -namespace chrome { +namespace ui { namespace { typedef PlatformTest GrabWindowSnapshotTest; @@ -39,7 +39,7 @@ - (CGFloat)backingScaleFactor; scoped_ptr > png_representation( new std::vector); gfx::Rect bounds = gfx::Rect(0, 0, frame.size.width, frame.size.height); - EXPECT_TRUE(internal::GrabWindowSnapshot(window, png_representation.get(), + EXPECT_TRUE(ui::GrabWindowSnapshot(window, png_representation.get(), bounds)); // Copy png back into NSData object so we can make sure we grabbed a png. @@ -59,4 +59,4 @@ - (CGFloat)backingScaleFactor; } } // namespace -} // namespace chrome +} // namespace ui diff --git a/chrome/browser/ui/window_snapshot/window_snapshot_win.cc b/ui/snapshot/snapshot_win.cc similarity index 92% rename from chrome/browser/ui/window_snapshot/window_snapshot_win.cc rename to ui/snapshot/snapshot_win.cc index bbef524f4a5f94..3a8d1e71576572 100644 --- a/chrome/browser/ui/window_snapshot/window_snapshot_win.cc +++ b/ui/snapshot/snapshot_win.cc @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "chrome/browser/ui/window_snapshot/window_snapshot.h" +#include "ui/snapshot/snapshot.h" #include "base/win/scoped_gdi_object.h" #include "base/win/scoped_hdc.h" @@ -34,8 +34,13 @@ gfx::Rect GetWindowBounds(gfx::NativeWindow window_handle) { } // namespace -namespace chrome { -namespace internal { +namespace ui { + +bool GrabViewSnapshot(gfx::NativeView view_handle, + std::vector* png_representation, + const gfx::Rect& snapshot_bounds) { + return GrabWindowSnapshot(view_handle, png_representation, snapshot_bounds); +} bool GrabWindowSnapshot(gfx::NativeWindow window_handle, std::vector* png_representation, @@ -98,5 +103,4 @@ bool GrabWindowSnapshot(gfx::NativeWindow window_handle, return true; } -} // namespace internal -} // namespace chrome +} // namespace ui