Logo Search packages:      
Sourcecode: chromium-browser version File versions  Download package

geolocation_content_settings_map.cc

// Copyright (c) 2010 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Implementation of the geolocation content settings map. Styled on
// HostContentSettingsMap however unlike that class, this one does not hold
// an additional in-memory copy of the settings as it does not need to support
// thread safe synchronous access to the settings; all geolocation permissions
// are read and written in the UI thread. (If in future this is no longer the
// case, refer to http://codereview.chromium.org/1525018 for a previous version
// with caching. Note that as we must observe the prefs store for settings
// changes, e.g. coming from the sync engine, the simplest design would be to
// always write-through changes straight to the prefs store, and rely on the
// notification observer to subsequently update any cached copy).

#include "chrome/browser/geolocation/geolocation_content_settings_map.h"

#include "base/utf_string_conversions.h"
#include "chrome/browser/chrome_thread.h"
#include "chrome/browser/pref_service.h"
#include "chrome/browser/profile.h"
#include "chrome/browser/scoped_pref_update.h"
#include "chrome/common/notification_service.h"
#include "chrome/common/notification_type.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/url_constants.h"
#include "net/base/dns_util.h"
#include "net/base/static_cookie_policy.h"

// static
const ContentSetting
    GeolocationContentSettingsMap::kDefaultSetting = CONTENT_SETTING_ASK;

GeolocationContentSettingsMap::GeolocationContentSettingsMap(Profile* profile)
    : profile_(profile) {
  DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
}

// static
void GeolocationContentSettingsMap::RegisterUserPrefs(PrefService* prefs) {
  prefs->RegisterIntegerPref(prefs::kGeolocationDefaultContentSetting,
                             CONTENT_SETTING_ASK);
  prefs->RegisterDictionaryPref(prefs::kGeolocationContentSettings);
}

// static
std::string GeolocationContentSettingsMap::OriginToString(const GURL& origin) {
  std::string port_component((origin.IntPort() != url_parse::PORT_UNSPECIFIED) ?
      ":" + origin.port() : "");
  std::string scheme_component(!origin.SchemeIs(chrome::kHttpScheme) ?
      origin.scheme() + chrome::kStandardSchemeSeparator : "");
  return scheme_component + origin.host() + port_component;
}

ContentSetting GeolocationContentSettingsMap::GetDefaultContentSetting() const {
  DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
  const PrefService* prefs = profile_->GetPrefs();
  const ContentSetting default_content_setting = IntToContentSetting(
      prefs->GetInteger(prefs::kGeolocationDefaultContentSetting));
  return default_content_setting == CONTENT_SETTING_DEFAULT ?
         kDefaultSetting : default_content_setting;
}

ContentSetting GeolocationContentSettingsMap::GetContentSetting(
    const GURL& requesting_url,
    const GURL& embedding_url) const {
  DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
  DCHECK(requesting_url.is_valid() && embedding_url.is_valid());
  GURL requesting_origin(requesting_url.GetOrigin());
  GURL embedding_origin(embedding_url.GetOrigin());
  DCHECK(requesting_origin.is_valid() && embedding_origin.is_valid());

  const DictionaryValue* all_settings_dictionary =
      profile_->GetPrefs()->GetDictionary(prefs::kGeolocationContentSettings);
  // Careful: The returned value could be NULL if the pref has never been set.
  if (all_settings_dictionary != NULL) {
    DictionaryValue* requesting_origin_settings;
    if (all_settings_dictionary->GetDictionaryWithoutPathExpansion(
        UTF8ToWide(requesting_origin.spec()), &requesting_origin_settings)) {
      int setting;
      if (requesting_origin_settings->GetIntegerWithoutPathExpansion(
          UTF8ToWide(embedding_origin.spec()), &setting))
        return IntToContentSetting(setting);
      // Check for any-embedder setting
      if (requesting_origin != embedding_origin &&
          requesting_origin_settings->GetIntegerWithoutPathExpansion(
          L"", &setting))
        return IntToContentSetting(setting);
    }
  }
  return GetDefaultContentSetting();
}

GeolocationContentSettingsMap::AllOriginsSettings
    GeolocationContentSettingsMap::GetAllOriginsSettings() const {
  DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
  AllOriginsSettings content_settings;
  const DictionaryValue* all_settings_dictionary =
      profile_->GetPrefs()->GetDictionary(prefs::kGeolocationContentSettings);
  // Careful: The returned value could be NULL if the pref has never been set.
  if (all_settings_dictionary != NULL) {
    for (DictionaryValue::key_iterator i(all_settings_dictionary->begin_keys());
         i != all_settings_dictionary->end_keys(); ++i) {
      const std::wstring& wide_origin(*i);
      GURL origin_as_url(WideToUTF8(wide_origin));
      if (!origin_as_url.is_valid())
        continue;
      DictionaryValue* requesting_origin_settings_dictionary = NULL;
      bool found = all_settings_dictionary->GetDictionaryWithoutPathExpansion(
          wide_origin, &requesting_origin_settings_dictionary);
      DCHECK(found);
      if (!requesting_origin_settings_dictionary)
        continue;
      GetOneOriginSettingsFromDictionary(
          requesting_origin_settings_dictionary,
          &content_settings[origin_as_url]);
    }
  }
  return content_settings;
}

void GeolocationContentSettingsMap::SetDefaultContentSetting(
    ContentSetting setting) {
  DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
  profile_->GetPrefs()->SetInteger(prefs::kGeolocationDefaultContentSetting,
                                   setting == CONTENT_SETTING_DEFAULT ?
                                       kDefaultSetting : setting);
}

void GeolocationContentSettingsMap::SetContentSetting(
    const GURL& requesting_url,
    const GURL& embedding_url,
    ContentSetting setting) {
  DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
  DCHECK(requesting_url.is_valid());
  DCHECK(embedding_url.is_valid() || embedding_url.is_empty());
  GURL requesting_origin(requesting_url.GetOrigin());
  GURL embedding_origin(embedding_url.GetOrigin());
  DCHECK(requesting_origin.is_valid());
  DCHECK(embedding_origin.is_valid() || embedding_url.is_empty());
  std::wstring wide_requesting_origin(UTF8ToWide(requesting_origin.spec()));
  std::wstring wide_embedding_origin(UTF8ToWide(embedding_origin.spec()));
  PrefService* prefs = profile_->GetPrefs();
  DictionaryValue* all_settings_dictionary = prefs->GetMutableDictionary(
      prefs::kGeolocationContentSettings);
  DCHECK(all_settings_dictionary);

  ScopedPrefUpdate update(prefs, prefs::kGeolocationContentSettings);
  DictionaryValue* requesting_origin_settings_dictionary = NULL;
  all_settings_dictionary->GetDictionaryWithoutPathExpansion(
      wide_requesting_origin, &requesting_origin_settings_dictionary);
  if (setting == CONTENT_SETTING_DEFAULT) {
    if (requesting_origin_settings_dictionary) {
      requesting_origin_settings_dictionary->RemoveWithoutPathExpansion(
          wide_embedding_origin, NULL);
      if (requesting_origin_settings_dictionary->empty())
        all_settings_dictionary->RemoveWithoutPathExpansion(
            wide_requesting_origin, NULL);
    }
  } else {
    if (!requesting_origin_settings_dictionary) {
      requesting_origin_settings_dictionary = new DictionaryValue;
      all_settings_dictionary->SetWithoutPathExpansion(
          wide_requesting_origin, requesting_origin_settings_dictionary);
    }
    DCHECK(requesting_origin_settings_dictionary);
    requesting_origin_settings_dictionary->SetWithoutPathExpansion(
        wide_embedding_origin, Value::CreateIntegerValue(setting));
  }
}

void GeolocationContentSettingsMap::ResetToDefault() {
  DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));

  PrefService* prefs = profile_->GetPrefs();
  prefs->ClearPref(prefs::kGeolocationDefaultContentSetting);
  prefs->ClearPref(prefs::kGeolocationContentSettings);
}

GeolocationContentSettingsMap::~GeolocationContentSettingsMap() {
}

// static
void GeolocationContentSettingsMap::GetOneOriginSettingsFromDictionary(
    const DictionaryValue* dictionary,
    OneOriginSettings* one_origin_settings) {
  for (DictionaryValue::key_iterator i(dictionary->begin_keys());
       i != dictionary->end_keys(); ++i) {
    const std::wstring& target(*i);
    int setting = kDefaultSetting;
    bool found = dictionary->GetIntegerWithoutPathExpansion(target, &setting);
    DCHECK(found);
    GURL target_url(WideToUTF8(target));
    // An empty URL has a special meaning (wildcard), so only accept invalid
    // URLs if the original version was empty (avoids treating corrupted prefs
    // as the wildcard entry; see http://crbug.com/39685)
    if (target_url.is_valid() || target.empty())
      (*one_origin_settings)[target_url] = IntToContentSetting(setting);
  }
}

Generated by  Doxygen 1.6.0   Back to index