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.
5 #include "chrome/browser/geolocation/chrome_access_token_store.h"
8 #include "base/prefs/pref_registry_simple.h"
9 #include "base/prefs/pref_service.h"
10 #include "base/prefs/scoped_user_pref_update.h"
11 #include "base/strings/string_piece.h"
12 #include "base/strings/utf_string_conversions.h"
13 #include "base/values.h"
14 #include "chrome/browser/browser_process.h"
15 #include "chrome/common/pref_names.h"
16 #include "content/public/browser/browser_thread.h"
19 using content::AccessTokenStore
;
20 using content::BrowserThread
;
24 bool IsUnsupportedNetworkProviderUrl(const GURL
& url
) {
25 const std::string
& spec
= url
.spec();
27 // Unsupported after Chrome v14.
28 if (spec
== "https://www.google.com/loc/json")
31 // Unsupported after Chrome v22.
32 if (spec
== "https://maps.googleapis.com/maps/api/browserlocation/json")
38 // Loads access tokens and other necessary data on the UI thread, and
39 // calls back to the originator on the originating thread.
40 class TokenLoadingJob
: public base::RefCountedThreadSafe
<TokenLoadingJob
> {
43 const AccessTokenStore::LoadAccessTokensCallbackType
& callback
)
44 : callback_(callback
),
45 system_request_context_(NULL
) {
49 BrowserThread::PostTaskAndReply(
52 base::Bind(&TokenLoadingJob::PerformWorkOnUIThread
, this),
53 base::Bind(&TokenLoadingJob::RespondOnOriginatingThread
, this));
57 friend class base::RefCountedThreadSafe
<TokenLoadingJob
>;
61 void PerformWorkOnUIThread() {
62 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
63 DictionaryPrefUpdate
update(g_browser_process
->local_state(),
64 prefs::kGeolocationAccessToken
);
65 base::DictionaryValue
* token_dictionary
= update
.Get();
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 (base::DictionaryValue::Iterator
it(*token_dictionary
); !it
.IsAtEnd();
75 if (IsUnsupportedNetworkProviderUrl(url
)) {
76 providers_to_remove
.push_back(it
.key());
79 it
.value().GetAsString(&access_token_set_
[url
]);
81 for (size_t i
= 0; i
< providers_to_remove
.size(); ++i
) {
82 token_dictionary
->RemoveWithoutPathExpansion(
83 providers_to_remove
[i
], NULL
);
87 system_request_context_
= g_browser_process
->system_request_context();
90 void RespondOnOriginatingThread() {
91 callback_
.Run(access_token_set_
, system_request_context_
);
94 AccessTokenStore::LoadAccessTokensCallbackType callback_
;
95 AccessTokenStore::AccessTokenSet access_token_set_
;
96 net::URLRequestContextGetter
* system_request_context_
;
101 void ChromeAccessTokenStore::RegisterPrefs(PrefRegistrySimple
* registry
) {
102 registry
->RegisterDictionaryPref(prefs::kGeolocationAccessToken
);
105 ChromeAccessTokenStore::ChromeAccessTokenStore() {}
107 void ChromeAccessTokenStore::LoadAccessTokens(
108 const LoadAccessTokensCallbackType
& callback
) {
109 scoped_refptr
<TokenLoadingJob
> job(new TokenLoadingJob(callback
));
113 ChromeAccessTokenStore::~ChromeAccessTokenStore() {}
115 static void SetAccessTokenOnUIThread(const GURL
& server_url
,
116 const base::string16
& token
) {
117 DCHECK_CURRENTLY_ON(BrowserThread::UI
);
118 DictionaryPrefUpdate
update(g_browser_process
->local_state(),
119 prefs::kGeolocationAccessToken
);
120 base::DictionaryValue
* access_token_dictionary
= update
.Get();
121 access_token_dictionary
->SetWithoutPathExpansion(
122 server_url
.spec(), new base::StringValue(token
));
125 void ChromeAccessTokenStore::SaveAccessToken(
126 const GURL
& server_url
,
127 const base::string16
& access_token
) {
128 BrowserThread::PostTask(
129 BrowserThread::UI
, FROM_HERE
,
130 base::Bind(&SetAccessTokenOnUIThread
, server_url
, access_token
));