OLD | NEW |
| (Empty) |
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. | |
4 | |
5 #include "content/browser/geolocation/geolocation_service_impl.h" | |
6 | |
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" | |
11 | |
12 namespace content { | |
13 | |
14 namespace { | |
15 | |
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. | |
21 | |
22 // There was no error. | |
23 GEOPOSITION_ERROR_CODE_NONE = 0, | |
24 | |
25 // User denied use of geolocation. | |
26 GEOPOSITION_ERROR_CODE_PERMISSION_DENIED = 1, | |
27 | |
28 // Geoposition could not be determined. | |
29 GEOPOSITION_ERROR_CODE_POSITION_UNAVAILABLE = 2, | |
30 | |
31 // Timeout. | |
32 GEOPOSITION_ERROR_CODE_TIMEOUT = 3, | |
33 | |
34 // NOTE: Add entries only immediately above this line. | |
35 GEOPOSITION_ERROR_CODE_COUNT = 4 | |
36 }; | |
37 | |
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; | |
53 } | |
54 UMA_HISTOGRAM_ENUMERATION("Geolocation.LocationUpdate.ErrorCode", | |
55 code, | |
56 GEOPOSITION_ERROR_CODE_COUNT); | |
57 } | |
58 | |
59 } // namespace | |
60 | |
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_); | |
68 } | |
69 | |
70 GeolocationServiceImpl::~GeolocationServiceImpl() { | |
71 } | |
72 | |
73 void GeolocationServiceImpl::PauseUpdates() { | |
74 geolocation_subscription_.reset(); | |
75 } | |
76 | |
77 void GeolocationServiceImpl::ResumeUpdates() { | |
78 if (position_override_.Validate()) { | |
79 OnLocationUpdate(position_override_); | |
80 return; | |
81 } | |
82 | |
83 StartListeningForUpdates(); | |
84 } | |
85 | |
86 void GeolocationServiceImpl::StartListeningForUpdates() { | |
87 geolocation_subscription_ = | |
88 GeolocationProvider::GetInstance()->AddLocationUpdateCallback( | |
89 base::Bind(&GeolocationServiceImpl::OnLocationUpdate, | |
90 base::Unretained(this)), | |
91 high_accuracy_); | |
92 } | |
93 | |
94 void GeolocationServiceImpl::SetHighAccuracy(bool high_accuracy) { | |
95 UMA_HISTOGRAM_BOOLEAN( | |
96 "Geolocation.GeolocationDispatcherHostImpl.EnableHighAccuracy", | |
97 high_accuracy); | |
98 high_accuracy_ = high_accuracy; | |
99 | |
100 if (position_override_.Validate()) { | |
101 OnLocationUpdate(position_override_); | |
102 return; | |
103 } | |
104 | |
105 StartListeningForUpdates(); | |
106 } | |
107 | |
108 void GeolocationServiceImpl::SetOverride(const Geoposition& position) { | |
109 position_override_ = position; | |
110 if (!position_override_.Validate()) { | |
111 ResumeUpdates(); | |
112 } | |
113 | |
114 geolocation_subscription_.reset(); | |
115 | |
116 OnLocationUpdate(position_override_); | |
117 } | |
118 | |
119 void GeolocationServiceImpl::ClearOverride() { | |
120 position_override_ = Geoposition(); | |
121 StartListeningForUpdates(); | |
122 } | |
123 | |
124 void GeolocationServiceImpl::OnConnectionError() { | |
125 context_->ServiceHadConnectionError(this); | |
126 | |
127 // The above call deleted this instance, so the only safe thing to do is | |
128 // return. | |
129 } | |
130 | |
131 void GeolocationServiceImpl::OnLocationUpdate(const Geoposition& position) { | |
132 RecordGeopositionErrorCode(position.error_code); | |
133 DCHECK(context_); | |
134 | |
135 if (context_->paused()) | |
136 return; | |
137 | |
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; | |
150 | |
151 update_callback_.Run(); | |
152 client()->OnLocationUpdate(geoposition.Pass()); | |
153 } | |
154 | |
155 } // namespace content | |
OLD | NEW |