GpsLocationProvider.java revision 660bbfcc54d48d5d32e64da683c76b9c372c19b1
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 1929c84340a14e70419449628ab193d11b7a609e9aMike Lockwoodimport android.app.AlarmManager; 2029c84340a14e70419449628ab193d11b7a609e9aMike Lockwoodimport android.app.PendingIntent; 21105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Projectimport android.content.BroadcastReceiver; 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Context; 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Intent; 24105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Projectimport android.content.IntentFilter; 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.location.Criteria; 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.location.IGpsStatusListener; 2715e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwoodimport android.location.IGpsStatusProvider; 284e50b78bda9cd58be61581d2886c88ff6348a1c1Mike Lockwoodimport android.location.ILocationManager; 2915e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwoodimport android.location.ILocationProvider; 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.location.Location; 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.location.LocationManager; 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.location.LocationProvider; 3358bda987665af759c379cd494ff4873ac61acf29Mike Lockwoodimport android.net.ConnectivityManager; 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.net.SntpClient; 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Bundle; 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.IBinder; 370528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwoodimport android.os.PowerManager; 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.RemoteException; 392f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwoodimport android.os.ServiceManager; 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.SystemClock; 41bcab8df83e6e769a7cbcc742e72b47d665998793Mike Lockwoodimport android.provider.Settings; 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Config; 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Log; 442f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwoodimport android.util.SparseIntArray; 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 462f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwoodimport com.android.internal.app.IBatteryStats; 47105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Projectimport com.android.internal.telephony.Phone; 48105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Projectimport com.android.internal.telephony.TelephonyIntents; 49105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.File; 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.FileInputStream; 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.IOException; 53105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Projectimport java.net.InetAddress; 54105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Projectimport java.net.UnknownHostException; 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.ArrayList; 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.Properties; 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * A GPS implementation of LocationProvider used by LocationManager. 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@hide} 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6315e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwoodpublic class GpsLocationProvider extends ILocationProvider.Stub { 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final String TAG = "GpsLocationProvider"; 6629c84340a14e70419449628ab193d11b7a609e9aMike Lockwood 6729c84340a14e70419449628ab193d11b7a609e9aMike Lockwood private static final boolean DEBUG = true; 6829c84340a14e70419449628ab193d11b7a609e9aMike Lockwood private static final boolean VERBOSE = false; 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Broadcast intent action indicating that the GPS has either been 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * enabled or disabled. An intent extra provides this state as a boolean, 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * where {@code true} means enabled. 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #EXTRA_ENABLED 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@hide} 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final String GPS_ENABLED_CHANGE_ACTION = 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "android.location.GPS_ENABLED_CHANGE"; 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Broadcast intent action indicating that the GPS has either started or 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * stopped receiving GPS fixes. An intent extra provides this state as a 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * boolean, where {@code true} means that the GPS is actively receiving fixes. 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #EXTRA_ENABLED 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@hide} 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final String GPS_FIX_CHANGE_ACTION = 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "android.location.GPS_FIX_CHANGE"; 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The lookup key for a boolean that indicates whether GPS is enabled or 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * disabled. {@code true} means GPS is enabled. Retrieve it with 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link android.content.Intent#getBooleanExtra(String,boolean)}. 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@hide} 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final String EXTRA_ENABLED = "enabled"; 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 101105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project // these need to match GpsPositionMode enum in gps.h 102105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project private static final int GPS_POSITION_MODE_STANDALONE = 0; 103105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project private static final int GPS_POSITION_MODE_MS_BASED = 1; 104105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project private static final int GPS_POSITION_MODE_MS_ASSISTED = 2; 105105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // these need to match GpsStatusValue defines in gps.h 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_STATUS_NONE = 0; 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_STATUS_SESSION_BEGIN = 1; 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_STATUS_SESSION_END = 2; 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_STATUS_ENGINE_ON = 3; 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_STATUS_ENGINE_OFF = 4; 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 113e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood // these need to match GpsApgsStatusValue defines in gps.h 114e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood /** AGPS status event values. */ 115e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood private static final int GPS_REQUEST_AGPS_DATA_CONN = 1; 116e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood private static final int GPS_RELEASE_AGPS_DATA_CONN = 2; 117e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood private static final int GPS_AGPS_DATA_CONNECTED = 3; 118e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood private static final int GPS_AGPS_DATA_CONN_DONE = 4; 119e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood private static final int GPS_AGPS_DATA_CONN_FAILED = 5; 12058bda987665af759c379cd494ff4873ac61acf29Mike Lockwood 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // these need to match GpsLocationFlags enum in gps.h 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int LOCATION_INVALID = 0; 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int LOCATION_HAS_LAT_LONG = 1; 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int LOCATION_HAS_ALTITUDE = 2; 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int LOCATION_HAS_SPEED = 4; 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int LOCATION_HAS_BEARING = 8; 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int LOCATION_HAS_ACCURACY = 16; 128e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood 129e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood// IMPORTANT - the GPS_DELETE_* symbols here must match constants in gps.h 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_DELETE_EPHEMERIS = 0x0001; 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_DELETE_ALMANAC = 0x0002; 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_DELETE_POSITION = 0x0004; 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_DELETE_TIME = 0x0008; 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_DELETE_IONO = 0x0010; 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_DELETE_UTC = 0x0020; 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_DELETE_HEALTH = 0x0040; 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_DELETE_SVDIR = 0x0080; 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_DELETE_SVSTEER = 0x0100; 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_DELETE_SADATA = 0x0200; 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_DELETE_RTI = 0x0400; 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_DELETE_CELLDB_INFO = 0x8000; 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_DELETE_ALL = 0xFFFF; 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 144e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood // these need to match AGpsType enum in gps.h 145e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood private static final int AGPS_TYPE_SUPL = 1; 146e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood private static final int AGPS_TYPE_C2K = 2; 147e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood 148e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood // for mAGpsDataConnectionState 149e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood private static final int AGPS_DATA_CONNECTION_CLOSED = 0; 150e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood private static final int AGPS_DATA_CONNECTION_OPENING = 1; 151e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood private static final int AGPS_DATA_CONNECTION_OPEN = 2; 15258bda987665af759c379cd494ff4873ac61acf29Mike Lockwood 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final String PROPERTIES_FILE = "/etc/gps.conf"; 1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mLocationFlags = LOCATION_INVALID; 1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // current status 15815e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood private int mStatus = LocationProvider.TEMPORARILY_UNAVAILABLE; 1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // time for last status update 1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private long mStatusUpdateTime = SystemClock.elapsedRealtime(); 1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // turn off GPS fix icon if we haven't received a fix in 10 seconds 1640632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood private static final long RECENT_FIX_TIMEOUT = 10; 16529c84340a14e70419449628ab193d11b7a609e9aMike Lockwood 16629c84340a14e70419449628ab193d11b7a609e9aMike Lockwood // number of fixes to receive before disabling GPS 16729c84340a14e70419449628ab193d11b7a609e9aMike Lockwood private static final int MIN_FIX_COUNT = 10; 1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1690632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood // stop trying if we do not receive a fix within 60 seconds 1700632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood private static final int NO_FIX_TIMEOUT = 60; 1710632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood 1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // true if we are enabled 1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mEnabled; 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // true if we have network connectivity 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mNetworkAvailable; 1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // true if GPS is navigating 1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mNavigating; 1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // requested frequency of fixes, in seconds 1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mFixInterval = 1; 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 18429c84340a14e70419449628ab193d11b7a609e9aMike Lockwood // number of fixes we have received since we started navigating 18529c84340a14e70419449628ab193d11b7a609e9aMike Lockwood private int mFixCount; 18629c84340a14e70419449628ab193d11b7a609e9aMike Lockwood 1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // true if we started navigation 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mStarted; 1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // for calculating time to first fix 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private long mFixRequestTime = 0; 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // time to first fix for most recent session 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mTTFF = 0; 1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // time we received our last fix 1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private long mLastFixTime; 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // properties loaded from PROPERTIES_FILE 1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Properties mProperties; 1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private String mNtpServer; 200734d6031a662a275ec68627bd1258159041d44deMike Lockwood private String mSuplServerHost; 201734d6031a662a275ec68627bd1258159041d44deMike Lockwood private int mSuplServerPort; 202734d6031a662a275ec68627bd1258159041d44deMike Lockwood private String mC2KServerHost; 203734d6031a662a275ec68627bd1258159041d44deMike Lockwood private int mC2KServerPort; 2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 20515e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood private final Context mContext; 20615e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood private final ILocationManager mLocationManager; 2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Location mLocation = new Location(LocationManager.GPS_PROVIDER); 2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Bundle mLocationExtras = new Bundle(); 2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private ArrayList<Listener> mListeners = new ArrayList<Listener>(); 2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private GpsEventThread mEventThread; 2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private GpsNetworkThread mNetworkThread; 2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Object mNetworkThreadLock = new Object(); 213105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project 214e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood private String mAGpsApn; 215e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood private int mAGpsDataConnectionState; 2162f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood private final ConnectivityManager mConnMgr; 2172f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood 2180528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood // Wakelocks 2190528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood private final static String WAKELOCK_KEY = "GpsLocationProvider"; 2200528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood private final PowerManager.WakeLock mWakeLock; 2210528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood 22229c84340a14e70419449628ab193d11b7a609e9aMike Lockwood // Alarms 22329c84340a14e70419449628ab193d11b7a609e9aMike Lockwood private final static String ALARM_WAKEUP = "com.android.internal.location.ALARM_WAKEUP"; 2240632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood private final static String ALARM_TIMEOUT = "com.android.internal.location.ALARM_TIMEOUT"; 22529c84340a14e70419449628ab193d11b7a609e9aMike Lockwood private final AlarmManager mAlarmManager; 22629c84340a14e70419449628ab193d11b7a609e9aMike Lockwood private final PendingIntent mWakeupIntent; 2270632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood private final PendingIntent mTimeoutIntent; 22829c84340a14e70419449628ab193d11b7a609e9aMike Lockwood 2292f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood private final IBatteryStats mBatteryStats; 2302f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood private final SparseIntArray mClientUids = new SparseIntArray(); 231105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project 2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // how often to request NTP time, in milliseconds 2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // current setting 4 hours 2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final long NTP_INTERVAL = 4*60*60*1000; 2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // how long to wait if we have a network error in NTP or XTRA downloading 2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // current setting - 5 minutes 2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final long RETRY_INTERVAL = 5*60*1000; 2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 23915e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood private final IGpsStatusProvider mGpsStatusProvider = new IGpsStatusProvider.Stub() { 24015e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood public void addGpsStatusListener(IGpsStatusListener listener) throws RemoteException { 24115e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood if (listener == null) { 24215e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood throw new NullPointerException("listener is null in addGpsStatusListener"); 24315e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 24415e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood 24515e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood synchronized(mListeners) { 24615e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood IBinder binder = listener.asBinder(); 24715e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood int size = mListeners.size(); 24815e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood for (int i = 0; i < size; i++) { 24915e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood Listener test = mListeners.get(i); 25015e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood if (binder.equals(test.mListener.asBinder())) { 25115e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood // listener already added 25215e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood return; 25315e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 25415e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 25515e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood 25615e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood Listener l = new Listener(listener); 25715e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood binder.linkToDeath(l, 0); 25815e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood mListeners.add(l); 25915e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 26015e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 26115e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood 26215e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood public void removeGpsStatusListener(IGpsStatusListener listener) { 26315e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood if (listener == null) { 26415e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood throw new NullPointerException("listener is null in addGpsStatusListener"); 26515e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 26615e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood 26715e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood synchronized(mListeners) { 26815e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood IBinder binder = listener.asBinder(); 26915e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood Listener l = null; 27015e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood int size = mListeners.size(); 27115e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood for (int i = 0; i < size && l == null; i++) { 27215e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood Listener test = mListeners.get(i); 27315e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood if (binder.equals(test.mListener.asBinder())) { 27415e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood l = test; 27515e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 27615e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 27715e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood 27815e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood if (l != null) { 27915e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood mListeners.remove(l); 28015e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood binder.unlinkToDeath(l, 0); 28115e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 28215e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 28315e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 28415e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood }; 28515e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood 28615e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood public IGpsStatusProvider getGpsStatusProvider() { 28715e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood return mGpsStatusProvider; 28815e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 28915e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood 29029c84340a14e70419449628ab193d11b7a609e9aMike Lockwood private final BroadcastReceiver mBroadcastReciever = new BroadcastReceiver() { 291105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project @Override public void onReceive(Context context, Intent intent) { 292105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project String action = intent.getAction(); 293105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project 29429c84340a14e70419449628ab193d11b7a609e9aMike Lockwood if (action.equals(ALARM_WAKEUP)) { 29529c84340a14e70419449628ab193d11b7a609e9aMike Lockwood if (DEBUG) Log.d(TAG, "ALARM_WAKEUP"); 29629c84340a14e70419449628ab193d11b7a609e9aMike Lockwood startNavigating(); 2970632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood } else if (action.equals(ALARM_TIMEOUT)) { 2980632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood if (DEBUG) Log.d(TAG, "ALARM_TIMEOUT"); 2990632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood hibernate(); 30029c84340a14e70419449628ab193d11b7a609e9aMike Lockwood } else if (action.equals(TelephonyIntents.ACTION_ANY_DATA_CONNECTION_STATE_CHANGED)) { 301105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project String state = intent.getStringExtra(Phone.STATE_KEY); 302105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project String apnName = intent.getStringExtra(Phone.DATA_APN_KEY); 303105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project String reason = intent.getStringExtra(Phone.STATE_CHANGE_REASON_KEY); 304105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project 305105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project if (Config.LOGD) { 306105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project Log.d(TAG, "state: " + state + " apnName: " + apnName + " reason: " + reason); 307105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project } 308e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood // FIXME - might not have an APN on CDMA 309375cbb47ff721a26b62385211b82a7cf26db0395Mike Lockwood if ("CONNECTED".equals(state) && apnName != null && apnName.length() > 0) { 310e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood mAGpsApn = apnName; 311e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood if (mAGpsDataConnectionState == AGPS_DATA_CONNECTION_OPENING) { 312e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood native_agps_data_conn_open(mAGpsApn); 313e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood mAGpsDataConnectionState = AGPS_DATA_CONNECTION_OPEN; 31458bda987665af759c379cd494ff4873ac61acf29Mike Lockwood } 315105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project } 316105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project } 317105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project } 31829c84340a14e70419449628ab193d11b7a609e9aMike Lockwood }; 319105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project 3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static boolean isSupported() { 3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return native_is_supported(); 3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3244e50b78bda9cd58be61581d2886c88ff6348a1c1Mike Lockwood public GpsLocationProvider(Context context, ILocationManager locationManager) { 3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContext = context; 32615e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood mLocationManager = locationManager; 3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3280528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood // Create a wake lock 3290528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood PowerManager powerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE); 3300528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, WAKELOCK_KEY); 3310528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood 33229c84340a14e70419449628ab193d11b7a609e9aMike Lockwood mAlarmManager = (AlarmManager)mContext.getSystemService(Context.ALARM_SERVICE); 33329c84340a14e70419449628ab193d11b7a609e9aMike Lockwood mWakeupIntent = PendingIntent.getBroadcast(mContext, 0, new Intent(ALARM_WAKEUP), 0); 3340632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood mTimeoutIntent = PendingIntent.getBroadcast(mContext, 0, new Intent(ALARM_TIMEOUT), 0); 33529c84340a14e70419449628ab193d11b7a609e9aMike Lockwood 336105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project IntentFilter intentFilter = new IntentFilter(); 33729c84340a14e70419449628ab193d11b7a609e9aMike Lockwood intentFilter.addAction(ALARM_WAKEUP); 3380632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood intentFilter.addAction(ALARM_TIMEOUT); 339105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project intentFilter.addAction(TelephonyIntents.ACTION_ANY_DATA_CONNECTION_STATE_CHANGED); 34029c84340a14e70419449628ab193d11b7a609e9aMike Lockwood context.registerReceiver(mBroadcastReciever, intentFilter); 341105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project 34258bda987665af759c379cd494ff4873ac61acf29Mike Lockwood mConnMgr = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE); 34358bda987665af759c379cd494ff4873ac61acf29Mike Lockwood 3442f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood // Battery statistics service to be notified when GPS turns on or off 3452f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood mBatteryStats = IBatteryStats.Stub.asInterface(ServiceManager.getService("batteryinfo")); 3462f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood 3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mProperties = new Properties(); 3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project File file = new File(PROPERTIES_FILE); 3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project FileInputStream stream = new FileInputStream(file); 3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mProperties.load(stream); 3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project stream.close(); 3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNtpServer = mProperties.getProperty("NTP_SERVER", null); 354e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood 355734d6031a662a275ec68627bd1258159041d44deMike Lockwood mSuplServerHost = mProperties.getProperty("SUPL_HOST"); 356e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood String portString = mProperties.getProperty("SUPL_PORT"); 357734d6031a662a275ec68627bd1258159041d44deMike Lockwood if (mSuplServerHost != null && portString != null) { 358105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project try { 359734d6031a662a275ec68627bd1258159041d44deMike Lockwood mSuplServerPort = Integer.parseInt(portString); 360105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project } catch (NumberFormatException e) { 361e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood Log.e(TAG, "unable to parse SUPL_PORT: " + portString); 362e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood } 363e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood } 364e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood 365734d6031a662a275ec68627bd1258159041d44deMike Lockwood mC2KServerHost = mProperties.getProperty("C2K_HOST"); 366e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood portString = mProperties.getProperty("C2K_PORT"); 367734d6031a662a275ec68627bd1258159041d44deMike Lockwood if (mC2KServerHost != null && portString != null) { 368e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood try { 369734d6031a662a275ec68627bd1258159041d44deMike Lockwood mC2KServerPort = Integer.parseInt(portString); 370e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood } catch (NumberFormatException e) { 371e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood Log.e(TAG, "unable to parse C2K_PORT: " + portString); 372105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project } 373105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project } 3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (IOException e) { 3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.w(TAG, "Could not open GPS configuration file " + PROPERTIES_FILE); 3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns true if the provider requires access to a 3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * data network (e.g., the Internet), false otherwise. 3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean requiresNetwork() { 384a9e546169b3c2c9c5f248d2f3abe3b934f48695dMike Lockwood return true; 3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void updateNetworkState(int state) { 3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNetworkAvailable = (state == LocationProvider.AVAILABLE); 3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Config.LOGD) { 3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.d(TAG, "updateNetworkState " + (mNetworkAvailable ? "available" : "unavailable")); 3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mNetworkAvailable && mNetworkThread != null && mEnabled) { 3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // signal the network thread when the network becomes available 3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNetworkThread.signal(); 3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 401fd6e5f0dda50e113db4ccc55338b6c4f09da37a4Mike Lockwood * This is called to inform us when another location provider returns a location. 402fd6e5f0dda50e113db4ccc55338b6c4f09da37a4Mike Lockwood * Someday we might use this for network location injection to aid the GPS 403fd6e5f0dda50e113db4ccc55338b6c4f09da37a4Mike Lockwood */ 404fd6e5f0dda50e113db4ccc55338b6c4f09da37a4Mike Lockwood public void updateLocation(Location location) { 405d26ce0d903f5141a346d67b2b94437ef3e2880aaMike Lockwood if (location.hasAccuracy()) { 406d26ce0d903f5141a346d67b2b94437ef3e2880aaMike Lockwood native_inject_location(location.getLatitude(), location.getLongitude(), 407d26ce0d903f5141a346d67b2b94437ef3e2880aaMike Lockwood location.getAccuracy()); 408d26ce0d903f5141a346d67b2b94437ef3e2880aaMike Lockwood } 409fd6e5f0dda50e113db4ccc55338b6c4f09da37a4Mike Lockwood } 410fd6e5f0dda50e113db4ccc55338b6c4f09da37a4Mike Lockwood 411fd6e5f0dda50e113db4ccc55338b6c4f09da37a4Mike Lockwood /** 4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns true if the provider requires access to a 4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * satellite-based positioning system (e.g., GPS), false 4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * otherwise. 4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean requiresSatellite() { 4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns true if the provider requires access to an appropriate 4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * cellular network (e.g., to make use of cell tower IDs), false 4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * otherwise. 4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean requiresCell() { 4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns true if the use of this provider may result in a 4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * monetary charge to the user, false if use is free. It is up to 4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * each provider to give accurate information. 4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean hasMonetaryCost() { 4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns true if the provider is able to provide altitude 4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * information, false otherwise. A provider that reports altitude 4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * under most circumstances but may occassionally not report it 4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * should return true. 4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean supportsAltitude() { 4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns true if the provider is able to provide speed 4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * information, false otherwise. A provider that reports speed 4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * under most circumstances but may occassionally not report it 4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * should return true. 4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean supportsSpeed() { 4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns true if the provider is able to provide bearing 4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * information, false otherwise. A provider that reports bearing 4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * under most circumstances but may occassionally not report it 4629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * should return true. 4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean supportsBearing() { 4659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns the power requirement for this provider. 4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the power requirement for this provider, as one of the 4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * constants Criteria.POWER_REQUIREMENT_*. 4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getPowerRequirement() { 4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return Criteria.POWER_HIGH; 4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns the horizontal accuracy of this provider 4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the accuracy of location from this provider, as one 4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * of the constants Criteria.ACCURACY_*. 4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getAccuracy() { 4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return Criteria.ACCURACY_FINE; 4869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Enables this provider. When enabled, calls to getStatus() 4904e50b78bda9cd58be61581d2886c88ff6348a1c1Mike Lockwood * must be handled. Hardware may be started up 4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * when the provider is enabled. 4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public synchronized void enable() { 4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Config.LOGD) Log.d(TAG, "enable"); 4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mEnabled) return; 4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEnabled = native_init(); 4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mEnabled) { 499734d6031a662a275ec68627bd1258159041d44deMike Lockwood if (mSuplServerHost != null) { 500734d6031a662a275ec68627bd1258159041d44deMike Lockwood native_set_agps_server(AGPS_TYPE_SUPL, mSuplServerHost, mSuplServerPort); 501734d6031a662a275ec68627bd1258159041d44deMike Lockwood } 502734d6031a662a275ec68627bd1258159041d44deMike Lockwood if (mC2KServerHost != null) { 503734d6031a662a275ec68627bd1258159041d44deMike Lockwood native_set_agps_server(AGPS_TYPE_C2K, mC2KServerHost, mC2KServerPort); 504734d6031a662a275ec68627bd1258159041d44deMike Lockwood } 505734d6031a662a275ec68627bd1258159041d44deMike Lockwood 5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // run event listener thread while we are enabled 5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEventThread = new GpsEventThread(); 5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEventThread.start(); 5099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (requiresNetwork()) { 5119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // run network thread for NTP and XTRA support 5129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mNetworkThread == null) { 5139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNetworkThread = new GpsNetworkThread(); 5149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNetworkThread.start(); 5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNetworkThread.signal(); 5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.w(TAG, "Failed to enable location provider"); 5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Disables this provider. When disabled, calls to getStatus() 5264e50b78bda9cd58be61581d2886c88ff6348a1c1Mike Lockwood * need not be handled. Hardware may be shut 5279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * down while the provider is disabled. 5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public synchronized void disable() { 5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Config.LOGD) Log.d(TAG, "disable"); 5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mEnabled) return; 5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEnabled = false; 5349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project stopNavigating(); 5359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project native_disable(); 5369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // make sure our event thread exits 5389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mEventThread != null) { 5399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 5409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEventThread.join(); 5419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (InterruptedException e) { 5429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.w(TAG, "InterruptedException when joining mEventThread"); 5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEventThread = null; 5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mNetworkThread != null) { 5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNetworkThread.setDone(); 5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNetworkThread = null; 5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 552d654f9f727b415b153c7190832db4b65f6943f32Mike Lockwood // The GpsEventThread does not wait for the GPS to shutdown 553d654f9f727b415b153c7190832db4b65f6943f32Mike Lockwood // so we need to report the GPS_STATUS_ENGINE_OFF event here 554d654f9f727b415b153c7190832db4b65f6943f32Mike Lockwood if (mNavigating) { 555d654f9f727b415b153c7190832db4b65f6943f32Mike Lockwood reportStatus(GPS_STATUS_ENGINE_OFF); 556d654f9f727b415b153c7190832db4b65f6943f32Mike Lockwood } 557d654f9f727b415b153c7190832db4b65f6943f32Mike Lockwood 5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project native_cleanup(); 5599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean isEnabled() { 5629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mEnabled; 5639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getStatus(Bundle extras) { 5669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras != null) { 5679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project extras.putInt("satellites", mSvCount); 5689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mStatus; 5709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void updateStatus(int status, int svCount) { 5739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (status != mStatus || svCount != mSvCount) { 5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStatus = status; 5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSvCount = svCount; 5769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocationExtras.putInt("satellites", svCount); 5779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStatusUpdateTime = SystemClock.elapsedRealtime(); 5789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public long getStatusUpdateTime() { 5829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mStatusUpdateTime; 5839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void enableLocationTracking(boolean enable) { 5869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (enable) { 5879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTTFF = 0; 5889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLastFixTime = 0; 5899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project startNavigating(); 5909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 59129c84340a14e70419449628ab193d11b7a609e9aMike Lockwood mAlarmManager.cancel(mWakeupIntent); 5920632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood mAlarmManager.cancel(mTimeoutIntent); 5939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project stopNavigating(); 5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setMinTime(long minTime) { 5989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Config.LOGD) Log.d(TAG, "setMinTime " + minTime); 5999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (minTime >= 0) { 6019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int interval = (int)(minTime/1000); 6029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (interval < 1) { 6039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project interval = 1; 6049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFixInterval = interval; 6069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final class Listener implements IBinder.DeathRecipient { 6109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final IGpsStatusListener mListener; 6119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int mSensors = 0; 6139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Listener(IGpsStatusListener listener) { 6159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mListener = listener; 6169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void binderDied() { 6199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Config.LOGD) Log.d(TAG, "GPS status listener died"); 6209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized(mListeners) { 6229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mListeners.remove(this); 6239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 624fff2fda0199dedbf1079454dca98a81190dce765Suchi Amalapurapu if (mListener != null) { 625fff2fda0199dedbf1079454dca98a81190dce765Suchi Amalapurapu mListener.asBinder().unlinkToDeath(this, 0); 626fff2fda0199dedbf1079454dca98a81190dce765Suchi Amalapurapu } 6279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6302f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood public void addListener(int uid) { 6312e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn synchronized(mListeners) { 6322e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn if (mClientUids.indexOfKey(uid) >= 0) { 6332e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn // Shouldn't be here -- already have this uid. 6342e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn Log.w(TAG, "Duplicate add listener for uid " + uid); 6352e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn return; 6362e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn } 6372e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn mClientUids.put(uid, 0); 6382e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn if (mNavigating) { 6392e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn try { 6402e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn mBatteryStats.noteStartGps(uid); 6412e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn } catch (RemoteException e) { 6422e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn Log.w(TAG, "RemoteException in addListener"); 6432e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn } 6442f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } 6452f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } 6462f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } 6472f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood 6482f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood public void removeListener(int uid) { 6492e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn synchronized(mListeners) { 6502e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn if (mClientUids.indexOfKey(uid) < 0) { 6512e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn // Shouldn't be here -- don't have this uid. 6522e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn Log.w(TAG, "Unneeded remove listener for uid " + uid); 6532e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn return; 6542e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn } 6552e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn mClientUids.delete(uid); 6562e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn if (mNavigating) { 6572e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn try { 6582e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn mBatteryStats.noteStopGps(uid); 6592e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn } catch (RemoteException e) { 6602e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn Log.w(TAG, "RemoteException in removeListener"); 6612e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn } 6622f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } 6632f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } 6642f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } 6652f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood 6669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean sendExtraCommand(String command, Bundle extras) { 6679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ("delete_aiding_data".equals(command)) { 6699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return deleteAidingData(extras); 6709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 67193bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood if ("force_time_injection".equals(command)) { 67293bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood return forceTimeInjection(); 67393bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood } 67493bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood if ("force_xtra_injection".equals(command)) { 67593bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood if (native_supports_xtra() && mNetworkThread != null) { 67693bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood xtraDownloadRequest(); 67793bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood return true; 67893bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood } 67993bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood return false; 68093bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood } 6819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.w(TAG, "sendExtraCommand: unknown command " + command); 6839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 6849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean deleteAidingData(Bundle extras) { 6879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int flags; 6889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras == null) { 6909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project flags = GPS_DELETE_ALL; 6919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 6929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project flags = 0; 6939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("ephemeris")) flags |= GPS_DELETE_EPHEMERIS; 6949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("almanac")) flags |= GPS_DELETE_ALMANAC; 6959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("position")) flags |= GPS_DELETE_POSITION; 6969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("time")) flags |= GPS_DELETE_TIME; 6979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("iono")) flags |= GPS_DELETE_IONO; 6989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("utc")) flags |= GPS_DELETE_UTC; 6999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("health")) flags |= GPS_DELETE_HEALTH; 7009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("svdir")) flags |= GPS_DELETE_SVDIR; 7019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("svsteer")) flags |= GPS_DELETE_SVSTEER; 7029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("sadata")) flags |= GPS_DELETE_SADATA; 7039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("rti")) flags |= GPS_DELETE_RTI; 7049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("celldb-info")) flags |= GPS_DELETE_CELLDB_INFO; 7059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("all")) flags |= GPS_DELETE_ALL; 7069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (flags != 0) { 7099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project native_delete_aiding_data(flags); 7109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 7119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 7149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 71693bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood private boolean forceTimeInjection() { 71793bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood if (Config.LOGD) Log.d(TAG, "forceTimeInjection"); 71893bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood if (mNetworkThread != null) { 71993bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood mNetworkThread.timeInjectRequest(); 72093bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood return true; 72193bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood } 72293bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood return false; 72393bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood } 72493bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood 7259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void startNavigating() { 7269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mStarted) { 72729c84340a14e70419449628ab193d11b7a609e9aMike Lockwood if (DEBUG) Log.d(TAG, "startNavigating"); 7289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStarted = true; 729bcab8df83e6e769a7cbcc742e72b47d665998793Mike Lockwood int positionMode; 7302bb99d1e2f0296dd8b09a451575f70f49da30a1bMike Lockwood if (Settings.Secure.getInt(mContext.getContentResolver(), 731660bbfcc54d48d5d32e64da683c76b9c372c19b1Mike Lockwood Settings.Secure.ASSISTED_GPS_ENABLED, 1) != 0) { 732bcab8df83e6e769a7cbcc742e72b47d665998793Mike Lockwood positionMode = GPS_POSITION_MODE_MS_BASED; 733bcab8df83e6e769a7cbcc742e72b47d665998793Mike Lockwood } else { 734bcab8df83e6e769a7cbcc742e72b47d665998793Mike Lockwood positionMode = GPS_POSITION_MODE_STANDALONE; 735bcab8df83e6e769a7cbcc742e72b47d665998793Mike Lockwood } 736bcab8df83e6e769a7cbcc742e72b47d665998793Mike Lockwood 737bcab8df83e6e769a7cbcc742e72b47d665998793Mike Lockwood if (!native_start(positionMode, false, mFixInterval)) { 7389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStarted = false; 7399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.e(TAG, "native_start failed in startNavigating()"); 7400632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood return; 7419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // reset SV count to zero 74415e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood updateStatus(LocationProvider.TEMPORARILY_UNAVAILABLE, 0); 74529c84340a14e70419449628ab193d11b7a609e9aMike Lockwood mFixCount = 0; 74629c84340a14e70419449628ab193d11b7a609e9aMike Lockwood mFixRequestTime = System.currentTimeMillis(); 7470632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood // set timer to give up if we do not receive a fix within NO_FIX_TIMEOUT 7480632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood // and our fix interval is not short 7490632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood if (mFixInterval >= NO_FIX_TIMEOUT) { 7500632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, 7510632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood SystemClock.elapsedRealtime() + NO_FIX_TIMEOUT * 1000, mTimeoutIntent); 7520632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood } 7539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void stopNavigating() { 75729c84340a14e70419449628ab193d11b7a609e9aMike Lockwood if (DEBUG) Log.d(TAG, "stopNavigating"); 7589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mStarted) { 7599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStarted = false; 7609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project native_stop(); 7619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTTFF = 0; 7629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLastFixTime = 0; 7639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocationFlags = LOCATION_INVALID; 7649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // reset SV count to zero 76615e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood updateStatus(LocationProvider.TEMPORARILY_UNAVAILABLE, 0); 7679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7700632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood private void hibernate() { 7710632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood // stop GPS until our next fix interval arrives 7720632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood stopNavigating(); 7730632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood mFixCount = 0; 7740632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood mAlarmManager.cancel(mTimeoutIntent); 7750632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood mAlarmManager.cancel(mWakeupIntent); 7760632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood long now = SystemClock.elapsedRealtime(); 7770632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, 7780632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood SystemClock.elapsedRealtime() + mFixInterval * 1000, mWakeupIntent); 7790632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood } 7800632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood 7819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * called from native code to update our position. 7839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void reportLocation(int flags, double latitude, double longitude, double altitude, 7859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float speed, float bearing, float accuracy, long timestamp) { 78629c84340a14e70419449628ab193d11b7a609e9aMike Lockwood if (VERBOSE) Log.v(TAG, "reportLocation lat: " + latitude + " long: " + longitude + 7879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project " timestamp: " + timestamp); 7889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLastFixTime = System.currentTimeMillis(); 7909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // report time to first fix 7919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mTTFF == 0 && (flags & LOCATION_HAS_LAT_LONG) == LOCATION_HAS_LAT_LONG) { 7929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTTFF = (int)(mLastFixTime - mFixRequestTime); 7939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Config.LOGD) Log.d(TAG, "TTFF: " + mTTFF); 7949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // notify status listeners 7969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized(mListeners) { 7979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int size = mListeners.size(); 7989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < size; i++) { 7999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Listener listener = mListeners.get(i); 8009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 8019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project listener.mListener.onFirstFix(mTTFF); 8029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 8039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.w(TAG, "RemoteException in stopNavigating"); 8049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mListeners.remove(listener); 8059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // adjust for size of list changing 8069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size--; 8079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mLocation) { 8139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocationFlags = flags; 8149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((flags & LOCATION_HAS_LAT_LONG) == LOCATION_HAS_LAT_LONG) { 8159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocation.setLatitude(latitude); 8169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocation.setLongitude(longitude); 8179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocation.setTime(timestamp); 8189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((flags & LOCATION_HAS_ALTITUDE) == LOCATION_HAS_ALTITUDE) { 8209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocation.setAltitude(altitude); 8219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 8229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocation.removeAltitude(); 8239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((flags & LOCATION_HAS_SPEED) == LOCATION_HAS_SPEED) { 8259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocation.setSpeed(speed); 8269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 8279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocation.removeSpeed(); 8289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((flags & LOCATION_HAS_BEARING) == LOCATION_HAS_BEARING) { 8309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocation.setBearing(bearing); 8319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 8329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocation.removeBearing(); 8339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((flags & LOCATION_HAS_ACCURACY) == LOCATION_HAS_ACCURACY) { 8359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocation.setAccuracy(accuracy); 8369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 8379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocation.removeAccuracy(); 8389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 84015e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood try { 841275555c8eb3fb5df6e7320873b88b77cdde85a9eMike Lockwood mLocationManager.reportLocation(mLocation); 84215e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } catch (RemoteException e) { 84315e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood Log.e(TAG, "RemoteException calling reportLocation"); 84415e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 8459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 84715e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood if (mStarted && mStatus != LocationProvider.AVAILABLE) { 8480632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood mAlarmManager.cancel(mTimeoutIntent); 8499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // send an intent to notify that the GPS is receiving fixes. 8509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Intent intent = new Intent(GPS_FIX_CHANGE_ACTION); 8519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project intent.putExtra(EXTRA_ENABLED, true); 8529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContext.sendBroadcast(intent); 85315e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood updateStatus(LocationProvider.AVAILABLE, mSvCount); 8549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 85529c84340a14e70419449628ab193d11b7a609e9aMike Lockwood 85629c84340a14e70419449628ab193d11b7a609e9aMike Lockwood if (mFixCount++ >= MIN_FIX_COUNT && mFixInterval > 1) { 85729c84340a14e70419449628ab193d11b7a609e9aMike Lockwood if (DEBUG) Log.d(TAG, "exceeded MIN_FIX_COUNT"); 8580632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood hibernate(); 85929c84340a14e70419449628ab193d11b7a609e9aMike Lockwood } 8609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 8639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * called from native code to update our status 8649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 8659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void reportStatus(int status) { 86629c84340a14e70419449628ab193d11b7a609e9aMike Lockwood if (VERBOSE) Log.v(TAG, "reportStatus status: " + status); 8679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8682e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn synchronized(mListeners) { 8692e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn boolean wasNavigating = mNavigating; 8702e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn mNavigating = (status == GPS_STATUS_SESSION_BEGIN); 8712e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn 8722e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn if (wasNavigating == mNavigating) { 8732e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn return; 8742e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn } 8752e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn 8760528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood if (mNavigating) { 8770528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood if (DEBUG) Log.d(TAG, "Acquiring wakelock"); 8780528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood mWakeLock.acquire(); 8790528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood } 8802e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn 8812e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn int size = mListeners.size(); 8822e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn for (int i = 0; i < size; i++) { 8832e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn Listener listener = mListeners.get(i); 8842e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn try { 8852e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn if (mNavigating) { 8862e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn listener.mListener.onGpsStarted(); 8872e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn } else { 8882e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn listener.mListener.onGpsStopped(); 8899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8902e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn } catch (RemoteException e) { 8912e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn Log.w(TAG, "RemoteException in reportStatus"); 8922e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn mListeners.remove(listener); 8932e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn // adjust for size of list changing 8942e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn size--; 8959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8982f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood try { 8992f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood // update battery stats 9002f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood for (int i=mClientUids.size() - 1; i >= 0; i--) { 9012f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood int uid = mClientUids.keyAt(i); 9022f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood if (mNavigating) { 9032f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood mBatteryStats.noteStartGps(uid); 9042f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } else { 9052f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood mBatteryStats.noteStopGps(uid); 9062f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } 9072f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } 9082f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } catch (RemoteException e) { 9092f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood Log.w(TAG, "RemoteException in reportStatus"); 9102f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } 9112f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood 9129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // send an intent to notify that the GPS has been enabled or disabled. 9139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Intent intent = new Intent(GPS_ENABLED_CHANGE_ACTION); 9149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project intent.putExtra(EXTRA_ENABLED, mNavigating); 9159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContext.sendBroadcast(intent); 9160528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood 9170528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood if (!mNavigating) { 9180528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood if (DEBUG) Log.d(TAG, "Releasing wakelock"); 9190528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood mWakeLock.release(); 9200528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood } 9219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 9259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * called from native code to update SV info 9269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 9279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void reportSvStatus() { 9289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int svCount = native_read_sv_status(mSvs, mSnrs, mSvElevations, mSvAzimuths, mSvMasks); 9309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized(mListeners) { 9329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int size = mListeners.size(); 9339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < size; i++) { 9349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Listener listener = mListeners.get(i); 9359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 9369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project listener.mListener.onSvStatusChanged(svCount, mSvs, mSnrs, 9379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSvElevations, mSvAzimuths, mSvMasks[EPHEMERIS_MASK], 9389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSvMasks[ALMANAC_MASK], mSvMasks[USED_FOR_FIX_MASK]); 9399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 9409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.w(TAG, "RemoteException in reportSvInfo"); 9419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mListeners.remove(listener); 9429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // adjust for size of list changing 9439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size--; 9449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 94829c84340a14e70419449628ab193d11b7a609e9aMike Lockwood if (VERBOSE) { 94929c84340a14e70419449628ab193d11b7a609e9aMike Lockwood Log.v(TAG, "SV count: " + svCount + 9509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project " ephemerisMask: " + Integer.toHexString(mSvMasks[EPHEMERIS_MASK]) + 9519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project " almanacMask: " + Integer.toHexString(mSvMasks[ALMANAC_MASK])); 9529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < svCount; i++) { 95329c84340a14e70419449628ab193d11b7a609e9aMike Lockwood Log.v(TAG, "sv: " + mSvs[i] + 9549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project " snr: " + (float)mSnrs[i]/10 + 9559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project " elev: " + mSvElevations[i] + 9569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project " azimuth: " + mSvAzimuths[i] + 9579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ((mSvMasks[EPHEMERIS_MASK] & (1 << (mSvs[i] - 1))) == 0 ? " " : " E") + 9589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ((mSvMasks[ALMANAC_MASK] & (1 << (mSvs[i] - 1))) == 0 ? " " : " A") + 9599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ((mSvMasks[USED_FOR_FIX_MASK] & (1 << (mSvs[i] - 1))) == 0 ? "" : "U")); 9609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project updateStatus(mStatus, svCount); 9649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 96515e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood if (mNavigating && mStatus == LocationProvider.AVAILABLE && mLastFixTime > 0 && 9660632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood System.currentTimeMillis() - mLastFixTime > RECENT_FIX_TIMEOUT * 1000) { 9679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // send an intent to notify that the GPS is no longer receiving fixes. 9689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Intent intent = new Intent(GPS_FIX_CHANGE_ACTION); 9699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project intent.putExtra(EXTRA_ENABLED, false); 9709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContext.sendBroadcast(intent); 97115e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood updateStatus(LocationProvider.TEMPORARILY_UNAVAILABLE, mSvCount); 9729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 97458bda987665af759c379cd494ff4873ac61acf29Mike Lockwood 97558bda987665af759c379cd494ff4873ac61acf29Mike Lockwood /** 976e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood * called from native code to update AGPS status 97758bda987665af759c379cd494ff4873ac61acf29Mike Lockwood */ 978e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood private void reportAGpsStatus(int type, int status) { 97958bda987665af759c379cd494ff4873ac61acf29Mike Lockwood switch (status) { 980e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood case GPS_REQUEST_AGPS_DATA_CONN: 98158bda987665af759c379cd494ff4873ac61acf29Mike Lockwood int result = mConnMgr.startUsingNetworkFeature( 98258bda987665af759c379cd494ff4873ac61acf29Mike Lockwood ConnectivityManager.TYPE_MOBILE, Phone.FEATURE_ENABLE_SUPL); 98358bda987665af759c379cd494ff4873ac61acf29Mike Lockwood if (result == Phone.APN_ALREADY_ACTIVE) { 984b362a9ab91bb4c05ef1d5c4e7019499257c7f849Mike Lockwood if (mAGpsApn != null) { 985b362a9ab91bb4c05ef1d5c4e7019499257c7f849Mike Lockwood native_agps_data_conn_open(mAGpsApn); 986b362a9ab91bb4c05ef1d5c4e7019499257c7f849Mike Lockwood mAGpsDataConnectionState = AGPS_DATA_CONNECTION_OPEN; 987b362a9ab91bb4c05ef1d5c4e7019499257c7f849Mike Lockwood } else { 988b362a9ab91bb4c05ef1d5c4e7019499257c7f849Mike Lockwood Log.e(TAG, "mAGpsApn not set when receiving Phone.APN_ALREADY_ACTIVE"); 989b362a9ab91bb4c05ef1d5c4e7019499257c7f849Mike Lockwood native_agps_data_conn_failed(); 990b362a9ab91bb4c05ef1d5c4e7019499257c7f849Mike Lockwood } 99158bda987665af759c379cd494ff4873ac61acf29Mike Lockwood } else if (result == Phone.APN_REQUEST_STARTED) { 992e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood mAGpsDataConnectionState = AGPS_DATA_CONNECTION_OPENING; 99358bda987665af759c379cd494ff4873ac61acf29Mike Lockwood } else { 994e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood native_agps_data_conn_failed(); 99558bda987665af759c379cd494ff4873ac61acf29Mike Lockwood } 99658bda987665af759c379cd494ff4873ac61acf29Mike Lockwood break; 997e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood case GPS_RELEASE_AGPS_DATA_CONN: 998e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood if (mAGpsDataConnectionState != AGPS_DATA_CONNECTION_CLOSED) { 99958bda987665af759c379cd494ff4873ac61acf29Mike Lockwood mConnMgr.stopUsingNetworkFeature( 100058bda987665af759c379cd494ff4873ac61acf29Mike Lockwood ConnectivityManager.TYPE_MOBILE, Phone.FEATURE_ENABLE_SUPL); 1001e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood native_agps_data_conn_closed(); 1002e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood mAGpsDataConnectionState = AGPS_DATA_CONNECTION_CLOSED; 100358bda987665af759c379cd494ff4873ac61acf29Mike Lockwood } 100458bda987665af759c379cd494ff4873ac61acf29Mike Lockwood break; 1005e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood case GPS_AGPS_DATA_CONNECTED: 1006e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood // Log.d(TAG, "GPS_AGPS_DATA_CONNECTED"); 100758bda987665af759c379cd494ff4873ac61acf29Mike Lockwood break; 1008e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood case GPS_AGPS_DATA_CONN_DONE: 1009e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood // Log.d(TAG, "GPS_AGPS_DATA_CONN_DONE"); 101058bda987665af759c379cd494ff4873ac61acf29Mike Lockwood break; 1011e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood case GPS_AGPS_DATA_CONN_FAILED: 1012e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood // Log.d(TAG, "GPS_AGPS_DATA_CONN_FAILED"); 101358bda987665af759c379cd494ff4873ac61acf29Mike Lockwood break; 101458bda987665af759c379cd494ff4873ac61acf29Mike Lockwood } 101558bda987665af759c379cd494ff4873ac61acf29Mike Lockwood } 101658bda987665af759c379cd494ff4873ac61acf29Mike Lockwood 1017b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood /** 1018b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood * called from native code to report NMEA data received 1019b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood */ 1020b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood private void reportNmea(int index, long timestamp) { 1021b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood synchronized(mListeners) { 1022b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood int size = mListeners.size(); 1023b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood if (size > 0) { 1024b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood // don't bother creating the String if we have no listeners 1025b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood int length = native_read_nmea(index, mNmeaBuffer, mNmeaBuffer.length); 1026b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood String nmea = new String(mNmeaBuffer, 0, length); 1027b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood 1028b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood for (int i = 0; i < size; i++) { 1029b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood Listener listener = mListeners.get(i); 1030b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood try { 1031b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood listener.mListener.onNmeaReceived(timestamp, nmea); 1032b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood } catch (RemoteException e) { 1033b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood Log.w(TAG, "RemoteException in reportNmea"); 1034b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood mListeners.remove(listener); 1035b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood // adjust for size of list changing 1036b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood size--; 1037b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood } 1038b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood } 1039b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood } 1040b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood } 1041b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood } 1042b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood 10439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void xtraDownloadRequest() { 10449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Config.LOGD) Log.d(TAG, "xtraDownloadRequest"); 10459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mNetworkThread != null) { 10469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNetworkThread.xtraDownloadRequest(); 10479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private class GpsEventThread extends Thread { 10519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public GpsEventThread() { 10539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super("GpsEventThread"); 10549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void run() { 10579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Config.LOGD) Log.d(TAG, "GpsEventThread starting"); 1058d654f9f727b415b153c7190832db4b65f6943f32Mike Lockwood // Exit as soon as disable() is called instead of waiting for the GPS to stop. 1059d654f9f727b415b153c7190832db4b65f6943f32Mike Lockwood while (mEnabled) { 10609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // this will wait for an event from the GPS, 10619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // which will be reported via reportLocation or reportStatus 10629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project native_wait_for_event(); 10639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Config.LOGD) Log.d(TAG, "GpsEventThread exiting"); 10659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private class GpsNetworkThread extends Thread { 10699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private long mNextNtpTime = 0; 10719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private long mNextXtraTime = 0; 107293bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood private boolean mTimeInjectRequested = false; 10739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mXtraDownloadRequested = false; 10749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mDone = false; 10759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public GpsNetworkThread() { 10779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super("GpsNetworkThread"); 10789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void run() { 10819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mNetworkThreadLock) { 10829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mDone) { 10839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project runLocked(); 10849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void runLocked() { 10899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Config.LOGD) Log.d(TAG, "NetworkThread starting"); 10909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SntpClient client = new SntpClient(); 10929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project GpsXtraDownloader xtraDownloader = null; 10939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (native_supports_xtra()) { 10959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project xtraDownloader = new GpsXtraDownloader(mContext, mProperties); 10969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // thread exits after disable() is called 10999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (!mDone) { 11009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long waitTime = getWaitTime(); 11019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project do { 11029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (this) { 11039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 11049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mNetworkAvailable) { 11059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Config.LOGD) Log.d(TAG, 11069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "NetworkThread wait for network"); 11079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project wait(); 11089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (waitTime > 0) { 11099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Config.LOGD) { 11109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.d(TAG, "NetworkThread wait for " + 11119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project waitTime + "ms"); 11129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project wait(waitTime); 11149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (InterruptedException e) { 11169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Config.LOGD) { 11179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.d(TAG, "InterruptedException in GpsNetworkThread"); 11189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project waitTime = getWaitTime(); 1122e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood } while (!mDone && ((!mXtraDownloadRequested && 1123a9e546169b3c2c9c5f248d2f3abe3b934f48695dMike Lockwood !mTimeInjectRequested && waitTime > 0) 11249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project || !mNetworkAvailable)); 11259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Config.LOGD) Log.d(TAG, "NetworkThread out of wake loop"); 11269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mDone) { 11289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mNtpServer != null && 112993bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood (mTimeInjectRequested || mNextNtpTime <= System.currentTimeMillis())) { 11309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Config.LOGD) { 11319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.d(TAG, "Requesting time from NTP server " + mNtpServer); 11329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 113393bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood mTimeInjectRequested = false; 11349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (client.requestTime(mNtpServer, 10000)) { 11359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long time = client.getNtpTime(); 11369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long timeReference = client.getNtpTimeReference(); 11379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int certainty = (int)(client.getRoundTripTime()/2); 11389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Config.LOGD) Log.d(TAG, "calling native_inject_time: " + 11409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project time + " reference: " + timeReference 11419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + " certainty: " + certainty); 11429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project native_inject_time(time, timeReference, certainty); 11449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNextNtpTime = System.currentTimeMillis() + NTP_INTERVAL; 11459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 11469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Config.LOGD) Log.d(TAG, "requestTime failed"); 11479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNextNtpTime = System.currentTimeMillis() + RETRY_INTERVAL; 11489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((mXtraDownloadRequested || 11529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (mNextXtraTime > 0 && mNextXtraTime <= System.currentTimeMillis())) 11539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project && xtraDownloader != null) { 115493bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood mXtraDownloadRequested = false; 11559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project byte[] data = xtraDownloader.downloadXtraData(); 11569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (data != null) { 11579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Config.LOGD) { 11589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.d(TAG, "calling native_inject_xtra_data"); 11599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project native_inject_xtra_data(data, data.length); 11619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNextXtraTime = 0; 11629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 11639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNextXtraTime = System.currentTimeMillis() + RETRY_INTERVAL; 11649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Config.LOGD) Log.d(TAG, "NetworkThread exiting"); 11699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized void xtraDownloadRequest() { 11729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mXtraDownloadRequested = true; 11739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project notify(); 11749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 117693bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood synchronized void timeInjectRequest() { 117793bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood mTimeInjectRequested = true; 117893bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood notify(); 117993bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood } 118093bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood 11819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized void signal() { 11829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project notify(); 11839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized void setDone() { 11869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Config.LOGD) Log.d(TAG, "stopping NetworkThread"); 11879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDone = true; 11889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project notify(); 11899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private long getWaitTime() { 11929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long now = System.currentTimeMillis(); 11939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long waitTime = Long.MAX_VALUE; 11949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mNtpServer != null) { 11959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project waitTime = mNextNtpTime - now; 11969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mNextXtraTime != 0) { 11989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long xtraWaitTime = mNextXtraTime - now; 11999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (xtraWaitTime < waitTime) { 12009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project waitTime = xtraWaitTime; 12019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (waitTime < 0) { 12049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project waitTime = 0; 12059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return waitTime; 12079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // for GPS SV statistics 12119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int MAX_SVS = 32; 12129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int EPHEMERIS_MASK = 0; 12139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int ALMANAC_MASK = 1; 12149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int USED_FOR_FIX_MASK = 2; 12159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // preallocated arrays, to avoid memory allocation in reportStatus() 12179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mSvs[] = new int[MAX_SVS]; 12189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private float mSnrs[] = new float[MAX_SVS]; 12199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private float mSvElevations[] = new float[MAX_SVS]; 12209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private float mSvAzimuths[] = new float[MAX_SVS]; 12219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mSvMasks[] = new int[3]; 12229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mSvCount; 1223b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood // preallocated to avoid memory allocation in reportNmea() 1224b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood private byte[] mNmeaBuffer = new byte[120]; 12259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static { class_init_native(); } 12279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static native void class_init_native(); 12289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static native boolean native_is_supported(); 12299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native boolean native_init(); 12319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native void native_disable(); 12329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native void native_cleanup(); 1233105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project private native boolean native_start(int positionMode, boolean singleFix, int fixInterval); 12349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native boolean native_stop(); 12359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native void native_set_fix_frequency(int fixFrequency); 12369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native void native_delete_aiding_data(int flags); 12379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native void native_wait_for_event(); 12389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // returns number of SVs 12399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // mask[0] is ephemeris mask and mask[1] is almanac mask 12409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native int native_read_sv_status(int[] svs, float[] snrs, 12419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float[] elevations, float[] azimuths, int[] masks); 1242b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood private native int native_read_nmea(int index, byte[] buffer, int bufferSize); 1243d26ce0d903f5141a346d67b2b94437ef3e2880aaMike Lockwood private native void native_inject_location(double latitude, double longitude, float accuracy); 1244d26ce0d903f5141a346d67b2b94437ef3e2880aaMike Lockwood 12459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // XTRA Support 12469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native void native_inject_time(long time, long timeReference, int uncertainty); 12479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native boolean native_supports_xtra(); 12489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native void native_inject_xtra_data(byte[] data, int length); 1249105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project 1250e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood // AGPS Support 1251e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood private native void native_agps_data_conn_open(String apn); 1252e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood private native void native_agps_data_conn_closed(); 1253e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood private native void native_agps_data_conn_failed(); 1254a9e546169b3c2c9c5f248d2f3abe3b934f48695dMike Lockwood private native void native_set_agps_server(int type, String hostname, int port); 12559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1256