1e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly/* 2e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly * Copyright (C) 2012 The Android Open Source Project 3e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly * 4e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly * Licensed under the Apache License, Version 2.0 (the "License"); 5e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly * you may not use this file except in compliance with the License. 6e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly * You may obtain a copy of the License at 7e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly * 8e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly * http://www.apache.org/licenses/LICENSE-2.0 9e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly * 10e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly * Unless required by applicable law or agreed to in writing, software 11e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly * distributed under the License is distributed on an "AS IS" BASIS, 12e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly * See the License for the specific language governing permissions and 14e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly * limitations under the License. 15e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly */ 16e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly 17e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly 18e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pellypackage com.android.server.location; 19e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly 206fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pellyimport android.app.PendingIntent; 216fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pellyimport android.location.Geofence; 22e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pellyimport android.location.Location; 23e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly 24e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly/** 256fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly * Represents state associated with a geofence 26e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly */ 276fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pellypublic class GeofenceState { 28e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly public final static int FLAG_ENTER = 0x01; 29e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly public final static int FLAG_EXIT = 0x02; 30e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly 316fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly private static final int STATE_UNKNOWN = 0; 326fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly private static final int STATE_INSIDE = 1; 336fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly private static final int STATE_OUTSIDE = 2; 34e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly 356fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly public final Geofence mFence; 366fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly private final Location mLocation; 376fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly public final long mExpireAt; 386fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly public final String mPackageName; 396fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly public final PendingIntent mIntent; 40e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly 41e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly int mState; // current state 424cd0a50b26eeb68517d03bc0cafc18e98bfc1fecVictoria Lease double mDistanceToCenter; // current distance to center of fence 43e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly 444cd0a50b26eeb68517d03bc0cafc18e98bfc1fecVictoria Lease public GeofenceState(Geofence fence, long expireAt, 456fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly String packageName, PendingIntent intent) { 46e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly mState = STATE_UNKNOWN; 474cd0a50b26eeb68517d03bc0cafc18e98bfc1fecVictoria Lease mDistanceToCenter = Double.MAX_VALUE; 48e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly 496fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly mFence = fence; 506fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly mExpireAt = expireAt; 516fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly mPackageName = packageName; 526fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly mIntent = intent; 53e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly 54e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly mLocation = new Location(""); 556fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly mLocation.setLatitude(fence.getLatitude()); 566fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly mLocation.setLongitude(fence.getLongitude()); 57e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly } 58e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly 59e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly /** 60e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly * Process a new location. 61e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly * @return FLAG_ENTER or FLAG_EXIT if the fence was crossed, 0 otherwise 62e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly */ 63e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly public int processLocation(Location location) { 644cd0a50b26eeb68517d03bc0cafc18e98bfc1fecVictoria Lease mDistanceToCenter = mLocation.distanceTo(location); 65e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly 66e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly int prevState = mState; 67e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly //TODO: inside/outside detection could be made more rigorous 684cd0a50b26eeb68517d03bc0cafc18e98bfc1fecVictoria Lease boolean inside = mDistanceToCenter <= Math.max(mFence.getRadius(), location.getAccuracy()); 69e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly if (inside) { 70e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly mState = STATE_INSIDE; 714cd0a50b26eeb68517d03bc0cafc18e98bfc1fecVictoria Lease if (prevState != STATE_INSIDE) { 724cd0a50b26eeb68517d03bc0cafc18e98bfc1fecVictoria Lease return FLAG_ENTER; // return enter if previously exited or unknown 734cd0a50b26eeb68517d03bc0cafc18e98bfc1fecVictoria Lease } 74e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly } else { 75e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly mState = STATE_OUTSIDE; 764cd0a50b26eeb68517d03bc0cafc18e98bfc1fecVictoria Lease if (prevState == STATE_INSIDE) { 774cd0a50b26eeb68517d03bc0cafc18e98bfc1fecVictoria Lease return FLAG_EXIT; // return exit only if previously entered 784cd0a50b26eeb68517d03bc0cafc18e98bfc1fecVictoria Lease } 79e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly } 80e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly return 0; 81e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly } 82e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly 834cd0a50b26eeb68517d03bc0cafc18e98bfc1fecVictoria Lease /** 844cd0a50b26eeb68517d03bc0cafc18e98bfc1fecVictoria Lease * Gets the distance from the current location to the fence's boundary. 854cd0a50b26eeb68517d03bc0cafc18e98bfc1fecVictoria Lease * @return The distance or {@link Double#MAX_VALUE} if unknown. 864cd0a50b26eeb68517d03bc0cafc18e98bfc1fecVictoria Lease */ 874cd0a50b26eeb68517d03bc0cafc18e98bfc1fecVictoria Lease public double getDistanceToBoundary() { 884cd0a50b26eeb68517d03bc0cafc18e98bfc1fecVictoria Lease if (Double.compare(mDistanceToCenter, Double.MAX_VALUE) == 0) { 894cd0a50b26eeb68517d03bc0cafc18e98bfc1fecVictoria Lease return Double.MAX_VALUE; 904cd0a50b26eeb68517d03bc0cafc18e98bfc1fecVictoria Lease } else { 914cd0a50b26eeb68517d03bc0cafc18e98bfc1fecVictoria Lease return Math.abs(mFence.getRadius() - mDistanceToCenter); 924cd0a50b26eeb68517d03bc0cafc18e98bfc1fecVictoria Lease } 93e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly } 94e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly 95e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly @Override 96e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly public String toString() { 97e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly String state; 98e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly switch (mState) { 99e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly case STATE_INSIDE: 100e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly state = "IN"; 101e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly break; 102e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly case STATE_OUTSIDE: 103e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly state = "OUT"; 104e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly break; 105e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly default: 106e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly state = "?"; 107e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly } 1084cd0a50b26eeb68517d03bc0cafc18e98bfc1fecVictoria Lease return String.format("%s d=%.0f %s", mFence.toString(), mDistanceToCenter, state); 109e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly } 110e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly} 111