Create separate request context for geolocation service.
authordeepak1556 <hop2deep@gmail.com>
Tue, 14 Mar 2017 15:38:10 +0000 (21:08 +0530)
committerdeepak1556 <hop2deep@gmail.com>
Sat, 18 Mar 2017 19:41:55 +0000 (01:11 +0530)
  * Geolocation service cannot hold reference to browser context,
    since it is destroyed at the end of everything and this will
    confuse the shutdown path of browser context.
  * Geolocation service run on its own thread.

atom/browser/atom_access_token_store.cc
atom/browser/atom_access_token_store.h

index aef54df..6a5597c 100644 (file)
@@ -7,11 +7,13 @@
 #include <string>
 #include <utility>
 
-#include "atom/browser/atom_browser_context.h"
 #include "atom/common/google_api_key.h"
 #include "base/environment.h"
 #include "content/public/browser/browser_thread.h"
 #include "device/geolocation/geolocation_provider.h"
+#include "net/url_request/url_request_context.h"
+#include "net/url_request/url_request_context_builder.h"
+#include "net/url_request/url_request_context_getter.h"
 
 using content::BrowserThread;
 
@@ -19,51 +21,40 @@ namespace atom {
 
 namespace internal {
 
-// 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> {
+class GeoURLRequestContextGetter : public net::URLRequestContextGetter {
  public:
-  explicit TokenLoadingJob(
-      const device::AccessTokenStore::LoadAccessTokensCallback& callback)
-      : callback_(callback), request_context_getter_(nullptr) {}
-
-  void Run(AtomBrowserContext* browser_context) {
-    DCHECK_CURRENTLY_ON(BrowserThread::UI);
-    request_context_getter_ = browser_context->GetRequestContext();
-    std::unique_ptr<base::Environment> env(base::Environment::Create());
-    if (!env->GetVar("GOOGLE_API_KEY", &api_key_))
-      api_key_ = GOOGLEAPIS_API_KEY;
-    BrowserThread::PostTask(
-        BrowserThread::IO, FROM_HERE,
-        base::Bind(&TokenLoadingJob::RespondOnIOThread, this));
+  net::URLRequestContext* GetURLRequestContext() override {
+    DCHECK_CURRENTLY_ON(BrowserThread::IO);
+    if (!url_request_context_.get()) {
+      net::URLRequestContextBuilder builder;
+      builder.set_proxy_config_service(
+          net::ProxyService::CreateSystemProxyConfigService(
+              BrowserThread::GetTaskRunnerForThread(BrowserThread::IO),
+              BrowserThread::GetTaskRunnerForThread(BrowserThread::FILE)));
+      url_request_context_ = builder.Build();
+    }
+    return url_request_context_.get();
   }
 
- private:
-  friend class base::RefCountedThreadSafe<TokenLoadingJob>;
+  scoped_refptr<base::SingleThreadTaskRunner> GetNetworkTaskRunner()
+      const override {
+    return BrowserThread::GetTaskRunnerForThread(BrowserThread::IO);
+  }
 
-  ~TokenLoadingJob() {}
+ private:
+  friend class atom::AtomAccessTokenStore;
 
-  void RespondOnIOThread() {
-    // Equivalent to access_token_map[kGeolocationProviderURL].
-    // Somehow base::string16 is causing compilation errors when used in a pair
-    // of std::map on Linux, this can work around it.
-    device::AccessTokenStore::AccessTokenMap access_token_map;
-    std::pair<GURL, base::string16> token_pair;
-    token_pair.first = GURL(GOOGLEAPIS_ENDPOINT + api_key_);
-    access_token_map.insert(token_pair);
+  GeoURLRequestContextGetter() {}
+  ~GeoURLRequestContextGetter() override {}
 
-    callback_.Run(access_token_map, request_context_getter_);
-  }
-
-  device::AccessTokenStore::LoadAccessTokensCallback callback_;
-  net::URLRequestContextGetter* request_context_getter_;
-  std::string api_key_;
+  std::unique_ptr<net::URLRequestContext> url_request_context_;
+  DISALLOW_COPY_AND_ASSIGN(GeoURLRequestContextGetter);
 };
 
 }  // namespace internal
 
-AtomAccessTokenStore::AtomAccessTokenStore() {
-  browser_context_ = AtomBrowserContext::From("", false);
+AtomAccessTokenStore::AtomAccessTokenStore()
+    : request_context_getter_(new internal::GeoURLRequestContextGetter) {
   device::GeolocationProvider::GetInstance()->UserDidOptIntoLocationServices();
 }
 
@@ -72,16 +63,19 @@ AtomAccessTokenStore::~AtomAccessTokenStore() {
 
 void AtomAccessTokenStore::LoadAccessTokens(
     const LoadAccessTokensCallback& callback) {
-  scoped_refptr<internal::TokenLoadingJob> job(
-      new internal::TokenLoadingJob(callback));
-  BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
-                          base::Bind(&AtomAccessTokenStore::RunTokenLoadingJob,
-                                     this, base::RetainedRef(job)));
-}
-
-void AtomAccessTokenStore::RunTokenLoadingJob(
-    scoped_refptr<internal::TokenLoadingJob> job) {
-  job->Run(browser_context_.get());
+  std::unique_ptr<base::Environment> env(base::Environment::Create());
+  std::string api_key;
+  if (!env->GetVar("GOOGLE_API_KEY", &api_key))
+    api_key = GOOGLEAPIS_API_KEY;
+  // Equivalent to access_token_map[kGeolocationProviderURL].
+  // Somehow base::string16 is causing compilation errors when used in a pair
+  // of std::map on Linux, this can work around it.
+  device::AccessTokenStore::AccessTokenMap access_token_map;
+  std::pair<GURL, base::string16> token_pair;
+  token_pair.first = GURL(GOOGLEAPIS_ENDPOINT + api_key);
+  access_token_map.insert(token_pair);
+
+  callback.Run(access_token_map, request_context_getter_.get());
 }
 
 void AtomAccessTokenStore::SaveAccessToken(const GURL& server_url,
index 07884e5..820cedd 100644 (file)
@@ -9,10 +9,8 @@
 
 namespace atom {
 
-class AtomBrowserContext;
-
 namespace internal {
-class TokenLoadingJob;
+class GeoURLRequestContextGetter;
 }
 
 class AtomAccessTokenStore : public device::AccessTokenStore {
@@ -27,9 +25,7 @@ class AtomAccessTokenStore : public device::AccessTokenStore {
                        const base::string16& access_token) override;
 
  private:
-  void RunTokenLoadingJob(scoped_refptr<internal::TokenLoadingJob> job);
-
-  scoped_refptr<AtomBrowserContext> browser_context_;
+  scoped_refptr<internal::GeoURLRequestContextGetter> request_context_getter_;
   DISALLOW_COPY_AND_ASSIGN(AtomAccessTokenStore);
 };