| OLD | NEW | 
|---|
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2010 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 // Implementation of the geolocation content settings map. Styled on | 5 // Implementation of the geolocation content settings map. Styled on | 
| 6 // HostContentSettingsMap however unlike that class, this one does not hold | 6 // HostContentSettingsMap however unlike that class, this one does not hold | 
| 7 // an additional in-memory copy of the settings as it does not need to support | 7 // an additional in-memory copy of the settings as it does not need to support | 
| 8 // thread safe synchronous access to the settings; all geolocation permissions | 8 // thread safe synchronous access to the settings; all geolocation permissions | 
| 9 // are read and written in the UI thread. (If in future this is no longer the | 9 // are read and written in the UI thread. (If in future this is no longer the | 
| 10 // case, refer to http://codereview.chromium.org/1525018 for a previous version | 10 // case, refer to http://codereview.chromium.org/1525018 for a previous version | 
| 11 // with caching. Note that as we must observe the prefs store for settings | 11 // with caching. Note that as we must observe the prefs store for settings | 
| 12 // changes, e.g. coming from the sync engine, the simplest design would be to | 12 // changes, e.g. coming from the sync engine, the simplest design would be to | 
| 13 // always write-through changes straight to the prefs store, and rely on the | 13 // always write-through changes straight to the prefs store, and rely on the | 
| 14 // notification observer to subsequently update any cached copy). | 14 // notification observer to subsequently update any cached copy). | 
| 15 | 15 | 
| 16 #include "chrome/browser/geolocation/geolocation_content_settings_map.h" | 16 #include "chrome/browser/geolocation/geolocation_content_settings_map.h" | 
| 17 | 17 | 
| 18 #include <string> | 18 #include <string> | 
| 19 | 19 | 
| 20 #include "base/string_piece.h" | 20 #include "base/string_piece.h" | 
| 21 #include "base/utf_string_conversions.h" | 21 #include "base/utf_string_conversions.h" | 
| 22 #include "chrome/browser/browser_thread.h" | 22 #include "chrome/browser/browser_thread.h" | 
|  | 23 #include "chrome/browser/content_settings/content_settings_details.h" | 
|  | 24 #include "chrome/browser/content_settings/content_settings_pattern.h" | 
| 23 #include "chrome/browser/prefs/pref_service.h" | 25 #include "chrome/browser/prefs/pref_service.h" | 
| 24 #include "chrome/browser/prefs/scoped_pref_update.h" | 26 #include "chrome/browser/prefs/scoped_pref_update.h" | 
| 25 #include "chrome/browser/profiles/profile.h" | 27 #include "chrome/browser/profiles/profile.h" | 
|  | 28 #include "chrome/common/notification_service.h" | 
|  | 29 #include "chrome/common/notification_source.h" | 
| 26 #include "chrome/common/notification_type.h" | 30 #include "chrome/common/notification_type.h" | 
| 27 #include "chrome/common/pref_names.h" | 31 #include "chrome/common/pref_names.h" | 
| 28 #include "chrome/common/url_constants.h" | 32 #include "chrome/common/url_constants.h" | 
| 29 #include "net/base/dns_util.h" | 33 #include "net/base/dns_util.h" | 
| 30 #include "net/base/static_cookie_policy.h" | 34 #include "net/base/static_cookie_policy.h" | 
| 31 | 35 | 
| 32 // static | 36 // static | 
| 33 const ContentSetting | 37 const ContentSetting | 
| 34     GeolocationContentSettingsMap::kDefaultSetting = CONTENT_SETTING_ASK; | 38     GeolocationContentSettingsMap::kDefaultSetting = CONTENT_SETTING_ASK; | 
| 35 | 39 | 
| 36 GeolocationContentSettingsMap::GeolocationContentSettingsMap(Profile* profile) | 40 GeolocationContentSettingsMap::GeolocationContentSettingsMap(Profile* profile) | 
| 37     : profile_(profile) { | 41     : profile_(profile) { | 
| 38   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 42   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 
|  | 43   prefs_registrar_.Init(profile_->GetPrefs()); | 
|  | 44   prefs_registrar_.Add(prefs::kGeolocationDefaultContentSetting, this); | 
|  | 45   prefs_registrar_.Add(prefs::kGeolocationContentSettings, this); | 
|  | 46   notification_registrar_.Add(this, NotificationType::PROFILE_DESTROYED, | 
|  | 47                               Source<Profile>(profile_)); | 
| 39 } | 48 } | 
| 40 | 49 | 
| 41 // static | 50 // static | 
| 42 void GeolocationContentSettingsMap::RegisterUserPrefs(PrefService* prefs) { | 51 void GeolocationContentSettingsMap::RegisterUserPrefs(PrefService* prefs) { | 
| 43   prefs->RegisterIntegerPref(prefs::kGeolocationDefaultContentSetting, | 52   prefs->RegisterIntegerPref(prefs::kGeolocationDefaultContentSetting, | 
| 44                              CONTENT_SETTING_ASK); | 53                              CONTENT_SETTING_ASK); | 
| 45   prefs->RegisterDictionaryPref(prefs::kGeolocationContentSettings); | 54   prefs->RegisterDictionaryPref(prefs::kGeolocationContentSettings); | 
| 46 } | 55 } | 
| 47 | 56 | 
| 48 ContentSetting GeolocationContentSettingsMap::GetDefaultContentSetting() const { | 57 ContentSetting GeolocationContentSettingsMap::GetDefaultContentSetting() const { | 
| 49   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 58   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 
|  | 59   // If the profile is destroyed (and set to NULL) return CONTENT_SETTING_BLOCK. | 
|  | 60   if (!profile_) | 
|  | 61     return CONTENT_SETTING_BLOCK; | 
| 50   const PrefService* prefs = profile_->GetPrefs(); | 62   const PrefService* prefs = profile_->GetPrefs(); | 
| 51   const ContentSetting default_content_setting = IntToContentSetting( | 63   const ContentSetting default_content_setting = IntToContentSetting( | 
| 52       prefs->GetInteger(prefs::kGeolocationDefaultContentSetting)); | 64       prefs->GetInteger(prefs::kGeolocationDefaultContentSetting)); | 
| 53   return default_content_setting == CONTENT_SETTING_DEFAULT ? | 65   return default_content_setting == CONTENT_SETTING_DEFAULT ? | 
| 54          kDefaultSetting : default_content_setting; | 66          kDefaultSetting : default_content_setting; | 
| 55 } | 67 } | 
| 56 | 68 | 
|  | 69 bool GeolocationContentSettingsMap::IsDefaultContentSettingManaged() const { | 
|  | 70   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 
|  | 71   // If the profile is destroyed (and set to NULL) return true. | 
|  | 72   if (!profile_) | 
|  | 73     return true; | 
|  | 74   return profile_->GetPrefs()->IsManagedPreference( | 
|  | 75       prefs::kGeolocationDefaultContentSetting); | 
|  | 76 } | 
|  | 77 | 
| 57 ContentSetting GeolocationContentSettingsMap::GetContentSetting( | 78 ContentSetting GeolocationContentSettingsMap::GetContentSetting( | 
| 58     const GURL& requesting_url, | 79     const GURL& requesting_url, | 
| 59     const GURL& embedding_url) const { | 80     const GURL& embedding_url) const { | 
| 60   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 81   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 
| 61   DCHECK(requesting_url.is_valid() && embedding_url.is_valid()); | 82   DCHECK(requesting_url.is_valid() && embedding_url.is_valid()); | 
| 62   GURL requesting_origin(requesting_url.GetOrigin()); | 83   GURL requesting_origin(requesting_url.GetOrigin()); | 
| 63   GURL embedding_origin(embedding_url.GetOrigin()); | 84   GURL embedding_origin(embedding_url.GetOrigin()); | 
| 64   DCHECK(requesting_origin.is_valid() && embedding_origin.is_valid()); | 85   DCHECK(requesting_origin.is_valid() && embedding_origin.is_valid()); | 
| 65 | 86   // If the profile is destroyed (and set to NULL) return CONTENT_SETTING_BLOCK. | 
|  | 87   if (!profile_) | 
|  | 88     return CONTENT_SETTING_BLOCK; | 
| 66   const DictionaryValue* all_settings_dictionary = | 89   const DictionaryValue* all_settings_dictionary = | 
| 67       profile_->GetPrefs()->GetDictionary(prefs::kGeolocationContentSettings); | 90       profile_->GetPrefs()->GetDictionary(prefs::kGeolocationContentSettings); | 
| 68   // Careful: The returned value could be NULL if the pref has never been set. | 91   // Careful: The returned value could be NULL if the pref has never been set. | 
| 69   if (all_settings_dictionary != NULL) { | 92   if (all_settings_dictionary != NULL) { | 
| 70     DictionaryValue* requesting_origin_settings; | 93     DictionaryValue* requesting_origin_settings; | 
| 71     if (all_settings_dictionary->GetDictionaryWithoutPathExpansion( | 94     if (all_settings_dictionary->GetDictionaryWithoutPathExpansion( | 
| 72         requesting_origin.spec(), &requesting_origin_settings)) { | 95         requesting_origin.spec(), &requesting_origin_settings)) { | 
| 73       int setting; | 96       int setting; | 
| 74       if (requesting_origin_settings->GetIntegerWithoutPathExpansion( | 97       if (requesting_origin_settings->GetIntegerWithoutPathExpansion( | 
| 75           embedding_origin.spec(), &setting)) | 98           embedding_origin.spec(), &setting)) | 
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 108           requesting_origin_settings_dictionary, | 131           requesting_origin_settings_dictionary, | 
| 109           &content_settings[origin_as_url]); | 132           &content_settings[origin_as_url]); | 
| 110     } | 133     } | 
| 111   } | 134   } | 
| 112   return content_settings; | 135   return content_settings; | 
| 113 } | 136 } | 
| 114 | 137 | 
| 115 void GeolocationContentSettingsMap::SetDefaultContentSetting( | 138 void GeolocationContentSettingsMap::SetDefaultContentSetting( | 
| 116     ContentSetting setting) { | 139     ContentSetting setting) { | 
| 117   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 140   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 
|  | 141   if (!profile_) | 
|  | 142     return; | 
| 118   profile_->GetPrefs()->SetInteger(prefs::kGeolocationDefaultContentSetting, | 143   profile_->GetPrefs()->SetInteger(prefs::kGeolocationDefaultContentSetting, | 
| 119                                    setting == CONTENT_SETTING_DEFAULT ? | 144                                    setting == CONTENT_SETTING_DEFAULT ? | 
| 120                                        kDefaultSetting : setting); | 145                                        kDefaultSetting : setting); | 
| 121 } | 146 } | 
| 122 | 147 | 
| 123 void GeolocationContentSettingsMap::SetContentSetting( | 148 void GeolocationContentSettingsMap::SetContentSetting( | 
| 124     const GURL& requesting_url, | 149     const GURL& requesting_url, | 
| 125     const GURL& embedding_url, | 150     const GURL& embedding_url, | 
| 126     ContentSetting setting) { | 151     ContentSetting setting) { | 
| 127   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 152   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 
| 128   DCHECK(requesting_url.is_valid()); | 153   DCHECK(requesting_url.is_valid()); | 
| 129   DCHECK(embedding_url.is_valid() || embedding_url.is_empty()); | 154   DCHECK(embedding_url.is_valid() || embedding_url.is_empty()); | 
| 130   GURL requesting_origin(requesting_url.GetOrigin()); | 155   GURL requesting_origin(requesting_url.GetOrigin()); | 
| 131   GURL embedding_origin(embedding_url.GetOrigin()); | 156   GURL embedding_origin(embedding_url.GetOrigin()); | 
| 132   DCHECK(requesting_origin.is_valid()); | 157   DCHECK(requesting_origin.is_valid()); | 
| 133   DCHECK(embedding_origin.is_valid() || embedding_url.is_empty()); | 158   DCHECK(embedding_origin.is_valid() || embedding_url.is_empty()); | 
|  | 159   if (!profile_) | 
|  | 160     return; | 
| 134   PrefService* prefs = profile_->GetPrefs(); | 161   PrefService* prefs = profile_->GetPrefs(); | 
| 135   DictionaryValue* all_settings_dictionary = prefs->GetMutableDictionary( | 162   DictionaryValue* all_settings_dictionary = prefs->GetMutableDictionary( | 
| 136       prefs::kGeolocationContentSettings); | 163       prefs::kGeolocationContentSettings); | 
| 137   DCHECK(all_settings_dictionary); | 164   DCHECK(all_settings_dictionary); | 
| 138 | 165 | 
| 139   ScopedPrefUpdate update(prefs, prefs::kGeolocationContentSettings); | 166   ScopedPrefUpdate update(prefs, prefs::kGeolocationContentSettings); | 
| 140   DictionaryValue* requesting_origin_settings_dictionary = NULL; | 167   DictionaryValue* requesting_origin_settings_dictionary = NULL; | 
| 141   all_settings_dictionary->GetDictionaryWithoutPathExpansion( | 168   all_settings_dictionary->GetDictionaryWithoutPathExpansion( | 
| 142       requesting_origin.spec(), &requesting_origin_settings_dictionary); | 169       requesting_origin.spec(), &requesting_origin_settings_dictionary); | 
| 143   if (setting == CONTENT_SETTING_DEFAULT) { | 170   if (setting == CONTENT_SETTING_DEFAULT) { | 
| (...skipping 11 matching lines...) Expand all  Loading... | 
| 155           requesting_origin.spec(), requesting_origin_settings_dictionary); | 182           requesting_origin.spec(), requesting_origin_settings_dictionary); | 
| 156     } | 183     } | 
| 157     DCHECK(requesting_origin_settings_dictionary); | 184     DCHECK(requesting_origin_settings_dictionary); | 
| 158     requesting_origin_settings_dictionary->SetWithoutPathExpansion( | 185     requesting_origin_settings_dictionary->SetWithoutPathExpansion( | 
| 159         embedding_origin.spec(), Value::CreateIntegerValue(setting)); | 186         embedding_origin.spec(), Value::CreateIntegerValue(setting)); | 
| 160   } | 187   } | 
| 161 } | 188 } | 
| 162 | 189 | 
| 163 void GeolocationContentSettingsMap::ResetToDefault() { | 190 void GeolocationContentSettingsMap::ResetToDefault() { | 
| 164   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 191   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 
| 165 | 192   if (!profile_) | 
|  | 193     return; | 
| 166   PrefService* prefs = profile_->GetPrefs(); | 194   PrefService* prefs = profile_->GetPrefs(); | 
| 167   prefs->ClearPref(prefs::kGeolocationDefaultContentSetting); | 195   prefs->ClearPref(prefs::kGeolocationDefaultContentSetting); | 
| 168   prefs->ClearPref(prefs::kGeolocationContentSettings); | 196   prefs->ClearPref(prefs::kGeolocationContentSettings); | 
| 169 } | 197 } | 
| 170 | 198 | 
|  | 199 void GeolocationContentSettingsMap::NotifyObservers( | 
|  | 200     const ContentSettingsDetails& details) { | 
|  | 201   NotificationService::current()->Notify( | 
|  | 202       NotificationType::GEOLOCATION_SETTINGS_CHANGED, | 
|  | 203       Source<GeolocationContentSettingsMap>(this), | 
|  | 204       Details<const ContentSettingsDetails>(&details)); | 
|  | 205 } | 
|  | 206 | 
|  | 207 void GeolocationContentSettingsMap::Observe( | 
|  | 208     NotificationType type, | 
|  | 209     const NotificationSource& source, | 
|  | 210     const NotificationDetails& details) { | 
|  | 211   if (type == NotificationType::PREF_CHANGED) { | 
|  | 212     const std::string& name = *Details<std::string>(details).ptr(); | 
|  | 213     if (name == prefs::kGeolocationDefaultContentSetting) { | 
|  | 214       NotifyObservers(ContentSettingsDetails( | 
|  | 215       ContentSettingsPattern(), | 
|  | 216       CONTENT_SETTINGS_TYPE_DEFAULT, | 
|  | 217       "")); | 
|  | 218     } | 
|  | 219   } else if (NotificationType::PROFILE_DESTROYED == type) { | 
|  | 220     UnregisterObservers(); | 
|  | 221   } else { | 
|  | 222     NOTREACHED(); | 
|  | 223   } | 
|  | 224 } | 
|  | 225 | 
|  | 226 void GeolocationContentSettingsMap::UnregisterObservers() { | 
|  | 227   DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); | 
|  | 228   if (!profile_) | 
|  | 229     return; | 
|  | 230   prefs_registrar_.RemoveAll(); | 
|  | 231   notification_registrar_.Remove(this, NotificationType::PROFILE_DESTROYED, | 
|  | 232                                  Source<Profile>(profile_)); | 
|  | 233   profile_ = NULL; | 
|  | 234 } | 
|  | 235 | 
| 171 GeolocationContentSettingsMap::~GeolocationContentSettingsMap() { | 236 GeolocationContentSettingsMap::~GeolocationContentSettingsMap() { | 
|  | 237   UnregisterObservers(); | 
| 172 } | 238 } | 
| 173 | 239 | 
| 174 // static | 240 // static | 
| 175 void GeolocationContentSettingsMap::GetOneOriginSettingsFromDictionary( | 241 void GeolocationContentSettingsMap::GetOneOriginSettingsFromDictionary( | 
| 176     const DictionaryValue* dictionary, | 242     const DictionaryValue* dictionary, | 
| 177     OneOriginSettings* one_origin_settings) { | 243     OneOriginSettings* one_origin_settings) { | 
| 178   for (DictionaryValue::key_iterator i(dictionary->begin_keys()); | 244   for (DictionaryValue::key_iterator i(dictionary->begin_keys()); | 
| 179        i != dictionary->end_keys(); ++i) { | 245        i != dictionary->end_keys(); ++i) { | 
| 180     const std::string& target(*i); | 246     const std::string& target(*i); | 
| 181     int setting = kDefaultSetting; | 247     int setting = kDefaultSetting; | 
| 182     bool found = dictionary->GetIntegerWithoutPathExpansion(target, &setting); | 248     bool found = dictionary->GetIntegerWithoutPathExpansion(target, &setting); | 
| 183     DCHECK(found); | 249     DCHECK(found); | 
| 184     GURL target_url(target); | 250     GURL target_url(target); | 
| 185     // An empty URL has a special meaning (wildcard), so only accept invalid | 251     // An empty URL has a special meaning (wildcard), so only accept invalid | 
| 186     // URLs if the original version was empty (avoids treating corrupted prefs | 252     // URLs if the original version was empty (avoids treating corrupted prefs | 
| 187     // as the wildcard entry; see http://crbug.com/39685) | 253     // as the wildcard entry; see http://crbug.com/39685) | 
| 188     if (target_url.is_valid() || target.empty()) | 254     if (target_url.is_valid() || target.empty()) | 
| 189       (*one_origin_settings)[target_url] = IntToContentSetting(setting); | 255       (*one_origin_settings)[target_url] = IntToContentSetting(setting); | 
| 190   } | 256   } | 
| 191 } | 257 } | 
| OLD | NEW | 
|---|