1 /* This Source Code Form is subject to the terms of the Mozilla Public 2 * License, v. 2.0. If a copy of the MPL was not distributed with this 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 4 5 package org.mozilla.mozstumbler.service.stumblerthread.scanners; 6 7 import android.location.Location; 8 import android.util.Log; 9 import org.mozilla.mozstumbler.service.AppGlobals; 10 import org.mozilla.mozstumbler.service.Prefs; 11 12 public final class LocationBlockList { 13 private static final String LOG_TAG = AppGlobals.makeLogTag(LocationBlockList.class.getSimpleName()); 14 private static final double MAX_ALTITUDE = 8848; // Mount Everest's altitude in meters 15 private static final double MIN_ALTITUDE = -418; // Dead Sea's altitude in meters 16 private static final float MAX_SPEED = 340.29f; // Mach 1 in meters/second 17 private static final float MIN_ACCURACY = 500; // meter radius 18 private static final long MIN_TIMESTAMP = 946684801; // 2000-01-01 00:00:01 19 private static final double GEOFENCE_RADIUS = 0.01; // .01 degrees is approximately 1km 20 private static final long MILLISECONDS_PER_DAY = 86400000; 21 22 private Location mBlockedLocation; 23 private boolean mGeofencingEnabled; 24 private boolean mIsGeofenced = false; 25 LocationBlockList()26 public LocationBlockList() { 27 updateBlocks(); 28 } 29 updateBlocks()30 public void updateBlocks() { 31 Prefs prefs = Prefs.getInstanceWithoutContext(); 32 if (prefs == null) { 33 return; 34 } 35 mBlockedLocation = prefs.getGeofenceLocation(); 36 mGeofencingEnabled = prefs.getGeofenceEnabled(); 37 } 38 contains(Location location)39 public boolean contains(Location location) { 40 final float inaccuracy = location.getAccuracy(); 41 final double altitude = location.getAltitude(); 42 final float bearing = location.getBearing(); 43 final double latitude = location.getLatitude(); 44 final double longitude = location.getLongitude(); 45 final float speed = location.getSpeed(); 46 final long timestamp = location.getTime(); 47 final long tomorrow = System.currentTimeMillis() + MILLISECONDS_PER_DAY; 48 49 boolean block = false; 50 mIsGeofenced = false; 51 52 if (latitude == 0 && longitude == 0) { 53 block = true; 54 Log.w(LOG_TAG, "Bogus latitude,longitude: 0,0"); 55 } else { 56 if (latitude < -90 || latitude > 90) { 57 block = true; 58 Log.w(LOG_TAG, "Bogus latitude: " + latitude); 59 } 60 61 if (longitude < -180 || longitude > 180) { 62 block = true; 63 Log.w(LOG_TAG, "Bogus longitude: " + longitude); 64 } 65 } 66 67 if (location.hasAccuracy() && (inaccuracy < 0 || inaccuracy > MIN_ACCURACY)) { 68 block = true; 69 Log.w(LOG_TAG, "Insufficient accuracy: " + inaccuracy + " meters"); 70 } 71 72 if (location.hasAltitude() && (altitude < MIN_ALTITUDE || altitude > MAX_ALTITUDE)) { 73 block = true; 74 Log.w(LOG_TAG, "Bogus altitude: " + altitude + " meters"); 75 } 76 77 if (location.hasBearing() && (bearing < 0 || bearing > 360)) { 78 block = true; 79 Log.w(LOG_TAG, "Bogus bearing: " + bearing + " degrees"); 80 } 81 82 if (location.hasSpeed() && (speed < 0 || speed > MAX_SPEED)) { 83 block = true; 84 Log.w(LOG_TAG, "Bogus speed: " + speed + " meters/second"); 85 } 86 87 if (timestamp < MIN_TIMESTAMP || timestamp > tomorrow) { 88 block = true; 89 Log.w(LOG_TAG, "Bogus timestamp: " + timestamp); 90 } 91 92 if (mGeofencingEnabled && 93 Math.abs(location.getLatitude() - mBlockedLocation.getLatitude()) < GEOFENCE_RADIUS && 94 Math.abs(location.getLongitude() - mBlockedLocation.getLongitude()) < GEOFENCE_RADIUS) { 95 block = true; 96 mIsGeofenced = true; 97 } 98 99 return block; 100 } 101 isGeofenced()102 public boolean isGeofenced() { 103 return mIsGeofenced; 104 } 105 } 106