| OLD | NEW |
| 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2011 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 <algorithm> | 7 #include <algorithm> |
| 8 #include <vector> | 8 #include <vector> |
| 9 | 9 |
| 10 #include "base/base64.h" | 10 #include "base/base64.h" |
| (...skipping 28 matching lines...) Expand all Loading... |
| 39 #include "chrome/common/chrome_notification_types.h" | 39 #include "chrome/common/chrome_notification_types.h" |
| 40 #include "chrome/common/chrome_switches.h" | 40 #include "chrome/common/chrome_switches.h" |
| 41 #include "chrome/common/extensions/extension.h" | 41 #include "chrome/common/extensions/extension.h" |
| 42 #include "chrome/common/extensions/extension_error_utils.h" | 42 #include "chrome/common/extensions/extension_error_utils.h" |
| 43 #include "chrome/common/extensions/extension_messages.h" | 43 #include "chrome/common/extensions/extension_messages.h" |
| 44 #include "chrome/common/pref_names.h" | 44 #include "chrome/common/pref_names.h" |
| 45 #include "chrome/common/url_constants.h" | 45 #include "chrome/common/url_constants.h" |
| 46 #include "content/browser/renderer_host/backing_store.h" | 46 #include "content/browser/renderer_host/backing_store.h" |
| 47 #include "content/browser/renderer_host/render_view_host.h" | 47 #include "content/browser/renderer_host/render_view_host.h" |
| 48 #include "content/browser/renderer_host/render_view_host_delegate.h" | 48 #include "content/browser/renderer_host/render_view_host_delegate.h" |
| 49 #include "content/browser/tab_contents/tab_contents.h" | 49 #include "content/browser/tab_contents/navigation_controller.h" |
| 50 #include "content/browser/tab_contents/tab_contents_view.h" | 50 #include "content/browser/tab_contents/tab_contents_view.h" |
| 51 #include "content/public/browser/navigation_entry.h" | 51 #include "content/public/browser/navigation_entry.h" |
| 52 #include "content/public/browser/notification_details.h" | 52 #include "content/public/browser/notification_details.h" |
| 53 #include "content/public/browser/notification_source.h" | 53 #include "content/public/browser/notification_source.h" |
| 54 #include "content/public/browser/web_contents.h" |
| 54 #include "skia/ext/image_operations.h" | 55 #include "skia/ext/image_operations.h" |
| 55 #include "skia/ext/platform_canvas.h" | 56 #include "skia/ext/platform_canvas.h" |
| 56 #include "third_party/skia/include/core/SkBitmap.h" | 57 #include "third_party/skia/include/core/SkBitmap.h" |
| 57 #include "ui/gfx/codec/jpeg_codec.h" | 58 #include "ui/gfx/codec/jpeg_codec.h" |
| 58 #include "ui/gfx/codec/png_codec.h" | 59 #include "ui/gfx/codec/png_codec.h" |
| 59 | 60 |
| 60 namespace keys = extension_tabs_module_constants; | 61 namespace keys = extension_tabs_module_constants; |
| 61 namespace errors = extension_manifest_errors; | 62 namespace errors = extension_manifest_errors; |
| 62 | 63 |
| 63 using content::NavigationEntry; | 64 using content::NavigationEntry; |
| (...skipping 652 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 716 } | 717 } |
| 717 if (!browser) | 718 if (!browser) |
| 718 return false; | 719 return false; |
| 719 | 720 |
| 720 TabStripModel* tab_strip = browser->tabstrip_model(); | 721 TabStripModel* tab_strip = browser->tabstrip_model(); |
| 721 TabContentsWrapper* contents = tab_strip->GetActiveTabContents(); | 722 TabContentsWrapper* contents = tab_strip->GetActiveTabContents(); |
| 722 if (!contents) { | 723 if (!contents) { |
| 723 error_ = keys::kNoSelectedTabError; | 724 error_ = keys::kNoSelectedTabError; |
| 724 return false; | 725 return false; |
| 725 } | 726 } |
| 726 result_.reset(ExtensionTabUtil::CreateTabValue(contents->tab_contents(), | 727 result_.reset(ExtensionTabUtil::CreateTabValue(contents->web_contents(), |
| 727 tab_strip, | 728 tab_strip, |
| 728 tab_strip->active_index())); | 729 tab_strip->active_index())); |
| 729 return true; | 730 return true; |
| 730 } | 731 } |
| 731 | 732 |
| 732 bool GetAllTabsInWindowFunction::RunImpl() { | 733 bool GetAllTabsInWindowFunction::RunImpl() { |
| 733 Browser* browser; | 734 Browser* browser; |
| 734 // windowId defaults to "current" window. | 735 // windowId defaults to "current" window. |
| 735 int window_id = -1; | 736 int window_id = -1; |
| 736 if (HasOptionalArgument(0)) { | 737 if (HasOptionalArgument(0)) { |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 801 | 802 |
| 802 if (window_id >= 0 && window_id != ExtensionTabUtil::GetWindowId(*browser)) | 803 if (window_id >= 0 && window_id != ExtensionTabUtil::GetWindowId(*browser)) |
| 803 continue; | 804 continue; |
| 804 | 805 |
| 805 if (!window_type.empty() && | 806 if (!window_type.empty() && |
| 806 window_type != ExtensionTabUtil::GetWindowTypeText(*browser)) | 807 window_type != ExtensionTabUtil::GetWindowTypeText(*browser)) |
| 807 continue; | 808 continue; |
| 808 | 809 |
| 809 TabStripModel* tab_strip = (*browser)->tabstrip_model(); | 810 TabStripModel* tab_strip = (*browser)->tabstrip_model(); |
| 810 for (int i = 0; i < tab_strip->count(); ++i) { | 811 for (int i = 0; i < tab_strip->count(); ++i) { |
| 811 const TabContents* tab_contents = | 812 const WebContents* web_contents = |
| 812 tab_strip->GetTabContentsAt(i)->tab_contents(); | 813 tab_strip->GetTabContentsAt(i)->web_contents(); |
| 813 | 814 |
| 814 if (!MatchesQueryArg(selected, tab_strip->IsTabSelected(i))) | 815 if (!MatchesQueryArg(selected, tab_strip->IsTabSelected(i))) |
| 815 continue; | 816 continue; |
| 816 | 817 |
| 817 if (!MatchesQueryArg(active, i == tab_strip->active_index())) | 818 if (!MatchesQueryArg(active, i == tab_strip->active_index())) |
| 818 continue; | 819 continue; |
| 819 | 820 |
| 820 if (!MatchesQueryArg(pinned, tab_strip->IsTabPinned(i))) | 821 if (!MatchesQueryArg(pinned, tab_strip->IsTabPinned(i))) |
| 821 continue; | 822 continue; |
| 822 | 823 |
| 823 if (!title.empty() && !MatchPattern(tab_contents->GetTitle(), | 824 if (!title.empty() && !MatchPattern(web_contents->GetTitle(), |
| 824 UTF8ToUTF16(title))) | 825 UTF8ToUTF16(title))) |
| 825 continue; | 826 continue; |
| 826 | 827 |
| 827 if (!url_pattern.MatchesURL(tab_contents->GetURL())) | 828 if (!url_pattern.MatchesURL(web_contents->GetURL())) |
| 828 continue; | 829 continue; |
| 829 | 830 |
| 830 if (!MatchesQueryArg(loading, tab_contents->IsLoading())) | 831 if (!MatchesQueryArg(loading, web_contents->IsLoading())) |
| 831 continue; | 832 continue; |
| 832 | 833 |
| 833 result->Append(ExtensionTabUtil::CreateTabValue( | 834 result->Append(ExtensionTabUtil::CreateTabValue( |
| 834 tab_contents, tab_strip, i)); | 835 web_contents, tab_strip, i)); |
| 835 } | 836 } |
| 836 } | 837 } |
| 837 | 838 |
| 838 result_.reset(result); | 839 result_.reset(result); |
| 839 return true; | 840 return true; |
| 840 } | 841 } |
| 841 | 842 |
| 842 bool CreateTabFunction::RunImpl() { | 843 bool CreateTabFunction::RunImpl() { |
| 843 DictionaryValue* args = NULL; | 844 DictionaryValue* args = NULL; |
| 844 EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &args)); | 845 EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &args)); |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 929 add_types |= TabStripModel::ADD_FORCE_INDEX; | 930 add_types |= TabStripModel::ADD_FORCE_INDEX; |
| 930 if (pinned) | 931 if (pinned) |
| 931 add_types |= TabStripModel::ADD_PINNED; | 932 add_types |= TabStripModel::ADD_PINNED; |
| 932 browser::NavigateParams params(browser, url, content::PAGE_TRANSITION_LINK); | 933 browser::NavigateParams params(browser, url, content::PAGE_TRANSITION_LINK); |
| 933 params.disposition = active ? NEW_FOREGROUND_TAB : NEW_BACKGROUND_TAB; | 934 params.disposition = active ? NEW_FOREGROUND_TAB : NEW_BACKGROUND_TAB; |
| 934 params.tabstrip_index = index; | 935 params.tabstrip_index = index; |
| 935 params.tabstrip_add_types = add_types; | 936 params.tabstrip_add_types = add_types; |
| 936 browser::Navigate(¶ms); | 937 browser::Navigate(¶ms); |
| 937 | 938 |
| 938 if (active) | 939 if (active) |
| 939 params.target_contents->tab_contents()->GetView()->SetInitialFocus(); | 940 params.target_contents->web_contents()->GetView()->SetInitialFocus(); |
| 940 | 941 |
| 941 // Return data about the newly created tab. | 942 // Return data about the newly created tab. |
| 942 if (has_callback()) { | 943 if (has_callback()) { |
| 943 result_.reset(ExtensionTabUtil::CreateTabValue( | 944 result_.reset(ExtensionTabUtil::CreateTabValue( |
| 944 params.target_contents->tab_contents(), | 945 params.target_contents->web_contents(), |
| 945 params.browser->tabstrip_model(), | 946 params.browser->tabstrip_model(), |
| 946 params.browser->tabstrip_model()->GetIndexOfTabContents( | 947 params.browser->tabstrip_model()->GetIndexOfTabContents( |
| 947 params.target_contents))); | 948 params.target_contents))); |
| 948 } | 949 } |
| 949 | 950 |
| 950 return true; | 951 return true; |
| 951 } | 952 } |
| 952 | 953 |
| 953 bool GetTabFunction::RunImpl() { | 954 bool GetTabFunction::RunImpl() { |
| 954 int tab_id = -1; | 955 int tab_id = -1; |
| 955 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &tab_id)); | 956 EXTENSION_FUNCTION_VALIDATE(args_->GetInteger(0, &tab_id)); |
| 956 | 957 |
| 957 TabStripModel* tab_strip = NULL; | 958 TabStripModel* tab_strip = NULL; |
| 958 TabContentsWrapper* contents = NULL; | 959 TabContentsWrapper* contents = NULL; |
| 959 int tab_index = -1; | 960 int tab_index = -1; |
| 960 if (!GetTabById(tab_id, profile(), include_incognito(), | 961 if (!GetTabById(tab_id, profile(), include_incognito(), |
| 961 NULL, &tab_strip, &contents, &tab_index, &error_)) | 962 NULL, &tab_strip, &contents, &tab_index, &error_)) |
| 962 return false; | 963 return false; |
| 963 | 964 |
| 964 result_.reset(ExtensionTabUtil::CreateTabValue(contents->tab_contents(), | 965 result_.reset(ExtensionTabUtil::CreateTabValue(contents->web_contents(), |
| 965 tab_strip, | 966 tab_strip, |
| 966 tab_index)); | 967 tab_index)); |
| 967 return true; | 968 return true; |
| 968 } | 969 } |
| 969 | 970 |
| 970 bool GetCurrentTabFunction::RunImpl() { | 971 bool GetCurrentTabFunction::RunImpl() { |
| 971 DCHECK(dispatcher()); | 972 DCHECK(dispatcher()); |
| 972 | 973 |
| 973 WebContents* contents = dispatcher()->delegate()->GetAssociatedWebContents(); | 974 WebContents* contents = dispatcher()->delegate()->GetAssociatedWebContents(); |
| 974 if (contents) | 975 if (contents) |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1053 Browser* browser = GetCurrentBrowser(); | 1054 Browser* browser = GetCurrentBrowser(); |
| 1054 if (!browser) { | 1055 if (!browser) { |
| 1055 error_ = keys::kNoCurrentWindowError; | 1056 error_ = keys::kNoCurrentWindowError; |
| 1056 return false; | 1057 return false; |
| 1057 } | 1058 } |
| 1058 contents = browser->tabstrip_model()->GetActiveTabContents(); | 1059 contents = browser->tabstrip_model()->GetActiveTabContents(); |
| 1059 if (!contents) { | 1060 if (!contents) { |
| 1060 error_ = keys::kNoSelectedTabError; | 1061 error_ = keys::kNoSelectedTabError; |
| 1061 return false; | 1062 return false; |
| 1062 } | 1063 } |
| 1063 tab_id = ExtensionTabUtil::GetTabId(contents->tab_contents()); | 1064 tab_id = ExtensionTabUtil::GetTabId(contents->web_contents()); |
| 1064 } else { | 1065 } else { |
| 1065 EXTENSION_FUNCTION_VALIDATE(tab_value->GetAsInteger(&tab_id)); | 1066 EXTENSION_FUNCTION_VALIDATE(tab_value->GetAsInteger(&tab_id)); |
| 1066 } | 1067 } |
| 1067 | 1068 |
| 1068 int tab_index = -1; | 1069 int tab_index = -1; |
| 1069 TabStripModel* tab_strip = NULL; | 1070 TabStripModel* tab_strip = NULL; |
| 1070 if (!GetTabById(tab_id, profile(), include_incognito(), | 1071 if (!GetTabById(tab_id, profile(), include_incognito(), |
| 1071 NULL, &tab_strip, &contents, &tab_index, &error_)) { | 1072 NULL, &tab_strip, &contents, &tab_index, &error_)) { |
| 1072 return false; | 1073 return false; |
| 1073 } | 1074 } |
| 1074 NavigationController& controller = contents->tab_contents()->GetController(); | 1075 NavigationController& controller = contents->web_contents()->GetController(); |
| 1075 | 1076 |
| 1076 // TODO(rafaelw): handle setting remaining tab properties: | 1077 // TODO(rafaelw): handle setting remaining tab properties: |
| 1077 // -title | 1078 // -title |
| 1078 // -favIconUrl | 1079 // -favIconUrl |
| 1079 | 1080 |
| 1080 // Navigate the tab to a new location if the url is different. | 1081 // Navigate the tab to a new location if the url is different. |
| 1081 std::string url_string; | 1082 std::string url_string; |
| 1082 if (update_props->HasKey(keys::kUrlKey)) { | 1083 if (update_props->HasKey(keys::kUrlKey)) { |
| 1083 EXTENSION_FUNCTION_VALIDATE(update_props->GetString( | 1084 EXTENSION_FUNCTION_VALIDATE(update_props->GetString( |
| 1084 keys::kUrlKey, &url_string)); | 1085 keys::kUrlKey, &url_string)); |
| 1085 GURL url = ResolvePossiblyRelativeURL(url_string, GetExtension()); | 1086 GURL url = ResolvePossiblyRelativeURL(url_string, GetExtension()); |
| 1086 | 1087 |
| 1087 if (!url.is_valid()) { | 1088 if (!url.is_valid()) { |
| 1088 error_ = ExtensionErrorUtils::FormatErrorMessage(keys::kInvalidUrlError, | 1089 error_ = ExtensionErrorUtils::FormatErrorMessage(keys::kInvalidUrlError, |
| 1089 url_string); | 1090 url_string); |
| 1090 return false; | 1091 return false; |
| 1091 } | 1092 } |
| 1092 | 1093 |
| 1093 // Don't let the extension crash the browser or renderers. | 1094 // Don't let the extension crash the browser or renderers. |
| 1094 if (IsCrashURL(url)) { | 1095 if (IsCrashURL(url)) { |
| 1095 error_ = keys::kNoCrashBrowserError; | 1096 error_ = keys::kNoCrashBrowserError; |
| 1096 return false; | 1097 return false; |
| 1097 } | 1098 } |
| 1098 | 1099 |
| 1099 // JavaScript URLs can do the same kinds of things as cross-origin XHR, so | 1100 // JavaScript URLs can do the same kinds of things as cross-origin XHR, so |
| 1100 // we need to check host permissions before allowing them. | 1101 // we need to check host permissions before allowing them. |
| 1101 if (url.SchemeIs(chrome::kJavaScriptScheme)) { | 1102 if (url.SchemeIs(chrome::kJavaScriptScheme)) { |
| 1102 if (!GetExtension()->CanExecuteScriptOnPage( | 1103 if (!GetExtension()->CanExecuteScriptOnPage( |
| 1103 contents->tab_contents()->GetURL(), NULL, &error_)) { | 1104 contents->web_contents()->GetURL(), NULL, &error_)) { |
| 1104 return false; | 1105 return false; |
| 1105 } | 1106 } |
| 1106 | 1107 |
| 1107 ExtensionMsg_ExecuteCode_Params params; | 1108 ExtensionMsg_ExecuteCode_Params params; |
| 1108 params.request_id = request_id(); | 1109 params.request_id = request_id(); |
| 1109 params.extension_id = extension_id(); | 1110 params.extension_id = extension_id(); |
| 1110 params.is_javascript = true; | 1111 params.is_javascript = true; |
| 1111 params.code = url.path(); | 1112 params.code = url.path(); |
| 1112 params.all_frames = false; | 1113 params.all_frames = false; |
| 1113 params.in_main_world = true; | 1114 params.in_main_world = true; |
| 1114 | 1115 |
| 1115 RenderViewHost* render_view_host = | 1116 RenderViewHost* render_view_host = |
| 1116 contents->tab_contents()->GetRenderViewHost(); | 1117 contents->web_contents()->GetRenderViewHost(); |
| 1117 render_view_host->Send( | 1118 render_view_host->Send( |
| 1118 new ExtensionMsg_ExecuteCode(render_view_host->routing_id(), | 1119 new ExtensionMsg_ExecuteCode(render_view_host->routing_id(), |
| 1119 params)); | 1120 params)); |
| 1120 | 1121 |
| 1121 Observe(contents->tab_contents()); | 1122 Observe(contents->web_contents()); |
| 1122 AddRef(); // balanced in Observe() | 1123 AddRef(); // balanced in Observe() |
| 1123 | 1124 |
| 1124 return true; | 1125 return true; |
| 1125 } | 1126 } |
| 1126 | 1127 |
| 1127 controller.LoadURL( | 1128 controller.LoadURL( |
| 1128 url, content::Referrer(), content::PAGE_TRANSITION_LINK, std::string()); | 1129 url, content::Referrer(), content::PAGE_TRANSITION_LINK, std::string()); |
| 1129 | 1130 |
| 1130 // The URL of a tab contents never actually changes to a JavaScript URL, so | 1131 // The URL of a tab contents never actually changes to a JavaScript URL, so |
| 1131 // this check only makes sense in other cases. | 1132 // this check only makes sense in other cases. |
| 1132 if (!url.SchemeIs(chrome::kJavaScriptScheme)) | 1133 if (!url.SchemeIs(chrome::kJavaScriptScheme)) |
| 1133 DCHECK_EQ(url.spec(), contents->tab_contents()->GetURL().spec()); | 1134 DCHECK_EQ(url.spec(), contents->web_contents()->GetURL().spec()); |
| 1134 } | 1135 } |
| 1135 | 1136 |
| 1136 bool active = false; | 1137 bool active = false; |
| 1137 // TODO(rafaelw): Setting |active| from js doesn't make much sense. | 1138 // TODO(rafaelw): Setting |active| from js doesn't make much sense. |
| 1138 // Move tab selection management up to window. | 1139 // Move tab selection management up to window. |
| 1139 if (update_props->HasKey(keys::kSelectedKey)) | 1140 if (update_props->HasKey(keys::kSelectedKey)) |
| 1140 EXTENSION_FUNCTION_VALIDATE(update_props->GetBoolean( | 1141 EXTENSION_FUNCTION_VALIDATE(update_props->GetBoolean( |
| 1141 keys::kSelectedKey, &active)); | 1142 keys::kSelectedKey, &active)); |
| 1142 | 1143 |
| 1143 // The 'active' property has replaced 'selected'. | 1144 // The 'active' property has replaced 'selected'. |
| 1144 if (update_props->HasKey(keys::kActiveKey)) | 1145 if (update_props->HasKey(keys::kActiveKey)) |
| 1145 EXTENSION_FUNCTION_VALIDATE(update_props->GetBoolean( | 1146 EXTENSION_FUNCTION_VALIDATE(update_props->GetBoolean( |
| 1146 keys::kActiveKey, &active)); | 1147 keys::kActiveKey, &active)); |
| 1147 | 1148 |
| 1148 if (active) { | 1149 if (active) { |
| 1149 if (tab_strip->active_index() != tab_index) { | 1150 if (tab_strip->active_index() != tab_index) { |
| 1150 tab_strip->ActivateTabAt(tab_index, false); | 1151 tab_strip->ActivateTabAt(tab_index, false); |
| 1151 DCHECK_EQ(contents, tab_strip->GetActiveTabContents()); | 1152 DCHECK_EQ(contents, tab_strip->GetActiveTabContents()); |
| 1152 } | 1153 } |
| 1153 contents->tab_contents()->Focus(); | 1154 contents->web_contents()->Focus(); |
| 1154 } | 1155 } |
| 1155 | 1156 |
| 1156 bool highlighted = false; | 1157 bool highlighted = false; |
| 1157 if (update_props->HasKey(keys::kHighlightedKey)) { | 1158 if (update_props->HasKey(keys::kHighlightedKey)) { |
| 1158 EXTENSION_FUNCTION_VALIDATE(update_props->GetBoolean( | 1159 EXTENSION_FUNCTION_VALIDATE(update_props->GetBoolean( |
| 1159 keys::kHighlightedKey, &highlighted)); | 1160 keys::kHighlightedKey, &highlighted)); |
| 1160 if (highlighted != tab_strip->IsTabSelected(tab_index)) | 1161 if (highlighted != tab_strip->IsTabSelected(tab_index)) |
| 1161 tab_strip->ToggleSelectionAt(tab_index); | 1162 tab_strip->ToggleSelectionAt(tab_index); |
| 1162 } | 1163 } |
| 1163 | 1164 |
| 1164 bool pinned = false; | 1165 bool pinned = false; |
| 1165 if (update_props->HasKey(keys::kPinnedKey)) { | 1166 if (update_props->HasKey(keys::kPinnedKey)) { |
| 1166 EXTENSION_FUNCTION_VALIDATE(update_props->GetBoolean(keys::kPinnedKey, | 1167 EXTENSION_FUNCTION_VALIDATE(update_props->GetBoolean(keys::kPinnedKey, |
| 1167 &pinned)); | 1168 &pinned)); |
| 1168 tab_strip->SetTabPinned(tab_index, pinned); | 1169 tab_strip->SetTabPinned(tab_index, pinned); |
| 1169 | 1170 |
| 1170 // Update the tab index because it may move when being pinned. | 1171 // Update the tab index because it may move when being pinned. |
| 1171 tab_index = tab_strip->GetIndexOfTabContents(contents); | 1172 tab_index = tab_strip->GetIndexOfTabContents(contents); |
| 1172 } | 1173 } |
| 1173 | 1174 |
| 1174 if (has_callback()) { | 1175 if (has_callback()) { |
| 1175 if (GetExtension()->HasAPIPermission(ExtensionAPIPermission::kTab)) { | 1176 if (GetExtension()->HasAPIPermission(ExtensionAPIPermission::kTab)) { |
| 1176 result_.reset(ExtensionTabUtil::CreateTabValue(contents->tab_contents(), | 1177 result_.reset(ExtensionTabUtil::CreateTabValue(contents->web_contents(), |
| 1177 tab_strip, | 1178 tab_strip, |
| 1178 tab_index)); | 1179 tab_index)); |
| 1179 } else { | 1180 } else { |
| 1180 result_.reset(Value::CreateNullValue()); | 1181 result_.reset(Value::CreateNullValue()); |
| 1181 } | 1182 } |
| 1182 } | 1183 } |
| 1183 | 1184 |
| 1184 SendResponse(true); | 1185 SendResponse(true); |
| 1185 return true; | 1186 return true; |
| 1186 } | 1187 } |
| (...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1294 // Clamp move location to the last position. | 1295 // Clamp move location to the last position. |
| 1295 // This is ">" because it can append to a new index position. | 1296 // This is ">" because it can append to a new index position. |
| 1296 if (new_index > target_tab_strip->count()) | 1297 if (new_index > target_tab_strip->count()) |
| 1297 new_index = target_tab_strip->count(); | 1298 new_index = target_tab_strip->count(); |
| 1298 | 1299 |
| 1299 target_tab_strip->InsertTabContentsAt( | 1300 target_tab_strip->InsertTabContentsAt( |
| 1300 new_index, contents, TabStripModel::ADD_NONE); | 1301 new_index, contents, TabStripModel::ADD_NONE); |
| 1301 | 1302 |
| 1302 if (has_callback()) | 1303 if (has_callback()) |
| 1303 tab_values.Append(ExtensionTabUtil::CreateTabValue( | 1304 tab_values.Append(ExtensionTabUtil::CreateTabValue( |
| 1304 contents->tab_contents(), target_tab_strip, new_index)); | 1305 contents->web_contents(), target_tab_strip, new_index)); |
| 1305 | 1306 |
| 1306 continue; | 1307 continue; |
| 1307 } | 1308 } |
| 1308 } | 1309 } |
| 1309 | 1310 |
| 1310 // Perform a simple within-window move. | 1311 // Perform a simple within-window move. |
| 1311 // Clamp move location to the last position. | 1312 // Clamp move location to the last position. |
| 1312 // This is ">=" because the move must be to an existing location. | 1313 // This is ">=" because the move must be to an existing location. |
| 1313 if (new_index >= source_tab_strip->count()) | 1314 if (new_index >= source_tab_strip->count()) |
| 1314 new_index = source_tab_strip->count() - 1; | 1315 new_index = source_tab_strip->count() - 1; |
| 1315 | 1316 |
| 1316 if (new_index != tab_index) | 1317 if (new_index != tab_index) |
| 1317 source_tab_strip->MoveTabContentsAt(tab_index, new_index, false); | 1318 source_tab_strip->MoveTabContentsAt(tab_index, new_index, false); |
| 1318 | 1319 |
| 1319 if (has_callback()) | 1320 if (has_callback()) |
| 1320 tab_values.Append(ExtensionTabUtil::CreateTabValue( | 1321 tab_values.Append(ExtensionTabUtil::CreateTabValue( |
| 1321 contents->tab_contents(), source_tab_strip, new_index)); | 1322 contents->web_contents(), source_tab_strip, new_index)); |
| 1322 } | 1323 } |
| 1323 | 1324 |
| 1324 if (!has_callback()) | 1325 if (!has_callback()) |
| 1325 return true; | 1326 return true; |
| 1326 | 1327 |
| 1327 // Only return the results as an array if there are multiple tabs. | 1328 // Only return the results as an array if there are multiple tabs. |
| 1328 if (tab_ids.size() > 1) { | 1329 if (tab_ids.size() > 1) { |
| 1329 result_.reset(tab_values.DeepCopy()); | 1330 result_.reset(tab_values.DeepCopy()); |
| 1330 } else if (tab_ids.size() == 1) { | 1331 } else if (tab_ids.size() == 1) { |
| 1331 Value* value = NULL; | 1332 Value* value = NULL; |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1368 } else { | 1369 } else { |
| 1369 int tab_id = -1; | 1370 int tab_id = -1; |
| 1370 EXTENSION_FUNCTION_VALIDATE(tab_value->GetAsInteger(&tab_id)); | 1371 EXTENSION_FUNCTION_VALIDATE(tab_value->GetAsInteger(&tab_id)); |
| 1371 | 1372 |
| 1372 Browser* browser = NULL; | 1373 Browser* browser = NULL; |
| 1373 if (!GetTabById(tab_id, profile(), include_incognito(), | 1374 if (!GetTabById(tab_id, profile(), include_incognito(), |
| 1374 &browser, NULL, &contents, NULL, &error_)) | 1375 &browser, NULL, &contents, NULL, &error_)) |
| 1375 return false; | 1376 return false; |
| 1376 } | 1377 } |
| 1377 | 1378 |
| 1378 TabContents* tab_contents = contents->tab_contents(); | 1379 WebContents* web_contents = contents->web_contents(); |
| 1379 if (tab_contents->ShowingInterstitialPage()) { | 1380 if (web_contents->ShowingInterstitialPage()) { |
| 1380 // This does as same as Browser::ReloadInternal. | 1381 // This does as same as Browser::ReloadInternal. |
| 1381 NavigationEntry* entry = tab_contents->GetController().GetActiveEntry(); | 1382 NavigationEntry* entry = web_contents->GetController().GetActiveEntry(); |
| 1382 OpenURLParams params(entry->GetURL(), Referrer(), CURRENT_TAB, | 1383 OpenURLParams params(entry->GetURL(), Referrer(), CURRENT_TAB, |
| 1383 content::PAGE_TRANSITION_RELOAD, false); | 1384 content::PAGE_TRANSITION_RELOAD, false); |
| 1384 GetCurrentBrowser()->OpenURL(params); | 1385 GetCurrentBrowser()->OpenURL(params); |
| 1385 } else if (bypass_cache) { | 1386 } else if (bypass_cache) { |
| 1386 tab_contents->GetController().ReloadIgnoringCache(true); | 1387 web_contents->GetController().ReloadIgnoringCache(true); |
| 1387 } else { | 1388 } else { |
| 1388 tab_contents->GetController().Reload(true); | 1389 web_contents->GetController().Reload(true); |
| 1389 } | 1390 } |
| 1390 | 1391 |
| 1391 return true; | 1392 return true; |
| 1392 } | 1393 } |
| 1393 | 1394 |
| 1394 bool RemoveTabsFunction::RunImpl() { | 1395 bool RemoveTabsFunction::RunImpl() { |
| 1395 Value* tab_value = NULL; | 1396 Value* tab_value = NULL; |
| 1396 EXTENSION_FUNCTION_VALIDATE(args_->Get(0, &tab_value)); | 1397 EXTENSION_FUNCTION_VALIDATE(args_->Get(0, &tab_value)); |
| 1397 | 1398 |
| 1398 std::vector<int> tab_ids; | 1399 std::vector<int> tab_ids; |
| (...skipping 10 matching lines...) Expand all Loading... |
| 1409 if (!browser->IsTabStripEditable()) { | 1410 if (!browser->IsTabStripEditable()) { |
| 1410 error_ = keys::kTabStripNotEditableError; | 1411 error_ = keys::kTabStripNotEditableError; |
| 1411 return false; | 1412 return false; |
| 1412 } | 1413 } |
| 1413 | 1414 |
| 1414 // Close the tab in this convoluted way, since there's a chance that the tab | 1415 // Close the tab in this convoluted way, since there's a chance that the tab |
| 1415 // is being dragged, or we're in some other nested event loop. This code | 1416 // is being dragged, or we're in some other nested event loop. This code |
| 1416 // path should ensure that the tab is safely closed under such | 1417 // path should ensure that the tab is safely closed under such |
| 1417 // circumstances, whereas |Browser::CloseTabContents()| does not. | 1418 // circumstances, whereas |Browser::CloseTabContents()| does not. |
| 1418 RenderViewHost* render_view_host = | 1419 RenderViewHost* render_view_host = |
| 1419 contents->tab_contents()->GetRenderViewHost(); | 1420 contents->web_contents()->GetRenderViewHost(); |
| 1420 render_view_host->delegate()->Close(render_view_host); | 1421 render_view_host->delegate()->Close(render_view_host); |
| 1421 } | 1422 } |
| 1422 return true; | 1423 return true; |
| 1423 } | 1424 } |
| 1424 | 1425 |
| 1425 bool CaptureVisibleTabFunction::RunImpl() { | 1426 bool CaptureVisibleTabFunction::RunImpl() { |
| 1426 Browser* browser = NULL; | 1427 Browser* browser = NULL; |
| 1427 // windowId defaults to "current" window. | 1428 // windowId defaults to "current" window. |
| 1428 int window_id = -1; | 1429 int window_id = -1; |
| 1429 | 1430 |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1461 EXTENSION_FUNCTION_VALIDATE(0); | 1462 EXTENSION_FUNCTION_VALIDATE(0); |
| 1462 } | 1463 } |
| 1463 } | 1464 } |
| 1464 | 1465 |
| 1465 if (options->HasKey(keys::kQualityKey)) { | 1466 if (options->HasKey(keys::kQualityKey)) { |
| 1466 EXTENSION_FUNCTION_VALIDATE( | 1467 EXTENSION_FUNCTION_VALIDATE( |
| 1467 options->GetInteger(keys::kQualityKey, &image_quality_)); | 1468 options->GetInteger(keys::kQualityKey, &image_quality_)); |
| 1468 } | 1469 } |
| 1469 } | 1470 } |
| 1470 | 1471 |
| 1471 TabContents* tab_contents = browser->GetSelectedTabContents(); | 1472 WebContents* web_contents = browser->GetSelectedWebContents(); |
| 1472 if (!tab_contents) { | 1473 if (!web_contents) { |
| 1473 error_ = keys::kInternalVisibleTabCaptureError; | 1474 error_ = keys::kInternalVisibleTabCaptureError; |
| 1474 return false; | 1475 return false; |
| 1475 } | 1476 } |
| 1476 | 1477 |
| 1477 // captureVisibleTab() can return an image containing sensitive information | 1478 // captureVisibleTab() can return an image containing sensitive information |
| 1478 // that the browser would otherwise protect. Ensure the extension has | 1479 // that the browser would otherwise protect. Ensure the extension has |
| 1479 // permission to do this. | 1480 // permission to do this. |
| 1480 if (!GetExtension()->CanCaptureVisiblePage(tab_contents->GetURL(), &error_)) | 1481 if (!GetExtension()->CanCaptureVisiblePage(web_contents->GetURL(), &error_)) |
| 1481 return false; | 1482 return false; |
| 1482 | 1483 |
| 1483 RenderViewHost* render_view_host = tab_contents->GetRenderViewHost(); | 1484 RenderViewHost* render_view_host = web_contents->GetRenderViewHost(); |
| 1484 | 1485 |
| 1485 // If a backing store is cached for the tab we want to capture, | 1486 // If a backing store is cached for the tab we want to capture, |
| 1486 // and it can be copied into a bitmap, then use it to generate the image. | 1487 // and it can be copied into a bitmap, then use it to generate the image. |
| 1487 BackingStore* backing_store = render_view_host->GetBackingStore(false); | 1488 BackingStore* backing_store = render_view_host->GetBackingStore(false); |
| 1488 if (backing_store && CaptureSnapshotFromBackingStore(backing_store)) | 1489 if (backing_store && CaptureSnapshotFromBackingStore(backing_store)) |
| 1489 return true; | 1490 return true; |
| 1490 | 1491 |
| 1491 // Ask the renderer for a snapshot of the tab. | 1492 // Ask the renderer for a snapshot of the tab. |
| 1492 TabContentsWrapper* wrapper = browser->GetSelectedTabContentsWrapper(); | 1493 TabContentsWrapper* wrapper = browser->GetSelectedTabContentsWrapper(); |
| 1493 wrapper->snapshot_tab_helper()->CaptureSnapshot(); | 1494 wrapper->snapshot_tab_helper()->CaptureSnapshot(); |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1607 return false; | 1608 return false; |
| 1608 } else { | 1609 } else { |
| 1609 browser = GetCurrentBrowser(); | 1610 browser = GetCurrentBrowser(); |
| 1610 if (!browser) | 1611 if (!browser) |
| 1611 return false; | 1612 return false; |
| 1612 contents = browser->tabstrip_model()->GetActiveTabContents(); | 1613 contents = browser->tabstrip_model()->GetActiveTabContents(); |
| 1613 if (!contents) | 1614 if (!contents) |
| 1614 return false; | 1615 return false; |
| 1615 } | 1616 } |
| 1616 | 1617 |
| 1617 if (contents->tab_contents()->GetController().NeedsReload()) { | 1618 if (contents->web_contents()->GetController().NeedsReload()) { |
| 1618 // If the tab hasn't been loaded, don't wait for the tab to load. | 1619 // If the tab hasn't been loaded, don't wait for the tab to load. |
| 1619 error_ = keys::kCannotDetermineLanguageOfUnloadedTab; | 1620 error_ = keys::kCannotDetermineLanguageOfUnloadedTab; |
| 1620 return false; | 1621 return false; |
| 1621 } | 1622 } |
| 1622 | 1623 |
| 1623 AddRef(); // Balanced in GotLanguage() | 1624 AddRef(); // Balanced in GotLanguage() |
| 1624 | 1625 |
| 1625 TranslateTabHelper* helper = contents->translate_tab_helper(); | 1626 TranslateTabHelper* helper = contents->translate_tab_helper(); |
| 1626 if (!helper->language_state().original_language().empty()) { | 1627 if (!helper->language_state().original_language().empty()) { |
| 1627 // Delay the callback invocation until after the current JS call has | 1628 // Delay the callback invocation until after the current JS call has |
| 1628 // returned. | 1629 // returned. |
| 1629 MessageLoop::current()->PostTask(FROM_HERE, base::Bind( | 1630 MessageLoop::current()->PostTask(FROM_HERE, base::Bind( |
| 1630 &DetectTabLanguageFunction::GotLanguage, this, | 1631 &DetectTabLanguageFunction::GotLanguage, this, |
| 1631 helper->language_state().original_language())); | 1632 helper->language_state().original_language())); |
| 1632 return true; | 1633 return true; |
| 1633 } | 1634 } |
| 1634 // The tab contents does not know its language yet. Let's wait until it | 1635 // The tab contents does not know its language yet. Let's wait until it |
| 1635 // receives it, or until the tab is closed/navigates to some other page. | 1636 // receives it, or until the tab is closed/navigates to some other page. |
| 1636 registrar_.Add(this, chrome::NOTIFICATION_TAB_LANGUAGE_DETERMINED, | 1637 registrar_.Add(this, chrome::NOTIFICATION_TAB_LANGUAGE_DETERMINED, |
| 1637 content::Source<WebContents>(contents->tab_contents())); | 1638 content::Source<WebContents>(contents->web_contents())); |
| 1638 registrar_.Add( | 1639 registrar_.Add( |
| 1639 this, content::NOTIFICATION_TAB_CLOSING, | 1640 this, content::NOTIFICATION_TAB_CLOSING, |
| 1640 content::Source<NavigationController>( | 1641 content::Source<NavigationController>( |
| 1641 &(contents->tab_contents()->GetController()))); | 1642 &(contents->web_contents()->GetController()))); |
| 1642 registrar_.Add( | 1643 registrar_.Add( |
| 1643 this, content::NOTIFICATION_NAV_ENTRY_COMMITTED, | 1644 this, content::NOTIFICATION_NAV_ENTRY_COMMITTED, |
| 1644 content::Source<NavigationController>( | 1645 content::Source<NavigationController>( |
| 1645 &(contents->tab_contents()->GetController()))); | 1646 &(contents->web_contents()->GetController()))); |
| 1646 return true; | 1647 return true; |
| 1647 } | 1648 } |
| 1648 | 1649 |
| 1649 void DetectTabLanguageFunction::Observe( | 1650 void DetectTabLanguageFunction::Observe( |
| 1650 int type, | 1651 int type, |
| 1651 const content::NotificationSource& source, | 1652 const content::NotificationSource& source, |
| 1652 const content::NotificationDetails& details) { | 1653 const content::NotificationDetails& details) { |
| 1653 std::string language; | 1654 std::string language; |
| 1654 if (type == chrome::NOTIFICATION_TAB_LANGUAGE_DETERMINED) | 1655 if (type == chrome::NOTIFICATION_TAB_LANGUAGE_DETERMINED) |
| 1655 language = *content::Details<std::string>(details).ptr(); | 1656 language = *content::Details<std::string>(details).ptr(); |
| 1656 | 1657 |
| 1657 registrar_.RemoveAll(); | 1658 registrar_.RemoveAll(); |
| 1658 | 1659 |
| 1659 // Call GotLanguage in all cases as we want to guarantee the callback is | 1660 // Call GotLanguage in all cases as we want to guarantee the callback is |
| 1660 // called for every API call the extension made. | 1661 // called for every API call the extension made. |
| 1661 GotLanguage(language); | 1662 GotLanguage(language); |
| 1662 } | 1663 } |
| 1663 | 1664 |
| 1664 void DetectTabLanguageFunction::GotLanguage(const std::string& language) { | 1665 void DetectTabLanguageFunction::GotLanguage(const std::string& language) { |
| 1665 result_.reset(Value::CreateStringValue(language.c_str())); | 1666 result_.reset(Value::CreateStringValue(language.c_str())); |
| 1666 SendResponse(true); | 1667 SendResponse(true); |
| 1667 | 1668 |
| 1668 Release(); // Balanced in Run() | 1669 Release(); // Balanced in Run() |
| 1669 } | 1670 } |
| OLD | NEW |