blob: bcac4730cb8b5c7f11ccc64a80974e7c95fd768f [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Mike Lockwood00b74272010-03-26 10:41:48 -040017package com.android.server.location;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080018
Mike Lockwood29c84342009-05-06 14:01:15 -040019import android.app.AlarmManager;
Dianne Hackborna06de0f2012-12-11 16:34:47 -080020import android.app.AppOpsManager;
Mike Lockwood29c84342009-05-06 14:01:15 -040021import android.app.PendingIntent;
The Android Open Source Project10592532009-03-18 17:39:46 -070022import android.content.BroadcastReceiver;
Yu-Han Yang74041ff2018-04-06 15:57:31 -070023import android.content.ContentResolver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080024import android.content.Context;
25import android.content.Intent;
The Android Open Source Project10592532009-03-18 17:39:46 -070026import android.content.IntentFilter;
Soonil Nagarkar35c3b912019-01-31 10:31:24 -080027import android.database.ContentObserver;
destradaa0682809a2013-08-12 18:50:30 -070028import android.hardware.location.GeofenceHardware;
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -070029import android.hardware.location.GeofenceHardwareImpl;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080030import android.location.Criteria;
destradaa0682809a2013-08-12 18:50:30 -070031import android.location.FusedBatchOptions;
Yu-Han Yange7baef32018-02-09 13:58:17 -080032import android.location.GnssMeasurementsEvent;
33import android.location.GnssNavigationMessage;
Lifu Tang30f95a72016-01-07 23:20:38 -080034import android.location.GnssStatus;
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -070035import android.location.IGpsGeofenceHardware;
Danke Xie22d1f9f2009-08-18 18:28:45 -040036import android.location.INetInitiatedListener;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080037import android.location.Location;
Nick Pelly6fa9ad42012-07-16 12:18:23 -070038import android.location.LocationListener;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080039import android.location.LocationManager;
Stan Chesnutt1d72d8c2013-04-15 19:18:02 -070040import android.location.LocationRequest;
Kevin Tang40e1baf2012-01-10 14:32:44 -080041import android.os.AsyncTask;
Dianne Hackborn91268cf2013-06-13 19:06:50 -070042import android.os.BatteryStats;
Mike Lockwood63aa5a62010-04-14 19:21:31 -040043import android.os.Binder;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080044import android.os.Bundle;
Mike Lockwood62a8fc12010-03-22 14:23:26 -040045import android.os.Handler;
Victoria Lease5cd731a2012-12-19 15:04:21 -080046import android.os.Looper;
Mike Lockwood62a8fc12010-03-22 14:23:26 -040047import android.os.Message;
Yu-Han Yange7baef32018-02-09 13:58:17 -080048import android.os.PersistableBundle;
Mike Lockwood0528b9b2009-05-07 10:12:54 -040049import android.os.PowerManager;
Yu-Han Yange7baef32018-02-09 13:58:17 -080050import android.os.PowerManager.ServiceType;
51import android.os.PowerSaveState;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080052import android.os.RemoteException;
Mike Lockwood2f82c4e2009-04-17 08:24:10 -040053import android.os.ServiceManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080054import android.os.SystemClock;
Colin Cross7c030ed2014-01-28 09:33:53 -080055import android.os.SystemProperties;
Dianne Hackborn5ac72a22012-08-29 18:32:08 -070056import android.os.UserHandle;
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -070057import android.os.WorkSource;
Narayan Kamath32684dd2018-01-08 17:32:51 +000058import android.os.WorkSource.WorkChain;
Mike Lockwoodbcab8df2009-06-25 16:39:09 -040059import android.provider.Settings;
Yu-Han Yange7baef32018-02-09 13:58:17 -080060import android.telephony.CarrierConfigManager;
Wink Savillea374c3d2014-11-11 11:48:04 -080061import android.telephony.SubscriptionManager;
Miguel Torroja1e84da82010-07-27 07:02:24 +020062import android.telephony.TelephonyManager;
63import android.telephony.gsm.GsmCellLocation;
Colin Cross7c030ed2014-01-28 09:33:53 -080064import android.text.TextUtils;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080065import android.util.Log;
WyattRileyba6072f2019-04-18 07:37:52 -070066import android.util.TimeUtils;
Yu-Han Yanga1862b52018-02-20 17:05:59 -080067
Anil Admal032aa812019-03-06 19:23:25 -080068import com.android.internal.annotations.GuardedBy;
Sasha Kuznetsovb9f26b42019-10-03 17:30:46 -070069import com.android.internal.annotations.VisibleForTesting;
jackqdyulei455e90a2017-02-09 15:29:16 -080070import com.android.internal.app.IBatteryStats;
71import com.android.internal.location.GpsNetInitiatedHandler;
72import com.android.internal.location.GpsNetInitiatedHandler.GpsNiNotification;
73import com.android.internal.location.ProviderProperties;
74import com.android.internal.location.ProviderRequest;
Yu-Han Yange7baef32018-02-09 13:58:17 -080075import com.android.internal.location.gnssmetrics.GnssMetrics;
Muhammad Qureshi6f207102020-01-28 10:37:41 -080076import com.android.internal.util.FrameworkStatsLog;
Kweku Adams810c77d2019-08-28 07:45:00 -070077import com.android.server.DeviceIdleInternal;
Soonil Nagarkarb6375a42020-01-29 15:23:06 -080078import com.android.server.FgThread;
Kweku Adams810c77d2019-08-28 07:45:00 -070079import com.android.server.LocalServices;
Yu-Han Yang66c7ea92018-03-11 17:17:15 -070080import com.android.server.location.GnssSatelliteBlacklistHelper.GnssSatelliteBlacklistCallback;
Yu-Han Yanga1862b52018-02-20 17:05:59 -080081import com.android.server.location.NtpTimeHelper.InjectNtpTimeCallback;
Yu-Han Yang66c7ea92018-03-11 17:17:15 -070082
Nick Pelly6fa9ad42012-07-16 12:18:23 -070083import java.io.FileDescriptor;
Nick Pelly6fa9ad42012-07-16 12:18:23 -070084import java.io.PrintWriter;
Soonil Nagarkar1575a042018-10-24 17:54:54 -070085import java.lang.annotation.ElementType;
86import java.lang.annotation.Retention;
87import java.lang.annotation.RetentionPolicy;
88import java.lang.annotation.Target;
Wyatt Rileycf879db2017-01-12 13:57:38 -080089import java.util.ArrayList;
Andreas Gampee6748ce2015-12-11 18:00:38 -080090import java.util.Arrays;
Wyatt Rileycf879db2017-01-12 13:57:38 -080091import java.util.List;
Yu-Han Yange7baef32018-02-09 13:58:17 -080092
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080093/**
gomo4402af62017-01-11 13:20:13 -080094 * A GNSS implementation of LocationProvider used by LocationManager.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080095 *
96 * {@hide}
97 */
Soonil Nagarkar1575a042018-10-24 17:54:54 -070098public class GnssLocationProvider extends AbstractLocationProvider implements
99 InjectNtpTimeCallback,
100 GnssSatelliteBlacklistCallback {
101
102 /**
103 * Indicates that this method is a native entry point. Useful purely for IDEs which can
104 * understand entry points, and thus eliminate incorrect warnings about methods not used.
105 */
106 @Target(ElementType.METHOD)
107 @Retention(RetentionPolicy.SOURCE)
108 private @interface NativeEntryPoint {
109 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800110
Lifu Tang30f95a72016-01-07 23:20:38 -0800111 private static final String TAG = "GnssLocationProvider";
Mike Lockwood29c84342009-05-06 14:01:15 -0400112
Brian Muramatsu1715cb32012-08-08 17:32:21 -0700113 private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
114 private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400115
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700116 private static final ProviderProperties PROPERTIES = new ProviderProperties(
Soonil Nagarkar8df02f42020-01-08 13:23:26 -0800117 /* requiresNetwork = */false,
118 /* requiresSatellite = */true,
119 /* requiresCell = */false,
120 /* hasMonetaryCost = */false,
121 /* supportAltitude = */true,
122 /* supportsSpeed = */true,
123 /* supportsBearing = */true,
124 Criteria.POWER_HIGH,
125 Criteria.ACCURACY_FINE);
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700126
gomo4402af62017-01-11 13:20:13 -0800127 // these need to match GnssPositionMode enum in IGnss.hal
The Android Open Source Project10592532009-03-18 17:39:46 -0700128 private static final int GPS_POSITION_MODE_STANDALONE = 0;
129 private static final int GPS_POSITION_MODE_MS_BASED = 1;
130 private static final int GPS_POSITION_MODE_MS_ASSISTED = 2;
131
gomo4402af62017-01-11 13:20:13 -0800132 // these need to match GnssPositionRecurrence enum in IGnss.hal
Mike Lockwood04598b62010-04-14 17:17:24 -0400133 private static final int GPS_POSITION_RECURRENCE_PERIODIC = 0;
134 private static final int GPS_POSITION_RECURRENCE_SINGLE = 1;
135
gomo4402af62017-01-11 13:20:13 -0800136 // these need to match GnssStatusValue enum in IGnssCallback.hal
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800137 private static final int GPS_STATUS_NONE = 0;
138 private static final int GPS_STATUS_SESSION_BEGIN = 1;
139 private static final int GPS_STATUS_SESSION_END = 2;
140 private static final int GPS_STATUS_ENGINE_ON = 3;
141 private static final int GPS_STATUS_ENGINE_OFF = 4;
142
gomo4402af62017-01-11 13:20:13 -0800143 // these need to match GnssLocationFlags enum in types.hal
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800144 private static final int LOCATION_INVALID = 0;
145 private static final int LOCATION_HAS_LAT_LONG = 1;
146 private static final int LOCATION_HAS_ALTITUDE = 2;
147 private static final int LOCATION_HAS_SPEED = 4;
148 private static final int LOCATION_HAS_BEARING = 8;
gomo4402af62017-01-11 13:20:13 -0800149 private static final int LOCATION_HAS_HORIZONTAL_ACCURACY = 16;
150 private static final int LOCATION_HAS_VERTICAL_ACCURACY = 32;
151 private static final int LOCATION_HAS_SPEED_ACCURACY = 64;
152 private static final int LOCATION_HAS_BEARING_ACCURACY = 128;
Mike Lockwoode3635c92009-05-11 08:38:02 -0400153
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -0800154 // these need to match ElapsedRealtimeFlags enum in types.hal
155 private static final int ELAPSED_REALTIME_HAS_TIMESTAMP_NS = 1;
Pierre Fite-Georgel9e96c572019-02-25 16:12:53 -0800156 private static final int ELAPSED_REALTIME_HAS_TIME_UNCERTAINTY_NS = 2;
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -0800157
gomo4402af62017-01-11 13:20:13 -0800158 // IMPORTANT - the GPS_DELETE_* symbols here must match GnssAidingData enum in IGnss.hal
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800159 private static final int GPS_DELETE_EPHEMERIS = 0x0001;
160 private static final int GPS_DELETE_ALMANAC = 0x0002;
161 private static final int GPS_DELETE_POSITION = 0x0004;
162 private static final int GPS_DELETE_TIME = 0x0008;
163 private static final int GPS_DELETE_IONO = 0x0010;
164 private static final int GPS_DELETE_UTC = 0x0020;
165 private static final int GPS_DELETE_HEALTH = 0x0040;
166 private static final int GPS_DELETE_SVDIR = 0x0080;
167 private static final int GPS_DELETE_SVSTEER = 0x0100;
168 private static final int GPS_DELETE_SADATA = 0x0200;
169 private static final int GPS_DELETE_RTI = 0x0400;
170 private static final int GPS_DELETE_CELLDB_INFO = 0x8000;
171 private static final int GPS_DELETE_ALL = 0xFFFF;
172
gomo4402af62017-01-11 13:20:13 -0800173 // The GPS_CAPABILITY_* flags must match Capabilities enum in IGnssCallback.hal
Mike Lockwood04598b62010-04-14 17:17:24 -0400174 private static final int GPS_CAPABILITY_SCHEDULING = 0x0000001;
175 private static final int GPS_CAPABILITY_MSB = 0x0000002;
176 private static final int GPS_CAPABILITY_MSA = 0x0000004;
177 private static final int GPS_CAPABILITY_SINGLE_SHOT = 0x0000008;
Mike Lockwood9b9fb5c2011-06-29 15:09:40 -0400178 private static final int GPS_CAPABILITY_ON_DEMAND_TIME = 0x0000010;
Anil Admalefd9dc62019-03-12 17:39:20 -0700179 public static final int GPS_CAPABILITY_GEOFENCING = 0x0000020;
gomo226b7b72018-12-12 16:49:39 -0800180 public static final int GPS_CAPABILITY_MEASUREMENTS = 0x0000040;
Anil Admalefd9dc62019-03-12 17:39:20 -0700181 public static final int GPS_CAPABILITY_NAV_MESSAGES = 0x0000080;
Anil Admal62c42dc2019-04-03 15:39:22 -0700182 public static final int GPS_CAPABILITY_LOW_POWER_MODE = 0x0000100;
183 public static final int GPS_CAPABILITY_SATELLITE_BLACKLIST = 0x0000200;
184 public static final int GPS_CAPABILITY_MEASUREMENT_CORRECTIONS = 0x0000400;
Mike Lockwood04598b62010-04-14 17:17:24 -0400185
Tsuwei Chen462bcd82014-09-17 12:28:49 -0700186 // The AGPS SUPL mode
187 private static final int AGPS_SUPL_MODE_MSA = 0x02;
188 private static final int AGPS_SUPL_MODE_MSB = 0x01;
189
Kweku Adams810c77d2019-08-28 07:45:00 -0700190 private static final int UPDATE_LOW_POWER_MODE = 1;
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700191 private static final int SET_REQUEST = 3;
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400192 private static final int INJECT_NTP_TIME = 5;
Kevin Tang8c6ac672019-03-22 12:31:01 -0700193 // PSDS stands for Predicted Satellite Data Service
194 private static final int DOWNLOAD_PSDS_DATA = 6;
Kevin Tang8c6ac672019-03-22 12:31:01 -0700195 private static final int DOWNLOAD_PSDS_DATA_FINISHED = 11;
destradaafb23c672015-04-16 14:01:27 -0700196 private static final int INITIALIZE_HANDLER = 13;
Yu-Han Yange7baef32018-02-09 13:58:17 -0800197 private static final int REQUEST_LOCATION = 16;
Wyatt Riley26465d22018-02-12 13:44:24 -0800198 private static final int REPORT_LOCATION = 17; // HAL reports location
199 private static final int REPORT_SV_STATUS = 18; // HAL reports SV status
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400200
Miguel Torroja1e84da82010-07-27 07:02:24 +0200201 // Request setid
202 private static final int AGPS_RIL_REQUEST_SETID_IMSI = 1;
203 private static final int AGPS_RIL_REQUEST_SETID_MSISDN = 2;
204
Miguel Torroja1e84da82010-07-27 07:02:24 +0200205 // ref. location info
206 private static final int AGPS_REF_LOCATION_TYPE_GSM_CELLID = 1;
207 private static final int AGPS_REF_LOCATION_TYPE_UMTS_CELLID = 2;
Miguel Torroja1e84da82010-07-27 07:02:24 +0200208
209 // set id info
210 private static final int AGPS_SETID_TYPE_NONE = 0;
211 private static final int AGPS_SETID_TYPE_IMSI = 1;
212 private static final int AGPS_SETID_TYPE_MSISDN = 2;
213
gomo48f1a642017-11-10 20:35:46 -0800214 private static final int GPS_GEOFENCE_UNAVAILABLE = 1 << 0L;
215 private static final int GPS_GEOFENCE_AVAILABLE = 1 << 1L;
destradaa0682809a2013-08-12 18:50:30 -0700216
gomo4402af62017-01-11 13:20:13 -0800217 // GPS Geofence errors. Should match GeofenceStatus enum in IGnssGeofenceCallback.hal.
destradaa0682809a2013-08-12 18:50:30 -0700218 private static final int GPS_GEOFENCE_OPERATION_SUCCESS = 0;
219 private static final int GPS_GEOFENCE_ERROR_TOO_MANY_GEOFENCES = 100;
gomo48f1a642017-11-10 20:35:46 -0800220 private static final int GPS_GEOFENCE_ERROR_ID_EXISTS = -101;
destradaa0682809a2013-08-12 18:50:30 -0700221 private static final int GPS_GEOFENCE_ERROR_ID_UNKNOWN = -102;
222 private static final int GPS_GEOFENCE_ERROR_INVALID_TRANSITION = -103;
223 private static final int GPS_GEOFENCE_ERROR_GENERIC = -149;
224
Tsuwei Chen678c13c2014-09-22 17:48:41 -0700225 // TCP/IP constants.
226 // Valid TCP/UDP port range is (0, 65535].
227 private static final int TCP_MIN_PORT = 0;
228 private static final int TCP_MAX_PORT = 0xffff;
229
Yu-Han Yange7baef32018-02-09 13:58:17 -0800230 // 1 second, or 1 Hz frequency.
231 private static final long LOCATION_UPDATE_MIN_TIME_INTERVAL_MILLIS = 1000;
Yu-Han Yang639f7592018-06-07 11:58:52 -0700232 // Default update duration in milliseconds for REQUEST_LOCATION.
Yu-Han Yang9e2a8232018-06-14 12:10:08 -0700233 private static final long LOCATION_UPDATE_DURATION_MILLIS = 10 * 1000;
Anil Admalb1c6c0d2019-06-20 12:00:16 -0700234 // Update duration extension multiplier for emergency REQUEST_LOCATION.
235 private static final int EMERGENCY_LOCATION_UPDATE_DURATION_MULTIPLIER = 3;
Yu-Han Yange7baef32018-02-09 13:58:17 -0800236
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700237 /** simpler wrapper for ProviderRequest + Worksource */
238 private static class GpsRequest {
239 public ProviderRequest request;
240 public WorkSource source;
gomo48f1a642017-11-10 20:35:46 -0800241
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700242 public GpsRequest(ProviderRequest request, WorkSource source) {
243 this.request = request;
244 this.source = source;
245 }
246 }
247
Wyatt Riley26465d22018-02-12 13:44:24 -0800248 // Threadsafe class to hold stats reported in the Extras Bundle
Wyatt Rileyc7067412018-02-07 15:50:35 -0800249 private static class LocationExtras {
250 private int mSvCount;
251 private int mMeanCn0;
252 private int mMaxCn0;
253 private final Bundle mBundle;
254
255 public LocationExtras() {
256 mBundle = new Bundle();
257 }
258
259 public void set(int svCount, int meanCn0, int maxCn0) {
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700260 synchronized (this) {
Wyatt Riley26465d22018-02-12 13:44:24 -0800261 mSvCount = svCount;
262 mMeanCn0 = meanCn0;
263 mMaxCn0 = maxCn0;
264 }
Wyatt Rileyc7067412018-02-07 15:50:35 -0800265 setBundle(mBundle);
266 }
267
268 public void reset() {
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700269 set(0, 0, 0);
Wyatt Rileyc7067412018-02-07 15:50:35 -0800270 }
271
272 // Also used by outside methods to add to other bundles
273 public void setBundle(Bundle extras) {
274 if (extras != null) {
Wyatt Riley26465d22018-02-12 13:44:24 -0800275 synchronized (this) {
276 extras.putInt("satellites", mSvCount);
277 extras.putInt("meanCn0", mMeanCn0);
278 extras.putInt("maxCn0", mMaxCn0);
279 }
Wyatt Rileyc7067412018-02-07 15:50:35 -0800280 }
281 }
282
283 public Bundle getBundle() {
Wyatt Riley26465d22018-02-12 13:44:24 -0800284 synchronized (this) {
285 return new Bundle(mBundle);
286 }
Wyatt Rileyc7067412018-02-07 15:50:35 -0800287 }
288 }
289
Yu-Han Yang66c7ea92018-03-11 17:17:15 -0700290 private final Object mLock = new Object();
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700291
Mike Lockwood0632ca72009-05-14 15:51:03 -0400292 // stop trying if we do not receive a fix within 60 seconds
Mike Lockwood04598b62010-04-14 17:17:24 -0400293 private static final int NO_FIX_TIMEOUT = 60 * 1000;
Mike Lockwood0632ca72009-05-14 15:51:03 -0400294
Nick Pellyb041f232012-05-07 17:12:25 -0700295 // if the fix interval is below this we leave GPS on,
296 // if above then we cycle the GPS driver.
297 // Typical hot TTTF is ~5 seconds, so 10 seconds seems sane.
298 private static final int GPS_POLLING_THRESHOLD_INTERVAL = 10 * 1000;
299
Kevin Tang8c6ac672019-03-22 12:31:01 -0700300 // how long to wait if we have a network error in NTP or PSDS downloading
Wei Liu6f6326b2015-06-24 23:47:50 -0700301 // the initial value of the exponential backoff
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700302 // current setting - 5 minutes
gomo48f1a642017-11-10 20:35:46 -0800303 private static final long RETRY_INTERVAL = 5 * 60 * 1000;
Kevin Tang8c6ac672019-03-22 12:31:01 -0700304 // how long to wait if we have a network error in NTP or PSDS downloading
Wei Liu6f6326b2015-06-24 23:47:50 -0700305 // the max value of the exponential backoff
306 // current setting - 4 hours
gomo48f1a642017-11-10 20:35:46 -0800307 private static final long MAX_RETRY_INTERVAL = 4 * 60 * 60 * 1000;
Wei Liu6f6326b2015-06-24 23:47:50 -0700308
Kevin Tang8c6ac672019-03-22 12:31:01 -0700309 // Timeout when holding wakelocks for downloading PSDS data.
310 private static final long DOWNLOAD_PSDS_DATA_TIMEOUT_MS = 60 * 1000;
Yu-Han Yang499a6ba2019-11-14 14:19:13 -0800311 private static final long WAKELOCK_TIMEOUT_MILLIS = 30 * 1000;
Wei Wangc5706f62017-04-18 11:26:26 -0700312
Kevin Tang8c6ac672019-03-22 12:31:01 -0700313 private final ExponentialBackOff mPsdsBackOff = new ExponentialBackOff(RETRY_INTERVAL,
Yu-Han Yanga1862b52018-02-20 17:05:59 -0800314 MAX_RETRY_INTERVAL);
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700315
Sasha Kuznetsovb9f26b42019-10-03 17:30:46 -0700316 private static boolean sIsInitialized = false;
317 private static boolean sStaticTestOverride = false;
318
Yu-Han Yang76f99952019-05-04 17:45:44 -0700319 // True if we are enabled
320 @GuardedBy("mLock")
321 private boolean mGpsEnabled;
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700322
Soonil Nagarkar35c3b912019-01-31 10:31:24 -0800323 private boolean mShutdown;
324
Kevin Tang8c6ac672019-03-22 12:31:01 -0700325 // states for injecting ntp and downloading psds data
Kevin Tang40e1baf2012-01-10 14:32:44 -0800326 private static final int STATE_PENDING_NETWORK = 0;
327 private static final int STATE_DOWNLOADING = 1;
328 private static final int STATE_IDLE = 2;
329
Kevin Tang8c6ac672019-03-22 12:31:01 -0700330 // flags to trigger NTP or PSDS data download when network becomes available
331 // initialized to true so we do NTP and PSDS when the network comes up after booting
332 private int mDownloadPsdsDataPending = STATE_PENDING_NETWORK;
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400333
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800334 // true if GPS is navigating
335 private boolean mNavigating;
Mike Lockwoodcf1d8cb2010-01-20 10:14:54 -0500336
Mike Lockwood04598b62010-04-14 17:17:24 -0400337 // requested frequency of fixes, in milliseconds
338 private int mFixInterval = 1000;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800339
gomo48f1a642017-11-10 20:35:46 -0800340 // true if low power mode for the GNSS chipset is part of the latest request.
341 private boolean mLowPowerMode = false;
342
WyattRileyba6072f2019-04-18 07:37:52 -0700343 // 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 -0800344 private boolean mStarted;
345
WyattRileyba6072f2019-04-18 07:37:52 -0700346 // for logging of latest change, and warning of ongoing location after a stop
347 private long mStartedChangedElapsedRealtime;
348
349 // threshold for delay in GNSS engine turning off before warning & error
350 private static final long LOCATION_OFF_DELAY_THRESHOLD_WARN_MILLIS = 2 * 1000;
351 private static final long LOCATION_OFF_DELAY_THRESHOLD_ERROR_MILLIS = 15 * 1000;
352
Anil Admal312fddb2019-03-25 12:15:43 -0700353 // capabilities reported through the top level IGnssCallback.hal
354 private volatile int mTopHalCapabilities;
Mike Lockwood04598b62010-04-14 17:17:24 -0400355
Kevin Tang8c6ac672019-03-22 12:31:01 -0700356 // true if PSDS is supported
357 private boolean mSupportsPsds;
Mike Lockwood1a1cd3a2010-08-17 07:42:54 -0400358
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800359 // for calculating time to first fix
360 private long mFixRequestTime = 0;
361 // time to first fix for most recent session
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700362 private int mTimeToFirstFix = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800363 // time we received our last fix
364 private long mLastFixTime;
365
Mike Lockwood04598b62010-04-14 17:17:24 -0400366 private int mPositionMode;
Yu-Han Yangc8b9ff72018-04-17 00:47:24 -0700367 private GnssPositionMode mLastPositionMode;
Mike Lockwood04598b62010-04-14 17:17:24 -0400368
David Christied4edf4c2014-08-12 15:22:27 -0700369 // Current request from underlying location clients.
Soonil Nagarkar35c3b912019-01-31 10:31:24 -0800370 private ProviderRequest mProviderRequest;
Narayan Kamath32684dd2018-01-08 17:32:51 +0000371 // The WorkSource associated with the most recent client request (i.e, most recent call to
372 // setRequest).
David Christied4edf4c2014-08-12 15:22:27 -0700373 private WorkSource mWorkSource = null;
WyattRileyb2446072019-03-01 07:41:49 -0800374 // True if gps should be disabled because of PowerManager controls
375 private boolean mDisableGpsForPowerManager = false;
David Christied4edf4c2014-08-12 15:22:27 -0700376
destradaafb23c672015-04-16 14:01:27 -0700377 /**
Kweku Adams810c77d2019-08-28 07:45:00 -0700378 * True if the device idle controller has determined that the device is stationary. This is only
379 * updated when the device enters idle mode.
380 */
381 private volatile boolean mIsDeviceStationary = false;
382
383 /**
destradaafb23c672015-04-16 14:01:27 -0700384 * Properties loaded from PROPERTIES_FILE.
385 * It must be accessed only inside {@link #mHandler}.
386 */
Anil Admald71cf142018-12-21 14:59:36 -0800387 private GnssConfiguration mGnssConfiguration;
destradaafb23c672015-04-16 14:01:27 -0700388
Mike Lockwood734d6032009-07-28 18:30:25 -0700389 private String mSuplServerHost;
Tsuwei Chen678c13c2014-09-22 17:48:41 -0700390 private int mSuplServerPort = TCP_MIN_PORT;
Mike Lockwood734d6032009-07-28 18:30:25 -0700391 private String mC2KServerHost;
392 private int mC2KServerPort;
Tsuwei Chen3324e952014-09-07 01:30:42 -0700393 private boolean mSuplEsEnabled = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800394
Anil Admal94ec76a2019-01-15 09:42:01 -0800395 private final Looper mLooper;
Wyatt Rileyc7067412018-02-07 15:50:35 -0800396 private final LocationExtras mLocationExtras = new LocationExtras();
Anil Admal75b9fd62018-11-28 11:22:50 -0800397 private final GnssStatusListenerHelper mGnssStatusListenerHelper;
Lifu Tang818aa2c2016-02-01 01:52:00 -0800398 private final GnssMeasurementsProvider mGnssMeasurementsProvider;
Anil Admalefd9dc62019-03-12 17:39:20 -0700399 private final GnssMeasurementCorrectionsProvider mGnssMeasurementCorrectionsProvider;
Lifu Tang818aa2c2016-02-01 01:52:00 -0800400 private final GnssNavigationMessageProvider mGnssNavigationMessageProvider;
Yu-Han Yang07561382018-02-21 13:08:37 -0800401 private final LocationChangeListener mNetworkLocationListener = new NetworkLocationListener();
402 private final LocationChangeListener mFusedLocationListener = new FusedLocationListener();
Yu-Han Yanga1862b52018-02-20 17:05:59 -0800403 private final NtpTimeHelper mNtpTimeHelper;
Yu-Han Yang3557cc72018-03-21 12:48:36 -0700404 private final GnssBatchingProvider mGnssBatchingProvider;
Yu-Han Yang890ca8b2018-04-16 22:11:31 -0700405 private final GnssGeofenceProvider mGnssGeofenceProvider;
Anil Admal312fddb2019-03-25 12:15:43 -0700406 private final GnssCapabilitiesProvider mGnssCapabilitiesProvider;
407
Anil Admal316f9482019-02-12 18:57:18 -0800408 // Available only on GNSS HAL 2.0 implementations and later.
Anil Admal94ec76a2019-01-15 09:42:01 -0800409 private GnssVisibilityControl mGnssVisibilityControl;
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400410
Soonil Nagarkar17d8c832020-01-29 18:02:53 -0800411 private final Context mContext;
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400412 private Handler mHandler;
The Android Open Source Project10592532009-03-18 17:39:46 -0700413
Anil Admal50ba15e2018-11-01 16:42:42 -0700414 private final GnssNetworkConnectivityHandler mNetworkConnectivityHandler;
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700415 private final GpsNetInitiatedHandler mNIHandler;
Mike Lockwood2f82c4e2009-04-17 08:24:10 -0400416
Mike Lockwood0528b9b2009-05-07 10:12:54 -0400417 // Wakelocks
Lifu Tang30f95a72016-01-07 23:20:38 -0800418 private final static String WAKELOCK_KEY = "GnssLocationProvider";
Mike Lockwood0528b9b2009-05-07 10:12:54 -0400419 private final PowerManager.WakeLock mWakeLock;
Kevin Tang8c6ac672019-03-22 12:31:01 -0700420 private static final String DOWNLOAD_EXTRA_WAKELOCK_KEY = "GnssLocationProviderPsdsDownload";
Yu-Han Yang76f99952019-05-04 17:45:44 -0700421 @GuardedBy("mLock")
Kevin Tang8c6ac672019-03-22 12:31:01 -0700422 private final PowerManager.WakeLock mDownloadPsdsWakeLock;
Mike Lockwood0528b9b2009-05-07 10:12:54 -0400423
Mike Lockwood29c84342009-05-06 14:01:15 -0400424 // Alarms
425 private final static String ALARM_WAKEUP = "com.android.internal.location.ALARM_WAKEUP";
Mike Lockwood0632ca72009-05-14 15:51:03 -0400426 private final static String ALARM_TIMEOUT = "com.android.internal.location.ALARM_TIMEOUT";
Tsuwei Chen52617bb2014-08-25 11:49:11 -0700427
David Christied4edf4c2014-08-12 15:22:27 -0700428 private final PowerManager mPowerManager;
Mike Lockwood29c84342009-05-06 14:01:15 -0400429 private final AlarmManager mAlarmManager;
430 private final PendingIntent mWakeupIntent;
Mike Lockwood0632ca72009-05-14 15:51:03 -0400431 private final PendingIntent mTimeoutIntent;
Mike Lockwood29c84342009-05-06 14:01:15 -0400432
Svet Ganovf7b47252018-02-26 11:11:27 -0800433 private final AppOpsManager mAppOps;
Mike Lockwood2f82c4e2009-04-17 08:24:10 -0400434 private final IBatteryStats mBatteryStats;
The Android Open Source Project10592532009-03-18 17:39:46 -0700435
Narayan Kamath32684dd2018-01-08 17:32:51 +0000436 // Current list of underlying location clients.
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700437 // only modified on handler thread
Dianne Hackborn002a54e2013-01-10 17:34:55 -0800438 private WorkSource mClientSource = new WorkSource();
Mike Lockwoodf1218be2010-01-29 09:20:06 -0500439
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -0700440 private GeofenceHardwareImpl mGeofenceHardwareImpl;
Wyatt Rileyd87cf912017-12-05 09:31:52 -0800441
442 // Volatile for simple inter-thread sync on these values.
443 private volatile int mHardwareYear = 0;
Wyatt Riley49097c02018-03-15 09:14:43 -0700444 private volatile String mHardwareModelName;
Lifu Tang82f893d2016-01-21 18:15:33 -0800445
Wyatt Riley5d5bac82016-11-01 07:05:16 -0700446 // Set lower than the current ITAR limit of 600m/s to allow this to trigger even if GPS HAL
447 // stops output right at 600m/s, depriving this of the information of a device that reaches
448 // greater than 600m/s, and higher than the speed of sound to avoid impacting most use cases.
449 private static final float ITAR_SPEED_LIMIT_METERS_PER_SECOND = 400.0F;
Wyatt Riley042c48f2017-10-06 14:59:25 -0700450
Wyatt Riley042c48f2017-10-06 14:59:25 -0700451 private volatile boolean mItarSpeedLimitExceeded = false;
Wyatt Riley5d5bac82016-11-01 07:05:16 -0700452
Siddharth Raybb608c82017-03-16 11:33:34 -0700453 // GNSS Metrics
454 private GnssMetrics mGnssMetrics;
455
Anil Admal75b9fd62018-11-28 11:22:50 -0800456 public GnssStatusListenerHelper getGnssStatusProvider() {
457 return mGnssStatusListenerHelper;
Mike Lockwood15e3d0f2009-05-01 07:53:28 -0400458 }
459
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -0700460 public IGpsGeofenceHardware getGpsGeofenceProxy() {
Yu-Han Yang890ca8b2018-04-16 22:11:31 -0700461 return mGnssGeofenceProvider;
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -0700462 }
463
Lifu Tang818aa2c2016-02-01 01:52:00 -0800464 public GnssMeasurementsProvider getGnssMeasurementsProvider() {
465 return mGnssMeasurementsProvider;
destradaaea8a8a62014-06-23 18:19:03 -0700466 }
467
Anil Admalefd9dc62019-03-12 17:39:20 -0700468 public GnssMeasurementCorrectionsProvider getGnssMeasurementCorrectionsProvider() {
469 return mGnssMeasurementCorrectionsProvider;
470 }
471
Lifu Tang818aa2c2016-02-01 01:52:00 -0800472 public GnssNavigationMessageProvider getGnssNavigationMessageProvider() {
473 return mGnssNavigationMessageProvider;
destradaa4b3e3932014-07-21 18:01:47 -0700474 }
Kweku Adams810c77d2019-08-28 07:45:00 -0700475
476 private final DeviceIdleInternal.StationaryListener mDeviceIdleStationaryListener =
477 isStationary -> {
478 mIsDeviceStationary = isStationary;
479 // Call updateLowPowerMode on handler thread so it's always called from the same
480 // thread.
481 mHandler.sendEmptyMessage(UPDATE_LOW_POWER_MODE);
482 };
483
Tsuwei Chen52617bb2014-08-25 11:49:11 -0700484 private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
gomo48f1a642017-11-10 20:35:46 -0800485 @Override
486 public void onReceive(Context context, Intent intent) {
The Android Open Source Project10592532009-03-18 17:39:46 -0700487 String action = intent.getAction();
Tsuwei Chen48d37f92014-09-05 15:15:34 -0700488 if (DEBUG) Log.d(TAG, "receive broadcast intent, action: " + action);
destradaaee9fd342015-08-31 13:31:17 -0700489 if (action == null) {
490 return;
491 }
492
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700493 switch (action) {
494 case ALARM_WAKEUP:
Yu-Han Yang6a5f0b72019-01-24 18:34:28 -0800495 startNavigating();
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700496 break;
497 case ALARM_TIMEOUT:
498 hibernate();
499 break;
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700500 case PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED:
Kweku Adams810c77d2019-08-28 07:45:00 -0700501 DeviceIdleInternal deviceIdleService = LocalServices.getService(
502 DeviceIdleInternal.class);
503 if (mPowerManager.isDeviceIdleMode()) {
504 deviceIdleService.registerStationaryListener(mDeviceIdleStationaryListener);
505 } else {
506 deviceIdleService.unregisterStationaryListener(
507 mDeviceIdleStationaryListener);
508 }
509 // Intentional fall-through.
510 case PowerManager.ACTION_POWER_SAVE_MODE_CHANGED:
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700511 case Intent.ACTION_SCREEN_OFF:
512 case Intent.ACTION_SCREEN_ON:
Kweku Adams810c77d2019-08-28 07:45:00 -0700513 // Call updateLowPowerMode on handler thread so it's always called from the
514 // same thread.
515 mHandler.sendEmptyMessage(UPDATE_LOW_POWER_MODE);
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700516 break;
Meng Wang19b214d2018-11-07 12:14:39 -0800517 case CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED:
Jayachandran C041e7692019-12-20 16:20:02 -0800518 case TelephonyManager.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED:
Soonil Nagarkarfc9c7f82019-07-16 12:07:57 -0700519 subscriptionOrCarrierConfigChanged();
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700520 break;
David Christied4edf4c2014-08-12 15:22:27 -0700521 }
The Android Open Source Project10592532009-03-18 17:39:46 -0700522 }
Mike Lockwood29c84342009-05-06 14:01:15 -0400523 };
The Android Open Source Project10592532009-03-18 17:39:46 -0700524
Yu-Han Yang66c7ea92018-03-11 17:17:15 -0700525 /**
526 * Implements {@link GnssSatelliteBlacklistCallback#onUpdateSatelliteBlacklist}.
527 */
528 @Override
529 public void onUpdateSatelliteBlacklist(int[] constellations, int[] svids) {
Anil Admald71cf142018-12-21 14:59:36 -0800530 mHandler.post(() -> mGnssConfiguration.setSatelliteBlacklist(constellations, svids));
Yu-Han Yang284234e2019-03-28 19:35:57 -0700531 mGnssMetrics.resetConstellationTypes();
Yu-Han Yang66c7ea92018-03-11 17:17:15 -0700532 }
533
Soonil Nagarkarfc9c7f82019-07-16 12:07:57 -0700534 private void subscriptionOrCarrierConfigChanged() {
Joe Onorato0c484102016-02-01 18:04:24 -0800535 if (DEBUG) Log.d(TAG, "received SIM related action: ");
Wink Savillea374c3d2014-11-11 11:48:04 -0800536 TelephonyManager phone = (TelephonyManager)
537 mContext.getSystemService(Context.TELEPHONY_SERVICE);
Ecco Park4fa1ab72016-10-24 13:04:52 -0700538 CarrierConfigManager configManager = (CarrierConfigManager)
539 mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE);
Anil Admale1539e82019-05-09 15:05:04 -0700540 int ddSubId = SubscriptionManager.getDefaultDataSubscriptionId();
zoey chen4841a272019-12-03 20:07:18 +0800541 if (SubscriptionManager.isValidSubscriptionId(ddSubId)) {
542 phone = phone.createForSubscriptionId(ddSubId);
543 }
544 String mccMnc = phone.getSimOperator();
Ecco Park4fa1ab72016-10-24 13:04:52 -0700545 boolean isKeepLppProfile = false;
Wink Savillea374c3d2014-11-11 11:48:04 -0800546 if (!TextUtils.isEmpty(mccMnc)) {
Joe Onorato0c484102016-02-01 18:04:24 -0800547 if (DEBUG) Log.d(TAG, "SIM MCC/MNC is available: " + mccMnc);
Yu-Han Yang76f99952019-05-04 17:45:44 -0700548 if (configManager != null) {
Anil Admale1539e82019-05-09 15:05:04 -0700549 PersistableBundle b = SubscriptionManager.isValidSubscriptionId(ddSubId)
550 ? configManager.getConfigForSubId(ddSubId) : null;
Yu-Han Yang76f99952019-05-04 17:45:44 -0700551 if (b != null) {
552 isKeepLppProfile =
553 b.getBoolean(CarrierConfigManager.Gps.KEY_PERSIST_LPP_MODE_BOOL);
Ecco Park4fa1ab72016-10-24 13:04:52 -0700554 }
Wink Savillea374c3d2014-11-11 11:48:04 -0800555 }
Yu-Han Yang76f99952019-05-04 17:45:44 -0700556 if (isKeepLppProfile) {
557 // load current properties for the carrier
558 mGnssConfiguration.loadPropertiesFromCarrierConfig();
559 String lpp_profile = mGnssConfiguration.getLppProfile();
560 // set the persist property LPP_PROFILE for the value
561 if (lpp_profile != null) {
562 SystemProperties.set(GnssConfiguration.LPP_PROFILE, lpp_profile);
563 }
564 } else {
565 // reset the persist property
566 SystemProperties.set(GnssConfiguration.LPP_PROFILE, "");
567 }
568 reloadGpsProperties();
Wink Savillea374c3d2014-11-11 11:48:04 -0800569 } else {
Joe Onorato0c484102016-02-01 18:04:24 -0800570 if (DEBUG) Log.d(TAG, "SIM MCC/MNC is still not available");
Wink Savillea374c3d2014-11-11 11:48:04 -0800571 }
572 }
573
David Christied4edf4c2014-08-12 15:22:27 -0700574 private void updateLowPowerMode() {
Kweku Adams810c77d2019-08-28 07:45:00 -0700575 // Disable GPS if we are in device idle mode and the device is stationary.
576 boolean disableGpsForPowerManager = mPowerManager.isDeviceIdleMode() && mIsDeviceStationary;
577 final PowerSaveState result = mPowerManager.getPowerSaveState(ServiceType.LOCATION);
Kweku Adams731a1032019-02-04 14:05:41 -0800578 switch (result.locationMode) {
Makoto Onuki57f0f552017-12-11 12:22:18 -0800579 case PowerManager.LOCATION_MODE_GPS_DISABLED_WHEN_SCREEN_OFF:
Kweku Adams5e0052b2019-02-22 15:17:52 -0800580 case PowerManager.LOCATION_MODE_ALL_DISABLED_WHEN_SCREEN_OFF:
Adam Lesinski87c17df2015-05-27 13:24:13 -0700581 // If we are in battery saver mode and the screen is off, disable GPS.
WyattRileyb2446072019-03-01 07:41:49 -0800582 disableGpsForPowerManager |=
583 result.batterySaverEnabled && !mPowerManager.isInteractive();
David Christied4edf4c2014-08-12 15:22:27 -0700584 break;
David Christied4edf4c2014-08-12 15:22:27 -0700585 }
WyattRileyb2446072019-03-01 07:41:49 -0800586 if (disableGpsForPowerManager != mDisableGpsForPowerManager) {
587 mDisableGpsForPowerManager = disableGpsForPowerManager;
Soonil Nagarkar35c3b912019-01-31 10:31:24 -0800588 updateEnabled();
David Christied4edf4c2014-08-12 15:22:27 -0700589 updateRequirements();
590 }
591 }
592
Sasha Kuznetsovb9f26b42019-10-03 17:30:46 -0700593 @VisibleForTesting
594 public static void setIsSupportedForTest(boolean override) {
595 sStaticTestOverride = override;
596 }
597
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800598 public static boolean isSupported() {
Sasha Kuznetsovb9f26b42019-10-03 17:30:46 -0700599 if (sStaticTestOverride) {
600 return true;
601 }
Sasha Kuznetsov24da7f92019-11-01 12:21:50 -0700602 ensureInitialized();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800603 return native_is_supported();
604 }
605
Sasha Kuznetsov24da7f92019-11-01 12:21:50 -0700606 private static synchronized void ensureInitialized() {
607 if (!sIsInitialized) {
608 class_init_native();
609 }
610 sIsInitialized = true;
611 }
612
Anil Admald71cf142018-12-21 14:59:36 -0800613 private void reloadGpsProperties() {
614 mGnssConfiguration.reloadGpsProperties();
615 setSuplHostPort();
Tsuwei Chen52617bb2014-08-25 11:49:11 -0700616 // TODO: we should get rid of C2K specific setting.
Anil Admald71cf142018-12-21 14:59:36 -0800617 mC2KServerHost = mGnssConfiguration.getC2KHost();
618 mC2KServerPort = mGnssConfiguration.getC2KPort(TCP_MIN_PORT);
619 mNIHandler.setEmergencyExtensionSeconds(mGnssConfiguration.getEsExtensionSec());
620 mSuplEsEnabled = mGnssConfiguration.getSuplEs(0) == 1;
Anil Admale1539e82019-05-09 15:05:04 -0700621 mNIHandler.setSuplEsEnabled(mSuplEsEnabled);
Anil Admal94ec76a2019-01-15 09:42:01 -0800622 if (mGnssVisibilityControl != null) {
Anil Admale1539e82019-05-09 15:05:04 -0700623 mGnssVisibilityControl.onConfigurationUpdated(mGnssConfiguration);
Anil Admal94ec76a2019-01-15 09:42:01 -0800624 }
Colin Cross7c030ed2014-01-28 09:33:53 -0800625 }
626
Soonil Nagarkarb6375a42020-01-29 15:23:06 -0800627 public GnssLocationProvider(Context context) {
Soonil Nagarkar17d8c832020-01-29 18:02:53 -0800628 super(FgThread.getExecutor(), context);
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700629
Sasha Kuznetsov24da7f92019-11-01 12:21:50 -0700630 ensureInitialized();
Sasha Kuznetsovb9f26b42019-10-03 17:30:46 -0700631
Soonil Nagarkar17d8c832020-01-29 18:02:53 -0800632 mContext = context;
Soonil Nagarkarb6375a42020-01-29 15:23:06 -0800633 mLooper = FgThread.getHandler().getLooper();
Mike Lockwood63598a02010-02-24 11:52:59 -0500634
Mike Lockwood0528b9b2009-05-07 10:12:54 -0400635 // Create a wake lock
David Christied4edf4c2014-08-12 15:22:27 -0700636 mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
637 mWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, WAKELOCK_KEY);
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700638 mWakeLock.setReferenceCounted(true);
Mike Lockwood0528b9b2009-05-07 10:12:54 -0400639
Kevin Tang8c6ac672019-03-22 12:31:01 -0700640 // Create a separate wake lock for psds downloader as it may be released due to timeout.
641 mDownloadPsdsWakeLock = mPowerManager.newWakeLock(
Wei Wangb71c0492017-05-01 20:24:19 -0700642 PowerManager.PARTIAL_WAKE_LOCK, DOWNLOAD_EXTRA_WAKELOCK_KEY);
Kevin Tang8c6ac672019-03-22 12:31:01 -0700643 mDownloadPsdsWakeLock.setReferenceCounted(true);
Wei Wangb71c0492017-05-01 20:24:19 -0700644
gomo48f1a642017-11-10 20:35:46 -0800645 mAlarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
Mike Lockwood29c84342009-05-06 14:01:15 -0400646 mWakeupIntent = PendingIntent.getBroadcast(mContext, 0, new Intent(ALARM_WAKEUP), 0);
Mike Lockwood0632ca72009-05-14 15:51:03 -0400647 mTimeoutIntent = PendingIntent.getBroadcast(mContext, 0, new Intent(ALARM_TIMEOUT), 0);
Mike Lockwood29c84342009-05-06 14:01:15 -0400648
Anil Admal312fddb2019-03-25 12:15:43 -0700649 mNetworkConnectivityHandler = new GnssNetworkConnectivityHandler(context,
Soonil Nagarkar8df02f42020-01-08 13:23:26 -0800650 GnssLocationProvider.this::onNetworkAvailable, mLooper);
Mike Lockwood58bda982009-04-14 16:25:07 -0400651
Dianne Hackborna06de0f2012-12-11 16:34:47 -0800652 // App ops service to keep track of who is accessing the GPS
Svet Ganovf7b47252018-02-26 11:11:27 -0800653 mAppOps = mContext.getSystemService(AppOpsManager.class);
Dianne Hackborna06de0f2012-12-11 16:34:47 -0800654
Mike Lockwood2f82c4e2009-04-17 08:24:10 -0400655 // Battery statistics service to be notified when GPS turns on or off
Dianne Hackborn91268cf2013-06-13 19:06:50 -0700656 mBatteryStats = IBatteryStats.Stub.asInterface(ServiceManager.getService(
657 BatteryStats.SERVICE_NAME));
Mike Lockwood2f82c4e2009-04-17 08:24:10 -0400658
destradaafb23c672015-04-16 14:01:27 -0700659 // Construct internal handler
Soonil Nagarkar8df02f42020-01-08 13:23:26 -0800660 mHandler = new ProviderHandler(mLooper);
destradaafb23c672015-04-16 14:01:27 -0700661
662 // Load GPS configuration and register listeners in the background:
663 // some operations, such as opening files and registering broadcast receivers, can take a
664 // relative long time, so the ctor() is kept to create objects needed by this instance,
665 // while IO initialization and registration is delegated to our internal handler
666 // this approach is just fine because events are posted to our handler anyway
Anil Admald71cf142018-12-21 14:59:36 -0800667 mGnssConfiguration = new GnssConfiguration(mContext);
Anil Admal312fddb2019-03-25 12:15:43 -0700668 mGnssCapabilitiesProvider = new GnssCapabilitiesProvider();
WyattRileyd1309312019-02-28 12:11:45 -0800669 // Create a GPS net-initiated handler (also needed by handleInitialize)
Tsuwei Chen3324e952014-09-07 01:30:42 -0700670 mNIHandler = new GpsNetInitiatedHandler(context,
gomo48f1a642017-11-10 20:35:46 -0800671 mNetInitiatedListener,
672 mSuplEsEnabled);
WyattRileyd1309312019-02-28 12:11:45 -0800673 sendMessage(INITIALIZE_HANDLER, 0, null);
Tsuwei Chen3324e952014-09-07 01:30:42 -0700674
Anil Admal75b9fd62018-11-28 11:22:50 -0800675 mGnssStatusListenerHelper = new GnssStatusListenerHelper(mContext, mHandler) {
destradaa6568d702014-10-27 12:47:41 -0700676 @Override
677 protected boolean isAvailableInPlatform() {
destradaa13a60b02015-01-15 18:36:01 -0800678 return isSupported();
destradaa6568d702014-10-27 12:47:41 -0700679 }
680
681 @Override
682 protected boolean isGpsEnabled() {
Yu-Han Yang76f99952019-05-04 17:45:44 -0700683 return GnssLocationProvider.this.isGpsEnabled();
destradaa6568d702014-10-27 12:47:41 -0700684 }
685 };
686
Yu-Han Yang8de21502018-04-23 01:40:25 -0700687 mGnssMeasurementsProvider = new GnssMeasurementsProvider(mContext, mHandler) {
destradaa6568d702014-10-27 12:47:41 -0700688 @Override
689 protected boolean isGpsEnabled() {
Yu-Han Yang76f99952019-05-04 17:45:44 -0700690 return GnssLocationProvider.this.isGpsEnabled();
destradaa6568d702014-10-27 12:47:41 -0700691 }
692 };
693
Anil Admalefd9dc62019-03-12 17:39:20 -0700694 mGnssMeasurementCorrectionsProvider = new GnssMeasurementCorrectionsProvider(mHandler);
695
Anil Admal75b9fd62018-11-28 11:22:50 -0800696 mGnssNavigationMessageProvider = new GnssNavigationMessageProvider(mContext, mHandler) {
destradaa6568d702014-10-27 12:47:41 -0700697 @Override
destradaa6568d702014-10-27 12:47:41 -0700698 protected boolean isGpsEnabled() {
Yu-Han Yang76f99952019-05-04 17:45:44 -0700699 return GnssLocationProvider.this.isGpsEnabled();
destradaa6568d702014-10-27 12:47:41 -0700700 }
701 };
Yu-Han Yanga1862b52018-02-20 17:05:59 -0800702
Anil Admal50ba15e2018-11-01 16:42:42 -0700703 mGnssMetrics = new GnssMetrics(mBatteryStats);
Soonil Nagarkar8df02f42020-01-08 13:23:26 -0800704 mNtpTimeHelper = new NtpTimeHelper(mContext, mLooper, this);
Soonil Nagarkar35c3b912019-01-31 10:31:24 -0800705 GnssSatelliteBlacklistHelper gnssSatelliteBlacklistHelper =
706 new GnssSatelliteBlacklistHelper(mContext,
Soonil Nagarkar8df02f42020-01-08 13:23:26 -0800707 mLooper, this);
Soonil Nagarkar35c3b912019-01-31 10:31:24 -0800708 mHandler.post(gnssSatelliteBlacklistHelper::updateSatelliteBlacklist);
Yu-Han Yang3557cc72018-03-21 12:48:36 -0700709 mGnssBatchingProvider = new GnssBatchingProvider();
Yu-Han Yang6dc9f052018-12-04 17:11:24 -0800710 mGnssGeofenceProvider = new GnssGeofenceProvider();
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400711
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700712 mContext.registerReceiverAsUser(new BroadcastReceiver() {
713 @Override
714 public void onReceive(Context context, Intent intent) {
715 if (getSendingUserId() == UserHandle.USER_ALL) {
Soonil Nagarkar35c3b912019-01-31 10:31:24 -0800716 mShutdown = true;
717 updateEnabled();
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700718 }
719 }
Soonil Nagarkar35c3b912019-01-31 10:31:24 -0800720 }, UserHandle.ALL, new IntentFilter(Intent.ACTION_SHUTDOWN), null, mHandler);
721
722 mContext.getContentResolver().registerContentObserver(
723 Settings.Secure.getUriFor(Settings.Secure.LOCATION_MODE),
724 true,
725 new ContentObserver(mHandler) {
726 @Override
727 public void onChange(boolean selfChange) {
728 updateEnabled();
729 }
730 }, UserHandle.USER_ALL);
Mike Lockwoodd03ff942010-02-09 08:46:14 -0500731
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700732 setProperties(PROPERTIES);
Soonil Nagarkar980ce6a2020-01-23 18:06:31 -0800733 setAllowed(true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800734 }
735
Yu-Han Yanga1862b52018-02-20 17:05:59 -0800736 /**
737 * Implements {@link InjectNtpTimeCallback#injectTime}
738 */
739 @Override
740 public void injectTime(long time, long timeReference, int uncertainty) {
741 native_inject_time(time, timeReference, uncertainty);
742 }
743
Anil Admal50ba15e2018-11-01 16:42:42 -0700744 /**
745 * Implements {@link GnssNetworkConnectivityHandler.GnssNetworkListener#onNetworkAvailable()}
746 */
747 private void onNetworkAvailable() {
748 mNtpTimeHelper.onNetworkAvailable();
Kevin Tang8c6ac672019-03-22 12:31:01 -0700749 if (mDownloadPsdsDataPending == STATE_PENDING_NETWORK) {
750 if (mSupportsPsds) {
Anil Admal316f9482019-02-12 18:57:18 -0800751 // Download only if supported, (prevents an unnecessary on-boot download)
Kevin Tang8c6ac672019-03-22 12:31:01 -0700752 psdsDownloadRequest();
destradaaef752b62015-04-17 13:10:47 -0700753 }
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400754 }
755 }
Yu-Han Yang8de21502018-04-23 01:40:25 -0700756
Yu-Han Yang53f4d6d2019-02-13 21:47:41 -0800757 private void handleRequestLocation(boolean independentFromGnss, boolean isUserEmergency) {
Yu-Han Yange7baef32018-02-09 13:58:17 -0800758 if (isRequestLocationRateLimited()) {
759 if (DEBUG) {
760 Log.d(TAG, "RequestLocation is denied due to too frequent requests.");
761 }
762 return;
763 }
Yu-Han Yang74041ff2018-04-06 15:57:31 -0700764 ContentResolver resolver = mContext.getContentResolver();
765 long durationMillis = Settings.Global.getLong(
766 resolver,
767 Settings.Global.GNSS_HAL_LOCATION_REQUEST_DURATION_MILLIS,
768 LOCATION_UPDATE_DURATION_MILLIS);
769 if (durationMillis == 0) {
770 Log.i(TAG, "GNSS HAL location request is disabled by Settings.");
771 return;
772 }
Yu-Han Yange7baef32018-02-09 13:58:17 -0800773
774 LocationManager locationManager = (LocationManager) mContext.getSystemService(
775 Context.LOCATION_SERVICE);
Yu-Han Yang07561382018-02-21 13:08:37 -0800776 String provider;
777 LocationChangeListener locationListener;
Anil Admalb1c6c0d2019-06-20 12:00:16 -0700778 LocationRequest locationRequest = new LocationRequest()
779 .setInterval(LOCATION_UPDATE_MIN_TIME_INTERVAL_MILLIS)
780 .setFastestInterval(LOCATION_UPDATE_MIN_TIME_INTERVAL_MILLIS);
Yu-Han Yange7baef32018-02-09 13:58:17 -0800781
782 if (independentFromGnss) {
783 // For fast GNSS TTFF
Yu-Han Yang07561382018-02-21 13:08:37 -0800784 provider = LocationManager.NETWORK_PROVIDER;
785 locationListener = mNetworkLocationListener;
Anil Admalb1c6c0d2019-06-20 12:00:16 -0700786 locationRequest.setQuality(LocationRequest.POWER_LOW);
Yu-Han Yange7baef32018-02-09 13:58:17 -0800787 } else {
788 // For Device-Based Hybrid (E911)
Yu-Han Yang07561382018-02-21 13:08:37 -0800789 provider = LocationManager.FUSED_PROVIDER;
790 locationListener = mFusedLocationListener;
Anil Admalb1c6c0d2019-06-20 12:00:16 -0700791 locationRequest.setQuality(LocationRequest.ACCURACY_FINE);
792 }
793
794 locationRequest.setProvider(provider);
795
796 // Ignore location settings if in emergency mode.
797 if (isUserEmergency && mNIHandler.getInEmergency()) {
798 locationRequest.setLocationSettingsIgnored(true);
799 durationMillis *= EMERGENCY_LOCATION_UPDATE_DURATION_MULTIPLIER;
Yu-Han Yange7baef32018-02-09 13:58:17 -0800800 }
Yu-Han Yang07561382018-02-21 13:08:37 -0800801
802 Log.i(TAG,
Yu-Han Yang74041ff2018-04-06 15:57:31 -0700803 String.format(
804 "GNSS HAL Requesting location updates from %s provider for %d millis.",
805 provider, durationMillis));
Yu-Han Yang53f4d6d2019-02-13 21:47:41 -0800806
Yu-Han Yange684dda2018-05-24 10:29:39 -0700807 try {
Yu-Han Yang53f4d6d2019-02-13 21:47:41 -0800808 locationManager.requestLocationUpdates(locationRequest,
Yu-Han Yange684dda2018-05-24 10:29:39 -0700809 locationListener, mHandler.getLooper());
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700810 locationListener.mNumLocationUpdateRequest++;
Yu-Han Yange684dda2018-05-24 10:29:39 -0700811 mHandler.postDelayed(() -> {
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700812 if (--locationListener.mNumLocationUpdateRequest == 0) {
Yu-Han Yange684dda2018-05-24 10:29:39 -0700813 Log.i(TAG,
814 String.format("Removing location updates from %s provider.", provider));
815 locationManager.removeUpdates(locationListener);
816 }
817 }, durationMillis);
818 } catch (IllegalArgumentException e) {
819 Log.w(TAG, "Unable to request location.", e);
820 }
Yu-Han Yange7baef32018-02-09 13:58:17 -0800821 }
822
823 private void injectBestLocation(Location location) {
Anil Admalb1c6c0d2019-06-20 12:00:16 -0700824 if (DEBUG) {
825 Log.d(TAG, "injectBestLocation: " + location);
826 }
Yu-Han Yange7baef32018-02-09 13:58:17 -0800827 int gnssLocationFlags = LOCATION_HAS_LAT_LONG |
828 (location.hasAltitude() ? LOCATION_HAS_ALTITUDE : 0) |
829 (location.hasSpeed() ? LOCATION_HAS_SPEED : 0) |
830 (location.hasBearing() ? LOCATION_HAS_BEARING : 0) |
831 (location.hasAccuracy() ? LOCATION_HAS_HORIZONTAL_ACCURACY : 0) |
832 (location.hasVerticalAccuracy() ? LOCATION_HAS_VERTICAL_ACCURACY : 0) |
833 (location.hasSpeedAccuracy() ? LOCATION_HAS_SPEED_ACCURACY : 0) |
834 (location.hasBearingAccuracy() ? LOCATION_HAS_BEARING_ACCURACY : 0);
835
836 double latitudeDegrees = location.getLatitude();
837 double longitudeDegrees = location.getLongitude();
838 double altitudeMeters = location.getAltitude();
839 float speedMetersPerSec = location.getSpeed();
840 float bearingDegrees = location.getBearing();
841 float horizontalAccuracyMeters = location.getAccuracy();
842 float verticalAccuracyMeters = location.getVerticalAccuracyMeters();
843 float speedAccuracyMetersPerSecond = location.getSpeedAccuracyMetersPerSecond();
844 float bearingAccuracyDegrees = location.getBearingAccuracyDegrees();
845 long timestamp = location.getTime();
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -0800846
Pierre Fite-Georgel9e96c572019-02-25 16:12:53 -0800847 int elapsedRealtimeFlags = ELAPSED_REALTIME_HAS_TIMESTAMP_NS
848 | (location.hasElapsedRealtimeUncertaintyNanos()
Sasha Kuznetsov24da7f92019-11-01 12:21:50 -0700849 ? ELAPSED_REALTIME_HAS_TIME_UNCERTAINTY_NS : 0);
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -0800850 long elapsedRealtimeNanos = location.getElapsedRealtimeNanos();
Yu-Han Yang3cd9a862019-03-25 17:00:03 -0700851 double elapsedRealtimeUncertaintyNanos = location.getElapsedRealtimeUncertaintyNanos();
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -0800852
853 native_inject_best_location(
854 gnssLocationFlags, latitudeDegrees, longitudeDegrees,
855 altitudeMeters, speedMetersPerSec, bearingDegrees,
856 horizontalAccuracyMeters, verticalAccuracyMeters,
857 speedAccuracyMetersPerSecond, bearingAccuracyDegrees, timestamp,
Pierre Fite-Georgel9e96c572019-02-25 16:12:53 -0800858 elapsedRealtimeFlags, elapsedRealtimeNanos, elapsedRealtimeUncertaintyNanos);
Yu-Han Yange7baef32018-02-09 13:58:17 -0800859 }
860
Yu-Han Yange7baef32018-02-09 13:58:17 -0800861 /** Returns true if the location request is too frequent. */
862 private boolean isRequestLocationRateLimited() {
Anil Admal316f9482019-02-12 18:57:18 -0800863 // TODO: implement exponential backoff.
Yu-Han Yange7baef32018-02-09 13:58:17 -0800864 return false;
865 }
866
Kevin Tang8c6ac672019-03-22 12:31:01 -0700867 private void handleDownloadPsdsData() {
868 if (!mSupportsPsds) {
869 // native code reports psds not supported, don't try
870 Log.d(TAG, "handleDownloadPsdsData() called when PSDS not supported");
Wyatt Riley0d6e54e22016-10-05 12:03:03 -0700871 return;
872 }
Kevin Tang8c6ac672019-03-22 12:31:01 -0700873 if (mDownloadPsdsDataPending == STATE_DOWNLOADING) {
Kevin Tang40e1baf2012-01-10 14:32:44 -0800874 // already downloading data
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400875 return;
876 }
Anil Admal50ba15e2018-11-01 16:42:42 -0700877 if (!mNetworkConnectivityHandler.isDataNetworkConnected()) {
Kevin Tang40e1baf2012-01-10 14:32:44 -0800878 // try again when network is up
Kevin Tang8c6ac672019-03-22 12:31:01 -0700879 mDownloadPsdsDataPending = STATE_PENDING_NETWORK;
Kevin Tang40e1baf2012-01-10 14:32:44 -0800880 return;
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400881 }
Kevin Tang8c6ac672019-03-22 12:31:01 -0700882 mDownloadPsdsDataPending = STATE_DOWNLOADING;
Kevin Tang40e1baf2012-01-10 14:32:44 -0800883
Yu-Han Yang76f99952019-05-04 17:45:44 -0700884 synchronized (mLock) {
885 // hold wake lock while task runs
886 mDownloadPsdsWakeLock.acquire(DOWNLOAD_PSDS_DATA_TIMEOUT_MS);
887 }
Kevin Tang8c6ac672019-03-22 12:31:01 -0700888 Log.i(TAG, "WakeLock acquired by handleDownloadPsdsData()");
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700889 AsyncTask.THREAD_POOL_EXECUTOR.execute(() -> {
Kevin Tang8c6ac672019-03-22 12:31:01 -0700890 GpsPsdsDownloader psdsDownloader = new GpsPsdsDownloader(
Anil Admald71cf142018-12-21 14:59:36 -0800891 mGnssConfiguration.getProperties());
Kevin Tang8c6ac672019-03-22 12:31:01 -0700892 byte[] data = psdsDownloader.downloadPsdsData();
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700893 if (data != null) {
Kevin Tang8c6ac672019-03-22 12:31:01 -0700894 if (DEBUG) Log.d(TAG, "calling native_inject_psds_data");
895 native_inject_psds_data(data, data.length);
896 mPsdsBackOff.reset();
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700897 }
Kevin Tang40e1baf2012-01-10 14:32:44 -0800898
Kevin Tang8c6ac672019-03-22 12:31:01 -0700899 sendMessage(DOWNLOAD_PSDS_DATA_FINISHED, 0, null);
Kevin Tang40e1baf2012-01-10 14:32:44 -0800900
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700901 if (data == null) {
902 // try again later
903 // since this is delayed and not urgent we do not hold a wake lock here
Kevin Tang8c6ac672019-03-22 12:31:01 -0700904 mHandler.sendEmptyMessageDelayed(DOWNLOAD_PSDS_DATA,
905 mPsdsBackOff.nextBackoffMillis());
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700906 }
Kevin Tang40e1baf2012-01-10 14:32:44 -0800907
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700908 // Release wake lock held by task, synchronize on mLock in case multiple
909 // download tasks overrun.
910 synchronized (mLock) {
Kevin Tang8c6ac672019-03-22 12:31:01 -0700911 if (mDownloadPsdsWakeLock.isHeld()) {
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700912 // This wakelock may have time-out, if a timeout was specified.
913 // Catch (and ignore) any timeout exceptions.
Yu-Han Yang499a6ba2019-11-14 14:19:13 -0800914 mDownloadPsdsWakeLock.release();
915 if (DEBUG) Log.d(TAG, "WakeLock released by handleDownloadPsdsData()");
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700916 } else {
917 Log.e(TAG, "WakeLock expired before release in "
Kevin Tang8c6ac672019-03-22 12:31:01 -0700918 + "handleDownloadPsdsData()");
Wei Wangc5706f62017-04-18 11:26:26 -0700919 }
Jeff Brown028872f2012-08-25 13:07:01 -0700920 }
Kevin Tang40e1baf2012-01-10 14:32:44 -0800921 });
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800922 }
923
Anil Admal2ac70462019-06-28 19:17:41 -0700924 private void injectLocation(Location location) {
Mike Lockwoodd26ce0d2009-06-11 12:25:46 -0400925 if (location.hasAccuracy()) {
Anil Admalb1c6c0d2019-06-20 12:00:16 -0700926 if (DEBUG) {
927 Log.d(TAG, "injectLocation: " + location);
928 }
Mike Lockwoodd26ce0d2009-06-11 12:25:46 -0400929 native_inject_location(location.getLatitude(), location.getLongitude(),
930 location.getAccuracy());
931 }
Mike Lockwoodfd6e5f02009-05-21 11:28:20 -0400932 }
933
Anil Admald71cf142018-12-21 14:59:36 -0800934 private void setSuplHostPort() {
935 mSuplServerHost = mGnssConfiguration.getSuplHost();
936 mSuplServerPort = mGnssConfiguration.getSuplPort(TCP_MIN_PORT);
Tsuwei Chen678c13c2014-09-22 17:48:41 -0700937 if (mSuplServerHost != null
938 && mSuplServerPort > TCP_MIN_PORT
939 && mSuplServerPort <= TCP_MAX_PORT) {
Anil Admalc70344b2018-11-16 14:22:38 -0800940 native_set_agps_server(GnssNetworkConnectivityHandler.AGPS_TYPE_SUPL,
941 mSuplServerHost, mSuplServerPort);
Tsuwei Chen678c13c2014-09-22 17:48:41 -0700942 }
Tsuwei Chen52617bb2014-08-25 11:49:11 -0700943 }
944
Tsuwei Chen462bcd82014-09-17 12:28:49 -0700945 /**
946 * Checks what SUPL mode to use, according to the AGPS mode as well as the
947 * allowed mode from properties.
948 *
Tsuwei Chen462bcd82014-09-17 12:28:49 -0700949 * @param agpsEnabled whether AGPS is enabled by settings value
Tsuwei Chen462bcd82014-09-17 12:28:49 -0700950 * @return SUPL mode (MSA vs MSB vs STANDALONE)
951 */
Yu-Han Yang6a5f0b72019-01-24 18:34:28 -0800952 private int getSuplMode(boolean agpsEnabled) {
Tsuwei Chen462bcd82014-09-17 12:28:49 -0700953 if (agpsEnabled) {
Anil Admald71cf142018-12-21 14:59:36 -0800954 int suplMode = mGnssConfiguration.getSuplMode(0);
955 if (suplMode == 0) {
956 return GPS_POSITION_MODE_STANDALONE;
Tsuwei Chen462bcd82014-09-17 12:28:49 -0700957 }
Anil Admald71cf142018-12-21 14:59:36 -0800958
destradaabfb3bdb2015-04-29 14:42:35 -0700959 // MS-Based is the preferred mode for Assisted-GPS position computation, so we favor
960 // such mode when it is available
961 if (hasCapability(GPS_CAPABILITY_MSB) && (suplMode & AGPS_SUPL_MODE_MSB) != 0) {
962 return GPS_POSITION_MODE_MS_BASED;
963 }
Tsuwei Chen462bcd82014-09-17 12:28:49 -0700964 }
965 return GPS_POSITION_MODE_STANDALONE;
966 }
967
Yu-Han Yang76f99952019-05-04 17:45:44 -0700968 private void setGpsEnabled(boolean enabled) {
969 synchronized (mLock) {
970 mGpsEnabled = enabled;
971 }
972 }
973
974 private void handleEnable() {
975 if (DEBUG) Log.d(TAG, "handleEnable");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800976
Soonil Nagarkar35c3b912019-01-31 10:31:24 -0800977 boolean inited = native_init();
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700978
Soonil Nagarkar35c3b912019-01-31 10:31:24 -0800979 if (inited) {
Yu-Han Yang76f99952019-05-04 17:45:44 -0700980 setGpsEnabled(true);
Kevin Tang8c6ac672019-03-22 12:31:01 -0700981 mSupportsPsds = native_supports_psds();
Tsuwei Chen678c13c2014-09-22 17:48:41 -0700982
983 // TODO: remove the following native calls if we can make sure they are redundant.
Mike Lockwood734d6032009-07-28 18:30:25 -0700984 if (mSuplServerHost != null) {
Anil Admalc70344b2018-11-16 14:22:38 -0800985 native_set_agps_server(GnssNetworkConnectivityHandler.AGPS_TYPE_SUPL,
986 mSuplServerHost, mSuplServerPort);
Mike Lockwood734d6032009-07-28 18:30:25 -0700987 }
988 if (mC2KServerHost != null) {
Anil Admalc70344b2018-11-16 14:22:38 -0800989 native_set_agps_server(GnssNetworkConnectivityHandler.AGPS_TYPE_C2K,
990 mC2KServerHost, mC2KServerPort);
Mike Lockwood734d6032009-07-28 18:30:25 -0700991 }
destradaa13a60b02015-01-15 18:36:01 -0800992
Lifu Tang818aa2c2016-02-01 01:52:00 -0800993 mGnssMeasurementsProvider.onGpsEnabledChanged();
994 mGnssNavigationMessageProvider.onGpsEnabledChanged();
Yu-Han Yang3557cc72018-03-21 12:48:36 -0700995 mGnssBatchingProvider.enable();
Anil Admal138cdc32019-04-16 10:07:43 -0700996 if (mGnssVisibilityControl != null) {
Anil Admal8b83dc12019-06-12 13:55:42 -0700997 mGnssVisibilityControl.onGpsEnabledChanged(/* isEnabled= */ true);
Anil Admal138cdc32019-04-16 10:07:43 -0700998 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800999 } else {
Yu-Han Yang76f99952019-05-04 17:45:44 -07001000 setGpsEnabled(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001001 Log.w(TAG, "Failed to enable location provider");
1002 }
1003 }
1004
Yu-Han Yang76f99952019-05-04 17:45:44 -07001005 private void handleDisable() {
1006 if (DEBUG) Log.d(TAG, "handleDisable");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001007
Yu-Han Yang76f99952019-05-04 17:45:44 -07001008 setGpsEnabled(false);
David Christie3bc26142013-12-19 14:53:44 -08001009 updateClientUids(new WorkSource());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001010 stopNavigating();
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001011 mAlarmManager.cancel(mWakeupIntent);
1012 mAlarmManager.cancel(mTimeoutIntent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001013
Anil Admal138cdc32019-04-16 10:07:43 -07001014 if (mGnssVisibilityControl != null) {
Yu-Han Yang76f99952019-05-04 17:45:44 -07001015 mGnssVisibilityControl.onGpsEnabledChanged(/* isEnabled= */ false);
Anil Admal138cdc32019-04-16 10:07:43 -07001016 }
Yu-Han Yang3557cc72018-03-21 12:48:36 -07001017 mGnssBatchingProvider.disable();
Mike Lockwoodcf1d8cb2010-01-20 10:14:54 -05001018 // do this before releasing wakelock
1019 native_cleanup();
destradaa13a60b02015-01-15 18:36:01 -08001020
Lifu Tang818aa2c2016-02-01 01:52:00 -08001021 mGnssMeasurementsProvider.onGpsEnabledChanged();
1022 mGnssNavigationMessageProvider.onGpsEnabledChanged();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001023 }
1024
Soonil Nagarkar35c3b912019-01-31 10:31:24 -08001025 private void updateEnabled() {
Tyler Trephan037ef9d2019-05-17 13:41:18 -07001026 // Generally follow location setting for current user
1027 boolean enabled = mContext.getSystemService(LocationManager.class)
1028 .isLocationEnabledForUser(UserHandle.CURRENT);
WyattRileyb2446072019-03-01 07:41:49 -08001029
Yu-Han Yang76f99952019-05-04 17:45:44 -07001030 // ... but disable if PowerManager overrides
1031 enabled &= !mDisableGpsForPowerManager;
WyattRileyb2446072019-03-01 07:41:49 -08001032
Yu-Han Yang76f99952019-05-04 17:45:44 -07001033 // .. but enable anyway, if there's an active settings-ignored request (e.g. ELS)
1034 enabled |= (mProviderRequest != null && mProviderRequest.reportLocation
Sasha Kuznetsov24da7f92019-11-01 12:21:50 -07001035 && mProviderRequest.locationSettingsIgnored);
WyattRileyb2446072019-03-01 07:41:49 -08001036
Yu-Han Yang76f99952019-05-04 17:45:44 -07001037 // ... and, finally, disable anyway, if device is being shut down
1038 enabled &= !mShutdown;
WyattRileyb2446072019-03-01 07:41:49 -08001039
Yu-Han Yang76f99952019-05-04 17:45:44 -07001040 if (enabled == isGpsEnabled()) {
1041 return;
1042 }
Soonil Nagarkar35c3b912019-01-31 10:31:24 -08001043
Yu-Han Yang76f99952019-05-04 17:45:44 -07001044 if (enabled) {
1045 handleEnable();
1046 } else {
1047 handleDisable();
Soonil Nagarkar35c3b912019-01-31 10:31:24 -08001048 }
1049 }
1050
Yu-Han Yang76f99952019-05-04 17:45:44 -07001051 private boolean isGpsEnabled() {
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001052 synchronized (mLock) {
Yu-Han Yang76f99952019-05-04 17:45:44 -07001053 return mGpsEnabled;
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001054 }
Mike Lockwoodd03ff942010-02-09 08:46:14 -05001055 }
1056
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001057 @Override
Soonil Nagarkar8df02f42020-01-08 13:23:26 -08001058 public void onSetRequest(ProviderRequest request) {
1059 sendMessage(SET_REQUEST, 0, new GpsRequest(request, request.workSource));
Mike Lockwood62a8fc12010-03-22 14:23:26 -04001060 }
1061
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001062 private void handleSetRequest(ProviderRequest request, WorkSource source) {
David Christied4edf4c2014-08-12 15:22:27 -07001063 mProviderRequest = request;
1064 mWorkSource = source;
Soonil Nagarkar35c3b912019-01-31 10:31:24 -08001065 updateEnabled();
David Christied4edf4c2014-08-12 15:22:27 -07001066 updateRequirements();
1067 }
1068
1069 // Called when the requirements for GPS may have changed
1070 private void updateRequirements() {
1071 if (mProviderRequest == null || mWorkSource == null) {
1072 return;
1073 }
1074
David Christied4edf4c2014-08-12 15:22:27 -07001075 if (DEBUG) Log.d(TAG, "setRequest " + mProviderRequest);
Yu-Han Yang76f99952019-05-04 17:45:44 -07001076 if (mProviderRequest.reportLocation && isGpsEnabled()) {
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001077 // update client uids
David Christied4edf4c2014-08-12 15:22:27 -07001078 updateClientUids(mWorkSource);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001079
David Christied4edf4c2014-08-12 15:22:27 -07001080 mFixInterval = (int) mProviderRequest.interval;
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001081 mLowPowerMode = mProviderRequest.lowPowerMode;
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001082 // check for overflow
David Christied4edf4c2014-08-12 15:22:27 -07001083 if (mFixInterval != mProviderRequest.interval) {
1084 Log.w(TAG, "interval overflow: " + mProviderRequest.interval);
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001085 mFixInterval = Integer.MAX_VALUE;
1086 }
Mike Lockwood03ca2162010-04-01 08:10:09 -07001087
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001088 // apply request to GPS engine
Mike Lockwood04598b62010-04-14 17:17:24 -04001089 if (mStarted && hasCapability(GPS_CAPABILITY_SCHEDULING)) {
gomo48f1a642017-11-10 20:35:46 -08001090 // change period and/or lowPowerMode
Yu-Han Yangc8b9ff72018-04-17 00:47:24 -07001091 if (!setPositionMode(mPositionMode, GPS_POSITION_RECURRENCE_PERIODIC,
gomo48f1a642017-11-10 20:35:46 -08001092 mFixInterval, 0, 0, mLowPowerMode)) {
1093 Log.e(TAG, "set_position_mode failed in updateRequirements");
Mike Lockwood04598b62010-04-14 17:17:24 -04001094 }
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001095 } else if (!mStarted) {
1096 // start GPS
Yu-Han Yang6a5f0b72019-01-24 18:34:28 -08001097 startNavigating();
gomo300b2402017-12-13 19:04:12 -08001098 } else {
1099 // GNSS Engine is already ON, but no GPS_CAPABILITY_SCHEDULING
1100 mAlarmManager.cancel(mTimeoutIntent);
1101 if (mFixInterval >= NO_FIX_TIMEOUT) {
1102 // set timer to give up if we do not receive a fix within NO_FIX_TIMEOUT
1103 // and our fix interval is not short
1104 mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001105 SystemClock.elapsedRealtime() + NO_FIX_TIMEOUT, mTimeoutIntent);
1106 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001107 }
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001108 } else {
Dianne Hackborn002a54e2013-01-10 17:34:55 -08001109 updateClientUids(new WorkSource());
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001110
1111 stopNavigating();
1112 mAlarmManager.cancel(mWakeupIntent);
1113 mAlarmManager.cancel(mTimeoutIntent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001114 }
1115 }
1116
Yu-Han Yangc8b9ff72018-04-17 00:47:24 -07001117 private boolean setPositionMode(int mode, int recurrence, int minInterval,
1118 int preferredAccuracy, int preferredTime, boolean lowPowerMode) {
1119 GnssPositionMode positionMode = new GnssPositionMode(mode, recurrence, minInterval,
1120 preferredAccuracy, preferredTime, lowPowerMode);
1121 if (mLastPositionMode != null && mLastPositionMode.equals(positionMode)) {
1122 return true;
1123 }
1124
1125 boolean result = native_set_position_mode(mode, recurrence, minInterval,
1126 preferredAccuracy, preferredTime, lowPowerMode);
1127 if (result) {
1128 mLastPositionMode = positionMode;
1129 } else {
1130 mLastPositionMode = null;
1131 }
1132 return result;
1133 }
1134
Dianne Hackborn002a54e2013-01-10 17:34:55 -08001135 private void updateClientUids(WorkSource source) {
Narayan Kamath32684dd2018-01-08 17:32:51 +00001136 if (source.equals(mClientSource)) {
Victoria Leaseea78b852013-01-15 10:39:28 -08001137 return;
1138 }
Dianne Hackborn002a54e2013-01-10 17:34:55 -08001139
Narayan Kamath32684dd2018-01-08 17:32:51 +00001140 // (1) Inform BatteryStats that the list of IDs we're tracking changed.
1141 try {
1142 mBatteryStats.noteGpsChanged(mClientSource, source);
1143 } catch (RemoteException e) {
1144 Log.w(TAG, "RemoteException", e);
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001145 }
1146
Narayan Kamath32684dd2018-01-08 17:32:51 +00001147 // (2) Inform AppOps service about the list of changes to UIDs.
1148
1149 List<WorkChain>[] diffs = WorkSource.diffChains(mClientSource, source);
1150 if (diffs != null) {
1151 List<WorkChain> newChains = diffs[0];
1152 List<WorkChain> goneChains = diffs[1];
1153
1154 if (newChains != null) {
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001155 for (WorkChain newChain : newChains) {
Svet Ganovf7b47252018-02-26 11:11:27 -08001156 mAppOps.startOpNoThrow(AppOpsManager.OP_GPS, newChain.getAttributionUid(),
1157 newChain.getAttributionTag());
Narayan Kamath32684dd2018-01-08 17:32:51 +00001158 }
1159 }
1160
1161 if (goneChains != null) {
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001162 for (WorkChain goneChain : goneChains) {
Svet Ganovf7b47252018-02-26 11:11:27 -08001163 mAppOps.finishOp(AppOpsManager.OP_GPS, goneChain.getAttributionUid(),
1164 goneChain.getAttributionTag());
Narayan Kamath32684dd2018-01-08 17:32:51 +00001165 }
1166 }
1167
1168 mClientSource.transferWorkChains(source);
1169 }
1170
1171 // Update the flat UIDs and names list and inform app-ops of all changes.
1172 WorkSource[] changes = mClientSource.setReturningDiffs(source);
1173 if (changes != null) {
1174 WorkSource newWork = changes[0];
1175 WorkSource goneWork = changes[1];
1176
1177 // Update sources that were not previously tracked.
1178 if (newWork != null) {
1179 for (int i = 0; i < newWork.size(); i++) {
Svet Ganovf7b47252018-02-26 11:11:27 -08001180 mAppOps.startOpNoThrow(AppOpsManager.OP_GPS,
Suprabh Shuklaf7cffa72019-11-08 17:03:03 -08001181 newWork.getUid(i), newWork.getPackageName(i));
Narayan Kamath32684dd2018-01-08 17:32:51 +00001182 }
1183 }
1184
1185 // Update sources that are no longer tracked.
1186 if (goneWork != null) {
1187 for (int i = 0; i < goneWork.size(); i++) {
Suprabh Shuklaf7cffa72019-11-08 17:03:03 -08001188 mAppOps.finishOp(AppOpsManager.OP_GPS, goneWork.getUid(i),
1189 goneWork.getPackageName(i));
Dianne Hackborn2e418422009-06-22 20:00:17 -07001190 }
Mike Lockwood2f82c4e2009-04-17 08:24:10 -04001191 }
1192 }
1193 }
1194
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001195 @Override
Soonil Nagarkar8df02f42020-01-08 13:23:26 -08001196 public void onExtraCommand(int uid, int pid, String command, Bundle extras) {
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001197
Mike Lockwood63aa5a62010-04-14 19:21:31 -04001198 long identity = Binder.clearCallingIdentity();
Peter Visontayb25db362017-11-01 18:18:12 +00001199 try {
Peter Visontayb25db362017-11-01 18:18:12 +00001200 if ("delete_aiding_data".equals(command)) {
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001201 deleteAidingData(extras);
Peter Visontayb25db362017-11-01 18:18:12 +00001202 } else if ("force_time_injection".equals(command)) {
1203 requestUtcTime();
Kevin Tang8c6ac672019-03-22 12:31:01 -07001204 } else if ("force_psds_injection".equals(command)) {
1205 if (mSupportsPsds) {
1206 psdsDownloadRequest();
Peter Visontayb25db362017-11-01 18:18:12 +00001207 }
1208 } else {
1209 Log.w(TAG, "sendExtraCommand: unknown command " + command);
Mike Lockwood93bc44d2009-05-20 16:58:22 -04001210 }
Peter Visontayb25db362017-11-01 18:18:12 +00001211 } finally {
1212 Binder.restoreCallingIdentity(identity);
Mike Lockwood93bc44d2009-05-20 16:58:22 -04001213 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001214 }
1215
Soonil Nagarkar17d8c832020-01-29 18:02:53 -08001216 @Override
1217 protected void onRequestSetAllowed(boolean allowed) {
1218 // do nothing - the gnss provider is always allowed
1219 }
1220
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001221 private void deleteAidingData(Bundle extras) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001222 int flags;
1223
1224 if (extras == null) {
1225 flags = GPS_DELETE_ALL;
1226 } else {
1227 flags = 0;
1228 if (extras.getBoolean("ephemeris")) flags |= GPS_DELETE_EPHEMERIS;
1229 if (extras.getBoolean("almanac")) flags |= GPS_DELETE_ALMANAC;
1230 if (extras.getBoolean("position")) flags |= GPS_DELETE_POSITION;
1231 if (extras.getBoolean("time")) flags |= GPS_DELETE_TIME;
1232 if (extras.getBoolean("iono")) flags |= GPS_DELETE_IONO;
1233 if (extras.getBoolean("utc")) flags |= GPS_DELETE_UTC;
1234 if (extras.getBoolean("health")) flags |= GPS_DELETE_HEALTH;
1235 if (extras.getBoolean("svdir")) flags |= GPS_DELETE_SVDIR;
1236 if (extras.getBoolean("svsteer")) flags |= GPS_DELETE_SVSTEER;
1237 if (extras.getBoolean("sadata")) flags |= GPS_DELETE_SADATA;
1238 if (extras.getBoolean("rti")) flags |= GPS_DELETE_RTI;
1239 if (extras.getBoolean("celldb-info")) flags |= GPS_DELETE_CELLDB_INFO;
1240 if (extras.getBoolean("all")) flags |= GPS_DELETE_ALL;
1241 }
1242
1243 if (flags != 0) {
1244 native_delete_aiding_data(flags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001245 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001246 }
1247
Yu-Han Yang6a5f0b72019-01-24 18:34:28 -08001248 private void startNavigating() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001249 if (!mStarted) {
Yu-Han Yang6a5f0b72019-01-24 18:34:28 -08001250 if (DEBUG) Log.d(TAG, "startNavigating");
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001251 mTimeToFirstFix = 0;
1252 mLastFixTime = 0;
WyattRileyba6072f2019-04-18 07:37:52 -07001253 setStarted(true);
Mike Lockwood03ca2162010-04-01 08:10:09 -07001254 mPositionMode = GPS_POSITION_MODE_STANDALONE;
Wyatt Riley5d5bac82016-11-01 07:05:16 -07001255 // Notify about suppressed output, if speed limit was previously exceeded.
1256 // Elsewhere, we check again with every speed output reported.
1257 if (mItarSpeedLimitExceeded) {
1258 Log.i(TAG, "startNavigating with ITAR limit in place. Output limited " +
1259 "until slow enough speed reported.");
1260 }
Mike Lockwood03ca2162010-04-01 08:10:09 -07001261
Tsuwei Chen462bcd82014-09-17 12:28:49 -07001262 boolean agpsEnabled =
1263 (Settings.Global.getInt(mContext.getContentResolver(),
gomo48f1a642017-11-10 20:35:46 -08001264 Settings.Global.ASSISTED_GPS_ENABLED, 1) != 0);
Yu-Han Yang6a5f0b72019-01-24 18:34:28 -08001265 mPositionMode = getSuplMode(agpsEnabled);
Mike Lockwoodbcab8df2009-06-25 16:39:09 -04001266
Stan Chesnutt1d72d8c2013-04-15 19:18:02 -07001267 if (DEBUG) {
1268 String mode;
1269
gomo48f1a642017-11-10 20:35:46 -08001270 switch (mPositionMode) {
Stan Chesnutt1d72d8c2013-04-15 19:18:02 -07001271 case GPS_POSITION_MODE_STANDALONE:
1272 mode = "standalone";
1273 break;
1274 case GPS_POSITION_MODE_MS_ASSISTED:
1275 mode = "MS_ASSISTED";
1276 break;
1277 case GPS_POSITION_MODE_MS_BASED:
1278 mode = "MS_BASED";
1279 break;
1280 default:
1281 mode = "unknown";
1282 break;
1283 }
1284 Log.d(TAG, "setting position_mode to " + mode);
1285 }
1286
Mike Lockwood04598b62010-04-14 17:17:24 -04001287 int interval = (hasCapability(GPS_CAPABILITY_SCHEDULING) ? mFixInterval : 1000);
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001288 mLowPowerMode = mProviderRequest.lowPowerMode;
Yu-Han Yangc8b9ff72018-04-17 00:47:24 -07001289 if (!setPositionMode(mPositionMode, GPS_POSITION_RECURRENCE_PERIODIC,
gomo48f1a642017-11-10 20:35:46 -08001290 interval, 0, 0, mLowPowerMode)) {
WyattRileyba6072f2019-04-18 07:37:52 -07001291 setStarted(false);
Mike Lockwood04598b62010-04-14 17:17:24 -04001292 Log.e(TAG, "set_position_mode failed in startNavigating()");
1293 return;
1294 }
1295 if (!native_start()) {
WyattRileyba6072f2019-04-18 07:37:52 -07001296 setStarted(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001297 Log.e(TAG, "native_start failed in startNavigating()");
Mike Lockwood0632ca72009-05-14 15:51:03 -04001298 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001299 }
1300
1301 // reset SV count to zero
Wyatt Rileyc7067412018-02-07 15:50:35 -08001302 mLocationExtras.reset();
Yipeng Cao282b5942017-05-17 20:31:39 -07001303 mFixRequestTime = SystemClock.elapsedRealtime();
Mike Lockwood04598b62010-04-14 17:17:24 -04001304 if (!hasCapability(GPS_CAPABILITY_SCHEDULING)) {
1305 // set timer to give up if we do not receive a fix within NO_FIX_TIMEOUT
1306 // and our fix interval is not short
1307 if (mFixInterval >= NO_FIX_TIMEOUT) {
1308 mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
1309 SystemClock.elapsedRealtime() + NO_FIX_TIMEOUT, mTimeoutIntent);
1310 }
Mike Lockwood0632ca72009-05-14 15:51:03 -04001311 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001312 }
1313 }
1314
Mike Lockwood62a8fc12010-03-22 14:23:26 -04001315 private void stopNavigating() {
Mike Lockwood29c84342009-05-06 14:01:15 -04001316 if (DEBUG) Log.d(TAG, "stopNavigating");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001317 if (mStarted) {
WyattRileyba6072f2019-04-18 07:37:52 -07001318 setStarted(false);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001319 native_stop();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001320 mLastFixTime = 0;
Yu-Han Yanga50cd602018-08-28 12:33:24 -07001321 // native_stop() may reset the position mode in hardware.
1322 mLastPositionMode = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001323
1324 // reset SV count to zero
Wyatt Rileyc7067412018-02-07 15:50:35 -08001325 mLocationExtras.reset();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001326 }
1327 }
1328
WyattRileyba6072f2019-04-18 07:37:52 -07001329 private void setStarted(boolean started) {
1330 if (mStarted != started) {
1331 mStarted = started;
1332 mStartedChangedElapsedRealtime = SystemClock.elapsedRealtime();
1333 }
1334 }
1335
Mike Lockwood0632ca72009-05-14 15:51:03 -04001336 private void hibernate() {
1337 // stop GPS until our next fix interval arrives
1338 stopNavigating();
Mike Lockwood0632ca72009-05-14 15:51:03 -04001339 mAlarmManager.cancel(mTimeoutIntent);
1340 mAlarmManager.cancel(mWakeupIntent);
1341 long now = SystemClock.elapsedRealtime();
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001342 mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, now + mFixInterval, mWakeupIntent);
Mike Lockwood04598b62010-04-14 17:17:24 -04001343 }
1344
1345 private boolean hasCapability(int capability) {
Anil Admal312fddb2019-03-25 12:15:43 -07001346 return (mTopHalCapabilities & capability) != 0;
Mike Lockwood0632ca72009-05-14 15:51:03 -04001347 }
1348
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001349 @NativeEntryPoint
Wyatt Riley5d229832017-02-10 17:06:00 -08001350 private void reportLocation(boolean hasLatLong, Location location) {
Wyatt Riley26465d22018-02-12 13:44:24 -08001351 sendMessage(REPORT_LOCATION, hasLatLong ? 1 : 0, location);
1352 }
1353
1354 private void handleReportLocation(boolean hasLatLong, Location location) {
Wyatt Riley5d229832017-02-10 17:06:00 -08001355 if (location.hasSpeed()) {
1356 mItarSpeedLimitExceeded = location.getSpeed() > ITAR_SPEED_LIMIT_METERS_PER_SECOND;
Wyatt Riley5d5bac82016-11-01 07:05:16 -07001357 }
1358
1359 if (mItarSpeedLimitExceeded) {
1360 Log.i(TAG, "Hal reported a speed in excess of ITAR limit." +
1361 " GPS/GNSS Navigation output blocked.");
Siddharth Ray53ddc802018-03-16 12:01:52 -07001362 if (mStarted) {
1363 mGnssMetrics.logReceivedLocationStatus(false);
1364 }
Wyatt Riley5d5bac82016-11-01 07:05:16 -07001365 return; // No output of location allowed
1366 }
1367
Wyatt Riley5d229832017-02-10 17:06:00 -08001368 if (VERBOSE) Log.v(TAG, "reportLocation " + location.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001369
Wyatt Riley26465d22018-02-12 13:44:24 -08001370 location.setExtras(mLocationExtras.getBundle());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001371
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001372 reportLocation(location);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001373
Siddharth Ray53ddc802018-03-16 12:01:52 -07001374 if (mStarted) {
1375 mGnssMetrics.logReceivedLocationStatus(hasLatLong);
1376 if (hasLatLong) {
1377 if (location.hasAccuracy()) {
1378 mGnssMetrics.logPositionAccuracyMeters(location.getAccuracy());
1379 }
1380 if (mTimeToFirstFix > 0) {
1381 int timeBetweenFixes = (int) (SystemClock.elapsedRealtime() - mLastFixTime);
1382 mGnssMetrics.logMissedReports(mFixInterval, timeBetweenFixes);
1383 }
Siddharth Raybb608c82017-03-16 11:33:34 -07001384 }
WyattRileyba6072f2019-04-18 07:37:52 -07001385 } else {
1386 // Warn or error about long delayed GNSS engine shutdown as this generally wastes
1387 // power and sends location when not expected.
1388 long locationAfterStartedFalseMillis =
1389 SystemClock.elapsedRealtime() - mStartedChangedElapsedRealtime;
1390 if (locationAfterStartedFalseMillis > LOCATION_OFF_DELAY_THRESHOLD_WARN_MILLIS) {
1391 String logMessage = "Unexpected GNSS Location report "
1392 + TimeUtils.formatDuration(locationAfterStartedFalseMillis)
1393 + " after location turned off";
1394 if (locationAfterStartedFalseMillis > LOCATION_OFF_DELAY_THRESHOLD_ERROR_MILLIS) {
1395 Log.e(TAG, logMessage);
1396 } else {
1397 Log.w(TAG, logMessage);
1398 }
1399 }
Siddharth Raybb608c82017-03-16 11:33:34 -07001400 }
1401
Yipeng Cao282b5942017-05-17 20:31:39 -07001402 mLastFixTime = SystemClock.elapsedRealtime();
Hakan Gustavssonfa94ff02010-02-23 09:12:38 +01001403 // report time to first fix
Wyatt Riley5d229832017-02-10 17:06:00 -08001404 if (mTimeToFirstFix == 0 && hasLatLong) {
gomo48f1a642017-11-10 20:35:46 -08001405 mTimeToFirstFix = (int) (mLastFixTime - mFixRequestTime);
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001406 if (DEBUG) Log.d(TAG, "TTFF: " + mTimeToFirstFix);
Siddharth Ray53ddc802018-03-16 12:01:52 -07001407 if (mStarted) {
1408 mGnssMetrics.logTimeToFirstFixMilliSecs(mTimeToFirstFix);
1409 }
Hakan Gustavssonfa94ff02010-02-23 09:12:38 +01001410
1411 // notify status listeners
Anil Admal75b9fd62018-11-28 11:22:50 -08001412 mGnssStatusListenerHelper.onFirstFix(mTimeToFirstFix);
Hakan Gustavssonfa94ff02010-02-23 09:12:38 +01001413 }
1414
Soonil Nagarkarfc9c7f82019-07-16 12:07:57 -07001415 if (mStarted) {
Wyatt Rileyc7067412018-02-07 15:50:35 -08001416 // For devices that use framework scheduling, a timer may be set to ensure we don't
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001417 // spend too much power searching for a location, when the requested update rate is
1418 // slow.
Wyatt Rileyc7067412018-02-07 15:50:35 -08001419 // As we just recievied a location, we'll cancel that timer.
Mike Lockwood04598b62010-04-14 17:17:24 -04001420 if (!hasCapability(GPS_CAPABILITY_SCHEDULING) && mFixInterval < NO_FIX_TIMEOUT) {
Mike Lockwoodb7be5442010-02-24 14:34:50 -05001421 mAlarmManager.cancel(mTimeoutIntent);
1422 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001423 }
Mike Lockwood29c84342009-05-06 14:01:15 -04001424
gomo48f1a642017-11-10 20:35:46 -08001425 if (!hasCapability(GPS_CAPABILITY_SCHEDULING) && mStarted &&
1426 mFixInterval > GPS_POLLING_THRESHOLD_INTERVAL) {
Mike Lockwoodd53ba012010-04-15 20:41:26 -04001427 if (DEBUG) Log.d(TAG, "got fix, hibernating");
Mike Lockwood0632ca72009-05-14 15:51:03 -04001428 hibernate();
Mike Lockwood29c84342009-05-06 14:01:15 -04001429 }
gomo48f1a642017-11-10 20:35:46 -08001430 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001431
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001432 @NativeEntryPoint
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001433 private void reportStatus(int status) {
Mike Lockwoodb8d90332010-10-18 17:59:48 -04001434 if (DEBUG) Log.v(TAG, "reportStatus status: " + status);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001435
destradaaea8a8a62014-06-23 18:19:03 -07001436 boolean wasNavigating = mNavigating;
1437 switch (status) {
1438 case GPS_STATUS_SESSION_BEGIN:
1439 mNavigating = true;
destradaaea8a8a62014-06-23 18:19:03 -07001440 break;
1441 case GPS_STATUS_SESSION_END:
1442 mNavigating = false;
1443 break;
1444 case GPS_STATUS_ENGINE_ON:
destradaaea8a8a62014-06-23 18:19:03 -07001445 break;
1446 case GPS_STATUS_ENGINE_OFF:
destradaaea8a8a62014-06-23 18:19:03 -07001447 mNavigating = false;
1448 break;
1449 }
Mike Lockwooddbd6fd82009-12-07 18:43:36 -05001450
destradaaea8a8a62014-06-23 18:19:03 -07001451 if (wasNavigating != mNavigating) {
Anil Admal75b9fd62018-11-28 11:22:50 -08001452 mGnssStatusListenerHelper.onStatusChanged(mNavigating);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001453 }
1454 }
1455
Wyatt Riley26465d22018-02-12 13:44:24 -08001456 // Helper class to carry data to handler for reportSvStatus
1457 private static class SvStatusInfo {
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001458 private int mSvCount;
1459 private int[] mSvidWithFlags;
1460 private float[] mCn0s;
1461 private float[] mSvElevations;
1462 private float[] mSvAzimuths;
1463 private float[] mSvCarrierFreqs;
Yu-Han Yang15e43032019-11-22 13:50:41 -08001464 private float[] mBasebandCn0s;
Wyatt Riley26465d22018-02-12 13:44:24 -08001465 }
1466
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001467 @NativeEntryPoint
Wyatt Riley26465d22018-02-12 13:44:24 -08001468 private void reportSvStatus(int svCount, int[] svidWithFlags, float[] cn0s,
Yu-Han Yang15e43032019-11-22 13:50:41 -08001469 float[] svElevations, float[] svAzimuths, float[] svCarrierFreqs,
1470 float[] basebandCn0s) {
Wyatt Riley26465d22018-02-12 13:44:24 -08001471 SvStatusInfo svStatusInfo = new SvStatusInfo();
1472 svStatusInfo.mSvCount = svCount;
1473 svStatusInfo.mSvidWithFlags = svidWithFlags;
1474 svStatusInfo.mCn0s = cn0s;
1475 svStatusInfo.mSvElevations = svElevations;
1476 svStatusInfo.mSvAzimuths = svAzimuths;
1477 svStatusInfo.mSvCarrierFreqs = svCarrierFreqs;
Yu-Han Yang15e43032019-11-22 13:50:41 -08001478 svStatusInfo.mBasebandCn0s = basebandCn0s;
Wyatt Riley26465d22018-02-12 13:44:24 -08001479
1480 sendMessage(REPORT_SV_STATUS, 0, svStatusInfo);
1481 }
1482
1483 private void handleReportSvStatus(SvStatusInfo info) {
Anil Admal75b9fd62018-11-28 11:22:50 -08001484 mGnssStatusListenerHelper.onSvStatusChanged(
Wyatt Riley26465d22018-02-12 13:44:24 -08001485 info.mSvCount,
1486 info.mSvidWithFlags,
1487 info.mCn0s,
1488 info.mSvElevations,
1489 info.mSvAzimuths,
Yu-Han Yang15e43032019-11-22 13:50:41 -08001490 info.mSvCarrierFreqs,
1491 info.mBasebandCn0s);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001492
Siddharth Ray168f12a2017-07-10 11:55:10 -07001493 // Log CN0 as part of GNSS metrics
Blake Kragtenbb613602019-08-28 16:21:35 -07001494 mGnssMetrics.logCn0(info.mCn0s, info.mSvCount, info.mSvCarrierFreqs);
Siddharth Ray168f12a2017-07-10 11:55:10 -07001495
Mike Lockwood29c84342009-05-06 14:01:15 -04001496 if (VERBOSE) {
Wyatt Riley26465d22018-02-12 13:44:24 -08001497 Log.v(TAG, "SV count: " + info.mSvCount);
Lifu Tang30f95a72016-01-07 23:20:38 -08001498 }
Wyatt Rileyc9f25dd2017-05-05 13:45:23 -07001499 // Calculate number of satellites used in fix.
Soonil Nagarkar0d1890b2019-11-12 12:13:14 -08001500 GnssStatus gnssStatus = GnssStatus.wrap(
1501 info.mSvCount,
1502 info.mSvidWithFlags,
1503 info.mCn0s,
1504 info.mSvElevations,
1505 info.mSvAzimuths,
Yu-Han Yang15e43032019-11-22 13:50:41 -08001506 info.mSvCarrierFreqs,
1507 info.mBasebandCn0s);
Lifu Tang30f95a72016-01-07 23:20:38 -08001508 int usedInFixCount = 0;
Wyatt Rileyc9f25dd2017-05-05 13:45:23 -07001509 int maxCn0 = 0;
1510 int meanCn0 = 0;
Soonil Nagarkar0d1890b2019-11-12 12:13:14 -08001511 for (int i = 0; i < gnssStatus.getSatelliteCount(); i++) {
1512 if (gnssStatus.usedInFix(i)) {
Lifu Tang30f95a72016-01-07 23:20:38 -08001513 ++usedInFixCount;
Soonil Nagarkar0d1890b2019-11-12 12:13:14 -08001514 if (gnssStatus.getCn0DbHz(i) > maxCn0) {
1515 maxCn0 = (int) gnssStatus.getCn0DbHz(i);
Wyatt Rileyc9f25dd2017-05-05 13:45:23 -07001516 }
Soonil Nagarkar0d1890b2019-11-12 12:13:14 -08001517 meanCn0 += gnssStatus.getCn0DbHz(i);
1518 mGnssMetrics.logConstellationType(gnssStatus.getConstellationType(i));
Lifu Tang30f95a72016-01-07 23:20:38 -08001519 }
1520 if (VERBOSE) {
Soonil Nagarkar0d1890b2019-11-12 12:13:14 -08001521 Log.v(TAG, "svid: " + gnssStatus.getSvid(i)
1522 + " cn0: " + gnssStatus.getCn0DbHz(i)
Yu-Han Yang15e43032019-11-22 13:50:41 -08001523 + " basebandCn0: " + gnssStatus.getBasebandCn0DbHz(i)
Soonil Nagarkar0d1890b2019-11-12 12:13:14 -08001524 + " elev: " + gnssStatus.getElevationDegrees(i)
1525 + " azimuth: " + gnssStatus.getAzimuthDegrees(i)
1526 + " carrier frequency: " + gnssStatus.getCn0DbHz(i)
1527 + (gnssStatus.hasEphemerisData(i) ? " E" : " ")
1528 + (gnssStatus.hasAlmanacData(i) ? " A" : " ")
1529 + (gnssStatus.usedInFix(i) ? "U" : "")
Yu-Han Yang15e43032019-11-22 13:50:41 -08001530 + (gnssStatus.hasCarrierFrequencyHz(i) ? "F" : "")
1531 + (gnssStatus.hasBasebandCn0DbHz(i) ? "B" : ""));
Yu-Han Yang284234e2019-03-28 19:35:57 -07001532 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001533 }
Wyatt Rileyc9f25dd2017-05-05 13:45:23 -07001534 if (usedInFixCount > 0) {
1535 meanCn0 /= usedInFixCount;
1536 }
1537 // return number of sats used in fix instead of total reported
Wyatt Rileyc7067412018-02-07 15:50:35 -08001538 mLocationExtras.set(usedInFixCount, meanCn0, maxCn0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001539
Soonil Nagarkar0d1890b2019-11-12 12:13:14 -08001540 mGnssMetrics.logSvStatus(gnssStatus);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001541 }
Mike Lockwood58bda982009-04-14 16:25:07 -04001542
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001543 @NativeEntryPoint
Anil Admalc70344b2018-11-16 14:22:38 -08001544 private void reportAGpsStatus(int agpsType, int agpsStatus, byte[] suplIpAddr) {
1545 mNetworkConnectivityHandler.onReportAGpsStatus(agpsType, agpsStatus, suplIpAddr);
destradaae21252a2015-09-08 12:32:59 -07001546 }
1547
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001548 @NativeEntryPoint
Mike Lockwoodf602d362010-06-20 14:28:16 -07001549 private void reportNmea(long timestamp) {
Wyatt Riley5d5bac82016-11-01 07:05:16 -07001550 if (!mItarSpeedLimitExceeded) {
1551 int length = native_read_nmea(mNmeaBuffer, mNmeaBuffer.length);
1552 String nmea = new String(mNmeaBuffer, 0 /* offset */, length);
Anil Admal75b9fd62018-11-28 11:22:50 -08001553 mGnssStatusListenerHelper.onNmeaReceived(timestamp, nmea);
Wyatt Riley5d5bac82016-11-01 07:05:16 -07001554 }
destradaaea8a8a62014-06-23 18:19:03 -07001555 }
Mike Lockwoodb16e7802009-08-06 09:26:02 -04001556
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001557 @NativeEntryPoint
Lifu Tang818aa2c2016-02-01 01:52:00 -08001558 private void reportMeasurementData(GnssMeasurementsEvent event) {
Wyatt Riley5d5bac82016-11-01 07:05:16 -07001559 if (!mItarSpeedLimitExceeded) {
Wyatt Rileyaa420d52017-07-03 15:14:42 -07001560 // send to handler to allow native to return quickly
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001561 mHandler.post(() -> mGnssMeasurementsProvider.onMeasurementsAvailable(event));
Wyatt Riley5d5bac82016-11-01 07:05:16 -07001562 }
Mike Lockwoodb16e7802009-08-06 09:26:02 -04001563 }
1564
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001565 @NativeEntryPoint
Lifu Tange8abe8e2016-04-01 10:32:05 -07001566 private void reportNavigationMessage(GnssNavigationMessage event) {
Wyatt Riley5d5bac82016-11-01 07:05:16 -07001567 if (!mItarSpeedLimitExceeded) {
Wyatt Rileyaa420d52017-07-03 15:14:42 -07001568 // send to handler to allow native to return quickly
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001569 mHandler.post(() -> mGnssNavigationMessageProvider.onNavigationMessageAvailable(event));
Wyatt Riley5d5bac82016-11-01 07:05:16 -07001570 }
destradaa4b3e3932014-07-21 18:01:47 -07001571 }
1572
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001573 @NativeEntryPoint
Anil Admal62c42dc2019-04-03 15:39:22 -07001574 private void setTopHalCapabilities(int topHalCapabilities) {
Anil Admalefd9dc62019-03-12 17:39:20 -07001575 mHandler.post(() -> {
Anil Admal312fddb2019-03-25 12:15:43 -07001576 mTopHalCapabilities = topHalCapabilities;
Mike Lockwood9b9fb5c2011-06-29 15:09:40 -04001577
Anil Admalefd9dc62019-03-12 17:39:20 -07001578 if (hasCapability(GPS_CAPABILITY_ON_DEMAND_TIME)) {
1579 mNtpTimeHelper.enablePeriodicTimeInjection();
1580 requestUtcTime();
1581 }
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001582
Anil Admal62c42dc2019-04-03 15:39:22 -07001583 mGnssMeasurementsProvider.onCapabilitiesUpdated(
1584 hasCapability(GPS_CAPABILITY_MEASUREMENTS));
1585 mGnssNavigationMessageProvider.onCapabilitiesUpdated(
1586 hasCapability(GPS_CAPABILITY_NAV_MESSAGES));
Anil Admalefd9dc62019-03-12 17:39:20 -07001587 restartRequests();
Anil Admal312fddb2019-03-25 12:15:43 -07001588
Anil Admal62c42dc2019-04-03 15:39:22 -07001589 mGnssCapabilitiesProvider.setTopHalCapabilities(mTopHalCapabilities);
Anil Admalefd9dc62019-03-12 17:39:20 -07001590 });
1591 }
1592
1593 @NativeEntryPoint
Anil Admal312fddb2019-03-25 12:15:43 -07001594 private void setSubHalMeasurementCorrectionsCapabilities(int subHalCapabilities) {
1595 mHandler.post(() -> {
1596 if (!mGnssMeasurementCorrectionsProvider.onCapabilitiesUpdated(subHalCapabilities)) {
1597 return;
1598 }
1599
1600 mGnssCapabilitiesProvider.setSubHalMeasurementCorrectionsCapabilities(
1601 subHalCapabilities);
1602 });
Yu-Han Yang52057622018-04-25 00:51:22 -07001603 }
1604
1605 private void restartRequests() {
1606 Log.i(TAG, "restartRequests");
1607
1608 restartLocationRequest();
1609 mGnssMeasurementsProvider.resumeIfStarted();
1610 mGnssNavigationMessageProvider.resumeIfStarted();
1611 mGnssBatchingProvider.resumeIfStarted();
1612 mGnssGeofenceProvider.resumeIfStarted();
1613 }
1614
1615 private void restartLocationRequest() {
1616 if (DEBUG) Log.d(TAG, "restartLocationRequest");
WyattRileyba6072f2019-04-18 07:37:52 -07001617 setStarted(false);
Yu-Han Yang52057622018-04-25 00:51:22 -07001618 updateRequirements();
1619 }
Wyatt Rileyd87cf912017-12-05 09:31:52 -08001620
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001621 @NativeEntryPoint
Wyatt Rileyd87cf912017-12-05 09:31:52 -08001622 private void setGnssYearOfHardware(final int yearOfHardware) {
1623 // mHardwareYear is simply set here, to be read elsewhere, and is volatile for safe sync
1624 if (DEBUG) Log.d(TAG, "setGnssYearOfHardware called with " + yearOfHardware);
1625 mHardwareYear = yearOfHardware;
Mike Lockwood04598b62010-04-14 17:17:24 -04001626 }
1627
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001628 @NativeEntryPoint
Wyatt Rileyd87cf912017-12-05 09:31:52 -08001629 private void setGnssHardwareModelName(final String modelName) {
1630 // mHardwareModelName is simply set here, to be read elsewhere, and volatile for safe sync
1631 if (DEBUG) Log.d(TAG, "setGnssModelName called with " + modelName);
1632 mHardwareModelName = modelName;
Lifu Tang82f893d2016-01-21 18:15:33 -08001633 }
1634
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001635 @NativeEntryPoint
Yu-Han Yang52057622018-04-25 00:51:22 -07001636 private void reportGnssServiceDied() {
1637 if (DEBUG) Log.d(TAG, "reportGnssServiceDied");
1638 mHandler.post(() -> {
Anil Admal0c2b21bd2019-05-03 18:29:02 -07001639 setupNativeGnssService(/* reinitializeGnssServiceHandle = */ true);
Anil Admal204406f2019-07-23 12:00:23 -07001640 // resend configuration into the restarted HAL service.
1641 reloadGpsProperties();
Yu-Han Yang76f99952019-05-04 17:45:44 -07001642 if (isGpsEnabled()) {
1643 setGpsEnabled(false);
Soonil Nagarkar35c3b912019-01-31 10:31:24 -08001644 updateEnabled();
Yu-Han Yang52057622018-04-25 00:51:22 -07001645 }
1646 });
1647 }
1648
Lifu Tang9363b942016-02-16 18:07:00 -08001649 public interface GnssSystemInfoProvider {
Lifu Tang82f893d2016-01-21 18:15:33 -08001650 /**
Wyatt Rileyd87cf912017-12-05 09:31:52 -08001651 * Returns the year of underlying GPS hardware.
Lifu Tang82f893d2016-01-21 18:15:33 -08001652 */
Lifu Tang9363b942016-02-16 18:07:00 -08001653 int getGnssYearOfHardware();
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001654
Wyatt Rileyd87cf912017-12-05 09:31:52 -08001655 /**
1656 * Returns the model name of underlying GPS hardware.
1657 */
1658 String getGnssHardwareModelName();
Lifu Tang82f893d2016-01-21 18:15:33 -08001659 }
1660
1661 /**
1662 * @hide
1663 */
Lifu Tang9363b942016-02-16 18:07:00 -08001664 public GnssSystemInfoProvider getGnssSystemInfoProvider() {
1665 return new GnssSystemInfoProvider() {
Lifu Tang82f893d2016-01-21 18:15:33 -08001666 @Override
Lifu Tang9363b942016-02-16 18:07:00 -08001667 public int getGnssYearOfHardware() {
Wyatt Rileyd87cf912017-12-05 09:31:52 -08001668 return mHardwareYear;
1669 }
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001670
Wyatt Rileyd87cf912017-12-05 09:31:52 -08001671 @Override
1672 public String getGnssHardwareModelName() {
1673 return mHardwareModelName;
Lifu Tang82f893d2016-01-21 18:15:33 -08001674 }
1675 };
1676 }
1677
Wyatt Rileycf879db2017-01-12 13:57:38 -08001678 /**
1679 * @hide
1680 */
1681 public GnssBatchingProvider getGnssBatchingProvider() {
Yu-Han Yang3557cc72018-03-21 12:48:36 -07001682 return mGnssBatchingProvider;
Wyatt Rileycf879db2017-01-12 13:57:38 -08001683 }
1684
Siddharth Raybb608c82017-03-16 11:33:34 -07001685 public interface GnssMetricsProvider {
1686 /**
1687 * Returns GNSS metrics as proto string
1688 */
1689 String getGnssMetricsAsProtoString();
1690 }
1691
1692 /**
1693 * @hide
1694 */
1695 public GnssMetricsProvider getGnssMetricsProvider() {
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001696 return () -> mGnssMetrics.dumpGnssMetricsAsProtoString();
Siddharth Raybb608c82017-03-16 11:33:34 -07001697 }
1698
Anil Admal312fddb2019-03-25 12:15:43 -07001699 /**
1700 * @hide
1701 */
1702 public GnssCapabilitiesProvider getGnssCapabilitiesProvider() {
1703 return mGnssCapabilitiesProvider;
1704 }
1705
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001706 @NativeEntryPoint
Wyatt Rileycf879db2017-01-12 13:57:38 -08001707 private void reportLocationBatch(Location[] locationArray) {
1708 List<Location> locations = new ArrayList<>(Arrays.asList(locationArray));
gomo48f1a642017-11-10 20:35:46 -08001709 if (DEBUG) {
1710 Log.d(TAG, "Location batch of size " + locationArray.length + " reported");
1711 }
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001712 reportLocation(locations);
Wyatt Rileycf879db2017-01-12 13:57:38 -08001713 }
1714
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001715 @NativeEntryPoint
Kevin Tang8c6ac672019-03-22 12:31:01 -07001716 private void psdsDownloadRequest() {
1717 if (DEBUG) Log.d(TAG, "psdsDownloadRequest");
1718 sendMessage(DOWNLOAD_PSDS_DATA, 0, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001719 }
1720
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07001721 /**
destradaa0682809a2013-08-12 18:50:30 -07001722 * Converts the GPS HAL status to the internal Geofence Hardware status.
1723 */
Yu-Han Yang6dc9f052018-12-04 17:11:24 -08001724 private static int getGeofenceStatus(int status) {
gomo48f1a642017-11-10 20:35:46 -08001725 switch (status) {
destradaa0682809a2013-08-12 18:50:30 -07001726 case GPS_GEOFENCE_OPERATION_SUCCESS:
1727 return GeofenceHardware.GEOFENCE_SUCCESS;
1728 case GPS_GEOFENCE_ERROR_GENERIC:
1729 return GeofenceHardware.GEOFENCE_FAILURE;
1730 case GPS_GEOFENCE_ERROR_ID_EXISTS:
1731 return GeofenceHardware.GEOFENCE_ERROR_ID_EXISTS;
1732 case GPS_GEOFENCE_ERROR_INVALID_TRANSITION:
1733 return GeofenceHardware.GEOFENCE_ERROR_INVALID_TRANSITION;
1734 case GPS_GEOFENCE_ERROR_TOO_MANY_GEOFENCES:
1735 return GeofenceHardware.GEOFENCE_ERROR_TOO_MANY_GEOFENCES;
1736 case GPS_GEOFENCE_ERROR_ID_UNKNOWN:
1737 return GeofenceHardware.GEOFENCE_ERROR_ID_UNKNOWN;
1738 default:
1739 return -1;
1740 }
1741 }
1742
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001743 @NativeEntryPoint
Wyatt Riley5d229832017-02-10 17:06:00 -08001744 private void reportGeofenceTransition(int geofenceId, Location location, int transition,
gomo48f1a642017-11-10 20:35:46 -08001745 long transitionTimestamp) {
Yu-Han Yang6dc9f052018-12-04 17:11:24 -08001746 mHandler.post(() -> {
1747 if (mGeofenceHardwareImpl == null) {
1748 mGeofenceHardwareImpl = GeofenceHardwareImpl.getInstance(mContext);
1749 }
Wyatt Riley5d229832017-02-10 17:06:00 -08001750
Yu-Han Yang6dc9f052018-12-04 17:11:24 -08001751 mGeofenceHardwareImpl.reportGeofenceTransition(
1752 geofenceId,
1753 location,
1754 transition,
1755 transitionTimestamp,
1756 GeofenceHardware.MONITORING_TYPE_GPS_HARDWARE,
1757 FusedBatchOptions.SourceTechnologies.GNSS);
1758 });
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07001759 }
1760
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001761 @NativeEntryPoint
Wyatt Riley5d229832017-02-10 17:06:00 -08001762 private void reportGeofenceStatus(int status, Location location) {
Yu-Han Yang6dc9f052018-12-04 17:11:24 -08001763 mHandler.post(() -> {
1764 if (mGeofenceHardwareImpl == null) {
1765 mGeofenceHardwareImpl = GeofenceHardwareImpl.getInstance(mContext);
1766 }
1767 int monitorStatus = GeofenceHardware.MONITOR_CURRENTLY_UNAVAILABLE;
1768 if (status == GPS_GEOFENCE_AVAILABLE) {
1769 monitorStatus = GeofenceHardware.MONITOR_CURRENTLY_AVAILABLE;
1770 }
1771 mGeofenceHardwareImpl.reportGeofenceMonitorStatus(
1772 GeofenceHardware.MONITORING_TYPE_GPS_HARDWARE,
1773 monitorStatus,
1774 location,
1775 FusedBatchOptions.SourceTechnologies.GNSS);
1776 });
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07001777 }
1778
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001779 @NativeEntryPoint
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07001780 private void reportGeofenceAddStatus(int geofenceId, int status) {
Yu-Han Yang6dc9f052018-12-04 17:11:24 -08001781 mHandler.post(() -> {
1782 if (mGeofenceHardwareImpl == null) {
1783 mGeofenceHardwareImpl = GeofenceHardwareImpl.getInstance(mContext);
1784 }
1785 mGeofenceHardwareImpl.reportGeofenceAddStatus(geofenceId, getGeofenceStatus(status));
1786 });
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07001787 }
1788
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001789 @NativeEntryPoint
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07001790 private void reportGeofenceRemoveStatus(int geofenceId, int status) {
Yu-Han Yang6dc9f052018-12-04 17:11:24 -08001791 mHandler.post(() -> {
1792 if (mGeofenceHardwareImpl == null) {
1793 mGeofenceHardwareImpl = GeofenceHardwareImpl.getInstance(mContext);
1794 }
1795 mGeofenceHardwareImpl.reportGeofenceRemoveStatus(geofenceId, getGeofenceStatus(status));
1796 });
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07001797 }
1798
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001799 @NativeEntryPoint
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07001800 private void reportGeofencePauseStatus(int geofenceId, int status) {
Yu-Han Yang6dc9f052018-12-04 17:11:24 -08001801 mHandler.post(() -> {
1802 if (mGeofenceHardwareImpl == null) {
1803 mGeofenceHardwareImpl = GeofenceHardwareImpl.getInstance(mContext);
1804 }
1805 mGeofenceHardwareImpl.reportGeofencePauseStatus(geofenceId, getGeofenceStatus(status));
1806 });
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07001807 }
1808
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001809 @NativeEntryPoint
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07001810 private void reportGeofenceResumeStatus(int geofenceId, int status) {
Yu-Han Yang6dc9f052018-12-04 17:11:24 -08001811 mHandler.post(() -> {
1812 if (mGeofenceHardwareImpl == null) {
1813 mGeofenceHardwareImpl = GeofenceHardwareImpl.getInstance(mContext);
1814 }
1815 mGeofenceHardwareImpl.reportGeofenceResumeStatus(geofenceId, getGeofenceStatus(status));
1816 });
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07001817 }
1818
Danke Xie22d1f9f2009-08-18 18:28:45 -04001819 //=============================================================
1820 // NI Client support
Miguel Torroja1e84da82010-07-27 07:02:24 +02001821 //=============================================================
Danke Xie22d1f9f2009-08-18 18:28:45 -04001822 private final INetInitiatedListener mNetInitiatedListener = new INetInitiatedListener.Stub() {
destradaaef752b62015-04-17 13:10:47 -07001823 // Sends a response for an NI request to HAL.
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001824 @Override
gomo48f1a642017-11-10 20:35:46 -08001825 public boolean sendNiResponse(int notificationId, int userResponse) {
Miguel Torroja1e84da82010-07-27 07:02:24 +02001826 // TODO Add Permission check
Danke Xie22d1f9f2009-08-18 18:28:45 -04001827
gomo48f1a642017-11-10 20:35:46 -08001828 if (DEBUG) {
1829 Log.d(TAG, "sendNiResponse, notifId: " + notificationId +
1830 ", response: " + userResponse);
1831 }
Miguel Torroja1e84da82010-07-27 07:02:24 +02001832 native_send_ni_response(notificationId, userResponse);
Yu-Han Yang8a1b51d2018-12-26 22:18:31 -08001833
Muhammad Qureshi6f207102020-01-28 10:37:41 -08001834 FrameworkStatsLog.write(FrameworkStatsLog.GNSS_NI_EVENT_REPORTED,
1835 FrameworkStatsLog.GNSS_NI_EVENT_REPORTED__EVENT_TYPE__NI_RESPONSE,
Yu-Han Yang8a1b51d2018-12-26 22:18:31 -08001836 notificationId,
1837 /* niType= */ 0,
1838 /* needNotify= */ false,
1839 /* needVerify= */ false,
1840 /* privacyOverride= */ false,
1841 /* timeout= */ 0,
1842 /* defaultResponse= */ 0,
1843 /* requestorId= */ null,
1844 /* text= */ null,
1845 /* requestorIdEncoding= */ 0,
1846 /* textEncoding= */ 0,
1847 mSuplEsEnabled,
Yu-Han Yang76f99952019-05-04 17:45:44 -07001848 isGpsEnabled(),
Yu-Han Yang8a1b51d2018-12-26 22:18:31 -08001849 userResponse);
1850
Miguel Torroja1e84da82010-07-27 07:02:24 +02001851 return true;
1852 }
Danke Xie22d1f9f2009-08-18 18:28:45 -04001853 };
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001854
Danke Xie22d1f9f2009-08-18 18:28:45 -04001855 public INetInitiatedListener getNetInitiatedListener() {
1856 return mNetInitiatedListener;
1857 }
1858
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001859 /** Reports a NI notification. */
1860 @NativeEntryPoint
Miguel Torroja1e84da82010-07-27 07:02:24 +02001861 public void reportNiNotification(
1862 int notificationId,
1863 int niType,
1864 int notifyFlags,
1865 int timeout,
1866 int defaultResponse,
1867 String requestorId,
1868 String text,
1869 int requestorIdEncoding,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001870 int textEncoding
gomo48f1a642017-11-10 20:35:46 -08001871 ) {
Miguel Torroja1e84da82010-07-27 07:02:24 +02001872 Log.i(TAG, "reportNiNotification: entered");
1873 Log.i(TAG, "notificationId: " + notificationId +
1874 ", niType: " + niType +
1875 ", notifyFlags: " + notifyFlags +
1876 ", timeout: " + timeout +
1877 ", defaultResponse: " + defaultResponse);
1878
1879 Log.i(TAG, "requestorId: " + requestorId +
1880 ", text: " + text +
1881 ", requestorIdEncoding: " + requestorIdEncoding +
1882 ", textEncoding: " + textEncoding);
1883
1884 GpsNiNotification notification = new GpsNiNotification();
1885
1886 notification.notificationId = notificationId;
1887 notification.niType = niType;
1888 notification.needNotify = (notifyFlags & GpsNetInitiatedHandler.GPS_NI_NEED_NOTIFY) != 0;
1889 notification.needVerify = (notifyFlags & GpsNetInitiatedHandler.GPS_NI_NEED_VERIFY) != 0;
gomo48f1a642017-11-10 20:35:46 -08001890 notification.privacyOverride =
1891 (notifyFlags & GpsNetInitiatedHandler.GPS_NI_PRIVACY_OVERRIDE) != 0;
Miguel Torroja1e84da82010-07-27 07:02:24 +02001892 notification.timeout = timeout;
1893 notification.defaultResponse = defaultResponse;
1894 notification.requestorId = requestorId;
1895 notification.text = text;
1896 notification.requestorIdEncoding = requestorIdEncoding;
1897 notification.textEncoding = textEncoding;
1898
Miguel Torroja1e84da82010-07-27 07:02:24 +02001899 mNIHandler.handleNiNotification(notification);
Muhammad Qureshi6f207102020-01-28 10:37:41 -08001900 FrameworkStatsLog.write(FrameworkStatsLog.GNSS_NI_EVENT_REPORTED,
1901 FrameworkStatsLog.GNSS_NI_EVENT_REPORTED__EVENT_TYPE__NI_REQUEST,
Yu-Han Yang8a1b51d2018-12-26 22:18:31 -08001902 notification.notificationId,
1903 notification.niType,
1904 notification.needNotify,
1905 notification.needVerify,
1906 notification.privacyOverride,
1907 notification.timeout,
1908 notification.defaultResponse,
1909 notification.requestorId,
1910 notification.text,
1911 notification.requestorIdEncoding,
1912 notification.textEncoding,
1913 mSuplEsEnabled,
Yu-Han Yang76f99952019-05-04 17:45:44 -07001914 isGpsEnabled(),
Yu-Han Yang8a1b51d2018-12-26 22:18:31 -08001915 /* userResponse= */ 0);
Miguel Torroja1e84da82010-07-27 07:02:24 +02001916 }
1917
1918 /**
Miguel Torroja1e84da82010-07-27 07:02:24 +02001919 * We should be careful about receiving null string from the TelephonyManager,
1920 * because sending null String to JNI function would cause a crash.
1921 */
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001922 @NativeEntryPoint
Miguel Torroja1e84da82010-07-27 07:02:24 +02001923 private void requestSetID(int flags) {
1924 TelephonyManager phone = (TelephonyManager)
1925 mContext.getSystemService(Context.TELEPHONY_SERVICE);
destradaaef752b62015-04-17 13:10:47 -07001926 int type = AGPS_SETID_TYPE_NONE;
Anil Admale1539e82019-05-09 15:05:04 -07001927 String setId = null;
Miguel Torroja1e84da82010-07-27 07:02:24 +02001928
Anil Admale1539e82019-05-09 15:05:04 -07001929 int ddSubId = SubscriptionManager.getDefaultDataSubscriptionId();
zoey chen4841a272019-12-03 20:07:18 +08001930 if (SubscriptionManager.isValidSubscriptionId(ddSubId)) {
1931 phone = phone.createForSubscriptionId(ddSubId);
1932 }
Miguel Torroja1e84da82010-07-27 07:02:24 +02001933 if ((flags & AGPS_RIL_REQUEST_SETID_IMSI) == AGPS_RIL_REQUEST_SETID_IMSI) {
zoey chen4841a272019-12-03 20:07:18 +08001934 setId = phone.getSubscriberId();
Anil Admale1539e82019-05-09 15:05:04 -07001935 if (setId != null) {
Miguel Torroja1e84da82010-07-27 07:02:24 +02001936 // This means the framework has the SIM card.
Miguel Torroja1e84da82010-07-27 07:02:24 +02001937 type = AGPS_SETID_TYPE_IMSI;
1938 }
gomo48f1a642017-11-10 20:35:46 -08001939 } else if ((flags & AGPS_RIL_REQUEST_SETID_MSISDN) == AGPS_RIL_REQUEST_SETID_MSISDN) {
zoey chen4841a272019-12-03 20:07:18 +08001940 setId = phone.getLine1Number();
Anil Admale1539e82019-05-09 15:05:04 -07001941 if (setId != null) {
Miguel Torroja1e84da82010-07-27 07:02:24 +02001942 // This means the framework has the SIM card.
Miguel Torroja1e84da82010-07-27 07:02:24 +02001943 type = AGPS_SETID_TYPE_MSISDN;
1944 }
1945 }
Anil Admale1539e82019-05-09 15:05:04 -07001946
1947 native_agps_set_id(type, (setId == null) ? "" : setId);
Miguel Torroja1e84da82010-07-27 07:02:24 +02001948 }
1949
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001950 @NativeEntryPoint
Yu-Han Yang53f4d6d2019-02-13 21:47:41 -08001951 private void requestLocation(boolean independentFromGnss, boolean isUserEmergency) {
Yu-Han Yange7baef32018-02-09 13:58:17 -08001952 if (DEBUG) {
Yu-Han Yang53f4d6d2019-02-13 21:47:41 -08001953 Log.d(TAG, "requestLocation. independentFromGnss: " + independentFromGnss
1954 + ", isUserEmergency: "
1955 + isUserEmergency);
Yu-Han Yange7baef32018-02-09 13:58:17 -08001956 }
Yu-Han Yang53f4d6d2019-02-13 21:47:41 -08001957 sendMessage(REQUEST_LOCATION, independentFromGnss ? 1 : 0, isUserEmergency);
Yu-Han Yange7baef32018-02-09 13:58:17 -08001958 }
1959
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001960 @NativeEntryPoint
Mike Lockwood9b9fb5c2011-06-29 15:09:40 -04001961 private void requestUtcTime() {
destradaae21252a2015-09-08 12:32:59 -07001962 if (DEBUG) Log.d(TAG, "utcTimeRequest");
Mike Lockwood9b9fb5c2011-06-29 15:09:40 -04001963 sendMessage(INJECT_NTP_TIME, 0, null);
1964 }
1965
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001966 @NativeEntryPoint
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001967 private void requestRefLocation() {
Miguel Torroja1e84da82010-07-27 07:02:24 +02001968 TelephonyManager phone = (TelephonyManager)
1969 mContext.getSystemService(Context.TELEPHONY_SERVICE);
Victoria Leased50d0c32012-10-29 13:16:17 -07001970 final int phoneType = phone.getPhoneType();
1971 if (phoneType == TelephonyManager.PHONE_TYPE_GSM) {
Miguel Torroja1e84da82010-07-27 07:02:24 +02001972 GsmCellLocation gsm_cell = (GsmCellLocation) phone.getCellLocation();
Victoria Leased50d0c32012-10-29 13:16:17 -07001973 if ((gsm_cell != null) && (phone.getNetworkOperator() != null)
1974 && (phone.getNetworkOperator().length() > 3)) {
Miguel Torroja1e84da82010-07-27 07:02:24 +02001975 int type;
gomo48f1a642017-11-10 20:35:46 -08001976 int mcc = Integer.parseInt(phone.getNetworkOperator().substring(0, 3));
Miguel Torroja1e84da82010-07-27 07:02:24 +02001977 int mnc = Integer.parseInt(phone.getNetworkOperator().substring(3));
Mike Lockwoodedc0f3872010-10-22 09:16:17 -04001978 int networkType = phone.getNetworkType();
1979 if (networkType == TelephonyManager.NETWORK_TYPE_UMTS
gomo48f1a642017-11-10 20:35:46 -08001980 || networkType == TelephonyManager.NETWORK_TYPE_HSDPA
1981 || networkType == TelephonyManager.NETWORK_TYPE_HSUPA
1982 || networkType == TelephonyManager.NETWORK_TYPE_HSPA
1983 || networkType == TelephonyManager.NETWORK_TYPE_HSPAP) {
Miguel Torroja1e84da82010-07-27 07:02:24 +02001984 type = AGPS_REF_LOCATION_TYPE_UMTS_CELLID;
Mike Lockwoodedc0f3872010-10-22 09:16:17 -04001985 } else {
Miguel Torroja1e84da82010-07-27 07:02:24 +02001986 type = AGPS_REF_LOCATION_TYPE_GSM_CELLID;
Mike Lockwoodedc0f3872010-10-22 09:16:17 -04001987 }
Miguel Torroja1e84da82010-07-27 07:02:24 +02001988 native_agps_set_ref_location_cellid(type, mcc, mnc,
1989 gsm_cell.getLac(), gsm_cell.getCid());
Mike Lockwoodedc0f3872010-10-22 09:16:17 -04001990 } else {
gomo48f1a642017-11-10 20:35:46 -08001991 Log.e(TAG, "Error getting cell location info.");
Mike Lockwoodedc0f3872010-10-22 09:16:17 -04001992 }
Victoria Leased50d0c32012-10-29 13:16:17 -07001993 } else if (phoneType == TelephonyManager.PHONE_TYPE_CDMA) {
1994 Log.e(TAG, "CDMA not supported.");
Mike Lockwoodedc0f3872010-10-22 09:16:17 -04001995 }
Miguel Torroja1e84da82010-07-27 07:02:24 +02001996 }
Danke Xie22d1f9f2009-08-18 18:28:45 -04001997
Anil Admal94ec76a2019-01-15 09:42:01 -08001998 // Implements method nfwNotifyCb() in IGnssVisibilityControlCallback.hal.
1999 @NativeEntryPoint
2000 private void reportNfwNotification(String proxyAppPackageName, byte protocolStack,
2001 String otherProtocolStackName, byte requestor, String requestorId, byte responseType,
2002 boolean inEmergencyMode, boolean isCachedLocation) {
2003 if (mGnssVisibilityControl == null) {
2004 Log.e(TAG, "reportNfwNotification: mGnssVisibilityControl is not initialized.");
2005 return;
2006 }
2007
2008 mGnssVisibilityControl.reportNfwNotification(proxyAppPackageName, protocolStack,
2009 otherProtocolStackName, requestor, requestorId, responseType, inEmergencyMode,
2010 isCachedLocation);
2011 }
2012
2013 // Implements method isInEmergencySession() in IGnssVisibilityControlCallback.hal.
2014 @NativeEntryPoint
2015 boolean isInEmergencySession() {
2016 return mNIHandler.getInEmergency();
2017 }
2018
Mike Lockwood98e48692010-04-07 16:32:51 -04002019 private void sendMessage(int message, int arg, Object obj) {
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002020 // hold a wake lock until this message is delivered
Jeff Brown028872f2012-08-25 13:07:01 -07002021 // note that this assumes the message will not be removed from the queue before
2022 // it is handled (otherwise the wake lock would be leaked).
Yu-Han Yang499a6ba2019-11-14 14:19:13 -08002023 mWakeLock.acquire(WAKELOCK_TIMEOUT_MILLIS);
Anil Admal4f97c942018-11-12 10:52:46 -08002024 if (DEBUG) {
2025 Log.d(TAG, "WakeLock acquired by sendMessage(" + messageIdAsString(message) + ", " + arg
Wyatt Rileycf879db2017-01-12 13:57:38 -08002026 + ", " + obj + ")");
2027 }
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002028 mHandler.obtainMessage(message, arg, 1, obj).sendToTarget();
Mike Lockwood98e48692010-04-07 16:32:51 -04002029 }
2030
Mike Lockwood62a8fc12010-03-22 14:23:26 -04002031 private final class ProviderHandler extends Handler {
Victoria Lease5cd731a2012-12-19 15:04:21 -08002032 public ProviderHandler(Looper looper) {
2033 super(looper, null, true /*async*/);
Jeff Brown028872f2012-08-25 13:07:01 -07002034 }
2035
Mike Lockwood62a8fc12010-03-22 14:23:26 -04002036 @Override
Mike Lockwood4a7b65e2010-10-25 16:35:55 -04002037 public void handleMessage(Message msg) {
Mike Lockwood98e48692010-04-07 16:32:51 -04002038 int message = msg.what;
2039 switch (message) {
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002040 case SET_REQUEST:
2041 GpsRequest gpsRequest = (GpsRequest) msg.obj;
2042 handleSetRequest(gpsRequest.request, gpsRequest.source);
Mike Lockwood03ca2162010-04-01 08:10:09 -07002043 break;
Mike Lockwood62a8fc12010-03-22 14:23:26 -04002044 case INJECT_NTP_TIME:
Yu-Han Yanga1862b52018-02-20 17:05:59 -08002045 mNtpTimeHelper.retrieveAndInjectNtpTime();
Mike Lockwood62a8fc12010-03-22 14:23:26 -04002046 break;
Yu-Han Yange7baef32018-02-09 13:58:17 -08002047 case REQUEST_LOCATION:
Yu-Han Yang53f4d6d2019-02-13 21:47:41 -08002048 handleRequestLocation(msg.arg1 == 1, (boolean) msg.obj);
Yu-Han Yange7baef32018-02-09 13:58:17 -08002049 break;
Kevin Tang8c6ac672019-03-22 12:31:01 -07002050 case DOWNLOAD_PSDS_DATA:
2051 handleDownloadPsdsData();
Mike Lockwood62a8fc12010-03-22 14:23:26 -04002052 break;
Kevin Tang8c6ac672019-03-22 12:31:01 -07002053 case DOWNLOAD_PSDS_DATA_FINISHED:
2054 mDownloadPsdsDataPending = STATE_IDLE;
Kevin Tang40e1baf2012-01-10 14:32:44 -08002055 break;
destradaafb23c672015-04-16 14:01:27 -07002056 case INITIALIZE_HANDLER:
destradaae21252a2015-09-08 12:32:59 -07002057 handleInitialize();
destradaafb23c672015-04-16 14:01:27 -07002058 break;
Wyatt Riley26465d22018-02-12 13:44:24 -08002059 case REPORT_LOCATION:
2060 handleReportLocation(msg.arg1 == 1, (Location) msg.obj);
2061 break;
2062 case REPORT_SV_STATUS:
2063 handleReportSvStatus((SvStatusInfo) msg.obj);
2064 break;
Kweku Adams810c77d2019-08-28 07:45:00 -07002065 case UPDATE_LOW_POWER_MODE:
2066 updateLowPowerMode();
2067 break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002068 }
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002069 if (msg.arg2 == 1) {
2070 // wakelock was taken for this message, release it
2071 mWakeLock.release();
Anil Admal4f97c942018-11-12 10:52:46 -08002072 if (DEBUG) {
2073 Log.d(TAG, "WakeLock released by handleMessage(" + messageIdAsString(message)
Wyatt Rileycf879db2017-01-12 13:57:38 -08002074 + ", " + msg.arg1 + ", " + msg.obj + ")");
2075 }
Mike Lockwood98e48692010-04-07 16:32:51 -04002076 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002077 }
destradaafb23c672015-04-16 14:01:27 -07002078
2079 /**
Soonil Nagarkar8df02f42020-01-08 13:23:26 -08002080 * This method is bound to the constructor. It is in charge of loading properties and
2081 * registering for events that will be posted to this handler.
destradaafb23c672015-04-16 14:01:27 -07002082 */
destradaae21252a2015-09-08 12:32:59 -07002083 private void handleInitialize() {
Anil Admal0c2b21bd2019-05-03 18:29:02 -07002084 // class_init_native() already initializes the GNSS service handle during class loading.
2085 setupNativeGnssService(/* reinitializeGnssServiceHandle = */ false);
Wyatt Riley523a0cf2017-10-31 14:36:52 -07002086
Anil Admal94ec76a2019-01-15 09:42:01 -08002087 if (native_is_gnss_visibility_control_supported()) {
Anil Admal8a246a22019-05-05 00:34:55 -07002088 mGnssVisibilityControl = new GnssVisibilityControl(mContext, mLooper, mNIHandler);
Anil Admal94ec76a2019-01-15 09:42:01 -08002089 }
2090
destradaafb23c672015-04-16 14:01:27 -07002091 // load default GPS configuration
2092 // (this configuration might change in the future based on SIM changes)
Anil Admald71cf142018-12-21 14:59:36 -08002093 reloadGpsProperties();
destradaafb23c672015-04-16 14:01:27 -07002094
destradaafb23c672015-04-16 14:01:27 -07002095 // listen for events
WyattRiley6593cf12018-06-23 10:37:48 -07002096 IntentFilter intentFilter = new IntentFilter();
destradaafb23c672015-04-16 14:01:27 -07002097 intentFilter.addAction(ALARM_WAKEUP);
2098 intentFilter.addAction(ALARM_TIMEOUT);
destradaafb23c672015-04-16 14:01:27 -07002099 intentFilter.addAction(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED);
Adam Lesinski87c17df2015-05-27 13:24:13 -07002100 intentFilter.addAction(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED);
destradaafb23c672015-04-16 14:01:27 -07002101 intentFilter.addAction(Intent.ACTION_SCREEN_OFF);
2102 intentFilter.addAction(Intent.ACTION_SCREEN_ON);
Meng Wang19b214d2018-11-07 12:14:39 -08002103 intentFilter.addAction(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
Jayachandran C041e7692019-12-20 16:20:02 -08002104 intentFilter.addAction(TelephonyManager.ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED);
destradaafb23c672015-04-16 14:01:27 -07002105 mContext.registerReceiver(mBroadcastReceiver, intentFilter, null, this);
2106
Anil Admal50ba15e2018-11-01 16:42:42 -07002107 mNetworkConnectivityHandler.registerNetworkCallbacks();
destradaae21252a2015-09-08 12:32:59 -07002108
destradaafb23c672015-04-16 14:01:27 -07002109 // listen for PASSIVE_PROVIDER updates
2110 LocationManager locManager =
2111 (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE);
2112 long minTime = 0;
2113 float minDistance = 0;
destradaafb23c672015-04-16 14:01:27 -07002114 LocationRequest request = LocationRequest.createFromDeprecatedProvider(
2115 LocationManager.PASSIVE_PROVIDER,
2116 minTime,
2117 minDistance,
Soonil Nagarkar1575a042018-10-24 17:54:54 -07002118 false);
destradaafb23c672015-04-16 14:01:27 -07002119 // Don't keep track of this request since it's done on behalf of other clients
2120 // (which are kept track of separately).
2121 request.setHideFromAppOps(true);
2122 locManager.requestLocationUpdates(
2123 request,
2124 new NetworkLocationListener(),
2125 getLooper());
Soonil Nagarkar1575a042018-10-24 17:54:54 -07002126
Soonil Nagarkar35c3b912019-01-31 10:31:24 -08002127 updateEnabled();
destradaafb23c672015-04-16 14:01:27 -07002128 }
2129 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002130
Yu-Han Yange7baef32018-02-09 13:58:17 -08002131 private abstract class LocationChangeListener implements LocationListener {
Soonil Nagarkar1575a042018-10-24 17:54:54 -07002132 private int mNumLocationUpdateRequest;
Yu-Han Yang07561382018-02-21 13:08:37 -08002133
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002134 @Override
gomo48f1a642017-11-10 20:35:46 -08002135 public void onStatusChanged(String provider, int status, Bundle extras) {
2136 }
2137
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002138 @Override
gomo48f1a642017-11-10 20:35:46 -08002139 public void onProviderEnabled(String provider) {
2140 }
2141
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002142 @Override
gomo48f1a642017-11-10 20:35:46 -08002143 public void onProviderDisabled(String provider) {
2144 }
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002145 }
2146
Yu-Han Yange7baef32018-02-09 13:58:17 -08002147 private final class NetworkLocationListener extends LocationChangeListener {
2148 @Override
2149 public void onLocationChanged(Location location) {
2150 // this callback happens on mHandler looper
2151 if (LocationManager.NETWORK_PROVIDER.equals(location.getProvider())) {
Anil Admal2ac70462019-06-28 19:17:41 -07002152 injectLocation(location);
Yu-Han Yange7baef32018-02-09 13:58:17 -08002153 }
2154 }
2155 }
2156
2157 private final class FusedLocationListener extends LocationChangeListener {
2158 @Override
2159 public void onLocationChanged(Location location) {
2160 if (LocationManager.FUSED_PROVIDER.equals(location.getProvider())) {
Yu-Han Yange7baef32018-02-09 13:58:17 -08002161 injectBestLocation(location);
2162 }
2163 }
2164 }
2165
Wyatt Rileycf879db2017-01-12 13:57:38 -08002166 /**
2167 * @return A string representing the given message ID.
2168 */
2169 private String messageIdAsString(int message) {
2170 switch (message) {
Wyatt Rileycf879db2017-01-12 13:57:38 -08002171 case SET_REQUEST:
2172 return "SET_REQUEST";
Wyatt Rileycf879db2017-01-12 13:57:38 -08002173 case INJECT_NTP_TIME:
2174 return "INJECT_NTP_TIME";
Yu-Han Yange7baef32018-02-09 13:58:17 -08002175 case REQUEST_LOCATION:
2176 return "REQUEST_LOCATION";
Kevin Tang8c6ac672019-03-22 12:31:01 -07002177 case DOWNLOAD_PSDS_DATA:
2178 return "DOWNLOAD_PSDS_DATA";
2179 case DOWNLOAD_PSDS_DATA_FINISHED:
2180 return "DOWNLOAD_PSDS_DATA_FINISHED";
Wyatt Rileycf879db2017-01-12 13:57:38 -08002181 case INITIALIZE_HANDLER:
2182 return "INITIALIZE_HANDLER";
Wyatt Riley26465d22018-02-12 13:44:24 -08002183 case REPORT_LOCATION:
2184 return "REPORT_LOCATION";
2185 case REPORT_SV_STATUS:
2186 return "REPORT_SV_STATUS";
Wyatt Rileycf879db2017-01-12 13:57:38 -08002187 default:
2188 return "<Unknown>";
2189 }
2190 }
2191
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002192 @Override
2193 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2194 StringBuilder s = new StringBuilder();
Soonil Nagarkar1c572552019-07-10 13:31:47 -07002195 s.append("mStarted=").append(mStarted).append(" (changed ");
WyattRileyba6072f2019-04-18 07:37:52 -07002196 TimeUtils.formatDuration(SystemClock.elapsedRealtime()
2197 - mStartedChangedElapsedRealtime, s);
2198 s.append(" ago)").append('\n');
Soonil Nagarkar1c572552019-07-10 13:31:47 -07002199 s.append("mFixInterval=").append(mFixInterval).append('\n');
2200 s.append("mLowPowerMode=").append(mLowPowerMode).append('\n');
2201 s.append("mGnssMeasurementsProvider.isRegistered()=")
Wyatt Riley74479bd2018-01-17 08:48:27 -08002202 .append(mGnssMeasurementsProvider.isRegistered()).append('\n');
Soonil Nagarkar1c572552019-07-10 13:31:47 -07002203 s.append("mGnssNavigationMessageProvider.isRegistered()=")
Wyatt Riley74479bd2018-01-17 08:48:27 -08002204 .append(mGnssNavigationMessageProvider.isRegistered()).append('\n');
Soonil Nagarkar1c572552019-07-10 13:31:47 -07002205 s.append("mDisableGpsForPowerManager=").append(mDisableGpsForPowerManager).append('\n');
2206 s.append("mTopHalCapabilities=0x").append(Integer.toHexString(mTopHalCapabilities));
destradaa25e8caf2015-08-24 14:14:44 -07002207 s.append(" ( ");
2208 if (hasCapability(GPS_CAPABILITY_SCHEDULING)) s.append("SCHEDULING ");
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002209 if (hasCapability(GPS_CAPABILITY_MSB)) s.append("MSB ");
2210 if (hasCapability(GPS_CAPABILITY_MSA)) s.append("MSA ");
2211 if (hasCapability(GPS_CAPABILITY_SINGLE_SHOT)) s.append("SINGLE_SHOT ");
2212 if (hasCapability(GPS_CAPABILITY_ON_DEMAND_TIME)) s.append("ON_DEMAND_TIME ");
destradaa25e8caf2015-08-24 14:14:44 -07002213 if (hasCapability(GPS_CAPABILITY_GEOFENCING)) s.append("GEOFENCING ");
2214 if (hasCapability(GPS_CAPABILITY_MEASUREMENTS)) s.append("MEASUREMENTS ");
2215 if (hasCapability(GPS_CAPABILITY_NAV_MESSAGES)) s.append("NAV_MESSAGES ");
Anil Admalefd9dc62019-03-12 17:39:20 -07002216 if (hasCapability(GPS_CAPABILITY_LOW_POWER_MODE)) s.append("LOW_POWER_MODE ");
2217 if (hasCapability(GPS_CAPABILITY_SATELLITE_BLACKLIST)) s.append("SATELLITE_BLACKLIST ");
Anil Admal62c42dc2019-04-03 15:39:22 -07002218 if (hasCapability(GPS_CAPABILITY_MEASUREMENT_CORRECTIONS)) {
2219 s.append("MEASUREMENT_CORRECTIONS ");
2220 }
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002221 s.append(")\n");
Anil Admal3ba0fa92019-04-19 17:43:00 -07002222 if (hasCapability(GPS_CAPABILITY_MEASUREMENT_CORRECTIONS)) {
Soonil Nagarkar1c572552019-07-10 13:31:47 -07002223 s.append("SubHal=MEASUREMENT_CORRECTIONS[");
Anil Admalefd9dc62019-03-12 17:39:20 -07002224 s.append(mGnssMeasurementCorrectionsProvider.toStringCapabilities());
2225 s.append("]\n");
2226 }
Siddharth Raybb608c82017-03-16 11:33:34 -07002227 s.append(mGnssMetrics.dumpGnssMetricsAsText());
Soonil Nagarkar1c572552019-07-10 13:31:47 -07002228 s.append("native internal state: \n");
2229 s.append(" ").append(native_get_internal_state());
Wyatt Rileycf879db2017-01-12 13:57:38 -08002230 s.append("\n");
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002231 pw.append(s);
2232 }
2233
Anil Admal0c2b21bd2019-05-03 18:29:02 -07002234 private void setupNativeGnssService(boolean reinitializeGnssServiceHandle) {
2235 native_init_once(reinitializeGnssServiceHandle);
Anil Admal7e3953b2019-05-04 20:45:22 -07002236
2237 /*
2238 * A cycle of native_init() and native_cleanup() is needed so that callbacks are
2239 * registered after bootup even when location is disabled.
2240 * This will allow Emergency SUPL to work even when location is disabled before device
2241 * restart.
2242 */
2243 boolean isInitialized = native_init();
2244 if (!isInitialized) {
2245 Log.w(TAG, "Native initialization failed.");
2246 } else {
2247 native_cleanup();
2248 }
2249 }
2250
Mike Lockwoodb16e7802009-08-06 09:26:02 -04002251 // preallocated to avoid memory allocation in reportNmea()
2252 private byte[] mNmeaBuffer = new byte[120];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002253
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002254 private static native void class_init_native();
gomo48f1a642017-11-10 20:35:46 -08002255
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002256 private static native boolean native_is_supported();
gomo48f1a642017-11-10 20:35:46 -08002257
Anil Admal94ec76a2019-01-15 09:42:01 -08002258 private static native boolean native_is_gnss_visibility_control_supported();
2259
Anil Admal0c2b21bd2019-05-03 18:29:02 -07002260 private static native void native_init_once(boolean reinitializeGnssServiceHandle);
Yu-Han Yang6d317352018-03-15 11:53:01 -07002261
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002262 private native boolean native_init();
gomo48f1a642017-11-10 20:35:46 -08002263
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002264 private native void native_cleanup();
gomo48f1a642017-11-10 20:35:46 -08002265
Mike Lockwood04598b62010-04-14 17:17:24 -04002266 private native boolean native_set_position_mode(int mode, int recurrence, int min_interval,
gomo48f1a642017-11-10 20:35:46 -08002267 int preferred_accuracy, int preferred_time, boolean lowPowerMode);
2268
Mike Lockwood04598b62010-04-14 17:17:24 -04002269 private native boolean native_start();
gomo48f1a642017-11-10 20:35:46 -08002270
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002271 private native boolean native_stop();
gomo48f1a642017-11-10 20:35:46 -08002272
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002273 private native void native_delete_aiding_data(int flags);
gomo48f1a642017-11-10 20:35:46 -08002274
Mike Lockwoodf602d362010-06-20 14:28:16 -07002275 private native int native_read_nmea(byte[] buffer, int bufferSize);
gomo48f1a642017-11-10 20:35:46 -08002276
Yu-Han Yange7baef32018-02-09 13:58:17 -08002277 private native void native_inject_best_location(
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -08002278 int gnssLocationFlags, double latitudeDegrees, double longitudeDegrees,
2279 double altitudeMeters, float speedMetersPerSec, float bearingDegrees,
2280 float horizontalAccuracyMeters, float verticalAccuracyMeters,
2281 float speedAccuracyMetersPerSecond, float bearingAccuracyDegrees,
Pierre Fite-Georgel9e96c572019-02-25 16:12:53 -08002282 long timestamp, int elapsedRealtimeFlags, long elapsedRealtimeNanos,
Yu-Han Yang3cd9a862019-03-25 17:00:03 -07002283 double elapsedRealtimeUncertaintyNanos);
Yu-Han Yange7baef32018-02-09 13:58:17 -08002284
Mike Lockwoodd26ce0d2009-06-11 12:25:46 -04002285 private native void native_inject_location(double latitude, double longitude, float accuracy);
2286
Kevin Tang8c6ac672019-03-22 12:31:01 -07002287 // PSDS Support
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002288 private native void native_inject_time(long time, long timeReference, int uncertainty);
gomo48f1a642017-11-10 20:35:46 -08002289
Kevin Tang8c6ac672019-03-22 12:31:01 -07002290 private native boolean native_supports_psds();
gomo48f1a642017-11-10 20:35:46 -08002291
Kevin Tang8c6ac672019-03-22 12:31:01 -07002292 private native void native_inject_psds_data(byte[] data, int length);
The Android Open Source Project10592532009-03-18 17:39:46 -07002293
Fred Fettinger3c8fbdf2010-01-04 15:38:13 -06002294 // DEBUG Support
2295 private native String native_get_internal_state();
2296
2297 // AGPS Support
gomo48f1a642017-11-10 20:35:46 -08002298 private native void native_agps_ni_message(byte[] msg, int length);
2299
Mike Lockwooda9e54612009-06-19 14:54:42 -04002300 private native void native_set_agps_server(int type, String hostname, int port);
Danke Xie22d1f9f2009-08-18 18:28:45 -04002301
2302 // Network-initiated (NI) Support
2303 private native void native_send_ni_response(int notificationId, int userResponse);
Miguel Torroja1e84da82010-07-27 07:02:24 +02002304
Anil Admal50ba15e2018-11-01 16:42:42 -07002305 // AGPS ril support
Miguel Torroja1e84da82010-07-27 07:02:24 +02002306 private native void native_agps_set_ref_location_cellid(int type, int mcc, int mnc,
2307 int lac, int cid);
gomo48f1a642017-11-10 20:35:46 -08002308
Miguel Torroja1e84da82010-07-27 07:02:24 +02002309 private native void native_agps_set_id(int type, String setid);
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -08002310}