GeofenceHardwareImpl.java revision 8ce470dd4ba0608abb6b5eae117cefca927af96b
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;
248ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganeshimport android.os.Bundle;
258ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganeshimport android.os.Handler;
268ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganeshimport android.os.Message;
278ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganeshimport android.os.PowerManager;
288ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganeshimport android.os.RemoteException;
298ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganeshimport android.os.ServiceManager;
308ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganeshimport android.os.SystemClock;
318ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganeshimport android.util.Log;
328ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganeshimport android.util.SparseArray;
338ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh
348ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganeshimport java.util.ArrayList;
358ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganeshimport java.util.HashMap;
368ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh
378ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh/**
388ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh * This class manages the geofences which are handled by hardware.
398ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh *
408ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh * @hide
418ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh */
428ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganeshpublic final class GeofenceHardwareImpl {
438ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    private static final String TAG = "GeofenceHardwareImpl";
448ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
458ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh
468ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    private final Context mContext;
478ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    private static GeofenceHardwareImpl sInstance;
488ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    private PowerManager.WakeLock mWakeLock;
498ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    private SparseArray<IGeofenceHardwareCallback> mGeofences =
508ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh            new SparseArray<IGeofenceHardwareCallback>();
518ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    private ArrayList<IGeofenceHardwareCallback>[] mCallbacks =
528ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh            new ArrayList[GeofenceHardware.NUM_MONITORS];
538ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh
548ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    private IGpsGeofenceHardware mGpsService;
558ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh
568ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    private int[] mSupportedMonitorTypes = new int[GeofenceHardware.NUM_MONITORS];
578ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh
588ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    // mGeofenceHandler message types
598ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    private static final int GEOFENCE_TRANSITION_CALLBACK = 1;
608ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    private static final int ADD_GEOFENCE_CALLBACK = 2;
618ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    private static final int REMOVE_GEOFENCE_CALLBACK = 3;
628ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    private static final int PAUSE_GEOFENCE_CALLBACK = 4;
638ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    private static final int RESUME_GEOFENCE_CALLBACK = 5;
648ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    private static final int ADD_GEOFENCE = 6;
658ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    private static final int REMOVE_GEOFENCE = 7;
668ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh
678ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    // mCallbacksHandler message types
688ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    private static final int GPS_GEOFENCE_STATUS = 1;
698ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    private static final int CALLBACK_ADD = 2;
708ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    private static final int CALLBACK_REMOVE = 3;
718ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh
728ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    // The following constants need to match GpsLocationFlags enum in gps.h
738ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    private static final int LOCATION_INVALID = 0;
748ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    private static final int LOCATION_HAS_LAT_LONG = 1;
758ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    private static final int LOCATION_HAS_ALTITUDE = 2;
768ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    private static final int LOCATION_HAS_SPEED = 4;
778ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    private static final int LOCATION_HAS_BEARING = 8;
788ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    private static final int LOCATION_HAS_ACCURACY = 16;
798ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh
808ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    // Resolution level constants used for permission checks.
818ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    // These constants must be in increasing order of finer resolution.
828ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    private static final int RESOLUTION_LEVEL_NONE = 1;
838ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    private static final int RESOLUTION_LEVEL_COARSE = 2;
848ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    private static final int RESOLUTION_LEVEL_FINE = 3;
858ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh
868ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    // GPS Geofence errors. Should match gps.h constants.
878ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    private static final int GPS_GEOFENCE_OPERATION_SUCCESS = 0;
888ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    private static final int GPS_GEOFENCE_ERROR_TOO_MANY_GEOFENCES = 100;
898ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    private static final int GPS_GEOFENCE_ERROR_ID_EXISTS  = -101;
908ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    private static final int GPS_GEOFENCE_ERROR_ID_UNKNOWN = -102;
918ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    private static final int GPS_GEOFENCE_ERROR_INVALID_TRANSITION = -103;
928ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    private static final int GPS_GEOFENCE_ERROR_GENERIC = -149;
938ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh
948ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh
958ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh
968ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    public synchronized static GeofenceHardwareImpl getInstance(Context context) {
978ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        if (sInstance == null) {
988ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh            sInstance = new GeofenceHardwareImpl(context);
998ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        }
1008ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        return sInstance;
1018ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    }
1028ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh
1038ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    private GeofenceHardwareImpl(Context context) {
1048ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        mContext = context;
1058ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        // Init everything to unsupported.
1068ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        setMonitorAvailability(GeofenceHardware.MONITORING_TYPE_GPS_HARDWARE,
1078ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                GeofenceHardware.MONITOR_UNSUPPORTED);
1088ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh
1098ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    }
1108ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh
1118ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    private void acquireWakeLock() {
1128ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        if (mWakeLock == null) {
1138ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh            PowerManager powerManager =
1148ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                    (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
1158ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh            mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, TAG);
1168ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        }
1178ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        mWakeLock.acquire();
1188ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    }
1198ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh
1208ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    private void releaseWakeLock() {
1218ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        if (mWakeLock.isHeld()) mWakeLock.release();
1228ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    }
1238ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh
1248ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    private void updateGpsHardwareAvailability() {
1258ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        //Check which monitors are available.
1268ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        boolean gpsSupported;
1278ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        try {
1288ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh            gpsSupported = mGpsService.isHardwareGeofenceSupported();
1298ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        } catch (RemoteException e) {
1308ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh            Log.e(TAG, "Remote Exception calling LocationManagerService");
1318ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh            gpsSupported = false;
1328ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        }
1338ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh
1348ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        if (gpsSupported) {
1358ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh            // Its assumed currently available at startup.
1368ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh            // native layer will update later.
1378ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh            setMonitorAvailability(GeofenceHardware.MONITORING_TYPE_GPS_HARDWARE,
1388ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                    GeofenceHardware.MONITOR_CURRENTLY_AVAILABLE);
1398ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        }
1408ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    }
1418ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh
1428ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    public void setGpsHardwareGeofence(IGpsGeofenceHardware service) {
1438ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        if (mGpsService == null) {
1448ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh            mGpsService = service;
1458ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh            updateGpsHardwareAvailability();
1468ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        } else if (service == null) {
1478ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh            mGpsService = null;
1488ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh            Log.w(TAG, "GPS Geofence Hardware service seems to have crashed");
1498ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        } else {
1508ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh            Log.e(TAG, "Error: GpsService being set again.");
1518ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        }
1528ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    }
1538ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh
1548ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    public int[] getMonitoringTypesAndStatus() {
1558ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        synchronized (mSupportedMonitorTypes) {
1568ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh            return mSupportedMonitorTypes;
1578ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        }
1588ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    }
1598ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh
1608ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    public boolean addCircularFence(int geofenceId, double latitude, double longitude,
1618ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh            double radius, int lastTransition,int monitorTransitions, int notificationResponsivenes,
1628ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh            int unknownTimer, int monitoringType, IGeofenceHardwareCallback callback) {
1638ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        // This API is not thread safe. Operations on the same geofence need to be serialized
1648ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        // by upper layers
1658ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        if (DEBUG) {
1668ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh            Log.d(TAG, "addCircularFence: GeofenceId: " + geofenceId + "Latitude: " + latitude +
1678ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                    "Longitude: " + longitude + "Radius: " + radius + "LastTransition: "
1688ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                    + lastTransition + "MonitorTransition: " + monitorTransitions +
1698ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                    "NotificationResponsiveness: " + notificationResponsivenes +
1708ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                    "UnKnown Timer: " + unknownTimer + "MonitoringType: " + monitoringType);
1718ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh
1728ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        }
1738ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        boolean result;
1748ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        Message m = mGeofenceHandler.obtainMessage(ADD_GEOFENCE, callback);
1758ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        m.arg1 = geofenceId;
1768ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        mGeofenceHandler.sendMessage(m);
1778ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh
1788ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        switch (monitoringType) {
1798ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh            case GeofenceHardware.MONITORING_TYPE_GPS_HARDWARE:
1808ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                if (mGpsService == null) return false;
1818ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                try {
1828ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                    result = mGpsService.addCircularHardwareGeofence(geofenceId, latitude,
1838ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                            longitude, radius, lastTransition, monitorTransitions,
1848ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                            notificationResponsivenes, unknownTimer);
1858ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                } catch (RemoteException e) {
1868ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                    Log.e(TAG, "AddGeofence: Remote Exception calling LocationManagerService");
1878ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                    result = false;
1888ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                }
1898ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                break;
1908ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh            default:
1918ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                result = false;
1928ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        }
1938ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        if (!result) {
1948ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh            m = mGeofenceHandler.obtainMessage(REMOVE_GEOFENCE);
1958ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh            m.arg1 = geofenceId;
1968ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh            mGeofenceHandler.sendMessage(m);
1978ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        }
1988ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh
1998ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        if (DEBUG) Log.d(TAG, "addCircularFence: Result is: " + result);
2008ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        return result;
2018ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    }
2028ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh
2038ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    public boolean removeGeofence(int geofenceId, int monitoringType) {
2048ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        // This API is not thread safe. Operations on the same geofence need to be serialized
2058ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        // by upper layers
2068ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        if (DEBUG) Log.d(TAG, "Remove Geofence: GeofenceId: " + geofenceId);
2078ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        boolean result = false;
2088ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        switch (monitoringType) {
2098ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh            case GeofenceHardware.MONITORING_TYPE_GPS_HARDWARE:
2108ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                if (mGpsService == null) return false;
2118ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                try {
2128ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                    result = mGpsService.removeHardwareGeofence(geofenceId);
2138ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                } catch (RemoteException e) {
2148ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                    Log.e(TAG, "RemoveGeofence: Remote Exception calling LocationManagerService");
2158ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                    result = false;
2168ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                }
2178ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                break;
2188ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh            default:
2198ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                result = false;
2208ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        }
2218ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        if (DEBUG) Log.d(TAG, "removeGeofence: Result is: " + result);
2228ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        return result;
2238ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    }
2248ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh
2258ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    public boolean pauseGeofence(int geofenceId, int monitoringType) {
2268ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        // This API is not thread safe. Operations on the same geofence need to be serialized
2278ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        // by upper layers
2288ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        if (DEBUG) Log.d(TAG, "Pause Geofence: GeofenceId: " + geofenceId);
2298ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        boolean result;
2308ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        switch (monitoringType) {
2318ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh            case GeofenceHardware.MONITORING_TYPE_GPS_HARDWARE:
2328ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                if (mGpsService == null) return false;
2338ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                try {
2348ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                    result = mGpsService.pauseHardwareGeofence(geofenceId);
2358ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                } catch (RemoteException e) {
2368ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                    Log.e(TAG, "PauseGeofence: Remote Exception calling LocationManagerService");
2378ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                    result = false;
2388ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                }
2398ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                break;
2408ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh            default:
2418ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                result = false;
2428ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        }
2438ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        if (DEBUG) Log.d(TAG, "pauseGeofence: Result is: " + result);
2448ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        return result;
2458ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    }
2468ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh
2478ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh
2488ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    public boolean resumeGeofence(int geofenceId, int monitorTransition, int monitoringType) {
2498ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        // This API is not thread safe. Operations on the same geofence need to be serialized
2508ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        // by upper layers
2518ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        if (DEBUG) Log.d(TAG, "Resume Geofence: GeofenceId: " + geofenceId);
2528ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        boolean result;
2538ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        switch (monitoringType) {
2548ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh            case GeofenceHardware.MONITORING_TYPE_GPS_HARDWARE:
2558ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                if (mGpsService == null) return false;
2568ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                try {
2578ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                    result = mGpsService.resumeHardwareGeofence(geofenceId, monitorTransition);
2588ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                } catch (RemoteException e) {
2598ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                    Log.e(TAG, "ResumeGeofence: Remote Exception calling LocationManagerService");
2608ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                    result = false;
2618ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                }
2628ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                break;
2638ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh            default:
2648ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                result = false;
2658ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        }
2668ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        if (DEBUG) Log.d(TAG, "resumeGeofence: Result is: " + result);
2678ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        return result;
2688ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    }
2698ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh
2708ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    public boolean registerForMonitorStateChangeCallback(int monitoringType,
2718ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh            IGeofenceHardwareCallback callback) {
2728ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        Message m = mCallbacksHandler.obtainMessage(CALLBACK_ADD, callback);
2738ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        m.arg1 = monitoringType;
2748ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        mCallbacksHandler.sendMessage(m);
2758ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        return true;
2768ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    }
2778ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh
2788ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    public boolean unregisterForMonitorStateChangeCallback(int monitoringType,
2798ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh            IGeofenceHardwareCallback callback) {
2808ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        Message m = mCallbacksHandler.obtainMessage(CALLBACK_REMOVE, callback);
2818ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        m.arg1 = monitoringType;
2828ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        mCallbacksHandler.sendMessage(m);
2838ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        return true;
2848ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    }
2858ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh
2868ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    private Location getLocation(int flags, double latitude,
2878ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh            double longitude, double altitude, float speed, float bearing, float accuracy,
2888ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh            long timestamp) {
2898ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        if (DEBUG) Log.d(TAG, "GetLocation: " + flags + ":" + latitude);
2908ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        Location location = new Location(LocationManager.GPS_PROVIDER);
2918ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        if ((flags & LOCATION_HAS_LAT_LONG) == LOCATION_HAS_LAT_LONG) {
2928ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh            location.setLatitude(latitude);
2938ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh            location.setLongitude(longitude);
2948ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh            location.setTime(timestamp);
2958ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh            // It would be nice to push the elapsed real-time timestamp
2968ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh            // further down the stack, but this is still useful
2978ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh            location.setElapsedRealtimeNanos(SystemClock.elapsedRealtimeNanos());
2988ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        }
2998ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        if ((flags & LOCATION_HAS_ALTITUDE) == LOCATION_HAS_ALTITUDE) {
3008ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh            location.setAltitude(altitude);
3018ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        } else {
3028ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh            location.removeAltitude();
3038ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        }
3048ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        if ((flags & LOCATION_HAS_SPEED) == LOCATION_HAS_SPEED) {
3058ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh            location.setSpeed(speed);
3068ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        } else {
3078ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh            location.removeSpeed();
3088ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        }
3098ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        if ((flags & LOCATION_HAS_BEARING) == LOCATION_HAS_BEARING) {
3108ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh            location.setBearing(bearing);
3118ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        } else {
3128ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh            location.removeBearing();
3138ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        }
3148ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        if ((flags & LOCATION_HAS_ACCURACY) == LOCATION_HAS_ACCURACY) {
3158ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh            location.setAccuracy(accuracy);
3168ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        } else {
3178ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh            location.removeAccuracy();
3188ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        }
3198ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        return location;
3208ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    }
3218ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh
3228ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    /**
3238ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     * called from GpsLocationProvider to report geofence transition
3248ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     */
3258ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    public void reportGpsGeofenceTransition(int geofenceId, int flags, double latitude,
3268ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh            double longitude, double altitude, float speed, float bearing, float accuracy,
3278ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh            long timestamp, int transition, long transitionTimestamp) {
3288ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        if (DEBUG) Log.d(TAG, "GeofenceTransition: Flags: " + flags + " Lat: " + latitude +
3298ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh            " Long: " + longitude + " Altitude: " + altitude + " Speed: " + speed + " Bearing: " +
3308ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh            bearing + " Accuracy: " + accuracy + " Timestamp: " + timestamp + " Transition: " +
3318ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh            transition + " TransitionTimestamp: " + transitionTimestamp);
3328ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        Location location = getLocation(flags, latitude, longitude, altitude, speed, bearing,
3338ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                accuracy, timestamp);
3348ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        GeofenceTransition t = new GeofenceTransition(geofenceId, transition, timestamp, location);
3358ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        acquireWakeLock();
3368ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        Message m = mGeofenceHandler.obtainMessage(GEOFENCE_TRANSITION_CALLBACK, t);
3378ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        mGeofenceHandler.sendMessage(m);
3388ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    }
3398ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh
3408ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    /**
3418ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     * called from GpsLocationProvider to report GPS status change.
3428ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     */
3438ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    public void reportGpsGeofenceStatus(int status, int flags, double latitude,
3448ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh            double longitude, double altitude, float speed, float bearing, float accuracy,
3458ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh            long timestamp) {
3468ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        Location location = getLocation(flags, latitude, longitude, altitude, speed, bearing,
3478ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                accuracy, timestamp);
3488ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        boolean available = false;
3498ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        if (status == GeofenceHardware.GPS_GEOFENCE_AVAILABLE) available = true;
3508ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh
3518ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        int val = (available ? GeofenceHardware.MONITOR_CURRENTLY_UNAVAILABLE :
3528ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                GeofenceHardware.MONITOR_CURRENTLY_AVAILABLE);
3538ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        setMonitorAvailability(GeofenceHardware.MONITORING_TYPE_GPS_HARDWARE, val);
3548ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh
3558ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        acquireWakeLock();
3568ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        Message m = mCallbacksHandler.obtainMessage(GPS_GEOFENCE_STATUS, location);
3578ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        m.arg1 = val;
3588ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        mCallbacksHandler.sendMessage(m);
3598ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    }
3608ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh
3618ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    /**
3628ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     * called from GpsLocationProvider add geofence callback.
3638ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     */
3648ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    public void reportGpsGeofenceAddStatus(int geofenceId, int status) {
3658ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        if (DEBUG) Log.d(TAG, "Add Callback: GPS : Id: " + geofenceId + " Status: " + status);
3668ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        acquireWakeLock();
3678ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        Message m = mGeofenceHandler.obtainMessage(ADD_GEOFENCE_CALLBACK);
3688ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        m.arg1 = geofenceId;
3698ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        m.arg2 = getGeofenceStatus(status);
3708ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        mGeofenceHandler.sendMessage(m);
3718ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    }
3728ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh
3738ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    /**
3748ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     * called from GpsLocationProvider remove geofence callback.
3758ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     */
3768ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    public void reportGpsGeofenceRemoveStatus(int geofenceId, int status) {
3778ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        if (DEBUG) Log.d(TAG, "Remove Callback: GPS : Id: " + geofenceId + " Status: " + status);
3788ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        acquireWakeLock();
3798ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        Message m = mGeofenceHandler.obtainMessage(REMOVE_GEOFENCE_CALLBACK);
3808ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        m.arg1 = geofenceId;
3818ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        m.arg2 = getGeofenceStatus(status);
3828ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        mGeofenceHandler.sendMessage(m);
3838ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    }
3848ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh
3858ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    /**
3868ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     * called from GpsLocationProvider pause geofence callback.
3878ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     */
3888ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    public void reportGpsGeofencePauseStatus(int geofenceId, int status) {
3898ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        if (DEBUG) Log.d(TAG, "Pause Callback: GPS : Id: " + geofenceId + " Status: " + status);
3908ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        acquireWakeLock();
3918ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        Message m = mGeofenceHandler.obtainMessage(PAUSE_GEOFENCE_CALLBACK);
3928ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        m.arg1 = geofenceId;
3938ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        m.arg2 = getGeofenceStatus(status);
3948ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        mGeofenceHandler.sendMessage(m);
3958ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    }
3968ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh
3978ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    /**
3988ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     * called from GpsLocationProvider resume geofence callback.
3998ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     */
4008ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    public void reportGpsGeofenceResumeStatus(int geofenceId, int status) {
4018ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        if (DEBUG) Log.d(TAG, "Resume Callback: GPS : Id: " + geofenceId + " Status: " + status);
4028ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        acquireWakeLock();
4038ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        Message m = mGeofenceHandler.obtainMessage(RESUME_GEOFENCE_CALLBACK);
4048ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        m.arg1 = geofenceId;
4058ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        m.arg2 = getGeofenceStatus(status);
4068ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        mGeofenceHandler.sendMessage(m);
4078ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    }
4088ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh
4098ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    // All operations on mGeofences
4108ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    private Handler mGeofenceHandler = new Handler() {
4118ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        @Override
4128ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        public void handleMessage(Message msg) {
4138ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh            int geofenceId;
4148ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh            int status;
4158ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh            IGeofenceHardwareCallback callback;
4168ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh            switch (msg.what) {
4178ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                case ADD_GEOFENCE:
4188ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                    geofenceId = msg.arg1;
4198ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                    callback = (IGeofenceHardwareCallback) msg.obj;
4208ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                    mGeofences.put(geofenceId, callback);
4218ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                    break;
4228ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                case REMOVE_GEOFENCE:
4238ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                    geofenceId = msg.arg1;
4248ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                    mGeofences.remove(geofenceId);
4258ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                    break;
4268ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                case ADD_GEOFENCE_CALLBACK:
4278ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                    geofenceId = msg.arg1;
4288ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                    callback = mGeofences.get(geofenceId);
4298ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                    if (callback == null) return;
4308ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh
4318ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                    try {
4328ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                        callback.onGeofenceAdd(geofenceId, msg.arg2);
4338ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                    } catch (RemoteException e) {Log.i(TAG, "Remote Exception:" + e);}
4348ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                    releaseWakeLock();
4358ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                    break;
4368ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                case REMOVE_GEOFENCE_CALLBACK:
4378ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                    geofenceId = msg.arg1;
4388ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                    callback = mGeofences.get(geofenceId);
4398ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                    if (callback == null) return;
4408ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh
4418ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                    try {
4428ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                        callback.onGeofenceRemove(geofenceId, msg.arg2);
4438ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                    } catch (RemoteException e) {}
4448ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                    mGeofences.remove(geofenceId);
4458ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                    releaseWakeLock();
4468ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                    break;
4478ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh
4488ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                case PAUSE_GEOFENCE_CALLBACK:
4498ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                    geofenceId = msg.arg1;
4508ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                    callback = mGeofences.get(geofenceId);
4518ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                    if (callback == null) return;
4528ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh
4538ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                    try {
4548ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                        callback.onGeofencePause(geofenceId, msg.arg2);
4558ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                    } catch (RemoteException e) {}
4568ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                    releaseWakeLock();
4578ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                    break;
4588ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh
4598ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                case RESUME_GEOFENCE_CALLBACK:
4608ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                    geofenceId = msg.arg1;
4618ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                    callback = mGeofences.get(geofenceId);
4628ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                    if (callback == null) return;
4638ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh
4648ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                    try {
4658ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                        callback.onGeofenceResume(geofenceId, msg.arg2);
4668ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                    } catch (RemoteException e) {}
4678ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                    releaseWakeLock();
4688ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                    break;
4698ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh
4708ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                case GEOFENCE_TRANSITION_CALLBACK:
4718ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                    GeofenceTransition geofenceTransition = (GeofenceTransition)(msg.obj);
4728ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                    callback = mGeofences.get(geofenceTransition.mGeofenceId);
4738ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh
4748ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                    if (DEBUG) Log.d(TAG, "GeofenceTransistionCallback: GPS : GeofenceId: " +
4758ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                            geofenceTransition.mGeofenceId +
4768ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                            "Transition: " + geofenceTransition.mTransition +
4778ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                            "Location: " + geofenceTransition.mLocation + ":" + mGeofences);
4788ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh
4798ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                    try {
4808ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                        callback.onGeofenceChange(
4818ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                                geofenceTransition.mGeofenceId, geofenceTransition.mTransition,
4828ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                                geofenceTransition.mLocation, geofenceTransition.mTimestamp,
4838ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                                GeofenceHardware.MONITORING_TYPE_GPS_HARDWARE);
4848ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                    } catch (RemoteException e) {}
4858ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                    releaseWakeLock();
4868ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                    break;
4878ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh            }
4888ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        }
4898ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    };
4908ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh
4918ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    // All operations on mCallbacks
4928ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    private Handler mCallbacksHandler = new Handler() {
4938ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        @Override
4948ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        public void handleMessage(Message msg) {
4958ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh            int monitoringType;
4968ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh            ArrayList<IGeofenceHardwareCallback> callbackList;
4978ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh            IGeofenceHardwareCallback callback;
4988ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh
4998ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh            switch (msg.what) {
5008ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                case GPS_GEOFENCE_STATUS:
5018ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                    Location location = (Location) msg.obj;
5028ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                    int val = msg.arg1;
5038ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                    boolean available;
5048ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                    available = (val == GeofenceHardware.MONITOR_CURRENTLY_AVAILABLE ?
5058ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                            true : false);
5068ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                    callbackList = mCallbacks[GeofenceHardware.MONITORING_TYPE_GPS_HARDWARE];
5078ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                    if (callbackList == null) return;
5088ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh
5098ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                    if (DEBUG) Log.d(TAG, "MonitoringSystemChangeCallback: GPS : " + available);
5108ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh
5118ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                    for (IGeofenceHardwareCallback c: callbackList) {
5128ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                        try {
5138ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                            c.onMonitoringSystemChange(
5148ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                                    GeofenceHardware.MONITORING_TYPE_GPS_HARDWARE, available,
5158ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                                    location);
5168ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                        } catch (RemoteException e) {}
5178ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                    }
5188ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                    releaseWakeLock();
5198ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                    break;
5208ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                case CALLBACK_ADD:
5218ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                    monitoringType = msg.arg1;
5228ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                    callback = (IGeofenceHardwareCallback) msg.obj;
5238ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                    callbackList = mCallbacks[monitoringType];
5248ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                    if (callbackList == null) {
5258ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                        callbackList = new ArrayList<IGeofenceHardwareCallback>();
5268ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                        mCallbacks[monitoringType] = callbackList;
5278ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                    }
5288ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                    if (!callbackList.contains(callback)) callbackList.add(callback);
5298ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                    break;
5308ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                case CALLBACK_REMOVE:
5318ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                    monitoringType = msg.arg1;
5328ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                    callback = (IGeofenceHardwareCallback) msg.obj;
5338ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                    callbackList = mCallbacks[monitoringType];
5348ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                    if (callbackList != null) {
5358ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                        callbackList.remove(callback);
5368ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                    }
5378ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                    break;
5388ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh            }
5398ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        }
5408ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    };
5418ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh
5428ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    private class GeofenceTransition {
5438ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        private int mGeofenceId, mTransition;
5448ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        private long mTimestamp;
5458ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        private Location mLocation;
5468ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh
5478ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        GeofenceTransition(int geofenceId, int transition, long timestamp, Location location) {
5488ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh            mGeofenceId = geofenceId;
5498ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh            mTransition = transition;
5508ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh            mTimestamp = timestamp;
5518ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh            mLocation = location;
5528ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        }
5538ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    }
5548ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh
5558ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    private void setMonitorAvailability(int monitor, int val) {
5568ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        synchronized (mSupportedMonitorTypes) {
5578ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh            mSupportedMonitorTypes[monitor] = val;
5588ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        }
5598ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    }
5608ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh
5618ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh
5628ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    int getMonitoringResolutionLevel(int monitoringType) {
5638ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        switch (monitoringType) {
5648ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh            case GeofenceHardware.MONITORING_TYPE_GPS_HARDWARE:
5658ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                return RESOLUTION_LEVEL_FINE;
5668ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        }
5678ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        return RESOLUTION_LEVEL_NONE;
5688ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    }
5698ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh
5708ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    int getAllowedResolutionLevel(int pid, int uid) {
5718ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        if (mContext.checkPermission(android.Manifest.permission.ACCESS_FINE_LOCATION,
5728ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                pid, uid) == PackageManager.PERMISSION_GRANTED) {
5738ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh            return RESOLUTION_LEVEL_FINE;
5748ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        } else if (mContext.checkPermission(android.Manifest.permission.ACCESS_COARSE_LOCATION,
5758ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                pid, uid) == PackageManager.PERMISSION_GRANTED) {
5768ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh            return RESOLUTION_LEVEL_COARSE;
5778ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        } else {
5788ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh            return RESOLUTION_LEVEL_NONE;
5798ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        }
5808ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    }
5818ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh
5828ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    private int getGeofenceStatus(int status) {
5838ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        switch (status) {
5848ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh            case GPS_GEOFENCE_OPERATION_SUCCESS:
5858ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                return GeofenceHardware.GEOFENCE_SUCCESS;
5868ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh            case GPS_GEOFENCE_ERROR_GENERIC:
5878ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                return GeofenceHardware.GEOFENCE_FAILURE;
5888ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh            case GPS_GEOFENCE_ERROR_ID_EXISTS:
5898ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                return GeofenceHardware.GEOFENCE_ERROR_ID_EXISTS;
5908ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh            case GPS_GEOFENCE_ERROR_INVALID_TRANSITION:
5918ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                return GeofenceHardware.GEOFENCE_ERROR_INVALID_TRANSITION;
5928ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh            case GPS_GEOFENCE_ERROR_TOO_MANY_GEOFENCES:
5938ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                return GeofenceHardware.GEOFENCE_ERROR_TOO_MANY_GEOFENCES;
5948ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh            case GPS_GEOFENCE_ERROR_ID_UNKNOWN:
5958ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                return GeofenceHardware.GEOFENCE_ERROR_ID_UNKNOWN;
5968ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        }
5978ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        return -1;
5988ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    }
5998ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh}
600