1// Copyright (c) 2011 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 "content/browser/geolocation/access_token_store.h"
6
7#include "base/string_piece.h"
8#include "base/utf_string_conversions.h"
9#include "base/values.h"
10#include "chrome/browser/browser_process.h"
11#include "chrome/browser/prefs/pref_service.h"
12#include "chrome/browser/prefs/scoped_user_pref_update.h"
13#include "chrome/common/pref_names.h"
14#include "content/browser/browser_thread.h"
15#include "googleurl/src/gurl.h"
16
17namespace {
18class ChromePrefsAccessTokenStore : public AccessTokenStore {
19 public:
20  ChromePrefsAccessTokenStore();
21
22 private:
23  void LoadDictionaryStoreInUIThread(
24      scoped_refptr<CancelableRequest<LoadAccessTokensCallbackType> > request);
25
26  // AccessTokenStore
27  virtual void DoLoadAccessTokens(
28      scoped_refptr<CancelableRequest<LoadAccessTokensCallbackType> > request);
29  virtual void SaveAccessToken(
30      const GURL& server_url, const string16& access_token);
31
32  DISALLOW_COPY_AND_ASSIGN(ChromePrefsAccessTokenStore);
33};
34
35ChromePrefsAccessTokenStore::ChromePrefsAccessTokenStore() {
36}
37
38void ChromePrefsAccessTokenStore::LoadDictionaryStoreInUIThread(
39      scoped_refptr<CancelableRequest<LoadAccessTokensCallbackType> > request) {
40  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
41  if (request->canceled())
42    return;
43  const DictionaryValue* token_dictionary =
44          g_browser_process->local_state()->GetDictionary(
45              prefs::kGeolocationAccessToken);
46
47  AccessTokenStore::AccessTokenSet access_token_set;
48  // The dictionary value could be NULL if the pref has never been set.
49  if (token_dictionary != NULL) {
50    for (DictionaryValue::key_iterator it = token_dictionary->begin_keys();
51        it != token_dictionary->end_keys(); ++it) {
52      GURL url(*it);
53      if (!url.is_valid())
54        continue;
55      token_dictionary->GetStringWithoutPathExpansion(*it,
56                                                      &access_token_set[url]);
57    }
58  }
59  request->ForwardResultAsync(MakeTuple(access_token_set));
60}
61
62void ChromePrefsAccessTokenStore::DoLoadAccessTokens(
63    scoped_refptr<CancelableRequest<LoadAccessTokensCallbackType> > request) {
64  BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, NewRunnableMethod(
65      this, &ChromePrefsAccessTokenStore::LoadDictionaryStoreInUIThread,
66      request));
67}
68
69void SetAccessTokenOnUIThread(const GURL& server_url, const string16& token) {
70  DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
71  DictionaryPrefUpdate update(g_browser_process->local_state(),
72                              prefs::kGeolocationAccessToken);
73  DictionaryValue* access_token_dictionary = update.Get();
74  access_token_dictionary->SetWithoutPathExpansion(
75      server_url.spec(), Value::CreateStringValue(token));
76}
77
78void ChromePrefsAccessTokenStore::SaveAccessToken(
79      const GURL& server_url, const string16& access_token) {
80  BrowserThread::PostTask(BrowserThread::UI, FROM_HERE, NewRunnableFunction(
81      &SetAccessTokenOnUIThread, server_url, access_token));
82}
83}  // namespace
84
85AccessTokenStore::AccessTokenStore() {
86}
87
88AccessTokenStore::~AccessTokenStore() {
89}
90
91void AccessTokenStore::RegisterPrefs(PrefService* prefs) {
92  prefs->RegisterDictionaryPref(prefs::kGeolocationAccessToken);
93}
94
95AccessTokenStore::Handle AccessTokenStore::LoadAccessTokens(
96    CancelableRequestConsumerBase* consumer,
97    LoadAccessTokensCallbackType* callback) {
98  scoped_refptr<CancelableRequest<LoadAccessTokensCallbackType> > request(
99      new CancelableRequest<LoadAccessTokensCallbackType>(callback));
100  AddRequest(request, consumer);
101  DCHECK(request->handle());
102
103  DoLoadAccessTokens(request);
104  return request->handle();
105}
106
107// Creates a new access token store backed by the global chome prefs.
108AccessTokenStore* NewChromePrefsAccessTokenStore() {
109  return new ChromePrefsAccessTokenStore;
110}
111