1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/ui/webui/conflicts_ui.h"
6
7 #if defined(OS_WIN)
8
9 #include <string>
10
11 #include "base/string_number_conversions.h"
12 #include "base/utf_string_conversions.h"
13 #include "base/values.h"
14 #include "chrome/browser/enumerate_modules_model_win.h"
15 #include "chrome/browser/metrics/user_metrics.h"
16 #include "chrome/browser/profiles/profile.h"
17 #include "chrome/browser/ui/webui/chrome_url_data_manager.h"
18 #include "chrome/common/jstemplate_builder.h"
19 #include "chrome/common/url_constants.h"
20 #include "content/browser/tab_contents/tab_contents.h"
21 #include "content/common/notification_observer.h"
22 #include "content/common/notification_registrar.h"
23 #include "content/common/notification_service.h"
24 #include "grit/browser_resources.h"
25 #include "grit/chromium_strings.h"
26 #include "grit/generated_resources.h"
27 #include "grit/theme_resources.h"
28 #include "ui/base/l10n/l10n_util.h"
29 #include "ui/base/resource/resource_bundle.h"
30
31 namespace {
32
33 ////////////////////////////////////////////////////////////////////////////////
34 //
35 // ConflictsUIHTMLSource
36 //
37 ////////////////////////////////////////////////////////////////////////////////
38
39 class ConflictsUIHTMLSource : public ChromeURLDataManager::DataSource {
40 public:
ConflictsUIHTMLSource()41 ConflictsUIHTMLSource()
42 : DataSource(chrome::kChromeUIConflictsHost, MessageLoop::current()) {}
43
44 // Called when the network layer has requested a resource underneath
45 // the path we registered.
46 virtual void StartDataRequest(const std::string& path,
47 bool is_incognito,
48 int request_id);
49
GetMimeType(const std::string &) const50 virtual std::string GetMimeType(const std::string&) const {
51 return "text/html";
52 }
53
54 private:
55 DISALLOW_COPY_AND_ASSIGN(ConflictsUIHTMLSource);
56 };
57
StartDataRequest(const std::string & path,bool is_incognito,int request_id)58 void ConflictsUIHTMLSource::StartDataRequest(const std::string& path,
59 bool is_incognito,
60 int request_id) {
61 // Strings used in the JsTemplate file.
62 DictionaryValue localized_strings;
63 localized_strings.SetString("loadingMessage",
64 l10n_util::GetStringUTF16(IDS_CONFLICTS_LOADING_MESSAGE));
65 localized_strings.SetString("modulesLongTitle",
66 l10n_util::GetStringUTF16(IDS_CONFLICTS_CHECK_PAGE_TITLE_LONG));
67 localized_strings.SetString("modulesBlurb",
68 l10n_util::GetStringUTF16(IDS_CONFLICTS_EXPLANATION_TEXT));
69 localized_strings.SetString("moduleSuspectedBad",
70 l10n_util::GetStringUTF16(IDS_CONFLICTS_CHECK_WARNING_SUSPECTED));
71 localized_strings.SetString("moduleConfirmedBad",
72 l10n_util::GetStringUTF16(IDS_CONFLICTS_CHECK_WARNING_CONFIRMED));
73 localized_strings.SetString("helpCenterLink",
74 l10n_util::GetStringUTF16(IDS_CONFLICTS_HELP_CENTER_LINK));
75 localized_strings.SetString("investigatingText",
76 l10n_util::GetStringUTF16(IDS_CONFLICTS_CHECK_INVESTIGATING));
77 localized_strings.SetString("modulesNoneLoaded",
78 l10n_util::GetStringUTF16(IDS_CONFLICTS_NO_MODULES_LOADED));
79 localized_strings.SetString("headerSoftware",
80 l10n_util::GetStringUTF16(IDS_CONFLICTS_HEADER_SOFTWARE));
81 localized_strings.SetString("headerSignedBy",
82 l10n_util::GetStringUTF16(IDS_CONFLICTS_HEADER_SIGNED_BY));
83 localized_strings.SetString("headerLocation",
84 l10n_util::GetStringUTF16(IDS_CONFLICTS_HEADER_LOCATION));
85 localized_strings.SetString("headerVersion",
86 l10n_util::GetStringUTF16(IDS_CONFLICTS_HEADER_VERSION));
87 localized_strings.SetString("headerHelpTip",
88 l10n_util::GetStringUTF16(IDS_CONFLICTS_HEADER_HELP_TIP));
89
90 ChromeURLDataManager::DataSource::SetFontAndTextDirection(&localized_strings);
91
92 static const base::StringPiece flags_html(
93 ResourceBundle::GetSharedInstance().GetRawDataResource(
94 IDR_ABOUT_CONFLICTS_HTML));
95 std::string full_html(flags_html.data(), flags_html.size());
96 jstemplate_builder::AppendJsonHtml(&localized_strings, &full_html);
97 jstemplate_builder::AppendI18nTemplateSourceHtml(&full_html);
98 jstemplate_builder::AppendI18nTemplateProcessHtml(&full_html);
99 jstemplate_builder::AppendJsTemplateSourceHtml(&full_html);
100
101 scoped_refptr<RefCountedBytes> html_bytes(new RefCountedBytes);
102 html_bytes->data.resize(full_html.size());
103 std::copy(full_html.begin(), full_html.end(), html_bytes->data.begin());
104
105 SendResponse(request_id, html_bytes);
106 }
107
108 ////////////////////////////////////////////////////////////////////////////////
109 //
110 // ConflictsDOMHandler
111 //
112 ////////////////////////////////////////////////////////////////////////////////
113
114 // The handler for JavaScript messages for the about:flags page.
115 class ConflictsDOMHandler : public WebUIMessageHandler,
116 public NotificationObserver {
117 public:
ConflictsDOMHandler()118 ConflictsDOMHandler() {}
~ConflictsDOMHandler()119 virtual ~ConflictsDOMHandler() {}
120
121 // WebUIMessageHandler implementation.
122 virtual void RegisterMessages();
123
124 // Callback for the "requestModuleList" message.
125 void HandleRequestModuleList(const ListValue* args);
126
127 private:
128 void SendModuleList();
129
130 void Observe(NotificationType type,
131 const NotificationSource& source,
132 const NotificationDetails& details);
133
134 NotificationRegistrar registrar_;
135
136 DISALLOW_COPY_AND_ASSIGN(ConflictsDOMHandler);
137 };
138
RegisterMessages()139 void ConflictsDOMHandler::RegisterMessages() {
140 web_ui_->RegisterMessageCallback("requestModuleList",
141 NewCallback(this, &ConflictsDOMHandler::HandleRequestModuleList));
142 }
143
HandleRequestModuleList(const ListValue * args)144 void ConflictsDOMHandler::HandleRequestModuleList(const ListValue* args) {
145 // This request is handled asynchronously. See Observe for when we reply back.
146 registrar_.Add(this, NotificationType::MODULE_LIST_ENUMERATED,
147 NotificationService::AllSources());
148 EnumerateModulesModel::GetInstance()->ScanNow();
149 }
150
SendModuleList()151 void ConflictsDOMHandler::SendModuleList() {
152 EnumerateModulesModel* loaded_modules = EnumerateModulesModel::GetInstance();
153 ListValue* list = loaded_modules->GetModuleList();
154 DictionaryValue results;
155 results.Set("moduleList", list);
156
157 // Add the section title and the total count for bad modules found.
158 int confirmed_bad = loaded_modules->confirmed_bad_modules_detected();
159 int suspected_bad = loaded_modules->suspected_bad_modules_detected();
160 string16 table_title;
161 if (!confirmed_bad && !suspected_bad) {
162 table_title += l10n_util::GetStringFUTF16(
163 IDS_CONFLICTS_CHECK_PAGE_TABLE_TITLE_SUFFIX_ONE,
164 base::IntToString16(list->GetSize()));
165 } else {
166 table_title += l10n_util::GetStringFUTF16(
167 IDS_CONFLICTS_CHECK_PAGE_TABLE_TITLE_SUFFIX_TWO,
168 base::IntToString16(list->GetSize()),
169 base::IntToString16(confirmed_bad),
170 base::IntToString16(suspected_bad));
171 }
172 results.SetString("modulesTableTitle", table_title);
173
174 web_ui_->CallJavascriptFunction("returnModuleList", results);
175 }
176
Observe(NotificationType type,const NotificationSource & source,const NotificationDetails & details)177 void ConflictsDOMHandler::Observe(NotificationType type,
178 const NotificationSource& source,
179 const NotificationDetails& details) {
180 switch (type.value) {
181 case NotificationType::MODULE_LIST_ENUMERATED:
182 SendModuleList();
183 registrar_.RemoveAll();
184 break;
185 default:
186 NOTREACHED();
187 break;
188 }
189 }
190
191 } // namespace
192
193 ///////////////////////////////////////////////////////////////////////////////
194 //
195 // ConflictsUI
196 //
197 ///////////////////////////////////////////////////////////////////////////////
198
ConflictsUI(TabContents * contents)199 ConflictsUI::ConflictsUI(TabContents* contents) : WebUI(contents) {
200 UserMetrics::RecordAction(
201 UserMetricsAction("ViewAboutConflicts"), contents->profile());
202
203 AddMessageHandler((new ConflictsDOMHandler())->Attach(this));
204
205 ConflictsUIHTMLSource* html_source = new ConflictsUIHTMLSource();
206
207 // Set up the about:conflicts source.
208 contents->profile()->GetChromeURLDataManager()->AddDataSource(html_source);
209 }
210
211 // static
GetFaviconResourceBytes()212 RefCountedMemory* ConflictsUI::GetFaviconResourceBytes() {
213 return ResourceBundle::GetSharedInstance().
214 LoadDataResourceBytes(IDR_CONFLICT_FAVICON);
215 }
216
217 #endif
218