11af4b0280af406cfc7eb46810f6b76e57b983e11destradaa/* 21af4b0280af406cfc7eb46810f6b76e57b983e11destradaa * Copyright (C) 2013 The Android Open Source Project 31af4b0280af406cfc7eb46810f6b76e57b983e11destradaa * 41af4b0280af406cfc7eb46810f6b76e57b983e11destradaa * Licensed under the Apache License, Version 2.0 (the "License"); 51af4b0280af406cfc7eb46810f6b76e57b983e11destradaa * you may not use this file except in compliance with the License. 61af4b0280af406cfc7eb46810f6b76e57b983e11destradaa * You may obtain a copy of the License at 71af4b0280af406cfc7eb46810f6b76e57b983e11destradaa * 81af4b0280af406cfc7eb46810f6b76e57b983e11destradaa * http://www.apache.org/licenses/LICENSE-2.0 91af4b0280af406cfc7eb46810f6b76e57b983e11destradaa * 101af4b0280af406cfc7eb46810f6b76e57b983e11destradaa * Unless required by applicable law or agreed to in writing, software 111af4b0280af406cfc7eb46810f6b76e57b983e11destradaa * distributed under the License is distributed on an "AS IS" BASIS, 121af4b0280af406cfc7eb46810f6b76e57b983e11destradaa * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 131af4b0280af406cfc7eb46810f6b76e57b983e11destradaa * See the License for the specific language governing permissions and 141af4b0280af406cfc7eb46810f6b76e57b983e11destradaa * limitations under the License. 151af4b0280af406cfc7eb46810f6b76e57b983e11destradaa */ 161af4b0280af406cfc7eb46810f6b76e57b983e11destradaa 171af4b0280af406cfc7eb46810f6b76e57b983e11destradaapackage com.android.server.location; 181af4b0280af406cfc7eb46810f6b76e57b983e11destradaa 190682809ad08db284d7110aab44108d5e9c310e6bdestradaaimport android.hardware.location.GeofenceHardware; 201af4b0280af406cfc7eb46810f6b76e57b983e11destradaaimport android.hardware.location.GeofenceHardwareImpl; 210682809ad08db284d7110aab44108d5e9c310e6bdestradaaimport android.hardware.location.GeofenceHardwareRequestParcelable; 221af4b0280af406cfc7eb46810f6b76e57b983e11destradaaimport android.hardware.location.IFusedLocationHardware; 231af4b0280af406cfc7eb46810f6b76e57b983e11destradaaimport android.hardware.location.IFusedLocationHardwareSink; 241af4b0280af406cfc7eb46810f6b76e57b983e11destradaaimport android.location.IFusedGeofenceHardware; 251af4b0280af406cfc7eb46810f6b76e57b983e11destradaaimport android.location.FusedBatchOptions; 261af4b0280af406cfc7eb46810f6b76e57b983e11destradaaimport android.location.Location; 271af4b0280af406cfc7eb46810f6b76e57b983e11destradaaimport android.location.LocationListener; 281af4b0280af406cfc7eb46810f6b76e57b983e11destradaaimport android.location.LocationManager; 299e9ce925418a0075234b3cc34261c6be32095412David Christieimport android.location.LocationRequest; 301af4b0280af406cfc7eb46810f6b76e57b983e11destradaa 311af4b0280af406cfc7eb46810f6b76e57b983e11destradaaimport android.content.Context; 321af4b0280af406cfc7eb46810f6b76e57b983e11destradaaimport android.os.Bundle; 3364be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaaimport android.os.Looper; 341af4b0280af406cfc7eb46810f6b76e57b983e11destradaaimport android.os.RemoteException; 351af4b0280af406cfc7eb46810f6b76e57b983e11destradaaimport android.os.SystemClock; 361af4b0280af406cfc7eb46810f6b76e57b983e11destradaaimport android.util.Log; 371af4b0280af406cfc7eb46810f6b76e57b983e11destradaa 381af4b0280af406cfc7eb46810f6b76e57b983e11destradaa/** 391af4b0280af406cfc7eb46810f6b76e57b983e11destradaa * This class is an interop layer for JVM types and the JNI code that interacts 401af4b0280af406cfc7eb46810f6b76e57b983e11destradaa * with the FLP HAL implementation. 411af4b0280af406cfc7eb46810f6b76e57b983e11destradaa * 421af4b0280af406cfc7eb46810f6b76e57b983e11destradaa * {@hide} 431af4b0280af406cfc7eb46810f6b76e57b983e11destradaa */ 441af4b0280af406cfc7eb46810f6b76e57b983e11destradaapublic class FlpHardwareProvider { 451af4b0280af406cfc7eb46810f6b76e57b983e11destradaa private GeofenceHardwareImpl mGeofenceHardwareSink = null; 461af4b0280af406cfc7eb46810f6b76e57b983e11destradaa private IFusedLocationHardwareSink mLocationSink = null; 471af4b0280af406cfc7eb46810f6b76e57b983e11destradaa 481af4b0280af406cfc7eb46810f6b76e57b983e11destradaa private static FlpHardwareProvider sSingletonInstance = null; 491af4b0280af406cfc7eb46810f6b76e57b983e11destradaa 501af4b0280af406cfc7eb46810f6b76e57b983e11destradaa private final static String TAG = "FlpHardwareProvider"; 511af4b0280af406cfc7eb46810f6b76e57b983e11destradaa private final Context mContext; 5264be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa private final Object mLocationSinkLock = new Object(); 531af4b0280af406cfc7eb46810f6b76e57b983e11destradaa 540682809ad08db284d7110aab44108d5e9c310e6bdestradaa // FlpHal result codes, they must be equal to the ones in fused_location.h 550682809ad08db284d7110aab44108d5e9c310e6bdestradaa private static final int FLP_RESULT_SUCCESS = 0; 560682809ad08db284d7110aab44108d5e9c310e6bdestradaa private static final int FLP_RESULT_ERROR = -1; 570682809ad08db284d7110aab44108d5e9c310e6bdestradaa private static final int FLP_RESULT_INSUFFICIENT_MEMORY = -2; 580682809ad08db284d7110aab44108d5e9c310e6bdestradaa private static final int FLP_RESULT_TOO_MANY_GEOFENCES = -3; 590682809ad08db284d7110aab44108d5e9c310e6bdestradaa private static final int FLP_RESULT_ID_EXISTS = -4; 600682809ad08db284d7110aab44108d5e9c310e6bdestradaa private static final int FLP_RESULT_ID_UNKNOWN = -5; 610682809ad08db284d7110aab44108d5e9c310e6bdestradaa private static final int FLP_RESULT_INVALID_GEOFENCE_TRANSITION = -6; 620682809ad08db284d7110aab44108d5e9c310e6bdestradaa 631af4b0280af406cfc7eb46810f6b76e57b983e11destradaa public static FlpHardwareProvider getInstance(Context context) { 641af4b0280af406cfc7eb46810f6b76e57b983e11destradaa if (sSingletonInstance == null) { 651af4b0280af406cfc7eb46810f6b76e57b983e11destradaa sSingletonInstance = new FlpHardwareProvider(context); 661af4b0280af406cfc7eb46810f6b76e57b983e11destradaa } 671af4b0280af406cfc7eb46810f6b76e57b983e11destradaa 681af4b0280af406cfc7eb46810f6b76e57b983e11destradaa return sSingletonInstance; 691af4b0280af406cfc7eb46810f6b76e57b983e11destradaa } 701af4b0280af406cfc7eb46810f6b76e57b983e11destradaa 711af4b0280af406cfc7eb46810f6b76e57b983e11destradaa private FlpHardwareProvider(Context context) { 721af4b0280af406cfc7eb46810f6b76e57b983e11destradaa mContext = context; 731af4b0280af406cfc7eb46810f6b76e57b983e11destradaa 741af4b0280af406cfc7eb46810f6b76e57b983e11destradaa // register for listening for passive provider data 751af4b0280af406cfc7eb46810f6b76e57b983e11destradaa LocationManager manager = (LocationManager) mContext.getSystemService( 761af4b0280af406cfc7eb46810f6b76e57b983e11destradaa Context.LOCATION_SERVICE); 779e9ce925418a0075234b3cc34261c6be32095412David Christie final long minTime = 0; 789e9ce925418a0075234b3cc34261c6be32095412David Christie final float minDistance = 0; 799e9ce925418a0075234b3cc34261c6be32095412David Christie final boolean oneShot = false; 809e9ce925418a0075234b3cc34261c6be32095412David Christie LocationRequest request = LocationRequest.createFromDeprecatedProvider( 811af4b0280af406cfc7eb46810f6b76e57b983e11destradaa LocationManager.PASSIVE_PROVIDER, 829e9ce925418a0075234b3cc34261c6be32095412David Christie minTime, 839e9ce925418a0075234b3cc34261c6be32095412David Christie minDistance, 849e9ce925418a0075234b3cc34261c6be32095412David Christie oneShot); 859e9ce925418a0075234b3cc34261c6be32095412David Christie // Don't keep track of this request since it's done on behalf of other clients 869e9ce925418a0075234b3cc34261c6be32095412David Christie // (which are kept track of separately). 879e9ce925418a0075234b3cc34261c6be32095412David Christie request.setHideFromAppOps(true); 889e9ce925418a0075234b3cc34261c6be32095412David Christie manager.requestLocationUpdates( 899e9ce925418a0075234b3cc34261c6be32095412David Christie request, 901af4b0280af406cfc7eb46810f6b76e57b983e11destradaa new NetworkLocationListener(), 9164be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa Looper.myLooper()); 921af4b0280af406cfc7eb46810f6b76e57b983e11destradaa } 931af4b0280af406cfc7eb46810f6b76e57b983e11destradaa 941af4b0280af406cfc7eb46810f6b76e57b983e11destradaa public static boolean isSupported() { 951af4b0280af406cfc7eb46810f6b76e57b983e11destradaa return nativeIsSupported(); 961af4b0280af406cfc7eb46810f6b76e57b983e11destradaa } 971af4b0280af406cfc7eb46810f6b76e57b983e11destradaa 981af4b0280af406cfc7eb46810f6b76e57b983e11destradaa /** 991af4b0280af406cfc7eb46810f6b76e57b983e11destradaa * Private callback functions used by FLP HAL. 1001af4b0280af406cfc7eb46810f6b76e57b983e11destradaa */ 1011af4b0280af406cfc7eb46810f6b76e57b983e11destradaa // FlpCallbacks members 1021af4b0280af406cfc7eb46810f6b76e57b983e11destradaa private void onLocationReport(Location[] locations) { 1031af4b0280af406cfc7eb46810f6b76e57b983e11destradaa for (Location location : locations) { 1041af4b0280af406cfc7eb46810f6b76e57b983e11destradaa location.setProvider(LocationManager.FUSED_PROVIDER); 1051af4b0280af406cfc7eb46810f6b76e57b983e11destradaa // set the elapsed time-stamp just as GPS provider does 1061af4b0280af406cfc7eb46810f6b76e57b983e11destradaa location.setElapsedRealtimeNanos(SystemClock.elapsedRealtimeNanos()); 1071af4b0280af406cfc7eb46810f6b76e57b983e11destradaa } 1081af4b0280af406cfc7eb46810f6b76e57b983e11destradaa 10964be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa IFusedLocationHardwareSink sink; 11064be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa synchronized (mLocationSinkLock) { 11164be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa sink = mLocationSink; 11264be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa } 1131af4b0280af406cfc7eb46810f6b76e57b983e11destradaa try { 11464be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa if (sink != null) { 11564be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa sink.onLocationAvailable(locations); 1161af4b0280af406cfc7eb46810f6b76e57b983e11destradaa } 1171af4b0280af406cfc7eb46810f6b76e57b983e11destradaa } catch (RemoteException e) { 1181af4b0280af406cfc7eb46810f6b76e57b983e11destradaa Log.e(TAG, "RemoteException calling onLocationAvailable"); 1191af4b0280af406cfc7eb46810f6b76e57b983e11destradaa } 1201af4b0280af406cfc7eb46810f6b76e57b983e11destradaa } 1211af4b0280af406cfc7eb46810f6b76e57b983e11destradaa 1221af4b0280af406cfc7eb46810f6b76e57b983e11destradaa // FlpDiagnosticCallbacks members 1231af4b0280af406cfc7eb46810f6b76e57b983e11destradaa private void onDataReport(String data) { 12464be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa IFusedLocationHardwareSink sink; 12564be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa synchronized (mLocationSinkLock) { 12664be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa sink = mLocationSink; 12764be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa } 1281af4b0280af406cfc7eb46810f6b76e57b983e11destradaa try { 1291af4b0280af406cfc7eb46810f6b76e57b983e11destradaa if (mLocationSink != null) { 13064be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa sink.onDiagnosticDataAvailable(data); 1311af4b0280af406cfc7eb46810f6b76e57b983e11destradaa } 1321af4b0280af406cfc7eb46810f6b76e57b983e11destradaa } catch (RemoteException e) { 1331af4b0280af406cfc7eb46810f6b76e57b983e11destradaa Log.e(TAG, "RemoteException calling onDiagnosticDataAvailable"); 1341af4b0280af406cfc7eb46810f6b76e57b983e11destradaa } 1351af4b0280af406cfc7eb46810f6b76e57b983e11destradaa } 1361af4b0280af406cfc7eb46810f6b76e57b983e11destradaa 1371af4b0280af406cfc7eb46810f6b76e57b983e11destradaa // FlpGeofenceCallbacks members 1381af4b0280af406cfc7eb46810f6b76e57b983e11destradaa private void onGeofenceTransition( 1391af4b0280af406cfc7eb46810f6b76e57b983e11destradaa int geofenceId, 1401af4b0280af406cfc7eb46810f6b76e57b983e11destradaa Location location, 1411af4b0280af406cfc7eb46810f6b76e57b983e11destradaa int transition, 1421af4b0280af406cfc7eb46810f6b76e57b983e11destradaa long timestamp, 1430682809ad08db284d7110aab44108d5e9c310e6bdestradaa int sourcesUsed) { 1440682809ad08db284d7110aab44108d5e9c310e6bdestradaa getGeofenceHardwareSink().reportGeofenceTransition( 1450682809ad08db284d7110aab44108d5e9c310e6bdestradaa geofenceId, 1460682809ad08db284d7110aab44108d5e9c310e6bdestradaa updateLocationInformation(location), 1470682809ad08db284d7110aab44108d5e9c310e6bdestradaa transition, 1480682809ad08db284d7110aab44108d5e9c310e6bdestradaa timestamp, 1490682809ad08db284d7110aab44108d5e9c310e6bdestradaa GeofenceHardware.MONITORING_TYPE_FUSED_HARDWARE, 1500682809ad08db284d7110aab44108d5e9c310e6bdestradaa sourcesUsed); 1511af4b0280af406cfc7eb46810f6b76e57b983e11destradaa } 1521af4b0280af406cfc7eb46810f6b76e57b983e11destradaa 1531af4b0280af406cfc7eb46810f6b76e57b983e11destradaa private void onGeofenceMonitorStatus(int status, int source, Location location) { 154839904eed81bf9cd87c27de49903dddb64ae3937destradaa // allow the location to be optional in this event 155839904eed81bf9cd87c27de49903dddb64ae3937destradaa Location updatedLocation = null; 156839904eed81bf9cd87c27de49903dddb64ae3937destradaa if(location != null) { 157839904eed81bf9cd87c27de49903dddb64ae3937destradaa updatedLocation = updateLocationInformation(location); 158839904eed81bf9cd87c27de49903dddb64ae3937destradaa } 159839904eed81bf9cd87c27de49903dddb64ae3937destradaa 1600682809ad08db284d7110aab44108d5e9c310e6bdestradaa getGeofenceHardwareSink().reportGeofenceMonitorStatus( 1610682809ad08db284d7110aab44108d5e9c310e6bdestradaa GeofenceHardware.MONITORING_TYPE_FUSED_HARDWARE, 1620682809ad08db284d7110aab44108d5e9c310e6bdestradaa status, 163839904eed81bf9cd87c27de49903dddb64ae3937destradaa updatedLocation, 1640682809ad08db284d7110aab44108d5e9c310e6bdestradaa source); 1651af4b0280af406cfc7eb46810f6b76e57b983e11destradaa } 1661af4b0280af406cfc7eb46810f6b76e57b983e11destradaa 1671af4b0280af406cfc7eb46810f6b76e57b983e11destradaa private void onGeofenceAdd(int geofenceId, int result) { 1680682809ad08db284d7110aab44108d5e9c310e6bdestradaa getGeofenceHardwareSink().reportGeofenceAddStatus( 1690682809ad08db284d7110aab44108d5e9c310e6bdestradaa geofenceId, 1700682809ad08db284d7110aab44108d5e9c310e6bdestradaa translateToGeofenceHardwareStatus(result)); 1711af4b0280af406cfc7eb46810f6b76e57b983e11destradaa } 1721af4b0280af406cfc7eb46810f6b76e57b983e11destradaa 1731af4b0280af406cfc7eb46810f6b76e57b983e11destradaa private void onGeofenceRemove(int geofenceId, int result) { 1740682809ad08db284d7110aab44108d5e9c310e6bdestradaa getGeofenceHardwareSink().reportGeofenceRemoveStatus( 1750682809ad08db284d7110aab44108d5e9c310e6bdestradaa geofenceId, 1760682809ad08db284d7110aab44108d5e9c310e6bdestradaa translateToGeofenceHardwareStatus(result)); 1771af4b0280af406cfc7eb46810f6b76e57b983e11destradaa } 1781af4b0280af406cfc7eb46810f6b76e57b983e11destradaa 1791af4b0280af406cfc7eb46810f6b76e57b983e11destradaa private void onGeofencePause(int geofenceId, int result) { 1800682809ad08db284d7110aab44108d5e9c310e6bdestradaa getGeofenceHardwareSink().reportGeofencePauseStatus( 1810682809ad08db284d7110aab44108d5e9c310e6bdestradaa geofenceId, 1820682809ad08db284d7110aab44108d5e9c310e6bdestradaa translateToGeofenceHardwareStatus(result)); 1831af4b0280af406cfc7eb46810f6b76e57b983e11destradaa } 1841af4b0280af406cfc7eb46810f6b76e57b983e11destradaa 1851af4b0280af406cfc7eb46810f6b76e57b983e11destradaa private void onGeofenceResume(int geofenceId, int result) { 1860682809ad08db284d7110aab44108d5e9c310e6bdestradaa getGeofenceHardwareSink().reportGeofenceResumeStatus( 1870682809ad08db284d7110aab44108d5e9c310e6bdestradaa geofenceId, 1880682809ad08db284d7110aab44108d5e9c310e6bdestradaa translateToGeofenceHardwareStatus(result)); 1891af4b0280af406cfc7eb46810f6b76e57b983e11destradaa } 1901af4b0280af406cfc7eb46810f6b76e57b983e11destradaa 1911af4b0280af406cfc7eb46810f6b76e57b983e11destradaa /** 1921af4b0280af406cfc7eb46810f6b76e57b983e11destradaa * Private native methods accessing FLP HAL. 1931af4b0280af406cfc7eb46810f6b76e57b983e11destradaa */ 1941af4b0280af406cfc7eb46810f6b76e57b983e11destradaa static { nativeClassInit(); } 1951af4b0280af406cfc7eb46810f6b76e57b983e11destradaa 1961af4b0280af406cfc7eb46810f6b76e57b983e11destradaa // Core members 1971af4b0280af406cfc7eb46810f6b76e57b983e11destradaa private static native void nativeClassInit(); 1981af4b0280af406cfc7eb46810f6b76e57b983e11destradaa private static native boolean nativeIsSupported(); 1991af4b0280af406cfc7eb46810f6b76e57b983e11destradaa 2001af4b0280af406cfc7eb46810f6b76e57b983e11destradaa // FlpLocationInterface members 2011af4b0280af406cfc7eb46810f6b76e57b983e11destradaa private native void nativeInit(); 2021af4b0280af406cfc7eb46810f6b76e57b983e11destradaa private native int nativeGetBatchSize(); 2031af4b0280af406cfc7eb46810f6b76e57b983e11destradaa private native void nativeStartBatching(int requestId, FusedBatchOptions options); 2041af4b0280af406cfc7eb46810f6b76e57b983e11destradaa private native void nativeUpdateBatchingOptions(int requestId, FusedBatchOptions optionsObject); 2051af4b0280af406cfc7eb46810f6b76e57b983e11destradaa private native void nativeStopBatching(int id); 2061af4b0280af406cfc7eb46810f6b76e57b983e11destradaa private native void nativeRequestBatchedLocation(int lastNLocations); 2071af4b0280af406cfc7eb46810f6b76e57b983e11destradaa private native void nativeInjectLocation(Location location); 2081af4b0280af406cfc7eb46810f6b76e57b983e11destradaa // TODO [Fix] sort out the lifetime of the instance 2091af4b0280af406cfc7eb46810f6b76e57b983e11destradaa private native void nativeCleanup(); 2101af4b0280af406cfc7eb46810f6b76e57b983e11destradaa 2111af4b0280af406cfc7eb46810f6b76e57b983e11destradaa // FlpDiagnosticsInterface members 2121af4b0280af406cfc7eb46810f6b76e57b983e11destradaa private native boolean nativeIsDiagnosticSupported(); 2131af4b0280af406cfc7eb46810f6b76e57b983e11destradaa private native void nativeInjectDiagnosticData(String data); 2141af4b0280af406cfc7eb46810f6b76e57b983e11destradaa 2151af4b0280af406cfc7eb46810f6b76e57b983e11destradaa // FlpDeviceContextInterface members 2161af4b0280af406cfc7eb46810f6b76e57b983e11destradaa private native boolean nativeIsDeviceContextSupported(); 2171af4b0280af406cfc7eb46810f6b76e57b983e11destradaa private native void nativeInjectDeviceContext(int deviceEnabledContext); 2181af4b0280af406cfc7eb46810f6b76e57b983e11destradaa 2191af4b0280af406cfc7eb46810f6b76e57b983e11destradaa // FlpGeofencingInterface members 2201af4b0280af406cfc7eb46810f6b76e57b983e11destradaa private native boolean nativeIsGeofencingSupported(); 2210682809ad08db284d7110aab44108d5e9c310e6bdestradaa private native void nativeAddGeofences( 2220682809ad08db284d7110aab44108d5e9c310e6bdestradaa GeofenceHardwareRequestParcelable[] geofenceRequestsArray); 2231af4b0280af406cfc7eb46810f6b76e57b983e11destradaa private native void nativePauseGeofence(int geofenceId); 2241af4b0280af406cfc7eb46810f6b76e57b983e11destradaa private native void nativeResumeGeofence(int geofenceId, int monitorTransitions); 2251af4b0280af406cfc7eb46810f6b76e57b983e11destradaa private native void nativeModifyGeofenceOption( 2261af4b0280af406cfc7eb46810f6b76e57b983e11destradaa int geofenceId, 2271af4b0280af406cfc7eb46810f6b76e57b983e11destradaa int lastTransition, 2281af4b0280af406cfc7eb46810f6b76e57b983e11destradaa int monitorTransitions, 2291af4b0280af406cfc7eb46810f6b76e57b983e11destradaa int notificationResponsiveness, 2301af4b0280af406cfc7eb46810f6b76e57b983e11destradaa int unknownTimer, 2311af4b0280af406cfc7eb46810f6b76e57b983e11destradaa int sourcesToUse); 2321af4b0280af406cfc7eb46810f6b76e57b983e11destradaa private native void nativeRemoveGeofences(int[] geofenceIdsArray); 2331af4b0280af406cfc7eb46810f6b76e57b983e11destradaa 2341af4b0280af406cfc7eb46810f6b76e57b983e11destradaa /** 2351af4b0280af406cfc7eb46810f6b76e57b983e11destradaa * Interface implementations for services built on top of this functionality. 2361af4b0280af406cfc7eb46810f6b76e57b983e11destradaa */ 2371af4b0280af406cfc7eb46810f6b76e57b983e11destradaa public static final String LOCATION = "Location"; 2381af4b0280af406cfc7eb46810f6b76e57b983e11destradaa public static final String GEOFENCING = "Geofencing"; 2391af4b0280af406cfc7eb46810f6b76e57b983e11destradaa 2401af4b0280af406cfc7eb46810f6b76e57b983e11destradaa public IFusedLocationHardware getLocationHardware() { 2411af4b0280af406cfc7eb46810f6b76e57b983e11destradaa nativeInit(); 2421af4b0280af406cfc7eb46810f6b76e57b983e11destradaa return mLocationHardware; 2431af4b0280af406cfc7eb46810f6b76e57b983e11destradaa } 2441af4b0280af406cfc7eb46810f6b76e57b983e11destradaa 2451af4b0280af406cfc7eb46810f6b76e57b983e11destradaa public IFusedGeofenceHardware getGeofenceHardware() { 2461af4b0280af406cfc7eb46810f6b76e57b983e11destradaa nativeInit(); 2471af4b0280af406cfc7eb46810f6b76e57b983e11destradaa return mGeofenceHardwareService; 2481af4b0280af406cfc7eb46810f6b76e57b983e11destradaa } 2491af4b0280af406cfc7eb46810f6b76e57b983e11destradaa 2501af4b0280af406cfc7eb46810f6b76e57b983e11destradaa private final IFusedLocationHardware mLocationHardware = new IFusedLocationHardware.Stub() { 2511af4b0280af406cfc7eb46810f6b76e57b983e11destradaa @Override 2521af4b0280af406cfc7eb46810f6b76e57b983e11destradaa public void registerSink(IFusedLocationHardwareSink eventSink) { 25364be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa synchronized (mLocationSinkLock) { 25464be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa // only one sink is allowed at the moment 25564be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa if (mLocationSink != null) { 25664be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa throw new RuntimeException( 25764be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa "IFusedLocationHardware does not support multiple sinks"); 25864be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa } 25964be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa 26064be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa mLocationSink = eventSink; 2611af4b0280af406cfc7eb46810f6b76e57b983e11destradaa } 2621af4b0280af406cfc7eb46810f6b76e57b983e11destradaa } 2631af4b0280af406cfc7eb46810f6b76e57b983e11destradaa 2641af4b0280af406cfc7eb46810f6b76e57b983e11destradaa @Override 2651af4b0280af406cfc7eb46810f6b76e57b983e11destradaa public void unregisterSink(IFusedLocationHardwareSink eventSink) { 26664be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa synchronized (mLocationSinkLock) { 26764be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa // don't throw if the sink is not registered, simply make it a no-op 26864be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa if (mLocationSink == eventSink) { 26964be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa mLocationSink = null; 27064be0c617f902398cbbcc2b145c86a8fbfc2feacdestradaa } 2711af4b0280af406cfc7eb46810f6b76e57b983e11destradaa } 2721af4b0280af406cfc7eb46810f6b76e57b983e11destradaa } 2731af4b0280af406cfc7eb46810f6b76e57b983e11destradaa 2741af4b0280af406cfc7eb46810f6b76e57b983e11destradaa @Override 2751af4b0280af406cfc7eb46810f6b76e57b983e11destradaa public int getSupportedBatchSize() { 2761af4b0280af406cfc7eb46810f6b76e57b983e11destradaa return nativeGetBatchSize(); 2771af4b0280af406cfc7eb46810f6b76e57b983e11destradaa } 2781af4b0280af406cfc7eb46810f6b76e57b983e11destradaa 2791af4b0280af406cfc7eb46810f6b76e57b983e11destradaa @Override 2801af4b0280af406cfc7eb46810f6b76e57b983e11destradaa public void startBatching(int requestId, FusedBatchOptions options) { 2811af4b0280af406cfc7eb46810f6b76e57b983e11destradaa nativeStartBatching(requestId, options); 2821af4b0280af406cfc7eb46810f6b76e57b983e11destradaa } 2831af4b0280af406cfc7eb46810f6b76e57b983e11destradaa 2841af4b0280af406cfc7eb46810f6b76e57b983e11destradaa @Override 2851af4b0280af406cfc7eb46810f6b76e57b983e11destradaa public void stopBatching(int requestId) { 2861af4b0280af406cfc7eb46810f6b76e57b983e11destradaa nativeStopBatching(requestId); 2871af4b0280af406cfc7eb46810f6b76e57b983e11destradaa } 2881af4b0280af406cfc7eb46810f6b76e57b983e11destradaa 2891af4b0280af406cfc7eb46810f6b76e57b983e11destradaa @Override 2901af4b0280af406cfc7eb46810f6b76e57b983e11destradaa public void updateBatchingOptions(int requestId, FusedBatchOptions options) { 2911af4b0280af406cfc7eb46810f6b76e57b983e11destradaa nativeUpdateBatchingOptions(requestId, options); 2921af4b0280af406cfc7eb46810f6b76e57b983e11destradaa } 2931af4b0280af406cfc7eb46810f6b76e57b983e11destradaa 2941af4b0280af406cfc7eb46810f6b76e57b983e11destradaa @Override 2951af4b0280af406cfc7eb46810f6b76e57b983e11destradaa public void requestBatchOfLocations(int batchSizeRequested) { 2961af4b0280af406cfc7eb46810f6b76e57b983e11destradaa nativeRequestBatchedLocation(batchSizeRequested); 2971af4b0280af406cfc7eb46810f6b76e57b983e11destradaa } 2981af4b0280af406cfc7eb46810f6b76e57b983e11destradaa 2991af4b0280af406cfc7eb46810f6b76e57b983e11destradaa @Override 3001af4b0280af406cfc7eb46810f6b76e57b983e11destradaa public boolean supportsDiagnosticDataInjection() { 3011af4b0280af406cfc7eb46810f6b76e57b983e11destradaa return nativeIsDiagnosticSupported(); 3021af4b0280af406cfc7eb46810f6b76e57b983e11destradaa } 3031af4b0280af406cfc7eb46810f6b76e57b983e11destradaa 3041af4b0280af406cfc7eb46810f6b76e57b983e11destradaa @Override 3051af4b0280af406cfc7eb46810f6b76e57b983e11destradaa public void injectDiagnosticData(String data) { 3061af4b0280af406cfc7eb46810f6b76e57b983e11destradaa nativeInjectDiagnosticData(data); 3071af4b0280af406cfc7eb46810f6b76e57b983e11destradaa } 3081af4b0280af406cfc7eb46810f6b76e57b983e11destradaa 3091af4b0280af406cfc7eb46810f6b76e57b983e11destradaa @Override 3101af4b0280af406cfc7eb46810f6b76e57b983e11destradaa public boolean supportsDeviceContextInjection() { 3111af4b0280af406cfc7eb46810f6b76e57b983e11destradaa return nativeIsDeviceContextSupported(); 3121af4b0280af406cfc7eb46810f6b76e57b983e11destradaa } 3131af4b0280af406cfc7eb46810f6b76e57b983e11destradaa 3141af4b0280af406cfc7eb46810f6b76e57b983e11destradaa @Override 3151af4b0280af406cfc7eb46810f6b76e57b983e11destradaa public void injectDeviceContext(int deviceEnabledContext) { 3161af4b0280af406cfc7eb46810f6b76e57b983e11destradaa nativeInjectDeviceContext(deviceEnabledContext); 3171af4b0280af406cfc7eb46810f6b76e57b983e11destradaa } 3181af4b0280af406cfc7eb46810f6b76e57b983e11destradaa }; 3191af4b0280af406cfc7eb46810f6b76e57b983e11destradaa 3201af4b0280af406cfc7eb46810f6b76e57b983e11destradaa private final IFusedGeofenceHardware mGeofenceHardwareService = 3211af4b0280af406cfc7eb46810f6b76e57b983e11destradaa new IFusedGeofenceHardware.Stub() { 3221af4b0280af406cfc7eb46810f6b76e57b983e11destradaa @Override 3231af4b0280af406cfc7eb46810f6b76e57b983e11destradaa public boolean isSupported() { 3241af4b0280af406cfc7eb46810f6b76e57b983e11destradaa return nativeIsGeofencingSupported(); 3251af4b0280af406cfc7eb46810f6b76e57b983e11destradaa } 3261af4b0280af406cfc7eb46810f6b76e57b983e11destradaa 3271af4b0280af406cfc7eb46810f6b76e57b983e11destradaa @Override 3280682809ad08db284d7110aab44108d5e9c310e6bdestradaa public void addGeofences(GeofenceHardwareRequestParcelable[] geofenceRequestsArray) { 3290682809ad08db284d7110aab44108d5e9c310e6bdestradaa nativeAddGeofences(geofenceRequestsArray); 3301af4b0280af406cfc7eb46810f6b76e57b983e11destradaa } 3311af4b0280af406cfc7eb46810f6b76e57b983e11destradaa 3321af4b0280af406cfc7eb46810f6b76e57b983e11destradaa @Override 3331af4b0280af406cfc7eb46810f6b76e57b983e11destradaa public void removeGeofences(int[] geofenceIds) { 3341af4b0280af406cfc7eb46810f6b76e57b983e11destradaa nativeRemoveGeofences(geofenceIds); 3351af4b0280af406cfc7eb46810f6b76e57b983e11destradaa } 3361af4b0280af406cfc7eb46810f6b76e57b983e11destradaa 3371af4b0280af406cfc7eb46810f6b76e57b983e11destradaa @Override 3381af4b0280af406cfc7eb46810f6b76e57b983e11destradaa public void pauseMonitoringGeofence(int geofenceId) { 3391af4b0280af406cfc7eb46810f6b76e57b983e11destradaa nativePauseGeofence(geofenceId); 3401af4b0280af406cfc7eb46810f6b76e57b983e11destradaa } 3411af4b0280af406cfc7eb46810f6b76e57b983e11destradaa 3421af4b0280af406cfc7eb46810f6b76e57b983e11destradaa @Override 3431af4b0280af406cfc7eb46810f6b76e57b983e11destradaa public void resumeMonitoringGeofence(int geofenceId, int monitorTransitions) { 3441af4b0280af406cfc7eb46810f6b76e57b983e11destradaa nativeResumeGeofence(geofenceId, monitorTransitions); 3451af4b0280af406cfc7eb46810f6b76e57b983e11destradaa } 3461af4b0280af406cfc7eb46810f6b76e57b983e11destradaa 3471af4b0280af406cfc7eb46810f6b76e57b983e11destradaa @Override 3481af4b0280af406cfc7eb46810f6b76e57b983e11destradaa public void modifyGeofenceOptions(int geofenceId, 3491af4b0280af406cfc7eb46810f6b76e57b983e11destradaa int lastTransition, 3501af4b0280af406cfc7eb46810f6b76e57b983e11destradaa int monitorTransitions, 3511af4b0280af406cfc7eb46810f6b76e57b983e11destradaa int notificationResponsiveness, 3520682809ad08db284d7110aab44108d5e9c310e6bdestradaa int unknownTimer, 3530682809ad08db284d7110aab44108d5e9c310e6bdestradaa int sourcesToUse) { 3541af4b0280af406cfc7eb46810f6b76e57b983e11destradaa nativeModifyGeofenceOption( 3551af4b0280af406cfc7eb46810f6b76e57b983e11destradaa geofenceId, 3561af4b0280af406cfc7eb46810f6b76e57b983e11destradaa lastTransition, 3571af4b0280af406cfc7eb46810f6b76e57b983e11destradaa monitorTransitions, 3581af4b0280af406cfc7eb46810f6b76e57b983e11destradaa notificationResponsiveness, 3591af4b0280af406cfc7eb46810f6b76e57b983e11destradaa unknownTimer, 3600682809ad08db284d7110aab44108d5e9c310e6bdestradaa sourcesToUse); 3611af4b0280af406cfc7eb46810f6b76e57b983e11destradaa } 3621af4b0280af406cfc7eb46810f6b76e57b983e11destradaa }; 3631af4b0280af406cfc7eb46810f6b76e57b983e11destradaa 3641af4b0280af406cfc7eb46810f6b76e57b983e11destradaa /** 3651af4b0280af406cfc7eb46810f6b76e57b983e11destradaa * Internal classes and functions used by the provider. 3661af4b0280af406cfc7eb46810f6b76e57b983e11destradaa */ 3671af4b0280af406cfc7eb46810f6b76e57b983e11destradaa private final class NetworkLocationListener implements LocationListener { 3681af4b0280af406cfc7eb46810f6b76e57b983e11destradaa @Override 3691af4b0280af406cfc7eb46810f6b76e57b983e11destradaa public void onLocationChanged(Location location) { 3701af4b0280af406cfc7eb46810f6b76e57b983e11destradaa if ( 3711af4b0280af406cfc7eb46810f6b76e57b983e11destradaa !LocationManager.NETWORK_PROVIDER.equals(location.getProvider()) || 3721af4b0280af406cfc7eb46810f6b76e57b983e11destradaa !location.hasAccuracy() 3731af4b0280af406cfc7eb46810f6b76e57b983e11destradaa ) { 3741af4b0280af406cfc7eb46810f6b76e57b983e11destradaa return; 3751af4b0280af406cfc7eb46810f6b76e57b983e11destradaa } 3761af4b0280af406cfc7eb46810f6b76e57b983e11destradaa 3771af4b0280af406cfc7eb46810f6b76e57b983e11destradaa nativeInjectLocation(location); 3781af4b0280af406cfc7eb46810f6b76e57b983e11destradaa } 3791af4b0280af406cfc7eb46810f6b76e57b983e11destradaa 3801af4b0280af406cfc7eb46810f6b76e57b983e11destradaa @Override 3811af4b0280af406cfc7eb46810f6b76e57b983e11destradaa public void onStatusChanged(String provider, int status, Bundle extras) { } 3821af4b0280af406cfc7eb46810f6b76e57b983e11destradaa 3831af4b0280af406cfc7eb46810f6b76e57b983e11destradaa @Override 3841af4b0280af406cfc7eb46810f6b76e57b983e11destradaa public void onProviderEnabled(String provider) { } 3851af4b0280af406cfc7eb46810f6b76e57b983e11destradaa 3861af4b0280af406cfc7eb46810f6b76e57b983e11destradaa @Override 3871af4b0280af406cfc7eb46810f6b76e57b983e11destradaa public void onProviderDisabled(String provider) { } 3881af4b0280af406cfc7eb46810f6b76e57b983e11destradaa } 3891af4b0280af406cfc7eb46810f6b76e57b983e11destradaa 3901af4b0280af406cfc7eb46810f6b76e57b983e11destradaa private GeofenceHardwareImpl getGeofenceHardwareSink() { 3911af4b0280af406cfc7eb46810f6b76e57b983e11destradaa if (mGeofenceHardwareSink == null) { 3921af4b0280af406cfc7eb46810f6b76e57b983e11destradaa mGeofenceHardwareSink = GeofenceHardwareImpl.getInstance(mContext); 3931af4b0280af406cfc7eb46810f6b76e57b983e11destradaa } 3941af4b0280af406cfc7eb46810f6b76e57b983e11destradaa 3951af4b0280af406cfc7eb46810f6b76e57b983e11destradaa return mGeofenceHardwareSink; 3961af4b0280af406cfc7eb46810f6b76e57b983e11destradaa } 3970682809ad08db284d7110aab44108d5e9c310e6bdestradaa 3980682809ad08db284d7110aab44108d5e9c310e6bdestradaa private static int translateToGeofenceHardwareStatus(int flpHalResult) { 3990682809ad08db284d7110aab44108d5e9c310e6bdestradaa switch(flpHalResult) { 4000682809ad08db284d7110aab44108d5e9c310e6bdestradaa case FLP_RESULT_SUCCESS: 4010682809ad08db284d7110aab44108d5e9c310e6bdestradaa return GeofenceHardware.GEOFENCE_SUCCESS; 4020682809ad08db284d7110aab44108d5e9c310e6bdestradaa case FLP_RESULT_ERROR: 4030682809ad08db284d7110aab44108d5e9c310e6bdestradaa return GeofenceHardware.GEOFENCE_FAILURE; 4040682809ad08db284d7110aab44108d5e9c310e6bdestradaa // TODO: uncomment this once the ERROR definition is marked public 4050682809ad08db284d7110aab44108d5e9c310e6bdestradaa //case FLP_RESULT_INSUFFICIENT_MEMORY: 4060682809ad08db284d7110aab44108d5e9c310e6bdestradaa // return GeofenceHardware.GEOFENCE_ERROR_INSUFFICIENT_MEMORY; 4070682809ad08db284d7110aab44108d5e9c310e6bdestradaa case FLP_RESULT_TOO_MANY_GEOFENCES: 4080682809ad08db284d7110aab44108d5e9c310e6bdestradaa return GeofenceHardware.GEOFENCE_ERROR_TOO_MANY_GEOFENCES; 4090682809ad08db284d7110aab44108d5e9c310e6bdestradaa case FLP_RESULT_ID_EXISTS: 4100682809ad08db284d7110aab44108d5e9c310e6bdestradaa return GeofenceHardware.GEOFENCE_ERROR_ID_EXISTS; 4110682809ad08db284d7110aab44108d5e9c310e6bdestradaa case FLP_RESULT_ID_UNKNOWN: 4120682809ad08db284d7110aab44108d5e9c310e6bdestradaa return GeofenceHardware.GEOFENCE_ERROR_ID_UNKNOWN; 4130682809ad08db284d7110aab44108d5e9c310e6bdestradaa case FLP_RESULT_INVALID_GEOFENCE_TRANSITION: 4140682809ad08db284d7110aab44108d5e9c310e6bdestradaa return GeofenceHardware.GEOFENCE_ERROR_INVALID_TRANSITION; 4150682809ad08db284d7110aab44108d5e9c310e6bdestradaa default: 4160682809ad08db284d7110aab44108d5e9c310e6bdestradaa Log.e(TAG, String.format("Invalid FlpHal result code: %d", flpHalResult)); 4170682809ad08db284d7110aab44108d5e9c310e6bdestradaa return GeofenceHardware.GEOFENCE_FAILURE; 4180682809ad08db284d7110aab44108d5e9c310e6bdestradaa } 4190682809ad08db284d7110aab44108d5e9c310e6bdestradaa } 4200682809ad08db284d7110aab44108d5e9c310e6bdestradaa 4210682809ad08db284d7110aab44108d5e9c310e6bdestradaa private Location updateLocationInformation(Location location) { 4220682809ad08db284d7110aab44108d5e9c310e6bdestradaa location.setProvider(LocationManager.FUSED_PROVIDER); 4230682809ad08db284d7110aab44108d5e9c310e6bdestradaa // set the elapsed time-stamp just as GPS provider does 4240682809ad08db284d7110aab44108d5e9c310e6bdestradaa location.setElapsedRealtimeNanos(SystemClock.elapsedRealtimeNanos()); 4250682809ad08db284d7110aab44108d5e9c310e6bdestradaa return location; 4260682809ad08db284d7110aab44108d5e9c310e6bdestradaa } 4270682809ad08db284d7110aab44108d5e9c310e6bdestradaa} 428