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 1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // true if we are enabled 19689096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood private volatile boolean mEnabled; 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // true if we have network connectivity 1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mNetworkAvailable; 2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 20162a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood // flags to trigger NTP or XTRA data download when network becomes available 20262a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood // initialized to true so we do NTP and XTRA when the network comes up after booting 20362a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood private boolean mInjectNtpTimePending = true; 2045982bf66d4fdea38105d91ff0f9d38660ac87581Mike Lockwood private boolean mDownloadXtraDataPending = true; 20562a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood 2069b9fb5cc08eaa0b66a80eba2f03168531544f65aMike Lockwood // set to true if the GPS engine does not do on-demand NTP time requests 2079b9fb5cc08eaa0b66a80eba2f03168531544f65aMike Lockwood private boolean mPeriodicTimeInjection; 2089b9fb5cc08eaa0b66a80eba2f03168531544f65aMike Lockwood 2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // true if GPS is navigating 2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mNavigating; 211cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood 212cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood // true if GPS engine is on 213cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood private boolean mEngineOn; 2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 21504598b67a58fad93e5060bb77756ba4863013aedMike Lockwood // requested frequency of fixes, in milliseconds 21604598b67a58fad93e5060bb77756ba4863013aedMike Lockwood private int mFixInterval = 1000; 2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // true if we started navigation 2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mStarted; 2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 22103ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood // true if single shot request is in progress 22203ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood private boolean mSingleShot; 22303ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood 22404598b67a58fad93e5060bb77756ba4863013aedMike Lockwood // capabilities of the GPS engine 22504598b67a58fad93e5060bb77756ba4863013aedMike Lockwood private int mEngineCapabilities; 22604598b67a58fad93e5060bb77756ba4863013aedMike Lockwood 2271a1cd3a878b6389c097e34d114b60cf953edaeaaMike Lockwood // true if XTRA is supported 2281a1cd3a878b6389c097e34d114b60cf953edaeaaMike Lockwood private boolean mSupportsXtra; 2291a1cd3a878b6389c097e34d114b60cf953edaeaaMike Lockwood 2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // for calculating time to first fix 2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private long mFixRequestTime = 0; 2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // time to first fix for most recent session 2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mTTFF = 0; 2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // time we received our last fix 2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private long mLastFixTime; 2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 23704598b67a58fad93e5060bb77756ba4863013aedMike Lockwood private int mPositionMode; 23804598b67a58fad93e5060bb77756ba4863013aedMike Lockwood 2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // properties loaded from PROPERTIES_FILE 2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Properties mProperties; 241734d6031a662a275ec68627bd1258159041d44deMike Lockwood private String mSuplServerHost; 242734d6031a662a275ec68627bd1258159041d44deMike Lockwood private int mSuplServerPort; 243734d6031a662a275ec68627bd1258159041d44deMike Lockwood private String mC2KServerHost; 244734d6031a662a275ec68627bd1258159041d44deMike Lockwood private int mC2KServerPort; 2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 24615e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood private final Context mContext; 247104344e507610be42fb70c7deda3c422c543bfcbJeff Sharkey private final NtpTrustedTime mNtpTime; 24815e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood private final ILocationManager mLocationManager; 2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Location mLocation = new Location(LocationManager.GPS_PROVIDER); 2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Bundle mLocationExtras = new Bundle(); 2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private ArrayList<Listener> mListeners = new ArrayList<Listener>(); 25262a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood 25389096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood // GpsLocationProvider's handler thread 25489096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood private final Thread mThread; 25589096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood // Handler for processing events in mThread. 25662a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood private Handler mHandler; 25789096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood // Used to signal when our main thread has initialized everything 25889096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood private final CountDownLatch mInitializedLatch = new CountDownLatch(1); 259105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project 260e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood private String mAGpsApn; 261e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood private int mAGpsDataConnectionState; 2628efd74dbedb65f69734318d9d6be70767f30b57aStephen Li private int mAGpsDataConnectionIpAddr; 2632f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood private final ConnectivityManager mConnMgr; 26422d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie private final GpsNetInitiatedHandler mNIHandler; 2652f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood 2660528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood // Wakelocks 2670528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood private final static String WAKELOCK_KEY = "GpsLocationProvider"; 2680528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood private final PowerManager.WakeLock mWakeLock; 26998e48691f738680fe59e7383a41458e7337daccdMike Lockwood // bitfield of pending messages to our Handler 27098e48691f738680fe59e7383a41458e7337daccdMike Lockwood // used only for messages that cannot have multiple instances queued 27198e48691f738680fe59e7383a41458e7337daccdMike Lockwood private int mPendingMessageBits; 27298e48691f738680fe59e7383a41458e7337daccdMike Lockwood // separate counter for ADD_LISTENER and REMOVE_LISTENER messages, 27398e48691f738680fe59e7383a41458e7337daccdMike Lockwood // which might have multiple instances queued 27498e48691f738680fe59e7383a41458e7337daccdMike Lockwood private int mPendingListenerMessages; 2750528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood 27629c84340a14e70419449628ab193d11b7a609e9aMike Lockwood // Alarms 27729c84340a14e70419449628ab193d11b7a609e9aMike Lockwood private final static String ALARM_WAKEUP = "com.android.internal.location.ALARM_WAKEUP"; 2780632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood private final static String ALARM_TIMEOUT = "com.android.internal.location.ALARM_TIMEOUT"; 27929c84340a14e70419449628ab193d11b7a609e9aMike Lockwood private final AlarmManager mAlarmManager; 28029c84340a14e70419449628ab193d11b7a609e9aMike Lockwood private final PendingIntent mWakeupIntent; 2810632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood private final PendingIntent mTimeoutIntent; 28229c84340a14e70419449628ab193d11b7a609e9aMike Lockwood 2832f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood private final IBatteryStats mBatteryStats; 2842f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood private final SparseIntArray mClientUids = new SparseIntArray(); 285105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project 2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // how often to request NTP time, in milliseconds 2874c126068527c9adba45aa227d40e245ee8e7c9a4Mike Lockwood // current setting 24 hours 2884c126068527c9adba45aa227d40e245ee8e7c9a4Mike Lockwood private static final long NTP_INTERVAL = 24*60*60*1000; 2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // how long to wait if we have a network error in NTP or XTRA downloading 2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // current setting - 5 minutes 291f1218be2d8f68f3f445f3bc90e0eca01946a0ddfMike Lockwood private static final long RETRY_INTERVAL = 5*60*1000; 292f1218be2d8f68f3f445f3bc90e0eca01946a0ddfMike Lockwood 29315e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood private final IGpsStatusProvider mGpsStatusProvider = new IGpsStatusProvider.Stub() { 29415e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood public void addGpsStatusListener(IGpsStatusListener listener) throws RemoteException { 29515e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood if (listener == null) { 29615e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood throw new NullPointerException("listener is null in addGpsStatusListener"); 29715e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 29815e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood 29915e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood synchronized(mListeners) { 30015e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood IBinder binder = listener.asBinder(); 30115e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood int size = mListeners.size(); 30215e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood for (int i = 0; i < size; i++) { 30315e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood Listener test = mListeners.get(i); 30415e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood if (binder.equals(test.mListener.asBinder())) { 30515e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood // listener already added 30615e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood return; 30715e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 30815e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 30915e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood 31015e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood Listener l = new Listener(listener); 31115e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood binder.linkToDeath(l, 0); 31215e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood mListeners.add(l); 31315e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 31415e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 31515e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood 31615e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood public void removeGpsStatusListener(IGpsStatusListener listener) { 31715e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood if (listener == null) { 31815e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood throw new NullPointerException("listener is null in addGpsStatusListener"); 31915e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 32015e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood 32115e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood synchronized(mListeners) { 32215e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood IBinder binder = listener.asBinder(); 32315e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood Listener l = null; 32415e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood int size = mListeners.size(); 32515e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood for (int i = 0; i < size && l == null; i++) { 32615e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood Listener test = mListeners.get(i); 32715e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood if (binder.equals(test.mListener.asBinder())) { 32815e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood l = test; 32915e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 33015e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 33115e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood 33215e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood if (l != null) { 33315e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood mListeners.remove(l); 33415e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood binder.unlinkToDeath(l, 0); 33515e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 33615e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 33715e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 33815e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood }; 33915e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood 34015e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood public IGpsStatusProvider getGpsStatusProvider() { 34115e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood return mGpsStatusProvider; 34215e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 34315e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood 34429c84340a14e70419449628ab193d11b7a609e9aMike Lockwood private final BroadcastReceiver mBroadcastReciever = new BroadcastReceiver() { 345105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project @Override public void onReceive(Context context, Intent intent) { 346105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project String action = intent.getAction(); 347105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project 34829c84340a14e70419449628ab193d11b7a609e9aMike Lockwood if (action.equals(ALARM_WAKEUP)) { 34929c84340a14e70419449628ab193d11b7a609e9aMike Lockwood if (DEBUG) Log.d(TAG, "ALARM_WAKEUP"); 35003ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood startNavigating(false); 3510632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood } else if (action.equals(ALARM_TIMEOUT)) { 3520632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood if (DEBUG) Log.d(TAG, "ALARM_TIMEOUT"); 3530632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood hibernate(); 3541e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja } else if (action.equals(Intents.DATA_SMS_RECEIVED_ACTION)) { 3551e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja checkSmsSuplInit(intent); 3561e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja } else if (action.equals(Intents.WAP_PUSH_RECEIVED_ACTION)) { 3571e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja checkWapSuplInit(intent); 3581e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja } 359105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project } 36029c84340a14e70419449628ab193d11b7a609e9aMike Lockwood }; 361105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project 3621e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja private void checkSmsSuplInit(Intent intent) { 3631e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja SmsMessage[] messages = Intents.getMessagesFromIntent(intent); 3641e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja for (int i=0; i <messages.length; i++) { 3651e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja byte[] supl_init = messages[i].getUserData(); 3661e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja native_agps_ni_message(supl_init,supl_init.length); 3671e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja } 3681e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja } 3691e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja 3701e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja private void checkWapSuplInit(Intent intent) { 3711e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja byte[] supl_init = (byte[]) intent.getExtra("data"); 3721e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja native_agps_ni_message(supl_init,supl_init.length); 3731e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja } 3741e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja 3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static boolean isSupported() { 3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return native_is_supported(); 3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3794e50b78bda9cd58be61581d2886c88ff6348a1c1Mike Lockwood public GpsLocationProvider(Context context, ILocationManager locationManager) { 3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContext = context; 381104344e507610be42fb70c7deda3c422c543bfcbJeff Sharkey mNtpTime = NtpTrustedTime.getInstance(context); 38215e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood mLocationManager = locationManager; 38379e642e8ed75033eacc461633a8f4cd5157d25dfMike Lockwood mNIHandler = new GpsNetInitiatedHandler(context); 38463598a0619776b421f27cd12fb29eb83dc327997Mike Lockwood 38563598a0619776b421f27cd12fb29eb83dc327997Mike Lockwood mLocation.setExtras(mLocationExtras); 3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3870528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood // Create a wake lock 3880528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood PowerManager powerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE); 3890528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, WAKELOCK_KEY); 39098e48691f738680fe59e7383a41458e7337daccdMike Lockwood mWakeLock.setReferenceCounted(false); 3910528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood 39229c84340a14e70419449628ab193d11b7a609e9aMike Lockwood mAlarmManager = (AlarmManager)mContext.getSystemService(Context.ALARM_SERVICE); 39329c84340a14e70419449628ab193d11b7a609e9aMike Lockwood mWakeupIntent = PendingIntent.getBroadcast(mContext, 0, new Intent(ALARM_WAKEUP), 0); 3940632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood mTimeoutIntent = PendingIntent.getBroadcast(mContext, 0, new Intent(ALARM_TIMEOUT), 0); 39529c84340a14e70419449628ab193d11b7a609e9aMike Lockwood 3961e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja IntentFilter intentFilter = new IntentFilter(); 3971e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja intentFilter.addAction(Intents.DATA_SMS_RECEIVED_ACTION); 3981e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja intentFilter.addDataScheme("sms"); 3991e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja intentFilter.addDataAuthority("localhost","7275"); 4001e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja context.registerReceiver(mBroadcastReciever, intentFilter); 4011e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja 4021e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja intentFilter = new IntentFilter(); 4031e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja intentFilter.addAction(Intents.WAP_PUSH_RECEIVED_ACTION); 4041e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja try { 4051e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja intentFilter.addDataType("application/vnd.omaloc-supl-init"); 4061e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja } catch (IntentFilter.MalformedMimeTypeException e) { 4071e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja Log.w(TAG, "Malformed SUPL init mime type"); 4081e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja } 4091e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja context.registerReceiver(mBroadcastReciever, intentFilter); 4101e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja 41158bda987665af759c379cd494ff4873ac61acf29Mike Lockwood mConnMgr = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE); 41258bda987665af759c379cd494ff4873ac61acf29Mike Lockwood 4132f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood // Battery statistics service to be notified when GPS turns on or off 4142f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood mBatteryStats = IBatteryStats.Stub.asInterface(ServiceManager.getService("batteryinfo")); 4152f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood 4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mProperties = new Properties(); 4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project File file = new File(PROPERTIES_FILE); 4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project FileInputStream stream = new FileInputStream(file); 4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mProperties.load(stream); 4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project stream.close(); 422e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood 423734d6031a662a275ec68627bd1258159041d44deMike Lockwood mSuplServerHost = mProperties.getProperty("SUPL_HOST"); 424e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood String portString = mProperties.getProperty("SUPL_PORT"); 425734d6031a662a275ec68627bd1258159041d44deMike Lockwood if (mSuplServerHost != null && portString != null) { 426105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project try { 427734d6031a662a275ec68627bd1258159041d44deMike Lockwood mSuplServerPort = Integer.parseInt(portString); 428105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project } catch (NumberFormatException e) { 429e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood Log.e(TAG, "unable to parse SUPL_PORT: " + portString); 430e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood } 431e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood } 432e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood 433734d6031a662a275ec68627bd1258159041d44deMike Lockwood mC2KServerHost = mProperties.getProperty("C2K_HOST"); 434e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood portString = mProperties.getProperty("C2K_PORT"); 435734d6031a662a275ec68627bd1258159041d44deMike Lockwood if (mC2KServerHost != null && portString != null) { 436e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood try { 437734d6031a662a275ec68627bd1258159041d44deMike Lockwood mC2KServerPort = Integer.parseInt(portString); 438e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood } catch (NumberFormatException e) { 439e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood Log.e(TAG, "unable to parse C2K_PORT: " + portString); 440105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project } 441105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project } 4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (IOException e) { 4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.w(TAG, "Could not open GPS configuration file " + PROPERTIES_FILE); 4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 44562a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood 44689096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood // wait until we are fully initialized before returning 44789096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood mThread = new GpsLocationProviderThread(); 44889096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood mThread.start(); 44989096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood while (true) { 45089096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood try { 45189096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood mInitializedLatch.await(); 45289096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood break; 45389096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood } catch (InterruptedException e) { 45489096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood Thread.currentThread().interrupt(); 45589096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood } 45689096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood } 45762a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood } 45862a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood 45962a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood private void initialize() { 46062a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood // register our receiver on our thread rather than the main thread 46162a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood IntentFilter intentFilter = new IntentFilter(); 46262a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood intentFilter.addAction(ALARM_WAKEUP); 46362a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood intentFilter.addAction(ALARM_TIMEOUT); 46462a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood mContext.registerReceiver(mBroadcastReciever, intentFilter); 4659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 468d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood * Returns the name of this provider. 469d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood */ 470d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood public String getName() { 471d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood return LocationManager.GPS_PROVIDER; 472d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood } 473d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood 474d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood /** 4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns true if the provider requires access to a 4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * data network (e.g., the Internet), false otherwise. 4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean requiresNetwork() { 479a9e546169b3c2c9c5f248d2f3abe3b934f48695dMike Lockwood return true; 4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 48203d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood public void updateNetworkState(int state, NetworkInfo info) { 48398e48691f738680fe59e7383a41458e7337daccdMike Lockwood sendMessage(UPDATE_NETWORK_STATE, state, info); 48462a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood } 48562a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood 48662a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood private void handleUpdateNetworkState(int state, NetworkInfo info) { 4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNetworkAvailable = (state == LocationProvider.AVAILABLE); 4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 489f5d95cbc1a6974afeb4d3155bdaa8dae55722a39Joe Onorato if (DEBUG) { 49003d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood Log.d(TAG, "updateNetworkState " + (mNetworkAvailable ? "available" : "unavailable") 49103d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood + " info: " + info); 4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 49303d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood 49450130bbc884a7ad7db39dbc4f54e76e8be87761fMike Lockwood if (info != null) { 495a5fe6b2efee02ab11c35e80ec50fec62be227273Kevin Tang boolean dataEnabled = Settings.Secure.getInt(mContext.getContentResolver(), 496a5fe6b2efee02ab11c35e80ec50fec62be227273Kevin Tang Settings.Secure.MOBILE_DATA, 1) == 1; 497a5fe6b2efee02ab11c35e80ec50fec62be227273Kevin Tang boolean networkAvailable = info.isAvailable() && dataEnabled; 498a5fe6b2efee02ab11c35e80ec50fec62be227273Kevin Tang String defaultApn = getSelectedApn(); 499a5fe6b2efee02ab11c35e80ec50fec62be227273Kevin Tang if (defaultApn == null) { 500a5fe6b2efee02ab11c35e80ec50fec62be227273Kevin Tang defaultApn = "dummy-apn"; 501a5fe6b2efee02ab11c35e80ec50fec62be227273Kevin Tang } 502a5fe6b2efee02ab11c35e80ec50fec62be227273Kevin Tang 50350130bbc884a7ad7db39dbc4f54e76e8be87761fMike Lockwood native_update_network_state(info.isConnected(), info.getType(), 504a5fe6b2efee02ab11c35e80ec50fec62be227273Kevin Tang info.isRoaming(), networkAvailable, 505a5fe6b2efee02ab11c35e80ec50fec62be227273Kevin Tang info.getExtraInfo(), defaultApn); 50650130bbc884a7ad7db39dbc4f54e76e8be87761fMike Lockwood } 50750130bbc884a7ad7db39dbc4f54e76e8be87761fMike Lockwood 50803d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood if (info != null && info.getType() == ConnectivityManager.TYPE_MOBILE_SUPL 50903d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood && mAGpsDataConnectionState == AGPS_DATA_CONNECTION_OPENING) { 51003d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood String apnName = info.getExtraInfo(); 51183b69713f2dbeee7ff5e07836673a9a477be236fStephen Li if (mNetworkAvailable) { 51283b69713f2dbeee7ff5e07836673a9a477be236fStephen Li if (apnName == null) { 51383b69713f2dbeee7ff5e07836673a9a477be236fStephen Li /* Assign a dummy value in the case of C2K as otherwise we will have a runtime 51483b69713f2dbeee7ff5e07836673a9a477be236fStephen Li exception in the following call to native_agps_data_conn_open*/ 51583b69713f2dbeee7ff5e07836673a9a477be236fStephen Li apnName = "dummy-apn"; 51683b69713f2dbeee7ff5e07836673a9a477be236fStephen Li } 51703d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood mAGpsApn = apnName; 5188efd74dbedb65f69734318d9d6be70767f30b57aStephen Li if (DEBUG) Log.d(TAG, "mAGpsDataConnectionIpAddr " + mAGpsDataConnectionIpAddr); 5198efd74dbedb65f69734318d9d6be70767f30b57aStephen Li if (mAGpsDataConnectionIpAddr != 0xffffffff) { 5208efd74dbedb65f69734318d9d6be70767f30b57aStephen Li boolean route_result; 5218efd74dbedb65f69734318d9d6be70767f30b57aStephen Li if (DEBUG) Log.d(TAG, "call requestRouteToHost"); 5228efd74dbedb65f69734318d9d6be70767f30b57aStephen Li route_result = mConnMgr.requestRouteToHost(ConnectivityManager.TYPE_MOBILE_SUPL, 5238efd74dbedb65f69734318d9d6be70767f30b57aStephen Li mAGpsDataConnectionIpAddr); 5248efd74dbedb65f69734318d9d6be70767f30b57aStephen Li if (route_result == false) Log.d(TAG, "call requestRouteToHost failed"); 5258efd74dbedb65f69734318d9d6be70767f30b57aStephen Li } 52603d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood if (DEBUG) Log.d(TAG, "call native_agps_data_conn_open"); 52703d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood native_agps_data_conn_open(apnName); 52803d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood mAGpsDataConnectionState = AGPS_DATA_CONNECTION_OPEN; 52903d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood } else { 53003d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood if (DEBUG) Log.d(TAG, "call native_agps_data_conn_failed"); 53103d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood mAGpsApn = null; 53203d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood mAGpsDataConnectionState = AGPS_DATA_CONNECTION_CLOSED; 53303d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood native_agps_data_conn_failed(); 53403d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood } 53503d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood } 53603d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood 53762a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood if (mNetworkAvailable) { 53862a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood if (mInjectNtpTimePending) { 53998e48691f738680fe59e7383a41458e7337daccdMike Lockwood sendMessage(INJECT_NTP_TIME, 0, null); 54062a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood } 54162a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood if (mDownloadXtraDataPending) { 54298e48691f738680fe59e7383a41458e7337daccdMike Lockwood sendMessage(DOWNLOAD_XTRA_DATA, 0, null); 54362a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood } 54462a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood } 54562a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood } 54662a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood 54762a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood private void handleInjectNtpTime() { 54862a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood if (!mNetworkAvailable) { 54962a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood // try again when network is up 55062a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood mInjectNtpTimePending = true; 55162a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood return; 55262a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood } 55362a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood mInjectNtpTimePending = false; 55462a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood 55562a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood long delay; 55662a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood 5572ffe0ad39127950074dc74bc5d15a284975da5aeMike Lockwood // GPS requires fresh NTP time 5582ffe0ad39127950074dc74bc5d15a284975da5aeMike Lockwood if (mNtpTime.forceRefresh()) { 559104344e507610be42fb70c7deda3c422c543bfcbJeff Sharkey long time = mNtpTime.getCachedNtpTime(); 560104344e507610be42fb70c7deda3c422c543bfcbJeff Sharkey long timeReference = mNtpTime.getCachedNtpTimeReference(); 561104344e507610be42fb70c7deda3c422c543bfcbJeff Sharkey long certainty = mNtpTime.getCacheCertainty(); 56262a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood long now = System.currentTimeMillis(); 56362a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood 56462a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood Log.d(TAG, "NTP server returned: " 56562a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood + time + " (" + new Date(time) 56662a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood + ") reference: " + timeReference 56762a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood + " certainty: " + certainty 5681879d284bf3dd704dbc8c95aad262ebbe3c3c0a4Mike Lockwood + " system time offset: " + (time - now)); 56962a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood 570104344e507610be42fb70c7deda3c422c543bfcbJeff Sharkey native_inject_time(time, timeReference, (int) certainty); 57162a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood delay = NTP_INTERVAL; 57262a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood } else { 57362a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood if (DEBUG) Log.d(TAG, "requestTime failed"); 57462a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood delay = RETRY_INTERVAL; 57562a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood } 57662a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood 5779b9fb5cc08eaa0b66a80eba2f03168531544f65aMike Lockwood if (mPeriodicTimeInjection) { 5789b9fb5cc08eaa0b66a80eba2f03168531544f65aMike Lockwood // send delayed message for next NTP injection 5799b9fb5cc08eaa0b66a80eba2f03168531544f65aMike Lockwood // since this is delayed and not urgent we do not hold a wake lock here 5809b9fb5cc08eaa0b66a80eba2f03168531544f65aMike Lockwood mHandler.removeMessages(INJECT_NTP_TIME); 5819b9fb5cc08eaa0b66a80eba2f03168531544f65aMike Lockwood mHandler.sendMessageDelayed(Message.obtain(mHandler, INJECT_NTP_TIME), delay); 5829b9fb5cc08eaa0b66a80eba2f03168531544f65aMike Lockwood } 58362a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood } 58462a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood 58562a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood private void handleDownloadXtraData() { 5865723dfe8c87d0887b8926f43637ed300466890d2Mike Lockwood if (!mNetworkAvailable) { 58762a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood // try again when network is up 58862a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood mDownloadXtraDataPending = true; 58962a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood return; 59062a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood } 59162a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood mDownloadXtraDataPending = false; 59262a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood 59362a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood 59462a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood GpsXtraDownloader xtraDownloader = new GpsXtraDownloader(mContext, mProperties); 59562a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood byte[] data = xtraDownloader.downloadXtraData(); 59662a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood if (data != null) { 59762a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood if (DEBUG) { 59862a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood Log.d(TAG, "calling native_inject_xtra_data"); 59962a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood } 60062a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood native_inject_xtra_data(data, data.length); 60162a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood } else { 60262a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood // try again later 60398e48691f738680fe59e7383a41458e7337daccdMike Lockwood // since this is delayed and not urgent we do not hold a wake lock here 60462a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood mHandler.removeMessages(DOWNLOAD_XTRA_DATA); 60562a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood mHandler.sendMessageDelayed(Message.obtain(mHandler, DOWNLOAD_XTRA_DATA), RETRY_INTERVAL); 60662a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood } 6079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 610fd6e5f0dda50e113db4ccc55338b6c4f09da37a4Mike Lockwood * This is called to inform us when another location provider returns a location. 611fd6e5f0dda50e113db4ccc55338b6c4f09da37a4Mike Lockwood * Someday we might use this for network location injection to aid the GPS 612fd6e5f0dda50e113db4ccc55338b6c4f09da37a4Mike Lockwood */ 613fd6e5f0dda50e113db4ccc55338b6c4f09da37a4Mike Lockwood public void updateLocation(Location location) { 61498e48691f738680fe59e7383a41458e7337daccdMike Lockwood sendMessage(UPDATE_LOCATION, 0, location); 61562a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood } 61662a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood 61762a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood private void handleUpdateLocation(Location location) { 618d26ce0d903f5141a346d67b2b94437ef3e2880aaMike Lockwood if (location.hasAccuracy()) { 619d26ce0d903f5141a346d67b2b94437ef3e2880aaMike Lockwood native_inject_location(location.getLatitude(), location.getLongitude(), 620d26ce0d903f5141a346d67b2b94437ef3e2880aaMike Lockwood location.getAccuracy()); 621d26ce0d903f5141a346d67b2b94437ef3e2880aaMike Lockwood } 622fd6e5f0dda50e113db4ccc55338b6c4f09da37a4Mike Lockwood } 623fd6e5f0dda50e113db4ccc55338b6c4f09da37a4Mike Lockwood 624fd6e5f0dda50e113db4ccc55338b6c4f09da37a4Mike Lockwood /** 6259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns true if the provider requires access to a 6269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * satellite-based positioning system (e.g., GPS), false 6279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * otherwise. 6289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean requiresSatellite() { 6309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 6319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns true if the provider requires access to an appropriate 6359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * cellular network (e.g., to make use of cell tower IDs), false 6369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * otherwise. 6379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean requiresCell() { 6399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 6409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns true if the use of this provider may result in a 6449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * monetary charge to the user, false if use is free. It is up to 6459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * each provider to give accurate information. 6469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean hasMonetaryCost() { 6489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 6499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns true if the provider is able to provide altitude 6539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * information, false otherwise. A provider that reports altitude 6549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * under most circumstances but may occassionally not report it 6559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * should return true. 6569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean supportsAltitude() { 6589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 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 speed 6639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * information, false otherwise. A provider that reports speed 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 supportsSpeed() { 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 bearing 6739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * information, false otherwise. A provider that reports bearing 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 supportsBearing() { 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 the power requirement for this provider. 6839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 6849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the power requirement for this provider, as one of the 6859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * constants Criteria.POWER_REQUIREMENT_*. 6869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getPowerRequirement() { 6889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return Criteria.POWER_HIGH; 6899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 69203ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood * Returns true if this provider meets the given criteria, 69303ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood * false otherwise. 69403ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood */ 69503ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood public boolean meetsCriteria(Criteria criteria) { 69603ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood return (criteria.getPowerRequirement() != Criteria.POWER_LOW); 69703ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood } 69803ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood 69903ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood /** 7009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns the horizontal accuracy of this provider 7019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 7029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the accuracy of location from this provider, as one 7039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * of the constants Criteria.ACCURACY_*. 7049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getAccuracy() { 7069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return Criteria.ACCURACY_FINE; 7079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Enables this provider. When enabled, calls to getStatus() 7114e50b78bda9cd58be61581d2886c88ff6348a1c1Mike Lockwood * must be handled. Hardware may be started up 7129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * when the provider is enabled. 7139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 71462a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood public void enable() { 71562a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood synchronized (mHandler) { 71698e48691f738680fe59e7383a41458e7337daccdMike Lockwood sendMessage(ENABLE, 1, null); 71762a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood } 71862a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood } 71962a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood 72062a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood private void handleEnable() { 72162a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood if (DEBUG) Log.d(TAG, "handleEnable"); 7229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mEnabled) return; 7239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEnabled = native_init(); 7249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mEnabled) { 7261a1cd3a878b6389c097e34d114b60cf953edaeaaMike Lockwood mSupportsXtra = native_supports_xtra(); 727734d6031a662a275ec68627bd1258159041d44deMike Lockwood if (mSuplServerHost != null) { 728734d6031a662a275ec68627bd1258159041d44deMike Lockwood native_set_agps_server(AGPS_TYPE_SUPL, mSuplServerHost, mSuplServerPort); 729734d6031a662a275ec68627bd1258159041d44deMike Lockwood } 730734d6031a662a275ec68627bd1258159041d44deMike Lockwood if (mC2KServerHost != null) { 731734d6031a662a275ec68627bd1258159041d44deMike Lockwood native_set_agps_server(AGPS_TYPE_C2K, mC2KServerHost, mC2KServerPort); 732734d6031a662a275ec68627bd1258159041d44deMike Lockwood } 7339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 7349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.w(TAG, "Failed to enable location provider"); 7359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Disables this provider. When disabled, calls to getStatus() 7404e50b78bda9cd58be61581d2886c88ff6348a1c1Mike Lockwood * need not be handled. Hardware may be shut 7419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * down while the provider is disabled. 7429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 74362a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood public void disable() { 74462a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood synchronized (mHandler) { 74598e48691f738680fe59e7383a41458e7337daccdMike Lockwood sendMessage(ENABLE, 0, null); 74662a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood } 74762a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood } 74862a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood 74962a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood private void handleDisable() { 75089096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood if (DEBUG) Log.d(TAG, "handleDisable"); 7519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mEnabled) return; 7529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEnabled = false; 7549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project stopNavigating(); 7559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 756cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood // do this before releasing wakelock 757cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood native_cleanup(); 7589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 760d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood public boolean isEnabled() { 761d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood return mEnabled; 762d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood } 763d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood 7649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getStatus(Bundle extras) { 7659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras != null) { 7669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project extras.putInt("satellites", mSvCount); 7679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mStatus; 7699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void updateStatus(int status, int svCount) { 7729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (status != mStatus || svCount != mSvCount) { 7739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStatus = status; 7749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSvCount = svCount; 7759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocationExtras.putInt("satellites", svCount); 7769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStatusUpdateTime = SystemClock.elapsedRealtime(); 7779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public long getStatusUpdateTime() { 7819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mStatusUpdateTime; 7829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void enableLocationTracking(boolean enable) { 78503ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood // FIXME - should set a flag here to avoid race conditions with single shot request 78662a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood synchronized (mHandler) { 78798e48691f738680fe59e7383a41458e7337daccdMike Lockwood sendMessage(ENABLE_TRACKING, (enable ? 1 : 0), null); 78862a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood } 78962a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood } 79062a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood 79162a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood private void handleEnableLocationTracking(boolean enable) { 7929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (enable) { 7939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTTFF = 0; 7949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLastFixTime = 0; 79503ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood startNavigating(false); 7969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 79704598b67a58fad93e5060bb77756ba4863013aedMike Lockwood if (!hasCapability(GPS_CAPABILITY_SCHEDULING)) { 79804598b67a58fad93e5060bb77756ba4863013aedMike Lockwood mAlarmManager.cancel(mWakeupIntent); 79904598b67a58fad93e5060bb77756ba4863013aedMike Lockwood mAlarmManager.cancel(mTimeoutIntent); 80004598b67a58fad93e5060bb77756ba4863013aedMike Lockwood } 8019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project stopNavigating(); 8029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 80503ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood public boolean requestSingleShotFix() { 80603ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood if (mStarted) { 80703ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood // cannot do single shot if already navigating 80803ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood return false; 80903ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood } 81003ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood synchronized (mHandler) { 81103ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood mHandler.removeMessages(REQUEST_SINGLE_SHOT); 81203ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood Message m = Message.obtain(mHandler, REQUEST_SINGLE_SHOT); 81303ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood mHandler.sendMessage(m); 81403ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood } 81503ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood return true; 81603ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood } 81703ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood 81803ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood private void handleRequestSingleShot() { 81903ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood mTTFF = 0; 82003ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood mLastFixTime = 0; 82103ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood startNavigating(true); 82203ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood } 82303ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood 8247e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn public void setMinTime(long minTime, WorkSource ws) { 825f5d95cbc1a6974afeb4d3155bdaa8dae55722a39Joe Onorato if (DEBUG) Log.d(TAG, "setMinTime " + minTime); 8269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (minTime >= 0) { 82804598b67a58fad93e5060bb77756ba4863013aedMike Lockwood mFixInterval = (int)minTime; 82904598b67a58fad93e5060bb77756ba4863013aedMike Lockwood 83004598b67a58fad93e5060bb77756ba4863013aedMike Lockwood if (mStarted && hasCapability(GPS_CAPABILITY_SCHEDULING)) { 83104598b67a58fad93e5060bb77756ba4863013aedMike Lockwood if (!native_set_position_mode(mPositionMode, GPS_POSITION_RECURRENCE_PERIODIC, 83204598b67a58fad93e5060bb77756ba4863013aedMike Lockwood mFixInterval, 0, 0)) { 83304598b67a58fad93e5060bb77756ba4863013aedMike Lockwood Log.e(TAG, "set_position_mode failed in setMinTime()"); 83404598b67a58fad93e5060bb77756ba4863013aedMike Lockwood } 8359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8393c8fbdf5dd19fad0b3006557716ee1026d7d5899Fred Fettinger public String getInternalState() { 8403c8fbdf5dd19fad0b3006557716ee1026d7d5899Fred Fettinger return native_get_internal_state(); 8413c8fbdf5dd19fad0b3006557716ee1026d7d5899Fred Fettinger } 8423c8fbdf5dd19fad0b3006557716ee1026d7d5899Fred Fettinger 8439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final class Listener implements IBinder.DeathRecipient { 8449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final IGpsStatusListener mListener; 8459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int mSensors = 0; 8479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Listener(IGpsStatusListener listener) { 8499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mListener = listener; 8509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void binderDied() { 853f5d95cbc1a6974afeb4d3155bdaa8dae55722a39Joe Onorato if (DEBUG) Log.d(TAG, "GPS status listener died"); 8549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized(mListeners) { 8569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mListeners.remove(this); 8579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 858fff2fda0199dedbf1079454dca98a81190dce765Suchi Amalapurapu if (mListener != null) { 859fff2fda0199dedbf1079454dca98a81190dce765Suchi Amalapurapu mListener.asBinder().unlinkToDeath(this, 0); 860fff2fda0199dedbf1079454dca98a81190dce765Suchi Amalapurapu } 8619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8642f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood public void addListener(int uid) { 86598e48691f738680fe59e7383a41458e7337daccdMike Lockwood synchronized (mWakeLock) { 86698e48691f738680fe59e7383a41458e7337daccdMike Lockwood mPendingListenerMessages++; 8677e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn mWakeLock.acquire(); 86898e48691f738680fe59e7383a41458e7337daccdMike Lockwood Message m = Message.obtain(mHandler, ADD_LISTENER); 86998e48691f738680fe59e7383a41458e7337daccdMike Lockwood m.arg1 = uid; 87098e48691f738680fe59e7383a41458e7337daccdMike Lockwood mHandler.sendMessage(m); 87198e48691f738680fe59e7383a41458e7337daccdMike Lockwood } 87262a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood } 87362a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood 87462a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood private void handleAddListener(int uid) { 8752e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn synchronized(mListeners) { 8762e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn if (mClientUids.indexOfKey(uid) >= 0) { 8772e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn // Shouldn't be here -- already have this uid. 8782e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn Log.w(TAG, "Duplicate add listener for uid " + uid); 8792e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn return; 8802e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn } 8812e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn mClientUids.put(uid, 0); 8822e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn if (mNavigating) { 8832e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn try { 8842e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn mBatteryStats.noteStartGps(uid); 8852e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn } catch (RemoteException e) { 8862e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn Log.w(TAG, "RemoteException in addListener"); 8872e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn } 8882f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } 8892f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } 8902f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } 8912f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood 8922f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood public void removeListener(int uid) { 89398e48691f738680fe59e7383a41458e7337daccdMike Lockwood synchronized (mWakeLock) { 89498e48691f738680fe59e7383a41458e7337daccdMike Lockwood mPendingListenerMessages++; 89598e48691f738680fe59e7383a41458e7337daccdMike Lockwood mWakeLock.acquire(); 89698e48691f738680fe59e7383a41458e7337daccdMike Lockwood Message m = Message.obtain(mHandler, REMOVE_LISTENER); 89798e48691f738680fe59e7383a41458e7337daccdMike Lockwood m.arg1 = uid; 89898e48691f738680fe59e7383a41458e7337daccdMike Lockwood mHandler.sendMessage(m); 89998e48691f738680fe59e7383a41458e7337daccdMike Lockwood } 90062a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood } 90162a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood 90262a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood private void handleRemoveListener(int uid) { 9032e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn synchronized(mListeners) { 9042e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn if (mClientUids.indexOfKey(uid) < 0) { 9052e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn // Shouldn't be here -- don't have this uid. 9062e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn Log.w(TAG, "Unneeded remove listener for uid " + uid); 9072e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn return; 9082e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn } 9092e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn mClientUids.delete(uid); 9102e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn if (mNavigating) { 9112e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn try { 9122e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn mBatteryStats.noteStopGps(uid); 9132e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn } catch (RemoteException e) { 9142e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn Log.w(TAG, "RemoteException in removeListener"); 9152e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn } 9162f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } 9172f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } 9182f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } 9192f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood 9209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean sendExtraCommand(String command, Bundle extras) { 9219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 92263aa5a6f98b1016863e4f6edd87eb471b28dc28fMike Lockwood long identity = Binder.clearCallingIdentity(); 92363aa5a6f98b1016863e4f6edd87eb471b28dc28fMike Lockwood boolean result = false; 92463aa5a6f98b1016863e4f6edd87eb471b28dc28fMike Lockwood 9259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ("delete_aiding_data".equals(command)) { 92663aa5a6f98b1016863e4f6edd87eb471b28dc28fMike Lockwood result = deleteAidingData(extras); 92763aa5a6f98b1016863e4f6edd87eb471b28dc28fMike Lockwood } else if ("force_time_injection".equals(command)) { 92898e48691f738680fe59e7383a41458e7337daccdMike Lockwood sendMessage(INJECT_NTP_TIME, 0, null); 92963aa5a6f98b1016863e4f6edd87eb471b28dc28fMike Lockwood result = true; 93063aa5a6f98b1016863e4f6edd87eb471b28dc28fMike Lockwood } else if ("force_xtra_injection".equals(command)) { 9311a1cd3a878b6389c097e34d114b60cf953edaeaaMike Lockwood if (mSupportsXtra) { 93293bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood xtraDownloadRequest(); 93363aa5a6f98b1016863e4f6edd87eb471b28dc28fMike Lockwood result = true; 93493bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood } 93563aa5a6f98b1016863e4f6edd87eb471b28dc28fMike Lockwood } else { 93663aa5a6f98b1016863e4f6edd87eb471b28dc28fMike Lockwood Log.w(TAG, "sendExtraCommand: unknown command " + command); 93793bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood } 9389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 93963aa5a6f98b1016863e4f6edd87eb471b28dc28fMike Lockwood Binder.restoreCallingIdentity(identity); 94063aa5a6f98b1016863e4f6edd87eb471b28dc28fMike Lockwood return result; 9419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean deleteAidingData(Bundle extras) { 9449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int flags; 9459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras == null) { 9479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project flags = GPS_DELETE_ALL; 9489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 9499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project flags = 0; 9509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("ephemeris")) flags |= GPS_DELETE_EPHEMERIS; 9519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("almanac")) flags |= GPS_DELETE_ALMANAC; 9529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("position")) flags |= GPS_DELETE_POSITION; 9539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("time")) flags |= GPS_DELETE_TIME; 9549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("iono")) flags |= GPS_DELETE_IONO; 9559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("utc")) flags |= GPS_DELETE_UTC; 9569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("health")) flags |= GPS_DELETE_HEALTH; 9579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("svdir")) flags |= GPS_DELETE_SVDIR; 9589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("svsteer")) flags |= GPS_DELETE_SVSTEER; 9599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("sadata")) flags |= GPS_DELETE_SADATA; 9609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("rti")) flags |= GPS_DELETE_RTI; 9619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("celldb-info")) flags |= GPS_DELETE_CELLDB_INFO; 9629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("all")) flags |= GPS_DELETE_ALL; 9639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (flags != 0) { 9669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project native_delete_aiding_data(flags); 9679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 9689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 9719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 97303ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood private void startNavigating(boolean singleShot) { 9749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mStarted) { 97529c84340a14e70419449628ab193d11b7a609e9aMike Lockwood if (DEBUG) Log.d(TAG, "startNavigating"); 9769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStarted = true; 97703ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood mSingleShot = singleShot; 97803ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood mPositionMode = GPS_POSITION_MODE_STANDALONE; 97903ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood 98003ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood if (Settings.Secure.getInt(mContext.getContentResolver(), 981660bbfcc54d48d5d32e64da683c76b9c372c19b1Mike Lockwood Settings.Secure.ASSISTED_GPS_ENABLED, 1) != 0) { 98203ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood if (singleShot && hasCapability(GPS_CAPABILITY_MSA)) { 98303ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood mPositionMode = GPS_POSITION_MODE_MS_ASSISTED; 9848dc16c27e23dae5bdf65fd2a2ced97c2f645a633Mike Lockwood } else if (hasCapability(GPS_CAPABILITY_MSB)) { 98503ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood mPositionMode = GPS_POSITION_MODE_MS_BASED; 98603ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood } 987bcab8df83e6e769a7cbcc742e72b47d665998793Mike Lockwood } 988bcab8df83e6e769a7cbcc742e72b47d665998793Mike Lockwood 98904598b67a58fad93e5060bb77756ba4863013aedMike Lockwood int interval = (hasCapability(GPS_CAPABILITY_SCHEDULING) ? mFixInterval : 1000); 99004598b67a58fad93e5060bb77756ba4863013aedMike Lockwood if (!native_set_position_mode(mPositionMode, GPS_POSITION_RECURRENCE_PERIODIC, 99104598b67a58fad93e5060bb77756ba4863013aedMike Lockwood interval, 0, 0)) { 99204598b67a58fad93e5060bb77756ba4863013aedMike Lockwood mStarted = false; 99304598b67a58fad93e5060bb77756ba4863013aedMike Lockwood Log.e(TAG, "set_position_mode failed in startNavigating()"); 99404598b67a58fad93e5060bb77756ba4863013aedMike Lockwood return; 99504598b67a58fad93e5060bb77756ba4863013aedMike Lockwood } 99604598b67a58fad93e5060bb77756ba4863013aedMike Lockwood if (!native_start()) { 9979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStarted = false; 9989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.e(TAG, "native_start failed in startNavigating()"); 9990632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood return; 10009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // reset SV count to zero 100315e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood updateStatus(LocationProvider.TEMPORARILY_UNAVAILABLE, 0); 100429c84340a14e70419449628ab193d11b7a609e9aMike Lockwood mFixRequestTime = System.currentTimeMillis(); 100504598b67a58fad93e5060bb77756ba4863013aedMike Lockwood if (!hasCapability(GPS_CAPABILITY_SCHEDULING)) { 100604598b67a58fad93e5060bb77756ba4863013aedMike Lockwood // set timer to give up if we do not receive a fix within NO_FIX_TIMEOUT 100704598b67a58fad93e5060bb77756ba4863013aedMike Lockwood // and our fix interval is not short 100804598b67a58fad93e5060bb77756ba4863013aedMike Lockwood if (mFixInterval >= NO_FIX_TIMEOUT) { 100904598b67a58fad93e5060bb77756ba4863013aedMike Lockwood mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, 101004598b67a58fad93e5060bb77756ba4863013aedMike Lockwood SystemClock.elapsedRealtime() + NO_FIX_TIMEOUT, mTimeoutIntent); 101104598b67a58fad93e5060bb77756ba4863013aedMike Lockwood } 10120632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood } 10139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 101662a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood private void stopNavigating() { 101729c84340a14e70419449628ab193d11b7a609e9aMike Lockwood if (DEBUG) Log.d(TAG, "stopNavigating"); 10189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mStarted) { 10199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStarted = false; 102003ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood mSingleShot = false; 10219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project native_stop(); 10229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTTFF = 0; 10239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLastFixTime = 0; 10249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocationFlags = LOCATION_INVALID; 10259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // reset SV count to zero 102715e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood updateStatus(LocationProvider.TEMPORARILY_UNAVAILABLE, 0); 10289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10310632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood private void hibernate() { 10320632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood // stop GPS until our next fix interval arrives 10330632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood stopNavigating(); 10340632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood mAlarmManager.cancel(mTimeoutIntent); 10350632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood mAlarmManager.cancel(mWakeupIntent); 10360632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood long now = SystemClock.elapsedRealtime(); 10370632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, 103804598b67a58fad93e5060bb77756ba4863013aedMike Lockwood SystemClock.elapsedRealtime() + mFixInterval, mWakeupIntent); 103904598b67a58fad93e5060bb77756ba4863013aedMike Lockwood } 104004598b67a58fad93e5060bb77756ba4863013aedMike Lockwood 104104598b67a58fad93e5060bb77756ba4863013aedMike Lockwood private boolean hasCapability(int capability) { 104204598b67a58fad93e5060bb77756ba4863013aedMike Lockwood return ((mEngineCapabilities & capability) != 0); 10430632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood } 10440632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood 10459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 10469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * called from native code to update our position. 10479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 10489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void reportLocation(int flags, double latitude, double longitude, double altitude, 10499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float speed, float bearing, float accuracy, long timestamp) { 105029c84340a14e70419449628ab193d11b7a609e9aMike Lockwood if (VERBOSE) Log.v(TAG, "reportLocation lat: " + latitude + " long: " + longitude + 10519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project " timestamp: " + timestamp); 10529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mLocation) { 10549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocationFlags = flags; 10559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((flags & LOCATION_HAS_LAT_LONG) == LOCATION_HAS_LAT_LONG) { 10569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocation.setLatitude(latitude); 10579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocation.setLongitude(longitude); 10589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocation.setTime(timestamp); 10599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((flags & LOCATION_HAS_ALTITUDE) == LOCATION_HAS_ALTITUDE) { 10619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocation.setAltitude(altitude); 10629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 10639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocation.removeAltitude(); 10649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((flags & LOCATION_HAS_SPEED) == LOCATION_HAS_SPEED) { 10669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocation.setSpeed(speed); 10679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 10689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocation.removeSpeed(); 10699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((flags & LOCATION_HAS_BEARING) == LOCATION_HAS_BEARING) { 10719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocation.setBearing(bearing); 10729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 10739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocation.removeBearing(); 10749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((flags & LOCATION_HAS_ACCURACY) == LOCATION_HAS_ACCURACY) { 10769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocation.setAccuracy(accuracy); 10779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 10789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocation.removeAccuracy(); 10799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 108115e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood try { 1082a4903f254b4711c8fc0ac5f7e3d605f4dce34f35Mike Lockwood mLocationManager.reportLocation(mLocation, false); 108315e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } catch (RemoteException e) { 108415e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood Log.e(TAG, "RemoteException calling reportLocation"); 108515e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 10869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1088fa94ff074d3200fae2f5d14a6d0f454e2ad23cfaHakan Gustavsson mLastFixTime = System.currentTimeMillis(); 1089fa94ff074d3200fae2f5d14a6d0f454e2ad23cfaHakan Gustavsson // report time to first fix 1090fa94ff074d3200fae2f5d14a6d0f454e2ad23cfaHakan Gustavsson if (mTTFF == 0 && (flags & LOCATION_HAS_LAT_LONG) == LOCATION_HAS_LAT_LONG) { 1091fa94ff074d3200fae2f5d14a6d0f454e2ad23cfaHakan Gustavsson mTTFF = (int)(mLastFixTime - mFixRequestTime); 1092f4dffd8a45386b5a5f0e6de4f30facc9eaac4001The Android Open Source Project if (DEBUG) Log.d(TAG, "TTFF: " + mTTFF); 1093fa94ff074d3200fae2f5d14a6d0f454e2ad23cfaHakan Gustavsson 1094fa94ff074d3200fae2f5d14a6d0f454e2ad23cfaHakan Gustavsson // notify status listeners 1095fa94ff074d3200fae2f5d14a6d0f454e2ad23cfaHakan Gustavsson synchronized(mListeners) { 1096fa94ff074d3200fae2f5d14a6d0f454e2ad23cfaHakan Gustavsson int size = mListeners.size(); 1097fa94ff074d3200fae2f5d14a6d0f454e2ad23cfaHakan Gustavsson for (int i = 0; i < size; i++) { 1098fa94ff074d3200fae2f5d14a6d0f454e2ad23cfaHakan Gustavsson Listener listener = mListeners.get(i); 1099fa94ff074d3200fae2f5d14a6d0f454e2ad23cfaHakan Gustavsson try { 1100f4dffd8a45386b5a5f0e6de4f30facc9eaac4001The Android Open Source Project listener.mListener.onFirstFix(mTTFF); 1101fa94ff074d3200fae2f5d14a6d0f454e2ad23cfaHakan Gustavsson } catch (RemoteException e) { 1102fa94ff074d3200fae2f5d14a6d0f454e2ad23cfaHakan Gustavsson Log.w(TAG, "RemoteException in stopNavigating"); 1103fa94ff074d3200fae2f5d14a6d0f454e2ad23cfaHakan Gustavsson mListeners.remove(listener); 1104fa94ff074d3200fae2f5d14a6d0f454e2ad23cfaHakan Gustavsson // adjust for size of list changing 1105fa94ff074d3200fae2f5d14a6d0f454e2ad23cfaHakan Gustavsson size--; 1106fa94ff074d3200fae2f5d14a6d0f454e2ad23cfaHakan Gustavsson } 1107fa94ff074d3200fae2f5d14a6d0f454e2ad23cfaHakan Gustavsson } 1108fa94ff074d3200fae2f5d14a6d0f454e2ad23cfaHakan Gustavsson } 1109fa94ff074d3200fae2f5d14a6d0f454e2ad23cfaHakan Gustavsson } 1110fa94ff074d3200fae2f5d14a6d0f454e2ad23cfaHakan Gustavsson 111103ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood if (mSingleShot) { 111203ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood stopNavigating(); 111303ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood } 111415e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood if (mStarted && mStatus != LocationProvider.AVAILABLE) { 1115d53ba017ee2381383b4bb4d92e6e0e661431660fMike Lockwood // we want to time out if we do not receive a fix 1116b7be5447a002b4a1cf7d4030cc8a0a330cd7517cMike Lockwood // within the time out and we are requesting infrequent fixes 111704598b67a58fad93e5060bb77756ba4863013aedMike Lockwood if (!hasCapability(GPS_CAPABILITY_SCHEDULING) && mFixInterval < NO_FIX_TIMEOUT) { 1118b7be5447a002b4a1cf7d4030cc8a0a330cd7517cMike Lockwood mAlarmManager.cancel(mTimeoutIntent); 1119b7be5447a002b4a1cf7d4030cc8a0a330cd7517cMike Lockwood } 1120b7be5447a002b4a1cf7d4030cc8a0a330cd7517cMike Lockwood 11219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // send an intent to notify that the GPS is receiving fixes. 112200b74270c9f136a8727c5f6cda0997a3a905f385Mike Lockwood Intent intent = new Intent(LocationManager.GPS_FIX_CHANGE_ACTION); 112300b74270c9f136a8727c5f6cda0997a3a905f385Mike Lockwood intent.putExtra(LocationManager.EXTRA_GPS_ENABLED, true); 11249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContext.sendBroadcast(intent); 112515e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood updateStatus(LocationProvider.AVAILABLE, mSvCount); 11269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 112729c84340a14e70419449628ab193d11b7a609e9aMike Lockwood 112803ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood if (!hasCapability(GPS_CAPABILITY_SCHEDULING) && mStarted && mFixInterval > 1000) { 1129d53ba017ee2381383b4bb4d92e6e0e661431660fMike Lockwood if (DEBUG) Log.d(TAG, "got fix, hibernating"); 11300632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood hibernate(); 113129c84340a14e70419449628ab193d11b7a609e9aMike Lockwood } 11329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 11359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * called from native code to update our status 11369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 11379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void reportStatus(int status) { 1138b8d9033d9928209e68518c4b12fea74187ddb382Mike Lockwood if (DEBUG) Log.v(TAG, "reportStatus status: " + status); 11399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11402e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn synchronized(mListeners) { 11412e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn boolean wasNavigating = mNavigating; 1142dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood 1143cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood switch (status) { 1144cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood case GPS_STATUS_SESSION_BEGIN: 1145cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood mNavigating = true; 1146271f9f172b241607b1ed39a7709c3ed47ee5dee7Mike Lockwood mEngineOn = true; 1147cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood break; 1148cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood case GPS_STATUS_SESSION_END: 1149cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood mNavigating = false; 1150cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood break; 1151cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood case GPS_STATUS_ENGINE_ON: 1152cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood mEngineOn = true; 1153cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood break; 1154cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood case GPS_STATUS_ENGINE_OFF: 1155cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood mEngineOn = false; 1156271f9f172b241607b1ed39a7709c3ed47ee5dee7Mike Lockwood mNavigating = false; 1157cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood break; 1158cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood } 1159cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood 1160dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood if (wasNavigating != mNavigating) { 1161dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood int size = mListeners.size(); 1162dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood for (int i = 0; i < size; i++) { 1163dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood Listener listener = mListeners.get(i); 1164dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood try { 1165dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood if (mNavigating) { 1166dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood listener.mListener.onGpsStarted(); 1167dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood } else { 1168dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood listener.mListener.onGpsStopped(); 1169dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood } 1170dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood } catch (RemoteException e) { 1171dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood Log.w(TAG, "RemoteException in reportStatus"); 1172dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood mListeners.remove(listener); 1173dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood // adjust for size of list changing 1174dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood size--; 1175dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood } 1176dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood } 1177dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood 11782e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn try { 1179dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood // update battery stats 1180dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood for (int i=mClientUids.size() - 1; i >= 0; i--) { 1181dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood int uid = mClientUids.keyAt(i); 1182dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood if (mNavigating) { 1183dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood mBatteryStats.noteStartGps(uid); 1184dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood } else { 1185dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood mBatteryStats.noteStopGps(uid); 1186dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood } 11879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11882e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn } catch (RemoteException e) { 11892e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn Log.w(TAG, "RemoteException in reportStatus"); 11909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1192dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood // send an intent to notify that the GPS has been enabled or disabled. 119300b74270c9f136a8727c5f6cda0997a3a905f385Mike Lockwood Intent intent = new Intent(LocationManager.GPS_ENABLED_CHANGE_ACTION); 119400b74270c9f136a8727c5f6cda0997a3a905f385Mike Lockwood intent.putExtra(LocationManager.EXTRA_GPS_ENABLED, mNavigating); 1195dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood mContext.sendBroadcast(intent); 11962f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } 11979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 12019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * called from native code to update SV info 12029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 12039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void reportSvStatus() { 12049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int svCount = native_read_sv_status(mSvs, mSnrs, mSvElevations, mSvAzimuths, mSvMasks); 12069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized(mListeners) { 12089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int size = mListeners.size(); 12099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < size; i++) { 12109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Listener listener = mListeners.get(i); 12119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 12129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project listener.mListener.onSvStatusChanged(svCount, mSvs, mSnrs, 12139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSvElevations, mSvAzimuths, mSvMasks[EPHEMERIS_MASK], 12149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSvMasks[ALMANAC_MASK], mSvMasks[USED_FOR_FIX_MASK]); 12159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 12169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.w(TAG, "RemoteException in reportSvInfo"); 12179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mListeners.remove(listener); 12189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // adjust for size of list changing 12199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size--; 12209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 122429c84340a14e70419449628ab193d11b7a609e9aMike Lockwood if (VERBOSE) { 122529c84340a14e70419449628ab193d11b7a609e9aMike Lockwood Log.v(TAG, "SV count: " + svCount + 12269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project " ephemerisMask: " + Integer.toHexString(mSvMasks[EPHEMERIS_MASK]) + 12279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project " almanacMask: " + Integer.toHexString(mSvMasks[ALMANAC_MASK])); 12289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < svCount; i++) { 122929c84340a14e70419449628ab193d11b7a609e9aMike Lockwood Log.v(TAG, "sv: " + mSvs[i] + 12309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project " snr: " + (float)mSnrs[i]/10 + 12319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project " elev: " + mSvElevations[i] + 12329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project " azimuth: " + mSvAzimuths[i] + 12339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ((mSvMasks[EPHEMERIS_MASK] & (1 << (mSvs[i] - 1))) == 0 ? " " : " E") + 12349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ((mSvMasks[ALMANAC_MASK] & (1 << (mSvs[i] - 1))) == 0 ? " " : " A") + 12359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ((mSvMasks[USED_FOR_FIX_MASK] & (1 << (mSvs[i] - 1))) == 0 ? "" : "U")); 12369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12390881f4f9339febee85c9ab4cba69970ac5cbde55Kevin.KY Tsai // return number of sets used in fix instead of total 12400881f4f9339febee85c9ab4cba69970ac5cbde55Kevin.KY Tsai updateStatus(mStatus, Integer.bitCount(mSvMasks[USED_FOR_FIX_MASK])); 12419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 124215e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood if (mNavigating && mStatus == LocationProvider.AVAILABLE && mLastFixTime > 0 && 124304598b67a58fad93e5060bb77756ba4863013aedMike Lockwood System.currentTimeMillis() - mLastFixTime > RECENT_FIX_TIMEOUT) { 12449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // send an intent to notify that the GPS is no longer receiving fixes. 124500b74270c9f136a8727c5f6cda0997a3a905f385Mike Lockwood Intent intent = new Intent(LocationManager.GPS_FIX_CHANGE_ACTION); 124600b74270c9f136a8727c5f6cda0997a3a905f385Mike Lockwood intent.putExtra(LocationManager.EXTRA_GPS_ENABLED, false); 12479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContext.sendBroadcast(intent); 124815e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood updateStatus(LocationProvider.TEMPORARILY_UNAVAILABLE, mSvCount); 12499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 125158bda987665af759c379cd494ff4873ac61acf29Mike Lockwood 125258bda987665af759c379cd494ff4873ac61acf29Mike Lockwood /** 1253e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood * called from native code to update AGPS status 125458bda987665af759c379cd494ff4873ac61acf29Mike Lockwood */ 12558efd74dbedb65f69734318d9d6be70767f30b57aStephen Li private void reportAGpsStatus(int type, int status, int ipaddr) { 125658bda987665af759c379cd494ff4873ac61acf29Mike Lockwood switch (status) { 1257e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood case GPS_REQUEST_AGPS_DATA_CONN: 1258b6e5fa895c03eeefaa810eaceb498254096c093dMike Lockwood if (DEBUG) Log.d(TAG, "GPS_REQUEST_AGPS_DATA_CONN"); 12592acfd34ccbd39258422333c9c66c586297c97683Mike Lockwood // Set mAGpsDataConnectionState before calling startUsingNetworkFeature 12602acfd34ccbd39258422333c9c66c586297c97683Mike Lockwood // to avoid a race condition with handleUpdateNetworkState() 12612acfd34ccbd39258422333c9c66c586297c97683Mike Lockwood mAGpsDataConnectionState = AGPS_DATA_CONNECTION_OPENING; 12622acfd34ccbd39258422333c9c66c586297c97683Mike Lockwood int result = mConnMgr.startUsingNetworkFeature( 126358bda987665af759c379cd494ff4873ac61acf29Mike Lockwood ConnectivityManager.TYPE_MOBILE, Phone.FEATURE_ENABLE_SUPL); 12648efd74dbedb65f69734318d9d6be70767f30b57aStephen Li mAGpsDataConnectionIpAddr = ipaddr; 126558bda987665af759c379cd494ff4873ac61acf29Mike Lockwood if (result == Phone.APN_ALREADY_ACTIVE) { 12662d4d1bf14b531de9d4238b1e41b53c77f8976405Mike Lockwood if (DEBUG) Log.d(TAG, "Phone.APN_ALREADY_ACTIVE"); 1267b362a9ab91bb4c05ef1d5c4e7019499257c7f849Mike Lockwood if (mAGpsApn != null) { 12688efd74dbedb65f69734318d9d6be70767f30b57aStephen Li Log.d(TAG, "mAGpsDataConnectionIpAddr " + mAGpsDataConnectionIpAddr); 12698efd74dbedb65f69734318d9d6be70767f30b57aStephen Li if (mAGpsDataConnectionIpAddr != 0xffffffff) { 12708efd74dbedb65f69734318d9d6be70767f30b57aStephen Li boolean route_result; 12718efd74dbedb65f69734318d9d6be70767f30b57aStephen Li if (DEBUG) Log.d(TAG, "call requestRouteToHost"); 12728efd74dbedb65f69734318d9d6be70767f30b57aStephen Li route_result = mConnMgr.requestRouteToHost( 12738efd74dbedb65f69734318d9d6be70767f30b57aStephen Li ConnectivityManager.TYPE_MOBILE_SUPL, 12748efd74dbedb65f69734318d9d6be70767f30b57aStephen Li mAGpsDataConnectionIpAddr); 12758efd74dbedb65f69734318d9d6be70767f30b57aStephen Li if (route_result == false) Log.d(TAG, "call requestRouteToHost failed"); 12768efd74dbedb65f69734318d9d6be70767f30b57aStephen Li } 1277b362a9ab91bb4c05ef1d5c4e7019499257c7f849Mike Lockwood native_agps_data_conn_open(mAGpsApn); 1278b362a9ab91bb4c05ef1d5c4e7019499257c7f849Mike Lockwood mAGpsDataConnectionState = AGPS_DATA_CONNECTION_OPEN; 1279b362a9ab91bb4c05ef1d5c4e7019499257c7f849Mike Lockwood } else { 1280b362a9ab91bb4c05ef1d5c4e7019499257c7f849Mike Lockwood Log.e(TAG, "mAGpsApn not set when receiving Phone.APN_ALREADY_ACTIVE"); 12812acfd34ccbd39258422333c9c66c586297c97683Mike Lockwood mAGpsDataConnectionState = AGPS_DATA_CONNECTION_CLOSED; 1282b362a9ab91bb4c05ef1d5c4e7019499257c7f849Mike Lockwood native_agps_data_conn_failed(); 1283b362a9ab91bb4c05ef1d5c4e7019499257c7f849Mike Lockwood } 128458bda987665af759c379cd494ff4873ac61acf29Mike Lockwood } else if (result == Phone.APN_REQUEST_STARTED) { 12854a7b65e0d544ef1feff8e1e5789f469f89ebb85cMike Lockwood if (DEBUG) Log.d(TAG, "Phone.APN_REQUEST_STARTED"); 12862acfd34ccbd39258422333c9c66c586297c97683Mike Lockwood // Nothing to do here 128758bda987665af759c379cd494ff4873ac61acf29Mike Lockwood } else { 1288b8d9033d9928209e68518c4b12fea74187ddb382Mike Lockwood if (DEBUG) Log.d(TAG, "startUsingNetworkFeature failed"); 12892acfd34ccbd39258422333c9c66c586297c97683Mike Lockwood mAGpsDataConnectionState = AGPS_DATA_CONNECTION_CLOSED; 1290e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood native_agps_data_conn_failed(); 129158bda987665af759c379cd494ff4873ac61acf29Mike Lockwood } 129258bda987665af759c379cd494ff4873ac61acf29Mike Lockwood break; 1293e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood case GPS_RELEASE_AGPS_DATA_CONN: 1294b6e5fa895c03eeefaa810eaceb498254096c093dMike Lockwood if (DEBUG) Log.d(TAG, "GPS_RELEASE_AGPS_DATA_CONN"); 1295e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood if (mAGpsDataConnectionState != AGPS_DATA_CONNECTION_CLOSED) { 129658bda987665af759c379cd494ff4873ac61acf29Mike Lockwood mConnMgr.stopUsingNetworkFeature( 129758bda987665af759c379cd494ff4873ac61acf29Mike Lockwood ConnectivityManager.TYPE_MOBILE, Phone.FEATURE_ENABLE_SUPL); 1298e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood native_agps_data_conn_closed(); 1299e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood mAGpsDataConnectionState = AGPS_DATA_CONNECTION_CLOSED; 130058bda987665af759c379cd494ff4873ac61acf29Mike Lockwood } 130158bda987665af759c379cd494ff4873ac61acf29Mike Lockwood break; 1302e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood case GPS_AGPS_DATA_CONNECTED: 1303b6e5fa895c03eeefaa810eaceb498254096c093dMike Lockwood if (DEBUG) Log.d(TAG, "GPS_AGPS_DATA_CONNECTED"); 130458bda987665af759c379cd494ff4873ac61acf29Mike Lockwood break; 1305e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood case GPS_AGPS_DATA_CONN_DONE: 1306b6e5fa895c03eeefaa810eaceb498254096c093dMike Lockwood if (DEBUG) Log.d(TAG, "GPS_AGPS_DATA_CONN_DONE"); 130758bda987665af759c379cd494ff4873ac61acf29Mike Lockwood break; 1308e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood case GPS_AGPS_DATA_CONN_FAILED: 1309b6e5fa895c03eeefaa810eaceb498254096c093dMike Lockwood if (DEBUG) Log.d(TAG, "GPS_AGPS_DATA_CONN_FAILED"); 131058bda987665af759c379cd494ff4873ac61acf29Mike Lockwood break; 131158bda987665af759c379cd494ff4873ac61acf29Mike Lockwood } 131258bda987665af759c379cd494ff4873ac61acf29Mike Lockwood } 131358bda987665af759c379cd494ff4873ac61acf29Mike Lockwood 1314b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood /** 1315b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood * called from native code to report NMEA data received 1316b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood */ 1317f602d362ba4bb3adbf1eb4e38a794fb14274293aMike Lockwood private void reportNmea(long timestamp) { 1318b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood synchronized(mListeners) { 1319b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood int size = mListeners.size(); 1320b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood if (size > 0) { 1321b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood // don't bother creating the String if we have no listeners 1322f602d362ba4bb3adbf1eb4e38a794fb14274293aMike Lockwood int length = native_read_nmea(mNmeaBuffer, mNmeaBuffer.length); 1323b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood String nmea = new String(mNmeaBuffer, 0, length); 1324b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood 1325b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood for (int i = 0; i < size; i++) { 1326b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood Listener listener = mListeners.get(i); 1327b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood try { 1328b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood listener.mListener.onNmeaReceived(timestamp, nmea); 1329b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood } catch (RemoteException e) { 1330b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood Log.w(TAG, "RemoteException in reportNmea"); 1331b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood mListeners.remove(listener); 1332b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood // adjust for size of list changing 1333b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood size--; 1334b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood } 1335b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood } 1336b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood } 1337b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood } 1338b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood } 1339b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood 134062a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood /** 134104598b67a58fad93e5060bb77756ba4863013aedMike Lockwood * called from native code to inform us what the GPS engine capabilities are 134204598b67a58fad93e5060bb77756ba4863013aedMike Lockwood */ 134304598b67a58fad93e5060bb77756ba4863013aedMike Lockwood private void setEngineCapabilities(int capabilities) { 134404598b67a58fad93e5060bb77756ba4863013aedMike Lockwood mEngineCapabilities = capabilities; 13459b9fb5cc08eaa0b66a80eba2f03168531544f65aMike Lockwood 13469b9fb5cc08eaa0b66a80eba2f03168531544f65aMike Lockwood if (!hasCapability(GPS_CAPABILITY_ON_DEMAND_TIME) && !mPeriodicTimeInjection) { 13479b9fb5cc08eaa0b66a80eba2f03168531544f65aMike Lockwood mPeriodicTimeInjection = true; 13489b9fb5cc08eaa0b66a80eba2f03168531544f65aMike Lockwood requestUtcTime(); 13499b9fb5cc08eaa0b66a80eba2f03168531544f65aMike Lockwood } 135004598b67a58fad93e5060bb77756ba4863013aedMike Lockwood } 135104598b67a58fad93e5060bb77756ba4863013aedMike Lockwood 135204598b67a58fad93e5060bb77756ba4863013aedMike Lockwood /** 135362a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood * called from native code to request XTRA data 135462a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood */ 13559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void xtraDownloadRequest() { 1356f5d95cbc1a6974afeb4d3155bdaa8dae55722a39Joe Onorato if (DEBUG) Log.d(TAG, "xtraDownloadRequest"); 135798e48691f738680fe59e7383a41458e7337daccdMike Lockwood sendMessage(DOWNLOAD_XTRA_DATA, 0, null); 13589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 136022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie //============================================================= 136122d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie // NI Client support 13621e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja //============================================================= 136322d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie private final INetInitiatedListener mNetInitiatedListener = new INetInitiatedListener.Stub() { 13641e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja // Sends a response for an NI reqeust to HAL. 13651e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja public boolean sendNiResponse(int notificationId, int userResponse) 13661e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja { 13671e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja // TODO Add Permission check 13681e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja 13691e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja StringBuilder extrasBuf = new StringBuilder(); 13701e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja 13711e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja if (DEBUG) Log.d(TAG, "sendNiResponse, notifId: " + notificationId + 13721e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja ", response: " + userResponse); 13731e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja native_send_ni_response(notificationId, userResponse); 13741e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja return true; 13751e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja } 137622d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie }; 137722d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie 137822d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie public INetInitiatedListener getNetInitiatedListener() { 137922d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie return mNetInitiatedListener; 138022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie } 138122d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie 138222d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie // Called by JNI function to report an NI request. 13831e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja public void reportNiNotification( 13841e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja int notificationId, 13851e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja int niType, 13861e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja int notifyFlags, 13871e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja int timeout, 13881e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja int defaultResponse, 13891e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja String requestorId, 13901e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja String text, 13911e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja int requestorIdEncoding, 13921e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja int textEncoding, 13931e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja String extras // Encoded extra data 139422d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie ) 13951e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja { 13961e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja Log.i(TAG, "reportNiNotification: entered"); 13971e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja Log.i(TAG, "notificationId: " + notificationId + 13981e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja ", niType: " + niType + 13991e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja ", notifyFlags: " + notifyFlags + 14001e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja ", timeout: " + timeout + 14011e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja ", defaultResponse: " + defaultResponse); 14021e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja 14031e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja Log.i(TAG, "requestorId: " + requestorId + 14041e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja ", text: " + text + 14051e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja ", requestorIdEncoding: " + requestorIdEncoding + 14061e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja ", textEncoding: " + textEncoding); 14071e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja 14081e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja GpsNiNotification notification = new GpsNiNotification(); 14091e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja 14101e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja notification.notificationId = notificationId; 14111e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja notification.niType = niType; 14121e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja notification.needNotify = (notifyFlags & GpsNetInitiatedHandler.GPS_NI_NEED_NOTIFY) != 0; 14131e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja notification.needVerify = (notifyFlags & GpsNetInitiatedHandler.GPS_NI_NEED_VERIFY) != 0; 14141e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja notification.privacyOverride = (notifyFlags & GpsNetInitiatedHandler.GPS_NI_PRIVACY_OVERRIDE) != 0; 14151e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja notification.timeout = timeout; 14161e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja notification.defaultResponse = defaultResponse; 14171e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja notification.requestorId = requestorId; 14181e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja notification.text = text; 14191e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja notification.requestorIdEncoding = requestorIdEncoding; 14201e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja notification.textEncoding = textEncoding; 14211e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja 14221e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja // Process extras, assuming the format is 14231e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja // one of more lines of "key = value" 14241e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja Bundle bundle = new Bundle(); 14251e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja 14261e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja if (extras == null) extras = ""; 14271e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja Properties extraProp = new Properties(); 14281e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja 14291e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja try { 1430104344e507610be42fb70c7deda3c422c543bfcbJeff Sharkey extraProp.load(new StringReader(extras)); 14311e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja } 14321e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja catch (IOException e) 14331e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja { 14341e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja Log.e(TAG, "reportNiNotification cannot parse extras data: " + extras); 14351e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja } 14361e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja 14371e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja for (Entry<Object, Object> ent : extraProp.entrySet()) 14381e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja { 14391e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja bundle.putString((String) ent.getKey(), (String) ent.getValue()); 14401e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja } 14411e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja 14421e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja notification.extras = bundle; 14431e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja 14441e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja mNIHandler.handleNiNotification(notification); 14451e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja } 14461e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja 14471e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja /** 14481e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja * Called from native code to request set id info. 14491e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja * We should be careful about receiving null string from the TelephonyManager, 14501e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja * because sending null String to JNI function would cause a crash. 14511e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja */ 14521e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja 14531e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja private void requestSetID(int flags) { 14541e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja TelephonyManager phone = (TelephonyManager) 14551e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja mContext.getSystemService(Context.TELEPHONY_SERVICE); 14561e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja int type = AGPS_SETID_TYPE_NONE; 14571e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja String data = ""; 14581e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja 14591e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja if ((flags & AGPS_RIL_REQUEST_SETID_IMSI) == AGPS_RIL_REQUEST_SETID_IMSI) { 14601e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja String data_temp = phone.getSubscriberId(); 14611e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja if (data_temp == null) { 14621e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja // This means the framework does not have the SIM card ready. 14631e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja } else { 14641e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja // This means the framework has the SIM card. 14651e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja data = data_temp; 14661e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja type = AGPS_SETID_TYPE_IMSI; 14671e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja } 14681e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja } 14691e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja else if ((flags & AGPS_RIL_REQUEST_SETID_MSISDN) == AGPS_RIL_REQUEST_SETID_MSISDN) { 14701e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja String data_temp = phone.getLine1Number(); 14711e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja if (data_temp == null) { 14721e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja // This means the framework does not have the SIM card ready. 14731e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja } else { 14741e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja // This means the framework has the SIM card. 14751e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja data = data_temp; 14761e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja type = AGPS_SETID_TYPE_MSISDN; 14771e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja } 14781e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja } 14791e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja native_agps_set_id(type, data); 14801e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja } 14811e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja 14821e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja /** 14839b9fb5cc08eaa0b66a80eba2f03168531544f65aMike Lockwood * Called from native code to request utc time info 14849b9fb5cc08eaa0b66a80eba2f03168531544f65aMike Lockwood */ 14859b9fb5cc08eaa0b66a80eba2f03168531544f65aMike Lockwood 14869b9fb5cc08eaa0b66a80eba2f03168531544f65aMike Lockwood private void requestUtcTime() { 14879b9fb5cc08eaa0b66a80eba2f03168531544f65aMike Lockwood sendMessage(INJECT_NTP_TIME, 0, null); 14889b9fb5cc08eaa0b66a80eba2f03168531544f65aMike Lockwood } 14899b9fb5cc08eaa0b66a80eba2f03168531544f65aMike Lockwood 14909b9fb5cc08eaa0b66a80eba2f03168531544f65aMike Lockwood /** 14911e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja * Called from native code to request reference location info 14921e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja */ 14931e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja 14941e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja private void requestRefLocation(int flags) { 14951e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja TelephonyManager phone = (TelephonyManager) 14961e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja mContext.getSystemService(Context.TELEPHONY_SERVICE); 14971e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja if (phone.getPhoneType() == TelephonyManager.PHONE_TYPE_GSM) { 14981e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja GsmCellLocation gsm_cell = (GsmCellLocation) phone.getCellLocation(); 1499edc0f3876ce6e14f0ce35ad950c55031694fd4f8Mike Lockwood if ((gsm_cell != null) && (phone.getPhoneType() == TelephonyManager.PHONE_TYPE_GSM) && 1500edc0f3876ce6e14f0ce35ad950c55031694fd4f8Mike Lockwood (phone.getNetworkOperator() != null) && 1501edc0f3876ce6e14f0ce35ad950c55031694fd4f8Mike Lockwood (phone.getNetworkOperator().length() > 3)) { 15021e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja int type; 15031e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja int mcc = Integer.parseInt(phone.getNetworkOperator().substring(0,3)); 15041e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja int mnc = Integer.parseInt(phone.getNetworkOperator().substring(3)); 1505edc0f3876ce6e14f0ce35ad950c55031694fd4f8Mike Lockwood int networkType = phone.getNetworkType(); 1506edc0f3876ce6e14f0ce35ad950c55031694fd4f8Mike Lockwood if (networkType == TelephonyManager.NETWORK_TYPE_UMTS 1507edc0f3876ce6e14f0ce35ad950c55031694fd4f8Mike Lockwood || networkType == TelephonyManager.NETWORK_TYPE_HSDPA 1508edc0f3876ce6e14f0ce35ad950c55031694fd4f8Mike Lockwood || networkType == TelephonyManager.NETWORK_TYPE_HSUPA 1509edc0f3876ce6e14f0ce35ad950c55031694fd4f8Mike Lockwood || networkType == TelephonyManager.NETWORK_TYPE_HSPA) { 15101e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja type = AGPS_REF_LOCATION_TYPE_UMTS_CELLID; 1511edc0f3876ce6e14f0ce35ad950c55031694fd4f8Mike Lockwood } else { 15121e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja type = AGPS_REF_LOCATION_TYPE_GSM_CELLID; 1513edc0f3876ce6e14f0ce35ad950c55031694fd4f8Mike Lockwood } 15141e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja native_agps_set_ref_location_cellid(type, mcc, mnc, 15151e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja gsm_cell.getLac(), gsm_cell.getCid()); 1516edc0f3876ce6e14f0ce35ad950c55031694fd4f8Mike Lockwood } else { 15171e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja Log.e(TAG,"Error getting cell location info."); 1518edc0f3876ce6e14f0ce35ad950c55031694fd4f8Mike Lockwood } 15191e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja } 1520edc0f3876ce6e14f0ce35ad950c55031694fd4f8Mike Lockwood else { 15211e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja Log.e(TAG,"CDMA not supported."); 1522edc0f3876ce6e14f0ce35ad950c55031694fd4f8Mike Lockwood } 15231e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja } 152422d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie 152598e48691f738680fe59e7383a41458e7337daccdMike Lockwood private void sendMessage(int message, int arg, Object obj) { 152698e48691f738680fe59e7383a41458e7337daccdMike Lockwood // hold a wake lock while messages are pending 152798e48691f738680fe59e7383a41458e7337daccdMike Lockwood synchronized (mWakeLock) { 152898e48691f738680fe59e7383a41458e7337daccdMike Lockwood mPendingMessageBits |= (1 << message); 152998e48691f738680fe59e7383a41458e7337daccdMike Lockwood mWakeLock.acquire(); 153098e48691f738680fe59e7383a41458e7337daccdMike Lockwood mHandler.removeMessages(message); 153198e48691f738680fe59e7383a41458e7337daccdMike Lockwood Message m = Message.obtain(mHandler, message); 153298e48691f738680fe59e7383a41458e7337daccdMike Lockwood m.arg1 = arg; 153398e48691f738680fe59e7383a41458e7337daccdMike Lockwood m.obj = obj; 153498e48691f738680fe59e7383a41458e7337daccdMike Lockwood mHandler.sendMessage(m); 153598e48691f738680fe59e7383a41458e7337daccdMike Lockwood } 153698e48691f738680fe59e7383a41458e7337daccdMike Lockwood } 153798e48691f738680fe59e7383a41458e7337daccdMike Lockwood 153862a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood private final class ProviderHandler extends Handler { 153962a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood @Override 15404a7b65e0d544ef1feff8e1e5789f469f89ebb85cMike Lockwood public void handleMessage(Message msg) { 154198e48691f738680fe59e7383a41458e7337daccdMike Lockwood int message = msg.what; 154298e48691f738680fe59e7383a41458e7337daccdMike Lockwood switch (message) { 154362a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood case ENABLE: 154462a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood if (msg.arg1 == 1) { 154562a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood handleEnable(); 154662a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood } else { 154762a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood handleDisable(); 15489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 154962a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood break; 155062a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood case ENABLE_TRACKING: 155162a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood handleEnableLocationTracking(msg.arg1 == 1); 155262a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood break; 155303ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood case REQUEST_SINGLE_SHOT: 155403ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood handleRequestSingleShot(); 155503ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood break; 155662a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood case UPDATE_NETWORK_STATE: 155762a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood handleUpdateNetworkState(msg.arg1, (NetworkInfo)msg.obj); 155862a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood break; 155962a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood case INJECT_NTP_TIME: 156062a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood handleInjectNtpTime(); 156162a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood break; 156262a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood case DOWNLOAD_XTRA_DATA: 15631a1cd3a878b6389c097e34d114b60cf953edaeaaMike Lockwood if (mSupportsXtra) { 156462a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood handleDownloadXtraData(); 15659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 156662a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood break; 156762a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood case UPDATE_LOCATION: 156862a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood handleUpdateLocation((Location)msg.obj); 156962a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood break; 157062a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood case ADD_LISTENER: 157162a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood handleAddListener(msg.arg1); 157262a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood break; 157362a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood case REMOVE_LISTENER: 157462a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood handleRemoveListener(msg.arg1); 157562a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood break; 15769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 157798e48691f738680fe59e7383a41458e7337daccdMike Lockwood // release wake lock if no messages are pending 157898e48691f738680fe59e7383a41458e7337daccdMike Lockwood synchronized (mWakeLock) { 157998e48691f738680fe59e7383a41458e7337daccdMike Lockwood mPendingMessageBits &= ~(1 << message); 158098e48691f738680fe59e7383a41458e7337daccdMike Lockwood if (message == ADD_LISTENER || message == REMOVE_LISTENER) { 158198e48691f738680fe59e7383a41458e7337daccdMike Lockwood mPendingListenerMessages--; 158298e48691f738680fe59e7383a41458e7337daccdMike Lockwood } 158398e48691f738680fe59e7383a41458e7337daccdMike Lockwood if (mPendingMessageBits == 0 && mPendingListenerMessages == 0) { 158498e48691f738680fe59e7383a41458e7337daccdMike Lockwood mWakeLock.release(); 158598e48691f738680fe59e7383a41458e7337daccdMike Lockwood } 158698e48691f738680fe59e7383a41458e7337daccdMike Lockwood } 15879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 158862a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood }; 15899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 159089096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood private final class GpsLocationProviderThread extends Thread { 159189096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood 159289096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood public GpsLocationProviderThread() { 159389096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood super("GpsLocationProvider"); 159489096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood } 159589096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood 159689096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood public void run() { 159789096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 159889096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood initialize(); 159989096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood Looper.prepare(); 160089096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood mHandler = new ProviderHandler(); 160189096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood // signal when we are initialized and ready to go 160289096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood mInitializedLatch.countDown(); 160389096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood Looper.loop(); 160489096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood } 16059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 16069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1607a5fe6b2efee02ab11c35e80ec50fec62be227273Kevin Tang private String getSelectedApn() { 1608a5fe6b2efee02ab11c35e80ec50fec62be227273Kevin Tang Uri uri = Uri.parse("content://telephony/carriers/preferapn"); 1609a5fe6b2efee02ab11c35e80ec50fec62be227273Kevin Tang String apn = null; 1610a5fe6b2efee02ab11c35e80ec50fec62be227273Kevin Tang 1611a5fe6b2efee02ab11c35e80ec50fec62be227273Kevin Tang Cursor cursor = mContext.getContentResolver().query(uri, new String[] {"apn"}, 1612a5fe6b2efee02ab11c35e80ec50fec62be227273Kevin Tang null, null, Carriers.DEFAULT_SORT_ORDER); 1613a5fe6b2efee02ab11c35e80ec50fec62be227273Kevin Tang 1614a5fe6b2efee02ab11c35e80ec50fec62be227273Kevin Tang if (null != cursor) { 1615a5fe6b2efee02ab11c35e80ec50fec62be227273Kevin Tang try { 1616a5fe6b2efee02ab11c35e80ec50fec62be227273Kevin Tang if (cursor.moveToFirst()) { 1617a5fe6b2efee02ab11c35e80ec50fec62be227273Kevin Tang apn = cursor.getString(0); 1618a5fe6b2efee02ab11c35e80ec50fec62be227273Kevin Tang } 1619a5fe6b2efee02ab11c35e80ec50fec62be227273Kevin Tang } finally { 1620a5fe6b2efee02ab11c35e80ec50fec62be227273Kevin Tang cursor.close(); 1621a5fe6b2efee02ab11c35e80ec50fec62be227273Kevin Tang } 1622a5fe6b2efee02ab11c35e80ec50fec62be227273Kevin Tang } 1623a5fe6b2efee02ab11c35e80ec50fec62be227273Kevin Tang return apn; 1624a5fe6b2efee02ab11c35e80ec50fec62be227273Kevin Tang } 1625a5fe6b2efee02ab11c35e80ec50fec62be227273Kevin Tang 16269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // for GPS SV statistics 16279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int MAX_SVS = 32; 16289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int EPHEMERIS_MASK = 0; 16299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int ALMANAC_MASK = 1; 16309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int USED_FOR_FIX_MASK = 2; 16319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // preallocated arrays, to avoid memory allocation in reportStatus() 16339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mSvs[] = new int[MAX_SVS]; 16349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private float mSnrs[] = new float[MAX_SVS]; 16359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private float mSvElevations[] = new float[MAX_SVS]; 16369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private float mSvAzimuths[] = new float[MAX_SVS]; 16379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mSvMasks[] = new int[3]; 16389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mSvCount; 1639b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood // preallocated to avoid memory allocation in reportNmea() 1640b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood private byte[] mNmeaBuffer = new byte[120]; 16419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static { class_init_native(); } 16439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static native void class_init_native(); 16449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static native boolean native_is_supported(); 16459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 16469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native boolean native_init(); 16479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native void native_cleanup(); 164804598b67a58fad93e5060bb77756ba4863013aedMike Lockwood private native boolean native_set_position_mode(int mode, int recurrence, int min_interval, 164904598b67a58fad93e5060bb77756ba4863013aedMike Lockwood int preferred_accuracy, int preferred_time); 165004598b67a58fad93e5060bb77756ba4863013aedMike Lockwood private native boolean native_start(); 16519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native boolean native_stop(); 16529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native void native_delete_aiding_data(int flags); 16539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // returns number of SVs 16549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // mask[0] is ephemeris mask and mask[1] is almanac mask 16559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native int native_read_sv_status(int[] svs, float[] snrs, 16569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float[] elevations, float[] azimuths, int[] masks); 1657f602d362ba4bb3adbf1eb4e38a794fb14274293aMike Lockwood private native int native_read_nmea(byte[] buffer, int bufferSize); 1658d26ce0d903f5141a346d67b2b94437ef3e2880aaMike Lockwood private native void native_inject_location(double latitude, double longitude, float accuracy); 1659d26ce0d903f5141a346d67b2b94437ef3e2880aaMike Lockwood 16603c8fbdf5dd19fad0b3006557716ee1026d7d5899Fred Fettinger // XTRA Support 16619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native void native_inject_time(long time, long timeReference, int uncertainty); 16629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native boolean native_supports_xtra(); 16639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native void native_inject_xtra_data(byte[] data, int length); 1664105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project 16653c8fbdf5dd19fad0b3006557716ee1026d7d5899Fred Fettinger // DEBUG Support 16663c8fbdf5dd19fad0b3006557716ee1026d7d5899Fred Fettinger private native String native_get_internal_state(); 16673c8fbdf5dd19fad0b3006557716ee1026d7d5899Fred Fettinger 16683c8fbdf5dd19fad0b3006557716ee1026d7d5899Fred Fettinger // AGPS Support 1669e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood private native void native_agps_data_conn_open(String apn); 1670e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood private native void native_agps_data_conn_closed(); 1671e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood private native void native_agps_data_conn_failed(); 16721e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja private native void native_agps_ni_message(byte [] msg, int length); 1673a9e546169b3c2c9c5f248d2f3abe3b934f48695dMike Lockwood private native void native_set_agps_server(int type, String hostname, int port); 167422d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie 167522d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie // Network-initiated (NI) Support 167622d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie private native void native_send_ni_response(int notificationId, int userResponse); 16771e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja 16781e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja // AGPS ril suport 16791e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja private native void native_agps_set_ref_location_cellid(int type, int mcc, int mnc, 16801e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja int lac, int cid); 16811e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja private native void native_agps_set_id(int type, String setid); 168250130bbc884a7ad7db39dbc4f54e76e8be87761fMike Lockwood 168350130bbc884a7ad7db39dbc4f54e76e8be87761fMike Lockwood private native void native_update_network_state(boolean connected, int type, 1684a5fe6b2efee02ab11c35e80ec50fec62be227273Kevin Tang boolean roaming, boolean available, String extraInfo, String defaultAPN); 16859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1686