GpsLocationProvider.java revision 104344e507610be42fb70c7deda3c422c543bfcb
19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License. 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1700b74270c9f136a8727c5f6cda0997a3a905f385Mike Lockwoodpackage com.android.server.location; 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1929c84340a14e70419449628ab193d11b7a609e9aMike Lockwoodimport android.app.AlarmManager; 2029c84340a14e70419449628ab193d11b7a609e9aMike Lockwoodimport android.app.PendingIntent; 21105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Projectimport android.content.BroadcastReceiver; 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Context; 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Intent; 24105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Projectimport android.content.IntentFilter; 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.location.Criteria; 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.location.IGpsStatusListener; 2715e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwoodimport android.location.IGpsStatusProvider; 284e50b78bda9cd58be61581d2886c88ff6348a1c1Mike Lockwoodimport android.location.ILocationManager; 2922d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xieimport android.location.INetInitiatedListener; 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.location.Location; 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.location.LocationManager; 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.location.LocationProvider; 3358bda987665af759c379cd494ff4873ac61acf29Mike Lockwoodimport android.net.ConnectivityManager; 3403d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwoodimport android.net.NetworkInfo; 3563aa5a6f98b1016863e4f6edd87eb471b28dc28fMike Lockwoodimport android.os.Binder; 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Bundle; 3762a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwoodimport android.os.Handler; 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.IBinder; 3962a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwoodimport android.os.Looper; 4062a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwoodimport android.os.Message; 410528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwoodimport android.os.PowerManager; 4262a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwoodimport android.os.Process; 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.RemoteException; 442f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwoodimport android.os.ServiceManager; 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.SystemClock; 467e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackbornimport android.os.WorkSource; 47bcab8df83e6e769a7cbcc742e72b47d665998793Mike Lockwoodimport android.provider.Settings; 481e84da822e7aa4d494b31c8759917d2751611f84Miguel Torrojaimport android.provider.Telephony.Sms.Intents; 49b49a73dfc4c9817bba1f227e9330555acdf9b56fJake Hambyimport android.telephony.SmsMessage; 501e84da822e7aa4d494b31c8759917d2751611f84Miguel Torrojaimport android.telephony.TelephonyManager; 511e84da822e7aa4d494b31c8759917d2751611f84Miguel Torrojaimport android.telephony.gsm.GsmCellLocation; 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Log; 53104344e507610be42fb70c7deda3c422c543bfcbJeff Sharkeyimport android.util.NtpTrustedTime; 542f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwoodimport android.util.SparseIntArray; 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 562f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwoodimport com.android.internal.app.IBatteryStats; 5722d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xieimport com.android.internal.location.GpsNetInitiatedHandler; 5822d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xieimport com.android.internal.location.GpsNetInitiatedHandler.GpsNiNotification; 59b49a73dfc4c9817bba1f227e9330555acdf9b56fJake Hambyimport com.android.internal.telephony.Phone; 60105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.File; 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.FileInputStream; 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.IOException; 64104344e507610be42fb70c7deda3c422c543bfcbJeff Sharkeyimport java.io.StringReader; 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.ArrayList; 66f1218be2d8f68f3f445f3bc90e0eca01946a0ddfMike Lockwoodimport java.util.Date; 6722d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xieimport java.util.Map.Entry; 68b49a73dfc4c9817bba1f227e9330555acdf9b56fJake Hambyimport java.util.Properties; 6989096317104722219f73a5c3cc424e6e98c90a61Mike Lockwoodimport java.util.concurrent.CountDownLatch; 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * A GPS implementation of LocationProvider used by LocationManager. 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@hide} 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7689096317104722219f73a5c3cc424e6e98c90a61Mike Lockwoodpublic class GpsLocationProvider implements LocationProviderInterface { 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final String TAG = "GpsLocationProvider"; 7929c84340a14e70419449628ab193d11b7a609e9aMike Lockwood 804a7b65e0d544ef1feff8e1e5789f469f89ebb85cMike Lockwood private static final boolean DEBUG = false; 8129c84340a14e70419449628ab193d11b7a609e9aMike Lockwood private static final boolean VERBOSE = false; 8262a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood 83105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project // these need to match GpsPositionMode enum in gps.h 84105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project private static final int GPS_POSITION_MODE_STANDALONE = 0; 85105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project private static final int GPS_POSITION_MODE_MS_BASED = 1; 86105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project private static final int GPS_POSITION_MODE_MS_ASSISTED = 2; 87105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project 8804598b67a58fad93e5060bb77756ba4863013aedMike Lockwood // these need to match GpsPositionRecurrence enum in gps.h 8904598b67a58fad93e5060bb77756ba4863013aedMike Lockwood private static final int GPS_POSITION_RECURRENCE_PERIODIC = 0; 9004598b67a58fad93e5060bb77756ba4863013aedMike Lockwood private static final int GPS_POSITION_RECURRENCE_SINGLE = 1; 9104598b67a58fad93e5060bb77756ba4863013aedMike Lockwood 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // these need to match GpsStatusValue defines in gps.h 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_STATUS_NONE = 0; 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_STATUS_SESSION_BEGIN = 1; 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_STATUS_SESSION_END = 2; 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_STATUS_ENGINE_ON = 3; 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_STATUS_ENGINE_OFF = 4; 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 99e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood // these need to match GpsApgsStatusValue defines in gps.h 100e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood /** AGPS status event values. */ 101e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood private static final int GPS_REQUEST_AGPS_DATA_CONN = 1; 102e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood private static final int GPS_RELEASE_AGPS_DATA_CONN = 2; 103e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood private static final int GPS_AGPS_DATA_CONNECTED = 3; 104e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood private static final int GPS_AGPS_DATA_CONN_DONE = 4; 105e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood private static final int GPS_AGPS_DATA_CONN_FAILED = 5; 10658bda987665af759c379cd494ff4873ac61acf29Mike Lockwood 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // these need to match GpsLocationFlags enum in gps.h 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int LOCATION_INVALID = 0; 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int LOCATION_HAS_LAT_LONG = 1; 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int LOCATION_HAS_ALTITUDE = 2; 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int LOCATION_HAS_SPEED = 4; 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int LOCATION_HAS_BEARING = 8; 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int LOCATION_HAS_ACCURACY = 16; 114e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood 115e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood// IMPORTANT - the GPS_DELETE_* symbols here must match constants in gps.h 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_DELETE_EPHEMERIS = 0x0001; 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_DELETE_ALMANAC = 0x0002; 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_DELETE_POSITION = 0x0004; 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_DELETE_TIME = 0x0008; 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_DELETE_IONO = 0x0010; 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_DELETE_UTC = 0x0020; 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_DELETE_HEALTH = 0x0040; 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_DELETE_SVDIR = 0x0080; 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_DELETE_SVSTEER = 0x0100; 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_DELETE_SADATA = 0x0200; 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_DELETE_RTI = 0x0400; 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_DELETE_CELLDB_INFO = 0x8000; 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_DELETE_ALL = 0xFFFF; 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13004598b67a58fad93e5060bb77756ba4863013aedMike Lockwood // The GPS_CAPABILITY_* flags must match the values in gps.h 13104598b67a58fad93e5060bb77756ba4863013aedMike Lockwood private static final int GPS_CAPABILITY_SCHEDULING = 0x0000001; 13204598b67a58fad93e5060bb77756ba4863013aedMike Lockwood private static final int GPS_CAPABILITY_MSB = 0x0000002; 13304598b67a58fad93e5060bb77756ba4863013aedMike Lockwood private static final int GPS_CAPABILITY_MSA = 0x0000004; 13404598b67a58fad93e5060bb77756ba4863013aedMike Lockwood private static final int GPS_CAPABILITY_SINGLE_SHOT = 0x0000008; 1359b9fb5cc08eaa0b66a80eba2f03168531544f65aMike Lockwood private static final int GPS_CAPABILITY_ON_DEMAND_TIME = 0x0000010; 13604598b67a58fad93e5060bb77756ba4863013aedMike Lockwood 137e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood // these need to match AGpsType enum in gps.h 138e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood private static final int AGPS_TYPE_SUPL = 1; 139e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood private static final int AGPS_TYPE_C2K = 2; 140e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood 141e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood // for mAGpsDataConnectionState 142e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood private static final int AGPS_DATA_CONNECTION_CLOSED = 0; 143e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood private static final int AGPS_DATA_CONNECTION_OPENING = 1; 144e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood private static final int AGPS_DATA_CONNECTION_OPEN = 2; 14558bda987665af759c379cd494ff4873ac61acf29Mike Lockwood 14662a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood // Handler messages 14762a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood private static final int CHECK_LOCATION = 1; 14862a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood private static final int ENABLE = 2; 14962a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood private static final int ENABLE_TRACKING = 3; 15062a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood private static final int UPDATE_NETWORK_STATE = 4; 15162a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood private static final int INJECT_NTP_TIME = 5; 15262a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood private static final int DOWNLOAD_XTRA_DATA = 6; 15362a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood private static final int UPDATE_LOCATION = 7; 15462a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood private static final int ADD_LISTENER = 8; 15562a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood private static final int REMOVE_LISTENER = 9; 15603ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood private static final int REQUEST_SINGLE_SHOT = 10; 15762a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood 1581e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja // Request setid 1591e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja private static final int AGPS_RIL_REQUEST_SETID_IMSI = 1; 1601e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja private static final int AGPS_RIL_REQUEST_SETID_MSISDN = 2; 1611e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja 1621e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja // Request ref location 1631e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja private static final int AGPS_RIL_REQUEST_REFLOC_CELLID = 1; 1641e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja private static final int AGPS_RIL_REQUEST_REFLOC_MAC = 2; 1651e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja 1661e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja // ref. location info 1671e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja private static final int AGPS_REF_LOCATION_TYPE_GSM_CELLID = 1; 1681e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja private static final int AGPS_REF_LOCATION_TYPE_UMTS_CELLID = 2; 1691e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja private static final int AGPS_REG_LOCATION_TYPE_MAC = 3; 1701e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja 1711e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja // set id info 1721e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja private static final int AGPS_SETID_TYPE_NONE = 0; 1731e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja private static final int AGPS_SETID_TYPE_IMSI = 1; 1741e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja private static final int AGPS_SETID_TYPE_MSISDN = 2; 1751e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final String PROPERTIES_FILE = "/etc/gps.conf"; 1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mLocationFlags = LOCATION_INVALID; 1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // current status 18115e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood private int mStatus = LocationProvider.TEMPORARILY_UNAVAILABLE; 1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // time for last status update 1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private long mStatusUpdateTime = SystemClock.elapsedRealtime(); 185d53ba017ee2381383b4bb4d92e6e0e661431660fMike Lockwood 1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // turn off GPS fix icon if we haven't received a fix in 10 seconds 18704598b67a58fad93e5060bb77756ba4863013aedMike Lockwood private static final long RECENT_FIX_TIMEOUT = 10 * 1000; 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1890632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood // stop trying if we do not receive a fix within 60 seconds 19004598b67a58fad93e5060bb77756ba4863013aedMike Lockwood private static final int NO_FIX_TIMEOUT = 60 * 1000; 1910632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // true if we are enabled 19389096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood private volatile boolean mEnabled; 1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // true if we have network connectivity 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mNetworkAvailable; 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 19862a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood // flags to trigger NTP or XTRA data download when network becomes available 19962a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood // initialized to true so we do NTP and XTRA when the network comes up after booting 20062a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood private boolean mInjectNtpTimePending = true; 2015982bf66d4fdea38105d91ff0f9d38660ac87581Mike Lockwood private boolean mDownloadXtraDataPending = true; 20262a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood 2039b9fb5cc08eaa0b66a80eba2f03168531544f65aMike Lockwood // set to true if the GPS engine does not do on-demand NTP time requests 2049b9fb5cc08eaa0b66a80eba2f03168531544f65aMike Lockwood private boolean mPeriodicTimeInjection; 2059b9fb5cc08eaa0b66a80eba2f03168531544f65aMike Lockwood 2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // true if GPS is navigating 2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mNavigating; 208cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood 209cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood // true if GPS engine is on 210cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood private boolean mEngineOn; 2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 21204598b67a58fad93e5060bb77756ba4863013aedMike Lockwood // requested frequency of fixes, in milliseconds 21304598b67a58fad93e5060bb77756ba4863013aedMike Lockwood private int mFixInterval = 1000; 2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // true if we started navigation 2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mStarted; 2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 21803ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood // true if single shot request is in progress 21903ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood private boolean mSingleShot; 22003ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood 22104598b67a58fad93e5060bb77756ba4863013aedMike Lockwood // capabilities of the GPS engine 22204598b67a58fad93e5060bb77756ba4863013aedMike Lockwood private int mEngineCapabilities; 22304598b67a58fad93e5060bb77756ba4863013aedMike Lockwood 2241a1cd3a878b6389c097e34d114b60cf953edaeaaMike Lockwood // true if XTRA is supported 2251a1cd3a878b6389c097e34d114b60cf953edaeaaMike Lockwood private boolean mSupportsXtra; 2261a1cd3a878b6389c097e34d114b60cf953edaeaaMike Lockwood 2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // for calculating time to first fix 2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private long mFixRequestTime = 0; 2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // time to first fix for most recent session 2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mTTFF = 0; 2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // time we received our last fix 2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private long mLastFixTime; 2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 23404598b67a58fad93e5060bb77756ba4863013aedMike Lockwood private int mPositionMode; 23504598b67a58fad93e5060bb77756ba4863013aedMike Lockwood 2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // properties loaded from PROPERTIES_FILE 2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Properties mProperties; 238734d6031a662a275ec68627bd1258159041d44deMike Lockwood private String mSuplServerHost; 239734d6031a662a275ec68627bd1258159041d44deMike Lockwood private int mSuplServerPort; 240734d6031a662a275ec68627bd1258159041d44deMike Lockwood private String mC2KServerHost; 241734d6031a662a275ec68627bd1258159041d44deMike Lockwood private int mC2KServerPort; 2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 24315e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood private final Context mContext; 244104344e507610be42fb70c7deda3c422c543bfcbJeff Sharkey private final NtpTrustedTime mNtpTime; 24515e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood private final ILocationManager mLocationManager; 2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Location mLocation = new Location(LocationManager.GPS_PROVIDER); 2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Bundle mLocationExtras = new Bundle(); 2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private ArrayList<Listener> mListeners = new ArrayList<Listener>(); 24962a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood 25089096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood // GpsLocationProvider's handler thread 25189096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood private final Thread mThread; 25289096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood // Handler for processing events in mThread. 25362a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood private Handler mHandler; 25489096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood // Used to signal when our main thread has initialized everything 25589096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood private final CountDownLatch mInitializedLatch = new CountDownLatch(1); 256105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project 257e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood private String mAGpsApn; 258e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood private int mAGpsDataConnectionState; 2592f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood private final ConnectivityManager mConnMgr; 26022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie private final GpsNetInitiatedHandler mNIHandler; 2612f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood 2620528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood // Wakelocks 2630528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood private final static String WAKELOCK_KEY = "GpsLocationProvider"; 2640528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood private final PowerManager.WakeLock mWakeLock; 26598e48691f738680fe59e7383a41458e7337daccdMike Lockwood // bitfield of pending messages to our Handler 26698e48691f738680fe59e7383a41458e7337daccdMike Lockwood // used only for messages that cannot have multiple instances queued 26798e48691f738680fe59e7383a41458e7337daccdMike Lockwood private int mPendingMessageBits; 26898e48691f738680fe59e7383a41458e7337daccdMike Lockwood // separate counter for ADD_LISTENER and REMOVE_LISTENER messages, 26998e48691f738680fe59e7383a41458e7337daccdMike Lockwood // which might have multiple instances queued 27098e48691f738680fe59e7383a41458e7337daccdMike Lockwood private int mPendingListenerMessages; 2710528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood 27229c84340a14e70419449628ab193d11b7a609e9aMike Lockwood // Alarms 27329c84340a14e70419449628ab193d11b7a609e9aMike Lockwood private final static String ALARM_WAKEUP = "com.android.internal.location.ALARM_WAKEUP"; 2740632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood private final static String ALARM_TIMEOUT = "com.android.internal.location.ALARM_TIMEOUT"; 27529c84340a14e70419449628ab193d11b7a609e9aMike Lockwood private final AlarmManager mAlarmManager; 27629c84340a14e70419449628ab193d11b7a609e9aMike Lockwood private final PendingIntent mWakeupIntent; 2770632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood private final PendingIntent mTimeoutIntent; 27829c84340a14e70419449628ab193d11b7a609e9aMike Lockwood 2792f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood private final IBatteryStats mBatteryStats; 2802f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood private final SparseIntArray mClientUids = new SparseIntArray(); 281105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project 2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // how often to request NTP time, in milliseconds 2834c126068527c9adba45aa227d40e245ee8e7c9a4Mike Lockwood // current setting 24 hours 2844c126068527c9adba45aa227d40e245ee8e7c9a4Mike Lockwood private static final long NTP_INTERVAL = 24*60*60*1000; 2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // how long to wait if we have a network error in NTP or XTRA downloading 2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // current setting - 5 minutes 287f1218be2d8f68f3f445f3bc90e0eca01946a0ddfMike Lockwood private static final long RETRY_INTERVAL = 5*60*1000; 288f1218be2d8f68f3f445f3bc90e0eca01946a0ddfMike Lockwood 28915e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood private final IGpsStatusProvider mGpsStatusProvider = new IGpsStatusProvider.Stub() { 29015e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood public void addGpsStatusListener(IGpsStatusListener listener) throws RemoteException { 29115e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood if (listener == null) { 29215e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood throw new NullPointerException("listener is null in addGpsStatusListener"); 29315e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 29415e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood 29515e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood synchronized(mListeners) { 29615e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood IBinder binder = listener.asBinder(); 29715e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood int size = mListeners.size(); 29815e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood for (int i = 0; i < size; i++) { 29915e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood Listener test = mListeners.get(i); 30015e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood if (binder.equals(test.mListener.asBinder())) { 30115e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood // listener already added 30215e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood return; 30315e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 30415e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 30515e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood 30615e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood Listener l = new Listener(listener); 30715e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood binder.linkToDeath(l, 0); 30815e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood mListeners.add(l); 30915e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 31015e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 31115e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood 31215e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood public void removeGpsStatusListener(IGpsStatusListener listener) { 31315e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood if (listener == null) { 31415e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood throw new NullPointerException("listener is null in addGpsStatusListener"); 31515e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 31615e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood 31715e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood synchronized(mListeners) { 31815e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood IBinder binder = listener.asBinder(); 31915e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood Listener l = null; 32015e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood int size = mListeners.size(); 32115e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood for (int i = 0; i < size && l == null; i++) { 32215e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood Listener test = mListeners.get(i); 32315e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood if (binder.equals(test.mListener.asBinder())) { 32415e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood l = test; 32515e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 32615e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 32715e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood 32815e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood if (l != null) { 32915e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood mListeners.remove(l); 33015e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood binder.unlinkToDeath(l, 0); 33115e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 33215e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 33315e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 33415e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood }; 33515e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood 33615e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood public IGpsStatusProvider getGpsStatusProvider() { 33715e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood return mGpsStatusProvider; 33815e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 33915e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood 34029c84340a14e70419449628ab193d11b7a609e9aMike Lockwood private final BroadcastReceiver mBroadcastReciever = new BroadcastReceiver() { 341105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project @Override public void onReceive(Context context, Intent intent) { 342105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project String action = intent.getAction(); 343105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project 34429c84340a14e70419449628ab193d11b7a609e9aMike Lockwood if (action.equals(ALARM_WAKEUP)) { 34529c84340a14e70419449628ab193d11b7a609e9aMike Lockwood if (DEBUG) Log.d(TAG, "ALARM_WAKEUP"); 34603ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood startNavigating(false); 3470632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood } else if (action.equals(ALARM_TIMEOUT)) { 3480632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood if (DEBUG) Log.d(TAG, "ALARM_TIMEOUT"); 3490632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood hibernate(); 3501e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja } else if (action.equals(Intents.DATA_SMS_RECEIVED_ACTION)) { 3511e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja checkSmsSuplInit(intent); 3521e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja } else if (action.equals(Intents.WAP_PUSH_RECEIVED_ACTION)) { 3531e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja checkWapSuplInit(intent); 3541e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja } 355105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project } 35629c84340a14e70419449628ab193d11b7a609e9aMike Lockwood }; 357105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project 3581e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja private void checkSmsSuplInit(Intent intent) { 3591e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja SmsMessage[] messages = Intents.getMessagesFromIntent(intent); 3601e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja for (int i=0; i <messages.length; i++) { 3611e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja byte[] supl_init = messages[i].getUserData(); 3621e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja native_agps_ni_message(supl_init,supl_init.length); 3631e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja } 3641e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja } 3651e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja 3661e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja private void checkWapSuplInit(Intent intent) { 3671e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja byte[] supl_init = (byte[]) intent.getExtra("data"); 3681e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja native_agps_ni_message(supl_init,supl_init.length); 3691e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja } 3701e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja 3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static boolean isSupported() { 3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return native_is_supported(); 3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3754e50b78bda9cd58be61581d2886c88ff6348a1c1Mike Lockwood public GpsLocationProvider(Context context, ILocationManager locationManager) { 3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContext = context; 377104344e507610be42fb70c7deda3c422c543bfcbJeff Sharkey mNtpTime = NtpTrustedTime.getInstance(context); 37815e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood mLocationManager = locationManager; 37979e642e8ed75033eacc461633a8f4cd5157d25dfMike Lockwood mNIHandler = new GpsNetInitiatedHandler(context); 38063598a0619776b421f27cd12fb29eb83dc327997Mike Lockwood 38163598a0619776b421f27cd12fb29eb83dc327997Mike Lockwood mLocation.setExtras(mLocationExtras); 3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3830528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood // Create a wake lock 3840528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood PowerManager powerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE); 3850528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, WAKELOCK_KEY); 38698e48691f738680fe59e7383a41458e7337daccdMike Lockwood mWakeLock.setReferenceCounted(false); 3870528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood 38829c84340a14e70419449628ab193d11b7a609e9aMike Lockwood mAlarmManager = (AlarmManager)mContext.getSystemService(Context.ALARM_SERVICE); 38929c84340a14e70419449628ab193d11b7a609e9aMike Lockwood mWakeupIntent = PendingIntent.getBroadcast(mContext, 0, new Intent(ALARM_WAKEUP), 0); 3900632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood mTimeoutIntent = PendingIntent.getBroadcast(mContext, 0, new Intent(ALARM_TIMEOUT), 0); 39129c84340a14e70419449628ab193d11b7a609e9aMike Lockwood 3921e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja IntentFilter intentFilter = new IntentFilter(); 3931e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja intentFilter.addAction(Intents.DATA_SMS_RECEIVED_ACTION); 3941e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja intentFilter.addDataScheme("sms"); 3951e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja intentFilter.addDataAuthority("localhost","7275"); 3961e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja context.registerReceiver(mBroadcastReciever, intentFilter); 3971e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja 3981e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja intentFilter = new IntentFilter(); 3991e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja intentFilter.addAction(Intents.WAP_PUSH_RECEIVED_ACTION); 4001e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja try { 4011e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja intentFilter.addDataType("application/vnd.omaloc-supl-init"); 4021e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja } catch (IntentFilter.MalformedMimeTypeException e) { 4031e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja Log.w(TAG, "Malformed SUPL init mime type"); 4041e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja } 4051e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja context.registerReceiver(mBroadcastReciever, intentFilter); 4061e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja 40758bda987665af759c379cd494ff4873ac61acf29Mike Lockwood mConnMgr = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE); 40858bda987665af759c379cd494ff4873ac61acf29Mike Lockwood 4092f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood // Battery statistics service to be notified when GPS turns on or off 4102f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood mBatteryStats = IBatteryStats.Stub.asInterface(ServiceManager.getService("batteryinfo")); 4112f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood 4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mProperties = new Properties(); 4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project File file = new File(PROPERTIES_FILE); 4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project FileInputStream stream = new FileInputStream(file); 4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mProperties.load(stream); 4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project stream.close(); 418e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood 419734d6031a662a275ec68627bd1258159041d44deMike Lockwood mSuplServerHost = mProperties.getProperty("SUPL_HOST"); 420e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood String portString = mProperties.getProperty("SUPL_PORT"); 421734d6031a662a275ec68627bd1258159041d44deMike Lockwood if (mSuplServerHost != null && portString != null) { 422105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project try { 423734d6031a662a275ec68627bd1258159041d44deMike Lockwood mSuplServerPort = Integer.parseInt(portString); 424105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project } catch (NumberFormatException e) { 425e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood Log.e(TAG, "unable to parse SUPL_PORT: " + portString); 426e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood } 427e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood } 428e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood 429734d6031a662a275ec68627bd1258159041d44deMike Lockwood mC2KServerHost = mProperties.getProperty("C2K_HOST"); 430e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood portString = mProperties.getProperty("C2K_PORT"); 431734d6031a662a275ec68627bd1258159041d44deMike Lockwood if (mC2KServerHost != null && portString != null) { 432e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood try { 433734d6031a662a275ec68627bd1258159041d44deMike Lockwood mC2KServerPort = Integer.parseInt(portString); 434e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood } catch (NumberFormatException e) { 435e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood Log.e(TAG, "unable to parse C2K_PORT: " + portString); 436105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project } 437105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project } 4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (IOException e) { 4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.w(TAG, "Could not open GPS configuration file " + PROPERTIES_FILE); 4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 44162a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood 44289096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood // wait until we are fully initialized before returning 44389096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood mThread = new GpsLocationProviderThread(); 44489096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood mThread.start(); 44589096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood while (true) { 44689096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood try { 44789096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood mInitializedLatch.await(); 44889096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood break; 44989096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood } catch (InterruptedException e) { 45089096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood Thread.currentThread().interrupt(); 45189096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood } 45289096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood } 45362a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood } 45462a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood 45562a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood private void initialize() { 45662a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood // register our receiver on our thread rather than the main thread 45762a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood IntentFilter intentFilter = new IntentFilter(); 45862a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood intentFilter.addAction(ALARM_WAKEUP); 45962a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood intentFilter.addAction(ALARM_TIMEOUT); 46062a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood mContext.registerReceiver(mBroadcastReciever, intentFilter); 4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 464d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood * Returns the name of this provider. 465d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood */ 466d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood public String getName() { 467d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood return LocationManager.GPS_PROVIDER; 468d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood } 469d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood 470d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood /** 4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns true if the provider requires access to a 4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * data network (e.g., the Internet), false otherwise. 4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean requiresNetwork() { 475a9e546169b3c2c9c5f248d2f3abe3b934f48695dMike Lockwood return true; 4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 47803d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood public void updateNetworkState(int state, NetworkInfo info) { 47998e48691f738680fe59e7383a41458e7337daccdMike Lockwood sendMessage(UPDATE_NETWORK_STATE, state, info); 48062a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood } 48162a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood 48262a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood private void handleUpdateNetworkState(int state, NetworkInfo info) { 4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNetworkAvailable = (state == LocationProvider.AVAILABLE); 4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 485f5d95cbc1a6974afeb4d3155bdaa8dae55722a39Joe Onorato if (DEBUG) { 48603d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood Log.d(TAG, "updateNetworkState " + (mNetworkAvailable ? "available" : "unavailable") 48703d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood + " info: " + info); 4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 48903d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood 49050130bbc884a7ad7db39dbc4f54e76e8be87761fMike Lockwood if (info != null) { 49150130bbc884a7ad7db39dbc4f54e76e8be87761fMike Lockwood native_update_network_state(info.isConnected(), info.getType(), 49250130bbc884a7ad7db39dbc4f54e76e8be87761fMike Lockwood info.isRoaming(), info.getExtraInfo()); 49350130bbc884a7ad7db39dbc4f54e76e8be87761fMike Lockwood } 49450130bbc884a7ad7db39dbc4f54e76e8be87761fMike Lockwood 49503d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood if (info != null && info.getType() == ConnectivityManager.TYPE_MOBILE_SUPL 49603d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood && mAGpsDataConnectionState == AGPS_DATA_CONNECTION_OPENING) { 49703d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood String apnName = info.getExtraInfo(); 49803d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood if (mNetworkAvailable && apnName != null && apnName.length() > 0) { 49903d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood mAGpsApn = apnName; 50003d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood if (DEBUG) Log.d(TAG, "call native_agps_data_conn_open"); 50103d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood native_agps_data_conn_open(apnName); 50203d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood mAGpsDataConnectionState = AGPS_DATA_CONNECTION_OPEN; 50303d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood } else { 50403d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood if (DEBUG) Log.d(TAG, "call native_agps_data_conn_failed"); 50503d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood mAGpsApn = null; 50603d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood mAGpsDataConnectionState = AGPS_DATA_CONNECTION_CLOSED; 50703d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood native_agps_data_conn_failed(); 50803d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood } 50903d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood } 51003d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood 51162a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood if (mNetworkAvailable) { 51262a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood if (mInjectNtpTimePending) { 51398e48691f738680fe59e7383a41458e7337daccdMike Lockwood sendMessage(INJECT_NTP_TIME, 0, null); 51462a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood } 51562a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood if (mDownloadXtraDataPending) { 51698e48691f738680fe59e7383a41458e7337daccdMike Lockwood sendMessage(DOWNLOAD_XTRA_DATA, 0, null); 51762a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood } 51862a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood } 51962a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood } 52062a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood 52162a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood private void handleInjectNtpTime() { 52262a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood if (!mNetworkAvailable) { 52362a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood // try again when network is up 52462a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood mInjectNtpTimePending = true; 52562a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood return; 52662a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood } 52762a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood mInjectNtpTimePending = false; 52862a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood 52962a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood long delay; 53062a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood 531104344e507610be42fb70c7deda3c422c543bfcbJeff Sharkey // force refresh NTP cache when outdated 532104344e507610be42fb70c7deda3c422c543bfcbJeff Sharkey if (mNtpTime.getCacheAge() >= NTP_INTERVAL) { 533104344e507610be42fb70c7deda3c422c543bfcbJeff Sharkey mNtpTime.forceRefresh(); 534104344e507610be42fb70c7deda3c422c543bfcbJeff Sharkey } 535104344e507610be42fb70c7deda3c422c543bfcbJeff Sharkey 536104344e507610be42fb70c7deda3c422c543bfcbJeff Sharkey // only update when NTP time is fresh 537104344e507610be42fb70c7deda3c422c543bfcbJeff Sharkey if (mNtpTime.getCacheAge() < NTP_INTERVAL) { 538104344e507610be42fb70c7deda3c422c543bfcbJeff Sharkey long time = mNtpTime.getCachedNtpTime(); 539104344e507610be42fb70c7deda3c422c543bfcbJeff Sharkey long timeReference = mNtpTime.getCachedNtpTimeReference(); 540104344e507610be42fb70c7deda3c422c543bfcbJeff Sharkey long certainty = mNtpTime.getCacheCertainty(); 54162a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood long now = System.currentTimeMillis(); 54262a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood 54362a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood Log.d(TAG, "NTP server returned: " 54462a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood + time + " (" + new Date(time) 54562a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood + ") reference: " + timeReference 54662a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood + " certainty: " + certainty 5471879d284bf3dd704dbc8c95aad262ebbe3c3c0a4Mike Lockwood + " system time offset: " + (time - now)); 54862a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood 549104344e507610be42fb70c7deda3c422c543bfcbJeff Sharkey native_inject_time(time, timeReference, (int) certainty); 55062a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood delay = NTP_INTERVAL; 55162a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood } else { 55262a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood if (DEBUG) Log.d(TAG, "requestTime failed"); 55362a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood delay = RETRY_INTERVAL; 55462a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood } 55562a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood 5569b9fb5cc08eaa0b66a80eba2f03168531544f65aMike Lockwood if (mPeriodicTimeInjection) { 5579b9fb5cc08eaa0b66a80eba2f03168531544f65aMike Lockwood // send delayed message for next NTP injection 5589b9fb5cc08eaa0b66a80eba2f03168531544f65aMike Lockwood // since this is delayed and not urgent we do not hold a wake lock here 5599b9fb5cc08eaa0b66a80eba2f03168531544f65aMike Lockwood mHandler.removeMessages(INJECT_NTP_TIME); 5609b9fb5cc08eaa0b66a80eba2f03168531544f65aMike Lockwood mHandler.sendMessageDelayed(Message.obtain(mHandler, INJECT_NTP_TIME), delay); 5619b9fb5cc08eaa0b66a80eba2f03168531544f65aMike Lockwood } 56262a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood } 56362a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood 56462a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood private void handleDownloadXtraData() { 5655723dfe8c87d0887b8926f43637ed300466890d2Mike Lockwood if (!mNetworkAvailable) { 56662a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood // try again when network is up 56762a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood mDownloadXtraDataPending = true; 56862a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood return; 56962a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood } 57062a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood mDownloadXtraDataPending = false; 57162a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood 57262a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood 57362a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood GpsXtraDownloader xtraDownloader = new GpsXtraDownloader(mContext, mProperties); 57462a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood byte[] data = xtraDownloader.downloadXtraData(); 57562a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood if (data != null) { 57662a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood if (DEBUG) { 57762a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood Log.d(TAG, "calling native_inject_xtra_data"); 57862a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood } 57962a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood native_inject_xtra_data(data, data.length); 58062a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood } else { 58162a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood // try again later 58298e48691f738680fe59e7383a41458e7337daccdMike Lockwood // since this is delayed and not urgent we do not hold a wake lock here 58362a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood mHandler.removeMessages(DOWNLOAD_XTRA_DATA); 58462a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood mHandler.sendMessageDelayed(Message.obtain(mHandler, DOWNLOAD_XTRA_DATA), RETRY_INTERVAL); 58562a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood } 5869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 589fd6e5f0dda50e113db4ccc55338b6c4f09da37a4Mike Lockwood * This is called to inform us when another location provider returns a location. 590fd6e5f0dda50e113db4ccc55338b6c4f09da37a4Mike Lockwood * Someday we might use this for network location injection to aid the GPS 591fd6e5f0dda50e113db4ccc55338b6c4f09da37a4Mike Lockwood */ 592fd6e5f0dda50e113db4ccc55338b6c4f09da37a4Mike Lockwood public void updateLocation(Location location) { 59398e48691f738680fe59e7383a41458e7337daccdMike Lockwood sendMessage(UPDATE_LOCATION, 0, location); 59462a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood } 59562a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood 59662a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood private void handleUpdateLocation(Location location) { 597d26ce0d903f5141a346d67b2b94437ef3e2880aaMike Lockwood if (location.hasAccuracy()) { 598d26ce0d903f5141a346d67b2b94437ef3e2880aaMike Lockwood native_inject_location(location.getLatitude(), location.getLongitude(), 599d26ce0d903f5141a346d67b2b94437ef3e2880aaMike Lockwood location.getAccuracy()); 600d26ce0d903f5141a346d67b2b94437ef3e2880aaMike Lockwood } 601fd6e5f0dda50e113db4ccc55338b6c4f09da37a4Mike Lockwood } 602fd6e5f0dda50e113db4ccc55338b6c4f09da37a4Mike Lockwood 603fd6e5f0dda50e113db4ccc55338b6c4f09da37a4Mike Lockwood /** 6049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns true if the provider requires access to a 6059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * satellite-based positioning system (e.g., GPS), false 6069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * otherwise. 6079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean requiresSatellite() { 6099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 6109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns true if the provider requires access to an appropriate 6149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * cellular network (e.g., to make use of cell tower IDs), false 6159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * otherwise. 6169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean requiresCell() { 6189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 6199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns true if the use of this provider may result in a 6239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * monetary charge to the user, false if use is free. It is up to 6249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * each provider to give accurate information. 6259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean hasMonetaryCost() { 6279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 6289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns true if the provider is able to provide altitude 6329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * information, false otherwise. A provider that reports altitude 6339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * under most circumstances but may occassionally not report it 6349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * should return true. 6359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean supportsAltitude() { 6379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 6389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns true if the provider is able to provide speed 6429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * information, false otherwise. A provider that reports speed 6439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * under most circumstances but may occassionally not report it 6449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * should return true. 6459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean supportsSpeed() { 6479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 6489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns true if the provider is able to provide bearing 6529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * information, false otherwise. A provider that reports bearing 6539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * under most circumstances but may occassionally not report it 6549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * should return true. 6559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean supportsBearing() { 6579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 6589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns the power requirement for this provider. 6629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 6639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the power requirement for this provider, as one of the 6649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * constants Criteria.POWER_REQUIREMENT_*. 6659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getPowerRequirement() { 6679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return Criteria.POWER_HIGH; 6689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 67103ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood * Returns true if this provider meets the given criteria, 67203ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood * false otherwise. 67303ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood */ 67403ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood public boolean meetsCriteria(Criteria criteria) { 67503ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood return (criteria.getPowerRequirement() != Criteria.POWER_LOW); 67603ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood } 67703ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood 67803ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood /** 6799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns the horizontal accuracy of this provider 6809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 6819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the accuracy of location from this provider, as one 6829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * of the constants Criteria.ACCURACY_*. 6839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getAccuracy() { 6859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return Criteria.ACCURACY_FINE; 6869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Enables this provider. When enabled, calls to getStatus() 6904e50b78bda9cd58be61581d2886c88ff6348a1c1Mike Lockwood * must be handled. Hardware may be started up 6919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * when the provider is enabled. 6929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 69362a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood public void enable() { 69462a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood synchronized (mHandler) { 69598e48691f738680fe59e7383a41458e7337daccdMike Lockwood sendMessage(ENABLE, 1, null); 69662a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood } 69762a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood } 69862a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood 69962a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood private void handleEnable() { 70062a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood if (DEBUG) Log.d(TAG, "handleEnable"); 7019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mEnabled) return; 7029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEnabled = native_init(); 7039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mEnabled) { 7051a1cd3a878b6389c097e34d114b60cf953edaeaaMike Lockwood mSupportsXtra = native_supports_xtra(); 706734d6031a662a275ec68627bd1258159041d44deMike Lockwood if (mSuplServerHost != null) { 707734d6031a662a275ec68627bd1258159041d44deMike Lockwood native_set_agps_server(AGPS_TYPE_SUPL, mSuplServerHost, mSuplServerPort); 708734d6031a662a275ec68627bd1258159041d44deMike Lockwood } 709734d6031a662a275ec68627bd1258159041d44deMike Lockwood if (mC2KServerHost != null) { 710734d6031a662a275ec68627bd1258159041d44deMike Lockwood native_set_agps_server(AGPS_TYPE_C2K, mC2KServerHost, mC2KServerPort); 711734d6031a662a275ec68627bd1258159041d44deMike Lockwood } 7129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 7139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.w(TAG, "Failed to enable location provider"); 7149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Disables this provider. When disabled, calls to getStatus() 7194e50b78bda9cd58be61581d2886c88ff6348a1c1Mike Lockwood * need not be handled. Hardware may be shut 7209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * down while the provider is disabled. 7219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 72262a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood public void disable() { 72362a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood synchronized (mHandler) { 72498e48691f738680fe59e7383a41458e7337daccdMike Lockwood sendMessage(ENABLE, 0, null); 72562a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood } 72662a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood } 72762a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood 72862a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood private void handleDisable() { 72989096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood if (DEBUG) Log.d(TAG, "handleDisable"); 7309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mEnabled) return; 7319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEnabled = false; 7339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project stopNavigating(); 7349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 735cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood // do this before releasing wakelock 736cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood native_cleanup(); 7379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 739d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood public boolean isEnabled() { 740d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood return mEnabled; 741d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood } 742d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood 7439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getStatus(Bundle extras) { 7449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras != null) { 7459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project extras.putInt("satellites", mSvCount); 7469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mStatus; 7489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void updateStatus(int status, int svCount) { 7519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (status != mStatus || svCount != mSvCount) { 7529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStatus = status; 7539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSvCount = svCount; 7549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocationExtras.putInt("satellites", svCount); 7559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStatusUpdateTime = SystemClock.elapsedRealtime(); 7569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public long getStatusUpdateTime() { 7609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mStatusUpdateTime; 7619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void enableLocationTracking(boolean enable) { 76403ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood // FIXME - should set a flag here to avoid race conditions with single shot request 76562a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood synchronized (mHandler) { 76698e48691f738680fe59e7383a41458e7337daccdMike Lockwood sendMessage(ENABLE_TRACKING, (enable ? 1 : 0), null); 76762a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood } 76862a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood } 76962a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood 77062a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood private void handleEnableLocationTracking(boolean enable) { 7719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (enable) { 7729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTTFF = 0; 7739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLastFixTime = 0; 77403ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood startNavigating(false); 7759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 77604598b67a58fad93e5060bb77756ba4863013aedMike Lockwood if (!hasCapability(GPS_CAPABILITY_SCHEDULING)) { 77704598b67a58fad93e5060bb77756ba4863013aedMike Lockwood mAlarmManager.cancel(mWakeupIntent); 77804598b67a58fad93e5060bb77756ba4863013aedMike Lockwood mAlarmManager.cancel(mTimeoutIntent); 77904598b67a58fad93e5060bb77756ba4863013aedMike Lockwood } 7809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project stopNavigating(); 7819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 78403ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood public boolean requestSingleShotFix() { 78503ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood if (mStarted) { 78603ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood // cannot do single shot if already navigating 78703ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood return false; 78803ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood } 78903ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood synchronized (mHandler) { 79003ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood mHandler.removeMessages(REQUEST_SINGLE_SHOT); 79103ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood Message m = Message.obtain(mHandler, REQUEST_SINGLE_SHOT); 79203ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood mHandler.sendMessage(m); 79303ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood } 79403ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood return true; 79503ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood } 79603ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood 79703ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood private void handleRequestSingleShot() { 79803ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood mTTFF = 0; 79903ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood mLastFixTime = 0; 80003ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood startNavigating(true); 80103ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood } 80203ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood 8037e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn public void setMinTime(long minTime, WorkSource ws) { 804f5d95cbc1a6974afeb4d3155bdaa8dae55722a39Joe Onorato if (DEBUG) Log.d(TAG, "setMinTime " + minTime); 8059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (minTime >= 0) { 80704598b67a58fad93e5060bb77756ba4863013aedMike Lockwood mFixInterval = (int)minTime; 80804598b67a58fad93e5060bb77756ba4863013aedMike Lockwood 80904598b67a58fad93e5060bb77756ba4863013aedMike Lockwood if (mStarted && hasCapability(GPS_CAPABILITY_SCHEDULING)) { 81004598b67a58fad93e5060bb77756ba4863013aedMike Lockwood if (!native_set_position_mode(mPositionMode, GPS_POSITION_RECURRENCE_PERIODIC, 81104598b67a58fad93e5060bb77756ba4863013aedMike Lockwood mFixInterval, 0, 0)) { 81204598b67a58fad93e5060bb77756ba4863013aedMike Lockwood Log.e(TAG, "set_position_mode failed in setMinTime()"); 81304598b67a58fad93e5060bb77756ba4863013aedMike Lockwood } 8149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8183c8fbdf5dd19fad0b3006557716ee1026d7d5899Fred Fettinger public String getInternalState() { 8193c8fbdf5dd19fad0b3006557716ee1026d7d5899Fred Fettinger return native_get_internal_state(); 8203c8fbdf5dd19fad0b3006557716ee1026d7d5899Fred Fettinger } 8213c8fbdf5dd19fad0b3006557716ee1026d7d5899Fred Fettinger 8229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final class Listener implements IBinder.DeathRecipient { 8239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final IGpsStatusListener mListener; 8249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int mSensors = 0; 8269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Listener(IGpsStatusListener listener) { 8289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mListener = listener; 8299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void binderDied() { 832f5d95cbc1a6974afeb4d3155bdaa8dae55722a39Joe Onorato if (DEBUG) Log.d(TAG, "GPS status listener died"); 8339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized(mListeners) { 8359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mListeners.remove(this); 8369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 837fff2fda0199dedbf1079454dca98a81190dce765Suchi Amalapurapu if (mListener != null) { 838fff2fda0199dedbf1079454dca98a81190dce765Suchi Amalapurapu mListener.asBinder().unlinkToDeath(this, 0); 839fff2fda0199dedbf1079454dca98a81190dce765Suchi Amalapurapu } 8409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8432f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood public void addListener(int uid) { 84498e48691f738680fe59e7383a41458e7337daccdMike Lockwood synchronized (mWakeLock) { 84598e48691f738680fe59e7383a41458e7337daccdMike Lockwood mPendingListenerMessages++; 8467e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn mWakeLock.acquire(); 84798e48691f738680fe59e7383a41458e7337daccdMike Lockwood Message m = Message.obtain(mHandler, ADD_LISTENER); 84898e48691f738680fe59e7383a41458e7337daccdMike Lockwood m.arg1 = uid; 84998e48691f738680fe59e7383a41458e7337daccdMike Lockwood mHandler.sendMessage(m); 85098e48691f738680fe59e7383a41458e7337daccdMike Lockwood } 85162a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood } 85262a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood 85362a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood private void handleAddListener(int uid) { 8542e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn synchronized(mListeners) { 8552e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn if (mClientUids.indexOfKey(uid) >= 0) { 8562e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn // Shouldn't be here -- already have this uid. 8572e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn Log.w(TAG, "Duplicate add listener for uid " + uid); 8582e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn return; 8592e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn } 8602e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn mClientUids.put(uid, 0); 8612e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn if (mNavigating) { 8622e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn try { 8632e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn mBatteryStats.noteStartGps(uid); 8642e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn } catch (RemoteException e) { 8652e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn Log.w(TAG, "RemoteException in addListener"); 8662e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn } 8672f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } 8682f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } 8692f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } 8702f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood 8712f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood public void removeListener(int uid) { 87298e48691f738680fe59e7383a41458e7337daccdMike Lockwood synchronized (mWakeLock) { 87398e48691f738680fe59e7383a41458e7337daccdMike Lockwood mPendingListenerMessages++; 87498e48691f738680fe59e7383a41458e7337daccdMike Lockwood mWakeLock.acquire(); 87598e48691f738680fe59e7383a41458e7337daccdMike Lockwood Message m = Message.obtain(mHandler, REMOVE_LISTENER); 87698e48691f738680fe59e7383a41458e7337daccdMike Lockwood m.arg1 = uid; 87798e48691f738680fe59e7383a41458e7337daccdMike Lockwood mHandler.sendMessage(m); 87898e48691f738680fe59e7383a41458e7337daccdMike Lockwood } 87962a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood } 88062a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood 88162a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood private void handleRemoveListener(int uid) { 8822e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn synchronized(mListeners) { 8832e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn if (mClientUids.indexOfKey(uid) < 0) { 8842e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn // Shouldn't be here -- don't have this uid. 8852e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn Log.w(TAG, "Unneeded remove listener for uid " + uid); 8862e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn return; 8872e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn } 8882e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn mClientUids.delete(uid); 8892e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn if (mNavigating) { 8902e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn try { 8912e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn mBatteryStats.noteStopGps(uid); 8922e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn } catch (RemoteException e) { 8932e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn Log.w(TAG, "RemoteException in removeListener"); 8942e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn } 8952f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } 8962f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } 8972f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } 8982f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood 8999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean sendExtraCommand(String command, Bundle extras) { 9009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 90163aa5a6f98b1016863e4f6edd87eb471b28dc28fMike Lockwood long identity = Binder.clearCallingIdentity(); 90263aa5a6f98b1016863e4f6edd87eb471b28dc28fMike Lockwood boolean result = false; 90363aa5a6f98b1016863e4f6edd87eb471b28dc28fMike Lockwood 9049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ("delete_aiding_data".equals(command)) { 90563aa5a6f98b1016863e4f6edd87eb471b28dc28fMike Lockwood result = deleteAidingData(extras); 90663aa5a6f98b1016863e4f6edd87eb471b28dc28fMike Lockwood } else if ("force_time_injection".equals(command)) { 90798e48691f738680fe59e7383a41458e7337daccdMike Lockwood sendMessage(INJECT_NTP_TIME, 0, null); 90863aa5a6f98b1016863e4f6edd87eb471b28dc28fMike Lockwood result = true; 90963aa5a6f98b1016863e4f6edd87eb471b28dc28fMike Lockwood } else if ("force_xtra_injection".equals(command)) { 9101a1cd3a878b6389c097e34d114b60cf953edaeaaMike Lockwood if (mSupportsXtra) { 91193bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood xtraDownloadRequest(); 91263aa5a6f98b1016863e4f6edd87eb471b28dc28fMike Lockwood result = true; 91393bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood } 91463aa5a6f98b1016863e4f6edd87eb471b28dc28fMike Lockwood } else { 91563aa5a6f98b1016863e4f6edd87eb471b28dc28fMike Lockwood Log.w(TAG, "sendExtraCommand: unknown command " + command); 91693bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood } 9179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 91863aa5a6f98b1016863e4f6edd87eb471b28dc28fMike Lockwood Binder.restoreCallingIdentity(identity); 91963aa5a6f98b1016863e4f6edd87eb471b28dc28fMike Lockwood return result; 9209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean deleteAidingData(Bundle extras) { 9239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int flags; 9249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras == null) { 9269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project flags = GPS_DELETE_ALL; 9279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 9289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project flags = 0; 9299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("ephemeris")) flags |= GPS_DELETE_EPHEMERIS; 9309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("almanac")) flags |= GPS_DELETE_ALMANAC; 9319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("position")) flags |= GPS_DELETE_POSITION; 9329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("time")) flags |= GPS_DELETE_TIME; 9339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("iono")) flags |= GPS_DELETE_IONO; 9349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("utc")) flags |= GPS_DELETE_UTC; 9359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("health")) flags |= GPS_DELETE_HEALTH; 9369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("svdir")) flags |= GPS_DELETE_SVDIR; 9379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("svsteer")) flags |= GPS_DELETE_SVSTEER; 9389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("sadata")) flags |= GPS_DELETE_SADATA; 9399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("rti")) flags |= GPS_DELETE_RTI; 9409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("celldb-info")) flags |= GPS_DELETE_CELLDB_INFO; 9419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("all")) flags |= GPS_DELETE_ALL; 9429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (flags != 0) { 9459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project native_delete_aiding_data(flags); 9469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 9479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 9509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 95203ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood private void startNavigating(boolean singleShot) { 9539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mStarted) { 95429c84340a14e70419449628ab193d11b7a609e9aMike Lockwood if (DEBUG) Log.d(TAG, "startNavigating"); 9559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStarted = true; 95603ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood mSingleShot = singleShot; 95703ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood mPositionMode = GPS_POSITION_MODE_STANDALONE; 95803ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood 95903ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood if (Settings.Secure.getInt(mContext.getContentResolver(), 960660bbfcc54d48d5d32e64da683c76b9c372c19b1Mike Lockwood Settings.Secure.ASSISTED_GPS_ENABLED, 1) != 0) { 96103ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood if (singleShot && hasCapability(GPS_CAPABILITY_MSA)) { 96203ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood mPositionMode = GPS_POSITION_MODE_MS_ASSISTED; 9638dc16c27e23dae5bdf65fd2a2ced97c2f645a633Mike Lockwood } else if (hasCapability(GPS_CAPABILITY_MSB)) { 96403ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood mPositionMode = GPS_POSITION_MODE_MS_BASED; 96503ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood } 966bcab8df83e6e769a7cbcc742e72b47d665998793Mike Lockwood } 967bcab8df83e6e769a7cbcc742e72b47d665998793Mike Lockwood 96804598b67a58fad93e5060bb77756ba4863013aedMike Lockwood int interval = (hasCapability(GPS_CAPABILITY_SCHEDULING) ? mFixInterval : 1000); 96904598b67a58fad93e5060bb77756ba4863013aedMike Lockwood if (!native_set_position_mode(mPositionMode, GPS_POSITION_RECURRENCE_PERIODIC, 97004598b67a58fad93e5060bb77756ba4863013aedMike Lockwood interval, 0, 0)) { 97104598b67a58fad93e5060bb77756ba4863013aedMike Lockwood mStarted = false; 97204598b67a58fad93e5060bb77756ba4863013aedMike Lockwood Log.e(TAG, "set_position_mode failed in startNavigating()"); 97304598b67a58fad93e5060bb77756ba4863013aedMike Lockwood return; 97404598b67a58fad93e5060bb77756ba4863013aedMike Lockwood } 97504598b67a58fad93e5060bb77756ba4863013aedMike Lockwood if (!native_start()) { 9769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStarted = false; 9779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.e(TAG, "native_start failed in startNavigating()"); 9780632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood return; 9799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // reset SV count to zero 98215e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood updateStatus(LocationProvider.TEMPORARILY_UNAVAILABLE, 0); 98329c84340a14e70419449628ab193d11b7a609e9aMike Lockwood mFixRequestTime = System.currentTimeMillis(); 98404598b67a58fad93e5060bb77756ba4863013aedMike Lockwood if (!hasCapability(GPS_CAPABILITY_SCHEDULING)) { 98504598b67a58fad93e5060bb77756ba4863013aedMike Lockwood // set timer to give up if we do not receive a fix within NO_FIX_TIMEOUT 98604598b67a58fad93e5060bb77756ba4863013aedMike Lockwood // and our fix interval is not short 98704598b67a58fad93e5060bb77756ba4863013aedMike Lockwood if (mFixInterval >= NO_FIX_TIMEOUT) { 98804598b67a58fad93e5060bb77756ba4863013aedMike Lockwood mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, 98904598b67a58fad93e5060bb77756ba4863013aedMike Lockwood SystemClock.elapsedRealtime() + NO_FIX_TIMEOUT, mTimeoutIntent); 99004598b67a58fad93e5060bb77756ba4863013aedMike Lockwood } 9910632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood } 9929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 99562a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood private void stopNavigating() { 99629c84340a14e70419449628ab193d11b7a609e9aMike Lockwood if (DEBUG) Log.d(TAG, "stopNavigating"); 9979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mStarted) { 9989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStarted = false; 99903ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood mSingleShot = false; 10009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project native_stop(); 10019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTTFF = 0; 10029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLastFixTime = 0; 10039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocationFlags = LOCATION_INVALID; 10049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // reset SV count to zero 100615e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood updateStatus(LocationProvider.TEMPORARILY_UNAVAILABLE, 0); 10079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10100632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood private void hibernate() { 10110632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood // stop GPS until our next fix interval arrives 10120632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood stopNavigating(); 10130632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood mAlarmManager.cancel(mTimeoutIntent); 10140632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood mAlarmManager.cancel(mWakeupIntent); 10150632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood long now = SystemClock.elapsedRealtime(); 10160632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, 101704598b67a58fad93e5060bb77756ba4863013aedMike Lockwood SystemClock.elapsedRealtime() + mFixInterval, mWakeupIntent); 101804598b67a58fad93e5060bb77756ba4863013aedMike Lockwood } 101904598b67a58fad93e5060bb77756ba4863013aedMike Lockwood 102004598b67a58fad93e5060bb77756ba4863013aedMike Lockwood private boolean hasCapability(int capability) { 102104598b67a58fad93e5060bb77756ba4863013aedMike Lockwood return ((mEngineCapabilities & capability) != 0); 10220632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood } 10230632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood 10249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 10259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * called from native code to update our position. 10269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 10279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void reportLocation(int flags, double latitude, double longitude, double altitude, 10289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float speed, float bearing, float accuracy, long timestamp) { 102929c84340a14e70419449628ab193d11b7a609e9aMike Lockwood if (VERBOSE) Log.v(TAG, "reportLocation lat: " + latitude + " long: " + longitude + 10309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project " timestamp: " + timestamp); 10319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mLocation) { 10339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocationFlags = flags; 10349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((flags & LOCATION_HAS_LAT_LONG) == LOCATION_HAS_LAT_LONG) { 10359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocation.setLatitude(latitude); 10369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocation.setLongitude(longitude); 10379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocation.setTime(timestamp); 10389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((flags & LOCATION_HAS_ALTITUDE) == LOCATION_HAS_ALTITUDE) { 10409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocation.setAltitude(altitude); 10419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 10429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocation.removeAltitude(); 10439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((flags & LOCATION_HAS_SPEED) == LOCATION_HAS_SPEED) { 10459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocation.setSpeed(speed); 10469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 10479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocation.removeSpeed(); 10489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((flags & LOCATION_HAS_BEARING) == LOCATION_HAS_BEARING) { 10509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocation.setBearing(bearing); 10519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 10529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocation.removeBearing(); 10539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((flags & LOCATION_HAS_ACCURACY) == LOCATION_HAS_ACCURACY) { 10559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocation.setAccuracy(accuracy); 10569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 10579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocation.removeAccuracy(); 10589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 106015e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood try { 1061a4903f254b4711c8fc0ac5f7e3d605f4dce34f35Mike Lockwood mLocationManager.reportLocation(mLocation, false); 106215e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } catch (RemoteException e) { 106315e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood Log.e(TAG, "RemoteException calling reportLocation"); 106415e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 10659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1067fa94ff074d3200fae2f5d14a6d0f454e2ad23cfaHakan Gustavsson mLastFixTime = System.currentTimeMillis(); 1068fa94ff074d3200fae2f5d14a6d0f454e2ad23cfaHakan Gustavsson // report time to first fix 1069fa94ff074d3200fae2f5d14a6d0f454e2ad23cfaHakan Gustavsson if (mTTFF == 0 && (flags & LOCATION_HAS_LAT_LONG) == LOCATION_HAS_LAT_LONG) { 1070fa94ff074d3200fae2f5d14a6d0f454e2ad23cfaHakan Gustavsson mTTFF = (int)(mLastFixTime - mFixRequestTime); 1071f4dffd8a45386b5a5f0e6de4f30facc9eaac4001The Android Open Source Project if (DEBUG) Log.d(TAG, "TTFF: " + mTTFF); 1072fa94ff074d3200fae2f5d14a6d0f454e2ad23cfaHakan Gustavsson 1073fa94ff074d3200fae2f5d14a6d0f454e2ad23cfaHakan Gustavsson // notify status listeners 1074fa94ff074d3200fae2f5d14a6d0f454e2ad23cfaHakan Gustavsson synchronized(mListeners) { 1075fa94ff074d3200fae2f5d14a6d0f454e2ad23cfaHakan Gustavsson int size = mListeners.size(); 1076fa94ff074d3200fae2f5d14a6d0f454e2ad23cfaHakan Gustavsson for (int i = 0; i < size; i++) { 1077fa94ff074d3200fae2f5d14a6d0f454e2ad23cfaHakan Gustavsson Listener listener = mListeners.get(i); 1078fa94ff074d3200fae2f5d14a6d0f454e2ad23cfaHakan Gustavsson try { 1079f4dffd8a45386b5a5f0e6de4f30facc9eaac4001The Android Open Source Project listener.mListener.onFirstFix(mTTFF); 1080fa94ff074d3200fae2f5d14a6d0f454e2ad23cfaHakan Gustavsson } catch (RemoteException e) { 1081fa94ff074d3200fae2f5d14a6d0f454e2ad23cfaHakan Gustavsson Log.w(TAG, "RemoteException in stopNavigating"); 1082fa94ff074d3200fae2f5d14a6d0f454e2ad23cfaHakan Gustavsson mListeners.remove(listener); 1083fa94ff074d3200fae2f5d14a6d0f454e2ad23cfaHakan Gustavsson // adjust for size of list changing 1084fa94ff074d3200fae2f5d14a6d0f454e2ad23cfaHakan Gustavsson size--; 1085fa94ff074d3200fae2f5d14a6d0f454e2ad23cfaHakan Gustavsson } 1086fa94ff074d3200fae2f5d14a6d0f454e2ad23cfaHakan Gustavsson } 1087fa94ff074d3200fae2f5d14a6d0f454e2ad23cfaHakan Gustavsson } 1088fa94ff074d3200fae2f5d14a6d0f454e2ad23cfaHakan Gustavsson } 1089fa94ff074d3200fae2f5d14a6d0f454e2ad23cfaHakan Gustavsson 109003ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood if (mSingleShot) { 109103ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood stopNavigating(); 109203ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood } 109315e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood if (mStarted && mStatus != LocationProvider.AVAILABLE) { 1094d53ba017ee2381383b4bb4d92e6e0e661431660fMike Lockwood // we want to time out if we do not receive a fix 1095b7be5447a002b4a1cf7d4030cc8a0a330cd7517cMike Lockwood // within the time out and we are requesting infrequent fixes 109604598b67a58fad93e5060bb77756ba4863013aedMike Lockwood if (!hasCapability(GPS_CAPABILITY_SCHEDULING) && mFixInterval < NO_FIX_TIMEOUT) { 1097b7be5447a002b4a1cf7d4030cc8a0a330cd7517cMike Lockwood mAlarmManager.cancel(mTimeoutIntent); 1098b7be5447a002b4a1cf7d4030cc8a0a330cd7517cMike Lockwood } 1099b7be5447a002b4a1cf7d4030cc8a0a330cd7517cMike Lockwood 11009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // send an intent to notify that the GPS is receiving fixes. 110100b74270c9f136a8727c5f6cda0997a3a905f385Mike Lockwood Intent intent = new Intent(LocationManager.GPS_FIX_CHANGE_ACTION); 110200b74270c9f136a8727c5f6cda0997a3a905f385Mike Lockwood intent.putExtra(LocationManager.EXTRA_GPS_ENABLED, true); 11039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContext.sendBroadcast(intent); 110415e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood updateStatus(LocationProvider.AVAILABLE, mSvCount); 11059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 110629c84340a14e70419449628ab193d11b7a609e9aMike Lockwood 110703ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood if (!hasCapability(GPS_CAPABILITY_SCHEDULING) && mStarted && mFixInterval > 1000) { 1108d53ba017ee2381383b4bb4d92e6e0e661431660fMike Lockwood if (DEBUG) Log.d(TAG, "got fix, hibernating"); 11090632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood hibernate(); 111029c84340a14e70419449628ab193d11b7a609e9aMike Lockwood } 11119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 11149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * called from native code to update our status 11159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 11169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void reportStatus(int status) { 1117b8d9033d9928209e68518c4b12fea74187ddb382Mike Lockwood if (DEBUG) Log.v(TAG, "reportStatus status: " + status); 11189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11192e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn synchronized(mListeners) { 11202e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn boolean wasNavigating = mNavigating; 1121dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood 1122cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood switch (status) { 1123cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood case GPS_STATUS_SESSION_BEGIN: 1124cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood mNavigating = true; 1125271f9f172b241607b1ed39a7709c3ed47ee5dee7Mike Lockwood mEngineOn = true; 1126cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood break; 1127cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood case GPS_STATUS_SESSION_END: 1128cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood mNavigating = false; 1129cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood break; 1130cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood case GPS_STATUS_ENGINE_ON: 1131cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood mEngineOn = true; 1132cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood break; 1133cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood case GPS_STATUS_ENGINE_OFF: 1134cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood mEngineOn = false; 1135271f9f172b241607b1ed39a7709c3ed47ee5dee7Mike Lockwood mNavigating = false; 1136cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood break; 1137cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood } 1138cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood 1139dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood if (wasNavigating != mNavigating) { 1140dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood int size = mListeners.size(); 1141dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood for (int i = 0; i < size; i++) { 1142dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood Listener listener = mListeners.get(i); 1143dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood try { 1144dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood if (mNavigating) { 1145dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood listener.mListener.onGpsStarted(); 1146dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood } else { 1147dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood listener.mListener.onGpsStopped(); 1148dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood } 1149dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood } catch (RemoteException e) { 1150dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood Log.w(TAG, "RemoteException in reportStatus"); 1151dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood mListeners.remove(listener); 1152dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood // adjust for size of list changing 1153dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood size--; 1154dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood } 1155dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood } 1156dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood 11572e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn try { 1158dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood // update battery stats 1159dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood for (int i=mClientUids.size() - 1; i >= 0; i--) { 1160dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood int uid = mClientUids.keyAt(i); 1161dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood if (mNavigating) { 1162dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood mBatteryStats.noteStartGps(uid); 1163dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood } else { 1164dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood mBatteryStats.noteStopGps(uid); 1165dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood } 11669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11672e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn } catch (RemoteException e) { 11682e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn Log.w(TAG, "RemoteException in reportStatus"); 11699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1171dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood // send an intent to notify that the GPS has been enabled or disabled. 117200b74270c9f136a8727c5f6cda0997a3a905f385Mike Lockwood Intent intent = new Intent(LocationManager.GPS_ENABLED_CHANGE_ACTION); 117300b74270c9f136a8727c5f6cda0997a3a905f385Mike Lockwood intent.putExtra(LocationManager.EXTRA_GPS_ENABLED, mNavigating); 1174dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood mContext.sendBroadcast(intent); 11752f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } 11769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 11809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * called from native code to update SV info 11819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 11829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void reportSvStatus() { 11839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int svCount = native_read_sv_status(mSvs, mSnrs, mSvElevations, mSvAzimuths, mSvMasks); 11859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized(mListeners) { 11879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int size = mListeners.size(); 11889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < size; i++) { 11899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Listener listener = mListeners.get(i); 11909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 11919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project listener.mListener.onSvStatusChanged(svCount, mSvs, mSnrs, 11929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSvElevations, mSvAzimuths, mSvMasks[EPHEMERIS_MASK], 11939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSvMasks[ALMANAC_MASK], mSvMasks[USED_FOR_FIX_MASK]); 11949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 11959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.w(TAG, "RemoteException in reportSvInfo"); 11969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mListeners.remove(listener); 11979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // adjust for size of list changing 11989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size--; 11999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 120329c84340a14e70419449628ab193d11b7a609e9aMike Lockwood if (VERBOSE) { 120429c84340a14e70419449628ab193d11b7a609e9aMike Lockwood Log.v(TAG, "SV count: " + svCount + 12059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project " ephemerisMask: " + Integer.toHexString(mSvMasks[EPHEMERIS_MASK]) + 12069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project " almanacMask: " + Integer.toHexString(mSvMasks[ALMANAC_MASK])); 12079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < svCount; i++) { 120829c84340a14e70419449628ab193d11b7a609e9aMike Lockwood Log.v(TAG, "sv: " + mSvs[i] + 12099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project " snr: " + (float)mSnrs[i]/10 + 12109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project " elev: " + mSvElevations[i] + 12119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project " azimuth: " + mSvAzimuths[i] + 12129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ((mSvMasks[EPHEMERIS_MASK] & (1 << (mSvs[i] - 1))) == 0 ? " " : " E") + 12139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ((mSvMasks[ALMANAC_MASK] & (1 << (mSvs[i] - 1))) == 0 ? " " : " A") + 12149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ((mSvMasks[USED_FOR_FIX_MASK] & (1 << (mSvs[i] - 1))) == 0 ? "" : "U")); 12159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12180881f4f9339febee85c9ab4cba69970ac5cbde55Kevin.KY Tsai // return number of sets used in fix instead of total 12190881f4f9339febee85c9ab4cba69970ac5cbde55Kevin.KY Tsai updateStatus(mStatus, Integer.bitCount(mSvMasks[USED_FOR_FIX_MASK])); 12209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 122115e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood if (mNavigating && mStatus == LocationProvider.AVAILABLE && mLastFixTime > 0 && 122204598b67a58fad93e5060bb77756ba4863013aedMike Lockwood System.currentTimeMillis() - mLastFixTime > RECENT_FIX_TIMEOUT) { 12239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // send an intent to notify that the GPS is no longer receiving fixes. 122400b74270c9f136a8727c5f6cda0997a3a905f385Mike Lockwood Intent intent = new Intent(LocationManager.GPS_FIX_CHANGE_ACTION); 122500b74270c9f136a8727c5f6cda0997a3a905f385Mike Lockwood intent.putExtra(LocationManager.EXTRA_GPS_ENABLED, false); 12269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContext.sendBroadcast(intent); 122715e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood updateStatus(LocationProvider.TEMPORARILY_UNAVAILABLE, mSvCount); 12289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 123058bda987665af759c379cd494ff4873ac61acf29Mike Lockwood 123158bda987665af759c379cd494ff4873ac61acf29Mike Lockwood /** 1232e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood * called from native code to update AGPS status 123358bda987665af759c379cd494ff4873ac61acf29Mike Lockwood */ 1234e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood private void reportAGpsStatus(int type, int status) { 123558bda987665af759c379cd494ff4873ac61acf29Mike Lockwood switch (status) { 1236e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood case GPS_REQUEST_AGPS_DATA_CONN: 1237b6e5fa895c03eeefaa810eaceb498254096c093dMike Lockwood if (DEBUG) Log.d(TAG, "GPS_REQUEST_AGPS_DATA_CONN"); 12382acfd34ccbd39258422333c9c66c586297c97683Mike Lockwood // Set mAGpsDataConnectionState before calling startUsingNetworkFeature 12392acfd34ccbd39258422333c9c66c586297c97683Mike Lockwood // to avoid a race condition with handleUpdateNetworkState() 12402acfd34ccbd39258422333c9c66c586297c97683Mike Lockwood mAGpsDataConnectionState = AGPS_DATA_CONNECTION_OPENING; 12412acfd34ccbd39258422333c9c66c586297c97683Mike Lockwood int result = mConnMgr.startUsingNetworkFeature( 124258bda987665af759c379cd494ff4873ac61acf29Mike Lockwood ConnectivityManager.TYPE_MOBILE, Phone.FEATURE_ENABLE_SUPL); 124358bda987665af759c379cd494ff4873ac61acf29Mike Lockwood if (result == Phone.APN_ALREADY_ACTIVE) { 12442d4d1bf14b531de9d4238b1e41b53c77f8976405Mike Lockwood if (DEBUG) Log.d(TAG, "Phone.APN_ALREADY_ACTIVE"); 1245b362a9ab91bb4c05ef1d5c4e7019499257c7f849Mike Lockwood if (mAGpsApn != null) { 1246b362a9ab91bb4c05ef1d5c4e7019499257c7f849Mike Lockwood native_agps_data_conn_open(mAGpsApn); 1247b362a9ab91bb4c05ef1d5c4e7019499257c7f849Mike Lockwood mAGpsDataConnectionState = AGPS_DATA_CONNECTION_OPEN; 1248b362a9ab91bb4c05ef1d5c4e7019499257c7f849Mike Lockwood } else { 1249b362a9ab91bb4c05ef1d5c4e7019499257c7f849Mike Lockwood Log.e(TAG, "mAGpsApn not set when receiving Phone.APN_ALREADY_ACTIVE"); 12502acfd34ccbd39258422333c9c66c586297c97683Mike Lockwood mAGpsDataConnectionState = AGPS_DATA_CONNECTION_CLOSED; 1251b362a9ab91bb4c05ef1d5c4e7019499257c7f849Mike Lockwood native_agps_data_conn_failed(); 1252b362a9ab91bb4c05ef1d5c4e7019499257c7f849Mike Lockwood } 125358bda987665af759c379cd494ff4873ac61acf29Mike Lockwood } else if (result == Phone.APN_REQUEST_STARTED) { 12544a7b65e0d544ef1feff8e1e5789f469f89ebb85cMike Lockwood if (DEBUG) Log.d(TAG, "Phone.APN_REQUEST_STARTED"); 12552acfd34ccbd39258422333c9c66c586297c97683Mike Lockwood // Nothing to do here 125658bda987665af759c379cd494ff4873ac61acf29Mike Lockwood } else { 1257b8d9033d9928209e68518c4b12fea74187ddb382Mike Lockwood if (DEBUG) Log.d(TAG, "startUsingNetworkFeature failed"); 12582acfd34ccbd39258422333c9c66c586297c97683Mike Lockwood mAGpsDataConnectionState = AGPS_DATA_CONNECTION_CLOSED; 1259e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood native_agps_data_conn_failed(); 126058bda987665af759c379cd494ff4873ac61acf29Mike Lockwood } 126158bda987665af759c379cd494ff4873ac61acf29Mike Lockwood break; 1262e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood case GPS_RELEASE_AGPS_DATA_CONN: 1263b6e5fa895c03eeefaa810eaceb498254096c093dMike Lockwood if (DEBUG) Log.d(TAG, "GPS_RELEASE_AGPS_DATA_CONN"); 1264e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood if (mAGpsDataConnectionState != AGPS_DATA_CONNECTION_CLOSED) { 126558bda987665af759c379cd494ff4873ac61acf29Mike Lockwood mConnMgr.stopUsingNetworkFeature( 126658bda987665af759c379cd494ff4873ac61acf29Mike Lockwood ConnectivityManager.TYPE_MOBILE, Phone.FEATURE_ENABLE_SUPL); 1267e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood native_agps_data_conn_closed(); 1268e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood mAGpsDataConnectionState = AGPS_DATA_CONNECTION_CLOSED; 126958bda987665af759c379cd494ff4873ac61acf29Mike Lockwood } 127058bda987665af759c379cd494ff4873ac61acf29Mike Lockwood break; 1271e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood case GPS_AGPS_DATA_CONNECTED: 1272b6e5fa895c03eeefaa810eaceb498254096c093dMike Lockwood if (DEBUG) Log.d(TAG, "GPS_AGPS_DATA_CONNECTED"); 127358bda987665af759c379cd494ff4873ac61acf29Mike Lockwood break; 1274e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood case GPS_AGPS_DATA_CONN_DONE: 1275b6e5fa895c03eeefaa810eaceb498254096c093dMike Lockwood if (DEBUG) Log.d(TAG, "GPS_AGPS_DATA_CONN_DONE"); 127658bda987665af759c379cd494ff4873ac61acf29Mike Lockwood break; 1277e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood case GPS_AGPS_DATA_CONN_FAILED: 1278b6e5fa895c03eeefaa810eaceb498254096c093dMike Lockwood if (DEBUG) Log.d(TAG, "GPS_AGPS_DATA_CONN_FAILED"); 127958bda987665af759c379cd494ff4873ac61acf29Mike Lockwood break; 128058bda987665af759c379cd494ff4873ac61acf29Mike Lockwood } 128158bda987665af759c379cd494ff4873ac61acf29Mike Lockwood } 128258bda987665af759c379cd494ff4873ac61acf29Mike Lockwood 1283b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood /** 1284b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood * called from native code to report NMEA data received 1285b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood */ 1286f602d362ba4bb3adbf1eb4e38a794fb14274293aMike Lockwood private void reportNmea(long timestamp) { 1287b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood synchronized(mListeners) { 1288b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood int size = mListeners.size(); 1289b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood if (size > 0) { 1290b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood // don't bother creating the String if we have no listeners 1291f602d362ba4bb3adbf1eb4e38a794fb14274293aMike Lockwood int length = native_read_nmea(mNmeaBuffer, mNmeaBuffer.length); 1292b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood String nmea = new String(mNmeaBuffer, 0, length); 1293b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood 1294b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood for (int i = 0; i < size; i++) { 1295b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood Listener listener = mListeners.get(i); 1296b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood try { 1297b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood listener.mListener.onNmeaReceived(timestamp, nmea); 1298b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood } catch (RemoteException e) { 1299b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood Log.w(TAG, "RemoteException in reportNmea"); 1300b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood mListeners.remove(listener); 1301b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood // adjust for size of list changing 1302b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood size--; 1303b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood } 1304b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood } 1305b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood } 1306b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood } 1307b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood } 1308b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood 130962a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood /** 131004598b67a58fad93e5060bb77756ba4863013aedMike Lockwood * called from native code to inform us what the GPS engine capabilities are 131104598b67a58fad93e5060bb77756ba4863013aedMike Lockwood */ 131204598b67a58fad93e5060bb77756ba4863013aedMike Lockwood private void setEngineCapabilities(int capabilities) { 131304598b67a58fad93e5060bb77756ba4863013aedMike Lockwood mEngineCapabilities = capabilities; 13149b9fb5cc08eaa0b66a80eba2f03168531544f65aMike Lockwood 13159b9fb5cc08eaa0b66a80eba2f03168531544f65aMike Lockwood if (!hasCapability(GPS_CAPABILITY_ON_DEMAND_TIME) && !mPeriodicTimeInjection) { 13169b9fb5cc08eaa0b66a80eba2f03168531544f65aMike Lockwood mPeriodicTimeInjection = true; 13179b9fb5cc08eaa0b66a80eba2f03168531544f65aMike Lockwood requestUtcTime(); 13189b9fb5cc08eaa0b66a80eba2f03168531544f65aMike Lockwood } 131904598b67a58fad93e5060bb77756ba4863013aedMike Lockwood } 132004598b67a58fad93e5060bb77756ba4863013aedMike Lockwood 132104598b67a58fad93e5060bb77756ba4863013aedMike Lockwood /** 132262a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood * called from native code to request XTRA data 132362a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood */ 13249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void xtraDownloadRequest() { 1325f5d95cbc1a6974afeb4d3155bdaa8dae55722a39Joe Onorato if (DEBUG) Log.d(TAG, "xtraDownloadRequest"); 132698e48691f738680fe59e7383a41458e7337daccdMike Lockwood sendMessage(DOWNLOAD_XTRA_DATA, 0, null); 13279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 132922d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie //============================================================= 133022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie // NI Client support 13311e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja //============================================================= 133222d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie private final INetInitiatedListener mNetInitiatedListener = new INetInitiatedListener.Stub() { 13331e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja // Sends a response for an NI reqeust to HAL. 13341e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja public boolean sendNiResponse(int notificationId, int userResponse) 13351e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja { 13361e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja // TODO Add Permission check 13371e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja 13381e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja StringBuilder extrasBuf = new StringBuilder(); 13391e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja 13401e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja if (DEBUG) Log.d(TAG, "sendNiResponse, notifId: " + notificationId + 13411e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja ", response: " + userResponse); 13421e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja native_send_ni_response(notificationId, userResponse); 13431e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja return true; 13441e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja } 134522d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie }; 134622d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie 134722d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie public INetInitiatedListener getNetInitiatedListener() { 134822d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie return mNetInitiatedListener; 134922d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie } 135022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie 135122d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie // Called by JNI function to report an NI request. 13521e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja public void reportNiNotification( 13531e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja int notificationId, 13541e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja int niType, 13551e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja int notifyFlags, 13561e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja int timeout, 13571e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja int defaultResponse, 13581e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja String requestorId, 13591e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja String text, 13601e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja int requestorIdEncoding, 13611e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja int textEncoding, 13621e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja String extras // Encoded extra data 136322d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie ) 13641e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja { 13651e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja Log.i(TAG, "reportNiNotification: entered"); 13661e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja Log.i(TAG, "notificationId: " + notificationId + 13671e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja ", niType: " + niType + 13681e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja ", notifyFlags: " + notifyFlags + 13691e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja ", timeout: " + timeout + 13701e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja ", defaultResponse: " + defaultResponse); 13711e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja 13721e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja Log.i(TAG, "requestorId: " + requestorId + 13731e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja ", text: " + text + 13741e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja ", requestorIdEncoding: " + requestorIdEncoding + 13751e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja ", textEncoding: " + textEncoding); 13761e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja 13771e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja GpsNiNotification notification = new GpsNiNotification(); 13781e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja 13791e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja notification.notificationId = notificationId; 13801e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja notification.niType = niType; 13811e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja notification.needNotify = (notifyFlags & GpsNetInitiatedHandler.GPS_NI_NEED_NOTIFY) != 0; 13821e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja notification.needVerify = (notifyFlags & GpsNetInitiatedHandler.GPS_NI_NEED_VERIFY) != 0; 13831e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja notification.privacyOverride = (notifyFlags & GpsNetInitiatedHandler.GPS_NI_PRIVACY_OVERRIDE) != 0; 13841e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja notification.timeout = timeout; 13851e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja notification.defaultResponse = defaultResponse; 13861e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja notification.requestorId = requestorId; 13871e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja notification.text = text; 13881e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja notification.requestorIdEncoding = requestorIdEncoding; 13891e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja notification.textEncoding = textEncoding; 13901e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja 13911e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja // Process extras, assuming the format is 13921e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja // one of more lines of "key = value" 13931e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja Bundle bundle = new Bundle(); 13941e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja 13951e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja if (extras == null) extras = ""; 13961e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja Properties extraProp = new Properties(); 13971e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja 13981e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja try { 1399104344e507610be42fb70c7deda3c422c543bfcbJeff Sharkey extraProp.load(new StringReader(extras)); 14001e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja } 14011e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja catch (IOException e) 14021e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja { 14031e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja Log.e(TAG, "reportNiNotification cannot parse extras data: " + extras); 14041e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja } 14051e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja 14061e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja for (Entry<Object, Object> ent : extraProp.entrySet()) 14071e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja { 14081e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja bundle.putString((String) ent.getKey(), (String) ent.getValue()); 14091e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja } 14101e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja 14111e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja notification.extras = bundle; 14121e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja 14131e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja mNIHandler.handleNiNotification(notification); 14141e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja } 14151e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja 14161e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja /** 14171e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja * Called from native code to request set id info. 14181e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja * We should be careful about receiving null string from the TelephonyManager, 14191e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja * because sending null String to JNI function would cause a crash. 14201e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja */ 14211e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja 14221e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja private void requestSetID(int flags) { 14231e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja TelephonyManager phone = (TelephonyManager) 14241e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja mContext.getSystemService(Context.TELEPHONY_SERVICE); 14251e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja int type = AGPS_SETID_TYPE_NONE; 14261e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja String data = ""; 14271e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja 14281e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja if ((flags & AGPS_RIL_REQUEST_SETID_IMSI) == AGPS_RIL_REQUEST_SETID_IMSI) { 14291e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja String data_temp = phone.getSubscriberId(); 14301e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja if (data_temp == null) { 14311e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja // This means the framework does not have the SIM card ready. 14321e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja } else { 14331e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja // This means the framework has the SIM card. 14341e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja data = data_temp; 14351e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja type = AGPS_SETID_TYPE_IMSI; 14361e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja } 14371e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja } 14381e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja else if ((flags & AGPS_RIL_REQUEST_SETID_MSISDN) == AGPS_RIL_REQUEST_SETID_MSISDN) { 14391e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja String data_temp = phone.getLine1Number(); 14401e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja if (data_temp == null) { 14411e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja // This means the framework does not have the SIM card ready. 14421e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja } else { 14431e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja // This means the framework has the SIM card. 14441e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja data = data_temp; 14451e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja type = AGPS_SETID_TYPE_MSISDN; 14461e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja } 14471e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja } 14481e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja native_agps_set_id(type, data); 14491e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja } 14501e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja 14511e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja /** 14529b9fb5cc08eaa0b66a80eba2f03168531544f65aMike Lockwood * Called from native code to request utc time info 14539b9fb5cc08eaa0b66a80eba2f03168531544f65aMike Lockwood */ 14549b9fb5cc08eaa0b66a80eba2f03168531544f65aMike Lockwood 14559b9fb5cc08eaa0b66a80eba2f03168531544f65aMike Lockwood private void requestUtcTime() { 14569b9fb5cc08eaa0b66a80eba2f03168531544f65aMike Lockwood sendMessage(INJECT_NTP_TIME, 0, null); 14579b9fb5cc08eaa0b66a80eba2f03168531544f65aMike Lockwood } 14589b9fb5cc08eaa0b66a80eba2f03168531544f65aMike Lockwood 14599b9fb5cc08eaa0b66a80eba2f03168531544f65aMike Lockwood /** 14601e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja * Called from native code to request reference location info 14611e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja */ 14621e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja 14631e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja private void requestRefLocation(int flags) { 14641e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja TelephonyManager phone = (TelephonyManager) 14651e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja mContext.getSystemService(Context.TELEPHONY_SERVICE); 14661e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja if (phone.getPhoneType() == TelephonyManager.PHONE_TYPE_GSM) { 14671e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja GsmCellLocation gsm_cell = (GsmCellLocation) phone.getCellLocation(); 1468edc0f3876ce6e14f0ce35ad950c55031694fd4f8Mike Lockwood if ((gsm_cell != null) && (phone.getPhoneType() == TelephonyManager.PHONE_TYPE_GSM) && 1469edc0f3876ce6e14f0ce35ad950c55031694fd4f8Mike Lockwood (phone.getNetworkOperator() != null) && 1470edc0f3876ce6e14f0ce35ad950c55031694fd4f8Mike Lockwood (phone.getNetworkOperator().length() > 3)) { 14711e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja int type; 14721e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja int mcc = Integer.parseInt(phone.getNetworkOperator().substring(0,3)); 14731e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja int mnc = Integer.parseInt(phone.getNetworkOperator().substring(3)); 1474edc0f3876ce6e14f0ce35ad950c55031694fd4f8Mike Lockwood int networkType = phone.getNetworkType(); 1475edc0f3876ce6e14f0ce35ad950c55031694fd4f8Mike Lockwood if (networkType == TelephonyManager.NETWORK_TYPE_UMTS 1476edc0f3876ce6e14f0ce35ad950c55031694fd4f8Mike Lockwood || networkType == TelephonyManager.NETWORK_TYPE_HSDPA 1477edc0f3876ce6e14f0ce35ad950c55031694fd4f8Mike Lockwood || networkType == TelephonyManager.NETWORK_TYPE_HSUPA 1478edc0f3876ce6e14f0ce35ad950c55031694fd4f8Mike Lockwood || networkType == TelephonyManager.NETWORK_TYPE_HSPA) { 14791e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja type = AGPS_REF_LOCATION_TYPE_UMTS_CELLID; 1480edc0f3876ce6e14f0ce35ad950c55031694fd4f8Mike Lockwood } else { 14811e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja type = AGPS_REF_LOCATION_TYPE_GSM_CELLID; 1482edc0f3876ce6e14f0ce35ad950c55031694fd4f8Mike Lockwood } 14831e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja native_agps_set_ref_location_cellid(type, mcc, mnc, 14841e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja gsm_cell.getLac(), gsm_cell.getCid()); 1485edc0f3876ce6e14f0ce35ad950c55031694fd4f8Mike Lockwood } else { 14861e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja Log.e(TAG,"Error getting cell location info."); 1487edc0f3876ce6e14f0ce35ad950c55031694fd4f8Mike Lockwood } 14881e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja } 1489edc0f3876ce6e14f0ce35ad950c55031694fd4f8Mike Lockwood else { 14901e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja Log.e(TAG,"CDMA not supported."); 1491edc0f3876ce6e14f0ce35ad950c55031694fd4f8Mike Lockwood } 14921e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja } 149322d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie 149498e48691f738680fe59e7383a41458e7337daccdMike Lockwood private void sendMessage(int message, int arg, Object obj) { 149598e48691f738680fe59e7383a41458e7337daccdMike Lockwood // hold a wake lock while messages are pending 149698e48691f738680fe59e7383a41458e7337daccdMike Lockwood synchronized (mWakeLock) { 149798e48691f738680fe59e7383a41458e7337daccdMike Lockwood mPendingMessageBits |= (1 << message); 149898e48691f738680fe59e7383a41458e7337daccdMike Lockwood mWakeLock.acquire(); 149998e48691f738680fe59e7383a41458e7337daccdMike Lockwood mHandler.removeMessages(message); 150098e48691f738680fe59e7383a41458e7337daccdMike Lockwood Message m = Message.obtain(mHandler, message); 150198e48691f738680fe59e7383a41458e7337daccdMike Lockwood m.arg1 = arg; 150298e48691f738680fe59e7383a41458e7337daccdMike Lockwood m.obj = obj; 150398e48691f738680fe59e7383a41458e7337daccdMike Lockwood mHandler.sendMessage(m); 150498e48691f738680fe59e7383a41458e7337daccdMike Lockwood } 150598e48691f738680fe59e7383a41458e7337daccdMike Lockwood } 150698e48691f738680fe59e7383a41458e7337daccdMike Lockwood 150762a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood private final class ProviderHandler extends Handler { 150862a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood @Override 15094a7b65e0d544ef1feff8e1e5789f469f89ebb85cMike Lockwood public void handleMessage(Message msg) { 151098e48691f738680fe59e7383a41458e7337daccdMike Lockwood int message = msg.what; 151198e48691f738680fe59e7383a41458e7337daccdMike Lockwood switch (message) { 151262a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood case ENABLE: 151362a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood if (msg.arg1 == 1) { 151462a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood handleEnable(); 151562a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood } else { 151662a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood handleDisable(); 15179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 151862a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood break; 151962a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood case ENABLE_TRACKING: 152062a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood handleEnableLocationTracking(msg.arg1 == 1); 152162a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood break; 152203ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood case REQUEST_SINGLE_SHOT: 152303ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood handleRequestSingleShot(); 152403ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood break; 152562a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood case UPDATE_NETWORK_STATE: 152662a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood handleUpdateNetworkState(msg.arg1, (NetworkInfo)msg.obj); 152762a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood break; 152862a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood case INJECT_NTP_TIME: 152962a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood handleInjectNtpTime(); 153062a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood break; 153162a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood case DOWNLOAD_XTRA_DATA: 15321a1cd3a878b6389c097e34d114b60cf953edaeaaMike Lockwood if (mSupportsXtra) { 153362a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood handleDownloadXtraData(); 15349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 153562a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood break; 153662a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood case UPDATE_LOCATION: 153762a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood handleUpdateLocation((Location)msg.obj); 153862a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood break; 153962a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood case ADD_LISTENER: 154062a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood handleAddListener(msg.arg1); 154162a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood break; 154262a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood case REMOVE_LISTENER: 154362a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood handleRemoveListener(msg.arg1); 154462a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood break; 15459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 154698e48691f738680fe59e7383a41458e7337daccdMike Lockwood // release wake lock if no messages are pending 154798e48691f738680fe59e7383a41458e7337daccdMike Lockwood synchronized (mWakeLock) { 154898e48691f738680fe59e7383a41458e7337daccdMike Lockwood mPendingMessageBits &= ~(1 << message); 154998e48691f738680fe59e7383a41458e7337daccdMike Lockwood if (message == ADD_LISTENER || message == REMOVE_LISTENER) { 155098e48691f738680fe59e7383a41458e7337daccdMike Lockwood mPendingListenerMessages--; 155198e48691f738680fe59e7383a41458e7337daccdMike Lockwood } 155298e48691f738680fe59e7383a41458e7337daccdMike Lockwood if (mPendingMessageBits == 0 && mPendingListenerMessages == 0) { 155398e48691f738680fe59e7383a41458e7337daccdMike Lockwood mWakeLock.release(); 155498e48691f738680fe59e7383a41458e7337daccdMike Lockwood } 155598e48691f738680fe59e7383a41458e7337daccdMike Lockwood } 15569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 155762a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood }; 15589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 155989096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood private final class GpsLocationProviderThread extends Thread { 156089096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood 156189096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood public GpsLocationProviderThread() { 156289096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood super("GpsLocationProvider"); 156389096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood } 156489096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood 156589096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood public void run() { 156689096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 156789096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood initialize(); 156889096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood Looper.prepare(); 156989096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood mHandler = new ProviderHandler(); 157089096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood // signal when we are initialized and ready to go 157189096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood mInitializedLatch.countDown(); 157289096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood Looper.loop(); 157389096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood } 15749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 15759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // for GPS SV statistics 15779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int MAX_SVS = 32; 15789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int EPHEMERIS_MASK = 0; 15799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int ALMANAC_MASK = 1; 15809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int USED_FOR_FIX_MASK = 2; 15819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // preallocated arrays, to avoid memory allocation in reportStatus() 15839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mSvs[] = new int[MAX_SVS]; 15849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private float mSnrs[] = new float[MAX_SVS]; 15859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private float mSvElevations[] = new float[MAX_SVS]; 15869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private float mSvAzimuths[] = new float[MAX_SVS]; 15879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mSvMasks[] = new int[3]; 15889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mSvCount; 1589b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood // preallocated to avoid memory allocation in reportNmea() 1590b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood private byte[] mNmeaBuffer = new byte[120]; 15919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static { class_init_native(); } 15939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static native void class_init_native(); 15949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static native boolean native_is_supported(); 15959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 15969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native boolean native_init(); 15979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native void native_cleanup(); 159804598b67a58fad93e5060bb77756ba4863013aedMike Lockwood private native boolean native_set_position_mode(int mode, int recurrence, int min_interval, 159904598b67a58fad93e5060bb77756ba4863013aedMike Lockwood int preferred_accuracy, int preferred_time); 160004598b67a58fad93e5060bb77756ba4863013aedMike Lockwood private native boolean native_start(); 16019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native boolean native_stop(); 16029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native void native_delete_aiding_data(int flags); 16039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // returns number of SVs 16049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // mask[0] is ephemeris mask and mask[1] is almanac mask 16059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native int native_read_sv_status(int[] svs, float[] snrs, 16069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float[] elevations, float[] azimuths, int[] masks); 1607f602d362ba4bb3adbf1eb4e38a794fb14274293aMike Lockwood private native int native_read_nmea(byte[] buffer, int bufferSize); 1608d26ce0d903f5141a346d67b2b94437ef3e2880aaMike Lockwood private native void native_inject_location(double latitude, double longitude, float accuracy); 1609d26ce0d903f5141a346d67b2b94437ef3e2880aaMike Lockwood 16103c8fbdf5dd19fad0b3006557716ee1026d7d5899Fred Fettinger // XTRA Support 16119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native void native_inject_time(long time, long timeReference, int uncertainty); 16129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native boolean native_supports_xtra(); 16139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native void native_inject_xtra_data(byte[] data, int length); 1614105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project 16153c8fbdf5dd19fad0b3006557716ee1026d7d5899Fred Fettinger // DEBUG Support 16163c8fbdf5dd19fad0b3006557716ee1026d7d5899Fred Fettinger private native String native_get_internal_state(); 16173c8fbdf5dd19fad0b3006557716ee1026d7d5899Fred Fettinger 16183c8fbdf5dd19fad0b3006557716ee1026d7d5899Fred Fettinger // AGPS Support 1619e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood private native void native_agps_data_conn_open(String apn); 1620e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood private native void native_agps_data_conn_closed(); 1621e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood private native void native_agps_data_conn_failed(); 16221e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja private native void native_agps_ni_message(byte [] msg, int length); 1623a9e546169b3c2c9c5f248d2f3abe3b934f48695dMike Lockwood private native void native_set_agps_server(int type, String hostname, int port); 162422d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie 162522d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie // Network-initiated (NI) Support 162622d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie private native void native_send_ni_response(int notificationId, int userResponse); 16271e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja 16281e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja // AGPS ril suport 16291e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja private native void native_agps_set_ref_location_cellid(int type, int mcc, int mnc, 16301e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja int lac, int cid); 16311e84da822e7aa4d494b31c8759917d2751611f84Miguel Torroja private native void native_agps_set_id(int type, String setid); 163250130bbc884a7ad7db39dbc4f54e76e8be87761fMike Lockwood 163350130bbc884a7ad7db39dbc4f54e76e8be87761fMike Lockwood private native void native_update_network_state(boolean connected, int type, 163450130bbc884a7ad7db39dbc4f54e76e8be87761fMike Lockwood boolean roaming, String extraInfo); 16359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1636