1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "chrome/browser/ui/location_bar/origin_chip_info.h"
7 #include "base/prefs/pref_service.h"
8 #include "base/strings/string_util.h"
9 #include "base/strings/utf_string_conversions.h"
10 #include "chrome/browser/extensions/extension_service.h"
11 #include "chrome/browser/extensions/extension_util.h"
12 #include "chrome/browser/profiles/profile.h"
13 #include "chrome/browser/safe_browsing/client_side_detection_host.h"
14 #include "chrome/browser/safe_browsing/safe_browsing_tab_observer.h"
15 #include "chrome/browser/ui/toolbar/toolbar_model.h"
16 #include "chrome/common/extensions/extension_constants.h"
17 #include "chrome/common/pref_names.h"
18 #include "chrome/common/url_constants.h"
19 #include "chrome/grit/chromium_strings.h"
20 #include "chrome/grit/generated_resources.h"
21 #include "content/public/browser/web_contents.h"
22 #include "extensions/browser/extension_icon_image.h"
23 #include "extensions/browser/extension_system.h"
24 #include "extensions/common/constants.h"
25 #include "extensions/common/manifest_handlers/icons_handler.h"
26 #include "grit/components_strings.h"
27 #include "grit/theme_resources.h"
28 #include "net/base/net_util.h"
29 #include "ui/base/l10n/l10n_util.h"
34 // For selected kChromeUIScheme and url::kAboutScheme, return the string
36 // number for the title of the page. If we don't have a specialized title,
38 int StringForChromeHost(const GURL
& url
) {
39 DCHECK(url
.is_empty() || url
.SchemeIs(content::kChromeUIScheme
));
42 return IDS_NEW_TAB_TITLE
;
44 // TODO(gbillock): Just get the page title and special case exceptions?
45 std::string host
= url
.host();
46 if (host
== chrome::kChromeUIAppLauncherPageHost
)
47 return IDS_APP_DEFAULT_PAGE_NAME
;
48 if (host
== chrome::kChromeUIBookmarksHost
)
49 return IDS_BOOKMARK_MANAGER_TITLE
;
50 if (host
== chrome::kChromeUIComponentsHost
)
51 return IDS_COMPONENTS_TITLE
;
52 if (host
== chrome::kChromeUICrashesHost
)
53 return IDS_CRASHES_TITLE
;
54 #if defined(ENABLE_SERVICE_DISCOVERY)
55 if (host
== chrome::kChromeUIDevicesHost
)
56 return IDS_LOCAL_DISCOVERY_DEVICES_PAGE_TITLE
;
57 #endif // ENABLE_SERVICE_DISCOVERY
58 if (host
== chrome::kChromeUIDownloadsHost
)
59 return IDS_DOWNLOAD_TITLE
;
60 if (host
== chrome::kChromeUIExtensionsHost
)
61 return IDS_MANAGE_EXTENSIONS_SETTING_WINDOWS_TITLE
;
62 if (host
== chrome::kChromeUIHelpHost
)
63 return IDS_ABOUT_TITLE
;
64 if (host
== chrome::kChromeUIHistoryHost
)
65 return IDS_HISTORY_TITLE
;
66 if (host
== chrome::kChromeUINewTabHost
)
67 return IDS_NEW_TAB_TITLE
;
68 if (host
== chrome::kChromeUIPluginsHost
)
69 return IDS_PLUGINS_TITLE
;
70 if (host
== chrome::kChromeUIPolicyHost
)
71 return IDS_POLICY_TITLE
;
72 #if defined(ENABLE_FULL_PRINTING)
73 if (host
== chrome::kChromeUIPrintHost
)
74 return IDS_PRINT_PREVIEW_TITLE
;
75 #endif // ENABLE_FULL_PRINTING
76 if (host
== chrome::kChromeUISettingsHost
)
77 return IDS_SETTINGS_TITLE
;
78 if (host
== chrome::kChromeUIVersionHost
)
79 return IDS_ABOUT_VERSION_TITLE
;
86 OriginChipInfo::OriginChipInfo(extensions::IconImage::Observer
* owner
,
90 security_level_(ToolbarModel::NONE
),
91 is_url_malware_(false),
92 icon_(IDR_PRODUCT_LOGO_16
) {
95 OriginChipInfo::~OriginChipInfo() {
98 bool OriginChipInfo::Update(const content::WebContents
* web_contents
,
99 const ToolbarModel
* toolbar_model
) {
100 GURL displayed_url
= toolbar_model
->GetURL();
101 ToolbarModel::SecurityLevel security_level
=
102 toolbar_model
->GetSecurityLevel(true);
103 bool is_url_malware
= OriginChip::IsMalware(displayed_url
, web_contents
);
105 if ((displayed_url_
== displayed_url
) &&
106 (security_level_
== security_level
) &&
107 (is_url_malware_
== is_url_malware
))
110 displayed_url_
= displayed_url
;
111 security_level_
= security_level
;
112 is_url_malware_
= is_url_malware
;
114 label_
= OriginChip::LabelFromURLForProfile(displayed_url
, profile_
);
115 if (security_level_
== ToolbarModel::EV_SECURE
) {
116 label_
= l10n_util::GetStringFUTF16(IDS_SITE_CHIP_EV_SSL_LABEL
,
117 toolbar_model
->GetEVCertName(),
122 if (displayed_url_
.SchemeIs(extensions::kExtensionScheme
)) {
123 const extensions::Extension
* extension
=
124 extensions::ExtensionSystem::Get(profile_
)->extension_service()->
125 extensions()->GetExtensionOrAppByURL(displayed_url_
);
128 icon_
= IDR_EXTENSIONS_FAVICON
;
129 extension_icon_image_
.reset(
130 new extensions::IconImage(profile_
,
132 extensions::IconsInfo::GetIcons(extension
),
133 extension_misc::EXTENSION_ICON_BITTY
,
134 extensions::util::GetDefaultAppIcon(),
137 // Forces load of the image.
138 extension_icon_image_
->image_skia().GetRepresentation(1.0f
);
139 if (!extension_icon_image_
->image_skia().image_reps().empty())
140 owner_
->OnExtensionIconImageChanged(extension_icon_image_
.get());
146 if (extension_icon_image_
) {
147 extension_icon_image_
.reset();
148 owner_
->OnExtensionIconImageChanged(NULL
);
151 icon_
= (displayed_url_
.is_empty() ||
152 displayed_url_
.SchemeIs(content::kChromeUIScheme
)) ?
153 IDR_PRODUCT_LOGO_16
:
154 toolbar_model
->GetIconForSecurityLevel(security_level_
);
159 base::string16
OriginChipInfo::Tooltip() const {
160 return base::UTF8ToUTF16(displayed_url_
.spec());
164 bool OriginChip::IsMalware(const GURL
& url
, const content::WebContents
* tab
) {
167 if (tab
->GetURL() != url
)
170 const safe_browsing::SafeBrowsingTabObserver
* sb_observer
=
171 safe_browsing::SafeBrowsingTabObserver::FromWebContents(tab
);
172 return sb_observer
&& sb_observer
->DidPageReceiveSafeBrowsingMatch();
176 base::string16
OriginChip::LabelFromURLForProfile(const GURL
& provided_url
,
178 // First, strip view-source: if it appears. Note that GetContent removes
179 // "view-source:" but leaves the original scheme (http, https, ftp, etc).
180 GURL
url(provided_url
);
181 if (url
.SchemeIs(content::kViewSourceScheme
))
182 url
= GURL(url
.GetContent());
184 // About scheme pages. Currently all about: URLs other than about:blank
185 // redirect to chrome: URLs, so this only affects about:blank.
186 if (url
.SchemeIs(url::kAboutScheme
))
187 return base::UTF8ToUTF16(url
.spec());
189 // Chrome built-in pages.
190 if (url
.is_empty() || url
.SchemeIs(content::kChromeUIScheme
)) {
191 int string_ref
= StringForChromeHost(url
);
192 return l10n_util::GetStringUTF16(
193 (string_ref
== -1) ? IDS_SHORT_PRODUCT_NAME
: string_ref
);
196 // For chrome-extension URLs, return the extension name.
197 if (url
.SchemeIs(extensions::kExtensionScheme
)) {
198 ExtensionService
* service
=
199 extensions::ExtensionSystem::Get(profile
)->extension_service();
200 const extensions::Extension
* extension
=
201 service
->extensions()->GetExtensionOrAppByURL(url
);
203 base::UTF8ToUTF16(extension
->name()) : base::UTF8ToUTF16(url
.host());
206 if (url
.SchemeIsHTTPOrHTTPS() || url
.SchemeIs(url::kFtpScheme
)) {
207 // See ToolbarModelImpl::GetText(). Does not pay attention to any user
208 // edits, and uses GetURL/net::FormatUrl -- We don't really care about
209 // length or the autocomplete parser.
210 // TODO(gbillock): This uses an algorithm very similar to GetText, which
211 // is probably too conservative. Try out just using a simpler mechanism of
212 // StripWWW() and IDNToUnicode().
213 std::string languages
;
215 languages
= profile
->GetPrefs()->GetString(prefs::kAcceptLanguages
);
217 // TODO(macourteau): Extract the bits we care about from FormatUrl to
218 // format |url.host()| instead of this.
219 base::string16 formatted
= net::FormatUrl(url
.GetOrigin(), languages
,
220 net::kFormatUrlOmitAll
, net::UnescapeRule::NORMAL
, NULL
, NULL
, NULL
);
221 // Remove scheme, "www.", and trailing "/".
222 if (StartsWith(formatted
, base::ASCIIToUTF16("http://"), false))
223 formatted
= formatted
.substr(7);
224 else if (StartsWith(formatted
, base::ASCIIToUTF16("https://"), false))
225 formatted
= formatted
.substr(8);
226 else if (StartsWith(formatted
, base::ASCIIToUTF16("ftp://"), false))
227 formatted
= formatted
.substr(6);
228 if (StartsWith(formatted
, base::ASCIIToUTF16("www."), false))
229 formatted
= formatted
.substr(4);
230 if (EndsWith(formatted
, base::ASCIIToUTF16("/"), false))
231 formatted
= formatted
.substr(0, formatted
.size() - 1);
235 // These internal-ish debugging-style schemes we don't expect users
236 // to see. In these cases, the site chip will display the first
237 // part of the full URL.
238 if (url
.SchemeIs(chrome::kChromeNativeScheme
) ||
239 url
.SchemeIs(url::kBlobScheme
) ||
240 url
.SchemeIs(content::kChromeDevToolsScheme
) ||
241 url
.SchemeIs(url::kDataScheme
) ||
242 url
.SchemeIs(url::kFileScheme
) ||
243 url
.SchemeIs(url::kFileSystemScheme
) ||
244 url
.SchemeIs(content::kGuestScheme
) ||
245 url
.SchemeIs(url::kJavaScriptScheme
) ||
246 url
.SchemeIs(url::kMailToScheme
) ||
247 url
.SchemeIs(content::kMetadataScheme
) ||
248 url
.SchemeIs(content::kSwappedOutScheme
)) {
249 std::string truncated_url
;
250 base::TruncateUTF8ToByteSize(url
.spec(), 1000, &truncated_url
);
251 return base::UTF8ToUTF16(truncated_url
);
254 #if defined(OS_CHROMEOS)
255 if (url
.SchemeIs(chrome::kCrosScheme
) ||
256 url
.SchemeIs(chrome::kDriveScheme
))
257 return base::UTF8ToUTF16(url
.spec());
260 // If all else fails, return the hostname.
261 return base::UTF8ToUTF16(url
.host());