blob: 11705ffa572f9ad611a64b5d294b2c687d4074c2 [file] [log] [blame]
Nick Pellye0fd6932012-07-11 10:26:13 -07001/*
2 * Copyright (C) 2012 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17
18package com.android.server.location;
19
Nick Pelly6fa9ad42012-07-16 12:18:23 -070020import android.app.PendingIntent;
21import android.location.Geofence;
Nick Pellye0fd6932012-07-11 10:26:13 -070022import android.location.Location;
23
24/**
Nick Pelly6fa9ad42012-07-16 12:18:23 -070025 * Represents state associated with a geofence
Nick Pellye0fd6932012-07-11 10:26:13 -070026 */
Nick Pelly6fa9ad42012-07-16 12:18:23 -070027public class GeofenceState {
Nick Pellye0fd6932012-07-11 10:26:13 -070028 public final static int FLAG_ENTER = 0x01;
29 public final static int FLAG_EXIT = 0x02;
30
Nick Pelly6fa9ad42012-07-16 12:18:23 -070031 private static final int STATE_UNKNOWN = 0;
32 private static final int STATE_INSIDE = 1;
33 private static final int STATE_OUTSIDE = 2;
Nick Pellye0fd6932012-07-11 10:26:13 -070034
Nick Pelly6fa9ad42012-07-16 12:18:23 -070035 public final Geofence mFence;
36 private final Location mLocation;
37 public final long mExpireAt;
38 public final String mPackageName;
39 public final PendingIntent mIntent;
Nick Pellye0fd6932012-07-11 10:26:13 -070040
41 int mState; // current state
Victoria Lease4cd0a502012-11-02 16:24:08 -070042 double mDistanceToCenter; // current distance to center of fence
Nick Pellye0fd6932012-07-11 10:26:13 -070043
Victoria Lease4cd0a502012-11-02 16:24:08 -070044 public GeofenceState(Geofence fence, long expireAt,
Nick Pelly6fa9ad42012-07-16 12:18:23 -070045 String packageName, PendingIntent intent) {
Nick Pellye0fd6932012-07-11 10:26:13 -070046 mState = STATE_UNKNOWN;
Victoria Lease4cd0a502012-11-02 16:24:08 -070047 mDistanceToCenter = Double.MAX_VALUE;
Nick Pellye0fd6932012-07-11 10:26:13 -070048
Nick Pelly6fa9ad42012-07-16 12:18:23 -070049 mFence = fence;
50 mExpireAt = expireAt;
51 mPackageName = packageName;
52 mIntent = intent;
Nick Pellye0fd6932012-07-11 10:26:13 -070053
54 mLocation = new Location("");
Nick Pelly6fa9ad42012-07-16 12:18:23 -070055 mLocation.setLatitude(fence.getLatitude());
56 mLocation.setLongitude(fence.getLongitude());
Nick Pellye0fd6932012-07-11 10:26:13 -070057 }
58
59 /**
60 * Process a new location.
61 * @return FLAG_ENTER or FLAG_EXIT if the fence was crossed, 0 otherwise
62 */
63 public int processLocation(Location location) {
Victoria Lease4cd0a502012-11-02 16:24:08 -070064 mDistanceToCenter = mLocation.distanceTo(location);
Nick Pellye0fd6932012-07-11 10:26:13 -070065
66 int prevState = mState;
67 //TODO: inside/outside detection could be made more rigorous
Victoria Lease4cd0a502012-11-02 16:24:08 -070068 boolean inside = mDistanceToCenter <= Math.max(mFence.getRadius(), location.getAccuracy());
Nick Pellye0fd6932012-07-11 10:26:13 -070069 if (inside) {
70 mState = STATE_INSIDE;
Victoria Lease4cd0a502012-11-02 16:24:08 -070071 if (prevState != STATE_INSIDE) {
72 return FLAG_ENTER; // return enter if previously exited or unknown
73 }
Nick Pellye0fd6932012-07-11 10:26:13 -070074 } else {
75 mState = STATE_OUTSIDE;
Victoria Lease4cd0a502012-11-02 16:24:08 -070076 if (prevState == STATE_INSIDE) {
77 return FLAG_EXIT; // return exit only if previously entered
78 }
Nick Pellye0fd6932012-07-11 10:26:13 -070079 }
80 return 0;
81 }
82
Victoria Lease4cd0a502012-11-02 16:24:08 -070083 /**
84 * Gets the distance from the current location to the fence's boundary.
85 * @return The distance or {@link Double#MAX_VALUE} if unknown.
86 */
87 public double getDistanceToBoundary() {
88 if (Double.compare(mDistanceToCenter, Double.MAX_VALUE) == 0) {
89 return Double.MAX_VALUE;
90 } else {
91 return Math.abs(mFence.getRadius() - mDistanceToCenter);
92 }
Nick Pellye0fd6932012-07-11 10:26:13 -070093 }
94
95 @Override
96 public String toString() {
97 String state;
98 switch (mState) {
99 case STATE_INSIDE:
100 state = "IN";
101 break;
102 case STATE_OUTSIDE:
103 state = "OUT";
104 break;
105 default:
106 state = "?";
107 }
Victoria Lease4cd0a502012-11-02 16:24:08 -0700108 return String.format("%s d=%.0f %s", mFence.toString(), mDistanceToCenter, state);
Nick Pellye0fd6932012-07-11 10:26:13 -0700109 }
110}