18ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh/* 28ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh * Copyright (C) 2013 The Android Open Source Project 38ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh * 48ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh * Licensed under the Apache License, Version 2.0 (the "License"); 58ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh * you may not use this file except in compliance with the License. 68ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh * You may obtain a copy of the License at 78ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh * 88ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh * http://www.apache.org/licenses/LICENSE-2.0 98ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh * 108ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh * Unless required by applicable law or agreed to in writing, software 118ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh * distributed under the License is distributed on an "AS IS" BASIS, 128ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 138ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh * See the License for the specific language governing permissions and 148ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh * limitations under the License. 158ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh */ 168ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 178ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganeshpackage android.hardware.location; 188ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 198ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganeshimport android.content.Context; 208ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganeshimport android.content.pm.PackageManager; 210682809ad08db284d7110aab44108d5e9c310e6bdestradaaimport android.location.IFusedGeofenceHardware; 228ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganeshimport android.location.IGpsGeofenceHardware; 238ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganeshimport android.location.Location; 248ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganeshimport android.os.Handler; 25da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganeshimport android.os.IBinder; 268ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganeshimport android.os.Message; 278ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganeshimport android.os.PowerManager; 288ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganeshimport android.os.RemoteException; 298ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganeshimport android.util.Log; 308ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganeshimport android.util.SparseArray; 318ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 328ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganeshimport java.util.ArrayList; 338ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 348ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh/** 358ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh * This class manages the geofences which are handled by hardware. 368ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh * 378ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh * @hide 388ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh */ 398ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganeshpublic final class GeofenceHardwareImpl { 408ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh private static final String TAG = "GeofenceHardwareImpl"; 418ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); 428ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 438ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh private final Context mContext; 448ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh private static GeofenceHardwareImpl sInstance; 458ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh private PowerManager.WakeLock mWakeLock; 46f8f085c51b5f8b180ad964d0385b34f8fa97cd32Zhentao Sun private final SparseArray<IGeofenceHardwareCallback> mGeofences = 478ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh new SparseArray<IGeofenceHardwareCallback>(); 48f8f085c51b5f8b180ad964d0385b34f8fa97cd32Zhentao Sun private final ArrayList<IGeofenceHardwareMonitorCallback>[] mCallbacks = 498ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh new ArrayList[GeofenceHardware.NUM_MONITORS]; 50f8f085c51b5f8b180ad964d0385b34f8fa97cd32Zhentao Sun private final ArrayList<Reaper> mReapers = new ArrayList<Reaper>(); 518ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 520682809ad08db284d7110aab44108d5e9c310e6bdestradaa private IFusedGeofenceHardware mFusedService; 538ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh private IGpsGeofenceHardware mGpsService; 548ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 558ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh private int[] mSupportedMonitorTypes = new int[GeofenceHardware.NUM_MONITORS]; 568ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 578ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh // mGeofenceHandler message types 588ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh private static final int GEOFENCE_TRANSITION_CALLBACK = 1; 598ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh private static final int ADD_GEOFENCE_CALLBACK = 2; 608ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh private static final int REMOVE_GEOFENCE_CALLBACK = 3; 618ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh private static final int PAUSE_GEOFENCE_CALLBACK = 4; 628ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh private static final int RESUME_GEOFENCE_CALLBACK = 5; 63f8f085c51b5f8b180ad964d0385b34f8fa97cd32Zhentao Sun private static final int GEOFENCE_CALLBACK_BINDER_DIED = 6; 648ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 658ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh // mCallbacksHandler message types 660682809ad08db284d7110aab44108d5e9c310e6bdestradaa private static final int GEOFENCE_STATUS = 1; 678ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh private static final int CALLBACK_ADD = 2; 688ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh private static final int CALLBACK_REMOVE = 3; 69da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh private static final int MONITOR_CALLBACK_BINDER_DIED = 4; 70da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh 71da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh // mReaperHandler message types 72da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh private static final int REAPER_GEOFENCE_ADDED = 1; 73da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh private static final int REAPER_MONITOR_CALLBACK_ADDED = 2; 74da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh private static final int REAPER_REMOVED = 3; 758ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 768ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh // The following constants need to match GpsLocationFlags enum in gps.h 778ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh private static final int LOCATION_INVALID = 0; 788ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh private static final int LOCATION_HAS_LAT_LONG = 1; 798ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh private static final int LOCATION_HAS_ALTITUDE = 2; 808ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh private static final int LOCATION_HAS_SPEED = 4; 818ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh private static final int LOCATION_HAS_BEARING = 8; 828ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh private static final int LOCATION_HAS_ACCURACY = 16; 838ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 848ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh // Resolution level constants used for permission checks. 858ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh // These constants must be in increasing order of finer resolution. 868ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh private static final int RESOLUTION_LEVEL_NONE = 1; 878ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh private static final int RESOLUTION_LEVEL_COARSE = 2; 888ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh private static final int RESOLUTION_LEVEL_FINE = 3; 898ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 908ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh public synchronized static GeofenceHardwareImpl getInstance(Context context) { 918ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh if (sInstance == null) { 928ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh sInstance = new GeofenceHardwareImpl(context); 938ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 948ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh return sInstance; 958ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 968ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 978ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh private GeofenceHardwareImpl(Context context) { 988ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh mContext = context; 998ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh // Init everything to unsupported. 1008ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh setMonitorAvailability(GeofenceHardware.MONITORING_TYPE_GPS_HARDWARE, 1018ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh GeofenceHardware.MONITOR_UNSUPPORTED); 1020682809ad08db284d7110aab44108d5e9c310e6bdestradaa setMonitorAvailability( 1030682809ad08db284d7110aab44108d5e9c310e6bdestradaa GeofenceHardware.MONITORING_TYPE_FUSED_HARDWARE, 1040682809ad08db284d7110aab44108d5e9c310e6bdestradaa GeofenceHardware.MONITOR_UNSUPPORTED); 1058ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 1068ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 1078ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 1088ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh private void acquireWakeLock() { 1098ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh if (mWakeLock == null) { 1108ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh PowerManager powerManager = 1118ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh (PowerManager) mContext.getSystemService(Context.POWER_SERVICE); 1128ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG); 1138ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 1148ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh mWakeLock.acquire(); 1158ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 1168ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 1178ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh private void releaseWakeLock() { 1188ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh if (mWakeLock.isHeld()) mWakeLock.release(); 1198ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 1208ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 1218ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh private void updateGpsHardwareAvailability() { 1228ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh //Check which monitors are available. 1238ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh boolean gpsSupported; 1248ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh try { 1258ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh gpsSupported = mGpsService.isHardwareGeofenceSupported(); 1268ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } catch (RemoteException e) { 1278ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh Log.e(TAG, "Remote Exception calling LocationManagerService"); 1288ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh gpsSupported = false; 1298ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 1308ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 1318ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh if (gpsSupported) { 1328ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh // Its assumed currently available at startup. 1338ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh // native layer will update later. 1348ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh setMonitorAvailability(GeofenceHardware.MONITORING_TYPE_GPS_HARDWARE, 1358ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh GeofenceHardware.MONITOR_CURRENTLY_AVAILABLE); 1368ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 1378ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 1388ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 1390682809ad08db284d7110aab44108d5e9c310e6bdestradaa private void updateFusedHardwareAvailability() { 1400682809ad08db284d7110aab44108d5e9c310e6bdestradaa boolean fusedSupported; 1410682809ad08db284d7110aab44108d5e9c310e6bdestradaa try { 1420682809ad08db284d7110aab44108d5e9c310e6bdestradaa fusedSupported = mFusedService.isSupported(); 1430682809ad08db284d7110aab44108d5e9c310e6bdestradaa } catch(RemoteException e) { 1440682809ad08db284d7110aab44108d5e9c310e6bdestradaa Log.e(TAG, "RemoteException calling LocationManagerService"); 1450682809ad08db284d7110aab44108d5e9c310e6bdestradaa fusedSupported = false; 1460682809ad08db284d7110aab44108d5e9c310e6bdestradaa } 1470682809ad08db284d7110aab44108d5e9c310e6bdestradaa 1480682809ad08db284d7110aab44108d5e9c310e6bdestradaa if(fusedSupported) { 1490682809ad08db284d7110aab44108d5e9c310e6bdestradaa setMonitorAvailability( 1500682809ad08db284d7110aab44108d5e9c310e6bdestradaa GeofenceHardware.MONITORING_TYPE_FUSED_HARDWARE, 1510682809ad08db284d7110aab44108d5e9c310e6bdestradaa GeofenceHardware.MONITOR_CURRENTLY_AVAILABLE); 1520682809ad08db284d7110aab44108d5e9c310e6bdestradaa } 1530682809ad08db284d7110aab44108d5e9c310e6bdestradaa } 1540682809ad08db284d7110aab44108d5e9c310e6bdestradaa 1558ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh public void setGpsHardwareGeofence(IGpsGeofenceHardware service) { 1568ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh if (mGpsService == null) { 1578ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh mGpsService = service; 1588ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh updateGpsHardwareAvailability(); 1598ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } else if (service == null) { 1608ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh mGpsService = null; 1618ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh Log.w(TAG, "GPS Geofence Hardware service seems to have crashed"); 1628ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } else { 1638ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh Log.e(TAG, "Error: GpsService being set again."); 1648ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 1658ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 1668ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 1670682809ad08db284d7110aab44108d5e9c310e6bdestradaa public void setFusedGeofenceHardware(IFusedGeofenceHardware service) { 1680682809ad08db284d7110aab44108d5e9c310e6bdestradaa if(mFusedService == null) { 1690682809ad08db284d7110aab44108d5e9c310e6bdestradaa mFusedService = service; 1700682809ad08db284d7110aab44108d5e9c310e6bdestradaa updateFusedHardwareAvailability(); 1710682809ad08db284d7110aab44108d5e9c310e6bdestradaa } else if(service == null) { 1720682809ad08db284d7110aab44108d5e9c310e6bdestradaa mFusedService = null; 1730682809ad08db284d7110aab44108d5e9c310e6bdestradaa Log.w(TAG, "Fused Geofence Hardware service seems to have crashed"); 1740682809ad08db284d7110aab44108d5e9c310e6bdestradaa } else { 1750682809ad08db284d7110aab44108d5e9c310e6bdestradaa Log.e(TAG, "Error: FusedService being set again"); 1760682809ad08db284d7110aab44108d5e9c310e6bdestradaa } 1770682809ad08db284d7110aab44108d5e9c310e6bdestradaa } 1780682809ad08db284d7110aab44108d5e9c310e6bdestradaa 179da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh public int[] getMonitoringTypes() { 1800682809ad08db284d7110aab44108d5e9c310e6bdestradaa boolean gpsSupported; 1810682809ad08db284d7110aab44108d5e9c310e6bdestradaa boolean fusedSupported; 1828ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh synchronized (mSupportedMonitorTypes) { 1830682809ad08db284d7110aab44108d5e9c310e6bdestradaa gpsSupported = mSupportedMonitorTypes[GeofenceHardware.MONITORING_TYPE_GPS_HARDWARE] 1840682809ad08db284d7110aab44108d5e9c310e6bdestradaa != GeofenceHardware.MONITOR_UNSUPPORTED; 1850682809ad08db284d7110aab44108d5e9c310e6bdestradaa fusedSupported = mSupportedMonitorTypes[GeofenceHardware.MONITORING_TYPE_FUSED_HARDWARE] 1860682809ad08db284d7110aab44108d5e9c310e6bdestradaa != GeofenceHardware.MONITOR_UNSUPPORTED; 1870682809ad08db284d7110aab44108d5e9c310e6bdestradaa } 1880682809ad08db284d7110aab44108d5e9c310e6bdestradaa 1890682809ad08db284d7110aab44108d5e9c310e6bdestradaa if(gpsSupported) { 1900682809ad08db284d7110aab44108d5e9c310e6bdestradaa if(fusedSupported) { 1910682809ad08db284d7110aab44108d5e9c310e6bdestradaa return new int[] { 1920682809ad08db284d7110aab44108d5e9c310e6bdestradaa GeofenceHardware.MONITORING_TYPE_GPS_HARDWARE, 1930682809ad08db284d7110aab44108d5e9c310e6bdestradaa GeofenceHardware.MONITORING_TYPE_FUSED_HARDWARE }; 1940682809ad08db284d7110aab44108d5e9c310e6bdestradaa } else { 1950682809ad08db284d7110aab44108d5e9c310e6bdestradaa return new int[] { GeofenceHardware.MONITORING_TYPE_GPS_HARDWARE }; 196da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh } 1970682809ad08db284d7110aab44108d5e9c310e6bdestradaa } else if (fusedSupported) { 1980682809ad08db284d7110aab44108d5e9c310e6bdestradaa return new int[] { GeofenceHardware.MONITORING_TYPE_FUSED_HARDWARE }; 1990682809ad08db284d7110aab44108d5e9c310e6bdestradaa } else { 200da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh return new int[0]; 201da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh } 202da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh } 203da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh 204da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh public int getStatusOfMonitoringType(int monitoringType) { 205da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh synchronized (mSupportedMonitorTypes) { 206da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh if (monitoringType >= mSupportedMonitorTypes.length || monitoringType < 0) { 207da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh throw new IllegalArgumentException("Unknown monitoring type"); 208da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh } 209da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh return mSupportedMonitorTypes[monitoringType]; 2108ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 2118ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 2128ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 213da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh public boolean addCircularFence(int geofenceId, int monitoringType, double latitude, 214da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh double longitude, double radius, int lastTransition,int monitorTransitions, 215da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh int notificationResponsivenes, int unknownTimer, IGeofenceHardwareCallback callback) { 2168ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh // This API is not thread safe. Operations on the same geofence need to be serialized 2178ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh // by upper layers 2188ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh if (DEBUG) { 219f8f085c51b5f8b180ad964d0385b34f8fa97cd32Zhentao Sun Log.d(TAG, "addCircularFence: GeofenceId: " + geofenceId + " Latitude: " + latitude + 220f8f085c51b5f8b180ad964d0385b34f8fa97cd32Zhentao Sun " Longitude: " + longitude + " Radius: " + radius + " LastTransition: " 221f8f085c51b5f8b180ad964d0385b34f8fa97cd32Zhentao Sun + lastTransition + " MonitorTransition: " + monitorTransitions + 222f8f085c51b5f8b180ad964d0385b34f8fa97cd32Zhentao Sun " NotificationResponsiveness: " + notificationResponsivenes + 223f8f085c51b5f8b180ad964d0385b34f8fa97cd32Zhentao Sun " UnKnown Timer: " + unknownTimer + " MonitoringType: " + monitoringType); 2248ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 2258ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 2268ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh boolean result; 227f8f085c51b5f8b180ad964d0385b34f8fa97cd32Zhentao Sun 228f8f085c51b5f8b180ad964d0385b34f8fa97cd32Zhentao Sun // The callback must be added before addCircularHardwareGeofence is called otherwise the 229f8f085c51b5f8b180ad964d0385b34f8fa97cd32Zhentao Sun // callback might not be called after the geofence is added in the geofence hardware. 230f8f085c51b5f8b180ad964d0385b34f8fa97cd32Zhentao Sun // This also means that the callback must be removed if the addCircularHardwareGeofence 231f8f085c51b5f8b180ad964d0385b34f8fa97cd32Zhentao Sun // operations is not called or fails. 232f8f085c51b5f8b180ad964d0385b34f8fa97cd32Zhentao Sun synchronized (mGeofences) { 233f8f085c51b5f8b180ad964d0385b34f8fa97cd32Zhentao Sun mGeofences.put(geofenceId, callback); 234f8f085c51b5f8b180ad964d0385b34f8fa97cd32Zhentao Sun } 2358ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 2368ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh switch (monitoringType) { 2378ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh case GeofenceHardware.MONITORING_TYPE_GPS_HARDWARE: 2388ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh if (mGpsService == null) return false; 2398ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh try { 2408ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh result = mGpsService.addCircularHardwareGeofence(geofenceId, latitude, 2418ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh longitude, radius, lastTransition, monitorTransitions, 2428ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh notificationResponsivenes, unknownTimer); 2438ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } catch (RemoteException e) { 2448ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh Log.e(TAG, "AddGeofence: Remote Exception calling LocationManagerService"); 2458ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh result = false; 2468ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 2478ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh break; 2480682809ad08db284d7110aab44108d5e9c310e6bdestradaa case GeofenceHardware.MONITORING_TYPE_FUSED_HARDWARE: 2490682809ad08db284d7110aab44108d5e9c310e6bdestradaa if(mFusedService == null) { 2500682809ad08db284d7110aab44108d5e9c310e6bdestradaa return false; 2510682809ad08db284d7110aab44108d5e9c310e6bdestradaa } 2520682809ad08db284d7110aab44108d5e9c310e6bdestradaa GeofenceHardwareRequest request = GeofenceHardwareRequest.createCircularGeofence( 2530682809ad08db284d7110aab44108d5e9c310e6bdestradaa latitude, 2540682809ad08db284d7110aab44108d5e9c310e6bdestradaa longitude, 2550682809ad08db284d7110aab44108d5e9c310e6bdestradaa radius); 2560682809ad08db284d7110aab44108d5e9c310e6bdestradaa request.setUnknownTimer(unknownTimer); 2570682809ad08db284d7110aab44108d5e9c310e6bdestradaa request.setNotificationResponsiveness(notificationResponsivenes); 2580682809ad08db284d7110aab44108d5e9c310e6bdestradaa request.setMonitorTransitions(monitorTransitions); 2590682809ad08db284d7110aab44108d5e9c310e6bdestradaa request.setLastTransition(lastTransition); 2600682809ad08db284d7110aab44108d5e9c310e6bdestradaa 2610682809ad08db284d7110aab44108d5e9c310e6bdestradaa GeofenceHardwareRequestParcelable parcelableRequest = 2620682809ad08db284d7110aab44108d5e9c310e6bdestradaa new GeofenceHardwareRequestParcelable(geofenceId, request); 2630682809ad08db284d7110aab44108d5e9c310e6bdestradaa try { 2640682809ad08db284d7110aab44108d5e9c310e6bdestradaa mFusedService.addGeofences( 2650682809ad08db284d7110aab44108d5e9c310e6bdestradaa new GeofenceHardwareRequestParcelable[] { parcelableRequest }); 2660682809ad08db284d7110aab44108d5e9c310e6bdestradaa result = true; 2670682809ad08db284d7110aab44108d5e9c310e6bdestradaa } catch(RemoteException e) { 2680682809ad08db284d7110aab44108d5e9c310e6bdestradaa Log.e(TAG, "AddGeofence: RemoteException calling LocationManagerService"); 2690682809ad08db284d7110aab44108d5e9c310e6bdestradaa result = false; 2700682809ad08db284d7110aab44108d5e9c310e6bdestradaa } 2710682809ad08db284d7110aab44108d5e9c310e6bdestradaa break; 2728ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh default: 2738ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh result = false; 2748ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 275da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh if (result) { 276f8f085c51b5f8b180ad964d0385b34f8fa97cd32Zhentao Sun Message m = mReaperHandler.obtainMessage(REAPER_GEOFENCE_ADDED, callback); 277da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh m.arg1 = monitoringType; 278da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh mReaperHandler.sendMessage(m); 279da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh } else { 280f8f085c51b5f8b180ad964d0385b34f8fa97cd32Zhentao Sun synchronized (mGeofences) { 281f8f085c51b5f8b180ad964d0385b34f8fa97cd32Zhentao Sun mGeofences.remove(geofenceId); 282f8f085c51b5f8b180ad964d0385b34f8fa97cd32Zhentao Sun } 2838ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 2848ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 2858ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh if (DEBUG) Log.d(TAG, "addCircularFence: Result is: " + result); 2868ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh return result; 2878ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 2888ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 2898ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh public boolean removeGeofence(int geofenceId, int monitoringType) { 2908ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh // This API is not thread safe. Operations on the same geofence need to be serialized 2918ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh // by upper layers 2928ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh if (DEBUG) Log.d(TAG, "Remove Geofence: GeofenceId: " + geofenceId); 2938ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh boolean result = false; 294f8f085c51b5f8b180ad964d0385b34f8fa97cd32Zhentao Sun 295f8f085c51b5f8b180ad964d0385b34f8fa97cd32Zhentao Sun synchronized (mGeofences) { 296f8f085c51b5f8b180ad964d0385b34f8fa97cd32Zhentao Sun if (mGeofences.get(geofenceId) == null) { 297f8f085c51b5f8b180ad964d0385b34f8fa97cd32Zhentao Sun throw new IllegalArgumentException("Geofence " + geofenceId + " not registered."); 298f8f085c51b5f8b180ad964d0385b34f8fa97cd32Zhentao Sun } 299f8f085c51b5f8b180ad964d0385b34f8fa97cd32Zhentao Sun } 3008ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh switch (monitoringType) { 3018ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh case GeofenceHardware.MONITORING_TYPE_GPS_HARDWARE: 3028ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh if (mGpsService == null) return false; 3038ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh try { 3048ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh result = mGpsService.removeHardwareGeofence(geofenceId); 3058ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } catch (RemoteException e) { 3068ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh Log.e(TAG, "RemoveGeofence: Remote Exception calling LocationManagerService"); 3078ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh result = false; 3088ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 3098ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh break; 3100682809ad08db284d7110aab44108d5e9c310e6bdestradaa case GeofenceHardware.MONITORING_TYPE_FUSED_HARDWARE: 3110682809ad08db284d7110aab44108d5e9c310e6bdestradaa if(mFusedService == null) { 3120682809ad08db284d7110aab44108d5e9c310e6bdestradaa return false; 3130682809ad08db284d7110aab44108d5e9c310e6bdestradaa } 3140682809ad08db284d7110aab44108d5e9c310e6bdestradaa try { 3150682809ad08db284d7110aab44108d5e9c310e6bdestradaa mFusedService.removeGeofences(new int[] { geofenceId }); 3160682809ad08db284d7110aab44108d5e9c310e6bdestradaa result = true; 3170682809ad08db284d7110aab44108d5e9c310e6bdestradaa } catch(RemoteException e) { 3180682809ad08db284d7110aab44108d5e9c310e6bdestradaa Log.e(TAG, "RemoveGeofence: RemoteException calling LocationManagerService"); 3190682809ad08db284d7110aab44108d5e9c310e6bdestradaa result = false; 3200682809ad08db284d7110aab44108d5e9c310e6bdestradaa } 3210682809ad08db284d7110aab44108d5e9c310e6bdestradaa break; 3228ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh default: 3238ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh result = false; 3248ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 3258ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh if (DEBUG) Log.d(TAG, "removeGeofence: Result is: " + result); 3268ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh return result; 3278ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 3288ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 3298ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh public boolean pauseGeofence(int geofenceId, int monitoringType) { 3308ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh // This API is not thread safe. Operations on the same geofence need to be serialized 3318ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh // by upper layers 3328ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh if (DEBUG) Log.d(TAG, "Pause Geofence: GeofenceId: " + geofenceId); 3338ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh boolean result; 334f8f085c51b5f8b180ad964d0385b34f8fa97cd32Zhentao Sun synchronized (mGeofences) { 335f8f085c51b5f8b180ad964d0385b34f8fa97cd32Zhentao Sun if (mGeofences.get(geofenceId) == null) { 336f8f085c51b5f8b180ad964d0385b34f8fa97cd32Zhentao Sun throw new IllegalArgumentException("Geofence " + geofenceId + " not registered."); 337f8f085c51b5f8b180ad964d0385b34f8fa97cd32Zhentao Sun } 338f8f085c51b5f8b180ad964d0385b34f8fa97cd32Zhentao Sun } 3398ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh switch (monitoringType) { 3408ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh case GeofenceHardware.MONITORING_TYPE_GPS_HARDWARE: 3418ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh if (mGpsService == null) return false; 3428ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh try { 3438ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh result = mGpsService.pauseHardwareGeofence(geofenceId); 3448ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } catch (RemoteException e) { 3458ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh Log.e(TAG, "PauseGeofence: Remote Exception calling LocationManagerService"); 3468ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh result = false; 3478ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 3488ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh break; 3490682809ad08db284d7110aab44108d5e9c310e6bdestradaa case GeofenceHardware.MONITORING_TYPE_FUSED_HARDWARE: 3500682809ad08db284d7110aab44108d5e9c310e6bdestradaa if(mFusedService == null) { 3510682809ad08db284d7110aab44108d5e9c310e6bdestradaa return false; 3520682809ad08db284d7110aab44108d5e9c310e6bdestradaa } 3530682809ad08db284d7110aab44108d5e9c310e6bdestradaa try { 3540682809ad08db284d7110aab44108d5e9c310e6bdestradaa mFusedService.pauseMonitoringGeofence(geofenceId); 3550682809ad08db284d7110aab44108d5e9c310e6bdestradaa result = true; 3560682809ad08db284d7110aab44108d5e9c310e6bdestradaa } catch(RemoteException e) { 3570682809ad08db284d7110aab44108d5e9c310e6bdestradaa Log.e(TAG, "PauseGeofence: RemoteException calling LocationManagerService"); 3580682809ad08db284d7110aab44108d5e9c310e6bdestradaa result = false; 3590682809ad08db284d7110aab44108d5e9c310e6bdestradaa } 3600682809ad08db284d7110aab44108d5e9c310e6bdestradaa break; 3618ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh default: 3628ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh result = false; 3638ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 3648ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh if (DEBUG) Log.d(TAG, "pauseGeofence: Result is: " + result); 3658ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh return result; 3668ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 3678ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 3688ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 369da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh public boolean resumeGeofence(int geofenceId, int monitoringType, int monitorTransition) { 3708ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh // This API is not thread safe. Operations on the same geofence need to be serialized 3718ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh // by upper layers 3728ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh if (DEBUG) Log.d(TAG, "Resume Geofence: GeofenceId: " + geofenceId); 3738ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh boolean result; 374f8f085c51b5f8b180ad964d0385b34f8fa97cd32Zhentao Sun synchronized (mGeofences) { 375f8f085c51b5f8b180ad964d0385b34f8fa97cd32Zhentao Sun if (mGeofences.get(geofenceId) == null) { 376f8f085c51b5f8b180ad964d0385b34f8fa97cd32Zhentao Sun throw new IllegalArgumentException("Geofence " + geofenceId + " not registered."); 377f8f085c51b5f8b180ad964d0385b34f8fa97cd32Zhentao Sun } 378f8f085c51b5f8b180ad964d0385b34f8fa97cd32Zhentao Sun } 3798ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh switch (monitoringType) { 3808ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh case GeofenceHardware.MONITORING_TYPE_GPS_HARDWARE: 3818ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh if (mGpsService == null) return false; 3828ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh try { 3838ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh result = mGpsService.resumeHardwareGeofence(geofenceId, monitorTransition); 3848ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } catch (RemoteException e) { 3858ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh Log.e(TAG, "ResumeGeofence: Remote Exception calling LocationManagerService"); 3868ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh result = false; 3878ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 3888ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh break; 3890682809ad08db284d7110aab44108d5e9c310e6bdestradaa case GeofenceHardware.MONITORING_TYPE_FUSED_HARDWARE: 3900682809ad08db284d7110aab44108d5e9c310e6bdestradaa if(mFusedService == null) { 3910682809ad08db284d7110aab44108d5e9c310e6bdestradaa return false; 3920682809ad08db284d7110aab44108d5e9c310e6bdestradaa } 3930682809ad08db284d7110aab44108d5e9c310e6bdestradaa try { 3940682809ad08db284d7110aab44108d5e9c310e6bdestradaa mFusedService.resumeMonitoringGeofence(geofenceId, monitorTransition); 3950682809ad08db284d7110aab44108d5e9c310e6bdestradaa result = true; 3960682809ad08db284d7110aab44108d5e9c310e6bdestradaa } catch(RemoteException e) { 3970682809ad08db284d7110aab44108d5e9c310e6bdestradaa Log.e(TAG, "ResumeGeofence: RemoteException calling LocationManagerService"); 3980682809ad08db284d7110aab44108d5e9c310e6bdestradaa result = false; 3990682809ad08db284d7110aab44108d5e9c310e6bdestradaa } 4000682809ad08db284d7110aab44108d5e9c310e6bdestradaa break; 4018ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh default: 4028ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh result = false; 4038ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 4048ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh if (DEBUG) Log.d(TAG, "resumeGeofence: Result is: " + result); 4058ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh return result; 4068ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 4078ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 4088ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh public boolean registerForMonitorStateChangeCallback(int monitoringType, 409da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh IGeofenceHardwareMonitorCallback callback) { 410da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh Message reaperMessage = 411da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh mReaperHandler.obtainMessage(REAPER_MONITOR_CALLBACK_ADDED, callback); 412da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh reaperMessage.arg1 = monitoringType; 413da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh mReaperHandler.sendMessage(reaperMessage); 414da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh 4158ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh Message m = mCallbacksHandler.obtainMessage(CALLBACK_ADD, callback); 4168ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh m.arg1 = monitoringType; 4178ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh mCallbacksHandler.sendMessage(m); 4188ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh return true; 4198ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 4208ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 4218ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh public boolean unregisterForMonitorStateChangeCallback(int monitoringType, 422da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh IGeofenceHardwareMonitorCallback callback) { 4238ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh Message m = mCallbacksHandler.obtainMessage(CALLBACK_REMOVE, callback); 4248ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh m.arg1 = monitoringType; 4258ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh mCallbacksHandler.sendMessage(m); 4268ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh return true; 4278ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 4288ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 4290682809ad08db284d7110aab44108d5e9c310e6bdestradaa /** 4300682809ad08db284d7110aab44108d5e9c310e6bdestradaa * Used to report geofence transitions 4310682809ad08db284d7110aab44108d5e9c310e6bdestradaa */ 4320682809ad08db284d7110aab44108d5e9c310e6bdestradaa public void reportGeofenceTransition( 4330682809ad08db284d7110aab44108d5e9c310e6bdestradaa int geofenceId, 4340682809ad08db284d7110aab44108d5e9c310e6bdestradaa Location location, 4350682809ad08db284d7110aab44108d5e9c310e6bdestradaa int transition, 4360682809ad08db284d7110aab44108d5e9c310e6bdestradaa long transitionTimestamp, 4370682809ad08db284d7110aab44108d5e9c310e6bdestradaa int monitoringType, 4380682809ad08db284d7110aab44108d5e9c310e6bdestradaa int sourcesUsed) { 4390682809ad08db284d7110aab44108d5e9c310e6bdestradaa if(location == null) { 4400682809ad08db284d7110aab44108d5e9c310e6bdestradaa Log.e(TAG, String.format("Invalid Geofence Transition: location=%p", location)); 4410682809ad08db284d7110aab44108d5e9c310e6bdestradaa return; 4420682809ad08db284d7110aab44108d5e9c310e6bdestradaa } 4430682809ad08db284d7110aab44108d5e9c310e6bdestradaa if(DEBUG) { 4440682809ad08db284d7110aab44108d5e9c310e6bdestradaa Log.d( 4450682809ad08db284d7110aab44108d5e9c310e6bdestradaa TAG, 4460682809ad08db284d7110aab44108d5e9c310e6bdestradaa "GeofenceTransition| " + location + ", transition:" + transition + 4470682809ad08db284d7110aab44108d5e9c310e6bdestradaa ", transitionTimestamp:" + transitionTimestamp + ", monitoringType:" + 4480682809ad08db284d7110aab44108d5e9c310e6bdestradaa monitoringType + ", sourcesUsed:" + sourcesUsed); 4490682809ad08db284d7110aab44108d5e9c310e6bdestradaa } 4500682809ad08db284d7110aab44108d5e9c310e6bdestradaa 4510682809ad08db284d7110aab44108d5e9c310e6bdestradaa GeofenceTransition geofenceTransition = new GeofenceTransition( 4520682809ad08db284d7110aab44108d5e9c310e6bdestradaa geofenceId, 4530682809ad08db284d7110aab44108d5e9c310e6bdestradaa transition, 4540682809ad08db284d7110aab44108d5e9c310e6bdestradaa transitionTimestamp, 4550682809ad08db284d7110aab44108d5e9c310e6bdestradaa location, 4560682809ad08db284d7110aab44108d5e9c310e6bdestradaa monitoringType, 4570682809ad08db284d7110aab44108d5e9c310e6bdestradaa sourcesUsed); 4580682809ad08db284d7110aab44108d5e9c310e6bdestradaa acquireWakeLock(); 4590682809ad08db284d7110aab44108d5e9c310e6bdestradaa 4600682809ad08db284d7110aab44108d5e9c310e6bdestradaa Message message = mGeofenceHandler.obtainMessage( 4610682809ad08db284d7110aab44108d5e9c310e6bdestradaa GEOFENCE_TRANSITION_CALLBACK, 4620682809ad08db284d7110aab44108d5e9c310e6bdestradaa geofenceTransition); 4630682809ad08db284d7110aab44108d5e9c310e6bdestradaa message.sendToTarget(); 4648ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 4658ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 4668ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh /** 4670682809ad08db284d7110aab44108d5e9c310e6bdestradaa * Used to report Monitor status changes. 4688ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh */ 4690682809ad08db284d7110aab44108d5e9c310e6bdestradaa public void reportGeofenceMonitorStatus( 4700682809ad08db284d7110aab44108d5e9c310e6bdestradaa int monitoringType, 4710682809ad08db284d7110aab44108d5e9c310e6bdestradaa int monitoringStatus, 4720682809ad08db284d7110aab44108d5e9c310e6bdestradaa Location location, 4730682809ad08db284d7110aab44108d5e9c310e6bdestradaa int source) { 4740682809ad08db284d7110aab44108d5e9c310e6bdestradaa // TODO: use the source if needed in the future 4750682809ad08db284d7110aab44108d5e9c310e6bdestradaa setMonitorAvailability(monitoringType, monitoringStatus); 4768ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh acquireWakeLock(); 4770682809ad08db284d7110aab44108d5e9c310e6bdestradaa Message message = mCallbacksHandler.obtainMessage(GEOFENCE_STATUS, location); 4780682809ad08db284d7110aab44108d5e9c310e6bdestradaa message.arg1 = monitoringStatus; 4790682809ad08db284d7110aab44108d5e9c310e6bdestradaa message.arg2 = monitoringType; 4800682809ad08db284d7110aab44108d5e9c310e6bdestradaa message.sendToTarget(); 4818ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 4828ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 4838ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh /** 4840682809ad08db284d7110aab44108d5e9c310e6bdestradaa * Internal generic status report function for Geofence operations. 4850682809ad08db284d7110aab44108d5e9c310e6bdestradaa * 4860682809ad08db284d7110aab44108d5e9c310e6bdestradaa * @param operation The operation to be reported as defined internally. 4870682809ad08db284d7110aab44108d5e9c310e6bdestradaa * @param geofenceId The id of the geofence the operation is related to. 4880682809ad08db284d7110aab44108d5e9c310e6bdestradaa * @param operationStatus The status of the operation as defined in GeofenceHardware class. This 4890682809ad08db284d7110aab44108d5e9c310e6bdestradaa * status is independent of the statuses reported by different HALs. 4908ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh */ 4910682809ad08db284d7110aab44108d5e9c310e6bdestradaa private void reportGeofenceOperationStatus(int operation, int geofenceId, int operationStatus) { 4928ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh acquireWakeLock(); 4930682809ad08db284d7110aab44108d5e9c310e6bdestradaa Message message = mGeofenceHandler.obtainMessage(operation); 4940682809ad08db284d7110aab44108d5e9c310e6bdestradaa message.arg1 = geofenceId; 4950682809ad08db284d7110aab44108d5e9c310e6bdestradaa message.arg2 = operationStatus; 4960682809ad08db284d7110aab44108d5e9c310e6bdestradaa message.sendToTarget(); 4978ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 4988ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 4998ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh /** 5000682809ad08db284d7110aab44108d5e9c310e6bdestradaa * Used to report the status of a Geofence Add operation. 5018ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh */ 5020682809ad08db284d7110aab44108d5e9c310e6bdestradaa public void reportGeofenceAddStatus(int geofenceId, int status) { 5030682809ad08db284d7110aab44108d5e9c310e6bdestradaa if(DEBUG) Log.d(TAG, "AddCallback| id:" + geofenceId + ", status:" + status); 5040682809ad08db284d7110aab44108d5e9c310e6bdestradaa reportGeofenceOperationStatus(ADD_GEOFENCE_CALLBACK, geofenceId, status); 5058ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 5068ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 5078ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh /** 5080682809ad08db284d7110aab44108d5e9c310e6bdestradaa * Used to report the status of a Geofence Remove operation. 5098ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh */ 5100682809ad08db284d7110aab44108d5e9c310e6bdestradaa public void reportGeofenceRemoveStatus(int geofenceId, int status) { 5110682809ad08db284d7110aab44108d5e9c310e6bdestradaa if(DEBUG) Log.d(TAG, "RemoveCallback| id:" + geofenceId + ", status:" + status); 5120682809ad08db284d7110aab44108d5e9c310e6bdestradaa reportGeofenceOperationStatus(REMOVE_GEOFENCE_CALLBACK, geofenceId, status); 5138ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 5148ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 5158ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh /** 5160682809ad08db284d7110aab44108d5e9c310e6bdestradaa * Used to report the status of a Geofence Pause operation. 5178ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh */ 5180682809ad08db284d7110aab44108d5e9c310e6bdestradaa public void reportGeofencePauseStatus(int geofenceId, int status) { 5190682809ad08db284d7110aab44108d5e9c310e6bdestradaa if(DEBUG) Log.d(TAG, "PauseCallbac| id:" + geofenceId + ", status" + status); 5200682809ad08db284d7110aab44108d5e9c310e6bdestradaa reportGeofenceOperationStatus(PAUSE_GEOFENCE_CALLBACK, geofenceId, status); 5218ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 5228ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 5238ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh /** 5240682809ad08db284d7110aab44108d5e9c310e6bdestradaa * Used to report the status of a Geofence Resume operation. 5258ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh */ 5260682809ad08db284d7110aab44108d5e9c310e6bdestradaa public void reportGeofenceResumeStatus(int geofenceId, int status) { 5270682809ad08db284d7110aab44108d5e9c310e6bdestradaa if(DEBUG) Log.d(TAG, "ResumeCallback| id:" + geofenceId + ", status:" + status); 5280682809ad08db284d7110aab44108d5e9c310e6bdestradaa reportGeofenceOperationStatus(RESUME_GEOFENCE_CALLBACK, geofenceId, status); 5298ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 5308ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 5318ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh // All operations on mGeofences 5328ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh private Handler mGeofenceHandler = new Handler() { 5338ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh @Override 5348ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh public void handleMessage(Message msg) { 5358ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh int geofenceId; 5368ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh int status; 5378ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh IGeofenceHardwareCallback callback; 5388ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh switch (msg.what) { 5398ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh case ADD_GEOFENCE_CALLBACK: 5408ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh geofenceId = msg.arg1; 541f8f085c51b5f8b180ad964d0385b34f8fa97cd32Zhentao Sun synchronized (mGeofences) { 542f8f085c51b5f8b180ad964d0385b34f8fa97cd32Zhentao Sun callback = mGeofences.get(geofenceId); 543f8f085c51b5f8b180ad964d0385b34f8fa97cd32Zhentao Sun } 5448ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 545cfa496f7cdc52711e9ad7521224f67d1aaee002cZhentao Sun if (callback != null) { 546cfa496f7cdc52711e9ad7521224f67d1aaee002cZhentao Sun try { 547cfa496f7cdc52711e9ad7521224f67d1aaee002cZhentao Sun callback.onGeofenceAdd(geofenceId, msg.arg2); 548cfa496f7cdc52711e9ad7521224f67d1aaee002cZhentao Sun } catch (RemoteException e) {Log.i(TAG, "Remote Exception:" + e);} 549cfa496f7cdc52711e9ad7521224f67d1aaee002cZhentao Sun } 5508ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh releaseWakeLock(); 5518ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh break; 5528ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh case REMOVE_GEOFENCE_CALLBACK: 5538ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh geofenceId = msg.arg1; 554f8f085c51b5f8b180ad964d0385b34f8fa97cd32Zhentao Sun synchronized (mGeofences) { 555f8f085c51b5f8b180ad964d0385b34f8fa97cd32Zhentao Sun callback = mGeofences.get(geofenceId); 556f8f085c51b5f8b180ad964d0385b34f8fa97cd32Zhentao Sun } 5578ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 558cfa496f7cdc52711e9ad7521224f67d1aaee002cZhentao Sun if (callback != null) { 559cfa496f7cdc52711e9ad7521224f67d1aaee002cZhentao Sun try { 560cfa496f7cdc52711e9ad7521224f67d1aaee002cZhentao Sun callback.onGeofenceRemove(geofenceId, msg.arg2); 561cfa496f7cdc52711e9ad7521224f67d1aaee002cZhentao Sun } catch (RemoteException e) {} 562cfa496f7cdc52711e9ad7521224f67d1aaee002cZhentao Sun synchronized (mGeofences) { 563cfa496f7cdc52711e9ad7521224f67d1aaee002cZhentao Sun mGeofences.remove(geofenceId); 564cfa496f7cdc52711e9ad7521224f67d1aaee002cZhentao Sun } 565f8f085c51b5f8b180ad964d0385b34f8fa97cd32Zhentao Sun } 5668ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh releaseWakeLock(); 5678ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh break; 5688ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 5698ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh case PAUSE_GEOFENCE_CALLBACK: 5708ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh geofenceId = msg.arg1; 571f8f085c51b5f8b180ad964d0385b34f8fa97cd32Zhentao Sun synchronized (mGeofences) { 572f8f085c51b5f8b180ad964d0385b34f8fa97cd32Zhentao Sun callback = mGeofences.get(geofenceId); 573f8f085c51b5f8b180ad964d0385b34f8fa97cd32Zhentao Sun } 5748ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 575cfa496f7cdc52711e9ad7521224f67d1aaee002cZhentao Sun if (callback != null) { 576cfa496f7cdc52711e9ad7521224f67d1aaee002cZhentao Sun try { 577cfa496f7cdc52711e9ad7521224f67d1aaee002cZhentao Sun callback.onGeofencePause(geofenceId, msg.arg2); 578cfa496f7cdc52711e9ad7521224f67d1aaee002cZhentao Sun } catch (RemoteException e) {} 579cfa496f7cdc52711e9ad7521224f67d1aaee002cZhentao Sun } 5808ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh releaseWakeLock(); 5818ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh break; 5828ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 5838ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh case RESUME_GEOFENCE_CALLBACK: 5848ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh geofenceId = msg.arg1; 585f8f085c51b5f8b180ad964d0385b34f8fa97cd32Zhentao Sun synchronized (mGeofences) { 586f8f085c51b5f8b180ad964d0385b34f8fa97cd32Zhentao Sun callback = mGeofences.get(geofenceId); 587f8f085c51b5f8b180ad964d0385b34f8fa97cd32Zhentao Sun } 5888ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 589cfa496f7cdc52711e9ad7521224f67d1aaee002cZhentao Sun if (callback != null) { 590cfa496f7cdc52711e9ad7521224f67d1aaee002cZhentao Sun try { 591cfa496f7cdc52711e9ad7521224f67d1aaee002cZhentao Sun callback.onGeofenceResume(geofenceId, msg.arg2); 592cfa496f7cdc52711e9ad7521224f67d1aaee002cZhentao Sun } catch (RemoteException e) {} 593cfa496f7cdc52711e9ad7521224f67d1aaee002cZhentao Sun } 5948ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh releaseWakeLock(); 5958ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh break; 5968ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 5978ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh case GEOFENCE_TRANSITION_CALLBACK: 5988ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh GeofenceTransition geofenceTransition = (GeofenceTransition)(msg.obj); 599f8f085c51b5f8b180ad964d0385b34f8fa97cd32Zhentao Sun synchronized (mGeofences) { 600f8f085c51b5f8b180ad964d0385b34f8fa97cd32Zhentao Sun callback = mGeofences.get(geofenceTransition.mGeofenceId); 6018ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 6027f02eb2c84c0a39e6357aca10a4fda1dd090a8a6destradaa // need to keep access to mGeofences synchronized at all times 6037f02eb2c84c0a39e6357aca10a4fda1dd090a8a6destradaa if (DEBUG) Log.d(TAG, "GeofenceTransistionCallback: GPS : GeofenceId: " + 6047f02eb2c84c0a39e6357aca10a4fda1dd090a8a6destradaa geofenceTransition.mGeofenceId + 6057f02eb2c84c0a39e6357aca10a4fda1dd090a8a6destradaa " Transition: " + geofenceTransition.mTransition + 6067f02eb2c84c0a39e6357aca10a4fda1dd090a8a6destradaa " Location: " + geofenceTransition.mLocation + ":" + mGeofences); 6077f02eb2c84c0a39e6357aca10a4fda1dd090a8a6destradaa } 6088ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 609cfa496f7cdc52711e9ad7521224f67d1aaee002cZhentao Sun if (callback != null) { 610cfa496f7cdc52711e9ad7521224f67d1aaee002cZhentao Sun try { 611cfa496f7cdc52711e9ad7521224f67d1aaee002cZhentao Sun callback.onGeofenceTransition( 612cfa496f7cdc52711e9ad7521224f67d1aaee002cZhentao Sun geofenceTransition.mGeofenceId, geofenceTransition.mTransition, 613cfa496f7cdc52711e9ad7521224f67d1aaee002cZhentao Sun geofenceTransition.mLocation, geofenceTransition.mTimestamp, 6140682809ad08db284d7110aab44108d5e9c310e6bdestradaa geofenceTransition.mMonitoringType); 615cfa496f7cdc52711e9ad7521224f67d1aaee002cZhentao Sun } catch (RemoteException e) {} 616cfa496f7cdc52711e9ad7521224f67d1aaee002cZhentao Sun } 6178ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh releaseWakeLock(); 6188ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh break; 619da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh case GEOFENCE_CALLBACK_BINDER_DIED: 620da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh // Find all geofences associated with this callback and remove them. 621da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh callback = (IGeofenceHardwareCallback) (msg.obj); 622da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh if (DEBUG) Log.d(TAG, "Geofence callback reaped:" + callback); 623da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh int monitoringType = msg.arg1; 624f8f085c51b5f8b180ad964d0385b34f8fa97cd32Zhentao Sun synchronized (mGeofences) { 625f8f085c51b5f8b180ad964d0385b34f8fa97cd32Zhentao Sun for (int i = 0; i < mGeofences.size(); i++) { 626f8f085c51b5f8b180ad964d0385b34f8fa97cd32Zhentao Sun if (mGeofences.valueAt(i).equals(callback)) { 627f8f085c51b5f8b180ad964d0385b34f8fa97cd32Zhentao Sun geofenceId = mGeofences.keyAt(i); 628f8f085c51b5f8b180ad964d0385b34f8fa97cd32Zhentao Sun removeGeofence(mGeofences.keyAt(i), monitoringType); 629f8f085c51b5f8b180ad964d0385b34f8fa97cd32Zhentao Sun mGeofences.remove(geofenceId); 630f8f085c51b5f8b180ad964d0385b34f8fa97cd32Zhentao Sun } 631f8f085c51b5f8b180ad964d0385b34f8fa97cd32Zhentao Sun } 632da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh } 6338ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 6348ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 6358ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh }; 6368ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 6378ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh // All operations on mCallbacks 6388ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh private Handler mCallbacksHandler = new Handler() { 6398ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh @Override 6408ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh public void handleMessage(Message msg) { 6418ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh int monitoringType; 642da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh ArrayList<IGeofenceHardwareMonitorCallback> callbackList; 643da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh IGeofenceHardwareMonitorCallback callback; 6448ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 6458ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh switch (msg.what) { 6460682809ad08db284d7110aab44108d5e9c310e6bdestradaa case GEOFENCE_STATUS: 6478ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh Location location = (Location) msg.obj; 6488ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh int val = msg.arg1; 6490682809ad08db284d7110aab44108d5e9c310e6bdestradaa monitoringType = msg.arg2; 6508ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh boolean available; 6518ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh available = (val == GeofenceHardware.MONITOR_CURRENTLY_AVAILABLE ? 6528ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh true : false); 6530682809ad08db284d7110aab44108d5e9c310e6bdestradaa callbackList = mCallbacks[monitoringType]; 654cfa496f7cdc52711e9ad7521224f67d1aaee002cZhentao Sun if (callbackList != null) { 655cfa496f7cdc52711e9ad7521224f67d1aaee002cZhentao Sun if (DEBUG) Log.d(TAG, "MonitoringSystemChangeCallback: GPS : " + available); 656cfa496f7cdc52711e9ad7521224f67d1aaee002cZhentao Sun 657cfa496f7cdc52711e9ad7521224f67d1aaee002cZhentao Sun for (IGeofenceHardwareMonitorCallback c: callbackList) { 658cfa496f7cdc52711e9ad7521224f67d1aaee002cZhentao Sun try { 6590682809ad08db284d7110aab44108d5e9c310e6bdestradaa c.onMonitoringSystemChange(monitoringType, available, location); 660cfa496f7cdc52711e9ad7521224f67d1aaee002cZhentao Sun } catch (RemoteException e) {} 661cfa496f7cdc52711e9ad7521224f67d1aaee002cZhentao Sun } 6628ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 6638ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh releaseWakeLock(); 6648ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh break; 6658ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh case CALLBACK_ADD: 6668ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh monitoringType = msg.arg1; 667da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh callback = (IGeofenceHardwareMonitorCallback) msg.obj; 6688ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh callbackList = mCallbacks[monitoringType]; 6698ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh if (callbackList == null) { 670da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh callbackList = new ArrayList<IGeofenceHardwareMonitorCallback>(); 6718ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh mCallbacks[monitoringType] = callbackList; 6728ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 6738ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh if (!callbackList.contains(callback)) callbackList.add(callback); 6748ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh break; 6758ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh case CALLBACK_REMOVE: 6768ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh monitoringType = msg.arg1; 677da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh callback = (IGeofenceHardwareMonitorCallback) msg.obj; 6788ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh callbackList = mCallbacks[monitoringType]; 6798ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh if (callbackList != null) { 6808ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh callbackList.remove(callback); 6818ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 6828ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh break; 683da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh case MONITOR_CALLBACK_BINDER_DIED: 684da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh callback = (IGeofenceHardwareMonitorCallback) msg.obj; 685da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh if (DEBUG) Log.d(TAG, "Monitor callback reaped:" + callback); 686da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh callbackList = mCallbacks[msg.arg1]; 687da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh if (callbackList != null && callbackList.contains(callback)) { 688da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh callbackList.remove(callback); 689da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh } 690da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh } 691da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh } 692da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh }; 693da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh 694da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh // All operations on mReaper 695da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh private Handler mReaperHandler = new Handler() { 696da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh @Override 697da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh public void handleMessage(Message msg) { 698da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh Reaper r; 699da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh IGeofenceHardwareCallback callback; 700da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh IGeofenceHardwareMonitorCallback monitorCallback; 701da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh int monitoringType; 702da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh 703da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh switch (msg.what) { 704da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh case REAPER_GEOFENCE_ADDED: 705da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh callback = (IGeofenceHardwareCallback) msg.obj; 706da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh monitoringType = msg.arg1; 707da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh r = new Reaper(callback, monitoringType); 708da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh if (!mReapers.contains(r)) { 709da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh mReapers.add(r); 710da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh IBinder b = callback.asBinder(); 711da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh try { 712da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh b.linkToDeath(r, 0); 713da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh } catch (RemoteException e) {} 714da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh } 715da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh break; 716da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh case REAPER_MONITOR_CALLBACK_ADDED: 717da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh monitorCallback = (IGeofenceHardwareMonitorCallback) msg.obj; 718da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh monitoringType = msg.arg1; 719da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh 720da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh r = new Reaper(monitorCallback, monitoringType); 721da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh if (!mReapers.contains(r)) { 722da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh mReapers.add(r); 723da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh IBinder b = monitorCallback.asBinder(); 724da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh try { 725da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh b.linkToDeath(r, 0); 726da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh } catch (RemoteException e) {} 727da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh } 728da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh break; 729da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh case REAPER_REMOVED: 730da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh r = (Reaper) msg.obj; 731da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh mReapers.remove(r); 7328ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 7338ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 7348ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh }; 7358ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 7368ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh private class GeofenceTransition { 7378ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh private int mGeofenceId, mTransition; 7388ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh private long mTimestamp; 7398ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh private Location mLocation; 7400682809ad08db284d7110aab44108d5e9c310e6bdestradaa private int mMonitoringType; 7410682809ad08db284d7110aab44108d5e9c310e6bdestradaa private int mSourcesUsed; 7420682809ad08db284d7110aab44108d5e9c310e6bdestradaa 7430682809ad08db284d7110aab44108d5e9c310e6bdestradaa GeofenceTransition( 7440682809ad08db284d7110aab44108d5e9c310e6bdestradaa int geofenceId, 7450682809ad08db284d7110aab44108d5e9c310e6bdestradaa int transition, 7460682809ad08db284d7110aab44108d5e9c310e6bdestradaa long timestamp, 7470682809ad08db284d7110aab44108d5e9c310e6bdestradaa Location location, 7480682809ad08db284d7110aab44108d5e9c310e6bdestradaa int monitoringType, 7490682809ad08db284d7110aab44108d5e9c310e6bdestradaa int sourcesUsed) { 7508ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh mGeofenceId = geofenceId; 7518ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh mTransition = transition; 7528ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh mTimestamp = timestamp; 7538ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh mLocation = location; 7540682809ad08db284d7110aab44108d5e9c310e6bdestradaa mMonitoringType = monitoringType; 7550682809ad08db284d7110aab44108d5e9c310e6bdestradaa mSourcesUsed = sourcesUsed; 7568ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 7578ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 7588ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 7598ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh private void setMonitorAvailability(int monitor, int val) { 7608ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh synchronized (mSupportedMonitorTypes) { 7618ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh mSupportedMonitorTypes[monitor] = val; 7628ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 7638ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 7648ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 7658ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 7668ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh int getMonitoringResolutionLevel(int monitoringType) { 7678ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh switch (monitoringType) { 7688ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh case GeofenceHardware.MONITORING_TYPE_GPS_HARDWARE: 7698ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh return RESOLUTION_LEVEL_FINE; 7700682809ad08db284d7110aab44108d5e9c310e6bdestradaa case GeofenceHardware.MONITORING_TYPE_FUSED_HARDWARE: 7710682809ad08db284d7110aab44108d5e9c310e6bdestradaa return RESOLUTION_LEVEL_FINE; 7728ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 7738ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh return RESOLUTION_LEVEL_NONE; 7748ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 7758ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 776da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh class Reaper implements IBinder.DeathRecipient { 777da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh private IGeofenceHardwareMonitorCallback mMonitorCallback; 778da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh private IGeofenceHardwareCallback mCallback; 779da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh private int mMonitoringType; 780da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh 781da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh Reaper(IGeofenceHardwareCallback c, int monitoringType) { 782da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh mCallback = c; 783da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh mMonitoringType = monitoringType; 784da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh } 785da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh 786da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh Reaper(IGeofenceHardwareMonitorCallback c, int monitoringType) { 787da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh mMonitorCallback = c; 788da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh mMonitoringType = monitoringType; 789da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh } 790da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh 791da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh @Override 792da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh public void binderDied() { 793da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh Message m; 794da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh if (mCallback != null) { 795da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh m = mGeofenceHandler.obtainMessage(GEOFENCE_CALLBACK_BINDER_DIED, mCallback); 796da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh m.arg1 = mMonitoringType; 797da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh mGeofenceHandler.sendMessage(m); 798da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh } else if (mMonitorCallback != null) { 799da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh m = mCallbacksHandler.obtainMessage(MONITOR_CALLBACK_BINDER_DIED, mMonitorCallback); 800da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh m.arg1 = mMonitoringType; 801da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh mCallbacksHandler.sendMessage(m); 802da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh } 803da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh Message reaperMessage = mReaperHandler.obtainMessage(REAPER_REMOVED, this); 804da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh mReaperHandler.sendMessage(reaperMessage); 805da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh } 806da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh 807da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh @Override 808da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh public int hashCode() { 809da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh int result = 17; 810da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh result = 31 * result + (mCallback != null ? mCallback.hashCode() : 0); 811da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh result = 31 * result + (mMonitorCallback != null ? mMonitorCallback.hashCode() : 0); 812da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh result = 31 * result + mMonitoringType; 813da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh return result; 814da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh } 815da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh 816da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh @Override 817da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh public boolean equals(Object obj) { 818da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh if (obj == null) return false; 819da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh if (obj == this) return true; 820da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh 821da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh Reaper rhs = (Reaper) obj; 822da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh return rhs.mCallback == mCallback && rhs.mMonitorCallback == mMonitorCallback && 823da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh rhs.mMonitoringType == mMonitoringType; 824da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh } 825da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh } 826da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh 8278ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh int getAllowedResolutionLevel(int pid, int uid) { 8288ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh if (mContext.checkPermission(android.Manifest.permission.ACCESS_FINE_LOCATION, 8298ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh pid, uid) == PackageManager.PERMISSION_GRANTED) { 8308ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh return RESOLUTION_LEVEL_FINE; 8318ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } else if (mContext.checkPermission(android.Manifest.permission.ACCESS_COARSE_LOCATION, 8328ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh pid, uid) == PackageManager.PERMISSION_GRANTED) { 8338ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh return RESOLUTION_LEVEL_COARSE; 8348ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } else { 8358ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh return RESOLUTION_LEVEL_NONE; 8368ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 8378ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 8388ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh} 839