OLD | NEW |
---|---|
1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/ui/webui/settings/site_settings_handler.h" | 5 #include "chrome/browser/ui/webui/settings/site_settings_handler.h" |
6 | 6 |
7 #include <memory> | 7 #include <memory> |
8 #include <string> | 8 #include <string> |
9 #include <utility> | 9 #include <utility> |
10 | 10 |
11 #include "base/bind.h" | 11 #include "base/bind.h" |
12 #include "base/i18n/number_formatting.h" | |
12 #include "base/macros.h" | 13 #include "base/macros.h" |
13 #include "base/values.h" | 14 #include "base/values.h" |
14 #include "chrome/browser/browsing_data/browsing_data_local_storage_helper.h" | 15 #include "chrome/browser/browsing_data/browsing_data_local_storage_helper.h" |
15 #include "chrome/browser/chrome_notification_types.h" | 16 #include "chrome/browser/chrome_notification_types.h" |
16 #include "chrome/browser/content_settings/host_content_settings_map_factory.h" | 17 #include "chrome/browser/content_settings/host_content_settings_map_factory.h" |
17 #include "chrome/browser/permissions/chooser_context_base.h" | 18 #include "chrome/browser/permissions/chooser_context_base.h" |
18 #include "chrome/browser/profiles/profile.h" | 19 #include "chrome/browser/profiles/profile.h" |
19 #include "chrome/browser/ui/webui/site_settings_helper.h" | 20 #include "chrome/browser/ui/webui/site_settings_helper.h" |
20 #include "chrome/common/extensions/manifest_handlers/app_launch_info.h" | 21 #include "chrome/common/extensions/manifest_handlers/app_launch_info.h" |
22 #include "chrome/grit/generated_resources.h" | |
21 #include "components/content_settings/core/browser/host_content_settings_map.h" | 23 #include "components/content_settings/core/browser/host_content_settings_map.h" |
22 #include "components/content_settings/core/common/content_settings_types.h" | 24 #include "components/content_settings/core/common/content_settings_types.h" |
23 #include "content/public/browser/browser_thread.h" | 25 #include "content/public/browser/browser_thread.h" |
24 #include "content/public/browser/notification_service.h" | 26 #include "content/public/browser/notification_service.h" |
25 #include "content/public/browser/web_ui.h" | 27 #include "content/public/browser/web_ui.h" |
28 #include "content/public/common/page_zoom.h" | |
29 #include "content/public/common/url_constants.h" | |
26 #include "extensions/browser/extension_registry.h" | 30 #include "extensions/browser/extension_registry.h" |
27 #include "extensions/common/permissions/api_permission.h" | 31 #include "extensions/common/permissions/api_permission.h" |
28 #include "extensions/common/permissions/permissions_data.h" | 32 #include "extensions/common/permissions/permissions_data.h" |
29 #include "storage/browser/quota/quota_manager.h" | 33 #include "storage/browser/quota/quota_manager.h" |
30 #include "storage/common/quota/quota_status_code.h" | 34 #include "storage/common/quota/quota_status_code.h" |
35 #include "ui/base/l10n/l10n_util.h" | |
31 #include "ui/base/text/bytes_formatting.h" | 36 #include "ui/base/text/bytes_formatting.h" |
32 | 37 |
33 namespace settings { | 38 namespace settings { |
34 | 39 |
35 namespace { | 40 namespace { |
36 | 41 |
37 const char kAppName[] = "appName"; | 42 const char kAppName[] = "appName"; |
38 const char kAppId[] = "appId"; | 43 const char kAppId[] = "appId"; |
44 const char kZoom[] = "zoom"; | |
39 | 45 |
40 // Return an appropriate API Permission ID for the given string name. | 46 // Return an appropriate API Permission ID for the given string name. |
41 extensions::APIPermission::APIPermission::ID APIPermissionFromGroupName( | 47 extensions::APIPermission::APIPermission::ID APIPermissionFromGroupName( |
42 std::string type) { | 48 std::string type) { |
43 // Once there are more than two groups to consider, this should be changed to | 49 // Once there are more than two groups to consider, this should be changed to |
44 // something better than if's. | 50 // something better than if's. |
45 | 51 |
46 if (site_settings::ContentSettingsTypeFromGroupName(type) == | 52 if (site_settings::ContentSettingsTypeFromGroupName(type) == |
47 CONTENT_SETTINGS_TYPE_GEOLOCATION) | 53 CONTENT_SETTINGS_TYPE_GEOLOCATION) |
48 return extensions::APIPermission::APIPermission::kGeolocation; | 54 return extensions::APIPermission::APIPermission::kGeolocation; |
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
151 base::Bind(&SiteSettingsHandler::HandleSetCategoryPermissionForOrigin, | 157 base::Bind(&SiteSettingsHandler::HandleSetCategoryPermissionForOrigin, |
152 base::Unretained(this))); | 158 base::Unretained(this))); |
153 web_ui()->RegisterMessageCallback( | 159 web_ui()->RegisterMessageCallback( |
154 "isPatternValid", | 160 "isPatternValid", |
155 base::Bind(&SiteSettingsHandler::HandleIsPatternValid, | 161 base::Bind(&SiteSettingsHandler::HandleIsPatternValid, |
156 base::Unretained(this))); | 162 base::Unretained(this))); |
157 web_ui()->RegisterMessageCallback( | 163 web_ui()->RegisterMessageCallback( |
158 "updateIncognitoStatus", | 164 "updateIncognitoStatus", |
159 base::Bind(&SiteSettingsHandler::HandleUpdateIncognitoStatus, | 165 base::Bind(&SiteSettingsHandler::HandleUpdateIncognitoStatus, |
160 base::Unretained(this))); | 166 base::Unretained(this))); |
167 web_ui()->RegisterMessageCallback( | |
168 "fetchZoomLevels", | |
169 base::Bind(&SiteSettingsHandler::HandleFetchZoomLevels, | |
170 base::Unretained(this))); | |
171 web_ui()->RegisterMessageCallback( | |
172 "removeZoomLevel", | |
173 base::Bind(&SiteSettingsHandler::HandleRemoveZoomLevel, | |
174 base::Unretained(this))); | |
161 } | 175 } |
162 | 176 |
163 void SiteSettingsHandler::OnJavascriptAllowed() { | 177 void SiteSettingsHandler::OnJavascriptAllowed() { |
164 observer_.Add(HostContentSettingsMapFactory::GetForProfile(profile_)); | 178 observer_.Add(HostContentSettingsMapFactory::GetForProfile(profile_)); |
165 if (profile_->HasOffTheRecordProfile()) { | 179 if (profile_->HasOffTheRecordProfile()) { |
166 auto* map = HostContentSettingsMapFactory::GetForProfile( | 180 auto* map = HostContentSettingsMapFactory::GetForProfile( |
167 profile_->GetOffTheRecordProfile()); | 181 profile_->GetOffTheRecordProfile()); |
168 if (!observer_.IsObserving(map)) | 182 if (!observer_.IsObserving(map)) |
169 observer_.Add(map); | 183 observer_.Add(map); |
170 } | 184 } |
171 | 185 |
172 notification_registrar_.Add( | 186 notification_registrar_.Add( |
173 this, chrome::NOTIFICATION_PROFILE_CREATED, | 187 this, chrome::NOTIFICATION_PROFILE_CREATED, |
174 content::NotificationService::AllSources()); | 188 content::NotificationService::AllSources()); |
175 notification_registrar_.Add( | 189 notification_registrar_.Add( |
176 this, chrome::NOTIFICATION_PROFILE_DESTROYED, | 190 this, chrome::NOTIFICATION_PROFILE_DESTROYED, |
177 content::NotificationService::AllSources()); | 191 content::NotificationService::AllSources()); |
192 | |
193 // Here we only subscribe to the HostZoomMap for the default storage partition | |
194 // since we don't allow the user to manage the zoom levels for apps. | |
195 // We're only interested in zoom-levels that are persisted, since the user | |
196 // is given the opportunity to view/delete these in the content-settings page. | |
197 host_zoom_map_subscription_ = | |
198 content::HostZoomMap::GetDefaultForBrowserContext(profile_) | |
199 ->AddZoomLevelChangedCallback( | |
200 base::Bind(&SiteSettingsHandler::OnZoomLevelChanged, | |
201 base::Unretained(this))); | |
178 } | 202 } |
179 | 203 |
180 void SiteSettingsHandler::OnJavascriptDisallowed() { | 204 void SiteSettingsHandler::OnJavascriptDisallowed() { |
181 observer_.RemoveAll(); | 205 observer_.RemoveAll(); |
182 notification_registrar_.RemoveAll(); | 206 notification_registrar_.RemoveAll(); |
207 host_zoom_map_subscription_.reset(); | |
183 } | 208 } |
184 | 209 |
185 void SiteSettingsHandler::OnGetUsageInfo( | 210 void SiteSettingsHandler::OnGetUsageInfo( |
186 const storage::UsageInfoEntries& entries) { | 211 const storage::UsageInfoEntries& entries) { |
187 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 212 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
188 | 213 |
189 for (const auto& entry : entries) { | 214 for (const auto& entry : entries) { |
190 if (entry.usage <= 0) continue; | 215 if (entry.usage <= 0) continue; |
191 if (entry.host == usage_host_) { | 216 if (entry.host == usage_host_) { |
192 CallJavascriptFunction("settings.WebsiteUsagePrivateApi.returnUsageTotal", | 217 CallJavascriptFunction("settings.WebsiteUsagePrivateApi.returnUsageTotal", |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
258 if (!profile_->IsSameProfile(profile)) | 283 if (!profile_->IsSameProfile(profile)) |
259 break; | 284 break; |
260 SendIncognitoStatus(profile, /*was_destroyed=*/ false); | 285 SendIncognitoStatus(profile, /*was_destroyed=*/ false); |
261 | 286 |
262 observer_.Add(HostContentSettingsMapFactory::GetForProfile(profile)); | 287 observer_.Add(HostContentSettingsMapFactory::GetForProfile(profile)); |
263 break; | 288 break; |
264 } | 289 } |
265 } | 290 } |
266 } | 291 } |
267 | 292 |
293 void SiteSettingsHandler::OnZoomLevelChanged( | |
294 const content::HostZoomMap::ZoomLevelChange& change) { | |
295 SendZoomLevels(); | |
296 } | |
297 | |
268 void SiteSettingsHandler::HandleFetchUsageTotal( | 298 void SiteSettingsHandler::HandleFetchUsageTotal( |
269 const base::ListValue* args) { | 299 const base::ListValue* args) { |
270 AllowJavascript(); | 300 AllowJavascript(); |
271 | 301 |
272 CHECK_EQ(1U, args->GetSize()); | 302 CHECK_EQ(1U, args->GetSize()); |
273 std::string host; | 303 std::string host; |
274 CHECK(args->GetString(0, &host)); | 304 CHECK(args->GetString(0, &host)); |
275 usage_host_ = host; | 305 usage_host_ = host; |
276 | 306 |
277 scoped_refptr<StorageInfoFetcher> storage_info_fetcher | 307 scoped_refptr<StorageInfoFetcher> storage_info_fetcher |
(...skipping 243 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
521 // message before destroying, so HasOffTheRecordProfile for profile_ won't | 551 // message before destroying, so HasOffTheRecordProfile for profile_ won't |
522 // return false until after the profile actually been destroyed. | 552 // return false until after the profile actually been destroyed. |
523 bool incognito_enabled = profile_->HasOffTheRecordProfile() && | 553 bool incognito_enabled = profile_->HasOffTheRecordProfile() && |
524 !(was_destroyed && profile == profile_->GetOffTheRecordProfile()); | 554 !(was_destroyed && profile == profile_->GetOffTheRecordProfile()); |
525 | 555 |
526 CallJavascriptFunction("cr.webUIListenerCallback", | 556 CallJavascriptFunction("cr.webUIListenerCallback", |
527 base::StringValue("onIncognitoStatusChanged"), | 557 base::StringValue("onIncognitoStatusChanged"), |
528 base::FundamentalValue(incognito_enabled)); | 558 base::FundamentalValue(incognito_enabled)); |
529 } | 559 } |
530 | 560 |
561 void SiteSettingsHandler::HandleFetchZoomLevels(const base::ListValue* args) { | |
562 AllowJavascript(); | |
563 SendZoomLevels(); | |
564 } | |
565 | |
566 void SiteSettingsHandler::SendZoomLevels() { | |
567 if (!IsJavascriptAllowed()) | |
568 return; | |
569 | |
570 base::ListValue zoom_levels_exceptions; | |
571 | |
572 content::HostZoomMap* host_zoom_map = | |
573 content::HostZoomMap::GetDefaultForBrowserContext(profile_); | |
574 content::HostZoomMap::ZoomLevelVector zoom_levels( | |
575 host_zoom_map->GetAllZoomLevels()); | |
576 | |
577 // Sort ZoomLevelChanges by host and scheme | |
578 // (a.com < http://a.com < https://a.com < b.com). | |
579 std::sort(zoom_levels.begin(), zoom_levels.end(), | |
580 [](const content::HostZoomMap::ZoomLevelChange& a, | |
581 const content::HostZoomMap::ZoomLevelChange& b) { | |
582 return a.host == b.host ? a.scheme < b.scheme : a.host < b.host; | |
583 }); | |
584 | |
585 for (content::HostZoomMap::ZoomLevelVector::const_iterator i = | |
586 zoom_levels.begin(); | |
587 i != zoom_levels.end(); | |
588 ++i) { | |
589 std::unique_ptr<base::DictionaryValue> exception(new base::DictionaryValue); | |
590 switch (i->mode) { | |
591 case content::HostZoomMap::ZOOM_CHANGED_FOR_HOST: { | |
592 exception->SetString(site_settings::kOrigin, i->host); | |
593 std::string host = i->host; | |
dschuyler
2016/09/08 22:14:32
nit: the two lines above could be swapped and the
Finnur
2016/09/09 09:56:18
This was copied verbatim from content_settings_han
| |
594 if (host == content::kUnreachableWebDataURL) { | |
595 host = | |
596 l10n_util::GetStringUTF8(IDS_ZOOMLEVELS_CHROME_ERROR_PAGES_LABEL); | |
597 } | |
598 exception->SetString(site_settings::kOrigin, host); | |
599 break; | |
600 } | |
601 case content::HostZoomMap::ZOOM_CHANGED_FOR_SCHEME_AND_HOST: | |
602 // These are not stored in preferences and get cleared on next browser | |
603 // start. Therefore, we don't care for them. | |
604 continue; | |
605 case content::HostZoomMap::PAGE_SCALE_IS_ONE_CHANGED: | |
606 continue; | |
607 case content::HostZoomMap::ZOOM_CHANGED_TEMPORARY_ZOOM: | |
608 NOTREACHED(); | |
609 } | |
610 | |
611 std::string setting_string = | |
612 content_settings::ContentSettingToString(CONTENT_SETTING_DEFAULT); | |
613 DCHECK(!setting_string.empty()); | |
614 | |
615 exception->SetString(site_settings::kSetting, setting_string); | |
616 | |
617 // Calculate the zoom percent from the factor. Round up to the nearest whole | |
618 // number. | |
619 int zoom_percent = static_cast<int>( | |
620 content::ZoomLevelToZoomFactor(i->zoom_level) * 100 + 0.5); | |
621 exception->SetString(kZoom, base::FormatPercent(zoom_percent)); | |
622 exception->SetString( | |
623 site_settings::kSource, site_settings::kPreferencesSource); | |
624 // Append the new entry to the list and map. | |
625 zoom_levels_exceptions.Append(std::move(exception)); | |
626 } | |
627 | |
628 CallJavascriptFunction("cr.webUIListenerCallback", | |
629 base::StringValue("onZoomLevelsChanged"), | |
630 zoom_levels_exceptions); | |
631 } | |
632 | |
633 void SiteSettingsHandler::HandleRemoveZoomLevel(const base::ListValue* args) { | |
634 CHECK_EQ(1U, args->GetSize()); | |
635 | |
636 std::string origin; | |
637 CHECK(args->GetString(0, &origin)); | |
638 | |
639 if (origin == | |
640 l10n_util::GetStringUTF8(IDS_ZOOMLEVELS_CHROME_ERROR_PAGES_LABEL)) { | |
641 origin = content::kUnreachableWebDataURL; | |
642 } | |
643 | |
644 content::HostZoomMap* host_zoom_map; | |
645 host_zoom_map = content::HostZoomMap::GetDefaultForBrowserContext(profile_); | |
646 double default_level = host_zoom_map->GetDefaultZoomLevel(); | |
647 host_zoom_map->SetZoomLevelForHost(origin, default_level); | |
648 } | |
649 | |
531 } // namespace settings | 650 } // namespace settings |
OLD | NEW |