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/macros.h" | 12 #include "base/macros.h" |
| 13 #include "base/values.h" | 13 #include "base/values.h" |
| 14 #include "chrome/browser/browsing_data/browsing_data_local_storage_helper.h" | 14 #include "chrome/browser/browsing_data/browsing_data_local_storage_helper.h" |
| 15 #include "chrome/browser/chrome_notification_types.h" | |
| 15 #include "chrome/browser/content_settings/host_content_settings_map_factory.h" | 16 #include "chrome/browser/content_settings/host_content_settings_map_factory.h" |
| 16 #include "chrome/browser/permissions/chooser_context_base.h" | 17 #include "chrome/browser/permissions/chooser_context_base.h" |
| 17 #include "chrome/browser/profiles/profile.h" | 18 #include "chrome/browser/profiles/profile.h" |
| 18 #include "chrome/browser/ui/webui/site_settings_helper.h" | 19 #include "chrome/browser/ui/webui/site_settings_helper.h" |
| 19 #include "chrome/common/extensions/manifest_handlers/app_launch_info.h" | 20 #include "chrome/common/extensions/manifest_handlers/app_launch_info.h" |
| 20 #include "components/content_settings/core/browser/host_content_settings_map.h" | 21 #include "components/content_settings/core/browser/host_content_settings_map.h" |
| 21 #include "components/content_settings/core/common/content_settings_types.h" | 22 #include "components/content_settings/core/common/content_settings_types.h" |
| 22 #include "content/public/browser/browser_thread.h" | 23 #include "content/public/browser/browser_thread.h" |
| 24 #include "content/public/browser/notification_service.h" | |
| 23 #include "content/public/browser/web_ui.h" | 25 #include "content/public/browser/web_ui.h" |
| 24 #include "extensions/browser/extension_registry.h" | 26 #include "extensions/browser/extension_registry.h" |
| 25 #include "extensions/common/permissions/api_permission.h" | 27 #include "extensions/common/permissions/api_permission.h" |
| 26 #include "extensions/common/permissions/permissions_data.h" | 28 #include "extensions/common/permissions/permissions_data.h" |
| 27 #include "storage/browser/quota/quota_manager.h" | 29 #include "storage/browser/quota/quota_manager.h" |
| 28 #include "storage/common/quota/quota_status_code.h" | 30 #include "storage/common/quota/quota_status_code.h" |
| 29 #include "ui/base/text/bytes_formatting.h" | 31 #include "ui/base/text/bytes_formatting.h" |
| 30 | 32 |
| 31 | |
| 32 namespace settings { | 33 namespace settings { |
| 33 | 34 |
| 34 namespace { | 35 namespace { |
| 35 | 36 |
| 36 const char kAppName[] = "appName"; | 37 const char kAppName[] = "appName"; |
| 37 const char kAppId[] = "appId"; | 38 const char kAppId[] = "appId"; |
| 38 | 39 |
| 39 // Return an appropriate API Permission ID for the given string name. | 40 // Return an appropriate API Permission ID for the given string name. |
| 40 extensions::APIPermission::APIPermission::ID APIPermissionFromGroupName( | 41 extensions::APIPermission::APIPermission::ID APIPermissionFromGroupName( |
| 41 std::string type) { | 42 std::string type) { |
| (...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 146 base::Bind(&SiteSettingsHandler::HandleResetCategoryPermissionForOrigin, | 147 base::Bind(&SiteSettingsHandler::HandleResetCategoryPermissionForOrigin, |
| 147 base::Unretained(this))); | 148 base::Unretained(this))); |
| 148 web_ui()->RegisterMessageCallback( | 149 web_ui()->RegisterMessageCallback( |
| 149 "setCategoryPermissionForOrigin", | 150 "setCategoryPermissionForOrigin", |
| 150 base::Bind(&SiteSettingsHandler::HandleSetCategoryPermissionForOrigin, | 151 base::Bind(&SiteSettingsHandler::HandleSetCategoryPermissionForOrigin, |
| 151 base::Unretained(this))); | 152 base::Unretained(this))); |
| 152 web_ui()->RegisterMessageCallback( | 153 web_ui()->RegisterMessageCallback( |
| 153 "isPatternValid", | 154 "isPatternValid", |
| 154 base::Bind(&SiteSettingsHandler::HandleIsPatternValid, | 155 base::Bind(&SiteSettingsHandler::HandleIsPatternValid, |
| 155 base::Unretained(this))); | 156 base::Unretained(this))); |
| 157 web_ui()->RegisterMessageCallback( | |
| 158 "updateIncognitoStatus", | |
| 159 base::Bind(&SiteSettingsHandler::HandleUpdateIncognitoStatus, | |
| 160 base::Unretained(this))); | |
| 156 } | 161 } |
| 157 | 162 |
| 158 void SiteSettingsHandler::OnJavascriptAllowed() { | 163 void SiteSettingsHandler::OnJavascriptAllowed() { |
| 159 observer_.Add(HostContentSettingsMapFactory::GetForProfile(profile_)); | 164 observer_.Add(HostContentSettingsMapFactory::GetForProfile(profile_)); |
| 160 if (profile_->HasOffTheRecordProfile()) { | 165 if (profile_->HasOffTheRecordProfile()) { |
| 161 auto* map = HostContentSettingsMapFactory::GetForProfile( | 166 auto* map = HostContentSettingsMapFactory::GetForProfile( |
| 162 profile_->GetOffTheRecordProfile()); | 167 profile_->GetOffTheRecordProfile()); |
| 163 if (!observer_.IsObserving(map)) | 168 if (!observer_.IsObserving(map)) |
| 164 observer_.Add(map); | 169 observer_.Add(map); |
| 165 } | 170 } |
| 171 | |
| 172 notification_registrar_.Add( | |
| 173 this, chrome::NOTIFICATION_PROFILE_CREATED, | |
| 174 content::NotificationService::AllSources()); | |
| 175 notification_registrar_.Add( | |
| 176 this, chrome::NOTIFICATION_PROFILE_DESTROYED, | |
| 177 content::NotificationService::AllSources()); | |
| 166 } | 178 } |
| 167 | 179 |
| 168 void SiteSettingsHandler::OnJavascriptDisallowed() { | 180 void SiteSettingsHandler::OnJavascriptDisallowed() { |
| 169 observer_.RemoveAll(); | 181 observer_.RemoveAll(); |
|
dschuyler
2016/08/31 21:48:52
Should we do something with notification_registrar
Finnur
2016/09/01 11:10:15
NotificationRegistrar calls RemoveAll in the dtor,
dschuyler
2016/09/01 23:13:49
Ah, please look specifically within
chrome/browse
Finnur
2016/09/02 15:44:14
Acknowledged.
| |
| 170 } | 182 } |
| 171 | 183 |
| 172 void SiteSettingsHandler::OnGetUsageInfo( | 184 void SiteSettingsHandler::OnGetUsageInfo( |
| 173 const storage::UsageInfoEntries& entries) { | 185 const storage::UsageInfoEntries& entries) { |
| 174 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); | 186 DCHECK_CURRENTLY_ON(content::BrowserThread::UI); |
| 175 | 187 |
| 176 for (const auto& entry : entries) { | 188 for (const auto& entry : entries) { |
| 177 if (entry.usage <= 0) continue; | 189 if (entry.usage <= 0) continue; |
| 178 if (entry.host == usage_host_) { | 190 if (entry.host == usage_host_) { |
| 179 CallJavascriptFunction("settings.WebsiteUsagePrivateApi.returnUsageTotal", | 191 CallJavascriptFunction("settings.WebsiteUsagePrivateApi.returnUsageTotal", |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 212 base::StringValue("contentSettingSitePermissionChanged"), | 224 base::StringValue("contentSettingSitePermissionChanged"), |
| 213 base::StringValue(site_settings::ContentSettingsTypeToGroupName( | 225 base::StringValue(site_settings::ContentSettingsTypeToGroupName( |
| 214 content_type)), | 226 content_type)), |
| 215 base::StringValue(primary_pattern.ToString()), | 227 base::StringValue(primary_pattern.ToString()), |
| 216 base::StringValue( | 228 base::StringValue( |
| 217 secondary_pattern == ContentSettingsPattern::Wildcard() ? | 229 secondary_pattern == ContentSettingsPattern::Wildcard() ? |
| 218 "" : secondary_pattern.ToString())); | 230 "" : secondary_pattern.ToString())); |
| 219 } | 231 } |
| 220 } | 232 } |
| 221 | 233 |
| 234 void SiteSettingsHandler::Observe( | |
| 235 int type, | |
| 236 const content::NotificationSource& source, | |
| 237 const content::NotificationDetails& details) { | |
| 238 switch (type) { | |
| 239 case chrome::NOTIFICATION_PROFILE_DESTROYED: { | |
| 240 Profile* profile = content::Source<Profile>(source).ptr(); | |
|
dschuyler
2016/08/31 21:48:52
Just a question (feel free to ignore):
Will we ge
Finnur
2016/09/01 11:10:15
No, it is an excellent question.
| |
| 241 SendIncognitoStatus(true, profile); | |
| 242 | |
| 243 HostContentSettingsMap* settings_map = | |
| 244 HostContentSettingsMapFactory::GetForProfile(profile); | |
| 245 if (profile->IsOffTheRecord() && | |
| 246 observer_.IsObserving(settings_map)) { | |
| 247 observer_.Remove(settings_map); | |
| 248 } | |
| 249 | |
| 250 break; | |
| 251 } | |
| 252 | |
| 253 case chrome::NOTIFICATION_PROFILE_CREATED: { | |
| 254 Profile* profile = content::Source<Profile>(source).ptr(); | |
| 255 SendIncognitoStatus(false, profile); | |
| 256 | |
| 257 observer_.Add(HostContentSettingsMapFactory::GetForProfile(profile)); | |
| 258 break; | |
| 259 } | |
| 260 } | |
| 261 } | |
| 262 | |
| 222 void SiteSettingsHandler::HandleFetchUsageTotal( | 263 void SiteSettingsHandler::HandleFetchUsageTotal( |
| 223 const base::ListValue* args) { | 264 const base::ListValue* args) { |
| 224 AllowJavascript(); | 265 AllowJavascript(); |
| 225 | 266 |
| 226 CHECK_EQ(1U, args->GetSize()); | 267 CHECK_EQ(1U, args->GetSize()); |
| 227 std::string host; | 268 std::string host; |
| 228 CHECK(args->GetString(0, &host)); | 269 CHECK(args->GetString(0, &host)); |
| 229 usage_host_ = host; | 270 usage_host_ = host; |
| 230 | 271 |
| 231 scoped_refptr<StorageInfoFetcher> storage_info_fetcher | 272 scoped_refptr<StorageInfoFetcher> storage_info_fetcher |
| (...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 346 | 387 |
| 347 CHECK_EQ(2U, args->GetSize()); | 388 CHECK_EQ(2U, args->GetSize()); |
| 348 const base::Value* callback_id; | 389 const base::Value* callback_id; |
| 349 CHECK(args->Get(0, &callback_id)); | 390 CHECK(args->Get(0, &callback_id)); |
| 350 std::string type; | 391 std::string type; |
| 351 CHECK(args->GetString(1, &type)); | 392 CHECK(args->GetString(1, &type)); |
| 352 ContentSettingsType content_type = | 393 ContentSettingsType content_type = |
| 353 static_cast<ContentSettingsType>(static_cast<int>( | 394 static_cast<ContentSettingsType>(static_cast<int>( |
| 354 site_settings::ContentSettingsTypeFromGroupName(type))); | 395 site_settings::ContentSettingsTypeFromGroupName(type))); |
| 355 | 396 |
| 397 std::unique_ptr<base::ListValue> exceptions(new base::ListValue); | |
| 398 | |
| 356 HostContentSettingsMap* map = | 399 HostContentSettingsMap* map = |
| 357 HostContentSettingsMapFactory::GetForProfile(profile_); | 400 HostContentSettingsMapFactory::GetForProfile(profile_); |
| 358 std::unique_ptr<base::ListValue> exceptions(new base::ListValue); | |
| 359 | |
| 360 AddExceptionsGrantedByHostedApps(profile_, APIPermissionFromGroupName(type), | 401 AddExceptionsGrantedByHostedApps(profile_, APIPermissionFromGroupName(type), |
| 361 exceptions.get()); | 402 exceptions.get()); |
| 403 site_settings::GetExceptionsFromHostContentSettingsMap( | |
| 404 map, content_type, web_ui(), false, exceptions.get()); | |
| 362 | 405 |
| 363 site_settings::GetExceptionsFromHostContentSettingsMap( | 406 if (profile_->HasOffTheRecordProfile()) { |
| 364 map, content_type, web_ui(), exceptions.get()); | 407 Profile* incognito = profile_->GetOffTheRecordProfile(); |
| 408 map = HostContentSettingsMapFactory::GetForProfile(incognito); | |
| 409 site_settings::GetExceptionsFromHostContentSettingsMap( | |
| 410 map, content_type, web_ui(), true, exceptions.get()); | |
| 411 } | |
| 412 | |
| 365 ResolveJavascriptCallback(*callback_id, *exceptions.get()); | 413 ResolveJavascriptCallback(*callback_id, *exceptions.get()); |
| 366 } | 414 } |
| 367 | 415 |
| 368 void SiteSettingsHandler::HandleResetCategoryPermissionForOrigin( | 416 void SiteSettingsHandler::HandleResetCategoryPermissionForOrigin( |
| 369 const base::ListValue* args) { | 417 const base::ListValue* args) { |
| 370 CHECK_EQ(3U, args->GetSize()); | 418 CHECK_EQ(4U, args->GetSize()); |
| 371 std::string primary_pattern; | 419 std::string primary_pattern; |
| 372 CHECK(args->GetString(0, &primary_pattern)); | 420 CHECK(args->GetString(0, &primary_pattern)); |
| 373 std::string secondary_pattern; | 421 std::string secondary_pattern; |
| 374 CHECK(args->GetString(1, &secondary_pattern)); | 422 CHECK(args->GetString(1, &secondary_pattern)); |
| 375 std::string type; | 423 std::string type; |
| 376 CHECK(args->GetString(2, &type)); | 424 CHECK(args->GetString(2, &type)); |
| 425 bool incognito; | |
| 426 CHECK(args->GetBoolean(3, &incognito)); | |
| 377 | 427 |
| 378 ContentSettingsType content_type = | 428 ContentSettingsType content_type = |
| 379 static_cast<ContentSettingsType>(static_cast<int>( | 429 static_cast<ContentSettingsType>(static_cast<int>( |
| 380 site_settings::ContentSettingsTypeFromGroupName(type))); | 430 site_settings::ContentSettingsTypeFromGroupName(type))); |
| 381 | 431 |
| 432 Profile* profile = incognito ? | |
| 433 (profile_->HasOffTheRecordProfile() | |
| 434 ? profile_->GetOffTheRecordProfile() : nullptr) : profile_; | |
|
dschuyler
2016/08/31 21:48:52
Optional: I'm found this hard to parse and I'm
wo
Finnur
2016/09/01 11:10:15
Done.
| |
| 435 if (!profile) | |
| 436 return; | |
| 437 | |
| 382 HostContentSettingsMap* map = | 438 HostContentSettingsMap* map = |
| 383 HostContentSettingsMapFactory::GetForProfile(profile_); | 439 HostContentSettingsMapFactory::GetForProfile(profile); |
| 384 map->SetContentSettingCustomScope( | 440 map->SetContentSettingCustomScope( |
| 385 ContentSettingsPattern::FromString(primary_pattern), | 441 ContentSettingsPattern::FromString(primary_pattern), |
| 386 secondary_pattern.empty() ? | 442 secondary_pattern.empty() ? |
| 387 ContentSettingsPattern::Wildcard() : | 443 ContentSettingsPattern::Wildcard() : |
| 388 ContentSettingsPattern::FromString(secondary_pattern), | 444 ContentSettingsPattern::FromString(secondary_pattern), |
| 389 content_type, "", CONTENT_SETTING_DEFAULT); | 445 content_type, "", CONTENT_SETTING_DEFAULT); |
| 390 } | 446 } |
| 391 | 447 |
| 392 void SiteSettingsHandler::HandleSetCategoryPermissionForOrigin( | 448 void SiteSettingsHandler::HandleSetCategoryPermissionForOrigin( |
| 393 const base::ListValue* args) { | 449 const base::ListValue* args) { |
| 394 CHECK_EQ(4U, args->GetSize()); | 450 CHECK_EQ(5U, args->GetSize()); |
| 395 std::string primary_pattern; | 451 std::string primary_pattern; |
| 396 CHECK(args->GetString(0, &primary_pattern)); | 452 CHECK(args->GetString(0, &primary_pattern)); |
| 397 std::string secondary_pattern; | 453 std::string secondary_pattern; |
| 398 CHECK(args->GetString(1, &secondary_pattern)); | 454 CHECK(args->GetString(1, &secondary_pattern)); |
| 399 std::string type; | 455 std::string type; |
| 400 CHECK(args->GetString(2, &type)); | 456 CHECK(args->GetString(2, &type)); |
| 401 std::string value; | 457 std::string value; |
| 402 CHECK(args->GetString(3, &value)); | 458 CHECK(args->GetString(3, &value)); |
| 459 bool incognito; | |
| 460 CHECK(args->GetBoolean(4, &incognito)); | |
| 403 | 461 |
| 404 ContentSettingsType content_type = | 462 ContentSettingsType content_type = |
| 405 static_cast<ContentSettingsType>(static_cast<int>( | 463 static_cast<ContentSettingsType>(static_cast<int>( |
| 406 site_settings::ContentSettingsTypeFromGroupName(type))); | 464 site_settings::ContentSettingsTypeFromGroupName(type))); |
| 407 ContentSetting setting; | 465 ContentSetting setting; |
| 408 CHECK(content_settings::ContentSettingFromString(value, &setting)); | 466 CHECK(content_settings::ContentSettingFromString(value, &setting)); |
| 409 | 467 |
| 468 Profile* profile = incognito ? | |
| 469 (profile_->HasOffTheRecordProfile() | |
| 470 ? profile_->GetOffTheRecordProfile() : nullptr) : profile_; | |
|
dschuyler
2016/08/31 21:48:52
If you decide to change the layout of the
ternary
Finnur
2016/09/01 11:10:15
Done.
| |
| 471 if (!profile) | |
| 472 return; | |
| 473 | |
| 410 HostContentSettingsMap* map = | 474 HostContentSettingsMap* map = |
| 411 HostContentSettingsMapFactory::GetForProfile(profile_); | 475 HostContentSettingsMapFactory::GetForProfile(profile); |
| 412 map->SetContentSettingCustomScope( | 476 map->SetContentSettingCustomScope( |
| 413 ContentSettingsPattern::FromString(primary_pattern), | 477 ContentSettingsPattern::FromString(primary_pattern), |
| 414 secondary_pattern.empty() ? | 478 secondary_pattern.empty() ? |
| 415 ContentSettingsPattern::Wildcard() : | 479 ContentSettingsPattern::Wildcard() : |
| 416 ContentSettingsPattern::FromString(secondary_pattern), | 480 ContentSettingsPattern::FromString(secondary_pattern), |
| 417 content_type, "", setting); | 481 content_type, "", setting); |
| 418 } | 482 } |
| 419 | 483 |
| 420 void SiteSettingsHandler::HandleIsPatternValid( | 484 void SiteSettingsHandler::HandleIsPatternValid( |
| 421 const base::ListValue* args) { | 485 const base::ListValue* args) { |
| 422 CHECK_EQ(2U, args->GetSize()); | 486 CHECK_EQ(2U, args->GetSize()); |
| 423 const base::Value* callback_id; | 487 const base::Value* callback_id; |
| 424 CHECK(args->Get(0, &callback_id)); | 488 CHECK(args->Get(0, &callback_id)); |
| 425 std::string pattern_string; | 489 std::string pattern_string; |
| 426 CHECK(args->GetString(1, &pattern_string)); | 490 CHECK(args->GetString(1, &pattern_string)); |
| 427 | 491 |
| 428 ContentSettingsPattern pattern = | 492 ContentSettingsPattern pattern = |
| 429 ContentSettingsPattern::FromString(pattern_string); | 493 ContentSettingsPattern::FromString(pattern_string); |
| 430 ResolveJavascriptCallback( | 494 ResolveJavascriptCallback( |
| 431 *callback_id, base::FundamentalValue(pattern.IsValid())); | 495 *callback_id, base::FundamentalValue(pattern.IsValid())); |
| 432 } | 496 } |
| 433 | 497 |
| 498 void SiteSettingsHandler::HandleUpdateIncognitoStatus( | |
| 499 const base::ListValue* args) { | |
| 500 AllowJavascript(); | |
| 501 SendIncognitoStatus(false, profile_); | |
| 502 } | |
| 503 | |
| 504 bool SiteSettingsHandler::IsOurIncognitoProfile(Profile* profile) { | |
| 505 return profile_->HasOffTheRecordProfile() && | |
| 506 profile == profile_->GetOffTheRecordProfile(); | |
| 507 } | |
| 508 | |
| 509 void SiteSettingsHandler::SendIncognitoStatus(bool destroy, Profile* profile) { | |
| 510 if (!IsJavascriptAllowed()) | |
| 511 return; | |
| 512 | |
| 513 // When an incognito profile is destroyed, it sends out the destruction | |
| 514 // message before destroying, so HasOffTheRecordProfile for profile_ won't | |
| 515 // return false until after the profile actually been destroyed. | |
|
dschuyler
2016/08/31 21:48:52
Thanks for that comment!
Finnur
2016/09/01 11:10:15
No problem. :)
| |
| 516 bool incognito_enabled = profile_->HasOffTheRecordProfile(); | |
| 517 if (incognito_enabled && destroy && | |
| 518 profile == profile_->GetOffTheRecordProfile()) { | |
| 519 incognito_enabled = false; // Our incognito profile was just destroyed. | |
| 520 } | |
| 521 | |
| 522 if (profile == profile_ || IsOurIncognitoProfile(profile)) { | |
| 523 CallJavascriptFunction("cr.webUIListenerCallback", | |
| 524 base::StringValue("onIncognitoStatusChanged"), | |
| 525 base::FundamentalValue(incognito_enabled)); | |
| 526 } | |
| 527 } | |
| 528 | |
| 434 } // namespace settings | 529 } // namespace settings |
| OLD | NEW |