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/site_settings_helper.h" | 5 #include "chrome/browser/ui/webui/site_settings_helper.h" |
| 6 | 6 |
| 7 #include "base/memory/ptr_util.h" | 7 #include "base/memory/ptr_util.h" |
| 8 #include "base/values.h" | 8 #include "base/values.h" |
| 9 #include "chrome/browser/permissions/chooser_context_base.h" | |
| 9 #include "chrome/browser/profiles/profile.h" | 10 #include "chrome/browser/profiles/profile.h" |
| 11 #include "chrome/browser/usb/usb_chooser_context_factory.h" | |
| 10 #include "chrome/common/pref_names.h" | 12 #include "chrome/common/pref_names.h" |
| 11 #include "components/content_settings/core/browser/host_content_settings_map.h" | 13 #include "components/content_settings/core/browser/host_content_settings_map.h" |
| 12 #include "components/prefs/pref_service.h" | 14 #include "components/prefs/pref_service.h" |
| 13 | 15 |
| 14 namespace site_settings { | 16 namespace site_settings { |
| 15 | 17 |
| 16 const char kSetting[] = "setting"; | 18 const char kSetting[] = "setting"; |
| 17 const char kOrigin[] = "origin"; | 19 const char kOrigin[] = "origin"; |
| 18 const char kPolicyProviderId[] = "policy"; | 20 const char kPolicyProviderId[] = "policy"; |
| 19 const char kSource[] = "source"; | 21 const char kSource[] = "source"; |
| 20 const char kEmbeddingOrigin[] = "embeddingOrigin"; | 22 const char kEmbeddingOrigin[] = "embeddingOrigin"; |
| 21 const char kPreferencesSource[] = "preference"; | 23 const char kPreferencesSource[] = "preference"; |
| 24 const char kObject[] = "object"; | |
| 25 const char kObjectName[] = "objectName"; | |
| 22 | 26 |
| 23 struct ContentSettingsTypeNameEntry { | 27 const char kGroupTypeUsb[] = "usb-devices"; |
| 24 ContentSettingsType type; | |
| 25 const char* name; | |
| 26 }; | |
| 27 | 28 |
| 28 const ContentSettingsTypeNameEntry kContentSettingsTypeGroupNames[] = { | 29 ChooserContextBase* GetUsbChooserContext(Profile* profile) { |
| 29 {CONTENT_SETTINGS_TYPE_COOKIES, "cookies"}, | 30 return reinterpret_cast<ChooserContextBase*>( |
| 30 {CONTENT_SETTINGS_TYPE_IMAGES, "images"}, | 31 UsbChooserContextFactory::GetForProfile(profile)); |
| 31 {CONTENT_SETTINGS_TYPE_JAVASCRIPT, "javascript"}, | 32 } |
| 32 {CONTENT_SETTINGS_TYPE_PLUGINS, "plugins"}, | 33 |
| 33 {CONTENT_SETTINGS_TYPE_POPUPS, "popups"}, | 34 namespace { |
| 34 {CONTENT_SETTINGS_TYPE_GEOLOCATION, "location"}, | 35 |
| 35 {CONTENT_SETTINGS_TYPE_NOTIFICATIONS, "notifications"}, | 36 // Maps from the UI string to the object it represents (for sorting purposes). |
| 36 {CONTENT_SETTINGS_TYPE_AUTO_SELECT_CERTIFICATE, "auto-select-certificate"}, | 37 typedef std::multimap<std::string, const base::DictionaryValue*> SortedObjects; |
| 37 {CONTENT_SETTINGS_TYPE_FULLSCREEN, "fullscreen"}, | 38 // Maps from a secondary URL to the set of objects it has permission to access. |
| 38 {CONTENT_SETTINGS_TYPE_MOUSELOCK, "mouselock"}, | 39 typedef std::map<GURL, SortedObjects> OneOriginObjects; |
| 39 {CONTENT_SETTINGS_TYPE_PROTOCOL_HANDLERS, "register-protocol-handler"}, | 40 // Maps from a primary URL/source pair to a OneOriginObjects. All the mappings |
| 40 {CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC, "media-stream-mic"}, | 41 // in OneOriginObjects share the given primary URL and source. |
| 41 {CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA, "media-stream-camera"}, | 42 typedef std::map<std::pair<GURL, std::string>, OneOriginObjects> |
| 42 {CONTENT_SETTINGS_TYPE_PPAPI_BROKER, "ppapi-broker"}, | 43 AllOriginObjects; |
|
dschuyler
2016/08/12 20:58:49
Optional: I'd find it easier to read if there were
Finnur
2016/08/15 11:54:33
Agreed.
| |
| 43 {CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS, "multiple-automatic-downloads"}, | 44 |
| 44 {CONTENT_SETTINGS_TYPE_MIDI_SYSEX, "midi-sysex"}, | 45 } // namespace |
| 45 {CONTENT_SETTINGS_TYPE_SSL_CERT_DECISIONS, "ssl-cert-decisions"}, | |
| 46 #if defined(OS_CHROMEOS) | |
| 47 {CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER, "protectedContent"}, | |
| 48 #endif | |
| 49 {CONTENT_SETTINGS_TYPE_KEYGEN, "keygen"}, | |
| 50 {CONTENT_SETTINGS_TYPE_BACKGROUND_SYNC, "background-sync"}, | |
| 51 }; | |
| 52 | 46 |
| 53 bool HasRegisteredGroupName(ContentSettingsType type) { | 47 bool HasRegisteredGroupName(ContentSettingsType type) { |
| 54 for (size_t i = 0; i < arraysize(kContentSettingsTypeGroupNames); ++i) { | 48 for (size_t i = 0; i < arraysize(kContentSettingsTypeGroupNames); ++i) { |
| 55 if (type == kContentSettingsTypeGroupNames[i].type) | 49 if (type == kContentSettingsTypeGroupNames[i].type) |
| 56 return true; | 50 return true; |
| 57 } | 51 } |
| 58 return false; | 52 return false; |
| 59 } | 53 } |
| 60 | 54 |
| 61 ContentSettingsType ContentSettingsTypeFromGroupName(const std::string& name) { | 55 ContentSettingsType ContentSettingsTypeFromGroupName(const std::string& name) { |
| (...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 225 std::sort( | 219 std::sort( |
| 226 patterns.begin(), patterns.end(), std::greater<ContentSettingsPattern>()); | 220 patterns.begin(), patterns.end(), std::greater<ContentSettingsPattern>()); |
| 227 | 221 |
| 228 for (const ContentSettingsPattern& pattern : patterns) { | 222 for (const ContentSettingsPattern& pattern : patterns) { |
| 229 exceptions->push_back(GetExceptionForPage(pattern, ContentSettingsPattern(), | 223 exceptions->push_back(GetExceptionForPage(pattern, ContentSettingsPattern(), |
| 230 CONTENT_SETTING_ALLOW, | 224 CONTENT_SETTING_ALLOW, |
| 231 kPolicyProviderId)); | 225 kPolicyProviderId)); |
| 232 } | 226 } |
| 233 } | 227 } |
| 234 | 228 |
| 229 const ChooserTypeNameEntry* ChooserTypeFromGroupName(const std::string& name) { | |
| 230 for (const auto& chooser_type : kChooserTypeGroupNames) { | |
| 231 if (chooser_type.name == name) | |
| 232 return &chooser_type; | |
| 233 } | |
| 234 return nullptr; | |
| 235 } | |
| 236 | |
| 237 // Create a DictionaryValue* that will act as a data source for a single row | |
| 238 // in a chooser permission exceptions table. | |
| 239 std::unique_ptr<base::DictionaryValue> GetChooserExceptionForPage( | |
| 240 const GURL& requesting_origin, | |
| 241 const GURL& embedding_origin, | |
| 242 const std::string& provider_name, | |
| 243 const std::string& name, | |
| 244 const base::DictionaryValue* object) { | |
| 245 std::unique_ptr<base::DictionaryValue> exception(new base::DictionaryValue()); | |
| 246 | |
| 247 std::string setting_string = | |
| 248 content_settings::ContentSettingToString(CONTENT_SETTING_DEFAULT); | |
| 249 DCHECK(!setting_string.empty()); | |
| 250 | |
| 251 exception->SetString(site_settings::kSetting, setting_string); | |
| 252 exception->SetString(site_settings::kOrigin, requesting_origin.spec()); | |
| 253 exception->SetString( | |
| 254 site_settings::kEmbeddingOrigin, embedding_origin.spec()); | |
| 255 exception->SetString(site_settings::kSource, provider_name); | |
| 256 if (object) { | |
| 257 exception->SetString(kObjectName, name); | |
| 258 exception->Set(kObject, object->CreateDeepCopy()); | |
| 259 } | |
| 260 return exception; | |
| 261 } | |
| 262 | |
| 263 void GetChooserExceptionsFromProfile( | |
| 264 Profile* profile, | |
| 265 bool incognito, | |
| 266 const ChooserTypeNameEntry& chooser_type, | |
| 267 base::ListValue* exceptions) { | |
| 268 if (incognito) { | |
| 269 if (profile->HasOffTheRecordProfile()) | |
| 270 profile = profile->GetOffTheRecordProfile(); | |
| 271 else | |
| 272 return; | |
| 273 } | |
| 274 | |
| 275 ChooserContextBase* chooser_context = chooser_type.get_context(profile); | |
| 276 std::vector<std::unique_ptr<ChooserContextBase::Object>> objects = | |
| 277 chooser_context->GetAllGrantedObjects(); | |
| 278 AllOriginObjects all_origin_objects; | |
| 279 for (const auto& object : objects) { | |
| 280 std::string name; | |
| 281 bool found = object->object.GetString(chooser_type.ui_name_key, &name); | |
| 282 DCHECK(found); | |
| 283 // It is safe for this structure to hold references into |objects| because | |
| 284 // they are both destroyed at the end of this function. | |
| 285 all_origin_objects[make_pair(object->requesting_origin, | |
| 286 object->source)][object->embedding_origin] | |
| 287 .insert(make_pair(name, &object->object)); | |
| 288 } | |
| 289 | |
| 290 // Keep the exceptions sorted by provider so they will be displayed in | |
| 291 // precedence order. | |
| 292 std::vector<std::unique_ptr<base::DictionaryValue>> | |
| 293 all_provider_exceptions[HostContentSettingsMap::NUM_PROVIDER_TYPES]; | |
| 294 | |
| 295 for (const auto& all_origin_objects_entry : all_origin_objects) { | |
| 296 const GURL& requesting_origin = all_origin_objects_entry.first.first; | |
| 297 const std::string& source = all_origin_objects_entry.first.second; | |
| 298 const OneOriginObjects& one_origin_objects = | |
| 299 all_origin_objects_entry.second; | |
| 300 | |
| 301 auto& this_provider_exceptions = all_provider_exceptions | |
| 302 [HostContentSettingsMap::GetProviderTypeFromSource(source)]; | |
| 303 | |
| 304 // Add entries for any non-embedded origins. | |
| 305 bool has_embedded_entries = false; | |
| 306 for (const auto& one_origin_objects_entry : one_origin_objects) { | |
| 307 const GURL& embedding_origin = one_origin_objects_entry.first; | |
| 308 const SortedObjects& sorted_objects = one_origin_objects_entry.second; | |
| 309 | |
| 310 // Skip the embedded settings which will be added below. | |
| 311 if (requesting_origin != embedding_origin) { | |
| 312 has_embedded_entries = true; | |
| 313 continue; | |
| 314 } | |
| 315 | |
| 316 for (const auto& sorted_objects_entry : sorted_objects) { | |
| 317 this_provider_exceptions.push_back(GetChooserExceptionForPage( | |
| 318 requesting_origin, embedding_origin, source, | |
| 319 sorted_objects_entry.first, sorted_objects_entry.second)); | |
| 320 } | |
| 321 } | |
| 322 | |
| 323 if (has_embedded_entries) { | |
| 324 // Add a "parent" entry that simply acts as a heading for all entries | |
| 325 // where |requesting_origin| has been embedded. | |
| 326 this_provider_exceptions.push_back( | |
| 327 GetChooserExceptionForPage(requesting_origin, requesting_origin, | |
| 328 source, std::string(), nullptr)); | |
| 329 | |
| 330 // Add the "children" for any embedded settings. | |
| 331 for (const auto& one_origin_objects_entry : one_origin_objects) { | |
| 332 const GURL& embedding_origin = one_origin_objects_entry.first; | |
| 333 const SortedObjects& sorted_objects = one_origin_objects_entry.second; | |
| 334 | |
| 335 // Skip the non-embedded setting which we already added above. | |
| 336 if (requesting_origin == embedding_origin) | |
| 337 continue; | |
| 338 | |
| 339 for (const auto& sorted_objects_entry : sorted_objects) { | |
| 340 this_provider_exceptions.push_back(GetChooserExceptionForPage( | |
| 341 requesting_origin, embedding_origin, source, | |
| 342 sorted_objects_entry.first, sorted_objects_entry.second)); | |
| 343 } | |
| 344 } | |
| 345 } | |
| 346 } | |
| 347 | |
| 348 for (auto& one_provider_exceptions : all_provider_exceptions) { | |
| 349 for (auto& exception : one_provider_exceptions) | |
| 350 exceptions->Append(std::move(exception)); | |
| 351 } | |
| 352 } | |
| 353 | |
| 235 } // namespace site_settings | 354 } // namespace site_settings |
| OLD | NEW |