chrome_access_token_store.cc revision 868fa2fe829687343ffae624259930155e16dbd8
1// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "chrome/browser/geolocation/chrome_access_token_store.h"
6
7#include "base/bind.h"
8#include "base/prefs/pref_registry_simple.h"
9#include "base/prefs/pref_service.h"
10#include "base/strings/string_piece.h"
11#include "base/strings/utf_string_conversions.h"
12#include "base/values.h"
13#include "chrome/browser/browser_process.h"
14#include "chrome/browser/prefs/scoped_user_pref_update.h"
15#include "chrome/common/pref_names.h"
16#include "content/public/browser/browser_thread.h"
17#include "googleurl/src/gurl.h"
18
19using content::AccessTokenStore;
20using content::BrowserThread;
21
22namespace {
23
24bool IsUnsupportedNetworkProviderUrl(const GURL& url) {
25  const std::string& spec = url.spec();
26
27  // Unsupported after Chrome v14.
28  if (spec == "https://www.google.com/loc/json")
29    return true;
30
31  // Unsupported after Chrome v22.
32  if (spec == "https://maps.googleapis.com/maps/api/browserlocation/json")
33    return true;
34
35  return false;
36}
37
38// Loads access tokens and other necessary data on the UI thread, and
39// calls back to the originator on the originating threaad.
40class TokenLoadingJob : public base::RefCountedThreadSafe<TokenLoadingJob> {
41 public:
42  TokenLoadingJob(
43      const AccessTokenStore::LoadAccessTokensCallbackType& callback)
44      : callback_(callback),
45        system_request_context_(NULL) {
46  }
47
48  void Run() {
49    BrowserThread::PostTaskAndReply(
50        BrowserThread::UI,
51        FROM_HERE,
52        base::Bind(&TokenLoadingJob::PerformWorkOnUIThread, this),
53        base::Bind(&TokenLoadingJob::RespondOnOriginatingThread, this));
54  }
55
56 private:
57  friend class base::RefCountedThreadSafe<TokenLoadingJob>;
58
59  ~TokenLoadingJob() {}
60
61  void PerformWorkOnUIThread() {
62    DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
63    DictionaryPrefUpdate update(g_browser_process->local_state(),
64                                prefs::kGeolocationAccessToken);
65    DictionaryValue* token_dictionary = update.Get();
66
67    std::vector<std::string> providers_to_remove;
68    // The dictionary value could be NULL if the pref has never been set.
69    if (token_dictionary != NULL) {
70      for (DictionaryValue::Iterator it(*token_dictionary); !it.IsAtEnd();
71           it.Advance()) {
72        GURL url(it.key());
73        if (!url.is_valid())
74          continue;
75        if (IsUnsupportedNetworkProviderUrl(url)) {
76          providers_to_remove.push_back(it.key());
77          continue;
78        }
79        it.value().GetAsString(&access_token_set_[url]);
80      }
81      for (size_t i = 0; i < providers_to_remove.size(); ++i) {
82        token_dictionary->RemoveWithoutPathExpansion(
83            providers_to_remove[i], NULL);
84      }
85    }
86
87    system_request_context_ = g_browser_process->system_request_context();
88  }
89
90  void RespondOnOriginatingThread() {
91    callback_.Run(access_token_set_, system_request_context_);
92  }
93
94  AccessTokenStore::LoadAccessTokensCallbackType callback_;
95  AccessTokenStore::AccessTokenSet access_token_set_;
96  net::URLRequestContextGetter* system_request_context_;
97};
98
99}  // namespace
100
101void ChromeAccessTokenStore::RegisterPrefs(PrefRegistrySimple* registry) {
102  registry->RegisterDictionaryPref(prefs::kGeolocationAccessToken);
103}
104
105ChromeAccessTokenStore::ChromeAccessTokenStore() {}
106
107void ChromeAccessTokenStore::LoadAccessTokens(
108    const LoadAccessTokensCallbackType& callback) {
109  scoped_refptr<TokenLoadingJob> job(new TokenLoadingJob(callback));
110  job->Run();
111}
112
113ChromeAccessTokenStore::~ChromeAccessTokenStore() {}
114
115static void SetAccessTokenOnUIThread(const GURL& server_url,
116                                     const string16& token) {
117  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
118  DictionaryPrefUpdate update(g_browser_process->local_state(),
119                              prefs::kGeolocationAccessToken);
120  DictionaryValue* access_token_dictionary = update.Get();
121  access_token_dictionary->SetWithoutPathExpansion(
122      server_url.spec(), Value::CreateStringValue(token));
123}
124
125void ChromeAccessTokenStore::SaveAccessToken(const GURL& server_url,
126                                             const string16& access_token) {
127  BrowserThread::PostTask(
128      BrowserThread::UI, FROM_HERE,
129      base::Bind(&SetAccessTokenOnUIThread, server_url, access_token));
130}
131