blob: 5ba738093c6dae04cce6decacb291f80dfb22386 [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
Yu-Han Yange7baef32018-02-09 13:58:17 -080019import android.annotation.Nullable;
Mike Lockwood29c84342009-05-06 14:01:15 -040020import android.app.AlarmManager;
Dianne Hackborna06de0f2012-12-11 16:34:47 -080021import android.app.AppOpsManager;
Mike Lockwood29c84342009-05-06 14:01:15 -040022import android.app.PendingIntent;
The Android Open Source Project10592532009-03-18 17:39:46 -070023import android.content.BroadcastReceiver;
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 Yanga1862b52018-02-20 17:05:59 -080086import com.android.server.location.NtpTimeHelper.InjectNtpTimeCallback;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080087import java.io.File;
Nick Pelly6fa9ad42012-07-16 12:18:23 -070088import java.io.FileDescriptor;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080089import java.io.FileInputStream;
90import java.io.IOException;
Nick Pelly6fa9ad42012-07-16 12:18:23 -070091import java.io.PrintWriter;
destradaaea8a8a62014-06-23 18:19:03 -070092import java.net.InetAddress;
93import java.net.UnknownHostException;
Wyatt Rileycf879db2017-01-12 13:57:38 -080094import java.util.ArrayList;
Andreas Gampee6748ce2015-12-11 18:00:38 -080095import java.util.Arrays;
Yu-Han Yange7baef32018-02-09 13:58:17 -080096import java.util.HashMap;
Wyatt Rileycf879db2017-01-12 13:57:38 -080097import java.util.List;
Yu-Han Yange7baef32018-02-09 13:58:17 -080098import java.util.Map;
Danke Xie22d1f9f2009-08-18 18:28:45 -040099import java.util.Map.Entry;
Jake Hambyb49a73d2011-03-15 20:09:46 -0700100import java.util.Properties;
Yu-Han Yange7baef32018-02-09 13:58:17 -0800101
102import libcore.io.IoUtils;
Colin Cross7c030ed2014-01-28 09:33:53 -0800103
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800104/**
gomo4402af62017-01-11 13:20:13 -0800105 * A GNSS implementation of LocationProvider used by LocationManager.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800106 *
107 * {@hide}
108 */
Yu-Han Yanga1862b52018-02-20 17:05:59 -0800109public class GnssLocationProvider implements LocationProviderInterface, InjectNtpTimeCallback {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800110
Lifu Tang30f95a72016-01-07 23:20:38 -0800111 private static final String TAG = "GnssLocationProvider";
Mike Lockwood29c84342009-05-06 14:01:15 -0400112
Brian Muramatsu1715cb32012-08-08 17:32:21 -0700113 private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
114 private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400115
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700116 private static final ProviderProperties PROPERTIES = new ProviderProperties(
117 true, true, false, false, true, true, true,
118 Criteria.POWER_HIGH, Criteria.ACCURACY_FINE);
119
gomo4402af62017-01-11 13:20:13 -0800120 // these need to match GnssPositionMode enum in IGnss.hal
The Android Open Source Project10592532009-03-18 17:39:46 -0700121 private static final int GPS_POSITION_MODE_STANDALONE = 0;
122 private static final int GPS_POSITION_MODE_MS_BASED = 1;
123 private static final int GPS_POSITION_MODE_MS_ASSISTED = 2;
124
gomo4402af62017-01-11 13:20:13 -0800125 // these need to match GnssPositionRecurrence enum in IGnss.hal
Mike Lockwood04598b62010-04-14 17:17:24 -0400126 private static final int GPS_POSITION_RECURRENCE_PERIODIC = 0;
127 private static final int GPS_POSITION_RECURRENCE_SINGLE = 1;
128
gomo4402af62017-01-11 13:20:13 -0800129 // these need to match GnssStatusValue enum in IGnssCallback.hal
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800130 private static final int GPS_STATUS_NONE = 0;
131 private static final int GPS_STATUS_SESSION_BEGIN = 1;
132 private static final int GPS_STATUS_SESSION_END = 2;
133 private static final int GPS_STATUS_ENGINE_ON = 3;
134 private static final int GPS_STATUS_ENGINE_OFF = 4;
135
gomo4402af62017-01-11 13:20:13 -0800136 // these need to match AGnssStatusValue enum in IAGnssCallback.hal
Mike Lockwoode3635c92009-05-11 08:38:02 -0400137 /** AGPS status event values. */
138 private static final int GPS_REQUEST_AGPS_DATA_CONN = 1;
139 private static final int GPS_RELEASE_AGPS_DATA_CONN = 2;
140 private static final int GPS_AGPS_DATA_CONNECTED = 3;
141 private static final int GPS_AGPS_DATA_CONN_DONE = 4;
142 private static final int GPS_AGPS_DATA_CONN_FAILED = 5;
Mike Lockwood58bda982009-04-14 16:25:07 -0400143
gomo4402af62017-01-11 13:20:13 -0800144 // these need to match GnssLocationFlags enum in types.hal
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800145 private static final int LOCATION_INVALID = 0;
146 private static final int LOCATION_HAS_LAT_LONG = 1;
147 private static final int LOCATION_HAS_ALTITUDE = 2;
148 private static final int LOCATION_HAS_SPEED = 4;
149 private static final int LOCATION_HAS_BEARING = 8;
gomo4402af62017-01-11 13:20:13 -0800150 private static final int LOCATION_HAS_HORIZONTAL_ACCURACY = 16;
151 private static final int LOCATION_HAS_VERTICAL_ACCURACY = 32;
152 private static final int LOCATION_HAS_SPEED_ACCURACY = 64;
153 private static final int LOCATION_HAS_BEARING_ACCURACY = 128;
Mike Lockwoode3635c92009-05-11 08:38:02 -0400154
gomo4402af62017-01-11 13:20:13 -0800155
156 // IMPORTANT - the GPS_DELETE_* symbols here must match GnssAidingData enum in IGnss.hal
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800157 private static final int GPS_DELETE_EPHEMERIS = 0x0001;
158 private static final int GPS_DELETE_ALMANAC = 0x0002;
159 private static final int GPS_DELETE_POSITION = 0x0004;
160 private static final int GPS_DELETE_TIME = 0x0008;
161 private static final int GPS_DELETE_IONO = 0x0010;
162 private static final int GPS_DELETE_UTC = 0x0020;
163 private static final int GPS_DELETE_HEALTH = 0x0040;
164 private static final int GPS_DELETE_SVDIR = 0x0080;
165 private static final int GPS_DELETE_SVSTEER = 0x0100;
166 private static final int GPS_DELETE_SADATA = 0x0200;
167 private static final int GPS_DELETE_RTI = 0x0400;
168 private static final int GPS_DELETE_CELLDB_INFO = 0x8000;
169 private static final int GPS_DELETE_ALL = 0xFFFF;
170
gomo4402af62017-01-11 13:20:13 -0800171 // The GPS_CAPABILITY_* flags must match Capabilities enum in IGnssCallback.hal
Mike Lockwood04598b62010-04-14 17:17:24 -0400172 private static final int GPS_CAPABILITY_SCHEDULING = 0x0000001;
173 private static final int GPS_CAPABILITY_MSB = 0x0000002;
174 private static final int GPS_CAPABILITY_MSA = 0x0000004;
175 private static final int GPS_CAPABILITY_SINGLE_SHOT = 0x0000008;
Mike Lockwood9b9fb5c2011-06-29 15:09:40 -0400176 private static final int GPS_CAPABILITY_ON_DEMAND_TIME = 0x0000010;
destradaa6568d702014-10-27 12:47:41 -0700177 private static final int GPS_CAPABILITY_GEOFENCING = 0x0000020;
178 private static final int GPS_CAPABILITY_MEASUREMENTS = 0x0000040;
179 private static final int GPS_CAPABILITY_NAV_MESSAGES = 0x0000080;
Mike Lockwood04598b62010-04-14 17:17:24 -0400180
Tsuwei Chen462bcd82014-09-17 12:28:49 -0700181 // The AGPS SUPL mode
182 private static final int AGPS_SUPL_MODE_MSA = 0x02;
183 private static final int AGPS_SUPL_MODE_MSB = 0x01;
184
gomo4402af62017-01-11 13:20:13 -0800185 // these need to match AGnssType enum in IAGnssCallback.hal
Mike Lockwoode3635c92009-05-11 08:38:02 -0400186 private static final int AGPS_TYPE_SUPL = 1;
187 private static final int AGPS_TYPE_C2K = 2;
188
gomo4402af62017-01-11 13:20:13 -0800189 // these must match the ApnIpType enum in IAGnss.hal
destradaa96a14702014-06-05 11:36:30 -0700190 private static final int APN_INVALID = 0;
191 private static final int APN_IPV4 = 1;
192 private static final int APN_IPV6 = 2;
193 private static final int APN_IPV4V6 = 3;
194
Mike Lockwoode3635c92009-05-11 08:38:02 -0400195 // for mAGpsDataConnectionState
196 private static final int AGPS_DATA_CONNECTION_CLOSED = 0;
197 private static final int AGPS_DATA_CONNECTION_OPENING = 1;
198 private static final int AGPS_DATA_CONNECTION_OPEN = 2;
Mike Lockwood58bda982009-04-14 16:25:07 -0400199
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400200 // Handler messages
201 private static final int CHECK_LOCATION = 1;
202 private static final int ENABLE = 2;
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700203 private static final int SET_REQUEST = 3;
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400204 private static final int UPDATE_NETWORK_STATE = 4;
205 private static final int INJECT_NTP_TIME = 5;
206 private static final int DOWNLOAD_XTRA_DATA = 6;
Wyatt Rileyc7067412018-02-07 15:50:35 -0800207 private static final int UPDATE_LOCATION = 7; // Handle external location from network listener
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400208 private static final int ADD_LISTENER = 8;
209 private static final int REMOVE_LISTENER = 9;
Kevin Tang40e1baf2012-01-10 14:32:44 -0800210 private static final int DOWNLOAD_XTRA_DATA_FINISHED = 11;
destradaafb23c672015-04-16 14:01:27 -0700211 private static final int SUBSCRIPTION_OR_SIM_CHANGED = 12;
212 private static final int INITIALIZE_HANDLER = 13;
destradaae21252a2015-09-08 12:32:59 -0700213 private static final int REQUEST_SUPL_CONNECTION = 14;
214 private static final int RELEASE_SUPL_CONNECTION = 15;
Yu-Han Yange7baef32018-02-09 13:58:17 -0800215 private static final int REQUEST_LOCATION = 16;
Wyatt Riley26465d22018-02-12 13:44:24 -0800216 private static final int REPORT_LOCATION = 17; // HAL reports location
217 private static final int REPORT_SV_STATUS = 18; // HAL reports SV status
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400218
Miguel Torroja1e84da82010-07-27 07:02:24 +0200219 // Request setid
220 private static final int AGPS_RIL_REQUEST_SETID_IMSI = 1;
221 private static final int AGPS_RIL_REQUEST_SETID_MSISDN = 2;
222
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700223 //TODO(b/33112647): Create gps_debug.conf with commented career parameters.
224 private static final String DEBUG_PROPERTIES_FILE = "/etc/gps_debug.conf";
Miguel Torroja1e84da82010-07-27 07:02:24 +0200225
226 // ref. location info
227 private static final int AGPS_REF_LOCATION_TYPE_GSM_CELLID = 1;
228 private static final int AGPS_REF_LOCATION_TYPE_UMTS_CELLID = 2;
Miguel Torroja1e84da82010-07-27 07:02:24 +0200229
230 // set id info
231 private static final int AGPS_SETID_TYPE_NONE = 0;
232 private static final int AGPS_SETID_TYPE_IMSI = 1;
233 private static final int AGPS_SETID_TYPE_MSISDN = 2;
234
gomo48f1a642017-11-10 20:35:46 -0800235 private static final int GPS_GEOFENCE_UNAVAILABLE = 1 << 0L;
236 private static final int GPS_GEOFENCE_AVAILABLE = 1 << 1L;
destradaa0682809a2013-08-12 18:50:30 -0700237
gomo4402af62017-01-11 13:20:13 -0800238 // GPS Geofence errors. Should match GeofenceStatus enum in IGnssGeofenceCallback.hal.
destradaa0682809a2013-08-12 18:50:30 -0700239 private static final int GPS_GEOFENCE_OPERATION_SUCCESS = 0;
240 private static final int GPS_GEOFENCE_ERROR_TOO_MANY_GEOFENCES = 100;
gomo48f1a642017-11-10 20:35:46 -0800241 private static final int GPS_GEOFENCE_ERROR_ID_EXISTS = -101;
destradaa0682809a2013-08-12 18:50:30 -0700242 private static final int GPS_GEOFENCE_ERROR_ID_UNKNOWN = -102;
243 private static final int GPS_GEOFENCE_ERROR_INVALID_TRANSITION = -103;
244 private static final int GPS_GEOFENCE_ERROR_GENERIC = -149;
245
Tsuwei Chen678c13c2014-09-22 17:48:41 -0700246 // TCP/IP constants.
247 // Valid TCP/UDP port range is (0, 65535].
248 private static final int TCP_MIN_PORT = 0;
249 private static final int TCP_MAX_PORT = 0xffff;
250
Yu-Han Yange7baef32018-02-09 13:58:17 -0800251 // 10 seconds.
252 private static final long LOCATION_TIME_FRESHNESS_THESHOLD_MILLIS = 10 * 1000;
253 // 1 second, or 1 Hz frequency.
254 private static final long LOCATION_UPDATE_MIN_TIME_INTERVAL_MILLIS = 1000;
255 // 30 seconds.
256 private static final long LOCATION_UPDATE_DURATION_MILLIS = 30 * 1000;
257
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700258 /** simpler wrapper for ProviderRequest + Worksource */
259 private static class GpsRequest {
260 public ProviderRequest request;
261 public WorkSource source;
gomo48f1a642017-11-10 20:35:46 -0800262
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700263 public GpsRequest(ProviderRequest request, WorkSource source) {
264 this.request = request;
265 this.source = source;
266 }
267 }
268
Wyatt Riley26465d22018-02-12 13:44:24 -0800269 // Threadsafe class to hold stats reported in the Extras Bundle
Wyatt Rileyc7067412018-02-07 15:50:35 -0800270 private static class LocationExtras {
271 private int mSvCount;
272 private int mMeanCn0;
273 private int mMaxCn0;
274 private final Bundle mBundle;
275
276 public LocationExtras() {
277 mBundle = new Bundle();
278 }
279
280 public void set(int svCount, int meanCn0, int maxCn0) {
Wyatt Riley26465d22018-02-12 13:44:24 -0800281 synchronized(this) {
282 mSvCount = svCount;
283 mMeanCn0 = meanCn0;
284 mMaxCn0 = maxCn0;
285 }
Wyatt Rileyc7067412018-02-07 15:50:35 -0800286 setBundle(mBundle);
287 }
288
289 public void reset() {
290 set(0,0,0);
291 }
292
293 // Also used by outside methods to add to other bundles
294 public void setBundle(Bundle extras) {
295 if (extras != null) {
Wyatt Riley26465d22018-02-12 13:44:24 -0800296 synchronized (this) {
297 extras.putInt("satellites", mSvCount);
298 extras.putInt("meanCn0", mMeanCn0);
299 extras.putInt("maxCn0", mMaxCn0);
300 }
Wyatt Rileyc7067412018-02-07 15:50:35 -0800301 }
302 }
303
304 public Bundle getBundle() {
Wyatt Riley26465d22018-02-12 13:44:24 -0800305 synchronized (this) {
306 return new Bundle(mBundle);
307 }
Wyatt Rileyc7067412018-02-07 15:50:35 -0800308 }
309 }
310
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700311 private Object mLock = new Object();
312
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800313 // current status
Mike Lockwood15e3d0f2009-05-01 07:53:28 -0400314 private int mStatus = LocationProvider.TEMPORARILY_UNAVAILABLE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800315
316 // time for last status update
317 private long mStatusUpdateTime = SystemClock.elapsedRealtime();
Mike Lockwoodd53ba012010-04-15 20:41:26 -0400318
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800319 // turn off GPS fix icon if we haven't received a fix in 10 seconds
Mike Lockwood04598b62010-04-14 17:17:24 -0400320 private static final long RECENT_FIX_TIMEOUT = 10 * 1000;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800321
Mike Lockwood0632ca72009-05-14 15:51:03 -0400322 // stop trying if we do not receive a fix within 60 seconds
Mike Lockwood04598b62010-04-14 17:17:24 -0400323 private static final int NO_FIX_TIMEOUT = 60 * 1000;
Mike Lockwood0632ca72009-05-14 15:51:03 -0400324
Nick Pellyb041f232012-05-07 17:12:25 -0700325 // if the fix interval is below this we leave GPS on,
326 // if above then we cycle the GPS driver.
327 // Typical hot TTTF is ~5 seconds, so 10 seconds seems sane.
328 private static final int GPS_POLLING_THRESHOLD_INTERVAL = 10 * 1000;
329
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700330 // how long to wait if we have a network error in NTP or XTRA downloading
Wei Liu6f6326b2015-06-24 23:47:50 -0700331 // the initial value of the exponential backoff
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700332 // current setting - 5 minutes
gomo48f1a642017-11-10 20:35:46 -0800333 private static final long RETRY_INTERVAL = 5 * 60 * 1000;
Wei Liu6f6326b2015-06-24 23:47:50 -0700334 // how long to wait if we have a network error in NTP or XTRA downloading
335 // the max value of the exponential backoff
336 // current setting - 4 hours
gomo48f1a642017-11-10 20:35:46 -0800337 private static final long MAX_RETRY_INTERVAL = 4 * 60 * 60 * 1000;
Wei Liu6f6326b2015-06-24 23:47:50 -0700338
Wei Wangc5706f62017-04-18 11:26:26 -0700339 // Timeout when holding wakelocks for downloading XTRA data.
340 private static final long DOWNLOAD_XTRA_DATA_TIMEOUT_MS = 60 * 1000;
341
Yu-Han Yanga1862b52018-02-20 17:05:59 -0800342 private final ExponentialBackOff mXtraBackOff = new ExponentialBackOff(RETRY_INTERVAL,
343 MAX_RETRY_INTERVAL);
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700344
345 // true if we are enabled, protected by this
346 private boolean mEnabled;
347
Kevin Tang40e1baf2012-01-10 14:32:44 -0800348 // states for injecting ntp and downloading xtra data
349 private static final int STATE_PENDING_NETWORK = 0;
350 private static final int STATE_DOWNLOADING = 1;
351 private static final int STATE_IDLE = 2;
352
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400353 // flags to trigger NTP or XTRA data download when network becomes available
354 // initialized to true so we do NTP and XTRA when the network comes up after booting
Kevin Tang40e1baf2012-01-10 14:32:44 -0800355 private int mDownloadXtraDataPending = STATE_PENDING_NETWORK;
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400356
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800357 // true if GPS is navigating
358 private boolean mNavigating;
Mike Lockwoodcf1d8cb2010-01-20 10:14:54 -0500359
360 // true if GPS engine is on
361 private boolean mEngineOn;
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700362
Mike Lockwood04598b62010-04-14 17:17:24 -0400363 // requested frequency of fixes, in milliseconds
364 private int mFixInterval = 1000;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800365
gomo48f1a642017-11-10 20:35:46 -0800366 // true if low power mode for the GNSS chipset is part of the latest request.
367 private boolean mLowPowerMode = false;
368
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800369 // true if we started navigation
370 private boolean mStarted;
371
Stan Chesnutt1d72d8c2013-04-15 19:18:02 -0700372 // true if single shot request is in progress
373 private boolean mSingleShot;
374
Mike Lockwood04598b62010-04-14 17:17:24 -0400375 // capabilities of the GPS engine
376 private int mEngineCapabilities;
377
Mike Lockwood1a1cd3a2010-08-17 07:42:54 -0400378 // true if XTRA is supported
379 private boolean mSupportsXtra;
380
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800381 // for calculating time to first fix
382 private long mFixRequestTime = 0;
383 // time to first fix for most recent session
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700384 private int mTimeToFirstFix = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800385 // time we received our last fix
386 private long mLastFixTime;
387
Mike Lockwood04598b62010-04-14 17:17:24 -0400388 private int mPositionMode;
389
David Christied4edf4c2014-08-12 15:22:27 -0700390 // Current request from underlying location clients.
391 private ProviderRequest mProviderRequest = null;
Narayan Kamath32684dd2018-01-08 17:32:51 +0000392 // The WorkSource associated with the most recent client request (i.e, most recent call to
393 // setRequest).
David Christied4edf4c2014-08-12 15:22:27 -0700394 private WorkSource mWorkSource = null;
395 // True if gps should be disabled (used to support battery saver mode in settings).
396 private boolean mDisableGps = false;
397
destradaafb23c672015-04-16 14:01:27 -0700398 /**
399 * Properties loaded from PROPERTIES_FILE.
400 * It must be accessed only inside {@link #mHandler}.
401 */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800402 private Properties mProperties;
destradaafb23c672015-04-16 14:01:27 -0700403
Mike Lockwood734d6032009-07-28 18:30:25 -0700404 private String mSuplServerHost;
Tsuwei Chen678c13c2014-09-22 17:48:41 -0700405 private int mSuplServerPort = TCP_MIN_PORT;
Mike Lockwood734d6032009-07-28 18:30:25 -0700406 private String mC2KServerHost;
407 private int mC2KServerPort;
Tsuwei Chen3324e952014-09-07 01:30:42 -0700408 private boolean mSuplEsEnabled = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800409
Mike Lockwood15e3d0f2009-05-01 07:53:28 -0400410 private final Context mContext;
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700411 private final ILocationManager mILocationManager;
Wyatt Rileyc7067412018-02-07 15:50:35 -0800412 private final LocationExtras mLocationExtras = new LocationExtras();
Lifu Tang30f95a72016-01-07 23:20:38 -0800413 private final GnssStatusListenerHelper mListenerHelper;
Lifu Tang818aa2c2016-02-01 01:52:00 -0800414 private final GnssMeasurementsProvider mGnssMeasurementsProvider;
415 private final GnssNavigationMessageProvider mGnssNavigationMessageProvider;
Yu-Han Yang07561382018-02-21 13:08:37 -0800416 private final LocationChangeListener mNetworkLocationListener = new NetworkLocationListener();
417 private final LocationChangeListener mFusedLocationListener = new FusedLocationListener();
Yu-Han Yanga1862b52018-02-20 17:05:59 -0800418 private final NtpTimeHelper mNtpTimeHelper;
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400419
Victoria Lease5c24fd02012-10-01 11:00:50 -0700420 // Handler for processing events
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400421 private Handler mHandler;
The Android Open Source Project10592532009-03-18 17:39:46 -0700422
destradaae21252a2015-09-08 12:32:59 -0700423 /** It must be accessed only inside {@link #mHandler}. */
Mike Lockwoode3635c92009-05-11 08:38:02 -0400424 private int mAGpsDataConnectionState;
destradaae21252a2015-09-08 12:32:59 -0700425 /** It must be accessed only inside {@link #mHandler}. */
destradaa96a14702014-06-05 11:36:30 -0700426 private InetAddress mAGpsDataConnectionIpAddr;
destradaae21252a2015-09-08 12:32:59 -0700427
Mike Lockwood2f82c4e2009-04-17 08:24:10 -0400428 private final ConnectivityManager mConnMgr;
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700429 private final GpsNetInitiatedHandler mNIHandler;
Mike Lockwood2f82c4e2009-04-17 08:24:10 -0400430
Mike Lockwood0528b9b2009-05-07 10:12:54 -0400431 // Wakelocks
Lifu Tang30f95a72016-01-07 23:20:38 -0800432 private final static String WAKELOCK_KEY = "GnssLocationProvider";
Mike Lockwood0528b9b2009-05-07 10:12:54 -0400433 private final PowerManager.WakeLock mWakeLock;
Wei Wangb71c0492017-05-01 20:24:19 -0700434 private static final String DOWNLOAD_EXTRA_WAKELOCK_KEY = "GnssLocationProviderXtraDownload";
435 private final PowerManager.WakeLock mDownloadXtraWakeLock;
Mike Lockwood0528b9b2009-05-07 10:12:54 -0400436
Mike Lockwood29c84342009-05-06 14:01:15 -0400437 // Alarms
438 private final static String ALARM_WAKEUP = "com.android.internal.location.ALARM_WAKEUP";
Mike Lockwood0632ca72009-05-14 15:51:03 -0400439 private final static String ALARM_TIMEOUT = "com.android.internal.location.ALARM_TIMEOUT";
Tsuwei Chen52617bb2014-08-25 11:49:11 -0700440
441 // SIM/Carrier info.
442 private final static String SIM_STATE_CHANGED = "android.intent.action.SIM_STATE_CHANGED";
443
Ecco Park624ac3c2016-07-18 14:08:05 -0700444 // Persist property for LPP_PROFILE
445 private final static String LPP_PROFILE = "persist.sys.gps.lpp";
446
Ecco Park624ac3c2016-07-18 14:08:05 -0700447
David Christied4edf4c2014-08-12 15:22:27 -0700448 private final PowerManager mPowerManager;
Mike Lockwood29c84342009-05-06 14:01:15 -0400449 private final AlarmManager mAlarmManager;
450 private final PendingIntent mWakeupIntent;
Mike Lockwood0632ca72009-05-14 15:51:03 -0400451 private final PendingIntent mTimeoutIntent;
Mike Lockwood29c84342009-05-06 14:01:15 -0400452
Svet Ganovf7b47252018-02-26 11:11:27 -0800453 private final AppOpsManager mAppOps;
Mike Lockwood2f82c4e2009-04-17 08:24:10 -0400454 private final IBatteryStats mBatteryStats;
The Android Open Source Project10592532009-03-18 17:39:46 -0700455
Narayan Kamath32684dd2018-01-08 17:32:51 +0000456 // Current list of underlying location clients.
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700457 // only modified on handler thread
Dianne Hackborn002a54e2013-01-10 17:34:55 -0800458 private WorkSource mClientSource = new WorkSource();
Mike Lockwoodf1218be2010-01-29 09:20:06 -0500459
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -0700460 private GeofenceHardwareImpl mGeofenceHardwareImpl;
Wyatt Rileyd87cf912017-12-05 09:31:52 -0800461
462 // Volatile for simple inter-thread sync on these values.
463 private volatile int mHardwareYear = 0;
Wyatt Riley49097c02018-03-15 09:14:43 -0700464 private volatile String mHardwareModelName;
Lifu Tang82f893d2016-01-21 18:15:33 -0800465
Wyatt Riley5d5bac82016-11-01 07:05:16 -0700466 // Set lower than the current ITAR limit of 600m/s to allow this to trigger even if GPS HAL
467 // stops output right at 600m/s, depriving this of the information of a device that reaches
468 // greater than 600m/s, and higher than the speed of sound to avoid impacting most use cases.
469 private static final float ITAR_SPEED_LIMIT_METERS_PER_SECOND = 400.0F;
Wyatt Riley042c48f2017-10-06 14:59:25 -0700470
Wyatt Riley042c48f2017-10-06 14:59:25 -0700471 private volatile boolean mItarSpeedLimitExceeded = false;
Wyatt Riley5d5bac82016-11-01 07:05:16 -0700472
Siddharth Raybb608c82017-03-16 11:33:34 -0700473 // GNSS Metrics
474 private GnssMetrics mGnssMetrics;
475
Lifu Tang30f95a72016-01-07 23:20:38 -0800476 private final IGnssStatusProvider mGnssStatusProvider = new IGnssStatusProvider.Stub() {
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700477 @Override
Lifu Tang30f95a72016-01-07 23:20:38 -0800478 public void registerGnssStatusCallback(IGnssStatusListener callback) {
479 mListenerHelper.addListener(callback);
Mike Lockwood15e3d0f2009-05-01 07:53:28 -0400480 }
481
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700482 @Override
Lifu Tang30f95a72016-01-07 23:20:38 -0800483 public void unregisterGnssStatusCallback(IGnssStatusListener callback) {
484 mListenerHelper.removeListener(callback);
destradaaea8a8a62014-06-23 18:19:03 -0700485 }
486 };
Mike Lockwood15e3d0f2009-05-01 07:53:28 -0400487
Lifu Tang30f95a72016-01-07 23:20:38 -0800488 public IGnssStatusProvider getGnssStatusProvider() {
489 return mGnssStatusProvider;
Mike Lockwood15e3d0f2009-05-01 07:53:28 -0400490 }
491
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -0700492 public IGpsGeofenceHardware getGpsGeofenceProxy() {
493 return mGpsGeofenceBinder;
494 }
495
Lifu Tang818aa2c2016-02-01 01:52:00 -0800496 public GnssMeasurementsProvider getGnssMeasurementsProvider() {
497 return mGnssMeasurementsProvider;
destradaaea8a8a62014-06-23 18:19:03 -0700498 }
499
Lifu Tang818aa2c2016-02-01 01:52:00 -0800500 public GnssNavigationMessageProvider getGnssNavigationMessageProvider() {
501 return mGnssNavigationMessageProvider;
destradaa4b3e3932014-07-21 18:01:47 -0700502 }
503
destradaae21252a2015-09-08 12:32:59 -0700504 /**
505 * Callback used to listen for data connectivity changes.
506 */
507 private final ConnectivityManager.NetworkCallback mNetworkConnectivityCallback =
508 new ConnectivityManager.NetworkCallback() {
gomo48f1a642017-11-10 20:35:46 -0800509 @Override
510 public void onAvailable(Network network) {
Yu-Han Yanga1862b52018-02-20 17:05:59 -0800511 mNtpTimeHelper.onNetworkAvailable();
gomo48f1a642017-11-10 20:35:46 -0800512 if (mDownloadXtraDataPending == STATE_PENDING_NETWORK) {
513 if (mSupportsXtra) {
514 // Download only if supported, (prevents an unneccesary on-boot
515 // download)
516 xtraDownloadRequest();
517 }
518 }
519 // Always on, notify HAL so it can get data it needs
520 sendMessage(UPDATE_NETWORK_STATE, 0 /*arg*/, network);
Wyatt Rileyabc69ea2017-08-08 15:15:28 -0700521 }
Kevin Tang71ad5fe2017-05-10 19:36:20 -0700522
gomo48f1a642017-11-10 20:35:46 -0800523 @Override
524 public void onLost(Network network) {
525 sendMessage(UPDATE_NETWORK_STATE, 0 /*arg*/, network);
526 }
527 };
destradaae21252a2015-09-08 12:32:59 -0700528
529 /**
530 * Callback used to listen for availability of a requested SUPL connection.
531 * It is kept as a separate instance from {@link #mNetworkConnectivityCallback} to be able to
532 * manage the registration/un-registration lifetimes separate.
533 */
534 private final ConnectivityManager.NetworkCallback mSuplConnectivityCallback =
535 new ConnectivityManager.NetworkCallback() {
gomo48f1a642017-11-10 20:35:46 -0800536 @Override
537 public void onAvailable(Network network) {
538 // Specific to a change to a SUPL enabled network becoming ready
539 sendMessage(UPDATE_NETWORK_STATE, 0 /*arg*/, network);
540 }
Wyatt Riley41f6bce2016-12-13 10:45:29 -0800541
gomo48f1a642017-11-10 20:35:46 -0800542 @Override
543 public void onLost(Network network) {
544 releaseSuplConnection(GPS_RELEASE_AGPS_DATA_CONN);
545 }
546 };
destradaae21252a2015-09-08 12:32:59 -0700547
Tsuwei Chen52617bb2014-08-25 11:49:11 -0700548 private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
gomo48f1a642017-11-10 20:35:46 -0800549 @Override
550 public void onReceive(Context context, Intent intent) {
The Android Open Source Project10592532009-03-18 17:39:46 -0700551 String action = intent.getAction();
Tsuwei Chen48d37f92014-09-05 15:15:34 -0700552 if (DEBUG) Log.d(TAG, "receive broadcast intent, action: " + action);
destradaaee9fd342015-08-31 13:31:17 -0700553 if (action == null) {
554 return;
555 }
556
Mike Lockwood29c84342009-05-06 14:01:15 -0400557 if (action.equals(ALARM_WAKEUP)) {
Stan Chesnutt1d72d8c2013-04-15 19:18:02 -0700558 startNavigating(false);
Mike Lockwood0632ca72009-05-14 15:51:03 -0400559 } else if (action.equals(ALARM_TIMEOUT)) {
Mike Lockwood0632ca72009-05-14 15:51:03 -0400560 hibernate();
David Christied4edf4c2014-08-12 15:22:27 -0700561 } else if (PowerManager.ACTION_POWER_SAVE_MODE_CHANGED.equals(action)
Adam Lesinski87c17df2015-05-27 13:24:13 -0700562 || PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED.equals(action)
David Christied4edf4c2014-08-12 15:22:27 -0700563 || Intent.ACTION_SCREEN_OFF.equals(action)
564 || Intent.ACTION_SCREEN_ON.equals(action)) {
565 updateLowPowerMode();
Wink Savillea374c3d2014-11-11 11:48:04 -0800566 } else if (action.equals(SIM_STATE_CHANGED)) {
567 subscriptionOrSimChanged(context);
David Christied4edf4c2014-08-12 15:22:27 -0700568 }
The Android Open Source Project10592532009-03-18 17:39:46 -0700569 }
Mike Lockwood29c84342009-05-06 14:01:15 -0400570 };
The Android Open Source Project10592532009-03-18 17:39:46 -0700571
Wink Savilled09c4ca2014-11-22 10:08:16 -0800572 private final OnSubscriptionsChangedListener mOnSubscriptionsChangedListener =
573 new OnSubscriptionsChangedListener() {
gomo48f1a642017-11-10 20:35:46 -0800574 @Override
575 public void onSubscriptionsChanged() {
576 sendMessage(SUBSCRIPTION_OR_SIM_CHANGED, 0, null);
577 }
578 };
Wink Savillea374c3d2014-11-11 11:48:04 -0800579
580 private void subscriptionOrSimChanged(Context context) {
Joe Onorato0c484102016-02-01 18:04:24 -0800581 if (DEBUG) Log.d(TAG, "received SIM related action: ");
Wink Savillea374c3d2014-11-11 11:48:04 -0800582 TelephonyManager phone = (TelephonyManager)
583 mContext.getSystemService(Context.TELEPHONY_SERVICE);
Ecco Park4fa1ab72016-10-24 13:04:52 -0700584 CarrierConfigManager configManager = (CarrierConfigManager)
585 mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE);
Wink Savillea374c3d2014-11-11 11:48:04 -0800586 String mccMnc = phone.getSimOperator();
Ecco Park4fa1ab72016-10-24 13:04:52 -0700587 boolean isKeepLppProfile = false;
Wink Savillea374c3d2014-11-11 11:48:04 -0800588 if (!TextUtils.isEmpty(mccMnc)) {
Joe Onorato0c484102016-02-01 18:04:24 -0800589 if (DEBUG) Log.d(TAG, "SIM MCC/MNC is available: " + mccMnc);
Wink Savillea374c3d2014-11-11 11:48:04 -0800590 synchronized (mLock) {
Ecco Park4fa1ab72016-10-24 13:04:52 -0700591 if (configManager != null) {
592 PersistableBundle b = configManager.getConfig();
Wyatt Rileya8ce2252017-09-01 13:31:17 -0700593 if (b != null) {
594 isKeepLppProfile =
595 b.getBoolean(CarrierConfigManager.KEY_PERSIST_LPP_MODE_BOOL);
596 }
Ecco Park4fa1ab72016-10-24 13:04:52 -0700597 }
598 if (isKeepLppProfile) {
599 // load current properties for the carrier
600 loadPropertiesFromResource(context, mProperties);
601 String lpp_profile = mProperties.getProperty("LPP_PROFILE");
602 // set the persist property LPP_PROFILE for the value
Ecco Park8eec7442017-08-04 16:21:59 -0700603 if (lpp_profile != null) {
604 SystemProperties.set(LPP_PROFILE, lpp_profile);
605 }
Ecco Park624ac3c2016-07-18 14:08:05 -0700606 } else {
Ecco Park4fa1ab72016-10-24 13:04:52 -0700607 // reset the persist property
608 SystemProperties.set(LPP_PROFILE, "");
Ecco Park624ac3c2016-07-18 14:08:05 -0700609 }
Wink Savillea374c3d2014-11-11 11:48:04 -0800610 reloadGpsProperties(context, mProperties);
611 mNIHandler.setSuplEsEnabled(mSuplEsEnabled);
612 }
613 } else {
Joe Onorato0c484102016-02-01 18:04:24 -0800614 if (DEBUG) Log.d(TAG, "SIM MCC/MNC is still not available");
Wink Savillea374c3d2014-11-11 11:48:04 -0800615 }
616 }
617
David Christied4edf4c2014-08-12 15:22:27 -0700618 private void updateLowPowerMode() {
Adam Lesinski87c17df2015-05-27 13:24:13 -0700619 // Disable GPS if we are in device idle mode.
620 boolean disableGps = mPowerManager.isDeviceIdleMode();
jackqdyulei455e90a2017-02-09 15:29:16 -0800621 final PowerSaveState result =
622 mPowerManager.getPowerSaveState(ServiceType.GPS);
623 switch (result.gpsMode) {
Makoto Onuki57f0f552017-12-11 12:22:18 -0800624 case PowerManager.LOCATION_MODE_GPS_DISABLED_WHEN_SCREEN_OFF:
Adam Lesinski87c17df2015-05-27 13:24:13 -0700625 // If we are in battery saver mode and the screen is off, disable GPS.
jackqdyulei455e90a2017-02-09 15:29:16 -0800626 disableGps |= result.batterySaverEnabled && !mPowerManager.isInteractive();
David Christied4edf4c2014-08-12 15:22:27 -0700627 break;
David Christied4edf4c2014-08-12 15:22:27 -0700628 }
629 if (disableGps != mDisableGps) {
630 mDisableGps = disableGps;
631 updateRequirements();
632 }
633 }
634
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800635 public static boolean isSupported() {
636 return native_is_supported();
637 }
638
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700639 interface SetCarrierProperty {
640 public boolean set(int value);
641 }
642
Tsuwei Chen52617bb2014-08-25 11:49:11 -0700643 private void reloadGpsProperties(Context context, Properties properties) {
Joe Onorato0c484102016-02-01 18:04:24 -0800644 if (DEBUG) Log.d(TAG, "Reset GPS properties, previous size = " + properties.size());
Tsuwei Chen52617bb2014-08-25 11:49:11 -0700645 loadPropertiesFromResource(context, properties);
Ecco Park624ac3c2016-07-18 14:08:05 -0700646
Ecco Park624ac3c2016-07-18 14:08:05 -0700647 String lpp_prof = SystemProperties.get(LPP_PROFILE);
648 if (!TextUtils.isEmpty(lpp_prof)) {
gomo48f1a642017-11-10 20:35:46 -0800649 // override default value of this if lpp_prof is not empty
650 properties.setProperty("LPP_PROFILE", lpp_prof);
Ecco Park624ac3c2016-07-18 14:08:05 -0700651 }
Wyatt Riley3e1cd0b2017-04-19 17:57:14 -0700652 /*
653 * Overlay carrier properties from a debug configuration file.
654 */
655 loadPropertiesFromFile(DEBUG_PROPERTIES_FILE, properties);
Tsuwei Chen52617bb2014-08-25 11:49:11 -0700656 // TODO: we should get rid of C2K specific setting.
657 setSuplHostPort(properties.getProperty("SUPL_HOST"),
gomo48f1a642017-11-10 20:35:46 -0800658 properties.getProperty("SUPL_PORT"));
Tsuwei Chen52617bb2014-08-25 11:49:11 -0700659 mC2KServerHost = properties.getProperty("C2K_HOST");
660 String portString = properties.getProperty("C2K_PORT");
661 if (mC2KServerHost != null && portString != null) {
662 try {
663 mC2KServerPort = Integer.parseInt(portString);
664 } catch (NumberFormatException e) {
665 Log.e(TAG, "unable to parse C2K_PORT: " + portString);
666 }
667 }
destradaaef752b62015-04-17 13:10:47 -0700668 if (native_is_gnss_configuration_supported()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700669 Map<String, SetCarrierProperty> map = new HashMap<String, SetCarrierProperty>() {
670 {
671 put("SUPL_VER", (val) -> native_set_supl_version(val));
672 put("SUPL_MODE", (val) -> native_set_supl_mode(val));
673 put("SUPL_ES", (val) -> native_set_supl_es(val));
674 put("LPP_PROFILE", (val) -> native_set_lpp_profile(val));
gomo48f1a642017-11-10 20:35:46 -0800675 put("A_GLONASS_POS_PROTOCOL_SELECT",
676 (val) -> native_set_gnss_pos_protocol_select(val));
677 put("USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL",
678 (val) -> native_set_emergency_supl_pdn(val));
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700679 put("GPS_LOCK", (val) -> native_set_gps_lock(val));
680 }
681 };
682
gomo48f1a642017-11-10 20:35:46 -0800683 for (Entry<String, SetCarrierProperty> entry : map.entrySet()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700684 String propertyName = entry.getKey();
685 String propertyValueString = properties.getProperty(propertyName);
686 if (propertyValueString != null) {
687 try {
gomo48f1a642017-11-10 20:35:46 -0800688 int propertyValueInt = Integer.decode(propertyValueString);
689 boolean result = entry.getValue().set(propertyValueInt);
690 if (result == false) {
691 Log.e(TAG, "Unable to set " + propertyName);
692 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700693 } catch (NumberFormatException e) {
gomo48f1a642017-11-10 20:35:46 -0800694 Log.e(TAG, "unable to parse propertyName: " + propertyValueString);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700695 }
696 }
destradaaef752b62015-04-17 13:10:47 -0700697 }
698 } else if (DEBUG) {
699 Log.d(TAG, "Skipped configuration update because GNSS configuration in GPS HAL is not"
700 + " supported");
Tsuwei Chen52617bb2014-08-25 11:49:11 -0700701 }
Tsuwei Chen3324e952014-09-07 01:30:42 -0700702
703 // SUPL_ES configuration.
704 String suplESProperty = mProperties.getProperty("SUPL_ES");
705 if (suplESProperty != null) {
706 try {
707 mSuplEsEnabled = (Integer.parseInt(suplESProperty) == 1);
708 } catch (NumberFormatException e) {
709 Log.e(TAG, "unable to parse SUPL_ES: " + suplESProperty);
710 }
711 }
Tsuwei Chen52617bb2014-08-25 11:49:11 -0700712 }
713
714 private void loadPropertiesFromResource(Context context,
gomo48f1a642017-11-10 20:35:46 -0800715 Properties properties) {
Tsuwei Chen52617bb2014-08-25 11:49:11 -0700716 String[] configValues = context.getResources().getStringArray(
717 com.android.internal.R.array.config_gpsParameters);
718 for (String item : configValues) {
Joe Onorato0c484102016-02-01 18:04:24 -0800719 if (DEBUG) Log.d(TAG, "GpsParamsResource: " + item);
Tsuwei Chen7c485bf2014-09-10 15:33:34 -0700720 // We need to support "KEY =", but not "=VALUE".
Zheng Zhangad48bd92017-10-16 10:27:28 -0700721 int index = item.indexOf("=");
722 if (index > 0 && index + 1 < item.length()) {
723 String key = item.substring(0, index);
724 String value = item.substring(index + 1);
725 properties.setProperty(key.trim().toUpperCase(), value);
Tsuwei Chen52617bb2014-08-25 11:49:11 -0700726 } else {
727 Log.w(TAG, "malformed contents: " + item);
728 }
729 }
730 }
731
732 private boolean loadPropertiesFromFile(String filename,
gomo48f1a642017-11-10 20:35:46 -0800733 Properties properties) {
Colin Cross7c030ed2014-01-28 09:33:53 -0800734 try {
735 File file = new File(filename);
736 FileInputStream stream = null;
737 try {
738 stream = new FileInputStream(file);
Tsuwei Chen52617bb2014-08-25 11:49:11 -0700739 properties.load(stream);
Colin Cross7c030ed2014-01-28 09:33:53 -0800740 } finally {
741 IoUtils.closeQuietly(stream);
742 }
743
Colin Cross7c030ed2014-01-28 09:33:53 -0800744 } catch (IOException e) {
Wyatt Riley3e1cd0b2017-04-19 17:57:14 -0700745 if (DEBUG) Log.d(TAG, "Could not open GPS configuration file " + filename);
Colin Cross7c030ed2014-01-28 09:33:53 -0800746 return false;
747 }
748 return true;
749 }
750
Lifu Tang30f95a72016-01-07 23:20:38 -0800751 public GnssLocationProvider(Context context, ILocationManager ilocationManager,
Victoria Lease5cd731a2012-12-19 15:04:21 -0800752 Looper looper) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800753 mContext = context;
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700754 mILocationManager = ilocationManager;
Mike Lockwood63598a02010-02-24 11:52:59 -0500755
Mike Lockwood0528b9b2009-05-07 10:12:54 -0400756 // Create a wake lock
David Christied4edf4c2014-08-12 15:22:27 -0700757 mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
758 mWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, WAKELOCK_KEY);
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700759 mWakeLock.setReferenceCounted(true);
Mike Lockwood0528b9b2009-05-07 10:12:54 -0400760
Wei Wangb71c0492017-05-01 20:24:19 -0700761 // Create a separate wake lock for xtra downloader as it may be released due to timeout.
762 mDownloadXtraWakeLock = mPowerManager.newWakeLock(
763 PowerManager.PARTIAL_WAKE_LOCK, DOWNLOAD_EXTRA_WAKELOCK_KEY);
764 mDownloadXtraWakeLock.setReferenceCounted(true);
765
gomo48f1a642017-11-10 20:35:46 -0800766 mAlarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
Mike Lockwood29c84342009-05-06 14:01:15 -0400767 mWakeupIntent = PendingIntent.getBroadcast(mContext, 0, new Intent(ALARM_WAKEUP), 0);
Mike Lockwood0632ca72009-05-14 15:51:03 -0400768 mTimeoutIntent = PendingIntent.getBroadcast(mContext, 0, new Intent(ALARM_TIMEOUT), 0);
Mike Lockwood29c84342009-05-06 14:01:15 -0400769
gomo48f1a642017-11-10 20:35:46 -0800770 mConnMgr = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
Mike Lockwood58bda982009-04-14 16:25:07 -0400771
Dianne Hackborna06de0f2012-12-11 16:34:47 -0800772 // App ops service to keep track of who is accessing the GPS
Svet Ganovf7b47252018-02-26 11:11:27 -0800773 mAppOps = mContext.getSystemService(AppOpsManager.class);
Dianne Hackborna06de0f2012-12-11 16:34:47 -0800774
Mike Lockwood2f82c4e2009-04-17 08:24:10 -0400775 // Battery statistics service to be notified when GPS turns on or off
Dianne Hackborn91268cf2013-06-13 19:06:50 -0700776 mBatteryStats = IBatteryStats.Stub.asInterface(ServiceManager.getService(
777 BatteryStats.SERVICE_NAME));
Mike Lockwood2f82c4e2009-04-17 08:24:10 -0400778
destradaafb23c672015-04-16 14:01:27 -0700779 // Construct internal handler
780 mHandler = new ProviderHandler(looper);
781
782 // Load GPS configuration and register listeners in the background:
783 // some operations, such as opening files and registering broadcast receivers, can take a
784 // relative long time, so the ctor() is kept to create objects needed by this instance,
785 // while IO initialization and registration is delegated to our internal handler
786 // this approach is just fine because events are posted to our handler anyway
Tsuwei Chen52617bb2014-08-25 11:49:11 -0700787 mProperties = new Properties();
destradaafb23c672015-04-16 14:01:27 -0700788 sendMessage(INITIALIZE_HANDLER, 0, null);
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400789
Tsuwei Chen3324e952014-09-07 01:30:42 -0700790 // Create a GPS net-initiated handler.
791 mNIHandler = new GpsNetInitiatedHandler(context,
gomo48f1a642017-11-10 20:35:46 -0800792 mNetInitiatedListener,
793 mSuplEsEnabled);
Tsuwei Chen3324e952014-09-07 01:30:42 -0700794
Lifu Tang30f95a72016-01-07 23:20:38 -0800795 mListenerHelper = new GnssStatusListenerHelper(mHandler) {
destradaa6568d702014-10-27 12:47:41 -0700796 @Override
797 protected boolean isAvailableInPlatform() {
destradaa13a60b02015-01-15 18:36:01 -0800798 return isSupported();
destradaa6568d702014-10-27 12:47:41 -0700799 }
800
801 @Override
802 protected boolean isGpsEnabled() {
803 return isEnabled();
804 }
805 };
806
Lifu Tang818aa2c2016-02-01 01:52:00 -0800807 mGnssMeasurementsProvider = new GnssMeasurementsProvider(mHandler) {
destradaa6568d702014-10-27 12:47:41 -0700808 @Override
809 public boolean isAvailableInPlatform() {
810 return native_is_measurement_supported();
811 }
812
813 @Override
gomo48f1a642017-11-10 20:35:46 -0800814 protected int registerWithService() {
815 int devOptions = Settings.Secure.getInt(mContext.getContentResolver(),
816 Settings.Global.DEVELOPMENT_SETTINGS_ENABLED , 0);
817 int fullTrackingToggled = Settings.Global.getInt(mContext.getContentResolver(),
818 Settings.Global.ENABLE_GNSS_RAW_MEAS_FULL_TRACKING , 0);
819 boolean result = false;
820 if (devOptions == 1 /* Developer Mode enabled */
821 && fullTrackingToggled == 1 /* Raw Measurements Full Tracking enabled */) {
822 result = native_start_measurement_collection(true /* enableFullTracking */);
823 } else {
824 result = native_start_measurement_collection(false /* enableFullTracking */);
825 }
826 if (result) {
827 return RemoteListenerHelper.RESULT_SUCCESS;
828 } else {
829 return RemoteListenerHelper.RESULT_INTERNAL_ERROR;
830 }
destradaa6568d702014-10-27 12:47:41 -0700831 }
832
833 @Override
834 protected void unregisterFromService() {
835 native_stop_measurement_collection();
836 }
837
838 @Override
839 protected boolean isGpsEnabled() {
840 return isEnabled();
841 }
842 };
843
Lifu Tang818aa2c2016-02-01 01:52:00 -0800844 mGnssNavigationMessageProvider = new GnssNavigationMessageProvider(mHandler) {
destradaa6568d702014-10-27 12:47:41 -0700845 @Override
846 protected boolean isAvailableInPlatform() {
847 return native_is_navigation_message_supported();
848 }
849
850 @Override
gomo48f1a642017-11-10 20:35:46 -0800851 protected int registerWithService() {
852 boolean result = native_start_navigation_message_collection();
853 if (result) {
854 return RemoteListenerHelper.RESULT_SUCCESS;
855 } else {
856 return RemoteListenerHelper.RESULT_INTERNAL_ERROR;
857 }
destradaa6568d702014-10-27 12:47:41 -0700858 }
859
860 @Override
861 protected void unregisterFromService() {
862 native_stop_navigation_message_collection();
863 }
864
865 @Override
866 protected boolean isGpsEnabled() {
867 return isEnabled();
868 }
869 };
Siddharth Ray78ccaf52017-12-23 16:16:21 -0800870 mGnssMetrics = new GnssMetrics(mBatteryStats);
Yu-Han Yanga1862b52018-02-20 17:05:59 -0800871
872 mNtpTimeHelper = new NtpTimeHelper(mContext, Looper.myLooper(), this);
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400873 }
874
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800875 /**
Mike Lockwoodd03ff942010-02-09 08:46:14 -0500876 * Returns the name of this provider.
877 */
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700878 @Override
Mike Lockwoodd03ff942010-02-09 08:46:14 -0500879 public String getName() {
880 return LocationManager.GPS_PROVIDER;
881 }
882
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700883 @Override
884 public ProviderProperties getProperties() {
885 return PROPERTIES;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800886 }
887
Yu-Han Yanga1862b52018-02-20 17:05:59 -0800888
889 /**
890 * Implements {@link InjectNtpTimeCallback#injectTime}
891 */
892 @Override
893 public void injectTime(long time, long timeReference, int uncertainty) {
894 native_inject_time(time, timeReference, uncertainty);
895 }
896
destradaae21252a2015-09-08 12:32:59 -0700897 private void handleUpdateNetworkState(Network network) {
898 // retrieve NetworkInfo for this UID
899 NetworkInfo info = mConnMgr.getNetworkInfo(network);
Kevin Tang71ad5fe2017-05-10 19:36:20 -0700900
901 boolean networkAvailable = false;
902 boolean isConnected = false;
903 int type = ConnectivityManager.TYPE_NONE;
904 boolean isRoaming = false;
905 String apnName = null;
906
907 if (info != null) {
908 networkAvailable = info.isAvailable() && TelephonyManager.getDefault().getDataEnabled();
909 isConnected = info.isConnected();
910 type = info.getType();
911 isRoaming = info.isRoaming();
912 apnName = info.getExtraInfo();
destradaae21252a2015-09-08 12:32:59 -0700913 }
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400914
Joe Onoratof5d95cb2010-01-07 21:48:32 -0500915 if (DEBUG) {
destradaae21252a2015-09-08 12:32:59 -0700916 String message = String.format(
917 "UpdateNetworkState, state=%s, connected=%s, info=%s, capabilities=%S",
918 agpsDataConnStateAsString(),
919 isConnected,
920 info,
921 mConnMgr.getNetworkCapabilities(network));
922 Log.d(TAG, message);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800923 }
Mike Lockwood03d24672009-10-08 15:45:03 -0400924
destradaae21252a2015-09-08 12:32:59 -0700925 if (native_is_agps_ril_supported()) {
destradaae21252a2015-09-08 12:32:59 -0700926 String defaultApn = getSelectedApn();
927 if (defaultApn == null) {
928 defaultApn = "dummy-apn";
destradaaef752b62015-04-17 13:10:47 -0700929 }
destradaae21252a2015-09-08 12:32:59 -0700930
931 native_update_network_state(
932 isConnected,
Kevin Tang71ad5fe2017-05-10 19:36:20 -0700933 type,
934 isRoaming,
destradaae21252a2015-09-08 12:32:59 -0700935 networkAvailable,
Kevin Tang71ad5fe2017-05-10 19:36:20 -0700936 apnName,
destradaae21252a2015-09-08 12:32:59 -0700937 defaultApn);
938 } else if (DEBUG) {
939 Log.d(TAG, "Skipped network state update because GPS HAL AGPS-RIL is not supported");
Mike Lockwood50130bb2010-10-11 06:22:50 -0400940 }
941
destradaae21252a2015-09-08 12:32:59 -0700942 if (mAGpsDataConnectionState == AGPS_DATA_CONNECTION_OPENING) {
943 if (isConnected) {
Stephen Li83b69712011-01-25 18:47:28 -0800944 if (apnName == null) {
destradaae21252a2015-09-08 12:32:59 -0700945 // assign a dummy value in the case of C2K as otherwise we will have a runtime
946 // exception in the following call to native_agps_data_conn_open
Stephen Li83b69712011-01-25 18:47:28 -0800947 apnName = "dummy-apn";
948 }
destradaae21252a2015-09-08 12:32:59 -0700949 int apnIpType = getApnIpType(apnName);
destradaa96a14702014-06-05 11:36:30 -0700950 setRouting();
951 if (DEBUG) {
952 String message = String.format(
953 "native_agps_data_conn_open: mAgpsApn=%s, mApnIpType=%s",
destradaae21252a2015-09-08 12:32:59 -0700954 apnName,
955 apnIpType);
destradaa96a14702014-06-05 11:36:30 -0700956 Log.d(TAG, message);
Stephen Li8efd74d2011-03-01 20:56:00 -0800957 }
destradaae21252a2015-09-08 12:32:59 -0700958 native_agps_data_conn_open(apnName, apnIpType);
Mike Lockwood03d24672009-10-08 15:45:03 -0400959 mAGpsDataConnectionState = AGPS_DATA_CONNECTION_OPEN;
960 } else {
destradaae21252a2015-09-08 12:32:59 -0700961 handleReleaseSuplConnection(GPS_AGPS_DATA_CONN_FAILED);
Mike Lockwood03d24672009-10-08 15:45:03 -0400962 }
963 }
destradaae21252a2015-09-08 12:32:59 -0700964 }
Mike Lockwood03d24672009-10-08 15:45:03 -0400965
destradaae21252a2015-09-08 12:32:59 -0700966 private void handleRequestSuplConnection(InetAddress address) {
967 if (DEBUG) {
968 String message = String.format(
969 "requestSuplConnection, state=%s, address=%s",
970 agpsDataConnStateAsString(),
971 address);
972 Log.d(TAG, message);
973 }
974
975 if (mAGpsDataConnectionState != AGPS_DATA_CONNECTION_CLOSED) {
976 return;
977 }
978 mAGpsDataConnectionIpAddr = address;
979 mAGpsDataConnectionState = AGPS_DATA_CONNECTION_OPENING;
980
981 NetworkRequest.Builder requestBuilder = new NetworkRequest.Builder();
982 requestBuilder.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR);
983 requestBuilder.addCapability(NetworkCapabilities.NET_CAPABILITY_SUPL);
984 NetworkRequest request = requestBuilder.build();
985 mConnMgr.requestNetwork(
986 request,
Etan Cohene9aea9d2017-02-09 18:16:58 -0800987 mSuplConnectivityCallback);
destradaae21252a2015-09-08 12:32:59 -0700988 }
989
990 private void handleReleaseSuplConnection(int agpsDataConnStatus) {
991 if (DEBUG) {
992 String message = String.format(
993 "releaseSuplConnection, state=%s, status=%s",
994 agpsDataConnStateAsString(),
995 agpsDataConnStatusAsString(agpsDataConnStatus));
996 Log.d(TAG, message);
997 }
998
999 if (mAGpsDataConnectionState == AGPS_DATA_CONNECTION_CLOSED) {
1000 return;
1001 }
1002 mAGpsDataConnectionState = AGPS_DATA_CONNECTION_CLOSED;
1003
1004 mConnMgr.unregisterNetworkCallback(mSuplConnectivityCallback);
1005 switch (agpsDataConnStatus) {
1006 case GPS_AGPS_DATA_CONN_FAILED:
1007 native_agps_data_conn_failed();
1008 break;
1009 case GPS_RELEASE_AGPS_DATA_CONN:
1010 native_agps_data_conn_closed();
1011 break;
1012 default:
1013 Log.e(TAG, "Invalid status to release SUPL connection: " + agpsDataConnStatus);
Mike Lockwood62a8fc12010-03-22 14:23:26 -04001014 }
1015 }
Yu-Han Yanga1862b52018-02-20 17:05:59 -08001016
Yu-Han Yange7baef32018-02-09 13:58:17 -08001017 private void handleRequestLocation(boolean independentFromGnss) {
1018 if (isRequestLocationRateLimited()) {
1019 if (DEBUG) {
1020 Log.d(TAG, "RequestLocation is denied due to too frequent requests.");
1021 }
1022 return;
1023 }
1024
1025 LocationManager locationManager = (LocationManager) mContext.getSystemService(
1026 Context.LOCATION_SERVICE);
Yu-Han Yang07561382018-02-21 13:08:37 -08001027 String provider;
1028 LocationChangeListener locationListener;
Yu-Han Yange7baef32018-02-09 13:58:17 -08001029
1030 if (independentFromGnss) {
1031 // For fast GNSS TTFF
Yu-Han Yang07561382018-02-21 13:08:37 -08001032 provider = LocationManager.NETWORK_PROVIDER;
1033 locationListener = mNetworkLocationListener;
Yu-Han Yange7baef32018-02-09 13:58:17 -08001034 } else {
1035 // For Device-Based Hybrid (E911)
Yu-Han Yang07561382018-02-21 13:08:37 -08001036 provider = LocationManager.FUSED_PROVIDER;
1037 locationListener = mFusedLocationListener;
Yu-Han Yange7baef32018-02-09 13:58:17 -08001038 }
Yu-Han Yang07561382018-02-21 13:08:37 -08001039
1040 Log.i(TAG,
1041 String.format("GNSS HAL Requesting location updates from %s provider.", provider));
1042 locationManager.requestLocationUpdates(provider,
1043 LOCATION_UPDATE_MIN_TIME_INTERVAL_MILLIS, /*minDistance=*/ 0,
1044 locationListener, mHandler.getLooper());
1045 locationListener.numLocationUpdateRequest++;
1046 mHandler.postDelayed(() -> {
1047 if (--locationListener.numLocationUpdateRequest == 0) {
1048 Log.i(TAG, String.format("Removing location updates from %s provider.", provider));
1049 locationManager.removeUpdates(locationListener);
1050 }
1051 }, LOCATION_UPDATE_DURATION_MILLIS);
Yu-Han Yange7baef32018-02-09 13:58:17 -08001052 }
1053
1054 private void injectBestLocation(Location location) {
1055 int gnssLocationFlags = LOCATION_HAS_LAT_LONG |
1056 (location.hasAltitude() ? LOCATION_HAS_ALTITUDE : 0) |
1057 (location.hasSpeed() ? LOCATION_HAS_SPEED : 0) |
1058 (location.hasBearing() ? LOCATION_HAS_BEARING : 0) |
1059 (location.hasAccuracy() ? LOCATION_HAS_HORIZONTAL_ACCURACY : 0) |
1060 (location.hasVerticalAccuracy() ? LOCATION_HAS_VERTICAL_ACCURACY : 0) |
1061 (location.hasSpeedAccuracy() ? LOCATION_HAS_SPEED_ACCURACY : 0) |
1062 (location.hasBearingAccuracy() ? LOCATION_HAS_BEARING_ACCURACY : 0);
1063
1064 double latitudeDegrees = location.getLatitude();
1065 double longitudeDegrees = location.getLongitude();
1066 double altitudeMeters = location.getAltitude();
1067 float speedMetersPerSec = location.getSpeed();
1068 float bearingDegrees = location.getBearing();
1069 float horizontalAccuracyMeters = location.getAccuracy();
1070 float verticalAccuracyMeters = location.getVerticalAccuracyMeters();
1071 float speedAccuracyMetersPerSecond = location.getSpeedAccuracyMetersPerSecond();
1072 float bearingAccuracyDegrees = location.getBearingAccuracyDegrees();
1073 long timestamp = location.getTime();
1074 native_inject_best_location(gnssLocationFlags, latitudeDegrees, longitudeDegrees,
1075 altitudeMeters, speedMetersPerSec, bearingDegrees, horizontalAccuracyMeters,
1076 verticalAccuracyMeters, speedAccuracyMetersPerSecond, bearingAccuracyDegrees,
1077 timestamp);
1078 }
1079
1080 /**
1081 * Get the last fresh location.
1082 *
1083 * Return null if the last location is not available or not fresh.
1084 */
1085 private @Nullable
1086 Location getLastFreshLocation(LocationManager locationManager, String provider) {
1087 Location location = locationManager.getLastKnownLocation(provider);
1088 if (location != null && System.currentTimeMillis() - location.getTime()
1089 < LOCATION_TIME_FRESHNESS_THESHOLD_MILLIS) {
1090 return location;
1091 }
1092 return null;
1093 }
1094
1095 /** Returns true if the location request is too frequent. */
1096 private boolean isRequestLocationRateLimited() {
1097 // TODO(b/73198123): implement exponential backoff.
1098 return false;
1099 }
1100
Mike Lockwood62a8fc12010-03-22 14:23:26 -04001101 private void handleDownloadXtraData() {
Wyatt Riley0d6e54e22016-10-05 12:03:03 -07001102 if (!mSupportsXtra) {
1103 // native code reports xtra not supported, don't try
1104 Log.d(TAG, "handleDownloadXtraData() called when Xtra not supported");
1105 return;
1106 }
Kevin Tang40e1baf2012-01-10 14:32:44 -08001107 if (mDownloadXtraDataPending == STATE_DOWNLOADING) {
1108 // already downloading data
Mike Lockwood62a8fc12010-03-22 14:23:26 -04001109 return;
1110 }
destradaae21252a2015-09-08 12:32:59 -07001111 if (!isDataNetworkConnected()) {
Kevin Tang40e1baf2012-01-10 14:32:44 -08001112 // try again when network is up
1113 mDownloadXtraDataPending = STATE_PENDING_NETWORK;
1114 return;
Mike Lockwood62a8fc12010-03-22 14:23:26 -04001115 }
Kevin Tang40e1baf2012-01-10 14:32:44 -08001116 mDownloadXtraDataPending = STATE_DOWNLOADING;
1117
Jeff Brown028872f2012-08-25 13:07:01 -07001118 // hold wake lock while task runs
Wei Wangb71c0492017-05-01 20:24:19 -07001119 mDownloadXtraWakeLock.acquire(DOWNLOAD_XTRA_DATA_TIMEOUT_MS);
Lifu Tangcbd2a142016-06-22 10:57:55 -07001120 Log.i(TAG, "WakeLock acquired by handleDownloadXtraData()");
Kevin Tang40e1baf2012-01-10 14:32:44 -08001121 AsyncTask.THREAD_POOL_EXECUTOR.execute(new Runnable() {
1122 @Override
1123 public void run() {
Andreas Gampedfdc6ac2014-10-28 20:42:53 -07001124 GpsXtraDownloader xtraDownloader = new GpsXtraDownloader(mProperties);
Kevin Tang40e1baf2012-01-10 14:32:44 -08001125 byte[] data = xtraDownloader.downloadXtraData();
1126 if (data != null) {
destradaae21252a2015-09-08 12:32:59 -07001127 if (DEBUG) Log.d(TAG, "calling native_inject_xtra_data");
Kevin Tang40e1baf2012-01-10 14:32:44 -08001128 native_inject_xtra_data(data, data.length);
Wei Liu6f6326b2015-06-24 23:47:50 -07001129 mXtraBackOff.reset();
Kevin Tang40e1baf2012-01-10 14:32:44 -08001130 }
1131
Jeff Brown028872f2012-08-25 13:07:01 -07001132 sendMessage(DOWNLOAD_XTRA_DATA_FINISHED, 0, null);
Kevin Tang40e1baf2012-01-10 14:32:44 -08001133
1134 if (data == null) {
1135 // try again later
1136 // since this is delayed and not urgent we do not hold a wake lock here
Wei Liu6f6326b2015-06-24 23:47:50 -07001137 mHandler.sendEmptyMessageDelayed(DOWNLOAD_XTRA_DATA,
1138 mXtraBackOff.nextBackoffMillis());
Kevin Tang40e1baf2012-01-10 14:32:44 -08001139 }
Kevin Tang40e1baf2012-01-10 14:32:44 -08001140
Wei Wangb71c0492017-05-01 20:24:19 -07001141 // Release wake lock held by task, synchronize on mLock in case multiple
1142 // download tasks overrun.
1143 synchronized (mLock) {
1144 if (mDownloadXtraWakeLock.isHeld()) {
Zheng Zhang3cceb252017-08-07 13:51:23 -07001145 // This wakelock may have time-out, if a timeout was specified.
1146 // Catch (and ignore) any timeout exceptions.
1147 try {
1148 mDownloadXtraWakeLock.release();
1149 if (DEBUG) Log.d(TAG, "WakeLock released by handleDownloadXtraData()");
1150 } catch (Exception e) {
1151 Log.i(TAG, "Wakelock timeout & release race exception in "
1152 + "handleDownloadXtraData()", e);
1153 }
Wei Wangb71c0492017-05-01 20:24:19 -07001154 } else {
1155 Log.e(TAG, "WakeLock expired before release in "
1156 + "handleDownloadXtraData()");
1157 }
Wei Wangc5706f62017-04-18 11:26:26 -07001158 }
Jeff Brown028872f2012-08-25 13:07:01 -07001159 }
Kevin Tang40e1baf2012-01-10 14:32:44 -08001160 });
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001161 }
1162
Mike Lockwood62a8fc12010-03-22 14:23:26 -04001163 private void handleUpdateLocation(Location location) {
Mike Lockwoodd26ce0d2009-06-11 12:25:46 -04001164 if (location.hasAccuracy()) {
1165 native_inject_location(location.getLatitude(), location.getLongitude(),
1166 location.getAccuracy());
1167 }
Mike Lockwoodfd6e5f02009-05-21 11:28:20 -04001168 }
1169
1170 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001171 * Enables this provider. When enabled, calls to getStatus()
Mike Lockwood4e50b782009-04-03 08:24:43 -07001172 * must be handled. Hardware may be started up
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001173 * when the provider is enabled.
1174 */
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001175 @Override
Mike Lockwood62a8fc12010-03-22 14:23:26 -04001176 public void enable() {
Laurent Tu7b5aeca2013-01-24 15:10:24 -08001177 synchronized (mLock) {
1178 if (mEnabled) return;
1179 mEnabled = true;
1180 }
1181
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001182 sendMessage(ENABLE, 1, null);
Mike Lockwood62a8fc12010-03-22 14:23:26 -04001183 }
1184
Tsuwei Chen52617bb2014-08-25 11:49:11 -07001185 private void setSuplHostPort(String hostString, String portString) {
1186 if (hostString != null) {
1187 mSuplServerHost = hostString;
1188 }
1189 if (portString != null) {
1190 try {
1191 mSuplServerPort = Integer.parseInt(portString);
1192 } catch (NumberFormatException e) {
1193 Log.e(TAG, "unable to parse SUPL_PORT: " + portString);
1194 }
1195 }
Tsuwei Chen678c13c2014-09-22 17:48:41 -07001196 if (mSuplServerHost != null
1197 && mSuplServerPort > TCP_MIN_PORT
1198 && mSuplServerPort <= TCP_MAX_PORT) {
1199 native_set_agps_server(AGPS_TYPE_SUPL, mSuplServerHost, mSuplServerPort);
1200 }
Tsuwei Chen52617bb2014-08-25 11:49:11 -07001201 }
1202
Tsuwei Chen462bcd82014-09-17 12:28:49 -07001203 /**
1204 * Checks what SUPL mode to use, according to the AGPS mode as well as the
1205 * allowed mode from properties.
1206 *
gomo48f1a642017-11-10 20:35:46 -08001207 * @param properties GPS properties
Tsuwei Chen462bcd82014-09-17 12:28:49 -07001208 * @param agpsEnabled whether AGPS is enabled by settings value
gomo48f1a642017-11-10 20:35:46 -08001209 * @param singleShot whether "singleshot" is needed
Tsuwei Chen462bcd82014-09-17 12:28:49 -07001210 * @return SUPL mode (MSA vs MSB vs STANDALONE)
1211 */
1212 private int getSuplMode(Properties properties, boolean agpsEnabled, boolean singleShot) {
1213 if (agpsEnabled) {
1214 String modeString = properties.getProperty("SUPL_MODE");
1215 int suplMode = 0;
1216 if (!TextUtils.isEmpty(modeString)) {
1217 try {
1218 suplMode = Integer.parseInt(modeString);
1219 } catch (NumberFormatException e) {
1220 Log.e(TAG, "unable to parse SUPL_MODE: " + modeString);
1221 return GPS_POSITION_MODE_STANDALONE;
1222 }
1223 }
destradaabfb3bdb2015-04-29 14:42:35 -07001224 // MS-Based is the preferred mode for Assisted-GPS position computation, so we favor
1225 // such mode when it is available
1226 if (hasCapability(GPS_CAPABILITY_MSB) && (suplMode & AGPS_SUPL_MODE_MSB) != 0) {
1227 return GPS_POSITION_MODE_MS_BASED;
1228 }
1229 // for now, just as the legacy code did, we fallback to MS-Assisted if it is available,
1230 // do fallback only for single-shot requests, because it is too expensive to do for
1231 // periodic requests as well
Tsuwei Chen462bcd82014-09-17 12:28:49 -07001232 if (singleShot
1233 && hasCapability(GPS_CAPABILITY_MSA)
1234 && (suplMode & AGPS_SUPL_MODE_MSA) != 0) {
1235 return GPS_POSITION_MODE_MS_ASSISTED;
Tsuwei Chen462bcd82014-09-17 12:28:49 -07001236 }
1237 }
1238 return GPS_POSITION_MODE_STANDALONE;
1239 }
1240
Mike Lockwood62a8fc12010-03-22 14:23:26 -04001241 private void handleEnable() {
1242 if (DEBUG) Log.d(TAG, "handleEnable");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001243
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001244 boolean enabled = native_init();
1245
1246 if (enabled) {
Mike Lockwood1a1cd3a2010-08-17 07:42:54 -04001247 mSupportsXtra = native_supports_xtra();
Tsuwei Chen678c13c2014-09-22 17:48:41 -07001248
1249 // TODO: remove the following native calls if we can make sure they are redundant.
Mike Lockwood734d6032009-07-28 18:30:25 -07001250 if (mSuplServerHost != null) {
1251 native_set_agps_server(AGPS_TYPE_SUPL, mSuplServerHost, mSuplServerPort);
1252 }
1253 if (mC2KServerHost != null) {
1254 native_set_agps_server(AGPS_TYPE_C2K, mC2KServerHost, mC2KServerPort);
1255 }
destradaa13a60b02015-01-15 18:36:01 -08001256
Lifu Tang818aa2c2016-02-01 01:52:00 -08001257 mGnssMeasurementsProvider.onGpsEnabledChanged();
1258 mGnssNavigationMessageProvider.onGpsEnabledChanged();
Wyatt Rileycf879db2017-01-12 13:57:38 -08001259 enableBatching();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001260 } else {
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001261 synchronized (mLock) {
1262 mEnabled = false;
1263 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001264 Log.w(TAG, "Failed to enable location provider");
1265 }
1266 }
1267
1268 /**
1269 * Disables this provider. When disabled, calls to getStatus()
Mike Lockwood4e50b782009-04-03 08:24:43 -07001270 * need not be handled. Hardware may be shut
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001271 * down while the provider is disabled.
1272 */
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001273 @Override
Mike Lockwood62a8fc12010-03-22 14:23:26 -04001274 public void disable() {
Laurent Tu7b5aeca2013-01-24 15:10:24 -08001275 synchronized (mLock) {
1276 if (!mEnabled) return;
1277 mEnabled = false;
1278 }
1279
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001280 sendMessage(ENABLE, 0, null);
Mike Lockwood62a8fc12010-03-22 14:23:26 -04001281 }
1282
1283 private void handleDisable() {
Mike Lockwood89096312010-03-24 10:14:55 -04001284 if (DEBUG) Log.d(TAG, "handleDisable");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001285
David Christie3bc26142013-12-19 14:53:44 -08001286 updateClientUids(new WorkSource());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001287 stopNavigating();
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001288 mAlarmManager.cancel(mWakeupIntent);
1289 mAlarmManager.cancel(mTimeoutIntent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001290
Wyatt Rileycf879db2017-01-12 13:57:38 -08001291 disableBatching();
Mike Lockwoodcf1d8cb2010-01-20 10:14:54 -05001292 // do this before releasing wakelock
1293 native_cleanup();
destradaa13a60b02015-01-15 18:36:01 -08001294
Lifu Tang818aa2c2016-02-01 01:52:00 -08001295 mGnssMeasurementsProvider.onGpsEnabledChanged();
1296 mGnssNavigationMessageProvider.onGpsEnabledChanged();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001297 }
1298
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001299 @Override
Mike Lockwoodd03ff942010-02-09 08:46:14 -05001300 public boolean isEnabled() {
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001301 synchronized (mLock) {
1302 return mEnabled;
1303 }
Mike Lockwoodd03ff942010-02-09 08:46:14 -05001304 }
1305
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001306 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001307 public int getStatus(Bundle extras) {
Wyatt Rileyc7067412018-02-07 15:50:35 -08001308 mLocationExtras.setBundle(extras);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001309 return mStatus;
1310 }
1311
Wyatt Rileyc7067412018-02-07 15:50:35 -08001312 private void updateStatus(int status) {
1313 if (status != mStatus) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001314 mStatus = status;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001315 mStatusUpdateTime = SystemClock.elapsedRealtime();
1316 }
1317 }
1318
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001319 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001320 public long getStatusUpdateTime() {
1321 return mStatusUpdateTime;
1322 }
1323
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001324 @Override
1325 public void setRequest(ProviderRequest request, WorkSource source) {
1326 sendMessage(SET_REQUEST, 0, new GpsRequest(request, source));
Mike Lockwood62a8fc12010-03-22 14:23:26 -04001327 }
1328
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001329 private void handleSetRequest(ProviderRequest request, WorkSource source) {
David Christied4edf4c2014-08-12 15:22:27 -07001330 mProviderRequest = request;
1331 mWorkSource = source;
1332 updateRequirements();
1333 }
1334
1335 // Called when the requirements for GPS may have changed
1336 private void updateRequirements() {
1337 if (mProviderRequest == null || mWorkSource == null) {
1338 return;
1339 }
1340
Stan Chesnutt1d72d8c2013-04-15 19:18:02 -07001341 boolean singleShot = false;
1342
1343 // see if the request is for a single update
David Christied4edf4c2014-08-12 15:22:27 -07001344 if (mProviderRequest.locationRequests != null
1345 && mProviderRequest.locationRequests.size() > 0) {
Stan Chesnutt1d72d8c2013-04-15 19:18:02 -07001346 // if any request has zero or more than one updates
1347 // requested, then this is not single-shot mode
1348 singleShot = true;
1349
David Christied4edf4c2014-08-12 15:22:27 -07001350 for (LocationRequest lr : mProviderRequest.locationRequests) {
Stan Chesnutt1d72d8c2013-04-15 19:18:02 -07001351 if (lr.getNumUpdates() != 1) {
1352 singleShot = false;
1353 }
1354 }
1355 }
1356
David Christied4edf4c2014-08-12 15:22:27 -07001357 if (DEBUG) Log.d(TAG, "setRequest " + mProviderRequest);
Dante Russo260d6672016-06-20 11:11:59 -07001358 if (mProviderRequest.reportLocation && !mDisableGps && isEnabled()) {
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001359 // update client uids
David Christied4edf4c2014-08-12 15:22:27 -07001360 updateClientUids(mWorkSource);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001361
David Christied4edf4c2014-08-12 15:22:27 -07001362 mFixInterval = (int) mProviderRequest.interval;
gomo48f1a642017-11-10 20:35:46 -08001363 mLowPowerMode = (boolean) mProviderRequest.lowPowerMode;
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001364 // check for overflow
David Christied4edf4c2014-08-12 15:22:27 -07001365 if (mFixInterval != mProviderRequest.interval) {
1366 Log.w(TAG, "interval overflow: " + mProviderRequest.interval);
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001367 mFixInterval = Integer.MAX_VALUE;
1368 }
Mike Lockwood03ca2162010-04-01 08:10:09 -07001369
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001370 // apply request to GPS engine
Mike Lockwood04598b62010-04-14 17:17:24 -04001371 if (mStarted && hasCapability(GPS_CAPABILITY_SCHEDULING)) {
gomo48f1a642017-11-10 20:35:46 -08001372 // change period and/or lowPowerMode
Mike Lockwood04598b62010-04-14 17:17:24 -04001373 if (!native_set_position_mode(mPositionMode, GPS_POSITION_RECURRENCE_PERIODIC,
gomo48f1a642017-11-10 20:35:46 -08001374 mFixInterval, 0, 0, mLowPowerMode)) {
1375 Log.e(TAG, "set_position_mode failed in updateRequirements");
Mike Lockwood04598b62010-04-14 17:17:24 -04001376 }
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001377 } else if (!mStarted) {
1378 // start GPS
Stan Chesnutt1d72d8c2013-04-15 19:18:02 -07001379 startNavigating(singleShot);
gomo300b2402017-12-13 19:04:12 -08001380 } else {
1381 // GNSS Engine is already ON, but no GPS_CAPABILITY_SCHEDULING
1382 mAlarmManager.cancel(mTimeoutIntent);
1383 if (mFixInterval >= NO_FIX_TIMEOUT) {
1384 // set timer to give up if we do not receive a fix within NO_FIX_TIMEOUT
1385 // and our fix interval is not short
1386 mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
1387 SystemClock.elapsedRealtime() + NO_FIX_TIMEOUT, mTimeoutIntent); }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001388 }
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001389 } else {
Dianne Hackborn002a54e2013-01-10 17:34:55 -08001390 updateClientUids(new WorkSource());
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001391
1392 stopNavigating();
1393 mAlarmManager.cancel(mWakeupIntent);
1394 mAlarmManager.cancel(mTimeoutIntent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001395 }
1396 }
1397
Dianne Hackborn002a54e2013-01-10 17:34:55 -08001398 private void updateClientUids(WorkSource source) {
Narayan Kamath32684dd2018-01-08 17:32:51 +00001399 if (source.equals(mClientSource)) {
Victoria Leaseea78b852013-01-15 10:39:28 -08001400 return;
1401 }
Dianne Hackborn002a54e2013-01-10 17:34:55 -08001402
Narayan Kamath32684dd2018-01-08 17:32:51 +00001403 // (1) Inform BatteryStats that the list of IDs we're tracking changed.
1404 try {
1405 mBatteryStats.noteGpsChanged(mClientSource, source);
1406 } catch (RemoteException e) {
1407 Log.w(TAG, "RemoteException", e);
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001408 }
1409
Narayan Kamath32684dd2018-01-08 17:32:51 +00001410 // (2) Inform AppOps service about the list of changes to UIDs.
1411
1412 List<WorkChain>[] diffs = WorkSource.diffChains(mClientSource, source);
1413 if (diffs != null) {
1414 List<WorkChain> newChains = diffs[0];
1415 List<WorkChain> goneChains = diffs[1];
1416
1417 if (newChains != null) {
1418 for (int i = 0; i < newChains.size(); ++i) {
1419 final WorkChain newChain = newChains.get(i);
Svet Ganovf7b47252018-02-26 11:11:27 -08001420 mAppOps.startOpNoThrow(AppOpsManager.OP_GPS, newChain.getAttributionUid(),
1421 newChain.getAttributionTag());
Narayan Kamath32684dd2018-01-08 17:32:51 +00001422 }
1423 }
1424
1425 if (goneChains != null) {
1426 for (int i = 0; i < goneChains.size(); i++) {
1427 final WorkChain goneChain = goneChains.get(i);
Svet Ganovf7b47252018-02-26 11:11:27 -08001428 mAppOps.finishOp(AppOpsManager.OP_GPS, goneChain.getAttributionUid(),
1429 goneChain.getAttributionTag());
Narayan Kamath32684dd2018-01-08 17:32:51 +00001430 }
1431 }
1432
1433 mClientSource.transferWorkChains(source);
1434 }
1435
1436 // Update the flat UIDs and names list and inform app-ops of all changes.
1437 WorkSource[] changes = mClientSource.setReturningDiffs(source);
1438 if (changes != null) {
1439 WorkSource newWork = changes[0];
1440 WorkSource goneWork = changes[1];
1441
1442 // Update sources that were not previously tracked.
1443 if (newWork != null) {
1444 for (int i = 0; i < newWork.size(); i++) {
Svet Ganovf7b47252018-02-26 11:11:27 -08001445 mAppOps.startOpNoThrow(AppOpsManager.OP_GPS,
1446 newWork.get(i), newWork.getName(i));
Narayan Kamath32684dd2018-01-08 17:32:51 +00001447 }
1448 }
1449
1450 // Update sources that are no longer tracked.
1451 if (goneWork != null) {
1452 for (int i = 0; i < goneWork.size(); i++) {
Svet Ganovf7b47252018-02-26 11:11:27 -08001453 mAppOps.finishOp(AppOpsManager.OP_GPS, goneWork.get(i), goneWork.getName(i));
Dianne Hackborn2e418422009-06-22 20:00:17 -07001454 }
Mike Lockwood2f82c4e2009-04-17 08:24:10 -04001455 }
1456 }
1457 }
1458
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001459 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001460 public boolean sendExtraCommand(String command, Bundle extras) {
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001461
Mike Lockwood63aa5a62010-04-14 19:21:31 -04001462 long identity = Binder.clearCallingIdentity();
Peter Visontayb25db362017-11-01 18:18:12 +00001463 try {
1464 boolean result = false;
Mike Lockwood63aa5a62010-04-14 19:21:31 -04001465
Peter Visontayb25db362017-11-01 18:18:12 +00001466 if ("delete_aiding_data".equals(command)) {
1467 result = deleteAidingData(extras);
1468 } else if ("force_time_injection".equals(command)) {
1469 requestUtcTime();
Mike Lockwood63aa5a62010-04-14 19:21:31 -04001470 result = true;
Peter Visontayb25db362017-11-01 18:18:12 +00001471 } else if ("force_xtra_injection".equals(command)) {
1472 if (mSupportsXtra) {
1473 xtraDownloadRequest();
1474 result = true;
1475 }
1476 } else {
1477 Log.w(TAG, "sendExtraCommand: unknown command " + command);
Mike Lockwood93bc44d2009-05-20 16:58:22 -04001478 }
Peter Visontayb25db362017-11-01 18:18:12 +00001479 return result;
1480 } finally {
1481 Binder.restoreCallingIdentity(identity);
Mike Lockwood93bc44d2009-05-20 16:58:22 -04001482 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001483 }
1484
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07001485 private IGpsGeofenceHardware mGpsGeofenceBinder = new IGpsGeofenceHardware.Stub() {
1486 public boolean isHardwareGeofenceSupported() {
1487 return native_is_geofence_supported();
1488 }
1489
1490 public boolean addCircularHardwareGeofence(int geofenceId, double latitude,
1491 double longitude, double radius, int lastTransition, int monitorTransitions,
1492 int notificationResponsiveness, int unknownTimer) {
1493 return native_add_geofence(geofenceId, latitude, longitude, radius,
1494 lastTransition, monitorTransitions, notificationResponsiveness, unknownTimer);
1495 }
1496
1497 public boolean removeHardwareGeofence(int geofenceId) {
1498 return native_remove_geofence(geofenceId);
1499 }
1500
1501 public boolean pauseHardwareGeofence(int geofenceId) {
1502 return native_pause_geofence(geofenceId);
1503 }
1504
1505 public boolean resumeHardwareGeofence(int geofenceId, int monitorTransition) {
1506 return native_resume_geofence(geofenceId, monitorTransition);
1507 }
1508 };
1509
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001510 private boolean deleteAidingData(Bundle extras) {
1511 int flags;
1512
1513 if (extras == null) {
1514 flags = GPS_DELETE_ALL;
1515 } else {
1516 flags = 0;
1517 if (extras.getBoolean("ephemeris")) flags |= GPS_DELETE_EPHEMERIS;
1518 if (extras.getBoolean("almanac")) flags |= GPS_DELETE_ALMANAC;
1519 if (extras.getBoolean("position")) flags |= GPS_DELETE_POSITION;
1520 if (extras.getBoolean("time")) flags |= GPS_DELETE_TIME;
1521 if (extras.getBoolean("iono")) flags |= GPS_DELETE_IONO;
1522 if (extras.getBoolean("utc")) flags |= GPS_DELETE_UTC;
1523 if (extras.getBoolean("health")) flags |= GPS_DELETE_HEALTH;
1524 if (extras.getBoolean("svdir")) flags |= GPS_DELETE_SVDIR;
1525 if (extras.getBoolean("svsteer")) flags |= GPS_DELETE_SVSTEER;
1526 if (extras.getBoolean("sadata")) flags |= GPS_DELETE_SADATA;
1527 if (extras.getBoolean("rti")) flags |= GPS_DELETE_RTI;
1528 if (extras.getBoolean("celldb-info")) flags |= GPS_DELETE_CELLDB_INFO;
1529 if (extras.getBoolean("all")) flags |= GPS_DELETE_ALL;
1530 }
1531
1532 if (flags != 0) {
1533 native_delete_aiding_data(flags);
1534 return true;
1535 }
1536
1537 return false;
1538 }
1539
Stan Chesnutt1d72d8c2013-04-15 19:18:02 -07001540 private void startNavigating(boolean singleShot) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001541 if (!mStarted) {
Stan Chesnutt1d72d8c2013-04-15 19:18:02 -07001542 if (DEBUG) Log.d(TAG, "startNavigating, singleShot is " + singleShot);
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001543 mTimeToFirstFix = 0;
1544 mLastFixTime = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001545 mStarted = true;
Stan Chesnutt1d72d8c2013-04-15 19:18:02 -07001546 mSingleShot = singleShot;
Mike Lockwood03ca2162010-04-01 08:10:09 -07001547 mPositionMode = GPS_POSITION_MODE_STANDALONE;
Wyatt Riley5d5bac82016-11-01 07:05:16 -07001548 // Notify about suppressed output, if speed limit was previously exceeded.
1549 // Elsewhere, we check again with every speed output reported.
1550 if (mItarSpeedLimitExceeded) {
1551 Log.i(TAG, "startNavigating with ITAR limit in place. Output limited " +
1552 "until slow enough speed reported.");
1553 }
Mike Lockwood03ca2162010-04-01 08:10:09 -07001554
Tsuwei Chen462bcd82014-09-17 12:28:49 -07001555 boolean agpsEnabled =
1556 (Settings.Global.getInt(mContext.getContentResolver(),
gomo48f1a642017-11-10 20:35:46 -08001557 Settings.Global.ASSISTED_GPS_ENABLED, 1) != 0);
Tsuwei Chen462bcd82014-09-17 12:28:49 -07001558 mPositionMode = getSuplMode(mProperties, agpsEnabled, singleShot);
Mike Lockwoodbcab8df2009-06-25 16:39:09 -04001559
Stan Chesnutt1d72d8c2013-04-15 19:18:02 -07001560 if (DEBUG) {
1561 String mode;
1562
gomo48f1a642017-11-10 20:35:46 -08001563 switch (mPositionMode) {
Stan Chesnutt1d72d8c2013-04-15 19:18:02 -07001564 case GPS_POSITION_MODE_STANDALONE:
1565 mode = "standalone";
1566 break;
1567 case GPS_POSITION_MODE_MS_ASSISTED:
1568 mode = "MS_ASSISTED";
1569 break;
1570 case GPS_POSITION_MODE_MS_BASED:
1571 mode = "MS_BASED";
1572 break;
1573 default:
1574 mode = "unknown";
1575 break;
1576 }
1577 Log.d(TAG, "setting position_mode to " + mode);
1578 }
1579
Mike Lockwood04598b62010-04-14 17:17:24 -04001580 int interval = (hasCapability(GPS_CAPABILITY_SCHEDULING) ? mFixInterval : 1000);
gomo48f1a642017-11-10 20:35:46 -08001581 mLowPowerMode = (boolean) mProviderRequest.lowPowerMode;
Mike Lockwood04598b62010-04-14 17:17:24 -04001582 if (!native_set_position_mode(mPositionMode, GPS_POSITION_RECURRENCE_PERIODIC,
gomo48f1a642017-11-10 20:35:46 -08001583 interval, 0, 0, mLowPowerMode)) {
Mike Lockwood04598b62010-04-14 17:17:24 -04001584 mStarted = false;
1585 Log.e(TAG, "set_position_mode failed in startNavigating()");
1586 return;
1587 }
1588 if (!native_start()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001589 mStarted = false;
1590 Log.e(TAG, "native_start failed in startNavigating()");
Mike Lockwood0632ca72009-05-14 15:51:03 -04001591 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001592 }
1593
1594 // reset SV count to zero
Wyatt Rileyc7067412018-02-07 15:50:35 -08001595 updateStatus(LocationProvider.TEMPORARILY_UNAVAILABLE);
1596 mLocationExtras.reset();
Yipeng Cao282b5942017-05-17 20:31:39 -07001597 mFixRequestTime = SystemClock.elapsedRealtime();
Mike Lockwood04598b62010-04-14 17:17:24 -04001598 if (!hasCapability(GPS_CAPABILITY_SCHEDULING)) {
1599 // set timer to give up if we do not receive a fix within NO_FIX_TIMEOUT
1600 // and our fix interval is not short
1601 if (mFixInterval >= NO_FIX_TIMEOUT) {
1602 mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
1603 SystemClock.elapsedRealtime() + NO_FIX_TIMEOUT, mTimeoutIntent);
1604 }
Mike Lockwood0632ca72009-05-14 15:51:03 -04001605 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001606 }
1607 }
1608
Mike Lockwood62a8fc12010-03-22 14:23:26 -04001609 private void stopNavigating() {
Mike Lockwood29c84342009-05-06 14:01:15 -04001610 if (DEBUG) Log.d(TAG, "stopNavigating");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001611 if (mStarted) {
1612 mStarted = false;
Stan Chesnutt1d72d8c2013-04-15 19:18:02 -07001613 mSingleShot = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001614 native_stop();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001615 mLastFixTime = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001616
1617 // reset SV count to zero
Wyatt Rileyc7067412018-02-07 15:50:35 -08001618 updateStatus(LocationProvider.TEMPORARILY_UNAVAILABLE);
1619 mLocationExtras.reset();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001620 }
1621 }
1622
Mike Lockwood0632ca72009-05-14 15:51:03 -04001623 private void hibernate() {
1624 // stop GPS until our next fix interval arrives
1625 stopNavigating();
Mike Lockwood0632ca72009-05-14 15:51:03 -04001626 mAlarmManager.cancel(mTimeoutIntent);
1627 mAlarmManager.cancel(mWakeupIntent);
1628 long now = SystemClock.elapsedRealtime();
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001629 mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, now + mFixInterval, mWakeupIntent);
Mike Lockwood04598b62010-04-14 17:17:24 -04001630 }
1631
1632 private boolean hasCapability(int capability) {
1633 return ((mEngineCapabilities & capability) != 0);
Mike Lockwood0632ca72009-05-14 15:51:03 -04001634 }
1635
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07001636
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001637 /**
1638 * called from native code to update our position.
1639 */
Wyatt Riley5d229832017-02-10 17:06:00 -08001640 private void reportLocation(boolean hasLatLong, Location location) {
Wyatt Riley26465d22018-02-12 13:44:24 -08001641 sendMessage(REPORT_LOCATION, hasLatLong ? 1 : 0, location);
1642 }
1643
1644 private void handleReportLocation(boolean hasLatLong, Location location) {
Wyatt Riley5d229832017-02-10 17:06:00 -08001645 if (location.hasSpeed()) {
1646 mItarSpeedLimitExceeded = location.getSpeed() > ITAR_SPEED_LIMIT_METERS_PER_SECOND;
Wyatt Riley5d5bac82016-11-01 07:05:16 -07001647 }
1648
1649 if (mItarSpeedLimitExceeded) {
1650 Log.i(TAG, "Hal reported a speed in excess of ITAR limit." +
1651 " GPS/GNSS Navigation output blocked.");
Siddharth Ray53ddc802018-03-16 12:01:52 -07001652 if (mStarted) {
1653 mGnssMetrics.logReceivedLocationStatus(false);
1654 }
Wyatt Riley5d5bac82016-11-01 07:05:16 -07001655 return; // No output of location allowed
1656 }
1657
Wyatt Riley5d229832017-02-10 17:06:00 -08001658 if (VERBOSE) Log.v(TAG, "reportLocation " + location.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001659
Wyatt Riley26465d22018-02-12 13:44:24 -08001660 // It would be nice to push the elapsed real-time timestamp
1661 // further down the stack, but this is still useful
1662 location.setElapsedRealtimeNanos(SystemClock.elapsedRealtimeNanos());
1663 location.setExtras(mLocationExtras.getBundle());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001664
Wyatt Riley26465d22018-02-12 13:44:24 -08001665 try {
1666 mILocationManager.reportLocation(location, false);
1667 } catch (RemoteException e) {
1668 Log.e(TAG, "RemoteException calling reportLocation");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001669 }
1670
Siddharth Ray53ddc802018-03-16 12:01:52 -07001671 if (mStarted) {
1672 mGnssMetrics.logReceivedLocationStatus(hasLatLong);
1673 if (hasLatLong) {
1674 if (location.hasAccuracy()) {
1675 mGnssMetrics.logPositionAccuracyMeters(location.getAccuracy());
1676 }
1677 if (mTimeToFirstFix > 0) {
1678 int timeBetweenFixes = (int) (SystemClock.elapsedRealtime() - mLastFixTime);
1679 mGnssMetrics.logMissedReports(mFixInterval, timeBetweenFixes);
1680 }
Siddharth Raybb608c82017-03-16 11:33:34 -07001681 }
1682 }
1683
Yipeng Cao282b5942017-05-17 20:31:39 -07001684 mLastFixTime = SystemClock.elapsedRealtime();
Hakan Gustavssonfa94ff02010-02-23 09:12:38 +01001685 // report time to first fix
Wyatt Riley5d229832017-02-10 17:06:00 -08001686 if (mTimeToFirstFix == 0 && hasLatLong) {
gomo48f1a642017-11-10 20:35:46 -08001687 mTimeToFirstFix = (int) (mLastFixTime - mFixRequestTime);
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001688 if (DEBUG) Log.d(TAG, "TTFF: " + mTimeToFirstFix);
Siddharth Ray53ddc802018-03-16 12:01:52 -07001689 if (mStarted) {
1690 mGnssMetrics.logTimeToFirstFixMilliSecs(mTimeToFirstFix);
1691 }
Hakan Gustavssonfa94ff02010-02-23 09:12:38 +01001692
1693 // notify status listeners
destradaaea8a8a62014-06-23 18:19:03 -07001694 mListenerHelper.onFirstFix(mTimeToFirstFix);
Hakan Gustavssonfa94ff02010-02-23 09:12:38 +01001695 }
1696
Stan Chesnutt1d72d8c2013-04-15 19:18:02 -07001697 if (mSingleShot) {
1698 stopNavigating();
1699 }
1700
Mike Lockwood15e3d0f2009-05-01 07:53:28 -04001701 if (mStarted && mStatus != LocationProvider.AVAILABLE) {
Wyatt Rileyc7067412018-02-07 15:50:35 -08001702 // For devices that use framework scheduling, a timer may be set to ensure we don't
1703 // spend too much power searching for a location, when the requested update rate is slow.
1704 // As we just recievied a location, we'll cancel that timer.
Mike Lockwood04598b62010-04-14 17:17:24 -04001705 if (!hasCapability(GPS_CAPABILITY_SCHEDULING) && mFixInterval < NO_FIX_TIMEOUT) {
Mike Lockwoodb7be5442010-02-24 14:34:50 -05001706 mAlarmManager.cancel(mTimeoutIntent);
1707 }
1708
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001709 // send an intent to notify that the GPS is receiving fixes.
Mike Lockwood00b74272010-03-26 10:41:48 -04001710 Intent intent = new Intent(LocationManager.GPS_FIX_CHANGE_ACTION);
1711 intent.putExtra(LocationManager.EXTRA_GPS_ENABLED, true);
Dianne Hackborn5ac72a22012-08-29 18:32:08 -07001712 mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
Wyatt Rileyc7067412018-02-07 15:50:35 -08001713 updateStatus(LocationProvider.AVAILABLE);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001714 }
Mike Lockwood29c84342009-05-06 14:01:15 -04001715
gomo48f1a642017-11-10 20:35:46 -08001716 if (!hasCapability(GPS_CAPABILITY_SCHEDULING) && mStarted &&
1717 mFixInterval > GPS_POLLING_THRESHOLD_INTERVAL) {
Mike Lockwoodd53ba012010-04-15 20:41:26 -04001718 if (DEBUG) Log.d(TAG, "got fix, hibernating");
Mike Lockwood0632ca72009-05-14 15:51:03 -04001719 hibernate();
Mike Lockwood29c84342009-05-06 14:01:15 -04001720 }
gomo48f1a642017-11-10 20:35:46 -08001721 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001722
1723 /**
1724 * called from native code to update our status
1725 */
1726 private void reportStatus(int status) {
Mike Lockwoodb8d90332010-10-18 17:59:48 -04001727 if (DEBUG) Log.v(TAG, "reportStatus status: " + status);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001728
destradaaea8a8a62014-06-23 18:19:03 -07001729 boolean wasNavigating = mNavigating;
1730 switch (status) {
1731 case GPS_STATUS_SESSION_BEGIN:
1732 mNavigating = true;
1733 mEngineOn = true;
1734 break;
1735 case GPS_STATUS_SESSION_END:
1736 mNavigating = false;
1737 break;
1738 case GPS_STATUS_ENGINE_ON:
1739 mEngineOn = true;
1740 break;
1741 case GPS_STATUS_ENGINE_OFF:
1742 mEngineOn = false;
1743 mNavigating = false;
1744 break;
1745 }
Mike Lockwooddbd6fd82009-12-07 18:43:36 -05001746
destradaaea8a8a62014-06-23 18:19:03 -07001747 if (wasNavigating != mNavigating) {
destradaa13a60b02015-01-15 18:36:01 -08001748 mListenerHelper.onStatusChanged(mNavigating);
Mike Lockwoodcf1d8cb2010-01-20 10:14:54 -05001749
destradaaea8a8a62014-06-23 18:19:03 -07001750 // send an intent to notify that the GPS has been enabled or disabled
1751 Intent intent = new Intent(LocationManager.GPS_ENABLED_CHANGE_ACTION);
1752 intent.putExtra(LocationManager.EXTRA_GPS_ENABLED, mNavigating);
1753 mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001754 }
1755 }
1756
Wyatt Riley26465d22018-02-12 13:44:24 -08001757 // Helper class to carry data to handler for reportSvStatus
1758 private static class SvStatusInfo {
1759 public int mSvCount;
1760 public int[] mSvidWithFlags;
1761 public float[] mCn0s;
1762 public float[] mSvElevations;
1763 public float[] mSvAzimuths;
1764 public float[] mSvCarrierFreqs;
1765 }
1766
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001767 /**
1768 * called from native code to update SV info
1769 */
Wyatt Riley26465d22018-02-12 13:44:24 -08001770 private void reportSvStatus(int svCount, int[] svidWithFlags, float[] cn0s,
1771 float[] svElevations, float[] svAzimuths, float[] svCarrierFreqs) {
1772 SvStatusInfo svStatusInfo = new SvStatusInfo();
1773 svStatusInfo.mSvCount = svCount;
1774 svStatusInfo.mSvidWithFlags = svidWithFlags;
1775 svStatusInfo.mCn0s = cn0s;
1776 svStatusInfo.mSvElevations = svElevations;
1777 svStatusInfo.mSvAzimuths = svAzimuths;
1778 svStatusInfo.mSvCarrierFreqs = svCarrierFreqs;
1779
1780 sendMessage(REPORT_SV_STATUS, 0, svStatusInfo);
1781 }
1782
1783 private void handleReportSvStatus(SvStatusInfo info) {
destradaaea8a8a62014-06-23 18:19:03 -07001784 mListenerHelper.onSvStatusChanged(
Wyatt Riley26465d22018-02-12 13:44:24 -08001785 info.mSvCount,
1786 info.mSvidWithFlags,
1787 info.mCn0s,
1788 info.mSvElevations,
1789 info.mSvAzimuths,
1790 info.mSvCarrierFreqs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001791
Siddharth Ray168f12a2017-07-10 11:55:10 -07001792 // Log CN0 as part of GNSS metrics
Wyatt Riley26465d22018-02-12 13:44:24 -08001793 mGnssMetrics.logCn0(info.mCn0s, info.mSvCount);
Siddharth Ray168f12a2017-07-10 11:55:10 -07001794
Mike Lockwood29c84342009-05-06 14:01:15 -04001795 if (VERBOSE) {
Wyatt Riley26465d22018-02-12 13:44:24 -08001796 Log.v(TAG, "SV count: " + info.mSvCount);
Lifu Tang30f95a72016-01-07 23:20:38 -08001797 }
Wyatt Rileyc9f25dd2017-05-05 13:45:23 -07001798 // Calculate number of satellites used in fix.
Lifu Tang30f95a72016-01-07 23:20:38 -08001799 int usedInFixCount = 0;
Wyatt Rileyc9f25dd2017-05-05 13:45:23 -07001800 int maxCn0 = 0;
1801 int meanCn0 = 0;
Wyatt Riley26465d22018-02-12 13:44:24 -08001802 for (int i = 0; i < info.mSvCount; i++) {
1803 if ((info.mSvidWithFlags[i] & GnssStatus.GNSS_SV_FLAGS_USED_IN_FIX) != 0) {
Lifu Tang30f95a72016-01-07 23:20:38 -08001804 ++usedInFixCount;
Wyatt Riley26465d22018-02-12 13:44:24 -08001805 if (info.mCn0s[i] > maxCn0) {
1806 maxCn0 = (int) info.mCn0s[i];
Wyatt Rileyc9f25dd2017-05-05 13:45:23 -07001807 }
Wyatt Riley26465d22018-02-12 13:44:24 -08001808 meanCn0 += info.mCn0s[i];
Lifu Tang30f95a72016-01-07 23:20:38 -08001809 }
1810 if (VERBOSE) {
Wyatt Riley26465d22018-02-12 13:44:24 -08001811 Log.v(TAG, "svid: " + (info.mSvidWithFlags[i] >> GnssStatus.SVID_SHIFT_WIDTH) +
1812 " cn0: " + info.mCn0s[i] +
1813 " elev: " + info.mSvElevations[i] +
1814 " azimuth: " + info.mSvAzimuths[i] +
1815 " carrier frequency: " + info.mSvCarrierFreqs[i] +
1816 ((info.mSvidWithFlags[i] & GnssStatus.GNSS_SV_FLAGS_HAS_EPHEMERIS_DATA) == 0
Lifu Tang30f95a72016-01-07 23:20:38 -08001817 ? " " : " E") +
Wyatt Riley26465d22018-02-12 13:44:24 -08001818 ((info.mSvidWithFlags[i] & GnssStatus.GNSS_SV_FLAGS_HAS_ALMANAC_DATA) == 0
Lifu Tang30f95a72016-01-07 23:20:38 -08001819 ? " " : " A") +
Wyatt Riley26465d22018-02-12 13:44:24 -08001820 ((info.mSvidWithFlags[i] & GnssStatus.GNSS_SV_FLAGS_USED_IN_FIX) == 0
gomo4402af62017-01-11 13:20:13 -08001821 ? "" : "U") +
Wyatt Riley26465d22018-02-12 13:44:24 -08001822 ((info.mSvidWithFlags[i] &
1823 GnssStatus.GNSS_SV_FLAGS_HAS_CARRIER_FREQUENCY) == 0
gomo48f1a642017-11-10 20:35:46 -08001824 ? "" : "F"));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001825 }
1826 }
Wyatt Rileyc9f25dd2017-05-05 13:45:23 -07001827 if (usedInFixCount > 0) {
1828 meanCn0 /= usedInFixCount;
1829 }
1830 // return number of sats used in fix instead of total reported
Wyatt Rileyc7067412018-02-07 15:50:35 -08001831 mLocationExtras.set(usedInFixCount, meanCn0, maxCn0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001832
Mike Lockwood15e3d0f2009-05-01 07:53:28 -04001833 if (mNavigating && mStatus == LocationProvider.AVAILABLE && mLastFixTime > 0 &&
gomo48f1a642017-11-10 20:35:46 -08001834 SystemClock.elapsedRealtime() - mLastFixTime > RECENT_FIX_TIMEOUT) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001835 // send an intent to notify that the GPS is no longer receiving fixes.
Mike Lockwood00b74272010-03-26 10:41:48 -04001836 Intent intent = new Intent(LocationManager.GPS_FIX_CHANGE_ACTION);
1837 intent.putExtra(LocationManager.EXTRA_GPS_ENABLED, false);
Dianne Hackborn5ac72a22012-08-29 18:32:08 -07001838 mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
Wyatt Rileyc7067412018-02-07 15:50:35 -08001839 updateStatus(LocationProvider.TEMPORARILY_UNAVAILABLE);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001840 }
1841 }
Mike Lockwood58bda982009-04-14 16:25:07 -04001842
1843 /**
Mike Lockwoode3635c92009-05-11 08:38:02 -04001844 * called from native code to update AGPS status
Mike Lockwood58bda982009-04-14 16:25:07 -04001845 */
destradaa96a14702014-06-05 11:36:30 -07001846 private void reportAGpsStatus(int type, int status, byte[] ipaddr) {
Mike Lockwood58bda982009-04-14 16:25:07 -04001847 switch (status) {
Mike Lockwoode3635c92009-05-11 08:38:02 -04001848 case GPS_REQUEST_AGPS_DATA_CONN:
Mike Lockwoodb6e5fa82010-10-09 20:10:46 -04001849 if (DEBUG) Log.d(TAG, "GPS_REQUEST_AGPS_DATA_CONN");
Andreas Gampee6748ce2015-12-11 18:00:38 -08001850 Log.v(TAG, "Received SUPL IP addr[]: " + Arrays.toString(ipaddr));
destradaae21252a2015-09-08 12:32:59 -07001851 InetAddress connectionIpAddress = null;
destradaa96a14702014-06-05 11:36:30 -07001852 if (ipaddr != null) {
1853 try {
destradaae21252a2015-09-08 12:32:59 -07001854 connectionIpAddress = InetAddress.getByAddress(ipaddr);
1855 if (DEBUG) Log.d(TAG, "IP address converted to: " + connectionIpAddress);
destradaa96a14702014-06-05 11:36:30 -07001856 } catch (UnknownHostException e) {
1857 Log.e(TAG, "Bad IP Address: " + ipaddr, e);
destradaa96a14702014-06-05 11:36:30 -07001858 }
1859 }
destradaae21252a2015-09-08 12:32:59 -07001860 sendMessage(REQUEST_SUPL_CONNECTION, 0 /*arg*/, connectionIpAddress);
Mike Lockwood58bda982009-04-14 16:25:07 -04001861 break;
Mike Lockwoode3635c92009-05-11 08:38:02 -04001862 case GPS_RELEASE_AGPS_DATA_CONN:
Mike Lockwoodb6e5fa82010-10-09 20:10:46 -04001863 if (DEBUG) Log.d(TAG, "GPS_RELEASE_AGPS_DATA_CONN");
destradaae21252a2015-09-08 12:32:59 -07001864 releaseSuplConnection(GPS_RELEASE_AGPS_DATA_CONN);
Mike Lockwood58bda982009-04-14 16:25:07 -04001865 break;
Mike Lockwoode3635c92009-05-11 08:38:02 -04001866 case GPS_AGPS_DATA_CONNECTED:
Mike Lockwoodb6e5fa82010-10-09 20:10:46 -04001867 if (DEBUG) Log.d(TAG, "GPS_AGPS_DATA_CONNECTED");
Mike Lockwood58bda982009-04-14 16:25:07 -04001868 break;
Mike Lockwoode3635c92009-05-11 08:38:02 -04001869 case GPS_AGPS_DATA_CONN_DONE:
Mike Lockwoodb6e5fa82010-10-09 20:10:46 -04001870 if (DEBUG) Log.d(TAG, "GPS_AGPS_DATA_CONN_DONE");
Mike Lockwood58bda982009-04-14 16:25:07 -04001871 break;
Mike Lockwoode3635c92009-05-11 08:38:02 -04001872 case GPS_AGPS_DATA_CONN_FAILED:
Mike Lockwoodb6e5fa82010-10-09 20:10:46 -04001873 if (DEBUG) Log.d(TAG, "GPS_AGPS_DATA_CONN_FAILED");
Mike Lockwood58bda982009-04-14 16:25:07 -04001874 break;
destradaa931a37f2014-08-12 16:36:59 -07001875 default:
Joe Onorato0c484102016-02-01 18:04:24 -08001876 if (DEBUG) Log.d(TAG, "Received Unknown AGPS status: " + status);
Mike Lockwood58bda982009-04-14 16:25:07 -04001877 }
1878 }
1879
destradaae21252a2015-09-08 12:32:59 -07001880 private void releaseSuplConnection(int connStatus) {
1881 sendMessage(RELEASE_SUPL_CONNECTION, connStatus, null /*obj*/);
1882 }
1883
Mike Lockwoodb16e7802009-08-06 09:26:02 -04001884 /**
1885 * called from native code to report NMEA data received
1886 */
Mike Lockwoodf602d362010-06-20 14:28:16 -07001887 private void reportNmea(long timestamp) {
Wyatt Riley5d5bac82016-11-01 07:05:16 -07001888 if (!mItarSpeedLimitExceeded) {
1889 int length = native_read_nmea(mNmeaBuffer, mNmeaBuffer.length);
1890 String nmea = new String(mNmeaBuffer, 0 /* offset */, length);
1891 mListenerHelper.onNmeaReceived(timestamp, nmea);
1892 }
destradaaea8a8a62014-06-23 18:19:03 -07001893 }
Mike Lockwoodb16e7802009-08-06 09:26:02 -04001894
destradaaea8a8a62014-06-23 18:19:03 -07001895 /**
Wyatt Rileyaa420d52017-07-03 15:14:42 -07001896 * called from native code - GNSS measurements callback
destradaaea8a8a62014-06-23 18:19:03 -07001897 */
Lifu Tang818aa2c2016-02-01 01:52:00 -08001898 private void reportMeasurementData(GnssMeasurementsEvent event) {
Wyatt Riley5d5bac82016-11-01 07:05:16 -07001899 if (!mItarSpeedLimitExceeded) {
Wyatt Rileyaa420d52017-07-03 15:14:42 -07001900 // send to handler to allow native to return quickly
1901 mHandler.post(new Runnable() {
1902 @Override
1903 public void run() {
1904 mGnssMeasurementsProvider.onMeasurementsAvailable(event);
1905 }
1906 });
Wyatt Riley5d5bac82016-11-01 07:05:16 -07001907 }
Mike Lockwoodb16e7802009-08-06 09:26:02 -04001908 }
1909
Mike Lockwood62a8fc12010-03-22 14:23:26 -04001910 /**
Wyatt Rileyaa420d52017-07-03 15:14:42 -07001911 * called from native code - GNSS navigation message callback
destradaa4b3e3932014-07-21 18:01:47 -07001912 */
Lifu Tange8abe8e2016-04-01 10:32:05 -07001913 private void reportNavigationMessage(GnssNavigationMessage event) {
Wyatt Riley5d5bac82016-11-01 07:05:16 -07001914 if (!mItarSpeedLimitExceeded) {
Wyatt Rileyaa420d52017-07-03 15:14:42 -07001915 // send to handler to allow native to return quickly
1916 mHandler.post(new Runnable() {
1917 @Override
1918 public void run() {
1919 mGnssNavigationMessageProvider.onNavigationMessageAvailable(event);
1920 }
1921 });
Wyatt Riley5d5bac82016-11-01 07:05:16 -07001922 }
destradaa4b3e3932014-07-21 18:01:47 -07001923 }
1924
1925 /**
Mike Lockwood04598b62010-04-14 17:17:24 -04001926 * called from native code to inform us what the GPS engine capabilities are
1927 */
Wyatt Rileyd87cf912017-12-05 09:31:52 -08001928 private void setEngineCapabilities(final int capabilities) {
1929 // send to handler thread for fast native return, and in-order handling
1930 mHandler.post(new Runnable() {
1931 @Override
1932 public void run() {
1933 mEngineCapabilities = capabilities;
Mike Lockwood9b9fb5c2011-06-29 15:09:40 -04001934
Wyatt Rileyd87cf912017-12-05 09:31:52 -08001935 if (hasCapability(GPS_CAPABILITY_ON_DEMAND_TIME)) {
Yu-Han Yanga1862b52018-02-20 17:05:59 -08001936 mNtpTimeHelper.enablePeriodicTimeInjection();
Wyatt Rileyd87cf912017-12-05 09:31:52 -08001937 requestUtcTime();
1938 }
destradaa6568d702014-10-27 12:47:41 -07001939
Wyatt Rileyd87cf912017-12-05 09:31:52 -08001940 mGnssMeasurementsProvider.onCapabilitiesUpdated(hasCapability(
1941 GPS_CAPABILITY_MEASUREMENTS));
1942 mGnssNavigationMessageProvider.onCapabilitiesUpdated(hasCapability(
1943 GPS_CAPABILITY_NAV_MESSAGES));
1944 }
1945 });
1946 }
1947
1948 /**
1949 * Called from native code to inform us the hardware year.
1950 */
1951 private void setGnssYearOfHardware(final int yearOfHardware) {
1952 // mHardwareYear is simply set here, to be read elsewhere, and is volatile for safe sync
1953 if (DEBUG) Log.d(TAG, "setGnssYearOfHardware called with " + yearOfHardware);
1954 mHardwareYear = yearOfHardware;
Mike Lockwood04598b62010-04-14 17:17:24 -04001955 }
1956
1957 /**
Wyatt Rileyd87cf912017-12-05 09:31:52 -08001958 * Called from native code to inform us the hardware model name.
Lifu Tang82f893d2016-01-21 18:15:33 -08001959 */
Wyatt Rileyd87cf912017-12-05 09:31:52 -08001960 private void setGnssHardwareModelName(final String modelName) {
1961 // mHardwareModelName is simply set here, to be read elsewhere, and volatile for safe sync
1962 if (DEBUG) Log.d(TAG, "setGnssModelName called with " + modelName);
1963 mHardwareModelName = modelName;
Lifu Tang82f893d2016-01-21 18:15:33 -08001964 }
1965
Lifu Tang9363b942016-02-16 18:07:00 -08001966 public interface GnssSystemInfoProvider {
Lifu Tang82f893d2016-01-21 18:15:33 -08001967 /**
Wyatt Rileyd87cf912017-12-05 09:31:52 -08001968 * Returns the year of underlying GPS hardware.
Lifu Tang82f893d2016-01-21 18:15:33 -08001969 */
Lifu Tang9363b942016-02-16 18:07:00 -08001970 int getGnssYearOfHardware();
Wyatt Rileyd87cf912017-12-05 09:31:52 -08001971 /**
1972 * Returns the model name of underlying GPS hardware.
1973 */
1974 String getGnssHardwareModelName();
Lifu Tang82f893d2016-01-21 18:15:33 -08001975 }
1976
1977 /**
1978 * @hide
1979 */
Lifu Tang9363b942016-02-16 18:07:00 -08001980 public GnssSystemInfoProvider getGnssSystemInfoProvider() {
1981 return new GnssSystemInfoProvider() {
Lifu Tang82f893d2016-01-21 18:15:33 -08001982 @Override
Lifu Tang9363b942016-02-16 18:07:00 -08001983 public int getGnssYearOfHardware() {
Wyatt Rileyd87cf912017-12-05 09:31:52 -08001984 return mHardwareYear;
1985 }
1986 @Override
1987 public String getGnssHardwareModelName() {
1988 return mHardwareModelName;
Lifu Tang82f893d2016-01-21 18:15:33 -08001989 }
1990 };
1991 }
1992
Wyatt Rileycf879db2017-01-12 13:57:38 -08001993 public interface GnssBatchingProvider {
1994 /**
1995 * Returns the GNSS batching size
1996 */
1997 int getSize();
gomo48f1a642017-11-10 20:35:46 -08001998
Wyatt Rileycf879db2017-01-12 13:57:38 -08001999 /**
2000 * Starts the hardware batching operation
2001 */
2002 boolean start(long periodNanos, boolean wakeOnFifoFull);
gomo48f1a642017-11-10 20:35:46 -08002003
Wyatt Rileycf879db2017-01-12 13:57:38 -08002004 /**
2005 * Forces a flush of existing locations from the hardware batching
2006 */
2007 void flush();
gomo48f1a642017-11-10 20:35:46 -08002008
Wyatt Rileycf879db2017-01-12 13:57:38 -08002009 /**
2010 * Stops the batching operation
2011 */
2012 boolean stop();
2013 }
2014
2015 /**
2016 * @hide
2017 */
2018 public GnssBatchingProvider getGnssBatchingProvider() {
2019 return new GnssBatchingProvider() {
2020 @Override
2021 public int getSize() {
2022 return native_get_batch_size();
2023 }
gomo48f1a642017-11-10 20:35:46 -08002024
Wyatt Rileycf879db2017-01-12 13:57:38 -08002025 @Override
2026 public boolean start(long periodNanos, boolean wakeOnFifoFull) {
2027 if (periodNanos <= 0) {
2028 Log.e(TAG, "Invalid periodNanos " + periodNanos +
2029 "in batching request, not started");
2030 return false;
2031 }
2032 return native_start_batch(periodNanos, wakeOnFifoFull);
2033 }
gomo48f1a642017-11-10 20:35:46 -08002034
Wyatt Rileycf879db2017-01-12 13:57:38 -08002035 @Override
2036 public void flush() {
2037 native_flush_batch();
2038 }
gomo48f1a642017-11-10 20:35:46 -08002039
Wyatt Rileycf879db2017-01-12 13:57:38 -08002040 @Override
2041 public boolean stop() {
2042 return native_stop_batch();
2043 }
2044 };
2045 }
2046
Siddharth Raybb608c82017-03-16 11:33:34 -07002047 public interface GnssMetricsProvider {
2048 /**
2049 * Returns GNSS metrics as proto string
2050 */
2051 String getGnssMetricsAsProtoString();
2052 }
2053
2054 /**
2055 * @hide
2056 */
2057 public GnssMetricsProvider getGnssMetricsProvider() {
2058 return new GnssMetricsProvider() {
2059 @Override
2060 public String getGnssMetricsAsProtoString() {
2061 return mGnssMetrics.dumpGnssMetricsAsProtoString();
2062 }
2063 };
2064 }
2065
Wyatt Rileycf879db2017-01-12 13:57:38 -08002066 /**
2067 * Initialize Batching if enabled
2068 */
2069 private void enableBatching() {
2070 if (!native_init_batching()) {
2071 Log.e(TAG, "Failed to initialize GNSS batching");
gomo48f1a642017-11-10 20:35:46 -08002072 }
Wyatt Rileycf879db2017-01-12 13:57:38 -08002073 }
2074
2075 /**
2076 * Disable batching
2077 */
2078 private void disableBatching() {
2079 native_stop_batch();
2080 native_cleanup_batching();
2081 }
2082
2083 /**
2084 * called from native code - GNSS location batch callback
2085 */
2086 private void reportLocationBatch(Location[] locationArray) {
2087 List<Location> locations = new ArrayList<>(Arrays.asList(locationArray));
gomo48f1a642017-11-10 20:35:46 -08002088 if (DEBUG) {
2089 Log.d(TAG, "Location batch of size " + locationArray.length + " reported");
2090 }
Wyatt Rileycf879db2017-01-12 13:57:38 -08002091 try {
2092 mILocationManager.reportLocationBatch(locations);
2093 } catch (RemoteException e) {
2094 Log.e(TAG, "RemoteException calling reportLocationBatch");
2095 }
2096 }
2097
Lifu Tang82f893d2016-01-21 18:15:33 -08002098 /**
Mike Lockwood62a8fc12010-03-22 14:23:26 -04002099 * called from native code to request XTRA data
2100 */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002101 private void xtraDownloadRequest() {
Joe Onoratof5d95cb2010-01-07 21:48:32 -05002102 if (DEBUG) Log.d(TAG, "xtraDownloadRequest");
Mike Lockwood98e48692010-04-07 16:32:51 -04002103 sendMessage(DOWNLOAD_XTRA_DATA, 0, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002104 }
2105
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07002106 /**
destradaa0682809a2013-08-12 18:50:30 -07002107 * Converts the GPS HAL status to the internal Geofence Hardware status.
2108 */
2109 private int getGeofenceStatus(int status) {
gomo48f1a642017-11-10 20:35:46 -08002110 switch (status) {
destradaa0682809a2013-08-12 18:50:30 -07002111 case GPS_GEOFENCE_OPERATION_SUCCESS:
2112 return GeofenceHardware.GEOFENCE_SUCCESS;
2113 case GPS_GEOFENCE_ERROR_GENERIC:
2114 return GeofenceHardware.GEOFENCE_FAILURE;
2115 case GPS_GEOFENCE_ERROR_ID_EXISTS:
2116 return GeofenceHardware.GEOFENCE_ERROR_ID_EXISTS;
2117 case GPS_GEOFENCE_ERROR_INVALID_TRANSITION:
2118 return GeofenceHardware.GEOFENCE_ERROR_INVALID_TRANSITION;
2119 case GPS_GEOFENCE_ERROR_TOO_MANY_GEOFENCES:
2120 return GeofenceHardware.GEOFENCE_ERROR_TOO_MANY_GEOFENCES;
2121 case GPS_GEOFENCE_ERROR_ID_UNKNOWN:
2122 return GeofenceHardware.GEOFENCE_ERROR_ID_UNKNOWN;
2123 default:
2124 return -1;
2125 }
2126 }
2127
2128 /**
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07002129 * Called from native to report GPS Geofence transition
2130 * All geofence callbacks are called on the same thread
2131 */
Wyatt Riley5d229832017-02-10 17:06:00 -08002132 private void reportGeofenceTransition(int geofenceId, Location location, int transition,
gomo48f1a642017-11-10 20:35:46 -08002133 long transitionTimestamp) {
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07002134 if (mGeofenceHardwareImpl == null) {
2135 mGeofenceHardwareImpl = GeofenceHardwareImpl.getInstance(mContext);
2136 }
Wyatt Riley5d229832017-02-10 17:06:00 -08002137
destradaa0682809a2013-08-12 18:50:30 -07002138 mGeofenceHardwareImpl.reportGeofenceTransition(
2139 geofenceId,
2140 location,
2141 transition,
2142 transitionTimestamp,
2143 GeofenceHardware.MONITORING_TYPE_GPS_HARDWARE,
2144 FusedBatchOptions.SourceTechnologies.GNSS);
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07002145 }
2146
2147 /**
2148 * called from native code to report GPS status change.
2149 */
Wyatt Riley5d229832017-02-10 17:06:00 -08002150 private void reportGeofenceStatus(int status, Location location) {
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07002151 if (mGeofenceHardwareImpl == null) {
2152 mGeofenceHardwareImpl = GeofenceHardwareImpl.getInstance(mContext);
2153 }
destradaa0682809a2013-08-12 18:50:30 -07002154 int monitorStatus = GeofenceHardware.MONITOR_CURRENTLY_UNAVAILABLE;
gomo48f1a642017-11-10 20:35:46 -08002155 if (status == GPS_GEOFENCE_AVAILABLE) {
destradaa0682809a2013-08-12 18:50:30 -07002156 monitorStatus = GeofenceHardware.MONITOR_CURRENTLY_AVAILABLE;
2157 }
2158 mGeofenceHardwareImpl.reportGeofenceMonitorStatus(
2159 GeofenceHardware.MONITORING_TYPE_GPS_HARDWARE,
2160 monitorStatus,
2161 location,
2162 FusedBatchOptions.SourceTechnologies.GNSS);
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07002163 }
2164
2165 /**
2166 * called from native code - Geofence Add callback
2167 */
2168 private void reportGeofenceAddStatus(int geofenceId, int status) {
2169 if (mGeofenceHardwareImpl == null) {
2170 mGeofenceHardwareImpl = GeofenceHardwareImpl.getInstance(mContext);
2171 }
destradaa0682809a2013-08-12 18:50:30 -07002172 mGeofenceHardwareImpl.reportGeofenceAddStatus(geofenceId, getGeofenceStatus(status));
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07002173 }
2174
2175 /**
2176 * called from native code - Geofence Remove callback
2177 */
2178 private void reportGeofenceRemoveStatus(int geofenceId, int status) {
2179 if (mGeofenceHardwareImpl == null) {
2180 mGeofenceHardwareImpl = GeofenceHardwareImpl.getInstance(mContext);
2181 }
destradaa0682809a2013-08-12 18:50:30 -07002182 mGeofenceHardwareImpl.reportGeofenceRemoveStatus(geofenceId, getGeofenceStatus(status));
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07002183 }
2184
2185 /**
2186 * called from native code - Geofence Pause callback
2187 */
2188 private void reportGeofencePauseStatus(int geofenceId, int status) {
2189 if (mGeofenceHardwareImpl == null) {
2190 mGeofenceHardwareImpl = GeofenceHardwareImpl.getInstance(mContext);
2191 }
destradaa0682809a2013-08-12 18:50:30 -07002192 mGeofenceHardwareImpl.reportGeofencePauseStatus(geofenceId, getGeofenceStatus(status));
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07002193 }
2194
2195 /**
2196 * called from native code - Geofence Resume callback
2197 */
2198 private void reportGeofenceResumeStatus(int geofenceId, int status) {
2199 if (mGeofenceHardwareImpl == null) {
2200 mGeofenceHardwareImpl = GeofenceHardwareImpl.getInstance(mContext);
2201 }
destradaa0682809a2013-08-12 18:50:30 -07002202 mGeofenceHardwareImpl.reportGeofenceResumeStatus(geofenceId, getGeofenceStatus(status));
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07002203 }
2204
Danke Xie22d1f9f2009-08-18 18:28:45 -04002205 //=============================================================
2206 // NI Client support
Miguel Torroja1e84da82010-07-27 07:02:24 +02002207 //=============================================================
Danke Xie22d1f9f2009-08-18 18:28:45 -04002208 private final INetInitiatedListener mNetInitiatedListener = new INetInitiatedListener.Stub() {
destradaaef752b62015-04-17 13:10:47 -07002209 // Sends a response for an NI request to HAL.
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002210 @Override
gomo48f1a642017-11-10 20:35:46 -08002211 public boolean sendNiResponse(int notificationId, int userResponse) {
Miguel Torroja1e84da82010-07-27 07:02:24 +02002212 // TODO Add Permission check
Danke Xie22d1f9f2009-08-18 18:28:45 -04002213
gomo48f1a642017-11-10 20:35:46 -08002214 if (DEBUG) {
2215 Log.d(TAG, "sendNiResponse, notifId: " + notificationId +
2216 ", response: " + userResponse);
2217 }
Miguel Torroja1e84da82010-07-27 07:02:24 +02002218 native_send_ni_response(notificationId, userResponse);
2219 return true;
2220 }
Danke Xie22d1f9f2009-08-18 18:28:45 -04002221 };
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002222
Danke Xie22d1f9f2009-08-18 18:28:45 -04002223 public INetInitiatedListener getNetInitiatedListener() {
2224 return mNetInitiatedListener;
2225 }
2226
2227 // Called by JNI function to report an NI request.
Miguel Torroja1e84da82010-07-27 07:02:24 +02002228 public void reportNiNotification(
2229 int notificationId,
2230 int niType,
2231 int notifyFlags,
2232 int timeout,
2233 int defaultResponse,
2234 String requestorId,
2235 String text,
2236 int requestorIdEncoding,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002237 int textEncoding
gomo48f1a642017-11-10 20:35:46 -08002238 ) {
Miguel Torroja1e84da82010-07-27 07:02:24 +02002239 Log.i(TAG, "reportNiNotification: entered");
2240 Log.i(TAG, "notificationId: " + notificationId +
2241 ", niType: " + niType +
2242 ", notifyFlags: " + notifyFlags +
2243 ", timeout: " + timeout +
2244 ", defaultResponse: " + defaultResponse);
2245
2246 Log.i(TAG, "requestorId: " + requestorId +
2247 ", text: " + text +
2248 ", requestorIdEncoding: " + requestorIdEncoding +
2249 ", textEncoding: " + textEncoding);
2250
2251 GpsNiNotification notification = new GpsNiNotification();
2252
2253 notification.notificationId = notificationId;
2254 notification.niType = niType;
2255 notification.needNotify = (notifyFlags & GpsNetInitiatedHandler.GPS_NI_NEED_NOTIFY) != 0;
2256 notification.needVerify = (notifyFlags & GpsNetInitiatedHandler.GPS_NI_NEED_VERIFY) != 0;
gomo48f1a642017-11-10 20:35:46 -08002257 notification.privacyOverride =
2258 (notifyFlags & GpsNetInitiatedHandler.GPS_NI_PRIVACY_OVERRIDE) != 0;
Miguel Torroja1e84da82010-07-27 07:02:24 +02002259 notification.timeout = timeout;
2260 notification.defaultResponse = defaultResponse;
2261 notification.requestorId = requestorId;
2262 notification.text = text;
2263 notification.requestorIdEncoding = requestorIdEncoding;
2264 notification.textEncoding = textEncoding;
2265
Miguel Torroja1e84da82010-07-27 07:02:24 +02002266 mNIHandler.handleNiNotification(notification);
2267 }
2268
2269 /**
2270 * Called from native code to request set id info.
2271 * We should be careful about receiving null string from the TelephonyManager,
2272 * because sending null String to JNI function would cause a crash.
2273 */
2274
2275 private void requestSetID(int flags) {
2276 TelephonyManager phone = (TelephonyManager)
2277 mContext.getSystemService(Context.TELEPHONY_SERVICE);
destradaaef752b62015-04-17 13:10:47 -07002278 int type = AGPS_SETID_TYPE_NONE;
Miguel Torroja1e84da82010-07-27 07:02:24 +02002279 String data = "";
2280
2281 if ((flags & AGPS_RIL_REQUEST_SETID_IMSI) == AGPS_RIL_REQUEST_SETID_IMSI) {
2282 String data_temp = phone.getSubscriberId();
2283 if (data_temp == null) {
2284 // This means the framework does not have the SIM card ready.
2285 } else {
2286 // This means the framework has the SIM card.
2287 data = data_temp;
2288 type = AGPS_SETID_TYPE_IMSI;
2289 }
gomo48f1a642017-11-10 20:35:46 -08002290 } else if ((flags & AGPS_RIL_REQUEST_SETID_MSISDN) == AGPS_RIL_REQUEST_SETID_MSISDN) {
Miguel Torroja1e84da82010-07-27 07:02:24 +02002291 String data_temp = phone.getLine1Number();
2292 if (data_temp == null) {
2293 // This means the framework does not have the SIM card ready.
2294 } else {
2295 // This means the framework has the SIM card.
2296 data = data_temp;
2297 type = AGPS_SETID_TYPE_MSISDN;
2298 }
2299 }
2300 native_agps_set_id(type, data);
2301 }
2302
2303 /**
Yu-Han Yange7baef32018-02-09 13:58:17 -08002304 * Called from native code to request location info.
2305 */
2306 private void requestLocation(boolean independentFromGnss) {
2307 if (DEBUG) {
2308 Log.d(TAG, "requestLocation. independentFromGnss: " + independentFromGnss);
2309 }
2310 sendMessage(REQUEST_LOCATION, 0, independentFromGnss);
2311 }
2312
2313 /**
Mike Lockwood9b9fb5c2011-06-29 15:09:40 -04002314 * Called from native code to request utc time info
2315 */
Mike Lockwood9b9fb5c2011-06-29 15:09:40 -04002316 private void requestUtcTime() {
destradaae21252a2015-09-08 12:32:59 -07002317 if (DEBUG) Log.d(TAG, "utcTimeRequest");
Mike Lockwood9b9fb5c2011-06-29 15:09:40 -04002318 sendMessage(INJECT_NTP_TIME, 0, null);
2319 }
2320
2321 /**
Miguel Torroja1e84da82010-07-27 07:02:24 +02002322 * Called from native code to request reference location info
2323 */
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002324 private void requestRefLocation() {
Miguel Torroja1e84da82010-07-27 07:02:24 +02002325 TelephonyManager phone = (TelephonyManager)
2326 mContext.getSystemService(Context.TELEPHONY_SERVICE);
Victoria Leased50d0c32012-10-29 13:16:17 -07002327 final int phoneType = phone.getPhoneType();
2328 if (phoneType == TelephonyManager.PHONE_TYPE_GSM) {
Miguel Torroja1e84da82010-07-27 07:02:24 +02002329 GsmCellLocation gsm_cell = (GsmCellLocation) phone.getCellLocation();
Victoria Leased50d0c32012-10-29 13:16:17 -07002330 if ((gsm_cell != null) && (phone.getNetworkOperator() != null)
2331 && (phone.getNetworkOperator().length() > 3)) {
Miguel Torroja1e84da82010-07-27 07:02:24 +02002332 int type;
gomo48f1a642017-11-10 20:35:46 -08002333 int mcc = Integer.parseInt(phone.getNetworkOperator().substring(0, 3));
Miguel Torroja1e84da82010-07-27 07:02:24 +02002334 int mnc = Integer.parseInt(phone.getNetworkOperator().substring(3));
Mike Lockwoodedc0f3872010-10-22 09:16:17 -04002335 int networkType = phone.getNetworkType();
2336 if (networkType == TelephonyManager.NETWORK_TYPE_UMTS
gomo48f1a642017-11-10 20:35:46 -08002337 || networkType == TelephonyManager.NETWORK_TYPE_HSDPA
2338 || networkType == TelephonyManager.NETWORK_TYPE_HSUPA
2339 || networkType == TelephonyManager.NETWORK_TYPE_HSPA
2340 || networkType == TelephonyManager.NETWORK_TYPE_HSPAP) {
Miguel Torroja1e84da82010-07-27 07:02:24 +02002341 type = AGPS_REF_LOCATION_TYPE_UMTS_CELLID;
Mike Lockwoodedc0f3872010-10-22 09:16:17 -04002342 } else {
Miguel Torroja1e84da82010-07-27 07:02:24 +02002343 type = AGPS_REF_LOCATION_TYPE_GSM_CELLID;
Mike Lockwoodedc0f3872010-10-22 09:16:17 -04002344 }
Miguel Torroja1e84da82010-07-27 07:02:24 +02002345 native_agps_set_ref_location_cellid(type, mcc, mnc,
2346 gsm_cell.getLac(), gsm_cell.getCid());
Mike Lockwoodedc0f3872010-10-22 09:16:17 -04002347 } else {
gomo48f1a642017-11-10 20:35:46 -08002348 Log.e(TAG, "Error getting cell location info.");
Mike Lockwoodedc0f3872010-10-22 09:16:17 -04002349 }
Victoria Leased50d0c32012-10-29 13:16:17 -07002350 } else if (phoneType == TelephonyManager.PHONE_TYPE_CDMA) {
2351 Log.e(TAG, "CDMA not supported.");
Mike Lockwoodedc0f3872010-10-22 09:16:17 -04002352 }
Miguel Torroja1e84da82010-07-27 07:02:24 +02002353 }
Danke Xie22d1f9f2009-08-18 18:28:45 -04002354
Mike Lockwood98e48692010-04-07 16:32:51 -04002355 private void sendMessage(int message, int arg, Object obj) {
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002356 // hold a wake lock until this message is delivered
Jeff Brown028872f2012-08-25 13:07:01 -07002357 // note that this assumes the message will not be removed from the queue before
2358 // it is handled (otherwise the wake lock would be leaked).
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002359 mWakeLock.acquire();
Wyatt Rileycf879db2017-01-12 13:57:38 -08002360 if (Log.isLoggable(TAG, Log.INFO)) {
2361 Log.i(TAG, "WakeLock acquired by sendMessage(" + messageIdAsString(message) + ", " + arg
2362 + ", " + obj + ")");
2363 }
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002364 mHandler.obtainMessage(message, arg, 1, obj).sendToTarget();
Mike Lockwood98e48692010-04-07 16:32:51 -04002365 }
2366
Mike Lockwood62a8fc12010-03-22 14:23:26 -04002367 private final class ProviderHandler extends Handler {
Victoria Lease5cd731a2012-12-19 15:04:21 -08002368 public ProviderHandler(Looper looper) {
2369 super(looper, null, true /*async*/);
Jeff Brown028872f2012-08-25 13:07:01 -07002370 }
2371
Mike Lockwood62a8fc12010-03-22 14:23:26 -04002372 @Override
Mike Lockwood4a7b65e2010-10-25 16:35:55 -04002373 public void handleMessage(Message msg) {
Mike Lockwood98e48692010-04-07 16:32:51 -04002374 int message = msg.what;
2375 switch (message) {
Mike Lockwood62a8fc12010-03-22 14:23:26 -04002376 case ENABLE:
2377 if (msg.arg1 == 1) {
2378 handleEnable();
2379 } else {
2380 handleDisable();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002381 }
Mike Lockwood62a8fc12010-03-22 14:23:26 -04002382 break;
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002383 case SET_REQUEST:
2384 GpsRequest gpsRequest = (GpsRequest) msg.obj;
2385 handleSetRequest(gpsRequest.request, gpsRequest.source);
Mike Lockwood03ca2162010-04-01 08:10:09 -07002386 break;
Mike Lockwood62a8fc12010-03-22 14:23:26 -04002387 case UPDATE_NETWORK_STATE:
destradaae21252a2015-09-08 12:32:59 -07002388 handleUpdateNetworkState((Network) msg.obj);
2389 break;
2390 case REQUEST_SUPL_CONNECTION:
2391 handleRequestSuplConnection((InetAddress) msg.obj);
2392 break;
2393 case RELEASE_SUPL_CONNECTION:
2394 handleReleaseSuplConnection(msg.arg1);
Mike Lockwood62a8fc12010-03-22 14:23:26 -04002395 break;
2396 case INJECT_NTP_TIME:
Yu-Han Yanga1862b52018-02-20 17:05:59 -08002397 mNtpTimeHelper.retrieveAndInjectNtpTime();
Mike Lockwood62a8fc12010-03-22 14:23:26 -04002398 break;
Yu-Han Yange7baef32018-02-09 13:58:17 -08002399 case REQUEST_LOCATION:
2400 handleRequestLocation((boolean) msg.obj);
2401 break;
Mike Lockwood62a8fc12010-03-22 14:23:26 -04002402 case DOWNLOAD_XTRA_DATA:
Wyatt Riley0d6e54e22016-10-05 12:03:03 -07002403 handleDownloadXtraData();
Mike Lockwood62a8fc12010-03-22 14:23:26 -04002404 break;
Kevin Tang40e1baf2012-01-10 14:32:44 -08002405 case DOWNLOAD_XTRA_DATA_FINISHED:
2406 mDownloadXtraDataPending = STATE_IDLE;
2407 break;
Mike Lockwood62a8fc12010-03-22 14:23:26 -04002408 case UPDATE_LOCATION:
destradaae21252a2015-09-08 12:32:59 -07002409 handleUpdateLocation((Location) msg.obj);
Mike Lockwood62a8fc12010-03-22 14:23:26 -04002410 break;
destradaafb23c672015-04-16 14:01:27 -07002411 case SUBSCRIPTION_OR_SIM_CHANGED:
2412 subscriptionOrSimChanged(mContext);
2413 break;
2414 case INITIALIZE_HANDLER:
destradaae21252a2015-09-08 12:32:59 -07002415 handleInitialize();
destradaafb23c672015-04-16 14:01:27 -07002416 break;
Wyatt Riley26465d22018-02-12 13:44:24 -08002417 case REPORT_LOCATION:
2418 handleReportLocation(msg.arg1 == 1, (Location) msg.obj);
2419 break;
2420 case REPORT_SV_STATUS:
2421 handleReportSvStatus((SvStatusInfo) msg.obj);
2422 break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002423 }
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002424 if (msg.arg2 == 1) {
2425 // wakelock was taken for this message, release it
2426 mWakeLock.release();
Wyatt Rileycf879db2017-01-12 13:57:38 -08002427 if (Log.isLoggable(TAG, Log.INFO)) {
2428 Log.i(TAG, "WakeLock released by handleMessage(" + messageIdAsString(message)
2429 + ", " + msg.arg1 + ", " + msg.obj + ")");
2430 }
Mike Lockwood98e48692010-04-07 16:32:51 -04002431 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002432 }
destradaafb23c672015-04-16 14:01:27 -07002433
2434 /**
Lifu Tang30f95a72016-01-07 23:20:38 -08002435 * This method is bound to {@link #GnssLocationProvider(Context, ILocationManager, Looper)}.
destradaafb23c672015-04-16 14:01:27 -07002436 * It is in charge of loading properties and registering for events that will be posted to
2437 * this handler.
2438 */
destradaae21252a2015-09-08 12:32:59 -07002439 private void handleInitialize() {
Yu-Han Yang6d317352018-03-15 11:53:01 -07002440 native_init_once();
2441
Wyatt Riley523a0cf2017-10-31 14:36:52 -07002442 /*
2443 * A cycle of native_init() and native_cleanup() is needed so that callbacks are
2444 * registered after bootup even when location is disabled.
2445 * This will allow Emergency SUPL to work even when location is disabled before device
2446 * restart.
2447 */
2448 boolean isInitialized = native_init();
gomo48f1a642017-11-10 20:35:46 -08002449 if (!isInitialized) {
Wyatt Riley523a0cf2017-10-31 14:36:52 -07002450 Log.w(TAG, "Native initialization failed at bootup");
2451 } else {
2452 native_cleanup();
2453 }
2454
destradaafb23c672015-04-16 14:01:27 -07002455 // load default GPS configuration
2456 // (this configuration might change in the future based on SIM changes)
2457 reloadGpsProperties(mContext, mProperties);
2458
2459 // TODO: When this object "finishes" we should unregister by invoking
gomo48f1a642017-11-10 20:35:46 -08002460 // SubscriptionManager.getInstance(mContext).unregister
2461 // (mOnSubscriptionsChangedListener);
destradaafb23c672015-04-16 14:01:27 -07002462 // This is not strictly necessary because it will be unregistered if the
2463 // notification fails but it is good form.
2464
2465 // Register for SubscriptionInfo list changes which is guaranteed
2466 // to invoke onSubscriptionsChanged the first time.
2467 SubscriptionManager.from(mContext)
2468 .addOnSubscriptionsChangedListener(mOnSubscriptionsChangedListener);
2469
2470 // listen for events
destradaaef752b62015-04-17 13:10:47 -07002471 IntentFilter intentFilter;
2472 if (native_is_agps_ril_supported()) {
2473 intentFilter = new IntentFilter();
2474 intentFilter.addAction(Intents.DATA_SMS_RECEIVED_ACTION);
2475 intentFilter.addDataScheme("sms");
2476 intentFilter.addDataAuthority("localhost", "7275");
2477 mContext.registerReceiver(mBroadcastReceiver, intentFilter, null, this);
destradaafb23c672015-04-16 14:01:27 -07002478
destradaaef752b62015-04-17 13:10:47 -07002479 intentFilter = new IntentFilter();
2480 intentFilter.addAction(Intents.WAP_PUSH_RECEIVED_ACTION);
2481 try {
2482 intentFilter.addDataType("application/vnd.omaloc-supl-init");
2483 } catch (IntentFilter.MalformedMimeTypeException e) {
2484 Log.w(TAG, "Malformed SUPL init mime type");
2485 }
2486 mContext.registerReceiver(mBroadcastReceiver, intentFilter, null, this);
2487 } else if (DEBUG) {
2488 Log.d(TAG, "Skipped registration for SMS/WAP-PUSH messages because AGPS Ril in GPS"
2489 + " HAL is not supported");
destradaafb23c672015-04-16 14:01:27 -07002490 }
destradaafb23c672015-04-16 14:01:27 -07002491
2492 intentFilter = new IntentFilter();
2493 intentFilter.addAction(ALARM_WAKEUP);
2494 intentFilter.addAction(ALARM_TIMEOUT);
destradaafb23c672015-04-16 14:01:27 -07002495 intentFilter.addAction(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED);
Adam Lesinski87c17df2015-05-27 13:24:13 -07002496 intentFilter.addAction(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED);
destradaafb23c672015-04-16 14:01:27 -07002497 intentFilter.addAction(Intent.ACTION_SCREEN_OFF);
2498 intentFilter.addAction(Intent.ACTION_SCREEN_ON);
2499 intentFilter.addAction(SIM_STATE_CHANGED);
2500 mContext.registerReceiver(mBroadcastReceiver, intentFilter, null, this);
2501
destradaae21252a2015-09-08 12:32:59 -07002502 // register for connectivity change events, this is equivalent to the deprecated way of
2503 // registering for CONNECTIVITY_ACTION broadcasts
2504 NetworkRequest.Builder networkRequestBuilder = new NetworkRequest.Builder();
Jeff Sharkeyc159d522018-03-28 10:54:07 -06002505 networkRequestBuilder.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
2506 networkRequestBuilder.addCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED);
2507 networkRequestBuilder.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN);
destradaae21252a2015-09-08 12:32:59 -07002508 NetworkRequest networkRequest = networkRequestBuilder.build();
2509 mConnMgr.registerNetworkCallback(networkRequest, mNetworkConnectivityCallback);
2510
destradaafb23c672015-04-16 14:01:27 -07002511 // listen for PASSIVE_PROVIDER updates
2512 LocationManager locManager =
2513 (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE);
2514 long minTime = 0;
2515 float minDistance = 0;
2516 boolean oneShot = false;
2517 LocationRequest request = LocationRequest.createFromDeprecatedProvider(
2518 LocationManager.PASSIVE_PROVIDER,
2519 minTime,
2520 minDistance,
2521 oneShot);
2522 // Don't keep track of this request since it's done on behalf of other clients
2523 // (which are kept track of separately).
2524 request.setHideFromAppOps(true);
2525 locManager.requestLocationUpdates(
2526 request,
2527 new NetworkLocationListener(),
2528 getLooper());
2529 }
2530 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002531
Yu-Han Yange7baef32018-02-09 13:58:17 -08002532 private abstract class LocationChangeListener implements LocationListener {
Yu-Han Yang07561382018-02-21 13:08:37 -08002533 int numLocationUpdateRequest;
2534
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002535 @Override
gomo48f1a642017-11-10 20:35:46 -08002536 public void onStatusChanged(String provider, int status, Bundle extras) {
2537 }
2538
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002539 @Override
gomo48f1a642017-11-10 20:35:46 -08002540 public void onProviderEnabled(String provider) {
2541 }
2542
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002543 @Override
gomo48f1a642017-11-10 20:35:46 -08002544 public void onProviderDisabled(String provider) {
2545 }
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002546 }
2547
Yu-Han Yange7baef32018-02-09 13:58:17 -08002548 private final class NetworkLocationListener extends LocationChangeListener {
2549 @Override
2550 public void onLocationChanged(Location location) {
2551 // this callback happens on mHandler looper
2552 if (LocationManager.NETWORK_PROVIDER.equals(location.getProvider())) {
2553 handleUpdateLocation(location);
2554 }
2555 }
2556 }
2557
2558 private final class FusedLocationListener extends LocationChangeListener {
2559 @Override
2560 public void onLocationChanged(Location location) {
2561 if (LocationManager.FUSED_PROVIDER.equals(location.getProvider())) {
Yu-Han Yange7baef32018-02-09 13:58:17 -08002562 injectBestLocation(location);
2563 }
2564 }
2565 }
2566
Kevin Tanga5fe6b22011-06-05 14:25:16 -07002567 private String getSelectedApn() {
2568 Uri uri = Uri.parse("content://telephony/carriers/preferapn");
destradaa96a14702014-06-05 11:36:30 -07002569 Cursor cursor = null;
2570 try {
2571 cursor = mContext.getContentResolver().query(
2572 uri,
gomo48f1a642017-11-10 20:35:46 -08002573 new String[]{"apn"},
destradaa96a14702014-06-05 11:36:30 -07002574 null /* selection */,
2575 null /* selectionArgs */,
2576 Carriers.DEFAULT_SORT_ORDER);
2577 if (cursor != null && cursor.moveToFirst()) {
2578 return cursor.getString(0);
2579 } else {
2580 Log.e(TAG, "No APN found to select.");
2581 }
2582 } catch (Exception e) {
destradaaea8a8a62014-06-23 18:19:03 -07002583 Log.e(TAG, "Error encountered on selecting the APN.", e);
destradaa96a14702014-06-05 11:36:30 -07002584 } finally {
2585 if (cursor != null) {
Kevin Tanga5fe6b22011-06-05 14:25:16 -07002586 cursor.close();
2587 }
2588 }
destradaa96a14702014-06-05 11:36:30 -07002589
2590 return null;
2591 }
2592
2593 private int getApnIpType(String apn) {
destradaae21252a2015-09-08 12:32:59 -07002594 ensureInHandlerThread();
destradaa96a14702014-06-05 11:36:30 -07002595 if (apn == null) {
2596 return APN_INVALID;
2597 }
2598
destradaa96a14702014-06-05 11:36:30 -07002599 String selection = String.format("current = 1 and apn = '%s' and carrier_enabled = 1", apn);
2600 Cursor cursor = null;
2601 try {
2602 cursor = mContext.getContentResolver().query(
2603 Carriers.CONTENT_URI,
gomo48f1a642017-11-10 20:35:46 -08002604 new String[]{Carriers.PROTOCOL},
destradaa96a14702014-06-05 11:36:30 -07002605 selection,
2606 null,
2607 Carriers.DEFAULT_SORT_ORDER);
2608
2609 if (null != cursor && cursor.moveToFirst()) {
2610 return translateToApnIpType(cursor.getString(0), apn);
2611 } else {
2612 Log.e(TAG, "No entry found in query for APN: " + apn);
2613 }
2614 } catch (Exception e) {
2615 Log.e(TAG, "Error encountered on APN query for: " + apn, e);
2616 } finally {
2617 if (cursor != null) {
2618 cursor.close();
2619 }
2620 }
2621
2622 return APN_INVALID;
2623 }
2624
2625 private int translateToApnIpType(String ipProtocol, String apn) {
2626 if ("IP".equals(ipProtocol)) {
2627 return APN_IPV4;
2628 }
2629 if ("IPV6".equals(ipProtocol)) {
2630 return APN_IPV6;
2631 }
2632 if ("IPV4V6".equals(ipProtocol)) {
2633 return APN_IPV4V6;
2634 }
2635
2636 // we hit the default case so the ipProtocol is not recognized
2637 String message = String.format("Unknown IP Protocol: %s, for APN: %s", ipProtocol, apn);
2638 Log.e(TAG, message);
2639 return APN_INVALID;
2640 }
2641
2642 private void setRouting() {
2643 if (mAGpsDataConnectionIpAddr == null) {
2644 return;
2645 }
2646
destradaae21252a2015-09-08 12:32:59 -07002647 // TODO: replace the use of this deprecated API
destradaa96a14702014-06-05 11:36:30 -07002648 boolean result = mConnMgr.requestRouteToHostAddress(
2649 ConnectivityManager.TYPE_MOBILE_SUPL,
2650 mAGpsDataConnectionIpAddr);
2651
2652 if (!result) {
2653 Log.e(TAG, "Error requesting route to host: " + mAGpsDataConnectionIpAddr);
2654 } else if (DEBUG) {
2655 Log.d(TAG, "Successfully requested route to host: " + mAGpsDataConnectionIpAddr);
2656 }
Kevin Tanga5fe6b22011-06-05 14:25:16 -07002657 }
2658
destradaae21252a2015-09-08 12:32:59 -07002659 /**
2660 * @return {@code true} if there is a data network available for outgoing connections,
gomo48f1a642017-11-10 20:35:46 -08002661 * {@code false} otherwise.
destradaae21252a2015-09-08 12:32:59 -07002662 */
2663 private boolean isDataNetworkConnected() {
2664 NetworkInfo activeNetworkInfo = mConnMgr.getActiveNetworkInfo();
2665 return activeNetworkInfo != null && activeNetworkInfo.isConnected();
2666 }
2667
2668 /**
2669 * Ensures the calling function is running in the thread associated with {@link #mHandler}.
2670 */
2671 private void ensureInHandlerThread() {
2672 if (mHandler != null && Looper.myLooper() == mHandler.getLooper()) {
2673 return;
2674 }
2675 throw new RuntimeException("This method must run on the Handler thread.");
2676 }
2677
2678 /**
2679 * @return A string representing the current state stored in {@link #mAGpsDataConnectionState}.
2680 */
2681 private String agpsDataConnStateAsString() {
gomo48f1a642017-11-10 20:35:46 -08002682 switch (mAGpsDataConnectionState) {
destradaae21252a2015-09-08 12:32:59 -07002683 case AGPS_DATA_CONNECTION_CLOSED:
2684 return "CLOSED";
2685 case AGPS_DATA_CONNECTION_OPEN:
2686 return "OPEN";
2687 case AGPS_DATA_CONNECTION_OPENING:
2688 return "OPENING";
2689 default:
2690 return "<Unknown>";
2691 }
2692 }
2693
2694 /**
2695 * @return A string representing the given GPS_AGPS_DATA status.
2696 */
2697 private String agpsDataConnStatusAsString(int agpsDataConnStatus) {
2698 switch (agpsDataConnStatus) {
2699 case GPS_AGPS_DATA_CONNECTED:
2700 return "CONNECTED";
2701 case GPS_AGPS_DATA_CONN_DONE:
2702 return "DONE";
2703 case GPS_AGPS_DATA_CONN_FAILED:
2704 return "FAILED";
2705 case GPS_RELEASE_AGPS_DATA_CONN:
2706 return "RELEASE";
2707 case GPS_REQUEST_AGPS_DATA_CONN:
2708 return "REQUEST";
2709 default:
2710 return "<Unknown>";
2711 }
2712 }
2713
Wyatt Rileycf879db2017-01-12 13:57:38 -08002714 /**
2715 * @return A string representing the given message ID.
2716 */
2717 private String messageIdAsString(int message) {
2718 switch (message) {
2719 case ENABLE:
2720 return "ENABLE";
2721 case SET_REQUEST:
2722 return "SET_REQUEST";
2723 case UPDATE_NETWORK_STATE:
2724 return "UPDATE_NETWORK_STATE";
2725 case REQUEST_SUPL_CONNECTION:
2726 return "REQUEST_SUPL_CONNECTION";
2727 case RELEASE_SUPL_CONNECTION:
2728 return "RELEASE_SUPL_CONNECTION";
2729 case INJECT_NTP_TIME:
2730 return "INJECT_NTP_TIME";
Yu-Han Yange7baef32018-02-09 13:58:17 -08002731 case REQUEST_LOCATION:
2732 return "REQUEST_LOCATION";
Wyatt Rileycf879db2017-01-12 13:57:38 -08002733 case DOWNLOAD_XTRA_DATA:
2734 return "DOWNLOAD_XTRA_DATA";
Wyatt Rileycf879db2017-01-12 13:57:38 -08002735 case DOWNLOAD_XTRA_DATA_FINISHED:
2736 return "DOWNLOAD_XTRA_DATA_FINISHED";
2737 case UPDATE_LOCATION:
2738 return "UPDATE_LOCATION";
2739 case SUBSCRIPTION_OR_SIM_CHANGED:
2740 return "SUBSCRIPTION_OR_SIM_CHANGED";
2741 case INITIALIZE_HANDLER:
2742 return "INITIALIZE_HANDLER";
Wyatt Riley26465d22018-02-12 13:44:24 -08002743 case REPORT_LOCATION:
2744 return "REPORT_LOCATION";
2745 case REPORT_SV_STATUS:
2746 return "REPORT_SV_STATUS";
Wyatt Rileycf879db2017-01-12 13:57:38 -08002747 default:
2748 return "<Unknown>";
2749 }
2750 }
2751
Siddharth Raybb608c82017-03-16 11:33:34 -07002752
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002753 @Override
2754 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2755 StringBuilder s = new StringBuilder();
Wyatt Riley77ca4f82017-06-30 18:13:44 -07002756 s.append(" mStarted=").append(mStarted).append('\n');
destradaa25e8caf2015-08-24 14:14:44 -07002757 s.append(" mFixInterval=").append(mFixInterval).append('\n');
gomo48f1a642017-11-10 20:35:46 -08002758 s.append(" mLowPowerMode=").append(mLowPowerMode).append('\n');
Wyatt Riley74479bd2018-01-17 08:48:27 -08002759 s.append(" mGnssMeasurementsProvider.isRegistered()=")
2760 .append(mGnssMeasurementsProvider.isRegistered()).append('\n');
2761 s.append(" mGnssNavigationMessageProvider.isRegistered()=")
2762 .append(mGnssNavigationMessageProvider.isRegistered()).append('\n');
destradaa25e8caf2015-08-24 14:14:44 -07002763 s.append(" mDisableGps (battery saver mode)=").append(mDisableGps).append('\n');
2764 s.append(" mEngineCapabilities=0x").append(Integer.toHexString(mEngineCapabilities));
2765 s.append(" ( ");
2766 if (hasCapability(GPS_CAPABILITY_SCHEDULING)) s.append("SCHEDULING ");
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002767 if (hasCapability(GPS_CAPABILITY_MSB)) s.append("MSB ");
2768 if (hasCapability(GPS_CAPABILITY_MSA)) s.append("MSA ");
2769 if (hasCapability(GPS_CAPABILITY_SINGLE_SHOT)) s.append("SINGLE_SHOT ");
2770 if (hasCapability(GPS_CAPABILITY_ON_DEMAND_TIME)) s.append("ON_DEMAND_TIME ");
destradaa25e8caf2015-08-24 14:14:44 -07002771 if (hasCapability(GPS_CAPABILITY_GEOFENCING)) s.append("GEOFENCING ");
2772 if (hasCapability(GPS_CAPABILITY_MEASUREMENTS)) s.append("MEASUREMENTS ");
2773 if (hasCapability(GPS_CAPABILITY_NAV_MESSAGES)) s.append("NAV_MESSAGES ");
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002774 s.append(")\n");
Siddharth Raybb608c82017-03-16 11:33:34 -07002775 s.append(mGnssMetrics.dumpGnssMetricsAsText());
2776 s.append(" native internal state: ").append(native_get_internal_state());
Wyatt Rileycf879db2017-01-12 13:57:38 -08002777 s.append("\n");
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002778 pw.append(s);
2779 }
2780
Mike Lockwoodb16e7802009-08-06 09:26:02 -04002781 // preallocated to avoid memory allocation in reportNmea()
2782 private byte[] mNmeaBuffer = new byte[120];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002783
gomo48f1a642017-11-10 20:35:46 -08002784 static {
2785 class_init_native();
2786 }
2787
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002788 private static native void class_init_native();
gomo48f1a642017-11-10 20:35:46 -08002789
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002790 private static native boolean native_is_supported();
gomo48f1a642017-11-10 20:35:46 -08002791
destradaaef752b62015-04-17 13:10:47 -07002792 private static native boolean native_is_agps_ril_supported();
gomo48f1a642017-11-10 20:35:46 -08002793
destradaaef752b62015-04-17 13:10:47 -07002794 private static native boolean native_is_gnss_configuration_supported();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002795
Yu-Han Yang6d317352018-03-15 11:53:01 -07002796 private static native void native_init_once();
2797
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002798 private native boolean native_init();
gomo48f1a642017-11-10 20:35:46 -08002799
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002800 private native void native_cleanup();
gomo48f1a642017-11-10 20:35:46 -08002801
Mike Lockwood04598b62010-04-14 17:17:24 -04002802 private native boolean native_set_position_mode(int mode, int recurrence, int min_interval,
gomo48f1a642017-11-10 20:35:46 -08002803 int preferred_accuracy, int preferred_time, boolean lowPowerMode);
2804
Mike Lockwood04598b62010-04-14 17:17:24 -04002805 private native boolean native_start();
gomo48f1a642017-11-10 20:35:46 -08002806
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002807 private native boolean native_stop();
gomo48f1a642017-11-10 20:35:46 -08002808
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002809 private native void native_delete_aiding_data(int flags);
gomo48f1a642017-11-10 20:35:46 -08002810
Mike Lockwoodf602d362010-06-20 14:28:16 -07002811 private native int native_read_nmea(byte[] buffer, int bufferSize);
gomo48f1a642017-11-10 20:35:46 -08002812
Yu-Han Yange7baef32018-02-09 13:58:17 -08002813 private native void native_inject_best_location(
2814 int gnssLocationFlags,
2815 double latitudeDegrees,
2816 double longitudeDegrees,
2817 double altitudeMeters,
2818 float speedMetersPerSec,
2819 float bearingDegrees,
2820 float horizontalAccuracyMeters,
2821 float verticalAccuracyMeters,
2822 float speedAccuracyMetersPerSecond,
2823 float bearingAccuracyDegrees,
2824 long timestamp);
2825
Mike Lockwoodd26ce0d2009-06-11 12:25:46 -04002826 private native void native_inject_location(double latitude, double longitude, float accuracy);
2827
Fred Fettinger3c8fbdf2010-01-04 15:38:13 -06002828 // XTRA Support
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002829 private native void native_inject_time(long time, long timeReference, int uncertainty);
gomo48f1a642017-11-10 20:35:46 -08002830
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002831 private native boolean native_supports_xtra();
gomo48f1a642017-11-10 20:35:46 -08002832
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002833 private native void native_inject_xtra_data(byte[] data, int length);
The Android Open Source Project10592532009-03-18 17:39:46 -07002834
Fred Fettinger3c8fbdf2010-01-04 15:38:13 -06002835 // DEBUG Support
2836 private native String native_get_internal_state();
2837
2838 // AGPS Support
destradaa96a14702014-06-05 11:36:30 -07002839 private native void native_agps_data_conn_open(String apn, int apnIpType);
gomo48f1a642017-11-10 20:35:46 -08002840
Mike Lockwoode3635c92009-05-11 08:38:02 -04002841 private native void native_agps_data_conn_closed();
gomo48f1a642017-11-10 20:35:46 -08002842
Mike Lockwoode3635c92009-05-11 08:38:02 -04002843 private native void native_agps_data_conn_failed();
gomo48f1a642017-11-10 20:35:46 -08002844
2845 private native void native_agps_ni_message(byte[] msg, int length);
2846
Mike Lockwooda9e54612009-06-19 14:54:42 -04002847 private native void native_set_agps_server(int type, String hostname, int port);
Danke Xie22d1f9f2009-08-18 18:28:45 -04002848
2849 // Network-initiated (NI) Support
2850 private native void native_send_ni_response(int notificationId, int userResponse);
Miguel Torroja1e84da82010-07-27 07:02:24 +02002851
2852 // AGPS ril suport
2853 private native void native_agps_set_ref_location_cellid(int type, int mcc, int mnc,
2854 int lac, int cid);
gomo48f1a642017-11-10 20:35:46 -08002855
Miguel Torroja1e84da82010-07-27 07:02:24 +02002856 private native void native_agps_set_id(int type, String setid);
Mike Lockwood50130bb2010-10-11 06:22:50 -04002857
2858 private native void native_update_network_state(boolean connected, int type,
Kevin Tanga5fe6b22011-06-05 14:25:16 -07002859 boolean roaming, boolean available, String extraInfo, String defaultAPN);
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07002860
2861 // Hardware Geofence support.
2862 private static native boolean native_is_geofence_supported();
gomo48f1a642017-11-10 20:35:46 -08002863
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07002864 private static native boolean native_add_geofence(int geofenceId, double latitude,
gomo48f1a642017-11-10 20:35:46 -08002865 double longitude, double radius, int lastTransition, int monitorTransitions,
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07002866 int notificationResponsivenes, int unknownTimer);
gomo48f1a642017-11-10 20:35:46 -08002867
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07002868 private static native boolean native_remove_geofence(int geofenceId);
gomo48f1a642017-11-10 20:35:46 -08002869
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07002870 private static native boolean native_resume_geofence(int geofenceId, int transitions);
gomo48f1a642017-11-10 20:35:46 -08002871
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07002872 private static native boolean native_pause_geofence(int geofenceId);
destradaaea8a8a62014-06-23 18:19:03 -07002873
2874 // Gps Hal measurements support.
2875 private static native boolean native_is_measurement_supported();
gomo48f1a642017-11-10 20:35:46 -08002876
2877 private native boolean native_start_measurement_collection(boolean enableFullTracking);
2878
destradaa4b3e3932014-07-21 18:01:47 -07002879 private native boolean native_stop_measurement_collection();
2880
2881 // Gps Navigation message support.
2882 private static native boolean native_is_navigation_message_supported();
gomo48f1a642017-11-10 20:35:46 -08002883
destradaa4b3e3932014-07-21 18:01:47 -07002884 private native boolean native_start_navigation_message_collection();
gomo48f1a642017-11-10 20:35:46 -08002885
destradaa4b3e3932014-07-21 18:01:47 -07002886 private native boolean native_stop_navigation_message_collection();
Tsuwei Chen52617bb2014-08-25 11:49:11 -07002887
2888 // GNSS Configuration
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002889 private static native boolean native_set_supl_version(int version);
gomo48f1a642017-11-10 20:35:46 -08002890
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002891 private static native boolean native_set_supl_mode(int mode);
gomo48f1a642017-11-10 20:35:46 -08002892
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002893 private static native boolean native_set_supl_es(int es);
gomo48f1a642017-11-10 20:35:46 -08002894
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002895 private static native boolean native_set_lpp_profile(int lppProfile);
gomo48f1a642017-11-10 20:35:46 -08002896
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002897 private static native boolean native_set_gnss_pos_protocol_select(int gnssPosProtocolSelect);
gomo48f1a642017-11-10 20:35:46 -08002898
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002899 private static native boolean native_set_gps_lock(int gpsLock);
gomo48f1a642017-11-10 20:35:46 -08002900
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002901 private static native boolean native_set_emergency_supl_pdn(int emergencySuplPdn);
2902
Wyatt Rileycf879db2017-01-12 13:57:38 -08002903 // GNSS Batching
2904 private static native int native_get_batch_size();
gomo48f1a642017-11-10 20:35:46 -08002905
Wyatt Rileycf879db2017-01-12 13:57:38 -08002906 private static native boolean native_start_batch(long periodNanos, boolean wakeOnFifoFull);
gomo48f1a642017-11-10 20:35:46 -08002907
Wyatt Rileycf879db2017-01-12 13:57:38 -08002908 private static native void native_flush_batch();
gomo48f1a642017-11-10 20:35:46 -08002909
Wyatt Rileycf879db2017-01-12 13:57:38 -08002910 private static native boolean native_stop_batch();
gomo48f1a642017-11-10 20:35:46 -08002911
Wyatt Rileycf879db2017-01-12 13:57:38 -08002912 private static native boolean native_init_batching();
gomo48f1a642017-11-10 20:35:46 -08002913
Wyatt Rileycf879db2017-01-12 13:57:38 -08002914 private static native void native_cleanup_batching();
2915
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002916}
Yu-Han Yanga1862b52018-02-20 17:05:59 -08002917