blob: 03046b6b4eb0b40022a887cf424e61bcf5a5c72e [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;
Kevin Tanga5fe6b22011-06-05 14:25:16 -070027import android.database.Cursor;
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;
35import android.location.IGnssStatusListener;
36import android.location.IGnssStatusProvider;
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -070037import android.location.IGpsGeofenceHardware;
Mike Lockwood4e50b782009-04-03 08:24:43 -070038import android.location.ILocationManager;
Danke Xie22d1f9f2009-08-18 18:28:45 -040039import android.location.INetInitiatedListener;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080040import android.location.Location;
Nick Pelly6fa9ad42012-07-16 12:18:23 -070041import android.location.LocationListener;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080042import android.location.LocationManager;
43import android.location.LocationProvider;
Stan Chesnutt1d72d8c2013-04-15 19:18:02 -070044import android.location.LocationRequest;
Mike Lockwood58bda982009-04-14 16:25:07 -040045import android.net.ConnectivityManager;
destradaae21252a2015-09-08 12:32:59 -070046import android.net.Network;
47import android.net.NetworkCapabilities;
Mike Lockwood03d24672009-10-08 15:45:03 -040048import android.net.NetworkInfo;
destradaae21252a2015-09-08 12:32:59 -070049import android.net.NetworkRequest;
Kevin Tanga5fe6b22011-06-05 14:25:16 -070050import android.net.Uri;
Kevin Tang40e1baf2012-01-10 14:32:44 -080051import android.os.AsyncTask;
Dianne Hackborn91268cf2013-06-13 19:06:50 -070052import android.os.BatteryStats;
Mike Lockwood63aa5a62010-04-14 19:21:31 -040053import android.os.Binder;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080054import android.os.Bundle;
Mike Lockwood62a8fc12010-03-22 14:23:26 -040055import android.os.Handler;
Victoria Lease5cd731a2012-12-19 15:04:21 -080056import android.os.Looper;
Mike Lockwood62a8fc12010-03-22 14:23:26 -040057import android.os.Message;
Yu-Han Yange7baef32018-02-09 13:58:17 -080058import android.os.PersistableBundle;
Mike Lockwood0528b9b2009-05-07 10:12:54 -040059import android.os.PowerManager;
Yu-Han Yange7baef32018-02-09 13:58:17 -080060import android.os.PowerManager.ServiceType;
61import android.os.PowerSaveState;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080062import android.os.RemoteException;
Mike Lockwood2f82c4e2009-04-17 08:24:10 -040063import android.os.ServiceManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080064import android.os.SystemClock;
Colin Cross7c030ed2014-01-28 09:33:53 -080065import android.os.SystemProperties;
Dianne Hackborn5ac72a22012-08-29 18:32:08 -070066import android.os.UserHandle;
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -070067import android.os.WorkSource;
Narayan Kamath32684dd2018-01-08 17:32:51 +000068import android.os.WorkSource.WorkChain;
Mike Lockwoodbcab8df2009-06-25 16:39:09 -040069import android.provider.Settings;
Kevin Tanga5fe6b22011-06-05 14:25:16 -070070import android.provider.Telephony.Carriers;
Miguel Torroja1e84da82010-07-27 07:02:24 +020071import android.provider.Telephony.Sms.Intents;
Yu-Han Yange7baef32018-02-09 13:58:17 -080072import android.telephony.CarrierConfigManager;
Wink Savillea374c3d2014-11-11 11:48:04 -080073import android.telephony.SubscriptionManager;
Wink Savilled09c4ca2014-11-22 10:08:16 -080074import android.telephony.SubscriptionManager.OnSubscriptionsChangedListener;
Miguel Torroja1e84da82010-07-27 07:02:24 +020075import android.telephony.TelephonyManager;
76import android.telephony.gsm.GsmCellLocation;
Colin Cross7c030ed2014-01-28 09:33:53 -080077import android.text.TextUtils;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080078import android.util.Log;
Yu-Han Yanga1862b52018-02-20 17:05:59 -080079
jackqdyulei455e90a2017-02-09 15:29:16 -080080import com.android.internal.app.IBatteryStats;
81import com.android.internal.location.GpsNetInitiatedHandler;
82import com.android.internal.location.GpsNetInitiatedHandler.GpsNiNotification;
83import com.android.internal.location.ProviderProperties;
84import com.android.internal.location.ProviderRequest;
Yu-Han Yange7baef32018-02-09 13:58:17 -080085import com.android.internal.location.gnssmetrics.GnssMetrics;
Yu-Han Yang66c7ea92018-03-11 17:17:15 -070086import com.android.server.location.GnssSatelliteBlacklistHelper.GnssSatelliteBlacklistCallback;
Yu-Han Yanga1862b52018-02-20 17:05:59 -080087import com.android.server.location.NtpTimeHelper.InjectNtpTimeCallback;
Yu-Han Yang66c7ea92018-03-11 17:17:15 -070088
89import libcore.io.IoUtils;
90
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080091import java.io.File;
Nick Pelly6fa9ad42012-07-16 12:18:23 -070092import java.io.FileDescriptor;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080093import java.io.FileInputStream;
94import java.io.IOException;
Nick Pelly6fa9ad42012-07-16 12:18:23 -070095import java.io.PrintWriter;
destradaaea8a8a62014-06-23 18:19:03 -070096import java.net.InetAddress;
97import java.net.UnknownHostException;
Wyatt Rileycf879db2017-01-12 13:57:38 -080098import java.util.ArrayList;
Andreas Gampee6748ce2015-12-11 18:00:38 -080099import java.util.Arrays;
Yu-Han Yange7baef32018-02-09 13:58:17 -0800100import java.util.HashMap;
Wyatt Rileycf879db2017-01-12 13:57:38 -0800101import java.util.List;
Yu-Han Yange7baef32018-02-09 13:58:17 -0800102import java.util.Map;
Danke Xie22d1f9f2009-08-18 18:28:45 -0400103import java.util.Map.Entry;
Jake Hambyb49a73d2011-03-15 20:09:46 -0700104import java.util.Properties;
Yu-Han Yange7baef32018-02-09 13:58:17 -0800105
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800106/**
gomo4402af62017-01-11 13:20:13 -0800107 * A GNSS implementation of LocationProvider used by LocationManager.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800108 *
109 * {@hide}
110 */
Yu-Han Yang66c7ea92018-03-11 17:17:15 -0700111public class GnssLocationProvider implements LocationProviderInterface, InjectNtpTimeCallback,
112 GnssSatelliteBlacklistCallback {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800113
Lifu Tang30f95a72016-01-07 23:20:38 -0800114 private static final String TAG = "GnssLocationProvider";
Mike Lockwood29c84342009-05-06 14:01:15 -0400115
Brian Muramatsu1715cb32012-08-08 17:32:21 -0700116 private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
117 private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400118
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700119 private static final ProviderProperties PROPERTIES = new ProviderProperties(
120 true, true, false, false, true, true, true,
121 Criteria.POWER_HIGH, Criteria.ACCURACY_FINE);
122
gomo4402af62017-01-11 13:20:13 -0800123 // these need to match GnssPositionMode enum in IGnss.hal
The Android Open Source Project10592532009-03-18 17:39:46 -0700124 private static final int GPS_POSITION_MODE_STANDALONE = 0;
125 private static final int GPS_POSITION_MODE_MS_BASED = 1;
126 private static final int GPS_POSITION_MODE_MS_ASSISTED = 2;
127
gomo4402af62017-01-11 13:20:13 -0800128 // these need to match GnssPositionRecurrence enum in IGnss.hal
Mike Lockwood04598b62010-04-14 17:17:24 -0400129 private static final int GPS_POSITION_RECURRENCE_PERIODIC = 0;
130 private static final int GPS_POSITION_RECURRENCE_SINGLE = 1;
131
gomo4402af62017-01-11 13:20:13 -0800132 // these need to match GnssStatusValue enum in IGnssCallback.hal
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800133 private static final int GPS_STATUS_NONE = 0;
134 private static final int GPS_STATUS_SESSION_BEGIN = 1;
135 private static final int GPS_STATUS_SESSION_END = 2;
136 private static final int GPS_STATUS_ENGINE_ON = 3;
137 private static final int GPS_STATUS_ENGINE_OFF = 4;
138
gomo4402af62017-01-11 13:20:13 -0800139 // these need to match AGnssStatusValue enum in IAGnssCallback.hal
Mike Lockwoode3635c92009-05-11 08:38:02 -0400140 /** AGPS status event values. */
141 private static final int GPS_REQUEST_AGPS_DATA_CONN = 1;
142 private static final int GPS_RELEASE_AGPS_DATA_CONN = 2;
143 private static final int GPS_AGPS_DATA_CONNECTED = 3;
144 private static final int GPS_AGPS_DATA_CONN_DONE = 4;
145 private static final int GPS_AGPS_DATA_CONN_FAILED = 5;
Mike Lockwood58bda982009-04-14 16:25:07 -0400146
gomo4402af62017-01-11 13:20:13 -0800147 // these need to match GnssLocationFlags enum in types.hal
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800148 private static final int LOCATION_INVALID = 0;
149 private static final int LOCATION_HAS_LAT_LONG = 1;
150 private static final int LOCATION_HAS_ALTITUDE = 2;
151 private static final int LOCATION_HAS_SPEED = 4;
152 private static final int LOCATION_HAS_BEARING = 8;
gomo4402af62017-01-11 13:20:13 -0800153 private static final int LOCATION_HAS_HORIZONTAL_ACCURACY = 16;
154 private static final int LOCATION_HAS_VERTICAL_ACCURACY = 32;
155 private static final int LOCATION_HAS_SPEED_ACCURACY = 64;
156 private static final int LOCATION_HAS_BEARING_ACCURACY = 128;
Mike Lockwoode3635c92009-05-11 08:38:02 -0400157
gomo4402af62017-01-11 13:20:13 -0800158
159 // IMPORTANT - the GPS_DELETE_* symbols here must match GnssAidingData enum in IGnss.hal
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800160 private static final int GPS_DELETE_EPHEMERIS = 0x0001;
161 private static final int GPS_DELETE_ALMANAC = 0x0002;
162 private static final int GPS_DELETE_POSITION = 0x0004;
163 private static final int GPS_DELETE_TIME = 0x0008;
164 private static final int GPS_DELETE_IONO = 0x0010;
165 private static final int GPS_DELETE_UTC = 0x0020;
166 private static final int GPS_DELETE_HEALTH = 0x0040;
167 private static final int GPS_DELETE_SVDIR = 0x0080;
168 private static final int GPS_DELETE_SVSTEER = 0x0100;
169 private static final int GPS_DELETE_SADATA = 0x0200;
170 private static final int GPS_DELETE_RTI = 0x0400;
171 private static final int GPS_DELETE_CELLDB_INFO = 0x8000;
172 private static final int GPS_DELETE_ALL = 0xFFFF;
173
gomo4402af62017-01-11 13:20:13 -0800174 // The GPS_CAPABILITY_* flags must match Capabilities enum in IGnssCallback.hal
Mike Lockwood04598b62010-04-14 17:17:24 -0400175 private static final int GPS_CAPABILITY_SCHEDULING = 0x0000001;
176 private static final int GPS_CAPABILITY_MSB = 0x0000002;
177 private static final int GPS_CAPABILITY_MSA = 0x0000004;
178 private static final int GPS_CAPABILITY_SINGLE_SHOT = 0x0000008;
Mike Lockwood9b9fb5c2011-06-29 15:09:40 -0400179 private static final int GPS_CAPABILITY_ON_DEMAND_TIME = 0x0000010;
destradaa6568d702014-10-27 12:47:41 -0700180 private static final int GPS_CAPABILITY_GEOFENCING = 0x0000020;
181 private static final int GPS_CAPABILITY_MEASUREMENTS = 0x0000040;
182 private static final int GPS_CAPABILITY_NAV_MESSAGES = 0x0000080;
Mike Lockwood04598b62010-04-14 17:17:24 -0400183
Tsuwei Chen462bcd82014-09-17 12:28:49 -0700184 // The AGPS SUPL mode
185 private static final int AGPS_SUPL_MODE_MSA = 0x02;
186 private static final int AGPS_SUPL_MODE_MSB = 0x01;
187
gomo4402af62017-01-11 13:20:13 -0800188 // these need to match AGnssType enum in IAGnssCallback.hal
Mike Lockwoode3635c92009-05-11 08:38:02 -0400189 private static final int AGPS_TYPE_SUPL = 1;
190 private static final int AGPS_TYPE_C2K = 2;
191
gomo4402af62017-01-11 13:20:13 -0800192 // these must match the ApnIpType enum in IAGnss.hal
destradaa96a14702014-06-05 11:36:30 -0700193 private static final int APN_INVALID = 0;
194 private static final int APN_IPV4 = 1;
195 private static final int APN_IPV6 = 2;
196 private static final int APN_IPV4V6 = 3;
197
Mike Lockwoode3635c92009-05-11 08:38:02 -0400198 // for mAGpsDataConnectionState
199 private static final int AGPS_DATA_CONNECTION_CLOSED = 0;
200 private static final int AGPS_DATA_CONNECTION_OPENING = 1;
201 private static final int AGPS_DATA_CONNECTION_OPEN = 2;
Mike Lockwood58bda982009-04-14 16:25:07 -0400202
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400203 // Handler messages
204 private static final int CHECK_LOCATION = 1;
205 private static final int ENABLE = 2;
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700206 private static final int SET_REQUEST = 3;
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400207 private static final int UPDATE_NETWORK_STATE = 4;
208 private static final int INJECT_NTP_TIME = 5;
209 private static final int DOWNLOAD_XTRA_DATA = 6;
Wyatt Rileyc7067412018-02-07 15:50:35 -0800210 private static final int UPDATE_LOCATION = 7; // Handle external location from network listener
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400211 private static final int ADD_LISTENER = 8;
212 private static final int REMOVE_LISTENER = 9;
Kevin Tang40e1baf2012-01-10 14:32:44 -0800213 private static final int DOWNLOAD_XTRA_DATA_FINISHED = 11;
destradaafb23c672015-04-16 14:01:27 -0700214 private static final int SUBSCRIPTION_OR_SIM_CHANGED = 12;
215 private static final int INITIALIZE_HANDLER = 13;
destradaae21252a2015-09-08 12:32:59 -0700216 private static final int REQUEST_SUPL_CONNECTION = 14;
217 private static final int RELEASE_SUPL_CONNECTION = 15;
Yu-Han Yange7baef32018-02-09 13:58:17 -0800218 private static final int REQUEST_LOCATION = 16;
Wyatt Riley26465d22018-02-12 13:44:24 -0800219 private static final int REPORT_LOCATION = 17; // HAL reports location
220 private static final int REPORT_SV_STATUS = 18; // HAL reports SV status
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400221
Miguel Torroja1e84da82010-07-27 07:02:24 +0200222 // Request setid
223 private static final int AGPS_RIL_REQUEST_SETID_IMSI = 1;
224 private static final int AGPS_RIL_REQUEST_SETID_MSISDN = 2;
225
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700226 //TODO(b/33112647): Create gps_debug.conf with commented career parameters.
227 private static final String DEBUG_PROPERTIES_FILE = "/etc/gps_debug.conf";
Miguel Torroja1e84da82010-07-27 07:02:24 +0200228
229 // ref. location info
230 private static final int AGPS_REF_LOCATION_TYPE_GSM_CELLID = 1;
231 private static final int AGPS_REF_LOCATION_TYPE_UMTS_CELLID = 2;
Miguel Torroja1e84da82010-07-27 07:02:24 +0200232
233 // set id info
234 private static final int AGPS_SETID_TYPE_NONE = 0;
235 private static final int AGPS_SETID_TYPE_IMSI = 1;
236 private static final int AGPS_SETID_TYPE_MSISDN = 2;
237
gomo48f1a642017-11-10 20:35:46 -0800238 private static final int GPS_GEOFENCE_UNAVAILABLE = 1 << 0L;
239 private static final int GPS_GEOFENCE_AVAILABLE = 1 << 1L;
destradaa0682809a2013-08-12 18:50:30 -0700240
gomo4402af62017-01-11 13:20:13 -0800241 // GPS Geofence errors. Should match GeofenceStatus enum in IGnssGeofenceCallback.hal.
destradaa0682809a2013-08-12 18:50:30 -0700242 private static final int GPS_GEOFENCE_OPERATION_SUCCESS = 0;
243 private static final int GPS_GEOFENCE_ERROR_TOO_MANY_GEOFENCES = 100;
gomo48f1a642017-11-10 20:35:46 -0800244 private static final int GPS_GEOFENCE_ERROR_ID_EXISTS = -101;
destradaa0682809a2013-08-12 18:50:30 -0700245 private static final int GPS_GEOFENCE_ERROR_ID_UNKNOWN = -102;
246 private static final int GPS_GEOFENCE_ERROR_INVALID_TRANSITION = -103;
247 private static final int GPS_GEOFENCE_ERROR_GENERIC = -149;
248
Tsuwei Chen678c13c2014-09-22 17:48:41 -0700249 // TCP/IP constants.
250 // Valid TCP/UDP port range is (0, 65535].
251 private static final int TCP_MIN_PORT = 0;
252 private static final int TCP_MAX_PORT = 0xffff;
253
Yu-Han Yange7baef32018-02-09 13:58:17 -0800254 // 1 second, or 1 Hz frequency.
255 private static final long LOCATION_UPDATE_MIN_TIME_INTERVAL_MILLIS = 1000;
256 // 30 seconds.
257 private static final long LOCATION_UPDATE_DURATION_MILLIS = 30 * 1000;
258
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700259 /** simpler wrapper for ProviderRequest + Worksource */
260 private static class GpsRequest {
261 public ProviderRequest request;
262 public WorkSource source;
gomo48f1a642017-11-10 20:35:46 -0800263
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700264 public GpsRequest(ProviderRequest request, WorkSource source) {
265 this.request = request;
266 this.source = source;
267 }
268 }
269
Wyatt Riley26465d22018-02-12 13:44:24 -0800270 // Threadsafe class to hold stats reported in the Extras Bundle
Wyatt Rileyc7067412018-02-07 15:50:35 -0800271 private static class LocationExtras {
272 private int mSvCount;
273 private int mMeanCn0;
274 private int mMaxCn0;
275 private final Bundle mBundle;
276
277 public LocationExtras() {
278 mBundle = new Bundle();
279 }
280
281 public void set(int svCount, int meanCn0, int maxCn0) {
Wyatt Riley26465d22018-02-12 13:44:24 -0800282 synchronized(this) {
283 mSvCount = svCount;
284 mMeanCn0 = meanCn0;
285 mMaxCn0 = maxCn0;
286 }
Wyatt Rileyc7067412018-02-07 15:50:35 -0800287 setBundle(mBundle);
288 }
289
290 public void reset() {
291 set(0,0,0);
292 }
293
294 // Also used by outside methods to add to other bundles
295 public void setBundle(Bundle extras) {
296 if (extras != null) {
Wyatt Riley26465d22018-02-12 13:44:24 -0800297 synchronized (this) {
298 extras.putInt("satellites", mSvCount);
299 extras.putInt("meanCn0", mMeanCn0);
300 extras.putInt("maxCn0", mMaxCn0);
301 }
Wyatt Rileyc7067412018-02-07 15:50:35 -0800302 }
303 }
304
305 public Bundle getBundle() {
Wyatt Riley26465d22018-02-12 13:44:24 -0800306 synchronized (this) {
307 return new Bundle(mBundle);
308 }
Wyatt Rileyc7067412018-02-07 15:50:35 -0800309 }
310 }
311
Yu-Han Yang66c7ea92018-03-11 17:17:15 -0700312 private final Object mLock = new Object();
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700313
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800314 // current status
Mike Lockwood15e3d0f2009-05-01 07:53:28 -0400315 private int mStatus = LocationProvider.TEMPORARILY_UNAVAILABLE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800316
317 // time for last status update
318 private long mStatusUpdateTime = SystemClock.elapsedRealtime();
Mike Lockwoodd53ba012010-04-15 20:41:26 -0400319
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800320 // turn off GPS fix icon if we haven't received a fix in 10 seconds
Mike Lockwood04598b62010-04-14 17:17:24 -0400321 private static final long RECENT_FIX_TIMEOUT = 10 * 1000;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800322
Mike Lockwood0632ca72009-05-14 15:51:03 -0400323 // stop trying if we do not receive a fix within 60 seconds
Mike Lockwood04598b62010-04-14 17:17:24 -0400324 private static final int NO_FIX_TIMEOUT = 60 * 1000;
Mike Lockwood0632ca72009-05-14 15:51:03 -0400325
Nick Pellyb041f232012-05-07 17:12:25 -0700326 // if the fix interval is below this we leave GPS on,
327 // if above then we cycle the GPS driver.
328 // Typical hot TTTF is ~5 seconds, so 10 seconds seems sane.
329 private static final int GPS_POLLING_THRESHOLD_INTERVAL = 10 * 1000;
330
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700331 // how long to wait if we have a network error in NTP or XTRA downloading
Wei Liu6f6326b2015-06-24 23:47:50 -0700332 // the initial value of the exponential backoff
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700333 // current setting - 5 minutes
gomo48f1a642017-11-10 20:35:46 -0800334 private static final long RETRY_INTERVAL = 5 * 60 * 1000;
Wei Liu6f6326b2015-06-24 23:47:50 -0700335 // how long to wait if we have a network error in NTP or XTRA downloading
336 // the max value of the exponential backoff
337 // current setting - 4 hours
gomo48f1a642017-11-10 20:35:46 -0800338 private static final long MAX_RETRY_INTERVAL = 4 * 60 * 60 * 1000;
Wei Liu6f6326b2015-06-24 23:47:50 -0700339
Wei Wangc5706f62017-04-18 11:26:26 -0700340 // Timeout when holding wakelocks for downloading XTRA data.
341 private static final long DOWNLOAD_XTRA_DATA_TIMEOUT_MS = 60 * 1000;
342
Yu-Han Yanga1862b52018-02-20 17:05:59 -0800343 private final ExponentialBackOff mXtraBackOff = new ExponentialBackOff(RETRY_INTERVAL,
344 MAX_RETRY_INTERVAL);
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700345
346 // true if we are enabled, protected by this
347 private boolean mEnabled;
348
Kevin Tang40e1baf2012-01-10 14:32:44 -0800349 // states for injecting ntp and downloading xtra data
350 private static final int STATE_PENDING_NETWORK = 0;
351 private static final int STATE_DOWNLOADING = 1;
352 private static final int STATE_IDLE = 2;
353
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400354 // flags to trigger NTP or XTRA data download when network becomes available
355 // initialized to true so we do NTP and XTRA when the network comes up after booting
Kevin Tang40e1baf2012-01-10 14:32:44 -0800356 private int mDownloadXtraDataPending = STATE_PENDING_NETWORK;
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400357
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800358 // true if GPS is navigating
359 private boolean mNavigating;
Mike Lockwoodcf1d8cb2010-01-20 10:14:54 -0500360
361 // true if GPS engine is on
362 private boolean mEngineOn;
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700363
Mike Lockwood04598b62010-04-14 17:17:24 -0400364 // requested frequency of fixes, in milliseconds
365 private int mFixInterval = 1000;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800366
gomo48f1a642017-11-10 20:35:46 -0800367 // true if low power mode for the GNSS chipset is part of the latest request.
368 private boolean mLowPowerMode = false;
369
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800370 // true if we started navigation
371 private boolean mStarted;
372
Stan Chesnutt1d72d8c2013-04-15 19:18:02 -0700373 // true if single shot request is in progress
374 private boolean mSingleShot;
375
Mike Lockwood04598b62010-04-14 17:17:24 -0400376 // capabilities of the GPS engine
377 private int mEngineCapabilities;
378
Mike Lockwood1a1cd3a2010-08-17 07:42:54 -0400379 // true if XTRA is supported
380 private boolean mSupportsXtra;
381
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800382 // for calculating time to first fix
383 private long mFixRequestTime = 0;
384 // time to first fix for most recent session
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700385 private int mTimeToFirstFix = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800386 // time we received our last fix
387 private long mLastFixTime;
388
Mike Lockwood04598b62010-04-14 17:17:24 -0400389 private int mPositionMode;
390
David Christied4edf4c2014-08-12 15:22:27 -0700391 // Current request from underlying location clients.
392 private ProviderRequest mProviderRequest = null;
Narayan Kamath32684dd2018-01-08 17:32:51 +0000393 // The WorkSource associated with the most recent client request (i.e, most recent call to
394 // setRequest).
David Christied4edf4c2014-08-12 15:22:27 -0700395 private WorkSource mWorkSource = null;
396 // True if gps should be disabled (used to support battery saver mode in settings).
397 private boolean mDisableGps = false;
398
destradaafb23c672015-04-16 14:01:27 -0700399 /**
400 * Properties loaded from PROPERTIES_FILE.
401 * It must be accessed only inside {@link #mHandler}.
402 */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800403 private Properties mProperties;
destradaafb23c672015-04-16 14:01:27 -0700404
Mike Lockwood734d6032009-07-28 18:30:25 -0700405 private String mSuplServerHost;
Tsuwei Chen678c13c2014-09-22 17:48:41 -0700406 private int mSuplServerPort = TCP_MIN_PORT;
Mike Lockwood734d6032009-07-28 18:30:25 -0700407 private String mC2KServerHost;
408 private int mC2KServerPort;
Tsuwei Chen3324e952014-09-07 01:30:42 -0700409 private boolean mSuplEsEnabled = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800410
Mike Lockwood15e3d0f2009-05-01 07:53:28 -0400411 private final Context mContext;
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700412 private final ILocationManager mILocationManager;
Wyatt Rileyc7067412018-02-07 15:50:35 -0800413 private final LocationExtras mLocationExtras = new LocationExtras();
Lifu Tang30f95a72016-01-07 23:20:38 -0800414 private final GnssStatusListenerHelper mListenerHelper;
Yu-Han Yang66c7ea92018-03-11 17:17:15 -0700415 private final GnssSatelliteBlacklistHelper mGnssSatelliteBlacklistHelper;
Lifu Tang818aa2c2016-02-01 01:52:00 -0800416 private final GnssMeasurementsProvider mGnssMeasurementsProvider;
417 private final GnssNavigationMessageProvider mGnssNavigationMessageProvider;
Yu-Han Yang07561382018-02-21 13:08:37 -0800418 private final LocationChangeListener mNetworkLocationListener = new NetworkLocationListener();
419 private final LocationChangeListener mFusedLocationListener = new FusedLocationListener();
Yu-Han Yanga1862b52018-02-20 17:05:59 -0800420 private final NtpTimeHelper mNtpTimeHelper;
Yu-Han Yang3557cc72018-03-21 12:48:36 -0700421 private final GnssBatchingProvider mGnssBatchingProvider;
Yu-Han Yang890ca8b2018-04-16 22:11:31 -0700422 private final GnssGeofenceProvider mGnssGeofenceProvider;
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400423
Victoria Lease5c24fd02012-10-01 11:00:50 -0700424 // Handler for processing events
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400425 private Handler mHandler;
The Android Open Source Project10592532009-03-18 17:39:46 -0700426
destradaae21252a2015-09-08 12:32:59 -0700427 /** It must be accessed only inside {@link #mHandler}. */
Mike Lockwoode3635c92009-05-11 08:38:02 -0400428 private int mAGpsDataConnectionState;
destradaae21252a2015-09-08 12:32:59 -0700429 /** It must be accessed only inside {@link #mHandler}. */
destradaa96a14702014-06-05 11:36:30 -0700430 private InetAddress mAGpsDataConnectionIpAddr;
destradaae21252a2015-09-08 12:32:59 -0700431
Mike Lockwood2f82c4e2009-04-17 08:24:10 -0400432 private final ConnectivityManager mConnMgr;
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700433 private final GpsNetInitiatedHandler mNIHandler;
Mike Lockwood2f82c4e2009-04-17 08:24:10 -0400434
Mike Lockwood0528b9b2009-05-07 10:12:54 -0400435 // Wakelocks
Lifu Tang30f95a72016-01-07 23:20:38 -0800436 private final static String WAKELOCK_KEY = "GnssLocationProvider";
Mike Lockwood0528b9b2009-05-07 10:12:54 -0400437 private final PowerManager.WakeLock mWakeLock;
Wei Wangb71c0492017-05-01 20:24:19 -0700438 private static final String DOWNLOAD_EXTRA_WAKELOCK_KEY = "GnssLocationProviderXtraDownload";
439 private final PowerManager.WakeLock mDownloadXtraWakeLock;
Mike Lockwood0528b9b2009-05-07 10:12:54 -0400440
Mike Lockwood29c84342009-05-06 14:01:15 -0400441 // Alarms
442 private final static String ALARM_WAKEUP = "com.android.internal.location.ALARM_WAKEUP";
Mike Lockwood0632ca72009-05-14 15:51:03 -0400443 private final static String ALARM_TIMEOUT = "com.android.internal.location.ALARM_TIMEOUT";
Tsuwei Chen52617bb2014-08-25 11:49:11 -0700444
445 // SIM/Carrier info.
446 private final static String SIM_STATE_CHANGED = "android.intent.action.SIM_STATE_CHANGED";
447
Ecco Park624ac3c2016-07-18 14:08:05 -0700448 // Persist property for LPP_PROFILE
449 private final static String LPP_PROFILE = "persist.sys.gps.lpp";
450
Ecco Park624ac3c2016-07-18 14:08:05 -0700451
David Christied4edf4c2014-08-12 15:22:27 -0700452 private final PowerManager mPowerManager;
Mike Lockwood29c84342009-05-06 14:01:15 -0400453 private final AlarmManager mAlarmManager;
454 private final PendingIntent mWakeupIntent;
Mike Lockwood0632ca72009-05-14 15:51:03 -0400455 private final PendingIntent mTimeoutIntent;
Mike Lockwood29c84342009-05-06 14:01:15 -0400456
Svet Ganovf7b47252018-02-26 11:11:27 -0800457 private final AppOpsManager mAppOps;
Mike Lockwood2f82c4e2009-04-17 08:24:10 -0400458 private final IBatteryStats mBatteryStats;
The Android Open Source Project10592532009-03-18 17:39:46 -0700459
Narayan Kamath32684dd2018-01-08 17:32:51 +0000460 // Current list of underlying location clients.
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700461 // only modified on handler thread
Dianne Hackborn002a54e2013-01-10 17:34:55 -0800462 private WorkSource mClientSource = new WorkSource();
Mike Lockwoodf1218be2010-01-29 09:20:06 -0500463
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -0700464 private GeofenceHardwareImpl mGeofenceHardwareImpl;
Wyatt Rileyd87cf912017-12-05 09:31:52 -0800465
466 // Volatile for simple inter-thread sync on these values.
467 private volatile int mHardwareYear = 0;
Wyatt Riley49097c02018-03-15 09:14:43 -0700468 private volatile String mHardwareModelName;
Lifu Tang82f893d2016-01-21 18:15:33 -0800469
Wyatt Riley5d5bac82016-11-01 07:05:16 -0700470 // Set lower than the current ITAR limit of 600m/s to allow this to trigger even if GPS HAL
471 // stops output right at 600m/s, depriving this of the information of a device that reaches
472 // greater than 600m/s, and higher than the speed of sound to avoid impacting most use cases.
473 private static final float ITAR_SPEED_LIMIT_METERS_PER_SECOND = 400.0F;
Wyatt Riley042c48f2017-10-06 14:59:25 -0700474
Wyatt Riley042c48f2017-10-06 14:59:25 -0700475 private volatile boolean mItarSpeedLimitExceeded = false;
Wyatt Riley5d5bac82016-11-01 07:05:16 -0700476
Siddharth Raybb608c82017-03-16 11:33:34 -0700477 // GNSS Metrics
478 private GnssMetrics mGnssMetrics;
479
Lifu Tang30f95a72016-01-07 23:20:38 -0800480 private final IGnssStatusProvider mGnssStatusProvider = new IGnssStatusProvider.Stub() {
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700481 @Override
Lifu Tang30f95a72016-01-07 23:20:38 -0800482 public void registerGnssStatusCallback(IGnssStatusListener callback) {
483 mListenerHelper.addListener(callback);
Mike Lockwood15e3d0f2009-05-01 07:53:28 -0400484 }
485
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700486 @Override
Lifu Tang30f95a72016-01-07 23:20:38 -0800487 public void unregisterGnssStatusCallback(IGnssStatusListener callback) {
488 mListenerHelper.removeListener(callback);
destradaaea8a8a62014-06-23 18:19:03 -0700489 }
490 };
Mike Lockwood15e3d0f2009-05-01 07:53:28 -0400491
Lifu Tang30f95a72016-01-07 23:20:38 -0800492 public IGnssStatusProvider getGnssStatusProvider() {
493 return mGnssStatusProvider;
Mike Lockwood15e3d0f2009-05-01 07:53:28 -0400494 }
495
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -0700496 public IGpsGeofenceHardware getGpsGeofenceProxy() {
Yu-Han Yang890ca8b2018-04-16 22:11:31 -0700497 return mGnssGeofenceProvider;
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -0700498 }
499
Lifu Tang818aa2c2016-02-01 01:52:00 -0800500 public GnssMeasurementsProvider getGnssMeasurementsProvider() {
501 return mGnssMeasurementsProvider;
destradaaea8a8a62014-06-23 18:19:03 -0700502 }
503
Lifu Tang818aa2c2016-02-01 01:52:00 -0800504 public GnssNavigationMessageProvider getGnssNavigationMessageProvider() {
505 return mGnssNavigationMessageProvider;
destradaa4b3e3932014-07-21 18:01:47 -0700506 }
507
destradaae21252a2015-09-08 12:32:59 -0700508 /**
509 * Callback used to listen for data connectivity changes.
510 */
511 private final ConnectivityManager.NetworkCallback mNetworkConnectivityCallback =
512 new ConnectivityManager.NetworkCallback() {
gomo48f1a642017-11-10 20:35:46 -0800513 @Override
514 public void onAvailable(Network network) {
Yu-Han Yanga1862b52018-02-20 17:05:59 -0800515 mNtpTimeHelper.onNetworkAvailable();
gomo48f1a642017-11-10 20:35:46 -0800516 if (mDownloadXtraDataPending == STATE_PENDING_NETWORK) {
517 if (mSupportsXtra) {
518 // Download only if supported, (prevents an unneccesary on-boot
519 // download)
520 xtraDownloadRequest();
521 }
522 }
523 // Always on, notify HAL so it can get data it needs
524 sendMessage(UPDATE_NETWORK_STATE, 0 /*arg*/, network);
Wyatt Rileyabc69ea2017-08-08 15:15:28 -0700525 }
Kevin Tang71ad5fe2017-05-10 19:36:20 -0700526
gomo48f1a642017-11-10 20:35:46 -0800527 @Override
528 public void onLost(Network network) {
529 sendMessage(UPDATE_NETWORK_STATE, 0 /*arg*/, network);
530 }
531 };
destradaae21252a2015-09-08 12:32:59 -0700532
533 /**
534 * Callback used to listen for availability of a requested SUPL connection.
535 * It is kept as a separate instance from {@link #mNetworkConnectivityCallback} to be able to
536 * manage the registration/un-registration lifetimes separate.
537 */
538 private final ConnectivityManager.NetworkCallback mSuplConnectivityCallback =
539 new ConnectivityManager.NetworkCallback() {
gomo48f1a642017-11-10 20:35:46 -0800540 @Override
541 public void onAvailable(Network network) {
542 // Specific to a change to a SUPL enabled network becoming ready
543 sendMessage(UPDATE_NETWORK_STATE, 0 /*arg*/, network);
544 }
Wyatt Riley41f6bce2016-12-13 10:45:29 -0800545
gomo48f1a642017-11-10 20:35:46 -0800546 @Override
547 public void onLost(Network network) {
548 releaseSuplConnection(GPS_RELEASE_AGPS_DATA_CONN);
549 }
550 };
destradaae21252a2015-09-08 12:32:59 -0700551
Tsuwei Chen52617bb2014-08-25 11:49:11 -0700552 private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
gomo48f1a642017-11-10 20:35:46 -0800553 @Override
554 public void onReceive(Context context, Intent intent) {
The Android Open Source Project10592532009-03-18 17:39:46 -0700555 String action = intent.getAction();
Tsuwei Chen48d37f92014-09-05 15:15:34 -0700556 if (DEBUG) Log.d(TAG, "receive broadcast intent, action: " + action);
destradaaee9fd342015-08-31 13:31:17 -0700557 if (action == null) {
558 return;
559 }
560
Mike Lockwood29c84342009-05-06 14:01:15 -0400561 if (action.equals(ALARM_WAKEUP)) {
Stan Chesnutt1d72d8c2013-04-15 19:18:02 -0700562 startNavigating(false);
Mike Lockwood0632ca72009-05-14 15:51:03 -0400563 } else if (action.equals(ALARM_TIMEOUT)) {
Mike Lockwood0632ca72009-05-14 15:51:03 -0400564 hibernate();
David Christied4edf4c2014-08-12 15:22:27 -0700565 } else if (PowerManager.ACTION_POWER_SAVE_MODE_CHANGED.equals(action)
Adam Lesinski87c17df2015-05-27 13:24:13 -0700566 || PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED.equals(action)
David Christied4edf4c2014-08-12 15:22:27 -0700567 || Intent.ACTION_SCREEN_OFF.equals(action)
568 || Intent.ACTION_SCREEN_ON.equals(action)) {
569 updateLowPowerMode();
Wink Savillea374c3d2014-11-11 11:48:04 -0800570 } else if (action.equals(SIM_STATE_CHANGED)) {
571 subscriptionOrSimChanged(context);
David Christied4edf4c2014-08-12 15:22:27 -0700572 }
The Android Open Source Project10592532009-03-18 17:39:46 -0700573 }
Mike Lockwood29c84342009-05-06 14:01:15 -0400574 };
The Android Open Source Project10592532009-03-18 17:39:46 -0700575
Wink Savilled09c4ca2014-11-22 10:08:16 -0800576 private final OnSubscriptionsChangedListener mOnSubscriptionsChangedListener =
577 new OnSubscriptionsChangedListener() {
gomo48f1a642017-11-10 20:35:46 -0800578 @Override
579 public void onSubscriptionsChanged() {
580 sendMessage(SUBSCRIPTION_OR_SIM_CHANGED, 0, null);
581 }
582 };
Wink Savillea374c3d2014-11-11 11:48:04 -0800583
Yu-Han Yang66c7ea92018-03-11 17:17:15 -0700584 /**
585 * Implements {@link GnssSatelliteBlacklistCallback#onUpdateSatelliteBlacklist}.
586 */
587 @Override
588 public void onUpdateSatelliteBlacklist(int[] constellations, int[] svids) {
589 mHandler.post(()->{
590 native_set_satellite_blacklist(constellations, svids);
591 });
592 }
593
Wink Savillea374c3d2014-11-11 11:48:04 -0800594 private void subscriptionOrSimChanged(Context context) {
Joe Onorato0c484102016-02-01 18:04:24 -0800595 if (DEBUG) Log.d(TAG, "received SIM related action: ");
Wink Savillea374c3d2014-11-11 11:48:04 -0800596 TelephonyManager phone = (TelephonyManager)
597 mContext.getSystemService(Context.TELEPHONY_SERVICE);
Ecco Park4fa1ab72016-10-24 13:04:52 -0700598 CarrierConfigManager configManager = (CarrierConfigManager)
599 mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE);
Wink Savillea374c3d2014-11-11 11:48:04 -0800600 String mccMnc = phone.getSimOperator();
Ecco Park4fa1ab72016-10-24 13:04:52 -0700601 boolean isKeepLppProfile = false;
Wink Savillea374c3d2014-11-11 11:48:04 -0800602 if (!TextUtils.isEmpty(mccMnc)) {
Joe Onorato0c484102016-02-01 18:04:24 -0800603 if (DEBUG) Log.d(TAG, "SIM MCC/MNC is available: " + mccMnc);
Wink Savillea374c3d2014-11-11 11:48:04 -0800604 synchronized (mLock) {
Ecco Park4fa1ab72016-10-24 13:04:52 -0700605 if (configManager != null) {
606 PersistableBundle b = configManager.getConfig();
Wyatt Rileya8ce2252017-09-01 13:31:17 -0700607 if (b != null) {
608 isKeepLppProfile =
609 b.getBoolean(CarrierConfigManager.KEY_PERSIST_LPP_MODE_BOOL);
610 }
Ecco Park4fa1ab72016-10-24 13:04:52 -0700611 }
612 if (isKeepLppProfile) {
613 // load current properties for the carrier
614 loadPropertiesFromResource(context, mProperties);
615 String lpp_profile = mProperties.getProperty("LPP_PROFILE");
616 // set the persist property LPP_PROFILE for the value
Ecco Park8eec7442017-08-04 16:21:59 -0700617 if (lpp_profile != null) {
618 SystemProperties.set(LPP_PROFILE, lpp_profile);
619 }
Ecco Park624ac3c2016-07-18 14:08:05 -0700620 } else {
Ecco Park4fa1ab72016-10-24 13:04:52 -0700621 // reset the persist property
622 SystemProperties.set(LPP_PROFILE, "");
Ecco Park624ac3c2016-07-18 14:08:05 -0700623 }
Wink Savillea374c3d2014-11-11 11:48:04 -0800624 reloadGpsProperties(context, mProperties);
625 mNIHandler.setSuplEsEnabled(mSuplEsEnabled);
626 }
627 } else {
Joe Onorato0c484102016-02-01 18:04:24 -0800628 if (DEBUG) Log.d(TAG, "SIM MCC/MNC is still not available");
Wink Savillea374c3d2014-11-11 11:48:04 -0800629 }
630 }
631
David Christied4edf4c2014-08-12 15:22:27 -0700632 private void updateLowPowerMode() {
Adam Lesinski87c17df2015-05-27 13:24:13 -0700633 // Disable GPS if we are in device idle mode.
634 boolean disableGps = mPowerManager.isDeviceIdleMode();
jackqdyulei455e90a2017-02-09 15:29:16 -0800635 final PowerSaveState result =
636 mPowerManager.getPowerSaveState(ServiceType.GPS);
637 switch (result.gpsMode) {
Makoto Onuki57f0f552017-12-11 12:22:18 -0800638 case PowerManager.LOCATION_MODE_GPS_DISABLED_WHEN_SCREEN_OFF:
Adam Lesinski87c17df2015-05-27 13:24:13 -0700639 // If we are in battery saver mode and the screen is off, disable GPS.
jackqdyulei455e90a2017-02-09 15:29:16 -0800640 disableGps |= result.batterySaverEnabled && !mPowerManager.isInteractive();
David Christied4edf4c2014-08-12 15:22:27 -0700641 break;
David Christied4edf4c2014-08-12 15:22:27 -0700642 }
643 if (disableGps != mDisableGps) {
644 mDisableGps = disableGps;
645 updateRequirements();
646 }
647 }
648
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800649 public static boolean isSupported() {
650 return native_is_supported();
651 }
652
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700653 interface SetCarrierProperty {
654 public boolean set(int value);
655 }
656
Tsuwei Chen52617bb2014-08-25 11:49:11 -0700657 private void reloadGpsProperties(Context context, Properties properties) {
Joe Onorato0c484102016-02-01 18:04:24 -0800658 if (DEBUG) Log.d(TAG, "Reset GPS properties, previous size = " + properties.size());
Tsuwei Chen52617bb2014-08-25 11:49:11 -0700659 loadPropertiesFromResource(context, properties);
Ecco Park624ac3c2016-07-18 14:08:05 -0700660
Ecco Park624ac3c2016-07-18 14:08:05 -0700661 String lpp_prof = SystemProperties.get(LPP_PROFILE);
662 if (!TextUtils.isEmpty(lpp_prof)) {
gomo48f1a642017-11-10 20:35:46 -0800663 // override default value of this if lpp_prof is not empty
664 properties.setProperty("LPP_PROFILE", lpp_prof);
Ecco Park624ac3c2016-07-18 14:08:05 -0700665 }
Wyatt Riley3e1cd0b2017-04-19 17:57:14 -0700666 /*
667 * Overlay carrier properties from a debug configuration file.
668 */
669 loadPropertiesFromFile(DEBUG_PROPERTIES_FILE, properties);
Tsuwei Chen52617bb2014-08-25 11:49:11 -0700670 // TODO: we should get rid of C2K specific setting.
671 setSuplHostPort(properties.getProperty("SUPL_HOST"),
gomo48f1a642017-11-10 20:35:46 -0800672 properties.getProperty("SUPL_PORT"));
Tsuwei Chen52617bb2014-08-25 11:49:11 -0700673 mC2KServerHost = properties.getProperty("C2K_HOST");
674 String portString = properties.getProperty("C2K_PORT");
675 if (mC2KServerHost != null && portString != null) {
676 try {
677 mC2KServerPort = Integer.parseInt(portString);
678 } catch (NumberFormatException e) {
679 Log.e(TAG, "unable to parse C2K_PORT: " + portString);
680 }
681 }
destradaaef752b62015-04-17 13:10:47 -0700682 if (native_is_gnss_configuration_supported()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700683 Map<String, SetCarrierProperty> map = new HashMap<String, SetCarrierProperty>() {
684 {
685 put("SUPL_VER", (val) -> native_set_supl_version(val));
686 put("SUPL_MODE", (val) -> native_set_supl_mode(val));
687 put("SUPL_ES", (val) -> native_set_supl_es(val));
688 put("LPP_PROFILE", (val) -> native_set_lpp_profile(val));
gomo48f1a642017-11-10 20:35:46 -0800689 put("A_GLONASS_POS_PROTOCOL_SELECT",
690 (val) -> native_set_gnss_pos_protocol_select(val));
691 put("USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL",
692 (val) -> native_set_emergency_supl_pdn(val));
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700693 put("GPS_LOCK", (val) -> native_set_gps_lock(val));
694 }
695 };
696
gomo48f1a642017-11-10 20:35:46 -0800697 for (Entry<String, SetCarrierProperty> entry : map.entrySet()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700698 String propertyName = entry.getKey();
699 String propertyValueString = properties.getProperty(propertyName);
700 if (propertyValueString != null) {
701 try {
gomo48f1a642017-11-10 20:35:46 -0800702 int propertyValueInt = Integer.decode(propertyValueString);
703 boolean result = entry.getValue().set(propertyValueInt);
704 if (result == false) {
705 Log.e(TAG, "Unable to set " + propertyName);
706 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700707 } catch (NumberFormatException e) {
gomo48f1a642017-11-10 20:35:46 -0800708 Log.e(TAG, "unable to parse propertyName: " + propertyValueString);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700709 }
710 }
destradaaef752b62015-04-17 13:10:47 -0700711 }
712 } else if (DEBUG) {
713 Log.d(TAG, "Skipped configuration update because GNSS configuration in GPS HAL is not"
714 + " supported");
Tsuwei Chen52617bb2014-08-25 11:49:11 -0700715 }
Tsuwei Chen3324e952014-09-07 01:30:42 -0700716
717 // SUPL_ES configuration.
718 String suplESProperty = mProperties.getProperty("SUPL_ES");
719 if (suplESProperty != null) {
720 try {
721 mSuplEsEnabled = (Integer.parseInt(suplESProperty) == 1);
722 } catch (NumberFormatException e) {
723 Log.e(TAG, "unable to parse SUPL_ES: " + suplESProperty);
724 }
725 }
Tsuwei Chen52617bb2014-08-25 11:49:11 -0700726 }
727
728 private void loadPropertiesFromResource(Context context,
gomo48f1a642017-11-10 20:35:46 -0800729 Properties properties) {
Tsuwei Chen52617bb2014-08-25 11:49:11 -0700730 String[] configValues = context.getResources().getStringArray(
731 com.android.internal.R.array.config_gpsParameters);
732 for (String item : configValues) {
Joe Onorato0c484102016-02-01 18:04:24 -0800733 if (DEBUG) Log.d(TAG, "GpsParamsResource: " + item);
Tsuwei Chen7c485bf2014-09-10 15:33:34 -0700734 // We need to support "KEY =", but not "=VALUE".
Zheng Zhangad48bd92017-10-16 10:27:28 -0700735 int index = item.indexOf("=");
736 if (index > 0 && index + 1 < item.length()) {
737 String key = item.substring(0, index);
738 String value = item.substring(index + 1);
739 properties.setProperty(key.trim().toUpperCase(), value);
Tsuwei Chen52617bb2014-08-25 11:49:11 -0700740 } else {
741 Log.w(TAG, "malformed contents: " + item);
742 }
743 }
744 }
745
746 private boolean loadPropertiesFromFile(String filename,
gomo48f1a642017-11-10 20:35:46 -0800747 Properties properties) {
Colin Cross7c030ed2014-01-28 09:33:53 -0800748 try {
749 File file = new File(filename);
750 FileInputStream stream = null;
751 try {
752 stream = new FileInputStream(file);
Tsuwei Chen52617bb2014-08-25 11:49:11 -0700753 properties.load(stream);
Colin Cross7c030ed2014-01-28 09:33:53 -0800754 } finally {
755 IoUtils.closeQuietly(stream);
756 }
757
Colin Cross7c030ed2014-01-28 09:33:53 -0800758 } catch (IOException e) {
Wyatt Riley3e1cd0b2017-04-19 17:57:14 -0700759 if (DEBUG) Log.d(TAG, "Could not open GPS configuration file " + filename);
Colin Cross7c030ed2014-01-28 09:33:53 -0800760 return false;
761 }
762 return true;
763 }
764
Lifu Tang30f95a72016-01-07 23:20:38 -0800765 public GnssLocationProvider(Context context, ILocationManager ilocationManager,
Victoria Lease5cd731a2012-12-19 15:04:21 -0800766 Looper looper) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800767 mContext = context;
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700768 mILocationManager = ilocationManager;
Mike Lockwood63598a02010-02-24 11:52:59 -0500769
Mike Lockwood0528b9b2009-05-07 10:12:54 -0400770 // Create a wake lock
David Christied4edf4c2014-08-12 15:22:27 -0700771 mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
772 mWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, WAKELOCK_KEY);
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700773 mWakeLock.setReferenceCounted(true);
Mike Lockwood0528b9b2009-05-07 10:12:54 -0400774
Wei Wangb71c0492017-05-01 20:24:19 -0700775 // Create a separate wake lock for xtra downloader as it may be released due to timeout.
776 mDownloadXtraWakeLock = mPowerManager.newWakeLock(
777 PowerManager.PARTIAL_WAKE_LOCK, DOWNLOAD_EXTRA_WAKELOCK_KEY);
778 mDownloadXtraWakeLock.setReferenceCounted(true);
779
gomo48f1a642017-11-10 20:35:46 -0800780 mAlarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
Mike Lockwood29c84342009-05-06 14:01:15 -0400781 mWakeupIntent = PendingIntent.getBroadcast(mContext, 0, new Intent(ALARM_WAKEUP), 0);
Mike Lockwood0632ca72009-05-14 15:51:03 -0400782 mTimeoutIntent = PendingIntent.getBroadcast(mContext, 0, new Intent(ALARM_TIMEOUT), 0);
Mike Lockwood29c84342009-05-06 14:01:15 -0400783
gomo48f1a642017-11-10 20:35:46 -0800784 mConnMgr = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
Mike Lockwood58bda982009-04-14 16:25:07 -0400785
Dianne Hackborna06de0f2012-12-11 16:34:47 -0800786 // App ops service to keep track of who is accessing the GPS
Svet Ganovf7b47252018-02-26 11:11:27 -0800787 mAppOps = mContext.getSystemService(AppOpsManager.class);
Dianne Hackborna06de0f2012-12-11 16:34:47 -0800788
Mike Lockwood2f82c4e2009-04-17 08:24:10 -0400789 // Battery statistics service to be notified when GPS turns on or off
Dianne Hackborn91268cf2013-06-13 19:06:50 -0700790 mBatteryStats = IBatteryStats.Stub.asInterface(ServiceManager.getService(
791 BatteryStats.SERVICE_NAME));
Mike Lockwood2f82c4e2009-04-17 08:24:10 -0400792
destradaafb23c672015-04-16 14:01:27 -0700793 // Construct internal handler
794 mHandler = new ProviderHandler(looper);
795
796 // Load GPS configuration and register listeners in the background:
797 // some operations, such as opening files and registering broadcast receivers, can take a
798 // relative long time, so the ctor() is kept to create objects needed by this instance,
799 // while IO initialization and registration is delegated to our internal handler
800 // this approach is just fine because events are posted to our handler anyway
Tsuwei Chen52617bb2014-08-25 11:49:11 -0700801 mProperties = new Properties();
destradaafb23c672015-04-16 14:01:27 -0700802 sendMessage(INITIALIZE_HANDLER, 0, null);
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400803
Tsuwei Chen3324e952014-09-07 01:30:42 -0700804 // Create a GPS net-initiated handler.
805 mNIHandler = new GpsNetInitiatedHandler(context,
gomo48f1a642017-11-10 20:35:46 -0800806 mNetInitiatedListener,
807 mSuplEsEnabled);
Tsuwei Chen3324e952014-09-07 01:30:42 -0700808
Lifu Tang30f95a72016-01-07 23:20:38 -0800809 mListenerHelper = new GnssStatusListenerHelper(mHandler) {
destradaa6568d702014-10-27 12:47:41 -0700810 @Override
811 protected boolean isAvailableInPlatform() {
destradaa13a60b02015-01-15 18:36:01 -0800812 return isSupported();
destradaa6568d702014-10-27 12:47:41 -0700813 }
814
815 @Override
816 protected boolean isGpsEnabled() {
817 return isEnabled();
818 }
819 };
820
Yu-Han Yang8de21502018-04-23 01:40:25 -0700821 mGnssMeasurementsProvider = new GnssMeasurementsProvider(mContext, mHandler) {
destradaa6568d702014-10-27 12:47:41 -0700822 @Override
823 protected boolean isGpsEnabled() {
824 return isEnabled();
825 }
826 };
827
Lifu Tang818aa2c2016-02-01 01:52:00 -0800828 mGnssNavigationMessageProvider = new GnssNavigationMessageProvider(mHandler) {
destradaa6568d702014-10-27 12:47:41 -0700829 @Override
830 protected boolean isAvailableInPlatform() {
831 return native_is_navigation_message_supported();
832 }
833
834 @Override
gomo48f1a642017-11-10 20:35:46 -0800835 protected int registerWithService() {
836 boolean result = native_start_navigation_message_collection();
837 if (result) {
838 return RemoteListenerHelper.RESULT_SUCCESS;
839 } else {
840 return RemoteListenerHelper.RESULT_INTERNAL_ERROR;
841 }
destradaa6568d702014-10-27 12:47:41 -0700842 }
843
844 @Override
845 protected void unregisterFromService() {
846 native_stop_navigation_message_collection();
847 }
848
849 @Override
850 protected boolean isGpsEnabled() {
851 return isEnabled();
852 }
853 };
Siddharth Ray78ccaf52017-12-23 16:16:21 -0800854 mGnssMetrics = new GnssMetrics(mBatteryStats);
Yu-Han Yanga1862b52018-02-20 17:05:59 -0800855
Yu-Han Yang66c7ea92018-03-11 17:17:15 -0700856 mNtpTimeHelper = new NtpTimeHelper(mContext, looper, this);
857 mGnssSatelliteBlacklistHelper = new GnssSatelliteBlacklistHelper(mContext,
858 looper, this);
859 mHandler.post(mGnssSatelliteBlacklistHelper::updateSatelliteBlacklist);
Yu-Han Yang3557cc72018-03-21 12:48:36 -0700860 mGnssBatchingProvider = new GnssBatchingProvider();
Yu-Han Yang890ca8b2018-04-16 22:11:31 -0700861 mGnssGeofenceProvider = new GnssGeofenceProvider(looper);
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400862 }
863
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800864 /**
Mike Lockwoodd03ff942010-02-09 08:46:14 -0500865 * Returns the name of this provider.
866 */
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700867 @Override
Mike Lockwoodd03ff942010-02-09 08:46:14 -0500868 public String getName() {
869 return LocationManager.GPS_PROVIDER;
870 }
871
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700872 @Override
873 public ProviderProperties getProperties() {
874 return PROPERTIES;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800875 }
876
Yu-Han Yanga1862b52018-02-20 17:05:59 -0800877
878 /**
879 * Implements {@link InjectNtpTimeCallback#injectTime}
880 */
881 @Override
882 public void injectTime(long time, long timeReference, int uncertainty) {
883 native_inject_time(time, timeReference, uncertainty);
884 }
885
destradaae21252a2015-09-08 12:32:59 -0700886 private void handleUpdateNetworkState(Network network) {
887 // retrieve NetworkInfo for this UID
888 NetworkInfo info = mConnMgr.getNetworkInfo(network);
Kevin Tang71ad5fe2017-05-10 19:36:20 -0700889
890 boolean networkAvailable = false;
891 boolean isConnected = false;
892 int type = ConnectivityManager.TYPE_NONE;
893 boolean isRoaming = false;
894 String apnName = null;
895
896 if (info != null) {
897 networkAvailable = info.isAvailable() && TelephonyManager.getDefault().getDataEnabled();
898 isConnected = info.isConnected();
899 type = info.getType();
900 isRoaming = info.isRoaming();
901 apnName = info.getExtraInfo();
destradaae21252a2015-09-08 12:32:59 -0700902 }
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400903
Joe Onoratof5d95cb2010-01-07 21:48:32 -0500904 if (DEBUG) {
destradaae21252a2015-09-08 12:32:59 -0700905 String message = String.format(
906 "UpdateNetworkState, state=%s, connected=%s, info=%s, capabilities=%S",
907 agpsDataConnStateAsString(),
908 isConnected,
909 info,
910 mConnMgr.getNetworkCapabilities(network));
911 Log.d(TAG, message);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800912 }
Mike Lockwood03d24672009-10-08 15:45:03 -0400913
destradaae21252a2015-09-08 12:32:59 -0700914 if (native_is_agps_ril_supported()) {
destradaae21252a2015-09-08 12:32:59 -0700915 String defaultApn = getSelectedApn();
916 if (defaultApn == null) {
917 defaultApn = "dummy-apn";
destradaaef752b62015-04-17 13:10:47 -0700918 }
destradaae21252a2015-09-08 12:32:59 -0700919
920 native_update_network_state(
921 isConnected,
Kevin Tang71ad5fe2017-05-10 19:36:20 -0700922 type,
923 isRoaming,
destradaae21252a2015-09-08 12:32:59 -0700924 networkAvailable,
Kevin Tang71ad5fe2017-05-10 19:36:20 -0700925 apnName,
destradaae21252a2015-09-08 12:32:59 -0700926 defaultApn);
927 } else if (DEBUG) {
928 Log.d(TAG, "Skipped network state update because GPS HAL AGPS-RIL is not supported");
Mike Lockwood50130bb2010-10-11 06:22:50 -0400929 }
930
destradaae21252a2015-09-08 12:32:59 -0700931 if (mAGpsDataConnectionState == AGPS_DATA_CONNECTION_OPENING) {
932 if (isConnected) {
Stephen Li83b69712011-01-25 18:47:28 -0800933 if (apnName == null) {
destradaae21252a2015-09-08 12:32:59 -0700934 // assign a dummy value in the case of C2K as otherwise we will have a runtime
935 // exception in the following call to native_agps_data_conn_open
Stephen Li83b69712011-01-25 18:47:28 -0800936 apnName = "dummy-apn";
937 }
destradaae21252a2015-09-08 12:32:59 -0700938 int apnIpType = getApnIpType(apnName);
destradaa96a14702014-06-05 11:36:30 -0700939 setRouting();
940 if (DEBUG) {
941 String message = String.format(
942 "native_agps_data_conn_open: mAgpsApn=%s, mApnIpType=%s",
destradaae21252a2015-09-08 12:32:59 -0700943 apnName,
944 apnIpType);
destradaa96a14702014-06-05 11:36:30 -0700945 Log.d(TAG, message);
Stephen Li8efd74d2011-03-01 20:56:00 -0800946 }
destradaae21252a2015-09-08 12:32:59 -0700947 native_agps_data_conn_open(apnName, apnIpType);
Mike Lockwood03d24672009-10-08 15:45:03 -0400948 mAGpsDataConnectionState = AGPS_DATA_CONNECTION_OPEN;
949 } else {
destradaae21252a2015-09-08 12:32:59 -0700950 handleReleaseSuplConnection(GPS_AGPS_DATA_CONN_FAILED);
Mike Lockwood03d24672009-10-08 15:45:03 -0400951 }
952 }
destradaae21252a2015-09-08 12:32:59 -0700953 }
Mike Lockwood03d24672009-10-08 15:45:03 -0400954
destradaae21252a2015-09-08 12:32:59 -0700955 private void handleRequestSuplConnection(InetAddress address) {
956 if (DEBUG) {
957 String message = String.format(
958 "requestSuplConnection, state=%s, address=%s",
959 agpsDataConnStateAsString(),
960 address);
961 Log.d(TAG, message);
962 }
963
964 if (mAGpsDataConnectionState != AGPS_DATA_CONNECTION_CLOSED) {
965 return;
966 }
967 mAGpsDataConnectionIpAddr = address;
968 mAGpsDataConnectionState = AGPS_DATA_CONNECTION_OPENING;
969
970 NetworkRequest.Builder requestBuilder = new NetworkRequest.Builder();
971 requestBuilder.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR);
972 requestBuilder.addCapability(NetworkCapabilities.NET_CAPABILITY_SUPL);
973 NetworkRequest request = requestBuilder.build();
974 mConnMgr.requestNetwork(
975 request,
Etan Cohene9aea9d2017-02-09 18:16:58 -0800976 mSuplConnectivityCallback);
destradaae21252a2015-09-08 12:32:59 -0700977 }
978
979 private void handleReleaseSuplConnection(int agpsDataConnStatus) {
980 if (DEBUG) {
981 String message = String.format(
982 "releaseSuplConnection, state=%s, status=%s",
983 agpsDataConnStateAsString(),
984 agpsDataConnStatusAsString(agpsDataConnStatus));
985 Log.d(TAG, message);
986 }
987
988 if (mAGpsDataConnectionState == AGPS_DATA_CONNECTION_CLOSED) {
989 return;
990 }
991 mAGpsDataConnectionState = AGPS_DATA_CONNECTION_CLOSED;
992
993 mConnMgr.unregisterNetworkCallback(mSuplConnectivityCallback);
994 switch (agpsDataConnStatus) {
995 case GPS_AGPS_DATA_CONN_FAILED:
996 native_agps_data_conn_failed();
997 break;
998 case GPS_RELEASE_AGPS_DATA_CONN:
999 native_agps_data_conn_closed();
1000 break;
1001 default:
1002 Log.e(TAG, "Invalid status to release SUPL connection: " + agpsDataConnStatus);
Mike Lockwood62a8fc12010-03-22 14:23:26 -04001003 }
1004 }
Yu-Han Yang8de21502018-04-23 01:40:25 -07001005
Yu-Han Yange7baef32018-02-09 13:58:17 -08001006 private void handleRequestLocation(boolean independentFromGnss) {
1007 if (isRequestLocationRateLimited()) {
1008 if (DEBUG) {
1009 Log.d(TAG, "RequestLocation is denied due to too frequent requests.");
1010 }
1011 return;
1012 }
Yu-Han Yang74041ff2018-04-06 15:57:31 -07001013 ContentResolver resolver = mContext.getContentResolver();
1014 long durationMillis = Settings.Global.getLong(
1015 resolver,
1016 Settings.Global.GNSS_HAL_LOCATION_REQUEST_DURATION_MILLIS,
1017 LOCATION_UPDATE_DURATION_MILLIS);
1018 if (durationMillis == 0) {
1019 Log.i(TAG, "GNSS HAL location request is disabled by Settings.");
1020 return;
1021 }
Yu-Han Yange7baef32018-02-09 13:58:17 -08001022
1023 LocationManager locationManager = (LocationManager) mContext.getSystemService(
1024 Context.LOCATION_SERVICE);
Yu-Han Yang07561382018-02-21 13:08:37 -08001025 String provider;
1026 LocationChangeListener locationListener;
Yu-Han Yange7baef32018-02-09 13:58:17 -08001027
1028 if (independentFromGnss) {
1029 // For fast GNSS TTFF
Yu-Han Yang07561382018-02-21 13:08:37 -08001030 provider = LocationManager.NETWORK_PROVIDER;
1031 locationListener = mNetworkLocationListener;
Yu-Han Yange7baef32018-02-09 13:58:17 -08001032 } else {
1033 // For Device-Based Hybrid (E911)
Yu-Han Yang07561382018-02-21 13:08:37 -08001034 provider = LocationManager.FUSED_PROVIDER;
1035 locationListener = mFusedLocationListener;
Yu-Han Yange7baef32018-02-09 13:58:17 -08001036 }
Yu-Han Yang07561382018-02-21 13:08:37 -08001037
Yu-Han Yang26491082018-04-18 02:51:33 -07001038 if (!locationManager.isProviderEnabled(provider)) {
1039 Log.w(TAG, "Unable to request location since " + provider
1040 + " provider does not exist or is not enabled.");
1041 return;
1042 }
1043
Yu-Han Yang07561382018-02-21 13:08:37 -08001044 Log.i(TAG,
Yu-Han Yang74041ff2018-04-06 15:57:31 -07001045 String.format(
1046 "GNSS HAL Requesting location updates from %s provider for %d millis.",
1047 provider, durationMillis));
Yu-Han Yang07561382018-02-21 13:08:37 -08001048 locationManager.requestLocationUpdates(provider,
1049 LOCATION_UPDATE_MIN_TIME_INTERVAL_MILLIS, /*minDistance=*/ 0,
1050 locationListener, mHandler.getLooper());
1051 locationListener.numLocationUpdateRequest++;
1052 mHandler.postDelayed(() -> {
1053 if (--locationListener.numLocationUpdateRequest == 0) {
1054 Log.i(TAG, String.format("Removing location updates from %s provider.", provider));
1055 locationManager.removeUpdates(locationListener);
1056 }
Yu-Han Yang74041ff2018-04-06 15:57:31 -07001057 }, durationMillis);
Yu-Han Yange7baef32018-02-09 13:58:17 -08001058 }
1059
1060 private void injectBestLocation(Location location) {
1061 int gnssLocationFlags = LOCATION_HAS_LAT_LONG |
1062 (location.hasAltitude() ? LOCATION_HAS_ALTITUDE : 0) |
1063 (location.hasSpeed() ? LOCATION_HAS_SPEED : 0) |
1064 (location.hasBearing() ? LOCATION_HAS_BEARING : 0) |
1065 (location.hasAccuracy() ? LOCATION_HAS_HORIZONTAL_ACCURACY : 0) |
1066 (location.hasVerticalAccuracy() ? LOCATION_HAS_VERTICAL_ACCURACY : 0) |
1067 (location.hasSpeedAccuracy() ? LOCATION_HAS_SPEED_ACCURACY : 0) |
1068 (location.hasBearingAccuracy() ? LOCATION_HAS_BEARING_ACCURACY : 0);
1069
1070 double latitudeDegrees = location.getLatitude();
1071 double longitudeDegrees = location.getLongitude();
1072 double altitudeMeters = location.getAltitude();
1073 float speedMetersPerSec = location.getSpeed();
1074 float bearingDegrees = location.getBearing();
1075 float horizontalAccuracyMeters = location.getAccuracy();
1076 float verticalAccuracyMeters = location.getVerticalAccuracyMeters();
1077 float speedAccuracyMetersPerSecond = location.getSpeedAccuracyMetersPerSecond();
1078 float bearingAccuracyDegrees = location.getBearingAccuracyDegrees();
1079 long timestamp = location.getTime();
1080 native_inject_best_location(gnssLocationFlags, latitudeDegrees, longitudeDegrees,
1081 altitudeMeters, speedMetersPerSec, bearingDegrees, horizontalAccuracyMeters,
1082 verticalAccuracyMeters, speedAccuracyMetersPerSecond, bearingAccuracyDegrees,
1083 timestamp);
1084 }
1085
Yu-Han Yange7baef32018-02-09 13:58:17 -08001086 /** Returns true if the location request is too frequent. */
1087 private boolean isRequestLocationRateLimited() {
1088 // TODO(b/73198123): implement exponential backoff.
1089 return false;
1090 }
1091
Mike Lockwood62a8fc12010-03-22 14:23:26 -04001092 private void handleDownloadXtraData() {
Wyatt Riley0d6e54e22016-10-05 12:03:03 -07001093 if (!mSupportsXtra) {
1094 // native code reports xtra not supported, don't try
1095 Log.d(TAG, "handleDownloadXtraData() called when Xtra not supported");
1096 return;
1097 }
Kevin Tang40e1baf2012-01-10 14:32:44 -08001098 if (mDownloadXtraDataPending == STATE_DOWNLOADING) {
1099 // already downloading data
Mike Lockwood62a8fc12010-03-22 14:23:26 -04001100 return;
1101 }
destradaae21252a2015-09-08 12:32:59 -07001102 if (!isDataNetworkConnected()) {
Kevin Tang40e1baf2012-01-10 14:32:44 -08001103 // try again when network is up
1104 mDownloadXtraDataPending = STATE_PENDING_NETWORK;
1105 return;
Mike Lockwood62a8fc12010-03-22 14:23:26 -04001106 }
Kevin Tang40e1baf2012-01-10 14:32:44 -08001107 mDownloadXtraDataPending = STATE_DOWNLOADING;
1108
Jeff Brown028872f2012-08-25 13:07:01 -07001109 // hold wake lock while task runs
Wei Wangb71c0492017-05-01 20:24:19 -07001110 mDownloadXtraWakeLock.acquire(DOWNLOAD_XTRA_DATA_TIMEOUT_MS);
Lifu Tangcbd2a142016-06-22 10:57:55 -07001111 Log.i(TAG, "WakeLock acquired by handleDownloadXtraData()");
Kevin Tang40e1baf2012-01-10 14:32:44 -08001112 AsyncTask.THREAD_POOL_EXECUTOR.execute(new Runnable() {
1113 @Override
1114 public void run() {
Andreas Gampedfdc6ac2014-10-28 20:42:53 -07001115 GpsXtraDownloader xtraDownloader = new GpsXtraDownloader(mProperties);
Kevin Tang40e1baf2012-01-10 14:32:44 -08001116 byte[] data = xtraDownloader.downloadXtraData();
1117 if (data != null) {
destradaae21252a2015-09-08 12:32:59 -07001118 if (DEBUG) Log.d(TAG, "calling native_inject_xtra_data");
Kevin Tang40e1baf2012-01-10 14:32:44 -08001119 native_inject_xtra_data(data, data.length);
Wei Liu6f6326b2015-06-24 23:47:50 -07001120 mXtraBackOff.reset();
Kevin Tang40e1baf2012-01-10 14:32:44 -08001121 }
1122
Jeff Brown028872f2012-08-25 13:07:01 -07001123 sendMessage(DOWNLOAD_XTRA_DATA_FINISHED, 0, null);
Kevin Tang40e1baf2012-01-10 14:32:44 -08001124
1125 if (data == null) {
1126 // try again later
1127 // since this is delayed and not urgent we do not hold a wake lock here
Wei Liu6f6326b2015-06-24 23:47:50 -07001128 mHandler.sendEmptyMessageDelayed(DOWNLOAD_XTRA_DATA,
1129 mXtraBackOff.nextBackoffMillis());
Kevin Tang40e1baf2012-01-10 14:32:44 -08001130 }
Kevin Tang40e1baf2012-01-10 14:32:44 -08001131
Wei Wangb71c0492017-05-01 20:24:19 -07001132 // Release wake lock held by task, synchronize on mLock in case multiple
1133 // download tasks overrun.
1134 synchronized (mLock) {
1135 if (mDownloadXtraWakeLock.isHeld()) {
Zheng Zhang3cceb252017-08-07 13:51:23 -07001136 // This wakelock may have time-out, if a timeout was specified.
1137 // Catch (and ignore) any timeout exceptions.
1138 try {
1139 mDownloadXtraWakeLock.release();
1140 if (DEBUG) Log.d(TAG, "WakeLock released by handleDownloadXtraData()");
1141 } catch (Exception e) {
1142 Log.i(TAG, "Wakelock timeout & release race exception in "
1143 + "handleDownloadXtraData()", e);
1144 }
Wei Wangb71c0492017-05-01 20:24:19 -07001145 } else {
1146 Log.e(TAG, "WakeLock expired before release in "
1147 + "handleDownloadXtraData()");
1148 }
Wei Wangc5706f62017-04-18 11:26:26 -07001149 }
Jeff Brown028872f2012-08-25 13:07:01 -07001150 }
Kevin Tang40e1baf2012-01-10 14:32:44 -08001151 });
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001152 }
1153
Mike Lockwood62a8fc12010-03-22 14:23:26 -04001154 private void handleUpdateLocation(Location location) {
Mike Lockwoodd26ce0d2009-06-11 12:25:46 -04001155 if (location.hasAccuracy()) {
1156 native_inject_location(location.getLatitude(), location.getLongitude(),
1157 location.getAccuracy());
1158 }
Mike Lockwoodfd6e5f02009-05-21 11:28:20 -04001159 }
1160
1161 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001162 * Enables this provider. When enabled, calls to getStatus()
Mike Lockwood4e50b782009-04-03 08:24:43 -07001163 * must be handled. Hardware may be started up
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001164 * when the provider is enabled.
1165 */
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001166 @Override
Mike Lockwood62a8fc12010-03-22 14:23:26 -04001167 public void enable() {
Laurent Tu7b5aeca2013-01-24 15:10:24 -08001168 synchronized (mLock) {
1169 if (mEnabled) return;
1170 mEnabled = true;
1171 }
1172
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001173 sendMessage(ENABLE, 1, null);
Mike Lockwood62a8fc12010-03-22 14:23:26 -04001174 }
1175
Tsuwei Chen52617bb2014-08-25 11:49:11 -07001176 private void setSuplHostPort(String hostString, String portString) {
1177 if (hostString != null) {
1178 mSuplServerHost = hostString;
1179 }
1180 if (portString != null) {
1181 try {
1182 mSuplServerPort = Integer.parseInt(portString);
1183 } catch (NumberFormatException e) {
1184 Log.e(TAG, "unable to parse SUPL_PORT: " + portString);
1185 }
1186 }
Tsuwei Chen678c13c2014-09-22 17:48:41 -07001187 if (mSuplServerHost != null
1188 && mSuplServerPort > TCP_MIN_PORT
1189 && mSuplServerPort <= TCP_MAX_PORT) {
1190 native_set_agps_server(AGPS_TYPE_SUPL, mSuplServerHost, mSuplServerPort);
1191 }
Tsuwei Chen52617bb2014-08-25 11:49:11 -07001192 }
1193
Tsuwei Chen462bcd82014-09-17 12:28:49 -07001194 /**
1195 * Checks what SUPL mode to use, according to the AGPS mode as well as the
1196 * allowed mode from properties.
1197 *
gomo48f1a642017-11-10 20:35:46 -08001198 * @param properties GPS properties
Tsuwei Chen462bcd82014-09-17 12:28:49 -07001199 * @param agpsEnabled whether AGPS is enabled by settings value
gomo48f1a642017-11-10 20:35:46 -08001200 * @param singleShot whether "singleshot" is needed
Tsuwei Chen462bcd82014-09-17 12:28:49 -07001201 * @return SUPL mode (MSA vs MSB vs STANDALONE)
1202 */
1203 private int getSuplMode(Properties properties, boolean agpsEnabled, boolean singleShot) {
1204 if (agpsEnabled) {
1205 String modeString = properties.getProperty("SUPL_MODE");
1206 int suplMode = 0;
1207 if (!TextUtils.isEmpty(modeString)) {
1208 try {
1209 suplMode = Integer.parseInt(modeString);
1210 } catch (NumberFormatException e) {
1211 Log.e(TAG, "unable to parse SUPL_MODE: " + modeString);
1212 return GPS_POSITION_MODE_STANDALONE;
1213 }
1214 }
destradaabfb3bdb2015-04-29 14:42:35 -07001215 // MS-Based is the preferred mode for Assisted-GPS position computation, so we favor
1216 // such mode when it is available
1217 if (hasCapability(GPS_CAPABILITY_MSB) && (suplMode & AGPS_SUPL_MODE_MSB) != 0) {
1218 return GPS_POSITION_MODE_MS_BASED;
1219 }
1220 // for now, just as the legacy code did, we fallback to MS-Assisted if it is available,
1221 // do fallback only for single-shot requests, because it is too expensive to do for
1222 // periodic requests as well
Tsuwei Chen462bcd82014-09-17 12:28:49 -07001223 if (singleShot
1224 && hasCapability(GPS_CAPABILITY_MSA)
1225 && (suplMode & AGPS_SUPL_MODE_MSA) != 0) {
1226 return GPS_POSITION_MODE_MS_ASSISTED;
Tsuwei Chen462bcd82014-09-17 12:28:49 -07001227 }
1228 }
1229 return GPS_POSITION_MODE_STANDALONE;
1230 }
1231
Mike Lockwood62a8fc12010-03-22 14:23:26 -04001232 private void handleEnable() {
1233 if (DEBUG) Log.d(TAG, "handleEnable");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001234
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001235 boolean enabled = native_init();
1236
1237 if (enabled) {
Mike Lockwood1a1cd3a2010-08-17 07:42:54 -04001238 mSupportsXtra = native_supports_xtra();
Tsuwei Chen678c13c2014-09-22 17:48:41 -07001239
1240 // TODO: remove the following native calls if we can make sure they are redundant.
Mike Lockwood734d6032009-07-28 18:30:25 -07001241 if (mSuplServerHost != null) {
1242 native_set_agps_server(AGPS_TYPE_SUPL, mSuplServerHost, mSuplServerPort);
1243 }
1244 if (mC2KServerHost != null) {
1245 native_set_agps_server(AGPS_TYPE_C2K, mC2KServerHost, mC2KServerPort);
1246 }
destradaa13a60b02015-01-15 18:36:01 -08001247
Lifu Tang818aa2c2016-02-01 01:52:00 -08001248 mGnssMeasurementsProvider.onGpsEnabledChanged();
1249 mGnssNavigationMessageProvider.onGpsEnabledChanged();
Yu-Han Yang3557cc72018-03-21 12:48:36 -07001250 mGnssBatchingProvider.enable();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001251 } else {
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001252 synchronized (mLock) {
1253 mEnabled = false;
1254 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001255 Log.w(TAG, "Failed to enable location provider");
1256 }
1257 }
1258
1259 /**
1260 * Disables this provider. When disabled, calls to getStatus()
Mike Lockwood4e50b782009-04-03 08:24:43 -07001261 * need not be handled. Hardware may be shut
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001262 * down while the provider is disabled.
1263 */
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001264 @Override
Mike Lockwood62a8fc12010-03-22 14:23:26 -04001265 public void disable() {
Laurent Tu7b5aeca2013-01-24 15:10:24 -08001266 synchronized (mLock) {
1267 if (!mEnabled) return;
1268 mEnabled = false;
1269 }
1270
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001271 sendMessage(ENABLE, 0, null);
Mike Lockwood62a8fc12010-03-22 14:23:26 -04001272 }
1273
1274 private void handleDisable() {
Mike Lockwood89096312010-03-24 10:14:55 -04001275 if (DEBUG) Log.d(TAG, "handleDisable");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001276
David Christie3bc26142013-12-19 14:53:44 -08001277 updateClientUids(new WorkSource());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001278 stopNavigating();
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001279 mAlarmManager.cancel(mWakeupIntent);
1280 mAlarmManager.cancel(mTimeoutIntent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001281
Yu-Han Yang3557cc72018-03-21 12:48:36 -07001282 mGnssBatchingProvider.disable();
Mike Lockwoodcf1d8cb2010-01-20 10:14:54 -05001283 // do this before releasing wakelock
1284 native_cleanup();
destradaa13a60b02015-01-15 18:36:01 -08001285
Lifu Tang818aa2c2016-02-01 01:52:00 -08001286 mGnssMeasurementsProvider.onGpsEnabledChanged();
1287 mGnssNavigationMessageProvider.onGpsEnabledChanged();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001288 }
1289
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001290 @Override
Mike Lockwoodd03ff942010-02-09 08:46:14 -05001291 public boolean isEnabled() {
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001292 synchronized (mLock) {
1293 return mEnabled;
1294 }
Mike Lockwoodd03ff942010-02-09 08:46:14 -05001295 }
1296
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001297 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001298 public int getStatus(Bundle extras) {
Wyatt Rileyc7067412018-02-07 15:50:35 -08001299 mLocationExtras.setBundle(extras);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001300 return mStatus;
1301 }
1302
Wyatt Rileyc7067412018-02-07 15:50:35 -08001303 private void updateStatus(int status) {
1304 if (status != mStatus) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001305 mStatus = status;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001306 mStatusUpdateTime = SystemClock.elapsedRealtime();
1307 }
1308 }
1309
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001310 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001311 public long getStatusUpdateTime() {
1312 return mStatusUpdateTime;
1313 }
1314
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001315 @Override
1316 public void setRequest(ProviderRequest request, WorkSource source) {
1317 sendMessage(SET_REQUEST, 0, new GpsRequest(request, source));
Mike Lockwood62a8fc12010-03-22 14:23:26 -04001318 }
1319
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001320 private void handleSetRequest(ProviderRequest request, WorkSource source) {
David Christied4edf4c2014-08-12 15:22:27 -07001321 mProviderRequest = request;
1322 mWorkSource = source;
1323 updateRequirements();
1324 }
1325
1326 // Called when the requirements for GPS may have changed
1327 private void updateRequirements() {
1328 if (mProviderRequest == null || mWorkSource == null) {
1329 return;
1330 }
1331
Stan Chesnutt1d72d8c2013-04-15 19:18:02 -07001332 boolean singleShot = false;
1333
1334 // see if the request is for a single update
David Christied4edf4c2014-08-12 15:22:27 -07001335 if (mProviderRequest.locationRequests != null
1336 && mProviderRequest.locationRequests.size() > 0) {
Stan Chesnutt1d72d8c2013-04-15 19:18:02 -07001337 // if any request has zero or more than one updates
1338 // requested, then this is not single-shot mode
1339 singleShot = true;
1340
David Christied4edf4c2014-08-12 15:22:27 -07001341 for (LocationRequest lr : mProviderRequest.locationRequests) {
Stan Chesnutt1d72d8c2013-04-15 19:18:02 -07001342 if (lr.getNumUpdates() != 1) {
1343 singleShot = false;
1344 }
1345 }
1346 }
1347
David Christied4edf4c2014-08-12 15:22:27 -07001348 if (DEBUG) Log.d(TAG, "setRequest " + mProviderRequest);
Dante Russo260d6672016-06-20 11:11:59 -07001349 if (mProviderRequest.reportLocation && !mDisableGps && isEnabled()) {
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001350 // update client uids
David Christied4edf4c2014-08-12 15:22:27 -07001351 updateClientUids(mWorkSource);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001352
David Christied4edf4c2014-08-12 15:22:27 -07001353 mFixInterval = (int) mProviderRequest.interval;
gomo48f1a642017-11-10 20:35:46 -08001354 mLowPowerMode = (boolean) mProviderRequest.lowPowerMode;
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001355 // check for overflow
David Christied4edf4c2014-08-12 15:22:27 -07001356 if (mFixInterval != mProviderRequest.interval) {
1357 Log.w(TAG, "interval overflow: " + mProviderRequest.interval);
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001358 mFixInterval = Integer.MAX_VALUE;
1359 }
Mike Lockwood03ca2162010-04-01 08:10:09 -07001360
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001361 // apply request to GPS engine
Mike Lockwood04598b62010-04-14 17:17:24 -04001362 if (mStarted && hasCapability(GPS_CAPABILITY_SCHEDULING)) {
gomo48f1a642017-11-10 20:35:46 -08001363 // change period and/or lowPowerMode
Mike Lockwood04598b62010-04-14 17:17:24 -04001364 if (!native_set_position_mode(mPositionMode, GPS_POSITION_RECURRENCE_PERIODIC,
gomo48f1a642017-11-10 20:35:46 -08001365 mFixInterval, 0, 0, mLowPowerMode)) {
1366 Log.e(TAG, "set_position_mode failed in updateRequirements");
Mike Lockwood04598b62010-04-14 17:17:24 -04001367 }
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001368 } else if (!mStarted) {
1369 // start GPS
Stan Chesnutt1d72d8c2013-04-15 19:18:02 -07001370 startNavigating(singleShot);
gomo300b2402017-12-13 19:04:12 -08001371 } else {
1372 // GNSS Engine is already ON, but no GPS_CAPABILITY_SCHEDULING
1373 mAlarmManager.cancel(mTimeoutIntent);
1374 if (mFixInterval >= NO_FIX_TIMEOUT) {
1375 // set timer to give up if we do not receive a fix within NO_FIX_TIMEOUT
1376 // and our fix interval is not short
1377 mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
1378 SystemClock.elapsedRealtime() + NO_FIX_TIMEOUT, mTimeoutIntent); }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001379 }
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001380 } else {
Dianne Hackborn002a54e2013-01-10 17:34:55 -08001381 updateClientUids(new WorkSource());
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001382
1383 stopNavigating();
1384 mAlarmManager.cancel(mWakeupIntent);
1385 mAlarmManager.cancel(mTimeoutIntent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001386 }
1387 }
1388
Dianne Hackborn002a54e2013-01-10 17:34:55 -08001389 private void updateClientUids(WorkSource source) {
Narayan Kamath32684dd2018-01-08 17:32:51 +00001390 if (source.equals(mClientSource)) {
Victoria Leaseea78b852013-01-15 10:39:28 -08001391 return;
1392 }
Dianne Hackborn002a54e2013-01-10 17:34:55 -08001393
Narayan Kamath32684dd2018-01-08 17:32:51 +00001394 // (1) Inform BatteryStats that the list of IDs we're tracking changed.
1395 try {
1396 mBatteryStats.noteGpsChanged(mClientSource, source);
1397 } catch (RemoteException e) {
1398 Log.w(TAG, "RemoteException", e);
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001399 }
1400
Narayan Kamath32684dd2018-01-08 17:32:51 +00001401 // (2) Inform AppOps service about the list of changes to UIDs.
1402
1403 List<WorkChain>[] diffs = WorkSource.diffChains(mClientSource, source);
1404 if (diffs != null) {
1405 List<WorkChain> newChains = diffs[0];
1406 List<WorkChain> goneChains = diffs[1];
1407
1408 if (newChains != null) {
1409 for (int i = 0; i < newChains.size(); ++i) {
1410 final WorkChain newChain = newChains.get(i);
Svet Ganovf7b47252018-02-26 11:11:27 -08001411 mAppOps.startOpNoThrow(AppOpsManager.OP_GPS, newChain.getAttributionUid(),
1412 newChain.getAttributionTag());
Narayan Kamath32684dd2018-01-08 17:32:51 +00001413 }
1414 }
1415
1416 if (goneChains != null) {
1417 for (int i = 0; i < goneChains.size(); i++) {
1418 final WorkChain goneChain = goneChains.get(i);
Svet Ganovf7b47252018-02-26 11:11:27 -08001419 mAppOps.finishOp(AppOpsManager.OP_GPS, goneChain.getAttributionUid(),
1420 goneChain.getAttributionTag());
Narayan Kamath32684dd2018-01-08 17:32:51 +00001421 }
1422 }
1423
1424 mClientSource.transferWorkChains(source);
1425 }
1426
1427 // Update the flat UIDs and names list and inform app-ops of all changes.
1428 WorkSource[] changes = mClientSource.setReturningDiffs(source);
1429 if (changes != null) {
1430 WorkSource newWork = changes[0];
1431 WorkSource goneWork = changes[1];
1432
1433 // Update sources that were not previously tracked.
1434 if (newWork != null) {
1435 for (int i = 0; i < newWork.size(); i++) {
Svet Ganovf7b47252018-02-26 11:11:27 -08001436 mAppOps.startOpNoThrow(AppOpsManager.OP_GPS,
1437 newWork.get(i), newWork.getName(i));
Narayan Kamath32684dd2018-01-08 17:32:51 +00001438 }
1439 }
1440
1441 // Update sources that are no longer tracked.
1442 if (goneWork != null) {
1443 for (int i = 0; i < goneWork.size(); i++) {
Svet Ganovf7b47252018-02-26 11:11:27 -08001444 mAppOps.finishOp(AppOpsManager.OP_GPS, goneWork.get(i), goneWork.getName(i));
Dianne Hackborn2e418422009-06-22 20:00:17 -07001445 }
Mike Lockwood2f82c4e2009-04-17 08:24:10 -04001446 }
1447 }
1448 }
1449
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001450 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001451 public boolean sendExtraCommand(String command, Bundle extras) {
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001452
Mike Lockwood63aa5a62010-04-14 19:21:31 -04001453 long identity = Binder.clearCallingIdentity();
Peter Visontayb25db362017-11-01 18:18:12 +00001454 try {
1455 boolean result = false;
Mike Lockwood63aa5a62010-04-14 19:21:31 -04001456
Peter Visontayb25db362017-11-01 18:18:12 +00001457 if ("delete_aiding_data".equals(command)) {
1458 result = deleteAidingData(extras);
1459 } else if ("force_time_injection".equals(command)) {
1460 requestUtcTime();
Mike Lockwood63aa5a62010-04-14 19:21:31 -04001461 result = true;
Peter Visontayb25db362017-11-01 18:18:12 +00001462 } else if ("force_xtra_injection".equals(command)) {
1463 if (mSupportsXtra) {
1464 xtraDownloadRequest();
1465 result = true;
1466 }
1467 } else {
1468 Log.w(TAG, "sendExtraCommand: unknown command " + command);
Mike Lockwood93bc44d2009-05-20 16:58:22 -04001469 }
Peter Visontayb25db362017-11-01 18:18:12 +00001470 return result;
1471 } finally {
1472 Binder.restoreCallingIdentity(identity);
Mike Lockwood93bc44d2009-05-20 16:58:22 -04001473 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001474 }
1475
1476 private boolean deleteAidingData(Bundle extras) {
1477 int flags;
1478
1479 if (extras == null) {
1480 flags = GPS_DELETE_ALL;
1481 } else {
1482 flags = 0;
1483 if (extras.getBoolean("ephemeris")) flags |= GPS_DELETE_EPHEMERIS;
1484 if (extras.getBoolean("almanac")) flags |= GPS_DELETE_ALMANAC;
1485 if (extras.getBoolean("position")) flags |= GPS_DELETE_POSITION;
1486 if (extras.getBoolean("time")) flags |= GPS_DELETE_TIME;
1487 if (extras.getBoolean("iono")) flags |= GPS_DELETE_IONO;
1488 if (extras.getBoolean("utc")) flags |= GPS_DELETE_UTC;
1489 if (extras.getBoolean("health")) flags |= GPS_DELETE_HEALTH;
1490 if (extras.getBoolean("svdir")) flags |= GPS_DELETE_SVDIR;
1491 if (extras.getBoolean("svsteer")) flags |= GPS_DELETE_SVSTEER;
1492 if (extras.getBoolean("sadata")) flags |= GPS_DELETE_SADATA;
1493 if (extras.getBoolean("rti")) flags |= GPS_DELETE_RTI;
1494 if (extras.getBoolean("celldb-info")) flags |= GPS_DELETE_CELLDB_INFO;
1495 if (extras.getBoolean("all")) flags |= GPS_DELETE_ALL;
1496 }
1497
1498 if (flags != 0) {
1499 native_delete_aiding_data(flags);
1500 return true;
1501 }
1502
1503 return false;
1504 }
1505
Stan Chesnutt1d72d8c2013-04-15 19:18:02 -07001506 private void startNavigating(boolean singleShot) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001507 if (!mStarted) {
Stan Chesnutt1d72d8c2013-04-15 19:18:02 -07001508 if (DEBUG) Log.d(TAG, "startNavigating, singleShot is " + singleShot);
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001509 mTimeToFirstFix = 0;
1510 mLastFixTime = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001511 mStarted = true;
Stan Chesnutt1d72d8c2013-04-15 19:18:02 -07001512 mSingleShot = singleShot;
Mike Lockwood03ca2162010-04-01 08:10:09 -07001513 mPositionMode = GPS_POSITION_MODE_STANDALONE;
Wyatt Riley5d5bac82016-11-01 07:05:16 -07001514 // Notify about suppressed output, if speed limit was previously exceeded.
1515 // Elsewhere, we check again with every speed output reported.
1516 if (mItarSpeedLimitExceeded) {
1517 Log.i(TAG, "startNavigating with ITAR limit in place. Output limited " +
1518 "until slow enough speed reported.");
1519 }
Mike Lockwood03ca2162010-04-01 08:10:09 -07001520
Tsuwei Chen462bcd82014-09-17 12:28:49 -07001521 boolean agpsEnabled =
1522 (Settings.Global.getInt(mContext.getContentResolver(),
gomo48f1a642017-11-10 20:35:46 -08001523 Settings.Global.ASSISTED_GPS_ENABLED, 1) != 0);
Tsuwei Chen462bcd82014-09-17 12:28:49 -07001524 mPositionMode = getSuplMode(mProperties, agpsEnabled, singleShot);
Mike Lockwoodbcab8df2009-06-25 16:39:09 -04001525
Stan Chesnutt1d72d8c2013-04-15 19:18:02 -07001526 if (DEBUG) {
1527 String mode;
1528
gomo48f1a642017-11-10 20:35:46 -08001529 switch (mPositionMode) {
Stan Chesnutt1d72d8c2013-04-15 19:18:02 -07001530 case GPS_POSITION_MODE_STANDALONE:
1531 mode = "standalone";
1532 break;
1533 case GPS_POSITION_MODE_MS_ASSISTED:
1534 mode = "MS_ASSISTED";
1535 break;
1536 case GPS_POSITION_MODE_MS_BASED:
1537 mode = "MS_BASED";
1538 break;
1539 default:
1540 mode = "unknown";
1541 break;
1542 }
1543 Log.d(TAG, "setting position_mode to " + mode);
1544 }
1545
Mike Lockwood04598b62010-04-14 17:17:24 -04001546 int interval = (hasCapability(GPS_CAPABILITY_SCHEDULING) ? mFixInterval : 1000);
gomo48f1a642017-11-10 20:35:46 -08001547 mLowPowerMode = (boolean) mProviderRequest.lowPowerMode;
Mike Lockwood04598b62010-04-14 17:17:24 -04001548 if (!native_set_position_mode(mPositionMode, GPS_POSITION_RECURRENCE_PERIODIC,
gomo48f1a642017-11-10 20:35:46 -08001549 interval, 0, 0, mLowPowerMode)) {
Mike Lockwood04598b62010-04-14 17:17:24 -04001550 mStarted = false;
1551 Log.e(TAG, "set_position_mode failed in startNavigating()");
1552 return;
1553 }
1554 if (!native_start()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001555 mStarted = false;
1556 Log.e(TAG, "native_start failed in startNavigating()");
Mike Lockwood0632ca72009-05-14 15:51:03 -04001557 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001558 }
1559
1560 // reset SV count to zero
Wyatt Rileyc7067412018-02-07 15:50:35 -08001561 updateStatus(LocationProvider.TEMPORARILY_UNAVAILABLE);
1562 mLocationExtras.reset();
Yipeng Cao282b5942017-05-17 20:31:39 -07001563 mFixRequestTime = SystemClock.elapsedRealtime();
Mike Lockwood04598b62010-04-14 17:17:24 -04001564 if (!hasCapability(GPS_CAPABILITY_SCHEDULING)) {
1565 // set timer to give up if we do not receive a fix within NO_FIX_TIMEOUT
1566 // and our fix interval is not short
1567 if (mFixInterval >= NO_FIX_TIMEOUT) {
1568 mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
1569 SystemClock.elapsedRealtime() + NO_FIX_TIMEOUT, mTimeoutIntent);
1570 }
Mike Lockwood0632ca72009-05-14 15:51:03 -04001571 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001572 }
1573 }
1574
Mike Lockwood62a8fc12010-03-22 14:23:26 -04001575 private void stopNavigating() {
Mike Lockwood29c84342009-05-06 14:01:15 -04001576 if (DEBUG) Log.d(TAG, "stopNavigating");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001577 if (mStarted) {
1578 mStarted = false;
Stan Chesnutt1d72d8c2013-04-15 19:18:02 -07001579 mSingleShot = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001580 native_stop();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001581 mLastFixTime = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001582
1583 // reset SV count to zero
Wyatt Rileyc7067412018-02-07 15:50:35 -08001584 updateStatus(LocationProvider.TEMPORARILY_UNAVAILABLE);
1585 mLocationExtras.reset();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001586 }
1587 }
1588
Mike Lockwood0632ca72009-05-14 15:51:03 -04001589 private void hibernate() {
1590 // stop GPS until our next fix interval arrives
1591 stopNavigating();
Mike Lockwood0632ca72009-05-14 15:51:03 -04001592 mAlarmManager.cancel(mTimeoutIntent);
1593 mAlarmManager.cancel(mWakeupIntent);
1594 long now = SystemClock.elapsedRealtime();
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001595 mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, now + mFixInterval, mWakeupIntent);
Mike Lockwood04598b62010-04-14 17:17:24 -04001596 }
1597
1598 private boolean hasCapability(int capability) {
1599 return ((mEngineCapabilities & capability) != 0);
Mike Lockwood0632ca72009-05-14 15:51:03 -04001600 }
1601
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07001602
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001603 /**
1604 * called from native code to update our position.
1605 */
Wyatt Riley5d229832017-02-10 17:06:00 -08001606 private void reportLocation(boolean hasLatLong, Location location) {
Wyatt Riley26465d22018-02-12 13:44:24 -08001607 sendMessage(REPORT_LOCATION, hasLatLong ? 1 : 0, location);
1608 }
1609
1610 private void handleReportLocation(boolean hasLatLong, Location location) {
Wyatt Riley5d229832017-02-10 17:06:00 -08001611 if (location.hasSpeed()) {
1612 mItarSpeedLimitExceeded = location.getSpeed() > ITAR_SPEED_LIMIT_METERS_PER_SECOND;
Wyatt Riley5d5bac82016-11-01 07:05:16 -07001613 }
1614
1615 if (mItarSpeedLimitExceeded) {
1616 Log.i(TAG, "Hal reported a speed in excess of ITAR limit." +
1617 " GPS/GNSS Navigation output blocked.");
Siddharth Ray53ddc802018-03-16 12:01:52 -07001618 if (mStarted) {
1619 mGnssMetrics.logReceivedLocationStatus(false);
1620 }
Wyatt Riley5d5bac82016-11-01 07:05:16 -07001621 return; // No output of location allowed
1622 }
1623
Wyatt Riley5d229832017-02-10 17:06:00 -08001624 if (VERBOSE) Log.v(TAG, "reportLocation " + location.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001625
Wyatt Riley26465d22018-02-12 13:44:24 -08001626 // It would be nice to push the elapsed real-time timestamp
1627 // further down the stack, but this is still useful
1628 location.setElapsedRealtimeNanos(SystemClock.elapsedRealtimeNanos());
1629 location.setExtras(mLocationExtras.getBundle());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001630
Wyatt Riley26465d22018-02-12 13:44:24 -08001631 try {
1632 mILocationManager.reportLocation(location, false);
1633 } catch (RemoteException e) {
1634 Log.e(TAG, "RemoteException calling reportLocation");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001635 }
1636
Siddharth Ray53ddc802018-03-16 12:01:52 -07001637 if (mStarted) {
1638 mGnssMetrics.logReceivedLocationStatus(hasLatLong);
1639 if (hasLatLong) {
1640 if (location.hasAccuracy()) {
1641 mGnssMetrics.logPositionAccuracyMeters(location.getAccuracy());
1642 }
1643 if (mTimeToFirstFix > 0) {
1644 int timeBetweenFixes = (int) (SystemClock.elapsedRealtime() - mLastFixTime);
1645 mGnssMetrics.logMissedReports(mFixInterval, timeBetweenFixes);
1646 }
Siddharth Raybb608c82017-03-16 11:33:34 -07001647 }
1648 }
1649
Yipeng Cao282b5942017-05-17 20:31:39 -07001650 mLastFixTime = SystemClock.elapsedRealtime();
Hakan Gustavssonfa94ff02010-02-23 09:12:38 +01001651 // report time to first fix
Wyatt Riley5d229832017-02-10 17:06:00 -08001652 if (mTimeToFirstFix == 0 && hasLatLong) {
gomo48f1a642017-11-10 20:35:46 -08001653 mTimeToFirstFix = (int) (mLastFixTime - mFixRequestTime);
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001654 if (DEBUG) Log.d(TAG, "TTFF: " + mTimeToFirstFix);
Siddharth Ray53ddc802018-03-16 12:01:52 -07001655 if (mStarted) {
1656 mGnssMetrics.logTimeToFirstFixMilliSecs(mTimeToFirstFix);
1657 }
Hakan Gustavssonfa94ff02010-02-23 09:12:38 +01001658
1659 // notify status listeners
destradaaea8a8a62014-06-23 18:19:03 -07001660 mListenerHelper.onFirstFix(mTimeToFirstFix);
Hakan Gustavssonfa94ff02010-02-23 09:12:38 +01001661 }
1662
Stan Chesnutt1d72d8c2013-04-15 19:18:02 -07001663 if (mSingleShot) {
1664 stopNavigating();
1665 }
1666
Mike Lockwood15e3d0f2009-05-01 07:53:28 -04001667 if (mStarted && mStatus != LocationProvider.AVAILABLE) {
Wyatt Rileyc7067412018-02-07 15:50:35 -08001668 // For devices that use framework scheduling, a timer may be set to ensure we don't
1669 // spend too much power searching for a location, when the requested update rate is slow.
1670 // As we just recievied a location, we'll cancel that timer.
Mike Lockwood04598b62010-04-14 17:17:24 -04001671 if (!hasCapability(GPS_CAPABILITY_SCHEDULING) && mFixInterval < NO_FIX_TIMEOUT) {
Mike Lockwoodb7be5442010-02-24 14:34:50 -05001672 mAlarmManager.cancel(mTimeoutIntent);
1673 }
1674
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001675 // send an intent to notify that the GPS is receiving fixes.
Mike Lockwood00b74272010-03-26 10:41:48 -04001676 Intent intent = new Intent(LocationManager.GPS_FIX_CHANGE_ACTION);
1677 intent.putExtra(LocationManager.EXTRA_GPS_ENABLED, true);
Dianne Hackborn5ac72a22012-08-29 18:32:08 -07001678 mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
Wyatt Rileyc7067412018-02-07 15:50:35 -08001679 updateStatus(LocationProvider.AVAILABLE);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001680 }
Mike Lockwood29c84342009-05-06 14:01:15 -04001681
gomo48f1a642017-11-10 20:35:46 -08001682 if (!hasCapability(GPS_CAPABILITY_SCHEDULING) && mStarted &&
1683 mFixInterval > GPS_POLLING_THRESHOLD_INTERVAL) {
Mike Lockwoodd53ba012010-04-15 20:41:26 -04001684 if (DEBUG) Log.d(TAG, "got fix, hibernating");
Mike Lockwood0632ca72009-05-14 15:51:03 -04001685 hibernate();
Mike Lockwood29c84342009-05-06 14:01:15 -04001686 }
gomo48f1a642017-11-10 20:35:46 -08001687 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001688
1689 /**
1690 * called from native code to update our status
1691 */
1692 private void reportStatus(int status) {
Mike Lockwoodb8d90332010-10-18 17:59:48 -04001693 if (DEBUG) Log.v(TAG, "reportStatus status: " + status);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001694
destradaaea8a8a62014-06-23 18:19:03 -07001695 boolean wasNavigating = mNavigating;
1696 switch (status) {
1697 case GPS_STATUS_SESSION_BEGIN:
1698 mNavigating = true;
1699 mEngineOn = true;
1700 break;
1701 case GPS_STATUS_SESSION_END:
1702 mNavigating = false;
1703 break;
1704 case GPS_STATUS_ENGINE_ON:
1705 mEngineOn = true;
1706 break;
1707 case GPS_STATUS_ENGINE_OFF:
1708 mEngineOn = false;
1709 mNavigating = false;
1710 break;
1711 }
Mike Lockwooddbd6fd82009-12-07 18:43:36 -05001712
destradaaea8a8a62014-06-23 18:19:03 -07001713 if (wasNavigating != mNavigating) {
destradaa13a60b02015-01-15 18:36:01 -08001714 mListenerHelper.onStatusChanged(mNavigating);
Mike Lockwoodcf1d8cb2010-01-20 10:14:54 -05001715
destradaaea8a8a62014-06-23 18:19:03 -07001716 // send an intent to notify that the GPS has been enabled or disabled
1717 Intent intent = new Intent(LocationManager.GPS_ENABLED_CHANGE_ACTION);
1718 intent.putExtra(LocationManager.EXTRA_GPS_ENABLED, mNavigating);
1719 mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001720 }
1721 }
1722
Wyatt Riley26465d22018-02-12 13:44:24 -08001723 // Helper class to carry data to handler for reportSvStatus
1724 private static class SvStatusInfo {
1725 public int mSvCount;
1726 public int[] mSvidWithFlags;
1727 public float[] mCn0s;
1728 public float[] mSvElevations;
1729 public float[] mSvAzimuths;
1730 public float[] mSvCarrierFreqs;
1731 }
1732
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001733 /**
1734 * called from native code to update SV info
1735 */
Wyatt Riley26465d22018-02-12 13:44:24 -08001736 private void reportSvStatus(int svCount, int[] svidWithFlags, float[] cn0s,
1737 float[] svElevations, float[] svAzimuths, float[] svCarrierFreqs) {
1738 SvStatusInfo svStatusInfo = new SvStatusInfo();
1739 svStatusInfo.mSvCount = svCount;
1740 svStatusInfo.mSvidWithFlags = svidWithFlags;
1741 svStatusInfo.mCn0s = cn0s;
1742 svStatusInfo.mSvElevations = svElevations;
1743 svStatusInfo.mSvAzimuths = svAzimuths;
1744 svStatusInfo.mSvCarrierFreqs = svCarrierFreqs;
1745
1746 sendMessage(REPORT_SV_STATUS, 0, svStatusInfo);
1747 }
1748
1749 private void handleReportSvStatus(SvStatusInfo info) {
destradaaea8a8a62014-06-23 18:19:03 -07001750 mListenerHelper.onSvStatusChanged(
Wyatt Riley26465d22018-02-12 13:44:24 -08001751 info.mSvCount,
1752 info.mSvidWithFlags,
1753 info.mCn0s,
1754 info.mSvElevations,
1755 info.mSvAzimuths,
1756 info.mSvCarrierFreqs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001757
Siddharth Ray168f12a2017-07-10 11:55:10 -07001758 // Log CN0 as part of GNSS metrics
Wyatt Riley26465d22018-02-12 13:44:24 -08001759 mGnssMetrics.logCn0(info.mCn0s, info.mSvCount);
Siddharth Ray168f12a2017-07-10 11:55:10 -07001760
Mike Lockwood29c84342009-05-06 14:01:15 -04001761 if (VERBOSE) {
Wyatt Riley26465d22018-02-12 13:44:24 -08001762 Log.v(TAG, "SV count: " + info.mSvCount);
Lifu Tang30f95a72016-01-07 23:20:38 -08001763 }
Wyatt Rileyc9f25dd2017-05-05 13:45:23 -07001764 // Calculate number of satellites used in fix.
Lifu Tang30f95a72016-01-07 23:20:38 -08001765 int usedInFixCount = 0;
Wyatt Rileyc9f25dd2017-05-05 13:45:23 -07001766 int maxCn0 = 0;
1767 int meanCn0 = 0;
Wyatt Riley26465d22018-02-12 13:44:24 -08001768 for (int i = 0; i < info.mSvCount; i++) {
1769 if ((info.mSvidWithFlags[i] & GnssStatus.GNSS_SV_FLAGS_USED_IN_FIX) != 0) {
Lifu Tang30f95a72016-01-07 23:20:38 -08001770 ++usedInFixCount;
Wyatt Riley26465d22018-02-12 13:44:24 -08001771 if (info.mCn0s[i] > maxCn0) {
1772 maxCn0 = (int) info.mCn0s[i];
Wyatt Rileyc9f25dd2017-05-05 13:45:23 -07001773 }
Wyatt Riley26465d22018-02-12 13:44:24 -08001774 meanCn0 += info.mCn0s[i];
Lifu Tang30f95a72016-01-07 23:20:38 -08001775 }
1776 if (VERBOSE) {
Wyatt Riley26465d22018-02-12 13:44:24 -08001777 Log.v(TAG, "svid: " + (info.mSvidWithFlags[i] >> GnssStatus.SVID_SHIFT_WIDTH) +
1778 " cn0: " + info.mCn0s[i] +
1779 " elev: " + info.mSvElevations[i] +
1780 " azimuth: " + info.mSvAzimuths[i] +
1781 " carrier frequency: " + info.mSvCarrierFreqs[i] +
1782 ((info.mSvidWithFlags[i] & GnssStatus.GNSS_SV_FLAGS_HAS_EPHEMERIS_DATA) == 0
Lifu Tang30f95a72016-01-07 23:20:38 -08001783 ? " " : " E") +
Wyatt Riley26465d22018-02-12 13:44:24 -08001784 ((info.mSvidWithFlags[i] & GnssStatus.GNSS_SV_FLAGS_HAS_ALMANAC_DATA) == 0
Lifu Tang30f95a72016-01-07 23:20:38 -08001785 ? " " : " A") +
Wyatt Riley26465d22018-02-12 13:44:24 -08001786 ((info.mSvidWithFlags[i] & GnssStatus.GNSS_SV_FLAGS_USED_IN_FIX) == 0
gomo4402af62017-01-11 13:20:13 -08001787 ? "" : "U") +
Wyatt Riley26465d22018-02-12 13:44:24 -08001788 ((info.mSvidWithFlags[i] &
1789 GnssStatus.GNSS_SV_FLAGS_HAS_CARRIER_FREQUENCY) == 0
gomo48f1a642017-11-10 20:35:46 -08001790 ? "" : "F"));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001791 }
1792 }
Wyatt Rileyc9f25dd2017-05-05 13:45:23 -07001793 if (usedInFixCount > 0) {
1794 meanCn0 /= usedInFixCount;
1795 }
1796 // return number of sats used in fix instead of total reported
Wyatt Rileyc7067412018-02-07 15:50:35 -08001797 mLocationExtras.set(usedInFixCount, meanCn0, maxCn0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001798
Mike Lockwood15e3d0f2009-05-01 07:53:28 -04001799 if (mNavigating && mStatus == LocationProvider.AVAILABLE && mLastFixTime > 0 &&
gomo48f1a642017-11-10 20:35:46 -08001800 SystemClock.elapsedRealtime() - mLastFixTime > RECENT_FIX_TIMEOUT) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001801 // send an intent to notify that the GPS is no longer receiving fixes.
Mike Lockwood00b74272010-03-26 10:41:48 -04001802 Intent intent = new Intent(LocationManager.GPS_FIX_CHANGE_ACTION);
1803 intent.putExtra(LocationManager.EXTRA_GPS_ENABLED, false);
Dianne Hackborn5ac72a22012-08-29 18:32:08 -07001804 mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
Wyatt Rileyc7067412018-02-07 15:50:35 -08001805 updateStatus(LocationProvider.TEMPORARILY_UNAVAILABLE);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001806 }
1807 }
Mike Lockwood58bda982009-04-14 16:25:07 -04001808
1809 /**
Mike Lockwoode3635c92009-05-11 08:38:02 -04001810 * called from native code to update AGPS status
Mike Lockwood58bda982009-04-14 16:25:07 -04001811 */
destradaa96a14702014-06-05 11:36:30 -07001812 private void reportAGpsStatus(int type, int status, byte[] ipaddr) {
Mike Lockwood58bda982009-04-14 16:25:07 -04001813 switch (status) {
Mike Lockwoode3635c92009-05-11 08:38:02 -04001814 case GPS_REQUEST_AGPS_DATA_CONN:
Mike Lockwoodb6e5fa82010-10-09 20:10:46 -04001815 if (DEBUG) Log.d(TAG, "GPS_REQUEST_AGPS_DATA_CONN");
Andreas Gampee6748ce2015-12-11 18:00:38 -08001816 Log.v(TAG, "Received SUPL IP addr[]: " + Arrays.toString(ipaddr));
destradaae21252a2015-09-08 12:32:59 -07001817 InetAddress connectionIpAddress = null;
destradaa96a14702014-06-05 11:36:30 -07001818 if (ipaddr != null) {
1819 try {
destradaae21252a2015-09-08 12:32:59 -07001820 connectionIpAddress = InetAddress.getByAddress(ipaddr);
1821 if (DEBUG) Log.d(TAG, "IP address converted to: " + connectionIpAddress);
destradaa96a14702014-06-05 11:36:30 -07001822 } catch (UnknownHostException e) {
1823 Log.e(TAG, "Bad IP Address: " + ipaddr, e);
destradaa96a14702014-06-05 11:36:30 -07001824 }
1825 }
destradaae21252a2015-09-08 12:32:59 -07001826 sendMessage(REQUEST_SUPL_CONNECTION, 0 /*arg*/, connectionIpAddress);
Mike Lockwood58bda982009-04-14 16:25:07 -04001827 break;
Mike Lockwoode3635c92009-05-11 08:38:02 -04001828 case GPS_RELEASE_AGPS_DATA_CONN:
Mike Lockwoodb6e5fa82010-10-09 20:10:46 -04001829 if (DEBUG) Log.d(TAG, "GPS_RELEASE_AGPS_DATA_CONN");
destradaae21252a2015-09-08 12:32:59 -07001830 releaseSuplConnection(GPS_RELEASE_AGPS_DATA_CONN);
Mike Lockwood58bda982009-04-14 16:25:07 -04001831 break;
Mike Lockwoode3635c92009-05-11 08:38:02 -04001832 case GPS_AGPS_DATA_CONNECTED:
Mike Lockwoodb6e5fa82010-10-09 20:10:46 -04001833 if (DEBUG) Log.d(TAG, "GPS_AGPS_DATA_CONNECTED");
Mike Lockwood58bda982009-04-14 16:25:07 -04001834 break;
Mike Lockwoode3635c92009-05-11 08:38:02 -04001835 case GPS_AGPS_DATA_CONN_DONE:
Mike Lockwoodb6e5fa82010-10-09 20:10:46 -04001836 if (DEBUG) Log.d(TAG, "GPS_AGPS_DATA_CONN_DONE");
Mike Lockwood58bda982009-04-14 16:25:07 -04001837 break;
Mike Lockwoode3635c92009-05-11 08:38:02 -04001838 case GPS_AGPS_DATA_CONN_FAILED:
Mike Lockwoodb6e5fa82010-10-09 20:10:46 -04001839 if (DEBUG) Log.d(TAG, "GPS_AGPS_DATA_CONN_FAILED");
Mike Lockwood58bda982009-04-14 16:25:07 -04001840 break;
destradaa931a37f2014-08-12 16:36:59 -07001841 default:
Joe Onorato0c484102016-02-01 18:04:24 -08001842 if (DEBUG) Log.d(TAG, "Received Unknown AGPS status: " + status);
Mike Lockwood58bda982009-04-14 16:25:07 -04001843 }
1844 }
1845
destradaae21252a2015-09-08 12:32:59 -07001846 private void releaseSuplConnection(int connStatus) {
1847 sendMessage(RELEASE_SUPL_CONNECTION, connStatus, null /*obj*/);
1848 }
1849
Mike Lockwoodb16e7802009-08-06 09:26:02 -04001850 /**
1851 * called from native code to report NMEA data received
1852 */
Mike Lockwoodf602d362010-06-20 14:28:16 -07001853 private void reportNmea(long timestamp) {
Wyatt Riley5d5bac82016-11-01 07:05:16 -07001854 if (!mItarSpeedLimitExceeded) {
1855 int length = native_read_nmea(mNmeaBuffer, mNmeaBuffer.length);
1856 String nmea = new String(mNmeaBuffer, 0 /* offset */, length);
1857 mListenerHelper.onNmeaReceived(timestamp, nmea);
1858 }
destradaaea8a8a62014-06-23 18:19:03 -07001859 }
Mike Lockwoodb16e7802009-08-06 09:26:02 -04001860
destradaaea8a8a62014-06-23 18:19:03 -07001861 /**
Wyatt Rileyaa420d52017-07-03 15:14:42 -07001862 * called from native code - GNSS measurements callback
destradaaea8a8a62014-06-23 18:19:03 -07001863 */
Lifu Tang818aa2c2016-02-01 01:52:00 -08001864 private void reportMeasurementData(GnssMeasurementsEvent event) {
Wyatt Riley5d5bac82016-11-01 07:05:16 -07001865 if (!mItarSpeedLimitExceeded) {
Wyatt Rileyaa420d52017-07-03 15:14:42 -07001866 // send to handler to allow native to return quickly
1867 mHandler.post(new Runnable() {
1868 @Override
1869 public void run() {
1870 mGnssMeasurementsProvider.onMeasurementsAvailable(event);
1871 }
1872 });
Wyatt Riley5d5bac82016-11-01 07:05:16 -07001873 }
Mike Lockwoodb16e7802009-08-06 09:26:02 -04001874 }
1875
Mike Lockwood62a8fc12010-03-22 14:23:26 -04001876 /**
Wyatt Rileyaa420d52017-07-03 15:14:42 -07001877 * called from native code - GNSS navigation message callback
destradaa4b3e3932014-07-21 18:01:47 -07001878 */
Lifu Tange8abe8e2016-04-01 10:32:05 -07001879 private void reportNavigationMessage(GnssNavigationMessage event) {
Wyatt Riley5d5bac82016-11-01 07:05:16 -07001880 if (!mItarSpeedLimitExceeded) {
Wyatt Rileyaa420d52017-07-03 15:14:42 -07001881 // send to handler to allow native to return quickly
1882 mHandler.post(new Runnable() {
1883 @Override
1884 public void run() {
1885 mGnssNavigationMessageProvider.onNavigationMessageAvailable(event);
1886 }
1887 });
Wyatt Riley5d5bac82016-11-01 07:05:16 -07001888 }
destradaa4b3e3932014-07-21 18:01:47 -07001889 }
1890
1891 /**
Mike Lockwood04598b62010-04-14 17:17:24 -04001892 * called from native code to inform us what the GPS engine capabilities are
1893 */
Wyatt Rileyd87cf912017-12-05 09:31:52 -08001894 private void setEngineCapabilities(final int capabilities) {
1895 // send to handler thread for fast native return, and in-order handling
1896 mHandler.post(new Runnable() {
1897 @Override
1898 public void run() {
1899 mEngineCapabilities = capabilities;
Mike Lockwood9b9fb5c2011-06-29 15:09:40 -04001900
Wyatt Rileyd87cf912017-12-05 09:31:52 -08001901 if (hasCapability(GPS_CAPABILITY_ON_DEMAND_TIME)) {
Yu-Han Yanga1862b52018-02-20 17:05:59 -08001902 mNtpTimeHelper.enablePeriodicTimeInjection();
Wyatt Rileyd87cf912017-12-05 09:31:52 -08001903 requestUtcTime();
1904 }
destradaa6568d702014-10-27 12:47:41 -07001905
Wyatt Rileyd87cf912017-12-05 09:31:52 -08001906 mGnssMeasurementsProvider.onCapabilitiesUpdated(hasCapability(
1907 GPS_CAPABILITY_MEASUREMENTS));
1908 mGnssNavigationMessageProvider.onCapabilitiesUpdated(hasCapability(
1909 GPS_CAPABILITY_NAV_MESSAGES));
1910 }
1911 });
1912 }
1913
1914 /**
1915 * Called from native code to inform us the hardware year.
1916 */
1917 private void setGnssYearOfHardware(final int yearOfHardware) {
1918 // mHardwareYear is simply set here, to be read elsewhere, and is volatile for safe sync
1919 if (DEBUG) Log.d(TAG, "setGnssYearOfHardware called with " + yearOfHardware);
1920 mHardwareYear = yearOfHardware;
Mike Lockwood04598b62010-04-14 17:17:24 -04001921 }
1922
1923 /**
Wyatt Rileyd87cf912017-12-05 09:31:52 -08001924 * Called from native code to inform us the hardware model name.
Lifu Tang82f893d2016-01-21 18:15:33 -08001925 */
Wyatt Rileyd87cf912017-12-05 09:31:52 -08001926 private void setGnssHardwareModelName(final String modelName) {
1927 // mHardwareModelName is simply set here, to be read elsewhere, and volatile for safe sync
1928 if (DEBUG) Log.d(TAG, "setGnssModelName called with " + modelName);
1929 mHardwareModelName = modelName;
Lifu Tang82f893d2016-01-21 18:15:33 -08001930 }
1931
Lifu Tang9363b942016-02-16 18:07:00 -08001932 public interface GnssSystemInfoProvider {
Lifu Tang82f893d2016-01-21 18:15:33 -08001933 /**
Wyatt Rileyd87cf912017-12-05 09:31:52 -08001934 * Returns the year of underlying GPS hardware.
Lifu Tang82f893d2016-01-21 18:15:33 -08001935 */
Lifu Tang9363b942016-02-16 18:07:00 -08001936 int getGnssYearOfHardware();
Wyatt Rileyd87cf912017-12-05 09:31:52 -08001937 /**
1938 * Returns the model name of underlying GPS hardware.
1939 */
1940 String getGnssHardwareModelName();
Lifu Tang82f893d2016-01-21 18:15:33 -08001941 }
1942
1943 /**
1944 * @hide
1945 */
Lifu Tang9363b942016-02-16 18:07:00 -08001946 public GnssSystemInfoProvider getGnssSystemInfoProvider() {
1947 return new GnssSystemInfoProvider() {
Lifu Tang82f893d2016-01-21 18:15:33 -08001948 @Override
Lifu Tang9363b942016-02-16 18:07:00 -08001949 public int getGnssYearOfHardware() {
Wyatt Rileyd87cf912017-12-05 09:31:52 -08001950 return mHardwareYear;
1951 }
1952 @Override
1953 public String getGnssHardwareModelName() {
1954 return mHardwareModelName;
Lifu Tang82f893d2016-01-21 18:15:33 -08001955 }
1956 };
1957 }
1958
Wyatt Rileycf879db2017-01-12 13:57:38 -08001959 /**
1960 * @hide
1961 */
1962 public GnssBatchingProvider getGnssBatchingProvider() {
Yu-Han Yang3557cc72018-03-21 12:48:36 -07001963 return mGnssBatchingProvider;
Wyatt Rileycf879db2017-01-12 13:57:38 -08001964 }
1965
Siddharth Raybb608c82017-03-16 11:33:34 -07001966 public interface GnssMetricsProvider {
1967 /**
1968 * Returns GNSS metrics as proto string
1969 */
1970 String getGnssMetricsAsProtoString();
1971 }
1972
1973 /**
1974 * @hide
1975 */
1976 public GnssMetricsProvider getGnssMetricsProvider() {
1977 return new GnssMetricsProvider() {
1978 @Override
1979 public String getGnssMetricsAsProtoString() {
1980 return mGnssMetrics.dumpGnssMetricsAsProtoString();
1981 }
1982 };
1983 }
1984
Wyatt Rileycf879db2017-01-12 13:57:38 -08001985 /**
Wyatt Rileycf879db2017-01-12 13:57:38 -08001986 * called from native code - GNSS location batch callback
1987 */
1988 private void reportLocationBatch(Location[] locationArray) {
1989 List<Location> locations = new ArrayList<>(Arrays.asList(locationArray));
gomo48f1a642017-11-10 20:35:46 -08001990 if (DEBUG) {
1991 Log.d(TAG, "Location batch of size " + locationArray.length + " reported");
1992 }
Wyatt Rileycf879db2017-01-12 13:57:38 -08001993 try {
1994 mILocationManager.reportLocationBatch(locations);
1995 } catch (RemoteException e) {
1996 Log.e(TAG, "RemoteException calling reportLocationBatch");
1997 }
1998 }
1999
Lifu Tang82f893d2016-01-21 18:15:33 -08002000 /**
Mike Lockwood62a8fc12010-03-22 14:23:26 -04002001 * called from native code to request XTRA data
2002 */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002003 private void xtraDownloadRequest() {
Joe Onoratof5d95cb2010-01-07 21:48:32 -05002004 if (DEBUG) Log.d(TAG, "xtraDownloadRequest");
Mike Lockwood98e48692010-04-07 16:32:51 -04002005 sendMessage(DOWNLOAD_XTRA_DATA, 0, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002006 }
2007
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07002008 /**
destradaa0682809a2013-08-12 18:50:30 -07002009 * Converts the GPS HAL status to the internal Geofence Hardware status.
2010 */
2011 private int getGeofenceStatus(int status) {
gomo48f1a642017-11-10 20:35:46 -08002012 switch (status) {
destradaa0682809a2013-08-12 18:50:30 -07002013 case GPS_GEOFENCE_OPERATION_SUCCESS:
2014 return GeofenceHardware.GEOFENCE_SUCCESS;
2015 case GPS_GEOFENCE_ERROR_GENERIC:
2016 return GeofenceHardware.GEOFENCE_FAILURE;
2017 case GPS_GEOFENCE_ERROR_ID_EXISTS:
2018 return GeofenceHardware.GEOFENCE_ERROR_ID_EXISTS;
2019 case GPS_GEOFENCE_ERROR_INVALID_TRANSITION:
2020 return GeofenceHardware.GEOFENCE_ERROR_INVALID_TRANSITION;
2021 case GPS_GEOFENCE_ERROR_TOO_MANY_GEOFENCES:
2022 return GeofenceHardware.GEOFENCE_ERROR_TOO_MANY_GEOFENCES;
2023 case GPS_GEOFENCE_ERROR_ID_UNKNOWN:
2024 return GeofenceHardware.GEOFENCE_ERROR_ID_UNKNOWN;
2025 default:
2026 return -1;
2027 }
2028 }
2029
2030 /**
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07002031 * Called from native to report GPS Geofence transition
2032 * All geofence callbacks are called on the same thread
2033 */
Wyatt Riley5d229832017-02-10 17:06:00 -08002034 private void reportGeofenceTransition(int geofenceId, Location location, int transition,
gomo48f1a642017-11-10 20:35:46 -08002035 long transitionTimestamp) {
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07002036 if (mGeofenceHardwareImpl == null) {
2037 mGeofenceHardwareImpl = GeofenceHardwareImpl.getInstance(mContext);
2038 }
Wyatt Riley5d229832017-02-10 17:06:00 -08002039
destradaa0682809a2013-08-12 18:50:30 -07002040 mGeofenceHardwareImpl.reportGeofenceTransition(
2041 geofenceId,
2042 location,
2043 transition,
2044 transitionTimestamp,
2045 GeofenceHardware.MONITORING_TYPE_GPS_HARDWARE,
2046 FusedBatchOptions.SourceTechnologies.GNSS);
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07002047 }
2048
2049 /**
2050 * called from native code to report GPS status change.
2051 */
Wyatt Riley5d229832017-02-10 17:06:00 -08002052 private void reportGeofenceStatus(int status, Location location) {
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07002053 if (mGeofenceHardwareImpl == null) {
2054 mGeofenceHardwareImpl = GeofenceHardwareImpl.getInstance(mContext);
2055 }
destradaa0682809a2013-08-12 18:50:30 -07002056 int monitorStatus = GeofenceHardware.MONITOR_CURRENTLY_UNAVAILABLE;
gomo48f1a642017-11-10 20:35:46 -08002057 if (status == GPS_GEOFENCE_AVAILABLE) {
destradaa0682809a2013-08-12 18:50:30 -07002058 monitorStatus = GeofenceHardware.MONITOR_CURRENTLY_AVAILABLE;
2059 }
2060 mGeofenceHardwareImpl.reportGeofenceMonitorStatus(
2061 GeofenceHardware.MONITORING_TYPE_GPS_HARDWARE,
2062 monitorStatus,
2063 location,
2064 FusedBatchOptions.SourceTechnologies.GNSS);
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07002065 }
2066
2067 /**
2068 * called from native code - Geofence Add callback
2069 */
2070 private void reportGeofenceAddStatus(int geofenceId, int status) {
2071 if (mGeofenceHardwareImpl == null) {
2072 mGeofenceHardwareImpl = GeofenceHardwareImpl.getInstance(mContext);
2073 }
destradaa0682809a2013-08-12 18:50:30 -07002074 mGeofenceHardwareImpl.reportGeofenceAddStatus(geofenceId, getGeofenceStatus(status));
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07002075 }
2076
2077 /**
2078 * called from native code - Geofence Remove callback
2079 */
2080 private void reportGeofenceRemoveStatus(int geofenceId, int status) {
2081 if (mGeofenceHardwareImpl == null) {
2082 mGeofenceHardwareImpl = GeofenceHardwareImpl.getInstance(mContext);
2083 }
destradaa0682809a2013-08-12 18:50:30 -07002084 mGeofenceHardwareImpl.reportGeofenceRemoveStatus(geofenceId, getGeofenceStatus(status));
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07002085 }
2086
2087 /**
2088 * called from native code - Geofence Pause callback
2089 */
2090 private void reportGeofencePauseStatus(int geofenceId, int status) {
2091 if (mGeofenceHardwareImpl == null) {
2092 mGeofenceHardwareImpl = GeofenceHardwareImpl.getInstance(mContext);
2093 }
destradaa0682809a2013-08-12 18:50:30 -07002094 mGeofenceHardwareImpl.reportGeofencePauseStatus(geofenceId, getGeofenceStatus(status));
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07002095 }
2096
2097 /**
2098 * called from native code - Geofence Resume callback
2099 */
2100 private void reportGeofenceResumeStatus(int geofenceId, int status) {
2101 if (mGeofenceHardwareImpl == null) {
2102 mGeofenceHardwareImpl = GeofenceHardwareImpl.getInstance(mContext);
2103 }
destradaa0682809a2013-08-12 18:50:30 -07002104 mGeofenceHardwareImpl.reportGeofenceResumeStatus(geofenceId, getGeofenceStatus(status));
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07002105 }
2106
Danke Xie22d1f9f2009-08-18 18:28:45 -04002107 //=============================================================
2108 // NI Client support
Miguel Torroja1e84da82010-07-27 07:02:24 +02002109 //=============================================================
Danke Xie22d1f9f2009-08-18 18:28:45 -04002110 private final INetInitiatedListener mNetInitiatedListener = new INetInitiatedListener.Stub() {
destradaaef752b62015-04-17 13:10:47 -07002111 // Sends a response for an NI request to HAL.
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002112 @Override
gomo48f1a642017-11-10 20:35:46 -08002113 public boolean sendNiResponse(int notificationId, int userResponse) {
Miguel Torroja1e84da82010-07-27 07:02:24 +02002114 // TODO Add Permission check
Danke Xie22d1f9f2009-08-18 18:28:45 -04002115
gomo48f1a642017-11-10 20:35:46 -08002116 if (DEBUG) {
2117 Log.d(TAG, "sendNiResponse, notifId: " + notificationId +
2118 ", response: " + userResponse);
2119 }
Miguel Torroja1e84da82010-07-27 07:02:24 +02002120 native_send_ni_response(notificationId, userResponse);
2121 return true;
2122 }
Danke Xie22d1f9f2009-08-18 18:28:45 -04002123 };
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002124
Danke Xie22d1f9f2009-08-18 18:28:45 -04002125 public INetInitiatedListener getNetInitiatedListener() {
2126 return mNetInitiatedListener;
2127 }
2128
2129 // Called by JNI function to report an NI request.
Miguel Torroja1e84da82010-07-27 07:02:24 +02002130 public void reportNiNotification(
2131 int notificationId,
2132 int niType,
2133 int notifyFlags,
2134 int timeout,
2135 int defaultResponse,
2136 String requestorId,
2137 String text,
2138 int requestorIdEncoding,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002139 int textEncoding
gomo48f1a642017-11-10 20:35:46 -08002140 ) {
Miguel Torroja1e84da82010-07-27 07:02:24 +02002141 Log.i(TAG, "reportNiNotification: entered");
2142 Log.i(TAG, "notificationId: " + notificationId +
2143 ", niType: " + niType +
2144 ", notifyFlags: " + notifyFlags +
2145 ", timeout: " + timeout +
2146 ", defaultResponse: " + defaultResponse);
2147
2148 Log.i(TAG, "requestorId: " + requestorId +
2149 ", text: " + text +
2150 ", requestorIdEncoding: " + requestorIdEncoding +
2151 ", textEncoding: " + textEncoding);
2152
2153 GpsNiNotification notification = new GpsNiNotification();
2154
2155 notification.notificationId = notificationId;
2156 notification.niType = niType;
2157 notification.needNotify = (notifyFlags & GpsNetInitiatedHandler.GPS_NI_NEED_NOTIFY) != 0;
2158 notification.needVerify = (notifyFlags & GpsNetInitiatedHandler.GPS_NI_NEED_VERIFY) != 0;
gomo48f1a642017-11-10 20:35:46 -08002159 notification.privacyOverride =
2160 (notifyFlags & GpsNetInitiatedHandler.GPS_NI_PRIVACY_OVERRIDE) != 0;
Miguel Torroja1e84da82010-07-27 07:02:24 +02002161 notification.timeout = timeout;
2162 notification.defaultResponse = defaultResponse;
2163 notification.requestorId = requestorId;
2164 notification.text = text;
2165 notification.requestorIdEncoding = requestorIdEncoding;
2166 notification.textEncoding = textEncoding;
2167
Miguel Torroja1e84da82010-07-27 07:02:24 +02002168 mNIHandler.handleNiNotification(notification);
2169 }
2170
2171 /**
2172 * Called from native code to request set id info.
2173 * We should be careful about receiving null string from the TelephonyManager,
2174 * because sending null String to JNI function would cause a crash.
2175 */
2176
2177 private void requestSetID(int flags) {
2178 TelephonyManager phone = (TelephonyManager)
2179 mContext.getSystemService(Context.TELEPHONY_SERVICE);
destradaaef752b62015-04-17 13:10:47 -07002180 int type = AGPS_SETID_TYPE_NONE;
Miguel Torroja1e84da82010-07-27 07:02:24 +02002181 String data = "";
2182
2183 if ((flags & AGPS_RIL_REQUEST_SETID_IMSI) == AGPS_RIL_REQUEST_SETID_IMSI) {
2184 String data_temp = phone.getSubscriberId();
2185 if (data_temp == null) {
2186 // This means the framework does not have the SIM card ready.
2187 } else {
2188 // This means the framework has the SIM card.
2189 data = data_temp;
2190 type = AGPS_SETID_TYPE_IMSI;
2191 }
gomo48f1a642017-11-10 20:35:46 -08002192 } else if ((flags & AGPS_RIL_REQUEST_SETID_MSISDN) == AGPS_RIL_REQUEST_SETID_MSISDN) {
Miguel Torroja1e84da82010-07-27 07:02:24 +02002193 String data_temp = phone.getLine1Number();
2194 if (data_temp == null) {
2195 // This means the framework does not have the SIM card ready.
2196 } else {
2197 // This means the framework has the SIM card.
2198 data = data_temp;
2199 type = AGPS_SETID_TYPE_MSISDN;
2200 }
2201 }
2202 native_agps_set_id(type, data);
2203 }
2204
2205 /**
Yu-Han Yange7baef32018-02-09 13:58:17 -08002206 * Called from native code to request location info.
2207 */
2208 private void requestLocation(boolean independentFromGnss) {
2209 if (DEBUG) {
2210 Log.d(TAG, "requestLocation. independentFromGnss: " + independentFromGnss);
2211 }
2212 sendMessage(REQUEST_LOCATION, 0, independentFromGnss);
2213 }
2214
2215 /**
Mike Lockwood9b9fb5c2011-06-29 15:09:40 -04002216 * Called from native code to request utc time info
2217 */
Mike Lockwood9b9fb5c2011-06-29 15:09:40 -04002218 private void requestUtcTime() {
destradaae21252a2015-09-08 12:32:59 -07002219 if (DEBUG) Log.d(TAG, "utcTimeRequest");
Mike Lockwood9b9fb5c2011-06-29 15:09:40 -04002220 sendMessage(INJECT_NTP_TIME, 0, null);
2221 }
2222
2223 /**
Miguel Torroja1e84da82010-07-27 07:02:24 +02002224 * Called from native code to request reference location info
2225 */
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002226 private void requestRefLocation() {
Miguel Torroja1e84da82010-07-27 07:02:24 +02002227 TelephonyManager phone = (TelephonyManager)
2228 mContext.getSystemService(Context.TELEPHONY_SERVICE);
Victoria Leased50d0c32012-10-29 13:16:17 -07002229 final int phoneType = phone.getPhoneType();
2230 if (phoneType == TelephonyManager.PHONE_TYPE_GSM) {
Miguel Torroja1e84da82010-07-27 07:02:24 +02002231 GsmCellLocation gsm_cell = (GsmCellLocation) phone.getCellLocation();
Victoria Leased50d0c32012-10-29 13:16:17 -07002232 if ((gsm_cell != null) && (phone.getNetworkOperator() != null)
2233 && (phone.getNetworkOperator().length() > 3)) {
Miguel Torroja1e84da82010-07-27 07:02:24 +02002234 int type;
gomo48f1a642017-11-10 20:35:46 -08002235 int mcc = Integer.parseInt(phone.getNetworkOperator().substring(0, 3));
Miguel Torroja1e84da82010-07-27 07:02:24 +02002236 int mnc = Integer.parseInt(phone.getNetworkOperator().substring(3));
Mike Lockwoodedc0f3872010-10-22 09:16:17 -04002237 int networkType = phone.getNetworkType();
2238 if (networkType == TelephonyManager.NETWORK_TYPE_UMTS
gomo48f1a642017-11-10 20:35:46 -08002239 || networkType == TelephonyManager.NETWORK_TYPE_HSDPA
2240 || networkType == TelephonyManager.NETWORK_TYPE_HSUPA
2241 || networkType == TelephonyManager.NETWORK_TYPE_HSPA
2242 || networkType == TelephonyManager.NETWORK_TYPE_HSPAP) {
Miguel Torroja1e84da82010-07-27 07:02:24 +02002243 type = AGPS_REF_LOCATION_TYPE_UMTS_CELLID;
Mike Lockwoodedc0f3872010-10-22 09:16:17 -04002244 } else {
Miguel Torroja1e84da82010-07-27 07:02:24 +02002245 type = AGPS_REF_LOCATION_TYPE_GSM_CELLID;
Mike Lockwoodedc0f3872010-10-22 09:16:17 -04002246 }
Miguel Torroja1e84da82010-07-27 07:02:24 +02002247 native_agps_set_ref_location_cellid(type, mcc, mnc,
2248 gsm_cell.getLac(), gsm_cell.getCid());
Mike Lockwoodedc0f3872010-10-22 09:16:17 -04002249 } else {
gomo48f1a642017-11-10 20:35:46 -08002250 Log.e(TAG, "Error getting cell location info.");
Mike Lockwoodedc0f3872010-10-22 09:16:17 -04002251 }
Victoria Leased50d0c32012-10-29 13:16:17 -07002252 } else if (phoneType == TelephonyManager.PHONE_TYPE_CDMA) {
2253 Log.e(TAG, "CDMA not supported.");
Mike Lockwoodedc0f3872010-10-22 09:16:17 -04002254 }
Miguel Torroja1e84da82010-07-27 07:02:24 +02002255 }
Danke Xie22d1f9f2009-08-18 18:28:45 -04002256
Mike Lockwood98e48692010-04-07 16:32:51 -04002257 private void sendMessage(int message, int arg, Object obj) {
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002258 // hold a wake lock until this message is delivered
Jeff Brown028872f2012-08-25 13:07:01 -07002259 // note that this assumes the message will not be removed from the queue before
2260 // it is handled (otherwise the wake lock would be leaked).
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002261 mWakeLock.acquire();
Wyatt Rileycf879db2017-01-12 13:57:38 -08002262 if (Log.isLoggable(TAG, Log.INFO)) {
2263 Log.i(TAG, "WakeLock acquired by sendMessage(" + messageIdAsString(message) + ", " + arg
2264 + ", " + obj + ")");
2265 }
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002266 mHandler.obtainMessage(message, arg, 1, obj).sendToTarget();
Mike Lockwood98e48692010-04-07 16:32:51 -04002267 }
2268
Mike Lockwood62a8fc12010-03-22 14:23:26 -04002269 private final class ProviderHandler extends Handler {
Victoria Lease5cd731a2012-12-19 15:04:21 -08002270 public ProviderHandler(Looper looper) {
2271 super(looper, null, true /*async*/);
Jeff Brown028872f2012-08-25 13:07:01 -07002272 }
2273
Mike Lockwood62a8fc12010-03-22 14:23:26 -04002274 @Override
Mike Lockwood4a7b65e2010-10-25 16:35:55 -04002275 public void handleMessage(Message msg) {
Mike Lockwood98e48692010-04-07 16:32:51 -04002276 int message = msg.what;
2277 switch (message) {
Mike Lockwood62a8fc12010-03-22 14:23:26 -04002278 case ENABLE:
2279 if (msg.arg1 == 1) {
2280 handleEnable();
2281 } else {
2282 handleDisable();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002283 }
Mike Lockwood62a8fc12010-03-22 14:23:26 -04002284 break;
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002285 case SET_REQUEST:
2286 GpsRequest gpsRequest = (GpsRequest) msg.obj;
2287 handleSetRequest(gpsRequest.request, gpsRequest.source);
Mike Lockwood03ca2162010-04-01 08:10:09 -07002288 break;
Mike Lockwood62a8fc12010-03-22 14:23:26 -04002289 case UPDATE_NETWORK_STATE:
destradaae21252a2015-09-08 12:32:59 -07002290 handleUpdateNetworkState((Network) msg.obj);
2291 break;
2292 case REQUEST_SUPL_CONNECTION:
2293 handleRequestSuplConnection((InetAddress) msg.obj);
2294 break;
2295 case RELEASE_SUPL_CONNECTION:
2296 handleReleaseSuplConnection(msg.arg1);
Mike Lockwood62a8fc12010-03-22 14:23:26 -04002297 break;
2298 case INJECT_NTP_TIME:
Yu-Han Yanga1862b52018-02-20 17:05:59 -08002299 mNtpTimeHelper.retrieveAndInjectNtpTime();
Mike Lockwood62a8fc12010-03-22 14:23:26 -04002300 break;
Yu-Han Yange7baef32018-02-09 13:58:17 -08002301 case REQUEST_LOCATION:
2302 handleRequestLocation((boolean) msg.obj);
2303 break;
Mike Lockwood62a8fc12010-03-22 14:23:26 -04002304 case DOWNLOAD_XTRA_DATA:
Wyatt Riley0d6e54e22016-10-05 12:03:03 -07002305 handleDownloadXtraData();
Mike Lockwood62a8fc12010-03-22 14:23:26 -04002306 break;
Kevin Tang40e1baf2012-01-10 14:32:44 -08002307 case DOWNLOAD_XTRA_DATA_FINISHED:
2308 mDownloadXtraDataPending = STATE_IDLE;
2309 break;
Mike Lockwood62a8fc12010-03-22 14:23:26 -04002310 case UPDATE_LOCATION:
destradaae21252a2015-09-08 12:32:59 -07002311 handleUpdateLocation((Location) msg.obj);
Mike Lockwood62a8fc12010-03-22 14:23:26 -04002312 break;
destradaafb23c672015-04-16 14:01:27 -07002313 case SUBSCRIPTION_OR_SIM_CHANGED:
2314 subscriptionOrSimChanged(mContext);
2315 break;
2316 case INITIALIZE_HANDLER:
destradaae21252a2015-09-08 12:32:59 -07002317 handleInitialize();
destradaafb23c672015-04-16 14:01:27 -07002318 break;
Wyatt Riley26465d22018-02-12 13:44:24 -08002319 case REPORT_LOCATION:
2320 handleReportLocation(msg.arg1 == 1, (Location) msg.obj);
2321 break;
2322 case REPORT_SV_STATUS:
2323 handleReportSvStatus((SvStatusInfo) msg.obj);
2324 break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002325 }
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002326 if (msg.arg2 == 1) {
2327 // wakelock was taken for this message, release it
2328 mWakeLock.release();
Wyatt Rileycf879db2017-01-12 13:57:38 -08002329 if (Log.isLoggable(TAG, Log.INFO)) {
2330 Log.i(TAG, "WakeLock released by handleMessage(" + messageIdAsString(message)
2331 + ", " + msg.arg1 + ", " + msg.obj + ")");
2332 }
Mike Lockwood98e48692010-04-07 16:32:51 -04002333 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002334 }
destradaafb23c672015-04-16 14:01:27 -07002335
2336 /**
Lifu Tang30f95a72016-01-07 23:20:38 -08002337 * This method is bound to {@link #GnssLocationProvider(Context, ILocationManager, Looper)}.
destradaafb23c672015-04-16 14:01:27 -07002338 * It is in charge of loading properties and registering for events that will be posted to
2339 * this handler.
2340 */
destradaae21252a2015-09-08 12:32:59 -07002341 private void handleInitialize() {
Yu-Han Yang6d317352018-03-15 11:53:01 -07002342 native_init_once();
2343
Wyatt Riley523a0cf2017-10-31 14:36:52 -07002344 /*
2345 * A cycle of native_init() and native_cleanup() is needed so that callbacks are
2346 * registered after bootup even when location is disabled.
2347 * This will allow Emergency SUPL to work even when location is disabled before device
2348 * restart.
2349 */
2350 boolean isInitialized = native_init();
gomo48f1a642017-11-10 20:35:46 -08002351 if (!isInitialized) {
Wyatt Riley523a0cf2017-10-31 14:36:52 -07002352 Log.w(TAG, "Native initialization failed at bootup");
2353 } else {
2354 native_cleanup();
2355 }
2356
destradaafb23c672015-04-16 14:01:27 -07002357 // load default GPS configuration
2358 // (this configuration might change in the future based on SIM changes)
2359 reloadGpsProperties(mContext, mProperties);
2360
2361 // TODO: When this object "finishes" we should unregister by invoking
gomo48f1a642017-11-10 20:35:46 -08002362 // SubscriptionManager.getInstance(mContext).unregister
2363 // (mOnSubscriptionsChangedListener);
destradaafb23c672015-04-16 14:01:27 -07002364 // This is not strictly necessary because it will be unregistered if the
2365 // notification fails but it is good form.
2366
2367 // Register for SubscriptionInfo list changes which is guaranteed
2368 // to invoke onSubscriptionsChanged the first time.
2369 SubscriptionManager.from(mContext)
2370 .addOnSubscriptionsChangedListener(mOnSubscriptionsChangedListener);
2371
2372 // listen for events
destradaaef752b62015-04-17 13:10:47 -07002373 IntentFilter intentFilter;
2374 if (native_is_agps_ril_supported()) {
2375 intentFilter = new IntentFilter();
2376 intentFilter.addAction(Intents.DATA_SMS_RECEIVED_ACTION);
2377 intentFilter.addDataScheme("sms");
2378 intentFilter.addDataAuthority("localhost", "7275");
2379 mContext.registerReceiver(mBroadcastReceiver, intentFilter, null, this);
destradaafb23c672015-04-16 14:01:27 -07002380
destradaaef752b62015-04-17 13:10:47 -07002381 intentFilter = new IntentFilter();
2382 intentFilter.addAction(Intents.WAP_PUSH_RECEIVED_ACTION);
2383 try {
2384 intentFilter.addDataType("application/vnd.omaloc-supl-init");
2385 } catch (IntentFilter.MalformedMimeTypeException e) {
2386 Log.w(TAG, "Malformed SUPL init mime type");
2387 }
2388 mContext.registerReceiver(mBroadcastReceiver, intentFilter, null, this);
2389 } else if (DEBUG) {
2390 Log.d(TAG, "Skipped registration for SMS/WAP-PUSH messages because AGPS Ril in GPS"
2391 + " HAL is not supported");
destradaafb23c672015-04-16 14:01:27 -07002392 }
destradaafb23c672015-04-16 14:01:27 -07002393
2394 intentFilter = new IntentFilter();
2395 intentFilter.addAction(ALARM_WAKEUP);
2396 intentFilter.addAction(ALARM_TIMEOUT);
destradaafb23c672015-04-16 14:01:27 -07002397 intentFilter.addAction(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED);
Adam Lesinski87c17df2015-05-27 13:24:13 -07002398 intentFilter.addAction(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED);
destradaafb23c672015-04-16 14:01:27 -07002399 intentFilter.addAction(Intent.ACTION_SCREEN_OFF);
2400 intentFilter.addAction(Intent.ACTION_SCREEN_ON);
2401 intentFilter.addAction(SIM_STATE_CHANGED);
2402 mContext.registerReceiver(mBroadcastReceiver, intentFilter, null, this);
2403
destradaae21252a2015-09-08 12:32:59 -07002404 // register for connectivity change events, this is equivalent to the deprecated way of
2405 // registering for CONNECTIVITY_ACTION broadcasts
2406 NetworkRequest.Builder networkRequestBuilder = new NetworkRequest.Builder();
Jeff Sharkeyc159d522018-03-28 10:54:07 -06002407 networkRequestBuilder.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
2408 networkRequestBuilder.addCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED);
2409 networkRequestBuilder.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN);
destradaae21252a2015-09-08 12:32:59 -07002410 NetworkRequest networkRequest = networkRequestBuilder.build();
2411 mConnMgr.registerNetworkCallback(networkRequest, mNetworkConnectivityCallback);
2412
destradaafb23c672015-04-16 14:01:27 -07002413 // listen for PASSIVE_PROVIDER updates
2414 LocationManager locManager =
2415 (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE);
2416 long minTime = 0;
2417 float minDistance = 0;
2418 boolean oneShot = false;
2419 LocationRequest request = LocationRequest.createFromDeprecatedProvider(
2420 LocationManager.PASSIVE_PROVIDER,
2421 minTime,
2422 minDistance,
2423 oneShot);
2424 // Don't keep track of this request since it's done on behalf of other clients
2425 // (which are kept track of separately).
2426 request.setHideFromAppOps(true);
2427 locManager.requestLocationUpdates(
2428 request,
2429 new NetworkLocationListener(),
2430 getLooper());
2431 }
2432 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002433
Yu-Han Yange7baef32018-02-09 13:58:17 -08002434 private abstract class LocationChangeListener implements LocationListener {
Yu-Han Yang07561382018-02-21 13:08:37 -08002435 int numLocationUpdateRequest;
2436
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002437 @Override
gomo48f1a642017-11-10 20:35:46 -08002438 public void onStatusChanged(String provider, int status, Bundle extras) {
2439 }
2440
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002441 @Override
gomo48f1a642017-11-10 20:35:46 -08002442 public void onProviderEnabled(String provider) {
2443 }
2444
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002445 @Override
gomo48f1a642017-11-10 20:35:46 -08002446 public void onProviderDisabled(String provider) {
2447 }
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002448 }
2449
Yu-Han Yange7baef32018-02-09 13:58:17 -08002450 private final class NetworkLocationListener extends LocationChangeListener {
2451 @Override
2452 public void onLocationChanged(Location location) {
2453 // this callback happens on mHandler looper
2454 if (LocationManager.NETWORK_PROVIDER.equals(location.getProvider())) {
2455 handleUpdateLocation(location);
2456 }
2457 }
2458 }
2459
2460 private final class FusedLocationListener extends LocationChangeListener {
2461 @Override
2462 public void onLocationChanged(Location location) {
2463 if (LocationManager.FUSED_PROVIDER.equals(location.getProvider())) {
Yu-Han Yange7baef32018-02-09 13:58:17 -08002464 injectBestLocation(location);
2465 }
2466 }
2467 }
2468
Kevin Tanga5fe6b22011-06-05 14:25:16 -07002469 private String getSelectedApn() {
2470 Uri uri = Uri.parse("content://telephony/carriers/preferapn");
destradaa96a14702014-06-05 11:36:30 -07002471 Cursor cursor = null;
2472 try {
2473 cursor = mContext.getContentResolver().query(
2474 uri,
gomo48f1a642017-11-10 20:35:46 -08002475 new String[]{"apn"},
destradaa96a14702014-06-05 11:36:30 -07002476 null /* selection */,
2477 null /* selectionArgs */,
2478 Carriers.DEFAULT_SORT_ORDER);
2479 if (cursor != null && cursor.moveToFirst()) {
2480 return cursor.getString(0);
2481 } else {
2482 Log.e(TAG, "No APN found to select.");
2483 }
2484 } catch (Exception e) {
destradaaea8a8a62014-06-23 18:19:03 -07002485 Log.e(TAG, "Error encountered on selecting the APN.", e);
destradaa96a14702014-06-05 11:36:30 -07002486 } finally {
2487 if (cursor != null) {
Kevin Tanga5fe6b22011-06-05 14:25:16 -07002488 cursor.close();
2489 }
2490 }
destradaa96a14702014-06-05 11:36:30 -07002491
2492 return null;
2493 }
2494
2495 private int getApnIpType(String apn) {
destradaae21252a2015-09-08 12:32:59 -07002496 ensureInHandlerThread();
destradaa96a14702014-06-05 11:36:30 -07002497 if (apn == null) {
2498 return APN_INVALID;
2499 }
2500
destradaa96a14702014-06-05 11:36:30 -07002501 String selection = String.format("current = 1 and apn = '%s' and carrier_enabled = 1", apn);
2502 Cursor cursor = null;
2503 try {
2504 cursor = mContext.getContentResolver().query(
2505 Carriers.CONTENT_URI,
gomo48f1a642017-11-10 20:35:46 -08002506 new String[]{Carriers.PROTOCOL},
destradaa96a14702014-06-05 11:36:30 -07002507 selection,
2508 null,
2509 Carriers.DEFAULT_SORT_ORDER);
2510
2511 if (null != cursor && cursor.moveToFirst()) {
2512 return translateToApnIpType(cursor.getString(0), apn);
2513 } else {
2514 Log.e(TAG, "No entry found in query for APN: " + apn);
2515 }
2516 } catch (Exception e) {
2517 Log.e(TAG, "Error encountered on APN query for: " + apn, e);
2518 } finally {
2519 if (cursor != null) {
2520 cursor.close();
2521 }
2522 }
2523
2524 return APN_INVALID;
2525 }
2526
2527 private int translateToApnIpType(String ipProtocol, String apn) {
2528 if ("IP".equals(ipProtocol)) {
2529 return APN_IPV4;
2530 }
2531 if ("IPV6".equals(ipProtocol)) {
2532 return APN_IPV6;
2533 }
2534 if ("IPV4V6".equals(ipProtocol)) {
2535 return APN_IPV4V6;
2536 }
2537
2538 // we hit the default case so the ipProtocol is not recognized
2539 String message = String.format("Unknown IP Protocol: %s, for APN: %s", ipProtocol, apn);
2540 Log.e(TAG, message);
2541 return APN_INVALID;
2542 }
2543
2544 private void setRouting() {
2545 if (mAGpsDataConnectionIpAddr == null) {
2546 return;
2547 }
2548
destradaae21252a2015-09-08 12:32:59 -07002549 // TODO: replace the use of this deprecated API
destradaa96a14702014-06-05 11:36:30 -07002550 boolean result = mConnMgr.requestRouteToHostAddress(
2551 ConnectivityManager.TYPE_MOBILE_SUPL,
2552 mAGpsDataConnectionIpAddr);
2553
2554 if (!result) {
2555 Log.e(TAG, "Error requesting route to host: " + mAGpsDataConnectionIpAddr);
2556 } else if (DEBUG) {
2557 Log.d(TAG, "Successfully requested route to host: " + mAGpsDataConnectionIpAddr);
2558 }
Kevin Tanga5fe6b22011-06-05 14:25:16 -07002559 }
2560
destradaae21252a2015-09-08 12:32:59 -07002561 /**
2562 * @return {@code true} if there is a data network available for outgoing connections,
gomo48f1a642017-11-10 20:35:46 -08002563 * {@code false} otherwise.
destradaae21252a2015-09-08 12:32:59 -07002564 */
2565 private boolean isDataNetworkConnected() {
2566 NetworkInfo activeNetworkInfo = mConnMgr.getActiveNetworkInfo();
2567 return activeNetworkInfo != null && activeNetworkInfo.isConnected();
2568 }
2569
2570 /**
2571 * Ensures the calling function is running in the thread associated with {@link #mHandler}.
2572 */
2573 private void ensureInHandlerThread() {
2574 if (mHandler != null && Looper.myLooper() == mHandler.getLooper()) {
2575 return;
2576 }
2577 throw new RuntimeException("This method must run on the Handler thread.");
2578 }
2579
2580 /**
2581 * @return A string representing the current state stored in {@link #mAGpsDataConnectionState}.
2582 */
2583 private String agpsDataConnStateAsString() {
gomo48f1a642017-11-10 20:35:46 -08002584 switch (mAGpsDataConnectionState) {
destradaae21252a2015-09-08 12:32:59 -07002585 case AGPS_DATA_CONNECTION_CLOSED:
2586 return "CLOSED";
2587 case AGPS_DATA_CONNECTION_OPEN:
2588 return "OPEN";
2589 case AGPS_DATA_CONNECTION_OPENING:
2590 return "OPENING";
2591 default:
2592 return "<Unknown>";
2593 }
2594 }
2595
2596 /**
2597 * @return A string representing the given GPS_AGPS_DATA status.
2598 */
2599 private String agpsDataConnStatusAsString(int agpsDataConnStatus) {
2600 switch (agpsDataConnStatus) {
2601 case GPS_AGPS_DATA_CONNECTED:
2602 return "CONNECTED";
2603 case GPS_AGPS_DATA_CONN_DONE:
2604 return "DONE";
2605 case GPS_AGPS_DATA_CONN_FAILED:
2606 return "FAILED";
2607 case GPS_RELEASE_AGPS_DATA_CONN:
2608 return "RELEASE";
2609 case GPS_REQUEST_AGPS_DATA_CONN:
2610 return "REQUEST";
2611 default:
2612 return "<Unknown>";
2613 }
2614 }
2615
Wyatt Rileycf879db2017-01-12 13:57:38 -08002616 /**
2617 * @return A string representing the given message ID.
2618 */
2619 private String messageIdAsString(int message) {
2620 switch (message) {
2621 case ENABLE:
2622 return "ENABLE";
2623 case SET_REQUEST:
2624 return "SET_REQUEST";
2625 case UPDATE_NETWORK_STATE:
2626 return "UPDATE_NETWORK_STATE";
2627 case REQUEST_SUPL_CONNECTION:
2628 return "REQUEST_SUPL_CONNECTION";
2629 case RELEASE_SUPL_CONNECTION:
2630 return "RELEASE_SUPL_CONNECTION";
2631 case INJECT_NTP_TIME:
2632 return "INJECT_NTP_TIME";
Yu-Han Yange7baef32018-02-09 13:58:17 -08002633 case REQUEST_LOCATION:
2634 return "REQUEST_LOCATION";
Wyatt Rileycf879db2017-01-12 13:57:38 -08002635 case DOWNLOAD_XTRA_DATA:
2636 return "DOWNLOAD_XTRA_DATA";
Wyatt Rileycf879db2017-01-12 13:57:38 -08002637 case DOWNLOAD_XTRA_DATA_FINISHED:
2638 return "DOWNLOAD_XTRA_DATA_FINISHED";
2639 case UPDATE_LOCATION:
2640 return "UPDATE_LOCATION";
2641 case SUBSCRIPTION_OR_SIM_CHANGED:
2642 return "SUBSCRIPTION_OR_SIM_CHANGED";
2643 case INITIALIZE_HANDLER:
2644 return "INITIALIZE_HANDLER";
Wyatt Riley26465d22018-02-12 13:44:24 -08002645 case REPORT_LOCATION:
2646 return "REPORT_LOCATION";
2647 case REPORT_SV_STATUS:
2648 return "REPORT_SV_STATUS";
Wyatt Rileycf879db2017-01-12 13:57:38 -08002649 default:
2650 return "<Unknown>";
2651 }
2652 }
2653
Siddharth Raybb608c82017-03-16 11:33:34 -07002654
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002655 @Override
2656 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2657 StringBuilder s = new StringBuilder();
Wyatt Riley77ca4f82017-06-30 18:13:44 -07002658 s.append(" mStarted=").append(mStarted).append('\n');
destradaa25e8caf2015-08-24 14:14:44 -07002659 s.append(" mFixInterval=").append(mFixInterval).append('\n');
gomo48f1a642017-11-10 20:35:46 -08002660 s.append(" mLowPowerMode=").append(mLowPowerMode).append('\n');
Wyatt Riley74479bd2018-01-17 08:48:27 -08002661 s.append(" mGnssMeasurementsProvider.isRegistered()=")
2662 .append(mGnssMeasurementsProvider.isRegistered()).append('\n');
2663 s.append(" mGnssNavigationMessageProvider.isRegistered()=")
2664 .append(mGnssNavigationMessageProvider.isRegistered()).append('\n');
destradaa25e8caf2015-08-24 14:14:44 -07002665 s.append(" mDisableGps (battery saver mode)=").append(mDisableGps).append('\n');
2666 s.append(" mEngineCapabilities=0x").append(Integer.toHexString(mEngineCapabilities));
2667 s.append(" ( ");
2668 if (hasCapability(GPS_CAPABILITY_SCHEDULING)) s.append("SCHEDULING ");
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002669 if (hasCapability(GPS_CAPABILITY_MSB)) s.append("MSB ");
2670 if (hasCapability(GPS_CAPABILITY_MSA)) s.append("MSA ");
2671 if (hasCapability(GPS_CAPABILITY_SINGLE_SHOT)) s.append("SINGLE_SHOT ");
2672 if (hasCapability(GPS_CAPABILITY_ON_DEMAND_TIME)) s.append("ON_DEMAND_TIME ");
destradaa25e8caf2015-08-24 14:14:44 -07002673 if (hasCapability(GPS_CAPABILITY_GEOFENCING)) s.append("GEOFENCING ");
2674 if (hasCapability(GPS_CAPABILITY_MEASUREMENTS)) s.append("MEASUREMENTS ");
2675 if (hasCapability(GPS_CAPABILITY_NAV_MESSAGES)) s.append("NAV_MESSAGES ");
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002676 s.append(")\n");
Siddharth Raybb608c82017-03-16 11:33:34 -07002677 s.append(mGnssMetrics.dumpGnssMetricsAsText());
2678 s.append(" native internal state: ").append(native_get_internal_state());
Wyatt Rileycf879db2017-01-12 13:57:38 -08002679 s.append("\n");
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002680 pw.append(s);
2681 }
2682
Mike Lockwoodb16e7802009-08-06 09:26:02 -04002683 // preallocated to avoid memory allocation in reportNmea()
2684 private byte[] mNmeaBuffer = new byte[120];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002685
gomo48f1a642017-11-10 20:35:46 -08002686 static {
2687 class_init_native();
2688 }
2689
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002690 private static native void class_init_native();
gomo48f1a642017-11-10 20:35:46 -08002691
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002692 private static native boolean native_is_supported();
gomo48f1a642017-11-10 20:35:46 -08002693
destradaaef752b62015-04-17 13:10:47 -07002694 private static native boolean native_is_agps_ril_supported();
gomo48f1a642017-11-10 20:35:46 -08002695
destradaaef752b62015-04-17 13:10:47 -07002696 private static native boolean native_is_gnss_configuration_supported();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002697
Yu-Han Yang6d317352018-03-15 11:53:01 -07002698 private static native void native_init_once();
2699
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002700 private native boolean native_init();
gomo48f1a642017-11-10 20:35:46 -08002701
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002702 private native void native_cleanup();
gomo48f1a642017-11-10 20:35:46 -08002703
Mike Lockwood04598b62010-04-14 17:17:24 -04002704 private native boolean native_set_position_mode(int mode, int recurrence, int min_interval,
gomo48f1a642017-11-10 20:35:46 -08002705 int preferred_accuracy, int preferred_time, boolean lowPowerMode);
2706
Mike Lockwood04598b62010-04-14 17:17:24 -04002707 private native boolean native_start();
gomo48f1a642017-11-10 20:35:46 -08002708
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002709 private native boolean native_stop();
gomo48f1a642017-11-10 20:35:46 -08002710
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002711 private native void native_delete_aiding_data(int flags);
gomo48f1a642017-11-10 20:35:46 -08002712
Mike Lockwoodf602d362010-06-20 14:28:16 -07002713 private native int native_read_nmea(byte[] buffer, int bufferSize);
gomo48f1a642017-11-10 20:35:46 -08002714
Yu-Han Yange7baef32018-02-09 13:58:17 -08002715 private native void native_inject_best_location(
2716 int gnssLocationFlags,
2717 double latitudeDegrees,
2718 double longitudeDegrees,
2719 double altitudeMeters,
2720 float speedMetersPerSec,
2721 float bearingDegrees,
2722 float horizontalAccuracyMeters,
2723 float verticalAccuracyMeters,
2724 float speedAccuracyMetersPerSecond,
2725 float bearingAccuracyDegrees,
2726 long timestamp);
2727
Mike Lockwoodd26ce0d2009-06-11 12:25:46 -04002728 private native void native_inject_location(double latitude, double longitude, float accuracy);
2729
Fred Fettinger3c8fbdf2010-01-04 15:38:13 -06002730 // XTRA Support
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002731 private native void native_inject_time(long time, long timeReference, int uncertainty);
gomo48f1a642017-11-10 20:35:46 -08002732
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002733 private native boolean native_supports_xtra();
gomo48f1a642017-11-10 20:35:46 -08002734
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002735 private native void native_inject_xtra_data(byte[] data, int length);
The Android Open Source Project10592532009-03-18 17:39:46 -07002736
Fred Fettinger3c8fbdf2010-01-04 15:38:13 -06002737 // DEBUG Support
2738 private native String native_get_internal_state();
2739
2740 // AGPS Support
destradaa96a14702014-06-05 11:36:30 -07002741 private native void native_agps_data_conn_open(String apn, int apnIpType);
gomo48f1a642017-11-10 20:35:46 -08002742
Mike Lockwoode3635c92009-05-11 08:38:02 -04002743 private native void native_agps_data_conn_closed();
gomo48f1a642017-11-10 20:35:46 -08002744
Mike Lockwoode3635c92009-05-11 08:38:02 -04002745 private native void native_agps_data_conn_failed();
gomo48f1a642017-11-10 20:35:46 -08002746
2747 private native void native_agps_ni_message(byte[] msg, int length);
2748
Mike Lockwooda9e54612009-06-19 14:54:42 -04002749 private native void native_set_agps_server(int type, String hostname, int port);
Danke Xie22d1f9f2009-08-18 18:28:45 -04002750
2751 // Network-initiated (NI) Support
2752 private native void native_send_ni_response(int notificationId, int userResponse);
Miguel Torroja1e84da82010-07-27 07:02:24 +02002753
2754 // AGPS ril suport
2755 private native void native_agps_set_ref_location_cellid(int type, int mcc, int mnc,
2756 int lac, int cid);
gomo48f1a642017-11-10 20:35:46 -08002757
Miguel Torroja1e84da82010-07-27 07:02:24 +02002758 private native void native_agps_set_id(int type, String setid);
Mike Lockwood50130bb2010-10-11 06:22:50 -04002759
2760 private native void native_update_network_state(boolean connected, int type,
Kevin Tanga5fe6b22011-06-05 14:25:16 -07002761 boolean roaming, boolean available, String extraInfo, String defaultAPN);
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07002762
destradaa4b3e3932014-07-21 18:01:47 -07002763 // Gps Navigation message support.
2764 private static native boolean native_is_navigation_message_supported();
gomo48f1a642017-11-10 20:35:46 -08002765
destradaa4b3e3932014-07-21 18:01:47 -07002766 private native boolean native_start_navigation_message_collection();
gomo48f1a642017-11-10 20:35:46 -08002767
destradaa4b3e3932014-07-21 18:01:47 -07002768 private native boolean native_stop_navigation_message_collection();
Tsuwei Chen52617bb2014-08-25 11:49:11 -07002769
2770 // GNSS Configuration
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002771 private static native boolean native_set_supl_version(int version);
gomo48f1a642017-11-10 20:35:46 -08002772
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002773 private static native boolean native_set_supl_mode(int mode);
gomo48f1a642017-11-10 20:35:46 -08002774
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002775 private static native boolean native_set_supl_es(int es);
gomo48f1a642017-11-10 20:35:46 -08002776
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002777 private static native boolean native_set_lpp_profile(int lppProfile);
gomo48f1a642017-11-10 20:35:46 -08002778
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002779 private static native boolean native_set_gnss_pos_protocol_select(int gnssPosProtocolSelect);
gomo48f1a642017-11-10 20:35:46 -08002780
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002781 private static native boolean native_set_gps_lock(int gpsLock);
gomo48f1a642017-11-10 20:35:46 -08002782
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002783 private static native boolean native_set_emergency_supl_pdn(int emergencySuplPdn);
2784
Yu-Han Yang66c7ea92018-03-11 17:17:15 -07002785 private static native boolean native_set_satellite_blacklist(int[] constellations, int[] svIds);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002786}
Yu-Han Yanga1862b52018-02-20 17:05:59 -08002787