diff options
author | rafaelw@chromium.org <rafaelw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-08-13 00:04:06 +0000 |
---|---|---|
committer | rafaelw@chromium.org <rafaelw@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-08-13 00:04:06 +0000 |
commit | 3947c4d60629f25db90519933ea98bf273259fdd (patch) | |
tree | 2c64bc019ecad853a0fc83ac5b5e59196c15d6ee /chrome/browser | |
parent | 576537844b224ca246713c57e039d19d0dfefbf7 (diff) | |
download | chromium_src-3947c4d60629f25db90519933ea98bf273259fdd.zip chromium_src-3947c4d60629f25db90519933ea98bf273259fdd.tar.gz chromium_src-3947c4d60629f25db90519933ea98bf273259fdd.tar.bz2 |
I have taken over this patch, original authored by Adam Hunter (adamhunter).
The original issue is: http://codereview.chromium.org/144019
--------------
Functionality has been requested in the Extension API for Javascript to
take screenshots of the currently visible tab. This changelist builds this
function, chrome.tabs.getVisibleScreenCapture. This function takes a
single callback function and returns to that function a data URL of a JPEG
image of the current screen. A simple sample extension is provided as a
use case.
BUG=14760
TEST=There is an extension in chrome\test\data\extensions\samples\screenshot,
load this extension. It creates a toolstrip button. Click this button, you
should get a page with a screenshot of the active tab. The API function
is found at chrome.tabs.getVisibleScreenCapture.
Review URL: http://codereview.chromium.org/160228
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@23259 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser')
5 files changed, 95 insertions, 0 deletions
diff --git a/chrome/browser/extensions/extension_function_dispatcher.cc b/chrome/browser/extensions/extension_function_dispatcher.cc index e9ddef4..314d349 100644 --- a/chrome/browser/extensions/extension_function_dispatcher.cc +++ b/chrome/browser/extensions/extension_function_dispatcher.cc @@ -105,6 +105,8 @@ void FactoryRegistry::ResetFunctions() { &NewExtensionFunction<RemoveTabFunction>; factories_[tabs::kDetectTabLanguageFunction] = &NewExtensionFunction<DetectTabLanguageFunction>; + factories_[tabs::kCaptureVisibleTabFunction] = + &NewExtensionFunction<CaptureVisibleTabFunction>; // Page Actions. factories_[page_actions::kEnablePageActionFunction] = diff --git a/chrome/browser/extensions/extension_tabs_module.cc b/chrome/browser/extensions/extension_tabs_module.cc index a51a9a2..12b3547 100644 --- a/chrome/browser/extensions/extension_tabs_module.cc +++ b/chrome/browser/extensions/extension_tabs_module.cc @@ -4,6 +4,7 @@ #include "chrome/browser/extensions/extension_tabs_module.h" +#include "base/gfx/jpeg_codec.h" #include "base/string_util.h" #include "chrome/browser/browser.h" #include "chrome/browser/browser_list.h" @@ -12,12 +13,18 @@ #include "chrome/browser/extensions/extension_tabs_module_constants.h" #include "chrome/browser/extensions/extensions_service.h" #include "chrome/browser/profile.h" +#include "chrome/browser/renderer_host/backing_store.h" +#include "chrome/browser/renderer_host/render_view_host.h" #include "chrome/browser/renderer_host/render_view_host_delegate.h" #include "chrome/browser/tab_contents/navigation_entry.h" #include "chrome/browser/tab_contents/tab_contents.h" #include "chrome/browser/window_sizer.h" #include "chrome/common/extensions/extension.h" #include "chrome/common/extensions/extension_error_utils.h" +#include "net/base/base64.h" +#include "skia/ext/image_operations.h" +#include "skia/ext/platform_canvas.h" +#include "third_party/skia/include/core/SkBitmap.h" namespace keys = extension_tabs_module_constants; @@ -615,6 +622,82 @@ bool RemoveTabFunction::RunImpl() { return true; } +bool CaptureVisibleTabFunction::RunImpl() { + Browser* browser; + // windowId defaults to "current" window. + int window_id = -1; + + if (!args_->IsType(Value::TYPE_NULL)) { + EXTENSION_FUNCTION_VALIDATE(args_->GetAsInteger(&window_id)); + browser = GetBrowserInProfileWithId(profile(), window_id, &error_); + } else { + browser = dispatcher()->GetBrowser(); + } + + if (!browser) { + error_ = keys::kNoCurrentWindowError; + return false; + } + + SkBitmap screen_capture; +#if defined(OS_WIN) + TabContents* tab_contents = browser->GetSelectedTabContents(); + if (!tab_contents) { + error_ = keys::kInternalVisibleTabCaptureError; + return false; + } + RenderViewHost* render_view_host = tab_contents->render_view_host(); + BackingStore* backing_store = render_view_host->GetBackingStore(false); + if (!backing_store) { + error_ = keys::kInternalVisibleTabCaptureError; + return false; + } + skia::PlatformCanvas temp_canvas; + if (!temp_canvas.initialize(backing_store->size().width(), + backing_store->size().height(), true)) { + error_ = ExtensionErrorUtils::FormatErrorMessage( + keys::kInternalVisibleTabCaptureError, ""); + return false; + } + HDC temp_dc = temp_canvas.beginPlatformPaint(); + BitBlt(temp_dc, + 0, 0, backing_store->size().width(), backing_store->size().height(), + backing_store->hdc(), 0, 0, SRCCOPY); + temp_canvas.endPlatformPaint(); + + screen_capture = temp_canvas.getTopPlatformDevice().accessBitmap(false); +#else + // TODO(port) + error_ = keys::kNotImplementedError; + return false; +#endif + scoped_refptr<RefCountedBytes> jpeg_data(new RefCountedBytes); + SkAutoLockPixels screen_capture_lock(screen_capture); + bool encoded = JPEGCodec::Encode( + reinterpret_cast<unsigned char*>(screen_capture.getAddr32(0, 0)), + JPEGCodec::FORMAT_BGRA, screen_capture.width(), + screen_capture.height(), + static_cast<int>(screen_capture.rowBytes()), 90, + &jpeg_data->data); + if (!encoded) { + error_ = ExtensionErrorUtils::FormatErrorMessage( + keys::kInternalVisibleTabCaptureError, ""); + return false; + } + + std::string base64_result; + std::string stream_as_string; + stream_as_string.resize(jpeg_data->data.size()); + memcpy(&stream_as_string[0], + reinterpret_cast<const char*>(&jpeg_data->data[0]), + jpeg_data->data.size()); + + net::Base64Encode(stream_as_string, &base64_result); + base64_result.insert(0, "data:image/jpg;base64,"); + result_.reset(new StringValue(base64_result)); + return true; +} + bool DetectTabLanguageFunction::RunImpl() { int tab_id = 0; Browser* browser = NULL; diff --git a/chrome/browser/extensions/extension_tabs_module.h b/chrome/browser/extensions/extension_tabs_module.h index 821ce89..a0d53c8 100644 --- a/chrome/browser/extensions/extension_tabs_module.h +++ b/chrome/browser/extensions/extension_tabs_module.h @@ -98,5 +98,8 @@ class DetectTabLanguageFunction : public AsyncExtensionFunction, const NotificationDetails& details); NotificationRegistrar registrar_; }; +class CaptureVisibleTabFunction : public SyncExtensionFunction { + virtual bool RunImpl(); +}; #endif // CHROME_BROWSER_EXTENSIONS_EXTENSION_TABS_MODULE_H__ diff --git a/chrome/browser/extensions/extension_tabs_module_constants.cc b/chrome/browser/extensions/extension_tabs_module_constants.cc index 11e7dad..92abf87 100644 --- a/chrome/browser/extensions/extension_tabs_module_constants.cc +++ b/chrome/browser/extensions/extension_tabs_module_constants.cc @@ -40,6 +40,9 @@ const char kWindowNotFoundError[] = "No window with id: *."; const char kTabNotFoundError[] = "No tab with id: *."; const char kNoSelectedTabError[] = "No selected tab"; const char kInvalidUrlError[] = "Invalid url: \"*\"."; +const char kInternalVisibleTabCaptureError[] = + "Internal error while trying to capture visible region of the current tab"; +const char kNotImplementedError[] = "This call is not yet implemented"; const char kGetWindowFunction[] = "windows.get"; const char kGetCurrentWindowFunction[] = "windows.getCurrent"; @@ -57,5 +60,6 @@ const char kUpdateTabFunction[] = "tabs.update"; const char kMoveTabFunction[] = "tabs.move"; const char kRemoveTabFunction[] = "tabs.remove"; const char kDetectTabLanguageFunction[] = "tabs.detectLanguage"; +const char kCaptureVisibleTabFunction[] = "tabs.captureVisibleTab"; } // namespace extension_tabs_module_constants diff --git a/chrome/browser/extensions/extension_tabs_module_constants.h b/chrome/browser/extensions/extension_tabs_module_constants.h index f601c84..dbf2ef0 100644 --- a/chrome/browser/extensions/extension_tabs_module_constants.h +++ b/chrome/browser/extensions/extension_tabs_module_constants.h @@ -46,6 +46,8 @@ extern const char kWindowNotFoundError[]; extern const char kTabNotFoundError[]; extern const char kNoSelectedTabError[]; extern const char kInvalidUrlError[]; +extern const char kInternalVisibleTabCaptureError[]; +extern const char kNotImplementedError[]; // Function names, Windows API. extern const char kGetWindowFunction[]; @@ -65,6 +67,7 @@ extern const char kUpdateTabFunction[]; extern const char kMoveTabFunction[]; extern const char kRemoveTabFunction[]; extern const char kDetectTabLanguageFunction[]; +extern const char kCaptureVisibleTabFunction[]; }; // namespace extension_tabs_module_constants |