blob: c312b76cc46340673f83267c322c4afab29452a8 [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;
Soonil Nagarkar35c3b912019-01-31 10:31:24 -080027import android.database.ContentObserver;
destradaa0682809a2013-08-12 18:50:30 -070028import android.hardware.location.GeofenceHardware;
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -070029import android.hardware.location.GeofenceHardwareImpl;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080030import android.location.Criteria;
destradaa0682809a2013-08-12 18:50:30 -070031import android.location.FusedBatchOptions;
Yu-Han Yange7baef32018-02-09 13:58:17 -080032import android.location.GnssMeasurementsEvent;
33import android.location.GnssNavigationMessage;
Lifu Tang30f95a72016-01-07 23:20:38 -080034import android.location.GnssStatus;
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -070035import android.location.IGpsGeofenceHardware;
Danke Xie22d1f9f2009-08-18 18:28:45 -040036import android.location.INetInitiatedListener;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080037import android.location.Location;
Nick Pelly6fa9ad42012-07-16 12:18:23 -070038import android.location.LocationListener;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080039import android.location.LocationManager;
40import android.location.LocationProvider;
Stan Chesnutt1d72d8c2013-04-15 19:18:02 -070041import android.location.LocationRequest;
Kevin Tang40e1baf2012-01-10 14:32:44 -080042import android.os.AsyncTask;
Dianne Hackborn91268cf2013-06-13 19:06:50 -070043import android.os.BatteryStats;
Mike Lockwood63aa5a62010-04-14 19:21:31 -040044import android.os.Binder;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080045import android.os.Bundle;
Mike Lockwood62a8fc12010-03-22 14:23:26 -040046import android.os.Handler;
Victoria Lease5cd731a2012-12-19 15:04:21 -080047import android.os.Looper;
Mike Lockwood62a8fc12010-03-22 14:23:26 -040048import android.os.Message;
Yu-Han Yange7baef32018-02-09 13:58:17 -080049import android.os.PersistableBundle;
Mike Lockwood0528b9b2009-05-07 10:12:54 -040050import android.os.PowerManager;
Yu-Han Yange7baef32018-02-09 13:58:17 -080051import android.os.PowerManager.ServiceType;
52import android.os.PowerSaveState;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080053import android.os.RemoteException;
Mike Lockwood2f82c4e2009-04-17 08:24:10 -040054import android.os.ServiceManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080055import android.os.SystemClock;
Colin Cross7c030ed2014-01-28 09:33:53 -080056import android.os.SystemProperties;
Dianne Hackborn5ac72a22012-08-29 18:32:08 -070057import android.os.UserHandle;
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -070058import android.os.WorkSource;
Narayan Kamath32684dd2018-01-08 17:32:51 +000059import android.os.WorkSource.WorkChain;
Mike Lockwoodbcab8df2009-06-25 16:39:09 -040060import android.provider.Settings;
Yu-Han Yange7baef32018-02-09 13:58:17 -080061import android.telephony.CarrierConfigManager;
Wink Savillea374c3d2014-11-11 11:48:04 -080062import android.telephony.SubscriptionManager;
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 Yang8a1b51d2018-12-26 22:18:31 -080067import android.util.StatsLog;
WyattRileyba6072f2019-04-18 07:37:52 -070068import android.util.TimeUtils;
Yu-Han Yanga1862b52018-02-20 17:05:59 -080069
Anil Admal032aa812019-03-06 19:23:25 -080070import com.android.internal.annotations.GuardedBy;
jackqdyulei455e90a2017-02-09 15:29:16 -080071import com.android.internal.app.IBatteryStats;
72import com.android.internal.location.GpsNetInitiatedHandler;
73import com.android.internal.location.GpsNetInitiatedHandler.GpsNiNotification;
74import com.android.internal.location.ProviderProperties;
75import com.android.internal.location.ProviderRequest;
Yu-Han Yange7baef32018-02-09 13:58:17 -080076import com.android.internal.location.gnssmetrics.GnssMetrics;
Anil Admale1539e82019-05-09 15:05:04 -070077import com.android.internal.telephony.TelephonyIntents;
Yu-Han Yang66c7ea92018-03-11 17:17:15 -070078import com.android.server.location.GnssSatelliteBlacklistHelper.GnssSatelliteBlacklistCallback;
Yu-Han Yanga1862b52018-02-20 17:05:59 -080079import com.android.server.location.NtpTimeHelper.InjectNtpTimeCallback;
Yu-Han Yang66c7ea92018-03-11 17:17:15 -070080
Nick Pelly6fa9ad42012-07-16 12:18:23 -070081import java.io.FileDescriptor;
Nick Pelly6fa9ad42012-07-16 12:18:23 -070082import java.io.PrintWriter;
Soonil Nagarkar1575a042018-10-24 17:54:54 -070083import java.lang.annotation.ElementType;
84import java.lang.annotation.Retention;
85import java.lang.annotation.RetentionPolicy;
86import java.lang.annotation.Target;
Wyatt Rileycf879db2017-01-12 13:57:38 -080087import java.util.ArrayList;
Andreas Gampee6748ce2015-12-11 18:00:38 -080088import java.util.Arrays;
Wyatt Rileycf879db2017-01-12 13:57:38 -080089import java.util.List;
Yu-Han Yange7baef32018-02-09 13:58:17 -080090
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080091/**
gomo4402af62017-01-11 13:20:13 -080092 * A GNSS implementation of LocationProvider used by LocationManager.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080093 *
94 * {@hide}
95 */
Soonil Nagarkar1575a042018-10-24 17:54:54 -070096public class GnssLocationProvider extends AbstractLocationProvider implements
97 InjectNtpTimeCallback,
98 GnssSatelliteBlacklistCallback {
99
100 /**
101 * Indicates that this method is a native entry point. Useful purely for IDEs which can
102 * understand entry points, and thus eliminate incorrect warnings about methods not used.
103 */
104 @Target(ElementType.METHOD)
105 @Retention(RetentionPolicy.SOURCE)
106 private @interface NativeEntryPoint {
107 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800108
Lifu Tang30f95a72016-01-07 23:20:38 -0800109 private static final String TAG = "GnssLocationProvider";
Mike Lockwood29c84342009-05-06 14:01:15 -0400110
Brian Muramatsu1715cb32012-08-08 17:32:21 -0700111 private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
112 private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400113
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700114 private static final ProviderProperties PROPERTIES = new ProviderProperties(
115 true, true, false, false, true, true, true,
116 Criteria.POWER_HIGH, Criteria.ACCURACY_FINE);
117
gomo4402af62017-01-11 13:20:13 -0800118 // these need to match GnssPositionMode enum in IGnss.hal
The Android Open Source Project10592532009-03-18 17:39:46 -0700119 private static final int GPS_POSITION_MODE_STANDALONE = 0;
120 private static final int GPS_POSITION_MODE_MS_BASED = 1;
121 private static final int GPS_POSITION_MODE_MS_ASSISTED = 2;
122
gomo4402af62017-01-11 13:20:13 -0800123 // these need to match GnssPositionRecurrence enum in IGnss.hal
Mike Lockwood04598b62010-04-14 17:17:24 -0400124 private static final int GPS_POSITION_RECURRENCE_PERIODIC = 0;
125 private static final int GPS_POSITION_RECURRENCE_SINGLE = 1;
126
gomo4402af62017-01-11 13:20:13 -0800127 // these need to match GnssStatusValue enum in IGnssCallback.hal
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800128 private static final int GPS_STATUS_NONE = 0;
129 private static final int GPS_STATUS_SESSION_BEGIN = 1;
130 private static final int GPS_STATUS_SESSION_END = 2;
131 private static final int GPS_STATUS_ENGINE_ON = 3;
132 private static final int GPS_STATUS_ENGINE_OFF = 4;
133
gomo4402af62017-01-11 13:20:13 -0800134 // these need to match GnssLocationFlags enum in types.hal
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800135 private static final int LOCATION_INVALID = 0;
136 private static final int LOCATION_HAS_LAT_LONG = 1;
137 private static final int LOCATION_HAS_ALTITUDE = 2;
138 private static final int LOCATION_HAS_SPEED = 4;
139 private static final int LOCATION_HAS_BEARING = 8;
gomo4402af62017-01-11 13:20:13 -0800140 private static final int LOCATION_HAS_HORIZONTAL_ACCURACY = 16;
141 private static final int LOCATION_HAS_VERTICAL_ACCURACY = 32;
142 private static final int LOCATION_HAS_SPEED_ACCURACY = 64;
143 private static final int LOCATION_HAS_BEARING_ACCURACY = 128;
Mike Lockwoode3635c92009-05-11 08:38:02 -0400144
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -0800145 // these need to match ElapsedRealtimeFlags enum in types.hal
146 private static final int ELAPSED_REALTIME_HAS_TIMESTAMP_NS = 1;
Pierre Fite-Georgel9e96c572019-02-25 16:12:53 -0800147 private static final int ELAPSED_REALTIME_HAS_TIME_UNCERTAINTY_NS = 2;
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -0800148
gomo4402af62017-01-11 13:20:13 -0800149 // IMPORTANT - the GPS_DELETE_* symbols here must match GnssAidingData enum in IGnss.hal
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800150 private static final int GPS_DELETE_EPHEMERIS = 0x0001;
151 private static final int GPS_DELETE_ALMANAC = 0x0002;
152 private static final int GPS_DELETE_POSITION = 0x0004;
153 private static final int GPS_DELETE_TIME = 0x0008;
154 private static final int GPS_DELETE_IONO = 0x0010;
155 private static final int GPS_DELETE_UTC = 0x0020;
156 private static final int GPS_DELETE_HEALTH = 0x0040;
157 private static final int GPS_DELETE_SVDIR = 0x0080;
158 private static final int GPS_DELETE_SVSTEER = 0x0100;
159 private static final int GPS_DELETE_SADATA = 0x0200;
160 private static final int GPS_DELETE_RTI = 0x0400;
161 private static final int GPS_DELETE_CELLDB_INFO = 0x8000;
162 private static final int GPS_DELETE_ALL = 0xFFFF;
163
gomo4402af62017-01-11 13:20:13 -0800164 // The GPS_CAPABILITY_* flags must match Capabilities enum in IGnssCallback.hal
Mike Lockwood04598b62010-04-14 17:17:24 -0400165 private static final int GPS_CAPABILITY_SCHEDULING = 0x0000001;
166 private static final int GPS_CAPABILITY_MSB = 0x0000002;
167 private static final int GPS_CAPABILITY_MSA = 0x0000004;
168 private static final int GPS_CAPABILITY_SINGLE_SHOT = 0x0000008;
Mike Lockwood9b9fb5c2011-06-29 15:09:40 -0400169 private static final int GPS_CAPABILITY_ON_DEMAND_TIME = 0x0000010;
Anil Admalefd9dc62019-03-12 17:39:20 -0700170 public static final int GPS_CAPABILITY_GEOFENCING = 0x0000020;
gomo226b7b72018-12-12 16:49:39 -0800171 public static final int GPS_CAPABILITY_MEASUREMENTS = 0x0000040;
Anil Admalefd9dc62019-03-12 17:39:20 -0700172 public static final int GPS_CAPABILITY_NAV_MESSAGES = 0x0000080;
Anil Admal62c42dc2019-04-03 15:39:22 -0700173 public static final int GPS_CAPABILITY_LOW_POWER_MODE = 0x0000100;
174 public static final int GPS_CAPABILITY_SATELLITE_BLACKLIST = 0x0000200;
175 public static final int GPS_CAPABILITY_MEASUREMENT_CORRECTIONS = 0x0000400;
Mike Lockwood04598b62010-04-14 17:17:24 -0400176
Tsuwei Chen462bcd82014-09-17 12:28:49 -0700177 // The AGPS SUPL mode
178 private static final int AGPS_SUPL_MODE_MSA = 0x02;
179 private static final int AGPS_SUPL_MODE_MSB = 0x01;
180
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700181 private static final int SET_REQUEST = 3;
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400182 private static final int INJECT_NTP_TIME = 5;
Kevin Tang8c6ac672019-03-22 12:31:01 -0700183 // PSDS stands for Predicted Satellite Data Service
184 private static final int DOWNLOAD_PSDS_DATA = 6;
Wyatt Rileyc7067412018-02-07 15:50:35 -0800185 private static final int UPDATE_LOCATION = 7; // Handle external location from network listener
Kevin Tang8c6ac672019-03-22 12:31:01 -0700186 private static final int DOWNLOAD_PSDS_DATA_FINISHED = 11;
destradaafb23c672015-04-16 14:01:27 -0700187 private static final int INITIALIZE_HANDLER = 13;
Yu-Han Yange7baef32018-02-09 13:58:17 -0800188 private static final int REQUEST_LOCATION = 16;
Wyatt Riley26465d22018-02-12 13:44:24 -0800189 private static final int REPORT_LOCATION = 17; // HAL reports location
190 private static final int REPORT_SV_STATUS = 18; // HAL reports SV status
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400191
Miguel Torroja1e84da82010-07-27 07:02:24 +0200192 // Request setid
193 private static final int AGPS_RIL_REQUEST_SETID_IMSI = 1;
194 private static final int AGPS_RIL_REQUEST_SETID_MSISDN = 2;
195
Miguel Torroja1e84da82010-07-27 07:02:24 +0200196 // ref. location info
197 private static final int AGPS_REF_LOCATION_TYPE_GSM_CELLID = 1;
198 private static final int AGPS_REF_LOCATION_TYPE_UMTS_CELLID = 2;
Miguel Torroja1e84da82010-07-27 07:02:24 +0200199
200 // set id info
201 private static final int AGPS_SETID_TYPE_NONE = 0;
202 private static final int AGPS_SETID_TYPE_IMSI = 1;
203 private static final int AGPS_SETID_TYPE_MSISDN = 2;
204
gomo48f1a642017-11-10 20:35:46 -0800205 private static final int GPS_GEOFENCE_UNAVAILABLE = 1 << 0L;
206 private static final int GPS_GEOFENCE_AVAILABLE = 1 << 1L;
destradaa0682809a2013-08-12 18:50:30 -0700207
gomo4402af62017-01-11 13:20:13 -0800208 // GPS Geofence errors. Should match GeofenceStatus enum in IGnssGeofenceCallback.hal.
destradaa0682809a2013-08-12 18:50:30 -0700209 private static final int GPS_GEOFENCE_OPERATION_SUCCESS = 0;
210 private static final int GPS_GEOFENCE_ERROR_TOO_MANY_GEOFENCES = 100;
gomo48f1a642017-11-10 20:35:46 -0800211 private static final int GPS_GEOFENCE_ERROR_ID_EXISTS = -101;
destradaa0682809a2013-08-12 18:50:30 -0700212 private static final int GPS_GEOFENCE_ERROR_ID_UNKNOWN = -102;
213 private static final int GPS_GEOFENCE_ERROR_INVALID_TRANSITION = -103;
214 private static final int GPS_GEOFENCE_ERROR_GENERIC = -149;
215
Tsuwei Chen678c13c2014-09-22 17:48:41 -0700216 // TCP/IP constants.
217 // Valid TCP/UDP port range is (0, 65535].
218 private static final int TCP_MIN_PORT = 0;
219 private static final int TCP_MAX_PORT = 0xffff;
220
Yu-Han Yange7baef32018-02-09 13:58:17 -0800221 // 1 second, or 1 Hz frequency.
222 private static final long LOCATION_UPDATE_MIN_TIME_INTERVAL_MILLIS = 1000;
Yu-Han Yang639f7592018-06-07 11:58:52 -0700223 // Default update duration in milliseconds for REQUEST_LOCATION.
Yu-Han Yang9e2a8232018-06-14 12:10:08 -0700224 private static final long LOCATION_UPDATE_DURATION_MILLIS = 10 * 1000;
Anil Admalb1c6c0d2019-06-20 12:00:16 -0700225 // Update duration extension multiplier for emergency REQUEST_LOCATION.
226 private static final int EMERGENCY_LOCATION_UPDATE_DURATION_MULTIPLIER = 3;
Yu-Han Yange7baef32018-02-09 13:58:17 -0800227
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700228 /** simpler wrapper for ProviderRequest + Worksource */
229 private static class GpsRequest {
230 public ProviderRequest request;
231 public WorkSource source;
gomo48f1a642017-11-10 20:35:46 -0800232
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700233 public GpsRequest(ProviderRequest request, WorkSource source) {
234 this.request = request;
235 this.source = source;
236 }
237 }
238
Wyatt Riley26465d22018-02-12 13:44:24 -0800239 // Threadsafe class to hold stats reported in the Extras Bundle
Wyatt Rileyc7067412018-02-07 15:50:35 -0800240 private static class LocationExtras {
241 private int mSvCount;
242 private int mMeanCn0;
243 private int mMaxCn0;
244 private final Bundle mBundle;
245
246 public LocationExtras() {
247 mBundle = new Bundle();
248 }
249
250 public void set(int svCount, int meanCn0, int maxCn0) {
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700251 synchronized (this) {
Wyatt Riley26465d22018-02-12 13:44:24 -0800252 mSvCount = svCount;
253 mMeanCn0 = meanCn0;
254 mMaxCn0 = maxCn0;
255 }
Wyatt Rileyc7067412018-02-07 15:50:35 -0800256 setBundle(mBundle);
257 }
258
259 public void reset() {
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700260 set(0, 0, 0);
Wyatt Rileyc7067412018-02-07 15:50:35 -0800261 }
262
263 // Also used by outside methods to add to other bundles
264 public void setBundle(Bundle extras) {
265 if (extras != null) {
Wyatt Riley26465d22018-02-12 13:44:24 -0800266 synchronized (this) {
267 extras.putInt("satellites", mSvCount);
268 extras.putInt("meanCn0", mMeanCn0);
269 extras.putInt("maxCn0", mMaxCn0);
270 }
Wyatt Rileyc7067412018-02-07 15:50:35 -0800271 }
272 }
273
274 public Bundle getBundle() {
Wyatt Riley26465d22018-02-12 13:44:24 -0800275 synchronized (this) {
276 return new Bundle(mBundle);
277 }
Wyatt Rileyc7067412018-02-07 15:50:35 -0800278 }
279 }
280
Yu-Han Yang66c7ea92018-03-11 17:17:15 -0700281 private final Object mLock = new Object();
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700282
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800283 // current status
Mike Lockwood15e3d0f2009-05-01 07:53:28 -0400284 private int mStatus = LocationProvider.TEMPORARILY_UNAVAILABLE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800285
286 // time for last status update
287 private long mStatusUpdateTime = SystemClock.elapsedRealtime();
Mike Lockwoodd53ba012010-04-15 20:41:26 -0400288
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800289 // turn off GPS fix icon if we haven't received a fix in 10 seconds
Mike Lockwood04598b62010-04-14 17:17:24 -0400290 private static final long RECENT_FIX_TIMEOUT = 10 * 1000;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800291
Mike Lockwood0632ca72009-05-14 15:51:03 -0400292 // stop trying if we do not receive a fix within 60 seconds
Mike Lockwood04598b62010-04-14 17:17:24 -0400293 private static final int NO_FIX_TIMEOUT = 60 * 1000;
Mike Lockwood0632ca72009-05-14 15:51:03 -0400294
Nick Pellyb041f232012-05-07 17:12:25 -0700295 // if the fix interval is below this we leave GPS on,
296 // if above then we cycle the GPS driver.
297 // Typical hot TTTF is ~5 seconds, so 10 seconds seems sane.
298 private static final int GPS_POLLING_THRESHOLD_INTERVAL = 10 * 1000;
299
Kevin Tang8c6ac672019-03-22 12:31:01 -0700300 // how long to wait if we have a network error in NTP or PSDS downloading
Wei Liu6f6326b2015-06-24 23:47:50 -0700301 // the initial value of the exponential backoff
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700302 // current setting - 5 minutes
gomo48f1a642017-11-10 20:35:46 -0800303 private static final long RETRY_INTERVAL = 5 * 60 * 1000;
Kevin Tang8c6ac672019-03-22 12:31:01 -0700304 // how long to wait if we have a network error in NTP or PSDS downloading
Wei Liu6f6326b2015-06-24 23:47:50 -0700305 // the max value of the exponential backoff
306 // current setting - 4 hours
gomo48f1a642017-11-10 20:35:46 -0800307 private static final long MAX_RETRY_INTERVAL = 4 * 60 * 60 * 1000;
Wei Liu6f6326b2015-06-24 23:47:50 -0700308
Kevin Tang8c6ac672019-03-22 12:31:01 -0700309 // Timeout when holding wakelocks for downloading PSDS data.
310 private static final long DOWNLOAD_PSDS_DATA_TIMEOUT_MS = 60 * 1000;
Wei Wangc5706f62017-04-18 11:26:26 -0700311
Kevin Tang8c6ac672019-03-22 12:31:01 -0700312 private final ExponentialBackOff mPsdsBackOff = new ExponentialBackOff(RETRY_INTERVAL,
Yu-Han Yanga1862b52018-02-20 17:05:59 -0800313 MAX_RETRY_INTERVAL);
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700314
Yu-Han Yang76f99952019-05-04 17:45:44 -0700315 // True if we are enabled
316 @GuardedBy("mLock")
317 private boolean mGpsEnabled;
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700318
Soonil Nagarkar35c3b912019-01-31 10:31:24 -0800319 private boolean mShutdown;
320
Kevin Tang8c6ac672019-03-22 12:31:01 -0700321 // states for injecting ntp and downloading psds data
Kevin Tang40e1baf2012-01-10 14:32:44 -0800322 private static final int STATE_PENDING_NETWORK = 0;
323 private static final int STATE_DOWNLOADING = 1;
324 private static final int STATE_IDLE = 2;
325
Kevin Tang8c6ac672019-03-22 12:31:01 -0700326 // flags to trigger NTP or PSDS data download when network becomes available
327 // initialized to true so we do NTP and PSDS when the network comes up after booting
328 private int mDownloadPsdsDataPending = STATE_PENDING_NETWORK;
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400329
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800330 // true if GPS is navigating
331 private boolean mNavigating;
Mike Lockwoodcf1d8cb2010-01-20 10:14:54 -0500332
Mike Lockwood04598b62010-04-14 17:17:24 -0400333 // requested frequency of fixes, in milliseconds
334 private int mFixInterval = 1000;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800335
gomo48f1a642017-11-10 20:35:46 -0800336 // true if low power mode for the GNSS chipset is part of the latest request.
337 private boolean mLowPowerMode = false;
338
WyattRileyba6072f2019-04-18 07:37:52 -0700339 // true if we started navigation in the HAL, only change value of this in setStarted
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800340 private boolean mStarted;
341
WyattRileyba6072f2019-04-18 07:37:52 -0700342 // for logging of latest change, and warning of ongoing location after a stop
343 private long mStartedChangedElapsedRealtime;
344
345 // threshold for delay in GNSS engine turning off before warning & error
346 private static final long LOCATION_OFF_DELAY_THRESHOLD_WARN_MILLIS = 2 * 1000;
347 private static final long LOCATION_OFF_DELAY_THRESHOLD_ERROR_MILLIS = 15 * 1000;
348
Anil Admal312fddb2019-03-25 12:15:43 -0700349 // capabilities reported through the top level IGnssCallback.hal
350 private volatile int mTopHalCapabilities;
Mike Lockwood04598b62010-04-14 17:17:24 -0400351
Kevin Tang8c6ac672019-03-22 12:31:01 -0700352 // true if PSDS is supported
353 private boolean mSupportsPsds;
Mike Lockwood1a1cd3a2010-08-17 07:42:54 -0400354
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800355 // for calculating time to first fix
356 private long mFixRequestTime = 0;
357 // time to first fix for most recent session
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700358 private int mTimeToFirstFix = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800359 // time we received our last fix
360 private long mLastFixTime;
361
Mike Lockwood04598b62010-04-14 17:17:24 -0400362 private int mPositionMode;
Yu-Han Yangc8b9ff72018-04-17 00:47:24 -0700363 private GnssPositionMode mLastPositionMode;
Mike Lockwood04598b62010-04-14 17:17:24 -0400364
David Christied4edf4c2014-08-12 15:22:27 -0700365 // Current request from underlying location clients.
Soonil Nagarkar35c3b912019-01-31 10:31:24 -0800366 private ProviderRequest mProviderRequest;
Narayan Kamath32684dd2018-01-08 17:32:51 +0000367 // The WorkSource associated with the most recent client request (i.e, most recent call to
368 // setRequest).
David Christied4edf4c2014-08-12 15:22:27 -0700369 private WorkSource mWorkSource = null;
WyattRileyb2446072019-03-01 07:41:49 -0800370 // True if gps should be disabled because of PowerManager controls
371 private boolean mDisableGpsForPowerManager = false;
David Christied4edf4c2014-08-12 15:22:27 -0700372
destradaafb23c672015-04-16 14:01:27 -0700373 /**
374 * Properties loaded from PROPERTIES_FILE.
375 * It must be accessed only inside {@link #mHandler}.
376 */
Anil Admald71cf142018-12-21 14:59:36 -0800377 private GnssConfiguration mGnssConfiguration;
destradaafb23c672015-04-16 14:01:27 -0700378
Mike Lockwood734d6032009-07-28 18:30:25 -0700379 private String mSuplServerHost;
Tsuwei Chen678c13c2014-09-22 17:48:41 -0700380 private int mSuplServerPort = TCP_MIN_PORT;
Mike Lockwood734d6032009-07-28 18:30:25 -0700381 private String mC2KServerHost;
382 private int mC2KServerPort;
Tsuwei Chen3324e952014-09-07 01:30:42 -0700383 private boolean mSuplEsEnabled = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800384
Anil Admal94ec76a2019-01-15 09:42:01 -0800385 private final Looper mLooper;
Wyatt Rileyc7067412018-02-07 15:50:35 -0800386 private final LocationExtras mLocationExtras = new LocationExtras();
Anil Admal75b9fd62018-11-28 11:22:50 -0800387 private final GnssStatusListenerHelper mGnssStatusListenerHelper;
Lifu Tang818aa2c2016-02-01 01:52:00 -0800388 private final GnssMeasurementsProvider mGnssMeasurementsProvider;
Anil Admalefd9dc62019-03-12 17:39:20 -0700389 private final GnssMeasurementCorrectionsProvider mGnssMeasurementCorrectionsProvider;
Lifu Tang818aa2c2016-02-01 01:52:00 -0800390 private final GnssNavigationMessageProvider mGnssNavigationMessageProvider;
Yu-Han Yang07561382018-02-21 13:08:37 -0800391 private final LocationChangeListener mNetworkLocationListener = new NetworkLocationListener();
392 private final LocationChangeListener mFusedLocationListener = new FusedLocationListener();
Yu-Han Yanga1862b52018-02-20 17:05:59 -0800393 private final NtpTimeHelper mNtpTimeHelper;
Yu-Han Yang3557cc72018-03-21 12:48:36 -0700394 private final GnssBatchingProvider mGnssBatchingProvider;
Yu-Han Yang890ca8b2018-04-16 22:11:31 -0700395 private final GnssGeofenceProvider mGnssGeofenceProvider;
Anil Admal312fddb2019-03-25 12:15:43 -0700396 private final GnssCapabilitiesProvider mGnssCapabilitiesProvider;
397
Anil Admal316f9482019-02-12 18:57:18 -0800398 // Available only on GNSS HAL 2.0 implementations and later.
Anil Admal94ec76a2019-01-15 09:42:01 -0800399 private GnssVisibilityControl mGnssVisibilityControl;
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400400
Victoria Lease5c24fd02012-10-01 11:00:50 -0700401 // Handler for processing events
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400402 private Handler mHandler;
The Android Open Source Project10592532009-03-18 17:39:46 -0700403
Anil Admal50ba15e2018-11-01 16:42:42 -0700404 private final GnssNetworkConnectivityHandler mNetworkConnectivityHandler;
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700405 private final GpsNetInitiatedHandler mNIHandler;
Mike Lockwood2f82c4e2009-04-17 08:24:10 -0400406
Mike Lockwood0528b9b2009-05-07 10:12:54 -0400407 // Wakelocks
Lifu Tang30f95a72016-01-07 23:20:38 -0800408 private final static String WAKELOCK_KEY = "GnssLocationProvider";
Mike Lockwood0528b9b2009-05-07 10:12:54 -0400409 private final PowerManager.WakeLock mWakeLock;
Kevin Tang8c6ac672019-03-22 12:31:01 -0700410 private static final String DOWNLOAD_EXTRA_WAKELOCK_KEY = "GnssLocationProviderPsdsDownload";
Yu-Han Yang76f99952019-05-04 17:45:44 -0700411 @GuardedBy("mLock")
Kevin Tang8c6ac672019-03-22 12:31:01 -0700412 private final PowerManager.WakeLock mDownloadPsdsWakeLock;
Mike Lockwood0528b9b2009-05-07 10:12:54 -0400413
Mike Lockwood29c84342009-05-06 14:01:15 -0400414 // Alarms
415 private final static String ALARM_WAKEUP = "com.android.internal.location.ALARM_WAKEUP";
Mike Lockwood0632ca72009-05-14 15:51:03 -0400416 private final static String ALARM_TIMEOUT = "com.android.internal.location.ALARM_TIMEOUT";
Tsuwei Chen52617bb2014-08-25 11:49:11 -0700417
David Christied4edf4c2014-08-12 15:22:27 -0700418 private final PowerManager mPowerManager;
Mike Lockwood29c84342009-05-06 14:01:15 -0400419 private final AlarmManager mAlarmManager;
420 private final PendingIntent mWakeupIntent;
Mike Lockwood0632ca72009-05-14 15:51:03 -0400421 private final PendingIntent mTimeoutIntent;
Mike Lockwood29c84342009-05-06 14:01:15 -0400422
Svet Ganovf7b47252018-02-26 11:11:27 -0800423 private final AppOpsManager mAppOps;
Mike Lockwood2f82c4e2009-04-17 08:24:10 -0400424 private final IBatteryStats mBatteryStats;
The Android Open Source Project10592532009-03-18 17:39:46 -0700425
Narayan Kamath32684dd2018-01-08 17:32:51 +0000426 // Current list of underlying location clients.
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700427 // only modified on handler thread
Dianne Hackborn002a54e2013-01-10 17:34:55 -0800428 private WorkSource mClientSource = new WorkSource();
Mike Lockwoodf1218be2010-01-29 09:20:06 -0500429
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -0700430 private GeofenceHardwareImpl mGeofenceHardwareImpl;
Wyatt Rileyd87cf912017-12-05 09:31:52 -0800431
432 // Volatile for simple inter-thread sync on these values.
433 private volatile int mHardwareYear = 0;
Wyatt Riley49097c02018-03-15 09:14:43 -0700434 private volatile String mHardwareModelName;
Lifu Tang82f893d2016-01-21 18:15:33 -0800435
Wyatt Riley5d5bac82016-11-01 07:05:16 -0700436 // Set lower than the current ITAR limit of 600m/s to allow this to trigger even if GPS HAL
437 // stops output right at 600m/s, depriving this of the information of a device that reaches
438 // greater than 600m/s, and higher than the speed of sound to avoid impacting most use cases.
439 private static final float ITAR_SPEED_LIMIT_METERS_PER_SECOND = 400.0F;
Wyatt Riley042c48f2017-10-06 14:59:25 -0700440
Wyatt Riley042c48f2017-10-06 14:59:25 -0700441 private volatile boolean mItarSpeedLimitExceeded = false;
Wyatt Riley5d5bac82016-11-01 07:05:16 -0700442
Siddharth Raybb608c82017-03-16 11:33:34 -0700443 // GNSS Metrics
444 private GnssMetrics mGnssMetrics;
445
Anil Admal75b9fd62018-11-28 11:22:50 -0800446 public GnssStatusListenerHelper getGnssStatusProvider() {
447 return mGnssStatusListenerHelper;
Mike Lockwood15e3d0f2009-05-01 07:53:28 -0400448 }
449
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -0700450 public IGpsGeofenceHardware getGpsGeofenceProxy() {
Yu-Han Yang890ca8b2018-04-16 22:11:31 -0700451 return mGnssGeofenceProvider;
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -0700452 }
453
Lifu Tang818aa2c2016-02-01 01:52:00 -0800454 public GnssMeasurementsProvider getGnssMeasurementsProvider() {
455 return mGnssMeasurementsProvider;
destradaaea8a8a62014-06-23 18:19:03 -0700456 }
457
Anil Admalefd9dc62019-03-12 17:39:20 -0700458 public GnssMeasurementCorrectionsProvider getGnssMeasurementCorrectionsProvider() {
459 return mGnssMeasurementCorrectionsProvider;
460 }
461
Lifu Tang818aa2c2016-02-01 01:52:00 -0800462 public GnssNavigationMessageProvider getGnssNavigationMessageProvider() {
463 return mGnssNavigationMessageProvider;
destradaa4b3e3932014-07-21 18:01:47 -0700464 }
Tsuwei Chen52617bb2014-08-25 11:49:11 -0700465 private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
gomo48f1a642017-11-10 20:35:46 -0800466 @Override
467 public void onReceive(Context context, Intent intent) {
The Android Open Source Project10592532009-03-18 17:39:46 -0700468 String action = intent.getAction();
Tsuwei Chen48d37f92014-09-05 15:15:34 -0700469 if (DEBUG) Log.d(TAG, "receive broadcast intent, action: " + action);
destradaaee9fd342015-08-31 13:31:17 -0700470 if (action == null) {
471 return;
472 }
473
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700474 switch (action) {
475 case ALARM_WAKEUP:
Yu-Han Yang6a5f0b72019-01-24 18:34:28 -0800476 startNavigating();
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700477 break;
478 case ALARM_TIMEOUT:
479 hibernate();
480 break;
481 case PowerManager.ACTION_POWER_SAVE_MODE_CHANGED:
482 case PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED:
483 case Intent.ACTION_SCREEN_OFF:
484 case Intent.ACTION_SCREEN_ON:
485 updateLowPowerMode();
486 break;
Meng Wang19b214d2018-11-07 12:14:39 -0800487 case CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED:
Anil Admale1539e82019-05-09 15:05:04 -0700488 case TelephonyIntents.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED:
Meng Wang19b214d2018-11-07 12:14:39 -0800489 subscriptionOrCarrierConfigChanged(context);
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700490 break;
David Christied4edf4c2014-08-12 15:22:27 -0700491 }
The Android Open Source Project10592532009-03-18 17:39:46 -0700492 }
Mike Lockwood29c84342009-05-06 14:01:15 -0400493 };
The Android Open Source Project10592532009-03-18 17:39:46 -0700494
Yu-Han Yang66c7ea92018-03-11 17:17:15 -0700495 /**
496 * Implements {@link GnssSatelliteBlacklistCallback#onUpdateSatelliteBlacklist}.
497 */
498 @Override
499 public void onUpdateSatelliteBlacklist(int[] constellations, int[] svids) {
Anil Admald71cf142018-12-21 14:59:36 -0800500 mHandler.post(() -> mGnssConfiguration.setSatelliteBlacklist(constellations, svids));
Yu-Han Yang284234e2019-03-28 19:35:57 -0700501 mGnssMetrics.resetConstellationTypes();
Yu-Han Yang66c7ea92018-03-11 17:17:15 -0700502 }
503
Meng Wang19b214d2018-11-07 12:14:39 -0800504 private void subscriptionOrCarrierConfigChanged(Context context) {
Joe Onorato0c484102016-02-01 18:04:24 -0800505 if (DEBUG) Log.d(TAG, "received SIM related action: ");
Wink Savillea374c3d2014-11-11 11:48:04 -0800506 TelephonyManager phone = (TelephonyManager)
507 mContext.getSystemService(Context.TELEPHONY_SERVICE);
Ecco Park4fa1ab72016-10-24 13:04:52 -0700508 CarrierConfigManager configManager = (CarrierConfigManager)
509 mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE);
Anil Admale1539e82019-05-09 15:05:04 -0700510 int ddSubId = SubscriptionManager.getDefaultDataSubscriptionId();
511 String mccMnc = SubscriptionManager.isValidSubscriptionId(ddSubId)
512 ? phone.getSimOperator(ddSubId) : phone.getSimOperator();
Ecco Park4fa1ab72016-10-24 13:04:52 -0700513 boolean isKeepLppProfile = false;
Wink Savillea374c3d2014-11-11 11:48:04 -0800514 if (!TextUtils.isEmpty(mccMnc)) {
Joe Onorato0c484102016-02-01 18:04:24 -0800515 if (DEBUG) Log.d(TAG, "SIM MCC/MNC is available: " + mccMnc);
Yu-Han Yang76f99952019-05-04 17:45:44 -0700516 if (configManager != null) {
Anil Admale1539e82019-05-09 15:05:04 -0700517 PersistableBundle b = SubscriptionManager.isValidSubscriptionId(ddSubId)
518 ? configManager.getConfigForSubId(ddSubId) : null;
Yu-Han Yang76f99952019-05-04 17:45:44 -0700519 if (b != null) {
520 isKeepLppProfile =
521 b.getBoolean(CarrierConfigManager.Gps.KEY_PERSIST_LPP_MODE_BOOL);
Ecco Park4fa1ab72016-10-24 13:04:52 -0700522 }
Wink Savillea374c3d2014-11-11 11:48:04 -0800523 }
Yu-Han Yang76f99952019-05-04 17:45:44 -0700524 if (isKeepLppProfile) {
525 // load current properties for the carrier
526 mGnssConfiguration.loadPropertiesFromCarrierConfig();
527 String lpp_profile = mGnssConfiguration.getLppProfile();
528 // set the persist property LPP_PROFILE for the value
529 if (lpp_profile != null) {
530 SystemProperties.set(GnssConfiguration.LPP_PROFILE, lpp_profile);
531 }
532 } else {
533 // reset the persist property
534 SystemProperties.set(GnssConfiguration.LPP_PROFILE, "");
535 }
536 reloadGpsProperties();
Wink Savillea374c3d2014-11-11 11:48:04 -0800537 } else {
Joe Onorato0c484102016-02-01 18:04:24 -0800538 if (DEBUG) Log.d(TAG, "SIM MCC/MNC is still not available");
Wink Savillea374c3d2014-11-11 11:48:04 -0800539 }
540 }
541
David Christied4edf4c2014-08-12 15:22:27 -0700542 private void updateLowPowerMode() {
Adam Lesinski87c17df2015-05-27 13:24:13 -0700543 // Disable GPS if we are in device idle mode.
WyattRileyb2446072019-03-01 07:41:49 -0800544 boolean disableGpsForPowerManager = mPowerManager.isDeviceIdleMode();
jackqdyulei455e90a2017-02-09 15:29:16 -0800545 final PowerSaveState result =
Kweku Adams731a1032019-02-04 14:05:41 -0800546 mPowerManager.getPowerSaveState(ServiceType.LOCATION);
547 switch (result.locationMode) {
Makoto Onuki57f0f552017-12-11 12:22:18 -0800548 case PowerManager.LOCATION_MODE_GPS_DISABLED_WHEN_SCREEN_OFF:
Kweku Adams5e0052b2019-02-22 15:17:52 -0800549 case PowerManager.LOCATION_MODE_ALL_DISABLED_WHEN_SCREEN_OFF:
Adam Lesinski87c17df2015-05-27 13:24:13 -0700550 // If we are in battery saver mode and the screen is off, disable GPS.
WyattRileyb2446072019-03-01 07:41:49 -0800551 disableGpsForPowerManager |=
552 result.batterySaverEnabled && !mPowerManager.isInteractive();
David Christied4edf4c2014-08-12 15:22:27 -0700553 break;
David Christied4edf4c2014-08-12 15:22:27 -0700554 }
WyattRileyb2446072019-03-01 07:41:49 -0800555 if (disableGpsForPowerManager != mDisableGpsForPowerManager) {
556 mDisableGpsForPowerManager = disableGpsForPowerManager;
Soonil Nagarkar35c3b912019-01-31 10:31:24 -0800557 updateEnabled();
David Christied4edf4c2014-08-12 15:22:27 -0700558 updateRequirements();
559 }
560 }
561
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800562 public static boolean isSupported() {
563 return native_is_supported();
564 }
565
Anil Admald71cf142018-12-21 14:59:36 -0800566 private void reloadGpsProperties() {
567 mGnssConfiguration.reloadGpsProperties();
568 setSuplHostPort();
Tsuwei Chen52617bb2014-08-25 11:49:11 -0700569 // TODO: we should get rid of C2K specific setting.
Anil Admald71cf142018-12-21 14:59:36 -0800570 mC2KServerHost = mGnssConfiguration.getC2KHost();
571 mC2KServerPort = mGnssConfiguration.getC2KPort(TCP_MIN_PORT);
572 mNIHandler.setEmergencyExtensionSeconds(mGnssConfiguration.getEsExtensionSec());
573 mSuplEsEnabled = mGnssConfiguration.getSuplEs(0) == 1;
Anil Admale1539e82019-05-09 15:05:04 -0700574 mNIHandler.setSuplEsEnabled(mSuplEsEnabled);
Anil Admal94ec76a2019-01-15 09:42:01 -0800575 if (mGnssVisibilityControl != null) {
Anil Admale1539e82019-05-09 15:05:04 -0700576 mGnssVisibilityControl.onConfigurationUpdated(mGnssConfiguration);
Anil Admal94ec76a2019-01-15 09:42:01 -0800577 }
Colin Cross7c030ed2014-01-28 09:33:53 -0800578 }
579
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700580 public GnssLocationProvider(Context context, LocationProviderManager locationProviderManager,
Victoria Lease5cd731a2012-12-19 15:04:21 -0800581 Looper looper) {
Soonil Nagarkar0d77ea62019-01-31 14:36:56 -0800582 super(context, locationProviderManager);
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700583
Anil Admal94ec76a2019-01-15 09:42:01 -0800584 mLooper = looper;
Mike Lockwood63598a02010-02-24 11:52:59 -0500585
Mike Lockwood0528b9b2009-05-07 10:12:54 -0400586 // Create a wake lock
David Christied4edf4c2014-08-12 15:22:27 -0700587 mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
588 mWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, WAKELOCK_KEY);
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700589 mWakeLock.setReferenceCounted(true);
Mike Lockwood0528b9b2009-05-07 10:12:54 -0400590
Kevin Tang8c6ac672019-03-22 12:31:01 -0700591 // Create a separate wake lock for psds downloader as it may be released due to timeout.
592 mDownloadPsdsWakeLock = mPowerManager.newWakeLock(
Wei Wangb71c0492017-05-01 20:24:19 -0700593 PowerManager.PARTIAL_WAKE_LOCK, DOWNLOAD_EXTRA_WAKELOCK_KEY);
Kevin Tang8c6ac672019-03-22 12:31:01 -0700594 mDownloadPsdsWakeLock.setReferenceCounted(true);
Wei Wangb71c0492017-05-01 20:24:19 -0700595
gomo48f1a642017-11-10 20:35:46 -0800596 mAlarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
Mike Lockwood29c84342009-05-06 14:01:15 -0400597 mWakeupIntent = PendingIntent.getBroadcast(mContext, 0, new Intent(ALARM_WAKEUP), 0);
Mike Lockwood0632ca72009-05-14 15:51:03 -0400598 mTimeoutIntent = PendingIntent.getBroadcast(mContext, 0, new Intent(ALARM_TIMEOUT), 0);
Mike Lockwood29c84342009-05-06 14:01:15 -0400599
Anil Admal312fddb2019-03-25 12:15:43 -0700600 mNetworkConnectivityHandler = new GnssNetworkConnectivityHandler(context,
601 GnssLocationProvider.this::onNetworkAvailable, looper);
Mike Lockwood58bda982009-04-14 16:25:07 -0400602
Dianne Hackborna06de0f2012-12-11 16:34:47 -0800603 // App ops service to keep track of who is accessing the GPS
Svet Ganovf7b47252018-02-26 11:11:27 -0800604 mAppOps = mContext.getSystemService(AppOpsManager.class);
Dianne Hackborna06de0f2012-12-11 16:34:47 -0800605
Mike Lockwood2f82c4e2009-04-17 08:24:10 -0400606 // Battery statistics service to be notified when GPS turns on or off
Dianne Hackborn91268cf2013-06-13 19:06:50 -0700607 mBatteryStats = IBatteryStats.Stub.asInterface(ServiceManager.getService(
608 BatteryStats.SERVICE_NAME));
Mike Lockwood2f82c4e2009-04-17 08:24:10 -0400609
destradaafb23c672015-04-16 14:01:27 -0700610 // Construct internal handler
611 mHandler = new ProviderHandler(looper);
612
613 // Load GPS configuration and register listeners in the background:
614 // some operations, such as opening files and registering broadcast receivers, can take a
615 // relative long time, so the ctor() is kept to create objects needed by this instance,
616 // while IO initialization and registration is delegated to our internal handler
617 // this approach is just fine because events are posted to our handler anyway
Anil Admald71cf142018-12-21 14:59:36 -0800618 mGnssConfiguration = new GnssConfiguration(mContext);
Anil Admal312fddb2019-03-25 12:15:43 -0700619 mGnssCapabilitiesProvider = new GnssCapabilitiesProvider();
WyattRileyd1309312019-02-28 12:11:45 -0800620 // Create a GPS net-initiated handler (also needed by handleInitialize)
Tsuwei Chen3324e952014-09-07 01:30:42 -0700621 mNIHandler = new GpsNetInitiatedHandler(context,
gomo48f1a642017-11-10 20:35:46 -0800622 mNetInitiatedListener,
623 mSuplEsEnabled);
WyattRileyd1309312019-02-28 12:11:45 -0800624 sendMessage(INITIALIZE_HANDLER, 0, null);
Tsuwei Chen3324e952014-09-07 01:30:42 -0700625
Anil Admal75b9fd62018-11-28 11:22:50 -0800626 mGnssStatusListenerHelper = new GnssStatusListenerHelper(mContext, mHandler) {
destradaa6568d702014-10-27 12:47:41 -0700627 @Override
628 protected boolean isAvailableInPlatform() {
destradaa13a60b02015-01-15 18:36:01 -0800629 return isSupported();
destradaa6568d702014-10-27 12:47:41 -0700630 }
631
632 @Override
633 protected boolean isGpsEnabled() {
Yu-Han Yang76f99952019-05-04 17:45:44 -0700634 return GnssLocationProvider.this.isGpsEnabled();
destradaa6568d702014-10-27 12:47:41 -0700635 }
636 };
637
Yu-Han Yang8de21502018-04-23 01:40:25 -0700638 mGnssMeasurementsProvider = new GnssMeasurementsProvider(mContext, mHandler) {
destradaa6568d702014-10-27 12:47:41 -0700639 @Override
640 protected boolean isGpsEnabled() {
Yu-Han Yang76f99952019-05-04 17:45:44 -0700641 return GnssLocationProvider.this.isGpsEnabled();
destradaa6568d702014-10-27 12:47:41 -0700642 }
643 };
644
Anil Admalefd9dc62019-03-12 17:39:20 -0700645 mGnssMeasurementCorrectionsProvider = new GnssMeasurementCorrectionsProvider(mHandler);
646
Anil Admal75b9fd62018-11-28 11:22:50 -0800647 mGnssNavigationMessageProvider = new GnssNavigationMessageProvider(mContext, mHandler) {
destradaa6568d702014-10-27 12:47:41 -0700648 @Override
destradaa6568d702014-10-27 12:47:41 -0700649 protected boolean isGpsEnabled() {
Yu-Han Yang76f99952019-05-04 17:45:44 -0700650 return GnssLocationProvider.this.isGpsEnabled();
destradaa6568d702014-10-27 12:47:41 -0700651 }
652 };
Yu-Han Yanga1862b52018-02-20 17:05:59 -0800653
Anil Admal50ba15e2018-11-01 16:42:42 -0700654 mGnssMetrics = new GnssMetrics(mBatteryStats);
Yu-Han Yang66c7ea92018-03-11 17:17:15 -0700655 mNtpTimeHelper = new NtpTimeHelper(mContext, looper, this);
Soonil Nagarkar35c3b912019-01-31 10:31:24 -0800656 GnssSatelliteBlacklistHelper gnssSatelliteBlacklistHelper =
657 new GnssSatelliteBlacklistHelper(mContext,
658 looper, this);
659 mHandler.post(gnssSatelliteBlacklistHelper::updateSatelliteBlacklist);
Yu-Han Yang3557cc72018-03-21 12:48:36 -0700660 mGnssBatchingProvider = new GnssBatchingProvider();
Yu-Han Yang6dc9f052018-12-04 17:11:24 -0800661 mGnssGeofenceProvider = new GnssGeofenceProvider();
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400662
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700663 mContext.registerReceiverAsUser(new BroadcastReceiver() {
664 @Override
665 public void onReceive(Context context, Intent intent) {
666 if (getSendingUserId() == UserHandle.USER_ALL) {
Soonil Nagarkar35c3b912019-01-31 10:31:24 -0800667 mShutdown = true;
668 updateEnabled();
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700669 }
670 }
Soonil Nagarkar35c3b912019-01-31 10:31:24 -0800671 }, UserHandle.ALL, new IntentFilter(Intent.ACTION_SHUTDOWN), null, mHandler);
672
673 mContext.getContentResolver().registerContentObserver(
674 Settings.Secure.getUriFor(Settings.Secure.LOCATION_MODE),
675 true,
676 new ContentObserver(mHandler) {
677 @Override
678 public void onChange(boolean selfChange) {
679 updateEnabled();
680 }
681 }, UserHandle.USER_ALL);
Mike Lockwoodd03ff942010-02-09 08:46:14 -0500682
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700683 setProperties(PROPERTIES);
Soonil Nagarkar90da1ab2019-01-04 16:26:59 -0800684 setEnabled(true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800685 }
686
Yu-Han Yanga1862b52018-02-20 17:05:59 -0800687 /**
688 * Implements {@link InjectNtpTimeCallback#injectTime}
689 */
690 @Override
691 public void injectTime(long time, long timeReference, int uncertainty) {
692 native_inject_time(time, timeReference, uncertainty);
693 }
694
Anil Admal50ba15e2018-11-01 16:42:42 -0700695 /**
696 * Implements {@link GnssNetworkConnectivityHandler.GnssNetworkListener#onNetworkAvailable()}
697 */
698 private void onNetworkAvailable() {
699 mNtpTimeHelper.onNetworkAvailable();
Kevin Tang8c6ac672019-03-22 12:31:01 -0700700 if (mDownloadPsdsDataPending == STATE_PENDING_NETWORK) {
701 if (mSupportsPsds) {
Anil Admal316f9482019-02-12 18:57:18 -0800702 // Download only if supported, (prevents an unnecessary on-boot download)
Kevin Tang8c6ac672019-03-22 12:31:01 -0700703 psdsDownloadRequest();
destradaaef752b62015-04-17 13:10:47 -0700704 }
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400705 }
706 }
Yu-Han Yang8de21502018-04-23 01:40:25 -0700707
Yu-Han Yang53f4d6d2019-02-13 21:47:41 -0800708 private void handleRequestLocation(boolean independentFromGnss, boolean isUserEmergency) {
Yu-Han Yange7baef32018-02-09 13:58:17 -0800709 if (isRequestLocationRateLimited()) {
710 if (DEBUG) {
711 Log.d(TAG, "RequestLocation is denied due to too frequent requests.");
712 }
713 return;
714 }
Yu-Han Yang74041ff2018-04-06 15:57:31 -0700715 ContentResolver resolver = mContext.getContentResolver();
716 long durationMillis = Settings.Global.getLong(
717 resolver,
718 Settings.Global.GNSS_HAL_LOCATION_REQUEST_DURATION_MILLIS,
719 LOCATION_UPDATE_DURATION_MILLIS);
720 if (durationMillis == 0) {
721 Log.i(TAG, "GNSS HAL location request is disabled by Settings.");
722 return;
723 }
Yu-Han Yange7baef32018-02-09 13:58:17 -0800724
725 LocationManager locationManager = (LocationManager) mContext.getSystemService(
726 Context.LOCATION_SERVICE);
Yu-Han Yang07561382018-02-21 13:08:37 -0800727 String provider;
728 LocationChangeListener locationListener;
Anil Admalb1c6c0d2019-06-20 12:00:16 -0700729 LocationRequest locationRequest = new LocationRequest()
730 .setInterval(LOCATION_UPDATE_MIN_TIME_INTERVAL_MILLIS)
731 .setFastestInterval(LOCATION_UPDATE_MIN_TIME_INTERVAL_MILLIS);
Yu-Han Yange7baef32018-02-09 13:58:17 -0800732
733 if (independentFromGnss) {
734 // For fast GNSS TTFF
Yu-Han Yang07561382018-02-21 13:08:37 -0800735 provider = LocationManager.NETWORK_PROVIDER;
736 locationListener = mNetworkLocationListener;
Anil Admalb1c6c0d2019-06-20 12:00:16 -0700737 locationRequest.setQuality(LocationRequest.POWER_LOW);
Yu-Han Yange7baef32018-02-09 13:58:17 -0800738 } else {
739 // For Device-Based Hybrid (E911)
Yu-Han Yang07561382018-02-21 13:08:37 -0800740 provider = LocationManager.FUSED_PROVIDER;
741 locationListener = mFusedLocationListener;
Anil Admalb1c6c0d2019-06-20 12:00:16 -0700742 locationRequest.setQuality(LocationRequest.ACCURACY_FINE);
743 }
744
745 locationRequest.setProvider(provider);
746
747 // Ignore location settings if in emergency mode.
748 if (isUserEmergency && mNIHandler.getInEmergency()) {
749 locationRequest.setLocationSettingsIgnored(true);
750 durationMillis *= EMERGENCY_LOCATION_UPDATE_DURATION_MULTIPLIER;
Yu-Han Yange7baef32018-02-09 13:58:17 -0800751 }
Yu-Han Yang07561382018-02-21 13:08:37 -0800752
753 Log.i(TAG,
Yu-Han Yang74041ff2018-04-06 15:57:31 -0700754 String.format(
755 "GNSS HAL Requesting location updates from %s provider for %d millis.",
756 provider, durationMillis));
Yu-Han Yang53f4d6d2019-02-13 21:47:41 -0800757
Yu-Han Yange684dda2018-05-24 10:29:39 -0700758 try {
Yu-Han Yang53f4d6d2019-02-13 21:47:41 -0800759 locationManager.requestLocationUpdates(locationRequest,
Yu-Han Yange684dda2018-05-24 10:29:39 -0700760 locationListener, mHandler.getLooper());
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700761 locationListener.mNumLocationUpdateRequest++;
Yu-Han Yange684dda2018-05-24 10:29:39 -0700762 mHandler.postDelayed(() -> {
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700763 if (--locationListener.mNumLocationUpdateRequest == 0) {
Yu-Han Yange684dda2018-05-24 10:29:39 -0700764 Log.i(TAG,
765 String.format("Removing location updates from %s provider.", provider));
766 locationManager.removeUpdates(locationListener);
767 }
768 }, durationMillis);
769 } catch (IllegalArgumentException e) {
770 Log.w(TAG, "Unable to request location.", e);
771 }
Yu-Han Yange7baef32018-02-09 13:58:17 -0800772 }
773
774 private void injectBestLocation(Location location) {
Anil Admalb1c6c0d2019-06-20 12:00:16 -0700775 if (DEBUG) {
776 Log.d(TAG, "injectBestLocation: " + location);
777 }
Yu-Han Yange7baef32018-02-09 13:58:17 -0800778 int gnssLocationFlags = LOCATION_HAS_LAT_LONG |
779 (location.hasAltitude() ? LOCATION_HAS_ALTITUDE : 0) |
780 (location.hasSpeed() ? LOCATION_HAS_SPEED : 0) |
781 (location.hasBearing() ? LOCATION_HAS_BEARING : 0) |
782 (location.hasAccuracy() ? LOCATION_HAS_HORIZONTAL_ACCURACY : 0) |
783 (location.hasVerticalAccuracy() ? LOCATION_HAS_VERTICAL_ACCURACY : 0) |
784 (location.hasSpeedAccuracy() ? LOCATION_HAS_SPEED_ACCURACY : 0) |
785 (location.hasBearingAccuracy() ? LOCATION_HAS_BEARING_ACCURACY : 0);
786
787 double latitudeDegrees = location.getLatitude();
788 double longitudeDegrees = location.getLongitude();
789 double altitudeMeters = location.getAltitude();
790 float speedMetersPerSec = location.getSpeed();
791 float bearingDegrees = location.getBearing();
792 float horizontalAccuracyMeters = location.getAccuracy();
793 float verticalAccuracyMeters = location.getVerticalAccuracyMeters();
794 float speedAccuracyMetersPerSecond = location.getSpeedAccuracyMetersPerSecond();
795 float bearingAccuracyDegrees = location.getBearingAccuracyDegrees();
796 long timestamp = location.getTime();
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -0800797
Pierre Fite-Georgel9e96c572019-02-25 16:12:53 -0800798 int elapsedRealtimeFlags = ELAPSED_REALTIME_HAS_TIMESTAMP_NS
799 | (location.hasElapsedRealtimeUncertaintyNanos()
800 ? ELAPSED_REALTIME_HAS_TIME_UNCERTAINTY_NS : 0);
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -0800801 long elapsedRealtimeNanos = location.getElapsedRealtimeNanos();
Yu-Han Yang3cd9a862019-03-25 17:00:03 -0700802 double elapsedRealtimeUncertaintyNanos = location.getElapsedRealtimeUncertaintyNanos();
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -0800803
804 native_inject_best_location(
805 gnssLocationFlags, latitudeDegrees, longitudeDegrees,
806 altitudeMeters, speedMetersPerSec, bearingDegrees,
807 horizontalAccuracyMeters, verticalAccuracyMeters,
808 speedAccuracyMetersPerSecond, bearingAccuracyDegrees, timestamp,
Pierre Fite-Georgel9e96c572019-02-25 16:12:53 -0800809 elapsedRealtimeFlags, elapsedRealtimeNanos, elapsedRealtimeUncertaintyNanos);
Yu-Han Yange7baef32018-02-09 13:58:17 -0800810 }
811
Yu-Han Yange7baef32018-02-09 13:58:17 -0800812 /** Returns true if the location request is too frequent. */
813 private boolean isRequestLocationRateLimited() {
Anil Admal316f9482019-02-12 18:57:18 -0800814 // TODO: implement exponential backoff.
Yu-Han Yange7baef32018-02-09 13:58:17 -0800815 return false;
816 }
817
Kevin Tang8c6ac672019-03-22 12:31:01 -0700818 private void handleDownloadPsdsData() {
819 if (!mSupportsPsds) {
820 // native code reports psds not supported, don't try
821 Log.d(TAG, "handleDownloadPsdsData() called when PSDS not supported");
Wyatt Riley0d6e54e22016-10-05 12:03:03 -0700822 return;
823 }
Kevin Tang8c6ac672019-03-22 12:31:01 -0700824 if (mDownloadPsdsDataPending == STATE_DOWNLOADING) {
Kevin Tang40e1baf2012-01-10 14:32:44 -0800825 // already downloading data
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400826 return;
827 }
Anil Admal50ba15e2018-11-01 16:42:42 -0700828 if (!mNetworkConnectivityHandler.isDataNetworkConnected()) {
Kevin Tang40e1baf2012-01-10 14:32:44 -0800829 // try again when network is up
Kevin Tang8c6ac672019-03-22 12:31:01 -0700830 mDownloadPsdsDataPending = STATE_PENDING_NETWORK;
Kevin Tang40e1baf2012-01-10 14:32:44 -0800831 return;
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400832 }
Kevin Tang8c6ac672019-03-22 12:31:01 -0700833 mDownloadPsdsDataPending = STATE_DOWNLOADING;
Kevin Tang40e1baf2012-01-10 14:32:44 -0800834
Yu-Han Yang76f99952019-05-04 17:45:44 -0700835 synchronized (mLock) {
836 // hold wake lock while task runs
837 mDownloadPsdsWakeLock.acquire(DOWNLOAD_PSDS_DATA_TIMEOUT_MS);
838 }
Kevin Tang8c6ac672019-03-22 12:31:01 -0700839 Log.i(TAG, "WakeLock acquired by handleDownloadPsdsData()");
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700840 AsyncTask.THREAD_POOL_EXECUTOR.execute(() -> {
Kevin Tang8c6ac672019-03-22 12:31:01 -0700841 GpsPsdsDownloader psdsDownloader = new GpsPsdsDownloader(
Anil Admald71cf142018-12-21 14:59:36 -0800842 mGnssConfiguration.getProperties());
Kevin Tang8c6ac672019-03-22 12:31:01 -0700843 byte[] data = psdsDownloader.downloadPsdsData();
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700844 if (data != null) {
Kevin Tang8c6ac672019-03-22 12:31:01 -0700845 if (DEBUG) Log.d(TAG, "calling native_inject_psds_data");
846 native_inject_psds_data(data, data.length);
847 mPsdsBackOff.reset();
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700848 }
Kevin Tang40e1baf2012-01-10 14:32:44 -0800849
Kevin Tang8c6ac672019-03-22 12:31:01 -0700850 sendMessage(DOWNLOAD_PSDS_DATA_FINISHED, 0, null);
Kevin Tang40e1baf2012-01-10 14:32:44 -0800851
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700852 if (data == null) {
853 // try again later
854 // since this is delayed and not urgent we do not hold a wake lock here
Kevin Tang8c6ac672019-03-22 12:31:01 -0700855 mHandler.sendEmptyMessageDelayed(DOWNLOAD_PSDS_DATA,
856 mPsdsBackOff.nextBackoffMillis());
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700857 }
Kevin Tang40e1baf2012-01-10 14:32:44 -0800858
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700859 // Release wake lock held by task, synchronize on mLock in case multiple
860 // download tasks overrun.
861 synchronized (mLock) {
Kevin Tang8c6ac672019-03-22 12:31:01 -0700862 if (mDownloadPsdsWakeLock.isHeld()) {
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700863 // This wakelock may have time-out, if a timeout was specified.
864 // Catch (and ignore) any timeout exceptions.
865 try {
Kevin Tang8c6ac672019-03-22 12:31:01 -0700866 mDownloadPsdsWakeLock.release();
867 if (DEBUG) Log.d(TAG, "WakeLock released by handleDownloadPsdsData()");
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700868 } catch (Exception e) {
869 Log.i(TAG, "Wakelock timeout & release race exception in "
Kevin Tang8c6ac672019-03-22 12:31:01 -0700870 + "handleDownloadPsdsData()", e);
Wei Wangb71c0492017-05-01 20:24:19 -0700871 }
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700872 } else {
873 Log.e(TAG, "WakeLock expired before release in "
Kevin Tang8c6ac672019-03-22 12:31:01 -0700874 + "handleDownloadPsdsData()");
Wei Wangc5706f62017-04-18 11:26:26 -0700875 }
Jeff Brown028872f2012-08-25 13:07:01 -0700876 }
Kevin Tang40e1baf2012-01-10 14:32:44 -0800877 });
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800878 }
879
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400880 private void handleUpdateLocation(Location location) {
Mike Lockwoodd26ce0d2009-06-11 12:25:46 -0400881 if (location.hasAccuracy()) {
Anil Admalb1c6c0d2019-06-20 12:00:16 -0700882 if (DEBUG) {
883 Log.d(TAG, "injectLocation: " + location);
884 }
Mike Lockwoodd26ce0d2009-06-11 12:25:46 -0400885 native_inject_location(location.getLatitude(), location.getLongitude(),
886 location.getAccuracy());
887 }
Mike Lockwoodfd6e5f02009-05-21 11:28:20 -0400888 }
889
Anil Admald71cf142018-12-21 14:59:36 -0800890 private void setSuplHostPort() {
891 mSuplServerHost = mGnssConfiguration.getSuplHost();
892 mSuplServerPort = mGnssConfiguration.getSuplPort(TCP_MIN_PORT);
Tsuwei Chen678c13c2014-09-22 17:48:41 -0700893 if (mSuplServerHost != null
894 && mSuplServerPort > TCP_MIN_PORT
895 && mSuplServerPort <= TCP_MAX_PORT) {
Anil Admalc70344b2018-11-16 14:22:38 -0800896 native_set_agps_server(GnssNetworkConnectivityHandler.AGPS_TYPE_SUPL,
897 mSuplServerHost, mSuplServerPort);
Tsuwei Chen678c13c2014-09-22 17:48:41 -0700898 }
Tsuwei Chen52617bb2014-08-25 11:49:11 -0700899 }
900
Tsuwei Chen462bcd82014-09-17 12:28:49 -0700901 /**
902 * Checks what SUPL mode to use, according to the AGPS mode as well as the
903 * allowed mode from properties.
904 *
Tsuwei Chen462bcd82014-09-17 12:28:49 -0700905 * @param agpsEnabled whether AGPS is enabled by settings value
Tsuwei Chen462bcd82014-09-17 12:28:49 -0700906 * @return SUPL mode (MSA vs MSB vs STANDALONE)
907 */
Yu-Han Yang6a5f0b72019-01-24 18:34:28 -0800908 private int getSuplMode(boolean agpsEnabled) {
Tsuwei Chen462bcd82014-09-17 12:28:49 -0700909 if (agpsEnabled) {
Anil Admald71cf142018-12-21 14:59:36 -0800910 int suplMode = mGnssConfiguration.getSuplMode(0);
911 if (suplMode == 0) {
912 return GPS_POSITION_MODE_STANDALONE;
Tsuwei Chen462bcd82014-09-17 12:28:49 -0700913 }
Anil Admald71cf142018-12-21 14:59:36 -0800914
destradaabfb3bdb2015-04-29 14:42:35 -0700915 // MS-Based is the preferred mode for Assisted-GPS position computation, so we favor
916 // such mode when it is available
917 if (hasCapability(GPS_CAPABILITY_MSB) && (suplMode & AGPS_SUPL_MODE_MSB) != 0) {
918 return GPS_POSITION_MODE_MS_BASED;
919 }
Tsuwei Chen462bcd82014-09-17 12:28:49 -0700920 }
921 return GPS_POSITION_MODE_STANDALONE;
922 }
923
Yu-Han Yang76f99952019-05-04 17:45:44 -0700924 private void setGpsEnabled(boolean enabled) {
925 synchronized (mLock) {
926 mGpsEnabled = enabled;
927 }
928 }
929
930 private void handleEnable() {
931 if (DEBUG) Log.d(TAG, "handleEnable");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800932
Soonil Nagarkar35c3b912019-01-31 10:31:24 -0800933 boolean inited = native_init();
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700934
Soonil Nagarkar35c3b912019-01-31 10:31:24 -0800935 if (inited) {
Yu-Han Yang76f99952019-05-04 17:45:44 -0700936 setGpsEnabled(true);
Kevin Tang8c6ac672019-03-22 12:31:01 -0700937 mSupportsPsds = native_supports_psds();
Tsuwei Chen678c13c2014-09-22 17:48:41 -0700938
939 // TODO: remove the following native calls if we can make sure they are redundant.
Mike Lockwood734d6032009-07-28 18:30:25 -0700940 if (mSuplServerHost != null) {
Anil Admalc70344b2018-11-16 14:22:38 -0800941 native_set_agps_server(GnssNetworkConnectivityHandler.AGPS_TYPE_SUPL,
942 mSuplServerHost, mSuplServerPort);
Mike Lockwood734d6032009-07-28 18:30:25 -0700943 }
944 if (mC2KServerHost != null) {
Anil Admalc70344b2018-11-16 14:22:38 -0800945 native_set_agps_server(GnssNetworkConnectivityHandler.AGPS_TYPE_C2K,
946 mC2KServerHost, mC2KServerPort);
Mike Lockwood734d6032009-07-28 18:30:25 -0700947 }
destradaa13a60b02015-01-15 18:36:01 -0800948
Lifu Tang818aa2c2016-02-01 01:52:00 -0800949 mGnssMeasurementsProvider.onGpsEnabledChanged();
950 mGnssNavigationMessageProvider.onGpsEnabledChanged();
Yu-Han Yang3557cc72018-03-21 12:48:36 -0700951 mGnssBatchingProvider.enable();
Anil Admal138cdc32019-04-16 10:07:43 -0700952 if (mGnssVisibilityControl != null) {
Anil Admal8b83dc12019-06-12 13:55:42 -0700953 mGnssVisibilityControl.onGpsEnabledChanged(/* isEnabled= */ true);
Anil Admal138cdc32019-04-16 10:07:43 -0700954 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800955 } else {
Yu-Han Yang76f99952019-05-04 17:45:44 -0700956 setGpsEnabled(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800957 Log.w(TAG, "Failed to enable location provider");
958 }
959 }
960
Yu-Han Yang76f99952019-05-04 17:45:44 -0700961 private void handleDisable() {
962 if (DEBUG) Log.d(TAG, "handleDisable");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800963
Yu-Han Yang76f99952019-05-04 17:45:44 -0700964 setGpsEnabled(false);
David Christie3bc26142013-12-19 14:53:44 -0800965 updateClientUids(new WorkSource());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800966 stopNavigating();
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700967 mAlarmManager.cancel(mWakeupIntent);
968 mAlarmManager.cancel(mTimeoutIntent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800969
Anil Admal138cdc32019-04-16 10:07:43 -0700970 if (mGnssVisibilityControl != null) {
Yu-Han Yang76f99952019-05-04 17:45:44 -0700971 mGnssVisibilityControl.onGpsEnabledChanged(/* isEnabled= */ false);
Anil Admal138cdc32019-04-16 10:07:43 -0700972 }
Yu-Han Yang3557cc72018-03-21 12:48:36 -0700973 mGnssBatchingProvider.disable();
Mike Lockwoodcf1d8cb2010-01-20 10:14:54 -0500974 // do this before releasing wakelock
975 native_cleanup();
destradaa13a60b02015-01-15 18:36:01 -0800976
Lifu Tang818aa2c2016-02-01 01:52:00 -0800977 mGnssMeasurementsProvider.onGpsEnabledChanged();
978 mGnssNavigationMessageProvider.onGpsEnabledChanged();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800979 }
980
Soonil Nagarkar35c3b912019-01-31 10:31:24 -0800981 private void updateEnabled() {
Tyler Trephan037ef9d2019-05-17 13:41:18 -0700982 // Generally follow location setting for current user
983 boolean enabled = mContext.getSystemService(LocationManager.class)
984 .isLocationEnabledForUser(UserHandle.CURRENT);
WyattRileyb2446072019-03-01 07:41:49 -0800985
Yu-Han Yang76f99952019-05-04 17:45:44 -0700986 // ... but disable if PowerManager overrides
987 enabled &= !mDisableGpsForPowerManager;
WyattRileyb2446072019-03-01 07:41:49 -0800988
Yu-Han Yang76f99952019-05-04 17:45:44 -0700989 // .. but enable anyway, if there's an active settings-ignored request (e.g. ELS)
990 enabled |= (mProviderRequest != null && mProviderRequest.reportLocation
991 && mProviderRequest.locationSettingsIgnored);
WyattRileyb2446072019-03-01 07:41:49 -0800992
Yu-Han Yang76f99952019-05-04 17:45:44 -0700993 // ... and, finally, disable anyway, if device is being shut down
994 enabled &= !mShutdown;
WyattRileyb2446072019-03-01 07:41:49 -0800995
Yu-Han Yang76f99952019-05-04 17:45:44 -0700996 if (enabled == isGpsEnabled()) {
997 return;
998 }
Soonil Nagarkar35c3b912019-01-31 10:31:24 -0800999
Yu-Han Yang76f99952019-05-04 17:45:44 -07001000 if (enabled) {
1001 handleEnable();
1002 } else {
1003 handleDisable();
Soonil Nagarkar35c3b912019-01-31 10:31:24 -08001004 }
1005 }
1006
Yu-Han Yang76f99952019-05-04 17:45:44 -07001007 private boolean isGpsEnabled() {
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001008 synchronized (mLock) {
Yu-Han Yang76f99952019-05-04 17:45:44 -07001009 return mGpsEnabled;
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001010 }
Mike Lockwoodd03ff942010-02-09 08:46:14 -05001011 }
1012
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001013 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001014 public int getStatus(Bundle extras) {
Wyatt Rileyc7067412018-02-07 15:50:35 -08001015 mLocationExtras.setBundle(extras);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001016 return mStatus;
1017 }
1018
Wyatt Rileyc7067412018-02-07 15:50:35 -08001019 private void updateStatus(int status) {
1020 if (status != mStatus) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001021 mStatus = status;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001022 mStatusUpdateTime = SystemClock.elapsedRealtime();
1023 }
1024 }
1025
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001026 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001027 public long getStatusUpdateTime() {
1028 return mStatusUpdateTime;
1029 }
1030
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001031 @Override
1032 public void setRequest(ProviderRequest request, WorkSource source) {
1033 sendMessage(SET_REQUEST, 0, new GpsRequest(request, source));
Mike Lockwood62a8fc12010-03-22 14:23:26 -04001034 }
1035
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001036 private void handleSetRequest(ProviderRequest request, WorkSource source) {
David Christied4edf4c2014-08-12 15:22:27 -07001037 mProviderRequest = request;
1038 mWorkSource = source;
Soonil Nagarkar35c3b912019-01-31 10:31:24 -08001039 updateEnabled();
David Christied4edf4c2014-08-12 15:22:27 -07001040 updateRequirements();
1041 }
1042
1043 // Called when the requirements for GPS may have changed
1044 private void updateRequirements() {
1045 if (mProviderRequest == null || mWorkSource == null) {
1046 return;
1047 }
1048
David Christied4edf4c2014-08-12 15:22:27 -07001049 if (DEBUG) Log.d(TAG, "setRequest " + mProviderRequest);
Yu-Han Yang76f99952019-05-04 17:45:44 -07001050 if (mProviderRequest.reportLocation && isGpsEnabled()) {
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001051 // update client uids
David Christied4edf4c2014-08-12 15:22:27 -07001052 updateClientUids(mWorkSource);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001053
David Christied4edf4c2014-08-12 15:22:27 -07001054 mFixInterval = (int) mProviderRequest.interval;
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001055 mLowPowerMode = mProviderRequest.lowPowerMode;
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001056 // check for overflow
David Christied4edf4c2014-08-12 15:22:27 -07001057 if (mFixInterval != mProviderRequest.interval) {
1058 Log.w(TAG, "interval overflow: " + mProviderRequest.interval);
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001059 mFixInterval = Integer.MAX_VALUE;
1060 }
Mike Lockwood03ca2162010-04-01 08:10:09 -07001061
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001062 // apply request to GPS engine
Mike Lockwood04598b62010-04-14 17:17:24 -04001063 if (mStarted && hasCapability(GPS_CAPABILITY_SCHEDULING)) {
gomo48f1a642017-11-10 20:35:46 -08001064 // change period and/or lowPowerMode
Yu-Han Yangc8b9ff72018-04-17 00:47:24 -07001065 if (!setPositionMode(mPositionMode, GPS_POSITION_RECURRENCE_PERIODIC,
gomo48f1a642017-11-10 20:35:46 -08001066 mFixInterval, 0, 0, mLowPowerMode)) {
1067 Log.e(TAG, "set_position_mode failed in updateRequirements");
Mike Lockwood04598b62010-04-14 17:17:24 -04001068 }
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001069 } else if (!mStarted) {
1070 // start GPS
Yu-Han Yang6a5f0b72019-01-24 18:34:28 -08001071 startNavigating();
gomo300b2402017-12-13 19:04:12 -08001072 } else {
1073 // GNSS Engine is already ON, but no GPS_CAPABILITY_SCHEDULING
1074 mAlarmManager.cancel(mTimeoutIntent);
1075 if (mFixInterval >= NO_FIX_TIMEOUT) {
1076 // set timer to give up if we do not receive a fix within NO_FIX_TIMEOUT
1077 // and our fix interval is not short
1078 mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001079 SystemClock.elapsedRealtime() + NO_FIX_TIMEOUT, mTimeoutIntent);
1080 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001081 }
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001082 } else {
Dianne Hackborn002a54e2013-01-10 17:34:55 -08001083 updateClientUids(new WorkSource());
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001084
1085 stopNavigating();
1086 mAlarmManager.cancel(mWakeupIntent);
1087 mAlarmManager.cancel(mTimeoutIntent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001088 }
1089 }
1090
Yu-Han Yangc8b9ff72018-04-17 00:47:24 -07001091 private boolean setPositionMode(int mode, int recurrence, int minInterval,
1092 int preferredAccuracy, int preferredTime, boolean lowPowerMode) {
1093 GnssPositionMode positionMode = new GnssPositionMode(mode, recurrence, minInterval,
1094 preferredAccuracy, preferredTime, lowPowerMode);
1095 if (mLastPositionMode != null && mLastPositionMode.equals(positionMode)) {
1096 return true;
1097 }
1098
1099 boolean result = native_set_position_mode(mode, recurrence, minInterval,
1100 preferredAccuracy, preferredTime, lowPowerMode);
1101 if (result) {
1102 mLastPositionMode = positionMode;
1103 } else {
1104 mLastPositionMode = null;
1105 }
1106 return result;
1107 }
1108
Dianne Hackborn002a54e2013-01-10 17:34:55 -08001109 private void updateClientUids(WorkSource source) {
Narayan Kamath32684dd2018-01-08 17:32:51 +00001110 if (source.equals(mClientSource)) {
Victoria Leaseea78b852013-01-15 10:39:28 -08001111 return;
1112 }
Dianne Hackborn002a54e2013-01-10 17:34:55 -08001113
Narayan Kamath32684dd2018-01-08 17:32:51 +00001114 // (1) Inform BatteryStats that the list of IDs we're tracking changed.
1115 try {
1116 mBatteryStats.noteGpsChanged(mClientSource, source);
1117 } catch (RemoteException e) {
1118 Log.w(TAG, "RemoteException", e);
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001119 }
1120
Narayan Kamath32684dd2018-01-08 17:32:51 +00001121 // (2) Inform AppOps service about the list of changes to UIDs.
1122
1123 List<WorkChain>[] diffs = WorkSource.diffChains(mClientSource, source);
1124 if (diffs != null) {
1125 List<WorkChain> newChains = diffs[0];
1126 List<WorkChain> goneChains = diffs[1];
1127
1128 if (newChains != null) {
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001129 for (WorkChain newChain : newChains) {
Svet Ganovf7b47252018-02-26 11:11:27 -08001130 mAppOps.startOpNoThrow(AppOpsManager.OP_GPS, newChain.getAttributionUid(),
1131 newChain.getAttributionTag());
Narayan Kamath32684dd2018-01-08 17:32:51 +00001132 }
1133 }
1134
1135 if (goneChains != null) {
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001136 for (WorkChain goneChain : goneChains) {
Svet Ganovf7b47252018-02-26 11:11:27 -08001137 mAppOps.finishOp(AppOpsManager.OP_GPS, goneChain.getAttributionUid(),
1138 goneChain.getAttributionTag());
Narayan Kamath32684dd2018-01-08 17:32:51 +00001139 }
1140 }
1141
1142 mClientSource.transferWorkChains(source);
1143 }
1144
1145 // Update the flat UIDs and names list and inform app-ops of all changes.
1146 WorkSource[] changes = mClientSource.setReturningDiffs(source);
1147 if (changes != null) {
1148 WorkSource newWork = changes[0];
1149 WorkSource goneWork = changes[1];
1150
1151 // Update sources that were not previously tracked.
1152 if (newWork != null) {
1153 for (int i = 0; i < newWork.size(); i++) {
Svet Ganovf7b47252018-02-26 11:11:27 -08001154 mAppOps.startOpNoThrow(AppOpsManager.OP_GPS,
1155 newWork.get(i), newWork.getName(i));
Narayan Kamath32684dd2018-01-08 17:32:51 +00001156 }
1157 }
1158
1159 // Update sources that are no longer tracked.
1160 if (goneWork != null) {
1161 for (int i = 0; i < goneWork.size(); i++) {
Svet Ganovf7b47252018-02-26 11:11:27 -08001162 mAppOps.finishOp(AppOpsManager.OP_GPS, goneWork.get(i), goneWork.getName(i));
Dianne Hackborn2e418422009-06-22 20:00:17 -07001163 }
Mike Lockwood2f82c4e2009-04-17 08:24:10 -04001164 }
1165 }
1166 }
1167
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001168 @Override
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001169 public void sendExtraCommand(String command, Bundle extras) {
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001170
Mike Lockwood63aa5a62010-04-14 19:21:31 -04001171 long identity = Binder.clearCallingIdentity();
Peter Visontayb25db362017-11-01 18:18:12 +00001172 try {
Peter Visontayb25db362017-11-01 18:18:12 +00001173 if ("delete_aiding_data".equals(command)) {
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001174 deleteAidingData(extras);
Peter Visontayb25db362017-11-01 18:18:12 +00001175 } else if ("force_time_injection".equals(command)) {
1176 requestUtcTime();
Kevin Tang8c6ac672019-03-22 12:31:01 -07001177 } else if ("force_psds_injection".equals(command)) {
1178 if (mSupportsPsds) {
1179 psdsDownloadRequest();
Peter Visontayb25db362017-11-01 18:18:12 +00001180 }
1181 } else {
1182 Log.w(TAG, "sendExtraCommand: unknown command " + command);
Mike Lockwood93bc44d2009-05-20 16:58:22 -04001183 }
Peter Visontayb25db362017-11-01 18:18:12 +00001184 } finally {
1185 Binder.restoreCallingIdentity(identity);
Mike Lockwood93bc44d2009-05-20 16:58:22 -04001186 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001187 }
1188
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001189 private void deleteAidingData(Bundle extras) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001190 int flags;
1191
1192 if (extras == null) {
1193 flags = GPS_DELETE_ALL;
1194 } else {
1195 flags = 0;
1196 if (extras.getBoolean("ephemeris")) flags |= GPS_DELETE_EPHEMERIS;
1197 if (extras.getBoolean("almanac")) flags |= GPS_DELETE_ALMANAC;
1198 if (extras.getBoolean("position")) flags |= GPS_DELETE_POSITION;
1199 if (extras.getBoolean("time")) flags |= GPS_DELETE_TIME;
1200 if (extras.getBoolean("iono")) flags |= GPS_DELETE_IONO;
1201 if (extras.getBoolean("utc")) flags |= GPS_DELETE_UTC;
1202 if (extras.getBoolean("health")) flags |= GPS_DELETE_HEALTH;
1203 if (extras.getBoolean("svdir")) flags |= GPS_DELETE_SVDIR;
1204 if (extras.getBoolean("svsteer")) flags |= GPS_DELETE_SVSTEER;
1205 if (extras.getBoolean("sadata")) flags |= GPS_DELETE_SADATA;
1206 if (extras.getBoolean("rti")) flags |= GPS_DELETE_RTI;
1207 if (extras.getBoolean("celldb-info")) flags |= GPS_DELETE_CELLDB_INFO;
1208 if (extras.getBoolean("all")) flags |= GPS_DELETE_ALL;
1209 }
1210
1211 if (flags != 0) {
1212 native_delete_aiding_data(flags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001213 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001214 }
1215
Yu-Han Yang6a5f0b72019-01-24 18:34:28 -08001216 private void startNavigating() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001217 if (!mStarted) {
Yu-Han Yang6a5f0b72019-01-24 18:34:28 -08001218 if (DEBUG) Log.d(TAG, "startNavigating");
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001219 mTimeToFirstFix = 0;
1220 mLastFixTime = 0;
WyattRileyba6072f2019-04-18 07:37:52 -07001221 setStarted(true);
Mike Lockwood03ca2162010-04-01 08:10:09 -07001222 mPositionMode = GPS_POSITION_MODE_STANDALONE;
Wyatt Riley5d5bac82016-11-01 07:05:16 -07001223 // Notify about suppressed output, if speed limit was previously exceeded.
1224 // Elsewhere, we check again with every speed output reported.
1225 if (mItarSpeedLimitExceeded) {
1226 Log.i(TAG, "startNavigating with ITAR limit in place. Output limited " +
1227 "until slow enough speed reported.");
1228 }
Mike Lockwood03ca2162010-04-01 08:10:09 -07001229
Tsuwei Chen462bcd82014-09-17 12:28:49 -07001230 boolean agpsEnabled =
1231 (Settings.Global.getInt(mContext.getContentResolver(),
gomo48f1a642017-11-10 20:35:46 -08001232 Settings.Global.ASSISTED_GPS_ENABLED, 1) != 0);
Yu-Han Yang6a5f0b72019-01-24 18:34:28 -08001233 mPositionMode = getSuplMode(agpsEnabled);
Mike Lockwoodbcab8df2009-06-25 16:39:09 -04001234
Stan Chesnutt1d72d8c2013-04-15 19:18:02 -07001235 if (DEBUG) {
1236 String mode;
1237
gomo48f1a642017-11-10 20:35:46 -08001238 switch (mPositionMode) {
Stan Chesnutt1d72d8c2013-04-15 19:18:02 -07001239 case GPS_POSITION_MODE_STANDALONE:
1240 mode = "standalone";
1241 break;
1242 case GPS_POSITION_MODE_MS_ASSISTED:
1243 mode = "MS_ASSISTED";
1244 break;
1245 case GPS_POSITION_MODE_MS_BASED:
1246 mode = "MS_BASED";
1247 break;
1248 default:
1249 mode = "unknown";
1250 break;
1251 }
1252 Log.d(TAG, "setting position_mode to " + mode);
1253 }
1254
Mike Lockwood04598b62010-04-14 17:17:24 -04001255 int interval = (hasCapability(GPS_CAPABILITY_SCHEDULING) ? mFixInterval : 1000);
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001256 mLowPowerMode = mProviderRequest.lowPowerMode;
Yu-Han Yangc8b9ff72018-04-17 00:47:24 -07001257 if (!setPositionMode(mPositionMode, GPS_POSITION_RECURRENCE_PERIODIC,
gomo48f1a642017-11-10 20:35:46 -08001258 interval, 0, 0, mLowPowerMode)) {
WyattRileyba6072f2019-04-18 07:37:52 -07001259 setStarted(false);
Mike Lockwood04598b62010-04-14 17:17:24 -04001260 Log.e(TAG, "set_position_mode failed in startNavigating()");
1261 return;
1262 }
1263 if (!native_start()) {
WyattRileyba6072f2019-04-18 07:37:52 -07001264 setStarted(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001265 Log.e(TAG, "native_start failed in startNavigating()");
Mike Lockwood0632ca72009-05-14 15:51:03 -04001266 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001267 }
1268
1269 // reset SV count to zero
Wyatt Rileyc7067412018-02-07 15:50:35 -08001270 updateStatus(LocationProvider.TEMPORARILY_UNAVAILABLE);
1271 mLocationExtras.reset();
Yipeng Cao282b5942017-05-17 20:31:39 -07001272 mFixRequestTime = SystemClock.elapsedRealtime();
Mike Lockwood04598b62010-04-14 17:17:24 -04001273 if (!hasCapability(GPS_CAPABILITY_SCHEDULING)) {
1274 // set timer to give up if we do not receive a fix within NO_FIX_TIMEOUT
1275 // and our fix interval is not short
1276 if (mFixInterval >= NO_FIX_TIMEOUT) {
1277 mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
1278 SystemClock.elapsedRealtime() + NO_FIX_TIMEOUT, mTimeoutIntent);
1279 }
Mike Lockwood0632ca72009-05-14 15:51:03 -04001280 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001281 }
1282 }
1283
Mike Lockwood62a8fc12010-03-22 14:23:26 -04001284 private void stopNavigating() {
Mike Lockwood29c84342009-05-06 14:01:15 -04001285 if (DEBUG) Log.d(TAG, "stopNavigating");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001286 if (mStarted) {
WyattRileyba6072f2019-04-18 07:37:52 -07001287 setStarted(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001288 native_stop();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001289 mLastFixTime = 0;
Yu-Han Yanga50cd602018-08-28 12:33:24 -07001290 // native_stop() may reset the position mode in hardware.
1291 mLastPositionMode = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001292
1293 // reset SV count to zero
Wyatt Rileyc7067412018-02-07 15:50:35 -08001294 updateStatus(LocationProvider.TEMPORARILY_UNAVAILABLE);
1295 mLocationExtras.reset();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001296 }
1297 }
1298
WyattRileyba6072f2019-04-18 07:37:52 -07001299 private void setStarted(boolean started) {
1300 if (mStarted != started) {
1301 mStarted = started;
1302 mStartedChangedElapsedRealtime = SystemClock.elapsedRealtime();
1303 }
1304 }
1305
Mike Lockwood0632ca72009-05-14 15:51:03 -04001306 private void hibernate() {
1307 // stop GPS until our next fix interval arrives
1308 stopNavigating();
Mike Lockwood0632ca72009-05-14 15:51:03 -04001309 mAlarmManager.cancel(mTimeoutIntent);
1310 mAlarmManager.cancel(mWakeupIntent);
1311 long now = SystemClock.elapsedRealtime();
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001312 mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, now + mFixInterval, mWakeupIntent);
Mike Lockwood04598b62010-04-14 17:17:24 -04001313 }
1314
1315 private boolean hasCapability(int capability) {
Anil Admal312fddb2019-03-25 12:15:43 -07001316 return (mTopHalCapabilities & capability) != 0;
Mike Lockwood0632ca72009-05-14 15:51:03 -04001317 }
1318
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001319 @NativeEntryPoint
Wyatt Riley5d229832017-02-10 17:06:00 -08001320 private void reportLocation(boolean hasLatLong, Location location) {
Wyatt Riley26465d22018-02-12 13:44:24 -08001321 sendMessage(REPORT_LOCATION, hasLatLong ? 1 : 0, location);
1322 }
1323
1324 private void handleReportLocation(boolean hasLatLong, Location location) {
Wyatt Riley5d229832017-02-10 17:06:00 -08001325 if (location.hasSpeed()) {
1326 mItarSpeedLimitExceeded = location.getSpeed() > ITAR_SPEED_LIMIT_METERS_PER_SECOND;
Wyatt Riley5d5bac82016-11-01 07:05:16 -07001327 }
1328
1329 if (mItarSpeedLimitExceeded) {
1330 Log.i(TAG, "Hal reported a speed in excess of ITAR limit." +
1331 " GPS/GNSS Navigation output blocked.");
Siddharth Ray53ddc802018-03-16 12:01:52 -07001332 if (mStarted) {
1333 mGnssMetrics.logReceivedLocationStatus(false);
1334 }
Wyatt Riley5d5bac82016-11-01 07:05:16 -07001335 return; // No output of location allowed
1336 }
1337
Wyatt Riley5d229832017-02-10 17:06:00 -08001338 if (VERBOSE) Log.v(TAG, "reportLocation " + location.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001339
Wyatt Riley26465d22018-02-12 13:44:24 -08001340 location.setExtras(mLocationExtras.getBundle());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001341
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001342 reportLocation(location);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001343
Siddharth Ray53ddc802018-03-16 12:01:52 -07001344 if (mStarted) {
1345 mGnssMetrics.logReceivedLocationStatus(hasLatLong);
1346 if (hasLatLong) {
1347 if (location.hasAccuracy()) {
1348 mGnssMetrics.logPositionAccuracyMeters(location.getAccuracy());
1349 }
1350 if (mTimeToFirstFix > 0) {
1351 int timeBetweenFixes = (int) (SystemClock.elapsedRealtime() - mLastFixTime);
1352 mGnssMetrics.logMissedReports(mFixInterval, timeBetweenFixes);
1353 }
Siddharth Raybb608c82017-03-16 11:33:34 -07001354 }
WyattRileyba6072f2019-04-18 07:37:52 -07001355 } else {
1356 // Warn or error about long delayed GNSS engine shutdown as this generally wastes
1357 // power and sends location when not expected.
1358 long locationAfterStartedFalseMillis =
1359 SystemClock.elapsedRealtime() - mStartedChangedElapsedRealtime;
1360 if (locationAfterStartedFalseMillis > LOCATION_OFF_DELAY_THRESHOLD_WARN_MILLIS) {
1361 String logMessage = "Unexpected GNSS Location report "
1362 + TimeUtils.formatDuration(locationAfterStartedFalseMillis)
1363 + " after location turned off";
1364 if (locationAfterStartedFalseMillis > LOCATION_OFF_DELAY_THRESHOLD_ERROR_MILLIS) {
1365 Log.e(TAG, logMessage);
1366 } else {
1367 Log.w(TAG, logMessage);
1368 }
1369 }
Siddharth Raybb608c82017-03-16 11:33:34 -07001370 }
1371
Yipeng Cao282b5942017-05-17 20:31:39 -07001372 mLastFixTime = SystemClock.elapsedRealtime();
Hakan Gustavssonfa94ff02010-02-23 09:12:38 +01001373 // report time to first fix
Wyatt Riley5d229832017-02-10 17:06:00 -08001374 if (mTimeToFirstFix == 0 && hasLatLong) {
gomo48f1a642017-11-10 20:35:46 -08001375 mTimeToFirstFix = (int) (mLastFixTime - mFixRequestTime);
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001376 if (DEBUG) Log.d(TAG, "TTFF: " + mTimeToFirstFix);
Siddharth Ray53ddc802018-03-16 12:01:52 -07001377 if (mStarted) {
1378 mGnssMetrics.logTimeToFirstFixMilliSecs(mTimeToFirstFix);
1379 }
Hakan Gustavssonfa94ff02010-02-23 09:12:38 +01001380
1381 // notify status listeners
Anil Admal75b9fd62018-11-28 11:22:50 -08001382 mGnssStatusListenerHelper.onFirstFix(mTimeToFirstFix);
Hakan Gustavssonfa94ff02010-02-23 09:12:38 +01001383 }
1384
Mike Lockwood15e3d0f2009-05-01 07:53:28 -04001385 if (mStarted && mStatus != LocationProvider.AVAILABLE) {
Wyatt Rileyc7067412018-02-07 15:50:35 -08001386 // For devices that use framework scheduling, a timer may be set to ensure we don't
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001387 // spend too much power searching for a location, when the requested update rate is
1388 // slow.
Wyatt Rileyc7067412018-02-07 15:50:35 -08001389 // As we just recievied a location, we'll cancel that timer.
Mike Lockwood04598b62010-04-14 17:17:24 -04001390 if (!hasCapability(GPS_CAPABILITY_SCHEDULING) && mFixInterval < NO_FIX_TIMEOUT) {
Mike Lockwoodb7be5442010-02-24 14:34:50 -05001391 mAlarmManager.cancel(mTimeoutIntent);
1392 }
1393
Wyatt Rileyc7067412018-02-07 15:50:35 -08001394 updateStatus(LocationProvider.AVAILABLE);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001395 }
Mike Lockwood29c84342009-05-06 14:01:15 -04001396
gomo48f1a642017-11-10 20:35:46 -08001397 if (!hasCapability(GPS_CAPABILITY_SCHEDULING) && mStarted &&
1398 mFixInterval > GPS_POLLING_THRESHOLD_INTERVAL) {
Mike Lockwoodd53ba012010-04-15 20:41:26 -04001399 if (DEBUG) Log.d(TAG, "got fix, hibernating");
Mike Lockwood0632ca72009-05-14 15:51:03 -04001400 hibernate();
Mike Lockwood29c84342009-05-06 14:01:15 -04001401 }
gomo48f1a642017-11-10 20:35:46 -08001402 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001403
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001404 @NativeEntryPoint
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001405 private void reportStatus(int status) {
Mike Lockwoodb8d90332010-10-18 17:59:48 -04001406 if (DEBUG) Log.v(TAG, "reportStatus status: " + status);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001407
destradaaea8a8a62014-06-23 18:19:03 -07001408 boolean wasNavigating = mNavigating;
1409 switch (status) {
1410 case GPS_STATUS_SESSION_BEGIN:
1411 mNavigating = true;
destradaaea8a8a62014-06-23 18:19:03 -07001412 break;
1413 case GPS_STATUS_SESSION_END:
1414 mNavigating = false;
1415 break;
1416 case GPS_STATUS_ENGINE_ON:
destradaaea8a8a62014-06-23 18:19:03 -07001417 break;
1418 case GPS_STATUS_ENGINE_OFF:
destradaaea8a8a62014-06-23 18:19:03 -07001419 mNavigating = false;
1420 break;
1421 }
Mike Lockwooddbd6fd82009-12-07 18:43:36 -05001422
destradaaea8a8a62014-06-23 18:19:03 -07001423 if (wasNavigating != mNavigating) {
Anil Admal75b9fd62018-11-28 11:22:50 -08001424 mGnssStatusListenerHelper.onStatusChanged(mNavigating);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001425 }
1426 }
1427
Wyatt Riley26465d22018-02-12 13:44:24 -08001428 // Helper class to carry data to handler for reportSvStatus
1429 private static class SvStatusInfo {
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001430 private int mSvCount;
1431 private int[] mSvidWithFlags;
1432 private float[] mCn0s;
1433 private float[] mSvElevations;
1434 private float[] mSvAzimuths;
1435 private float[] mSvCarrierFreqs;
Wyatt Riley26465d22018-02-12 13:44:24 -08001436 }
1437
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001438 @NativeEntryPoint
Wyatt Riley26465d22018-02-12 13:44:24 -08001439 private void reportSvStatus(int svCount, int[] svidWithFlags, float[] cn0s,
1440 float[] svElevations, float[] svAzimuths, float[] svCarrierFreqs) {
1441 SvStatusInfo svStatusInfo = new SvStatusInfo();
1442 svStatusInfo.mSvCount = svCount;
1443 svStatusInfo.mSvidWithFlags = svidWithFlags;
1444 svStatusInfo.mCn0s = cn0s;
1445 svStatusInfo.mSvElevations = svElevations;
1446 svStatusInfo.mSvAzimuths = svAzimuths;
1447 svStatusInfo.mSvCarrierFreqs = svCarrierFreqs;
1448
1449 sendMessage(REPORT_SV_STATUS, 0, svStatusInfo);
1450 }
1451
1452 private void handleReportSvStatus(SvStatusInfo info) {
Anil Admal75b9fd62018-11-28 11:22:50 -08001453 mGnssStatusListenerHelper.onSvStatusChanged(
Wyatt Riley26465d22018-02-12 13:44:24 -08001454 info.mSvCount,
1455 info.mSvidWithFlags,
1456 info.mCn0s,
1457 info.mSvElevations,
1458 info.mSvAzimuths,
1459 info.mSvCarrierFreqs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001460
Siddharth Ray168f12a2017-07-10 11:55:10 -07001461 // Log CN0 as part of GNSS metrics
Wyatt Riley26465d22018-02-12 13:44:24 -08001462 mGnssMetrics.logCn0(info.mCn0s, info.mSvCount);
Siddharth Ray168f12a2017-07-10 11:55:10 -07001463
Mike Lockwood29c84342009-05-06 14:01:15 -04001464 if (VERBOSE) {
Wyatt Riley26465d22018-02-12 13:44:24 -08001465 Log.v(TAG, "SV count: " + info.mSvCount);
Lifu Tang30f95a72016-01-07 23:20:38 -08001466 }
Wyatt Rileyc9f25dd2017-05-05 13:45:23 -07001467 // Calculate number of satellites used in fix.
Lifu Tang30f95a72016-01-07 23:20:38 -08001468 int usedInFixCount = 0;
Wyatt Rileyc9f25dd2017-05-05 13:45:23 -07001469 int maxCn0 = 0;
1470 int meanCn0 = 0;
Wyatt Riley26465d22018-02-12 13:44:24 -08001471 for (int i = 0; i < info.mSvCount; i++) {
1472 if ((info.mSvidWithFlags[i] & GnssStatus.GNSS_SV_FLAGS_USED_IN_FIX) != 0) {
Lifu Tang30f95a72016-01-07 23:20:38 -08001473 ++usedInFixCount;
Wyatt Riley26465d22018-02-12 13:44:24 -08001474 if (info.mCn0s[i] > maxCn0) {
1475 maxCn0 = (int) info.mCn0s[i];
Wyatt Rileyc9f25dd2017-05-05 13:45:23 -07001476 }
Wyatt Riley26465d22018-02-12 13:44:24 -08001477 meanCn0 += info.mCn0s[i];
Lifu Tang30f95a72016-01-07 23:20:38 -08001478 }
1479 if (VERBOSE) {
Wyatt Riley26465d22018-02-12 13:44:24 -08001480 Log.v(TAG, "svid: " + (info.mSvidWithFlags[i] >> GnssStatus.SVID_SHIFT_WIDTH) +
1481 " cn0: " + info.mCn0s[i] +
1482 " elev: " + info.mSvElevations[i] +
1483 " azimuth: " + info.mSvAzimuths[i] +
1484 " carrier frequency: " + info.mSvCarrierFreqs[i] +
1485 ((info.mSvidWithFlags[i] & GnssStatus.GNSS_SV_FLAGS_HAS_EPHEMERIS_DATA) == 0
Lifu Tang30f95a72016-01-07 23:20:38 -08001486 ? " " : " E") +
Wyatt Riley26465d22018-02-12 13:44:24 -08001487 ((info.mSvidWithFlags[i] & GnssStatus.GNSS_SV_FLAGS_HAS_ALMANAC_DATA) == 0
Lifu Tang30f95a72016-01-07 23:20:38 -08001488 ? " " : " A") +
Wyatt Riley26465d22018-02-12 13:44:24 -08001489 ((info.mSvidWithFlags[i] & GnssStatus.GNSS_SV_FLAGS_USED_IN_FIX) == 0
gomo4402af62017-01-11 13:20:13 -08001490 ? "" : "U") +
Wyatt Riley26465d22018-02-12 13:44:24 -08001491 ((info.mSvidWithFlags[i] &
1492 GnssStatus.GNSS_SV_FLAGS_HAS_CARRIER_FREQUENCY) == 0
gomo48f1a642017-11-10 20:35:46 -08001493 ? "" : "F"));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001494 }
Yu-Han Yang284234e2019-03-28 19:35:57 -07001495
1496 if ((info.mSvidWithFlags[i] & GnssStatus.GNSS_SV_FLAGS_USED_IN_FIX) != 0) {
1497 int constellationType =
1498 (info.mSvidWithFlags[i] >> GnssStatus.CONSTELLATION_TYPE_SHIFT_WIDTH)
1499 & GnssStatus.CONSTELLATION_TYPE_MASK;
1500 mGnssMetrics.logConstellationType(constellationType);
1501 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001502 }
Wyatt Rileyc9f25dd2017-05-05 13:45:23 -07001503 if (usedInFixCount > 0) {
1504 meanCn0 /= usedInFixCount;
1505 }
1506 // return number of sats used in fix instead of total reported
Wyatt Rileyc7067412018-02-07 15:50:35 -08001507 mLocationExtras.set(usedInFixCount, meanCn0, maxCn0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001508
Mike Lockwood15e3d0f2009-05-01 07:53:28 -04001509 if (mNavigating && mStatus == LocationProvider.AVAILABLE && mLastFixTime > 0 &&
gomo48f1a642017-11-10 20:35:46 -08001510 SystemClock.elapsedRealtime() - mLastFixTime > RECENT_FIX_TIMEOUT) {
Wyatt Rileyc7067412018-02-07 15:50:35 -08001511 updateStatus(LocationProvider.TEMPORARILY_UNAVAILABLE);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001512 }
1513 }
Mike Lockwood58bda982009-04-14 16:25:07 -04001514
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001515 @NativeEntryPoint
Anil Admalc70344b2018-11-16 14:22:38 -08001516 private void reportAGpsStatus(int agpsType, int agpsStatus, byte[] suplIpAddr) {
1517 mNetworkConnectivityHandler.onReportAGpsStatus(agpsType, agpsStatus, suplIpAddr);
destradaae21252a2015-09-08 12:32:59 -07001518 }
1519
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001520 @NativeEntryPoint
Mike Lockwoodf602d362010-06-20 14:28:16 -07001521 private void reportNmea(long timestamp) {
Wyatt Riley5d5bac82016-11-01 07:05:16 -07001522 if (!mItarSpeedLimitExceeded) {
1523 int length = native_read_nmea(mNmeaBuffer, mNmeaBuffer.length);
1524 String nmea = new String(mNmeaBuffer, 0 /* offset */, length);
Anil Admal75b9fd62018-11-28 11:22:50 -08001525 mGnssStatusListenerHelper.onNmeaReceived(timestamp, nmea);
Wyatt Riley5d5bac82016-11-01 07:05:16 -07001526 }
destradaaea8a8a62014-06-23 18:19:03 -07001527 }
Mike Lockwoodb16e7802009-08-06 09:26:02 -04001528
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001529 @NativeEntryPoint
Lifu Tang818aa2c2016-02-01 01:52:00 -08001530 private void reportMeasurementData(GnssMeasurementsEvent event) {
Wyatt Riley5d5bac82016-11-01 07:05:16 -07001531 if (!mItarSpeedLimitExceeded) {
Wyatt Rileyaa420d52017-07-03 15:14:42 -07001532 // send to handler to allow native to return quickly
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001533 mHandler.post(() -> mGnssMeasurementsProvider.onMeasurementsAvailable(event));
Wyatt Riley5d5bac82016-11-01 07:05:16 -07001534 }
Mike Lockwoodb16e7802009-08-06 09:26:02 -04001535 }
1536
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001537 @NativeEntryPoint
Lifu Tange8abe8e2016-04-01 10:32:05 -07001538 private void reportNavigationMessage(GnssNavigationMessage event) {
Wyatt Riley5d5bac82016-11-01 07:05:16 -07001539 if (!mItarSpeedLimitExceeded) {
Wyatt Rileyaa420d52017-07-03 15:14:42 -07001540 // send to handler to allow native to return quickly
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001541 mHandler.post(() -> mGnssNavigationMessageProvider.onNavigationMessageAvailable(event));
Wyatt Riley5d5bac82016-11-01 07:05:16 -07001542 }
destradaa4b3e3932014-07-21 18:01:47 -07001543 }
1544
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001545 @NativeEntryPoint
Anil Admal62c42dc2019-04-03 15:39:22 -07001546 private void setTopHalCapabilities(int topHalCapabilities) {
Anil Admalefd9dc62019-03-12 17:39:20 -07001547 mHandler.post(() -> {
Anil Admal312fddb2019-03-25 12:15:43 -07001548 mTopHalCapabilities = topHalCapabilities;
Mike Lockwood9b9fb5c2011-06-29 15:09:40 -04001549
Anil Admalefd9dc62019-03-12 17:39:20 -07001550 if (hasCapability(GPS_CAPABILITY_ON_DEMAND_TIME)) {
1551 mNtpTimeHelper.enablePeriodicTimeInjection();
1552 requestUtcTime();
1553 }
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001554
Anil Admal62c42dc2019-04-03 15:39:22 -07001555 mGnssMeasurementsProvider.onCapabilitiesUpdated(
1556 hasCapability(GPS_CAPABILITY_MEASUREMENTS));
1557 mGnssNavigationMessageProvider.onCapabilitiesUpdated(
1558 hasCapability(GPS_CAPABILITY_NAV_MESSAGES));
Anil Admalefd9dc62019-03-12 17:39:20 -07001559 restartRequests();
Anil Admal312fddb2019-03-25 12:15:43 -07001560
Anil Admal62c42dc2019-04-03 15:39:22 -07001561 mGnssCapabilitiesProvider.setTopHalCapabilities(mTopHalCapabilities);
Anil Admalefd9dc62019-03-12 17:39:20 -07001562 });
1563 }
1564
1565 @NativeEntryPoint
Anil Admal312fddb2019-03-25 12:15:43 -07001566 private void setSubHalMeasurementCorrectionsCapabilities(int subHalCapabilities) {
1567 mHandler.post(() -> {
1568 if (!mGnssMeasurementCorrectionsProvider.onCapabilitiesUpdated(subHalCapabilities)) {
1569 return;
1570 }
1571
1572 mGnssCapabilitiesProvider.setSubHalMeasurementCorrectionsCapabilities(
1573 subHalCapabilities);
1574 });
Yu-Han Yang52057622018-04-25 00:51:22 -07001575 }
1576
1577 private void restartRequests() {
1578 Log.i(TAG, "restartRequests");
1579
1580 restartLocationRequest();
1581 mGnssMeasurementsProvider.resumeIfStarted();
1582 mGnssNavigationMessageProvider.resumeIfStarted();
1583 mGnssBatchingProvider.resumeIfStarted();
1584 mGnssGeofenceProvider.resumeIfStarted();
1585 }
1586
1587 private void restartLocationRequest() {
1588 if (DEBUG) Log.d(TAG, "restartLocationRequest");
WyattRileyba6072f2019-04-18 07:37:52 -07001589 setStarted(false);
Yu-Han Yang52057622018-04-25 00:51:22 -07001590 updateRequirements();
1591 }
Wyatt Rileyd87cf912017-12-05 09:31:52 -08001592
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001593 @NativeEntryPoint
Wyatt Rileyd87cf912017-12-05 09:31:52 -08001594 private void setGnssYearOfHardware(final int yearOfHardware) {
1595 // mHardwareYear is simply set here, to be read elsewhere, and is volatile for safe sync
1596 if (DEBUG) Log.d(TAG, "setGnssYearOfHardware called with " + yearOfHardware);
1597 mHardwareYear = yearOfHardware;
Mike Lockwood04598b62010-04-14 17:17:24 -04001598 }
1599
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001600 @NativeEntryPoint
Wyatt Rileyd87cf912017-12-05 09:31:52 -08001601 private void setGnssHardwareModelName(final String modelName) {
1602 // mHardwareModelName is simply set here, to be read elsewhere, and volatile for safe sync
1603 if (DEBUG) Log.d(TAG, "setGnssModelName called with " + modelName);
1604 mHardwareModelName = modelName;
Lifu Tang82f893d2016-01-21 18:15:33 -08001605 }
1606
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001607 @NativeEntryPoint
Yu-Han Yang52057622018-04-25 00:51:22 -07001608 private void reportGnssServiceDied() {
1609 if (DEBUG) Log.d(TAG, "reportGnssServiceDied");
1610 mHandler.post(() -> {
Anil Admal0c2b21bd2019-05-03 18:29:02 -07001611 setupNativeGnssService(/* reinitializeGnssServiceHandle = */ true);
Yu-Han Yang76f99952019-05-04 17:45:44 -07001612 if (isGpsEnabled()) {
1613 setGpsEnabled(false);
1614
Soonil Nagarkar35c3b912019-01-31 10:31:24 -08001615 updateEnabled();
1616
Yu-Han Yang52057622018-04-25 00:51:22 -07001617 // resend configuration into the restarted HAL service.
Anil Admald71cf142018-12-21 14:59:36 -08001618 reloadGpsProperties();
Yu-Han Yang52057622018-04-25 00:51:22 -07001619 }
1620 });
1621 }
1622
Lifu Tang9363b942016-02-16 18:07:00 -08001623 public interface GnssSystemInfoProvider {
Lifu Tang82f893d2016-01-21 18:15:33 -08001624 /**
Wyatt Rileyd87cf912017-12-05 09:31:52 -08001625 * Returns the year of underlying GPS hardware.
Lifu Tang82f893d2016-01-21 18:15:33 -08001626 */
Lifu Tang9363b942016-02-16 18:07:00 -08001627 int getGnssYearOfHardware();
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001628
Wyatt Rileyd87cf912017-12-05 09:31:52 -08001629 /**
1630 * Returns the model name of underlying GPS hardware.
1631 */
1632 String getGnssHardwareModelName();
Lifu Tang82f893d2016-01-21 18:15:33 -08001633 }
1634
1635 /**
1636 * @hide
1637 */
Lifu Tang9363b942016-02-16 18:07:00 -08001638 public GnssSystemInfoProvider getGnssSystemInfoProvider() {
1639 return new GnssSystemInfoProvider() {
Lifu Tang82f893d2016-01-21 18:15:33 -08001640 @Override
Lifu Tang9363b942016-02-16 18:07:00 -08001641 public int getGnssYearOfHardware() {
Wyatt Rileyd87cf912017-12-05 09:31:52 -08001642 return mHardwareYear;
1643 }
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001644
Wyatt Rileyd87cf912017-12-05 09:31:52 -08001645 @Override
1646 public String getGnssHardwareModelName() {
1647 return mHardwareModelName;
Lifu Tang82f893d2016-01-21 18:15:33 -08001648 }
1649 };
1650 }
1651
Wyatt Rileycf879db2017-01-12 13:57:38 -08001652 /**
1653 * @hide
1654 */
1655 public GnssBatchingProvider getGnssBatchingProvider() {
Yu-Han Yang3557cc72018-03-21 12:48:36 -07001656 return mGnssBatchingProvider;
Wyatt Rileycf879db2017-01-12 13:57:38 -08001657 }
1658
Siddharth Raybb608c82017-03-16 11:33:34 -07001659 public interface GnssMetricsProvider {
1660 /**
1661 * Returns GNSS metrics as proto string
1662 */
1663 String getGnssMetricsAsProtoString();
1664 }
1665
1666 /**
1667 * @hide
1668 */
1669 public GnssMetricsProvider getGnssMetricsProvider() {
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001670 return () -> mGnssMetrics.dumpGnssMetricsAsProtoString();
Siddharth Raybb608c82017-03-16 11:33:34 -07001671 }
1672
Anil Admal312fddb2019-03-25 12:15:43 -07001673 /**
1674 * @hide
1675 */
1676 public GnssCapabilitiesProvider getGnssCapabilitiesProvider() {
1677 return mGnssCapabilitiesProvider;
1678 }
1679
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001680 @NativeEntryPoint
Wyatt Rileycf879db2017-01-12 13:57:38 -08001681 private void reportLocationBatch(Location[] locationArray) {
1682 List<Location> locations = new ArrayList<>(Arrays.asList(locationArray));
gomo48f1a642017-11-10 20:35:46 -08001683 if (DEBUG) {
1684 Log.d(TAG, "Location batch of size " + locationArray.length + " reported");
1685 }
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001686 reportLocation(locations);
Wyatt Rileycf879db2017-01-12 13:57:38 -08001687 }
1688
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001689 @NativeEntryPoint
Kevin Tang8c6ac672019-03-22 12:31:01 -07001690 private void psdsDownloadRequest() {
1691 if (DEBUG) Log.d(TAG, "psdsDownloadRequest");
1692 sendMessage(DOWNLOAD_PSDS_DATA, 0, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001693 }
1694
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07001695 /**
destradaa0682809a2013-08-12 18:50:30 -07001696 * Converts the GPS HAL status to the internal Geofence Hardware status.
1697 */
Yu-Han Yang6dc9f052018-12-04 17:11:24 -08001698 private static int getGeofenceStatus(int status) {
gomo48f1a642017-11-10 20:35:46 -08001699 switch (status) {
destradaa0682809a2013-08-12 18:50:30 -07001700 case GPS_GEOFENCE_OPERATION_SUCCESS:
1701 return GeofenceHardware.GEOFENCE_SUCCESS;
1702 case GPS_GEOFENCE_ERROR_GENERIC:
1703 return GeofenceHardware.GEOFENCE_FAILURE;
1704 case GPS_GEOFENCE_ERROR_ID_EXISTS:
1705 return GeofenceHardware.GEOFENCE_ERROR_ID_EXISTS;
1706 case GPS_GEOFENCE_ERROR_INVALID_TRANSITION:
1707 return GeofenceHardware.GEOFENCE_ERROR_INVALID_TRANSITION;
1708 case GPS_GEOFENCE_ERROR_TOO_MANY_GEOFENCES:
1709 return GeofenceHardware.GEOFENCE_ERROR_TOO_MANY_GEOFENCES;
1710 case GPS_GEOFENCE_ERROR_ID_UNKNOWN:
1711 return GeofenceHardware.GEOFENCE_ERROR_ID_UNKNOWN;
1712 default:
1713 return -1;
1714 }
1715 }
1716
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001717 @NativeEntryPoint
Wyatt Riley5d229832017-02-10 17:06:00 -08001718 private void reportGeofenceTransition(int geofenceId, Location location, int transition,
gomo48f1a642017-11-10 20:35:46 -08001719 long transitionTimestamp) {
Yu-Han Yang6dc9f052018-12-04 17:11:24 -08001720 mHandler.post(() -> {
1721 if (mGeofenceHardwareImpl == null) {
1722 mGeofenceHardwareImpl = GeofenceHardwareImpl.getInstance(mContext);
1723 }
Wyatt Riley5d229832017-02-10 17:06:00 -08001724
Yu-Han Yang6dc9f052018-12-04 17:11:24 -08001725 mGeofenceHardwareImpl.reportGeofenceTransition(
1726 geofenceId,
1727 location,
1728 transition,
1729 transitionTimestamp,
1730 GeofenceHardware.MONITORING_TYPE_GPS_HARDWARE,
1731 FusedBatchOptions.SourceTechnologies.GNSS);
1732 });
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07001733 }
1734
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001735 @NativeEntryPoint
Wyatt Riley5d229832017-02-10 17:06:00 -08001736 private void reportGeofenceStatus(int status, Location location) {
Yu-Han Yang6dc9f052018-12-04 17:11:24 -08001737 mHandler.post(() -> {
1738 if (mGeofenceHardwareImpl == null) {
1739 mGeofenceHardwareImpl = GeofenceHardwareImpl.getInstance(mContext);
1740 }
1741 int monitorStatus = GeofenceHardware.MONITOR_CURRENTLY_UNAVAILABLE;
1742 if (status == GPS_GEOFENCE_AVAILABLE) {
1743 monitorStatus = GeofenceHardware.MONITOR_CURRENTLY_AVAILABLE;
1744 }
1745 mGeofenceHardwareImpl.reportGeofenceMonitorStatus(
1746 GeofenceHardware.MONITORING_TYPE_GPS_HARDWARE,
1747 monitorStatus,
1748 location,
1749 FusedBatchOptions.SourceTechnologies.GNSS);
1750 });
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07001751 }
1752
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001753 @NativeEntryPoint
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07001754 private void reportGeofenceAddStatus(int geofenceId, int status) {
Yu-Han Yang6dc9f052018-12-04 17:11:24 -08001755 mHandler.post(() -> {
1756 if (mGeofenceHardwareImpl == null) {
1757 mGeofenceHardwareImpl = GeofenceHardwareImpl.getInstance(mContext);
1758 }
1759 mGeofenceHardwareImpl.reportGeofenceAddStatus(geofenceId, getGeofenceStatus(status));
1760 });
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07001761 }
1762
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001763 @NativeEntryPoint
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07001764 private void reportGeofenceRemoveStatus(int geofenceId, int status) {
Yu-Han Yang6dc9f052018-12-04 17:11:24 -08001765 mHandler.post(() -> {
1766 if (mGeofenceHardwareImpl == null) {
1767 mGeofenceHardwareImpl = GeofenceHardwareImpl.getInstance(mContext);
1768 }
1769 mGeofenceHardwareImpl.reportGeofenceRemoveStatus(geofenceId, getGeofenceStatus(status));
1770 });
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07001771 }
1772
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001773 @NativeEntryPoint
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07001774 private void reportGeofencePauseStatus(int geofenceId, int status) {
Yu-Han Yang6dc9f052018-12-04 17:11:24 -08001775 mHandler.post(() -> {
1776 if (mGeofenceHardwareImpl == null) {
1777 mGeofenceHardwareImpl = GeofenceHardwareImpl.getInstance(mContext);
1778 }
1779 mGeofenceHardwareImpl.reportGeofencePauseStatus(geofenceId, getGeofenceStatus(status));
1780 });
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07001781 }
1782
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001783 @NativeEntryPoint
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07001784 private void reportGeofenceResumeStatus(int geofenceId, int status) {
Yu-Han Yang6dc9f052018-12-04 17:11:24 -08001785 mHandler.post(() -> {
1786 if (mGeofenceHardwareImpl == null) {
1787 mGeofenceHardwareImpl = GeofenceHardwareImpl.getInstance(mContext);
1788 }
1789 mGeofenceHardwareImpl.reportGeofenceResumeStatus(geofenceId, getGeofenceStatus(status));
1790 });
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07001791 }
1792
Danke Xie22d1f9f2009-08-18 18:28:45 -04001793 //=============================================================
1794 // NI Client support
Miguel Torroja1e84da82010-07-27 07:02:24 +02001795 //=============================================================
Danke Xie22d1f9f2009-08-18 18:28:45 -04001796 private final INetInitiatedListener mNetInitiatedListener = new INetInitiatedListener.Stub() {
destradaaef752b62015-04-17 13:10:47 -07001797 // Sends a response for an NI request to HAL.
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001798 @Override
gomo48f1a642017-11-10 20:35:46 -08001799 public boolean sendNiResponse(int notificationId, int userResponse) {
Miguel Torroja1e84da82010-07-27 07:02:24 +02001800 // TODO Add Permission check
Danke Xie22d1f9f2009-08-18 18:28:45 -04001801
gomo48f1a642017-11-10 20:35:46 -08001802 if (DEBUG) {
1803 Log.d(TAG, "sendNiResponse, notifId: " + notificationId +
1804 ", response: " + userResponse);
1805 }
Miguel Torroja1e84da82010-07-27 07:02:24 +02001806 native_send_ni_response(notificationId, userResponse);
Yu-Han Yang8a1b51d2018-12-26 22:18:31 -08001807
1808 StatsLog.write(StatsLog.GNSS_NI_EVENT_REPORTED,
1809 StatsLog.GNSS_NI_EVENT_REPORTED__EVENT_TYPE__NI_RESPONSE,
1810 notificationId,
1811 /* niType= */ 0,
1812 /* needNotify= */ false,
1813 /* needVerify= */ false,
1814 /* privacyOverride= */ false,
1815 /* timeout= */ 0,
1816 /* defaultResponse= */ 0,
1817 /* requestorId= */ null,
1818 /* text= */ null,
1819 /* requestorIdEncoding= */ 0,
1820 /* textEncoding= */ 0,
1821 mSuplEsEnabled,
Yu-Han Yang76f99952019-05-04 17:45:44 -07001822 isGpsEnabled(),
Yu-Han Yang8a1b51d2018-12-26 22:18:31 -08001823 userResponse);
1824
Miguel Torroja1e84da82010-07-27 07:02:24 +02001825 return true;
1826 }
Danke Xie22d1f9f2009-08-18 18:28:45 -04001827 };
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001828
Danke Xie22d1f9f2009-08-18 18:28:45 -04001829 public INetInitiatedListener getNetInitiatedListener() {
1830 return mNetInitiatedListener;
1831 }
1832
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001833 /** Reports a NI notification. */
1834 @NativeEntryPoint
Miguel Torroja1e84da82010-07-27 07:02:24 +02001835 public void reportNiNotification(
1836 int notificationId,
1837 int niType,
1838 int notifyFlags,
1839 int timeout,
1840 int defaultResponse,
1841 String requestorId,
1842 String text,
1843 int requestorIdEncoding,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001844 int textEncoding
gomo48f1a642017-11-10 20:35:46 -08001845 ) {
Miguel Torroja1e84da82010-07-27 07:02:24 +02001846 Log.i(TAG, "reportNiNotification: entered");
1847 Log.i(TAG, "notificationId: " + notificationId +
1848 ", niType: " + niType +
1849 ", notifyFlags: " + notifyFlags +
1850 ", timeout: " + timeout +
1851 ", defaultResponse: " + defaultResponse);
1852
1853 Log.i(TAG, "requestorId: " + requestorId +
1854 ", text: " + text +
1855 ", requestorIdEncoding: " + requestorIdEncoding +
1856 ", textEncoding: " + textEncoding);
1857
1858 GpsNiNotification notification = new GpsNiNotification();
1859
1860 notification.notificationId = notificationId;
1861 notification.niType = niType;
1862 notification.needNotify = (notifyFlags & GpsNetInitiatedHandler.GPS_NI_NEED_NOTIFY) != 0;
1863 notification.needVerify = (notifyFlags & GpsNetInitiatedHandler.GPS_NI_NEED_VERIFY) != 0;
gomo48f1a642017-11-10 20:35:46 -08001864 notification.privacyOverride =
1865 (notifyFlags & GpsNetInitiatedHandler.GPS_NI_PRIVACY_OVERRIDE) != 0;
Miguel Torroja1e84da82010-07-27 07:02:24 +02001866 notification.timeout = timeout;
1867 notification.defaultResponse = defaultResponse;
1868 notification.requestorId = requestorId;
1869 notification.text = text;
1870 notification.requestorIdEncoding = requestorIdEncoding;
1871 notification.textEncoding = textEncoding;
1872
Miguel Torroja1e84da82010-07-27 07:02:24 +02001873 mNIHandler.handleNiNotification(notification);
Yu-Han Yang8a1b51d2018-12-26 22:18:31 -08001874 StatsLog.write(StatsLog.GNSS_NI_EVENT_REPORTED,
1875 StatsLog.GNSS_NI_EVENT_REPORTED__EVENT_TYPE__NI_REQUEST,
1876 notification.notificationId,
1877 notification.niType,
1878 notification.needNotify,
1879 notification.needVerify,
1880 notification.privacyOverride,
1881 notification.timeout,
1882 notification.defaultResponse,
1883 notification.requestorId,
1884 notification.text,
1885 notification.requestorIdEncoding,
1886 notification.textEncoding,
1887 mSuplEsEnabled,
Yu-Han Yang76f99952019-05-04 17:45:44 -07001888 isGpsEnabled(),
Yu-Han Yang8a1b51d2018-12-26 22:18:31 -08001889 /* userResponse= */ 0);
Miguel Torroja1e84da82010-07-27 07:02:24 +02001890 }
1891
1892 /**
Miguel Torroja1e84da82010-07-27 07:02:24 +02001893 * We should be careful about receiving null string from the TelephonyManager,
1894 * because sending null String to JNI function would cause a crash.
1895 */
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001896 @NativeEntryPoint
Miguel Torroja1e84da82010-07-27 07:02:24 +02001897 private void requestSetID(int flags) {
1898 TelephonyManager phone = (TelephonyManager)
1899 mContext.getSystemService(Context.TELEPHONY_SERVICE);
destradaaef752b62015-04-17 13:10:47 -07001900 int type = AGPS_SETID_TYPE_NONE;
Anil Admale1539e82019-05-09 15:05:04 -07001901 String setId = null;
Miguel Torroja1e84da82010-07-27 07:02:24 +02001902
Anil Admale1539e82019-05-09 15:05:04 -07001903 int ddSubId = SubscriptionManager.getDefaultDataSubscriptionId();
Miguel Torroja1e84da82010-07-27 07:02:24 +02001904 if ((flags & AGPS_RIL_REQUEST_SETID_IMSI) == AGPS_RIL_REQUEST_SETID_IMSI) {
Anil Admale1539e82019-05-09 15:05:04 -07001905 if (SubscriptionManager.isValidSubscriptionId(ddSubId)) {
1906 setId = phone.getSubscriberId(ddSubId);
1907 }
1908 if (setId == null) {
1909 setId = phone.getSubscriberId();
1910 }
1911 if (setId != null) {
Miguel Torroja1e84da82010-07-27 07:02:24 +02001912 // This means the framework has the SIM card.
Miguel Torroja1e84da82010-07-27 07:02:24 +02001913 type = AGPS_SETID_TYPE_IMSI;
1914 }
gomo48f1a642017-11-10 20:35:46 -08001915 } else if ((flags & AGPS_RIL_REQUEST_SETID_MSISDN) == AGPS_RIL_REQUEST_SETID_MSISDN) {
Anil Admale1539e82019-05-09 15:05:04 -07001916 if (SubscriptionManager.isValidSubscriptionId(ddSubId)) {
1917 setId = phone.getLine1Number(ddSubId);
1918 }
1919 if (setId == null) {
1920 setId = phone.getLine1Number();
1921 }
1922 if (setId != null) {
Miguel Torroja1e84da82010-07-27 07:02:24 +02001923 // This means the framework has the SIM card.
Miguel Torroja1e84da82010-07-27 07:02:24 +02001924 type = AGPS_SETID_TYPE_MSISDN;
1925 }
1926 }
Anil Admale1539e82019-05-09 15:05:04 -07001927
1928 native_agps_set_id(type, (setId == null) ? "" : setId);
Miguel Torroja1e84da82010-07-27 07:02:24 +02001929 }
1930
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001931 @NativeEntryPoint
Yu-Han Yang53f4d6d2019-02-13 21:47:41 -08001932 private void requestLocation(boolean independentFromGnss, boolean isUserEmergency) {
Yu-Han Yange7baef32018-02-09 13:58:17 -08001933 if (DEBUG) {
Yu-Han Yang53f4d6d2019-02-13 21:47:41 -08001934 Log.d(TAG, "requestLocation. independentFromGnss: " + independentFromGnss
1935 + ", isUserEmergency: "
1936 + isUserEmergency);
Yu-Han Yange7baef32018-02-09 13:58:17 -08001937 }
Yu-Han Yang53f4d6d2019-02-13 21:47:41 -08001938 sendMessage(REQUEST_LOCATION, independentFromGnss ? 1 : 0, isUserEmergency);
Yu-Han Yange7baef32018-02-09 13:58:17 -08001939 }
1940
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001941 @NativeEntryPoint
Mike Lockwood9b9fb5c2011-06-29 15:09:40 -04001942 private void requestUtcTime() {
destradaae21252a2015-09-08 12:32:59 -07001943 if (DEBUG) Log.d(TAG, "utcTimeRequest");
Mike Lockwood9b9fb5c2011-06-29 15:09:40 -04001944 sendMessage(INJECT_NTP_TIME, 0, null);
1945 }
1946
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001947 @NativeEntryPoint
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001948 private void requestRefLocation() {
Miguel Torroja1e84da82010-07-27 07:02:24 +02001949 TelephonyManager phone = (TelephonyManager)
1950 mContext.getSystemService(Context.TELEPHONY_SERVICE);
Victoria Leased50d0c32012-10-29 13:16:17 -07001951 final int phoneType = phone.getPhoneType();
1952 if (phoneType == TelephonyManager.PHONE_TYPE_GSM) {
Miguel Torroja1e84da82010-07-27 07:02:24 +02001953 GsmCellLocation gsm_cell = (GsmCellLocation) phone.getCellLocation();
Victoria Leased50d0c32012-10-29 13:16:17 -07001954 if ((gsm_cell != null) && (phone.getNetworkOperator() != null)
1955 && (phone.getNetworkOperator().length() > 3)) {
Miguel Torroja1e84da82010-07-27 07:02:24 +02001956 int type;
gomo48f1a642017-11-10 20:35:46 -08001957 int mcc = Integer.parseInt(phone.getNetworkOperator().substring(0, 3));
Miguel Torroja1e84da82010-07-27 07:02:24 +02001958 int mnc = Integer.parseInt(phone.getNetworkOperator().substring(3));
Mike Lockwoodedc0f3872010-10-22 09:16:17 -04001959 int networkType = phone.getNetworkType();
1960 if (networkType == TelephonyManager.NETWORK_TYPE_UMTS
gomo48f1a642017-11-10 20:35:46 -08001961 || networkType == TelephonyManager.NETWORK_TYPE_HSDPA
1962 || networkType == TelephonyManager.NETWORK_TYPE_HSUPA
1963 || networkType == TelephonyManager.NETWORK_TYPE_HSPA
1964 || networkType == TelephonyManager.NETWORK_TYPE_HSPAP) {
Miguel Torroja1e84da82010-07-27 07:02:24 +02001965 type = AGPS_REF_LOCATION_TYPE_UMTS_CELLID;
Mike Lockwoodedc0f3872010-10-22 09:16:17 -04001966 } else {
Miguel Torroja1e84da82010-07-27 07:02:24 +02001967 type = AGPS_REF_LOCATION_TYPE_GSM_CELLID;
Mike Lockwoodedc0f3872010-10-22 09:16:17 -04001968 }
Miguel Torroja1e84da82010-07-27 07:02:24 +02001969 native_agps_set_ref_location_cellid(type, mcc, mnc,
1970 gsm_cell.getLac(), gsm_cell.getCid());
Mike Lockwoodedc0f3872010-10-22 09:16:17 -04001971 } else {
gomo48f1a642017-11-10 20:35:46 -08001972 Log.e(TAG, "Error getting cell location info.");
Mike Lockwoodedc0f3872010-10-22 09:16:17 -04001973 }
Victoria Leased50d0c32012-10-29 13:16:17 -07001974 } else if (phoneType == TelephonyManager.PHONE_TYPE_CDMA) {
1975 Log.e(TAG, "CDMA not supported.");
Mike Lockwoodedc0f3872010-10-22 09:16:17 -04001976 }
Miguel Torroja1e84da82010-07-27 07:02:24 +02001977 }
Danke Xie22d1f9f2009-08-18 18:28:45 -04001978
Anil Admal94ec76a2019-01-15 09:42:01 -08001979 // Implements method nfwNotifyCb() in IGnssVisibilityControlCallback.hal.
1980 @NativeEntryPoint
1981 private void reportNfwNotification(String proxyAppPackageName, byte protocolStack,
1982 String otherProtocolStackName, byte requestor, String requestorId, byte responseType,
1983 boolean inEmergencyMode, boolean isCachedLocation) {
1984 if (mGnssVisibilityControl == null) {
1985 Log.e(TAG, "reportNfwNotification: mGnssVisibilityControl is not initialized.");
1986 return;
1987 }
1988
1989 mGnssVisibilityControl.reportNfwNotification(proxyAppPackageName, protocolStack,
1990 otherProtocolStackName, requestor, requestorId, responseType, inEmergencyMode,
1991 isCachedLocation);
1992 }
1993
1994 // Implements method isInEmergencySession() in IGnssVisibilityControlCallback.hal.
1995 @NativeEntryPoint
1996 boolean isInEmergencySession() {
1997 return mNIHandler.getInEmergency();
1998 }
1999
Mike Lockwood98e48692010-04-07 16:32:51 -04002000 private void sendMessage(int message, int arg, Object obj) {
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002001 // hold a wake lock until this message is delivered
Jeff Brown028872f2012-08-25 13:07:01 -07002002 // note that this assumes the message will not be removed from the queue before
2003 // it is handled (otherwise the wake lock would be leaked).
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002004 mWakeLock.acquire();
Anil Admal4f97c942018-11-12 10:52:46 -08002005 if (DEBUG) {
2006 Log.d(TAG, "WakeLock acquired by sendMessage(" + messageIdAsString(message) + ", " + arg
Wyatt Rileycf879db2017-01-12 13:57:38 -08002007 + ", " + obj + ")");
2008 }
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002009 mHandler.obtainMessage(message, arg, 1, obj).sendToTarget();
Mike Lockwood98e48692010-04-07 16:32:51 -04002010 }
2011
Mike Lockwood62a8fc12010-03-22 14:23:26 -04002012 private final class ProviderHandler extends Handler {
Victoria Lease5cd731a2012-12-19 15:04:21 -08002013 public ProviderHandler(Looper looper) {
2014 super(looper, null, true /*async*/);
Jeff Brown028872f2012-08-25 13:07:01 -07002015 }
2016
Mike Lockwood62a8fc12010-03-22 14:23:26 -04002017 @Override
Mike Lockwood4a7b65e2010-10-25 16:35:55 -04002018 public void handleMessage(Message msg) {
Mike Lockwood98e48692010-04-07 16:32:51 -04002019 int message = msg.what;
2020 switch (message) {
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002021 case SET_REQUEST:
2022 GpsRequest gpsRequest = (GpsRequest) msg.obj;
2023 handleSetRequest(gpsRequest.request, gpsRequest.source);
Mike Lockwood03ca2162010-04-01 08:10:09 -07002024 break;
Mike Lockwood62a8fc12010-03-22 14:23:26 -04002025 case INJECT_NTP_TIME:
Yu-Han Yanga1862b52018-02-20 17:05:59 -08002026 mNtpTimeHelper.retrieveAndInjectNtpTime();
Mike Lockwood62a8fc12010-03-22 14:23:26 -04002027 break;
Yu-Han Yange7baef32018-02-09 13:58:17 -08002028 case REQUEST_LOCATION:
Yu-Han Yang53f4d6d2019-02-13 21:47:41 -08002029 handleRequestLocation(msg.arg1 == 1, (boolean) msg.obj);
Yu-Han Yange7baef32018-02-09 13:58:17 -08002030 break;
Kevin Tang8c6ac672019-03-22 12:31:01 -07002031 case DOWNLOAD_PSDS_DATA:
2032 handleDownloadPsdsData();
Mike Lockwood62a8fc12010-03-22 14:23:26 -04002033 break;
Kevin Tang8c6ac672019-03-22 12:31:01 -07002034 case DOWNLOAD_PSDS_DATA_FINISHED:
2035 mDownloadPsdsDataPending = STATE_IDLE;
Kevin Tang40e1baf2012-01-10 14:32:44 -08002036 break;
Mike Lockwood62a8fc12010-03-22 14:23:26 -04002037 case UPDATE_LOCATION:
destradaae21252a2015-09-08 12:32:59 -07002038 handleUpdateLocation((Location) msg.obj);
Mike Lockwood62a8fc12010-03-22 14:23:26 -04002039 break;
destradaafb23c672015-04-16 14:01:27 -07002040 case INITIALIZE_HANDLER:
destradaae21252a2015-09-08 12:32:59 -07002041 handleInitialize();
destradaafb23c672015-04-16 14:01:27 -07002042 break;
Wyatt Riley26465d22018-02-12 13:44:24 -08002043 case REPORT_LOCATION:
2044 handleReportLocation(msg.arg1 == 1, (Location) msg.obj);
2045 break;
2046 case REPORT_SV_STATUS:
2047 handleReportSvStatus((SvStatusInfo) msg.obj);
2048 break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002049 }
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002050 if (msg.arg2 == 1) {
2051 // wakelock was taken for this message, release it
2052 mWakeLock.release();
Anil Admal4f97c942018-11-12 10:52:46 -08002053 if (DEBUG) {
2054 Log.d(TAG, "WakeLock released by handleMessage(" + messageIdAsString(message)
Wyatt Rileycf879db2017-01-12 13:57:38 -08002055 + ", " + msg.arg1 + ", " + msg.obj + ")");
2056 }
Mike Lockwood98e48692010-04-07 16:32:51 -04002057 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002058 }
destradaafb23c672015-04-16 14:01:27 -07002059
2060 /**
Soonil Nagarkar1575a042018-10-24 17:54:54 -07002061 * This method is bound to {@link #GnssLocationProvider(Context, LocationProviderManager,
2062 * Looper)}.
destradaafb23c672015-04-16 14:01:27 -07002063 * It is in charge of loading properties and registering for events that will be posted to
2064 * this handler.
2065 */
destradaae21252a2015-09-08 12:32:59 -07002066 private void handleInitialize() {
Anil Admal0c2b21bd2019-05-03 18:29:02 -07002067 // class_init_native() already initializes the GNSS service handle during class loading.
2068 setupNativeGnssService(/* reinitializeGnssServiceHandle = */ false);
Wyatt Riley523a0cf2017-10-31 14:36:52 -07002069
Anil Admal94ec76a2019-01-15 09:42:01 -08002070 if (native_is_gnss_visibility_control_supported()) {
Anil Admal8a246a22019-05-05 00:34:55 -07002071 mGnssVisibilityControl = new GnssVisibilityControl(mContext, mLooper, mNIHandler);
Anil Admal94ec76a2019-01-15 09:42:01 -08002072 }
2073
destradaafb23c672015-04-16 14:01:27 -07002074 // load default GPS configuration
2075 // (this configuration might change in the future based on SIM changes)
Anil Admald71cf142018-12-21 14:59:36 -08002076 reloadGpsProperties();
destradaafb23c672015-04-16 14:01:27 -07002077
destradaafb23c672015-04-16 14:01:27 -07002078 // listen for events
WyattRiley6593cf12018-06-23 10:37:48 -07002079 IntentFilter intentFilter = new IntentFilter();
destradaafb23c672015-04-16 14:01:27 -07002080 intentFilter.addAction(ALARM_WAKEUP);
2081 intentFilter.addAction(ALARM_TIMEOUT);
destradaafb23c672015-04-16 14:01:27 -07002082 intentFilter.addAction(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED);
Adam Lesinski87c17df2015-05-27 13:24:13 -07002083 intentFilter.addAction(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED);
destradaafb23c672015-04-16 14:01:27 -07002084 intentFilter.addAction(Intent.ACTION_SCREEN_OFF);
2085 intentFilter.addAction(Intent.ACTION_SCREEN_ON);
Meng Wang19b214d2018-11-07 12:14:39 -08002086 intentFilter.addAction(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
Anil Admale1539e82019-05-09 15:05:04 -07002087 intentFilter.addAction(TelephonyIntents.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED);
destradaafb23c672015-04-16 14:01:27 -07002088 mContext.registerReceiver(mBroadcastReceiver, intentFilter, null, this);
2089
Anil Admal50ba15e2018-11-01 16:42:42 -07002090 mNetworkConnectivityHandler.registerNetworkCallbacks();
destradaae21252a2015-09-08 12:32:59 -07002091
destradaafb23c672015-04-16 14:01:27 -07002092 // listen for PASSIVE_PROVIDER updates
2093 LocationManager locManager =
2094 (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE);
2095 long minTime = 0;
2096 float minDistance = 0;
destradaafb23c672015-04-16 14:01:27 -07002097 LocationRequest request = LocationRequest.createFromDeprecatedProvider(
2098 LocationManager.PASSIVE_PROVIDER,
2099 minTime,
2100 minDistance,
Soonil Nagarkar1575a042018-10-24 17:54:54 -07002101 false);
destradaafb23c672015-04-16 14:01:27 -07002102 // Don't keep track of this request since it's done on behalf of other clients
2103 // (which are kept track of separately).
2104 request.setHideFromAppOps(true);
2105 locManager.requestLocationUpdates(
2106 request,
2107 new NetworkLocationListener(),
2108 getLooper());
Soonil Nagarkar1575a042018-10-24 17:54:54 -07002109
Soonil Nagarkar35c3b912019-01-31 10:31:24 -08002110 updateEnabled();
destradaafb23c672015-04-16 14:01:27 -07002111 }
2112 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002113
Yu-Han Yange7baef32018-02-09 13:58:17 -08002114 private abstract class LocationChangeListener implements LocationListener {
Soonil Nagarkar1575a042018-10-24 17:54:54 -07002115 private int mNumLocationUpdateRequest;
Yu-Han Yang07561382018-02-21 13:08:37 -08002116
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002117 @Override
gomo48f1a642017-11-10 20:35:46 -08002118 public void onStatusChanged(String provider, int status, Bundle extras) {
2119 }
2120
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002121 @Override
gomo48f1a642017-11-10 20:35:46 -08002122 public void onProviderEnabled(String provider) {
2123 }
2124
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002125 @Override
gomo48f1a642017-11-10 20:35:46 -08002126 public void onProviderDisabled(String provider) {
2127 }
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002128 }
2129
Yu-Han Yange7baef32018-02-09 13:58:17 -08002130 private final class NetworkLocationListener extends LocationChangeListener {
2131 @Override
2132 public void onLocationChanged(Location location) {
2133 // this callback happens on mHandler looper
2134 if (LocationManager.NETWORK_PROVIDER.equals(location.getProvider())) {
2135 handleUpdateLocation(location);
2136 }
2137 }
2138 }
2139
2140 private final class FusedLocationListener extends LocationChangeListener {
2141 @Override
2142 public void onLocationChanged(Location location) {
2143 if (LocationManager.FUSED_PROVIDER.equals(location.getProvider())) {
Yu-Han Yange7baef32018-02-09 13:58:17 -08002144 injectBestLocation(location);
2145 }
2146 }
2147 }
2148
Wyatt Rileycf879db2017-01-12 13:57:38 -08002149 /**
2150 * @return A string representing the given message ID.
2151 */
2152 private String messageIdAsString(int message) {
2153 switch (message) {
Wyatt Rileycf879db2017-01-12 13:57:38 -08002154 case SET_REQUEST:
2155 return "SET_REQUEST";
Wyatt Rileycf879db2017-01-12 13:57:38 -08002156 case INJECT_NTP_TIME:
2157 return "INJECT_NTP_TIME";
Yu-Han Yange7baef32018-02-09 13:58:17 -08002158 case REQUEST_LOCATION:
2159 return "REQUEST_LOCATION";
Kevin Tang8c6ac672019-03-22 12:31:01 -07002160 case DOWNLOAD_PSDS_DATA:
2161 return "DOWNLOAD_PSDS_DATA";
2162 case DOWNLOAD_PSDS_DATA_FINISHED:
2163 return "DOWNLOAD_PSDS_DATA_FINISHED";
Wyatt Rileycf879db2017-01-12 13:57:38 -08002164 case UPDATE_LOCATION:
2165 return "UPDATE_LOCATION";
Wyatt Rileycf879db2017-01-12 13:57:38 -08002166 case INITIALIZE_HANDLER:
2167 return "INITIALIZE_HANDLER";
Wyatt Riley26465d22018-02-12 13:44:24 -08002168 case REPORT_LOCATION:
2169 return "REPORT_LOCATION";
2170 case REPORT_SV_STATUS:
2171 return "REPORT_SV_STATUS";
Wyatt Rileycf879db2017-01-12 13:57:38 -08002172 default:
2173 return "<Unknown>";
2174 }
2175 }
2176
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002177 @Override
2178 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2179 StringBuilder s = new StringBuilder();
WyattRileyba6072f2019-04-18 07:37:52 -07002180 s.append(" mStarted=").append(mStarted).append(" (changed ");
2181 TimeUtils.formatDuration(SystemClock.elapsedRealtime()
2182 - mStartedChangedElapsedRealtime, s);
2183 s.append(" ago)").append('\n');
destradaa25e8caf2015-08-24 14:14:44 -07002184 s.append(" mFixInterval=").append(mFixInterval).append('\n');
gomo48f1a642017-11-10 20:35:46 -08002185 s.append(" mLowPowerMode=").append(mLowPowerMode).append('\n');
Wyatt Riley74479bd2018-01-17 08:48:27 -08002186 s.append(" mGnssMeasurementsProvider.isRegistered()=")
2187 .append(mGnssMeasurementsProvider.isRegistered()).append('\n');
2188 s.append(" mGnssNavigationMessageProvider.isRegistered()=")
2189 .append(mGnssNavigationMessageProvider.isRegistered()).append('\n');
WyattRileyb2446072019-03-01 07:41:49 -08002190 s.append(" mDisableGpsForPowerManager=").append(mDisableGpsForPowerManager).append('\n');
Anil Admal312fddb2019-03-25 12:15:43 -07002191 s.append(" mTopHalCapabilities=0x").append(Integer.toHexString(mTopHalCapabilities));
destradaa25e8caf2015-08-24 14:14:44 -07002192 s.append(" ( ");
2193 if (hasCapability(GPS_CAPABILITY_SCHEDULING)) s.append("SCHEDULING ");
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002194 if (hasCapability(GPS_CAPABILITY_MSB)) s.append("MSB ");
2195 if (hasCapability(GPS_CAPABILITY_MSA)) s.append("MSA ");
2196 if (hasCapability(GPS_CAPABILITY_SINGLE_SHOT)) s.append("SINGLE_SHOT ");
2197 if (hasCapability(GPS_CAPABILITY_ON_DEMAND_TIME)) s.append("ON_DEMAND_TIME ");
destradaa25e8caf2015-08-24 14:14:44 -07002198 if (hasCapability(GPS_CAPABILITY_GEOFENCING)) s.append("GEOFENCING ");
2199 if (hasCapability(GPS_CAPABILITY_MEASUREMENTS)) s.append("MEASUREMENTS ");
2200 if (hasCapability(GPS_CAPABILITY_NAV_MESSAGES)) s.append("NAV_MESSAGES ");
Anil Admalefd9dc62019-03-12 17:39:20 -07002201 if (hasCapability(GPS_CAPABILITY_LOW_POWER_MODE)) s.append("LOW_POWER_MODE ");
2202 if (hasCapability(GPS_CAPABILITY_SATELLITE_BLACKLIST)) s.append("SATELLITE_BLACKLIST ");
Anil Admal62c42dc2019-04-03 15:39:22 -07002203 if (hasCapability(GPS_CAPABILITY_MEASUREMENT_CORRECTIONS)) {
2204 s.append("MEASUREMENT_CORRECTIONS ");
2205 }
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002206 s.append(")\n");
Anil Admal3ba0fa92019-04-19 17:43:00 -07002207 if (hasCapability(GPS_CAPABILITY_MEASUREMENT_CORRECTIONS)) {
Anil Admal62c42dc2019-04-03 15:39:22 -07002208 s.append(" SubHal=MEASUREMENT_CORRECTIONS[");
Anil Admalefd9dc62019-03-12 17:39:20 -07002209 s.append(mGnssMeasurementCorrectionsProvider.toStringCapabilities());
2210 s.append("]\n");
2211 }
Siddharth Raybb608c82017-03-16 11:33:34 -07002212 s.append(mGnssMetrics.dumpGnssMetricsAsText());
2213 s.append(" native internal state: ").append(native_get_internal_state());
Wyatt Rileycf879db2017-01-12 13:57:38 -08002214 s.append("\n");
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002215 pw.append(s);
2216 }
2217
Anil Admal0c2b21bd2019-05-03 18:29:02 -07002218 private void setupNativeGnssService(boolean reinitializeGnssServiceHandle) {
2219 native_init_once(reinitializeGnssServiceHandle);
Anil Admal7e3953b2019-05-04 20:45:22 -07002220
2221 /*
2222 * A cycle of native_init() and native_cleanup() is needed so that callbacks are
2223 * registered after bootup even when location is disabled.
2224 * This will allow Emergency SUPL to work even when location is disabled before device
2225 * restart.
2226 */
2227 boolean isInitialized = native_init();
2228 if (!isInitialized) {
2229 Log.w(TAG, "Native initialization failed.");
2230 } else {
2231 native_cleanup();
2232 }
2233 }
2234
Mike Lockwoodb16e7802009-08-06 09:26:02 -04002235 // preallocated to avoid memory allocation in reportNmea()
2236 private byte[] mNmeaBuffer = new byte[120];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002237
gomo48f1a642017-11-10 20:35:46 -08002238 static {
2239 class_init_native();
2240 }
2241
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002242 private static native void class_init_native();
gomo48f1a642017-11-10 20:35:46 -08002243
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002244 private static native boolean native_is_supported();
gomo48f1a642017-11-10 20:35:46 -08002245
Anil Admal94ec76a2019-01-15 09:42:01 -08002246 private static native boolean native_is_gnss_visibility_control_supported();
2247
Anil Admal0c2b21bd2019-05-03 18:29:02 -07002248 private static native void native_init_once(boolean reinitializeGnssServiceHandle);
Yu-Han Yang6d317352018-03-15 11:53:01 -07002249
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002250 private native boolean native_init();
gomo48f1a642017-11-10 20:35:46 -08002251
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002252 private native void native_cleanup();
gomo48f1a642017-11-10 20:35:46 -08002253
Mike Lockwood04598b62010-04-14 17:17:24 -04002254 private native boolean native_set_position_mode(int mode, int recurrence, int min_interval,
gomo48f1a642017-11-10 20:35:46 -08002255 int preferred_accuracy, int preferred_time, boolean lowPowerMode);
2256
Mike Lockwood04598b62010-04-14 17:17:24 -04002257 private native boolean native_start();
gomo48f1a642017-11-10 20:35:46 -08002258
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002259 private native boolean native_stop();
gomo48f1a642017-11-10 20:35:46 -08002260
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002261 private native void native_delete_aiding_data(int flags);
gomo48f1a642017-11-10 20:35:46 -08002262
Mike Lockwoodf602d362010-06-20 14:28:16 -07002263 private native int native_read_nmea(byte[] buffer, int bufferSize);
gomo48f1a642017-11-10 20:35:46 -08002264
Yu-Han Yange7baef32018-02-09 13:58:17 -08002265 private native void native_inject_best_location(
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -08002266 int gnssLocationFlags, double latitudeDegrees, double longitudeDegrees,
2267 double altitudeMeters, float speedMetersPerSec, float bearingDegrees,
2268 float horizontalAccuracyMeters, float verticalAccuracyMeters,
2269 float speedAccuracyMetersPerSecond, float bearingAccuracyDegrees,
Pierre Fite-Georgel9e96c572019-02-25 16:12:53 -08002270 long timestamp, int elapsedRealtimeFlags, long elapsedRealtimeNanos,
Yu-Han Yang3cd9a862019-03-25 17:00:03 -07002271 double elapsedRealtimeUncertaintyNanos);
Yu-Han Yange7baef32018-02-09 13:58:17 -08002272
Mike Lockwoodd26ce0d2009-06-11 12:25:46 -04002273 private native void native_inject_location(double latitude, double longitude, float accuracy);
2274
Kevin Tang8c6ac672019-03-22 12:31:01 -07002275 // PSDS Support
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002276 private native void native_inject_time(long time, long timeReference, int uncertainty);
gomo48f1a642017-11-10 20:35:46 -08002277
Kevin Tang8c6ac672019-03-22 12:31:01 -07002278 private native boolean native_supports_psds();
gomo48f1a642017-11-10 20:35:46 -08002279
Kevin Tang8c6ac672019-03-22 12:31:01 -07002280 private native void native_inject_psds_data(byte[] data, int length);
The Android Open Source Project10592532009-03-18 17:39:46 -07002281
Fred Fettinger3c8fbdf2010-01-04 15:38:13 -06002282 // DEBUG Support
2283 private native String native_get_internal_state();
2284
2285 // AGPS Support
gomo48f1a642017-11-10 20:35:46 -08002286 private native void native_agps_ni_message(byte[] msg, int length);
2287
Mike Lockwooda9e54612009-06-19 14:54:42 -04002288 private native void native_set_agps_server(int type, String hostname, int port);
Danke Xie22d1f9f2009-08-18 18:28:45 -04002289
2290 // Network-initiated (NI) Support
2291 private native void native_send_ni_response(int notificationId, int userResponse);
Miguel Torroja1e84da82010-07-27 07:02:24 +02002292
Anil Admal50ba15e2018-11-01 16:42:42 -07002293 // AGPS ril support
Miguel Torroja1e84da82010-07-27 07:02:24 +02002294 private native void native_agps_set_ref_location_cellid(int type, int mcc, int mnc,
2295 int lac, int cid);
gomo48f1a642017-11-10 20:35:46 -08002296
Miguel Torroja1e84da82010-07-27 07:02:24 +02002297 private native void native_agps_set_id(int type, String setid);
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -08002298}