| 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 // MSVC++ requires this to be set before any other includes to get M_PI. | |
| 6 #define _USE_MATH_DEFINES | |
| 7 | |
| 8 #include "content/browser/geofencing/mock_geofencing_service.h" | |
| 9 | |
| 10 #include <cmath> | |
| 11 | |
| 12 #include "base/bind.h" | |
| 13 #include "base/location.h" | |
| 14 #include "base/single_thread_task_runner.h" | |
| 15 #include "base/threading/thread_task_runner_handle.h" | |
| 16 #include "content/browser/geofencing/geofencing_registration_delegate.h" | |
| 17 #include "third_party/WebKit/public/platform/WebCircularGeofencingRegion.h" | |
| 18 | |
| 19 namespace content { | |
| 20 | |
| 21 namespace { | |
| 22 | |
| 23 void RegisterRegionResult(GeofencingRegistrationDelegate* delegate, | |
| 24 int64_t geofencing_registration_id, | |
| 25 GeofencingStatus status) { | |
| 26 base::ThreadTaskRunnerHandle::Get()->PostTask( | |
| 27 FROM_HERE, | |
| 28 base::Bind(&GeofencingRegistrationDelegate::RegistrationFinished, | |
| 29 base::Unretained(delegate), geofencing_registration_id, | |
| 30 status)); | |
| 31 } | |
| 32 | |
| 33 double DegreesToRadians(float degrees) { | |
| 34 return (M_PI * degrees) / 180.f; | |
| 35 } | |
| 36 | |
| 37 double Haversin(double theta) { | |
| 38 double temp = sin(theta / 2); | |
| 39 return temp * temp; | |
| 40 } | |
| 41 | |
| 42 // Calculates the distance in meters between two points with coordinates in | |
| 43 // degrees. | |
| 44 double Distance(double lat1, double long1, double lat2, double long2) { | |
| 45 double R = 6371000; // radius of earth in meters | |
| 46 double phi1 = DegreesToRadians(lat1); | |
| 47 double phi2 = DegreesToRadians(lat2); | |
| 48 double dphi = DegreesToRadians(lat2 - lat1); | |
| 49 double dlambda = DegreesToRadians(long2 - long1); | |
| 50 double haversine = Haversin(dphi) + cos(phi1) * cos(phi2) * Haversin(dlambda); | |
| 51 return 2 * R * asin(sqrt(haversine)); | |
| 52 } | |
| 53 | |
| 54 // Returns true iff the provided coordinate is inside the region. | |
| 55 bool PositionInRegion(double latitude, | |
| 56 double longitude, | |
| 57 const blink::WebCircularGeofencingRegion& region) { | |
| 58 return Distance(latitude, longitude, region.latitude, region.longitude) <= | |
| 59 region.radius; | |
| 60 } | |
| 61 } | |
| 62 | |
| 63 struct MockGeofencingService::Registration { | |
| 64 blink::WebCircularGeofencingRegion region; | |
| 65 GeofencingRegistrationDelegate* delegate; | |
| 66 // True iff the last event emitted for this region was a RegionEntered event. | |
| 67 bool is_inside; | |
| 68 }; | |
| 69 | |
| 70 MockGeofencingService::MockGeofencingService(bool service_available) | |
| 71 : available_(service_available), | |
| 72 next_id_(0), | |
| 73 has_position_(false), | |
| 74 last_latitude_(0), | |
| 75 last_longitude_(0) { | |
| 76 } | |
| 77 | |
| 78 MockGeofencingService::~MockGeofencingService() { | |
| 79 } | |
| 80 | |
| 81 void MockGeofencingService::SetMockPosition(double latitude, double longitude) { | |
| 82 has_position_ = true; | |
| 83 last_latitude_ = latitude; | |
| 84 last_longitude_ = longitude; | |
| 85 for (auto& registration : registrations_) { | |
| 86 bool is_inside = | |
| 87 PositionInRegion(latitude, longitude, registration.second.region); | |
| 88 if (is_inside != registration.second.is_inside) { | |
| 89 if (is_inside) | |
| 90 registration.second.delegate->RegionEntered(registration.first); | |
| 91 else | |
| 92 registration.second.delegate->RegionExited(registration.first); | |
| 93 } | |
| 94 registration.second.is_inside = is_inside; | |
| 95 } | |
| 96 } | |
| 97 | |
| 98 bool MockGeofencingService::IsServiceAvailable() { | |
| 99 return available_; | |
| 100 } | |
| 101 | |
| 102 int64_t MockGeofencingService::RegisterRegion( | |
| 103 const blink::WebCircularGeofencingRegion& region, | |
| 104 GeofencingRegistrationDelegate* delegate) { | |
| 105 int64_t id = next_id_++; | |
| 106 Registration& registration = registrations_[id]; | |
| 107 registration.region = region; | |
| 108 registration.delegate = delegate; | |
| 109 registration.is_inside = | |
| 110 has_position_ && | |
| 111 PositionInRegion(last_latitude_, last_longitude_, region); | |
| 112 RegisterRegionResult(delegate, id, GEOFENCING_STATUS_OK); | |
| 113 if (registration.is_inside) { | |
| 114 base::ThreadTaskRunnerHandle::Get()->PostTask( | |
| 115 FROM_HERE, base::Bind(&GeofencingRegistrationDelegate::RegionEntered, | |
| 116 base::Unretained(delegate), id)); | |
| 117 } | |
| 118 return id; | |
| 119 } | |
| 120 | |
| 121 void MockGeofencingService::UnregisterRegion( | |
| 122 int64_t geofencing_registration_id) { | |
| 123 registrations_.erase(geofencing_registration_id); | |
| 124 } | |
| 125 | |
| 126 } // namespace content | |
| OLD | NEW |