GpsLocationProvider.java revision a4903f254b4711c8fc0ac5f7e3d605f4dce34f35
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 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectpackage com.android.internal.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; 33d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwoodimport android.location.LocationProviderInterface; 3458bda987665af759c379cd494ff4873ac61acf29Mike Lockwoodimport android.net.ConnectivityManager; 3503d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwoodimport android.net.NetworkInfo; 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.net.SntpClient; 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.Bundle; 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.IBinder; 390528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwoodimport android.os.PowerManager; 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.RemoteException; 412f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwoodimport android.os.ServiceManager; 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.os.SystemClock; 43bcab8df83e6e769a7cbcc742e72b47d665998793Mike Lockwoodimport android.provider.Settings; 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Log; 452f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwoodimport android.util.SparseIntArray; 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 472f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwoodimport com.android.internal.app.IBatteryStats; 48105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Projectimport com.android.internal.telephony.Phone; 4922d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xieimport com.android.internal.location.GpsNetInitiatedHandler; 5022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xieimport com.android.internal.location.GpsNetInitiatedHandler.GpsNiNotification; 51105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.File; 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.FileInputStream; 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.IOException; 5522d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xieimport java.io.StringBufferInputStream; 56105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Projectimport java.net.InetAddress; 57105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Projectimport java.net.UnknownHostException; 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.ArrayList; 59f1218be2d8f68f3f445f3bc90e0eca01946a0ddfMike Lockwoodimport java.util.Date; 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.Properties; 6122d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xieimport java.util.Map.Entry; 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/** 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * A GPS implementation of LocationProvider used by LocationManager. 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@hide} 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 68d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwoodpublic class GpsLocationProvider implements LocationProviderInterface { 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final String TAG = "GpsLocationProvider"; 7129c84340a14e70419449628ab193d11b7a609e9aMike Lockwood 72f5d95cbc1a6974afeb4d3155bdaa8dae55722a39Joe Onorato private static final boolean DEBUG = false; 7329c84340a14e70419449628ab193d11b7a609e9aMike Lockwood private static final boolean VERBOSE = false; 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Broadcast intent action indicating that the GPS has either been 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * enabled or disabled. An intent extra provides this state as a boolean, 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * where {@code true} means enabled. 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #EXTRA_ENABLED 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@hide} 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final String GPS_ENABLED_CHANGE_ACTION = 849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "android.location.GPS_ENABLED_CHANGE"; 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Broadcast intent action indicating that the GPS has either started or 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * stopped receiving GPS fixes. An intent extra provides this state as a 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * boolean, where {@code true} means that the GPS is actively receiving fixes. 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @see #EXTRA_ENABLED 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@hide} 939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final String GPS_FIX_CHANGE_ACTION = 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "android.location.GPS_FIX_CHANGE"; 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The lookup key for a boolean that indicates whether GPS is enabled or 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * disabled. {@code true} means GPS is enabled. Retrieve it with 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@link android.content.Intent#getBooleanExtra(String,boolean)}. 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * {@hide} 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static final String EXTRA_ENABLED = "enabled"; 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 106105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project // these need to match GpsPositionMode enum in gps.h 107105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project private static final int GPS_POSITION_MODE_STANDALONE = 0; 108105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project private static final int GPS_POSITION_MODE_MS_BASED = 1; 109105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project private static final int GPS_POSITION_MODE_MS_ASSISTED = 2; 110105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // these need to match GpsStatusValue defines in gps.h 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_STATUS_NONE = 0; 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_STATUS_SESSION_BEGIN = 1; 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_STATUS_SESSION_END = 2; 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_STATUS_ENGINE_ON = 3; 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_STATUS_ENGINE_OFF = 4; 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 118e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood // these need to match GpsApgsStatusValue defines in gps.h 119e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood /** AGPS status event values. */ 120e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood private static final int GPS_REQUEST_AGPS_DATA_CONN = 1; 121e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood private static final int GPS_RELEASE_AGPS_DATA_CONN = 2; 122e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood private static final int GPS_AGPS_DATA_CONNECTED = 3; 123e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood private static final int GPS_AGPS_DATA_CONN_DONE = 4; 124e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood private static final int GPS_AGPS_DATA_CONN_FAILED = 5; 12558bda987665af759c379cd494ff4873ac61acf29Mike Lockwood 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // these need to match GpsLocationFlags enum in gps.h 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int LOCATION_INVALID = 0; 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int LOCATION_HAS_LAT_LONG = 1; 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int LOCATION_HAS_ALTITUDE = 2; 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int LOCATION_HAS_SPEED = 4; 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int LOCATION_HAS_BEARING = 8; 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int LOCATION_HAS_ACCURACY = 16; 133e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood 134e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood// IMPORTANT - the GPS_DELETE_* symbols here must match constants in gps.h 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_DELETE_EPHEMERIS = 0x0001; 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_DELETE_ALMANAC = 0x0002; 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_DELETE_POSITION = 0x0004; 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_DELETE_TIME = 0x0008; 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_DELETE_IONO = 0x0010; 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_DELETE_UTC = 0x0020; 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_DELETE_HEALTH = 0x0040; 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_DELETE_SVDIR = 0x0080; 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_DELETE_SVSTEER = 0x0100; 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_DELETE_SADATA = 0x0200; 1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_DELETE_RTI = 0x0400; 1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_DELETE_CELLDB_INFO = 0x8000; 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int GPS_DELETE_ALL = 0xFFFF; 1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 149e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood // these need to match AGpsType enum in gps.h 150e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood private static final int AGPS_TYPE_SUPL = 1; 151e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood private static final int AGPS_TYPE_C2K = 2; 152e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood 153e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood // for mAGpsDataConnectionState 154e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood private static final int AGPS_DATA_CONNECTION_CLOSED = 0; 155e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood private static final int AGPS_DATA_CONNECTION_OPENING = 1; 156e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood private static final int AGPS_DATA_CONNECTION_OPEN = 2; 15758bda987665af759c379cd494ff4873ac61acf29Mike Lockwood 1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final String PROPERTIES_FILE = "/etc/gps.conf"; 1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mLocationFlags = LOCATION_INVALID; 1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // current status 16315e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood private int mStatus = LocationProvider.TEMPORARILY_UNAVAILABLE; 1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // time for last status update 1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private long mStatusUpdateTime = SystemClock.elapsedRealtime(); 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // turn off GPS fix icon if we haven't received a fix in 10 seconds 1690632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood private static final long RECENT_FIX_TIMEOUT = 10; 17029c84340a14e70419449628ab193d11b7a609e9aMike Lockwood 17129c84340a14e70419449628ab193d11b7a609e9aMike Lockwood // number of fixes to receive before disabling GPS 17229c84340a14e70419449628ab193d11b7a609e9aMike Lockwood private static final int MIN_FIX_COUNT = 10; 1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1740632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood // stop trying if we do not receive a fix within 60 seconds 1750632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood private static final int NO_FIX_TIMEOUT = 60; 1760632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood 1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // true if we are enabled 1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mEnabled; 1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // true if we have network connectivity 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mNetworkAvailable; 1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 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 1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // requested frequency of fixes, in seconds 1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mFixInterval = 1; 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 19229c84340a14e70419449628ab193d11b7a609e9aMike Lockwood // number of fixes we have received since we started navigating 19329c84340a14e70419449628ab193d11b7a609e9aMike Lockwood private int mFixCount; 19429c84340a14e70419449628ab193d11b7a609e9aMike Lockwood 1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // true if we started navigation 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mStarted; 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // for calculating time to first fix 1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private long mFixRequestTime = 0; 2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // time to first fix for most recent session 2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mTTFF = 0; 2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // time we received our last fix 2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private long mLastFixTime; 2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // properties loaded from PROPERTIES_FILE 2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Properties mProperties; 2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private String mNtpServer; 208734d6031a662a275ec68627bd1258159041d44deMike Lockwood private String mSuplServerHost; 209734d6031a662a275ec68627bd1258159041d44deMike Lockwood private int mSuplServerPort; 210734d6031a662a275ec68627bd1258159041d44deMike Lockwood private String mC2KServerHost; 211734d6031a662a275ec68627bd1258159041d44deMike Lockwood private int mC2KServerPort; 2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 21315e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood private final Context mContext; 21415e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood private final ILocationManager mLocationManager; 2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Location mLocation = new Location(LocationManager.GPS_PROVIDER); 2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Bundle mLocationExtras = new Bundle(); 2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private ArrayList<Listener> mListeners = new ArrayList<Listener>(); 2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private GpsEventThread mEventThread; 2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private GpsNetworkThread mNetworkThread; 2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Object mNetworkThreadLock = new Object(); 221105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project 222e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood private String mAGpsApn; 223e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood private int mAGpsDataConnectionState; 2242f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood private final ConnectivityManager mConnMgr; 22522d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie private final GpsNetInitiatedHandler mNIHandler; 2262f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood 2270528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood // Wakelocks 2280528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood private final static String WAKELOCK_KEY = "GpsLocationProvider"; 2290528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood private final PowerManager.WakeLock mWakeLock; 2300528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood 23129c84340a14e70419449628ab193d11b7a609e9aMike Lockwood // Alarms 23229c84340a14e70419449628ab193d11b7a609e9aMike Lockwood private final static String ALARM_WAKEUP = "com.android.internal.location.ALARM_WAKEUP"; 2330632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood private final static String ALARM_TIMEOUT = "com.android.internal.location.ALARM_TIMEOUT"; 23429c84340a14e70419449628ab193d11b7a609e9aMike Lockwood private final AlarmManager mAlarmManager; 23529c84340a14e70419449628ab193d11b7a609e9aMike Lockwood private final PendingIntent mWakeupIntent; 2360632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood private final PendingIntent mTimeoutIntent; 23729c84340a14e70419449628ab193d11b7a609e9aMike Lockwood 2382f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood private final IBatteryStats mBatteryStats; 2392f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood private final SparseIntArray mClientUids = new SparseIntArray(); 240105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project 2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // how often to request NTP time, in milliseconds 2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // current setting 4 hours 243f1218be2d8f68f3f445f3bc90e0eca01946a0ddfMike Lockwood private static final long NTP_INTERVAL = 4*60*60*1000; 2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // how long to wait if we have a network error in NTP or XTRA downloading 2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // current setting - 5 minutes 246f1218be2d8f68f3f445f3bc90e0eca01946a0ddfMike Lockwood private static final long RETRY_INTERVAL = 5*60*1000; 247f1218be2d8f68f3f445f3bc90e0eca01946a0ddfMike Lockwood 248f1218be2d8f68f3f445f3bc90e0eca01946a0ddfMike Lockwood // to avoid injecting bad NTP time, we reject any time fixes that differ from system time 249f1218be2d8f68f3f445f3bc90e0eca01946a0ddfMike Lockwood // by more than 5 minutes. 250f1218be2d8f68f3f445f3bc90e0eca01946a0ddfMike Lockwood private static final long MAX_NTP_SYSTEM_TIME_OFFSET = 5*60*1000; 2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 25215e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood private final IGpsStatusProvider mGpsStatusProvider = new IGpsStatusProvider.Stub() { 25315e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood public void addGpsStatusListener(IGpsStatusListener listener) throws RemoteException { 25415e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood if (listener == null) { 25515e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood throw new NullPointerException("listener is null in addGpsStatusListener"); 25615e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 25715e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood 25815e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood synchronized(mListeners) { 25915e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood IBinder binder = listener.asBinder(); 26015e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood int size = mListeners.size(); 26115e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood for (int i = 0; i < size; i++) { 26215e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood Listener test = mListeners.get(i); 26315e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood if (binder.equals(test.mListener.asBinder())) { 26415e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood // listener already added 26515e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood return; 26615e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 26715e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 26815e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood 26915e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood Listener l = new Listener(listener); 27015e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood binder.linkToDeath(l, 0); 27115e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood mListeners.add(l); 27215e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 27315e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 27415e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood 27515e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood public void removeGpsStatusListener(IGpsStatusListener listener) { 27615e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood if (listener == null) { 27715e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood throw new NullPointerException("listener is null in addGpsStatusListener"); 27815e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 27915e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood 28015e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood synchronized(mListeners) { 28115e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood IBinder binder = listener.asBinder(); 28215e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood Listener l = null; 28315e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood int size = mListeners.size(); 28415e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood for (int i = 0; i < size && l == null; i++) { 28515e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood Listener test = mListeners.get(i); 28615e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood if (binder.equals(test.mListener.asBinder())) { 28715e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood l = test; 28815e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 28915e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 29015e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood 29115e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood if (l != null) { 29215e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood mListeners.remove(l); 29315e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood binder.unlinkToDeath(l, 0); 29415e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 29515e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 29615e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 29715e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood }; 29815e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood 29915e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood public IGpsStatusProvider getGpsStatusProvider() { 30015e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood return mGpsStatusProvider; 30115e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 30215e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood 30329c84340a14e70419449628ab193d11b7a609e9aMike Lockwood private final BroadcastReceiver mBroadcastReciever = new BroadcastReceiver() { 304105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project @Override public void onReceive(Context context, Intent intent) { 305105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project String action = intent.getAction(); 306105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project 30729c84340a14e70419449628ab193d11b7a609e9aMike Lockwood if (action.equals(ALARM_WAKEUP)) { 30829c84340a14e70419449628ab193d11b7a609e9aMike Lockwood if (DEBUG) Log.d(TAG, "ALARM_WAKEUP"); 30929c84340a14e70419449628ab193d11b7a609e9aMike Lockwood startNavigating(); 3100632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood } else if (action.equals(ALARM_TIMEOUT)) { 3110632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood if (DEBUG) Log.d(TAG, "ALARM_TIMEOUT"); 3120632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood hibernate(); 313105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project } 314105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project } 31529c84340a14e70419449628ab193d11b7a609e9aMike Lockwood }; 316105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project 3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static boolean isSupported() { 3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return native_is_supported(); 3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3214e50b78bda9cd58be61581d2886c88ff6348a1c1Mike Lockwood public GpsLocationProvider(Context context, ILocationManager locationManager) { 3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContext = context; 32315e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood mLocationManager = locationManager; 32422d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie mNIHandler= new GpsNetInitiatedHandler(context, this); 3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3260528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood // Create a wake lock 3270528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood PowerManager powerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE); 3280528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, WAKELOCK_KEY); 3290528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood 33029c84340a14e70419449628ab193d11b7a609e9aMike Lockwood mAlarmManager = (AlarmManager)mContext.getSystemService(Context.ALARM_SERVICE); 33129c84340a14e70419449628ab193d11b7a609e9aMike Lockwood mWakeupIntent = PendingIntent.getBroadcast(mContext, 0, new Intent(ALARM_WAKEUP), 0); 3320632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood mTimeoutIntent = PendingIntent.getBroadcast(mContext, 0, new Intent(ALARM_TIMEOUT), 0); 33329c84340a14e70419449628ab193d11b7a609e9aMike Lockwood 334105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project IntentFilter intentFilter = new IntentFilter(); 33529c84340a14e70419449628ab193d11b7a609e9aMike Lockwood intentFilter.addAction(ALARM_WAKEUP); 3360632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood intentFilter.addAction(ALARM_TIMEOUT); 33729c84340a14e70419449628ab193d11b7a609e9aMike Lockwood context.registerReceiver(mBroadcastReciever, intentFilter); 338105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project 33958bda987665af759c379cd494ff4873ac61acf29Mike Lockwood mConnMgr = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE); 34058bda987665af759c379cd494ff4873ac61acf29Mike Lockwood 3412f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood // Battery statistics service to be notified when GPS turns on or off 3422f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood mBatteryStats = IBatteryStats.Stub.asInterface(ServiceManager.getService("batteryinfo")); 3432f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood 3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mProperties = new Properties(); 3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project File file = new File(PROPERTIES_FILE); 3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project FileInputStream stream = new FileInputStream(file); 3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mProperties.load(stream); 3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project stream.close(); 3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNtpServer = mProperties.getProperty("NTP_SERVER", null); 351e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood 352734d6031a662a275ec68627bd1258159041d44deMike Lockwood mSuplServerHost = mProperties.getProperty("SUPL_HOST"); 353e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood String portString = mProperties.getProperty("SUPL_PORT"); 354734d6031a662a275ec68627bd1258159041d44deMike Lockwood if (mSuplServerHost != null && portString != null) { 355105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project try { 356734d6031a662a275ec68627bd1258159041d44deMike Lockwood mSuplServerPort = Integer.parseInt(portString); 357105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project } catch (NumberFormatException e) { 358e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood Log.e(TAG, "unable to parse SUPL_PORT: " + portString); 359e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood } 360e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood } 361e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood 362734d6031a662a275ec68627bd1258159041d44deMike Lockwood mC2KServerHost = mProperties.getProperty("C2K_HOST"); 363e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood portString = mProperties.getProperty("C2K_PORT"); 364734d6031a662a275ec68627bd1258159041d44deMike Lockwood if (mC2KServerHost != null && portString != null) { 365e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood try { 366734d6031a662a275ec68627bd1258159041d44deMike Lockwood mC2KServerPort = Integer.parseInt(portString); 367e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood } catch (NumberFormatException e) { 368e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood Log.e(TAG, "unable to parse C2K_PORT: " + portString); 369105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project } 370105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project } 3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (IOException e) { 3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.w(TAG, "Could not open GPS configuration file " + PROPERTIES_FILE); 3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 377d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood * Returns the name of this provider. 378d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood */ 379d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood public String getName() { 380d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood return LocationManager.GPS_PROVIDER; 381d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood } 382d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood 383d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood /** 3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns true if the provider requires access to a 3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * data network (e.g., the Internet), false otherwise. 3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean requiresNetwork() { 388a9e546169b3c2c9c5f248d2f3abe3b934f48695dMike Lockwood return true; 3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 39103d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood public void updateNetworkState(int state, NetworkInfo info) { 3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNetworkAvailable = (state == LocationProvider.AVAILABLE); 3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 394f5d95cbc1a6974afeb4d3155bdaa8dae55722a39Joe Onorato if (DEBUG) { 39503d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood Log.d(TAG, "updateNetworkState " + (mNetworkAvailable ? "available" : "unavailable") 39603d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood + " info: " + info); 3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 39803d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood 39903d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood if (info != null && info.getType() == ConnectivityManager.TYPE_MOBILE_SUPL 40003d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood && mAGpsDataConnectionState == AGPS_DATA_CONNECTION_OPENING) { 40103d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood String apnName = info.getExtraInfo(); 40203d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood if (mNetworkAvailable && apnName != null && apnName.length() > 0) { 40303d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood mAGpsApn = apnName; 40403d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood if (DEBUG) Log.d(TAG, "call native_agps_data_conn_open"); 40503d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood native_agps_data_conn_open(apnName); 40603d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood mAGpsDataConnectionState = AGPS_DATA_CONNECTION_OPEN; 40703d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood } else { 40803d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood if (DEBUG) Log.d(TAG, "call native_agps_data_conn_failed"); 40903d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood mAGpsApn = null; 41003d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood mAGpsDataConnectionState = AGPS_DATA_CONNECTION_CLOSED; 41103d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood native_agps_data_conn_failed(); 41203d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood } 41303d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood } 41403d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood 4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mNetworkAvailable && mNetworkThread != null && mEnabled) { 4169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // signal the network thread when the network becomes available 4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNetworkThread.signal(); 4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 422fd6e5f0dda50e113db4ccc55338b6c4f09da37a4Mike Lockwood * This is called to inform us when another location provider returns a location. 423fd6e5f0dda50e113db4ccc55338b6c4f09da37a4Mike Lockwood * Someday we might use this for network location injection to aid the GPS 424fd6e5f0dda50e113db4ccc55338b6c4f09da37a4Mike Lockwood */ 425fd6e5f0dda50e113db4ccc55338b6c4f09da37a4Mike Lockwood public void updateLocation(Location location) { 426d26ce0d903f5141a346d67b2b94437ef3e2880aaMike Lockwood if (location.hasAccuracy()) { 427d26ce0d903f5141a346d67b2b94437ef3e2880aaMike Lockwood native_inject_location(location.getLatitude(), location.getLongitude(), 428d26ce0d903f5141a346d67b2b94437ef3e2880aaMike Lockwood location.getAccuracy()); 429d26ce0d903f5141a346d67b2b94437ef3e2880aaMike Lockwood } 430fd6e5f0dda50e113db4ccc55338b6c4f09da37a4Mike Lockwood } 431fd6e5f0dda50e113db4ccc55338b6c4f09da37a4Mike Lockwood 432fd6e5f0dda50e113db4ccc55338b6c4f09da37a4Mike Lockwood /** 4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns true if the provider requires access to a 4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * satellite-based positioning system (e.g., GPS), false 4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * otherwise. 4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean requiresSatellite() { 4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns true if the provider requires access to an appropriate 4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * cellular network (e.g., to make use of cell tower IDs), false 4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * otherwise. 4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean requiresCell() { 4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns true if the use of this provider may result in a 4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * monetary charge to the user, false if use is free. It is up to 4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * each provider to give accurate information. 4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean hasMonetaryCost() { 4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns true if the provider is able to provide altitude 4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * information, false otherwise. A provider that reports altitude 4629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * under most circumstances but may occassionally not report it 4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * should return true. 4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean supportsAltitude() { 4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns true if the provider is able to provide speed 4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * information, false otherwise. A provider that reports speed 4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * under most circumstances but may occassionally not report it 4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * should return true. 4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean supportsSpeed() { 4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns true if the provider is able to provide bearing 4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * information, false otherwise. A provider that reports bearing 4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * under most circumstances but may occassionally not report it 4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * should return true. 4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean supportsBearing() { 4869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns the power requirement for this provider. 4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the power requirement for this provider, as one of the 4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * constants Criteria.POWER_REQUIREMENT_*. 4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getPowerRequirement() { 4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return Criteria.POWER_HIGH; 4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns the horizontal accuracy of this provider 5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the accuracy of location from this provider, as one 5039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * of the constants Criteria.ACCURACY_*. 5049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getAccuracy() { 5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return Criteria.ACCURACY_FINE; 5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 5109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Enables this provider. When enabled, calls to getStatus() 5114e50b78bda9cd58be61581d2886c88ff6348a1c1Mike Lockwood * must be handled. Hardware may be started up 5129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * when the provider is enabled. 5139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public synchronized void enable() { 515f5d95cbc1a6974afeb4d3155bdaa8dae55722a39Joe Onorato if (DEBUG) Log.d(TAG, "enable"); 5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mEnabled) return; 5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEnabled = native_init(); 5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mEnabled) { 520734d6031a662a275ec68627bd1258159041d44deMike Lockwood if (mSuplServerHost != null) { 521734d6031a662a275ec68627bd1258159041d44deMike Lockwood native_set_agps_server(AGPS_TYPE_SUPL, mSuplServerHost, mSuplServerPort); 522734d6031a662a275ec68627bd1258159041d44deMike Lockwood } 523734d6031a662a275ec68627bd1258159041d44deMike Lockwood if (mC2KServerHost != null) { 524734d6031a662a275ec68627bd1258159041d44deMike Lockwood native_set_agps_server(AGPS_TYPE_C2K, mC2KServerHost, mC2KServerPort); 525734d6031a662a275ec68627bd1258159041d44deMike Lockwood } 526734d6031a662a275ec68627bd1258159041d44deMike Lockwood 5279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // run event listener thread while we are enabled 5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEventThread = new GpsEventThread(); 5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEventThread.start(); 5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (requiresNetwork()) { 5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // run network thread for NTP and XTRA support 5339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mNetworkThread == null) { 5349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNetworkThread = new GpsNetworkThread(); 5359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNetworkThread.start(); 5369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNetworkThread.signal(); 5389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 5419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.w(TAG, "Failed to enable location provider"); 5429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Disables this provider. When disabled, calls to getStatus() 5474e50b78bda9cd58be61581d2886c88ff6348a1c1Mike Lockwood * need not be handled. Hardware may be shut 5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * down while the provider is disabled. 5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public synchronized void disable() { 551f5d95cbc1a6974afeb4d3155bdaa8dae55722a39Joe Onorato if (DEBUG) Log.d(TAG, "disable"); 5529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mEnabled) return; 5539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEnabled = false; 5559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project stopNavigating(); 5569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project native_disable(); 5579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // make sure our event thread exits 5599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mEventThread != null) { 5609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 5619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEventThread.join(); 5629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (InterruptedException e) { 5639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.w(TAG, "InterruptedException when joining mEventThread"); 5649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEventThread = null; 5669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mNetworkThread != null) { 5699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNetworkThread.setDone(); 5709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNetworkThread = null; 5719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 573cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood // do this before releasing wakelock 574cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood native_cleanup(); 575cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood 576d654f9f727b415b153c7190832db4b65f6943f32Mike Lockwood // The GpsEventThread does not wait for the GPS to shutdown 577d654f9f727b415b153c7190832db4b65f6943f32Mike Lockwood // so we need to report the GPS_STATUS_ENGINE_OFF event here 578d654f9f727b415b153c7190832db4b65f6943f32Mike Lockwood if (mNavigating) { 579cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood reportStatus(GPS_STATUS_SESSION_END); 580cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood } 581cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood if (mEngineOn) { 582d654f9f727b415b153c7190832db4b65f6943f32Mike Lockwood reportStatus(GPS_STATUS_ENGINE_OFF); 583d654f9f727b415b153c7190832db4b65f6943f32Mike Lockwood } 5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 586d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood public boolean isEnabled() { 587d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood return mEnabled; 588d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood } 589d03ff94fe58045b5bd1dd783fb98026778a4265dMike Lockwood 5909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getStatus(Bundle extras) { 5919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras != null) { 5929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project extras.putInt("satellites", mSvCount); 5939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mStatus; 5959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void updateStatus(int status, int svCount) { 5989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (status != mStatus || svCount != mSvCount) { 5999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStatus = status; 6009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSvCount = svCount; 6019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocationExtras.putInt("satellites", svCount); 6029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStatusUpdateTime = SystemClock.elapsedRealtime(); 6039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public long getStatusUpdateTime() { 6079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mStatusUpdateTime; 6089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void enableLocationTracking(boolean enable) { 6119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (enable) { 6129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTTFF = 0; 6139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLastFixTime = 0; 6149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project startNavigating(); 6159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 61629c84340a14e70419449628ab193d11b7a609e9aMike Lockwood mAlarmManager.cancel(mWakeupIntent); 6170632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood mAlarmManager.cancel(mTimeoutIntent); 6189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project stopNavigating(); 6199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setMinTime(long minTime) { 623f5d95cbc1a6974afeb4d3155bdaa8dae55722a39Joe Onorato if (DEBUG) Log.d(TAG, "setMinTime " + minTime); 6249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (minTime >= 0) { 6269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int interval = (int)(minTime/1000); 6279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (interval < 1) { 6289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project interval = 1; 6299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFixInterval = interval; 6319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final class Listener implements IBinder.DeathRecipient { 6359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final IGpsStatusListener mListener; 6369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int mSensors = 0; 6389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Listener(IGpsStatusListener listener) { 6409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mListener = listener; 6419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void binderDied() { 644f5d95cbc1a6974afeb4d3155bdaa8dae55722a39Joe Onorato if (DEBUG) Log.d(TAG, "GPS status listener died"); 6459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized(mListeners) { 6479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mListeners.remove(this); 6489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 649fff2fda0199dedbf1079454dca98a81190dce765Suchi Amalapurapu if (mListener != null) { 650fff2fda0199dedbf1079454dca98a81190dce765Suchi Amalapurapu mListener.asBinder().unlinkToDeath(this, 0); 651fff2fda0199dedbf1079454dca98a81190dce765Suchi Amalapurapu } 6529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6552f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood public void addListener(int uid) { 6562e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn synchronized(mListeners) { 6572e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn if (mClientUids.indexOfKey(uid) >= 0) { 6582e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn // Shouldn't be here -- already have this uid. 6592e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn Log.w(TAG, "Duplicate add listener for uid " + uid); 6602e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn return; 6612e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn } 6622e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn mClientUids.put(uid, 0); 6632e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn if (mNavigating) { 6642e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn try { 6652e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn mBatteryStats.noteStartGps(uid); 6662e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn } catch (RemoteException e) { 6672e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn Log.w(TAG, "RemoteException in addListener"); 6682e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn } 6692f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } 6702f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } 6712f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } 6722f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood 6732f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood public void removeListener(int uid) { 6742e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn synchronized(mListeners) { 6752e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn if (mClientUids.indexOfKey(uid) < 0) { 6762e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn // Shouldn't be here -- don't have this uid. 6772e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn Log.w(TAG, "Unneeded remove listener for uid " + uid); 6782e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn return; 6792e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn } 6802e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn mClientUids.delete(uid); 6812e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn if (mNavigating) { 6822e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn try { 6832e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn mBatteryStats.noteStopGps(uid); 6842e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn } catch (RemoteException e) { 6852e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn Log.w(TAG, "RemoteException in removeListener"); 6862e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn } 6872f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } 6882f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } 6892f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } 6902f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood 6919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean sendExtraCommand(String command, Bundle extras) { 6929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ("delete_aiding_data".equals(command)) { 6949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return deleteAidingData(extras); 6959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 69693bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood if ("force_time_injection".equals(command)) { 69793bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood return forceTimeInjection(); 69893bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood } 69993bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood if ("force_xtra_injection".equals(command)) { 70093bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood if (native_supports_xtra() && mNetworkThread != null) { 70193bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood xtraDownloadRequest(); 70293bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood return true; 70393bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood } 70493bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood return false; 70593bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood } 7069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.w(TAG, "sendExtraCommand: unknown command " + command); 7089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 7099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean deleteAidingData(Bundle extras) { 7129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int flags; 7139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras == null) { 7159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project flags = GPS_DELETE_ALL; 7169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 7179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project flags = 0; 7189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("ephemeris")) flags |= GPS_DELETE_EPHEMERIS; 7199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("almanac")) flags |= GPS_DELETE_ALMANAC; 7209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("position")) flags |= GPS_DELETE_POSITION; 7219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("time")) flags |= GPS_DELETE_TIME; 7229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("iono")) flags |= GPS_DELETE_IONO; 7239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("utc")) flags |= GPS_DELETE_UTC; 7249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("health")) flags |= GPS_DELETE_HEALTH; 7259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("svdir")) flags |= GPS_DELETE_SVDIR; 7269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("svsteer")) flags |= GPS_DELETE_SVSTEER; 7279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("sadata")) flags |= GPS_DELETE_SADATA; 7289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("rti")) flags |= GPS_DELETE_RTI; 7299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("celldb-info")) flags |= GPS_DELETE_CELLDB_INFO; 7309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("all")) flags |= GPS_DELETE_ALL; 7319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (flags != 0) { 7349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project native_delete_aiding_data(flags); 7359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 7369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 7399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 74193bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood private boolean forceTimeInjection() { 742f5d95cbc1a6974afeb4d3155bdaa8dae55722a39Joe Onorato if (DEBUG) Log.d(TAG, "forceTimeInjection"); 74393bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood if (mNetworkThread != null) { 74493bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood mNetworkThread.timeInjectRequest(); 74593bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood return true; 74693bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood } 74793bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood return false; 74893bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood } 74993bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood 7509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void startNavigating() { 7519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mStarted) { 75229c84340a14e70419449628ab193d11b7a609e9aMike Lockwood if (DEBUG) Log.d(TAG, "startNavigating"); 7539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStarted = true; 754bcab8df83e6e769a7cbcc742e72b47d665998793Mike Lockwood int positionMode; 7552bb99d1e2f0296dd8b09a451575f70f49da30a1bMike Lockwood if (Settings.Secure.getInt(mContext.getContentResolver(), 756660bbfcc54d48d5d32e64da683c76b9c372c19b1Mike Lockwood Settings.Secure.ASSISTED_GPS_ENABLED, 1) != 0) { 757bcab8df83e6e769a7cbcc742e72b47d665998793Mike Lockwood positionMode = GPS_POSITION_MODE_MS_BASED; 758bcab8df83e6e769a7cbcc742e72b47d665998793Mike Lockwood } else { 759bcab8df83e6e769a7cbcc742e72b47d665998793Mike Lockwood positionMode = GPS_POSITION_MODE_STANDALONE; 760bcab8df83e6e769a7cbcc742e72b47d665998793Mike Lockwood } 761bcab8df83e6e769a7cbcc742e72b47d665998793Mike Lockwood 762bcab8df83e6e769a7cbcc742e72b47d665998793Mike Lockwood if (!native_start(positionMode, false, mFixInterval)) { 7639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStarted = false; 7649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.e(TAG, "native_start failed in startNavigating()"); 7650632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood return; 7669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // reset SV count to zero 76915e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood updateStatus(LocationProvider.TEMPORARILY_UNAVAILABLE, 0); 77029c84340a14e70419449628ab193d11b7a609e9aMike Lockwood mFixCount = 0; 77129c84340a14e70419449628ab193d11b7a609e9aMike Lockwood mFixRequestTime = System.currentTimeMillis(); 7720632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood // set timer to give up if we do not receive a fix within NO_FIX_TIMEOUT 7730632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood // and our fix interval is not short 7740632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood if (mFixInterval >= NO_FIX_TIMEOUT) { 7750632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, 7760632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood SystemClock.elapsedRealtime() + NO_FIX_TIMEOUT * 1000, mTimeoutIntent); 7770632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood } 7789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void stopNavigating() { 78229c84340a14e70419449628ab193d11b7a609e9aMike Lockwood if (DEBUG) Log.d(TAG, "stopNavigating"); 7839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mStarted) { 7849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStarted = false; 7859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project native_stop(); 7869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTTFF = 0; 7879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLastFixTime = 0; 7889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocationFlags = LOCATION_INVALID; 7899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // reset SV count to zero 79115e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood updateStatus(LocationProvider.TEMPORARILY_UNAVAILABLE, 0); 7929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7950632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood private void hibernate() { 7960632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood // stop GPS until our next fix interval arrives 7970632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood stopNavigating(); 7980632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood mFixCount = 0; 7990632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood mAlarmManager.cancel(mTimeoutIntent); 8000632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood mAlarmManager.cancel(mWakeupIntent); 8010632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood long now = SystemClock.elapsedRealtime(); 8020632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, 8030632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood SystemClock.elapsedRealtime() + mFixInterval * 1000, mWakeupIntent); 8040632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood } 8050632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood 8069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 8079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * called from native code to update our position. 8089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 8099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void reportLocation(int flags, double latitude, double longitude, double altitude, 8109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float speed, float bearing, float accuracy, long timestamp) { 81129c84340a14e70419449628ab193d11b7a609e9aMike Lockwood if (VERBOSE) Log.v(TAG, "reportLocation lat: " + latitude + " long: " + longitude + 8129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project " timestamp: " + timestamp); 8139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLastFixTime = System.currentTimeMillis(); 8159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // report time to first fix 8169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mTTFF == 0 && (flags & LOCATION_HAS_LAT_LONG) == LOCATION_HAS_LAT_LONG) { 8179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTTFF = (int)(mLastFixTime - mFixRequestTime); 818f5d95cbc1a6974afeb4d3155bdaa8dae55722a39Joe Onorato if (DEBUG) Log.d(TAG, "TTFF: " + mTTFF); 8199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // notify status listeners 8219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized(mListeners) { 8229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int size = mListeners.size(); 8239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < size; i++) { 8249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Listener listener = mListeners.get(i); 8259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 8269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project listener.mListener.onFirstFix(mTTFF); 8279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 8289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.w(TAG, "RemoteException in stopNavigating"); 8299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mListeners.remove(listener); 8309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // adjust for size of list changing 8319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size--; 8329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mLocation) { 8389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocationFlags = flags; 8399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((flags & LOCATION_HAS_LAT_LONG) == LOCATION_HAS_LAT_LONG) { 8409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocation.setLatitude(latitude); 8419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocation.setLongitude(longitude); 8429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocation.setTime(timestamp); 8439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((flags & LOCATION_HAS_ALTITUDE) == LOCATION_HAS_ALTITUDE) { 8459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocation.setAltitude(altitude); 8469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 8479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocation.removeAltitude(); 8489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((flags & LOCATION_HAS_SPEED) == LOCATION_HAS_SPEED) { 8509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocation.setSpeed(speed); 8519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 8529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocation.removeSpeed(); 8539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((flags & LOCATION_HAS_BEARING) == LOCATION_HAS_BEARING) { 8559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocation.setBearing(bearing); 8569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 8579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocation.removeBearing(); 8589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((flags & LOCATION_HAS_ACCURACY) == LOCATION_HAS_ACCURACY) { 8609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocation.setAccuracy(accuracy); 8619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 8629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocation.removeAccuracy(); 8639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 86515e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood try { 866a4903f254b4711c8fc0ac5f7e3d605f4dce34f35Mike Lockwood mLocationManager.reportLocation(mLocation, false); 86715e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } catch (RemoteException e) { 86815e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood Log.e(TAG, "RemoteException calling reportLocation"); 86915e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 8709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 87215e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood if (mStarted && mStatus != LocationProvider.AVAILABLE) { 8730632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood mAlarmManager.cancel(mTimeoutIntent); 8749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // send an intent to notify that the GPS is receiving fixes. 8759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Intent intent = new Intent(GPS_FIX_CHANGE_ACTION); 8769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project intent.putExtra(EXTRA_ENABLED, true); 8779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContext.sendBroadcast(intent); 87815e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood updateStatus(LocationProvider.AVAILABLE, mSvCount); 8799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 88029c84340a14e70419449628ab193d11b7a609e9aMike Lockwood 88129c84340a14e70419449628ab193d11b7a609e9aMike Lockwood if (mFixCount++ >= MIN_FIX_COUNT && mFixInterval > 1) { 88229c84340a14e70419449628ab193d11b7a609e9aMike Lockwood if (DEBUG) Log.d(TAG, "exceeded MIN_FIX_COUNT"); 8830632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood hibernate(); 88429c84340a14e70419449628ab193d11b7a609e9aMike Lockwood } 8859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 8889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * called from native code to update our status 8899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 8909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void reportStatus(int status) { 89129c84340a14e70419449628ab193d11b7a609e9aMike Lockwood if (VERBOSE) Log.v(TAG, "reportStatus status: " + status); 8929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8932e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn synchronized(mListeners) { 8942e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn boolean wasNavigating = mNavigating; 895dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood 896cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood switch (status) { 897cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood case GPS_STATUS_SESSION_BEGIN: 898cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood mNavigating = true; 899271f9f172b241607b1ed39a7709c3ed47ee5dee7Mike Lockwood mEngineOn = true; 900cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood break; 901cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood case GPS_STATUS_SESSION_END: 902cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood mNavigating = false; 903cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood break; 904cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood case GPS_STATUS_ENGINE_ON: 905cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood mEngineOn = true; 906cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood break; 907cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood case GPS_STATUS_ENGINE_OFF: 908cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood mEngineOn = false; 909271f9f172b241607b1ed39a7709c3ed47ee5dee7Mike Lockwood mNavigating = false; 910cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood break; 911cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood } 912cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood 913cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood // beware, the events can come out of order 914cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood if ((mNavigating || mEngineOn) && !mWakeLock.isHeld()) { 9150528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood if (DEBUG) Log.d(TAG, "Acquiring wakelock"); 9160528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood mWakeLock.acquire(); 9170528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood } 918dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood 919dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood if (wasNavigating != mNavigating) { 920dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood int size = mListeners.size(); 921dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood for (int i = 0; i < size; i++) { 922dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood Listener listener = mListeners.get(i); 923dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood try { 924dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood if (mNavigating) { 925dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood listener.mListener.onGpsStarted(); 926dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood } else { 927dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood listener.mListener.onGpsStopped(); 928dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood } 929dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood } catch (RemoteException e) { 930dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood Log.w(TAG, "RemoteException in reportStatus"); 931dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood mListeners.remove(listener); 932dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood // adjust for size of list changing 933dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood size--; 934dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood } 935dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood } 936dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood 9372e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn try { 938dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood // update battery stats 939dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood for (int i=mClientUids.size() - 1; i >= 0; i--) { 940dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood int uid = mClientUids.keyAt(i); 941dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood if (mNavigating) { 942dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood mBatteryStats.noteStartGps(uid); 943dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood } else { 944dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood mBatteryStats.noteStopGps(uid); 945dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood } 9469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9472e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn } catch (RemoteException e) { 9482e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn Log.w(TAG, "RemoteException in reportStatus"); 9499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 951dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood // send an intent to notify that the GPS has been enabled or disabled. 952dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood Intent intent = new Intent(GPS_ENABLED_CHANGE_ACTION); 953dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood intent.putExtra(EXTRA_ENABLED, mNavigating); 954dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood mContext.sendBroadcast(intent); 9552f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } 9562f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood 957cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood // beware, the events can come out of order 958cf1d8cb36fade2bfbfb94af371de23684e0f7ac7Mike Lockwood if (!mNavigating && !mEngineOn && mWakeLock.isHeld()) { 9590528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood if (DEBUG) Log.d(TAG, "Releasing wakelock"); 9600528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood mWakeLock.release(); 9610528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood } 9629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 9669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * called from native code to update SV info 9679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 9689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void reportSvStatus() { 9699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int svCount = native_read_sv_status(mSvs, mSnrs, mSvElevations, mSvAzimuths, mSvMasks); 9719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized(mListeners) { 9739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int size = mListeners.size(); 9749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < size; i++) { 9759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Listener listener = mListeners.get(i); 9769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 9779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project listener.mListener.onSvStatusChanged(svCount, mSvs, mSnrs, 9789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSvElevations, mSvAzimuths, mSvMasks[EPHEMERIS_MASK], 9799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSvMasks[ALMANAC_MASK], mSvMasks[USED_FOR_FIX_MASK]); 9809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 9819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.w(TAG, "RemoteException in reportSvInfo"); 9829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mListeners.remove(listener); 9839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // adjust for size of list changing 9849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size--; 9859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 98929c84340a14e70419449628ab193d11b7a609e9aMike Lockwood if (VERBOSE) { 99029c84340a14e70419449628ab193d11b7a609e9aMike Lockwood Log.v(TAG, "SV count: " + svCount + 9919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project " ephemerisMask: " + Integer.toHexString(mSvMasks[EPHEMERIS_MASK]) + 9929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project " almanacMask: " + Integer.toHexString(mSvMasks[ALMANAC_MASK])); 9939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < svCount; i++) { 99429c84340a14e70419449628ab193d11b7a609e9aMike Lockwood Log.v(TAG, "sv: " + mSvs[i] + 9959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project " snr: " + (float)mSnrs[i]/10 + 9969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project " elev: " + mSvElevations[i] + 9979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project " azimuth: " + mSvAzimuths[i] + 9989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ((mSvMasks[EPHEMERIS_MASK] & (1 << (mSvs[i] - 1))) == 0 ? " " : " E") + 9999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ((mSvMasks[ALMANAC_MASK] & (1 << (mSvs[i] - 1))) == 0 ? " " : " A") + 10009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ((mSvMasks[USED_FOR_FIX_MASK] & (1 << (mSvs[i] - 1))) == 0 ? "" : "U")); 10019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 10049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project updateStatus(mStatus, svCount); 10059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 100615e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood if (mNavigating && mStatus == LocationProvider.AVAILABLE && mLastFixTime > 0 && 10070632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood System.currentTimeMillis() - mLastFixTime > RECENT_FIX_TIMEOUT * 1000) { 10089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // send an intent to notify that the GPS is no longer receiving fixes. 10099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Intent intent = new Intent(GPS_FIX_CHANGE_ACTION); 10109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project intent.putExtra(EXTRA_ENABLED, false); 10119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContext.sendBroadcast(intent); 101215e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood updateStatus(LocationProvider.TEMPORARILY_UNAVAILABLE, mSvCount); 10139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 101558bda987665af759c379cd494ff4873ac61acf29Mike Lockwood 101658bda987665af759c379cd494ff4873ac61acf29Mike Lockwood /** 1017e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood * called from native code to update AGPS status 101858bda987665af759c379cd494ff4873ac61acf29Mike Lockwood */ 1019e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood private void reportAGpsStatus(int type, int status) { 102058bda987665af759c379cd494ff4873ac61acf29Mike Lockwood switch (status) { 1021e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood case GPS_REQUEST_AGPS_DATA_CONN: 102258bda987665af759c379cd494ff4873ac61acf29Mike Lockwood int result = mConnMgr.startUsingNetworkFeature( 102358bda987665af759c379cd494ff4873ac61acf29Mike Lockwood ConnectivityManager.TYPE_MOBILE, Phone.FEATURE_ENABLE_SUPL); 102458bda987665af759c379cd494ff4873ac61acf29Mike Lockwood if (result == Phone.APN_ALREADY_ACTIVE) { 1025b362a9ab91bb4c05ef1d5c4e7019499257c7f849Mike Lockwood if (mAGpsApn != null) { 1026b362a9ab91bb4c05ef1d5c4e7019499257c7f849Mike Lockwood native_agps_data_conn_open(mAGpsApn); 1027b362a9ab91bb4c05ef1d5c4e7019499257c7f849Mike Lockwood mAGpsDataConnectionState = AGPS_DATA_CONNECTION_OPEN; 1028b362a9ab91bb4c05ef1d5c4e7019499257c7f849Mike Lockwood } else { 1029b362a9ab91bb4c05ef1d5c4e7019499257c7f849Mike Lockwood Log.e(TAG, "mAGpsApn not set when receiving Phone.APN_ALREADY_ACTIVE"); 1030b362a9ab91bb4c05ef1d5c4e7019499257c7f849Mike Lockwood native_agps_data_conn_failed(); 1031b362a9ab91bb4c05ef1d5c4e7019499257c7f849Mike Lockwood } 103258bda987665af759c379cd494ff4873ac61acf29Mike Lockwood } else if (result == Phone.APN_REQUEST_STARTED) { 1033e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood mAGpsDataConnectionState = AGPS_DATA_CONNECTION_OPENING; 103458bda987665af759c379cd494ff4873ac61acf29Mike Lockwood } else { 1035e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood native_agps_data_conn_failed(); 103658bda987665af759c379cd494ff4873ac61acf29Mike Lockwood } 103758bda987665af759c379cd494ff4873ac61acf29Mike Lockwood break; 1038e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood case GPS_RELEASE_AGPS_DATA_CONN: 1039e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood if (mAGpsDataConnectionState != AGPS_DATA_CONNECTION_CLOSED) { 104058bda987665af759c379cd494ff4873ac61acf29Mike Lockwood mConnMgr.stopUsingNetworkFeature( 104158bda987665af759c379cd494ff4873ac61acf29Mike Lockwood ConnectivityManager.TYPE_MOBILE, Phone.FEATURE_ENABLE_SUPL); 1042e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood native_agps_data_conn_closed(); 1043e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood mAGpsDataConnectionState = AGPS_DATA_CONNECTION_CLOSED; 104458bda987665af759c379cd494ff4873ac61acf29Mike Lockwood } 104558bda987665af759c379cd494ff4873ac61acf29Mike Lockwood break; 1046e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood case GPS_AGPS_DATA_CONNECTED: 1047e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood // Log.d(TAG, "GPS_AGPS_DATA_CONNECTED"); 104858bda987665af759c379cd494ff4873ac61acf29Mike Lockwood break; 1049e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood case GPS_AGPS_DATA_CONN_DONE: 1050e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood // Log.d(TAG, "GPS_AGPS_DATA_CONN_DONE"); 105158bda987665af759c379cd494ff4873ac61acf29Mike Lockwood break; 1052e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood case GPS_AGPS_DATA_CONN_FAILED: 1053e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood // Log.d(TAG, "GPS_AGPS_DATA_CONN_FAILED"); 105458bda987665af759c379cd494ff4873ac61acf29Mike Lockwood break; 105558bda987665af759c379cd494ff4873ac61acf29Mike Lockwood } 105658bda987665af759c379cd494ff4873ac61acf29Mike Lockwood } 105758bda987665af759c379cd494ff4873ac61acf29Mike Lockwood 1058b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood /** 1059b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood * called from native code to report NMEA data received 1060b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood */ 1061b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood private void reportNmea(int index, long timestamp) { 1062b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood synchronized(mListeners) { 1063b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood int size = mListeners.size(); 1064b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood if (size > 0) { 1065b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood // don't bother creating the String if we have no listeners 1066b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood int length = native_read_nmea(index, mNmeaBuffer, mNmeaBuffer.length); 1067b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood String nmea = new String(mNmeaBuffer, 0, length); 1068b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood 1069b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood for (int i = 0; i < size; i++) { 1070b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood Listener listener = mListeners.get(i); 1071b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood try { 1072b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood listener.mListener.onNmeaReceived(timestamp, nmea); 1073b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood } catch (RemoteException e) { 1074b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood Log.w(TAG, "RemoteException in reportNmea"); 1075b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood mListeners.remove(listener); 1076b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood // adjust for size of list changing 1077b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood size--; 1078b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood } 1079b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood } 1080b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood } 1081b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood } 1082b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood } 1083b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood 10849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void xtraDownloadRequest() { 1085f5d95cbc1a6974afeb4d3155bdaa8dae55722a39Joe Onorato if (DEBUG) Log.d(TAG, "xtraDownloadRequest"); 10869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mNetworkThread != null) { 10879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNetworkThread.xtraDownloadRequest(); 10889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 109122d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie //============================================================= 109222d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie // NI Client support 109322d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie //============================================================= 109422d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie private final INetInitiatedListener mNetInitiatedListener = new INetInitiatedListener.Stub() { 109522d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie // Sends a response for an NI reqeust to HAL. 109622d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie public boolean sendNiResponse(int notificationId, int userResponse) 109722d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie { 109822d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie // TODO Add Permission check 109922d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie 110022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie StringBuilder extrasBuf = new StringBuilder(); 110122d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie 1102f5d95cbc1a6974afeb4d3155bdaa8dae55722a39Joe Onorato if (DEBUG) Log.d(TAG, "sendNiResponse, notifId: " + notificationId + 110322d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie ", response: " + userResponse); 110422d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie 110522d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie native_send_ni_response(notificationId, userResponse); 110622d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie 110722d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie return true; 110822d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie } 110922d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie }; 111022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie 111122d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie public INetInitiatedListener getNetInitiatedListener() { 111222d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie return mNetInitiatedListener; 111322d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie } 111422d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie 111522d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie // Called by JNI function to report an NI request. 111622d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie @SuppressWarnings("deprecation") 111722d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie public void reportNiNotification( 111822d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie int notificationId, 111922d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie int niType, 112022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie int notifyFlags, 112122d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie int timeout, 112222d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie int defaultResponse, 112322d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie String requestorId, 112422d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie String text, 112522d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie int requestorIdEncoding, 112622d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie int textEncoding, 112722d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie String extras // Encoded extra data 112822d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie ) 112922d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie { 113022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie Log.i(TAG, "reportNiNotification: entered"); 113122d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie Log.i(TAG, "notificationId: " + notificationId + 113222d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie ", niType: " + niType + 113322d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie ", notifyFlags: " + notifyFlags + 113422d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie ", timeout: " + timeout + 113522d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie ", defaultResponse: " + defaultResponse); 113622d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie 113722d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie Log.i(TAG, "requestorId: " + requestorId + 113822d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie ", text: " + text + 113922d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie ", requestorIdEncoding: " + requestorIdEncoding + 114022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie ", textEncoding: " + textEncoding); 114122d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie 114222d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie GpsNiNotification notification = new GpsNiNotification(); 114322d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie 114422d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie notification.notificationId = notificationId; 114522d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie notification.niType = niType; 114622d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie notification.needNotify = (notifyFlags & GpsNetInitiatedHandler.GPS_NI_NEED_NOTIFY) != 0; 114722d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie notification.needVerify = (notifyFlags & GpsNetInitiatedHandler.GPS_NI_NEED_VERIFY) != 0; 114822d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie notification.privacyOverride = (notifyFlags & GpsNetInitiatedHandler.GPS_NI_PRIVACY_OVERRIDE) != 0; 114922d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie notification.timeout = timeout; 115022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie notification.defaultResponse = defaultResponse; 115122d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie notification.requestorId = requestorId; 115222d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie notification.text = text; 115322d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie notification.requestorIdEncoding = requestorIdEncoding; 115422d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie notification.textEncoding = textEncoding; 115522d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie 115622d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie // Process extras, assuming the format is 115722d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie // one of more lines of "key = value" 115822d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie Bundle bundle = new Bundle(); 115922d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie 116022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie if (extras == null) extras = ""; 116122d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie Properties extraProp = new Properties(); 116222d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie 116322d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie try { 116422d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie extraProp.load(new StringBufferInputStream(extras)); 116522d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie } 116622d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie catch (IOException e) 116722d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie { 116822d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie Log.e(TAG, "reportNiNotification cannot parse extras data: " + extras); 116922d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie } 117022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie 117122d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie for (Entry<Object, Object> ent : extraProp.entrySet()) 117222d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie { 117322d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie bundle.putString((String) ent.getKey(), (String) ent.getValue()); 117422d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie } 117522d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie 117622d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie notification.extras = bundle; 117722d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie 117822d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie mNIHandler.handleNiNotification(notification); 117922d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie } 118022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie 11819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private class GpsEventThread extends Thread { 11829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public GpsEventThread() { 11849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super("GpsEventThread"); 11859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void run() { 1188f5d95cbc1a6974afeb4d3155bdaa8dae55722a39Joe Onorato if (DEBUG) Log.d(TAG, "GpsEventThread starting"); 1189d654f9f727b415b153c7190832db4b65f6943f32Mike Lockwood // Exit as soon as disable() is called instead of waiting for the GPS to stop. 1190d654f9f727b415b153c7190832db4b65f6943f32Mike Lockwood while (mEnabled) { 11919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // this will wait for an event from the GPS, 11929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // which will be reported via reportLocation or reportStatus 11939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project native_wait_for_event(); 11949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1195f5d95cbc1a6974afeb4d3155bdaa8dae55722a39Joe Onorato if (DEBUG) Log.d(TAG, "GpsEventThread exiting"); 11969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private class GpsNetworkThread extends Thread { 12009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private long mNextNtpTime = 0; 12029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private long mNextXtraTime = 0; 120393bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood private boolean mTimeInjectRequested = false; 12049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mXtraDownloadRequested = false; 12059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mDone = false; 12069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public GpsNetworkThread() { 12089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super("GpsNetworkThread"); 12099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void run() { 12129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mNetworkThreadLock) { 12139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mDone) { 12149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project runLocked(); 12159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void runLocked() { 1220f5d95cbc1a6974afeb4d3155bdaa8dae55722a39Joe Onorato if (DEBUG) Log.d(TAG, "NetworkThread starting"); 12219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SntpClient client = new SntpClient(); 12239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project GpsXtraDownloader xtraDownloader = null; 12249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (native_supports_xtra()) { 12269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project xtraDownloader = new GpsXtraDownloader(mContext, mProperties); 12279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // thread exits after disable() is called 12309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (!mDone) { 12319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long waitTime = getWaitTime(); 12329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project do { 12339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (this) { 12349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 12359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mNetworkAvailable) { 1236f5d95cbc1a6974afeb4d3155bdaa8dae55722a39Joe Onorato if (DEBUG) Log.d(TAG, "NetworkThread wait for network"); 12379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project wait(); 12389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (waitTime > 0) { 1239f5d95cbc1a6974afeb4d3155bdaa8dae55722a39Joe Onorato if (DEBUG) { 12409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.d(TAG, "NetworkThread wait for " + 12419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project waitTime + "ms"); 12429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project wait(waitTime); 12449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (InterruptedException e) { 1246f5d95cbc1a6974afeb4d3155bdaa8dae55722a39Joe Onorato if (DEBUG) { 12479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.d(TAG, "InterruptedException in GpsNetworkThread"); 12489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project waitTime = getWaitTime(); 1252e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood } while (!mDone && ((!mXtraDownloadRequested && 1253a9e546169b3c2c9c5f248d2f3abe3b934f48695dMike Lockwood !mTimeInjectRequested && waitTime > 0) 12549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project || !mNetworkAvailable)); 1255f5d95cbc1a6974afeb4d3155bdaa8dae55722a39Joe Onorato if (DEBUG) Log.d(TAG, "NetworkThread out of wake loop"); 12569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mDone) { 12579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mNtpServer != null && 125893bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood (mTimeInjectRequested || mNextNtpTime <= System.currentTimeMillis())) { 1259f5d95cbc1a6974afeb4d3155bdaa8dae55722a39Joe Onorato if (DEBUG) { 12609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.d(TAG, "Requesting time from NTP server " + mNtpServer); 12619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 126293bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood mTimeInjectRequested = false; 12639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (client.requestTime(mNtpServer, 10000)) { 12649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long time = client.getNtpTime(); 12659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long timeReference = client.getNtpTimeReference(); 12669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int certainty = (int)(client.getRoundTripTime()/2); 1267f1218be2d8f68f3f445f3bc90e0eca01946a0ddfMike Lockwood long now = System.currentTimeMillis(); 1268f1218be2d8f68f3f445f3bc90e0eca01946a0ddfMike Lockwood long systemTimeOffset = time - now; 12699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1270f1218be2d8f68f3f445f3bc90e0eca01946a0ddfMike Lockwood Log.d(TAG, "NTP server returned: " 1271f1218be2d8f68f3f445f3bc90e0eca01946a0ddfMike Lockwood + time + " (" + new Date(time) 1272f1218be2d8f68f3f445f3bc90e0eca01946a0ddfMike Lockwood + ") reference: " + timeReference 1273f1218be2d8f68f3f445f3bc90e0eca01946a0ddfMike Lockwood + " certainty: " + certainty 1274f1218be2d8f68f3f445f3bc90e0eca01946a0ddfMike Lockwood + " system time offset: " + systemTimeOffset); 1275f1218be2d8f68f3f445f3bc90e0eca01946a0ddfMike Lockwood 1276f1218be2d8f68f3f445f3bc90e0eca01946a0ddfMike Lockwood // sanity check NTP time and do not use if it is too far from system time 1277f1218be2d8f68f3f445f3bc90e0eca01946a0ddfMike Lockwood if (systemTimeOffset < 0) { 1278f1218be2d8f68f3f445f3bc90e0eca01946a0ddfMike Lockwood systemTimeOffset = -systemTimeOffset; 1279f1218be2d8f68f3f445f3bc90e0eca01946a0ddfMike Lockwood } 1280f1218be2d8f68f3f445f3bc90e0eca01946a0ddfMike Lockwood if (systemTimeOffset < MAX_NTP_SYSTEM_TIME_OFFSET) { 1281f1218be2d8f68f3f445f3bc90e0eca01946a0ddfMike Lockwood native_inject_time(time, timeReference, certainty); 1282f1218be2d8f68f3f445f3bc90e0eca01946a0ddfMike Lockwood } else { 1283f1218be2d8f68f3f445f3bc90e0eca01946a0ddfMike Lockwood Log.e(TAG, "NTP time differs from system time by " + systemTimeOffset 1284f1218be2d8f68f3f445f3bc90e0eca01946a0ddfMike Lockwood + "ms. Ignoring."); 1285f1218be2d8f68f3f445f3bc90e0eca01946a0ddfMike Lockwood } 1286f1218be2d8f68f3f445f3bc90e0eca01946a0ddfMike Lockwood mNextNtpTime = now + NTP_INTERVAL; 12879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 1288f5d95cbc1a6974afeb4d3155bdaa8dae55722a39Joe Onorato if (DEBUG) Log.d(TAG, "requestTime failed"); 12899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNextNtpTime = System.currentTimeMillis() + RETRY_INTERVAL; 12909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((mXtraDownloadRequested || 12949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (mNextXtraTime > 0 && mNextXtraTime <= System.currentTimeMillis())) 12959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project && xtraDownloader != null) { 129693bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood mXtraDownloadRequested = false; 12979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project byte[] data = xtraDownloader.downloadXtraData(); 12989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (data != null) { 1299f5d95cbc1a6974afeb4d3155bdaa8dae55722a39Joe Onorato if (DEBUG) { 13009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.d(TAG, "calling native_inject_xtra_data"); 13019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project native_inject_xtra_data(data, data.length); 13039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNextXtraTime = 0; 13049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 13059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNextXtraTime = System.currentTimeMillis() + RETRY_INTERVAL; 13069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1310f5d95cbc1a6974afeb4d3155bdaa8dae55722a39Joe Onorato if (DEBUG) Log.d(TAG, "NetworkThread exiting"); 13119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized void xtraDownloadRequest() { 13149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mXtraDownloadRequested = true; 13159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project notify(); 13169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 131893bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood synchronized void timeInjectRequest() { 131993bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood mTimeInjectRequested = true; 132093bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood notify(); 132193bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood } 132293bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood 13239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized void signal() { 13249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project notify(); 13259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized void setDone() { 1328f5d95cbc1a6974afeb4d3155bdaa8dae55722a39Joe Onorato if (DEBUG) Log.d(TAG, "stopping NetworkThread"); 13299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDone = true; 13309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project notify(); 13319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private long getWaitTime() { 13349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long now = System.currentTimeMillis(); 13359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long waitTime = Long.MAX_VALUE; 13369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mNtpServer != null) { 13379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project waitTime = mNextNtpTime - now; 13389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mNextXtraTime != 0) { 13409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long xtraWaitTime = mNextXtraTime - now; 13419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (xtraWaitTime < waitTime) { 13429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project waitTime = xtraWaitTime; 13439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (waitTime < 0) { 13469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project waitTime = 0; 13479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return waitTime; 13499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // for GPS SV statistics 13539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int MAX_SVS = 32; 13549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int EPHEMERIS_MASK = 0; 13559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int ALMANAC_MASK = 1; 13569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int USED_FOR_FIX_MASK = 2; 13579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // preallocated arrays, to avoid memory allocation in reportStatus() 13599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mSvs[] = new int[MAX_SVS]; 13609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private float mSnrs[] = new float[MAX_SVS]; 13619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private float mSvElevations[] = new float[MAX_SVS]; 13629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private float mSvAzimuths[] = new float[MAX_SVS]; 13639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mSvMasks[] = new int[3]; 13649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mSvCount; 1365b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood // preallocated to avoid memory allocation in reportNmea() 1366b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood private byte[] mNmeaBuffer = new byte[120]; 13679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static { class_init_native(); } 13699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static native void class_init_native(); 13709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static native boolean native_is_supported(); 13719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native boolean native_init(); 13739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native void native_disable(); 13749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native void native_cleanup(); 1375105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project private native boolean native_start(int positionMode, boolean singleFix, int fixInterval); 13769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native boolean native_stop(); 13779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native void native_set_fix_frequency(int fixFrequency); 13789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native void native_delete_aiding_data(int flags); 13799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native void native_wait_for_event(); 13809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // returns number of SVs 13819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // mask[0] is ephemeris mask and mask[1] is almanac mask 13829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native int native_read_sv_status(int[] svs, float[] snrs, 13839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float[] elevations, float[] azimuths, int[] masks); 1384b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood private native int native_read_nmea(int index, byte[] buffer, int bufferSize); 1385d26ce0d903f5141a346d67b2b94437ef3e2880aaMike Lockwood private native void native_inject_location(double latitude, double longitude, float accuracy); 1386d26ce0d903f5141a346d67b2b94437ef3e2880aaMike Lockwood 13879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // XTRA Support 13889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native void native_inject_time(long time, long timeReference, int uncertainty); 13899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native boolean native_supports_xtra(); 13909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native void native_inject_xtra_data(byte[] data, int length); 1391105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project 1392e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood // AGPS Support 1393e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood private native void native_agps_data_conn_open(String apn); 1394e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood private native void native_agps_data_conn_closed(); 1395e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood private native void native_agps_data_conn_failed(); 1396a9e546169b3c2c9c5f248d2f3abe3b934f48695dMike Lockwood private native void native_set_agps_server(int type, String hostname, int port); 139722d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie 139822d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie // Network-initiated (NI) Support 139922d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie private native void native_send_ni_response(int notificationId, int userResponse); 14009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1401