extensions_ui.cc revision 3345a6884c488ff3a535c2c9acdd33d74b37e311
1c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Copyright (c) 2010 The Chromium Authors. All rights reserved.
2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file.
4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/extensions/extensions_ui.h"
6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "app/l10n_util.h"
8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "app/resource_bundle.h"
9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/base64.h"
10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/callback.h"
11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/file_util.h"
123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/string_number_conversions.h"
13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/string_util.h"
143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/utf_string_conversions.h"
15c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/thread.h"
163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/version.h"
17c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/browser.h"
183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "chrome/browser/browser_list.h"
19c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/browser_process.h"
20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/debugger/devtools_manager.h"
21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/debugger/devtools_toggle_action.h"
22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/extensions/crx_installer.h"
23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/extensions/extension_disabled_infobar_delegate.h"
24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/extensions/extension_error_reporter.h"
25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/extensions/extension_function_dispatcher.h"
26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/extensions/extension_host.h"
27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/extensions/extension_message_service.h"
28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/extensions/extensions_service.h"
29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/extensions/extension_updater.h"
303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "chrome/browser/google/google_util.h"
313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "chrome/browser/prefs/pref_service.h"
32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/profile.h"
33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/renderer_host/render_process_host.h"
34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/renderer_host/render_widget_host.h"
35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/renderer_host/render_view_host.h"
36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/tab_contents/background_contents.h"
37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/tab_contents/tab_contents.h"
38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/tab_contents/tab_contents_view.h"
39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/chrome_switches.h"
40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/extensions/extension.h"
413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "chrome/common/extensions/extension_icon_set.h"
42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/extensions/user_script.h"
43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/extensions/url_pattern.h"
44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/jstemplate_builder.h"
45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/notification_service.h"
46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/notification_type.h"
47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/pref_names.h"
48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/url_constants.h"
49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "gfx/codec/png_codec.h"
50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "gfx/color_utils.h"
51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "gfx/skbitmap_operations.h"
52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "grit/browser_resources.h"
53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "grit/chromium_strings.h"
54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "grit/generated_resources.h"
55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "grit/theme_resources.h"
56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/base/net_util.h"
57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "webkit/glue/image_decoder.h"
58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace {
60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickbool ShouldShowExtension(Extension* extension) {
623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Don't show themes since this page's UI isn't really useful for themes.
64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (extension->is_theme())
65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return false;
66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Don't show component extensions because they are only extensions as an
68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // implementation detail of Chrome.
69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (extension->location() == Extension::COMPONENT)
70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return false;
71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Always show unpacked extensions and apps.
733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (extension->location() == Extension::LOAD)
743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    return true;
753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Unless they are unpacked, never show hosted apps.
773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (extension->is_hosted_app())
783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    return false;
793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return true;
81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}  // namespace
84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch////////////////////////////////////////////////////////////////////////////////
86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//
87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// ExtensionsHTMLSource
88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//
89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch////////////////////////////////////////////////////////////////////////////////
90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
91c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochExtensionsUIHTMLSource::ExtensionsUIHTMLSource()
92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    : DataSource(chrome::kChromeUIExtensionsHost, MessageLoop::current()) {
93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ExtensionsUIHTMLSource::StartDataRequest(const std::string& path,
96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    bool is_off_the_record, int request_id) {
97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DictionaryValue localized_strings;
983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  localized_strings.SetString("title",
993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      l10n_util::GetStringUTF16(IDS_EXTENSIONS_TITLE));
1003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  localized_strings.SetString("devModeLink",
1013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      l10n_util::GetStringUTF16(IDS_EXTENSIONS_DEVELOPER_MODE_LINK));
1023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  localized_strings.SetString("devModePrefix",
1033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      l10n_util::GetStringUTF16(IDS_EXTENSIONS_DEVELOPER_MODE_PREFIX));
1043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  localized_strings.SetString("loadUnpackedButton",
1053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      l10n_util::GetStringUTF16(IDS_EXTENSIONS_LOAD_UNPACKED_BUTTON));
1063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  localized_strings.SetString("packButton",
1073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      l10n_util::GetStringUTF16(IDS_EXTENSIONS_PACK_BUTTON));
1083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  localized_strings.SetString("updateButton",
1093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      l10n_util::GetStringUTF16(IDS_EXTENSIONS_UPDATE_BUTTON));
1103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  localized_strings.SetString("noExtensions",
1113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      l10n_util::GetStringUTF16(IDS_EXTENSIONS_NONE_INSTALLED));
1123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  localized_strings.SetString("suggestGallery",
1133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      l10n_util::GetStringFUTF16(IDS_EXTENSIONS_NONE_INSTALLED_SUGGEST_GALLERY,
1143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick          ASCIIToUTF16("<a href='") +
1153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick          ASCIIToUTF16(google_util::AppendGoogleLocaleParam(
1163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick              GURL(Extension::ChromeStoreURL())).spec()) + ASCIIToUTF16("'>"),
1173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick          ASCIIToUTF16("</a>")));
1183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  localized_strings.SetString("getMoreExtensions",
1193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      ASCIIToUTF16("<a href='") +
1203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick          ASCIIToUTF16(google_util::AppendGoogleLocaleParam(
1213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick              GURL(Extension::ChromeStoreURL())).spec()) + ASCIIToUTF16("'>") +
1223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick          l10n_util::GetStringUTF16(IDS_GET_MORE_EXTENSIONS) +
1233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick          ASCIIToUTF16("</a>"));
1243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  localized_strings.SetString("extensionDisabled",
1253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      l10n_util::GetStringUTF16(IDS_EXTENSIONS_DISABLED_EXTENSION));
1263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  localized_strings.SetString("inDevelopment",
1273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      l10n_util::GetStringUTF16(IDS_EXTENSIONS_IN_DEVELOPMENT));
1283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  localized_strings.SetString("viewIncognito",
1293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      l10n_util::GetStringUTF16(IDS_EXTENSIONS_VIEW_INCOGNITO));
1303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  localized_strings.SetString("extensionId",
1313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      l10n_util::GetStringUTF16(IDS_EXTENSIONS_ID));
1323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  localized_strings.SetString("extensionVersion",
1333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      l10n_util::GetStringUTF16(IDS_EXTENSIONS_VERSION));
1343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  localized_strings.SetString("inspectViews",
1353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      l10n_util::GetStringUTF16(IDS_EXTENSIONS_INSPECT_VIEWS));
1363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  localized_strings.SetString("inspectPopupsInstructions",
1373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      l10n_util::GetStringUTF16(IDS_EXTENSIONS_INSPECT_POPUPS_INSTRUCTIONS));
1383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  localized_strings.SetString("disable",
1393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      l10n_util::GetStringUTF16(IDS_EXTENSIONS_DISABLE));
1403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  localized_strings.SetString("enable",
1413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      l10n_util::GetStringUTF16(IDS_EXTENSIONS_ENABLE));
1423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  localized_strings.SetString("enableIncognito",
1433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      l10n_util::GetStringUTF16(IDS_EXTENSIONS_ENABLE_INCOGNITO));
1443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  localized_strings.SetString("allowFileAccess",
1453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      l10n_util::GetStringUTF16(IDS_EXTENSIONS_ALLOW_FILE_ACCESS));
1463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  localized_strings.SetString("incognitoWarning",
1473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      l10n_util::GetStringUTF16(IDS_EXTENSIONS_INCOGNITO_WARNING));
1483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  localized_strings.SetString("reload",
1493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      l10n_util::GetStringUTF16(IDS_EXTENSIONS_RELOAD));
1503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  localized_strings.SetString("uninstall",
1513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      l10n_util::GetStringUTF16(IDS_EXTENSIONS_UNINSTALL));
1523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  localized_strings.SetString("options",
1533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      l10n_util::GetStringUTF16(IDS_EXTENSIONS_OPTIONS));
1543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  localized_strings.SetString("packDialogTitle",
1553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      l10n_util::GetStringUTF16(IDS_EXTENSION_PACK_DIALOG_TITLE));
1563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  localized_strings.SetString("packDialogHeading",
1573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      l10n_util::GetStringUTF16(IDS_EXTENSION_PACK_DIALOG_HEADING));
1583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  localized_strings.SetString("rootDirectoryLabel",
1593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      l10n_util::GetStringUTF16(
1603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick          IDS_EXTENSION_PACK_DIALOG_ROOT_DIRECTORY_LABEL));
1613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  localized_strings.SetString("packDialogBrowse",
1623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      l10n_util::GetStringUTF16(IDS_EXTENSION_PACK_DIALOG_BROWSE));
1633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  localized_strings.SetString("privateKeyLabel",
1643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      l10n_util::GetStringUTF16(IDS_EXTENSION_PACK_DIALOG_PRIVATE_KEY_LABEL));
1653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  localized_strings.SetString("okButton",
1663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      l10n_util::GetStringUTF16(IDS_OK));
1673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  localized_strings.SetString("cancelButton",
1683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      l10n_util::GetStringUTF16(IDS_CANCEL));
169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  SetFontAndTextDirection(&localized_strings);
171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  static const base::StringPiece extensions_html(
173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      ResourceBundle::GetSharedInstance().GetRawDataResource(
174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          IDR_EXTENSIONS_UI_HTML));
175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string full_html(extensions_html.data(), extensions_html.size());
176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  jstemplate_builder::AppendJsonHtml(&localized_strings, &full_html);
177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  jstemplate_builder::AppendI18nTemplateSourceHtml(&full_html);
178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  jstemplate_builder::AppendI18nTemplateProcessHtml(&full_html);
179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  jstemplate_builder::AppendJsTemplateSourceHtml(&full_html);
180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_refptr<RefCountedBytes> html_bytes(new RefCountedBytes);
182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  html_bytes->data.resize(full_html.size());
183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::copy(full_html.begin(), full_html.end(), html_bytes->data.begin());
184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  SendResponse(request_id, html_bytes);
186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
188c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
189c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch////////////////////////////////////////////////////////////////////////////////
190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//
191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// ExtensionsDOMHandler::IconLoader
192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//
193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch////////////////////////////////////////////////////////////////////////////////
194c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
195c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochExtensionsDOMHandler::IconLoader::IconLoader(ExtensionsDOMHandler* handler)
196c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    : handler_(handler) {
197c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
198c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
199c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ExtensionsDOMHandler::IconLoader::LoadIcons(
200c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    std::vector<ExtensionResource>* icons, DictionaryValue* json) {
201c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ChromeThread::PostTask(
202c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      ChromeThread::FILE, FROM_HERE,
203c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NewRunnableMethod(this,
204c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          &IconLoader::LoadIconsOnFileThread, icons, json));
205c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
206c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
207c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ExtensionsDOMHandler::IconLoader::Cancel() {
208c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  handler_ = NULL;
209c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
210c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
211c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ExtensionsDOMHandler::IconLoader::LoadIconsOnFileThread(
212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    std::vector<ExtensionResource>* icons, DictionaryValue* json) {
213c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_ptr<std::vector<ExtensionResource> > icons_deleter(icons);
214c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_ptr<DictionaryValue> json_deleter(json);
215c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
216c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ListValue* extensions = NULL;
2173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  CHECK(json->GetList("extensions", &extensions));
218c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (size_t i = 0; i < icons->size(); ++i) {
220c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DictionaryValue* extension = NULL;
221c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    CHECK(extensions->GetDictionary(static_cast<int>(i), &extension));
222c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Read the file.
224c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    std::string file_contents;
225c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (icons->at(i).relative_path().empty() ||
226c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        !file_util::ReadFileToString(icons->at(i).GetFilePath(),
227c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                     &file_contents)) {
2283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      // If there's no icon, use the default icon. This is safe to do from
229c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // the file thread.
2303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      // TODO(erikkay) Assuming we're going to keep showing apps in this list,
2313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      // then we need to figure out when we should use the app default icon.
232c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      file_contents = ResourceBundle::GetSharedInstance().GetRawDataResource(
233c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          IDR_EXTENSION_DEFAULT_ICON).as_string();
234c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
235c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
236c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // If the extension is disabled, we desaturate the icon to add to the
237c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // disabledness effect.
238c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    bool enabled = false;
2393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    CHECK(extension->GetBoolean("enabled", &enabled));
240c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (!enabled) {
241c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      const unsigned char* data =
242c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          reinterpret_cast<const unsigned char*>(file_contents.data());
243c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      webkit_glue::ImageDecoder decoder;
244c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      scoped_ptr<SkBitmap> decoded(new SkBitmap());
245c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      *decoded = decoder.Decode(data, file_contents.length());
246c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
247c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // Desaturate the icon and lighten it a bit.
248c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      color_utils::HSL shift = {-1, 0, 0.6};
249c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      *decoded = SkBitmapOperations::CreateHSLShiftedBitmap(*decoded, shift);
250c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
251c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      std::vector<unsigned char> output;
252c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      gfx::PNGCodec::EncodeBGRASkBitmap(*decoded, false, &output);
253c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
254c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // Lame, but we must make a copy of this now, because base64 doesn't take
255c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // the same input type.
256c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      file_contents.assign(reinterpret_cast<char*>(&output.front()),
257c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                           output.size());
258c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
259c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
260c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Create a data URL (all icons are converted to PNGs during unpacking).
261c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    std::string base64_encoded;
262c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    base::Base64Encode(file_contents, &base64_encoded);
263c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    GURL icon_url("data:image/png;base64," + base64_encoded);
264c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    extension->SetString("icon", icon_url.spec());
266c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
267c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
268c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ChromeThread::PostTask(
269c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      ChromeThread::UI, FROM_HERE,
270c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NewRunnableMethod(this, &IconLoader::ReportResultOnUIThread,
271c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                        json_deleter.release()));
272c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
273c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
274c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ExtensionsDOMHandler::IconLoader::ReportResultOnUIThread(
275c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DictionaryValue* json) {
276c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (handler_)
277c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    handler_->OnIconsLoaded(json);
278c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
279c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
280c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
281c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch///////////////////////////////////////////////////////////////////////////////
282c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//
283c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// ExtensionsDOMHandler
284c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//
285c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch///////////////////////////////////////////////////////////////////////////////
286c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
287c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochExtensionsDOMHandler::ExtensionsDOMHandler(ExtensionsService* extension_service)
288c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    : extensions_service_(extension_service),
289c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      ignore_notifications_(false),
290c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      deleting_rvh_(NULL) {
291c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
292c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
293c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ExtensionsDOMHandler::RegisterMessages() {
294c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  dom_ui_->RegisterMessageCallback("requestExtensionsData",
295c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NewCallback(this, &ExtensionsDOMHandler::HandleRequestExtensionsData));
296c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  dom_ui_->RegisterMessageCallback("toggleDeveloperMode",
297c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NewCallback(this, &ExtensionsDOMHandler::HandleToggleDeveloperMode));
298c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  dom_ui_->RegisterMessageCallback("inspect",
299c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NewCallback(this, &ExtensionsDOMHandler::HandleInspectMessage));
300c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  dom_ui_->RegisterMessageCallback("reload",
301c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NewCallback(this, &ExtensionsDOMHandler::HandleReloadMessage));
302c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  dom_ui_->RegisterMessageCallback("enable",
303c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NewCallback(this, &ExtensionsDOMHandler::HandleEnableMessage));
304c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  dom_ui_->RegisterMessageCallback("enableIncognito",
305c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NewCallback(this, &ExtensionsDOMHandler::HandleEnableIncognitoMessage));
306c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  dom_ui_->RegisterMessageCallback("allowFileAccess",
307c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NewCallback(this, &ExtensionsDOMHandler::HandleAllowFileAccessMessage));
308c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  dom_ui_->RegisterMessageCallback("uninstall",
309c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NewCallback(this, &ExtensionsDOMHandler::HandleUninstallMessage));
310c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  dom_ui_->RegisterMessageCallback("options",
311c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    NewCallback(this, &ExtensionsDOMHandler::HandleOptionsMessage));
312c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  dom_ui_->RegisterMessageCallback("load",
313c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NewCallback(this, &ExtensionsDOMHandler::HandleLoadMessage));
314c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  dom_ui_->RegisterMessageCallback("pack",
315c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NewCallback(this, &ExtensionsDOMHandler::HandlePackMessage));
316c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  dom_ui_->RegisterMessageCallback("autoupdate",
317c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NewCallback(this, &ExtensionsDOMHandler::HandleAutoUpdateMessage));
318c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  dom_ui_->RegisterMessageCallback("selectFilePath",
319c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NewCallback(this, &ExtensionsDOMHandler::HandleSelectFilePathMessage));
320c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
321c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid ExtensionsDOMHandler::HandleRequestExtensionsData(const ListValue* args) {
323c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DictionaryValue* results = new DictionaryValue();
324c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
325c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Add the extensions to the results structure.
326c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ListValue *extensions_list = new ListValue();
327c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
328c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Stores the icon resource for each of the extensions in extensions_list. We
329c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // build up a list of them here, then load them on the file thread in
330c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // ::LoadIcons().
331c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::vector<ExtensionResource>* extension_icons =
332c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      new std::vector<ExtensionResource>();
333c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
334c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const ExtensionList* extensions = extensions_service_->extensions();
335c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (ExtensionList::const_iterator extension = extensions->begin();
336c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch       extension != extensions->end(); ++extension) {
337c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (ShouldShowExtension(*extension)) {
338c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      extensions_list->Append(CreateExtensionDetailValue(
339c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          extensions_service_.get(),
340c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          *extension,
3413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick          GetActivePagesForExtension(*extension),
342c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          true));  // enabled
343c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      extension_icons->push_back(PickExtensionIcon(*extension));
344c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
345c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
346c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  extensions = extensions_service_->disabled_extensions();
347c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (ExtensionList::const_iterator extension = extensions->begin();
348c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch       extension != extensions->end(); ++extension) {
349c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (ShouldShowExtension(*extension)) {
350c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      extensions_list->Append(CreateExtensionDetailValue(
351c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          extensions_service_.get(),
352c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          *extension,
3533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick          GetActivePagesForExtension(*extension),
354c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          false));  // enabled
355c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      extension_icons->push_back(PickExtensionIcon(*extension));
356c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
357c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
3583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  results->Set("extensions", extensions_list);
359c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
360c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool developer_mode = dom_ui_->GetProfile()->GetPrefs()
361c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      ->GetBoolean(prefs::kExtensionsUIDeveloperMode);
3623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  results->SetBoolean("developerMode", developer_mode);
363c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
364c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (icon_loader_.get())
365c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    icon_loader_->Cancel();
366c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
367c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  icon_loader_ = new IconLoader(this);
368c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  icon_loader_->LoadIcons(extension_icons, results);
369c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
370c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
371c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ExtensionsDOMHandler::OnIconsLoaded(DictionaryValue* json) {
372c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  dom_ui_->CallJavascriptFunction(L"returnExtensionsData", *json);
373c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  delete json;
374c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
375c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Register for notifications that we need to reload the page.
376c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  registrar_.RemoveAll();
377c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  registrar_.Add(this, NotificationType::EXTENSION_LOADED,
378c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NotificationService::AllSources());
379c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  registrar_.Add(this, NotificationType::EXTENSION_PROCESS_CREATED,
380c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NotificationService::AllSources());
381c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  registrar_.Add(this, NotificationType::EXTENSION_UNLOADED,
382c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NotificationService::AllSources());
383c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  registrar_.Add(this, NotificationType::EXTENSION_UNLOADED_DISABLED,
384c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NotificationService::AllSources());
385c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  registrar_.Add(this, NotificationType::EXTENSION_UPDATE_DISABLED,
386c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NotificationService::AllSources());
387c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  registrar_.Add(this, NotificationType::EXTENSION_FUNCTION_DISPATCHER_CREATED,
388c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NotificationService::AllSources());
389c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  registrar_.Add(this,
390c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NotificationType::EXTENSION_FUNCTION_DISPATCHER_DESTROYED,
391c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NotificationService::AllSources());
392c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  registrar_.Add(this,
393c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NotificationType::NAV_ENTRY_COMMITTED,
394c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NotificationService::AllSources());
395c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  registrar_.Add(this,
396c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NotificationType::RENDER_VIEW_HOST_DELETED,
397c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NotificationService::AllSources());
398c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  registrar_.Add(this,
399c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NotificationType::BACKGROUND_CONTENTS_NAVIGATED,
400c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NotificationService::AllSources());
401c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  registrar_.Add(this,
402c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NotificationType::BACKGROUND_CONTENTS_DELETED,
403c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NotificationService::AllSources());
404c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
405c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
406c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochExtensionResource ExtensionsDOMHandler::PickExtensionIcon(
407c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    Extension* extension) {
4083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  return extension->GetIconResource(Extension::EXTENSION_ICON_MEDIUM,
4093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                    ExtensionIconSet::MATCH_BIGGER);
410c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
411c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
412c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochExtensionInstallUI* ExtensionsDOMHandler::GetExtensionInstallUI() {
413c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!install_ui_.get())
414c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    install_ui_.reset(new ExtensionInstallUI(dom_ui_->GetProfile()));
415c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return install_ui_.get();
416c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
417c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
4183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid ExtensionsDOMHandler::HandleToggleDeveloperMode(const ListValue* args) {
419c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool developer_mode = dom_ui_->GetProfile()->GetPrefs()
420c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      ->GetBoolean(prefs::kExtensionsUIDeveloperMode);
421c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  dom_ui_->GetProfile()->GetPrefs()->SetBoolean(
422c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      prefs::kExtensionsUIDeveloperMode, !developer_mode);
423c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
424c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
4253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid ExtensionsDOMHandler::HandleInspectMessage(const ListValue* args) {
426c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string render_process_id_str;
427c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string render_view_id_str;
428c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int render_process_id;
429c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int render_view_id;
4303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  CHECK(args->GetSize() == 2);
4313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  CHECK(args->GetString(0, &render_process_id_str));
4323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  CHECK(args->GetString(1, &render_view_id_str));
4333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  CHECK(base::StringToInt(render_process_id_str, &render_process_id));
4343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  CHECK(base::StringToInt(render_view_id_str, &render_view_id));
435c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  RenderViewHost* host = RenderViewHost::FromID(render_process_id,
436c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                                render_view_id);
437c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!host) {
438c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // This can happen if the host has gone away since the page was displayed.
439c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
440c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
441c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
442c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DevToolsManager::GetInstance()->ToggleDevToolsWindow(
443c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      host,
444c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      DEVTOOLS_TOGGLE_ACTION_SHOW_CONSOLE);
445c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
446c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
4473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid ExtensionsDOMHandler::HandleReloadMessage(const ListValue* args) {
4483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  std::string extension_id = WideToASCII(ExtractStringValue(args));
4493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  CHECK(!extension_id.empty());
450c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  extensions_service_->ReloadExtension(extension_id);
451c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
452c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
4533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid ExtensionsDOMHandler::HandleEnableMessage(const ListValue* args) {
4543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  CHECK(args->GetSize() == 2);
455c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string extension_id, enable_str;
4563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  CHECK(args->GetString(0, &extension_id));
4573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  CHECK(args->GetString(1, &enable_str));
458c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (enable_str == "true") {
459c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ExtensionPrefs* prefs = extensions_service_->extension_prefs();
460c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (prefs->DidExtensionEscalatePermissions(extension_id)) {
461c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      Extension* extension =
462c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          extensions_service_->GetExtensionById(extension_id, true);
463c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      ShowExtensionDisabledDialog(extensions_service_,
464c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                  dom_ui_->GetProfile(), extension);
465c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    } else {
466c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      extensions_service_->EnableExtension(extension_id);
467c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
468c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else {
469c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    extensions_service_->DisableExtension(extension_id);
470c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
471c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
472c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
4733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid ExtensionsDOMHandler::HandleEnableIncognitoMessage(const ListValue* args) {
4743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  CHECK(args->GetSize() == 2);
475c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string extension_id, enable_str;
4763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  CHECK(args->GetString(0, &extension_id));
4773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  CHECK(args->GetString(1, &enable_str));
478c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Extension* extension = extensions_service_->GetExtensionById(extension_id,
479c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                                               true);
480c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(extension);
481c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
482c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Flipping the incognito bit will generate unload/load notifications for the
483c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // extension, but we don't want to reload the page, because a) we've already
484c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // updated the UI to reflect the change, and b) we want the yellow warning
485c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // text to stay until the user has left the page.
486c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  //
487c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // TODO(aa): This creates crapiness in some cases. For example, in a main
488c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // window, when toggling this, the browser action will flicker because it gets
489c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // unloaded, then reloaded. It would be better to have a dedicated
490c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // notification for this case.
491c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  //
492c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Bug: http://crbug.com/41384
493c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ignore_notifications_ = true;
494c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  extensions_service_->SetIsIncognitoEnabled(extension, enable_str == "true");
495c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ignore_notifications_ = false;
496c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
497c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
4983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid ExtensionsDOMHandler::HandleAllowFileAccessMessage(const ListValue* args) {
4993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  CHECK(args->GetSize() == 2);
500c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string extension_id, allow_str;
5013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  CHECK(args->GetString(0, &extension_id));
5023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  CHECK(args->GetString(1, &allow_str));
503c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Extension* extension = extensions_service_->GetExtensionById(extension_id,
504c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                                               true);
505c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(extension);
506c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
507c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  extensions_service_->SetAllowFileAccess(extension, allow_str == "true");
508c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
509c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
5103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid ExtensionsDOMHandler::HandleUninstallMessage(const ListValue* args) {
5113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  Extension* extension = GetExtension(args);
512c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!extension)
513c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
514c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
515c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!extension_id_prompting_.empty())
5163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    return;  // Only one prompt at a time.
517c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
5183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  std::string extension_id = WideToASCII(ExtractStringValue(args));
519c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  extension_id_prompting_ = extension_id;
520c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
521c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GetExtensionInstallUI()->ConfirmUninstall(this, extension);
522c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
523c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
5243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid ExtensionsDOMHandler::InstallUIProceed() {
525c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(!extension_id_prompting_.empty());
526c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
527c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The extension can be uninstalled in another window while the UI was
528c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // showing. Do nothing in that case.
529c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Extension* extension =
530c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      extensions_service_->GetExtensionById(extension_id_prompting_, true);
531c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!extension)
532c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
533c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
534c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  extensions_service_->UninstallExtension(extension_id_prompting_,
535c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                          false /* external_uninstall */);
536c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  extension_id_prompting_ = "";
537c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
538c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
539c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ExtensionsDOMHandler::InstallUIAbort() {
540c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  extension_id_prompting_ = "";
541c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
542c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
5433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid ExtensionsDOMHandler::HandleOptionsMessage(const ListValue* args) {
5443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  Extension* extension = GetExtension(args);
5453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (!extension || extension->options_url().is_empty())
546c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
547c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  dom_ui_->GetProfile()->GetExtensionProcessManager()->OpenOptionsPage(
548c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      extension, NULL);
549c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
550c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
5513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid ExtensionsDOMHandler::HandleLoadMessage(const ListValue* args) {
552c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  FilePath::StringType string_path;
5533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  CHECK(args->GetSize() == 1) << args->GetSize();
5543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  CHECK(args->GetString(0, &string_path));
555c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  extensions_service_->LoadExtension(FilePath(string_path));
556c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
557c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
558c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ExtensionsDOMHandler::ShowAlert(const std::string& message) {
559c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ListValue arguments;
560c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  arguments.Append(Value::CreateStringValue(message));
561c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  dom_ui_->CallJavascriptFunction(L"alert", arguments);
562c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
563c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
5643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid ExtensionsDOMHandler::HandlePackMessage(const ListValue* args) {
5653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  std::string extension_path;
5663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  std::string private_key_path;
5673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  CHECK(args->GetSize() == 2);
5683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  CHECK(args->GetString(0, &extension_path));
5693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  CHECK(args->GetString(1, &private_key_path));
570c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
5713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  FilePath root_directory =
5723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      FilePath::FromWStringHack(UTF8ToWide(extension_path));
5733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  FilePath key_file = FilePath::FromWStringHack(UTF8ToWide(private_key_path));
574c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
575c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (root_directory.empty()) {
576c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (extension_path.empty()) {
577c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      ShowAlert(l10n_util::GetStringUTF8(
578c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          IDS_EXTENSION_PACK_DIALOG_ERROR_ROOT_REQUIRED));
579c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    } else {
580c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      ShowAlert(l10n_util::GetStringUTF8(
581c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          IDS_EXTENSION_PACK_DIALOG_ERROR_ROOT_INVALID));
582c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
583c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
584c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
585c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
586c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
587c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!private_key_path.empty() && key_file.empty()) {
588c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ShowAlert(l10n_util::GetStringUTF8(
589c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        IDS_EXTENSION_PACK_DIALOG_ERROR_KEY_INVALID));
590c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
591c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
592c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
593c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  pack_job_ = new PackExtensionJob(this, root_directory, key_file);
594c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  pack_job_->Start();
595c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
596c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
597c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ExtensionsDOMHandler::OnPackSuccess(const FilePath& crx_file,
598c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                         const FilePath& pem_file) {
5993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ShowAlert(WideToUTF8(PackExtensionJob::StandardSuccessMessage(crx_file,
6003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                                                pem_file)));
601c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
602c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ListValue results;
603c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  dom_ui_->CallJavascriptFunction(L"hidePackDialog", results);
604c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
605c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
6063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid ExtensionsDOMHandler::OnPackFailure(const std::string& error) {
6073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ShowAlert(error);
608c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
609c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
6103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid ExtensionsDOMHandler::HandleAutoUpdateMessage(const ListValue* args) {
611c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ExtensionUpdater* updater = extensions_service_->updater();
6123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (updater)
613c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    updater->CheckNow();
614c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
615c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
6163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid ExtensionsDOMHandler::HandleSelectFilePathMessage(const ListValue* args) {
617c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string select_type;
618c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string operation;
6193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  CHECK(args->GetSize() == 2);
6203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  CHECK(args->GetString(0, &select_type));
6213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  CHECK(args->GetString(1, &operation));
622c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
623c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  SelectFileDialog::Type type = SelectFileDialog::SELECT_FOLDER;
624c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  static SelectFileDialog::FileTypeInfo info;
625c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int file_type_index = 0;
626c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (select_type == "file")
627c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    type = SelectFileDialog::SELECT_OPEN_FILE;
628c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
629c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  string16 select_title;
6303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (operation == "load") {
631c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    select_title = l10n_util::GetStringUTF16(IDS_EXTENSION_LOAD_FROM_DIRECTORY);
6323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  } else if (operation == "packRoot") {
633c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    select_title = l10n_util::GetStringUTF16(
634c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        IDS_EXTENSION_PACK_DIALOG_SELECT_ROOT);
6353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  } else if (operation == "pem") {
636c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    select_title = l10n_util::GetStringUTF16(
637c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        IDS_EXTENSION_PACK_DIALOG_SELECT_KEY);
638c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    info.extensions.push_back(std::vector<FilePath::StringType>());
639c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        info.extensions.front().push_back(FILE_PATH_LITERAL("pem"));
6403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        info.extension_description_overrides.push_back(
6413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick            l10n_util::GetStringUTF16(
6423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                IDS_EXTENSION_PACK_DIALOG_KEY_FILE_TYPE_DESCRIPTION));
643c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        info.include_all_files = true;
644c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    file_type_index = 1;
645c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else {
646c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    NOTREACHED();
647c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
648c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
649c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
650c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  load_extension_dialog_ = SelectFileDialog::Create(this);
651c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  load_extension_dialog_->SelectFile(type, select_title, FilePath(), &info,
652c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      file_type_index, FILE_PATH_LITERAL(""),
653c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      dom_ui_->tab_contents()->view()->GetTopLevelNativeWindow(), NULL);
654c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
655c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
656c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
657c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ExtensionsDOMHandler::FileSelected(const FilePath& path, int index,
658c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                        void* params) {
659c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Add the extensions to the results structure.
660c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ListValue results;
661c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  results.Append(Value::CreateStringValue(path.value()));
662c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  dom_ui_->CallJavascriptFunction(L"window.handleFilePathSelected", results);
663c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
664c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
665c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ExtensionsDOMHandler::Observe(NotificationType type,
666c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                   const NotificationSource& source,
667c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                   const NotificationDetails& details) {
668c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  switch (type.value) {
669c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // We listen for notifications that will result in the page being
670c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // repopulated with data twice for the same event in certain cases.
671c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // For instance, EXTENSION_LOADED & EXTENSION_PROCESS_CREATED because
672c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // we don't know about the views for an extension at EXTENSION_LOADED, but
673c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // if we only listen to EXTENSION_PROCESS_CREATED, we'll miss extensions
674c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // that don't have a process at startup. Similarly, NAV_ENTRY_COMMITTED &
675c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // EXTENSION_FUNCTION_DISPATCHER_CREATED because we want to handle both
676c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // the case of live app pages (which don't have an EFD) and
677c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // chrome-extension:// urls which are served in a TabContents.
678c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    //
679c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Doing it this way gets everything but causes the page to be rendered
680c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // more than we need. It doesn't seem to result in any noticeable flicker.
681c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case NotificationType::RENDER_VIEW_HOST_DELETED:
682c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      deleting_rvh_ = Details<RenderViewHost>(details).ptr();
683c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      MaybeUpdateAfterNotification();
684c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      break;
685c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case NotificationType::BACKGROUND_CONTENTS_DELETED:
686c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      deleting_rvh_ = Details<BackgroundContents>(details)->render_view_host();
687c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      MaybeUpdateAfterNotification();
688c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      break;
689c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case NotificationType::EXTENSION_LOADED:
690c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case NotificationType::EXTENSION_PROCESS_CREATED:
691c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case NotificationType::EXTENSION_UNLOADED:
692c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case NotificationType::EXTENSION_UNLOADED_DISABLED:
693c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case NotificationType::EXTENSION_UPDATE_DISABLED:
694c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case NotificationType::EXTENSION_FUNCTION_DISPATCHER_CREATED:
695c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case NotificationType::EXTENSION_FUNCTION_DISPATCHER_DESTROYED:
696c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case NotificationType::NAV_ENTRY_COMMITTED:
697c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case NotificationType::BACKGROUND_CONTENTS_NAVIGATED:
698c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      MaybeUpdateAfterNotification();
699c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      break;
700c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    default:
701c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NOTREACHED();
702c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
703c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
704c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
7053345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickExtension* ExtensionsDOMHandler::GetExtension(const ListValue* args) {
7063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  std::string extension_id = WideToASCII(ExtractStringValue(args));
7073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  CHECK(!extension_id.empty());
7083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  return extensions_service_->GetExtensionById(extension_id, true);
7093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
7103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
711c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ExtensionsDOMHandler::MaybeUpdateAfterNotification() {
712c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!ignore_notifications_ && dom_ui_->tab_contents())
713c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    HandleRequestExtensionsData(NULL);
714c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  deleting_rvh_ = NULL;
715c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
716c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
717c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic void CreateScriptFileDetailValue(
718c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const FilePath& extension_path, const UserScript::FileList& scripts,
7193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    const char* key, DictionaryValue* script_data) {
720c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (scripts.empty())
721c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
722c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
723c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ListValue *list = new ListValue();
724c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (size_t i = 0; i < scripts.size(); ++i) {
725c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const UserScript::File& file = scripts[i];
726c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // TODO(cira): this information is not used on extension page yet. We
727c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // may want to display actual resource that got loaded, not default.
728c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    list->Append(
729c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        new StringValue(file.relative_path().value()));
730c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
731c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  script_data->Set(key, list);
732c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
733c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
734c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Static
735c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochDictionaryValue* ExtensionsDOMHandler::CreateContentScriptDetailValue(
736c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const UserScript& script, const FilePath& extension_path) {
737c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DictionaryValue* script_data = new DictionaryValue();
7383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  CreateScriptFileDetailValue(extension_path, script.js_scripts(), "js",
739c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    script_data);
7403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  CreateScriptFileDetailValue(extension_path, script.css_scripts(), "css",
741c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    script_data);
742c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
743c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Get list of glob "matches" strings
744c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ListValue *url_pattern_list = new ListValue();
745c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const std::vector<URLPattern>& url_patterns = script.url_patterns();
746c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (std::vector<URLPattern>::const_iterator url_pattern =
747c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      url_patterns.begin();
748c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    url_pattern != url_patterns.end(); ++url_pattern) {
749c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    url_pattern_list->Append(new StringValue(url_pattern->GetAsString()));
750c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
751c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
7523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  script_data->Set("matches", url_pattern_list);
753c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
754c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return script_data;
755c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
756c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
757c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic bool ExtensionWantsFileAccess(const Extension* extension) {
758c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (UserScriptList::const_iterator it = extension->content_scripts().begin();
759c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch       it != extension->content_scripts().end(); ++it) {
760c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    for (UserScript::PatternList::const_iterator pattern =
761c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch             it->url_patterns().begin();
762c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch         pattern != it->url_patterns().end(); ++pattern) {
763c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      if (pattern->MatchesScheme(chrome::kFileScheme))
764c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        return true;
765c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
766c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
767c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
768c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return false;
769c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
770c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
771c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Static
772c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochDictionaryValue* ExtensionsDOMHandler::CreateExtensionDetailValue(
773c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ExtensionsService* service, const Extension* extension,
774c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const std::vector<ExtensionPage>& pages, bool enabled) {
775c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DictionaryValue* extension_data = new DictionaryValue();
776c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
7773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  extension_data->SetString("id", extension->id());
7783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  extension_data->SetString("name", extension->name());
7793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  extension_data->SetString("description", extension->description());
7803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  extension_data->SetString("version", extension->version()->GetString());
7813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  extension_data->SetBoolean("enabled", enabled);
7823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  extension_data->SetBoolean("enabledIncognito",
783c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      service ? service->IsIncognitoEnabled(extension) : false);
7843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  extension_data->SetBoolean("wantsFileAccess",
785c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      ExtensionWantsFileAccess(extension));
7863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  extension_data->SetBoolean("allowFileAccess",
787c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      service ? service->AllowFileAccess(extension) : false);
7883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  extension_data->SetBoolean("allow_reload",
789c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                             extension->location() == Extension::LOAD);
7903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  extension_data->SetBoolean("is_hosted_app", extension->is_hosted_app());
791c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
792c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Determine the sort order: Extensions loaded through --load-extensions show
793c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // up at the top. Disabled extensions show up at the bottom.
794c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (extension->location() == Extension::LOAD)
7953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    extension_data->SetInteger("order", 1);
796c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  else
7973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    extension_data->SetInteger("order", 2);
798c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
799c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!extension->options_url().is_empty())
8003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    extension_data->SetString("options_url", extension->options_url().spec());
801c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
802c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Add list of content_script detail DictionaryValues.
803c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ListValue *content_script_list = new ListValue();
804c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  UserScriptList content_scripts = extension->content_scripts();
805c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (UserScriptList::const_iterator script = content_scripts.begin();
806c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    script != content_scripts.end(); ++script) {
807c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      content_script_list->Append(
808c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          CreateContentScriptDetailValue(*script, extension->path()));
809c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
8103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  extension_data->Set("content_scripts", content_script_list);
811c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
812c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Add permissions.
813c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ListValue *permission_list = new ListValue;
814c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::vector<URLPattern> permissions = extension->host_permissions();
815c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (std::vector<URLPattern>::iterator permission = permissions.begin();
816c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch       permission != permissions.end(); ++permission) {
817c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    permission_list->Append(Value::CreateStringValue(
818c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        permission->GetAsString()));
819c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
8203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  extension_data->Set("permissions", permission_list);
821c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
822c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Add views
823c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ListValue* views = new ListValue;
824c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (std::vector<ExtensionPage>::const_iterator iter = pages.begin();
825c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch       iter != pages.end(); ++iter) {
826c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DictionaryValue* view_value = new DictionaryValue;
827c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (iter->url.scheme() == chrome::kExtensionScheme) {
828c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // No leading slash.
8293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      view_value->SetString("path", iter->url.path().substr(1));
830c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    } else {
831c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // For live pages, use the full URL.
8323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      view_value->SetString("path", iter->url.spec());
833c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
8343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    view_value->SetInteger("renderViewId", iter->render_view_id);
8353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    view_value->SetInteger("renderProcessId", iter->render_process_id);
8363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    view_value->SetBoolean("incognito", iter->incognito);
837c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    views->Append(view_value);
838c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
8393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  extension_data->Set("views", views);
8403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  extension_data->SetBoolean("hasPopupAction",
841c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      extension->browser_action() || extension->page_action());
8423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  extension_data->SetString("galleryUrl", extension->GalleryUrl().spec());
843c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
844c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return extension_data;
845c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
846c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
847c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstd::vector<ExtensionPage> ExtensionsDOMHandler::GetActivePagesForExtension(
848c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    Extension* extension) {
849c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::vector<ExtensionPage> result;
8503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
8513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Get the extension process's active views.
8523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ExtensionProcessManager* process_manager =
8533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      extensions_service_->profile()->GetExtensionProcessManager();
8543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  GetActivePagesForExtensionProcess(
8553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      process_manager->GetExtensionProcess(extension->url()),
8563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      extension, &result);
8573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
8583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Repeat for the incognito process, if applicable.
8593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (extensions_service_->profile()->HasOffTheRecordProfile() &&
8603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      extension->incognito_split_mode()) {
8613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    ExtensionProcessManager* process_manager =
8623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        extensions_service_->profile()->GetOffTheRecordProfile()->
8633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick            GetExtensionProcessManager();
8643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    GetActivePagesForExtensionProcess(
8653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        process_manager->GetExtensionProcess(extension->url()),
8663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        extension, &result);
8673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  }
8683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
8693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  return result;
8703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
8713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
8723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickvoid ExtensionsDOMHandler::GetActivePagesForExtensionProcess(
8733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    RenderProcessHost* process,
8743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    Extension* extension,
8753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    std::vector<ExtensionPage> *result) {
876c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!process)
8773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    return;
878c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
879c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  RenderProcessHost::listeners_iterator iter = process->ListenersIterator();
880c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (; !iter.IsAtEnd(); iter.Advance()) {
881c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const RenderWidgetHost* widget =
882c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        static_cast<const RenderWidgetHost*>(iter.GetCurrentValue());
883c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DCHECK(widget);
884c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (!widget || !widget->IsRenderView())
885c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      continue;
886c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const RenderViewHost* host = static_cast<const RenderViewHost*>(widget);
887c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (host == deleting_rvh_ ||
888c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        ViewType::EXTENSION_POPUP == host->delegate()->GetRenderViewType())
889c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      continue;
890c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
891c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    GURL url = host->delegate()->GetURL();
892c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (url.SchemeIs(chrome::kExtensionScheme)) {
893c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      if (url.host() != extension->id())
894c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        continue;
895c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    } else if (!extension->web_extent().ContainsURL(url)) {
896c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      continue;
897c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
898c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
8993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    result->push_back(ExtensionPage(url, process->id(), host->routing_id(),
9003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                    process->profile()->IsOffTheRecord()));
901c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
902c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
903c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
904c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochExtensionsDOMHandler::~ExtensionsDOMHandler() {
905c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (pack_job_.get())
906c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    pack_job_->ClearClient();
907c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
908c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (icon_loader_.get())
909c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    icon_loader_->Cancel();
910c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
911c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
912c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// ExtensionsDOMHandler, public: -----------------------------------------------
913c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
914c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochExtensionsUI::ExtensionsUI(TabContents* contents) : DOMUI(contents) {
915c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ExtensionsService *exstension_service =
916c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      GetProfile()->GetOriginalProfile()->GetExtensionsService();
917c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
918c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ExtensionsDOMHandler* handler = new ExtensionsDOMHandler(exstension_service);
919c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  AddMessageHandler(handler);
920c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  handler->Attach(this);
921c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
922c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ExtensionsUIHTMLSource* html_source = new ExtensionsUIHTMLSource();
923c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
924c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Set up the chrome://extensions/ source.
925c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ChromeThread::PostTask(
926c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      ChromeThread::IO, FROM_HERE,
927c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NewRunnableMethod(
928c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          Singleton<ChromeURLDataManager>::get(),
929c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          &ChromeURLDataManager::AddDataSource,
930c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          make_scoped_refptr(html_source)));
931c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
932c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
933c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// static
934c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochRefCountedMemory* ExtensionsUI::GetFaviconResourceBytes() {
935c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return ResourceBundle::GetSharedInstance().
936c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      LoadDataResourceBytes(IDR_PLUGIN);
937c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
938c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
939c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// static
940c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ExtensionsUI::RegisterUserPrefs(PrefService* prefs) {
941c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  prefs->RegisterBooleanPref(prefs::kExtensionsUIDeveloperMode, false);
942c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
943