Chromium Code Reviews| Index: chrome/browser/ui/webui/site_settings_helper.cc |
| diff --git a/chrome/browser/ui/webui/site_settings_helper.cc b/chrome/browser/ui/webui/site_settings_helper.cc |
| index 78adacb8121fb14da6bc69c85970106e3aa43715..bf9e3cade1772f241f2d3e05fe11d31b11aacfc6 100644 |
| --- a/chrome/browser/ui/webui/site_settings_helper.cc |
| +++ b/chrome/browser/ui/webui/site_settings_helper.cc |
| @@ -6,7 +6,9 @@ |
| #include "base/memory/ptr_util.h" |
| #include "base/values.h" |
| +#include "chrome/browser/permissions/chooser_context_base.h" |
| #include "chrome/browser/profiles/profile.h" |
| +#include "chrome/browser/usb/usb_chooser_context_factory.h" |
| #include "chrome/common/pref_names.h" |
| #include "components/content_settings/core/browser/host_content_settings_map.h" |
| #include "components/prefs/pref_service.h" |
| @@ -19,36 +21,30 @@ const char kPolicyProviderId[] = "policy"; |
| const char kSource[] = "source"; |
| const char kEmbeddingOrigin[] = "embeddingOrigin"; |
| const char kPreferencesSource[] = "preference"; |
| +const char kObject[] = "object"; |
| +const char kObjectName[] = "objectName"; |
| -struct ContentSettingsTypeNameEntry { |
| - ContentSettingsType type; |
| - const char* name; |
| -}; |
| - |
| -const ContentSettingsTypeNameEntry kContentSettingsTypeGroupNames[] = { |
| - {CONTENT_SETTINGS_TYPE_COOKIES, "cookies"}, |
| - {CONTENT_SETTINGS_TYPE_IMAGES, "images"}, |
| - {CONTENT_SETTINGS_TYPE_JAVASCRIPT, "javascript"}, |
| - {CONTENT_SETTINGS_TYPE_PLUGINS, "plugins"}, |
| - {CONTENT_SETTINGS_TYPE_POPUPS, "popups"}, |
| - {CONTENT_SETTINGS_TYPE_GEOLOCATION, "location"}, |
| - {CONTENT_SETTINGS_TYPE_NOTIFICATIONS, "notifications"}, |
| - {CONTENT_SETTINGS_TYPE_AUTO_SELECT_CERTIFICATE, "auto-select-certificate"}, |
| - {CONTENT_SETTINGS_TYPE_FULLSCREEN, "fullscreen"}, |
| - {CONTENT_SETTINGS_TYPE_MOUSELOCK, "mouselock"}, |
| - {CONTENT_SETTINGS_TYPE_PROTOCOL_HANDLERS, "register-protocol-handler"}, |
| - {CONTENT_SETTINGS_TYPE_MEDIASTREAM_MIC, "media-stream-mic"}, |
| - {CONTENT_SETTINGS_TYPE_MEDIASTREAM_CAMERA, "media-stream-camera"}, |
| - {CONTENT_SETTINGS_TYPE_PPAPI_BROKER, "ppapi-broker"}, |
| - {CONTENT_SETTINGS_TYPE_AUTOMATIC_DOWNLOADS, "multiple-automatic-downloads"}, |
| - {CONTENT_SETTINGS_TYPE_MIDI_SYSEX, "midi-sysex"}, |
| - {CONTENT_SETTINGS_TYPE_SSL_CERT_DECISIONS, "ssl-cert-decisions"}, |
| -#if defined(OS_CHROMEOS) |
| - {CONTENT_SETTINGS_TYPE_PROTECTED_MEDIA_IDENTIFIER, "protectedContent"}, |
| -#endif |
| - {CONTENT_SETTINGS_TYPE_KEYGEN, "keygen"}, |
| - {CONTENT_SETTINGS_TYPE_BACKGROUND_SYNC, "background-sync"}, |
| -}; |
| +const char kGroupTypeUsb[] = "usb-devices"; |
| + |
| +ChooserContextBase* GetUsbChooserContext(Profile* profile) { |
| + return reinterpret_cast<ChooserContextBase*>( |
| + UsbChooserContextFactory::GetForProfile(profile)); |
| +} |
| + |
| +namespace { |
| + |
| +// Maps from the UI string to the object it represents (for sorting purposes). |
| +typedef std::multimap<std::string, const base::DictionaryValue*> SortedObjects; |
| + |
| +// Maps from a secondary URL to the set of objects it has permission to access. |
| +typedef std::map<GURL, SortedObjects> OneOriginObjects; |
| + |
| +// Maps from a primary URL/source pair to a OneOriginObjects. All the mappings |
| +// in OneOriginObjects share the given primary URL and source. |
| +typedef std::map<std::pair<GURL, std::string>, OneOriginObjects> |
| + AllOriginObjects; |
| + |
| +} // namespace |
| bool HasRegisteredGroupName(ContentSettingsType type) { |
| for (size_t i = 0; i < arraysize(kContentSettingsTypeGroupNames); ++i) { |
| @@ -232,4 +228,129 @@ void GetPolicyAllowedUrls( |
| } |
| } |
| +const ChooserTypeNameEntry* ChooserTypeFromGroupName(const std::string& name) { |
| + for (const auto& chooser_type : kChooserTypeGroupNames) { |
| + if (chooser_type.name == name) |
| + return &chooser_type; |
| + } |
| + return nullptr; |
| +} |
| + |
| +// Create a DictionaryValue* that will act as a data source for a single row |
| +// in a chooser permission exceptions table. |
| +std::unique_ptr<base::DictionaryValue> GetChooserExceptionForPage( |
| + const GURL& requesting_origin, |
| + const GURL& embedding_origin, |
| + const std::string& provider_name, |
| + const std::string& name, |
| + const base::DictionaryValue* object) { |
| + std::unique_ptr<base::DictionaryValue> exception(new base::DictionaryValue()); |
| + |
| + std::string setting_string = |
| + content_settings::ContentSettingToString(CONTENT_SETTING_DEFAULT); |
| + DCHECK(!setting_string.empty()); |
| + |
| + exception->SetString(site_settings::kSetting, setting_string); |
| + exception->SetString(site_settings::kOrigin, requesting_origin.spec()); |
| + exception->SetString( |
| + site_settings::kEmbeddingOrigin, embedding_origin.spec()); |
| + exception->SetString(site_settings::kSource, provider_name); |
| + if (object) { |
| + exception->SetString(kObjectName, name); |
| + exception->Set(kObject, object->CreateDeepCopy()); |
| + } |
| + return exception; |
| +} |
| + |
| +void GetChooserExceptionsFromProfile( |
| + Profile* profile, |
| + bool incognito, |
| + const ChooserTypeNameEntry& chooser_type, |
| + base::ListValue* exceptions) { |
| + if (incognito) { |
| + if (profile->HasOffTheRecordProfile()) |
|
Bernhard Bauer
2016/08/15 14:14:54
Invert the condition and return early?
Finnur
2016/08/16 10:13:55
Done.
|
| + profile = profile->GetOffTheRecordProfile(); |
| + else |
| + return; |
| + } |
| + |
| + ChooserContextBase* chooser_context = chooser_type.get_context(profile); |
| + std::vector<std::unique_ptr<ChooserContextBase::Object>> objects = |
| + chooser_context->GetAllGrantedObjects(); |
| + AllOriginObjects all_origin_objects; |
| + for (const auto& object : objects) { |
| + std::string name; |
| + bool found = object->object.GetString(chooser_type.ui_name_key, &name); |
| + DCHECK(found); |
| + // It is safe for this structure to hold references into |objects| because |
| + // they are both destroyed at the end of this function. |
| + all_origin_objects[make_pair(object->requesting_origin, |
| + object->source)][object->embedding_origin] |
| + .insert(make_pair(name, &object->object)); |
| + } |
| + |
| + // Keep the exceptions sorted by provider so they will be displayed in |
| + // precedence order. |
| + std::vector<std::unique_ptr<base::DictionaryValue>> |
| + all_provider_exceptions[HostContentSettingsMap::NUM_PROVIDER_TYPES]; |
| + |
| + for (const auto& all_origin_objects_entry : all_origin_objects) { |
| + const GURL& requesting_origin = all_origin_objects_entry.first.first; |
| + const std::string& source = all_origin_objects_entry.first.second; |
| + const OneOriginObjects& one_origin_objects = |
| + all_origin_objects_entry.second; |
| + |
| + auto& this_provider_exceptions = all_provider_exceptions |
| + [HostContentSettingsMap::GetProviderTypeFromSource(source)]; |
| + |
| + // Add entries for any non-embedded origins. |
| + bool has_embedded_entries = false; |
| + for (const auto& one_origin_objects_entry : one_origin_objects) { |
| + const GURL& embedding_origin = one_origin_objects_entry.first; |
| + const SortedObjects& sorted_objects = one_origin_objects_entry.second; |
| + |
| + // Skip the embedded settings which will be added below. |
| + if (requesting_origin != embedding_origin) { |
| + has_embedded_entries = true; |
| + continue; |
| + } |
| + |
| + for (const auto& sorted_objects_entry : sorted_objects) { |
| + this_provider_exceptions.push_back(GetChooserExceptionForPage( |
| + requesting_origin, embedding_origin, source, |
| + sorted_objects_entry.first, sorted_objects_entry.second)); |
| + } |
| + } |
| + |
| + if (has_embedded_entries) { |
| + // Add a "parent" entry that simply acts as a heading for all entries |
| + // where |requesting_origin| has been embedded. |
| + this_provider_exceptions.push_back( |
| + GetChooserExceptionForPage(requesting_origin, requesting_origin, |
| + source, std::string(), nullptr)); |
| + |
| + // Add the "children" for any embedded settings. |
| + for (const auto& one_origin_objects_entry : one_origin_objects) { |
| + const GURL& embedding_origin = one_origin_objects_entry.first; |
| + const SortedObjects& sorted_objects = one_origin_objects_entry.second; |
| + |
| + // Skip the non-embedded setting which we already added above. |
| + if (requesting_origin == embedding_origin) |
| + continue; |
| + |
| + for (const auto& sorted_objects_entry : sorted_objects) { |
| + this_provider_exceptions.push_back(GetChooserExceptionForPage( |
| + requesting_origin, embedding_origin, source, |
| + sorted_objects_entry.first, sorted_objects_entry.second)); |
| + } |
| + } |
| + } |
| + } |
| + |
| + for (auto& one_provider_exceptions : all_provider_exceptions) { |
| + for (auto& exception : one_provider_exceptions) |
| + exceptions->Append(std::move(exception)); |
| + } |
| +} |
| + |
| } // namespace site_settings |