blob: 3c81a456940719fcaef772c767f41a5104ece0d9 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Mike Lockwood00b74272010-03-26 10:41:48 -040017package com.android.server.location;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080018
Mike Lockwood29c84342009-05-06 14:01:15 -040019import android.app.AlarmManager;
Dianne Hackborna06de0f2012-12-11 16:34:47 -080020import android.app.AppOpsManager;
Mike Lockwood29c84342009-05-06 14:01:15 -040021import android.app.PendingIntent;
The Android Open Source Project10592532009-03-18 17:39:46 -070022import android.content.BroadcastReceiver;
Yu-Han Yang74041ff2018-04-06 15:57:31 -070023import android.content.ContentResolver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080024import android.content.Context;
25import android.content.Intent;
The Android Open Source Project10592532009-03-18 17:39:46 -070026import android.content.IntentFilter;
destradaa0682809a2013-08-12 18:50:30 -070027import android.hardware.location.GeofenceHardware;
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -070028import android.hardware.location.GeofenceHardwareImpl;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080029import android.location.Criteria;
destradaa0682809a2013-08-12 18:50:30 -070030import android.location.FusedBatchOptions;
Yu-Han Yange7baef32018-02-09 13:58:17 -080031import android.location.GnssMeasurementsEvent;
32import android.location.GnssNavigationMessage;
Lifu Tang30f95a72016-01-07 23:20:38 -080033import android.location.GnssStatus;
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -070034import android.location.IGpsGeofenceHardware;
Danke Xie22d1f9f2009-08-18 18:28:45 -040035import android.location.INetInitiatedListener;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080036import android.location.Location;
Nick Pelly6fa9ad42012-07-16 12:18:23 -070037import android.location.LocationListener;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080038import android.location.LocationManager;
39import android.location.LocationProvider;
Stan Chesnutt1d72d8c2013-04-15 19:18:02 -070040import android.location.LocationRequest;
Kevin Tang40e1baf2012-01-10 14:32:44 -080041import android.os.AsyncTask;
Dianne Hackborn91268cf2013-06-13 19:06:50 -070042import android.os.BatteryStats;
Mike Lockwood63aa5a62010-04-14 19:21:31 -040043import android.os.Binder;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080044import android.os.Bundle;
Mike Lockwood62a8fc12010-03-22 14:23:26 -040045import android.os.Handler;
Victoria Lease5cd731a2012-12-19 15:04:21 -080046import android.os.Looper;
Mike Lockwood62a8fc12010-03-22 14:23:26 -040047import android.os.Message;
Yu-Han Yange7baef32018-02-09 13:58:17 -080048import android.os.PersistableBundle;
Mike Lockwood0528b9b2009-05-07 10:12:54 -040049import android.os.PowerManager;
Yu-Han Yange7baef32018-02-09 13:58:17 -080050import android.os.PowerManager.ServiceType;
51import android.os.PowerSaveState;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080052import android.os.RemoteException;
Mike Lockwood2f82c4e2009-04-17 08:24:10 -040053import android.os.ServiceManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080054import android.os.SystemClock;
Colin Cross7c030ed2014-01-28 09:33:53 -080055import android.os.SystemProperties;
Dianne Hackborn5ac72a22012-08-29 18:32:08 -070056import android.os.UserHandle;
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -070057import android.os.WorkSource;
Narayan Kamath32684dd2018-01-08 17:32:51 +000058import android.os.WorkSource.WorkChain;
Mike Lockwoodbcab8df2009-06-25 16:39:09 -040059import android.provider.Settings;
Yu-Han Yange7baef32018-02-09 13:58:17 -080060import android.telephony.CarrierConfigManager;
Wink Savillea374c3d2014-11-11 11:48:04 -080061import android.telephony.SubscriptionManager;
Wink Savilled09c4ca2014-11-22 10:08:16 -080062import android.telephony.SubscriptionManager.OnSubscriptionsChangedListener;
Miguel Torroja1e84da82010-07-27 07:02:24 +020063import android.telephony.TelephonyManager;
64import android.telephony.gsm.GsmCellLocation;
Colin Cross7c030ed2014-01-28 09:33:53 -080065import android.text.TextUtils;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080066import android.util.Log;
Yu-Han Yanga1862b52018-02-20 17:05:59 -080067
jackqdyulei455e90a2017-02-09 15:29:16 -080068import com.android.internal.app.IBatteryStats;
69import com.android.internal.location.GpsNetInitiatedHandler;
70import com.android.internal.location.GpsNetInitiatedHandler.GpsNiNotification;
71import com.android.internal.location.ProviderProperties;
72import com.android.internal.location.ProviderRequest;
Yu-Han Yange7baef32018-02-09 13:58:17 -080073import com.android.internal.location.gnssmetrics.GnssMetrics;
Yu-Han Yang66c7ea92018-03-11 17:17:15 -070074import com.android.server.location.GnssSatelliteBlacklistHelper.GnssSatelliteBlacklistCallback;
Yu-Han Yanga1862b52018-02-20 17:05:59 -080075import com.android.server.location.NtpTimeHelper.InjectNtpTimeCallback;
Yu-Han Yang66c7ea92018-03-11 17:17:15 -070076
Nick Pelly6fa9ad42012-07-16 12:18:23 -070077import java.io.FileDescriptor;
Nick Pelly6fa9ad42012-07-16 12:18:23 -070078import java.io.PrintWriter;
Soonil Nagarkar1575a042018-10-24 17:54:54 -070079import java.lang.annotation.ElementType;
80import java.lang.annotation.Retention;
81import java.lang.annotation.RetentionPolicy;
82import java.lang.annotation.Target;
Wyatt Rileycf879db2017-01-12 13:57:38 -080083import java.util.ArrayList;
Andreas Gampee6748ce2015-12-11 18:00:38 -080084import java.util.Arrays;
Wyatt Rileycf879db2017-01-12 13:57:38 -080085import java.util.List;
Yu-Han Yange7baef32018-02-09 13:58:17 -080086
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080087/**
gomo4402af62017-01-11 13:20:13 -080088 * A GNSS implementation of LocationProvider used by LocationManager.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080089 *
90 * {@hide}
91 */
Soonil Nagarkar1575a042018-10-24 17:54:54 -070092public class GnssLocationProvider extends AbstractLocationProvider implements
93 InjectNtpTimeCallback,
94 GnssSatelliteBlacklistCallback {
95
96 /**
97 * Indicates that this method is a native entry point. Useful purely for IDEs which can
98 * understand entry points, and thus eliminate incorrect warnings about methods not used.
99 */
100 @Target(ElementType.METHOD)
101 @Retention(RetentionPolicy.SOURCE)
102 private @interface NativeEntryPoint {
103 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800104
Lifu Tang30f95a72016-01-07 23:20:38 -0800105 private static final String TAG = "GnssLocationProvider";
Mike Lockwood29c84342009-05-06 14:01:15 -0400106
Brian Muramatsu1715cb32012-08-08 17:32:21 -0700107 private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
108 private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400109
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700110 private static final ProviderProperties PROPERTIES = new ProviderProperties(
111 true, true, false, false, true, true, true,
112 Criteria.POWER_HIGH, Criteria.ACCURACY_FINE);
113
gomo4402af62017-01-11 13:20:13 -0800114 // these need to match GnssPositionMode enum in IGnss.hal
The Android Open Source Project10592532009-03-18 17:39:46 -0700115 private static final int GPS_POSITION_MODE_STANDALONE = 0;
116 private static final int GPS_POSITION_MODE_MS_BASED = 1;
117 private static final int GPS_POSITION_MODE_MS_ASSISTED = 2;
118
gomo4402af62017-01-11 13:20:13 -0800119 // these need to match GnssPositionRecurrence enum in IGnss.hal
Mike Lockwood04598b62010-04-14 17:17:24 -0400120 private static final int GPS_POSITION_RECURRENCE_PERIODIC = 0;
121 private static final int GPS_POSITION_RECURRENCE_SINGLE = 1;
122
gomo4402af62017-01-11 13:20:13 -0800123 // these need to match GnssStatusValue enum in IGnssCallback.hal
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800124 private static final int GPS_STATUS_NONE = 0;
125 private static final int GPS_STATUS_SESSION_BEGIN = 1;
126 private static final int GPS_STATUS_SESSION_END = 2;
127 private static final int GPS_STATUS_ENGINE_ON = 3;
128 private static final int GPS_STATUS_ENGINE_OFF = 4;
129
gomo4402af62017-01-11 13:20:13 -0800130 // these need to match GnssLocationFlags enum in types.hal
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800131 private static final int LOCATION_INVALID = 0;
132 private static final int LOCATION_HAS_LAT_LONG = 1;
133 private static final int LOCATION_HAS_ALTITUDE = 2;
134 private static final int LOCATION_HAS_SPEED = 4;
135 private static final int LOCATION_HAS_BEARING = 8;
gomo4402af62017-01-11 13:20:13 -0800136 private static final int LOCATION_HAS_HORIZONTAL_ACCURACY = 16;
137 private static final int LOCATION_HAS_VERTICAL_ACCURACY = 32;
138 private static final int LOCATION_HAS_SPEED_ACCURACY = 64;
139 private static final int LOCATION_HAS_BEARING_ACCURACY = 128;
Mike Lockwoode3635c92009-05-11 08:38:02 -0400140
gomo4402af62017-01-11 13:20:13 -0800141 // IMPORTANT - the GPS_DELETE_* symbols here must match GnssAidingData enum in IGnss.hal
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800142 private static final int GPS_DELETE_EPHEMERIS = 0x0001;
143 private static final int GPS_DELETE_ALMANAC = 0x0002;
144 private static final int GPS_DELETE_POSITION = 0x0004;
145 private static final int GPS_DELETE_TIME = 0x0008;
146 private static final int GPS_DELETE_IONO = 0x0010;
147 private static final int GPS_DELETE_UTC = 0x0020;
148 private static final int GPS_DELETE_HEALTH = 0x0040;
149 private static final int GPS_DELETE_SVDIR = 0x0080;
150 private static final int GPS_DELETE_SVSTEER = 0x0100;
151 private static final int GPS_DELETE_SADATA = 0x0200;
152 private static final int GPS_DELETE_RTI = 0x0400;
153 private static final int GPS_DELETE_CELLDB_INFO = 0x8000;
154 private static final int GPS_DELETE_ALL = 0xFFFF;
155
gomo4402af62017-01-11 13:20:13 -0800156 // The GPS_CAPABILITY_* flags must match Capabilities enum in IGnssCallback.hal
Mike Lockwood04598b62010-04-14 17:17:24 -0400157 private static final int GPS_CAPABILITY_SCHEDULING = 0x0000001;
158 private static final int GPS_CAPABILITY_MSB = 0x0000002;
159 private static final int GPS_CAPABILITY_MSA = 0x0000004;
160 private static final int GPS_CAPABILITY_SINGLE_SHOT = 0x0000008;
Mike Lockwood9b9fb5c2011-06-29 15:09:40 -0400161 private static final int GPS_CAPABILITY_ON_DEMAND_TIME = 0x0000010;
destradaa6568d702014-10-27 12:47:41 -0700162 private static final int GPS_CAPABILITY_GEOFENCING = 0x0000020;
gomo226b7b72018-12-12 16:49:39 -0800163 public static final int GPS_CAPABILITY_MEASUREMENTS = 0x0000040;
destradaa6568d702014-10-27 12:47:41 -0700164 private static final int GPS_CAPABILITY_NAV_MESSAGES = 0x0000080;
Mike Lockwood04598b62010-04-14 17:17:24 -0400165
Tsuwei Chen462bcd82014-09-17 12:28:49 -0700166 // The AGPS SUPL mode
167 private static final int AGPS_SUPL_MODE_MSA = 0x02;
168 private static final int AGPS_SUPL_MODE_MSB = 0x01;
169
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400170 // Handler messages
171 private static final int CHECK_LOCATION = 1;
172 private static final int ENABLE = 2;
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700173 private static final int SET_REQUEST = 3;
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400174 private static final int UPDATE_NETWORK_STATE = 4;
175 private static final int INJECT_NTP_TIME = 5;
176 private static final int DOWNLOAD_XTRA_DATA = 6;
Wyatt Rileyc7067412018-02-07 15:50:35 -0800177 private static final int UPDATE_LOCATION = 7; // Handle external location from network listener
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400178 private static final int ADD_LISTENER = 8;
179 private static final int REMOVE_LISTENER = 9;
Kevin Tang40e1baf2012-01-10 14:32:44 -0800180 private static final int DOWNLOAD_XTRA_DATA_FINISHED = 11;
Meng Wang19b214d2018-11-07 12:14:39 -0800181 private static final int SUBSCRIPTION_OR_CARRIER_CONFIG_CHANGED = 12;
destradaafb23c672015-04-16 14:01:27 -0700182 private static final int INITIALIZE_HANDLER = 13;
destradaae21252a2015-09-08 12:32:59 -0700183 private static final int REQUEST_SUPL_CONNECTION = 14;
184 private static final int RELEASE_SUPL_CONNECTION = 15;
Yu-Han Yange7baef32018-02-09 13:58:17 -0800185 private static final int REQUEST_LOCATION = 16;
Wyatt Riley26465d22018-02-12 13:44:24 -0800186 private static final int REPORT_LOCATION = 17; // HAL reports location
187 private static final int REPORT_SV_STATUS = 18; // HAL reports SV status
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400188
Miguel Torroja1e84da82010-07-27 07:02:24 +0200189 // Request setid
190 private static final int AGPS_RIL_REQUEST_SETID_IMSI = 1;
191 private static final int AGPS_RIL_REQUEST_SETID_MSISDN = 2;
192
Miguel Torroja1e84da82010-07-27 07:02:24 +0200193 // ref. location info
194 private static final int AGPS_REF_LOCATION_TYPE_GSM_CELLID = 1;
195 private static final int AGPS_REF_LOCATION_TYPE_UMTS_CELLID = 2;
Miguel Torroja1e84da82010-07-27 07:02:24 +0200196
197 // set id info
198 private static final int AGPS_SETID_TYPE_NONE = 0;
199 private static final int AGPS_SETID_TYPE_IMSI = 1;
200 private static final int AGPS_SETID_TYPE_MSISDN = 2;
201
gomo48f1a642017-11-10 20:35:46 -0800202 private static final int GPS_GEOFENCE_UNAVAILABLE = 1 << 0L;
203 private static final int GPS_GEOFENCE_AVAILABLE = 1 << 1L;
destradaa0682809a2013-08-12 18:50:30 -0700204
gomo4402af62017-01-11 13:20:13 -0800205 // GPS Geofence errors. Should match GeofenceStatus enum in IGnssGeofenceCallback.hal.
destradaa0682809a2013-08-12 18:50:30 -0700206 private static final int GPS_GEOFENCE_OPERATION_SUCCESS = 0;
207 private static final int GPS_GEOFENCE_ERROR_TOO_MANY_GEOFENCES = 100;
gomo48f1a642017-11-10 20:35:46 -0800208 private static final int GPS_GEOFENCE_ERROR_ID_EXISTS = -101;
destradaa0682809a2013-08-12 18:50:30 -0700209 private static final int GPS_GEOFENCE_ERROR_ID_UNKNOWN = -102;
210 private static final int GPS_GEOFENCE_ERROR_INVALID_TRANSITION = -103;
211 private static final int GPS_GEOFENCE_ERROR_GENERIC = -149;
212
Tsuwei Chen678c13c2014-09-22 17:48:41 -0700213 // TCP/IP constants.
214 // Valid TCP/UDP port range is (0, 65535].
215 private static final int TCP_MIN_PORT = 0;
216 private static final int TCP_MAX_PORT = 0xffff;
217
Yu-Han Yange7baef32018-02-09 13:58:17 -0800218 // 1 second, or 1 Hz frequency.
219 private static final long LOCATION_UPDATE_MIN_TIME_INTERVAL_MILLIS = 1000;
Yu-Han Yang639f7592018-06-07 11:58:52 -0700220 // Default update duration in milliseconds for REQUEST_LOCATION.
Yu-Han Yang9e2a8232018-06-14 12:10:08 -0700221 private static final long LOCATION_UPDATE_DURATION_MILLIS = 10 * 1000;
Yu-Han Yange7baef32018-02-09 13:58:17 -0800222
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700223 /** simpler wrapper for ProviderRequest + Worksource */
224 private static class GpsRequest {
225 public ProviderRequest request;
226 public WorkSource source;
gomo48f1a642017-11-10 20:35:46 -0800227
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700228 public GpsRequest(ProviderRequest request, WorkSource source) {
229 this.request = request;
230 this.source = source;
231 }
232 }
233
Wyatt Riley26465d22018-02-12 13:44:24 -0800234 // Threadsafe class to hold stats reported in the Extras Bundle
Wyatt Rileyc7067412018-02-07 15:50:35 -0800235 private static class LocationExtras {
236 private int mSvCount;
237 private int mMeanCn0;
238 private int mMaxCn0;
239 private final Bundle mBundle;
240
241 public LocationExtras() {
242 mBundle = new Bundle();
243 }
244
245 public void set(int svCount, int meanCn0, int maxCn0) {
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700246 synchronized (this) {
Wyatt Riley26465d22018-02-12 13:44:24 -0800247 mSvCount = svCount;
248 mMeanCn0 = meanCn0;
249 mMaxCn0 = maxCn0;
250 }
Wyatt Rileyc7067412018-02-07 15:50:35 -0800251 setBundle(mBundle);
252 }
253
254 public void reset() {
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700255 set(0, 0, 0);
Wyatt Rileyc7067412018-02-07 15:50:35 -0800256 }
257
258 // Also used by outside methods to add to other bundles
259 public void setBundle(Bundle extras) {
260 if (extras != null) {
Wyatt Riley26465d22018-02-12 13:44:24 -0800261 synchronized (this) {
262 extras.putInt("satellites", mSvCount);
263 extras.putInt("meanCn0", mMeanCn0);
264 extras.putInt("maxCn0", mMaxCn0);
265 }
Wyatt Rileyc7067412018-02-07 15:50:35 -0800266 }
267 }
268
269 public Bundle getBundle() {
Wyatt Riley26465d22018-02-12 13:44:24 -0800270 synchronized (this) {
271 return new Bundle(mBundle);
272 }
Wyatt Rileyc7067412018-02-07 15:50:35 -0800273 }
274 }
275
Yu-Han Yang66c7ea92018-03-11 17:17:15 -0700276 private final Object mLock = new Object();
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700277
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800278 // current status
Mike Lockwood15e3d0f2009-05-01 07:53:28 -0400279 private int mStatus = LocationProvider.TEMPORARILY_UNAVAILABLE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800280
281 // time for last status update
282 private long mStatusUpdateTime = SystemClock.elapsedRealtime();
Mike Lockwoodd53ba012010-04-15 20:41:26 -0400283
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800284 // turn off GPS fix icon if we haven't received a fix in 10 seconds
Mike Lockwood04598b62010-04-14 17:17:24 -0400285 private static final long RECENT_FIX_TIMEOUT = 10 * 1000;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800286
Mike Lockwood0632ca72009-05-14 15:51:03 -0400287 // stop trying if we do not receive a fix within 60 seconds
Mike Lockwood04598b62010-04-14 17:17:24 -0400288 private static final int NO_FIX_TIMEOUT = 60 * 1000;
Mike Lockwood0632ca72009-05-14 15:51:03 -0400289
Nick Pellyb041f232012-05-07 17:12:25 -0700290 // if the fix interval is below this we leave GPS on,
291 // if above then we cycle the GPS driver.
292 // Typical hot TTTF is ~5 seconds, so 10 seconds seems sane.
293 private static final int GPS_POLLING_THRESHOLD_INTERVAL = 10 * 1000;
294
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700295 // how long to wait if we have a network error in NTP or XTRA downloading
Wei Liu6f6326b2015-06-24 23:47:50 -0700296 // the initial value of the exponential backoff
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700297 // current setting - 5 minutes
gomo48f1a642017-11-10 20:35:46 -0800298 private static final long RETRY_INTERVAL = 5 * 60 * 1000;
Wei Liu6f6326b2015-06-24 23:47:50 -0700299 // how long to wait if we have a network error in NTP or XTRA downloading
300 // the max value of the exponential backoff
301 // current setting - 4 hours
gomo48f1a642017-11-10 20:35:46 -0800302 private static final long MAX_RETRY_INTERVAL = 4 * 60 * 60 * 1000;
Wei Liu6f6326b2015-06-24 23:47:50 -0700303
Wei Wangc5706f62017-04-18 11:26:26 -0700304 // Timeout when holding wakelocks for downloading XTRA data.
305 private static final long DOWNLOAD_XTRA_DATA_TIMEOUT_MS = 60 * 1000;
306
Yu-Han Yanga1862b52018-02-20 17:05:59 -0800307 private final ExponentialBackOff mXtraBackOff = new ExponentialBackOff(RETRY_INTERVAL,
308 MAX_RETRY_INTERVAL);
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700309
310 // true if we are enabled, protected by this
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700311 private boolean mEnabled = true;
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700312
Kevin Tang40e1baf2012-01-10 14:32:44 -0800313 // states for injecting ntp and downloading xtra data
314 private static final int STATE_PENDING_NETWORK = 0;
315 private static final int STATE_DOWNLOADING = 1;
316 private static final int STATE_IDLE = 2;
317
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400318 // flags to trigger NTP or XTRA data download when network becomes available
319 // initialized to true so we do NTP and XTRA when the network comes up after booting
Kevin Tang40e1baf2012-01-10 14:32:44 -0800320 private int mDownloadXtraDataPending = STATE_PENDING_NETWORK;
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400321
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800322 // true if GPS is navigating
323 private boolean mNavigating;
Mike Lockwoodcf1d8cb2010-01-20 10:14:54 -0500324
Mike Lockwood04598b62010-04-14 17:17:24 -0400325 // requested frequency of fixes, in milliseconds
326 private int mFixInterval = 1000;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800327
gomo48f1a642017-11-10 20:35:46 -0800328 // true if low power mode for the GNSS chipset is part of the latest request.
329 private boolean mLowPowerMode = false;
330
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800331 // true if we started navigation
332 private boolean mStarted;
333
Stan Chesnutt1d72d8c2013-04-15 19:18:02 -0700334 // true if single shot request is in progress
335 private boolean mSingleShot;
336
Mike Lockwood04598b62010-04-14 17:17:24 -0400337 // capabilities of the GPS engine
338 private int mEngineCapabilities;
339
Mike Lockwood1a1cd3a2010-08-17 07:42:54 -0400340 // true if XTRA is supported
341 private boolean mSupportsXtra;
342
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800343 // for calculating time to first fix
344 private long mFixRequestTime = 0;
345 // time to first fix for most recent session
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700346 private int mTimeToFirstFix = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800347 // time we received our last fix
348 private long mLastFixTime;
349
Mike Lockwood04598b62010-04-14 17:17:24 -0400350 private int mPositionMode;
Yu-Han Yangc8b9ff72018-04-17 00:47:24 -0700351 private GnssPositionMode mLastPositionMode;
Mike Lockwood04598b62010-04-14 17:17:24 -0400352
David Christied4edf4c2014-08-12 15:22:27 -0700353 // Current request from underlying location clients.
354 private ProviderRequest mProviderRequest = null;
Narayan Kamath32684dd2018-01-08 17:32:51 +0000355 // The WorkSource associated with the most recent client request (i.e, most recent call to
356 // setRequest).
David Christied4edf4c2014-08-12 15:22:27 -0700357 private WorkSource mWorkSource = null;
358 // True if gps should be disabled (used to support battery saver mode in settings).
359 private boolean mDisableGps = false;
360
destradaafb23c672015-04-16 14:01:27 -0700361 /**
362 * Properties loaded from PROPERTIES_FILE.
363 * It must be accessed only inside {@link #mHandler}.
364 */
Anil Admald71cf142018-12-21 14:59:36 -0800365 private GnssConfiguration mGnssConfiguration;
destradaafb23c672015-04-16 14:01:27 -0700366
Mike Lockwood734d6032009-07-28 18:30:25 -0700367 private String mSuplServerHost;
Tsuwei Chen678c13c2014-09-22 17:48:41 -0700368 private int mSuplServerPort = TCP_MIN_PORT;
Mike Lockwood734d6032009-07-28 18:30:25 -0700369 private String mC2KServerHost;
370 private int mC2KServerPort;
Tsuwei Chen3324e952014-09-07 01:30:42 -0700371 private boolean mSuplEsEnabled = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800372
Mike Lockwood15e3d0f2009-05-01 07:53:28 -0400373 private final Context mContext;
Wyatt Rileyc7067412018-02-07 15:50:35 -0800374 private final LocationExtras mLocationExtras = new LocationExtras();
Anil Admal75b9fd62018-11-28 11:22:50 -0800375 private final GnssStatusListenerHelper mGnssStatusListenerHelper;
Yu-Han Yang66c7ea92018-03-11 17:17:15 -0700376 private final GnssSatelliteBlacklistHelper mGnssSatelliteBlacklistHelper;
Lifu Tang818aa2c2016-02-01 01:52:00 -0800377 private final GnssMeasurementsProvider mGnssMeasurementsProvider;
378 private final GnssNavigationMessageProvider mGnssNavigationMessageProvider;
Yu-Han Yang07561382018-02-21 13:08:37 -0800379 private final LocationChangeListener mNetworkLocationListener = new NetworkLocationListener();
380 private final LocationChangeListener mFusedLocationListener = new FusedLocationListener();
Yu-Han Yanga1862b52018-02-20 17:05:59 -0800381 private final NtpTimeHelper mNtpTimeHelper;
Yu-Han Yang3557cc72018-03-21 12:48:36 -0700382 private final GnssBatchingProvider mGnssBatchingProvider;
Yu-Han Yang890ca8b2018-04-16 22:11:31 -0700383 private final GnssGeofenceProvider mGnssGeofenceProvider;
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400384
Victoria Lease5c24fd02012-10-01 11:00:50 -0700385 // Handler for processing events
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400386 private Handler mHandler;
The Android Open Source Project10592532009-03-18 17:39:46 -0700387
Anil Admal50ba15e2018-11-01 16:42:42 -0700388 private final GnssNetworkConnectivityHandler mNetworkConnectivityHandler;
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700389 private final GpsNetInitiatedHandler mNIHandler;
Mike Lockwood2f82c4e2009-04-17 08:24:10 -0400390
Mike Lockwood0528b9b2009-05-07 10:12:54 -0400391 // Wakelocks
Lifu Tang30f95a72016-01-07 23:20:38 -0800392 private final static String WAKELOCK_KEY = "GnssLocationProvider";
Mike Lockwood0528b9b2009-05-07 10:12:54 -0400393 private final PowerManager.WakeLock mWakeLock;
Wei Wangb71c0492017-05-01 20:24:19 -0700394 private static final String DOWNLOAD_EXTRA_WAKELOCK_KEY = "GnssLocationProviderXtraDownload";
395 private final PowerManager.WakeLock mDownloadXtraWakeLock;
Mike Lockwood0528b9b2009-05-07 10:12:54 -0400396
Mike Lockwood29c84342009-05-06 14:01:15 -0400397 // Alarms
398 private final static String ALARM_WAKEUP = "com.android.internal.location.ALARM_WAKEUP";
Mike Lockwood0632ca72009-05-14 15:51:03 -0400399 private final static String ALARM_TIMEOUT = "com.android.internal.location.ALARM_TIMEOUT";
Tsuwei Chen52617bb2014-08-25 11:49:11 -0700400
David Christied4edf4c2014-08-12 15:22:27 -0700401 private final PowerManager mPowerManager;
Mike Lockwood29c84342009-05-06 14:01:15 -0400402 private final AlarmManager mAlarmManager;
403 private final PendingIntent mWakeupIntent;
Mike Lockwood0632ca72009-05-14 15:51:03 -0400404 private final PendingIntent mTimeoutIntent;
Mike Lockwood29c84342009-05-06 14:01:15 -0400405
Svet Ganovf7b47252018-02-26 11:11:27 -0800406 private final AppOpsManager mAppOps;
Mike Lockwood2f82c4e2009-04-17 08:24:10 -0400407 private final IBatteryStats mBatteryStats;
The Android Open Source Project10592532009-03-18 17:39:46 -0700408
Narayan Kamath32684dd2018-01-08 17:32:51 +0000409 // Current list of underlying location clients.
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700410 // only modified on handler thread
Dianne Hackborn002a54e2013-01-10 17:34:55 -0800411 private WorkSource mClientSource = new WorkSource();
Mike Lockwoodf1218be2010-01-29 09:20:06 -0500412
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -0700413 private GeofenceHardwareImpl mGeofenceHardwareImpl;
Wyatt Rileyd87cf912017-12-05 09:31:52 -0800414
415 // Volatile for simple inter-thread sync on these values.
416 private volatile int mHardwareYear = 0;
Wyatt Riley49097c02018-03-15 09:14:43 -0700417 private volatile String mHardwareModelName;
Lifu Tang82f893d2016-01-21 18:15:33 -0800418
Wyatt Riley5d5bac82016-11-01 07:05:16 -0700419 // Set lower than the current ITAR limit of 600m/s to allow this to trigger even if GPS HAL
420 // stops output right at 600m/s, depriving this of the information of a device that reaches
421 // greater than 600m/s, and higher than the speed of sound to avoid impacting most use cases.
422 private static final float ITAR_SPEED_LIMIT_METERS_PER_SECOND = 400.0F;
Wyatt Riley042c48f2017-10-06 14:59:25 -0700423
Wyatt Riley042c48f2017-10-06 14:59:25 -0700424 private volatile boolean mItarSpeedLimitExceeded = false;
Wyatt Riley5d5bac82016-11-01 07:05:16 -0700425
Siddharth Raybb608c82017-03-16 11:33:34 -0700426 // GNSS Metrics
427 private GnssMetrics mGnssMetrics;
428
Anil Admal75b9fd62018-11-28 11:22:50 -0800429 public GnssStatusListenerHelper getGnssStatusProvider() {
430 return mGnssStatusListenerHelper;
Mike Lockwood15e3d0f2009-05-01 07:53:28 -0400431 }
432
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -0700433 public IGpsGeofenceHardware getGpsGeofenceProxy() {
Yu-Han Yang890ca8b2018-04-16 22:11:31 -0700434 return mGnssGeofenceProvider;
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -0700435 }
436
Lifu Tang818aa2c2016-02-01 01:52:00 -0800437 public GnssMeasurementsProvider getGnssMeasurementsProvider() {
438 return mGnssMeasurementsProvider;
destradaaea8a8a62014-06-23 18:19:03 -0700439 }
440
Lifu Tang818aa2c2016-02-01 01:52:00 -0800441 public GnssNavigationMessageProvider getGnssNavigationMessageProvider() {
442 return mGnssNavigationMessageProvider;
destradaa4b3e3932014-07-21 18:01:47 -0700443 }
Tsuwei Chen52617bb2014-08-25 11:49:11 -0700444 private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
gomo48f1a642017-11-10 20:35:46 -0800445 @Override
446 public void onReceive(Context context, Intent intent) {
The Android Open Source Project10592532009-03-18 17:39:46 -0700447 String action = intent.getAction();
Tsuwei Chen48d37f92014-09-05 15:15:34 -0700448 if (DEBUG) Log.d(TAG, "receive broadcast intent, action: " + action);
destradaaee9fd342015-08-31 13:31:17 -0700449 if (action == null) {
450 return;
451 }
452
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700453 switch (action) {
454 case ALARM_WAKEUP:
455 startNavigating(false);
456 break;
457 case ALARM_TIMEOUT:
458 hibernate();
459 break;
460 case PowerManager.ACTION_POWER_SAVE_MODE_CHANGED:
461 case PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED:
462 case Intent.ACTION_SCREEN_OFF:
463 case Intent.ACTION_SCREEN_ON:
464 updateLowPowerMode();
465 break;
Meng Wang19b214d2018-11-07 12:14:39 -0800466 case CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED:
467 subscriptionOrCarrierConfigChanged(context);
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700468 break;
David Christied4edf4c2014-08-12 15:22:27 -0700469 }
The Android Open Source Project10592532009-03-18 17:39:46 -0700470 }
Mike Lockwood29c84342009-05-06 14:01:15 -0400471 };
The Android Open Source Project10592532009-03-18 17:39:46 -0700472
Meng Wang19b214d2018-11-07 12:14:39 -0800473 // TODO(b/119326010): replace OnSubscriptionsChangedListener with
474 // ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED broadcast reseiver.
Wink Savilled09c4ca2014-11-22 10:08:16 -0800475 private final OnSubscriptionsChangedListener mOnSubscriptionsChangedListener =
476 new OnSubscriptionsChangedListener() {
gomo48f1a642017-11-10 20:35:46 -0800477 @Override
478 public void onSubscriptionsChanged() {
Meng Wang19b214d2018-11-07 12:14:39 -0800479 sendMessage(SUBSCRIPTION_OR_CARRIER_CONFIG_CHANGED, 0, null);
gomo48f1a642017-11-10 20:35:46 -0800480 }
481 };
Wink Savillea374c3d2014-11-11 11:48:04 -0800482
Yu-Han Yang66c7ea92018-03-11 17:17:15 -0700483 /**
484 * Implements {@link GnssSatelliteBlacklistCallback#onUpdateSatelliteBlacklist}.
485 */
486 @Override
487 public void onUpdateSatelliteBlacklist(int[] constellations, int[] svids) {
Anil Admald71cf142018-12-21 14:59:36 -0800488 mHandler.post(() -> mGnssConfiguration.setSatelliteBlacklist(constellations, svids));
Yu-Han Yang66c7ea92018-03-11 17:17:15 -0700489 }
490
Meng Wang19b214d2018-11-07 12:14:39 -0800491 private void subscriptionOrCarrierConfigChanged(Context context) {
Joe Onorato0c484102016-02-01 18:04:24 -0800492 if (DEBUG) Log.d(TAG, "received SIM related action: ");
Wink Savillea374c3d2014-11-11 11:48:04 -0800493 TelephonyManager phone = (TelephonyManager)
494 mContext.getSystemService(Context.TELEPHONY_SERVICE);
Ecco Park4fa1ab72016-10-24 13:04:52 -0700495 CarrierConfigManager configManager = (CarrierConfigManager)
496 mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE);
Wink Savillea374c3d2014-11-11 11:48:04 -0800497 String mccMnc = phone.getSimOperator();
Ecco Park4fa1ab72016-10-24 13:04:52 -0700498 boolean isKeepLppProfile = false;
Wink Savillea374c3d2014-11-11 11:48:04 -0800499 if (!TextUtils.isEmpty(mccMnc)) {
Joe Onorato0c484102016-02-01 18:04:24 -0800500 if (DEBUG) Log.d(TAG, "SIM MCC/MNC is available: " + mccMnc);
Wink Savillea374c3d2014-11-11 11:48:04 -0800501 synchronized (mLock) {
Ecco Park4fa1ab72016-10-24 13:04:52 -0700502 if (configManager != null) {
503 PersistableBundle b = configManager.getConfig();
Wyatt Rileya8ce2252017-09-01 13:31:17 -0700504 if (b != null) {
505 isKeepLppProfile =
Meng Wang19b214d2018-11-07 12:14:39 -0800506 b.getBoolean(CarrierConfigManager.Gps.KEY_PERSIST_LPP_MODE_BOOL);
Wyatt Rileya8ce2252017-09-01 13:31:17 -0700507 }
Ecco Park4fa1ab72016-10-24 13:04:52 -0700508 }
509 if (isKeepLppProfile) {
510 // load current properties for the carrier
Anil Admald71cf142018-12-21 14:59:36 -0800511 mGnssConfiguration.loadPropertiesFromCarrierConfig();
512 String lpp_profile = mGnssConfiguration.getLppProfile();
Ecco Park4fa1ab72016-10-24 13:04:52 -0700513 // set the persist property LPP_PROFILE for the value
Ecco Park8eec7442017-08-04 16:21:59 -0700514 if (lpp_profile != null) {
Anil Admald71cf142018-12-21 14:59:36 -0800515 SystemProperties.set(GnssConfiguration.LPP_PROFILE, lpp_profile);
Ecco Park8eec7442017-08-04 16:21:59 -0700516 }
Ecco Park624ac3c2016-07-18 14:08:05 -0700517 } else {
Ecco Park4fa1ab72016-10-24 13:04:52 -0700518 // reset the persist property
Anil Admald71cf142018-12-21 14:59:36 -0800519 SystemProperties.set(GnssConfiguration.LPP_PROFILE, "");
Ecco Park624ac3c2016-07-18 14:08:05 -0700520 }
Anil Admald71cf142018-12-21 14:59:36 -0800521 reloadGpsProperties();
Wink Savillea374c3d2014-11-11 11:48:04 -0800522 mNIHandler.setSuplEsEnabled(mSuplEsEnabled);
523 }
524 } else {
Joe Onorato0c484102016-02-01 18:04:24 -0800525 if (DEBUG) Log.d(TAG, "SIM MCC/MNC is still not available");
Wink Savillea374c3d2014-11-11 11:48:04 -0800526 }
527 }
528
David Christied4edf4c2014-08-12 15:22:27 -0700529 private void updateLowPowerMode() {
Adam Lesinski87c17df2015-05-27 13:24:13 -0700530 // Disable GPS if we are in device idle mode.
531 boolean disableGps = mPowerManager.isDeviceIdleMode();
jackqdyulei455e90a2017-02-09 15:29:16 -0800532 final PowerSaveState result =
533 mPowerManager.getPowerSaveState(ServiceType.GPS);
534 switch (result.gpsMode) {
Makoto Onuki57f0f552017-12-11 12:22:18 -0800535 case PowerManager.LOCATION_MODE_GPS_DISABLED_WHEN_SCREEN_OFF:
Adam Lesinski87c17df2015-05-27 13:24:13 -0700536 // If we are in battery saver mode and the screen is off, disable GPS.
jackqdyulei455e90a2017-02-09 15:29:16 -0800537 disableGps |= result.batterySaverEnabled && !mPowerManager.isInteractive();
David Christied4edf4c2014-08-12 15:22:27 -0700538 break;
David Christied4edf4c2014-08-12 15:22:27 -0700539 }
540 if (disableGps != mDisableGps) {
541 mDisableGps = disableGps;
542 updateRequirements();
543 }
544 }
545
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800546 public static boolean isSupported() {
547 return native_is_supported();
548 }
549
Anil Admald71cf142018-12-21 14:59:36 -0800550 private void reloadGpsProperties() {
551 mGnssConfiguration.reloadGpsProperties();
552 setSuplHostPort();
Tsuwei Chen52617bb2014-08-25 11:49:11 -0700553 // TODO: we should get rid of C2K specific setting.
Anil Admald71cf142018-12-21 14:59:36 -0800554 mC2KServerHost = mGnssConfiguration.getC2KHost();
555 mC2KServerPort = mGnssConfiguration.getC2KPort(TCP_MIN_PORT);
556 mNIHandler.setEmergencyExtensionSeconds(mGnssConfiguration.getEsExtensionSec());
557 mSuplEsEnabled = mGnssConfiguration.getSuplEs(0) == 1;
Colin Cross7c030ed2014-01-28 09:33:53 -0800558 }
559
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700560 public GnssLocationProvider(Context context, LocationProviderManager locationProviderManager,
Victoria Lease5cd731a2012-12-19 15:04:21 -0800561 Looper looper) {
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700562 super(locationProviderManager, true);
563
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800564 mContext = context;
Mike Lockwood63598a02010-02-24 11:52:59 -0500565
Mike Lockwood0528b9b2009-05-07 10:12:54 -0400566 // Create a wake lock
David Christied4edf4c2014-08-12 15:22:27 -0700567 mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
568 mWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, WAKELOCK_KEY);
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700569 mWakeLock.setReferenceCounted(true);
Mike Lockwood0528b9b2009-05-07 10:12:54 -0400570
Wei Wangb71c0492017-05-01 20:24:19 -0700571 // Create a separate wake lock for xtra downloader as it may be released due to timeout.
572 mDownloadXtraWakeLock = mPowerManager.newWakeLock(
573 PowerManager.PARTIAL_WAKE_LOCK, DOWNLOAD_EXTRA_WAKELOCK_KEY);
574 mDownloadXtraWakeLock.setReferenceCounted(true);
575
gomo48f1a642017-11-10 20:35:46 -0800576 mAlarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
Mike Lockwood29c84342009-05-06 14:01:15 -0400577 mWakeupIntent = PendingIntent.getBroadcast(mContext, 0, new Intent(ALARM_WAKEUP), 0);
Mike Lockwood0632ca72009-05-14 15:51:03 -0400578 mTimeoutIntent = PendingIntent.getBroadcast(mContext, 0, new Intent(ALARM_TIMEOUT), 0);
Mike Lockwood29c84342009-05-06 14:01:15 -0400579
Anil Admal50ba15e2018-11-01 16:42:42 -0700580 mNetworkConnectivityHandler = new GnssNetworkConnectivityHandler(
581 context,
582 GnssLocationProvider.this::onNetworkAvailable,
583 looper);
Mike Lockwood58bda982009-04-14 16:25:07 -0400584
Dianne Hackborna06de0f2012-12-11 16:34:47 -0800585 // App ops service to keep track of who is accessing the GPS
Svet Ganovf7b47252018-02-26 11:11:27 -0800586 mAppOps = mContext.getSystemService(AppOpsManager.class);
Dianne Hackborna06de0f2012-12-11 16:34:47 -0800587
Mike Lockwood2f82c4e2009-04-17 08:24:10 -0400588 // Battery statistics service to be notified when GPS turns on or off
Dianne Hackborn91268cf2013-06-13 19:06:50 -0700589 mBatteryStats = IBatteryStats.Stub.asInterface(ServiceManager.getService(
590 BatteryStats.SERVICE_NAME));
Mike Lockwood2f82c4e2009-04-17 08:24:10 -0400591
destradaafb23c672015-04-16 14:01:27 -0700592 // Construct internal handler
593 mHandler = new ProviderHandler(looper);
594
595 // Load GPS configuration and register listeners in the background:
596 // some operations, such as opening files and registering broadcast receivers, can take a
597 // relative long time, so the ctor() is kept to create objects needed by this instance,
598 // while IO initialization and registration is delegated to our internal handler
599 // this approach is just fine because events are posted to our handler anyway
Anil Admald71cf142018-12-21 14:59:36 -0800600 mGnssConfiguration = new GnssConfiguration(mContext);
destradaafb23c672015-04-16 14:01:27 -0700601 sendMessage(INITIALIZE_HANDLER, 0, null);
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400602
Tsuwei Chen3324e952014-09-07 01:30:42 -0700603 // Create a GPS net-initiated handler.
604 mNIHandler = new GpsNetInitiatedHandler(context,
gomo48f1a642017-11-10 20:35:46 -0800605 mNetInitiatedListener,
606 mSuplEsEnabled);
Tsuwei Chen3324e952014-09-07 01:30:42 -0700607
Anil Admal75b9fd62018-11-28 11:22:50 -0800608 mGnssStatusListenerHelper = new GnssStatusListenerHelper(mContext, mHandler) {
destradaa6568d702014-10-27 12:47:41 -0700609 @Override
610 protected boolean isAvailableInPlatform() {
destradaa13a60b02015-01-15 18:36:01 -0800611 return isSupported();
destradaa6568d702014-10-27 12:47:41 -0700612 }
613
614 @Override
615 protected boolean isGpsEnabled() {
616 return isEnabled();
617 }
618 };
619
Yu-Han Yang8de21502018-04-23 01:40:25 -0700620 mGnssMeasurementsProvider = new GnssMeasurementsProvider(mContext, mHandler) {
destradaa6568d702014-10-27 12:47:41 -0700621 @Override
622 protected boolean isGpsEnabled() {
623 return isEnabled();
624 }
625 };
626
Anil Admal75b9fd62018-11-28 11:22:50 -0800627 mGnssNavigationMessageProvider = new GnssNavigationMessageProvider(mContext, mHandler) {
destradaa6568d702014-10-27 12:47:41 -0700628 @Override
destradaa6568d702014-10-27 12:47:41 -0700629 protected boolean isGpsEnabled() {
630 return isEnabled();
631 }
632 };
Yu-Han Yanga1862b52018-02-20 17:05:59 -0800633
Anil Admal50ba15e2018-11-01 16:42:42 -0700634 mGnssMetrics = new GnssMetrics(mBatteryStats);
Yu-Han Yang66c7ea92018-03-11 17:17:15 -0700635 mNtpTimeHelper = new NtpTimeHelper(mContext, looper, this);
636 mGnssSatelliteBlacklistHelper = new GnssSatelliteBlacklistHelper(mContext,
637 looper, this);
638 mHandler.post(mGnssSatelliteBlacklistHelper::updateSatelliteBlacklist);
Yu-Han Yang3557cc72018-03-21 12:48:36 -0700639 mGnssBatchingProvider = new GnssBatchingProvider();
Yu-Han Yang6dc9f052018-12-04 17:11:24 -0800640 mGnssGeofenceProvider = new GnssGeofenceProvider();
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400641
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700642 IntentFilter intentFilter = new IntentFilter();
643 intentFilter.addAction(Intent.ACTION_SHUTDOWN);
644 mContext.registerReceiverAsUser(new BroadcastReceiver() {
645 @Override
646 public void onReceive(Context context, Intent intent) {
647 if (getSendingUserId() == UserHandle.USER_ALL) {
648 mEnabled = false;
649 handleDisable();
650 }
651 }
652 }, UserHandle.ALL, intentFilter, null, mHandler);
Mike Lockwoodd03ff942010-02-09 08:46:14 -0500653
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700654 setProperties(PROPERTIES);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800655 }
656
Yu-Han Yanga1862b52018-02-20 17:05:59 -0800657 /**
658 * Implements {@link InjectNtpTimeCallback#injectTime}
659 */
660 @Override
661 public void injectTime(long time, long timeReference, int uncertainty) {
662 native_inject_time(time, timeReference, uncertainty);
663 }
664
Anil Admal50ba15e2018-11-01 16:42:42 -0700665 /**
666 * Implements {@link GnssNetworkConnectivityHandler.GnssNetworkListener#onNetworkAvailable()}
667 */
668 private void onNetworkAvailable() {
669 mNtpTimeHelper.onNetworkAvailable();
670 if (mDownloadXtraDataPending == STATE_PENDING_NETWORK) {
671 if (mSupportsXtra) {
672 // Download only if supported, (prevents an unneccesary on-boot
673 // download)
674 xtraDownloadRequest();
destradaaef752b62015-04-17 13:10:47 -0700675 }
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400676 }
677 }
Yu-Han Yang8de21502018-04-23 01:40:25 -0700678
Yu-Han Yange7baef32018-02-09 13:58:17 -0800679 private void handleRequestLocation(boolean independentFromGnss) {
680 if (isRequestLocationRateLimited()) {
681 if (DEBUG) {
682 Log.d(TAG, "RequestLocation is denied due to too frequent requests.");
683 }
684 return;
685 }
Yu-Han Yang74041ff2018-04-06 15:57:31 -0700686 ContentResolver resolver = mContext.getContentResolver();
687 long durationMillis = Settings.Global.getLong(
688 resolver,
689 Settings.Global.GNSS_HAL_LOCATION_REQUEST_DURATION_MILLIS,
690 LOCATION_UPDATE_DURATION_MILLIS);
691 if (durationMillis == 0) {
692 Log.i(TAG, "GNSS HAL location request is disabled by Settings.");
693 return;
694 }
Yu-Han Yange7baef32018-02-09 13:58:17 -0800695
696 LocationManager locationManager = (LocationManager) mContext.getSystemService(
697 Context.LOCATION_SERVICE);
Yu-Han Yang07561382018-02-21 13:08:37 -0800698 String provider;
699 LocationChangeListener locationListener;
Yu-Han Yange7baef32018-02-09 13:58:17 -0800700
701 if (independentFromGnss) {
702 // For fast GNSS TTFF
Yu-Han Yang07561382018-02-21 13:08:37 -0800703 provider = LocationManager.NETWORK_PROVIDER;
704 locationListener = mNetworkLocationListener;
Yu-Han Yange7baef32018-02-09 13:58:17 -0800705 } else {
706 // For Device-Based Hybrid (E911)
Yu-Han Yang07561382018-02-21 13:08:37 -0800707 provider = LocationManager.FUSED_PROVIDER;
708 locationListener = mFusedLocationListener;
Yu-Han Yange7baef32018-02-09 13:58:17 -0800709 }
Yu-Han Yang07561382018-02-21 13:08:37 -0800710
711 Log.i(TAG,
Yu-Han Yang74041ff2018-04-06 15:57:31 -0700712 String.format(
713 "GNSS HAL Requesting location updates from %s provider for %d millis.",
714 provider, durationMillis));
Yu-Han Yange684dda2018-05-24 10:29:39 -0700715 try {
716 locationManager.requestLocationUpdates(provider,
717 LOCATION_UPDATE_MIN_TIME_INTERVAL_MILLIS, /*minDistance=*/ 0,
718 locationListener, mHandler.getLooper());
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700719 locationListener.mNumLocationUpdateRequest++;
Yu-Han Yange684dda2018-05-24 10:29:39 -0700720 mHandler.postDelayed(() -> {
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700721 if (--locationListener.mNumLocationUpdateRequest == 0) {
Yu-Han Yange684dda2018-05-24 10:29:39 -0700722 Log.i(TAG,
723 String.format("Removing location updates from %s provider.", provider));
724 locationManager.removeUpdates(locationListener);
725 }
726 }, durationMillis);
727 } catch (IllegalArgumentException e) {
728 Log.w(TAG, "Unable to request location.", e);
729 }
Yu-Han Yange7baef32018-02-09 13:58:17 -0800730 }
731
732 private void injectBestLocation(Location location) {
733 int gnssLocationFlags = LOCATION_HAS_LAT_LONG |
734 (location.hasAltitude() ? LOCATION_HAS_ALTITUDE : 0) |
735 (location.hasSpeed() ? LOCATION_HAS_SPEED : 0) |
736 (location.hasBearing() ? LOCATION_HAS_BEARING : 0) |
737 (location.hasAccuracy() ? LOCATION_HAS_HORIZONTAL_ACCURACY : 0) |
738 (location.hasVerticalAccuracy() ? LOCATION_HAS_VERTICAL_ACCURACY : 0) |
739 (location.hasSpeedAccuracy() ? LOCATION_HAS_SPEED_ACCURACY : 0) |
740 (location.hasBearingAccuracy() ? LOCATION_HAS_BEARING_ACCURACY : 0);
741
742 double latitudeDegrees = location.getLatitude();
743 double longitudeDegrees = location.getLongitude();
744 double altitudeMeters = location.getAltitude();
745 float speedMetersPerSec = location.getSpeed();
746 float bearingDegrees = location.getBearing();
747 float horizontalAccuracyMeters = location.getAccuracy();
748 float verticalAccuracyMeters = location.getVerticalAccuracyMeters();
749 float speedAccuracyMetersPerSecond = location.getSpeedAccuracyMetersPerSecond();
750 float bearingAccuracyDegrees = location.getBearingAccuracyDegrees();
751 long timestamp = location.getTime();
752 native_inject_best_location(gnssLocationFlags, latitudeDegrees, longitudeDegrees,
753 altitudeMeters, speedMetersPerSec, bearingDegrees, horizontalAccuracyMeters,
754 verticalAccuracyMeters, speedAccuracyMetersPerSecond, bearingAccuracyDegrees,
755 timestamp);
756 }
757
Yu-Han Yange7baef32018-02-09 13:58:17 -0800758 /** Returns true if the location request is too frequent. */
759 private boolean isRequestLocationRateLimited() {
760 // TODO(b/73198123): implement exponential backoff.
761 return false;
762 }
763
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400764 private void handleDownloadXtraData() {
Wyatt Riley0d6e54e22016-10-05 12:03:03 -0700765 if (!mSupportsXtra) {
766 // native code reports xtra not supported, don't try
767 Log.d(TAG, "handleDownloadXtraData() called when Xtra not supported");
768 return;
769 }
Kevin Tang40e1baf2012-01-10 14:32:44 -0800770 if (mDownloadXtraDataPending == STATE_DOWNLOADING) {
771 // already downloading data
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400772 return;
773 }
Anil Admal50ba15e2018-11-01 16:42:42 -0700774 if (!mNetworkConnectivityHandler.isDataNetworkConnected()) {
Kevin Tang40e1baf2012-01-10 14:32:44 -0800775 // try again when network is up
776 mDownloadXtraDataPending = STATE_PENDING_NETWORK;
777 return;
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400778 }
Kevin Tang40e1baf2012-01-10 14:32:44 -0800779 mDownloadXtraDataPending = STATE_DOWNLOADING;
780
Jeff Brown028872f2012-08-25 13:07:01 -0700781 // hold wake lock while task runs
Wei Wangb71c0492017-05-01 20:24:19 -0700782 mDownloadXtraWakeLock.acquire(DOWNLOAD_XTRA_DATA_TIMEOUT_MS);
Lifu Tangcbd2a142016-06-22 10:57:55 -0700783 Log.i(TAG, "WakeLock acquired by handleDownloadXtraData()");
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700784 AsyncTask.THREAD_POOL_EXECUTOR.execute(() -> {
Anil Admald71cf142018-12-21 14:59:36 -0800785 GpsXtraDownloader xtraDownloader = new GpsXtraDownloader(
786 mGnssConfiguration.getProperties());
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700787 byte[] data = xtraDownloader.downloadXtraData();
788 if (data != null) {
789 if (DEBUG) Log.d(TAG, "calling native_inject_xtra_data");
790 native_inject_xtra_data(data, data.length);
791 mXtraBackOff.reset();
792 }
Kevin Tang40e1baf2012-01-10 14:32:44 -0800793
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700794 sendMessage(DOWNLOAD_XTRA_DATA_FINISHED, 0, null);
Kevin Tang40e1baf2012-01-10 14:32:44 -0800795
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700796 if (data == null) {
797 // try again later
798 // since this is delayed and not urgent we do not hold a wake lock here
799 mHandler.sendEmptyMessageDelayed(DOWNLOAD_XTRA_DATA,
800 mXtraBackOff.nextBackoffMillis());
801 }
Kevin Tang40e1baf2012-01-10 14:32:44 -0800802
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700803 // Release wake lock held by task, synchronize on mLock in case multiple
804 // download tasks overrun.
805 synchronized (mLock) {
806 if (mDownloadXtraWakeLock.isHeld()) {
807 // This wakelock may have time-out, if a timeout was specified.
808 // Catch (and ignore) any timeout exceptions.
809 try {
810 mDownloadXtraWakeLock.release();
811 if (DEBUG) Log.d(TAG, "WakeLock released by handleDownloadXtraData()");
812 } catch (Exception e) {
813 Log.i(TAG, "Wakelock timeout & release race exception in "
814 + "handleDownloadXtraData()", e);
Wei Wangb71c0492017-05-01 20:24:19 -0700815 }
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700816 } else {
817 Log.e(TAG, "WakeLock expired before release in "
818 + "handleDownloadXtraData()");
Wei Wangc5706f62017-04-18 11:26:26 -0700819 }
Jeff Brown028872f2012-08-25 13:07:01 -0700820 }
Kevin Tang40e1baf2012-01-10 14:32:44 -0800821 });
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800822 }
823
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400824 private void handleUpdateLocation(Location location) {
Mike Lockwoodd26ce0d2009-06-11 12:25:46 -0400825 if (location.hasAccuracy()) {
826 native_inject_location(location.getLatitude(), location.getLongitude(),
827 location.getAccuracy());
828 }
Mike Lockwoodfd6e5f02009-05-21 11:28:20 -0400829 }
830
Anil Admald71cf142018-12-21 14:59:36 -0800831 private void setSuplHostPort() {
832 mSuplServerHost = mGnssConfiguration.getSuplHost();
833 mSuplServerPort = mGnssConfiguration.getSuplPort(TCP_MIN_PORT);
Tsuwei Chen678c13c2014-09-22 17:48:41 -0700834 if (mSuplServerHost != null
835 && mSuplServerPort > TCP_MIN_PORT
836 && mSuplServerPort <= TCP_MAX_PORT) {
Anil Admalc70344b2018-11-16 14:22:38 -0800837 native_set_agps_server(GnssNetworkConnectivityHandler.AGPS_TYPE_SUPL,
838 mSuplServerHost, mSuplServerPort);
Tsuwei Chen678c13c2014-09-22 17:48:41 -0700839 }
Tsuwei Chen52617bb2014-08-25 11:49:11 -0700840 }
841
Tsuwei Chen462bcd82014-09-17 12:28:49 -0700842 /**
843 * Checks what SUPL mode to use, according to the AGPS mode as well as the
844 * allowed mode from properties.
845 *
Tsuwei Chen462bcd82014-09-17 12:28:49 -0700846 * @param agpsEnabled whether AGPS is enabled by settings value
gomo48f1a642017-11-10 20:35:46 -0800847 * @param singleShot whether "singleshot" is needed
Tsuwei Chen462bcd82014-09-17 12:28:49 -0700848 * @return SUPL mode (MSA vs MSB vs STANDALONE)
849 */
Anil Admald71cf142018-12-21 14:59:36 -0800850 private int getSuplMode(boolean agpsEnabled, boolean singleShot) {
Tsuwei Chen462bcd82014-09-17 12:28:49 -0700851 if (agpsEnabled) {
Anil Admald71cf142018-12-21 14:59:36 -0800852 int suplMode = mGnssConfiguration.getSuplMode(0);
853 if (suplMode == 0) {
854 return GPS_POSITION_MODE_STANDALONE;
Tsuwei Chen462bcd82014-09-17 12:28:49 -0700855 }
Anil Admald71cf142018-12-21 14:59:36 -0800856
destradaabfb3bdb2015-04-29 14:42:35 -0700857 // MS-Based is the preferred mode for Assisted-GPS position computation, so we favor
858 // such mode when it is available
859 if (hasCapability(GPS_CAPABILITY_MSB) && (suplMode & AGPS_SUPL_MODE_MSB) != 0) {
860 return GPS_POSITION_MODE_MS_BASED;
861 }
862 // for now, just as the legacy code did, we fallback to MS-Assisted if it is available,
863 // do fallback only for single-shot requests, because it is too expensive to do for
864 // periodic requests as well
Tsuwei Chen462bcd82014-09-17 12:28:49 -0700865 if (singleShot
866 && hasCapability(GPS_CAPABILITY_MSA)
867 && (suplMode & AGPS_SUPL_MODE_MSA) != 0) {
868 return GPS_POSITION_MODE_MS_ASSISTED;
Tsuwei Chen462bcd82014-09-17 12:28:49 -0700869 }
870 }
871 return GPS_POSITION_MODE_STANDALONE;
872 }
873
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400874 private void handleEnable() {
875 if (DEBUG) Log.d(TAG, "handleEnable");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800876
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700877 boolean enabled = native_init();
878
879 if (enabled) {
Mike Lockwood1a1cd3a2010-08-17 07:42:54 -0400880 mSupportsXtra = native_supports_xtra();
Tsuwei Chen678c13c2014-09-22 17:48:41 -0700881
882 // TODO: remove the following native calls if we can make sure they are redundant.
Mike Lockwood734d6032009-07-28 18:30:25 -0700883 if (mSuplServerHost != null) {
Anil Admalc70344b2018-11-16 14:22:38 -0800884 native_set_agps_server(GnssNetworkConnectivityHandler.AGPS_TYPE_SUPL,
885 mSuplServerHost, mSuplServerPort);
Mike Lockwood734d6032009-07-28 18:30:25 -0700886 }
887 if (mC2KServerHost != null) {
Anil Admalc70344b2018-11-16 14:22:38 -0800888 native_set_agps_server(GnssNetworkConnectivityHandler.AGPS_TYPE_C2K,
889 mC2KServerHost, mC2KServerPort);
Mike Lockwood734d6032009-07-28 18:30:25 -0700890 }
destradaa13a60b02015-01-15 18:36:01 -0800891
Lifu Tang818aa2c2016-02-01 01:52:00 -0800892 mGnssMeasurementsProvider.onGpsEnabledChanged();
893 mGnssNavigationMessageProvider.onGpsEnabledChanged();
Yu-Han Yang3557cc72018-03-21 12:48:36 -0700894 mGnssBatchingProvider.enable();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800895 } else {
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700896 synchronized (mLock) {
897 mEnabled = false;
898 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800899 Log.w(TAG, "Failed to enable location provider");
900 }
901 }
902
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400903 private void handleDisable() {
Mike Lockwood89096312010-03-24 10:14:55 -0400904 if (DEBUG) Log.d(TAG, "handleDisable");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800905
David Christie3bc26142013-12-19 14:53:44 -0800906 updateClientUids(new WorkSource());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800907 stopNavigating();
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700908 mAlarmManager.cancel(mWakeupIntent);
909 mAlarmManager.cancel(mTimeoutIntent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800910
Yu-Han Yang3557cc72018-03-21 12:48:36 -0700911 mGnssBatchingProvider.disable();
Mike Lockwoodcf1d8cb2010-01-20 10:14:54 -0500912 // do this before releasing wakelock
913 native_cleanup();
destradaa13a60b02015-01-15 18:36:01 -0800914
Lifu Tang818aa2c2016-02-01 01:52:00 -0800915 mGnssMeasurementsProvider.onGpsEnabledChanged();
916 mGnssNavigationMessageProvider.onGpsEnabledChanged();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800917 }
918
Mike Lockwoodd03ff942010-02-09 08:46:14 -0500919 public boolean isEnabled() {
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700920 synchronized (mLock) {
921 return mEnabled;
922 }
Mike Lockwoodd03ff942010-02-09 08:46:14 -0500923 }
924
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700925 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800926 public int getStatus(Bundle extras) {
Wyatt Rileyc7067412018-02-07 15:50:35 -0800927 mLocationExtras.setBundle(extras);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800928 return mStatus;
929 }
930
Wyatt Rileyc7067412018-02-07 15:50:35 -0800931 private void updateStatus(int status) {
932 if (status != mStatus) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800933 mStatus = status;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800934 mStatusUpdateTime = SystemClock.elapsedRealtime();
935 }
936 }
937
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700938 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800939 public long getStatusUpdateTime() {
940 return mStatusUpdateTime;
941 }
942
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700943 @Override
944 public void setRequest(ProviderRequest request, WorkSource source) {
945 sendMessage(SET_REQUEST, 0, new GpsRequest(request, source));
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400946 }
947
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700948 private void handleSetRequest(ProviderRequest request, WorkSource source) {
David Christied4edf4c2014-08-12 15:22:27 -0700949 mProviderRequest = request;
950 mWorkSource = source;
951 updateRequirements();
952 }
953
954 // Called when the requirements for GPS may have changed
955 private void updateRequirements() {
956 if (mProviderRequest == null || mWorkSource == null) {
957 return;
958 }
959
Stan Chesnutt1d72d8c2013-04-15 19:18:02 -0700960 boolean singleShot = false;
961
962 // see if the request is for a single update
David Christied4edf4c2014-08-12 15:22:27 -0700963 if (mProviderRequest.locationRequests != null
964 && mProviderRequest.locationRequests.size() > 0) {
Stan Chesnutt1d72d8c2013-04-15 19:18:02 -0700965 // if any request has zero or more than one updates
966 // requested, then this is not single-shot mode
967 singleShot = true;
968
David Christied4edf4c2014-08-12 15:22:27 -0700969 for (LocationRequest lr : mProviderRequest.locationRequests) {
Stan Chesnutt1d72d8c2013-04-15 19:18:02 -0700970 if (lr.getNumUpdates() != 1) {
971 singleShot = false;
972 }
973 }
974 }
975
David Christied4edf4c2014-08-12 15:22:27 -0700976 if (DEBUG) Log.d(TAG, "setRequest " + mProviderRequest);
Dante Russo260d6672016-06-20 11:11:59 -0700977 if (mProviderRequest.reportLocation && !mDisableGps && isEnabled()) {
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700978 // update client uids
David Christied4edf4c2014-08-12 15:22:27 -0700979 updateClientUids(mWorkSource);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800980
David Christied4edf4c2014-08-12 15:22:27 -0700981 mFixInterval = (int) mProviderRequest.interval;
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700982 mLowPowerMode = mProviderRequest.lowPowerMode;
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700983 // check for overflow
David Christied4edf4c2014-08-12 15:22:27 -0700984 if (mFixInterval != mProviderRequest.interval) {
985 Log.w(TAG, "interval overflow: " + mProviderRequest.interval);
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700986 mFixInterval = Integer.MAX_VALUE;
987 }
Mike Lockwood03ca2162010-04-01 08:10:09 -0700988
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700989 // apply request to GPS engine
Mike Lockwood04598b62010-04-14 17:17:24 -0400990 if (mStarted && hasCapability(GPS_CAPABILITY_SCHEDULING)) {
gomo48f1a642017-11-10 20:35:46 -0800991 // change period and/or lowPowerMode
Yu-Han Yangc8b9ff72018-04-17 00:47:24 -0700992 if (!setPositionMode(mPositionMode, GPS_POSITION_RECURRENCE_PERIODIC,
gomo48f1a642017-11-10 20:35:46 -0800993 mFixInterval, 0, 0, mLowPowerMode)) {
994 Log.e(TAG, "set_position_mode failed in updateRequirements");
Mike Lockwood04598b62010-04-14 17:17:24 -0400995 }
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700996 } else if (!mStarted) {
997 // start GPS
Stan Chesnutt1d72d8c2013-04-15 19:18:02 -0700998 startNavigating(singleShot);
gomo300b2402017-12-13 19:04:12 -0800999 } else {
1000 // GNSS Engine is already ON, but no GPS_CAPABILITY_SCHEDULING
1001 mAlarmManager.cancel(mTimeoutIntent);
1002 if (mFixInterval >= NO_FIX_TIMEOUT) {
1003 // set timer to give up if we do not receive a fix within NO_FIX_TIMEOUT
1004 // and our fix interval is not short
1005 mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001006 SystemClock.elapsedRealtime() + NO_FIX_TIMEOUT, mTimeoutIntent);
1007 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001008 }
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001009 } else {
Dianne Hackborn002a54e2013-01-10 17:34:55 -08001010 updateClientUids(new WorkSource());
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001011
1012 stopNavigating();
1013 mAlarmManager.cancel(mWakeupIntent);
1014 mAlarmManager.cancel(mTimeoutIntent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001015 }
1016 }
1017
Yu-Han Yangc8b9ff72018-04-17 00:47:24 -07001018 private boolean setPositionMode(int mode, int recurrence, int minInterval,
1019 int preferredAccuracy, int preferredTime, boolean lowPowerMode) {
1020 GnssPositionMode positionMode = new GnssPositionMode(mode, recurrence, minInterval,
1021 preferredAccuracy, preferredTime, lowPowerMode);
1022 if (mLastPositionMode != null && mLastPositionMode.equals(positionMode)) {
1023 return true;
1024 }
1025
1026 boolean result = native_set_position_mode(mode, recurrence, minInterval,
1027 preferredAccuracy, preferredTime, lowPowerMode);
1028 if (result) {
1029 mLastPositionMode = positionMode;
1030 } else {
1031 mLastPositionMode = null;
1032 }
1033 return result;
1034 }
1035
Dianne Hackborn002a54e2013-01-10 17:34:55 -08001036 private void updateClientUids(WorkSource source) {
Narayan Kamath32684dd2018-01-08 17:32:51 +00001037 if (source.equals(mClientSource)) {
Victoria Leaseea78b852013-01-15 10:39:28 -08001038 return;
1039 }
Dianne Hackborn002a54e2013-01-10 17:34:55 -08001040
Narayan Kamath32684dd2018-01-08 17:32:51 +00001041 // (1) Inform BatteryStats that the list of IDs we're tracking changed.
1042 try {
1043 mBatteryStats.noteGpsChanged(mClientSource, source);
1044 } catch (RemoteException e) {
1045 Log.w(TAG, "RemoteException", e);
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001046 }
1047
Narayan Kamath32684dd2018-01-08 17:32:51 +00001048 // (2) Inform AppOps service about the list of changes to UIDs.
1049
1050 List<WorkChain>[] diffs = WorkSource.diffChains(mClientSource, source);
1051 if (diffs != null) {
1052 List<WorkChain> newChains = diffs[0];
1053 List<WorkChain> goneChains = diffs[1];
1054
1055 if (newChains != null) {
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001056 for (WorkChain newChain : newChains) {
Svet Ganovf7b47252018-02-26 11:11:27 -08001057 mAppOps.startOpNoThrow(AppOpsManager.OP_GPS, newChain.getAttributionUid(),
1058 newChain.getAttributionTag());
Narayan Kamath32684dd2018-01-08 17:32:51 +00001059 }
1060 }
1061
1062 if (goneChains != null) {
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001063 for (WorkChain goneChain : goneChains) {
Svet Ganovf7b47252018-02-26 11:11:27 -08001064 mAppOps.finishOp(AppOpsManager.OP_GPS, goneChain.getAttributionUid(),
1065 goneChain.getAttributionTag());
Narayan Kamath32684dd2018-01-08 17:32:51 +00001066 }
1067 }
1068
1069 mClientSource.transferWorkChains(source);
1070 }
1071
1072 // Update the flat UIDs and names list and inform app-ops of all changes.
1073 WorkSource[] changes = mClientSource.setReturningDiffs(source);
1074 if (changes != null) {
1075 WorkSource newWork = changes[0];
1076 WorkSource goneWork = changes[1];
1077
1078 // Update sources that were not previously tracked.
1079 if (newWork != null) {
1080 for (int i = 0; i < newWork.size(); i++) {
Svet Ganovf7b47252018-02-26 11:11:27 -08001081 mAppOps.startOpNoThrow(AppOpsManager.OP_GPS,
1082 newWork.get(i), newWork.getName(i));
Narayan Kamath32684dd2018-01-08 17:32:51 +00001083 }
1084 }
1085
1086 // Update sources that are no longer tracked.
1087 if (goneWork != null) {
1088 for (int i = 0; i < goneWork.size(); i++) {
Svet Ganovf7b47252018-02-26 11:11:27 -08001089 mAppOps.finishOp(AppOpsManager.OP_GPS, goneWork.get(i), goneWork.getName(i));
Dianne Hackborn2e418422009-06-22 20:00:17 -07001090 }
Mike Lockwood2f82c4e2009-04-17 08:24:10 -04001091 }
1092 }
1093 }
1094
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001095 @Override
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001096 public void sendExtraCommand(String command, Bundle extras) {
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001097
Mike Lockwood63aa5a62010-04-14 19:21:31 -04001098 long identity = Binder.clearCallingIdentity();
Peter Visontayb25db362017-11-01 18:18:12 +00001099 try {
Peter Visontayb25db362017-11-01 18:18:12 +00001100 if ("delete_aiding_data".equals(command)) {
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001101 deleteAidingData(extras);
Peter Visontayb25db362017-11-01 18:18:12 +00001102 } else if ("force_time_injection".equals(command)) {
1103 requestUtcTime();
Peter Visontayb25db362017-11-01 18:18:12 +00001104 } else if ("force_xtra_injection".equals(command)) {
1105 if (mSupportsXtra) {
1106 xtraDownloadRequest();
Peter Visontayb25db362017-11-01 18:18:12 +00001107 }
1108 } else {
1109 Log.w(TAG, "sendExtraCommand: unknown command " + command);
Mike Lockwood93bc44d2009-05-20 16:58:22 -04001110 }
Peter Visontayb25db362017-11-01 18:18:12 +00001111 } finally {
1112 Binder.restoreCallingIdentity(identity);
Mike Lockwood93bc44d2009-05-20 16:58:22 -04001113 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001114 }
1115
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001116 private void deleteAidingData(Bundle extras) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001117 int flags;
1118
1119 if (extras == null) {
1120 flags = GPS_DELETE_ALL;
1121 } else {
1122 flags = 0;
1123 if (extras.getBoolean("ephemeris")) flags |= GPS_DELETE_EPHEMERIS;
1124 if (extras.getBoolean("almanac")) flags |= GPS_DELETE_ALMANAC;
1125 if (extras.getBoolean("position")) flags |= GPS_DELETE_POSITION;
1126 if (extras.getBoolean("time")) flags |= GPS_DELETE_TIME;
1127 if (extras.getBoolean("iono")) flags |= GPS_DELETE_IONO;
1128 if (extras.getBoolean("utc")) flags |= GPS_DELETE_UTC;
1129 if (extras.getBoolean("health")) flags |= GPS_DELETE_HEALTH;
1130 if (extras.getBoolean("svdir")) flags |= GPS_DELETE_SVDIR;
1131 if (extras.getBoolean("svsteer")) flags |= GPS_DELETE_SVSTEER;
1132 if (extras.getBoolean("sadata")) flags |= GPS_DELETE_SADATA;
1133 if (extras.getBoolean("rti")) flags |= GPS_DELETE_RTI;
1134 if (extras.getBoolean("celldb-info")) flags |= GPS_DELETE_CELLDB_INFO;
1135 if (extras.getBoolean("all")) flags |= GPS_DELETE_ALL;
1136 }
1137
1138 if (flags != 0) {
1139 native_delete_aiding_data(flags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001140 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001141 }
1142
Stan Chesnutt1d72d8c2013-04-15 19:18:02 -07001143 private void startNavigating(boolean singleShot) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001144 if (!mStarted) {
Stan Chesnutt1d72d8c2013-04-15 19:18:02 -07001145 if (DEBUG) Log.d(TAG, "startNavigating, singleShot is " + singleShot);
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001146 mTimeToFirstFix = 0;
1147 mLastFixTime = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001148 mStarted = true;
Stan Chesnutt1d72d8c2013-04-15 19:18:02 -07001149 mSingleShot = singleShot;
Mike Lockwood03ca2162010-04-01 08:10:09 -07001150 mPositionMode = GPS_POSITION_MODE_STANDALONE;
Wyatt Riley5d5bac82016-11-01 07:05:16 -07001151 // Notify about suppressed output, if speed limit was previously exceeded.
1152 // Elsewhere, we check again with every speed output reported.
1153 if (mItarSpeedLimitExceeded) {
1154 Log.i(TAG, "startNavigating with ITAR limit in place. Output limited " +
1155 "until slow enough speed reported.");
1156 }
Mike Lockwood03ca2162010-04-01 08:10:09 -07001157
Tsuwei Chen462bcd82014-09-17 12:28:49 -07001158 boolean agpsEnabled =
1159 (Settings.Global.getInt(mContext.getContentResolver(),
gomo48f1a642017-11-10 20:35:46 -08001160 Settings.Global.ASSISTED_GPS_ENABLED, 1) != 0);
Anil Admald71cf142018-12-21 14:59:36 -08001161 mPositionMode = getSuplMode(agpsEnabled, singleShot);
Mike Lockwoodbcab8df2009-06-25 16:39:09 -04001162
Stan Chesnutt1d72d8c2013-04-15 19:18:02 -07001163 if (DEBUG) {
1164 String mode;
1165
gomo48f1a642017-11-10 20:35:46 -08001166 switch (mPositionMode) {
Stan Chesnutt1d72d8c2013-04-15 19:18:02 -07001167 case GPS_POSITION_MODE_STANDALONE:
1168 mode = "standalone";
1169 break;
1170 case GPS_POSITION_MODE_MS_ASSISTED:
1171 mode = "MS_ASSISTED";
1172 break;
1173 case GPS_POSITION_MODE_MS_BASED:
1174 mode = "MS_BASED";
1175 break;
1176 default:
1177 mode = "unknown";
1178 break;
1179 }
1180 Log.d(TAG, "setting position_mode to " + mode);
1181 }
1182
Mike Lockwood04598b62010-04-14 17:17:24 -04001183 int interval = (hasCapability(GPS_CAPABILITY_SCHEDULING) ? mFixInterval : 1000);
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001184 mLowPowerMode = mProviderRequest.lowPowerMode;
Yu-Han Yangc8b9ff72018-04-17 00:47:24 -07001185 if (!setPositionMode(mPositionMode, GPS_POSITION_RECURRENCE_PERIODIC,
gomo48f1a642017-11-10 20:35:46 -08001186 interval, 0, 0, mLowPowerMode)) {
Mike Lockwood04598b62010-04-14 17:17:24 -04001187 mStarted = false;
1188 Log.e(TAG, "set_position_mode failed in startNavigating()");
1189 return;
1190 }
1191 if (!native_start()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001192 mStarted = false;
1193 Log.e(TAG, "native_start failed in startNavigating()");
Mike Lockwood0632ca72009-05-14 15:51:03 -04001194 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001195 }
1196
1197 // reset SV count to zero
Wyatt Rileyc7067412018-02-07 15:50:35 -08001198 updateStatus(LocationProvider.TEMPORARILY_UNAVAILABLE);
1199 mLocationExtras.reset();
Yipeng Cao282b5942017-05-17 20:31:39 -07001200 mFixRequestTime = SystemClock.elapsedRealtime();
Mike Lockwood04598b62010-04-14 17:17:24 -04001201 if (!hasCapability(GPS_CAPABILITY_SCHEDULING)) {
1202 // set timer to give up if we do not receive a fix within NO_FIX_TIMEOUT
1203 // and our fix interval is not short
1204 if (mFixInterval >= NO_FIX_TIMEOUT) {
1205 mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
1206 SystemClock.elapsedRealtime() + NO_FIX_TIMEOUT, mTimeoutIntent);
1207 }
Mike Lockwood0632ca72009-05-14 15:51:03 -04001208 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001209 }
1210 }
1211
Mike Lockwood62a8fc12010-03-22 14:23:26 -04001212 private void stopNavigating() {
Mike Lockwood29c84342009-05-06 14:01:15 -04001213 if (DEBUG) Log.d(TAG, "stopNavigating");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001214 if (mStarted) {
1215 mStarted = false;
Stan Chesnutt1d72d8c2013-04-15 19:18:02 -07001216 mSingleShot = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001217 native_stop();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001218 mLastFixTime = 0;
Yu-Han Yanga50cd602018-08-28 12:33:24 -07001219 // native_stop() may reset the position mode in hardware.
1220 mLastPositionMode = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001221
1222 // reset SV count to zero
Wyatt Rileyc7067412018-02-07 15:50:35 -08001223 updateStatus(LocationProvider.TEMPORARILY_UNAVAILABLE);
1224 mLocationExtras.reset();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001225 }
1226 }
1227
Mike Lockwood0632ca72009-05-14 15:51:03 -04001228 private void hibernate() {
1229 // stop GPS until our next fix interval arrives
1230 stopNavigating();
Mike Lockwood0632ca72009-05-14 15:51:03 -04001231 mAlarmManager.cancel(mTimeoutIntent);
1232 mAlarmManager.cancel(mWakeupIntent);
1233 long now = SystemClock.elapsedRealtime();
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001234 mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, now + mFixInterval, mWakeupIntent);
Mike Lockwood04598b62010-04-14 17:17:24 -04001235 }
1236
1237 private boolean hasCapability(int capability) {
1238 return ((mEngineCapabilities & capability) != 0);
Mike Lockwood0632ca72009-05-14 15:51:03 -04001239 }
1240
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001241 @NativeEntryPoint
Wyatt Riley5d229832017-02-10 17:06:00 -08001242 private void reportLocation(boolean hasLatLong, Location location) {
Wyatt Riley26465d22018-02-12 13:44:24 -08001243 sendMessage(REPORT_LOCATION, hasLatLong ? 1 : 0, location);
1244 }
1245
1246 private void handleReportLocation(boolean hasLatLong, Location location) {
Wyatt Riley5d229832017-02-10 17:06:00 -08001247 if (location.hasSpeed()) {
1248 mItarSpeedLimitExceeded = location.getSpeed() > ITAR_SPEED_LIMIT_METERS_PER_SECOND;
Wyatt Riley5d5bac82016-11-01 07:05:16 -07001249 }
1250
1251 if (mItarSpeedLimitExceeded) {
1252 Log.i(TAG, "Hal reported a speed in excess of ITAR limit." +
1253 " GPS/GNSS Navigation output blocked.");
Siddharth Ray53ddc802018-03-16 12:01:52 -07001254 if (mStarted) {
1255 mGnssMetrics.logReceivedLocationStatus(false);
1256 }
Wyatt Riley5d5bac82016-11-01 07:05:16 -07001257 return; // No output of location allowed
1258 }
1259
Wyatt Riley5d229832017-02-10 17:06:00 -08001260 if (VERBOSE) Log.v(TAG, "reportLocation " + location.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001261
Wyatt Riley26465d22018-02-12 13:44:24 -08001262 // It would be nice to push the elapsed real-time timestamp
1263 // further down the stack, but this is still useful
1264 location.setElapsedRealtimeNanos(SystemClock.elapsedRealtimeNanos());
1265 location.setExtras(mLocationExtras.getBundle());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001266
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001267 reportLocation(location);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001268
Siddharth Ray53ddc802018-03-16 12:01:52 -07001269 if (mStarted) {
1270 mGnssMetrics.logReceivedLocationStatus(hasLatLong);
1271 if (hasLatLong) {
1272 if (location.hasAccuracy()) {
1273 mGnssMetrics.logPositionAccuracyMeters(location.getAccuracy());
1274 }
1275 if (mTimeToFirstFix > 0) {
1276 int timeBetweenFixes = (int) (SystemClock.elapsedRealtime() - mLastFixTime);
1277 mGnssMetrics.logMissedReports(mFixInterval, timeBetweenFixes);
1278 }
Siddharth Raybb608c82017-03-16 11:33:34 -07001279 }
1280 }
1281
Yipeng Cao282b5942017-05-17 20:31:39 -07001282 mLastFixTime = SystemClock.elapsedRealtime();
Hakan Gustavssonfa94ff02010-02-23 09:12:38 +01001283 // report time to first fix
Wyatt Riley5d229832017-02-10 17:06:00 -08001284 if (mTimeToFirstFix == 0 && hasLatLong) {
gomo48f1a642017-11-10 20:35:46 -08001285 mTimeToFirstFix = (int) (mLastFixTime - mFixRequestTime);
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001286 if (DEBUG) Log.d(TAG, "TTFF: " + mTimeToFirstFix);
Siddharth Ray53ddc802018-03-16 12:01:52 -07001287 if (mStarted) {
1288 mGnssMetrics.logTimeToFirstFixMilliSecs(mTimeToFirstFix);
1289 }
Hakan Gustavssonfa94ff02010-02-23 09:12:38 +01001290
1291 // notify status listeners
Anil Admal75b9fd62018-11-28 11:22:50 -08001292 mGnssStatusListenerHelper.onFirstFix(mTimeToFirstFix);
Hakan Gustavssonfa94ff02010-02-23 09:12:38 +01001293 }
1294
Stan Chesnutt1d72d8c2013-04-15 19:18:02 -07001295 if (mSingleShot) {
1296 stopNavigating();
1297 }
1298
Mike Lockwood15e3d0f2009-05-01 07:53:28 -04001299 if (mStarted && mStatus != LocationProvider.AVAILABLE) {
Wyatt Rileyc7067412018-02-07 15:50:35 -08001300 // For devices that use framework scheduling, a timer may be set to ensure we don't
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001301 // spend too much power searching for a location, when the requested update rate is
1302 // slow.
Wyatt Rileyc7067412018-02-07 15:50:35 -08001303 // As we just recievied a location, we'll cancel that timer.
Mike Lockwood04598b62010-04-14 17:17:24 -04001304 if (!hasCapability(GPS_CAPABILITY_SCHEDULING) && mFixInterval < NO_FIX_TIMEOUT) {
Mike Lockwoodb7be5442010-02-24 14:34:50 -05001305 mAlarmManager.cancel(mTimeoutIntent);
1306 }
1307
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001308 // send an intent to notify that the GPS is receiving fixes.
Mike Lockwood00b74272010-03-26 10:41:48 -04001309 Intent intent = new Intent(LocationManager.GPS_FIX_CHANGE_ACTION);
1310 intent.putExtra(LocationManager.EXTRA_GPS_ENABLED, true);
Dianne Hackborn5ac72a22012-08-29 18:32:08 -07001311 mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
Wyatt Rileyc7067412018-02-07 15:50:35 -08001312 updateStatus(LocationProvider.AVAILABLE);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001313 }
Mike Lockwood29c84342009-05-06 14:01:15 -04001314
gomo48f1a642017-11-10 20:35:46 -08001315 if (!hasCapability(GPS_CAPABILITY_SCHEDULING) && mStarted &&
1316 mFixInterval > GPS_POLLING_THRESHOLD_INTERVAL) {
Mike Lockwoodd53ba012010-04-15 20:41:26 -04001317 if (DEBUG) Log.d(TAG, "got fix, hibernating");
Mike Lockwood0632ca72009-05-14 15:51:03 -04001318 hibernate();
Mike Lockwood29c84342009-05-06 14:01:15 -04001319 }
gomo48f1a642017-11-10 20:35:46 -08001320 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001321
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001322 @NativeEntryPoint
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001323 private void reportStatus(int status) {
Mike Lockwoodb8d90332010-10-18 17:59:48 -04001324 if (DEBUG) Log.v(TAG, "reportStatus status: " + status);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001325
destradaaea8a8a62014-06-23 18:19:03 -07001326 boolean wasNavigating = mNavigating;
1327 switch (status) {
1328 case GPS_STATUS_SESSION_BEGIN:
1329 mNavigating = true;
destradaaea8a8a62014-06-23 18:19:03 -07001330 break;
1331 case GPS_STATUS_SESSION_END:
1332 mNavigating = false;
1333 break;
1334 case GPS_STATUS_ENGINE_ON:
destradaaea8a8a62014-06-23 18:19:03 -07001335 break;
1336 case GPS_STATUS_ENGINE_OFF:
destradaaea8a8a62014-06-23 18:19:03 -07001337 mNavigating = false;
1338 break;
1339 }
Mike Lockwooddbd6fd82009-12-07 18:43:36 -05001340
destradaaea8a8a62014-06-23 18:19:03 -07001341 if (wasNavigating != mNavigating) {
Anil Admal75b9fd62018-11-28 11:22:50 -08001342 mGnssStatusListenerHelper.onStatusChanged(mNavigating);
Mike Lockwoodcf1d8cb2010-01-20 10:14:54 -05001343
destradaaea8a8a62014-06-23 18:19:03 -07001344 // send an intent to notify that the GPS has been enabled or disabled
1345 Intent intent = new Intent(LocationManager.GPS_ENABLED_CHANGE_ACTION);
1346 intent.putExtra(LocationManager.EXTRA_GPS_ENABLED, mNavigating);
1347 mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001348 }
1349 }
1350
Wyatt Riley26465d22018-02-12 13:44:24 -08001351 // Helper class to carry data to handler for reportSvStatus
1352 private static class SvStatusInfo {
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001353 private int mSvCount;
1354 private int[] mSvidWithFlags;
1355 private float[] mCn0s;
1356 private float[] mSvElevations;
1357 private float[] mSvAzimuths;
1358 private float[] mSvCarrierFreqs;
Wyatt Riley26465d22018-02-12 13:44:24 -08001359 }
1360
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001361 @NativeEntryPoint
Wyatt Riley26465d22018-02-12 13:44:24 -08001362 private void reportSvStatus(int svCount, int[] svidWithFlags, float[] cn0s,
1363 float[] svElevations, float[] svAzimuths, float[] svCarrierFreqs) {
1364 SvStatusInfo svStatusInfo = new SvStatusInfo();
1365 svStatusInfo.mSvCount = svCount;
1366 svStatusInfo.mSvidWithFlags = svidWithFlags;
1367 svStatusInfo.mCn0s = cn0s;
1368 svStatusInfo.mSvElevations = svElevations;
1369 svStatusInfo.mSvAzimuths = svAzimuths;
1370 svStatusInfo.mSvCarrierFreqs = svCarrierFreqs;
1371
1372 sendMessage(REPORT_SV_STATUS, 0, svStatusInfo);
1373 }
1374
1375 private void handleReportSvStatus(SvStatusInfo info) {
Anil Admal75b9fd62018-11-28 11:22:50 -08001376 mGnssStatusListenerHelper.onSvStatusChanged(
Wyatt Riley26465d22018-02-12 13:44:24 -08001377 info.mSvCount,
1378 info.mSvidWithFlags,
1379 info.mCn0s,
1380 info.mSvElevations,
1381 info.mSvAzimuths,
1382 info.mSvCarrierFreqs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001383
Siddharth Ray168f12a2017-07-10 11:55:10 -07001384 // Log CN0 as part of GNSS metrics
Wyatt Riley26465d22018-02-12 13:44:24 -08001385 mGnssMetrics.logCn0(info.mCn0s, info.mSvCount);
Siddharth Ray168f12a2017-07-10 11:55:10 -07001386
Mike Lockwood29c84342009-05-06 14:01:15 -04001387 if (VERBOSE) {
Wyatt Riley26465d22018-02-12 13:44:24 -08001388 Log.v(TAG, "SV count: " + info.mSvCount);
Lifu Tang30f95a72016-01-07 23:20:38 -08001389 }
Wyatt Rileyc9f25dd2017-05-05 13:45:23 -07001390 // Calculate number of satellites used in fix.
Lifu Tang30f95a72016-01-07 23:20:38 -08001391 int usedInFixCount = 0;
Wyatt Rileyc9f25dd2017-05-05 13:45:23 -07001392 int maxCn0 = 0;
1393 int meanCn0 = 0;
Wyatt Riley26465d22018-02-12 13:44:24 -08001394 for (int i = 0; i < info.mSvCount; i++) {
1395 if ((info.mSvidWithFlags[i] & GnssStatus.GNSS_SV_FLAGS_USED_IN_FIX) != 0) {
Lifu Tang30f95a72016-01-07 23:20:38 -08001396 ++usedInFixCount;
Wyatt Riley26465d22018-02-12 13:44:24 -08001397 if (info.mCn0s[i] > maxCn0) {
1398 maxCn0 = (int) info.mCn0s[i];
Wyatt Rileyc9f25dd2017-05-05 13:45:23 -07001399 }
Wyatt Riley26465d22018-02-12 13:44:24 -08001400 meanCn0 += info.mCn0s[i];
Lifu Tang30f95a72016-01-07 23:20:38 -08001401 }
1402 if (VERBOSE) {
Wyatt Riley26465d22018-02-12 13:44:24 -08001403 Log.v(TAG, "svid: " + (info.mSvidWithFlags[i] >> GnssStatus.SVID_SHIFT_WIDTH) +
1404 " cn0: " + info.mCn0s[i] +
1405 " elev: " + info.mSvElevations[i] +
1406 " azimuth: " + info.mSvAzimuths[i] +
1407 " carrier frequency: " + info.mSvCarrierFreqs[i] +
1408 ((info.mSvidWithFlags[i] & GnssStatus.GNSS_SV_FLAGS_HAS_EPHEMERIS_DATA) == 0
Lifu Tang30f95a72016-01-07 23:20:38 -08001409 ? " " : " E") +
Wyatt Riley26465d22018-02-12 13:44:24 -08001410 ((info.mSvidWithFlags[i] & GnssStatus.GNSS_SV_FLAGS_HAS_ALMANAC_DATA) == 0
Lifu Tang30f95a72016-01-07 23:20:38 -08001411 ? " " : " A") +
Wyatt Riley26465d22018-02-12 13:44:24 -08001412 ((info.mSvidWithFlags[i] & GnssStatus.GNSS_SV_FLAGS_USED_IN_FIX) == 0
gomo4402af62017-01-11 13:20:13 -08001413 ? "" : "U") +
Wyatt Riley26465d22018-02-12 13:44:24 -08001414 ((info.mSvidWithFlags[i] &
1415 GnssStatus.GNSS_SV_FLAGS_HAS_CARRIER_FREQUENCY) == 0
gomo48f1a642017-11-10 20:35:46 -08001416 ? "" : "F"));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001417 }
1418 }
Wyatt Rileyc9f25dd2017-05-05 13:45:23 -07001419 if (usedInFixCount > 0) {
1420 meanCn0 /= usedInFixCount;
1421 }
1422 // return number of sats used in fix instead of total reported
Wyatt Rileyc7067412018-02-07 15:50:35 -08001423 mLocationExtras.set(usedInFixCount, meanCn0, maxCn0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001424
Mike Lockwood15e3d0f2009-05-01 07:53:28 -04001425 if (mNavigating && mStatus == LocationProvider.AVAILABLE && mLastFixTime > 0 &&
gomo48f1a642017-11-10 20:35:46 -08001426 SystemClock.elapsedRealtime() - mLastFixTime > RECENT_FIX_TIMEOUT) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001427 // send an intent to notify that the GPS is no longer receiving fixes.
Mike Lockwood00b74272010-03-26 10:41:48 -04001428 Intent intent = new Intent(LocationManager.GPS_FIX_CHANGE_ACTION);
1429 intent.putExtra(LocationManager.EXTRA_GPS_ENABLED, false);
Dianne Hackborn5ac72a22012-08-29 18:32:08 -07001430 mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
Wyatt Rileyc7067412018-02-07 15:50:35 -08001431 updateStatus(LocationProvider.TEMPORARILY_UNAVAILABLE);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001432 }
1433 }
Mike Lockwood58bda982009-04-14 16:25:07 -04001434
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001435 @NativeEntryPoint
Anil Admalc70344b2018-11-16 14:22:38 -08001436 private void reportAGpsStatus(int agpsType, int agpsStatus, byte[] suplIpAddr) {
1437 mNetworkConnectivityHandler.onReportAGpsStatus(agpsType, agpsStatus, suplIpAddr);
destradaae21252a2015-09-08 12:32:59 -07001438 }
1439
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001440 @NativeEntryPoint
Mike Lockwoodf602d362010-06-20 14:28:16 -07001441 private void reportNmea(long timestamp) {
Wyatt Riley5d5bac82016-11-01 07:05:16 -07001442 if (!mItarSpeedLimitExceeded) {
1443 int length = native_read_nmea(mNmeaBuffer, mNmeaBuffer.length);
1444 String nmea = new String(mNmeaBuffer, 0 /* offset */, length);
Anil Admal75b9fd62018-11-28 11:22:50 -08001445 mGnssStatusListenerHelper.onNmeaReceived(timestamp, nmea);
Wyatt Riley5d5bac82016-11-01 07:05:16 -07001446 }
destradaaea8a8a62014-06-23 18:19:03 -07001447 }
Mike Lockwoodb16e7802009-08-06 09:26:02 -04001448
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001449 @NativeEntryPoint
Lifu Tang818aa2c2016-02-01 01:52:00 -08001450 private void reportMeasurementData(GnssMeasurementsEvent event) {
Wyatt Riley5d5bac82016-11-01 07:05:16 -07001451 if (!mItarSpeedLimitExceeded) {
Wyatt Rileyaa420d52017-07-03 15:14:42 -07001452 // send to handler to allow native to return quickly
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001453 mHandler.post(() -> mGnssMeasurementsProvider.onMeasurementsAvailable(event));
Wyatt Riley5d5bac82016-11-01 07:05:16 -07001454 }
Mike Lockwoodb16e7802009-08-06 09:26:02 -04001455 }
1456
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001457 @NativeEntryPoint
Lifu Tange8abe8e2016-04-01 10:32:05 -07001458 private void reportNavigationMessage(GnssNavigationMessage event) {
Wyatt Riley5d5bac82016-11-01 07:05:16 -07001459 if (!mItarSpeedLimitExceeded) {
Wyatt Rileyaa420d52017-07-03 15:14:42 -07001460 // send to handler to allow native to return quickly
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001461 mHandler.post(() -> mGnssNavigationMessageProvider.onNavigationMessageAvailable(event));
Wyatt Riley5d5bac82016-11-01 07:05:16 -07001462 }
destradaa4b3e3932014-07-21 18:01:47 -07001463 }
1464
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001465 @NativeEntryPoint
Wyatt Rileyd87cf912017-12-05 09:31:52 -08001466 private void setEngineCapabilities(final int capabilities) {
1467 // send to handler thread for fast native return, and in-order handling
gomo226b7b72018-12-12 16:49:39 -08001468 mHandler.post(
1469 () -> {
1470 mEngineCapabilities = capabilities;
Mike Lockwood9b9fb5c2011-06-29 15:09:40 -04001471
gomo226b7b72018-12-12 16:49:39 -08001472 if (hasCapability(GPS_CAPABILITY_ON_DEMAND_TIME)) {
1473 mNtpTimeHelper.enablePeriodicTimeInjection();
1474 requestUtcTime();
1475 }
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001476
gomo226b7b72018-12-12 16:49:39 -08001477 mGnssMeasurementsProvider.onCapabilitiesUpdated(capabilities);
1478 mGnssNavigationMessageProvider.onCapabilitiesUpdated(
1479 hasCapability(GPS_CAPABILITY_NAV_MESSAGES));
1480 restartRequests();
1481 });
Yu-Han Yang52057622018-04-25 00:51:22 -07001482 }
1483
1484 private void restartRequests() {
1485 Log.i(TAG, "restartRequests");
1486
1487 restartLocationRequest();
1488 mGnssMeasurementsProvider.resumeIfStarted();
1489 mGnssNavigationMessageProvider.resumeIfStarted();
1490 mGnssBatchingProvider.resumeIfStarted();
1491 mGnssGeofenceProvider.resumeIfStarted();
1492 }
1493
1494 private void restartLocationRequest() {
1495 if (DEBUG) Log.d(TAG, "restartLocationRequest");
1496 mStarted = false;
1497 updateRequirements();
1498 }
Wyatt Rileyd87cf912017-12-05 09:31:52 -08001499
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001500 @NativeEntryPoint
Wyatt Rileyd87cf912017-12-05 09:31:52 -08001501 private void setGnssYearOfHardware(final int yearOfHardware) {
1502 // mHardwareYear is simply set here, to be read elsewhere, and is volatile for safe sync
1503 if (DEBUG) Log.d(TAG, "setGnssYearOfHardware called with " + yearOfHardware);
1504 mHardwareYear = yearOfHardware;
Mike Lockwood04598b62010-04-14 17:17:24 -04001505 }
1506
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001507 @NativeEntryPoint
Wyatt Rileyd87cf912017-12-05 09:31:52 -08001508 private void setGnssHardwareModelName(final String modelName) {
1509 // mHardwareModelName is simply set here, to be read elsewhere, and volatile for safe sync
1510 if (DEBUG) Log.d(TAG, "setGnssModelName called with " + modelName);
1511 mHardwareModelName = modelName;
Lifu Tang82f893d2016-01-21 18:15:33 -08001512 }
1513
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001514 @NativeEntryPoint
Yu-Han Yang52057622018-04-25 00:51:22 -07001515 private void reportGnssServiceDied() {
1516 if (DEBUG) Log.d(TAG, "reportGnssServiceDied");
1517 mHandler.post(() -> {
1518 class_init_native();
1519 native_init_once();
1520 if (isEnabled()) {
1521 // re-calls native_init() and other setup.
1522 handleEnable();
1523 // resend configuration into the restarted HAL service.
Anil Admald71cf142018-12-21 14:59:36 -08001524 reloadGpsProperties();
Yu-Han Yang52057622018-04-25 00:51:22 -07001525 }
1526 });
1527 }
1528
Lifu Tang9363b942016-02-16 18:07:00 -08001529 public interface GnssSystemInfoProvider {
Lifu Tang82f893d2016-01-21 18:15:33 -08001530 /**
Wyatt Rileyd87cf912017-12-05 09:31:52 -08001531 * Returns the year of underlying GPS hardware.
Lifu Tang82f893d2016-01-21 18:15:33 -08001532 */
Lifu Tang9363b942016-02-16 18:07:00 -08001533 int getGnssYearOfHardware();
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001534
Wyatt Rileyd87cf912017-12-05 09:31:52 -08001535 /**
1536 * Returns the model name of underlying GPS hardware.
1537 */
1538 String getGnssHardwareModelName();
Lifu Tang82f893d2016-01-21 18:15:33 -08001539 }
1540
1541 /**
1542 * @hide
1543 */
Lifu Tang9363b942016-02-16 18:07:00 -08001544 public GnssSystemInfoProvider getGnssSystemInfoProvider() {
1545 return new GnssSystemInfoProvider() {
Lifu Tang82f893d2016-01-21 18:15:33 -08001546 @Override
Lifu Tang9363b942016-02-16 18:07:00 -08001547 public int getGnssYearOfHardware() {
Wyatt Rileyd87cf912017-12-05 09:31:52 -08001548 return mHardwareYear;
1549 }
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001550
Wyatt Rileyd87cf912017-12-05 09:31:52 -08001551 @Override
1552 public String getGnssHardwareModelName() {
1553 return mHardwareModelName;
Lifu Tang82f893d2016-01-21 18:15:33 -08001554 }
1555 };
1556 }
1557
Wyatt Rileycf879db2017-01-12 13:57:38 -08001558 /**
1559 * @hide
1560 */
1561 public GnssBatchingProvider getGnssBatchingProvider() {
Yu-Han Yang3557cc72018-03-21 12:48:36 -07001562 return mGnssBatchingProvider;
Wyatt Rileycf879db2017-01-12 13:57:38 -08001563 }
1564
Siddharth Raybb608c82017-03-16 11:33:34 -07001565 public interface GnssMetricsProvider {
1566 /**
1567 * Returns GNSS metrics as proto string
1568 */
1569 String getGnssMetricsAsProtoString();
1570 }
1571
1572 /**
1573 * @hide
1574 */
1575 public GnssMetricsProvider getGnssMetricsProvider() {
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001576 return () -> mGnssMetrics.dumpGnssMetricsAsProtoString();
Siddharth Raybb608c82017-03-16 11:33:34 -07001577 }
1578
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001579 @NativeEntryPoint
Wyatt Rileycf879db2017-01-12 13:57:38 -08001580 private void reportLocationBatch(Location[] locationArray) {
1581 List<Location> locations = new ArrayList<>(Arrays.asList(locationArray));
gomo48f1a642017-11-10 20:35:46 -08001582 if (DEBUG) {
1583 Log.d(TAG, "Location batch of size " + locationArray.length + " reported");
1584 }
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001585 reportLocation(locations);
Wyatt Rileycf879db2017-01-12 13:57:38 -08001586 }
1587
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001588 @NativeEntryPoint
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001589 private void xtraDownloadRequest() {
Joe Onoratof5d95cb2010-01-07 21:48:32 -05001590 if (DEBUG) Log.d(TAG, "xtraDownloadRequest");
Mike Lockwood98e48692010-04-07 16:32:51 -04001591 sendMessage(DOWNLOAD_XTRA_DATA, 0, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001592 }
1593
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07001594 /**
destradaa0682809a2013-08-12 18:50:30 -07001595 * Converts the GPS HAL status to the internal Geofence Hardware status.
1596 */
Yu-Han Yang6dc9f052018-12-04 17:11:24 -08001597 private static int getGeofenceStatus(int status) {
gomo48f1a642017-11-10 20:35:46 -08001598 switch (status) {
destradaa0682809a2013-08-12 18:50:30 -07001599 case GPS_GEOFENCE_OPERATION_SUCCESS:
1600 return GeofenceHardware.GEOFENCE_SUCCESS;
1601 case GPS_GEOFENCE_ERROR_GENERIC:
1602 return GeofenceHardware.GEOFENCE_FAILURE;
1603 case GPS_GEOFENCE_ERROR_ID_EXISTS:
1604 return GeofenceHardware.GEOFENCE_ERROR_ID_EXISTS;
1605 case GPS_GEOFENCE_ERROR_INVALID_TRANSITION:
1606 return GeofenceHardware.GEOFENCE_ERROR_INVALID_TRANSITION;
1607 case GPS_GEOFENCE_ERROR_TOO_MANY_GEOFENCES:
1608 return GeofenceHardware.GEOFENCE_ERROR_TOO_MANY_GEOFENCES;
1609 case GPS_GEOFENCE_ERROR_ID_UNKNOWN:
1610 return GeofenceHardware.GEOFENCE_ERROR_ID_UNKNOWN;
1611 default:
1612 return -1;
1613 }
1614 }
1615
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001616 @NativeEntryPoint
Wyatt Riley5d229832017-02-10 17:06:00 -08001617 private void reportGeofenceTransition(int geofenceId, Location location, int transition,
gomo48f1a642017-11-10 20:35:46 -08001618 long transitionTimestamp) {
Yu-Han Yang6dc9f052018-12-04 17:11:24 -08001619 mHandler.post(() -> {
1620 if (mGeofenceHardwareImpl == null) {
1621 mGeofenceHardwareImpl = GeofenceHardwareImpl.getInstance(mContext);
1622 }
Wyatt Riley5d229832017-02-10 17:06:00 -08001623
Yu-Han Yang6dc9f052018-12-04 17:11:24 -08001624 mGeofenceHardwareImpl.reportGeofenceTransition(
1625 geofenceId,
1626 location,
1627 transition,
1628 transitionTimestamp,
1629 GeofenceHardware.MONITORING_TYPE_GPS_HARDWARE,
1630 FusedBatchOptions.SourceTechnologies.GNSS);
1631 });
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07001632 }
1633
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001634 @NativeEntryPoint
Wyatt Riley5d229832017-02-10 17:06:00 -08001635 private void reportGeofenceStatus(int status, Location location) {
Yu-Han Yang6dc9f052018-12-04 17:11:24 -08001636 mHandler.post(() -> {
1637 if (mGeofenceHardwareImpl == null) {
1638 mGeofenceHardwareImpl = GeofenceHardwareImpl.getInstance(mContext);
1639 }
1640 int monitorStatus = GeofenceHardware.MONITOR_CURRENTLY_UNAVAILABLE;
1641 if (status == GPS_GEOFENCE_AVAILABLE) {
1642 monitorStatus = GeofenceHardware.MONITOR_CURRENTLY_AVAILABLE;
1643 }
1644 mGeofenceHardwareImpl.reportGeofenceMonitorStatus(
1645 GeofenceHardware.MONITORING_TYPE_GPS_HARDWARE,
1646 monitorStatus,
1647 location,
1648 FusedBatchOptions.SourceTechnologies.GNSS);
1649 });
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07001650 }
1651
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001652 @NativeEntryPoint
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07001653 private void reportGeofenceAddStatus(int geofenceId, int status) {
Yu-Han Yang6dc9f052018-12-04 17:11:24 -08001654 mHandler.post(() -> {
1655 if (mGeofenceHardwareImpl == null) {
1656 mGeofenceHardwareImpl = GeofenceHardwareImpl.getInstance(mContext);
1657 }
1658 mGeofenceHardwareImpl.reportGeofenceAddStatus(geofenceId, getGeofenceStatus(status));
1659 });
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07001660 }
1661
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001662 @NativeEntryPoint
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07001663 private void reportGeofenceRemoveStatus(int geofenceId, int status) {
Yu-Han Yang6dc9f052018-12-04 17:11:24 -08001664 mHandler.post(() -> {
1665 if (mGeofenceHardwareImpl == null) {
1666 mGeofenceHardwareImpl = GeofenceHardwareImpl.getInstance(mContext);
1667 }
1668 mGeofenceHardwareImpl.reportGeofenceRemoveStatus(geofenceId, getGeofenceStatus(status));
1669 });
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07001670 }
1671
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001672 @NativeEntryPoint
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07001673 private void reportGeofencePauseStatus(int geofenceId, int status) {
Yu-Han Yang6dc9f052018-12-04 17:11:24 -08001674 mHandler.post(() -> {
1675 if (mGeofenceHardwareImpl == null) {
1676 mGeofenceHardwareImpl = GeofenceHardwareImpl.getInstance(mContext);
1677 }
1678 mGeofenceHardwareImpl.reportGeofencePauseStatus(geofenceId, getGeofenceStatus(status));
1679 });
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07001680 }
1681
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001682 @NativeEntryPoint
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07001683 private void reportGeofenceResumeStatus(int geofenceId, int status) {
Yu-Han Yang6dc9f052018-12-04 17:11:24 -08001684 mHandler.post(() -> {
1685 if (mGeofenceHardwareImpl == null) {
1686 mGeofenceHardwareImpl = GeofenceHardwareImpl.getInstance(mContext);
1687 }
1688 mGeofenceHardwareImpl.reportGeofenceResumeStatus(geofenceId, getGeofenceStatus(status));
1689 });
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07001690 }
1691
Danke Xie22d1f9f2009-08-18 18:28:45 -04001692 //=============================================================
1693 // NI Client support
Miguel Torroja1e84da82010-07-27 07:02:24 +02001694 //=============================================================
Danke Xie22d1f9f2009-08-18 18:28:45 -04001695 private final INetInitiatedListener mNetInitiatedListener = new INetInitiatedListener.Stub() {
destradaaef752b62015-04-17 13:10:47 -07001696 // Sends a response for an NI request to HAL.
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001697 @Override
gomo48f1a642017-11-10 20:35:46 -08001698 public boolean sendNiResponse(int notificationId, int userResponse) {
Miguel Torroja1e84da82010-07-27 07:02:24 +02001699 // TODO Add Permission check
Danke Xie22d1f9f2009-08-18 18:28:45 -04001700
gomo48f1a642017-11-10 20:35:46 -08001701 if (DEBUG) {
1702 Log.d(TAG, "sendNiResponse, notifId: " + notificationId +
1703 ", response: " + userResponse);
1704 }
Miguel Torroja1e84da82010-07-27 07:02:24 +02001705 native_send_ni_response(notificationId, userResponse);
1706 return true;
1707 }
Danke Xie22d1f9f2009-08-18 18:28:45 -04001708 };
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001709
Danke Xie22d1f9f2009-08-18 18:28:45 -04001710 public INetInitiatedListener getNetInitiatedListener() {
1711 return mNetInitiatedListener;
1712 }
1713
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001714 /** Reports a NI notification. */
1715 @NativeEntryPoint
Miguel Torroja1e84da82010-07-27 07:02:24 +02001716 public void reportNiNotification(
1717 int notificationId,
1718 int niType,
1719 int notifyFlags,
1720 int timeout,
1721 int defaultResponse,
1722 String requestorId,
1723 String text,
1724 int requestorIdEncoding,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001725 int textEncoding
gomo48f1a642017-11-10 20:35:46 -08001726 ) {
Miguel Torroja1e84da82010-07-27 07:02:24 +02001727 Log.i(TAG, "reportNiNotification: entered");
1728 Log.i(TAG, "notificationId: " + notificationId +
1729 ", niType: " + niType +
1730 ", notifyFlags: " + notifyFlags +
1731 ", timeout: " + timeout +
1732 ", defaultResponse: " + defaultResponse);
1733
1734 Log.i(TAG, "requestorId: " + requestorId +
1735 ", text: " + text +
1736 ", requestorIdEncoding: " + requestorIdEncoding +
1737 ", textEncoding: " + textEncoding);
1738
1739 GpsNiNotification notification = new GpsNiNotification();
1740
1741 notification.notificationId = notificationId;
1742 notification.niType = niType;
1743 notification.needNotify = (notifyFlags & GpsNetInitiatedHandler.GPS_NI_NEED_NOTIFY) != 0;
1744 notification.needVerify = (notifyFlags & GpsNetInitiatedHandler.GPS_NI_NEED_VERIFY) != 0;
gomo48f1a642017-11-10 20:35:46 -08001745 notification.privacyOverride =
1746 (notifyFlags & GpsNetInitiatedHandler.GPS_NI_PRIVACY_OVERRIDE) != 0;
Miguel Torroja1e84da82010-07-27 07:02:24 +02001747 notification.timeout = timeout;
1748 notification.defaultResponse = defaultResponse;
1749 notification.requestorId = requestorId;
1750 notification.text = text;
1751 notification.requestorIdEncoding = requestorIdEncoding;
1752 notification.textEncoding = textEncoding;
1753
Miguel Torroja1e84da82010-07-27 07:02:24 +02001754 mNIHandler.handleNiNotification(notification);
1755 }
1756
1757 /**
Miguel Torroja1e84da82010-07-27 07:02:24 +02001758 * We should be careful about receiving null string from the TelephonyManager,
1759 * because sending null String to JNI function would cause a crash.
1760 */
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001761 @NativeEntryPoint
Miguel Torroja1e84da82010-07-27 07:02:24 +02001762 private void requestSetID(int flags) {
1763 TelephonyManager phone = (TelephonyManager)
1764 mContext.getSystemService(Context.TELEPHONY_SERVICE);
destradaaef752b62015-04-17 13:10:47 -07001765 int type = AGPS_SETID_TYPE_NONE;
Miguel Torroja1e84da82010-07-27 07:02:24 +02001766 String data = "";
1767
1768 if ((flags & AGPS_RIL_REQUEST_SETID_IMSI) == AGPS_RIL_REQUEST_SETID_IMSI) {
1769 String data_temp = phone.getSubscriberId();
1770 if (data_temp == null) {
1771 // This means the framework does not have the SIM card ready.
1772 } else {
1773 // This means the framework has the SIM card.
1774 data = data_temp;
1775 type = AGPS_SETID_TYPE_IMSI;
1776 }
gomo48f1a642017-11-10 20:35:46 -08001777 } else if ((flags & AGPS_RIL_REQUEST_SETID_MSISDN) == AGPS_RIL_REQUEST_SETID_MSISDN) {
Miguel Torroja1e84da82010-07-27 07:02:24 +02001778 String data_temp = phone.getLine1Number();
1779 if (data_temp == null) {
1780 // This means the framework does not have the SIM card ready.
1781 } else {
1782 // This means the framework has the SIM card.
1783 data = data_temp;
1784 type = AGPS_SETID_TYPE_MSISDN;
1785 }
1786 }
1787 native_agps_set_id(type, data);
1788 }
1789
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001790 @NativeEntryPoint
Yu-Han Yange7baef32018-02-09 13:58:17 -08001791 private void requestLocation(boolean independentFromGnss) {
1792 if (DEBUG) {
1793 Log.d(TAG, "requestLocation. independentFromGnss: " + independentFromGnss);
1794 }
1795 sendMessage(REQUEST_LOCATION, 0, independentFromGnss);
1796 }
1797
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001798 @NativeEntryPoint
Mike Lockwood9b9fb5c2011-06-29 15:09:40 -04001799 private void requestUtcTime() {
destradaae21252a2015-09-08 12:32:59 -07001800 if (DEBUG) Log.d(TAG, "utcTimeRequest");
Mike Lockwood9b9fb5c2011-06-29 15:09:40 -04001801 sendMessage(INJECT_NTP_TIME, 0, null);
1802 }
1803
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001804 @NativeEntryPoint
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001805 private void requestRefLocation() {
Miguel Torroja1e84da82010-07-27 07:02:24 +02001806 TelephonyManager phone = (TelephonyManager)
1807 mContext.getSystemService(Context.TELEPHONY_SERVICE);
Victoria Leased50d0c32012-10-29 13:16:17 -07001808 final int phoneType = phone.getPhoneType();
1809 if (phoneType == TelephonyManager.PHONE_TYPE_GSM) {
Miguel Torroja1e84da82010-07-27 07:02:24 +02001810 GsmCellLocation gsm_cell = (GsmCellLocation) phone.getCellLocation();
Victoria Leased50d0c32012-10-29 13:16:17 -07001811 if ((gsm_cell != null) && (phone.getNetworkOperator() != null)
1812 && (phone.getNetworkOperator().length() > 3)) {
Miguel Torroja1e84da82010-07-27 07:02:24 +02001813 int type;
gomo48f1a642017-11-10 20:35:46 -08001814 int mcc = Integer.parseInt(phone.getNetworkOperator().substring(0, 3));
Miguel Torroja1e84da82010-07-27 07:02:24 +02001815 int mnc = Integer.parseInt(phone.getNetworkOperator().substring(3));
Mike Lockwoodedc0f3872010-10-22 09:16:17 -04001816 int networkType = phone.getNetworkType();
1817 if (networkType == TelephonyManager.NETWORK_TYPE_UMTS
gomo48f1a642017-11-10 20:35:46 -08001818 || networkType == TelephonyManager.NETWORK_TYPE_HSDPA
1819 || networkType == TelephonyManager.NETWORK_TYPE_HSUPA
1820 || networkType == TelephonyManager.NETWORK_TYPE_HSPA
1821 || networkType == TelephonyManager.NETWORK_TYPE_HSPAP) {
Miguel Torroja1e84da82010-07-27 07:02:24 +02001822 type = AGPS_REF_LOCATION_TYPE_UMTS_CELLID;
Mike Lockwoodedc0f3872010-10-22 09:16:17 -04001823 } else {
Miguel Torroja1e84da82010-07-27 07:02:24 +02001824 type = AGPS_REF_LOCATION_TYPE_GSM_CELLID;
Mike Lockwoodedc0f3872010-10-22 09:16:17 -04001825 }
Miguel Torroja1e84da82010-07-27 07:02:24 +02001826 native_agps_set_ref_location_cellid(type, mcc, mnc,
1827 gsm_cell.getLac(), gsm_cell.getCid());
Mike Lockwoodedc0f3872010-10-22 09:16:17 -04001828 } else {
gomo48f1a642017-11-10 20:35:46 -08001829 Log.e(TAG, "Error getting cell location info.");
Mike Lockwoodedc0f3872010-10-22 09:16:17 -04001830 }
Victoria Leased50d0c32012-10-29 13:16:17 -07001831 } else if (phoneType == TelephonyManager.PHONE_TYPE_CDMA) {
1832 Log.e(TAG, "CDMA not supported.");
Mike Lockwoodedc0f3872010-10-22 09:16:17 -04001833 }
Miguel Torroja1e84da82010-07-27 07:02:24 +02001834 }
Danke Xie22d1f9f2009-08-18 18:28:45 -04001835
Mike Lockwood98e48692010-04-07 16:32:51 -04001836 private void sendMessage(int message, int arg, Object obj) {
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001837 // hold a wake lock until this message is delivered
Jeff Brown028872f2012-08-25 13:07:01 -07001838 // note that this assumes the message will not be removed from the queue before
1839 // it is handled (otherwise the wake lock would be leaked).
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001840 mWakeLock.acquire();
Anil Admal4f97c942018-11-12 10:52:46 -08001841 if (DEBUG) {
1842 Log.d(TAG, "WakeLock acquired by sendMessage(" + messageIdAsString(message) + ", " + arg
Wyatt Rileycf879db2017-01-12 13:57:38 -08001843 + ", " + obj + ")");
1844 }
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001845 mHandler.obtainMessage(message, arg, 1, obj).sendToTarget();
Mike Lockwood98e48692010-04-07 16:32:51 -04001846 }
1847
Mike Lockwood62a8fc12010-03-22 14:23:26 -04001848 private final class ProviderHandler extends Handler {
Victoria Lease5cd731a2012-12-19 15:04:21 -08001849 public ProviderHandler(Looper looper) {
1850 super(looper, null, true /*async*/);
Jeff Brown028872f2012-08-25 13:07:01 -07001851 }
1852
Mike Lockwood62a8fc12010-03-22 14:23:26 -04001853 @Override
Mike Lockwood4a7b65e2010-10-25 16:35:55 -04001854 public void handleMessage(Message msg) {
Mike Lockwood98e48692010-04-07 16:32:51 -04001855 int message = msg.what;
1856 switch (message) {
Mike Lockwood62a8fc12010-03-22 14:23:26 -04001857 case ENABLE:
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001858 handleEnable();
Mike Lockwood62a8fc12010-03-22 14:23:26 -04001859 break;
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001860 case SET_REQUEST:
1861 GpsRequest gpsRequest = (GpsRequest) msg.obj;
1862 handleSetRequest(gpsRequest.request, gpsRequest.source);
Mike Lockwood03ca2162010-04-01 08:10:09 -07001863 break;
Mike Lockwood62a8fc12010-03-22 14:23:26 -04001864 case INJECT_NTP_TIME:
Yu-Han Yanga1862b52018-02-20 17:05:59 -08001865 mNtpTimeHelper.retrieveAndInjectNtpTime();
Mike Lockwood62a8fc12010-03-22 14:23:26 -04001866 break;
Yu-Han Yange7baef32018-02-09 13:58:17 -08001867 case REQUEST_LOCATION:
1868 handleRequestLocation((boolean) msg.obj);
1869 break;
Mike Lockwood62a8fc12010-03-22 14:23:26 -04001870 case DOWNLOAD_XTRA_DATA:
Wyatt Riley0d6e54e22016-10-05 12:03:03 -07001871 handleDownloadXtraData();
Mike Lockwood62a8fc12010-03-22 14:23:26 -04001872 break;
Kevin Tang40e1baf2012-01-10 14:32:44 -08001873 case DOWNLOAD_XTRA_DATA_FINISHED:
1874 mDownloadXtraDataPending = STATE_IDLE;
1875 break;
Mike Lockwood62a8fc12010-03-22 14:23:26 -04001876 case UPDATE_LOCATION:
destradaae21252a2015-09-08 12:32:59 -07001877 handleUpdateLocation((Location) msg.obj);
Mike Lockwood62a8fc12010-03-22 14:23:26 -04001878 break;
Meng Wang19b214d2018-11-07 12:14:39 -08001879 case SUBSCRIPTION_OR_CARRIER_CONFIG_CHANGED:
1880 subscriptionOrCarrierConfigChanged(mContext);
destradaafb23c672015-04-16 14:01:27 -07001881 break;
1882 case INITIALIZE_HANDLER:
destradaae21252a2015-09-08 12:32:59 -07001883 handleInitialize();
destradaafb23c672015-04-16 14:01:27 -07001884 break;
Wyatt Riley26465d22018-02-12 13:44:24 -08001885 case REPORT_LOCATION:
1886 handleReportLocation(msg.arg1 == 1, (Location) msg.obj);
1887 break;
1888 case REPORT_SV_STATUS:
1889 handleReportSvStatus((SvStatusInfo) msg.obj);
1890 break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001891 }
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001892 if (msg.arg2 == 1) {
1893 // wakelock was taken for this message, release it
1894 mWakeLock.release();
Anil Admal4f97c942018-11-12 10:52:46 -08001895 if (DEBUG) {
1896 Log.d(TAG, "WakeLock released by handleMessage(" + messageIdAsString(message)
Wyatt Rileycf879db2017-01-12 13:57:38 -08001897 + ", " + msg.arg1 + ", " + msg.obj + ")");
1898 }
Mike Lockwood98e48692010-04-07 16:32:51 -04001899 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001900 }
destradaafb23c672015-04-16 14:01:27 -07001901
1902 /**
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001903 * This method is bound to {@link #GnssLocationProvider(Context, LocationProviderManager,
1904 * Looper)}.
destradaafb23c672015-04-16 14:01:27 -07001905 * It is in charge of loading properties and registering for events that will be posted to
1906 * this handler.
1907 */
destradaae21252a2015-09-08 12:32:59 -07001908 private void handleInitialize() {
Yu-Han Yang6d317352018-03-15 11:53:01 -07001909 native_init_once();
1910
Wyatt Riley523a0cf2017-10-31 14:36:52 -07001911 /*
1912 * A cycle of native_init() and native_cleanup() is needed so that callbacks are
1913 * registered after bootup even when location is disabled.
1914 * This will allow Emergency SUPL to work even when location is disabled before device
1915 * restart.
1916 */
1917 boolean isInitialized = native_init();
gomo48f1a642017-11-10 20:35:46 -08001918 if (!isInitialized) {
Wyatt Riley523a0cf2017-10-31 14:36:52 -07001919 Log.w(TAG, "Native initialization failed at bootup");
1920 } else {
1921 native_cleanup();
1922 }
1923
destradaafb23c672015-04-16 14:01:27 -07001924 // load default GPS configuration
1925 // (this configuration might change in the future based on SIM changes)
Anil Admald71cf142018-12-21 14:59:36 -08001926 reloadGpsProperties();
destradaafb23c672015-04-16 14:01:27 -07001927
1928 // TODO: When this object "finishes" we should unregister by invoking
gomo48f1a642017-11-10 20:35:46 -08001929 // SubscriptionManager.getInstance(mContext).unregister
1930 // (mOnSubscriptionsChangedListener);
destradaafb23c672015-04-16 14:01:27 -07001931 // This is not strictly necessary because it will be unregistered if the
1932 // notification fails but it is good form.
1933
1934 // Register for SubscriptionInfo list changes which is guaranteed
1935 // to invoke onSubscriptionsChanged the first time.
1936 SubscriptionManager.from(mContext)
1937 .addOnSubscriptionsChangedListener(mOnSubscriptionsChangedListener);
1938
1939 // listen for events
WyattRiley6593cf12018-06-23 10:37:48 -07001940 IntentFilter intentFilter = new IntentFilter();
destradaafb23c672015-04-16 14:01:27 -07001941 intentFilter.addAction(ALARM_WAKEUP);
1942 intentFilter.addAction(ALARM_TIMEOUT);
destradaafb23c672015-04-16 14:01:27 -07001943 intentFilter.addAction(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED);
Adam Lesinski87c17df2015-05-27 13:24:13 -07001944 intentFilter.addAction(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED);
destradaafb23c672015-04-16 14:01:27 -07001945 intentFilter.addAction(Intent.ACTION_SCREEN_OFF);
1946 intentFilter.addAction(Intent.ACTION_SCREEN_ON);
Meng Wang19b214d2018-11-07 12:14:39 -08001947 intentFilter.addAction(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
destradaafb23c672015-04-16 14:01:27 -07001948 mContext.registerReceiver(mBroadcastReceiver, intentFilter, null, this);
1949
Anil Admal50ba15e2018-11-01 16:42:42 -07001950 mNetworkConnectivityHandler.registerNetworkCallbacks();
destradaae21252a2015-09-08 12:32:59 -07001951
destradaafb23c672015-04-16 14:01:27 -07001952 // listen for PASSIVE_PROVIDER updates
1953 LocationManager locManager =
1954 (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE);
1955 long minTime = 0;
1956 float minDistance = 0;
destradaafb23c672015-04-16 14:01:27 -07001957 LocationRequest request = LocationRequest.createFromDeprecatedProvider(
1958 LocationManager.PASSIVE_PROVIDER,
1959 minTime,
1960 minDistance,
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001961 false);
destradaafb23c672015-04-16 14:01:27 -07001962 // Don't keep track of this request since it's done on behalf of other clients
1963 // (which are kept track of separately).
1964 request.setHideFromAppOps(true);
1965 locManager.requestLocationUpdates(
1966 request,
1967 new NetworkLocationListener(),
1968 getLooper());
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001969
1970 // enable gps provider, it will never be disabled (legacy behavior)
1971 sendEmptyMessage(ENABLE);
destradaafb23c672015-04-16 14:01:27 -07001972 }
1973 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001974
Yu-Han Yange7baef32018-02-09 13:58:17 -08001975 private abstract class LocationChangeListener implements LocationListener {
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001976 private int mNumLocationUpdateRequest;
Yu-Han Yang07561382018-02-21 13:08:37 -08001977
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001978 @Override
gomo48f1a642017-11-10 20:35:46 -08001979 public void onStatusChanged(String provider, int status, Bundle extras) {
1980 }
1981
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001982 @Override
gomo48f1a642017-11-10 20:35:46 -08001983 public void onProviderEnabled(String provider) {
1984 }
1985
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001986 @Override
gomo48f1a642017-11-10 20:35:46 -08001987 public void onProviderDisabled(String provider) {
1988 }
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001989 }
1990
Yu-Han Yange7baef32018-02-09 13:58:17 -08001991 private final class NetworkLocationListener extends LocationChangeListener {
1992 @Override
1993 public void onLocationChanged(Location location) {
1994 // this callback happens on mHandler looper
1995 if (LocationManager.NETWORK_PROVIDER.equals(location.getProvider())) {
1996 handleUpdateLocation(location);
1997 }
1998 }
1999 }
2000
2001 private final class FusedLocationListener extends LocationChangeListener {
2002 @Override
2003 public void onLocationChanged(Location location) {
2004 if (LocationManager.FUSED_PROVIDER.equals(location.getProvider())) {
Yu-Han Yange7baef32018-02-09 13:58:17 -08002005 injectBestLocation(location);
2006 }
2007 }
2008 }
2009
Wyatt Rileycf879db2017-01-12 13:57:38 -08002010 /**
2011 * @return A string representing the given message ID.
2012 */
2013 private String messageIdAsString(int message) {
2014 switch (message) {
2015 case ENABLE:
2016 return "ENABLE";
2017 case SET_REQUEST:
2018 return "SET_REQUEST";
Wyatt Rileycf879db2017-01-12 13:57:38 -08002019 case INJECT_NTP_TIME:
2020 return "INJECT_NTP_TIME";
Yu-Han Yange7baef32018-02-09 13:58:17 -08002021 case REQUEST_LOCATION:
2022 return "REQUEST_LOCATION";
Wyatt Rileycf879db2017-01-12 13:57:38 -08002023 case DOWNLOAD_XTRA_DATA:
2024 return "DOWNLOAD_XTRA_DATA";
Wyatt Rileycf879db2017-01-12 13:57:38 -08002025 case DOWNLOAD_XTRA_DATA_FINISHED:
2026 return "DOWNLOAD_XTRA_DATA_FINISHED";
2027 case UPDATE_LOCATION:
2028 return "UPDATE_LOCATION";
Meng Wang19b214d2018-11-07 12:14:39 -08002029 case SUBSCRIPTION_OR_CARRIER_CONFIG_CHANGED:
2030 return "SUBSCRIPTION_OR_CARRIER_CONFIG_CHANGED";
Wyatt Rileycf879db2017-01-12 13:57:38 -08002031 case INITIALIZE_HANDLER:
2032 return "INITIALIZE_HANDLER";
Wyatt Riley26465d22018-02-12 13:44:24 -08002033 case REPORT_LOCATION:
2034 return "REPORT_LOCATION";
2035 case REPORT_SV_STATUS:
2036 return "REPORT_SV_STATUS";
Wyatt Rileycf879db2017-01-12 13:57:38 -08002037 default:
2038 return "<Unknown>";
2039 }
2040 }
2041
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002042 @Override
2043 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2044 StringBuilder s = new StringBuilder();
Wyatt Riley77ca4f82017-06-30 18:13:44 -07002045 s.append(" mStarted=").append(mStarted).append('\n');
destradaa25e8caf2015-08-24 14:14:44 -07002046 s.append(" mFixInterval=").append(mFixInterval).append('\n');
gomo48f1a642017-11-10 20:35:46 -08002047 s.append(" mLowPowerMode=").append(mLowPowerMode).append('\n');
Wyatt Riley74479bd2018-01-17 08:48:27 -08002048 s.append(" mGnssMeasurementsProvider.isRegistered()=")
2049 .append(mGnssMeasurementsProvider.isRegistered()).append('\n');
2050 s.append(" mGnssNavigationMessageProvider.isRegistered()=")
2051 .append(mGnssNavigationMessageProvider.isRegistered()).append('\n');
destradaa25e8caf2015-08-24 14:14:44 -07002052 s.append(" mDisableGps (battery saver mode)=").append(mDisableGps).append('\n');
2053 s.append(" mEngineCapabilities=0x").append(Integer.toHexString(mEngineCapabilities));
2054 s.append(" ( ");
2055 if (hasCapability(GPS_CAPABILITY_SCHEDULING)) s.append("SCHEDULING ");
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002056 if (hasCapability(GPS_CAPABILITY_MSB)) s.append("MSB ");
2057 if (hasCapability(GPS_CAPABILITY_MSA)) s.append("MSA ");
2058 if (hasCapability(GPS_CAPABILITY_SINGLE_SHOT)) s.append("SINGLE_SHOT ");
2059 if (hasCapability(GPS_CAPABILITY_ON_DEMAND_TIME)) s.append("ON_DEMAND_TIME ");
destradaa25e8caf2015-08-24 14:14:44 -07002060 if (hasCapability(GPS_CAPABILITY_GEOFENCING)) s.append("GEOFENCING ");
2061 if (hasCapability(GPS_CAPABILITY_MEASUREMENTS)) s.append("MEASUREMENTS ");
2062 if (hasCapability(GPS_CAPABILITY_NAV_MESSAGES)) s.append("NAV_MESSAGES ");
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002063 s.append(")\n");
Siddharth Raybb608c82017-03-16 11:33:34 -07002064 s.append(mGnssMetrics.dumpGnssMetricsAsText());
2065 s.append(" native internal state: ").append(native_get_internal_state());
Wyatt Rileycf879db2017-01-12 13:57:38 -08002066 s.append("\n");
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002067 pw.append(s);
2068 }
2069
Mike Lockwoodb16e7802009-08-06 09:26:02 -04002070 // preallocated to avoid memory allocation in reportNmea()
2071 private byte[] mNmeaBuffer = new byte[120];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002072
gomo48f1a642017-11-10 20:35:46 -08002073 static {
2074 class_init_native();
2075 }
2076
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002077 private static native void class_init_native();
gomo48f1a642017-11-10 20:35:46 -08002078
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002079 private static native boolean native_is_supported();
gomo48f1a642017-11-10 20:35:46 -08002080
Yu-Han Yang6d317352018-03-15 11:53:01 -07002081 private static native void native_init_once();
2082
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002083 private native boolean native_init();
gomo48f1a642017-11-10 20:35:46 -08002084
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002085 private native void native_cleanup();
gomo48f1a642017-11-10 20:35:46 -08002086
Mike Lockwood04598b62010-04-14 17:17:24 -04002087 private native boolean native_set_position_mode(int mode, int recurrence, int min_interval,
gomo48f1a642017-11-10 20:35:46 -08002088 int preferred_accuracy, int preferred_time, boolean lowPowerMode);
2089
Mike Lockwood04598b62010-04-14 17:17:24 -04002090 private native boolean native_start();
gomo48f1a642017-11-10 20:35:46 -08002091
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002092 private native boolean native_stop();
gomo48f1a642017-11-10 20:35:46 -08002093
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002094 private native void native_delete_aiding_data(int flags);
gomo48f1a642017-11-10 20:35:46 -08002095
Mike Lockwoodf602d362010-06-20 14:28:16 -07002096 private native int native_read_nmea(byte[] buffer, int bufferSize);
gomo48f1a642017-11-10 20:35:46 -08002097
Yu-Han Yange7baef32018-02-09 13:58:17 -08002098 private native void native_inject_best_location(
2099 int gnssLocationFlags,
2100 double latitudeDegrees,
2101 double longitudeDegrees,
2102 double altitudeMeters,
2103 float speedMetersPerSec,
2104 float bearingDegrees,
2105 float horizontalAccuracyMeters,
2106 float verticalAccuracyMeters,
2107 float speedAccuracyMetersPerSecond,
2108 float bearingAccuracyDegrees,
2109 long timestamp);
2110
Mike Lockwoodd26ce0d2009-06-11 12:25:46 -04002111 private native void native_inject_location(double latitude, double longitude, float accuracy);
2112
Fred Fettinger3c8fbdf2010-01-04 15:38:13 -06002113 // XTRA Support
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002114 private native void native_inject_time(long time, long timeReference, int uncertainty);
gomo48f1a642017-11-10 20:35:46 -08002115
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002116 private native boolean native_supports_xtra();
gomo48f1a642017-11-10 20:35:46 -08002117
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002118 private native void native_inject_xtra_data(byte[] data, int length);
The Android Open Source Project10592532009-03-18 17:39:46 -07002119
Fred Fettinger3c8fbdf2010-01-04 15:38:13 -06002120 // DEBUG Support
2121 private native String native_get_internal_state();
2122
2123 // AGPS Support
gomo48f1a642017-11-10 20:35:46 -08002124 private native void native_agps_ni_message(byte[] msg, int length);
2125
Mike Lockwooda9e54612009-06-19 14:54:42 -04002126 private native void native_set_agps_server(int type, String hostname, int port);
Danke Xie22d1f9f2009-08-18 18:28:45 -04002127
2128 // Network-initiated (NI) Support
2129 private native void native_send_ni_response(int notificationId, int userResponse);
Miguel Torroja1e84da82010-07-27 07:02:24 +02002130
Anil Admal50ba15e2018-11-01 16:42:42 -07002131 // AGPS ril support
Miguel Torroja1e84da82010-07-27 07:02:24 +02002132 private native void native_agps_set_ref_location_cellid(int type, int mcc, int mnc,
2133 int lac, int cid);
gomo48f1a642017-11-10 20:35:46 -08002134
Miguel Torroja1e84da82010-07-27 07:02:24 +02002135 private native void native_agps_set_id(int type, String setid);
Anil Admald71cf142018-12-21 14:59:36 -08002136}