File: mock_geofencing_service.cc

package info (click to toggle)
chromium-browser 41.0.2272.118-1
  • links: PTS, VCS
  • area: main
  • in suites: jessie-kfreebsd
  • size: 2,189,132 kB
  • sloc: cpp: 9,691,462; ansic: 3,341,451; python: 712,689; asm: 518,779; xml: 208,926; java: 169,820; sh: 119,353; perl: 68,907; makefile: 28,311; yacc: 13,305; objc: 11,385; tcl: 3,186; cs: 2,225; sql: 2,217; lex: 2,215; lisp: 1,349; pascal: 1,256; awk: 407; ruby: 155; sed: 53; php: 14; exp: 11
file content (123 lines) | stat: -rw-r--r-- 4,057 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
// Copyright 2014 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// MSVC++ requires this to be set before any other includes to get M_PI.
#define _USE_MATH_DEFINES

#include "content/browser/geofencing/mock_geofencing_service.h"

#include <cmath>

#include "base/bind.h"
#include "base/message_loop/message_loop.h"
#include "content/browser/geofencing/geofencing_registration_delegate.h"
#include "third_party/WebKit/public/platform/WebCircularGeofencingRegion.h"

namespace content {

namespace {

void RegisterRegionResult(GeofencingRegistrationDelegate* delegate,
                          int64 geofencing_registration_id,
                          GeofencingStatus status) {
  base::MessageLoop::current()->PostTask(
      FROM_HERE,
      base::Bind(&GeofencingRegistrationDelegate::RegistrationFinished,
                 base::Unretained(delegate), geofencing_registration_id,
                 status));
}

double DegreesToRadians(float degrees) {
  return (M_PI * degrees) / 180.f;
}

double Haversin(double theta) {
  double temp = sin(theta / 2);
  return temp * temp;
}

// Calculates the distance in meters between two points with coordinates in
// degrees.
double Distance(double lat1, double long1, double lat2, double long2) {
  double R = 6371000;  // radius of earth in meters
  double phi1 = DegreesToRadians(lat1);
  double phi2 = DegreesToRadians(lat2);
  double dphi = DegreesToRadians(lat2 - lat1);
  double dlambda = DegreesToRadians(long2 - long1);
  double haversine = Haversin(dphi) + cos(phi1) * cos(phi2) * Haversin(dlambda);
  return 2 * R * asin(sqrt(haversine));
}

// Returns true iff the provided coordinate is inside the region.
bool PositionInRegion(double latitude,
                      double longitude,
                      const blink::WebCircularGeofencingRegion& region) {
  return Distance(latitude, longitude, region.latitude, region.longitude) <=
         region.radius;
}
}

struct MockGeofencingService::Registration {
  blink::WebCircularGeofencingRegion region;
  GeofencingRegistrationDelegate* delegate;
  // True iff the last event emitted for this region was a RegionEntered event.
  bool is_inside;
};

MockGeofencingService::MockGeofencingService(bool service_available)
    : available_(service_available),
      next_id_(0),
      has_position_(false),
      last_latitude_(0),
      last_longitude_(0) {
}

MockGeofencingService::~MockGeofencingService() {
}

void MockGeofencingService::SetMockPosition(double latitude, double longitude) {
  has_position_ = true;
  last_latitude_ = latitude;
  last_longitude_ = longitude;
  for (auto& registration : registrations_) {
    bool is_inside =
        PositionInRegion(latitude, longitude, registration.second.region);
    if (is_inside != registration.second.is_inside) {
      if (is_inside)
        registration.second.delegate->RegionEntered(registration.first);
      else
        registration.second.delegate->RegionExited(registration.first);
    }
    registration.second.is_inside = is_inside;
  }
}

bool MockGeofencingService::IsServiceAvailable() {
  return available_;
}

int64 MockGeofencingService::RegisterRegion(
    const blink::WebCircularGeofencingRegion& region,
    GeofencingRegistrationDelegate* delegate) {
  int64 id = next_id_++;
  Registration& registration = registrations_[id];
  registration.region = region;
  registration.delegate = delegate;
  registration.is_inside =
      has_position_ &&
      PositionInRegion(last_latitude_, last_longitude_, region);
  RegisterRegionResult(delegate, id, GEOFENCING_STATUS_OK);
  if (registration.is_inside) {
    base::MessageLoop::current()->PostTask(
        FROM_HERE, base::Bind(&GeofencingRegistrationDelegate::RegionEntered,
                              base::Unretained(delegate), id));
  }
  return id;
}

void MockGeofencingService::UnregisterRegion(int64 geofencing_registration_id) {
  registrations_.erase(geofencing_registration_id);
}

}  // namespace content