Revert 239759 "The comment in base64.h implies that base::Base64..."
[chromium-blink-merge.git] / chrome / browser / extensions / api / developer_private / developer_private_api.cc
blobdb64c33b96c7041aab449fce9a622aaf108c43e4
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
3 // found in the LICENSE file.
5 #include "chrome/browser/extensions/api/developer_private/developer_private_api.h"
7 #include "apps/app_load_service.h"
8 #include "apps/app_restore_service.h"
9 #include "apps/saved_files_service.h"
10 #include "apps/shell_window.h"
11 #include "apps/shell_window_registry.h"
12 #include "base/base64.h"
13 #include "base/command_line.h"
14 #include "base/file_util.h"
15 #include "base/files/file_enumerator.h"
16 #include "base/i18n/file_util_icu.h"
17 #include "base/strings/string_number_conversions.h"
18 #include "base/strings/utf_string_conversions.h"
19 #include "base/values.h"
20 #include "chrome/browser/chrome_notification_types.h"
21 #include "chrome/browser/devtools/devtools_window.h"
22 #include "chrome/browser/extensions/api/developer_private/developer_private_api_factory.h"
23 #include "chrome/browser/extensions/api/developer_private/entry_picker.h"
24 #include "chrome/browser/extensions/api/extension_action/extension_action_api.h"
25 #include "chrome/browser/extensions/devtools_util.h"
26 #include "chrome/browser/extensions/extension_disabled_ui.h"
27 #include "chrome/browser/extensions/extension_error_reporter.h"
28 #include "chrome/browser/extensions/extension_service.h"
29 #include "chrome/browser/extensions/extension_system.h"
30 #include "chrome/browser/extensions/extension_util.h"
31 #include "chrome/browser/extensions/unpacked_installer.h"
32 #include "chrome/browser/extensions/updater/extension_updater.h"
33 #include "chrome/browser/platform_util.h"
34 #include "chrome/browser/profiles/profile.h"
35 #include "chrome/browser/sync_file_system/drive_backend_v1/drive_file_sync_service.h"
36 #include "chrome/browser/sync_file_system/syncable_file_system_util.h"
37 #include "chrome/browser/ui/chrome_select_file_policy.h"
38 #include "chrome/browser/ui/webui/extensions/extension_icon_source.h"
39 #include "chrome/common/extensions/api/developer_private.h"
40 #include "chrome/common/extensions/manifest_handlers/app_launch_info.h"
41 #include "chrome/common/extensions/manifest_handlers/icons_handler.h"
42 #include "chrome/common/extensions/manifest_url_handler.h"
43 #include "chrome/common/url_constants.h"
44 #include "content/public/browser/browser_thread.h"
45 #include "content/public/browser/notification_service.h"
46 #include "content/public/browser/render_process_host.h"
47 #include "content/public/browser/render_view_host.h"
48 #include "content/public/browser/site_instance.h"
49 #include "content/public/browser/storage_partition.h"
50 #include "content/public/browser/web_contents.h"
51 #include "extensions/browser/management_policy.h"
52 #include "extensions/browser/view_type_utils.h"
53 #include "extensions/common/constants.h"
54 #include "extensions/common/extension_resource.h"
55 #include "extensions/common/install_warning.h"
56 #include "extensions/common/manifest_handlers/background_info.h"
57 #include "extensions/common/manifest_handlers/incognito_info.h"
58 #include "extensions/common/manifest_handlers/offline_enabled_info.h"
59 #include "extensions/common/switches.h"
60 #include "grit/chromium_strings.h"
61 #include "grit/generated_resources.h"
62 #include "grit/theme_resources.h"
63 #include "net/base/net_util.h"
64 #include "ui/base/l10n/l10n_util.h"
65 #include "ui/base/resource/resource_bundle.h"
66 #include "ui/base/webui/web_ui_util.h"
67 #include "webkit/browser/fileapi/file_system_context.h"
68 #include "webkit/browser/fileapi/file_system_operation.h"
69 #include "webkit/browser/fileapi/file_system_operation_runner.h"
70 #include "webkit/common/blob/shareable_file_reference.h"
72 using apps::ShellWindow;
73 using apps::ShellWindowRegistry;
74 using content::RenderViewHost;
76 namespace extensions {
78 namespace developer_private = api::developer_private;
80 namespace {
82 const base::FilePath::CharType kUnpackedAppsFolder[]
83 = FILE_PATH_LITERAL("apps_target");
85 ExtensionUpdater* GetExtensionUpdater(Profile* profile) {
86 return profile->GetExtensionService()->updater();
89 GURL GetImageURLFromData(std::string contents) {
90 std::string contents_base64;
91 if (!base::Base64Encode(contents, &contents_base64))
92 return GURL();
94 // TODO(dvh): make use of chrome::kDataScheme. Filed as crbug/297301.
95 const char kDataURLPrefix[] = "data:image;base64,";
96 return GURL(kDataURLPrefix + contents_base64);
99 GURL GetDefaultImageURL(developer_private::ItemType type) {
100 int icon_resource_id;
101 switch (type) {
102 case developer::ITEM_TYPE_LEGACY_PACKAGED_APP:
103 case developer::ITEM_TYPE_HOSTED_APP:
104 case developer::ITEM_TYPE_PACKAGED_APP:
105 icon_resource_id = IDR_APP_DEFAULT_ICON;
106 break;
107 default:
108 icon_resource_id = IDR_EXTENSION_DEFAULT_ICON;
109 break;
112 return GetImageURLFromData(
113 ResourceBundle::GetSharedInstance().GetRawDataResourceForScale(
114 icon_resource_id, ui::SCALE_FACTOR_100P).as_string());
117 // TODO(dvh): This code should be refactored and moved to
118 // extensions::ImageLoader. Also a resize should be performed to avoid
119 // potential huge URLs: crbug/297298.
120 GURL ToDataURL(const base::FilePath& path, developer_private::ItemType type) {
121 std::string contents;
122 if (path.empty() || !base::ReadFileToString(path, &contents))
123 return GetDefaultImageURL(type);
125 return GetImageURLFromData(contents);
128 bool ValidateFolderName(const base::FilePath::StringType& name) {
129 base::FilePath::StringType name_sanitized(name);
130 file_util::ReplaceIllegalCharactersInPath(&name_sanitized, '_');
131 return name == name_sanitized;
134 const Extension* GetExtensionByPath(const ExtensionSet* extensions,
135 const base::FilePath& path) {
136 base::FilePath extension_path = base::MakeAbsoluteFilePath(path);
137 for (ExtensionSet::const_iterator iter = extensions->begin();
138 iter != extensions->end(); ++iter) {
139 if ((*iter)->path() == extension_path)
140 return iter->get();
142 return NULL;
145 std::string GetExtensionID(const RenderViewHost* render_view_host) {
146 if (!render_view_host->GetSiteInstance())
147 return std::string();
149 return render_view_host->GetSiteInstance()->GetSiteURL().host();
152 } // namespace
154 namespace AllowFileAccess = api::developer_private::AllowFileAccess;
155 namespace AllowIncognito = api::developer_private::AllowIncognito;
156 namespace ChoosePath = api::developer_private::ChoosePath;
157 namespace Enable = api::developer_private::Enable;
158 namespace GetItemsInfo = api::developer_private::GetItemsInfo;
159 namespace Inspect = api::developer_private::Inspect;
160 namespace PackDirectory = api::developer_private::PackDirectory;
161 namespace Reload = api::developer_private::Reload;
163 DeveloperPrivateAPI* DeveloperPrivateAPI::Get(Profile* profile) {
164 return DeveloperPrivateAPIFactory::GetForProfile(profile);
167 DeveloperPrivateAPI::DeveloperPrivateAPI(Profile* profile) : profile_(profile) {
168 RegisterNotifications();
171 DeveloperPrivateEventRouter::DeveloperPrivateEventRouter(Profile* profile)
172 : profile_(profile) {
173 int types[] = {
174 chrome::NOTIFICATION_EXTENSION_INSTALLED,
175 chrome::NOTIFICATION_EXTENSION_UNINSTALLED,
176 chrome::NOTIFICATION_EXTENSION_LOADED,
177 chrome::NOTIFICATION_EXTENSION_UNLOADED,
178 chrome::NOTIFICATION_EXTENSION_VIEW_REGISTERED,
179 chrome::NOTIFICATION_EXTENSION_VIEW_UNREGISTERED
182 CHECK(registrar_.IsEmpty());
183 for (size_t i = 0; i < arraysize(types); ++i) {
184 registrar_.Add(this,
185 types[i],
186 content::Source<Profile>(profile_));
191 DeveloperPrivateEventRouter::~DeveloperPrivateEventRouter() {}
193 void DeveloperPrivateEventRouter::Observe(
194 int type,
195 const content::NotificationSource& source,
196 const content::NotificationDetails& details) {
197 const char* event_name = NULL;
198 Profile* profile = content::Source<Profile>(source).ptr();
199 CHECK(profile);
200 CHECK(profile_->IsSameProfile(profile));
201 developer::EventData event_data;
202 const Extension* extension = NULL;
204 switch (type) {
205 case chrome::NOTIFICATION_EXTENSION_INSTALLED:
206 event_data.event_type = developer::EVENT_TYPE_INSTALLED;
207 extension =
208 content::Details<const InstalledExtensionInfo>(details)->extension;
209 break;
210 case chrome::NOTIFICATION_EXTENSION_UNINSTALLED:
211 event_data.event_type = developer::EVENT_TYPE_UNINSTALLED;
212 extension = content::Details<const Extension>(details).ptr();
213 break;
214 case chrome::NOTIFICATION_EXTENSION_LOADED:
215 event_data.event_type = developer::EVENT_TYPE_LOADED;
216 extension = content::Details<const Extension>(details).ptr();
217 break;
218 case chrome::NOTIFICATION_EXTENSION_UNLOADED:
219 event_data.event_type = developer::EVENT_TYPE_UNLOADED;
220 extension =
221 content::Details<const UnloadedExtensionInfo>(details)->extension;
222 break;
223 case chrome::NOTIFICATION_EXTENSION_VIEW_UNREGISTERED:
224 event_data.event_type = developer::EVENT_TYPE_VIEW_UNREGISTERED;
225 event_data.item_id = GetExtensionID(
226 content::Details<const RenderViewHost>(details).ptr());
227 break;
228 case chrome::NOTIFICATION_EXTENSION_VIEW_REGISTERED:
229 event_data.event_type = developer::EVENT_TYPE_VIEW_REGISTERED;
230 event_data.item_id = GetExtensionID(
231 content::Details<const RenderViewHost>(details).ptr());
232 break;
233 default:
234 NOTREACHED();
235 return;
238 if (extension)
239 event_data.item_id = extension->id();
241 scoped_ptr<ListValue> args(new ListValue());
242 args->Append(event_data.ToValue().release());
244 event_name = developer_private::OnItemStateChanged::kEventName;
245 scoped_ptr<Event> event(new Event(event_name, args.Pass()));
246 ExtensionSystem::Get(profile)->event_router()->BroadcastEvent(event.Pass());
249 void DeveloperPrivateAPI::SetLastUnpackedDirectory(const base::FilePath& path) {
250 last_unpacked_directory_ = path;
253 void DeveloperPrivateAPI::RegisterNotifications() {
254 ExtensionSystem::Get(profile_)->event_router()->RegisterObserver(
255 this, developer_private::OnItemStateChanged::kEventName);
258 DeveloperPrivateAPI::~DeveloperPrivateAPI() {}
260 void DeveloperPrivateAPI::Shutdown() {}
262 void DeveloperPrivateAPI::OnListenerAdded(
263 const EventListenerInfo& details) {
264 if (!developer_private_event_router_)
265 developer_private_event_router_.reset(
266 new DeveloperPrivateEventRouter(profile_));
269 void DeveloperPrivateAPI::OnListenerRemoved(
270 const EventListenerInfo& details) {
271 if (!ExtensionSystem::Get(profile_)->event_router()->HasEventListener(
272 developer_private::OnItemStateChanged::kEventName))
273 developer_private_event_router_.reset(NULL);
276 namespace api {
278 bool DeveloperPrivateAutoUpdateFunction::RunImpl() {
279 ExtensionUpdater* updater = GetExtensionUpdater(GetProfile());
280 if (updater)
281 updater->CheckNow(ExtensionUpdater::CheckParams());
282 SetResult(new base::FundamentalValue(true));
283 return true;
286 DeveloperPrivateAutoUpdateFunction::~DeveloperPrivateAutoUpdateFunction() {}
288 scoped_ptr<developer::ItemInfo>
289 DeveloperPrivateGetItemsInfoFunction::CreateItemInfo(
290 const Extension& item,
291 bool item_is_enabled) {
292 scoped_ptr<developer::ItemInfo> info(new developer::ItemInfo());
294 ExtensionSystem* system = ExtensionSystem::Get(GetProfile());
295 ExtensionService* service = GetProfile()->GetExtensionService();
297 info->id = item.id();
298 info->name = item.name();
299 info->enabled = service->IsExtensionEnabled(info->id);
300 info->offline_enabled = OfflineEnabledInfo::IsOfflineEnabled(&item);
301 info->version = item.VersionString();
302 info->description = item.description();
304 if (item.is_app()) {
305 if (item.is_legacy_packaged_app())
306 info->type = developer::ITEM_TYPE_LEGACY_PACKAGED_APP;
307 else if (item.is_hosted_app())
308 info->type = developer::ITEM_TYPE_HOSTED_APP;
309 else if (item.is_platform_app())
310 info->type = developer::ITEM_TYPE_PACKAGED_APP;
311 else
312 NOTREACHED();
313 } else if (item.is_theme()) {
314 info->type = developer::ITEM_TYPE_THEME;
315 } else if (item.is_extension()) {
316 info->type = developer::ITEM_TYPE_EXTENSION;
317 } else {
318 NOTREACHED();
321 if (Manifest::IsUnpackedLocation(item.location())) {
322 info->path.reset(
323 new std::string(UTF16ToUTF8(item.path().LossyDisplayName())));
324 for (std::vector<extensions::InstallWarning>::const_iterator it =
325 item.install_warnings().begin();
326 it != item.install_warnings().end(); ++it) {
327 developer::InstallWarning* warning = new developer::InstallWarning();
328 warning->message = it->message;
329 info->install_warnings.push_back(make_linked_ptr(warning));
333 info->incognito_enabled =
334 extension_util::IsIncognitoEnabled(item.id(),service);
335 info->wants_file_access = item.wants_file_access();
336 info->allow_file_access = extension_util::AllowFileAccess(&item, service);
337 info->allow_reload = Manifest::IsUnpackedLocation(item.location());
338 info->is_unpacked = Manifest::IsUnpackedLocation(item.location());
339 info->terminated = service->terminated_extensions()->Contains(item.id());
340 info->allow_incognito = item.can_be_incognito_enabled();
342 info->homepage_url.reset(new std::string(
343 ManifestURL::GetHomepageURL(&item).spec()));
344 if (!ManifestURL::GetOptionsPage(&item).is_empty()) {
345 info->options_url.reset(
346 new std::string(ManifestURL::GetOptionsPage(&item).spec()));
349 if (!ManifestURL::GetUpdateURL(&item).is_empty()) {
350 info->update_url.reset(
351 new std::string(ManifestURL::GetUpdateURL(&item).spec()));
354 if (item.is_app()) {
355 info->app_launch_url.reset(new std::string(
356 extensions::AppLaunchInfo::GetFullLaunchURL(&item).spec()));
359 info->may_disable = system->management_policy()->
360 UserMayModifySettings(&item, NULL);
361 info->is_app = item.is_app();
362 info->views = GetInspectablePagesForExtension(&item, item_is_enabled);
364 return info.Pass();
367 void DeveloperPrivateGetItemsInfoFunction::GetIconsOnFileThread(
368 ItemInfoList item_list,
369 const std::map<std::string, ExtensionResource> idToIcon) {
370 for (ItemInfoList::iterator iter = item_list.begin();
371 iter != item_list.end(); ++iter) {
372 developer_private::ItemInfo* info = iter->get();
373 std::map<std::string, ExtensionResource>::const_iterator resource_ptr
374 = idToIcon.find(info->id);
375 if (resource_ptr != idToIcon.end()) {
376 info->icon_url =
377 ToDataURL(resource_ptr->second.GetFilePath(), info->type).spec();
381 results_ = developer::GetItemsInfo::Results::Create(item_list);
382 content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
383 base::Bind(&DeveloperPrivateGetItemsInfoFunction::SendResponse,
384 this,
385 true));
388 void DeveloperPrivateGetItemsInfoFunction::
389 GetInspectablePagesForExtensionProcess(
390 const Extension* extension,
391 const std::set<content::RenderViewHost*>& views,
392 ItemInspectViewList* result) {
393 bool has_generated_background_page =
394 BackgroundInfo::HasGeneratedBackgroundPage(extension);
395 for (std::set<content::RenderViewHost*>::const_iterator iter = views.begin();
396 iter != views.end(); ++iter) {
397 content::RenderViewHost* host = *iter;
398 content::WebContents* web_contents =
399 content::WebContents::FromRenderViewHost(host);
400 ViewType host_type = GetViewType(web_contents);
401 if (VIEW_TYPE_EXTENSION_POPUP == host_type ||
402 VIEW_TYPE_EXTENSION_DIALOG == host_type)
403 continue;
405 content::RenderProcessHost* process = host->GetProcess();
406 bool is_background_page =
407 (web_contents->GetURL() == BackgroundInfo::GetBackgroundURL(extension));
408 result->push_back(constructInspectView(
409 web_contents->GetURL(),
410 process->GetID(),
411 host->GetRoutingID(),
412 process->GetBrowserContext()->IsOffTheRecord(),
413 is_background_page && has_generated_background_page));
417 void DeveloperPrivateGetItemsInfoFunction::
418 GetShellWindowPagesForExtensionProfile(
419 const Extension* extension,
420 ItemInspectViewList* result) {
421 ShellWindowRegistry* registry = ShellWindowRegistry::Get(GetProfile());
422 if (!registry) return;
424 const ShellWindowRegistry::ShellWindowList windows =
425 registry->GetShellWindowsForApp(extension->id());
427 bool has_generated_background_page =
428 BackgroundInfo::HasGeneratedBackgroundPage(extension);
429 for (ShellWindowRegistry::const_iterator it = windows.begin();
430 it != windows.end(); ++it) {
431 content::WebContents* web_contents = (*it)->web_contents();
432 RenderViewHost* host = web_contents->GetRenderViewHost();
433 content::RenderProcessHost* process = host->GetProcess();
434 bool is_background_page =
435 (web_contents->GetURL() == BackgroundInfo::GetBackgroundURL(extension));
436 result->push_back(constructInspectView(
437 web_contents->GetURL(),
438 process->GetID(),
439 host->GetRoutingID(),
440 process->GetBrowserContext()->IsOffTheRecord(),
441 is_background_page && has_generated_background_page));
445 linked_ptr<developer::ItemInspectView> DeveloperPrivateGetItemsInfoFunction::
446 constructInspectView(
447 const GURL& url,
448 int render_process_id,
449 int render_view_id,
450 bool incognito,
451 bool generated_background_page) {
452 linked_ptr<developer::ItemInspectView> view(new developer::ItemInspectView());
454 if (url.scheme() == kExtensionScheme) {
455 // No leading slash.
456 view->path = url.path().substr(1);
457 } else {
458 // For live pages, use the full URL.
459 view->path = url.spec();
462 view->render_process_id = render_process_id;
463 view->render_view_id = render_view_id;
464 view->incognito = incognito;
465 view->generated_background_page = generated_background_page;
466 return view;
469 ItemInspectViewList DeveloperPrivateGetItemsInfoFunction::
470 GetInspectablePagesForExtension(
471 const Extension* extension,
472 bool extension_is_enabled) {
474 ItemInspectViewList result;
475 // Get the extension process's active views.
476 extensions::ProcessManager* process_manager =
477 ExtensionSystem::Get(GetProfile())->process_manager();
478 GetInspectablePagesForExtensionProcess(
479 extension,
480 process_manager->GetRenderViewHostsForExtension(extension->id()),
481 &result);
483 // Get shell window views
484 GetShellWindowPagesForExtensionProfile(extension, &result);
486 // Include a link to start the lazy background page, if applicable.
487 if (BackgroundInfo::HasLazyBackgroundPage(extension) &&
488 extension_is_enabled &&
489 !process_manager->GetBackgroundHostForExtension(extension->id())) {
490 result.push_back(constructInspectView(
491 BackgroundInfo::GetBackgroundURL(extension),
494 false,
495 BackgroundInfo::HasGeneratedBackgroundPage(extension)));
498 ExtensionService* service = GetProfile()->GetExtensionService();
499 // Repeat for the incognito process, if applicable. Don't try to get
500 // shell windows for incognito process.
501 if (service->profile()->HasOffTheRecordProfile() &&
502 IncognitoInfo::IsSplitMode(extension)) {
503 process_manager = ExtensionSystem::Get(
504 service->profile()->GetOffTheRecordProfile())->process_manager();
505 GetInspectablePagesForExtensionProcess(
506 extension,
507 process_manager->GetRenderViewHostsForExtension(extension->id()),
508 &result);
510 if (BackgroundInfo::HasLazyBackgroundPage(extension) &&
511 extension_is_enabled &&
512 !process_manager->GetBackgroundHostForExtension(extension->id())) {
513 result.push_back(constructInspectView(
514 BackgroundInfo::GetBackgroundURL(extension),
517 false,
518 BackgroundInfo::HasGeneratedBackgroundPage(extension)));
522 return result;
525 bool DeveloperPrivateGetItemsInfoFunction::RunImpl() {
526 scoped_ptr<developer::GetItemsInfo::Params> params(
527 developer::GetItemsInfo::Params::Create(*args_));
528 EXTENSION_FUNCTION_VALIDATE(params.get() != NULL);
530 bool include_disabled = params->include_disabled;
531 bool include_terminated = params->include_terminated;
533 ExtensionSet items;
535 ExtensionService* service = GetProfile()->GetExtensionService();
537 items.InsertAll(*service->extensions());
539 if (include_disabled) {
540 items.InsertAll(*service->disabled_extensions());
543 if (include_terminated) {
544 items.InsertAll(*service->terminated_extensions());
547 std::map<std::string, ExtensionResource> id_to_icon;
548 ItemInfoList item_list;
550 for (ExtensionSet::const_iterator iter = items.begin();
551 iter != items.end(); ++iter) {
552 const Extension& item = *iter->get();
554 ExtensionResource item_resource =
555 IconsInfo::GetIconResource(&item,
556 extension_misc::EXTENSION_ICON_MEDIUM,
557 ExtensionIconSet::MATCH_BIGGER);
558 id_to_icon[item.id()] = item_resource;
560 // Don't show component extensions and invisible apps.
561 if (item.ShouldNotBeVisible())
562 continue;
564 item_list.push_back(make_linked_ptr<developer::ItemInfo>(
565 CreateItemInfo(
566 item, service->IsExtensionEnabled(item.id())).release()));
569 content::BrowserThread::PostTask(content::BrowserThread::FILE, FROM_HERE,
570 base::Bind(&DeveloperPrivateGetItemsInfoFunction::GetIconsOnFileThread,
571 this,
572 item_list,
573 id_to_icon));
575 return true;
578 DeveloperPrivateGetItemsInfoFunction::~DeveloperPrivateGetItemsInfoFunction() {}
580 bool DeveloperPrivateAllowFileAccessFunction::RunImpl() {
581 scoped_ptr<AllowFileAccess::Params> params(
582 AllowFileAccess::Params::Create(*args_));
583 EXTENSION_FUNCTION_VALIDATE(params.get());
585 EXTENSION_FUNCTION_VALIDATE(user_gesture_);
587 ExtensionSystem* system = ExtensionSystem::Get(GetProfile());
588 ManagementPolicy* management_policy = system->management_policy();
589 ExtensionService* service = GetProfile()->GetExtensionService();
590 const Extension* extension = service->GetInstalledExtension(params->item_id);
591 bool result = true;
593 if (!extension) {
594 result = false;
595 } else if (!management_policy->UserMayModifySettings(extension, NULL)) {
596 LOG(ERROR) << "Attempt to change allow file access of an extension that "
597 << "non-usermanagable was made. Extension id : "
598 << extension->id();
599 result = false;
600 } else {
601 extension_util::SetAllowFileAccess(extension, service, params->allow);
602 result = true;
605 return result;
608 DeveloperPrivateAllowFileAccessFunction::
609 ~DeveloperPrivateAllowFileAccessFunction() {}
611 bool DeveloperPrivateAllowIncognitoFunction::RunImpl() {
612 scoped_ptr<AllowIncognito::Params> params(
613 AllowIncognito::Params::Create(*args_));
614 EXTENSION_FUNCTION_VALIDATE(params.get());
616 ExtensionService* service = GetProfile()->GetExtensionService();
617 const Extension* extension = service->GetInstalledExtension(params->item_id);
618 bool result = true;
620 if (!extension)
621 result = false;
622 else
623 extension_util::SetIsIncognitoEnabled(
624 extension->id(),service, params->allow);
626 return result;
629 DeveloperPrivateAllowIncognitoFunction::
630 ~DeveloperPrivateAllowIncognitoFunction() {}
633 bool DeveloperPrivateReloadFunction::RunImpl() {
634 scoped_ptr<Reload::Params> params(Reload::Params::Create(*args_));
635 EXTENSION_FUNCTION_VALIDATE(params.get());
637 ExtensionService* service = GetProfile()->GetExtensionService();
638 CHECK(!params->item_id.empty());
639 service->ReloadExtension(params->item_id);
640 return true;
643 bool DeveloperPrivateShowPermissionsDialogFunction::RunImpl() {
644 EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &extension_id_));
645 ExtensionService* service = GetProfile()->GetExtensionService();
646 CHECK(!extension_id_.empty());
647 ShellWindowRegistry* registry = ShellWindowRegistry::Get(GetProfile());
648 DCHECK(registry);
649 ShellWindow* shell_window = registry->GetShellWindowForRenderViewHost(
650 render_view_host());
651 prompt_.reset(new ExtensionInstallPrompt(shell_window->web_contents()));
652 const Extension* extension = service->GetInstalledExtension(extension_id_);
654 if (!extension)
655 return false;
657 // Released by InstallUIAbort or InstallUIProceed.
658 AddRef();
659 std::vector<base::FilePath> retained_file_paths;
660 if (extension->HasAPIPermission(extensions::APIPermission::kFileSystem)) {
661 std::vector<apps::SavedFileEntry> retained_file_entries =
662 apps::SavedFilesService::Get(GetProfile())
663 ->GetAllFileEntries(extension_id_);
664 for (size_t i = 0; i < retained_file_entries.size(); i++) {
665 retained_file_paths.push_back(retained_file_entries[i].path);
668 prompt_->ReviewPermissions(this, extension, retained_file_paths);
669 return true;
672 DeveloperPrivateReloadFunction::~DeveloperPrivateReloadFunction() {}
674 // This is called when the user clicks "Revoke File Access."
675 void DeveloperPrivateShowPermissionsDialogFunction::InstallUIProceed() {
676 apps::SavedFilesService::Get(GetProfile())
677 ->ClearQueue(GetProfile()->GetExtensionService()->GetExtensionById(
678 extension_id_, true));
679 if (apps::AppRestoreService::Get(GetProfile())
680 ->IsAppRestorable(extension_id_))
681 apps::AppLoadService::Get(GetProfile())->RestartApplication(extension_id_);
682 SendResponse(true);
683 Release();
686 void DeveloperPrivateShowPermissionsDialogFunction::InstallUIAbort(
687 bool user_initiated) {
688 SendResponse(true);
689 Release();
692 DeveloperPrivateShowPermissionsDialogFunction::
693 DeveloperPrivateShowPermissionsDialogFunction() {}
695 DeveloperPrivateShowPermissionsDialogFunction::
696 ~DeveloperPrivateShowPermissionsDialogFunction() {}
698 DeveloperPrivateEnableFunction::DeveloperPrivateEnableFunction() {}
700 bool DeveloperPrivateEnableFunction::RunImpl() {
701 scoped_ptr<Enable::Params> params(Enable::Params::Create(*args_));
702 EXTENSION_FUNCTION_VALIDATE(params.get());
704 std::string extension_id = params->item_id;
706 ExtensionSystem* system = ExtensionSystem::Get(GetProfile());
707 ManagementPolicy* policy = system->management_policy();
708 ExtensionService* service = GetProfile()->GetExtensionService();
710 const Extension* extension = service->GetInstalledExtension(extension_id);
711 if (!extension) {
712 LOG(ERROR) << "Did not find extension with id " << extension_id;
713 return false;
715 bool enable = params->enable;
716 if (!policy->UserMayModifySettings(extension, NULL) ||
717 (!enable && policy->MustRemainEnabled(extension, NULL)) ||
718 (enable && policy->MustRemainDisabled(extension, NULL, NULL))) {
719 LOG(ERROR) << "Attempt to change enable state denied by management policy. "
720 << "Extension id: " << extension_id.c_str();
721 return false;
724 if (enable) {
725 ExtensionPrefs* prefs = service->extension_prefs();
726 if (prefs->DidExtensionEscalatePermissions(extension_id)) {
727 ShellWindowRegistry* registry = ShellWindowRegistry::Get(GetProfile());
728 CHECK(registry);
729 ShellWindow* shell_window = registry->GetShellWindowForRenderViewHost(
730 render_view_host());
731 if (!shell_window) {
732 return false;
735 ShowExtensionDisabledDialog(
736 service, shell_window->web_contents(), extension);
737 } else if ((prefs->GetDisableReasons(extension_id) &
738 Extension::DISABLE_UNSUPPORTED_REQUIREMENT) &&
739 !requirements_checker_.get()) {
740 // Recheck the requirements.
741 scoped_refptr<const Extension> extension =
742 service->GetExtensionById(extension_id,
743 true );// include_disabled
744 requirements_checker_.reset(new RequirementsChecker);
745 // Released by OnRequirementsChecked.
746 AddRef();
747 requirements_checker_->Check(
748 extension,
749 base::Bind(&DeveloperPrivateEnableFunction::OnRequirementsChecked,
750 this, extension_id));
751 } else {
752 service->EnableExtension(extension_id);
754 // Make sure any browser action contained within it is not hidden.
755 ExtensionActionAPI::SetBrowserActionVisibility(
756 prefs, extension->id(), true);
758 } else {
759 service->DisableExtension(extension_id, Extension::DISABLE_USER_ACTION);
761 return true;
764 void DeveloperPrivateEnableFunction::OnRequirementsChecked(
765 std::string extension_id,
766 std::vector<std::string> requirements_errors) {
767 if (requirements_errors.empty()) {
768 ExtensionService* service = GetProfile()->GetExtensionService();
769 service->EnableExtension(extension_id);
770 } else {
771 ExtensionErrorReporter::GetInstance()->ReportError(
772 UTF8ToUTF16(JoinString(requirements_errors, ' ')),
773 true /* be noisy */);
775 Release();
778 DeveloperPrivateEnableFunction::~DeveloperPrivateEnableFunction() {}
780 bool DeveloperPrivateInspectFunction::RunImpl() {
781 scoped_ptr<developer::Inspect::Params> params(
782 developer::Inspect::Params::Create(*args_));
783 EXTENSION_FUNCTION_VALIDATE(params.get() != NULL);
784 const developer::InspectOptions& options = params->options;
786 int render_process_id;
787 base::StringToInt(options.render_process_id, &render_process_id);
789 if (render_process_id == -1) {
790 // This is a lazy background page. Identify if it is a normal
791 // or incognito background page.
792 ExtensionService* service = GetProfile()->GetExtensionService();
793 if (options.incognito)
794 service = ExtensionSystem::Get(
795 service->profile()->GetOffTheRecordProfile())->extension_service();
796 const Extension* extension = service->extensions()->GetByID(
797 options.extension_id);
798 DCHECK(extension);
799 // Wakes up the background page and opens the inspect window.
800 devtools_util::InspectBackgroundPage(extension, GetProfile());
801 return false;
804 int render_view_id;
805 base::StringToInt(options.render_view_id, &render_view_id);
806 content::RenderViewHost* host = content::RenderViewHost::FromID(
807 render_process_id, render_view_id);
809 if (!host) {
810 // This can happen if the host has gone away since the page was displayed.
811 return false;
814 DevToolsWindow::OpenDevToolsWindow(host);
815 return true;
818 DeveloperPrivateInspectFunction::~DeveloperPrivateInspectFunction() {}
820 bool DeveloperPrivateLoadUnpackedFunction::RunImpl() {
821 base::string16 select_title =
822 l10n_util::GetStringUTF16(IDS_EXTENSION_LOAD_FROM_DIRECTORY);
824 // Balanced in FileSelected / FileSelectionCanceled.
825 AddRef();
826 bool result = ShowPicker(
827 ui::SelectFileDialog::SELECT_FOLDER,
828 DeveloperPrivateAPI::Get(GetProfile())->GetLastUnpackedDirectory(),
829 select_title,
830 ui::SelectFileDialog::FileTypeInfo(),
832 return result;
835 void DeveloperPrivateLoadUnpackedFunction::FileSelected(
836 const base::FilePath& path) {
837 ExtensionService* service = GetProfile()->GetExtensionService();
838 UnpackedInstaller::Create(service)->Load(path);
839 DeveloperPrivateAPI::Get(GetProfile())->SetLastUnpackedDirectory(path);
840 SendResponse(true);
841 Release();
844 void DeveloperPrivateLoadUnpackedFunction::FileSelectionCanceled() {
845 SendResponse(false);
846 Release();
849 bool DeveloperPrivateChooseEntryFunction::ShowPicker(
850 ui::SelectFileDialog::Type picker_type,
851 const base::FilePath& last_directory,
852 const base::string16& select_title,
853 const ui::SelectFileDialog::FileTypeInfo& info,
854 int file_type_index) {
855 ShellWindowRegistry* registry = ShellWindowRegistry::Get(GetProfile());
856 DCHECK(registry);
857 ShellWindow* shell_window = registry->GetShellWindowForRenderViewHost(
858 render_view_host());
859 if (!shell_window) {
860 return false;
863 // The entry picker will hold a reference to this function instance,
864 // and subsequent sending of the function response) until the user has
865 // selected a file or cancelled the picker. At that point, the picker will
866 // delete itself.
867 new EntryPicker(this, shell_window->web_contents(), picker_type,
868 last_directory, select_title, info, file_type_index);
869 return true;
872 bool DeveloperPrivateChooseEntryFunction::RunImpl() { return false; }
874 DeveloperPrivateChooseEntryFunction::~DeveloperPrivateChooseEntryFunction() {}
876 void DeveloperPrivatePackDirectoryFunction::OnPackSuccess(
877 const base::FilePath& crx_file,
878 const base::FilePath& pem_file) {
879 developer::PackDirectoryResponse response;
880 response.message =
881 UTF16ToUTF8(PackExtensionJob::StandardSuccessMessage(crx_file, pem_file));
882 response.status = developer::PACK_STATUS_SUCCESS;
883 results_ = developer::PackDirectory::Results::Create(response);
884 SendResponse(true);
885 Release();
888 void DeveloperPrivatePackDirectoryFunction::OnPackFailure(
889 const std::string& error,
890 ExtensionCreator::ErrorType error_type) {
891 developer::PackDirectoryResponse response;
892 response.message = error;
893 if (error_type == ExtensionCreator::kCRXExists) {
894 response.item_path = item_path_str_;
895 response.pem_path = key_path_str_;
896 response.override_flags = ExtensionCreator::kOverwriteCRX;
897 response.status = developer::PACK_STATUS_WARNING;
898 } else {
899 response.status = developer::PACK_STATUS_ERROR;
901 results_ = developer::PackDirectory::Results::Create(response);
902 SendResponse(true);
903 Release();
906 bool DeveloperPrivatePackDirectoryFunction::RunImpl() {
907 scoped_ptr<PackDirectory::Params> params(
908 PackDirectory::Params::Create(*args_));
909 EXTENSION_FUNCTION_VALIDATE(params.get());
911 int flags = params->flags;
912 item_path_str_ = params->path;
913 key_path_str_ = params->private_key_path;
915 base::FilePath root_directory =
916 base::FilePath::FromUTF8Unsafe(item_path_str_);
918 base::FilePath key_file = base::FilePath::FromUTF8Unsafe(key_path_str_);
920 developer::PackDirectoryResponse response;
921 if (root_directory.empty()) {
922 if (item_path_str_.empty())
923 response.message = l10n_util::GetStringUTF8(
924 IDS_EXTENSION_PACK_DIALOG_ERROR_ROOT_REQUIRED);
925 else
926 response.message = l10n_util::GetStringUTF8(
927 IDS_EXTENSION_PACK_DIALOG_ERROR_ROOT_INVALID);
929 response.status = developer::PACK_STATUS_ERROR;
930 results_ = developer::PackDirectory::Results::Create(response);
931 SendResponse(true);
932 return true;
935 if (!key_path_str_.empty() && key_file.empty()) {
936 response.message = l10n_util::GetStringUTF8(
937 IDS_EXTENSION_PACK_DIALOG_ERROR_KEY_INVALID);
938 response.status = developer::PACK_STATUS_ERROR;
939 results_ = developer::PackDirectory::Results::Create(response);
940 SendResponse(true);
941 return true;
944 // Balanced in OnPackSuccess / OnPackFailure.
945 AddRef();
947 pack_job_ = new PackExtensionJob(this, root_directory, key_file, flags);
948 pack_job_->Start();
949 return true;
952 DeveloperPrivatePackDirectoryFunction::DeveloperPrivatePackDirectoryFunction()
955 DeveloperPrivatePackDirectoryFunction::~DeveloperPrivatePackDirectoryFunction()
958 DeveloperPrivateLoadUnpackedFunction::~DeveloperPrivateLoadUnpackedFunction() {}
960 bool DeveloperPrivateExportSyncfsFolderToLocalfsFunction::RunImpl() {
961 // TODO(grv) : add unittests.
962 base::FilePath::StringType project_name;
963 EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &project_name));
964 if (!ValidateFolderName(project_name)) {
965 DVLOG(0) << "Invalid project_name : [" << project_name << "]";
966 return false;
969 context_ = content::BrowserContext::GetStoragePartition(
970 GetProfile(), render_view_host()->GetSiteInstance())
971 ->GetFileSystemContext();
973 base::FilePath project_path(GetProfile()->GetPath());
974 project_path = project_path.Append(kUnpackedAppsFolder);
975 project_path = project_path.Append(project_name);
977 content::BrowserThread::PostTask(content::BrowserThread::FILE, FROM_HERE,
978 base::Bind(&DeveloperPrivateExportSyncfsFolderToLocalfsFunction::
979 ClearPrexistingDirectoryContent,
980 this,
981 project_path));
983 return true;
986 void DeveloperPrivateExportSyncfsFolderToLocalfsFunction::
987 ClearPrexistingDirectoryContent(const base::FilePath& project_path) {
989 // Clear the project directory before copying new files.
990 base::DeleteFile(project_path, true/*recursive*/);
992 pendingCopyOperationsCount_ = 1;
994 content::BrowserThread::PostTask(content::BrowserThread::IO, FROM_HERE,
995 base::Bind(&DeveloperPrivateExportSyncfsFolderToLocalfsFunction::
996 ReadSyncFileSystemDirectory,
997 this, project_path, project_path.BaseName()));
1000 void DeveloperPrivateExportSyncfsFolderToLocalfsFunction::
1001 ReadSyncFileSystemDirectory(const base::FilePath& project_path,
1002 const base::FilePath& destination_path) {
1003 std::string origin_url(
1004 Extension::GetBaseURLFromExtensionId(extension_id()).spec());
1005 fileapi::FileSystemURL url(sync_file_system::CreateSyncableFileSystemURL(
1006 GURL(origin_url),
1007 destination_path));
1009 context_->operation_runner()->ReadDirectory(
1010 url, base::Bind(&DeveloperPrivateExportSyncfsFolderToLocalfsFunction::
1011 ReadSyncFileSystemDirectoryCb,
1012 this, project_path, destination_path));
1015 void DeveloperPrivateExportSyncfsFolderToLocalfsFunction::
1016 ReadSyncFileSystemDirectoryCb(
1017 const base::FilePath& project_path,
1018 const base::FilePath& destination_path,
1019 base::PlatformFileError status,
1020 const fileapi::FileSystemOperation::FileEntryList& file_list,
1021 bool has_more) {
1023 if (status != base::PLATFORM_FILE_OK) {
1024 DLOG(ERROR) << "Error in copying files from sync filesystem.";
1025 return;
1028 // We add 1 to the pending copy operations for both files and directories. We
1029 // release the directory copy operation once all the files under the directory
1030 // are added for copying. We do that to ensure that pendingCopyOperationsCount
1031 // does not become zero before all copy operations are finished.
1032 // In case the directory happens to be executing the last copy operation it
1033 // will call SendResponse to send the response to the API. The pending copy
1034 // operations of files are released by the CopyFile function.
1035 pendingCopyOperationsCount_ += file_list.size();
1037 for (size_t i = 0; i < file_list.size(); ++i) {
1038 if (file_list[i].is_directory) {
1039 ReadSyncFileSystemDirectory(project_path.Append(file_list[i].name),
1040 destination_path.Append(file_list[i].name));
1041 continue;
1044 std::string origin_url(
1045 Extension::GetBaseURLFromExtensionId(extension_id()).spec());
1046 fileapi::FileSystemURL url(sync_file_system::CreateSyncableFileSystemURL(
1047 GURL(origin_url),
1048 destination_path.Append(file_list[i].name)));
1049 base::FilePath target_path = project_path;
1050 target_path = target_path.Append(file_list[i].name);
1052 context_->operation_runner()->CreateSnapshotFile(
1053 url,
1054 base::Bind(
1055 &DeveloperPrivateExportSyncfsFolderToLocalfsFunction::
1056 SnapshotFileCallback,
1057 this,
1058 target_path));
1062 // Directory copy operation released here.
1063 pendingCopyOperationsCount_--;
1065 if (!pendingCopyOperationsCount_) {
1066 content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
1067 base::Bind(&DeveloperPrivateExportSyncfsFolderToLocalfsFunction::
1068 SendResponse,
1069 this,
1070 success_));
1074 void DeveloperPrivateExportSyncfsFolderToLocalfsFunction::SnapshotFileCallback(
1075 const base::FilePath& target_path,
1076 base::PlatformFileError result,
1077 const base::PlatformFileInfo& file_info,
1078 const base::FilePath& src_path,
1079 const scoped_refptr<webkit_blob::ShareableFileReference>& file_ref) {
1080 if (result != base::PLATFORM_FILE_OK) {
1081 SetError("Error in copying files from sync filesystem.");
1082 success_ = false;
1083 return;
1086 content::BrowserThread::PostTask(content::BrowserThread::FILE, FROM_HERE,
1087 base::Bind(&DeveloperPrivateExportSyncfsFolderToLocalfsFunction::CopyFile,
1088 this,
1089 src_path,
1090 target_path));
1093 void DeveloperPrivateExportSyncfsFolderToLocalfsFunction::CopyFile(
1094 const base::FilePath& src_path,
1095 const base::FilePath& target_path) {
1096 if (!base::CreateDirectory(target_path.DirName())) {
1097 SetError("Error in copying files from sync filesystem.");
1098 success_ = false;
1101 if (success_)
1102 base::CopyFile(src_path, target_path);
1104 CHECK(pendingCopyOperationsCount_ > 0);
1105 pendingCopyOperationsCount_--;
1107 if (!pendingCopyOperationsCount_) {
1108 content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
1109 base::Bind(&DeveloperPrivateExportSyncfsFolderToLocalfsFunction::
1110 SendResponse,
1111 this,
1112 success_));
1116 DeveloperPrivateExportSyncfsFolderToLocalfsFunction::
1117 DeveloperPrivateExportSyncfsFolderToLocalfsFunction()
1118 : pendingCopyOperationsCount_(0), success_(true) {}
1120 DeveloperPrivateExportSyncfsFolderToLocalfsFunction::
1121 ~DeveloperPrivateExportSyncfsFolderToLocalfsFunction() {}
1123 bool DeveloperPrivateLoadProjectFunction::RunImpl() {
1124 // TODO(grv) : add unit tests.
1125 base::FilePath::StringType project_name;
1126 EXTENSION_FUNCTION_VALIDATE(args_->GetString(0, &project_name));
1127 if (!ValidateFolderName(project_name)) {
1128 DVLOG(0) << "Invalid project_name : [" << project_name << "]";
1129 return false;
1132 base::FilePath path(GetProfile()->GetPath());
1133 path = path.Append(kUnpackedAppsFolder);
1134 // TODO(grv) : Sanitize / check project_name.
1135 path = path.Append(project_name);
1136 ExtensionService* service = GetProfile()->GetExtensionService();
1137 UnpackedInstaller::Create(service)->Load(path);
1139 const ExtensionSet* extensions = service->extensions();
1140 // Released by GetUnpackedExtension.
1141 AddRef();
1142 content::BrowserThread::PostTask(content::BrowserThread::FILE, FROM_HERE,
1143 base::Bind(&DeveloperPrivateLoadProjectFunction::GetUnpackedExtension,
1144 this, path, extensions));
1145 return true;
1148 void DeveloperPrivateLoadProjectFunction::GetUnpackedExtension(
1149 const base::FilePath& path,
1150 const ExtensionSet* extensions) {
1151 const Extension* extension = GetExtensionByPath(extensions, path);
1152 bool success = true;
1153 if (extension) {
1154 SetResult(new base::StringValue(extension->id()));
1155 } else {
1156 SetError("unable to load the project");
1157 success = false;
1159 content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
1160 base::Bind(&DeveloperPrivateLoadProjectFunction::SendResponse,
1161 this,
1162 success));
1163 Release();
1166 DeveloperPrivateLoadProjectFunction::DeveloperPrivateLoadProjectFunction() {}
1168 DeveloperPrivateLoadProjectFunction::~DeveloperPrivateLoadProjectFunction() {}
1170 bool DeveloperPrivateChoosePathFunction::RunImpl() {
1172 scoped_ptr<developer::ChoosePath::Params> params(
1173 developer::ChoosePath::Params::Create(*args_));
1174 EXTENSION_FUNCTION_VALIDATE(params.get() != NULL);
1176 ui::SelectFileDialog::Type type = ui::SelectFileDialog::SELECT_FOLDER;
1177 ui::SelectFileDialog::FileTypeInfo info;
1178 if (params->select_type == developer::SELECT_TYPE_FILE) {
1179 type = ui::SelectFileDialog::SELECT_OPEN_FILE;
1181 base::string16 select_title;
1183 int file_type_index = 0;
1184 if (params->file_type == developer::FILE_TYPE_LOAD)
1185 select_title = l10n_util::GetStringUTF16(IDS_EXTENSION_LOAD_FROM_DIRECTORY);
1186 else if (params->file_type== developer::FILE_TYPE_PEM) {
1187 select_title = l10n_util::GetStringUTF16(
1188 IDS_EXTENSION_PACK_DIALOG_SELECT_KEY);
1189 info.extensions.push_back(std::vector<base::FilePath::StringType>());
1190 info.extensions.front().push_back(FILE_PATH_LITERAL("pem"));
1191 info.extension_description_overrides.push_back(
1192 l10n_util::GetStringUTF16(
1193 IDS_EXTENSION_PACK_DIALOG_KEY_FILE_TYPE_DESCRIPTION));
1194 info.include_all_files = true;
1195 file_type_index = 1;
1196 } else {
1197 NOTREACHED();
1200 // Balanced by FileSelected / FileSelectionCanceled.
1201 AddRef();
1202 bool result = ShowPicker(
1203 type,
1204 DeveloperPrivateAPI::Get(GetProfile())->GetLastUnpackedDirectory(),
1205 select_title,
1206 info,
1207 file_type_index);
1208 return result;
1211 void DeveloperPrivateChoosePathFunction::FileSelected(
1212 const base::FilePath& path) {
1213 SetResult(new base::StringValue(UTF16ToUTF8(path.LossyDisplayName())));
1214 SendResponse(true);
1215 Release();
1218 void DeveloperPrivateChoosePathFunction::FileSelectionCanceled() {
1219 SendResponse(false);
1220 Release();
1223 DeveloperPrivateChoosePathFunction::~DeveloperPrivateChoosePathFunction() {}
1225 bool DeveloperPrivateGetStringsFunction::RunImpl() {
1226 base::DictionaryValue* dict = new base::DictionaryValue();
1227 SetResult(dict);
1229 webui::SetFontAndTextDirection(dict);
1231 #define SET_STRING(id, idr) \
1232 dict->SetString(id, l10n_util::GetStringUTF16(idr))
1233 SET_STRING("extensionSettings", IDS_MANAGE_EXTENSIONS_SETTING_WINDOWS_TITLE);
1235 SET_STRING("appsDevtoolSearch", IDS_APPS_DEVTOOL_SEARCH);
1236 SET_STRING("appsDevtoolApps", IDS_APPS_DEVTOOL_APPS_INSTALLED);
1237 SET_STRING("appsDevtoolExtensions", IDS_APPS_DEVTOOL_EXTENSIONS_INSTALLED);
1238 SET_STRING("appsDevtoolNoExtensions", IDS_EXTENSIONS_NONE_INSTALLED);
1239 SET_STRING("appsDevtoolUnpacked", IDS_APPS_DEVTOOL_UNPACKED_INSTALLED);
1240 SET_STRING("appsDevtoolInstalled", IDS_APPS_DEVTOOL_INSTALLED);
1241 SET_STRING("appsDevtoolNoPackedApps", IDS_APPS_DEVTOOL_NO_PACKED_APPS);
1242 SET_STRING("appsDevtoolNoUnpackedApps", IDS_APPS_DEVTOOL_NO_UNPACKED_APPS);
1243 SET_STRING("appsDevtoolNoPackedExtensions",
1244 IDS_APPS_DEVTOOL_NO_PACKED_EXTENSIONS);
1245 SET_STRING("appsDevtoolNoUnpackedExtensions",
1246 IDS_APPS_DEVTOOL_NO_UNPACKED_EXTENSIONS);
1247 SET_STRING("appsDevtoolUpdating", IDS_APPS_DEVTOOL_UPDATING);
1248 SET_STRING("extensionSettingsGetMoreExtensions", IDS_GET_MORE_EXTENSIONS);
1249 SET_STRING("extensionSettingsExtensionId", IDS_EXTENSIONS_ID);
1250 SET_STRING("extensionSettingsExtensionPath", IDS_EXTENSIONS_PATH);
1251 SET_STRING("extensionSettingsInspectViews", IDS_EXTENSIONS_INSPECT_VIEWS);
1252 SET_STRING("extensionSettingsInstallWarnings",
1253 IDS_EXTENSIONS_INSTALL_WARNINGS);
1254 SET_STRING("viewIncognito", IDS_EXTENSIONS_VIEW_INCOGNITO);
1255 SET_STRING("viewInactive", IDS_EXTENSIONS_VIEW_INACTIVE);
1256 SET_STRING("backgroundPage", IDS_EXTENSIONS_BACKGROUND_PAGE);
1257 SET_STRING("extensionSettingsEnable", IDS_EXTENSIONS_ENABLE);
1258 SET_STRING("extensionSettingsEnabled", IDS_EXTENSIONS_ENABLED);
1259 SET_STRING("extensionSettingsRemove", IDS_EXTENSIONS_REMOVE);
1260 SET_STRING("extensionSettingsEnableIncognito",
1261 IDS_EXTENSIONS_ENABLE_INCOGNITO);
1262 SET_STRING("extensionSettingsAllowFileAccess",
1263 IDS_EXTENSIONS_ALLOW_FILE_ACCESS);
1264 SET_STRING("extensionSettingsReloadTerminated",
1265 IDS_EXTENSIONS_RELOAD_TERMINATED);
1266 SET_STRING("extensionSettingsReloadUnpacked",
1267 IDS_APPS_DEV_TOOLS_RELOAD_UNPACKED);
1268 SET_STRING("extensionSettingsLaunch", IDS_EXTENSIONS_LAUNCH);
1269 SET_STRING("extensionSettingsOptions", IDS_EXTENSIONS_OPTIONS_LINK);
1270 SET_STRING("extensionSettingsPermissions", IDS_EXTENSIONS_PERMISSIONS_LINK);
1271 SET_STRING("extensionSettingsVisitWebsite", IDS_EXTENSIONS_VISIT_WEBSITE);
1272 SET_STRING("extensionSettingsVisitWebStore", IDS_EXTENSIONS_VISIT_WEBSTORE);
1273 SET_STRING("extensionSettingsPolicyControlled",
1274 IDS_EXTENSIONS_POLICY_CONTROLLED);
1275 SET_STRING("extensionSettingsManagedMode",
1276 IDS_EXTENSIONS_LOCKED_MANAGED_USER);
1277 SET_STRING("extensionSettingsShowButton", IDS_EXTENSIONS_SHOW_BUTTON);
1278 SET_STRING("appsDevtoolLoadUnpackedButton",
1279 IDS_APPS_DEVTOOL_LOAD_UNPACKED_BUTTON);
1280 SET_STRING("appsDevtoolPackButton", IDS_APPS_DEVTOOL_PACK_BUTTON);
1281 SET_STRING("extensionSettingsCommandsLink",
1282 IDS_EXTENSIONS_COMMANDS_CONFIGURE);
1283 SET_STRING("appsDevtoolUpdateButton", IDS_APPS_DEVTOOL_UPDATE_BUTTON);
1284 SET_STRING("extensionSettingsWarningsTitle", IDS_EXTENSION_WARNINGS_TITLE);
1285 SET_STRING("extensionSettingsShowDetails", IDS_EXTENSIONS_SHOW_DETAILS);
1286 SET_STRING("extensionSettingsHideDetails", IDS_EXTENSIONS_HIDE_DETAILS);
1287 SET_STRING("extensionUninstall", IDS_EXTENSIONS_UNINSTALL);
1288 SET_STRING("extensionsPermissionsHeading",
1289 IDS_EXTENSIONS_PERMISSIONS_HEADING);
1290 SET_STRING("extensionsPermissionsClose", IDS_EXTENSIONS_PERMISSIONS_CLOSE);
1291 SET_STRING("extensionDisabled", IDS_EXTENSIONS_DISABLED);
1292 SET_STRING("extensionSettingsShowLogsButton", IDS_EXTENSIONS_SHOW_LOGS);
1293 SET_STRING("extensionSettingsMoreDetailsButton", IDS_EXTENSIONS_MORE_DETAILS);
1294 SET_STRING("extensionSettingsVersion", IDS_EXTENSIONS_VERSION);
1295 SET_STRING("extensionSettingsDelete", IDS_EXTENSIONS_ADT_DELETE);
1296 SET_STRING("extensionSettingsPack", IDS_EXTENSIONS_PACK);
1298 // Pack Extension strings
1299 SET_STRING("packExtensionOverlay", IDS_EXTENSION_PACK_DIALOG_TITLE);
1300 SET_STRING("packExtensionHeading", IDS_EXTENSION_ADT_PACK_DIALOG_HEADING);
1301 SET_STRING("packButton", IDS_EXTENSION_ADT_PACK_BUTTON);
1302 SET_STRING("ok", IDS_OK);
1303 SET_STRING("cancel", IDS_CANCEL);
1304 SET_STRING("packExtensionRootDir",
1305 IDS_EXTENSION_PACK_DIALOG_ROOT_DIRECTORY_LABEL);
1306 SET_STRING("packExtensionPrivateKey",
1307 IDS_EXTENSION_PACK_DIALOG_PRIVATE_KEY_LABEL);
1308 SET_STRING("packExtensionBrowseButton", IDS_EXTENSION_PACK_DIALOG_BROWSE);
1309 SET_STRING("packExtensionProceedAnyway", IDS_EXTENSION_PROCEED_ANYWAY);
1310 SET_STRING("packExtensionWarningTitle", IDS_EXTENSION_PACK_WARNING_TITLE);
1311 SET_STRING("packExtensionErrorTitle", IDS_EXTENSION_PACK_ERROR_TITLE);
1312 SET_STRING("packAppOverlay", IDS_EXTENSION_PACK_APP_DIALOG_TITLE);
1313 SET_STRING("packAppHeading", IDS_EXTENSION_ADT_PACK_APP_DIALOG_HEADING);
1315 // Delete confirmation dialog.
1316 SET_STRING("deleteConfirmationDeleteButton",
1317 IDS_APPS_DEVTOOL_DELETE_CONFIRMATION_BUTTON);
1318 SET_STRING("deleteConfirmationTitle",
1319 IDS_APPS_DEVTOOL_DELETE_CONFIRMATION_TITLE);
1320 SET_STRING("deleteConfirmationMessageApp",
1321 IDS_APPS_DEVTOOL_DELETE_CONFIRMATION_MESSAGE_APP);
1322 SET_STRING("deleteConfirmationMessageExtension",
1323 IDS_APPS_DEVTOOL_DELETE_CONFIRMATION_MESSAGE_EXTENSION);
1325 // Dialog when profile is managed.
1326 SET_STRING("managedProfileDialogCloseButton",
1327 IDS_APPS_DEVTOOL_MANAGED_PROFILE_DIALOG_CLOSE_BUTTON);
1328 SET_STRING("managedProfileDialogTitle",
1329 IDS_APPS_DEVTOOL_MANAGED_PROFILE_DIALOG_TITLE);
1330 SET_STRING("managedProfileDialogDescription",
1331 IDS_APPS_DEVTOOL_MANAGED_PROFILE_DIALOG_DESCRIPTION);
1333 #undef SET_STRING
1334 return true;
1337 DeveloperPrivateGetStringsFunction::~DeveloperPrivateGetStringsFunction() {}
1339 bool DeveloperPrivateIsProfileManagedFunction::RunImpl() {
1340 SetResult(new base::FundamentalValue(GetProfile()->IsManaged()));
1341 return true;
1344 DeveloperPrivateIsProfileManagedFunction::
1345 ~DeveloperPrivateIsProfileManagedFunction() {
1348 } // namespace api
1350 } // namespace extensions