blob: ae915037947e43d81b46429496227b558c652077 [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 Yang53f4d6d2019-02-13 21:47:41 -0800690 private void handleRequestLocation(boolean independentFromGnss, boolean isUserEmergency) {
Yu-Han Yange7baef32018-02-09 13:58:17 -0800691 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 Yang53f4d6d2019-02-13 21:47:41 -0800726
727 LocationRequest locationRequest = LocationRequest.createFromDeprecatedProvider(provider,
728 LOCATION_UPDATE_MIN_TIME_INTERVAL_MILLIS, /* minDistance= */ 0,
729 /* singleShot= */ false);
730
731 // Ignore location settings if in emergency mode.
732 if (isUserEmergency && mNIHandler.getInEmergency()) {
733 locationRequest.setLocationSettingsIgnored(true);
734 }
Yu-Han Yange684dda2018-05-24 10:29:39 -0700735 try {
Yu-Han Yang53f4d6d2019-02-13 21:47:41 -0800736 locationManager.requestLocationUpdates(locationRequest,
Yu-Han Yange684dda2018-05-24 10:29:39 -0700737 locationListener, mHandler.getLooper());
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700738 locationListener.mNumLocationUpdateRequest++;
Yu-Han Yange684dda2018-05-24 10:29:39 -0700739 mHandler.postDelayed(() -> {
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700740 if (--locationListener.mNumLocationUpdateRequest == 0) {
Yu-Han Yange684dda2018-05-24 10:29:39 -0700741 Log.i(TAG,
742 String.format("Removing location updates from %s provider.", provider));
743 locationManager.removeUpdates(locationListener);
744 }
745 }, durationMillis);
746 } catch (IllegalArgumentException e) {
747 Log.w(TAG, "Unable to request location.", e);
748 }
Yu-Han Yange7baef32018-02-09 13:58:17 -0800749 }
750
751 private void injectBestLocation(Location location) {
752 int gnssLocationFlags = LOCATION_HAS_LAT_LONG |
753 (location.hasAltitude() ? LOCATION_HAS_ALTITUDE : 0) |
754 (location.hasSpeed() ? LOCATION_HAS_SPEED : 0) |
755 (location.hasBearing() ? LOCATION_HAS_BEARING : 0) |
756 (location.hasAccuracy() ? LOCATION_HAS_HORIZONTAL_ACCURACY : 0) |
757 (location.hasVerticalAccuracy() ? LOCATION_HAS_VERTICAL_ACCURACY : 0) |
758 (location.hasSpeedAccuracy() ? LOCATION_HAS_SPEED_ACCURACY : 0) |
759 (location.hasBearingAccuracy() ? LOCATION_HAS_BEARING_ACCURACY : 0);
760
761 double latitudeDegrees = location.getLatitude();
762 double longitudeDegrees = location.getLongitude();
763 double altitudeMeters = location.getAltitude();
764 float speedMetersPerSec = location.getSpeed();
765 float bearingDegrees = location.getBearing();
766 float horizontalAccuracyMeters = location.getAccuracy();
767 float verticalAccuracyMeters = location.getVerticalAccuracyMeters();
768 float speedAccuracyMetersPerSecond = location.getSpeedAccuracyMetersPerSecond();
769 float bearingAccuracyDegrees = location.getBearingAccuracyDegrees();
770 long timestamp = location.getTime();
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -0800771
772 int elapsedRealtimeFlags = ELAPSED_REALTIME_HAS_TIMESTAMP_NS;
773 long elapsedRealtimeNanos = location.getElapsedRealtimeNanos();
774
775 native_inject_best_location(
776 gnssLocationFlags, latitudeDegrees, longitudeDegrees,
777 altitudeMeters, speedMetersPerSec, bearingDegrees,
778 horizontalAccuracyMeters, verticalAccuracyMeters,
779 speedAccuracyMetersPerSecond, bearingAccuracyDegrees, timestamp,
780 elapsedRealtimeFlags, elapsedRealtimeNanos);
Yu-Han Yange7baef32018-02-09 13:58:17 -0800781 }
782
Yu-Han Yange7baef32018-02-09 13:58:17 -0800783 /** Returns true if the location request is too frequent. */
784 private boolean isRequestLocationRateLimited() {
Anil Admal316f9482019-02-12 18:57:18 -0800785 // TODO: implement exponential backoff.
Yu-Han Yange7baef32018-02-09 13:58:17 -0800786 return false;
787 }
788
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400789 private void handleDownloadXtraData() {
Wyatt Riley0d6e54e22016-10-05 12:03:03 -0700790 if (!mSupportsXtra) {
791 // native code reports xtra not supported, don't try
792 Log.d(TAG, "handleDownloadXtraData() called when Xtra not supported");
793 return;
794 }
Kevin Tang40e1baf2012-01-10 14:32:44 -0800795 if (mDownloadXtraDataPending == STATE_DOWNLOADING) {
796 // already downloading data
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400797 return;
798 }
Anil Admal50ba15e2018-11-01 16:42:42 -0700799 if (!mNetworkConnectivityHandler.isDataNetworkConnected()) {
Kevin Tang40e1baf2012-01-10 14:32:44 -0800800 // try again when network is up
801 mDownloadXtraDataPending = STATE_PENDING_NETWORK;
802 return;
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400803 }
Kevin Tang40e1baf2012-01-10 14:32:44 -0800804 mDownloadXtraDataPending = STATE_DOWNLOADING;
805
Jeff Brown028872f2012-08-25 13:07:01 -0700806 // hold wake lock while task runs
Wei Wangb71c0492017-05-01 20:24:19 -0700807 mDownloadXtraWakeLock.acquire(DOWNLOAD_XTRA_DATA_TIMEOUT_MS);
Lifu Tangcbd2a142016-06-22 10:57:55 -0700808 Log.i(TAG, "WakeLock acquired by handleDownloadXtraData()");
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700809 AsyncTask.THREAD_POOL_EXECUTOR.execute(() -> {
Anil Admald71cf142018-12-21 14:59:36 -0800810 GpsXtraDownloader xtraDownloader = new GpsXtraDownloader(
811 mGnssConfiguration.getProperties());
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700812 byte[] data = xtraDownloader.downloadXtraData();
813 if (data != null) {
814 if (DEBUG) Log.d(TAG, "calling native_inject_xtra_data");
815 native_inject_xtra_data(data, data.length);
816 mXtraBackOff.reset();
817 }
Kevin Tang40e1baf2012-01-10 14:32:44 -0800818
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700819 sendMessage(DOWNLOAD_XTRA_DATA_FINISHED, 0, null);
Kevin Tang40e1baf2012-01-10 14:32:44 -0800820
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700821 if (data == null) {
822 // try again later
823 // since this is delayed and not urgent we do not hold a wake lock here
824 mHandler.sendEmptyMessageDelayed(DOWNLOAD_XTRA_DATA,
825 mXtraBackOff.nextBackoffMillis());
826 }
Kevin Tang40e1baf2012-01-10 14:32:44 -0800827
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700828 // Release wake lock held by task, synchronize on mLock in case multiple
829 // download tasks overrun.
830 synchronized (mLock) {
831 if (mDownloadXtraWakeLock.isHeld()) {
832 // This wakelock may have time-out, if a timeout was specified.
833 // Catch (and ignore) any timeout exceptions.
834 try {
835 mDownloadXtraWakeLock.release();
836 if (DEBUG) Log.d(TAG, "WakeLock released by handleDownloadXtraData()");
837 } catch (Exception e) {
838 Log.i(TAG, "Wakelock timeout & release race exception in "
839 + "handleDownloadXtraData()", e);
Wei Wangb71c0492017-05-01 20:24:19 -0700840 }
Soonil Nagarkar1575a042018-10-24 17:54:54 -0700841 } else {
842 Log.e(TAG, "WakeLock expired before release in "
843 + "handleDownloadXtraData()");
Wei Wangc5706f62017-04-18 11:26:26 -0700844 }
Jeff Brown028872f2012-08-25 13:07:01 -0700845 }
Kevin Tang40e1baf2012-01-10 14:32:44 -0800846 });
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800847 }
848
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400849 private void handleUpdateLocation(Location location) {
Mike Lockwoodd26ce0d2009-06-11 12:25:46 -0400850 if (location.hasAccuracy()) {
851 native_inject_location(location.getLatitude(), location.getLongitude(),
852 location.getAccuracy());
853 }
Mike Lockwoodfd6e5f02009-05-21 11:28:20 -0400854 }
855
Anil Admald71cf142018-12-21 14:59:36 -0800856 private void setSuplHostPort() {
857 mSuplServerHost = mGnssConfiguration.getSuplHost();
858 mSuplServerPort = mGnssConfiguration.getSuplPort(TCP_MIN_PORT);
Tsuwei Chen678c13c2014-09-22 17:48:41 -0700859 if (mSuplServerHost != null
860 && mSuplServerPort > TCP_MIN_PORT
861 && mSuplServerPort <= TCP_MAX_PORT) {
Anil Admalc70344b2018-11-16 14:22:38 -0800862 native_set_agps_server(GnssNetworkConnectivityHandler.AGPS_TYPE_SUPL,
863 mSuplServerHost, mSuplServerPort);
Tsuwei Chen678c13c2014-09-22 17:48:41 -0700864 }
Tsuwei Chen52617bb2014-08-25 11:49:11 -0700865 }
866
Tsuwei Chen462bcd82014-09-17 12:28:49 -0700867 /**
868 * Checks what SUPL mode to use, according to the AGPS mode as well as the
869 * allowed mode from properties.
870 *
Tsuwei Chen462bcd82014-09-17 12:28:49 -0700871 * @param agpsEnabled whether AGPS is enabled by settings value
Tsuwei Chen462bcd82014-09-17 12:28:49 -0700872 * @return SUPL mode (MSA vs MSB vs STANDALONE)
873 */
Yu-Han Yang6a5f0b72019-01-24 18:34:28 -0800874 private int getSuplMode(boolean agpsEnabled) {
Tsuwei Chen462bcd82014-09-17 12:28:49 -0700875 if (agpsEnabled) {
Anil Admald71cf142018-12-21 14:59:36 -0800876 int suplMode = mGnssConfiguration.getSuplMode(0);
877 if (suplMode == 0) {
878 return GPS_POSITION_MODE_STANDALONE;
Tsuwei Chen462bcd82014-09-17 12:28:49 -0700879 }
Anil Admald71cf142018-12-21 14:59:36 -0800880
destradaabfb3bdb2015-04-29 14:42:35 -0700881 // MS-Based is the preferred mode for Assisted-GPS position computation, so we favor
882 // such mode when it is available
883 if (hasCapability(GPS_CAPABILITY_MSB) && (suplMode & AGPS_SUPL_MODE_MSB) != 0) {
884 return GPS_POSITION_MODE_MS_BASED;
885 }
Tsuwei Chen462bcd82014-09-17 12:28:49 -0700886 }
887 return GPS_POSITION_MODE_STANDALONE;
888 }
889
Soonil Nagarkar35c3b912019-01-31 10:31:24 -0800890 private boolean handleEnable() {
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400891 if (DEBUG) Log.d(TAG, "handleEnable");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800892
Soonil Nagarkar35c3b912019-01-31 10:31:24 -0800893 boolean inited = native_init();
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700894
Soonil Nagarkar35c3b912019-01-31 10:31:24 -0800895 if (inited) {
Mike Lockwood1a1cd3a2010-08-17 07:42:54 -0400896 mSupportsXtra = native_supports_xtra();
Tsuwei Chen678c13c2014-09-22 17:48:41 -0700897
898 // TODO: remove the following native calls if we can make sure they are redundant.
Mike Lockwood734d6032009-07-28 18:30:25 -0700899 if (mSuplServerHost != null) {
Anil Admalc70344b2018-11-16 14:22:38 -0800900 native_set_agps_server(GnssNetworkConnectivityHandler.AGPS_TYPE_SUPL,
901 mSuplServerHost, mSuplServerPort);
Mike Lockwood734d6032009-07-28 18:30:25 -0700902 }
903 if (mC2KServerHost != null) {
Anil Admalc70344b2018-11-16 14:22:38 -0800904 native_set_agps_server(GnssNetworkConnectivityHandler.AGPS_TYPE_C2K,
905 mC2KServerHost, mC2KServerPort);
Mike Lockwood734d6032009-07-28 18:30:25 -0700906 }
destradaa13a60b02015-01-15 18:36:01 -0800907
Lifu Tang818aa2c2016-02-01 01:52:00 -0800908 mGnssMeasurementsProvider.onGpsEnabledChanged();
909 mGnssNavigationMessageProvider.onGpsEnabledChanged();
Yu-Han Yang3557cc72018-03-21 12:48:36 -0700910 mGnssBatchingProvider.enable();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800911 } else {
912 Log.w(TAG, "Failed to enable location provider");
913 }
Soonil Nagarkar35c3b912019-01-31 10:31:24 -0800914
915 return inited;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800916 }
917
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400918 private void handleDisable() {
Mike Lockwood89096312010-03-24 10:14:55 -0400919 if (DEBUG) Log.d(TAG, "handleDisable");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800920
David Christie3bc26142013-12-19 14:53:44 -0800921 updateClientUids(new WorkSource());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800922 stopNavigating();
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700923 mAlarmManager.cancel(mWakeupIntent);
924 mAlarmManager.cancel(mTimeoutIntent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800925
Yu-Han Yang3557cc72018-03-21 12:48:36 -0700926 mGnssBatchingProvider.disable();
Mike Lockwoodcf1d8cb2010-01-20 10:14:54 -0500927 // do this before releasing wakelock
928 native_cleanup();
destradaa13a60b02015-01-15 18:36:01 -0800929
Lifu Tang818aa2c2016-02-01 01:52:00 -0800930 mGnssMeasurementsProvider.onGpsEnabledChanged();
931 mGnssNavigationMessageProvider.onGpsEnabledChanged();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800932 }
933
Soonil Nagarkar35c3b912019-01-31 10:31:24 -0800934 private void updateEnabled() {
935 synchronized (mLock) {
936 boolean enabled =
937 ((mProviderRequest != null && mProviderRequest.reportLocation
Soonil Nagarkar509580f2019-02-06 15:57:26 -0800938 && mProviderRequest.locationSettingsIgnored) || (
Soonil Nagarkar35c3b912019-01-31 10:31:24 -0800939 mContext.getSystemService(LocationManager.class).isLocationEnabled()
940 && !mDisableGps)) && !mShutdown;
941 if (enabled == mEnabled) {
942 return;
943 }
944
945 if (enabled) {
946 mEnabled = handleEnable();
947 } else {
948 mEnabled = false;
949 handleDisable();
950 }
951 }
952 }
953
Mike Lockwoodd03ff942010-02-09 08:46:14 -0500954 public boolean isEnabled() {
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700955 synchronized (mLock) {
956 return mEnabled;
957 }
Mike Lockwoodd03ff942010-02-09 08:46:14 -0500958 }
959
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700960 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800961 public int getStatus(Bundle extras) {
Wyatt Rileyc7067412018-02-07 15:50:35 -0800962 mLocationExtras.setBundle(extras);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800963 return mStatus;
964 }
965
Wyatt Rileyc7067412018-02-07 15:50:35 -0800966 private void updateStatus(int status) {
967 if (status != mStatus) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800968 mStatus = status;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800969 mStatusUpdateTime = SystemClock.elapsedRealtime();
970 }
971 }
972
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700973 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800974 public long getStatusUpdateTime() {
975 return mStatusUpdateTime;
976 }
977
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700978 @Override
979 public void setRequest(ProviderRequest request, WorkSource source) {
980 sendMessage(SET_REQUEST, 0, new GpsRequest(request, source));
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400981 }
982
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700983 private void handleSetRequest(ProviderRequest request, WorkSource source) {
David Christied4edf4c2014-08-12 15:22:27 -0700984 mProviderRequest = request;
985 mWorkSource = source;
Soonil Nagarkar35c3b912019-01-31 10:31:24 -0800986 updateEnabled();
David Christied4edf4c2014-08-12 15:22:27 -0700987 updateRequirements();
988 }
989
990 // Called when the requirements for GPS may have changed
991 private void updateRequirements() {
992 if (mProviderRequest == null || mWorkSource == null) {
993 return;
994 }
995
David Christied4edf4c2014-08-12 15:22:27 -0700996 if (DEBUG) Log.d(TAG, "setRequest " + mProviderRequest);
Soonil Nagarkar41153fd2019-02-12 15:02:37 -0800997 if (mProviderRequest.reportLocation && isEnabled()) {
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700998 // update client uids
David Christied4edf4c2014-08-12 15:22:27 -0700999 updateClientUids(mWorkSource);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001000
David Christied4edf4c2014-08-12 15:22:27 -07001001 mFixInterval = (int) mProviderRequest.interval;
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001002 mLowPowerMode = mProviderRequest.lowPowerMode;
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001003 // check for overflow
David Christied4edf4c2014-08-12 15:22:27 -07001004 if (mFixInterval != mProviderRequest.interval) {
1005 Log.w(TAG, "interval overflow: " + mProviderRequest.interval);
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001006 mFixInterval = Integer.MAX_VALUE;
1007 }
Mike Lockwood03ca2162010-04-01 08:10:09 -07001008
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001009 // apply request to GPS engine
Mike Lockwood04598b62010-04-14 17:17:24 -04001010 if (mStarted && hasCapability(GPS_CAPABILITY_SCHEDULING)) {
gomo48f1a642017-11-10 20:35:46 -08001011 // change period and/or lowPowerMode
Yu-Han Yangc8b9ff72018-04-17 00:47:24 -07001012 if (!setPositionMode(mPositionMode, GPS_POSITION_RECURRENCE_PERIODIC,
gomo48f1a642017-11-10 20:35:46 -08001013 mFixInterval, 0, 0, mLowPowerMode)) {
1014 Log.e(TAG, "set_position_mode failed in updateRequirements");
Mike Lockwood04598b62010-04-14 17:17:24 -04001015 }
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001016 } else if (!mStarted) {
1017 // start GPS
Yu-Han Yang6a5f0b72019-01-24 18:34:28 -08001018 startNavigating();
gomo300b2402017-12-13 19:04:12 -08001019 } else {
1020 // GNSS Engine is already ON, but no GPS_CAPABILITY_SCHEDULING
1021 mAlarmManager.cancel(mTimeoutIntent);
1022 if (mFixInterval >= NO_FIX_TIMEOUT) {
1023 // set timer to give up if we do not receive a fix within NO_FIX_TIMEOUT
1024 // and our fix interval is not short
1025 mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001026 SystemClock.elapsedRealtime() + NO_FIX_TIMEOUT, mTimeoutIntent);
1027 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001028 }
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001029 } else {
Dianne Hackborn002a54e2013-01-10 17:34:55 -08001030 updateClientUids(new WorkSource());
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001031
1032 stopNavigating();
1033 mAlarmManager.cancel(mWakeupIntent);
1034 mAlarmManager.cancel(mTimeoutIntent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001035 }
1036 }
1037
Yu-Han Yangc8b9ff72018-04-17 00:47:24 -07001038 private boolean setPositionMode(int mode, int recurrence, int minInterval,
1039 int preferredAccuracy, int preferredTime, boolean lowPowerMode) {
1040 GnssPositionMode positionMode = new GnssPositionMode(mode, recurrence, minInterval,
1041 preferredAccuracy, preferredTime, lowPowerMode);
1042 if (mLastPositionMode != null && mLastPositionMode.equals(positionMode)) {
1043 return true;
1044 }
1045
1046 boolean result = native_set_position_mode(mode, recurrence, minInterval,
1047 preferredAccuracy, preferredTime, lowPowerMode);
1048 if (result) {
1049 mLastPositionMode = positionMode;
1050 } else {
1051 mLastPositionMode = null;
1052 }
1053 return result;
1054 }
1055
Dianne Hackborn002a54e2013-01-10 17:34:55 -08001056 private void updateClientUids(WorkSource source) {
Narayan Kamath32684dd2018-01-08 17:32:51 +00001057 if (source.equals(mClientSource)) {
Victoria Leaseea78b852013-01-15 10:39:28 -08001058 return;
1059 }
Dianne Hackborn002a54e2013-01-10 17:34:55 -08001060
Narayan Kamath32684dd2018-01-08 17:32:51 +00001061 // (1) Inform BatteryStats that the list of IDs we're tracking changed.
1062 try {
1063 mBatteryStats.noteGpsChanged(mClientSource, source);
1064 } catch (RemoteException e) {
1065 Log.w(TAG, "RemoteException", e);
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001066 }
1067
Narayan Kamath32684dd2018-01-08 17:32:51 +00001068 // (2) Inform AppOps service about the list of changes to UIDs.
1069
1070 List<WorkChain>[] diffs = WorkSource.diffChains(mClientSource, source);
1071 if (diffs != null) {
1072 List<WorkChain> newChains = diffs[0];
1073 List<WorkChain> goneChains = diffs[1];
1074
1075 if (newChains != null) {
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001076 for (WorkChain newChain : newChains) {
Svet Ganovf7b47252018-02-26 11:11:27 -08001077 mAppOps.startOpNoThrow(AppOpsManager.OP_GPS, newChain.getAttributionUid(),
1078 newChain.getAttributionTag());
Narayan Kamath32684dd2018-01-08 17:32:51 +00001079 }
1080 }
1081
1082 if (goneChains != null) {
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001083 for (WorkChain goneChain : goneChains) {
Svet Ganovf7b47252018-02-26 11:11:27 -08001084 mAppOps.finishOp(AppOpsManager.OP_GPS, goneChain.getAttributionUid(),
1085 goneChain.getAttributionTag());
Narayan Kamath32684dd2018-01-08 17:32:51 +00001086 }
1087 }
1088
1089 mClientSource.transferWorkChains(source);
1090 }
1091
1092 // Update the flat UIDs and names list and inform app-ops of all changes.
1093 WorkSource[] changes = mClientSource.setReturningDiffs(source);
1094 if (changes != null) {
1095 WorkSource newWork = changes[0];
1096 WorkSource goneWork = changes[1];
1097
1098 // Update sources that were not previously tracked.
1099 if (newWork != null) {
1100 for (int i = 0; i < newWork.size(); i++) {
Svet Ganovf7b47252018-02-26 11:11:27 -08001101 mAppOps.startOpNoThrow(AppOpsManager.OP_GPS,
1102 newWork.get(i), newWork.getName(i));
Narayan Kamath32684dd2018-01-08 17:32:51 +00001103 }
1104 }
1105
1106 // Update sources that are no longer tracked.
1107 if (goneWork != null) {
1108 for (int i = 0; i < goneWork.size(); i++) {
Svet Ganovf7b47252018-02-26 11:11:27 -08001109 mAppOps.finishOp(AppOpsManager.OP_GPS, goneWork.get(i), goneWork.getName(i));
Dianne Hackborn2e418422009-06-22 20:00:17 -07001110 }
Mike Lockwood2f82c4e2009-04-17 08:24:10 -04001111 }
1112 }
1113 }
1114
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001115 @Override
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001116 public void sendExtraCommand(String command, Bundle extras) {
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001117
Mike Lockwood63aa5a62010-04-14 19:21:31 -04001118 long identity = Binder.clearCallingIdentity();
Peter Visontayb25db362017-11-01 18:18:12 +00001119 try {
Peter Visontayb25db362017-11-01 18:18:12 +00001120 if ("delete_aiding_data".equals(command)) {
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001121 deleteAidingData(extras);
Peter Visontayb25db362017-11-01 18:18:12 +00001122 } else if ("force_time_injection".equals(command)) {
1123 requestUtcTime();
Peter Visontayb25db362017-11-01 18:18:12 +00001124 } else if ("force_xtra_injection".equals(command)) {
1125 if (mSupportsXtra) {
1126 xtraDownloadRequest();
Peter Visontayb25db362017-11-01 18:18:12 +00001127 }
1128 } else {
1129 Log.w(TAG, "sendExtraCommand: unknown command " + command);
Mike Lockwood93bc44d2009-05-20 16:58:22 -04001130 }
Peter Visontayb25db362017-11-01 18:18:12 +00001131 } finally {
1132 Binder.restoreCallingIdentity(identity);
Mike Lockwood93bc44d2009-05-20 16:58:22 -04001133 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001134 }
1135
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001136 private void deleteAidingData(Bundle extras) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001137 int flags;
1138
1139 if (extras == null) {
1140 flags = GPS_DELETE_ALL;
1141 } else {
1142 flags = 0;
1143 if (extras.getBoolean("ephemeris")) flags |= GPS_DELETE_EPHEMERIS;
1144 if (extras.getBoolean("almanac")) flags |= GPS_DELETE_ALMANAC;
1145 if (extras.getBoolean("position")) flags |= GPS_DELETE_POSITION;
1146 if (extras.getBoolean("time")) flags |= GPS_DELETE_TIME;
1147 if (extras.getBoolean("iono")) flags |= GPS_DELETE_IONO;
1148 if (extras.getBoolean("utc")) flags |= GPS_DELETE_UTC;
1149 if (extras.getBoolean("health")) flags |= GPS_DELETE_HEALTH;
1150 if (extras.getBoolean("svdir")) flags |= GPS_DELETE_SVDIR;
1151 if (extras.getBoolean("svsteer")) flags |= GPS_DELETE_SVSTEER;
1152 if (extras.getBoolean("sadata")) flags |= GPS_DELETE_SADATA;
1153 if (extras.getBoolean("rti")) flags |= GPS_DELETE_RTI;
1154 if (extras.getBoolean("celldb-info")) flags |= GPS_DELETE_CELLDB_INFO;
1155 if (extras.getBoolean("all")) flags |= GPS_DELETE_ALL;
1156 }
1157
1158 if (flags != 0) {
1159 native_delete_aiding_data(flags);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001160 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001161 }
1162
Yu-Han Yang6a5f0b72019-01-24 18:34:28 -08001163 private void startNavigating() {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001164 if (!mStarted) {
Yu-Han Yang6a5f0b72019-01-24 18:34:28 -08001165 if (DEBUG) Log.d(TAG, "startNavigating");
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001166 mTimeToFirstFix = 0;
1167 mLastFixTime = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001168 mStarted = true;
Mike Lockwood03ca2162010-04-01 08:10:09 -07001169 mPositionMode = GPS_POSITION_MODE_STANDALONE;
Wyatt Riley5d5bac82016-11-01 07:05:16 -07001170 // Notify about suppressed output, if speed limit was previously exceeded.
1171 // Elsewhere, we check again with every speed output reported.
1172 if (mItarSpeedLimitExceeded) {
1173 Log.i(TAG, "startNavigating with ITAR limit in place. Output limited " +
1174 "until slow enough speed reported.");
1175 }
Mike Lockwood03ca2162010-04-01 08:10:09 -07001176
Tsuwei Chen462bcd82014-09-17 12:28:49 -07001177 boolean agpsEnabled =
1178 (Settings.Global.getInt(mContext.getContentResolver(),
gomo48f1a642017-11-10 20:35:46 -08001179 Settings.Global.ASSISTED_GPS_ENABLED, 1) != 0);
Yu-Han Yang6a5f0b72019-01-24 18:34:28 -08001180 mPositionMode = getSuplMode(agpsEnabled);
Mike Lockwoodbcab8df2009-06-25 16:39:09 -04001181
Stan Chesnutt1d72d8c2013-04-15 19:18:02 -07001182 if (DEBUG) {
1183 String mode;
1184
gomo48f1a642017-11-10 20:35:46 -08001185 switch (mPositionMode) {
Stan Chesnutt1d72d8c2013-04-15 19:18:02 -07001186 case GPS_POSITION_MODE_STANDALONE:
1187 mode = "standalone";
1188 break;
1189 case GPS_POSITION_MODE_MS_ASSISTED:
1190 mode = "MS_ASSISTED";
1191 break;
1192 case GPS_POSITION_MODE_MS_BASED:
1193 mode = "MS_BASED";
1194 break;
1195 default:
1196 mode = "unknown";
1197 break;
1198 }
1199 Log.d(TAG, "setting position_mode to " + mode);
1200 }
1201
Mike Lockwood04598b62010-04-14 17:17:24 -04001202 int interval = (hasCapability(GPS_CAPABILITY_SCHEDULING) ? mFixInterval : 1000);
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001203 mLowPowerMode = mProviderRequest.lowPowerMode;
Yu-Han Yangc8b9ff72018-04-17 00:47:24 -07001204 if (!setPositionMode(mPositionMode, GPS_POSITION_RECURRENCE_PERIODIC,
gomo48f1a642017-11-10 20:35:46 -08001205 interval, 0, 0, mLowPowerMode)) {
Mike Lockwood04598b62010-04-14 17:17:24 -04001206 mStarted = false;
1207 Log.e(TAG, "set_position_mode failed in startNavigating()");
1208 return;
1209 }
1210 if (!native_start()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001211 mStarted = false;
1212 Log.e(TAG, "native_start failed in startNavigating()");
Mike Lockwood0632ca72009-05-14 15:51:03 -04001213 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001214 }
1215
1216 // reset SV count to zero
Wyatt Rileyc7067412018-02-07 15:50:35 -08001217 updateStatus(LocationProvider.TEMPORARILY_UNAVAILABLE);
1218 mLocationExtras.reset();
Yipeng Cao282b5942017-05-17 20:31:39 -07001219 mFixRequestTime = SystemClock.elapsedRealtime();
Mike Lockwood04598b62010-04-14 17:17:24 -04001220 if (!hasCapability(GPS_CAPABILITY_SCHEDULING)) {
1221 // set timer to give up if we do not receive a fix within NO_FIX_TIMEOUT
1222 // and our fix interval is not short
1223 if (mFixInterval >= NO_FIX_TIMEOUT) {
1224 mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
1225 SystemClock.elapsedRealtime() + NO_FIX_TIMEOUT, mTimeoutIntent);
1226 }
Mike Lockwood0632ca72009-05-14 15:51:03 -04001227 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001228 }
1229 }
1230
Mike Lockwood62a8fc12010-03-22 14:23:26 -04001231 private void stopNavigating() {
Mike Lockwood29c84342009-05-06 14:01:15 -04001232 if (DEBUG) Log.d(TAG, "stopNavigating");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001233 if (mStarted) {
1234 mStarted = false;
1235 native_stop();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001236 mLastFixTime = 0;
Yu-Han Yanga50cd602018-08-28 12:33:24 -07001237 // native_stop() may reset the position mode in hardware.
1238 mLastPositionMode = null;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001239
1240 // reset SV count to zero
Wyatt Rileyc7067412018-02-07 15:50:35 -08001241 updateStatus(LocationProvider.TEMPORARILY_UNAVAILABLE);
1242 mLocationExtras.reset();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001243 }
1244 }
1245
Mike Lockwood0632ca72009-05-14 15:51:03 -04001246 private void hibernate() {
1247 // stop GPS until our next fix interval arrives
1248 stopNavigating();
Mike Lockwood0632ca72009-05-14 15:51:03 -04001249 mAlarmManager.cancel(mTimeoutIntent);
1250 mAlarmManager.cancel(mWakeupIntent);
1251 long now = SystemClock.elapsedRealtime();
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001252 mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, now + mFixInterval, mWakeupIntent);
Mike Lockwood04598b62010-04-14 17:17:24 -04001253 }
1254
1255 private boolean hasCapability(int capability) {
1256 return ((mEngineCapabilities & capability) != 0);
Mike Lockwood0632ca72009-05-14 15:51:03 -04001257 }
1258
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001259 @NativeEntryPoint
Wyatt Riley5d229832017-02-10 17:06:00 -08001260 private void reportLocation(boolean hasLatLong, Location location) {
Wyatt Riley26465d22018-02-12 13:44:24 -08001261 sendMessage(REPORT_LOCATION, hasLatLong ? 1 : 0, location);
1262 }
1263
1264 private void handleReportLocation(boolean hasLatLong, Location location) {
Wyatt Riley5d229832017-02-10 17:06:00 -08001265 if (location.hasSpeed()) {
1266 mItarSpeedLimitExceeded = location.getSpeed() > ITAR_SPEED_LIMIT_METERS_PER_SECOND;
Wyatt Riley5d5bac82016-11-01 07:05:16 -07001267 }
1268
1269 if (mItarSpeedLimitExceeded) {
1270 Log.i(TAG, "Hal reported a speed in excess of ITAR limit." +
1271 " GPS/GNSS Navigation output blocked.");
Siddharth Ray53ddc802018-03-16 12:01:52 -07001272 if (mStarted) {
1273 mGnssMetrics.logReceivedLocationStatus(false);
1274 }
Wyatt Riley5d5bac82016-11-01 07:05:16 -07001275 return; // No output of location allowed
1276 }
1277
Wyatt Riley5d229832017-02-10 17:06:00 -08001278 if (VERBOSE) Log.v(TAG, "reportLocation " + location.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001279
Wyatt Riley26465d22018-02-12 13:44:24 -08001280 location.setExtras(mLocationExtras.getBundle());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001281
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001282 reportLocation(location);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001283
Siddharth Ray53ddc802018-03-16 12:01:52 -07001284 if (mStarted) {
1285 mGnssMetrics.logReceivedLocationStatus(hasLatLong);
1286 if (hasLatLong) {
1287 if (location.hasAccuracy()) {
1288 mGnssMetrics.logPositionAccuracyMeters(location.getAccuracy());
1289 }
1290 if (mTimeToFirstFix > 0) {
1291 int timeBetweenFixes = (int) (SystemClock.elapsedRealtime() - mLastFixTime);
1292 mGnssMetrics.logMissedReports(mFixInterval, timeBetweenFixes);
1293 }
Siddharth Raybb608c82017-03-16 11:33:34 -07001294 }
1295 }
1296
Yipeng Cao282b5942017-05-17 20:31:39 -07001297 mLastFixTime = SystemClock.elapsedRealtime();
Hakan Gustavssonfa94ff02010-02-23 09:12:38 +01001298 // report time to first fix
Wyatt Riley5d229832017-02-10 17:06:00 -08001299 if (mTimeToFirstFix == 0 && hasLatLong) {
gomo48f1a642017-11-10 20:35:46 -08001300 mTimeToFirstFix = (int) (mLastFixTime - mFixRequestTime);
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001301 if (DEBUG) Log.d(TAG, "TTFF: " + mTimeToFirstFix);
Siddharth Ray53ddc802018-03-16 12:01:52 -07001302 if (mStarted) {
1303 mGnssMetrics.logTimeToFirstFixMilliSecs(mTimeToFirstFix);
1304 }
Hakan Gustavssonfa94ff02010-02-23 09:12:38 +01001305
1306 // notify status listeners
Anil Admal75b9fd62018-11-28 11:22:50 -08001307 mGnssStatusListenerHelper.onFirstFix(mTimeToFirstFix);
Hakan Gustavssonfa94ff02010-02-23 09:12:38 +01001308 }
1309
Mike Lockwood15e3d0f2009-05-01 07:53:28 -04001310 if (mStarted && mStatus != LocationProvider.AVAILABLE) {
Wyatt Rileyc7067412018-02-07 15:50:35 -08001311 // For devices that use framework scheduling, a timer may be set to ensure we don't
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001312 // spend too much power searching for a location, when the requested update rate is
1313 // slow.
Wyatt Rileyc7067412018-02-07 15:50:35 -08001314 // As we just recievied a location, we'll cancel that timer.
Mike Lockwood04598b62010-04-14 17:17:24 -04001315 if (!hasCapability(GPS_CAPABILITY_SCHEDULING) && mFixInterval < NO_FIX_TIMEOUT) {
Mike Lockwoodb7be5442010-02-24 14:34:50 -05001316 mAlarmManager.cancel(mTimeoutIntent);
1317 }
1318
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001319 // send an intent to notify that the GPS is receiving fixes.
Mike Lockwood00b74272010-03-26 10:41:48 -04001320 Intent intent = new Intent(LocationManager.GPS_FIX_CHANGE_ACTION);
1321 intent.putExtra(LocationManager.EXTRA_GPS_ENABLED, true);
Dianne Hackborn5ac72a22012-08-29 18:32:08 -07001322 mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
Wyatt Rileyc7067412018-02-07 15:50:35 -08001323 updateStatus(LocationProvider.AVAILABLE);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001324 }
Mike Lockwood29c84342009-05-06 14:01:15 -04001325
gomo48f1a642017-11-10 20:35:46 -08001326 if (!hasCapability(GPS_CAPABILITY_SCHEDULING) && mStarted &&
1327 mFixInterval > GPS_POLLING_THRESHOLD_INTERVAL) {
Mike Lockwoodd53ba012010-04-15 20:41:26 -04001328 if (DEBUG) Log.d(TAG, "got fix, hibernating");
Mike Lockwood0632ca72009-05-14 15:51:03 -04001329 hibernate();
Mike Lockwood29c84342009-05-06 14:01:15 -04001330 }
gomo48f1a642017-11-10 20:35:46 -08001331 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001332
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001333 @NativeEntryPoint
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001334 private void reportStatus(int status) {
Mike Lockwoodb8d90332010-10-18 17:59:48 -04001335 if (DEBUG) Log.v(TAG, "reportStatus status: " + status);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001336
destradaaea8a8a62014-06-23 18:19:03 -07001337 boolean wasNavigating = mNavigating;
1338 switch (status) {
1339 case GPS_STATUS_SESSION_BEGIN:
1340 mNavigating = true;
destradaaea8a8a62014-06-23 18:19:03 -07001341 break;
1342 case GPS_STATUS_SESSION_END:
1343 mNavigating = false;
1344 break;
1345 case GPS_STATUS_ENGINE_ON:
destradaaea8a8a62014-06-23 18:19:03 -07001346 break;
1347 case GPS_STATUS_ENGINE_OFF:
destradaaea8a8a62014-06-23 18:19:03 -07001348 mNavigating = false;
1349 break;
1350 }
Mike Lockwooddbd6fd82009-12-07 18:43:36 -05001351
destradaaea8a8a62014-06-23 18:19:03 -07001352 if (wasNavigating != mNavigating) {
Anil Admal75b9fd62018-11-28 11:22:50 -08001353 mGnssStatusListenerHelper.onStatusChanged(mNavigating);
Mike Lockwoodcf1d8cb2010-01-20 10:14:54 -05001354
destradaaea8a8a62014-06-23 18:19:03 -07001355 // send an intent to notify that the GPS has been enabled or disabled
1356 Intent intent = new Intent(LocationManager.GPS_ENABLED_CHANGE_ACTION);
1357 intent.putExtra(LocationManager.EXTRA_GPS_ENABLED, mNavigating);
1358 mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001359 }
1360 }
1361
Wyatt Riley26465d22018-02-12 13:44:24 -08001362 // Helper class to carry data to handler for reportSvStatus
1363 private static class SvStatusInfo {
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001364 private int mSvCount;
1365 private int[] mSvidWithFlags;
1366 private float[] mCn0s;
1367 private float[] mSvElevations;
1368 private float[] mSvAzimuths;
1369 private float[] mSvCarrierFreqs;
Wyatt Riley26465d22018-02-12 13:44:24 -08001370 }
1371
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001372 @NativeEntryPoint
Wyatt Riley26465d22018-02-12 13:44:24 -08001373 private void reportSvStatus(int svCount, int[] svidWithFlags, float[] cn0s,
1374 float[] svElevations, float[] svAzimuths, float[] svCarrierFreqs) {
1375 SvStatusInfo svStatusInfo = new SvStatusInfo();
1376 svStatusInfo.mSvCount = svCount;
1377 svStatusInfo.mSvidWithFlags = svidWithFlags;
1378 svStatusInfo.mCn0s = cn0s;
1379 svStatusInfo.mSvElevations = svElevations;
1380 svStatusInfo.mSvAzimuths = svAzimuths;
1381 svStatusInfo.mSvCarrierFreqs = svCarrierFreqs;
1382
1383 sendMessage(REPORT_SV_STATUS, 0, svStatusInfo);
1384 }
1385
1386 private void handleReportSvStatus(SvStatusInfo info) {
Anil Admal75b9fd62018-11-28 11:22:50 -08001387 mGnssStatusListenerHelper.onSvStatusChanged(
Wyatt Riley26465d22018-02-12 13:44:24 -08001388 info.mSvCount,
1389 info.mSvidWithFlags,
1390 info.mCn0s,
1391 info.mSvElevations,
1392 info.mSvAzimuths,
1393 info.mSvCarrierFreqs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001394
Siddharth Ray168f12a2017-07-10 11:55:10 -07001395 // Log CN0 as part of GNSS metrics
Wyatt Riley26465d22018-02-12 13:44:24 -08001396 mGnssMetrics.logCn0(info.mCn0s, info.mSvCount);
Siddharth Ray168f12a2017-07-10 11:55:10 -07001397
Mike Lockwood29c84342009-05-06 14:01:15 -04001398 if (VERBOSE) {
Wyatt Riley26465d22018-02-12 13:44:24 -08001399 Log.v(TAG, "SV count: " + info.mSvCount);
Lifu Tang30f95a72016-01-07 23:20:38 -08001400 }
Wyatt Rileyc9f25dd2017-05-05 13:45:23 -07001401 // Calculate number of satellites used in fix.
Lifu Tang30f95a72016-01-07 23:20:38 -08001402 int usedInFixCount = 0;
Wyatt Rileyc9f25dd2017-05-05 13:45:23 -07001403 int maxCn0 = 0;
1404 int meanCn0 = 0;
Wyatt Riley26465d22018-02-12 13:44:24 -08001405 for (int i = 0; i < info.mSvCount; i++) {
1406 if ((info.mSvidWithFlags[i] & GnssStatus.GNSS_SV_FLAGS_USED_IN_FIX) != 0) {
Lifu Tang30f95a72016-01-07 23:20:38 -08001407 ++usedInFixCount;
Wyatt Riley26465d22018-02-12 13:44:24 -08001408 if (info.mCn0s[i] > maxCn0) {
1409 maxCn0 = (int) info.mCn0s[i];
Wyatt Rileyc9f25dd2017-05-05 13:45:23 -07001410 }
Wyatt Riley26465d22018-02-12 13:44:24 -08001411 meanCn0 += info.mCn0s[i];
Lifu Tang30f95a72016-01-07 23:20:38 -08001412 }
1413 if (VERBOSE) {
Wyatt Riley26465d22018-02-12 13:44:24 -08001414 Log.v(TAG, "svid: " + (info.mSvidWithFlags[i] >> GnssStatus.SVID_SHIFT_WIDTH) +
1415 " cn0: " + info.mCn0s[i] +
1416 " elev: " + info.mSvElevations[i] +
1417 " azimuth: " + info.mSvAzimuths[i] +
1418 " carrier frequency: " + info.mSvCarrierFreqs[i] +
1419 ((info.mSvidWithFlags[i] & GnssStatus.GNSS_SV_FLAGS_HAS_EPHEMERIS_DATA) == 0
Lifu Tang30f95a72016-01-07 23:20:38 -08001420 ? " " : " E") +
Wyatt Riley26465d22018-02-12 13:44:24 -08001421 ((info.mSvidWithFlags[i] & GnssStatus.GNSS_SV_FLAGS_HAS_ALMANAC_DATA) == 0
Lifu Tang30f95a72016-01-07 23:20:38 -08001422 ? " " : " A") +
Wyatt Riley26465d22018-02-12 13:44:24 -08001423 ((info.mSvidWithFlags[i] & GnssStatus.GNSS_SV_FLAGS_USED_IN_FIX) == 0
gomo4402af62017-01-11 13:20:13 -08001424 ? "" : "U") +
Wyatt Riley26465d22018-02-12 13:44:24 -08001425 ((info.mSvidWithFlags[i] &
1426 GnssStatus.GNSS_SV_FLAGS_HAS_CARRIER_FREQUENCY) == 0
gomo48f1a642017-11-10 20:35:46 -08001427 ? "" : "F"));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001428 }
1429 }
Wyatt Rileyc9f25dd2017-05-05 13:45:23 -07001430 if (usedInFixCount > 0) {
1431 meanCn0 /= usedInFixCount;
1432 }
1433 // return number of sats used in fix instead of total reported
Wyatt Rileyc7067412018-02-07 15:50:35 -08001434 mLocationExtras.set(usedInFixCount, meanCn0, maxCn0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001435
Mike Lockwood15e3d0f2009-05-01 07:53:28 -04001436 if (mNavigating && mStatus == LocationProvider.AVAILABLE && mLastFixTime > 0 &&
gomo48f1a642017-11-10 20:35:46 -08001437 SystemClock.elapsedRealtime() - mLastFixTime > RECENT_FIX_TIMEOUT) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001438 // send an intent to notify that the GPS is no longer receiving fixes.
Mike Lockwood00b74272010-03-26 10:41:48 -04001439 Intent intent = new Intent(LocationManager.GPS_FIX_CHANGE_ACTION);
1440 intent.putExtra(LocationManager.EXTRA_GPS_ENABLED, false);
Dianne Hackborn5ac72a22012-08-29 18:32:08 -07001441 mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
Wyatt Rileyc7067412018-02-07 15:50:35 -08001442 updateStatus(LocationProvider.TEMPORARILY_UNAVAILABLE);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001443 }
1444 }
Mike Lockwood58bda982009-04-14 16:25:07 -04001445
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001446 @NativeEntryPoint
Anil Admalc70344b2018-11-16 14:22:38 -08001447 private void reportAGpsStatus(int agpsType, int agpsStatus, byte[] suplIpAddr) {
1448 mNetworkConnectivityHandler.onReportAGpsStatus(agpsType, agpsStatus, suplIpAddr);
destradaae21252a2015-09-08 12:32:59 -07001449 }
1450
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001451 @NativeEntryPoint
Mike Lockwoodf602d362010-06-20 14:28:16 -07001452 private void reportNmea(long timestamp) {
Wyatt Riley5d5bac82016-11-01 07:05:16 -07001453 if (!mItarSpeedLimitExceeded) {
1454 int length = native_read_nmea(mNmeaBuffer, mNmeaBuffer.length);
1455 String nmea = new String(mNmeaBuffer, 0 /* offset */, length);
Anil Admal75b9fd62018-11-28 11:22:50 -08001456 mGnssStatusListenerHelper.onNmeaReceived(timestamp, nmea);
Wyatt Riley5d5bac82016-11-01 07:05:16 -07001457 }
destradaaea8a8a62014-06-23 18:19:03 -07001458 }
Mike Lockwoodb16e7802009-08-06 09:26:02 -04001459
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001460 @NativeEntryPoint
Lifu Tang818aa2c2016-02-01 01:52:00 -08001461 private void reportMeasurementData(GnssMeasurementsEvent 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(() -> mGnssMeasurementsProvider.onMeasurementsAvailable(event));
Wyatt Riley5d5bac82016-11-01 07:05:16 -07001465 }
Mike Lockwoodb16e7802009-08-06 09:26:02 -04001466 }
1467
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001468 @NativeEntryPoint
Lifu Tange8abe8e2016-04-01 10:32:05 -07001469 private void reportNavigationMessage(GnssNavigationMessage event) {
Wyatt Riley5d5bac82016-11-01 07:05:16 -07001470 if (!mItarSpeedLimitExceeded) {
Wyatt Rileyaa420d52017-07-03 15:14:42 -07001471 // send to handler to allow native to return quickly
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001472 mHandler.post(() -> mGnssNavigationMessageProvider.onNavigationMessageAvailable(event));
Wyatt Riley5d5bac82016-11-01 07:05:16 -07001473 }
destradaa4b3e3932014-07-21 18:01:47 -07001474 }
1475
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001476 @NativeEntryPoint
Wyatt Rileyd87cf912017-12-05 09:31:52 -08001477 private void setEngineCapabilities(final int capabilities) {
1478 // send to handler thread for fast native return, and in-order handling
gomo226b7b72018-12-12 16:49:39 -08001479 mHandler.post(
1480 () -> {
1481 mEngineCapabilities = capabilities;
Mike Lockwood9b9fb5c2011-06-29 15:09:40 -04001482
gomo226b7b72018-12-12 16:49:39 -08001483 if (hasCapability(GPS_CAPABILITY_ON_DEMAND_TIME)) {
1484 mNtpTimeHelper.enablePeriodicTimeInjection();
1485 requestUtcTime();
1486 }
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001487
gomo226b7b72018-12-12 16:49:39 -08001488 mGnssMeasurementsProvider.onCapabilitiesUpdated(capabilities);
1489 mGnssNavigationMessageProvider.onCapabilitiesUpdated(
1490 hasCapability(GPS_CAPABILITY_NAV_MESSAGES));
1491 restartRequests();
1492 });
Yu-Han Yang52057622018-04-25 00:51:22 -07001493 }
1494
1495 private void restartRequests() {
1496 Log.i(TAG, "restartRequests");
1497
1498 restartLocationRequest();
1499 mGnssMeasurementsProvider.resumeIfStarted();
1500 mGnssNavigationMessageProvider.resumeIfStarted();
1501 mGnssBatchingProvider.resumeIfStarted();
1502 mGnssGeofenceProvider.resumeIfStarted();
1503 }
1504
1505 private void restartLocationRequest() {
1506 if (DEBUG) Log.d(TAG, "restartLocationRequest");
1507 mStarted = false;
1508 updateRequirements();
1509 }
Wyatt Rileyd87cf912017-12-05 09:31:52 -08001510
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001511 @NativeEntryPoint
Wyatt Rileyd87cf912017-12-05 09:31:52 -08001512 private void setGnssYearOfHardware(final int yearOfHardware) {
1513 // mHardwareYear is simply set here, to be read elsewhere, and is volatile for safe sync
1514 if (DEBUG) Log.d(TAG, "setGnssYearOfHardware called with " + yearOfHardware);
1515 mHardwareYear = yearOfHardware;
Mike Lockwood04598b62010-04-14 17:17:24 -04001516 }
1517
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001518 @NativeEntryPoint
Wyatt Rileyd87cf912017-12-05 09:31:52 -08001519 private void setGnssHardwareModelName(final String modelName) {
1520 // mHardwareModelName is simply set here, to be read elsewhere, and volatile for safe sync
1521 if (DEBUG) Log.d(TAG, "setGnssModelName called with " + modelName);
1522 mHardwareModelName = modelName;
Lifu Tang82f893d2016-01-21 18:15:33 -08001523 }
1524
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001525 @NativeEntryPoint
Yu-Han Yang52057622018-04-25 00:51:22 -07001526 private void reportGnssServiceDied() {
1527 if (DEBUG) Log.d(TAG, "reportGnssServiceDied");
1528 mHandler.post(() -> {
1529 class_init_native();
1530 native_init_once();
1531 if (isEnabled()) {
Soonil Nagarkar35c3b912019-01-31 10:31:24 -08001532 synchronized (mLock) {
1533 mEnabled = false;
1534 }
1535 updateEnabled();
1536
Yu-Han Yang52057622018-04-25 00:51:22 -07001537 // resend configuration into the restarted HAL service.
Anil Admald71cf142018-12-21 14:59:36 -08001538 reloadGpsProperties();
Yu-Han Yang52057622018-04-25 00:51:22 -07001539 }
1540 });
1541 }
1542
Lifu Tang9363b942016-02-16 18:07:00 -08001543 public interface GnssSystemInfoProvider {
Lifu Tang82f893d2016-01-21 18:15:33 -08001544 /**
Wyatt Rileyd87cf912017-12-05 09:31:52 -08001545 * Returns the year of underlying GPS hardware.
Lifu Tang82f893d2016-01-21 18:15:33 -08001546 */
Lifu Tang9363b942016-02-16 18:07:00 -08001547 int getGnssYearOfHardware();
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001548
Wyatt Rileyd87cf912017-12-05 09:31:52 -08001549 /**
1550 * Returns the model name of underlying GPS hardware.
1551 */
1552 String getGnssHardwareModelName();
Lifu Tang82f893d2016-01-21 18:15:33 -08001553 }
1554
1555 /**
1556 * @hide
1557 */
Lifu Tang9363b942016-02-16 18:07:00 -08001558 public GnssSystemInfoProvider getGnssSystemInfoProvider() {
1559 return new GnssSystemInfoProvider() {
Lifu Tang82f893d2016-01-21 18:15:33 -08001560 @Override
Lifu Tang9363b942016-02-16 18:07:00 -08001561 public int getGnssYearOfHardware() {
Wyatt Rileyd87cf912017-12-05 09:31:52 -08001562 return mHardwareYear;
1563 }
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001564
Wyatt Rileyd87cf912017-12-05 09:31:52 -08001565 @Override
1566 public String getGnssHardwareModelName() {
1567 return mHardwareModelName;
Lifu Tang82f893d2016-01-21 18:15:33 -08001568 }
1569 };
1570 }
1571
Wyatt Rileycf879db2017-01-12 13:57:38 -08001572 /**
1573 * @hide
1574 */
1575 public GnssBatchingProvider getGnssBatchingProvider() {
Yu-Han Yang3557cc72018-03-21 12:48:36 -07001576 return mGnssBatchingProvider;
Wyatt Rileycf879db2017-01-12 13:57:38 -08001577 }
1578
Siddharth Raybb608c82017-03-16 11:33:34 -07001579 public interface GnssMetricsProvider {
1580 /**
1581 * Returns GNSS metrics as proto string
1582 */
1583 String getGnssMetricsAsProtoString();
1584 }
1585
1586 /**
1587 * @hide
1588 */
1589 public GnssMetricsProvider getGnssMetricsProvider() {
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001590 return () -> mGnssMetrics.dumpGnssMetricsAsProtoString();
Siddharth Raybb608c82017-03-16 11:33:34 -07001591 }
1592
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001593 @NativeEntryPoint
Wyatt Rileycf879db2017-01-12 13:57:38 -08001594 private void reportLocationBatch(Location[] locationArray) {
1595 List<Location> locations = new ArrayList<>(Arrays.asList(locationArray));
gomo48f1a642017-11-10 20:35:46 -08001596 if (DEBUG) {
1597 Log.d(TAG, "Location batch of size " + locationArray.length + " reported");
1598 }
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001599 reportLocation(locations);
Wyatt Rileycf879db2017-01-12 13:57:38 -08001600 }
1601
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001602 @NativeEntryPoint
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001603 private void xtraDownloadRequest() {
Joe Onoratof5d95cb2010-01-07 21:48:32 -05001604 if (DEBUG) Log.d(TAG, "xtraDownloadRequest");
Mike Lockwood98e48692010-04-07 16:32:51 -04001605 sendMessage(DOWNLOAD_XTRA_DATA, 0, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001606 }
1607
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07001608 /**
destradaa0682809a2013-08-12 18:50:30 -07001609 * Converts the GPS HAL status to the internal Geofence Hardware status.
1610 */
Yu-Han Yang6dc9f052018-12-04 17:11:24 -08001611 private static int getGeofenceStatus(int status) {
gomo48f1a642017-11-10 20:35:46 -08001612 switch (status) {
destradaa0682809a2013-08-12 18:50:30 -07001613 case GPS_GEOFENCE_OPERATION_SUCCESS:
1614 return GeofenceHardware.GEOFENCE_SUCCESS;
1615 case GPS_GEOFENCE_ERROR_GENERIC:
1616 return GeofenceHardware.GEOFENCE_FAILURE;
1617 case GPS_GEOFENCE_ERROR_ID_EXISTS:
1618 return GeofenceHardware.GEOFENCE_ERROR_ID_EXISTS;
1619 case GPS_GEOFENCE_ERROR_INVALID_TRANSITION:
1620 return GeofenceHardware.GEOFENCE_ERROR_INVALID_TRANSITION;
1621 case GPS_GEOFENCE_ERROR_TOO_MANY_GEOFENCES:
1622 return GeofenceHardware.GEOFENCE_ERROR_TOO_MANY_GEOFENCES;
1623 case GPS_GEOFENCE_ERROR_ID_UNKNOWN:
1624 return GeofenceHardware.GEOFENCE_ERROR_ID_UNKNOWN;
1625 default:
1626 return -1;
1627 }
1628 }
1629
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001630 @NativeEntryPoint
Wyatt Riley5d229832017-02-10 17:06:00 -08001631 private void reportGeofenceTransition(int geofenceId, Location location, int transition,
gomo48f1a642017-11-10 20:35:46 -08001632 long transitionTimestamp) {
Yu-Han Yang6dc9f052018-12-04 17:11:24 -08001633 mHandler.post(() -> {
1634 if (mGeofenceHardwareImpl == null) {
1635 mGeofenceHardwareImpl = GeofenceHardwareImpl.getInstance(mContext);
1636 }
Wyatt Riley5d229832017-02-10 17:06:00 -08001637
Yu-Han Yang6dc9f052018-12-04 17:11:24 -08001638 mGeofenceHardwareImpl.reportGeofenceTransition(
1639 geofenceId,
1640 location,
1641 transition,
1642 transitionTimestamp,
1643 GeofenceHardware.MONITORING_TYPE_GPS_HARDWARE,
1644 FusedBatchOptions.SourceTechnologies.GNSS);
1645 });
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07001646 }
1647
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001648 @NativeEntryPoint
Wyatt Riley5d229832017-02-10 17:06:00 -08001649 private void reportGeofenceStatus(int status, Location location) {
Yu-Han Yang6dc9f052018-12-04 17:11:24 -08001650 mHandler.post(() -> {
1651 if (mGeofenceHardwareImpl == null) {
1652 mGeofenceHardwareImpl = GeofenceHardwareImpl.getInstance(mContext);
1653 }
1654 int monitorStatus = GeofenceHardware.MONITOR_CURRENTLY_UNAVAILABLE;
1655 if (status == GPS_GEOFENCE_AVAILABLE) {
1656 monitorStatus = GeofenceHardware.MONITOR_CURRENTLY_AVAILABLE;
1657 }
1658 mGeofenceHardwareImpl.reportGeofenceMonitorStatus(
1659 GeofenceHardware.MONITORING_TYPE_GPS_HARDWARE,
1660 monitorStatus,
1661 location,
1662 FusedBatchOptions.SourceTechnologies.GNSS);
1663 });
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07001664 }
1665
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001666 @NativeEntryPoint
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07001667 private void reportGeofenceAddStatus(int geofenceId, int status) {
Yu-Han Yang6dc9f052018-12-04 17:11:24 -08001668 mHandler.post(() -> {
1669 if (mGeofenceHardwareImpl == null) {
1670 mGeofenceHardwareImpl = GeofenceHardwareImpl.getInstance(mContext);
1671 }
1672 mGeofenceHardwareImpl.reportGeofenceAddStatus(geofenceId, getGeofenceStatus(status));
1673 });
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07001674 }
1675
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001676 @NativeEntryPoint
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07001677 private void reportGeofenceRemoveStatus(int geofenceId, int status) {
Yu-Han Yang6dc9f052018-12-04 17:11:24 -08001678 mHandler.post(() -> {
1679 if (mGeofenceHardwareImpl == null) {
1680 mGeofenceHardwareImpl = GeofenceHardwareImpl.getInstance(mContext);
1681 }
1682 mGeofenceHardwareImpl.reportGeofenceRemoveStatus(geofenceId, getGeofenceStatus(status));
1683 });
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07001684 }
1685
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001686 @NativeEntryPoint
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07001687 private void reportGeofencePauseStatus(int geofenceId, int status) {
Yu-Han Yang6dc9f052018-12-04 17:11:24 -08001688 mHandler.post(() -> {
1689 if (mGeofenceHardwareImpl == null) {
1690 mGeofenceHardwareImpl = GeofenceHardwareImpl.getInstance(mContext);
1691 }
1692 mGeofenceHardwareImpl.reportGeofencePauseStatus(geofenceId, getGeofenceStatus(status));
1693 });
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07001694 }
1695
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001696 @NativeEntryPoint
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07001697 private void reportGeofenceResumeStatus(int geofenceId, int status) {
Yu-Han Yang6dc9f052018-12-04 17:11:24 -08001698 mHandler.post(() -> {
1699 if (mGeofenceHardwareImpl == null) {
1700 mGeofenceHardwareImpl = GeofenceHardwareImpl.getInstance(mContext);
1701 }
1702 mGeofenceHardwareImpl.reportGeofenceResumeStatus(geofenceId, getGeofenceStatus(status));
1703 });
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07001704 }
1705
Danke Xie22d1f9f2009-08-18 18:28:45 -04001706 //=============================================================
1707 // NI Client support
Miguel Torroja1e84da82010-07-27 07:02:24 +02001708 //=============================================================
Danke Xie22d1f9f2009-08-18 18:28:45 -04001709 private final INetInitiatedListener mNetInitiatedListener = new INetInitiatedListener.Stub() {
destradaaef752b62015-04-17 13:10:47 -07001710 // Sends a response for an NI request to HAL.
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001711 @Override
gomo48f1a642017-11-10 20:35:46 -08001712 public boolean sendNiResponse(int notificationId, int userResponse) {
Miguel Torroja1e84da82010-07-27 07:02:24 +02001713 // TODO Add Permission check
Danke Xie22d1f9f2009-08-18 18:28:45 -04001714
gomo48f1a642017-11-10 20:35:46 -08001715 if (DEBUG) {
1716 Log.d(TAG, "sendNiResponse, notifId: " + notificationId +
1717 ", response: " + userResponse);
1718 }
Miguel Torroja1e84da82010-07-27 07:02:24 +02001719 native_send_ni_response(notificationId, userResponse);
Yu-Han Yang8a1b51d2018-12-26 22:18:31 -08001720
1721 StatsLog.write(StatsLog.GNSS_NI_EVENT_REPORTED,
1722 StatsLog.GNSS_NI_EVENT_REPORTED__EVENT_TYPE__NI_RESPONSE,
1723 notificationId,
1724 /* niType= */ 0,
1725 /* needNotify= */ false,
1726 /* needVerify= */ false,
1727 /* privacyOverride= */ false,
1728 /* timeout= */ 0,
1729 /* defaultResponse= */ 0,
1730 /* requestorId= */ null,
1731 /* text= */ null,
1732 /* requestorIdEncoding= */ 0,
1733 /* textEncoding= */ 0,
1734 mSuplEsEnabled,
Soonil Nagarkar35c3b912019-01-31 10:31:24 -08001735 isEnabled(),
Yu-Han Yang8a1b51d2018-12-26 22:18:31 -08001736 userResponse);
1737
Miguel Torroja1e84da82010-07-27 07:02:24 +02001738 return true;
1739 }
Danke Xie22d1f9f2009-08-18 18:28:45 -04001740 };
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001741
Danke Xie22d1f9f2009-08-18 18:28:45 -04001742 public INetInitiatedListener getNetInitiatedListener() {
1743 return mNetInitiatedListener;
1744 }
1745
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001746 /** Reports a NI notification. */
1747 @NativeEntryPoint
Miguel Torroja1e84da82010-07-27 07:02:24 +02001748 public void reportNiNotification(
1749 int notificationId,
1750 int niType,
1751 int notifyFlags,
1752 int timeout,
1753 int defaultResponse,
1754 String requestorId,
1755 String text,
1756 int requestorIdEncoding,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001757 int textEncoding
gomo48f1a642017-11-10 20:35:46 -08001758 ) {
Miguel Torroja1e84da82010-07-27 07:02:24 +02001759 Log.i(TAG, "reportNiNotification: entered");
1760 Log.i(TAG, "notificationId: " + notificationId +
1761 ", niType: " + niType +
1762 ", notifyFlags: " + notifyFlags +
1763 ", timeout: " + timeout +
1764 ", defaultResponse: " + defaultResponse);
1765
1766 Log.i(TAG, "requestorId: " + requestorId +
1767 ", text: " + text +
1768 ", requestorIdEncoding: " + requestorIdEncoding +
1769 ", textEncoding: " + textEncoding);
1770
1771 GpsNiNotification notification = new GpsNiNotification();
1772
1773 notification.notificationId = notificationId;
1774 notification.niType = niType;
1775 notification.needNotify = (notifyFlags & GpsNetInitiatedHandler.GPS_NI_NEED_NOTIFY) != 0;
1776 notification.needVerify = (notifyFlags & GpsNetInitiatedHandler.GPS_NI_NEED_VERIFY) != 0;
gomo48f1a642017-11-10 20:35:46 -08001777 notification.privacyOverride =
1778 (notifyFlags & GpsNetInitiatedHandler.GPS_NI_PRIVACY_OVERRIDE) != 0;
Miguel Torroja1e84da82010-07-27 07:02:24 +02001779 notification.timeout = timeout;
1780 notification.defaultResponse = defaultResponse;
1781 notification.requestorId = requestorId;
1782 notification.text = text;
1783 notification.requestorIdEncoding = requestorIdEncoding;
1784 notification.textEncoding = textEncoding;
1785
Miguel Torroja1e84da82010-07-27 07:02:24 +02001786 mNIHandler.handleNiNotification(notification);
Yu-Han Yang8a1b51d2018-12-26 22:18:31 -08001787 StatsLog.write(StatsLog.GNSS_NI_EVENT_REPORTED,
1788 StatsLog.GNSS_NI_EVENT_REPORTED__EVENT_TYPE__NI_REQUEST,
1789 notification.notificationId,
1790 notification.niType,
1791 notification.needNotify,
1792 notification.needVerify,
1793 notification.privacyOverride,
1794 notification.timeout,
1795 notification.defaultResponse,
1796 notification.requestorId,
1797 notification.text,
1798 notification.requestorIdEncoding,
1799 notification.textEncoding,
1800 mSuplEsEnabled,
Soonil Nagarkar35c3b912019-01-31 10:31:24 -08001801 isEnabled(),
Yu-Han Yang8a1b51d2018-12-26 22:18:31 -08001802 /* userResponse= */ 0);
Miguel Torroja1e84da82010-07-27 07:02:24 +02001803 }
1804
1805 /**
Miguel Torroja1e84da82010-07-27 07:02:24 +02001806 * We should be careful about receiving null string from the TelephonyManager,
1807 * because sending null String to JNI function would cause a crash.
1808 */
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001809 @NativeEntryPoint
Miguel Torroja1e84da82010-07-27 07:02:24 +02001810 private void requestSetID(int flags) {
1811 TelephonyManager phone = (TelephonyManager)
1812 mContext.getSystemService(Context.TELEPHONY_SERVICE);
destradaaef752b62015-04-17 13:10:47 -07001813 int type = AGPS_SETID_TYPE_NONE;
Miguel Torroja1e84da82010-07-27 07:02:24 +02001814 String data = "";
1815
1816 if ((flags & AGPS_RIL_REQUEST_SETID_IMSI) == AGPS_RIL_REQUEST_SETID_IMSI) {
1817 String data_temp = phone.getSubscriberId();
1818 if (data_temp == null) {
1819 // This means the framework does not have the SIM card ready.
1820 } else {
1821 // This means the framework has the SIM card.
1822 data = data_temp;
1823 type = AGPS_SETID_TYPE_IMSI;
1824 }
gomo48f1a642017-11-10 20:35:46 -08001825 } else if ((flags & AGPS_RIL_REQUEST_SETID_MSISDN) == AGPS_RIL_REQUEST_SETID_MSISDN) {
Miguel Torroja1e84da82010-07-27 07:02:24 +02001826 String data_temp = phone.getLine1Number();
1827 if (data_temp == null) {
1828 // This means the framework does not have the SIM card ready.
1829 } else {
1830 // This means the framework has the SIM card.
1831 data = data_temp;
1832 type = AGPS_SETID_TYPE_MSISDN;
1833 }
1834 }
1835 native_agps_set_id(type, data);
1836 }
1837
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001838 @NativeEntryPoint
Yu-Han Yang53f4d6d2019-02-13 21:47:41 -08001839 private void requestLocation(boolean independentFromGnss, boolean isUserEmergency) {
Yu-Han Yange7baef32018-02-09 13:58:17 -08001840 if (DEBUG) {
Yu-Han Yang53f4d6d2019-02-13 21:47:41 -08001841 Log.d(TAG, "requestLocation. independentFromGnss: " + independentFromGnss
1842 + ", isUserEmergency: "
1843 + isUserEmergency);
Yu-Han Yange7baef32018-02-09 13:58:17 -08001844 }
Yu-Han Yang53f4d6d2019-02-13 21:47:41 -08001845 sendMessage(REQUEST_LOCATION, independentFromGnss ? 1 : 0, isUserEmergency);
Yu-Han Yange7baef32018-02-09 13:58:17 -08001846 }
1847
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001848 @NativeEntryPoint
Mike Lockwood9b9fb5c2011-06-29 15:09:40 -04001849 private void requestUtcTime() {
destradaae21252a2015-09-08 12:32:59 -07001850 if (DEBUG) Log.d(TAG, "utcTimeRequest");
Mike Lockwood9b9fb5c2011-06-29 15:09:40 -04001851 sendMessage(INJECT_NTP_TIME, 0, null);
1852 }
1853
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001854 @NativeEntryPoint
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07001855 private void requestRefLocation() {
Miguel Torroja1e84da82010-07-27 07:02:24 +02001856 TelephonyManager phone = (TelephonyManager)
1857 mContext.getSystemService(Context.TELEPHONY_SERVICE);
Victoria Leased50d0c32012-10-29 13:16:17 -07001858 final int phoneType = phone.getPhoneType();
1859 if (phoneType == TelephonyManager.PHONE_TYPE_GSM) {
Miguel Torroja1e84da82010-07-27 07:02:24 +02001860 GsmCellLocation gsm_cell = (GsmCellLocation) phone.getCellLocation();
Victoria Leased50d0c32012-10-29 13:16:17 -07001861 if ((gsm_cell != null) && (phone.getNetworkOperator() != null)
1862 && (phone.getNetworkOperator().length() > 3)) {
Miguel Torroja1e84da82010-07-27 07:02:24 +02001863 int type;
gomo48f1a642017-11-10 20:35:46 -08001864 int mcc = Integer.parseInt(phone.getNetworkOperator().substring(0, 3));
Miguel Torroja1e84da82010-07-27 07:02:24 +02001865 int mnc = Integer.parseInt(phone.getNetworkOperator().substring(3));
Mike Lockwoodedc0f3872010-10-22 09:16:17 -04001866 int networkType = phone.getNetworkType();
1867 if (networkType == TelephonyManager.NETWORK_TYPE_UMTS
gomo48f1a642017-11-10 20:35:46 -08001868 || networkType == TelephonyManager.NETWORK_TYPE_HSDPA
1869 || networkType == TelephonyManager.NETWORK_TYPE_HSUPA
1870 || networkType == TelephonyManager.NETWORK_TYPE_HSPA
1871 || networkType == TelephonyManager.NETWORK_TYPE_HSPAP) {
Miguel Torroja1e84da82010-07-27 07:02:24 +02001872 type = AGPS_REF_LOCATION_TYPE_UMTS_CELLID;
Mike Lockwoodedc0f3872010-10-22 09:16:17 -04001873 } else {
Miguel Torroja1e84da82010-07-27 07:02:24 +02001874 type = AGPS_REF_LOCATION_TYPE_GSM_CELLID;
Mike Lockwoodedc0f3872010-10-22 09:16:17 -04001875 }
Miguel Torroja1e84da82010-07-27 07:02:24 +02001876 native_agps_set_ref_location_cellid(type, mcc, mnc,
1877 gsm_cell.getLac(), gsm_cell.getCid());
Mike Lockwoodedc0f3872010-10-22 09:16:17 -04001878 } else {
gomo48f1a642017-11-10 20:35:46 -08001879 Log.e(TAG, "Error getting cell location info.");
Mike Lockwoodedc0f3872010-10-22 09:16:17 -04001880 }
Victoria Leased50d0c32012-10-29 13:16:17 -07001881 } else if (phoneType == TelephonyManager.PHONE_TYPE_CDMA) {
1882 Log.e(TAG, "CDMA not supported.");
Mike Lockwoodedc0f3872010-10-22 09:16:17 -04001883 }
Miguel Torroja1e84da82010-07-27 07:02:24 +02001884 }
Danke Xie22d1f9f2009-08-18 18:28:45 -04001885
Anil Admal94ec76a2019-01-15 09:42:01 -08001886 // Implements method nfwNotifyCb() in IGnssVisibilityControlCallback.hal.
1887 @NativeEntryPoint
1888 private void reportNfwNotification(String proxyAppPackageName, byte protocolStack,
1889 String otherProtocolStackName, byte requestor, String requestorId, byte responseType,
1890 boolean inEmergencyMode, boolean isCachedLocation) {
1891 if (mGnssVisibilityControl == null) {
1892 Log.e(TAG, "reportNfwNotification: mGnssVisibilityControl is not initialized.");
1893 return;
1894 }
1895
1896 mGnssVisibilityControl.reportNfwNotification(proxyAppPackageName, protocolStack,
1897 otherProtocolStackName, requestor, requestorId, responseType, inEmergencyMode,
1898 isCachedLocation);
1899 }
1900
1901 // Implements method isInEmergencySession() in IGnssVisibilityControlCallback.hal.
1902 @NativeEntryPoint
1903 boolean isInEmergencySession() {
1904 return mNIHandler.getInEmergency();
1905 }
1906
Mike Lockwood98e48692010-04-07 16:32:51 -04001907 private void sendMessage(int message, int arg, Object obj) {
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001908 // hold a wake lock until this message is delivered
Jeff Brown028872f2012-08-25 13:07:01 -07001909 // note that this assumes the message will not be removed from the queue before
1910 // it is handled (otherwise the wake lock would be leaked).
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001911 mWakeLock.acquire();
Anil Admal4f97c942018-11-12 10:52:46 -08001912 if (DEBUG) {
1913 Log.d(TAG, "WakeLock acquired by sendMessage(" + messageIdAsString(message) + ", " + arg
Wyatt Rileycf879db2017-01-12 13:57:38 -08001914 + ", " + obj + ")");
1915 }
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001916 mHandler.obtainMessage(message, arg, 1, obj).sendToTarget();
Mike Lockwood98e48692010-04-07 16:32:51 -04001917 }
1918
Mike Lockwood62a8fc12010-03-22 14:23:26 -04001919 private final class ProviderHandler extends Handler {
Victoria Lease5cd731a2012-12-19 15:04:21 -08001920 public ProviderHandler(Looper looper) {
1921 super(looper, null, true /*async*/);
Jeff Brown028872f2012-08-25 13:07:01 -07001922 }
1923
Mike Lockwood62a8fc12010-03-22 14:23:26 -04001924 @Override
Mike Lockwood4a7b65e2010-10-25 16:35:55 -04001925 public void handleMessage(Message msg) {
Mike Lockwood98e48692010-04-07 16:32:51 -04001926 int message = msg.what;
1927 switch (message) {
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001928 case SET_REQUEST:
1929 GpsRequest gpsRequest = (GpsRequest) msg.obj;
1930 handleSetRequest(gpsRequest.request, gpsRequest.source);
Mike Lockwood03ca2162010-04-01 08:10:09 -07001931 break;
Mike Lockwood62a8fc12010-03-22 14:23:26 -04001932 case INJECT_NTP_TIME:
Yu-Han Yanga1862b52018-02-20 17:05:59 -08001933 mNtpTimeHelper.retrieveAndInjectNtpTime();
Mike Lockwood62a8fc12010-03-22 14:23:26 -04001934 break;
Yu-Han Yange7baef32018-02-09 13:58:17 -08001935 case REQUEST_LOCATION:
Yu-Han Yang53f4d6d2019-02-13 21:47:41 -08001936 handleRequestLocation(msg.arg1 == 1, (boolean) msg.obj);
Yu-Han Yange7baef32018-02-09 13:58:17 -08001937 break;
Mike Lockwood62a8fc12010-03-22 14:23:26 -04001938 case DOWNLOAD_XTRA_DATA:
Wyatt Riley0d6e54e22016-10-05 12:03:03 -07001939 handleDownloadXtraData();
Mike Lockwood62a8fc12010-03-22 14:23:26 -04001940 break;
Kevin Tang40e1baf2012-01-10 14:32:44 -08001941 case DOWNLOAD_XTRA_DATA_FINISHED:
1942 mDownloadXtraDataPending = STATE_IDLE;
1943 break;
Mike Lockwood62a8fc12010-03-22 14:23:26 -04001944 case UPDATE_LOCATION:
destradaae21252a2015-09-08 12:32:59 -07001945 handleUpdateLocation((Location) msg.obj);
Mike Lockwood62a8fc12010-03-22 14:23:26 -04001946 break;
Meng Wang19b214d2018-11-07 12:14:39 -08001947 case SUBSCRIPTION_OR_CARRIER_CONFIG_CHANGED:
1948 subscriptionOrCarrierConfigChanged(mContext);
destradaafb23c672015-04-16 14:01:27 -07001949 break;
1950 case INITIALIZE_HANDLER:
destradaae21252a2015-09-08 12:32:59 -07001951 handleInitialize();
destradaafb23c672015-04-16 14:01:27 -07001952 break;
Wyatt Riley26465d22018-02-12 13:44:24 -08001953 case REPORT_LOCATION:
1954 handleReportLocation(msg.arg1 == 1, (Location) msg.obj);
1955 break;
1956 case REPORT_SV_STATUS:
1957 handleReportSvStatus((SvStatusInfo) msg.obj);
1958 break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001959 }
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001960 if (msg.arg2 == 1) {
1961 // wakelock was taken for this message, release it
1962 mWakeLock.release();
Anil Admal4f97c942018-11-12 10:52:46 -08001963 if (DEBUG) {
1964 Log.d(TAG, "WakeLock released by handleMessage(" + messageIdAsString(message)
Wyatt Rileycf879db2017-01-12 13:57:38 -08001965 + ", " + msg.arg1 + ", " + msg.obj + ")");
1966 }
Mike Lockwood98e48692010-04-07 16:32:51 -04001967 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001968 }
destradaafb23c672015-04-16 14:01:27 -07001969
1970 /**
Soonil Nagarkar1575a042018-10-24 17:54:54 -07001971 * This method is bound to {@link #GnssLocationProvider(Context, LocationProviderManager,
1972 * Looper)}.
destradaafb23c672015-04-16 14:01:27 -07001973 * It is in charge of loading properties and registering for events that will be posted to
1974 * this handler.
1975 */
destradaae21252a2015-09-08 12:32:59 -07001976 private void handleInitialize() {
Yu-Han Yang6d317352018-03-15 11:53:01 -07001977 native_init_once();
1978
Wyatt Riley523a0cf2017-10-31 14:36:52 -07001979 /*
1980 * A cycle of native_init() and native_cleanup() is needed so that callbacks are
1981 * registered after bootup even when location is disabled.
1982 * This will allow Emergency SUPL to work even when location is disabled before device
1983 * restart.
1984 */
1985 boolean isInitialized = native_init();
gomo48f1a642017-11-10 20:35:46 -08001986 if (!isInitialized) {
Wyatt Riley523a0cf2017-10-31 14:36:52 -07001987 Log.w(TAG, "Native initialization failed at bootup");
1988 } else {
1989 native_cleanup();
1990 }
1991
Anil Admal94ec76a2019-01-15 09:42:01 -08001992 if (native_is_gnss_visibility_control_supported()) {
1993 mGnssVisibilityControl = new GnssVisibilityControl(mContext, mLooper);
1994 }
1995
destradaafb23c672015-04-16 14:01:27 -07001996 // load default GPS configuration
1997 // (this configuration might change in the future based on SIM changes)
Anil Admald71cf142018-12-21 14:59:36 -08001998 reloadGpsProperties();
destradaafb23c672015-04-16 14:01:27 -07001999
2000 // TODO: When this object "finishes" we should unregister by invoking
gomo48f1a642017-11-10 20:35:46 -08002001 // SubscriptionManager.getInstance(mContext).unregister
2002 // (mOnSubscriptionsChangedListener);
destradaafb23c672015-04-16 14:01:27 -07002003 // This is not strictly necessary because it will be unregistered if the
2004 // notification fails but it is good form.
2005
2006 // Register for SubscriptionInfo list changes which is guaranteed
2007 // to invoke onSubscriptionsChanged the first time.
2008 SubscriptionManager.from(mContext)
2009 .addOnSubscriptionsChangedListener(mOnSubscriptionsChangedListener);
2010
2011 // listen for events
WyattRiley6593cf12018-06-23 10:37:48 -07002012 IntentFilter intentFilter = new IntentFilter();
destradaafb23c672015-04-16 14:01:27 -07002013 intentFilter.addAction(ALARM_WAKEUP);
2014 intentFilter.addAction(ALARM_TIMEOUT);
destradaafb23c672015-04-16 14:01:27 -07002015 intentFilter.addAction(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED);
Adam Lesinski87c17df2015-05-27 13:24:13 -07002016 intentFilter.addAction(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED);
destradaafb23c672015-04-16 14:01:27 -07002017 intentFilter.addAction(Intent.ACTION_SCREEN_OFF);
2018 intentFilter.addAction(Intent.ACTION_SCREEN_ON);
Meng Wang19b214d2018-11-07 12:14:39 -08002019 intentFilter.addAction(CarrierConfigManager.ACTION_CARRIER_CONFIG_CHANGED);
destradaafb23c672015-04-16 14:01:27 -07002020 mContext.registerReceiver(mBroadcastReceiver, intentFilter, null, this);
2021
Anil Admal50ba15e2018-11-01 16:42:42 -07002022 mNetworkConnectivityHandler.registerNetworkCallbacks();
destradaae21252a2015-09-08 12:32:59 -07002023
destradaafb23c672015-04-16 14:01:27 -07002024 // listen for PASSIVE_PROVIDER updates
2025 LocationManager locManager =
2026 (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE);
2027 long minTime = 0;
2028 float minDistance = 0;
destradaafb23c672015-04-16 14:01:27 -07002029 LocationRequest request = LocationRequest.createFromDeprecatedProvider(
2030 LocationManager.PASSIVE_PROVIDER,
2031 minTime,
2032 minDistance,
Soonil Nagarkar1575a042018-10-24 17:54:54 -07002033 false);
destradaafb23c672015-04-16 14:01:27 -07002034 // Don't keep track of this request since it's done on behalf of other clients
2035 // (which are kept track of separately).
2036 request.setHideFromAppOps(true);
2037 locManager.requestLocationUpdates(
2038 request,
2039 new NetworkLocationListener(),
2040 getLooper());
Soonil Nagarkar1575a042018-10-24 17:54:54 -07002041
Soonil Nagarkar35c3b912019-01-31 10:31:24 -08002042 updateEnabled();
destradaafb23c672015-04-16 14:01:27 -07002043 }
2044 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002045
Yu-Han Yange7baef32018-02-09 13:58:17 -08002046 private abstract class LocationChangeListener implements LocationListener {
Soonil Nagarkar1575a042018-10-24 17:54:54 -07002047 private int mNumLocationUpdateRequest;
Yu-Han Yang07561382018-02-21 13:08:37 -08002048
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002049 @Override
gomo48f1a642017-11-10 20:35:46 -08002050 public void onStatusChanged(String provider, int status, Bundle extras) {
2051 }
2052
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002053 @Override
gomo48f1a642017-11-10 20:35:46 -08002054 public void onProviderEnabled(String provider) {
2055 }
2056
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002057 @Override
gomo48f1a642017-11-10 20:35:46 -08002058 public void onProviderDisabled(String provider) {
2059 }
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002060 }
2061
Yu-Han Yange7baef32018-02-09 13:58:17 -08002062 private final class NetworkLocationListener extends LocationChangeListener {
2063 @Override
2064 public void onLocationChanged(Location location) {
2065 // this callback happens on mHandler looper
2066 if (LocationManager.NETWORK_PROVIDER.equals(location.getProvider())) {
2067 handleUpdateLocation(location);
2068 }
2069 }
2070 }
2071
2072 private final class FusedLocationListener extends LocationChangeListener {
2073 @Override
2074 public void onLocationChanged(Location location) {
2075 if (LocationManager.FUSED_PROVIDER.equals(location.getProvider())) {
Yu-Han Yange7baef32018-02-09 13:58:17 -08002076 injectBestLocation(location);
2077 }
2078 }
2079 }
2080
Wyatt Rileycf879db2017-01-12 13:57:38 -08002081 /**
2082 * @return A string representing the given message ID.
2083 */
2084 private String messageIdAsString(int message) {
2085 switch (message) {
Wyatt Rileycf879db2017-01-12 13:57:38 -08002086 case SET_REQUEST:
2087 return "SET_REQUEST";
Wyatt Rileycf879db2017-01-12 13:57:38 -08002088 case INJECT_NTP_TIME:
2089 return "INJECT_NTP_TIME";
Yu-Han Yange7baef32018-02-09 13:58:17 -08002090 case REQUEST_LOCATION:
2091 return "REQUEST_LOCATION";
Wyatt Rileycf879db2017-01-12 13:57:38 -08002092 case DOWNLOAD_XTRA_DATA:
2093 return "DOWNLOAD_XTRA_DATA";
Wyatt Rileycf879db2017-01-12 13:57:38 -08002094 case DOWNLOAD_XTRA_DATA_FINISHED:
2095 return "DOWNLOAD_XTRA_DATA_FINISHED";
2096 case UPDATE_LOCATION:
2097 return "UPDATE_LOCATION";
Meng Wang19b214d2018-11-07 12:14:39 -08002098 case SUBSCRIPTION_OR_CARRIER_CONFIG_CHANGED:
2099 return "SUBSCRIPTION_OR_CARRIER_CONFIG_CHANGED";
Wyatt Rileycf879db2017-01-12 13:57:38 -08002100 case INITIALIZE_HANDLER:
2101 return "INITIALIZE_HANDLER";
Wyatt Riley26465d22018-02-12 13:44:24 -08002102 case REPORT_LOCATION:
2103 return "REPORT_LOCATION";
2104 case REPORT_SV_STATUS:
2105 return "REPORT_SV_STATUS";
Wyatt Rileycf879db2017-01-12 13:57:38 -08002106 default:
2107 return "<Unknown>";
2108 }
2109 }
2110
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002111 @Override
2112 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2113 StringBuilder s = new StringBuilder();
Wyatt Riley77ca4f82017-06-30 18:13:44 -07002114 s.append(" mStarted=").append(mStarted).append('\n');
destradaa25e8caf2015-08-24 14:14:44 -07002115 s.append(" mFixInterval=").append(mFixInterval).append('\n');
gomo48f1a642017-11-10 20:35:46 -08002116 s.append(" mLowPowerMode=").append(mLowPowerMode).append('\n');
Wyatt Riley74479bd2018-01-17 08:48:27 -08002117 s.append(" mGnssMeasurementsProvider.isRegistered()=")
2118 .append(mGnssMeasurementsProvider.isRegistered()).append('\n');
2119 s.append(" mGnssNavigationMessageProvider.isRegistered()=")
2120 .append(mGnssNavigationMessageProvider.isRegistered()).append('\n');
destradaa25e8caf2015-08-24 14:14:44 -07002121 s.append(" mDisableGps (battery saver mode)=").append(mDisableGps).append('\n');
2122 s.append(" mEngineCapabilities=0x").append(Integer.toHexString(mEngineCapabilities));
2123 s.append(" ( ");
2124 if (hasCapability(GPS_CAPABILITY_SCHEDULING)) s.append("SCHEDULING ");
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002125 if (hasCapability(GPS_CAPABILITY_MSB)) s.append("MSB ");
2126 if (hasCapability(GPS_CAPABILITY_MSA)) s.append("MSA ");
2127 if (hasCapability(GPS_CAPABILITY_SINGLE_SHOT)) s.append("SINGLE_SHOT ");
2128 if (hasCapability(GPS_CAPABILITY_ON_DEMAND_TIME)) s.append("ON_DEMAND_TIME ");
destradaa25e8caf2015-08-24 14:14:44 -07002129 if (hasCapability(GPS_CAPABILITY_GEOFENCING)) s.append("GEOFENCING ");
2130 if (hasCapability(GPS_CAPABILITY_MEASUREMENTS)) s.append("MEASUREMENTS ");
2131 if (hasCapability(GPS_CAPABILITY_NAV_MESSAGES)) s.append("NAV_MESSAGES ");
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002132 s.append(")\n");
Siddharth Raybb608c82017-03-16 11:33:34 -07002133 s.append(mGnssMetrics.dumpGnssMetricsAsText());
2134 s.append(" native internal state: ").append(native_get_internal_state());
Wyatt Rileycf879db2017-01-12 13:57:38 -08002135 s.append("\n");
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002136 pw.append(s);
2137 }
2138
Mike Lockwoodb16e7802009-08-06 09:26:02 -04002139 // preallocated to avoid memory allocation in reportNmea()
2140 private byte[] mNmeaBuffer = new byte[120];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002141
gomo48f1a642017-11-10 20:35:46 -08002142 static {
2143 class_init_native();
2144 }
2145
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002146 private static native void class_init_native();
gomo48f1a642017-11-10 20:35:46 -08002147
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002148 private static native boolean native_is_supported();
gomo48f1a642017-11-10 20:35:46 -08002149
Anil Admal94ec76a2019-01-15 09:42:01 -08002150 private static native boolean native_is_gnss_visibility_control_supported();
2151
Yu-Han Yang6d317352018-03-15 11:53:01 -07002152 private static native void native_init_once();
2153
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002154 private native boolean native_init();
gomo48f1a642017-11-10 20:35:46 -08002155
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002156 private native void native_cleanup();
gomo48f1a642017-11-10 20:35:46 -08002157
Mike Lockwood04598b62010-04-14 17:17:24 -04002158 private native boolean native_set_position_mode(int mode, int recurrence, int min_interval,
gomo48f1a642017-11-10 20:35:46 -08002159 int preferred_accuracy, int preferred_time, boolean lowPowerMode);
2160
Mike Lockwood04598b62010-04-14 17:17:24 -04002161 private native boolean native_start();
gomo48f1a642017-11-10 20:35:46 -08002162
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002163 private native boolean native_stop();
gomo48f1a642017-11-10 20:35:46 -08002164
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002165 private native void native_delete_aiding_data(int flags);
gomo48f1a642017-11-10 20:35:46 -08002166
Mike Lockwoodf602d362010-06-20 14:28:16 -07002167 private native int native_read_nmea(byte[] buffer, int bufferSize);
gomo48f1a642017-11-10 20:35:46 -08002168
Yu-Han Yange7baef32018-02-09 13:58:17 -08002169 private native void native_inject_best_location(
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -08002170 int gnssLocationFlags, double latitudeDegrees, double longitudeDegrees,
2171 double altitudeMeters, float speedMetersPerSec, float bearingDegrees,
2172 float horizontalAccuracyMeters, float verticalAccuracyMeters,
2173 float speedAccuracyMetersPerSecond, float bearingAccuracyDegrees,
2174 long timestamp, int elapsedRealtimeFlags, long elapsedRealtimeNanos);
Yu-Han Yange7baef32018-02-09 13:58:17 -08002175
Mike Lockwoodd26ce0d2009-06-11 12:25:46 -04002176 private native void native_inject_location(double latitude, double longitude, float accuracy);
2177
Fred Fettinger3c8fbdf2010-01-04 15:38:13 -06002178 // XTRA Support
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002179 private native void native_inject_time(long time, long timeReference, int uncertainty);
gomo48f1a642017-11-10 20:35:46 -08002180
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002181 private native boolean native_supports_xtra();
gomo48f1a642017-11-10 20:35:46 -08002182
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002183 private native void native_inject_xtra_data(byte[] data, int length);
The Android Open Source Project10592532009-03-18 17:39:46 -07002184
Fred Fettinger3c8fbdf2010-01-04 15:38:13 -06002185 // DEBUG Support
2186 private native String native_get_internal_state();
2187
2188 // AGPS Support
gomo48f1a642017-11-10 20:35:46 -08002189 private native void native_agps_ni_message(byte[] msg, int length);
2190
Mike Lockwooda9e54612009-06-19 14:54:42 -04002191 private native void native_set_agps_server(int type, String hostname, int port);
Danke Xie22d1f9f2009-08-18 18:28:45 -04002192
2193 // Network-initiated (NI) Support
2194 private native void native_send_ni_response(int notificationId, int userResponse);
Miguel Torroja1e84da82010-07-27 07:02:24 +02002195
Anil Admal50ba15e2018-11-01 16:42:42 -07002196 // AGPS ril support
Miguel Torroja1e84da82010-07-27 07:02:24 +02002197 private native void native_agps_set_ref_location_cellid(int type, int mcc, int mnc,
2198 int lac, int cid);
gomo48f1a642017-11-10 20:35:46 -08002199
Miguel Torroja1e84da82010-07-27 07:02:24 +02002200 private native void native_agps_set_id(int type, String setid);
Pierre Fite-Georgelb50cdaf2019-02-25 15:42:45 -08002201}