extensions_ui.cc revision c407dc5cd9bdc5668497f21b26b09d988ab439de
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"
12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/string_util.h"
13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/thread.h"
14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/browser.h"
15c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/browser_process.h"
16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/debugger/devtools_manager.h"
17c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/debugger/devtools_toggle_action.h"
18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/extensions/crx_installer.h"
19c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/extensions/extension_disabled_infobar_delegate.h"
20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/extensions/extension_error_reporter.h"
21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/extensions/extension_function_dispatcher.h"
22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/extensions/extension_host.h"
23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/extensions/extension_message_service.h"
24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/extensions/extensions_service.h"
25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/extensions/extension_updater.h"
26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/google_util.h"
27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/pref_service.h"
28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/profile.h"
29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/renderer_host/render_process_host.h"
30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/renderer_host/render_widget_host.h"
31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/renderer_host/render_view_host.h"
32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/tab_contents/background_contents.h"
33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/tab_contents/tab_contents.h"
34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/browser/tab_contents/tab_contents_view.h"
35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/chrome_switches.h"
36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/extensions/extension.h"
37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/extensions/user_script.h"
38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/extensions/url_pattern.h"
39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/jstemplate_builder.h"
40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/notification_service.h"
41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/notification_type.h"
42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/pref_names.h"
43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "chrome/common/url_constants.h"
44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "gfx/codec/png_codec.h"
45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "gfx/color_utils.h"
46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "gfx/skbitmap_operations.h"
47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "grit/browser_resources.h"
48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "grit/chromium_strings.h"
49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "grit/generated_resources.h"
50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "grit/theme_resources.h"
51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/base/net_util.h"
52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "webkit/glue/image_decoder.h"
53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace {
55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic bool ShouldShowExtension(Extension* extension) {
57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Don't show the themes since this page's UI isn't really useful for
58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // themes.
59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (extension->is_theme())
60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return false;
61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Don't show component extensions because they are only extensions as an
63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // implementation detail of Chrome.
64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (extension->location() == Extension::COMPONENT)
65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return false;
66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return true;
68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch////////////////////////////////////////////////////////////////////////////////
73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//
74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// ExtensionsHTMLSource
75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//
76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch////////////////////////////////////////////////////////////////////////////////
77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
78c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochExtensionsUIHTMLSource::ExtensionsUIHTMLSource()
79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    : DataSource(chrome::kChromeUIExtensionsHost, MessageLoop::current()) {
80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ExtensionsUIHTMLSource::StartDataRequest(const std::string& path,
83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    bool is_off_the_record, int request_id) {
84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DictionaryValue localized_strings;
85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  localized_strings.SetString(L"title",
86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      l10n_util::GetString(IDS_EXTENSIONS_TITLE));
87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  localized_strings.SetString(L"devModeLink",
88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      l10n_util::GetString(IDS_EXTENSIONS_DEVELOPER_MODE_LINK));
89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  localized_strings.SetString(L"devModePrefix",
90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      l10n_util::GetString(IDS_EXTENSIONS_DEVELOPER_MODE_PREFIX));
91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  localized_strings.SetString(L"loadUnpackedButton",
92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      l10n_util::GetString(IDS_EXTENSIONS_LOAD_UNPACKED_BUTTON));
93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  localized_strings.SetString(L"packButton",
94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      l10n_util::GetString(IDS_EXTENSIONS_PACK_BUTTON));
95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  localized_strings.SetString(L"updateButton",
96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      l10n_util::GetString(IDS_EXTENSIONS_UPDATE_BUTTON));
97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  localized_strings.SetString(L"noExtensions",
98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      l10n_util::GetString(IDS_EXTENSIONS_NONE_INSTALLED));
99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  localized_strings.SetString(L"suggestGallery",
100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      l10n_util::GetStringF(IDS_EXTENSIONS_NONE_INSTALLED_SUGGEST_GALLERY,
101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          std::wstring(L"<a href='") +
102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          ASCIIToWide(google_util::AppendGoogleLocaleParam(
103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch              GURL(Extension::ChromeStoreURL())).spec()) + L"'>",
104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          L"</a>"));
105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  localized_strings.SetString(L"getMoreExtensions",
106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      std::wstring(L"<a href='") +
107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          ASCIIToWide(google_util::AppendGoogleLocaleParam(
108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch              GURL(Extension::ChromeStoreURL())).spec()) + L"'>" +
109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          l10n_util::GetString(IDS_GET_MORE_EXTENSIONS) +
110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          L"</a>");
111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  localized_strings.SetString(L"extensionDisabled",
112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      l10n_util::GetString(IDS_EXTENSIONS_DISABLED_EXTENSION));
113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  localized_strings.SetString(L"inDevelopment",
114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      l10n_util::GetString(IDS_EXTENSIONS_IN_DEVELOPMENT));
115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  localized_strings.SetString(L"extensionId",
116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      l10n_util::GetString(IDS_EXTENSIONS_ID));
117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  localized_strings.SetString(L"extensionVersion",
118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      l10n_util::GetString(IDS_EXTENSIONS_VERSION));
119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  localized_strings.SetString(L"inspectViews",
120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      l10n_util::GetString(IDS_EXTENSIONS_INSPECT_VIEWS));
121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  localized_strings.SetString(L"inspectPopupsInstructions",
122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      l10n_util::GetString(IDS_EXTENSIONS_INSPECT_POPUPS_INSTRUCTIONS));
123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  localized_strings.SetString(L"disable",
124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      l10n_util::GetString(IDS_EXTENSIONS_DISABLE));
125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  localized_strings.SetString(L"enable",
126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      l10n_util::GetString(IDS_EXTENSIONS_ENABLE));
127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  localized_strings.SetString(L"enableIncognito",
128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      l10n_util::GetString(IDS_EXTENSIONS_ENABLE_INCOGNITO));
129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  localized_strings.SetString(L"allowFileAccess",
130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      l10n_util::GetString(IDS_EXTENSIONS_ALLOW_FILE_ACCESS));
131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  localized_strings.SetString(L"incognitoWarning",
132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      l10n_util::GetString(IDS_EXTENSIONS_INCOGNITO_WARNING));
133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  localized_strings.SetString(L"reload",
134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      l10n_util::GetString(IDS_EXTENSIONS_RELOAD));
135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  localized_strings.SetString(L"uninstall",
136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      l10n_util::GetString(IDS_EXTENSIONS_UNINSTALL));
137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  localized_strings.SetString(L"options",
138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      l10n_util::GetString(IDS_EXTENSIONS_OPTIONS));
139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  localized_strings.SetString(L"packDialogTitle",
140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      l10n_util::GetString(IDS_EXTENSION_PACK_DIALOG_TITLE));
141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  localized_strings.SetString(L"packDialogHeading",
142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      l10n_util::GetString(IDS_EXTENSION_PACK_DIALOG_HEADING));
143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  localized_strings.SetString(L"rootDirectoryLabel",
144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      l10n_util::GetString(IDS_EXTENSION_PACK_DIALOG_ROOT_DIRECTORY_LABEL));
145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  localized_strings.SetString(L"packDialogBrowse",
146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      l10n_util::GetString(IDS_EXTENSION_PACK_DIALOG_BROWSE));
147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  localized_strings.SetString(L"privateKeyLabel",
148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      l10n_util::GetString(IDS_EXTENSION_PACK_DIALOG_PRIVATE_KEY_LABEL));
149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  localized_strings.SetString(L"okButton",
150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      l10n_util::GetString(IDS_OK));
151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  localized_strings.SetString(L"cancelButton",
152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      l10n_util::GetString(IDS_CANCEL));
153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  SetFontAndTextDirection(&localized_strings);
155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  static const base::StringPiece extensions_html(
157c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      ResourceBundle::GetSharedInstance().GetRawDataResource(
158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          IDR_EXTENSIONS_UI_HTML));
159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string full_html(extensions_html.data(), extensions_html.size());
160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  jstemplate_builder::AppendJsonHtml(&localized_strings, &full_html);
161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  jstemplate_builder::AppendI18nTemplateSourceHtml(&full_html);
162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  jstemplate_builder::AppendI18nTemplateProcessHtml(&full_html);
163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  jstemplate_builder::AppendJsTemplateSourceHtml(&full_html);
164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_refptr<RefCountedBytes> html_bytes(new RefCountedBytes);
166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  html_bytes->data.resize(full_html.size());
167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::copy(full_html.begin(), full_html.end(), html_bytes->data.begin());
168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  SendResponse(request_id, html_bytes);
170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch////////////////////////////////////////////////////////////////////////////////
174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//
175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// ExtensionsDOMHandler::IconLoader
176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//
177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch////////////////////////////////////////////////////////////////////////////////
178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
179c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochExtensionsDOMHandler::IconLoader::IconLoader(ExtensionsDOMHandler* handler)
180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    : handler_(handler) {
181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ExtensionsDOMHandler::IconLoader::LoadIcons(
184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    std::vector<ExtensionResource>* icons, DictionaryValue* json) {
185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ChromeThread::PostTask(
186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      ChromeThread::FILE, FROM_HERE,
187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NewRunnableMethod(this,
188c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          &IconLoader::LoadIconsOnFileThread, icons, json));
189c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ExtensionsDOMHandler::IconLoader::Cancel() {
192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  handler_ = NULL;
193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
194c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
195c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ExtensionsDOMHandler::IconLoader::LoadIconsOnFileThread(
196c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    std::vector<ExtensionResource>* icons, DictionaryValue* json) {
197c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_ptr<std::vector<ExtensionResource> > icons_deleter(icons);
198c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_ptr<DictionaryValue> json_deleter(json);
199c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
200c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ListValue* extensions = NULL;
201c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CHECK(json->GetList(L"extensions", &extensions));
202c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
203c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (size_t i = 0; i < icons->size(); ++i) {
204c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DictionaryValue* extension = NULL;
205c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    CHECK(extensions->GetDictionary(static_cast<int>(i), &extension));
206c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
207c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Read the file.
208c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    std::string file_contents;
209c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (icons->at(i).relative_path().empty() ||
210c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        !file_util::ReadFileToString(icons->at(i).GetFilePath(),
211c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                     &file_contents)) {
212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // If there's no icon, default to the puzzle icon. This is safe to do from
213c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // the file thread.
214c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      file_contents = ResourceBundle::GetSharedInstance().GetRawDataResource(
215c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          IDR_EXTENSION_DEFAULT_ICON).as_string();
216c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
217c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
218c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // If the extension is disabled, we desaturate the icon to add to the
219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // disabledness effect.
220c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    bool enabled = false;
221c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    CHECK(extension->GetBoolean(L"enabled", &enabled));
222c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (!enabled) {
223c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      const unsigned char* data =
224c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          reinterpret_cast<const unsigned char*>(file_contents.data());
225c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      webkit_glue::ImageDecoder decoder;
226c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      scoped_ptr<SkBitmap> decoded(new SkBitmap());
227c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      *decoded = decoder.Decode(data, file_contents.length());
228c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
229c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // Desaturate the icon and lighten it a bit.
230c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      color_utils::HSL shift = {-1, 0, 0.6};
231c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      *decoded = SkBitmapOperations::CreateHSLShiftedBitmap(*decoded, shift);
232c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
233c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      std::vector<unsigned char> output;
234c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      gfx::PNGCodec::EncodeBGRASkBitmap(*decoded, false, &output);
235c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
236c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // Lame, but we must make a copy of this now, because base64 doesn't take
237c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // the same input type.
238c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      file_contents.assign(reinterpret_cast<char*>(&output.front()),
239c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                           output.size());
240c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
241c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
242c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Create a data URL (all icons are converted to PNGs during unpacking).
243c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    std::string base64_encoded;
244c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    base::Base64Encode(file_contents, &base64_encoded);
245c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    GURL icon_url("data:image/png;base64," + base64_encoded);
246c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
247c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    extension->SetString(L"icon", icon_url.spec());
248c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
249c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
250c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ChromeThread::PostTask(
251c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      ChromeThread::UI, FROM_HERE,
252c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NewRunnableMethod(this, &IconLoader::ReportResultOnUIThread,
253c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                        json_deleter.release()));
254c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
255c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
256c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ExtensionsDOMHandler::IconLoader::ReportResultOnUIThread(
257c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DictionaryValue* json) {
258c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (handler_)
259c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    handler_->OnIconsLoaded(json);
260c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
261c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
262c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
263c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch///////////////////////////////////////////////////////////////////////////////
264c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//
265c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// ExtensionsDOMHandler
266c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch//
267c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch///////////////////////////////////////////////////////////////////////////////
268c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
269c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochExtensionsDOMHandler::ExtensionsDOMHandler(ExtensionsService* extension_service)
270c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    : extensions_service_(extension_service),
271c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      ignore_notifications_(false),
272c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      deleting_rvh_(NULL) {
273c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
274c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
275c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ExtensionsDOMHandler::RegisterMessages() {
276c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  dom_ui_->RegisterMessageCallback("requestExtensionsData",
277c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NewCallback(this, &ExtensionsDOMHandler::HandleRequestExtensionsData));
278c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  dom_ui_->RegisterMessageCallback("toggleDeveloperMode",
279c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NewCallback(this, &ExtensionsDOMHandler::HandleToggleDeveloperMode));
280c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  dom_ui_->RegisterMessageCallback("inspect",
281c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NewCallback(this, &ExtensionsDOMHandler::HandleInspectMessage));
282c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  dom_ui_->RegisterMessageCallback("reload",
283c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NewCallback(this, &ExtensionsDOMHandler::HandleReloadMessage));
284c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  dom_ui_->RegisterMessageCallback("enable",
285c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NewCallback(this, &ExtensionsDOMHandler::HandleEnableMessage));
286c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  dom_ui_->RegisterMessageCallback("enableIncognito",
287c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NewCallback(this, &ExtensionsDOMHandler::HandleEnableIncognitoMessage));
288c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  dom_ui_->RegisterMessageCallback("allowFileAccess",
289c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NewCallback(this, &ExtensionsDOMHandler::HandleAllowFileAccessMessage));
290c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  dom_ui_->RegisterMessageCallback("uninstall",
291c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NewCallback(this, &ExtensionsDOMHandler::HandleUninstallMessage));
292c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  dom_ui_->RegisterMessageCallback("options",
293c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    NewCallback(this, &ExtensionsDOMHandler::HandleOptionsMessage));
294c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  dom_ui_->RegisterMessageCallback("load",
295c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NewCallback(this, &ExtensionsDOMHandler::HandleLoadMessage));
296c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  dom_ui_->RegisterMessageCallback("pack",
297c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NewCallback(this, &ExtensionsDOMHandler::HandlePackMessage));
298c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  dom_ui_->RegisterMessageCallback("autoupdate",
299c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NewCallback(this, &ExtensionsDOMHandler::HandleAutoUpdateMessage));
300c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  dom_ui_->RegisterMessageCallback("selectFilePath",
301c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NewCallback(this, &ExtensionsDOMHandler::HandleSelectFilePathMessage));
302c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
303c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
304c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ExtensionsDOMHandler::HandleRequestExtensionsData(const Value* value) {
305c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DictionaryValue* results = new DictionaryValue();
306c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
307c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Add the extensions to the results structure.
308c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ListValue *extensions_list = new ListValue();
309c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
310c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Stores the icon resource for each of the extensions in extensions_list. We
311c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // build up a list of them here, then load them on the file thread in
312c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // ::LoadIcons().
313c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::vector<ExtensionResource>* extension_icons =
314c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      new std::vector<ExtensionResource>();
315c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
316c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ExtensionProcessManager* process_manager =
317c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      extensions_service_->profile()->GetExtensionProcessManager();
318c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const ExtensionList* extensions = extensions_service_->extensions();
319c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (ExtensionList::const_iterator extension = extensions->begin();
320c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch       extension != extensions->end(); ++extension) {
321c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (ShouldShowExtension(*extension)) {
322c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      RenderProcessHost* process =
323c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          process_manager->GetExtensionProcess((*extension)->url());
324c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      extensions_list->Append(CreateExtensionDetailValue(
325c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          extensions_service_.get(),
326c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          *extension,
327c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          GetActivePagesForExtension(process, *extension),
328c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          true));  // enabled
329c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      extension_icons->push_back(PickExtensionIcon(*extension));
330c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
331c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
332c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  extensions = extensions_service_->disabled_extensions();
333c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (ExtensionList::const_iterator extension = extensions->begin();
334c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch       extension != extensions->end(); ++extension) {
335c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (ShouldShowExtension(*extension)) {
336c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      RenderProcessHost* process =
337c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          process_manager->GetExtensionProcess((*extension)->url());
338c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      extensions_list->Append(CreateExtensionDetailValue(
339c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          extensions_service_.get(),
340c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          *extension,
341c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          GetActivePagesForExtension(process, *extension),
342c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          false));  // enabled
343c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      extension_icons->push_back(PickExtensionIcon(*extension));
344c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
345c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
346c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  results->Set(L"extensions", extensions_list);
347c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
348c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool developer_mode = dom_ui_->GetProfile()->GetPrefs()
349c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      ->GetBoolean(prefs::kExtensionsUIDeveloperMode);
350c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  results->SetBoolean(L"developerMode", developer_mode);
351c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
352c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (icon_loader_.get())
353c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    icon_loader_->Cancel();
354c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
355c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  icon_loader_ = new IconLoader(this);
356c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  icon_loader_->LoadIcons(extension_icons, results);
357c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
358c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
359c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ExtensionsDOMHandler::OnIconsLoaded(DictionaryValue* json) {
360c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  dom_ui_->CallJavascriptFunction(L"returnExtensionsData", *json);
361c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  delete json;
362c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
363c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Register for notifications that we need to reload the page.
364c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  registrar_.RemoveAll();
365c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  registrar_.Add(this, NotificationType::EXTENSION_LOADED,
366c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NotificationService::AllSources());
367c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  registrar_.Add(this, NotificationType::EXTENSION_PROCESS_CREATED,
368c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NotificationService::AllSources());
369c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  registrar_.Add(this, NotificationType::EXTENSION_UNLOADED,
370c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NotificationService::AllSources());
371c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  registrar_.Add(this, NotificationType::EXTENSION_UNLOADED_DISABLED,
372c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NotificationService::AllSources());
373c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  registrar_.Add(this, NotificationType::EXTENSION_UPDATE_DISABLED,
374c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NotificationService::AllSources());
375c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  registrar_.Add(this, NotificationType::EXTENSION_FUNCTION_DISPATCHER_CREATED,
376c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NotificationService::AllSources());
377c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  registrar_.Add(this,
378c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NotificationType::EXTENSION_FUNCTION_DISPATCHER_DESTROYED,
379c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NotificationService::AllSources());
380c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  registrar_.Add(this,
381c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NotificationType::NAV_ENTRY_COMMITTED,
382c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NotificationService::AllSources());
383c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  registrar_.Add(this,
384c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NotificationType::RENDER_VIEW_HOST_DELETED,
385c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NotificationService::AllSources());
386c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  registrar_.Add(this,
387c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NotificationType::BACKGROUND_CONTENTS_NAVIGATED,
388c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NotificationService::AllSources());
389c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  registrar_.Add(this,
390c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NotificationType::BACKGROUND_CONTENTS_DELETED,
391c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NotificationService::AllSources());
392c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
393c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
394c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochExtensionResource ExtensionsDOMHandler::PickExtensionIcon(
395c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    Extension* extension) {
396c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Try to fetch the medium sized icon, then (if missing) go for the large one.
397c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const std::map<int, std::string>& icons = extension->icons();
398c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::map<int, std::string>::const_iterator iter =
399c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      icons.find(Extension::EXTENSION_ICON_MEDIUM);
400c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (iter == icons.end())
401c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    iter = icons.find(Extension::EXTENSION_ICON_LARGE);
402c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (iter != icons.end())
403c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return extension->GetResource(iter->second);
404c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  else
405c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return ExtensionResource();
406c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
407c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
408c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochExtensionInstallUI* ExtensionsDOMHandler::GetExtensionInstallUI() {
409c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!install_ui_.get())
410c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    install_ui_.reset(new ExtensionInstallUI(dom_ui_->GetProfile()));
411c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return install_ui_.get();
412c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
413c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
414c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ExtensionsDOMHandler::HandleToggleDeveloperMode(const Value* value) {
415c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  bool developer_mode = dom_ui_->GetProfile()->GetPrefs()
416c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      ->GetBoolean(prefs::kExtensionsUIDeveloperMode);
417c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  dom_ui_->GetProfile()->GetPrefs()->SetBoolean(
418c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      prefs::kExtensionsUIDeveloperMode, !developer_mode);
419c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
420c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
421c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ExtensionsDOMHandler::HandleInspectMessage(const Value* value) {
422c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string render_process_id_str;
423c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string render_view_id_str;
424c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int render_process_id;
425c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int render_view_id;
426c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CHECK(value->IsType(Value::TYPE_LIST));
427c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const ListValue* list = static_cast<const ListValue*>(value);
428c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CHECK(list->GetSize() == 2);
429c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CHECK(list->GetString(0, &render_process_id_str));
430c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CHECK(list->GetString(1, &render_view_id_str));
431c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CHECK(StringToInt(render_process_id_str, &render_process_id));
432c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CHECK(StringToInt(render_view_id_str, &render_view_id));
433c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  RenderViewHost* host = RenderViewHost::FromID(render_process_id,
434c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                                render_view_id);
435c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!host) {
436c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // This can happen if the host has gone away since the page was displayed.
437c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
438c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
439c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
440c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DevToolsManager::GetInstance()->ToggleDevToolsWindow(
441c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      host,
442c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      DEVTOOLS_TOGGLE_ACTION_SHOW_CONSOLE);
443c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
444c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
445c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ExtensionsDOMHandler::HandleReloadMessage(const Value* value) {
446c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CHECK(value->IsType(Value::TYPE_LIST));
447c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const ListValue* list = static_cast<const ListValue*>(value);
448c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CHECK(list->GetSize() == 1);
449c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string extension_id;
450c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CHECK(list->GetString(0, &extension_id));
451c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  extensions_service_->ReloadExtension(extension_id);
452c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
453c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
454c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ExtensionsDOMHandler::HandleEnableMessage(const Value* value) {
455c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CHECK(value->IsType(Value::TYPE_LIST));
456c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const ListValue* list = static_cast<const ListValue*>(value);
457c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CHECK(list->GetSize() == 2);
458c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string extension_id, enable_str;
459c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CHECK(list->GetString(0, &extension_id));
460c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CHECK(list->GetString(1, &enable_str));
461c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (enable_str == "true") {
462c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ExtensionPrefs* prefs = extensions_service_->extension_prefs();
463c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (prefs->DidExtensionEscalatePermissions(extension_id)) {
464c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      Extension* extension =
465c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          extensions_service_->GetExtensionById(extension_id, true);
466c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      ShowExtensionDisabledDialog(extensions_service_,
467c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                  dom_ui_->GetProfile(), extension);
468c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    } else {
469c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      extensions_service_->EnableExtension(extension_id);
470c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
471c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else {
472c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    extensions_service_->DisableExtension(extension_id);
473c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
474c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
475c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
476c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ExtensionsDOMHandler::HandleEnableIncognitoMessage(const Value* value) {
477c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CHECK(value->IsType(Value::TYPE_LIST));
478c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const ListValue* list = static_cast<const ListValue*>(value);
479c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CHECK(list->GetSize() == 2);
480c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string extension_id, enable_str;
481c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CHECK(list->GetString(0, &extension_id));
482c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CHECK(list->GetString(1, &enable_str));
483c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Extension* extension = extensions_service_->GetExtensionById(extension_id,
484c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                                               true);
485c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(extension);
486c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
487c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Flipping the incognito bit will generate unload/load notifications for the
488c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // extension, but we don't want to reload the page, because a) we've already
489c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // updated the UI to reflect the change, and b) we want the yellow warning
490c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // text to stay until the user has left the page.
491c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  //
492c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // TODO(aa): This creates crapiness in some cases. For example, in a main
493c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // window, when toggling this, the browser action will flicker because it gets
494c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // unloaded, then reloaded. It would be better to have a dedicated
495c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // notification for this case.
496c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  //
497c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Bug: http://crbug.com/41384
498c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ignore_notifications_ = true;
499c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  extensions_service_->SetIsIncognitoEnabled(extension, enable_str == "true");
500c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ignore_notifications_ = false;
501c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
502c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
503c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ExtensionsDOMHandler::HandleAllowFileAccessMessage(const Value* value) {
504c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CHECK(value->IsType(Value::TYPE_LIST));
505c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const ListValue* list = static_cast<const ListValue*>(value);
506c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CHECK(list->GetSize() == 2);
507c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string extension_id, allow_str;
508c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CHECK(list->GetString(0, &extension_id));
509c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CHECK(list->GetString(1, &allow_str));
510c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Extension* extension = extensions_service_->GetExtensionById(extension_id,
511c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                                               true);
512c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(extension);
513c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
514c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  extensions_service_->SetAllowFileAccess(extension, allow_str == "true");
515c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
516c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
517c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ExtensionsDOMHandler::HandleUninstallMessage(const Value* value) {
518c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CHECK(value->IsType(Value::TYPE_LIST));
519c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const ListValue* list = static_cast<const ListValue*>(value);
520c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CHECK(list->GetSize() == 1);
521c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string extension_id;
522c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CHECK(list->GetString(0, &extension_id));
523c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
524c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Extension *extension =
525c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      extensions_service_->GetExtensionById(extension_id, true);
526c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!extension)
527c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
528c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
529c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!extension_id_prompting_.empty())
530c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;  // only one prompt at a time
531c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
532c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  extension_id_prompting_ = extension_id;
533c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
534c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GetExtensionInstallUI()->ConfirmUninstall(this, extension);
535c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
536c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
537c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ExtensionsDOMHandler::InstallUIProceed(bool create_app_shortcut) {
538c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // We only ever use ExtensionInstallUI for uninstalling, which should never
539c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // result in it telling us to create a shortcut.
540c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(!create_app_shortcut);
541c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
542c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DCHECK(!extension_id_prompting_.empty());
543c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
544c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // The extension can be uninstalled in another window while the UI was
545c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // showing. Do nothing in that case.
546c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Extension* extension =
547c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      extensions_service_->GetExtensionById(extension_id_prompting_, true);
548c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!extension)
549c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
550c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
551c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  extensions_service_->UninstallExtension(extension_id_prompting_,
552c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                          false /* external_uninstall */);
553c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  extension_id_prompting_ = "";
554c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
555c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
556c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ExtensionsDOMHandler::InstallUIAbort() {
557c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  extension_id_prompting_ = "";
558c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
559c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
560c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ExtensionsDOMHandler::HandleOptionsMessage(const Value* value) {
561c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CHECK(value->IsType(Value::TYPE_LIST));
562c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const ListValue* list = static_cast<const ListValue*>(value);
563c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CHECK(list->GetSize() == 1);
564c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string extension_id;
565c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CHECK(list->GetString(0, &extension_id));
566c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  Extension *extension =
567c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      extensions_service_->GetExtensionById(extension_id, false);
568c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!extension || extension->options_url().is_empty()) {
569c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
570c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
571c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  dom_ui_->GetProfile()->GetExtensionProcessManager()->OpenOptionsPage(
572c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      extension, NULL);
573c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
574c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
575c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ExtensionsDOMHandler::HandleLoadMessage(const Value* value) {
576c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  FilePath::StringType string_path;
577c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CHECK(value->IsType(Value::TYPE_LIST));
578c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const ListValue* list = static_cast<const ListValue*>(value);
579c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CHECK(list->GetSize() == 1) << list->GetSize();
580c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CHECK(list->GetString(0, &string_path));
581c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  extensions_service_->LoadExtension(FilePath(string_path));
582c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
583c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
584c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ExtensionsDOMHandler::ShowAlert(const std::string& message) {
585c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ListValue arguments;
586c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  arguments.Append(Value::CreateStringValue(message));
587c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  dom_ui_->CallJavascriptFunction(L"alert", arguments);
588c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
589c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
590c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ExtensionsDOMHandler::HandlePackMessage(const Value* value) {
591c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::wstring extension_path;
592c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::wstring private_key_path;
593c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CHECK(value->IsType(Value::TYPE_LIST));
594c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const ListValue* list = static_cast<const ListValue*>(value);
595c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CHECK(list->GetSize() == 2);
596c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CHECK(list->GetString(0, &extension_path));
597c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CHECK(list->GetString(1, &private_key_path));
598c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
599c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  FilePath root_directory = FilePath::FromWStringHack(extension_path);
600c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  FilePath key_file = FilePath::FromWStringHack(private_key_path);
601c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
602c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (root_directory.empty()) {
603c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (extension_path.empty()) {
604c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      ShowAlert(l10n_util::GetStringUTF8(
605c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          IDS_EXTENSION_PACK_DIALOG_ERROR_ROOT_REQUIRED));
606c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    } else {
607c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      ShowAlert(l10n_util::GetStringUTF8(
608c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          IDS_EXTENSION_PACK_DIALOG_ERROR_ROOT_INVALID));
609c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
610c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
611c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
612c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
613c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
614c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!private_key_path.empty() && key_file.empty()) {
615c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ShowAlert(l10n_util::GetStringUTF8(
616c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        IDS_EXTENSION_PACK_DIALOG_ERROR_KEY_INVALID));
617c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
618c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
619c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
620c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  pack_job_ = new PackExtensionJob(this, root_directory, key_file);
621c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  pack_job_->Start();
622c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
623c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
624c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ExtensionsDOMHandler::OnPackSuccess(const FilePath& crx_file,
625c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                         const FilePath& pem_file) {
626c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string message;
627c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!pem_file.empty()) {
628c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    message = WideToUTF8(l10n_util::GetStringF(
629c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        IDS_EXTENSION_PACK_DIALOG_SUCCESS_BODY_NEW,
630c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        crx_file.ToWStringHack(),
631c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        pem_file.ToWStringHack()));
632c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else {
633c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    message = WideToUTF8(l10n_util::GetStringF(
634c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        IDS_EXTENSION_PACK_DIALOG_SUCCESS_BODY_UPDATE,
635c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        crx_file.ToWStringHack()));
636c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
637c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ShowAlert(message);
638c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
639c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ListValue results;
640c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  dom_ui_->CallJavascriptFunction(L"hidePackDialog", results);
641c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
642c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
643c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ExtensionsDOMHandler::OnPackFailure(const std::wstring& error) {
644c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ShowAlert(WideToUTF8(error));
645c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
646c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
647c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ExtensionsDOMHandler::HandleAutoUpdateMessage(const Value* value) {
648c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ExtensionUpdater* updater = extensions_service_->updater();
649c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (updater) {
650c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    updater->CheckNow();
651c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
652c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
653c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
654c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ExtensionsDOMHandler::HandleSelectFilePathMessage(const Value* value) {
655c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string select_type;
656c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::string operation;
657c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CHECK(value->IsType(Value::TYPE_LIST));
658c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const ListValue* list = static_cast<const ListValue*>(value);
659c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CHECK(list->GetSize() == 2);
660c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CHECK(list->GetString(0, &select_type));
661c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CHECK(list->GetString(1, &operation));
662c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
663c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  SelectFileDialog::Type type = SelectFileDialog::SELECT_FOLDER;
664c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  static SelectFileDialog::FileTypeInfo info;
665c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int file_type_index = 0;
666c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (select_type == "file")
667c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    type = SelectFileDialog::SELECT_OPEN_FILE;
668c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
669c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  string16 select_title;
670c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (operation == "load")
671c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    select_title = l10n_util::GetStringUTF16(IDS_EXTENSION_LOAD_FROM_DIRECTORY);
672c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  else if (operation == "packRoot")
673c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    select_title = l10n_util::GetStringUTF16(
674c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        IDS_EXTENSION_PACK_DIALOG_SELECT_ROOT);
675c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  else if (operation == "pem") {
676c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    select_title = l10n_util::GetStringUTF16(
677c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        IDS_EXTENSION_PACK_DIALOG_SELECT_KEY);
678c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    info.extensions.push_back(std::vector<FilePath::StringType>());
679c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        info.extensions.front().push_back(FILE_PATH_LITERAL("pem"));
680c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        info.extension_description_overrides.push_back(WideToUTF16(
681c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            l10n_util::GetString(
682c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                IDS_EXTENSION_PACK_DIALOG_KEY_FILE_TYPE_DESCRIPTION)));
683c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        info.include_all_files = true;
684c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    file_type_index = 1;
685c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  } else {
686c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    NOTREACHED();
687c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
688c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
689c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
690c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  load_extension_dialog_ = SelectFileDialog::Create(this);
691c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  load_extension_dialog_->SelectFile(type, select_title, FilePath(), &info,
692c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      file_type_index, FILE_PATH_LITERAL(""),
693c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      dom_ui_->tab_contents()->view()->GetTopLevelNativeWindow(), NULL);
694c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
695c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
696c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
697c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ExtensionsDOMHandler::FileSelected(const FilePath& path, int index,
698c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                        void* params) {
699c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Add the extensions to the results structure.
700c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ListValue results;
701c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  results.Append(Value::CreateStringValue(path.value()));
702c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  dom_ui_->CallJavascriptFunction(L"window.handleFilePathSelected", results);
703c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
704c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
705c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ExtensionsDOMHandler::Observe(NotificationType type,
706c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                   const NotificationSource& source,
707c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                   const NotificationDetails& details) {
708c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  switch (type.value) {
709c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // We listen for notifications that will result in the page being
710c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // repopulated with data twice for the same event in certain cases.
711c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // For instance, EXTENSION_LOADED & EXTENSION_PROCESS_CREATED because
712c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // we don't know about the views for an extension at EXTENSION_LOADED, but
713c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // if we only listen to EXTENSION_PROCESS_CREATED, we'll miss extensions
714c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // that don't have a process at startup. Similarly, NAV_ENTRY_COMMITTED &
715c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // EXTENSION_FUNCTION_DISPATCHER_CREATED because we want to handle both
716c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // the case of live app pages (which don't have an EFD) and
717c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // chrome-extension:// urls which are served in a TabContents.
718c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    //
719c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Doing it this way gets everything but causes the page to be rendered
720c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // more than we need. It doesn't seem to result in any noticeable flicker.
721c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case NotificationType::RENDER_VIEW_HOST_DELETED:
722c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      deleting_rvh_ = Details<RenderViewHost>(details).ptr();
723c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      MaybeUpdateAfterNotification();
724c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      break;
725c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case NotificationType::BACKGROUND_CONTENTS_DELETED:
726c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      deleting_rvh_ = Details<BackgroundContents>(details)->render_view_host();
727c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      MaybeUpdateAfterNotification();
728c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      break;
729c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case NotificationType::EXTENSION_LOADED:
730c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case NotificationType::EXTENSION_PROCESS_CREATED:
731c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case NotificationType::EXTENSION_UNLOADED:
732c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case NotificationType::EXTENSION_UNLOADED_DISABLED:
733c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case NotificationType::EXTENSION_UPDATE_DISABLED:
734c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case NotificationType::EXTENSION_FUNCTION_DISPATCHER_CREATED:
735c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case NotificationType::EXTENSION_FUNCTION_DISPATCHER_DESTROYED:
736c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case NotificationType::NAV_ENTRY_COMMITTED:
737c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    case NotificationType::BACKGROUND_CONTENTS_NAVIGATED:
738c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      MaybeUpdateAfterNotification();
739c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      break;
740c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    default:
741c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NOTREACHED();
742c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
743c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
744c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
745c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ExtensionsDOMHandler::MaybeUpdateAfterNotification() {
746c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!ignore_notifications_ && dom_ui_->tab_contents())
747c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    HandleRequestExtensionsData(NULL);
748c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  deleting_rvh_ = NULL;
749c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
750c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
751c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic void CreateScriptFileDetailValue(
752c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const FilePath& extension_path, const UserScript::FileList& scripts,
753c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const wchar_t* key, DictionaryValue* script_data) {
754c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (scripts.empty())
755c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return;
756c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
757c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ListValue *list = new ListValue();
758c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (size_t i = 0; i < scripts.size(); ++i) {
759c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const UserScript::File& file = scripts[i];
760c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // TODO(cira): this information is not used on extension page yet. We
761c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // may want to display actual resource that got loaded, not default.
762c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    list->Append(
763c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        new StringValue(file.relative_path().value()));
764c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
765c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  script_data->Set(key, list);
766c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
767c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
768c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Static
769c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochDictionaryValue* ExtensionsDOMHandler::CreateContentScriptDetailValue(
770c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const UserScript& script, const FilePath& extension_path) {
771c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DictionaryValue* script_data = new DictionaryValue();
772c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CreateScriptFileDetailValue(extension_path, script.js_scripts(), L"js",
773c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    script_data);
774c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  CreateScriptFileDetailValue(extension_path, script.css_scripts(), L"css",
775c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    script_data);
776c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
777c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Get list of glob "matches" strings
778c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ListValue *url_pattern_list = new ListValue();
779c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const std::vector<URLPattern>& url_patterns = script.url_patterns();
780c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (std::vector<URLPattern>::const_iterator url_pattern =
781c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      url_patterns.begin();
782c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    url_pattern != url_patterns.end(); ++url_pattern) {
783c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    url_pattern_list->Append(new StringValue(url_pattern->GetAsString()));
784c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
785c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
786c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  script_data->Set(L"matches", url_pattern_list);
787c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
788c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return script_data;
789c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
790c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
791c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic bool ExtensionWantsFileAccess(const Extension* extension) {
792c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (UserScriptList::const_iterator it = extension->content_scripts().begin();
793c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch       it != extension->content_scripts().end(); ++it) {
794c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    for (UserScript::PatternList::const_iterator pattern =
795c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch             it->url_patterns().begin();
796c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch         pattern != it->url_patterns().end(); ++pattern) {
797c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      if (pattern->MatchesScheme(chrome::kFileScheme))
798c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        return true;
799c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
800c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
801c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
802c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return false;
803c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
804c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
805c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Static
806c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochDictionaryValue* ExtensionsDOMHandler::CreateExtensionDetailValue(
807c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ExtensionsService* service, const Extension* extension,
808c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const std::vector<ExtensionPage>& pages, bool enabled) {
809c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DictionaryValue* extension_data = new DictionaryValue();
810c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
811c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  extension_data->SetString(L"id", extension->id());
812c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  extension_data->SetString(L"name", extension->name());
813c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  extension_data->SetString(L"description", extension->description());
814c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  extension_data->SetString(L"version", extension->version()->GetString());
815c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  extension_data->SetBoolean(L"enabled", enabled);
816c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  extension_data->SetBoolean(L"enabledIncognito",
817c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      service ? service->IsIncognitoEnabled(extension) : false);
818c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  extension_data->SetBoolean(L"wantsFileAccess",
819c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      ExtensionWantsFileAccess(extension));
820c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  extension_data->SetBoolean(L"allowFileAccess",
821c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      service ? service->AllowFileAccess(extension) : false);
822c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  extension_data->SetBoolean(L"allow_reload",
823c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                             extension->location() == Extension::LOAD);
824c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
825c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Determine the sort order: Extensions loaded through --load-extensions show
826c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // up at the top. Disabled extensions show up at the bottom.
827c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (extension->location() == Extension::LOAD)
828c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    extension_data->SetInteger(L"order", 1);
829c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  else
830c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    extension_data->SetInteger(L"order", 2);
831c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
832c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!extension->options_url().is_empty())
833c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    extension_data->SetString(L"options_url", extension->options_url().spec());
834c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
835c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Add list of content_script detail DictionaryValues.
836c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ListValue *content_script_list = new ListValue();
837c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  UserScriptList content_scripts = extension->content_scripts();
838c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (UserScriptList::const_iterator script = content_scripts.begin();
839c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    script != content_scripts.end(); ++script) {
840c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      content_script_list->Append(
841c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          CreateContentScriptDetailValue(*script, extension->path()));
842c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
843c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  extension_data->Set(L"content_scripts", content_script_list);
844c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
845c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Add permissions.
846c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ListValue *permission_list = new ListValue;
847c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::vector<URLPattern> permissions = extension->host_permissions();
848c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (std::vector<URLPattern>::iterator permission = permissions.begin();
849c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch       permission != permissions.end(); ++permission) {
850c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    permission_list->Append(Value::CreateStringValue(
851c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        permission->GetAsString()));
852c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
853c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  extension_data->Set(L"permissions", permission_list);
854c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
855c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Add views
856c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ListValue* views = new ListValue;
857c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (std::vector<ExtensionPage>::const_iterator iter = pages.begin();
858c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch       iter != pages.end(); ++iter) {
859c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DictionaryValue* view_value = new DictionaryValue;
860c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (iter->url.scheme() == chrome::kExtensionScheme) {
861c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // No leading slash.
862c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      view_value->SetString(L"path", iter->url.path().substr(1));
863c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    } else {
864c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // For live pages, use the full URL.
865c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      view_value->SetString(L"path", iter->url.spec());
866c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
867c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    view_value->SetInteger(L"renderViewId", iter->render_view_id);
868c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    view_value->SetInteger(L"renderProcessId", iter->render_process_id);
869c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    views->Append(view_value);
870c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
871c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  extension_data->Set(L"views", views);
872c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  extension_data->SetBoolean(L"hasPopupAction",
873c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      extension->browser_action() || extension->page_action());
874c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  extension_data->SetString(L"galleryUrl", extension->GalleryUrl().spec());
875c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
876c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return extension_data;
877c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
878c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
879c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstd::vector<ExtensionPage> ExtensionsDOMHandler::GetActivePagesForExtension(
880c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    RenderProcessHost* process,
881c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    Extension* extension) {
882c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  std::vector<ExtensionPage> result;
883c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (!process)
884c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    return result;
885c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
886c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  RenderProcessHost::listeners_iterator iter = process->ListenersIterator();
887c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  for (; !iter.IsAtEnd(); iter.Advance()) {
888c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const RenderWidgetHost* widget =
889c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        static_cast<const RenderWidgetHost*>(iter.GetCurrentValue());
890c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    DCHECK(widget);
891c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (!widget || !widget->IsRenderView())
892c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      continue;
893c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const RenderViewHost* host = static_cast<const RenderViewHost*>(widget);
894c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (host == deleting_rvh_ ||
895c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        ViewType::EXTENSION_POPUP == host->delegate()->GetRenderViewType())
896c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      continue;
897c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
898c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    GURL url = host->delegate()->GetURL();
899c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (url.SchemeIs(chrome::kExtensionScheme)) {
900c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      if (url.host() != extension->id())
901c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        continue;
902c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    } else if (!extension->web_extent().ContainsURL(url)) {
903c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      continue;
904c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
905c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
906c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    result.push_back(ExtensionPage(url, process->id(), host->routing_id()));
907c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
908c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
909c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return result;
910c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
911c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
912c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochExtensionsDOMHandler::~ExtensionsDOMHandler() {
913c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (pack_job_.get())
914c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    pack_job_->ClearClient();
915c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
916c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (icon_loader_.get())
917c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    icon_loader_->Cancel();
918c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
919c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
920c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// ExtensionsDOMHandler, public: -----------------------------------------------
921c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
922c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochExtensionsUI::ExtensionsUI(TabContents* contents) : DOMUI(contents) {
923c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ExtensionsService *exstension_service =
924c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      GetProfile()->GetOriginalProfile()->GetExtensionsService();
925c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
926c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ExtensionsDOMHandler* handler = new ExtensionsDOMHandler(exstension_service);
927c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  AddMessageHandler(handler);
928c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  handler->Attach(this);
929c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
930c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ExtensionsUIHTMLSource* html_source = new ExtensionsUIHTMLSource();
931c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
932c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Set up the chrome://extensions/ source.
933c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ChromeThread::PostTask(
934c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      ChromeThread::IO, FROM_HERE,
935c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NewRunnableMethod(
936c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          Singleton<ChromeURLDataManager>::get(),
937c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          &ChromeURLDataManager::AddDataSource,
938c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          make_scoped_refptr(html_source)));
939c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
940c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
941c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// static
942c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochRefCountedMemory* ExtensionsUI::GetFaviconResourceBytes() {
943c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return ResourceBundle::GetSharedInstance().
944c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      LoadDataResourceBytes(IDR_PLUGIN);
945c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
946c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
947c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// static
948c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid ExtensionsUI::RegisterUserPrefs(PrefService* prefs) {
949c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  prefs->RegisterBooleanPref(prefs::kExtensionsUIDeveloperMode, false);
950c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
951