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
;
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
))
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
;
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
;
108 icon_resource_id
= IDR_EXTENSION_DEFAULT_ICON
;
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
)
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();
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
) {
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
) {
186 content::Source
<Profile
>(profile_
));
191 DeveloperPrivateEventRouter::~DeveloperPrivateEventRouter() {}
193 void DeveloperPrivateEventRouter::Observe(
195 const content::NotificationSource
& source
,
196 const content::NotificationDetails
& details
) {
197 const char* event_name
= NULL
;
198 Profile
* profile
= content::Source
<Profile
>(source
).ptr();
200 CHECK(profile_
->IsSameProfile(profile
));
201 developer::EventData event_data
;
202 const Extension
* extension
= NULL
;
205 case chrome::NOTIFICATION_EXTENSION_INSTALLED
:
206 event_data
.event_type
= developer::EVENT_TYPE_INSTALLED
;
208 content::Details
<const InstalledExtensionInfo
>(details
)->extension
;
210 case chrome::NOTIFICATION_EXTENSION_UNINSTALLED
:
211 event_data
.event_type
= developer::EVENT_TYPE_UNINSTALLED
;
212 extension
= content::Details
<const Extension
>(details
).ptr();
214 case chrome::NOTIFICATION_EXTENSION_LOADED
:
215 event_data
.event_type
= developer::EVENT_TYPE_LOADED
;
216 extension
= content::Details
<const Extension
>(details
).ptr();
218 case chrome::NOTIFICATION_EXTENSION_UNLOADED
:
219 event_data
.event_type
= developer::EVENT_TYPE_UNLOADED
;
221 content::Details
<const UnloadedExtensionInfo
>(details
)->extension
;
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());
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());
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
);
278 bool DeveloperPrivateAutoUpdateFunction::RunImpl() {
279 ExtensionUpdater
* updater
= GetExtensionUpdater(GetProfile());
281 updater
->CheckNow(ExtensionUpdater::CheckParams());
282 SetResult(new base::FundamentalValue(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();
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
;
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
;
321 if (Manifest::IsUnpackedLocation(item
.location())) {
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()));
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
);
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()) {
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
,
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
)
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(),
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(),
439 host
->GetRoutingID(),
440 process
->GetBrowserContext()->IsOffTheRecord(),
441 is_background_page
&& has_generated_background_page
));
445 linked_ptr
<developer::ItemInspectView
> DeveloperPrivateGetItemsInfoFunction::
446 constructInspectView(
448 int render_process_id
,
451 bool generated_background_page
) {
452 linked_ptr
<developer::ItemInspectView
> view(new developer::ItemInspectView());
454 if (url
.scheme() == kExtensionScheme
) {
456 view
->path
= url
.path().substr(1);
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
;
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(
480 process_manager
->GetRenderViewHostsForExtension(extension
->id()),
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
),
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(
507 process_manager
->GetRenderViewHostsForExtension(extension
->id()),
510 if (BackgroundInfo::HasLazyBackgroundPage(extension
) &&
511 extension_is_enabled
&&
512 !process_manager
->GetBackgroundHostForExtension(extension
->id())) {
513 result
.push_back(constructInspectView(
514 BackgroundInfo::GetBackgroundURL(extension
),
518 BackgroundInfo::HasGeneratedBackgroundPage(extension
)));
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
;
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())
564 item_list
.push_back(make_linked_ptr
<developer::ItemInfo
>(
566 item
, service
->IsExtensionEnabled(item
.id())).release()));
569 content::BrowserThread::PostTask(content::BrowserThread::FILE, FROM_HERE
,
570 base::Bind(&DeveloperPrivateGetItemsInfoFunction::GetIconsOnFileThread
,
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
);
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 : "
601 extension_util::SetAllowFileAccess(extension
, service
, params
->allow
);
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
);
623 extension_util::SetIsIncognitoEnabled(
624 extension
->id(),service
, params
->allow
);
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
);
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());
649 ShellWindow
* shell_window
= registry
->GetShellWindowForRenderViewHost(
651 prompt_
.reset(new ExtensionInstallPrompt(shell_window
->web_contents()));
652 const Extension
* extension
= service
->GetInstalledExtension(extension_id_
);
657 // Released by InstallUIAbort or InstallUIProceed.
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
);
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_
);
686 void DeveloperPrivateShowPermissionsDialogFunction::InstallUIAbort(
687 bool user_initiated
) {
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
);
712 LOG(ERROR
) << "Did not find extension with id " << extension_id
;
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();
725 ExtensionPrefs
* prefs
= service
->extension_prefs();
726 if (prefs
->DidExtensionEscalatePermissions(extension_id
)) {
727 ShellWindowRegistry
* registry
= ShellWindowRegistry::Get(GetProfile());
729 ShellWindow
* shell_window
= registry
->GetShellWindowForRenderViewHost(
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.
747 requirements_checker_
->Check(
749 base::Bind(&DeveloperPrivateEnableFunction::OnRequirementsChecked
,
750 this, extension_id
));
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);
759 service
->DisableExtension(extension_id
, Extension::DISABLE_USER_ACTION
);
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
);
771 ExtensionErrorReporter::GetInstance()->ReportError(
772 UTF8ToUTF16(JoinString(requirements_errors
, ' ')),
773 true /* be noisy */);
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
);
799 // Wakes up the background page and opens the inspect window.
800 devtools_util::InspectBackgroundPage(extension
, GetProfile());
805 base::StringToInt(options
.render_view_id
, &render_view_id
);
806 content::RenderViewHost
* host
= content::RenderViewHost::FromID(
807 render_process_id
, render_view_id
);
810 // This can happen if the host has gone away since the page was displayed.
814 DevToolsWindow::OpenDevToolsWindow(host
);
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.
826 bool result
= ShowPicker(
827 ui::SelectFileDialog::SELECT_FOLDER
,
828 DeveloperPrivateAPI::Get(GetProfile())->GetLastUnpackedDirectory(),
830 ui::SelectFileDialog::FileTypeInfo(),
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
);
844 void DeveloperPrivateLoadUnpackedFunction::FileSelectionCanceled() {
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());
857 ShellWindow
* shell_window
= registry
->GetShellWindowForRenderViewHost(
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
867 new EntryPicker(this, shell_window
->web_contents(), picker_type
,
868 last_directory
, select_title
, info
, file_type_index
);
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
;
881 UTF16ToUTF8(PackExtensionJob::StandardSuccessMessage(crx_file
, pem_file
));
882 response
.status
= developer::PACK_STATUS_SUCCESS
;
883 results_
= developer::PackDirectory::Results::Create(response
);
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
;
899 response
.status
= developer::PACK_STATUS_ERROR
;
901 results_
= developer::PackDirectory::Results::Create(response
);
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
);
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
);
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
);
944 // Balanced in OnPackSuccess / OnPackFailure.
947 pack_job_
= new PackExtensionJob(this, root_directory
, key_file
, flags
);
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
<< "]";
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
,
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(
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
,
1023 if (status
!= base::PLATFORM_FILE_OK
) {
1024 DLOG(ERROR
) << "Error in copying files from sync filesystem.";
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
));
1044 std::string
origin_url(
1045 Extension::GetBaseURLFromExtensionId(extension_id()).spec());
1046 fileapi::FileSystemURL
url(sync_file_system::CreateSyncableFileSystemURL(
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(
1055 &DeveloperPrivateExportSyncfsFolderToLocalfsFunction::
1056 SnapshotFileCallback
,
1062 // Directory copy operation released here.
1063 pendingCopyOperationsCount_
--;
1065 if (!pendingCopyOperationsCount_
) {
1066 content::BrowserThread::PostTask(content::BrowserThread::UI
, FROM_HERE
,
1067 base::Bind(&DeveloperPrivateExportSyncfsFolderToLocalfsFunction::
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.");
1086 content::BrowserThread::PostTask(content::BrowserThread::FILE, FROM_HERE
,
1087 base::Bind(&DeveloperPrivateExportSyncfsFolderToLocalfsFunction::CopyFile
,
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.");
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::
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
<< "]";
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.
1142 content::BrowserThread::PostTask(content::BrowserThread::FILE, FROM_HERE
,
1143 base::Bind(&DeveloperPrivateLoadProjectFunction::GetUnpackedExtension
,
1144 this, path
, extensions
));
1148 void DeveloperPrivateLoadProjectFunction::GetUnpackedExtension(
1149 const base::FilePath
& path
,
1150 const ExtensionSet
* extensions
) {
1151 const Extension
* extension
= GetExtensionByPath(extensions
, path
);
1152 bool success
= true;
1154 SetResult(new base::StringValue(extension
->id()));
1156 SetError("unable to load the project");
1159 content::BrowserThread::PostTask(content::BrowserThread::UI
, FROM_HERE
,
1160 base::Bind(&DeveloperPrivateLoadProjectFunction::SendResponse
,
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;
1200 // Balanced by FileSelected / FileSelectionCanceled.
1202 bool result
= ShowPicker(
1204 DeveloperPrivateAPI::Get(GetProfile())->GetLastUnpackedDirectory(),
1211 void DeveloperPrivateChoosePathFunction::FileSelected(
1212 const base::FilePath
& path
) {
1213 SetResult(new base::StringValue(UTF16ToUTF8(path
.LossyDisplayName())));
1218 void DeveloperPrivateChoosePathFunction::FileSelectionCanceled() {
1219 SendResponse(false);
1223 DeveloperPrivateChoosePathFunction::~DeveloperPrivateChoosePathFunction() {}
1225 bool DeveloperPrivateGetStringsFunction::RunImpl() {
1226 base::DictionaryValue
* dict
= new base::DictionaryValue();
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
);
1337 DeveloperPrivateGetStringsFunction::~DeveloperPrivateGetStringsFunction() {}
1339 bool DeveloperPrivateIsProfileManagedFunction::RunImpl() {
1340 SetResult(new base::FundamentalValue(GetProfile()->IsManaged()));
1344 DeveloperPrivateIsProfileManagedFunction::
1345 ~DeveloperPrivateIsProfileManagedFunction() {
1350 } // namespace extensions