blob: a91a1dcb78e70bc300e575a402fd8a4089e11056 [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
Philip P. Moltmannbc8b48a2019-09-27 17:06:25 -070020import android.annotation.NonNull;
Philip P. Moltmann6c7377c2019-09-27 17:06:25 -070021import android.annotation.Nullable;
Nick Pelly6fa9ad42012-07-16 12:18:23 -070022import android.app.PendingIntent;
23import android.location.Geofence;
Nick Pellye0fd6932012-07-11 10:26:13 -070024import android.location.Location;
25
26/**
Nick Pelly6fa9ad42012-07-16 12:18:23 -070027 * Represents state associated with a geofence
Nick Pellye0fd6932012-07-11 10:26:13 -070028 */
Nick Pelly6fa9ad42012-07-16 12:18:23 -070029public class GeofenceState {
Nick Pellye0fd6932012-07-11 10:26:13 -070030 public final static int FLAG_ENTER = 0x01;
31 public final static int FLAG_EXIT = 0x02;
32
Nick Pelly6fa9ad42012-07-16 12:18:23 -070033 private static final int STATE_UNKNOWN = 0;
34 private static final int STATE_INSIDE = 1;
35 private static final int STATE_OUTSIDE = 2;
Nick Pellye0fd6932012-07-11 10:26:13 -070036
Nick Pelly6fa9ad42012-07-16 12:18:23 -070037 public final Geofence mFence;
38 private final Location mLocation;
39 public final long mExpireAt;
Dianne Hackborn5e45ee62013-01-24 19:13:44 -080040 public final int mAllowedResolutionLevel;
41 public final int mUid;
Nick Pelly6fa9ad42012-07-16 12:18:23 -070042 public final String mPackageName;
Philip P. Moltmann6c7377c2019-09-27 17:06:25 -070043 public final @Nullable String mFeatureId;
Philip P. Moltmannbc8b48a2019-09-27 17:06:25 -070044 public final @NonNull String mListenerIdentifier;
Nick Pelly6fa9ad42012-07-16 12:18:23 -070045 public final PendingIntent mIntent;
Nick Pellye0fd6932012-07-11 10:26:13 -070046
47 int mState; // current state
Victoria Lease4cd0a502012-11-02 16:24:08 -070048 double mDistanceToCenter; // current distance to center of fence
Nick Pellye0fd6932012-07-11 10:26:13 -070049
Philip P. Moltmannbc8b48a2019-09-27 17:06:25 -070050 public GeofenceState(Geofence fence, long expireAt, int allowedResolutionLevel, int uid,
Philip P. Moltmann6c7377c2019-09-27 17:06:25 -070051 String packageName, @Nullable String featureId, @NonNull String listenerIdentifier,
52 PendingIntent intent) {
Nick Pellye0fd6932012-07-11 10:26:13 -070053 mState = STATE_UNKNOWN;
Victoria Lease4cd0a502012-11-02 16:24:08 -070054 mDistanceToCenter = Double.MAX_VALUE;
Nick Pellye0fd6932012-07-11 10:26:13 -070055
Nick Pelly6fa9ad42012-07-16 12:18:23 -070056 mFence = fence;
57 mExpireAt = expireAt;
Dianne Hackborn5e45ee62013-01-24 19:13:44 -080058 mAllowedResolutionLevel = allowedResolutionLevel;
59 mUid = uid;
Nick Pelly6fa9ad42012-07-16 12:18:23 -070060 mPackageName = packageName;
Philip P. Moltmann6c7377c2019-09-27 17:06:25 -070061 mFeatureId = featureId;
Philip P. Moltmannbc8b48a2019-09-27 17:06:25 -070062 mListenerIdentifier = listenerIdentifier;
Nick Pelly6fa9ad42012-07-16 12:18:23 -070063 mIntent = intent;
Nick Pellye0fd6932012-07-11 10:26:13 -070064
65 mLocation = new Location("");
Nick Pelly6fa9ad42012-07-16 12:18:23 -070066 mLocation.setLatitude(fence.getLatitude());
67 mLocation.setLongitude(fence.getLongitude());
Nick Pellye0fd6932012-07-11 10:26:13 -070068 }
69
70 /**
71 * Process a new location.
72 * @return FLAG_ENTER or FLAG_EXIT if the fence was crossed, 0 otherwise
73 */
74 public int processLocation(Location location) {
Victoria Lease4cd0a502012-11-02 16:24:08 -070075 mDistanceToCenter = mLocation.distanceTo(location);
Nick Pellye0fd6932012-07-11 10:26:13 -070076
77 int prevState = mState;
78 //TODO: inside/outside detection could be made more rigorous
Victoria Lease4cd0a502012-11-02 16:24:08 -070079 boolean inside = mDistanceToCenter <= Math.max(mFence.getRadius(), location.getAccuracy());
Nick Pellye0fd6932012-07-11 10:26:13 -070080 if (inside) {
81 mState = STATE_INSIDE;
Victoria Lease4cd0a502012-11-02 16:24:08 -070082 if (prevState != STATE_INSIDE) {
83 return FLAG_ENTER; // return enter if previously exited or unknown
84 }
Nick Pellye0fd6932012-07-11 10:26:13 -070085 } else {
86 mState = STATE_OUTSIDE;
Victoria Lease4cd0a502012-11-02 16:24:08 -070087 if (prevState == STATE_INSIDE) {
88 return FLAG_EXIT; // return exit only if previously entered
89 }
Nick Pellye0fd6932012-07-11 10:26:13 -070090 }
91 return 0;
92 }
93
Victoria Lease4cd0a502012-11-02 16:24:08 -070094 /**
95 * Gets the distance from the current location to the fence's boundary.
96 * @return The distance or {@link Double#MAX_VALUE} if unknown.
97 */
98 public double getDistanceToBoundary() {
99 if (Double.compare(mDistanceToCenter, Double.MAX_VALUE) == 0) {
100 return Double.MAX_VALUE;
101 } else {
102 return Math.abs(mFence.getRadius() - mDistanceToCenter);
103 }
Nick Pellye0fd6932012-07-11 10:26:13 -0700104 }
105
106 @Override
107 public String toString() {
108 String state;
109 switch (mState) {
110 case STATE_INSIDE:
111 state = "IN";
112 break;
113 case STATE_OUTSIDE:
114 state = "OUT";
115 break;
116 default:
117 state = "?";
118 }
Victoria Lease4cd0a502012-11-02 16:24:08 -0700119 return String.format("%s d=%.0f %s", mFence.toString(), mDistanceToCenter, state);
Nick Pellye0fd6932012-07-11 10:26:13 -0700120 }
121}