blob: 51563008464c3a7dec289e7faa74e1bf47f66291 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Mike Lockwood00b74272010-03-26 10:41:48 -040017package com.android.server.location;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080018
Mike Lockwood29c84342009-05-06 14:01:15 -040019import android.app.AlarmManager;
Dianne Hackborna06de0f2012-12-11 16:34:47 -080020import android.app.AppOpsManager;
Mike Lockwood29c84342009-05-06 14:01:15 -040021import android.app.PendingIntent;
The Android Open Source Project10592532009-03-18 17:39:46 -070022import android.content.BroadcastReceiver;
Yu-Han Yang74041ff2018-04-06 15:57:31 -070023import android.content.ContentResolver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080024import android.content.Context;
25import android.content.Intent;
The Android Open Source Project10592532009-03-18 17:39:46 -070026import android.content.IntentFilter;
Soonil Nagarkar35c3b912019-01-31 10:31:24 -080027import android.database.ContentObserver;
destradaa0682809a2013-08-12 18:50:30 -070028import android.hardware.location.GeofenceHardware;
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -070029import android.hardware.location.GeofenceHardwareImpl;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080030import android.location.Criteria;
destradaa0682809a2013-08-12 18:50:30 -070031import android.location.FusedBatchOptions;
Yu-Han Yange7baef32018-02-09 13:58:17 -080032import android.location.GnssMeasurementsEvent;
33import android.location.GnssNavigationMessage;
Lifu Tang30f95a72016-01-07 23:20:38 -080034import android.location.GnssStatus;
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -070035import android.location.IGpsGeofenceHardware;
Danke Xie22d1f9f2009-08-18 18:28:45 -040036import android.location.INetInitiatedListener;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080037import android.location.Location;
Nick Pelly6fa9ad42012-07-16 12:18:23 -070038import android.location.LocationListener;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080039import android.location.LocationManager;
40import android.location.LocationProvider;
Stan Chesnutt1d72d8c2013-04-15 19:18:02 -070041import android.location.LocationRequest;
Kevin Tang40e1baf2012-01-10 14:32:44 -080042import android.os.AsyncTask;
Dianne Hackborn91268cf2013-06-13 19:06:50 -070043import android.os.BatteryStats;
Mike Lockwood63aa5a62010-04-14 19:21:31 -040044import android.os.Binder;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080045import android.os.Bundle;
Mike Lockwood62a8fc12010-03-22 14:23:26 -040046import android.os.Handler;
Victoria Lease5cd731a2012-12-19 15:04:21 -080047import android.os.Looper;
Mike Lockwood62a8fc12010-03-22 14:23:26 -040048import android.os.Message;
Yu-Han Yange7baef32018-02-09 13:58:17 -080049import android.os.PersistableBundle;
Mike Lockwood0528b9b2009-05-07 10:12:54 -040050import android.os.PowerManager;
Yu-Han Yange7baef32018-02-09 13:58:17 -080051import android.os.PowerManager.ServiceType;
52import android.os.PowerSaveState;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080053import android.os.RemoteException;
Mike Lockwood2f82c4e2009-04-17 08:24:10 -040054import android.os.ServiceManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080055import android.os.SystemClock;
Colin Cross7c030ed2014-01-28 09:33:53 -080056import android.os.SystemProperties;
Dianne Hackborn5ac72a22012-08-29 18:32:08 -070057import android.os.UserHandle;
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -070058import android.os.WorkSource;
Narayan Kamath32684dd2018-01-08 17:32:51 +000059import android.os.WorkSource.WorkChain;
Mike Lockwoodbcab8df2009-06-25 16:39:09 -040060import android.provider.Settings;
Yu-Han Yange7baef32018-02-09 13:58:17 -080061import android.telephony.CarrierConfigManager;
Wink Savillea374c3d2014-11-11 11:48:04 -080062import android.telephony.SubscriptionManager;
Wink Savilled09c4ca2014-11-22 10:08:16 -080063import android.telephony.SubscriptionManager.OnSubscriptionsChangedListener;
Miguel Torroja1e84da82010-07-27 07:02:24 +020064import android.telephony.TelephonyManager;
65import android.telephony.gsm.GsmCellLocation;
Colin Cross7c030ed2014-01-28 09:33:53 -080066import android.text.TextUtils;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080067import android.util.Log;
Yu-Han Yang8a1b51d2018-12-26 22:18:31 -080068import android.util.StatsLog;
Yu-Han Yanga1862b52018-02-20 17:05:59 -080069
jackqdyulei455e90a2017-02-09 15:29:16 -080070import com.android.internal.app.IBatteryStats;
71import com.android.internal.location.GpsNetInitiatedHandler;
72import com.android.internal.location.GpsNetInitiatedHandler.GpsNiNotification;
73import com.android.internal.location.ProviderProperties;
74import com.android.internal.location.ProviderRequest;
Yu-Han Yange7baef32018-02-09 13:58:17 -080075import com.android.internal.location.gnssmetrics.GnssMetrics;
Yu-Han Yang66c7ea92018-03-11 17:17:15 -070076import com.android.server.location.GnssSatelliteBlacklistHelper.GnssSatelliteBlacklistCallback;
Yu-Han Yanga1862b52018-02-20 17:05:59 -080077import com.android.server.location.NtpTimeHelper.InjectNtpTimeCallback;
Yu-Han Yang66c7ea92018-03-11 17:17:15 -070078
Nick Pelly6fa9ad42012-07-16 12:18:23 -070079import java.io.FileDescriptor;
Nick Pelly6fa9ad42012-07-16 12:18:23 -070080import java.io.PrintWriter;
Soonil Nagarkar1575a042018-10-24 17:54:54 -070081import java.lang.annotation.ElementType;
82import java.lang.annotation.Retention;
83import java.lang.annotation.RetentionPolicy;
84import java.lang.annotation.Target;
Wyatt Rileycf879db2017-01-12 13:57:38 -080085import java.util.ArrayList;
Andreas Gampee6748ce2015-12-11 18:00:38 -080086import java.util.Arrays;
Wyatt Rileycf879db2017-01-12 13:57:38 -080087import java.util.List;
Yu-Han Yange7baef32018-02-09 13:58:17 -080088
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080089/**
gomo4402af62017-01-11 13:20:13 -080090 * A GNSS implementation of LocationProvider used by LocationManager.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080091 *
92 * {@hide}
93 */
Soonil Nagarkar1575a042018-10-24 17:54:54 -070094public class GnssLocationProvider extends AbstractLocationProvider implements
95 InjectNtpTimeCallback,
96 GnssSatelliteBlacklistCallback {
97
98 /**
99 * Indicates that this method is a native entry point. Useful purely for IDEs which can
100 * understand entry points, and thus eliminate incorrect warnings about methods not used.
101 */
102 @Target(ElementType.METHOD)
103 @Retention(RetentionPolicy.SOURCE)
104 private @interface NativeEntryPoint {
105 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800106
Lifu Tang30f95a72016-01-07 23:20:38 -0800107 private static final String TAG = "GnssLocationProvider";
Mike Lockwood29c84342009-05-06 14:01:15 -0400108
Brian Muramatsu1715cb32012-08-08 17:32:21 -0700109 private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
110 private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400111
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700112 private static final ProviderProperties PROPERTIES = new ProviderProperties(
113 true, true, false, false, true, true, true,
114 Criteria.POWER_HIGH, Criteria.ACCURACY_FINE);
115
gomo4402af62017-01-11 13:20:13 -0800116 // these need to match GnssPositionMode enum in IGnss.hal
The Android Open Source Project10592532009-03-18 17:39:46 -0700117 private static final int GPS_POSITION_MODE_STANDALONE = 0;
118 private static final int GPS_POSITION_MODE_MS_BASED = 1;
119 private static final int GPS_POSITION_MODE_MS_ASSISTED = 2;
120
gomo4402af62017-01-11 13:20:13 -0800121 // these need to match GnssPositionRecurrence enum in IGnss.hal
Mike Lockwood04598b62010-04-14 17:17:24 -0400122 private static final int GPS_POSITION_RECURRENCE_PERIODIC = 0;
123 private static final int GPS_POSITION_RECURRENCE_SINGLE = 1;
124
gomo4402af62017-01-11 13:20:13 -0800125 // these need to match GnssStatusValue enum in IGnssCallback.hal
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800126 private static final int GPS_STATUS_NONE = 0;
127 private static final int GPS_STATUS_SESSION_BEGIN = 1;
128 private static final int GPS_STATUS_SESSION_END = 2;
129 private static final int GPS_STATUS_ENGINE_ON = 3;
130 private static final int GPS_STATUS_ENGINE_OFF = 4;
131
gomo4402af62017-01-11 13:20:13 -0800132 // these need to match GnssLocationFlags enum in types.hal
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800133 private static final int LOCATION_INVALID = 0;
134 private static final int LOCATION_HAS_LAT_LONG = 1;
135 private static final int LOCATION_HAS_ALTITUDE = 2;
136 private static final int LOCATION_HAS_SPEED = 4;
137 private static final int LOCATION_HAS_BEARING = 8;
gomo4402af62017-01-11 13:20:13 -0800138 private static final int LOCATION_HAS_HORIZONTAL_ACCURACY = 16;
139 private static final int LOCATION_HAS_VERTICAL_ACCURACY = 32;
140 private static final int LOCATION_HAS_SPEED_ACCURACY = 64;
141 private static final int LOCATION_HAS_BEARING_ACCURACY = 128;
Mike Lockwoode3635c92009-05-11 08:38:02 -0400142
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -0800143 // these need to match ElapsedRealtimeFlags enum in types.hal
144 private static final int ELAPSED_REALTIME_HAS_TIMESTAMP_NS = 1;
145
gomo4402af62017-01-11 13:20:13 -0800146 // IMPORTANT - the GPS_DELETE_* symbols here must match GnssAidingData enum in IGnss.hal
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800147 private static final int GPS_DELETE_EPHEMERIS = 0x0001;
148 private static final int GPS_DELETE_ALMANAC = 0x0002;
149 private static final int GPS_DELETE_POSITION = 0x0004;
150 private static final int GPS_DELETE_TIME = 0x0008;
151 private static final int GPS_DELETE_IONO = 0x0010;
152 private static final int GPS_DELETE_UTC = 0x0020;
153 private static final int GPS_DELETE_HEALTH = 0x0040;
154 private static final int GPS_DELETE_SVDIR = 0x0080;
155 private static final int GPS_DELETE_SVSTEER = 0x0100;
156 private static final int GPS_DELETE_SADATA = 0x0200;
157 private static final int GPS_DELETE_RTI = 0x0400;
158 private static final int GPS_DELETE_CELLDB_INFO = 0x8000;
159 private static final int GPS_DELETE_ALL = 0xFFFF;
160
gomo4402af62017-01-11 13:20:13 -0800161 // The GPS_CAPABILITY_* flags must match Capabilities enum in IGnssCallback.hal
Mike Lockwood04598b62010-04-14 17:17:24 -0400162 private static final int GPS_CAPABILITY_SCHEDULING = 0x0000001;
163 private static final int GPS_CAPABILITY_MSB = 0x0000002;
164 private static final int GPS_CAPABILITY_MSA = 0x0000004;
165 private static final int GPS_CAPABILITY_SINGLE_SHOT = 0x0000008;
Mike Lockwood9b9fb5c2011-06-29 15:09:40 -0400166 private static final int GPS_CAPABILITY_ON_DEMAND_TIME = 0x0000010;
destradaa6568d702014-10-27 12:47:41 -0700167 private static final int GPS_CAPABILITY_GEOFENCING = 0x0000020;
gomo226b7b72018-12-12 16:49:39 -0800168 public static final int GPS_CAPABILITY_MEASUREMENTS = 0x0000040;
destradaa6568d702014-10-27 12:47:41 -0700169 private static final int GPS_CAPABILITY_NAV_MESSAGES = 0x0000080;
Mike Lockwood04598b62010-04-14 17:17:24 -0400170
Tsuwei Chen462bcd82014-09-17 12:28:49 -0700171 // The AGPS SUPL mode
172 private static final int AGPS_SUPL_MODE_MSA = 0x02;
173 private static final int AGPS_SUPL_MODE_MSB = 0x01;
174
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700175 private static final int SET_REQUEST = 3;
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400176 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
Kevin Tang40e1baf2012-01-10 14:32:44 -0800179 private static final int DOWNLOAD_XTRA_DATA_FINISHED = 11;
Meng Wang19b214d2018-11-07 12:14:39 -0800180 private static final int SUBSCRIPTION_OR_CARRIER_CONFIG_CHANGED = 12;
destradaafb23c672015-04-16 14:01:27 -0700181 private static final int INITIALIZE_HANDLER = 13;
Yu-Han Yange7baef32018-02-09 13:58:17 -0800182 private static final int REQUEST_LOCATION = 16;
Wyatt Riley26465d22018-02-12 13:44:24 -0800183 private static final int REPORT_LOCATION = 17; // HAL reports location
184 private static final int REPORT_SV_STATUS = 18; // HAL reports SV status
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400185
Miguel Torroja1e84da82010-07-27 07:02:24 +0200186 // Request setid
187 private static final int AGPS_RIL_REQUEST_SETID_IMSI = 1;
188 private static final int AGPS_RIL_REQUEST_SETID_MSISDN = 2;
189
Miguel Torroja1e84da82010-07-27 07:02:24 +0200190 // ref. location info
191 private static final int AGPS_REF_LOCATION_TYPE_GSM_CELLID = 1;
192 private static final int AGPS_REF_LOCATION_TYPE_UMTS_CELLID = 2;
Miguel Torroja1e84da82010-07-27 07:02:24 +0200193
194 // set id info
195 private static final int AGPS_SETID_TYPE_NONE = 0;
196 private static final int AGPS_SETID_TYPE_IMSI = 1;
197 private static final int AGPS_SETID_TYPE_MSISDN = 2;
198
gomo48f1a642017-11-10 20:35:46 -0800199 private static final int GPS_GEOFENCE_UNAVAILABLE = 1 << 0L;
200 private static final int GPS_GEOFENCE_AVAILABLE = 1 << 1L;
destradaa0682809a2013-08-12 18:50:30 -0700201
gomo4402af62017-01-11 13:20:13 -0800202 // GPS Geofence errors. Should match GeofenceStatus enum in IGnssGeofenceCallback.hal.
destradaa0682809a2013-08-12 18:50:30 -0700203 private static final int GPS_GEOFENCE_OPERATION_SUCCESS = 0;
204 private static final int GPS_GEOFENCE_ERROR_TOO_MANY_GEOFENCES = 100;
gomo48f1a642017-11-10 20:35:46 -0800205 private static final int GPS_GEOFENCE_ERROR_ID_EXISTS = -101;
destradaa0682809a2013-08-12 18:50:30 -0700206 private static final int GPS_GEOFENCE_ERROR_ID_UNKNOWN = -102;
207 private static final int GPS_GEOFENCE_ERROR_INVALID_TRANSITION = -103;
208 private static final int GPS_GEOFENCE_ERROR_GENERIC = -149;
209
Tsuwei Chen678c13c2014-09-22 17:48:41 -0700210 // TCP/IP constants.
211 // Valid TCP/UDP port range is (0, 65535].
212 private static final int TCP_MIN_PORT = 0;
213 private static final int TCP_MAX_PORT = 0xffff;
214
Yu-Han Yange7baef32018-02-09 13:58:17 -0800215 // 1 second, or 1 Hz frequency.
216 private static final long LOCATION_UPDATE_MIN_TIME_INTERVAL_MILLIS = 1000;
Yu-Han Yang639f7592018-06-07 11:58:52 -0700217 // Default update duration in milliseconds for REQUEST_LOCATION.
Yu-Han Yang9e2a8232018-06-14 12:10:08 -0700218 private static final long LOCATION_UPDATE_DURATION_MILLIS = 10 * 1000;
Yu-Han Yange7baef32018-02-09 13:58:17 -0800219
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700220 /** simpler wrapper for ProviderRequest + Worksource */
221 private static class GpsRequest {
222 public ProviderRequest request;
223 public WorkSource source;
gomo48f1a642017-11-10 20:35:46 -0800224
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700225 public GpsRequest(ProviderRequest request, WorkSource source) {
226 this.request = request;
227 this.source = source;
228 }
229 }
230
Wyatt Riley26465d22018-02-12 13:44:24 -0800231 // Threadsafe class to hold stats reported in the Extras Bundle
Wyatt Rileyc7067412018-02-07 15:50:35 -0800232 private static class LocationExtras {
233 private int mSvCount;
234 private int mMeanCn0;
235 private int mMaxCn0;
236 private final Bundle mBundle;
237
238 public LocationExtras() {
239 mBundle = new Bundle();
240 }
241
242 public void set(int svCount, int meanCn0, int maxCn0) {
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700243 synchronized (this) {
Wyatt Riley26465d22018-02-12 13:44:24 -0800244 mSvCount = svCount;
245 mMeanCn0 = meanCn0;
246 mMaxCn0 = maxCn0;
247 }
Wyatt Rileyc7067412018-02-07 15:50:35 -0800248 setBundle(mBundle);
249 }
250
251 public void reset() {
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700252 set(0, 0, 0);
Wyatt Rileyc7067412018-02-07 15:50:35 -0800253 }
254
255 // Also used by outside methods to add to other bundles
256 public void setBundle(Bundle extras) {
257 if (extras != null) {
Wyatt Riley26465d22018-02-12 13:44:24 -0800258 synchronized (this) {
259 extras.putInt("satellites", mSvCount);
260 extras.putInt("meanCn0", mMeanCn0);
261 extras.putInt("maxCn0", mMaxCn0);
262 }
Wyatt Rileyc7067412018-02-07 15:50:35 -0800263 }
264 }
265
266 public Bundle getBundle() {
Wyatt Riley26465d22018-02-12 13:44:24 -0800267 synchronized (this) {
268 return new Bundle(mBundle);
269 }
Wyatt Rileyc7067412018-02-07 15:50:35 -0800270 }
271 }
272
Yu-Han Yang66c7ea92018-03-11 17:17:15 -0700273 private final Object mLock = new Object();
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700274
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800275 // current status
Mike Lockwood15e3d0f2009-05-01 07:53:28 -0400276 private int mStatus = LocationProvider.TEMPORARILY_UNAVAILABLE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800277
278 // time for last status update
279 private long mStatusUpdateTime = SystemClock.elapsedRealtime();
Mike Lockwoodd53ba012010-04-15 20:41:26 -0400280
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800281 // turn off GPS fix icon if we haven't received a fix in 10 seconds
Mike Lockwood04598b62010-04-14 17:17:24 -0400282 private static final long RECENT_FIX_TIMEOUT = 10 * 1000;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800283
Mike Lockwood0632ca72009-05-14 15:51:03 -0400284 // stop trying if we do not receive a fix within 60 seconds
Mike Lockwood04598b62010-04-14 17:17:24 -0400285 private static final int NO_FIX_TIMEOUT = 60 * 1000;
Mike Lockwood0632ca72009-05-14 15:51:03 -0400286
Nick Pellyb041f232012-05-07 17:12:25 -0700287 // if the fix interval is below this we leave GPS on,
288 // if above then we cycle the GPS driver.
289 // Typical hot TTTF is ~5 seconds, so 10 seconds seems sane.
290 private static final int GPS_POLLING_THRESHOLD_INTERVAL = 10 * 1000;
291
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700292 // how long to wait if we have a network error in NTP or XTRA downloading
Wei Liu6f6326b2015-06-24 23:47:50 -0700293 // the initial value of the exponential backoff
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700294 // current setting - 5 minutes
gomo48f1a642017-11-10 20:35:46 -0800295 private static final long RETRY_INTERVAL = 5 * 60 * 1000;
Wei Liu6f6326b2015-06-24 23:47:50 -0700296 // how long to wait if we have a network error in NTP or XTRA downloading
297 // the max value of the exponential backoff
298 // current setting - 4 hours
gomo48f1a642017-11-10 20:35:46 -0800299 private static final long MAX_RETRY_INTERVAL = 4 * 60 * 60 * 1000;
Wei Liu6f6326b2015-06-24 23:47:50 -0700300
Wei Wangc5706f62017-04-18 11:26:26 -0700301 // Timeout when holding wakelocks for downloading XTRA data.
302 private static final long DOWNLOAD_XTRA_DATA_TIMEOUT_MS = 60 * 1000;
303
Yu-Han Yanga1862b52018-02-20 17:05:59 -0800304 private final ExponentialBackOff mXtraBackOff = new ExponentialBackOff(RETRY_INTERVAL,
305 MAX_RETRY_INTERVAL);
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700306
307 // true if we are enabled, protected by this
gomo92ace292019-02-09 19:17:47 -0800308 private boolean mEnabled;
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700309
Soonil Nagarkar35c3b912019-01-31 10:31:24 -0800310 private boolean mShutdown;
311
Kevin Tang40e1baf2012-01-10 14:32:44 -0800312 // states for injecting ntp and downloading xtra data
313 private static final int STATE_PENDING_NETWORK = 0;
314 private static final int STATE_DOWNLOADING = 1;
315 private static final int STATE_IDLE = 2;
316
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400317 // flags to trigger NTP or XTRA data download when network becomes available
318 // initialized to true so we do NTP and XTRA when the network comes up after booting
Kevin Tang40e1baf2012-01-10 14:32:44 -0800319 private int mDownloadXtraDataPending = STATE_PENDING_NETWORK;
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400320
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800321 // true if GPS is navigating
322 private boolean mNavigating;
Mike Lockwoodcf1d8cb2010-01-20 10:14:54 -0500323
Mike Lockwood04598b62010-04-14 17:17:24 -0400324 // requested frequency of fixes, in milliseconds
325 private int mFixInterval = 1000;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800326
gomo48f1a642017-11-10 20:35:46 -0800327 // true if low power mode for the GNSS chipset is part of the latest request.
328 private boolean mLowPowerMode = false;
329
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800330 // true if we started navigation
331 private boolean mStarted;
332
Mike Lockwood04598b62010-04-14 17:17:24 -0400333 // capabilities of the GPS engine
334 private int mEngineCapabilities;
335
Mike Lockwood1a1cd3a2010-08-17 07:42:54 -0400336 // true if XTRA is supported
337 private boolean mSupportsXtra;
338
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800339 // for calculating time to first fix
340 private long mFixRequestTime = 0;
341 // time to first fix for most recent session
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700342 private int mTimeToFirstFix = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800343 // time we received our last fix
344 private long mLastFixTime;
345
Mike Lockwood04598b62010-04-14 17:17:24 -0400346 private int mPositionMode;
Yu-Han Yangc8b9ff72018-04-17 00:47:24 -0700347 private GnssPositionMode mLastPositionMode;
Mike Lockwood04598b62010-04-14 17:17:24 -0400348
David Christied4edf4c2014-08-12 15:22:27 -0700349 // Current request from underlying location clients.
Soonil Nagarkar35c3b912019-01-31 10:31:24 -0800350 private ProviderRequest mProviderRequest;
Narayan Kamath32684dd2018-01-08 17:32:51 +0000351 // The WorkSource associated with the most recent client request (i.e, most recent call to
352 // setRequest).
David Christied4edf4c2014-08-12 15:22:27 -0700353 private WorkSource mWorkSource = null;
354 // True if gps should be disabled (used to support battery saver mode in settings).
355 private boolean mDisableGps = false;
356
destradaafb23c672015-04-16 14:01:27 -0700357 /**
358 * Properties loaded from PROPERTIES_FILE.
359 * It must be accessed only inside {@link #mHandler}.
360 */
Anil Admald71cf142018-12-21 14:59:36 -0800361 private GnssConfiguration mGnssConfiguration;
destradaafb23c672015-04-16 14:01:27 -0700362
Mike Lockwood734d6032009-07-28 18:30:25 -0700363 private String mSuplServerHost;
Tsuwei Chen678c13c2014-09-22 17:48:41 -0700364 private int mSuplServerPort = TCP_MIN_PORT;
Mike Lockwood734d6032009-07-28 18:30:25 -0700365 private String mC2KServerHost;
366 private int mC2KServerPort;
Tsuwei Chen3324e952014-09-07 01:30:42 -0700367 private boolean mSuplEsEnabled = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800368
Anil Admal94ec76a2019-01-15 09:42:01 -0800369 private final Looper mLooper;
Wyatt Rileyc7067412018-02-07 15:50:35 -0800370 private final LocationExtras mLocationExtras = new LocationExtras();
Anil Admal75b9fd62018-11-28 11:22:50 -0800371 private final GnssStatusListenerHelper mGnssStatusListenerHelper;
Lifu Tang818aa2c2016-02-01 01:52:00 -0800372 private final GnssMeasurementsProvider mGnssMeasurementsProvider;
373 private final GnssNavigationMessageProvider mGnssNavigationMessageProvider;
Yu-Han Yang07561382018-02-21 13:08:37 -0800374 private final LocationChangeListener mNetworkLocationListener = new NetworkLocationListener();
375 private final LocationChangeListener mFusedLocationListener = new FusedLocationListener();
Yu-Han Yanga1862b52018-02-20 17:05:59 -0800376 private final NtpTimeHelper mNtpTimeHelper;
Yu-Han Yang3557cc72018-03-21 12:48:36 -0700377 private final GnssBatchingProvider mGnssBatchingProvider;
Yu-Han Yang890ca8b2018-04-16 22:11:31 -0700378 private final GnssGeofenceProvider mGnssGeofenceProvider;
Anil Admal316f9482019-02-12 18:57:18 -0800379 // Available only on GNSS HAL 2.0 implementations and later.
Anil Admal94ec76a2019-01-15 09:42:01 -0800380 private GnssVisibilityControl mGnssVisibilityControl;
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400381
Victoria Lease5c24fd02012-10-01 11:00:50 -0700382 // Handler for processing events
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400383 private Handler mHandler;
The Android Open Source Project10592532009-03-18 17:39:46 -0700384
Anil Admal50ba15e2018-11-01 16:42:42 -0700385 private final GnssNetworkConnectivityHandler mNetworkConnectivityHandler;
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700386 private final GpsNetInitiatedHandler mNIHandler;
Mike Lockwood2f82c4e2009-04-17 08:24:10 -0400387
Mike Lockwood0528b9b2009-05-07 10:12:54 -0400388 // Wakelocks
Lifu Tang30f95a72016-01-07 23:20:38 -0800389 private final static String WAKELOCK_KEY = "GnssLocationProvider";
Mike Lockwood0528b9b2009-05-07 10:12:54 -0400390 private final PowerManager.WakeLock mWakeLock;
Wei Wangb71c0492017-05-01 20:24:19 -0700391 private static final String DOWNLOAD_EXTRA_WAKELOCK_KEY = "GnssLocationProviderXtraDownload";
392 private final PowerManager.WakeLock mDownloadXtraWakeLock;
Mike Lockwood0528b9b2009-05-07 10:12:54 -0400393
Mike Lockwood29c84342009-05-06 14:01:15 -0400394 // Alarms
395 private final static String ALARM_WAKEUP = "com.android.internal.location.ALARM_WAKEUP";
Mike Lockwood0632ca72009-05-14 15:51:03 -0400396 private final static String ALARM_TIMEOUT = "com.android.internal.location.ALARM_TIMEOUT";
Tsuwei Chen52617bb2014-08-25 11:49:11 -0700397
David Christied4edf4c2014-08-12 15:22:27 -0700398 private final PowerManager mPowerManager;
Mike Lockwood29c84342009-05-06 14:01:15 -0400399 private final AlarmManager mAlarmManager;
400 private final PendingIntent mWakeupIntent;
Mike Lockwood0632ca72009-05-14 15:51:03 -0400401 private final PendingIntent mTimeoutIntent;
Mike Lockwood29c84342009-05-06 14:01:15 -0400402
Svet Ganovf7b47252018-02-26 11:11:27 -0800403 private final AppOpsManager mAppOps;
Mike Lockwood2f82c4e2009-04-17 08:24:10 -0400404 private final IBatteryStats mBatteryStats;
The Android Open Source Project10592532009-03-18 17:39:46 -0700405
Narayan Kamath32684dd2018-01-08 17:32:51 +0000406 // Current list of underlying location clients.
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700407 // only modified on handler thread
Dianne Hackborn002a54e2013-01-10 17:34:55 -0800408 private WorkSource mClientSource = new WorkSource();
Mike Lockwoodf1218be2010-01-29 09:20:06 -0500409
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -0700410 private GeofenceHardwareImpl mGeofenceHardwareImpl;
Wyatt Rileyd87cf912017-12-05 09:31:52 -0800411
412 // Volatile for simple inter-thread sync on these values.
413 private volatile int mHardwareYear = 0;
Wyatt Riley49097c02018-03-15 09:14:43 -0700414 private volatile String mHardwareModelName;
Lifu Tang82f893d2016-01-21 18:15:33 -0800415
Wyatt Riley5d5bac82016-11-01 07:05:16 -0700416 // Set lower than the current ITAR limit of 600m/s to allow this to trigger even if GPS HAL
417 // stops output right at 600m/s, depriving this of the information of a device that reaches
418 // greater than 600m/s, and higher than the speed of sound to avoid impacting most use cases.
419 private static final float ITAR_SPEED_LIMIT_METERS_PER_SECOND = 400.0F;
Wyatt Riley042c48f2017-10-06 14:59:25 -0700420
Wyatt Riley042c48f2017-10-06 14:59:25 -0700421 private volatile boolean mItarSpeedLimitExceeded = false;
Wyatt Riley5d5bac82016-11-01 07:05:16 -0700422
Siddharth Raybb608c82017-03-16 11:33:34 -0700423 // GNSS Metrics
424 private GnssMetrics mGnssMetrics;
425
Anil Admal75b9fd62018-11-28 11:22:50 -0800426 public GnssStatusListenerHelper getGnssStatusProvider() {
427 return mGnssStatusListenerHelper;
Mike Lockwood15e3d0f2009-05-01 07:53:28 -0400428 }
429
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -0700430 public IGpsGeofenceHardware getGpsGeofenceProxy() {
Yu-Han Yang890ca8b2018-04-16 22:11:31 -0700431 return mGnssGeofenceProvider;
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -0700432 }
433
Lifu Tang818aa2c2016-02-01 01:52:00 -0800434 public GnssMeasurementsProvider getGnssMeasurementsProvider() {
435 return mGnssMeasurementsProvider;
destradaaea8a8a62014-06-23 18:19:03 -0700436 }
437
Lifu Tang818aa2c2016-02-01 01:52:00 -0800438 public GnssNavigationMessageProvider getGnssNavigationMessageProvider() {
439 return mGnssNavigationMessageProvider;
destradaa4b3e3932014-07-21 18:01:47 -0700440 }
Tsuwei Chen52617bb2014-08-25 11:49:11 -0700441 private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
gomo48f1a642017-11-10 20:35:46 -0800442 @Override
443 public void onReceive(Context context, Intent intent) {
The Android Open Source Project10592532009-03-18 17:39:46 -0700444 String action = intent.getAction();
Tsuwei Chen48d37f92014-09-05 15:15:34 -0700445 if (DEBUG) Log.d(TAG, "receive broadcast intent, action: " + action);
destradaaee9fd342015-08-31 13:31:17 -0700446 if (action == null) {
447 return;
448 }
449
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700450 switch (action) {
451 case ALARM_WAKEUP:
Yu-Han Yang6a5f0b72019-01-24 18:34:28 -0800452 startNavigating();
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700453 break;
454 case ALARM_TIMEOUT:
455 hibernate();
456 break;
457 case PowerManager.ACTION_POWER_SAVE_MODE_CHANGED:
458 case PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED:
459 case Intent.ACTION_SCREEN_OFF:
460 case Intent.ACTION_SCREEN_ON:
461 updateLowPowerMode();
462 break;
Meng Wang19b214d2018-11-07 12:14:39 -0800463 case CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED:
464 subscriptionOrCarrierConfigChanged(context);
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700465 break;
David Christied4edf4c2014-08-12 15:22:27 -0700466 }
The Android Open Source Project10592532009-03-18 17:39:46 -0700467 }
Mike Lockwood29c84342009-05-06 14:01:15 -0400468 };
The Android Open Source Project10592532009-03-18 17:39:46 -0700469
Anil Admal316f9482019-02-12 18:57:18 -0800470 // TODO: replace OnSubscriptionsChangedListener with ACTION_DEFAULT_DATA_SUBSCRIPTION_CHANGED
471 // broadcast receiver.
Wink Savilled09c4ca2014-11-22 10:08:16 -0800472 private final OnSubscriptionsChangedListener mOnSubscriptionsChangedListener =
473 new OnSubscriptionsChangedListener() {
gomo48f1a642017-11-10 20:35:46 -0800474 @Override
475 public void onSubscriptionsChanged() {
Meng Wang19b214d2018-11-07 12:14:39 -0800476 sendMessage(SUBSCRIPTION_OR_CARRIER_CONFIG_CHANGED, 0, null);
gomo48f1a642017-11-10 20:35:46 -0800477 }
478 };
Wink Savillea374c3d2014-11-11 11:48:04 -0800479
Yu-Han Yang66c7ea92018-03-11 17:17:15 -0700480 /**
481 * Implements {@link GnssSatelliteBlacklistCallback#onUpdateSatelliteBlacklist}.
482 */
483 @Override
484 public void onUpdateSatelliteBlacklist(int[] constellations, int[] svids) {
Anil Admald71cf142018-12-21 14:59:36 -0800485 mHandler.post(() -> mGnssConfiguration.setSatelliteBlacklist(constellations, svids));
Yu-Han Yang66c7ea92018-03-11 17:17:15 -0700486 }
487
Meng Wang19b214d2018-11-07 12:14:39 -0800488 private void subscriptionOrCarrierConfigChanged(Context context) {
Joe Onorato0c484102016-02-01 18:04:24 -0800489 if (DEBUG) Log.d(TAG, "received SIM related action: ");
Wink Savillea374c3d2014-11-11 11:48:04 -0800490 TelephonyManager phone = (TelephonyManager)
491 mContext.getSystemService(Context.TELEPHONY_SERVICE);
Ecco Park4fa1ab72016-10-24 13:04:52 -0700492 CarrierConfigManager configManager = (CarrierConfigManager)
493 mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE);
Wink Savillea374c3d2014-11-11 11:48:04 -0800494 String mccMnc = phone.getSimOperator();
Ecco Park4fa1ab72016-10-24 13:04:52 -0700495 boolean isKeepLppProfile = false;
Wink Savillea374c3d2014-11-11 11:48:04 -0800496 if (!TextUtils.isEmpty(mccMnc)) {
Joe Onorato0c484102016-02-01 18:04:24 -0800497 if (DEBUG) Log.d(TAG, "SIM MCC/MNC is available: " + mccMnc);
Wink Savillea374c3d2014-11-11 11:48:04 -0800498 synchronized (mLock) {
Ecco Park4fa1ab72016-10-24 13:04:52 -0700499 if (configManager != null) {
500 PersistableBundle b = configManager.getConfig();
Wyatt Rileya8ce2252017-09-01 13:31:17 -0700501 if (b != null) {
502 isKeepLppProfile =
Meng Wang19b214d2018-11-07 12:14:39 -0800503 b.getBoolean(CarrierConfigManager.Gps.KEY_PERSIST_LPP_MODE_BOOL);
Wyatt Rileya8ce2252017-09-01 13:31:17 -0700504 }
Ecco Park4fa1ab72016-10-24 13:04:52 -0700505 }
506 if (isKeepLppProfile) {
507 // load current properties for the carrier
Anil Admald71cf142018-12-21 14:59:36 -0800508 mGnssConfiguration.loadPropertiesFromCarrierConfig();
509 String lpp_profile = mGnssConfiguration.getLppProfile();
Ecco Park4fa1ab72016-10-24 13:04:52 -0700510 // set the persist property LPP_PROFILE for the value
Ecco Park8eec7442017-08-04 16:21:59 -0700511 if (lpp_profile != null) {
Anil Admald71cf142018-12-21 14:59:36 -0800512 SystemProperties.set(GnssConfiguration.LPP_PROFILE, lpp_profile);
Ecco Park8eec7442017-08-04 16:21:59 -0700513 }
Ecco Park624ac3c2016-07-18 14:08:05 -0700514 } else {
Ecco Park4fa1ab72016-10-24 13:04:52 -0700515 // reset the persist property
Anil Admald71cf142018-12-21 14:59:36 -0800516 SystemProperties.set(GnssConfiguration.LPP_PROFILE, "");
Ecco Park624ac3c2016-07-18 14:08:05 -0700517 }
Anil Admald71cf142018-12-21 14:59:36 -0800518 reloadGpsProperties();
Wink Savillea374c3d2014-11-11 11:48:04 -0800519 mNIHandler.setSuplEsEnabled(mSuplEsEnabled);
520 }
521 } else {
Joe Onorato0c484102016-02-01 18:04:24 -0800522 if (DEBUG) Log.d(TAG, "SIM MCC/MNC is still not available");
Wink Savillea374c3d2014-11-11 11:48:04 -0800523 }
524 }
525
David Christied4edf4c2014-08-12 15:22:27 -0700526 private void updateLowPowerMode() {
Adam Lesinski87c17df2015-05-27 13:24:13 -0700527 // Disable GPS if we are in device idle mode.
528 boolean disableGps = mPowerManager.isDeviceIdleMode();
jackqdyulei455e90a2017-02-09 15:29:16 -0800529 final PowerSaveState result =
Kweku Adams731a1032019-02-04 14:05:41 -0800530 mPowerManager.getPowerSaveState(ServiceType.LOCATION);
531 switch (result.locationMode) {
Makoto Onuki57f0f552017-12-11 12:22:18 -0800532 case PowerManager.LOCATION_MODE_GPS_DISABLED_WHEN_SCREEN_OFF:
Kweku Adams5e0052b2019-02-22 15:17:52 -0800533 case PowerManager.LOCATION_MODE_ALL_DISABLED_WHEN_SCREEN_OFF:
Adam Lesinski87c17df2015-05-27 13:24:13 -0700534 // If we are in battery saver mode and the screen is off, disable GPS.
jackqdyulei455e90a2017-02-09 15:29:16 -0800535 disableGps |= result.batterySaverEnabled && !mPowerManager.isInteractive();
David Christied4edf4c2014-08-12 15:22:27 -0700536 break;
David Christied4edf4c2014-08-12 15:22:27 -0700537 }
538 if (disableGps != mDisableGps) {
539 mDisableGps = disableGps;
Soonil Nagarkar35c3b912019-01-31 10:31:24 -0800540 updateEnabled();
David Christied4edf4c2014-08-12 15:22:27 -0700541 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);
destradaafb23c672015-04-16 14:01:27 -0700603 sendMessage(INITIALIZE_HANDLER, 0, null);
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400604
Tsuwei Chen3324e952014-09-07 01:30:42 -0700605 // Create a GPS net-initiated handler.
606 mNIHandler = new GpsNetInitiatedHandler(context,
gomo48f1a642017-11-10 20:35:46 -0800607 mNetInitiatedListener,
608 mSuplEsEnabled);
Tsuwei Chen3324e952014-09-07 01:30:42 -0700609
Anil Admal75b9fd62018-11-28 11:22:50 -0800610 mGnssStatusListenerHelper = new GnssStatusListenerHelper(mContext, mHandler) {
destradaa6568d702014-10-27 12:47:41 -0700611 @Override
612 protected boolean isAvailableInPlatform() {
destradaa13a60b02015-01-15 18:36:01 -0800613 return isSupported();
destradaa6568d702014-10-27 12:47:41 -0700614 }
615
616 @Override
617 protected boolean isGpsEnabled() {
618 return isEnabled();
619 }
620 };
621
Yu-Han Yang8de21502018-04-23 01:40:25 -0700622 mGnssMeasurementsProvider = new GnssMeasurementsProvider(mContext, mHandler) {
destradaa6568d702014-10-27 12:47:41 -0700623 @Override
624 protected boolean isGpsEnabled() {
625 return isEnabled();
626 }
627 };
628
Anil Admal75b9fd62018-11-28 11:22:50 -0800629 mGnssNavigationMessageProvider = new GnssNavigationMessageProvider(mContext, mHandler) {
destradaa6568d702014-10-27 12:47:41 -0700630 @Override
destradaa6568d702014-10-27 12:47:41 -0700631 protected boolean isGpsEnabled() {
632 return isEnabled();
633 }
634 };
Yu-Han Yanga1862b52018-02-20 17:05:59 -0800635
Anil Admal50ba15e2018-11-01 16:42:42 -0700636 mGnssMetrics = new GnssMetrics(mBatteryStats);
Yu-Han Yang66c7ea92018-03-11 17:17:15 -0700637 mNtpTimeHelper = new NtpTimeHelper(mContext, looper, this);
Soonil Nagarkar35c3b912019-01-31 10:31:24 -0800638 GnssSatelliteBlacklistHelper gnssSatelliteBlacklistHelper =
639 new GnssSatelliteBlacklistHelper(mContext,
640 looper, this);
641 mHandler.post(gnssSatelliteBlacklistHelper::updateSatelliteBlacklist);
Yu-Han Yang3557cc72018-03-21 12:48:36 -0700642 mGnssBatchingProvider = new GnssBatchingProvider();
Yu-Han Yang6dc9f052018-12-04 17:11:24 -0800643 mGnssGeofenceProvider = new GnssGeofenceProvider();
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400644
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700645 mContext.registerReceiverAsUser(new BroadcastReceiver() {
646 @Override
647 public void onReceive(Context context, Intent intent) {
648 if (getSendingUserId() == UserHandle.USER_ALL) {
Soonil Nagarkar35c3b912019-01-31 10:31:24 -0800649 mShutdown = true;
650 updateEnabled();
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700651 }
652 }
Soonil Nagarkar35c3b912019-01-31 10:31:24 -0800653 }, UserHandle.ALL, new IntentFilter(Intent.ACTION_SHUTDOWN), null, mHandler);
654
655 mContext.getContentResolver().registerContentObserver(
656 Settings.Secure.getUriFor(Settings.Secure.LOCATION_MODE),
657 true,
658 new ContentObserver(mHandler) {
659 @Override
660 public void onChange(boolean selfChange) {
661 updateEnabled();
662 }
663 }, UserHandle.USER_ALL);
Mike Lockwoodd03ff942010-02-09 08:46:14 -0500664
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700665 setProperties(PROPERTIES);
Soonil Nagarkar90da1ab2019-01-04 16:26:59 -0800666 setEnabled(true);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800667 }
668
Yu-Han Yanga1862b52018-02-20 17:05:59 -0800669 /**
670 * Implements {@link InjectNtpTimeCallback#injectTime}
671 */
672 @Override
673 public void injectTime(long time, long timeReference, int uncertainty) {
674 native_inject_time(time, timeReference, uncertainty);
675 }
676
Anil Admal50ba15e2018-11-01 16:42:42 -0700677 /**
678 * Implements {@link GnssNetworkConnectivityHandler.GnssNetworkListener#onNetworkAvailable()}
679 */
680 private void onNetworkAvailable() {
681 mNtpTimeHelper.onNetworkAvailable();
682 if (mDownloadXtraDataPending == STATE_PENDING_NETWORK) {
683 if (mSupportsXtra) {
Anil Admal316f9482019-02-12 18:57:18 -0800684 // Download only if supported, (prevents an unnecessary on-boot download)
Anil Admal50ba15e2018-11-01 16:42:42 -0700685 xtraDownloadRequest();
destradaaef752b62015-04-17 13:10:47 -0700686 }
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400687 }
688 }
Yu-Han Yang8de21502018-04-23 01:40:25 -0700689
Yu-Han Yange7baef32018-02-09 13:58:17 -0800690 private void handleRequestLocation(boolean independentFromGnss) {
691 if (isRequestLocationRateLimited()) {
692 if (DEBUG) {
693 Log.d(TAG, "RequestLocation is denied due to too frequent requests.");
694 }
695 return;
696 }
Yu-Han Yang74041ff2018-04-06 15:57:31 -0700697 ContentResolver resolver = mContext.getContentResolver();
698 long durationMillis = Settings.Global.getLong(
699 resolver,
700 Settings.Global.GNSS_HAL_LOCATION_REQUEST_DURATION_MILLIS,
701 LOCATION_UPDATE_DURATION_MILLIS);
702 if (durationMillis == 0) {
703 Log.i(TAG, "GNSS HAL location request is disabled by Settings.");
704 return;
705 }
Yu-Han Yange7baef32018-02-09 13:58:17 -0800706
707 LocationManager locationManager = (LocationManager) mContext.getSystemService(
708 Context.LOCATION_SERVICE);
Yu-Han Yang07561382018-02-21 13:08:37 -0800709 String provider;
710 LocationChangeListener locationListener;
Yu-Han Yange7baef32018-02-09 13:58:17 -0800711
712 if (independentFromGnss) {
713 // For fast GNSS TTFF
Yu-Han Yang07561382018-02-21 13:08:37 -0800714 provider = LocationManager.NETWORK_PROVIDER;
715 locationListener = mNetworkLocationListener;
Yu-Han Yange7baef32018-02-09 13:58:17 -0800716 } else {
717 // For Device-Based Hybrid (E911)
Yu-Han Yang07561382018-02-21 13:08:37 -0800718 provider = LocationManager.FUSED_PROVIDER;
719 locationListener = mFusedLocationListener;
Yu-Han Yange7baef32018-02-09 13:58:17 -0800720 }
Yu-Han Yang07561382018-02-21 13:08:37 -0800721
722 Log.i(TAG,
Yu-Han Yang74041ff2018-04-06 15:57:31 -0700723 String.format(
724 "GNSS HAL Requesting location updates from %s provider for %d millis.",
725 provider, durationMillis));
Yu-Han Yange684dda2018-05-24 10:29:39 -0700726 try {
727 locationManager.requestLocationUpdates(provider,
728 LOCATION_UPDATE_MIN_TIME_INTERVAL_MILLIS, /*minDistance=*/ 0,
729 locationListener, mHandler.getLooper());
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700730 locationListener.mNumLocationUpdateRequest++;
Yu-Han Yange684dda2018-05-24 10:29:39 -0700731 mHandler.postDelayed(() -> {
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700732 if (--locationListener.mNumLocationUpdateRequest == 0) {
Yu-Han Yange684dda2018-05-24 10:29:39 -0700733 Log.i(TAG,
734 String.format("Removing location updates from %s provider.", provider));
735 locationManager.removeUpdates(locationListener);
736 }
737 }, durationMillis);
738 } catch (IllegalArgumentException e) {
739 Log.w(TAG, "Unable to request location.", e);
740 }
Yu-Han Yange7baef32018-02-09 13:58:17 -0800741 }
742
743 private void injectBestLocation(Location location) {
744 int gnssLocationFlags = LOCATION_HAS_LAT_LONG |
745 (location.hasAltitude() ? LOCATION_HAS_ALTITUDE : 0) |
746 (location.hasSpeed() ? LOCATION_HAS_SPEED : 0) |
747 (location.hasBearing() ? LOCATION_HAS_BEARING : 0) |
748 (location.hasAccuracy() ? LOCATION_HAS_HORIZONTAL_ACCURACY : 0) |
749 (location.hasVerticalAccuracy() ? LOCATION_HAS_VERTICAL_ACCURACY : 0) |
750 (location.hasSpeedAccuracy() ? LOCATION_HAS_SPEED_ACCURACY : 0) |
751 (location.hasBearingAccuracy() ? LOCATION_HAS_BEARING_ACCURACY : 0);
752
753 double latitudeDegrees = location.getLatitude();
754 double longitudeDegrees = location.getLongitude();
755 double altitudeMeters = location.getAltitude();
756 float speedMetersPerSec = location.getSpeed();
757 float bearingDegrees = location.getBearing();
758 float horizontalAccuracyMeters = location.getAccuracy();
759 float verticalAccuracyMeters = location.getVerticalAccuracyMeters();
760 float speedAccuracyMetersPerSecond = location.getSpeedAccuracyMetersPerSecond();
761 float bearingAccuracyDegrees = location.getBearingAccuracyDegrees();
762 long timestamp = location.getTime();
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -0800763
764 int elapsedRealtimeFlags = ELAPSED_REALTIME_HAS_TIMESTAMP_NS;
765 long elapsedRealtimeNanos = location.getElapsedRealtimeNanos();
766
767 native_inject_best_location(
768 gnssLocationFlags, latitudeDegrees, longitudeDegrees,
769 altitudeMeters, speedMetersPerSec, bearingDegrees,
770 horizontalAccuracyMeters, verticalAccuracyMeters,
771 speedAccuracyMetersPerSecond, bearingAccuracyDegrees, timestamp,
772 elapsedRealtimeFlags, elapsedRealtimeNanos);
Yu-Han Yange7baef32018-02-09 13:58:17 -0800773 }
774
Yu-Han Yange7baef32018-02-09 13:58:17 -0800775 /** Returns true if the location request is too frequent. */
776 private boolean isRequestLocationRateLimited() {
Anil Admal316f9482019-02-12 18:57:18 -0800777 // TODO: implement exponential backoff.
Yu-Han Yange7baef32018-02-09 13:58:17 -0800778 return false;
779 }
780
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400781 private void handleDownloadXtraData() {
Wyatt Riley0d6e54e22016-10-05 12:03:03 -0700782 if (!mSupportsXtra) {
783 // native code reports xtra not supported, don't try
784 Log.d(TAG, "handleDownloadXtraData() called when Xtra not supported");
785 return;
786 }
Kevin Tang40e1baf2012-01-10 14:32:44 -0800787 if (mDownloadXtraDataPending == STATE_DOWNLOADING) {
788 // already downloading data
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400789 return;
790 }
Anil Admal50ba15e2018-11-01 16:42:42 -0700791 if (!mNetworkConnectivityHandler.isDataNetworkConnected()) {
Kevin Tang40e1baf2012-01-10 14:32:44 -0800792 // try again when network is up
793 mDownloadXtraDataPending = STATE_PENDING_NETWORK;
794 return;
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400795 }
Kevin Tang40e1baf2012-01-10 14:32:44 -0800796 mDownloadXtraDataPending = STATE_DOWNLOADING;
797
Jeff Brown028872f2012-08-25 13:07:01 -0700798 // hold wake lock while task runs
Wei Wangb71c0492017-05-01 20:24:19 -0700799 mDownloadXtraWakeLock.acquire(DOWNLOAD_XTRA_DATA_TIMEOUT_MS);
Lifu Tangcbd2a142016-06-22 10:57:55 -0700800 Log.i(TAG, "WakeLock acquired by handleDownloadXtraData()");
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700801 AsyncTask.THREAD_POOL_EXECUTOR.execute(() -> {
Anil Admald71cf142018-12-21 14:59:36 -0800802 GpsXtraDownloader xtraDownloader = new GpsXtraDownloader(
803 mGnssConfiguration.getProperties());
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700804 byte[] data = xtraDownloader.downloadXtraData();
805 if (data != null) {
806 if (DEBUG) Log.d(TAG, "calling native_inject_xtra_data");
807 native_inject_xtra_data(data, data.length);
808 mXtraBackOff.reset();
809 }
Kevin Tang40e1baf2012-01-10 14:32:44 -0800810
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700811 sendMessage(DOWNLOAD_XTRA_DATA_FINISHED, 0, null);
Kevin Tang40e1baf2012-01-10 14:32:44 -0800812
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700813 if (data == null) {
814 // try again later
815 // since this is delayed and not urgent we do not hold a wake lock here
816 mHandler.sendEmptyMessageDelayed(DOWNLOAD_XTRA_DATA,
817 mXtraBackOff.nextBackoffMillis());
818 }
Kevin Tang40e1baf2012-01-10 14:32:44 -0800819
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700820 // Release wake lock held by task, synchronize on mLock in case multiple
821 // download tasks overrun.
822 synchronized (mLock) {
823 if (mDownloadXtraWakeLock.isHeld()) {
824 // This wakelock may have time-out, if a timeout was specified.
825 // Catch (and ignore) any timeout exceptions.
826 try {
827 mDownloadXtraWakeLock.release();
828 if (DEBUG) Log.d(TAG, "WakeLock released by handleDownloadXtraData()");
829 } catch (Exception e) {
830 Log.i(TAG, "Wakelock timeout & release race exception in "
831 + "handleDownloadXtraData()", e);
Wei Wangb71c0492017-05-01 20:24:19 -0700832 }
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700833 } else {
834 Log.e(TAG, "WakeLock expired before release in "
835 + "handleDownloadXtraData()");
Wei Wangc5706f62017-04-18 11:26:26 -0700836 }
Jeff Brown028872f2012-08-25 13:07:01 -0700837 }
Kevin Tang40e1baf2012-01-10 14:32:44 -0800838 });
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800839 }
840
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400841 private void handleUpdateLocation(Location location) {
Mike Lockwoodd26ce0d2009-06-11 12:25:46 -0400842 if (location.hasAccuracy()) {
843 native_inject_location(location.getLatitude(), location.getLongitude(),
844 location.getAccuracy());
845 }
Mike Lockwoodfd6e5f02009-05-21 11:28:20 -0400846 }
847
Anil Admald71cf142018-12-21 14:59:36 -0800848 private void setSuplHostPort() {
849 mSuplServerHost = mGnssConfiguration.getSuplHost();
850 mSuplServerPort = mGnssConfiguration.getSuplPort(TCP_MIN_PORT);
Tsuwei Chen678c13c2014-09-22 17:48:41 -0700851 if (mSuplServerHost != null
852 && mSuplServerPort > TCP_MIN_PORT
853 && mSuplServerPort <= TCP_MAX_PORT) {
Anil Admalc70344b2018-11-16 14:22:38 -0800854 native_set_agps_server(GnssNetworkConnectivityHandler.AGPS_TYPE_SUPL,
855 mSuplServerHost, mSuplServerPort);
Tsuwei Chen678c13c2014-09-22 17:48:41 -0700856 }
Tsuwei Chen52617bb2014-08-25 11:49:11 -0700857 }
858
Tsuwei Chen462bcd82014-09-17 12:28:49 -0700859 /**
860 * Checks what SUPL mode to use, according to the AGPS mode as well as the
861 * allowed mode from properties.
862 *
Tsuwei Chen462bcd82014-09-17 12:28:49 -0700863 * @param agpsEnabled whether AGPS is enabled by settings value
Tsuwei Chen462bcd82014-09-17 12:28:49 -0700864 * @return SUPL mode (MSA vs MSB vs STANDALONE)
865 */
Yu-Han Yang6a5f0b72019-01-24 18:34:28 -0800866 private int getSuplMode(boolean agpsEnabled) {
Tsuwei Chen462bcd82014-09-17 12:28:49 -0700867 if (agpsEnabled) {
Anil Admald71cf142018-12-21 14:59:36 -0800868 int suplMode = mGnssConfiguration.getSuplMode(0);
869 if (suplMode == 0) {
870 return GPS_POSITION_MODE_STANDALONE;
Tsuwei Chen462bcd82014-09-17 12:28:49 -0700871 }
Anil Admald71cf142018-12-21 14:59:36 -0800872
destradaabfb3bdb2015-04-29 14:42:35 -0700873 // MS-Based is the preferred mode for Assisted-GPS position computation, so we favor
874 // such mode when it is available
875 if (hasCapability(GPS_CAPABILITY_MSB) && (suplMode & AGPS_SUPL_MODE_MSB) != 0) {
876 return GPS_POSITION_MODE_MS_BASED;
877 }
Tsuwei Chen462bcd82014-09-17 12:28:49 -0700878 }
879 return GPS_POSITION_MODE_STANDALONE;
880 }
881
Soonil Nagarkar35c3b912019-01-31 10:31:24 -0800882 private boolean handleEnable() {
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400883 if (DEBUG) Log.d(TAG, "handleEnable");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800884
Soonil Nagarkar35c3b912019-01-31 10:31:24 -0800885 boolean inited = native_init();
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700886
Soonil Nagarkar35c3b912019-01-31 10:31:24 -0800887 if (inited) {
Mike Lockwood1a1cd3a2010-08-17 07:42:54 -0400888 mSupportsXtra = native_supports_xtra();
Tsuwei Chen678c13c2014-09-22 17:48:41 -0700889
890 // TODO: remove the following native calls if we can make sure they are redundant.
Mike Lockwood734d6032009-07-28 18:30:25 -0700891 if (mSuplServerHost != null) {
Anil Admalc70344b2018-11-16 14:22:38 -0800892 native_set_agps_server(GnssNetworkConnectivityHandler.AGPS_TYPE_SUPL,
893 mSuplServerHost, mSuplServerPort);
Mike Lockwood734d6032009-07-28 18:30:25 -0700894 }
895 if (mC2KServerHost != null) {
Anil Admalc70344b2018-11-16 14:22:38 -0800896 native_set_agps_server(GnssNetworkConnectivityHandler.AGPS_TYPE_C2K,
897 mC2KServerHost, mC2KServerPort);
Mike Lockwood734d6032009-07-28 18:30:25 -0700898 }
destradaa13a60b02015-01-15 18:36:01 -0800899
Lifu Tang818aa2c2016-02-01 01:52:00 -0800900 mGnssMeasurementsProvider.onGpsEnabledChanged();
901 mGnssNavigationMessageProvider.onGpsEnabledChanged();
Yu-Han Yang3557cc72018-03-21 12:48:36 -0700902 mGnssBatchingProvider.enable();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800903 } else {
904 Log.w(TAG, "Failed to enable location provider");
905 }
Soonil Nagarkar35c3b912019-01-31 10:31:24 -0800906
907 return inited;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800908 }
909
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400910 private void handleDisable() {
Mike Lockwood89096312010-03-24 10:14:55 -0400911 if (DEBUG) Log.d(TAG, "handleDisable");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800912
David Christie3bc26142013-12-19 14:53:44 -0800913 updateClientUids(new WorkSource());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800914 stopNavigating();
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700915 mAlarmManager.cancel(mWakeupIntent);
916 mAlarmManager.cancel(mTimeoutIntent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800917
Yu-Han Yang3557cc72018-03-21 12:48:36 -0700918 mGnssBatchingProvider.disable();
Mike Lockwoodcf1d8cb2010-01-20 10:14:54 -0500919 // do this before releasing wakelock
920 native_cleanup();
destradaa13a60b02015-01-15 18:36:01 -0800921
Lifu Tang818aa2c2016-02-01 01:52:00 -0800922 mGnssMeasurementsProvider.onGpsEnabledChanged();
923 mGnssNavigationMessageProvider.onGpsEnabledChanged();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800924 }
925
Soonil Nagarkar35c3b912019-01-31 10:31:24 -0800926 private void updateEnabled() {
927 synchronized (mLock) {
928 boolean enabled =
929 ((mProviderRequest != null && mProviderRequest.reportLocation
Soonil Nagarkar509580f2019-02-06 15:57:26 -0800930 && mProviderRequest.locationSettingsIgnored) || (
Soonil Nagarkar35c3b912019-01-31 10:31:24 -0800931 mContext.getSystemService(LocationManager.class).isLocationEnabled()
932 && !mDisableGps)) && !mShutdown;
933 if (enabled == mEnabled) {
934 return;
935 }
936
937 if (enabled) {
938 mEnabled = handleEnable();
939 } else {
940 mEnabled = false;
941 handleDisable();
942 }
943 }
944 }
945
Mike Lockwoodd03ff942010-02-09 08:46:14 -0500946 public boolean isEnabled() {
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700947 synchronized (mLock) {
948 return mEnabled;
949 }
Mike Lockwoodd03ff942010-02-09 08:46:14 -0500950 }
951
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700952 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800953 public int getStatus(Bundle extras) {
Wyatt Rileyc7067412018-02-07 15:50:35 -0800954 mLocationExtras.setBundle(extras);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800955 return mStatus;
956 }
957
Wyatt Rileyc7067412018-02-07 15:50:35 -0800958 private void updateStatus(int status) {
959 if (status != mStatus) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800960 mStatus = status;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800961 mStatusUpdateTime = SystemClock.elapsedRealtime();
962 }
963 }
964
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700965 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800966 public long getStatusUpdateTime() {
967 return mStatusUpdateTime;
968 }
969
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700970 @Override
971 public void setRequest(ProviderRequest request, WorkSource source) {
972 sendMessage(SET_REQUEST, 0, new GpsRequest(request, source));
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400973 }
974
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700975 private void handleSetRequest(ProviderRequest request, WorkSource source) {
David Christied4edf4c2014-08-12 15:22:27 -0700976 mProviderRequest = request;
977 mWorkSource = source;
Soonil Nagarkar35c3b912019-01-31 10:31:24 -0800978 updateEnabled();
David Christied4edf4c2014-08-12 15:22:27 -0700979 updateRequirements();
980 }
981
982 // Called when the requirements for GPS may have changed
983 private void updateRequirements() {
984 if (mProviderRequest == null || mWorkSource == null) {
985 return;
986 }
987
David Christied4edf4c2014-08-12 15:22:27 -0700988 if (DEBUG) Log.d(TAG, "setRequest " + mProviderRequest);
Soonil Nagarkar41153fd2019-02-12 15:02:37 -0800989 if (mProviderRequest.reportLocation && isEnabled()) {
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700990 // update client uids
David Christied4edf4c2014-08-12 15:22:27 -0700991 updateClientUids(mWorkSource);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800992
David Christied4edf4c2014-08-12 15:22:27 -0700993 mFixInterval = (int) mProviderRequest.interval;
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700994 mLowPowerMode = mProviderRequest.lowPowerMode;
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700995 // check for overflow
David Christied4edf4c2014-08-12 15:22:27 -0700996 if (mFixInterval != mProviderRequest.interval) {
997 Log.w(TAG, "interval overflow: " + mProviderRequest.interval);
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700998 mFixInterval = Integer.MAX_VALUE;
999 }
Mike Lockwood03ca2162010-04-01 08:10:09 -07001000
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001001 // apply request to GPS engine
Mike Lockwood04598b62010-04-14 17:17:24 -04001002 if (mStarted && hasCapability(GPS_CAPABILITY_SCHEDULING)) {
gomo48f1a642017-11-10 20:35:46 -08001003 // change period and/or lowPowerMode
Yu-Han Yangc8b9ff72018-04-17 00:47:24 -07001004 if (!setPositionMode(mPositionMode, GPS_POSITION_RECURRENCE_PERIODIC,
gomo48f1a642017-11-10 20:35:46 -08001005 mFixInterval, 0, 0, mLowPowerMode)) {
1006 Log.e(TAG, "set_position_mode failed in updateRequirements");
Mike Lockwood04598b62010-04-14 17:17:24 -04001007 }
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001008 } else if (!mStarted) {
1009 // start GPS
Yu-Han Yang6a5f0b72019-01-24 18:34:28 -08001010 startNavigating();
gomo300b2402017-12-13 19:04:12 -08001011 } else {
1012 // GNSS Engine is already ON, but no GPS_CAPABILITY_SCHEDULING
1013 mAlarmManager.cancel(mTimeoutIntent);
1014 if (mFixInterval >= NO_FIX_TIMEOUT) {
1015 // set timer to give up if we do not receive a fix within NO_FIX_TIMEOUT
1016 // and our fix interval is not short
1017 mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001018 SystemClock.elapsedRealtime() + NO_FIX_TIMEOUT, mTimeoutIntent);
1019 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001020 }
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001021 } else {
Dianne Hackborn002a54e2013-01-10 17:34:55 -08001022 updateClientUids(new WorkSource());
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001023
1024 stopNavigating();
1025 mAlarmManager.cancel(mWakeupIntent);
1026 mAlarmManager.cancel(mTimeoutIntent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001027 }
1028 }
1029
Yu-Han Yangc8b9ff72018-04-17 00:47:24 -07001030 private boolean setPositionMode(int mode, int recurrence, int minInterval,
1031 int preferredAccuracy, int preferredTime, boolean lowPowerMode) {
1032 GnssPositionMode positionMode = new GnssPositionMode(mode, recurrence, minInterval,
1033 preferredAccuracy, preferredTime, lowPowerMode);
1034 if (mLastPositionMode != null && mLastPositionMode.equals(positionMode)) {
1035 return true;
1036 }
1037
1038 boolean result = native_set_position_mode(mode, recurrence, minInterval,
1039 preferredAccuracy, preferredTime, lowPowerMode);
1040 if (result) {
1041 mLastPositionMode = positionMode;
1042 } else {
1043 mLastPositionMode = null;
1044 }
1045 return result;
1046 }
1047
Dianne Hackborn002a54e2013-01-10 17:34:55 -08001048 private void updateClientUids(WorkSource source) {
Narayan Kamath32684dd2018-01-08 17:32:51 +00001049 if (source.equals(mClientSource)) {
Victoria Leaseea78b852013-01-15 10:39:28 -08001050 return;
1051 }
Dianne Hackborn002a54e2013-01-10 17:34:55 -08001052
Narayan Kamath32684dd2018-01-08 17:32:51 +00001053 // (1) Inform BatteryStats that the list of IDs we're tracking changed.
1054 try {
1055 mBatteryStats.noteGpsChanged(mClientSource, source);
1056 } catch (RemoteException e) {
1057 Log.w(TAG, "RemoteException", e);
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001058 }
1059
Narayan Kamath32684dd2018-01-08 17:32:51 +00001060 // (2) Inform AppOps service about the list of changes to UIDs.
1061
1062 List<WorkChain>[] diffs = WorkSource.diffChains(mClientSource, source);
1063 if (diffs != null) {
1064 List<WorkChain> newChains = diffs[0];
1065 List<WorkChain> goneChains = diffs[1];
1066
1067 if (newChains != null) {
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001068 for (WorkChain newChain : newChains) {
Svet Ganovf7b47252018-02-26 11:11:27 -08001069 mAppOps.startOpNoThrow(AppOpsManager.OP_GPS, newChain.getAttributionUid(),
1070 newChain.getAttributionTag());
Narayan Kamath32684dd2018-01-08 17:32:51 +00001071 }
1072 }
1073
1074 if (goneChains != null) {
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001075 for (WorkChain goneChain : goneChains) {
Svet Ganovf7b47252018-02-26 11:11:27 -08001076 mAppOps.finishOp(AppOpsManager.OP_GPS, goneChain.getAttributionUid(),
1077 goneChain.getAttributionTag());
Narayan Kamath32684dd2018-01-08 17:32:51 +00001078 }
1079 }
1080
1081 mClientSource.transferWorkChains(source);
1082 }
1083
1084 // Update the flat UIDs and names list and inform app-ops of all changes.
1085 WorkSource[] changes = mClientSource.setReturningDiffs(source);
1086 if (changes != null) {
1087 WorkSource newWork = changes[0];
1088 WorkSource goneWork = changes[1];
1089
1090 // Update sources that were not previously tracked.
1091 if (newWork != null) {
1092 for (int i = 0; i < newWork.size(); i++) {
Svet Ganovf7b47252018-02-26 11:11:27 -08001093 mAppOps.startOpNoThrow(AppOpsManager.OP_GPS,
1094 newWork.get(i), newWork.getName(i));
Narayan Kamath32684dd2018-01-08 17:32:51 +00001095 }
1096 }
1097
1098 // Update sources that are no longer tracked.
1099 if (goneWork != null) {
1100 for (int i = 0; i < goneWork.size(); i++) {
Svet Ganovf7b47252018-02-26 11:11:27 -08001101 mAppOps.finishOp(AppOpsManager.OP_GPS, goneWork.get(i), goneWork.getName(i));
Dianne Hackborn2e418422009-06-22 20:00:17 -07001102 }
Mike Lockwood2f82c4e2009-04-17 08:24:10 -04001103 }
1104 }
1105 }
1106
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001107 @Override
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001108 public void sendExtraCommand(String command, Bundle extras) {
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001109
Mike Lockwood63aa5a62010-04-14 19:21:31 -04001110 long identity = Binder.clearCallingIdentity();
Peter Visontayb25db362017-11-01 18:18:12 +00001111 try {
Peter Visontayb25db362017-11-01 18:18:12 +00001112 if ("delete_aiding_data".equals(command)) {
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001113 deleteAidingData(extras);
Peter Visontayb25db362017-11-01 18:18:12 +00001114 } else if ("force_time_injection".equals(command)) {
1115 requestUtcTime();
Peter Visontayb25db362017-11-01 18:18:12 +00001116 } else if ("force_xtra_injection".equals(command)) {
1117 if (mSupportsXtra) {
1118 xtraDownloadRequest();
Peter Visontayb25db362017-11-01 18:18:12 +00001119 }
1120 } else {
1121 Log.w(TAG, "sendExtraCommand: unknown command " + command);
Mike Lockwood93bc44d2009-05-20 16:58:22 -04001122 }
Peter Visontayb25db362017-11-01 18:18:12 +00001123 } finally {
1124 Binder.restoreCallingIdentity(identity);
Mike Lockwood93bc44d2009-05-20 16:58:22 -04001125 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001126 }
1127
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001128 private void deleteAidingData(Bundle extras) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001129 int flags;
1130
1131 if (extras == null) {
1132 flags = GPS_DELETE_ALL;
1133 } else {
1134 flags = 0;
1135 if (extras.getBoolean("ephemeris")) flags |= GPS_DELETE_EPHEMERIS;
1136 if (extras.getBoolean("almanac")) flags |= GPS_DELETE_ALMANAC;
1137 if (extras.getBoolean("position")) flags |= GPS_DELETE_POSITION;
1138 if (extras.getBoolean("time")) flags |= GPS_DELETE_TIME;
1139 if (extras.getBoolean("iono")) flags |= GPS_DELETE_IONO;
1140 if (extras.getBoolean("utc")) flags |= GPS_DELETE_UTC;
1141 if (extras.getBoolean("health")) flags |= GPS_DELETE_HEALTH;
1142 if (extras.getBoolean("svdir")) flags |= GPS_DELETE_SVDIR;
1143 if (extras.getBoolean("svsteer")) flags |= GPS_DELETE_SVSTEER;
1144 if (extras.getBoolean("sadata")) flags |= GPS_DELETE_SADATA;
1145 if (extras.getBoolean("rti")) flags |= GPS_DELETE_RTI;
1146 if (extras.getBoolean("celldb-info")) flags |= GPS_DELETE_CELLDB_INFO;
1147 if (extras.getBoolean("all")) flags |= GPS_DELETE_ALL;
1148 }
1149
1150 if (flags != 0) {
1151 native_delete_aiding_data(flags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001152 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001153 }
1154
Yu-Han Yang6a5f0b72019-01-24 18:34:28 -08001155 private void startNavigating() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001156 if (!mStarted) {
Yu-Han Yang6a5f0b72019-01-24 18:34:28 -08001157 if (DEBUG) Log.d(TAG, "startNavigating");
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001158 mTimeToFirstFix = 0;
1159 mLastFixTime = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001160 mStarted = true;
Mike Lockwood03ca2162010-04-01 08:10:09 -07001161 mPositionMode = GPS_POSITION_MODE_STANDALONE;
Wyatt Riley5d5bac82016-11-01 07:05:16 -07001162 // Notify about suppressed output, if speed limit was previously exceeded.
1163 // Elsewhere, we check again with every speed output reported.
1164 if (mItarSpeedLimitExceeded) {
1165 Log.i(TAG, "startNavigating with ITAR limit in place. Output limited " +
1166 "until slow enough speed reported.");
1167 }
Mike Lockwood03ca2162010-04-01 08:10:09 -07001168
Tsuwei Chen462bcd82014-09-17 12:28:49 -07001169 boolean agpsEnabled =
1170 (Settings.Global.getInt(mContext.getContentResolver(),
gomo48f1a642017-11-10 20:35:46 -08001171 Settings.Global.ASSISTED_GPS_ENABLED, 1) != 0);
Yu-Han Yang6a5f0b72019-01-24 18:34:28 -08001172 mPositionMode = getSuplMode(agpsEnabled);
Mike Lockwoodbcab8df2009-06-25 16:39:09 -04001173
Stan Chesnutt1d72d8c2013-04-15 19:18:02 -07001174 if (DEBUG) {
1175 String mode;
1176
gomo48f1a642017-11-10 20:35:46 -08001177 switch (mPositionMode) {
Stan Chesnutt1d72d8c2013-04-15 19:18:02 -07001178 case GPS_POSITION_MODE_STANDALONE:
1179 mode = "standalone";
1180 break;
1181 case GPS_POSITION_MODE_MS_ASSISTED:
1182 mode = "MS_ASSISTED";
1183 break;
1184 case GPS_POSITION_MODE_MS_BASED:
1185 mode = "MS_BASED";
1186 break;
1187 default:
1188 mode = "unknown";
1189 break;
1190 }
1191 Log.d(TAG, "setting position_mode to " + mode);
1192 }
1193
Mike Lockwood04598b62010-04-14 17:17:24 -04001194 int interval = (hasCapability(GPS_CAPABILITY_SCHEDULING) ? mFixInterval : 1000);
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001195 mLowPowerMode = mProviderRequest.lowPowerMode;
Yu-Han Yangc8b9ff72018-04-17 00:47:24 -07001196 if (!setPositionMode(mPositionMode, GPS_POSITION_RECURRENCE_PERIODIC,
gomo48f1a642017-11-10 20:35:46 -08001197 interval, 0, 0, mLowPowerMode)) {
Mike Lockwood04598b62010-04-14 17:17:24 -04001198 mStarted = false;
1199 Log.e(TAG, "set_position_mode failed in startNavigating()");
1200 return;
1201 }
1202 if (!native_start()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001203 mStarted = false;
1204 Log.e(TAG, "native_start failed in startNavigating()");
Mike Lockwood0632ca72009-05-14 15:51:03 -04001205 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001206 }
1207
1208 // reset SV count to zero
Wyatt Rileyc7067412018-02-07 15:50:35 -08001209 updateStatus(LocationProvider.TEMPORARILY_UNAVAILABLE);
1210 mLocationExtras.reset();
Yipeng Cao282b5942017-05-17 20:31:39 -07001211 mFixRequestTime = SystemClock.elapsedRealtime();
Mike Lockwood04598b62010-04-14 17:17:24 -04001212 if (!hasCapability(GPS_CAPABILITY_SCHEDULING)) {
1213 // set timer to give up if we do not receive a fix within NO_FIX_TIMEOUT
1214 // and our fix interval is not short
1215 if (mFixInterval >= NO_FIX_TIMEOUT) {
1216 mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
1217 SystemClock.elapsedRealtime() + NO_FIX_TIMEOUT, mTimeoutIntent);
1218 }
Mike Lockwood0632ca72009-05-14 15:51:03 -04001219 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001220 }
1221 }
1222
Mike Lockwood62a8fc12010-03-22 14:23:26 -04001223 private void stopNavigating() {
Mike Lockwood29c84342009-05-06 14:01:15 -04001224 if (DEBUG) Log.d(TAG, "stopNavigating");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001225 if (mStarted) {
1226 mStarted = false;
1227 native_stop();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001228 mLastFixTime = 0;
Yu-Han Yanga50cd602018-08-28 12:33:24 -07001229 // native_stop() may reset the position mode in hardware.
1230 mLastPositionMode = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001231
1232 // reset SV count to zero
Wyatt Rileyc7067412018-02-07 15:50:35 -08001233 updateStatus(LocationProvider.TEMPORARILY_UNAVAILABLE);
1234 mLocationExtras.reset();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001235 }
1236 }
1237
Mike Lockwood0632ca72009-05-14 15:51:03 -04001238 private void hibernate() {
1239 // stop GPS until our next fix interval arrives
1240 stopNavigating();
Mike Lockwood0632ca72009-05-14 15:51:03 -04001241 mAlarmManager.cancel(mTimeoutIntent);
1242 mAlarmManager.cancel(mWakeupIntent);
1243 long now = SystemClock.elapsedRealtime();
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001244 mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, now + mFixInterval, mWakeupIntent);
Mike Lockwood04598b62010-04-14 17:17:24 -04001245 }
1246
1247 private boolean hasCapability(int capability) {
1248 return ((mEngineCapabilities & capability) != 0);
Mike Lockwood0632ca72009-05-14 15:51:03 -04001249 }
1250
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001251 @NativeEntryPoint
Wyatt Riley5d229832017-02-10 17:06:00 -08001252 private void reportLocation(boolean hasLatLong, Location location) {
Wyatt Riley26465d22018-02-12 13:44:24 -08001253 sendMessage(REPORT_LOCATION, hasLatLong ? 1 : 0, location);
1254 }
1255
1256 private void handleReportLocation(boolean hasLatLong, Location location) {
Wyatt Riley5d229832017-02-10 17:06:00 -08001257 if (location.hasSpeed()) {
1258 mItarSpeedLimitExceeded = location.getSpeed() > ITAR_SPEED_LIMIT_METERS_PER_SECOND;
Wyatt Riley5d5bac82016-11-01 07:05:16 -07001259 }
1260
1261 if (mItarSpeedLimitExceeded) {
1262 Log.i(TAG, "Hal reported a speed in excess of ITAR limit." +
1263 " GPS/GNSS Navigation output blocked.");
Siddharth Ray53ddc802018-03-16 12:01:52 -07001264 if (mStarted) {
1265 mGnssMetrics.logReceivedLocationStatus(false);
1266 }
Wyatt Riley5d5bac82016-11-01 07:05:16 -07001267 return; // No output of location allowed
1268 }
1269
Wyatt Riley5d229832017-02-10 17:06:00 -08001270 if (VERBOSE) Log.v(TAG, "reportLocation " + location.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001271
Wyatt Riley26465d22018-02-12 13:44:24 -08001272 location.setExtras(mLocationExtras.getBundle());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001273
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001274 reportLocation(location);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001275
Siddharth Ray53ddc802018-03-16 12:01:52 -07001276 if (mStarted) {
1277 mGnssMetrics.logReceivedLocationStatus(hasLatLong);
1278 if (hasLatLong) {
1279 if (location.hasAccuracy()) {
1280 mGnssMetrics.logPositionAccuracyMeters(location.getAccuracy());
1281 }
1282 if (mTimeToFirstFix > 0) {
1283 int timeBetweenFixes = (int) (SystemClock.elapsedRealtime() - mLastFixTime);
1284 mGnssMetrics.logMissedReports(mFixInterval, timeBetweenFixes);
1285 }
Siddharth Raybb608c82017-03-16 11:33:34 -07001286 }
1287 }
1288
Yipeng Cao282b5942017-05-17 20:31:39 -07001289 mLastFixTime = SystemClock.elapsedRealtime();
Hakan Gustavssonfa94ff02010-02-23 09:12:38 +01001290 // report time to first fix
Wyatt Riley5d229832017-02-10 17:06:00 -08001291 if (mTimeToFirstFix == 0 && hasLatLong) {
gomo48f1a642017-11-10 20:35:46 -08001292 mTimeToFirstFix = (int) (mLastFixTime - mFixRequestTime);
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001293 if (DEBUG) Log.d(TAG, "TTFF: " + mTimeToFirstFix);
Siddharth Ray53ddc802018-03-16 12:01:52 -07001294 if (mStarted) {
1295 mGnssMetrics.logTimeToFirstFixMilliSecs(mTimeToFirstFix);
1296 }
Hakan Gustavssonfa94ff02010-02-23 09:12:38 +01001297
1298 // notify status listeners
Anil Admal75b9fd62018-11-28 11:22:50 -08001299 mGnssStatusListenerHelper.onFirstFix(mTimeToFirstFix);
Hakan Gustavssonfa94ff02010-02-23 09:12:38 +01001300 }
1301
Mike Lockwood15e3d0f2009-05-01 07:53:28 -04001302 if (mStarted && mStatus != LocationProvider.AVAILABLE) {
Wyatt Rileyc7067412018-02-07 15:50:35 -08001303 // For devices that use framework scheduling, a timer may be set to ensure we don't
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001304 // spend too much power searching for a location, when the requested update rate is
1305 // slow.
Wyatt Rileyc7067412018-02-07 15:50:35 -08001306 // As we just recievied a location, we'll cancel that timer.
Mike Lockwood04598b62010-04-14 17:17:24 -04001307 if (!hasCapability(GPS_CAPABILITY_SCHEDULING) && mFixInterval < NO_FIX_TIMEOUT) {
Mike Lockwoodb7be5442010-02-24 14:34:50 -05001308 mAlarmManager.cancel(mTimeoutIntent);
1309 }
1310
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001311 // send an intent to notify that the GPS is receiving fixes.
Mike Lockwood00b74272010-03-26 10:41:48 -04001312 Intent intent = new Intent(LocationManager.GPS_FIX_CHANGE_ACTION);
1313 intent.putExtra(LocationManager.EXTRA_GPS_ENABLED, true);
Dianne Hackborn5ac72a22012-08-29 18:32:08 -07001314 mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
Wyatt Rileyc7067412018-02-07 15:50:35 -08001315 updateStatus(LocationProvider.AVAILABLE);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001316 }
Mike Lockwood29c84342009-05-06 14:01:15 -04001317
gomo48f1a642017-11-10 20:35:46 -08001318 if (!hasCapability(GPS_CAPABILITY_SCHEDULING) && mStarted &&
1319 mFixInterval > GPS_POLLING_THRESHOLD_INTERVAL) {
Mike Lockwoodd53ba012010-04-15 20:41:26 -04001320 if (DEBUG) Log.d(TAG, "got fix, hibernating");
Mike Lockwood0632ca72009-05-14 15:51:03 -04001321 hibernate();
Mike Lockwood29c84342009-05-06 14:01:15 -04001322 }
gomo48f1a642017-11-10 20:35:46 -08001323 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001324
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001325 @NativeEntryPoint
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001326 private void reportStatus(int status) {
Mike Lockwoodb8d90332010-10-18 17:59:48 -04001327 if (DEBUG) Log.v(TAG, "reportStatus status: " + status);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001328
destradaaea8a8a62014-06-23 18:19:03 -07001329 boolean wasNavigating = mNavigating;
1330 switch (status) {
1331 case GPS_STATUS_SESSION_BEGIN:
1332 mNavigating = true;
destradaaea8a8a62014-06-23 18:19:03 -07001333 break;
1334 case GPS_STATUS_SESSION_END:
1335 mNavigating = false;
1336 break;
1337 case GPS_STATUS_ENGINE_ON:
destradaaea8a8a62014-06-23 18:19:03 -07001338 break;
1339 case GPS_STATUS_ENGINE_OFF:
destradaaea8a8a62014-06-23 18:19:03 -07001340 mNavigating = false;
1341 break;
1342 }
Mike Lockwooddbd6fd82009-12-07 18:43:36 -05001343
destradaaea8a8a62014-06-23 18:19:03 -07001344 if (wasNavigating != mNavigating) {
Anil Admal75b9fd62018-11-28 11:22:50 -08001345 mGnssStatusListenerHelper.onStatusChanged(mNavigating);
Mike Lockwoodcf1d8cb2010-01-20 10:14:54 -05001346
destradaaea8a8a62014-06-23 18:19:03 -07001347 // send an intent to notify that the GPS has been enabled or disabled
1348 Intent intent = new Intent(LocationManager.GPS_ENABLED_CHANGE_ACTION);
1349 intent.putExtra(LocationManager.EXTRA_GPS_ENABLED, mNavigating);
1350 mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001351 }
1352 }
1353
Wyatt Riley26465d22018-02-12 13:44:24 -08001354 // Helper class to carry data to handler for reportSvStatus
1355 private static class SvStatusInfo {
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001356 private int mSvCount;
1357 private int[] mSvidWithFlags;
1358 private float[] mCn0s;
1359 private float[] mSvElevations;
1360 private float[] mSvAzimuths;
1361 private float[] mSvCarrierFreqs;
Wyatt Riley26465d22018-02-12 13:44:24 -08001362 }
1363
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001364 @NativeEntryPoint
Wyatt Riley26465d22018-02-12 13:44:24 -08001365 private void reportSvStatus(int svCount, int[] svidWithFlags, float[] cn0s,
1366 float[] svElevations, float[] svAzimuths, float[] svCarrierFreqs) {
1367 SvStatusInfo svStatusInfo = new SvStatusInfo();
1368 svStatusInfo.mSvCount = svCount;
1369 svStatusInfo.mSvidWithFlags = svidWithFlags;
1370 svStatusInfo.mCn0s = cn0s;
1371 svStatusInfo.mSvElevations = svElevations;
1372 svStatusInfo.mSvAzimuths = svAzimuths;
1373 svStatusInfo.mSvCarrierFreqs = svCarrierFreqs;
1374
1375 sendMessage(REPORT_SV_STATUS, 0, svStatusInfo);
1376 }
1377
1378 private void handleReportSvStatus(SvStatusInfo info) {
Anil Admal75b9fd62018-11-28 11:22:50 -08001379 mGnssStatusListenerHelper.onSvStatusChanged(
Wyatt Riley26465d22018-02-12 13:44:24 -08001380 info.mSvCount,
1381 info.mSvidWithFlags,
1382 info.mCn0s,
1383 info.mSvElevations,
1384 info.mSvAzimuths,
1385 info.mSvCarrierFreqs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001386
Siddharth Ray168f12a2017-07-10 11:55:10 -07001387 // Log CN0 as part of GNSS metrics
Wyatt Riley26465d22018-02-12 13:44:24 -08001388 mGnssMetrics.logCn0(info.mCn0s, info.mSvCount);
Siddharth Ray168f12a2017-07-10 11:55:10 -07001389
Mike Lockwood29c84342009-05-06 14:01:15 -04001390 if (VERBOSE) {
Wyatt Riley26465d22018-02-12 13:44:24 -08001391 Log.v(TAG, "SV count: " + info.mSvCount);
Lifu Tang30f95a72016-01-07 23:20:38 -08001392 }
Wyatt Rileyc9f25dd2017-05-05 13:45:23 -07001393 // Calculate number of satellites used in fix.
Lifu Tang30f95a72016-01-07 23:20:38 -08001394 int usedInFixCount = 0;
Wyatt Rileyc9f25dd2017-05-05 13:45:23 -07001395 int maxCn0 = 0;
1396 int meanCn0 = 0;
Wyatt Riley26465d22018-02-12 13:44:24 -08001397 for (int i = 0; i < info.mSvCount; i++) {
1398 if ((info.mSvidWithFlags[i] & GnssStatus.GNSS_SV_FLAGS_USED_IN_FIX) != 0) {
Lifu Tang30f95a72016-01-07 23:20:38 -08001399 ++usedInFixCount;
Wyatt Riley26465d22018-02-12 13:44:24 -08001400 if (info.mCn0s[i] > maxCn0) {
1401 maxCn0 = (int) info.mCn0s[i];
Wyatt Rileyc9f25dd2017-05-05 13:45:23 -07001402 }
Wyatt Riley26465d22018-02-12 13:44:24 -08001403 meanCn0 += info.mCn0s[i];
Lifu Tang30f95a72016-01-07 23:20:38 -08001404 }
1405 if (VERBOSE) {
Wyatt Riley26465d22018-02-12 13:44:24 -08001406 Log.v(TAG, "svid: " + (info.mSvidWithFlags[i] >> GnssStatus.SVID_SHIFT_WIDTH) +
1407 " cn0: " + info.mCn0s[i] +
1408 " elev: " + info.mSvElevations[i] +
1409 " azimuth: " + info.mSvAzimuths[i] +
1410 " carrier frequency: " + info.mSvCarrierFreqs[i] +
1411 ((info.mSvidWithFlags[i] & GnssStatus.GNSS_SV_FLAGS_HAS_EPHEMERIS_DATA) == 0
Lifu Tang30f95a72016-01-07 23:20:38 -08001412 ? " " : " E") +
Wyatt Riley26465d22018-02-12 13:44:24 -08001413 ((info.mSvidWithFlags[i] & GnssStatus.GNSS_SV_FLAGS_HAS_ALMANAC_DATA) == 0
Lifu Tang30f95a72016-01-07 23:20:38 -08001414 ? " " : " A") +
Wyatt Riley26465d22018-02-12 13:44:24 -08001415 ((info.mSvidWithFlags[i] & GnssStatus.GNSS_SV_FLAGS_USED_IN_FIX) == 0
gomo4402af62017-01-11 13:20:13 -08001416 ? "" : "U") +
Wyatt Riley26465d22018-02-12 13:44:24 -08001417 ((info.mSvidWithFlags[i] &
1418 GnssStatus.GNSS_SV_FLAGS_HAS_CARRIER_FREQUENCY) == 0
gomo48f1a642017-11-10 20:35:46 -08001419 ? "" : "F"));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001420 }
1421 }
Wyatt Rileyc9f25dd2017-05-05 13:45:23 -07001422 if (usedInFixCount > 0) {
1423 meanCn0 /= usedInFixCount;
1424 }
1425 // return number of sats used in fix instead of total reported
Wyatt Rileyc7067412018-02-07 15:50:35 -08001426 mLocationExtras.set(usedInFixCount, meanCn0, maxCn0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001427
Mike Lockwood15e3d0f2009-05-01 07:53:28 -04001428 if (mNavigating && mStatus == LocationProvider.AVAILABLE && mLastFixTime > 0 &&
gomo48f1a642017-11-10 20:35:46 -08001429 SystemClock.elapsedRealtime() - mLastFixTime > RECENT_FIX_TIMEOUT) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001430 // send an intent to notify that the GPS is no longer receiving fixes.
Mike Lockwood00b74272010-03-26 10:41:48 -04001431 Intent intent = new Intent(LocationManager.GPS_FIX_CHANGE_ACTION);
1432 intent.putExtra(LocationManager.EXTRA_GPS_ENABLED, false);
Dianne Hackborn5ac72a22012-08-29 18:32:08 -07001433 mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
Wyatt Rileyc7067412018-02-07 15:50:35 -08001434 updateStatus(LocationProvider.TEMPORARILY_UNAVAILABLE);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001435 }
1436 }
Mike Lockwood58bda982009-04-14 16:25:07 -04001437
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001438 @NativeEntryPoint
Anil Admalc70344b2018-11-16 14:22:38 -08001439 private void reportAGpsStatus(int agpsType, int agpsStatus, byte[] suplIpAddr) {
1440 mNetworkConnectivityHandler.onReportAGpsStatus(agpsType, agpsStatus, suplIpAddr);
destradaae21252a2015-09-08 12:32:59 -07001441 }
1442
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001443 @NativeEntryPoint
Mike Lockwoodf602d362010-06-20 14:28:16 -07001444 private void reportNmea(long timestamp) {
Wyatt Riley5d5bac82016-11-01 07:05:16 -07001445 if (!mItarSpeedLimitExceeded) {
1446 int length = native_read_nmea(mNmeaBuffer, mNmeaBuffer.length);
1447 String nmea = new String(mNmeaBuffer, 0 /* offset */, length);
Anil Admal75b9fd62018-11-28 11:22:50 -08001448 mGnssStatusListenerHelper.onNmeaReceived(timestamp, nmea);
Wyatt Riley5d5bac82016-11-01 07:05:16 -07001449 }
destradaaea8a8a62014-06-23 18:19:03 -07001450 }
Mike Lockwoodb16e7802009-08-06 09:26:02 -04001451
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001452 @NativeEntryPoint
Lifu Tang818aa2c2016-02-01 01:52:00 -08001453 private void reportMeasurementData(GnssMeasurementsEvent event) {
Wyatt Riley5d5bac82016-11-01 07:05:16 -07001454 if (!mItarSpeedLimitExceeded) {
Wyatt Rileyaa420d52017-07-03 15:14:42 -07001455 // send to handler to allow native to return quickly
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001456 mHandler.post(() -> mGnssMeasurementsProvider.onMeasurementsAvailable(event));
Wyatt Riley5d5bac82016-11-01 07:05:16 -07001457 }
Mike Lockwoodb16e7802009-08-06 09:26:02 -04001458 }
1459
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001460 @NativeEntryPoint
Lifu Tange8abe8e2016-04-01 10:32:05 -07001461 private void reportNavigationMessage(GnssNavigationMessage event) {
Wyatt Riley5d5bac82016-11-01 07:05:16 -07001462 if (!mItarSpeedLimitExceeded) {
Wyatt Rileyaa420d52017-07-03 15:14:42 -07001463 // send to handler to allow native to return quickly
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001464 mHandler.post(() -> mGnssNavigationMessageProvider.onNavigationMessageAvailable(event));
Wyatt Riley5d5bac82016-11-01 07:05:16 -07001465 }
destradaa4b3e3932014-07-21 18:01:47 -07001466 }
1467
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001468 @NativeEntryPoint
Wyatt Rileyd87cf912017-12-05 09:31:52 -08001469 private void setEngineCapabilities(final int capabilities) {
1470 // send to handler thread for fast native return, and in-order handling
gomo226b7b72018-12-12 16:49:39 -08001471 mHandler.post(
1472 () -> {
1473 mEngineCapabilities = capabilities;
Mike Lockwood9b9fb5c2011-06-29 15:09:40 -04001474
gomo226b7b72018-12-12 16:49:39 -08001475 if (hasCapability(GPS_CAPABILITY_ON_DEMAND_TIME)) {
1476 mNtpTimeHelper.enablePeriodicTimeInjection();
1477 requestUtcTime();
1478 }
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001479
gomo226b7b72018-12-12 16:49:39 -08001480 mGnssMeasurementsProvider.onCapabilitiesUpdated(capabilities);
1481 mGnssNavigationMessageProvider.onCapabilitiesUpdated(
1482 hasCapability(GPS_CAPABILITY_NAV_MESSAGES));
1483 restartRequests();
1484 });
Yu-Han Yang52057622018-04-25 00:51:22 -07001485 }
1486
1487 private void restartRequests() {
1488 Log.i(TAG, "restartRequests");
1489
1490 restartLocationRequest();
1491 mGnssMeasurementsProvider.resumeIfStarted();
1492 mGnssNavigationMessageProvider.resumeIfStarted();
1493 mGnssBatchingProvider.resumeIfStarted();
1494 mGnssGeofenceProvider.resumeIfStarted();
1495 }
1496
1497 private void restartLocationRequest() {
1498 if (DEBUG) Log.d(TAG, "restartLocationRequest");
1499 mStarted = false;
1500 updateRequirements();
1501 }
Wyatt Rileyd87cf912017-12-05 09:31:52 -08001502
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001503 @NativeEntryPoint
Wyatt Rileyd87cf912017-12-05 09:31:52 -08001504 private void setGnssYearOfHardware(final int yearOfHardware) {
1505 // mHardwareYear is simply set here, to be read elsewhere, and is volatile for safe sync
1506 if (DEBUG) Log.d(TAG, "setGnssYearOfHardware called with " + yearOfHardware);
1507 mHardwareYear = yearOfHardware;
Mike Lockwood04598b62010-04-14 17:17:24 -04001508 }
1509
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001510 @NativeEntryPoint
Wyatt Rileyd87cf912017-12-05 09:31:52 -08001511 private void setGnssHardwareModelName(final String modelName) {
1512 // mHardwareModelName is simply set here, to be read elsewhere, and volatile for safe sync
1513 if (DEBUG) Log.d(TAG, "setGnssModelName called with " + modelName);
1514 mHardwareModelName = modelName;
Lifu Tang82f893d2016-01-21 18:15:33 -08001515 }
1516
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001517 @NativeEntryPoint
Yu-Han Yang52057622018-04-25 00:51:22 -07001518 private void reportGnssServiceDied() {
1519 if (DEBUG) Log.d(TAG, "reportGnssServiceDied");
1520 mHandler.post(() -> {
1521 class_init_native();
1522 native_init_once();
1523 if (isEnabled()) {
Soonil Nagarkar35c3b912019-01-31 10:31:24 -08001524 synchronized (mLock) {
1525 mEnabled = false;
1526 }
1527 updateEnabled();
1528
Yu-Han Yang52057622018-04-25 00:51:22 -07001529 // resend configuration into the restarted HAL service.
Anil Admald71cf142018-12-21 14:59:36 -08001530 reloadGpsProperties();
Yu-Han Yang52057622018-04-25 00:51:22 -07001531 }
1532 });
1533 }
1534
Lifu Tang9363b942016-02-16 18:07:00 -08001535 public interface GnssSystemInfoProvider {
Lifu Tang82f893d2016-01-21 18:15:33 -08001536 /**
Wyatt Rileyd87cf912017-12-05 09:31:52 -08001537 * Returns the year of underlying GPS hardware.
Lifu Tang82f893d2016-01-21 18:15:33 -08001538 */
Lifu Tang9363b942016-02-16 18:07:00 -08001539 int getGnssYearOfHardware();
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001540
Wyatt Rileyd87cf912017-12-05 09:31:52 -08001541 /**
1542 * Returns the model name of underlying GPS hardware.
1543 */
1544 String getGnssHardwareModelName();
Lifu Tang82f893d2016-01-21 18:15:33 -08001545 }
1546
1547 /**
1548 * @hide
1549 */
Lifu Tang9363b942016-02-16 18:07:00 -08001550 public GnssSystemInfoProvider getGnssSystemInfoProvider() {
1551 return new GnssSystemInfoProvider() {
Lifu Tang82f893d2016-01-21 18:15:33 -08001552 @Override
Lifu Tang9363b942016-02-16 18:07:00 -08001553 public int getGnssYearOfHardware() {
Wyatt Rileyd87cf912017-12-05 09:31:52 -08001554 return mHardwareYear;
1555 }
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001556
Wyatt Rileyd87cf912017-12-05 09:31:52 -08001557 @Override
1558 public String getGnssHardwareModelName() {
1559 return mHardwareModelName;
Lifu Tang82f893d2016-01-21 18:15:33 -08001560 }
1561 };
1562 }
1563
Wyatt Rileycf879db2017-01-12 13:57:38 -08001564 /**
1565 * @hide
1566 */
1567 public GnssBatchingProvider getGnssBatchingProvider() {
Yu-Han Yang3557cc72018-03-21 12:48:36 -07001568 return mGnssBatchingProvider;
Wyatt Rileycf879db2017-01-12 13:57:38 -08001569 }
1570
Siddharth Raybb608c82017-03-16 11:33:34 -07001571 public interface GnssMetricsProvider {
1572 /**
1573 * Returns GNSS metrics as proto string
1574 */
1575 String getGnssMetricsAsProtoString();
1576 }
1577
1578 /**
1579 * @hide
1580 */
1581 public GnssMetricsProvider getGnssMetricsProvider() {
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001582 return () -> mGnssMetrics.dumpGnssMetricsAsProtoString();
Siddharth Raybb608c82017-03-16 11:33:34 -07001583 }
1584
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001585 @NativeEntryPoint
Wyatt Rileycf879db2017-01-12 13:57:38 -08001586 private void reportLocationBatch(Location[] locationArray) {
1587 List<Location> locations = new ArrayList<>(Arrays.asList(locationArray));
gomo48f1a642017-11-10 20:35:46 -08001588 if (DEBUG) {
1589 Log.d(TAG, "Location batch of size " + locationArray.length + " reported");
1590 }
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001591 reportLocation(locations);
Wyatt Rileycf879db2017-01-12 13:57:38 -08001592 }
1593
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001594 @NativeEntryPoint
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001595 private void xtraDownloadRequest() {
Joe Onoratof5d95cb2010-01-07 21:48:32 -05001596 if (DEBUG) Log.d(TAG, "xtraDownloadRequest");
Mike Lockwood98e48692010-04-07 16:32:51 -04001597 sendMessage(DOWNLOAD_XTRA_DATA, 0, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001598 }
1599
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07001600 /**
destradaa0682809a2013-08-12 18:50:30 -07001601 * Converts the GPS HAL status to the internal Geofence Hardware status.
1602 */
Yu-Han Yang6dc9f052018-12-04 17:11:24 -08001603 private static int getGeofenceStatus(int status) {
gomo48f1a642017-11-10 20:35:46 -08001604 switch (status) {
destradaa0682809a2013-08-12 18:50:30 -07001605 case GPS_GEOFENCE_OPERATION_SUCCESS:
1606 return GeofenceHardware.GEOFENCE_SUCCESS;
1607 case GPS_GEOFENCE_ERROR_GENERIC:
1608 return GeofenceHardware.GEOFENCE_FAILURE;
1609 case GPS_GEOFENCE_ERROR_ID_EXISTS:
1610 return GeofenceHardware.GEOFENCE_ERROR_ID_EXISTS;
1611 case GPS_GEOFENCE_ERROR_INVALID_TRANSITION:
1612 return GeofenceHardware.GEOFENCE_ERROR_INVALID_TRANSITION;
1613 case GPS_GEOFENCE_ERROR_TOO_MANY_GEOFENCES:
1614 return GeofenceHardware.GEOFENCE_ERROR_TOO_MANY_GEOFENCES;
1615 case GPS_GEOFENCE_ERROR_ID_UNKNOWN:
1616 return GeofenceHardware.GEOFENCE_ERROR_ID_UNKNOWN;
1617 default:
1618 return -1;
1619 }
1620 }
1621
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001622 @NativeEntryPoint
Wyatt Riley5d229832017-02-10 17:06:00 -08001623 private void reportGeofenceTransition(int geofenceId, Location location, int transition,
gomo48f1a642017-11-10 20:35:46 -08001624 long transitionTimestamp) {
Yu-Han Yang6dc9f052018-12-04 17:11:24 -08001625 mHandler.post(() -> {
1626 if (mGeofenceHardwareImpl == null) {
1627 mGeofenceHardwareImpl = GeofenceHardwareImpl.getInstance(mContext);
1628 }
Wyatt Riley5d229832017-02-10 17:06:00 -08001629
Yu-Han Yang6dc9f052018-12-04 17:11:24 -08001630 mGeofenceHardwareImpl.reportGeofenceTransition(
1631 geofenceId,
1632 location,
1633 transition,
1634 transitionTimestamp,
1635 GeofenceHardware.MONITORING_TYPE_GPS_HARDWARE,
1636 FusedBatchOptions.SourceTechnologies.GNSS);
1637 });
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07001638 }
1639
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001640 @NativeEntryPoint
Wyatt Riley5d229832017-02-10 17:06:00 -08001641 private void reportGeofenceStatus(int status, Location location) {
Yu-Han Yang6dc9f052018-12-04 17:11:24 -08001642 mHandler.post(() -> {
1643 if (mGeofenceHardwareImpl == null) {
1644 mGeofenceHardwareImpl = GeofenceHardwareImpl.getInstance(mContext);
1645 }
1646 int monitorStatus = GeofenceHardware.MONITOR_CURRENTLY_UNAVAILABLE;
1647 if (status == GPS_GEOFENCE_AVAILABLE) {
1648 monitorStatus = GeofenceHardware.MONITOR_CURRENTLY_AVAILABLE;
1649 }
1650 mGeofenceHardwareImpl.reportGeofenceMonitorStatus(
1651 GeofenceHardware.MONITORING_TYPE_GPS_HARDWARE,
1652 monitorStatus,
1653 location,
1654 FusedBatchOptions.SourceTechnologies.GNSS);
1655 });
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07001656 }
1657
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001658 @NativeEntryPoint
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07001659 private void reportGeofenceAddStatus(int geofenceId, int status) {
Yu-Han Yang6dc9f052018-12-04 17:11:24 -08001660 mHandler.post(() -> {
1661 if (mGeofenceHardwareImpl == null) {
1662 mGeofenceHardwareImpl = GeofenceHardwareImpl.getInstance(mContext);
1663 }
1664 mGeofenceHardwareImpl.reportGeofenceAddStatus(geofenceId, getGeofenceStatus(status));
1665 });
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07001666 }
1667
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001668 @NativeEntryPoint
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07001669 private void reportGeofenceRemoveStatus(int geofenceId, int status) {
Yu-Han Yang6dc9f052018-12-04 17:11:24 -08001670 mHandler.post(() -> {
1671 if (mGeofenceHardwareImpl == null) {
1672 mGeofenceHardwareImpl = GeofenceHardwareImpl.getInstance(mContext);
1673 }
1674 mGeofenceHardwareImpl.reportGeofenceRemoveStatus(geofenceId, getGeofenceStatus(status));
1675 });
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07001676 }
1677
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001678 @NativeEntryPoint
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07001679 private void reportGeofencePauseStatus(int geofenceId, int status) {
Yu-Han Yang6dc9f052018-12-04 17:11:24 -08001680 mHandler.post(() -> {
1681 if (mGeofenceHardwareImpl == null) {
1682 mGeofenceHardwareImpl = GeofenceHardwareImpl.getInstance(mContext);
1683 }
1684 mGeofenceHardwareImpl.reportGeofencePauseStatus(geofenceId, getGeofenceStatus(status));
1685 });
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07001686 }
1687
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001688 @NativeEntryPoint
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07001689 private void reportGeofenceResumeStatus(int geofenceId, int status) {
Yu-Han Yang6dc9f052018-12-04 17:11:24 -08001690 mHandler.post(() -> {
1691 if (mGeofenceHardwareImpl == null) {
1692 mGeofenceHardwareImpl = GeofenceHardwareImpl.getInstance(mContext);
1693 }
1694 mGeofenceHardwareImpl.reportGeofenceResumeStatus(geofenceId, getGeofenceStatus(status));
1695 });
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07001696 }
1697
Danke Xie22d1f9f2009-08-18 18:28:45 -04001698 //=============================================================
1699 // NI Client support
Miguel Torroja1e84da82010-07-27 07:02:24 +02001700 //=============================================================
Danke Xie22d1f9f2009-08-18 18:28:45 -04001701 private final INetInitiatedListener mNetInitiatedListener = new INetInitiatedListener.Stub() {
destradaaef752b62015-04-17 13:10:47 -07001702 // Sends a response for an NI request to HAL.
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001703 @Override
gomo48f1a642017-11-10 20:35:46 -08001704 public boolean sendNiResponse(int notificationId, int userResponse) {
Miguel Torroja1e84da82010-07-27 07:02:24 +02001705 // TODO Add Permission check
Danke Xie22d1f9f2009-08-18 18:28:45 -04001706
gomo48f1a642017-11-10 20:35:46 -08001707 if (DEBUG) {
1708 Log.d(TAG, "sendNiResponse, notifId: " + notificationId +
1709 ", response: " + userResponse);
1710 }
Miguel Torroja1e84da82010-07-27 07:02:24 +02001711 native_send_ni_response(notificationId, userResponse);
Yu-Han Yang8a1b51d2018-12-26 22:18:31 -08001712
1713 StatsLog.write(StatsLog.GNSS_NI_EVENT_REPORTED,
1714 StatsLog.GNSS_NI_EVENT_REPORTED__EVENT_TYPE__NI_RESPONSE,
1715 notificationId,
1716 /* niType= */ 0,
1717 /* needNotify= */ false,
1718 /* needVerify= */ false,
1719 /* privacyOverride= */ false,
1720 /* timeout= */ 0,
1721 /* defaultResponse= */ 0,
1722 /* requestorId= */ null,
1723 /* text= */ null,
1724 /* requestorIdEncoding= */ 0,
1725 /* textEncoding= */ 0,
1726 mSuplEsEnabled,
Soonil Nagarkar35c3b912019-01-31 10:31:24 -08001727 isEnabled(),
Yu-Han Yang8a1b51d2018-12-26 22:18:31 -08001728 userResponse);
1729
Miguel Torroja1e84da82010-07-27 07:02:24 +02001730 return true;
1731 }
Danke Xie22d1f9f2009-08-18 18:28:45 -04001732 };
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001733
Danke Xie22d1f9f2009-08-18 18:28:45 -04001734 public INetInitiatedListener getNetInitiatedListener() {
1735 return mNetInitiatedListener;
1736 }
1737
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001738 /** Reports a NI notification. */
1739 @NativeEntryPoint
Miguel Torroja1e84da82010-07-27 07:02:24 +02001740 public void reportNiNotification(
1741 int notificationId,
1742 int niType,
1743 int notifyFlags,
1744 int timeout,
1745 int defaultResponse,
1746 String requestorId,
1747 String text,
1748 int requestorIdEncoding,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001749 int textEncoding
gomo48f1a642017-11-10 20:35:46 -08001750 ) {
Miguel Torroja1e84da82010-07-27 07:02:24 +02001751 Log.i(TAG, "reportNiNotification: entered");
1752 Log.i(TAG, "notificationId: " + notificationId +
1753 ", niType: " + niType +
1754 ", notifyFlags: " + notifyFlags +
1755 ", timeout: " + timeout +
1756 ", defaultResponse: " + defaultResponse);
1757
1758 Log.i(TAG, "requestorId: " + requestorId +
1759 ", text: " + text +
1760 ", requestorIdEncoding: " + requestorIdEncoding +
1761 ", textEncoding: " + textEncoding);
1762
1763 GpsNiNotification notification = new GpsNiNotification();
1764
1765 notification.notificationId = notificationId;
1766 notification.niType = niType;
1767 notification.needNotify = (notifyFlags & GpsNetInitiatedHandler.GPS_NI_NEED_NOTIFY) != 0;
1768 notification.needVerify = (notifyFlags & GpsNetInitiatedHandler.GPS_NI_NEED_VERIFY) != 0;
gomo48f1a642017-11-10 20:35:46 -08001769 notification.privacyOverride =
1770 (notifyFlags & GpsNetInitiatedHandler.GPS_NI_PRIVACY_OVERRIDE) != 0;
Miguel Torroja1e84da82010-07-27 07:02:24 +02001771 notification.timeout = timeout;
1772 notification.defaultResponse = defaultResponse;
1773 notification.requestorId = requestorId;
1774 notification.text = text;
1775 notification.requestorIdEncoding = requestorIdEncoding;
1776 notification.textEncoding = textEncoding;
1777
Miguel Torroja1e84da82010-07-27 07:02:24 +02001778 mNIHandler.handleNiNotification(notification);
Yu-Han Yang8a1b51d2018-12-26 22:18:31 -08001779 StatsLog.write(StatsLog.GNSS_NI_EVENT_REPORTED,
1780 StatsLog.GNSS_NI_EVENT_REPORTED__EVENT_TYPE__NI_REQUEST,
1781 notification.notificationId,
1782 notification.niType,
1783 notification.needNotify,
1784 notification.needVerify,
1785 notification.privacyOverride,
1786 notification.timeout,
1787 notification.defaultResponse,
1788 notification.requestorId,
1789 notification.text,
1790 notification.requestorIdEncoding,
1791 notification.textEncoding,
1792 mSuplEsEnabled,
Soonil Nagarkar35c3b912019-01-31 10:31:24 -08001793 isEnabled(),
Yu-Han Yang8a1b51d2018-12-26 22:18:31 -08001794 /* userResponse= */ 0);
Miguel Torroja1e84da82010-07-27 07:02:24 +02001795 }
1796
1797 /**
Miguel Torroja1e84da82010-07-27 07:02:24 +02001798 * We should be careful about receiving null string from the TelephonyManager,
1799 * because sending null String to JNI function would cause a crash.
1800 */
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001801 @NativeEntryPoint
Miguel Torroja1e84da82010-07-27 07:02:24 +02001802 private void requestSetID(int flags) {
1803 TelephonyManager phone = (TelephonyManager)
1804 mContext.getSystemService(Context.TELEPHONY_SERVICE);
destradaaef752b62015-04-17 13:10:47 -07001805 int type = AGPS_SETID_TYPE_NONE;
Miguel Torroja1e84da82010-07-27 07:02:24 +02001806 String data = "";
1807
1808 if ((flags & AGPS_RIL_REQUEST_SETID_IMSI) == AGPS_RIL_REQUEST_SETID_IMSI) {
1809 String data_temp = phone.getSubscriberId();
1810 if (data_temp == null) {
1811 // This means the framework does not have the SIM card ready.
1812 } else {
1813 // This means the framework has the SIM card.
1814 data = data_temp;
1815 type = AGPS_SETID_TYPE_IMSI;
1816 }
gomo48f1a642017-11-10 20:35:46 -08001817 } else if ((flags & AGPS_RIL_REQUEST_SETID_MSISDN) == AGPS_RIL_REQUEST_SETID_MSISDN) {
Miguel Torroja1e84da82010-07-27 07:02:24 +02001818 String data_temp = phone.getLine1Number();
1819 if (data_temp == null) {
1820 // This means the framework does not have the SIM card ready.
1821 } else {
1822 // This means the framework has the SIM card.
1823 data = data_temp;
1824 type = AGPS_SETID_TYPE_MSISDN;
1825 }
1826 }
1827 native_agps_set_id(type, data);
1828 }
1829
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001830 @NativeEntryPoint
Yu-Han Yange7baef32018-02-09 13:58:17 -08001831 private void requestLocation(boolean independentFromGnss) {
1832 if (DEBUG) {
1833 Log.d(TAG, "requestLocation. independentFromGnss: " + independentFromGnss);
1834 }
1835 sendMessage(REQUEST_LOCATION, 0, independentFromGnss);
1836 }
1837
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001838 @NativeEntryPoint
Mike Lockwood9b9fb5c2011-06-29 15:09:40 -04001839 private void requestUtcTime() {
destradaae21252a2015-09-08 12:32:59 -07001840 if (DEBUG) Log.d(TAG, "utcTimeRequest");
Mike Lockwood9b9fb5c2011-06-29 15:09:40 -04001841 sendMessage(INJECT_NTP_TIME, 0, null);
1842 }
1843
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001844 @NativeEntryPoint
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001845 private void requestRefLocation() {
Miguel Torroja1e84da82010-07-27 07:02:24 +02001846 TelephonyManager phone = (TelephonyManager)
1847 mContext.getSystemService(Context.TELEPHONY_SERVICE);
Victoria Leased50d0c32012-10-29 13:16:17 -07001848 final int phoneType = phone.getPhoneType();
1849 if (phoneType == TelephonyManager.PHONE_TYPE_GSM) {
Miguel Torroja1e84da82010-07-27 07:02:24 +02001850 GsmCellLocation gsm_cell = (GsmCellLocation) phone.getCellLocation();
Victoria Leased50d0c32012-10-29 13:16:17 -07001851 if ((gsm_cell != null) && (phone.getNetworkOperator() != null)
1852 && (phone.getNetworkOperator().length() > 3)) {
Miguel Torroja1e84da82010-07-27 07:02:24 +02001853 int type;
gomo48f1a642017-11-10 20:35:46 -08001854 int mcc = Integer.parseInt(phone.getNetworkOperator().substring(0, 3));
Miguel Torroja1e84da82010-07-27 07:02:24 +02001855 int mnc = Integer.parseInt(phone.getNetworkOperator().substring(3));
Mike Lockwoodedc0f3872010-10-22 09:16:17 -04001856 int networkType = phone.getNetworkType();
1857 if (networkType == TelephonyManager.NETWORK_TYPE_UMTS
gomo48f1a642017-11-10 20:35:46 -08001858 || networkType == TelephonyManager.NETWORK_TYPE_HSDPA
1859 || networkType == TelephonyManager.NETWORK_TYPE_HSUPA
1860 || networkType == TelephonyManager.NETWORK_TYPE_HSPA
1861 || networkType == TelephonyManager.NETWORK_TYPE_HSPAP) {
Miguel Torroja1e84da82010-07-27 07:02:24 +02001862 type = AGPS_REF_LOCATION_TYPE_UMTS_CELLID;
Mike Lockwoodedc0f3872010-10-22 09:16:17 -04001863 } else {
Miguel Torroja1e84da82010-07-27 07:02:24 +02001864 type = AGPS_REF_LOCATION_TYPE_GSM_CELLID;
Mike Lockwoodedc0f3872010-10-22 09:16:17 -04001865 }
Miguel Torroja1e84da82010-07-27 07:02:24 +02001866 native_agps_set_ref_location_cellid(type, mcc, mnc,
1867 gsm_cell.getLac(), gsm_cell.getCid());
Mike Lockwoodedc0f3872010-10-22 09:16:17 -04001868 } else {
gomo48f1a642017-11-10 20:35:46 -08001869 Log.e(TAG, "Error getting cell location info.");
Mike Lockwoodedc0f3872010-10-22 09:16:17 -04001870 }
Victoria Leased50d0c32012-10-29 13:16:17 -07001871 } else if (phoneType == TelephonyManager.PHONE_TYPE_CDMA) {
1872 Log.e(TAG, "CDMA not supported.");
Mike Lockwoodedc0f3872010-10-22 09:16:17 -04001873 }
Miguel Torroja1e84da82010-07-27 07:02:24 +02001874 }
Danke Xie22d1f9f2009-08-18 18:28:45 -04001875
Anil Admal94ec76a2019-01-15 09:42:01 -08001876 // Implements method nfwNotifyCb() in IGnssVisibilityControlCallback.hal.
1877 @NativeEntryPoint
1878 private void reportNfwNotification(String proxyAppPackageName, byte protocolStack,
1879 String otherProtocolStackName, byte requestor, String requestorId, byte responseType,
1880 boolean inEmergencyMode, boolean isCachedLocation) {
1881 if (mGnssVisibilityControl == null) {
1882 Log.e(TAG, "reportNfwNotification: mGnssVisibilityControl is not initialized.");
1883 return;
1884 }
1885
1886 mGnssVisibilityControl.reportNfwNotification(proxyAppPackageName, protocolStack,
1887 otherProtocolStackName, requestor, requestorId, responseType, inEmergencyMode,
1888 isCachedLocation);
1889 }
1890
1891 // Implements method isInEmergencySession() in IGnssVisibilityControlCallback.hal.
1892 @NativeEntryPoint
1893 boolean isInEmergencySession() {
1894 return mNIHandler.getInEmergency();
1895 }
1896
Mike Lockwood98e48692010-04-07 16:32:51 -04001897 private void sendMessage(int message, int arg, Object obj) {
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001898 // hold a wake lock until this message is delivered
Jeff Brown028872f2012-08-25 13:07:01 -07001899 // note that this assumes the message will not be removed from the queue before
1900 // it is handled (otherwise the wake lock would be leaked).
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001901 mWakeLock.acquire();
Anil Admal4f97c942018-11-12 10:52:46 -08001902 if (DEBUG) {
1903 Log.d(TAG, "WakeLock acquired by sendMessage(" + messageIdAsString(message) + ", " + arg
Wyatt Rileycf879db2017-01-12 13:57:38 -08001904 + ", " + obj + ")");
1905 }
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001906 mHandler.obtainMessage(message, arg, 1, obj).sendToTarget();
Mike Lockwood98e48692010-04-07 16:32:51 -04001907 }
1908
Mike Lockwood62a8fc12010-03-22 14:23:26 -04001909 private final class ProviderHandler extends Handler {
Victoria Lease5cd731a2012-12-19 15:04:21 -08001910 public ProviderHandler(Looper looper) {
1911 super(looper, null, true /*async*/);
Jeff Brown028872f2012-08-25 13:07:01 -07001912 }
1913
Mike Lockwood62a8fc12010-03-22 14:23:26 -04001914 @Override
Mike Lockwood4a7b65e2010-10-25 16:35:55 -04001915 public void handleMessage(Message msg) {
Mike Lockwood98e48692010-04-07 16:32:51 -04001916 int message = msg.what;
1917 switch (message) {
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001918 case SET_REQUEST:
1919 GpsRequest gpsRequest = (GpsRequest) msg.obj;
1920 handleSetRequest(gpsRequest.request, gpsRequest.source);
Mike Lockwood03ca2162010-04-01 08:10:09 -07001921 break;
Mike Lockwood62a8fc12010-03-22 14:23:26 -04001922 case INJECT_NTP_TIME:
Yu-Han Yanga1862b52018-02-20 17:05:59 -08001923 mNtpTimeHelper.retrieveAndInjectNtpTime();
Mike Lockwood62a8fc12010-03-22 14:23:26 -04001924 break;
Yu-Han Yange7baef32018-02-09 13:58:17 -08001925 case REQUEST_LOCATION:
1926 handleRequestLocation((boolean) msg.obj);
1927 break;
Mike Lockwood62a8fc12010-03-22 14:23:26 -04001928 case DOWNLOAD_XTRA_DATA:
Wyatt Riley0d6e54e22016-10-05 12:03:03 -07001929 handleDownloadXtraData();
Mike Lockwood62a8fc12010-03-22 14:23:26 -04001930 break;
Kevin Tang40e1baf2012-01-10 14:32:44 -08001931 case DOWNLOAD_XTRA_DATA_FINISHED:
1932 mDownloadXtraDataPending = STATE_IDLE;
1933 break;
Mike Lockwood62a8fc12010-03-22 14:23:26 -04001934 case UPDATE_LOCATION:
destradaae21252a2015-09-08 12:32:59 -07001935 handleUpdateLocation((Location) msg.obj);
Mike Lockwood62a8fc12010-03-22 14:23:26 -04001936 break;
Meng Wang19b214d2018-11-07 12:14:39 -08001937 case SUBSCRIPTION_OR_CARRIER_CONFIG_CHANGED:
1938 subscriptionOrCarrierConfigChanged(mContext);
destradaafb23c672015-04-16 14:01:27 -07001939 break;
1940 case INITIALIZE_HANDLER:
destradaae21252a2015-09-08 12:32:59 -07001941 handleInitialize();
destradaafb23c672015-04-16 14:01:27 -07001942 break;
Wyatt Riley26465d22018-02-12 13:44:24 -08001943 case REPORT_LOCATION:
1944 handleReportLocation(msg.arg1 == 1, (Location) msg.obj);
1945 break;
1946 case REPORT_SV_STATUS:
1947 handleReportSvStatus((SvStatusInfo) msg.obj);
1948 break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001949 }
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001950 if (msg.arg2 == 1) {
1951 // wakelock was taken for this message, release it
1952 mWakeLock.release();
Anil Admal4f97c942018-11-12 10:52:46 -08001953 if (DEBUG) {
1954 Log.d(TAG, "WakeLock released by handleMessage(" + messageIdAsString(message)
Wyatt Rileycf879db2017-01-12 13:57:38 -08001955 + ", " + msg.arg1 + ", " + msg.obj + ")");
1956 }
Mike Lockwood98e48692010-04-07 16:32:51 -04001957 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001958 }
destradaafb23c672015-04-16 14:01:27 -07001959
1960 /**
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001961 * This method is bound to {@link #GnssLocationProvider(Context, LocationProviderManager,
1962 * Looper)}.
destradaafb23c672015-04-16 14:01:27 -07001963 * It is in charge of loading properties and registering for events that will be posted to
1964 * this handler.
1965 */
destradaae21252a2015-09-08 12:32:59 -07001966 private void handleInitialize() {
Yu-Han Yang6d317352018-03-15 11:53:01 -07001967 native_init_once();
1968
Wyatt Riley523a0cf2017-10-31 14:36:52 -07001969 /*
1970 * A cycle of native_init() and native_cleanup() is needed so that callbacks are
1971 * registered after bootup even when location is disabled.
1972 * This will allow Emergency SUPL to work even when location is disabled before device
1973 * restart.
1974 */
1975 boolean isInitialized = native_init();
gomo48f1a642017-11-10 20:35:46 -08001976 if (!isInitialized) {
Wyatt Riley523a0cf2017-10-31 14:36:52 -07001977 Log.w(TAG, "Native initialization failed at bootup");
1978 } else {
1979 native_cleanup();
1980 }
1981
Anil Admal94ec76a2019-01-15 09:42:01 -08001982 if (native_is_gnss_visibility_control_supported()) {
1983 mGnssVisibilityControl = new GnssVisibilityControl(mContext, mLooper);
1984 }
1985
destradaafb23c672015-04-16 14:01:27 -07001986 // load default GPS configuration
1987 // (this configuration might change in the future based on SIM changes)
Anil Admald71cf142018-12-21 14:59:36 -08001988 reloadGpsProperties();
destradaafb23c672015-04-16 14:01:27 -07001989
1990 // TODO: When this object "finishes" we should unregister by invoking
gomo48f1a642017-11-10 20:35:46 -08001991 // SubscriptionManager.getInstance(mContext).unregister
1992 // (mOnSubscriptionsChangedListener);
destradaafb23c672015-04-16 14:01:27 -07001993 // This is not strictly necessary because it will be unregistered if the
1994 // notification fails but it is good form.
1995
1996 // Register for SubscriptionInfo list changes which is guaranteed
1997 // to invoke onSubscriptionsChanged the first time.
1998 SubscriptionManager.from(mContext)
1999 .addOnSubscriptionsChangedListener(mOnSubscriptionsChangedListener);
2000
2001 // listen for events
WyattRiley6593cf12018-06-23 10:37:48 -07002002 IntentFilter intentFilter = new IntentFilter();
destradaafb23c672015-04-16 14:01:27 -07002003 intentFilter.addAction(ALARM_WAKEUP);
2004 intentFilter.addAction(ALARM_TIMEOUT);
destradaafb23c672015-04-16 14:01:27 -07002005 intentFilter.addAction(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED);
Adam Lesinski87c17df2015-05-27 13:24:13 -07002006 intentFilter.addAction(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED);
destradaafb23c672015-04-16 14:01:27 -07002007 intentFilter.addAction(Intent.ACTION_SCREEN_OFF);
2008 intentFilter.addAction(Intent.ACTION_SCREEN_ON);
Meng Wang19b214d2018-11-07 12:14:39 -08002009 intentFilter.addAction(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
destradaafb23c672015-04-16 14:01:27 -07002010 mContext.registerReceiver(mBroadcastReceiver, intentFilter, null, this);
2011
Anil Admal50ba15e2018-11-01 16:42:42 -07002012 mNetworkConnectivityHandler.registerNetworkCallbacks();
destradaae21252a2015-09-08 12:32:59 -07002013
destradaafb23c672015-04-16 14:01:27 -07002014 // listen for PASSIVE_PROVIDER updates
2015 LocationManager locManager =
2016 (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE);
2017 long minTime = 0;
2018 float minDistance = 0;
destradaafb23c672015-04-16 14:01:27 -07002019 LocationRequest request = LocationRequest.createFromDeprecatedProvider(
2020 LocationManager.PASSIVE_PROVIDER,
2021 minTime,
2022 minDistance,
Soonil Nagarkar1575a042018-10-24 17:54:54 -07002023 false);
destradaafb23c672015-04-16 14:01:27 -07002024 // Don't keep track of this request since it's done on behalf of other clients
2025 // (which are kept track of separately).
2026 request.setHideFromAppOps(true);
2027 locManager.requestLocationUpdates(
2028 request,
2029 new NetworkLocationListener(),
2030 getLooper());
Soonil Nagarkar1575a042018-10-24 17:54:54 -07002031
Soonil Nagarkar35c3b912019-01-31 10:31:24 -08002032 updateEnabled();
destradaafb23c672015-04-16 14:01:27 -07002033 }
2034 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002035
Yu-Han Yange7baef32018-02-09 13:58:17 -08002036 private abstract class LocationChangeListener implements LocationListener {
Soonil Nagarkar1575a042018-10-24 17:54:54 -07002037 private int mNumLocationUpdateRequest;
Yu-Han Yang07561382018-02-21 13:08:37 -08002038
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002039 @Override
gomo48f1a642017-11-10 20:35:46 -08002040 public void onStatusChanged(String provider, int status, Bundle extras) {
2041 }
2042
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002043 @Override
gomo48f1a642017-11-10 20:35:46 -08002044 public void onProviderEnabled(String provider) {
2045 }
2046
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002047 @Override
gomo48f1a642017-11-10 20:35:46 -08002048 public void onProviderDisabled(String provider) {
2049 }
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002050 }
2051
Yu-Han Yange7baef32018-02-09 13:58:17 -08002052 private final class NetworkLocationListener extends LocationChangeListener {
2053 @Override
2054 public void onLocationChanged(Location location) {
2055 // this callback happens on mHandler looper
2056 if (LocationManager.NETWORK_PROVIDER.equals(location.getProvider())) {
2057 handleUpdateLocation(location);
2058 }
2059 }
2060 }
2061
2062 private final class FusedLocationListener extends LocationChangeListener {
2063 @Override
2064 public void onLocationChanged(Location location) {
2065 if (LocationManager.FUSED_PROVIDER.equals(location.getProvider())) {
Yu-Han Yange7baef32018-02-09 13:58:17 -08002066 injectBestLocation(location);
2067 }
2068 }
2069 }
2070
Wyatt Rileycf879db2017-01-12 13:57:38 -08002071 /**
2072 * @return A string representing the given message ID.
2073 */
2074 private String messageIdAsString(int message) {
2075 switch (message) {
Wyatt Rileycf879db2017-01-12 13:57:38 -08002076 case SET_REQUEST:
2077 return "SET_REQUEST";
Wyatt Rileycf879db2017-01-12 13:57:38 -08002078 case INJECT_NTP_TIME:
2079 return "INJECT_NTP_TIME";
Yu-Han Yange7baef32018-02-09 13:58:17 -08002080 case REQUEST_LOCATION:
2081 return "REQUEST_LOCATION";
Wyatt Rileycf879db2017-01-12 13:57:38 -08002082 case DOWNLOAD_XTRA_DATA:
2083 return "DOWNLOAD_XTRA_DATA";
Wyatt Rileycf879db2017-01-12 13:57:38 -08002084 case DOWNLOAD_XTRA_DATA_FINISHED:
2085 return "DOWNLOAD_XTRA_DATA_FINISHED";
2086 case UPDATE_LOCATION:
2087 return "UPDATE_LOCATION";
Meng Wang19b214d2018-11-07 12:14:39 -08002088 case SUBSCRIPTION_OR_CARRIER_CONFIG_CHANGED:
2089 return "SUBSCRIPTION_OR_CARRIER_CONFIG_CHANGED";
Wyatt Rileycf879db2017-01-12 13:57:38 -08002090 case INITIALIZE_HANDLER:
2091 return "INITIALIZE_HANDLER";
Wyatt Riley26465d22018-02-12 13:44:24 -08002092 case REPORT_LOCATION:
2093 return "REPORT_LOCATION";
2094 case REPORT_SV_STATUS:
2095 return "REPORT_SV_STATUS";
Wyatt Rileycf879db2017-01-12 13:57:38 -08002096 default:
2097 return "<Unknown>";
2098 }
2099 }
2100
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002101 @Override
2102 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2103 StringBuilder s = new StringBuilder();
Wyatt Riley77ca4f82017-06-30 18:13:44 -07002104 s.append(" mStarted=").append(mStarted).append('\n');
destradaa25e8caf2015-08-24 14:14:44 -07002105 s.append(" mFixInterval=").append(mFixInterval).append('\n');
gomo48f1a642017-11-10 20:35:46 -08002106 s.append(" mLowPowerMode=").append(mLowPowerMode).append('\n');
Wyatt Riley74479bd2018-01-17 08:48:27 -08002107 s.append(" mGnssMeasurementsProvider.isRegistered()=")
2108 .append(mGnssMeasurementsProvider.isRegistered()).append('\n');
2109 s.append(" mGnssNavigationMessageProvider.isRegistered()=")
2110 .append(mGnssNavigationMessageProvider.isRegistered()).append('\n');
destradaa25e8caf2015-08-24 14:14:44 -07002111 s.append(" mDisableGps (battery saver mode)=").append(mDisableGps).append('\n');
2112 s.append(" mEngineCapabilities=0x").append(Integer.toHexString(mEngineCapabilities));
2113 s.append(" ( ");
2114 if (hasCapability(GPS_CAPABILITY_SCHEDULING)) s.append("SCHEDULING ");
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002115 if (hasCapability(GPS_CAPABILITY_MSB)) s.append("MSB ");
2116 if (hasCapability(GPS_CAPABILITY_MSA)) s.append("MSA ");
2117 if (hasCapability(GPS_CAPABILITY_SINGLE_SHOT)) s.append("SINGLE_SHOT ");
2118 if (hasCapability(GPS_CAPABILITY_ON_DEMAND_TIME)) s.append("ON_DEMAND_TIME ");
destradaa25e8caf2015-08-24 14:14:44 -07002119 if (hasCapability(GPS_CAPABILITY_GEOFENCING)) s.append("GEOFENCING ");
2120 if (hasCapability(GPS_CAPABILITY_MEASUREMENTS)) s.append("MEASUREMENTS ");
2121 if (hasCapability(GPS_CAPABILITY_NAV_MESSAGES)) s.append("NAV_MESSAGES ");
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002122 s.append(")\n");
Siddharth Raybb608c82017-03-16 11:33:34 -07002123 s.append(mGnssMetrics.dumpGnssMetricsAsText());
2124 s.append(" native internal state: ").append(native_get_internal_state());
Wyatt Rileycf879db2017-01-12 13:57:38 -08002125 s.append("\n");
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002126 pw.append(s);
2127 }
2128
Mike Lockwoodb16e7802009-08-06 09:26:02 -04002129 // preallocated to avoid memory allocation in reportNmea()
2130 private byte[] mNmeaBuffer = new byte[120];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002131
gomo48f1a642017-11-10 20:35:46 -08002132 static {
2133 class_init_native();
2134 }
2135
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002136 private static native void class_init_native();
gomo48f1a642017-11-10 20:35:46 -08002137
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002138 private static native boolean native_is_supported();
gomo48f1a642017-11-10 20:35:46 -08002139
Anil Admal94ec76a2019-01-15 09:42:01 -08002140 private static native boolean native_is_gnss_visibility_control_supported();
2141
Yu-Han Yang6d317352018-03-15 11:53:01 -07002142 private static native void native_init_once();
2143
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002144 private native boolean native_init();
gomo48f1a642017-11-10 20:35:46 -08002145
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002146 private native void native_cleanup();
gomo48f1a642017-11-10 20:35:46 -08002147
Mike Lockwood04598b62010-04-14 17:17:24 -04002148 private native boolean native_set_position_mode(int mode, int recurrence, int min_interval,
gomo48f1a642017-11-10 20:35:46 -08002149 int preferred_accuracy, int preferred_time, boolean lowPowerMode);
2150
Mike Lockwood04598b62010-04-14 17:17:24 -04002151 private native boolean native_start();
gomo48f1a642017-11-10 20:35:46 -08002152
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002153 private native boolean native_stop();
gomo48f1a642017-11-10 20:35:46 -08002154
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002155 private native void native_delete_aiding_data(int flags);
gomo48f1a642017-11-10 20:35:46 -08002156
Mike Lockwoodf602d362010-06-20 14:28:16 -07002157 private native int native_read_nmea(byte[] buffer, int bufferSize);
gomo48f1a642017-11-10 20:35:46 -08002158
Yu-Han Yange7baef32018-02-09 13:58:17 -08002159 private native void native_inject_best_location(
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -08002160 int gnssLocationFlags, double latitudeDegrees, double longitudeDegrees,
2161 double altitudeMeters, float speedMetersPerSec, float bearingDegrees,
2162 float horizontalAccuracyMeters, float verticalAccuracyMeters,
2163 float speedAccuracyMetersPerSecond, float bearingAccuracyDegrees,
2164 long timestamp, int elapsedRealtimeFlags, long elapsedRealtimeNanos);
Yu-Han Yange7baef32018-02-09 13:58:17 -08002165
Mike Lockwoodd26ce0d2009-06-11 12:25:46 -04002166 private native void native_inject_location(double latitude, double longitude, float accuracy);
2167
Fred Fettinger3c8fbdf2010-01-04 15:38:13 -06002168 // XTRA Support
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002169 private native void native_inject_time(long time, long timeReference, int uncertainty);
gomo48f1a642017-11-10 20:35:46 -08002170
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002171 private native boolean native_supports_xtra();
gomo48f1a642017-11-10 20:35:46 -08002172
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002173 private native void native_inject_xtra_data(byte[] data, int length);
The Android Open Source Project10592532009-03-18 17:39:46 -07002174
Fred Fettinger3c8fbdf2010-01-04 15:38:13 -06002175 // DEBUG Support
2176 private native String native_get_internal_state();
2177
2178 // AGPS Support
gomo48f1a642017-11-10 20:35:46 -08002179 private native void native_agps_ni_message(byte[] msg, int length);
2180
Mike Lockwooda9e54612009-06-19 14:54:42 -04002181 private native void native_set_agps_server(int type, String hostname, int port);
Danke Xie22d1f9f2009-08-18 18:28:45 -04002182
2183 // Network-initiated (NI) Support
2184 private native void native_send_ni_response(int notificationId, int userResponse);
Miguel Torroja1e84da82010-07-27 07:02:24 +02002185
Anil Admal50ba15e2018-11-01 16:42:42 -07002186 // AGPS ril support
Miguel Torroja1e84da82010-07-27 07:02:24 +02002187 private native void native_agps_set_ref_location_cellid(int type, int mcc, int mnc,
2188 int lac, int cid);
gomo48f1a642017-11-10 20:35:46 -08002189
Miguel Torroja1e84da82010-07-27 07:02:24 +02002190 private native void native_agps_set_id(int type, String setid);
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -08002191}