blob: 3ebe20a7e8e682708739456a04b81f7c014aaea9 [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;
Dianne Hackborn5e45ee62013-01-24 19:13:44 -080038 public final int mAllowedResolutionLevel;
39 public final int mUid;
Nick Pelly6fa9ad42012-07-16 12:18:23 -070040 public final String mPackageName;
41 public final PendingIntent mIntent;
Nick Pellye0fd6932012-07-11 10:26:13 -070042
43 int mState; // current state
Victoria Lease4cd0a502012-11-02 16:24:08 -070044 double mDistanceToCenter; // current distance to center of fence
Nick Pellye0fd6932012-07-11 10:26:13 -070045
Victoria Lease4cd0a502012-11-02 16:24:08 -070046 public GeofenceState(Geofence fence, long expireAt,
Dianne Hackborn5e45ee62013-01-24 19:13:44 -080047 int allowedResolutionLevel, int uid, String packageName, PendingIntent intent) {
Nick Pellye0fd6932012-07-11 10:26:13 -070048 mState = STATE_UNKNOWN;
Victoria Lease4cd0a502012-11-02 16:24:08 -070049 mDistanceToCenter = Double.MAX_VALUE;
Nick Pellye0fd6932012-07-11 10:26:13 -070050
Nick Pelly6fa9ad42012-07-16 12:18:23 -070051 mFence = fence;
52 mExpireAt = expireAt;
Dianne Hackborn5e45ee62013-01-24 19:13:44 -080053 mAllowedResolutionLevel = allowedResolutionLevel;
54 mUid = uid;
Nick Pelly6fa9ad42012-07-16 12:18:23 -070055 mPackageName = packageName;
56 mIntent = intent;
Nick Pellye0fd6932012-07-11 10:26:13 -070057
58 mLocation = new Location("");
Nick Pelly6fa9ad42012-07-16 12:18:23 -070059 mLocation.setLatitude(fence.getLatitude());
60 mLocation.setLongitude(fence.getLongitude());
Nick Pellye0fd6932012-07-11 10:26:13 -070061 }
62
63 /**
64 * Process a new location.
65 * @return FLAG_ENTER or FLAG_EXIT if the fence was crossed, 0 otherwise
66 */
67 public int processLocation(Location location) {
Victoria Lease4cd0a502012-11-02 16:24:08 -070068 mDistanceToCenter = mLocation.distanceTo(location);
Nick Pellye0fd6932012-07-11 10:26:13 -070069
70 int prevState = mState;
71 //TODO: inside/outside detection could be made more rigorous
Victoria Lease4cd0a502012-11-02 16:24:08 -070072 boolean inside = mDistanceToCenter <= Math.max(mFence.getRadius(), location.getAccuracy());
Nick Pellye0fd6932012-07-11 10:26:13 -070073 if (inside) {
74 mState = STATE_INSIDE;
Victoria Lease4cd0a502012-11-02 16:24:08 -070075 if (prevState != STATE_INSIDE) {
76 return FLAG_ENTER; // return enter if previously exited or unknown
77 }
Nick Pellye0fd6932012-07-11 10:26:13 -070078 } else {
79 mState = STATE_OUTSIDE;
Victoria Lease4cd0a502012-11-02 16:24:08 -070080 if (prevState == STATE_INSIDE) {
81 return FLAG_EXIT; // return exit only if previously entered
82 }
Nick Pellye0fd6932012-07-11 10:26:13 -070083 }
84 return 0;
85 }
86
Victoria Lease4cd0a502012-11-02 16:24:08 -070087 /**
88 * Gets the distance from the current location to the fence's boundary.
89 * @return The distance or {@link Double#MAX_VALUE} if unknown.
90 */
91 public double getDistanceToBoundary() {
92 if (Double.compare(mDistanceToCenter, Double.MAX_VALUE) == 0) {
93 return Double.MAX_VALUE;
94 } else {
95 return Math.abs(mFence.getRadius() - mDistanceToCenter);
96 }
Nick Pellye0fd6932012-07-11 10:26:13 -070097 }
98
99 @Override
100 public String toString() {
101 String state;
102 switch (mState) {
103 case STATE_INSIDE:
104 state = "IN";
105 break;
106 case STATE_OUTSIDE:
107 state = "OUT";
108 break;
109 default:
110 state = "?";
111 }
Victoria Lease4cd0a502012-11-02 16:24:08 -0700112 return String.format("%s d=%.0f %s", mFence.toString(), mDistanceToCenter, state);
Nick Pellye0fd6932012-07-11 10:26:13 -0700113 }
114}