Chromium Code Reviews| 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 |