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; 218ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganeshimport android.location.IGpsGeofenceHardware; 228ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganeshimport android.location.Location; 238ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganeshimport android.location.LocationManager; 24da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganeshimport android.os.Binder; 258ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganeshimport android.os.Bundle; 268ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganeshimport android.os.Handler; 27da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganeshimport android.os.IBinder; 288ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganeshimport android.os.Message; 298ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganeshimport android.os.PowerManager; 308ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganeshimport android.os.RemoteException; 318ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganeshimport android.os.ServiceManager; 328ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganeshimport android.os.SystemClock; 338ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganeshimport android.util.Log; 348ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganeshimport android.util.SparseArray; 358ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 368ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganeshimport java.util.ArrayList; 378ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganeshimport java.util.HashMap; 388ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 398ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh/** 408ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh * This class manages the geofences which are handled by hardware. 418ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh * 428ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh * @hide 438ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh */ 448ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganeshpublic final class GeofenceHardwareImpl { 458ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh private static final String TAG = "GeofenceHardwareImpl"; 468ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG); 478ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 488ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh private final Context mContext; 498ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh private static GeofenceHardwareImpl sInstance; 508ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh private PowerManager.WakeLock mWakeLock; 51f8f085c51b5f8b180ad964d0385b34f8fa97cd32Zhentao Sun private final SparseArray<IGeofenceHardwareCallback> mGeofences = 528ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh new SparseArray<IGeofenceHardwareCallback>(); 53f8f085c51b5f8b180ad964d0385b34f8fa97cd32Zhentao Sun private final ArrayList<IGeofenceHardwareMonitorCallback>[] mCallbacks = 548ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh new ArrayList[GeofenceHardware.NUM_MONITORS]; 55f8f085c51b5f8b180ad964d0385b34f8fa97cd32Zhentao Sun private final ArrayList<Reaper> mReapers = new ArrayList<Reaper>(); 568ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 578ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh private IGpsGeofenceHardware mGpsService; 588ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 598ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh private int[] mSupportedMonitorTypes = new int[GeofenceHardware.NUM_MONITORS]; 608ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 618ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh // mGeofenceHandler message types 628ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh private static final int GEOFENCE_TRANSITION_CALLBACK = 1; 638ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh private static final int ADD_GEOFENCE_CALLBACK = 2; 648ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh private static final int REMOVE_GEOFENCE_CALLBACK = 3; 658ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh private static final int PAUSE_GEOFENCE_CALLBACK = 4; 668ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh private static final int RESUME_GEOFENCE_CALLBACK = 5; 67f8f085c51b5f8b180ad964d0385b34f8fa97cd32Zhentao Sun private static final int GEOFENCE_CALLBACK_BINDER_DIED = 6; 688ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 698ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh // mCallbacksHandler message types 708ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh private static final int GPS_GEOFENCE_STATUS = 1; 718ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh private static final int CALLBACK_ADD = 2; 728ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh private static final int CALLBACK_REMOVE = 3; 73da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh private static final int MONITOR_CALLBACK_BINDER_DIED = 4; 74da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh 75da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh // mReaperHandler message types 76da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh private static final int REAPER_GEOFENCE_ADDED = 1; 77da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh private static final int REAPER_MONITOR_CALLBACK_ADDED = 2; 78da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh private static final int REAPER_REMOVED = 3; 798ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 808ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh // The following constants need to match GpsLocationFlags enum in gps.h 818ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh private static final int LOCATION_INVALID = 0; 828ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh private static final int LOCATION_HAS_LAT_LONG = 1; 838ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh private static final int LOCATION_HAS_ALTITUDE = 2; 848ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh private static final int LOCATION_HAS_SPEED = 4; 858ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh private static final int LOCATION_HAS_BEARING = 8; 868ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh private static final int LOCATION_HAS_ACCURACY = 16; 878ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 888ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh // Resolution level constants used for permission checks. 898ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh // These constants must be in increasing order of finer resolution. 908ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh private static final int RESOLUTION_LEVEL_NONE = 1; 918ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh private static final int RESOLUTION_LEVEL_COARSE = 2; 928ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh private static final int RESOLUTION_LEVEL_FINE = 3; 938ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 948ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh // GPS Geofence errors. Should match gps.h constants. 958ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh private static final int GPS_GEOFENCE_OPERATION_SUCCESS = 0; 968ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh private static final int GPS_GEOFENCE_ERROR_TOO_MANY_GEOFENCES = 100; 978ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh private static final int GPS_GEOFENCE_ERROR_ID_EXISTS = -101; 988ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh private static final int GPS_GEOFENCE_ERROR_ID_UNKNOWN = -102; 998ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh private static final int GPS_GEOFENCE_ERROR_INVALID_TRANSITION = -103; 1008ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh private static final int GPS_GEOFENCE_ERROR_GENERIC = -149; 1018ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 1028ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 1038ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 1048ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh public synchronized static GeofenceHardwareImpl getInstance(Context context) { 1058ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh if (sInstance == null) { 1068ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh sInstance = new GeofenceHardwareImpl(context); 1078ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 1088ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh return sInstance; 1098ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 1108ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 1118ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh private GeofenceHardwareImpl(Context context) { 1128ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh mContext = context; 1138ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh // Init everything to unsupported. 1148ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh setMonitorAvailability(GeofenceHardware.MONITORING_TYPE_GPS_HARDWARE, 1158ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh GeofenceHardware.MONITOR_UNSUPPORTED); 1168ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 1178ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 1188ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 1198ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh private void acquireWakeLock() { 1208ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh if (mWakeLock == null) { 1218ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh PowerManager powerManager = 1228ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh (PowerManager) mContext.getSystemService(Context.POWER_SERVICE); 1238ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG); 1248ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 1258ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh mWakeLock.acquire(); 1268ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 1278ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 1288ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh private void releaseWakeLock() { 1298ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh if (mWakeLock.isHeld()) mWakeLock.release(); 1308ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 1318ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 1328ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh private void updateGpsHardwareAvailability() { 1338ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh //Check which monitors are available. 1348ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh boolean gpsSupported; 1358ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh try { 1368ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh gpsSupported = mGpsService.isHardwareGeofenceSupported(); 1378ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } catch (RemoteException e) { 1388ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh Log.e(TAG, "Remote Exception calling LocationManagerService"); 1398ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh gpsSupported = false; 1408ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 1418ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 1428ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh if (gpsSupported) { 1438ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh // Its assumed currently available at startup. 1448ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh // native layer will update later. 1458ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh setMonitorAvailability(GeofenceHardware.MONITORING_TYPE_GPS_HARDWARE, 1468ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh GeofenceHardware.MONITOR_CURRENTLY_AVAILABLE); 1478ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 1488ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 1498ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 1508ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh public void setGpsHardwareGeofence(IGpsGeofenceHardware service) { 1518ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh if (mGpsService == null) { 1528ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh mGpsService = service; 1538ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh updateGpsHardwareAvailability(); 1548ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } else if (service == null) { 1558ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh mGpsService = null; 1568ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh Log.w(TAG, "GPS Geofence Hardware service seems to have crashed"); 1578ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } else { 1588ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh Log.e(TAG, "Error: GpsService being set again."); 1598ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 1608ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 1618ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 162da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh public int[] getMonitoringTypes() { 1638ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh synchronized (mSupportedMonitorTypes) { 164da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh if (mSupportedMonitorTypes[GeofenceHardware.MONITORING_TYPE_GPS_HARDWARE] != 165da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh GeofenceHardware.MONITOR_UNSUPPORTED) { 166da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh return new int[] {GeofenceHardware.MONITORING_TYPE_GPS_HARDWARE}; 167da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh } 168da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh return new int[0]; 169da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh } 170da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh } 171da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh 172da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh public int getStatusOfMonitoringType(int monitoringType) { 173da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh synchronized (mSupportedMonitorTypes) { 174da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh if (monitoringType >= mSupportedMonitorTypes.length || monitoringType < 0) { 175da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh throw new IllegalArgumentException("Unknown monitoring type"); 176da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh } 177da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh return mSupportedMonitorTypes[monitoringType]; 1788ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 1798ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 1808ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 181da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh public boolean addCircularFence(int geofenceId, int monitoringType, double latitude, 182da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh double longitude, double radius, int lastTransition,int monitorTransitions, 183da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh int notificationResponsivenes, int unknownTimer, IGeofenceHardwareCallback callback) { 1848ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh // This API is not thread safe. Operations on the same geofence need to be serialized 1858ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh // by upper layers 1868ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh if (DEBUG) { 187f8f085c51b5f8b180ad964d0385b34f8fa97cd32Zhentao Sun Log.d(TAG, "addCircularFence: GeofenceId: " + geofenceId + " Latitude: " + latitude + 188f8f085c51b5f8b180ad964d0385b34f8fa97cd32Zhentao Sun " Longitude: " + longitude + " Radius: " + radius + " LastTransition: " 189f8f085c51b5f8b180ad964d0385b34f8fa97cd32Zhentao Sun + lastTransition + " MonitorTransition: " + monitorTransitions + 190f8f085c51b5f8b180ad964d0385b34f8fa97cd32Zhentao Sun " NotificationResponsiveness: " + notificationResponsivenes + 191f8f085c51b5f8b180ad964d0385b34f8fa97cd32Zhentao Sun " UnKnown Timer: " + unknownTimer + " MonitoringType: " + monitoringType); 1928ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 1938ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 1948ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh boolean result; 195f8f085c51b5f8b180ad964d0385b34f8fa97cd32Zhentao Sun 196f8f085c51b5f8b180ad964d0385b34f8fa97cd32Zhentao Sun // The callback must be added before addCircularHardwareGeofence is called otherwise the 197f8f085c51b5f8b180ad964d0385b34f8fa97cd32Zhentao Sun // callback might not be called after the geofence is added in the geofence hardware. 198f8f085c51b5f8b180ad964d0385b34f8fa97cd32Zhentao Sun // This also means that the callback must be removed if the addCircularHardwareGeofence 199f8f085c51b5f8b180ad964d0385b34f8fa97cd32Zhentao Sun // operations is not called or fails. 200f8f085c51b5f8b180ad964d0385b34f8fa97cd32Zhentao Sun synchronized (mGeofences) { 201f8f085c51b5f8b180ad964d0385b34f8fa97cd32Zhentao Sun mGeofences.put(geofenceId, callback); 202f8f085c51b5f8b180ad964d0385b34f8fa97cd32Zhentao Sun } 2038ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 2048ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh switch (monitoringType) { 2058ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh case GeofenceHardware.MONITORING_TYPE_GPS_HARDWARE: 2068ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh if (mGpsService == null) return false; 2078ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh try { 2088ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh result = mGpsService.addCircularHardwareGeofence(geofenceId, latitude, 2098ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh longitude, radius, lastTransition, monitorTransitions, 2108ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh notificationResponsivenes, unknownTimer); 2118ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } catch (RemoteException e) { 2128ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh Log.e(TAG, "AddGeofence: Remote Exception calling LocationManagerService"); 2138ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh result = false; 2148ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 2158ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh break; 2168ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh default: 2178ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh result = false; 2188ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 219da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh if (result) { 220f8f085c51b5f8b180ad964d0385b34f8fa97cd32Zhentao Sun Message m = mReaperHandler.obtainMessage(REAPER_GEOFENCE_ADDED, callback); 221da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh m.arg1 = monitoringType; 222da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh mReaperHandler.sendMessage(m); 223da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh } else { 224f8f085c51b5f8b180ad964d0385b34f8fa97cd32Zhentao Sun synchronized (mGeofences) { 225f8f085c51b5f8b180ad964d0385b34f8fa97cd32Zhentao Sun mGeofences.remove(geofenceId); 226f8f085c51b5f8b180ad964d0385b34f8fa97cd32Zhentao Sun } 2278ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 2288ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 2298ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh if (DEBUG) Log.d(TAG, "addCircularFence: Result is: " + result); 2308ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh return result; 2318ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 2328ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 2338ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh public boolean removeGeofence(int geofenceId, int monitoringType) { 2348ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh // This API is not thread safe. Operations on the same geofence need to be serialized 2358ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh // by upper layers 2368ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh if (DEBUG) Log.d(TAG, "Remove Geofence: GeofenceId: " + geofenceId); 2378ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh boolean result = false; 238f8f085c51b5f8b180ad964d0385b34f8fa97cd32Zhentao Sun 239f8f085c51b5f8b180ad964d0385b34f8fa97cd32Zhentao Sun synchronized (mGeofences) { 240f8f085c51b5f8b180ad964d0385b34f8fa97cd32Zhentao Sun if (mGeofences.get(geofenceId) == null) { 241f8f085c51b5f8b180ad964d0385b34f8fa97cd32Zhentao Sun throw new IllegalArgumentException("Geofence " + geofenceId + " not registered."); 242f8f085c51b5f8b180ad964d0385b34f8fa97cd32Zhentao Sun } 243f8f085c51b5f8b180ad964d0385b34f8fa97cd32Zhentao Sun } 2448ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh switch (monitoringType) { 2458ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh case GeofenceHardware.MONITORING_TYPE_GPS_HARDWARE: 2468ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh if (mGpsService == null) return false; 2478ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh try { 2488ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh result = mGpsService.removeHardwareGeofence(geofenceId); 2498ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } catch (RemoteException e) { 2508ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh Log.e(TAG, "RemoveGeofence: Remote Exception calling LocationManagerService"); 2518ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh result = false; 2528ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 2538ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh break; 2548ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh default: 2558ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh result = false; 2568ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 2578ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh if (DEBUG) Log.d(TAG, "removeGeofence: Result is: " + result); 2588ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh return result; 2598ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 2608ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 2618ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh public boolean pauseGeofence(int geofenceId, int monitoringType) { 2628ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh // This API is not thread safe. Operations on the same geofence need to be serialized 2638ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh // by upper layers 2648ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh if (DEBUG) Log.d(TAG, "Pause Geofence: GeofenceId: " + geofenceId); 2658ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh boolean result; 266f8f085c51b5f8b180ad964d0385b34f8fa97cd32Zhentao Sun synchronized (mGeofences) { 267f8f085c51b5f8b180ad964d0385b34f8fa97cd32Zhentao Sun if (mGeofences.get(geofenceId) == null) { 268f8f085c51b5f8b180ad964d0385b34f8fa97cd32Zhentao Sun throw new IllegalArgumentException("Geofence " + geofenceId + " not registered."); 269f8f085c51b5f8b180ad964d0385b34f8fa97cd32Zhentao Sun } 270f8f085c51b5f8b180ad964d0385b34f8fa97cd32Zhentao Sun } 2718ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh switch (monitoringType) { 2728ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh case GeofenceHardware.MONITORING_TYPE_GPS_HARDWARE: 2738ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh if (mGpsService == null) return false; 2748ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh try { 2758ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh result = mGpsService.pauseHardwareGeofence(geofenceId); 2768ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } catch (RemoteException e) { 2778ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh Log.e(TAG, "PauseGeofence: Remote Exception calling LocationManagerService"); 2788ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh result = false; 2798ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 2808ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh break; 2818ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh default: 2828ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh result = false; 2838ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 2848ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh if (DEBUG) Log.d(TAG, "pauseGeofence: Result is: " + result); 2858ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh return result; 2868ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 2878ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 2888ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 289da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh public boolean resumeGeofence(int geofenceId, int monitoringType, int monitorTransition) { 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, "Resume Geofence: GeofenceId: " + geofenceId); 2938ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh boolean result; 294f8f085c51b5f8b180ad964d0385b34f8fa97cd32Zhentao Sun synchronized (mGeofences) { 295f8f085c51b5f8b180ad964d0385b34f8fa97cd32Zhentao Sun if (mGeofences.get(geofenceId) == null) { 296f8f085c51b5f8b180ad964d0385b34f8fa97cd32Zhentao Sun throw new IllegalArgumentException("Geofence " + geofenceId + " not registered."); 297f8f085c51b5f8b180ad964d0385b34f8fa97cd32Zhentao Sun } 298f8f085c51b5f8b180ad964d0385b34f8fa97cd32Zhentao Sun } 2998ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh switch (monitoringType) { 3008ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh case GeofenceHardware.MONITORING_TYPE_GPS_HARDWARE: 3018ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh if (mGpsService == null) return false; 3028ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh try { 3038ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh result = mGpsService.resumeHardwareGeofence(geofenceId, monitorTransition); 3048ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } catch (RemoteException e) { 3058ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh Log.e(TAG, "ResumeGeofence: Remote Exception calling LocationManagerService"); 3068ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh result = false; 3078ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 3088ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh break; 3098ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh default: 3108ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh result = false; 3118ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 3128ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh if (DEBUG) Log.d(TAG, "resumeGeofence: Result is: " + result); 3138ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh return result; 3148ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 3158ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 3168ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh public boolean registerForMonitorStateChangeCallback(int monitoringType, 317da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh IGeofenceHardwareMonitorCallback callback) { 318da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh Message reaperMessage = 319da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh mReaperHandler.obtainMessage(REAPER_MONITOR_CALLBACK_ADDED, callback); 320da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh reaperMessage.arg1 = monitoringType; 321da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh mReaperHandler.sendMessage(reaperMessage); 322da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh 3238ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh Message m = mCallbacksHandler.obtainMessage(CALLBACK_ADD, callback); 3248ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh m.arg1 = monitoringType; 3258ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh mCallbacksHandler.sendMessage(m); 3268ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh return true; 3278ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 3288ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 3298ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh public boolean unregisterForMonitorStateChangeCallback(int monitoringType, 330da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh IGeofenceHardwareMonitorCallback callback) { 3318ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh Message m = mCallbacksHandler.obtainMessage(CALLBACK_REMOVE, callback); 3328ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh m.arg1 = monitoringType; 3338ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh mCallbacksHandler.sendMessage(m); 3348ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh return true; 3358ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 3368ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 3378ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh private Location getLocation(int flags, double latitude, 3388ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh double longitude, double altitude, float speed, float bearing, float accuracy, 3398ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh long timestamp) { 3408ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh if (DEBUG) Log.d(TAG, "GetLocation: " + flags + ":" + latitude); 3418ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh Location location = new Location(LocationManager.GPS_PROVIDER); 3428ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh if ((flags & LOCATION_HAS_LAT_LONG) == LOCATION_HAS_LAT_LONG) { 3438ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh location.setLatitude(latitude); 3448ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh location.setLongitude(longitude); 3458ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh location.setTime(timestamp); 3468ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh // It would be nice to push the elapsed real-time timestamp 3478ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh // further down the stack, but this is still useful 3488ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh location.setElapsedRealtimeNanos(SystemClock.elapsedRealtimeNanos()); 3498ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 3508ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh if ((flags & LOCATION_HAS_ALTITUDE) == LOCATION_HAS_ALTITUDE) { 3518ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh location.setAltitude(altitude); 3528ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } else { 3538ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh location.removeAltitude(); 3548ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 3558ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh if ((flags & LOCATION_HAS_SPEED) == LOCATION_HAS_SPEED) { 3568ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh location.setSpeed(speed); 3578ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } else { 3588ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh location.removeSpeed(); 3598ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 3608ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh if ((flags & LOCATION_HAS_BEARING) == LOCATION_HAS_BEARING) { 3618ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh location.setBearing(bearing); 3628ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } else { 3638ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh location.removeBearing(); 3648ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 3658ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh if ((flags & LOCATION_HAS_ACCURACY) == LOCATION_HAS_ACCURACY) { 3668ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh location.setAccuracy(accuracy); 3678ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } else { 3688ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh location.removeAccuracy(); 3698ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 3708ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh return location; 3718ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 3728ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 3738ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh /** 3748ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh * called from GpsLocationProvider to report geofence transition 3758ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh */ 3768ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh public void reportGpsGeofenceTransition(int geofenceId, int flags, double latitude, 3778ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh double longitude, double altitude, float speed, float bearing, float accuracy, 3788ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh long timestamp, int transition, long transitionTimestamp) { 3798ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh if (DEBUG) Log.d(TAG, "GeofenceTransition: Flags: " + flags + " Lat: " + latitude + 3808ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh " Long: " + longitude + " Altitude: " + altitude + " Speed: " + speed + " Bearing: " + 3818ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh bearing + " Accuracy: " + accuracy + " Timestamp: " + timestamp + " Transition: " + 3828ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh transition + " TransitionTimestamp: " + transitionTimestamp); 3838ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh Location location = getLocation(flags, latitude, longitude, altitude, speed, bearing, 3848ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh accuracy, timestamp); 3858ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh GeofenceTransition t = new GeofenceTransition(geofenceId, transition, timestamp, location); 3868ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh acquireWakeLock(); 3878ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh Message m = mGeofenceHandler.obtainMessage(GEOFENCE_TRANSITION_CALLBACK, t); 3888ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh mGeofenceHandler.sendMessage(m); 3898ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 3908ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 3918ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh /** 3928ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh * called from GpsLocationProvider to report GPS status change. 3938ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh */ 3948ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh public void reportGpsGeofenceStatus(int status, int flags, double latitude, 3958ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh double longitude, double altitude, float speed, float bearing, float accuracy, 3968ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh long timestamp) { 3978ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh Location location = getLocation(flags, latitude, longitude, altitude, speed, bearing, 3988ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh accuracy, timestamp); 3998ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh boolean available = false; 4008ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh if (status == GeofenceHardware.GPS_GEOFENCE_AVAILABLE) available = true; 4018ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 402b8061be81c7a7cf87f4edc7ea48a8fd464363a61Zhentao Sun int val = (available ? GeofenceHardware.MONITOR_CURRENTLY_AVAILABLE : 403b8061be81c7a7cf87f4edc7ea48a8fd464363a61Zhentao Sun GeofenceHardware.MONITOR_CURRENTLY_UNAVAILABLE); 4048ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh setMonitorAvailability(GeofenceHardware.MONITORING_TYPE_GPS_HARDWARE, val); 4058ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 4068ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh acquireWakeLock(); 4078ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh Message m = mCallbacksHandler.obtainMessage(GPS_GEOFENCE_STATUS, location); 4088ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh m.arg1 = val; 4098ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh mCallbacksHandler.sendMessage(m); 4108ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 4118ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 4128ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh /** 4138ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh * called from GpsLocationProvider add geofence callback. 4148ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh */ 4158ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh public void reportGpsGeofenceAddStatus(int geofenceId, int status) { 4168ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh if (DEBUG) Log.d(TAG, "Add Callback: GPS : Id: " + geofenceId + " Status: " + status); 4178ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh acquireWakeLock(); 4188ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh Message m = mGeofenceHandler.obtainMessage(ADD_GEOFENCE_CALLBACK); 4198ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh m.arg1 = geofenceId; 4208ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh m.arg2 = getGeofenceStatus(status); 4218ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh mGeofenceHandler.sendMessage(m); 4228ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 4238ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 4248ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh /** 4258ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh * called from GpsLocationProvider remove geofence callback. 4268ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh */ 4278ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh public void reportGpsGeofenceRemoveStatus(int geofenceId, int status) { 4288ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh if (DEBUG) Log.d(TAG, "Remove Callback: GPS : Id: " + geofenceId + " Status: " + status); 4298ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh acquireWakeLock(); 4308ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh Message m = mGeofenceHandler.obtainMessage(REMOVE_GEOFENCE_CALLBACK); 4318ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh m.arg1 = geofenceId; 4328ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh m.arg2 = getGeofenceStatus(status); 4338ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh mGeofenceHandler.sendMessage(m); 4348ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 4358ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 4368ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh /** 4378ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh * called from GpsLocationProvider pause geofence callback. 4388ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh */ 4398ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh public void reportGpsGeofencePauseStatus(int geofenceId, int status) { 4408ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh if (DEBUG) Log.d(TAG, "Pause Callback: GPS : Id: " + geofenceId + " Status: " + status); 4418ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh acquireWakeLock(); 4428ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh Message m = mGeofenceHandler.obtainMessage(PAUSE_GEOFENCE_CALLBACK); 4438ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh m.arg1 = geofenceId; 4448ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh m.arg2 = getGeofenceStatus(status); 4458ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh mGeofenceHandler.sendMessage(m); 4468ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 4478ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 4488ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh /** 4498ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh * called from GpsLocationProvider resume geofence callback. 4508ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh */ 4518ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh public void reportGpsGeofenceResumeStatus(int geofenceId, int status) { 4528ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh if (DEBUG) Log.d(TAG, "Resume Callback: GPS : Id: " + geofenceId + " Status: " + status); 4538ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh acquireWakeLock(); 4548ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh Message m = mGeofenceHandler.obtainMessage(RESUME_GEOFENCE_CALLBACK); 4558ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh m.arg1 = geofenceId; 4568ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh m.arg2 = getGeofenceStatus(status); 4578ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh mGeofenceHandler.sendMessage(m); 4588ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 4598ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 4608ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh // All operations on mGeofences 4618ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh private Handler mGeofenceHandler = new Handler() { 4628ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh @Override 4638ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh public void handleMessage(Message msg) { 4648ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh int geofenceId; 4658ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh int status; 4668ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh IGeofenceHardwareCallback callback; 4678ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh switch (msg.what) { 4688ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh case ADD_GEOFENCE_CALLBACK: 4698ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh geofenceId = msg.arg1; 470f8f085c51b5f8b180ad964d0385b34f8fa97cd32Zhentao Sun synchronized (mGeofences) { 471f8f085c51b5f8b180ad964d0385b34f8fa97cd32Zhentao Sun callback = mGeofences.get(geofenceId); 472f8f085c51b5f8b180ad964d0385b34f8fa97cd32Zhentao Sun } 4738ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 474cfa496f7cdc52711e9ad7521224f67d1aaee002cZhentao Sun if (callback != null) { 475cfa496f7cdc52711e9ad7521224f67d1aaee002cZhentao Sun try { 476cfa496f7cdc52711e9ad7521224f67d1aaee002cZhentao Sun callback.onGeofenceAdd(geofenceId, msg.arg2); 477cfa496f7cdc52711e9ad7521224f67d1aaee002cZhentao Sun } catch (RemoteException e) {Log.i(TAG, "Remote Exception:" + e);} 478cfa496f7cdc52711e9ad7521224f67d1aaee002cZhentao Sun } 4798ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh releaseWakeLock(); 4808ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh break; 4818ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh case REMOVE_GEOFENCE_CALLBACK: 4828ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh geofenceId = msg.arg1; 483f8f085c51b5f8b180ad964d0385b34f8fa97cd32Zhentao Sun synchronized (mGeofences) { 484f8f085c51b5f8b180ad964d0385b34f8fa97cd32Zhentao Sun callback = mGeofences.get(geofenceId); 485f8f085c51b5f8b180ad964d0385b34f8fa97cd32Zhentao Sun } 4868ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 487cfa496f7cdc52711e9ad7521224f67d1aaee002cZhentao Sun if (callback != null) { 488cfa496f7cdc52711e9ad7521224f67d1aaee002cZhentao Sun try { 489cfa496f7cdc52711e9ad7521224f67d1aaee002cZhentao Sun callback.onGeofenceRemove(geofenceId, msg.arg2); 490cfa496f7cdc52711e9ad7521224f67d1aaee002cZhentao Sun } catch (RemoteException e) {} 491cfa496f7cdc52711e9ad7521224f67d1aaee002cZhentao Sun synchronized (mGeofences) { 492cfa496f7cdc52711e9ad7521224f67d1aaee002cZhentao Sun mGeofences.remove(geofenceId); 493cfa496f7cdc52711e9ad7521224f67d1aaee002cZhentao Sun } 494f8f085c51b5f8b180ad964d0385b34f8fa97cd32Zhentao Sun } 4958ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh releaseWakeLock(); 4968ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh break; 4978ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 4988ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh case PAUSE_GEOFENCE_CALLBACK: 4998ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh geofenceId = msg.arg1; 500f8f085c51b5f8b180ad964d0385b34f8fa97cd32Zhentao Sun synchronized (mGeofences) { 501f8f085c51b5f8b180ad964d0385b34f8fa97cd32Zhentao Sun callback = mGeofences.get(geofenceId); 502f8f085c51b5f8b180ad964d0385b34f8fa97cd32Zhentao Sun } 5038ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 504cfa496f7cdc52711e9ad7521224f67d1aaee002cZhentao Sun if (callback != null) { 505cfa496f7cdc52711e9ad7521224f67d1aaee002cZhentao Sun try { 506cfa496f7cdc52711e9ad7521224f67d1aaee002cZhentao Sun callback.onGeofencePause(geofenceId, msg.arg2); 507cfa496f7cdc52711e9ad7521224f67d1aaee002cZhentao Sun } catch (RemoteException e) {} 508cfa496f7cdc52711e9ad7521224f67d1aaee002cZhentao Sun } 5098ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh releaseWakeLock(); 5108ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh break; 5118ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 5128ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh case RESUME_GEOFENCE_CALLBACK: 5138ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh geofenceId = msg.arg1; 514f8f085c51b5f8b180ad964d0385b34f8fa97cd32Zhentao Sun synchronized (mGeofences) { 515f8f085c51b5f8b180ad964d0385b34f8fa97cd32Zhentao Sun callback = mGeofences.get(geofenceId); 516f8f085c51b5f8b180ad964d0385b34f8fa97cd32Zhentao Sun } 5178ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 518cfa496f7cdc52711e9ad7521224f67d1aaee002cZhentao Sun if (callback != null) { 519cfa496f7cdc52711e9ad7521224f67d1aaee002cZhentao Sun try { 520cfa496f7cdc52711e9ad7521224f67d1aaee002cZhentao Sun callback.onGeofenceResume(geofenceId, msg.arg2); 521cfa496f7cdc52711e9ad7521224f67d1aaee002cZhentao Sun } catch (RemoteException e) {} 522cfa496f7cdc52711e9ad7521224f67d1aaee002cZhentao Sun } 5238ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh releaseWakeLock(); 5248ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh break; 5258ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 5268ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh case GEOFENCE_TRANSITION_CALLBACK: 5278ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh GeofenceTransition geofenceTransition = (GeofenceTransition)(msg.obj); 528f8f085c51b5f8b180ad964d0385b34f8fa97cd32Zhentao Sun synchronized (mGeofences) { 529f8f085c51b5f8b180ad964d0385b34f8fa97cd32Zhentao Sun callback = mGeofences.get(geofenceTransition.mGeofenceId); 530f8f085c51b5f8b180ad964d0385b34f8fa97cd32Zhentao Sun } 5318ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 5328ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh if (DEBUG) Log.d(TAG, "GeofenceTransistionCallback: GPS : GeofenceId: " + 5338ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh geofenceTransition.mGeofenceId + 534f8f085c51b5f8b180ad964d0385b34f8fa97cd32Zhentao Sun " Transition: " + geofenceTransition.mTransition + 535f8f085c51b5f8b180ad964d0385b34f8fa97cd32Zhentao Sun " Location: " + geofenceTransition.mLocation + ":" + mGeofences); 5368ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 537cfa496f7cdc52711e9ad7521224f67d1aaee002cZhentao Sun if (callback != null) { 538cfa496f7cdc52711e9ad7521224f67d1aaee002cZhentao Sun try { 539cfa496f7cdc52711e9ad7521224f67d1aaee002cZhentao Sun callback.onGeofenceTransition( 540cfa496f7cdc52711e9ad7521224f67d1aaee002cZhentao Sun geofenceTransition.mGeofenceId, geofenceTransition.mTransition, 541cfa496f7cdc52711e9ad7521224f67d1aaee002cZhentao Sun geofenceTransition.mLocation, geofenceTransition.mTimestamp, 542cfa496f7cdc52711e9ad7521224f67d1aaee002cZhentao Sun GeofenceHardware.MONITORING_TYPE_GPS_HARDWARE); 543cfa496f7cdc52711e9ad7521224f67d1aaee002cZhentao Sun } catch (RemoteException e) {} 544cfa496f7cdc52711e9ad7521224f67d1aaee002cZhentao Sun } 5458ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh releaseWakeLock(); 5468ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh break; 547da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh case GEOFENCE_CALLBACK_BINDER_DIED: 548da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh // Find all geofences associated with this callback and remove them. 549da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh callback = (IGeofenceHardwareCallback) (msg.obj); 550da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh if (DEBUG) Log.d(TAG, "Geofence callback reaped:" + callback); 551da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh int monitoringType = msg.arg1; 552f8f085c51b5f8b180ad964d0385b34f8fa97cd32Zhentao Sun synchronized (mGeofences) { 553f8f085c51b5f8b180ad964d0385b34f8fa97cd32Zhentao Sun for (int i = 0; i < mGeofences.size(); i++) { 554f8f085c51b5f8b180ad964d0385b34f8fa97cd32Zhentao Sun if (mGeofences.valueAt(i).equals(callback)) { 555f8f085c51b5f8b180ad964d0385b34f8fa97cd32Zhentao Sun geofenceId = mGeofences.keyAt(i); 556f8f085c51b5f8b180ad964d0385b34f8fa97cd32Zhentao Sun removeGeofence(mGeofences.keyAt(i), monitoringType); 557f8f085c51b5f8b180ad964d0385b34f8fa97cd32Zhentao Sun mGeofences.remove(geofenceId); 558f8f085c51b5f8b180ad964d0385b34f8fa97cd32Zhentao Sun } 559f8f085c51b5f8b180ad964d0385b34f8fa97cd32Zhentao Sun } 560da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh } 5618ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 5628ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 5638ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh }; 5648ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 5658ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh // All operations on mCallbacks 5668ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh private Handler mCallbacksHandler = new Handler() { 5678ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh @Override 5688ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh public void handleMessage(Message msg) { 5698ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh int monitoringType; 570da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh ArrayList<IGeofenceHardwareMonitorCallback> callbackList; 571da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh IGeofenceHardwareMonitorCallback callback; 5728ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 5738ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh switch (msg.what) { 5748ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh case GPS_GEOFENCE_STATUS: 5758ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh Location location = (Location) msg.obj; 5768ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh int val = msg.arg1; 5778ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh boolean available; 5788ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh available = (val == GeofenceHardware.MONITOR_CURRENTLY_AVAILABLE ? 5798ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh true : false); 5808ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh callbackList = mCallbacks[GeofenceHardware.MONITORING_TYPE_GPS_HARDWARE]; 581cfa496f7cdc52711e9ad7521224f67d1aaee002cZhentao Sun if (callbackList != null) { 582cfa496f7cdc52711e9ad7521224f67d1aaee002cZhentao Sun if (DEBUG) Log.d(TAG, "MonitoringSystemChangeCallback: GPS : " + available); 583cfa496f7cdc52711e9ad7521224f67d1aaee002cZhentao Sun 584cfa496f7cdc52711e9ad7521224f67d1aaee002cZhentao Sun for (IGeofenceHardwareMonitorCallback c: callbackList) { 585cfa496f7cdc52711e9ad7521224f67d1aaee002cZhentao Sun try { 586cfa496f7cdc52711e9ad7521224f67d1aaee002cZhentao Sun c.onMonitoringSystemChange( 587cfa496f7cdc52711e9ad7521224f67d1aaee002cZhentao Sun GeofenceHardware.MONITORING_TYPE_GPS_HARDWARE, available, 588cfa496f7cdc52711e9ad7521224f67d1aaee002cZhentao Sun location); 589cfa496f7cdc52711e9ad7521224f67d1aaee002cZhentao Sun } catch (RemoteException e) {} 590cfa496f7cdc52711e9ad7521224f67d1aaee002cZhentao Sun } 5918ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 5928ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh releaseWakeLock(); 5938ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh break; 5948ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh case CALLBACK_ADD: 5958ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh monitoringType = msg.arg1; 596da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh callback = (IGeofenceHardwareMonitorCallback) msg.obj; 5978ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh callbackList = mCallbacks[monitoringType]; 5988ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh if (callbackList == null) { 599da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh callbackList = new ArrayList<IGeofenceHardwareMonitorCallback>(); 6008ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh mCallbacks[monitoringType] = callbackList; 6018ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 6028ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh if (!callbackList.contains(callback)) callbackList.add(callback); 6038ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh break; 6048ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh case CALLBACK_REMOVE: 6058ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh monitoringType = msg.arg1; 606da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh callback = (IGeofenceHardwareMonitorCallback) msg.obj; 6078ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh callbackList = mCallbacks[monitoringType]; 6088ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh if (callbackList != null) { 6098ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh callbackList.remove(callback); 6108ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 6118ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh break; 612da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh case MONITOR_CALLBACK_BINDER_DIED: 613da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh callback = (IGeofenceHardwareMonitorCallback) msg.obj; 614da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh if (DEBUG) Log.d(TAG, "Monitor callback reaped:" + callback); 615da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh callbackList = mCallbacks[msg.arg1]; 616da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh if (callbackList != null && callbackList.contains(callback)) { 617da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh callbackList.remove(callback); 618da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh } 619da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh } 620da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh } 621da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh }; 622da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh 623da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh // All operations on mReaper 624da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh private Handler mReaperHandler = new Handler() { 625da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh @Override 626da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh public void handleMessage(Message msg) { 627da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh Reaper r; 628da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh IGeofenceHardwareCallback callback; 629da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh IGeofenceHardwareMonitorCallback monitorCallback; 630da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh int monitoringType; 631da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh 632da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh switch (msg.what) { 633da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh case REAPER_GEOFENCE_ADDED: 634da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh callback = (IGeofenceHardwareCallback) msg.obj; 635da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh monitoringType = msg.arg1; 636da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh r = new Reaper(callback, monitoringType); 637da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh if (!mReapers.contains(r)) { 638da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh mReapers.add(r); 639da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh IBinder b = callback.asBinder(); 640da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh try { 641da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh b.linkToDeath(r, 0); 642da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh } catch (RemoteException e) {} 643da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh } 644da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh break; 645da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh case REAPER_MONITOR_CALLBACK_ADDED: 646da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh monitorCallback = (IGeofenceHardwareMonitorCallback) msg.obj; 647da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh monitoringType = msg.arg1; 648da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh 649da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh r = new Reaper(monitorCallback, monitoringType); 650da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh if (!mReapers.contains(r)) { 651da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh mReapers.add(r); 652da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh IBinder b = monitorCallback.asBinder(); 653da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh try { 654da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh b.linkToDeath(r, 0); 655da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh } catch (RemoteException e) {} 656da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh } 657da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh break; 658da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh case REAPER_REMOVED: 659da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh r = (Reaper) msg.obj; 660da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh mReapers.remove(r); 6618ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 6628ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 6638ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh }; 6648ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 6658ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh private class GeofenceTransition { 6668ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh private int mGeofenceId, mTransition; 6678ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh private long mTimestamp; 6688ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh private Location mLocation; 6698ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 6708ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh GeofenceTransition(int geofenceId, int transition, long timestamp, Location location) { 6718ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh mGeofenceId = geofenceId; 6728ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh mTransition = transition; 6738ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh mTimestamp = timestamp; 6748ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh mLocation = location; 6758ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 6768ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 6778ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 6788ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh private void setMonitorAvailability(int monitor, int val) { 6798ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh synchronized (mSupportedMonitorTypes) { 6808ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh mSupportedMonitorTypes[monitor] = val; 6818ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 6828ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 6838ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 6848ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 6858ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh int getMonitoringResolutionLevel(int monitoringType) { 6868ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh switch (monitoringType) { 6878ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh case GeofenceHardware.MONITORING_TYPE_GPS_HARDWARE: 6888ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh return RESOLUTION_LEVEL_FINE; 6898ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 6908ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh return RESOLUTION_LEVEL_NONE; 6918ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 6928ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 693da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh class Reaper implements IBinder.DeathRecipient { 694da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh private IGeofenceHardwareMonitorCallback mMonitorCallback; 695da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh private IGeofenceHardwareCallback mCallback; 696da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh private int mMonitoringType; 697da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh 698da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh Reaper(IGeofenceHardwareCallback c, int monitoringType) { 699da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh mCallback = c; 700da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh mMonitoringType = monitoringType; 701da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh } 702da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh 703da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh Reaper(IGeofenceHardwareMonitorCallback c, int monitoringType) { 704da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh mMonitorCallback = c; 705da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh mMonitoringType = monitoringType; 706da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh } 707da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh 708da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh @Override 709da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh public void binderDied() { 710da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh Message m; 711da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh if (mCallback != null) { 712da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh m = mGeofenceHandler.obtainMessage(GEOFENCE_CALLBACK_BINDER_DIED, mCallback); 713da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh m.arg1 = mMonitoringType; 714da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh mGeofenceHandler.sendMessage(m); 715da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh } else if (mMonitorCallback != null) { 716da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh m = mCallbacksHandler.obtainMessage(MONITOR_CALLBACK_BINDER_DIED, mMonitorCallback); 717da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh m.arg1 = mMonitoringType; 718da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh mCallbacksHandler.sendMessage(m); 719da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh } 720da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh Message reaperMessage = mReaperHandler.obtainMessage(REAPER_REMOVED, this); 721da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh mReaperHandler.sendMessage(reaperMessage); 722da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh } 723da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh 724da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh @Override 725da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh public int hashCode() { 726da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh int result = 17; 727da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh result = 31 * result + (mCallback != null ? mCallback.hashCode() : 0); 728da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh result = 31 * result + (mMonitorCallback != null ? mMonitorCallback.hashCode() : 0); 729da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh result = 31 * result + mMonitoringType; 730da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh return result; 731da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh } 732da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh 733da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh @Override 734da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh public boolean equals(Object obj) { 735da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh if (obj == null) return false; 736da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh if (obj == this) return true; 737da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh 738da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh Reaper rhs = (Reaper) obj; 739da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh return rhs.mCallback == mCallback && rhs.mMonitorCallback == mMonitorCallback && 740da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh rhs.mMonitoringType == mMonitoringType; 741da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh } 742da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh } 743da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh 7448ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh int getAllowedResolutionLevel(int pid, int uid) { 7458ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh if (mContext.checkPermission(android.Manifest.permission.ACCESS_FINE_LOCATION, 7468ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh pid, uid) == PackageManager.PERMISSION_GRANTED) { 7478ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh return RESOLUTION_LEVEL_FINE; 7488ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } else if (mContext.checkPermission(android.Manifest.permission.ACCESS_COARSE_LOCATION, 7498ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh pid, uid) == PackageManager.PERMISSION_GRANTED) { 7508ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh return RESOLUTION_LEVEL_COARSE; 7518ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } else { 7528ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh return RESOLUTION_LEVEL_NONE; 7538ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 7548ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 7558ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh 7568ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh private int getGeofenceStatus(int status) { 7578ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh switch (status) { 7588ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh case GPS_GEOFENCE_OPERATION_SUCCESS: 7598ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh return GeofenceHardware.GEOFENCE_SUCCESS; 7608ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh case GPS_GEOFENCE_ERROR_GENERIC: 7618ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh return GeofenceHardware.GEOFENCE_FAILURE; 7628ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh case GPS_GEOFENCE_ERROR_ID_EXISTS: 7638ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh return GeofenceHardware.GEOFENCE_ERROR_ID_EXISTS; 7648ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh case GPS_GEOFENCE_ERROR_INVALID_TRANSITION: 7658ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh return GeofenceHardware.GEOFENCE_ERROR_INVALID_TRANSITION; 7668ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh case GPS_GEOFENCE_ERROR_TOO_MANY_GEOFENCES: 7678ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh return GeofenceHardware.GEOFENCE_ERROR_TOO_MANY_GEOFENCES; 7688ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh case GPS_GEOFENCE_ERROR_ID_UNKNOWN: 7698ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh return GeofenceHardware.GEOFENCE_ERROR_ID_UNKNOWN; 7708ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 7718ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh return -1; 7728ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh } 7738ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh} 774