Home | History | Annotate | Download | only in location
      1 /*
      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 
     18 package com.android.server.location;
     19 
     20 import android.app.PendingIntent;
     21 import android.location.Geofence;
     22 import android.location.Location;
     23 
     24 /**
     25  * Represents state associated with a geofence
     26  */
     27 public class GeofenceState {
     28     public final static int FLAG_ENTER = 0x01;
     29     public final static int FLAG_EXIT = 0x02;
     30 
     31     private static final int STATE_UNKNOWN = 0;
     32     private static final int STATE_INSIDE = 1;
     33     private static final int STATE_OUTSIDE = 2;
     34 
     35     public final Geofence mFence;
     36     private final Location mLocation;
     37     public final long mExpireAt;
     38     public final int mAllowedResolutionLevel;
     39     public final int mUid;
     40     public final String mPackageName;
     41     public final PendingIntent mIntent;
     42 
     43     int mState;  // current state
     44     double mDistanceToCenter;  // current distance to center of fence
     45 
     46     public GeofenceState(Geofence fence, long expireAt,
     47             int allowedResolutionLevel, int uid, String packageName, PendingIntent intent) {
     48         mState = STATE_UNKNOWN;
     49         mDistanceToCenter = Double.MAX_VALUE;
     50 
     51         mFence = fence;
     52         mExpireAt = expireAt;
     53         mAllowedResolutionLevel = allowedResolutionLevel;
     54         mUid = uid;
     55         mPackageName = packageName;
     56         mIntent = intent;
     57 
     58         mLocation = new Location("");
     59         mLocation.setLatitude(fence.getLatitude());
     60         mLocation.setLongitude(fence.getLongitude());
     61     }
     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) {
     68         mDistanceToCenter = mLocation.distanceTo(location);
     69 
     70         int prevState = mState;
     71         //TODO: inside/outside detection could be made more rigorous
     72         boolean inside = mDistanceToCenter <= Math.max(mFence.getRadius(), location.getAccuracy());
     73         if (inside) {
     74             mState = STATE_INSIDE;
     75             if (prevState != STATE_INSIDE) {
     76                 return FLAG_ENTER; // return enter if previously exited or unknown
     77             }
     78         } else {
     79             mState = STATE_OUTSIDE;
     80             if (prevState == STATE_INSIDE) {
     81                 return FLAG_EXIT; // return exit only if previously entered
     82             }
     83         }
     84         return 0;
     85     }
     86 
     87     /**
     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         }
     97     }
     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         }
    112         return String.format("%s d=%.0f %s", mFence.toString(), mDistanceToCenter, state);
    113     }
    114 }
    115