blob: 0a59e01ddc2b50f2d006f6351c15063ff2ec1927 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Mike Lockwood00b74272010-03-26 10:41:48 -040017package com.android.server.location;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080018
Mike Lockwood29c84342009-05-06 14:01:15 -040019import android.app.AlarmManager;
Dianne Hackborna06de0f2012-12-11 16:34:47 -080020import android.app.AppOpsManager;
Mike Lockwood29c84342009-05-06 14:01:15 -040021import android.app.PendingIntent;
The Android Open Source Project10592532009-03-18 17:39:46 -070022import android.content.BroadcastReceiver;
Yu-Han Yang74041ff2018-04-06 15:57:31 -070023import android.content.ContentResolver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080024import android.content.Context;
25import android.content.Intent;
The Android Open Source Project10592532009-03-18 17:39:46 -070026import android.content.IntentFilter;
destradaa0682809a2013-08-12 18:50:30 -070027import android.hardware.location.GeofenceHardware;
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -070028import android.hardware.location.GeofenceHardwareImpl;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080029import android.location.Criteria;
destradaa0682809a2013-08-12 18:50:30 -070030import android.location.FusedBatchOptions;
Yu-Han Yange7baef32018-02-09 13:58:17 -080031import android.location.GnssMeasurementsEvent;
32import android.location.GnssNavigationMessage;
Lifu Tang30f95a72016-01-07 23:20:38 -080033import android.location.GnssStatus;
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -070034import android.location.IGpsGeofenceHardware;
Danke Xie22d1f9f2009-08-18 18:28:45 -040035import android.location.INetInitiatedListener;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080036import android.location.Location;
Nick Pelly6fa9ad42012-07-16 12:18:23 -070037import android.location.LocationListener;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080038import android.location.LocationManager;
39import android.location.LocationProvider;
Stan Chesnutt1d72d8c2013-04-15 19:18:02 -070040import android.location.LocationRequest;
Kevin Tang40e1baf2012-01-10 14:32:44 -080041import android.os.AsyncTask;
Dianne Hackborn91268cf2013-06-13 19:06:50 -070042import android.os.BatteryStats;
Mike Lockwood63aa5a62010-04-14 19:21:31 -040043import android.os.Binder;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080044import android.os.Bundle;
Mike Lockwood62a8fc12010-03-22 14:23:26 -040045import android.os.Handler;
Victoria Lease5cd731a2012-12-19 15:04:21 -080046import android.os.Looper;
Mike Lockwood62a8fc12010-03-22 14:23:26 -040047import android.os.Message;
Yu-Han Yange7baef32018-02-09 13:58:17 -080048import android.os.PersistableBundle;
Mike Lockwood0528b9b2009-05-07 10:12:54 -040049import android.os.PowerManager;
Yu-Han Yange7baef32018-02-09 13:58:17 -080050import android.os.PowerManager.ServiceType;
51import android.os.PowerSaveState;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080052import android.os.RemoteException;
Mike Lockwood2f82c4e2009-04-17 08:24:10 -040053import android.os.ServiceManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080054import android.os.SystemClock;
Colin Cross7c030ed2014-01-28 09:33:53 -080055import android.os.SystemProperties;
Dianne Hackborn5ac72a22012-08-29 18:32:08 -070056import android.os.UserHandle;
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -070057import android.os.WorkSource;
Narayan Kamath32684dd2018-01-08 17:32:51 +000058import android.os.WorkSource.WorkChain;
Mike Lockwoodbcab8df2009-06-25 16:39:09 -040059import android.provider.Settings;
Yu-Han Yange7baef32018-02-09 13:58:17 -080060import android.telephony.CarrierConfigManager;
Wink Savillea374c3d2014-11-11 11:48:04 -080061import android.telephony.SubscriptionManager;
Wink Savilled09c4ca2014-11-22 10:08:16 -080062import android.telephony.SubscriptionManager.OnSubscriptionsChangedListener;
Miguel Torroja1e84da82010-07-27 07:02:24 +020063import android.telephony.TelephonyManager;
64import android.telephony.gsm.GsmCellLocation;
Colin Cross7c030ed2014-01-28 09:33:53 -080065import android.text.TextUtils;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080066import android.util.Log;
Yu-Han Yang8a1b51d2018-12-26 22:18:31 -080067import android.util.StatsLog;
Yu-Han Yanga1862b52018-02-20 17:05:59 -080068
jackqdyulei455e90a2017-02-09 15:29:16 -080069import com.android.internal.app.IBatteryStats;
70import com.android.internal.location.GpsNetInitiatedHandler;
71import com.android.internal.location.GpsNetInitiatedHandler.GpsNiNotification;
72import com.android.internal.location.ProviderProperties;
73import com.android.internal.location.ProviderRequest;
Yu-Han Yange7baef32018-02-09 13:58:17 -080074import com.android.internal.location.gnssmetrics.GnssMetrics;
Yu-Han Yang66c7ea92018-03-11 17:17:15 -070075import com.android.server.location.GnssSatelliteBlacklistHelper.GnssSatelliteBlacklistCallback;
Yu-Han Yanga1862b52018-02-20 17:05:59 -080076import com.android.server.location.NtpTimeHelper.InjectNtpTimeCallback;
Yu-Han Yang66c7ea92018-03-11 17:17:15 -070077
Nick Pelly6fa9ad42012-07-16 12:18:23 -070078import java.io.FileDescriptor;
Nick Pelly6fa9ad42012-07-16 12:18:23 -070079import java.io.PrintWriter;
Soonil Nagarkar1575a042018-10-24 17:54:54 -070080import java.lang.annotation.ElementType;
81import java.lang.annotation.Retention;
82import java.lang.annotation.RetentionPolicy;
83import java.lang.annotation.Target;
Wyatt Rileycf879db2017-01-12 13:57:38 -080084import java.util.ArrayList;
Andreas Gampee6748ce2015-12-11 18:00:38 -080085import java.util.Arrays;
Wyatt Rileycf879db2017-01-12 13:57:38 -080086import java.util.List;
Yu-Han Yange7baef32018-02-09 13:58:17 -080087
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080088/**
gomo4402af62017-01-11 13:20:13 -080089 * A GNSS implementation of LocationProvider used by LocationManager.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080090 *
91 * {@hide}
92 */
Soonil Nagarkar1575a042018-10-24 17:54:54 -070093public class GnssLocationProvider extends AbstractLocationProvider implements
94 InjectNtpTimeCallback,
95 GnssSatelliteBlacklistCallback {
96
97 /**
98 * Indicates that this method is a native entry point. Useful purely for IDEs which can
99 * understand entry points, and thus eliminate incorrect warnings about methods not used.
100 */
101 @Target(ElementType.METHOD)
102 @Retention(RetentionPolicy.SOURCE)
103 private @interface NativeEntryPoint {
104 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800105
Lifu Tang30f95a72016-01-07 23:20:38 -0800106 private static final String TAG = "GnssLocationProvider";
Mike Lockwood29c84342009-05-06 14:01:15 -0400107
Brian Muramatsu1715cb32012-08-08 17:32:21 -0700108 private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
109 private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400110
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700111 private static final ProviderProperties PROPERTIES = new ProviderProperties(
112 true, true, false, false, true, true, true,
113 Criteria.POWER_HIGH, Criteria.ACCURACY_FINE);
114
gomo4402af62017-01-11 13:20:13 -0800115 // these need to match GnssPositionMode enum in IGnss.hal
The Android Open Source Project10592532009-03-18 17:39:46 -0700116 private static final int GPS_POSITION_MODE_STANDALONE = 0;
117 private static final int GPS_POSITION_MODE_MS_BASED = 1;
118 private static final int GPS_POSITION_MODE_MS_ASSISTED = 2;
119
gomo4402af62017-01-11 13:20:13 -0800120 // these need to match GnssPositionRecurrence enum in IGnss.hal
Mike Lockwood04598b62010-04-14 17:17:24 -0400121 private static final int GPS_POSITION_RECURRENCE_PERIODIC = 0;
122 private static final int GPS_POSITION_RECURRENCE_SINGLE = 1;
123
gomo4402af62017-01-11 13:20:13 -0800124 // these need to match GnssStatusValue enum in IGnssCallback.hal
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800125 private static final int GPS_STATUS_NONE = 0;
126 private static final int GPS_STATUS_SESSION_BEGIN = 1;
127 private static final int GPS_STATUS_SESSION_END = 2;
128 private static final int GPS_STATUS_ENGINE_ON = 3;
129 private static final int GPS_STATUS_ENGINE_OFF = 4;
130
gomo4402af62017-01-11 13:20:13 -0800131 // these need to match GnssLocationFlags enum in types.hal
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800132 private static final int LOCATION_INVALID = 0;
133 private static final int LOCATION_HAS_LAT_LONG = 1;
134 private static final int LOCATION_HAS_ALTITUDE = 2;
135 private static final int LOCATION_HAS_SPEED = 4;
136 private static final int LOCATION_HAS_BEARING = 8;
gomo4402af62017-01-11 13:20:13 -0800137 private static final int LOCATION_HAS_HORIZONTAL_ACCURACY = 16;
138 private static final int LOCATION_HAS_VERTICAL_ACCURACY = 32;
139 private static final int LOCATION_HAS_SPEED_ACCURACY = 64;
140 private static final int LOCATION_HAS_BEARING_ACCURACY = 128;
Mike Lockwoode3635c92009-05-11 08:38:02 -0400141
gomo4402af62017-01-11 13:20:13 -0800142 // IMPORTANT - the GPS_DELETE_* symbols here must match GnssAidingData enum in IGnss.hal
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800143 private static final int GPS_DELETE_EPHEMERIS = 0x0001;
144 private static final int GPS_DELETE_ALMANAC = 0x0002;
145 private static final int GPS_DELETE_POSITION = 0x0004;
146 private static final int GPS_DELETE_TIME = 0x0008;
147 private static final int GPS_DELETE_IONO = 0x0010;
148 private static final int GPS_DELETE_UTC = 0x0020;
149 private static final int GPS_DELETE_HEALTH = 0x0040;
150 private static final int GPS_DELETE_SVDIR = 0x0080;
151 private static final int GPS_DELETE_SVSTEER = 0x0100;
152 private static final int GPS_DELETE_SADATA = 0x0200;
153 private static final int GPS_DELETE_RTI = 0x0400;
154 private static final int GPS_DELETE_CELLDB_INFO = 0x8000;
155 private static final int GPS_DELETE_ALL = 0xFFFF;
156
gomo4402af62017-01-11 13:20:13 -0800157 // The GPS_CAPABILITY_* flags must match Capabilities enum in IGnssCallback.hal
Mike Lockwood04598b62010-04-14 17:17:24 -0400158 private static final int GPS_CAPABILITY_SCHEDULING = 0x0000001;
159 private static final int GPS_CAPABILITY_MSB = 0x0000002;
160 private static final int GPS_CAPABILITY_MSA = 0x0000004;
161 private static final int GPS_CAPABILITY_SINGLE_SHOT = 0x0000008;
Mike Lockwood9b9fb5c2011-06-29 15:09:40 -0400162 private static final int GPS_CAPABILITY_ON_DEMAND_TIME = 0x0000010;
destradaa6568d702014-10-27 12:47:41 -0700163 private static final int GPS_CAPABILITY_GEOFENCING = 0x0000020;
gomo226b7b72018-12-12 16:49:39 -0800164 public static final int GPS_CAPABILITY_MEASUREMENTS = 0x0000040;
destradaa6568d702014-10-27 12:47:41 -0700165 private static final int GPS_CAPABILITY_NAV_MESSAGES = 0x0000080;
Mike Lockwood04598b62010-04-14 17:17:24 -0400166
Tsuwei Chen462bcd82014-09-17 12:28:49 -0700167 // The AGPS SUPL mode
168 private static final int AGPS_SUPL_MODE_MSA = 0x02;
169 private static final int AGPS_SUPL_MODE_MSB = 0x01;
170
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400171 // Handler messages
172 private static final int CHECK_LOCATION = 1;
173 private static final int ENABLE = 2;
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700174 private static final int SET_REQUEST = 3;
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400175 private static final int UPDATE_NETWORK_STATE = 4;
176 private static final int INJECT_NTP_TIME = 5;
177 private static final int DOWNLOAD_XTRA_DATA = 6;
Wyatt Rileyc7067412018-02-07 15:50:35 -0800178 private static final int UPDATE_LOCATION = 7; // Handle external location from network listener
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400179 private static final int ADD_LISTENER = 8;
180 private static final int REMOVE_LISTENER = 9;
Kevin Tang40e1baf2012-01-10 14:32:44 -0800181 private static final int DOWNLOAD_XTRA_DATA_FINISHED = 11;
Meng Wang19b214d2018-11-07 12:14:39 -0800182 private static final int SUBSCRIPTION_OR_CARRIER_CONFIG_CHANGED = 12;
destradaafb23c672015-04-16 14:01:27 -0700183 private static final int INITIALIZE_HANDLER = 13;
destradaae21252a2015-09-08 12:32:59 -0700184 private static final int REQUEST_SUPL_CONNECTION = 14;
185 private static final int RELEASE_SUPL_CONNECTION = 15;
Yu-Han Yange7baef32018-02-09 13:58:17 -0800186 private static final int REQUEST_LOCATION = 16;
Wyatt Riley26465d22018-02-12 13:44:24 -0800187 private static final int REPORT_LOCATION = 17; // HAL reports location
188 private static final int REPORT_SV_STATUS = 18; // HAL reports SV status
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400189
Miguel Torroja1e84da82010-07-27 07:02:24 +0200190 // Request setid
191 private static final int AGPS_RIL_REQUEST_SETID_IMSI = 1;
192 private static final int AGPS_RIL_REQUEST_SETID_MSISDN = 2;
193
Miguel Torroja1e84da82010-07-27 07:02:24 +0200194 // ref. location info
195 private static final int AGPS_REF_LOCATION_TYPE_GSM_CELLID = 1;
196 private static final int AGPS_REF_LOCATION_TYPE_UMTS_CELLID = 2;
Miguel Torroja1e84da82010-07-27 07:02:24 +0200197
198 // set id info
199 private static final int AGPS_SETID_TYPE_NONE = 0;
200 private static final int AGPS_SETID_TYPE_IMSI = 1;
201 private static final int AGPS_SETID_TYPE_MSISDN = 2;
202
gomo48f1a642017-11-10 20:35:46 -0800203 private static final int GPS_GEOFENCE_UNAVAILABLE = 1 << 0L;
204 private static final int GPS_GEOFENCE_AVAILABLE = 1 << 1L;
destradaa0682809a2013-08-12 18:50:30 -0700205
gomo4402af62017-01-11 13:20:13 -0800206 // GPS Geofence errors. Should match GeofenceStatus enum in IGnssGeofenceCallback.hal.
destradaa0682809a2013-08-12 18:50:30 -0700207 private static final int GPS_GEOFENCE_OPERATION_SUCCESS = 0;
208 private static final int GPS_GEOFENCE_ERROR_TOO_MANY_GEOFENCES = 100;
gomo48f1a642017-11-10 20:35:46 -0800209 private static final int GPS_GEOFENCE_ERROR_ID_EXISTS = -101;
destradaa0682809a2013-08-12 18:50:30 -0700210 private static final int GPS_GEOFENCE_ERROR_ID_UNKNOWN = -102;
211 private static final int GPS_GEOFENCE_ERROR_INVALID_TRANSITION = -103;
212 private static final int GPS_GEOFENCE_ERROR_GENERIC = -149;
213
Tsuwei Chen678c13c2014-09-22 17:48:41 -0700214 // TCP/IP constants.
215 // Valid TCP/UDP port range is (0, 65535].
216 private static final int TCP_MIN_PORT = 0;
217 private static final int TCP_MAX_PORT = 0xffff;
218
Yu-Han Yange7baef32018-02-09 13:58:17 -0800219 // 1 second, or 1 Hz frequency.
220 private static final long LOCATION_UPDATE_MIN_TIME_INTERVAL_MILLIS = 1000;
Yu-Han Yang639f7592018-06-07 11:58:52 -0700221 // Default update duration in milliseconds for REQUEST_LOCATION.
Yu-Han Yang9e2a8232018-06-14 12:10:08 -0700222 private static final long LOCATION_UPDATE_DURATION_MILLIS = 10 * 1000;
Yu-Han Yange7baef32018-02-09 13:58:17 -0800223
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700224 /** simpler wrapper for ProviderRequest + Worksource */
225 private static class GpsRequest {
226 public ProviderRequest request;
227 public WorkSource source;
gomo48f1a642017-11-10 20:35:46 -0800228
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700229 public GpsRequest(ProviderRequest request, WorkSource source) {
230 this.request = request;
231 this.source = source;
232 }
233 }
234
Wyatt Riley26465d22018-02-12 13:44:24 -0800235 // Threadsafe class to hold stats reported in the Extras Bundle
Wyatt Rileyc7067412018-02-07 15:50:35 -0800236 private static class LocationExtras {
237 private int mSvCount;
238 private int mMeanCn0;
239 private int mMaxCn0;
240 private final Bundle mBundle;
241
242 public LocationExtras() {
243 mBundle = new Bundle();
244 }
245
246 public void set(int svCount, int meanCn0, int maxCn0) {
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700247 synchronized (this) {
Wyatt Riley26465d22018-02-12 13:44:24 -0800248 mSvCount = svCount;
249 mMeanCn0 = meanCn0;
250 mMaxCn0 = maxCn0;
251 }
Wyatt Rileyc7067412018-02-07 15:50:35 -0800252 setBundle(mBundle);
253 }
254
255 public void reset() {
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700256 set(0, 0, 0);
Wyatt Rileyc7067412018-02-07 15:50:35 -0800257 }
258
259 // Also used by outside methods to add to other bundles
260 public void setBundle(Bundle extras) {
261 if (extras != null) {
Wyatt Riley26465d22018-02-12 13:44:24 -0800262 synchronized (this) {
263 extras.putInt("satellites", mSvCount);
264 extras.putInt("meanCn0", mMeanCn0);
265 extras.putInt("maxCn0", mMaxCn0);
266 }
Wyatt Rileyc7067412018-02-07 15:50:35 -0800267 }
268 }
269
270 public Bundle getBundle() {
Wyatt Riley26465d22018-02-12 13:44:24 -0800271 synchronized (this) {
272 return new Bundle(mBundle);
273 }
Wyatt Rileyc7067412018-02-07 15:50:35 -0800274 }
275 }
276
Yu-Han Yang66c7ea92018-03-11 17:17:15 -0700277 private final Object mLock = new Object();
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700278
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800279 // current status
Mike Lockwood15e3d0f2009-05-01 07:53:28 -0400280 private int mStatus = LocationProvider.TEMPORARILY_UNAVAILABLE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800281
282 // time for last status update
283 private long mStatusUpdateTime = SystemClock.elapsedRealtime();
Mike Lockwoodd53ba012010-04-15 20:41:26 -0400284
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800285 // turn off GPS fix icon if we haven't received a fix in 10 seconds
Mike Lockwood04598b62010-04-14 17:17:24 -0400286 private static final long RECENT_FIX_TIMEOUT = 10 * 1000;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800287
Mike Lockwood0632ca72009-05-14 15:51:03 -0400288 // stop trying if we do not receive a fix within 60 seconds
Mike Lockwood04598b62010-04-14 17:17:24 -0400289 private static final int NO_FIX_TIMEOUT = 60 * 1000;
Mike Lockwood0632ca72009-05-14 15:51:03 -0400290
Nick Pellyb041f232012-05-07 17:12:25 -0700291 // if the fix interval is below this we leave GPS on,
292 // if above then we cycle the GPS driver.
293 // Typical hot TTTF is ~5 seconds, so 10 seconds seems sane.
294 private static final int GPS_POLLING_THRESHOLD_INTERVAL = 10 * 1000;
295
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700296 // how long to wait if we have a network error in NTP or XTRA downloading
Wei Liu6f6326b2015-06-24 23:47:50 -0700297 // the initial value of the exponential backoff
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700298 // current setting - 5 minutes
gomo48f1a642017-11-10 20:35:46 -0800299 private static final long RETRY_INTERVAL = 5 * 60 * 1000;
Wei Liu6f6326b2015-06-24 23:47:50 -0700300 // how long to wait if we have a network error in NTP or XTRA downloading
301 // the max value of the exponential backoff
302 // current setting - 4 hours
gomo48f1a642017-11-10 20:35:46 -0800303 private static final long MAX_RETRY_INTERVAL = 4 * 60 * 60 * 1000;
Wei Liu6f6326b2015-06-24 23:47:50 -0700304
Wei Wangc5706f62017-04-18 11:26:26 -0700305 // Timeout when holding wakelocks for downloading XTRA data.
306 private static final long DOWNLOAD_XTRA_DATA_TIMEOUT_MS = 60 * 1000;
307
Yu-Han Yanga1862b52018-02-20 17:05:59 -0800308 private final ExponentialBackOff mXtraBackOff = new ExponentialBackOff(RETRY_INTERVAL,
309 MAX_RETRY_INTERVAL);
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700310
311 // true if we are enabled, protected by this
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700312 private boolean mEnabled = true;
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700313
Kevin Tang40e1baf2012-01-10 14:32:44 -0800314 // states for injecting ntp and downloading xtra data
315 private static final int STATE_PENDING_NETWORK = 0;
316 private static final int STATE_DOWNLOADING = 1;
317 private static final int STATE_IDLE = 2;
318
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400319 // flags to trigger NTP or XTRA data download when network becomes available
320 // initialized to true so we do NTP and XTRA when the network comes up after booting
Kevin Tang40e1baf2012-01-10 14:32:44 -0800321 private int mDownloadXtraDataPending = STATE_PENDING_NETWORK;
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400322
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800323 // true if GPS is navigating
324 private boolean mNavigating;
Mike Lockwoodcf1d8cb2010-01-20 10:14:54 -0500325
Mike Lockwood04598b62010-04-14 17:17:24 -0400326 // requested frequency of fixes, in milliseconds
327 private int mFixInterval = 1000;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800328
gomo48f1a642017-11-10 20:35:46 -0800329 // true if low power mode for the GNSS chipset is part of the latest request.
330 private boolean mLowPowerMode = false;
331
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800332 // true if we started navigation
333 private boolean mStarted;
334
Mike Lockwood04598b62010-04-14 17:17:24 -0400335 // capabilities of the GPS engine
336 private int mEngineCapabilities;
337
Mike Lockwood1a1cd3a2010-08-17 07:42:54 -0400338 // true if XTRA is supported
339 private boolean mSupportsXtra;
340
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800341 // for calculating time to first fix
342 private long mFixRequestTime = 0;
343 // time to first fix for most recent session
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700344 private int mTimeToFirstFix = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800345 // time we received our last fix
346 private long mLastFixTime;
347
Mike Lockwood04598b62010-04-14 17:17:24 -0400348 private int mPositionMode;
Yu-Han Yangc8b9ff72018-04-17 00:47:24 -0700349 private GnssPositionMode mLastPositionMode;
Mike Lockwood04598b62010-04-14 17:17:24 -0400350
David Christied4edf4c2014-08-12 15:22:27 -0700351 // Current request from underlying location clients.
352 private ProviderRequest mProviderRequest = null;
Narayan Kamath32684dd2018-01-08 17:32:51 +0000353 // The WorkSource associated with the most recent client request (i.e, most recent call to
354 // setRequest).
David Christied4edf4c2014-08-12 15:22:27 -0700355 private WorkSource mWorkSource = null;
356 // True if gps should be disabled (used to support battery saver mode in settings).
357 private boolean mDisableGps = false;
358
destradaafb23c672015-04-16 14:01:27 -0700359 /**
360 * Properties loaded from PROPERTIES_FILE.
361 * It must be accessed only inside {@link #mHandler}.
362 */
Anil Admald71cf142018-12-21 14:59:36 -0800363 private GnssConfiguration mGnssConfiguration;
destradaafb23c672015-04-16 14:01:27 -0700364
Mike Lockwood734d6032009-07-28 18:30:25 -0700365 private String mSuplServerHost;
Tsuwei Chen678c13c2014-09-22 17:48:41 -0700366 private int mSuplServerPort = TCP_MIN_PORT;
Mike Lockwood734d6032009-07-28 18:30:25 -0700367 private String mC2KServerHost;
368 private int mC2KServerPort;
Tsuwei Chen3324e952014-09-07 01:30:42 -0700369 private boolean mSuplEsEnabled = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800370
Anil Admal94ec76a2019-01-15 09:42:01 -0800371 private final Looper mLooper;
Wyatt Rileyc7067412018-02-07 15:50:35 -0800372 private final LocationExtras mLocationExtras = new LocationExtras();
Anil Admal75b9fd62018-11-28 11:22:50 -0800373 private final GnssStatusListenerHelper mGnssStatusListenerHelper;
Yu-Han Yang66c7ea92018-03-11 17:17:15 -0700374 private final GnssSatelliteBlacklistHelper mGnssSatelliteBlacklistHelper;
Lifu Tang818aa2c2016-02-01 01:52:00 -0800375 private final GnssMeasurementsProvider mGnssMeasurementsProvider;
376 private final GnssNavigationMessageProvider mGnssNavigationMessageProvider;
Yu-Han Yang07561382018-02-21 13:08:37 -0800377 private final LocationChangeListener mNetworkLocationListener = new NetworkLocationListener();
378 private final LocationChangeListener mFusedLocationListener = new FusedLocationListener();
Yu-Han Yanga1862b52018-02-20 17:05:59 -0800379 private final NtpTimeHelper mNtpTimeHelper;
Yu-Han Yang3557cc72018-03-21 12:48:36 -0700380 private final GnssBatchingProvider mGnssBatchingProvider;
Yu-Han Yang890ca8b2018-04-16 22:11:31 -0700381 private final GnssGeofenceProvider mGnssGeofenceProvider;
Anil Admal94ec76a2019-01-15 09:42:01 -0800382 private GnssVisibilityControl mGnssVisibilityControl;
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400383
Victoria Lease5c24fd02012-10-01 11:00:50 -0700384 // Handler for processing events
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400385 private Handler mHandler;
The Android Open Source Project10592532009-03-18 17:39:46 -0700386
Anil Admal50ba15e2018-11-01 16:42:42 -0700387 private final GnssNetworkConnectivityHandler mNetworkConnectivityHandler;
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700388 private final GpsNetInitiatedHandler mNIHandler;
Mike Lockwood2f82c4e2009-04-17 08:24:10 -0400389
Mike Lockwood0528b9b2009-05-07 10:12:54 -0400390 // Wakelocks
Lifu Tang30f95a72016-01-07 23:20:38 -0800391 private final static String WAKELOCK_KEY = "GnssLocationProvider";
Mike Lockwood0528b9b2009-05-07 10:12:54 -0400392 private final PowerManager.WakeLock mWakeLock;
Wei Wangb71c0492017-05-01 20:24:19 -0700393 private static final String DOWNLOAD_EXTRA_WAKELOCK_KEY = "GnssLocationProviderXtraDownload";
394 private final PowerManager.WakeLock mDownloadXtraWakeLock;
Mike Lockwood0528b9b2009-05-07 10:12:54 -0400395
Mike Lockwood29c84342009-05-06 14:01:15 -0400396 // Alarms
397 private final static String ALARM_WAKEUP = "com.android.internal.location.ALARM_WAKEUP";
Mike Lockwood0632ca72009-05-14 15:51:03 -0400398 private final static String ALARM_TIMEOUT = "com.android.internal.location.ALARM_TIMEOUT";
Tsuwei Chen52617bb2014-08-25 11:49:11 -0700399
David Christied4edf4c2014-08-12 15:22:27 -0700400 private final PowerManager mPowerManager;
Mike Lockwood29c84342009-05-06 14:01:15 -0400401 private final AlarmManager mAlarmManager;
402 private final PendingIntent mWakeupIntent;
Mike Lockwood0632ca72009-05-14 15:51:03 -0400403 private final PendingIntent mTimeoutIntent;
Mike Lockwood29c84342009-05-06 14:01:15 -0400404
Svet Ganovf7b47252018-02-26 11:11:27 -0800405 private final AppOpsManager mAppOps;
Mike Lockwood2f82c4e2009-04-17 08:24:10 -0400406 private final IBatteryStats mBatteryStats;
The Android Open Source Project10592532009-03-18 17:39:46 -0700407
Narayan Kamath32684dd2018-01-08 17:32:51 +0000408 // Current list of underlying location clients.
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700409 // only modified on handler thread
Dianne Hackborn002a54e2013-01-10 17:34:55 -0800410 private WorkSource mClientSource = new WorkSource();
Mike Lockwoodf1218be2010-01-29 09:20:06 -0500411
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -0700412 private GeofenceHardwareImpl mGeofenceHardwareImpl;
Wyatt Rileyd87cf912017-12-05 09:31:52 -0800413
414 // Volatile for simple inter-thread sync on these values.
415 private volatile int mHardwareYear = 0;
Wyatt Riley49097c02018-03-15 09:14:43 -0700416 private volatile String mHardwareModelName;
Lifu Tang82f893d2016-01-21 18:15:33 -0800417
Wyatt Riley5d5bac82016-11-01 07:05:16 -0700418 // Set lower than the current ITAR limit of 600m/s to allow this to trigger even if GPS HAL
419 // stops output right at 600m/s, depriving this of the information of a device that reaches
420 // greater than 600m/s, and higher than the speed of sound to avoid impacting most use cases.
421 private static final float ITAR_SPEED_LIMIT_METERS_PER_SECOND = 400.0F;
Wyatt Riley042c48f2017-10-06 14:59:25 -0700422
Wyatt Riley042c48f2017-10-06 14:59:25 -0700423 private volatile boolean mItarSpeedLimitExceeded = false;
Wyatt Riley5d5bac82016-11-01 07:05:16 -0700424
Siddharth Raybb608c82017-03-16 11:33:34 -0700425 // GNSS Metrics
426 private GnssMetrics mGnssMetrics;
427
Anil Admal75b9fd62018-11-28 11:22:50 -0800428 public GnssStatusListenerHelper getGnssStatusProvider() {
429 return mGnssStatusListenerHelper;
Mike Lockwood15e3d0f2009-05-01 07:53:28 -0400430 }
431
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -0700432 public IGpsGeofenceHardware getGpsGeofenceProxy() {
Yu-Han Yang890ca8b2018-04-16 22:11:31 -0700433 return mGnssGeofenceProvider;
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -0700434 }
435
Lifu Tang818aa2c2016-02-01 01:52:00 -0800436 public GnssMeasurementsProvider getGnssMeasurementsProvider() {
437 return mGnssMeasurementsProvider;
destradaaea8a8a62014-06-23 18:19:03 -0700438 }
439
Lifu Tang818aa2c2016-02-01 01:52:00 -0800440 public GnssNavigationMessageProvider getGnssNavigationMessageProvider() {
441 return mGnssNavigationMessageProvider;
destradaa4b3e3932014-07-21 18:01:47 -0700442 }
Tsuwei Chen52617bb2014-08-25 11:49:11 -0700443 private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
gomo48f1a642017-11-10 20:35:46 -0800444 @Override
445 public void onReceive(Context context, Intent intent) {
The Android Open Source Project10592532009-03-18 17:39:46 -0700446 String action = intent.getAction();
Tsuwei Chen48d37f92014-09-05 15:15:34 -0700447 if (DEBUG) Log.d(TAG, "receive broadcast intent, action: " + action);
destradaaee9fd342015-08-31 13:31:17 -0700448 if (action == null) {
449 return;
450 }
451
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700452 switch (action) {
453 case ALARM_WAKEUP:
Yu-Han Yang6a5f0b72019-01-24 18:34:28 -0800454 startNavigating();
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700455 break;
456 case ALARM_TIMEOUT:
457 hibernate();
458 break;
459 case PowerManager.ACTION_POWER_SAVE_MODE_CHANGED:
460 case PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED:
461 case Intent.ACTION_SCREEN_OFF:
462 case Intent.ACTION_SCREEN_ON:
463 updateLowPowerMode();
464 break;
Meng Wang19b214d2018-11-07 12:14:39 -0800465 case CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED:
466 subscriptionOrCarrierConfigChanged(context);
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700467 break;
David Christied4edf4c2014-08-12 15:22:27 -0700468 }
The Android Open Source Project10592532009-03-18 17:39:46 -0700469 }
Mike Lockwood29c84342009-05-06 14:01:15 -0400470 };
The Android Open Source Project10592532009-03-18 17:39:46 -0700471
Meng Wang19b214d2018-11-07 12:14:39 -0800472 // TODO(b/119326010): replace OnSubscriptionsChangedListener with
473 // ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED broadcast reseiver.
Wink Savilled09c4ca2014-11-22 10:08:16 -0800474 private final OnSubscriptionsChangedListener mOnSubscriptionsChangedListener =
475 new OnSubscriptionsChangedListener() {
gomo48f1a642017-11-10 20:35:46 -0800476 @Override
477 public void onSubscriptionsChanged() {
Meng Wang19b214d2018-11-07 12:14:39 -0800478 sendMessage(SUBSCRIPTION_OR_CARRIER_CONFIG_CHANGED, 0, null);
gomo48f1a642017-11-10 20:35:46 -0800479 }
480 };
Wink Savillea374c3d2014-11-11 11:48:04 -0800481
Yu-Han Yang66c7ea92018-03-11 17:17:15 -0700482 /**
483 * Implements {@link GnssSatelliteBlacklistCallback#onUpdateSatelliteBlacklist}.
484 */
485 @Override
486 public void onUpdateSatelliteBlacklist(int[] constellations, int[] svids) {
Anil Admald71cf142018-12-21 14:59:36 -0800487 mHandler.post(() -> mGnssConfiguration.setSatelliteBlacklist(constellations, svids));
Yu-Han Yang66c7ea92018-03-11 17:17:15 -0700488 }
489
Meng Wang19b214d2018-11-07 12:14:39 -0800490 private void subscriptionOrCarrierConfigChanged(Context context) {
Joe Onorato0c484102016-02-01 18:04:24 -0800491 if (DEBUG) Log.d(TAG, "received SIM related action: ");
Wink Savillea374c3d2014-11-11 11:48:04 -0800492 TelephonyManager phone = (TelephonyManager)
493 mContext.getSystemService(Context.TELEPHONY_SERVICE);
Ecco Park4fa1ab72016-10-24 13:04:52 -0700494 CarrierConfigManager configManager = (CarrierConfigManager)
495 mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE);
Wink Savillea374c3d2014-11-11 11:48:04 -0800496 String mccMnc = phone.getSimOperator();
Ecco Park4fa1ab72016-10-24 13:04:52 -0700497 boolean isKeepLppProfile = false;
Wink Savillea374c3d2014-11-11 11:48:04 -0800498 if (!TextUtils.isEmpty(mccMnc)) {
Joe Onorato0c484102016-02-01 18:04:24 -0800499 if (DEBUG) Log.d(TAG, "SIM MCC/MNC is available: " + mccMnc);
Wink Savillea374c3d2014-11-11 11:48:04 -0800500 synchronized (mLock) {
Ecco Park4fa1ab72016-10-24 13:04:52 -0700501 if (configManager != null) {
502 PersistableBundle b = configManager.getConfig();
Wyatt Rileya8ce2252017-09-01 13:31:17 -0700503 if (b != null) {
504 isKeepLppProfile =
Meng Wang19b214d2018-11-07 12:14:39 -0800505 b.getBoolean(CarrierConfigManager.Gps.KEY_PERSIST_LPP_MODE_BOOL);
Wyatt Rileya8ce2252017-09-01 13:31:17 -0700506 }
Ecco Park4fa1ab72016-10-24 13:04:52 -0700507 }
508 if (isKeepLppProfile) {
509 // load current properties for the carrier
Anil Admald71cf142018-12-21 14:59:36 -0800510 mGnssConfiguration.loadPropertiesFromCarrierConfig();
511 String lpp_profile = mGnssConfiguration.getLppProfile();
Ecco Park4fa1ab72016-10-24 13:04:52 -0700512 // set the persist property LPP_PROFILE for the value
Ecco Park8eec7442017-08-04 16:21:59 -0700513 if (lpp_profile != null) {
Anil Admald71cf142018-12-21 14:59:36 -0800514 SystemProperties.set(GnssConfiguration.LPP_PROFILE, lpp_profile);
Ecco Park8eec7442017-08-04 16:21:59 -0700515 }
Ecco Park624ac3c2016-07-18 14:08:05 -0700516 } else {
Ecco Park4fa1ab72016-10-24 13:04:52 -0700517 // reset the persist property
Anil Admald71cf142018-12-21 14:59:36 -0800518 SystemProperties.set(GnssConfiguration.LPP_PROFILE, "");
Ecco Park624ac3c2016-07-18 14:08:05 -0700519 }
Anil Admald71cf142018-12-21 14:59:36 -0800520 reloadGpsProperties();
Wink Savillea374c3d2014-11-11 11:48:04 -0800521 mNIHandler.setSuplEsEnabled(mSuplEsEnabled);
522 }
523 } else {
Joe Onorato0c484102016-02-01 18:04:24 -0800524 if (DEBUG) Log.d(TAG, "SIM MCC/MNC is still not available");
Wink Savillea374c3d2014-11-11 11:48:04 -0800525 }
526 }
527
David Christied4edf4c2014-08-12 15:22:27 -0700528 private void updateLowPowerMode() {
Adam Lesinski87c17df2015-05-27 13:24:13 -0700529 // Disable GPS if we are in device idle mode.
530 boolean disableGps = mPowerManager.isDeviceIdleMode();
jackqdyulei455e90a2017-02-09 15:29:16 -0800531 final PowerSaveState result =
532 mPowerManager.getPowerSaveState(ServiceType.GPS);
533 switch (result.gpsMode) {
Makoto Onuki57f0f552017-12-11 12:22:18 -0800534 case PowerManager.LOCATION_MODE_GPS_DISABLED_WHEN_SCREEN_OFF:
Adam Lesinski87c17df2015-05-27 13:24:13 -0700535 // If we are in battery saver mode and the screen is off, disable GPS.
jackqdyulei455e90a2017-02-09 15:29:16 -0800536 disableGps |= result.batterySaverEnabled && !mPowerManager.isInteractive();
David Christied4edf4c2014-08-12 15:22:27 -0700537 break;
David Christied4edf4c2014-08-12 15:22:27 -0700538 }
539 if (disableGps != mDisableGps) {
540 mDisableGps = disableGps;
541 updateRequirements();
542 }
543 }
544
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800545 public static boolean isSupported() {
546 return native_is_supported();
547 }
548
Anil Admald71cf142018-12-21 14:59:36 -0800549 private void reloadGpsProperties() {
550 mGnssConfiguration.reloadGpsProperties();
551 setSuplHostPort();
Tsuwei Chen52617bb2014-08-25 11:49:11 -0700552 // TODO: we should get rid of C2K specific setting.
Anil Admald71cf142018-12-21 14:59:36 -0800553 mC2KServerHost = mGnssConfiguration.getC2KHost();
554 mC2KServerPort = mGnssConfiguration.getC2KPort(TCP_MIN_PORT);
555 mNIHandler.setEmergencyExtensionSeconds(mGnssConfiguration.getEsExtensionSec());
556 mSuplEsEnabled = mGnssConfiguration.getSuplEs(0) == 1;
Anil Admal94ec76a2019-01-15 09:42:01 -0800557 if (mGnssVisibilityControl != null) {
558 mGnssVisibilityControl.updateProxyApps(mGnssConfiguration.getProxyApps());
559 }
Colin Cross7c030ed2014-01-28 09:33:53 -0800560 }
561
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700562 public GnssLocationProvider(Context context, LocationProviderManager locationProviderManager,
Victoria Lease5cd731a2012-12-19 15:04:21 -0800563 Looper looper) {
Soonil Nagarkar0d77ea62019-01-31 14:36:56 -0800564 super(context, locationProviderManager);
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700565
Anil Admal94ec76a2019-01-15 09:42:01 -0800566 mLooper = looper;
Mike Lockwood63598a02010-02-24 11:52:59 -0500567
Mike Lockwood0528b9b2009-05-07 10:12:54 -0400568 // Create a wake lock
David Christied4edf4c2014-08-12 15:22:27 -0700569 mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
570 mWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, WAKELOCK_KEY);
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700571 mWakeLock.setReferenceCounted(true);
Mike Lockwood0528b9b2009-05-07 10:12:54 -0400572
Wei Wangb71c0492017-05-01 20:24:19 -0700573 // Create a separate wake lock for xtra downloader as it may be released due to timeout.
574 mDownloadXtraWakeLock = mPowerManager.newWakeLock(
575 PowerManager.PARTIAL_WAKE_LOCK, DOWNLOAD_EXTRA_WAKELOCK_KEY);
576 mDownloadXtraWakeLock.setReferenceCounted(true);
577
gomo48f1a642017-11-10 20:35:46 -0800578 mAlarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
Mike Lockwood29c84342009-05-06 14:01:15 -0400579 mWakeupIntent = PendingIntent.getBroadcast(mContext, 0, new Intent(ALARM_WAKEUP), 0);
Mike Lockwood0632ca72009-05-14 15:51:03 -0400580 mTimeoutIntent = PendingIntent.getBroadcast(mContext, 0, new Intent(ALARM_TIMEOUT), 0);
Mike Lockwood29c84342009-05-06 14:01:15 -0400581
Anil Admal50ba15e2018-11-01 16:42:42 -0700582 mNetworkConnectivityHandler = new GnssNetworkConnectivityHandler(
583 context,
584 GnssLocationProvider.this::onNetworkAvailable,
585 looper);
Mike Lockwood58bda982009-04-14 16:25:07 -0400586
Dianne Hackborna06de0f2012-12-11 16:34:47 -0800587 // App ops service to keep track of who is accessing the GPS
Svet Ganovf7b47252018-02-26 11:11:27 -0800588 mAppOps = mContext.getSystemService(AppOpsManager.class);
Dianne Hackborna06de0f2012-12-11 16:34:47 -0800589
Mike Lockwood2f82c4e2009-04-17 08:24:10 -0400590 // Battery statistics service to be notified when GPS turns on or off
Dianne Hackborn91268cf2013-06-13 19:06:50 -0700591 mBatteryStats = IBatteryStats.Stub.asInterface(ServiceManager.getService(
592 BatteryStats.SERVICE_NAME));
Mike Lockwood2f82c4e2009-04-17 08:24:10 -0400593
destradaafb23c672015-04-16 14:01:27 -0700594 // Construct internal handler
595 mHandler = new ProviderHandler(looper);
596
597 // Load GPS configuration and register listeners in the background:
598 // some operations, such as opening files and registering broadcast receivers, can take a
599 // relative long time, so the ctor() is kept to create objects needed by this instance,
600 // while IO initialization and registration is delegated to our internal handler
601 // this approach is just fine because events are posted to our handler anyway
Anil Admald71cf142018-12-21 14:59:36 -0800602 mGnssConfiguration = new GnssConfiguration(mContext);
WyattRileyd1309312019-02-28 12:11:45 -0800603 // Create a GPS net-initiated handler (also needed by handleInitialize)
Tsuwei Chen3324e952014-09-07 01:30:42 -0700604 mNIHandler = new GpsNetInitiatedHandler(context,
gomo48f1a642017-11-10 20:35:46 -0800605 mNetInitiatedListener,
606 mSuplEsEnabled);
WyattRileyd1309312019-02-28 12:11:45 -0800607 sendMessage(INITIALIZE_HANDLER, 0, null);
Tsuwei Chen3324e952014-09-07 01:30:42 -0700608
Anil Admal75b9fd62018-11-28 11:22:50 -0800609 mGnssStatusListenerHelper = new GnssStatusListenerHelper(mContext, mHandler) {
destradaa6568d702014-10-27 12:47:41 -0700610 @Override
611 protected boolean isAvailableInPlatform() {
destradaa13a60b02015-01-15 18:36:01 -0800612 return isSupported();
destradaa6568d702014-10-27 12:47:41 -0700613 }
614
615 @Override
616 protected boolean isGpsEnabled() {
617 return isEnabled();
618 }
619 };
620
Yu-Han Yang8de21502018-04-23 01:40:25 -0700621 mGnssMeasurementsProvider = new GnssMeasurementsProvider(mContext, mHandler) {
destradaa6568d702014-10-27 12:47:41 -0700622 @Override
623 protected boolean isGpsEnabled() {
624 return isEnabled();
625 }
626 };
627
Anil Admal75b9fd62018-11-28 11:22:50 -0800628 mGnssNavigationMessageProvider = new GnssNavigationMessageProvider(mContext, mHandler) {
destradaa6568d702014-10-27 12:47:41 -0700629 @Override
destradaa6568d702014-10-27 12:47:41 -0700630 protected boolean isGpsEnabled() {
631 return isEnabled();
632 }
633 };
Yu-Han Yanga1862b52018-02-20 17:05:59 -0800634
Anil Admal50ba15e2018-11-01 16:42:42 -0700635 mGnssMetrics = new GnssMetrics(mBatteryStats);
Yu-Han Yang66c7ea92018-03-11 17:17:15 -0700636 mNtpTimeHelper = new NtpTimeHelper(mContext, looper, this);
637 mGnssSatelliteBlacklistHelper = new GnssSatelliteBlacklistHelper(mContext,
638 looper, this);
639 mHandler.post(mGnssSatelliteBlacklistHelper::updateSatelliteBlacklist);
Yu-Han Yang3557cc72018-03-21 12:48:36 -0700640 mGnssBatchingProvider = new GnssBatchingProvider();
Yu-Han Yang6dc9f052018-12-04 17:11:24 -0800641 mGnssGeofenceProvider = new GnssGeofenceProvider();
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400642
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700643 IntentFilter intentFilter = new IntentFilter();
644 intentFilter.addAction(Intent.ACTION_SHUTDOWN);
645 mContext.registerReceiverAsUser(new BroadcastReceiver() {
646 @Override
647 public void onReceive(Context context, Intent intent) {
648 if (getSendingUserId() == UserHandle.USER_ALL) {
649 mEnabled = false;
650 handleDisable();
651 }
652 }
653 }, UserHandle.ALL, intentFilter, null, mHandler);
Mike Lockwoodd03ff942010-02-09 08:46:14 -0500654
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700655 setProperties(PROPERTIES);
Soonil Nagarkar90da1ab2019-01-04 16:26:59 -0800656 setEnabled(true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800657 }
658
Yu-Han Yanga1862b52018-02-20 17:05:59 -0800659 /**
660 * Implements {@link InjectNtpTimeCallback#injectTime}
661 */
662 @Override
663 public void injectTime(long time, long timeReference, int uncertainty) {
664 native_inject_time(time, timeReference, uncertainty);
665 }
666
Anil Admal50ba15e2018-11-01 16:42:42 -0700667 /**
668 * Implements {@link GnssNetworkConnectivityHandler.GnssNetworkListener#onNetworkAvailable()}
669 */
670 private void onNetworkAvailable() {
671 mNtpTimeHelper.onNetworkAvailable();
672 if (mDownloadXtraDataPending == STATE_PENDING_NETWORK) {
673 if (mSupportsXtra) {
674 // Download only if supported, (prevents an unneccesary on-boot
675 // download)
676 xtraDownloadRequest();
destradaaef752b62015-04-17 13:10:47 -0700677 }
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400678 }
679 }
Yu-Han Yang8de21502018-04-23 01:40:25 -0700680
Yu-Han Yange7baef32018-02-09 13:58:17 -0800681 private void handleRequestLocation(boolean independentFromGnss) {
682 if (isRequestLocationRateLimited()) {
683 if (DEBUG) {
684 Log.d(TAG, "RequestLocation is denied due to too frequent requests.");
685 }
686 return;
687 }
Yu-Han Yang74041ff2018-04-06 15:57:31 -0700688 ContentResolver resolver = mContext.getContentResolver();
689 long durationMillis = Settings.Global.getLong(
690 resolver,
691 Settings.Global.GNSS_HAL_LOCATION_REQUEST_DURATION_MILLIS,
692 LOCATION_UPDATE_DURATION_MILLIS);
693 if (durationMillis == 0) {
694 Log.i(TAG, "GNSS HAL location request is disabled by Settings.");
695 return;
696 }
Yu-Han Yange7baef32018-02-09 13:58:17 -0800697
698 LocationManager locationManager = (LocationManager) mContext.getSystemService(
699 Context.LOCATION_SERVICE);
Yu-Han Yang07561382018-02-21 13:08:37 -0800700 String provider;
701 LocationChangeListener locationListener;
Yu-Han Yange7baef32018-02-09 13:58:17 -0800702
703 if (independentFromGnss) {
704 // For fast GNSS TTFF
Yu-Han Yang07561382018-02-21 13:08:37 -0800705 provider = LocationManager.NETWORK_PROVIDER;
706 locationListener = mNetworkLocationListener;
Yu-Han Yange7baef32018-02-09 13:58:17 -0800707 } else {
708 // For Device-Based Hybrid (E911)
Yu-Han Yang07561382018-02-21 13:08:37 -0800709 provider = LocationManager.FUSED_PROVIDER;
710 locationListener = mFusedLocationListener;
Yu-Han Yange7baef32018-02-09 13:58:17 -0800711 }
Yu-Han Yang07561382018-02-21 13:08:37 -0800712
713 Log.i(TAG,
Yu-Han Yang74041ff2018-04-06 15:57:31 -0700714 String.format(
715 "GNSS HAL Requesting location updates from %s provider for %d millis.",
716 provider, durationMillis));
Yu-Han Yange684dda2018-05-24 10:29:39 -0700717 try {
718 locationManager.requestLocationUpdates(provider,
719 LOCATION_UPDATE_MIN_TIME_INTERVAL_MILLIS, /*minDistance=*/ 0,
720 locationListener, mHandler.getLooper());
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700721 locationListener.mNumLocationUpdateRequest++;
Yu-Han Yange684dda2018-05-24 10:29:39 -0700722 mHandler.postDelayed(() -> {
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700723 if (--locationListener.mNumLocationUpdateRequest == 0) {
Yu-Han Yange684dda2018-05-24 10:29:39 -0700724 Log.i(TAG,
725 String.format("Removing location updates from %s provider.", provider));
726 locationManager.removeUpdates(locationListener);
727 }
728 }, durationMillis);
729 } catch (IllegalArgumentException e) {
730 Log.w(TAG, "Unable to request location.", e);
731 }
Yu-Han Yange7baef32018-02-09 13:58:17 -0800732 }
733
734 private void injectBestLocation(Location location) {
735 int gnssLocationFlags = LOCATION_HAS_LAT_LONG |
736 (location.hasAltitude() ? LOCATION_HAS_ALTITUDE : 0) |
737 (location.hasSpeed() ? LOCATION_HAS_SPEED : 0) |
738 (location.hasBearing() ? LOCATION_HAS_BEARING : 0) |
739 (location.hasAccuracy() ? LOCATION_HAS_HORIZONTAL_ACCURACY : 0) |
740 (location.hasVerticalAccuracy() ? LOCATION_HAS_VERTICAL_ACCURACY : 0) |
741 (location.hasSpeedAccuracy() ? LOCATION_HAS_SPEED_ACCURACY : 0) |
742 (location.hasBearingAccuracy() ? LOCATION_HAS_BEARING_ACCURACY : 0);
743
744 double latitudeDegrees = location.getLatitude();
745 double longitudeDegrees = location.getLongitude();
746 double altitudeMeters = location.getAltitude();
747 float speedMetersPerSec = location.getSpeed();
748 float bearingDegrees = location.getBearing();
749 float horizontalAccuracyMeters = location.getAccuracy();
750 float verticalAccuracyMeters = location.getVerticalAccuracyMeters();
751 float speedAccuracyMetersPerSecond = location.getSpeedAccuracyMetersPerSecond();
752 float bearingAccuracyDegrees = location.getBearingAccuracyDegrees();
753 long timestamp = location.getTime();
754 native_inject_best_location(gnssLocationFlags, latitudeDegrees, longitudeDegrees,
755 altitudeMeters, speedMetersPerSec, bearingDegrees, horizontalAccuracyMeters,
756 verticalAccuracyMeters, speedAccuracyMetersPerSecond, bearingAccuracyDegrees,
757 timestamp);
758 }
759
Yu-Han Yange7baef32018-02-09 13:58:17 -0800760 /** Returns true if the location request is too frequent. */
761 private boolean isRequestLocationRateLimited() {
762 // TODO(b/73198123): implement exponential backoff.
763 return false;
764 }
765
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400766 private void handleDownloadXtraData() {
Wyatt Riley0d6e54e22016-10-05 12:03:03 -0700767 if (!mSupportsXtra) {
768 // native code reports xtra not supported, don't try
769 Log.d(TAG, "handleDownloadXtraData() called when Xtra not supported");
770 return;
771 }
Kevin Tang40e1baf2012-01-10 14:32:44 -0800772 if (mDownloadXtraDataPending == STATE_DOWNLOADING) {
773 // already downloading data
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400774 return;
775 }
Anil Admal50ba15e2018-11-01 16:42:42 -0700776 if (!mNetworkConnectivityHandler.isDataNetworkConnected()) {
Kevin Tang40e1baf2012-01-10 14:32:44 -0800777 // try again when network is up
778 mDownloadXtraDataPending = STATE_PENDING_NETWORK;
779 return;
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400780 }
Kevin Tang40e1baf2012-01-10 14:32:44 -0800781 mDownloadXtraDataPending = STATE_DOWNLOADING;
782
Jeff Brown028872f2012-08-25 13:07:01 -0700783 // hold wake lock while task runs
Wei Wangb71c0492017-05-01 20:24:19 -0700784 mDownloadXtraWakeLock.acquire(DOWNLOAD_XTRA_DATA_TIMEOUT_MS);
Lifu Tangcbd2a142016-06-22 10:57:55 -0700785 Log.i(TAG, "WakeLock acquired by handleDownloadXtraData()");
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700786 AsyncTask.THREAD_POOL_EXECUTOR.execute(() -> {
Anil Admald71cf142018-12-21 14:59:36 -0800787 GpsXtraDownloader xtraDownloader = new GpsXtraDownloader(
788 mGnssConfiguration.getProperties());
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700789 byte[] data = xtraDownloader.downloadXtraData();
790 if (data != null) {
791 if (DEBUG) Log.d(TAG, "calling native_inject_xtra_data");
792 native_inject_xtra_data(data, data.length);
793 mXtraBackOff.reset();
794 }
Kevin Tang40e1baf2012-01-10 14:32:44 -0800795
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700796 sendMessage(DOWNLOAD_XTRA_DATA_FINISHED, 0, null);
Kevin Tang40e1baf2012-01-10 14:32:44 -0800797
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700798 if (data == null) {
799 // try again later
800 // since this is delayed and not urgent we do not hold a wake lock here
801 mHandler.sendEmptyMessageDelayed(DOWNLOAD_XTRA_DATA,
802 mXtraBackOff.nextBackoffMillis());
803 }
Kevin Tang40e1baf2012-01-10 14:32:44 -0800804
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700805 // Release wake lock held by task, synchronize on mLock in case multiple
806 // download tasks overrun.
807 synchronized (mLock) {
808 if (mDownloadXtraWakeLock.isHeld()) {
809 // This wakelock may have time-out, if a timeout was specified.
810 // Catch (and ignore) any timeout exceptions.
811 try {
812 mDownloadXtraWakeLock.release();
813 if (DEBUG) Log.d(TAG, "WakeLock released by handleDownloadXtraData()");
814 } catch (Exception e) {
815 Log.i(TAG, "Wakelock timeout & release race exception in "
816 + "handleDownloadXtraData()", e);
Wei Wangb71c0492017-05-01 20:24:19 -0700817 }
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700818 } else {
819 Log.e(TAG, "WakeLock expired before release in "
820 + "handleDownloadXtraData()");
Wei Wangc5706f62017-04-18 11:26:26 -0700821 }
Jeff Brown028872f2012-08-25 13:07:01 -0700822 }
Kevin Tang40e1baf2012-01-10 14:32:44 -0800823 });
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800824 }
825
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400826 private void handleUpdateLocation(Location location) {
Mike Lockwoodd26ce0d2009-06-11 12:25:46 -0400827 if (location.hasAccuracy()) {
828 native_inject_location(location.getLatitude(), location.getLongitude(),
829 location.getAccuracy());
830 }
Mike Lockwoodfd6e5f02009-05-21 11:28:20 -0400831 }
832
Anil Admald71cf142018-12-21 14:59:36 -0800833 private void setSuplHostPort() {
834 mSuplServerHost = mGnssConfiguration.getSuplHost();
835 mSuplServerPort = mGnssConfiguration.getSuplPort(TCP_MIN_PORT);
Tsuwei Chen678c13c2014-09-22 17:48:41 -0700836 if (mSuplServerHost != null
837 && mSuplServerPort > TCP_MIN_PORT
838 && mSuplServerPort <= TCP_MAX_PORT) {
Anil Admalc70344b2018-11-16 14:22:38 -0800839 native_set_agps_server(GnssNetworkConnectivityHandler.AGPS_TYPE_SUPL,
840 mSuplServerHost, mSuplServerPort);
Tsuwei Chen678c13c2014-09-22 17:48:41 -0700841 }
Tsuwei Chen52617bb2014-08-25 11:49:11 -0700842 }
843
Tsuwei Chen462bcd82014-09-17 12:28:49 -0700844 /**
845 * Checks what SUPL mode to use, according to the AGPS mode as well as the
846 * allowed mode from properties.
847 *
Tsuwei Chen462bcd82014-09-17 12:28:49 -0700848 * @param agpsEnabled whether AGPS is enabled by settings value
Tsuwei Chen462bcd82014-09-17 12:28:49 -0700849 * @return SUPL mode (MSA vs MSB vs STANDALONE)
850 */
Yu-Han Yang6a5f0b72019-01-24 18:34:28 -0800851 private int getSuplMode(boolean agpsEnabled) {
Tsuwei Chen462bcd82014-09-17 12:28:49 -0700852 if (agpsEnabled) {
Anil Admald71cf142018-12-21 14:59:36 -0800853 int suplMode = mGnssConfiguration.getSuplMode(0);
854 if (suplMode == 0) {
855 return GPS_POSITION_MODE_STANDALONE;
Tsuwei Chen462bcd82014-09-17 12:28:49 -0700856 }
Anil Admald71cf142018-12-21 14:59:36 -0800857
destradaabfb3bdb2015-04-29 14:42:35 -0700858 // MS-Based is the preferred mode for Assisted-GPS position computation, so we favor
859 // such mode when it is available
860 if (hasCapability(GPS_CAPABILITY_MSB) && (suplMode & AGPS_SUPL_MODE_MSB) != 0) {
861 return GPS_POSITION_MODE_MS_BASED;
862 }
Tsuwei Chen462bcd82014-09-17 12:28:49 -0700863 }
864 return GPS_POSITION_MODE_STANDALONE;
865 }
866
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400867 private void handleEnable() {
868 if (DEBUG) Log.d(TAG, "handleEnable");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800869
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700870 boolean enabled = native_init();
871
872 if (enabled) {
Mike Lockwood1a1cd3a2010-08-17 07:42:54 -0400873 mSupportsXtra = native_supports_xtra();
Tsuwei Chen678c13c2014-09-22 17:48:41 -0700874
875 // TODO: remove the following native calls if we can make sure they are redundant.
Mike Lockwood734d6032009-07-28 18:30:25 -0700876 if (mSuplServerHost != null) {
Anil Admalc70344b2018-11-16 14:22:38 -0800877 native_set_agps_server(GnssNetworkConnectivityHandler.AGPS_TYPE_SUPL,
878 mSuplServerHost, mSuplServerPort);
Mike Lockwood734d6032009-07-28 18:30:25 -0700879 }
880 if (mC2KServerHost != null) {
Anil Admalc70344b2018-11-16 14:22:38 -0800881 native_set_agps_server(GnssNetworkConnectivityHandler.AGPS_TYPE_C2K,
882 mC2KServerHost, mC2KServerPort);
Mike Lockwood734d6032009-07-28 18:30:25 -0700883 }
destradaa13a60b02015-01-15 18:36:01 -0800884
Lifu Tang818aa2c2016-02-01 01:52:00 -0800885 mGnssMeasurementsProvider.onGpsEnabledChanged();
886 mGnssNavigationMessageProvider.onGpsEnabledChanged();
Yu-Han Yang3557cc72018-03-21 12:48:36 -0700887 mGnssBatchingProvider.enable();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800888 } else {
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700889 synchronized (mLock) {
890 mEnabled = false;
891 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800892 Log.w(TAG, "Failed to enable location provider");
893 }
894 }
895
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400896 private void handleDisable() {
Mike Lockwood89096312010-03-24 10:14:55 -0400897 if (DEBUG) Log.d(TAG, "handleDisable");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800898
David Christie3bc26142013-12-19 14:53:44 -0800899 updateClientUids(new WorkSource());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800900 stopNavigating();
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700901 mAlarmManager.cancel(mWakeupIntent);
902 mAlarmManager.cancel(mTimeoutIntent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800903
Yu-Han Yang3557cc72018-03-21 12:48:36 -0700904 mGnssBatchingProvider.disable();
Mike Lockwoodcf1d8cb2010-01-20 10:14:54 -0500905 // do this before releasing wakelock
906 native_cleanup();
destradaa13a60b02015-01-15 18:36:01 -0800907
Lifu Tang818aa2c2016-02-01 01:52:00 -0800908 mGnssMeasurementsProvider.onGpsEnabledChanged();
909 mGnssNavigationMessageProvider.onGpsEnabledChanged();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800910 }
911
Mike Lockwoodd03ff942010-02-09 08:46:14 -0500912 public boolean isEnabled() {
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700913 synchronized (mLock) {
914 return mEnabled;
915 }
Mike Lockwoodd03ff942010-02-09 08:46:14 -0500916 }
917
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700918 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800919 public int getStatus(Bundle extras) {
Wyatt Rileyc7067412018-02-07 15:50:35 -0800920 mLocationExtras.setBundle(extras);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800921 return mStatus;
922 }
923
Wyatt Rileyc7067412018-02-07 15:50:35 -0800924 private void updateStatus(int status) {
925 if (status != mStatus) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800926 mStatus = status;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800927 mStatusUpdateTime = SystemClock.elapsedRealtime();
928 }
929 }
930
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700931 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800932 public long getStatusUpdateTime() {
933 return mStatusUpdateTime;
934 }
935
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700936 @Override
937 public void setRequest(ProviderRequest request, WorkSource source) {
938 sendMessage(SET_REQUEST, 0, new GpsRequest(request, source));
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400939 }
940
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700941 private void handleSetRequest(ProviderRequest request, WorkSource source) {
David Christied4edf4c2014-08-12 15:22:27 -0700942 mProviderRequest = request;
943 mWorkSource = source;
944 updateRequirements();
945 }
946
947 // Called when the requirements for GPS may have changed
948 private void updateRequirements() {
949 if (mProviderRequest == null || mWorkSource == null) {
950 return;
951 }
952
David Christied4edf4c2014-08-12 15:22:27 -0700953 if (DEBUG) Log.d(TAG, "setRequest " + mProviderRequest);
Dante Russo260d6672016-06-20 11:11:59 -0700954 if (mProviderRequest.reportLocation && !mDisableGps && isEnabled()) {
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700955 // update client uids
David Christied4edf4c2014-08-12 15:22:27 -0700956 updateClientUids(mWorkSource);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800957
David Christied4edf4c2014-08-12 15:22:27 -0700958 mFixInterval = (int) mProviderRequest.interval;
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700959 mLowPowerMode = mProviderRequest.lowPowerMode;
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700960 // check for overflow
David Christied4edf4c2014-08-12 15:22:27 -0700961 if (mFixInterval != mProviderRequest.interval) {
962 Log.w(TAG, "interval overflow: " + mProviderRequest.interval);
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700963 mFixInterval = Integer.MAX_VALUE;
964 }
Mike Lockwood03ca2162010-04-01 08:10:09 -0700965
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700966 // apply request to GPS engine
Mike Lockwood04598b62010-04-14 17:17:24 -0400967 if (mStarted && hasCapability(GPS_CAPABILITY_SCHEDULING)) {
gomo48f1a642017-11-10 20:35:46 -0800968 // change period and/or lowPowerMode
Yu-Han Yangc8b9ff72018-04-17 00:47:24 -0700969 if (!setPositionMode(mPositionMode, GPS_POSITION_RECURRENCE_PERIODIC,
gomo48f1a642017-11-10 20:35:46 -0800970 mFixInterval, 0, 0, mLowPowerMode)) {
971 Log.e(TAG, "set_position_mode failed in updateRequirements");
Mike Lockwood04598b62010-04-14 17:17:24 -0400972 }
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700973 } else if (!mStarted) {
974 // start GPS
Yu-Han Yang6a5f0b72019-01-24 18:34:28 -0800975 startNavigating();
gomo300b2402017-12-13 19:04:12 -0800976 } else {
977 // GNSS Engine is already ON, but no GPS_CAPABILITY_SCHEDULING
978 mAlarmManager.cancel(mTimeoutIntent);
979 if (mFixInterval >= NO_FIX_TIMEOUT) {
980 // set timer to give up if we do not receive a fix within NO_FIX_TIMEOUT
981 // and our fix interval is not short
982 mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700983 SystemClock.elapsedRealtime() + NO_FIX_TIMEOUT, mTimeoutIntent);
984 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800985 }
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700986 } else {
Dianne Hackborn002a54e2013-01-10 17:34:55 -0800987 updateClientUids(new WorkSource());
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700988
989 stopNavigating();
990 mAlarmManager.cancel(mWakeupIntent);
991 mAlarmManager.cancel(mTimeoutIntent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800992 }
993 }
994
Yu-Han Yangc8b9ff72018-04-17 00:47:24 -0700995 private boolean setPositionMode(int mode, int recurrence, int minInterval,
996 int preferredAccuracy, int preferredTime, boolean lowPowerMode) {
997 GnssPositionMode positionMode = new GnssPositionMode(mode, recurrence, minInterval,
998 preferredAccuracy, preferredTime, lowPowerMode);
999 if (mLastPositionMode != null && mLastPositionMode.equals(positionMode)) {
1000 return true;
1001 }
1002
1003 boolean result = native_set_position_mode(mode, recurrence, minInterval,
1004 preferredAccuracy, preferredTime, lowPowerMode);
1005 if (result) {
1006 mLastPositionMode = positionMode;
1007 } else {
1008 mLastPositionMode = null;
1009 }
1010 return result;
1011 }
1012
Dianne Hackborn002a54e2013-01-10 17:34:55 -08001013 private void updateClientUids(WorkSource source) {
Narayan Kamath32684dd2018-01-08 17:32:51 +00001014 if (source.equals(mClientSource)) {
Victoria Leaseea78b852013-01-15 10:39:28 -08001015 return;
1016 }
Dianne Hackborn002a54e2013-01-10 17:34:55 -08001017
Narayan Kamath32684dd2018-01-08 17:32:51 +00001018 // (1) Inform BatteryStats that the list of IDs we're tracking changed.
1019 try {
1020 mBatteryStats.noteGpsChanged(mClientSource, source);
1021 } catch (RemoteException e) {
1022 Log.w(TAG, "RemoteException", e);
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001023 }
1024
Narayan Kamath32684dd2018-01-08 17:32:51 +00001025 // (2) Inform AppOps service about the list of changes to UIDs.
1026
1027 List<WorkChain>[] diffs = WorkSource.diffChains(mClientSource, source);
1028 if (diffs != null) {
1029 List<WorkChain> newChains = diffs[0];
1030 List<WorkChain> goneChains = diffs[1];
1031
1032 if (newChains != null) {
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001033 for (WorkChain newChain : newChains) {
Svet Ganovf7b47252018-02-26 11:11:27 -08001034 mAppOps.startOpNoThrow(AppOpsManager.OP_GPS, newChain.getAttributionUid(),
1035 newChain.getAttributionTag());
Narayan Kamath32684dd2018-01-08 17:32:51 +00001036 }
1037 }
1038
1039 if (goneChains != null) {
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001040 for (WorkChain goneChain : goneChains) {
Svet Ganovf7b47252018-02-26 11:11:27 -08001041 mAppOps.finishOp(AppOpsManager.OP_GPS, goneChain.getAttributionUid(),
1042 goneChain.getAttributionTag());
Narayan Kamath32684dd2018-01-08 17:32:51 +00001043 }
1044 }
1045
1046 mClientSource.transferWorkChains(source);
1047 }
1048
1049 // Update the flat UIDs and names list and inform app-ops of all changes.
1050 WorkSource[] changes = mClientSource.setReturningDiffs(source);
1051 if (changes != null) {
1052 WorkSource newWork = changes[0];
1053 WorkSource goneWork = changes[1];
1054
1055 // Update sources that were not previously tracked.
1056 if (newWork != null) {
1057 for (int i = 0; i < newWork.size(); i++) {
Svet Ganovf7b47252018-02-26 11:11:27 -08001058 mAppOps.startOpNoThrow(AppOpsManager.OP_GPS,
1059 newWork.get(i), newWork.getName(i));
Narayan Kamath32684dd2018-01-08 17:32:51 +00001060 }
1061 }
1062
1063 // Update sources that are no longer tracked.
1064 if (goneWork != null) {
1065 for (int i = 0; i < goneWork.size(); i++) {
Svet Ganovf7b47252018-02-26 11:11:27 -08001066 mAppOps.finishOp(AppOpsManager.OP_GPS, goneWork.get(i), goneWork.getName(i));
Dianne Hackborn2e418422009-06-22 20:00:17 -07001067 }
Mike Lockwood2f82c4e2009-04-17 08:24:10 -04001068 }
1069 }
1070 }
1071
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001072 @Override
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001073 public void sendExtraCommand(String command, Bundle extras) {
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001074
Mike Lockwood63aa5a62010-04-14 19:21:31 -04001075 long identity = Binder.clearCallingIdentity();
Peter Visontayb25db362017-11-01 18:18:12 +00001076 try {
Peter Visontayb25db362017-11-01 18:18:12 +00001077 if ("delete_aiding_data".equals(command)) {
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001078 deleteAidingData(extras);
Peter Visontayb25db362017-11-01 18:18:12 +00001079 } else if ("force_time_injection".equals(command)) {
1080 requestUtcTime();
Peter Visontayb25db362017-11-01 18:18:12 +00001081 } else if ("force_xtra_injection".equals(command)) {
1082 if (mSupportsXtra) {
1083 xtraDownloadRequest();
Peter Visontayb25db362017-11-01 18:18:12 +00001084 }
1085 } else {
1086 Log.w(TAG, "sendExtraCommand: unknown command " + command);
Mike Lockwood93bc44d2009-05-20 16:58:22 -04001087 }
Peter Visontayb25db362017-11-01 18:18:12 +00001088 } finally {
1089 Binder.restoreCallingIdentity(identity);
Mike Lockwood93bc44d2009-05-20 16:58:22 -04001090 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001091 }
1092
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001093 private void deleteAidingData(Bundle extras) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001094 int flags;
1095
1096 if (extras == null) {
1097 flags = GPS_DELETE_ALL;
1098 } else {
1099 flags = 0;
1100 if (extras.getBoolean("ephemeris")) flags |= GPS_DELETE_EPHEMERIS;
1101 if (extras.getBoolean("almanac")) flags |= GPS_DELETE_ALMANAC;
1102 if (extras.getBoolean("position")) flags |= GPS_DELETE_POSITION;
1103 if (extras.getBoolean("time")) flags |= GPS_DELETE_TIME;
1104 if (extras.getBoolean("iono")) flags |= GPS_DELETE_IONO;
1105 if (extras.getBoolean("utc")) flags |= GPS_DELETE_UTC;
1106 if (extras.getBoolean("health")) flags |= GPS_DELETE_HEALTH;
1107 if (extras.getBoolean("svdir")) flags |= GPS_DELETE_SVDIR;
1108 if (extras.getBoolean("svsteer")) flags |= GPS_DELETE_SVSTEER;
1109 if (extras.getBoolean("sadata")) flags |= GPS_DELETE_SADATA;
1110 if (extras.getBoolean("rti")) flags |= GPS_DELETE_RTI;
1111 if (extras.getBoolean("celldb-info")) flags |= GPS_DELETE_CELLDB_INFO;
1112 if (extras.getBoolean("all")) flags |= GPS_DELETE_ALL;
1113 }
1114
1115 if (flags != 0) {
1116 native_delete_aiding_data(flags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001117 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001118 }
1119
Yu-Han Yang6a5f0b72019-01-24 18:34:28 -08001120 private void startNavigating() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001121 if (!mStarted) {
Yu-Han Yang6a5f0b72019-01-24 18:34:28 -08001122 if (DEBUG) Log.d(TAG, "startNavigating");
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001123 mTimeToFirstFix = 0;
1124 mLastFixTime = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001125 mStarted = true;
Mike Lockwood03ca2162010-04-01 08:10:09 -07001126 mPositionMode = GPS_POSITION_MODE_STANDALONE;
Wyatt Riley5d5bac82016-11-01 07:05:16 -07001127 // Notify about suppressed output, if speed limit was previously exceeded.
1128 // Elsewhere, we check again with every speed output reported.
1129 if (mItarSpeedLimitExceeded) {
1130 Log.i(TAG, "startNavigating with ITAR limit in place. Output limited " +
1131 "until slow enough speed reported.");
1132 }
Mike Lockwood03ca2162010-04-01 08:10:09 -07001133
Tsuwei Chen462bcd82014-09-17 12:28:49 -07001134 boolean agpsEnabled =
1135 (Settings.Global.getInt(mContext.getContentResolver(),
gomo48f1a642017-11-10 20:35:46 -08001136 Settings.Global.ASSISTED_GPS_ENABLED, 1) != 0);
Yu-Han Yang6a5f0b72019-01-24 18:34:28 -08001137 mPositionMode = getSuplMode(agpsEnabled);
Mike Lockwoodbcab8df2009-06-25 16:39:09 -04001138
Stan Chesnutt1d72d8c2013-04-15 19:18:02 -07001139 if (DEBUG) {
1140 String mode;
1141
gomo48f1a642017-11-10 20:35:46 -08001142 switch (mPositionMode) {
Stan Chesnutt1d72d8c2013-04-15 19:18:02 -07001143 case GPS_POSITION_MODE_STANDALONE:
1144 mode = "standalone";
1145 break;
1146 case GPS_POSITION_MODE_MS_ASSISTED:
1147 mode = "MS_ASSISTED";
1148 break;
1149 case GPS_POSITION_MODE_MS_BASED:
1150 mode = "MS_BASED";
1151 break;
1152 default:
1153 mode = "unknown";
1154 break;
1155 }
1156 Log.d(TAG, "setting position_mode to " + mode);
1157 }
1158
Mike Lockwood04598b62010-04-14 17:17:24 -04001159 int interval = (hasCapability(GPS_CAPABILITY_SCHEDULING) ? mFixInterval : 1000);
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001160 mLowPowerMode = mProviderRequest.lowPowerMode;
Yu-Han Yangc8b9ff72018-04-17 00:47:24 -07001161 if (!setPositionMode(mPositionMode, GPS_POSITION_RECURRENCE_PERIODIC,
gomo48f1a642017-11-10 20:35:46 -08001162 interval, 0, 0, mLowPowerMode)) {
Mike Lockwood04598b62010-04-14 17:17:24 -04001163 mStarted = false;
1164 Log.e(TAG, "set_position_mode failed in startNavigating()");
1165 return;
1166 }
1167 if (!native_start()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001168 mStarted = false;
1169 Log.e(TAG, "native_start failed in startNavigating()");
Mike Lockwood0632ca72009-05-14 15:51:03 -04001170 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001171 }
1172
1173 // reset SV count to zero
Wyatt Rileyc7067412018-02-07 15:50:35 -08001174 updateStatus(LocationProvider.TEMPORARILY_UNAVAILABLE);
1175 mLocationExtras.reset();
Yipeng Cao282b5942017-05-17 20:31:39 -07001176 mFixRequestTime = SystemClock.elapsedRealtime();
Mike Lockwood04598b62010-04-14 17:17:24 -04001177 if (!hasCapability(GPS_CAPABILITY_SCHEDULING)) {
1178 // set timer to give up if we do not receive a fix within NO_FIX_TIMEOUT
1179 // and our fix interval is not short
1180 if (mFixInterval >= NO_FIX_TIMEOUT) {
1181 mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
1182 SystemClock.elapsedRealtime() + NO_FIX_TIMEOUT, mTimeoutIntent);
1183 }
Mike Lockwood0632ca72009-05-14 15:51:03 -04001184 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001185 }
1186 }
1187
Mike Lockwood62a8fc12010-03-22 14:23:26 -04001188 private void stopNavigating() {
Mike Lockwood29c84342009-05-06 14:01:15 -04001189 if (DEBUG) Log.d(TAG, "stopNavigating");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001190 if (mStarted) {
1191 mStarted = false;
1192 native_stop();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001193 mLastFixTime = 0;
Yu-Han Yanga50cd602018-08-28 12:33:24 -07001194 // native_stop() may reset the position mode in hardware.
1195 mLastPositionMode = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001196
1197 // reset SV count to zero
Wyatt Rileyc7067412018-02-07 15:50:35 -08001198 updateStatus(LocationProvider.TEMPORARILY_UNAVAILABLE);
1199 mLocationExtras.reset();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001200 }
1201 }
1202
Mike Lockwood0632ca72009-05-14 15:51:03 -04001203 private void hibernate() {
1204 // stop GPS until our next fix interval arrives
1205 stopNavigating();
Mike Lockwood0632ca72009-05-14 15:51:03 -04001206 mAlarmManager.cancel(mTimeoutIntent);
1207 mAlarmManager.cancel(mWakeupIntent);
1208 long now = SystemClock.elapsedRealtime();
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001209 mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, now + mFixInterval, mWakeupIntent);
Mike Lockwood04598b62010-04-14 17:17:24 -04001210 }
1211
1212 private boolean hasCapability(int capability) {
1213 return ((mEngineCapabilities & capability) != 0);
Mike Lockwood0632ca72009-05-14 15:51:03 -04001214 }
1215
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001216 @NativeEntryPoint
Wyatt Riley5d229832017-02-10 17:06:00 -08001217 private void reportLocation(boolean hasLatLong, Location location) {
Wyatt Riley26465d22018-02-12 13:44:24 -08001218 sendMessage(REPORT_LOCATION, hasLatLong ? 1 : 0, location);
1219 }
1220
1221 private void handleReportLocation(boolean hasLatLong, Location location) {
Wyatt Riley5d229832017-02-10 17:06:00 -08001222 if (location.hasSpeed()) {
1223 mItarSpeedLimitExceeded = location.getSpeed() > ITAR_SPEED_LIMIT_METERS_PER_SECOND;
Wyatt Riley5d5bac82016-11-01 07:05:16 -07001224 }
1225
1226 if (mItarSpeedLimitExceeded) {
1227 Log.i(TAG, "Hal reported a speed in excess of ITAR limit." +
1228 " GPS/GNSS Navigation output blocked.");
Siddharth Ray53ddc802018-03-16 12:01:52 -07001229 if (mStarted) {
1230 mGnssMetrics.logReceivedLocationStatus(false);
1231 }
Wyatt Riley5d5bac82016-11-01 07:05:16 -07001232 return; // No output of location allowed
1233 }
1234
Wyatt Riley5d229832017-02-10 17:06:00 -08001235 if (VERBOSE) Log.v(TAG, "reportLocation " + location.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001236
Wyatt Riley26465d22018-02-12 13:44:24 -08001237 // It would be nice to push the elapsed real-time timestamp
1238 // further down the stack, but this is still useful
1239 location.setElapsedRealtimeNanos(SystemClock.elapsedRealtimeNanos());
1240 location.setExtras(mLocationExtras.getBundle());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001241
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001242 reportLocation(location);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001243
Siddharth Ray53ddc802018-03-16 12:01:52 -07001244 if (mStarted) {
1245 mGnssMetrics.logReceivedLocationStatus(hasLatLong);
1246 if (hasLatLong) {
1247 if (location.hasAccuracy()) {
1248 mGnssMetrics.logPositionAccuracyMeters(location.getAccuracy());
1249 }
1250 if (mTimeToFirstFix > 0) {
1251 int timeBetweenFixes = (int) (SystemClock.elapsedRealtime() - mLastFixTime);
1252 mGnssMetrics.logMissedReports(mFixInterval, timeBetweenFixes);
1253 }
Siddharth Raybb608c82017-03-16 11:33:34 -07001254 }
1255 }
1256
Yipeng Cao282b5942017-05-17 20:31:39 -07001257 mLastFixTime = SystemClock.elapsedRealtime();
Hakan Gustavssonfa94ff02010-02-23 09:12:38 +01001258 // report time to first fix
Wyatt Riley5d229832017-02-10 17:06:00 -08001259 if (mTimeToFirstFix == 0 && hasLatLong) {
gomo48f1a642017-11-10 20:35:46 -08001260 mTimeToFirstFix = (int) (mLastFixTime - mFixRequestTime);
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001261 if (DEBUG) Log.d(TAG, "TTFF: " + mTimeToFirstFix);
Siddharth Ray53ddc802018-03-16 12:01:52 -07001262 if (mStarted) {
1263 mGnssMetrics.logTimeToFirstFixMilliSecs(mTimeToFirstFix);
1264 }
Hakan Gustavssonfa94ff02010-02-23 09:12:38 +01001265
1266 // notify status listeners
Anil Admal75b9fd62018-11-28 11:22:50 -08001267 mGnssStatusListenerHelper.onFirstFix(mTimeToFirstFix);
Hakan Gustavssonfa94ff02010-02-23 09:12:38 +01001268 }
1269
Mike Lockwood15e3d0f2009-05-01 07:53:28 -04001270 if (mStarted && mStatus != LocationProvider.AVAILABLE) {
Wyatt Rileyc7067412018-02-07 15:50:35 -08001271 // For devices that use framework scheduling, a timer may be set to ensure we don't
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001272 // spend too much power searching for a location, when the requested update rate is
1273 // slow.
Wyatt Rileyc7067412018-02-07 15:50:35 -08001274 // As we just recievied a location, we'll cancel that timer.
Mike Lockwood04598b62010-04-14 17:17:24 -04001275 if (!hasCapability(GPS_CAPABILITY_SCHEDULING) && mFixInterval < NO_FIX_TIMEOUT) {
Mike Lockwoodb7be5442010-02-24 14:34:50 -05001276 mAlarmManager.cancel(mTimeoutIntent);
1277 }
1278
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001279 // send an intent to notify that the GPS is receiving fixes.
Mike Lockwood00b74272010-03-26 10:41:48 -04001280 Intent intent = new Intent(LocationManager.GPS_FIX_CHANGE_ACTION);
1281 intent.putExtra(LocationManager.EXTRA_GPS_ENABLED, true);
Dianne Hackborn5ac72a22012-08-29 18:32:08 -07001282 mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
Wyatt Rileyc7067412018-02-07 15:50:35 -08001283 updateStatus(LocationProvider.AVAILABLE);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001284 }
Mike Lockwood29c84342009-05-06 14:01:15 -04001285
gomo48f1a642017-11-10 20:35:46 -08001286 if (!hasCapability(GPS_CAPABILITY_SCHEDULING) && mStarted &&
1287 mFixInterval > GPS_POLLING_THRESHOLD_INTERVAL) {
Mike Lockwoodd53ba012010-04-15 20:41:26 -04001288 if (DEBUG) Log.d(TAG, "got fix, hibernating");
Mike Lockwood0632ca72009-05-14 15:51:03 -04001289 hibernate();
Mike Lockwood29c84342009-05-06 14:01:15 -04001290 }
gomo48f1a642017-11-10 20:35:46 -08001291 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001292
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001293 @NativeEntryPoint
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001294 private void reportStatus(int status) {
Mike Lockwoodb8d90332010-10-18 17:59:48 -04001295 if (DEBUG) Log.v(TAG, "reportStatus status: " + status);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001296
destradaaea8a8a62014-06-23 18:19:03 -07001297 boolean wasNavigating = mNavigating;
1298 switch (status) {
1299 case GPS_STATUS_SESSION_BEGIN:
1300 mNavigating = true;
destradaaea8a8a62014-06-23 18:19:03 -07001301 break;
1302 case GPS_STATUS_SESSION_END:
1303 mNavigating = false;
1304 break;
1305 case GPS_STATUS_ENGINE_ON:
destradaaea8a8a62014-06-23 18:19:03 -07001306 break;
1307 case GPS_STATUS_ENGINE_OFF:
destradaaea8a8a62014-06-23 18:19:03 -07001308 mNavigating = false;
1309 break;
1310 }
Mike Lockwooddbd6fd82009-12-07 18:43:36 -05001311
destradaaea8a8a62014-06-23 18:19:03 -07001312 if (wasNavigating != mNavigating) {
Anil Admal75b9fd62018-11-28 11:22:50 -08001313 mGnssStatusListenerHelper.onStatusChanged(mNavigating);
Mike Lockwoodcf1d8cb2010-01-20 10:14:54 -05001314
destradaaea8a8a62014-06-23 18:19:03 -07001315 // send an intent to notify that the GPS has been enabled or disabled
1316 Intent intent = new Intent(LocationManager.GPS_ENABLED_CHANGE_ACTION);
1317 intent.putExtra(LocationManager.EXTRA_GPS_ENABLED, mNavigating);
1318 mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001319 }
1320 }
1321
Wyatt Riley26465d22018-02-12 13:44:24 -08001322 // Helper class to carry data to handler for reportSvStatus
1323 private static class SvStatusInfo {
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001324 private int mSvCount;
1325 private int[] mSvidWithFlags;
1326 private float[] mCn0s;
1327 private float[] mSvElevations;
1328 private float[] mSvAzimuths;
1329 private float[] mSvCarrierFreqs;
Wyatt Riley26465d22018-02-12 13:44:24 -08001330 }
1331
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001332 @NativeEntryPoint
Wyatt Riley26465d22018-02-12 13:44:24 -08001333 private void reportSvStatus(int svCount, int[] svidWithFlags, float[] cn0s,
1334 float[] svElevations, float[] svAzimuths, float[] svCarrierFreqs) {
1335 SvStatusInfo svStatusInfo = new SvStatusInfo();
1336 svStatusInfo.mSvCount = svCount;
1337 svStatusInfo.mSvidWithFlags = svidWithFlags;
1338 svStatusInfo.mCn0s = cn0s;
1339 svStatusInfo.mSvElevations = svElevations;
1340 svStatusInfo.mSvAzimuths = svAzimuths;
1341 svStatusInfo.mSvCarrierFreqs = svCarrierFreqs;
1342
1343 sendMessage(REPORT_SV_STATUS, 0, svStatusInfo);
1344 }
1345
1346 private void handleReportSvStatus(SvStatusInfo info) {
Anil Admal75b9fd62018-11-28 11:22:50 -08001347 mGnssStatusListenerHelper.onSvStatusChanged(
Wyatt Riley26465d22018-02-12 13:44:24 -08001348 info.mSvCount,
1349 info.mSvidWithFlags,
1350 info.mCn0s,
1351 info.mSvElevations,
1352 info.mSvAzimuths,
1353 info.mSvCarrierFreqs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001354
Siddharth Ray168f12a2017-07-10 11:55:10 -07001355 // Log CN0 as part of GNSS metrics
Wyatt Riley26465d22018-02-12 13:44:24 -08001356 mGnssMetrics.logCn0(info.mCn0s, info.mSvCount);
Siddharth Ray168f12a2017-07-10 11:55:10 -07001357
Mike Lockwood29c84342009-05-06 14:01:15 -04001358 if (VERBOSE) {
Wyatt Riley26465d22018-02-12 13:44:24 -08001359 Log.v(TAG, "SV count: " + info.mSvCount);
Lifu Tang30f95a72016-01-07 23:20:38 -08001360 }
Wyatt Rileyc9f25dd2017-05-05 13:45:23 -07001361 // Calculate number of satellites used in fix.
Lifu Tang30f95a72016-01-07 23:20:38 -08001362 int usedInFixCount = 0;
Wyatt Rileyc9f25dd2017-05-05 13:45:23 -07001363 int maxCn0 = 0;
1364 int meanCn0 = 0;
Wyatt Riley26465d22018-02-12 13:44:24 -08001365 for (int i = 0; i < info.mSvCount; i++) {
1366 if ((info.mSvidWithFlags[i] & GnssStatus.GNSS_SV_FLAGS_USED_IN_FIX) != 0) {
Lifu Tang30f95a72016-01-07 23:20:38 -08001367 ++usedInFixCount;
Wyatt Riley26465d22018-02-12 13:44:24 -08001368 if (info.mCn0s[i] > maxCn0) {
1369 maxCn0 = (int) info.mCn0s[i];
Wyatt Rileyc9f25dd2017-05-05 13:45:23 -07001370 }
Wyatt Riley26465d22018-02-12 13:44:24 -08001371 meanCn0 += info.mCn0s[i];
Lifu Tang30f95a72016-01-07 23:20:38 -08001372 }
1373 if (VERBOSE) {
Wyatt Riley26465d22018-02-12 13:44:24 -08001374 Log.v(TAG, "svid: " + (info.mSvidWithFlags[i] >> GnssStatus.SVID_SHIFT_WIDTH) +
1375 " cn0: " + info.mCn0s[i] +
1376 " elev: " + info.mSvElevations[i] +
1377 " azimuth: " + info.mSvAzimuths[i] +
1378 " carrier frequency: " + info.mSvCarrierFreqs[i] +
1379 ((info.mSvidWithFlags[i] & GnssStatus.GNSS_SV_FLAGS_HAS_EPHEMERIS_DATA) == 0
Lifu Tang30f95a72016-01-07 23:20:38 -08001380 ? " " : " E") +
Wyatt Riley26465d22018-02-12 13:44:24 -08001381 ((info.mSvidWithFlags[i] & GnssStatus.GNSS_SV_FLAGS_HAS_ALMANAC_DATA) == 0
Lifu Tang30f95a72016-01-07 23:20:38 -08001382 ? " " : " A") +
Wyatt Riley26465d22018-02-12 13:44:24 -08001383 ((info.mSvidWithFlags[i] & GnssStatus.GNSS_SV_FLAGS_USED_IN_FIX) == 0
gomo4402af62017-01-11 13:20:13 -08001384 ? "" : "U") +
Wyatt Riley26465d22018-02-12 13:44:24 -08001385 ((info.mSvidWithFlags[i] &
1386 GnssStatus.GNSS_SV_FLAGS_HAS_CARRIER_FREQUENCY) == 0
gomo48f1a642017-11-10 20:35:46 -08001387 ? "" : "F"));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001388 }
1389 }
Wyatt Rileyc9f25dd2017-05-05 13:45:23 -07001390 if (usedInFixCount > 0) {
1391 meanCn0 /= usedInFixCount;
1392 }
1393 // return number of sats used in fix instead of total reported
Wyatt Rileyc7067412018-02-07 15:50:35 -08001394 mLocationExtras.set(usedInFixCount, meanCn0, maxCn0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001395
Mike Lockwood15e3d0f2009-05-01 07:53:28 -04001396 if (mNavigating && mStatus == LocationProvider.AVAILABLE && mLastFixTime > 0 &&
gomo48f1a642017-11-10 20:35:46 -08001397 SystemClock.elapsedRealtime() - mLastFixTime > RECENT_FIX_TIMEOUT) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001398 // send an intent to notify that the GPS is no longer receiving fixes.
Mike Lockwood00b74272010-03-26 10:41:48 -04001399 Intent intent = new Intent(LocationManager.GPS_FIX_CHANGE_ACTION);
1400 intent.putExtra(LocationManager.EXTRA_GPS_ENABLED, false);
Dianne Hackborn5ac72a22012-08-29 18:32:08 -07001401 mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
Wyatt Rileyc7067412018-02-07 15:50:35 -08001402 updateStatus(LocationProvider.TEMPORARILY_UNAVAILABLE);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001403 }
1404 }
Mike Lockwood58bda982009-04-14 16:25:07 -04001405
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001406 @NativeEntryPoint
Anil Admalc70344b2018-11-16 14:22:38 -08001407 private void reportAGpsStatus(int agpsType, int agpsStatus, byte[] suplIpAddr) {
1408 mNetworkConnectivityHandler.onReportAGpsStatus(agpsType, agpsStatus, suplIpAddr);
destradaae21252a2015-09-08 12:32:59 -07001409 }
1410
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001411 @NativeEntryPoint
Mike Lockwoodf602d362010-06-20 14:28:16 -07001412 private void reportNmea(long timestamp) {
Wyatt Riley5d5bac82016-11-01 07:05:16 -07001413 if (!mItarSpeedLimitExceeded) {
1414 int length = native_read_nmea(mNmeaBuffer, mNmeaBuffer.length);
1415 String nmea = new String(mNmeaBuffer, 0 /* offset */, length);
Anil Admal75b9fd62018-11-28 11:22:50 -08001416 mGnssStatusListenerHelper.onNmeaReceived(timestamp, nmea);
Wyatt Riley5d5bac82016-11-01 07:05:16 -07001417 }
destradaaea8a8a62014-06-23 18:19:03 -07001418 }
Mike Lockwoodb16e7802009-08-06 09:26:02 -04001419
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001420 @NativeEntryPoint
Lifu Tang818aa2c2016-02-01 01:52:00 -08001421 private void reportMeasurementData(GnssMeasurementsEvent event) {
Wyatt Riley5d5bac82016-11-01 07:05:16 -07001422 if (!mItarSpeedLimitExceeded) {
Wyatt Rileyaa420d52017-07-03 15:14:42 -07001423 // send to handler to allow native to return quickly
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001424 mHandler.post(() -> mGnssMeasurementsProvider.onMeasurementsAvailable(event));
Wyatt Riley5d5bac82016-11-01 07:05:16 -07001425 }
Mike Lockwoodb16e7802009-08-06 09:26:02 -04001426 }
1427
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001428 @NativeEntryPoint
Lifu Tange8abe8e2016-04-01 10:32:05 -07001429 private void reportNavigationMessage(GnssNavigationMessage event) {
Wyatt Riley5d5bac82016-11-01 07:05:16 -07001430 if (!mItarSpeedLimitExceeded) {
Wyatt Rileyaa420d52017-07-03 15:14:42 -07001431 // send to handler to allow native to return quickly
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001432 mHandler.post(() -> mGnssNavigationMessageProvider.onNavigationMessageAvailable(event));
Wyatt Riley5d5bac82016-11-01 07:05:16 -07001433 }
destradaa4b3e3932014-07-21 18:01:47 -07001434 }
1435
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001436 @NativeEntryPoint
Wyatt Rileyd87cf912017-12-05 09:31:52 -08001437 private void setEngineCapabilities(final int capabilities) {
1438 // send to handler thread for fast native return, and in-order handling
gomo226b7b72018-12-12 16:49:39 -08001439 mHandler.post(
1440 () -> {
1441 mEngineCapabilities = capabilities;
Mike Lockwood9b9fb5c2011-06-29 15:09:40 -04001442
gomo226b7b72018-12-12 16:49:39 -08001443 if (hasCapability(GPS_CAPABILITY_ON_DEMAND_TIME)) {
1444 mNtpTimeHelper.enablePeriodicTimeInjection();
1445 requestUtcTime();
1446 }
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001447
gomo226b7b72018-12-12 16:49:39 -08001448 mGnssMeasurementsProvider.onCapabilitiesUpdated(capabilities);
1449 mGnssNavigationMessageProvider.onCapabilitiesUpdated(
1450 hasCapability(GPS_CAPABILITY_NAV_MESSAGES));
1451 restartRequests();
1452 });
Yu-Han Yang52057622018-04-25 00:51:22 -07001453 }
1454
1455 private void restartRequests() {
1456 Log.i(TAG, "restartRequests");
1457
1458 restartLocationRequest();
1459 mGnssMeasurementsProvider.resumeIfStarted();
1460 mGnssNavigationMessageProvider.resumeIfStarted();
1461 mGnssBatchingProvider.resumeIfStarted();
1462 mGnssGeofenceProvider.resumeIfStarted();
1463 }
1464
1465 private void restartLocationRequest() {
1466 if (DEBUG) Log.d(TAG, "restartLocationRequest");
1467 mStarted = false;
1468 updateRequirements();
1469 }
Wyatt Rileyd87cf912017-12-05 09:31:52 -08001470
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001471 @NativeEntryPoint
Wyatt Rileyd87cf912017-12-05 09:31:52 -08001472 private void setGnssYearOfHardware(final int yearOfHardware) {
1473 // mHardwareYear is simply set here, to be read elsewhere, and is volatile for safe sync
1474 if (DEBUG) Log.d(TAG, "setGnssYearOfHardware called with " + yearOfHardware);
1475 mHardwareYear = yearOfHardware;
Mike Lockwood04598b62010-04-14 17:17:24 -04001476 }
1477
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001478 @NativeEntryPoint
Wyatt Rileyd87cf912017-12-05 09:31:52 -08001479 private void setGnssHardwareModelName(final String modelName) {
1480 // mHardwareModelName is simply set here, to be read elsewhere, and volatile for safe sync
1481 if (DEBUG) Log.d(TAG, "setGnssModelName called with " + modelName);
1482 mHardwareModelName = modelName;
Lifu Tang82f893d2016-01-21 18:15:33 -08001483 }
1484
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001485 @NativeEntryPoint
Yu-Han Yang52057622018-04-25 00:51:22 -07001486 private void reportGnssServiceDied() {
1487 if (DEBUG) Log.d(TAG, "reportGnssServiceDied");
1488 mHandler.post(() -> {
1489 class_init_native();
1490 native_init_once();
1491 if (isEnabled()) {
1492 // re-calls native_init() and other setup.
1493 handleEnable();
1494 // resend configuration into the restarted HAL service.
Anil Admald71cf142018-12-21 14:59:36 -08001495 reloadGpsProperties();
Yu-Han Yang52057622018-04-25 00:51:22 -07001496 }
1497 });
1498 }
1499
Lifu Tang9363b942016-02-16 18:07:00 -08001500 public interface GnssSystemInfoProvider {
Lifu Tang82f893d2016-01-21 18:15:33 -08001501 /**
Wyatt Rileyd87cf912017-12-05 09:31:52 -08001502 * Returns the year of underlying GPS hardware.
Lifu Tang82f893d2016-01-21 18:15:33 -08001503 */
Lifu Tang9363b942016-02-16 18:07:00 -08001504 int getGnssYearOfHardware();
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001505
Wyatt Rileyd87cf912017-12-05 09:31:52 -08001506 /**
1507 * Returns the model name of underlying GPS hardware.
1508 */
1509 String getGnssHardwareModelName();
Lifu Tang82f893d2016-01-21 18:15:33 -08001510 }
1511
1512 /**
1513 * @hide
1514 */
Lifu Tang9363b942016-02-16 18:07:00 -08001515 public GnssSystemInfoProvider getGnssSystemInfoProvider() {
1516 return new GnssSystemInfoProvider() {
Lifu Tang82f893d2016-01-21 18:15:33 -08001517 @Override
Lifu Tang9363b942016-02-16 18:07:00 -08001518 public int getGnssYearOfHardware() {
Wyatt Rileyd87cf912017-12-05 09:31:52 -08001519 return mHardwareYear;
1520 }
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001521
Wyatt Rileyd87cf912017-12-05 09:31:52 -08001522 @Override
1523 public String getGnssHardwareModelName() {
1524 return mHardwareModelName;
Lifu Tang82f893d2016-01-21 18:15:33 -08001525 }
1526 };
1527 }
1528
Wyatt Rileycf879db2017-01-12 13:57:38 -08001529 /**
1530 * @hide
1531 */
1532 public GnssBatchingProvider getGnssBatchingProvider() {
Yu-Han Yang3557cc72018-03-21 12:48:36 -07001533 return mGnssBatchingProvider;
Wyatt Rileycf879db2017-01-12 13:57:38 -08001534 }
1535
Siddharth Raybb608c82017-03-16 11:33:34 -07001536 public interface GnssMetricsProvider {
1537 /**
1538 * Returns GNSS metrics as proto string
1539 */
1540 String getGnssMetricsAsProtoString();
1541 }
1542
1543 /**
1544 * @hide
1545 */
1546 public GnssMetricsProvider getGnssMetricsProvider() {
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001547 return () -> mGnssMetrics.dumpGnssMetricsAsProtoString();
Siddharth Raybb608c82017-03-16 11:33:34 -07001548 }
1549
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001550 @NativeEntryPoint
Wyatt Rileycf879db2017-01-12 13:57:38 -08001551 private void reportLocationBatch(Location[] locationArray) {
1552 List<Location> locations = new ArrayList<>(Arrays.asList(locationArray));
gomo48f1a642017-11-10 20:35:46 -08001553 if (DEBUG) {
1554 Log.d(TAG, "Location batch of size " + locationArray.length + " reported");
1555 }
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001556 reportLocation(locations);
Wyatt Rileycf879db2017-01-12 13:57:38 -08001557 }
1558
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001559 @NativeEntryPoint
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001560 private void xtraDownloadRequest() {
Joe Onoratof5d95cb2010-01-07 21:48:32 -05001561 if (DEBUG) Log.d(TAG, "xtraDownloadRequest");
Mike Lockwood98e48692010-04-07 16:32:51 -04001562 sendMessage(DOWNLOAD_XTRA_DATA, 0, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001563 }
1564
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07001565 /**
destradaa0682809a2013-08-12 18:50:30 -07001566 * Converts the GPS HAL status to the internal Geofence Hardware status.
1567 */
Yu-Han Yang6dc9f052018-12-04 17:11:24 -08001568 private static int getGeofenceStatus(int status) {
gomo48f1a642017-11-10 20:35:46 -08001569 switch (status) {
destradaa0682809a2013-08-12 18:50:30 -07001570 case GPS_GEOFENCE_OPERATION_SUCCESS:
1571 return GeofenceHardware.GEOFENCE_SUCCESS;
1572 case GPS_GEOFENCE_ERROR_GENERIC:
1573 return GeofenceHardware.GEOFENCE_FAILURE;
1574 case GPS_GEOFENCE_ERROR_ID_EXISTS:
1575 return GeofenceHardware.GEOFENCE_ERROR_ID_EXISTS;
1576 case GPS_GEOFENCE_ERROR_INVALID_TRANSITION:
1577 return GeofenceHardware.GEOFENCE_ERROR_INVALID_TRANSITION;
1578 case GPS_GEOFENCE_ERROR_TOO_MANY_GEOFENCES:
1579 return GeofenceHardware.GEOFENCE_ERROR_TOO_MANY_GEOFENCES;
1580 case GPS_GEOFENCE_ERROR_ID_UNKNOWN:
1581 return GeofenceHardware.GEOFENCE_ERROR_ID_UNKNOWN;
1582 default:
1583 return -1;
1584 }
1585 }
1586
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001587 @NativeEntryPoint
Wyatt Riley5d229832017-02-10 17:06:00 -08001588 private void reportGeofenceTransition(int geofenceId, Location location, int transition,
gomo48f1a642017-11-10 20:35:46 -08001589 long transitionTimestamp) {
Yu-Han Yang6dc9f052018-12-04 17:11:24 -08001590 mHandler.post(() -> {
1591 if (mGeofenceHardwareImpl == null) {
1592 mGeofenceHardwareImpl = GeofenceHardwareImpl.getInstance(mContext);
1593 }
Wyatt Riley5d229832017-02-10 17:06:00 -08001594
Yu-Han Yang6dc9f052018-12-04 17:11:24 -08001595 mGeofenceHardwareImpl.reportGeofenceTransition(
1596 geofenceId,
1597 location,
1598 transition,
1599 transitionTimestamp,
1600 GeofenceHardware.MONITORING_TYPE_GPS_HARDWARE,
1601 FusedBatchOptions.SourceTechnologies.GNSS);
1602 });
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07001603 }
1604
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001605 @NativeEntryPoint
Wyatt Riley5d229832017-02-10 17:06:00 -08001606 private void reportGeofenceStatus(int status, Location location) {
Yu-Han Yang6dc9f052018-12-04 17:11:24 -08001607 mHandler.post(() -> {
1608 if (mGeofenceHardwareImpl == null) {
1609 mGeofenceHardwareImpl = GeofenceHardwareImpl.getInstance(mContext);
1610 }
1611 int monitorStatus = GeofenceHardware.MONITOR_CURRENTLY_UNAVAILABLE;
1612 if (status == GPS_GEOFENCE_AVAILABLE) {
1613 monitorStatus = GeofenceHardware.MONITOR_CURRENTLY_AVAILABLE;
1614 }
1615 mGeofenceHardwareImpl.reportGeofenceMonitorStatus(
1616 GeofenceHardware.MONITORING_TYPE_GPS_HARDWARE,
1617 monitorStatus,
1618 location,
1619 FusedBatchOptions.SourceTechnologies.GNSS);
1620 });
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07001621 }
1622
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001623 @NativeEntryPoint
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07001624 private void reportGeofenceAddStatus(int geofenceId, int status) {
Yu-Han Yang6dc9f052018-12-04 17:11:24 -08001625 mHandler.post(() -> {
1626 if (mGeofenceHardwareImpl == null) {
1627 mGeofenceHardwareImpl = GeofenceHardwareImpl.getInstance(mContext);
1628 }
1629 mGeofenceHardwareImpl.reportGeofenceAddStatus(geofenceId, getGeofenceStatus(status));
1630 });
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07001631 }
1632
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001633 @NativeEntryPoint
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07001634 private void reportGeofenceRemoveStatus(int geofenceId, int status) {
Yu-Han Yang6dc9f052018-12-04 17:11:24 -08001635 mHandler.post(() -> {
1636 if (mGeofenceHardwareImpl == null) {
1637 mGeofenceHardwareImpl = GeofenceHardwareImpl.getInstance(mContext);
1638 }
1639 mGeofenceHardwareImpl.reportGeofenceRemoveStatus(geofenceId, getGeofenceStatus(status));
1640 });
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07001641 }
1642
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001643 @NativeEntryPoint
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07001644 private void reportGeofencePauseStatus(int geofenceId, int status) {
Yu-Han Yang6dc9f052018-12-04 17:11:24 -08001645 mHandler.post(() -> {
1646 if (mGeofenceHardwareImpl == null) {
1647 mGeofenceHardwareImpl = GeofenceHardwareImpl.getInstance(mContext);
1648 }
1649 mGeofenceHardwareImpl.reportGeofencePauseStatus(geofenceId, getGeofenceStatus(status));
1650 });
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07001651 }
1652
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001653 @NativeEntryPoint
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07001654 private void reportGeofenceResumeStatus(int geofenceId, int status) {
Yu-Han Yang6dc9f052018-12-04 17:11:24 -08001655 mHandler.post(() -> {
1656 if (mGeofenceHardwareImpl == null) {
1657 mGeofenceHardwareImpl = GeofenceHardwareImpl.getInstance(mContext);
1658 }
1659 mGeofenceHardwareImpl.reportGeofenceResumeStatus(geofenceId, getGeofenceStatus(status));
1660 });
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07001661 }
1662
Danke Xie22d1f9f2009-08-18 18:28:45 -04001663 //=============================================================
1664 // NI Client support
Miguel Torroja1e84da82010-07-27 07:02:24 +02001665 //=============================================================
Danke Xie22d1f9f2009-08-18 18:28:45 -04001666 private final INetInitiatedListener mNetInitiatedListener = new INetInitiatedListener.Stub() {
destradaaef752b62015-04-17 13:10:47 -07001667 // Sends a response for an NI request to HAL.
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001668 @Override
gomo48f1a642017-11-10 20:35:46 -08001669 public boolean sendNiResponse(int notificationId, int userResponse) {
Miguel Torroja1e84da82010-07-27 07:02:24 +02001670 // TODO Add Permission check
Danke Xie22d1f9f2009-08-18 18:28:45 -04001671
gomo48f1a642017-11-10 20:35:46 -08001672 if (DEBUG) {
1673 Log.d(TAG, "sendNiResponse, notifId: " + notificationId +
1674 ", response: " + userResponse);
1675 }
Miguel Torroja1e84da82010-07-27 07:02:24 +02001676 native_send_ni_response(notificationId, userResponse);
Yu-Han Yang8a1b51d2018-12-26 22:18:31 -08001677
1678 StatsLog.write(StatsLog.GNSS_NI_EVENT_REPORTED,
1679 StatsLog.GNSS_NI_EVENT_REPORTED__EVENT_TYPE__NI_RESPONSE,
1680 notificationId,
1681 /* niType= */ 0,
1682 /* needNotify= */ false,
1683 /* needVerify= */ false,
1684 /* privacyOverride= */ false,
1685 /* timeout= */ 0,
1686 /* defaultResponse= */ 0,
1687 /* requestorId= */ null,
1688 /* text= */ null,
1689 /* requestorIdEncoding= */ 0,
1690 /* textEncoding= */ 0,
1691 mSuplEsEnabled,
1692 mEnabled,
1693 userResponse);
1694
Miguel Torroja1e84da82010-07-27 07:02:24 +02001695 return true;
1696 }
Danke Xie22d1f9f2009-08-18 18:28:45 -04001697 };
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001698
Danke Xie22d1f9f2009-08-18 18:28:45 -04001699 public INetInitiatedListener getNetInitiatedListener() {
1700 return mNetInitiatedListener;
1701 }
1702
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001703 /** Reports a NI notification. */
1704 @NativeEntryPoint
Miguel Torroja1e84da82010-07-27 07:02:24 +02001705 public void reportNiNotification(
1706 int notificationId,
1707 int niType,
1708 int notifyFlags,
1709 int timeout,
1710 int defaultResponse,
1711 String requestorId,
1712 String text,
1713 int requestorIdEncoding,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001714 int textEncoding
gomo48f1a642017-11-10 20:35:46 -08001715 ) {
Miguel Torroja1e84da82010-07-27 07:02:24 +02001716 Log.i(TAG, "reportNiNotification: entered");
1717 Log.i(TAG, "notificationId: " + notificationId +
1718 ", niType: " + niType +
1719 ", notifyFlags: " + notifyFlags +
1720 ", timeout: " + timeout +
1721 ", defaultResponse: " + defaultResponse);
1722
1723 Log.i(TAG, "requestorId: " + requestorId +
1724 ", text: " + text +
1725 ", requestorIdEncoding: " + requestorIdEncoding +
1726 ", textEncoding: " + textEncoding);
1727
1728 GpsNiNotification notification = new GpsNiNotification();
1729
1730 notification.notificationId = notificationId;
1731 notification.niType = niType;
1732 notification.needNotify = (notifyFlags & GpsNetInitiatedHandler.GPS_NI_NEED_NOTIFY) != 0;
1733 notification.needVerify = (notifyFlags & GpsNetInitiatedHandler.GPS_NI_NEED_VERIFY) != 0;
gomo48f1a642017-11-10 20:35:46 -08001734 notification.privacyOverride =
1735 (notifyFlags & GpsNetInitiatedHandler.GPS_NI_PRIVACY_OVERRIDE) != 0;
Miguel Torroja1e84da82010-07-27 07:02:24 +02001736 notification.timeout = timeout;
1737 notification.defaultResponse = defaultResponse;
1738 notification.requestorId = requestorId;
1739 notification.text = text;
1740 notification.requestorIdEncoding = requestorIdEncoding;
1741 notification.textEncoding = textEncoding;
1742
Miguel Torroja1e84da82010-07-27 07:02:24 +02001743 mNIHandler.handleNiNotification(notification);
Yu-Han Yang8a1b51d2018-12-26 22:18:31 -08001744 StatsLog.write(StatsLog.GNSS_NI_EVENT_REPORTED,
1745 StatsLog.GNSS_NI_EVENT_REPORTED__EVENT_TYPE__NI_REQUEST,
1746 notification.notificationId,
1747 notification.niType,
1748 notification.needNotify,
1749 notification.needVerify,
1750 notification.privacyOverride,
1751 notification.timeout,
1752 notification.defaultResponse,
1753 notification.requestorId,
1754 notification.text,
1755 notification.requestorIdEncoding,
1756 notification.textEncoding,
1757 mSuplEsEnabled,
1758 mEnabled,
1759 /* userResponse= */ 0);
Miguel Torroja1e84da82010-07-27 07:02:24 +02001760 }
1761
1762 /**
Miguel Torroja1e84da82010-07-27 07:02:24 +02001763 * We should be careful about receiving null string from the TelephonyManager,
1764 * because sending null String to JNI function would cause a crash.
1765 */
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001766 @NativeEntryPoint
Miguel Torroja1e84da82010-07-27 07:02:24 +02001767 private void requestSetID(int flags) {
1768 TelephonyManager phone = (TelephonyManager)
1769 mContext.getSystemService(Context.TELEPHONY_SERVICE);
destradaaef752b62015-04-17 13:10:47 -07001770 int type = AGPS_SETID_TYPE_NONE;
Miguel Torroja1e84da82010-07-27 07:02:24 +02001771 String data = "";
1772
1773 if ((flags & AGPS_RIL_REQUEST_SETID_IMSI) == AGPS_RIL_REQUEST_SETID_IMSI) {
1774 String data_temp = phone.getSubscriberId();
1775 if (data_temp == null) {
1776 // This means the framework does not have the SIM card ready.
1777 } else {
1778 // This means the framework has the SIM card.
1779 data = data_temp;
1780 type = AGPS_SETID_TYPE_IMSI;
1781 }
gomo48f1a642017-11-10 20:35:46 -08001782 } else if ((flags & AGPS_RIL_REQUEST_SETID_MSISDN) == AGPS_RIL_REQUEST_SETID_MSISDN) {
Miguel Torroja1e84da82010-07-27 07:02:24 +02001783 String data_temp = phone.getLine1Number();
1784 if (data_temp == null) {
1785 // This means the framework does not have the SIM card ready.
1786 } else {
1787 // This means the framework has the SIM card.
1788 data = data_temp;
1789 type = AGPS_SETID_TYPE_MSISDN;
1790 }
1791 }
1792 native_agps_set_id(type, data);
1793 }
1794
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001795 @NativeEntryPoint
Yu-Han Yange7baef32018-02-09 13:58:17 -08001796 private void requestLocation(boolean independentFromGnss) {
1797 if (DEBUG) {
1798 Log.d(TAG, "requestLocation. independentFromGnss: " + independentFromGnss);
1799 }
1800 sendMessage(REQUEST_LOCATION, 0, independentFromGnss);
1801 }
1802
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001803 @NativeEntryPoint
Mike Lockwood9b9fb5c2011-06-29 15:09:40 -04001804 private void requestUtcTime() {
destradaae21252a2015-09-08 12:32:59 -07001805 if (DEBUG) Log.d(TAG, "utcTimeRequest");
Mike Lockwood9b9fb5c2011-06-29 15:09:40 -04001806 sendMessage(INJECT_NTP_TIME, 0, null);
1807 }
1808
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001809 @NativeEntryPoint
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001810 private void requestRefLocation() {
Miguel Torroja1e84da82010-07-27 07:02:24 +02001811 TelephonyManager phone = (TelephonyManager)
1812 mContext.getSystemService(Context.TELEPHONY_SERVICE);
Victoria Leased50d0c32012-10-29 13:16:17 -07001813 final int phoneType = phone.getPhoneType();
1814 if (phoneType == TelephonyManager.PHONE_TYPE_GSM) {
Miguel Torroja1e84da82010-07-27 07:02:24 +02001815 GsmCellLocation gsm_cell = (GsmCellLocation) phone.getCellLocation();
Victoria Leased50d0c32012-10-29 13:16:17 -07001816 if ((gsm_cell != null) && (phone.getNetworkOperator() != null)
1817 && (phone.getNetworkOperator().length() > 3)) {
Miguel Torroja1e84da82010-07-27 07:02:24 +02001818 int type;
gomo48f1a642017-11-10 20:35:46 -08001819 int mcc = Integer.parseInt(phone.getNetworkOperator().substring(0, 3));
Miguel Torroja1e84da82010-07-27 07:02:24 +02001820 int mnc = Integer.parseInt(phone.getNetworkOperator().substring(3));
Mike Lockwoodedc0f3872010-10-22 09:16:17 -04001821 int networkType = phone.getNetworkType();
1822 if (networkType == TelephonyManager.NETWORK_TYPE_UMTS
gomo48f1a642017-11-10 20:35:46 -08001823 || networkType == TelephonyManager.NETWORK_TYPE_HSDPA
1824 || networkType == TelephonyManager.NETWORK_TYPE_HSUPA
1825 || networkType == TelephonyManager.NETWORK_TYPE_HSPA
1826 || networkType == TelephonyManager.NETWORK_TYPE_HSPAP) {
Miguel Torroja1e84da82010-07-27 07:02:24 +02001827 type = AGPS_REF_LOCATION_TYPE_UMTS_CELLID;
Mike Lockwoodedc0f3872010-10-22 09:16:17 -04001828 } else {
Miguel Torroja1e84da82010-07-27 07:02:24 +02001829 type = AGPS_REF_LOCATION_TYPE_GSM_CELLID;
Mike Lockwoodedc0f3872010-10-22 09:16:17 -04001830 }
Miguel Torroja1e84da82010-07-27 07:02:24 +02001831 native_agps_set_ref_location_cellid(type, mcc, mnc,
1832 gsm_cell.getLac(), gsm_cell.getCid());
Mike Lockwoodedc0f3872010-10-22 09:16:17 -04001833 } else {
gomo48f1a642017-11-10 20:35:46 -08001834 Log.e(TAG, "Error getting cell location info.");
Mike Lockwoodedc0f3872010-10-22 09:16:17 -04001835 }
Victoria Leased50d0c32012-10-29 13:16:17 -07001836 } else if (phoneType == TelephonyManager.PHONE_TYPE_CDMA) {
1837 Log.e(TAG, "CDMA not supported.");
Mike Lockwoodedc0f3872010-10-22 09:16:17 -04001838 }
Miguel Torroja1e84da82010-07-27 07:02:24 +02001839 }
Danke Xie22d1f9f2009-08-18 18:28:45 -04001840
Anil Admal94ec76a2019-01-15 09:42:01 -08001841 // Implements method nfwNotifyCb() in IGnssVisibilityControlCallback.hal.
1842 @NativeEntryPoint
1843 private void reportNfwNotification(String proxyAppPackageName, byte protocolStack,
1844 String otherProtocolStackName, byte requestor, String requestorId, byte responseType,
1845 boolean inEmergencyMode, boolean isCachedLocation) {
1846 if (mGnssVisibilityControl == null) {
1847 Log.e(TAG, "reportNfwNotification: mGnssVisibilityControl is not initialized.");
1848 return;
1849 }
1850
1851 mGnssVisibilityControl.reportNfwNotification(proxyAppPackageName, protocolStack,
1852 otherProtocolStackName, requestor, requestorId, responseType, inEmergencyMode,
1853 isCachedLocation);
1854 }
1855
1856 // Implements method isInEmergencySession() in IGnssVisibilityControlCallback.hal.
1857 @NativeEntryPoint
1858 boolean isInEmergencySession() {
1859 return mNIHandler.getInEmergency();
1860 }
1861
Mike Lockwood98e48692010-04-07 16:32:51 -04001862 private void sendMessage(int message, int arg, Object obj) {
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001863 // hold a wake lock until this message is delivered
Jeff Brown028872f2012-08-25 13:07:01 -07001864 // note that this assumes the message will not be removed from the queue before
1865 // it is handled (otherwise the wake lock would be leaked).
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001866 mWakeLock.acquire();
Anil Admal4f97c942018-11-12 10:52:46 -08001867 if (DEBUG) {
1868 Log.d(TAG, "WakeLock acquired by sendMessage(" + messageIdAsString(message) + ", " + arg
Wyatt Rileycf879db2017-01-12 13:57:38 -08001869 + ", " + obj + ")");
1870 }
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001871 mHandler.obtainMessage(message, arg, 1, obj).sendToTarget();
Mike Lockwood98e48692010-04-07 16:32:51 -04001872 }
1873
Mike Lockwood62a8fc12010-03-22 14:23:26 -04001874 private final class ProviderHandler extends Handler {
Victoria Lease5cd731a2012-12-19 15:04:21 -08001875 public ProviderHandler(Looper looper) {
1876 super(looper, null, true /*async*/);
Jeff Brown028872f2012-08-25 13:07:01 -07001877 }
1878
Mike Lockwood62a8fc12010-03-22 14:23:26 -04001879 @Override
Mike Lockwood4a7b65e2010-10-25 16:35:55 -04001880 public void handleMessage(Message msg) {
Mike Lockwood98e48692010-04-07 16:32:51 -04001881 int message = msg.what;
1882 switch (message) {
Mike Lockwood62a8fc12010-03-22 14:23:26 -04001883 case ENABLE:
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001884 handleEnable();
Mike Lockwood62a8fc12010-03-22 14:23:26 -04001885 break;
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001886 case SET_REQUEST:
1887 GpsRequest gpsRequest = (GpsRequest) msg.obj;
1888 handleSetRequest(gpsRequest.request, gpsRequest.source);
Mike Lockwood03ca2162010-04-01 08:10:09 -07001889 break;
Mike Lockwood62a8fc12010-03-22 14:23:26 -04001890 case INJECT_NTP_TIME:
Yu-Han Yanga1862b52018-02-20 17:05:59 -08001891 mNtpTimeHelper.retrieveAndInjectNtpTime();
Mike Lockwood62a8fc12010-03-22 14:23:26 -04001892 break;
Yu-Han Yange7baef32018-02-09 13:58:17 -08001893 case REQUEST_LOCATION:
1894 handleRequestLocation((boolean) msg.obj);
1895 break;
Mike Lockwood62a8fc12010-03-22 14:23:26 -04001896 case DOWNLOAD_XTRA_DATA:
Wyatt Riley0d6e54e22016-10-05 12:03:03 -07001897 handleDownloadXtraData();
Mike Lockwood62a8fc12010-03-22 14:23:26 -04001898 break;
Kevin Tang40e1baf2012-01-10 14:32:44 -08001899 case DOWNLOAD_XTRA_DATA_FINISHED:
1900 mDownloadXtraDataPending = STATE_IDLE;
1901 break;
Mike Lockwood62a8fc12010-03-22 14:23:26 -04001902 case UPDATE_LOCATION:
destradaae21252a2015-09-08 12:32:59 -07001903 handleUpdateLocation((Location) msg.obj);
Mike Lockwood62a8fc12010-03-22 14:23:26 -04001904 break;
Meng Wang19b214d2018-11-07 12:14:39 -08001905 case SUBSCRIPTION_OR_CARRIER_CONFIG_CHANGED:
1906 subscriptionOrCarrierConfigChanged(mContext);
destradaafb23c672015-04-16 14:01:27 -07001907 break;
1908 case INITIALIZE_HANDLER:
destradaae21252a2015-09-08 12:32:59 -07001909 handleInitialize();
destradaafb23c672015-04-16 14:01:27 -07001910 break;
Wyatt Riley26465d22018-02-12 13:44:24 -08001911 case REPORT_LOCATION:
1912 handleReportLocation(msg.arg1 == 1, (Location) msg.obj);
1913 break;
1914 case REPORT_SV_STATUS:
1915 handleReportSvStatus((SvStatusInfo) msg.obj);
1916 break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001917 }
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001918 if (msg.arg2 == 1) {
1919 // wakelock was taken for this message, release it
1920 mWakeLock.release();
Anil Admal4f97c942018-11-12 10:52:46 -08001921 if (DEBUG) {
1922 Log.d(TAG, "WakeLock released by handleMessage(" + messageIdAsString(message)
Wyatt Rileycf879db2017-01-12 13:57:38 -08001923 + ", " + msg.arg1 + ", " + msg.obj + ")");
1924 }
Mike Lockwood98e48692010-04-07 16:32:51 -04001925 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001926 }
destradaafb23c672015-04-16 14:01:27 -07001927
1928 /**
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001929 * This method is bound to {@link #GnssLocationProvider(Context, LocationProviderManager,
1930 * Looper)}.
destradaafb23c672015-04-16 14:01:27 -07001931 * It is in charge of loading properties and registering for events that will be posted to
1932 * this handler.
1933 */
destradaae21252a2015-09-08 12:32:59 -07001934 private void handleInitialize() {
Yu-Han Yang6d317352018-03-15 11:53:01 -07001935 native_init_once();
1936
Wyatt Riley523a0cf2017-10-31 14:36:52 -07001937 /*
1938 * A cycle of native_init() and native_cleanup() is needed so that callbacks are
1939 * registered after bootup even when location is disabled.
1940 * This will allow Emergency SUPL to work even when location is disabled before device
1941 * restart.
1942 */
1943 boolean isInitialized = native_init();
gomo48f1a642017-11-10 20:35:46 -08001944 if (!isInitialized) {
Wyatt Riley523a0cf2017-10-31 14:36:52 -07001945 Log.w(TAG, "Native initialization failed at bootup");
1946 } else {
1947 native_cleanup();
1948 }
1949
Anil Admal94ec76a2019-01-15 09:42:01 -08001950 if (native_is_gnss_visibility_control_supported()) {
1951 mGnssVisibilityControl = new GnssVisibilityControl(mContext, mLooper);
1952 }
1953
destradaafb23c672015-04-16 14:01:27 -07001954 // load default GPS configuration
1955 // (this configuration might change in the future based on SIM changes)
Anil Admald71cf142018-12-21 14:59:36 -08001956 reloadGpsProperties();
destradaafb23c672015-04-16 14:01:27 -07001957
1958 // TODO: When this object "finishes" we should unregister by invoking
gomo48f1a642017-11-10 20:35:46 -08001959 // SubscriptionManager.getInstance(mContext).unregister
1960 // (mOnSubscriptionsChangedListener);
destradaafb23c672015-04-16 14:01:27 -07001961 // This is not strictly necessary because it will be unregistered if the
1962 // notification fails but it is good form.
1963
1964 // Register for SubscriptionInfo list changes which is guaranteed
1965 // to invoke onSubscriptionsChanged the first time.
1966 SubscriptionManager.from(mContext)
1967 .addOnSubscriptionsChangedListener(mOnSubscriptionsChangedListener);
1968
1969 // listen for events
WyattRiley6593cf12018-06-23 10:37:48 -07001970 IntentFilter intentFilter = new IntentFilter();
destradaafb23c672015-04-16 14:01:27 -07001971 intentFilter.addAction(ALARM_WAKEUP);
1972 intentFilter.addAction(ALARM_TIMEOUT);
destradaafb23c672015-04-16 14:01:27 -07001973 intentFilter.addAction(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED);
Adam Lesinski87c17df2015-05-27 13:24:13 -07001974 intentFilter.addAction(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED);
destradaafb23c672015-04-16 14:01:27 -07001975 intentFilter.addAction(Intent.ACTION_SCREEN_OFF);
1976 intentFilter.addAction(Intent.ACTION_SCREEN_ON);
Meng Wang19b214d2018-11-07 12:14:39 -08001977 intentFilter.addAction(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
destradaafb23c672015-04-16 14:01:27 -07001978 mContext.registerReceiver(mBroadcastReceiver, intentFilter, null, this);
1979
Anil Admal50ba15e2018-11-01 16:42:42 -07001980 mNetworkConnectivityHandler.registerNetworkCallbacks();
destradaae21252a2015-09-08 12:32:59 -07001981
destradaafb23c672015-04-16 14:01:27 -07001982 // listen for PASSIVE_PROVIDER updates
1983 LocationManager locManager =
1984 (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE);
1985 long minTime = 0;
1986 float minDistance = 0;
destradaafb23c672015-04-16 14:01:27 -07001987 LocationRequest request = LocationRequest.createFromDeprecatedProvider(
1988 LocationManager.PASSIVE_PROVIDER,
1989 minTime,
1990 minDistance,
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001991 false);
destradaafb23c672015-04-16 14:01:27 -07001992 // Don't keep track of this request since it's done on behalf of other clients
1993 // (which are kept track of separately).
1994 request.setHideFromAppOps(true);
1995 locManager.requestLocationUpdates(
1996 request,
1997 new NetworkLocationListener(),
1998 getLooper());
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001999
2000 // enable gps provider, it will never be disabled (legacy behavior)
2001 sendEmptyMessage(ENABLE);
destradaafb23c672015-04-16 14:01:27 -07002002 }
2003 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002004
Yu-Han Yange7baef32018-02-09 13:58:17 -08002005 private abstract class LocationChangeListener implements LocationListener {
Soonil Nagarkar1575a042018-10-24 17:54:54 -07002006 private int mNumLocationUpdateRequest;
Yu-Han Yang07561382018-02-21 13:08:37 -08002007
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002008 @Override
gomo48f1a642017-11-10 20:35:46 -08002009 public void onStatusChanged(String provider, int status, Bundle extras) {
2010 }
2011
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002012 @Override
gomo48f1a642017-11-10 20:35:46 -08002013 public void onProviderEnabled(String provider) {
2014 }
2015
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002016 @Override
gomo48f1a642017-11-10 20:35:46 -08002017 public void onProviderDisabled(String provider) {
2018 }
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002019 }
2020
Yu-Han Yange7baef32018-02-09 13:58:17 -08002021 private final class NetworkLocationListener extends LocationChangeListener {
2022 @Override
2023 public void onLocationChanged(Location location) {
2024 // this callback happens on mHandler looper
2025 if (LocationManager.NETWORK_PROVIDER.equals(location.getProvider())) {
2026 handleUpdateLocation(location);
2027 }
2028 }
2029 }
2030
2031 private final class FusedLocationListener extends LocationChangeListener {
2032 @Override
2033 public void onLocationChanged(Location location) {
2034 if (LocationManager.FUSED_PROVIDER.equals(location.getProvider())) {
Yu-Han Yange7baef32018-02-09 13:58:17 -08002035 injectBestLocation(location);
2036 }
2037 }
2038 }
2039
Wyatt Rileycf879db2017-01-12 13:57:38 -08002040 /**
2041 * @return A string representing the given message ID.
2042 */
2043 private String messageIdAsString(int message) {
2044 switch (message) {
2045 case ENABLE:
2046 return "ENABLE";
2047 case SET_REQUEST:
2048 return "SET_REQUEST";
Wyatt Rileycf879db2017-01-12 13:57:38 -08002049 case INJECT_NTP_TIME:
2050 return "INJECT_NTP_TIME";
Yu-Han Yange7baef32018-02-09 13:58:17 -08002051 case REQUEST_LOCATION:
2052 return "REQUEST_LOCATION";
Wyatt Rileycf879db2017-01-12 13:57:38 -08002053 case DOWNLOAD_XTRA_DATA:
2054 return "DOWNLOAD_XTRA_DATA";
Wyatt Rileycf879db2017-01-12 13:57:38 -08002055 case DOWNLOAD_XTRA_DATA_FINISHED:
2056 return "DOWNLOAD_XTRA_DATA_FINISHED";
2057 case UPDATE_LOCATION:
2058 return "UPDATE_LOCATION";
Meng Wang19b214d2018-11-07 12:14:39 -08002059 case SUBSCRIPTION_OR_CARRIER_CONFIG_CHANGED:
2060 return "SUBSCRIPTION_OR_CARRIER_CONFIG_CHANGED";
Wyatt Rileycf879db2017-01-12 13:57:38 -08002061 case INITIALIZE_HANDLER:
2062 return "INITIALIZE_HANDLER";
Wyatt Riley26465d22018-02-12 13:44:24 -08002063 case REPORT_LOCATION:
2064 return "REPORT_LOCATION";
2065 case REPORT_SV_STATUS:
2066 return "REPORT_SV_STATUS";
Wyatt Rileycf879db2017-01-12 13:57:38 -08002067 default:
2068 return "<Unknown>";
2069 }
2070 }
2071
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002072 @Override
2073 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2074 StringBuilder s = new StringBuilder();
Wyatt Riley77ca4f82017-06-30 18:13:44 -07002075 s.append(" mStarted=").append(mStarted).append('\n');
destradaa25e8caf2015-08-24 14:14:44 -07002076 s.append(" mFixInterval=").append(mFixInterval).append('\n');
gomo48f1a642017-11-10 20:35:46 -08002077 s.append(" mLowPowerMode=").append(mLowPowerMode).append('\n');
Wyatt Riley74479bd2018-01-17 08:48:27 -08002078 s.append(" mGnssMeasurementsProvider.isRegistered()=")
2079 .append(mGnssMeasurementsProvider.isRegistered()).append('\n');
2080 s.append(" mGnssNavigationMessageProvider.isRegistered()=")
2081 .append(mGnssNavigationMessageProvider.isRegistered()).append('\n');
destradaa25e8caf2015-08-24 14:14:44 -07002082 s.append(" mDisableGps (battery saver mode)=").append(mDisableGps).append('\n');
2083 s.append(" mEngineCapabilities=0x").append(Integer.toHexString(mEngineCapabilities));
2084 s.append(" ( ");
2085 if (hasCapability(GPS_CAPABILITY_SCHEDULING)) s.append("SCHEDULING ");
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002086 if (hasCapability(GPS_CAPABILITY_MSB)) s.append("MSB ");
2087 if (hasCapability(GPS_CAPABILITY_MSA)) s.append("MSA ");
2088 if (hasCapability(GPS_CAPABILITY_SINGLE_SHOT)) s.append("SINGLE_SHOT ");
2089 if (hasCapability(GPS_CAPABILITY_ON_DEMAND_TIME)) s.append("ON_DEMAND_TIME ");
destradaa25e8caf2015-08-24 14:14:44 -07002090 if (hasCapability(GPS_CAPABILITY_GEOFENCING)) s.append("GEOFENCING ");
2091 if (hasCapability(GPS_CAPABILITY_MEASUREMENTS)) s.append("MEASUREMENTS ");
2092 if (hasCapability(GPS_CAPABILITY_NAV_MESSAGES)) s.append("NAV_MESSAGES ");
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002093 s.append(")\n");
Siddharth Raybb608c82017-03-16 11:33:34 -07002094 s.append(mGnssMetrics.dumpGnssMetricsAsText());
2095 s.append(" native internal state: ").append(native_get_internal_state());
Wyatt Rileycf879db2017-01-12 13:57:38 -08002096 s.append("\n");
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002097 pw.append(s);
2098 }
2099
Mike Lockwoodb16e7802009-08-06 09:26:02 -04002100 // preallocated to avoid memory allocation in reportNmea()
2101 private byte[] mNmeaBuffer = new byte[120];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002102
gomo48f1a642017-11-10 20:35:46 -08002103 static {
2104 class_init_native();
2105 }
2106
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002107 private static native void class_init_native();
gomo48f1a642017-11-10 20:35:46 -08002108
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002109 private static native boolean native_is_supported();
gomo48f1a642017-11-10 20:35:46 -08002110
Anil Admal94ec76a2019-01-15 09:42:01 -08002111 private static native boolean native_is_gnss_visibility_control_supported();
2112
Yu-Han Yang6d317352018-03-15 11:53:01 -07002113 private static native void native_init_once();
2114
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002115 private native boolean native_init();
gomo48f1a642017-11-10 20:35:46 -08002116
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002117 private native void native_cleanup();
gomo48f1a642017-11-10 20:35:46 -08002118
Mike Lockwood04598b62010-04-14 17:17:24 -04002119 private native boolean native_set_position_mode(int mode, int recurrence, int min_interval,
gomo48f1a642017-11-10 20:35:46 -08002120 int preferred_accuracy, int preferred_time, boolean lowPowerMode);
2121
Mike Lockwood04598b62010-04-14 17:17:24 -04002122 private native boolean native_start();
gomo48f1a642017-11-10 20:35:46 -08002123
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002124 private native boolean native_stop();
gomo48f1a642017-11-10 20:35:46 -08002125
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002126 private native void native_delete_aiding_data(int flags);
gomo48f1a642017-11-10 20:35:46 -08002127
Mike Lockwoodf602d362010-06-20 14:28:16 -07002128 private native int native_read_nmea(byte[] buffer, int bufferSize);
gomo48f1a642017-11-10 20:35:46 -08002129
Yu-Han Yange7baef32018-02-09 13:58:17 -08002130 private native void native_inject_best_location(
2131 int gnssLocationFlags,
2132 double latitudeDegrees,
2133 double longitudeDegrees,
2134 double altitudeMeters,
2135 float speedMetersPerSec,
2136 float bearingDegrees,
2137 float horizontalAccuracyMeters,
2138 float verticalAccuracyMeters,
2139 float speedAccuracyMetersPerSecond,
2140 float bearingAccuracyDegrees,
2141 long timestamp);
2142
Mike Lockwoodd26ce0d2009-06-11 12:25:46 -04002143 private native void native_inject_location(double latitude, double longitude, float accuracy);
2144
Fred Fettinger3c8fbdf2010-01-04 15:38:13 -06002145 // XTRA Support
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002146 private native void native_inject_time(long time, long timeReference, int uncertainty);
gomo48f1a642017-11-10 20:35:46 -08002147
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002148 private native boolean native_supports_xtra();
gomo48f1a642017-11-10 20:35:46 -08002149
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002150 private native void native_inject_xtra_data(byte[] data, int length);
The Android Open Source Project10592532009-03-18 17:39:46 -07002151
Fred Fettinger3c8fbdf2010-01-04 15:38:13 -06002152 // DEBUG Support
2153 private native String native_get_internal_state();
2154
2155 // AGPS Support
gomo48f1a642017-11-10 20:35:46 -08002156 private native void native_agps_ni_message(byte[] msg, int length);
2157
Mike Lockwooda9e54612009-06-19 14:54:42 -04002158 private native void native_set_agps_server(int type, String hostname, int port);
Danke Xie22d1f9f2009-08-18 18:28:45 -04002159
2160 // Network-initiated (NI) Support
2161 private native void native_send_ni_response(int notificationId, int userResponse);
Miguel Torroja1e84da82010-07-27 07:02:24 +02002162
Anil Admal50ba15e2018-11-01 16:42:42 -07002163 // AGPS ril support
Miguel Torroja1e84da82010-07-27 07:02:24 +02002164 private native void native_agps_set_ref_location_cellid(int type, int mcc, int mnc,
2165 int lac, int cid);
gomo48f1a642017-11-10 20:35:46 -08002166
Miguel Torroja1e84da82010-07-27 07:02:24 +02002167 private native void native_agps_set_id(int type, String setid);
WyattRileyd1309312019-02-28 12:11:45 -08002168}