GpsLocationProvider.java revision 4e50b78bda9cd58be61581d2886c88ff6348a1c1
19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License. 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage com.android.internal.location; 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 19105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Projectimport android.content.BroadcastReceiver; 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Context; 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Intent; 22105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Projectimport android.content.IntentFilter; 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.location.Criteria; 249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.location.IGpsStatusListener; 254e50b78bda9cd58be61581d2886c88ff6348a1c1Mike Lockwoodimport android.location.ILocationManager; 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.location.Location; 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.location.LocationManager; 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.location.LocationProvider; 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.location.LocationProviderImpl; 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.net.SntpClient; 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Bundle; 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.IBinder; 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.RemoteException; 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.SystemClock; 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Config; 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Log; 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 38105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Projectimport com.android.internal.telephony.Phone; 39105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Projectimport com.android.internal.telephony.TelephonyIntents; 40105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.File; 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.FileInputStream; 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.IOException; 44105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Projectimport java.net.InetAddress; 45105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Projectimport java.net.UnknownHostException; 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.ArrayList; 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.Properties; 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * A GPS implementation of LocationProvider used by LocationManager. 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@hide} 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpublic class GpsLocationProvider extends LocationProviderImpl { 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final String TAG = "GpsLocationProvider"; 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Broadcast intent action indicating that the GPS has either been 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * enabled or disabled. An intent extra provides this state as a boolean, 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * where {@code true} means enabled. 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #EXTRA_ENABLED 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@hide} 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final String GPS_ENABLED_CHANGE_ACTION = 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "android.location.GPS_ENABLED_CHANGE"; 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Broadcast intent action indicating that the GPS has either started or 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * stopped receiving GPS fixes. An intent extra provides this state as a 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * boolean, where {@code true} means that the GPS is actively receiving fixes. 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #EXTRA_ENABLED 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@hide} 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final String GPS_FIX_CHANGE_ACTION = 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "android.location.GPS_FIX_CHANGE"; 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The lookup key for a boolean that indicates whether GPS is enabled or 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * disabled. {@code true} means GPS is enabled. Retrieve it with 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link android.content.Intent#getBooleanExtra(String,boolean)}. 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@hide} 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final String EXTRA_ENABLED = "enabled"; 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 89105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project // these need to match GpsPositionMode enum in gps.h 90105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project private static final int GPS_POSITION_MODE_STANDALONE = 0; 91105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project private static final int GPS_POSITION_MODE_MS_BASED = 1; 92105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project private static final int GPS_POSITION_MODE_MS_ASSISTED = 2; 93105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // these need to match GpsStatusValue defines in gps.h 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_STATUS_NONE = 0; 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_STATUS_SESSION_BEGIN = 1; 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_STATUS_SESSION_END = 2; 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_STATUS_ENGINE_ON = 3; 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_STATUS_ENGINE_OFF = 4; 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // these need to match GpsLocationFlags enum in gps.h 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int LOCATION_INVALID = 0; 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int LOCATION_HAS_LAT_LONG = 1; 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int LOCATION_HAS_ALTITUDE = 2; 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int LOCATION_HAS_SPEED = 4; 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int LOCATION_HAS_BEARING = 8; 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int LOCATION_HAS_ACCURACY = 16; 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// IMPORTANT - the GPS_DELETE_* symbols here must match constants in GpsLocationProvider.java 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_DELETE_EPHEMERIS = 0x0001; 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_DELETE_ALMANAC = 0x0002; 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_DELETE_POSITION = 0x0004; 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_DELETE_TIME = 0x0008; 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_DELETE_IONO = 0x0010; 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_DELETE_UTC = 0x0020; 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_DELETE_HEALTH = 0x0040; 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_DELETE_SVDIR = 0x0080; 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_DELETE_SVSTEER = 0x0100; 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_DELETE_SADATA = 0x0200; 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_DELETE_RTI = 0x0400; 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_DELETE_CELLDB_INFO = 0x8000; 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_DELETE_ALL = 0xFFFF; 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final String PROPERTIES_FILE = "/etc/gps.conf"; 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mLocationFlags = LOCATION_INVALID; 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // current status 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mStatus = TEMPORARILY_UNAVAILABLE; 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // time for last status update 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private long mStatusUpdateTime = SystemClock.elapsedRealtime(); 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // turn off GPS fix icon if we haven't received a fix in 10 seconds 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final long RECENT_FIX_TIMEOUT = 10 * 1000; 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // true if we are enabled 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mEnabled; 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // true if we are enabled for location updates 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mLocationTracking; 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // true if we have network connectivity 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mNetworkAvailable; 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // true if GPS is navigating 1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mNavigating; 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // requested frequency of fixes, in seconds 1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mFixInterval = 1; 1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 151105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project private int mPositionMode = GPS_POSITION_MODE_STANDALONE; 152105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // true if we started navigation 1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mStarted; 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // for calculating time to first fix 1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private long mFixRequestTime = 0; 1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // time to first fix for most recent session 1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mTTFF = 0; 1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // time we received our last fix 1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private long mLastFixTime; 1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // properties loaded from PROPERTIES_FILE 1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Properties mProperties; 1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private String mNtpServer; 1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Context mContext; 1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Location mLocation = new Location(LocationManager.GPS_PROVIDER); 1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Bundle mLocationExtras = new Bundle(); 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private ArrayList<Listener> mListeners = new ArrayList<Listener>(); 1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private GpsEventThread mEventThread; 1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private GpsNetworkThread mNetworkThread; 1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Object mNetworkThreadLock = new Object(); 174105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project 175105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project private String mSuplHost; 176105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project private int mSuplPort; 177105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project private boolean mSetSuplServer; 178105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project 1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // how often to request NTP time, in milliseconds 1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // current setting 4 hours 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final long NTP_INTERVAL = 4*60*60*1000; 1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // how long to wait if we have a network error in NTP or XTRA downloading 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // current setting - 5 minutes 1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final long RETRY_INTERVAL = 5*60*1000; 1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private ILocationCollector mCollector; 1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 188105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project private class TelephonyBroadcastReceiver extends BroadcastReceiver { 189105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project @Override public void onReceive(Context context, Intent intent) { 190105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project String action = intent.getAction(); 191105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project 192105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project if (action.equals(TelephonyIntents.ACTION_ANY_DATA_CONNECTION_STATE_CHANGED)) { 193105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project String state = intent.getStringExtra(Phone.STATE_KEY); 194105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project String apnName = intent.getStringExtra(Phone.DATA_APN_KEY); 195105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project String reason = intent.getStringExtra(Phone.STATE_CHANGE_REASON_KEY); 196105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project 197105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project if (Config.LOGD) { 198105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project Log.d(TAG, "state: " + state + " apnName: " + apnName + " reason: " + reason); 199105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project } 200105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project if ("CONNECTED".equals(state)) { 201105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project native_set_supl_apn(apnName); 202105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project } else { 203105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project native_set_supl_apn(""); 204105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project } 205105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project } 206105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project } 207105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project } 208105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project 2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static boolean isSupported() { 2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return native_is_supported(); 2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2134e50b78bda9cd58be61581d2886c88ff6348a1c1Mike Lockwood public GpsLocationProvider(Context context, ILocationManager locationManager) { 2144e50b78bda9cd58be61581d2886c88ff6348a1c1Mike Lockwood super(LocationManager.GPS_PROVIDER, locationManager); 2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContext = context; 2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 217105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project TelephonyBroadcastReceiver receiver = new TelephonyBroadcastReceiver(); 218105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project IntentFilter intentFilter = new IntentFilter(); 219105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project intentFilter.addAction(TelephonyIntents.ACTION_ANY_DATA_CONNECTION_STATE_CHANGED); 220105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project context.registerReceiver(receiver, intentFilter); 221105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project 2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mProperties = new Properties(); 2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project File file = new File(PROPERTIES_FILE); 2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project FileInputStream stream = new FileInputStream(file); 2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mProperties.load(stream); 2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project stream.close(); 2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNtpServer = mProperties.getProperty("NTP_SERVER", null); 229105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project mSuplHost = mProperties.getProperty("SUPL_HOST"); 230105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project String suplPortString = mProperties.getProperty("SUPL_PORT"); 231105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project if (mSuplHost != null && suplPortString != null) { 232105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project try { 233105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project mSuplPort = Integer.parseInt(suplPortString); 234105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project mSetSuplServer = true; 235105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project } catch (NumberFormatException e) { 236105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project Log.e(TAG, "unable to parse SUPL_PORT: " + suplPortString); 237105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project } 238105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project } 2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (IOException e) { 2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.w(TAG, "Could not open GPS configuration file " + PROPERTIES_FILE); 2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setLocationCollector(ILocationCollector collector) { 2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCollector = collector; 2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns true if the provider requires access to a 2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * data network (e.g., the Internet), false otherwise. 2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean requiresNetwork() { 2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // We want updateNetworkState() to get called when the network state changes 2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // for XTRA and NTP time injection support. 256105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project return (mNtpServer != null || native_supports_xtra() || mSuplHost != null); 2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void updateNetworkState(int state) { 2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNetworkAvailable = (state == LocationProvider.AVAILABLE); 2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Config.LOGD) { 2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.d(TAG, "updateNetworkState " + (mNetworkAvailable ? "available" : "unavailable")); 2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mNetworkAvailable && mNetworkThread != null && mEnabled) { 2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // signal the network thread when the network becomes available 2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNetworkThread.signal(); 2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns true if the provider requires access to a 2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * satellite-based positioning system (e.g., GPS), false 2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * otherwise. 2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean requiresSatellite() { 2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns true if the provider requires access to an appropriate 2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * cellular network (e.g., to make use of cell tower IDs), false 2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * otherwise. 2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean requiresCell() { 2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns true if the use of this provider may result in a 2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * monetary charge to the user, false if use is free. It is up to 2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * each provider to give accurate information. 2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean hasMonetaryCost() { 2999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns true if the provider is able to provide altitude 3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * information, false otherwise. A provider that reports altitude 3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * under most circumstances but may occassionally not report it 3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * should return true. 3079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean supportsAltitude() { 3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns true if the provider is able to provide speed 3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * information, false otherwise. A provider that reports speed 3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * under most circumstances but may occassionally not report it 3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * should return true. 3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean supportsSpeed() { 3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns true if the provider is able to provide bearing 3269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * information, false otherwise. A provider that reports bearing 3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * under most circumstances but may occassionally not report it 3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * should return true. 3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean supportsBearing() { 3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns the power requirement for this provider. 3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the power requirement for this provider, as one of the 3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * constants Criteria.POWER_REQUIREMENT_*. 3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getPowerRequirement() { 3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return Criteria.POWER_HIGH; 3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns the horizontal accuracy of this provider 3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the accuracy of location from this provider, as one 3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * of the constants Criteria.ACCURACY_*. 3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getAccuracy() { 3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return Criteria.ACCURACY_FINE; 3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Enables this provider. When enabled, calls to getStatus() 3594e50b78bda9cd58be61581d2886c88ff6348a1c1Mike Lockwood * must be handled. Hardware may be started up 3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * when the provider is enabled. 3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public synchronized void enable() { 3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Config.LOGD) Log.d(TAG, "enable"); 3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mEnabled) return; 3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEnabled = native_init(); 3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mEnabled) { 3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // run event listener thread while we are enabled 3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEventThread = new GpsEventThread(); 3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEventThread.start(); 3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (requiresNetwork()) { 3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // run network thread for NTP and XTRA support 3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mNetworkThread == null) { 3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNetworkThread = new GpsNetworkThread(); 3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNetworkThread.start(); 3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNetworkThread.signal(); 3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.w(TAG, "Failed to enable location provider"); 3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Disables this provider. When disabled, calls to getStatus() 3894e50b78bda9cd58be61581d2886c88ff6348a1c1Mike Lockwood * need not be handled. Hardware may be shut 3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * down while the provider is disabled. 3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public synchronized void disable() { 3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Config.LOGD) Log.d(TAG, "disable"); 3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mEnabled) return; 3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEnabled = false; 3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project stopNavigating(); 3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project native_disable(); 4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // make sure our event thread exits 4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mEventThread != null) { 4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEventThread.join(); 4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (InterruptedException e) { 4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.w(TAG, "InterruptedException when joining mEventThread"); 4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEventThread = null; 4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mNetworkThread != null) { 4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNetworkThread.setDone(); 4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNetworkThread = null; 4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 416d654f9f727b415b153c7190832db4b65f6943f32Mike Lockwood // The GpsEventThread does not wait for the GPS to shutdown 417d654f9f727b415b153c7190832db4b65f6943f32Mike Lockwood // so we need to report the GPS_STATUS_ENGINE_OFF event here 418d654f9f727b415b153c7190832db4b65f6943f32Mike Lockwood if (mNavigating) { 419d654f9f727b415b153c7190832db4b65f6943f32Mike Lockwood reportStatus(GPS_STATUS_ENGINE_OFF); 420d654f9f727b415b153c7190832db4b65f6943f32Mike Lockwood } 421d654f9f727b415b153c7190832db4b65f6943f32Mike Lockwood 4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project native_cleanup(); 4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean isEnabled() { 4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mEnabled; 4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getStatus(Bundle extras) { 4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras != null) { 4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project extras.putInt("satellites", mSvCount); 4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mStatus; 4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void updateStatus(int status, int svCount) { 4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (status != mStatus || svCount != mSvCount) { 4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStatus = status; 4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSvCount = svCount; 4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocationExtras.putInt("satellites", svCount); 4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStatusUpdateTime = SystemClock.elapsedRealtime(); 4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public long getStatusUpdateTime() { 4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mStatusUpdateTime; 4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void enableLocationTracking(boolean enable) { 4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mLocationTracking == enable) { 4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (enable) { 4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFixRequestTime = System.currentTimeMillis(); 4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTTFF = 0; 4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLastFixTime = 0; 4629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project startNavigating(); 4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project stopNavigating(); 4659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocationTracking = enable; 4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean isLocationTracking() { 4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mLocationTracking; 4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setMinTime(long minTime) { 4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super.setMinTime(minTime); 4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Config.LOGD) Log.d(TAG, "setMinTime " + minTime); 4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (minTime >= 0) { 4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int interval = (int)(minTime/1000); 4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (interval < 1) { 4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project interval = 1; 4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFixInterval = interval; 4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project native_set_fix_frequency(mFixInterval); 4869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final class Listener implements IBinder.DeathRecipient { 4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final IGpsStatusListener mListener; 4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int mSensors = 0; 4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Listener(IGpsStatusListener listener) { 4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mListener = listener; 4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void binderDied() { 4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Config.LOGD) Log.d(TAG, "GPS status listener died"); 5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized(mListeners) { 5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mListeners.remove(this); 5039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void addGpsStatusListener(IGpsStatusListener listener) throws RemoteException { 5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (listener == null) throw new NullPointerException("listener is null in addGpsStatusListener"); 5099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized(mListeners) { 5119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project IBinder binder = listener.asBinder(); 5129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int size = mListeners.size(); 5139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < size; i++) { 5149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Listener test = mListeners.get(i); 5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (binder.equals(test.mListener.asBinder())) { 5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // listener already added 5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return; 5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Listener l = new Listener(listener); 5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project binder.linkToDeath(l, 0); 5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mListeners.add(l); 5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void removeGpsStatusListener(IGpsStatusListener listener) { 5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (listener == null) throw new NullPointerException("listener is null in addGpsStatusListener"); 5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized(mListeners) { 5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project IBinder binder = listener.asBinder(); 5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Listener l = null; 5339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int size = mListeners.size(); 5349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < size && l == null; i++) { 5359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Listener test = mListeners.get(i); 5369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (binder.equals(test.mListener.asBinder())) { 5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project l = test; 5389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (l != null) { 5429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mListeners.remove(l); 5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project binder.unlinkToDeath(l, 0); 5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project @Override 5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean sendExtraCommand(String command, Bundle extras) { 5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ("delete_aiding_data".equals(command)) { 5529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return deleteAidingData(extras); 5539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.w(TAG, "sendExtraCommand: unknown command " + command); 5569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 5579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean deleteAidingData(Bundle extras) { 5609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int flags; 5619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras == null) { 5639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project flags = GPS_DELETE_ALL; 5649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 5659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project flags = 0; 5669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("ephemeris")) flags |= GPS_DELETE_EPHEMERIS; 5679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("almanac")) flags |= GPS_DELETE_ALMANAC; 5689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("position")) flags |= GPS_DELETE_POSITION; 5699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("time")) flags |= GPS_DELETE_TIME; 5709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("iono")) flags |= GPS_DELETE_IONO; 5719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("utc")) flags |= GPS_DELETE_UTC; 5729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("health")) flags |= GPS_DELETE_HEALTH; 5739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("svdir")) flags |= GPS_DELETE_SVDIR; 5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("svsteer")) flags |= GPS_DELETE_SVSTEER; 5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("sadata")) flags |= GPS_DELETE_SADATA; 5769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("rti")) flags |= GPS_DELETE_RTI; 5779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("celldb-info")) flags |= GPS_DELETE_CELLDB_INFO; 5789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("all")) flags |= GPS_DELETE_ALL; 5799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (flags != 0) { 5829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project native_delete_aiding_data(flags); 5839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 5879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void startNavigating() { 5909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mStarted) { 5919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Config.LOGV) Log.v(TAG, "startNavigating"); 5929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStarted = true; 593105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project if (!native_start(mPositionMode, false, mFixInterval)) { 5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStarted = false; 5959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.e(TAG, "native_start failed in startNavigating()"); 5969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // reset SV count to zero 5999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project updateStatus(TEMPORARILY_UNAVAILABLE, 0); 6009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void stopNavigating() { 6049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Config.LOGV) Log.v(TAG, "stopNavigating"); 6059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mStarted) { 6069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStarted = false; 6079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project native_stop(); 6089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTTFF = 0; 6099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLastFixTime = 0; 6109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocationFlags = LOCATION_INVALID; 6119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // reset SV count to zero 6139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project updateStatus(TEMPORARILY_UNAVAILABLE, 0); 6149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * called from native code to update our position. 6199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void reportLocation(int flags, double latitude, double longitude, double altitude, 6219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float speed, float bearing, float accuracy, long timestamp) { 6229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Config.LOGV) Log.v(TAG, "reportLocation lat: " + latitude + " long: " + longitude + 6239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project " timestamp: " + timestamp); 6249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLastFixTime = System.currentTimeMillis(); 6269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // report time to first fix 6279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mTTFF == 0 && (flags & LOCATION_HAS_LAT_LONG) == LOCATION_HAS_LAT_LONG) { 6289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTTFF = (int)(mLastFixTime - mFixRequestTime); 6299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Config.LOGD) Log.d(TAG, "TTFF: " + mTTFF); 6309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // notify status listeners 6329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized(mListeners) { 6339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int size = mListeners.size(); 6349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < size; i++) { 6359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Listener listener = mListeners.get(i); 6369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 6379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project listener.mListener.onFirstFix(mTTFF); 6389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 6399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.w(TAG, "RemoteException in stopNavigating"); 6409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mListeners.remove(listener); 6419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // adjust for size of list changing 6429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size--; 6439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mLocation) { 6499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocationFlags = flags; 6509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((flags & LOCATION_HAS_LAT_LONG) == LOCATION_HAS_LAT_LONG) { 6519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocation.setLatitude(latitude); 6529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocation.setLongitude(longitude); 6539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocation.setTime(timestamp); 6549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((flags & LOCATION_HAS_ALTITUDE) == LOCATION_HAS_ALTITUDE) { 6569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocation.setAltitude(altitude); 6579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 6589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocation.removeAltitude(); 6599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((flags & LOCATION_HAS_SPEED) == LOCATION_HAS_SPEED) { 6619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocation.setSpeed(speed); 6629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 6639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocation.removeSpeed(); 6649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((flags & LOCATION_HAS_BEARING) == LOCATION_HAS_BEARING) { 6669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocation.setBearing(bearing); 6679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 6689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocation.removeBearing(); 6699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((flags & LOCATION_HAS_ACCURACY) == LOCATION_HAS_ACCURACY) { 6719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocation.setAccuracy(accuracy); 6729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 6739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocation.removeAccuracy(); 6749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6764e50b78bda9cd58be61581d2886c88ff6348a1c1Mike Lockwood reportLocationChanged(mLocation); 6774e50b78bda9cd58be61581d2886c88ff6348a1c1Mike Lockwood 6789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // Send to collector 6799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((flags & LOCATION_HAS_LAT_LONG) == LOCATION_HAS_LAT_LONG 6809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project && mCollector != null) { 6819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCollector.updateLocation(mLocation); 6829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mStarted && mStatus != AVAILABLE) { 6869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // send an intent to notify that the GPS is receiving fixes. 6879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Intent intent = new Intent(GPS_FIX_CHANGE_ACTION); 6889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project intent.putExtra(EXTRA_ENABLED, true); 6899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContext.sendBroadcast(intent); 6909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project updateStatus(AVAILABLE, mSvCount); 6919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * called from native code to update our status 6969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void reportStatus(int status) { 6989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Config.LOGV) Log.v(TAG, "reportStatus status: " + status); 6999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean wasNavigating = mNavigating; 7019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNavigating = (status == GPS_STATUS_SESSION_BEGIN); 7029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (wasNavigating != mNavigating) { 7049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized(mListeners) { 7059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int size = mListeners.size(); 7069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < size; i++) { 7079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Listener listener = mListeners.get(i); 7089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 7099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mNavigating) { 7109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project listener.mListener.onGpsStarted(); 7119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 7129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project listener.mListener.onGpsStopped(); 7139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 7159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.w(TAG, "RemoteException in reportStatus"); 7169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mListeners.remove(listener); 7179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // adjust for size of list changing 7189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size--; 7199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // send an intent to notify that the GPS has been enabled or disabled. 7249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Intent intent = new Intent(GPS_ENABLED_CHANGE_ACTION); 7259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project intent.putExtra(EXTRA_ENABLED, mNavigating); 7269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContext.sendBroadcast(intent); 7279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * called from native code to update SV info 7329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void reportSvStatus() { 7349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int svCount = native_read_sv_status(mSvs, mSnrs, mSvElevations, mSvAzimuths, mSvMasks); 7369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized(mListeners) { 7389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int size = mListeners.size(); 7399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < size; i++) { 7409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Listener listener = mListeners.get(i); 7419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 7429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project listener.mListener.onSvStatusChanged(svCount, mSvs, mSnrs, 7439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSvElevations, mSvAzimuths, mSvMasks[EPHEMERIS_MASK], 7449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSvMasks[ALMANAC_MASK], mSvMasks[USED_FOR_FIX_MASK]); 7459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 7469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.w(TAG, "RemoteException in reportSvInfo"); 7479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mListeners.remove(listener); 7489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // adjust for size of list changing 7499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size--; 7509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Config.LOGD) { 7559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Config.LOGV) Log.v(TAG, "SV count: " + svCount + 7569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project " ephemerisMask: " + Integer.toHexString(mSvMasks[EPHEMERIS_MASK]) + 7579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project " almanacMask: " + Integer.toHexString(mSvMasks[ALMANAC_MASK])); 7589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < svCount; i++) { 7599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Config.LOGV) Log.v(TAG, "sv: " + mSvs[i] + 7609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project " snr: " + (float)mSnrs[i]/10 + 7619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project " elev: " + mSvElevations[i] + 7629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project " azimuth: " + mSvAzimuths[i] + 7639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ((mSvMasks[EPHEMERIS_MASK] & (1 << (mSvs[i] - 1))) == 0 ? " " : " E") + 7649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ((mSvMasks[ALMANAC_MASK] & (1 << (mSvs[i] - 1))) == 0 ? " " : " A") + 7659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ((mSvMasks[USED_FOR_FIX_MASK] & (1 << (mSvs[i] - 1))) == 0 ? "" : "U")); 7669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project updateStatus(mStatus, svCount); 7709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mNavigating && mStatus == AVAILABLE && mLastFixTime > 0 && 7729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project System.currentTimeMillis() - mLastFixTime > RECENT_FIX_TIMEOUT) { 7739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // send an intent to notify that the GPS is no longer receiving fixes. 7749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Intent intent = new Intent(GPS_FIX_CHANGE_ACTION); 7759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project intent.putExtra(EXTRA_ENABLED, false); 7769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContext.sendBroadcast(intent); 7779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project updateStatus(TEMPORARILY_UNAVAILABLE, mSvCount); 7789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void xtraDownloadRequest() { 7829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Config.LOGD) Log.d(TAG, "xtraDownloadRequest"); 7839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mNetworkThread != null) { 7849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNetworkThread.xtraDownloadRequest(); 7859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private class GpsEventThread extends Thread { 7899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public GpsEventThread() { 7919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super("GpsEventThread"); 7929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void run() { 7959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Config.LOGD) Log.d(TAG, "GpsEventThread starting"); 796d654f9f727b415b153c7190832db4b65f6943f32Mike Lockwood // Exit as soon as disable() is called instead of waiting for the GPS to stop. 797d654f9f727b415b153c7190832db4b65f6943f32Mike Lockwood while (mEnabled) { 7989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // this will wait for an event from the GPS, 7999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // which will be reported via reportLocation or reportStatus 8009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project native_wait_for_event(); 8019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Config.LOGD) Log.d(TAG, "GpsEventThread exiting"); 8039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private class GpsNetworkThread extends Thread { 8079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private long mNextNtpTime = 0; 8099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private long mNextXtraTime = 0; 8109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mXtraDownloadRequested = false; 8119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mDone = false; 8129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public GpsNetworkThread() { 8149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super("GpsNetworkThread"); 8159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void run() { 8189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mNetworkThreadLock) { 8199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mDone) { 8209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project runLocked(); 8219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void runLocked() { 8269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Config.LOGD) Log.d(TAG, "NetworkThread starting"); 8279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SntpClient client = new SntpClient(); 8299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project GpsXtraDownloader xtraDownloader = null; 8309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (native_supports_xtra()) { 8329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project xtraDownloader = new GpsXtraDownloader(mContext, mProperties); 8339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // thread exits after disable() is called 8369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (!mDone) { 8379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long waitTime = getWaitTime(); 8389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project do { 8399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (this) { 8409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 8419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mNetworkAvailable) { 8429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Config.LOGD) Log.d(TAG, 8439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "NetworkThread wait for network"); 8449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project wait(); 8459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (waitTime > 0) { 8469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Config.LOGD) { 8479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.d(TAG, "NetworkThread wait for " + 8489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project waitTime + "ms"); 8499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project wait(waitTime); 8519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (InterruptedException e) { 8539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Config.LOGD) { 8549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.d(TAG, "InterruptedException in GpsNetworkThread"); 8559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project waitTime = getWaitTime(); 859105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project } while (!mDone && ((!mXtraDownloadRequested && !mSetSuplServer && waitTime > 0) 8609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project || !mNetworkAvailable)); 8619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Config.LOGD) Log.d(TAG, "NetworkThread out of wake loop"); 8629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mDone) { 8649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mNtpServer != null && 8659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNextNtpTime <= System.currentTimeMillis()) { 8669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Config.LOGD) { 8679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.d(TAG, "Requesting time from NTP server " + mNtpServer); 8689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (client.requestTime(mNtpServer, 10000)) { 8709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long time = client.getNtpTime(); 8719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long timeReference = client.getNtpTimeReference(); 8729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int certainty = (int)(client.getRoundTripTime()/2); 8739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Config.LOGD) Log.d(TAG, "calling native_inject_time: " + 8759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project time + " reference: " + timeReference 8769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + " certainty: " + certainty); 8779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project native_inject_time(time, timeReference, certainty); 8799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNextNtpTime = System.currentTimeMillis() + NTP_INTERVAL; 8809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 8819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Config.LOGD) Log.d(TAG, "requestTime failed"); 8829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNextNtpTime = System.currentTimeMillis() + RETRY_INTERVAL; 8839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 886105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project // Set the SUPL server address if we have not yet 887105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project if (mSetSuplServer) { 888105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project try { 889105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project InetAddress inetAddress = InetAddress.getByName(mSuplHost); 890105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project if (inetAddress != null) { 891105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project byte[] addrBytes = inetAddress.getAddress(); 892105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project long addr = 0; 893105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project for (int i = 0; i < addrBytes.length; i++) { 894105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project int temp = addrBytes[i]; 895105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project // signed -> unsigned 896105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project if (temp < 0) temp = 256 + temp; 897105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project addr = addr * 256 + temp; 898105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project } 899105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project // use MS-Based position mode if SUPL support is enabled 900105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project mPositionMode = GPS_POSITION_MODE_MS_BASED; 901105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project native_set_supl_server((int)addr, mSuplPort); 902105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project mSetSuplServer = false; 903105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project } 904105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project } catch (UnknownHostException e) { 905105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project Log.e(TAG, "unknown host for SUPL server " + mSuplHost); 906105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project } 907105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project } 908105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project 9099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((mXtraDownloadRequested || 9109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (mNextXtraTime > 0 && mNextXtraTime <= System.currentTimeMillis())) 9119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project && xtraDownloader != null) { 9129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project byte[] data = xtraDownloader.downloadXtraData(); 9139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (data != null) { 9149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Config.LOGD) { 9159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.d(TAG, "calling native_inject_xtra_data"); 9169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project native_inject_xtra_data(data, data.length); 9189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNextXtraTime = 0; 9199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mXtraDownloadRequested = false; 9209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 9219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNextXtraTime = System.currentTimeMillis() + RETRY_INTERVAL; 9229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Config.LOGD) Log.d(TAG, "NetworkThread exiting"); 9279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized void xtraDownloadRequest() { 9309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mXtraDownloadRequested = true; 9319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project notify(); 9329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized void signal() { 9359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project notify(); 9369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized void setDone() { 9399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Config.LOGD) Log.d(TAG, "stopping NetworkThread"); 9409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDone = true; 9419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project notify(); 9429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private long getWaitTime() { 9459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long now = System.currentTimeMillis(); 9469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long waitTime = Long.MAX_VALUE; 9479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mNtpServer != null) { 9489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project waitTime = mNextNtpTime - now; 9499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mNextXtraTime != 0) { 9519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long xtraWaitTime = mNextXtraTime - now; 9529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (xtraWaitTime < waitTime) { 9539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project waitTime = xtraWaitTime; 9549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (waitTime < 0) { 9579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project waitTime = 0; 9589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return waitTime; 9609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // for GPS SV statistics 9649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int MAX_SVS = 32; 9659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int EPHEMERIS_MASK = 0; 9669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int ALMANAC_MASK = 1; 9679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int USED_FOR_FIX_MASK = 2; 9689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // preallocated arrays, to avoid memory allocation in reportStatus() 9709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mSvs[] = new int[MAX_SVS]; 9719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private float mSnrs[] = new float[MAX_SVS]; 9729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private float mSvElevations[] = new float[MAX_SVS]; 9739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private float mSvAzimuths[] = new float[MAX_SVS]; 9749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mSvMasks[] = new int[3]; 9759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mSvCount; 9769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static { class_init_native(); } 9789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static native void class_init_native(); 9799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static native boolean native_is_supported(); 9809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native boolean native_init(); 9829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native void native_disable(); 9839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native void native_cleanup(); 984105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project private native boolean native_start(int positionMode, boolean singleFix, int fixInterval); 9859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native boolean native_stop(); 9869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native void native_set_fix_frequency(int fixFrequency); 9879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native void native_delete_aiding_data(int flags); 9889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native void native_wait_for_event(); 9899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // returns number of SVs 9909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // mask[0] is ephemeris mask and mask[1] is almanac mask 9919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native int native_read_sv_status(int[] svs, float[] snrs, 9929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float[] elevations, float[] azimuths, int[] masks); 9939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // XTRA Support 9959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native void native_inject_time(long time, long timeReference, int uncertainty); 9969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native boolean native_supports_xtra(); 9979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native void native_inject_xtra_data(byte[] data, int length); 998105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project 999105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project // SUPL Support 1000105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project private native void native_set_supl_server(int addr, int port); 1001105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project private native void native_set_supl_apn(String apn); 10029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1003