blob: a84b0b1c4335d54577f5f66171dc0612f7af1bd5 [file] [log] [blame]
Yu-Han Yang890ca8b2018-04-16 22:11:31 -07001package com.android.server.location;
2
3import android.location.IGpsGeofenceHardware;
Yu-Han Yang890ca8b2018-04-16 22:11:31 -07004import android.util.Log;
5import android.util.SparseArray;
6
Yu-Han Yang6dc9f052018-12-04 17:11:24 -08007import com.android.internal.annotations.GuardedBy;
Yu-Han Yang890ca8b2018-04-16 22:11:31 -07008import com.android.internal.annotations.VisibleForTesting;
9
Yu-Han Yang890ca8b2018-04-16 22:11:31 -070010/**
11 * Manages GNSS Geofence operations.
12 */
13class GnssGeofenceProvider extends IGpsGeofenceHardware.Stub {
14
15 private static final String TAG = "GnssGeofenceProvider";
16 private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
17
18 /** Holds the parameters of a geofence. */
19 private static class GeofenceEntry {
20 public int geofenceId;
21 public double latitude;
22 public double longitude;
23 public double radius;
24 public int lastTransition;
25 public int monitorTransitions;
26 public int notificationResponsiveness;
27 public int unknownTimer;
28 public boolean paused;
29 }
30
Yu-Han Yang6dc9f052018-12-04 17:11:24 -080031 private final Object mLock = new Object();
32 @GuardedBy("mLock")
Yu-Han Yang890ca8b2018-04-16 22:11:31 -070033 private final GnssGeofenceProviderNative mNative;
Yu-Han Yang6dc9f052018-12-04 17:11:24 -080034 @GuardedBy("mLock")
Yu-Han Yang890ca8b2018-04-16 22:11:31 -070035 private final SparseArray<GeofenceEntry> mGeofenceEntries = new SparseArray<>();
Yu-Han Yang890ca8b2018-04-16 22:11:31 -070036
Yu-Han Yang6dc9f052018-12-04 17:11:24 -080037 GnssGeofenceProvider() {
38 this(new GnssGeofenceProviderNative());
Yu-Han Yang890ca8b2018-04-16 22:11:31 -070039 }
40
41 @VisibleForTesting
Yu-Han Yang6dc9f052018-12-04 17:11:24 -080042 GnssGeofenceProvider(GnssGeofenceProviderNative gnssGeofenceProviderNative) {
Yu-Han Yang890ca8b2018-04-16 22:11:31 -070043 mNative = gnssGeofenceProviderNative;
44 }
45
Yu-Han Yang890ca8b2018-04-16 22:11:31 -070046 void resumeIfStarted() {
47 if (DEBUG) {
48 Log.d(TAG, "resumeIfStarted");
49 }
Yu-Han Yang6dc9f052018-12-04 17:11:24 -080050 synchronized (mLock) {
Yu-Han Yang890ca8b2018-04-16 22:11:31 -070051 for (int i = 0; i < mGeofenceEntries.size(); i++) {
52 GeofenceEntry entry = mGeofenceEntries.valueAt(i);
53 boolean added = mNative.addGeofence(entry.geofenceId, entry.latitude,
54 entry.longitude,
55 entry.radius,
56 entry.lastTransition, entry.monitorTransitions,
57 entry.notificationResponsiveness, entry.unknownTimer);
58 if (added && entry.paused) {
59 mNative.pauseGeofence(entry.geofenceId);
60 }
61 }
Yu-Han Yang890ca8b2018-04-16 22:11:31 -070062 }
Yu-Han Yang890ca8b2018-04-16 22:11:31 -070063 }
64
65 @Override
66 public boolean isHardwareGeofenceSupported() {
Yu-Han Yang6dc9f052018-12-04 17:11:24 -080067 synchronized (mLock) {
68 return mNative.isGeofenceSupported();
69 }
Yu-Han Yang890ca8b2018-04-16 22:11:31 -070070 }
71
72 @Override
73 public boolean addCircularHardwareGeofence(int geofenceId, double latitude,
74 double longitude, double radius, int lastTransition, int monitorTransitions,
75 int notificationResponsiveness, int unknownTimer) {
Yu-Han Yang6dc9f052018-12-04 17:11:24 -080076 synchronized (mLock) {
Yu-Han Yang890ca8b2018-04-16 22:11:31 -070077 boolean added = mNative.addGeofence(geofenceId, latitude, longitude, radius,
78 lastTransition, monitorTransitions, notificationResponsiveness,
79 unknownTimer);
80 if (added) {
81 GeofenceEntry entry = new GeofenceEntry();
82 entry.geofenceId = geofenceId;
83 entry.latitude = latitude;
84 entry.longitude = longitude;
85 entry.radius = radius;
86 entry.lastTransition = lastTransition;
87 entry.monitorTransitions = monitorTransitions;
88 entry.notificationResponsiveness = notificationResponsiveness;
89 entry.unknownTimer = unknownTimer;
90 mGeofenceEntries.put(geofenceId, entry);
91 }
92 return added;
Yu-Han Yang6dc9f052018-12-04 17:11:24 -080093 }
Yu-Han Yang890ca8b2018-04-16 22:11:31 -070094 }
95
96 @Override
97 public boolean removeHardwareGeofence(int geofenceId) {
Yu-Han Yang6dc9f052018-12-04 17:11:24 -080098 synchronized (mLock) {
Yu-Han Yang890ca8b2018-04-16 22:11:31 -070099 boolean removed = mNative.removeGeofence(geofenceId);
100 if (removed) {
101 mGeofenceEntries.remove(geofenceId);
102 }
103 return removed;
Yu-Han Yang6dc9f052018-12-04 17:11:24 -0800104 }
Yu-Han Yang890ca8b2018-04-16 22:11:31 -0700105 }
106
107 @Override
108 public boolean pauseHardwareGeofence(int geofenceId) {
Yu-Han Yang6dc9f052018-12-04 17:11:24 -0800109 synchronized (mLock) {
Yu-Han Yang890ca8b2018-04-16 22:11:31 -0700110 boolean paused = mNative.pauseGeofence(geofenceId);
111 if (paused) {
112 GeofenceEntry entry = mGeofenceEntries.get(geofenceId);
113 if (entry != null) {
114 entry.paused = true;
115 }
116 }
117 return paused;
Yu-Han Yang6dc9f052018-12-04 17:11:24 -0800118 }
Yu-Han Yang890ca8b2018-04-16 22:11:31 -0700119 }
120
121 @Override
122 public boolean resumeHardwareGeofence(int geofenceId, int monitorTransitions) {
Yu-Han Yang6dc9f052018-12-04 17:11:24 -0800123 synchronized (mLock) {
Yu-Han Yang890ca8b2018-04-16 22:11:31 -0700124 boolean resumed = mNative.resumeGeofence(geofenceId, monitorTransitions);
125 if (resumed) {
126 GeofenceEntry entry = mGeofenceEntries.get(geofenceId);
127 if (entry != null) {
128 entry.paused = false;
129 entry.monitorTransitions = monitorTransitions;
130 }
131 }
132 return resumed;
Yu-Han Yang6dc9f052018-12-04 17:11:24 -0800133 }
Yu-Han Yang890ca8b2018-04-16 22:11:31 -0700134 }
135
136 @VisibleForTesting
137 static class GnssGeofenceProviderNative {
138 public boolean isGeofenceSupported() {
139 return native_is_geofence_supported();
140 }
141
142 public boolean addGeofence(int geofenceId, double latitude, double longitude, double radius,
143 int lastTransition, int monitorTransitions, int notificationResponsiveness,
144 int unknownTimer) {
145 return native_add_geofence(geofenceId, latitude, longitude, radius, lastTransition,
146 monitorTransitions, notificationResponsiveness, unknownTimer);
147 }
148
149 public boolean removeGeofence(int geofenceId) {
150 return native_remove_geofence(geofenceId);
151 }
152
153 public boolean resumeGeofence(int geofenceId, int transitions) {
154 return native_resume_geofence(geofenceId, transitions);
155 }
156
157 public boolean pauseGeofence(int geofenceId) {
158 return native_pause_geofence(geofenceId);
159 }
160 }
161
162 private static native boolean native_is_geofence_supported();
163
164 private static native boolean native_add_geofence(int geofenceId, double latitude,
165 double longitude, double radius, int lastTransition, int monitorTransitions,
166 int notificationResponsivenes, int unknownTimer);
167
168 private static native boolean native_remove_geofence(int geofenceId);
169
170 private static native boolean native_resume_geofence(int geofenceId, int transitions);
171
172 private static native boolean native_pause_geofence(int geofenceId);
173}