blob: d8acf0e331afeadd688cefbc48b936a235153ae7 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
Sasha Kuznetsov94bb0092020-03-26 12:08:17 -07002 * Copyright (C) 2020 The Android Open Source Project
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08003 *
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
Sasha Kuznetsov94bb0092020-03-26 12:08:17 -070017package com.android.server.location.gnss;
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;
Sasha Kuznetsova68a7a32020-02-11 06:00:10 +000032import android.location.GnssAntennaInfo;
Yu-Han Yange7baef32018-02-09 13:58:17 -080033import android.location.GnssMeasurementsEvent;
34import android.location.GnssNavigationMessage;
Lifu Tang30f95a72016-01-07 23:20:38 -080035import android.location.GnssStatus;
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -070036import android.location.IGpsGeofenceHardware;
Danke Xie22d1f9f2009-08-18 18:28:45 -040037import android.location.INetInitiatedListener;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080038import android.location.Location;
Nick Pelly6fa9ad42012-07-16 12:18:23 -070039import android.location.LocationListener;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080040import android.location.LocationManager;
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;
WyattRileyba6072f2019-04-18 07:37:52 -070067import android.util.TimeUtils;
Yu-Han Yanga1862b52018-02-20 17:05:59 -080068
Anil Admal032aa812019-03-06 19:23:25 -080069import com.android.internal.annotations.GuardedBy;
Sasha Kuznetsovb9f26b42019-10-03 17:30:46 -070070import com.android.internal.annotations.VisibleForTesting;
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;
Muhammad Qureshi6f207102020-01-28 10:37:41 -080077import com.android.internal.util.FrameworkStatsLog;
Kweku Adams810c77d2019-08-28 07:45:00 -070078import com.android.server.DeviceIdleInternal;
Soonil Nagarkarb6375a42020-01-29 15:23:06 -080079import com.android.server.FgThread;
Kweku Adams810c77d2019-08-28 07:45:00 -070080import com.android.server.LocalServices;
Sasha Kuznetsov94bb0092020-03-26 12:08:17 -070081import com.android.server.location.AbstractLocationProvider;
82import com.android.server.location.gnss.NtpTimeHelper.InjectNtpTimeCallback;
83import com.android.server.location.gnss.GnssSatelliteBlacklistHelper.GnssSatelliteBlacklistCallback;
Yu-Han Yang66c7ea92018-03-11 17:17:15 -070084
Nick Pelly6fa9ad42012-07-16 12:18:23 -070085import java.io.FileDescriptor;
Nick Pelly6fa9ad42012-07-16 12:18:23 -070086import java.io.PrintWriter;
Soonil Nagarkar1575a042018-10-24 17:54:54 -070087import java.lang.annotation.ElementType;
88import java.lang.annotation.Retention;
89import java.lang.annotation.RetentionPolicy;
90import java.lang.annotation.Target;
Wyatt Rileycf879db2017-01-12 13:57:38 -080091import java.util.ArrayList;
Andreas Gampee6748ce2015-12-11 18:00:38 -080092import java.util.Arrays;
Wyatt Rileycf879db2017-01-12 13:57:38 -080093import java.util.List;
Yu-Han Yange7baef32018-02-09 13:58:17 -080094
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080095/**
gomo4402af62017-01-11 13:20:13 -080096 * A GNSS implementation of LocationProvider used by LocationManager.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080097 *
98 * {@hide}
99 */
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700100public class GnssLocationProvider extends AbstractLocationProvider implements
101 InjectNtpTimeCallback,
102 GnssSatelliteBlacklistCallback {
103
104 /**
105 * Indicates that this method is a native entry point. Useful purely for IDEs which can
106 * understand entry points, and thus eliminate incorrect warnings about methods not used.
107 */
108 @Target(ElementType.METHOD)
109 @Retention(RetentionPolicy.SOURCE)
110 private @interface NativeEntryPoint {
111 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800112
Lifu Tang30f95a72016-01-07 23:20:38 -0800113 private static final String TAG = "GnssLocationProvider";
Mike Lockwood29c84342009-05-06 14:01:15 -0400114
Brian Muramatsu1715cb32012-08-08 17:32:21 -0700115 private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
116 private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400117
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700118 private static final ProviderProperties PROPERTIES = new ProviderProperties(
Soonil Nagarkar8df02f42020-01-08 13:23:26 -0800119 /* requiresNetwork = */false,
120 /* requiresSatellite = */true,
121 /* requiresCell = */false,
122 /* hasMonetaryCost = */false,
123 /* supportAltitude = */true,
124 /* supportsSpeed = */true,
125 /* supportsBearing = */true,
126 Criteria.POWER_HIGH,
127 Criteria.ACCURACY_FINE);
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700128
gomo4402af62017-01-11 13:20:13 -0800129 // these need to match GnssPositionMode enum in IGnss.hal
The Android Open Source Project10592532009-03-18 17:39:46 -0700130 private static final int GPS_POSITION_MODE_STANDALONE = 0;
131 private static final int GPS_POSITION_MODE_MS_BASED = 1;
132 private static final int GPS_POSITION_MODE_MS_ASSISTED = 2;
133
gomo4402af62017-01-11 13:20:13 -0800134 // these need to match GnssPositionRecurrence enum in IGnss.hal
Mike Lockwood04598b62010-04-14 17:17:24 -0400135 private static final int GPS_POSITION_RECURRENCE_PERIODIC = 0;
136 private static final int GPS_POSITION_RECURRENCE_SINGLE = 1;
137
gomo4402af62017-01-11 13:20:13 -0800138 // these need to match GnssStatusValue enum in IGnssCallback.hal
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800139 private static final int GPS_STATUS_NONE = 0;
140 private static final int GPS_STATUS_SESSION_BEGIN = 1;
141 private static final int GPS_STATUS_SESSION_END = 2;
142 private static final int GPS_STATUS_ENGINE_ON = 3;
143 private static final int GPS_STATUS_ENGINE_OFF = 4;
144
gomo4402af62017-01-11 13:20:13 -0800145 // these need to match GnssLocationFlags enum in types.hal
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800146 private static final int LOCATION_INVALID = 0;
147 private static final int LOCATION_HAS_LAT_LONG = 1;
148 private static final int LOCATION_HAS_ALTITUDE = 2;
149 private static final int LOCATION_HAS_SPEED = 4;
150 private static final int LOCATION_HAS_BEARING = 8;
gomo4402af62017-01-11 13:20:13 -0800151 private static final int LOCATION_HAS_HORIZONTAL_ACCURACY = 16;
152 private static final int LOCATION_HAS_VERTICAL_ACCURACY = 32;
153 private static final int LOCATION_HAS_SPEED_ACCURACY = 64;
154 private static final int LOCATION_HAS_BEARING_ACCURACY = 128;
Mike Lockwoode3635c92009-05-11 08:38:02 -0400155
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -0800156 // these need to match ElapsedRealtimeFlags enum in types.hal
157 private static final int ELAPSED_REALTIME_HAS_TIMESTAMP_NS = 1;
Pierre Fite-Georgel9e96c572019-02-25 16:12:53 -0800158 private static final int ELAPSED_REALTIME_HAS_TIME_UNCERTAINTY_NS = 2;
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -0800159
gomo4402af62017-01-11 13:20:13 -0800160 // IMPORTANT - the GPS_DELETE_* symbols here must match GnssAidingData enum in IGnss.hal
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800161 private static final int GPS_DELETE_EPHEMERIS = 0x0001;
162 private static final int GPS_DELETE_ALMANAC = 0x0002;
163 private static final int GPS_DELETE_POSITION = 0x0004;
164 private static final int GPS_DELETE_TIME = 0x0008;
165 private static final int GPS_DELETE_IONO = 0x0010;
166 private static final int GPS_DELETE_UTC = 0x0020;
167 private static final int GPS_DELETE_HEALTH = 0x0040;
168 private static final int GPS_DELETE_SVDIR = 0x0080;
169 private static final int GPS_DELETE_SVSTEER = 0x0100;
170 private static final int GPS_DELETE_SADATA = 0x0200;
171 private static final int GPS_DELETE_RTI = 0x0400;
172 private static final int GPS_DELETE_CELLDB_INFO = 0x8000;
173 private static final int GPS_DELETE_ALL = 0xFFFF;
174
gomo4402af62017-01-11 13:20:13 -0800175 // The GPS_CAPABILITY_* flags must match Capabilities enum in IGnssCallback.hal
Mike Lockwood04598b62010-04-14 17:17:24 -0400176 private static final int GPS_CAPABILITY_SCHEDULING = 0x0000001;
177 private static final int GPS_CAPABILITY_MSB = 0x0000002;
178 private static final int GPS_CAPABILITY_MSA = 0x0000004;
179 private static final int GPS_CAPABILITY_SINGLE_SHOT = 0x0000008;
Mike Lockwood9b9fb5c2011-06-29 15:09:40 -0400180 private static final int GPS_CAPABILITY_ON_DEMAND_TIME = 0x0000010;
Anil Admalefd9dc62019-03-12 17:39:20 -0700181 public static final int GPS_CAPABILITY_GEOFENCING = 0x0000020;
gomo226b7b72018-12-12 16:49:39 -0800182 public static final int GPS_CAPABILITY_MEASUREMENTS = 0x0000040;
Anil Admalefd9dc62019-03-12 17:39:20 -0700183 public static final int GPS_CAPABILITY_NAV_MESSAGES = 0x0000080;
Anil Admal62c42dc2019-04-03 15:39:22 -0700184 public static final int GPS_CAPABILITY_LOW_POWER_MODE = 0x0000100;
185 public static final int GPS_CAPABILITY_SATELLITE_BLACKLIST = 0x0000200;
186 public static final int GPS_CAPABILITY_MEASUREMENT_CORRECTIONS = 0x0000400;
Sasha Kuznetsova68a7a32020-02-11 06:00:10 +0000187 public static final int GPS_CAPABILITY_ANTENNA_INFO = 0x0000800;
Mike Lockwood04598b62010-04-14 17:17:24 -0400188
Tsuwei Chen462bcd82014-09-17 12:28:49 -0700189 // The AGPS SUPL mode
190 private static final int AGPS_SUPL_MODE_MSA = 0x02;
191 private static final int AGPS_SUPL_MODE_MSB = 0x01;
192
Kweku Adams810c77d2019-08-28 07:45:00 -0700193 private static final int UPDATE_LOW_POWER_MODE = 1;
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700194 private static final int SET_REQUEST = 3;
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400195 private static final int INJECT_NTP_TIME = 5;
Kevin Tang8c6ac672019-03-22 12:31:01 -0700196 // PSDS stands for Predicted Satellite Data Service
197 private static final int DOWNLOAD_PSDS_DATA = 6;
Kevin Tang8c6ac672019-03-22 12:31:01 -0700198 private static final int DOWNLOAD_PSDS_DATA_FINISHED = 11;
destradaafb23c672015-04-16 14:01:27 -0700199 private static final int INITIALIZE_HANDLER = 13;
Yu-Han Yange7baef32018-02-09 13:58:17 -0800200 private static final int REQUEST_LOCATION = 16;
Wyatt Riley26465d22018-02-12 13:44:24 -0800201 private static final int REPORT_LOCATION = 17; // HAL reports location
202 private static final int REPORT_SV_STATUS = 18; // HAL reports SV status
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400203
Miguel Torroja1e84da82010-07-27 07:02:24 +0200204 // Request setid
205 private static final int AGPS_RIL_REQUEST_SETID_IMSI = 1;
206 private static final int AGPS_RIL_REQUEST_SETID_MSISDN = 2;
207
Miguel Torroja1e84da82010-07-27 07:02:24 +0200208 // ref. location info
209 private static final int AGPS_REF_LOCATION_TYPE_GSM_CELLID = 1;
210 private static final int AGPS_REF_LOCATION_TYPE_UMTS_CELLID = 2;
Miguel Torroja1e84da82010-07-27 07:02:24 +0200211
212 // set id info
213 private static final int AGPS_SETID_TYPE_NONE = 0;
214 private static final int AGPS_SETID_TYPE_IMSI = 1;
215 private static final int AGPS_SETID_TYPE_MSISDN = 2;
216
gomo48f1a642017-11-10 20:35:46 -0800217 private static final int GPS_GEOFENCE_UNAVAILABLE = 1 << 0L;
218 private static final int GPS_GEOFENCE_AVAILABLE = 1 << 1L;
destradaa0682809a2013-08-12 18:50:30 -0700219
gomo4402af62017-01-11 13:20:13 -0800220 // GPS Geofence errors. Should match GeofenceStatus enum in IGnssGeofenceCallback.hal.
destradaa0682809a2013-08-12 18:50:30 -0700221 private static final int GPS_GEOFENCE_OPERATION_SUCCESS = 0;
222 private static final int GPS_GEOFENCE_ERROR_TOO_MANY_GEOFENCES = 100;
gomo48f1a642017-11-10 20:35:46 -0800223 private static final int GPS_GEOFENCE_ERROR_ID_EXISTS = -101;
destradaa0682809a2013-08-12 18:50:30 -0700224 private static final int GPS_GEOFENCE_ERROR_ID_UNKNOWN = -102;
225 private static final int GPS_GEOFENCE_ERROR_INVALID_TRANSITION = -103;
226 private static final int GPS_GEOFENCE_ERROR_GENERIC = -149;
227
Tsuwei Chen678c13c2014-09-22 17:48:41 -0700228 // TCP/IP constants.
229 // Valid TCP/UDP port range is (0, 65535].
230 private static final int TCP_MIN_PORT = 0;
231 private static final int TCP_MAX_PORT = 0xffff;
232
Yu-Han Yange7baef32018-02-09 13:58:17 -0800233 // 1 second, or 1 Hz frequency.
234 private static final long LOCATION_UPDATE_MIN_TIME_INTERVAL_MILLIS = 1000;
Yu-Han Yang639f7592018-06-07 11:58:52 -0700235 // Default update duration in milliseconds for REQUEST_LOCATION.
Yu-Han Yang9e2a8232018-06-14 12:10:08 -0700236 private static final long LOCATION_UPDATE_DURATION_MILLIS = 10 * 1000;
Anil Admalb1c6c0d2019-06-20 12:00:16 -0700237 // Update duration extension multiplier for emergency REQUEST_LOCATION.
238 private static final int EMERGENCY_LOCATION_UPDATE_DURATION_MULTIPLIER = 3;
Yu-Han Yange7baef32018-02-09 13:58:17 -0800239
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700240 /** simpler wrapper for ProviderRequest + Worksource */
241 private static class GpsRequest {
242 public ProviderRequest request;
243 public WorkSource source;
gomo48f1a642017-11-10 20:35:46 -0800244
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700245 public GpsRequest(ProviderRequest request, WorkSource source) {
246 this.request = request;
247 this.source = source;
248 }
249 }
250
Wyatt Riley26465d22018-02-12 13:44:24 -0800251 // Threadsafe class to hold stats reported in the Extras Bundle
Wyatt Rileyc7067412018-02-07 15:50:35 -0800252 private static class LocationExtras {
253 private int mSvCount;
254 private int mMeanCn0;
255 private int mMaxCn0;
256 private final Bundle mBundle;
257
258 public LocationExtras() {
259 mBundle = new Bundle();
260 }
261
262 public void set(int svCount, int meanCn0, int maxCn0) {
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700263 synchronized (this) {
Wyatt Riley26465d22018-02-12 13:44:24 -0800264 mSvCount = svCount;
265 mMeanCn0 = meanCn0;
266 mMaxCn0 = maxCn0;
267 }
Wyatt Rileyc7067412018-02-07 15:50:35 -0800268 setBundle(mBundle);
269 }
270
271 public void reset() {
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700272 set(0, 0, 0);
Wyatt Rileyc7067412018-02-07 15:50:35 -0800273 }
274
275 // Also used by outside methods to add to other bundles
276 public void setBundle(Bundle extras) {
277 if (extras != null) {
Wyatt Riley26465d22018-02-12 13:44:24 -0800278 synchronized (this) {
279 extras.putInt("satellites", mSvCount);
280 extras.putInt("meanCn0", mMeanCn0);
281 extras.putInt("maxCn0", mMaxCn0);
282 }
Wyatt Rileyc7067412018-02-07 15:50:35 -0800283 }
284 }
285
286 public Bundle getBundle() {
Wyatt Riley26465d22018-02-12 13:44:24 -0800287 synchronized (this) {
288 return new Bundle(mBundle);
289 }
Wyatt Rileyc7067412018-02-07 15:50:35 -0800290 }
291 }
292
Yu-Han Yang66c7ea92018-03-11 17:17:15 -0700293 private final Object mLock = new Object();
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700294
Mike Lockwood0632ca72009-05-14 15:51:03 -0400295 // stop trying if we do not receive a fix within 60 seconds
Mike Lockwood04598b62010-04-14 17:17:24 -0400296 private static final int NO_FIX_TIMEOUT = 60 * 1000;
Mike Lockwood0632ca72009-05-14 15:51:03 -0400297
Nick Pellyb041f232012-05-07 17:12:25 -0700298 // if the fix interval is below this we leave GPS on,
299 // if above then we cycle the GPS driver.
300 // Typical hot TTTF is ~5 seconds, so 10 seconds seems sane.
301 private static final int GPS_POLLING_THRESHOLD_INTERVAL = 10 * 1000;
302
Kevin Tang8c6ac672019-03-22 12:31:01 -0700303 // how long to wait if we have a network error in NTP or PSDS downloading
Wei Liu6f6326b2015-06-24 23:47:50 -0700304 // the initial value of the exponential backoff
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700305 // current setting - 5 minutes
gomo48f1a642017-11-10 20:35:46 -0800306 private static final long RETRY_INTERVAL = 5 * 60 * 1000;
Kevin Tang8c6ac672019-03-22 12:31:01 -0700307 // how long to wait if we have a network error in NTP or PSDS downloading
Wei Liu6f6326b2015-06-24 23:47:50 -0700308 // the max value of the exponential backoff
309 // current setting - 4 hours
gomo48f1a642017-11-10 20:35:46 -0800310 private static final long MAX_RETRY_INTERVAL = 4 * 60 * 60 * 1000;
Wei Liu6f6326b2015-06-24 23:47:50 -0700311
Kevin Tang8c6ac672019-03-22 12:31:01 -0700312 // Timeout when holding wakelocks for downloading PSDS data.
313 private static final long DOWNLOAD_PSDS_DATA_TIMEOUT_MS = 60 * 1000;
Yu-Han Yang499a6ba2019-11-14 14:19:13 -0800314 private static final long WAKELOCK_TIMEOUT_MILLIS = 30 * 1000;
Wei Wangc5706f62017-04-18 11:26:26 -0700315
Kevin Tang8c6ac672019-03-22 12:31:01 -0700316 private final ExponentialBackOff mPsdsBackOff = new ExponentialBackOff(RETRY_INTERVAL,
Yu-Han Yanga1862b52018-02-20 17:05:59 -0800317 MAX_RETRY_INTERVAL);
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700318
Sasha Kuznetsovb9f26b42019-10-03 17:30:46 -0700319 private static boolean sIsInitialized = false;
320 private static boolean sStaticTestOverride = false;
321
Yu-Han Yang76f99952019-05-04 17:45:44 -0700322 // True if we are enabled
323 @GuardedBy("mLock")
324 private boolean mGpsEnabled;
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700325
Soonil Nagarkar35c3b912019-01-31 10:31:24 -0800326 private boolean mShutdown;
327
Kevin Tang8c6ac672019-03-22 12:31:01 -0700328 // states for injecting ntp and downloading psds data
Kevin Tang40e1baf2012-01-10 14:32:44 -0800329 private static final int STATE_PENDING_NETWORK = 0;
330 private static final int STATE_DOWNLOADING = 1;
331 private static final int STATE_IDLE = 2;
332
Kevin Tang8c6ac672019-03-22 12:31:01 -0700333 // flags to trigger NTP or PSDS data download when network becomes available
334 // initialized to true so we do NTP and PSDS when the network comes up after booting
335 private int mDownloadPsdsDataPending = STATE_PENDING_NETWORK;
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400336
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800337 // true if GPS is navigating
338 private boolean mNavigating;
Mike Lockwoodcf1d8cb2010-01-20 10:14:54 -0500339
Mike Lockwood04598b62010-04-14 17:17:24 -0400340 // requested frequency of fixes, in milliseconds
341 private int mFixInterval = 1000;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800342
gomo48f1a642017-11-10 20:35:46 -0800343 // true if low power mode for the GNSS chipset is part of the latest request.
344 private boolean mLowPowerMode = false;
345
WyattRileyba6072f2019-04-18 07:37:52 -0700346 // 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 -0800347 private boolean mStarted;
348
WyattRileyba6072f2019-04-18 07:37:52 -0700349 // for logging of latest change, and warning of ongoing location after a stop
350 private long mStartedChangedElapsedRealtime;
351
352 // threshold for delay in GNSS engine turning off before warning & error
353 private static final long LOCATION_OFF_DELAY_THRESHOLD_WARN_MILLIS = 2 * 1000;
354 private static final long LOCATION_OFF_DELAY_THRESHOLD_ERROR_MILLIS = 15 * 1000;
355
Anil Admal312fddb2019-03-25 12:15:43 -0700356 // capabilities reported through the top level IGnssCallback.hal
357 private volatile int mTopHalCapabilities;
Mike Lockwood04598b62010-04-14 17:17:24 -0400358
Kevin Tang8c6ac672019-03-22 12:31:01 -0700359 // true if PSDS is supported
360 private boolean mSupportsPsds;
Mike Lockwood1a1cd3a2010-08-17 07:42:54 -0400361
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800362 // for calculating time to first fix
363 private long mFixRequestTime = 0;
364 // time to first fix for most recent session
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700365 private int mTimeToFirstFix = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800366 // time we received our last fix
367 private long mLastFixTime;
368
Mike Lockwood04598b62010-04-14 17:17:24 -0400369 private int mPositionMode;
Yu-Han Yangc8b9ff72018-04-17 00:47:24 -0700370 private GnssPositionMode mLastPositionMode;
Mike Lockwood04598b62010-04-14 17:17:24 -0400371
David Christied4edf4c2014-08-12 15:22:27 -0700372 // Current request from underlying location clients.
Soonil Nagarkar35c3b912019-01-31 10:31:24 -0800373 private ProviderRequest mProviderRequest;
Narayan Kamath32684dd2018-01-08 17:32:51 +0000374 // The WorkSource associated with the most recent client request (i.e, most recent call to
375 // setRequest).
David Christied4edf4c2014-08-12 15:22:27 -0700376 private WorkSource mWorkSource = null;
WyattRileyb2446072019-03-01 07:41:49 -0800377 // True if gps should be disabled because of PowerManager controls
378 private boolean mDisableGpsForPowerManager = false;
David Christied4edf4c2014-08-12 15:22:27 -0700379
destradaafb23c672015-04-16 14:01:27 -0700380 /**
Kweku Adams810c77d2019-08-28 07:45:00 -0700381 * True if the device idle controller has determined that the device is stationary. This is only
382 * updated when the device enters idle mode.
383 */
384 private volatile boolean mIsDeviceStationary = false;
385
386 /**
destradaafb23c672015-04-16 14:01:27 -0700387 * Properties loaded from PROPERTIES_FILE.
388 * It must be accessed only inside {@link #mHandler}.
389 */
Anil Admald71cf142018-12-21 14:59:36 -0800390 private GnssConfiguration mGnssConfiguration;
destradaafb23c672015-04-16 14:01:27 -0700391
Mike Lockwood734d6032009-07-28 18:30:25 -0700392 private String mSuplServerHost;
Tsuwei Chen678c13c2014-09-22 17:48:41 -0700393 private int mSuplServerPort = TCP_MIN_PORT;
Mike Lockwood734d6032009-07-28 18:30:25 -0700394 private String mC2KServerHost;
395 private int mC2KServerPort;
Tsuwei Chen3324e952014-09-07 01:30:42 -0700396 private boolean mSuplEsEnabled = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800397
Anil Admal94ec76a2019-01-15 09:42:01 -0800398 private final Looper mLooper;
Wyatt Rileyc7067412018-02-07 15:50:35 -0800399 private final LocationExtras mLocationExtras = new LocationExtras();
Anil Admal75b9fd62018-11-28 11:22:50 -0800400 private final GnssStatusListenerHelper mGnssStatusListenerHelper;
Lifu Tang818aa2c2016-02-01 01:52:00 -0800401 private final GnssMeasurementsProvider mGnssMeasurementsProvider;
Anil Admalefd9dc62019-03-12 17:39:20 -0700402 private final GnssMeasurementCorrectionsProvider mGnssMeasurementCorrectionsProvider;
Sasha Kuznetsova68a7a32020-02-11 06:00:10 +0000403 private final GnssAntennaInfoProvider mGnssAntennaInfoProvider;
Lifu Tang818aa2c2016-02-01 01:52:00 -0800404 private final GnssNavigationMessageProvider mGnssNavigationMessageProvider;
Yu-Han Yang07561382018-02-21 13:08:37 -0800405 private final LocationChangeListener mNetworkLocationListener = new NetworkLocationListener();
406 private final LocationChangeListener mFusedLocationListener = new FusedLocationListener();
Yu-Han Yanga1862b52018-02-20 17:05:59 -0800407 private final NtpTimeHelper mNtpTimeHelper;
Yu-Han Yang3557cc72018-03-21 12:48:36 -0700408 private final GnssBatchingProvider mGnssBatchingProvider;
Yu-Han Yang890ca8b2018-04-16 22:11:31 -0700409 private final GnssGeofenceProvider mGnssGeofenceProvider;
Anil Admal312fddb2019-03-25 12:15:43 -0700410 private final GnssCapabilitiesProvider mGnssCapabilitiesProvider;
411
Anil Admal316f9482019-02-12 18:57:18 -0800412 // Available only on GNSS HAL 2.0 implementations and later.
Anil Admal94ec76a2019-01-15 09:42:01 -0800413 private GnssVisibilityControl mGnssVisibilityControl;
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400414
Soonil Nagarkar17d8c832020-01-29 18:02:53 -0800415 private final Context mContext;
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400416 private Handler mHandler;
The Android Open Source Project10592532009-03-18 17:39:46 -0700417
Anil Admal50ba15e2018-11-01 16:42:42 -0700418 private final GnssNetworkConnectivityHandler mNetworkConnectivityHandler;
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700419 private final GpsNetInitiatedHandler mNIHandler;
Mike Lockwood2f82c4e2009-04-17 08:24:10 -0400420
Mike Lockwood0528b9b2009-05-07 10:12:54 -0400421 // Wakelocks
Lifu Tang30f95a72016-01-07 23:20:38 -0800422 private final static String WAKELOCK_KEY = "GnssLocationProvider";
Mike Lockwood0528b9b2009-05-07 10:12:54 -0400423 private final PowerManager.WakeLock mWakeLock;
Kevin Tang8c6ac672019-03-22 12:31:01 -0700424 private static final String DOWNLOAD_EXTRA_WAKELOCK_KEY = "GnssLocationProviderPsdsDownload";
Yu-Han Yang76f99952019-05-04 17:45:44 -0700425 @GuardedBy("mLock")
Kevin Tang8c6ac672019-03-22 12:31:01 -0700426 private final PowerManager.WakeLock mDownloadPsdsWakeLock;
Mike Lockwood0528b9b2009-05-07 10:12:54 -0400427
Mike Lockwood29c84342009-05-06 14:01:15 -0400428 // Alarms
429 private final static String ALARM_WAKEUP = "com.android.internal.location.ALARM_WAKEUP";
Mike Lockwood0632ca72009-05-14 15:51:03 -0400430 private final static String ALARM_TIMEOUT = "com.android.internal.location.ALARM_TIMEOUT";
Tsuwei Chen52617bb2014-08-25 11:49:11 -0700431
David Christied4edf4c2014-08-12 15:22:27 -0700432 private final PowerManager mPowerManager;
Mike Lockwood29c84342009-05-06 14:01:15 -0400433 private final AlarmManager mAlarmManager;
434 private final PendingIntent mWakeupIntent;
Mike Lockwood0632ca72009-05-14 15:51:03 -0400435 private final PendingIntent mTimeoutIntent;
Mike Lockwood29c84342009-05-06 14:01:15 -0400436
Svet Ganovf7b47252018-02-26 11:11:27 -0800437 private final AppOpsManager mAppOps;
Mike Lockwood2f82c4e2009-04-17 08:24:10 -0400438 private final IBatteryStats mBatteryStats;
The Android Open Source Project10592532009-03-18 17:39:46 -0700439
Narayan Kamath32684dd2018-01-08 17:32:51 +0000440 // Current list of underlying location clients.
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700441 // only modified on handler thread
Dianne Hackborn002a54e2013-01-10 17:34:55 -0800442 private WorkSource mClientSource = new WorkSource();
Mike Lockwoodf1218be2010-01-29 09:20:06 -0500443
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -0700444 private GeofenceHardwareImpl mGeofenceHardwareImpl;
Wyatt Rileyd87cf912017-12-05 09:31:52 -0800445
446 // Volatile for simple inter-thread sync on these values.
447 private volatile int mHardwareYear = 0;
Wyatt Riley49097c02018-03-15 09:14:43 -0700448 private volatile String mHardwareModelName;
Lifu Tang82f893d2016-01-21 18:15:33 -0800449
Wyatt Riley5d5bac82016-11-01 07:05:16 -0700450 // Set lower than the current ITAR limit of 600m/s to allow this to trigger even if GPS HAL
451 // stops output right at 600m/s, depriving this of the information of a device that reaches
452 // greater than 600m/s, and higher than the speed of sound to avoid impacting most use cases.
453 private static final float ITAR_SPEED_LIMIT_METERS_PER_SECOND = 400.0F;
Wyatt Riley042c48f2017-10-06 14:59:25 -0700454
Wyatt Riley042c48f2017-10-06 14:59:25 -0700455 private volatile boolean mItarSpeedLimitExceeded = false;
Wyatt Riley5d5bac82016-11-01 07:05:16 -0700456
Siddharth Raybb608c82017-03-16 11:33:34 -0700457 // GNSS Metrics
458 private GnssMetrics mGnssMetrics;
459
Anil Admal75b9fd62018-11-28 11:22:50 -0800460 public GnssStatusListenerHelper getGnssStatusProvider() {
461 return mGnssStatusListenerHelper;
Mike Lockwood15e3d0f2009-05-01 07:53:28 -0400462 }
463
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -0700464 public IGpsGeofenceHardware getGpsGeofenceProxy() {
Yu-Han Yang890ca8b2018-04-16 22:11:31 -0700465 return mGnssGeofenceProvider;
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -0700466 }
467
Lifu Tang818aa2c2016-02-01 01:52:00 -0800468 public GnssMeasurementsProvider getGnssMeasurementsProvider() {
469 return mGnssMeasurementsProvider;
destradaaea8a8a62014-06-23 18:19:03 -0700470 }
471
Anil Admalefd9dc62019-03-12 17:39:20 -0700472 public GnssMeasurementCorrectionsProvider getGnssMeasurementCorrectionsProvider() {
473 return mGnssMeasurementCorrectionsProvider;
474 }
475
Sasha Kuznetsova68a7a32020-02-11 06:00:10 +0000476 public GnssAntennaInfoProvider getGnssAntennaInfoProvider() {
477 return mGnssAntennaInfoProvider;
478 }
479
Lifu Tang818aa2c2016-02-01 01:52:00 -0800480 public GnssNavigationMessageProvider getGnssNavigationMessageProvider() {
481 return mGnssNavigationMessageProvider;
destradaa4b3e3932014-07-21 18:01:47 -0700482 }
Kweku Adams810c77d2019-08-28 07:45:00 -0700483
484 private final DeviceIdleInternal.StationaryListener mDeviceIdleStationaryListener =
485 isStationary -> {
486 mIsDeviceStationary = isStationary;
487 // Call updateLowPowerMode on handler thread so it's always called from the same
488 // thread.
489 mHandler.sendEmptyMessage(UPDATE_LOW_POWER_MODE);
490 };
491
Tsuwei Chen52617bb2014-08-25 11:49:11 -0700492 private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
gomo48f1a642017-11-10 20:35:46 -0800493 @Override
494 public void onReceive(Context context, Intent intent) {
The Android Open Source Project10592532009-03-18 17:39:46 -0700495 String action = intent.getAction();
Tsuwei Chen48d37f92014-09-05 15:15:34 -0700496 if (DEBUG) Log.d(TAG, "receive broadcast intent, action: " + action);
destradaaee9fd342015-08-31 13:31:17 -0700497 if (action == null) {
498 return;
499 }
500
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700501 switch (action) {
502 case ALARM_WAKEUP:
Yu-Han Yang6a5f0b72019-01-24 18:34:28 -0800503 startNavigating();
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700504 break;
505 case ALARM_TIMEOUT:
506 hibernate();
507 break;
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700508 case PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED:
Kweku Adams810c77d2019-08-28 07:45:00 -0700509 DeviceIdleInternal deviceIdleService = LocalServices.getService(
510 DeviceIdleInternal.class);
511 if (mPowerManager.isDeviceIdleMode()) {
512 deviceIdleService.registerStationaryListener(mDeviceIdleStationaryListener);
513 } else {
514 deviceIdleService.unregisterStationaryListener(
515 mDeviceIdleStationaryListener);
516 }
517 // Intentional fall-through.
518 case PowerManager.ACTION_POWER_SAVE_MODE_CHANGED:
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700519 case Intent.ACTION_SCREEN_OFF:
520 case Intent.ACTION_SCREEN_ON:
Kweku Adams810c77d2019-08-28 07:45:00 -0700521 // Call updateLowPowerMode on handler thread so it's always called from the
522 // same thread.
523 mHandler.sendEmptyMessage(UPDATE_LOW_POWER_MODE);
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700524 break;
Meng Wang19b214d2018-11-07 12:14:39 -0800525 case CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED:
Jayachandran C041e7692019-12-20 16:20:02 -0800526 case TelephonyManager.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED:
Soonil Nagarkarfc9c7f82019-07-16 12:07:57 -0700527 subscriptionOrCarrierConfigChanged();
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700528 break;
David Christied4edf4c2014-08-12 15:22:27 -0700529 }
The Android Open Source Project10592532009-03-18 17:39:46 -0700530 }
Mike Lockwood29c84342009-05-06 14:01:15 -0400531 };
The Android Open Source Project10592532009-03-18 17:39:46 -0700532
Yu-Han Yang66c7ea92018-03-11 17:17:15 -0700533 /**
534 * Implements {@link GnssSatelliteBlacklistCallback#onUpdateSatelliteBlacklist}.
535 */
536 @Override
537 public void onUpdateSatelliteBlacklist(int[] constellations, int[] svids) {
Anil Admald71cf142018-12-21 14:59:36 -0800538 mHandler.post(() -> mGnssConfiguration.setSatelliteBlacklist(constellations, svids));
Yu-Han Yang284234e2019-03-28 19:35:57 -0700539 mGnssMetrics.resetConstellationTypes();
Yu-Han Yang66c7ea92018-03-11 17:17:15 -0700540 }
541
Soonil Nagarkarfc9c7f82019-07-16 12:07:57 -0700542 private void subscriptionOrCarrierConfigChanged() {
Joe Onorato0c484102016-02-01 18:04:24 -0800543 if (DEBUG) Log.d(TAG, "received SIM related action: ");
Wink Savillea374c3d2014-11-11 11:48:04 -0800544 TelephonyManager phone = (TelephonyManager)
545 mContext.getSystemService(Context.TELEPHONY_SERVICE);
Ecco Park4fa1ab72016-10-24 13:04:52 -0700546 CarrierConfigManager configManager = (CarrierConfigManager)
547 mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE);
Anil Admale1539e82019-05-09 15:05:04 -0700548 int ddSubId = SubscriptionManager.getDefaultDataSubscriptionId();
zoey chen4841a272019-12-03 20:07:18 +0800549 if (SubscriptionManager.isValidSubscriptionId(ddSubId)) {
550 phone = phone.createForSubscriptionId(ddSubId);
551 }
552 String mccMnc = phone.getSimOperator();
Ecco Park4fa1ab72016-10-24 13:04:52 -0700553 boolean isKeepLppProfile = false;
Wink Savillea374c3d2014-11-11 11:48:04 -0800554 if (!TextUtils.isEmpty(mccMnc)) {
Joe Onorato0c484102016-02-01 18:04:24 -0800555 if (DEBUG) Log.d(TAG, "SIM MCC/MNC is available: " + mccMnc);
Yu-Han Yang76f99952019-05-04 17:45:44 -0700556 if (configManager != null) {
Anil Admale1539e82019-05-09 15:05:04 -0700557 PersistableBundle b = SubscriptionManager.isValidSubscriptionId(ddSubId)
558 ? configManager.getConfigForSubId(ddSubId) : null;
Yu-Han Yang76f99952019-05-04 17:45:44 -0700559 if (b != null) {
560 isKeepLppProfile =
561 b.getBoolean(CarrierConfigManager.Gps.KEY_PERSIST_LPP_MODE_BOOL);
Ecco Park4fa1ab72016-10-24 13:04:52 -0700562 }
Wink Savillea374c3d2014-11-11 11:48:04 -0800563 }
Yu-Han Yang76f99952019-05-04 17:45:44 -0700564 if (isKeepLppProfile) {
565 // load current properties for the carrier
566 mGnssConfiguration.loadPropertiesFromCarrierConfig();
567 String lpp_profile = mGnssConfiguration.getLppProfile();
568 // set the persist property LPP_PROFILE for the value
569 if (lpp_profile != null) {
570 SystemProperties.set(GnssConfiguration.LPP_PROFILE, lpp_profile);
571 }
572 } else {
573 // reset the persist property
574 SystemProperties.set(GnssConfiguration.LPP_PROFILE, "");
575 }
576 reloadGpsProperties();
Wink Savillea374c3d2014-11-11 11:48:04 -0800577 } else {
Joe Onorato0c484102016-02-01 18:04:24 -0800578 if (DEBUG) Log.d(TAG, "SIM MCC/MNC is still not available");
Wink Savillea374c3d2014-11-11 11:48:04 -0800579 }
580 }
581
David Christied4edf4c2014-08-12 15:22:27 -0700582 private void updateLowPowerMode() {
Kweku Adams810c77d2019-08-28 07:45:00 -0700583 // Disable GPS if we are in device idle mode and the device is stationary.
584 boolean disableGpsForPowerManager = mPowerManager.isDeviceIdleMode() && mIsDeviceStationary;
585 final PowerSaveState result = mPowerManager.getPowerSaveState(ServiceType.LOCATION);
Kweku Adams731a1032019-02-04 14:05:41 -0800586 switch (result.locationMode) {
Makoto Onuki57f0f552017-12-11 12:22:18 -0800587 case PowerManager.LOCATION_MODE_GPS_DISABLED_WHEN_SCREEN_OFF:
Kweku Adams5e0052b2019-02-22 15:17:52 -0800588 case PowerManager.LOCATION_MODE_ALL_DISABLED_WHEN_SCREEN_OFF:
Adam Lesinski87c17df2015-05-27 13:24:13 -0700589 // If we are in battery saver mode and the screen is off, disable GPS.
WyattRileyb2446072019-03-01 07:41:49 -0800590 disableGpsForPowerManager |=
591 result.batterySaverEnabled && !mPowerManager.isInteractive();
David Christied4edf4c2014-08-12 15:22:27 -0700592 break;
David Christied4edf4c2014-08-12 15:22:27 -0700593 }
WyattRileyb2446072019-03-01 07:41:49 -0800594 if (disableGpsForPowerManager != mDisableGpsForPowerManager) {
595 mDisableGpsForPowerManager = disableGpsForPowerManager;
Soonil Nagarkar35c3b912019-01-31 10:31:24 -0800596 updateEnabled();
David Christied4edf4c2014-08-12 15:22:27 -0700597 updateRequirements();
598 }
599 }
600
Sasha Kuznetsovb9f26b42019-10-03 17:30:46 -0700601 @VisibleForTesting
602 public static void setIsSupportedForTest(boolean override) {
603 sStaticTestOverride = override;
604 }
605
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800606 public static boolean isSupported() {
Sasha Kuznetsovb9f26b42019-10-03 17:30:46 -0700607 if (sStaticTestOverride) {
608 return true;
609 }
Sasha Kuznetsov24da7f92019-11-01 12:21:50 -0700610 ensureInitialized();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800611 return native_is_supported();
612 }
613
Sasha Kuznetsov24da7f92019-11-01 12:21:50 -0700614 private static synchronized void ensureInitialized() {
615 if (!sIsInitialized) {
616 class_init_native();
617 }
618 sIsInitialized = true;
619 }
620
Anil Admald71cf142018-12-21 14:59:36 -0800621 private void reloadGpsProperties() {
622 mGnssConfiguration.reloadGpsProperties();
623 setSuplHostPort();
Tsuwei Chen52617bb2014-08-25 11:49:11 -0700624 // TODO: we should get rid of C2K specific setting.
Anil Admald71cf142018-12-21 14:59:36 -0800625 mC2KServerHost = mGnssConfiguration.getC2KHost();
626 mC2KServerPort = mGnssConfiguration.getC2KPort(TCP_MIN_PORT);
627 mNIHandler.setEmergencyExtensionSeconds(mGnssConfiguration.getEsExtensionSec());
628 mSuplEsEnabled = mGnssConfiguration.getSuplEs(0) == 1;
Anil Admale1539e82019-05-09 15:05:04 -0700629 mNIHandler.setSuplEsEnabled(mSuplEsEnabled);
Anil Admal94ec76a2019-01-15 09:42:01 -0800630 if (mGnssVisibilityControl != null) {
Anil Admale1539e82019-05-09 15:05:04 -0700631 mGnssVisibilityControl.onConfigurationUpdated(mGnssConfiguration);
Anil Admal94ec76a2019-01-15 09:42:01 -0800632 }
Colin Cross7c030ed2014-01-28 09:33:53 -0800633 }
634
Soonil Nagarkarb6375a42020-01-29 15:23:06 -0800635 public GnssLocationProvider(Context context) {
Soonil Nagarkar17d8c832020-01-29 18:02:53 -0800636 super(FgThread.getExecutor(), context);
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700637
Sasha Kuznetsov24da7f92019-11-01 12:21:50 -0700638 ensureInitialized();
Sasha Kuznetsovb9f26b42019-10-03 17:30:46 -0700639
Soonil Nagarkar17d8c832020-01-29 18:02:53 -0800640 mContext = context;
Soonil Nagarkarb6375a42020-01-29 15:23:06 -0800641 mLooper = FgThread.getHandler().getLooper();
Mike Lockwood63598a02010-02-24 11:52:59 -0500642
Mike Lockwood0528b9b2009-05-07 10:12:54 -0400643 // Create a wake lock
David Christied4edf4c2014-08-12 15:22:27 -0700644 mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
645 mWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, WAKELOCK_KEY);
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700646 mWakeLock.setReferenceCounted(true);
Mike Lockwood0528b9b2009-05-07 10:12:54 -0400647
Kevin Tang8c6ac672019-03-22 12:31:01 -0700648 // Create a separate wake lock for psds downloader as it may be released due to timeout.
649 mDownloadPsdsWakeLock = mPowerManager.newWakeLock(
Wei Wangb71c0492017-05-01 20:24:19 -0700650 PowerManager.PARTIAL_WAKE_LOCK, DOWNLOAD_EXTRA_WAKELOCK_KEY);
Kevin Tang8c6ac672019-03-22 12:31:01 -0700651 mDownloadPsdsWakeLock.setReferenceCounted(true);
Wei Wangb71c0492017-05-01 20:24:19 -0700652
gomo48f1a642017-11-10 20:35:46 -0800653 mAlarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
Mike Lockwood29c84342009-05-06 14:01:15 -0400654 mWakeupIntent = PendingIntent.getBroadcast(mContext, 0, new Intent(ALARM_WAKEUP), 0);
Mike Lockwood0632ca72009-05-14 15:51:03 -0400655 mTimeoutIntent = PendingIntent.getBroadcast(mContext, 0, new Intent(ALARM_TIMEOUT), 0);
Mike Lockwood29c84342009-05-06 14:01:15 -0400656
Dianne Hackborna06de0f2012-12-11 16:34:47 -0800657 // App ops service to keep track of who is accessing the GPS
Svet Ganovf7b47252018-02-26 11:11:27 -0800658 mAppOps = mContext.getSystemService(AppOpsManager.class);
Dianne Hackborna06de0f2012-12-11 16:34:47 -0800659
Mike Lockwood2f82c4e2009-04-17 08:24:10 -0400660 // Battery statistics service to be notified when GPS turns on or off
Dianne Hackborn91268cf2013-06-13 19:06:50 -0700661 mBatteryStats = IBatteryStats.Stub.asInterface(ServiceManager.getService(
662 BatteryStats.SERVICE_NAME));
Mike Lockwood2f82c4e2009-04-17 08:24:10 -0400663
destradaafb23c672015-04-16 14:01:27 -0700664 // Construct internal handler
Soonil Nagarkar8df02f42020-01-08 13:23:26 -0800665 mHandler = new ProviderHandler(mLooper);
destradaafb23c672015-04-16 14:01:27 -0700666
667 // Load GPS configuration and register listeners in the background:
668 // some operations, such as opening files and registering broadcast receivers, can take a
669 // relative long time, so the ctor() is kept to create objects needed by this instance,
670 // while IO initialization and registration is delegated to our internal handler
671 // this approach is just fine because events are posted to our handler anyway
Anil Admald71cf142018-12-21 14:59:36 -0800672 mGnssConfiguration = new GnssConfiguration(mContext);
Anil Admal312fddb2019-03-25 12:15:43 -0700673 mGnssCapabilitiesProvider = new GnssCapabilitiesProvider();
WyattRileyd1309312019-02-28 12:11:45 -0800674 // Create a GPS net-initiated handler (also needed by handleInitialize)
Tsuwei Chen3324e952014-09-07 01:30:42 -0700675 mNIHandler = new GpsNetInitiatedHandler(context,
gomo48f1a642017-11-10 20:35:46 -0800676 mNetInitiatedListener,
677 mSuplEsEnabled);
Dante Russodffe0ce2020-02-25 11:01:00 +0800678 mNetworkConnectivityHandler = new GnssNetworkConnectivityHandler(context,
679 GnssLocationProvider.this::onNetworkAvailable, mLooper, mNIHandler);
680
WyattRileyd1309312019-02-28 12:11:45 -0800681 sendMessage(INITIALIZE_HANDLER, 0, null);
Tsuwei Chen3324e952014-09-07 01:30:42 -0700682
Anil Admal75b9fd62018-11-28 11:22:50 -0800683 mGnssStatusListenerHelper = new GnssStatusListenerHelper(mContext, mHandler) {
destradaa6568d702014-10-27 12:47:41 -0700684 @Override
685 protected boolean isAvailableInPlatform() {
destradaa13a60b02015-01-15 18:36:01 -0800686 return isSupported();
destradaa6568d702014-10-27 12:47:41 -0700687 }
688
689 @Override
690 protected boolean isGpsEnabled() {
Yu-Han Yang76f99952019-05-04 17:45:44 -0700691 return GnssLocationProvider.this.isGpsEnabled();
destradaa6568d702014-10-27 12:47:41 -0700692 }
693 };
694
Yu-Han Yang8de21502018-04-23 01:40:25 -0700695 mGnssMeasurementsProvider = new GnssMeasurementsProvider(mContext, mHandler) {
destradaa6568d702014-10-27 12:47:41 -0700696 @Override
697 protected boolean isGpsEnabled() {
Yu-Han Yang76f99952019-05-04 17:45:44 -0700698 return GnssLocationProvider.this.isGpsEnabled();
destradaa6568d702014-10-27 12:47:41 -0700699 }
700 };
701
Anil Admalefd9dc62019-03-12 17:39:20 -0700702 mGnssMeasurementCorrectionsProvider = new GnssMeasurementCorrectionsProvider(mHandler);
703
Sasha Kuznetsova68a7a32020-02-11 06:00:10 +0000704 mGnssAntennaInfoProvider = new GnssAntennaInfoProvider(mContext, mHandler) {
705 @Override
706 protected boolean isGpsEnabled() {
707 return GnssLocationProvider.this.isGpsEnabled();
708 }
709 };
710
Anil Admal75b9fd62018-11-28 11:22:50 -0800711 mGnssNavigationMessageProvider = new GnssNavigationMessageProvider(mContext, mHandler) {
destradaa6568d702014-10-27 12:47:41 -0700712 @Override
destradaa6568d702014-10-27 12:47:41 -0700713 protected boolean isGpsEnabled() {
Yu-Han Yang76f99952019-05-04 17:45:44 -0700714 return GnssLocationProvider.this.isGpsEnabled();
destradaa6568d702014-10-27 12:47:41 -0700715 }
716 };
Yu-Han Yanga1862b52018-02-20 17:05:59 -0800717
Blake Kragten6ce382a2020-01-16 20:20:46 -0800718 mGnssMetrics = new GnssMetrics(mContext, mBatteryStats);
Soonil Nagarkar8df02f42020-01-08 13:23:26 -0800719 mNtpTimeHelper = new NtpTimeHelper(mContext, mLooper, this);
Soonil Nagarkar35c3b912019-01-31 10:31:24 -0800720 GnssSatelliteBlacklistHelper gnssSatelliteBlacklistHelper =
721 new GnssSatelliteBlacklistHelper(mContext,
Soonil Nagarkar8df02f42020-01-08 13:23:26 -0800722 mLooper, this);
Soonil Nagarkar35c3b912019-01-31 10:31:24 -0800723 mHandler.post(gnssSatelliteBlacklistHelper::updateSatelliteBlacklist);
Yu-Han Yang3557cc72018-03-21 12:48:36 -0700724 mGnssBatchingProvider = new GnssBatchingProvider();
Yu-Han Yang6dc9f052018-12-04 17:11:24 -0800725 mGnssGeofenceProvider = new GnssGeofenceProvider();
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400726
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700727 mContext.registerReceiverAsUser(new BroadcastReceiver() {
728 @Override
729 public void onReceive(Context context, Intent intent) {
730 if (getSendingUserId() == UserHandle.USER_ALL) {
Soonil Nagarkar35c3b912019-01-31 10:31:24 -0800731 mShutdown = true;
732 updateEnabled();
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700733 }
734 }
Soonil Nagarkar35c3b912019-01-31 10:31:24 -0800735 }, UserHandle.ALL, new IntentFilter(Intent.ACTION_SHUTDOWN), null, mHandler);
736
737 mContext.getContentResolver().registerContentObserver(
738 Settings.Secure.getUriFor(Settings.Secure.LOCATION_MODE),
739 true,
740 new ContentObserver(mHandler) {
741 @Override
742 public void onChange(boolean selfChange) {
743 updateEnabled();
744 }
745 }, UserHandle.USER_ALL);
Mike Lockwoodd03ff942010-02-09 08:46:14 -0500746
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700747 setProperties(PROPERTIES);
Soonil Nagarkar980ce6a2020-01-23 18:06:31 -0800748 setAllowed(true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800749 }
750
Yu-Han Yanga1862b52018-02-20 17:05:59 -0800751 /**
752 * Implements {@link InjectNtpTimeCallback#injectTime}
753 */
754 @Override
755 public void injectTime(long time, long timeReference, int uncertainty) {
756 native_inject_time(time, timeReference, uncertainty);
757 }
758
Anil Admal50ba15e2018-11-01 16:42:42 -0700759 /**
760 * Implements {@link GnssNetworkConnectivityHandler.GnssNetworkListener#onNetworkAvailable()}
761 */
762 private void onNetworkAvailable() {
763 mNtpTimeHelper.onNetworkAvailable();
Kevin Tang8c6ac672019-03-22 12:31:01 -0700764 if (mDownloadPsdsDataPending == STATE_PENDING_NETWORK) {
765 if (mSupportsPsds) {
Anil Admal316f9482019-02-12 18:57:18 -0800766 // Download only if supported, (prevents an unnecessary on-boot download)
Kevin Tang8c6ac672019-03-22 12:31:01 -0700767 psdsDownloadRequest();
destradaaef752b62015-04-17 13:10:47 -0700768 }
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400769 }
770 }
Yu-Han Yang8de21502018-04-23 01:40:25 -0700771
Yu-Han Yang53f4d6d2019-02-13 21:47:41 -0800772 private void handleRequestLocation(boolean independentFromGnss, boolean isUserEmergency) {
Yu-Han Yange7baef32018-02-09 13:58:17 -0800773 if (isRequestLocationRateLimited()) {
774 if (DEBUG) {
775 Log.d(TAG, "RequestLocation is denied due to too frequent requests.");
776 }
777 return;
778 }
Yu-Han Yang74041ff2018-04-06 15:57:31 -0700779 ContentResolver resolver = mContext.getContentResolver();
780 long durationMillis = Settings.Global.getLong(
781 resolver,
782 Settings.Global.GNSS_HAL_LOCATION_REQUEST_DURATION_MILLIS,
783 LOCATION_UPDATE_DURATION_MILLIS);
784 if (durationMillis == 0) {
785 Log.i(TAG, "GNSS HAL location request is disabled by Settings.");
786 return;
787 }
Yu-Han Yange7baef32018-02-09 13:58:17 -0800788
789 LocationManager locationManager = (LocationManager) mContext.getSystemService(
790 Context.LOCATION_SERVICE);
Yu-Han Yang07561382018-02-21 13:08:37 -0800791 String provider;
792 LocationChangeListener locationListener;
Anil Admalb1c6c0d2019-06-20 12:00:16 -0700793 LocationRequest locationRequest = new LocationRequest()
794 .setInterval(LOCATION_UPDATE_MIN_TIME_INTERVAL_MILLIS)
795 .setFastestInterval(LOCATION_UPDATE_MIN_TIME_INTERVAL_MILLIS);
Yu-Han Yange7baef32018-02-09 13:58:17 -0800796
797 if (independentFromGnss) {
798 // For fast GNSS TTFF
Yu-Han Yang07561382018-02-21 13:08:37 -0800799 provider = LocationManager.NETWORK_PROVIDER;
800 locationListener = mNetworkLocationListener;
Anil Admalb1c6c0d2019-06-20 12:00:16 -0700801 locationRequest.setQuality(LocationRequest.POWER_LOW);
Yu-Han Yange7baef32018-02-09 13:58:17 -0800802 } else {
803 // For Device-Based Hybrid (E911)
Yu-Han Yang07561382018-02-21 13:08:37 -0800804 provider = LocationManager.FUSED_PROVIDER;
805 locationListener = mFusedLocationListener;
Anil Admalb1c6c0d2019-06-20 12:00:16 -0700806 locationRequest.setQuality(LocationRequest.ACCURACY_FINE);
807 }
808
809 locationRequest.setProvider(provider);
810
Yu-Han Yang97e162d2020-02-26 12:46:01 -0800811 // Ignore location settings if in emergency mode. This is only allowed for
Yu-Han Yang311a9092020-04-07 15:20:59 -0700812 // isUserEmergency request (introduced in HAL v2.0), or HAL v1.1.
Yu-Han Yang97e162d2020-02-26 12:46:01 -0800813 if (mNIHandler.getInEmergency()) {
814 GnssConfiguration.HalInterfaceVersion halVersion =
815 mGnssConfiguration.getHalInterfaceVersion();
Yu-Han Yang311a9092020-04-07 15:20:59 -0700816 if (isUserEmergency || halVersion.mMajor < 2) {
Yu-Han Yang97e162d2020-02-26 12:46:01 -0800817 locationRequest.setLocationSettingsIgnored(true);
818 durationMillis *= EMERGENCY_LOCATION_UPDATE_DURATION_MULTIPLIER;
819 }
Yu-Han Yange7baef32018-02-09 13:58:17 -0800820 }
Yu-Han Yang07561382018-02-21 13:08:37 -0800821
822 Log.i(TAG,
Yu-Han Yang74041ff2018-04-06 15:57:31 -0700823 String.format(
824 "GNSS HAL Requesting location updates from %s provider for %d millis.",
825 provider, durationMillis));
Yu-Han Yang53f4d6d2019-02-13 21:47:41 -0800826
Yu-Han Yange684dda2018-05-24 10:29:39 -0700827 try {
Yu-Han Yang53f4d6d2019-02-13 21:47:41 -0800828 locationManager.requestLocationUpdates(locationRequest,
Yu-Han Yange684dda2018-05-24 10:29:39 -0700829 locationListener, mHandler.getLooper());
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700830 locationListener.mNumLocationUpdateRequest++;
Yu-Han Yange684dda2018-05-24 10:29:39 -0700831 mHandler.postDelayed(() -> {
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700832 if (--locationListener.mNumLocationUpdateRequest == 0) {
Yu-Han Yange684dda2018-05-24 10:29:39 -0700833 Log.i(TAG,
834 String.format("Removing location updates from %s provider.", provider));
835 locationManager.removeUpdates(locationListener);
836 }
837 }, durationMillis);
838 } catch (IllegalArgumentException e) {
839 Log.w(TAG, "Unable to request location.", e);
840 }
Yu-Han Yange7baef32018-02-09 13:58:17 -0800841 }
842
843 private void injectBestLocation(Location location) {
Anil Admalb1c6c0d2019-06-20 12:00:16 -0700844 if (DEBUG) {
845 Log.d(TAG, "injectBestLocation: " + location);
846 }
Yu-Han Yange7baef32018-02-09 13:58:17 -0800847 int gnssLocationFlags = LOCATION_HAS_LAT_LONG |
848 (location.hasAltitude() ? LOCATION_HAS_ALTITUDE : 0) |
849 (location.hasSpeed() ? LOCATION_HAS_SPEED : 0) |
850 (location.hasBearing() ? LOCATION_HAS_BEARING : 0) |
851 (location.hasAccuracy() ? LOCATION_HAS_HORIZONTAL_ACCURACY : 0) |
852 (location.hasVerticalAccuracy() ? LOCATION_HAS_VERTICAL_ACCURACY : 0) |
853 (location.hasSpeedAccuracy() ? LOCATION_HAS_SPEED_ACCURACY : 0) |
854 (location.hasBearingAccuracy() ? LOCATION_HAS_BEARING_ACCURACY : 0);
855
856 double latitudeDegrees = location.getLatitude();
857 double longitudeDegrees = location.getLongitude();
858 double altitudeMeters = location.getAltitude();
859 float speedMetersPerSec = location.getSpeed();
860 float bearingDegrees = location.getBearing();
861 float horizontalAccuracyMeters = location.getAccuracy();
862 float verticalAccuracyMeters = location.getVerticalAccuracyMeters();
863 float speedAccuracyMetersPerSecond = location.getSpeedAccuracyMetersPerSecond();
864 float bearingAccuracyDegrees = location.getBearingAccuracyDegrees();
865 long timestamp = location.getTime();
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -0800866
Pierre Fite-Georgel9e96c572019-02-25 16:12:53 -0800867 int elapsedRealtimeFlags = ELAPSED_REALTIME_HAS_TIMESTAMP_NS
868 | (location.hasElapsedRealtimeUncertaintyNanos()
Sasha Kuznetsov24da7f92019-11-01 12:21:50 -0700869 ? ELAPSED_REALTIME_HAS_TIME_UNCERTAINTY_NS : 0);
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -0800870 long elapsedRealtimeNanos = location.getElapsedRealtimeNanos();
Yu-Han Yang3cd9a862019-03-25 17:00:03 -0700871 double elapsedRealtimeUncertaintyNanos = location.getElapsedRealtimeUncertaintyNanos();
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -0800872
873 native_inject_best_location(
874 gnssLocationFlags, latitudeDegrees, longitudeDegrees,
875 altitudeMeters, speedMetersPerSec, bearingDegrees,
876 horizontalAccuracyMeters, verticalAccuracyMeters,
877 speedAccuracyMetersPerSecond, bearingAccuracyDegrees, timestamp,
Pierre Fite-Georgel9e96c572019-02-25 16:12:53 -0800878 elapsedRealtimeFlags, elapsedRealtimeNanos, elapsedRealtimeUncertaintyNanos);
Yu-Han Yange7baef32018-02-09 13:58:17 -0800879 }
880
Yu-Han Yange7baef32018-02-09 13:58:17 -0800881 /** Returns true if the location request is too frequent. */
882 private boolean isRequestLocationRateLimited() {
Anil Admal316f9482019-02-12 18:57:18 -0800883 // TODO: implement exponential backoff.
Yu-Han Yange7baef32018-02-09 13:58:17 -0800884 return false;
885 }
886
Kevin Tang8c6ac672019-03-22 12:31:01 -0700887 private void handleDownloadPsdsData() {
888 if (!mSupportsPsds) {
889 // native code reports psds not supported, don't try
890 Log.d(TAG, "handleDownloadPsdsData() called when PSDS not supported");
Wyatt Riley0d6e54e22016-10-05 12:03:03 -0700891 return;
892 }
Kevin Tang8c6ac672019-03-22 12:31:01 -0700893 if (mDownloadPsdsDataPending == STATE_DOWNLOADING) {
Kevin Tang40e1baf2012-01-10 14:32:44 -0800894 // already downloading data
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400895 return;
896 }
Anil Admal50ba15e2018-11-01 16:42:42 -0700897 if (!mNetworkConnectivityHandler.isDataNetworkConnected()) {
Kevin Tang40e1baf2012-01-10 14:32:44 -0800898 // try again when network is up
Kevin Tang8c6ac672019-03-22 12:31:01 -0700899 mDownloadPsdsDataPending = STATE_PENDING_NETWORK;
Kevin Tang40e1baf2012-01-10 14:32:44 -0800900 return;
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400901 }
Kevin Tang8c6ac672019-03-22 12:31:01 -0700902 mDownloadPsdsDataPending = STATE_DOWNLOADING;
Kevin Tang40e1baf2012-01-10 14:32:44 -0800903
Yu-Han Yang76f99952019-05-04 17:45:44 -0700904 synchronized (mLock) {
905 // hold wake lock while task runs
906 mDownloadPsdsWakeLock.acquire(DOWNLOAD_PSDS_DATA_TIMEOUT_MS);
907 }
Kevin Tang8c6ac672019-03-22 12:31:01 -0700908 Log.i(TAG, "WakeLock acquired by handleDownloadPsdsData()");
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700909 AsyncTask.THREAD_POOL_EXECUTOR.execute(() -> {
Kevin Tang8c6ac672019-03-22 12:31:01 -0700910 GpsPsdsDownloader psdsDownloader = new GpsPsdsDownloader(
Anil Admald71cf142018-12-21 14:59:36 -0800911 mGnssConfiguration.getProperties());
Kevin Tang8c6ac672019-03-22 12:31:01 -0700912 byte[] data = psdsDownloader.downloadPsdsData();
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700913 if (data != null) {
Kevin Tang8c6ac672019-03-22 12:31:01 -0700914 if (DEBUG) Log.d(TAG, "calling native_inject_psds_data");
915 native_inject_psds_data(data, data.length);
916 mPsdsBackOff.reset();
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700917 }
Kevin Tang40e1baf2012-01-10 14:32:44 -0800918
Kevin Tang8c6ac672019-03-22 12:31:01 -0700919 sendMessage(DOWNLOAD_PSDS_DATA_FINISHED, 0, null);
Kevin Tang40e1baf2012-01-10 14:32:44 -0800920
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700921 if (data == null) {
922 // try again later
923 // since this is delayed and not urgent we do not hold a wake lock here
Kevin Tang8c6ac672019-03-22 12:31:01 -0700924 mHandler.sendEmptyMessageDelayed(DOWNLOAD_PSDS_DATA,
925 mPsdsBackOff.nextBackoffMillis());
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700926 }
Kevin Tang40e1baf2012-01-10 14:32:44 -0800927
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700928 // Release wake lock held by task, synchronize on mLock in case multiple
929 // download tasks overrun.
930 synchronized (mLock) {
Kevin Tang8c6ac672019-03-22 12:31:01 -0700931 if (mDownloadPsdsWakeLock.isHeld()) {
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700932 // This wakelock may have time-out, if a timeout was specified.
933 // Catch (and ignore) any timeout exceptions.
Yu-Han Yang499a6ba2019-11-14 14:19:13 -0800934 mDownloadPsdsWakeLock.release();
935 if (DEBUG) Log.d(TAG, "WakeLock released by handleDownloadPsdsData()");
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700936 } else {
937 Log.e(TAG, "WakeLock expired before release in "
Kevin Tang8c6ac672019-03-22 12:31:01 -0700938 + "handleDownloadPsdsData()");
Wei Wangc5706f62017-04-18 11:26:26 -0700939 }
Jeff Brown028872f2012-08-25 13:07:01 -0700940 }
Kevin Tang40e1baf2012-01-10 14:32:44 -0800941 });
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800942 }
943
Anil Admal2ac70462019-06-28 19:17:41 -0700944 private void injectLocation(Location location) {
Mike Lockwoodd26ce0d2009-06-11 12:25:46 -0400945 if (location.hasAccuracy()) {
Anil Admalb1c6c0d2019-06-20 12:00:16 -0700946 if (DEBUG) {
947 Log.d(TAG, "injectLocation: " + location);
948 }
Mike Lockwoodd26ce0d2009-06-11 12:25:46 -0400949 native_inject_location(location.getLatitude(), location.getLongitude(),
950 location.getAccuracy());
951 }
Mike Lockwoodfd6e5f02009-05-21 11:28:20 -0400952 }
953
Anil Admald71cf142018-12-21 14:59:36 -0800954 private void setSuplHostPort() {
955 mSuplServerHost = mGnssConfiguration.getSuplHost();
956 mSuplServerPort = mGnssConfiguration.getSuplPort(TCP_MIN_PORT);
Tsuwei Chen678c13c2014-09-22 17:48:41 -0700957 if (mSuplServerHost != null
958 && mSuplServerPort > TCP_MIN_PORT
959 && mSuplServerPort <= TCP_MAX_PORT) {
Anil Admalc70344b2018-11-16 14:22:38 -0800960 native_set_agps_server(GnssNetworkConnectivityHandler.AGPS_TYPE_SUPL,
961 mSuplServerHost, mSuplServerPort);
Tsuwei Chen678c13c2014-09-22 17:48:41 -0700962 }
Tsuwei Chen52617bb2014-08-25 11:49:11 -0700963 }
964
Tsuwei Chen462bcd82014-09-17 12:28:49 -0700965 /**
966 * Checks what SUPL mode to use, according to the AGPS mode as well as the
967 * allowed mode from properties.
968 *
Tsuwei Chen462bcd82014-09-17 12:28:49 -0700969 * @param agpsEnabled whether AGPS is enabled by settings value
Tsuwei Chen462bcd82014-09-17 12:28:49 -0700970 * @return SUPL mode (MSA vs MSB vs STANDALONE)
971 */
Yu-Han Yang6a5f0b72019-01-24 18:34:28 -0800972 private int getSuplMode(boolean agpsEnabled) {
Tsuwei Chen462bcd82014-09-17 12:28:49 -0700973 if (agpsEnabled) {
Anil Admald71cf142018-12-21 14:59:36 -0800974 int suplMode = mGnssConfiguration.getSuplMode(0);
975 if (suplMode == 0) {
976 return GPS_POSITION_MODE_STANDALONE;
Tsuwei Chen462bcd82014-09-17 12:28:49 -0700977 }
Anil Admald71cf142018-12-21 14:59:36 -0800978
destradaabfb3bdb2015-04-29 14:42:35 -0700979 // MS-Based is the preferred mode for Assisted-GPS position computation, so we favor
980 // such mode when it is available
981 if (hasCapability(GPS_CAPABILITY_MSB) && (suplMode & AGPS_SUPL_MODE_MSB) != 0) {
982 return GPS_POSITION_MODE_MS_BASED;
983 }
Tsuwei Chen462bcd82014-09-17 12:28:49 -0700984 }
985 return GPS_POSITION_MODE_STANDALONE;
986 }
987
Yu-Han Yang76f99952019-05-04 17:45:44 -0700988 private void setGpsEnabled(boolean enabled) {
989 synchronized (mLock) {
990 mGpsEnabled = enabled;
991 }
992 }
993
994 private void handleEnable() {
995 if (DEBUG) Log.d(TAG, "handleEnable");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800996
Soonil Nagarkar35c3b912019-01-31 10:31:24 -0800997 boolean inited = native_init();
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700998
Soonil Nagarkar35c3b912019-01-31 10:31:24 -0800999 if (inited) {
Yu-Han Yang76f99952019-05-04 17:45:44 -07001000 setGpsEnabled(true);
Kevin Tang8c6ac672019-03-22 12:31:01 -07001001 mSupportsPsds = native_supports_psds();
Tsuwei Chen678c13c2014-09-22 17:48:41 -07001002
1003 // TODO: remove the following native calls if we can make sure they are redundant.
Mike Lockwood734d6032009-07-28 18:30:25 -07001004 if (mSuplServerHost != null) {
Anil Admalc70344b2018-11-16 14:22:38 -08001005 native_set_agps_server(GnssNetworkConnectivityHandler.AGPS_TYPE_SUPL,
1006 mSuplServerHost, mSuplServerPort);
Mike Lockwood734d6032009-07-28 18:30:25 -07001007 }
1008 if (mC2KServerHost != null) {
Anil Admalc70344b2018-11-16 14:22:38 -08001009 native_set_agps_server(GnssNetworkConnectivityHandler.AGPS_TYPE_C2K,
1010 mC2KServerHost, mC2KServerPort);
Mike Lockwood734d6032009-07-28 18:30:25 -07001011 }
destradaa13a60b02015-01-15 18:36:01 -08001012
Lifu Tang818aa2c2016-02-01 01:52:00 -08001013 mGnssMeasurementsProvider.onGpsEnabledChanged();
1014 mGnssNavigationMessageProvider.onGpsEnabledChanged();
Sasha Kuznetsova68a7a32020-02-11 06:00:10 +00001015 mGnssAntennaInfoProvider.onGpsEnabledChanged();
Yu-Han Yang3557cc72018-03-21 12:48:36 -07001016 mGnssBatchingProvider.enable();
Anil Admal138cdc32019-04-16 10:07:43 -07001017 if (mGnssVisibilityControl != null) {
Anil Admal8b83dc12019-06-12 13:55:42 -07001018 mGnssVisibilityControl.onGpsEnabledChanged(/* isEnabled= */ true);
Anil Admal138cdc32019-04-16 10:07:43 -07001019 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001020 } else {
Yu-Han Yang76f99952019-05-04 17:45:44 -07001021 setGpsEnabled(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001022 Log.w(TAG, "Failed to enable location provider");
1023 }
1024 }
1025
Yu-Han Yang76f99952019-05-04 17:45:44 -07001026 private void handleDisable() {
1027 if (DEBUG) Log.d(TAG, "handleDisable");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001028
Yu-Han Yang76f99952019-05-04 17:45:44 -07001029 setGpsEnabled(false);
David Christie3bc26142013-12-19 14:53:44 -08001030 updateClientUids(new WorkSource());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001031 stopNavigating();
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001032 mAlarmManager.cancel(mWakeupIntent);
1033 mAlarmManager.cancel(mTimeoutIntent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001034
Anil Admal138cdc32019-04-16 10:07:43 -07001035 if (mGnssVisibilityControl != null) {
Yu-Han Yang76f99952019-05-04 17:45:44 -07001036 mGnssVisibilityControl.onGpsEnabledChanged(/* isEnabled= */ false);
Anil Admal138cdc32019-04-16 10:07:43 -07001037 }
Yu-Han Yang3557cc72018-03-21 12:48:36 -07001038 mGnssBatchingProvider.disable();
Mike Lockwoodcf1d8cb2010-01-20 10:14:54 -05001039 // do this before releasing wakelock
1040 native_cleanup();
destradaa13a60b02015-01-15 18:36:01 -08001041
Sasha Kuznetsova68a7a32020-02-11 06:00:10 +00001042 mGnssAntennaInfoProvider.onGpsEnabledChanged();
Lifu Tang818aa2c2016-02-01 01:52:00 -08001043 mGnssMeasurementsProvider.onGpsEnabledChanged();
1044 mGnssNavigationMessageProvider.onGpsEnabledChanged();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001045 }
1046
Soonil Nagarkar35c3b912019-01-31 10:31:24 -08001047 private void updateEnabled() {
Tyler Trephan037ef9d2019-05-17 13:41:18 -07001048 // Generally follow location setting for current user
1049 boolean enabled = mContext.getSystemService(LocationManager.class)
1050 .isLocationEnabledForUser(UserHandle.CURRENT);
WyattRileyb2446072019-03-01 07:41:49 -08001051
Yu-Han Yang76f99952019-05-04 17:45:44 -07001052 // ... but disable if PowerManager overrides
1053 enabled &= !mDisableGpsForPowerManager;
WyattRileyb2446072019-03-01 07:41:49 -08001054
Yu-Han Yang76f99952019-05-04 17:45:44 -07001055 // .. but enable anyway, if there's an active settings-ignored request (e.g. ELS)
1056 enabled |= (mProviderRequest != null && mProviderRequest.reportLocation
Sasha Kuznetsov24da7f92019-11-01 12:21:50 -07001057 && mProviderRequest.locationSettingsIgnored);
WyattRileyb2446072019-03-01 07:41:49 -08001058
Yu-Han Yang76f99952019-05-04 17:45:44 -07001059 // ... and, finally, disable anyway, if device is being shut down
1060 enabled &= !mShutdown;
WyattRileyb2446072019-03-01 07:41:49 -08001061
Yu-Han Yang76f99952019-05-04 17:45:44 -07001062 if (enabled == isGpsEnabled()) {
1063 return;
1064 }
Soonil Nagarkar35c3b912019-01-31 10:31:24 -08001065
Yu-Han Yang76f99952019-05-04 17:45:44 -07001066 if (enabled) {
1067 handleEnable();
1068 } else {
1069 handleDisable();
Soonil Nagarkar35c3b912019-01-31 10:31:24 -08001070 }
1071 }
1072
Yu-Han Yang76f99952019-05-04 17:45:44 -07001073 private boolean isGpsEnabled() {
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001074 synchronized (mLock) {
Yu-Han Yang76f99952019-05-04 17:45:44 -07001075 return mGpsEnabled;
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001076 }
Mike Lockwoodd03ff942010-02-09 08:46:14 -05001077 }
1078
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001079 @Override
Soonil Nagarkar8df02f42020-01-08 13:23:26 -08001080 public void onSetRequest(ProviderRequest request) {
1081 sendMessage(SET_REQUEST, 0, new GpsRequest(request, request.workSource));
Mike Lockwood62a8fc12010-03-22 14:23:26 -04001082 }
1083
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001084 private void handleSetRequest(ProviderRequest request, WorkSource source) {
David Christied4edf4c2014-08-12 15:22:27 -07001085 mProviderRequest = request;
1086 mWorkSource = source;
Soonil Nagarkar35c3b912019-01-31 10:31:24 -08001087 updateEnabled();
David Christied4edf4c2014-08-12 15:22:27 -07001088 updateRequirements();
1089 }
1090
1091 // Called when the requirements for GPS may have changed
1092 private void updateRequirements() {
1093 if (mProviderRequest == null || mWorkSource == null) {
1094 return;
1095 }
1096
David Christied4edf4c2014-08-12 15:22:27 -07001097 if (DEBUG) Log.d(TAG, "setRequest " + mProviderRequest);
Yu-Han Yang76f99952019-05-04 17:45:44 -07001098 if (mProviderRequest.reportLocation && isGpsEnabled()) {
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001099 // update client uids
David Christied4edf4c2014-08-12 15:22:27 -07001100 updateClientUids(mWorkSource);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001101
David Christied4edf4c2014-08-12 15:22:27 -07001102 mFixInterval = (int) mProviderRequest.interval;
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001103 mLowPowerMode = mProviderRequest.lowPowerMode;
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001104 // check for overflow
David Christied4edf4c2014-08-12 15:22:27 -07001105 if (mFixInterval != mProviderRequest.interval) {
1106 Log.w(TAG, "interval overflow: " + mProviderRequest.interval);
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001107 mFixInterval = Integer.MAX_VALUE;
1108 }
Mike Lockwood03ca2162010-04-01 08:10:09 -07001109
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001110 // apply request to GPS engine
Mike Lockwood04598b62010-04-14 17:17:24 -04001111 if (mStarted && hasCapability(GPS_CAPABILITY_SCHEDULING)) {
gomo48f1a642017-11-10 20:35:46 -08001112 // change period and/or lowPowerMode
Yu-Han Yangc8b9ff72018-04-17 00:47:24 -07001113 if (!setPositionMode(mPositionMode, GPS_POSITION_RECURRENCE_PERIODIC,
gomo48f1a642017-11-10 20:35:46 -08001114 mFixInterval, 0, 0, mLowPowerMode)) {
1115 Log.e(TAG, "set_position_mode failed in updateRequirements");
Mike Lockwood04598b62010-04-14 17:17:24 -04001116 }
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001117 } else if (!mStarted) {
1118 // start GPS
Yu-Han Yang6a5f0b72019-01-24 18:34:28 -08001119 startNavigating();
gomo300b2402017-12-13 19:04:12 -08001120 } else {
1121 // GNSS Engine is already ON, but no GPS_CAPABILITY_SCHEDULING
1122 mAlarmManager.cancel(mTimeoutIntent);
1123 if (mFixInterval >= NO_FIX_TIMEOUT) {
1124 // set timer to give up if we do not receive a fix within NO_FIX_TIMEOUT
1125 // and our fix interval is not short
1126 mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001127 SystemClock.elapsedRealtime() + NO_FIX_TIMEOUT, mTimeoutIntent);
1128 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001129 }
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001130 } else {
Dianne Hackborn002a54e2013-01-10 17:34:55 -08001131 updateClientUids(new WorkSource());
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001132
1133 stopNavigating();
1134 mAlarmManager.cancel(mWakeupIntent);
1135 mAlarmManager.cancel(mTimeoutIntent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001136 }
1137 }
1138
Yu-Han Yangc8b9ff72018-04-17 00:47:24 -07001139 private boolean setPositionMode(int mode, int recurrence, int minInterval,
1140 int preferredAccuracy, int preferredTime, boolean lowPowerMode) {
1141 GnssPositionMode positionMode = new GnssPositionMode(mode, recurrence, minInterval,
1142 preferredAccuracy, preferredTime, lowPowerMode);
1143 if (mLastPositionMode != null && mLastPositionMode.equals(positionMode)) {
1144 return true;
1145 }
1146
1147 boolean result = native_set_position_mode(mode, recurrence, minInterval,
1148 preferredAccuracy, preferredTime, lowPowerMode);
1149 if (result) {
1150 mLastPositionMode = positionMode;
1151 } else {
1152 mLastPositionMode = null;
1153 }
1154 return result;
1155 }
1156
Dianne Hackborn002a54e2013-01-10 17:34:55 -08001157 private void updateClientUids(WorkSource source) {
Narayan Kamath32684dd2018-01-08 17:32:51 +00001158 if (source.equals(mClientSource)) {
Victoria Leaseea78b852013-01-15 10:39:28 -08001159 return;
1160 }
Dianne Hackborn002a54e2013-01-10 17:34:55 -08001161
Narayan Kamath32684dd2018-01-08 17:32:51 +00001162 // (1) Inform BatteryStats that the list of IDs we're tracking changed.
1163 try {
1164 mBatteryStats.noteGpsChanged(mClientSource, source);
1165 } catch (RemoteException e) {
1166 Log.w(TAG, "RemoteException", e);
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001167 }
1168
Narayan Kamath32684dd2018-01-08 17:32:51 +00001169 // (2) Inform AppOps service about the list of changes to UIDs.
1170
1171 List<WorkChain>[] diffs = WorkSource.diffChains(mClientSource, source);
1172 if (diffs != null) {
1173 List<WorkChain> newChains = diffs[0];
1174 List<WorkChain> goneChains = diffs[1];
1175
1176 if (newChains != null) {
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001177 for (WorkChain newChain : newChains) {
Svet Ganovf7b47252018-02-26 11:11:27 -08001178 mAppOps.startOpNoThrow(AppOpsManager.OP_GPS, newChain.getAttributionUid(),
1179 newChain.getAttributionTag());
Narayan Kamath32684dd2018-01-08 17:32:51 +00001180 }
1181 }
1182
1183 if (goneChains != null) {
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001184 for (WorkChain goneChain : goneChains) {
Svet Ganovf7b47252018-02-26 11:11:27 -08001185 mAppOps.finishOp(AppOpsManager.OP_GPS, goneChain.getAttributionUid(),
1186 goneChain.getAttributionTag());
Narayan Kamath32684dd2018-01-08 17:32:51 +00001187 }
1188 }
1189
1190 mClientSource.transferWorkChains(source);
1191 }
1192
1193 // Update the flat UIDs and names list and inform app-ops of all changes.
1194 WorkSource[] changes = mClientSource.setReturningDiffs(source);
1195 if (changes != null) {
1196 WorkSource newWork = changes[0];
1197 WorkSource goneWork = changes[1];
1198
1199 // Update sources that were not previously tracked.
1200 if (newWork != null) {
1201 for (int i = 0; i < newWork.size(); i++) {
Svet Ganovf7b47252018-02-26 11:11:27 -08001202 mAppOps.startOpNoThrow(AppOpsManager.OP_GPS,
Suprabh Shuklaf7cffa72019-11-08 17:03:03 -08001203 newWork.getUid(i), newWork.getPackageName(i));
Narayan Kamath32684dd2018-01-08 17:32:51 +00001204 }
1205 }
1206
1207 // Update sources that are no longer tracked.
1208 if (goneWork != null) {
1209 for (int i = 0; i < goneWork.size(); i++) {
Suprabh Shuklaf7cffa72019-11-08 17:03:03 -08001210 mAppOps.finishOp(AppOpsManager.OP_GPS, goneWork.getUid(i),
1211 goneWork.getPackageName(i));
Dianne Hackborn2e418422009-06-22 20:00:17 -07001212 }
Mike Lockwood2f82c4e2009-04-17 08:24:10 -04001213 }
1214 }
1215 }
1216
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001217 @Override
Soonil Nagarkar8df02f42020-01-08 13:23:26 -08001218 public void onExtraCommand(int uid, int pid, String command, Bundle extras) {
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001219
Mike Lockwood63aa5a62010-04-14 19:21:31 -04001220 long identity = Binder.clearCallingIdentity();
Peter Visontayb25db362017-11-01 18:18:12 +00001221 try {
Peter Visontayb25db362017-11-01 18:18:12 +00001222 if ("delete_aiding_data".equals(command)) {
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001223 deleteAidingData(extras);
Peter Visontayb25db362017-11-01 18:18:12 +00001224 } else if ("force_time_injection".equals(command)) {
1225 requestUtcTime();
Kevin Tang8c6ac672019-03-22 12:31:01 -07001226 } else if ("force_psds_injection".equals(command)) {
1227 if (mSupportsPsds) {
1228 psdsDownloadRequest();
Peter Visontayb25db362017-11-01 18:18:12 +00001229 }
1230 } else {
1231 Log.w(TAG, "sendExtraCommand: unknown command " + command);
Mike Lockwood93bc44d2009-05-20 16:58:22 -04001232 }
Peter Visontayb25db362017-11-01 18:18:12 +00001233 } finally {
1234 Binder.restoreCallingIdentity(identity);
Mike Lockwood93bc44d2009-05-20 16:58:22 -04001235 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001236 }
1237
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001238 private void deleteAidingData(Bundle extras) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001239 int flags;
1240
1241 if (extras == null) {
1242 flags = GPS_DELETE_ALL;
1243 } else {
1244 flags = 0;
1245 if (extras.getBoolean("ephemeris")) flags |= GPS_DELETE_EPHEMERIS;
1246 if (extras.getBoolean("almanac")) flags |= GPS_DELETE_ALMANAC;
1247 if (extras.getBoolean("position")) flags |= GPS_DELETE_POSITION;
1248 if (extras.getBoolean("time")) flags |= GPS_DELETE_TIME;
1249 if (extras.getBoolean("iono")) flags |= GPS_DELETE_IONO;
1250 if (extras.getBoolean("utc")) flags |= GPS_DELETE_UTC;
1251 if (extras.getBoolean("health")) flags |= GPS_DELETE_HEALTH;
1252 if (extras.getBoolean("svdir")) flags |= GPS_DELETE_SVDIR;
1253 if (extras.getBoolean("svsteer")) flags |= GPS_DELETE_SVSTEER;
1254 if (extras.getBoolean("sadata")) flags |= GPS_DELETE_SADATA;
1255 if (extras.getBoolean("rti")) flags |= GPS_DELETE_RTI;
1256 if (extras.getBoolean("celldb-info")) flags |= GPS_DELETE_CELLDB_INFO;
1257 if (extras.getBoolean("all")) flags |= GPS_DELETE_ALL;
1258 }
1259
1260 if (flags != 0) {
1261 native_delete_aiding_data(flags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001262 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001263 }
1264
Yu-Han Yang6a5f0b72019-01-24 18:34:28 -08001265 private void startNavigating() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001266 if (!mStarted) {
Yu-Han Yang6a5f0b72019-01-24 18:34:28 -08001267 if (DEBUG) Log.d(TAG, "startNavigating");
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001268 mTimeToFirstFix = 0;
1269 mLastFixTime = 0;
WyattRileyba6072f2019-04-18 07:37:52 -07001270 setStarted(true);
Mike Lockwood03ca2162010-04-01 08:10:09 -07001271 mPositionMode = GPS_POSITION_MODE_STANDALONE;
Wyatt Riley5d5bac82016-11-01 07:05:16 -07001272 // Notify about suppressed output, if speed limit was previously exceeded.
1273 // Elsewhere, we check again with every speed output reported.
1274 if (mItarSpeedLimitExceeded) {
1275 Log.i(TAG, "startNavigating with ITAR limit in place. Output limited " +
1276 "until slow enough speed reported.");
1277 }
Mike Lockwood03ca2162010-04-01 08:10:09 -07001278
Tsuwei Chen462bcd82014-09-17 12:28:49 -07001279 boolean agpsEnabled =
1280 (Settings.Global.getInt(mContext.getContentResolver(),
gomo48f1a642017-11-10 20:35:46 -08001281 Settings.Global.ASSISTED_GPS_ENABLED, 1) != 0);
Yu-Han Yang6a5f0b72019-01-24 18:34:28 -08001282 mPositionMode = getSuplMode(agpsEnabled);
Mike Lockwoodbcab8df2009-06-25 16:39:09 -04001283
Stan Chesnutt1d72d8c2013-04-15 19:18:02 -07001284 if (DEBUG) {
1285 String mode;
1286
gomo48f1a642017-11-10 20:35:46 -08001287 switch (mPositionMode) {
Stan Chesnutt1d72d8c2013-04-15 19:18:02 -07001288 case GPS_POSITION_MODE_STANDALONE:
1289 mode = "standalone";
1290 break;
1291 case GPS_POSITION_MODE_MS_ASSISTED:
1292 mode = "MS_ASSISTED";
1293 break;
1294 case GPS_POSITION_MODE_MS_BASED:
1295 mode = "MS_BASED";
1296 break;
1297 default:
1298 mode = "unknown";
1299 break;
1300 }
1301 Log.d(TAG, "setting position_mode to " + mode);
1302 }
1303
Mike Lockwood04598b62010-04-14 17:17:24 -04001304 int interval = (hasCapability(GPS_CAPABILITY_SCHEDULING) ? mFixInterval : 1000);
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001305 mLowPowerMode = mProviderRequest.lowPowerMode;
Yu-Han Yangc8b9ff72018-04-17 00:47:24 -07001306 if (!setPositionMode(mPositionMode, GPS_POSITION_RECURRENCE_PERIODIC,
gomo48f1a642017-11-10 20:35:46 -08001307 interval, 0, 0, mLowPowerMode)) {
WyattRileyba6072f2019-04-18 07:37:52 -07001308 setStarted(false);
Mike Lockwood04598b62010-04-14 17:17:24 -04001309 Log.e(TAG, "set_position_mode failed in startNavigating()");
1310 return;
1311 }
1312 if (!native_start()) {
WyattRileyba6072f2019-04-18 07:37:52 -07001313 setStarted(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001314 Log.e(TAG, "native_start failed in startNavigating()");
Mike Lockwood0632ca72009-05-14 15:51:03 -04001315 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001316 }
1317
1318 // reset SV count to zero
Wyatt Rileyc7067412018-02-07 15:50:35 -08001319 mLocationExtras.reset();
Yipeng Cao282b5942017-05-17 20:31:39 -07001320 mFixRequestTime = SystemClock.elapsedRealtime();
Mike Lockwood04598b62010-04-14 17:17:24 -04001321 if (!hasCapability(GPS_CAPABILITY_SCHEDULING)) {
1322 // set timer to give up if we do not receive a fix within NO_FIX_TIMEOUT
1323 // and our fix interval is not short
1324 if (mFixInterval >= NO_FIX_TIMEOUT) {
1325 mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
1326 SystemClock.elapsedRealtime() + NO_FIX_TIMEOUT, mTimeoutIntent);
1327 }
Mike Lockwood0632ca72009-05-14 15:51:03 -04001328 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001329 }
1330 }
1331
Mike Lockwood62a8fc12010-03-22 14:23:26 -04001332 private void stopNavigating() {
Mike Lockwood29c84342009-05-06 14:01:15 -04001333 if (DEBUG) Log.d(TAG, "stopNavigating");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001334 if (mStarted) {
WyattRileyba6072f2019-04-18 07:37:52 -07001335 setStarted(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001336 native_stop();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001337 mLastFixTime = 0;
Yu-Han Yanga50cd602018-08-28 12:33:24 -07001338 // native_stop() may reset the position mode in hardware.
1339 mLastPositionMode = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001340
1341 // reset SV count to zero
Wyatt Rileyc7067412018-02-07 15:50:35 -08001342 mLocationExtras.reset();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001343 }
1344 }
1345
WyattRileyba6072f2019-04-18 07:37:52 -07001346 private void setStarted(boolean started) {
1347 if (mStarted != started) {
1348 mStarted = started;
1349 mStartedChangedElapsedRealtime = SystemClock.elapsedRealtime();
1350 }
1351 }
1352
Mike Lockwood0632ca72009-05-14 15:51:03 -04001353 private void hibernate() {
1354 // stop GPS until our next fix interval arrives
1355 stopNavigating();
Mike Lockwood0632ca72009-05-14 15:51:03 -04001356 mAlarmManager.cancel(mTimeoutIntent);
1357 mAlarmManager.cancel(mWakeupIntent);
1358 long now = SystemClock.elapsedRealtime();
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001359 mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, now + mFixInterval, mWakeupIntent);
Mike Lockwood04598b62010-04-14 17:17:24 -04001360 }
1361
1362 private boolean hasCapability(int capability) {
Anil Admal312fddb2019-03-25 12:15:43 -07001363 return (mTopHalCapabilities & capability) != 0;
Mike Lockwood0632ca72009-05-14 15:51:03 -04001364 }
1365
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001366 @NativeEntryPoint
Wyatt Riley5d229832017-02-10 17:06:00 -08001367 private void reportLocation(boolean hasLatLong, Location location) {
Wyatt Riley26465d22018-02-12 13:44:24 -08001368 sendMessage(REPORT_LOCATION, hasLatLong ? 1 : 0, location);
1369 }
1370
1371 private void handleReportLocation(boolean hasLatLong, Location location) {
Wyatt Riley5d229832017-02-10 17:06:00 -08001372 if (location.hasSpeed()) {
1373 mItarSpeedLimitExceeded = location.getSpeed() > ITAR_SPEED_LIMIT_METERS_PER_SECOND;
Wyatt Riley5d5bac82016-11-01 07:05:16 -07001374 }
1375
1376 if (mItarSpeedLimitExceeded) {
1377 Log.i(TAG, "Hal reported a speed in excess of ITAR limit." +
1378 " GPS/GNSS Navigation output blocked.");
Siddharth Ray53ddc802018-03-16 12:01:52 -07001379 if (mStarted) {
1380 mGnssMetrics.logReceivedLocationStatus(false);
1381 }
Wyatt Riley5d5bac82016-11-01 07:05:16 -07001382 return; // No output of location allowed
1383 }
1384
Wyatt Riley5d229832017-02-10 17:06:00 -08001385 if (VERBOSE) Log.v(TAG, "reportLocation " + location.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001386
Wyatt Riley26465d22018-02-12 13:44:24 -08001387 location.setExtras(mLocationExtras.getBundle());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001388
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001389 reportLocation(location);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001390
Siddharth Ray53ddc802018-03-16 12:01:52 -07001391 if (mStarted) {
1392 mGnssMetrics.logReceivedLocationStatus(hasLatLong);
1393 if (hasLatLong) {
1394 if (location.hasAccuracy()) {
1395 mGnssMetrics.logPositionAccuracyMeters(location.getAccuracy());
1396 }
1397 if (mTimeToFirstFix > 0) {
1398 int timeBetweenFixes = (int) (SystemClock.elapsedRealtime() - mLastFixTime);
1399 mGnssMetrics.logMissedReports(mFixInterval, timeBetweenFixes);
1400 }
Siddharth Raybb608c82017-03-16 11:33:34 -07001401 }
WyattRileyba6072f2019-04-18 07:37:52 -07001402 } else {
1403 // Warn or error about long delayed GNSS engine shutdown as this generally wastes
1404 // power and sends location when not expected.
1405 long locationAfterStartedFalseMillis =
1406 SystemClock.elapsedRealtime() - mStartedChangedElapsedRealtime;
1407 if (locationAfterStartedFalseMillis > LOCATION_OFF_DELAY_THRESHOLD_WARN_MILLIS) {
1408 String logMessage = "Unexpected GNSS Location report "
1409 + TimeUtils.formatDuration(locationAfterStartedFalseMillis)
1410 + " after location turned off";
1411 if (locationAfterStartedFalseMillis > LOCATION_OFF_DELAY_THRESHOLD_ERROR_MILLIS) {
1412 Log.e(TAG, logMessage);
1413 } else {
1414 Log.w(TAG, logMessage);
1415 }
1416 }
Siddharth Raybb608c82017-03-16 11:33:34 -07001417 }
1418
Yipeng Cao282b5942017-05-17 20:31:39 -07001419 mLastFixTime = SystemClock.elapsedRealtime();
Hakan Gustavssonfa94ff02010-02-23 09:12:38 +01001420 // report time to first fix
Wyatt Riley5d229832017-02-10 17:06:00 -08001421 if (mTimeToFirstFix == 0 && hasLatLong) {
gomo48f1a642017-11-10 20:35:46 -08001422 mTimeToFirstFix = (int) (mLastFixTime - mFixRequestTime);
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001423 if (DEBUG) Log.d(TAG, "TTFF: " + mTimeToFirstFix);
Siddharth Ray53ddc802018-03-16 12:01:52 -07001424 if (mStarted) {
1425 mGnssMetrics.logTimeToFirstFixMilliSecs(mTimeToFirstFix);
1426 }
Hakan Gustavssonfa94ff02010-02-23 09:12:38 +01001427
1428 // notify status listeners
Anil Admal75b9fd62018-11-28 11:22:50 -08001429 mGnssStatusListenerHelper.onFirstFix(mTimeToFirstFix);
Hakan Gustavssonfa94ff02010-02-23 09:12:38 +01001430 }
1431
Soonil Nagarkarfc9c7f82019-07-16 12:07:57 -07001432 if (mStarted) {
Wyatt Rileyc7067412018-02-07 15:50:35 -08001433 // For devices that use framework scheduling, a timer may be set to ensure we don't
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001434 // spend too much power searching for a location, when the requested update rate is
1435 // slow.
Wyatt Rileyc7067412018-02-07 15:50:35 -08001436 // As we just recievied a location, we'll cancel that timer.
Mike Lockwood04598b62010-04-14 17:17:24 -04001437 if (!hasCapability(GPS_CAPABILITY_SCHEDULING) && mFixInterval < NO_FIX_TIMEOUT) {
Mike Lockwoodb7be5442010-02-24 14:34:50 -05001438 mAlarmManager.cancel(mTimeoutIntent);
1439 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001440 }
Mike Lockwood29c84342009-05-06 14:01:15 -04001441
gomo48f1a642017-11-10 20:35:46 -08001442 if (!hasCapability(GPS_CAPABILITY_SCHEDULING) && mStarted &&
1443 mFixInterval > GPS_POLLING_THRESHOLD_INTERVAL) {
Mike Lockwoodd53ba012010-04-15 20:41:26 -04001444 if (DEBUG) Log.d(TAG, "got fix, hibernating");
Mike Lockwood0632ca72009-05-14 15:51:03 -04001445 hibernate();
Mike Lockwood29c84342009-05-06 14:01:15 -04001446 }
gomo48f1a642017-11-10 20:35:46 -08001447 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001448
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001449 @NativeEntryPoint
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001450 private void reportStatus(int status) {
Mike Lockwoodb8d90332010-10-18 17:59:48 -04001451 if (DEBUG) Log.v(TAG, "reportStatus status: " + status);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001452
destradaaea8a8a62014-06-23 18:19:03 -07001453 boolean wasNavigating = mNavigating;
1454 switch (status) {
1455 case GPS_STATUS_SESSION_BEGIN:
1456 mNavigating = true;
destradaaea8a8a62014-06-23 18:19:03 -07001457 break;
1458 case GPS_STATUS_SESSION_END:
1459 mNavigating = false;
1460 break;
1461 case GPS_STATUS_ENGINE_ON:
destradaaea8a8a62014-06-23 18:19:03 -07001462 break;
1463 case GPS_STATUS_ENGINE_OFF:
destradaaea8a8a62014-06-23 18:19:03 -07001464 mNavigating = false;
1465 break;
1466 }
Mike Lockwooddbd6fd82009-12-07 18:43:36 -05001467
destradaaea8a8a62014-06-23 18:19:03 -07001468 if (wasNavigating != mNavigating) {
Anil Admal75b9fd62018-11-28 11:22:50 -08001469 mGnssStatusListenerHelper.onStatusChanged(mNavigating);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001470 }
1471 }
1472
Wyatt Riley26465d22018-02-12 13:44:24 -08001473 // Helper class to carry data to handler for reportSvStatus
1474 private static class SvStatusInfo {
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001475 private int mSvCount;
1476 private int[] mSvidWithFlags;
1477 private float[] mCn0s;
1478 private float[] mSvElevations;
1479 private float[] mSvAzimuths;
1480 private float[] mSvCarrierFreqs;
Yu-Han Yang15e43032019-11-22 13:50:41 -08001481 private float[] mBasebandCn0s;
Wyatt Riley26465d22018-02-12 13:44:24 -08001482 }
1483
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001484 @NativeEntryPoint
Wyatt Riley26465d22018-02-12 13:44:24 -08001485 private void reportSvStatus(int svCount, int[] svidWithFlags, float[] cn0s,
Yu-Han Yang15e43032019-11-22 13:50:41 -08001486 float[] svElevations, float[] svAzimuths, float[] svCarrierFreqs,
1487 float[] basebandCn0s) {
Wyatt Riley26465d22018-02-12 13:44:24 -08001488 SvStatusInfo svStatusInfo = new SvStatusInfo();
1489 svStatusInfo.mSvCount = svCount;
1490 svStatusInfo.mSvidWithFlags = svidWithFlags;
1491 svStatusInfo.mCn0s = cn0s;
1492 svStatusInfo.mSvElevations = svElevations;
1493 svStatusInfo.mSvAzimuths = svAzimuths;
1494 svStatusInfo.mSvCarrierFreqs = svCarrierFreqs;
Yu-Han Yang15e43032019-11-22 13:50:41 -08001495 svStatusInfo.mBasebandCn0s = basebandCn0s;
Wyatt Riley26465d22018-02-12 13:44:24 -08001496
1497 sendMessage(REPORT_SV_STATUS, 0, svStatusInfo);
1498 }
1499
1500 private void handleReportSvStatus(SvStatusInfo info) {
Anil Admal75b9fd62018-11-28 11:22:50 -08001501 mGnssStatusListenerHelper.onSvStatusChanged(
Wyatt Riley26465d22018-02-12 13:44:24 -08001502 info.mSvCount,
1503 info.mSvidWithFlags,
1504 info.mCn0s,
1505 info.mSvElevations,
1506 info.mSvAzimuths,
Yu-Han Yang15e43032019-11-22 13:50:41 -08001507 info.mSvCarrierFreqs,
1508 info.mBasebandCn0s);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001509
Siddharth Ray168f12a2017-07-10 11:55:10 -07001510 // Log CN0 as part of GNSS metrics
Blake Kragtenbb613602019-08-28 16:21:35 -07001511 mGnssMetrics.logCn0(info.mCn0s, info.mSvCount, info.mSvCarrierFreqs);
Siddharth Ray168f12a2017-07-10 11:55:10 -07001512
Mike Lockwood29c84342009-05-06 14:01:15 -04001513 if (VERBOSE) {
Wyatt Riley26465d22018-02-12 13:44:24 -08001514 Log.v(TAG, "SV count: " + info.mSvCount);
Lifu Tang30f95a72016-01-07 23:20:38 -08001515 }
Wyatt Rileyc9f25dd2017-05-05 13:45:23 -07001516 // Calculate number of satellites used in fix.
Soonil Nagarkar0d1890b2019-11-12 12:13:14 -08001517 GnssStatus gnssStatus = GnssStatus.wrap(
1518 info.mSvCount,
1519 info.mSvidWithFlags,
1520 info.mCn0s,
1521 info.mSvElevations,
1522 info.mSvAzimuths,
Yu-Han Yang15e43032019-11-22 13:50:41 -08001523 info.mSvCarrierFreqs,
1524 info.mBasebandCn0s);
Lifu Tang30f95a72016-01-07 23:20:38 -08001525 int usedInFixCount = 0;
Wyatt Rileyc9f25dd2017-05-05 13:45:23 -07001526 int maxCn0 = 0;
1527 int meanCn0 = 0;
Soonil Nagarkar0d1890b2019-11-12 12:13:14 -08001528 for (int i = 0; i < gnssStatus.getSatelliteCount(); i++) {
1529 if (gnssStatus.usedInFix(i)) {
Lifu Tang30f95a72016-01-07 23:20:38 -08001530 ++usedInFixCount;
Soonil Nagarkar0d1890b2019-11-12 12:13:14 -08001531 if (gnssStatus.getCn0DbHz(i) > maxCn0) {
1532 maxCn0 = (int) gnssStatus.getCn0DbHz(i);
Wyatt Rileyc9f25dd2017-05-05 13:45:23 -07001533 }
Soonil Nagarkar0d1890b2019-11-12 12:13:14 -08001534 meanCn0 += gnssStatus.getCn0DbHz(i);
1535 mGnssMetrics.logConstellationType(gnssStatus.getConstellationType(i));
Lifu Tang30f95a72016-01-07 23:20:38 -08001536 }
1537 if (VERBOSE) {
Soonil Nagarkar0d1890b2019-11-12 12:13:14 -08001538 Log.v(TAG, "svid: " + gnssStatus.getSvid(i)
1539 + " cn0: " + gnssStatus.getCn0DbHz(i)
Yu-Han Yang15e43032019-11-22 13:50:41 -08001540 + " basebandCn0: " + gnssStatus.getBasebandCn0DbHz(i)
Soonil Nagarkar0d1890b2019-11-12 12:13:14 -08001541 + " elev: " + gnssStatus.getElevationDegrees(i)
1542 + " azimuth: " + gnssStatus.getAzimuthDegrees(i)
1543 + " carrier frequency: " + gnssStatus.getCn0DbHz(i)
1544 + (gnssStatus.hasEphemerisData(i) ? " E" : " ")
1545 + (gnssStatus.hasAlmanacData(i) ? " A" : " ")
1546 + (gnssStatus.usedInFix(i) ? "U" : "")
Yu-Han Yang15e43032019-11-22 13:50:41 -08001547 + (gnssStatus.hasCarrierFrequencyHz(i) ? "F" : "")
1548 + (gnssStatus.hasBasebandCn0DbHz(i) ? "B" : ""));
Yu-Han Yang284234e2019-03-28 19:35:57 -07001549 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001550 }
Wyatt Rileyc9f25dd2017-05-05 13:45:23 -07001551 if (usedInFixCount > 0) {
1552 meanCn0 /= usedInFixCount;
1553 }
1554 // return number of sats used in fix instead of total reported
Wyatt Rileyc7067412018-02-07 15:50:35 -08001555 mLocationExtras.set(usedInFixCount, meanCn0, maxCn0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001556
Soonil Nagarkar0d1890b2019-11-12 12:13:14 -08001557 mGnssMetrics.logSvStatus(gnssStatus);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001558 }
Mike Lockwood58bda982009-04-14 16:25:07 -04001559
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001560 @NativeEntryPoint
Anil Admalc70344b2018-11-16 14:22:38 -08001561 private void reportAGpsStatus(int agpsType, int agpsStatus, byte[] suplIpAddr) {
1562 mNetworkConnectivityHandler.onReportAGpsStatus(agpsType, agpsStatus, suplIpAddr);
destradaae21252a2015-09-08 12:32:59 -07001563 }
1564
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001565 @NativeEntryPoint
Mike Lockwoodf602d362010-06-20 14:28:16 -07001566 private void reportNmea(long timestamp) {
Wyatt Riley5d5bac82016-11-01 07:05:16 -07001567 if (!mItarSpeedLimitExceeded) {
1568 int length = native_read_nmea(mNmeaBuffer, mNmeaBuffer.length);
1569 String nmea = new String(mNmeaBuffer, 0 /* offset */, length);
Anil Admal75b9fd62018-11-28 11:22:50 -08001570 mGnssStatusListenerHelper.onNmeaReceived(timestamp, nmea);
Wyatt Riley5d5bac82016-11-01 07:05:16 -07001571 }
destradaaea8a8a62014-06-23 18:19:03 -07001572 }
Mike Lockwoodb16e7802009-08-06 09:26:02 -04001573
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001574 @NativeEntryPoint
Lifu Tang818aa2c2016-02-01 01:52:00 -08001575 private void reportMeasurementData(GnssMeasurementsEvent event) {
Wyatt Riley5d5bac82016-11-01 07:05:16 -07001576 if (!mItarSpeedLimitExceeded) {
Wyatt Rileyaa420d52017-07-03 15:14:42 -07001577 // send to handler to allow native to return quickly
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001578 mHandler.post(() -> mGnssMeasurementsProvider.onMeasurementsAvailable(event));
Wyatt Riley5d5bac82016-11-01 07:05:16 -07001579 }
Mike Lockwoodb16e7802009-08-06 09:26:02 -04001580 }
1581
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001582 @NativeEntryPoint
Sasha Kuznetsova68a7a32020-02-11 06:00:10 +00001583 private void reportAntennaInfo(List<GnssAntennaInfo> antennaInfos) {
1584 mHandler.post(() -> mGnssAntennaInfoProvider.onGnssAntennaInfoAvailable(antennaInfos));
1585 }
1586
1587 @NativeEntryPoint
Lifu Tange8abe8e2016-04-01 10:32:05 -07001588 private void reportNavigationMessage(GnssNavigationMessage event) {
Wyatt Riley5d5bac82016-11-01 07:05:16 -07001589 if (!mItarSpeedLimitExceeded) {
Wyatt Rileyaa420d52017-07-03 15:14:42 -07001590 // send to handler to allow native to return quickly
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001591 mHandler.post(() -> mGnssNavigationMessageProvider.onNavigationMessageAvailable(event));
Wyatt Riley5d5bac82016-11-01 07:05:16 -07001592 }
destradaa4b3e3932014-07-21 18:01:47 -07001593 }
1594
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001595 @NativeEntryPoint
Anil Admal62c42dc2019-04-03 15:39:22 -07001596 private void setTopHalCapabilities(int topHalCapabilities) {
Anil Admalefd9dc62019-03-12 17:39:20 -07001597 mHandler.post(() -> {
Anil Admal312fddb2019-03-25 12:15:43 -07001598 mTopHalCapabilities = topHalCapabilities;
Mike Lockwood9b9fb5c2011-06-29 15:09:40 -04001599
Anil Admalefd9dc62019-03-12 17:39:20 -07001600 if (hasCapability(GPS_CAPABILITY_ON_DEMAND_TIME)) {
1601 mNtpTimeHelper.enablePeriodicTimeInjection();
1602 requestUtcTime();
1603 }
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001604
Anil Admal62c42dc2019-04-03 15:39:22 -07001605 mGnssMeasurementsProvider.onCapabilitiesUpdated(
1606 hasCapability(GPS_CAPABILITY_MEASUREMENTS));
1607 mGnssNavigationMessageProvider.onCapabilitiesUpdated(
1608 hasCapability(GPS_CAPABILITY_NAV_MESSAGES));
Anil Admalefd9dc62019-03-12 17:39:20 -07001609 restartRequests();
Sasha Kuznetsova68a7a32020-02-11 06:00:10 +00001610 mGnssAntennaInfoProvider.onCapabilitiesUpdated(
1611 hasCapability(GPS_CAPABILITY_ANTENNA_INFO));
Anil Admal312fddb2019-03-25 12:15:43 -07001612
Anil Admal62c42dc2019-04-03 15:39:22 -07001613 mGnssCapabilitiesProvider.setTopHalCapabilities(mTopHalCapabilities);
Anil Admalefd9dc62019-03-12 17:39:20 -07001614 });
1615 }
1616
1617 @NativeEntryPoint
Anil Admal312fddb2019-03-25 12:15:43 -07001618 private void setSubHalMeasurementCorrectionsCapabilities(int subHalCapabilities) {
1619 mHandler.post(() -> {
1620 if (!mGnssMeasurementCorrectionsProvider.onCapabilitiesUpdated(subHalCapabilities)) {
1621 return;
1622 }
1623
1624 mGnssCapabilitiesProvider.setSubHalMeasurementCorrectionsCapabilities(
1625 subHalCapabilities);
1626 });
Yu-Han Yang52057622018-04-25 00:51:22 -07001627 }
1628
1629 private void restartRequests() {
1630 Log.i(TAG, "restartRequests");
1631
1632 restartLocationRequest();
Sasha Kuznetsova68a7a32020-02-11 06:00:10 +00001633 mGnssAntennaInfoProvider.resumeIfStarted();
Yu-Han Yang52057622018-04-25 00:51:22 -07001634 mGnssMeasurementsProvider.resumeIfStarted();
1635 mGnssNavigationMessageProvider.resumeIfStarted();
1636 mGnssBatchingProvider.resumeIfStarted();
1637 mGnssGeofenceProvider.resumeIfStarted();
1638 }
1639
1640 private void restartLocationRequest() {
1641 if (DEBUG) Log.d(TAG, "restartLocationRequest");
WyattRileyba6072f2019-04-18 07:37:52 -07001642 setStarted(false);
Yu-Han Yang52057622018-04-25 00:51:22 -07001643 updateRequirements();
1644 }
Wyatt Rileyd87cf912017-12-05 09:31:52 -08001645
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001646 @NativeEntryPoint
Wyatt Rileyd87cf912017-12-05 09:31:52 -08001647 private void setGnssYearOfHardware(final int yearOfHardware) {
1648 // mHardwareYear is simply set here, to be read elsewhere, and is volatile for safe sync
1649 if (DEBUG) Log.d(TAG, "setGnssYearOfHardware called with " + yearOfHardware);
1650 mHardwareYear = yearOfHardware;
Mike Lockwood04598b62010-04-14 17:17:24 -04001651 }
1652
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001653 @NativeEntryPoint
Wyatt Rileyd87cf912017-12-05 09:31:52 -08001654 private void setGnssHardwareModelName(final String modelName) {
1655 // mHardwareModelName is simply set here, to be read elsewhere, and volatile for safe sync
1656 if (DEBUG) Log.d(TAG, "setGnssModelName called with " + modelName);
1657 mHardwareModelName = modelName;
Lifu Tang82f893d2016-01-21 18:15:33 -08001658 }
1659
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001660 @NativeEntryPoint
Yu-Han Yang52057622018-04-25 00:51:22 -07001661 private void reportGnssServiceDied() {
1662 if (DEBUG) Log.d(TAG, "reportGnssServiceDied");
1663 mHandler.post(() -> {
Anil Admal0c2b21bd2019-05-03 18:29:02 -07001664 setupNativeGnssService(/* reinitializeGnssServiceHandle = */ true);
Anil Admal204406f2019-07-23 12:00:23 -07001665 // resend configuration into the restarted HAL service.
1666 reloadGpsProperties();
Yu-Han Yang76f99952019-05-04 17:45:44 -07001667 if (isGpsEnabled()) {
1668 setGpsEnabled(false);
Soonil Nagarkar35c3b912019-01-31 10:31:24 -08001669 updateEnabled();
Yu-Han Yang52057622018-04-25 00:51:22 -07001670 }
1671 });
1672 }
1673
Lifu Tang9363b942016-02-16 18:07:00 -08001674 public interface GnssSystemInfoProvider {
Lifu Tang82f893d2016-01-21 18:15:33 -08001675 /**
Wyatt Rileyd87cf912017-12-05 09:31:52 -08001676 * Returns the year of underlying GPS hardware.
Lifu Tang82f893d2016-01-21 18:15:33 -08001677 */
Lifu Tang9363b942016-02-16 18:07:00 -08001678 int getGnssYearOfHardware();
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001679
Wyatt Rileyd87cf912017-12-05 09:31:52 -08001680 /**
1681 * Returns the model name of underlying GPS hardware.
1682 */
1683 String getGnssHardwareModelName();
Lifu Tang82f893d2016-01-21 18:15:33 -08001684 }
1685
1686 /**
1687 * @hide
1688 */
Lifu Tang9363b942016-02-16 18:07:00 -08001689 public GnssSystemInfoProvider getGnssSystemInfoProvider() {
1690 return new GnssSystemInfoProvider() {
Lifu Tang82f893d2016-01-21 18:15:33 -08001691 @Override
Lifu Tang9363b942016-02-16 18:07:00 -08001692 public int getGnssYearOfHardware() {
Wyatt Rileyd87cf912017-12-05 09:31:52 -08001693 return mHardwareYear;
1694 }
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001695
Wyatt Rileyd87cf912017-12-05 09:31:52 -08001696 @Override
1697 public String getGnssHardwareModelName() {
1698 return mHardwareModelName;
Lifu Tang82f893d2016-01-21 18:15:33 -08001699 }
1700 };
1701 }
1702
Wyatt Rileycf879db2017-01-12 13:57:38 -08001703 /**
1704 * @hide
1705 */
1706 public GnssBatchingProvider getGnssBatchingProvider() {
Yu-Han Yang3557cc72018-03-21 12:48:36 -07001707 return mGnssBatchingProvider;
Wyatt Rileycf879db2017-01-12 13:57:38 -08001708 }
1709
Siddharth Raybb608c82017-03-16 11:33:34 -07001710 public interface GnssMetricsProvider {
1711 /**
1712 * Returns GNSS metrics as proto string
1713 */
1714 String getGnssMetricsAsProtoString();
1715 }
1716
1717 /**
1718 * @hide
1719 */
1720 public GnssMetricsProvider getGnssMetricsProvider() {
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001721 return () -> mGnssMetrics.dumpGnssMetricsAsProtoString();
Siddharth Raybb608c82017-03-16 11:33:34 -07001722 }
1723
Anil Admal312fddb2019-03-25 12:15:43 -07001724 /**
1725 * @hide
1726 */
1727 public GnssCapabilitiesProvider getGnssCapabilitiesProvider() {
1728 return mGnssCapabilitiesProvider;
1729 }
1730
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001731 @NativeEntryPoint
Wyatt Rileycf879db2017-01-12 13:57:38 -08001732 private void reportLocationBatch(Location[] locationArray) {
1733 List<Location> locations = new ArrayList<>(Arrays.asList(locationArray));
gomo48f1a642017-11-10 20:35:46 -08001734 if (DEBUG) {
1735 Log.d(TAG, "Location batch of size " + locationArray.length + " reported");
1736 }
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001737 reportLocation(locations);
Wyatt Rileycf879db2017-01-12 13:57:38 -08001738 }
1739
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001740 @NativeEntryPoint
Kevin Tang8c6ac672019-03-22 12:31:01 -07001741 private void psdsDownloadRequest() {
1742 if (DEBUG) Log.d(TAG, "psdsDownloadRequest");
1743 sendMessage(DOWNLOAD_PSDS_DATA, 0, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001744 }
1745
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07001746 /**
destradaa0682809a2013-08-12 18:50:30 -07001747 * Converts the GPS HAL status to the internal Geofence Hardware status.
1748 */
Yu-Han Yang6dc9f052018-12-04 17:11:24 -08001749 private static int getGeofenceStatus(int status) {
gomo48f1a642017-11-10 20:35:46 -08001750 switch (status) {
destradaa0682809a2013-08-12 18:50:30 -07001751 case GPS_GEOFENCE_OPERATION_SUCCESS:
1752 return GeofenceHardware.GEOFENCE_SUCCESS;
1753 case GPS_GEOFENCE_ERROR_GENERIC:
1754 return GeofenceHardware.GEOFENCE_FAILURE;
1755 case GPS_GEOFENCE_ERROR_ID_EXISTS:
1756 return GeofenceHardware.GEOFENCE_ERROR_ID_EXISTS;
1757 case GPS_GEOFENCE_ERROR_INVALID_TRANSITION:
1758 return GeofenceHardware.GEOFENCE_ERROR_INVALID_TRANSITION;
1759 case GPS_GEOFENCE_ERROR_TOO_MANY_GEOFENCES:
1760 return GeofenceHardware.GEOFENCE_ERROR_TOO_MANY_GEOFENCES;
1761 case GPS_GEOFENCE_ERROR_ID_UNKNOWN:
1762 return GeofenceHardware.GEOFENCE_ERROR_ID_UNKNOWN;
1763 default:
1764 return -1;
1765 }
1766 }
1767
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001768 @NativeEntryPoint
Wyatt Riley5d229832017-02-10 17:06:00 -08001769 private void reportGeofenceTransition(int geofenceId, Location location, int transition,
gomo48f1a642017-11-10 20:35:46 -08001770 long transitionTimestamp) {
Yu-Han Yang6dc9f052018-12-04 17:11:24 -08001771 mHandler.post(() -> {
1772 if (mGeofenceHardwareImpl == null) {
1773 mGeofenceHardwareImpl = GeofenceHardwareImpl.getInstance(mContext);
1774 }
Wyatt Riley5d229832017-02-10 17:06:00 -08001775
Yu-Han Yang6dc9f052018-12-04 17:11:24 -08001776 mGeofenceHardwareImpl.reportGeofenceTransition(
1777 geofenceId,
1778 location,
1779 transition,
1780 transitionTimestamp,
1781 GeofenceHardware.MONITORING_TYPE_GPS_HARDWARE,
1782 FusedBatchOptions.SourceTechnologies.GNSS);
1783 });
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07001784 }
1785
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001786 @NativeEntryPoint
Wyatt Riley5d229832017-02-10 17:06:00 -08001787 private void reportGeofenceStatus(int status, Location location) {
Yu-Han Yang6dc9f052018-12-04 17:11:24 -08001788 mHandler.post(() -> {
1789 if (mGeofenceHardwareImpl == null) {
1790 mGeofenceHardwareImpl = GeofenceHardwareImpl.getInstance(mContext);
1791 }
1792 int monitorStatus = GeofenceHardware.MONITOR_CURRENTLY_UNAVAILABLE;
1793 if (status == GPS_GEOFENCE_AVAILABLE) {
1794 monitorStatus = GeofenceHardware.MONITOR_CURRENTLY_AVAILABLE;
1795 }
1796 mGeofenceHardwareImpl.reportGeofenceMonitorStatus(
1797 GeofenceHardware.MONITORING_TYPE_GPS_HARDWARE,
1798 monitorStatus,
1799 location,
1800 FusedBatchOptions.SourceTechnologies.GNSS);
1801 });
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07001802 }
1803
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001804 @NativeEntryPoint
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07001805 private void reportGeofenceAddStatus(int geofenceId, int status) {
Yu-Han Yang6dc9f052018-12-04 17:11:24 -08001806 mHandler.post(() -> {
1807 if (mGeofenceHardwareImpl == null) {
1808 mGeofenceHardwareImpl = GeofenceHardwareImpl.getInstance(mContext);
1809 }
1810 mGeofenceHardwareImpl.reportGeofenceAddStatus(geofenceId, getGeofenceStatus(status));
1811 });
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07001812 }
1813
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001814 @NativeEntryPoint
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07001815 private void reportGeofenceRemoveStatus(int geofenceId, int status) {
Yu-Han Yang6dc9f052018-12-04 17:11:24 -08001816 mHandler.post(() -> {
1817 if (mGeofenceHardwareImpl == null) {
1818 mGeofenceHardwareImpl = GeofenceHardwareImpl.getInstance(mContext);
1819 }
1820 mGeofenceHardwareImpl.reportGeofenceRemoveStatus(geofenceId, getGeofenceStatus(status));
1821 });
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07001822 }
1823
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001824 @NativeEntryPoint
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07001825 private void reportGeofencePauseStatus(int geofenceId, int status) {
Yu-Han Yang6dc9f052018-12-04 17:11:24 -08001826 mHandler.post(() -> {
1827 if (mGeofenceHardwareImpl == null) {
1828 mGeofenceHardwareImpl = GeofenceHardwareImpl.getInstance(mContext);
1829 }
1830 mGeofenceHardwareImpl.reportGeofencePauseStatus(geofenceId, getGeofenceStatus(status));
1831 });
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07001832 }
1833
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001834 @NativeEntryPoint
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07001835 private void reportGeofenceResumeStatus(int geofenceId, int status) {
Yu-Han Yang6dc9f052018-12-04 17:11:24 -08001836 mHandler.post(() -> {
1837 if (mGeofenceHardwareImpl == null) {
1838 mGeofenceHardwareImpl = GeofenceHardwareImpl.getInstance(mContext);
1839 }
1840 mGeofenceHardwareImpl.reportGeofenceResumeStatus(geofenceId, getGeofenceStatus(status));
1841 });
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07001842 }
1843
Danke Xie22d1f9f2009-08-18 18:28:45 -04001844 //=============================================================
1845 // NI Client support
Miguel Torroja1e84da82010-07-27 07:02:24 +02001846 //=============================================================
Danke Xie22d1f9f2009-08-18 18:28:45 -04001847 private final INetInitiatedListener mNetInitiatedListener = new INetInitiatedListener.Stub() {
destradaaef752b62015-04-17 13:10:47 -07001848 // Sends a response for an NI request to HAL.
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001849 @Override
gomo48f1a642017-11-10 20:35:46 -08001850 public boolean sendNiResponse(int notificationId, int userResponse) {
Miguel Torroja1e84da82010-07-27 07:02:24 +02001851 // TODO Add Permission check
Danke Xie22d1f9f2009-08-18 18:28:45 -04001852
gomo48f1a642017-11-10 20:35:46 -08001853 if (DEBUG) {
1854 Log.d(TAG, "sendNiResponse, notifId: " + notificationId +
1855 ", response: " + userResponse);
1856 }
Miguel Torroja1e84da82010-07-27 07:02:24 +02001857 native_send_ni_response(notificationId, userResponse);
Yu-Han Yang8a1b51d2018-12-26 22:18:31 -08001858
Muhammad Qureshi6f207102020-01-28 10:37:41 -08001859 FrameworkStatsLog.write(FrameworkStatsLog.GNSS_NI_EVENT_REPORTED,
1860 FrameworkStatsLog.GNSS_NI_EVENT_REPORTED__EVENT_TYPE__NI_RESPONSE,
Yu-Han Yang8a1b51d2018-12-26 22:18:31 -08001861 notificationId,
1862 /* niType= */ 0,
1863 /* needNotify= */ false,
1864 /* needVerify= */ false,
1865 /* privacyOverride= */ false,
1866 /* timeout= */ 0,
1867 /* defaultResponse= */ 0,
1868 /* requestorId= */ null,
1869 /* text= */ null,
1870 /* requestorIdEncoding= */ 0,
1871 /* textEncoding= */ 0,
1872 mSuplEsEnabled,
Yu-Han Yang76f99952019-05-04 17:45:44 -07001873 isGpsEnabled(),
Yu-Han Yang8a1b51d2018-12-26 22:18:31 -08001874 userResponse);
1875
Miguel Torroja1e84da82010-07-27 07:02:24 +02001876 return true;
1877 }
Danke Xie22d1f9f2009-08-18 18:28:45 -04001878 };
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001879
Danke Xie22d1f9f2009-08-18 18:28:45 -04001880 public INetInitiatedListener getNetInitiatedListener() {
1881 return mNetInitiatedListener;
1882 }
1883
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001884 /** Reports a NI notification. */
1885 @NativeEntryPoint
Miguel Torroja1e84da82010-07-27 07:02:24 +02001886 public void reportNiNotification(
1887 int notificationId,
1888 int niType,
1889 int notifyFlags,
1890 int timeout,
1891 int defaultResponse,
1892 String requestorId,
1893 String text,
1894 int requestorIdEncoding,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001895 int textEncoding
gomo48f1a642017-11-10 20:35:46 -08001896 ) {
Miguel Torroja1e84da82010-07-27 07:02:24 +02001897 Log.i(TAG, "reportNiNotification: entered");
1898 Log.i(TAG, "notificationId: " + notificationId +
1899 ", niType: " + niType +
1900 ", notifyFlags: " + notifyFlags +
1901 ", timeout: " + timeout +
1902 ", defaultResponse: " + defaultResponse);
1903
1904 Log.i(TAG, "requestorId: " + requestorId +
1905 ", text: " + text +
1906 ", requestorIdEncoding: " + requestorIdEncoding +
1907 ", textEncoding: " + textEncoding);
1908
1909 GpsNiNotification notification = new GpsNiNotification();
1910
1911 notification.notificationId = notificationId;
1912 notification.niType = niType;
1913 notification.needNotify = (notifyFlags & GpsNetInitiatedHandler.GPS_NI_NEED_NOTIFY) != 0;
1914 notification.needVerify = (notifyFlags & GpsNetInitiatedHandler.GPS_NI_NEED_VERIFY) != 0;
gomo48f1a642017-11-10 20:35:46 -08001915 notification.privacyOverride =
1916 (notifyFlags & GpsNetInitiatedHandler.GPS_NI_PRIVACY_OVERRIDE) != 0;
Miguel Torroja1e84da82010-07-27 07:02:24 +02001917 notification.timeout = timeout;
1918 notification.defaultResponse = defaultResponse;
1919 notification.requestorId = requestorId;
1920 notification.text = text;
1921 notification.requestorIdEncoding = requestorIdEncoding;
1922 notification.textEncoding = textEncoding;
1923
Miguel Torroja1e84da82010-07-27 07:02:24 +02001924 mNIHandler.handleNiNotification(notification);
Muhammad Qureshi6f207102020-01-28 10:37:41 -08001925 FrameworkStatsLog.write(FrameworkStatsLog.GNSS_NI_EVENT_REPORTED,
1926 FrameworkStatsLog.GNSS_NI_EVENT_REPORTED__EVENT_TYPE__NI_REQUEST,
Yu-Han Yang8a1b51d2018-12-26 22:18:31 -08001927 notification.notificationId,
1928 notification.niType,
1929 notification.needNotify,
1930 notification.needVerify,
1931 notification.privacyOverride,
1932 notification.timeout,
1933 notification.defaultResponse,
1934 notification.requestorId,
1935 notification.text,
1936 notification.requestorIdEncoding,
1937 notification.textEncoding,
1938 mSuplEsEnabled,
Yu-Han Yang76f99952019-05-04 17:45:44 -07001939 isGpsEnabled(),
Yu-Han Yang8a1b51d2018-12-26 22:18:31 -08001940 /* userResponse= */ 0);
Miguel Torroja1e84da82010-07-27 07:02:24 +02001941 }
1942
1943 /**
Miguel Torroja1e84da82010-07-27 07:02:24 +02001944 * We should be careful about receiving null string from the TelephonyManager,
1945 * because sending null String to JNI function would cause a crash.
1946 */
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001947 @NativeEntryPoint
Miguel Torroja1e84da82010-07-27 07:02:24 +02001948 private void requestSetID(int flags) {
1949 TelephonyManager phone = (TelephonyManager)
1950 mContext.getSystemService(Context.TELEPHONY_SERVICE);
destradaaef752b62015-04-17 13:10:47 -07001951 int type = AGPS_SETID_TYPE_NONE;
Anil Admale1539e82019-05-09 15:05:04 -07001952 String setId = null;
Miguel Torroja1e84da82010-07-27 07:02:24 +02001953
Anil Admale1539e82019-05-09 15:05:04 -07001954 int ddSubId = SubscriptionManager.getDefaultDataSubscriptionId();
zoey chen4841a272019-12-03 20:07:18 +08001955 if (SubscriptionManager.isValidSubscriptionId(ddSubId)) {
1956 phone = phone.createForSubscriptionId(ddSubId);
1957 }
Miguel Torroja1e84da82010-07-27 07:02:24 +02001958 if ((flags & AGPS_RIL_REQUEST_SETID_IMSI) == AGPS_RIL_REQUEST_SETID_IMSI) {
zoey chen4841a272019-12-03 20:07:18 +08001959 setId = phone.getSubscriberId();
Anil Admale1539e82019-05-09 15:05:04 -07001960 if (setId != null) {
Miguel Torroja1e84da82010-07-27 07:02:24 +02001961 // This means the framework has the SIM card.
Miguel Torroja1e84da82010-07-27 07:02:24 +02001962 type = AGPS_SETID_TYPE_IMSI;
1963 }
gomo48f1a642017-11-10 20:35:46 -08001964 } else if ((flags & AGPS_RIL_REQUEST_SETID_MSISDN) == AGPS_RIL_REQUEST_SETID_MSISDN) {
zoey chen4841a272019-12-03 20:07:18 +08001965 setId = phone.getLine1Number();
Anil Admale1539e82019-05-09 15:05:04 -07001966 if (setId != null) {
Miguel Torroja1e84da82010-07-27 07:02:24 +02001967 // This means the framework has the SIM card.
Miguel Torroja1e84da82010-07-27 07:02:24 +02001968 type = AGPS_SETID_TYPE_MSISDN;
1969 }
1970 }
Anil Admale1539e82019-05-09 15:05:04 -07001971
1972 native_agps_set_id(type, (setId == null) ? "" : setId);
Miguel Torroja1e84da82010-07-27 07:02:24 +02001973 }
1974
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001975 @NativeEntryPoint
Yu-Han Yang53f4d6d2019-02-13 21:47:41 -08001976 private void requestLocation(boolean independentFromGnss, boolean isUserEmergency) {
Yu-Han Yange7baef32018-02-09 13:58:17 -08001977 if (DEBUG) {
Yu-Han Yang53f4d6d2019-02-13 21:47:41 -08001978 Log.d(TAG, "requestLocation. independentFromGnss: " + independentFromGnss
1979 + ", isUserEmergency: "
1980 + isUserEmergency);
Yu-Han Yange7baef32018-02-09 13:58:17 -08001981 }
Yu-Han Yang53f4d6d2019-02-13 21:47:41 -08001982 sendMessage(REQUEST_LOCATION, independentFromGnss ? 1 : 0, isUserEmergency);
Yu-Han Yange7baef32018-02-09 13:58:17 -08001983 }
1984
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001985 @NativeEntryPoint
Mike Lockwood9b9fb5c2011-06-29 15:09:40 -04001986 private void requestUtcTime() {
destradaae21252a2015-09-08 12:32:59 -07001987 if (DEBUG) Log.d(TAG, "utcTimeRequest");
Mike Lockwood9b9fb5c2011-06-29 15:09:40 -04001988 sendMessage(INJECT_NTP_TIME, 0, null);
1989 }
1990
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001991 @NativeEntryPoint
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001992 private void requestRefLocation() {
Miguel Torroja1e84da82010-07-27 07:02:24 +02001993 TelephonyManager phone = (TelephonyManager)
1994 mContext.getSystemService(Context.TELEPHONY_SERVICE);
Victoria Leased50d0c32012-10-29 13:16:17 -07001995 final int phoneType = phone.getPhoneType();
1996 if (phoneType == TelephonyManager.PHONE_TYPE_GSM) {
Miguel Torroja1e84da82010-07-27 07:02:24 +02001997 GsmCellLocation gsm_cell = (GsmCellLocation) phone.getCellLocation();
Victoria Leased50d0c32012-10-29 13:16:17 -07001998 if ((gsm_cell != null) && (phone.getNetworkOperator() != null)
1999 && (phone.getNetworkOperator().length() > 3)) {
Miguel Torroja1e84da82010-07-27 07:02:24 +02002000 int type;
gomo48f1a642017-11-10 20:35:46 -08002001 int mcc = Integer.parseInt(phone.getNetworkOperator().substring(0, 3));
Miguel Torroja1e84da82010-07-27 07:02:24 +02002002 int mnc = Integer.parseInt(phone.getNetworkOperator().substring(3));
Mike Lockwoodedc0f3872010-10-22 09:16:17 -04002003 int networkType = phone.getNetworkType();
2004 if (networkType == TelephonyManager.NETWORK_TYPE_UMTS
gomo48f1a642017-11-10 20:35:46 -08002005 || networkType == TelephonyManager.NETWORK_TYPE_HSDPA
2006 || networkType == TelephonyManager.NETWORK_TYPE_HSUPA
2007 || networkType == TelephonyManager.NETWORK_TYPE_HSPA
2008 || networkType == TelephonyManager.NETWORK_TYPE_HSPAP) {
Miguel Torroja1e84da82010-07-27 07:02:24 +02002009 type = AGPS_REF_LOCATION_TYPE_UMTS_CELLID;
Mike Lockwoodedc0f3872010-10-22 09:16:17 -04002010 } else {
Miguel Torroja1e84da82010-07-27 07:02:24 +02002011 type = AGPS_REF_LOCATION_TYPE_GSM_CELLID;
Mike Lockwoodedc0f3872010-10-22 09:16:17 -04002012 }
Miguel Torroja1e84da82010-07-27 07:02:24 +02002013 native_agps_set_ref_location_cellid(type, mcc, mnc,
2014 gsm_cell.getLac(), gsm_cell.getCid());
Mike Lockwoodedc0f3872010-10-22 09:16:17 -04002015 } else {
gomo48f1a642017-11-10 20:35:46 -08002016 Log.e(TAG, "Error getting cell location info.");
Mike Lockwoodedc0f3872010-10-22 09:16:17 -04002017 }
Victoria Leased50d0c32012-10-29 13:16:17 -07002018 } else if (phoneType == TelephonyManager.PHONE_TYPE_CDMA) {
2019 Log.e(TAG, "CDMA not supported.");
Mike Lockwoodedc0f3872010-10-22 09:16:17 -04002020 }
Miguel Torroja1e84da82010-07-27 07:02:24 +02002021 }
Danke Xie22d1f9f2009-08-18 18:28:45 -04002022
Anil Admal94ec76a2019-01-15 09:42:01 -08002023 // Implements method nfwNotifyCb() in IGnssVisibilityControlCallback.hal.
2024 @NativeEntryPoint
2025 private void reportNfwNotification(String proxyAppPackageName, byte protocolStack,
2026 String otherProtocolStackName, byte requestor, String requestorId, byte responseType,
2027 boolean inEmergencyMode, boolean isCachedLocation) {
2028 if (mGnssVisibilityControl == null) {
2029 Log.e(TAG, "reportNfwNotification: mGnssVisibilityControl is not initialized.");
2030 return;
2031 }
2032
2033 mGnssVisibilityControl.reportNfwNotification(proxyAppPackageName, protocolStack,
2034 otherProtocolStackName, requestor, requestorId, responseType, inEmergencyMode,
2035 isCachedLocation);
2036 }
2037
2038 // Implements method isInEmergencySession() in IGnssVisibilityControlCallback.hal.
2039 @NativeEntryPoint
2040 boolean isInEmergencySession() {
2041 return mNIHandler.getInEmergency();
2042 }
2043
Mike Lockwood98e48692010-04-07 16:32:51 -04002044 private void sendMessage(int message, int arg, Object obj) {
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002045 // hold a wake lock until this message is delivered
Jeff Brown028872f2012-08-25 13:07:01 -07002046 // note that this assumes the message will not be removed from the queue before
2047 // it is handled (otherwise the wake lock would be leaked).
Yu-Han Yang499a6ba2019-11-14 14:19:13 -08002048 mWakeLock.acquire(WAKELOCK_TIMEOUT_MILLIS);
Anil Admal4f97c942018-11-12 10:52:46 -08002049 if (DEBUG) {
2050 Log.d(TAG, "WakeLock acquired by sendMessage(" + messageIdAsString(message) + ", " + arg
Wyatt Rileycf879db2017-01-12 13:57:38 -08002051 + ", " + obj + ")");
2052 }
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002053 mHandler.obtainMessage(message, arg, 1, obj).sendToTarget();
Mike Lockwood98e48692010-04-07 16:32:51 -04002054 }
2055
Mike Lockwood62a8fc12010-03-22 14:23:26 -04002056 private final class ProviderHandler extends Handler {
Victoria Lease5cd731a2012-12-19 15:04:21 -08002057 public ProviderHandler(Looper looper) {
2058 super(looper, null, true /*async*/);
Jeff Brown028872f2012-08-25 13:07:01 -07002059 }
2060
Mike Lockwood62a8fc12010-03-22 14:23:26 -04002061 @Override
Mike Lockwood4a7b65e2010-10-25 16:35:55 -04002062 public void handleMessage(Message msg) {
Mike Lockwood98e48692010-04-07 16:32:51 -04002063 int message = msg.what;
2064 switch (message) {
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002065 case SET_REQUEST:
2066 GpsRequest gpsRequest = (GpsRequest) msg.obj;
2067 handleSetRequest(gpsRequest.request, gpsRequest.source);
Mike Lockwood03ca2162010-04-01 08:10:09 -07002068 break;
Mike Lockwood62a8fc12010-03-22 14:23:26 -04002069 case INJECT_NTP_TIME:
Yu-Han Yanga1862b52018-02-20 17:05:59 -08002070 mNtpTimeHelper.retrieveAndInjectNtpTime();
Mike Lockwood62a8fc12010-03-22 14:23:26 -04002071 break;
Yu-Han Yange7baef32018-02-09 13:58:17 -08002072 case REQUEST_LOCATION:
Yu-Han Yang53f4d6d2019-02-13 21:47:41 -08002073 handleRequestLocation(msg.arg1 == 1, (boolean) msg.obj);
Yu-Han Yange7baef32018-02-09 13:58:17 -08002074 break;
Kevin Tang8c6ac672019-03-22 12:31:01 -07002075 case DOWNLOAD_PSDS_DATA:
2076 handleDownloadPsdsData();
Mike Lockwood62a8fc12010-03-22 14:23:26 -04002077 break;
Kevin Tang8c6ac672019-03-22 12:31:01 -07002078 case DOWNLOAD_PSDS_DATA_FINISHED:
2079 mDownloadPsdsDataPending = STATE_IDLE;
Kevin Tang40e1baf2012-01-10 14:32:44 -08002080 break;
destradaafb23c672015-04-16 14:01:27 -07002081 case INITIALIZE_HANDLER:
destradaae21252a2015-09-08 12:32:59 -07002082 handleInitialize();
destradaafb23c672015-04-16 14:01:27 -07002083 break;
Wyatt Riley26465d22018-02-12 13:44:24 -08002084 case REPORT_LOCATION:
2085 handleReportLocation(msg.arg1 == 1, (Location) msg.obj);
2086 break;
2087 case REPORT_SV_STATUS:
2088 handleReportSvStatus((SvStatusInfo) msg.obj);
2089 break;
Kweku Adams810c77d2019-08-28 07:45:00 -07002090 case UPDATE_LOW_POWER_MODE:
2091 updateLowPowerMode();
2092 break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002093 }
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002094 if (msg.arg2 == 1) {
2095 // wakelock was taken for this message, release it
2096 mWakeLock.release();
Anil Admal4f97c942018-11-12 10:52:46 -08002097 if (DEBUG) {
2098 Log.d(TAG, "WakeLock released by handleMessage(" + messageIdAsString(message)
Wyatt Rileycf879db2017-01-12 13:57:38 -08002099 + ", " + msg.arg1 + ", " + msg.obj + ")");
2100 }
Mike Lockwood98e48692010-04-07 16:32:51 -04002101 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002102 }
destradaafb23c672015-04-16 14:01:27 -07002103
2104 /**
Soonil Nagarkar8df02f42020-01-08 13:23:26 -08002105 * This method is bound to the constructor. It is in charge of loading properties and
2106 * registering for events that will be posted to this handler.
destradaafb23c672015-04-16 14:01:27 -07002107 */
destradaae21252a2015-09-08 12:32:59 -07002108 private void handleInitialize() {
Anil Admal0c2b21bd2019-05-03 18:29:02 -07002109 // class_init_native() already initializes the GNSS service handle during class loading.
2110 setupNativeGnssService(/* reinitializeGnssServiceHandle = */ false);
Wyatt Riley523a0cf2017-10-31 14:36:52 -07002111
Anil Admal94ec76a2019-01-15 09:42:01 -08002112 if (native_is_gnss_visibility_control_supported()) {
Anil Admal8a246a22019-05-05 00:34:55 -07002113 mGnssVisibilityControl = new GnssVisibilityControl(mContext, mLooper, mNIHandler);
Anil Admal94ec76a2019-01-15 09:42:01 -08002114 }
2115
destradaafb23c672015-04-16 14:01:27 -07002116 // load default GPS configuration
2117 // (this configuration might change in the future based on SIM changes)
Anil Admald71cf142018-12-21 14:59:36 -08002118 reloadGpsProperties();
destradaafb23c672015-04-16 14:01:27 -07002119
destradaafb23c672015-04-16 14:01:27 -07002120 // listen for events
WyattRiley6593cf12018-06-23 10:37:48 -07002121 IntentFilter intentFilter = new IntentFilter();
destradaafb23c672015-04-16 14:01:27 -07002122 intentFilter.addAction(ALARM_WAKEUP);
2123 intentFilter.addAction(ALARM_TIMEOUT);
destradaafb23c672015-04-16 14:01:27 -07002124 intentFilter.addAction(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED);
Adam Lesinski87c17df2015-05-27 13:24:13 -07002125 intentFilter.addAction(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED);
destradaafb23c672015-04-16 14:01:27 -07002126 intentFilter.addAction(Intent.ACTION_SCREEN_OFF);
2127 intentFilter.addAction(Intent.ACTION_SCREEN_ON);
Meng Wang19b214d2018-11-07 12:14:39 -08002128 intentFilter.addAction(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
Jayachandran C041e7692019-12-20 16:20:02 -08002129 intentFilter.addAction(TelephonyManager.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED);
destradaafb23c672015-04-16 14:01:27 -07002130 mContext.registerReceiver(mBroadcastReceiver, intentFilter, null, this);
2131
Anil Admal50ba15e2018-11-01 16:42:42 -07002132 mNetworkConnectivityHandler.registerNetworkCallbacks();
destradaae21252a2015-09-08 12:32:59 -07002133
destradaafb23c672015-04-16 14:01:27 -07002134 // listen for PASSIVE_PROVIDER updates
2135 LocationManager locManager =
2136 (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE);
2137 long minTime = 0;
2138 float minDistance = 0;
destradaafb23c672015-04-16 14:01:27 -07002139 LocationRequest request = LocationRequest.createFromDeprecatedProvider(
2140 LocationManager.PASSIVE_PROVIDER,
2141 minTime,
2142 minDistance,
Soonil Nagarkar1575a042018-10-24 17:54:54 -07002143 false);
destradaafb23c672015-04-16 14:01:27 -07002144 // Don't keep track of this request since it's done on behalf of other clients
2145 // (which are kept track of separately).
2146 request.setHideFromAppOps(true);
2147 locManager.requestLocationUpdates(
2148 request,
2149 new NetworkLocationListener(),
2150 getLooper());
Soonil Nagarkar1575a042018-10-24 17:54:54 -07002151
Soonil Nagarkar35c3b912019-01-31 10:31:24 -08002152 updateEnabled();
destradaafb23c672015-04-16 14:01:27 -07002153 }
2154 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002155
Yu-Han Yange7baef32018-02-09 13:58:17 -08002156 private abstract class LocationChangeListener implements LocationListener {
Soonil Nagarkar1575a042018-10-24 17:54:54 -07002157 private int mNumLocationUpdateRequest;
Yu-Han Yang07561382018-02-21 13:08:37 -08002158
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002159 @Override
gomo48f1a642017-11-10 20:35:46 -08002160 public void onStatusChanged(String provider, int status, Bundle extras) {
2161 }
2162
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002163 @Override
gomo48f1a642017-11-10 20:35:46 -08002164 public void onProviderEnabled(String provider) {
2165 }
2166
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002167 @Override
gomo48f1a642017-11-10 20:35:46 -08002168 public void onProviderDisabled(String provider) {
2169 }
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002170 }
2171
Yu-Han Yange7baef32018-02-09 13:58:17 -08002172 private final class NetworkLocationListener extends LocationChangeListener {
2173 @Override
2174 public void onLocationChanged(Location location) {
2175 // this callback happens on mHandler looper
2176 if (LocationManager.NETWORK_PROVIDER.equals(location.getProvider())) {
Anil Admal2ac70462019-06-28 19:17:41 -07002177 injectLocation(location);
Yu-Han Yange7baef32018-02-09 13:58:17 -08002178 }
2179 }
2180 }
2181
2182 private final class FusedLocationListener extends LocationChangeListener {
2183 @Override
2184 public void onLocationChanged(Location location) {
2185 if (LocationManager.FUSED_PROVIDER.equals(location.getProvider())) {
Yu-Han Yange7baef32018-02-09 13:58:17 -08002186 injectBestLocation(location);
2187 }
2188 }
2189 }
2190
Wyatt Rileycf879db2017-01-12 13:57:38 -08002191 /**
2192 * @return A string representing the given message ID.
2193 */
2194 private String messageIdAsString(int message) {
2195 switch (message) {
Wyatt Rileycf879db2017-01-12 13:57:38 -08002196 case SET_REQUEST:
2197 return "SET_REQUEST";
Wyatt Rileycf879db2017-01-12 13:57:38 -08002198 case INJECT_NTP_TIME:
2199 return "INJECT_NTP_TIME";
Yu-Han Yange7baef32018-02-09 13:58:17 -08002200 case REQUEST_LOCATION:
2201 return "REQUEST_LOCATION";
Kevin Tang8c6ac672019-03-22 12:31:01 -07002202 case DOWNLOAD_PSDS_DATA:
2203 return "DOWNLOAD_PSDS_DATA";
2204 case DOWNLOAD_PSDS_DATA_FINISHED:
2205 return "DOWNLOAD_PSDS_DATA_FINISHED";
Wyatt Rileycf879db2017-01-12 13:57:38 -08002206 case INITIALIZE_HANDLER:
2207 return "INITIALIZE_HANDLER";
Wyatt Riley26465d22018-02-12 13:44:24 -08002208 case REPORT_LOCATION:
2209 return "REPORT_LOCATION";
2210 case REPORT_SV_STATUS:
2211 return "REPORT_SV_STATUS";
Wyatt Rileycf879db2017-01-12 13:57:38 -08002212 default:
2213 return "<Unknown>";
2214 }
2215 }
2216
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002217 @Override
2218 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2219 StringBuilder s = new StringBuilder();
Soonil Nagarkar1c572552019-07-10 13:31:47 -07002220 s.append("mStarted=").append(mStarted).append(" (changed ");
WyattRileyba6072f2019-04-18 07:37:52 -07002221 TimeUtils.formatDuration(SystemClock.elapsedRealtime()
2222 - mStartedChangedElapsedRealtime, s);
2223 s.append(" ago)").append('\n');
Soonil Nagarkar1c572552019-07-10 13:31:47 -07002224 s.append("mFixInterval=").append(mFixInterval).append('\n');
2225 s.append("mLowPowerMode=").append(mLowPowerMode).append('\n');
Sasha Kuznetsova68a7a32020-02-11 06:00:10 +00002226 s.append("mGnssAntennaInfoProvider.isRegistered()=")
2227 .append(mGnssAntennaInfoProvider.isRegistered()).append('\n');
Soonil Nagarkar1c572552019-07-10 13:31:47 -07002228 s.append("mGnssMeasurementsProvider.isRegistered()=")
Wyatt Riley74479bd2018-01-17 08:48:27 -08002229 .append(mGnssMeasurementsProvider.isRegistered()).append('\n');
Soonil Nagarkar1c572552019-07-10 13:31:47 -07002230 s.append("mGnssNavigationMessageProvider.isRegistered()=")
Wyatt Riley74479bd2018-01-17 08:48:27 -08002231 .append(mGnssNavigationMessageProvider.isRegistered()).append('\n');
Soonil Nagarkar1c572552019-07-10 13:31:47 -07002232 s.append("mDisableGpsForPowerManager=").append(mDisableGpsForPowerManager).append('\n');
2233 s.append("mTopHalCapabilities=0x").append(Integer.toHexString(mTopHalCapabilities));
destradaa25e8caf2015-08-24 14:14:44 -07002234 s.append(" ( ");
2235 if (hasCapability(GPS_CAPABILITY_SCHEDULING)) s.append("SCHEDULING ");
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002236 if (hasCapability(GPS_CAPABILITY_MSB)) s.append("MSB ");
2237 if (hasCapability(GPS_CAPABILITY_MSA)) s.append("MSA ");
2238 if (hasCapability(GPS_CAPABILITY_SINGLE_SHOT)) s.append("SINGLE_SHOT ");
2239 if (hasCapability(GPS_CAPABILITY_ON_DEMAND_TIME)) s.append("ON_DEMAND_TIME ");
destradaa25e8caf2015-08-24 14:14:44 -07002240 if (hasCapability(GPS_CAPABILITY_GEOFENCING)) s.append("GEOFENCING ");
2241 if (hasCapability(GPS_CAPABILITY_MEASUREMENTS)) s.append("MEASUREMENTS ");
2242 if (hasCapability(GPS_CAPABILITY_NAV_MESSAGES)) s.append("NAV_MESSAGES ");
Anil Admalefd9dc62019-03-12 17:39:20 -07002243 if (hasCapability(GPS_CAPABILITY_LOW_POWER_MODE)) s.append("LOW_POWER_MODE ");
2244 if (hasCapability(GPS_CAPABILITY_SATELLITE_BLACKLIST)) s.append("SATELLITE_BLACKLIST ");
Anil Admal62c42dc2019-04-03 15:39:22 -07002245 if (hasCapability(GPS_CAPABILITY_MEASUREMENT_CORRECTIONS)) {
2246 s.append("MEASUREMENT_CORRECTIONS ");
2247 }
Sasha Kuznetsov213bb702020-02-14 16:14:39 -08002248 if (hasCapability(GPS_CAPABILITY_ANTENNA_INFO)) s.append("ANTENNA_INFO ");
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002249 s.append(")\n");
Anil Admal3ba0fa92019-04-19 17:43:00 -07002250 if (hasCapability(GPS_CAPABILITY_MEASUREMENT_CORRECTIONS)) {
Soonil Nagarkar1c572552019-07-10 13:31:47 -07002251 s.append("SubHal=MEASUREMENT_CORRECTIONS[");
Anil Admalefd9dc62019-03-12 17:39:20 -07002252 s.append(mGnssMeasurementCorrectionsProvider.toStringCapabilities());
2253 s.append("]\n");
2254 }
Siddharth Raybb608c82017-03-16 11:33:34 -07002255 s.append(mGnssMetrics.dumpGnssMetricsAsText());
Soonil Nagarkar1c572552019-07-10 13:31:47 -07002256 s.append("native internal state: \n");
2257 s.append(" ").append(native_get_internal_state());
Wyatt Rileycf879db2017-01-12 13:57:38 -08002258 s.append("\n");
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002259 pw.append(s);
2260 }
2261
Anil Admal0c2b21bd2019-05-03 18:29:02 -07002262 private void setupNativeGnssService(boolean reinitializeGnssServiceHandle) {
2263 native_init_once(reinitializeGnssServiceHandle);
Anil Admal7e3953b2019-05-04 20:45:22 -07002264
2265 /*
2266 * A cycle of native_init() and native_cleanup() is needed so that callbacks are
2267 * registered after bootup even when location is disabled.
2268 * This will allow Emergency SUPL to work even when location is disabled before device
2269 * restart.
2270 */
2271 boolean isInitialized = native_init();
2272 if (!isInitialized) {
2273 Log.w(TAG, "Native initialization failed.");
2274 } else {
2275 native_cleanup();
2276 }
2277 }
2278
Mike Lockwoodb16e7802009-08-06 09:26:02 -04002279 // preallocated to avoid memory allocation in reportNmea()
2280 private byte[] mNmeaBuffer = new byte[120];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002281
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002282 private static native void class_init_native();
gomo48f1a642017-11-10 20:35:46 -08002283
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002284 private static native boolean native_is_supported();
gomo48f1a642017-11-10 20:35:46 -08002285
Anil Admal94ec76a2019-01-15 09:42:01 -08002286 private static native boolean native_is_gnss_visibility_control_supported();
2287
Anil Admal0c2b21bd2019-05-03 18:29:02 -07002288 private static native void native_init_once(boolean reinitializeGnssServiceHandle);
Yu-Han Yang6d317352018-03-15 11:53:01 -07002289
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002290 private native boolean native_init();
gomo48f1a642017-11-10 20:35:46 -08002291
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002292 private native void native_cleanup();
gomo48f1a642017-11-10 20:35:46 -08002293
Mike Lockwood04598b62010-04-14 17:17:24 -04002294 private native boolean native_set_position_mode(int mode, int recurrence, int min_interval,
gomo48f1a642017-11-10 20:35:46 -08002295 int preferred_accuracy, int preferred_time, boolean lowPowerMode);
2296
Mike Lockwood04598b62010-04-14 17:17:24 -04002297 private native boolean native_start();
gomo48f1a642017-11-10 20:35:46 -08002298
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002299 private native boolean native_stop();
gomo48f1a642017-11-10 20:35:46 -08002300
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002301 private native void native_delete_aiding_data(int flags);
gomo48f1a642017-11-10 20:35:46 -08002302
Mike Lockwoodf602d362010-06-20 14:28:16 -07002303 private native int native_read_nmea(byte[] buffer, int bufferSize);
gomo48f1a642017-11-10 20:35:46 -08002304
Yu-Han Yange7baef32018-02-09 13:58:17 -08002305 private native void native_inject_best_location(
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -08002306 int gnssLocationFlags, double latitudeDegrees, double longitudeDegrees,
2307 double altitudeMeters, float speedMetersPerSec, float bearingDegrees,
2308 float horizontalAccuracyMeters, float verticalAccuracyMeters,
2309 float speedAccuracyMetersPerSecond, float bearingAccuracyDegrees,
Pierre Fite-Georgel9e96c572019-02-25 16:12:53 -08002310 long timestamp, int elapsedRealtimeFlags, long elapsedRealtimeNanos,
Yu-Han Yang3cd9a862019-03-25 17:00:03 -07002311 double elapsedRealtimeUncertaintyNanos);
Yu-Han Yange7baef32018-02-09 13:58:17 -08002312
Mike Lockwoodd26ce0d2009-06-11 12:25:46 -04002313 private native void native_inject_location(double latitude, double longitude, float accuracy);
2314
Kevin Tang8c6ac672019-03-22 12:31:01 -07002315 // PSDS Support
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002316 private native void native_inject_time(long time, long timeReference, int uncertainty);
gomo48f1a642017-11-10 20:35:46 -08002317
Kevin Tang8c6ac672019-03-22 12:31:01 -07002318 private native boolean native_supports_psds();
gomo48f1a642017-11-10 20:35:46 -08002319
Kevin Tang8c6ac672019-03-22 12:31:01 -07002320 private native void native_inject_psds_data(byte[] data, int length);
The Android Open Source Project10592532009-03-18 17:39:46 -07002321
Fred Fettinger3c8fbdf2010-01-04 15:38:13 -06002322 // DEBUG Support
2323 private native String native_get_internal_state();
2324
2325 // AGPS Support
gomo48f1a642017-11-10 20:35:46 -08002326 private native void native_agps_ni_message(byte[] msg, int length);
2327
Mike Lockwooda9e54612009-06-19 14:54:42 -04002328 private native void native_set_agps_server(int type, String hostname, int port);
Danke Xie22d1f9f2009-08-18 18:28:45 -04002329
2330 // Network-initiated (NI) Support
2331 private native void native_send_ni_response(int notificationId, int userResponse);
Miguel Torroja1e84da82010-07-27 07:02:24 +02002332
Anil Admal50ba15e2018-11-01 16:42:42 -07002333 // AGPS ril support
Miguel Torroja1e84da82010-07-27 07:02:24 +02002334 private native void native_agps_set_ref_location_cellid(int type, int mcc, int mnc,
2335 int lac, int cid);
gomo48f1a642017-11-10 20:35:46 -08002336
Miguel Torroja1e84da82010-07-27 07:02:24 +02002337 private native void native_agps_set_id(int type, String setid);
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -08002338}