root/chrome/browser/geolocation/chrome_access_token_store.cc

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. IsUnsupportedNetworkProviderUrl
  2. system_request_context_
  3. Run
  4. PerformWorkOnUIThread
  5. RespondOnOriginatingThread
  6. RegisterPrefs
  7. LoadAccessTokens
  8. SetAccessTokenOnUIThread
  9. SaveAccessToken

// Copyright (c) 2012 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.

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

#include "base/bind.h"
#include "base/prefs/pref_registry_simple.h"
#include "base/prefs/pref_service.h"
#include "base/prefs/scoped_user_pref_update.h"
#include "base/strings/string_piece.h"
#include "base/strings/utf_string_conversions.h"
#include "base/values.h"
#include "chrome/browser/browser_process.h"
#include "chrome/common/pref_names.h"
#include "content/public/browser/browser_thread.h"
#include "url/gurl.h"

using content::AccessTokenStore;
using content::BrowserThread;

namespace {

bool IsUnsupportedNetworkProviderUrl(const GURL& url) {
  const std::string& spec = url.spec();

  // Unsupported after Chrome v14.
  if (spec == "https://www.google.com/loc/json")
    return true;

  // Unsupported after Chrome v22.
  if (spec == "https://maps.googleapis.com/maps/api/browserlocation/json")
    return true;

  return false;
}

// Loads access tokens and other necessary data on the UI thread, and
// calls back to the originator on the originating thread.
class TokenLoadingJob : public base::RefCountedThreadSafe<TokenLoadingJob> {
 public:
  TokenLoadingJob(
      const AccessTokenStore::LoadAccessTokensCallbackType& callback)
      : callback_(callback),
        system_request_context_(NULL) {
  }

  void Run() {
    BrowserThread::PostTaskAndReply(
        BrowserThread::UI,
        FROM_HERE,
        base::Bind(&TokenLoadingJob::PerformWorkOnUIThread, this),
        base::Bind(&TokenLoadingJob::RespondOnOriginatingThread, this));
  }

 private:
  friend class base::RefCountedThreadSafe<TokenLoadingJob>;

  ~TokenLoadingJob() {}

  void PerformWorkOnUIThread() {
    DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
    DictionaryPrefUpdate update(g_browser_process->local_state(),
                                prefs::kGeolocationAccessToken);
    base::DictionaryValue* token_dictionary = update.Get();

    std::vector<std::string> providers_to_remove;
    // The dictionary value could be NULL if the pref has never been set.
    if (token_dictionary != NULL) {
      for (base::DictionaryValue::Iterator it(*token_dictionary); !it.IsAtEnd();
           it.Advance()) {
        GURL url(it.key());
        if (!url.is_valid())
          continue;
        if (IsUnsupportedNetworkProviderUrl(url)) {
          providers_to_remove.push_back(it.key());
          continue;
        }
        it.value().GetAsString(&access_token_set_[url]);
      }
      for (size_t i = 0; i < providers_to_remove.size(); ++i) {
        token_dictionary->RemoveWithoutPathExpansion(
            providers_to_remove[i], NULL);
      }
    }

    system_request_context_ = g_browser_process->system_request_context();
  }

  void RespondOnOriginatingThread() {
    callback_.Run(access_token_set_, system_request_context_);
  }

  AccessTokenStore::LoadAccessTokensCallbackType callback_;
  AccessTokenStore::AccessTokenSet access_token_set_;
  net::URLRequestContextGetter* system_request_context_;
};

}  // namespace

void ChromeAccessTokenStore::RegisterPrefs(PrefRegistrySimple* registry) {
  registry->RegisterDictionaryPref(prefs::kGeolocationAccessToken);
}

ChromeAccessTokenStore::ChromeAccessTokenStore() {}

void ChromeAccessTokenStore::LoadAccessTokens(
    const LoadAccessTokensCallbackType& callback) {
  scoped_refptr<TokenLoadingJob> job(new TokenLoadingJob(callback));
  job->Run();
}

ChromeAccessTokenStore::~ChromeAccessTokenStore() {}

static void SetAccessTokenOnUIThread(const GURL& server_url,
                                     const base::string16& token) {
  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
  DictionaryPrefUpdate update(g_browser_process->local_state(),
                              prefs::kGeolocationAccessToken);
  base::DictionaryValue* access_token_dictionary = update.Get();
  access_token_dictionary->SetWithoutPathExpansion(
      server_url.spec(), new base::StringValue(token));
}

void ChromeAccessTokenStore::SaveAccessToken(
    const GURL& server_url,
    const base::string16& access_token) {
  BrowserThread::PostTask(
      BrowserThread::UI, FROM_HERE,
      base::Bind(&SetAccessTokenOnUIThread, server_url, access_token));
}

/* [<][>][^][v][top][bottom][index][help] */