GpsLocationProvider.java revision 2acfd34ccbd39258422333c9c66c586297c97683
19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License. 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1700b74270c9f136a8727c5f6cda0997a3a905f385Mike Lockwoodpackage com.android.server.location; 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1929c84340a14e70419449628ab193d11b7a609e9aMike Lockwoodimport android.app.AlarmManager; 2029c84340a14e70419449628ab193d11b7a609e9aMike Lockwoodimport android.app.PendingIntent; 21105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Projectimport android.content.BroadcastReceiver; 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Context; 239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.content.Intent; 24105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Projectimport android.content.IntentFilter; 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.location.Criteria; 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.location.IGpsStatusListener; 2715e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwoodimport android.location.IGpsStatusProvider; 284e50b78bda9cd58be61581d2886c88ff6348a1c1Mike Lockwoodimport android.location.ILocationManager; 2922d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xieimport android.location.INetInitiatedListener; 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.location.Location; 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.location.LocationManager; 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.location.LocationProvider; 3358bda987665af759c379cd494ff4873ac61acf29Mike Lockwoodimport android.net.ConnectivityManager; 3403d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwoodimport android.net.NetworkInfo; 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.net.SntpClient; 3663aa5a6f98b1016863e4f6edd87eb471b28dc28fMike Lockwoodimport android.os.Binder; 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Bundle; 3862a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwoodimport android.os.Handler; 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.IBinder; 4062a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwoodimport android.os.Looper; 4162a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwoodimport android.os.Message; 420528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwoodimport android.os.PowerManager; 4362a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwoodimport android.os.Process; 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.RemoteException; 452f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwoodimport android.os.ServiceManager; 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.SystemClock; 477e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackbornimport android.os.WorkSource; 48bcab8df83e6e769a7cbcc742e72b47d665998793Mike Lockwoodimport android.provider.Settings; 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Log; 502f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwoodimport android.util.SparseIntArray; 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 522f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwoodimport com.android.internal.app.IBatteryStats; 53105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Projectimport com.android.internal.telephony.Phone; 5422d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xieimport com.android.internal.location.GpsNetInitiatedHandler; 5522d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xieimport com.android.internal.location.GpsNetInitiatedHandler.GpsNiNotification; 56105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.File; 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.FileInputStream; 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.IOException; 6022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xieimport java.io.StringBufferInputStream; 61105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Projectimport java.net.InetAddress; 62105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Projectimport java.net.UnknownHostException; 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.ArrayList; 64f1218be2d8f68f3f445f3bc90e0eca01946a0ddfMike Lockwoodimport java.util.Date; 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.Properties; 6622d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xieimport java.util.Map.Entry; 6789096317104722219f73a5c3cc424e6e98c90a61Mike Lockwoodimport java.util.concurrent.CountDownLatch; 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * A GPS implementation of LocationProvider used by LocationManager. 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@hide} 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7489096317104722219f73a5c3cc424e6e98c90a61Mike Lockwoodpublic class GpsLocationProvider implements LocationProviderInterface { 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final String TAG = "GpsLocationProvider"; 7729c84340a14e70419449628ab193d11b7a609e9aMike Lockwood 78f5d95cbc1a6974afeb4d3155bdaa8dae55722a39Joe Onorato private static final boolean DEBUG = false; 7929c84340a14e70419449628ab193d11b7a609e9aMike Lockwood private static final boolean VERBOSE = false; 8062a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood 81105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project // these need to match GpsPositionMode enum in gps.h 82105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project private static final int GPS_POSITION_MODE_STANDALONE = 0; 83105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project private static final int GPS_POSITION_MODE_MS_BASED = 1; 84105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project private static final int GPS_POSITION_MODE_MS_ASSISTED = 2; 85105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project 8604598b67a58fad93e5060bb77756ba4863013aedMike Lockwood // these need to match GpsPositionRecurrence enum in gps.h 8704598b67a58fad93e5060bb77756ba4863013aedMike Lockwood private static final int GPS_POSITION_RECURRENCE_PERIODIC = 0; 8804598b67a58fad93e5060bb77756ba4863013aedMike Lockwood private static final int GPS_POSITION_RECURRENCE_SINGLE = 1; 8904598b67a58fad93e5060bb77756ba4863013aedMike Lockwood 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // these need to match GpsStatusValue defines in gps.h 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_STATUS_NONE = 0; 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_STATUS_SESSION_BEGIN = 1; 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_STATUS_SESSION_END = 2; 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_STATUS_ENGINE_ON = 3; 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_STATUS_ENGINE_OFF = 4; 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 97e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood // these need to match GpsApgsStatusValue defines in gps.h 98e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood /** AGPS status event values. */ 99e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood private static final int GPS_REQUEST_AGPS_DATA_CONN = 1; 100e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood private static final int GPS_RELEASE_AGPS_DATA_CONN = 2; 101e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood private static final int GPS_AGPS_DATA_CONNECTED = 3; 102e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood private static final int GPS_AGPS_DATA_CONN_DONE = 4; 103e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood private static final int GPS_AGPS_DATA_CONN_FAILED = 5; 10458bda987665af759c379cd494ff4873ac61acf29Mike Lockwood 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // these need to match GpsLocationFlags enum in gps.h 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int LOCATION_INVALID = 0; 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int LOCATION_HAS_LAT_LONG = 1; 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int LOCATION_HAS_ALTITUDE = 2; 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int LOCATION_HAS_SPEED = 4; 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int LOCATION_HAS_BEARING = 8; 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int LOCATION_HAS_ACCURACY = 16; 112e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood 113e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood// IMPORTANT - the GPS_DELETE_* symbols here must match constants in gps.h 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_DELETE_EPHEMERIS = 0x0001; 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_DELETE_ALMANAC = 0x0002; 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_DELETE_POSITION = 0x0004; 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_DELETE_TIME = 0x0008; 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_DELETE_IONO = 0x0010; 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_DELETE_UTC = 0x0020; 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_DELETE_HEALTH = 0x0040; 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_DELETE_SVDIR = 0x0080; 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_DELETE_SVSTEER = 0x0100; 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_DELETE_SADATA = 0x0200; 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_DELETE_RTI = 0x0400; 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_DELETE_CELLDB_INFO = 0x8000; 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_DELETE_ALL = 0xFFFF; 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12804598b67a58fad93e5060bb77756ba4863013aedMike Lockwood // The GPS_CAPABILITY_* flags must match the values in gps.h 12904598b67a58fad93e5060bb77756ba4863013aedMike Lockwood private static final int GPS_CAPABILITY_SCHEDULING = 0x0000001; 13004598b67a58fad93e5060bb77756ba4863013aedMike Lockwood private static final int GPS_CAPABILITY_MSB = 0x0000002; 13104598b67a58fad93e5060bb77756ba4863013aedMike Lockwood private static final int GPS_CAPABILITY_MSA = 0x0000004; 13204598b67a58fad93e5060bb77756ba4863013aedMike Lockwood private static final int GPS_CAPABILITY_SINGLE_SHOT = 0x0000008; 13304598b67a58fad93e5060bb77756ba4863013aedMike Lockwood 13404598b67a58fad93e5060bb77756ba4863013aedMike Lockwood 135e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood // these need to match AGpsType enum in gps.h 136e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood private static final int AGPS_TYPE_SUPL = 1; 137e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood private static final int AGPS_TYPE_C2K = 2; 138e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood 139e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood // for mAGpsDataConnectionState 140e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood private static final int AGPS_DATA_CONNECTION_CLOSED = 0; 141e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood private static final int AGPS_DATA_CONNECTION_OPENING = 1; 142e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood private static final int AGPS_DATA_CONNECTION_OPEN = 2; 14358bda987665af759c379cd494ff4873ac61acf29Mike Lockwood 14462a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood // Handler messages 14562a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood private static final int CHECK_LOCATION = 1; 14662a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood private static final int ENABLE = 2; 14762a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood private static final int ENABLE_TRACKING = 3; 14862a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood private static final int UPDATE_NETWORK_STATE = 4; 14962a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood private static final int INJECT_NTP_TIME = 5; 15062a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood private static final int DOWNLOAD_XTRA_DATA = 6; 15162a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood private static final int UPDATE_LOCATION = 7; 15262a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood private static final int ADD_LISTENER = 8; 15362a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood private static final int REMOVE_LISTENER = 9; 15403ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood private static final int REQUEST_SINGLE_SHOT = 10; 15562a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood 1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final String PROPERTIES_FILE = "/etc/gps.conf"; 1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mLocationFlags = LOCATION_INVALID; 1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // current status 16115e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood private int mStatus = LocationProvider.TEMPORARILY_UNAVAILABLE; 1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // time for last status update 1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private long mStatusUpdateTime = SystemClock.elapsedRealtime(); 165d53ba017ee2381383b4bb4d92e6e0e661431660fMike Lockwood 1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // turn off GPS fix icon if we haven't received a fix in 10 seconds 16704598b67a58fad93e5060bb77756ba4863013aedMike Lockwood private static final long RECENT_FIX_TIMEOUT = 10 * 1000; 1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1690632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood // stop trying if we do not receive a fix within 60 seconds 17004598b67a58fad93e5060bb77756ba4863013aedMike Lockwood private static final int NO_FIX_TIMEOUT = 60 * 1000; 1710632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood 1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // true if we are enabled 17389096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood private volatile boolean mEnabled; 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // true if we have network connectivity 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mNetworkAvailable; 1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 17862a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood // flags to trigger NTP or XTRA data download when network becomes available 17962a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood // initialized to true so we do NTP and XTRA when the network comes up after booting 18062a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood private boolean mInjectNtpTimePending = true; 1815723dfe8c87d0887b8926f43637ed300466890d2Mike Lockwood private boolean mDownloadXtraDataPending = false; 18262a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // true if GPS is navigating 1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mNavigating; 185cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood 186cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood // true if GPS engine is on 187cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood private boolean mEngineOn; 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 18904598b67a58fad93e5060bb77756ba4863013aedMike Lockwood // requested frequency of fixes, in milliseconds 19004598b67a58fad93e5060bb77756ba4863013aedMike Lockwood private int mFixInterval = 1000; 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // true if we started navigation 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mStarted; 1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 19503ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood // true if single shot request is in progress 19603ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood private boolean mSingleShot; 19703ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood 19804598b67a58fad93e5060bb77756ba4863013aedMike Lockwood // capabilities of the GPS engine 19904598b67a58fad93e5060bb77756ba4863013aedMike Lockwood private int mEngineCapabilities; 20004598b67a58fad93e5060bb77756ba4863013aedMike Lockwood 2011a1cd3a878b6389c097e34d114b60cf953edaeaaMike Lockwood // true if XTRA is supported 2021a1cd3a878b6389c097e34d114b60cf953edaeaaMike Lockwood private boolean mSupportsXtra; 2031a1cd3a878b6389c097e34d114b60cf953edaeaaMike Lockwood 2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // for calculating time to first fix 2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private long mFixRequestTime = 0; 2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // time to first fix for most recent session 2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mTTFF = 0; 2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // time we received our last fix 2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private long mLastFixTime; 2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 21104598b67a58fad93e5060bb77756ba4863013aedMike Lockwood private int mPositionMode; 21204598b67a58fad93e5060bb77756ba4863013aedMike Lockwood 2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // properties loaded from PROPERTIES_FILE 2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Properties mProperties; 2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private String mNtpServer; 216734d6031a662a275ec68627bd1258159041d44deMike Lockwood private String mSuplServerHost; 217734d6031a662a275ec68627bd1258159041d44deMike Lockwood private int mSuplServerPort; 218734d6031a662a275ec68627bd1258159041d44deMike Lockwood private String mC2KServerHost; 219734d6031a662a275ec68627bd1258159041d44deMike Lockwood private int mC2KServerPort; 2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 22115e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood private final Context mContext; 22215e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood private final ILocationManager mLocationManager; 2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Location mLocation = new Location(LocationManager.GPS_PROVIDER); 2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Bundle mLocationExtras = new Bundle(); 2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private ArrayList<Listener> mListeners = new ArrayList<Listener>(); 22662a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood 22789096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood // GpsLocationProvider's handler thread 22889096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood private final Thread mThread; 22989096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood // Handler for processing events in mThread. 23062a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood private Handler mHandler; 23189096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood // Used to signal when our main thread has initialized everything 23289096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood private final CountDownLatch mInitializedLatch = new CountDownLatch(1); 233105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project 234e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood private String mAGpsApn; 235e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood private int mAGpsDataConnectionState; 2362f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood private final ConnectivityManager mConnMgr; 23722d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie private final GpsNetInitiatedHandler mNIHandler; 2382f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood 2390528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood // Wakelocks 2400528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood private final static String WAKELOCK_KEY = "GpsLocationProvider"; 2410528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood private final PowerManager.WakeLock mWakeLock; 24298e48691f738680fe59e7383a41458e7337daccdMike Lockwood // bitfield of pending messages to our Handler 24398e48691f738680fe59e7383a41458e7337daccdMike Lockwood // used only for messages that cannot have multiple instances queued 24498e48691f738680fe59e7383a41458e7337daccdMike Lockwood private int mPendingMessageBits; 24598e48691f738680fe59e7383a41458e7337daccdMike Lockwood // separate counter for ADD_LISTENER and REMOVE_LISTENER messages, 24698e48691f738680fe59e7383a41458e7337daccdMike Lockwood // which might have multiple instances queued 24798e48691f738680fe59e7383a41458e7337daccdMike Lockwood private int mPendingListenerMessages; 2480528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood 24929c84340a14e70419449628ab193d11b7a609e9aMike Lockwood // Alarms 25029c84340a14e70419449628ab193d11b7a609e9aMike Lockwood private final static String ALARM_WAKEUP = "com.android.internal.location.ALARM_WAKEUP"; 2510632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood private final static String ALARM_TIMEOUT = "com.android.internal.location.ALARM_TIMEOUT"; 25229c84340a14e70419449628ab193d11b7a609e9aMike Lockwood private final AlarmManager mAlarmManager; 25329c84340a14e70419449628ab193d11b7a609e9aMike Lockwood private final PendingIntent mWakeupIntent; 2540632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood private final PendingIntent mTimeoutIntent; 25529c84340a14e70419449628ab193d11b7a609e9aMike Lockwood 2562f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood private final IBatteryStats mBatteryStats; 2572f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood private final SparseIntArray mClientUids = new SparseIntArray(); 258105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project 2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // how often to request NTP time, in milliseconds 2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // current setting 4 hours 261f1218be2d8f68f3f445f3bc90e0eca01946a0ddfMike Lockwood private static final long NTP_INTERVAL = 4*60*60*1000; 2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // how long to wait if we have a network error in NTP or XTRA downloading 2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // current setting - 5 minutes 264f1218be2d8f68f3f445f3bc90e0eca01946a0ddfMike Lockwood private static final long RETRY_INTERVAL = 5*60*1000; 265f1218be2d8f68f3f445f3bc90e0eca01946a0ddfMike Lockwood 266f1218be2d8f68f3f445f3bc90e0eca01946a0ddfMike Lockwood // to avoid injecting bad NTP time, we reject any time fixes that differ from system time 267f1218be2d8f68f3f445f3bc90e0eca01946a0ddfMike Lockwood // by more than 5 minutes. 268f1218be2d8f68f3f445f3bc90e0eca01946a0ddfMike Lockwood private static final long MAX_NTP_SYSTEM_TIME_OFFSET = 5*60*1000; 2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 27015e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood private final IGpsStatusProvider mGpsStatusProvider = new IGpsStatusProvider.Stub() { 27115e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood public void addGpsStatusListener(IGpsStatusListener listener) throws RemoteException { 27215e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood if (listener == null) { 27315e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood throw new NullPointerException("listener is null in addGpsStatusListener"); 27415e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 27515e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood 27615e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood synchronized(mListeners) { 27715e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood IBinder binder = listener.asBinder(); 27815e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood int size = mListeners.size(); 27915e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood for (int i = 0; i < size; i++) { 28015e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood Listener test = mListeners.get(i); 28115e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood if (binder.equals(test.mListener.asBinder())) { 28215e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood // listener already added 28315e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood return; 28415e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 28515e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 28615e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood 28715e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood Listener l = new Listener(listener); 28815e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood binder.linkToDeath(l, 0); 28915e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood mListeners.add(l); 29015e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 29115e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 29215e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood 29315e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood public void removeGpsStatusListener(IGpsStatusListener listener) { 29415e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood if (listener == null) { 29515e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood throw new NullPointerException("listener is null in addGpsStatusListener"); 29615e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 29715e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood 29815e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood synchronized(mListeners) { 29915e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood IBinder binder = listener.asBinder(); 30015e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood Listener l = null; 30115e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood int size = mListeners.size(); 30215e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood for (int i = 0; i < size && l == null; i++) { 30315e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood Listener test = mListeners.get(i); 30415e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood if (binder.equals(test.mListener.asBinder())) { 30515e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood l = test; 30615e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 30715e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 30815e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood 30915e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood if (l != null) { 31015e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood mListeners.remove(l); 31115e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood binder.unlinkToDeath(l, 0); 31215e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 31315e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 31415e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 31515e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood }; 31615e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood 31715e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood public IGpsStatusProvider getGpsStatusProvider() { 31815e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood return mGpsStatusProvider; 31915e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 32015e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood 32129c84340a14e70419449628ab193d11b7a609e9aMike Lockwood private final BroadcastReceiver mBroadcastReciever = new BroadcastReceiver() { 322105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project @Override public void onReceive(Context context, Intent intent) { 323105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project String action = intent.getAction(); 324105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project 32529c84340a14e70419449628ab193d11b7a609e9aMike Lockwood if (action.equals(ALARM_WAKEUP)) { 32629c84340a14e70419449628ab193d11b7a609e9aMike Lockwood if (DEBUG) Log.d(TAG, "ALARM_WAKEUP"); 32703ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood startNavigating(false); 3280632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood } else if (action.equals(ALARM_TIMEOUT)) { 3290632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood if (DEBUG) Log.d(TAG, "ALARM_TIMEOUT"); 3300632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood hibernate(); 331105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project } 332105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project } 33329c84340a14e70419449628ab193d11b7a609e9aMike Lockwood }; 334105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project 3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static boolean isSupported() { 3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return native_is_supported(); 3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3394e50b78bda9cd58be61581d2886c88ff6348a1c1Mike Lockwood public GpsLocationProvider(Context context, ILocationManager locationManager) { 3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContext = context; 34115e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood mLocationManager = locationManager; 34279e642e8ed75033eacc461633a8f4cd5157d25dfMike Lockwood mNIHandler = new GpsNetInitiatedHandler(context); 34363598a0619776b421f27cd12fb29eb83dc327997Mike Lockwood 34463598a0619776b421f27cd12fb29eb83dc327997Mike Lockwood mLocation.setExtras(mLocationExtras); 3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3460528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood // Create a wake lock 3470528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood PowerManager powerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE); 3480528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, WAKELOCK_KEY); 34998e48691f738680fe59e7383a41458e7337daccdMike Lockwood mWakeLock.setReferenceCounted(false); 3500528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood 35129c84340a14e70419449628ab193d11b7a609e9aMike Lockwood mAlarmManager = (AlarmManager)mContext.getSystemService(Context.ALARM_SERVICE); 35229c84340a14e70419449628ab193d11b7a609e9aMike Lockwood mWakeupIntent = PendingIntent.getBroadcast(mContext, 0, new Intent(ALARM_WAKEUP), 0); 3530632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood mTimeoutIntent = PendingIntent.getBroadcast(mContext, 0, new Intent(ALARM_TIMEOUT), 0); 35429c84340a14e70419449628ab193d11b7a609e9aMike Lockwood 35558bda987665af759c379cd494ff4873ac61acf29Mike Lockwood mConnMgr = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE); 35658bda987665af759c379cd494ff4873ac61acf29Mike Lockwood 3572f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood // Battery statistics service to be notified when GPS turns on or off 3582f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood mBatteryStats = IBatteryStats.Stub.asInterface(ServiceManager.getService("batteryinfo")); 3592f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood 3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mProperties = new Properties(); 3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project File file = new File(PROPERTIES_FILE); 3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project FileInputStream stream = new FileInputStream(file); 3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mProperties.load(stream); 3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project stream.close(); 3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNtpServer = mProperties.getProperty("NTP_SERVER", null); 367e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood 368734d6031a662a275ec68627bd1258159041d44deMike Lockwood mSuplServerHost = mProperties.getProperty("SUPL_HOST"); 369e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood String portString = mProperties.getProperty("SUPL_PORT"); 370734d6031a662a275ec68627bd1258159041d44deMike Lockwood if (mSuplServerHost != null && portString != null) { 371105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project try { 372734d6031a662a275ec68627bd1258159041d44deMike Lockwood mSuplServerPort = Integer.parseInt(portString); 373105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project } catch (NumberFormatException e) { 374e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood Log.e(TAG, "unable to parse SUPL_PORT: " + portString); 375e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood } 376e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood } 377e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood 378734d6031a662a275ec68627bd1258159041d44deMike Lockwood mC2KServerHost = mProperties.getProperty("C2K_HOST"); 379e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood portString = mProperties.getProperty("C2K_PORT"); 380734d6031a662a275ec68627bd1258159041d44deMike Lockwood if (mC2KServerHost != null && portString != null) { 381e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood try { 382734d6031a662a275ec68627bd1258159041d44deMike Lockwood mC2KServerPort = Integer.parseInt(portString); 383e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood } catch (NumberFormatException e) { 384e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood Log.e(TAG, "unable to parse C2K_PORT: " + portString); 385105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project } 386105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project } 3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (IOException e) { 3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.w(TAG, "Could not open GPS configuration file " + PROPERTIES_FILE); 3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 39062a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood 39189096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood // wait until we are fully initialized before returning 39289096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood mThread = new GpsLocationProviderThread(); 39389096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood mThread.start(); 39489096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood while (true) { 39589096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood try { 39689096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood mInitializedLatch.await(); 39789096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood break; 39889096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood } catch (InterruptedException e) { 39989096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood Thread.currentThread().interrupt(); 40089096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood } 40189096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood } 40262a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood } 40362a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood 40462a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood private void initialize() { 40562a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood // register our receiver on our thread rather than the main thread 40662a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood IntentFilter intentFilter = new IntentFilter(); 40762a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood intentFilter.addAction(ALARM_WAKEUP); 40862a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood intentFilter.addAction(ALARM_TIMEOUT); 40962a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood mContext.registerReceiver(mBroadcastReciever, intentFilter); 4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 413d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood * Returns the name of this provider. 414d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood */ 415d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood public String getName() { 416d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood return LocationManager.GPS_PROVIDER; 417d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood } 418d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood 419d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood /** 4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns true if the provider requires access to a 4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * data network (e.g., the Internet), false otherwise. 4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean requiresNetwork() { 424a9e546169b3c2c9c5f248d2f3abe3b934f48695dMike Lockwood return true; 4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 42703d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood public void updateNetworkState(int state, NetworkInfo info) { 42898e48691f738680fe59e7383a41458e7337daccdMike Lockwood sendMessage(UPDATE_NETWORK_STATE, state, info); 42962a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood } 43062a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood 43162a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood private void handleUpdateNetworkState(int state, NetworkInfo info) { 4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNetworkAvailable = (state == LocationProvider.AVAILABLE); 4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 434f5d95cbc1a6974afeb4d3155bdaa8dae55722a39Joe Onorato if (DEBUG) { 43503d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood Log.d(TAG, "updateNetworkState " + (mNetworkAvailable ? "available" : "unavailable") 43603d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood + " info: " + info); 4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 43803d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood 43903d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood if (info != null && info.getType() == ConnectivityManager.TYPE_MOBILE_SUPL 44003d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood && mAGpsDataConnectionState == AGPS_DATA_CONNECTION_OPENING) { 44103d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood String apnName = info.getExtraInfo(); 44203d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood if (mNetworkAvailable && apnName != null && apnName.length() > 0) { 44303d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood mAGpsApn = apnName; 44403d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood if (DEBUG) Log.d(TAG, "call native_agps_data_conn_open"); 44503d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood native_agps_data_conn_open(apnName); 44603d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood mAGpsDataConnectionState = AGPS_DATA_CONNECTION_OPEN; 44703d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood } else { 44803d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood if (DEBUG) Log.d(TAG, "call native_agps_data_conn_failed"); 44903d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood mAGpsApn = null; 45003d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood mAGpsDataConnectionState = AGPS_DATA_CONNECTION_CLOSED; 45103d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood native_agps_data_conn_failed(); 45203d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood } 45303d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood } 45403d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood 45562a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood if (mNetworkAvailable) { 45662a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood if (mInjectNtpTimePending) { 45798e48691f738680fe59e7383a41458e7337daccdMike Lockwood sendMessage(INJECT_NTP_TIME, 0, null); 45862a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood } 45962a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood if (mDownloadXtraDataPending) { 46098e48691f738680fe59e7383a41458e7337daccdMike Lockwood sendMessage(DOWNLOAD_XTRA_DATA, 0, null); 46162a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood } 46262a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood } 46362a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood } 46462a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood 46562a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood private void handleInjectNtpTime() { 46662a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood if (!mNetworkAvailable) { 46762a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood // try again when network is up 46862a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood mInjectNtpTimePending = true; 46962a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood return; 47062a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood } 47162a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood mInjectNtpTimePending = false; 47262a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood 47362a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood SntpClient client = new SntpClient(); 47462a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood long delay; 47562a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood 47662a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood if (client.requestTime(mNtpServer, 10000)) { 47762a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood long time = client.getNtpTime(); 47862a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood long timeReference = client.getNtpTimeReference(); 47962a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood int certainty = (int)(client.getRoundTripTime()/2); 48062a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood long now = System.currentTimeMillis(); 48162a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood 48262a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood Log.d(TAG, "NTP server returned: " 48362a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood + time + " (" + new Date(time) 48462a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood + ") reference: " + timeReference 48562a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood + " certainty: " + certainty 4861879d284bf3dd704dbc8c95aad262ebbe3c3c0a4Mike Lockwood + " system time offset: " + (time - now)); 48762a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood 4881879d284bf3dd704dbc8c95aad262ebbe3c3c0a4Mike Lockwood native_inject_time(time, timeReference, certainty); 48962a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood delay = NTP_INTERVAL; 49062a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood } else { 49162a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood if (DEBUG) Log.d(TAG, "requestTime failed"); 49262a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood delay = RETRY_INTERVAL; 49362a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood } 49462a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood 49562a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood // send delayed message for next NTP injection 49698e48691f738680fe59e7383a41458e7337daccdMike Lockwood // since this is delayed and not urgent we do not hold a wake lock here 49762a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood mHandler.removeMessages(INJECT_NTP_TIME); 49862a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood mHandler.sendMessageDelayed(Message.obtain(mHandler, INJECT_NTP_TIME), delay); 49962a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood } 50062a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood 50162a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood private void handleDownloadXtraData() { 5025723dfe8c87d0887b8926f43637ed300466890d2Mike Lockwood if (!mNetworkAvailable) { 50362a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood // try again when network is up 50462a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood mDownloadXtraDataPending = true; 50562a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood return; 50662a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood } 50762a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood mDownloadXtraDataPending = false; 50862a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood 50962a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood 51062a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood GpsXtraDownloader xtraDownloader = new GpsXtraDownloader(mContext, mProperties); 51162a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood byte[] data = xtraDownloader.downloadXtraData(); 51262a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood if (data != null) { 51362a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood if (DEBUG) { 51462a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood Log.d(TAG, "calling native_inject_xtra_data"); 51562a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood } 51662a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood native_inject_xtra_data(data, data.length); 51762a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood } else { 51862a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood // try again later 51998e48691f738680fe59e7383a41458e7337daccdMike Lockwood // since this is delayed and not urgent we do not hold a wake lock here 52062a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood mHandler.removeMessages(DOWNLOAD_XTRA_DATA); 52162a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood mHandler.sendMessageDelayed(Message.obtain(mHandler, DOWNLOAD_XTRA_DATA), RETRY_INTERVAL); 52262a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood } 5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 526fd6e5f0dda50e113db4ccc55338b6c4f09da37a4Mike Lockwood * This is called to inform us when another location provider returns a location. 527fd6e5f0dda50e113db4ccc55338b6c4f09da37a4Mike Lockwood * Someday we might use this for network location injection to aid the GPS 528fd6e5f0dda50e113db4ccc55338b6c4f09da37a4Mike Lockwood */ 529fd6e5f0dda50e113db4ccc55338b6c4f09da37a4Mike Lockwood public void updateLocation(Location location) { 53098e48691f738680fe59e7383a41458e7337daccdMike Lockwood sendMessage(UPDATE_LOCATION, 0, location); 53162a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood } 53262a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood 53362a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood private void handleUpdateLocation(Location location) { 534d26ce0d903f5141a346d67b2b94437ef3e2880aaMike Lockwood if (location.hasAccuracy()) { 535d26ce0d903f5141a346d67b2b94437ef3e2880aaMike Lockwood native_inject_location(location.getLatitude(), location.getLongitude(), 536d26ce0d903f5141a346d67b2b94437ef3e2880aaMike Lockwood location.getAccuracy()); 537d26ce0d903f5141a346d67b2b94437ef3e2880aaMike Lockwood } 538fd6e5f0dda50e113db4ccc55338b6c4f09da37a4Mike Lockwood } 539fd6e5f0dda50e113db4ccc55338b6c4f09da37a4Mike Lockwood 540fd6e5f0dda50e113db4ccc55338b6c4f09da37a4Mike Lockwood /** 5419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns true if the provider requires access to a 5429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * satellite-based positioning system (e.g., GPS), false 5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * otherwise. 5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean requiresSatellite() { 5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns true if the provider requires access to an appropriate 5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * cellular network (e.g., to make use of cell tower IDs), false 5529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * otherwise. 5539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean requiresCell() { 5559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 5569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 5599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns true if the use of this provider may result in a 5609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * monetary charge to the user, false if use is free. It is up to 5619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * each provider to give accurate information. 5629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean hasMonetaryCost() { 5649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 5659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 5689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns true if the provider is able to provide altitude 5699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * information, false otherwise. A provider that reports altitude 5709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * under most circumstances but may occassionally not report it 5719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * should return true. 5729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean supportsAltitude() { 5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 5789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns true if the provider is able to provide speed 5799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * information, false otherwise. A provider that reports speed 5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * under most circumstances but may occassionally not report it 5819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * should return true. 5829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean supportsSpeed() { 5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 5889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns true if the provider is able to provide bearing 5899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * information, false otherwise. A provider that reports bearing 5909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * under most circumstances but may occassionally not report it 5919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * should return true. 5929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean supportsBearing() { 5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 5959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 5989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns the power requirement for this provider. 5999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 6009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the power requirement for this provider, as one of the 6019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * constants Criteria.POWER_REQUIREMENT_*. 6029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getPowerRequirement() { 6049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return Criteria.POWER_HIGH; 6059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 60803ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood * Returns true if this provider meets the given criteria, 60903ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood * false otherwise. 61003ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood */ 61103ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood public boolean meetsCriteria(Criteria criteria) { 61203ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood return (criteria.getPowerRequirement() != Criteria.POWER_LOW); 61303ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood } 61403ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood 61503ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood /** 6169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns the horizontal accuracy of this provider 6179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 6189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the accuracy of location from this provider, as one 6199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * of the constants Criteria.ACCURACY_*. 6209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getAccuracy() { 6229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return Criteria.ACCURACY_FINE; 6239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Enables this provider. When enabled, calls to getStatus() 6274e50b78bda9cd58be61581d2886c88ff6348a1c1Mike Lockwood * must be handled. Hardware may be started up 6289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * when the provider is enabled. 6299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 63062a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood public void enable() { 63162a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood synchronized (mHandler) { 63298e48691f738680fe59e7383a41458e7337daccdMike Lockwood sendMessage(ENABLE, 1, null); 63362a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood } 63462a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood } 63562a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood 63662a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood private void handleEnable() { 63762a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood if (DEBUG) Log.d(TAG, "handleEnable"); 6389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mEnabled) return; 6399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEnabled = native_init(); 6409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mEnabled) { 6421a1cd3a878b6389c097e34d114b60cf953edaeaaMike Lockwood mSupportsXtra = native_supports_xtra(); 643734d6031a662a275ec68627bd1258159041d44deMike Lockwood if (mSuplServerHost != null) { 644734d6031a662a275ec68627bd1258159041d44deMike Lockwood native_set_agps_server(AGPS_TYPE_SUPL, mSuplServerHost, mSuplServerPort); 645734d6031a662a275ec68627bd1258159041d44deMike Lockwood } 646734d6031a662a275ec68627bd1258159041d44deMike Lockwood if (mC2KServerHost != null) { 647734d6031a662a275ec68627bd1258159041d44deMike Lockwood native_set_agps_server(AGPS_TYPE_C2K, mC2KServerHost, mC2KServerPort); 648734d6031a662a275ec68627bd1258159041d44deMike Lockwood } 6499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 6509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.w(TAG, "Failed to enable location provider"); 6519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 6559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Disables this provider. When disabled, calls to getStatus() 6564e50b78bda9cd58be61581d2886c88ff6348a1c1Mike Lockwood * need not be handled. Hardware may be shut 6579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * down while the provider is disabled. 6589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 65962a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood public void disable() { 66062a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood synchronized (mHandler) { 66198e48691f738680fe59e7383a41458e7337daccdMike Lockwood sendMessage(ENABLE, 0, null); 66262a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood } 66362a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood } 66462a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood 66562a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood private void handleDisable() { 66689096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood if (DEBUG) Log.d(TAG, "handleDisable"); 6679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mEnabled) return; 6689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEnabled = false; 6709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project stopNavigating(); 6719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 672cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood // do this before releasing wakelock 673cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood native_cleanup(); 6749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 676d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood public boolean isEnabled() { 677d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood return mEnabled; 678d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood } 679d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood 6809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getStatus(Bundle extras) { 6819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras != null) { 6829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project extras.putInt("satellites", mSvCount); 6839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mStatus; 6859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void updateStatus(int status, int svCount) { 6889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (status != mStatus || svCount != mSvCount) { 6899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStatus = status; 6909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSvCount = svCount; 6919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocationExtras.putInt("satellites", svCount); 6929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStatusUpdateTime = SystemClock.elapsedRealtime(); 6939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public long getStatusUpdateTime() { 6979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mStatusUpdateTime; 6989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void enableLocationTracking(boolean enable) { 70103ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood // FIXME - should set a flag here to avoid race conditions with single shot request 70262a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood synchronized (mHandler) { 70398e48691f738680fe59e7383a41458e7337daccdMike Lockwood sendMessage(ENABLE_TRACKING, (enable ? 1 : 0), null); 70462a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood } 70562a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood } 70662a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood 70762a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood private void handleEnableLocationTracking(boolean enable) { 7089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (enable) { 7099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTTFF = 0; 7109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLastFixTime = 0; 71103ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood startNavigating(false); 7129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 71304598b67a58fad93e5060bb77756ba4863013aedMike Lockwood if (!hasCapability(GPS_CAPABILITY_SCHEDULING)) { 71404598b67a58fad93e5060bb77756ba4863013aedMike Lockwood mAlarmManager.cancel(mWakeupIntent); 71504598b67a58fad93e5060bb77756ba4863013aedMike Lockwood mAlarmManager.cancel(mTimeoutIntent); 71604598b67a58fad93e5060bb77756ba4863013aedMike Lockwood } 7179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project stopNavigating(); 7189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 72103ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood public boolean requestSingleShotFix() { 72203ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood if (mStarted) { 72303ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood // cannot do single shot if already navigating 72403ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood return false; 72503ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood } 72603ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood synchronized (mHandler) { 72703ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood mHandler.removeMessages(REQUEST_SINGLE_SHOT); 72803ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood Message m = Message.obtain(mHandler, REQUEST_SINGLE_SHOT); 72903ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood mHandler.sendMessage(m); 73003ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood } 73103ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood return true; 73203ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood } 73303ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood 73403ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood private void handleRequestSingleShot() { 73503ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood mTTFF = 0; 73603ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood mLastFixTime = 0; 73703ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood startNavigating(true); 73803ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood } 73903ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood 7407e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn public void setMinTime(long minTime, WorkSource ws) { 741f5d95cbc1a6974afeb4d3155bdaa8dae55722a39Joe Onorato if (DEBUG) Log.d(TAG, "setMinTime " + minTime); 7429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (minTime >= 0) { 74404598b67a58fad93e5060bb77756ba4863013aedMike Lockwood mFixInterval = (int)minTime; 74504598b67a58fad93e5060bb77756ba4863013aedMike Lockwood 74604598b67a58fad93e5060bb77756ba4863013aedMike Lockwood if (mStarted && hasCapability(GPS_CAPABILITY_SCHEDULING)) { 74704598b67a58fad93e5060bb77756ba4863013aedMike Lockwood if (!native_set_position_mode(mPositionMode, GPS_POSITION_RECURRENCE_PERIODIC, 74804598b67a58fad93e5060bb77756ba4863013aedMike Lockwood mFixInterval, 0, 0)) { 74904598b67a58fad93e5060bb77756ba4863013aedMike Lockwood Log.e(TAG, "set_position_mode failed in setMinTime()"); 75004598b67a58fad93e5060bb77756ba4863013aedMike Lockwood } 7519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7553c8fbdf5dd19fad0b3006557716ee1026d7d5899Fred Fettinger public String getInternalState() { 7563c8fbdf5dd19fad0b3006557716ee1026d7d5899Fred Fettinger return native_get_internal_state(); 7573c8fbdf5dd19fad0b3006557716ee1026d7d5899Fred Fettinger } 7583c8fbdf5dd19fad0b3006557716ee1026d7d5899Fred Fettinger 7599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final class Listener implements IBinder.DeathRecipient { 7609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final IGpsStatusListener mListener; 7619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int mSensors = 0; 7639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Listener(IGpsStatusListener listener) { 7659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mListener = listener; 7669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void binderDied() { 769f5d95cbc1a6974afeb4d3155bdaa8dae55722a39Joe Onorato if (DEBUG) Log.d(TAG, "GPS status listener died"); 7709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized(mListeners) { 7729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mListeners.remove(this); 7739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 774fff2fda0199dedbf1079454dca98a81190dce765Suchi Amalapurapu if (mListener != null) { 775fff2fda0199dedbf1079454dca98a81190dce765Suchi Amalapurapu mListener.asBinder().unlinkToDeath(this, 0); 776fff2fda0199dedbf1079454dca98a81190dce765Suchi Amalapurapu } 7779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7802f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood public void addListener(int uid) { 78198e48691f738680fe59e7383a41458e7337daccdMike Lockwood synchronized (mWakeLock) { 78298e48691f738680fe59e7383a41458e7337daccdMike Lockwood mPendingListenerMessages++; 7837e9f4eb2608148436cef36c9969bf8a599b39e72Dianne Hackborn mWakeLock.acquire(); 78498e48691f738680fe59e7383a41458e7337daccdMike Lockwood Message m = Message.obtain(mHandler, ADD_LISTENER); 78598e48691f738680fe59e7383a41458e7337daccdMike Lockwood m.arg1 = uid; 78698e48691f738680fe59e7383a41458e7337daccdMike Lockwood mHandler.sendMessage(m); 78798e48691f738680fe59e7383a41458e7337daccdMike Lockwood } 78862a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood } 78962a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood 79062a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood private void handleAddListener(int uid) { 7912e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn synchronized(mListeners) { 7922e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn if (mClientUids.indexOfKey(uid) >= 0) { 7932e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn // Shouldn't be here -- already have this uid. 7942e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn Log.w(TAG, "Duplicate add listener for uid " + uid); 7952e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn return; 7962e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn } 7972e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn mClientUids.put(uid, 0); 7982e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn if (mNavigating) { 7992e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn try { 8002e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn mBatteryStats.noteStartGps(uid); 8012e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn } catch (RemoteException e) { 8022e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn Log.w(TAG, "RemoteException in addListener"); 8032e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn } 8042f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } 8052f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } 8062f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } 8072f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood 8082f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood public void removeListener(int uid) { 80998e48691f738680fe59e7383a41458e7337daccdMike Lockwood synchronized (mWakeLock) { 81098e48691f738680fe59e7383a41458e7337daccdMike Lockwood mPendingListenerMessages++; 81198e48691f738680fe59e7383a41458e7337daccdMike Lockwood mWakeLock.acquire(); 81298e48691f738680fe59e7383a41458e7337daccdMike Lockwood Message m = Message.obtain(mHandler, REMOVE_LISTENER); 81398e48691f738680fe59e7383a41458e7337daccdMike Lockwood m.arg1 = uid; 81498e48691f738680fe59e7383a41458e7337daccdMike Lockwood mHandler.sendMessage(m); 81598e48691f738680fe59e7383a41458e7337daccdMike Lockwood } 81662a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood } 81762a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood 81862a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood private void handleRemoveListener(int uid) { 8192e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn synchronized(mListeners) { 8202e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn if (mClientUids.indexOfKey(uid) < 0) { 8212e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn // Shouldn't be here -- don't have this uid. 8222e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn Log.w(TAG, "Unneeded remove listener for uid " + uid); 8232e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn return; 8242e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn } 8252e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn mClientUids.delete(uid); 8262e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn if (mNavigating) { 8272e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn try { 8282e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn mBatteryStats.noteStopGps(uid); 8292e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn } catch (RemoteException e) { 8302e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn Log.w(TAG, "RemoteException in removeListener"); 8312e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn } 8322f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } 8332f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } 8342f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } 8352f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood 8369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean sendExtraCommand(String command, Bundle extras) { 8379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 83863aa5a6f98b1016863e4f6edd87eb471b28dc28fMike Lockwood long identity = Binder.clearCallingIdentity(); 83963aa5a6f98b1016863e4f6edd87eb471b28dc28fMike Lockwood boolean result = false; 84063aa5a6f98b1016863e4f6edd87eb471b28dc28fMike Lockwood 8419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ("delete_aiding_data".equals(command)) { 84263aa5a6f98b1016863e4f6edd87eb471b28dc28fMike Lockwood result = deleteAidingData(extras); 84363aa5a6f98b1016863e4f6edd87eb471b28dc28fMike Lockwood } else if ("force_time_injection".equals(command)) { 84498e48691f738680fe59e7383a41458e7337daccdMike Lockwood sendMessage(INJECT_NTP_TIME, 0, null); 84563aa5a6f98b1016863e4f6edd87eb471b28dc28fMike Lockwood result = true; 84663aa5a6f98b1016863e4f6edd87eb471b28dc28fMike Lockwood } else if ("force_xtra_injection".equals(command)) { 8471a1cd3a878b6389c097e34d114b60cf953edaeaaMike Lockwood if (mSupportsXtra) { 84893bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood xtraDownloadRequest(); 84963aa5a6f98b1016863e4f6edd87eb471b28dc28fMike Lockwood result = true; 85093bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood } 85163aa5a6f98b1016863e4f6edd87eb471b28dc28fMike Lockwood } else { 85263aa5a6f98b1016863e4f6edd87eb471b28dc28fMike Lockwood Log.w(TAG, "sendExtraCommand: unknown command " + command); 85393bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood } 8549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 85563aa5a6f98b1016863e4f6edd87eb471b28dc28fMike Lockwood Binder.restoreCallingIdentity(identity); 85663aa5a6f98b1016863e4f6edd87eb471b28dc28fMike Lockwood return result; 8579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean deleteAidingData(Bundle extras) { 8609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int flags; 8619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras == null) { 8639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project flags = GPS_DELETE_ALL; 8649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 8659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project flags = 0; 8669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("ephemeris")) flags |= GPS_DELETE_EPHEMERIS; 8679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("almanac")) flags |= GPS_DELETE_ALMANAC; 8689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("position")) flags |= GPS_DELETE_POSITION; 8699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("time")) flags |= GPS_DELETE_TIME; 8709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("iono")) flags |= GPS_DELETE_IONO; 8719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("utc")) flags |= GPS_DELETE_UTC; 8729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("health")) flags |= GPS_DELETE_HEALTH; 8739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("svdir")) flags |= GPS_DELETE_SVDIR; 8749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("svsteer")) flags |= GPS_DELETE_SVSTEER; 8759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("sadata")) flags |= GPS_DELETE_SADATA; 8769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("rti")) flags |= GPS_DELETE_RTI; 8779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("celldb-info")) flags |= GPS_DELETE_CELLDB_INFO; 8789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("all")) flags |= GPS_DELETE_ALL; 8799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (flags != 0) { 8829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project native_delete_aiding_data(flags); 8839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 8849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 8879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 88903ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood private void startNavigating(boolean singleShot) { 8909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mStarted) { 89129c84340a14e70419449628ab193d11b7a609e9aMike Lockwood if (DEBUG) Log.d(TAG, "startNavigating"); 8929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStarted = true; 89303ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood mSingleShot = singleShot; 89403ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood mPositionMode = GPS_POSITION_MODE_STANDALONE; 89503ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood 89603ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood if (Settings.Secure.getInt(mContext.getContentResolver(), 897660bbfcc54d48d5d32e64da683c76b9c372c19b1Mike Lockwood Settings.Secure.ASSISTED_GPS_ENABLED, 1) != 0) { 89803ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood if (singleShot && hasCapability(GPS_CAPABILITY_MSA)) { 89903ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood mPositionMode = GPS_POSITION_MODE_MS_ASSISTED; 9008dc16c27e23dae5bdf65fd2a2ced97c2f645a633Mike Lockwood } else if (hasCapability(GPS_CAPABILITY_MSB)) { 90103ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood mPositionMode = GPS_POSITION_MODE_MS_BASED; 90203ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood } 903bcab8df83e6e769a7cbcc742e72b47d665998793Mike Lockwood } 904bcab8df83e6e769a7cbcc742e72b47d665998793Mike Lockwood 90504598b67a58fad93e5060bb77756ba4863013aedMike Lockwood int interval = (hasCapability(GPS_CAPABILITY_SCHEDULING) ? mFixInterval : 1000); 90604598b67a58fad93e5060bb77756ba4863013aedMike Lockwood if (!native_set_position_mode(mPositionMode, GPS_POSITION_RECURRENCE_PERIODIC, 90704598b67a58fad93e5060bb77756ba4863013aedMike Lockwood interval, 0, 0)) { 90804598b67a58fad93e5060bb77756ba4863013aedMike Lockwood mStarted = false; 90904598b67a58fad93e5060bb77756ba4863013aedMike Lockwood Log.e(TAG, "set_position_mode failed in startNavigating()"); 91004598b67a58fad93e5060bb77756ba4863013aedMike Lockwood return; 91104598b67a58fad93e5060bb77756ba4863013aedMike Lockwood } 91204598b67a58fad93e5060bb77756ba4863013aedMike Lockwood if (!native_start()) { 9139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStarted = false; 9149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.e(TAG, "native_start failed in startNavigating()"); 9150632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood return; 9169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // reset SV count to zero 91915e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood updateStatus(LocationProvider.TEMPORARILY_UNAVAILABLE, 0); 92029c84340a14e70419449628ab193d11b7a609e9aMike Lockwood mFixRequestTime = System.currentTimeMillis(); 92104598b67a58fad93e5060bb77756ba4863013aedMike Lockwood if (!hasCapability(GPS_CAPABILITY_SCHEDULING)) { 92204598b67a58fad93e5060bb77756ba4863013aedMike Lockwood // set timer to give up if we do not receive a fix within NO_FIX_TIMEOUT 92304598b67a58fad93e5060bb77756ba4863013aedMike Lockwood // and our fix interval is not short 92404598b67a58fad93e5060bb77756ba4863013aedMike Lockwood if (mFixInterval >= NO_FIX_TIMEOUT) { 92504598b67a58fad93e5060bb77756ba4863013aedMike Lockwood mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, 92604598b67a58fad93e5060bb77756ba4863013aedMike Lockwood SystemClock.elapsedRealtime() + NO_FIX_TIMEOUT, mTimeoutIntent); 92704598b67a58fad93e5060bb77756ba4863013aedMike Lockwood } 9280632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood } 9299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 93262a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood private void stopNavigating() { 93329c84340a14e70419449628ab193d11b7a609e9aMike Lockwood if (DEBUG) Log.d(TAG, "stopNavigating"); 9349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mStarted) { 9359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStarted = false; 93603ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood mSingleShot = false; 9379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project native_stop(); 9389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTTFF = 0; 9399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLastFixTime = 0; 9409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocationFlags = LOCATION_INVALID; 9419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // reset SV count to zero 94315e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood updateStatus(LocationProvider.TEMPORARILY_UNAVAILABLE, 0); 9449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9470632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood private void hibernate() { 9480632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood // stop GPS until our next fix interval arrives 9490632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood stopNavigating(); 9500632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood mAlarmManager.cancel(mTimeoutIntent); 9510632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood mAlarmManager.cancel(mWakeupIntent); 9520632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood long now = SystemClock.elapsedRealtime(); 9530632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, 95404598b67a58fad93e5060bb77756ba4863013aedMike Lockwood SystemClock.elapsedRealtime() + mFixInterval, mWakeupIntent); 95504598b67a58fad93e5060bb77756ba4863013aedMike Lockwood } 95604598b67a58fad93e5060bb77756ba4863013aedMike Lockwood 95704598b67a58fad93e5060bb77756ba4863013aedMike Lockwood private boolean hasCapability(int capability) { 95804598b67a58fad93e5060bb77756ba4863013aedMike Lockwood return ((mEngineCapabilities & capability) != 0); 9590632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood } 9600632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood 9619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 9629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * called from native code to update our position. 9639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 9649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void reportLocation(int flags, double latitude, double longitude, double altitude, 9659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float speed, float bearing, float accuracy, long timestamp) { 96629c84340a14e70419449628ab193d11b7a609e9aMike Lockwood if (VERBOSE) Log.v(TAG, "reportLocation lat: " + latitude + " long: " + longitude + 9679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project " timestamp: " + timestamp); 9689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mLocation) { 9709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocationFlags = flags; 9719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((flags & LOCATION_HAS_LAT_LONG) == LOCATION_HAS_LAT_LONG) { 9729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocation.setLatitude(latitude); 9739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocation.setLongitude(longitude); 9749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocation.setTime(timestamp); 9759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((flags & LOCATION_HAS_ALTITUDE) == LOCATION_HAS_ALTITUDE) { 9779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocation.setAltitude(altitude); 9789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 9799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocation.removeAltitude(); 9809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((flags & LOCATION_HAS_SPEED) == LOCATION_HAS_SPEED) { 9829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocation.setSpeed(speed); 9839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 9849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocation.removeSpeed(); 9859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((flags & LOCATION_HAS_BEARING) == LOCATION_HAS_BEARING) { 9879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocation.setBearing(bearing); 9889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 9899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocation.removeBearing(); 9909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((flags & LOCATION_HAS_ACCURACY) == LOCATION_HAS_ACCURACY) { 9929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocation.setAccuracy(accuracy); 9939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 9949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocation.removeAccuracy(); 9959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 99715e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood try { 998a4903f254b4711c8fc0ac5f7e3d605f4dce34f35Mike Lockwood mLocationManager.reportLocation(mLocation, false); 99915e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } catch (RemoteException e) { 100015e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood Log.e(TAG, "RemoteException calling reportLocation"); 100115e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 10029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1004fa94ff074d3200fae2f5d14a6d0f454e2ad23cfaHakan Gustavsson mLastFixTime = System.currentTimeMillis(); 1005fa94ff074d3200fae2f5d14a6d0f454e2ad23cfaHakan Gustavsson // report time to first fix 1006fa94ff074d3200fae2f5d14a6d0f454e2ad23cfaHakan Gustavsson if (mTTFF == 0 && (flags & LOCATION_HAS_LAT_LONG) == LOCATION_HAS_LAT_LONG) { 1007fa94ff074d3200fae2f5d14a6d0f454e2ad23cfaHakan Gustavsson mTTFF = (int)(mLastFixTime - mFixRequestTime); 1008f4dffd8a45386b5a5f0e6de4f30facc9eaac4001The Android Open Source Project if (DEBUG) Log.d(TAG, "TTFF: " + mTTFF); 1009fa94ff074d3200fae2f5d14a6d0f454e2ad23cfaHakan Gustavsson 1010fa94ff074d3200fae2f5d14a6d0f454e2ad23cfaHakan Gustavsson // notify status listeners 1011fa94ff074d3200fae2f5d14a6d0f454e2ad23cfaHakan Gustavsson synchronized(mListeners) { 1012fa94ff074d3200fae2f5d14a6d0f454e2ad23cfaHakan Gustavsson int size = mListeners.size(); 1013fa94ff074d3200fae2f5d14a6d0f454e2ad23cfaHakan Gustavsson for (int i = 0; i < size; i++) { 1014fa94ff074d3200fae2f5d14a6d0f454e2ad23cfaHakan Gustavsson Listener listener = mListeners.get(i); 1015fa94ff074d3200fae2f5d14a6d0f454e2ad23cfaHakan Gustavsson try { 1016f4dffd8a45386b5a5f0e6de4f30facc9eaac4001The Android Open Source Project listener.mListener.onFirstFix(mTTFF); 1017fa94ff074d3200fae2f5d14a6d0f454e2ad23cfaHakan Gustavsson } catch (RemoteException e) { 1018fa94ff074d3200fae2f5d14a6d0f454e2ad23cfaHakan Gustavsson Log.w(TAG, "RemoteException in stopNavigating"); 1019fa94ff074d3200fae2f5d14a6d0f454e2ad23cfaHakan Gustavsson mListeners.remove(listener); 1020fa94ff074d3200fae2f5d14a6d0f454e2ad23cfaHakan Gustavsson // adjust for size of list changing 1021fa94ff074d3200fae2f5d14a6d0f454e2ad23cfaHakan Gustavsson size--; 1022fa94ff074d3200fae2f5d14a6d0f454e2ad23cfaHakan Gustavsson } 1023fa94ff074d3200fae2f5d14a6d0f454e2ad23cfaHakan Gustavsson } 1024fa94ff074d3200fae2f5d14a6d0f454e2ad23cfaHakan Gustavsson } 1025fa94ff074d3200fae2f5d14a6d0f454e2ad23cfaHakan Gustavsson } 1026fa94ff074d3200fae2f5d14a6d0f454e2ad23cfaHakan Gustavsson 102703ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood if (mSingleShot) { 102803ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood stopNavigating(); 102903ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood } 103015e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood if (mStarted && mStatus != LocationProvider.AVAILABLE) { 1031d53ba017ee2381383b4bb4d92e6e0e661431660fMike Lockwood // we want to time out if we do not receive a fix 1032b7be5447a002b4a1cf7d4030cc8a0a330cd7517cMike Lockwood // within the time out and we are requesting infrequent fixes 103304598b67a58fad93e5060bb77756ba4863013aedMike Lockwood if (!hasCapability(GPS_CAPABILITY_SCHEDULING) && mFixInterval < NO_FIX_TIMEOUT) { 1034b7be5447a002b4a1cf7d4030cc8a0a330cd7517cMike Lockwood mAlarmManager.cancel(mTimeoutIntent); 1035b7be5447a002b4a1cf7d4030cc8a0a330cd7517cMike Lockwood } 1036b7be5447a002b4a1cf7d4030cc8a0a330cd7517cMike Lockwood 10379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // send an intent to notify that the GPS is receiving fixes. 103800b74270c9f136a8727c5f6cda0997a3a905f385Mike Lockwood Intent intent = new Intent(LocationManager.GPS_FIX_CHANGE_ACTION); 103900b74270c9f136a8727c5f6cda0997a3a905f385Mike Lockwood intent.putExtra(LocationManager.EXTRA_GPS_ENABLED, true); 10409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContext.sendBroadcast(intent); 104115e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood updateStatus(LocationProvider.AVAILABLE, mSvCount); 10429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 104329c84340a14e70419449628ab193d11b7a609e9aMike Lockwood 104403ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood if (!hasCapability(GPS_CAPABILITY_SCHEDULING) && mStarted && mFixInterval > 1000) { 1045d53ba017ee2381383b4bb4d92e6e0e661431660fMike Lockwood if (DEBUG) Log.d(TAG, "got fix, hibernating"); 10460632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood hibernate(); 104729c84340a14e70419449628ab193d11b7a609e9aMike Lockwood } 10489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 10519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * called from native code to update our status 10529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 10539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void reportStatus(int status) { 105429c84340a14e70419449628ab193d11b7a609e9aMike Lockwood if (VERBOSE) Log.v(TAG, "reportStatus status: " + status); 10559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10562e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn synchronized(mListeners) { 10572e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn boolean wasNavigating = mNavigating; 1058dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood 1059cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood switch (status) { 1060cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood case GPS_STATUS_SESSION_BEGIN: 1061cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood mNavigating = true; 1062271f9f172b241607b1ed39a7709c3ed47ee5dee7Mike Lockwood mEngineOn = true; 1063cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood break; 1064cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood case GPS_STATUS_SESSION_END: 1065cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood mNavigating = false; 1066cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood break; 1067cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood case GPS_STATUS_ENGINE_ON: 1068cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood mEngineOn = true; 1069cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood break; 1070cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood case GPS_STATUS_ENGINE_OFF: 1071cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood mEngineOn = false; 1072271f9f172b241607b1ed39a7709c3ed47ee5dee7Mike Lockwood mNavigating = false; 1073cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood break; 1074cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood } 1075cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood 1076dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood if (wasNavigating != mNavigating) { 1077dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood int size = mListeners.size(); 1078dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood for (int i = 0; i < size; i++) { 1079dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood Listener listener = mListeners.get(i); 1080dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood try { 1081dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood if (mNavigating) { 1082dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood listener.mListener.onGpsStarted(); 1083dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood } else { 1084dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood listener.mListener.onGpsStopped(); 1085dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood } 1086dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood } catch (RemoteException e) { 1087dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood Log.w(TAG, "RemoteException in reportStatus"); 1088dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood mListeners.remove(listener); 1089dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood // adjust for size of list changing 1090dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood size--; 1091dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood } 1092dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood } 1093dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood 10942e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn try { 1095dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood // update battery stats 1096dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood for (int i=mClientUids.size() - 1; i >= 0; i--) { 1097dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood int uid = mClientUids.keyAt(i); 1098dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood if (mNavigating) { 1099dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood mBatteryStats.noteStartGps(uid); 1100dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood } else { 1101dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood mBatteryStats.noteStopGps(uid); 1102dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood } 11039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11042e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn } catch (RemoteException e) { 11052e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn Log.w(TAG, "RemoteException in reportStatus"); 11069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1108dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood // send an intent to notify that the GPS has been enabled or disabled. 110900b74270c9f136a8727c5f6cda0997a3a905f385Mike Lockwood Intent intent = new Intent(LocationManager.GPS_ENABLED_CHANGE_ACTION); 111000b74270c9f136a8727c5f6cda0997a3a905f385Mike Lockwood intent.putExtra(LocationManager.EXTRA_GPS_ENABLED, mNavigating); 1111dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood mContext.sendBroadcast(intent); 11122f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } 11139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 11179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * called from native code to update SV info 11189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 11199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void reportSvStatus() { 11209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int svCount = native_read_sv_status(mSvs, mSnrs, mSvElevations, mSvAzimuths, mSvMasks); 11229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized(mListeners) { 11249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int size = mListeners.size(); 11259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < size; i++) { 11269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Listener listener = mListeners.get(i); 11279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 11289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project listener.mListener.onSvStatusChanged(svCount, mSvs, mSnrs, 11299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSvElevations, mSvAzimuths, mSvMasks[EPHEMERIS_MASK], 11309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSvMasks[ALMANAC_MASK], mSvMasks[USED_FOR_FIX_MASK]); 11319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 11329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.w(TAG, "RemoteException in reportSvInfo"); 11339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mListeners.remove(listener); 11349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // adjust for size of list changing 11359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size--; 11369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 114029c84340a14e70419449628ab193d11b7a609e9aMike Lockwood if (VERBOSE) { 114129c84340a14e70419449628ab193d11b7a609e9aMike Lockwood Log.v(TAG, "SV count: " + svCount + 11429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project " ephemerisMask: " + Integer.toHexString(mSvMasks[EPHEMERIS_MASK]) + 11439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project " almanacMask: " + Integer.toHexString(mSvMasks[ALMANAC_MASK])); 11449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < svCount; i++) { 114529c84340a14e70419449628ab193d11b7a609e9aMike Lockwood Log.v(TAG, "sv: " + mSvs[i] + 11469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project " snr: " + (float)mSnrs[i]/10 + 11479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project " elev: " + mSvElevations[i] + 11489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project " azimuth: " + mSvAzimuths[i] + 11499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ((mSvMasks[EPHEMERIS_MASK] & (1 << (mSvs[i] - 1))) == 0 ? " " : " E") + 11509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ((mSvMasks[ALMANAC_MASK] & (1 << (mSvs[i] - 1))) == 0 ? " " : " A") + 11519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ((mSvMasks[USED_FOR_FIX_MASK] & (1 << (mSvs[i] - 1))) == 0 ? "" : "U")); 11529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11550881f4f9339febee85c9ab4cba69970ac5cbde55Kevin.KY Tsai // return number of sets used in fix instead of total 11560881f4f9339febee85c9ab4cba69970ac5cbde55Kevin.KY Tsai updateStatus(mStatus, Integer.bitCount(mSvMasks[USED_FOR_FIX_MASK])); 11579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 115815e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood if (mNavigating && mStatus == LocationProvider.AVAILABLE && mLastFixTime > 0 && 115904598b67a58fad93e5060bb77756ba4863013aedMike Lockwood System.currentTimeMillis() - mLastFixTime > RECENT_FIX_TIMEOUT) { 11609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // send an intent to notify that the GPS is no longer receiving fixes. 116100b74270c9f136a8727c5f6cda0997a3a905f385Mike Lockwood Intent intent = new Intent(LocationManager.GPS_FIX_CHANGE_ACTION); 116200b74270c9f136a8727c5f6cda0997a3a905f385Mike Lockwood intent.putExtra(LocationManager.EXTRA_GPS_ENABLED, false); 11639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContext.sendBroadcast(intent); 116415e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood updateStatus(LocationProvider.TEMPORARILY_UNAVAILABLE, mSvCount); 11659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 116758bda987665af759c379cd494ff4873ac61acf29Mike Lockwood 116858bda987665af759c379cd494ff4873ac61acf29Mike Lockwood /** 1169e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood * called from native code to update AGPS status 117058bda987665af759c379cd494ff4873ac61acf29Mike Lockwood */ 1171e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood private void reportAGpsStatus(int type, int status) { 117258bda987665af759c379cd494ff4873ac61acf29Mike Lockwood switch (status) { 1173e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood case GPS_REQUEST_AGPS_DATA_CONN: 11742acfd34ccbd39258422333c9c66c586297c97683Mike Lockwood // Set mAGpsDataConnectionState before calling startUsingNetworkFeature 11752acfd34ccbd39258422333c9c66c586297c97683Mike Lockwood // to avoid a race condition with handleUpdateNetworkState() 11762acfd34ccbd39258422333c9c66c586297c97683Mike Lockwood mAGpsDataConnectionState = AGPS_DATA_CONNECTION_OPENING; 11772acfd34ccbd39258422333c9c66c586297c97683Mike Lockwood int result = mConnMgr.startUsingNetworkFeature( 117858bda987665af759c379cd494ff4873ac61acf29Mike Lockwood ConnectivityManager.TYPE_MOBILE, Phone.FEATURE_ENABLE_SUPL); 117958bda987665af759c379cd494ff4873ac61acf29Mike Lockwood if (result == Phone.APN_ALREADY_ACTIVE) { 1180b362a9ab91bb4c05ef1d5c4e7019499257c7f849Mike Lockwood if (mAGpsApn != null) { 1181b362a9ab91bb4c05ef1d5c4e7019499257c7f849Mike Lockwood native_agps_data_conn_open(mAGpsApn); 1182b362a9ab91bb4c05ef1d5c4e7019499257c7f849Mike Lockwood mAGpsDataConnectionState = AGPS_DATA_CONNECTION_OPEN; 1183b362a9ab91bb4c05ef1d5c4e7019499257c7f849Mike Lockwood } else { 1184b362a9ab91bb4c05ef1d5c4e7019499257c7f849Mike Lockwood Log.e(TAG, "mAGpsApn not set when receiving Phone.APN_ALREADY_ACTIVE"); 11852acfd34ccbd39258422333c9c66c586297c97683Mike Lockwood mAGpsDataConnectionState = AGPS_DATA_CONNECTION_CLOSED; 1186b362a9ab91bb4c05ef1d5c4e7019499257c7f849Mike Lockwood native_agps_data_conn_failed(); 1187b362a9ab91bb4c05ef1d5c4e7019499257c7f849Mike Lockwood } 118858bda987665af759c379cd494ff4873ac61acf29Mike Lockwood } else if (result == Phone.APN_REQUEST_STARTED) { 11892acfd34ccbd39258422333c9c66c586297c97683Mike Lockwood // Nothing to do here 119058bda987665af759c379cd494ff4873ac61acf29Mike Lockwood } else { 11912acfd34ccbd39258422333c9c66c586297c97683Mike Lockwood mAGpsDataConnectionState = AGPS_DATA_CONNECTION_CLOSED; 1192e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood native_agps_data_conn_failed(); 119358bda987665af759c379cd494ff4873ac61acf29Mike Lockwood } 119458bda987665af759c379cd494ff4873ac61acf29Mike Lockwood break; 1195e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood case GPS_RELEASE_AGPS_DATA_CONN: 1196e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood if (mAGpsDataConnectionState != AGPS_DATA_CONNECTION_CLOSED) { 119758bda987665af759c379cd494ff4873ac61acf29Mike Lockwood mConnMgr.stopUsingNetworkFeature( 119858bda987665af759c379cd494ff4873ac61acf29Mike Lockwood ConnectivityManager.TYPE_MOBILE, Phone.FEATURE_ENABLE_SUPL); 1199e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood native_agps_data_conn_closed(); 1200e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood mAGpsDataConnectionState = AGPS_DATA_CONNECTION_CLOSED; 120158bda987665af759c379cd494ff4873ac61acf29Mike Lockwood } 120258bda987665af759c379cd494ff4873ac61acf29Mike Lockwood break; 1203e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood case GPS_AGPS_DATA_CONNECTED: 1204e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood // Log.d(TAG, "GPS_AGPS_DATA_CONNECTED"); 120558bda987665af759c379cd494ff4873ac61acf29Mike Lockwood break; 1206e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood case GPS_AGPS_DATA_CONN_DONE: 1207e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood // Log.d(TAG, "GPS_AGPS_DATA_CONN_DONE"); 120858bda987665af759c379cd494ff4873ac61acf29Mike Lockwood break; 1209e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood case GPS_AGPS_DATA_CONN_FAILED: 1210e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood // Log.d(TAG, "GPS_AGPS_DATA_CONN_FAILED"); 121158bda987665af759c379cd494ff4873ac61acf29Mike Lockwood break; 121258bda987665af759c379cd494ff4873ac61acf29Mike Lockwood } 121358bda987665af759c379cd494ff4873ac61acf29Mike Lockwood } 121458bda987665af759c379cd494ff4873ac61acf29Mike Lockwood 1215b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood /** 1216b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood * called from native code to report NMEA data received 1217b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood */ 1218f602d362ba4bb3adbf1eb4e38a794fb14274293aMike Lockwood private void reportNmea(long timestamp) { 1219b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood synchronized(mListeners) { 1220b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood int size = mListeners.size(); 1221b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood if (size > 0) { 1222b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood // don't bother creating the String if we have no listeners 1223f602d362ba4bb3adbf1eb4e38a794fb14274293aMike Lockwood int length = native_read_nmea(mNmeaBuffer, mNmeaBuffer.length); 1224b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood String nmea = new String(mNmeaBuffer, 0, length); 1225b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood 1226b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood for (int i = 0; i < size; i++) { 1227b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood Listener listener = mListeners.get(i); 1228b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood try { 1229b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood listener.mListener.onNmeaReceived(timestamp, nmea); 1230b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood } catch (RemoteException e) { 1231b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood Log.w(TAG, "RemoteException in reportNmea"); 1232b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood mListeners.remove(listener); 1233b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood // adjust for size of list changing 1234b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood size--; 1235b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood } 1236b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood } 1237b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood } 1238b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood } 1239b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood } 1240b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood 124162a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood /** 124204598b67a58fad93e5060bb77756ba4863013aedMike Lockwood * called from native code to inform us what the GPS engine capabilities are 124304598b67a58fad93e5060bb77756ba4863013aedMike Lockwood */ 124404598b67a58fad93e5060bb77756ba4863013aedMike Lockwood private void setEngineCapabilities(int capabilities) { 124504598b67a58fad93e5060bb77756ba4863013aedMike Lockwood mEngineCapabilities = capabilities; 124604598b67a58fad93e5060bb77756ba4863013aedMike Lockwood } 124704598b67a58fad93e5060bb77756ba4863013aedMike Lockwood 124804598b67a58fad93e5060bb77756ba4863013aedMike Lockwood /** 124962a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood * called from native code to request XTRA data 125062a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood */ 12519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void xtraDownloadRequest() { 1252f5d95cbc1a6974afeb4d3155bdaa8dae55722a39Joe Onorato if (DEBUG) Log.d(TAG, "xtraDownloadRequest"); 125398e48691f738680fe59e7383a41458e7337daccdMike Lockwood sendMessage(DOWNLOAD_XTRA_DATA, 0, null); 12549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 125622d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie //============================================================= 125722d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie // NI Client support 125822d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie //============================================================= 125922d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie private final INetInitiatedListener mNetInitiatedListener = new INetInitiatedListener.Stub() { 126022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie // Sends a response for an NI reqeust to HAL. 126122d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie public boolean sendNiResponse(int notificationId, int userResponse) 126222d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie { 126322d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie // TODO Add Permission check 126422d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie 126522d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie StringBuilder extrasBuf = new StringBuilder(); 126622d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie 1267f5d95cbc1a6974afeb4d3155bdaa8dae55722a39Joe Onorato if (DEBUG) Log.d(TAG, "sendNiResponse, notifId: " + notificationId + 126822d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie ", response: " + userResponse); 126922d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie 127022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie native_send_ni_response(notificationId, userResponse); 127122d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie 127222d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie return true; 127322d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie } 127422d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie }; 127522d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie 127622d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie public INetInitiatedListener getNetInitiatedListener() { 127722d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie return mNetInitiatedListener; 127822d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie } 127922d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie 128022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie // Called by JNI function to report an NI request. 128122d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie @SuppressWarnings("deprecation") 128222d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie public void reportNiNotification( 128322d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie int notificationId, 128422d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie int niType, 128522d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie int notifyFlags, 128622d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie int timeout, 128722d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie int defaultResponse, 128822d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie String requestorId, 128922d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie String text, 129022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie int requestorIdEncoding, 129122d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie int textEncoding, 129222d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie String extras // Encoded extra data 129322d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie ) 129422d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie { 129522d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie Log.i(TAG, "reportNiNotification: entered"); 129622d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie Log.i(TAG, "notificationId: " + notificationId + 129722d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie ", niType: " + niType + 129822d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie ", notifyFlags: " + notifyFlags + 129922d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie ", timeout: " + timeout + 130022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie ", defaultResponse: " + defaultResponse); 130122d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie 130222d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie Log.i(TAG, "requestorId: " + requestorId + 130322d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie ", text: " + text + 130422d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie ", requestorIdEncoding: " + requestorIdEncoding + 130522d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie ", textEncoding: " + textEncoding); 130622d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie 130722d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie GpsNiNotification notification = new GpsNiNotification(); 130822d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie 130922d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie notification.notificationId = notificationId; 131022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie notification.niType = niType; 131122d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie notification.needNotify = (notifyFlags & GpsNetInitiatedHandler.GPS_NI_NEED_NOTIFY) != 0; 131222d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie notification.needVerify = (notifyFlags & GpsNetInitiatedHandler.GPS_NI_NEED_VERIFY) != 0; 131322d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie notification.privacyOverride = (notifyFlags & GpsNetInitiatedHandler.GPS_NI_PRIVACY_OVERRIDE) != 0; 131422d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie notification.timeout = timeout; 131522d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie notification.defaultResponse = defaultResponse; 131622d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie notification.requestorId = requestorId; 131722d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie notification.text = text; 131822d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie notification.requestorIdEncoding = requestorIdEncoding; 131922d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie notification.textEncoding = textEncoding; 132022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie 132122d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie // Process extras, assuming the format is 132222d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie // one of more lines of "key = value" 132322d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie Bundle bundle = new Bundle(); 132422d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie 132522d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie if (extras == null) extras = ""; 132622d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie Properties extraProp = new Properties(); 132722d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie 132822d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie try { 132922d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie extraProp.load(new StringBufferInputStream(extras)); 133022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie } 133122d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie catch (IOException e) 133222d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie { 133322d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie Log.e(TAG, "reportNiNotification cannot parse extras data: " + extras); 133422d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie } 133522d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie 133622d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie for (Entry<Object, Object> ent : extraProp.entrySet()) 133722d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie { 133822d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie bundle.putString((String) ent.getKey(), (String) ent.getValue()); 133922d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie } 134022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie 134122d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie notification.extras = bundle; 134222d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie 134322d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie mNIHandler.handleNiNotification(notification); 134422d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie } 134522d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie 134698e48691f738680fe59e7383a41458e7337daccdMike Lockwood private void sendMessage(int message, int arg, Object obj) { 134798e48691f738680fe59e7383a41458e7337daccdMike Lockwood // hold a wake lock while messages are pending 134898e48691f738680fe59e7383a41458e7337daccdMike Lockwood synchronized (mWakeLock) { 134998e48691f738680fe59e7383a41458e7337daccdMike Lockwood mPendingMessageBits |= (1 << message); 135098e48691f738680fe59e7383a41458e7337daccdMike Lockwood mWakeLock.acquire(); 135198e48691f738680fe59e7383a41458e7337daccdMike Lockwood mHandler.removeMessages(message); 135298e48691f738680fe59e7383a41458e7337daccdMike Lockwood Message m = Message.obtain(mHandler, message); 135398e48691f738680fe59e7383a41458e7337daccdMike Lockwood m.arg1 = arg; 135498e48691f738680fe59e7383a41458e7337daccdMike Lockwood m.obj = obj; 135598e48691f738680fe59e7383a41458e7337daccdMike Lockwood mHandler.sendMessage(m); 135698e48691f738680fe59e7383a41458e7337daccdMike Lockwood } 135798e48691f738680fe59e7383a41458e7337daccdMike Lockwood } 135898e48691f738680fe59e7383a41458e7337daccdMike Lockwood 135962a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood private final class ProviderHandler extends Handler { 136062a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood @Override 136162a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood public void handleMessage(Message msg) 136262a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood { 136398e48691f738680fe59e7383a41458e7337daccdMike Lockwood int message = msg.what; 136498e48691f738680fe59e7383a41458e7337daccdMike Lockwood switch (message) { 136562a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood case ENABLE: 136662a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood if (msg.arg1 == 1) { 136762a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood handleEnable(); 136862a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood } else { 136962a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood handleDisable(); 13709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 137162a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood break; 137262a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood case ENABLE_TRACKING: 137362a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood handleEnableLocationTracking(msg.arg1 == 1); 137462a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood break; 137503ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood case REQUEST_SINGLE_SHOT: 137603ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood handleRequestSingleShot(); 137703ca216ac19ea4e7afcb183c20c7c780f0d97756Mike Lockwood break; 137862a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood case UPDATE_NETWORK_STATE: 137962a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood handleUpdateNetworkState(msg.arg1, (NetworkInfo)msg.obj); 138062a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood break; 138162a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood case INJECT_NTP_TIME: 138262a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood handleInjectNtpTime(); 138362a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood break; 138462a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood case DOWNLOAD_XTRA_DATA: 13851a1cd3a878b6389c097e34d114b60cf953edaeaaMike Lockwood if (mSupportsXtra) { 138662a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood handleDownloadXtraData(); 13879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 138862a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood break; 138962a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood case UPDATE_LOCATION: 139062a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood handleUpdateLocation((Location)msg.obj); 139162a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood break; 139262a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood case ADD_LISTENER: 139362a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood handleAddListener(msg.arg1); 139462a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood break; 139562a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood case REMOVE_LISTENER: 139662a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood handleRemoveListener(msg.arg1); 139762a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood break; 13989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 139998e48691f738680fe59e7383a41458e7337daccdMike Lockwood // release wake lock if no messages are pending 140098e48691f738680fe59e7383a41458e7337daccdMike Lockwood synchronized (mWakeLock) { 140198e48691f738680fe59e7383a41458e7337daccdMike Lockwood mPendingMessageBits &= ~(1 << message); 140298e48691f738680fe59e7383a41458e7337daccdMike Lockwood if (message == ADD_LISTENER || message == REMOVE_LISTENER) { 140398e48691f738680fe59e7383a41458e7337daccdMike Lockwood mPendingListenerMessages--; 140498e48691f738680fe59e7383a41458e7337daccdMike Lockwood } 140598e48691f738680fe59e7383a41458e7337daccdMike Lockwood if (mPendingMessageBits == 0 && mPendingListenerMessages == 0) { 140698e48691f738680fe59e7383a41458e7337daccdMike Lockwood mWakeLock.release(); 140798e48691f738680fe59e7383a41458e7337daccdMike Lockwood } 140898e48691f738680fe59e7383a41458e7337daccdMike Lockwood } 14099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 141062a8fc159ad8d8044f3cde6ee6d46e9cc56b823fMike Lockwood }; 14119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 141289096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood private final class GpsLocationProviderThread extends Thread { 141389096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood 141489096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood public GpsLocationProviderThread() { 141589096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood super("GpsLocationProvider"); 141689096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood } 141789096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood 141889096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood public void run() { 141989096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND); 142089096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood initialize(); 142189096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood Looper.prepare(); 142289096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood mHandler = new ProviderHandler(); 142389096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood // signal when we are initialized and ready to go 142489096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood mInitializedLatch.countDown(); 142589096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood Looper.loop(); 142689096317104722219f73a5c3cc424e6e98c90a61Mike Lockwood } 14279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 14289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // for GPS SV statistics 14309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int MAX_SVS = 32; 14319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int EPHEMERIS_MASK = 0; 14329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int ALMANAC_MASK = 1; 14339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int USED_FOR_FIX_MASK = 2; 14349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // preallocated arrays, to avoid memory allocation in reportStatus() 14369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mSvs[] = new int[MAX_SVS]; 14379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private float mSnrs[] = new float[MAX_SVS]; 14389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private float mSvElevations[] = new float[MAX_SVS]; 14399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private float mSvAzimuths[] = new float[MAX_SVS]; 14409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mSvMasks[] = new int[3]; 14419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mSvCount; 1442b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood // preallocated to avoid memory allocation in reportNmea() 1443b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood private byte[] mNmeaBuffer = new byte[120]; 14449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static { class_init_native(); } 14469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static native void class_init_native(); 14479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static native boolean native_is_supported(); 14489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 14499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native boolean native_init(); 14509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native void native_cleanup(); 145104598b67a58fad93e5060bb77756ba4863013aedMike Lockwood private native boolean native_set_position_mode(int mode, int recurrence, int min_interval, 145204598b67a58fad93e5060bb77756ba4863013aedMike Lockwood int preferred_accuracy, int preferred_time); 145304598b67a58fad93e5060bb77756ba4863013aedMike Lockwood private native boolean native_start(); 14549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native boolean native_stop(); 14559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native void native_delete_aiding_data(int flags); 14569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // returns number of SVs 14579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // mask[0] is ephemeris mask and mask[1] is almanac mask 14589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native int native_read_sv_status(int[] svs, float[] snrs, 14599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float[] elevations, float[] azimuths, int[] masks); 1460f602d362ba4bb3adbf1eb4e38a794fb14274293aMike Lockwood private native int native_read_nmea(byte[] buffer, int bufferSize); 1461d26ce0d903f5141a346d67b2b94437ef3e2880aaMike Lockwood private native void native_inject_location(double latitude, double longitude, float accuracy); 1462d26ce0d903f5141a346d67b2b94437ef3e2880aaMike Lockwood 14633c8fbdf5dd19fad0b3006557716ee1026d7d5899Fred Fettinger // XTRA Support 14649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native void native_inject_time(long time, long timeReference, int uncertainty); 14659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native boolean native_supports_xtra(); 14669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native void native_inject_xtra_data(byte[] data, int length); 1467105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project 14683c8fbdf5dd19fad0b3006557716ee1026d7d5899Fred Fettinger // DEBUG Support 14693c8fbdf5dd19fad0b3006557716ee1026d7d5899Fred Fettinger private native String native_get_internal_state(); 14703c8fbdf5dd19fad0b3006557716ee1026d7d5899Fred Fettinger 14713c8fbdf5dd19fad0b3006557716ee1026d7d5899Fred Fettinger // AGPS Support 1472e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood private native void native_agps_data_conn_open(String apn); 1473e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood private native void native_agps_data_conn_closed(); 1474e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood private native void native_agps_data_conn_failed(); 1475a9e546169b3c2c9c5f248d2f3abe3b934f48695dMike Lockwood private native void native_set_agps_server(int type, String hostname, int port); 147622d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie 147722d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie // Network-initiated (NI) Support 147822d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie private native void native_send_ni_response(int notificationId, int userResponse); 14799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1480