Blink roll 25b6bd3a7a131ffe68d809546ad1a20707915cdc:3a503f41ae42e5b79cfcd2ff10e65afde...
[chromium-blink-merge.git] / content / browser / geolocation / geolocation_service_impl.cc
blob4c855f27046541b5ede834728846617cbd5b07b2
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "content/browser/geolocation/geolocation_service_impl.h"
7 #include "base/bind.h"
8 #include "base/metrics/histogram.h"
9 #include "content/browser/geolocation/geolocation_service_context.h"
10 #include "content/public/common/mojo_geoposition.mojom.h"
12 namespace content {
14 namespace {
16 // Geoposition error codes for reporting in UMA.
17 enum GeopositionErrorCode {
18 // NOTE: Do not renumber these as that would confuse interpretation of
19 // previously logged data. When making changes, also update the enum list
20 // in tools/metrics/histograms/histograms.xml to keep it in sync.
22 // There was no error.
23 GEOPOSITION_ERROR_CODE_NONE = 0,
25 // User denied use of geolocation.
26 GEOPOSITION_ERROR_CODE_PERMISSION_DENIED = 1,
28 // Geoposition could not be determined.
29 GEOPOSITION_ERROR_CODE_POSITION_UNAVAILABLE = 2,
31 // Timeout.
32 GEOPOSITION_ERROR_CODE_TIMEOUT = 3,
34 // NOTE: Add entries only immediately above this line.
35 GEOPOSITION_ERROR_CODE_COUNT = 4
38 void RecordGeopositionErrorCode(Geoposition::ErrorCode error_code) {
39 GeopositionErrorCode code = GEOPOSITION_ERROR_CODE_NONE;
40 switch (error_code) {
41 case Geoposition::ERROR_CODE_NONE:
42 code = GEOPOSITION_ERROR_CODE_NONE;
43 break;
44 case Geoposition::ERROR_CODE_PERMISSION_DENIED:
45 code = GEOPOSITION_ERROR_CODE_PERMISSION_DENIED;
46 break;
47 case Geoposition::ERROR_CODE_POSITION_UNAVAILABLE:
48 code = GEOPOSITION_ERROR_CODE_POSITION_UNAVAILABLE;
49 break;
50 case Geoposition::ERROR_CODE_TIMEOUT:
51 code = GEOPOSITION_ERROR_CODE_TIMEOUT;
52 break;
54 UMA_HISTOGRAM_ENUMERATION("Geolocation.LocationUpdate.ErrorCode",
55 code,
56 GEOPOSITION_ERROR_CODE_COUNT);
59 } // namespace
61 GeolocationServiceImpl::GeolocationServiceImpl(
62 GeolocationServiceContext* context,
63 const base::Closure& update_callback)
64 : context_(context),
65 update_callback_(update_callback),
66 high_accuracy_(false) {
67 DCHECK(context_);
70 GeolocationServiceImpl::~GeolocationServiceImpl() {
73 void GeolocationServiceImpl::PauseUpdates() {
74 geolocation_subscription_.reset();
77 void GeolocationServiceImpl::ResumeUpdates() {
78 if (position_override_.Validate()) {
79 OnLocationUpdate(position_override_);
80 return;
83 StartListeningForUpdates();
86 void GeolocationServiceImpl::StartListeningForUpdates() {
87 geolocation_subscription_ =
88 GeolocationProvider::GetInstance()->AddLocationUpdateCallback(
89 base::Bind(&GeolocationServiceImpl::OnLocationUpdate,
90 base::Unretained(this)),
91 high_accuracy_);
94 void GeolocationServiceImpl::SetHighAccuracy(bool high_accuracy) {
95 UMA_HISTOGRAM_BOOLEAN(
96 "Geolocation.GeolocationDispatcherHostImpl.EnableHighAccuracy",
97 high_accuracy);
98 high_accuracy_ = high_accuracy;
100 if (position_override_.Validate()) {
101 OnLocationUpdate(position_override_);
102 return;
105 StartListeningForUpdates();
108 void GeolocationServiceImpl::SetOverride(const Geoposition& position) {
109 position_override_ = position;
110 if (!position_override_.Validate()) {
111 ResumeUpdates();
114 geolocation_subscription_.reset();
116 OnLocationUpdate(position_override_);
119 void GeolocationServiceImpl::ClearOverride() {
120 position_override_ = Geoposition();
121 StartListeningForUpdates();
124 void GeolocationServiceImpl::OnConnectionError() {
125 context_->ServiceHadConnectionError(this);
127 // The above call deleted this instance, so the only safe thing to do is
128 // return.
131 void GeolocationServiceImpl::OnLocationUpdate(const Geoposition& position) {
132 RecordGeopositionErrorCode(position.error_code);
133 DCHECK(context_);
135 if (context_->paused())
136 return;
138 MojoGeopositionPtr geoposition(MojoGeoposition::New());
139 geoposition->valid = position.Validate();
140 geoposition->latitude = position.latitude;
141 geoposition->longitude = position.longitude;
142 geoposition->altitude = position.altitude;
143 geoposition->accuracy = position.accuracy;
144 geoposition->altitude_accuracy = position.altitude_accuracy;
145 geoposition->heading = position.heading;
146 geoposition->speed = position.speed;
147 geoposition->timestamp = position.timestamp.ToDoubleT();
148 geoposition->error_code = MojoGeoposition::ErrorCode(position.error_code);
149 geoposition->error_message = position.error_message;
151 update_callback_.Run();
152 client()->OnLocationUpdate(geoposition.Pass());
155 } // namespace content