summaryrefslogtreecommitdiffstats
path: root/chrome/browser/geolocation/access_token_store.cc
diff options
context:
space:
mode:
Diffstat (limited to 'chrome/browser/geolocation/access_token_store.cc')
-rw-r--r--chrome/browser/geolocation/access_token_store.cc155
1 files changed, 131 insertions, 24 deletions
diff --git a/chrome/browser/geolocation/access_token_store.cc b/chrome/browser/geolocation/access_token_store.cc
index 0055103..9c5388f 100644
--- a/chrome/browser/geolocation/access_token_store.cc
+++ b/chrome/browser/geolocation/access_token_store.cc
@@ -7,45 +7,152 @@
#include "base/utf_string_conversions.h"
#include "base/values.h"
#include "chrome/browser/browser_process.h"
+#include "chrome/browser/chrome_thread.h"
#include "chrome/common/pref_names.h"
#include "chrome/common/pref_service.h"
#include "googleurl/src/gurl.h"
namespace {
-// Implementation of the geolocation access token store using chrome's prefs
-// store (local_state) to persist these tokens.
-// TODO(joth): Calls APIs which probably can't be used from the thread that it
-// will be run on; needs prefs access bounced via UI thread.
class ChromePrefsAccessTokenStore : public AccessTokenStore {
public:
+ ChromePrefsAccessTokenStore(
+ const GURL& url, bool token_valid, const string16& initial_access_token);
+
+ private:
// AccessTokenStore
- virtual bool SetAccessToken(const GURL& url,
- const string16& access_token) {
- DictionaryValue* access_token_dictionary =
- g_browser_process->local_state()->GetMutableDictionary(
- prefs::kGeolocationAccessToken);
- access_token_dictionary->SetWithoutPathExpansion(
- UTF8ToWide(url.spec()),
- Value::CreateStringValueFromUTF16(access_token));
- return true;
+ virtual void DoSetAccessToken(const string16& access_token);
+};
+
+
+class ChromePrefsAccessTokenStoreFactory : public AccessTokenStoreFactory {
+ private:
+ void LoadDictionaryStoreInUIThread(ChromeThread::ID client_thread_id,
+ const GURL& default_url);
+ void NotifyDelegateInClientThread(const TokenStoreSet& token_stores);
+
+ // AccessTokenStoreFactory
+ virtual void CreateAccessTokenStores(
+ const base::WeakPtr<AccessTokenStoreFactory::Delegate>& delegate,
+ const GURL& default_url);
+
+ base::WeakPtr<AccessTokenStoreFactory::Delegate> delegate_;
+};
+
+ChromePrefsAccessTokenStore::ChromePrefsAccessTokenStore(
+ const GURL& url, bool token_valid, const string16& initial_access_token)
+ : AccessTokenStore(url, token_valid, initial_access_token) {
+}
+
+void ChromePrefsAccessTokenStore::DoSetAccessToken(
+ const string16& access_token) {
+ if (!ChromeThread::CurrentlyOn(ChromeThread::UI)) {
+ ChromeThread::PostTask(
+ ChromeThread::UI, FROM_HERE, NewRunnableMethod(
+ this, &ChromePrefsAccessTokenStore::DoSetAccessToken,
+ access_token));
+ return;
}
+ DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
+ DictionaryValue* access_token_dictionary =
+ g_browser_process->local_state()->GetMutableDictionary(
+ prefs::kGeolocationAccessToken);
+ access_token_dictionary->SetWithoutPathExpansion(
+ UTF8ToWide(server_url().spec()),
+ Value::CreateStringValueFromUTF16(access_token));
+}
- virtual bool GetAccessToken(const GURL& url, string16* access_token) {
- const DictionaryValue* access_token_dictionary =
- g_browser_process->local_state()->GetDictionary(
- prefs::kGeolocationAccessToken);
- // Careful: The returned value could be NULL if the pref has never been set.
- if (access_token_dictionary == NULL)
- return false;
- return access_token_dictionary->GetStringAsUTF16WithoutPathExpansion(
- UTF8ToWide(url.spec()), access_token);
+void ChromePrefsAccessTokenStoreFactory::LoadDictionaryStoreInUIThread(
+ ChromeThread::ID client_thread_id, const GURL& default_url) {
+ DCHECK(ChromeThread::CurrentlyOn(ChromeThread::UI));
+ const DictionaryValue* token_dictionary =
+ g_browser_process->local_state()->GetDictionary(
+ prefs::kGeolocationAccessToken);
+ TokenStoreSet token_stores;
+ // Careful: The returned value could be NULL if the pref has never been set.
+ if (token_dictionary != NULL) {
+ for (DictionaryValue::key_iterator it = token_dictionary->begin_keys();
+ it != token_dictionary->end_keys(); ++it) {
+ GURL this_url(WideToUTF8(*it));
+ if (!this_url.is_valid())
+ continue;
+ string16 token;
+ const bool token_valid =
+ token_dictionary->GetStringAsUTF16WithoutPathExpansion(*it, &token);
+ token_stores[this_url] =
+ new ChromePrefsAccessTokenStore(this_url, token_valid, token);
+ }
}
-};
+ if (default_url.is_valid() && token_stores[default_url] == NULL) {
+ token_stores[default_url] =
+ new ChromePrefsAccessTokenStore(default_url, false, string16());
+ }
+ ChromeThread::PostTask(
+ client_thread_id, FROM_HERE, NewRunnableMethod(
+ this,
+ &ChromePrefsAccessTokenStoreFactory::NotifyDelegateInClientThread,
+ token_stores));
+}
+void ChromePrefsAccessTokenStoreFactory::NotifyDelegateInClientThread(
+ const TokenStoreSet& token_stores) {
+ if (delegate_ != NULL) {
+ delegate_->OnAccessTokenStoresCreated(token_stores);
+ }
+}
+
+void ChromePrefsAccessTokenStoreFactory::CreateAccessTokenStores(
+ const base::WeakPtr<AccessTokenStoreFactory::Delegate>& delegate,
+ const GURL& default_url) {
+ // Capture the thread that created the factory, in order to make callbacks
+ // on the same thread. We could capture a MessageLoop* but in practice we only
+ // expect to be called from well-known chrome threads, so this is sufficient.
+ ChromeThread::ID client_thread_id;
+ bool ok = ChromeThread::GetCurrentThreadIdentifier(&client_thread_id);
+ CHECK(ok);
+ DCHECK_NE(ChromeThread::UI, client_thread_id)
+ << "If I'm only used from the UI thread I don't need to post tasks";
+ delegate_ = delegate;
+ ChromeThread::PostTask(
+ ChromeThread::UI, FROM_HERE, NewRunnableMethod(
+ this,
+ &ChromePrefsAccessTokenStoreFactory::LoadDictionaryStoreInUIThread,
+ client_thread_id, default_url));
+}
} // namespace
void AccessTokenStore::RegisterPrefs(PrefService* prefs) {
prefs->RegisterDictionaryPref(prefs::kGeolocationAccessToken);
}
-AccessTokenStore* NewChromePrefsAccessTokenStore();
+AccessTokenStore::AccessTokenStore(
+ const GURL& url, bool token_valid, const string16& initial_access_token)
+ : url_(url), access_token_valid_(token_valid),
+ access_token_(initial_access_token) {
+}
+
+AccessTokenStore::~AccessTokenStore() {
+}
+
+GURL AccessTokenStore::server_url() const {
+ return url_;
+}
+
+void AccessTokenStore::SetAccessToken(const string16& access_token) {
+ access_token_ = access_token;
+ access_token_valid_ = true;
+ DoSetAccessToken(access_token);
+}
+
+bool AccessTokenStore::GetAccessToken(string16* access_token) const {
+ DCHECK(access_token);
+ *access_token = access_token_;
+ return access_token_valid_;
+}
+
+AccessTokenStoreFactory::~AccessTokenStoreFactory() {
+}
+
+// Creates a new access token store backed by the global chome prefs.
+AccessTokenStoreFactory* NewChromePrefsAccessTokenStoreFactory() {
+ return new ChromePrefsAccessTokenStoreFactory;
+}