summaryrefslogtreecommitdiff
path: root/platform/android/MapboxGLAndroidSDKTestApp/src/main/java/com/mapbox/mapboxsdk/testapp/activity/userlocation/MockLocationEngine.java
blob: f4fe710de14741625abe4b61266da7abd6f57770 (plain)
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
124
125
126
127
128
129
130
package com.mapbox.mapboxsdk.testapp.activity.userlocation;

import android.animation.AnimatorListenerAdapter;
import android.animation.TypeEvaluator;
import android.animation.ValueAnimator;
import android.location.Location;

import com.mapbox.android.core.location.LocationEngine;
import com.mapbox.android.core.location.LocationEngineListener;

import timber.log.Timber;

/**
 * Sample LocationEngine that provides mocked LOCATIONS simulating GPS updates
 */
public class MockLocationEngine extends LocationEngine {
  private static MockLocationEngine INSTANCE;

  private final LocationAnimator locationAnimator;
  private boolean running;
  private static int counter;

  MockLocationEngine(Location start, Location end) {
    locationAnimator = new LocationAnimator(start, end, animation -> {
      for (LocationEngineListener listener : locationListeners) {
        listener.onLocationChanged((Location) animation.getAnimatedValue());
      }
    });
  }

  public static synchronized MockLocationEngine getInstance() {
    if (INSTANCE == null) {
      INSTANCE = new MockLocationEngine(
        MockLocationEngine.createLocation(40.416913, -3.703861),
        MockLocationEngine.createLocation(39.461643, -0.368041)
      );
    }
    return INSTANCE;
  }

  public static Location createLocation(double latitude, double longitude) {
    Location location = new Location(MockLocationEngine.class.getSimpleName());
    location.setLatitude(latitude);
    location.setLongitude(longitude);
    return location;
  }

  @Override
  public void activate() {
    // "Connection" is immediate here
    for (LocationEngineListener listener : locationListeners) {
      listener.onConnected();
    }
  }

  @Override
  public void deactivate() {
  }

  @Override
  public boolean isConnected() {
    return true; // Always connected
  }

  @Override
  public Location getLastLocation() {
    return null;
  }

  @Override
  public void requestLocationUpdates() {
    if (!running) {
      locationAnimator.start();
      running = true;
    }
  }

  @Override
  public void removeLocationUpdates() {
    if (running) {
      locationAnimator.stop();
      running = false;
      Timber.e("LOC %s", counter);
    }
  }

  @Override
  public Type obtainType() {
    return Type.MOCK;
  }

  private static class LocationAnimator extends AnimatorListenerAdapter {

    private static final long DURATION_ANIMATION = 10000;
    private final ValueAnimator locationAnimator;
    private long animationTime;

    LocationAnimator(Location start, Location end, ValueAnimator.AnimatorUpdateListener listener) {
      locationAnimator = ValueAnimator.ofObject(new LocationEvaluator(), start, end);
      locationAnimator.setDuration(DURATION_ANIMATION);
      locationAnimator.addUpdateListener(listener);
      locationAnimator.addListener(this);
    }

    void start() {
      locationAnimator.start();
      locationAnimator.setCurrentPlayTime(animationTime);
    }

    void stop() {
      animationTime = locationAnimator.getCurrentPlayTime();
      locationAnimator.cancel();
    }

    private static class LocationEvaluator implements TypeEvaluator<Location> {

      private Location location = new Location(MockLocationEngine.class.getSimpleName());

      @Override
      public Location evaluate(float fraction, Location startValue, Location endValue) {
        counter++;
        location.setLatitude(startValue.getLatitude()
          + ((endValue.getLatitude() - startValue.getLatitude()) * fraction));
        location.setLongitude(startValue.getLongitude()
          + ((endValue.getLongitude() - startValue.getLongitude()) * fraction));
        return location;
      }
    }
  }
}