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; 385e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn public final int mAllowedResolutionLevel; 395e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn public final int mUid; 406fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly public final String mPackageName; 416fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly public final PendingIntent mIntent; 42e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly 43e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly int mState; // current state 444cd0a50b26eeb68517d03bc0cafc18e98bfc1fecVictoria Lease double mDistanceToCenter; // current distance to center of fence 45e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly 464cd0a50b26eeb68517d03bc0cafc18e98bfc1fecVictoria Lease public GeofenceState(Geofence fence, long expireAt, 475e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn int allowedResolutionLevel, int uid, String packageName, PendingIntent intent) { 48e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly mState = STATE_UNKNOWN; 494cd0a50b26eeb68517d03bc0cafc18e98bfc1fecVictoria Lease mDistanceToCenter = Double.MAX_VALUE; 50e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly 516fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly mFence = fence; 526fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly mExpireAt = expireAt; 535e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn mAllowedResolutionLevel = allowedResolutionLevel; 545e45ee6752528791deb66b83d76250685de15d47Dianne Hackborn mUid = uid; 556fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly mPackageName = packageName; 566fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly mIntent = intent; 57e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly 58e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly mLocation = new Location(""); 596fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly mLocation.setLatitude(fence.getLatitude()); 606fa9ad4afcd762aea519ff61811386c23d18ddb2Nick Pelly mLocation.setLongitude(fence.getLongitude()); 61e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly } 62e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly 63e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly /** 64e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly * Process a new location. 65e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly * @return FLAG_ENTER or FLAG_EXIT if the fence was crossed, 0 otherwise 66e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly */ 67e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly public int processLocation(Location location) { 684cd0a50b26eeb68517d03bc0cafc18e98bfc1fecVictoria Lease mDistanceToCenter = mLocation.distanceTo(location); 69e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly 70e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly int prevState = mState; 71e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly //TODO: inside/outside detection could be made more rigorous 724cd0a50b26eeb68517d03bc0cafc18e98bfc1fecVictoria Lease boolean inside = mDistanceToCenter <= Math.max(mFence.getRadius(), location.getAccuracy()); 73e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly if (inside) { 74e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly mState = STATE_INSIDE; 754cd0a50b26eeb68517d03bc0cafc18e98bfc1fecVictoria Lease if (prevState != STATE_INSIDE) { 764cd0a50b26eeb68517d03bc0cafc18e98bfc1fecVictoria Lease return FLAG_ENTER; // return enter if previously exited or unknown 774cd0a50b26eeb68517d03bc0cafc18e98bfc1fecVictoria Lease } 78e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly } else { 79e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly mState = STATE_OUTSIDE; 804cd0a50b26eeb68517d03bc0cafc18e98bfc1fecVictoria Lease if (prevState == STATE_INSIDE) { 814cd0a50b26eeb68517d03bc0cafc18e98bfc1fecVictoria Lease return FLAG_EXIT; // return exit only if previously entered 824cd0a50b26eeb68517d03bc0cafc18e98bfc1fecVictoria Lease } 83e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly } 84e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly return 0; 85e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly } 86e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly 874cd0a50b26eeb68517d03bc0cafc18e98bfc1fecVictoria Lease /** 884cd0a50b26eeb68517d03bc0cafc18e98bfc1fecVictoria Lease * Gets the distance from the current location to the fence's boundary. 894cd0a50b26eeb68517d03bc0cafc18e98bfc1fecVictoria Lease * @return The distance or {@link Double#MAX_VALUE} if unknown. 904cd0a50b26eeb68517d03bc0cafc18e98bfc1fecVictoria Lease */ 914cd0a50b26eeb68517d03bc0cafc18e98bfc1fecVictoria Lease public double getDistanceToBoundary() { 924cd0a50b26eeb68517d03bc0cafc18e98bfc1fecVictoria Lease if (Double.compare(mDistanceToCenter, Double.MAX_VALUE) == 0) { 934cd0a50b26eeb68517d03bc0cafc18e98bfc1fecVictoria Lease return Double.MAX_VALUE; 944cd0a50b26eeb68517d03bc0cafc18e98bfc1fecVictoria Lease } else { 954cd0a50b26eeb68517d03bc0cafc18e98bfc1fecVictoria Lease return Math.abs(mFence.getRadius() - mDistanceToCenter); 964cd0a50b26eeb68517d03bc0cafc18e98bfc1fecVictoria Lease } 97e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly } 98e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly 99e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly @Override 100e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly public String toString() { 101e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly String state; 102e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly switch (mState) { 103e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly case STATE_INSIDE: 104e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly state = "IN"; 105e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly break; 106e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly case STATE_OUTSIDE: 107e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly state = "OUT"; 108e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly break; 109e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly default: 110e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly state = "?"; 111e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly } 1124cd0a50b26eeb68517d03bc0cafc18e98bfc1fecVictoria Lease return String.format("%s d=%.0f %s", mFence.toString(), mDistanceToCenter, state); 113e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly } 114e0fd693c6098f59004f9e96ad75c058e26c337b0Nick Pelly} 115