GpsLocationProvider.java revision 50130bbc884a7ad7db39dbc4f54e76e8be87761f
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 1700b74270c9f136a8727c5f6cda0997a3a905f385Mike Lockwoodpackage com.android.server.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; 2922d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xieimport android.location.INetInitiatedListener; 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; 3403d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwoodimport android.net.NetworkInfo; 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.net.SntpClient; 3663aa5a6f98b1016863e4f6edd87eb471b28dc28fMike Lockwoodimport android.os.Binder; 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Bundle; 3862a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwoodimport android.os.Handler; 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.IBinder; 4062a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwoodimport android.os.Looper; 4162a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwoodimport android.os.Message; 420528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwoodimport android.os.PowerManager; 4362a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwoodimport android.os.Process; 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.RemoteException; 452f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwoodimport android.os.ServiceManager; 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.SystemClock; 477e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackbornimport android.os.WorkSource; 48bcab8df83e6e769a7cbcc742e72b47d665998793Mike Lockwoodimport android.provider.Settings; 491e84da822e7aa4d494b31c8759917d2751611f84Miguel Torrojaimport android.provider.Telephony.Sms.Intents; 501e84da822e7aa4d494b31c8759917d2751611f84Miguel Torrojaimport android.telephony.TelephonyManager; 511e84da822e7aa4d494b31c8759917d2751611f84Miguel Torrojaimport android.telephony.gsm.GsmCellLocation; 521e84da822e7aa4d494b31c8759917d2751611f84Miguel Torrojaimport android.telephony.SmsMessage; 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Log; 542f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwoodimport android.util.SparseIntArray; 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 562f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwoodimport com.android.internal.app.IBatteryStats; 57105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Projectimport com.android.internal.telephony.Phone; 5822d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xieimport com.android.internal.location.GpsNetInitiatedHandler; 5922d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xieimport com.android.internal.location.GpsNetInitiatedHandler.GpsNiNotification; 601e84da822e7aa4d494b31c8759917d2751611f84Miguel Torrojaimport com.android.internal.telephony.GsmAlphabet; 611e84da822e7aa4d494b31c8759917d2751611f84Miguel Torrojaimport com.android.internal.telephony.SmsHeader; 621e84da822e7aa4d494b31c8759917d2751611f84Miguel Torrojaimport com.android.internal.util.HexDump; 63105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.File; 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.FileInputStream; 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.IOException; 6722d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xieimport java.io.StringBufferInputStream; 68105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Projectimport java.net.InetAddress; 69105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Projectimport java.net.UnknownHostException; 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.ArrayList; 71f1218be2d8f68f3f445f3bc90e0eca01946a0ddfMike Lockwoodimport java.util.Date; 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.Properties; 7322d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xieimport java.util.Map.Entry; 7489096317104722219f73a5c3cc424e6e98c90a61Mike Lockwoodimport java.util.concurrent.CountDownLatch; 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * A GPS implementation of LocationProvider used by LocationManager. 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@hide} 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 8189096317104722219f73a5c3cc424e6e98c90a61Mike Lockwoodpublic class GpsLocationProvider implements LocationProviderInterface { 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final String TAG = "GpsLocationProvider"; 8429c84340a14e70419449628ab193d11b7a609e9aMike Lockwood 85f5d95cbc1a6974afeb4d3155bdaa8dae55722a39Joe Onorato private static final boolean DEBUG = false; 8629c84340a14e70419449628ab193d11b7a609e9aMike Lockwood private static final boolean VERBOSE = false; 8762a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood 88105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project // these need to match GpsPositionMode enum in gps.h 89105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project private static final int GPS_POSITION_MODE_STANDALONE = 0; 90105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project private static final int GPS_POSITION_MODE_MS_BASED = 1; 91105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project private static final int GPS_POSITION_MODE_MS_ASSISTED = 2; 92105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project 9304598b67a58fad93e5060bb77756ba4863013aedMike Lockwood // these need to match GpsPositionRecurrence enum in gps.h 9404598b67a58fad93e5060bb77756ba4863013aedMike Lockwood private static final int GPS_POSITION_RECURRENCE_PERIODIC = 0; 9504598b67a58fad93e5060bb77756ba4863013aedMike Lockwood private static final int GPS_POSITION_RECURRENCE_SINGLE = 1; 9604598b67a58fad93e5060bb77756ba4863013aedMike Lockwood 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // these need to match GpsStatusValue defines in gps.h 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_STATUS_NONE = 0; 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_STATUS_SESSION_BEGIN = 1; 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_STATUS_SESSION_END = 2; 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_STATUS_ENGINE_ON = 3; 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_STATUS_ENGINE_OFF = 4; 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 104e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood // these need to match GpsApgsStatusValue defines in gps.h 105e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood /** AGPS status event values. */ 106e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood private static final int GPS_REQUEST_AGPS_DATA_CONN = 1; 107e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood private static final int GPS_RELEASE_AGPS_DATA_CONN = 2; 108e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood private static final int GPS_AGPS_DATA_CONNECTED = 3; 109e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood private static final int GPS_AGPS_DATA_CONN_DONE = 4; 110e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood private static final int GPS_AGPS_DATA_CONN_FAILED = 5; 11158bda987665af759c379cd494ff4873ac61acf29Mike Lockwood 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // these need to match GpsLocationFlags enum in gps.h 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int LOCATION_INVALID = 0; 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int LOCATION_HAS_LAT_LONG = 1; 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int LOCATION_HAS_ALTITUDE = 2; 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int LOCATION_HAS_SPEED = 4; 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int LOCATION_HAS_BEARING = 8; 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int LOCATION_HAS_ACCURACY = 16; 119e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood 120e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood// IMPORTANT - the GPS_DELETE_* symbols here must match constants in gps.h 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_DELETE_EPHEMERIS = 0x0001; 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_DELETE_ALMANAC = 0x0002; 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_DELETE_POSITION = 0x0004; 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_DELETE_TIME = 0x0008; 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_DELETE_IONO = 0x0010; 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_DELETE_UTC = 0x0020; 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_DELETE_HEALTH = 0x0040; 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_DELETE_SVDIR = 0x0080; 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_DELETE_SVSTEER = 0x0100; 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_DELETE_SADATA = 0x0200; 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_DELETE_RTI = 0x0400; 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_DELETE_CELLDB_INFO = 0x8000; 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_DELETE_ALL = 0xFFFF; 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13504598b67a58fad93e5060bb77756ba4863013aedMike Lockwood // The GPS_CAPABILITY_* flags must match the values in gps.h 13604598b67a58fad93e5060bb77756ba4863013aedMike Lockwood private static final int GPS_CAPABILITY_SCHEDULING = 0x0000001; 13704598b67a58fad93e5060bb77756ba4863013aedMike Lockwood private static final int GPS_CAPABILITY_MSB = 0x0000002; 13804598b67a58fad93e5060bb77756ba4863013aedMike Lockwood private static final int GPS_CAPABILITY_MSA = 0x0000004; 13904598b67a58fad93e5060bb77756ba4863013aedMike Lockwood private static final int GPS_CAPABILITY_SINGLE_SHOT = 0x0000008; 14004598b67a58fad93e5060bb77756ba4863013aedMike Lockwood 14104598b67a58fad93e5060bb77756ba4863013aedMike Lockwood 142e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood // these need to match AGpsType enum in gps.h 143e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood private static final int AGPS_TYPE_SUPL = 1; 144e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood private static final int AGPS_TYPE_C2K = 2; 145e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood 146e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood // for mAGpsDataConnectionState 147e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood private static final int AGPS_DATA_CONNECTION_CLOSED = 0; 148e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood private static final int AGPS_DATA_CONNECTION_OPENING = 1; 149e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood private static final int AGPS_DATA_CONNECTION_OPEN = 2; 15058bda987665af759c379cd494ff4873ac61acf29Mike Lockwood 15162a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood // Handler messages 15262a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood private static final int CHECK_LOCATION = 1; 15362a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood private static final int ENABLE = 2; 15462a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood private static final int ENABLE_TRACKING = 3; 15562a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood private static final int UPDATE_NETWORK_STATE = 4; 15662a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood private static final int INJECT_NTP_TIME = 5; 15762a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood private static final int DOWNLOAD_XTRA_DATA = 6; 15862a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood private static final int UPDATE_LOCATION = 7; 15962a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood private static final int ADD_LISTENER = 8; 16062a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood private static final int REMOVE_LISTENER = 9; 16103ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood private static final int REQUEST_SINGLE_SHOT = 10; 16262a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood 1631e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja // Request setid 1641e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja private static final int AGPS_RIL_REQUEST_SETID_IMSI = 1; 1651e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja private static final int AGPS_RIL_REQUEST_SETID_MSISDN = 2; 1661e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja 1671e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja // Request ref location 1681e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja private static final int AGPS_RIL_REQUEST_REFLOC_CELLID = 1; 1691e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja private static final int AGPS_RIL_REQUEST_REFLOC_MAC = 2; 1701e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja 1711e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja // ref. location info 1721e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja private static final int AGPS_REF_LOCATION_TYPE_GSM_CELLID = 1; 1731e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja private static final int AGPS_REF_LOCATION_TYPE_UMTS_CELLID = 2; 1741e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja private static final int AGPS_REG_LOCATION_TYPE_MAC = 3; 1751e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja 1761e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja // set id info 1771e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja private static final int AGPS_SETID_TYPE_NONE = 0; 1781e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja private static final int AGPS_SETID_TYPE_IMSI = 1; 1791e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja private static final int AGPS_SETID_TYPE_MSISDN = 2; 1801e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final String PROPERTIES_FILE = "/etc/gps.conf"; 1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mLocationFlags = LOCATION_INVALID; 1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // current status 18615e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood private int mStatus = LocationProvider.TEMPORARILY_UNAVAILABLE; 1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // time for last status update 1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private long mStatusUpdateTime = SystemClock.elapsedRealtime(); 190d53ba017ee2381383b4bb4d92e6e0e661431660fMike Lockwood 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // turn off GPS fix icon if we haven't received a fix in 10 seconds 19204598b67a58fad93e5060bb77756ba4863013aedMike Lockwood private static final long RECENT_FIX_TIMEOUT = 10 * 1000; 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1940632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood // stop trying if we do not receive a fix within 60 seconds 19504598b67a58fad93e5060bb77756ba4863013aedMike Lockwood private static final int NO_FIX_TIMEOUT = 60 * 1000; 1960632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // true if we are enabled 19889096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood private volatile boolean mEnabled; 1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // true if we have network connectivity 2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mNetworkAvailable; 2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 20362a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood // flags to trigger NTP or XTRA data download when network becomes available 20462a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood // initialized to true so we do NTP and XTRA when the network comes up after booting 20562a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood private boolean mInjectNtpTimePending = true; 2065723dfe8c87d0887b8926f43637ed300466890d2Mike Lockwood private boolean mDownloadXtraDataPending = false; 20762a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood 2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // true if GPS is navigating 2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mNavigating; 210cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood 211cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood // true if GPS engine is on 212cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood private boolean mEngineOn; 2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 21404598b67a58fad93e5060bb77756ba4863013aedMike Lockwood // requested frequency of fixes, in milliseconds 21504598b67a58fad93e5060bb77756ba4863013aedMike Lockwood private int mFixInterval = 1000; 2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // true if we started navigation 2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mStarted; 2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 22003ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood // true if single shot request is in progress 22103ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood private boolean mSingleShot; 22203ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood 22304598b67a58fad93e5060bb77756ba4863013aedMike Lockwood // capabilities of the GPS engine 22404598b67a58fad93e5060bb77756ba4863013aedMike Lockwood private int mEngineCapabilities; 22504598b67a58fad93e5060bb77756ba4863013aedMike Lockwood 2261a1cd3a878b6389c097e34d114b60cf953edaeaaMike Lockwood // true if XTRA is supported 2271a1cd3a878b6389c097e34d114b60cf953edaeaaMike Lockwood private boolean mSupportsXtra; 2281a1cd3a878b6389c097e34d114b60cf953edaeaaMike Lockwood 2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // for calculating time to first fix 2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private long mFixRequestTime = 0; 2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // time to first fix for most recent session 2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mTTFF = 0; 2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // time we received our last fix 2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private long mLastFixTime; 2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 23604598b67a58fad93e5060bb77756ba4863013aedMike Lockwood private int mPositionMode; 23704598b67a58fad93e5060bb77756ba4863013aedMike Lockwood 2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // properties loaded from PROPERTIES_FILE 2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Properties mProperties; 2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private String mNtpServer; 241734d6031a662a275ec68627bd1258159041d44deMike Lockwood private String mSuplServerHost; 242734d6031a662a275ec68627bd1258159041d44deMike Lockwood private int mSuplServerPort; 243734d6031a662a275ec68627bd1258159041d44deMike Lockwood private String mC2KServerHost; 244734d6031a662a275ec68627bd1258159041d44deMike Lockwood private int mC2KServerPort; 2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 24615e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood private final Context mContext; 24715e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood private final ILocationManager mLocationManager; 2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Location mLocation = new Location(LocationManager.GPS_PROVIDER); 2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Bundle mLocationExtras = new Bundle(); 2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private ArrayList<Listener> mListeners = new ArrayList<Listener>(); 25162a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood 25289096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood // GpsLocationProvider's handler thread 25389096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood private final Thread mThread; 25489096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood // Handler for processing events in mThread. 25562a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood private Handler mHandler; 25689096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood // Used to signal when our main thread has initialized everything 25789096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood private final CountDownLatch mInitializedLatch = new CountDownLatch(1); 258105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project 259e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood private String mAGpsApn; 260e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood private int mAGpsDataConnectionState; 2612f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood private final ConnectivityManager mConnMgr; 26222d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie private final GpsNetInitiatedHandler mNIHandler; 2632f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood 2640528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood // Wakelocks 2650528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood private final static String WAKELOCK_KEY = "GpsLocationProvider"; 2660528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood private final PowerManager.WakeLock mWakeLock; 26798e48691f738680fe59e7383a41458e7337daccdMike Lockwood // bitfield of pending messages to our Handler 26898e48691f738680fe59e7383a41458e7337daccdMike Lockwood // used only for messages that cannot have multiple instances queued 26998e48691f738680fe59e7383a41458e7337daccdMike Lockwood private int mPendingMessageBits; 27098e48691f738680fe59e7383a41458e7337daccdMike Lockwood // separate counter for ADD_LISTENER and REMOVE_LISTENER messages, 27198e48691f738680fe59e7383a41458e7337daccdMike Lockwood // which might have multiple instances queued 27298e48691f738680fe59e7383a41458e7337daccdMike Lockwood private int mPendingListenerMessages; 2730528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood 27429c84340a14e70419449628ab193d11b7a609e9aMike Lockwood // Alarms 27529c84340a14e70419449628ab193d11b7a609e9aMike Lockwood private final static String ALARM_WAKEUP = "com.android.internal.location.ALARM_WAKEUP"; 2760632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood private final static String ALARM_TIMEOUT = "com.android.internal.location.ALARM_TIMEOUT"; 27729c84340a14e70419449628ab193d11b7a609e9aMike Lockwood private final AlarmManager mAlarmManager; 27829c84340a14e70419449628ab193d11b7a609e9aMike Lockwood private final PendingIntent mWakeupIntent; 2790632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood private final PendingIntent mTimeoutIntent; 28029c84340a14e70419449628ab193d11b7a609e9aMike Lockwood 2812f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood private final IBatteryStats mBatteryStats; 2822f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood private final SparseIntArray mClientUids = new SparseIntArray(); 283105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project 2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // how often to request NTP time, in milliseconds 2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // current setting 4 hours 286f1218be2d8f68f3f445f3bc90e0eca01946a0ddfMike Lockwood private static final long NTP_INTERVAL = 4*60*60*1000; 2879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // how long to wait if we have a network error in NTP or XTRA downloading 2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // current setting - 5 minutes 289f1218be2d8f68f3f445f3bc90e0eca01946a0ddfMike Lockwood private static final long RETRY_INTERVAL = 5*60*1000; 290f1218be2d8f68f3f445f3bc90e0eca01946a0ddfMike Lockwood 291f1218be2d8f68f3f445f3bc90e0eca01946a0ddfMike Lockwood // to avoid injecting bad NTP time, we reject any time fixes that differ from system time 292f1218be2d8f68f3f445f3bc90e0eca01946a0ddfMike Lockwood // by more than 5 minutes. 293f1218be2d8f68f3f445f3bc90e0eca01946a0ddfMike Lockwood private static final long MAX_NTP_SYSTEM_TIME_OFFSET = 5*60*1000; 2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 29515e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood private final IGpsStatusProvider mGpsStatusProvider = new IGpsStatusProvider.Stub() { 29615e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood public void addGpsStatusListener(IGpsStatusListener listener) throws RemoteException { 29715e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood if (listener == null) { 29815e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood throw new NullPointerException("listener is null in addGpsStatusListener"); 29915e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 30015e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood 30115e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood synchronized(mListeners) { 30215e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood IBinder binder = listener.asBinder(); 30315e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood int size = mListeners.size(); 30415e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood for (int i = 0; i < size; i++) { 30515e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood Listener test = mListeners.get(i); 30615e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood if (binder.equals(test.mListener.asBinder())) { 30715e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood // listener already added 30815e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood return; 30915e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 31015e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 31115e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood 31215e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood Listener l = new Listener(listener); 31315e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood binder.linkToDeath(l, 0); 31415e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood mListeners.add(l); 31515e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 31615e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 31715e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood 31815e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood public void removeGpsStatusListener(IGpsStatusListener listener) { 31915e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood if (listener == null) { 32015e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood throw new NullPointerException("listener is null in addGpsStatusListener"); 32115e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 32215e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood 32315e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood synchronized(mListeners) { 32415e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood IBinder binder = listener.asBinder(); 32515e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood Listener l = null; 32615e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood int size = mListeners.size(); 32715e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood for (int i = 0; i < size && l == null; i++) { 32815e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood Listener test = mListeners.get(i); 32915e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood if (binder.equals(test.mListener.asBinder())) { 33015e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood l = test; 33115e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 33215e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 33315e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood 33415e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood if (l != null) { 33515e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood mListeners.remove(l); 33615e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood binder.unlinkToDeath(l, 0); 33715e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 33815e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 33915e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 34015e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood }; 34115e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood 34215e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood public IGpsStatusProvider getGpsStatusProvider() { 34315e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood return mGpsStatusProvider; 34415e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 34515e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood 34629c84340a14e70419449628ab193d11b7a609e9aMike Lockwood private final BroadcastReceiver mBroadcastReciever = new BroadcastReceiver() { 347105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project @Override public void onReceive(Context context, Intent intent) { 348105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project String action = intent.getAction(); 349105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project 35029c84340a14e70419449628ab193d11b7a609e9aMike Lockwood if (action.equals(ALARM_WAKEUP)) { 35129c84340a14e70419449628ab193d11b7a609e9aMike Lockwood if (DEBUG) Log.d(TAG, "ALARM_WAKEUP"); 35203ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood startNavigating(false); 3530632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood } else if (action.equals(ALARM_TIMEOUT)) { 3540632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood if (DEBUG) Log.d(TAG, "ALARM_TIMEOUT"); 3550632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood hibernate(); 3561e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja } else if (action.equals(Intents.DATA_SMS_RECEIVED_ACTION)) { 3571e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja checkSmsSuplInit(intent); 3581e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja } else if (action.equals(Intents.WAP_PUSH_RECEIVED_ACTION)) { 3591e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja checkWapSuplInit(intent); 3601e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja } 361105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project } 36229c84340a14e70419449628ab193d11b7a609e9aMike Lockwood }; 363105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project 3641e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja private void checkSmsSuplInit(Intent intent) { 3651e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja SmsMessage[] messages = Intents.getMessagesFromIntent(intent); 3661e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja for (int i=0; i <messages.length; i++) { 3671e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja byte[] supl_init = messages[i].getUserData(); 3681e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja native_agps_ni_message(supl_init,supl_init.length); 3691e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja } 3701e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja } 3711e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja 3721e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja private void checkWapSuplInit(Intent intent) { 3731e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja byte[] supl_init = (byte[]) intent.getExtra("data"); 3741e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja native_agps_ni_message(supl_init,supl_init.length); 3751e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja } 3761e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja 3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static boolean isSupported() { 3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return native_is_supported(); 3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3814e50b78bda9cd58be61581d2886c88ff6348a1c1Mike Lockwood public GpsLocationProvider(Context context, ILocationManager locationManager) { 3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContext = context; 38315e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood mLocationManager = locationManager; 38479e642e8ed75033eacc461633a8f4cd5157d25dfMike Lockwood mNIHandler = new GpsNetInitiatedHandler(context); 38563598a0619776b421f27cd12fb29eb83dc327997Mike Lockwood 38663598a0619776b421f27cd12fb29eb83dc327997Mike Lockwood mLocation.setExtras(mLocationExtras); 3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3880528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood // Create a wake lock 3890528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood PowerManager powerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE); 3900528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, WAKELOCK_KEY); 39198e48691f738680fe59e7383a41458e7337daccdMike Lockwood mWakeLock.setReferenceCounted(false); 3920528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood 39329c84340a14e70419449628ab193d11b7a609e9aMike Lockwood mAlarmManager = (AlarmManager)mContext.getSystemService(Context.ALARM_SERVICE); 39429c84340a14e70419449628ab193d11b7a609e9aMike Lockwood mWakeupIntent = PendingIntent.getBroadcast(mContext, 0, new Intent(ALARM_WAKEUP), 0); 3950632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood mTimeoutIntent = PendingIntent.getBroadcast(mContext, 0, new Intent(ALARM_TIMEOUT), 0); 39629c84340a14e70419449628ab193d11b7a609e9aMike Lockwood 3971e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja IntentFilter intentFilter = new IntentFilter(); 3981e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja intentFilter.addAction(Intents.DATA_SMS_RECEIVED_ACTION); 3991e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja intentFilter.addDataScheme("sms"); 4001e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja intentFilter.addDataAuthority("localhost","7275"); 4011e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja context.registerReceiver(mBroadcastReciever, intentFilter); 4021e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja 4031e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja intentFilter = new IntentFilter(); 4041e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja intentFilter.addAction(Intents.WAP_PUSH_RECEIVED_ACTION); 4051e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja try { 4061e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja intentFilter.addDataType("application/vnd.omaloc-supl-init"); 4071e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja } catch (IntentFilter.MalformedMimeTypeException e) { 4081e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja Log.w(TAG, "Malformed SUPL init mime type"); 4091e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja } 4101e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja context.registerReceiver(mBroadcastReciever, intentFilter); 4111e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja 41258bda987665af759c379cd494ff4873ac61acf29Mike Lockwood mConnMgr = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE); 41358bda987665af759c379cd494ff4873ac61acf29Mike Lockwood 4142f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood // Battery statistics service to be notified when GPS turns on or off 4152f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood mBatteryStats = IBatteryStats.Stub.asInterface(ServiceManager.getService("batteryinfo")); 4162f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood 4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mProperties = new Properties(); 4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project File file = new File(PROPERTIES_FILE); 4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project FileInputStream stream = new FileInputStream(file); 4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mProperties.load(stream); 4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project stream.close(); 4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNtpServer = mProperties.getProperty("NTP_SERVER", null); 424e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood 425734d6031a662a275ec68627bd1258159041d44deMike Lockwood mSuplServerHost = mProperties.getProperty("SUPL_HOST"); 426e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood String portString = mProperties.getProperty("SUPL_PORT"); 427734d6031a662a275ec68627bd1258159041d44deMike Lockwood if (mSuplServerHost != null && portString != null) { 428105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project try { 429734d6031a662a275ec68627bd1258159041d44deMike Lockwood mSuplServerPort = Integer.parseInt(portString); 430105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project } catch (NumberFormatException e) { 431e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood Log.e(TAG, "unable to parse SUPL_PORT: " + portString); 432e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood } 433e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood } 434e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood 435734d6031a662a275ec68627bd1258159041d44deMike Lockwood mC2KServerHost = mProperties.getProperty("C2K_HOST"); 436e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood portString = mProperties.getProperty("C2K_PORT"); 437734d6031a662a275ec68627bd1258159041d44deMike Lockwood if (mC2KServerHost != null && portString != null) { 438e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood try { 439734d6031a662a275ec68627bd1258159041d44deMike Lockwood mC2KServerPort = Integer.parseInt(portString); 440e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood } catch (NumberFormatException e) { 441e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood Log.e(TAG, "unable to parse C2K_PORT: " + portString); 442105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project } 443105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project } 4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (IOException e) { 4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.w(TAG, "Could not open GPS configuration file " + PROPERTIES_FILE); 4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 44762a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood 44889096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood // wait until we are fully initialized before returning 44989096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood mThread = new GpsLocationProviderThread(); 45089096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood mThread.start(); 45189096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood while (true) { 45289096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood try { 45389096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood mInitializedLatch.await(); 45489096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood break; 45589096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood } catch (InterruptedException e) { 45689096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood Thread.currentThread().interrupt(); 45789096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood } 45889096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood } 45962a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood } 46062a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood 46162a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood private void initialize() { 46262a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood // register our receiver on our thread rather than the main thread 46362a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood IntentFilter intentFilter = new IntentFilter(); 46462a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood intentFilter.addAction(ALARM_WAKEUP); 46562a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood intentFilter.addAction(ALARM_TIMEOUT); 46662a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood mContext.registerReceiver(mBroadcastReciever, intentFilter); 4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 470d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood * Returns the name of this provider. 471d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood */ 472d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood public String getName() { 473d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood return LocationManager.GPS_PROVIDER; 474d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood } 475d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood 476d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood /** 4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns true if the provider requires access to a 4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * data network (e.g., the Internet), false otherwise. 4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean requiresNetwork() { 481a9e546169b3c2c9c5f248d2f3abe3b934f48695dMike Lockwood return true; 4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 48403d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood public void updateNetworkState(int state, NetworkInfo info) { 48598e48691f738680fe59e7383a41458e7337daccdMike Lockwood sendMessage(UPDATE_NETWORK_STATE, state, info); 48662a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood } 48762a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood 48862a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood private void handleUpdateNetworkState(int state, NetworkInfo info) { 4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNetworkAvailable = (state == LocationProvider.AVAILABLE); 4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 491f5d95cbc1a6974afeb4d3155bdaa8dae55722a39Joe Onorato if (DEBUG) { 49203d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood Log.d(TAG, "updateNetworkState " + (mNetworkAvailable ? "available" : "unavailable") 49303d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood + " info: " + info); 4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 49503d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood 49650130bbc884a7ad7db39dbc4f54e76e8be87761fMike Lockwood if (info != null) { 49750130bbc884a7ad7db39dbc4f54e76e8be87761fMike Lockwood native_update_network_state(info.isConnected(), info.getType(), 49850130bbc884a7ad7db39dbc4f54e76e8be87761fMike Lockwood info.isRoaming(), info.getExtraInfo()); 49950130bbc884a7ad7db39dbc4f54e76e8be87761fMike Lockwood } 50050130bbc884a7ad7db39dbc4f54e76e8be87761fMike Lockwood 50103d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood if (info != null && info.getType() == ConnectivityManager.TYPE_MOBILE_SUPL 50203d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood && mAGpsDataConnectionState == AGPS_DATA_CONNECTION_OPENING) { 50303d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood String apnName = info.getExtraInfo(); 50403d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood if (mNetworkAvailable && apnName != null && apnName.length() > 0) { 50503d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood mAGpsApn = apnName; 50603d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood if (DEBUG) Log.d(TAG, "call native_agps_data_conn_open"); 50703d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood native_agps_data_conn_open(apnName); 50803d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood mAGpsDataConnectionState = AGPS_DATA_CONNECTION_OPEN; 50903d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood } else { 51003d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood if (DEBUG) Log.d(TAG, "call native_agps_data_conn_failed"); 51103d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood mAGpsApn = null; 51203d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood mAGpsDataConnectionState = AGPS_DATA_CONNECTION_CLOSED; 51303d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood native_agps_data_conn_failed(); 51403d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood } 51503d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood } 51603d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood 51762a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood if (mNetworkAvailable) { 51862a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood if (mInjectNtpTimePending) { 51998e48691f738680fe59e7383a41458e7337daccdMike Lockwood sendMessage(INJECT_NTP_TIME, 0, null); 52062a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood } 52162a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood if (mDownloadXtraDataPending) { 52298e48691f738680fe59e7383a41458e7337daccdMike Lockwood sendMessage(DOWNLOAD_XTRA_DATA, 0, null); 52362a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood } 52462a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood } 52562a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood } 52662a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood 52762a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood private void handleInjectNtpTime() { 52862a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood if (!mNetworkAvailable) { 52962a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood // try again when network is up 53062a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood mInjectNtpTimePending = true; 53162a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood return; 53262a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood } 53362a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood mInjectNtpTimePending = false; 53462a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood 53562a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood SntpClient client = new SntpClient(); 53662a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood long delay; 53762a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood 53862a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood if (client.requestTime(mNtpServer, 10000)) { 53962a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood long time = client.getNtpTime(); 54062a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood long timeReference = client.getNtpTimeReference(); 54162a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood int certainty = (int)(client.getRoundTripTime()/2); 54262a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood long now = System.currentTimeMillis(); 54362a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood 54462a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood Log.d(TAG, "NTP server returned: " 54562a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood + time + " (" + new Date(time) 54662a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood + ") reference: " + timeReference 54762a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood + " certainty: " + certainty 5481879d284bf3dd704dbc8c95aad262ebbe3c3c0a4Mike Lockwood + " system time offset: " + (time - now)); 54962a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood 5501879d284bf3dd704dbc8c95aad262ebbe3c3c0a4Mike Lockwood native_inject_time(time, timeReference, certainty); 55162a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood delay = NTP_INTERVAL; 55262a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood } else { 55362a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood if (DEBUG) Log.d(TAG, "requestTime failed"); 55462a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood delay = RETRY_INTERVAL; 55562a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood } 55662a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood 55762a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood // send delayed message for next NTP injection 55898e48691f738680fe59e7383a41458e7337daccdMike Lockwood // since this is delayed and not urgent we do not hold a wake lock here 55962a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood mHandler.removeMessages(INJECT_NTP_TIME); 56062a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood mHandler.sendMessageDelayed(Message.obtain(mHandler, INJECT_NTP_TIME), delay); 56162a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood } 56262a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood 56362a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood private void handleDownloadXtraData() { 5645723dfe8c87d0887b8926f43637ed300466890d2Mike Lockwood if (!mNetworkAvailable) { 56562a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood // try again when network is up 56662a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood mDownloadXtraDataPending = true; 56762a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood return; 56862a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood } 56962a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood mDownloadXtraDataPending = false; 57062a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood 57162a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood 57262a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood GpsXtraDownloader xtraDownloader = new GpsXtraDownloader(mContext, mProperties); 57362a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood byte[] data = xtraDownloader.downloadXtraData(); 57462a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood if (data != null) { 57562a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood if (DEBUG) { 57662a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood Log.d(TAG, "calling native_inject_xtra_data"); 57762a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood } 57862a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood native_inject_xtra_data(data, data.length); 57962a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood } else { 58062a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood // try again later 58198e48691f738680fe59e7383a41458e7337daccdMike Lockwood // since this is delayed and not urgent we do not hold a wake lock here 58262a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood mHandler.removeMessages(DOWNLOAD_XTRA_DATA); 58362a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood mHandler.sendMessageDelayed(Message.obtain(mHandler, DOWNLOAD_XTRA_DATA), RETRY_INTERVAL); 58462a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood } 5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 588fd6e5f0dda50e113db4ccc55338b6c4f09da37a4Mike Lockwood * This is called to inform us when another location provider returns a location. 589fd6e5f0dda50e113db4ccc55338b6c4f09da37a4Mike Lockwood * Someday we might use this for network location injection to aid the GPS 590fd6e5f0dda50e113db4ccc55338b6c4f09da37a4Mike Lockwood */ 591fd6e5f0dda50e113db4ccc55338b6c4f09da37a4Mike Lockwood public void updateLocation(Location location) { 59298e48691f738680fe59e7383a41458e7337daccdMike Lockwood sendMessage(UPDATE_LOCATION, 0, location); 59362a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood } 59462a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood 59562a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood private void handleUpdateLocation(Location location) { 596d26ce0d903f5141a346d67b2b94437ef3e2880aaMike Lockwood if (location.hasAccuracy()) { 597d26ce0d903f5141a346d67b2b94437ef3e2880aaMike Lockwood native_inject_location(location.getLatitude(), location.getLongitude(), 598d26ce0d903f5141a346d67b2b94437ef3e2880aaMike Lockwood location.getAccuracy()); 599d26ce0d903f5141a346d67b2b94437ef3e2880aaMike Lockwood } 600fd6e5f0dda50e113db4ccc55338b6c4f09da37a4Mike Lockwood } 601fd6e5f0dda50e113db4ccc55338b6c4f09da37a4Mike Lockwood 602fd6e5f0dda50e113db4ccc55338b6c4f09da37a4Mike Lockwood /** 6039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns true if the provider requires access to a 6049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * satellite-based positioning system (e.g., GPS), false 6059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * otherwise. 6069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean requiresSatellite() { 6089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 6099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns true if the provider requires access to an appropriate 6139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * cellular network (e.g., to make use of cell tower IDs), false 6149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * otherwise. 6159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean requiresCell() { 6179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 6189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns true if the use of this provider may result in a 6229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * monetary charge to the user, false if use is free. It is up to 6239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * each provider to give accurate information. 6249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean hasMonetaryCost() { 6269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 6279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns true if the provider is able to provide altitude 6319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * information, false otherwise. A provider that reports altitude 6329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * under most circumstances but may occassionally not report it 6339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * should return true. 6349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean supportsAltitude() { 6369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 6379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns true if the provider is able to provide speed 6419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * information, false otherwise. A provider that reports speed 6429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * under most circumstances but may occassionally not report it 6439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * should return true. 6449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean supportsSpeed() { 6469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 6479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns true if the provider is able to provide bearing 6519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * information, false otherwise. A provider that reports bearing 6529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * under most circumstances but may occassionally not report it 6539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * should return true. 6549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean supportsBearing() { 6569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 6579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns the power requirement for this provider. 6619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 6629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the power requirement for this provider, as one of the 6639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * constants Criteria.POWER_REQUIREMENT_*. 6649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getPowerRequirement() { 6669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return Criteria.POWER_HIGH; 6679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 67003ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood * Returns true if this provider meets the given criteria, 67103ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood * false otherwise. 67203ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood */ 67303ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood public boolean meetsCriteria(Criteria criteria) { 67403ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood return (criteria.getPowerRequirement() != Criteria.POWER_LOW); 67503ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood } 67603ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood 67703ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood /** 6789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns the horizontal accuracy of this provider 6799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 6809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the accuracy of location from this provider, as one 6819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * of the constants Criteria.ACCURACY_*. 6829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getAccuracy() { 6849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return Criteria.ACCURACY_FINE; 6859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Enables this provider. When enabled, calls to getStatus() 6894e50b78bda9cd58be61581d2886c88ff6348a1c1Mike Lockwood * must be handled. Hardware may be started up 6909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * when the provider is enabled. 6919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 69262a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood public void enable() { 69362a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood synchronized (mHandler) { 69498e48691f738680fe59e7383a41458e7337daccdMike Lockwood sendMessage(ENABLE, 1, null); 69562a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood } 69662a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood } 69762a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood 69862a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood private void handleEnable() { 69962a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood if (DEBUG) Log.d(TAG, "handleEnable"); 7009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mEnabled) return; 7019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEnabled = native_init(); 7029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mEnabled) { 7041a1cd3a878b6389c097e34d114b60cf953edaeaaMike Lockwood mSupportsXtra = native_supports_xtra(); 705734d6031a662a275ec68627bd1258159041d44deMike Lockwood if (mSuplServerHost != null) { 706734d6031a662a275ec68627bd1258159041d44deMike Lockwood native_set_agps_server(AGPS_TYPE_SUPL, mSuplServerHost, mSuplServerPort); 707734d6031a662a275ec68627bd1258159041d44deMike Lockwood } 708734d6031a662a275ec68627bd1258159041d44deMike Lockwood if (mC2KServerHost != null) { 709734d6031a662a275ec68627bd1258159041d44deMike Lockwood native_set_agps_server(AGPS_TYPE_C2K, mC2KServerHost, mC2KServerPort); 710734d6031a662a275ec68627bd1258159041d44deMike Lockwood } 7119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 7129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.w(TAG, "Failed to enable location provider"); 7139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Disables this provider. When disabled, calls to getStatus() 7184e50b78bda9cd58be61581d2886c88ff6348a1c1Mike Lockwood * need not be handled. Hardware may be shut 7199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * down while the provider is disabled. 7209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 72162a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood public void disable() { 72262a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood synchronized (mHandler) { 72398e48691f738680fe59e7383a41458e7337daccdMike Lockwood sendMessage(ENABLE, 0, null); 72462a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood } 72562a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood } 72662a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood 72762a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood private void handleDisable() { 72889096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood if (DEBUG) Log.d(TAG, "handleDisable"); 7299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mEnabled) return; 7309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEnabled = false; 7329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project stopNavigating(); 7339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 734cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood // do this before releasing wakelock 735cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood native_cleanup(); 7369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 738d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood public boolean isEnabled() { 739d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood return mEnabled; 740d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood } 741d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood 7429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getStatus(Bundle extras) { 7439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras != null) { 7449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project extras.putInt("satellites", mSvCount); 7459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mStatus; 7479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void updateStatus(int status, int svCount) { 7509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (status != mStatus || svCount != mSvCount) { 7519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStatus = status; 7529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSvCount = svCount; 7539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocationExtras.putInt("satellites", svCount); 7549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStatusUpdateTime = SystemClock.elapsedRealtime(); 7559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public long getStatusUpdateTime() { 7599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mStatusUpdateTime; 7609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void enableLocationTracking(boolean enable) { 76303ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood // FIXME - should set a flag here to avoid race conditions with single shot request 76462a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood synchronized (mHandler) { 76598e48691f738680fe59e7383a41458e7337daccdMike Lockwood sendMessage(ENABLE_TRACKING, (enable ? 1 : 0), null); 76662a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood } 76762a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood } 76862a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood 76962a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood private void handleEnableLocationTracking(boolean enable) { 7709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (enable) { 7719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTTFF = 0; 7729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLastFixTime = 0; 77303ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood startNavigating(false); 7749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 77504598b67a58fad93e5060bb77756ba4863013aedMike Lockwood if (!hasCapability(GPS_CAPABILITY_SCHEDULING)) { 77604598b67a58fad93e5060bb77756ba4863013aedMike Lockwood mAlarmManager.cancel(mWakeupIntent); 77704598b67a58fad93e5060bb77756ba4863013aedMike Lockwood mAlarmManager.cancel(mTimeoutIntent); 77804598b67a58fad93e5060bb77756ba4863013aedMike Lockwood } 7799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project stopNavigating(); 7809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 78303ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood public boolean requestSingleShotFix() { 78403ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood if (mStarted) { 78503ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood // cannot do single shot if already navigating 78603ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood return false; 78703ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood } 78803ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood synchronized (mHandler) { 78903ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood mHandler.removeMessages(REQUEST_SINGLE_SHOT); 79003ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood Message m = Message.obtain(mHandler, REQUEST_SINGLE_SHOT); 79103ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood mHandler.sendMessage(m); 79203ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood } 79303ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood return true; 79403ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood } 79503ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood 79603ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood private void handleRequestSingleShot() { 79703ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood mTTFF = 0; 79803ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood mLastFixTime = 0; 79903ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood startNavigating(true); 80003ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood } 80103ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood 8027e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn public void setMinTime(long minTime, WorkSource ws) { 803f5d95cbc1a6974afeb4d3155bdaa8dae55722a39Joe Onorato if (DEBUG) Log.d(TAG, "setMinTime " + minTime); 8049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (minTime >= 0) { 80604598b67a58fad93e5060bb77756ba4863013aedMike Lockwood mFixInterval = (int)minTime; 80704598b67a58fad93e5060bb77756ba4863013aedMike Lockwood 80804598b67a58fad93e5060bb77756ba4863013aedMike Lockwood if (mStarted && hasCapability(GPS_CAPABILITY_SCHEDULING)) { 80904598b67a58fad93e5060bb77756ba4863013aedMike Lockwood if (!native_set_position_mode(mPositionMode, GPS_POSITION_RECURRENCE_PERIODIC, 81004598b67a58fad93e5060bb77756ba4863013aedMike Lockwood mFixInterval, 0, 0)) { 81104598b67a58fad93e5060bb77756ba4863013aedMike Lockwood Log.e(TAG, "set_position_mode failed in setMinTime()"); 81204598b67a58fad93e5060bb77756ba4863013aedMike Lockwood } 8139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8173c8fbdf5dd19fad0b3006557716ee1026d7d5899Fred Fettinger public String getInternalState() { 8183c8fbdf5dd19fad0b3006557716ee1026d7d5899Fred Fettinger return native_get_internal_state(); 8193c8fbdf5dd19fad0b3006557716ee1026d7d5899Fred Fettinger } 8203c8fbdf5dd19fad0b3006557716ee1026d7d5899Fred Fettinger 8219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final class Listener implements IBinder.DeathRecipient { 8229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final IGpsStatusListener mListener; 8239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int mSensors = 0; 8259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Listener(IGpsStatusListener listener) { 8279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mListener = listener; 8289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void binderDied() { 831f5d95cbc1a6974afeb4d3155bdaa8dae55722a39Joe Onorato if (DEBUG) Log.d(TAG, "GPS status listener died"); 8329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized(mListeners) { 8349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mListeners.remove(this); 8359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 836fff2fda0199dedbf1079454dca98a81190dce765Suchi Amalapurapu if (mListener != null) { 837fff2fda0199dedbf1079454dca98a81190dce765Suchi Amalapurapu mListener.asBinder().unlinkToDeath(this, 0); 838fff2fda0199dedbf1079454dca98a81190dce765Suchi Amalapurapu } 8399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8422f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood public void addListener(int uid) { 84398e48691f738680fe59e7383a41458e7337daccdMike Lockwood synchronized (mWakeLock) { 84498e48691f738680fe59e7383a41458e7337daccdMike Lockwood mPendingListenerMessages++; 8457e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn mWakeLock.acquire(); 84698e48691f738680fe59e7383a41458e7337daccdMike Lockwood Message m = Message.obtain(mHandler, ADD_LISTENER); 84798e48691f738680fe59e7383a41458e7337daccdMike Lockwood m.arg1 = uid; 84898e48691f738680fe59e7383a41458e7337daccdMike Lockwood mHandler.sendMessage(m); 84998e48691f738680fe59e7383a41458e7337daccdMike Lockwood } 85062a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood } 85162a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood 85262a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood private void handleAddListener(int uid) { 8532e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn synchronized(mListeners) { 8542e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn if (mClientUids.indexOfKey(uid) >= 0) { 8552e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn // Shouldn't be here -- already have this uid. 8562e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn Log.w(TAG, "Duplicate add listener for uid " + uid); 8572e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn return; 8582e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn } 8592e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn mClientUids.put(uid, 0); 8602e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn if (mNavigating) { 8612e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn try { 8622e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn mBatteryStats.noteStartGps(uid); 8632e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn } catch (RemoteException e) { 8642e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn Log.w(TAG, "RemoteException in addListener"); 8652e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn } 8662f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } 8672f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } 8682f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } 8692f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood 8702f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood public void removeListener(int uid) { 87198e48691f738680fe59e7383a41458e7337daccdMike Lockwood synchronized (mWakeLock) { 87298e48691f738680fe59e7383a41458e7337daccdMike Lockwood mPendingListenerMessages++; 87398e48691f738680fe59e7383a41458e7337daccdMike Lockwood mWakeLock.acquire(); 87498e48691f738680fe59e7383a41458e7337daccdMike Lockwood Message m = Message.obtain(mHandler, REMOVE_LISTENER); 87598e48691f738680fe59e7383a41458e7337daccdMike Lockwood m.arg1 = uid; 87698e48691f738680fe59e7383a41458e7337daccdMike Lockwood mHandler.sendMessage(m); 87798e48691f738680fe59e7383a41458e7337daccdMike Lockwood } 87862a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood } 87962a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood 88062a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood private void handleRemoveListener(int uid) { 8812e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn synchronized(mListeners) { 8822e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn if (mClientUids.indexOfKey(uid) < 0) { 8832e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn // Shouldn't be here -- don't have this uid. 8842e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn Log.w(TAG, "Unneeded remove listener for uid " + uid); 8852e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn return; 8862e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn } 8872e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn mClientUids.delete(uid); 8882e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn if (mNavigating) { 8892e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn try { 8902e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn mBatteryStats.noteStopGps(uid); 8912e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn } catch (RemoteException e) { 8922e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn Log.w(TAG, "RemoteException in removeListener"); 8932e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn } 8942f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } 8952f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } 8962f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } 8972f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood 8989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean sendExtraCommand(String command, Bundle extras) { 8999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 90063aa5a6f98b1016863e4f6edd87eb471b28dc28fMike Lockwood long identity = Binder.clearCallingIdentity(); 90163aa5a6f98b1016863e4f6edd87eb471b28dc28fMike Lockwood boolean result = false; 90263aa5a6f98b1016863e4f6edd87eb471b28dc28fMike Lockwood 9039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ("delete_aiding_data".equals(command)) { 90463aa5a6f98b1016863e4f6edd87eb471b28dc28fMike Lockwood result = deleteAidingData(extras); 90563aa5a6f98b1016863e4f6edd87eb471b28dc28fMike Lockwood } else if ("force_time_injection".equals(command)) { 90698e48691f738680fe59e7383a41458e7337daccdMike Lockwood sendMessage(INJECT_NTP_TIME, 0, null); 90763aa5a6f98b1016863e4f6edd87eb471b28dc28fMike Lockwood result = true; 90863aa5a6f98b1016863e4f6edd87eb471b28dc28fMike Lockwood } else if ("force_xtra_injection".equals(command)) { 9091a1cd3a878b6389c097e34d114b60cf953edaeaaMike Lockwood if (mSupportsXtra) { 91093bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood xtraDownloadRequest(); 91163aa5a6f98b1016863e4f6edd87eb471b28dc28fMike Lockwood result = true; 91293bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood } 91363aa5a6f98b1016863e4f6edd87eb471b28dc28fMike Lockwood } else { 91463aa5a6f98b1016863e4f6edd87eb471b28dc28fMike Lockwood Log.w(TAG, "sendExtraCommand: unknown command " + command); 91593bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood } 9169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 91763aa5a6f98b1016863e4f6edd87eb471b28dc28fMike Lockwood Binder.restoreCallingIdentity(identity); 91863aa5a6f98b1016863e4f6edd87eb471b28dc28fMike Lockwood return result; 9199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean deleteAidingData(Bundle extras) { 9229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int flags; 9239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras == null) { 9259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project flags = GPS_DELETE_ALL; 9269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 9279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project flags = 0; 9289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("ephemeris")) flags |= GPS_DELETE_EPHEMERIS; 9299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("almanac")) flags |= GPS_DELETE_ALMANAC; 9309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("position")) flags |= GPS_DELETE_POSITION; 9319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("time")) flags |= GPS_DELETE_TIME; 9329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("iono")) flags |= GPS_DELETE_IONO; 9339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("utc")) flags |= GPS_DELETE_UTC; 9349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("health")) flags |= GPS_DELETE_HEALTH; 9359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("svdir")) flags |= GPS_DELETE_SVDIR; 9369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("svsteer")) flags |= GPS_DELETE_SVSTEER; 9379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("sadata")) flags |= GPS_DELETE_SADATA; 9389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("rti")) flags |= GPS_DELETE_RTI; 9399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("celldb-info")) flags |= GPS_DELETE_CELLDB_INFO; 9409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("all")) flags |= GPS_DELETE_ALL; 9419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (flags != 0) { 9449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project native_delete_aiding_data(flags); 9459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 9469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 9499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 95103ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood private void startNavigating(boolean singleShot) { 9529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mStarted) { 95329c84340a14e70419449628ab193d11b7a609e9aMike Lockwood if (DEBUG) Log.d(TAG, "startNavigating"); 9549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStarted = true; 95503ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood mSingleShot = singleShot; 95603ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood mPositionMode = GPS_POSITION_MODE_STANDALONE; 95703ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood 95803ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood if (Settings.Secure.getInt(mContext.getContentResolver(), 959660bbfcc54d48d5d32e64da683c76b9c372c19b1Mike Lockwood Settings.Secure.ASSISTED_GPS_ENABLED, 1) != 0) { 96003ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood if (singleShot && hasCapability(GPS_CAPABILITY_MSA)) { 96103ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood mPositionMode = GPS_POSITION_MODE_MS_ASSISTED; 9628dc16c27e23dae5bdf65fd2a2ced97c2f645a633Mike Lockwood } else if (hasCapability(GPS_CAPABILITY_MSB)) { 96303ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood mPositionMode = GPS_POSITION_MODE_MS_BASED; 96403ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood } 965bcab8df83e6e769a7cbcc742e72b47d665998793Mike Lockwood } 966bcab8df83e6e769a7cbcc742e72b47d665998793Mike Lockwood 96704598b67a58fad93e5060bb77756ba4863013aedMike Lockwood int interval = (hasCapability(GPS_CAPABILITY_SCHEDULING) ? mFixInterval : 1000); 96804598b67a58fad93e5060bb77756ba4863013aedMike Lockwood if (!native_set_position_mode(mPositionMode, GPS_POSITION_RECURRENCE_PERIODIC, 96904598b67a58fad93e5060bb77756ba4863013aedMike Lockwood interval, 0, 0)) { 97004598b67a58fad93e5060bb77756ba4863013aedMike Lockwood mStarted = false; 97104598b67a58fad93e5060bb77756ba4863013aedMike Lockwood Log.e(TAG, "set_position_mode failed in startNavigating()"); 97204598b67a58fad93e5060bb77756ba4863013aedMike Lockwood return; 97304598b67a58fad93e5060bb77756ba4863013aedMike Lockwood } 97404598b67a58fad93e5060bb77756ba4863013aedMike Lockwood if (!native_start()) { 9759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStarted = false; 9769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.e(TAG, "native_start failed in startNavigating()"); 9770632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood return; 9789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // reset SV count to zero 98115e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood updateStatus(LocationProvider.TEMPORARILY_UNAVAILABLE, 0); 98229c84340a14e70419449628ab193d11b7a609e9aMike Lockwood mFixRequestTime = System.currentTimeMillis(); 98304598b67a58fad93e5060bb77756ba4863013aedMike Lockwood if (!hasCapability(GPS_CAPABILITY_SCHEDULING)) { 98404598b67a58fad93e5060bb77756ba4863013aedMike Lockwood // set timer to give up if we do not receive a fix within NO_FIX_TIMEOUT 98504598b67a58fad93e5060bb77756ba4863013aedMike Lockwood // and our fix interval is not short 98604598b67a58fad93e5060bb77756ba4863013aedMike Lockwood if (mFixInterval >= NO_FIX_TIMEOUT) { 98704598b67a58fad93e5060bb77756ba4863013aedMike Lockwood mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, 98804598b67a58fad93e5060bb77756ba4863013aedMike Lockwood SystemClock.elapsedRealtime() + NO_FIX_TIMEOUT, mTimeoutIntent); 98904598b67a58fad93e5060bb77756ba4863013aedMike Lockwood } 9900632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood } 9919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 99462a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood private void stopNavigating() { 99529c84340a14e70419449628ab193d11b7a609e9aMike Lockwood if (DEBUG) Log.d(TAG, "stopNavigating"); 9969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mStarted) { 9979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStarted = false; 99803ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood mSingleShot = false; 9999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project native_stop(); 10009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTTFF = 0; 10019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLastFixTime = 0; 10029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocationFlags = LOCATION_INVALID; 10039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // reset SV count to zero 100515e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood updateStatus(LocationProvider.TEMPORARILY_UNAVAILABLE, 0); 10069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10090632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood private void hibernate() { 10100632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood // stop GPS until our next fix interval arrives 10110632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood stopNavigating(); 10120632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood mAlarmManager.cancel(mTimeoutIntent); 10130632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood mAlarmManager.cancel(mWakeupIntent); 10140632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood long now = SystemClock.elapsedRealtime(); 10150632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, 101604598b67a58fad93e5060bb77756ba4863013aedMike Lockwood SystemClock.elapsedRealtime() + mFixInterval, mWakeupIntent); 101704598b67a58fad93e5060bb77756ba4863013aedMike Lockwood } 101804598b67a58fad93e5060bb77756ba4863013aedMike Lockwood 101904598b67a58fad93e5060bb77756ba4863013aedMike Lockwood private boolean hasCapability(int capability) { 102004598b67a58fad93e5060bb77756ba4863013aedMike Lockwood return ((mEngineCapabilities & capability) != 0); 10210632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood } 10220632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood 10239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 10249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * called from native code to update our position. 10259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 10269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void reportLocation(int flags, double latitude, double longitude, double altitude, 10279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float speed, float bearing, float accuracy, long timestamp) { 102829c84340a14e70419449628ab193d11b7a609e9aMike Lockwood if (VERBOSE) Log.v(TAG, "reportLocation lat: " + latitude + " long: " + longitude + 10299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project " timestamp: " + timestamp); 10309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mLocation) { 10329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocationFlags = flags; 10339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((flags & LOCATION_HAS_LAT_LONG) == LOCATION_HAS_LAT_LONG) { 10349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocation.setLatitude(latitude); 10359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocation.setLongitude(longitude); 10369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocation.setTime(timestamp); 10379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((flags & LOCATION_HAS_ALTITUDE) == LOCATION_HAS_ALTITUDE) { 10399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocation.setAltitude(altitude); 10409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 10419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocation.removeAltitude(); 10429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((flags & LOCATION_HAS_SPEED) == LOCATION_HAS_SPEED) { 10449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocation.setSpeed(speed); 10459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 10469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocation.removeSpeed(); 10479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((flags & LOCATION_HAS_BEARING) == LOCATION_HAS_BEARING) { 10499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocation.setBearing(bearing); 10509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 10519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocation.removeBearing(); 10529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((flags & LOCATION_HAS_ACCURACY) == LOCATION_HAS_ACCURACY) { 10549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocation.setAccuracy(accuracy); 10559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 10569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocation.removeAccuracy(); 10579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 105915e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood try { 1060a4903f254b4711c8fc0ac5f7e3d605f4dce34f35Mike Lockwood mLocationManager.reportLocation(mLocation, false); 106115e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } catch (RemoteException e) { 106215e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood Log.e(TAG, "RemoteException calling reportLocation"); 106315e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 10649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1066fa94ff074d3200fae2f5d14a6d0f454e2ad23cfaHakan Gustavsson mLastFixTime = System.currentTimeMillis(); 1067fa94ff074d3200fae2f5d14a6d0f454e2ad23cfaHakan Gustavsson // report time to first fix 1068fa94ff074d3200fae2f5d14a6d0f454e2ad23cfaHakan Gustavsson if (mTTFF == 0 && (flags & LOCATION_HAS_LAT_LONG) == LOCATION_HAS_LAT_LONG) { 1069fa94ff074d3200fae2f5d14a6d0f454e2ad23cfaHakan Gustavsson mTTFF = (int)(mLastFixTime - mFixRequestTime); 1070f4dffd8a45386b5a5f0e6de4f30facc9eaac4001The Android Open Source Project if (DEBUG) Log.d(TAG, "TTFF: " + mTTFF); 1071fa94ff074d3200fae2f5d14a6d0f454e2ad23cfaHakan Gustavsson 1072fa94ff074d3200fae2f5d14a6d0f454e2ad23cfaHakan Gustavsson // notify status listeners 1073fa94ff074d3200fae2f5d14a6d0f454e2ad23cfaHakan Gustavsson synchronized(mListeners) { 1074fa94ff074d3200fae2f5d14a6d0f454e2ad23cfaHakan Gustavsson int size = mListeners.size(); 1075fa94ff074d3200fae2f5d14a6d0f454e2ad23cfaHakan Gustavsson for (int i = 0; i < size; i++) { 1076fa94ff074d3200fae2f5d14a6d0f454e2ad23cfaHakan Gustavsson Listener listener = mListeners.get(i); 1077fa94ff074d3200fae2f5d14a6d0f454e2ad23cfaHakan Gustavsson try { 1078f4dffd8a45386b5a5f0e6de4f30facc9eaac4001The Android Open Source Project listener.mListener.onFirstFix(mTTFF); 1079fa94ff074d3200fae2f5d14a6d0f454e2ad23cfaHakan Gustavsson } catch (RemoteException e) { 1080fa94ff074d3200fae2f5d14a6d0f454e2ad23cfaHakan Gustavsson Log.w(TAG, "RemoteException in stopNavigating"); 1081fa94ff074d3200fae2f5d14a6d0f454e2ad23cfaHakan Gustavsson mListeners.remove(listener); 1082fa94ff074d3200fae2f5d14a6d0f454e2ad23cfaHakan Gustavsson // adjust for size of list changing 1083fa94ff074d3200fae2f5d14a6d0f454e2ad23cfaHakan Gustavsson size--; 1084fa94ff074d3200fae2f5d14a6d0f454e2ad23cfaHakan Gustavsson } 1085fa94ff074d3200fae2f5d14a6d0f454e2ad23cfaHakan Gustavsson } 1086fa94ff074d3200fae2f5d14a6d0f454e2ad23cfaHakan Gustavsson } 1087fa94ff074d3200fae2f5d14a6d0f454e2ad23cfaHakan Gustavsson } 1088fa94ff074d3200fae2f5d14a6d0f454e2ad23cfaHakan Gustavsson 108903ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood if (mSingleShot) { 109003ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood stopNavigating(); 109103ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood } 109215e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood if (mStarted && mStatus != LocationProvider.AVAILABLE) { 1093d53ba017ee2381383b4bb4d92e6e0e661431660fMike Lockwood // we want to time out if we do not receive a fix 1094b7be5447a002b4a1cf7d4030cc8a0a330cd7517cMike Lockwood // within the time out and we are requesting infrequent fixes 109504598b67a58fad93e5060bb77756ba4863013aedMike Lockwood if (!hasCapability(GPS_CAPABILITY_SCHEDULING) && mFixInterval < NO_FIX_TIMEOUT) { 1096b7be5447a002b4a1cf7d4030cc8a0a330cd7517cMike Lockwood mAlarmManager.cancel(mTimeoutIntent); 1097b7be5447a002b4a1cf7d4030cc8a0a330cd7517cMike Lockwood } 1098b7be5447a002b4a1cf7d4030cc8a0a330cd7517cMike Lockwood 10999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // send an intent to notify that the GPS is receiving fixes. 110000b74270c9f136a8727c5f6cda0997a3a905f385Mike Lockwood Intent intent = new Intent(LocationManager.GPS_FIX_CHANGE_ACTION); 110100b74270c9f136a8727c5f6cda0997a3a905f385Mike Lockwood intent.putExtra(LocationManager.EXTRA_GPS_ENABLED, true); 11029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContext.sendBroadcast(intent); 110315e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood updateStatus(LocationProvider.AVAILABLE, mSvCount); 11049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 110529c84340a14e70419449628ab193d11b7a609e9aMike Lockwood 110603ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood if (!hasCapability(GPS_CAPABILITY_SCHEDULING) && mStarted && mFixInterval > 1000) { 1107d53ba017ee2381383b4bb4d92e6e0e661431660fMike Lockwood if (DEBUG) Log.d(TAG, "got fix, hibernating"); 11080632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood hibernate(); 110929c84340a14e70419449628ab193d11b7a609e9aMike Lockwood } 11109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 11139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * called from native code to update our status 11149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 11159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void reportStatus(int status) { 111629c84340a14e70419449628ab193d11b7a609e9aMike Lockwood if (VERBOSE) Log.v(TAG, "reportStatus status: " + status); 11179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11182e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn synchronized(mListeners) { 11192e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn boolean wasNavigating = mNavigating; 1120dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood 1121cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood switch (status) { 1122cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood case GPS_STATUS_SESSION_BEGIN: 1123cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood mNavigating = true; 1124271f9f172b241607b1ed39a7709c3ed47ee5dee7Mike Lockwood mEngineOn = true; 1125cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood break; 1126cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood case GPS_STATUS_SESSION_END: 1127cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood mNavigating = false; 1128cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood break; 1129cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood case GPS_STATUS_ENGINE_ON: 1130cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood mEngineOn = true; 1131cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood break; 1132cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood case GPS_STATUS_ENGINE_OFF: 1133cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood mEngineOn = false; 1134271f9f172b241607b1ed39a7709c3ed47ee5dee7Mike Lockwood mNavigating = false; 1135cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood break; 1136cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood } 1137cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood 1138dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood if (wasNavigating != mNavigating) { 1139dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood int size = mListeners.size(); 1140dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood for (int i = 0; i < size; i++) { 1141dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood Listener listener = mListeners.get(i); 1142dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood try { 1143dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood if (mNavigating) { 1144dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood listener.mListener.onGpsStarted(); 1145dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood } else { 1146dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood listener.mListener.onGpsStopped(); 1147dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood } 1148dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood } catch (RemoteException e) { 1149dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood Log.w(TAG, "RemoteException in reportStatus"); 1150dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood mListeners.remove(listener); 1151dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood // adjust for size of list changing 1152dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood size--; 1153dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood } 1154dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood } 1155dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood 11562e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn try { 1157dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood // update battery stats 1158dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood for (int i=mClientUids.size() - 1; i >= 0; i--) { 1159dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood int uid = mClientUids.keyAt(i); 1160dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood if (mNavigating) { 1161dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood mBatteryStats.noteStartGps(uid); 1162dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood } else { 1163dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood mBatteryStats.noteStopGps(uid); 1164dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood } 11659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11662e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn } catch (RemoteException e) { 11672e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn Log.w(TAG, "RemoteException in reportStatus"); 11689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1170dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood // send an intent to notify that the GPS has been enabled or disabled. 117100b74270c9f136a8727c5f6cda0997a3a905f385Mike Lockwood Intent intent = new Intent(LocationManager.GPS_ENABLED_CHANGE_ACTION); 117200b74270c9f136a8727c5f6cda0997a3a905f385Mike Lockwood intent.putExtra(LocationManager.EXTRA_GPS_ENABLED, mNavigating); 1173dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood mContext.sendBroadcast(intent); 11742f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } 11759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 11799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * called from native code to update SV info 11809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 11819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void reportSvStatus() { 11829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int svCount = native_read_sv_status(mSvs, mSnrs, mSvElevations, mSvAzimuths, mSvMasks); 11849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized(mListeners) { 11869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int size = mListeners.size(); 11879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < size; i++) { 11889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Listener listener = mListeners.get(i); 11899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 11909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project listener.mListener.onSvStatusChanged(svCount, mSvs, mSnrs, 11919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSvElevations, mSvAzimuths, mSvMasks[EPHEMERIS_MASK], 11929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSvMasks[ALMANAC_MASK], mSvMasks[USED_FOR_FIX_MASK]); 11939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 11949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.w(TAG, "RemoteException in reportSvInfo"); 11959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mListeners.remove(listener); 11969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // adjust for size of list changing 11979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size--; 11989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 120229c84340a14e70419449628ab193d11b7a609e9aMike Lockwood if (VERBOSE) { 120329c84340a14e70419449628ab193d11b7a609e9aMike Lockwood Log.v(TAG, "SV count: " + svCount + 12049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project " ephemerisMask: " + Integer.toHexString(mSvMasks[EPHEMERIS_MASK]) + 12059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project " almanacMask: " + Integer.toHexString(mSvMasks[ALMANAC_MASK])); 12069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < svCount; i++) { 120729c84340a14e70419449628ab193d11b7a609e9aMike Lockwood Log.v(TAG, "sv: " + mSvs[i] + 12089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project " snr: " + (float)mSnrs[i]/10 + 12099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project " elev: " + mSvElevations[i] + 12109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project " azimuth: " + mSvAzimuths[i] + 12119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ((mSvMasks[EPHEMERIS_MASK] & (1 << (mSvs[i] - 1))) == 0 ? " " : " E") + 12129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ((mSvMasks[ALMANAC_MASK] & (1 << (mSvs[i] - 1))) == 0 ? " " : " A") + 12139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ((mSvMasks[USED_FOR_FIX_MASK] & (1 << (mSvs[i] - 1))) == 0 ? "" : "U")); 12149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12170881f4f9339febee85c9ab4cba69970ac5cbde55Kevin.KY Tsai // return number of sets used in fix instead of total 12180881f4f9339febee85c9ab4cba69970ac5cbde55Kevin.KY Tsai updateStatus(mStatus, Integer.bitCount(mSvMasks[USED_FOR_FIX_MASK])); 12199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 122015e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood if (mNavigating && mStatus == LocationProvider.AVAILABLE && mLastFixTime > 0 && 122104598b67a58fad93e5060bb77756ba4863013aedMike Lockwood System.currentTimeMillis() - mLastFixTime > RECENT_FIX_TIMEOUT) { 12229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // send an intent to notify that the GPS is no longer receiving fixes. 122300b74270c9f136a8727c5f6cda0997a3a905f385Mike Lockwood Intent intent = new Intent(LocationManager.GPS_FIX_CHANGE_ACTION); 122400b74270c9f136a8727c5f6cda0997a3a905f385Mike Lockwood intent.putExtra(LocationManager.EXTRA_GPS_ENABLED, false); 12259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContext.sendBroadcast(intent); 122615e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood updateStatus(LocationProvider.TEMPORARILY_UNAVAILABLE, mSvCount); 12279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 122958bda987665af759c379cd494ff4873ac61acf29Mike Lockwood 123058bda987665af759c379cd494ff4873ac61acf29Mike Lockwood /** 1231e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood * called from native code to update AGPS status 123258bda987665af759c379cd494ff4873ac61acf29Mike Lockwood */ 1233e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood private void reportAGpsStatus(int type, int status) { 123458bda987665af759c379cd494ff4873ac61acf29Mike Lockwood switch (status) { 1235e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood case GPS_REQUEST_AGPS_DATA_CONN: 1236b6e5fa895c03eeefaa810eaceb498254096c093dMike Lockwood if (DEBUG) Log.d(TAG, "GPS_REQUEST_AGPS_DATA_CONN"); 12372acfd34ccbd39258422333c9c66c586297c97683Mike Lockwood // Set mAGpsDataConnectionState before calling startUsingNetworkFeature 12382acfd34ccbd39258422333c9c66c586297c97683Mike Lockwood // to avoid a race condition with handleUpdateNetworkState() 12392acfd34ccbd39258422333c9c66c586297c97683Mike Lockwood mAGpsDataConnectionState = AGPS_DATA_CONNECTION_OPENING; 12402acfd34ccbd39258422333c9c66c586297c97683Mike Lockwood int result = mConnMgr.startUsingNetworkFeature( 124158bda987665af759c379cd494ff4873ac61acf29Mike Lockwood ConnectivityManager.TYPE_MOBILE, Phone.FEATURE_ENABLE_SUPL); 124258bda987665af759c379cd494ff4873ac61acf29Mike Lockwood if (result == Phone.APN_ALREADY_ACTIVE) { 1243b362a9ab91bb4c05ef1d5c4e7019499257c7f849Mike Lockwood if (mAGpsApn != null) { 1244b362a9ab91bb4c05ef1d5c4e7019499257c7f849Mike Lockwood native_agps_data_conn_open(mAGpsApn); 1245b362a9ab91bb4c05ef1d5c4e7019499257c7f849Mike Lockwood mAGpsDataConnectionState = AGPS_DATA_CONNECTION_OPEN; 1246b362a9ab91bb4c05ef1d5c4e7019499257c7f849Mike Lockwood } else { 1247b362a9ab91bb4c05ef1d5c4e7019499257c7f849Mike Lockwood Log.e(TAG, "mAGpsApn not set when receiving Phone.APN_ALREADY_ACTIVE"); 12482acfd34ccbd39258422333c9c66c586297c97683Mike Lockwood mAGpsDataConnectionState = AGPS_DATA_CONNECTION_CLOSED; 1249b362a9ab91bb4c05ef1d5c4e7019499257c7f849Mike Lockwood native_agps_data_conn_failed(); 1250b362a9ab91bb4c05ef1d5c4e7019499257c7f849Mike Lockwood } 125158bda987665af759c379cd494ff4873ac61acf29Mike Lockwood } else if (result == Phone.APN_REQUEST_STARTED) { 12522acfd34ccbd39258422333c9c66c586297c97683Mike Lockwood // Nothing to do here 125358bda987665af759c379cd494ff4873ac61acf29Mike Lockwood } else { 12542acfd34ccbd39258422333c9c66c586297c97683Mike Lockwood mAGpsDataConnectionState = AGPS_DATA_CONNECTION_CLOSED; 1255e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood native_agps_data_conn_failed(); 125658bda987665af759c379cd494ff4873ac61acf29Mike Lockwood } 125758bda987665af759c379cd494ff4873ac61acf29Mike Lockwood break; 1258e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood case GPS_RELEASE_AGPS_DATA_CONN: 1259b6e5fa895c03eeefaa810eaceb498254096c093dMike Lockwood if (DEBUG) Log.d(TAG, "GPS_RELEASE_AGPS_DATA_CONN"); 1260e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood if (mAGpsDataConnectionState != AGPS_DATA_CONNECTION_CLOSED) { 126158bda987665af759c379cd494ff4873ac61acf29Mike Lockwood mConnMgr.stopUsingNetworkFeature( 126258bda987665af759c379cd494ff4873ac61acf29Mike Lockwood ConnectivityManager.TYPE_MOBILE, Phone.FEATURE_ENABLE_SUPL); 1263e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood native_agps_data_conn_closed(); 1264e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood mAGpsDataConnectionState = AGPS_DATA_CONNECTION_CLOSED; 126558bda987665af759c379cd494ff4873ac61acf29Mike Lockwood } 126658bda987665af759c379cd494ff4873ac61acf29Mike Lockwood break; 1267e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood case GPS_AGPS_DATA_CONNECTED: 1268b6e5fa895c03eeefaa810eaceb498254096c093dMike Lockwood if (DEBUG) Log.d(TAG, "GPS_AGPS_DATA_CONNECTED"); 126958bda987665af759c379cd494ff4873ac61acf29Mike Lockwood break; 1270e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood case GPS_AGPS_DATA_CONN_DONE: 1271b6e5fa895c03eeefaa810eaceb498254096c093dMike Lockwood if (DEBUG) Log.d(TAG, "GPS_AGPS_DATA_CONN_DONE"); 127258bda987665af759c379cd494ff4873ac61acf29Mike Lockwood break; 1273e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood case GPS_AGPS_DATA_CONN_FAILED: 1274b6e5fa895c03eeefaa810eaceb498254096c093dMike Lockwood if (DEBUG) Log.d(TAG, "GPS_AGPS_DATA_CONN_FAILED"); 127558bda987665af759c379cd494ff4873ac61acf29Mike Lockwood break; 127658bda987665af759c379cd494ff4873ac61acf29Mike Lockwood } 127758bda987665af759c379cd494ff4873ac61acf29Mike Lockwood } 127858bda987665af759c379cd494ff4873ac61acf29Mike Lockwood 1279b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood /** 1280b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood * called from native code to report NMEA data received 1281b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood */ 1282f602d362ba4bb3adbf1eb4e38a794fb14274293aMike Lockwood private void reportNmea(long timestamp) { 1283b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood synchronized(mListeners) { 1284b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood int size = mListeners.size(); 1285b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood if (size > 0) { 1286b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood // don't bother creating the String if we have no listeners 1287f602d362ba4bb3adbf1eb4e38a794fb14274293aMike Lockwood int length = native_read_nmea(mNmeaBuffer, mNmeaBuffer.length); 1288b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood String nmea = new String(mNmeaBuffer, 0, length); 1289b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood 1290b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood for (int i = 0; i < size; i++) { 1291b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood Listener listener = mListeners.get(i); 1292b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood try { 1293b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood listener.mListener.onNmeaReceived(timestamp, nmea); 1294b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood } catch (RemoteException e) { 1295b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood Log.w(TAG, "RemoteException in reportNmea"); 1296b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood mListeners.remove(listener); 1297b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood // adjust for size of list changing 1298b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood size--; 1299b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood } 1300b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood } 1301b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood } 1302b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood } 1303b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood } 1304b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood 130562a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood /** 130604598b67a58fad93e5060bb77756ba4863013aedMike Lockwood * called from native code to inform us what the GPS engine capabilities are 130704598b67a58fad93e5060bb77756ba4863013aedMike Lockwood */ 130804598b67a58fad93e5060bb77756ba4863013aedMike Lockwood private void setEngineCapabilities(int capabilities) { 130904598b67a58fad93e5060bb77756ba4863013aedMike Lockwood mEngineCapabilities = capabilities; 131004598b67a58fad93e5060bb77756ba4863013aedMike Lockwood } 131104598b67a58fad93e5060bb77756ba4863013aedMike Lockwood 131204598b67a58fad93e5060bb77756ba4863013aedMike Lockwood /** 131362a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood * called from native code to request XTRA data 131462a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood */ 13159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void xtraDownloadRequest() { 1316f5d95cbc1a6974afeb4d3155bdaa8dae55722a39Joe Onorato if (DEBUG) Log.d(TAG, "xtraDownloadRequest"); 131798e48691f738680fe59e7383a41458e7337daccdMike Lockwood sendMessage(DOWNLOAD_XTRA_DATA, 0, null); 13189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 132022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie //============================================================= 132122d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie // NI Client support 13221e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja //============================================================= 132322d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie private final INetInitiatedListener mNetInitiatedListener = new INetInitiatedListener.Stub() { 13241e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja // Sends a response for an NI reqeust to HAL. 13251e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja public boolean sendNiResponse(int notificationId, int userResponse) 13261e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja { 13271e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja // TODO Add Permission check 13281e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja 13291e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja StringBuilder extrasBuf = new StringBuilder(); 13301e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja 13311e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja if (DEBUG) Log.d(TAG, "sendNiResponse, notifId: " + notificationId + 13321e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja ", response: " + userResponse); 13331e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja native_send_ni_response(notificationId, userResponse); 13341e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja return true; 13351e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja } 133622d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie }; 133722d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie 133822d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie public INetInitiatedListener getNetInitiatedListener() { 133922d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie return mNetInitiatedListener; 134022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie } 134122d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie 134222d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie // Called by JNI function to report an NI request. 13431e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja public void reportNiNotification( 13441e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja int notificationId, 13451e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja int niType, 13461e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja int notifyFlags, 13471e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja int timeout, 13481e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja int defaultResponse, 13491e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja String requestorId, 13501e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja String text, 13511e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja int requestorIdEncoding, 13521e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja int textEncoding, 13531e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja String extras // Encoded extra data 135422d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie ) 13551e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja { 13561e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja Log.i(TAG, "reportNiNotification: entered"); 13571e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja Log.i(TAG, "notificationId: " + notificationId + 13581e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja ", niType: " + niType + 13591e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja ", notifyFlags: " + notifyFlags + 13601e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja ", timeout: " + timeout + 13611e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja ", defaultResponse: " + defaultResponse); 13621e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja 13631e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja Log.i(TAG, "requestorId: " + requestorId + 13641e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja ", text: " + text + 13651e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja ", requestorIdEncoding: " + requestorIdEncoding + 13661e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja ", textEncoding: " + textEncoding); 13671e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja 13681e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja GpsNiNotification notification = new GpsNiNotification(); 13691e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja 13701e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja notification.notificationId = notificationId; 13711e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja notification.niType = niType; 13721e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja notification.needNotify = (notifyFlags & GpsNetInitiatedHandler.GPS_NI_NEED_NOTIFY) != 0; 13731e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja notification.needVerify = (notifyFlags & GpsNetInitiatedHandler.GPS_NI_NEED_VERIFY) != 0; 13741e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja notification.privacyOverride = (notifyFlags & GpsNetInitiatedHandler.GPS_NI_PRIVACY_OVERRIDE) != 0; 13751e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja notification.timeout = timeout; 13761e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja notification.defaultResponse = defaultResponse; 13771e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja notification.requestorId = requestorId; 13781e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja notification.text = text; 13791e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja notification.requestorIdEncoding = requestorIdEncoding; 13801e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja notification.textEncoding = textEncoding; 13811e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja 13821e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja // Process extras, assuming the format is 13831e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja // one of more lines of "key = value" 13841e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja Bundle bundle = new Bundle(); 13851e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja 13861e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja if (extras == null) extras = ""; 13871e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja Properties extraProp = new Properties(); 13881e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja 13891e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja try { 13901e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja extraProp.load(new StringBufferInputStream(extras)); 13911e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja } 13921e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja catch (IOException e) 13931e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja { 13941e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja Log.e(TAG, "reportNiNotification cannot parse extras data: " + extras); 13951e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja } 13961e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja 13971e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja for (Entry<Object, Object> ent : extraProp.entrySet()) 13981e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja { 13991e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja bundle.putString((String) ent.getKey(), (String) ent.getValue()); 14001e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja } 14011e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja 14021e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja notification.extras = bundle; 14031e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja 14041e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja mNIHandler.handleNiNotification(notification); 14051e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja } 14061e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja 14071e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja /** 14081e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja * Called from native code to request set id info. 14091e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja * We should be careful about receiving null string from the TelephonyManager, 14101e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja * because sending null String to JNI function would cause a crash. 14111e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja */ 14121e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja 14131e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja private void requestSetID(int flags) { 14141e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja TelephonyManager phone = (TelephonyManager) 14151e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja mContext.getSystemService(Context.TELEPHONY_SERVICE); 14161e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja int type = AGPS_SETID_TYPE_NONE; 14171e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja String data = ""; 14181e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja 14191e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja if ((flags & AGPS_RIL_REQUEST_SETID_IMSI) == AGPS_RIL_REQUEST_SETID_IMSI) { 14201e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja String data_temp = phone.getSubscriberId(); 14211e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja if (data_temp == null) { 14221e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja // This means the framework does not have the SIM card ready. 14231e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja } else { 14241e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja // This means the framework has the SIM card. 14251e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja data = data_temp; 14261e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja type = AGPS_SETID_TYPE_IMSI; 14271e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja } 14281e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja } 14291e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja else if ((flags & AGPS_RIL_REQUEST_SETID_MSISDN) == AGPS_RIL_REQUEST_SETID_MSISDN) { 14301e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja String data_temp = phone.getLine1Number(); 14311e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja if (data_temp == null) { 14321e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja // This means the framework does not have the SIM card ready. 14331e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja } else { 14341e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja // This means the framework has the SIM card. 14351e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja data = data_temp; 14361e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja type = AGPS_SETID_TYPE_MSISDN; 14371e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja } 14381e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja } 14391e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja native_agps_set_id(type, data); 14401e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja } 14411e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja 14421e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja /** 14431e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja * Called from native code to request reference location info 14441e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja */ 14451e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja 14461e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja private void requestRefLocation(int flags) { 14471e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja TelephonyManager phone = (TelephonyManager) 14481e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja mContext.getSystemService(Context.TELEPHONY_SERVICE); 14491e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja if (phone.getPhoneType() == TelephonyManager.PHONE_TYPE_GSM) { 14501e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja GsmCellLocation gsm_cell = (GsmCellLocation) phone.getCellLocation(); 14511e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja if ((gsm_cell != null) && (phone.getPhoneType() == TelephonyManager.PHONE_TYPE_GSM) 14521e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja && (phone.getNetworkOperator().length() > 3)) { 14531e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja int type; 14541e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja int mcc = Integer.parseInt(phone.getNetworkOperator().substring(0,3)); 14551e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja int mnc = Integer.parseInt(phone.getNetworkOperator().substring(3)); 14561e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja if (phone.getNetworkType() == TelephonyManager.NETWORK_TYPE_UMTS) 14571e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja type = AGPS_REF_LOCATION_TYPE_UMTS_CELLID; 14581e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja else 14591e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja type = AGPS_REF_LOCATION_TYPE_GSM_CELLID; 14601e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja native_agps_set_ref_location_cellid(type, mcc, mnc, 14611e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja gsm_cell.getLac(), gsm_cell.getCid()); 14621e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja } 14631e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja else 14641e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja Log.e(TAG,"Error getting cell location info."); 14651e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja } 14661e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja else 14671e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja Log.e(TAG,"CDMA not supported."); 14681e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja } 146922d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie 147098e48691f738680fe59e7383a41458e7337daccdMike Lockwood private void sendMessage(int message, int arg, Object obj) { 147198e48691f738680fe59e7383a41458e7337daccdMike Lockwood // hold a wake lock while messages are pending 147298e48691f738680fe59e7383a41458e7337daccdMike Lockwood synchronized (mWakeLock) { 147398e48691f738680fe59e7383a41458e7337daccdMike Lockwood mPendingMessageBits |= (1 << message); 147498e48691f738680fe59e7383a41458e7337daccdMike Lockwood mWakeLock.acquire(); 147598e48691f738680fe59e7383a41458e7337daccdMike Lockwood mHandler.removeMessages(message); 147698e48691f738680fe59e7383a41458e7337daccdMike Lockwood Message m = Message.obtain(mHandler, message); 147798e48691f738680fe59e7383a41458e7337daccdMike Lockwood m.arg1 = arg; 147898e48691f738680fe59e7383a41458e7337daccdMike Lockwood m.obj = obj; 147998e48691f738680fe59e7383a41458e7337daccdMike Lockwood mHandler.sendMessage(m); 148098e48691f738680fe59e7383a41458e7337daccdMike Lockwood } 148198e48691f738680fe59e7383a41458e7337daccdMike Lockwood } 148298e48691f738680fe59e7383a41458e7337daccdMike Lockwood 148362a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood private final class ProviderHandler extends Handler { 148462a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood @Override 148562a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood public void handleMessage(Message msg) 148662a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood { 148798e48691f738680fe59e7383a41458e7337daccdMike Lockwood int message = msg.what; 148898e48691f738680fe59e7383a41458e7337daccdMike Lockwood switch (message) { 148962a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood case ENABLE: 149062a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood if (msg.arg1 == 1) { 149162a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood handleEnable(); 149262a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood } else { 149362a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood handleDisable(); 14949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 149562a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood break; 149662a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood case ENABLE_TRACKING: 149762a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood handleEnableLocationTracking(msg.arg1 == 1); 149862a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood break; 149903ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood case REQUEST_SINGLE_SHOT: 150003ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood handleRequestSingleShot(); 150103ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood break; 150262a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood case UPDATE_NETWORK_STATE: 150362a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood handleUpdateNetworkState(msg.arg1, (NetworkInfo)msg.obj); 150462a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood break; 150562a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood case INJECT_NTP_TIME: 150662a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood handleInjectNtpTime(); 150762a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood break; 150862a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood case DOWNLOAD_XTRA_DATA: 15091a1cd3a878b6389c097e34d114b60cf953edaeaaMike Lockwood if (mSupportsXtra) { 151062a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood handleDownloadXtraData(); 15119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 151262a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood break; 151362a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood case UPDATE_LOCATION: 151462a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood handleUpdateLocation((Location)msg.obj); 151562a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood break; 151662a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood case ADD_LISTENER: 151762a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood handleAddListener(msg.arg1); 151862a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood break; 151962a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood case REMOVE_LISTENER: 152062a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood handleRemoveListener(msg.arg1); 152162a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood break; 15229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 152398e48691f738680fe59e7383a41458e7337daccdMike Lockwood // release wake lock if no messages are pending 152498e48691f738680fe59e7383a41458e7337daccdMike Lockwood synchronized (mWakeLock) { 152598e48691f738680fe59e7383a41458e7337daccdMike Lockwood mPendingMessageBits &= ~(1 << message); 152698e48691f738680fe59e7383a41458e7337daccdMike Lockwood if (message == ADD_LISTENER || message == REMOVE_LISTENER) { 152798e48691f738680fe59e7383a41458e7337daccdMike Lockwood mPendingListenerMessages--; 152898e48691f738680fe59e7383a41458e7337daccdMike Lockwood } 152998e48691f738680fe59e7383a41458e7337daccdMike Lockwood if (mPendingMessageBits == 0 && mPendingListenerMessages == 0) { 153098e48691f738680fe59e7383a41458e7337daccdMike Lockwood mWakeLock.release(); 153198e48691f738680fe59e7383a41458e7337daccdMike Lockwood } 153298e48691f738680fe59e7383a41458e7337daccdMike Lockwood } 15339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 153462a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood }; 15359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 153689096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood private final class GpsLocationProviderThread extends Thread { 153789096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood 153889096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood public GpsLocationProviderThread() { 153989096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood super("GpsLocationProvider"); 154089096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood } 154189096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood 154289096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood public void run() { 154389096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 154489096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood initialize(); 154589096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood Looper.prepare(); 154689096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood mHandler = new ProviderHandler(); 154789096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood // signal when we are initialized and ready to go 154889096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood mInitializedLatch.countDown(); 154989096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood Looper.loop(); 155089096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood } 15519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // for GPS SV statistics 15549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int MAX_SVS = 32; 15559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int EPHEMERIS_MASK = 0; 15569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int ALMANAC_MASK = 1; 15579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int USED_FOR_FIX_MASK = 2; 15589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // preallocated arrays, to avoid memory allocation in reportStatus() 15609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mSvs[] = new int[MAX_SVS]; 15619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private float mSnrs[] = new float[MAX_SVS]; 15629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private float mSvElevations[] = new float[MAX_SVS]; 15639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private float mSvAzimuths[] = new float[MAX_SVS]; 15649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mSvMasks[] = new int[3]; 15659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mSvCount; 1566b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood // preallocated to avoid memory allocation in reportNmea() 1567b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood private byte[] mNmeaBuffer = new byte[120]; 15689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static { class_init_native(); } 15709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static native void class_init_native(); 15719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static native boolean native_is_supported(); 15729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native boolean native_init(); 15749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native void native_cleanup(); 157504598b67a58fad93e5060bb77756ba4863013aedMike Lockwood private native boolean native_set_position_mode(int mode, int recurrence, int min_interval, 157604598b67a58fad93e5060bb77756ba4863013aedMike Lockwood int preferred_accuracy, int preferred_time); 157704598b67a58fad93e5060bb77756ba4863013aedMike Lockwood private native boolean native_start(); 15789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native boolean native_stop(); 15799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native void native_delete_aiding_data(int flags); 15809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // returns number of SVs 15819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // mask[0] is ephemeris mask and mask[1] is almanac mask 15829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native int native_read_sv_status(int[] svs, float[] snrs, 15839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float[] elevations, float[] azimuths, int[] masks); 1584f602d362ba4bb3adbf1eb4e38a794fb14274293aMike Lockwood private native int native_read_nmea(byte[] buffer, int bufferSize); 1585d26ce0d903f5141a346d67b2b94437ef3e2880aaMike Lockwood private native void native_inject_location(double latitude, double longitude, float accuracy); 1586d26ce0d903f5141a346d67b2b94437ef3e2880aaMike Lockwood 15873c8fbdf5dd19fad0b3006557716ee1026d7d5899Fred Fettinger // XTRA Support 15889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native void native_inject_time(long time, long timeReference, int uncertainty); 15899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native boolean native_supports_xtra(); 15909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native void native_inject_xtra_data(byte[] data, int length); 1591105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project 15923c8fbdf5dd19fad0b3006557716ee1026d7d5899Fred Fettinger // DEBUG Support 15933c8fbdf5dd19fad0b3006557716ee1026d7d5899Fred Fettinger private native String native_get_internal_state(); 15943c8fbdf5dd19fad0b3006557716ee1026d7d5899Fred Fettinger 15953c8fbdf5dd19fad0b3006557716ee1026d7d5899Fred Fettinger // AGPS Support 1596e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood private native void native_agps_data_conn_open(String apn); 1597e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood private native void native_agps_data_conn_closed(); 1598e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood private native void native_agps_data_conn_failed(); 15991e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja private native void native_agps_ni_message(byte [] msg, int length); 1600a9e546169b3c2c9c5f248d2f3abe3b934f48695dMike Lockwood private native void native_set_agps_server(int type, String hostname, int port); 160122d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie 160222d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie // Network-initiated (NI) Support 160322d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie private native void native_send_ni_response(int notificationId, int userResponse); 16041e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja 16051e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja // AGPS ril suport 16061e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja private native void native_agps_set_ref_location_cellid(int type, int mcc, int mnc, 16071e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja int lac, int cid); 16081e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja private native void native_agps_set_id(int type, String setid); 160950130bbc884a7ad7db39dbc4f54e76e8be87761fMike Lockwood 161050130bbc884a7ad7db39dbc4f54e76e8be87761fMike Lockwood private native void native_update_network_state(boolean connected, int type, 161150130bbc884a7ad7db39dbc4f54e76e8be87761fMike Lockwood boolean roaming, String extraInfo); 16129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1613