Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(269)

Side by Side Diff: chrome/browser/extensions/extension_tabs_module.cc

Issue 10383104: Extract executeScript-like functionality into a single ExtensionScriptExecutor class. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase Created 8 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 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 <limits> 8 #include <limits>
9 #include <vector> 9 #include <vector>
10 10
11 #include "base/base64.h" 11 #include "base/base64.h"
12 #include "base/bind.h" 12 #include "base/bind.h"
13 #include "base/logging.h" 13 #include "base/logging.h"
14 #include "base/memory/ref_counted_memory.h" 14 #include "base/memory/ref_counted_memory.h"
15 #include "base/message_loop.h" 15 #include "base/message_loop.h"
16 #include "base/stl_util.h" 16 #include "base/stl_util.h"
17 #include "base/string16.h" 17 #include "base/string16.h"
18 #include "base/string_number_conversions.h" 18 #include "base/string_number_conversions.h"
19 #include "base/string_util.h" 19 #include "base/string_util.h"
20 #include "base/stringprintf.h" 20 #include "base/stringprintf.h"
21 #include "base/utf_string_conversions.h" 21 #include "base/utf_string_conversions.h"
22 #include "chrome/browser/extensions/extension_function_dispatcher.h" 22 #include "chrome/browser/extensions/extension_function_dispatcher.h"
23 #include "chrome/browser/extensions/extension_host.h" 23 #include "chrome/browser/extensions/extension_host.h"
24 #include "chrome/browser/extensions/extension_service.h" 24 #include "chrome/browser/extensions/extension_service.h"
25 #include "chrome/browser/extensions/extension_tab_helper.h" 25 #include "chrome/browser/extensions/extension_tab_helper.h"
26 #include "chrome/browser/extensions/extension_tab_util.h" 26 #include "chrome/browser/extensions/extension_tab_util.h"
27 #include "chrome/browser/extensions/extension_tabs_module_constants.h" 27 #include "chrome/browser/extensions/extension_tabs_module_constants.h"
28 #include "chrome/browser/extensions/extension_window_controller.h" 28 #include "chrome/browser/extensions/extension_window_controller.h"
29 #include "chrome/browser/extensions/extension_window_list.h" 29 #include "chrome/browser/extensions/extension_window_list.h"
30 #include "chrome/browser/extensions/script_executor.h"
30 #include "chrome/browser/prefs/incognito_mode_prefs.h" 31 #include "chrome/browser/prefs/incognito_mode_prefs.h"
31 #include "chrome/browser/profiles/profile.h" 32 #include "chrome/browser/profiles/profile.h"
32 #include "chrome/browser/sessions/restore_tab_helper.h" 33 #include "chrome/browser/sessions/restore_tab_helper.h"
33 #include "chrome/browser/translate/translate_tab_helper.h" 34 #include "chrome/browser/translate/translate_tab_helper.h"
34 #include "chrome/browser/ui/browser.h" 35 #include "chrome/browser/ui/browser.h"
35 #include "chrome/browser/ui/browser_list.h" 36 #include "chrome/browser/ui/browser_list.h"
36 #include "chrome/browser/ui/browser_navigator.h" 37 #include "chrome/browser/ui/browser_navigator.h"
37 #include "chrome/browser/ui/browser_window.h" 38 #include "chrome/browser/ui/browser_window.h"
38 #include "chrome/browser/ui/extensions/shell_window.h" 39 #include "chrome/browser/ui/extensions/shell_window.h"
39 #include "chrome/browser/ui/panels/panel_manager.h" 40 #include "chrome/browser/ui/panels/panel_manager.h"
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
81 namespace GetLastFocused = extensions::api::windows::GetLastFocused; 82 namespace GetLastFocused = extensions::api::windows::GetLastFocused;
82 namespace errors = extension_manifest_errors; 83 namespace errors = extension_manifest_errors;
83 namespace keys = extension_tabs_module_constants; 84 namespace keys = extension_tabs_module_constants;
84 85
85 using content::NavigationController; 86 using content::NavigationController;
86 using content::NavigationEntry; 87 using content::NavigationEntry;
87 using content::OpenURLParams; 88 using content::OpenURLParams;
88 using content::Referrer; 89 using content::Referrer;
89 using content::RenderViewHost; 90 using content::RenderViewHost;
90 using content::WebContents; 91 using content::WebContents;
92 using extensions::ScriptExecutor;
91 93
92 const int CaptureVisibleTabFunction::kDefaultQuality = 90; 94 const int CaptureVisibleTabFunction::kDefaultQuality = 90;
93 95
94 namespace { 96 namespace {
95 97
96 // |error_message| can optionally be passed in a will be set with an appropriate 98 // |error_message| can optionally be passed in a will be set with an appropriate
97 // message if the window cannot be found by id. 99 // message if the window cannot be found by id.
98 Browser* GetBrowserInProfileWithId(Profile* profile, 100 Browser* GetBrowserInProfileWithId(Profile* profile,
99 const int window_id, 101 const int window_id,
100 bool include_incognito, 102 bool include_incognito,
(...skipping 1070 matching lines...) Expand 10 before | Expand all | Expand 10 after
1171 return false; 1173 return false;
1172 } 1174 }
1173 1175
1174 selection.set_active(active_index); 1176 selection.set_active(active_index);
1175 browser->tab_strip_model()->SetSelectionFromModel(selection); 1177 browser->tab_strip_model()->SetSelectionFromModel(selection);
1176 result_.reset( 1178 result_.reset(
1177 browser->extension_window_controller()->CreateWindowValueWithTabs()); 1179 browser->extension_window_controller()->CreateWindowValueWithTabs());
1178 return true; 1180 return true;
1179 } 1181 }
1180 1182
1181 UpdateTabFunction::UpdateTabFunction() : web_contents_(NULL) { 1183 UpdateTabFunction::UpdateTabFunction() : tab_contents_(NULL) {
1182 } 1184 }
1183 1185
1184 bool UpdateTabFunction::RunImpl() { 1186 bool UpdateTabFunction::RunImpl() {
1185 DictionaryValue* update_props = NULL; 1187 DictionaryValue* update_props = NULL;
1186 EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(1, &update_props)); 1188 EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(1, &update_props));
1187 1189
1188 Value* tab_value = NULL; 1190 Value* tab_value = NULL;
1189 if (HasOptionalArgument(0)) { 1191 if (HasOptionalArgument(0)) {
1190 EXTENSION_FUNCTION_VALIDATE(args_->Get(0, &tab_value)); 1192 EXTENSION_FUNCTION_VALIDATE(args_->Get(0, &tab_value));
1191 } 1193 }
(...skipping 16 matching lines...) Expand all
1208 EXTENSION_FUNCTION_VALIDATE(tab_value->GetAsInteger(&tab_id)); 1210 EXTENSION_FUNCTION_VALIDATE(tab_value->GetAsInteger(&tab_id));
1209 } 1211 }
1210 1212
1211 int tab_index = -1; 1213 int tab_index = -1;
1212 TabStripModel* tab_strip = NULL; 1214 TabStripModel* tab_strip = NULL;
1213 if (!GetTabById(tab_id, profile(), include_incognito(), 1215 if (!GetTabById(tab_id, profile(), include_incognito(),
1214 NULL, &tab_strip, &contents, &tab_index, &error_)) { 1216 NULL, &tab_strip, &contents, &tab_index, &error_)) {
1215 return false; 1217 return false;
1216 } 1218 }
1217 1219
1218 web_contents_ = contents->web_contents(); 1220 tab_contents_ = contents;
1219 1221
1220 // TODO(rafaelw): handle setting remaining tab properties: 1222 // TODO(rafaelw): handle setting remaining tab properties:
1221 // -title 1223 // -title
1222 // -favIconUrl 1224 // -favIconUrl
1223 1225
1224 // Navigate the tab to a new location if the url is different. 1226 // Navigate the tab to a new location if the url is different.
1225 bool is_async = false; 1227 bool is_async = false;
1226 if (!UpdateURLIfPresent(update_props, &is_async)) 1228 if (!UpdateURLIfPresent(update_props, &is_async))
1227 return false; 1229 return false;
1228 1230
1229 bool active = false; 1231 bool active = false;
1230 // TODO(rafaelw): Setting |active| from js doesn't make much sense. 1232 // TODO(rafaelw): Setting |active| from js doesn't make much sense.
1231 // Move tab selection management up to window. 1233 // Move tab selection management up to window.
1232 if (update_props->HasKey(keys::kSelectedKey)) 1234 if (update_props->HasKey(keys::kSelectedKey))
1233 EXTENSION_FUNCTION_VALIDATE(update_props->GetBoolean( 1235 EXTENSION_FUNCTION_VALIDATE(update_props->GetBoolean(
1234 keys::kSelectedKey, &active)); 1236 keys::kSelectedKey, &active));
1235 1237
1236 // The 'active' property has replaced 'selected'. 1238 // The 'active' property has replaced 'selected'.
1237 if (update_props->HasKey(keys::kActiveKey)) 1239 if (update_props->HasKey(keys::kActiveKey))
1238 EXTENSION_FUNCTION_VALIDATE(update_props->GetBoolean( 1240 EXTENSION_FUNCTION_VALIDATE(update_props->GetBoolean(
1239 keys::kActiveKey, &active)); 1241 keys::kActiveKey, &active));
1240 1242
1241 if (active) { 1243 if (active) {
1242 if (tab_strip->active_index() != tab_index) { 1244 if (tab_strip->active_index() != tab_index) {
1243 tab_strip->ActivateTabAt(tab_index, false); 1245 tab_strip->ActivateTabAt(tab_index, false);
1244 DCHECK_EQ(contents, tab_strip->GetActiveTabContents()); 1246 DCHECK_EQ(contents, tab_strip->GetActiveTabContents());
1245 } 1247 }
1246 web_contents_->Focus(); 1248 tab_contents_->web_contents()->Focus();
1247 } 1249 }
1248 1250
1249 if (update_props->HasKey(keys::kHighlightedKey)) { 1251 if (update_props->HasKey(keys::kHighlightedKey)) {
1250 bool highlighted = false; 1252 bool highlighted = false;
1251 EXTENSION_FUNCTION_VALIDATE(update_props->GetBoolean( 1253 EXTENSION_FUNCTION_VALIDATE(update_props->GetBoolean(
1252 keys::kHighlightedKey, &highlighted)); 1254 keys::kHighlightedKey, &highlighted));
1253 if (highlighted != tab_strip->IsTabSelected(tab_index)) 1255 if (highlighted != tab_strip->IsTabSelected(tab_index))
1254 tab_strip->ToggleSelectionAt(tab_index); 1256 tab_strip->ToggleSelectionAt(tab_index);
1255 } 1257 }
1256 1258
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
1306 // Don't let the extension crash the browser or renderers. 1308 // Don't let the extension crash the browser or renderers.
1307 if (ExtensionTabUtil::IsCrashURL(url)) { 1309 if (ExtensionTabUtil::IsCrashURL(url)) {
1308 error_ = keys::kNoCrashBrowserError; 1310 error_ = keys::kNoCrashBrowserError;
1309 return false; 1311 return false;
1310 } 1312 }
1311 1313
1312 // JavaScript URLs can do the same kinds of things as cross-origin XHR, so 1314 // JavaScript URLs can do the same kinds of things as cross-origin XHR, so
1313 // we need to check host permissions before allowing them. 1315 // we need to check host permissions before allowing them.
1314 if (url.SchemeIs(chrome::kJavaScriptScheme)) { 1316 if (url.SchemeIs(chrome::kJavaScriptScheme)) {
1315 if (!GetExtension()->CanExecuteScriptOnPage( 1317 if (!GetExtension()->CanExecuteScriptOnPage(
1316 web_contents_->GetURL(), NULL, &error_)) { 1318 tab_contents_->web_contents()->GetURL(), NULL, &error_)) {
1317 return false; 1319 return false;
1318 } 1320 }
1319 1321
1320 ExtensionMsg_ExecuteCode_Params params; 1322 tab_contents_->extension_script_executor()->ExecuteScript(
1321 params.request_id = request_id(); 1323 extension_id(),
1322 params.extension_id = extension_id(); 1324 ScriptExecutor::JAVASCRIPT,
1323 params.is_javascript = true; 1325 url.path(),
1324 params.code = url.path(); 1326 ScriptExecutor::TOP_FRAME,
1325 params.run_at = UserScript::DOCUMENT_IDLE; 1327 UserScript::DOCUMENT_IDLE,
1326 params.all_frames = false; 1328 ScriptExecutor::MAIN_WORLD,
1327 params.in_main_world = true; 1329 base::Bind(&UpdateTabFunction::OnExecuteCodeFinished, this));
1328
1329 RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
1330 render_view_host->Send(
1331 new ExtensionMsg_ExecuteCode(render_view_host->GetRoutingID(), params));
1332
1333 Observe(web_contents_);
1334 AddRef(); // Balanced in OnExecuteCodeFinished().
1335 1330
1336 *is_async = true; 1331 *is_async = true;
1337 return true; 1332 return true;
1338 } 1333 }
1339 1334
1340 web_contents_->GetController().LoadURL( 1335 tab_contents_->web_contents()->GetController().LoadURL(
1341 url, content::Referrer(), content::PAGE_TRANSITION_LINK, std::string()); 1336 url, content::Referrer(), content::PAGE_TRANSITION_LINK, std::string());
1342 1337
1343 // The URL of a tab contents never actually changes to a JavaScript URL, so 1338 // The URL of a tab contents never actually changes to a JavaScript URL, so
1344 // this check only makes sense in other cases. 1339 // this check only makes sense in other cases.
1345 if (!url.SchemeIs(chrome::kJavaScriptScheme)) 1340 if (!url.SchemeIs(chrome::kJavaScriptScheme))
1346 DCHECK_EQ(url.spec(), web_contents_->GetURL().spec()); 1341 DCHECK_EQ(url.spec(), tab_contents_->web_contents()->GetURL().spec());
1347 1342
1348 return true; 1343 return true;
1349 } 1344 }
1350 1345
1351 void UpdateTabFunction::PopulateResult() { 1346 void UpdateTabFunction::PopulateResult() {
1352 if (!has_callback()) 1347 if (!has_callback())
1353 return; 1348 return;
1354 1349
1355 if (GetExtension()->HasAPIPermission(ExtensionAPIPermission::kTab) && 1350 if (GetExtension()->HasAPIPermission(ExtensionAPIPermission::kTab)) {
1356 web_contents_ != NULL) { 1351 result_.reset(
1357 result_.reset(ExtensionTabUtil::CreateTabValue(web_contents_)); 1352 ExtensionTabUtil::CreateTabValue(tab_contents_->web_contents()));
1358 } else { 1353 } else {
1359 result_.reset(Value::CreateNullValue()); 1354 result_.reset(Value::CreateNullValue());
1360 } 1355 }
1361 } 1356 }
1362 1357
1363 void UpdateTabFunction::WebContentsDestroyed(WebContents* tab) { 1358 void UpdateTabFunction::OnExecuteCodeFinished(bool success,
1364 CHECK_EQ(tab, web_contents_);
1365 web_contents_ = NULL;
1366 }
1367
1368 bool UpdateTabFunction::OnMessageReceived(const IPC::Message& message) {
1369 if (message.type() != ExtensionHostMsg_ExecuteCodeFinished::ID)
1370 return false;
1371
1372 int message_request_id = -1;
1373 PickleIterator iter(message);
1374 if (!message.ReadInt(&iter, &message_request_id)) {
1375 NOTREACHED() << "malformed extension message";
1376 return true;
1377 }
1378
1379 if (message_request_id != request_id())
1380 return false;
1381
1382 IPC_BEGIN_MESSAGE_MAP(UpdateTabFunction, message)
1383 IPC_MESSAGE_HANDLER(ExtensionHostMsg_ExecuteCodeFinished,
1384 OnExecuteCodeFinished)
1385 IPC_END_MESSAGE_MAP()
1386 return true;
1387 }
1388
1389 void UpdateTabFunction::OnExecuteCodeFinished(int request_id,
1390 bool success,
1391 const std::string& error) { 1359 const std::string& error) {
1392 if (!error.empty()) { 1360 if (!error.empty()) {
1393 CHECK(!success); 1361 CHECK(!success);
1394 error_ = error; 1362 error_ = error;
1395 } 1363 }
1396 1364
1397 if (success) 1365 if (success)
1398 PopulateResult(); 1366 PopulateResult();
1399 SendResponse(success); 1367 SendResponse(success);
1400
1401 Observe(NULL);
1402 Release(); // Balanced in UpdateURLIfPresent().
1403 } 1368 }
1404 1369
1405 bool MoveTabsFunction::RunImpl() { 1370 bool MoveTabsFunction::RunImpl() {
1406 Value* tab_value = NULL; 1371 Value* tab_value = NULL;
1407 EXTENSION_FUNCTION_VALIDATE(args_->Get(0, &tab_value)); 1372 EXTENSION_FUNCTION_VALIDATE(args_->Get(0, &tab_value));
1408 1373
1409 std::vector<int> tab_ids; 1374 std::vector<int> tab_ids;
1410 EXTENSION_FUNCTION_VALIDATE(ReadOneOrMoreIntegers(tab_value, &tab_ids)); 1375 EXTENSION_FUNCTION_VALIDATE(ReadOneOrMoreIntegers(tab_value, &tab_ids));
1411 1376
1412 DictionaryValue* update_props = NULL; 1377 DictionaryValue* update_props = NULL;
(...skipping 437 matching lines...) Expand 10 before | Expand all | Expand 10 after
1850 // called for every API call the extension made. 1815 // called for every API call the extension made.
1851 GotLanguage(language); 1816 GotLanguage(language);
1852 } 1817 }
1853 1818
1854 void DetectTabLanguageFunction::GotLanguage(const std::string& language) { 1819 void DetectTabLanguageFunction::GotLanguage(const std::string& language) {
1855 result_.reset(Value::CreateStringValue(language.c_str())); 1820 result_.reset(Value::CreateStringValue(language.c_str()));
1856 SendResponse(true); 1821 SendResponse(true);
1857 1822
1858 Release(); // Balanced in Run() 1823 Release(); // Balanced in Run()
1859 } 1824 }
OLDNEW
« no previous file with comments | « chrome/browser/extensions/extension_tabs_module.h ('k') | chrome/browser/extensions/script_executor.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698