summaryrefslogtreecommitdiffstats
path: root/services/core/java/com/android/server/location/GeofenceState.java
diff options
context:
space:
mode:
Diffstat (limited to 'services/core/java/com/android/server/location/GeofenceState.java')
-rw-r--r--services/core/java/com/android/server/location/GeofenceState.java114
1 files changed, 114 insertions, 0 deletions
diff --git a/services/core/java/com/android/server/location/GeofenceState.java b/services/core/java/com/android/server/location/GeofenceState.java
new file mode 100644
index 0000000..3ebe20a
--- /dev/null
+++ b/services/core/java/com/android/server/location/GeofenceState.java
@@ -0,0 +1,114 @@
+/*
+ * Copyright (C) 2012 The Android Open Source Project
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+
+package com.android.server.location;
+
+import android.app.PendingIntent;
+import android.location.Geofence;
+import android.location.Location;
+
+/**
+ * Represents state associated with a geofence
+ */
+public class GeofenceState {
+ public final static int FLAG_ENTER = 0x01;
+ public final static int FLAG_EXIT = 0x02;
+
+ private static final int STATE_UNKNOWN = 0;
+ private static final int STATE_INSIDE = 1;
+ private static final int STATE_OUTSIDE = 2;
+
+ public final Geofence mFence;
+ private final Location mLocation;
+ public final long mExpireAt;
+ public final int mAllowedResolutionLevel;
+ public final int mUid;
+ public final String mPackageName;
+ public final PendingIntent mIntent;
+
+ int mState; // current state
+ double mDistanceToCenter; // current distance to center of fence
+
+ public GeofenceState(Geofence fence, long expireAt,
+ int allowedResolutionLevel, int uid, String packageName, PendingIntent intent) {
+ mState = STATE_UNKNOWN;
+ mDistanceToCenter = Double.MAX_VALUE;
+
+ mFence = fence;
+ mExpireAt = expireAt;
+ mAllowedResolutionLevel = allowedResolutionLevel;
+ mUid = uid;
+ mPackageName = packageName;
+ mIntent = intent;
+
+ mLocation = new Location("");
+ mLocation.setLatitude(fence.getLatitude());
+ mLocation.setLongitude(fence.getLongitude());
+ }
+
+ /**
+ * Process a new location.
+ * @return FLAG_ENTER or FLAG_EXIT if the fence was crossed, 0 otherwise
+ */
+ public int processLocation(Location location) {
+ mDistanceToCenter = mLocation.distanceTo(location);
+
+ int prevState = mState;
+ //TODO: inside/outside detection could be made more rigorous
+ boolean inside = mDistanceToCenter <= Math.max(mFence.getRadius(), location.getAccuracy());
+ if (inside) {
+ mState = STATE_INSIDE;
+ if (prevState != STATE_INSIDE) {
+ return FLAG_ENTER; // return enter if previously exited or unknown
+ }
+ } else {
+ mState = STATE_OUTSIDE;
+ if (prevState == STATE_INSIDE) {
+ return FLAG_EXIT; // return exit only if previously entered
+ }
+ }
+ return 0;
+ }
+
+ /**
+ * Gets the distance from the current location to the fence's boundary.
+ * @return The distance or {@link Double#MAX_VALUE} if unknown.
+ */
+ public double getDistanceToBoundary() {
+ if (Double.compare(mDistanceToCenter, Double.MAX_VALUE) == 0) {
+ return Double.MAX_VALUE;
+ } else {
+ return Math.abs(mFence.getRadius() - mDistanceToCenter);
+ }
+ }
+
+ @Override
+ public String toString() {
+ String state;
+ switch (mState) {
+ case STATE_INSIDE:
+ state = "IN";
+ break;
+ case STATE_OUTSIDE:
+ state = "OUT";
+ break;
+ default:
+ state = "?";
+ }
+ return String.format("%s d=%.0f %s", mFence.toString(), mDistanceToCenter, state);
+ }
+}