GpsLocationProvider.java revision a9e546169b3c2c9c5f248d2f3abe3b934f48695d
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; 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Config; 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Log; 432f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwoodimport android.util.SparseIntArray; 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 452f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwoodimport com.android.internal.app.IBatteryStats; 46105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Projectimport com.android.internal.telephony.Phone; 47105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Projectimport com.android.internal.telephony.TelephonyIntents; 48105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.File; 509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.FileInputStream; 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.IOException; 52105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Projectimport java.net.InetAddress; 53105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Projectimport java.net.UnknownHostException; 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.ArrayList; 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.Properties; 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * A GPS implementation of LocationProvider used by LocationManager. 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@hide} 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6215e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwoodpublic class GpsLocationProvider extends ILocationProvider.Stub { 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final String TAG = "GpsLocationProvider"; 6529c84340a14e70419449628ab193d11b7a609e9aMike Lockwood 6629c84340a14e70419449628ab193d11b7a609e9aMike Lockwood private static final boolean DEBUG = true; 6729c84340a14e70419449628ab193d11b7a609e9aMike Lockwood private static final boolean VERBOSE = false; 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Broadcast intent action indicating that the GPS has either been 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * enabled or disabled. An intent extra provides this state as a boolean, 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * where {@code true} means enabled. 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #EXTRA_ENABLED 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@hide} 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final String GPS_ENABLED_CHANGE_ACTION = 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "android.location.GPS_ENABLED_CHANGE"; 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Broadcast intent action indicating that the GPS has either started or 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * stopped receiving GPS fixes. An intent extra provides this state as a 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * boolean, where {@code true} means that the GPS is actively receiving fixes. 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #EXTRA_ENABLED 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@hide} 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final String GPS_FIX_CHANGE_ACTION = 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "android.location.GPS_FIX_CHANGE"; 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The lookup key for a boolean that indicates whether GPS is enabled or 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * disabled. {@code true} means GPS is enabled. Retrieve it with 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link android.content.Intent#getBooleanExtra(String,boolean)}. 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@hide} 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final String EXTRA_ENABLED = "enabled"; 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 100105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project // these need to match GpsPositionMode enum in gps.h 101105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project private static final int GPS_POSITION_MODE_STANDALONE = 0; 102105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project private static final int GPS_POSITION_MODE_MS_BASED = 1; 103105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project private static final int GPS_POSITION_MODE_MS_ASSISTED = 2; 104105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // these need to match GpsStatusValue defines in gps.h 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_STATUS_NONE = 0; 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_STATUS_SESSION_BEGIN = 1; 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_STATUS_SESSION_END = 2; 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_STATUS_ENGINE_ON = 3; 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_STATUS_ENGINE_OFF = 4; 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 112e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood // these need to match GpsApgsStatusValue defines in gps.h 113e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood /** AGPS status event values. */ 114e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood private static final int GPS_REQUEST_AGPS_DATA_CONN = 1; 115e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood private static final int GPS_RELEASE_AGPS_DATA_CONN = 2; 116e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood private static final int GPS_AGPS_DATA_CONNECTED = 3; 117e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood private static final int GPS_AGPS_DATA_CONN_DONE = 4; 118e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood private static final int GPS_AGPS_DATA_CONN_FAILED = 5; 11958bda987665af759c379cd494ff4873ac61acf29Mike Lockwood 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // these need to match GpsLocationFlags enum in gps.h 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int LOCATION_INVALID = 0; 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int LOCATION_HAS_LAT_LONG = 1; 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int LOCATION_HAS_ALTITUDE = 2; 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int LOCATION_HAS_SPEED = 4; 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int LOCATION_HAS_BEARING = 8; 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int LOCATION_HAS_ACCURACY = 16; 127e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood 128e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood// IMPORTANT - the GPS_DELETE_* symbols here must match constants in gps.h 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_DELETE_EPHEMERIS = 0x0001; 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_DELETE_ALMANAC = 0x0002; 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_DELETE_POSITION = 0x0004; 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_DELETE_TIME = 0x0008; 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_DELETE_IONO = 0x0010; 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_DELETE_UTC = 0x0020; 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_DELETE_HEALTH = 0x0040; 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_DELETE_SVDIR = 0x0080; 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_DELETE_SVSTEER = 0x0100; 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_DELETE_SADATA = 0x0200; 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_DELETE_RTI = 0x0400; 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_DELETE_CELLDB_INFO = 0x8000; 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_DELETE_ALL = 0xFFFF; 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 143e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood // these need to match AGpsType enum in gps.h 144e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood private static final int AGPS_TYPE_SUPL = 1; 145e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood private static final int AGPS_TYPE_C2K = 2; 146e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood 147e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood // for mAGpsDataConnectionState 148e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood private static final int AGPS_DATA_CONNECTION_CLOSED = 0; 149e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood private static final int AGPS_DATA_CONNECTION_OPENING = 1; 150e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood private static final int AGPS_DATA_CONNECTION_OPEN = 2; 15158bda987665af759c379cd494ff4873ac61acf29Mike Lockwood 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final String PROPERTIES_FILE = "/etc/gps.conf"; 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mLocationFlags = LOCATION_INVALID; 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // current status 15715e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood private int mStatus = LocationProvider.TEMPORARILY_UNAVAILABLE; 1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // time for last status update 1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private long mStatusUpdateTime = SystemClock.elapsedRealtime(); 1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // turn off GPS fix icon if we haven't received a fix in 10 seconds 1630632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood private static final long RECENT_FIX_TIMEOUT = 10; 16429c84340a14e70419449628ab193d11b7a609e9aMike Lockwood 16529c84340a14e70419449628ab193d11b7a609e9aMike Lockwood // number of fixes to receive before disabling GPS 16629c84340a14e70419449628ab193d11b7a609e9aMike Lockwood private static final int MIN_FIX_COUNT = 10; 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1680632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood // stop trying if we do not receive a fix within 60 seconds 1690632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood private static final int NO_FIX_TIMEOUT = 60; 1700632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood 1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // true if we are enabled 1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mEnabled; 1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // true if we have network connectivity 1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mNetworkAvailable; 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // true if GPS is navigating 1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mNavigating; 1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // requested frequency of fixes, in seconds 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mFixInterval = 1; 1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 18329c84340a14e70419449628ab193d11b7a609e9aMike Lockwood // number of fixes we have received since we started navigating 18429c84340a14e70419449628ab193d11b7a609e9aMike Lockwood private int mFixCount; 18529c84340a14e70419449628ab193d11b7a609e9aMike Lockwood 186105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project private int mPositionMode = GPS_POSITION_MODE_STANDALONE; 187105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // true if we started navigation 1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mStarted; 1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // for calculating time to first fix 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private long mFixRequestTime = 0; 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // time to first fix for most recent session 1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mTTFF = 0; 1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // time we received our last fix 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private long mLastFixTime; 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // properties loaded from PROPERTIES_FILE 1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Properties mProperties; 2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private String mNtpServer; 2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 20215e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood private final Context mContext; 20315e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood private final ILocationManager mLocationManager; 2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Location mLocation = new Location(LocationManager.GPS_PROVIDER); 2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Bundle mLocationExtras = new Bundle(); 2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private ArrayList<Listener> mListeners = new ArrayList<Listener>(); 2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private GpsEventThread mEventThread; 2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private GpsNetworkThread mNetworkThread; 2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Object mNetworkThreadLock = new Object(); 210105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project 211e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood private String mAGpsApn; 212e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood private int mAGpsDataConnectionState; 2132f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood private final ConnectivityManager mConnMgr; 2142f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood 2150528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood // Wakelocks 2160528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood private final static String WAKELOCK_KEY = "GpsLocationProvider"; 2170528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood private final PowerManager.WakeLock mWakeLock; 2180528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood 21929c84340a14e70419449628ab193d11b7a609e9aMike Lockwood // Alarms 22029c84340a14e70419449628ab193d11b7a609e9aMike Lockwood private final static String ALARM_WAKEUP = "com.android.internal.location.ALARM_WAKEUP"; 2210632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood private final static String ALARM_TIMEOUT = "com.android.internal.location.ALARM_TIMEOUT"; 22229c84340a14e70419449628ab193d11b7a609e9aMike Lockwood private final AlarmManager mAlarmManager; 22329c84340a14e70419449628ab193d11b7a609e9aMike Lockwood private final PendingIntent mWakeupIntent; 2240632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood private final PendingIntent mTimeoutIntent; 22529c84340a14e70419449628ab193d11b7a609e9aMike Lockwood 2262f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood private final IBatteryStats mBatteryStats; 2272f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood private final SparseIntArray mClientUids = new SparseIntArray(); 228105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project 2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // how often to request NTP time, in milliseconds 2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // current setting 4 hours 2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final long NTP_INTERVAL = 4*60*60*1000; 2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // how long to wait if we have a network error in NTP or XTRA downloading 2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // current setting - 5 minutes 2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final long RETRY_INTERVAL = 5*60*1000; 2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 23615e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood private final IGpsStatusProvider mGpsStatusProvider = new IGpsStatusProvider.Stub() { 23715e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood public void addGpsStatusListener(IGpsStatusListener listener) throws RemoteException { 23815e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood if (listener == null) { 23915e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood throw new NullPointerException("listener is null in addGpsStatusListener"); 24015e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 24115e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood 24215e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood synchronized(mListeners) { 24315e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood IBinder binder = listener.asBinder(); 24415e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood int size = mListeners.size(); 24515e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood for (int i = 0; i < size; i++) { 24615e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood Listener test = mListeners.get(i); 24715e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood if (binder.equals(test.mListener.asBinder())) { 24815e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood // listener already added 24915e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood return; 25015e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 25115e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 25215e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood 25315e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood Listener l = new Listener(listener); 25415e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood binder.linkToDeath(l, 0); 25515e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood mListeners.add(l); 25615e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 25715e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 25815e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood 25915e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood public void removeGpsStatusListener(IGpsStatusListener listener) { 26015e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood if (listener == null) { 26115e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood throw new NullPointerException("listener is null in addGpsStatusListener"); 26215e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 26315e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood 26415e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood synchronized(mListeners) { 26515e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood IBinder binder = listener.asBinder(); 26615e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood Listener l = null; 26715e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood int size = mListeners.size(); 26815e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood for (int i = 0; i < size && l == null; i++) { 26915e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood Listener test = mListeners.get(i); 27015e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood if (binder.equals(test.mListener.asBinder())) { 27115e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood l = test; 27215e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 27315e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 27415e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood 27515e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood if (l != null) { 27615e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood mListeners.remove(l); 27715e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood binder.unlinkToDeath(l, 0); 27815e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 27915e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 28015e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 28115e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood }; 28215e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood 28315e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood public IGpsStatusProvider getGpsStatusProvider() { 28415e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood return mGpsStatusProvider; 28515e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 28615e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood 28729c84340a14e70419449628ab193d11b7a609e9aMike Lockwood private final BroadcastReceiver mBroadcastReciever = new BroadcastReceiver() { 288105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project @Override public void onReceive(Context context, Intent intent) { 289105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project String action = intent.getAction(); 290105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project 29129c84340a14e70419449628ab193d11b7a609e9aMike Lockwood if (action.equals(ALARM_WAKEUP)) { 29229c84340a14e70419449628ab193d11b7a609e9aMike Lockwood if (DEBUG) Log.d(TAG, "ALARM_WAKEUP"); 29329c84340a14e70419449628ab193d11b7a609e9aMike Lockwood startNavigating(); 2940632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood } else if (action.equals(ALARM_TIMEOUT)) { 2950632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood if (DEBUG) Log.d(TAG, "ALARM_TIMEOUT"); 2960632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood hibernate(); 29729c84340a14e70419449628ab193d11b7a609e9aMike Lockwood } else if (action.equals(TelephonyIntents.ACTION_ANY_DATA_CONNECTION_STATE_CHANGED)) { 298105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project String state = intent.getStringExtra(Phone.STATE_KEY); 299105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project String apnName = intent.getStringExtra(Phone.DATA_APN_KEY); 300105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project String reason = intent.getStringExtra(Phone.STATE_CHANGE_REASON_KEY); 301105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project 302105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project if (Config.LOGD) { 303105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project Log.d(TAG, "state: " + state + " apnName: " + apnName + " reason: " + reason); 304105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project } 305e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood // FIXME - might not have an APN on CDMA 306375cbb47ff721a26b62385211b82a7cf26db0395Mike Lockwood if ("CONNECTED".equals(state) && apnName != null && apnName.length() > 0) { 307e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood mAGpsApn = apnName; 308e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood if (mAGpsDataConnectionState == AGPS_DATA_CONNECTION_OPENING) { 309e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood native_agps_data_conn_open(mAGpsApn); 310e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood mAGpsDataConnectionState = AGPS_DATA_CONNECTION_OPEN; 31158bda987665af759c379cd494ff4873ac61acf29Mike Lockwood } 312105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project } 313105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project } 314105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project } 31529c84340a14e70419449628ab193d11b7a609e9aMike Lockwood }; 316105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project 3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static boolean isSupported() { 3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return native_is_supported(); 3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3214e50b78bda9cd58be61581d2886c88ff6348a1c1Mike Lockwood public GpsLocationProvider(Context context, ILocationManager locationManager) { 3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContext = context; 32315e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood mLocationManager = locationManager; 3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3250528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood // Create a wake lock 3260528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood PowerManager powerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE); 3270528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, WAKELOCK_KEY); 3280528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood 32929c84340a14e70419449628ab193d11b7a609e9aMike Lockwood mAlarmManager = (AlarmManager)mContext.getSystemService(Context.ALARM_SERVICE); 33029c84340a14e70419449628ab193d11b7a609e9aMike Lockwood mWakeupIntent = PendingIntent.getBroadcast(mContext, 0, new Intent(ALARM_WAKEUP), 0); 3310632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood mTimeoutIntent = PendingIntent.getBroadcast(mContext, 0, new Intent(ALARM_TIMEOUT), 0); 33229c84340a14e70419449628ab193d11b7a609e9aMike Lockwood 333105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project IntentFilter intentFilter = new IntentFilter(); 33429c84340a14e70419449628ab193d11b7a609e9aMike Lockwood intentFilter.addAction(ALARM_WAKEUP); 3350632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood intentFilter.addAction(ALARM_TIMEOUT); 336105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project intentFilter.addAction(TelephonyIntents.ACTION_ANY_DATA_CONNECTION_STATE_CHANGED); 33729c84340a14e70419449628ab193d11b7a609e9aMike Lockwood context.registerReceiver(mBroadcastReciever, intentFilter); 338105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project 33958bda987665af759c379cd494ff4873ac61acf29Mike Lockwood mConnMgr = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE); 34058bda987665af759c379cd494ff4873ac61acf29Mike Lockwood 3412f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood // Battery statistics service to be notified when GPS turns on or off 3422f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood mBatteryStats = IBatteryStats.Stub.asInterface(ServiceManager.getService("batteryinfo")); 3432f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood 3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mProperties = new Properties(); 3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project File file = new File(PROPERTIES_FILE); 3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project FileInputStream stream = new FileInputStream(file); 3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mProperties.load(stream); 3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project stream.close(); 3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNtpServer = mProperties.getProperty("NTP_SERVER", null); 351e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood 352a9e546169b3c2c9c5f248d2f3abe3b934f48695dMike Lockwood String host = mProperties.getProperty("SUPL_HOST"); 353e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood String portString = mProperties.getProperty("SUPL_PORT"); 354a9e546169b3c2c9c5f248d2f3abe3b934f48695dMike Lockwood if (host != null && portString != null) { 355105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project try { 356a9e546169b3c2c9c5f248d2f3abe3b934f48695dMike Lockwood int port = Integer.parseInt(portString); 357a9e546169b3c2c9c5f248d2f3abe3b934f48695dMike Lockwood native_set_agps_server(AGPS_TYPE_SUPL, host, port); 358a9e546169b3c2c9c5f248d2f3abe3b934f48695dMike Lockwood // use MS-Based position mode if SUPL support is enabled 359a9e546169b3c2c9c5f248d2f3abe3b934f48695dMike Lockwood mPositionMode = GPS_POSITION_MODE_MS_BASED; 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 365a9e546169b3c2c9c5f248d2f3abe3b934f48695dMike Lockwood host = mProperties.getProperty("C2K_HOST"); 366e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood portString = mProperties.getProperty("C2K_PORT"); 367a9e546169b3c2c9c5f248d2f3abe3b934f48695dMike Lockwood if (host != null && portString != null) { 368e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood try { 369a9e546169b3c2c9c5f248d2f3abe3b934f48695dMike Lockwood int port = Integer.parseInt(portString); 370a9e546169b3c2c9c5f248d2f3abe3b934f48695dMike Lockwood native_set_agps_server(AGPS_TYPE_C2K, host, port); 371a9e546169b3c2c9c5f248d2f3abe3b934f48695dMike Lockwood // use MS-Based position mode if SUPL support is enabled 372a9e546169b3c2c9c5f248d2f3abe3b934f48695dMike Lockwood mPositionMode = GPS_POSITION_MODE_MS_BASED; 373e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood } catch (NumberFormatException e) { 374e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood Log.e(TAG, "unable to parse C2K_PORT: " + portString); 375105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project } 376105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project } 3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (IOException e) { 3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.w(TAG, "Could not open GPS configuration file " + PROPERTIES_FILE); 3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns true if the provider requires access to a 3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * data network (e.g., the Internet), false otherwise. 3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean requiresNetwork() { 387a9e546169b3c2c9c5f248d2f3abe3b934f48695dMike Lockwood return true; 3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void updateNetworkState(int state) { 3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNetworkAvailable = (state == LocationProvider.AVAILABLE); 3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Config.LOGD) { 3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.d(TAG, "updateNetworkState " + (mNetworkAvailable ? "available" : "unavailable")); 3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mNetworkAvailable && mNetworkThread != null && mEnabled) { 3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // signal the network thread when the network becomes available 3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNetworkThread.signal(); 4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 404fd6e5f0dda50e113db4ccc55338b6c4f09da37a4Mike Lockwood * This is called to inform us when another location provider returns a location. 405fd6e5f0dda50e113db4ccc55338b6c4f09da37a4Mike Lockwood * Someday we might use this for network location injection to aid the GPS 406fd6e5f0dda50e113db4ccc55338b6c4f09da37a4Mike Lockwood */ 407fd6e5f0dda50e113db4ccc55338b6c4f09da37a4Mike Lockwood public void updateLocation(Location location) { 408d26ce0d903f5141a346d67b2b94437ef3e2880aaMike Lockwood if (location.hasAccuracy()) { 409d26ce0d903f5141a346d67b2b94437ef3e2880aaMike Lockwood native_inject_location(location.getLatitude(), location.getLongitude(), 410d26ce0d903f5141a346d67b2b94437ef3e2880aaMike Lockwood location.getAccuracy()); 411d26ce0d903f5141a346d67b2b94437ef3e2880aaMike Lockwood } 412fd6e5f0dda50e113db4ccc55338b6c4f09da37a4Mike Lockwood } 413fd6e5f0dda50e113db4ccc55338b6c4f09da37a4Mike Lockwood 414fd6e5f0dda50e113db4ccc55338b6c4f09da37a4Mike Lockwood /** 4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns true if the provider requires access to a 4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * satellite-based positioning system (e.g., GPS), false 4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * otherwise. 4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean requiresSatellite() { 4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns true if the provider requires access to an appropriate 4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * cellular network (e.g., to make use of cell tower IDs), false 4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * otherwise. 4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean requiresCell() { 4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns true if the use of this provider may result in a 4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * monetary charge to the user, false if use is free. It is up to 4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * each provider to give accurate information. 4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean hasMonetaryCost() { 4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns true if the provider is able to provide altitude 4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * information, false otherwise. A provider that reports altitude 4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * under most circumstances but may occassionally not report it 4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * should return true. 4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean supportsAltitude() { 4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns true if the provider is able to provide speed 4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * information, false otherwise. A provider that reports speed 4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * under most circumstances but may occassionally not report it 4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * should return true. 4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean supportsSpeed() { 4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns true if the provider is able to provide bearing 4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * information, false otherwise. A provider that reports bearing 4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * under most circumstances but may occassionally not report it 4659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * should return true. 4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean supportsBearing() { 4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns the power requirement for this provider. 4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the power requirement for this provider, as one of the 4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * constants Criteria.POWER_REQUIREMENT_*. 4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getPowerRequirement() { 4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return Criteria.POWER_HIGH; 4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns the horizontal accuracy of this provider 4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the accuracy of location from this provider, as one 4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * of the constants Criteria.ACCURACY_*. 4869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getAccuracy() { 4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return Criteria.ACCURACY_FINE; 4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Enables this provider. When enabled, calls to getStatus() 4934e50b78bda9cd58be61581d2886c88ff6348a1c1Mike Lockwood * must be handled. Hardware may be started up 4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * when the provider is enabled. 4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public synchronized void enable() { 4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Config.LOGD) Log.d(TAG, "enable"); 4989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mEnabled) return; 4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEnabled = native_init(); 5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mEnabled) { 5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // run event listener thread while we are enabled 5039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEventThread = new GpsEventThread(); 5049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEventThread.start(); 5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (requiresNetwork()) { 5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // run network thread for NTP and XTRA support 5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mNetworkThread == null) { 5099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNetworkThread = new GpsNetworkThread(); 5109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNetworkThread.start(); 5119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 5129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNetworkThread.signal(); 5139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.w(TAG, "Failed to enable location provider"); 5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Disables this provider. When disabled, calls to getStatus() 5224e50b78bda9cd58be61581d2886c88ff6348a1c1Mike Lockwood * need not be handled. Hardware may be shut 5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * down while the provider is disabled. 5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public synchronized void disable() { 5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Config.LOGD) Log.d(TAG, "disable"); 5279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mEnabled) return; 5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEnabled = false; 5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project stopNavigating(); 5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project native_disable(); 5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // make sure our event thread exits 5349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mEventThread != null) { 5359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 5369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEventThread.join(); 5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (InterruptedException e) { 5389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.w(TAG, "InterruptedException when joining mEventThread"); 5399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEventThread = null; 5419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mNetworkThread != null) { 5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNetworkThread.setDone(); 5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNetworkThread = null; 5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 548d654f9f727b415b153c7190832db4b65f6943f32Mike Lockwood // The GpsEventThread does not wait for the GPS to shutdown 549d654f9f727b415b153c7190832db4b65f6943f32Mike Lockwood // so we need to report the GPS_STATUS_ENGINE_OFF event here 550d654f9f727b415b153c7190832db4b65f6943f32Mike Lockwood if (mNavigating) { 551d654f9f727b415b153c7190832db4b65f6943f32Mike Lockwood reportStatus(GPS_STATUS_ENGINE_OFF); 552d654f9f727b415b153c7190832db4b65f6943f32Mike Lockwood } 553d654f9f727b415b153c7190832db4b65f6943f32Mike Lockwood 5549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project native_cleanup(); 5559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean isEnabled() { 5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mEnabled; 5599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getStatus(Bundle extras) { 5629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras != null) { 5639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project extras.putInt("satellites", mSvCount); 5649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mStatus; 5669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void updateStatus(int status, int svCount) { 5699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (status != mStatus || svCount != mSvCount) { 5709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStatus = status; 5719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSvCount = svCount; 5729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocationExtras.putInt("satellites", svCount); 5739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStatusUpdateTime = SystemClock.elapsedRealtime(); 5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public long getStatusUpdateTime() { 5789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mStatusUpdateTime; 5799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void enableLocationTracking(boolean enable) { 5829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (enable) { 5839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTTFF = 0; 5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLastFixTime = 0; 5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project startNavigating(); 5869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 58729c84340a14e70419449628ab193d11b7a609e9aMike Lockwood mAlarmManager.cancel(mWakeupIntent); 5880632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood mAlarmManager.cancel(mTimeoutIntent); 5899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project stopNavigating(); 5909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setMinTime(long minTime) { 5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Config.LOGD) Log.d(TAG, "setMinTime " + minTime); 5959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (minTime >= 0) { 5979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int interval = (int)(minTime/1000); 5989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (interval < 1) { 5999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project interval = 1; 6009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFixInterval = interval; 6029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final class Listener implements IBinder.DeathRecipient { 6069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final IGpsStatusListener mListener; 6079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int mSensors = 0; 6099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Listener(IGpsStatusListener listener) { 6119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mListener = listener; 6129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void binderDied() { 6159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Config.LOGD) Log.d(TAG, "GPS status listener died"); 6169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized(mListeners) { 6189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mListeners.remove(this); 6199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6232f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood public void addListener(int uid) { 6242f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood mClientUids.put(uid, 0); 6252f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood if (mNavigating) { 6262f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood try { 6272f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood mBatteryStats.noteStartGps(uid); 6282f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } catch (RemoteException e) { 6292f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood Log.w(TAG, "RemoteException in addListener"); 6302f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } 6312f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } 6322f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } 6332f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood 6342f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood public void removeListener(int uid) { 6352f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood mClientUids.delete(uid); 6362f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood if (mNavigating) { 6372f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood try { 6382f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood mBatteryStats.noteStopGps(uid); 6392f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } catch (RemoteException e) { 6402f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood Log.w(TAG, "RemoteException in removeListener"); 6412f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } 6422f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } 6432f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } 6442f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood 6459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean sendExtraCommand(String command, Bundle extras) { 6469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ("delete_aiding_data".equals(command)) { 6489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return deleteAidingData(extras); 6499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 65093bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood if ("force_time_injection".equals(command)) { 65193bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood return forceTimeInjection(); 65293bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood } 65393bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood if ("force_xtra_injection".equals(command)) { 65493bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood if (native_supports_xtra() && mNetworkThread != null) { 65593bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood xtraDownloadRequest(); 65693bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood return true; 65793bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood } 65893bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood return false; 65993bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood } 6609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.w(TAG, "sendExtraCommand: unknown command " + command); 6629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 6639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean deleteAidingData(Bundle extras) { 6669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int flags; 6679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras == null) { 6699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project flags = GPS_DELETE_ALL; 6709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 6719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project flags = 0; 6729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("ephemeris")) flags |= GPS_DELETE_EPHEMERIS; 6739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("almanac")) flags |= GPS_DELETE_ALMANAC; 6749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("position")) flags |= GPS_DELETE_POSITION; 6759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("time")) flags |= GPS_DELETE_TIME; 6769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("iono")) flags |= GPS_DELETE_IONO; 6779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("utc")) flags |= GPS_DELETE_UTC; 6789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("health")) flags |= GPS_DELETE_HEALTH; 6799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("svdir")) flags |= GPS_DELETE_SVDIR; 6809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("svsteer")) flags |= GPS_DELETE_SVSTEER; 6819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("sadata")) flags |= GPS_DELETE_SADATA; 6829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("rti")) flags |= GPS_DELETE_RTI; 6839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("celldb-info")) flags |= GPS_DELETE_CELLDB_INFO; 6849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("all")) flags |= GPS_DELETE_ALL; 6859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (flags != 0) { 6889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project native_delete_aiding_data(flags); 6899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 6909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 6939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 69593bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood private boolean forceTimeInjection() { 69693bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood if (Config.LOGD) Log.d(TAG, "forceTimeInjection"); 69793bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood if (mNetworkThread != null) { 69893bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood mNetworkThread.timeInjectRequest(); 69993bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood return true; 70093bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood } 70193bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood return false; 70293bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood } 70393bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood 7049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void startNavigating() { 7059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mStarted) { 70629c84340a14e70419449628ab193d11b7a609e9aMike Lockwood if (DEBUG) Log.d(TAG, "startNavigating"); 7079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStarted = true; 708105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project if (!native_start(mPositionMode, false, mFixInterval)) { 7099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStarted = false; 7109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.e(TAG, "native_start failed in startNavigating()"); 7110632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood return; 7129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // reset SV count to zero 71515e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood updateStatus(LocationProvider.TEMPORARILY_UNAVAILABLE, 0); 71629c84340a14e70419449628ab193d11b7a609e9aMike Lockwood mFixCount = 0; 71729c84340a14e70419449628ab193d11b7a609e9aMike Lockwood mFixRequestTime = System.currentTimeMillis(); 7180632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood // set timer to give up if we do not receive a fix within NO_FIX_TIMEOUT 7190632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood // and our fix interval is not short 7200632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood if (mFixInterval >= NO_FIX_TIMEOUT) { 7210632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, 7220632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood SystemClock.elapsedRealtime() + NO_FIX_TIMEOUT * 1000, mTimeoutIntent); 7230632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood } 7249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void stopNavigating() { 72829c84340a14e70419449628ab193d11b7a609e9aMike Lockwood if (DEBUG) Log.d(TAG, "stopNavigating"); 7299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mStarted) { 7309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStarted = false; 7319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project native_stop(); 7329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTTFF = 0; 7339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLastFixTime = 0; 7349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocationFlags = LOCATION_INVALID; 7359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // reset SV count to zero 73715e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood updateStatus(LocationProvider.TEMPORARILY_UNAVAILABLE, 0); 7389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7410632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood private void hibernate() { 7420632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood // stop GPS until our next fix interval arrives 7430632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood stopNavigating(); 7440632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood mFixCount = 0; 7450632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood mAlarmManager.cancel(mTimeoutIntent); 7460632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood mAlarmManager.cancel(mWakeupIntent); 7470632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood long now = SystemClock.elapsedRealtime(); 7480632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, 7490632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood SystemClock.elapsedRealtime() + mFixInterval * 1000, mWakeupIntent); 7500632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood } 7510632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood 7529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * called from native code to update our position. 7549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void reportLocation(int flags, double latitude, double longitude, double altitude, 7569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float speed, float bearing, float accuracy, long timestamp) { 75729c84340a14e70419449628ab193d11b7a609e9aMike Lockwood if (VERBOSE) Log.v(TAG, "reportLocation lat: " + latitude + " long: " + longitude + 7589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project " timestamp: " + timestamp); 7599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLastFixTime = System.currentTimeMillis(); 7619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // report time to first fix 7629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mTTFF == 0 && (flags & LOCATION_HAS_LAT_LONG) == LOCATION_HAS_LAT_LONG) { 7639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTTFF = (int)(mLastFixTime - mFixRequestTime); 7649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Config.LOGD) Log.d(TAG, "TTFF: " + mTTFF); 7659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // notify status listeners 7679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized(mListeners) { 7689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int size = mListeners.size(); 7699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < size; i++) { 7709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Listener listener = mListeners.get(i); 7719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 7729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project listener.mListener.onFirstFix(mTTFF); 7739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 7749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.w(TAG, "RemoteException in stopNavigating"); 7759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mListeners.remove(listener); 7769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // adjust for size of list changing 7779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size--; 7789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mLocation) { 7849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocationFlags = flags; 7859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((flags & LOCATION_HAS_LAT_LONG) == LOCATION_HAS_LAT_LONG) { 7869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocation.setLatitude(latitude); 7879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocation.setLongitude(longitude); 7889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocation.setTime(timestamp); 7899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((flags & LOCATION_HAS_ALTITUDE) == LOCATION_HAS_ALTITUDE) { 7919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocation.setAltitude(altitude); 7929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 7939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocation.removeAltitude(); 7949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((flags & LOCATION_HAS_SPEED) == LOCATION_HAS_SPEED) { 7969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocation.setSpeed(speed); 7979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 7989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocation.removeSpeed(); 7999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((flags & LOCATION_HAS_BEARING) == LOCATION_HAS_BEARING) { 8019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocation.setBearing(bearing); 8029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 8039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocation.removeBearing(); 8049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((flags & LOCATION_HAS_ACCURACY) == LOCATION_HAS_ACCURACY) { 8069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocation.setAccuracy(accuracy); 8079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 8089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocation.removeAccuracy(); 8099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 81115e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood try { 812275555c8eb3fb5df6e7320873b88b77cdde85a9eMike Lockwood mLocationManager.reportLocation(mLocation); 81315e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } catch (RemoteException e) { 81415e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood Log.e(TAG, "RemoteException calling reportLocation"); 81515e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 8169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 81815e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood if (mStarted && mStatus != LocationProvider.AVAILABLE) { 8190632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood mAlarmManager.cancel(mTimeoutIntent); 8209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // send an intent to notify that the GPS is receiving fixes. 8219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Intent intent = new Intent(GPS_FIX_CHANGE_ACTION); 8229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project intent.putExtra(EXTRA_ENABLED, true); 8239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContext.sendBroadcast(intent); 82415e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood updateStatus(LocationProvider.AVAILABLE, mSvCount); 8259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 82629c84340a14e70419449628ab193d11b7a609e9aMike Lockwood 82729c84340a14e70419449628ab193d11b7a609e9aMike Lockwood if (mFixCount++ >= MIN_FIX_COUNT && mFixInterval > 1) { 82829c84340a14e70419449628ab193d11b7a609e9aMike Lockwood if (DEBUG) Log.d(TAG, "exceeded MIN_FIX_COUNT"); 8290632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood hibernate(); 83029c84340a14e70419449628ab193d11b7a609e9aMike Lockwood } 8319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 8349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * called from native code to update our status 8359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 8369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void reportStatus(int status) { 83729c84340a14e70419449628ab193d11b7a609e9aMike Lockwood if (VERBOSE) Log.v(TAG, "reportStatus status: " + status); 8389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project boolean wasNavigating = mNavigating; 8409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNavigating = (status == GPS_STATUS_SESSION_BEGIN); 8419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (wasNavigating != mNavigating) { 8430528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood if (mNavigating) { 8440528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood if (DEBUG) Log.d(TAG, "Acquiring wakelock"); 8450528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood mWakeLock.acquire(); 8460528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood } 8479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized(mListeners) { 8489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int size = mListeners.size(); 8499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < size; i++) { 8509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Listener listener = mListeners.get(i); 8519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 8529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mNavigating) { 8539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project listener.mListener.onGpsStarted(); 8549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 8559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project listener.mListener.onGpsStopped(); 8569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 8589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.w(TAG, "RemoteException in reportStatus"); 8599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mListeners.remove(listener); 8609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // adjust for size of list changing 8619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size--; 8629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8662f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood try { 8672f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood // update battery stats 8682f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood for (int i=mClientUids.size() - 1; i >= 0; i--) { 8692f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood int uid = mClientUids.keyAt(i); 8702f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood if (mNavigating) { 8712f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood mBatteryStats.noteStartGps(uid); 8722f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } else { 8732f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood mBatteryStats.noteStopGps(uid); 8742f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } 8752f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } 8762f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } catch (RemoteException e) { 8772f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood Log.w(TAG, "RemoteException in reportStatus"); 8782f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } 8792f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood 8809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // send an intent to notify that the GPS has been enabled or disabled. 8819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Intent intent = new Intent(GPS_ENABLED_CHANGE_ACTION); 8829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project intent.putExtra(EXTRA_ENABLED, mNavigating); 8839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContext.sendBroadcast(intent); 8840528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood 8850528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood if (!mNavigating) { 8860528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood if (DEBUG) Log.d(TAG, "Releasing wakelock"); 8870528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood mWakeLock.release(); 8880528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood } 8899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 8939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * called from native code to update SV info 8949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 8959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void reportSvStatus() { 8969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int svCount = native_read_sv_status(mSvs, mSnrs, mSvElevations, mSvAzimuths, mSvMasks); 8989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized(mListeners) { 9009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int size = mListeners.size(); 9019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < size; i++) { 9029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Listener listener = mListeners.get(i); 9039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 9049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project listener.mListener.onSvStatusChanged(svCount, mSvs, mSnrs, 9059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSvElevations, mSvAzimuths, mSvMasks[EPHEMERIS_MASK], 9069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSvMasks[ALMANAC_MASK], mSvMasks[USED_FOR_FIX_MASK]); 9079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 9089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.w(TAG, "RemoteException in reportSvInfo"); 9099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mListeners.remove(listener); 9109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // adjust for size of list changing 9119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size--; 9129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 91629c84340a14e70419449628ab193d11b7a609e9aMike Lockwood if (VERBOSE) { 91729c84340a14e70419449628ab193d11b7a609e9aMike Lockwood Log.v(TAG, "SV count: " + svCount + 9189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project " ephemerisMask: " + Integer.toHexString(mSvMasks[EPHEMERIS_MASK]) + 9199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project " almanacMask: " + Integer.toHexString(mSvMasks[ALMANAC_MASK])); 9209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < svCount; i++) { 92129c84340a14e70419449628ab193d11b7a609e9aMike Lockwood Log.v(TAG, "sv: " + mSvs[i] + 9229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project " snr: " + (float)mSnrs[i]/10 + 9239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project " elev: " + mSvElevations[i] + 9249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project " azimuth: " + mSvAzimuths[i] + 9259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ((mSvMasks[EPHEMERIS_MASK] & (1 << (mSvs[i] - 1))) == 0 ? " " : " E") + 9269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ((mSvMasks[ALMANAC_MASK] & (1 << (mSvs[i] - 1))) == 0 ? " " : " A") + 9279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ((mSvMasks[USED_FOR_FIX_MASK] & (1 << (mSvs[i] - 1))) == 0 ? "" : "U")); 9289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project updateStatus(mStatus, svCount); 9329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 93315e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood if (mNavigating && mStatus == LocationProvider.AVAILABLE && mLastFixTime > 0 && 9340632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood System.currentTimeMillis() - mLastFixTime > RECENT_FIX_TIMEOUT * 1000) { 9359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // send an intent to notify that the GPS is no longer receiving fixes. 9369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Intent intent = new Intent(GPS_FIX_CHANGE_ACTION); 9379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project intent.putExtra(EXTRA_ENABLED, false); 9389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContext.sendBroadcast(intent); 93915e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood updateStatus(LocationProvider.TEMPORARILY_UNAVAILABLE, mSvCount); 9409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 94258bda987665af759c379cd494ff4873ac61acf29Mike Lockwood 94358bda987665af759c379cd494ff4873ac61acf29Mike Lockwood /** 944e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood * called from native code to update AGPS status 94558bda987665af759c379cd494ff4873ac61acf29Mike Lockwood */ 946e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood private void reportAGpsStatus(int type, int status) { 94758bda987665af759c379cd494ff4873ac61acf29Mike Lockwood switch (status) { 948e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood case GPS_REQUEST_AGPS_DATA_CONN: 94958bda987665af759c379cd494ff4873ac61acf29Mike Lockwood int result = mConnMgr.startUsingNetworkFeature( 95058bda987665af759c379cd494ff4873ac61acf29Mike Lockwood ConnectivityManager.TYPE_MOBILE, Phone.FEATURE_ENABLE_SUPL); 95158bda987665af759c379cd494ff4873ac61acf29Mike Lockwood if (result == Phone.APN_ALREADY_ACTIVE) { 952e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood native_agps_data_conn_open(mAGpsApn); 953e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood mAGpsDataConnectionState = AGPS_DATA_CONNECTION_OPEN; 95458bda987665af759c379cd494ff4873ac61acf29Mike Lockwood } else if (result == Phone.APN_REQUEST_STARTED) { 955e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood mAGpsDataConnectionState = AGPS_DATA_CONNECTION_OPENING; 95658bda987665af759c379cd494ff4873ac61acf29Mike Lockwood } else { 957e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood native_agps_data_conn_failed(); 95858bda987665af759c379cd494ff4873ac61acf29Mike Lockwood } 95958bda987665af759c379cd494ff4873ac61acf29Mike Lockwood break; 960e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood case GPS_RELEASE_AGPS_DATA_CONN: 961e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood if (mAGpsDataConnectionState != AGPS_DATA_CONNECTION_CLOSED) { 96258bda987665af759c379cd494ff4873ac61acf29Mike Lockwood mConnMgr.stopUsingNetworkFeature( 96358bda987665af759c379cd494ff4873ac61acf29Mike Lockwood ConnectivityManager.TYPE_MOBILE, Phone.FEATURE_ENABLE_SUPL); 964e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood native_agps_data_conn_closed(); 965e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood mAGpsDataConnectionState = AGPS_DATA_CONNECTION_CLOSED; 96658bda987665af759c379cd494ff4873ac61acf29Mike Lockwood } 96758bda987665af759c379cd494ff4873ac61acf29Mike Lockwood break; 968e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood case GPS_AGPS_DATA_CONNECTED: 969e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood // Log.d(TAG, "GPS_AGPS_DATA_CONNECTED"); 97058bda987665af759c379cd494ff4873ac61acf29Mike Lockwood break; 971e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood case GPS_AGPS_DATA_CONN_DONE: 972e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood // Log.d(TAG, "GPS_AGPS_DATA_CONN_DONE"); 97358bda987665af759c379cd494ff4873ac61acf29Mike Lockwood break; 974e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood case GPS_AGPS_DATA_CONN_FAILED: 975e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood // Log.d(TAG, "GPS_AGPS_DATA_CONN_FAILED"); 97658bda987665af759c379cd494ff4873ac61acf29Mike Lockwood break; 97758bda987665af759c379cd494ff4873ac61acf29Mike Lockwood } 97858bda987665af759c379cd494ff4873ac61acf29Mike Lockwood } 97958bda987665af759c379cd494ff4873ac61acf29Mike Lockwood 9809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void xtraDownloadRequest() { 9819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Config.LOGD) Log.d(TAG, "xtraDownloadRequest"); 9829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mNetworkThread != null) { 9839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNetworkThread.xtraDownloadRequest(); 9849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private class GpsEventThread extends Thread { 9889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public GpsEventThread() { 9909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super("GpsEventThread"); 9919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void run() { 9949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Config.LOGD) Log.d(TAG, "GpsEventThread starting"); 995d654f9f727b415b153c7190832db4b65f6943f32Mike Lockwood // Exit as soon as disable() is called instead of waiting for the GPS to stop. 996d654f9f727b415b153c7190832db4b65f6943f32Mike Lockwood while (mEnabled) { 9979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // this will wait for an event from the GPS, 9989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // which will be reported via reportLocation or reportStatus 9999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project native_wait_for_event(); 10009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Config.LOGD) Log.d(TAG, "GpsEventThread exiting"); 10029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private class GpsNetworkThread extends Thread { 10069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private long mNextNtpTime = 0; 10089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private long mNextXtraTime = 0; 100993bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood private boolean mTimeInjectRequested = false; 10109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mXtraDownloadRequested = false; 10119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mDone = false; 10129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public GpsNetworkThread() { 10149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super("GpsNetworkThread"); 10159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void run() { 10189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mNetworkThreadLock) { 10199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mDone) { 10209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project runLocked(); 10219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void runLocked() { 10269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Config.LOGD) Log.d(TAG, "NetworkThread starting"); 10279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SntpClient client = new SntpClient(); 10299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project GpsXtraDownloader xtraDownloader = null; 10309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (native_supports_xtra()) { 10329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project xtraDownloader = new GpsXtraDownloader(mContext, mProperties); 10339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // thread exits after disable() is called 10369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (!mDone) { 10379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long waitTime = getWaitTime(); 10389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project do { 10399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (this) { 10409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 10419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mNetworkAvailable) { 10429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Config.LOGD) Log.d(TAG, 10439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "NetworkThread wait for network"); 10449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project wait(); 10459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (waitTime > 0) { 10469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Config.LOGD) { 10479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.d(TAG, "NetworkThread wait for " + 10489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project waitTime + "ms"); 10499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project wait(waitTime); 10519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (InterruptedException e) { 10539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Config.LOGD) { 10549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.d(TAG, "InterruptedException in GpsNetworkThread"); 10559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project waitTime = getWaitTime(); 1059e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood } while (!mDone && ((!mXtraDownloadRequested && 1060a9e546169b3c2c9c5f248d2f3abe3b934f48695dMike Lockwood !mTimeInjectRequested && waitTime > 0) 10619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project || !mNetworkAvailable)); 10629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Config.LOGD) Log.d(TAG, "NetworkThread out of wake loop"); 10639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mDone) { 10659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mNtpServer != null && 106693bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood (mTimeInjectRequested || mNextNtpTime <= System.currentTimeMillis())) { 10679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Config.LOGD) { 10689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.d(TAG, "Requesting time from NTP server " + mNtpServer); 10699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 107093bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood mTimeInjectRequested = false; 10719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (client.requestTime(mNtpServer, 10000)) { 10729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long time = client.getNtpTime(); 10739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long timeReference = client.getNtpTimeReference(); 10749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int certainty = (int)(client.getRoundTripTime()/2); 10759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Config.LOGD) Log.d(TAG, "calling native_inject_time: " + 10779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project time + " reference: " + timeReference 10789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + " certainty: " + certainty); 10799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project native_inject_time(time, timeReference, certainty); 10819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNextNtpTime = System.currentTimeMillis() + NTP_INTERVAL; 10829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 10839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Config.LOGD) Log.d(TAG, "requestTime failed"); 10849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNextNtpTime = System.currentTimeMillis() + RETRY_INTERVAL; 10859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((mXtraDownloadRequested || 10899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (mNextXtraTime > 0 && mNextXtraTime <= System.currentTimeMillis())) 10909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project && xtraDownloader != null) { 109193bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood mXtraDownloadRequested = false; 10929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project byte[] data = xtraDownloader.downloadXtraData(); 10939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (data != null) { 10949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Config.LOGD) { 10959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.d(TAG, "calling native_inject_xtra_data"); 10969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project native_inject_xtra_data(data, data.length); 10989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNextXtraTime = 0; 10999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 11009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNextXtraTime = System.currentTimeMillis() + RETRY_INTERVAL; 11019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Config.LOGD) Log.d(TAG, "NetworkThread exiting"); 11069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized void xtraDownloadRequest() { 11099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mXtraDownloadRequested = true; 11109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project notify(); 11119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 111393bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood synchronized void timeInjectRequest() { 111493bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood mTimeInjectRequested = true; 111593bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood notify(); 111693bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood } 111793bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood 11189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized void signal() { 11199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project notify(); 11209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized void setDone() { 11239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Config.LOGD) Log.d(TAG, "stopping NetworkThread"); 11249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDone = true; 11259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project notify(); 11269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private long getWaitTime() { 11299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long now = System.currentTimeMillis(); 11309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long waitTime = Long.MAX_VALUE; 11319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mNtpServer != null) { 11329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project waitTime = mNextNtpTime - now; 11339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mNextXtraTime != 0) { 11359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long xtraWaitTime = mNextXtraTime - now; 11369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (xtraWaitTime < waitTime) { 11379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project waitTime = xtraWaitTime; 11389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (waitTime < 0) { 11419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project waitTime = 0; 11429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return waitTime; 11449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // for GPS SV statistics 11489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int MAX_SVS = 32; 11499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int EPHEMERIS_MASK = 0; 11509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int ALMANAC_MASK = 1; 11519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int USED_FOR_FIX_MASK = 2; 11529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // preallocated arrays, to avoid memory allocation in reportStatus() 11549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mSvs[] = new int[MAX_SVS]; 11559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private float mSnrs[] = new float[MAX_SVS]; 11569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private float mSvElevations[] = new float[MAX_SVS]; 11579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private float mSvAzimuths[] = new float[MAX_SVS]; 11589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mSvMasks[] = new int[3]; 11599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mSvCount; 11609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static { class_init_native(); } 11629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static native void class_init_native(); 11639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static native boolean native_is_supported(); 11649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native boolean native_init(); 11669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native void native_disable(); 11679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native void native_cleanup(); 1168105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project private native boolean native_start(int positionMode, boolean singleFix, int fixInterval); 11699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native boolean native_stop(); 11709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native void native_set_fix_frequency(int fixFrequency); 11719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native void native_delete_aiding_data(int flags); 11729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native void native_wait_for_event(); 11739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // returns number of SVs 11749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // mask[0] is ephemeris mask and mask[1] is almanac mask 11759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native int native_read_sv_status(int[] svs, float[] snrs, 11769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float[] elevations, float[] azimuths, int[] masks); 1177d26ce0d903f5141a346d67b2b94437ef3e2880aaMike Lockwood private native void native_inject_location(double latitude, double longitude, float accuracy); 1178d26ce0d903f5141a346d67b2b94437ef3e2880aaMike Lockwood 11799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // XTRA Support 11809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native void native_inject_time(long time, long timeReference, int uncertainty); 11819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native boolean native_supports_xtra(); 11829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native void native_inject_xtra_data(byte[] data, int length); 1183105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project 1184e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood // AGPS Support 1185e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood private native void native_agps_data_conn_open(String apn); 1186e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood private native void native_agps_data_conn_closed(); 1187e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood private native void native_agps_data_conn_failed(); 1188a9e546169b3c2c9c5f248d2f3abe3b934f48695dMike Lockwood private native void native_set_agps_server(int type, String hostname, int port); 11899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1190