Revert of Add button to add new FSP services to Files app. (patchset #8 id:140001...
[chromium-blink-merge.git] / chrome / browser / ui / webui / extensions / extension_settings_handler.cc
blob92cdd553cc938cea3a8fedfcf0735177164d8d64
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"
7 #include <vector>
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"
77 #include "url/gurl.h"
79 namespace {
81 const char kAppsDeveloperToolsExtensionId[] =
82 "ohmmkhmmmpcnpikjeljgnaoabkaalbgc";
84 } // namespace
86 namespace extensions {
88 ///////////////////////////////////////////////////////////////////////////////
90 // ExtensionSettingsHandler
92 ///////////////////////////////////////////////////////////////////////////////
94 ExtensionSettingsHandler::ExtensionSettingsHandler()
95 : extension_service_(NULL),
96 ignore_notifications_(false),
97 deleting_rvh_(NULL),
98 deleting_rwh_id_(-1),
99 deleting_rph_id_(-1),
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() {
112 // static
113 void ExtensionSettingsHandler::RegisterProfilePrefs(
114 user_prefs::PrefRegistrySyncable* registry) {
115 registry->RegisterBooleanPref(
116 prefs::kExtensionsUIDeveloperMode,
117 false,
118 user_prefs::PrefRegistrySyncable::SYNCABLE_PREF);
119 registry->RegisterBooleanPref(
120 prefs::kExtensionsUIDismissedADTPromo,
121 false,
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));
134 source->AddString(
135 "extensionSettingsSuggestGallery",
136 l10n_util::GetStringFUTF16(
137 IDS_EXTENSIONS_NONE_INSTALLED_SUGGEST_GALLERY,
138 base::ASCIIToUTF16(
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));
144 source->AddString(
145 "extensionSettingsGetMoreExtensionsUrl",
146 base::ASCIIToUTF16(
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));
193 } else {
194 source->AddString(
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",
220 base::ASCIIToUTF16(
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));
234 source->AddString(
235 "extensionSettingsAppsDevToolsPromoHTML",
236 l10n_util::GetStringFUTF16(
237 IDS_EXTENSIONS_APPS_DEV_TOOLS_PROMO_HTML,
238 base::ASCIIToUTF16(
239 google_util::AppendGoogleLocaleParam(
240 GURL(extension_urls::GetWebstoreItemDetailURLPrefix() +
241 kAppsDeveloperToolsExtensionId),
242 g_browser_process->GetApplicationLocale()).spec())));
243 source->AddString(
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
261 // uber extensions.
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:
289 source->AddString(
290 "extensionErrorsShowMore",
291 l10n_util::GetStringUTF16(IDS_EXTENSIONS_ERRORS_SHOW_MORE));
292 source->AddString(
293 "extensionErrorsShowFewer",
294 l10n_util::GetStringUTF16(IDS_EXTENSIONS_ERRORS_SHOW_FEWER));
295 source->AddString(
296 "extensionErrorViewDetails",
297 l10n_util::GetStringUTF16(IDS_EXTENSIONS_ERROR_VIEW_DETAILS));
298 source->AddString(
299 "extensionErrorViewManifest",
300 l10n_util::GetStringUTF16(IDS_EXTENSIONS_ERROR_VIEW_MANIFEST));
301 source->AddString("extensionErrorOverlayDone",
302 l10n_util::GetStringUTF16(IDS_DONE));
303 source->AddString(
304 "extensionErrorOverlayContextUrl",
305 l10n_util::GetStringUTF16(IDS_EXTENSIONS_ERROR_CONTEXT));
306 source->AddString(
307 "extensionErrorOverlayStackTrace",
308 l10n_util::GetStringUTF16(IDS_EXTENSIONS_ERROR_STACK_TRACE));
309 source->AddString(
310 "extensionErrorOverlayAnonymousFunction",
311 l10n_util::GetStringUTF16(IDS_EXTENSIONS_ERROR_ANONYMOUS_FUNCTION));
312 source->AddString(
313 "extensionErrorOverlayLaunchDevtools",
314 l10n_util::GetStringUTF16(IDS_EXTENSIONS_ERROR_LAUNCH_DEVTOOLS));
315 source->AddString(
316 "extensionErrorOverlayContextUnknown",
317 l10n_util::GetStringUTF16(IDS_EXTENSIONS_ERROR_CONTEXT_UNKNOWN));
318 source->AddString(
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))
329 return;
330 MaybeUpdateAfterNotification();
333 void ExtensionSettingsHandler::DidStartNavigationToPendingEntry(
334 const GURL& url,
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();
342 extension_service_ =
343 extensions::ExtensionSystem::Get(profile)->extension_service();
345 web_ui()->RegisterMessageCallback("extensionSettingsRequestExtensionsData",
346 base::Bind(&ExtensionSettingsHandler::HandleRequestExtensionsData,
347 AsWeakPtr()));
348 web_ui()->RegisterMessageCallback("extensionSettingsToggleDeveloperMode",
349 base::Bind(&ExtensionSettingsHandler::HandleToggleDeveloperMode,
350 AsWeakPtr()));
351 web_ui()->RegisterMessageCallback("extensionSettingsLaunch",
352 base::Bind(&ExtensionSettingsHandler::HandleLaunchMessage,
353 AsWeakPtr()));
354 web_ui()->RegisterMessageCallback("extensionSettingsRepair",
355 base::Bind(&ExtensionSettingsHandler::HandleRepairMessage,
356 AsWeakPtr()));
357 web_ui()->RegisterMessageCallback("extensionSettingsOptions",
358 base::Bind(&ExtensionSettingsHandler::HandleOptionsMessage,
359 AsWeakPtr()));
360 web_ui()->RegisterMessageCallback("extensionSettingsAutoupdate",
361 base::Bind(&ExtensionSettingsHandler::HandleAutoUpdateMessage,
362 AsWeakPtr()));
363 web_ui()->RegisterMessageCallback("extensionSettingsDismissADTPromo",
364 base::Bind(&ExtensionSettingsHandler::HandleDismissADTPromoMessage,
365 AsWeakPtr()));
366 web_ui()->RegisterMessageCallback("extensionSettingsShowPath",
367 base::Bind(&ExtensionSettingsHandler::HandleShowPath,
368 AsWeakPtr()));
371 void ExtensionSettingsHandler::OnErrorAdded(const ExtensionError* error) {
372 MaybeUpdateAfterNotification();
375 void ExtensionSettingsHandler::Observe(
376 int type,
377 const content::NotificationSource& source,
378 const content::NotificationDetails& details) {
379 Profile* profile = Profile::FromWebUI(web_ui());
380 Profile* source_profile = NULL;
381 switch (type) {
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();
394 // Fall through.
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))
399 return;
400 MaybeUpdateAfterNotification();
401 break;
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();
408 break;
410 case extensions::NOTIFICATION_EXTENSION_UPDATE_DISABLED:
411 case extensions::NOTIFICATION_EXTENSION_BROWSER_ACTION_VISIBILITY_CHANGED:
412 MaybeUpdateAfterNotification();
413 break;
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(
419 FROM_HERE,
420 base::Bind(&ExtensionSettingsHandler::MaybeUpdateAfterNotification,
421 AsWeakPtr()));
422 break;
423 default:
424 NOTREACHED();
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
482 // here.
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 =
492 !is_supervised &&
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()))
524 ->install_verifier()
525 ->VerifyAllExtensions();
529 void ExtensionSettingsHandler::HandleToggleDeveloperMode(
530 const base::ListValue* args) {
531 Profile* profile = Profile::FromWebUI(web_ui());
532 if (profile->IsSupervised())
533 return;
535 bool developer_mode_on;
536 CHECK(args->GetBoolean(0, &developer_mode_on));
537 profile->GetPrefs()->SetBoolean(prefs::kExtensionsUIDeveloperMode,
538 developer_mode_on);
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,
550 NEW_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(
559 web_contents(),
560 extension_id,
561 base::Bind(&ExtensionSettingsHandler::OnReinstallComplete,
562 AsWeakPtr())));
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())
570 return;
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();
578 if (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(
599 extension_id,
600 ExtensionRegistry::EVERYTHING);
601 CHECK(extension);
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_)
624 return;
626 registered_for_notifications_ = true;
627 Profile* profile = Profile::FromWebUI(web_ui());
629 // Register for notifications that we need to reload the page.
630 registrar_.Add(this,
631 extensions::NOTIFICATION_EXTENSION_UPDATE_DISABLED,
632 content::Source<Profile>(profile));
633 registrar_.Add(this,
634 extensions::NOTIFICATION_EXTENSION_HOST_CREATED,
635 content::NotificationService::AllBrowserContextsAndSources());
636 registrar_.Add(this,
637 chrome::NOTIFICATION_BACKGROUND_CONTENTS_NAVIGATED,
638 content::NotificationService::AllBrowserContextsAndSources());
639 registrar_.Add(this,
640 chrome::NOTIFICATION_BACKGROUND_CONTENTS_DELETED,
641 content::NotificationService::AllBrowserContextsAndSources());
642 registrar_.Add(
643 this,
644 extensions::NOTIFICATION_EXTENSION_BROWSER_ACTION_VISIBILITY_CHANGED,
645 content::Source<ExtensionPrefs>(ExtensionPrefs::Get(profile)));
646 registrar_.Add(this,
647 extensions::NOTIFICATION_EXTENSION_HOST_DESTROYED,
648 content::NotificationService::AllBrowserContextsAndSources());
649 registrar_.Add(this,
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(
666 bool success,
667 const std::string& error,
668 webstore_install::Result result) {
669 MaybeUpdateAfterNotification();
672 } // namespace extensions