OLD | NEW |
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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/extensions/extension_tabs_module.h" | 5 #include "chrome/browser/extensions/extension_tabs_module.h" |
6 | 6 |
7 #include "base/histogram.h" | 7 #include "base/histogram.h" |
8 #include "base/base64.h" | 8 #include "base/base64.h" |
9 #include "base/string_util.h" | 9 #include "base/string_util.h" |
10 #include "chrome/browser/browser.h" | 10 #include "chrome/browser/browser.h" |
11 #include "chrome/browser/browser_list.h" | 11 #include "chrome/browser/browser_list.h" |
12 #include "chrome/browser/browser_window.h" | 12 #include "chrome/browser/browser_window.h" |
13 #include "chrome/browser/extensions/extension_function_dispatcher.h" | 13 #include "chrome/browser/extensions/extension_function_dispatcher.h" |
14 #include "chrome/browser/extensions/extension_tabs_module_constants.h" | 14 #include "chrome/browser/extensions/extension_tabs_module_constants.h" |
15 #include "chrome/browser/extensions/extensions_service.h" | 15 #include "chrome/browser/extensions/extensions_service.h" |
16 #include "chrome/browser/profile.h" | 16 #include "chrome/browser/profile.h" |
17 #include "chrome/browser/renderer_host/backing_store.h" | 17 #include "chrome/browser/renderer_host/backing_store.h" |
18 #include "chrome/browser/renderer_host/render_view_host.h" | 18 #include "chrome/browser/renderer_host/render_view_host.h" |
19 #include "chrome/browser/renderer_host/render_view_host_delegate.h" | 19 #include "chrome/browser/renderer_host/render_view_host_delegate.h" |
20 #include "chrome/browser/tab_contents/navigation_entry.h" | 20 #include "chrome/browser/tab_contents/navigation_entry.h" |
21 #include "chrome/browser/tab_contents/tab_contents.h" | 21 #include "chrome/browser/tab_contents/tab_contents.h" |
22 #include "chrome/browser/tabs/tab_strip_model.h" | 22 #include "chrome/browser/tabs/tab_strip_model.h" |
23 #include "chrome/browser/window_sizer.h" | 23 #include "chrome/browser/window_sizer.h" |
24 #include "chrome/common/extensions/extension.h" | 24 #include "chrome/common/extensions/extension.h" |
25 #include "chrome/common/extensions/extension_error_utils.h" | 25 #include "chrome/common/extensions/extension_error_utils.h" |
26 #include "chrome/common/url_constants.h" | 26 #include "chrome/common/url_constants.h" |
27 #include "gfx/codec/jpeg_codec.h" | 27 #include "gfx/codec/jpeg_codec.h" |
| 28 #include "gfx/codec/png_codec.h" |
28 #include "skia/ext/image_operations.h" | 29 #include "skia/ext/image_operations.h" |
29 #include "skia/ext/platform_canvas.h" | 30 #include "skia/ext/platform_canvas.h" |
30 #include "third_party/skia/include/core/SkBitmap.h" | 31 #include "third_party/skia/include/core/SkBitmap.h" |
31 | 32 |
32 namespace keys = extension_tabs_module_constants; | 33 namespace keys = extension_tabs_module_constants; |
33 | 34 |
| 35 const int CaptureVisibleTabFunction::kDefaultQuality = 90; |
| 36 |
34 // Forward declare static helper functions defined below. | 37 // Forward declare static helper functions defined below. |
35 | 38 |
36 // |error_message| can optionally be passed in a will be set with an appropriate | 39 // |error_message| can optionally be passed in a will be set with an appropriate |
37 // message if the window cannot be found by id. | 40 // message if the window cannot be found by id. |
38 static Browser* GetBrowserInProfileWithId(Profile* profile, | 41 static Browser* GetBrowserInProfileWithId(Profile* profile, |
39 const int window_id, | 42 const int window_id, |
40 bool include_incognito, | 43 bool include_incognito, |
41 std::string* error_message); | 44 std::string* error_message); |
42 | 45 |
43 // |error_message| can optionally be passed in and will be set with an | 46 // |error_message| can optionally be passed in and will be set with an |
(...skipping 754 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
798 RenderViewHost* render_view_host = contents->render_view_host(); | 801 RenderViewHost* render_view_host = contents->render_view_host(); |
799 render_view_host->delegate()->Close(render_view_host); | 802 render_view_host->delegate()->Close(render_view_host); |
800 return true; | 803 return true; |
801 } | 804 } |
802 | 805 |
803 bool CaptureVisibleTabFunction::RunImpl() { | 806 bool CaptureVisibleTabFunction::RunImpl() { |
804 Browser* browser; | 807 Browser* browser; |
805 // windowId defaults to "current" window. | 808 // windowId defaults to "current" window. |
806 int window_id = -1; | 809 int window_id = -1; |
807 | 810 |
808 if (!args_->IsType(Value::TYPE_NULL)) { | 811 EXTENSION_FUNCTION_VALIDATE(args_->IsType(Value::TYPE_LIST)); |
809 EXTENSION_FUNCTION_VALIDATE(args_->GetAsInteger(&window_id)); | 812 const ListValue* args = args_as_list(); |
| 813 |
| 814 if (HasOptionalArgument(0)) { |
| 815 EXTENSION_FUNCTION_VALIDATE(args->GetInteger(0, &window_id)); |
810 browser = GetBrowserInProfileWithId(profile(), window_id, | 816 browser = GetBrowserInProfileWithId(profile(), window_id, |
811 include_incognito(), &error_); | 817 include_incognito(), &error_); |
812 } else { | 818 } else { |
813 browser = GetCurrentBrowser(); | 819 browser = GetCurrentBrowser(); |
814 } | 820 } |
815 | 821 |
816 if (!browser) { | 822 if (!browser) { |
817 error_ = keys::kNoCurrentWindowError; | 823 error_ = keys::kNoCurrentWindowError; |
818 return false; | 824 return false; |
819 } | 825 } |
820 | 826 |
| 827 image_format_ = FORMAT_JPEG; // Default format is JPEG. |
| 828 image_quality_ = kDefaultQuality; // Default quality setting. |
| 829 |
| 830 if (HasOptionalArgument(1)) { |
| 831 DictionaryValue* options; |
| 832 EXTENSION_FUNCTION_VALIDATE(args->GetDictionary(1, &options)); |
| 833 |
| 834 if (options->HasKey(keys::kFormatKey)) { |
| 835 std::string format; |
| 836 EXTENSION_FUNCTION_VALIDATE( |
| 837 options->GetString(keys::kFormatKey, &format)); |
| 838 |
| 839 if (format == keys::kFormatValueJpeg) { |
| 840 image_format_ = FORMAT_JPEG; |
| 841 } else if (format == keys::kFormatValuePng) { |
| 842 image_format_ = FORMAT_PNG; |
| 843 } else { |
| 844 // Schema validation should make this unreachable. |
| 845 EXTENSION_FUNCTION_VALIDATE(0); |
| 846 } |
| 847 } |
| 848 |
| 849 if (options->HasKey(keys::kQualityKey)) { |
| 850 EXTENSION_FUNCTION_VALIDATE( |
| 851 options->GetInteger(keys::kQualityKey, &image_quality_)); |
| 852 } |
| 853 } |
| 854 |
821 TabContents* tab_contents = browser->GetSelectedTabContents(); | 855 TabContents* tab_contents = browser->GetSelectedTabContents(); |
822 if (!tab_contents) { | 856 if (!tab_contents) { |
823 error_ = keys::kInternalVisibleTabCaptureError; | 857 error_ = keys::kInternalVisibleTabCaptureError; |
824 return false; | 858 return false; |
825 } | 859 } |
826 RenderViewHost* render_view_host = tab_contents->render_view_host(); | 860 RenderViewHost* render_view_host = tab_contents->render_view_host(); |
827 | 861 |
828 // If a backing store is cached for the tab we want to capture, | 862 // If a backing store is cached for the tab we want to capture, |
829 // and it can be copied into a bitmap, then use it to generate the image. | 863 // and it can be copied into a bitmap, then use it to generate the image. |
830 BackingStore* backing_store = render_view_host->GetBackingStore(false); | 864 BackingStore* backing_store = render_view_host->GetBackingStore(false); |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
877 SendResultFromBitmap(*screen_capture); | 911 SendResultFromBitmap(*screen_capture); |
878 } | 912 } |
879 | 913 |
880 Release(); // Balanced in CaptureVisibleTabFunction::RunImpl(). | 914 Release(); // Balanced in CaptureVisibleTabFunction::RunImpl(). |
881 } | 915 } |
882 | 916 |
883 // Turn a bitmap of the screen into an image, set that image as the result, | 917 // Turn a bitmap of the screen into an image, set that image as the result, |
884 // and call SendResponse(). | 918 // and call SendResponse(). |
885 void CaptureVisibleTabFunction::SendResultFromBitmap( | 919 void CaptureVisibleTabFunction::SendResultFromBitmap( |
886 const SkBitmap& screen_capture) { | 920 const SkBitmap& screen_capture) { |
887 scoped_refptr<RefCountedBytes> jpeg_data(new RefCountedBytes); | 921 scoped_refptr<RefCountedBytes> image_data(new RefCountedBytes); |
888 SkAutoLockPixels screen_capture_lock(screen_capture); | 922 SkAutoLockPixels screen_capture_lock(screen_capture); |
889 bool encoded = gfx::JPEGCodec::Encode( | 923 bool encoded; |
890 reinterpret_cast<unsigned char*>(screen_capture.getAddr32(0, 0)), | 924 std::string mime_type; |
891 gfx::JPEGCodec::FORMAT_BGRA, screen_capture.width(), | 925 switch (image_format_) { |
892 screen_capture.height(), | 926 case FORMAT_JPEG: |
893 static_cast<int>(screen_capture.rowBytes()), 90, | 927 encoded = gfx::JPEGCodec::Encode( |
894 &jpeg_data->data); | 928 reinterpret_cast<unsigned char*>(screen_capture.getAddr32(0, 0)), |
| 929 gfx::JPEGCodec::FORMAT_BGRA, |
| 930 screen_capture.width(), |
| 931 screen_capture.height(), |
| 932 static_cast<int>(screen_capture.rowBytes()), image_quality_, |
| 933 &image_data->data); |
| 934 mime_type = keys::kMimeTypeJpeg; |
| 935 break; |
| 936 case FORMAT_PNG: |
| 937 encoded = gfx::PNGCodec::Encode( |
| 938 reinterpret_cast<unsigned char*>(screen_capture.getAddr32(0, 0)), |
| 939 gfx::PNGCodec::FORMAT_BGRA, |
| 940 screen_capture.width(), |
| 941 screen_capture.height(), |
| 942 static_cast<int>(screen_capture.rowBytes()), false, |
| 943 &image_data->data); |
| 944 mime_type = keys::kMimeTypePng; |
| 945 break; |
| 946 default: |
| 947 NOTREACHED() << "Invalid image format."; |
| 948 } |
| 949 |
895 if (!encoded) { | 950 if (!encoded) { |
896 error_ = ExtensionErrorUtils::FormatErrorMessage( | 951 error_ = ExtensionErrorUtils::FormatErrorMessage( |
897 keys::kInternalVisibleTabCaptureError, ""); | 952 keys::kInternalVisibleTabCaptureError, ""); |
898 SendResponse(false); | 953 SendResponse(false); |
899 return; | 954 return; |
900 } | 955 } |
901 | 956 |
902 std::string base64_result; | 957 std::string base64_result; |
903 std::string stream_as_string; | 958 std::string stream_as_string; |
904 stream_as_string.resize(jpeg_data->data.size()); | 959 stream_as_string.resize(image_data->data.size()); |
905 memcpy(&stream_as_string[0], | 960 memcpy(&stream_as_string[0], |
906 reinterpret_cast<const char*>(&jpeg_data->data[0]), | 961 reinterpret_cast<const char*>(&image_data->data[0]), |
907 jpeg_data->data.size()); | 962 image_data->data.size()); |
908 | 963 |
909 base::Base64Encode(stream_as_string, &base64_result); | 964 base::Base64Encode(stream_as_string, &base64_result); |
910 base64_result.insert(0, "data:image/jpg;base64,"); | 965 base64_result.insert(0, StringPrintf("data:%s;base64,", mime_type.c_str())); |
911 result_.reset(new StringValue(base64_result)); | 966 result_.reset(new StringValue(base64_result)); |
912 SendResponse(true); | 967 SendResponse(true); |
913 } | 968 } |
914 | 969 |
915 bool DetectTabLanguageFunction::RunImpl() { | 970 bool DetectTabLanguageFunction::RunImpl() { |
916 int tab_id = 0; | 971 int tab_id = 0; |
917 Browser* browser = NULL; | 972 Browser* browser = NULL; |
918 TabContents* contents = NULL; | 973 TabContents* contents = NULL; |
919 | 974 |
920 // If |tab_id| is specified, look for it. Otherwise default to selected tab | 975 // If |tab_id| is specified, look for it. Otherwise default to selected tab |
(...skipping 143 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1064 // caller. | 1119 // caller. |
1065 use_type = url.is_valid() && (url != resolved_url) ? | 1120 use_type = url.is_valid() && (url != resolved_url) ? |
1066 RELATIVE_URL_RESOLUTIONS_DIFFER : RELATIVE_URL_RESOLUTIONS_AGREE; | 1121 RELATIVE_URL_RESOLUTIONS_DIFFER : RELATIVE_URL_RESOLUTIONS_AGREE; |
1067 } | 1122 } |
1068 | 1123 |
1069 UMA_HISTOGRAM_ENUMERATION("Extensions.APIUse_RelativeURL", use_type, | 1124 UMA_HISTOGRAM_ENUMERATION("Extensions.APIUse_RelativeURL", use_type, |
1070 EXTENSION_API_RELATIVE_URL_USE_MAX_VALUE); | 1125 EXTENSION_API_RELATIVE_URL_USE_MAX_VALUE); |
1071 | 1126 |
1072 return url; | 1127 return url; |
1073 } | 1128 } |
1074 | |
OLD | NEW |