summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorjam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-05-12 16:36:10 +0000
committerjam@chromium.org <jam@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-05-12 16:36:10 +0000
commitf28ef9a32852ef01e582ebafe0b7dca0d1f6e761 (patch)
tree28bc372258cafa54475ff8a3f5604655b055c0cb
parentc831e9c6e946328048680b4bdaf4a80eb8e8d622 (diff)
downloadchromium_src-f28ef9a32852ef01e582ebafe0b7dca0d1f6e761.zip
chromium_src-f28ef9a32852ef01e582ebafe0b7dca0d1f6e761.tar.gz
chromium_src-f28ef9a32852ef01e582ebafe0b7dca0d1f6e761.tar.bz2
Dispatch geolocation IPCs on the UI thread. Aside from simplifying the code to avoid a lot of thread hops, this sets things up for converting the code to work on RenderFrames instead of RenderViews.
In the process I also switched the code to use CallbackList which simplifies the registration. BUG=304341 R=benm@chromium.org, brettw@chromium.org, bulach@chromium.org, caitkp@chromium.org, isherman@chromium.org, mvanouwerkerk@chromium.org, nasko@chromium.org Review URL: https://codereview.chromium.org/273523007 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@269795 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--android_webview/native/aw_contents.cc2
-rw-r--r--android_webview/native/aw_geolocation_permission_context.cc62
-rw-r--r--android_webview/native/aw_geolocation_permission_context.h19
-rw-r--r--base/callback_list.h30
-rw-r--r--base/callback_list.h.pump30
-rw-r--r--chrome/browser/chromeos/policy/device_status_collector.cc68
-rw-r--r--chrome/browser/chromeos/policy/device_status_collector.h33
-rw-r--r--chrome/browser/extensions/api/location/location_manager.cc96
-rw-r--r--chrome/browser/extensions/api/location/location_manager.h4
-rw-r--r--chrome/browser/geolocation/chrome_geolocation_permission_context.cc43
-rw-r--r--chrome/browser/geolocation/chrome_geolocation_permission_context.h6
-rw-r--r--chrome/browser/geolocation/chrome_geolocation_permission_context_unittest.cc68
-rw-r--r--chrome/browser/guest_view/web_view/web_view_guest.cc3
-rw-r--r--chrome/browser/ui/autofill/autofill_dialog_controller_impl.cc12
-rw-r--r--chrome/test/base/ui_test_utils.cc9
-rw-r--r--components/autofill/content/browser/risk/fingerprint.cc84
-rw-r--r--components/autofill/content/browser/risk/fingerprint_browsertest.cc7
-rw-r--r--content/browser/android/content_view_core_impl.cc22
-rw-r--r--content/browser/android/content_view_core_impl.h3
-rw-r--r--content/browser/geolocation/geolocation_dispatcher_host.cc176
-rw-r--r--content/browser/geolocation/geolocation_dispatcher_host.h77
-rw-r--r--content/browser/geolocation/geolocation_provider_impl.cc121
-rw-r--r--content/browser/geolocation/geolocation_provider_impl.h37
-rw-r--r--content/browser/geolocation/geolocation_provider_unittest.cc35
-rw-r--r--content/browser/renderer_host/render_process_host_impl.cc6
-rw-r--r--content/browser/renderer_host/render_process_host_impl.h10
-rw-r--r--content/browser/renderer_host/render_widget_host_view_android.cc1
-rw-r--r--content/browser/web_contents/aura/gesture_nav_simple.cc1
-rw-r--r--content/browser/web_contents/aura/overscroll_navigation_overlay.cc1
-rw-r--r--content/browser/web_contents/web_contents_impl.cc4
-rw-r--r--content/browser/web_contents/web_contents_impl.h7
-rw-r--r--content/common/geolocation_messages.h29
-rw-r--r--content/public/browser/geolocation_permission_context.h7
-rw-r--r--content/public/browser/geolocation_provider.h47
34 files changed, 364 insertions, 796 deletions
diff --git a/android_webview/native/aw_contents.cc b/android_webview/native/aw_contents.cc
index 2cfdcd5..6762e78 100644
--- a/android_webview/native/aw_contents.cc
+++ b/android_webview/native/aw_contents.cc
@@ -135,12 +135,12 @@ void OnIoThreadClientReady(content::RenderFrameHost* rfh) {
// static
AwContents* AwContents::FromWebContents(WebContents* web_contents) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
return AwContentsUserData::GetContents(web_contents);
}
// static
AwContents* AwContents::FromID(int render_process_id, int render_view_id) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
const content::RenderViewHost* rvh =
content::RenderViewHost::FromID(render_process_id, render_view_id);
if (!rvh) return NULL;
diff --git a/android_webview/native/aw_geolocation_permission_context.cc b/android_webview/native/aw_geolocation_permission_context.cc
index b68608a..11d9140 100644
--- a/android_webview/native/aw_geolocation_permission_context.cc
+++ b/android_webview/native/aw_geolocation_permission_context.cc
@@ -16,18 +16,13 @@ namespace android_webview {
AwGeolocationPermissionContext::~AwGeolocationPermissionContext() {
}
-void
-AwGeolocationPermissionContext::RequestGeolocationPermissionOnUIThread(
- int render_process_id,
- int render_view_id,
+void AwGeolocationPermissionContext::RequestGeolocationPermission(
+ content::WebContents* web_contents,
int bridge_id,
const GURL& requesting_frame,
bool user_gesture,
base::Callback<void(bool)> callback) {
- DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
-
- AwContents* aw_contents =
- AwContents::FromID(render_process_id, render_view_id);
+ AwContents* aw_contents = AwContents::FromWebContents(web_contents);
if (!aw_contents) {
callback.Run(false);
return;
@@ -35,65 +30,20 @@ AwGeolocationPermissionContext::RequestGeolocationPermissionOnUIThread(
aw_contents->ShowGeolocationPrompt(requesting_frame, callback);
}
-void
-AwGeolocationPermissionContext::RequestGeolocationPermission(
- int render_process_id,
- int render_view_id,
- int bridge_id,
- const GURL& requesting_frame,
- bool user_gesture,
- base::Callback<void(bool)> callback) {
- content::BrowserThread::PostTask(
- content::BrowserThread::UI, FROM_HERE,
- base::Bind(
- &AwGeolocationPermissionContext::
- RequestGeolocationPermissionOnUIThread,
- this,
- render_process_id,
- render_view_id,
- bridge_id,
- requesting_frame,
- user_gesture,
- callback));
-}
-
// static
content::GeolocationPermissionContext*
AwGeolocationPermissionContext::Create(AwBrowserContext* browser_context) {
return new AwGeolocationPermissionContext();
}
-void
-AwGeolocationPermissionContext::CancelGeolocationPermissionRequestOnUIThread(
- int render_process_id,
- int render_view_id,
+void AwGeolocationPermissionContext::CancelGeolocationPermissionRequest(
+ content::WebContents* web_contents,
int bridge_id,
const GURL& requesting_frame) {
- DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
-
- AwContents* aw_contents =
- AwContents::FromID(render_process_id, render_view_id);
+ AwContents* aw_contents = AwContents::FromWebContents(web_contents);
if (aw_contents) {
aw_contents->HideGeolocationPrompt(requesting_frame);
}
}
-void
-AwGeolocationPermissionContext::CancelGeolocationPermissionRequest(
- int render_process_id,
- int render_view_id,
- int bridge_id,
- const GURL& requesting_frame) {
- content::BrowserThread::PostTask(
- content::BrowserThread::UI, FROM_HERE,
- base::Bind(
- &AwGeolocationPermissionContext::
- CancelGeolocationPermissionRequestOnUIThread,
- this,
- render_process_id,
- render_view_id,
- bridge_id,
- requesting_frame));
-}
-
} // namespace android_webview
diff --git a/android_webview/native/aw_geolocation_permission_context.h b/android_webview/native/aw_geolocation_permission_context.h
index 18439fb..2ad18a6 100644
--- a/android_webview/native/aw_geolocation_permission_context.h
+++ b/android_webview/native/aw_geolocation_permission_context.h
@@ -21,15 +21,13 @@ class AwGeolocationPermissionContext :
// content::GeolocationPermissionContext implementation
virtual void RequestGeolocationPermission(
- int render_process_id,
- int render_view_id,
+ content::WebContents* web_contents,
int bridge_id,
const GURL& requesting_frame,
bool user_gesture,
base::Callback<void(bool)> callback) OVERRIDE;
virtual void CancelGeolocationPermissionRequest(
- int render_process_id,
- int render_view_id,
+ content::WebContents* web_contents,
int bridge_id,
const GURL& requesting_frame) OVERRIDE;
@@ -37,19 +35,6 @@ class AwGeolocationPermissionContext :
virtual ~AwGeolocationPermissionContext();
private:
- void RequestGeolocationPermissionOnUIThread(
- int render_process_id,
- int render_view_id,
- int bridge_id,
- const GURL& requesting_frame,
- bool user_gesture,
- base::Callback<void(bool)> callback);
-
- void CancelGeolocationPermissionRequestOnUIThread(
- int render_process_id,
- int render_view_id,
- int bridge_id,
- const GURL& requesting_frame);
};
} // namespace android_webview
diff --git a/base/callback_list.h b/base/callback_list.h
index d12a1e9..5b911fd 100644
--- a/base/callback_list.h
+++ b/base/callback_list.h
@@ -89,10 +89,13 @@ class CallbackListBase {
}
~Subscription() {
- if (list_->active_iterator_count_)
+ if (list_->active_iterator_count_) {
iter_->Reset();
- else
+ } else {
list_->callbacks_.erase(iter_);
+ if (!list_->removal_callback_.is_null())
+ list_->removal_callback_.Run();
+ }
}
private:
@@ -111,6 +114,18 @@ class CallbackListBase {
new Subscription(this, callbacks_.insert(callbacks_.end(), cb)));
}
+ // Sets a callback which will be run when a subscription list is changed.
+ void set_removal_callback(const Closure& callback) {
+ removal_callback_ = callback;
+ }
+
+ // Returns true if there are no subscriptions. This is only valid to call when
+ // not looping through the list.
+ bool empty() {
+ DCHECK_EQ(0, active_iterator_count_);
+ return callbacks_.empty();
+ }
+
protected:
// An iterator class that can be used to access the list of callbacks.
class Iterator {
@@ -167,17 +182,24 @@ class CallbackListBase {
// iteration.
void Compact() {
typename std::list<CallbackType>::iterator it = callbacks_.begin();
+ bool updated = false;
while (it != callbacks_.end()) {
- if ((*it).is_null())
+ if ((*it).is_null()) {
+ updated = true;
it = callbacks_.erase(it);
- else
+ } else {
++it;
+ }
+
+ if (updated && !removal_callback_.is_null())
+ removal_callback_.Run();
}
}
private:
std::list<CallbackType> callbacks_;
int active_iterator_count_;
+ Closure removal_callback_;
DISALLOW_COPY_AND_ASSIGN(CallbackListBase);
};
diff --git a/base/callback_list.h.pump b/base/callback_list.h.pump
index ea2103e..d7f84736 100644
--- a/base/callback_list.h.pump
+++ b/base/callback_list.h.pump
@@ -94,10 +94,13 @@ class CallbackListBase {
}
~Subscription() {
- if (list_->active_iterator_count_)
+ if (list_->active_iterator_count_) {
iter_->Reset();
- else
+ } else {
list_->callbacks_.erase(iter_);
+ if (!list_->removal_callback_.is_null())
+ list_->removal_callback_.Run();
+ }
}
private:
@@ -116,6 +119,18 @@ class CallbackListBase {
new Subscription(this, callbacks_.insert(callbacks_.end(), cb)));
}
+ // Sets a callback which will be run when a subscription list is changed.
+ void set_removal_callback(const Closure& callback) {
+ removal_callback_ = callback;
+ }
+
+ // Returns true if there are no subscriptions. This is only valid to call when
+ // not looping through the list.
+ bool empty() {
+ DCHECK_EQ(0, active_iterator_count_);
+ return callbacks_.empty();
+ }
+
protected:
// An iterator class that can be used to access the list of callbacks.
class Iterator {
@@ -172,17 +187,24 @@ class CallbackListBase {
// iteration.
void Compact() {
typename std::list<CallbackType>::iterator it = callbacks_.begin();
+ bool updated = false;
while (it != callbacks_.end()) {
- if ((*it).is_null())
+ if ((*it).is_null()) {
+ updated = true;
it = callbacks_.erase(it);
- else
+ } else {
++it;
+ }
+
+ if (updated && !removal_callback_.is_null())
+ removal_callback_.Run();
}
}
private:
std::list<CallbackType> callbacks_;
int active_iterator_count_;
+ Closure removal_callback_;
DISALLOW_COPY_AND_ASSIGN(CallbackListBase);
};
diff --git a/chrome/browser/chromeos/policy/device_status_collector.cc b/chrome/browser/chromeos/policy/device_status_collector.cc
index b160744..d5936f1 100644
--- a/chrome/browser/chromeos/policy/device_status_collector.cc
+++ b/chrome/browser/chromeos/policy/device_status_collector.cc
@@ -81,47 +81,6 @@ const int kMaxUserCount = 5;
namespace policy {
-DeviceStatusCollector::Context::Context() {
-}
-
-DeviceStatusCollector::Context::~Context() {
-}
-
-void DeviceStatusCollector::Context::GetLocationUpdate(
- const content::GeolocationProvider::LocationUpdateCallback& callback) {
- owner_callback_ = callback;
- content::BrowserThread::PostTask(
- content::BrowserThread::IO,
- FROM_HERE,
- base::Bind(&DeviceStatusCollector::Context::GetLocationUpdateInternal,
- this));
-}
-
-void DeviceStatusCollector::Context::GetLocationUpdateInternal() {
- our_callback_ = base::Bind(
- &DeviceStatusCollector::Context::OnLocationUpdate, this);
- content::GeolocationProvider::GetInstance()->AddLocationUpdateCallback(
- our_callback_, true);
-}
-
-void DeviceStatusCollector::Context::OnLocationUpdate(
- const content::Geoposition& geoposition) {
- content::GeolocationProvider::GetInstance()->RemoveLocationUpdateCallback(
- our_callback_);
- our_callback_.Reset();
- content::BrowserThread::PostTask(
- content::BrowserThread::UI,
- FROM_HERE,
- base::Bind(&DeviceStatusCollector::Context::CallCollector,
- this, geoposition));
-}
-
-void DeviceStatusCollector::Context::CallCollector(
- const content::Geoposition& geoposition) {
- owner_callback_.Run(geoposition);
- owner_callback_.Reset();
-}
-
DeviceStatusCollector::DeviceStatusCollector(
PrefService* local_state,
chromeos::system::StatisticsProvider* provider,
@@ -140,14 +99,9 @@ DeviceStatusCollector::DeviceStatusCollector(
report_boot_mode_(false),
report_location_(false),
report_network_interfaces_(false),
- report_users_(false),
- context_(new Context()) {
- if (location_update_requester) {
+ report_users_(false) {
+ if (location_update_requester)
location_update_requester_ = *location_update_requester;
- } else {
- location_update_requester_ =
- base::Bind(&Context::GetLocationUpdate, context_.get());
- }
idle_poll_timer_.Start(FROM_HERE,
TimeDelta::FromSeconds(kIdlePollIntervalSeconds),
this, &DeviceStatusCollector::CheckIdleState);
@@ -552,20 +506,24 @@ void DeviceStatusCollector::ScheduleGeolocationUpdateRequest() {
TimeDelta elapsed = GetCurrentTime() - position_.timestamp;
TimeDelta interval =
TimeDelta::FromSeconds(kGeolocationPollIntervalSeconds);
- if (elapsed > interval) {
- geolocation_update_in_progress_ = true;
- location_update_requester_.Run(base::Bind(
- &DeviceStatusCollector::ReceiveGeolocationUpdate,
- weak_factory_.GetWeakPtr()));
- } else {
+ if (elapsed <= interval) {
geolocation_update_timer_.Start(
FROM_HERE,
interval - elapsed,
this,
&DeviceStatusCollector::ScheduleGeolocationUpdateRequest);
+ return;
}
+ }
+
+ geolocation_update_in_progress_ = true;
+ if (location_update_requester_.is_null()) {
+ geolocation_subscription_ = content::GeolocationProvider::GetInstance()->
+ AddLocationUpdateCallback(
+ base::Bind(&DeviceStatusCollector::ReceiveGeolocationUpdate,
+ weak_factory_.GetWeakPtr()),
+ true);
} else {
- geolocation_update_in_progress_ = true;
location_update_requester_.Run(base::Bind(
&DeviceStatusCollector::ReceiveGeolocationUpdate,
weak_factory_.GetWeakPtr()));
diff --git a/chrome/browser/chromeos/policy/device_status_collector.h b/chrome/browser/chromeos/policy/device_status_collector.h
index a787721..d4f70fe 100644
--- a/chrome/browser/chromeos/policy/device_status_collector.h
+++ b/chrome/browser/chromeos/policy/device_status_collector.h
@@ -8,7 +8,7 @@
#include <string>
#include "base/basictypes.h"
-#include "base/callback_forward.h"
+#include "base/callback_list.h"
#include "base/compiler_specific.h"
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
@@ -93,32 +93,6 @@ class DeviceStatusCollector : public CloudPolicyClient::StatusProvider {
unsigned int max_stored_future_activity_days_;
private:
- // A helper class to manage receiving geolocation callbacks on the IO
- // thread.
- class Context : public base::RefCountedThreadSafe<Context> {
- public:
- Context();
-
- void GetLocationUpdate(
- const content::GeolocationProvider::LocationUpdateCallback& callback);
-
- private:
- friend class base::RefCountedThreadSafe<Context>;
-
- ~Context();
-
- void GetLocationUpdateInternal();
- void OnLocationUpdate(const content::Geoposition& geoposition);
- void CallCollector(const content::Geoposition& geoposition);
-
- // The callback which this class registers with
- // content::GeolocationProvider.
- content::GeolocationProvider::LocationUpdateCallback our_callback_;
-
- // The callback passed in to GetLocationUpdate.
- content::GeolocationProvider::LocationUpdateCallback owner_callback_;
- };
-
// Prevents the local store of activity periods from growing too large by
// removing entries that are outside the reporting window.
void PruneStoredActivityPeriods(base::Time base_time);
@@ -197,6 +171,9 @@ class DeviceStatusCollector : public CloudPolicyClient::StatusProvider {
// way to mock geolocation exists.
LocationUpdateRequester location_update_requester_;
+ scoped_ptr<content::GeolocationProvider::Subscription>
+ geolocation_subscription_;
+
// Cached values of the reporting settings from the device policy.
bool report_version_info_;
bool report_activity_times_;
@@ -205,8 +182,6 @@ class DeviceStatusCollector : public CloudPolicyClient::StatusProvider {
bool report_network_interfaces_;
bool report_users_;
- scoped_refptr<Context> context_;
-
scoped_ptr<chromeos::CrosSettings::ObserverSubscription>
version_info_subscription_;
scoped_ptr<chromeos::CrosSettings::ObserverSubscription>
diff --git a/chrome/browser/extensions/api/location/location_manager.cc b/chrome/browser/extensions/api/location/location_manager.cc
index 38a7cf0..b436e9e 100644
--- a/chrome/browser/extensions/api/location/location_manager.cc
+++ b/chrome/browser/extensions/api/location/location_manager.cc
@@ -140,40 +140,20 @@ class TimeBasedUpdatePolicy : public UpdatePolicy {
} // namespace updatepolicy
// Request created by chrome.location.watchLocation() call.
-// Lives in the IO thread, except for the constructor.
-class LocationRequest
- : public base::RefCountedThreadSafe<LocationRequest,
- BrowserThread::DeleteOnIOThread> {
+class LocationRequest : public base::RefCounted<LocationRequest> {
public:
LocationRequest(
- const base::WeakPtr<LocationManager>& location_manager,
+ LocationManager* location_manager,
const std::string& extension_id,
const std::string& request_name,
const double* distance_update_threshold_meters,
const double* time_between_updates_ms);
- // Finishes the necessary setup for this object.
- // Call this method immediately after taking a strong reference
- // to this object.
- //
- // Ideally, we would do this at construction time, but currently
- // our refcount starts at zero. BrowserThread::PostTask will take a ref
- // and potentially release it before we are done, destroying us in the
- // constructor.
- void Initialize();
-
const std::string& request_name() const { return request_name_; }
- // Grants permission for using geolocation.
- static void GrantPermission();
-
private:
- friend class base::DeleteHelper<LocationRequest>;
- friend struct BrowserThread::DeleteOnThread<BrowserThread::IO>;
-
- virtual ~LocationRequest();
-
- void AddObserverOnIOThread();
+ friend class base::RefCounted<LocationRequest>;
+ ~LocationRequest();
void OnLocationUpdate(const content::Geoposition& position);
@@ -191,20 +171,21 @@ class LocationRequest
const std::string extension_id_;
// Owning location manager.
- const base::WeakPtr<LocationManager> location_manager_;
+ LocationManager* location_manager_;
// Holds Update Policies.
typedef std::vector<scoped_refptr<updatepolicy::UpdatePolicy> >
UpdatePolicyVector;
UpdatePolicyVector update_policies_;
- content::GeolocationProvider::LocationUpdateCallback callback_;
+ scoped_ptr<content::GeolocationProvider::Subscription>
+ geolocation_subscription_;
DISALLOW_COPY_AND_ASSIGN(LocationRequest);
};
LocationRequest::LocationRequest(
- const base::WeakPtr<LocationManager>& location_manager,
+ LocationManager* location_manager,
const std::string& extension_id,
const std::string& request_name,
const double* distance_update_threshold_meters,
@@ -213,8 +194,6 @@ LocationRequest::LocationRequest(
extension_id_(extension_id),
location_manager_(location_manager) {
// TODO(vadimt): use request_info.
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
-
if (time_between_updates_ms) {
update_policies_.push_back(
new updatepolicy::TimeBasedUpdatePolicy(
@@ -226,58 +205,29 @@ LocationRequest::LocationRequest(
new updatepolicy::DistanceBasedUpdatePolicy(
*distance_update_threshold_meters));
}
-}
-
-void LocationRequest::Initialize() {
- DCHECK_CURRENTLY_ON(BrowserThread::UI);
- callback_ = base::Bind(&LocationRequest::OnLocationUpdate,
- base::Unretained(this));
-
- BrowserThread::PostTask(
- BrowserThread::IO,
- FROM_HERE,
- base::Bind(&LocationRequest::AddObserverOnIOThread,
- this));
-}
-
-void LocationRequest::GrantPermission() {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
- content::GeolocationProvider::GetInstance()->UserDidOptIntoLocationServices();
-}
-
-LocationRequest::~LocationRequest() {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
- content::GeolocationProvider::GetInstance()->RemoveLocationUpdateCallback(
- callback_);
-}
-
-void LocationRequest::AddObserverOnIOThread() {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
// TODO(vadimt): This can get a location cached by GeolocationProvider,
// contrary to the API definition which says that creating a location watch
// will get new location.
- content::GeolocationProvider::GetInstance()->AddLocationUpdateCallback(
- callback_, true);
+ geolocation_subscription_ = content::GeolocationProvider::GetInstance()->
+ AddLocationUpdateCallback(
+ base::Bind(&LocationRequest::OnLocationUpdate,
+ base::Unretained(this)),
+ true);
+}
+
+LocationRequest::~LocationRequest() {
}
void LocationRequest::OnLocationUpdate(const content::Geoposition& position) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
if (ShouldSendUpdate(position)) {
OnPositionReported(position);
- BrowserThread::PostTask(
- BrowserThread::UI,
- FROM_HERE,
- base::Bind(&LocationManager::SendLocationUpdate,
- location_manager_,
- extension_id_,
- request_name_,
- position));
+ location_manager_->SendLocationUpdate(
+ extension_id_, request_name_, position);
}
}
bool LocationRequest::ShouldSendUpdate(const content::Geoposition& position) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
for (UpdatePolicyVector::iterator it = update_policies_.begin();
it != update_policies_.end();
++it) {
@@ -289,7 +239,6 @@ bool LocationRequest::ShouldSendUpdate(const content::Geoposition& position) {
}
void LocationRequest::OnPositionReported(const content::Geoposition& position) {
- DCHECK_CURRENTLY_ON(BrowserThread::IO);
for (UpdatePolicyVector::iterator it = update_policies_.begin();
it != update_policies_.end();
++it) {
@@ -318,12 +267,11 @@ void LocationManager::AddLocationRequest(
RemoveLocationRequest(extension_id, request_name);
LocationRequestPointer location_request =
- new LocationRequest(AsWeakPtr(),
+ new LocationRequest(this,
extension_id,
request_name,
distance_update_threshold_meters,
time_between_updates_ms);
- location_request->Initialize();
location_requests_.insert(
LocationRequestMap::value_type(extension_id, location_request));
}
@@ -411,10 +359,8 @@ void LocationManager::Observe(int type,
content::Details<const Extension>(details).ptr();
if (extension->HasAPIPermission(APIPermission::kLocation)) {
- BrowserThread::PostTask(
- BrowserThread::IO,
- FROM_HERE,
- base::Bind(&LocationRequest::GrantPermission));
+ content::GeolocationProvider::GetInstance()->
+ UserDidOptIntoLocationServices();
}
break;
}
diff --git a/chrome/browser/extensions/api/location/location_manager.h b/chrome/browser/extensions/api/location/location_manager.h
index db23a9a..233fa22 100644
--- a/chrome/browser/extensions/api/location/location_manager.h
+++ b/chrome/browser/extensions/api/location/location_manager.h
@@ -8,7 +8,6 @@
#include <map>
#include <string>
-#include "base/memory/weak_ptr.h"
#include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_registrar.h"
#include "extensions/browser/browser_context_keyed_api_factory.h"
@@ -35,8 +34,7 @@ struct Coordinates;
// Profile's manager of all location watch requests created by chrome.location
// API. Lives in the UI thread.
class LocationManager : public BrowserContextKeyedAPI,
- public content::NotificationObserver,
- public base::SupportsWeakPtr<LocationManager> {
+ public content::NotificationObserver {
public:
explicit LocationManager(content::BrowserContext* context);
virtual ~LocationManager();
diff --git a/chrome/browser/geolocation/chrome_geolocation_permission_context.cc b/chrome/browser/geolocation/chrome_geolocation_permission_context.cc
index f5507c7..37d0326 100644
--- a/chrome/browser/geolocation/chrome_geolocation_permission_context.cc
+++ b/chrome/browser/geolocation/chrome_geolocation_permission_context.cc
@@ -22,6 +22,7 @@
#include "chrome/browser/ui/website_settings/permission_bubble_request.h"
#include "chrome/common/pref_names.h"
#include "content/public/browser/browser_thread.h"
+#include "content/public/browser/render_process_host.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/browser/web_contents.h"
#include "extensions/browser/extension_registry.h"
@@ -135,30 +136,15 @@ ChromeGeolocationPermissionContext::~ChromeGeolocationPermissionContext() {
}
void ChromeGeolocationPermissionContext::RequestGeolocationPermission(
- int render_process_id,
- int render_view_id,
+ content::WebContents* web_contents,
int bridge_id,
const GURL& requesting_frame,
bool user_gesture,
base::Callback<void(bool)> callback) {
GURL requesting_frame_origin = requesting_frame.GetOrigin();
- if (!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)) {
- content::BrowserThread::PostTask(
- content::BrowserThread::UI, FROM_HERE,
- base::Bind(
- &ChromeGeolocationPermissionContext::RequestGeolocationPermission,
- this, render_process_id, render_view_id, bridge_id,
- requesting_frame_origin, user_gesture, callback));
- return;
- }
-
- DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
if (shutting_down_)
return;
- content::WebContents* web_contents =
- tab_util::GetWebContentsByID(render_process_id, render_view_id);
-
WebViewGuest* guest = WebViewGuest::FromWebContents(web_contents);
if (guest) {
guest->RequestGeolocationPermission(bridge_id,
@@ -167,6 +153,9 @@ void ChromeGeolocationPermissionContext::RequestGeolocationPermission(
callback);
return;
}
+
+ int render_process_id = web_contents->GetRenderProcessHost()->GetID();
+ int render_view_id = web_contents->GetRenderViewHost()->GetRoutingID();
const PermissionRequestID id(render_process_id, render_view_id, bridge_id, 0);
ExtensionRegistry* extension_registry = ExtensionRegistry::Get(profile_);
if (extension_registry) {
@@ -212,27 +201,9 @@ void ChromeGeolocationPermissionContext::RequestGeolocationPermission(
}
void ChromeGeolocationPermissionContext::CancelGeolocationPermissionRequest(
- int render_process_id,
- int render_view_id,
+ content::WebContents* web_contents,
int bridge_id,
const GURL& requesting_frame) {
- if (!content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)) {
- content::BrowserThread::PostTask(
- content::BrowserThread::UI, FROM_HERE,
- base::Bind(
- &ChromeGeolocationPermissionContext::
- CancelGeolocationPermissionRequest,
- this,
- render_process_id,
- render_view_id,
- bridge_id,
- requesting_frame));
- return;
- }
-
- DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI));
- content::WebContents* web_contents =
- tab_util::GetWebContentsByID(render_process_id, render_view_id);
WebViewGuest* guest =
web_contents ? WebViewGuest::FromWebContents(web_contents) : NULL;
if (guest) {
@@ -240,6 +211,8 @@ void ChromeGeolocationPermissionContext::CancelGeolocationPermissionRequest(
return;
}
// TODO(gbillock): cancel permission bubble request.
+ int render_process_id = web_contents->GetRenderProcessHost()->GetID();
+ int render_view_id = web_contents->GetRenderViewHost()->GetRoutingID();
CancelPendingInfobarRequest(PermissionRequestID(
render_process_id, render_view_id, bridge_id, 0));
}
diff --git a/chrome/browser/geolocation/chrome_geolocation_permission_context.h b/chrome/browser/geolocation/chrome_geolocation_permission_context.h
index e590923..38552c8 100644
--- a/chrome/browser/geolocation/chrome_geolocation_permission_context.h
+++ b/chrome/browser/geolocation/chrome_geolocation_permission_context.h
@@ -28,15 +28,13 @@ class ChromeGeolocationPermissionContext
// GeolocationPermissionContext:
virtual void RequestGeolocationPermission(
- int render_process_id,
- int render_view_id,
+ content::WebContents* web_contents,
int bridge_id,
const GURL& requesting_frame,
bool user_gesture,
base::Callback<void(bool)> callback) OVERRIDE;
virtual void CancelGeolocationPermissionRequest(
- int render_process_id,
- int render_view_id,
+ content::WebContents* web_contents,
int bridge_id,
const GURL& requesting_frame) OVERRIDE;
diff --git a/chrome/browser/geolocation/chrome_geolocation_permission_context_unittest.cc b/chrome/browser/geolocation/chrome_geolocation_permission_context_unittest.cc
index 5b796fd..9f8d16f 100644
--- a/chrome/browser/geolocation/chrome_geolocation_permission_context_unittest.cc
+++ b/chrome/browser/geolocation/chrome_geolocation_permission_context_unittest.cc
@@ -112,9 +112,11 @@ class GeolocationPermissionContextTests
return InfoBarService::FromWebContents(extra_tabs_[tab]);
}
- void RequestGeolocationPermission(const PermissionRequestID& id,
+ void RequestGeolocationPermission(content::WebContents* web_contents,
+ const PermissionRequestID& id,
const GURL& requesting_frame);
- void CancelGeolocationPermissionRequest(const PermissionRequestID& id,
+ void CancelGeolocationPermissionRequest(content::WebContents* web_contents,
+ const PermissionRequestID& id,
const GURL& requesting_frame);
void PermissionResponse(const PermissionRequestID& id,
bool allowed);
@@ -157,11 +159,11 @@ PermissionRequestID GeolocationPermissionContextTests::RequestIDForTab(
}
void GeolocationPermissionContextTests::RequestGeolocationPermission(
+ content::WebContents* web_contents,
const PermissionRequestID& id,
const GURL& requesting_frame) {
geolocation_permission_context_->RequestGeolocationPermission(
- id.render_process_id(), id.render_view_id(), id.bridge_id(),
- requesting_frame, false,
+ web_contents, id.bridge_id(), requesting_frame, false,
base::Bind(&GeolocationPermissionContextTests::PermissionResponse,
base::Unretained(this), id));
content::BrowserThread::GetBlockingPool()->FlushForTesting();
@@ -169,11 +171,11 @@ void GeolocationPermissionContextTests::RequestGeolocationPermission(
}
void GeolocationPermissionContextTests::CancelGeolocationPermissionRequest(
+ content::WebContents* web_contents,
const PermissionRequestID& id,
const GURL& requesting_frame) {
geolocation_permission_context_->CancelGeolocationPermissionRequest(
- id.render_process_id(), id.render_view_id(), id.bridge_id(),
- requesting_frame);
+ web_contents, id.bridge_id(), requesting_frame);
}
void GeolocationPermissionContextTests::PermissionResponse(
@@ -263,7 +265,7 @@ TEST_F(GeolocationPermissionContextTests, SinglePermission) {
GURL requesting_frame("http://www.example.com/geolocation");
NavigateAndCommit(requesting_frame);
EXPECT_EQ(0U, infobar_service()->infobar_count());
- RequestGeolocationPermission(RequestID(0), requesting_frame);
+ RequestGeolocationPermission(web_contents(), RequestID(0), requesting_frame);
ASSERT_EQ(1U, infobar_service()->infobar_count());
infobars::InfoBar* infobar = infobar_service()->infobar_at(0);
ConfirmInfoBarDelegate* infobar_delegate =
@@ -281,7 +283,7 @@ TEST_F(GeolocationPermissionContextTests, GeolocationEnabledDisabled) {
NavigateAndCommit(requesting_frame);
MockGoogleLocationSettingsHelper::SetLocationStatus(true, true);
EXPECT_EQ(0U, infobar_service()->infobar_count());
- RequestGeolocationPermission(RequestID(0), requesting_frame);
+ RequestGeolocationPermission(web_contents(), RequestID(0), requesting_frame);
EXPECT_EQ(1U, infobar_service()->infobar_count());
ConfirmInfoBarDelegate* infobar_delegate_0 =
infobar_service()->infobar_at(0)->delegate()->AsConfirmInfoBarDelegate();
@@ -292,7 +294,7 @@ TEST_F(GeolocationPermissionContextTests, GeolocationEnabledDisabled) {
NavigateAndCommit(requesting_frame);
MockGoogleLocationSettingsHelper::SetLocationStatus(true, false);
EXPECT_EQ(0U, infobar_service()->infobar_count());
- RequestGeolocationPermission(RequestID(0), requesting_frame);
+ RequestGeolocationPermission(web_contents(), RequestID(0), requesting_frame);
EXPECT_EQ(1U, infobar_service()->infobar_count());
ConfirmInfoBarDelegate* infobar_delegate_1 =
infobar_service()->infobar_at(0)->delegate()->AsConfirmInfoBarDelegate();
@@ -304,7 +306,7 @@ TEST_F(GeolocationPermissionContextTests, GeolocationEnabledDisabled) {
NavigateAndCommit(requesting_frame);
MockGoogleLocationSettingsHelper::SetLocationStatus(false, false);
EXPECT_EQ(0U, infobar_service()->infobar_count());
- RequestGeolocationPermission(RequestID(0), requesting_frame);
+ RequestGeolocationPermission(web_contents(), RequestID(0), requesting_frame);
EXPECT_EQ(0U, infobar_service()->infobar_count());
}
@@ -313,7 +315,7 @@ TEST_F(GeolocationPermissionContextTests, MasterEnabledGoogleAppsEnabled) {
NavigateAndCommit(requesting_frame);
MockGoogleLocationSettingsHelper::SetLocationStatus(true, true);
EXPECT_EQ(0U, infobar_service()->infobar_count());
- RequestGeolocationPermission(RequestID(0), requesting_frame);
+ RequestGeolocationPermission(web_contents(), RequestID(0), requesting_frame);
EXPECT_EQ(1U, infobar_service()->infobar_count());
ConfirmInfoBarDelegate* infobar_delegate =
infobar_service()->infobar_at(0)->delegate()->AsConfirmInfoBarDelegate();
@@ -328,7 +330,7 @@ TEST_F(GeolocationPermissionContextTests, MasterEnabledGoogleAppsDisabled) {
NavigateAndCommit(requesting_frame);
MockGoogleLocationSettingsHelper::SetLocationStatus(true, false);
EXPECT_EQ(0U, infobar_service()->infobar_count());
- RequestGeolocationPermission(RequestID(0), requesting_frame);
+ RequestGeolocationPermission(web_contents(), RequestID(0), requesting_frame);
EXPECT_EQ(1U, infobar_service()->infobar_count());
ConfirmInfoBarDelegate* infobar_delegate =
infobar_service()->infobar_at(0)->delegate()->AsConfirmInfoBarDelegate();
@@ -354,8 +356,10 @@ TEST_F(GeolocationPermissionContextTests, QueuedPermission) {
NavigateAndCommit(requesting_frame_0);
EXPECT_EQ(0U, infobar_service()->infobar_count());
// Request permission for two frames.
- RequestGeolocationPermission(RequestID(0), requesting_frame_0);
- RequestGeolocationPermission(RequestID(1), requesting_frame_1);
+ RequestGeolocationPermission(
+ web_contents(), RequestID(0), requesting_frame_0);
+ RequestGeolocationPermission(
+ web_contents(), RequestID(1), requesting_frame_1);
// Ensure only one infobar is created.
ASSERT_EQ(1U, infobar_service()->infobar_count());
infobars::InfoBar* infobar_0 = infobar_service()->infobar_at(0);
@@ -410,7 +414,7 @@ TEST_F(GeolocationPermissionContextTests, HashIsIgnored) {
// Navigate to the first url and check permission is requested.
NavigateAndCommit(url_a);
EXPECT_EQ(0U, infobar_service()->infobar_count());
- RequestGeolocationPermission(RequestID(0), url_a);
+ RequestGeolocationPermission(web_contents(), RequestID(0), url_a);
ASSERT_EQ(1U, infobar_service()->infobar_count());
infobars::InfoBar* infobar = infobar_service()->infobar_at(0);
ConfirmInfoBarDelegate* infobar_delegate =
@@ -436,7 +440,7 @@ TEST_F(GeolocationPermissionContextTests, PermissionForFileScheme) {
GURL requesting_frame("file://example/geolocation.html");
NavigateAndCommit(requesting_frame);
EXPECT_EQ(0U, infobar_service()->infobar_count());
- RequestGeolocationPermission(RequestID(0), requesting_frame);
+ RequestGeolocationPermission(web_contents(), RequestID(0), requesting_frame);
EXPECT_EQ(1U, infobar_service()->infobar_count());
infobars::InfoBar* infobar = infobar_service()->infobar_at(0);
ConfirmInfoBarDelegate* infobar_delegate =
@@ -473,8 +477,10 @@ TEST_F(GeolocationPermissionContextTests, CancelGeolocationPermissionRequest) {
NavigateAndCommit(requesting_frame_0);
EXPECT_EQ(0U, infobar_service()->infobar_count());
// Request permission for two frames.
- RequestGeolocationPermission(RequestID(0), requesting_frame_0);
- RequestGeolocationPermission(RequestID(1), requesting_frame_1);
+ RequestGeolocationPermission(
+ web_contents(), RequestID(0), requesting_frame_0);
+ RequestGeolocationPermission(
+ web_contents(), RequestID(1), requesting_frame_1);
ASSERT_EQ(1U, infobar_service()->infobar_count());
infobars::InfoBar* infobar_0 = infobar_service()->infobar_at(0);
@@ -485,7 +491,8 @@ TEST_F(GeolocationPermissionContextTests, CancelGeolocationPermissionRequest) {
// Simulate the frame going away, ensure the infobar for this frame
// is removed and the next pending infobar is created.
- CancelGeolocationPermissionRequest(RequestID(0), requesting_frame_0);
+ CancelGeolocationPermissionRequest(
+ web_contents(), RequestID(0), requesting_frame_0);
EXPECT_EQ(1U, closed_infobar_tracker_.size());
EXPECT_TRUE(closed_infobar_tracker_.Contains(infobar_0));
closed_infobar_tracker_.Clear();
@@ -523,7 +530,7 @@ TEST_F(GeolocationPermissionContextTests, InvalidURL) {
GURL requesting_frame;
NavigateAndCommit(invalid_embedder);
EXPECT_EQ(0U, infobar_service()->infobar_count());
- RequestGeolocationPermission(RequestID(0), requesting_frame);
+ RequestGeolocationPermission(web_contents(), RequestID(0), requesting_frame);
EXPECT_EQ(0U, infobar_service()->infobar_count());
CheckPermissionMessageSent(0, false);
}
@@ -536,13 +543,13 @@ TEST_F(GeolocationPermissionContextTests, SameOriginMultipleTabs) {
AddNewTab(url_a);
EXPECT_EQ(0U, infobar_service()->infobar_count());
- RequestGeolocationPermission(RequestID(0), url_a);
+ RequestGeolocationPermission(web_contents(), RequestID(0), url_a);
ASSERT_EQ(1U, infobar_service()->infobar_count());
- RequestGeolocationPermission(RequestIDForTab(0, 0), url_b);
+ RequestGeolocationPermission(extra_tabs_[0], RequestIDForTab(0, 0), url_b);
EXPECT_EQ(1U, infobar_service_for_tab(0)->infobar_count());
- RequestGeolocationPermission(RequestIDForTab(1, 0), url_a);
+ RequestGeolocationPermission(extra_tabs_[1], RequestIDForTab(1, 0), url_a);
ASSERT_EQ(1U, infobar_service_for_tab(1)->infobar_count());
infobars::InfoBar* removed_infobar =
@@ -583,13 +590,13 @@ TEST_F(GeolocationPermissionContextTests, QueuedOriginMultipleTabs) {
AddNewTab(url_a);
EXPECT_EQ(0U, infobar_service()->infobar_count());
- RequestGeolocationPermission(RequestID(0), url_a);
+ RequestGeolocationPermission(web_contents(), RequestID(0), url_a);
ASSERT_EQ(1U, infobar_service()->infobar_count());
- RequestGeolocationPermission(RequestIDForTab(0, 0), url_a);
+ RequestGeolocationPermission(extra_tabs_[0], RequestIDForTab(0, 0), url_a);
EXPECT_EQ(1U, infobar_service_for_tab(0)->infobar_count());
- RequestGeolocationPermission(RequestIDForTab(0, 1), url_b);
+ RequestGeolocationPermission(extra_tabs_[0], RequestIDForTab(0, 1), url_b);
ASSERT_EQ(1U, infobar_service_for_tab(0)->infobar_count());
infobars::InfoBar* removed_infobar = infobar_service()->infobar_at(0);
@@ -641,8 +648,10 @@ TEST_F(GeolocationPermissionContextTests, TabDestroyed) {
NavigateAndCommit(requesting_frame_0);
EXPECT_EQ(0U, infobar_service()->infobar_count());
// Request permission for two frames.
- RequestGeolocationPermission(RequestID(0), requesting_frame_0);
- RequestGeolocationPermission(RequestID(1), requesting_frame_1);
+ RequestGeolocationPermission(
+ web_contents(), RequestID(0), requesting_frame_0);
+ RequestGeolocationPermission(
+ web_contents(), RequestID(1), requesting_frame_1);
// Ensure only one infobar is created.
ASSERT_EQ(1U, infobar_service()->infobar_count());
infobars::InfoBar* infobar = infobar_service()->infobar_at(0);
@@ -666,7 +675,8 @@ TEST_F(GeolocationPermissionContextTests, InfoBarUsesCommittedEntry) {
// permission.
web_contents()->GetController().GoBack();
// Request permission for the committed frame (not the pending one).
- RequestGeolocationPermission(RequestID(0), requesting_frame_1);
+ RequestGeolocationPermission(
+ web_contents(), RequestID(0), requesting_frame_1);
// Ensure the infobar is created.
ASSERT_EQ(1U, infobar_service()->infobar_count());
infobars::InfoBarDelegate* infobar_delegate =
diff --git a/chrome/browser/guest_view/web_view/web_view_guest.cc b/chrome/browser/guest_view/web_view/web_view_guest.cc
index b29d103..3fcbd37 100644
--- a/chrome/browser/guest_view/web_view/web_view_guest.cc
+++ b/chrome/browser/guest_view/web_view/web_view_guest.cc
@@ -591,8 +591,7 @@ void WebViewGuest::OnWebViewGeolocationPermissionResponse(
DCHECK(geolocation_context);
geolocation_context->RequestGeolocationPermission(
- embedder_web_contents()->GetRenderProcessHost()->GetID(),
- embedder_web_contents()->GetRoutingID(),
+ embedder_web_contents(),
// The geolocation permission request here is not initiated
// through WebGeolocationPermissionRequest. We are only interested
// in the fact whether the embedder/app has geolocation
diff --git a/chrome/browser/ui/autofill/autofill_dialog_controller_impl.cc b/chrome/browser/ui/autofill/autofill_dialog_controller_impl.cc
index ec41f89..2a72054 100644
--- a/chrome/browser/ui/autofill/autofill_dialog_controller_impl.cc
+++ b/chrome/browser/ui/autofill/autofill_dialog_controller_impl.cc
@@ -305,14 +305,6 @@ bool IsInstrumentAllowed(
}
}
-// Signals that the user has opted in to geolocation services. Factored out
-// into a separate method because all interaction with the geolocation provider
-// needs to happen on the IO thread, which is not the thread
-// AutofillDialogViewDelegate lives on.
-void UserDidOptIntoLocationServices() {
- content::GeolocationProvider::GetInstance()->UserDidOptIntoLocationServices();
-}
-
// Loops through |addresses_| comparing to |address| ignoring ID. If a match
// is not found, NULL is returned.
const wallet::Address* FindDuplicateAddress(
@@ -3625,9 +3617,7 @@ bool AutofillDialogControllerImpl::AreLegalDocumentsCurrent() const {
}
void AutofillDialogControllerImpl::AcceptLegalTerms() {
- content::BrowserThread::PostTask(
- content::BrowserThread::IO, FROM_HERE,
- base::Bind(&UserDidOptIntoLocationServices));
+ content::GeolocationProvider::GetInstance()->UserDidOptIntoLocationServices();
PrefService* local_state = g_browser_process->local_state();
ListPrefUpdate accepted(
local_state, ::prefs::kAutofillDialogWalletLocationAcceptance);
diff --git a/chrome/test/base/ui_test_utils.cc b/chrome/test/base/ui_test_utils.cc
index 5c23911..94885c7 100644
--- a/chrome/test/base/ui_test_utils.cc
+++ b/chrome/test/base/ui_test_utils.cc
@@ -561,13 +561,8 @@ void OverrideGeolocation(double latitude, double longitude) {
position.altitude = 0.;
position.accuracy = 0.;
position.timestamp = base::Time::Now();
- scoped_refptr<content::MessageLoopRunner> runner =
- new content::MessageLoopRunner;
-
- content::GeolocationProvider::OverrideLocationForTesting(
- position, runner->QuitClosure());
-
- runner->Run();
+ content::GeolocationProvider::GetInstance()->OverrideLocationForTesting(
+ position);
}
HistoryEnumerator::HistoryEnumerator(Profile* profile) {
diff --git a/components/autofill/content/browser/risk/fingerprint.cc b/components/autofill/content/browser/risk/fingerprint.cc
index 5c741b4..fb516c5 100644
--- a/components/autofill/content/browser/risk/fingerprint.cc
+++ b/components/autofill/content/browser/risk/fingerprint.cc
@@ -179,74 +179,6 @@ void AddGpuInfoToFingerprint(Fingerprint::MachineCharacteristics* machine) {
gpu_performance->set_overall_score(gpu_info.performance_stats.overall);
}
-// Waits for geoposition data to be loaded. Lives on the IO thread.
-class GeopositionLoader {
- public:
- // |callback_| will be called on the UI thread with the loaded geoposition,
- // once it is available.
- GeopositionLoader(
- const base::TimeDelta& timeout,
- const base::Callback<void(const content::Geoposition&)>& callback);
- ~GeopositionLoader() {}
-
- private:
- // Methods to communicate with the GeolocationProvider.
- void OnGotGeoposition(const content::Geoposition& geoposition);
-
- // The callback that will be called once the geoposition is available.
- // Will be called on the UI thread.
- const base::Callback<void(const content::Geoposition&)> callback_;
-
- // The callback used as an "observer" of the GeolocationProvider.
- content::GeolocationProvider::LocationUpdateCallback geolocation_callback_;
-
- // Timer to enforce a maximum timeout before the |callback_| is called, even
- // if the geoposition has not been loaded.
- base::OneShotTimer<GeopositionLoader> timeout_timer_;
-};
-
-GeopositionLoader::GeopositionLoader(
- const base::TimeDelta& timeout,
- const base::Callback<void(const content::Geoposition&)>& callback)
- : callback_(callback) {
- timeout_timer_.Start(FROM_HERE, timeout,
- base::Bind(&GeopositionLoader::OnGotGeoposition,
- base::Unretained(this),
- content::Geoposition()));
-
- geolocation_callback_ =
- base::Bind(&GeopositionLoader::OnGotGeoposition, base::Unretained(this));
- content::GeolocationProvider::GetInstance()->AddLocationUpdateCallback(
- geolocation_callback_, false);
-}
-
-void GeopositionLoader::OnGotGeoposition(
- const content::Geoposition& geoposition) {
- content::BrowserThread::PostTask(content::BrowserThread::UI, FROM_HERE,
- base::Bind(callback_, geoposition));
-
- // Unregister as an observer, since this class instance might be destroyed
- // after this callback. Note: It's important to unregister *after* posting
- // the task above. Unregistering as an observer can have the side-effect of
- // modifying the value of |geoposition|.
- bool removed =
- content::GeolocationProvider::GetInstance()->RemoveLocationUpdateCallback(
- geolocation_callback_);
- DCHECK(removed);
-
- delete this;
-}
-
-// Asynchronously loads the user's current geoposition and calls |callback_| on
-// the UI thread with the loaded geoposition, once it is available. Expected to
-// be called on the IO thread.
-void LoadGeoposition(
- const base::TimeDelta& timeout,
- const base::Callback<void(const content::Geoposition&)>& callback) {
- // The loader is responsible for freeing its own memory.
- new GeopositionLoader(timeout, callback);
-}
-
// Waits for all asynchronous data required for the fingerprint to be loaded,
// then fills out the fingerprint.
class FingerprintDataLoader : public content::GpuDataManagerObserver {
@@ -321,6 +253,10 @@ class FingerprintDataLoader : public content::GpuDataManagerObserver {
// The callback that will be called once all the data is available.
base::Callback<void(scoped_ptr<Fingerprint>)> callback_;
+ // The callback used as an "observer" of the GeolocationProvider.
+ scoped_ptr<content::GeolocationProvider::Subscription>
+ geolocation_subscription_;
+
DISALLOW_COPY_AND_ASSIGN(FingerprintDataLoader);
};
@@ -380,12 +316,11 @@ FingerprintDataLoader::FingerprintDataLoader(
weak_ptr_factory_.GetWeakPtr()));
// Load geolocation data.
- content::BrowserThread::PostTask(
- content::BrowserThread::IO, FROM_HERE,
- base::Bind(&LoadGeoposition,
- timeout,
- base::Bind(&FingerprintDataLoader::OnGotGeoposition,
- weak_ptr_factory_.GetWeakPtr())));
+ geolocation_subscription_ = content::GeolocationProvider::GetInstance()->
+ AddLocationUpdateCallback(
+ base::Bind(&FingerprintDataLoader::OnGotGeoposition,
+ weak_ptr_factory_.GetWeakPtr()),
+ false);
}
void FingerprintDataLoader::OnGpuInfoUpdate() {
@@ -417,6 +352,7 @@ void FingerprintDataLoader::OnGotGeoposition(
geoposition_ = geoposition;
DCHECK(geoposition_.Validate() ||
geoposition_.error_code != content::Geoposition::ERROR_CODE_NONE);
+ geolocation_subscription_.reset();
MaybeFillFingerprint();
}
diff --git a/components/autofill/content/browser/risk/fingerprint_browsertest.cc b/components/autofill/content/browser/risk/fingerprint_browsertest.cc
index fb2e0ca..6bee2ef 100644
--- a/components/autofill/content/browser/risk/fingerprint_browsertest.cc
+++ b/components/autofill/content/browser/risk/fingerprint_browsertest.cc
@@ -187,11 +187,8 @@ IN_PROC_BROWSER_TEST_F(AutofillRiskFingerprintTest, GetFingerprint) {
position.timestamp =
base::Time::UnixEpoch() +
base::TimeDelta::FromMilliseconds(kGeolocationTime);
- scoped_refptr<content::MessageLoopRunner> runner =
- new content::MessageLoopRunner;
- content::GeolocationProvider::OverrideLocationForTesting(
- position, runner->QuitClosure());
- runner->Run();
+ content::GeolocationProvider::GetInstance()->OverrideLocationForTesting(
+ position);
blink::WebScreenInfo screen_info;
screen_info.depth = kScreenColorDepth;
diff --git a/content/browser/android/content_view_core_impl.cc b/content/browser/android/content_view_core_impl.cc
index 9f4ebfb..60d1b85 100644
--- a/content/browser/android/content_view_core_impl.cc
+++ b/content/browser/android/content_view_core_impl.cc
@@ -23,6 +23,7 @@
#include "content/browser/frame_host/interstitial_page_impl.h"
#include "content/browser/frame_host/navigation_controller_impl.h"
#include "content/browser/frame_host/navigation_entry_impl.h"
+#include "content/browser/geolocation/geolocation_dispatcher_host.h"
#include "content/browser/media/android/browser_media_player_manager.h"
#include "content/browser/renderer_host/compositor_impl_android.h"
#include "content/browser/renderer_host/input/motion_event_android.h"
@@ -225,7 +226,6 @@ ContentViewCoreImpl::ContentViewCoreImpl(
view_android_(view_android),
window_android_(window_android),
device_orientation_(0),
- geolocation_needs_pause_(false),
accessibility_enabled_(false) {
CHECK(web_contents) <<
"A ContentViewCoreImpl should be created with a valid WebContents.";
@@ -333,8 +333,6 @@ void ContentViewCoreImpl::Observe(int type,
}
}
SetFocusInternal(HasFocus());
- if (geolocation_needs_pause_)
- PauseOrResumeGeolocation(true);
SetAccessibilityEnabledInternal(accessibility_enabled_);
break;
@@ -421,23 +419,7 @@ void ContentViewCoreImpl::PauseVideo() {
}
void ContentViewCoreImpl::PauseOrResumeGeolocation(bool should_pause) {
- geolocation_needs_pause_ = should_pause;
- RenderViewHostImpl* rvh =
- static_cast<RenderViewHostImpl*>(web_contents_->GetRenderViewHost());
- if (rvh) {
- scoped_refptr<GeolocationDispatcherHost> geolocation_dispatcher =
- static_cast<RenderProcessHostImpl*>(
- web_contents_->GetRenderProcessHost())->
- geolocation_dispatcher_host();
- if (geolocation_dispatcher.get()) {
- BrowserThread::PostTask(BrowserThread::IO, FROM_HERE,
- base::Bind(&GeolocationDispatcherHost::PauseOrResume,
- geolocation_dispatcher,
- rvh->GetRoutingID(),
- should_pause));
- geolocation_needs_pause_ = false;
- }
- }
+ web_contents_->geolocation_dispatcher_host()->PauseOrResume(should_pause);
}
// All positions and sizes are in CSS pixels.
diff --git a/content/browser/android/content_view_core_impl.h b/content/browser/android/content_view_core_impl.h
index 52cf643..3752789 100644
--- a/content/browser/android/content_view_core_impl.h
+++ b/content/browser/android/content_view_core_impl.h
@@ -374,9 +374,6 @@ class ContentViewCoreImpl : public ContentViewCore,
// will be sent to Renderer once it is ready.
int device_orientation_;
- bool geolocation_needs_pause_;
-
-
bool accessibility_enabled_;
// Manages injecting Java objects.
diff --git a/content/browser/geolocation/geolocation_dispatcher_host.cc b/content/browser/geolocation/geolocation_dispatcher_host.cc
index 5479446..34b9e84 100644
--- a/content/browser/geolocation/geolocation_dispatcher_host.cc
+++ b/content/browser/geolocation/geolocation_dispatcher_host.cc
@@ -11,6 +11,8 @@
#include "content/browser/renderer_host/render_message_filter.h"
#include "content/browser/renderer_host/render_process_host_impl.h"
#include "content/browser/renderer_host/render_view_host_impl.h"
+#include "content/browser/web_contents/web_contents_impl.h"
+#include "content/public/browser/browser_context.h"
#include "content/public/browser/geolocation_permission_context.h"
#include "content/public/common/geoposition.h"
#include "content/common/geolocation_messages.h"
@@ -61,16 +63,10 @@ void RecordGeopositionErrorCode(Geoposition::ErrorCode error_code) {
GEOPOSITION_ERROR_CODE_COUNT);
}
-void NotifyGeolocationProviderPermissionGranted() {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
- GeolocationProviderImpl::GetInstance()->UserDidOptIntoLocationServices();
-}
-
void SendGeolocationPermissionResponse(int render_process_id,
int render_view_id,
int bridge_id,
bool allowed) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
RenderViewHostImpl* render_view_host =
RenderViewHostImpl::FromID(render_process_id, render_view_id);
if (!render_view_host)
@@ -78,41 +74,37 @@ void SendGeolocationPermissionResponse(int render_process_id,
render_view_host->Send(
new GeolocationMsg_PermissionSet(render_view_id, bridge_id, allowed));
- if (allowed) {
- BrowserThread::PostTask(
- BrowserThread::IO, FROM_HERE,
- base::Bind(&NotifyGeolocationProviderPermissionGranted));
- }
+ if (allowed)
+ GeolocationProviderImpl::GetInstance()->UserDidOptIntoLocationServices();
}
} // namespace
GeolocationDispatcherHost::GeolocationDispatcherHost(
- int render_process_id,
- GeolocationPermissionContext* geolocation_permission_context)
- : BrowserMessageFilter(GeolocationMsgStart),
- render_process_id_(render_process_id),
- geolocation_permission_context_(geolocation_permission_context),
- geolocation_provider_(NULL) {
- callback_ = base::Bind(
- &GeolocationDispatcherHost::OnLocationUpdate, base::Unretained(this));
- // This is initialized by ResourceMessageFilter. Do not add any non-trivial
- // initialization here, defer to OnRegisterBridge which is triggered whenever
+ WebContents* web_contents)
+ : WebContentsObserver(web_contents),
+ watching_requested_(false),
+ paused_(false),
+ high_accuracy_(false) {
+ // This is initialized by WebContentsImpl. Do not add any non-trivial
+ // initialization here, defer to OnStartUpdating which is triggered whenever
// a javascript geolocation object is actually initialized.
}
GeolocationDispatcherHost::~GeolocationDispatcherHost() {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
- if (geolocation_provider_)
- geolocation_provider_->RemoveLocationUpdateCallback(callback_);
}
-bool GeolocationDispatcherHost::OnMessageReceived(
- const IPC::Message& msg, bool* msg_was_ok) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
- *msg_was_ok = true;
+void GeolocationDispatcherHost::RenderViewHostChanged(
+ RenderViewHost* old_host,
+ RenderViewHost* new_host) {
+ watching_requested_ = false;
+ paused_ = false;
+ geolocation_subscription_.reset();
+}
+
+bool GeolocationDispatcherHost::OnMessageReceived(const IPC::Message& msg) {
bool handled = true;
- IPC_BEGIN_MESSAGE_MAP_EX(GeolocationDispatcherHost, msg, *msg_was_ok)
+ IPC_BEGIN_MESSAGE_MAP(GeolocationDispatcherHost, msg)
IPC_MESSAGE_HANDLER(GeolocationHostMsg_CancelPermissionRequest,
OnCancelPermissionRequest)
IPC_MESSAGE_HANDLER(GeolocationHostMsg_RequestPermission,
@@ -126,140 +118,84 @@ bool GeolocationDispatcherHost::OnMessageReceived(
void GeolocationDispatcherHost::OnLocationUpdate(
const Geoposition& geoposition) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
RecordGeopositionErrorCode(geoposition.error_code);
- for (std::map<int, RendererGeolocationOptions>::iterator it =
- geolocation_renderers_.begin();
- it != geolocation_renderers_.end(); ++it) {
- if (!(it->second.is_paused))
- Send(new GeolocationMsg_PositionUpdated(it->first, geoposition));
- }
+ if (!paused_)
+ Send(new GeolocationMsg_PositionUpdated(routing_id(), geoposition));
}
void GeolocationDispatcherHost::OnRequestPermission(
- int render_view_id,
int bridge_id,
const GURL& requesting_frame,
bool user_gesture) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
- DVLOG(1) << __FUNCTION__ << " " << render_process_id_ << ":"
- << render_view_id << ":" << bridge_id;
- if (geolocation_permission_context_.get()) {
- geolocation_permission_context_->RequestGeolocationPermission(
- render_process_id_,
- render_view_id,
+ GeolocationPermissionContext* context =
+ web_contents()->GetBrowserContext()->GetGeolocationPermissionContext();
+ int render_process_id = web_contents()->GetRenderProcessHost()->GetID();
+ int render_view_id = web_contents()->GetRenderViewHost()->GetRoutingID();
+ if (context) {
+ context->RequestGeolocationPermission(
+ web_contents(),
bridge_id,
requesting_frame,
user_gesture,
base::Bind(&SendGeolocationPermissionResponse,
- render_process_id_,
+ render_process_id,
render_view_id,
bridge_id));
} else {
- BrowserThread::PostTask(
- BrowserThread::UI, FROM_HERE,
- base::Bind(&SendGeolocationPermissionResponse, render_process_id_,
- render_view_id, bridge_id, true));
+ SendGeolocationPermissionResponse(
+ render_process_id, render_view_id, bridge_id, true);
}
}
void GeolocationDispatcherHost::OnCancelPermissionRequest(
- int render_view_id,
int bridge_id,
const GURL& requesting_frame) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
- DVLOG(1) << __FUNCTION__ << " " << render_process_id_ << ":"
- << render_view_id << ":" << bridge_id;
- if (geolocation_permission_context_.get()) {
- geolocation_permission_context_->CancelGeolocationPermissionRequest(
- render_process_id_, render_view_id, bridge_id, requesting_frame);
+ GeolocationPermissionContext* context =
+ web_contents()->GetBrowserContext()->GetGeolocationPermissionContext();
+ if (context) {
+ context->CancelGeolocationPermissionRequest(
+ web_contents(), bridge_id, requesting_frame);
}
}
void GeolocationDispatcherHost::OnStartUpdating(
- int render_view_id,
const GURL& requesting_frame,
bool enable_high_accuracy) {
// StartUpdating() can be invoked as a result of high-accuracy mode
// being enabled / disabled. No need to record the dispatcher again.
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
- DVLOG(1) << __FUNCTION__ << " " << render_process_id_ << ":"
- << render_view_id;
UMA_HISTOGRAM_BOOLEAN(
"Geolocation.GeolocationDispatcherHostImpl.EnableHighAccuracy",
enable_high_accuracy);
- std::map<int, RendererGeolocationOptions>::iterator it =
- geolocation_renderers_.find(render_view_id);
- if (it == geolocation_renderers_.end()) {
- bool should_start_paused = false;
- if (pending_paused_geolocation_renderers_.erase(render_view_id) == 1) {
- should_start_paused = true;
- }
- RendererGeolocationOptions opts = {
- enable_high_accuracy,
- should_start_paused
- };
- geolocation_renderers_[render_view_id] = opts;
- } else {
- it->second.high_accuracy = enable_high_accuracy;
- }
+ watching_requested_ = true;
+ high_accuracy_ = enable_high_accuracy;
RefreshGeolocationOptions();
}
-void GeolocationDispatcherHost::OnStopUpdating(int render_view_id) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
- DVLOG(1) << __FUNCTION__ << " " << render_process_id_ << ":"
- << render_view_id;
- DCHECK_EQ(1U, geolocation_renderers_.count(render_view_id));
- geolocation_renderers_.erase(render_view_id);
+void GeolocationDispatcherHost::OnStopUpdating() {
+ watching_requested_ = false;
RefreshGeolocationOptions();
}
-void GeolocationDispatcherHost::PauseOrResume(int render_view_id,
- bool should_pause) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
- std::map<int, RendererGeolocationOptions>::iterator it =
- geolocation_renderers_.find(render_view_id);
- if (it == geolocation_renderers_.end()) {
- // This renderer is not using geolocation yet, but if it does before
- // we get a call to resume, we should start it up in the paused state.
- if (should_pause) {
- pending_paused_geolocation_renderers_.insert(render_view_id);
- } else {
- pending_paused_geolocation_renderers_.erase(render_view_id);
- }
- } else {
- RendererGeolocationOptions* opts = &(it->second);
- if (opts->is_paused != should_pause)
- opts->is_paused = should_pause;
- RefreshGeolocationOptions();
- }
+void GeolocationDispatcherHost::PauseOrResume(bool should_pause) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ paused_ = should_pause;
+ RefreshGeolocationOptions();
}
void GeolocationDispatcherHost::RefreshGeolocationOptions() {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- bool needs_updates = false;
- bool use_high_accuracy = false;
- std::map<int, RendererGeolocationOptions>::const_iterator i =
- geolocation_renderers_.begin();
- for (; i != geolocation_renderers_.end(); ++i) {
- needs_updates |= !(i->second.is_paused);
- use_high_accuracy |= i->second.high_accuracy;
- if (needs_updates && use_high_accuracy)
- break;
- }
- if (needs_updates) {
- if (!geolocation_provider_)
- geolocation_provider_ = GeolocationProviderImpl::GetInstance();
- // Re-add to re-establish our options, in case they changed.
- geolocation_provider_->AddLocationUpdateCallback(
- callback_, use_high_accuracy);
+ if (watching_requested_ && !paused_) {
+ geolocation_subscription_ = GeolocationProvider::GetInstance()->
+ AddLocationUpdateCallback(
+ base::Bind(&GeolocationDispatcherHost::OnLocationUpdate,
+ base::Unretained(this)),
+ high_accuracy_);
} else {
- if (geolocation_provider_)
- geolocation_provider_->RemoveLocationUpdateCallback(callback_);
- geolocation_provider_ = NULL;
+ geolocation_subscription_.reset();
}
}
diff --git a/content/browser/geolocation/geolocation_dispatcher_host.h b/content/browser/geolocation/geolocation_dispatcher_host.h
index 28c6003..a73487f 100644
--- a/content/browser/geolocation/geolocation_dispatcher_host.h
+++ b/content/browser/geolocation/geolocation_dispatcher_host.h
@@ -5,11 +5,8 @@
#ifndef CONTENT_BROWSER_GEOLOCATION_GEOLOCATION_DISPATCHER_HOST_H_
#define CONTENT_BROWSER_GEOLOCATION_GEOLOCATION_DISPATCHER_HOST_H_
-#include <map>
-#include <set>
-
#include "content/browser/geolocation/geolocation_provider_impl.h"
-#include "content/public/browser/browser_message_filter.h"
+#include "content/public/browser/web_contents_observer.h"
class GURL;
@@ -17,74 +14,48 @@ namespace content {
class GeolocationPermissionContext;
-// GeolocationDispatcherHost is a browser filter for Geolocation messages.
+// GeolocationDispatcherHost is an observer for Geolocation messages.
// It's the complement of GeolocationDispatcher (owned by RenderView).
-class GeolocationDispatcherHost : public BrowserMessageFilter {
+class GeolocationDispatcherHost : public WebContentsObserver {
public:
- GeolocationDispatcherHost(
- int render_process_id,
- GeolocationPermissionContext* geolocation_permission_context);
+ explicit GeolocationDispatcherHost(WebContents* web_contents);
+ virtual ~GeolocationDispatcherHost();
- // Pause or resumes geolocation for the given |render_view_id|. Should
- // be called on the IO thread. Resuming when nothing is paused is a no-op.
- // If a renderer is paused while not currently using geolocation but
- // then goes on to do so before being resumed, then that renderer will
- // not get geolocation updates until it is resumed.
- void PauseOrResume(int render_view_id, bool should_pause);
+ // Pause or resumes geolocation. Resuming when nothing is paused is a no-op.
+ // If the web contents is paused while not currently using geolocation but
+ // then goes on to do so before being resumed, then it will not get
+ // geolocation updates until it is resumed.
+ void PauseOrResume(bool should_pause);
private:
- virtual ~GeolocationDispatcherHost();
-
- // GeolocationDispatcherHost
- virtual bool OnMessageReceived(const IPC::Message& msg,
- bool* msg_was_ok) OVERRIDE;
+ // WebContentsObserver
+ virtual void RenderViewHostChanged(RenderViewHost* old_host,
+ RenderViewHost* new_host) OVERRIDE;
+ virtual bool OnMessageReceived(const IPC::Message& msg) OVERRIDE;
// Message handlers:
- void OnRequestPermission(int render_view_id,
- int bridge_id,
+ void OnRequestPermission(int bridge_id,
const GURL& requesting_frame,
bool user_gesture);
- void OnCancelPermissionRequest(int render_view_id,
- int bridge_id,
+ void OnCancelPermissionRequest(int bridge_id,
const GURL& requesting_frame);
- void OnStartUpdating(int render_view_id,
- const GURL& requesting_frame,
+ void OnStartUpdating(const GURL& requesting_frame,
bool enable_high_accuracy);
- void OnStopUpdating(int render_view_id);
+ void OnStopUpdating();
- // Updates the |geolocation_provider_| with the currently required update
+ // Updates the geolocation provider with the currently required update
// options.
void RefreshGeolocationOptions();
void OnLocationUpdate(const Geoposition& position);
- int render_process_id_;
scoped_refptr<GeolocationPermissionContext> geolocation_permission_context_;
- struct RendererGeolocationOptions {
- bool high_accuracy;
- bool is_paused;
- };
-
- // Used to keep track of the renderers in this process that are using
- // geolocation and the options associated with them. The map is iterated
- // when a location update is available and the fan out to individual bridge
- // IDs happens renderer side, in order to minimize context switches.
- // Only used on the IO thread.
- std::map<int, RendererGeolocationOptions> geolocation_renderers_;
-
- // Used by Android WebView to support that case that a renderer is in the
- // 'paused' state but not yet using geolocation. If the renderer does start
- // using geolocation while paused, we move from this set into
- // |geolocation_renderers_|. If the renderer doesn't end up wanting to use
- // geolocation while 'paused' then we remove from this set. A renderer id
- // can exist only in this set or |geolocation_renderers_|, never both.
- std::set<int> pending_paused_geolocation_renderers_;
-
- // Only set whilst we are registered with the geolocation provider.
- GeolocationProviderImpl* geolocation_provider_;
-
- GeolocationProviderImpl::LocationUpdateCallback callback_;
+ bool watching_requested_;
+ bool paused_;
+ bool high_accuracy_;
+
+ scoped_ptr<GeolocationProvider::Subscription> geolocation_subscription_;
DISALLOW_COPY_AND_ASSIGN(GeolocationDispatcherHost);
};
diff --git a/content/browser/geolocation/geolocation_provider_impl.cc b/content/browser/geolocation/geolocation_provider_impl.cc
index f343c29..901cade 100644
--- a/content/browser/geolocation/geolocation_provider_impl.cc
+++ b/content/browser/geolocation/geolocation_provider_impl.cc
@@ -16,84 +16,44 @@
namespace content {
-namespace {
-void OverrideLocationForTestingOnIOThread(
- const Geoposition& position,
- const base::Closure& completion_callback,
- scoped_refptr<base::MessageLoopProxy> callback_loop) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
- GeolocationProviderImpl::GetInstance()->OverrideLocationForTesting(position);
- callback_loop->PostTask(FROM_HERE, completion_callback);
-}
-} // namespace
-
GeolocationProvider* GeolocationProvider::GetInstance() {
return GeolocationProviderImpl::GetInstance();
}
-void GeolocationProvider::OverrideLocationForTesting(
- const Geoposition& position,
- const base::Closure& completion_callback) {
- base::Closure closure = base::Bind(&OverrideLocationForTestingOnIOThread,
- position,
- completion_callback,
- base::MessageLoopProxy::current());
- if (!BrowserThread::CurrentlyOn(BrowserThread::IO))
- BrowserThread::PostTask(BrowserThread::IO, FROM_HERE, closure);
- else
- closure.Run();
-}
-
-void GeolocationProviderImpl::AddLocationUpdateCallback(
+scoped_ptr<GeolocationProvider::Subscription>
+GeolocationProviderImpl::AddLocationUpdateCallback(
const LocationUpdateCallback& callback, bool use_high_accuracy) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
- bool found = false;
- CallbackList::iterator i = callbacks_.begin();
- for (; i != callbacks_.end(); ++i) {
- if (i->first.Equals(callback)) {
- i->second = use_high_accuracy;
- found = true;
- break;
- }
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ scoped_ptr<GeolocationProvider::Subscription> subscription;
+ if (use_high_accuracy) {
+ subscription = high_accuracy_callbacks_.Add(callback);
+ } else {
+ subscription = low_accuracy_callbacks_.Add(callback);
}
- if (!found)
- callbacks_.push_back(std::make_pair(callback, use_high_accuracy));
OnClientsChanged();
if (position_.Validate() ||
position_.error_code != Geoposition::ERROR_CODE_NONE) {
callback.Run(position_);
}
-}
-bool GeolocationProviderImpl::RemoveLocationUpdateCallback(
- const LocationUpdateCallback& callback) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
- bool removed = false;
- CallbackList::iterator i = callbacks_.begin();
- for (; i != callbacks_.end(); ++i) {
- if (i->first.Equals(callback)) {
- callbacks_.erase(i);
- removed = true;
- break;
- }
- }
- if (removed)
- OnClientsChanged();
- return removed;
+ return subscription.Pass();
}
void GeolocationProviderImpl::UserDidOptIntoLocationServices() {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
bool was_permission_granted = user_did_opt_into_location_services_;
user_did_opt_into_location_services_ = true;
if (IsRunning() && !was_permission_granted)
InformProvidersPermissionGranted();
}
-bool GeolocationProviderImpl::LocationServicesOptedIn() const {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
- return user_did_opt_into_location_services_;
+void GeolocationProviderImpl::OverrideLocationForTesting(
+ const Geoposition& position) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ position_ = position;
+ ignore_location_updates_ = true;
+ NotifyClients(position);
}
void GeolocationProviderImpl::OnLocationUpdate(const Geoposition& position) {
@@ -101,22 +61,14 @@ void GeolocationProviderImpl::OnLocationUpdate(const Geoposition& position) {
// Will be true only in testing.
if (ignore_location_updates_)
return;
- BrowserThread::PostTask(BrowserThread::IO,
+ BrowserThread::PostTask(BrowserThread::UI,
FROM_HERE,
base::Bind(&GeolocationProviderImpl::NotifyClients,
base::Unretained(this), position));
}
-void GeolocationProviderImpl::OverrideLocationForTesting(
- const Geoposition& position) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
- position_ = position;
- ignore_location_updates_ = true;
- NotifyClients(position);
-}
-
GeolocationProviderImpl* GeolocationProviderImpl::GetInstance() {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
return Singleton<GeolocationProviderImpl>::get();
}
@@ -125,12 +77,16 @@ GeolocationProviderImpl::GeolocationProviderImpl()
user_did_opt_into_location_services_(false),
ignore_location_updates_(false),
arbitrator_(NULL) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ high_accuracy_callbacks_.set_removal_callback(
+ base::Bind(&GeolocationProviderImpl::OnClientsChanged,
+ base::Unretained(this)));
+ low_accuracy_callbacks_.set_removal_callback(
+ base::Bind(&GeolocationProviderImpl::OnClientsChanged,
+ base::Unretained(this)));
}
GeolocationProviderImpl::~GeolocationProviderImpl() {
- // All callbacks should have unregistered before this singleton is destructed.
- DCHECK(callbacks_.empty());
Stop();
DCHECK(!arbitrator_);
}
@@ -140,9 +96,9 @@ bool GeolocationProviderImpl::OnGeolocationThread() const {
}
void GeolocationProviderImpl::OnClientsChanged() {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
base::Closure task;
- if (callbacks_.empty()) {
+ if (high_accuracy_callbacks_.empty() && low_accuracy_callbacks_.empty()) {
DCHECK(IsRunning());
// We have no more observers, so we clear the cached geoposition so that
// when the next observer is added we will not provide a stale position.
@@ -152,18 +108,11 @@ void GeolocationProviderImpl::OnClientsChanged() {
} else {
if (!IsRunning()) {
Start();
- if (LocationServicesOptedIn())
+ if (user_did_opt_into_location_services_)
InformProvidersPermissionGranted();
}
// Determine a set of options that satisfies all clients.
- bool use_high_accuracy = false;
- CallbackList::iterator i = callbacks_.begin();
- for (; i != callbacks_.end(); ++i) {
- if (i->second) {
- use_high_accuracy = true;
- break;
- }
- }
+ bool use_high_accuracy = !high_accuracy_callbacks_.empty();
// Send the current options to the providers as they may have changed.
task = base::Bind(&GeolocationProviderImpl::StartProviders,
@@ -201,18 +150,12 @@ void GeolocationProviderImpl::InformProvidersPermissionGranted() {
}
void GeolocationProviderImpl::NotifyClients(const Geoposition& position) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
DCHECK(position.Validate() ||
position.error_code != Geoposition::ERROR_CODE_NONE);
position_ = position;
- CallbackList::const_iterator it = callbacks_.begin();
- while (it != callbacks_.end()) {
- // Advance iterator before calling the observer to guard against synchronous
- // unregister.
- LocationUpdateCallback callback = it->first;
- ++it;
- callback.Run(position_);
- }
+ high_accuracy_callbacks_.Notify(position_);
+ low_accuracy_callbacks_.Notify(position_);
}
void GeolocationProviderImpl::Init() {
diff --git a/content/browser/geolocation/geolocation_provider_impl.h b/content/browser/geolocation/geolocation_provider_impl.h
index 6613f44..e3b8762 100644
--- a/content/browser/geolocation/geolocation_provider_impl.h
+++ b/content/browser/geolocation/geolocation_provider_impl.h
@@ -21,33 +21,16 @@ template<typename Type> struct DefaultSingletonTraits;
namespace content {
class LocationArbitrator;
-// This is the main API to the geolocation subsystem. The application will hold
-// a single instance of this class and can register multiple clients to be
-// notified of location changes:
-// * Callbacks are registered by AddLocationUpdateCallback() and will keep
-// receiving updates until unregistered by RemoveLocationUpdateCallback().
-// The application must instantiate the GeolocationProvider on the IO thread and
-// must communicate with it on the same thread.
-// The underlying location arbitrator will only be enabled whilst there is at
-// least one registered observer or pending callback. The arbitrator and the
-// location providers it uses run on a separate Geolocation thread.
class CONTENT_EXPORT GeolocationProviderImpl
: public NON_EXPORTED_BASE(GeolocationProvider),
public base::Thread {
public:
// GeolocationProvider implementation:
- virtual void AddLocationUpdateCallback(const LocationUpdateCallback& callback,
- bool use_high_accuracy) OVERRIDE;
- virtual bool RemoveLocationUpdateCallback(
- const LocationUpdateCallback& callback) OVERRIDE;
+ virtual scoped_ptr<GeolocationProvider::Subscription>
+ AddLocationUpdateCallback(const LocationUpdateCallback& callback,
+ bool use_high_accuracy) OVERRIDE;
virtual void UserDidOptIntoLocationServices() OVERRIDE;
-
- bool LocationServicesOptedIn() const;
-
- // Overrides the location for automation/testing. Suppresses any further
- // updates from the actual providers and sends an update with the overridden
- // position to all registered clients.
- void OverrideLocationForTesting(const Geoposition& override_position);
+ virtual void OverrideLocationForTesting(const Geoposition& position) OVERRIDE;
// Callback from the LocationArbitrator. Public for testing.
void OnLocationUpdate(const Geoposition& position);
@@ -58,6 +41,10 @@ class CONTENT_EXPORT GeolocationProviderImpl
// instantiated on the same thread. Ownership is NOT returned.
static GeolocationProviderImpl* GetInstance();
+ bool user_did_opt_into_location_services_for_testing() {
+ return user_did_opt_into_location_services_;
+ }
+
protected:
friend struct DefaultSingletonTraits<GeolocationProviderImpl>;
GeolocationProviderImpl();
@@ -67,9 +54,6 @@ class CONTENT_EXPORT GeolocationProviderImpl
virtual LocationArbitrator* CreateArbitrator();
private:
- typedef std::pair<LocationUpdateCallback, bool> LocationUpdateInfo;
- typedef std::list<LocationUpdateInfo> CallbackList;
-
bool OnGeolocationThread() const;
// Start and stop providers as needed when clients are added or removed.
@@ -94,8 +78,9 @@ class CONTENT_EXPORT GeolocationProviderImpl
virtual void Init() OVERRIDE;
virtual void CleanUp() OVERRIDE;
- // Only used on the IO thread
- CallbackList callbacks_;
+ base::CallbackList<void(const Geoposition&)> high_accuracy_callbacks_;
+ base::CallbackList<void(const Geoposition&)> low_accuracy_callbacks_;
+
bool user_did_opt_into_location_services_;
Geoposition position_;
diff --git a/content/browser/geolocation/geolocation_provider_unittest.cc b/content/browser/geolocation/geolocation_provider_unittest.cc
index a2aa88d..95fa1b6 100644
--- a/content/browser/geolocation/geolocation_provider_unittest.cc
+++ b/content/browser/geolocation/geolocation_provider_unittest.cc
@@ -114,7 +114,7 @@ class GeolocationProviderTest : public testing::Test {
protected:
GeolocationProviderTest()
: message_loop_(),
- io_thread_(BrowserThread::IO, &message_loop_),
+ ui_thread_(BrowserThread::UI, &message_loop_),
provider_(new LocationProviderForTestArbitrator) {
}
@@ -131,7 +131,7 @@ class GeolocationProviderTest : public testing::Test {
void GetProvidersStarted(bool* started);
base::MessageLoop message_loop_;
- TestBrowserThread io_thread_;
+ TestBrowserThread ui_thread_;
scoped_ptr<LocationProviderForTestArbitrator> provider_;
};
@@ -167,19 +167,25 @@ void GeolocationProviderTest::SendMockLocation(const Geoposition& position) {
// Regression test for http://crbug.com/59377
TEST_F(GeolocationProviderTest, OnPermissionGrantedWithoutObservers) {
- EXPECT_FALSE(provider()->LocationServicesOptedIn());
+ EXPECT_FALSE(provider()->user_did_opt_into_location_services_for_testing());
provider()->UserDidOptIntoLocationServices();
- EXPECT_TRUE(provider()->LocationServicesOptedIn());
+ EXPECT_TRUE(provider()->user_did_opt_into_location_services_for_testing());
+}
+
+void DummyFunction(const Geoposition& position) {
}
TEST_F(GeolocationProviderTest, StartStop) {
EXPECT_FALSE(provider()->IsRunning());
- GeolocationProviderImpl::LocationUpdateCallback null_callback;
- provider()->AddLocationUpdateCallback(null_callback, false);
+ GeolocationProviderImpl::LocationUpdateCallback callback =
+ base::Bind(&DummyFunction);
+ scoped_ptr<content::GeolocationProvider::Subscription> subscription =
+ provider()->AddLocationUpdateCallback(callback, false);
EXPECT_TRUE(provider()->IsRunning());
EXPECT_TRUE(ProvidersStarted());
- provider()->RemoveLocationUpdateCallback(null_callback);
+ subscription.reset();
+
EXPECT_FALSE(ProvidersStarted());
EXPECT_TRUE(provider()->IsRunning());
}
@@ -196,11 +202,12 @@ TEST_F(GeolocationProviderTest, StalePositionNotSent) {
&MockGeolocationObserver::OnLocationUpdate,
base::Unretained(&first_observer));
EXPECT_CALL(first_observer, OnLocationUpdate(GeopositionEq(first_position)));
- provider()->AddLocationUpdateCallback(first_callback, false);
+ scoped_ptr<content::GeolocationProvider::Subscription> subscription =
+ provider()->AddLocationUpdateCallback(first_callback, false);
SendMockLocation(first_position);
base::MessageLoop::current()->Run();
- provider()->RemoveLocationUpdateCallback(first_callback);
+ subscription.reset();
Geoposition second_position;
second_position.latitude = 13;
@@ -216,7 +223,8 @@ TEST_F(GeolocationProviderTest, StalePositionNotSent) {
GeolocationProviderImpl::LocationUpdateCallback second_callback = base::Bind(
&MockGeolocationObserver::OnLocationUpdate,
base::Unretained(&second_observer));
- provider()->AddLocationUpdateCallback(second_callback, false);
+ scoped_ptr<content::GeolocationProvider::Subscription> subscription2 =
+ provider()->AddLocationUpdateCallback(second_callback, false);
base::MessageLoop::current()->RunUntilIdle();
// The second observer should receive the new position now.
@@ -225,7 +233,7 @@ TEST_F(GeolocationProviderTest, StalePositionNotSent) {
SendMockLocation(second_position);
base::MessageLoop::current()->Run();
- provider()->RemoveLocationUpdateCallback(second_callback);
+ subscription2.reset();
EXPECT_FALSE(ProvidersStarted());
}
@@ -240,8 +248,9 @@ TEST_F(GeolocationProviderTest, OverrideLocationForTesting) {
GeolocationProviderImpl::LocationUpdateCallback callback = base::Bind(
&MockGeolocationObserver::OnLocationUpdate,
base::Unretained(&mock_observer));
- provider()->AddLocationUpdateCallback(callback, false);
- provider()->RemoveLocationUpdateCallback(callback);
+ scoped_ptr<content::GeolocationProvider::Subscription> subscription =
+ provider()->AddLocationUpdateCallback(callback, false);
+ subscription.reset();
// Wait for the providers to be stopped now that all clients are gone.
EXPECT_FALSE(ProvidersStarted());
}
diff --git a/content/browser/renderer_host/render_process_host_impl.cc b/content/browser/renderer_host/render_process_host_impl.cc
index c01dc5c..d5870eb 100644
--- a/content/browser/renderer_host/render_process_host_impl.cc
+++ b/content/browser/renderer_host/render_process_host_impl.cc
@@ -411,7 +411,6 @@ RenderProcessHostImpl::RenderProcessHostImpl(
delayed_cleanup_needed_(false),
within_process_died_observer_(false),
power_monitor_broadcaster_(this),
- geolocation_dispatcher_host_(NULL),
screen_orientation_dispatcher_host_(NULL),
worker_ref_count_(0),
weak_factory_(this) {
@@ -705,9 +704,6 @@ void RenderProcessHostImpl::CreateMessageFilters() {
storage_partition_impl_->GetIndexedDBContext(),
ChromeBlobStorageContext::GetFor(browser_context)));
- geolocation_dispatcher_host_ = new GeolocationDispatcherHost(
- GetID(), browser_context->GetGeolocationPermissionContext());
- AddFilter(geolocation_dispatcher_host_);
gpu_message_filter_ = new GpuMessageFilter(GetID(), widget_helper_.get());
AddFilter(gpu_message_filter_);
#if defined(ENABLE_WEBRTC)
@@ -1452,7 +1448,6 @@ void RenderProcessHostImpl::Cleanup() {
channel_.reset();
gpu_message_filter_ = NULL;
message_port_message_filter_ = NULL;
- geolocation_dispatcher_host_ = NULL;
screen_orientation_dispatcher_host_ = NULL;
// Remove ourself from the list of renderer processes so that we can't be
@@ -1840,7 +1835,6 @@ void RenderProcessHostImpl::ProcessDied(bool already_dead) {
channel_.reset();
gpu_message_filter_ = NULL;
message_port_message_filter_ = NULL;
- geolocation_dispatcher_host_ = NULL;
screen_orientation_dispatcher_host_ = NULL;
IDMap<IPC::Listener>::iterator iter(&listeners_);
diff --git a/content/browser/renderer_host/render_process_host_impl.h b/content/browser/renderer_host/render_process_host_impl.h
index 358109f..d0f9e96 100644
--- a/content/browser/renderer_host/render_process_host_impl.h
+++ b/content/browser/renderer_host/render_process_host_impl.h
@@ -14,7 +14,6 @@
#include "base/process/process.h"
#include "base/timer/timer.h"
#include "content/browser/child_process_launcher.h"
-#include "content/browser/geolocation/geolocation_dispatcher_host.h"
#include "content/browser/power_monitor_message_broadcaster.h"
#include "content/common/content_export.h"
#include "content/public/browser/gpu_data_manager_observer.h"
@@ -37,7 +36,6 @@ class Size;
namespace content {
class AudioRendererHost;
class BrowserDemuxerAndroid;
-class GeolocationDispatcherHost;
class GpuMessageFilter;
class MessagePortMessageFilter;
class MojoApplicationHost;
@@ -163,11 +161,6 @@ class CONTENT_EXPORT RenderProcessHostImpl
scoped_ptr<RenderWidgetHostViewFrameSubscriber> subscriber);
void EndFrameSubscription(int route_id);
- scoped_refptr<GeolocationDispatcherHost>
- geolocation_dispatcher_host() const {
- return make_scoped_refptr(geolocation_dispatcher_host_);
- }
-
#if defined(ENABLE_WEBRTC)
// Fires the webrtc log message callback with |message|, if callback is set.
void WebRtcLogMessage(const std::string& message);
@@ -417,9 +410,6 @@ class CONTENT_EXPORT RenderProcessHostImpl
scoped_refptr<BrowserDemuxerAndroid> browser_demuxer_android_;
#endif
- // Message filter for geolocation messages.
- GeolocationDispatcherHost* geolocation_dispatcher_host_;
-
#if defined(ENABLE_WEBRTC)
base::Callback<void(const std::string&)> webrtc_log_message_callback_;
#endif
diff --git a/content/browser/renderer_host/render_widget_host_view_android.cc b/content/browser/renderer_host/render_widget_host_view_android.cc
index 1fbe093..d093def 100644
--- a/content/browser/renderer_host/render_widget_host_view_android.cc
+++ b/content/browser/renderer_host/render_widget_host_view_android.cc
@@ -49,6 +49,7 @@
#include "content/common/input/did_overscroll_params.h"
#include "content/common/input_messages.h"
#include "content/common/view_messages.h"
+#include "content/public/browser/browser_thread.h"
#include "content/public/browser/devtools_agent_host.h"
#include "content/public/browser/render_view_host.h"
#include "content/public/common/content_switches.h"
diff --git a/content/browser/web_contents/aura/gesture_nav_simple.cc b/content/browser/web_contents/aura/gesture_nav_simple.cc
index 44f16bc..f904fe2 100644
--- a/content/browser/web_contents/aura/gesture_nav_simple.cc
+++ b/content/browser/web_contents/aura/gesture_nav_simple.cc
@@ -9,6 +9,7 @@
#include "content/browser/renderer_host/overscroll_controller.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/browser/web_contents/web_contents_view.h"
+#include "content/public/browser/browser_thread.h"
#include "content/public/browser/overscroll_configuration.h"
#include "content/public/common/content_client.h"
#include "grit/ui_resources.h"
diff --git a/content/browser/web_contents/aura/overscroll_navigation_overlay.cc b/content/browser/web_contents/aura/overscroll_navigation_overlay.cc
index 1a17d90..0d66ff1 100644
--- a/content/browser/web_contents/aura/overscroll_navigation_overlay.cc
+++ b/content/browser/web_contents/aura/overscroll_navigation_overlay.cc
@@ -9,6 +9,7 @@
#include "content/browser/web_contents/aura/image_window_delegate.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/common/view_messages.h"
+#include "content/public/browser/browser_thread.h"
#include "content/public/browser/render_widget_host_view.h"
#include "ui/aura/window.h"
#include "ui/compositor/layer.h"
diff --git a/content/browser/web_contents/web_contents_impl.cc b/content/browser/web_contents/web_contents_impl.cc
index 45f6468..b02984b 100644
--- a/content/browser/web_contents/web_contents_impl.cc
+++ b/content/browser/web_contents/web_contents_impl.cc
@@ -33,6 +33,7 @@
#include "content/browser/frame_host/navigator_impl.h"
#include "content/browser/frame_host/render_frame_host_impl.h"
#include "content/browser/frame_host/render_widget_host_view_child_frame.h"
+#include "content/browser/geolocation/geolocation_dispatcher_host.h"
#include "content/browser/host_zoom_map_impl.h"
#include "content/browser/loader/resource_dispatcher_host_impl.h"
#include "content/browser/message_port_message_filter.h"
@@ -1087,6 +1088,9 @@ void WebContentsImpl::Init(const WebContents::CreateParams& params) {
registrar_.Add(this,
NOTIFICATION_RENDER_WIDGET_HOST_DESTROYED,
NotificationService::AllBrowserContextsAndSources());
+
+ geolocation_dispatcher_host_.reset(new GeolocationDispatcherHost(this));
+
#if defined(OS_ANDROID)
date_time_chooser_.reset(new DateTimeChooserAndroid());
#endif
diff --git a/content/browser/web_contents/web_contents_impl.h b/content/browser/web_contents/web_contents_impl.h
index 0ca0f1a..7db4ec6 100644
--- a/content/browser/web_contents/web_contents_impl.h
+++ b/content/browser/web_contents/web_contents_impl.h
@@ -48,6 +48,7 @@ class BrowserPluginGuest;
class BrowserPluginGuestManager;
class DateTimeChooserAndroid;
class DownloadItem;
+class GeolocationDispatcherHost;
class InterstitialPageImpl;
class JavaScriptDialogManager;
class PowerSaveBlocker;
@@ -160,6 +161,10 @@ class CONTENT_EXPORT WebContentsImpl
WebContentsView* GetView() const;
+ GeolocationDispatcherHost* geolocation_dispatcher_host() {
+ return geolocation_dispatcher_host_.get();
+ }
+
// WebContents ------------------------------------------------------
virtual WebContentsDelegate* GetDelegate() OVERRIDE;
virtual void SetDelegate(WebContentsDelegate* delegate) OVERRIDE;
@@ -1092,6 +1097,8 @@ class CONTENT_EXPORT WebContentsImpl
// Whether the last JavaScript dialog shown was suppressed. Used for testing.
bool last_dialog_suppressed_;
+ scoped_ptr<GeolocationDispatcherHost> geolocation_dispatcher_host_;
+
DISALLOW_COPY_AND_ASSIGN(WebContentsImpl);
};
diff --git a/content/common/geolocation_messages.h b/content/common/geolocation_messages.h
index 8582828..55b4bd7 100644
--- a/content/common/geolocation_messages.h
+++ b/content/common/geolocation_messages.h
@@ -42,33 +42,28 @@ IPC_MESSAGE_ROUTED1(GeolocationMsg_PositionUpdated,
// Messages sent from the renderer to the browser.
-// The |render_view_id| and |bridge_id| representing |host| is requesting
-// permission to access geolocation position.
-// This will be replied by GeolocationMsg_PermissionSet.
-IPC_MESSAGE_CONTROL4(GeolocationHostMsg_RequestPermission,
- int /* render_view_id */,
+// The |bridge_id| representing |host| is requesting permission to access
+// geolocation position. This will be replied by GeolocationMsg_PermissionSet.
+IPC_MESSAGE_ROUTED3(GeolocationHostMsg_RequestPermission,
int /* bridge_id */,
GURL /* GURL of the frame requesting geolocation */,
bool /* user_gesture */)
-// The |render_view_id| and |bridge_id| representing |GURL| is cancelling its
-// previous permission request to access geolocation position.
-IPC_MESSAGE_CONTROL3(GeolocationHostMsg_CancelPermissionRequest,
- int /* render_view_id */,
- int /* bridge_id */,
- GURL /* GURL of the frame */)
+// The |bridge_id| representing |GURL| is cancelling its previous permission
+// request to access geolocation position.
+IPC_MESSAGE_ROUTED2(GeolocationHostMsg_CancelPermissionRequest,
+ int /* bridge_id */,
+ GURL /* GURL of the frame */)
-// The |render_view_id| requests Geolocation service to start updating.
+// The render view requests the Geolocation service to start updating.
// This is an asynchronous call, and the browser process may eventually reply
// with the updated geoposition, or an error (access denied, location
// unavailable, etc.)
-IPC_MESSAGE_CONTROL3(GeolocationHostMsg_StartUpdating,
- int /* render_view_id */,
+IPC_MESSAGE_ROUTED2(GeolocationHostMsg_StartUpdating,
GURL /* GURL of the frame requesting geolocation */,
bool /* enable_high_accuracy */)
-// The |render_view_id| requests Geolocation service to stop updating.
+// The render view requests Geolocation service to stop updating.
// Note that the geolocation service may continue to fetch geolocation data
// for other origins.
-IPC_MESSAGE_CONTROL1(GeolocationHostMsg_StopUpdating,
- int /* render_view_id */)
+IPC_MESSAGE_ROUTED0(GeolocationHostMsg_StopUpdating)
diff --git a/content/public/browser/geolocation_permission_context.h b/content/public/browser/geolocation_permission_context.h
index ab85862..a97c83f 100644
--- a/content/public/browser/geolocation_permission_context.h
+++ b/content/public/browser/geolocation_permission_context.h
@@ -12,6 +12,7 @@
class GURL;
namespace content {
+class WebContents;
// GeolocationPermissionContext must be implemented by the embedder, to provide
// the policy and logic for the Geolocation permissions flow.
@@ -23,8 +24,7 @@ class CONTENT_EXPORT GeolocationPermissionContext
// When the answer to a permission request has been determined, |callback|
// should be called with the result.
virtual void RequestGeolocationPermission(
- int render_process_id,
- int render_view_id,
+ WebContents* web_contents,
int bridge_id,
const GURL& requesting_frame,
bool user_gesture,
@@ -32,8 +32,7 @@ class CONTENT_EXPORT GeolocationPermissionContext
// The renderer is cancelling a pending permission request.
virtual void CancelGeolocationPermissionRequest(
- int render_process_id,
- int render_view_id,
+ WebContents* web_contents,
int bridge_id,
const GURL& requesting_frame) = 0;
diff --git a/content/public/browser/geolocation_provider.h b/content/public/browser/geolocation_provider.h
index 5e27db4..dea3c7e 100644
--- a/content/public/browser/geolocation_provider.h
+++ b/content/public/browser/geolocation_provider.h
@@ -5,33 +5,36 @@
#ifndef CONTENT_PUBLIC_BROWSER_GEOLOCATION_PROVIDER_H_
#define CONTENT_PUBLIC_BROWSER_GEOLOCATION_PROVIDER_H_
-#include "base/callback_forward.h"
+#include "base/callback_list.h"
#include "content/common/content_export.h"
namespace content {
struct Geoposition;
-class CONTENT_EXPORT GeolocationProvider {
+// This is the main API to the geolocation subsystem. The application will hold
+// a single instance of this class and can register multiple clients to be
+// notified of location changes:
+// * Callbacks are registered by AddLocationUpdateCallback() and will keep
+// receiving updates until the returned subscription object is destructed.
+// The application must instantiate the GeolocationProvider on the UI thread and
+// must communicate with it on the same thread.
+// The underlying location arbitrator will only be enabled whilst there is at
+// least one registered observer or pending callback (and only after
+// UserDidOptIntoLocationServices). The arbitrator and the location providers it
+// uses run on a separate Geolocation thread.
+class GeolocationProvider {
public:
- // This method, and all below, can only be called on the IO thread unless
- // otherwise specified.
- static GeolocationProvider* GetInstance();
+ CONTENT_EXPORT static GeolocationProvider* GetInstance();
typedef base::Callback<void(const Geoposition&)> LocationUpdateCallback;
+ typedef base::CallbackList<void(const Geoposition&)>::Subscription
+ Subscription;
// |use_high_accuracy| is used as a 'hint' for the provider preferences for
// this particular observer, however the observer could receive updates for
// best available locations from any active provider whilst it is registered.
- // If an existing observer is added a second time, its options are updated
- // but only a single call to RemoveLocationUpdateCallback() is required to
- // remove it.
- virtual void AddLocationUpdateCallback(const LocationUpdateCallback& callback,
- bool use_high_accuracy) = 0;
-
- // Remove a previously registered observer. No-op if not previously registered
- // via AddLocationUpdateCallback(). Returns true if the observer was removed.
- virtual bool RemoveLocationUpdateCallback(
- const LocationUpdateCallback& callback) = 0;
+ virtual scoped_ptr<Subscription> AddLocationUpdateCallback(
+ const LocationUpdateCallback& callback, bool use_high_accuracy) = 0;
// Calling this method indicates the user has opted into using location
// services, including sending network requests to [Google servers to] resolve
@@ -39,21 +42,17 @@ class CONTENT_EXPORT GeolocationProvider {
// go/chrome-privacy-doc.
virtual void UserDidOptIntoLocationServices() = 0;
- // Overrides the current location for testing. This function may be called on
- // any thread. The completion callback will be invoked asynchronously on the
- // calling thread when the override operation is completed.
+ // Overrides the current location for testing.
//
- // This function allows the current location to be faked without having to
- // manually instantiate a GeolocationProvider backed by a MockLocationProvider
- // that serves a fake location.
+ // Overrides the location for automation/testing. Suppresses any further
+ // updates from the actual providers and sends an update with the overridden
+ // position to all registered clients.
//
// Do not use this function in unit tests. The function instantiates the
// singleton geolocation stack in the background and manipulates it to report
// a fake location. Neither step can be undone, breaking unit test isolation
// (crbug.com/125931).
- static void OverrideLocationForTesting(
- const Geoposition& position,
- const base::Closure& completion_callback);
+ virtual void OverrideLocationForTesting(const Geoposition& position) = 0;
protected:
virtual~GeolocationProvider() {}