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

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: . 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 <vector> 8 #include <vector>
9 9
10 #include "base/base64.h" 10 #include "base/base64.h"
11 #include "base/bind.h" 11 #include "base/bind.h"
12 #include "base/logging.h" 12 #include "base/logging.h"
13 #include "base/memory/ref_counted_memory.h" 13 #include "base/memory/ref_counted_memory.h"
14 #include "base/message_loop.h" 14 #include "base/message_loop.h"
15 #include "base/stl_util.h" 15 #include "base/stl_util.h"
16 #include "base/string16.h" 16 #include "base/string16.h"
17 #include "base/string_number_conversions.h" 17 #include "base/string_number_conversions.h"
18 #include "base/string_util.h" 18 #include "base/string_util.h"
19 #include "base/stringprintf.h" 19 #include "base/stringprintf.h"
20 #include "base/utf_string_conversions.h" 20 #include "base/utf_string_conversions.h"
21 #include "chrome/browser/extensions/extension_function_dispatcher.h" 21 #include "chrome/browser/extensions/extension_function_dispatcher.h"
22 #include "chrome/browser/extensions/extension_host.h" 22 #include "chrome/browser/extensions/extension_host.h"
23 #include "chrome/browser/extensions/extension_service.h" 23 #include "chrome/browser/extensions/extension_service.h"
24 #include "chrome/browser/extensions/extension_tab_helper.h" 24 #include "chrome/browser/extensions/extension_tab_helper.h"
25 #include "chrome/browser/extensions/extension_tab_util.h" 25 #include "chrome/browser/extensions/extension_tab_util.h"
26 #include "chrome/browser/extensions/extension_tabs_module_constants.h" 26 #include "chrome/browser/extensions/extension_tabs_module_constants.h"
27 #include "chrome/browser/extensions/extension_window_controller.h" 27 #include "chrome/browser/extensions/extension_window_controller.h"
28 #include "chrome/browser/extensions/extension_window_list.h" 28 #include "chrome/browser/extensions/extension_window_list.h"
29 #include "chrome/browser/extensions/script_executor.h"
29 #include "chrome/browser/prefs/incognito_mode_prefs.h" 30 #include "chrome/browser/prefs/incognito_mode_prefs.h"
30 #include "chrome/browser/profiles/profile.h" 31 #include "chrome/browser/profiles/profile.h"
31 #include "chrome/browser/sessions/restore_tab_helper.h" 32 #include "chrome/browser/sessions/restore_tab_helper.h"
32 #include "chrome/browser/tabs/tab_strip_model.h" 33 #include "chrome/browser/tabs/tab_strip_model.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"
(...skipping 1130 matching lines...) Expand 10 before | Expand all | Expand 10 after
1169 return false; 1170 return false;
1170 } 1171 }
1171 1172
1172 selection.set_active(active_index); 1173 selection.set_active(active_index);
1173 browser->tabstrip_model()->SetSelectionFromModel(selection); 1174 browser->tabstrip_model()->SetSelectionFromModel(selection);
1174 result_.reset( 1175 result_.reset(
1175 browser->extension_window_controller()->CreateWindowValueWithTabs()); 1176 browser->extension_window_controller()->CreateWindowValueWithTabs());
1176 return true; 1177 return true;
1177 } 1178 }
1178 1179
1179 UpdateTabFunction::UpdateTabFunction() : web_contents_(NULL) { 1180 UpdateTabFunction::UpdateTabFunction() : tab_contents_(NULL) {
1180 } 1181 }
1181 1182
1182 bool UpdateTabFunction::RunImpl() { 1183 bool UpdateTabFunction::RunImpl() {
1183 DictionaryValue* update_props = NULL; 1184 DictionaryValue* update_props = NULL;
1184 EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(1, &update_props)); 1185 EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(1, &update_props));
1185 1186
1186 Value* tab_value = NULL; 1187 Value* tab_value = NULL;
1187 if (HasOptionalArgument(0)) { 1188 if (HasOptionalArgument(0)) {
1188 EXTENSION_FUNCTION_VALIDATE(args_->Get(0, &tab_value)); 1189 EXTENSION_FUNCTION_VALIDATE(args_->Get(0, &tab_value));
1189 } 1190 }
(...skipping 16 matching lines...) Expand all
1206 EXTENSION_FUNCTION_VALIDATE(tab_value->GetAsInteger(&tab_id)); 1207 EXTENSION_FUNCTION_VALIDATE(tab_value->GetAsInteger(&tab_id));
1207 } 1208 }
1208 1209
1209 int tab_index = -1; 1210 int tab_index = -1;
1210 TabStripModel* tab_strip = NULL; 1211 TabStripModel* tab_strip = NULL;
1211 if (!GetTabById(tab_id, profile(), include_incognito(), 1212 if (!GetTabById(tab_id, profile(), include_incognito(),
1212 NULL, &tab_strip, &contents, &tab_index, &error_)) { 1213 NULL, &tab_strip, &contents, &tab_index, &error_)) {
1213 return false; 1214 return false;
1214 } 1215 }
1215 1216
1216 web_contents_ = contents->web_contents(); 1217 tab_contents_ = contents;
1217 1218
1218 // TODO(rafaelw): handle setting remaining tab properties: 1219 // TODO(rafaelw): handle setting remaining tab properties:
1219 // -title 1220 // -title
1220 // -favIconUrl 1221 // -favIconUrl
1221 1222
1222 // Navigate the tab to a new location if the url is different. 1223 // Navigate the tab to a new location if the url is different.
1223 bool is_async = false; 1224 bool is_async = false;
1224 if (!UpdateURLIfPresent(update_props, &is_async)) 1225 if (!UpdateURLIfPresent(update_props, &is_async))
1225 return false; 1226 return false;
1226 1227
1227 bool active = false; 1228 bool active = false;
1228 // TODO(rafaelw): Setting |active| from js doesn't make much sense. 1229 // TODO(rafaelw): Setting |active| from js doesn't make much sense.
1229 // Move tab selection management up to window. 1230 // Move tab selection management up to window.
1230 if (update_props->HasKey(keys::kSelectedKey)) 1231 if (update_props->HasKey(keys::kSelectedKey))
1231 EXTENSION_FUNCTION_VALIDATE(update_props->GetBoolean( 1232 EXTENSION_FUNCTION_VALIDATE(update_props->GetBoolean(
1232 keys::kSelectedKey, &active)); 1233 keys::kSelectedKey, &active));
1233 1234
1234 // The 'active' property has replaced 'selected'. 1235 // The 'active' property has replaced 'selected'.
1235 if (update_props->HasKey(keys::kActiveKey)) 1236 if (update_props->HasKey(keys::kActiveKey))
1236 EXTENSION_FUNCTION_VALIDATE(update_props->GetBoolean( 1237 EXTENSION_FUNCTION_VALIDATE(update_props->GetBoolean(
1237 keys::kActiveKey, &active)); 1238 keys::kActiveKey, &active));
1238 1239
1239 if (active) { 1240 if (active) {
1240 if (tab_strip->active_index() != tab_index) { 1241 if (tab_strip->active_index() != tab_index) {
1241 tab_strip->ActivateTabAt(tab_index, false); 1242 tab_strip->ActivateTabAt(tab_index, false);
1242 DCHECK_EQ(contents, tab_strip->GetActiveTabContents()); 1243 DCHECK_EQ(contents, tab_strip->GetActiveTabContents());
1243 } 1244 }
1244 web_contents_->Focus(); 1245 tab_contents_->web_contents()->Focus();
1245 } 1246 }
1246 1247
1247 if (update_props->HasKey(keys::kHighlightedKey)) { 1248 if (update_props->HasKey(keys::kHighlightedKey)) {
1248 bool highlighted = false; 1249 bool highlighted = false;
1249 EXTENSION_FUNCTION_VALIDATE(update_props->GetBoolean( 1250 EXTENSION_FUNCTION_VALIDATE(update_props->GetBoolean(
1250 keys::kHighlightedKey, &highlighted)); 1251 keys::kHighlightedKey, &highlighted));
1251 if (highlighted != tab_strip->IsTabSelected(tab_index)) 1252 if (highlighted != tab_strip->IsTabSelected(tab_index))
1252 tab_strip->ToggleSelectionAt(tab_index); 1253 tab_strip->ToggleSelectionAt(tab_index);
1253 } 1254 }
1254 1255
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
1304 // Don't let the extension crash the browser or renderers. 1305 // Don't let the extension crash the browser or renderers.
1305 if (ExtensionTabUtil::IsCrashURL(url)) { 1306 if (ExtensionTabUtil::IsCrashURL(url)) {
1306 error_ = keys::kNoCrashBrowserError; 1307 error_ = keys::kNoCrashBrowserError;
1307 return false; 1308 return false;
1308 } 1309 }
1309 1310
1310 // JavaScript URLs can do the same kinds of things as cross-origin XHR, so 1311 // JavaScript URLs can do the same kinds of things as cross-origin XHR, so
1311 // we need to check host permissions before allowing them. 1312 // we need to check host permissions before allowing them.
1312 if (url.SchemeIs(chrome::kJavaScriptScheme)) { 1313 if (url.SchemeIs(chrome::kJavaScriptScheme)) {
1313 if (!GetExtension()->CanExecuteScriptOnPage( 1314 if (!GetExtension()->CanExecuteScriptOnPage(
1314 web_contents_->GetURL(), NULL, &error_)) { 1315 tab_contents_->web_contents()->GetURL(), NULL, &error_)) {
1315 return false; 1316 return false;
1316 } 1317 }
1317 1318
1318 ExtensionMsg_ExecuteCode_Params params; 1319 tab_contents_->extensions_script_executor()->ExecuteScript(
1319 params.request_id = request_id(); 1320 extension_id(),
1320 params.extension_id = extension_id(); 1321 true,
1321 params.is_javascript = true; 1322 url.path(),
1322 params.code = url.path(); 1323 false,
1323 params.run_at = UserScript::DOCUMENT_IDLE; 1324 UserScript::DOCUMENT_IDLE,
1324 params.all_frames = false; 1325 true,
1325 params.in_main_world = true; 1326 base::Bind(&UpdateTabFunction::OnExecuteCodeFinished, this));
1326
1327 RenderViewHost* render_view_host = web_contents_->GetRenderViewHost();
1328 render_view_host->Send(
1329 new ExtensionMsg_ExecuteCode(render_view_host->GetRoutingID(), params));
1330
1331 Observe(web_contents_);
1332 AddRef(); // Balanced in OnExecuteCodeFinished().
1333 1327
1334 *is_async = true; 1328 *is_async = true;
1335 return true; 1329 return true;
1336 } 1330 }
1337 1331
1338 web_contents_->GetController().LoadURL( 1332 tab_contents_->web_contents()->GetController().LoadURL(
1339 url, content::Referrer(), content::PAGE_TRANSITION_LINK, std::string()); 1333 url, content::Referrer(), content::PAGE_TRANSITION_LINK, std::string());
1340 1334
1341 // The URL of a tab contents never actually changes to a JavaScript URL, so 1335 // The URL of a tab contents never actually changes to a JavaScript URL, so
1342 // this check only makes sense in other cases. 1336 // this check only makes sense in other cases.
1343 if (!url.SchemeIs(chrome::kJavaScriptScheme)) 1337 if (!url.SchemeIs(chrome::kJavaScriptScheme))
1344 DCHECK_EQ(url.spec(), web_contents_->GetURL().spec()); 1338 DCHECK_EQ(url.spec(), tab_contents_->web_contents()->GetURL().spec());
1345 1339
1346 return true; 1340 return true;
1347 } 1341 }
1348 1342
1349 void UpdateTabFunction::PopulateResult() { 1343 void UpdateTabFunction::PopulateResult() {
1350 if (!has_callback()) 1344 if (!has_callback())
1351 return; 1345 return;
1352 1346
1353 if (GetExtension()->HasAPIPermission(ExtensionAPIPermission::kTab) && 1347 if (GetExtension()->HasAPIPermission(ExtensionAPIPermission::kTab)) {
1354 web_contents_ != NULL) { 1348 result_.reset(
1355 result_.reset(ExtensionTabUtil::CreateTabValue(web_contents_)); 1349 ExtensionTabUtil::CreateTabValue(tab_contents_->web_contents()));
1356 } else { 1350 } else {
1357 result_.reset(Value::CreateNullValue()); 1351 result_.reset(Value::CreateNullValue());
1358 } 1352 }
1359 } 1353 }
1360 1354
1361 void UpdateTabFunction::WebContentsDestroyed(WebContents* tab) { 1355 void UpdateTabFunction::OnExecuteCodeFinished(bool success,
1362 CHECK_EQ(tab, web_contents_);
1363 web_contents_ = NULL;
1364 }
1365
1366 bool UpdateTabFunction::OnMessageReceived(const IPC::Message& message) {
1367 if (message.type() != ExtensionHostMsg_ExecuteCodeFinished::ID)
1368 return false;
1369
1370 int message_request_id = -1;
1371 PickleIterator iter(message);
1372 if (!message.ReadInt(&iter, &message_request_id)) {
1373 NOTREACHED() << "malformed extension message";
1374 return true;
1375 }
1376
1377 if (message_request_id != request_id())
1378 return false;
1379
1380 IPC_BEGIN_MESSAGE_MAP(UpdateTabFunction, message)
1381 IPC_MESSAGE_HANDLER(ExtensionHostMsg_ExecuteCodeFinished,
1382 OnExecuteCodeFinished)
1383 IPC_END_MESSAGE_MAP()
1384 return true;
1385 }
1386
1387 void UpdateTabFunction::OnExecuteCodeFinished(int request_id,
1388 bool success,
1389 const std::string& error) { 1356 const std::string& error) {
1390 if (!error.empty()) { 1357 if (!error.empty()) {
1391 CHECK(!success); 1358 CHECK(!success);
1392 error_ = error; 1359 error_ = error;
1393 } 1360 }
1394 1361
1395 if (success) 1362 if (success)
1396 PopulateResult(); 1363 PopulateResult();
1397 SendResponse(success); 1364 SendResponse(success);
1398
1399 Observe(NULL);
1400 Release(); // Balanced in UpdateURLIfPresent().
1401 } 1365 }
1402 1366
1403 bool MoveTabsFunction::RunImpl() { 1367 bool MoveTabsFunction::RunImpl() {
1404 Value* tab_value = NULL; 1368 Value* tab_value = NULL;
1405 EXTENSION_FUNCTION_VALIDATE(args_->Get(0, &tab_value)); 1369 EXTENSION_FUNCTION_VALIDATE(args_->Get(0, &tab_value));
1406 1370
1407 std::vector<int> tab_ids; 1371 std::vector<int> tab_ids;
1408 EXTENSION_FUNCTION_VALIDATE(ReadOneOrMoreIntegers(tab_value, &tab_ids)); 1372 EXTENSION_FUNCTION_VALIDATE(ReadOneOrMoreIntegers(tab_value, &tab_ids));
1409 1373
1410 DictionaryValue* update_props = NULL; 1374 DictionaryValue* update_props = NULL;
(...skipping 436 matching lines...) Expand 10 before | Expand all | Expand 10 after
1847 // called for every API call the extension made. 1811 // called for every API call the extension made.
1848 GotLanguage(language); 1812 GotLanguage(language);
1849 } 1813 }
1850 1814
1851 void DetectTabLanguageFunction::GotLanguage(const std::string& language) { 1815 void DetectTabLanguageFunction::GotLanguage(const std::string& language) {
1852 result_.reset(Value::CreateStringValue(language.c_str())); 1816 result_.reset(Value::CreateStringValue(language.c_str()));
1853 SendResponse(true); 1817 SendResponse(true);
1854 1818
1855 Release(); // Balanced in Run() 1819 Release(); // Balanced in Run()
1856 } 1820 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698