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; 25a5fe6b2efee02ab11c35e80ec50fec62be227273Kevin Tangimport android.database.Cursor; 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.location.Criteria; 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.location.IGpsStatusListener; 2815e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwoodimport android.location.IGpsStatusProvider; 294e50b78bda9cd58be61581d2886c88ff6348a1c1Mike Lockwoodimport android.location.ILocationManager; 3022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xieimport android.location.INetInitiatedListener; 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.location.Location; 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.location.LocationManager; 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.location.LocationProvider; 3458bda987665af759c379cd494ff4873ac61acf29Mike Lockwoodimport android.net.ConnectivityManager; 3503d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwoodimport android.net.NetworkInfo; 36a5fe6b2efee02ab11c35e80ec50fec62be227273Kevin Tangimport android.net.Uri; 3763aa5a6f98b1016863e4f6edd87eb471b28dc28fMike Lockwoodimport android.os.Binder; 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Bundle; 3962a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwoodimport android.os.Handler; 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.IBinder; 4162a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwoodimport android.os.Looper; 4262a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwoodimport android.os.Message; 430528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwoodimport android.os.PowerManager; 4462a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwoodimport android.os.Process; 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.RemoteException; 462f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwoodimport android.os.ServiceManager; 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.SystemClock; 487e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackbornimport android.os.WorkSource; 49bcab8df83e6e769a7cbcc742e72b47d665998793Mike Lockwoodimport android.provider.Settings; 50a5fe6b2efee02ab11c35e80ec50fec62be227273Kevin Tangimport android.provider.Telephony.Carriers; 511e84da822e7aa4d494b31c8759917d2751611f84Miguel Torrojaimport android.provider.Telephony.Sms.Intents; 52b49a73dfc4c9817bba1f227e9330555acdf9b56fJake Hambyimport android.telephony.SmsMessage; 531e84da822e7aa4d494b31c8759917d2751611f84Miguel Torrojaimport android.telephony.TelephonyManager; 541e84da822e7aa4d494b31c8759917d2751611f84Miguel Torrojaimport android.telephony.gsm.GsmCellLocation; 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Log; 56104344e507610be42fb70c7deda3c422c543bfcbJeff Sharkeyimport android.util.NtpTrustedTime; 572f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwoodimport android.util.SparseIntArray; 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 592f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwoodimport com.android.internal.app.IBatteryStats; 6022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xieimport com.android.internal.location.GpsNetInitiatedHandler; 6122d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xieimport com.android.internal.location.GpsNetInitiatedHandler.GpsNiNotification; 62b49a73dfc4c9817bba1f227e9330555acdf9b56fJake Hambyimport com.android.internal.telephony.Phone; 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; 67104344e507610be42fb70c7deda3c422c543bfcbJeff Sharkeyimport java.io.StringReader; 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.ArrayList; 69f1218be2d8f68f3f445f3bc90e0eca01946a0ddfMike Lockwoodimport java.util.Date; 7022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xieimport java.util.Map.Entry; 71b49a73dfc4c9817bba1f227e9330555acdf9b56fJake Hambyimport java.util.Properties; 7289096317104722219f73a5c3cc424e6e98c90a61Mike Lockwoodimport java.util.concurrent.CountDownLatch; 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * A GPS implementation of LocationProvider used by LocationManager. 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@hide} 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7989096317104722219f73a5c3cc424e6e98c90a61Mike Lockwoodpublic class GpsLocationProvider implements LocationProviderInterface { 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final String TAG = "GpsLocationProvider"; 8229c84340a14e70419449628ab193d11b7a609e9aMike Lockwood 834a7b65e0d544ef1feff8e1e5789f469f89ebb85cMike Lockwood private static final boolean DEBUG = false; 8429c84340a14e70419449628ab193d11b7a609e9aMike Lockwood private static final boolean VERBOSE = false; 8562a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood 86105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project // these need to match GpsPositionMode enum in gps.h 87105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project private static final int GPS_POSITION_MODE_STANDALONE = 0; 88105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project private static final int GPS_POSITION_MODE_MS_BASED = 1; 89105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project private static final int GPS_POSITION_MODE_MS_ASSISTED = 2; 90105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project 9104598b67a58fad93e5060bb77756ba4863013aedMike Lockwood // these need to match GpsPositionRecurrence enum in gps.h 9204598b67a58fad93e5060bb77756ba4863013aedMike Lockwood private static final int GPS_POSITION_RECURRENCE_PERIODIC = 0; 9304598b67a58fad93e5060bb77756ba4863013aedMike Lockwood private static final int GPS_POSITION_RECURRENCE_SINGLE = 1; 9404598b67a58fad93e5060bb77756ba4863013aedMike Lockwood 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // these need to match GpsStatusValue defines in gps.h 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_STATUS_NONE = 0; 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_STATUS_SESSION_BEGIN = 1; 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_STATUS_SESSION_END = 2; 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_STATUS_ENGINE_ON = 3; 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_STATUS_ENGINE_OFF = 4; 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 102e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood // these need to match GpsApgsStatusValue defines in gps.h 103e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood /** AGPS status event values. */ 104e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood private static final int GPS_REQUEST_AGPS_DATA_CONN = 1; 105e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood private static final int GPS_RELEASE_AGPS_DATA_CONN = 2; 106e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood private static final int GPS_AGPS_DATA_CONNECTED = 3; 107e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood private static final int GPS_AGPS_DATA_CONN_DONE = 4; 108e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood private static final int GPS_AGPS_DATA_CONN_FAILED = 5; 10958bda987665af759c379cd494ff4873ac61acf29Mike Lockwood 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // these need to match GpsLocationFlags enum in gps.h 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int LOCATION_INVALID = 0; 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int LOCATION_HAS_LAT_LONG = 1; 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int LOCATION_HAS_ALTITUDE = 2; 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int LOCATION_HAS_SPEED = 4; 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int LOCATION_HAS_BEARING = 8; 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int LOCATION_HAS_ACCURACY = 16; 117e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood 118e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood// IMPORTANT - the GPS_DELETE_* symbols here must match constants in gps.h 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_DELETE_EPHEMERIS = 0x0001; 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_DELETE_ALMANAC = 0x0002; 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_DELETE_POSITION = 0x0004; 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_DELETE_TIME = 0x0008; 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_DELETE_IONO = 0x0010; 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_DELETE_UTC = 0x0020; 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_DELETE_HEALTH = 0x0040; 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_DELETE_SVDIR = 0x0080; 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_DELETE_SVSTEER = 0x0100; 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_DELETE_SADATA = 0x0200; 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_DELETE_RTI = 0x0400; 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_DELETE_CELLDB_INFO = 0x8000; 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_DELETE_ALL = 0xFFFF; 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13304598b67a58fad93e5060bb77756ba4863013aedMike Lockwood // The GPS_CAPABILITY_* flags must match the values in gps.h 13404598b67a58fad93e5060bb77756ba4863013aedMike Lockwood private static final int GPS_CAPABILITY_SCHEDULING = 0x0000001; 13504598b67a58fad93e5060bb77756ba4863013aedMike Lockwood private static final int GPS_CAPABILITY_MSB = 0x0000002; 13604598b67a58fad93e5060bb77756ba4863013aedMike Lockwood private static final int GPS_CAPABILITY_MSA = 0x0000004; 13704598b67a58fad93e5060bb77756ba4863013aedMike Lockwood private static final int GPS_CAPABILITY_SINGLE_SHOT = 0x0000008; 1389b9fb5cc08eaa0b66a80eba2f03168531544f65aMike Lockwood private static final int GPS_CAPABILITY_ON_DEMAND_TIME = 0x0000010; 13904598b67a58fad93e5060bb77756ba4863013aedMike Lockwood 140e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood // these need to match AGpsType enum in gps.h 141e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood private static final int AGPS_TYPE_SUPL = 1; 142e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood private static final int AGPS_TYPE_C2K = 2; 143e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood 144e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood // for mAGpsDataConnectionState 145e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood private static final int AGPS_DATA_CONNECTION_CLOSED = 0; 146e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood private static final int AGPS_DATA_CONNECTION_OPENING = 1; 147e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood private static final int AGPS_DATA_CONNECTION_OPEN = 2; 14858bda987665af759c379cd494ff4873ac61acf29Mike Lockwood 14962a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood // Handler messages 15062a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood private static final int CHECK_LOCATION = 1; 15162a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood private static final int ENABLE = 2; 15262a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood private static final int ENABLE_TRACKING = 3; 15362a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood private static final int UPDATE_NETWORK_STATE = 4; 15462a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood private static final int INJECT_NTP_TIME = 5; 15562a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood private static final int DOWNLOAD_XTRA_DATA = 6; 15662a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood private static final int UPDATE_LOCATION = 7; 15762a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood private static final int ADD_LISTENER = 8; 15862a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood private static final int REMOVE_LISTENER = 9; 15903ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood private static final int REQUEST_SINGLE_SHOT = 10; 16062a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood 1611e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja // Request setid 1621e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja private static final int AGPS_RIL_REQUEST_SETID_IMSI = 1; 1631e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja private static final int AGPS_RIL_REQUEST_SETID_MSISDN = 2; 1641e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja 1651e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja // Request ref location 1661e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja private static final int AGPS_RIL_REQUEST_REFLOC_CELLID = 1; 1671e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja private static final int AGPS_RIL_REQUEST_REFLOC_MAC = 2; 1681e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja 1691e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja // ref. location info 1701e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja private static final int AGPS_REF_LOCATION_TYPE_GSM_CELLID = 1; 1711e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja private static final int AGPS_REF_LOCATION_TYPE_UMTS_CELLID = 2; 1721e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja private static final int AGPS_REG_LOCATION_TYPE_MAC = 3; 1731e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja 1741e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja // set id info 1751e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja private static final int AGPS_SETID_TYPE_NONE = 0; 1761e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja private static final int AGPS_SETID_TYPE_IMSI = 1; 1771e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja private static final int AGPS_SETID_TYPE_MSISDN = 2; 1781e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja 1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final String PROPERTIES_FILE = "/etc/gps.conf"; 1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mLocationFlags = LOCATION_INVALID; 1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // current status 18415e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood private int mStatus = LocationProvider.TEMPORARILY_UNAVAILABLE; 1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // time for last status update 1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private long mStatusUpdateTime = SystemClock.elapsedRealtime(); 188d53ba017ee2381383b4bb4d92e6e0e661431660fMike Lockwood 1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // turn off GPS fix icon if we haven't received a fix in 10 seconds 19004598b67a58fad93e5060bb77756ba4863013aedMike Lockwood private static final long RECENT_FIX_TIMEOUT = 10 * 1000; 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1920632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood // stop trying if we do not receive a fix within 60 seconds 19304598b67a58fad93e5060bb77756ba4863013aedMike Lockwood private static final int NO_FIX_TIMEOUT = 60 * 1000; 1940632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood 195b041f23026536dd287c1a9a962642c84ebd10004Nick Pelly // if the fix interval is below this we leave GPS on, 196b041f23026536dd287c1a9a962642c84ebd10004Nick Pelly // if above then we cycle the GPS driver. 197b041f23026536dd287c1a9a962642c84ebd10004Nick Pelly // Typical hot TTTF is ~5 seconds, so 10 seconds seems sane. 198b041f23026536dd287c1a9a962642c84ebd10004Nick Pelly private static final int GPS_POLLING_THRESHOLD_INTERVAL = 10 * 1000; 199b041f23026536dd287c1a9a962642c84ebd10004Nick Pelly 2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // true if we are enabled 20189096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood private volatile boolean mEnabled; 2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // true if we have network connectivity 2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mNetworkAvailable; 2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 20662a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood // flags to trigger NTP or XTRA data download when network becomes available 20762a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood // initialized to true so we do NTP and XTRA when the network comes up after booting 20862a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood private boolean mInjectNtpTimePending = true; 2095982bf66d4fdea38105d91ff0f9d38660ac87581Mike Lockwood private boolean mDownloadXtraDataPending = true; 21062a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood 2119b9fb5cc08eaa0b66a80eba2f03168531544f65aMike Lockwood // set to true if the GPS engine does not do on-demand NTP time requests 2129b9fb5cc08eaa0b66a80eba2f03168531544f65aMike Lockwood private boolean mPeriodicTimeInjection; 2139b9fb5cc08eaa0b66a80eba2f03168531544f65aMike Lockwood 2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // true if GPS is navigating 2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mNavigating; 216cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood 217cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood // true if GPS engine is on 218cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood private boolean mEngineOn; 2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 22004598b67a58fad93e5060bb77756ba4863013aedMike Lockwood // requested frequency of fixes, in milliseconds 22104598b67a58fad93e5060bb77756ba4863013aedMike Lockwood private int mFixInterval = 1000; 2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // true if we started navigation 2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mStarted; 2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 22603ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood // true if single shot request is in progress 22703ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood private boolean mSingleShot; 22803ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood 22904598b67a58fad93e5060bb77756ba4863013aedMike Lockwood // capabilities of the GPS engine 23004598b67a58fad93e5060bb77756ba4863013aedMike Lockwood private int mEngineCapabilities; 23104598b67a58fad93e5060bb77756ba4863013aedMike Lockwood 2321a1cd3a878b6389c097e34d114b60cf953edaeaaMike Lockwood // true if XTRA is supported 2331a1cd3a878b6389c097e34d114b60cf953edaeaaMike Lockwood private boolean mSupportsXtra; 2341a1cd3a878b6389c097e34d114b60cf953edaeaaMike Lockwood 2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // for calculating time to first fix 2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private long mFixRequestTime = 0; 2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // time to first fix for most recent session 2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mTTFF = 0; 2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // time we received our last fix 2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private long mLastFixTime; 2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 24204598b67a58fad93e5060bb77756ba4863013aedMike Lockwood private int mPositionMode; 24304598b67a58fad93e5060bb77756ba4863013aedMike Lockwood 2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // properties loaded from PROPERTIES_FILE 2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Properties mProperties; 246734d6031a662a275ec68627bd1258159041d44deMike Lockwood private String mSuplServerHost; 247734d6031a662a275ec68627bd1258159041d44deMike Lockwood private int mSuplServerPort; 248734d6031a662a275ec68627bd1258159041d44deMike Lockwood private String mC2KServerHost; 249734d6031a662a275ec68627bd1258159041d44deMike Lockwood private int mC2KServerPort; 2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 25115e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood private final Context mContext; 252104344e507610be42fb70c7deda3c422c543bfcbJeff Sharkey private final NtpTrustedTime mNtpTime; 25315e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood private final ILocationManager mLocationManager; 2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Location mLocation = new Location(LocationManager.GPS_PROVIDER); 2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Bundle mLocationExtras = new Bundle(); 2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private ArrayList<Listener> mListeners = new ArrayList<Listener>(); 25762a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood 25889096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood // GpsLocationProvider's handler thread 25989096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood private final Thread mThread; 26089096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood // Handler for processing events in mThread. 26162a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood private Handler mHandler; 26289096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood // Used to signal when our main thread has initialized everything 26389096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood private final CountDownLatch mInitializedLatch = new CountDownLatch(1); 264105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project 265e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood private String mAGpsApn; 266e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood private int mAGpsDataConnectionState; 2678efd74dbedb65f69734318d9d6be70767f30b57aStephen Li private int mAGpsDataConnectionIpAddr; 2682f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood private final ConnectivityManager mConnMgr; 26922d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie private final GpsNetInitiatedHandler mNIHandler; 2702f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood 2710528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood // Wakelocks 2720528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood private final static String WAKELOCK_KEY = "GpsLocationProvider"; 2730528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood private final PowerManager.WakeLock mWakeLock; 27498e48691f738680fe59e7383a41458e7337daccdMike Lockwood // bitfield of pending messages to our Handler 27598e48691f738680fe59e7383a41458e7337daccdMike Lockwood // used only for messages that cannot have multiple instances queued 27698e48691f738680fe59e7383a41458e7337daccdMike Lockwood private int mPendingMessageBits; 27798e48691f738680fe59e7383a41458e7337daccdMike Lockwood // separate counter for ADD_LISTENER and REMOVE_LISTENER messages, 27898e48691f738680fe59e7383a41458e7337daccdMike Lockwood // which might have multiple instances queued 27998e48691f738680fe59e7383a41458e7337daccdMike Lockwood private int mPendingListenerMessages; 2800528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood 28129c84340a14e70419449628ab193d11b7a609e9aMike Lockwood // Alarms 28229c84340a14e70419449628ab193d11b7a609e9aMike Lockwood private final static String ALARM_WAKEUP = "com.android.internal.location.ALARM_WAKEUP"; 2830632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood private final static String ALARM_TIMEOUT = "com.android.internal.location.ALARM_TIMEOUT"; 28429c84340a14e70419449628ab193d11b7a609e9aMike Lockwood private final AlarmManager mAlarmManager; 28529c84340a14e70419449628ab193d11b7a609e9aMike Lockwood private final PendingIntent mWakeupIntent; 2860632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood private final PendingIntent mTimeoutIntent; 28729c84340a14e70419449628ab193d11b7a609e9aMike Lockwood 2882f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood private final IBatteryStats mBatteryStats; 2892f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood private final SparseIntArray mClientUids = new SparseIntArray(); 290105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project 2919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // how often to request NTP time, in milliseconds 2924c126068527c9adba45aa227d40e245ee8e7c9a4Mike Lockwood // current setting 24 hours 2934c126068527c9adba45aa227d40e245ee8e7c9a4Mike Lockwood private static final long NTP_INTERVAL = 24*60*60*1000; 2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // how long to wait if we have a network error in NTP or XTRA downloading 2959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // current setting - 5 minutes 296f1218be2d8f68f3f445f3bc90e0eca01946a0ddfMike Lockwood private static final long RETRY_INTERVAL = 5*60*1000; 297f1218be2d8f68f3f445f3bc90e0eca01946a0ddfMike Lockwood 29815e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood private final IGpsStatusProvider mGpsStatusProvider = new IGpsStatusProvider.Stub() { 29915e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood public void addGpsStatusListener(IGpsStatusListener listener) throws RemoteException { 30015e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood if (listener == null) { 30115e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood throw new NullPointerException("listener is null in addGpsStatusListener"); 30215e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 30315e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood 30415e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood synchronized(mListeners) { 30515e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood IBinder binder = listener.asBinder(); 30615e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood int size = mListeners.size(); 30715e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood for (int i = 0; i < size; i++) { 30815e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood Listener test = mListeners.get(i); 30915e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood if (binder.equals(test.mListener.asBinder())) { 31015e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood // listener already added 31115e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood return; 31215e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 31315e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 31415e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood 31515e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood Listener l = new Listener(listener); 31615e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood binder.linkToDeath(l, 0); 31715e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood mListeners.add(l); 31815e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 31915e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 32015e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood 32115e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood public void removeGpsStatusListener(IGpsStatusListener listener) { 32215e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood if (listener == null) { 32315e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood throw new NullPointerException("listener is null in addGpsStatusListener"); 32415e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 32515e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood 32615e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood synchronized(mListeners) { 32715e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood IBinder binder = listener.asBinder(); 32815e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood Listener l = null; 32915e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood int size = mListeners.size(); 33015e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood for (int i = 0; i < size && l == null; i++) { 33115e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood Listener test = mListeners.get(i); 33215e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood if (binder.equals(test.mListener.asBinder())) { 33315e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood l = test; 33415e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 33515e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 33615e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood 33715e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood if (l != null) { 33815e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood mListeners.remove(l); 33915e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood binder.unlinkToDeath(l, 0); 34015e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 34115e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 34215e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 34315e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood }; 34415e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood 34515e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood public IGpsStatusProvider getGpsStatusProvider() { 34615e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood return mGpsStatusProvider; 34715e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 34815e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood 34929c84340a14e70419449628ab193d11b7a609e9aMike Lockwood private final BroadcastReceiver mBroadcastReciever = new BroadcastReceiver() { 350105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project @Override public void onReceive(Context context, Intent intent) { 351105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project String action = intent.getAction(); 352105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project 35329c84340a14e70419449628ab193d11b7a609e9aMike Lockwood if (action.equals(ALARM_WAKEUP)) { 35429c84340a14e70419449628ab193d11b7a609e9aMike Lockwood if (DEBUG) Log.d(TAG, "ALARM_WAKEUP"); 35503ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood startNavigating(false); 3560632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood } else if (action.equals(ALARM_TIMEOUT)) { 3570632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood if (DEBUG) Log.d(TAG, "ALARM_TIMEOUT"); 3580632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood hibernate(); 3591e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja } else if (action.equals(Intents.DATA_SMS_RECEIVED_ACTION)) { 3601e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja checkSmsSuplInit(intent); 3611e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja } else if (action.equals(Intents.WAP_PUSH_RECEIVED_ACTION)) { 3621e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja checkWapSuplInit(intent); 3631e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja } 364105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project } 36529c84340a14e70419449628ab193d11b7a609e9aMike Lockwood }; 366105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project 3671e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja private void checkSmsSuplInit(Intent intent) { 3681e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja SmsMessage[] messages = Intents.getMessagesFromIntent(intent); 3691e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja for (int i=0; i <messages.length; i++) { 3701e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja byte[] supl_init = messages[i].getUserData(); 3711e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja native_agps_ni_message(supl_init,supl_init.length); 3721e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja } 3731e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja } 3741e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja 3751e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja private void checkWapSuplInit(Intent intent) { 3761e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja byte[] supl_init = (byte[]) intent.getExtra("data"); 3771e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja native_agps_ni_message(supl_init,supl_init.length); 3781e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja } 3791e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja 3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static boolean isSupported() { 3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return native_is_supported(); 3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3844e50b78bda9cd58be61581d2886c88ff6348a1c1Mike Lockwood public GpsLocationProvider(Context context, ILocationManager locationManager) { 3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContext = context; 386104344e507610be42fb70c7deda3c422c543bfcbJeff Sharkey mNtpTime = NtpTrustedTime.getInstance(context); 38715e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood mLocationManager = locationManager; 38879e642e8ed75033eacc461633a8f4cd5157d25dfMike Lockwood mNIHandler = new GpsNetInitiatedHandler(context); 38963598a0619776b421f27cd12fb29eb83dc327997Mike Lockwood 39063598a0619776b421f27cd12fb29eb83dc327997Mike Lockwood mLocation.setExtras(mLocationExtras); 3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3920528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood // Create a wake lock 3930528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood PowerManager powerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE); 3940528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, WAKELOCK_KEY); 39598e48691f738680fe59e7383a41458e7337daccdMike Lockwood mWakeLock.setReferenceCounted(false); 3960528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood 39729c84340a14e70419449628ab193d11b7a609e9aMike Lockwood mAlarmManager = (AlarmManager)mContext.getSystemService(Context.ALARM_SERVICE); 39829c84340a14e70419449628ab193d11b7a609e9aMike Lockwood mWakeupIntent = PendingIntent.getBroadcast(mContext, 0, new Intent(ALARM_WAKEUP), 0); 3990632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood mTimeoutIntent = PendingIntent.getBroadcast(mContext, 0, new Intent(ALARM_TIMEOUT), 0); 40029c84340a14e70419449628ab193d11b7a609e9aMike Lockwood 4011e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja IntentFilter intentFilter = new IntentFilter(); 4021e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja intentFilter.addAction(Intents.DATA_SMS_RECEIVED_ACTION); 4031e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja intentFilter.addDataScheme("sms"); 4041e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja intentFilter.addDataAuthority("localhost","7275"); 4051e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja context.registerReceiver(mBroadcastReciever, intentFilter); 4061e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja 4071e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja intentFilter = new IntentFilter(); 4081e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja intentFilter.addAction(Intents.WAP_PUSH_RECEIVED_ACTION); 4091e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja try { 4101e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja intentFilter.addDataType("application/vnd.omaloc-supl-init"); 4111e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja } catch (IntentFilter.MalformedMimeTypeException e) { 4121e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja Log.w(TAG, "Malformed SUPL init mime type"); 4131e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja } 4141e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja context.registerReceiver(mBroadcastReciever, intentFilter); 4151e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja 41658bda987665af759c379cd494ff4873ac61acf29Mike Lockwood mConnMgr = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE); 41758bda987665af759c379cd494ff4873ac61acf29Mike Lockwood 4182f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood // Battery statistics service to be notified when GPS turns on or off 4192f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood mBatteryStats = IBatteryStats.Stub.asInterface(ServiceManager.getService("batteryinfo")); 4202f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood 4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mProperties = new Properties(); 4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project File file = new File(PROPERTIES_FILE); 4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project FileInputStream stream = new FileInputStream(file); 4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mProperties.load(stream); 4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project stream.close(); 427e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood 428734d6031a662a275ec68627bd1258159041d44deMike Lockwood mSuplServerHost = mProperties.getProperty("SUPL_HOST"); 429e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood String portString = mProperties.getProperty("SUPL_PORT"); 430734d6031a662a275ec68627bd1258159041d44deMike Lockwood if (mSuplServerHost != null && portString != null) { 431105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project try { 432734d6031a662a275ec68627bd1258159041d44deMike Lockwood mSuplServerPort = Integer.parseInt(portString); 433105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project } catch (NumberFormatException e) { 434e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood Log.e(TAG, "unable to parse SUPL_PORT: " + portString); 435e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood } 436e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood } 437e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood 438734d6031a662a275ec68627bd1258159041d44deMike Lockwood mC2KServerHost = mProperties.getProperty("C2K_HOST"); 439e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood portString = mProperties.getProperty("C2K_PORT"); 440734d6031a662a275ec68627bd1258159041d44deMike Lockwood if (mC2KServerHost != null && portString != null) { 441e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood try { 442734d6031a662a275ec68627bd1258159041d44deMike Lockwood mC2KServerPort = Integer.parseInt(portString); 443e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood } catch (NumberFormatException e) { 444e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood Log.e(TAG, "unable to parse C2K_PORT: " + portString); 445105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project } 446105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project } 4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (IOException e) { 4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.w(TAG, "Could not open GPS configuration file " + PROPERTIES_FILE); 4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 45062a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood 45189096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood // wait until we are fully initialized before returning 45289096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood mThread = new GpsLocationProviderThread(); 45389096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood mThread.start(); 45489096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood while (true) { 45589096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood try { 45689096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood mInitializedLatch.await(); 45789096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood break; 45889096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood } catch (InterruptedException e) { 45989096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood Thread.currentThread().interrupt(); 46089096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood } 46189096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood } 46262a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood } 46362a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood 46462a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood private void initialize() { 46562a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood // register our receiver on our thread rather than the main thread 46662a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood IntentFilter intentFilter = new IntentFilter(); 46762a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood intentFilter.addAction(ALARM_WAKEUP); 46862a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood intentFilter.addAction(ALARM_TIMEOUT); 46962a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood mContext.registerReceiver(mBroadcastReciever, intentFilter); 4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 473d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood * Returns the name of this provider. 474d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood */ 475d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood public String getName() { 476d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood return LocationManager.GPS_PROVIDER; 477d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood } 478d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood 479d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood /** 4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns true if the provider requires access to a 4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * data network (e.g., the Internet), false otherwise. 4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean requiresNetwork() { 484a9e546169b3c2c9c5f248d2f3abe3b934f48695dMike Lockwood return true; 4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 48703d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood public void updateNetworkState(int state, NetworkInfo info) { 48898e48691f738680fe59e7383a41458e7337daccdMike Lockwood sendMessage(UPDATE_NETWORK_STATE, state, info); 48962a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood } 49062a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood 49162a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood private void handleUpdateNetworkState(int state, NetworkInfo info) { 4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNetworkAvailable = (state == LocationProvider.AVAILABLE); 4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 494f5d95cbc1a6974afeb4d3155bdaa8dae55722a39Joe Onorato if (DEBUG) { 49503d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood Log.d(TAG, "updateNetworkState " + (mNetworkAvailable ? "available" : "unavailable") 49603d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood + " info: " + info); 4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 49803d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood 49950130bbc884a7ad7db39dbc4f54e76e8be87761fMike Lockwood if (info != null) { 500a5fe6b2efee02ab11c35e80ec50fec62be227273Kevin Tang boolean dataEnabled = Settings.Secure.getInt(mContext.getContentResolver(), 501a5fe6b2efee02ab11c35e80ec50fec62be227273Kevin Tang Settings.Secure.MOBILE_DATA, 1) == 1; 502a5fe6b2efee02ab11c35e80ec50fec62be227273Kevin Tang boolean networkAvailable = info.isAvailable() && dataEnabled; 503a5fe6b2efee02ab11c35e80ec50fec62be227273Kevin Tang String defaultApn = getSelectedApn(); 504a5fe6b2efee02ab11c35e80ec50fec62be227273Kevin Tang if (defaultApn == null) { 505a5fe6b2efee02ab11c35e80ec50fec62be227273Kevin Tang defaultApn = "dummy-apn"; 506a5fe6b2efee02ab11c35e80ec50fec62be227273Kevin Tang } 507a5fe6b2efee02ab11c35e80ec50fec62be227273Kevin Tang 50850130bbc884a7ad7db39dbc4f54e76e8be87761fMike Lockwood native_update_network_state(info.isConnected(), info.getType(), 509a5fe6b2efee02ab11c35e80ec50fec62be227273Kevin Tang info.isRoaming(), networkAvailable, 510a5fe6b2efee02ab11c35e80ec50fec62be227273Kevin Tang info.getExtraInfo(), defaultApn); 51150130bbc884a7ad7db39dbc4f54e76e8be87761fMike Lockwood } 51250130bbc884a7ad7db39dbc4f54e76e8be87761fMike Lockwood 51303d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood if (info != null && info.getType() == ConnectivityManager.TYPE_MOBILE_SUPL 51403d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood && mAGpsDataConnectionState == AGPS_DATA_CONNECTION_OPENING) { 51503d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood String apnName = info.getExtraInfo(); 51683b69713f2dbeee7ff5e07836673a9a477be236fStephen Li if (mNetworkAvailable) { 51783b69713f2dbeee7ff5e07836673a9a477be236fStephen Li if (apnName == null) { 51883b69713f2dbeee7ff5e07836673a9a477be236fStephen Li /* Assign a dummy value in the case of C2K as otherwise we will have a runtime 51983b69713f2dbeee7ff5e07836673a9a477be236fStephen Li exception in the following call to native_agps_data_conn_open*/ 52083b69713f2dbeee7ff5e07836673a9a477be236fStephen Li apnName = "dummy-apn"; 52183b69713f2dbeee7ff5e07836673a9a477be236fStephen Li } 52203d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood mAGpsApn = apnName; 5238efd74dbedb65f69734318d9d6be70767f30b57aStephen Li if (DEBUG) Log.d(TAG, "mAGpsDataConnectionIpAddr " + mAGpsDataConnectionIpAddr); 5248efd74dbedb65f69734318d9d6be70767f30b57aStephen Li if (mAGpsDataConnectionIpAddr != 0xffffffff) { 5258efd74dbedb65f69734318d9d6be70767f30b57aStephen Li boolean route_result; 5268efd74dbedb65f69734318d9d6be70767f30b57aStephen Li if (DEBUG) Log.d(TAG, "call requestRouteToHost"); 5278efd74dbedb65f69734318d9d6be70767f30b57aStephen Li route_result = mConnMgr.requestRouteToHost(ConnectivityManager.TYPE_MOBILE_SUPL, 5288efd74dbedb65f69734318d9d6be70767f30b57aStephen Li mAGpsDataConnectionIpAddr); 5298efd74dbedb65f69734318d9d6be70767f30b57aStephen Li if (route_result == false) Log.d(TAG, "call requestRouteToHost failed"); 5308efd74dbedb65f69734318d9d6be70767f30b57aStephen Li } 53103d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood if (DEBUG) Log.d(TAG, "call native_agps_data_conn_open"); 53203d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood native_agps_data_conn_open(apnName); 53303d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood mAGpsDataConnectionState = AGPS_DATA_CONNECTION_OPEN; 53403d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood } else { 53503d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood if (DEBUG) Log.d(TAG, "call native_agps_data_conn_failed"); 53603d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood mAGpsApn = null; 53703d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood mAGpsDataConnectionState = AGPS_DATA_CONNECTION_CLOSED; 53803d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood native_agps_data_conn_failed(); 53903d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood } 54003d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood } 54103d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood 54262a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood if (mNetworkAvailable) { 54362a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood if (mInjectNtpTimePending) { 54498e48691f738680fe59e7383a41458e7337daccdMike Lockwood sendMessage(INJECT_NTP_TIME, 0, null); 54562a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood } 54662a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood if (mDownloadXtraDataPending) { 54798e48691f738680fe59e7383a41458e7337daccdMike Lockwood sendMessage(DOWNLOAD_XTRA_DATA, 0, null); 54862a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood } 54962a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood } 55062a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood } 55162a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood 55262a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood private void handleInjectNtpTime() { 55362a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood if (!mNetworkAvailable) { 55462a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood // try again when network is up 55562a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood mInjectNtpTimePending = true; 55662a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood return; 55762a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood } 55862a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood mInjectNtpTimePending = false; 55962a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood 56062a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood long delay; 56162a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood 562104344e507610be42fb70c7deda3c422c543bfcbJeff Sharkey // force refresh NTP cache when outdated 563104344e507610be42fb70c7deda3c422c543bfcbJeff Sharkey if (mNtpTime.getCacheAge() >= NTP_INTERVAL) { 564104344e507610be42fb70c7deda3c422c543bfcbJeff Sharkey mNtpTime.forceRefresh(); 565104344e507610be42fb70c7deda3c422c543bfcbJeff Sharkey } 566104344e507610be42fb70c7deda3c422c543bfcbJeff Sharkey 567104344e507610be42fb70c7deda3c422c543bfcbJeff Sharkey // only update when NTP time is fresh 568104344e507610be42fb70c7deda3c422c543bfcbJeff Sharkey if (mNtpTime.getCacheAge() < NTP_INTERVAL) { 569104344e507610be42fb70c7deda3c422c543bfcbJeff Sharkey long time = mNtpTime.getCachedNtpTime(); 570104344e507610be42fb70c7deda3c422c543bfcbJeff Sharkey long timeReference = mNtpTime.getCachedNtpTimeReference(); 571104344e507610be42fb70c7deda3c422c543bfcbJeff Sharkey long certainty = mNtpTime.getCacheCertainty(); 57262a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood long now = System.currentTimeMillis(); 57362a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood 57462a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood Log.d(TAG, "NTP server returned: " 57562a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood + time + " (" + new Date(time) 57662a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood + ") reference: " + timeReference 57762a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood + " certainty: " + certainty 5781879d284bf3dd704dbc8c95aad262ebbe3c3c0a4Mike Lockwood + " system time offset: " + (time - now)); 57962a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood 580104344e507610be42fb70c7deda3c422c543bfcbJeff Sharkey native_inject_time(time, timeReference, (int) certainty); 58162a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood delay = NTP_INTERVAL; 58262a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood } else { 58362a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood if (DEBUG) Log.d(TAG, "requestTime failed"); 58462a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood delay = RETRY_INTERVAL; 58562a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood } 58662a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood 5879b9fb5cc08eaa0b66a80eba2f03168531544f65aMike Lockwood if (mPeriodicTimeInjection) { 5889b9fb5cc08eaa0b66a80eba2f03168531544f65aMike Lockwood // send delayed message for next NTP injection 5899b9fb5cc08eaa0b66a80eba2f03168531544f65aMike Lockwood // since this is delayed and not urgent we do not hold a wake lock here 5909b9fb5cc08eaa0b66a80eba2f03168531544f65aMike Lockwood mHandler.removeMessages(INJECT_NTP_TIME); 5919b9fb5cc08eaa0b66a80eba2f03168531544f65aMike Lockwood mHandler.sendMessageDelayed(Message.obtain(mHandler, INJECT_NTP_TIME), delay); 5929b9fb5cc08eaa0b66a80eba2f03168531544f65aMike Lockwood } 59362a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood } 59462a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood 59562a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood private void handleDownloadXtraData() { 5965723dfe8c87d0887b8926f43637ed300466890d2Mike Lockwood if (!mNetworkAvailable) { 59762a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood // try again when network is up 59862a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood mDownloadXtraDataPending = true; 59962a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood return; 60062a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood } 60162a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood mDownloadXtraDataPending = false; 60262a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood 60362a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood 60462a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood GpsXtraDownloader xtraDownloader = new GpsXtraDownloader(mContext, mProperties); 60562a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood byte[] data = xtraDownloader.downloadXtraData(); 60662a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood if (data != null) { 60762a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood if (DEBUG) { 60862a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood Log.d(TAG, "calling native_inject_xtra_data"); 60962a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood } 61062a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood native_inject_xtra_data(data, data.length); 61162a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood } else { 61262a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood // try again later 61398e48691f738680fe59e7383a41458e7337daccdMike Lockwood // since this is delayed and not urgent we do not hold a wake lock here 61462a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood mHandler.removeMessages(DOWNLOAD_XTRA_DATA); 61562a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood mHandler.sendMessageDelayed(Message.obtain(mHandler, DOWNLOAD_XTRA_DATA), RETRY_INTERVAL); 61662a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood } 6179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 620fd6e5f0dda50e113db4ccc55338b6c4f09da37a4Mike Lockwood * This is called to inform us when another location provider returns a location. 621fd6e5f0dda50e113db4ccc55338b6c4f09da37a4Mike Lockwood * Someday we might use this for network location injection to aid the GPS 622fd6e5f0dda50e113db4ccc55338b6c4f09da37a4Mike Lockwood */ 623fd6e5f0dda50e113db4ccc55338b6c4f09da37a4Mike Lockwood public void updateLocation(Location location) { 62498e48691f738680fe59e7383a41458e7337daccdMike Lockwood sendMessage(UPDATE_LOCATION, 0, location); 62562a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood } 62662a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood 62762a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood private void handleUpdateLocation(Location location) { 628d26ce0d903f5141a346d67b2b94437ef3e2880aaMike Lockwood if (location.hasAccuracy()) { 629d26ce0d903f5141a346d67b2b94437ef3e2880aaMike Lockwood native_inject_location(location.getLatitude(), location.getLongitude(), 630d26ce0d903f5141a346d67b2b94437ef3e2880aaMike Lockwood location.getAccuracy()); 631d26ce0d903f5141a346d67b2b94437ef3e2880aaMike Lockwood } 632fd6e5f0dda50e113db4ccc55338b6c4f09da37a4Mike Lockwood } 633fd6e5f0dda50e113db4ccc55338b6c4f09da37a4Mike Lockwood 634fd6e5f0dda50e113db4ccc55338b6c4f09da37a4Mike Lockwood /** 6359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns true if the provider requires access to a 6369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * satellite-based positioning system (e.g., GPS), false 6379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * otherwise. 6389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean requiresSatellite() { 6409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 6419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns true if the provider requires access to an appropriate 6459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * cellular network (e.g., to make use of cell tower IDs), false 6469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * otherwise. 6479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean requiresCell() { 6499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 6509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns true if the use of this provider may result in a 6549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * monetary charge to the user, false if use is free. It is up to 6559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * each provider to give accurate information. 6569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean hasMonetaryCost() { 6589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 6599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns true if the provider is able to provide altitude 6639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * information, false otherwise. A provider that reports altitude 6649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * under most circumstances but may occassionally not report it 6659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * should return true. 6669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean supportsAltitude() { 6689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 6699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns true if the provider is able to provide speed 6739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * information, false otherwise. A provider that reports speed 6749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * under most circumstances but may occassionally not report it 6759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * should return true. 6769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean supportsSpeed() { 6789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 6799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns true if the provider is able to provide bearing 6839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * information, false otherwise. A provider that reports bearing 6849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * under most circumstances but may occassionally not report it 6859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * should return true. 6869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean supportsBearing() { 6889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 6899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns the power requirement for this provider. 6939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 6949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the power requirement for this provider, as one of the 6959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * constants Criteria.POWER_REQUIREMENT_*. 6969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getPowerRequirement() { 6989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return Criteria.POWER_HIGH; 6999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 70203ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood * Returns true if this provider meets the given criteria, 70303ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood * false otherwise. 70403ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood */ 70503ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood public boolean meetsCriteria(Criteria criteria) { 70603ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood return (criteria.getPowerRequirement() != Criteria.POWER_LOW); 70703ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood } 70803ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood 70903ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood /** 7109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns the horizontal accuracy of this provider 7119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 7129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the accuracy of location from this provider, as one 7139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * of the constants Criteria.ACCURACY_*. 7149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getAccuracy() { 7169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return Criteria.ACCURACY_FINE; 7179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Enables this provider. When enabled, calls to getStatus() 7214e50b78bda9cd58be61581d2886c88ff6348a1c1Mike Lockwood * must be handled. Hardware may be started up 7229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * when the provider is enabled. 7239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 72462a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood public void enable() { 72562a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood synchronized (mHandler) { 72698e48691f738680fe59e7383a41458e7337daccdMike Lockwood sendMessage(ENABLE, 1, null); 72762a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood } 72862a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood } 72962a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood 73062a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood private void handleEnable() { 73162a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood if (DEBUG) Log.d(TAG, "handleEnable"); 7329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mEnabled) return; 7339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEnabled = native_init(); 7349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mEnabled) { 7361a1cd3a878b6389c097e34d114b60cf953edaeaaMike Lockwood mSupportsXtra = native_supports_xtra(); 737734d6031a662a275ec68627bd1258159041d44deMike Lockwood if (mSuplServerHost != null) { 738734d6031a662a275ec68627bd1258159041d44deMike Lockwood native_set_agps_server(AGPS_TYPE_SUPL, mSuplServerHost, mSuplServerPort); 739734d6031a662a275ec68627bd1258159041d44deMike Lockwood } 740734d6031a662a275ec68627bd1258159041d44deMike Lockwood if (mC2KServerHost != null) { 741734d6031a662a275ec68627bd1258159041d44deMike Lockwood native_set_agps_server(AGPS_TYPE_C2K, mC2KServerHost, mC2KServerPort); 742734d6031a662a275ec68627bd1258159041d44deMike Lockwood } 7439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 7449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.w(TAG, "Failed to enable location provider"); 7459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Disables this provider. When disabled, calls to getStatus() 7504e50b78bda9cd58be61581d2886c88ff6348a1c1Mike Lockwood * need not be handled. Hardware may be shut 7519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * down while the provider is disabled. 7529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 75362a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood public void disable() { 75462a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood synchronized (mHandler) { 75598e48691f738680fe59e7383a41458e7337daccdMike Lockwood sendMessage(ENABLE, 0, null); 75662a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood } 75762a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood } 75862a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood 75962a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood private void handleDisable() { 76089096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood if (DEBUG) Log.d(TAG, "handleDisable"); 7619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mEnabled) return; 7629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEnabled = false; 7649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project stopNavigating(); 7659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 766cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood // do this before releasing wakelock 767cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood native_cleanup(); 7689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 770d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood public boolean isEnabled() { 771d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood return mEnabled; 772d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood } 773d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood 7749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getStatus(Bundle extras) { 7759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras != null) { 7769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project extras.putInt("satellites", mSvCount); 7779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mStatus; 7799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void updateStatus(int status, int svCount) { 7829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (status != mStatus || svCount != mSvCount) { 7839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStatus = status; 7849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSvCount = svCount; 7859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocationExtras.putInt("satellites", svCount); 7869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStatusUpdateTime = SystemClock.elapsedRealtime(); 7879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public long getStatusUpdateTime() { 7919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mStatusUpdateTime; 7929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void enableLocationTracking(boolean enable) { 79503ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood // FIXME - should set a flag here to avoid race conditions with single shot request 79662a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood synchronized (mHandler) { 79798e48691f738680fe59e7383a41458e7337daccdMike Lockwood sendMessage(ENABLE_TRACKING, (enable ? 1 : 0), null); 79862a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood } 79962a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood } 80062a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood 80162a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood private void handleEnableLocationTracking(boolean enable) { 8029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (enable) { 8039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTTFF = 0; 8049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLastFixTime = 0; 80503ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood startNavigating(false); 8069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 80704598b67a58fad93e5060bb77756ba4863013aedMike Lockwood if (!hasCapability(GPS_CAPABILITY_SCHEDULING)) { 80804598b67a58fad93e5060bb77756ba4863013aedMike Lockwood mAlarmManager.cancel(mWakeupIntent); 80904598b67a58fad93e5060bb77756ba4863013aedMike Lockwood mAlarmManager.cancel(mTimeoutIntent); 81004598b67a58fad93e5060bb77756ba4863013aedMike Lockwood } 8119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project stopNavigating(); 8129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 81503ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood public boolean requestSingleShotFix() { 81603ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood if (mStarted) { 81703ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood // cannot do single shot if already navigating 81803ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood return false; 81903ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood } 82003ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood synchronized (mHandler) { 82103ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood mHandler.removeMessages(REQUEST_SINGLE_SHOT); 82203ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood Message m = Message.obtain(mHandler, REQUEST_SINGLE_SHOT); 82303ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood mHandler.sendMessage(m); 82403ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood } 82503ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood return true; 82603ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood } 82703ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood 82803ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood private void handleRequestSingleShot() { 82903ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood mTTFF = 0; 83003ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood mLastFixTime = 0; 83103ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood startNavigating(true); 83203ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood } 83303ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood 8347e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn public void setMinTime(long minTime, WorkSource ws) { 835f5d95cbc1a6974afeb4d3155bdaa8dae55722a39Joe Onorato if (DEBUG) Log.d(TAG, "setMinTime " + minTime); 8369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (minTime >= 0) { 83804598b67a58fad93e5060bb77756ba4863013aedMike Lockwood mFixInterval = (int)minTime; 83904598b67a58fad93e5060bb77756ba4863013aedMike Lockwood 84004598b67a58fad93e5060bb77756ba4863013aedMike Lockwood if (mStarted && hasCapability(GPS_CAPABILITY_SCHEDULING)) { 84104598b67a58fad93e5060bb77756ba4863013aedMike Lockwood if (!native_set_position_mode(mPositionMode, GPS_POSITION_RECURRENCE_PERIODIC, 84204598b67a58fad93e5060bb77756ba4863013aedMike Lockwood mFixInterval, 0, 0)) { 84304598b67a58fad93e5060bb77756ba4863013aedMike Lockwood Log.e(TAG, "set_position_mode failed in setMinTime()"); 84404598b67a58fad93e5060bb77756ba4863013aedMike Lockwood } 8459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8493c8fbdf5dd19fad0b3006557716ee1026d7d5899Fred Fettinger public String getInternalState() { 850b041f23026536dd287c1a9a962642c84ebd10004Nick Pelly StringBuilder s = new StringBuilder(); 851b041f23026536dd287c1a9a962642c84ebd10004Nick Pelly s.append(" mFixInterval=").append(mFixInterval).append("\n"); 852b041f23026536dd287c1a9a962642c84ebd10004Nick Pelly s.append(" mEngineCapabilities=0x").append(Integer.toHexString(mEngineCapabilities)).append(" ("); 853b041f23026536dd287c1a9a962642c84ebd10004Nick Pelly if (hasCapability(GPS_CAPABILITY_SCHEDULING)) s.append("SCHED "); 854b041f23026536dd287c1a9a962642c84ebd10004Nick Pelly if (hasCapability(GPS_CAPABILITY_MSB)) s.append("MSB "); 855b041f23026536dd287c1a9a962642c84ebd10004Nick Pelly if (hasCapability(GPS_CAPABILITY_MSA)) s.append("MSA "); 856b041f23026536dd287c1a9a962642c84ebd10004Nick Pelly if (hasCapability(GPS_CAPABILITY_SINGLE_SHOT)) s.append("SINGLE_SHOT "); 857b041f23026536dd287c1a9a962642c84ebd10004Nick Pelly if (hasCapability(GPS_CAPABILITY_ON_DEMAND_TIME)) s.append("ON_DEMAND_TIME "); 858b041f23026536dd287c1a9a962642c84ebd10004Nick Pelly s.append(")\n"); 859b041f23026536dd287c1a9a962642c84ebd10004Nick Pelly 860b041f23026536dd287c1a9a962642c84ebd10004Nick Pelly s.append(native_get_internal_state()); 861b041f23026536dd287c1a9a962642c84ebd10004Nick Pelly return s.toString(); 8623c8fbdf5dd19fad0b3006557716ee1026d7d5899Fred Fettinger } 8633c8fbdf5dd19fad0b3006557716ee1026d7d5899Fred Fettinger 8649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final class Listener implements IBinder.DeathRecipient { 8659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final IGpsStatusListener mListener; 8669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int mSensors = 0; 8689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Listener(IGpsStatusListener listener) { 8709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mListener = listener; 8719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void binderDied() { 874f5d95cbc1a6974afeb4d3155bdaa8dae55722a39Joe Onorato if (DEBUG) Log.d(TAG, "GPS status listener died"); 8759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized(mListeners) { 8779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mListeners.remove(this); 8789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 879fff2fda0199dedbf1079454dca98a81190dce765Suchi Amalapurapu if (mListener != null) { 880fff2fda0199dedbf1079454dca98a81190dce765Suchi Amalapurapu mListener.asBinder().unlinkToDeath(this, 0); 881fff2fda0199dedbf1079454dca98a81190dce765Suchi Amalapurapu } 8829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8852f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood public void addListener(int uid) { 88698e48691f738680fe59e7383a41458e7337daccdMike Lockwood synchronized (mWakeLock) { 88798e48691f738680fe59e7383a41458e7337daccdMike Lockwood mPendingListenerMessages++; 8887e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn mWakeLock.acquire(); 88998e48691f738680fe59e7383a41458e7337daccdMike Lockwood Message m = Message.obtain(mHandler, ADD_LISTENER); 89098e48691f738680fe59e7383a41458e7337daccdMike Lockwood m.arg1 = uid; 89198e48691f738680fe59e7383a41458e7337daccdMike Lockwood mHandler.sendMessage(m); 89298e48691f738680fe59e7383a41458e7337daccdMike Lockwood } 89362a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood } 89462a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood 89562a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood private void handleAddListener(int uid) { 8962e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn synchronized(mListeners) { 8972e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn if (mClientUids.indexOfKey(uid) >= 0) { 8982e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn // Shouldn't be here -- already have this uid. 8992e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn Log.w(TAG, "Duplicate add listener for uid " + uid); 9002e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn return; 9012e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn } 9022e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn mClientUids.put(uid, 0); 9032e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn if (mNavigating) { 9042e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn try { 9052e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn mBatteryStats.noteStartGps(uid); 9062e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn } catch (RemoteException e) { 9072e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn Log.w(TAG, "RemoteException in addListener"); 9082e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn } 9092f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } 9102f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } 9112f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } 9122f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood 9132f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood public void removeListener(int uid) { 91498e48691f738680fe59e7383a41458e7337daccdMike Lockwood synchronized (mWakeLock) { 91598e48691f738680fe59e7383a41458e7337daccdMike Lockwood mPendingListenerMessages++; 91698e48691f738680fe59e7383a41458e7337daccdMike Lockwood mWakeLock.acquire(); 91798e48691f738680fe59e7383a41458e7337daccdMike Lockwood Message m = Message.obtain(mHandler, REMOVE_LISTENER); 91898e48691f738680fe59e7383a41458e7337daccdMike Lockwood m.arg1 = uid; 91998e48691f738680fe59e7383a41458e7337daccdMike Lockwood mHandler.sendMessage(m); 92098e48691f738680fe59e7383a41458e7337daccdMike Lockwood } 92162a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood } 92262a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood 92362a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood private void handleRemoveListener(int uid) { 9242e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn synchronized(mListeners) { 9252e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn if (mClientUids.indexOfKey(uid) < 0) { 9262e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn // Shouldn't be here -- don't have this uid. 9272e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn Log.w(TAG, "Unneeded remove listener for uid " + uid); 9282e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn return; 9292e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn } 9302e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn mClientUids.delete(uid); 9312e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn if (mNavigating) { 9322e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn try { 9332e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn mBatteryStats.noteStopGps(uid); 9342e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn } catch (RemoteException e) { 9352e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn Log.w(TAG, "RemoteException in removeListener"); 9362e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn } 9372f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } 9382f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } 9392f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } 9402f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood 9419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean sendExtraCommand(String command, Bundle extras) { 9429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 94363aa5a6f98b1016863e4f6edd87eb471b28dc28fMike Lockwood long identity = Binder.clearCallingIdentity(); 94463aa5a6f98b1016863e4f6edd87eb471b28dc28fMike Lockwood boolean result = false; 94563aa5a6f98b1016863e4f6edd87eb471b28dc28fMike Lockwood 9469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ("delete_aiding_data".equals(command)) { 94763aa5a6f98b1016863e4f6edd87eb471b28dc28fMike Lockwood result = deleteAidingData(extras); 94863aa5a6f98b1016863e4f6edd87eb471b28dc28fMike Lockwood } else if ("force_time_injection".equals(command)) { 94998e48691f738680fe59e7383a41458e7337daccdMike Lockwood sendMessage(INJECT_NTP_TIME, 0, null); 95063aa5a6f98b1016863e4f6edd87eb471b28dc28fMike Lockwood result = true; 95163aa5a6f98b1016863e4f6edd87eb471b28dc28fMike Lockwood } else if ("force_xtra_injection".equals(command)) { 9521a1cd3a878b6389c097e34d114b60cf953edaeaaMike Lockwood if (mSupportsXtra) { 95393bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood xtraDownloadRequest(); 95463aa5a6f98b1016863e4f6edd87eb471b28dc28fMike Lockwood result = true; 95593bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood } 95663aa5a6f98b1016863e4f6edd87eb471b28dc28fMike Lockwood } else { 95763aa5a6f98b1016863e4f6edd87eb471b28dc28fMike Lockwood Log.w(TAG, "sendExtraCommand: unknown command " + command); 95893bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood } 9599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 96063aa5a6f98b1016863e4f6edd87eb471b28dc28fMike Lockwood Binder.restoreCallingIdentity(identity); 96163aa5a6f98b1016863e4f6edd87eb471b28dc28fMike Lockwood return result; 9629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean deleteAidingData(Bundle extras) { 9659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int flags; 9669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras == null) { 9689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project flags = GPS_DELETE_ALL; 9699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 9709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project flags = 0; 9719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("ephemeris")) flags |= GPS_DELETE_EPHEMERIS; 9729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("almanac")) flags |= GPS_DELETE_ALMANAC; 9739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("position")) flags |= GPS_DELETE_POSITION; 9749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("time")) flags |= GPS_DELETE_TIME; 9759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("iono")) flags |= GPS_DELETE_IONO; 9769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("utc")) flags |= GPS_DELETE_UTC; 9779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("health")) flags |= GPS_DELETE_HEALTH; 9789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("svdir")) flags |= GPS_DELETE_SVDIR; 9799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("svsteer")) flags |= GPS_DELETE_SVSTEER; 9809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("sadata")) flags |= GPS_DELETE_SADATA; 9819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("rti")) flags |= GPS_DELETE_RTI; 9829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("celldb-info")) flags |= GPS_DELETE_CELLDB_INFO; 9839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("all")) flags |= GPS_DELETE_ALL; 9849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (flags != 0) { 9879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project native_delete_aiding_data(flags); 9889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 9899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 9929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 99403ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood private void startNavigating(boolean singleShot) { 9959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mStarted) { 99629c84340a14e70419449628ab193d11b7a609e9aMike Lockwood if (DEBUG) Log.d(TAG, "startNavigating"); 9979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStarted = true; 99803ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood mSingleShot = singleShot; 99903ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood mPositionMode = GPS_POSITION_MODE_STANDALONE; 100003ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood 100103ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood if (Settings.Secure.getInt(mContext.getContentResolver(), 1002660bbfcc54d48d5d32e64da683c76b9c372c19b1Mike Lockwood Settings.Secure.ASSISTED_GPS_ENABLED, 1) != 0) { 100303ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood if (singleShot && hasCapability(GPS_CAPABILITY_MSA)) { 100403ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood mPositionMode = GPS_POSITION_MODE_MS_ASSISTED; 10058dc16c27e23dae5bdf65fd2a2ced97c2f645a633Mike Lockwood } else if (hasCapability(GPS_CAPABILITY_MSB)) { 100603ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood mPositionMode = GPS_POSITION_MODE_MS_BASED; 100703ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood } 1008bcab8df83e6e769a7cbcc742e72b47d665998793Mike Lockwood } 1009bcab8df83e6e769a7cbcc742e72b47d665998793Mike Lockwood 101004598b67a58fad93e5060bb77756ba4863013aedMike Lockwood int interval = (hasCapability(GPS_CAPABILITY_SCHEDULING) ? mFixInterval : 1000); 101104598b67a58fad93e5060bb77756ba4863013aedMike Lockwood if (!native_set_position_mode(mPositionMode, GPS_POSITION_RECURRENCE_PERIODIC, 101204598b67a58fad93e5060bb77756ba4863013aedMike Lockwood interval, 0, 0)) { 101304598b67a58fad93e5060bb77756ba4863013aedMike Lockwood mStarted = false; 101404598b67a58fad93e5060bb77756ba4863013aedMike Lockwood Log.e(TAG, "set_position_mode failed in startNavigating()"); 101504598b67a58fad93e5060bb77756ba4863013aedMike Lockwood return; 101604598b67a58fad93e5060bb77756ba4863013aedMike Lockwood } 101704598b67a58fad93e5060bb77756ba4863013aedMike Lockwood if (!native_start()) { 10189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStarted = false; 10199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.e(TAG, "native_start failed in startNavigating()"); 10200632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood return; 10219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // reset SV count to zero 102415e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood updateStatus(LocationProvider.TEMPORARILY_UNAVAILABLE, 0); 102529c84340a14e70419449628ab193d11b7a609e9aMike Lockwood mFixRequestTime = System.currentTimeMillis(); 102604598b67a58fad93e5060bb77756ba4863013aedMike Lockwood if (!hasCapability(GPS_CAPABILITY_SCHEDULING)) { 102704598b67a58fad93e5060bb77756ba4863013aedMike Lockwood // set timer to give up if we do not receive a fix within NO_FIX_TIMEOUT 102804598b67a58fad93e5060bb77756ba4863013aedMike Lockwood // and our fix interval is not short 102904598b67a58fad93e5060bb77756ba4863013aedMike Lockwood if (mFixInterval >= NO_FIX_TIMEOUT) { 103004598b67a58fad93e5060bb77756ba4863013aedMike Lockwood mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, 103104598b67a58fad93e5060bb77756ba4863013aedMike Lockwood SystemClock.elapsedRealtime() + NO_FIX_TIMEOUT, mTimeoutIntent); 103204598b67a58fad93e5060bb77756ba4863013aedMike Lockwood } 10330632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood } 10349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 103762a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood private void stopNavigating() { 103829c84340a14e70419449628ab193d11b7a609e9aMike Lockwood if (DEBUG) Log.d(TAG, "stopNavigating"); 10399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mStarted) { 10409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStarted = false; 104103ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood mSingleShot = false; 10429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project native_stop(); 10439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTTFF = 0; 10449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLastFixTime = 0; 10459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocationFlags = LOCATION_INVALID; 10469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // reset SV count to zero 104815e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood updateStatus(LocationProvider.TEMPORARILY_UNAVAILABLE, 0); 10499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10520632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood private void hibernate() { 10530632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood // stop GPS until our next fix interval arrives 10540632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood stopNavigating(); 10550632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood mAlarmManager.cancel(mTimeoutIntent); 10560632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood mAlarmManager.cancel(mWakeupIntent); 10570632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood long now = SystemClock.elapsedRealtime(); 10580632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, 105904598b67a58fad93e5060bb77756ba4863013aedMike Lockwood SystemClock.elapsedRealtime() + mFixInterval, mWakeupIntent); 106004598b67a58fad93e5060bb77756ba4863013aedMike Lockwood } 106104598b67a58fad93e5060bb77756ba4863013aedMike Lockwood 106204598b67a58fad93e5060bb77756ba4863013aedMike Lockwood private boolean hasCapability(int capability) { 106304598b67a58fad93e5060bb77756ba4863013aedMike Lockwood return ((mEngineCapabilities & capability) != 0); 10640632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood } 10650632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood 10669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 10679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * called from native code to update our position. 10689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 10699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void reportLocation(int flags, double latitude, double longitude, double altitude, 10709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float speed, float bearing, float accuracy, long timestamp) { 107129c84340a14e70419449628ab193d11b7a609e9aMike Lockwood if (VERBOSE) Log.v(TAG, "reportLocation lat: " + latitude + " long: " + longitude + 10729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project " timestamp: " + timestamp); 10739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mLocation) { 10759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocationFlags = flags; 10769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((flags & LOCATION_HAS_LAT_LONG) == LOCATION_HAS_LAT_LONG) { 10779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocation.setLatitude(latitude); 10789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocation.setLongitude(longitude); 10799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocation.setTime(timestamp); 10809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((flags & LOCATION_HAS_ALTITUDE) == LOCATION_HAS_ALTITUDE) { 10829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocation.setAltitude(altitude); 10839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 10849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocation.removeAltitude(); 10859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((flags & LOCATION_HAS_SPEED) == LOCATION_HAS_SPEED) { 10879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocation.setSpeed(speed); 10889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 10899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocation.removeSpeed(); 10909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((flags & LOCATION_HAS_BEARING) == LOCATION_HAS_BEARING) { 10929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocation.setBearing(bearing); 10939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 10949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocation.removeBearing(); 10959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((flags & LOCATION_HAS_ACCURACY) == LOCATION_HAS_ACCURACY) { 10979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocation.setAccuracy(accuracy); 10989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 10999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocation.removeAccuracy(); 11009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1101ced2b2c09a209e017f02cf28ddd9d35b2d8b8adaSean Barbeau mLocation.setExtras(mLocationExtras); 11029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 110315e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood try { 1104a4903f254b4711c8fc0ac5f7e3d605f4dce34f35Mike Lockwood mLocationManager.reportLocation(mLocation, false); 110515e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } catch (RemoteException e) { 110615e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood Log.e(TAG, "RemoteException calling reportLocation"); 110715e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 11089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1110fa94ff074d3200fae2f5d14a6d0f454e2ad23cfaHakan Gustavsson mLastFixTime = System.currentTimeMillis(); 1111fa94ff074d3200fae2f5d14a6d0f454e2ad23cfaHakan Gustavsson // report time to first fix 1112fa94ff074d3200fae2f5d14a6d0f454e2ad23cfaHakan Gustavsson if (mTTFF == 0 && (flags & LOCATION_HAS_LAT_LONG) == LOCATION_HAS_LAT_LONG) { 1113fa94ff074d3200fae2f5d14a6d0f454e2ad23cfaHakan Gustavsson mTTFF = (int)(mLastFixTime - mFixRequestTime); 1114f4dffd8a45386b5a5f0e6de4f30facc9eaac4001The Android Open Source Project if (DEBUG) Log.d(TAG, "TTFF: " + mTTFF); 1115fa94ff074d3200fae2f5d14a6d0f454e2ad23cfaHakan Gustavsson 1116fa94ff074d3200fae2f5d14a6d0f454e2ad23cfaHakan Gustavsson // notify status listeners 1117fa94ff074d3200fae2f5d14a6d0f454e2ad23cfaHakan Gustavsson synchronized(mListeners) { 1118fa94ff074d3200fae2f5d14a6d0f454e2ad23cfaHakan Gustavsson int size = mListeners.size(); 1119fa94ff074d3200fae2f5d14a6d0f454e2ad23cfaHakan Gustavsson for (int i = 0; i < size; i++) { 1120fa94ff074d3200fae2f5d14a6d0f454e2ad23cfaHakan Gustavsson Listener listener = mListeners.get(i); 1121fa94ff074d3200fae2f5d14a6d0f454e2ad23cfaHakan Gustavsson try { 1122f4dffd8a45386b5a5f0e6de4f30facc9eaac4001The Android Open Source Project listener.mListener.onFirstFix(mTTFF); 1123fa94ff074d3200fae2f5d14a6d0f454e2ad23cfaHakan Gustavsson } catch (RemoteException e) { 1124fa94ff074d3200fae2f5d14a6d0f454e2ad23cfaHakan Gustavsson Log.w(TAG, "RemoteException in stopNavigating"); 1125fa94ff074d3200fae2f5d14a6d0f454e2ad23cfaHakan Gustavsson mListeners.remove(listener); 1126fa94ff074d3200fae2f5d14a6d0f454e2ad23cfaHakan Gustavsson // adjust for size of list changing 1127fa94ff074d3200fae2f5d14a6d0f454e2ad23cfaHakan Gustavsson size--; 1128fa94ff074d3200fae2f5d14a6d0f454e2ad23cfaHakan Gustavsson } 1129fa94ff074d3200fae2f5d14a6d0f454e2ad23cfaHakan Gustavsson } 1130fa94ff074d3200fae2f5d14a6d0f454e2ad23cfaHakan Gustavsson } 1131fa94ff074d3200fae2f5d14a6d0f454e2ad23cfaHakan Gustavsson } 1132fa94ff074d3200fae2f5d14a6d0f454e2ad23cfaHakan Gustavsson 113303ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood if (mSingleShot) { 113403ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood stopNavigating(); 113503ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood } 113615e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood if (mStarted && mStatus != LocationProvider.AVAILABLE) { 1137d53ba017ee2381383b4bb4d92e6e0e661431660fMike Lockwood // we want to time out if we do not receive a fix 1138b7be5447a002b4a1cf7d4030cc8a0a330cd7517cMike Lockwood // within the time out and we are requesting infrequent fixes 113904598b67a58fad93e5060bb77756ba4863013aedMike Lockwood if (!hasCapability(GPS_CAPABILITY_SCHEDULING) && mFixInterval < NO_FIX_TIMEOUT) { 1140b7be5447a002b4a1cf7d4030cc8a0a330cd7517cMike Lockwood mAlarmManager.cancel(mTimeoutIntent); 1141b7be5447a002b4a1cf7d4030cc8a0a330cd7517cMike Lockwood } 1142b7be5447a002b4a1cf7d4030cc8a0a330cd7517cMike Lockwood 11439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // send an intent to notify that the GPS is receiving fixes. 114400b74270c9f136a8727c5f6cda0997a3a905f385Mike Lockwood Intent intent = new Intent(LocationManager.GPS_FIX_CHANGE_ACTION); 114500b74270c9f136a8727c5f6cda0997a3a905f385Mike Lockwood intent.putExtra(LocationManager.EXTRA_GPS_ENABLED, true); 11469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContext.sendBroadcast(intent); 114715e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood updateStatus(LocationProvider.AVAILABLE, mSvCount); 11489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 114929c84340a14e70419449628ab193d11b7a609e9aMike Lockwood 1150b041f23026536dd287c1a9a962642c84ebd10004Nick Pelly if (!hasCapability(GPS_CAPABILITY_SCHEDULING) && mStarted && 1151b041f23026536dd287c1a9a962642c84ebd10004Nick Pelly mFixInterval > GPS_POLLING_THRESHOLD_INTERVAL) { 1152d53ba017ee2381383b4bb4d92e6e0e661431660fMike Lockwood if (DEBUG) Log.d(TAG, "got fix, hibernating"); 11530632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood hibernate(); 115429c84340a14e70419449628ab193d11b7a609e9aMike Lockwood } 11559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 11589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * called from native code to update our status 11599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 11609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void reportStatus(int status) { 1161b8d9033d9928209e68518c4b12fea74187ddb382Mike Lockwood if (DEBUG) Log.v(TAG, "reportStatus status: " + status); 11629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11632e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn synchronized(mListeners) { 11642e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn boolean wasNavigating = mNavigating; 1165dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood 1166cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood switch (status) { 1167cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood case GPS_STATUS_SESSION_BEGIN: 1168cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood mNavigating = true; 1169271f9f172b241607b1ed39a7709c3ed47ee5dee7Mike Lockwood mEngineOn = true; 1170cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood break; 1171cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood case GPS_STATUS_SESSION_END: 1172cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood mNavigating = false; 1173cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood break; 1174cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood case GPS_STATUS_ENGINE_ON: 1175cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood mEngineOn = true; 1176cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood break; 1177cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood case GPS_STATUS_ENGINE_OFF: 1178cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood mEngineOn = false; 1179271f9f172b241607b1ed39a7709c3ed47ee5dee7Mike Lockwood mNavigating = false; 1180cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood break; 1181cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood } 1182cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood 1183dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood if (wasNavigating != mNavigating) { 1184dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood int size = mListeners.size(); 1185dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood for (int i = 0; i < size; i++) { 1186dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood Listener listener = mListeners.get(i); 1187dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood try { 1188dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood if (mNavigating) { 1189dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood listener.mListener.onGpsStarted(); 1190dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood } else { 1191dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood listener.mListener.onGpsStopped(); 1192dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood } 1193dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood } catch (RemoteException e) { 1194dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood Log.w(TAG, "RemoteException in reportStatus"); 1195dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood mListeners.remove(listener); 1196dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood // adjust for size of list changing 1197dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood size--; 1198dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood } 1199dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood } 1200dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood 12012e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn try { 1202dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood // update battery stats 1203dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood for (int i=mClientUids.size() - 1; i >= 0; i--) { 1204dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood int uid = mClientUids.keyAt(i); 1205dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood if (mNavigating) { 1206dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood mBatteryStats.noteStartGps(uid); 1207dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood } else { 1208dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood mBatteryStats.noteStopGps(uid); 1209dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood } 12109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12112e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn } catch (RemoteException e) { 12122e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn Log.w(TAG, "RemoteException in reportStatus"); 12139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1215dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood // send an intent to notify that the GPS has been enabled or disabled. 121600b74270c9f136a8727c5f6cda0997a3a905f385Mike Lockwood Intent intent = new Intent(LocationManager.GPS_ENABLED_CHANGE_ACTION); 121700b74270c9f136a8727c5f6cda0997a3a905f385Mike Lockwood intent.putExtra(LocationManager.EXTRA_GPS_ENABLED, mNavigating); 1218dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood mContext.sendBroadcast(intent); 12192f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } 12209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 12249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * called from native code to update SV info 12259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 12269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void reportSvStatus() { 12279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int svCount = native_read_sv_status(mSvs, mSnrs, mSvElevations, mSvAzimuths, mSvMasks); 12299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized(mListeners) { 12319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int size = mListeners.size(); 12329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < size; i++) { 12339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Listener listener = mListeners.get(i); 12349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 12359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project listener.mListener.onSvStatusChanged(svCount, mSvs, mSnrs, 12369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSvElevations, mSvAzimuths, mSvMasks[EPHEMERIS_MASK], 12379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSvMasks[ALMANAC_MASK], mSvMasks[USED_FOR_FIX_MASK]); 12389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 12399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.w(TAG, "RemoteException in reportSvInfo"); 12409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mListeners.remove(listener); 12419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // adjust for size of list changing 12429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size--; 12439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 124729c84340a14e70419449628ab193d11b7a609e9aMike Lockwood if (VERBOSE) { 124829c84340a14e70419449628ab193d11b7a609e9aMike Lockwood Log.v(TAG, "SV count: " + svCount + 12499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project " ephemerisMask: " + Integer.toHexString(mSvMasks[EPHEMERIS_MASK]) + 12509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project " almanacMask: " + Integer.toHexString(mSvMasks[ALMANAC_MASK])); 12519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < svCount; i++) { 125229c84340a14e70419449628ab193d11b7a609e9aMike Lockwood Log.v(TAG, "sv: " + mSvs[i] + 12539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project " snr: " + (float)mSnrs[i]/10 + 12549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project " elev: " + mSvElevations[i] + 12559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project " azimuth: " + mSvAzimuths[i] + 12569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ((mSvMasks[EPHEMERIS_MASK] & (1 << (mSvs[i] - 1))) == 0 ? " " : " E") + 12579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ((mSvMasks[ALMANAC_MASK] & (1 << (mSvs[i] - 1))) == 0 ? " " : " A") + 12589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ((mSvMasks[USED_FOR_FIX_MASK] & (1 << (mSvs[i] - 1))) == 0 ? "" : "U")); 12599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12620881f4f9339febee85c9ab4cba69970ac5cbde55Kevin.KY Tsai // return number of sets used in fix instead of total 12630881f4f9339febee85c9ab4cba69970ac5cbde55Kevin.KY Tsai updateStatus(mStatus, Integer.bitCount(mSvMasks[USED_FOR_FIX_MASK])); 12649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 126515e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood if (mNavigating && mStatus == LocationProvider.AVAILABLE && mLastFixTime > 0 && 126604598b67a58fad93e5060bb77756ba4863013aedMike Lockwood System.currentTimeMillis() - mLastFixTime > RECENT_FIX_TIMEOUT) { 12679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // send an intent to notify that the GPS is no longer receiving fixes. 126800b74270c9f136a8727c5f6cda0997a3a905f385Mike Lockwood Intent intent = new Intent(LocationManager.GPS_FIX_CHANGE_ACTION); 126900b74270c9f136a8727c5f6cda0997a3a905f385Mike Lockwood intent.putExtra(LocationManager.EXTRA_GPS_ENABLED, false); 12709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContext.sendBroadcast(intent); 127115e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood updateStatus(LocationProvider.TEMPORARILY_UNAVAILABLE, mSvCount); 12729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 127458bda987665af759c379cd494ff4873ac61acf29Mike Lockwood 127558bda987665af759c379cd494ff4873ac61acf29Mike Lockwood /** 1276e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood * called from native code to update AGPS status 127758bda987665af759c379cd494ff4873ac61acf29Mike Lockwood */ 12788efd74dbedb65f69734318d9d6be70767f30b57aStephen Li private void reportAGpsStatus(int type, int status, int ipaddr) { 127958bda987665af759c379cd494ff4873ac61acf29Mike Lockwood switch (status) { 1280e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood case GPS_REQUEST_AGPS_DATA_CONN: 1281b6e5fa895c03eeefaa810eaceb498254096c093dMike Lockwood if (DEBUG) Log.d(TAG, "GPS_REQUEST_AGPS_DATA_CONN"); 12822acfd34ccbd39258422333c9c66c586297c97683Mike Lockwood // Set mAGpsDataConnectionState before calling startUsingNetworkFeature 12832acfd34ccbd39258422333c9c66c586297c97683Mike Lockwood // to avoid a race condition with handleUpdateNetworkState() 12842acfd34ccbd39258422333c9c66c586297c97683Mike Lockwood mAGpsDataConnectionState = AGPS_DATA_CONNECTION_OPENING; 12852acfd34ccbd39258422333c9c66c586297c97683Mike Lockwood int result = mConnMgr.startUsingNetworkFeature( 128658bda987665af759c379cd494ff4873ac61acf29Mike Lockwood ConnectivityManager.TYPE_MOBILE, Phone.FEATURE_ENABLE_SUPL); 12878efd74dbedb65f69734318d9d6be70767f30b57aStephen Li mAGpsDataConnectionIpAddr = ipaddr; 128858bda987665af759c379cd494ff4873ac61acf29Mike Lockwood if (result == Phone.APN_ALREADY_ACTIVE) { 12892d4d1bf14b531de9d4238b1e41b53c77f8976405Mike Lockwood if (DEBUG) Log.d(TAG, "Phone.APN_ALREADY_ACTIVE"); 1290b362a9ab91bb4c05ef1d5c4e7019499257c7f849Mike Lockwood if (mAGpsApn != null) { 12918efd74dbedb65f69734318d9d6be70767f30b57aStephen Li Log.d(TAG, "mAGpsDataConnectionIpAddr " + mAGpsDataConnectionIpAddr); 12928efd74dbedb65f69734318d9d6be70767f30b57aStephen Li if (mAGpsDataConnectionIpAddr != 0xffffffff) { 12938efd74dbedb65f69734318d9d6be70767f30b57aStephen Li boolean route_result; 12948efd74dbedb65f69734318d9d6be70767f30b57aStephen Li if (DEBUG) Log.d(TAG, "call requestRouteToHost"); 12958efd74dbedb65f69734318d9d6be70767f30b57aStephen Li route_result = mConnMgr.requestRouteToHost( 12968efd74dbedb65f69734318d9d6be70767f30b57aStephen Li ConnectivityManager.TYPE_MOBILE_SUPL, 12978efd74dbedb65f69734318d9d6be70767f30b57aStephen Li mAGpsDataConnectionIpAddr); 12988efd74dbedb65f69734318d9d6be70767f30b57aStephen Li if (route_result == false) Log.d(TAG, "call requestRouteToHost failed"); 12998efd74dbedb65f69734318d9d6be70767f30b57aStephen Li } 1300b362a9ab91bb4c05ef1d5c4e7019499257c7f849Mike Lockwood native_agps_data_conn_open(mAGpsApn); 1301b362a9ab91bb4c05ef1d5c4e7019499257c7f849Mike Lockwood mAGpsDataConnectionState = AGPS_DATA_CONNECTION_OPEN; 1302b362a9ab91bb4c05ef1d5c4e7019499257c7f849Mike Lockwood } else { 1303b362a9ab91bb4c05ef1d5c4e7019499257c7f849Mike Lockwood Log.e(TAG, "mAGpsApn not set when receiving Phone.APN_ALREADY_ACTIVE"); 13042acfd34ccbd39258422333c9c66c586297c97683Mike Lockwood mAGpsDataConnectionState = AGPS_DATA_CONNECTION_CLOSED; 1305b362a9ab91bb4c05ef1d5c4e7019499257c7f849Mike Lockwood native_agps_data_conn_failed(); 1306b362a9ab91bb4c05ef1d5c4e7019499257c7f849Mike Lockwood } 130758bda987665af759c379cd494ff4873ac61acf29Mike Lockwood } else if (result == Phone.APN_REQUEST_STARTED) { 13084a7b65e0d544ef1feff8e1e5789f469f89ebb85cMike Lockwood if (DEBUG) Log.d(TAG, "Phone.APN_REQUEST_STARTED"); 13092acfd34ccbd39258422333c9c66c586297c97683Mike Lockwood // Nothing to do here 131058bda987665af759c379cd494ff4873ac61acf29Mike Lockwood } else { 1311b8d9033d9928209e68518c4b12fea74187ddb382Mike Lockwood if (DEBUG) Log.d(TAG, "startUsingNetworkFeature failed"); 13122acfd34ccbd39258422333c9c66c586297c97683Mike Lockwood mAGpsDataConnectionState = AGPS_DATA_CONNECTION_CLOSED; 1313e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood native_agps_data_conn_failed(); 131458bda987665af759c379cd494ff4873ac61acf29Mike Lockwood } 131558bda987665af759c379cd494ff4873ac61acf29Mike Lockwood break; 1316e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood case GPS_RELEASE_AGPS_DATA_CONN: 1317b6e5fa895c03eeefaa810eaceb498254096c093dMike Lockwood if (DEBUG) Log.d(TAG, "GPS_RELEASE_AGPS_DATA_CONN"); 1318e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood if (mAGpsDataConnectionState != AGPS_DATA_CONNECTION_CLOSED) { 131958bda987665af759c379cd494ff4873ac61acf29Mike Lockwood mConnMgr.stopUsingNetworkFeature( 132058bda987665af759c379cd494ff4873ac61acf29Mike Lockwood ConnectivityManager.TYPE_MOBILE, Phone.FEATURE_ENABLE_SUPL); 1321e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood native_agps_data_conn_closed(); 1322e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood mAGpsDataConnectionState = AGPS_DATA_CONNECTION_CLOSED; 132358bda987665af759c379cd494ff4873ac61acf29Mike Lockwood } 132458bda987665af759c379cd494ff4873ac61acf29Mike Lockwood break; 1325e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood case GPS_AGPS_DATA_CONNECTED: 1326b6e5fa895c03eeefaa810eaceb498254096c093dMike Lockwood if (DEBUG) Log.d(TAG, "GPS_AGPS_DATA_CONNECTED"); 132758bda987665af759c379cd494ff4873ac61acf29Mike Lockwood break; 1328e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood case GPS_AGPS_DATA_CONN_DONE: 1329b6e5fa895c03eeefaa810eaceb498254096c093dMike Lockwood if (DEBUG) Log.d(TAG, "GPS_AGPS_DATA_CONN_DONE"); 133058bda987665af759c379cd494ff4873ac61acf29Mike Lockwood break; 1331e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood case GPS_AGPS_DATA_CONN_FAILED: 1332b6e5fa895c03eeefaa810eaceb498254096c093dMike Lockwood if (DEBUG) Log.d(TAG, "GPS_AGPS_DATA_CONN_FAILED"); 133358bda987665af759c379cd494ff4873ac61acf29Mike Lockwood break; 133458bda987665af759c379cd494ff4873ac61acf29Mike Lockwood } 133558bda987665af759c379cd494ff4873ac61acf29Mike Lockwood } 133658bda987665af759c379cd494ff4873ac61acf29Mike Lockwood 1337b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood /** 1338b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood * called from native code to report NMEA data received 1339b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood */ 1340f602d362ba4bb3adbf1eb4e38a794fb14274293aMike Lockwood private void reportNmea(long timestamp) { 1341b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood synchronized(mListeners) { 1342b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood int size = mListeners.size(); 1343b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood if (size > 0) { 1344b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood // don't bother creating the String if we have no listeners 1345f602d362ba4bb3adbf1eb4e38a794fb14274293aMike Lockwood int length = native_read_nmea(mNmeaBuffer, mNmeaBuffer.length); 1346b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood String nmea = new String(mNmeaBuffer, 0, length); 1347b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood 1348b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood for (int i = 0; i < size; i++) { 1349b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood Listener listener = mListeners.get(i); 1350b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood try { 1351b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood listener.mListener.onNmeaReceived(timestamp, nmea); 1352b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood } catch (RemoteException e) { 1353b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood Log.w(TAG, "RemoteException in reportNmea"); 1354b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood mListeners.remove(listener); 1355b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood // adjust for size of list changing 1356b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood size--; 1357b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood } 1358b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood } 1359b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood } 1360b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood } 1361b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood } 1362b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood 136362a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood /** 136404598b67a58fad93e5060bb77756ba4863013aedMike Lockwood * called from native code to inform us what the GPS engine capabilities are 136504598b67a58fad93e5060bb77756ba4863013aedMike Lockwood */ 136604598b67a58fad93e5060bb77756ba4863013aedMike Lockwood private void setEngineCapabilities(int capabilities) { 136704598b67a58fad93e5060bb77756ba4863013aedMike Lockwood mEngineCapabilities = capabilities; 13689b9fb5cc08eaa0b66a80eba2f03168531544f65aMike Lockwood 13699b9fb5cc08eaa0b66a80eba2f03168531544f65aMike Lockwood if (!hasCapability(GPS_CAPABILITY_ON_DEMAND_TIME) && !mPeriodicTimeInjection) { 13709b9fb5cc08eaa0b66a80eba2f03168531544f65aMike Lockwood mPeriodicTimeInjection = true; 13719b9fb5cc08eaa0b66a80eba2f03168531544f65aMike Lockwood requestUtcTime(); 13729b9fb5cc08eaa0b66a80eba2f03168531544f65aMike Lockwood } 137304598b67a58fad93e5060bb77756ba4863013aedMike Lockwood } 137404598b67a58fad93e5060bb77756ba4863013aedMike Lockwood 137504598b67a58fad93e5060bb77756ba4863013aedMike Lockwood /** 137662a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood * called from native code to request XTRA data 137762a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood */ 13789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void xtraDownloadRequest() { 1379f5d95cbc1a6974afeb4d3155bdaa8dae55722a39Joe Onorato if (DEBUG) Log.d(TAG, "xtraDownloadRequest"); 138098e48691f738680fe59e7383a41458e7337daccdMike Lockwood sendMessage(DOWNLOAD_XTRA_DATA, 0, null); 13819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 138322d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie //============================================================= 138422d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie // NI Client support 13851e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja //============================================================= 138622d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie private final INetInitiatedListener mNetInitiatedListener = new INetInitiatedListener.Stub() { 13871e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja // Sends a response for an NI reqeust to HAL. 13881e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja public boolean sendNiResponse(int notificationId, int userResponse) 13891e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja { 13901e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja // TODO Add Permission check 13911e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja 13921e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja StringBuilder extrasBuf = new StringBuilder(); 13931e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja 13941e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja if (DEBUG) Log.d(TAG, "sendNiResponse, notifId: " + notificationId + 13951e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja ", response: " + userResponse); 13961e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja native_send_ni_response(notificationId, userResponse); 13971e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja return true; 13981e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja } 139922d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie }; 140022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie 140122d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie public INetInitiatedListener getNetInitiatedListener() { 140222d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie return mNetInitiatedListener; 140322d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie } 140422d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie 140522d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie // Called by JNI function to report an NI request. 14061e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja public void reportNiNotification( 14071e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja int notificationId, 14081e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja int niType, 14091e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja int notifyFlags, 14101e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja int timeout, 14111e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja int defaultResponse, 14121e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja String requestorId, 14131e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja String text, 14141e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja int requestorIdEncoding, 14151e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja int textEncoding, 14161e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja String extras // Encoded extra data 141722d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie ) 14181e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja { 14191e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja Log.i(TAG, "reportNiNotification: entered"); 14201e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja Log.i(TAG, "notificationId: " + notificationId + 14211e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja ", niType: " + niType + 14221e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja ", notifyFlags: " + notifyFlags + 14231e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja ", timeout: " + timeout + 14241e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja ", defaultResponse: " + defaultResponse); 14251e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja 14261e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja Log.i(TAG, "requestorId: " + requestorId + 14271e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja ", text: " + text + 14281e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja ", requestorIdEncoding: " + requestorIdEncoding + 14291e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja ", textEncoding: " + textEncoding); 14301e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja 14311e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja GpsNiNotification notification = new GpsNiNotification(); 14321e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja 14331e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja notification.notificationId = notificationId; 14341e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja notification.niType = niType; 14351e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja notification.needNotify = (notifyFlags & GpsNetInitiatedHandler.GPS_NI_NEED_NOTIFY) != 0; 14361e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja notification.needVerify = (notifyFlags & GpsNetInitiatedHandler.GPS_NI_NEED_VERIFY) != 0; 14371e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja notification.privacyOverride = (notifyFlags & GpsNetInitiatedHandler.GPS_NI_PRIVACY_OVERRIDE) != 0; 14381e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja notification.timeout = timeout; 14391e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja notification.defaultResponse = defaultResponse; 14401e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja notification.requestorId = requestorId; 14411e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja notification.text = text; 14421e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja notification.requestorIdEncoding = requestorIdEncoding; 14431e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja notification.textEncoding = textEncoding; 14441e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja 14451e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja // Process extras, assuming the format is 14461e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja // one of more lines of "key = value" 14471e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja Bundle bundle = new Bundle(); 14481e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja 14491e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja if (extras == null) extras = ""; 14501e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja Properties extraProp = new Properties(); 14511e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja 14521e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja try { 1453104344e507610be42fb70c7deda3c422c543bfcbJeff Sharkey extraProp.load(new StringReader(extras)); 14541e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja } 14551e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja catch (IOException e) 14561e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja { 14571e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja Log.e(TAG, "reportNiNotification cannot parse extras data: " + extras); 14581e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja } 14591e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja 14601e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja for (Entry<Object, Object> ent : extraProp.entrySet()) 14611e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja { 14621e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja bundle.putString((String) ent.getKey(), (String) ent.getValue()); 14631e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja } 14641e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja 14651e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja notification.extras = bundle; 14661e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja 14671e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja mNIHandler.handleNiNotification(notification); 14681e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja } 14691e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja 14701e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja /** 14711e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja * Called from native code to request set id info. 14721e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja * We should be careful about receiving null string from the TelephonyManager, 14731e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja * because sending null String to JNI function would cause a crash. 14741e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja */ 14751e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja 14761e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja private void requestSetID(int flags) { 14771e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja TelephonyManager phone = (TelephonyManager) 14781e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja mContext.getSystemService(Context.TELEPHONY_SERVICE); 14791e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja int type = AGPS_SETID_TYPE_NONE; 14801e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja String data = ""; 14811e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja 14821e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja if ((flags & AGPS_RIL_REQUEST_SETID_IMSI) == AGPS_RIL_REQUEST_SETID_IMSI) { 14831e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja String data_temp = phone.getSubscriberId(); 14841e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja if (data_temp == null) { 14851e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja // This means the framework does not have the SIM card ready. 14861e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja } else { 14871e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja // This means the framework has the SIM card. 14881e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja data = data_temp; 14891e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja type = AGPS_SETID_TYPE_IMSI; 14901e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja } 14911e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja } 14921e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja else if ((flags & AGPS_RIL_REQUEST_SETID_MSISDN) == AGPS_RIL_REQUEST_SETID_MSISDN) { 14931e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja String data_temp = phone.getLine1Number(); 14941e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja if (data_temp == null) { 14951e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja // This means the framework does not have the SIM card ready. 14961e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja } else { 14971e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja // This means the framework has the SIM card. 14981e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja data = data_temp; 14991e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja type = AGPS_SETID_TYPE_MSISDN; 15001e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja } 15011e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja } 15021e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja native_agps_set_id(type, data); 15031e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja } 15041e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja 15051e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja /** 15069b9fb5cc08eaa0b66a80eba2f03168531544f65aMike Lockwood * Called from native code to request utc time info 15079b9fb5cc08eaa0b66a80eba2f03168531544f65aMike Lockwood */ 15089b9fb5cc08eaa0b66a80eba2f03168531544f65aMike Lockwood 15099b9fb5cc08eaa0b66a80eba2f03168531544f65aMike Lockwood private void requestUtcTime() { 15109b9fb5cc08eaa0b66a80eba2f03168531544f65aMike Lockwood sendMessage(INJECT_NTP_TIME, 0, null); 15119b9fb5cc08eaa0b66a80eba2f03168531544f65aMike Lockwood } 15129b9fb5cc08eaa0b66a80eba2f03168531544f65aMike Lockwood 15139b9fb5cc08eaa0b66a80eba2f03168531544f65aMike Lockwood /** 15141e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja * Called from native code to request reference location info 15151e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja */ 15161e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja 15171e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja private void requestRefLocation(int flags) { 15181e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja TelephonyManager phone = (TelephonyManager) 15191e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja mContext.getSystemService(Context.TELEPHONY_SERVICE); 15201e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja if (phone.getPhoneType() == TelephonyManager.PHONE_TYPE_GSM) { 15211e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja GsmCellLocation gsm_cell = (GsmCellLocation) phone.getCellLocation(); 1522edc0f3876ce6e14f0ce35ad950c55031694fd4f8Mike Lockwood if ((gsm_cell != null) && (phone.getPhoneType() == TelephonyManager.PHONE_TYPE_GSM) && 1523edc0f3876ce6e14f0ce35ad950c55031694fd4f8Mike Lockwood (phone.getNetworkOperator() != null) && 1524edc0f3876ce6e14f0ce35ad950c55031694fd4f8Mike Lockwood (phone.getNetworkOperator().length() > 3)) { 15251e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja int type; 15261e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja int mcc = Integer.parseInt(phone.getNetworkOperator().substring(0,3)); 15271e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja int mnc = Integer.parseInt(phone.getNetworkOperator().substring(3)); 1528edc0f3876ce6e14f0ce35ad950c55031694fd4f8Mike Lockwood int networkType = phone.getNetworkType(); 1529edc0f3876ce6e14f0ce35ad950c55031694fd4f8Mike Lockwood if (networkType == TelephonyManager.NETWORK_TYPE_UMTS 1530edc0f3876ce6e14f0ce35ad950c55031694fd4f8Mike Lockwood || networkType == TelephonyManager.NETWORK_TYPE_HSDPA 1531edc0f3876ce6e14f0ce35ad950c55031694fd4f8Mike Lockwood || networkType == TelephonyManager.NETWORK_TYPE_HSUPA 1532edc0f3876ce6e14f0ce35ad950c55031694fd4f8Mike Lockwood || networkType == TelephonyManager.NETWORK_TYPE_HSPA) { 15331e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja type = AGPS_REF_LOCATION_TYPE_UMTS_CELLID; 1534edc0f3876ce6e14f0ce35ad950c55031694fd4f8Mike Lockwood } else { 15351e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja type = AGPS_REF_LOCATION_TYPE_GSM_CELLID; 1536edc0f3876ce6e14f0ce35ad950c55031694fd4f8Mike Lockwood } 15371e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja native_agps_set_ref_location_cellid(type, mcc, mnc, 15381e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja gsm_cell.getLac(), gsm_cell.getCid()); 1539edc0f3876ce6e14f0ce35ad950c55031694fd4f8Mike Lockwood } else { 15401e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja Log.e(TAG,"Error getting cell location info."); 1541edc0f3876ce6e14f0ce35ad950c55031694fd4f8Mike Lockwood } 15421e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja } 1543edc0f3876ce6e14f0ce35ad950c55031694fd4f8Mike Lockwood else { 15441e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja Log.e(TAG,"CDMA not supported."); 1545edc0f3876ce6e14f0ce35ad950c55031694fd4f8Mike Lockwood } 15461e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja } 154722d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie 154898e48691f738680fe59e7383a41458e7337daccdMike Lockwood private void sendMessage(int message, int arg, Object obj) { 154998e48691f738680fe59e7383a41458e7337daccdMike Lockwood // hold a wake lock while messages are pending 155098e48691f738680fe59e7383a41458e7337daccdMike Lockwood synchronized (mWakeLock) { 155198e48691f738680fe59e7383a41458e7337daccdMike Lockwood mPendingMessageBits |= (1 << message); 155298e48691f738680fe59e7383a41458e7337daccdMike Lockwood mWakeLock.acquire(); 155398e48691f738680fe59e7383a41458e7337daccdMike Lockwood mHandler.removeMessages(message); 155498e48691f738680fe59e7383a41458e7337daccdMike Lockwood Message m = Message.obtain(mHandler, message); 155598e48691f738680fe59e7383a41458e7337daccdMike Lockwood m.arg1 = arg; 155698e48691f738680fe59e7383a41458e7337daccdMike Lockwood m.obj = obj; 155798e48691f738680fe59e7383a41458e7337daccdMike Lockwood mHandler.sendMessage(m); 155898e48691f738680fe59e7383a41458e7337daccdMike Lockwood } 155998e48691f738680fe59e7383a41458e7337daccdMike Lockwood } 156098e48691f738680fe59e7383a41458e7337daccdMike Lockwood 156162a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood private final class ProviderHandler extends Handler { 156262a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood @Override 15634a7b65e0d544ef1feff8e1e5789f469f89ebb85cMike Lockwood public void handleMessage(Message msg) { 156498e48691f738680fe59e7383a41458e7337daccdMike Lockwood int message = msg.what; 156598e48691f738680fe59e7383a41458e7337daccdMike Lockwood switch (message) { 156662a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood case ENABLE: 156762a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood if (msg.arg1 == 1) { 156862a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood handleEnable(); 156962a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood } else { 157062a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood handleDisable(); 15719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 157262a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood break; 157362a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood case ENABLE_TRACKING: 157462a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood handleEnableLocationTracking(msg.arg1 == 1); 157562a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood break; 157603ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood case REQUEST_SINGLE_SHOT: 157703ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood handleRequestSingleShot(); 157803ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood break; 157962a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood case UPDATE_NETWORK_STATE: 158062a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood handleUpdateNetworkState(msg.arg1, (NetworkInfo)msg.obj); 158162a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood break; 158262a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood case INJECT_NTP_TIME: 158362a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood handleInjectNtpTime(); 158462a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood break; 158562a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood case DOWNLOAD_XTRA_DATA: 15861a1cd3a878b6389c097e34d114b60cf953edaeaaMike Lockwood if (mSupportsXtra) { 158762a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood handleDownloadXtraData(); 15889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 158962a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood break; 159062a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood case UPDATE_LOCATION: 159162a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood handleUpdateLocation((Location)msg.obj); 159262a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood break; 159362a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood case ADD_LISTENER: 159462a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood handleAddListener(msg.arg1); 159562a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood break; 159662a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood case REMOVE_LISTENER: 159762a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood handleRemoveListener(msg.arg1); 159862a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood break; 15999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 160098e48691f738680fe59e7383a41458e7337daccdMike Lockwood // release wake lock if no messages are pending 160198e48691f738680fe59e7383a41458e7337daccdMike Lockwood synchronized (mWakeLock) { 160298e48691f738680fe59e7383a41458e7337daccdMike Lockwood mPendingMessageBits &= ~(1 << message); 160398e48691f738680fe59e7383a41458e7337daccdMike Lockwood if (message == ADD_LISTENER || message == REMOVE_LISTENER) { 160498e48691f738680fe59e7383a41458e7337daccdMike Lockwood mPendingListenerMessages--; 160598e48691f738680fe59e7383a41458e7337daccdMike Lockwood } 160698e48691f738680fe59e7383a41458e7337daccdMike Lockwood if (mPendingMessageBits == 0 && mPendingListenerMessages == 0) { 160798e48691f738680fe59e7383a41458e7337daccdMike Lockwood mWakeLock.release(); 160898e48691f738680fe59e7383a41458e7337daccdMike Lockwood } 160998e48691f738680fe59e7383a41458e7337daccdMike Lockwood } 16109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 161162a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood }; 16129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 161389096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood private final class GpsLocationProviderThread extends Thread { 161489096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood 161589096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood public GpsLocationProviderThread() { 161689096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood super("GpsLocationProvider"); 161789096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood } 161889096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood 161989096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood public void run() { 162089096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 162189096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood initialize(); 162289096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood Looper.prepare(); 162389096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood mHandler = new ProviderHandler(); 162489096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood // signal when we are initialized and ready to go 162589096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood mInitializedLatch.countDown(); 162689096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood Looper.loop(); 162789096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood } 16289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1630a5fe6b2efee02ab11c35e80ec50fec62be227273Kevin Tang private String getSelectedApn() { 1631a5fe6b2efee02ab11c35e80ec50fec62be227273Kevin Tang Uri uri = Uri.parse("content://telephony/carriers/preferapn"); 1632a5fe6b2efee02ab11c35e80ec50fec62be227273Kevin Tang String apn = null; 1633a5fe6b2efee02ab11c35e80ec50fec62be227273Kevin Tang 1634a5fe6b2efee02ab11c35e80ec50fec62be227273Kevin Tang Cursor cursor = mContext.getContentResolver().query(uri, new String[] {"apn"}, 1635a5fe6b2efee02ab11c35e80ec50fec62be227273Kevin Tang null, null, Carriers.DEFAULT_SORT_ORDER); 1636a5fe6b2efee02ab11c35e80ec50fec62be227273Kevin Tang 1637a5fe6b2efee02ab11c35e80ec50fec62be227273Kevin Tang if (null != cursor) { 1638a5fe6b2efee02ab11c35e80ec50fec62be227273Kevin Tang try { 1639a5fe6b2efee02ab11c35e80ec50fec62be227273Kevin Tang if (cursor.moveToFirst()) { 1640a5fe6b2efee02ab11c35e80ec50fec62be227273Kevin Tang apn = cursor.getString(0); 1641a5fe6b2efee02ab11c35e80ec50fec62be227273Kevin Tang } 1642a5fe6b2efee02ab11c35e80ec50fec62be227273Kevin Tang } finally { 1643a5fe6b2efee02ab11c35e80ec50fec62be227273Kevin Tang cursor.close(); 1644a5fe6b2efee02ab11c35e80ec50fec62be227273Kevin Tang } 1645a5fe6b2efee02ab11c35e80ec50fec62be227273Kevin Tang } 1646a5fe6b2efee02ab11c35e80ec50fec62be227273Kevin Tang return apn; 1647a5fe6b2efee02ab11c35e80ec50fec62be227273Kevin Tang } 1648a5fe6b2efee02ab11c35e80ec50fec62be227273Kevin Tang 16499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // for GPS SV statistics 16509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int MAX_SVS = 32; 16519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int EPHEMERIS_MASK = 0; 16529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int ALMANAC_MASK = 1; 16539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int USED_FOR_FIX_MASK = 2; 16549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // preallocated arrays, to avoid memory allocation in reportStatus() 16569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mSvs[] = new int[MAX_SVS]; 16579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private float mSnrs[] = new float[MAX_SVS]; 16589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private float mSvElevations[] = new float[MAX_SVS]; 16599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private float mSvAzimuths[] = new float[MAX_SVS]; 16609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mSvMasks[] = new int[3]; 16619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mSvCount; 1662b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood // preallocated to avoid memory allocation in reportNmea() 1663b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood private byte[] mNmeaBuffer = new byte[120]; 16649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static { class_init_native(); } 16669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static native void class_init_native(); 16679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static native boolean native_is_supported(); 16689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native boolean native_init(); 16709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native void native_cleanup(); 167104598b67a58fad93e5060bb77756ba4863013aedMike Lockwood private native boolean native_set_position_mode(int mode, int recurrence, int min_interval, 167204598b67a58fad93e5060bb77756ba4863013aedMike Lockwood int preferred_accuracy, int preferred_time); 167304598b67a58fad93e5060bb77756ba4863013aedMike Lockwood private native boolean native_start(); 16749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native boolean native_stop(); 16759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native void native_delete_aiding_data(int flags); 16769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // returns number of SVs 16779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // mask[0] is ephemeris mask and mask[1] is almanac mask 16789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native int native_read_sv_status(int[] svs, float[] snrs, 16799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float[] elevations, float[] azimuths, int[] masks); 1680f602d362ba4bb3adbf1eb4e38a794fb14274293aMike Lockwood private native int native_read_nmea(byte[] buffer, int bufferSize); 1681d26ce0d903f5141a346d67b2b94437ef3e2880aaMike Lockwood private native void native_inject_location(double latitude, double longitude, float accuracy); 1682d26ce0d903f5141a346d67b2b94437ef3e2880aaMike Lockwood 16833c8fbdf5dd19fad0b3006557716ee1026d7d5899Fred Fettinger // XTRA Support 16849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native void native_inject_time(long time, long timeReference, int uncertainty); 16859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native boolean native_supports_xtra(); 16869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native void native_inject_xtra_data(byte[] data, int length); 1687105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project 16883c8fbdf5dd19fad0b3006557716ee1026d7d5899Fred Fettinger // DEBUG Support 16893c8fbdf5dd19fad0b3006557716ee1026d7d5899Fred Fettinger private native String native_get_internal_state(); 16903c8fbdf5dd19fad0b3006557716ee1026d7d5899Fred Fettinger 16913c8fbdf5dd19fad0b3006557716ee1026d7d5899Fred Fettinger // AGPS Support 1692e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood private native void native_agps_data_conn_open(String apn); 1693e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood private native void native_agps_data_conn_closed(); 1694e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood private native void native_agps_data_conn_failed(); 16951e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja private native void native_agps_ni_message(byte [] msg, int length); 1696a9e546169b3c2c9c5f248d2f3abe3b934f48695dMike Lockwood private native void native_set_agps_server(int type, String hostname, int port); 169722d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie 169822d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie // Network-initiated (NI) Support 169922d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie private native void native_send_ni_response(int notificationId, int userResponse); 17001e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja 17011e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja // AGPS ril suport 17021e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja private native void native_agps_set_ref_location_cellid(int type, int mcc, int mnc, 17031e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja int lac, int cid); 17041e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja private native void native_agps_set_id(int type, String setid); 170550130bbc884a7ad7db39dbc4f54e76e8be87761fMike Lockwood 170650130bbc884a7ad7db39dbc4f54e76e8be87761fMike Lockwood private native void native_update_network_state(boolean connected, int type, 1707a5fe6b2efee02ab11c35e80ec50fec62be227273Kevin Tang boolean roaming, boolean available, String extraInfo, String defaultAPN); 17089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1709