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/ui/webui/extensions/extension_settings_handler.h"
9 #include "base/auto_reset.h"
10 #include "base/bind.h"
11 #include "base/bind_helpers.h"
12 #include "base/location.h"
13 #include "base/message_loop/message_loop.h"
14 #include "base/metrics/histogram.h"
15 #include "base/prefs/pref_service.h"
16 #include "base/strings/string_util.h"
17 #include "base/strings/utf_string_conversions.h"
18 #include "base/values.h"
19 #include "base/version.h"
20 #include "chrome/browser/background/background_contents.h"
21 #include "chrome/browser/browser_process.h"
22 #include "chrome/browser/chrome_notification_types.h"
23 #include "chrome/browser/extensions/error_console/error_console.h"
24 #include "chrome/browser/extensions/extension_management.h"
25 #include "chrome/browser/extensions/extension_service.h"
26 #include "chrome/browser/extensions/extension_tab_util.h"
27 #include "chrome/browser/extensions/extension_ui_util.h"
28 #include "chrome/browser/extensions/install_verifier.h"
29 #include "chrome/browser/extensions/updater/extension_updater.h"
30 #include "chrome/browser/extensions/webstore_reinstaller.h"
31 #include "chrome/browser/platform_util.h"
32 #include "chrome/browser/prefs/incognito_mode_prefs.h"
33 #include "chrome/browser/profiles/profile.h"
34 #include "chrome/browser/ui/apps/app_info_dialog.h"
35 #include "chrome/browser/ui/browser.h"
36 #include "chrome/browser/ui/browser_finder.h"
37 #include "chrome/browser/ui/browser_window.h"
38 #include "chrome/browser/ui/extensions/app_launch_params.h"
39 #include "chrome/browser/ui/extensions/application_launch.h"
40 #include "chrome/browser/ui/webui/extensions/extension_basic_info.h"
41 #include "chrome/common/chrome_version_info.h"
42 #include "chrome/common/pref_names.h"
43 #include "chrome/common/url_constants.h"
44 #include "chrome/grit/chromium_strings.h"
45 #include "chrome/grit/generated_resources.h"
46 #include "components/google/core/browser/google_util.h"
47 #include "components/pref_registry/pref_registry_syncable.h"
48 #include "content/public/browser/notification_service.h"
49 #include "content/public/browser/notification_source.h"
50 #include "content/public/browser/notification_types.h"
51 #include "content/public/browser/render_process_host.h"
52 #include "content/public/browser/render_view_host.h"
53 #include "content/public/browser/site_instance.h"
54 #include "content/public/browser/web_contents.h"
55 #include "content/public/browser/web_ui.h"
56 #include "content/public/browser/web_ui_data_source.h"
57 #include "extensions/browser/api/device_permissions_manager.h"
58 #include "extensions/browser/blacklist_state.h"
59 #include "extensions/browser/extension_prefs.h"
60 #include "extensions/browser/extension_registry.h"
61 #include "extensions/browser/extension_system.h"
62 #include "extensions/browser/management_policy.h"
63 #include "extensions/browser/pref_names.h"
64 #include "extensions/browser/warning_set.h"
65 #include "extensions/common/constants.h"
66 #include "extensions/common/extension.h"
67 #include "extensions/common/extension_icon_set.h"
68 #include "extensions/common/extension_set.h"
69 #include "extensions/common/extension_urls.h"
70 #include "extensions/common/manifest.h"
71 #include "extensions/common/manifest_handlers/options_page_info.h"
72 #include "extensions/common/permissions/permissions_data.h"
73 #include "grit/browser_resources.h"
74 #include "grit/components_strings.h"
75 #include "grit/theme_resources.h"
76 #include "ui/base/l10n/l10n_util.h"
81 const char kAppsDeveloperToolsExtensionId
[] =
82 "ohmmkhmmmpcnpikjeljgnaoabkaalbgc";
86 namespace extensions
{
88 ///////////////////////////////////////////////////////////////////////////////
90 // ExtensionSettingsHandler
92 ///////////////////////////////////////////////////////////////////////////////
94 ExtensionSettingsHandler::ExtensionSettingsHandler()
95 : extension_service_(NULL
),
96 ignore_notifications_(false),
100 registered_for_notifications_(false),
101 warning_service_observer_(this),
102 error_console_observer_(this),
103 extension_prefs_observer_(this),
104 extension_registry_observer_(this),
105 extension_management_observer_(this),
106 should_do_verification_check_(false) {
109 ExtensionSettingsHandler::~ExtensionSettingsHandler() {
113 void ExtensionSettingsHandler::RegisterProfilePrefs(
114 user_prefs::PrefRegistrySyncable
* registry
) {
115 registry
->RegisterBooleanPref(
116 prefs::kExtensionsUIDeveloperMode
,
118 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF
);
119 registry
->RegisterBooleanPref(
120 prefs::kExtensionsUIDismissedADTPromo
,
122 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF
);
125 void ExtensionSettingsHandler::GetLocalizedValues(
126 content::WebUIDataSource
* source
) {
127 source
->AddString("extensionSettings",
128 l10n_util::GetStringUTF16(IDS_MANAGE_EXTENSIONS_SETTING_WINDOWS_TITLE
));
130 source
->AddString("extensionSettingsDeveloperMode",
131 l10n_util::GetStringUTF16(IDS_EXTENSIONS_DEVELOPER_MODE_LINK
));
132 source
->AddString("extensionSettingsNoExtensions",
133 l10n_util::GetStringUTF16(IDS_EXTENSIONS_NONE_INSTALLED
));
135 "extensionSettingsSuggestGallery",
136 l10n_util::GetStringFUTF16(
137 IDS_EXTENSIONS_NONE_INSTALLED_SUGGEST_GALLERY
,
139 google_util::AppendGoogleLocaleParam(
140 GURL(extension_urls::GetWebstoreExtensionsCategoryURL()),
141 g_browser_process
->GetApplicationLocale()).spec())));
142 source
->AddString("extensionSettingsGetMoreExtensions",
143 l10n_util::GetStringUTF16(IDS_GET_MORE_EXTENSIONS
));
145 "extensionSettingsGetMoreExtensionsUrl",
147 google_util::AppendGoogleLocaleParam(
148 GURL(extension_urls::GetWebstoreExtensionsCategoryURL()),
149 g_browser_process
->GetApplicationLocale()).spec()));
150 source
->AddString("extensionSettingsExtensionId",
151 l10n_util::GetStringUTF16(IDS_EXTENSIONS_ID
));
152 source
->AddString("extensionSettingsExtensionPath",
153 l10n_util::GetStringUTF16(IDS_EXTENSIONS_PATH
));
154 source
->AddString("extensionSettingsInspectViews",
155 l10n_util::GetStringUTF16(IDS_EXTENSIONS_INSPECT_VIEWS
));
156 source
->AddString("extensionSettingsInstallWarnings",
157 l10n_util::GetStringUTF16(IDS_EXTENSIONS_INSTALL_WARNINGS
));
158 source
->AddString("viewIncognito",
159 l10n_util::GetStringUTF16(IDS_EXTENSIONS_VIEW_INCOGNITO
));
160 source
->AddString("viewInactive",
161 l10n_util::GetStringUTF16(IDS_EXTENSIONS_VIEW_INACTIVE
));
162 source
->AddString("backgroundPage",
163 l10n_util::GetStringUTF16(IDS_EXTENSIONS_BACKGROUND_PAGE
));
164 source
->AddString("extensionSettingsEnable",
165 l10n_util::GetStringUTF16(IDS_EXTENSIONS_ENABLE
));
166 source
->AddString("extensionSettingsEnabled",
167 l10n_util::GetStringUTF16(IDS_EXTENSIONS_ENABLED
));
168 source
->AddString("extensionSettingsRemove",
169 l10n_util::GetStringUTF16(IDS_EXTENSIONS_REMOVE
));
170 source
->AddString("extensionSettingsEnableIncognito",
171 l10n_util::GetStringUTF16(IDS_EXTENSIONS_ENABLE_INCOGNITO
));
172 source
->AddString("extensionSettingsEnableErrorCollection",
173 l10n_util::GetStringUTF16(IDS_EXTENSIONS_ENABLE_ERROR_COLLECTION
));
174 source
->AddString("extensionSettingsAllowFileAccess",
175 l10n_util::GetStringUTF16(IDS_EXTENSIONS_ALLOW_FILE_ACCESS
));
176 source
->AddString("extensionSettingsAllowOnAllUrls",
177 l10n_util::GetStringUTF16(IDS_EXTENSIONS_ALLOW_ON_ALL_URLS
));
178 source
->AddString("extensionSettingsIncognitoWarning",
179 l10n_util::GetStringUTF16(IDS_EXTENSIONS_INCOGNITO_WARNING
));
180 source
->AddString("extensionSettingsReloadTerminated",
181 l10n_util::GetStringUTF16(IDS_EXTENSIONS_RELOAD_TERMINATED
));
182 source
->AddString("extensionSettingsRepairCorrupted",
183 l10n_util::GetStringUTF16(IDS_EXTENSIONS_REPAIR_CORRUPTED
));
184 source
->AddString("extensionSettingsLaunch",
185 l10n_util::GetStringUTF16(IDS_EXTENSIONS_LAUNCH
));
186 source
->AddString("extensionSettingsReloadUnpacked",
187 l10n_util::GetStringUTF16(IDS_EXTENSIONS_RELOAD_UNPACKED
));
188 source
->AddString("extensionSettingsOptions",
189 l10n_util::GetStringUTF16(IDS_EXTENSIONS_OPTIONS_LINK
));
190 if (CanShowAppInfoDialog()) {
191 source
->AddString("extensionSettingsPermissions",
192 l10n_util::GetStringUTF16(IDS_EXTENSIONS_INFO_LINK
));
195 "extensionSettingsPermissions",
196 l10n_util::GetStringUTF16(IDS_EXTENSIONS_PERMISSIONS_LINK
));
198 source
->AddString("extensionSettingsVisitWebsite",
199 l10n_util::GetStringUTF16(IDS_EXTENSIONS_VISIT_WEBSITE
));
200 source
->AddString("extensionSettingsVisitWebStore",
201 l10n_util::GetStringUTF16(IDS_EXTENSIONS_VISIT_WEBSTORE
));
202 source
->AddString("extensionSettingsPolicyControlled",
203 l10n_util::GetStringUTF16(IDS_EXTENSIONS_POLICY_CONTROLLED
));
204 source
->AddString("extensionSettingsPolicyRecommeneded",
205 l10n_util::GetStringUTF16(IDS_EXTENSIONS_POLICY_RECOMMENDED
));
206 source
->AddString("extensionSettingsDependentExtensions",
207 l10n_util::GetStringUTF16(IDS_EXTENSIONS_DEPENDENT_EXTENSIONS
));
208 source
->AddString("extensionSettingsSupervisedUser",
209 l10n_util::GetStringUTF16(IDS_EXTENSIONS_LOCKED_SUPERVISED_USER
));
210 source
->AddString("extensionSettingsCorruptInstall",
211 l10n_util::GetStringUTF16(
212 IDS_EXTENSIONS_CORRUPTED_EXTENSION
));
213 source
->AddString("extensionSettingsSuspiciousInstall",
214 l10n_util::GetStringFUTF16(
215 IDS_EXTENSIONS_ADDED_WITHOUT_KNOWLEDGE
,
216 l10n_util::GetStringUTF16(IDS_EXTENSION_WEB_STORE_TITLE
)));
217 source
->AddString("extensionSettingsLearnMore",
218 l10n_util::GetStringUTF16(IDS_LEARN_MORE
));
219 source
->AddString("extensionSettingsSuspiciousInstallHelpUrl",
221 google_util::AppendGoogleLocaleParam(
222 GURL(chrome::kRemoveNonCWSExtensionURL
),
223 g_browser_process
->GetApplicationLocale()).spec()));
224 source
->AddString("extensionSettingsShowButton",
225 l10n_util::GetStringUTF16(IDS_EXTENSIONS_SHOW_BUTTON
));
226 source
->AddString("extensionSettingsLoadUnpackedButton",
227 l10n_util::GetStringUTF16(IDS_EXTENSIONS_LOAD_UNPACKED_BUTTON
));
228 source
->AddString("extensionSettingsPackButton",
229 l10n_util::GetStringUTF16(IDS_EXTENSIONS_PACK_BUTTON
));
230 source
->AddString("extensionSettingsCommandsLink",
231 l10n_util::GetStringUTF16(IDS_EXTENSIONS_COMMANDS_CONFIGURE
));
232 source
->AddString("extensionSettingsUpdateButton",
233 l10n_util::GetStringUTF16(IDS_EXTENSIONS_UPDATE_BUTTON
));
235 "extensionSettingsAppsDevToolsPromoHTML",
236 l10n_util::GetStringFUTF16(
237 IDS_EXTENSIONS_APPS_DEV_TOOLS_PROMO_HTML
,
239 google_util::AppendGoogleLocaleParam(
240 GURL(extension_urls::GetWebstoreItemDetailURLPrefix() +
241 kAppsDeveloperToolsExtensionId
),
242 g_browser_process
->GetApplicationLocale()).spec())));
244 "extensionSettingsAppDevToolsPromoClose",
245 l10n_util::GetStringUTF16(IDS_CLOSE
));
246 source
->AddString("extensionSettingsCrashMessage",
247 l10n_util::GetStringUTF16(IDS_EXTENSIONS_CRASHED_EXTENSION
));
248 source
->AddString("extensionSettingsInDevelopment",
249 l10n_util::GetStringUTF16(IDS_EXTENSIONS_IN_DEVELOPMENT
));
250 source
->AddString("extensionSettingsWarningsTitle",
251 l10n_util::GetStringUTF16(IDS_EXTENSION_WARNINGS_TITLE
));
252 source
->AddString("extensionSettingsShowDetails",
253 l10n_util::GetStringUTF16(IDS_EXTENSIONS_SHOW_DETAILS
));
254 source
->AddString("extensionSettingsHideDetails",
255 l10n_util::GetStringUTF16(IDS_EXTENSIONS_HIDE_DETAILS
));
256 source
->AddString("extensionSettingsUpdateRequiredBePolicy",
257 l10n_util::GetStringUTF16(
258 IDS_EXTENSIONS_DISABLED_UPDATE_REQUIRED_BY_POLICY
));
260 // TODO(estade): comb through the above strings to find ones no longer used in
262 source
->AddString("extensionUninstall",
263 l10n_util::GetStringUTF16(IDS_EXTENSIONS_UNINSTALL
));
265 // Pack Extension Overlay:
266 source
->AddString("packExtensionOverlay",
267 l10n_util::GetStringUTF16(IDS_EXTENSION_PACK_DIALOG_TITLE
));
268 source
->AddString("packExtensionHeading",
269 l10n_util::GetStringUTF16(IDS_EXTENSION_PACK_DIALOG_HEADING
));
270 source
->AddString("packExtensionCommit",
271 l10n_util::GetStringUTF16(IDS_EXTENSION_PACK_BUTTON
));
272 source
->AddString("ok", l10n_util::GetStringUTF16(IDS_OK
));
273 source
->AddString("cancel", l10n_util::GetStringUTF16(IDS_CANCEL
));
274 source
->AddString("packExtensionRootDir",
275 l10n_util::GetStringUTF16(
276 IDS_EXTENSION_PACK_DIALOG_ROOT_DIRECTORY_LABEL
));
277 source
->AddString("packExtensionPrivateKey",
278 l10n_util::GetStringUTF16(IDS_EXTENSION_PACK_DIALOG_PRIVATE_KEY_LABEL
));
279 source
->AddString("packExtensionBrowseButton",
280 l10n_util::GetStringUTF16(IDS_EXTENSION_PACK_DIALOG_BROWSE
));
281 source
->AddString("packExtensionProceedAnyway",
282 l10n_util::GetStringUTF16(IDS_EXTENSION_PROCEED_ANYWAY
));
283 source
->AddString("packExtensionWarningTitle",
284 l10n_util::GetStringUTF16(IDS_EXTENSION_PACK_WARNING_TITLE
));
285 source
->AddString("packExtensionErrorTitle",
286 l10n_util::GetStringUTF16(IDS_EXTENSION_PACK_ERROR_TITLE
));
288 // Extension Error and Extension Error Overlay:
290 "extensionErrorsShowMore",
291 l10n_util::GetStringUTF16(IDS_EXTENSIONS_ERRORS_SHOW_MORE
));
293 "extensionErrorsShowFewer",
294 l10n_util::GetStringUTF16(IDS_EXTENSIONS_ERRORS_SHOW_FEWER
));
296 "extensionErrorViewDetails",
297 l10n_util::GetStringUTF16(IDS_EXTENSIONS_ERROR_VIEW_DETAILS
));
299 "extensionErrorViewManifest",
300 l10n_util::GetStringUTF16(IDS_EXTENSIONS_ERROR_VIEW_MANIFEST
));
301 source
->AddString("extensionErrorOverlayDone",
302 l10n_util::GetStringUTF16(IDS_DONE
));
304 "extensionErrorOverlayContextUrl",
305 l10n_util::GetStringUTF16(IDS_EXTENSIONS_ERROR_CONTEXT
));
307 "extensionErrorOverlayStackTrace",
308 l10n_util::GetStringUTF16(IDS_EXTENSIONS_ERROR_STACK_TRACE
));
310 "extensionErrorOverlayAnonymousFunction",
311 l10n_util::GetStringUTF16(IDS_EXTENSIONS_ERROR_ANONYMOUS_FUNCTION
));
313 "extensionErrorOverlayLaunchDevtools",
314 l10n_util::GetStringUTF16(IDS_EXTENSIONS_ERROR_LAUNCH_DEVTOOLS
));
316 "extensionErrorOverlayContextUnknown",
317 l10n_util::GetStringUTF16(IDS_EXTENSIONS_ERROR_CONTEXT_UNKNOWN
));
319 "extensionErrorOverlayNoCodeToDisplay",
320 l10n_util::GetStringUTF16(IDS_EXTENSIONS_ERROR_NO_CODE_TO_DISPLAY
));
323 void ExtensionSettingsHandler::RenderViewDeleted(
324 content::RenderViewHost
* render_view_host
) {
325 deleting_rvh_
= render_view_host
;
326 Profile
* source_profile
= Profile::FromBrowserContext(
327 render_view_host
->GetSiteInstance()->GetBrowserContext());
328 if (!Profile::FromWebUI(web_ui())->IsSameProfile(source_profile
))
330 MaybeUpdateAfterNotification();
333 void ExtensionSettingsHandler::DidStartNavigationToPendingEntry(
335 content::NavigationController::ReloadType reload_type
) {
336 if (reload_type
!= content::NavigationController::NO_RELOAD
)
337 ReloadUnpackedExtensions();
340 void ExtensionSettingsHandler::RegisterMessages() {
341 Profile
* profile
= Profile::FromWebUI(web_ui())->GetOriginalProfile();
343 extensions::ExtensionSystem::Get(profile
)->extension_service();
345 web_ui()->RegisterMessageCallback("extensionSettingsRequestExtensionsData",
346 base::Bind(&ExtensionSettingsHandler::HandleRequestExtensionsData
,
348 web_ui()->RegisterMessageCallback("extensionSettingsToggleDeveloperMode",
349 base::Bind(&ExtensionSettingsHandler::HandleToggleDeveloperMode
,
351 web_ui()->RegisterMessageCallback("extensionSettingsLaunch",
352 base::Bind(&ExtensionSettingsHandler::HandleLaunchMessage
,
354 web_ui()->RegisterMessageCallback("extensionSettingsRepair",
355 base::Bind(&ExtensionSettingsHandler::HandleRepairMessage
,
357 web_ui()->RegisterMessageCallback("extensionSettingsOptions",
358 base::Bind(&ExtensionSettingsHandler::HandleOptionsMessage
,
360 web_ui()->RegisterMessageCallback("extensionSettingsAutoupdate",
361 base::Bind(&ExtensionSettingsHandler::HandleAutoUpdateMessage
,
363 web_ui()->RegisterMessageCallback("extensionSettingsDismissADTPromo",
364 base::Bind(&ExtensionSettingsHandler::HandleDismissADTPromoMessage
,
366 web_ui()->RegisterMessageCallback("extensionSettingsShowPath",
367 base::Bind(&ExtensionSettingsHandler::HandleShowPath
,
371 void ExtensionSettingsHandler::OnErrorAdded(const ExtensionError
* error
) {
372 MaybeUpdateAfterNotification();
375 void ExtensionSettingsHandler::Observe(
377 const content::NotificationSource
& source
,
378 const content::NotificationDetails
& details
) {
379 Profile
* profile
= Profile::FromWebUI(web_ui());
380 Profile
* source_profile
= NULL
;
382 // We listen for notifications that will result in the page being
383 // repopulated with data twice for the same event in certain cases.
384 // For instance, EXTENSION_LOADED & EXTENSION_HOST_CREATED because
385 // we don't know about the views for an extension at EXTENSION_LOADED, but
386 // if we only listen to EXTENSION_HOST_CREATED, we'll miss extensions
387 // that don't have a process at startup.
389 // Doing it this way gets everything but causes the page to be rendered
390 // more than we need. It doesn't seem to result in any noticeable flicker.
391 case chrome::NOTIFICATION_BACKGROUND_CONTENTS_DELETED
:
392 deleting_rvh_
= content::Details
<BackgroundContents
>(details
)->
393 web_contents()->GetRenderViewHost();
395 case chrome::NOTIFICATION_BACKGROUND_CONTENTS_NAVIGATED
:
396 case extensions::NOTIFICATION_EXTENSION_HOST_CREATED
:
397 source_profile
= content::Source
<Profile
>(source
).ptr();
398 if (!profile
->IsSameProfile(source_profile
))
400 MaybeUpdateAfterNotification();
402 case content::NOTIFICATION_RENDER_WIDGET_HOST_DESTROYED
: {
403 content::RenderWidgetHost
* rwh
=
404 content::Source
<content::RenderWidgetHost
>(source
).ptr();
405 deleting_rwh_id_
= rwh
->GetRoutingID();
406 deleting_rph_id_
= rwh
->GetProcess()->GetID();
407 MaybeUpdateAfterNotification();
410 case extensions::NOTIFICATION_EXTENSION_UPDATE_DISABLED
:
411 case extensions::NOTIFICATION_EXTENSION_BROWSER_ACTION_VISIBILITY_CHANGED
:
412 MaybeUpdateAfterNotification();
414 case extensions::NOTIFICATION_EXTENSION_HOST_DESTROYED
:
415 // This notification is sent when the extension host destruction begins,
416 // not when it finishes. We use PostTask to delay the update until after
417 // the destruction finishes.
418 base::MessageLoop::current()->PostTask(
420 base::Bind(&ExtensionSettingsHandler::MaybeUpdateAfterNotification
,
428 void ExtensionSettingsHandler::OnExtensionLoaded(
429 content::BrowserContext
* browser_context
,
430 const Extension
* extension
) {
431 MaybeUpdateAfterNotification();
434 void ExtensionSettingsHandler::OnExtensionUnloaded(
435 content::BrowserContext
* browser_context
,
436 const Extension
* extension
,
437 UnloadedExtensionInfo::Reason reason
) {
438 MaybeUpdateAfterNotification();
441 void ExtensionSettingsHandler::OnExtensionUninstalled(
442 content::BrowserContext
* browser_context
,
443 const Extension
* extension
,
444 extensions::UninstallReason reason
) {
445 MaybeUpdateAfterNotification();
448 void ExtensionSettingsHandler::OnExtensionDisableReasonsChanged(
449 const std::string
& extension_id
, int disable_reasons
) {
450 MaybeUpdateAfterNotification();
453 void ExtensionSettingsHandler::OnExtensionManagementSettingsChanged() {
454 MaybeUpdateAfterNotification();
457 void ExtensionSettingsHandler::ExtensionWarningsChanged() {
458 MaybeUpdateAfterNotification();
461 void ExtensionSettingsHandler::ReloadUnpackedExtensions() {
462 ExtensionRegistry
* registry
=
463 ExtensionRegistry::Get(extension_service_
->profile());
464 std::vector
<const Extension
*> unpacked_extensions
;
465 for (const scoped_refptr
<const extensions::Extension
>& extension
:
466 registry
->enabled_extensions()) {
467 if (Manifest::IsUnpackedLocation(extension
->location()))
468 unpacked_extensions
.push_back(extension
.get());
471 for (std::vector
<const Extension
*>::iterator iter
=
472 unpacked_extensions
.begin(); iter
!= unpacked_extensions
.end(); ++iter
) {
473 extension_service_
->ReloadExtensionWithQuietFailure((*iter
)->id());
477 void ExtensionSettingsHandler::HandleRequestExtensionsData(
478 const base::ListValue
* args
) {
479 // The items which are to be written into results are also described in
480 // chrome/browser/resources/extensions/extensions.js in @typedef for
481 // ExtensionDataResponse. Please update it whenever you add or remove any keys
483 base::DictionaryValue results
;
485 Profile
* profile
= Profile::FromWebUI(web_ui());
487 bool is_supervised
= profile
->IsSupervised();
488 bool incognito_available
=
489 IncognitoModePrefs::GetAvailability(profile
->GetPrefs()) !=
490 IncognitoModePrefs::DISABLED
;
491 bool developer_mode
=
493 profile
->GetPrefs()->GetBoolean(prefs::kExtensionsUIDeveloperMode
);
494 results
.SetBoolean("profileIsSupervised", is_supervised
);
495 results
.SetBoolean("incognitoAvailable", incognito_available
);
496 results
.SetBoolean("developerMode", developer_mode
);
497 results
.SetBoolean("enableAppInfoDialog", CanShowAppInfoDialog());
499 // Promote the Chrome Apps & Extensions Developer Tools if they are not
500 // installed and the user has not previously dismissed the warning.
501 bool promote_apps_dev_tools
= false;
502 if (!ExtensionRegistry::Get(Profile::FromWebUI(web_ui()))->
503 GetExtensionById(kAppsDeveloperToolsExtensionId
,
504 ExtensionRegistry::EVERYTHING
) &&
505 !profile
->GetPrefs()->GetBoolean(prefs::kExtensionsUIDismissedADTPromo
)) {
506 promote_apps_dev_tools
= true;
508 results
.SetBoolean("promoteAppsDevTools", promote_apps_dev_tools
);
510 const bool load_unpacked_disabled
=
511 ExtensionManagementFactory::GetForBrowserContext(profile
)
512 ->BlacklistedByDefault();
513 results
.SetBoolean("loadUnpackedDisabled", load_unpacked_disabled
);
515 web_ui()->CallJavascriptFunction(
516 "extensions.ExtensionSettings.returnExtensionsData", results
);
518 MaybeRegisterForNotifications();
519 UMA_HISTOGRAM_BOOLEAN("ExtensionSettings.ShouldDoVerificationCheck",
520 should_do_verification_check_
);
521 if (should_do_verification_check_
) {
522 should_do_verification_check_
= false;
523 ExtensionSystem::Get(Profile::FromWebUI(web_ui()))
525 ->VerifyAllExtensions();
529 void ExtensionSettingsHandler::HandleToggleDeveloperMode(
530 const base::ListValue
* args
) {
531 Profile
* profile
= Profile::FromWebUI(web_ui());
532 if (profile
->IsSupervised())
535 bool developer_mode_on
;
536 CHECK(args
->GetBoolean(0, &developer_mode_on
));
537 profile
->GetPrefs()->SetBoolean(prefs::kExtensionsUIDeveloperMode
,
541 void ExtensionSettingsHandler::HandleLaunchMessage(
542 const base::ListValue
* args
) {
543 CHECK_EQ(1U, args
->GetSize());
544 std::string extension_id
;
545 CHECK(args
->GetString(0, &extension_id
));
546 const Extension
* extension
=
547 extension_service_
->GetExtensionById(extension_id
, false);
548 OpenApplication(AppLaunchParams(extension_service_
->profile(), extension
,
549 extensions::LAUNCH_CONTAINER_WINDOW
,
551 extensions::SOURCE_EXTENSIONS_PAGE
));
554 void ExtensionSettingsHandler::HandleRepairMessage(
555 const base::ListValue
* args
) {
556 std::string extension_id
= base::UTF16ToUTF8(ExtractStringValue(args
));
557 CHECK(!extension_id
.empty());
558 scoped_refptr
<WebstoreReinstaller
> reinstaller(new WebstoreReinstaller(
561 base::Bind(&ExtensionSettingsHandler::OnReinstallComplete
,
563 reinstaller
->BeginReinstall();
566 void ExtensionSettingsHandler::HandleOptionsMessage(
567 const base::ListValue
* args
) {
568 const Extension
* extension
= GetActiveExtension(args
);
569 if (!extension
|| OptionsPageInfo::GetOptionsPage(extension
).is_empty())
571 ExtensionTabUtil::OpenOptionsPage(extension
,
572 chrome::FindBrowserWithWebContents(web_ui()->GetWebContents()));
575 void ExtensionSettingsHandler::HandleAutoUpdateMessage(
576 const base::ListValue
* args
) {
577 ExtensionUpdater
* updater
= extension_service_
->updater();
579 ExtensionUpdater::CheckParams params
;
580 params
.install_immediately
= true;
581 updater
->CheckNow(params
);
585 void ExtensionSettingsHandler::HandleDismissADTPromoMessage(
586 const base::ListValue
* args
) {
587 DCHECK(args
->empty());
588 Profile::FromWebUI(web_ui())->GetPrefs()->SetBoolean(
589 prefs::kExtensionsUIDismissedADTPromo
, true);
592 void ExtensionSettingsHandler::HandleShowPath(const base::ListValue
* args
) {
593 DCHECK(!args
->empty());
594 std::string extension_id
= base::UTF16ToUTF8(ExtractStringValue(args
));
596 Profile
* profile
= Profile::FromWebUI(web_ui());
597 ExtensionRegistry
* registry
= ExtensionRegistry::Get(profile
);
598 const Extension
* extension
= registry
->GetExtensionById(
600 ExtensionRegistry::EVERYTHING
);
602 // We explicitly show manifest.json in order to work around an issue in OSX
603 // where opening the directory doesn't focus the Finder.
604 platform_util::ShowItemInFolder(profile
,
605 extension
->path().Append(kManifestFilename
));
608 const Extension
* ExtensionSettingsHandler::GetActiveExtension(
609 const base::ListValue
* args
) {
610 std::string extension_id
= base::UTF16ToUTF8(ExtractStringValue(args
));
611 CHECK(!extension_id
.empty());
612 return extension_service_
->GetExtensionById(extension_id
, false);
615 void ExtensionSettingsHandler::MaybeUpdateAfterNotification() {
616 content::WebContents
* contents
= web_ui()->GetWebContents();
617 if (!ignore_notifications_
&& contents
&& contents
->GetRenderViewHost())
618 HandleRequestExtensionsData(NULL
);
619 deleting_rvh_
= NULL
;
622 void ExtensionSettingsHandler::MaybeRegisterForNotifications() {
623 if (registered_for_notifications_
)
626 registered_for_notifications_
= true;
627 Profile
* profile
= Profile::FromWebUI(web_ui());
629 // Register for notifications that we need to reload the page.
631 extensions::NOTIFICATION_EXTENSION_UPDATE_DISABLED
,
632 content::Source
<Profile
>(profile
));
634 extensions::NOTIFICATION_EXTENSION_HOST_CREATED
,
635 content::NotificationService::AllBrowserContextsAndSources());
637 chrome::NOTIFICATION_BACKGROUND_CONTENTS_NAVIGATED
,
638 content::NotificationService::AllBrowserContextsAndSources());
640 chrome::NOTIFICATION_BACKGROUND_CONTENTS_DELETED
,
641 content::NotificationService::AllBrowserContextsAndSources());
644 extensions::NOTIFICATION_EXTENSION_BROWSER_ACTION_VISIBILITY_CHANGED
,
645 content::Source
<ExtensionPrefs
>(ExtensionPrefs::Get(profile
)));
647 extensions::NOTIFICATION_EXTENSION_HOST_DESTROYED
,
648 content::NotificationService::AllBrowserContextsAndSources());
650 content::NOTIFICATION_RENDER_WIDGET_HOST_DESTROYED
,
651 content::NotificationService::AllBrowserContextsAndSources());
653 extension_registry_observer_
.Add(ExtensionRegistry::Get(profile
));
655 content::WebContentsObserver::Observe(web_ui()->GetWebContents());
657 warning_service_observer_
.Add(WarningService::Get(profile
));
659 error_console_observer_
.Add(ErrorConsole::Get(profile
));
661 extension_management_observer_
.Add(
662 ExtensionManagementFactory::GetForBrowserContext(profile
));
665 void ExtensionSettingsHandler::OnReinstallComplete(
667 const std::string
& error
,
668 webstore_install::Result result
) {
669 MaybeUpdateAfterNotification();
672 } // namespace extensions