blob: 809a48f2b4af88108c22256300000bc477075b91 [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 }
WyattRileya725dd62018-12-06 11:43:58 -0800726
727 String emergencyExtensionSecondsString
728 = properties.getProperty("ES_EXTENSION_SEC", "0");
729 try {
730 int emergencyExtensionSeconds =
731 Integer.parseInt(emergencyExtensionSecondsString);
732 mNIHandler.setEmergencyExtensionSeconds(emergencyExtensionSeconds);
733 } catch (NumberFormatException e) {
734 Log.e(TAG, "unable to parse ES_EXTENSION_SEC: "
735 + emergencyExtensionSecondsString);
736 }
Tsuwei Chen52617bb2014-08-25 11:49:11 -0700737 }
738
739 private void loadPropertiesFromResource(Context context,
gomo48f1a642017-11-10 20:35:46 -0800740 Properties properties) {
Tsuwei Chen52617bb2014-08-25 11:49:11 -0700741 String[] configValues = context.getResources().getStringArray(
742 com.android.internal.R.array.config_gpsParameters);
743 for (String item : configValues) {
Joe Onorato0c484102016-02-01 18:04:24 -0800744 if (DEBUG) Log.d(TAG, "GpsParamsResource: " + item);
Tsuwei Chen7c485bf2014-09-10 15:33:34 -0700745 // We need to support "KEY =", but not "=VALUE".
Zheng Zhangad48bd92017-10-16 10:27:28 -0700746 int index = item.indexOf("=");
747 if (index > 0 && index + 1 < item.length()) {
748 String key = item.substring(0, index);
749 String value = item.substring(index + 1);
750 properties.setProperty(key.trim().toUpperCase(), value);
Tsuwei Chen52617bb2014-08-25 11:49:11 -0700751 } else {
752 Log.w(TAG, "malformed contents: " + item);
753 }
754 }
755 }
756
757 private boolean loadPropertiesFromFile(String filename,
gomo48f1a642017-11-10 20:35:46 -0800758 Properties properties) {
Colin Cross7c030ed2014-01-28 09:33:53 -0800759 try {
760 File file = new File(filename);
761 FileInputStream stream = null;
762 try {
763 stream = new FileInputStream(file);
Tsuwei Chen52617bb2014-08-25 11:49:11 -0700764 properties.load(stream);
Colin Cross7c030ed2014-01-28 09:33:53 -0800765 } finally {
766 IoUtils.closeQuietly(stream);
767 }
768
Colin Cross7c030ed2014-01-28 09:33:53 -0800769 } catch (IOException e) {
Wyatt Riley3e1cd0b2017-04-19 17:57:14 -0700770 if (DEBUG) Log.d(TAG, "Could not open GPS configuration file " + filename);
Colin Cross7c030ed2014-01-28 09:33:53 -0800771 return false;
772 }
773 return true;
774 }
775
Lifu Tang30f95a72016-01-07 23:20:38 -0800776 public GnssLocationProvider(Context context, ILocationManager ilocationManager,
Victoria Lease5cd731a2012-12-19 15:04:21 -0800777 Looper looper) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800778 mContext = context;
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700779 mILocationManager = ilocationManager;
Mike Lockwood63598a02010-02-24 11:52:59 -0500780
Mike Lockwood0528b9b2009-05-07 10:12:54 -0400781 // Create a wake lock
David Christied4edf4c2014-08-12 15:22:27 -0700782 mPowerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
783 mWakeLock = mPowerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, WAKELOCK_KEY);
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700784 mWakeLock.setReferenceCounted(true);
Mike Lockwood0528b9b2009-05-07 10:12:54 -0400785
Wei Wangb71c0492017-05-01 20:24:19 -0700786 // Create a separate wake lock for xtra downloader as it may be released due to timeout.
787 mDownloadXtraWakeLock = mPowerManager.newWakeLock(
788 PowerManager.PARTIAL_WAKE_LOCK, DOWNLOAD_EXTRA_WAKELOCK_KEY);
789 mDownloadXtraWakeLock.setReferenceCounted(true);
790
gomo48f1a642017-11-10 20:35:46 -0800791 mAlarmManager = (AlarmManager) mContext.getSystemService(Context.ALARM_SERVICE);
Mike Lockwood29c84342009-05-06 14:01:15 -0400792 mWakeupIntent = PendingIntent.getBroadcast(mContext, 0, new Intent(ALARM_WAKEUP), 0);
Mike Lockwood0632ca72009-05-14 15:51:03 -0400793 mTimeoutIntent = PendingIntent.getBroadcast(mContext, 0, new Intent(ALARM_TIMEOUT), 0);
Mike Lockwood29c84342009-05-06 14:01:15 -0400794
gomo48f1a642017-11-10 20:35:46 -0800795 mConnMgr = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
Mike Lockwood58bda982009-04-14 16:25:07 -0400796
Dianne Hackborna06de0f2012-12-11 16:34:47 -0800797 // App ops service to keep track of who is accessing the GPS
Svet Ganovf7b47252018-02-26 11:11:27 -0800798 mAppOps = mContext.getSystemService(AppOpsManager.class);
Dianne Hackborna06de0f2012-12-11 16:34:47 -0800799
Mike Lockwood2f82c4e2009-04-17 08:24:10 -0400800 // Battery statistics service to be notified when GPS turns on or off
Dianne Hackborn91268cf2013-06-13 19:06:50 -0700801 mBatteryStats = IBatteryStats.Stub.asInterface(ServiceManager.getService(
802 BatteryStats.SERVICE_NAME));
Mike Lockwood2f82c4e2009-04-17 08:24:10 -0400803
destradaafb23c672015-04-16 14:01:27 -0700804 // Construct internal handler
805 mHandler = new ProviderHandler(looper);
806
807 // Load GPS configuration and register listeners in the background:
808 // some operations, such as opening files and registering broadcast receivers, can take a
809 // relative long time, so the ctor() is kept to create objects needed by this instance,
810 // while IO initialization and registration is delegated to our internal handler
811 // this approach is just fine because events are posted to our handler anyway
Tsuwei Chen52617bb2014-08-25 11:49:11 -0700812 mProperties = new Properties();
destradaafb23c672015-04-16 14:01:27 -0700813 sendMessage(INITIALIZE_HANDLER, 0, null);
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400814
Tsuwei Chen3324e952014-09-07 01:30:42 -0700815 // Create a GPS net-initiated handler.
816 mNIHandler = new GpsNetInitiatedHandler(context,
gomo48f1a642017-11-10 20:35:46 -0800817 mNetInitiatedListener,
818 mSuplEsEnabled);
Tsuwei Chen3324e952014-09-07 01:30:42 -0700819
Lifu Tang30f95a72016-01-07 23:20:38 -0800820 mListenerHelper = new GnssStatusListenerHelper(mHandler) {
destradaa6568d702014-10-27 12:47:41 -0700821 @Override
822 protected boolean isAvailableInPlatform() {
destradaa13a60b02015-01-15 18:36:01 -0800823 return isSupported();
destradaa6568d702014-10-27 12:47:41 -0700824 }
825
826 @Override
827 protected boolean isGpsEnabled() {
828 return isEnabled();
829 }
830 };
831
Yu-Han Yang8de21502018-04-23 01:40:25 -0700832 mGnssMeasurementsProvider = new GnssMeasurementsProvider(mContext, mHandler) {
destradaa6568d702014-10-27 12:47:41 -0700833 @Override
834 protected boolean isGpsEnabled() {
835 return isEnabled();
836 }
837 };
838
Lifu Tang818aa2c2016-02-01 01:52:00 -0800839 mGnssNavigationMessageProvider = new GnssNavigationMessageProvider(mHandler) {
destradaa6568d702014-10-27 12:47:41 -0700840 @Override
destradaa6568d702014-10-27 12:47:41 -0700841 protected boolean isGpsEnabled() {
842 return isEnabled();
843 }
844 };
Siddharth Ray78ccaf52017-12-23 16:16:21 -0800845 mGnssMetrics = new GnssMetrics(mBatteryStats);
Yu-Han Yanga1862b52018-02-20 17:05:59 -0800846
Yu-Han Yang66c7ea92018-03-11 17:17:15 -0700847 mNtpTimeHelper = new NtpTimeHelper(mContext, looper, this);
848 mGnssSatelliteBlacklistHelper = new GnssSatelliteBlacklistHelper(mContext,
849 looper, this);
850 mHandler.post(mGnssSatelliteBlacklistHelper::updateSatelliteBlacklist);
Yu-Han Yang3557cc72018-03-21 12:48:36 -0700851 mGnssBatchingProvider = new GnssBatchingProvider();
Yu-Han Yang890ca8b2018-04-16 22:11:31 -0700852 mGnssGeofenceProvider = new GnssGeofenceProvider(looper);
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400853 }
854
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800855 /**
Mike Lockwoodd03ff942010-02-09 08:46:14 -0500856 * Returns the name of this provider.
857 */
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700858 @Override
Mike Lockwoodd03ff942010-02-09 08:46:14 -0500859 public String getName() {
860 return LocationManager.GPS_PROVIDER;
861 }
862
Nick Pelly6fa9ad42012-07-16 12:18:23 -0700863 @Override
864 public ProviderProperties getProperties() {
865 return PROPERTIES;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800866 }
867
Yu-Han Yanga1862b52018-02-20 17:05:59 -0800868
869 /**
870 * Implements {@link InjectNtpTimeCallback#injectTime}
871 */
872 @Override
873 public void injectTime(long time, long timeReference, int uncertainty) {
874 native_inject_time(time, timeReference, uncertainty);
875 }
876
destradaae21252a2015-09-08 12:32:59 -0700877 private void handleUpdateNetworkState(Network network) {
878 // retrieve NetworkInfo for this UID
879 NetworkInfo info = mConnMgr.getNetworkInfo(network);
Kevin Tang71ad5fe2017-05-10 19:36:20 -0700880
881 boolean networkAvailable = false;
882 boolean isConnected = false;
883 int type = ConnectivityManager.TYPE_NONE;
884 boolean isRoaming = false;
885 String apnName = null;
886
887 if (info != null) {
888 networkAvailable = info.isAvailable() && TelephonyManager.getDefault().getDataEnabled();
889 isConnected = info.isConnected();
890 type = info.getType();
891 isRoaming = info.isRoaming();
892 apnName = info.getExtraInfo();
destradaae21252a2015-09-08 12:32:59 -0700893 }
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400894
Joe Onoratof5d95cb2010-01-07 21:48:32 -0500895 if (DEBUG) {
destradaae21252a2015-09-08 12:32:59 -0700896 String message = String.format(
897 "UpdateNetworkState, state=%s, connected=%s, info=%s, capabilities=%S",
898 agpsDataConnStateAsString(),
899 isConnected,
900 info,
901 mConnMgr.getNetworkCapabilities(network));
902 Log.d(TAG, message);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -0800903 }
Mike Lockwood03d24672009-10-08 15:45:03 -0400904
destradaae21252a2015-09-08 12:32:59 -0700905 if (native_is_agps_ril_supported()) {
destradaae21252a2015-09-08 12:32:59 -0700906 String defaultApn = getSelectedApn();
907 if (defaultApn == null) {
908 defaultApn = "dummy-apn";
destradaaef752b62015-04-17 13:10:47 -0700909 }
destradaae21252a2015-09-08 12:32:59 -0700910
911 native_update_network_state(
912 isConnected,
Kevin Tang71ad5fe2017-05-10 19:36:20 -0700913 type,
914 isRoaming,
destradaae21252a2015-09-08 12:32:59 -0700915 networkAvailable,
Kevin Tang71ad5fe2017-05-10 19:36:20 -0700916 apnName,
destradaae21252a2015-09-08 12:32:59 -0700917 defaultApn);
918 } else if (DEBUG) {
919 Log.d(TAG, "Skipped network state update because GPS HAL AGPS-RIL is not supported");
Mike Lockwood50130bb2010-10-11 06:22:50 -0400920 }
921
destradaae21252a2015-09-08 12:32:59 -0700922 if (mAGpsDataConnectionState == AGPS_DATA_CONNECTION_OPENING) {
923 if (isConnected) {
Stephen Li83b69712011-01-25 18:47:28 -0800924 if (apnName == null) {
destradaae21252a2015-09-08 12:32:59 -0700925 // assign a dummy value in the case of C2K as otherwise we will have a runtime
926 // exception in the following call to native_agps_data_conn_open
Stephen Li83b69712011-01-25 18:47:28 -0800927 apnName = "dummy-apn";
928 }
destradaae21252a2015-09-08 12:32:59 -0700929 int apnIpType = getApnIpType(apnName);
destradaa96a14702014-06-05 11:36:30 -0700930 setRouting();
931 if (DEBUG) {
932 String message = String.format(
933 "native_agps_data_conn_open: mAgpsApn=%s, mApnIpType=%s",
destradaae21252a2015-09-08 12:32:59 -0700934 apnName,
935 apnIpType);
destradaa96a14702014-06-05 11:36:30 -0700936 Log.d(TAG, message);
Stephen Li8efd74d2011-03-01 20:56:00 -0800937 }
destradaae21252a2015-09-08 12:32:59 -0700938 native_agps_data_conn_open(apnName, apnIpType);
Mike Lockwood03d24672009-10-08 15:45:03 -0400939 mAGpsDataConnectionState = AGPS_DATA_CONNECTION_OPEN;
940 } else {
destradaae21252a2015-09-08 12:32:59 -0700941 handleReleaseSuplConnection(GPS_AGPS_DATA_CONN_FAILED);
Mike Lockwood03d24672009-10-08 15:45:03 -0400942 }
943 }
destradaae21252a2015-09-08 12:32:59 -0700944 }
Mike Lockwood03d24672009-10-08 15:45:03 -0400945
destradaae21252a2015-09-08 12:32:59 -0700946 private void handleRequestSuplConnection(InetAddress address) {
947 if (DEBUG) {
948 String message = String.format(
949 "requestSuplConnection, state=%s, address=%s",
950 agpsDataConnStateAsString(),
951 address);
952 Log.d(TAG, message);
953 }
954
955 if (mAGpsDataConnectionState != AGPS_DATA_CONNECTION_CLOSED) {
956 return;
957 }
958 mAGpsDataConnectionIpAddr = address;
959 mAGpsDataConnectionState = AGPS_DATA_CONNECTION_OPENING;
960
961 NetworkRequest.Builder requestBuilder = new NetworkRequest.Builder();
962 requestBuilder.addTransportType(NetworkCapabilities.TRANSPORT_CELLULAR);
963 requestBuilder.addCapability(NetworkCapabilities.NET_CAPABILITY_SUPL);
964 NetworkRequest request = requestBuilder.build();
965 mConnMgr.requestNetwork(
966 request,
Etan Cohene9aea9d2017-02-09 18:16:58 -0800967 mSuplConnectivityCallback);
destradaae21252a2015-09-08 12:32:59 -0700968 }
969
970 private void handleReleaseSuplConnection(int agpsDataConnStatus) {
971 if (DEBUG) {
972 String message = String.format(
973 "releaseSuplConnection, state=%s, status=%s",
974 agpsDataConnStateAsString(),
975 agpsDataConnStatusAsString(agpsDataConnStatus));
976 Log.d(TAG, message);
977 }
978
979 if (mAGpsDataConnectionState == AGPS_DATA_CONNECTION_CLOSED) {
980 return;
981 }
982 mAGpsDataConnectionState = AGPS_DATA_CONNECTION_CLOSED;
983
984 mConnMgr.unregisterNetworkCallback(mSuplConnectivityCallback);
985 switch (agpsDataConnStatus) {
986 case GPS_AGPS_DATA_CONN_FAILED:
987 native_agps_data_conn_failed();
988 break;
989 case GPS_RELEASE_AGPS_DATA_CONN:
990 native_agps_data_conn_closed();
991 break;
992 default:
993 Log.e(TAG, "Invalid status to release SUPL connection: " + agpsDataConnStatus);
Mike Lockwood62a8fc12010-03-22 14:23:26 -0400994 }
995 }
Yu-Han Yang8de21502018-04-23 01:40:25 -0700996
Yu-Han Yange7baef32018-02-09 13:58:17 -0800997 private void handleRequestLocation(boolean independentFromGnss) {
998 if (isRequestLocationRateLimited()) {
999 if (DEBUG) {
1000 Log.d(TAG, "RequestLocation is denied due to too frequent requests.");
1001 }
1002 return;
1003 }
Yu-Han Yang74041ff2018-04-06 15:57:31 -07001004 ContentResolver resolver = mContext.getContentResolver();
1005 long durationMillis = Settings.Global.getLong(
1006 resolver,
1007 Settings.Global.GNSS_HAL_LOCATION_REQUEST_DURATION_MILLIS,
1008 LOCATION_UPDATE_DURATION_MILLIS);
1009 if (durationMillis == 0) {
1010 Log.i(TAG, "GNSS HAL location request is disabled by Settings.");
1011 return;
1012 }
Yu-Han Yange7baef32018-02-09 13:58:17 -08001013
1014 LocationManager locationManager = (LocationManager) mContext.getSystemService(
1015 Context.LOCATION_SERVICE);
Yu-Han Yang07561382018-02-21 13:08:37 -08001016 String provider;
1017 LocationChangeListener locationListener;
Yu-Han Yange7baef32018-02-09 13:58:17 -08001018
1019 if (independentFromGnss) {
1020 // For fast GNSS TTFF
Yu-Han Yang07561382018-02-21 13:08:37 -08001021 provider = LocationManager.NETWORK_PROVIDER;
1022 locationListener = mNetworkLocationListener;
Yu-Han Yange7baef32018-02-09 13:58:17 -08001023 } else {
1024 // For Device-Based Hybrid (E911)
Yu-Han Yang07561382018-02-21 13:08:37 -08001025 provider = LocationManager.FUSED_PROVIDER;
1026 locationListener = mFusedLocationListener;
Yu-Han Yange7baef32018-02-09 13:58:17 -08001027 }
Yu-Han Yang07561382018-02-21 13:08:37 -08001028
1029 Log.i(TAG,
Yu-Han Yang74041ff2018-04-06 15:57:31 -07001030 String.format(
1031 "GNSS HAL Requesting location updates from %s provider for %d millis.",
1032 provider, durationMillis));
Yu-Han Yange684dda2018-05-24 10:29:39 -07001033 try {
1034 locationManager.requestLocationUpdates(provider,
1035 LOCATION_UPDATE_MIN_TIME_INTERVAL_MILLIS, /*minDistance=*/ 0,
1036 locationListener, mHandler.getLooper());
1037 locationListener.numLocationUpdateRequest++;
1038 mHandler.postDelayed(() -> {
1039 if (--locationListener.numLocationUpdateRequest == 0) {
1040 Log.i(TAG,
1041 String.format("Removing location updates from %s provider.", provider));
1042 locationManager.removeUpdates(locationListener);
1043 }
1044 }, durationMillis);
1045 } catch (IllegalArgumentException e) {
1046 Log.w(TAG, "Unable to request location.", e);
1047 }
Yu-Han Yange7baef32018-02-09 13:58:17 -08001048 }
1049
1050 private void injectBestLocation(Location location) {
1051 int gnssLocationFlags = LOCATION_HAS_LAT_LONG |
1052 (location.hasAltitude() ? LOCATION_HAS_ALTITUDE : 0) |
1053 (location.hasSpeed() ? LOCATION_HAS_SPEED : 0) |
1054 (location.hasBearing() ? LOCATION_HAS_BEARING : 0) |
1055 (location.hasAccuracy() ? LOCATION_HAS_HORIZONTAL_ACCURACY : 0) |
1056 (location.hasVerticalAccuracy() ? LOCATION_HAS_VERTICAL_ACCURACY : 0) |
1057 (location.hasSpeedAccuracy() ? LOCATION_HAS_SPEED_ACCURACY : 0) |
1058 (location.hasBearingAccuracy() ? LOCATION_HAS_BEARING_ACCURACY : 0);
1059
1060 double latitudeDegrees = location.getLatitude();
1061 double longitudeDegrees = location.getLongitude();
1062 double altitudeMeters = location.getAltitude();
1063 float speedMetersPerSec = location.getSpeed();
1064 float bearingDegrees = location.getBearing();
1065 float horizontalAccuracyMeters = location.getAccuracy();
1066 float verticalAccuracyMeters = location.getVerticalAccuracyMeters();
1067 float speedAccuracyMetersPerSecond = location.getSpeedAccuracyMetersPerSecond();
1068 float bearingAccuracyDegrees = location.getBearingAccuracyDegrees();
1069 long timestamp = location.getTime();
1070 native_inject_best_location(gnssLocationFlags, latitudeDegrees, longitudeDegrees,
1071 altitudeMeters, speedMetersPerSec, bearingDegrees, horizontalAccuracyMeters,
1072 verticalAccuracyMeters, speedAccuracyMetersPerSecond, bearingAccuracyDegrees,
1073 timestamp);
1074 }
1075
Yu-Han Yange7baef32018-02-09 13:58:17 -08001076 /** Returns true if the location request is too frequent. */
1077 private boolean isRequestLocationRateLimited() {
1078 // TODO(b/73198123): implement exponential backoff.
1079 return false;
1080 }
1081
Mike Lockwood62a8fc12010-03-22 14:23:26 -04001082 private void handleDownloadXtraData() {
Wyatt Riley0d6e54e22016-10-05 12:03:03 -07001083 if (!mSupportsXtra) {
1084 // native code reports xtra not supported, don't try
1085 Log.d(TAG, "handleDownloadXtraData() called when Xtra not supported");
1086 return;
1087 }
Kevin Tang40e1baf2012-01-10 14:32:44 -08001088 if (mDownloadXtraDataPending == STATE_DOWNLOADING) {
1089 // already downloading data
Mike Lockwood62a8fc12010-03-22 14:23:26 -04001090 return;
1091 }
destradaae21252a2015-09-08 12:32:59 -07001092 if (!isDataNetworkConnected()) {
Kevin Tang40e1baf2012-01-10 14:32:44 -08001093 // try again when network is up
1094 mDownloadXtraDataPending = STATE_PENDING_NETWORK;
1095 return;
Mike Lockwood62a8fc12010-03-22 14:23:26 -04001096 }
Kevin Tang40e1baf2012-01-10 14:32:44 -08001097 mDownloadXtraDataPending = STATE_DOWNLOADING;
1098
Jeff Brown028872f2012-08-25 13:07:01 -07001099 // hold wake lock while task runs
Wei Wangb71c0492017-05-01 20:24:19 -07001100 mDownloadXtraWakeLock.acquire(DOWNLOAD_XTRA_DATA_TIMEOUT_MS);
Lifu Tangcbd2a142016-06-22 10:57:55 -07001101 Log.i(TAG, "WakeLock acquired by handleDownloadXtraData()");
Kevin Tang40e1baf2012-01-10 14:32:44 -08001102 AsyncTask.THREAD_POOL_EXECUTOR.execute(new Runnable() {
1103 @Override
1104 public void run() {
Andreas Gampedfdc6ac2014-10-28 20:42:53 -07001105 GpsXtraDownloader xtraDownloader = new GpsXtraDownloader(mProperties);
Kevin Tang40e1baf2012-01-10 14:32:44 -08001106 byte[] data = xtraDownloader.downloadXtraData();
1107 if (data != null) {
destradaae21252a2015-09-08 12:32:59 -07001108 if (DEBUG) Log.d(TAG, "calling native_inject_xtra_data");
Kevin Tang40e1baf2012-01-10 14:32:44 -08001109 native_inject_xtra_data(data, data.length);
Wei Liu6f6326b2015-06-24 23:47:50 -07001110 mXtraBackOff.reset();
Kevin Tang40e1baf2012-01-10 14:32:44 -08001111 }
1112
Jeff Brown028872f2012-08-25 13:07:01 -07001113 sendMessage(DOWNLOAD_XTRA_DATA_FINISHED, 0, null);
Kevin Tang40e1baf2012-01-10 14:32:44 -08001114
1115 if (data == null) {
1116 // try again later
1117 // since this is delayed and not urgent we do not hold a wake lock here
Wei Liu6f6326b2015-06-24 23:47:50 -07001118 mHandler.sendEmptyMessageDelayed(DOWNLOAD_XTRA_DATA,
1119 mXtraBackOff.nextBackoffMillis());
Kevin Tang40e1baf2012-01-10 14:32:44 -08001120 }
Kevin Tang40e1baf2012-01-10 14:32:44 -08001121
Wei Wangb71c0492017-05-01 20:24:19 -07001122 // Release wake lock held by task, synchronize on mLock in case multiple
1123 // download tasks overrun.
1124 synchronized (mLock) {
1125 if (mDownloadXtraWakeLock.isHeld()) {
Zheng Zhang3cceb252017-08-07 13:51:23 -07001126 // This wakelock may have time-out, if a timeout was specified.
1127 // Catch (and ignore) any timeout exceptions.
1128 try {
1129 mDownloadXtraWakeLock.release();
1130 if (DEBUG) Log.d(TAG, "WakeLock released by handleDownloadXtraData()");
1131 } catch (Exception e) {
1132 Log.i(TAG, "Wakelock timeout & release race exception in "
1133 + "handleDownloadXtraData()", e);
1134 }
Wei Wangb71c0492017-05-01 20:24:19 -07001135 } else {
1136 Log.e(TAG, "WakeLock expired before release in "
1137 + "handleDownloadXtraData()");
1138 }
Wei Wangc5706f62017-04-18 11:26:26 -07001139 }
Jeff Brown028872f2012-08-25 13:07:01 -07001140 }
Kevin Tang40e1baf2012-01-10 14:32:44 -08001141 });
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001142 }
1143
Mike Lockwood62a8fc12010-03-22 14:23:26 -04001144 private void handleUpdateLocation(Location location) {
Mike Lockwoodd26ce0d2009-06-11 12:25:46 -04001145 if (location.hasAccuracy()) {
1146 native_inject_location(location.getLatitude(), location.getLongitude(),
1147 location.getAccuracy());
1148 }
Mike Lockwoodfd6e5f02009-05-21 11:28:20 -04001149 }
1150
1151 /**
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001152 * Enables this provider. When enabled, calls to getStatus()
Mike Lockwood4e50b782009-04-03 08:24:43 -07001153 * must be handled. Hardware may be started up
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001154 * when the provider is enabled.
1155 */
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001156 @Override
Mike Lockwood62a8fc12010-03-22 14:23:26 -04001157 public void enable() {
Laurent Tu7b5aeca2013-01-24 15:10:24 -08001158 synchronized (mLock) {
1159 if (mEnabled) return;
1160 mEnabled = true;
1161 }
1162
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001163 sendMessage(ENABLE, 1, null);
Mike Lockwood62a8fc12010-03-22 14:23:26 -04001164 }
1165
Tsuwei Chen52617bb2014-08-25 11:49:11 -07001166 private void setSuplHostPort(String hostString, String portString) {
1167 if (hostString != null) {
1168 mSuplServerHost = hostString;
1169 }
1170 if (portString != null) {
1171 try {
1172 mSuplServerPort = Integer.parseInt(portString);
1173 } catch (NumberFormatException e) {
1174 Log.e(TAG, "unable to parse SUPL_PORT: " + portString);
1175 }
1176 }
Tsuwei Chen678c13c2014-09-22 17:48:41 -07001177 if (mSuplServerHost != null
1178 && mSuplServerPort > TCP_MIN_PORT
1179 && mSuplServerPort <= TCP_MAX_PORT) {
1180 native_set_agps_server(AGPS_TYPE_SUPL, mSuplServerHost, mSuplServerPort);
1181 }
Tsuwei Chen52617bb2014-08-25 11:49:11 -07001182 }
1183
Tsuwei Chen462bcd82014-09-17 12:28:49 -07001184 /**
1185 * Checks what SUPL mode to use, according to the AGPS mode as well as the
1186 * allowed mode from properties.
1187 *
gomo48f1a642017-11-10 20:35:46 -08001188 * @param properties GPS properties
Tsuwei Chen462bcd82014-09-17 12:28:49 -07001189 * @param agpsEnabled whether AGPS is enabled by settings value
gomo48f1a642017-11-10 20:35:46 -08001190 * @param singleShot whether "singleshot" is needed
Tsuwei Chen462bcd82014-09-17 12:28:49 -07001191 * @return SUPL mode (MSA vs MSB vs STANDALONE)
1192 */
1193 private int getSuplMode(Properties properties, boolean agpsEnabled, boolean singleShot) {
1194 if (agpsEnabled) {
1195 String modeString = properties.getProperty("SUPL_MODE");
1196 int suplMode = 0;
1197 if (!TextUtils.isEmpty(modeString)) {
1198 try {
1199 suplMode = Integer.parseInt(modeString);
1200 } catch (NumberFormatException e) {
1201 Log.e(TAG, "unable to parse SUPL_MODE: " + modeString);
1202 return GPS_POSITION_MODE_STANDALONE;
1203 }
1204 }
destradaabfb3bdb2015-04-29 14:42:35 -07001205 // MS-Based is the preferred mode for Assisted-GPS position computation, so we favor
1206 // such mode when it is available
1207 if (hasCapability(GPS_CAPABILITY_MSB) && (suplMode & AGPS_SUPL_MODE_MSB) != 0) {
1208 return GPS_POSITION_MODE_MS_BASED;
1209 }
1210 // for now, just as the legacy code did, we fallback to MS-Assisted if it is available,
1211 // do fallback only for single-shot requests, because it is too expensive to do for
1212 // periodic requests as well
Tsuwei Chen462bcd82014-09-17 12:28:49 -07001213 if (singleShot
1214 && hasCapability(GPS_CAPABILITY_MSA)
1215 && (suplMode & AGPS_SUPL_MODE_MSA) != 0) {
1216 return GPS_POSITION_MODE_MS_ASSISTED;
Tsuwei Chen462bcd82014-09-17 12:28:49 -07001217 }
1218 }
1219 return GPS_POSITION_MODE_STANDALONE;
1220 }
1221
Mike Lockwood62a8fc12010-03-22 14:23:26 -04001222 private void handleEnable() {
1223 if (DEBUG) Log.d(TAG, "handleEnable");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001224
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001225 boolean enabled = native_init();
1226
1227 if (enabled) {
Mike Lockwood1a1cd3a2010-08-17 07:42:54 -04001228 mSupportsXtra = native_supports_xtra();
Tsuwei Chen678c13c2014-09-22 17:48:41 -07001229
1230 // TODO: remove the following native calls if we can make sure they are redundant.
Mike Lockwood734d6032009-07-28 18:30:25 -07001231 if (mSuplServerHost != null) {
1232 native_set_agps_server(AGPS_TYPE_SUPL, mSuplServerHost, mSuplServerPort);
1233 }
1234 if (mC2KServerHost != null) {
1235 native_set_agps_server(AGPS_TYPE_C2K, mC2KServerHost, mC2KServerPort);
1236 }
destradaa13a60b02015-01-15 18:36:01 -08001237
Lifu Tang818aa2c2016-02-01 01:52:00 -08001238 mGnssMeasurementsProvider.onGpsEnabledChanged();
1239 mGnssNavigationMessageProvider.onGpsEnabledChanged();
Yu-Han Yang3557cc72018-03-21 12:48:36 -07001240 mGnssBatchingProvider.enable();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001241 } else {
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001242 synchronized (mLock) {
1243 mEnabled = false;
1244 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001245 Log.w(TAG, "Failed to enable location provider");
1246 }
1247 }
1248
1249 /**
1250 * Disables this provider. When disabled, calls to getStatus()
Mike Lockwood4e50b782009-04-03 08:24:43 -07001251 * need not be handled. Hardware may be shut
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001252 * down while the provider is disabled.
1253 */
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001254 @Override
Mike Lockwood62a8fc12010-03-22 14:23:26 -04001255 public void disable() {
Laurent Tu7b5aeca2013-01-24 15:10:24 -08001256 synchronized (mLock) {
1257 if (!mEnabled) return;
1258 mEnabled = false;
1259 }
1260
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001261 sendMessage(ENABLE, 0, null);
Mike Lockwood62a8fc12010-03-22 14:23:26 -04001262 }
1263
1264 private void handleDisable() {
Mike Lockwood89096312010-03-24 10:14:55 -04001265 if (DEBUG) Log.d(TAG, "handleDisable");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001266
David Christie3bc26142013-12-19 14:53:44 -08001267 updateClientUids(new WorkSource());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001268 stopNavigating();
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001269 mAlarmManager.cancel(mWakeupIntent);
1270 mAlarmManager.cancel(mTimeoutIntent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001271
Yu-Han Yang3557cc72018-03-21 12:48:36 -07001272 mGnssBatchingProvider.disable();
Mike Lockwoodcf1d8cb2010-01-20 10:14:54 -05001273 // do this before releasing wakelock
1274 native_cleanup();
destradaa13a60b02015-01-15 18:36:01 -08001275
Lifu Tang818aa2c2016-02-01 01:52:00 -08001276 mGnssMeasurementsProvider.onGpsEnabledChanged();
1277 mGnssNavigationMessageProvider.onGpsEnabledChanged();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001278 }
1279
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001280 @Override
Mike Lockwoodd03ff942010-02-09 08:46:14 -05001281 public boolean isEnabled() {
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001282 synchronized (mLock) {
1283 return mEnabled;
1284 }
Mike Lockwoodd03ff942010-02-09 08:46:14 -05001285 }
1286
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001287 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001288 public int getStatus(Bundle extras) {
Wyatt Rileyc7067412018-02-07 15:50:35 -08001289 mLocationExtras.setBundle(extras);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001290 return mStatus;
1291 }
1292
Wyatt Rileyc7067412018-02-07 15:50:35 -08001293 private void updateStatus(int status) {
1294 if (status != mStatus) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001295 mStatus = status;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001296 mStatusUpdateTime = SystemClock.elapsedRealtime();
1297 }
1298 }
1299
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001300 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001301 public long getStatusUpdateTime() {
1302 return mStatusUpdateTime;
1303 }
1304
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001305 @Override
1306 public void setRequest(ProviderRequest request, WorkSource source) {
1307 sendMessage(SET_REQUEST, 0, new GpsRequest(request, source));
Mike Lockwood62a8fc12010-03-22 14:23:26 -04001308 }
1309
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001310 private void handleSetRequest(ProviderRequest request, WorkSource source) {
David Christied4edf4c2014-08-12 15:22:27 -07001311 mProviderRequest = request;
1312 mWorkSource = source;
1313 updateRequirements();
1314 }
1315
1316 // Called when the requirements for GPS may have changed
1317 private void updateRequirements() {
1318 if (mProviderRequest == null || mWorkSource == null) {
1319 return;
1320 }
1321
Stan Chesnutt1d72d8c2013-04-15 19:18:02 -07001322 boolean singleShot = false;
1323
1324 // see if the request is for a single update
David Christied4edf4c2014-08-12 15:22:27 -07001325 if (mProviderRequest.locationRequests != null
1326 && mProviderRequest.locationRequests.size() > 0) {
Stan Chesnutt1d72d8c2013-04-15 19:18:02 -07001327 // if any request has zero or more than one updates
1328 // requested, then this is not single-shot mode
1329 singleShot = true;
1330
David Christied4edf4c2014-08-12 15:22:27 -07001331 for (LocationRequest lr : mProviderRequest.locationRequests) {
Stan Chesnutt1d72d8c2013-04-15 19:18:02 -07001332 if (lr.getNumUpdates() != 1) {
1333 singleShot = false;
1334 }
1335 }
1336 }
1337
David Christied4edf4c2014-08-12 15:22:27 -07001338 if (DEBUG) Log.d(TAG, "setRequest " + mProviderRequest);
Dante Russo260d6672016-06-20 11:11:59 -07001339 if (mProviderRequest.reportLocation && !mDisableGps && isEnabled()) {
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001340 // update client uids
David Christied4edf4c2014-08-12 15:22:27 -07001341 updateClientUids(mWorkSource);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001342
David Christied4edf4c2014-08-12 15:22:27 -07001343 mFixInterval = (int) mProviderRequest.interval;
gomo48f1a642017-11-10 20:35:46 -08001344 mLowPowerMode = (boolean) mProviderRequest.lowPowerMode;
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001345 // check for overflow
David Christied4edf4c2014-08-12 15:22:27 -07001346 if (mFixInterval != mProviderRequest.interval) {
1347 Log.w(TAG, "interval overflow: " + mProviderRequest.interval);
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001348 mFixInterval = Integer.MAX_VALUE;
1349 }
Mike Lockwood03ca2162010-04-01 08:10:09 -07001350
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001351 // apply request to GPS engine
Mike Lockwood04598b62010-04-14 17:17:24 -04001352 if (mStarted && hasCapability(GPS_CAPABILITY_SCHEDULING)) {
gomo48f1a642017-11-10 20:35:46 -08001353 // change period and/or lowPowerMode
Mike Lockwood04598b62010-04-14 17:17:24 -04001354 if (!native_set_position_mode(mPositionMode, GPS_POSITION_RECURRENCE_PERIODIC,
gomo48f1a642017-11-10 20:35:46 -08001355 mFixInterval, 0, 0, mLowPowerMode)) {
1356 Log.e(TAG, "set_position_mode failed in updateRequirements");
Mike Lockwood04598b62010-04-14 17:17:24 -04001357 }
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001358 } else if (!mStarted) {
1359 // start GPS
Stan Chesnutt1d72d8c2013-04-15 19:18:02 -07001360 startNavigating(singleShot);
gomo300b2402017-12-13 19:04:12 -08001361 } else {
1362 // GNSS Engine is already ON, but no GPS_CAPABILITY_SCHEDULING
1363 mAlarmManager.cancel(mTimeoutIntent);
1364 if (mFixInterval >= NO_FIX_TIMEOUT) {
1365 // set timer to give up if we do not receive a fix within NO_FIX_TIMEOUT
1366 // and our fix interval is not short
1367 mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
1368 SystemClock.elapsedRealtime() + NO_FIX_TIMEOUT, mTimeoutIntent); }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001369 }
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001370 } else {
Dianne Hackborn002a54e2013-01-10 17:34:55 -08001371 updateClientUids(new WorkSource());
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001372
1373 stopNavigating();
1374 mAlarmManager.cancel(mWakeupIntent);
1375 mAlarmManager.cancel(mTimeoutIntent);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001376 }
1377 }
1378
Dianne Hackborn002a54e2013-01-10 17:34:55 -08001379 private void updateClientUids(WorkSource source) {
Narayan Kamath32684dd2018-01-08 17:32:51 +00001380 if (source.equals(mClientSource)) {
Victoria Leaseea78b852013-01-15 10:39:28 -08001381 return;
1382 }
Dianne Hackborn002a54e2013-01-10 17:34:55 -08001383
Narayan Kamath32684dd2018-01-08 17:32:51 +00001384 // (1) Inform BatteryStats that the list of IDs we're tracking changed.
1385 try {
1386 mBatteryStats.noteGpsChanged(mClientSource, source);
1387 } catch (RemoteException e) {
1388 Log.w(TAG, "RemoteException", e);
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001389 }
1390
Narayan Kamath32684dd2018-01-08 17:32:51 +00001391 // (2) Inform AppOps service about the list of changes to UIDs.
1392
1393 List<WorkChain>[] diffs = WorkSource.diffChains(mClientSource, source);
1394 if (diffs != null) {
1395 List<WorkChain> newChains = diffs[0];
1396 List<WorkChain> goneChains = diffs[1];
1397
1398 if (newChains != null) {
1399 for (int i = 0; i < newChains.size(); ++i) {
1400 final WorkChain newChain = newChains.get(i);
Svet Ganovf7b47252018-02-26 11:11:27 -08001401 mAppOps.startOpNoThrow(AppOpsManager.OP_GPS, newChain.getAttributionUid(),
1402 newChain.getAttributionTag());
Narayan Kamath32684dd2018-01-08 17:32:51 +00001403 }
1404 }
1405
1406 if (goneChains != null) {
1407 for (int i = 0; i < goneChains.size(); i++) {
1408 final WorkChain goneChain = goneChains.get(i);
Svet Ganovf7b47252018-02-26 11:11:27 -08001409 mAppOps.finishOp(AppOpsManager.OP_GPS, goneChain.getAttributionUid(),
1410 goneChain.getAttributionTag());
Narayan Kamath32684dd2018-01-08 17:32:51 +00001411 }
1412 }
1413
1414 mClientSource.transferWorkChains(source);
1415 }
1416
1417 // Update the flat UIDs and names list and inform app-ops of all changes.
1418 WorkSource[] changes = mClientSource.setReturningDiffs(source);
1419 if (changes != null) {
1420 WorkSource newWork = changes[0];
1421 WorkSource goneWork = changes[1];
1422
1423 // Update sources that were not previously tracked.
1424 if (newWork != null) {
1425 for (int i = 0; i < newWork.size(); i++) {
Svet Ganovf7b47252018-02-26 11:11:27 -08001426 mAppOps.startOpNoThrow(AppOpsManager.OP_GPS,
1427 newWork.get(i), newWork.getName(i));
Narayan Kamath32684dd2018-01-08 17:32:51 +00001428 }
1429 }
1430
1431 // Update sources that are no longer tracked.
1432 if (goneWork != null) {
1433 for (int i = 0; i < goneWork.size(); i++) {
Svet Ganovf7b47252018-02-26 11:11:27 -08001434 mAppOps.finishOp(AppOpsManager.OP_GPS, goneWork.get(i), goneWork.getName(i));
Dianne Hackborn2e418422009-06-22 20:00:17 -07001435 }
Mike Lockwood2f82c4e2009-04-17 08:24:10 -04001436 }
1437 }
1438 }
1439
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001440 @Override
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001441 public boolean sendExtraCommand(String command, Bundle extras) {
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001442
Mike Lockwood63aa5a62010-04-14 19:21:31 -04001443 long identity = Binder.clearCallingIdentity();
Peter Visontayb25db362017-11-01 18:18:12 +00001444 try {
1445 boolean result = false;
Mike Lockwood63aa5a62010-04-14 19:21:31 -04001446
Peter Visontayb25db362017-11-01 18:18:12 +00001447 if ("delete_aiding_data".equals(command)) {
1448 result = deleteAidingData(extras);
1449 } else if ("force_time_injection".equals(command)) {
1450 requestUtcTime();
Mike Lockwood63aa5a62010-04-14 19:21:31 -04001451 result = true;
Peter Visontayb25db362017-11-01 18:18:12 +00001452 } else if ("force_xtra_injection".equals(command)) {
1453 if (mSupportsXtra) {
1454 xtraDownloadRequest();
1455 result = true;
1456 }
1457 } else {
1458 Log.w(TAG, "sendExtraCommand: unknown command " + command);
Mike Lockwood93bc44d2009-05-20 16:58:22 -04001459 }
Peter Visontayb25db362017-11-01 18:18:12 +00001460 return result;
1461 } finally {
1462 Binder.restoreCallingIdentity(identity);
Mike Lockwood93bc44d2009-05-20 16:58:22 -04001463 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001464 }
1465
1466 private boolean deleteAidingData(Bundle extras) {
1467 int flags;
1468
1469 if (extras == null) {
1470 flags = GPS_DELETE_ALL;
1471 } else {
1472 flags = 0;
1473 if (extras.getBoolean("ephemeris")) flags |= GPS_DELETE_EPHEMERIS;
1474 if (extras.getBoolean("almanac")) flags |= GPS_DELETE_ALMANAC;
1475 if (extras.getBoolean("position")) flags |= GPS_DELETE_POSITION;
1476 if (extras.getBoolean("time")) flags |= GPS_DELETE_TIME;
1477 if (extras.getBoolean("iono")) flags |= GPS_DELETE_IONO;
1478 if (extras.getBoolean("utc")) flags |= GPS_DELETE_UTC;
1479 if (extras.getBoolean("health")) flags |= GPS_DELETE_HEALTH;
1480 if (extras.getBoolean("svdir")) flags |= GPS_DELETE_SVDIR;
1481 if (extras.getBoolean("svsteer")) flags |= GPS_DELETE_SVSTEER;
1482 if (extras.getBoolean("sadata")) flags |= GPS_DELETE_SADATA;
1483 if (extras.getBoolean("rti")) flags |= GPS_DELETE_RTI;
1484 if (extras.getBoolean("celldb-info")) flags |= GPS_DELETE_CELLDB_INFO;
1485 if (extras.getBoolean("all")) flags |= GPS_DELETE_ALL;
1486 }
1487
1488 if (flags != 0) {
1489 native_delete_aiding_data(flags);
1490 return true;
1491 }
1492
1493 return false;
1494 }
1495
Stan Chesnutt1d72d8c2013-04-15 19:18:02 -07001496 private void startNavigating(boolean singleShot) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001497 if (!mStarted) {
Stan Chesnutt1d72d8c2013-04-15 19:18:02 -07001498 if (DEBUG) Log.d(TAG, "startNavigating, singleShot is " + singleShot);
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001499 mTimeToFirstFix = 0;
1500 mLastFixTime = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001501 mStarted = true;
Stan Chesnutt1d72d8c2013-04-15 19:18:02 -07001502 mSingleShot = singleShot;
Mike Lockwood03ca2162010-04-01 08:10:09 -07001503 mPositionMode = GPS_POSITION_MODE_STANDALONE;
Wyatt Riley5d5bac82016-11-01 07:05:16 -07001504 // Notify about suppressed output, if speed limit was previously exceeded.
1505 // Elsewhere, we check again with every speed output reported.
1506 if (mItarSpeedLimitExceeded) {
1507 Log.i(TAG, "startNavigating with ITAR limit in place. Output limited " +
1508 "until slow enough speed reported.");
1509 }
Mike Lockwood03ca2162010-04-01 08:10:09 -07001510
Tsuwei Chen462bcd82014-09-17 12:28:49 -07001511 boolean agpsEnabled =
1512 (Settings.Global.getInt(mContext.getContentResolver(),
gomo48f1a642017-11-10 20:35:46 -08001513 Settings.Global.ASSISTED_GPS_ENABLED, 1) != 0);
Tsuwei Chen462bcd82014-09-17 12:28:49 -07001514 mPositionMode = getSuplMode(mProperties, agpsEnabled, singleShot);
Mike Lockwoodbcab8df2009-06-25 16:39:09 -04001515
Stan Chesnutt1d72d8c2013-04-15 19:18:02 -07001516 if (DEBUG) {
1517 String mode;
1518
gomo48f1a642017-11-10 20:35:46 -08001519 switch (mPositionMode) {
Stan Chesnutt1d72d8c2013-04-15 19:18:02 -07001520 case GPS_POSITION_MODE_STANDALONE:
1521 mode = "standalone";
1522 break;
1523 case GPS_POSITION_MODE_MS_ASSISTED:
1524 mode = "MS_ASSISTED";
1525 break;
1526 case GPS_POSITION_MODE_MS_BASED:
1527 mode = "MS_BASED";
1528 break;
1529 default:
1530 mode = "unknown";
1531 break;
1532 }
1533 Log.d(TAG, "setting position_mode to " + mode);
1534 }
1535
Mike Lockwood04598b62010-04-14 17:17:24 -04001536 int interval = (hasCapability(GPS_CAPABILITY_SCHEDULING) ? mFixInterval : 1000);
gomo48f1a642017-11-10 20:35:46 -08001537 mLowPowerMode = (boolean) mProviderRequest.lowPowerMode;
Mike Lockwood04598b62010-04-14 17:17:24 -04001538 if (!native_set_position_mode(mPositionMode, GPS_POSITION_RECURRENCE_PERIODIC,
gomo48f1a642017-11-10 20:35:46 -08001539 interval, 0, 0, mLowPowerMode)) {
Mike Lockwood04598b62010-04-14 17:17:24 -04001540 mStarted = false;
1541 Log.e(TAG, "set_position_mode failed in startNavigating()");
1542 return;
1543 }
1544 if (!native_start()) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001545 mStarted = false;
1546 Log.e(TAG, "native_start failed in startNavigating()");
Mike Lockwood0632ca72009-05-14 15:51:03 -04001547 return;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001548 }
1549
1550 // reset SV count to zero
Wyatt Rileyc7067412018-02-07 15:50:35 -08001551 updateStatus(LocationProvider.TEMPORARILY_UNAVAILABLE);
1552 mLocationExtras.reset();
Yipeng Cao282b5942017-05-17 20:31:39 -07001553 mFixRequestTime = SystemClock.elapsedRealtime();
Mike Lockwood04598b62010-04-14 17:17:24 -04001554 if (!hasCapability(GPS_CAPABILITY_SCHEDULING)) {
1555 // set timer to give up if we do not receive a fix within NO_FIX_TIMEOUT
1556 // and our fix interval is not short
1557 if (mFixInterval >= NO_FIX_TIMEOUT) {
1558 mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP,
1559 SystemClock.elapsedRealtime() + NO_FIX_TIMEOUT, mTimeoutIntent);
1560 }
Mike Lockwood0632ca72009-05-14 15:51:03 -04001561 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001562 }
1563 }
1564
Mike Lockwood62a8fc12010-03-22 14:23:26 -04001565 private void stopNavigating() {
Mike Lockwood29c84342009-05-06 14:01:15 -04001566 if (DEBUG) Log.d(TAG, "stopNavigating");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001567 if (mStarted) {
1568 mStarted = false;
Stan Chesnutt1d72d8c2013-04-15 19:18:02 -07001569 mSingleShot = false;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001570 native_stop();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001571 mLastFixTime = 0;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001572
1573 // reset SV count to zero
Wyatt Rileyc7067412018-02-07 15:50:35 -08001574 updateStatus(LocationProvider.TEMPORARILY_UNAVAILABLE);
1575 mLocationExtras.reset();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001576 }
1577 }
1578
Mike Lockwood0632ca72009-05-14 15:51:03 -04001579 private void hibernate() {
1580 // stop GPS until our next fix interval arrives
1581 stopNavigating();
Mike Lockwood0632ca72009-05-14 15:51:03 -04001582 mAlarmManager.cancel(mTimeoutIntent);
1583 mAlarmManager.cancel(mWakeupIntent);
1584 long now = SystemClock.elapsedRealtime();
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001585 mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, now + mFixInterval, mWakeupIntent);
Mike Lockwood04598b62010-04-14 17:17:24 -04001586 }
1587
1588 private boolean hasCapability(int capability) {
1589 return ((mEngineCapabilities & capability) != 0);
Mike Lockwood0632ca72009-05-14 15:51:03 -04001590 }
1591
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07001592
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001593 /**
1594 * called from native code to update our position.
1595 */
Wyatt Riley5d229832017-02-10 17:06:00 -08001596 private void reportLocation(boolean hasLatLong, Location location) {
Wyatt Riley26465d22018-02-12 13:44:24 -08001597 sendMessage(REPORT_LOCATION, hasLatLong ? 1 : 0, location);
1598 }
1599
1600 private void handleReportLocation(boolean hasLatLong, Location location) {
Wyatt Riley5d229832017-02-10 17:06:00 -08001601 if (location.hasSpeed()) {
1602 mItarSpeedLimitExceeded = location.getSpeed() > ITAR_SPEED_LIMIT_METERS_PER_SECOND;
Wyatt Riley5d5bac82016-11-01 07:05:16 -07001603 }
1604
1605 if (mItarSpeedLimitExceeded) {
1606 Log.i(TAG, "Hal reported a speed in excess of ITAR limit." +
1607 " GPS/GNSS Navigation output blocked.");
Siddharth Ray53ddc802018-03-16 12:01:52 -07001608 if (mStarted) {
1609 mGnssMetrics.logReceivedLocationStatus(false);
1610 }
Wyatt Riley5d5bac82016-11-01 07:05:16 -07001611 return; // No output of location allowed
1612 }
1613
Wyatt Riley5d229832017-02-10 17:06:00 -08001614 if (VERBOSE) Log.v(TAG, "reportLocation " + location.toString());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001615
Wyatt Riley26465d22018-02-12 13:44:24 -08001616 // It would be nice to push the elapsed real-time timestamp
1617 // further down the stack, but this is still useful
1618 location.setElapsedRealtimeNanos(SystemClock.elapsedRealtimeNanos());
1619 location.setExtras(mLocationExtras.getBundle());
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001620
Wyatt Riley26465d22018-02-12 13:44:24 -08001621 try {
1622 mILocationManager.reportLocation(location, false);
1623 } catch (RemoteException e) {
1624 Log.e(TAG, "RemoteException calling reportLocation");
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001625 }
1626
Siddharth Ray53ddc802018-03-16 12:01:52 -07001627 if (mStarted) {
1628 mGnssMetrics.logReceivedLocationStatus(hasLatLong);
1629 if (hasLatLong) {
1630 if (location.hasAccuracy()) {
1631 mGnssMetrics.logPositionAccuracyMeters(location.getAccuracy());
1632 }
1633 if (mTimeToFirstFix > 0) {
1634 int timeBetweenFixes = (int) (SystemClock.elapsedRealtime() - mLastFixTime);
1635 mGnssMetrics.logMissedReports(mFixInterval, timeBetweenFixes);
1636 }
Siddharth Raybb608c82017-03-16 11:33:34 -07001637 }
1638 }
1639
Yipeng Cao282b5942017-05-17 20:31:39 -07001640 mLastFixTime = SystemClock.elapsedRealtime();
Hakan Gustavssonfa94ff02010-02-23 09:12:38 +01001641 // report time to first fix
Wyatt Riley5d229832017-02-10 17:06:00 -08001642 if (mTimeToFirstFix == 0 && hasLatLong) {
gomo48f1a642017-11-10 20:35:46 -08001643 mTimeToFirstFix = (int) (mLastFixTime - mFixRequestTime);
Nick Pelly6fa9ad42012-07-16 12:18:23 -07001644 if (DEBUG) Log.d(TAG, "TTFF: " + mTimeToFirstFix);
Siddharth Ray53ddc802018-03-16 12:01:52 -07001645 if (mStarted) {
1646 mGnssMetrics.logTimeToFirstFixMilliSecs(mTimeToFirstFix);
1647 }
Hakan Gustavssonfa94ff02010-02-23 09:12:38 +01001648
1649 // notify status listeners
destradaaea8a8a62014-06-23 18:19:03 -07001650 mListenerHelper.onFirstFix(mTimeToFirstFix);
Hakan Gustavssonfa94ff02010-02-23 09:12:38 +01001651 }
1652
Stan Chesnutt1d72d8c2013-04-15 19:18:02 -07001653 if (mSingleShot) {
1654 stopNavigating();
1655 }
1656
Mike Lockwood15e3d0f2009-05-01 07:53:28 -04001657 if (mStarted && mStatus != LocationProvider.AVAILABLE) {
Wyatt Rileyc7067412018-02-07 15:50:35 -08001658 // For devices that use framework scheduling, a timer may be set to ensure we don't
1659 // spend too much power searching for a location, when the requested update rate is slow.
1660 // As we just recievied a location, we'll cancel that timer.
Mike Lockwood04598b62010-04-14 17:17:24 -04001661 if (!hasCapability(GPS_CAPABILITY_SCHEDULING) && mFixInterval < NO_FIX_TIMEOUT) {
Mike Lockwoodb7be5442010-02-24 14:34:50 -05001662 mAlarmManager.cancel(mTimeoutIntent);
1663 }
1664
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001665 // send an intent to notify that the GPS is receiving fixes.
Mike Lockwood00b74272010-03-26 10:41:48 -04001666 Intent intent = new Intent(LocationManager.GPS_FIX_CHANGE_ACTION);
1667 intent.putExtra(LocationManager.EXTRA_GPS_ENABLED, true);
Dianne Hackborn5ac72a22012-08-29 18:32:08 -07001668 mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
Wyatt Rileyc7067412018-02-07 15:50:35 -08001669 updateStatus(LocationProvider.AVAILABLE);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001670 }
Mike Lockwood29c84342009-05-06 14:01:15 -04001671
gomo48f1a642017-11-10 20:35:46 -08001672 if (!hasCapability(GPS_CAPABILITY_SCHEDULING) && mStarted &&
1673 mFixInterval > GPS_POLLING_THRESHOLD_INTERVAL) {
Mike Lockwoodd53ba012010-04-15 20:41:26 -04001674 if (DEBUG) Log.d(TAG, "got fix, hibernating");
Mike Lockwood0632ca72009-05-14 15:51:03 -04001675 hibernate();
Mike Lockwood29c84342009-05-06 14:01:15 -04001676 }
gomo48f1a642017-11-10 20:35:46 -08001677 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001678
1679 /**
1680 * called from native code to update our status
1681 */
1682 private void reportStatus(int status) {
Mike Lockwoodb8d90332010-10-18 17:59:48 -04001683 if (DEBUG) Log.v(TAG, "reportStatus status: " + status);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001684
destradaaea8a8a62014-06-23 18:19:03 -07001685 boolean wasNavigating = mNavigating;
1686 switch (status) {
1687 case GPS_STATUS_SESSION_BEGIN:
1688 mNavigating = true;
1689 mEngineOn = true;
1690 break;
1691 case GPS_STATUS_SESSION_END:
1692 mNavigating = false;
1693 break;
1694 case GPS_STATUS_ENGINE_ON:
1695 mEngineOn = true;
1696 break;
1697 case GPS_STATUS_ENGINE_OFF:
1698 mEngineOn = false;
1699 mNavigating = false;
1700 break;
1701 }
Mike Lockwooddbd6fd82009-12-07 18:43:36 -05001702
destradaaea8a8a62014-06-23 18:19:03 -07001703 if (wasNavigating != mNavigating) {
destradaa13a60b02015-01-15 18:36:01 -08001704 mListenerHelper.onStatusChanged(mNavigating);
Mike Lockwoodcf1d8cb2010-01-20 10:14:54 -05001705
destradaaea8a8a62014-06-23 18:19:03 -07001706 // send an intent to notify that the GPS has been enabled or disabled
1707 Intent intent = new Intent(LocationManager.GPS_ENABLED_CHANGE_ACTION);
1708 intent.putExtra(LocationManager.EXTRA_GPS_ENABLED, mNavigating);
1709 mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001710 }
1711 }
1712
Wyatt Riley26465d22018-02-12 13:44:24 -08001713 // Helper class to carry data to handler for reportSvStatus
1714 private static class SvStatusInfo {
1715 public int mSvCount;
1716 public int[] mSvidWithFlags;
1717 public float[] mCn0s;
1718 public float[] mSvElevations;
1719 public float[] mSvAzimuths;
1720 public float[] mSvCarrierFreqs;
1721 }
1722
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001723 /**
1724 * called from native code to update SV info
1725 */
Wyatt Riley26465d22018-02-12 13:44:24 -08001726 private void reportSvStatus(int svCount, int[] svidWithFlags, float[] cn0s,
1727 float[] svElevations, float[] svAzimuths, float[] svCarrierFreqs) {
1728 SvStatusInfo svStatusInfo = new SvStatusInfo();
1729 svStatusInfo.mSvCount = svCount;
1730 svStatusInfo.mSvidWithFlags = svidWithFlags;
1731 svStatusInfo.mCn0s = cn0s;
1732 svStatusInfo.mSvElevations = svElevations;
1733 svStatusInfo.mSvAzimuths = svAzimuths;
1734 svStatusInfo.mSvCarrierFreqs = svCarrierFreqs;
1735
1736 sendMessage(REPORT_SV_STATUS, 0, svStatusInfo);
1737 }
1738
1739 private void handleReportSvStatus(SvStatusInfo info) {
destradaaea8a8a62014-06-23 18:19:03 -07001740 mListenerHelper.onSvStatusChanged(
Wyatt Riley26465d22018-02-12 13:44:24 -08001741 info.mSvCount,
1742 info.mSvidWithFlags,
1743 info.mCn0s,
1744 info.mSvElevations,
1745 info.mSvAzimuths,
1746 info.mSvCarrierFreqs);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001747
Siddharth Ray168f12a2017-07-10 11:55:10 -07001748 // Log CN0 as part of GNSS metrics
Wyatt Riley26465d22018-02-12 13:44:24 -08001749 mGnssMetrics.logCn0(info.mCn0s, info.mSvCount);
Siddharth Ray168f12a2017-07-10 11:55:10 -07001750
Mike Lockwood29c84342009-05-06 14:01:15 -04001751 if (VERBOSE) {
Wyatt Riley26465d22018-02-12 13:44:24 -08001752 Log.v(TAG, "SV count: " + info.mSvCount);
Lifu Tang30f95a72016-01-07 23:20:38 -08001753 }
Wyatt Rileyc9f25dd2017-05-05 13:45:23 -07001754 // Calculate number of satellites used in fix.
Lifu Tang30f95a72016-01-07 23:20:38 -08001755 int usedInFixCount = 0;
Wyatt Rileyc9f25dd2017-05-05 13:45:23 -07001756 int maxCn0 = 0;
1757 int meanCn0 = 0;
Wyatt Riley26465d22018-02-12 13:44:24 -08001758 for (int i = 0; i < info.mSvCount; i++) {
1759 if ((info.mSvidWithFlags[i] & GnssStatus.GNSS_SV_FLAGS_USED_IN_FIX) != 0) {
Lifu Tang30f95a72016-01-07 23:20:38 -08001760 ++usedInFixCount;
Wyatt Riley26465d22018-02-12 13:44:24 -08001761 if (info.mCn0s[i] > maxCn0) {
1762 maxCn0 = (int) info.mCn0s[i];
Wyatt Rileyc9f25dd2017-05-05 13:45:23 -07001763 }
Wyatt Riley26465d22018-02-12 13:44:24 -08001764 meanCn0 += info.mCn0s[i];
Lifu Tang30f95a72016-01-07 23:20:38 -08001765 }
1766 if (VERBOSE) {
Wyatt Riley26465d22018-02-12 13:44:24 -08001767 Log.v(TAG, "svid: " + (info.mSvidWithFlags[i] >> GnssStatus.SVID_SHIFT_WIDTH) +
1768 " cn0: " + info.mCn0s[i] +
1769 " elev: " + info.mSvElevations[i] +
1770 " azimuth: " + info.mSvAzimuths[i] +
1771 " carrier frequency: " + info.mSvCarrierFreqs[i] +
1772 ((info.mSvidWithFlags[i] & GnssStatus.GNSS_SV_FLAGS_HAS_EPHEMERIS_DATA) == 0
Lifu Tang30f95a72016-01-07 23:20:38 -08001773 ? " " : " E") +
Wyatt Riley26465d22018-02-12 13:44:24 -08001774 ((info.mSvidWithFlags[i] & GnssStatus.GNSS_SV_FLAGS_HAS_ALMANAC_DATA) == 0
Lifu Tang30f95a72016-01-07 23:20:38 -08001775 ? " " : " A") +
Wyatt Riley26465d22018-02-12 13:44:24 -08001776 ((info.mSvidWithFlags[i] & GnssStatus.GNSS_SV_FLAGS_USED_IN_FIX) == 0
gomo4402af62017-01-11 13:20:13 -08001777 ? "" : "U") +
Wyatt Riley26465d22018-02-12 13:44:24 -08001778 ((info.mSvidWithFlags[i] &
1779 GnssStatus.GNSS_SV_FLAGS_HAS_CARRIER_FREQUENCY) == 0
gomo48f1a642017-11-10 20:35:46 -08001780 ? "" : "F"));
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001781 }
1782 }
Wyatt Rileyc9f25dd2017-05-05 13:45:23 -07001783 if (usedInFixCount > 0) {
1784 meanCn0 /= usedInFixCount;
1785 }
1786 // return number of sats used in fix instead of total reported
Wyatt Rileyc7067412018-02-07 15:50:35 -08001787 mLocationExtras.set(usedInFixCount, meanCn0, maxCn0);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001788
Mike Lockwood15e3d0f2009-05-01 07:53:28 -04001789 if (mNavigating && mStatus == LocationProvider.AVAILABLE && mLastFixTime > 0 &&
gomo48f1a642017-11-10 20:35:46 -08001790 SystemClock.elapsedRealtime() - mLastFixTime > RECENT_FIX_TIMEOUT) {
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001791 // send an intent to notify that the GPS is no longer receiving fixes.
Mike Lockwood00b74272010-03-26 10:41:48 -04001792 Intent intent = new Intent(LocationManager.GPS_FIX_CHANGE_ACTION);
1793 intent.putExtra(LocationManager.EXTRA_GPS_ENABLED, false);
Dianne Hackborn5ac72a22012-08-29 18:32:08 -07001794 mContext.sendBroadcastAsUser(intent, UserHandle.ALL);
Wyatt Rileyc7067412018-02-07 15:50:35 -08001795 updateStatus(LocationProvider.TEMPORARILY_UNAVAILABLE);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08001796 }
1797 }
Mike Lockwood58bda982009-04-14 16:25:07 -04001798
1799 /**
Mike Lockwoode3635c92009-05-11 08:38:02 -04001800 * called from native code to update AGPS status
Mike Lockwood58bda982009-04-14 16:25:07 -04001801 */
destradaa96a14702014-06-05 11:36:30 -07001802 private void reportAGpsStatus(int type, int status, byte[] ipaddr) {
Mike Lockwood58bda982009-04-14 16:25:07 -04001803 switch (status) {
Mike Lockwoode3635c92009-05-11 08:38:02 -04001804 case GPS_REQUEST_AGPS_DATA_CONN:
Mike Lockwoodb6e5fa82010-10-09 20:10:46 -04001805 if (DEBUG) Log.d(TAG, "GPS_REQUEST_AGPS_DATA_CONN");
Andreas Gampee6748ce2015-12-11 18:00:38 -08001806 Log.v(TAG, "Received SUPL IP addr[]: " + Arrays.toString(ipaddr));
destradaae21252a2015-09-08 12:32:59 -07001807 InetAddress connectionIpAddress = null;
destradaa96a14702014-06-05 11:36:30 -07001808 if (ipaddr != null) {
1809 try {
destradaae21252a2015-09-08 12:32:59 -07001810 connectionIpAddress = InetAddress.getByAddress(ipaddr);
1811 if (DEBUG) Log.d(TAG, "IP address converted to: " + connectionIpAddress);
destradaa96a14702014-06-05 11:36:30 -07001812 } catch (UnknownHostException e) {
1813 Log.e(TAG, "Bad IP Address: " + ipaddr, e);
destradaa96a14702014-06-05 11:36:30 -07001814 }
1815 }
destradaae21252a2015-09-08 12:32:59 -07001816 sendMessage(REQUEST_SUPL_CONNECTION, 0 /*arg*/, connectionIpAddress);
Mike Lockwood58bda982009-04-14 16:25:07 -04001817 break;
Mike Lockwoode3635c92009-05-11 08:38:02 -04001818 case GPS_RELEASE_AGPS_DATA_CONN:
Mike Lockwoodb6e5fa82010-10-09 20:10:46 -04001819 if (DEBUG) Log.d(TAG, "GPS_RELEASE_AGPS_DATA_CONN");
destradaae21252a2015-09-08 12:32:59 -07001820 releaseSuplConnection(GPS_RELEASE_AGPS_DATA_CONN);
Mike Lockwood58bda982009-04-14 16:25:07 -04001821 break;
Mike Lockwoode3635c92009-05-11 08:38:02 -04001822 case GPS_AGPS_DATA_CONNECTED:
Mike Lockwoodb6e5fa82010-10-09 20:10:46 -04001823 if (DEBUG) Log.d(TAG, "GPS_AGPS_DATA_CONNECTED");
Mike Lockwood58bda982009-04-14 16:25:07 -04001824 break;
Mike Lockwoode3635c92009-05-11 08:38:02 -04001825 case GPS_AGPS_DATA_CONN_DONE:
Mike Lockwoodb6e5fa82010-10-09 20:10:46 -04001826 if (DEBUG) Log.d(TAG, "GPS_AGPS_DATA_CONN_DONE");
Mike Lockwood58bda982009-04-14 16:25:07 -04001827 break;
Mike Lockwoode3635c92009-05-11 08:38:02 -04001828 case GPS_AGPS_DATA_CONN_FAILED:
Mike Lockwoodb6e5fa82010-10-09 20:10:46 -04001829 if (DEBUG) Log.d(TAG, "GPS_AGPS_DATA_CONN_FAILED");
Mike Lockwood58bda982009-04-14 16:25:07 -04001830 break;
destradaa931a37f2014-08-12 16:36:59 -07001831 default:
Joe Onorato0c484102016-02-01 18:04:24 -08001832 if (DEBUG) Log.d(TAG, "Received Unknown AGPS status: " + status);
Mike Lockwood58bda982009-04-14 16:25:07 -04001833 }
1834 }
1835
destradaae21252a2015-09-08 12:32:59 -07001836 private void releaseSuplConnection(int connStatus) {
1837 sendMessage(RELEASE_SUPL_CONNECTION, connStatus, null /*obj*/);
1838 }
1839
Mike Lockwoodb16e7802009-08-06 09:26:02 -04001840 /**
1841 * called from native code to report NMEA data received
1842 */
Mike Lockwoodf602d362010-06-20 14:28:16 -07001843 private void reportNmea(long timestamp) {
Wyatt Riley5d5bac82016-11-01 07:05:16 -07001844 if (!mItarSpeedLimitExceeded) {
1845 int length = native_read_nmea(mNmeaBuffer, mNmeaBuffer.length);
1846 String nmea = new String(mNmeaBuffer, 0 /* offset */, length);
1847 mListenerHelper.onNmeaReceived(timestamp, nmea);
1848 }
destradaaea8a8a62014-06-23 18:19:03 -07001849 }
Mike Lockwoodb16e7802009-08-06 09:26:02 -04001850
destradaaea8a8a62014-06-23 18:19:03 -07001851 /**
Wyatt Rileyaa420d52017-07-03 15:14:42 -07001852 * called from native code - GNSS measurements callback
destradaaea8a8a62014-06-23 18:19:03 -07001853 */
Lifu Tang818aa2c2016-02-01 01:52:00 -08001854 private void reportMeasurementData(GnssMeasurementsEvent event) {
Wyatt Riley5d5bac82016-11-01 07:05:16 -07001855 if (!mItarSpeedLimitExceeded) {
Wyatt Rileyaa420d52017-07-03 15:14:42 -07001856 // send to handler to allow native to return quickly
1857 mHandler.post(new Runnable() {
1858 @Override
1859 public void run() {
1860 mGnssMeasurementsProvider.onMeasurementsAvailable(event);
1861 }
1862 });
Wyatt Riley5d5bac82016-11-01 07:05:16 -07001863 }
Mike Lockwoodb16e7802009-08-06 09:26:02 -04001864 }
1865
Mike Lockwood62a8fc12010-03-22 14:23:26 -04001866 /**
Wyatt Rileyaa420d52017-07-03 15:14:42 -07001867 * called from native code - GNSS navigation message callback
destradaa4b3e3932014-07-21 18:01:47 -07001868 */
Lifu Tange8abe8e2016-04-01 10:32:05 -07001869 private void reportNavigationMessage(GnssNavigationMessage event) {
Wyatt Riley5d5bac82016-11-01 07:05:16 -07001870 if (!mItarSpeedLimitExceeded) {
Wyatt Rileyaa420d52017-07-03 15:14:42 -07001871 // send to handler to allow native to return quickly
1872 mHandler.post(new Runnable() {
1873 @Override
1874 public void run() {
1875 mGnssNavigationMessageProvider.onNavigationMessageAvailable(event);
1876 }
1877 });
Wyatt Riley5d5bac82016-11-01 07:05:16 -07001878 }
destradaa4b3e3932014-07-21 18:01:47 -07001879 }
1880
1881 /**
Mike Lockwood04598b62010-04-14 17:17:24 -04001882 * called from native code to inform us what the GPS engine capabilities are
1883 */
Wyatt Rileyd87cf912017-12-05 09:31:52 -08001884 private void setEngineCapabilities(final int capabilities) {
1885 // send to handler thread for fast native return, and in-order handling
1886 mHandler.post(new Runnable() {
1887 @Override
1888 public void run() {
1889 mEngineCapabilities = capabilities;
Mike Lockwood9b9fb5c2011-06-29 15:09:40 -04001890
Wyatt Rileyd87cf912017-12-05 09:31:52 -08001891 if (hasCapability(GPS_CAPABILITY_ON_DEMAND_TIME)) {
Yu-Han Yanga1862b52018-02-20 17:05:59 -08001892 mNtpTimeHelper.enablePeriodicTimeInjection();
Wyatt Rileyd87cf912017-12-05 09:31:52 -08001893 requestUtcTime();
1894 }
destradaa6568d702014-10-27 12:47:41 -07001895
Wyatt Rileyd87cf912017-12-05 09:31:52 -08001896 mGnssMeasurementsProvider.onCapabilitiesUpdated(hasCapability(
1897 GPS_CAPABILITY_MEASUREMENTS));
1898 mGnssNavigationMessageProvider.onCapabilitiesUpdated(hasCapability(
1899 GPS_CAPABILITY_NAV_MESSAGES));
Yu-Han Yang52057622018-04-25 00:51:22 -07001900 restartRequests();
Wyatt Rileyd87cf912017-12-05 09:31:52 -08001901 }
1902 });
Yu-Han Yang52057622018-04-25 00:51:22 -07001903 }
1904
1905 private void restartRequests() {
1906 Log.i(TAG, "restartRequests");
1907
1908 restartLocationRequest();
1909 mGnssMeasurementsProvider.resumeIfStarted();
1910 mGnssNavigationMessageProvider.resumeIfStarted();
1911 mGnssBatchingProvider.resumeIfStarted();
1912 mGnssGeofenceProvider.resumeIfStarted();
1913 }
1914
1915 private void restartLocationRequest() {
1916 if (DEBUG) Log.d(TAG, "restartLocationRequest");
1917 mStarted = false;
1918 updateRequirements();
1919 }
Wyatt Rileyd87cf912017-12-05 09:31:52 -08001920
1921 /**
1922 * Called from native code to inform us the hardware year.
1923 */
1924 private void setGnssYearOfHardware(final int yearOfHardware) {
1925 // mHardwareYear is simply set here, to be read elsewhere, and is volatile for safe sync
1926 if (DEBUG) Log.d(TAG, "setGnssYearOfHardware called with " + yearOfHardware);
1927 mHardwareYear = yearOfHardware;
Mike Lockwood04598b62010-04-14 17:17:24 -04001928 }
1929
1930 /**
Wyatt Rileyd87cf912017-12-05 09:31:52 -08001931 * Called from native code to inform us the hardware model name.
Lifu Tang82f893d2016-01-21 18:15:33 -08001932 */
Wyatt Rileyd87cf912017-12-05 09:31:52 -08001933 private void setGnssHardwareModelName(final String modelName) {
1934 // mHardwareModelName is simply set here, to be read elsewhere, and volatile for safe sync
1935 if (DEBUG) Log.d(TAG, "setGnssModelName called with " + modelName);
1936 mHardwareModelName = modelName;
Lifu Tang82f893d2016-01-21 18:15:33 -08001937 }
1938
Yu-Han Yang52057622018-04-25 00:51:22 -07001939 /**
1940 * Called from native code to inform us GNSS HAL service died.
1941 */
1942 private void reportGnssServiceDied() {
1943 if (DEBUG) Log.d(TAG, "reportGnssServiceDied");
1944 mHandler.post(() -> {
1945 class_init_native();
1946 native_init_once();
1947 if (isEnabled()) {
1948 // re-calls native_init() and other setup.
1949 handleEnable();
1950 // resend configuration into the restarted HAL service.
1951 reloadGpsProperties(mContext, mProperties);
1952 }
1953 });
1954 }
1955
Lifu Tang9363b942016-02-16 18:07:00 -08001956 public interface GnssSystemInfoProvider {
Lifu Tang82f893d2016-01-21 18:15:33 -08001957 /**
Wyatt Rileyd87cf912017-12-05 09:31:52 -08001958 * Returns the year of underlying GPS hardware.
Lifu Tang82f893d2016-01-21 18:15:33 -08001959 */
Lifu Tang9363b942016-02-16 18:07:00 -08001960 int getGnssYearOfHardware();
Wyatt Rileyd87cf912017-12-05 09:31:52 -08001961 /**
1962 * Returns the model name of underlying GPS hardware.
1963 */
1964 String getGnssHardwareModelName();
Lifu Tang82f893d2016-01-21 18:15:33 -08001965 }
1966
1967 /**
1968 * @hide
1969 */
Lifu Tang9363b942016-02-16 18:07:00 -08001970 public GnssSystemInfoProvider getGnssSystemInfoProvider() {
1971 return new GnssSystemInfoProvider() {
Lifu Tang82f893d2016-01-21 18:15:33 -08001972 @Override
Lifu Tang9363b942016-02-16 18:07:00 -08001973 public int getGnssYearOfHardware() {
Wyatt Rileyd87cf912017-12-05 09:31:52 -08001974 return mHardwareYear;
1975 }
1976 @Override
1977 public String getGnssHardwareModelName() {
1978 return mHardwareModelName;
Lifu Tang82f893d2016-01-21 18:15:33 -08001979 }
1980 };
1981 }
1982
Wyatt Rileycf879db2017-01-12 13:57:38 -08001983 /**
1984 * @hide
1985 */
1986 public GnssBatchingProvider getGnssBatchingProvider() {
Yu-Han Yang3557cc72018-03-21 12:48:36 -07001987 return mGnssBatchingProvider;
Wyatt Rileycf879db2017-01-12 13:57:38 -08001988 }
1989
Siddharth Raybb608c82017-03-16 11:33:34 -07001990 public interface GnssMetricsProvider {
1991 /**
1992 * Returns GNSS metrics as proto string
1993 */
1994 String getGnssMetricsAsProtoString();
1995 }
1996
1997 /**
1998 * @hide
1999 */
2000 public GnssMetricsProvider getGnssMetricsProvider() {
2001 return new GnssMetricsProvider() {
2002 @Override
2003 public String getGnssMetricsAsProtoString() {
2004 return mGnssMetrics.dumpGnssMetricsAsProtoString();
2005 }
2006 };
2007 }
2008
Wyatt Rileycf879db2017-01-12 13:57:38 -08002009 /**
Wyatt Rileycf879db2017-01-12 13:57:38 -08002010 * called from native code - GNSS location batch callback
2011 */
2012 private void reportLocationBatch(Location[] locationArray) {
2013 List<Location> locations = new ArrayList<>(Arrays.asList(locationArray));
gomo48f1a642017-11-10 20:35:46 -08002014 if (DEBUG) {
2015 Log.d(TAG, "Location batch of size " + locationArray.length + " reported");
2016 }
Wyatt Rileycf879db2017-01-12 13:57:38 -08002017 try {
2018 mILocationManager.reportLocationBatch(locations);
2019 } catch (RemoteException e) {
2020 Log.e(TAG, "RemoteException calling reportLocationBatch");
2021 }
2022 }
2023
Lifu Tang82f893d2016-01-21 18:15:33 -08002024 /**
Mike Lockwood62a8fc12010-03-22 14:23:26 -04002025 * called from native code to request XTRA data
2026 */
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002027 private void xtraDownloadRequest() {
Joe Onoratof5d95cb2010-01-07 21:48:32 -05002028 if (DEBUG) Log.d(TAG, "xtraDownloadRequest");
Mike Lockwood98e48692010-04-07 16:32:51 -04002029 sendMessage(DOWNLOAD_XTRA_DATA, 0, null);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002030 }
2031
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07002032 /**
destradaa0682809a2013-08-12 18:50:30 -07002033 * Converts the GPS HAL status to the internal Geofence Hardware status.
2034 */
2035 private int getGeofenceStatus(int status) {
gomo48f1a642017-11-10 20:35:46 -08002036 switch (status) {
destradaa0682809a2013-08-12 18:50:30 -07002037 case GPS_GEOFENCE_OPERATION_SUCCESS:
2038 return GeofenceHardware.GEOFENCE_SUCCESS;
2039 case GPS_GEOFENCE_ERROR_GENERIC:
2040 return GeofenceHardware.GEOFENCE_FAILURE;
2041 case GPS_GEOFENCE_ERROR_ID_EXISTS:
2042 return GeofenceHardware.GEOFENCE_ERROR_ID_EXISTS;
2043 case GPS_GEOFENCE_ERROR_INVALID_TRANSITION:
2044 return GeofenceHardware.GEOFENCE_ERROR_INVALID_TRANSITION;
2045 case GPS_GEOFENCE_ERROR_TOO_MANY_GEOFENCES:
2046 return GeofenceHardware.GEOFENCE_ERROR_TOO_MANY_GEOFENCES;
2047 case GPS_GEOFENCE_ERROR_ID_UNKNOWN:
2048 return GeofenceHardware.GEOFENCE_ERROR_ID_UNKNOWN;
2049 default:
2050 return -1;
2051 }
2052 }
2053
2054 /**
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07002055 * Called from native to report GPS Geofence transition
2056 * All geofence callbacks are called on the same thread
2057 */
Wyatt Riley5d229832017-02-10 17:06:00 -08002058 private void reportGeofenceTransition(int geofenceId, Location location, int transition,
gomo48f1a642017-11-10 20:35:46 -08002059 long transitionTimestamp) {
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07002060 if (mGeofenceHardwareImpl == null) {
2061 mGeofenceHardwareImpl = GeofenceHardwareImpl.getInstance(mContext);
2062 }
Wyatt Riley5d229832017-02-10 17:06:00 -08002063
destradaa0682809a2013-08-12 18:50:30 -07002064 mGeofenceHardwareImpl.reportGeofenceTransition(
2065 geofenceId,
2066 location,
2067 transition,
2068 transitionTimestamp,
2069 GeofenceHardware.MONITORING_TYPE_GPS_HARDWARE,
2070 FusedBatchOptions.SourceTechnologies.GNSS);
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07002071 }
2072
2073 /**
2074 * called from native code to report GPS status change.
2075 */
Wyatt Riley5d229832017-02-10 17:06:00 -08002076 private void reportGeofenceStatus(int status, Location location) {
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07002077 if (mGeofenceHardwareImpl == null) {
2078 mGeofenceHardwareImpl = GeofenceHardwareImpl.getInstance(mContext);
2079 }
destradaa0682809a2013-08-12 18:50:30 -07002080 int monitorStatus = GeofenceHardware.MONITOR_CURRENTLY_UNAVAILABLE;
gomo48f1a642017-11-10 20:35:46 -08002081 if (status == GPS_GEOFENCE_AVAILABLE) {
destradaa0682809a2013-08-12 18:50:30 -07002082 monitorStatus = GeofenceHardware.MONITOR_CURRENTLY_AVAILABLE;
2083 }
2084 mGeofenceHardwareImpl.reportGeofenceMonitorStatus(
2085 GeofenceHardware.MONITORING_TYPE_GPS_HARDWARE,
2086 monitorStatus,
2087 location,
2088 FusedBatchOptions.SourceTechnologies.GNSS);
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07002089 }
2090
2091 /**
2092 * called from native code - Geofence Add callback
2093 */
2094 private void reportGeofenceAddStatus(int geofenceId, int status) {
2095 if (mGeofenceHardwareImpl == null) {
2096 mGeofenceHardwareImpl = GeofenceHardwareImpl.getInstance(mContext);
2097 }
destradaa0682809a2013-08-12 18:50:30 -07002098 mGeofenceHardwareImpl.reportGeofenceAddStatus(geofenceId, getGeofenceStatus(status));
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07002099 }
2100
2101 /**
2102 * called from native code - Geofence Remove callback
2103 */
2104 private void reportGeofenceRemoveStatus(int geofenceId, int status) {
2105 if (mGeofenceHardwareImpl == null) {
2106 mGeofenceHardwareImpl = GeofenceHardwareImpl.getInstance(mContext);
2107 }
destradaa0682809a2013-08-12 18:50:30 -07002108 mGeofenceHardwareImpl.reportGeofenceRemoveStatus(geofenceId, getGeofenceStatus(status));
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07002109 }
2110
2111 /**
2112 * called from native code - Geofence Pause callback
2113 */
2114 private void reportGeofencePauseStatus(int geofenceId, int status) {
2115 if (mGeofenceHardwareImpl == null) {
2116 mGeofenceHardwareImpl = GeofenceHardwareImpl.getInstance(mContext);
2117 }
destradaa0682809a2013-08-12 18:50:30 -07002118 mGeofenceHardwareImpl.reportGeofencePauseStatus(geofenceId, getGeofenceStatus(status));
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07002119 }
2120
2121 /**
2122 * called from native code - Geofence Resume callback
2123 */
2124 private void reportGeofenceResumeStatus(int geofenceId, int status) {
2125 if (mGeofenceHardwareImpl == null) {
2126 mGeofenceHardwareImpl = GeofenceHardwareImpl.getInstance(mContext);
2127 }
destradaa0682809a2013-08-12 18:50:30 -07002128 mGeofenceHardwareImpl.reportGeofenceResumeStatus(geofenceId, getGeofenceStatus(status));
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07002129 }
2130
Danke Xie22d1f9f2009-08-18 18:28:45 -04002131 //=============================================================
2132 // NI Client support
Miguel Torroja1e84da82010-07-27 07:02:24 +02002133 //=============================================================
Danke Xie22d1f9f2009-08-18 18:28:45 -04002134 private final INetInitiatedListener mNetInitiatedListener = new INetInitiatedListener.Stub() {
destradaaef752b62015-04-17 13:10:47 -07002135 // Sends a response for an NI request to HAL.
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002136 @Override
gomo48f1a642017-11-10 20:35:46 -08002137 public boolean sendNiResponse(int notificationId, int userResponse) {
Miguel Torroja1e84da82010-07-27 07:02:24 +02002138 // TODO Add Permission check
Danke Xie22d1f9f2009-08-18 18:28:45 -04002139
gomo48f1a642017-11-10 20:35:46 -08002140 if (DEBUG) {
2141 Log.d(TAG, "sendNiResponse, notifId: " + notificationId +
2142 ", response: " + userResponse);
2143 }
Miguel Torroja1e84da82010-07-27 07:02:24 +02002144 native_send_ni_response(notificationId, userResponse);
2145 return true;
2146 }
Danke Xie22d1f9f2009-08-18 18:28:45 -04002147 };
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002148
Danke Xie22d1f9f2009-08-18 18:28:45 -04002149 public INetInitiatedListener getNetInitiatedListener() {
2150 return mNetInitiatedListener;
2151 }
2152
2153 // Called by JNI function to report an NI request.
Miguel Torroja1e84da82010-07-27 07:02:24 +02002154 public void reportNiNotification(
2155 int notificationId,
2156 int niType,
2157 int notifyFlags,
2158 int timeout,
2159 int defaultResponse,
2160 String requestorId,
2161 String text,
2162 int requestorIdEncoding,
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002163 int textEncoding
gomo48f1a642017-11-10 20:35:46 -08002164 ) {
Miguel Torroja1e84da82010-07-27 07:02:24 +02002165 Log.i(TAG, "reportNiNotification: entered");
2166 Log.i(TAG, "notificationId: " + notificationId +
2167 ", niType: " + niType +
2168 ", notifyFlags: " + notifyFlags +
2169 ", timeout: " + timeout +
2170 ", defaultResponse: " + defaultResponse);
2171
2172 Log.i(TAG, "requestorId: " + requestorId +
2173 ", text: " + text +
2174 ", requestorIdEncoding: " + requestorIdEncoding +
2175 ", textEncoding: " + textEncoding);
2176
2177 GpsNiNotification notification = new GpsNiNotification();
2178
2179 notification.notificationId = notificationId;
2180 notification.niType = niType;
2181 notification.needNotify = (notifyFlags & GpsNetInitiatedHandler.GPS_NI_NEED_NOTIFY) != 0;
2182 notification.needVerify = (notifyFlags & GpsNetInitiatedHandler.GPS_NI_NEED_VERIFY) != 0;
gomo48f1a642017-11-10 20:35:46 -08002183 notification.privacyOverride =
2184 (notifyFlags & GpsNetInitiatedHandler.GPS_NI_PRIVACY_OVERRIDE) != 0;
Miguel Torroja1e84da82010-07-27 07:02:24 +02002185 notification.timeout = timeout;
2186 notification.defaultResponse = defaultResponse;
2187 notification.requestorId = requestorId;
2188 notification.text = text;
2189 notification.requestorIdEncoding = requestorIdEncoding;
2190 notification.textEncoding = textEncoding;
2191
Miguel Torroja1e84da82010-07-27 07:02:24 +02002192 mNIHandler.handleNiNotification(notification);
2193 }
2194
2195 /**
2196 * Called from native code to request set id info.
2197 * We should be careful about receiving null string from the TelephonyManager,
2198 * because sending null String to JNI function would cause a crash.
2199 */
2200
2201 private void requestSetID(int flags) {
2202 TelephonyManager phone = (TelephonyManager)
2203 mContext.getSystemService(Context.TELEPHONY_SERVICE);
destradaaef752b62015-04-17 13:10:47 -07002204 int type = AGPS_SETID_TYPE_NONE;
Miguel Torroja1e84da82010-07-27 07:02:24 +02002205 String data = "";
2206
2207 if ((flags & AGPS_RIL_REQUEST_SETID_IMSI) == AGPS_RIL_REQUEST_SETID_IMSI) {
2208 String data_temp = phone.getSubscriberId();
2209 if (data_temp == null) {
2210 // This means the framework does not have the SIM card ready.
2211 } else {
2212 // This means the framework has the SIM card.
2213 data = data_temp;
2214 type = AGPS_SETID_TYPE_IMSI;
2215 }
gomo48f1a642017-11-10 20:35:46 -08002216 } else if ((flags & AGPS_RIL_REQUEST_SETID_MSISDN) == AGPS_RIL_REQUEST_SETID_MSISDN) {
Miguel Torroja1e84da82010-07-27 07:02:24 +02002217 String data_temp = phone.getLine1Number();
2218 if (data_temp == null) {
2219 // This means the framework does not have the SIM card ready.
2220 } else {
2221 // This means the framework has the SIM card.
2222 data = data_temp;
2223 type = AGPS_SETID_TYPE_MSISDN;
2224 }
2225 }
2226 native_agps_set_id(type, data);
2227 }
2228
2229 /**
Yu-Han Yange7baef32018-02-09 13:58:17 -08002230 * Called from native code to request location info.
2231 */
2232 private void requestLocation(boolean independentFromGnss) {
2233 if (DEBUG) {
2234 Log.d(TAG, "requestLocation. independentFromGnss: " + independentFromGnss);
2235 }
2236 sendMessage(REQUEST_LOCATION, 0, independentFromGnss);
2237 }
2238
2239 /**
Mike Lockwood9b9fb5c2011-06-29 15:09:40 -04002240 * Called from native code to request utc time info
2241 */
Mike Lockwood9b9fb5c2011-06-29 15:09:40 -04002242 private void requestUtcTime() {
destradaae21252a2015-09-08 12:32:59 -07002243 if (DEBUG) Log.d(TAG, "utcTimeRequest");
Mike Lockwood9b9fb5c2011-06-29 15:09:40 -04002244 sendMessage(INJECT_NTP_TIME, 0, null);
2245 }
2246
2247 /**
Miguel Torroja1e84da82010-07-27 07:02:24 +02002248 * Called from native code to request reference location info
2249 */
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002250 private void requestRefLocation() {
Miguel Torroja1e84da82010-07-27 07:02:24 +02002251 TelephonyManager phone = (TelephonyManager)
2252 mContext.getSystemService(Context.TELEPHONY_SERVICE);
Victoria Leased50d0c32012-10-29 13:16:17 -07002253 final int phoneType = phone.getPhoneType();
2254 if (phoneType == TelephonyManager.PHONE_TYPE_GSM) {
Miguel Torroja1e84da82010-07-27 07:02:24 +02002255 GsmCellLocation gsm_cell = (GsmCellLocation) phone.getCellLocation();
Victoria Leased50d0c32012-10-29 13:16:17 -07002256 if ((gsm_cell != null) && (phone.getNetworkOperator() != null)
2257 && (phone.getNetworkOperator().length() > 3)) {
Miguel Torroja1e84da82010-07-27 07:02:24 +02002258 int type;
gomo48f1a642017-11-10 20:35:46 -08002259 int mcc = Integer.parseInt(phone.getNetworkOperator().substring(0, 3));
Miguel Torroja1e84da82010-07-27 07:02:24 +02002260 int mnc = Integer.parseInt(phone.getNetworkOperator().substring(3));
Mike Lockwoodedc0f3872010-10-22 09:16:17 -04002261 int networkType = phone.getNetworkType();
2262 if (networkType == TelephonyManager.NETWORK_TYPE_UMTS
gomo48f1a642017-11-10 20:35:46 -08002263 || networkType == TelephonyManager.NETWORK_TYPE_HSDPA
2264 || networkType == TelephonyManager.NETWORK_TYPE_HSUPA
2265 || networkType == TelephonyManager.NETWORK_TYPE_HSPA
2266 || networkType == TelephonyManager.NETWORK_TYPE_HSPAP) {
Miguel Torroja1e84da82010-07-27 07:02:24 +02002267 type = AGPS_REF_LOCATION_TYPE_UMTS_CELLID;
Mike Lockwoodedc0f3872010-10-22 09:16:17 -04002268 } else {
Miguel Torroja1e84da82010-07-27 07:02:24 +02002269 type = AGPS_REF_LOCATION_TYPE_GSM_CELLID;
Mike Lockwoodedc0f3872010-10-22 09:16:17 -04002270 }
Miguel Torroja1e84da82010-07-27 07:02:24 +02002271 native_agps_set_ref_location_cellid(type, mcc, mnc,
2272 gsm_cell.getLac(), gsm_cell.getCid());
Mike Lockwoodedc0f3872010-10-22 09:16:17 -04002273 } else {
gomo48f1a642017-11-10 20:35:46 -08002274 Log.e(TAG, "Error getting cell location info.");
Mike Lockwoodedc0f3872010-10-22 09:16:17 -04002275 }
Victoria Leased50d0c32012-10-29 13:16:17 -07002276 } else if (phoneType == TelephonyManager.PHONE_TYPE_CDMA) {
2277 Log.e(TAG, "CDMA not supported.");
Mike Lockwoodedc0f3872010-10-22 09:16:17 -04002278 }
Miguel Torroja1e84da82010-07-27 07:02:24 +02002279 }
Danke Xie22d1f9f2009-08-18 18:28:45 -04002280
Mike Lockwood98e48692010-04-07 16:32:51 -04002281 private void sendMessage(int message, int arg, Object obj) {
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002282 // hold a wake lock until this message is delivered
Jeff Brown028872f2012-08-25 13:07:01 -07002283 // note that this assumes the message will not be removed from the queue before
2284 // it is handled (otherwise the wake lock would be leaked).
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002285 mWakeLock.acquire();
Wyatt Rileycf879db2017-01-12 13:57:38 -08002286 if (Log.isLoggable(TAG, Log.INFO)) {
2287 Log.i(TAG, "WakeLock acquired by sendMessage(" + messageIdAsString(message) + ", " + arg
2288 + ", " + obj + ")");
2289 }
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002290 mHandler.obtainMessage(message, arg, 1, obj).sendToTarget();
Mike Lockwood98e48692010-04-07 16:32:51 -04002291 }
2292
Mike Lockwood62a8fc12010-03-22 14:23:26 -04002293 private final class ProviderHandler extends Handler {
Victoria Lease5cd731a2012-12-19 15:04:21 -08002294 public ProviderHandler(Looper looper) {
2295 super(looper, null, true /*async*/);
Jeff Brown028872f2012-08-25 13:07:01 -07002296 }
2297
Mike Lockwood62a8fc12010-03-22 14:23:26 -04002298 @Override
Mike Lockwood4a7b65e2010-10-25 16:35:55 -04002299 public void handleMessage(Message msg) {
Mike Lockwood98e48692010-04-07 16:32:51 -04002300 int message = msg.what;
2301 switch (message) {
Mike Lockwood62a8fc12010-03-22 14:23:26 -04002302 case ENABLE:
2303 if (msg.arg1 == 1) {
2304 handleEnable();
2305 } else {
2306 handleDisable();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002307 }
Mike Lockwood62a8fc12010-03-22 14:23:26 -04002308 break;
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002309 case SET_REQUEST:
2310 GpsRequest gpsRequest = (GpsRequest) msg.obj;
2311 handleSetRequest(gpsRequest.request, gpsRequest.source);
Mike Lockwood03ca2162010-04-01 08:10:09 -07002312 break;
Mike Lockwood62a8fc12010-03-22 14:23:26 -04002313 case UPDATE_NETWORK_STATE:
destradaae21252a2015-09-08 12:32:59 -07002314 handleUpdateNetworkState((Network) msg.obj);
2315 break;
2316 case REQUEST_SUPL_CONNECTION:
2317 handleRequestSuplConnection((InetAddress) msg.obj);
2318 break;
2319 case RELEASE_SUPL_CONNECTION:
2320 handleReleaseSuplConnection(msg.arg1);
Mike Lockwood62a8fc12010-03-22 14:23:26 -04002321 break;
2322 case INJECT_NTP_TIME:
Yu-Han Yanga1862b52018-02-20 17:05:59 -08002323 mNtpTimeHelper.retrieveAndInjectNtpTime();
Mike Lockwood62a8fc12010-03-22 14:23:26 -04002324 break;
Yu-Han Yange7baef32018-02-09 13:58:17 -08002325 case REQUEST_LOCATION:
2326 handleRequestLocation((boolean) msg.obj);
2327 break;
Mike Lockwood62a8fc12010-03-22 14:23:26 -04002328 case DOWNLOAD_XTRA_DATA:
Wyatt Riley0d6e54e22016-10-05 12:03:03 -07002329 handleDownloadXtraData();
Mike Lockwood62a8fc12010-03-22 14:23:26 -04002330 break;
Kevin Tang40e1baf2012-01-10 14:32:44 -08002331 case DOWNLOAD_XTRA_DATA_FINISHED:
2332 mDownloadXtraDataPending = STATE_IDLE;
2333 break;
Mike Lockwood62a8fc12010-03-22 14:23:26 -04002334 case UPDATE_LOCATION:
destradaae21252a2015-09-08 12:32:59 -07002335 handleUpdateLocation((Location) msg.obj);
Mike Lockwood62a8fc12010-03-22 14:23:26 -04002336 break;
destradaafb23c672015-04-16 14:01:27 -07002337 case SUBSCRIPTION_OR_SIM_CHANGED:
2338 subscriptionOrSimChanged(mContext);
2339 break;
2340 case INITIALIZE_HANDLER:
destradaae21252a2015-09-08 12:32:59 -07002341 handleInitialize();
destradaafb23c672015-04-16 14:01:27 -07002342 break;
Wyatt Riley26465d22018-02-12 13:44:24 -08002343 case REPORT_LOCATION:
2344 handleReportLocation(msg.arg1 == 1, (Location) msg.obj);
2345 break;
2346 case REPORT_SV_STATUS:
2347 handleReportSvStatus((SvStatusInfo) msg.obj);
2348 break;
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002349 }
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002350 if (msg.arg2 == 1) {
2351 // wakelock was taken for this message, release it
2352 mWakeLock.release();
Wyatt Rileycf879db2017-01-12 13:57:38 -08002353 if (Log.isLoggable(TAG, Log.INFO)) {
2354 Log.i(TAG, "WakeLock released by handleMessage(" + messageIdAsString(message)
2355 + ", " + msg.arg1 + ", " + msg.obj + ")");
2356 }
Mike Lockwood98e48692010-04-07 16:32:51 -04002357 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002358 }
destradaafb23c672015-04-16 14:01:27 -07002359
2360 /**
Lifu Tang30f95a72016-01-07 23:20:38 -08002361 * This method is bound to {@link #GnssLocationProvider(Context, ILocationManager, Looper)}.
destradaafb23c672015-04-16 14:01:27 -07002362 * It is in charge of loading properties and registering for events that will be posted to
2363 * this handler.
2364 */
destradaae21252a2015-09-08 12:32:59 -07002365 private void handleInitialize() {
Yu-Han Yang6d317352018-03-15 11:53:01 -07002366 native_init_once();
2367
Wyatt Riley523a0cf2017-10-31 14:36:52 -07002368 /*
2369 * A cycle of native_init() and native_cleanup() is needed so that callbacks are
2370 * registered after bootup even when location is disabled.
2371 * This will allow Emergency SUPL to work even when location is disabled before device
2372 * restart.
2373 */
2374 boolean isInitialized = native_init();
gomo48f1a642017-11-10 20:35:46 -08002375 if (!isInitialized) {
Wyatt Riley523a0cf2017-10-31 14:36:52 -07002376 Log.w(TAG, "Native initialization failed at bootup");
2377 } else {
2378 native_cleanup();
2379 }
2380
destradaafb23c672015-04-16 14:01:27 -07002381 // load default GPS configuration
2382 // (this configuration might change in the future based on SIM changes)
2383 reloadGpsProperties(mContext, mProperties);
2384
2385 // TODO: When this object "finishes" we should unregister by invoking
gomo48f1a642017-11-10 20:35:46 -08002386 // SubscriptionManager.getInstance(mContext).unregister
2387 // (mOnSubscriptionsChangedListener);
destradaafb23c672015-04-16 14:01:27 -07002388 // This is not strictly necessary because it will be unregistered if the
2389 // notification fails but it is good form.
2390
2391 // Register for SubscriptionInfo list changes which is guaranteed
2392 // to invoke onSubscriptionsChanged the first time.
2393 SubscriptionManager.from(mContext)
2394 .addOnSubscriptionsChangedListener(mOnSubscriptionsChangedListener);
2395
2396 // listen for events
destradaaef752b62015-04-17 13:10:47 -07002397 IntentFilter intentFilter;
2398 if (native_is_agps_ril_supported()) {
2399 intentFilter = new IntentFilter();
2400 intentFilter.addAction(Intents.DATA_SMS_RECEIVED_ACTION);
2401 intentFilter.addDataScheme("sms");
2402 intentFilter.addDataAuthority("localhost", "7275");
2403 mContext.registerReceiver(mBroadcastReceiver, intentFilter, null, this);
destradaafb23c672015-04-16 14:01:27 -07002404
destradaaef752b62015-04-17 13:10:47 -07002405 intentFilter = new IntentFilter();
2406 intentFilter.addAction(Intents.WAP_PUSH_RECEIVED_ACTION);
2407 try {
2408 intentFilter.addDataType("application/vnd.omaloc-supl-init");
2409 } catch (IntentFilter.MalformedMimeTypeException e) {
2410 Log.w(TAG, "Malformed SUPL init mime type");
2411 }
2412 mContext.registerReceiver(mBroadcastReceiver, intentFilter, null, this);
2413 } else if (DEBUG) {
2414 Log.d(TAG, "Skipped registration for SMS/WAP-PUSH messages because AGPS Ril in GPS"
2415 + " HAL is not supported");
destradaafb23c672015-04-16 14:01:27 -07002416 }
destradaafb23c672015-04-16 14:01:27 -07002417
2418 intentFilter = new IntentFilter();
2419 intentFilter.addAction(ALARM_WAKEUP);
2420 intentFilter.addAction(ALARM_TIMEOUT);
destradaafb23c672015-04-16 14:01:27 -07002421 intentFilter.addAction(PowerManager.ACTION_POWER_SAVE_MODE_CHANGED);
Adam Lesinski87c17df2015-05-27 13:24:13 -07002422 intentFilter.addAction(PowerManager.ACTION_DEVICE_IDLE_MODE_CHANGED);
destradaafb23c672015-04-16 14:01:27 -07002423 intentFilter.addAction(Intent.ACTION_SCREEN_OFF);
2424 intentFilter.addAction(Intent.ACTION_SCREEN_ON);
2425 intentFilter.addAction(SIM_STATE_CHANGED);
2426 mContext.registerReceiver(mBroadcastReceiver, intentFilter, null, this);
2427
destradaae21252a2015-09-08 12:32:59 -07002428 // register for connectivity change events, this is equivalent to the deprecated way of
2429 // registering for CONNECTIVITY_ACTION broadcasts
2430 NetworkRequest.Builder networkRequestBuilder = new NetworkRequest.Builder();
Jeff Sharkeyc159d522018-03-28 10:54:07 -06002431 networkRequestBuilder.addCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET);
2432 networkRequestBuilder.addCapability(NetworkCapabilities.NET_CAPABILITY_VALIDATED);
2433 networkRequestBuilder.removeCapability(NetworkCapabilities.NET_CAPABILITY_NOT_VPN);
destradaae21252a2015-09-08 12:32:59 -07002434 NetworkRequest networkRequest = networkRequestBuilder.build();
2435 mConnMgr.registerNetworkCallback(networkRequest, mNetworkConnectivityCallback);
2436
destradaafb23c672015-04-16 14:01:27 -07002437 // listen for PASSIVE_PROVIDER updates
2438 LocationManager locManager =
2439 (LocationManager) mContext.getSystemService(Context.LOCATION_SERVICE);
2440 long minTime = 0;
2441 float minDistance = 0;
2442 boolean oneShot = false;
2443 LocationRequest request = LocationRequest.createFromDeprecatedProvider(
2444 LocationManager.PASSIVE_PROVIDER,
2445 minTime,
2446 minDistance,
2447 oneShot);
2448 // Don't keep track of this request since it's done on behalf of other clients
2449 // (which are kept track of separately).
2450 request.setHideFromAppOps(true);
2451 locManager.requestLocationUpdates(
2452 request,
2453 new NetworkLocationListener(),
2454 getLooper());
2455 }
2456 }
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002457
Yu-Han Yange7baef32018-02-09 13:58:17 -08002458 private abstract class LocationChangeListener implements LocationListener {
Yu-Han Yang07561382018-02-21 13:08:37 -08002459 int numLocationUpdateRequest;
2460
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002461 @Override
gomo48f1a642017-11-10 20:35:46 -08002462 public void onStatusChanged(String provider, int status, Bundle extras) {
2463 }
2464
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002465 @Override
gomo48f1a642017-11-10 20:35:46 -08002466 public void onProviderEnabled(String provider) {
2467 }
2468
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002469 @Override
gomo48f1a642017-11-10 20:35:46 -08002470 public void onProviderDisabled(String provider) {
2471 }
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002472 }
2473
Yu-Han Yange7baef32018-02-09 13:58:17 -08002474 private final class NetworkLocationListener extends LocationChangeListener {
2475 @Override
2476 public void onLocationChanged(Location location) {
2477 // this callback happens on mHandler looper
2478 if (LocationManager.NETWORK_PROVIDER.equals(location.getProvider())) {
2479 handleUpdateLocation(location);
2480 }
2481 }
2482 }
2483
2484 private final class FusedLocationListener extends LocationChangeListener {
2485 @Override
2486 public void onLocationChanged(Location location) {
2487 if (LocationManager.FUSED_PROVIDER.equals(location.getProvider())) {
Yu-Han Yange7baef32018-02-09 13:58:17 -08002488 injectBestLocation(location);
2489 }
2490 }
2491 }
2492
Kevin Tanga5fe6b22011-06-05 14:25:16 -07002493 private String getSelectedApn() {
2494 Uri uri = Uri.parse("content://telephony/carriers/preferapn");
destradaa96a14702014-06-05 11:36:30 -07002495 Cursor cursor = null;
2496 try {
2497 cursor = mContext.getContentResolver().query(
2498 uri,
gomo48f1a642017-11-10 20:35:46 -08002499 new String[]{"apn"},
destradaa96a14702014-06-05 11:36:30 -07002500 null /* selection */,
2501 null /* selectionArgs */,
2502 Carriers.DEFAULT_SORT_ORDER);
2503 if (cursor != null && cursor.moveToFirst()) {
2504 return cursor.getString(0);
2505 } else {
2506 Log.e(TAG, "No APN found to select.");
2507 }
2508 } catch (Exception e) {
destradaaea8a8a62014-06-23 18:19:03 -07002509 Log.e(TAG, "Error encountered on selecting the APN.", e);
destradaa96a14702014-06-05 11:36:30 -07002510 } finally {
2511 if (cursor != null) {
Kevin Tanga5fe6b22011-06-05 14:25:16 -07002512 cursor.close();
2513 }
2514 }
destradaa96a14702014-06-05 11:36:30 -07002515
2516 return null;
2517 }
2518
2519 private int getApnIpType(String apn) {
destradaae21252a2015-09-08 12:32:59 -07002520 ensureInHandlerThread();
destradaa96a14702014-06-05 11:36:30 -07002521 if (apn == null) {
2522 return APN_INVALID;
2523 }
2524
destradaa96a14702014-06-05 11:36:30 -07002525 String selection = String.format("current = 1 and apn = '%s' and carrier_enabled = 1", apn);
2526 Cursor cursor = null;
2527 try {
2528 cursor = mContext.getContentResolver().query(
2529 Carriers.CONTENT_URI,
gomo48f1a642017-11-10 20:35:46 -08002530 new String[]{Carriers.PROTOCOL},
destradaa96a14702014-06-05 11:36:30 -07002531 selection,
2532 null,
2533 Carriers.DEFAULT_SORT_ORDER);
2534
2535 if (null != cursor && cursor.moveToFirst()) {
2536 return translateToApnIpType(cursor.getString(0), apn);
2537 } else {
2538 Log.e(TAG, "No entry found in query for APN: " + apn);
2539 }
2540 } catch (Exception e) {
2541 Log.e(TAG, "Error encountered on APN query for: " + apn, e);
2542 } finally {
2543 if (cursor != null) {
2544 cursor.close();
2545 }
2546 }
2547
2548 return APN_INVALID;
2549 }
2550
2551 private int translateToApnIpType(String ipProtocol, String apn) {
2552 if ("IP".equals(ipProtocol)) {
2553 return APN_IPV4;
2554 }
2555 if ("IPV6".equals(ipProtocol)) {
2556 return APN_IPV6;
2557 }
2558 if ("IPV4V6".equals(ipProtocol)) {
2559 return APN_IPV4V6;
2560 }
2561
2562 // we hit the default case so the ipProtocol is not recognized
2563 String message = String.format("Unknown IP Protocol: %s, for APN: %s", ipProtocol, apn);
2564 Log.e(TAG, message);
2565 return APN_INVALID;
2566 }
2567
2568 private void setRouting() {
2569 if (mAGpsDataConnectionIpAddr == null) {
2570 return;
2571 }
2572
destradaae21252a2015-09-08 12:32:59 -07002573 // TODO: replace the use of this deprecated API
destradaa96a14702014-06-05 11:36:30 -07002574 boolean result = mConnMgr.requestRouteToHostAddress(
2575 ConnectivityManager.TYPE_MOBILE_SUPL,
2576 mAGpsDataConnectionIpAddr);
2577
2578 if (!result) {
2579 Log.e(TAG, "Error requesting route to host: " + mAGpsDataConnectionIpAddr);
2580 } else if (DEBUG) {
2581 Log.d(TAG, "Successfully requested route to host: " + mAGpsDataConnectionIpAddr);
2582 }
Kevin Tanga5fe6b22011-06-05 14:25:16 -07002583 }
2584
destradaae21252a2015-09-08 12:32:59 -07002585 /**
2586 * @return {@code true} if there is a data network available for outgoing connections,
gomo48f1a642017-11-10 20:35:46 -08002587 * {@code false} otherwise.
destradaae21252a2015-09-08 12:32:59 -07002588 */
2589 private boolean isDataNetworkConnected() {
2590 NetworkInfo activeNetworkInfo = mConnMgr.getActiveNetworkInfo();
2591 return activeNetworkInfo != null && activeNetworkInfo.isConnected();
2592 }
2593
2594 /**
2595 * Ensures the calling function is running in the thread associated with {@link #mHandler}.
2596 */
2597 private void ensureInHandlerThread() {
2598 if (mHandler != null && Looper.myLooper() == mHandler.getLooper()) {
2599 return;
2600 }
2601 throw new RuntimeException("This method must run on the Handler thread.");
2602 }
2603
2604 /**
2605 * @return A string representing the current state stored in {@link #mAGpsDataConnectionState}.
2606 */
2607 private String agpsDataConnStateAsString() {
gomo48f1a642017-11-10 20:35:46 -08002608 switch (mAGpsDataConnectionState) {
destradaae21252a2015-09-08 12:32:59 -07002609 case AGPS_DATA_CONNECTION_CLOSED:
2610 return "CLOSED";
2611 case AGPS_DATA_CONNECTION_OPEN:
2612 return "OPEN";
2613 case AGPS_DATA_CONNECTION_OPENING:
2614 return "OPENING";
2615 default:
2616 return "<Unknown>";
2617 }
2618 }
2619
2620 /**
2621 * @return A string representing the given GPS_AGPS_DATA status.
2622 */
2623 private String agpsDataConnStatusAsString(int agpsDataConnStatus) {
2624 switch (agpsDataConnStatus) {
2625 case GPS_AGPS_DATA_CONNECTED:
2626 return "CONNECTED";
2627 case GPS_AGPS_DATA_CONN_DONE:
2628 return "DONE";
2629 case GPS_AGPS_DATA_CONN_FAILED:
2630 return "FAILED";
2631 case GPS_RELEASE_AGPS_DATA_CONN:
2632 return "RELEASE";
2633 case GPS_REQUEST_AGPS_DATA_CONN:
2634 return "REQUEST";
2635 default:
2636 return "<Unknown>";
2637 }
2638 }
2639
Wyatt Rileycf879db2017-01-12 13:57:38 -08002640 /**
2641 * @return A string representing the given message ID.
2642 */
2643 private String messageIdAsString(int message) {
2644 switch (message) {
2645 case ENABLE:
2646 return "ENABLE";
2647 case SET_REQUEST:
2648 return "SET_REQUEST";
2649 case UPDATE_NETWORK_STATE:
2650 return "UPDATE_NETWORK_STATE";
2651 case REQUEST_SUPL_CONNECTION:
2652 return "REQUEST_SUPL_CONNECTION";
2653 case RELEASE_SUPL_CONNECTION:
2654 return "RELEASE_SUPL_CONNECTION";
2655 case INJECT_NTP_TIME:
2656 return "INJECT_NTP_TIME";
Yu-Han Yange7baef32018-02-09 13:58:17 -08002657 case REQUEST_LOCATION:
2658 return "REQUEST_LOCATION";
Wyatt Rileycf879db2017-01-12 13:57:38 -08002659 case DOWNLOAD_XTRA_DATA:
2660 return "DOWNLOAD_XTRA_DATA";
Wyatt Rileycf879db2017-01-12 13:57:38 -08002661 case DOWNLOAD_XTRA_DATA_FINISHED:
2662 return "DOWNLOAD_XTRA_DATA_FINISHED";
2663 case UPDATE_LOCATION:
2664 return "UPDATE_LOCATION";
2665 case SUBSCRIPTION_OR_SIM_CHANGED:
2666 return "SUBSCRIPTION_OR_SIM_CHANGED";
2667 case INITIALIZE_HANDLER:
2668 return "INITIALIZE_HANDLER";
Wyatt Riley26465d22018-02-12 13:44:24 -08002669 case REPORT_LOCATION:
2670 return "REPORT_LOCATION";
2671 case REPORT_SV_STATUS:
2672 return "REPORT_SV_STATUS";
Wyatt Rileycf879db2017-01-12 13:57:38 -08002673 default:
2674 return "<Unknown>";
2675 }
2676 }
2677
Siddharth Raybb608c82017-03-16 11:33:34 -07002678
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002679 @Override
2680 public void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2681 StringBuilder s = new StringBuilder();
Wyatt Riley77ca4f82017-06-30 18:13:44 -07002682 s.append(" mStarted=").append(mStarted).append('\n');
destradaa25e8caf2015-08-24 14:14:44 -07002683 s.append(" mFixInterval=").append(mFixInterval).append('\n');
gomo48f1a642017-11-10 20:35:46 -08002684 s.append(" mLowPowerMode=").append(mLowPowerMode).append('\n');
Wyatt Riley74479bd2018-01-17 08:48:27 -08002685 s.append(" mGnssMeasurementsProvider.isRegistered()=")
2686 .append(mGnssMeasurementsProvider.isRegistered()).append('\n');
2687 s.append(" mGnssNavigationMessageProvider.isRegistered()=")
2688 .append(mGnssNavigationMessageProvider.isRegistered()).append('\n');
destradaa25e8caf2015-08-24 14:14:44 -07002689 s.append(" mDisableGps (battery saver mode)=").append(mDisableGps).append('\n');
2690 s.append(" mEngineCapabilities=0x").append(Integer.toHexString(mEngineCapabilities));
2691 s.append(" ( ");
2692 if (hasCapability(GPS_CAPABILITY_SCHEDULING)) s.append("SCHEDULING ");
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002693 if (hasCapability(GPS_CAPABILITY_MSB)) s.append("MSB ");
2694 if (hasCapability(GPS_CAPABILITY_MSA)) s.append("MSA ");
2695 if (hasCapability(GPS_CAPABILITY_SINGLE_SHOT)) s.append("SINGLE_SHOT ");
2696 if (hasCapability(GPS_CAPABILITY_ON_DEMAND_TIME)) s.append("ON_DEMAND_TIME ");
destradaa25e8caf2015-08-24 14:14:44 -07002697 if (hasCapability(GPS_CAPABILITY_GEOFENCING)) s.append("GEOFENCING ");
2698 if (hasCapability(GPS_CAPABILITY_MEASUREMENTS)) s.append("MEASUREMENTS ");
2699 if (hasCapability(GPS_CAPABILITY_NAV_MESSAGES)) s.append("NAV_MESSAGES ");
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002700 s.append(")\n");
Siddharth Raybb608c82017-03-16 11:33:34 -07002701 s.append(mGnssMetrics.dumpGnssMetricsAsText());
2702 s.append(" native internal state: ").append(native_get_internal_state());
Wyatt Rileycf879db2017-01-12 13:57:38 -08002703 s.append("\n");
Nick Pelly6fa9ad42012-07-16 12:18:23 -07002704 pw.append(s);
2705 }
2706
Mike Lockwoodb16e7802009-08-06 09:26:02 -04002707 // preallocated to avoid memory allocation in reportNmea()
2708 private byte[] mNmeaBuffer = new byte[120];
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002709
gomo48f1a642017-11-10 20:35:46 -08002710 static {
2711 class_init_native();
2712 }
2713
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002714 private static native void class_init_native();
gomo48f1a642017-11-10 20:35:46 -08002715
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002716 private static native boolean native_is_supported();
gomo48f1a642017-11-10 20:35:46 -08002717
destradaaef752b62015-04-17 13:10:47 -07002718 private static native boolean native_is_agps_ril_supported();
gomo48f1a642017-11-10 20:35:46 -08002719
destradaaef752b62015-04-17 13:10:47 -07002720 private static native boolean native_is_gnss_configuration_supported();
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002721
Yu-Han Yang6d317352018-03-15 11:53:01 -07002722 private static native void native_init_once();
2723
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002724 private native boolean native_init();
gomo48f1a642017-11-10 20:35:46 -08002725
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002726 private native void native_cleanup();
gomo48f1a642017-11-10 20:35:46 -08002727
Mike Lockwood04598b62010-04-14 17:17:24 -04002728 private native boolean native_set_position_mode(int mode, int recurrence, int min_interval,
gomo48f1a642017-11-10 20:35:46 -08002729 int preferred_accuracy, int preferred_time, boolean lowPowerMode);
2730
Mike Lockwood04598b62010-04-14 17:17:24 -04002731 private native boolean native_start();
gomo48f1a642017-11-10 20:35:46 -08002732
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002733 private native boolean native_stop();
gomo48f1a642017-11-10 20:35:46 -08002734
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002735 private native void native_delete_aiding_data(int flags);
gomo48f1a642017-11-10 20:35:46 -08002736
Mike Lockwoodf602d362010-06-20 14:28:16 -07002737 private native int native_read_nmea(byte[] buffer, int bufferSize);
gomo48f1a642017-11-10 20:35:46 -08002738
Yu-Han Yange7baef32018-02-09 13:58:17 -08002739 private native void native_inject_best_location(
2740 int gnssLocationFlags,
2741 double latitudeDegrees,
2742 double longitudeDegrees,
2743 double altitudeMeters,
2744 float speedMetersPerSec,
2745 float bearingDegrees,
2746 float horizontalAccuracyMeters,
2747 float verticalAccuracyMeters,
2748 float speedAccuracyMetersPerSecond,
2749 float bearingAccuracyDegrees,
2750 long timestamp);
2751
Mike Lockwoodd26ce0d2009-06-11 12:25:46 -04002752 private native void native_inject_location(double latitude, double longitude, float accuracy);
2753
Fred Fettinger3c8fbdf2010-01-04 15:38:13 -06002754 // XTRA Support
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002755 private native void native_inject_time(long time, long timeReference, int uncertainty);
gomo48f1a642017-11-10 20:35:46 -08002756
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002757 private native boolean native_supports_xtra();
gomo48f1a642017-11-10 20:35:46 -08002758
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002759 private native void native_inject_xtra_data(byte[] data, int length);
The Android Open Source Project10592532009-03-18 17:39:46 -07002760
Fred Fettinger3c8fbdf2010-01-04 15:38:13 -06002761 // DEBUG Support
2762 private native String native_get_internal_state();
2763
2764 // AGPS Support
destradaa96a14702014-06-05 11:36:30 -07002765 private native void native_agps_data_conn_open(String apn, int apnIpType);
gomo48f1a642017-11-10 20:35:46 -08002766
Mike Lockwoode3635c92009-05-11 08:38:02 -04002767 private native void native_agps_data_conn_closed();
gomo48f1a642017-11-10 20:35:46 -08002768
Mike Lockwoode3635c92009-05-11 08:38:02 -04002769 private native void native_agps_data_conn_failed();
gomo48f1a642017-11-10 20:35:46 -08002770
2771 private native void native_agps_ni_message(byte[] msg, int length);
2772
Mike Lockwooda9e54612009-06-19 14:54:42 -04002773 private native void native_set_agps_server(int type, String hostname, int port);
Danke Xie22d1f9f2009-08-18 18:28:45 -04002774
2775 // Network-initiated (NI) Support
2776 private native void native_send_ni_response(int notificationId, int userResponse);
Miguel Torroja1e84da82010-07-27 07:02:24 +02002777
2778 // AGPS ril suport
2779 private native void native_agps_set_ref_location_cellid(int type, int mcc, int mnc,
2780 int lac, int cid);
gomo48f1a642017-11-10 20:35:46 -08002781
Miguel Torroja1e84da82010-07-27 07:02:24 +02002782 private native void native_agps_set_id(int type, String setid);
Mike Lockwood50130bb2010-10-11 06:22:50 -04002783
2784 private native void native_update_network_state(boolean connected, int type,
Kevin Tanga5fe6b22011-06-05 14:25:16 -07002785 boolean roaming, boolean available, String extraInfo, String defaultAPN);
Jaikumar Ganesh8ce470d2013-04-03 12:22:18 -07002786
Tsuwei Chen52617bb2014-08-25 11:49:11 -07002787 // GNSS Configuration
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002788 private static native boolean native_set_supl_version(int version);
gomo48f1a642017-11-10 20:35:46 -08002789
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002790 private static native boolean native_set_supl_mode(int mode);
gomo48f1a642017-11-10 20:35:46 -08002791
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002792 private static native boolean native_set_supl_es(int es);
gomo48f1a642017-11-10 20:35:46 -08002793
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002794 private static native boolean native_set_lpp_profile(int lppProfile);
gomo48f1a642017-11-10 20:35:46 -08002795
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002796 private static native boolean native_set_gnss_pos_protocol_select(int gnssPosProtocolSelect);
gomo48f1a642017-11-10 20:35:46 -08002797
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002798 private static native boolean native_set_gps_lock(int gpsLock);
gomo48f1a642017-11-10 20:35:46 -08002799
Hridya Valsaraju2ea29602016-09-13 08:38:09 -07002800 private static native boolean native_set_emergency_supl_pdn(int emergencySuplPdn);
2801
Yu-Han Yang66c7ea92018-03-11 17:17:15 -07002802 private static native boolean native_set_satellite_blacklist(int[] constellations, int[] svIds);
The Android Open Source Project9066cfe2009-03-03 19:31:44 -08002803}
Yu-Han Yanga1862b52018-02-20 17:05:59 -08002804