OLD | NEW |
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/api/developer_private/developer_private_api.
h" | 5 #include "chrome/browser/extensions/api/developer_private/developer_private_api.
h" |
6 | 6 |
7 #include "apps/app_load_service.h" | 7 #include "apps/app_load_service.h" |
8 #include "apps/saved_files_service.h" | 8 #include "apps/saved_files_service.h" |
9 #include "base/base64.h" | 9 #include "base/base64.h" |
10 #include "base/bind.h" | 10 #include "base/bind.h" |
11 #include "base/command_line.h" | 11 #include "base/command_line.h" |
12 #include "base/files/file_enumerator.h" | 12 #include "base/files/file_enumerator.h" |
13 #include "base/files/file_util.h" | 13 #include "base/files/file_util.h" |
14 #include "base/i18n/file_util_icu.h" | 14 #include "base/i18n/file_util_icu.h" |
15 #include "base/lazy_instance.h" | 15 #include "base/lazy_instance.h" |
16 #include "base/strings/string_number_conversions.h" | 16 #include "base/strings/string_number_conversions.h" |
| 17 #include "base/strings/stringprintf.h" |
17 #include "base/strings/utf_string_conversions.h" | 18 #include "base/strings/utf_string_conversions.h" |
18 #include "base/values.h" | 19 #include "base/values.h" |
19 #include "chrome/browser/devtools/devtools_window.h" | 20 #include "chrome/browser/devtools/devtools_window.h" |
20 #include "chrome/browser/extensions/api/developer_private/entry_picker.h" | 21 #include "chrome/browser/extensions/api/developer_private/entry_picker.h" |
21 #include "chrome/browser/extensions/api/extension_action/extension_action_api.h" | 22 #include "chrome/browser/extensions/api/extension_action/extension_action_api.h" |
22 #include "chrome/browser/extensions/api/file_handlers/app_file_handler_util.h" | 23 #include "chrome/browser/extensions/api/file_handlers/app_file_handler_util.h" |
23 #include "chrome/browser/extensions/chrome_requirements_checker.h" | 24 #include "chrome/browser/extensions/chrome_requirements_checker.h" |
24 #include "chrome/browser/extensions/devtools_util.h" | 25 #include "chrome/browser/extensions/devtools_util.h" |
25 #include "chrome/browser/extensions/extension_disabled_ui.h" | 26 #include "chrome/browser/extensions/extension_disabled_ui.h" |
26 #include "chrome/browser/extensions/extension_error_reporter.h" | 27 #include "chrome/browser/extensions/extension_error_reporter.h" |
27 #include "chrome/browser/extensions/extension_service.h" | 28 #include "chrome/browser/extensions/extension_service.h" |
28 #include "chrome/browser/extensions/extension_ui_util.h" | 29 #include "chrome/browser/extensions/extension_ui_util.h" |
29 #include "chrome/browser/extensions/extension_util.h" | 30 #include "chrome/browser/extensions/extension_util.h" |
30 #include "chrome/browser/extensions/unpacked_installer.h" | 31 #include "chrome/browser/extensions/unpacked_installer.h" |
31 #include "chrome/browser/extensions/updater/extension_updater.h" | 32 #include "chrome/browser/extensions/updater/extension_updater.h" |
32 #include "chrome/browser/platform_util.h" | 33 #include "chrome/browser/platform_util.h" |
33 #include "chrome/browser/profiles/profile.h" | 34 #include "chrome/browser/profiles/profile.h" |
34 #include "chrome/browser/sync_file_system/syncable_file_system_util.h" | 35 #include "chrome/browser/sync_file_system/syncable_file_system_util.h" |
| 36 #include "chrome/browser/ui/browser_finder.h" |
35 #include "chrome/browser/ui/chrome_select_file_policy.h" | 37 #include "chrome/browser/ui/chrome_select_file_policy.h" |
36 #include "chrome/browser/ui/webui/extensions/extension_error_ui_util.h" | 38 #include "chrome/browser/ui/tabs/tab_strip_model.h" |
37 #include "chrome/browser/ui/webui/extensions/extension_icon_source.h" | 39 #include "chrome/browser/ui/webui/extensions/extension_icon_source.h" |
38 #include "chrome/common/extensions/api/developer_private.h" | 40 #include "chrome/common/extensions/api/developer_private.h" |
39 #include "chrome/common/extensions/manifest_handlers/app_launch_info.h" | 41 #include "chrome/common/extensions/manifest_handlers/app_launch_info.h" |
40 #include "chrome/common/url_constants.h" | 42 #include "chrome/common/url_constants.h" |
41 #include "chrome/grit/generated_resources.h" | 43 #include "chrome/grit/generated_resources.h" |
42 #include "content/public/browser/browser_thread.h" | 44 #include "content/public/browser/browser_thread.h" |
43 #include "content/public/browser/notification_service.h" | 45 #include "content/public/browser/notification_service.h" |
44 #include "content/public/browser/render_process_host.h" | 46 #include "content/public/browser/render_process_host.h" |
45 #include "content/public/browser/render_view_host.h" | 47 #include "content/public/browser/render_view_host.h" |
46 #include "content/public/browser/site_instance.h" | 48 #include "content/public/browser/site_instance.h" |
47 #include "content/public/browser/storage_partition.h" | 49 #include "content/public/browser/storage_partition.h" |
48 #include "content/public/browser/web_contents.h" | 50 #include "content/public/browser/web_contents.h" |
49 #include "extensions/browser/api/device_permissions_manager.h" | 51 #include "extensions/browser/api/device_permissions_manager.h" |
50 #include "extensions/browser/app_window/app_window.h" | 52 #include "extensions/browser/app_window/app_window.h" |
51 #include "extensions/browser/app_window/app_window_registry.h" | 53 #include "extensions/browser/app_window/app_window_registry.h" |
52 #include "extensions/browser/extension_error.h" | 54 #include "extensions/browser/extension_error.h" |
53 #include "extensions/browser/extension_prefs.h" | 55 #include "extensions/browser/extension_prefs.h" |
54 #include "extensions/browser/extension_registry.h" | 56 #include "extensions/browser/extension_registry.h" |
55 #include "extensions/browser/extension_system.h" | 57 #include "extensions/browser/extension_system.h" |
| 58 #include "extensions/browser/file_highlighter.h" |
56 #include "extensions/browser/management_policy.h" | 59 #include "extensions/browser/management_policy.h" |
57 #include "extensions/browser/notification_types.h" | 60 #include "extensions/browser/notification_types.h" |
58 #include "extensions/browser/view_type_utils.h" | 61 #include "extensions/browser/view_type_utils.h" |
59 #include "extensions/common/constants.h" | 62 #include "extensions/common/constants.h" |
60 #include "extensions/common/extension_resource.h" | 63 #include "extensions/common/extension_resource.h" |
61 #include "extensions/common/extension_set.h" | 64 #include "extensions/common/extension_set.h" |
62 #include "extensions/common/install_warning.h" | 65 #include "extensions/common/install_warning.h" |
63 #include "extensions/common/manifest.h" | 66 #include "extensions/common/manifest.h" |
64 #include "extensions/common/manifest_handlers/background_info.h" | 67 #include "extensions/common/manifest_handlers/background_info.h" |
65 #include "extensions/common/manifest_handlers/icons_handler.h" | 68 #include "extensions/common/manifest_handlers/icons_handler.h" |
(...skipping 27 matching lines...) Expand all Loading... |
93 const char kSupervisedUserError[] = | 96 const char kSupervisedUserError[] = |
94 "Supervised users cannot modify extension settings."; | 97 "Supervised users cannot modify extension settings."; |
95 const char kCannotModifyPolicyExtensionError[] = | 98 const char kCannotModifyPolicyExtensionError[] = |
96 "Cannot modify the extension by policy."; | 99 "Cannot modify the extension by policy."; |
97 const char kRequiresUserGestureError[] = | 100 const char kRequiresUserGestureError[] = |
98 "This action requires a user gesture."; | 101 "This action requires a user gesture."; |
99 const char kCouldNotShowSelectFileDialogError[] = | 102 const char kCouldNotShowSelectFileDialogError[] = |
100 "Could not show a file chooser."; | 103 "Could not show a file chooser."; |
101 const char kFileSelectionCanceled[] = | 104 const char kFileSelectionCanceled[] = |
102 "File selection was canceled."; | 105 "File selection was canceled."; |
| 106 const char kInvalidPathError[] = "Invalid path."; |
| 107 const char kManifestKeyIsRequiredError[] = |
| 108 "The 'manifestKey' argument is required for manifest files."; |
| 109 const char kNoSuchRendererError[] = "Could not find the renderer."; |
103 | 110 |
104 const char kUnpackedAppsFolder[] = "apps_target"; | 111 const char kUnpackedAppsFolder[] = "apps_target"; |
| 112 const char kManifestFile[] = "manifest.json"; |
105 | 113 |
106 ExtensionService* GetExtensionService(content::BrowserContext* context) { | 114 ExtensionService* GetExtensionService(content::BrowserContext* context) { |
107 return ExtensionSystem::Get(context)->extension_service(); | 115 return ExtensionSystem::Get(context)->extension_service(); |
108 } | 116 } |
109 | 117 |
110 ExtensionUpdater* GetExtensionUpdater(Profile* profile) { | 118 ExtensionUpdater* GetExtensionUpdater(Profile* profile) { |
111 return GetExtensionService(profile)->updater(); | 119 return GetExtensionService(profile)->updater(); |
112 } | 120 } |
113 | 121 |
114 GURL GetImageURLFromData(const std::string& contents) { | 122 GURL GetImageURLFromData(const std::string& contents) { |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
163 event_data.event_type = event_type; | 171 event_data.event_type = event_type; |
164 event_data.item_id = item_id; | 172 event_data.item_id = item_id; |
165 | 173 |
166 scoped_ptr<base::ListValue> args(new base::ListValue()); | 174 scoped_ptr<base::ListValue> args(new base::ListValue()); |
167 args->Append(event_data.ToValue().release()); | 175 args->Append(event_data.ToValue().release()); |
168 scoped_ptr<Event> event(new Event( | 176 scoped_ptr<Event> event(new Event( |
169 developer_private::OnItemStateChanged::kEventName, args.Pass())); | 177 developer_private::OnItemStateChanged::kEventName, args.Pass())); |
170 EventRouter::Get(browser_context)->BroadcastEvent(event.Pass()); | 178 EventRouter::Get(browser_context)->BroadcastEvent(event.Pass()); |
171 } | 179 } |
172 | 180 |
| 181 std::string ReadFileToString(const base::FilePath& path) { |
| 182 std::string data; |
| 183 ignore_result(base::ReadFileToString(path, &data)); |
| 184 return data; |
| 185 } |
| 186 |
173 } // namespace | 187 } // namespace |
174 | 188 |
175 namespace AllowFileAccess = api::developer_private::AllowFileAccess; | 189 namespace AllowFileAccess = api::developer_private::AllowFileAccess; |
176 namespace AllowIncognito = api::developer_private::AllowIncognito; | 190 namespace AllowIncognito = api::developer_private::AllowIncognito; |
177 namespace ChoosePath = api::developer_private::ChoosePath; | 191 namespace ChoosePath = api::developer_private::ChoosePath; |
178 namespace GetItemsInfo = api::developer_private::GetItemsInfo; | 192 namespace GetItemsInfo = api::developer_private::GetItemsInfo; |
179 namespace Inspect = api::developer_private::Inspect; | 193 namespace Inspect = api::developer_private::Inspect; |
180 namespace PackDirectory = api::developer_private::PackDirectory; | 194 namespace PackDirectory = api::developer_private::PackDirectory; |
181 namespace Reload = api::developer_private::Reload; | 195 namespace Reload = api::developer_private::Reload; |
182 | 196 |
(...skipping 1142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1325 DeveloperPrivateIsProfileManagedFunction:: | 1339 DeveloperPrivateIsProfileManagedFunction:: |
1326 ~DeveloperPrivateIsProfileManagedFunction() { | 1340 ~DeveloperPrivateIsProfileManagedFunction() { |
1327 } | 1341 } |
1328 | 1342 |
1329 DeveloperPrivateRequestFileSourceFunction:: | 1343 DeveloperPrivateRequestFileSourceFunction:: |
1330 DeveloperPrivateRequestFileSourceFunction() {} | 1344 DeveloperPrivateRequestFileSourceFunction() {} |
1331 | 1345 |
1332 DeveloperPrivateRequestFileSourceFunction:: | 1346 DeveloperPrivateRequestFileSourceFunction:: |
1333 ~DeveloperPrivateRequestFileSourceFunction() {} | 1347 ~DeveloperPrivateRequestFileSourceFunction() {} |
1334 | 1348 |
1335 bool DeveloperPrivateRequestFileSourceFunction::RunAsync() { | 1349 ExtensionFunction::ResponseAction |
1336 scoped_ptr<developer::RequestFileSource::Params> params( | 1350 DeveloperPrivateRequestFileSourceFunction::Run() { |
1337 developer::RequestFileSource::Params::Create(*args_)); | 1351 params_ = developer::RequestFileSource::Params::Create(*args_); |
1338 EXTENSION_FUNCTION_VALIDATE(params); | 1352 EXTENSION_FUNCTION_VALIDATE(params_); |
1339 | 1353 |
1340 base::DictionaryValue* dict = nullptr; | 1354 const developer::RequestFileSourceProperties& properties = |
1341 // TODO(devlin): Use generated |params|. | 1355 params_->properties; |
1342 EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0u, &dict)); | 1356 const Extension* extension = GetExtensionById(properties.extension_id); |
| 1357 if (!extension) |
| 1358 return RespondNow(Error(kNoSuchExtensionError)); |
1343 | 1359 |
1344 AddRef(); // Balanced in LaunchCallback(). | 1360 // Under no circumstances should we ever need to reference a file outside of |
1345 error_ui_util::HandleRequestFileSource( | 1361 // the extension's directory. If it tries to, abort. |
1346 dict, | 1362 base::FilePath path_suffix = |
1347 GetProfile(), | 1363 base::FilePath::FromUTF8Unsafe(properties.path_suffix); |
1348 base::Bind(&DeveloperPrivateRequestFileSourceFunction::LaunchCallback, | 1364 if (path_suffix.empty() || path_suffix.ReferencesParent()) |
1349 base::Unretained(this))); | 1365 return RespondNow(Error(kInvalidPathError)); |
1350 return true; | 1366 |
| 1367 if (properties.path_suffix == kManifestFile && !properties.manifest_key) |
| 1368 return RespondNow(Error(kManifestKeyIsRequiredError)); |
| 1369 |
| 1370 base::PostTaskAndReplyWithResult( |
| 1371 content::BrowserThread::GetBlockingPool(), |
| 1372 FROM_HERE, |
| 1373 base::Bind(&ReadFileToString, extension->path().Append(path_suffix)), |
| 1374 base::Bind(&DeveloperPrivateRequestFileSourceFunction::Finish, this)); |
| 1375 |
| 1376 return RespondLater(); |
1351 } | 1377 } |
1352 | 1378 |
1353 void DeveloperPrivateRequestFileSourceFunction::LaunchCallback( | 1379 void DeveloperPrivateRequestFileSourceFunction::Finish( |
1354 const base::DictionaryValue& results) { | 1380 const std::string& file_contents) { |
1355 SetResult(results.DeepCopy()); | 1381 const developer::RequestFileSourceProperties& properties = |
1356 SendResponse(true); | 1382 params_->properties; |
1357 Release(); // Balanced in RunAsync(). | 1383 const Extension* extension = GetExtensionById(properties.extension_id); |
| 1384 if (!extension) { |
| 1385 Respond(Error(kNoSuchExtensionError)); |
| 1386 return; |
| 1387 } |
| 1388 |
| 1389 developer::RequestFileSourceResponse response; |
| 1390 base::FilePath path_suffix = |
| 1391 base::FilePath::FromUTF8Unsafe(properties.path_suffix); |
| 1392 base::FilePath path = extension->path().Append(path_suffix); |
| 1393 response.title = base::StringPrintf("%s: %s", |
| 1394 extension->name().c_str(), |
| 1395 path.BaseName().AsUTF8Unsafe().c_str()); |
| 1396 response.message = properties.message; |
| 1397 |
| 1398 scoped_ptr<FileHighlighter> highlighter; |
| 1399 if (properties.path_suffix == kManifestFile) { |
| 1400 highlighter.reset(new ManifestHighlighter( |
| 1401 file_contents, |
| 1402 *properties.manifest_key, |
| 1403 properties.manifest_specific ? |
| 1404 *properties.manifest_specific : std::string())); |
| 1405 } else { |
| 1406 highlighter.reset(new SourceHighlighter( |
| 1407 file_contents, |
| 1408 properties.line_number ? *properties.line_number : 0)); |
| 1409 } |
| 1410 |
| 1411 response.before_highlight = highlighter->GetBeforeFeature(); |
| 1412 response.highlight = highlighter->GetFeature(); |
| 1413 response.after_highlight = highlighter->GetAfterFeature(); |
| 1414 |
| 1415 Respond(OneArgument(response.ToValue().release())); |
1358 } | 1416 } |
1359 | 1417 |
1360 DeveloperPrivateOpenDevToolsFunction::DeveloperPrivateOpenDevToolsFunction() {} | 1418 DeveloperPrivateOpenDevToolsFunction::DeveloperPrivateOpenDevToolsFunction() {} |
1361 DeveloperPrivateOpenDevToolsFunction::~DeveloperPrivateOpenDevToolsFunction() {} | 1419 DeveloperPrivateOpenDevToolsFunction::~DeveloperPrivateOpenDevToolsFunction() {} |
1362 | 1420 |
1363 bool DeveloperPrivateOpenDevToolsFunction::RunAsync() { | 1421 ExtensionFunction::ResponseAction |
| 1422 DeveloperPrivateOpenDevToolsFunction::Run() { |
1364 scoped_ptr<developer::OpenDevTools::Params> params( | 1423 scoped_ptr<developer::OpenDevTools::Params> params( |
1365 developer::OpenDevTools::Params::Create(*args_)); | 1424 developer::OpenDevTools::Params::Create(*args_)); |
1366 EXTENSION_FUNCTION_VALIDATE(params); | 1425 EXTENSION_FUNCTION_VALIDATE(params); |
| 1426 const developer::OpenDevToolsProperties& properties = params->properties; |
1367 | 1427 |
1368 base::DictionaryValue* dict = nullptr; | 1428 content::RenderViewHost* rvh = |
1369 // TODO(devlin): Use generated |params|. | 1429 content::RenderViewHost::FromID(properties.render_process_id, |
1370 EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0u, &dict)); | 1430 properties.render_view_id); |
| 1431 content::WebContents* web_contents = |
| 1432 rvh ? content::WebContents::FromRenderViewHost(rvh) : nullptr; |
| 1433 // It's possible that the render view was closed since we last updated the |
| 1434 // links. Handle this gracefully. |
| 1435 if (!web_contents) |
| 1436 return RespondNow(Error(kNoSuchRendererError)); |
1371 | 1437 |
1372 error_ui_util::HandleOpenDevTools(dict); | 1438 // If we include a url, we should inspect it specifically (and not just the |
| 1439 // render view). |
| 1440 if (properties.url) { |
| 1441 // Line/column numbers are reported in display-friendly 1-based numbers, |
| 1442 // but are inspected in zero-based numbers. |
| 1443 // Default to the first line/column. |
| 1444 DevToolsWindow::OpenDevToolsWindow( |
| 1445 web_contents, |
| 1446 DevToolsToggleAction::Reveal( |
| 1447 base::UTF8ToUTF16(*properties.url), |
| 1448 properties.line_number ? *properties.line_number - 1 : 0, |
| 1449 properties.column_number ? *properties.column_number - 1 : 0)); |
| 1450 } else { |
| 1451 DevToolsWindow::OpenDevToolsWindow(web_contents); |
| 1452 } |
1373 | 1453 |
1374 return true; | 1454 // Once we open the inspector, we focus on the appropriate tab... |
| 1455 Browser* browser = chrome::FindBrowserWithWebContents(web_contents); |
| 1456 |
| 1457 // ... but some pages (popups and apps) don't have tabs, and some (background |
| 1458 // pages) don't have an associated browser. For these, the inspector opens in |
| 1459 // a new window, and our work is done. |
| 1460 if (!browser || !browser->is_type_tabbed()) |
| 1461 return RespondNow(NoArguments()); |
| 1462 |
| 1463 TabStripModel* tab_strip = browser->tab_strip_model(); |
| 1464 tab_strip->ActivateTabAt(tab_strip->GetIndexOfWebContents(web_contents), |
| 1465 false); // Not through direct user gesture. |
| 1466 return RespondNow(NoArguments()); |
1375 } | 1467 } |
1376 | 1468 |
1377 } // namespace api | 1469 } // namespace api |
1378 | 1470 |
1379 } // namespace extensions | 1471 } // namespace extensions |
OLD | NEW |