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 Ganeshpackage android.hardware.location;
178ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh
188ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganeshimport android.location.Location;
198ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganeshimport android.os.RemoteException;
208ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh
218ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganeshimport java.lang.ref.WeakReference;
228ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganeshimport java.util.HashMap;
238ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh
248ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh/**
258ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh * This class handles geofences managed by various hardware subsystems. It contains
268ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh * the public APIs that is needed to accomplish the task.
278ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh *
288ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh * <p>The APIs should not be called directly by the app developers. A higher level api
298ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh * which abstracts the hardware should be used instead. All the checks are done by the higher
308ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh * level public API. Any needed locking should be handled by the higher level API.
318ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh *
328ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh * <p> There are 3 states associated with a Geofence: Inside, Outside, Unknown.
338ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh * There are 3 transitions: {@link #GEOFENCE_ENTERED}, {@link #GEOFENCE_EXITED},
348ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh * {@link #GEOFENCE_UNCERTAIN}. The APIs only expose the transitions.
358ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh *
368ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh * <p> Inside state: The hardware subsystem is reasonably confident that the user is inside
378ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh * the geofence. Outside state: The hardware subsystem is reasonably confident that the user
388ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh * is outside the geofence Unknown state: Unknown state can be interpreted as a state in which the
398ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh * monitoring subsystem isn't confident enough that the user is either inside or
408ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh * outside the Geofence. If the accuracy does not improve for a sufficient period of time,
418ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh * the {@link #GEOFENCE_UNCERTAIN} transition would be triggered. If the accuracy improves later,
428ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh * an appropriate transition would be triggered. The "reasonably confident" parameter
438ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh * depends on the hardware system and the positioning algorithms used.
448ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh * For instance, {@link #MONITORING_TYPE_GPS_HARDWARE} uses 95% as a confidence level.
458ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh */
468ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganeshpublic final class GeofenceHardware {
478ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    private IGeofenceHardware mService;
488ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh
498ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    // Hardware systems that do geofence monitoring.
500682809ad08db284d7110aab44108d5e9c310e6bdestradaa    static final int NUM_MONITORS = 2;
518ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh
528ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    /**
538ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     * Constant for geofence monitoring done by the GPS hardware.
548ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     */
558ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    public static final int MONITORING_TYPE_GPS_HARDWARE = 0;
568ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh
578ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    /**
580682809ad08db284d7110aab44108d5e9c310e6bdestradaa     * Constant for geofence monitoring done by the Fused hardware.
590682809ad08db284d7110aab44108d5e9c310e6bdestradaa     *
600682809ad08db284d7110aab44108d5e9c310e6bdestradaa     * @hide
610682809ad08db284d7110aab44108d5e9c310e6bdestradaa     */
620682809ad08db284d7110aab44108d5e9c310e6bdestradaa    public static final int MONITORING_TYPE_FUSED_HARDWARE = 1;
630682809ad08db284d7110aab44108d5e9c310e6bdestradaa
640682809ad08db284d7110aab44108d5e9c310e6bdestradaa    /**
658ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     * Constant to indiciate that the monitoring system is currently
668ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     * available for monitoring geofences.
678ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     */
688ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    public static final int MONITOR_CURRENTLY_AVAILABLE = 0;
698ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh
708ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    /**
718ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     * Constant to indiciate that the monitoring system is currently
728ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     * unavailable for monitoring geofences.
738ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     */
748ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    public static final int MONITOR_CURRENTLY_UNAVAILABLE = 1;
758ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh
768ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    /**
778ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     * Constant to indiciate that the monitoring system is unsupported
788ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     * for hardware geofence monitoring.
798ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     */
808ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    public static final int MONITOR_UNSUPPORTED = 2;
818ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh
828ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    // The following constants need to match geofence flags in gps.h
838ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    /**
848ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     * The constant to indicate that the user has entered the geofence.
858ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     */
868ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    public static final int GEOFENCE_ENTERED = 1<<0L;
878ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh
888ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    /**
898ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     * The constant to indicate that the user has exited the geofence.
908ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     */
918ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    public static final int GEOFENCE_EXITED = 1<<1L;
928ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh
938ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    /**
948ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     * The constant to indicate that the user is uncertain with respect to a
958ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     * geofence.                                                  nn
968ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     */
978ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    public static final int GEOFENCE_UNCERTAIN = 1<<2L;
988ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh
998ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    /**
1008ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     * The constant used to indicate success of the particular geofence call
1018ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     */
1028ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    public static final int GEOFENCE_SUCCESS = 0;
1038ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh
1048ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    /**
1058ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     * The constant used to indicate that too many geofences have been registered.
1068ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     */
1078ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    public static final int GEOFENCE_ERROR_TOO_MANY_GEOFENCES = 1;
1088ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh
1098ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    /**
1108ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     * The constant used to indicate that the geofence id already exists.
1118ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     */
1128ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    public static final int GEOFENCE_ERROR_ID_EXISTS  = 2;
1138ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh
1148ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    /**
1158ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     * The constant used to indicate that the geofence id is unknown.
1168ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     */
1178ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    public static final int GEOFENCE_ERROR_ID_UNKNOWN = 3;
1188ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh
1198ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    /**
1208ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     * The constant used to indicate that the transition requested for the geofence is invalid.
1218ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     */
1228ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    public static final int GEOFENCE_ERROR_INVALID_TRANSITION = 4;
1238ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh
1248ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    /**
1258ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     * The constant used to indicate that the geofence operation has failed.
1268ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     */
1278ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    public static final int GEOFENCE_FAILURE = 5;
1288ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh
1290682809ad08db284d7110aab44108d5e9c310e6bdestradaa    /**
1300682809ad08db284d7110aab44108d5e9c310e6bdestradaa     * The constant used to indicate that the operation failed due to insufficient memory.
1310682809ad08db284d7110aab44108d5e9c310e6bdestradaa     *
1320682809ad08db284d7110aab44108d5e9c310e6bdestradaa     * @hide
1330682809ad08db284d7110aab44108d5e9c310e6bdestradaa     */
1340682809ad08db284d7110aab44108d5e9c310e6bdestradaa    public static final int GEOFENCE_ERROR_INSUFFICIENT_MEMORY = 6;
1358ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh
1368ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    private HashMap<GeofenceHardwareCallback, GeofenceHardwareCallbackWrapper>
1378ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh            mCallbacks = new HashMap<GeofenceHardwareCallback, GeofenceHardwareCallbackWrapper>();
138da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh    private HashMap<GeofenceHardwareMonitorCallback, GeofenceHardwareMonitorCallbackWrapper>
139da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh            mMonitorCallbacks = new HashMap<GeofenceHardwareMonitorCallback,
140da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh                    GeofenceHardwareMonitorCallbackWrapper>();
1418ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    /**
1428ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     * @hide
1438ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     */
1448ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    public GeofenceHardware(IGeofenceHardware service) {
1458ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        mService = service;
1468ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    }
1478ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh
1488ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    /**
149da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh     * Returns all the hardware geofence monitoring systems which are supported
150da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh     *
151da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh     * <p> Call {@link #getStatusOfMonitoringType(int)} to know the current state
152da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh     * of a monitoring system.
153da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh     *
154da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh     * <p> Requires {@link android.Manifest.permission#LOCATION_HARDWARE} permission to access
155da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh     * geofencing in hardware.
156da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh     *
157da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh     * @return An array of all the monitoring types.
158da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh     *         An array of length 0 is returned in case of errors.
159da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh     */
160da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh    public int[] getMonitoringTypes() {
161da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh        try {
162da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh            return mService.getMonitoringTypes();
163da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh        } catch (RemoteException e) {
164da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh        }
165da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh        return new int[0];
166da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh    }
167da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh
168da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh    /**
169da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh     * Returns current status of a hardware geofence monitoring system.
170da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh     *
171da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh     * <p>Status can be one of {@link #MONITOR_CURRENTLY_AVAILABLE},
1728ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     * {@link #MONITOR_CURRENTLY_UNAVAILABLE} or {@link #MONITOR_UNSUPPORTED}
1738ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     *
1748ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     * <p> Some supported hardware monitoring systems might not be available
1758ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     * for monitoring geofences in certain scenarios. For example, when a user
1768ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     * enters a building, the GPS hardware subsystem might not be able monitor
1778ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     * geofences and will change from {@link #MONITOR_CURRENTLY_AVAILABLE} to
1788ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     * {@link #MONITOR_CURRENTLY_UNAVAILABLE}.
1798ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     *
180da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh     * @param monitoringType
181da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh     * @return Current status of the monitoring type.
1828ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     */
183da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh    public int getStatusOfMonitoringType(int monitoringType) {
1848ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        try {
185da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh            return mService.getStatusOfMonitoringType(monitoringType);
1868ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        } catch (RemoteException e) {
187da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh            return MONITOR_UNSUPPORTED;
1888ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        }
1898ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    }
1908ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh
1918ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    /**
1928ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     * Creates a circular geofence which is monitored by subsystems in the hardware.
1938ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     *
1948ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     * <p> When the device detects that is has entered, exited or is uncertain
1958ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     * about the area specified by the geofence, the given callback will be called.
1968ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     *
197da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh     * <p> If this call returns true, it means that the geofence has been sent to the hardware.
198da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh     * {@link GeofenceHardwareCallback#onGeofenceAdd} will be called with the result of the
199da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh     * add call from the hardware. The {@link GeofenceHardwareCallback#onGeofenceAdd} will be
200da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh     * called with the following parameters when a transition event occurs.
2018ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     * <ul>
2028ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     * <li> The geofence Id
2038ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     * <li> The location object indicating the last known location.
2048ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     * <li> The transition associated with the geofence. One of
2058ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     *      {@link #GEOFENCE_ENTERED}, {@link #GEOFENCE_EXITED}, {@link #GEOFENCE_UNCERTAIN}
2068ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     * <li> The timestamp when the geofence transition occured.
2078ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     * <li> The monitoring type ({@link #MONITORING_TYPE_GPS_HARDWARE} is one such example)
2088ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     *      that was used.
2098ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     * </ul>
2108ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     *
2118ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     * <p> The geofence will be monitored by the subsystem specified by monitoring_type parameter.
2128ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     * The application does not need to hold a wakelock when the monitoring
2138ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     * is being done by the underlying hardware subsystem. If the same geofence Id is being
2148ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     * monitored by two different monitoring systems, the same id can be used for both calls, as
2158ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     * long as the same callback object is used.
2168ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     *
2178ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     * <p> Requires {@link android.Manifest.permission#ACCESS_FINE_LOCATION} permission when
2188ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     * {@link #MONITORING_TYPE_GPS_HARDWARE} is used.
2198ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     *
2208ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     * <p> Requires {@link android.Manifest.permission#LOCATION_HARDWARE} permission to access
2218ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     * geofencing in hardware.
2228ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     *
2238ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     * <p>This API should not be called directly by the app developers. A higher level api
2248ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     * which abstracts the hardware should be used instead. All the checks are done by the higher
2258ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     * level public API. Any needed locking should be handled by the higher level API.
2268ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     *
227da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh     * <p> Create a geofence request object using the methods in {@link GeofenceHardwareRequest} to
228da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh     * set all the characteristics of the geofence. Use the created GeofenceHardwareRequest object
229da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh     * in this call.
230da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh     *
231da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh     * @param geofenceId The id associated with the geofence.
2328ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     * @param monitoringType The type of the hardware subsystem that should be used
2338ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     *        to monitor the geofence.
234da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh     * @param geofenceRequest The {@link GeofenceHardwareRequest} object associated with the
235da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh     *        geofence.
2368ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     * @param callback {@link GeofenceHardwareCallback} that will be use to notify the
2378ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     *        transition.
238da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh     * @return true when the geofence is successfully sent to the hardware for addition.
239da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh     * @throws IllegalArgumentException when the geofence request type is not supported.
2408ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     */
241da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh    public boolean addGeofence(int geofenceId, int monitoringType, GeofenceHardwareRequest
242da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh            geofenceRequest, GeofenceHardwareCallback callback) {
2438ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        try {
244da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh            if (geofenceRequest.getType() == GeofenceHardwareRequest.GEOFENCE_TYPE_CIRCLE) {
245da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh                return mService.addCircularFence(geofenceId, monitoringType,
246da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh                        geofenceRequest.getLatitude(),
247da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh                        geofenceRequest.getLongitude(), geofenceRequest.getRadius(),
248da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh                        geofenceRequest.getLastTransition(),
249da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh                        geofenceRequest.getMonitorTransitions(),
250da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh                        geofenceRequest.getNotificationResponsiveness(),
251da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh                        geofenceRequest.getUnknownTimer(),
252da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh                        getCallbackWrapper(callback));
253da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh            } else {
254da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh                throw new IllegalArgumentException("Geofence Request type not supported");
255da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh            }
2568ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        } catch (RemoteException e) {
2578ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        }
2588ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        return false;
2598ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    }
2608ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh
2618ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    /**
262da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh     * Removes a geofence added by {@link #addGeofence} call.
263da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh     *
264da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh     * <p> If this call returns true, it means that the geofence has been sent to the hardware.
265da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh     * {@link GeofenceHardwareCallback#onGeofenceRemove} will be called with the result of the
266da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh     * remove call from the hardware.
2678ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     *
2688ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     * <p> Requires {@link android.Manifest.permission#ACCESS_FINE_LOCATION} permission when
2698ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     * {@link #MONITORING_TYPE_GPS_HARDWARE} is used.
2708ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     *
2718ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     * <p> Requires {@link android.Manifest.permission#LOCATION_HARDWARE} permission to access
2728ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     * geofencing in hardware.
2738ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     *
2748ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     * <p>This API should not be called directly by the app developers. A higher level api
2758ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     * which abstracts the hardware should be used instead. All the checks are done by the higher
2768ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     * level public API. Any needed locking should be handled by the higher level API.
2778ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     *
2788ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     * @param geofenceId The id of the geofence.
2798ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     * @param monitoringType The type of the hardware subsystem that should be used
2808ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     *        to monitor the geofence.
281da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh     * @return true when the geofence is successfully sent to the hardware for removal.                     .
2828ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     */
2838ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh   public boolean removeGeofence(int geofenceId, int monitoringType) {
2848ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh       try {
2858ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh           return mService.removeGeofence(geofenceId, monitoringType);
2868ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh       } catch (RemoteException e) {
2878ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh       }
2888ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh       return false;
2898ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh   }
2908ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh
2918ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    /**
292da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh     * Pauses the monitoring of a geofence added by {@link #addGeofence} call.
293da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh     *
294da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh     * <p> If this call returns true, it means that the geofence has been sent to the hardware.
295da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh     * {@link GeofenceHardwareCallback#onGeofencePause} will be called with the result of the
296da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh     * pause call from the hardware.
2978ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     *
2988ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     * <p> Requires {@link android.Manifest.permission#ACCESS_FINE_LOCATION} permission when
2998ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     * {@link #MONITORING_TYPE_GPS_HARDWARE} is used.
3008ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     *
3018ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     * <p> Requires {@link android.Manifest.permission#LOCATION_HARDWARE} permission to access
3028ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     * geofencing in hardware.
3038ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     *
3048ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     * <p>This API should not be called directly by the app developers. A higher level api
3058ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     * which abstracts the hardware should be used instead. All the checks are done by the higher
3068ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     * level public API. Any needed locking should be handled by the higher level API.
3078ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     *
3088ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     * @param geofenceId The id of the geofence.
3098ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     * @param monitoringType The type of the hardware subsystem that should be used
3108ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     *        to monitor the geofence.
311da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh     * @return true when the geofence is successfully sent to the hardware for pausing.
3128ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     */
3138ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    public boolean pauseGeofence(int geofenceId, int monitoringType) {
3148ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        try {
3158ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh            return mService.pauseGeofence(geofenceId, monitoringType);
3168ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        } catch (RemoteException e) {
3178ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        }
3188ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        return false;
3198ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    }
3208ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh
3218ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    /**
3228ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     * Resumes the monitoring of a geofence added by {@link #pauseGeofence} call.
3238ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     *
324da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh     * <p> If this call returns true, it means that the geofence has been sent to the hardware.
325da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh     * {@link GeofenceHardwareCallback#onGeofenceResume} will be called with the result of the
326da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh     * resume call from the hardware.
327da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh     *
3288ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     * <p> Requires {@link android.Manifest.permission#ACCESS_FINE_LOCATION} permission when
3298ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     * {@link #MONITORING_TYPE_GPS_HARDWARE} is used.
3308ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     *
3318ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     * <p> Requires {@link android.Manifest.permission#LOCATION_HARDWARE} permission to access
3328ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     * geofencing in hardware.
3338ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     *
3348ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     * <p>This API should not be called directly by the app developers. A higher level api
3358ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     * which abstracts the hardware should be used instead. All the checks are done by the higher
3368ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     * level public API. Any needed locking should be handled by the higher level API.
3378ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     *
3388ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     * @param geofenceId The id of the geofence.
3398ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     * @param monitoringType The type of the hardware subsystem that should be used
3408ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     *        to monitor the geofence.
341da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh     * @param monitorTransition Bitwise OR of {@link #GEOFENCE_ENTERED},
342da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh     *        {@link #GEOFENCE_EXITED}, {@link #GEOFENCE_UNCERTAIN}
343da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh     * @return true when the geofence is successfully sent to the hardware for resumption.
3448ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     */
345da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh    public boolean resumeGeofence(int geofenceId, int monitoringType, int monitorTransition) {
3468ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        try {
347da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh            return mService.resumeGeofence(geofenceId, monitoringType, monitorTransition);
3488ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        } catch (RemoteException e) {
3498ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        }
3508ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        return false;
3518ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    }
3528ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh
3538ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    /**
3548ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     * Register the callback to be notified when the state of a hardware geofence
3558ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     * monitoring system changes. For instance, it can change from
3568ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     * {@link #MONITOR_CURRENTLY_AVAILABLE} to {@link #MONITOR_CURRENTLY_UNAVAILABLE}
3578ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     *
3588ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     * <p> Requires {@link android.Manifest.permission#ACCESS_FINE_LOCATION} permission when
3598ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     * {@link #MONITORING_TYPE_GPS_HARDWARE} is used.
3608ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     *
3618ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     * <p> Requires {@link android.Manifest.permission#LOCATION_HARDWARE} permission to access
3628ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     * geofencing in hardware.
3638ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     *
3648ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     * <p>This API should not be called directly by the app developers. A higher level api
3658ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     * which abstracts the hardware should be used instead. All the checks are done by the higher
3668ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     * level public API. Any needed locking should be handled by the higher level API.
3678ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     *
3688ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     * <p> The same callback object can be used to be informed of geofence transitions
3698ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     * and state changes of the underlying hardware subsystem.
3708ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     *
3718ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     * @param monitoringType Type of the monitor
3728ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     * @param callback Callback that will be called.
3738ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     * @return true on success
3748ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     */
3758ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    public boolean registerForMonitorStateChangeCallback(int monitoringType,
376da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh            GeofenceHardwareMonitorCallback callback) {
3778ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        try {
3788ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh            return mService.registerForMonitorStateChangeCallback(monitoringType,
379da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh                    getMonitorCallbackWrapper(callback));
3808ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        } catch (RemoteException e) {
3818ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        }
3828ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        return false;
3838ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    }
3848ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh
3858ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    /**
3868ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     * Unregister the callback that was used with {@link #registerForMonitorStateChangeCallback}
3878ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     * to notify when the state of the hardware geofence monitoring system changes.
3888ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     *
3898ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     * <p> Requires {@link android.Manifest.permission#ACCESS_FINE_LOCATION} permission when
3908ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     * {@link #MONITORING_TYPE_GPS_HARDWARE} is used.
3918ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     *
3928ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     * <p> Requires {@link android.Manifest.permission#LOCATION_HARDWARE} permission to access
3938ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     * geofencing in hardware.
3948ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     *
3958ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     * <p>This API should not be called directly by the app developers. A higher level api
3968ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     * which abstracts the hardware should be used instead. All the checks are done by the higher
3978ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     * level public API. Any needed locking should be handled by the higher level API.
3988ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     *
3998ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     * @param monitoringType Type of the monitor
4008ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     * @param callback Callback that will be called.
4018ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     * @return true on success
4028ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh     */
4038ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    public boolean unregisterForMonitorStateChangeCallback(int monitoringType,
404da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh            GeofenceHardwareMonitorCallback callback) {
4058ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        boolean  result = false;
4068ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        try {
4078ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh            result = mService.unregisterForMonitorStateChangeCallback(monitoringType,
408da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh                    getMonitorCallbackWrapper(callback));
409da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh            if (result) removeMonitorCallback(callback);
4108ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh
4118ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        } catch (RemoteException e) {
4128ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        }
4138ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        return result;
4148ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    }
4158ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh
4168ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh
4178ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    private void removeCallback(GeofenceHardwareCallback callback) {
4188ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        synchronized (mCallbacks) {
4198ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh            mCallbacks.remove(callback);
4208ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        }
4218ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    }
4228ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh
4238ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    private GeofenceHardwareCallbackWrapper getCallbackWrapper(GeofenceHardwareCallback callback) {
4248ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        synchronized (mCallbacks) {
4258ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh            GeofenceHardwareCallbackWrapper wrapper = mCallbacks.get(callback);
4268ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh            if (wrapper == null) {
4278ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                wrapper = new GeofenceHardwareCallbackWrapper(callback);
4288ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                mCallbacks.put(callback, wrapper);
4298ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh            }
4308ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh            return wrapper;
4318ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        }
4328ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    }
4338ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh
434da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh    private void removeMonitorCallback(GeofenceHardwareMonitorCallback callback) {
435da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh        synchronized (mMonitorCallbacks) {
436da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh            mMonitorCallbacks.remove(callback);
437da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh        }
438da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh    }
4398ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh
440da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh    private GeofenceHardwareMonitorCallbackWrapper getMonitorCallbackWrapper(
441da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh            GeofenceHardwareMonitorCallback callback) {
442da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh        synchronized (mMonitorCallbacks) {
443da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh            GeofenceHardwareMonitorCallbackWrapper wrapper = mMonitorCallbacks.get(callback);
444da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh            if (wrapper == null) {
445da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh                wrapper = new GeofenceHardwareMonitorCallbackWrapper(callback);
446da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh                mMonitorCallbacks.put(callback, wrapper);
447da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh            }
448da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh            return wrapper;
449da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh        }
450da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh    }
451da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh
452da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh    class GeofenceHardwareMonitorCallbackWrapper extends IGeofenceHardwareMonitorCallback.Stub {
453da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh        private WeakReference<GeofenceHardwareMonitorCallback> mCallback;
454da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh
455da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh        GeofenceHardwareMonitorCallbackWrapper(GeofenceHardwareMonitorCallback c) {
456da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh            mCallback = new WeakReference<GeofenceHardwareMonitorCallback>(c);
4578ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        }
4588ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh
4598ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        public void onMonitoringSystemChange(int monitoringType, boolean available,
4608ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                Location location) {
461da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh            GeofenceHardwareMonitorCallback c = mCallback.get();
4628ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh            if (c != null) c.onMonitoringSystemChange(monitoringType, available, location);
4638ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        }
464da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh    }
465da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh
466da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh    class GeofenceHardwareCallbackWrapper extends IGeofenceHardwareCallback.Stub {
467da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh        private WeakReference<GeofenceHardwareCallback> mCallback;
4688ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh
469da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh        GeofenceHardwareCallbackWrapper(GeofenceHardwareCallback c) {
470da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh            mCallback = new WeakReference<GeofenceHardwareCallback>(c);
471da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh        }
472da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh
473da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh        public void onGeofenceTransition(int geofenceId, int transition, Location location,
4748ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                long timestamp, int monitoringType) {
4758ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh            GeofenceHardwareCallback c = mCallback.get();
4768ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh            if (c != null) {
477da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh                c.onGeofenceTransition(geofenceId, transition, location, timestamp,
4788ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                        monitoringType);
4798ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh            }
4808ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        }
4818ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh
4828ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        public void onGeofenceAdd(int geofenceId, int status) {
4838ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh            GeofenceHardwareCallback c = mCallback.get();
4848ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh            if (c != null) c.onGeofenceAdd(geofenceId, status);
4858ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        }
4868ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh
4878ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        public void onGeofenceRemove(int geofenceId, int status) {
4888ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh            GeofenceHardwareCallback c = mCallback.get();
4898ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh            if (c != null) {
4908ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                c.onGeofenceRemove(geofenceId, status);
4918ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh                removeCallback(c);
4928ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh            }
4938ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        }
4948ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh
4958ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        public void onGeofencePause(int geofenceId, int status) {
4968ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh            GeofenceHardwareCallback c = mCallback.get();
497da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh            if (c != null) {
498da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh                c.onGeofencePause(geofenceId, status);
499da6508954a492f3dd4397e70e4fa08ee54bd2741Jaikumar Ganesh            }
5008ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        }
5018ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh
5028ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        public void onGeofenceResume(int geofenceId, int status) {
5038ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh            GeofenceHardwareCallback c = mCallback.get();
5048ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh            if (c != null) c.onGeofenceResume(geofenceId, status);
5058ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh        }
5068ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh    }
5078ce470dd4ba0608abb6b5eae117cefca927af96bJaikumar Ganesh}
508