blob: 0ec1f9ccd37be6ae2ef578398326370dd8ced603 [file] [log] [blame]
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001/*
2 * Copyright (C) 2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Mike Lockwood00b74272010-03-26 10:41:48 -040017package com.android.server.location;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080018
Mike Lockwood29c84342009-05-06 14:01:15 -040019import android.app.AlarmManager;
Dianne Hackborna06de0f2012-12-11 16:34:47 -080020import android.app.AppOpsManager;
Mike Lockwood29c84342009-05-06 14:01:15 -040021import android.app.PendingIntent;
The Android Open Source Project10592532009-03-18 17:39:46 -070022import android.content.BroadcastReceiver;
Yu-Han Yang74041ff2018-04-06 15:57:31 -070023import android.content.ContentResolver;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080024import android.content.Context;
25import android.content.Intent;
The Android Open Source Project10592532009-03-18 17:39:46 -070026import android.content.IntentFilter;
Kevin Tanga5fe6b22011-06-05 14:25:16 -070027import android.database.Cursor;
destradaa0682809a2013-08-12 18:50:30 -070028import android.hardware.location.GeofenceHardware;
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -070029import android.hardware.location.GeofenceHardwareImpl;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080030import android.location.Criteria;
destradaa0682809a2013-08-12 18:50:30 -070031import android.location.FusedBatchOptions;
Yu-Han Yange7baef32018-02-09 13:58:17 -080032import android.location.GnssMeasurementsEvent;
33import android.location.GnssNavigationMessage;
Lifu Tang30f95a72016-01-07 23:20:38 -080034import android.location.GnssStatus;
35import android.location.IGnssStatusListener;
36import android.location.IGnssStatusProvider;
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -070037import android.location.IGpsGeofenceHardware;
Mike Lockwood4e50b782009-04-03 08:24:43 -070038import android.location.ILocationManager;
Danke Xie22d1f9f2009-08-18 18:28:45 -040039import android.location.INetInitiatedListener;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080040import android.location.Location;
Nick Pelly6fa9ad42012-07-16 12:18:23 -070041import android.location.LocationListener;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080042import android.location.LocationManager;
43import android.location.LocationProvider;
Stan Chesnutt1d72d8c2013-04-15 19:18:02 -070044import android.location.LocationRequest;
Mike Lockwood58bda982009-04-14 16:25:07 -040045import android.net.ConnectivityManager;
destradaae21252a2015-09-08 12:32:59 -070046import android.net.Network;
47import android.net.NetworkCapabilities;
Mike Lockwood03d24672009-10-08 15:45:03 -040048import android.net.NetworkInfo;
destradaae21252a2015-09-08 12:32:59 -070049import android.net.NetworkRequest;
Kevin Tanga5fe6b22011-06-05 14:25:16 -070050import android.net.Uri;
Kevin Tang40e1baf2012-01-10 14:32:44 -080051import android.os.AsyncTask;
Dianne Hackborn91268cf2013-06-13 19:06:50 -070052import android.os.BatteryStats;
Mike Lockwood63aa5a62010-04-14 19:21:31 -040053import android.os.Binder;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080054import android.os.Bundle;
Mike Lockwood62a8fc12010-03-22 14:23:26 -040055import android.os.Handler;
Victoria Lease5cd731a2012-12-19 15:04:21 -080056import android.os.Looper;
Mike Lockwood62a8fc12010-03-22 14:23:26 -040057import android.os.Message;
Yu-Han Yange7baef32018-02-09 13:58:17 -080058import android.os.PersistableBundle;
Mike Lockwood0528b9b2009-05-07 10:12:54 -040059import android.os.PowerManager;
Yu-Han Yange7baef32018-02-09 13:58:17 -080060import android.os.PowerManager.ServiceType;
61import android.os.PowerSaveState;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080062import android.os.RemoteException;
Mike Lockwood2f82c4e2009-04-17 08:24:10 -040063import android.os.ServiceManager;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080064import android.os.SystemClock;
Colin Cross7c030ed2014-01-28 09:33:53 -080065import android.os.SystemProperties;
Dianne Hackborn5ac72a22012-08-29 18:32:08 -070066import android.os.UserHandle;
Dianne Hackborn7e9f4eb2010-09-10 18:43:00 -070067import android.os.WorkSource;
Narayan Kamath32684dd2018-01-08 17:32:51 +000068import android.os.WorkSource.WorkChain;
Mike Lockwoodbcab8df2009-06-25 16:39:09 -040069import android.provider.Settings;
Kevin Tanga5fe6b22011-06-05 14:25:16 -070070import android.provider.Telephony.Carriers;
Miguel Torroja1e84da82010-07-27 07:02:24 +020071import android.provider.Telephony.Sms.Intents;
Yu-Han Yange7baef32018-02-09 13:58:17 -080072import android.telephony.CarrierConfigManager;
Wink Savillea374c3d2014-11-11 11:48:04 -080073import android.telephony.SubscriptionManager;
Wink Savilled09c4ca2014-11-22 10:08:16 -080074import android.telephony.SubscriptionManager.OnSubscriptionsChangedListener;
Miguel Torroja1e84da82010-07-27 07:02:24 +020075import android.telephony.TelephonyManager;
76import android.telephony.gsm.GsmCellLocation;
Colin Cross7c030ed2014-01-28 09:33:53 -080077import android.text.TextUtils;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080078import android.util.Log;
Yu-Han Yanga1862b52018-02-20 17:05:59 -080079
jackqdyulei455e90a2017-02-09 15:29:16 -080080import com.android.internal.app.IBatteryStats;
81import com.android.internal.location.GpsNetInitiatedHandler;
82import com.android.internal.location.GpsNetInitiatedHandler.GpsNiNotification;
83import com.android.internal.location.ProviderProperties;
84import com.android.internal.location.ProviderRequest;
Yu-Han Yange7baef32018-02-09 13:58:17 -080085import com.android.internal.location.gnssmetrics.GnssMetrics;
Yu-Han Yang66c7ea92018-03-11 17:17:15 -070086import com.android.server.location.GnssSatelliteBlacklistHelper.GnssSatelliteBlacklistCallback;
Yu-Han Yanga1862b52018-02-20 17:05:59 -080087import com.android.server.location.NtpTimeHelper.InjectNtpTimeCallback;
Yu-Han Yang66c7ea92018-03-11 17:17:15 -070088
89import libcore.io.IoUtils;
90
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080091import java.io.File;
Nick Pelly6fa9ad42012-07-16 12:18:23 -070092import java.io.FileDescriptor;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -080093import java.io.FileInputStream;
94import java.io.IOException;
Nick Pelly6fa9ad42012-07-16 12:18:23 -070095import java.io.PrintWriter;
destradaaea8a8a62014-06-23 18:19:03 -070096import java.net.InetAddress;
97import java.net.UnknownHostException;
Wyatt Rileycf879db2017-01-12 13:57:38 -080098import java.util.ArrayList;
Andreas Gampee6748ce2015-12-11 18:00:38 -080099import java.util.Arrays;
Yu-Han Yange7baef32018-02-09 13:58:17 -0800100import java.util.HashMap;
Wyatt Rileycf879db2017-01-12 13:57:38 -0800101import java.util.List;
Yu-Han Yange7baef32018-02-09 13:58:17 -0800102import java.util.Map;
Danke Xie22d1f9f2009-08-18 18:28:45 -0400103import java.util.Map.Entry;
Jake Hambyb49a73d2011-03-15 20:09:46 -0700104import java.util.Properties;
Yu-Han Yange7baef32018-02-09 13:58:17 -0800105
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800106/**
gomo4402af62017-01-11 13:20:13 -0800107 * A GNSS implementation of LocationProvider used by LocationManager.
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800108 *
109 * {@hide}
110 */
Yu-Han Yang66c7ea92018-03-11 17:17:15 -0700111public class GnssLocationProvider implements LocationProviderInterface, InjectNtpTimeCallback,
112 GnssSatelliteBlacklistCallback {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800113
Lifu Tang30f95a72016-01-07 23:20:38 -0800114 private static final String TAG = "GnssLocationProvider";
Mike Lockwood29c84342009-05-06 14:01:15 -0400115
Brian Muramatsu1715cb32012-08-08 17:32:21 -0700116 private static final boolean DEBUG = Log.isLoggable(TAG, Log.DEBUG);
117 private static final boolean VERBOSE = Log.isLoggable(TAG, Log.VERBOSE);
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400118
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700119 private static final ProviderProperties PROPERTIES = new ProviderProperties(
120 true, true, false, false, true, true, true,
121 Criteria.POWER_HIGH, Criteria.ACCURACY_FINE);
122
gomo4402af62017-01-11 13:20:13 -0800123 // these need to match GnssPositionMode enum in IGnss.hal
The Android Open Source Project10592532009-03-18 17:39:46 -0700124 private static final int GPS_POSITION_MODE_STANDALONE = 0;
125 private static final int GPS_POSITION_MODE_MS_BASED = 1;
126 private static final int GPS_POSITION_MODE_MS_ASSISTED = 2;
127
gomo4402af62017-01-11 13:20:13 -0800128 // these need to match GnssPositionRecurrence enum in IGnss.hal
Mike Lockwood04598b62010-04-14 17:17:24 -0400129 private static final int GPS_POSITION_RECURRENCE_PERIODIC = 0;
130 private static final int GPS_POSITION_RECURRENCE_SINGLE = 1;
131
gomo4402af62017-01-11 13:20:13 -0800132 // these need to match GnssStatusValue enum in IGnssCallback.hal
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800133 private static final int GPS_STATUS_NONE = 0;
134 private static final int GPS_STATUS_SESSION_BEGIN = 1;
135 private static final int GPS_STATUS_SESSION_END = 2;
136 private static final int GPS_STATUS_ENGINE_ON = 3;
137 private static final int GPS_STATUS_ENGINE_OFF = 4;
138
gomo4402af62017-01-11 13:20:13 -0800139 // these need to match AGnssStatusValue enum in IAGnssCallback.hal
Mike Lockwoode3635c92009-05-11 08:38:02 -0400140 /** AGPS status event values. */
141 private static final int GPS_REQUEST_AGPS_DATA_CONN = 1;
142 private static final int GPS_RELEASE_AGPS_DATA_CONN = 2;
143 private static final int GPS_AGPS_DATA_CONNECTED = 3;
144 private static final int GPS_AGPS_DATA_CONN_DONE = 4;
145 private static final int GPS_AGPS_DATA_CONN_FAILED = 5;
Mike Lockwood58bda982009-04-14 16:25:07 -0400146
gomo4402af62017-01-11 13:20:13 -0800147 // these need to match GnssLocationFlags enum in types.hal
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800148 private static final int LOCATION_INVALID = 0;
149 private static final int LOCATION_HAS_LAT_LONG = 1;
150 private static final int LOCATION_HAS_ALTITUDE = 2;
151 private static final int LOCATION_HAS_SPEED = 4;
152 private static final int LOCATION_HAS_BEARING = 8;
gomo4402af62017-01-11 13:20:13 -0800153 private static final int LOCATION_HAS_HORIZONTAL_ACCURACY = 16;
154 private static final int LOCATION_HAS_VERTICAL_ACCURACY = 32;
155 private static final int LOCATION_HAS_SPEED_ACCURACY = 64;
156 private static final int LOCATION_HAS_BEARING_ACCURACY = 128;
Mike Lockwoode3635c92009-05-11 08:38:02 -0400157
gomo4402af62017-01-11 13:20:13 -0800158
159 // IMPORTANT - the GPS_DELETE_* symbols here must match GnssAidingData enum in IGnss.hal
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800160 private static final int GPS_DELETE_EPHEMERIS = 0x0001;
161 private static final int GPS_DELETE_ALMANAC = 0x0002;
162 private static final int GPS_DELETE_POSITION = 0x0004;
163 private static final int GPS_DELETE_TIME = 0x0008;
164 private static final int GPS_DELETE_IONO = 0x0010;
165 private static final int GPS_DELETE_UTC = 0x0020;
166 private static final int GPS_DELETE_HEALTH = 0x0040;
167 private static final int GPS_DELETE_SVDIR = 0x0080;
168 private static final int GPS_DELETE_SVSTEER = 0x0100;
169 private static final int GPS_DELETE_SADATA = 0x0200;
170 private static final int GPS_DELETE_RTI = 0x0400;
171 private static final int GPS_DELETE_CELLDB_INFO = 0x8000;
172 private static final int GPS_DELETE_ALL = 0xFFFF;
173
gomo4402af62017-01-11 13:20:13 -0800174 // The GPS_CAPABILITY_* flags must match Capabilities enum in IGnssCallback.hal
Mike Lockwood04598b62010-04-14 17:17:24 -0400175 private static final int GPS_CAPABILITY_SCHEDULING = 0x0000001;
176 private static final int GPS_CAPABILITY_MSB = 0x0000002;
177 private static final int GPS_CAPABILITY_MSA = 0x0000004;
178 private static final int GPS_CAPABILITY_SINGLE_SHOT = 0x0000008;
Mike Lockwood9b9fb5c2011-06-29 15:09:40 -0400179 private static final int GPS_CAPABILITY_ON_DEMAND_TIME = 0x0000010;
destradaa6568d702014-10-27 12:47:41 -0700180 private static final int GPS_CAPABILITY_GEOFENCING = 0x0000020;
181 private static final int GPS_CAPABILITY_MEASUREMENTS = 0x0000040;
182 private static final int GPS_CAPABILITY_NAV_MESSAGES = 0x0000080;
Mike Lockwood04598b62010-04-14 17:17:24 -0400183
Tsuwei Chen462bcd82014-09-17 12:28:49 -0700184 // The AGPS SUPL mode
185 private static final int AGPS_SUPL_MODE_MSA = 0x02;
186 private static final int AGPS_SUPL_MODE_MSB = 0x01;
187
gomo4402af62017-01-11 13:20:13 -0800188 // these need to match AGnssType enum in IAGnssCallback.hal
Mike Lockwoode3635c92009-05-11 08:38:02 -0400189 private static final int AGPS_TYPE_SUPL = 1;
190 private static final int AGPS_TYPE_C2K = 2;
191
gomo4402af62017-01-11 13:20:13 -0800192 // these must match the ApnIpType enum in IAGnss.hal
destradaa96a14702014-06-05 11:36:30 -0700193 private static final int APN_INVALID = 0;
194 private static final int APN_IPV4 = 1;
195 private static final int APN_IPV6 = 2;
196 private static final int APN_IPV4V6 = 3;
197
Mike Lockwoode3635c92009-05-11 08:38:02 -0400198 // for mAGpsDataConnectionState
199 private static final int AGPS_DATA_CONNECTION_CLOSED = 0;
200 private static final int AGPS_DATA_CONNECTION_OPENING = 1;
201 private static final int AGPS_DATA_CONNECTION_OPEN = 2;
Mike Lockwood58bda982009-04-14 16:25:07 -0400202
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400203 // Handler messages
204 private static final int CHECK_LOCATION = 1;
205 private static final int ENABLE = 2;
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700206 private static final int SET_REQUEST = 3;
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400207 private static final int UPDATE_NETWORK_STATE = 4;
208 private static final int INJECT_NTP_TIME = 5;
209 private static final int DOWNLOAD_XTRA_DATA = 6;
Wyatt Rileyc7067412018-02-07 15:50:35 -0800210 private static final int UPDATE_LOCATION = 7; // Handle external location from network listener
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400211 private static final int ADD_LISTENER = 8;
212 private static final int REMOVE_LISTENER = 9;
Kevin Tang40e1baf2012-01-10 14:32:44 -0800213 private static final int DOWNLOAD_XTRA_DATA_FINISHED = 11;
destradaafb23c672015-04-16 14:01:27 -0700214 private static final int SUBSCRIPTION_OR_SIM_CHANGED = 12;
215 private static final int INITIALIZE_HANDLER = 13;
destradaae21252a2015-09-08 12:32:59 -0700216 private static final int REQUEST_SUPL_CONNECTION = 14;
217 private static final int RELEASE_SUPL_CONNECTION = 15;
Yu-Han Yange7baef32018-02-09 13:58:17 -0800218 private static final int REQUEST_LOCATION = 16;
Wyatt Riley26465d22018-02-12 13:44:24 -0800219 private static final int REPORT_LOCATION = 17; // HAL reports location
220 private static final int REPORT_SV_STATUS = 18; // HAL reports SV status
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400221
Miguel Torroja1e84da82010-07-27 07:02:24 +0200222 // Request setid
223 private static final int AGPS_RIL_REQUEST_SETID_IMSI = 1;
224 private static final int AGPS_RIL_REQUEST_SETID_MSISDN = 2;
225
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700226 //TODO(b/33112647): Create gps_debug.conf with commented career parameters.
227 private static final String DEBUG_PROPERTIES_FILE = "/etc/gps_debug.conf";
Miguel Torroja1e84da82010-07-27 07:02:24 +0200228
229 // ref. location info
230 private static final int AGPS_REF_LOCATION_TYPE_GSM_CELLID = 1;
231 private static final int AGPS_REF_LOCATION_TYPE_UMTS_CELLID = 2;
Miguel Torroja1e84da82010-07-27 07:02:24 +0200232
233 // set id info
234 private static final int AGPS_SETID_TYPE_NONE = 0;
235 private static final int AGPS_SETID_TYPE_IMSI = 1;
236 private static final int AGPS_SETID_TYPE_MSISDN = 2;
237
gomo48f1a642017-11-10 20:35:46 -0800238 private static final int GPS_GEOFENCE_UNAVAILABLE = 1 << 0L;
239 private static final int GPS_GEOFENCE_AVAILABLE = 1 << 1L;
destradaa0682809a2013-08-12 18:50:30 -0700240
gomo4402af62017-01-11 13:20:13 -0800241 // GPS Geofence errors. Should match GeofenceStatus enum in IGnssGeofenceCallback.hal.
destradaa0682809a2013-08-12 18:50:30 -0700242 private static final int GPS_GEOFENCE_OPERATION_SUCCESS = 0;
243 private static final int GPS_GEOFENCE_ERROR_TOO_MANY_GEOFENCES = 100;
gomo48f1a642017-11-10 20:35:46 -0800244 private static final int GPS_GEOFENCE_ERROR_ID_EXISTS = -101;
destradaa0682809a2013-08-12 18:50:30 -0700245 private static final int GPS_GEOFENCE_ERROR_ID_UNKNOWN = -102;
246 private static final int GPS_GEOFENCE_ERROR_INVALID_TRANSITION = -103;
247 private static final int GPS_GEOFENCE_ERROR_GENERIC = -149;
248
Tsuwei Chen678c13c2014-09-22 17:48:41 -0700249 // TCP/IP constants.
250 // Valid TCP/UDP port range is (0, 65535].
251 private static final int TCP_MIN_PORT = 0;
252 private static final int TCP_MAX_PORT = 0xffff;
253
Yu-Han Yange7baef32018-02-09 13:58:17 -0800254 // 1 second, or 1 Hz frequency.
255 private static final long LOCATION_UPDATE_MIN_TIME_INTERVAL_MILLIS = 1000;
Yu-Han Yang639f7592018-06-07 11:58:52 -0700256 // Default update duration in milliseconds for REQUEST_LOCATION.
Yu-Han Yang9e2a8232018-06-14 12:10:08 -0700257 private static final long LOCATION_UPDATE_DURATION_MILLIS = 10 * 1000;
Yu-Han Yange7baef32018-02-09 13:58:17 -0800258
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700259 /** simpler wrapper for ProviderRequest + Worksource */
260 private static class GpsRequest {
261 public ProviderRequest request;
262 public WorkSource source;
gomo48f1a642017-11-10 20:35:46 -0800263
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700264 public GpsRequest(ProviderRequest request, WorkSource source) {
265 this.request = request;
266 this.source = source;
267 }
268 }
269
Wyatt Riley26465d22018-02-12 13:44:24 -0800270 // Threadsafe class to hold stats reported in the Extras Bundle
Wyatt Rileyc7067412018-02-07 15:50:35 -0800271 private static class LocationExtras {
272 private int mSvCount;
273 private int mMeanCn0;
274 private int mMaxCn0;
275 private final Bundle mBundle;
276
277 public LocationExtras() {
278 mBundle = new Bundle();
279 }
280
281 public void set(int svCount, int meanCn0, int maxCn0) {
Wyatt Riley26465d22018-02-12 13:44:24 -0800282 synchronized(this) {
283 mSvCount = svCount;
284 mMeanCn0 = meanCn0;
285 mMaxCn0 = maxCn0;
286 }
Wyatt Rileyc7067412018-02-07 15:50:35 -0800287 setBundle(mBundle);
288 }
289
290 public void reset() {
291 set(0,0,0);
292 }
293
294 // Also used by outside methods to add to other bundles
295 public void setBundle(Bundle extras) {
296 if (extras != null) {
Wyatt Riley26465d22018-02-12 13:44:24 -0800297 synchronized (this) {
298 extras.putInt("satellites", mSvCount);
299 extras.putInt("meanCn0", mMeanCn0);
300 extras.putInt("maxCn0", mMaxCn0);
301 }
Wyatt Rileyc7067412018-02-07 15:50:35 -0800302 }
303 }
304
305 public Bundle getBundle() {
Wyatt Riley26465d22018-02-12 13:44:24 -0800306 synchronized (this) {
307 return new Bundle(mBundle);
308 }
Wyatt Rileyc7067412018-02-07 15:50:35 -0800309 }
310 }
311
Yu-Han Yang66c7ea92018-03-11 17:17:15 -0700312 private final Object mLock = new Object();
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700313
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800314 // current status
Mike Lockwood15e3d0f2009-05-01 07:53:28 -0400315 private int mStatus = LocationProvider.TEMPORARILY_UNAVAILABLE;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800316
317 // time for last status update
318 private long mStatusUpdateTime = SystemClock.elapsedRealtime();
Mike Lockwoodd53ba012010-04-15 20:41:26 -0400319
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800320 // turn off GPS fix icon if we haven't received a fix in 10 seconds
Mike Lockwood04598b62010-04-14 17:17:24 -0400321 private static final long RECENT_FIX_TIMEOUT = 10 * 1000;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800322
Mike Lockwood0632ca72009-05-14 15:51:03 -0400323 // stop trying if we do not receive a fix within 60 seconds
Mike Lockwood04598b62010-04-14 17:17:24 -0400324 private static final int NO_FIX_TIMEOUT = 60 * 1000;
Mike Lockwood0632ca72009-05-14 15:51:03 -0400325
Nick Pellyb041f232012-05-07 17:12:25 -0700326 // if the fix interval is below this we leave GPS on,
327 // if above then we cycle the GPS driver.
328 // Typical hot TTTF is ~5 seconds, so 10 seconds seems sane.
329 private static final int GPS_POLLING_THRESHOLD_INTERVAL = 10 * 1000;
330
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700331 // how long to wait if we have a network error in NTP or XTRA downloading
Wei Liu6f6326b2015-06-24 23:47:50 -0700332 // the initial value of the exponential backoff
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700333 // current setting - 5 minutes
gomo48f1a642017-11-10 20:35:46 -0800334 private static final long RETRY_INTERVAL = 5 * 60 * 1000;
Wei Liu6f6326b2015-06-24 23:47:50 -0700335 // how long to wait if we have a network error in NTP or XTRA downloading
336 // the max value of the exponential backoff
337 // current setting - 4 hours
gomo48f1a642017-11-10 20:35:46 -0800338 private static final long MAX_RETRY_INTERVAL = 4 * 60 * 60 * 1000;
Wei Liu6f6326b2015-06-24 23:47:50 -0700339
Wei Wangc5706f62017-04-18 11:26:26 -0700340 // Timeout when holding wakelocks for downloading XTRA data.
341 private static final long DOWNLOAD_XTRA_DATA_TIMEOUT_MS = 60 * 1000;
342
Yu-Han Yanga1862b52018-02-20 17:05:59 -0800343 private final ExponentialBackOff mXtraBackOff = new ExponentialBackOff(RETRY_INTERVAL,
344 MAX_RETRY_INTERVAL);
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700345
346 // true if we are enabled, protected by this
347 private boolean mEnabled;
348
Kevin Tang40e1baf2012-01-10 14:32:44 -0800349 // states for injecting ntp and downloading xtra data
350 private static final int STATE_PENDING_NETWORK = 0;
351 private static final int STATE_DOWNLOADING = 1;
352 private static final int STATE_IDLE = 2;
353
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400354 // flags to trigger NTP or XTRA data download when network becomes available
355 // initialized to true so we do NTP and XTRA when the network comes up after booting
Kevin Tang40e1baf2012-01-10 14:32:44 -0800356 private int mDownloadXtraDataPending = STATE_PENDING_NETWORK;
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400357
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800358 // true if GPS is navigating
359 private boolean mNavigating;
Mike Lockwoodcf1d8cb2010-01-20 10:14:54 -0500360
361 // true if GPS engine is on
362 private boolean mEngineOn;
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700363
Mike Lockwood04598b62010-04-14 17:17:24 -0400364 // requested frequency of fixes, in milliseconds
365 private int mFixInterval = 1000;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800366
gomo48f1a642017-11-10 20:35:46 -0800367 // true if low power mode for the GNSS chipset is part of the latest request.
368 private boolean mLowPowerMode = false;
369
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800370 // true if we started navigation
371 private boolean mStarted;
372
Stan Chesnutt1d72d8c2013-04-15 19:18:02 -0700373 // true if single shot request is in progress
374 private boolean mSingleShot;
375
Mike Lockwood04598b62010-04-14 17:17:24 -0400376 // capabilities of the GPS engine
377 private int mEngineCapabilities;
378
Mike Lockwood1a1cd3a2010-08-17 07:42:54 -0400379 // true if XTRA is supported
380 private boolean mSupportsXtra;
381
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800382 // for calculating time to first fix
383 private long mFixRequestTime = 0;
384 // time to first fix for most recent session
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700385 private int mTimeToFirstFix = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800386 // time we received our last fix
387 private long mLastFixTime;
388
Mike Lockwood04598b62010-04-14 17:17:24 -0400389 private int mPositionMode;
390
David Christied4edf4c2014-08-12 15:22:27 -0700391 // Current request from underlying location clients.
392 private ProviderRequest mProviderRequest = null;
Narayan Kamath32684dd2018-01-08 17:32:51 +0000393 // The WorkSource associated with the most recent client request (i.e, most recent call to
394 // setRequest).
David Christied4edf4c2014-08-12 15:22:27 -0700395 private WorkSource mWorkSource = null;
396 // True if gps should be disabled (used to support battery saver mode in settings).
397 private boolean mDisableGps = false;
398
destradaafb23c672015-04-16 14:01:27 -0700399 /**
400 * Properties loaded from PROPERTIES_FILE.
401 * It must be accessed only inside {@link #mHandler}.
402 */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800403 private Properties mProperties;
destradaafb23c672015-04-16 14:01:27 -0700404
Mike Lockwood734d6032009-07-28 18:30:25 -0700405 private String mSuplServerHost;
Tsuwei Chen678c13c2014-09-22 17:48:41 -0700406 private int mSuplServerPort = TCP_MIN_PORT;
Mike Lockwood734d6032009-07-28 18:30:25 -0700407 private String mC2KServerHost;
408 private int mC2KServerPort;
Tsuwei Chen3324e952014-09-07 01:30:42 -0700409 private boolean mSuplEsEnabled = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800410
Mike Lockwood15e3d0f2009-05-01 07:53:28 -0400411 private final Context mContext;
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700412 private final ILocationManager mILocationManager;
Wyatt Rileyc7067412018-02-07 15:50:35 -0800413 private final LocationExtras mLocationExtras = new LocationExtras();
Lifu Tang30f95a72016-01-07 23:20:38 -0800414 private final GnssStatusListenerHelper mListenerHelper;
Yu-Han Yang66c7ea92018-03-11 17:17:15 -0700415 private final GnssSatelliteBlacklistHelper mGnssSatelliteBlacklistHelper;
Lifu Tang818aa2c2016-02-01 01:52:00 -0800416 private final GnssMeasurementsProvider mGnssMeasurementsProvider;
417 private final GnssNavigationMessageProvider mGnssNavigationMessageProvider;
Yu-Han Yang07561382018-02-21 13:08:37 -0800418 private final LocationChangeListener mNetworkLocationListener = new NetworkLocationListener();
419 private final LocationChangeListener mFusedLocationListener = new FusedLocationListener();
Yu-Han Yanga1862b52018-02-20 17:05:59 -0800420 private final NtpTimeHelper mNtpTimeHelper;
Yu-Han Yang3557cc72018-03-21 12:48:36 -0700421 private final GnssBatchingProvider mGnssBatchingProvider;
Yu-Han Yang890ca8b2018-04-16 22:11:31 -0700422 private final GnssGeofenceProvider mGnssGeofenceProvider;
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400423
Victoria Lease5c24fd02012-10-01 11:00:50 -0700424 // Handler for processing events
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400425 private Handler mHandler;
The Android Open Source Project10592532009-03-18 17:39:46 -0700426
destradaae21252a2015-09-08 12:32:59 -0700427 /** It must be accessed only inside {@link #mHandler}. */
Mike Lockwoode3635c92009-05-11 08:38:02 -0400428 private int mAGpsDataConnectionState;
destradaae21252a2015-09-08 12:32:59 -0700429 /** It must be accessed only inside {@link #mHandler}. */
destradaa96a14702014-06-05 11:36:30 -0700430 private InetAddress mAGpsDataConnectionIpAddr;
destradaae21252a2015-09-08 12:32:59 -0700431
Mike Lockwood2f82c4e2009-04-17 08:24:10 -0400432 private final ConnectivityManager mConnMgr;
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700433 private final GpsNetInitiatedHandler mNIHandler;
Mike Lockwood2f82c4e2009-04-17 08:24:10 -0400434
Mike Lockwood0528b9b2009-05-07 10:12:54 -0400435 // Wakelocks
Lifu Tang30f95a72016-01-07 23:20:38 -0800436 private final static String WAKELOCK_KEY = "GnssLocationProvider";
Mike Lockwood0528b9b2009-05-07 10:12:54 -0400437 private final PowerManager.WakeLock mWakeLock;
Wei Wangb71c0492017-05-01 20:24:19 -0700438 private static final String DOWNLOAD_EXTRA_WAKELOCK_KEY = "GnssLocationProviderXtraDownload";
439 private final PowerManager.WakeLock mDownloadXtraWakeLock;
Mike Lockwood0528b9b2009-05-07 10:12:54 -0400440
Mike Lockwood29c84342009-05-06 14:01:15 -0400441 // Alarms
442 private final static String ALARM_WAKEUP = "com.android.internal.location.ALARM_WAKEUP";
Mike Lockwood0632ca72009-05-14 15:51:03 -0400443 private final static String ALARM_TIMEOUT = "com.android.internal.location.ALARM_TIMEOUT";
Tsuwei Chen52617bb2014-08-25 11:49:11 -0700444
445 // SIM/Carrier info.
446 private final static String SIM_STATE_CHANGED = "android.intent.action.SIM_STATE_CHANGED";
447
Ecco Park624ac3c2016-07-18 14:08:05 -0700448 // Persist property for LPP_PROFILE
449 private final static String LPP_PROFILE = "persist.sys.gps.lpp";
450
Ecco Park624ac3c2016-07-18 14:08:05 -0700451
David Christied4edf4c2014-08-12 15:22:27 -0700452 private final PowerManager mPowerManager;
Mike Lockwood29c84342009-05-06 14:01:15 -0400453 private final AlarmManager mAlarmManager;
454 private final PendingIntent mWakeupIntent;
Mike Lockwood0632ca72009-05-14 15:51:03 -0400455 private final PendingIntent mTimeoutIntent;
Mike Lockwood29c84342009-05-06 14:01:15 -0400456
Svet Ganovf7b47252018-02-26 11:11:27 -0800457 private final AppOpsManager mAppOps;
Mike Lockwood2f82c4e2009-04-17 08:24:10 -0400458 private final IBatteryStats mBatteryStats;
The Android Open Source Project10592532009-03-18 17:39:46 -0700459
Narayan Kamath32684dd2018-01-08 17:32:51 +0000460 // Current list of underlying location clients.
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700461 // only modified on handler thread
Dianne Hackborn002a54e2013-01-10 17:34:55 -0800462 private WorkSource mClientSource = new WorkSource();
Mike Lockwoodf1218be2010-01-29 09:20:06 -0500463
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -0700464 private GeofenceHardwareImpl mGeofenceHardwareImpl;
Wyatt Rileyd87cf912017-12-05 09:31:52 -0800465
466 // Volatile for simple inter-thread sync on these values.
467 private volatile int mHardwareYear = 0;
Wyatt Riley49097c02018-03-15 09:14:43 -0700468 private volatile String mHardwareModelName;
Lifu Tang82f893d2016-01-21 18:15:33 -0800469
Wyatt Riley5d5bac82016-11-01 07:05:16 -0700470 // Set lower than the current ITAR limit of 600m/s to allow this to trigger even if GPS HAL
471 // stops output right at 600m/s, depriving this of the information of a device that reaches
472 // greater than 600m/s, and higher than the speed of sound to avoid impacting most use cases.
473 private static final float ITAR_SPEED_LIMIT_METERS_PER_SECOND = 400.0F;
Wyatt Riley042c48f2017-10-06 14:59:25 -0700474
Wyatt Riley042c48f2017-10-06 14:59:25 -0700475 private volatile boolean mItarSpeedLimitExceeded = false;
Wyatt Riley5d5bac82016-11-01 07:05:16 -0700476
Siddharth Raybb608c82017-03-16 11:33:34 -0700477 // GNSS Metrics
478 private GnssMetrics mGnssMetrics;
479
Lifu Tang30f95a72016-01-07 23:20:38 -0800480 private final IGnssStatusProvider mGnssStatusProvider = new IGnssStatusProvider.Stub() {
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700481 @Override
Lifu Tang30f95a72016-01-07 23:20:38 -0800482 public void registerGnssStatusCallback(IGnssStatusListener callback) {
483 mListenerHelper.addListener(callback);
Mike Lockwood15e3d0f2009-05-01 07:53:28 -0400484 }
485
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700486 @Override
Lifu Tang30f95a72016-01-07 23:20:38 -0800487 public void unregisterGnssStatusCallback(IGnssStatusListener callback) {
488 mListenerHelper.removeListener(callback);
destradaaea8a8a62014-06-23 18:19:03 -0700489 }
490 };
Mike Lockwood15e3d0f2009-05-01 07:53:28 -0400491
Lifu Tang30f95a72016-01-07 23:20:38 -0800492 public IGnssStatusProvider getGnssStatusProvider() {
493 return mGnssStatusProvider;
Mike Lockwood15e3d0f2009-05-01 07:53:28 -0400494 }
495
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -0700496 public IGpsGeofenceHardware getGpsGeofenceProxy() {
Yu-Han Yang890ca8b2018-04-16 22:11:31 -0700497 return mGnssGeofenceProvider;
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -0700498 }
499
Lifu Tang818aa2c2016-02-01 01:52:00 -0800500 public GnssMeasurementsProvider getGnssMeasurementsProvider() {
501 return mGnssMeasurementsProvider;
destradaaea8a8a62014-06-23 18:19:03 -0700502 }
503
Lifu Tang818aa2c2016-02-01 01:52:00 -0800504 public GnssNavigationMessageProvider getGnssNavigationMessageProvider() {
505 return mGnssNavigationMessageProvider;
destradaa4b3e3932014-07-21 18:01:47 -0700506 }
507
destradaae21252a2015-09-08 12:32:59 -0700508 /**
509 * Callback used to listen for data connectivity changes.
510 */
511 private final ConnectivityManager.NetworkCallback mNetworkConnectivityCallback =
512 new ConnectivityManager.NetworkCallback() {
gomo48f1a642017-11-10 20:35:46 -0800513 @Override
514 public void onAvailable(Network network) {
Yu-Han Yanga1862b52018-02-20 17:05:59 -0800515 mNtpTimeHelper.onNetworkAvailable();
gomo48f1a642017-11-10 20:35:46 -0800516 if (mDownloadXtraDataPending == STATE_PENDING_NETWORK) {
517 if (mSupportsXtra) {
518 // Download only if supported, (prevents an unneccesary on-boot
519 // download)
520 xtraDownloadRequest();
521 }
522 }
523 // Always on, notify HAL so it can get data it needs
524 sendMessage(UPDATE_NETWORK_STATE, 0 /*arg*/, network);
Wyatt Rileyabc69ea2017-08-08 15:15:28 -0700525 }
Kevin Tang71ad5fe2017-05-10 19:36:20 -0700526
gomo48f1a642017-11-10 20:35:46 -0800527 @Override
528 public void onLost(Network network) {
529 sendMessage(UPDATE_NETWORK_STATE, 0 /*arg*/, network);
530 }
531 };
destradaae21252a2015-09-08 12:32:59 -0700532
533 /**
534 * Callback used to listen for availability of a requested SUPL connection.
535 * It is kept as a separate instance from {@link #mNetworkConnectivityCallback} to be able to
536 * manage the registration/un-registration lifetimes separate.
537 */
538 private final ConnectivityManager.NetworkCallback mSuplConnectivityCallback =
539 new ConnectivityManager.NetworkCallback() {
gomo48f1a642017-11-10 20:35:46 -0800540 @Override
541 public void onAvailable(Network network) {
542 // Specific to a change to a SUPL enabled network becoming ready
543 sendMessage(UPDATE_NETWORK_STATE, 0 /*arg*/, network);
544 }
Wyatt Riley41f6bce2016-12-13 10:45:29 -0800545
gomo48f1a642017-11-10 20:35:46 -0800546 @Override
547 public void onLost(Network network) {
548 releaseSuplConnection(GPS_RELEASE_AGPS_DATA_CONN);
549 }
550 };
destradaae21252a2015-09-08 12:32:59 -0700551
Tsuwei Chen52617bb2014-08-25 11:49:11 -0700552 private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
gomo48f1a642017-11-10 20:35:46 -0800553 @Override
554 public void onReceive(Context context, Intent intent) {
The Android Open Source Project10592532009-03-18 17:39:46 -0700555 String action = intent.getAction();
Tsuwei Chen48d37f92014-09-05 15:15:34 -0700556 if (DEBUG) Log.d(TAG, "receive broadcast intent, action: " + action);
destradaaee9fd342015-08-31 13:31:17 -0700557 if (action == null) {
558 return;
559 }
560
Mike Lockwood29c84342009-05-06 14:01:15 -0400561 if (action.equals(ALARM_WAKEUP)) {
Stan Chesnutt1d72d8c2013-04-15 19:18:02 -0700562 startNavigating(false);
Mike Lockwood0632ca72009-05-14 15:51:03 -0400563 } else if (action.equals(ALARM_TIMEOUT)) {
Mike Lockwood0632ca72009-05-14 15:51:03 -0400564 hibernate();
David Christied4edf4c2014-08-12 15:22:27 -0700565 } else if (PowerManager.ACTION_POWER_SAVE_MODE_CHANGED.equals(action)
Adam Lesinski87c17df2015-05-27 13:24:13 -0700566 || PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED.equals(action)
David Christied4edf4c2014-08-12 15:22:27 -0700567 || Intent.ACTION_SCREEN_OFF.equals(action)
568 || Intent.ACTION_SCREEN_ON.equals(action)) {
569 updateLowPowerMode();
Wink Savillea374c3d2014-11-11 11:48:04 -0800570 } else if (action.equals(SIM_STATE_CHANGED)) {
571 subscriptionOrSimChanged(context);
David Christied4edf4c2014-08-12 15:22:27 -0700572 }
The Android Open Source Project10592532009-03-18 17:39:46 -0700573 }
Mike Lockwood29c84342009-05-06 14:01:15 -0400574 };
The Android Open Source Project10592532009-03-18 17:39:46 -0700575
Wink Savilled09c4ca2014-11-22 10:08:16 -0800576 private final OnSubscriptionsChangedListener mOnSubscriptionsChangedListener =
577 new OnSubscriptionsChangedListener() {
gomo48f1a642017-11-10 20:35:46 -0800578 @Override
579 public void onSubscriptionsChanged() {
580 sendMessage(SUBSCRIPTION_OR_SIM_CHANGED, 0, null);
581 }
582 };
Wink Savillea374c3d2014-11-11 11:48:04 -0800583
Yu-Han Yang66c7ea92018-03-11 17:17:15 -0700584 /**
585 * Implements {@link GnssSatelliteBlacklistCallback#onUpdateSatelliteBlacklist}.
586 */
587 @Override
588 public void onUpdateSatelliteBlacklist(int[] constellations, int[] svids) {
589 mHandler.post(()->{
590 native_set_satellite_blacklist(constellations, svids);
591 });
592 }
593
Wink Savillea374c3d2014-11-11 11:48:04 -0800594 private void subscriptionOrSimChanged(Context context) {
Joe Onorato0c484102016-02-01 18:04:24 -0800595 if (DEBUG) Log.d(TAG, "received SIM related action: ");
Wink Savillea374c3d2014-11-11 11:48:04 -0800596 TelephonyManager phone = (TelephonyManager)
597 mContext.getSystemService(Context.TELEPHONY_SERVICE);
Ecco Park4fa1ab72016-10-24 13:04:52 -0700598 CarrierConfigManager configManager = (CarrierConfigManager)
599 mContext.getSystemService(Context.CARRIER_CONFIG_SERVICE);
Wink Savillea374c3d2014-11-11 11:48:04 -0800600 String mccMnc = phone.getSimOperator();
Ecco Park4fa1ab72016-10-24 13:04:52 -0700601 boolean isKeepLppProfile = false;
Wink Savillea374c3d2014-11-11 11:48:04 -0800602 if (!TextUtils.isEmpty(mccMnc)) {
Joe Onorato0c484102016-02-01 18:04:24 -0800603 if (DEBUG) Log.d(TAG, "SIM MCC/MNC is available: " + mccMnc);
Wink Savillea374c3d2014-11-11 11:48:04 -0800604 synchronized (mLock) {
Ecco Park4fa1ab72016-10-24 13:04:52 -0700605 if (configManager != null) {
606 PersistableBundle b = configManager.getConfig();
Wyatt Rileya8ce2252017-09-01 13:31:17 -0700607 if (b != null) {
608 isKeepLppProfile =
609 b.getBoolean(CarrierConfigManager.KEY_PERSIST_LPP_MODE_BOOL);
610 }
Ecco Park4fa1ab72016-10-24 13:04:52 -0700611 }
612 if (isKeepLppProfile) {
613 // load current properties for the carrier
614 loadPropertiesFromResource(context, mProperties);
615 String lpp_profile = mProperties.getProperty("LPP_PROFILE");
616 // set the persist property LPP_PROFILE for the value
Ecco Park8eec7442017-08-04 16:21:59 -0700617 if (lpp_profile != null) {
618 SystemProperties.set(LPP_PROFILE, lpp_profile);
619 }
Ecco Park624ac3c2016-07-18 14:08:05 -0700620 } else {
Ecco Park4fa1ab72016-10-24 13:04:52 -0700621 // reset the persist property
622 SystemProperties.set(LPP_PROFILE, "");
Ecco Park624ac3c2016-07-18 14:08:05 -0700623 }
Wink Savillea374c3d2014-11-11 11:48:04 -0800624 reloadGpsProperties(context, mProperties);
625 mNIHandler.setSuplEsEnabled(mSuplEsEnabled);
626 }
627 } else {
Joe Onorato0c484102016-02-01 18:04:24 -0800628 if (DEBUG) Log.d(TAG, "SIM MCC/MNC is still not available");
Wink Savillea374c3d2014-11-11 11:48:04 -0800629 }
630 }
631
David Christied4edf4c2014-08-12 15:22:27 -0700632 private void updateLowPowerMode() {
Adam Lesinski87c17df2015-05-27 13:24:13 -0700633 // Disable GPS if we are in device idle mode.
634 boolean disableGps = mPowerManager.isDeviceIdleMode();
jackqdyulei455e90a2017-02-09 15:29:16 -0800635 final PowerSaveState result =
636 mPowerManager.getPowerSaveState(ServiceType.GPS);
637 switch (result.gpsMode) {
Makoto Onuki57f0f552017-12-11 12:22:18 -0800638 case PowerManager.LOCATION_MODE_GPS_DISABLED_WHEN_SCREEN_OFF:
Adam Lesinski87c17df2015-05-27 13:24:13 -0700639 // If we are in battery saver mode and the screen is off, disable GPS.
jackqdyulei455e90a2017-02-09 15:29:16 -0800640 disableGps |= result.batterySaverEnabled && !mPowerManager.isInteractive();
David Christied4edf4c2014-08-12 15:22:27 -0700641 break;
David Christied4edf4c2014-08-12 15:22:27 -0700642 }
643 if (disableGps != mDisableGps) {
644 mDisableGps = disableGps;
645 updateRequirements();
646 }
647 }
648
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800649 public static boolean isSupported() {
650 return native_is_supported();
651 }
652
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700653 interface SetCarrierProperty {
654 public boolean set(int value);
655 }
656
Tsuwei Chen52617bb2014-08-25 11:49:11 -0700657 private void reloadGpsProperties(Context context, Properties properties) {
Joe Onorato0c484102016-02-01 18:04:24 -0800658 if (DEBUG) Log.d(TAG, "Reset GPS properties, previous size = " + properties.size());
Tsuwei Chen52617bb2014-08-25 11:49:11 -0700659 loadPropertiesFromResource(context, properties);
Ecco Park624ac3c2016-07-18 14:08:05 -0700660
Ecco Park624ac3c2016-07-18 14:08:05 -0700661 String lpp_prof = SystemProperties.get(LPP_PROFILE);
662 if (!TextUtils.isEmpty(lpp_prof)) {
gomo48f1a642017-11-10 20:35:46 -0800663 // override default value of this if lpp_prof is not empty
664 properties.setProperty("LPP_PROFILE", lpp_prof);
Ecco Park624ac3c2016-07-18 14:08:05 -0700665 }
Wyatt Riley3e1cd0b2017-04-19 17:57:14 -0700666 /*
667 * Overlay carrier properties from a debug configuration file.
668 */
669 loadPropertiesFromFile(DEBUG_PROPERTIES_FILE, properties);
Tsuwei Chen52617bb2014-08-25 11:49:11 -0700670 // TODO: we should get rid of C2K specific setting.
671 setSuplHostPort(properties.getProperty("SUPL_HOST"),
gomo48f1a642017-11-10 20:35:46 -0800672 properties.getProperty("SUPL_PORT"));
Tsuwei Chen52617bb2014-08-25 11:49:11 -0700673 mC2KServerHost = properties.getProperty("C2K_HOST");
674 String portString = properties.getProperty("C2K_PORT");
675 if (mC2KServerHost != null && portString != null) {
676 try {
677 mC2KServerPort = Integer.parseInt(portString);
678 } catch (NumberFormatException e) {
679 Log.e(TAG, "unable to parse C2K_PORT: " + portString);
680 }
681 }
destradaaef752b62015-04-17 13:10:47 -0700682 if (native_is_gnss_configuration_supported()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700683 Map<String, SetCarrierProperty> map = new HashMap<String, SetCarrierProperty>() {
684 {
685 put("SUPL_VER", (val) -> native_set_supl_version(val));
686 put("SUPL_MODE", (val) -> native_set_supl_mode(val));
687 put("SUPL_ES", (val) -> native_set_supl_es(val));
688 put("LPP_PROFILE", (val) -> native_set_lpp_profile(val));
gomo48f1a642017-11-10 20:35:46 -0800689 put("A_GLONASS_POS_PROTOCOL_SELECT",
690 (val) -> native_set_gnss_pos_protocol_select(val));
691 put("USE_EMERGENCY_PDN_FOR_EMERGENCY_SUPL",
692 (val) -> native_set_emergency_supl_pdn(val));
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700693 put("GPS_LOCK", (val) -> native_set_gps_lock(val));
694 }
695 };
696
gomo48f1a642017-11-10 20:35:46 -0800697 for (Entry<String, SetCarrierProperty> entry : map.entrySet()) {
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700698 String propertyName = entry.getKey();
699 String propertyValueString = properties.getProperty(propertyName);
700 if (propertyValueString != null) {
701 try {
gomo48f1a642017-11-10 20:35:46 -0800702 int propertyValueInt = Integer.decode(propertyValueString);
703 boolean result = entry.getValue().set(propertyValueInt);
704 if (result == false) {
705 Log.e(TAG, "Unable to set " + propertyName);
706 }
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700707 } catch (NumberFormatException e) {
gomo48f1a642017-11-10 20:35:46 -0800708 Log.e(TAG, "unable to parse propertyName: " + propertyValueString);
Hridya Valsaraju2ea29602016-09-13 08:38:09 -0700709 }
710 }
destradaaef752b62015-04-17 13:10:47 -0700711 }
712 } else if (DEBUG) {
713 Log.d(TAG, "Skipped configuration update because GNSS configuration in GPS HAL is not"
714 + " supported");
Tsuwei Chen52617bb2014-08-25 11:49:11 -0700715 }
Tsuwei Chen3324e952014-09-07 01:30:42 -0700716
717 // SUPL_ES configuration.
718 String suplESProperty = mProperties.getProperty("SUPL_ES");
719 if (suplESProperty != null) {
720 try {
721 mSuplEsEnabled = (Integer.parseInt(suplESProperty) == 1);
722 } catch (NumberFormatException e) {
723 Log.e(TAG, "unable to parse SUPL_ES: " + suplESProperty);
724 }
725 }
Tsuwei Chen52617bb2014-08-25 11:49:11 -0700726 }
727
728 private void loadPropertiesFromResource(Context context,
gomo48f1a642017-11-10 20:35:46 -0800729 Properties properties) {
Tsuwei Chen52617bb2014-08-25 11:49:11 -0700730 String[] configValues = context.getResources().getStringArray(
731 com.android.internal.R.array.config_gpsParameters);
732 for (String item : configValues) {
Joe Onorato0c484102016-02-01 18:04:24 -0800733 if (DEBUG) Log.d(TAG, "GpsParamsResource: " + item);
Tsuwei Chen7c485bf2014-09-10 15:33:34 -0700734 // We need to support "KEY =", but not "=VALUE".
Zheng Zhangad48bd92017-10-16 10:27:28 -0700735 int index = item.indexOf("=");
736 if (index > 0 && index + 1 < item.length()) {
737 String key = item.substring(0, index);
738 String value = item.substring(index + 1);
739 properties.setProperty(key.trim().toUpperCase(), value);
Tsuwei Chen52617bb2014-08-25 11:49:11 -0700740 } else {
741 Log.w(TAG, "malformed contents: " + item);
742 }
743 }
744 }
745
746 private boolean loadPropertiesFromFile(String filename,
gomo48f1a642017-11-10 20:35:46 -0800747 Properties properties) {
Colin Cross7c030ed2014-01-28 09:33:53 -0800748 try {
749 File file = new File(filename);
750 FileInputStream stream = null;
751 try {
752 stream = new FileInputStream(file);
Tsuwei Chen52617bb2014-08-25 11:49:11 -0700753 properties.load(stream);
Colin Cross7c030ed2014-01-28 09:33:53 -0800754 } finally {
755 IoUtils.closeQuietly(stream);
756 }
757
Colin Cross7c030ed2014-01-28 09:33:53 -0800758 } catch (IOException e) {
Wyatt Riley3e1cd0b2017-04-19 17:57:14 -0700759 if (DEBUG) Log.d(TAG, "Could not open GPS configuration file " + filename);
Colin Cross7c030ed2014-01-28 09:33:53 -0800760 return false;
761 }
762 return true;
763 }
764
Lifu Tang30f95a72016-01-07 23:20:38 -0800765 public GnssLocationProvider(Context context, ILocationManager ilocationManager,
Victoria Lease5cd731a2012-12-19 15:04:21 -0800766 Looper looper) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800767 mContext = context;
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700768 mILocationManager = ilocationManager;
Mike Lockwood63598a02010-02-24 11:52:59 -0500769
Mike Lockwood0528b9b2009-05-07 10:12:54 -0400770 // Create a wake lock
David Christied4edf4c2014-08-12 15:22:27 -0700771 mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
772 mWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, WAKELOCK_KEY);
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700773 mWakeLock.setReferenceCounted(true);
Mike Lockwood0528b9b2009-05-07 10:12:54 -0400774
Wei Wangb71c0492017-05-01 20:24:19 -0700775 // Create a separate wake lock for xtra downloader as it may be released due to timeout.
776 mDownloadXtraWakeLock = mPowerManager.newWakeLock(
777 PowerManager.PARTIAL_WAKE_LOCK, DOWNLOAD_EXTRA_WAKELOCK_KEY);
778 mDownloadXtraWakeLock.setReferenceCounted(true);
779
gomo48f1a642017-11-10 20:35:46 -0800780 mAlarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
Mike Lockwood29c84342009-05-06 14:01:15 -0400781 mWakeupIntent = PendingIntent.getBroadcast(mContext, 0, new Intent(ALARM_WAKEUP), 0);
Mike Lockwood0632ca72009-05-14 15:51:03 -0400782 mTimeoutIntent = PendingIntent.getBroadcast(mContext, 0, new Intent(ALARM_TIMEOUT), 0);
Mike Lockwood29c84342009-05-06 14:01:15 -0400783
gomo48f1a642017-11-10 20:35:46 -0800784 mConnMgr = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
Mike Lockwood58bda982009-04-14 16:25:07 -0400785
Dianne Hackborna06de0f2012-12-11 16:34:47 -0800786 // App ops service to keep track of who is accessing the GPS
Svet Ganovf7b47252018-02-26 11:11:27 -0800787 mAppOps = mContext.getSystemService(AppOpsManager.class);
Dianne Hackborna06de0f2012-12-11 16:34:47 -0800788
Mike Lockwood2f82c4e2009-04-17 08:24:10 -0400789 // Battery statistics service to be notified when GPS turns on or off
Dianne Hackborn91268cf2013-06-13 19:06:50 -0700790 mBatteryStats = IBatteryStats.Stub.asInterface(ServiceManager.getService(
791 BatteryStats.SERVICE_NAME));
Mike Lockwood2f82c4e2009-04-17 08:24:10 -0400792
destradaafb23c672015-04-16 14:01:27 -0700793 // Construct internal handler
794 mHandler = new ProviderHandler(looper);
795
796 // Load GPS configuration and register listeners in the background:
797 // some operations, such as opening files and registering broadcast receivers, can take a
798 // relative long time, so the ctor() is kept to create objects needed by this instance,
799 // while IO initialization and registration is delegated to our internal handler
800 // this approach is just fine because events are posted to our handler anyway
Tsuwei Chen52617bb2014-08-25 11:49:11 -0700801 mProperties = new Properties();
destradaafb23c672015-04-16 14:01:27 -0700802 sendMessage(INITIALIZE_HANDLER, 0, null);
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400803
Tsuwei Chen3324e952014-09-07 01:30:42 -0700804 // Create a GPS net-initiated handler.
805 mNIHandler = new GpsNetInitiatedHandler(context,
gomo48f1a642017-11-10 20:35:46 -0800806 mNetInitiatedListener,
807 mSuplEsEnabled);
Tsuwei Chen3324e952014-09-07 01:30:42 -0700808
Lifu Tang30f95a72016-01-07 23:20:38 -0800809 mListenerHelper = new GnssStatusListenerHelper(mHandler) {
destradaa6568d702014-10-27 12:47:41 -0700810 @Override
811 protected boolean isAvailableInPlatform() {
destradaa13a60b02015-01-15 18:36:01 -0800812 return isSupported();
destradaa6568d702014-10-27 12:47:41 -0700813 }
814
815 @Override
816 protected boolean isGpsEnabled() {
817 return isEnabled();
818 }
819 };
820
Yu-Han Yang8de21502018-04-23 01:40:25 -0700821 mGnssMeasurementsProvider = new GnssMeasurementsProvider(mContext, mHandler) {
destradaa6568d702014-10-27 12:47:41 -0700822 @Override
823 protected boolean isGpsEnabled() {
824 return isEnabled();
825 }
826 };
827
Lifu Tang818aa2c2016-02-01 01:52:00 -0800828 mGnssNavigationMessageProvider = new GnssNavigationMessageProvider(mHandler) {
destradaa6568d702014-10-27 12:47:41 -0700829 @Override
destradaa6568d702014-10-27 12:47:41 -0700830 protected boolean isGpsEnabled() {
831 return isEnabled();
832 }
833 };
Siddharth Ray78ccaf52017-12-23 16:16:21 -0800834 mGnssMetrics = new GnssMetrics(mBatteryStats);
Yu-Han Yanga1862b52018-02-20 17:05:59 -0800835
Yu-Han Yang66c7ea92018-03-11 17:17:15 -0700836 mNtpTimeHelper = new NtpTimeHelper(mContext, looper, this);
837 mGnssSatelliteBlacklistHelper = new GnssSatelliteBlacklistHelper(mContext,
838 looper, this);
839 mHandler.post(mGnssSatelliteBlacklistHelper::updateSatelliteBlacklist);
Yu-Han Yang3557cc72018-03-21 12:48:36 -0700840 mGnssBatchingProvider = new GnssBatchingProvider();
Yu-Han Yang890ca8b2018-04-16 22:11:31 -0700841 mGnssGeofenceProvider = new GnssGeofenceProvider(looper);
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400842 }
843
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800844 /**
Mike Lockwoodd03ff942010-02-09 08:46:14 -0500845 * Returns the name of this provider.
846 */
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700847 @Override
Mike Lockwoodd03ff942010-02-09 08:46:14 -0500848 public String getName() {
849 return LocationManager.GPS_PROVIDER;
850 }
851
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700852 @Override
853 public ProviderProperties getProperties() {
854 return PROPERTIES;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800855 }
856
Yu-Han Yanga1862b52018-02-20 17:05:59 -0800857
858 /**
859 * Implements {@link InjectNtpTimeCallback#injectTime}
860 */
861 @Override
862 public void injectTime(long time, long timeReference, int uncertainty) {
863 native_inject_time(time, timeReference, uncertainty);
864 }
865
destradaae21252a2015-09-08 12:32:59 -0700866 private void handleUpdateNetworkState(Network network) {
867 // retrieve NetworkInfo for this UID
868 NetworkInfo info = mConnMgr.getNetworkInfo(network);
Kevin Tang71ad5fe2017-05-10 19:36:20 -0700869
870 boolean networkAvailable = false;
871 boolean isConnected = false;
872 int type = ConnectivityManager.TYPE_NONE;
873 boolean isRoaming = false;
874 String apnName = null;
875
876 if (info != null) {
877 networkAvailable = info.isAvailable() && TelephonyManager.getDefault().getDataEnabled();
878 isConnected = info.isConnected();
879 type = info.getType();
880 isRoaming = info.isRoaming();
881 apnName = info.getExtraInfo();
destradaae21252a2015-09-08 12:32:59 -0700882 }
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400883
Joe Onoratof5d95cb2010-01-07 21:48:32 -0500884 if (DEBUG) {
destradaae21252a2015-09-08 12:32:59 -0700885 String message = String.format(
886 "UpdateNetworkState, state=%s, connected=%s, info=%s, capabilities=%S",
887 agpsDataConnStateAsString(),
888 isConnected,
889 info,
890 mConnMgr.getNetworkCapabilities(network));
891 Log.d(TAG, message);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800892 }
Mike Lockwood03d24672009-10-08 15:45:03 -0400893
destradaae21252a2015-09-08 12:32:59 -0700894 if (native_is_agps_ril_supported()) {
destradaae21252a2015-09-08 12:32:59 -0700895 String defaultApn = getSelectedApn();
896 if (defaultApn == null) {
897 defaultApn = "dummy-apn";
destradaaef752b62015-04-17 13:10:47 -0700898 }
destradaae21252a2015-09-08 12:32:59 -0700899
900 native_update_network_state(
901 isConnected,
Kevin Tang71ad5fe2017-05-10 19:36:20 -0700902 type,
903 isRoaming,
destradaae21252a2015-09-08 12:32:59 -0700904 networkAvailable,
Kevin Tang71ad5fe2017-05-10 19:36:20 -0700905 apnName,
destradaae21252a2015-09-08 12:32:59 -0700906 defaultApn);
907 } else if (DEBUG) {
908 Log.d(TAG, "Skipped network state update because GPS HAL AGPS-RIL is not supported");
Mike Lockwood50130bb2010-10-11 06:22:50 -0400909 }
910
destradaae21252a2015-09-08 12:32:59 -0700911 if (mAGpsDataConnectionState == AGPS_DATA_CONNECTION_OPENING) {
912 if (isConnected) {
Stephen Li83b69712011-01-25 18:47:28 -0800913 if (apnName == null) {
destradaae21252a2015-09-08 12:32:59 -0700914 // assign a dummy value in the case of C2K as otherwise we will have a runtime
915 // exception in the following call to native_agps_data_conn_open
Stephen Li83b69712011-01-25 18:47:28 -0800916 apnName = "dummy-apn";
917 }
destradaae21252a2015-09-08 12:32:59 -0700918 int apnIpType = getApnIpType(apnName);
destradaa96a14702014-06-05 11:36:30 -0700919 setRouting();
920 if (DEBUG) {
921 String message = String.format(
922 "native_agps_data_conn_open: mAgpsApn=%s, mApnIpType=%s",
destradaae21252a2015-09-08 12:32:59 -0700923 apnName,
924 apnIpType);
destradaa96a14702014-06-05 11:36:30 -0700925 Log.d(TAG, message);
Stephen Li8efd74d2011-03-01 20:56:00 -0800926 }
destradaae21252a2015-09-08 12:32:59 -0700927 native_agps_data_conn_open(apnName, apnIpType);
Mike Lockwood03d24672009-10-08 15:45:03 -0400928 mAGpsDataConnectionState = AGPS_DATA_CONNECTION_OPEN;
929 } else {
destradaae21252a2015-09-08 12:32:59 -0700930 handleReleaseSuplConnection(GPS_AGPS_DATA_CONN_FAILED);
Mike Lockwood03d24672009-10-08 15:45:03 -0400931 }
932 }
destradaae21252a2015-09-08 12:32:59 -0700933 }
Mike Lockwood03d24672009-10-08 15:45:03 -0400934
destradaae21252a2015-09-08 12:32:59 -0700935 private void handleRequestSuplConnection(InetAddress address) {
936 if (DEBUG) {
937 String message = String.format(
938 "requestSuplConnection, state=%s, address=%s",
939 agpsDataConnStateAsString(),
940 address);
941 Log.d(TAG, message);
942 }
943
944 if (mAGpsDataConnectionState != AGPS_DATA_CONNECTION_CLOSED) {
945 return;
946 }
947 mAGpsDataConnectionIpAddr = address;
948 mAGpsDataConnectionState = AGPS_DATA_CONNECTION_OPENING;
949
950 NetworkRequest.Builder requestBuilder = new NetworkRequest.Builder();
951 requestBuilder.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR);
952 requestBuilder.addCapability(NetworkCapabilities.NET_CAPABILITY_SUPL);
953 NetworkRequest request = requestBuilder.build();
954 mConnMgr.requestNetwork(
955 request,
Etan Cohene9aea9d2017-02-09 18:16:58 -0800956 mSuplConnectivityCallback);
destradaae21252a2015-09-08 12:32:59 -0700957 }
958
959 private void handleReleaseSuplConnection(int agpsDataConnStatus) {
960 if (DEBUG) {
961 String message = String.format(
962 "releaseSuplConnection, state=%s, status=%s",
963 agpsDataConnStateAsString(),
964 agpsDataConnStatusAsString(agpsDataConnStatus));
965 Log.d(TAG, message);
966 }
967
968 if (mAGpsDataConnectionState == AGPS_DATA_CONNECTION_CLOSED) {
969 return;
970 }
971 mAGpsDataConnectionState = AGPS_DATA_CONNECTION_CLOSED;
972
973 mConnMgr.unregisterNetworkCallback(mSuplConnectivityCallback);
974 switch (agpsDataConnStatus) {
975 case GPS_AGPS_DATA_CONN_FAILED:
976 native_agps_data_conn_failed();
977 break;
978 case GPS_RELEASE_AGPS_DATA_CONN:
979 native_agps_data_conn_closed();
980 break;
981 default:
982 Log.e(TAG, "Invalid status to release SUPL connection: " + agpsDataConnStatus);
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400983 }
984 }
Yu-Han Yang8de21502018-04-23 01:40:25 -0700985
Yu-Han Yange7baef32018-02-09 13:58:17 -0800986 private void handleRequestLocation(boolean independentFromGnss) {
987 if (isRequestLocationRateLimited()) {
988 if (DEBUG) {
989 Log.d(TAG, "RequestLocation is denied due to too frequent requests.");
990 }
991 return;
992 }
Yu-Han Yang74041ff2018-04-06 15:57:31 -0700993 ContentResolver resolver = mContext.getContentResolver();
994 long durationMillis = Settings.Global.getLong(
995 resolver,
996 Settings.Global.GNSS_HAL_LOCATION_REQUEST_DURATION_MILLIS,
997 LOCATION_UPDATE_DURATION_MILLIS);
998 if (durationMillis == 0) {
999 Log.i(TAG, "GNSS HAL location request is disabled by Settings.");
1000 return;
1001 }
Yu-Han Yange7baef32018-02-09 13:58:17 -08001002
1003 LocationManager locationManager = (LocationManager) mContext.getSystemService(
1004 Context.LOCATION_SERVICE);
Yu-Han Yang07561382018-02-21 13:08:37 -08001005 String provider;
1006 LocationChangeListener locationListener;
Yu-Han Yange7baef32018-02-09 13:58:17 -08001007
1008 if (independentFromGnss) {
1009 // For fast GNSS TTFF
Yu-Han Yang07561382018-02-21 13:08:37 -08001010 provider = LocationManager.NETWORK_PROVIDER;
1011 locationListener = mNetworkLocationListener;
Yu-Han Yange7baef32018-02-09 13:58:17 -08001012 } else {
1013 // For Device-Based Hybrid (E911)
Yu-Han Yang07561382018-02-21 13:08:37 -08001014 provider = LocationManager.FUSED_PROVIDER;
1015 locationListener = mFusedLocationListener;
Yu-Han Yange7baef32018-02-09 13:58:17 -08001016 }
Yu-Han Yang07561382018-02-21 13:08:37 -08001017
1018 Log.i(TAG,
Yu-Han Yang74041ff2018-04-06 15:57:31 -07001019 String.format(
1020 "GNSS HAL Requesting location updates from %s provider for %d millis.",
1021 provider, durationMillis));
Yu-Han Yange684dda2018-05-24 10:29:39 -07001022 try {
1023 locationManager.requestLocationUpdates(provider,
1024 LOCATION_UPDATE_MIN_TIME_INTERVAL_MILLIS, /*minDistance=*/ 0,
1025 locationListener, mHandler.getLooper());
1026 locationListener.numLocationUpdateRequest++;
1027 mHandler.postDelayed(() -> {
1028 if (--locationListener.numLocationUpdateRequest == 0) {
1029 Log.i(TAG,
1030 String.format("Removing location updates from %s provider.", provider));
1031 locationManager.removeUpdates(locationListener);
1032 }
1033 }, durationMillis);
1034 } catch (IllegalArgumentException e) {
1035 Log.w(TAG, "Unable to request location.", e);
1036 }
Yu-Han Yange7baef32018-02-09 13:58:17 -08001037 }
1038
1039 private void injectBestLocation(Location location) {
1040 int gnssLocationFlags = LOCATION_HAS_LAT_LONG |
1041 (location.hasAltitude() ? LOCATION_HAS_ALTITUDE : 0) |
1042 (location.hasSpeed() ? LOCATION_HAS_SPEED : 0) |
1043 (location.hasBearing() ? LOCATION_HAS_BEARING : 0) |
1044 (location.hasAccuracy() ? LOCATION_HAS_HORIZONTAL_ACCURACY : 0) |
1045 (location.hasVerticalAccuracy() ? LOCATION_HAS_VERTICAL_ACCURACY : 0) |
1046 (location.hasSpeedAccuracy() ? LOCATION_HAS_SPEED_ACCURACY : 0) |
1047 (location.hasBearingAccuracy() ? LOCATION_HAS_BEARING_ACCURACY : 0);
1048
1049 double latitudeDegrees = location.getLatitude();
1050 double longitudeDegrees = location.getLongitude();
1051 double altitudeMeters = location.getAltitude();
1052 float speedMetersPerSec = location.getSpeed();
1053 float bearingDegrees = location.getBearing();
1054 float horizontalAccuracyMeters = location.getAccuracy();
1055 float verticalAccuracyMeters = location.getVerticalAccuracyMeters();
1056 float speedAccuracyMetersPerSecond = location.getSpeedAccuracyMetersPerSecond();
1057 float bearingAccuracyDegrees = location.getBearingAccuracyDegrees();
1058 long timestamp = location.getTime();
1059 native_inject_best_location(gnssLocationFlags, latitudeDegrees, longitudeDegrees,
1060 altitudeMeters, speedMetersPerSec, bearingDegrees, horizontalAccuracyMeters,
1061 verticalAccuracyMeters, speedAccuracyMetersPerSecond, bearingAccuracyDegrees,
1062 timestamp);
1063 }
1064
Yu-Han Yange7baef32018-02-09 13:58:17 -08001065 /** Returns true if the location request is too frequent. */
1066 private boolean isRequestLocationRateLimited() {
1067 // TODO(b/73198123): implement exponential backoff.
1068 return false;
1069 }
1070
Mike Lockwood62a8fc12010-03-22 14:23:26 -04001071 private void handleDownloadXtraData() {
Wyatt Riley0d6e54e22016-10-05 12:03:03 -07001072 if (!mSupportsXtra) {
1073 // native code reports xtra not supported, don't try
1074 Log.d(TAG, "handleDownloadXtraData() called when Xtra not supported");
1075 return;
1076 }
Kevin Tang40e1baf2012-01-10 14:32:44 -08001077 if (mDownloadXtraDataPending == STATE_DOWNLOADING) {
1078 // already downloading data
Mike Lockwood62a8fc12010-03-22 14:23:26 -04001079 return;
1080 }
destradaae21252a2015-09-08 12:32:59 -07001081 if (!isDataNetworkConnected()) {
Kevin Tang40e1baf2012-01-10 14:32:44 -08001082 // try again when network is up
1083 mDownloadXtraDataPending = STATE_PENDING_NETWORK;
1084 return;
Mike Lockwood62a8fc12010-03-22 14:23:26 -04001085 }
Kevin Tang40e1baf2012-01-10 14:32:44 -08001086 mDownloadXtraDataPending = STATE_DOWNLOADING;
1087
Jeff Brown028872f2012-08-25 13:07:01 -07001088 // hold wake lock while task runs
Wei Wangb71c0492017-05-01 20:24:19 -07001089 mDownloadXtraWakeLock.acquire(DOWNLOAD_XTRA_DATA_TIMEOUT_MS);
Lifu Tangcbd2a142016-06-22 10:57:55 -07001090 Log.i(TAG, "WakeLock acquired by handleDownloadXtraData()");
Kevin Tang40e1baf2012-01-10 14:32:44 -08001091 AsyncTask.THREAD_POOL_EXECUTOR.execute(new Runnable() {
1092 @Override
1093 public void run() {
Andreas Gampedfdc6ac2014-10-28 20:42:53 -07001094 GpsXtraDownloader xtraDownloader = new GpsXtraDownloader(mProperties);
Kevin Tang40e1baf2012-01-10 14:32:44 -08001095 byte[] data = xtraDownloader.downloadXtraData();
1096 if (data != null) {
destradaae21252a2015-09-08 12:32:59 -07001097 if (DEBUG) Log.d(TAG, "calling native_inject_xtra_data");
Kevin Tang40e1baf2012-01-10 14:32:44 -08001098 native_inject_xtra_data(data, data.length);
Wei Liu6f6326b2015-06-24 23:47:50 -07001099 mXtraBackOff.reset();
Kevin Tang40e1baf2012-01-10 14:32:44 -08001100 }
1101
Jeff Brown028872f2012-08-25 13:07:01 -07001102 sendMessage(DOWNLOAD_XTRA_DATA_FINISHED, 0, null);
Kevin Tang40e1baf2012-01-10 14:32:44 -08001103
1104 if (data == null) {
1105 // try again later
1106 // since this is delayed and not urgent we do not hold a wake lock here
Wei Liu6f6326b2015-06-24 23:47:50 -07001107 mHandler.sendEmptyMessageDelayed(DOWNLOAD_XTRA_DATA,
1108 mXtraBackOff.nextBackoffMillis());
Kevin Tang40e1baf2012-01-10 14:32:44 -08001109 }
Kevin Tang40e1baf2012-01-10 14:32:44 -08001110
Wei Wangb71c0492017-05-01 20:24:19 -07001111 // Release wake lock held by task, synchronize on mLock in case multiple
1112 // download tasks overrun.
1113 synchronized (mLock) {
1114 if (mDownloadXtraWakeLock.isHeld()) {
Zheng Zhang3cceb252017-08-07 13:51:23 -07001115 // This wakelock may have time-out, if a timeout was specified.
1116 // Catch (and ignore) any timeout exceptions.
1117 try {
1118 mDownloadXtraWakeLock.release();
1119 if (DEBUG) Log.d(TAG, "WakeLock released by handleDownloadXtraData()");
1120 } catch (Exception e) {
1121 Log.i(TAG, "Wakelock timeout & release race exception in "
1122 + "handleDownloadXtraData()", e);
1123 }
Wei Wangb71c0492017-05-01 20:24:19 -07001124 } else {
1125 Log.e(TAG, "WakeLock expired before release in "
1126 + "handleDownloadXtraData()");
1127 }
Wei Wangc5706f62017-04-18 11:26:26 -07001128 }
Jeff Brown028872f2012-08-25 13:07:01 -07001129 }
Kevin Tang40e1baf2012-01-10 14:32:44 -08001130 });
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001131 }
1132
Mike Lockwood62a8fc12010-03-22 14:23:26 -04001133 private void handleUpdateLocation(Location location) {
Mike Lockwoodd26ce0d2009-06-11 12:25:46 -04001134 if (location.hasAccuracy()) {
1135 native_inject_location(location.getLatitude(), location.getLongitude(),
1136 location.getAccuracy());
1137 }
Mike Lockwoodfd6e5f02009-05-21 11:28:20 -04001138 }
1139
1140 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001141 * Enables this provider. When enabled, calls to getStatus()
Mike Lockwood4e50b782009-04-03 08:24:43 -07001142 * must be handled. Hardware may be started up
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001143 * when the provider is enabled.
1144 */
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001145 @Override
Mike Lockwood62a8fc12010-03-22 14:23:26 -04001146 public void enable() {
Laurent Tu7b5aeca2013-01-24 15:10:24 -08001147 synchronized (mLock) {
1148 if (mEnabled) return;
1149 mEnabled = true;
1150 }
1151
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001152 sendMessage(ENABLE, 1, null);
Mike Lockwood62a8fc12010-03-22 14:23:26 -04001153 }
1154
Tsuwei Chen52617bb2014-08-25 11:49:11 -07001155 private void setSuplHostPort(String hostString, String portString) {
1156 if (hostString != null) {
1157 mSuplServerHost = hostString;
1158 }
1159 if (portString != null) {
1160 try {
1161 mSuplServerPort = Integer.parseInt(portString);
1162 } catch (NumberFormatException e) {
1163 Log.e(TAG, "unable to parse SUPL_PORT: " + portString);
1164 }
1165 }
Tsuwei Chen678c13c2014-09-22 17:48:41 -07001166 if (mSuplServerHost != null
1167 && mSuplServerPort > TCP_MIN_PORT
1168 && mSuplServerPort <= TCP_MAX_PORT) {
1169 native_set_agps_server(AGPS_TYPE_SUPL, mSuplServerHost, mSuplServerPort);
1170 }
Tsuwei Chen52617bb2014-08-25 11:49:11 -07001171 }
1172
Tsuwei Chen462bcd82014-09-17 12:28:49 -07001173 /**
1174 * Checks what SUPL mode to use, according to the AGPS mode as well as the
1175 * allowed mode from properties.
1176 *
gomo48f1a642017-11-10 20:35:46 -08001177 * @param properties GPS properties
Tsuwei Chen462bcd82014-09-17 12:28:49 -07001178 * @param agpsEnabled whether AGPS is enabled by settings value
gomo48f1a642017-11-10 20:35:46 -08001179 * @param singleShot whether "singleshot" is needed
Tsuwei Chen462bcd82014-09-17 12:28:49 -07001180 * @return SUPL mode (MSA vs MSB vs STANDALONE)
1181 */
1182 private int getSuplMode(Properties properties, boolean agpsEnabled, boolean singleShot) {
1183 if (agpsEnabled) {
1184 String modeString = properties.getProperty("SUPL_MODE");
1185 int suplMode = 0;
1186 if (!TextUtils.isEmpty(modeString)) {
1187 try {
1188 suplMode = Integer.parseInt(modeString);
1189 } catch (NumberFormatException e) {
1190 Log.e(TAG, "unable to parse SUPL_MODE: " + modeString);
1191 return GPS_POSITION_MODE_STANDALONE;
1192 }
1193 }
destradaabfb3bdb2015-04-29 14:42:35 -07001194 // MS-Based is the preferred mode for Assisted-GPS position computation, so we favor
1195 // such mode when it is available
1196 if (hasCapability(GPS_CAPABILITY_MSB) && (suplMode & AGPS_SUPL_MODE_MSB) != 0) {
1197 return GPS_POSITION_MODE_MS_BASED;
1198 }
1199 // for now, just as the legacy code did, we fallback to MS-Assisted if it is available,
1200 // do fallback only for single-shot requests, because it is too expensive to do for
1201 // periodic requests as well
Tsuwei Chen462bcd82014-09-17 12:28:49 -07001202 if (singleShot
1203 && hasCapability(GPS_CAPABILITY_MSA)
1204 && (suplMode & AGPS_SUPL_MODE_MSA) != 0) {
1205 return GPS_POSITION_MODE_MS_ASSISTED;
Tsuwei Chen462bcd82014-09-17 12:28:49 -07001206 }
1207 }
1208 return GPS_POSITION_MODE_STANDALONE;
1209 }
1210
Mike Lockwood62a8fc12010-03-22 14:23:26 -04001211 private void handleEnable() {
1212 if (DEBUG) Log.d(TAG, "handleEnable");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001213
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001214 boolean enabled = native_init();
1215
1216 if (enabled) {
Mike Lockwood1a1cd3a2010-08-17 07:42:54 -04001217 mSupportsXtra = native_supports_xtra();
Tsuwei Chen678c13c2014-09-22 17:48:41 -07001218
1219 // TODO: remove the following native calls if we can make sure they are redundant.
Mike Lockwood734d6032009-07-28 18:30:25 -07001220 if (mSuplServerHost != null) {
1221 native_set_agps_server(AGPS_TYPE_SUPL, mSuplServerHost, mSuplServerPort);
1222 }
1223 if (mC2KServerHost != null) {
1224 native_set_agps_server(AGPS_TYPE_C2K, mC2KServerHost, mC2KServerPort);
1225 }
destradaa13a60b02015-01-15 18:36:01 -08001226
Lifu Tang818aa2c2016-02-01 01:52:00 -08001227 mGnssMeasurementsProvider.onGpsEnabledChanged();
1228 mGnssNavigationMessageProvider.onGpsEnabledChanged();
Yu-Han Yang3557cc72018-03-21 12:48:36 -07001229 mGnssBatchingProvider.enable();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001230 } else {
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001231 synchronized (mLock) {
1232 mEnabled = false;
1233 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001234 Log.w(TAG, "Failed to enable location provider");
1235 }
1236 }
1237
1238 /**
1239 * Disables this provider. When disabled, calls to getStatus()
Mike Lockwood4e50b782009-04-03 08:24:43 -07001240 * need not be handled. Hardware may be shut
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001241 * down while the provider is disabled.
1242 */
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001243 @Override
Mike Lockwood62a8fc12010-03-22 14:23:26 -04001244 public void disable() {
Laurent Tu7b5aeca2013-01-24 15:10:24 -08001245 synchronized (mLock) {
1246 if (!mEnabled) return;
1247 mEnabled = false;
1248 }
1249
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001250 sendMessage(ENABLE, 0, null);
Mike Lockwood62a8fc12010-03-22 14:23:26 -04001251 }
1252
1253 private void handleDisable() {
Mike Lockwood89096312010-03-24 10:14:55 -04001254 if (DEBUG) Log.d(TAG, "handleDisable");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001255
David Christie3bc26142013-12-19 14:53:44 -08001256 updateClientUids(new WorkSource());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001257 stopNavigating();
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001258 mAlarmManager.cancel(mWakeupIntent);
1259 mAlarmManager.cancel(mTimeoutIntent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001260
Yu-Han Yang3557cc72018-03-21 12:48:36 -07001261 mGnssBatchingProvider.disable();
Mike Lockwoodcf1d8cb2010-01-20 10:14:54 -05001262 // do this before releasing wakelock
1263 native_cleanup();
destradaa13a60b02015-01-15 18:36:01 -08001264
Lifu Tang818aa2c2016-02-01 01:52:00 -08001265 mGnssMeasurementsProvider.onGpsEnabledChanged();
1266 mGnssNavigationMessageProvider.onGpsEnabledChanged();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001267 }
1268
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001269 @Override
Mike Lockwoodd03ff942010-02-09 08:46:14 -05001270 public boolean isEnabled() {
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001271 synchronized (mLock) {
1272 return mEnabled;
1273 }
Mike Lockwoodd03ff942010-02-09 08:46:14 -05001274 }
1275
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001276 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001277 public int getStatus(Bundle extras) {
Wyatt Rileyc7067412018-02-07 15:50:35 -08001278 mLocationExtras.setBundle(extras);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001279 return mStatus;
1280 }
1281
Wyatt Rileyc7067412018-02-07 15:50:35 -08001282 private void updateStatus(int status) {
1283 if (status != mStatus) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001284 mStatus = status;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001285 mStatusUpdateTime = SystemClock.elapsedRealtime();
1286 }
1287 }
1288
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001289 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001290 public long getStatusUpdateTime() {
1291 return mStatusUpdateTime;
1292 }
1293
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001294 @Override
1295 public void setRequest(ProviderRequest request, WorkSource source) {
1296 sendMessage(SET_REQUEST, 0, new GpsRequest(request, source));
Mike Lockwood62a8fc12010-03-22 14:23:26 -04001297 }
1298
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001299 private void handleSetRequest(ProviderRequest request, WorkSource source) {
David Christied4edf4c2014-08-12 15:22:27 -07001300 mProviderRequest = request;
1301 mWorkSource = source;
1302 updateRequirements();
1303 }
1304
1305 // Called when the requirements for GPS may have changed
1306 private void updateRequirements() {
1307 if (mProviderRequest == null || mWorkSource == null) {
1308 return;
1309 }
1310
Stan Chesnutt1d72d8c2013-04-15 19:18:02 -07001311 boolean singleShot = false;
1312
1313 // see if the request is for a single update
David Christied4edf4c2014-08-12 15:22:27 -07001314 if (mProviderRequest.locationRequests != null
1315 && mProviderRequest.locationRequests.size() > 0) {
Stan Chesnutt1d72d8c2013-04-15 19:18:02 -07001316 // if any request has zero or more than one updates
1317 // requested, then this is not single-shot mode
1318 singleShot = true;
1319
David Christied4edf4c2014-08-12 15:22:27 -07001320 for (LocationRequest lr : mProviderRequest.locationRequests) {
Stan Chesnutt1d72d8c2013-04-15 19:18:02 -07001321 if (lr.getNumUpdates() != 1) {
1322 singleShot = false;
1323 }
1324 }
1325 }
1326
David Christied4edf4c2014-08-12 15:22:27 -07001327 if (DEBUG) Log.d(TAG, "setRequest " + mProviderRequest);
Dante Russo260d6672016-06-20 11:11:59 -07001328 if (mProviderRequest.reportLocation && !mDisableGps && isEnabled()) {
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001329 // update client uids
David Christied4edf4c2014-08-12 15:22:27 -07001330 updateClientUids(mWorkSource);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001331
David Christied4edf4c2014-08-12 15:22:27 -07001332 mFixInterval = (int) mProviderRequest.interval;
gomo48f1a642017-11-10 20:35:46 -08001333 mLowPowerMode = (boolean) mProviderRequest.lowPowerMode;
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001334 // check for overflow
David Christied4edf4c2014-08-12 15:22:27 -07001335 if (mFixInterval != mProviderRequest.interval) {
1336 Log.w(TAG, "interval overflow: " + mProviderRequest.interval);
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001337 mFixInterval = Integer.MAX_VALUE;
1338 }
Mike Lockwood03ca2162010-04-01 08:10:09 -07001339
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001340 // apply request to GPS engine
Mike Lockwood04598b62010-04-14 17:17:24 -04001341 if (mStarted && hasCapability(GPS_CAPABILITY_SCHEDULING)) {
gomo48f1a642017-11-10 20:35:46 -08001342 // change period and/or lowPowerMode
Mike Lockwood04598b62010-04-14 17:17:24 -04001343 if (!native_set_position_mode(mPositionMode, GPS_POSITION_RECURRENCE_PERIODIC,
gomo48f1a642017-11-10 20:35:46 -08001344 mFixInterval, 0, 0, mLowPowerMode)) {
1345 Log.e(TAG, "set_position_mode failed in updateRequirements");
Mike Lockwood04598b62010-04-14 17:17:24 -04001346 }
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001347 } else if (!mStarted) {
1348 // start GPS
Stan Chesnutt1d72d8c2013-04-15 19:18:02 -07001349 startNavigating(singleShot);
gomo300b2402017-12-13 19:04:12 -08001350 } else {
1351 // GNSS Engine is already ON, but no GPS_CAPABILITY_SCHEDULING
1352 mAlarmManager.cancel(mTimeoutIntent);
1353 if (mFixInterval >= NO_FIX_TIMEOUT) {
1354 // set timer to give up if we do not receive a fix within NO_FIX_TIMEOUT
1355 // and our fix interval is not short
1356 mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
1357 SystemClock.elapsedRealtime() + NO_FIX_TIMEOUT, mTimeoutIntent); }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001358 }
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001359 } else {
Dianne Hackborn002a54e2013-01-10 17:34:55 -08001360 updateClientUids(new WorkSource());
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001361
1362 stopNavigating();
1363 mAlarmManager.cancel(mWakeupIntent);
1364 mAlarmManager.cancel(mTimeoutIntent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001365 }
1366 }
1367
Dianne Hackborn002a54e2013-01-10 17:34:55 -08001368 private void updateClientUids(WorkSource source) {
Narayan Kamath32684dd2018-01-08 17:32:51 +00001369 if (source.equals(mClientSource)) {
Victoria Leaseea78b852013-01-15 10:39:28 -08001370 return;
1371 }
Dianne Hackborn002a54e2013-01-10 17:34:55 -08001372
Narayan Kamath32684dd2018-01-08 17:32:51 +00001373 // (1) Inform BatteryStats that the list of IDs we're tracking changed.
1374 try {
1375 mBatteryStats.noteGpsChanged(mClientSource, source);
1376 } catch (RemoteException e) {
1377 Log.w(TAG, "RemoteException", e);
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001378 }
1379
Narayan Kamath32684dd2018-01-08 17:32:51 +00001380 // (2) Inform AppOps service about the list of changes to UIDs.
1381
1382 List<WorkChain>[] diffs = WorkSource.diffChains(mClientSource, source);
1383 if (diffs != null) {
1384 List<WorkChain> newChains = diffs[0];
1385 List<WorkChain> goneChains = diffs[1];
1386
1387 if (newChains != null) {
1388 for (int i = 0; i < newChains.size(); ++i) {
1389 final WorkChain newChain = newChains.get(i);
Svet Ganovf7b47252018-02-26 11:11:27 -08001390 mAppOps.startOpNoThrow(AppOpsManager.OP_GPS, newChain.getAttributionUid(),
1391 newChain.getAttributionTag());
Narayan Kamath32684dd2018-01-08 17:32:51 +00001392 }
1393 }
1394
1395 if (goneChains != null) {
1396 for (int i = 0; i < goneChains.size(); i++) {
1397 final WorkChain goneChain = goneChains.get(i);
Svet Ganovf7b47252018-02-26 11:11:27 -08001398 mAppOps.finishOp(AppOpsManager.OP_GPS, goneChain.getAttributionUid(),
1399 goneChain.getAttributionTag());
Narayan Kamath32684dd2018-01-08 17:32:51 +00001400 }
1401 }
1402
1403 mClientSource.transferWorkChains(source);
1404 }
1405
1406 // Update the flat UIDs and names list and inform app-ops of all changes.
1407 WorkSource[] changes = mClientSource.setReturningDiffs(source);
1408 if (changes != null) {
1409 WorkSource newWork = changes[0];
1410 WorkSource goneWork = changes[1];
1411
1412 // Update sources that were not previously tracked.
1413 if (newWork != null) {
1414 for (int i = 0; i < newWork.size(); i++) {
Svet Ganovf7b47252018-02-26 11:11:27 -08001415 mAppOps.startOpNoThrow(AppOpsManager.OP_GPS,
1416 newWork.get(i), newWork.getName(i));
Narayan Kamath32684dd2018-01-08 17:32:51 +00001417 }
1418 }
1419
1420 // Update sources that are no longer tracked.
1421 if (goneWork != null) {
1422 for (int i = 0; i < goneWork.size(); i++) {
Svet Ganovf7b47252018-02-26 11:11:27 -08001423 mAppOps.finishOp(AppOpsManager.OP_GPS, goneWork.get(i), goneWork.getName(i));
Dianne Hackborn2e418422009-06-22 20:00:17 -07001424 }
Mike Lockwood2f82c4e2009-04-17 08:24:10 -04001425 }
1426 }
1427 }
1428
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001429 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001430 public boolean sendExtraCommand(String command, Bundle extras) {
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001431
Mike Lockwood63aa5a62010-04-14 19:21:31 -04001432 long identity = Binder.clearCallingIdentity();
Peter Visontayb25db362017-11-01 18:18:12 +00001433 try {
1434 boolean result = false;
Mike Lockwood63aa5a62010-04-14 19:21:31 -04001435
Peter Visontayb25db362017-11-01 18:18:12 +00001436 if ("delete_aiding_data".equals(command)) {
1437 result = deleteAidingData(extras);
1438 } else if ("force_time_injection".equals(command)) {
1439 requestUtcTime();
Mike Lockwood63aa5a62010-04-14 19:21:31 -04001440 result = true;
Peter Visontayb25db362017-11-01 18:18:12 +00001441 } else if ("force_xtra_injection".equals(command)) {
1442 if (mSupportsXtra) {
1443 xtraDownloadRequest();
1444 result = true;
1445 }
1446 } else {
1447 Log.w(TAG, "sendExtraCommand: unknown command " + command);
Mike Lockwood93bc44d2009-05-20 16:58:22 -04001448 }
Peter Visontayb25db362017-11-01 18:18:12 +00001449 return result;
1450 } finally {
1451 Binder.restoreCallingIdentity(identity);
Mike Lockwood93bc44d2009-05-20 16:58:22 -04001452 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001453 }
1454
1455 private boolean deleteAidingData(Bundle extras) {
1456 int flags;
1457
1458 if (extras == null) {
1459 flags = GPS_DELETE_ALL;
1460 } else {
1461 flags = 0;
1462 if (extras.getBoolean("ephemeris")) flags |= GPS_DELETE_EPHEMERIS;
1463 if (extras.getBoolean("almanac")) flags |= GPS_DELETE_ALMANAC;
1464 if (extras.getBoolean("position")) flags |= GPS_DELETE_POSITION;
1465 if (extras.getBoolean("time")) flags |= GPS_DELETE_TIME;
1466 if (extras.getBoolean("iono")) flags |= GPS_DELETE_IONO;
1467 if (extras.getBoolean("utc")) flags |= GPS_DELETE_UTC;
1468 if (extras.getBoolean("health")) flags |= GPS_DELETE_HEALTH;
1469 if (extras.getBoolean("svdir")) flags |= GPS_DELETE_SVDIR;
1470 if (extras.getBoolean("svsteer")) flags |= GPS_DELETE_SVSTEER;
1471 if (extras.getBoolean("sadata")) flags |= GPS_DELETE_SADATA;
1472 if (extras.getBoolean("rti")) flags |= GPS_DELETE_RTI;
1473 if (extras.getBoolean("celldb-info")) flags |= GPS_DELETE_CELLDB_INFO;
1474 if (extras.getBoolean("all")) flags |= GPS_DELETE_ALL;
1475 }
1476
1477 if (flags != 0) {
1478 native_delete_aiding_data(flags);
1479 return true;
1480 }
1481
1482 return false;
1483 }
1484
Stan Chesnutt1d72d8c2013-04-15 19:18:02 -07001485 private void startNavigating(boolean singleShot) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001486 if (!mStarted) {
Stan Chesnutt1d72d8c2013-04-15 19:18:02 -07001487 if (DEBUG) Log.d(TAG, "startNavigating, singleShot is " + singleShot);
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001488 mTimeToFirstFix = 0;
1489 mLastFixTime = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001490 mStarted = true;
Stan Chesnutt1d72d8c2013-04-15 19:18:02 -07001491 mSingleShot = singleShot;
Mike Lockwood03ca2162010-04-01 08:10:09 -07001492 mPositionMode = GPS_POSITION_MODE_STANDALONE;
Wyatt Riley5d5bac82016-11-01 07:05:16 -07001493 // Notify about suppressed output, if speed limit was previously exceeded.
1494 // Elsewhere, we check again with every speed output reported.
1495 if (mItarSpeedLimitExceeded) {
1496 Log.i(TAG, "startNavigating with ITAR limit in place. Output limited " +
1497 "until slow enough speed reported.");
1498 }
Mike Lockwood03ca2162010-04-01 08:10:09 -07001499
Tsuwei Chen462bcd82014-09-17 12:28:49 -07001500 boolean agpsEnabled =
1501 (Settings.Global.getInt(mContext.getContentResolver(),
gomo48f1a642017-11-10 20:35:46 -08001502 Settings.Global.ASSISTED_GPS_ENABLED, 1) != 0);
Tsuwei Chen462bcd82014-09-17 12:28:49 -07001503 mPositionMode = getSuplMode(mProperties, agpsEnabled, singleShot);
Mike Lockwoodbcab8df2009-06-25 16:39:09 -04001504
Stan Chesnutt1d72d8c2013-04-15 19:18:02 -07001505 if (DEBUG) {
1506 String mode;
1507
gomo48f1a642017-11-10 20:35:46 -08001508 switch (mPositionMode) {
Stan Chesnutt1d72d8c2013-04-15 19:18:02 -07001509 case GPS_POSITION_MODE_STANDALONE:
1510 mode = "standalone";
1511 break;
1512 case GPS_POSITION_MODE_MS_ASSISTED:
1513 mode = "MS_ASSISTED";
1514 break;
1515 case GPS_POSITION_MODE_MS_BASED:
1516 mode = "MS_BASED";
1517 break;
1518 default:
1519 mode = "unknown";
1520 break;
1521 }
1522 Log.d(TAG, "setting position_mode to " + mode);
1523 }
1524
Mike Lockwood04598b62010-04-14 17:17:24 -04001525 int interval = (hasCapability(GPS_CAPABILITY_SCHEDULING) ? mFixInterval : 1000);
gomo48f1a642017-11-10 20:35:46 -08001526 mLowPowerMode = (boolean) mProviderRequest.lowPowerMode;
Mike Lockwood04598b62010-04-14 17:17:24 -04001527 if (!native_set_position_mode(mPositionMode, GPS_POSITION_RECURRENCE_PERIODIC,
gomo48f1a642017-11-10 20:35:46 -08001528 interval, 0, 0, mLowPowerMode)) {
Mike Lockwood04598b62010-04-14 17:17:24 -04001529 mStarted = false;
1530 Log.e(TAG, "set_position_mode failed in startNavigating()");
1531 return;
1532 }
1533 if (!native_start()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001534 mStarted = false;
1535 Log.e(TAG, "native_start failed in startNavigating()");
Mike Lockwood0632ca72009-05-14 15:51:03 -04001536 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001537 }
1538
1539 // reset SV count to zero
Wyatt Rileyc7067412018-02-07 15:50:35 -08001540 updateStatus(LocationProvider.TEMPORARILY_UNAVAILABLE);
1541 mLocationExtras.reset();
Yipeng Cao282b5942017-05-17 20:31:39 -07001542 mFixRequestTime = SystemClock.elapsedRealtime();
Mike Lockwood04598b62010-04-14 17:17:24 -04001543 if (!hasCapability(GPS_CAPABILITY_SCHEDULING)) {
1544 // set timer to give up if we do not receive a fix within NO_FIX_TIMEOUT
1545 // and our fix interval is not short
1546 if (mFixInterval >= NO_FIX_TIMEOUT) {
1547 mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
1548 SystemClock.elapsedRealtime() + NO_FIX_TIMEOUT, mTimeoutIntent);
1549 }
Mike Lockwood0632ca72009-05-14 15:51:03 -04001550 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001551 }
1552 }
1553
Mike Lockwood62a8fc12010-03-22 14:23:26 -04001554 private void stopNavigating() {
Mike Lockwood29c84342009-05-06 14:01:15 -04001555 if (DEBUG) Log.d(TAG, "stopNavigating");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001556 if (mStarted) {
1557 mStarted = false;
Stan Chesnutt1d72d8c2013-04-15 19:18:02 -07001558 mSingleShot = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001559 native_stop();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001560 mLastFixTime = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001561
1562 // reset SV count to zero
Wyatt Rileyc7067412018-02-07 15:50:35 -08001563 updateStatus(LocationProvider.TEMPORARILY_UNAVAILABLE);
1564 mLocationExtras.reset();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001565 }
1566 }
1567
Mike Lockwood0632ca72009-05-14 15:51:03 -04001568 private void hibernate() {
1569 // stop GPS until our next fix interval arrives
1570 stopNavigating();
Mike Lockwood0632ca72009-05-14 15:51:03 -04001571 mAlarmManager.cancel(mTimeoutIntent);
1572 mAlarmManager.cancel(mWakeupIntent);
1573 long now = SystemClock.elapsedRealtime();
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001574 mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, now + mFixInterval, mWakeupIntent);
Mike Lockwood04598b62010-04-14 17:17:24 -04001575 }
1576
1577 private boolean hasCapability(int capability) {
1578 return ((mEngineCapabilities & capability) != 0);
Mike Lockwood0632ca72009-05-14 15:51:03 -04001579 }
1580
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07001581
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001582 /**
1583 * called from native code to update our position.
1584 */
Wyatt Riley5d229832017-02-10 17:06:00 -08001585 private void reportLocation(boolean hasLatLong, Location location) {
Wyatt Riley26465d22018-02-12 13:44:24 -08001586 sendMessage(REPORT_LOCATION, hasLatLong ? 1 : 0, location);
1587 }
1588
1589 private void handleReportLocation(boolean hasLatLong, Location location) {
Wyatt Riley5d229832017-02-10 17:06:00 -08001590 if (location.hasSpeed()) {
1591 mItarSpeedLimitExceeded = location.getSpeed() > ITAR_SPEED_LIMIT_METERS_PER_SECOND;
Wyatt Riley5d5bac82016-11-01 07:05:16 -07001592 }
1593
1594 if (mItarSpeedLimitExceeded) {
1595 Log.i(TAG, "Hal reported a speed in excess of ITAR limit." +
1596 " GPS/GNSS Navigation output blocked.");
Siddharth Ray53ddc802018-03-16 12:01:52 -07001597 if (mStarted) {
1598 mGnssMetrics.logReceivedLocationStatus(false);
1599 }
Wyatt Riley5d5bac82016-11-01 07:05:16 -07001600 return; // No output of location allowed
1601 }
1602
Wyatt Riley5d229832017-02-10 17:06:00 -08001603 if (VERBOSE) Log.v(TAG, "reportLocation " + location.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001604
Wyatt Riley26465d22018-02-12 13:44:24 -08001605 // It would be nice to push the elapsed real-time timestamp
1606 // further down the stack, but this is still useful
1607 location.setElapsedRealtimeNanos(SystemClock.elapsedRealtimeNanos());
1608 location.setExtras(mLocationExtras.getBundle());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001609
Wyatt Riley26465d22018-02-12 13:44:24 -08001610 try {
1611 mILocationManager.reportLocation(location, false);
1612 } catch (RemoteException e) {
1613 Log.e(TAG, "RemoteException calling reportLocation");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001614 }
1615
Siddharth Ray53ddc802018-03-16 12:01:52 -07001616 if (mStarted) {
1617 mGnssMetrics.logReceivedLocationStatus(hasLatLong);
1618 if (hasLatLong) {
1619 if (location.hasAccuracy()) {
1620 mGnssMetrics.logPositionAccuracyMeters(location.getAccuracy());
1621 }
1622 if (mTimeToFirstFix > 0) {
1623 int timeBetweenFixes = (int) (SystemClock.elapsedRealtime() - mLastFixTime);
1624 mGnssMetrics.logMissedReports(mFixInterval, timeBetweenFixes);
1625 }
Siddharth Raybb608c82017-03-16 11:33:34 -07001626 }
1627 }
1628
Yipeng Cao282b5942017-05-17 20:31:39 -07001629 mLastFixTime = SystemClock.elapsedRealtime();
Hakan Gustavssonfa94ff02010-02-23 09:12:38 +01001630 // report time to first fix
Wyatt Riley5d229832017-02-10 17:06:00 -08001631 if (mTimeToFirstFix == 0 && hasLatLong) {
gomo48f1a642017-11-10 20:35:46 -08001632 mTimeToFirstFix = (int) (mLastFixTime - mFixRequestTime);
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001633 if (DEBUG) Log.d(TAG, "TTFF: " + mTimeToFirstFix);
Siddharth Ray53ddc802018-03-16 12:01:52 -07001634 if (mStarted) {
1635 mGnssMetrics.logTimeToFirstFixMilliSecs(mTimeToFirstFix);
1636 }
Hakan Gustavssonfa94ff02010-02-23 09:12:38 +01001637
1638 // notify status listeners
destradaaea8a8a62014-06-23 18:19:03 -07001639 mListenerHelper.onFirstFix(mTimeToFirstFix);
Hakan Gustavssonfa94ff02010-02-23 09:12:38 +01001640 }
1641
Stan Chesnutt1d72d8c2013-04-15 19:18:02 -07001642 if (mSingleShot) {
1643 stopNavigating();
1644 }
1645
Mike Lockwood15e3d0f2009-05-01 07:53:28 -04001646 if (mStarted && mStatus != LocationProvider.AVAILABLE) {
Wyatt Rileyc7067412018-02-07 15:50:35 -08001647 // For devices that use framework scheduling, a timer may be set to ensure we don't
1648 // spend too much power searching for a location, when the requested update rate is slow.
1649 // As we just recievied a location, we'll cancel that timer.
Mike Lockwood04598b62010-04-14 17:17:24 -04001650 if (!hasCapability(GPS_CAPABILITY_SCHEDULING) && mFixInterval < NO_FIX_TIMEOUT) {
Mike Lockwoodb7be5442010-02-24 14:34:50 -05001651 mAlarmManager.cancel(mTimeoutIntent);
1652 }
1653
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001654 // send an intent to notify that the GPS is receiving fixes.
Mike Lockwood00b74272010-03-26 10:41:48 -04001655 Intent intent = new Intent(LocationManager.GPS_FIX_CHANGE_ACTION);
1656 intent.putExtra(LocationManager.EXTRA_GPS_ENABLED, true);
Dianne Hackborn5ac72a22012-08-29 18:32:08 -07001657 mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
Wyatt Rileyc7067412018-02-07 15:50:35 -08001658 updateStatus(LocationProvider.AVAILABLE);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001659 }
Mike Lockwood29c84342009-05-06 14:01:15 -04001660
gomo48f1a642017-11-10 20:35:46 -08001661 if (!hasCapability(GPS_CAPABILITY_SCHEDULING) && mStarted &&
1662 mFixInterval > GPS_POLLING_THRESHOLD_INTERVAL) {
Mike Lockwoodd53ba012010-04-15 20:41:26 -04001663 if (DEBUG) Log.d(TAG, "got fix, hibernating");
Mike Lockwood0632ca72009-05-14 15:51:03 -04001664 hibernate();
Mike Lockwood29c84342009-05-06 14:01:15 -04001665 }
gomo48f1a642017-11-10 20:35:46 -08001666 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001667
1668 /**
1669 * called from native code to update our status
1670 */
1671 private void reportStatus(int status) {
Mike Lockwoodb8d90332010-10-18 17:59:48 -04001672 if (DEBUG) Log.v(TAG, "reportStatus status: " + status);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001673
destradaaea8a8a62014-06-23 18:19:03 -07001674 boolean wasNavigating = mNavigating;
1675 switch (status) {
1676 case GPS_STATUS_SESSION_BEGIN:
1677 mNavigating = true;
1678 mEngineOn = true;
1679 break;
1680 case GPS_STATUS_SESSION_END:
1681 mNavigating = false;
1682 break;
1683 case GPS_STATUS_ENGINE_ON:
1684 mEngineOn = true;
1685 break;
1686 case GPS_STATUS_ENGINE_OFF:
1687 mEngineOn = false;
1688 mNavigating = false;
1689 break;
1690 }
Mike Lockwooddbd6fd82009-12-07 18:43:36 -05001691
destradaaea8a8a62014-06-23 18:19:03 -07001692 if (wasNavigating != mNavigating) {
destradaa13a60b02015-01-15 18:36:01 -08001693 mListenerHelper.onStatusChanged(mNavigating);
Mike Lockwoodcf1d8cb2010-01-20 10:14:54 -05001694
destradaaea8a8a62014-06-23 18:19:03 -07001695 // send an intent to notify that the GPS has been enabled or disabled
1696 Intent intent = new Intent(LocationManager.GPS_ENABLED_CHANGE_ACTION);
1697 intent.putExtra(LocationManager.EXTRA_GPS_ENABLED, mNavigating);
1698 mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001699 }
1700 }
1701
Wyatt Riley26465d22018-02-12 13:44:24 -08001702 // Helper class to carry data to handler for reportSvStatus
1703 private static class SvStatusInfo {
1704 public int mSvCount;
1705 public int[] mSvidWithFlags;
1706 public float[] mCn0s;
1707 public float[] mSvElevations;
1708 public float[] mSvAzimuths;
1709 public float[] mSvCarrierFreqs;
1710 }
1711
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001712 /**
1713 * called from native code to update SV info
1714 */
Wyatt Riley26465d22018-02-12 13:44:24 -08001715 private void reportSvStatus(int svCount, int[] svidWithFlags, float[] cn0s,
1716 float[] svElevations, float[] svAzimuths, float[] svCarrierFreqs) {
1717 SvStatusInfo svStatusInfo = new SvStatusInfo();
1718 svStatusInfo.mSvCount = svCount;
1719 svStatusInfo.mSvidWithFlags = svidWithFlags;
1720 svStatusInfo.mCn0s = cn0s;
1721 svStatusInfo.mSvElevations = svElevations;
1722 svStatusInfo.mSvAzimuths = svAzimuths;
1723 svStatusInfo.mSvCarrierFreqs = svCarrierFreqs;
1724
1725 sendMessage(REPORT_SV_STATUS, 0, svStatusInfo);
1726 }
1727
1728 private void handleReportSvStatus(SvStatusInfo info) {
destradaaea8a8a62014-06-23 18:19:03 -07001729 mListenerHelper.onSvStatusChanged(
Wyatt Riley26465d22018-02-12 13:44:24 -08001730 info.mSvCount,
1731 info.mSvidWithFlags,
1732 info.mCn0s,
1733 info.mSvElevations,
1734 info.mSvAzimuths,
1735 info.mSvCarrierFreqs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001736
Siddharth Ray168f12a2017-07-10 11:55:10 -07001737 // Log CN0 as part of GNSS metrics
Wyatt Riley26465d22018-02-12 13:44:24 -08001738 mGnssMetrics.logCn0(info.mCn0s, info.mSvCount);
Siddharth Ray168f12a2017-07-10 11:55:10 -07001739
Mike Lockwood29c84342009-05-06 14:01:15 -04001740 if (VERBOSE) {
Wyatt Riley26465d22018-02-12 13:44:24 -08001741 Log.v(TAG, "SV count: " + info.mSvCount);
Lifu Tang30f95a72016-01-07 23:20:38 -08001742 }
Wyatt Rileyc9f25dd2017-05-05 13:45:23 -07001743 // Calculate number of satellites used in fix.
Lifu Tang30f95a72016-01-07 23:20:38 -08001744 int usedInFixCount = 0;
Wyatt Rileyc9f25dd2017-05-05 13:45:23 -07001745 int maxCn0 = 0;
1746 int meanCn0 = 0;
Wyatt Riley26465d22018-02-12 13:44:24 -08001747 for (int i = 0; i < info.mSvCount; i++) {
1748 if ((info.mSvidWithFlags[i] & GnssStatus.GNSS_SV_FLAGS_USED_IN_FIX) != 0) {
Lifu Tang30f95a72016-01-07 23:20:38 -08001749 ++usedInFixCount;
Wyatt Riley26465d22018-02-12 13:44:24 -08001750 if (info.mCn0s[i] > maxCn0) {
1751 maxCn0 = (int) info.mCn0s[i];
Wyatt Rileyc9f25dd2017-05-05 13:45:23 -07001752 }
Wyatt Riley26465d22018-02-12 13:44:24 -08001753 meanCn0 += info.mCn0s[i];
Lifu Tang30f95a72016-01-07 23:20:38 -08001754 }
1755 if (VERBOSE) {
Wyatt Riley26465d22018-02-12 13:44:24 -08001756 Log.v(TAG, "svid: " + (info.mSvidWithFlags[i] >> GnssStatus.SVID_SHIFT_WIDTH) +
1757 " cn0: " + info.mCn0s[i] +
1758 " elev: " + info.mSvElevations[i] +
1759 " azimuth: " + info.mSvAzimuths[i] +
1760 " carrier frequency: " + info.mSvCarrierFreqs[i] +
1761 ((info.mSvidWithFlags[i] & GnssStatus.GNSS_SV_FLAGS_HAS_EPHEMERIS_DATA) == 0
Lifu Tang30f95a72016-01-07 23:20:38 -08001762 ? " " : " E") +
Wyatt Riley26465d22018-02-12 13:44:24 -08001763 ((info.mSvidWithFlags[i] & GnssStatus.GNSS_SV_FLAGS_HAS_ALMANAC_DATA) == 0
Lifu Tang30f95a72016-01-07 23:20:38 -08001764 ? " " : " A") +
Wyatt Riley26465d22018-02-12 13:44:24 -08001765 ((info.mSvidWithFlags[i] & GnssStatus.GNSS_SV_FLAGS_USED_IN_FIX) == 0
gomo4402af62017-01-11 13:20:13 -08001766 ? "" : "U") +
Wyatt Riley26465d22018-02-12 13:44:24 -08001767 ((info.mSvidWithFlags[i] &
1768 GnssStatus.GNSS_SV_FLAGS_HAS_CARRIER_FREQUENCY) == 0
gomo48f1a642017-11-10 20:35:46 -08001769 ? "" : "F"));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001770 }
1771 }
Wyatt Rileyc9f25dd2017-05-05 13:45:23 -07001772 if (usedInFixCount > 0) {
1773 meanCn0 /= usedInFixCount;
1774 }
1775 // return number of sats used in fix instead of total reported
Wyatt Rileyc7067412018-02-07 15:50:35 -08001776 mLocationExtras.set(usedInFixCount, meanCn0, maxCn0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001777
Mike Lockwood15e3d0f2009-05-01 07:53:28 -04001778 if (mNavigating && mStatus == LocationProvider.AVAILABLE && mLastFixTime > 0 &&
gomo48f1a642017-11-10 20:35:46 -08001779 SystemClock.elapsedRealtime() - mLastFixTime > RECENT_FIX_TIMEOUT) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001780 // send an intent to notify that the GPS is no longer receiving fixes.
Mike Lockwood00b74272010-03-26 10:41:48 -04001781 Intent intent = new Intent(LocationManager.GPS_FIX_CHANGE_ACTION);
1782 intent.putExtra(LocationManager.EXTRA_GPS_ENABLED, false);
Dianne Hackborn5ac72a22012-08-29 18:32:08 -07001783 mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
Wyatt Rileyc7067412018-02-07 15:50:35 -08001784 updateStatus(LocationProvider.TEMPORARILY_UNAVAILABLE);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001785 }
1786 }
Mike Lockwood58bda982009-04-14 16:25:07 -04001787
1788 /**
Mike Lockwoode3635c92009-05-11 08:38:02 -04001789 * called from native code to update AGPS status
Mike Lockwood58bda982009-04-14 16:25:07 -04001790 */
destradaa96a14702014-06-05 11:36:30 -07001791 private void reportAGpsStatus(int type, int status, byte[] ipaddr) {
Mike Lockwood58bda982009-04-14 16:25:07 -04001792 switch (status) {
Mike Lockwoode3635c92009-05-11 08:38:02 -04001793 case GPS_REQUEST_AGPS_DATA_CONN:
Mike Lockwoodb6e5fa82010-10-09 20:10:46 -04001794 if (DEBUG) Log.d(TAG, "GPS_REQUEST_AGPS_DATA_CONN");
Andreas Gampee6748ce2015-12-11 18:00:38 -08001795 Log.v(TAG, "Received SUPL IP addr[]: " + Arrays.toString(ipaddr));
destradaae21252a2015-09-08 12:32:59 -07001796 InetAddress connectionIpAddress = null;
destradaa96a14702014-06-05 11:36:30 -07001797 if (ipaddr != null) {
1798 try {
destradaae21252a2015-09-08 12:32:59 -07001799 connectionIpAddress = InetAddress.getByAddress(ipaddr);
1800 if (DEBUG) Log.d(TAG, "IP address converted to: " + connectionIpAddress);
destradaa96a14702014-06-05 11:36:30 -07001801 } catch (UnknownHostException e) {
1802 Log.e(TAG, "Bad IP Address: " + ipaddr, e);
destradaa96a14702014-06-05 11:36:30 -07001803 }
1804 }
destradaae21252a2015-09-08 12:32:59 -07001805 sendMessage(REQUEST_SUPL_CONNECTION, 0 /*arg*/, connectionIpAddress);
Mike Lockwood58bda982009-04-14 16:25:07 -04001806 break;
Mike Lockwoode3635c92009-05-11 08:38:02 -04001807 case GPS_RELEASE_AGPS_DATA_CONN:
Mike Lockwoodb6e5fa82010-10-09 20:10:46 -04001808 if (DEBUG) Log.d(TAG, "GPS_RELEASE_AGPS_DATA_CONN");
destradaae21252a2015-09-08 12:32:59 -07001809 releaseSuplConnection(GPS_RELEASE_AGPS_DATA_CONN);
Mike Lockwood58bda982009-04-14 16:25:07 -04001810 break;
Mike Lockwoode3635c92009-05-11 08:38:02 -04001811 case GPS_AGPS_DATA_CONNECTED:
Mike Lockwoodb6e5fa82010-10-09 20:10:46 -04001812 if (DEBUG) Log.d(TAG, "GPS_AGPS_DATA_CONNECTED");
Mike Lockwood58bda982009-04-14 16:25:07 -04001813 break;
Mike Lockwoode3635c92009-05-11 08:38:02 -04001814 case GPS_AGPS_DATA_CONN_DONE:
Mike Lockwoodb6e5fa82010-10-09 20:10:46 -04001815 if (DEBUG) Log.d(TAG, "GPS_AGPS_DATA_CONN_DONE");
Mike Lockwood58bda982009-04-14 16:25:07 -04001816 break;
Mike Lockwoode3635c92009-05-11 08:38:02 -04001817 case GPS_AGPS_DATA_CONN_FAILED:
Mike Lockwoodb6e5fa82010-10-09 20:10:46 -04001818 if (DEBUG) Log.d(TAG, "GPS_AGPS_DATA_CONN_FAILED");
Mike Lockwood58bda982009-04-14 16:25:07 -04001819 break;
destradaa931a37f2014-08-12 16:36:59 -07001820 default:
Joe Onorato0c484102016-02-01 18:04:24 -08001821 if (DEBUG) Log.d(TAG, "Received Unknown AGPS status: " + status);
Mike Lockwood58bda982009-04-14 16:25:07 -04001822 }
1823 }
1824
destradaae21252a2015-09-08 12:32:59 -07001825 private void releaseSuplConnection(int connStatus) {
1826 sendMessage(RELEASE_SUPL_CONNECTION, connStatus, null /*obj*/);
1827 }
1828
Mike Lockwoodb16e7802009-08-06 09:26:02 -04001829 /**
1830 * called from native code to report NMEA data received
1831 */
Mike Lockwoodf602d362010-06-20 14:28:16 -07001832 private void reportNmea(long timestamp) {
Wyatt Riley5d5bac82016-11-01 07:05:16 -07001833 if (!mItarSpeedLimitExceeded) {
1834 int length = native_read_nmea(mNmeaBuffer, mNmeaBuffer.length);
1835 String nmea = new String(mNmeaBuffer, 0 /* offset */, length);
1836 mListenerHelper.onNmeaReceived(timestamp, nmea);
1837 }
destradaaea8a8a62014-06-23 18:19:03 -07001838 }
Mike Lockwoodb16e7802009-08-06 09:26:02 -04001839
destradaaea8a8a62014-06-23 18:19:03 -07001840 /**
Wyatt Rileyaa420d52017-07-03 15:14:42 -07001841 * called from native code - GNSS measurements callback
destradaaea8a8a62014-06-23 18:19:03 -07001842 */
Lifu Tang818aa2c2016-02-01 01:52:00 -08001843 private void reportMeasurementData(GnssMeasurementsEvent event) {
Wyatt Riley5d5bac82016-11-01 07:05:16 -07001844 if (!mItarSpeedLimitExceeded) {
Wyatt Rileyaa420d52017-07-03 15:14:42 -07001845 // send to handler to allow native to return quickly
1846 mHandler.post(new Runnable() {
1847 @Override
1848 public void run() {
1849 mGnssMeasurementsProvider.onMeasurementsAvailable(event);
1850 }
1851 });
Wyatt Riley5d5bac82016-11-01 07:05:16 -07001852 }
Mike Lockwoodb16e7802009-08-06 09:26:02 -04001853 }
1854
Mike Lockwood62a8fc12010-03-22 14:23:26 -04001855 /**
Wyatt Rileyaa420d52017-07-03 15:14:42 -07001856 * called from native code - GNSS navigation message callback
destradaa4b3e3932014-07-21 18:01:47 -07001857 */
Lifu Tange8abe8e2016-04-01 10:32:05 -07001858 private void reportNavigationMessage(GnssNavigationMessage event) {
Wyatt Riley5d5bac82016-11-01 07:05:16 -07001859 if (!mItarSpeedLimitExceeded) {
Wyatt Rileyaa420d52017-07-03 15:14:42 -07001860 // send to handler to allow native to return quickly
1861 mHandler.post(new Runnable() {
1862 @Override
1863 public void run() {
1864 mGnssNavigationMessageProvider.onNavigationMessageAvailable(event);
1865 }
1866 });
Wyatt Riley5d5bac82016-11-01 07:05:16 -07001867 }
destradaa4b3e3932014-07-21 18:01:47 -07001868 }
1869
1870 /**
Mike Lockwood04598b62010-04-14 17:17:24 -04001871 * called from native code to inform us what the GPS engine capabilities are
1872 */
Wyatt Rileyd87cf912017-12-05 09:31:52 -08001873 private void setEngineCapabilities(final int capabilities) {
1874 // send to handler thread for fast native return, and in-order handling
1875 mHandler.post(new Runnable() {
1876 @Override
1877 public void run() {
1878 mEngineCapabilities = capabilities;
Mike Lockwood9b9fb5c2011-06-29 15:09:40 -04001879
Wyatt Rileyd87cf912017-12-05 09:31:52 -08001880 if (hasCapability(GPS_CAPABILITY_ON_DEMAND_TIME)) {
Yu-Han Yanga1862b52018-02-20 17:05:59 -08001881 mNtpTimeHelper.enablePeriodicTimeInjection();
Wyatt Rileyd87cf912017-12-05 09:31:52 -08001882 requestUtcTime();
1883 }
destradaa6568d702014-10-27 12:47:41 -07001884
Wyatt Rileyd87cf912017-12-05 09:31:52 -08001885 mGnssMeasurementsProvider.onCapabilitiesUpdated(hasCapability(
1886 GPS_CAPABILITY_MEASUREMENTS));
1887 mGnssNavigationMessageProvider.onCapabilitiesUpdated(hasCapability(
1888 GPS_CAPABILITY_NAV_MESSAGES));
Yu-Han Yang52057622018-04-25 00:51:22 -07001889 restartRequests();
Wyatt Rileyd87cf912017-12-05 09:31:52 -08001890 }
1891 });
Yu-Han Yang52057622018-04-25 00:51:22 -07001892 }
1893
1894 private void restartRequests() {
1895 Log.i(TAG, "restartRequests");
1896
1897 restartLocationRequest();
1898 mGnssMeasurementsProvider.resumeIfStarted();
1899 mGnssNavigationMessageProvider.resumeIfStarted();
1900 mGnssBatchingProvider.resumeIfStarted();
1901 mGnssGeofenceProvider.resumeIfStarted();
1902 }
1903
1904 private void restartLocationRequest() {
1905 if (DEBUG) Log.d(TAG, "restartLocationRequest");
1906 mStarted = false;
1907 updateRequirements();
1908 }
Wyatt Rileyd87cf912017-12-05 09:31:52 -08001909
1910 /**
1911 * Called from native code to inform us the hardware year.
1912 */
1913 private void setGnssYearOfHardware(final int yearOfHardware) {
1914 // mHardwareYear is simply set here, to be read elsewhere, and is volatile for safe sync
1915 if (DEBUG) Log.d(TAG, "setGnssYearOfHardware called with " + yearOfHardware);
1916 mHardwareYear = yearOfHardware;
Mike Lockwood04598b62010-04-14 17:17:24 -04001917 }
1918
1919 /**
Wyatt Rileyd87cf912017-12-05 09:31:52 -08001920 * Called from native code to inform us the hardware model name.
Lifu Tang82f893d2016-01-21 18:15:33 -08001921 */
Wyatt Rileyd87cf912017-12-05 09:31:52 -08001922 private void setGnssHardwareModelName(final String modelName) {
1923 // mHardwareModelName is simply set here, to be read elsewhere, and volatile for safe sync
1924 if (DEBUG) Log.d(TAG, "setGnssModelName called with " + modelName);
1925 mHardwareModelName = modelName;
Lifu Tang82f893d2016-01-21 18:15:33 -08001926 }
1927
Yu-Han Yang52057622018-04-25 00:51:22 -07001928 /**
1929 * Called from native code to inform us GNSS HAL service died.
1930 */
1931 private void reportGnssServiceDied() {
1932 if (DEBUG) Log.d(TAG, "reportGnssServiceDied");
1933 mHandler.post(() -> {
1934 class_init_native();
1935 native_init_once();
1936 if (isEnabled()) {
1937 // re-calls native_init() and other setup.
1938 handleEnable();
1939 // resend configuration into the restarted HAL service.
1940 reloadGpsProperties(mContext, mProperties);
1941 }
1942 });
1943 }
1944
Lifu Tang9363b942016-02-16 18:07:00 -08001945 public interface GnssSystemInfoProvider {
Lifu Tang82f893d2016-01-21 18:15:33 -08001946 /**
Wyatt Rileyd87cf912017-12-05 09:31:52 -08001947 * Returns the year of underlying GPS hardware.
Lifu Tang82f893d2016-01-21 18:15:33 -08001948 */
Lifu Tang9363b942016-02-16 18:07:00 -08001949 int getGnssYearOfHardware();
Wyatt Rileyd87cf912017-12-05 09:31:52 -08001950 /**
1951 * Returns the model name of underlying GPS hardware.
1952 */
1953 String getGnssHardwareModelName();
Lifu Tang82f893d2016-01-21 18:15:33 -08001954 }
1955
1956 /**
1957 * @hide
1958 */
Lifu Tang9363b942016-02-16 18:07:00 -08001959 public GnssSystemInfoProvider getGnssSystemInfoProvider() {
1960 return new GnssSystemInfoProvider() {
Lifu Tang82f893d2016-01-21 18:15:33 -08001961 @Override
Lifu Tang9363b942016-02-16 18:07:00 -08001962 public int getGnssYearOfHardware() {
Wyatt Rileyd87cf912017-12-05 09:31:52 -08001963 return mHardwareYear;
1964 }
1965 @Override
1966 public String getGnssHardwareModelName() {
1967 return mHardwareModelName;
Lifu Tang82f893d2016-01-21 18:15:33 -08001968 }
1969 };
1970 }
1971
Wyatt Rileycf879db2017-01-12 13:57:38 -08001972 /**
1973 * @hide
1974 */
1975 public GnssBatchingProvider getGnssBatchingProvider() {
Yu-Han Yang3557cc72018-03-21 12:48:36 -07001976 return mGnssBatchingProvider;
Wyatt Rileycf879db2017-01-12 13:57:38 -08001977 }
1978
Siddharth Raybb608c82017-03-16 11:33:34 -07001979 public interface GnssMetricsProvider {
1980 /**
1981 * Returns GNSS metrics as proto string
1982 */
1983 String getGnssMetricsAsProtoString();
1984 }
1985
1986 /**
1987 * @hide
1988 */
1989 public GnssMetricsProvider getGnssMetricsProvider() {
1990 return new GnssMetricsProvider() {
1991 @Override
1992 public String getGnssMetricsAsProtoString() {
1993 return mGnssMetrics.dumpGnssMetricsAsProtoString();
1994 }
1995 };
1996 }
1997
Wyatt Rileycf879db2017-01-12 13:57:38 -08001998 /**
Wyatt Rileycf879db2017-01-12 13:57:38 -08001999 * called from native code - GNSS location batch callback
2000 */
2001 private void reportLocationBatch(Location[] locationArray) {
2002 List<Location> locations = new ArrayList<>(Arrays.asList(locationArray));
gomo48f1a642017-11-10 20:35:46 -08002003 if (DEBUG) {
2004 Log.d(TAG, "Location batch of size " + locationArray.length + " reported");
2005 }
Wyatt Rileycf879db2017-01-12 13:57:38 -08002006 try {
2007 mILocationManager.reportLocationBatch(locations);
2008 } catch (RemoteException e) {
2009 Log.e(TAG, "RemoteException calling reportLocationBatch");
2010 }
2011 }
2012
Lifu Tang82f893d2016-01-21 18:15:33 -08002013 /**
Mike Lockwood62a8fc12010-03-22 14:23:26 -04002014 * called from native code to request XTRA data
2015 */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002016 private void xtraDownloadRequest() {
Joe Onoratof5d95cb2010-01-07 21:48:32 -05002017 if (DEBUG) Log.d(TAG, "xtraDownloadRequest");
Mike Lockwood98e48692010-04-07 16:32:51 -04002018 sendMessage(DOWNLOAD_XTRA_DATA, 0, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002019 }
2020
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07002021 /**
destradaa0682809a2013-08-12 18:50:30 -07002022 * Converts the GPS HAL status to the internal Geofence Hardware status.
2023 */
2024 private int getGeofenceStatus(int status) {
gomo48f1a642017-11-10 20:35:46 -08002025 switch (status) {
destradaa0682809a2013-08-12 18:50:30 -07002026 case GPS_GEOFENCE_OPERATION_SUCCESS:
2027 return GeofenceHardware.GEOFENCE_SUCCESS;
2028 case GPS_GEOFENCE_ERROR_GENERIC:
2029 return GeofenceHardware.GEOFENCE_FAILURE;
2030 case GPS_GEOFENCE_ERROR_ID_EXISTS:
2031 return GeofenceHardware.GEOFENCE_ERROR_ID_EXISTS;
2032 case GPS_GEOFENCE_ERROR_INVALID_TRANSITION:
2033 return GeofenceHardware.GEOFENCE_ERROR_INVALID_TRANSITION;
2034 case GPS_GEOFENCE_ERROR_TOO_MANY_GEOFENCES:
2035 return GeofenceHardware.GEOFENCE_ERROR_TOO_MANY_GEOFENCES;
2036 case GPS_GEOFENCE_ERROR_ID_UNKNOWN:
2037 return GeofenceHardware.GEOFENCE_ERROR_ID_UNKNOWN;
2038 default:
2039 return -1;
2040 }
2041 }
2042
2043 /**
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07002044 * Called from native to report GPS Geofence transition
2045 * All geofence callbacks are called on the same thread
2046 */
Wyatt Riley5d229832017-02-10 17:06:00 -08002047 private void reportGeofenceTransition(int geofenceId, Location location, int transition,
gomo48f1a642017-11-10 20:35:46 -08002048 long transitionTimestamp) {
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07002049 if (mGeofenceHardwareImpl == null) {
2050 mGeofenceHardwareImpl = GeofenceHardwareImpl.getInstance(mContext);
2051 }
Wyatt Riley5d229832017-02-10 17:06:00 -08002052
destradaa0682809a2013-08-12 18:50:30 -07002053 mGeofenceHardwareImpl.reportGeofenceTransition(
2054 geofenceId,
2055 location,
2056 transition,
2057 transitionTimestamp,
2058 GeofenceHardware.MONITORING_TYPE_GPS_HARDWARE,
2059 FusedBatchOptions.SourceTechnologies.GNSS);
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07002060 }
2061
2062 /**
2063 * called from native code to report GPS status change.
2064 */
Wyatt Riley5d229832017-02-10 17:06:00 -08002065 private void reportGeofenceStatus(int status, Location location) {
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07002066 if (mGeofenceHardwareImpl == null) {
2067 mGeofenceHardwareImpl = GeofenceHardwareImpl.getInstance(mContext);
2068 }
destradaa0682809a2013-08-12 18:50:30 -07002069 int monitorStatus = GeofenceHardware.MONITOR_CURRENTLY_UNAVAILABLE;
gomo48f1a642017-11-10 20:35:46 -08002070 if (status == GPS_GEOFENCE_AVAILABLE) {
destradaa0682809a2013-08-12 18:50:30 -07002071 monitorStatus = GeofenceHardware.MONITOR_CURRENTLY_AVAILABLE;
2072 }
2073 mGeofenceHardwareImpl.reportGeofenceMonitorStatus(
2074 GeofenceHardware.MONITORING_TYPE_GPS_HARDWARE,
2075 monitorStatus,
2076 location,
2077 FusedBatchOptions.SourceTechnologies.GNSS);
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07002078 }
2079
2080 /**
2081 * called from native code - Geofence Add callback
2082 */
2083 private void reportGeofenceAddStatus(int geofenceId, int status) {
2084 if (mGeofenceHardwareImpl == null) {
2085 mGeofenceHardwareImpl = GeofenceHardwareImpl.getInstance(mContext);
2086 }
destradaa0682809a2013-08-12 18:50:30 -07002087 mGeofenceHardwareImpl.reportGeofenceAddStatus(geofenceId, getGeofenceStatus(status));
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07002088 }
2089
2090 /**
2091 * called from native code - Geofence Remove callback
2092 */
2093 private void reportGeofenceRemoveStatus(int geofenceId, int status) {
2094 if (mGeofenceHardwareImpl == null) {
2095 mGeofenceHardwareImpl = GeofenceHardwareImpl.getInstance(mContext);
2096 }
destradaa0682809a2013-08-12 18:50:30 -07002097 mGeofenceHardwareImpl.reportGeofenceRemoveStatus(geofenceId, getGeofenceStatus(status));
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07002098 }
2099
2100 /**
2101 * called from native code - Geofence Pause callback
2102 */
2103 private void reportGeofencePauseStatus(int geofenceId, int status) {
2104 if (mGeofenceHardwareImpl == null) {
2105 mGeofenceHardwareImpl = GeofenceHardwareImpl.getInstance(mContext);
2106 }
destradaa0682809a2013-08-12 18:50:30 -07002107 mGeofenceHardwareImpl.reportGeofencePauseStatus(geofenceId, getGeofenceStatus(status));
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07002108 }
2109
2110 /**
2111 * called from native code - Geofence Resume callback
2112 */
2113 private void reportGeofenceResumeStatus(int geofenceId, int status) {
2114 if (mGeofenceHardwareImpl == null) {
2115 mGeofenceHardwareImpl = GeofenceHardwareImpl.getInstance(mContext);
2116 }
destradaa0682809a2013-08-12 18:50:30 -07002117 mGeofenceHardwareImpl.reportGeofenceResumeStatus(geofenceId, getGeofenceStatus(status));
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07002118 }
2119
Danke Xie22d1f9f2009-08-18 18:28:45 -04002120 //=============================================================
2121 // NI Client support
Miguel Torroja1e84da82010-07-27 07:02:24 +02002122 //=============================================================
Danke Xie22d1f9f2009-08-18 18:28:45 -04002123 private final INetInitiatedListener mNetInitiatedListener = new INetInitiatedListener.Stub() {
destradaaef752b62015-04-17 13:10:47 -07002124 // Sends a response for an NI request to HAL.
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002125 @Override
gomo48f1a642017-11-10 20:35:46 -08002126 public boolean sendNiResponse(int notificationId, int userResponse) {
Miguel Torroja1e84da82010-07-27 07:02:24 +02002127 // TODO Add Permission check
Danke Xie22d1f9f2009-08-18 18:28:45 -04002128
gomo48f1a642017-11-10 20:35:46 -08002129 if (DEBUG) {
2130 Log.d(TAG, "sendNiResponse, notifId: " + notificationId +
2131 ", response: " + userResponse);
2132 }
Miguel Torroja1e84da82010-07-27 07:02:24 +02002133 native_send_ni_response(notificationId, userResponse);
2134 return true;
2135 }
Danke Xie22d1f9f2009-08-18 18:28:45 -04002136 };
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002137
Danke Xie22d1f9f2009-08-18 18:28:45 -04002138 public INetInitiatedListener getNetInitiatedListener() {
2139 return mNetInitiatedListener;
2140 }
2141
2142 // Called by JNI function to report an NI request.
Miguel Torroja1e84da82010-07-27 07:02:24 +02002143 public void reportNiNotification(
2144 int notificationId,
2145 int niType,
2146 int notifyFlags,
2147 int timeout,
2148 int defaultResponse,
2149 String requestorId,
2150 String text,
2151 int requestorIdEncoding,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002152 int textEncoding
gomo48f1a642017-11-10 20:35:46 -08002153 ) {
Miguel Torroja1e84da82010-07-27 07:02:24 +02002154 Log.i(TAG, "reportNiNotification: entered");
2155 Log.i(TAG, "notificationId: " + notificationId +
2156 ", niType: " + niType +
2157 ", notifyFlags: " + notifyFlags +
2158 ", timeout: " + timeout +
2159 ", defaultResponse: " + defaultResponse);
2160
2161 Log.i(TAG, "requestorId: " + requestorId +
2162 ", text: " + text +
2163 ", requestorIdEncoding: " + requestorIdEncoding +
2164 ", textEncoding: " + textEncoding);
2165
2166 GpsNiNotification notification = new GpsNiNotification();
2167
2168 notification.notificationId = notificationId;
2169 notification.niType = niType;
2170 notification.needNotify = (notifyFlags & GpsNetInitiatedHandler.GPS_NI_NEED_NOTIFY) != 0;
2171 notification.needVerify = (notifyFlags & GpsNetInitiatedHandler.GPS_NI_NEED_VERIFY) != 0;
gomo48f1a642017-11-10 20:35:46 -08002172 notification.privacyOverride =
2173 (notifyFlags & GpsNetInitiatedHandler.GPS_NI_PRIVACY_OVERRIDE) != 0;
Miguel Torroja1e84da82010-07-27 07:02:24 +02002174 notification.timeout = timeout;
2175 notification.defaultResponse = defaultResponse;
2176 notification.requestorId = requestorId;
2177 notification.text = text;
2178 notification.requestorIdEncoding = requestorIdEncoding;
2179 notification.textEncoding = textEncoding;
2180
Miguel Torroja1e84da82010-07-27 07:02:24 +02002181 mNIHandler.handleNiNotification(notification);
2182 }
2183
2184 /**
2185 * Called from native code to request set id info.
2186 * We should be careful about receiving null string from the TelephonyManager,
2187 * because sending null String to JNI function would cause a crash.
2188 */
2189
2190 private void requestSetID(int flags) {
2191 TelephonyManager phone = (TelephonyManager)
2192 mContext.getSystemService(Context.TELEPHONY_SERVICE);
destradaaef752b62015-04-17 13:10:47 -07002193 int type = AGPS_SETID_TYPE_NONE;
Miguel Torroja1e84da82010-07-27 07:02:24 +02002194 String data = "";
2195
2196 if ((flags & AGPS_RIL_REQUEST_SETID_IMSI) == AGPS_RIL_REQUEST_SETID_IMSI) {
2197 String data_temp = phone.getSubscriberId();
2198 if (data_temp == null) {
2199 // This means the framework does not have the SIM card ready.
2200 } else {
2201 // This means the framework has the SIM card.
2202 data = data_temp;
2203 type = AGPS_SETID_TYPE_IMSI;
2204 }
gomo48f1a642017-11-10 20:35:46 -08002205 } else if ((flags & AGPS_RIL_REQUEST_SETID_MSISDN) == AGPS_RIL_REQUEST_SETID_MSISDN) {
Miguel Torroja1e84da82010-07-27 07:02:24 +02002206 String data_temp = phone.getLine1Number();
2207 if (data_temp == null) {
2208 // This means the framework does not have the SIM card ready.
2209 } else {
2210 // This means the framework has the SIM card.
2211 data = data_temp;
2212 type = AGPS_SETID_TYPE_MSISDN;
2213 }
2214 }
2215 native_agps_set_id(type, data);
2216 }
2217
2218 /**
Yu-Han Yange7baef32018-02-09 13:58:17 -08002219 * Called from native code to request location info.
2220 */
2221 private void requestLocation(boolean independentFromGnss) {
2222 if (DEBUG) {
2223 Log.d(TAG, "requestLocation. independentFromGnss: " + independentFromGnss);
2224 }
2225 sendMessage(REQUEST_LOCATION, 0, independentFromGnss);
2226 }
2227
2228 /**
Mike Lockwood9b9fb5c2011-06-29 15:09:40 -04002229 * Called from native code to request utc time info
2230 */
Mike Lockwood9b9fb5c2011-06-29 15:09:40 -04002231 private void requestUtcTime() {
destradaae21252a2015-09-08 12:32:59 -07002232 if (DEBUG) Log.d(TAG, "utcTimeRequest");
Mike Lockwood9b9fb5c2011-06-29 15:09:40 -04002233 sendMessage(INJECT_NTP_TIME, 0, null);
2234 }
2235
2236 /**
Miguel Torroja1e84da82010-07-27 07:02:24 +02002237 * Called from native code to request reference location info
2238 */
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002239 private void requestRefLocation() {
Miguel Torroja1e84da82010-07-27 07:02:24 +02002240 TelephonyManager phone = (TelephonyManager)
2241 mContext.getSystemService(Context.TELEPHONY_SERVICE);
Victoria Leased50d0c32012-10-29 13:16:17 -07002242 final int phoneType = phone.getPhoneType();
2243 if (phoneType == TelephonyManager.PHONE_TYPE_GSM) {
Miguel Torroja1e84da82010-07-27 07:02:24 +02002244 GsmCellLocation gsm_cell = (GsmCellLocation) phone.getCellLocation();
Victoria Leased50d0c32012-10-29 13:16:17 -07002245 if ((gsm_cell != null) && (phone.getNetworkOperator() != null)
2246 && (phone.getNetworkOperator().length() > 3)) {
Miguel Torroja1e84da82010-07-27 07:02:24 +02002247 int type;
gomo48f1a642017-11-10 20:35:46 -08002248 int mcc = Integer.parseInt(phone.getNetworkOperator().substring(0, 3));
Miguel Torroja1e84da82010-07-27 07:02:24 +02002249 int mnc = Integer.parseInt(phone.getNetworkOperator().substring(3));
Mike Lockwoodedc0f3872010-10-22 09:16:17 -04002250 int networkType = phone.getNetworkType();
2251 if (networkType == TelephonyManager.NETWORK_TYPE_UMTS
gomo48f1a642017-11-10 20:35:46 -08002252 || networkType == TelephonyManager.NETWORK_TYPE_HSDPA
2253 || networkType == TelephonyManager.NETWORK_TYPE_HSUPA
2254 || networkType == TelephonyManager.NETWORK_TYPE_HSPA
2255 || networkType == TelephonyManager.NETWORK_TYPE_HSPAP) {
Miguel Torroja1e84da82010-07-27 07:02:24 +02002256 type = AGPS_REF_LOCATION_TYPE_UMTS_CELLID;
Mike Lockwoodedc0f3872010-10-22 09:16:17 -04002257 } else {
Miguel Torroja1e84da82010-07-27 07:02:24 +02002258 type = AGPS_REF_LOCATION_TYPE_GSM_CELLID;
Mike Lockwoodedc0f3872010-10-22 09:16:17 -04002259 }
Miguel Torroja1e84da82010-07-27 07:02:24 +02002260 native_agps_set_ref_location_cellid(type, mcc, mnc,
2261 gsm_cell.getLac(), gsm_cell.getCid());
Mike Lockwoodedc0f3872010-10-22 09:16:17 -04002262 } else {
gomo48f1a642017-11-10 20:35:46 -08002263 Log.e(TAG, "Error getting cell location info.");
Mike Lockwoodedc0f3872010-10-22 09:16:17 -04002264 }
Victoria Leased50d0c32012-10-29 13:16:17 -07002265 } else if (phoneType == TelephonyManager.PHONE_TYPE_CDMA) {
2266 Log.e(TAG, "CDMA not supported.");
Mike Lockwoodedc0f3872010-10-22 09:16:17 -04002267 }
Miguel Torroja1e84da82010-07-27 07:02:24 +02002268 }
Danke Xie22d1f9f2009-08-18 18:28:45 -04002269
Mike Lockwood98e48692010-04-07 16:32:51 -04002270 private void sendMessage(int message, int arg, Object obj) {
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002271 // hold a wake lock until this message is delivered
Jeff Brown028872f2012-08-25 13:07:01 -07002272 // note that this assumes the message will not be removed from the queue before
2273 // it is handled (otherwise the wake lock would be leaked).
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002274 mWakeLock.acquire();
Wyatt Rileycf879db2017-01-12 13:57:38 -08002275 if (Log.isLoggable(TAG, Log.INFO)) {
2276 Log.i(TAG, "WakeLock acquired by sendMessage(" + messageIdAsString(message) + ", " + arg
2277 + ", " + obj + ")");
2278 }
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002279 mHandler.obtainMessage(message, arg, 1, obj).sendToTarget();
Mike Lockwood98e48692010-04-07 16:32:51 -04002280 }
2281
Mike Lockwood62a8fc12010-03-22 14:23:26 -04002282 private final class ProviderHandler extends Handler {
Victoria Lease5cd731a2012-12-19 15:04:21 -08002283 public ProviderHandler(Looper looper) {
2284 super(looper, null, true /*async*/);
Jeff Brown028872f2012-08-25 13:07:01 -07002285 }
2286
Mike Lockwood62a8fc12010-03-22 14:23:26 -04002287 @Override
Mike Lockwood4a7b65e2010-10-25 16:35:55 -04002288 public void handleMessage(Message msg) {
Mike Lockwood98e48692010-04-07 16:32:51 -04002289 int message = msg.what;
2290 switch (message) {
Mike Lockwood62a8fc12010-03-22 14:23:26 -04002291 case ENABLE:
2292 if (msg.arg1 == 1) {
2293 handleEnable();
2294 } else {
2295 handleDisable();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002296 }
Mike Lockwood62a8fc12010-03-22 14:23:26 -04002297 break;
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002298 case SET_REQUEST:
2299 GpsRequest gpsRequest = (GpsRequest) msg.obj;
2300 handleSetRequest(gpsRequest.request, gpsRequest.source);
Mike Lockwood03ca2162010-04-01 08:10:09 -07002301 break;
Mike Lockwood62a8fc12010-03-22 14:23:26 -04002302 case UPDATE_NETWORK_STATE:
destradaae21252a2015-09-08 12:32:59 -07002303 handleUpdateNetworkState((Network) msg.obj);
2304 break;
2305 case REQUEST_SUPL_CONNECTION:
2306 handleRequestSuplConnection((InetAddress) msg.obj);
2307 break;
2308 case RELEASE_SUPL_CONNECTION:
2309 handleReleaseSuplConnection(msg.arg1);
Mike Lockwood62a8fc12010-03-22 14:23:26 -04002310 break;
2311 case INJECT_NTP_TIME:
Yu-Han Yanga1862b52018-02-20 17:05:59 -08002312 mNtpTimeHelper.retrieveAndInjectNtpTime();
Mike Lockwood62a8fc12010-03-22 14:23:26 -04002313 break;
Yu-Han Yange7baef32018-02-09 13:58:17 -08002314 case REQUEST_LOCATION:
2315 handleRequestLocation((boolean) msg.obj);
2316 break;
Mike Lockwood62a8fc12010-03-22 14:23:26 -04002317 case DOWNLOAD_XTRA_DATA:
Wyatt Riley0d6e54e22016-10-05 12:03:03 -07002318 handleDownloadXtraData();
Mike Lockwood62a8fc12010-03-22 14:23:26 -04002319 break;
Kevin Tang40e1baf2012-01-10 14:32:44 -08002320 case DOWNLOAD_XTRA_DATA_FINISHED:
2321 mDownloadXtraDataPending = STATE_IDLE;
2322 break;
Mike Lockwood62a8fc12010-03-22 14:23:26 -04002323 case UPDATE_LOCATION:
destradaae21252a2015-09-08 12:32:59 -07002324 handleUpdateLocation((Location) msg.obj);
Mike Lockwood62a8fc12010-03-22 14:23:26 -04002325 break;
destradaafb23c672015-04-16 14:01:27 -07002326 case SUBSCRIPTION_OR_SIM_CHANGED:
2327 subscriptionOrSimChanged(mContext);
2328 break;
2329 case INITIALIZE_HANDLER:
destradaae21252a2015-09-08 12:32:59 -07002330 handleInitialize();
destradaafb23c672015-04-16 14:01:27 -07002331 break;
Wyatt Riley26465d22018-02-12 13:44:24 -08002332 case REPORT_LOCATION:
2333 handleReportLocation(msg.arg1 == 1, (Location) msg.obj);
2334 break;
2335 case REPORT_SV_STATUS:
2336 handleReportSvStatus((SvStatusInfo) msg.obj);
2337 break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002338 }
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002339 if (msg.arg2 == 1) {
2340 // wakelock was taken for this message, release it
2341 mWakeLock.release();
Wyatt Rileycf879db2017-01-12 13:57:38 -08002342 if (Log.isLoggable(TAG, Log.INFO)) {
2343 Log.i(TAG, "WakeLock released by handleMessage(" + messageIdAsString(message)
2344 + ", " + msg.arg1 + ", " + msg.obj + ")");
2345 }
Mike Lockwood98e48692010-04-07 16:32:51 -04002346 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002347 }
destradaafb23c672015-04-16 14:01:27 -07002348
2349 /**
Lifu Tang30f95a72016-01-07 23:20:38 -08002350 * This method is bound to {@link #GnssLocationProvider(Context, ILocationManager, Looper)}.
destradaafb23c672015-04-16 14:01:27 -07002351 * It is in charge of loading properties and registering for events that will be posted to
2352 * this handler.
2353 */
destradaae21252a2015-09-08 12:32:59 -07002354 private void handleInitialize() {
Yu-Han Yang6d317352018-03-15 11:53:01 -07002355 native_init_once();
2356
Wyatt Riley523a0cf2017-10-31 14:36:52 -07002357 /*
2358 * A cycle of native_init() and native_cleanup() is needed so that callbacks are
2359 * registered after bootup even when location is disabled.
2360 * This will allow Emergency SUPL to work even when location is disabled before device
2361 * restart.
2362 */
2363 boolean isInitialized = native_init();
gomo48f1a642017-11-10 20:35:46 -08002364 if (!isInitialized) {
Wyatt Riley523a0cf2017-10-31 14:36:52 -07002365 Log.w(TAG, "Native initialization failed at bootup");
2366 } else {
2367 native_cleanup();
2368 }
2369
destradaafb23c672015-04-16 14:01:27 -07002370 // load default GPS configuration
2371 // (this configuration might change in the future based on SIM changes)
2372 reloadGpsProperties(mContext, mProperties);
2373
2374 // TODO: When this object "finishes" we should unregister by invoking
gomo48f1a642017-11-10 20:35:46 -08002375 // SubscriptionManager.getInstance(mContext).unregister
2376 // (mOnSubscriptionsChangedListener);
destradaafb23c672015-04-16 14:01:27 -07002377 // This is not strictly necessary because it will be unregistered if the
2378 // notification fails but it is good form.
2379
2380 // Register for SubscriptionInfo list changes which is guaranteed
2381 // to invoke onSubscriptionsChanged the first time.
2382 SubscriptionManager.from(mContext)
2383 .addOnSubscriptionsChangedListener(mOnSubscriptionsChangedListener);
2384
2385 // listen for events
destradaaef752b62015-04-17 13:10:47 -07002386 IntentFilter intentFilter;
2387 if (native_is_agps_ril_supported()) {
2388 intentFilter = new IntentFilter();
2389 intentFilter.addAction(Intents.DATA_SMS_RECEIVED_ACTION);
2390 intentFilter.addDataScheme("sms");
2391 intentFilter.addDataAuthority("localhost", "7275");
2392 mContext.registerReceiver(mBroadcastReceiver, intentFilter, null, this);
destradaafb23c672015-04-16 14:01:27 -07002393
destradaaef752b62015-04-17 13:10:47 -07002394 intentFilter = new IntentFilter();
2395 intentFilter.addAction(Intents.WAP_PUSH_RECEIVED_ACTION);
2396 try {
2397 intentFilter.addDataType("application/vnd.omaloc-supl-init");
2398 } catch (IntentFilter.MalformedMimeTypeException e) {
2399 Log.w(TAG, "Malformed SUPL init mime type");
2400 }
2401 mContext.registerReceiver(mBroadcastReceiver, intentFilter, null, this);
2402 } else if (DEBUG) {
2403 Log.d(TAG, "Skipped registration for SMS/WAP-PUSH messages because AGPS Ril in GPS"
2404 + " HAL is not supported");
destradaafb23c672015-04-16 14:01:27 -07002405 }
destradaafb23c672015-04-16 14:01:27 -07002406
2407 intentFilter = new IntentFilter();
2408 intentFilter.addAction(ALARM_WAKEUP);
2409 intentFilter.addAction(ALARM_TIMEOUT);
destradaafb23c672015-04-16 14:01:27 -07002410 intentFilter.addAction(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED);
Adam Lesinski87c17df2015-05-27 13:24:13 -07002411 intentFilter.addAction(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED);
destradaafb23c672015-04-16 14:01:27 -07002412 intentFilter.addAction(Intent.ACTION_SCREEN_OFF);
2413 intentFilter.addAction(Intent.ACTION_SCREEN_ON);
2414 intentFilter.addAction(SIM_STATE_CHANGED);
2415 mContext.registerReceiver(mBroadcastReceiver, intentFilter, null, this);
2416
destradaae21252a2015-09-08 12:32:59 -07002417 // register for connectivity change events, this is equivalent to the deprecated way of
2418 // registering for CONNECTIVITY_ACTION broadcasts
2419 NetworkRequest.Builder networkRequestBuilder = new NetworkRequest.Builder();
Jeff Sharkeyc159d522018-03-28 10:54:07 -06002420 networkRequestBuilder.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
2421 networkRequestBuilder.addCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED);
2422 networkRequestBuilder.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN);
destradaae21252a2015-09-08 12:32:59 -07002423 NetworkRequest networkRequest = networkRequestBuilder.build();
2424 mConnMgr.registerNetworkCallback(networkRequest, mNetworkConnectivityCallback);
2425
destradaafb23c672015-04-16 14:01:27 -07002426 // listen for PASSIVE_PROVIDER updates
2427 LocationManager locManager =
2428 (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE);
2429 long minTime = 0;
2430 float minDistance = 0;
2431 boolean oneShot = false;
2432 LocationRequest request = LocationRequest.createFromDeprecatedProvider(
2433 LocationManager.PASSIVE_PROVIDER,
2434 minTime,
2435 minDistance,
2436 oneShot);
2437 // Don't keep track of this request since it's done on behalf of other clients
2438 // (which are kept track of separately).
2439 request.setHideFromAppOps(true);
2440 locManager.requestLocationUpdates(
2441 request,
2442 new NetworkLocationListener(),
2443 getLooper());
2444 }
2445 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002446
Yu-Han Yange7baef32018-02-09 13:58:17 -08002447 private abstract class LocationChangeListener implements LocationListener {
Yu-Han Yang07561382018-02-21 13:08:37 -08002448 int numLocationUpdateRequest;
2449
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002450 @Override
gomo48f1a642017-11-10 20:35:46 -08002451 public void onStatusChanged(String provider, int status, Bundle extras) {
2452 }
2453
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002454 @Override
gomo48f1a642017-11-10 20:35:46 -08002455 public void onProviderEnabled(String provider) {
2456 }
2457
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002458 @Override
gomo48f1a642017-11-10 20:35:46 -08002459 public void onProviderDisabled(String provider) {
2460 }
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002461 }
2462
Yu-Han Yange7baef32018-02-09 13:58:17 -08002463 private final class NetworkLocationListener extends LocationChangeListener {
2464 @Override
2465 public void onLocationChanged(Location location) {
2466 // this callback happens on mHandler looper
2467 if (LocationManager.NETWORK_PROVIDER.equals(location.getProvider())) {
2468 handleUpdateLocation(location);
2469 }
2470 }
2471 }
2472
2473 private final class FusedLocationListener extends LocationChangeListener {
2474 @Override
2475 public void onLocationChanged(Location location) {
2476 if (LocationManager.FUSED_PROVIDER.equals(location.getProvider())) {
Yu-Han Yange7baef32018-02-09 13:58:17 -08002477 injectBestLocation(location);
2478 }
2479 }
2480 }
2481
Kevin Tanga5fe6b22011-06-05 14:25:16 -07002482 private String getSelectedApn() {
2483 Uri uri = Uri.parse("content://telephony/carriers/preferapn");
destradaa96a14702014-06-05 11:36:30 -07002484 Cursor cursor = null;
2485 try {
2486 cursor = mContext.getContentResolver().query(
2487 uri,
gomo48f1a642017-11-10 20:35:46 -08002488 new String[]{"apn"},
destradaa96a14702014-06-05 11:36:30 -07002489 null /* selection */,
2490 null /* selectionArgs */,
2491 Carriers.DEFAULT_SORT_ORDER);
2492 if (cursor != null && cursor.moveToFirst()) {
2493 return cursor.getString(0);
2494 } else {
2495 Log.e(TAG, "No APN found to select.");
2496 }
2497 } catch (Exception e) {
destradaaea8a8a62014-06-23 18:19:03 -07002498 Log.e(TAG, "Error encountered on selecting the APN.", e);
destradaa96a14702014-06-05 11:36:30 -07002499 } finally {
2500 if (cursor != null) {
Kevin Tanga5fe6b22011-06-05 14:25:16 -07002501 cursor.close();
2502 }
2503 }
destradaa96a14702014-06-05 11:36:30 -07002504
2505 return null;
2506 }
2507
2508 private int getApnIpType(String apn) {
destradaae21252a2015-09-08 12:32:59 -07002509 ensureInHandlerThread();
destradaa96a14702014-06-05 11:36:30 -07002510 if (apn == null) {
2511 return APN_INVALID;
2512 }
2513
destradaa96a14702014-06-05 11:36:30 -07002514 String selection = String.format("current = 1 and apn = '%s' and carrier_enabled = 1", apn);
2515 Cursor cursor = null;
2516 try {
2517 cursor = mContext.getContentResolver().query(
2518 Carriers.CONTENT_URI,
gomo48f1a642017-11-10 20:35:46 -08002519 new String[]{Carriers.PROTOCOL},
destradaa96a14702014-06-05 11:36:30 -07002520 selection,
2521 null,
2522 Carriers.DEFAULT_SORT_ORDER);
2523
2524 if (null != cursor && cursor.moveToFirst()) {
2525 return translateToApnIpType(cursor.getString(0), apn);
2526 } else {
2527 Log.e(TAG, "No entry found in query for APN: " + apn);
2528 }
2529 } catch (Exception e) {
2530 Log.e(TAG, "Error encountered on APN query for: " + apn, e);
2531 } finally {
2532 if (cursor != null) {
2533 cursor.close();
2534 }
2535 }
2536
2537 return APN_INVALID;
2538 }
2539
2540 private int translateToApnIpType(String ipProtocol, String apn) {
2541 if ("IP".equals(ipProtocol)) {
2542 return APN_IPV4;
2543 }
2544 if ("IPV6".equals(ipProtocol)) {
2545 return APN_IPV6;
2546 }
2547 if ("IPV4V6".equals(ipProtocol)) {
2548 return APN_IPV4V6;
2549 }
2550
2551 // we hit the default case so the ipProtocol is not recognized
2552 String message = String.format("Unknown IP Protocol: %s, for APN: %s", ipProtocol, apn);
2553 Log.e(TAG, message);
2554 return APN_INVALID;
2555 }
2556
2557 private void setRouting() {
2558 if (mAGpsDataConnectionIpAddr == null) {
2559 return;
2560 }
2561
destradaae21252a2015-09-08 12:32:59 -07002562 // TODO: replace the use of this deprecated API
destradaa96a14702014-06-05 11:36:30 -07002563 boolean result = mConnMgr.requestRouteToHostAddress(
2564 ConnectivityManager.TYPE_MOBILE_SUPL,
2565 mAGpsDataConnectionIpAddr);
2566
2567 if (!result) {
2568 Log.e(TAG, "Error requesting route to host: " + mAGpsDataConnectionIpAddr);
2569 } else if (DEBUG) {
2570 Log.d(TAG, "Successfully requested route to host: " + mAGpsDataConnectionIpAddr);
2571 }
Kevin Tanga5fe6b22011-06-05 14:25:16 -07002572 }
2573
destradaae21252a2015-09-08 12:32:59 -07002574 /**
2575 * @return {@code true} if there is a data network available for outgoing connections,
gomo48f1a642017-11-10 20:35:46 -08002576 * {@code false} otherwise.
destradaae21252a2015-09-08 12:32:59 -07002577 */
2578 private boolean isDataNetworkConnected() {
2579 NetworkInfo activeNetworkInfo = mConnMgr.getActiveNetworkInfo();
2580 return activeNetworkInfo != null && activeNetworkInfo.isConnected();
2581 }
2582
2583 /**
2584 * Ensures the calling function is running in the thread associated with {@link #mHandler}.
2585 */
2586 private void ensureInHandlerThread() {
2587 if (mHandler != null && Looper.myLooper() == mHandler.getLooper()) {
2588 return;
2589 }
2590 throw new RuntimeException("This method must run on the Handler thread.");
2591 }
2592
2593 /**
2594 * @return A string representing the current state stored in {@link #mAGpsDataConnectionState}.
2595 */
2596 private String agpsDataConnStateAsString() {
gomo48f1a642017-11-10 20:35:46 -08002597 switch (mAGpsDataConnectionState) {
destradaae21252a2015-09-08 12:32:59 -07002598 case AGPS_DATA_CONNECTION_CLOSED:
2599 return "CLOSED";
2600 case AGPS_DATA_CONNECTION_OPEN:
2601 return "OPEN";
2602 case AGPS_DATA_CONNECTION_OPENING:
2603 return "OPENING";
2604 default:
2605 return "<Unknown>";
2606 }
2607 }
2608
2609 /**
2610 * @return A string representing the given GPS_AGPS_DATA status.
2611 */
2612 private String agpsDataConnStatusAsString(int agpsDataConnStatus) {
2613 switch (agpsDataConnStatus) {
2614 case GPS_AGPS_DATA_CONNECTED:
2615 return "CONNECTED";
2616 case GPS_AGPS_DATA_CONN_DONE:
2617 return "DONE";
2618 case GPS_AGPS_DATA_CONN_FAILED:
2619 return "FAILED";
2620 case GPS_RELEASE_AGPS_DATA_CONN:
2621 return "RELEASE";
2622 case GPS_REQUEST_AGPS_DATA_CONN:
2623 return "REQUEST";
2624 default:
2625 return "<Unknown>";
2626 }
2627 }
2628
Wyatt Rileycf879db2017-01-12 13:57:38 -08002629 /**
2630 * @return A string representing the given message ID.
2631 */
2632 private String messageIdAsString(int message) {
2633 switch (message) {
2634 case ENABLE:
2635 return "ENABLE";
2636 case SET_REQUEST:
2637 return "SET_REQUEST";
2638 case UPDATE_NETWORK_STATE:
2639 return "UPDATE_NETWORK_STATE";
2640 case REQUEST_SUPL_CONNECTION:
2641 return "REQUEST_SUPL_CONNECTION";
2642 case RELEASE_SUPL_CONNECTION:
2643 return "RELEASE_SUPL_CONNECTION";
2644 case INJECT_NTP_TIME:
2645 return "INJECT_NTP_TIME";
Yu-Han Yange7baef32018-02-09 13:58:17 -08002646 case REQUEST_LOCATION:
2647 return "REQUEST_LOCATION";
Wyatt Rileycf879db2017-01-12 13:57:38 -08002648 case DOWNLOAD_XTRA_DATA:
2649 return "DOWNLOAD_XTRA_DATA";
Wyatt Rileycf879db2017-01-12 13:57:38 -08002650 case DOWNLOAD_XTRA_DATA_FINISHED:
2651 return "DOWNLOAD_XTRA_DATA_FINISHED";
2652 case UPDATE_LOCATION:
2653 return "UPDATE_LOCATION";
2654 case SUBSCRIPTION_OR_SIM_CHANGED:
2655 return "SUBSCRIPTION_OR_SIM_CHANGED";
2656 case INITIALIZE_HANDLER:
2657 return "INITIALIZE_HANDLER";
Wyatt Riley26465d22018-02-12 13:44:24 -08002658 case REPORT_LOCATION:
2659 return "REPORT_LOCATION";
2660 case REPORT_SV_STATUS:
2661 return "REPORT_SV_STATUS";
Wyatt Rileycf879db2017-01-12 13:57:38 -08002662 default:
2663 return "<Unknown>";
2664 }
2665 }
2666
Siddharth Raybb608c82017-03-16 11:33:34 -07002667
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002668 @Override
2669 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2670 StringBuilder s = new StringBuilder();
Wyatt Riley77ca4f82017-06-30 18:13:44 -07002671 s.append(" mStarted=").append(mStarted).append('\n');
destradaa25e8caf2015-08-24 14:14:44 -07002672 s.append(" mFixInterval=").append(mFixInterval).append('\n');
gomo48f1a642017-11-10 20:35:46 -08002673 s.append(" mLowPowerMode=").append(mLowPowerMode).append('\n');
Wyatt Riley74479bd2018-01-17 08:48:27 -08002674 s.append(" mGnssMeasurementsProvider.isRegistered()=")
2675 .append(mGnssMeasurementsProvider.isRegistered()).append('\n');
2676 s.append(" mGnssNavigationMessageProvider.isRegistered()=")
2677 .append(mGnssNavigationMessageProvider.isRegistered()).append('\n');
destradaa25e8caf2015-08-24 14:14:44 -07002678 s.append(" mDisableGps (battery saver mode)=").append(mDisableGps).append('\n');
2679 s.append(" mEngineCapabilities=0x").append(Integer.toHexString(mEngineCapabilities));
2680 s.append(" ( ");
2681 if (hasCapability(GPS_CAPABILITY_SCHEDULING)) s.append("SCHEDULING ");
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002682 if (hasCapability(GPS_CAPABILITY_MSB)) s.append("MSB ");
2683 if (hasCapability(GPS_CAPABILITY_MSA)) s.append("MSA ");
2684 if (hasCapability(GPS_CAPABILITY_SINGLE_SHOT)) s.append("SINGLE_SHOT ");
2685 if (hasCapability(GPS_CAPABILITY_ON_DEMAND_TIME)) s.append("ON_DEMAND_TIME ");
destradaa25e8caf2015-08-24 14:14:44 -07002686 if (hasCapability(GPS_CAPABILITY_GEOFENCING)) s.append("GEOFENCING ");
2687 if (hasCapability(GPS_CAPABILITY_MEASUREMENTS)) s.append("MEASUREMENTS ");
2688 if (hasCapability(GPS_CAPABILITY_NAV_MESSAGES)) s.append("NAV_MESSAGES ");
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002689 s.append(")\n");
Siddharth Raybb608c82017-03-16 11:33:34 -07002690 s.append(mGnssMetrics.dumpGnssMetricsAsText());
2691 s.append(" native internal state: ").append(native_get_internal_state());
Wyatt Rileycf879db2017-01-12 13:57:38 -08002692 s.append("\n");
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002693 pw.append(s);
2694 }
2695
Mike Lockwoodb16e7802009-08-06 09:26:02 -04002696 // preallocated to avoid memory allocation in reportNmea()
2697 private byte[] mNmeaBuffer = new byte[120];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002698
gomo48f1a642017-11-10 20:35:46 -08002699 static {
2700 class_init_native();
2701 }
2702
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002703 private static native void class_init_native();
gomo48f1a642017-11-10 20:35:46 -08002704
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002705 private static native boolean native_is_supported();
gomo48f1a642017-11-10 20:35:46 -08002706
destradaaef752b62015-04-17 13:10:47 -07002707 private static native boolean native_is_agps_ril_supported();
gomo48f1a642017-11-10 20:35:46 -08002708
destradaaef752b62015-04-17 13:10:47 -07002709 private static native boolean native_is_gnss_configuration_supported();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002710
Yu-Han Yang6d317352018-03-15 11:53:01 -07002711 private static native void native_init_once();
2712
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002713 private native boolean native_init();
gomo48f1a642017-11-10 20:35:46 -08002714
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002715 private native void native_cleanup();
gomo48f1a642017-11-10 20:35:46 -08002716
Mike Lockwood04598b62010-04-14 17:17:24 -04002717 private native boolean native_set_position_mode(int mode, int recurrence, int min_interval,
gomo48f1a642017-11-10 20:35:46 -08002718 int preferred_accuracy, int preferred_time, boolean lowPowerMode);
2719
Mike Lockwood04598b62010-04-14 17:17:24 -04002720 private native boolean native_start();
gomo48f1a642017-11-10 20:35:46 -08002721
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002722 private native boolean native_stop();
gomo48f1a642017-11-10 20:35:46 -08002723
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002724 private native void native_delete_aiding_data(int flags);
gomo48f1a642017-11-10 20:35:46 -08002725
Mike Lockwoodf602d362010-06-20 14:28:16 -07002726 private native int native_read_nmea(byte[] buffer, int bufferSize);
gomo48f1a642017-11-10 20:35:46 -08002727
Yu-Han Yange7baef32018-02-09 13:58:17 -08002728 private native void native_inject_best_location(
2729 int gnssLocationFlags,
2730 double latitudeDegrees,
2731 double longitudeDegrees,
2732 double altitudeMeters,
2733 float speedMetersPerSec,
2734 float bearingDegrees,
2735 float horizontalAccuracyMeters,
2736 float verticalAccuracyMeters,
2737 float speedAccuracyMetersPerSecond,
2738 float bearingAccuracyDegrees,
2739 long timestamp);
2740
Mike Lockwoodd26ce0d2009-06-11 12:25:46 -04002741 private native void native_inject_location(double latitude, double longitude, float accuracy);
2742
Fred Fettinger3c8fbdf2010-01-04 15:38:13 -06002743 // XTRA Support
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002744 private native void native_inject_time(long time, long timeReference, int uncertainty);
gomo48f1a642017-11-10 20:35:46 -08002745
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002746 private native boolean native_supports_xtra();
gomo48f1a642017-11-10 20:35:46 -08002747
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002748 private native void native_inject_xtra_data(byte[] data, int length);
The Android Open Source Project10592532009-03-18 17:39:46 -07002749
Fred Fettinger3c8fbdf2010-01-04 15:38:13 -06002750 // DEBUG Support
2751 private native String native_get_internal_state();
2752
2753 // AGPS Support
destradaa96a14702014-06-05 11:36:30 -07002754 private native void native_agps_data_conn_open(String apn, int apnIpType);
gomo48f1a642017-11-10 20:35:46 -08002755
Mike Lockwoode3635c92009-05-11 08:38:02 -04002756 private native void native_agps_data_conn_closed();
gomo48f1a642017-11-10 20:35:46 -08002757
Mike Lockwoode3635c92009-05-11 08:38:02 -04002758 private native void native_agps_data_conn_failed();
gomo48f1a642017-11-10 20:35:46 -08002759
2760 private native void native_agps_ni_message(byte[] msg, int length);
2761
Mike Lockwooda9e54612009-06-19 14:54:42 -04002762 private native void native_set_agps_server(int type, String hostname, int port);
Danke Xie22d1f9f2009-08-18 18:28:45 -04002763
2764 // Network-initiated (NI) Support
2765 private native void native_send_ni_response(int notificationId, int userResponse);
Miguel Torroja1e84da82010-07-27 07:02:24 +02002766
2767 // AGPS ril suport
2768 private native void native_agps_set_ref_location_cellid(int type, int mcc, int mnc,
2769 int lac, int cid);
gomo48f1a642017-11-10 20:35:46 -08002770
Miguel Torroja1e84da82010-07-27 07:02:24 +02002771 private native void native_agps_set_id(int type, String setid);
Mike Lockwood50130bb2010-10-11 06:22:50 -04002772
2773 private native void native_update_network_state(boolean connected, int type,
Kevin Tanga5fe6b22011-06-05 14:25:16 -07002774 boolean roaming, boolean available, String extraInfo, String defaultAPN);
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07002775
Tsuwei Chen52617bb2014-08-25 11:49:11 -07002776 // GNSS Configuration
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002777 private static native boolean native_set_supl_version(int version);
gomo48f1a642017-11-10 20:35:46 -08002778
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002779 private static native boolean native_set_supl_mode(int mode);
gomo48f1a642017-11-10 20:35:46 -08002780
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002781 private static native boolean native_set_supl_es(int es);
gomo48f1a642017-11-10 20:35:46 -08002782
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002783 private static native boolean native_set_lpp_profile(int lppProfile);
gomo48f1a642017-11-10 20:35:46 -08002784
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002785 private static native boolean native_set_gnss_pos_protocol_select(int gnssPosProtocolSelect);
gomo48f1a642017-11-10 20:35:46 -08002786
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002787 private static native boolean native_set_gps_lock(int gpsLock);
gomo48f1a642017-11-10 20:35:46 -08002788
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002789 private static native boolean native_set_emergency_supl_pdn(int emergencySuplPdn);
2790
Yu-Han Yang66c7ea92018-03-11 17:17:15 -07002791 private static native boolean native_set_satellite_blacklist(int[] constellations, int[] svIds);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002792}
Yu-Han Yanga1862b52018-02-20 17:05:59 -08002793