GpsLocationProvider.java revision dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9
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; 2915e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwoodimport android.location.ILocationProvider; 3022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xieimport android.location.INetInitiatedListener; 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.location.Location; 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.location.LocationManager; 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.location.LocationProvider; 3458bda987665af759c379cd494ff4873ac61acf29Mike Lockwoodimport android.net.ConnectivityManager; 3503d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwoodimport android.net.NetworkInfo; 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.Config; 459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport android.util.Log; 462f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwoodimport android.util.SparseIntArray; 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 482f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwoodimport com.android.internal.app.IBatteryStats; 49105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Projectimport com.android.internal.telephony.Phone; 5022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xieimport com.android.internal.location.GpsNetInitiatedHandler; 5122d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xieimport com.android.internal.location.GpsNetInitiatedHandler.GpsNiNotification; 52105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.File; 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.FileInputStream; 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.io.IOException; 5622d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xieimport java.io.StringBufferInputStream; 57105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Projectimport java.net.InetAddress; 58105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Projectimport java.net.UnknownHostException; 599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectimport java.util.ArrayList; 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 */ 6815e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwoodpublic class GpsLocationProvider extends ILocationProvider.Stub { 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final String TAG = "GpsLocationProvider"; 7129c84340a14e70419449628ab193d11b7a609e9aMike Lockwood 7229c84340a14e70419449628ab193d11b7a609e9aMike Lockwood private static final boolean DEBUG = true; 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; 1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // requested frequency of fixes, in seconds 1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mFixInterval = 1; 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 18929c84340a14e70419449628ab193d11b7a609e9aMike Lockwood // number of fixes we have received since we started navigating 19029c84340a14e70419449628ab193d11b7a609e9aMike Lockwood private int mFixCount; 19129c84340a14e70419449628ab193d11b7a609e9aMike Lockwood 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // true if we started navigation 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mStarted; 1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // for calculating time to first fix 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private long mFixRequestTime = 0; 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // time to first fix for most recent session 1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mTTFF = 0; 1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // time we received our last fix 2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private long mLastFixTime; 2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // properties loaded from PROPERTIES_FILE 2039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Properties mProperties; 2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private String mNtpServer; 205734d6031a662a275ec68627bd1258159041d44deMike Lockwood private String mSuplServerHost; 206734d6031a662a275ec68627bd1258159041d44deMike Lockwood private int mSuplServerPort; 207734d6031a662a275ec68627bd1258159041d44deMike Lockwood private String mC2KServerHost; 208734d6031a662a275ec68627bd1258159041d44deMike Lockwood private int mC2KServerPort; 2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 21015e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood private final Context mContext; 21115e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood private final ILocationManager mLocationManager; 2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Location mLocation = new Location(LocationManager.GPS_PROVIDER); 2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Bundle mLocationExtras = new Bundle(); 2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private ArrayList<Listener> mListeners = new ArrayList<Listener>(); 2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private GpsEventThread mEventThread; 2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private GpsNetworkThread mNetworkThread; 2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private Object mNetworkThreadLock = new Object(); 218105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project 219e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood private String mAGpsApn; 220e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood private int mAGpsDataConnectionState; 2212f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood private final ConnectivityManager mConnMgr; 22222d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie private final GpsNetInitiatedHandler mNIHandler; 2232f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood 2240528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood // Wakelocks 2250528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood private final static String WAKELOCK_KEY = "GpsLocationProvider"; 2260528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood private final PowerManager.WakeLock mWakeLock; 2270528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood 22829c84340a14e70419449628ab193d11b7a609e9aMike Lockwood // Alarms 22929c84340a14e70419449628ab193d11b7a609e9aMike Lockwood private final static String ALARM_WAKEUP = "com.android.internal.location.ALARM_WAKEUP"; 2300632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood private final static String ALARM_TIMEOUT = "com.android.internal.location.ALARM_TIMEOUT"; 23129c84340a14e70419449628ab193d11b7a609e9aMike Lockwood private final AlarmManager mAlarmManager; 23229c84340a14e70419449628ab193d11b7a609e9aMike Lockwood private final PendingIntent mWakeupIntent; 2330632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood private final PendingIntent mTimeoutIntent; 23429c84340a14e70419449628ab193d11b7a609e9aMike Lockwood 2352f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood private final IBatteryStats mBatteryStats; 2362f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood private final SparseIntArray mClientUids = new SparseIntArray(); 237105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project 2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // how often to request NTP time, in milliseconds 2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // current setting 4 hours 2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final long NTP_INTERVAL = 4*60*60*1000; 2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // how long to wait if we have a network error in NTP or XTRA downloading 2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // current setting - 5 minutes 2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final long RETRY_INTERVAL = 5*60*1000; 2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 24515e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood private final IGpsStatusProvider mGpsStatusProvider = new IGpsStatusProvider.Stub() { 24615e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood public void addGpsStatusListener(IGpsStatusListener listener) throws RemoteException { 24715e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood if (listener == null) { 24815e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood throw new NullPointerException("listener is null in addGpsStatusListener"); 24915e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 25015e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood 25115e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood synchronized(mListeners) { 25215e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood IBinder binder = listener.asBinder(); 25315e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood int size = mListeners.size(); 25415e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood for (int i = 0; i < size; i++) { 25515e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood Listener test = mListeners.get(i); 25615e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood if (binder.equals(test.mListener.asBinder())) { 25715e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood // listener already added 25815e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood return; 25915e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 26015e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 26115e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood 26215e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood Listener l = new Listener(listener); 26315e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood binder.linkToDeath(l, 0); 26415e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood mListeners.add(l); 26515e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 26615e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 26715e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood 26815e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood public void removeGpsStatusListener(IGpsStatusListener listener) { 26915e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood if (listener == null) { 27015e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood throw new NullPointerException("listener is null in addGpsStatusListener"); 27115e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 27215e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood 27315e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood synchronized(mListeners) { 27415e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood IBinder binder = listener.asBinder(); 27515e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood Listener l = null; 27615e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood int size = mListeners.size(); 27715e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood for (int i = 0; i < size && l == null; i++) { 27815e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood Listener test = mListeners.get(i); 27915e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood if (binder.equals(test.mListener.asBinder())) { 28015e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood l = test; 28115e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 28215e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 28315e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood 28415e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood if (l != null) { 28515e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood mListeners.remove(l); 28615e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood binder.unlinkToDeath(l, 0); 28715e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 28815e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 28915e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 29015e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood }; 29115e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood 29215e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood public IGpsStatusProvider getGpsStatusProvider() { 29315e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood return mGpsStatusProvider; 29415e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 29515e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood 29629c84340a14e70419449628ab193d11b7a609e9aMike Lockwood private final BroadcastReceiver mBroadcastReciever = new BroadcastReceiver() { 297105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project @Override public void onReceive(Context context, Intent intent) { 298105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project String action = intent.getAction(); 299105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project 30029c84340a14e70419449628ab193d11b7a609e9aMike Lockwood if (action.equals(ALARM_WAKEUP)) { 30129c84340a14e70419449628ab193d11b7a609e9aMike Lockwood if (DEBUG) Log.d(TAG, "ALARM_WAKEUP"); 30229c84340a14e70419449628ab193d11b7a609e9aMike Lockwood startNavigating(); 3030632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood } else if (action.equals(ALARM_TIMEOUT)) { 3040632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood if (DEBUG) Log.d(TAG, "ALARM_TIMEOUT"); 3050632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood hibernate(); 306105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project } 307105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project } 30829c84340a14e70419449628ab193d11b7a609e9aMike Lockwood }; 309105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project 3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public static boolean isSupported() { 3119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return native_is_supported(); 3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3144e50b78bda9cd58be61581d2886c88ff6348a1c1Mike Lockwood public GpsLocationProvider(Context context, ILocationManager locationManager) { 3159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContext = context; 31615e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood mLocationManager = locationManager; 31722d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie mNIHandler= new GpsNetInitiatedHandler(context, this); 3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3190528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood // Create a wake lock 3200528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood PowerManager powerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE); 3210528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, WAKELOCK_KEY); 3220528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood 32329c84340a14e70419449628ab193d11b7a609e9aMike Lockwood mAlarmManager = (AlarmManager)mContext.getSystemService(Context.ALARM_SERVICE); 32429c84340a14e70419449628ab193d11b7a609e9aMike Lockwood mWakeupIntent = PendingIntent.getBroadcast(mContext, 0, new Intent(ALARM_WAKEUP), 0); 3250632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood mTimeoutIntent = PendingIntent.getBroadcast(mContext, 0, new Intent(ALARM_TIMEOUT), 0); 32629c84340a14e70419449628ab193d11b7a609e9aMike Lockwood 327105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project IntentFilter intentFilter = new IntentFilter(); 32829c84340a14e70419449628ab193d11b7a609e9aMike Lockwood intentFilter.addAction(ALARM_WAKEUP); 3290632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood intentFilter.addAction(ALARM_TIMEOUT); 33029c84340a14e70419449628ab193d11b7a609e9aMike Lockwood context.registerReceiver(mBroadcastReciever, intentFilter); 331105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project 33258bda987665af759c379cd494ff4873ac61acf29Mike Lockwood mConnMgr = (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE); 33358bda987665af759c379cd494ff4873ac61acf29Mike Lockwood 3342f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood // Battery statistics service to be notified when GPS turns on or off 3352f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood mBatteryStats = IBatteryStats.Stub.asInterface(ServiceManager.getService("batteryinfo")); 3362f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood 3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mProperties = new Properties(); 3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project File file = new File(PROPERTIES_FILE); 3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project FileInputStream stream = new FileInputStream(file); 3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mProperties.load(stream); 3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project stream.close(); 3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNtpServer = mProperties.getProperty("NTP_SERVER", null); 344e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood 345734d6031a662a275ec68627bd1258159041d44deMike Lockwood mSuplServerHost = mProperties.getProperty("SUPL_HOST"); 346e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood String portString = mProperties.getProperty("SUPL_PORT"); 347734d6031a662a275ec68627bd1258159041d44deMike Lockwood if (mSuplServerHost != null && portString != null) { 348105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project try { 349734d6031a662a275ec68627bd1258159041d44deMike Lockwood mSuplServerPort = Integer.parseInt(portString); 350105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project } catch (NumberFormatException e) { 351e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood Log.e(TAG, "unable to parse SUPL_PORT: " + portString); 352e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood } 353e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood } 354e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood 355734d6031a662a275ec68627bd1258159041d44deMike Lockwood mC2KServerHost = mProperties.getProperty("C2K_HOST"); 356e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood portString = mProperties.getProperty("C2K_PORT"); 357734d6031a662a275ec68627bd1258159041d44deMike Lockwood if (mC2KServerHost != null && portString != null) { 358e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood try { 359734d6031a662a275ec68627bd1258159041d44deMike Lockwood mC2KServerPort = Integer.parseInt(portString); 360e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood } catch (NumberFormatException e) { 361e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood Log.e(TAG, "unable to parse C2K_PORT: " + portString); 362105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project } 363105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project } 3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (IOException e) { 3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.w(TAG, "Could not open GPS configuration file " + PROPERTIES_FILE); 3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns true if the provider requires access to a 3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * data network (e.g., the Internet), false otherwise. 3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean requiresNetwork() { 374a9e546169b3c2c9c5f248d2f3abe3b934f48695dMike Lockwood return true; 3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 37703d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood public void updateNetworkState(int state, NetworkInfo info) { 3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNetworkAvailable = (state == LocationProvider.AVAILABLE); 3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Config.LOGD) { 38103d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood Log.d(TAG, "updateNetworkState " + (mNetworkAvailable ? "available" : "unavailable") 38203d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood + " info: " + info); 3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 38403d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood 38503d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood if (info != null && info.getType() == ConnectivityManager.TYPE_MOBILE_SUPL 38603d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood && mAGpsDataConnectionState == AGPS_DATA_CONNECTION_OPENING) { 38703d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood String apnName = info.getExtraInfo(); 38803d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood if (mNetworkAvailable && apnName != null && apnName.length() > 0) { 38903d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood mAGpsApn = apnName; 39003d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood if (DEBUG) Log.d(TAG, "call native_agps_data_conn_open"); 39103d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood native_agps_data_conn_open(apnName); 39203d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood mAGpsDataConnectionState = AGPS_DATA_CONNECTION_OPEN; 39303d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood } else { 39403d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood if (DEBUG) Log.d(TAG, "call native_agps_data_conn_failed"); 39503d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood mAGpsApn = null; 39603d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood mAGpsDataConnectionState = AGPS_DATA_CONNECTION_CLOSED; 39703d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood native_agps_data_conn_failed(); 39803d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood } 39903d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood } 40003d246779ea65fc2bd10d0b4f32620f45211133aMike Lockwood 4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mNetworkAvailable && mNetworkThread != null && mEnabled) { 4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // signal the network thread when the network becomes available 4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNetworkThread.signal(); 4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 408fd6e5f0dda50e113db4ccc55338b6c4f09da37a4Mike Lockwood * This is called to inform us when another location provider returns a location. 409fd6e5f0dda50e113db4ccc55338b6c4f09da37a4Mike Lockwood * Someday we might use this for network location injection to aid the GPS 410fd6e5f0dda50e113db4ccc55338b6c4f09da37a4Mike Lockwood */ 411fd6e5f0dda50e113db4ccc55338b6c4f09da37a4Mike Lockwood public void updateLocation(Location location) { 412d26ce0d903f5141a346d67b2b94437ef3e2880aaMike Lockwood if (location.hasAccuracy()) { 413d26ce0d903f5141a346d67b2b94437ef3e2880aaMike Lockwood native_inject_location(location.getLatitude(), location.getLongitude(), 414d26ce0d903f5141a346d67b2b94437ef3e2880aaMike Lockwood location.getAccuracy()); 415d26ce0d903f5141a346d67b2b94437ef3e2880aaMike Lockwood } 416fd6e5f0dda50e113db4ccc55338b6c4f09da37a4Mike Lockwood } 417fd6e5f0dda50e113db4ccc55338b6c4f09da37a4Mike Lockwood 418fd6e5f0dda50e113db4ccc55338b6c4f09da37a4Mike Lockwood /** 4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns true if the provider requires access to a 4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * satellite-based positioning system (e.g., GPS), false 4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * otherwise. 4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean requiresSatellite() { 4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns true if the provider requires access to an appropriate 4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * cellular network (e.g., to make use of cell tower IDs), false 4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * otherwise. 4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean requiresCell() { 4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns true if the use of this provider may result in a 4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * monetary charge to the user, false if use is free. It is up to 4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * each provider to give accurate information. 4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean hasMonetaryCost() { 4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns true if the provider is able to provide altitude 4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * information, false otherwise. A provider that reports altitude 4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * under most circumstances but may occassionally not report it 4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * should return true. 4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean supportsAltitude() { 4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns true if the provider is able to provide speed 4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * information, false otherwise. A provider that reports speed 4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * under most circumstances but may occassionally not report it 4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * should return true. 4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean supportsSpeed() { 4629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns true if the provider is able to provide bearing 4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * information, false otherwise. A provider that reports bearing 4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * under most circumstances but may occassionally not report it 4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * should return true. 4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean supportsBearing() { 4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns the power requirement for this provider. 4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the power requirement for this provider, as one of the 4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * constants Criteria.POWER_REQUIREMENT_*. 4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getPowerRequirement() { 4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return Criteria.POWER_HIGH; 4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns the horizontal accuracy of this provider 4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * @return the accuracy of location from this provider, as one 4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * of the constants Criteria.ACCURACY_*. 4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getAccuracy() { 4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return Criteria.ACCURACY_FINE; 4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Enables this provider. When enabled, calls to getStatus() 4974e50b78bda9cd58be61581d2886c88ff6348a1c1Mike Lockwood * must be handled. Hardware may be started up 4989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * when the provider is enabled. 4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public synchronized void enable() { 5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Config.LOGD) Log.d(TAG, "enable"); 5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mEnabled) return; 5039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEnabled = native_init(); 5049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mEnabled) { 506734d6031a662a275ec68627bd1258159041d44deMike Lockwood if (mSuplServerHost != null) { 507734d6031a662a275ec68627bd1258159041d44deMike Lockwood native_set_agps_server(AGPS_TYPE_SUPL, mSuplServerHost, mSuplServerPort); 508734d6031a662a275ec68627bd1258159041d44deMike Lockwood } 509734d6031a662a275ec68627bd1258159041d44deMike Lockwood if (mC2KServerHost != null) { 510734d6031a662a275ec68627bd1258159041d44deMike Lockwood native_set_agps_server(AGPS_TYPE_C2K, mC2KServerHost, mC2KServerPort); 511734d6031a662a275ec68627bd1258159041d44deMike Lockwood } 512734d6031a662a275ec68627bd1258159041d44deMike Lockwood 5139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // run event listener thread while we are enabled 5149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEventThread = new GpsEventThread(); 5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEventThread.start(); 5169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (requiresNetwork()) { 5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // run network thread for NTP and XTRA support 5199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mNetworkThread == null) { 5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNetworkThread = new GpsNetworkThread(); 5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNetworkThread.start(); 5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNetworkThread.signal(); 5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 5279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.w(TAG, "Failed to enable location provider"); 5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Disables this provider. When disabled, calls to getStatus() 5334e50b78bda9cd58be61581d2886c88ff6348a1c1Mike Lockwood * need not be handled. Hardware may be shut 5349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * down while the provider is disabled. 5359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public synchronized void disable() { 5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Config.LOGD) Log.d(TAG, "disable"); 5389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mEnabled) return; 5399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEnabled = false; 5419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project stopNavigating(); 5429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project native_disable(); 5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // make sure our event thread exits 5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mEventThread != null) { 5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEventThread.join(); 5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (InterruptedException e) { 5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.w(TAG, "InterruptedException when joining mEventThread"); 5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mEventThread = null; 5529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mNetworkThread != null) { 5559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNetworkThread.setDone(); 5569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNetworkThread = null; 5579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 559d654f9f727b415b153c7190832db4b65f6943f32Mike Lockwood // The GpsEventThread does not wait for the GPS to shutdown 560d654f9f727b415b153c7190832db4b65f6943f32Mike Lockwood // so we need to report the GPS_STATUS_ENGINE_OFF event here 561d654f9f727b415b153c7190832db4b65f6943f32Mike Lockwood if (mNavigating) { 562d654f9f727b415b153c7190832db4b65f6943f32Mike Lockwood reportStatus(GPS_STATUS_ENGINE_OFF); 563d654f9f727b415b153c7190832db4b65f6943f32Mike Lockwood } 564d654f9f727b415b153c7190832db4b65f6943f32Mike Lockwood 5659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project native_cleanup(); 5669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean isEnabled() { 5699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mEnabled; 5709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public int getStatus(Bundle extras) { 5739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras != null) { 5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project extras.putInt("satellites", mSvCount); 5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mStatus; 5779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void updateStatus(int status, int svCount) { 5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (status != mStatus || svCount != mSvCount) { 5819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStatus = status; 5829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSvCount = svCount; 5839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocationExtras.putInt("satellites", svCount); 5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStatusUpdateTime = SystemClock.elapsedRealtime(); 5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public long getStatusUpdateTime() { 5899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mStatusUpdateTime; 5909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void enableLocationTracking(boolean enable) { 5939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (enable) { 5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTTFF = 0; 5959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLastFixTime = 0; 5969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project startNavigating(); 5979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 59829c84340a14e70419449628ab193d11b7a609e9aMike Lockwood mAlarmManager.cancel(mWakeupIntent); 5990632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood mAlarmManager.cancel(mTimeoutIntent); 6009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project stopNavigating(); 6019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void setMinTime(long minTime) { 6059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Config.LOGD) Log.d(TAG, "setMinTime " + minTime); 6069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (minTime >= 0) { 6089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int interval = (int)(minTime/1000); 6099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (interval < 1) { 6109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project interval = 1; 6119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFixInterval = interval; 6139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private final class Listener implements IBinder.DeathRecipient { 6179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project final IGpsStatusListener mListener; 6189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int mSensors = 0; 6209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Listener(IGpsStatusListener listener) { 6229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mListener = listener; 6239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void binderDied() { 6269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Config.LOGD) Log.d(TAG, "GPS status listener died"); 6279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized(mListeners) { 6299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mListeners.remove(this); 6309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 631fff2fda0199dedbf1079454dca98a81190dce765Suchi Amalapurapu if (mListener != null) { 632fff2fda0199dedbf1079454dca98a81190dce765Suchi Amalapurapu mListener.asBinder().unlinkToDeath(this, 0); 633fff2fda0199dedbf1079454dca98a81190dce765Suchi Amalapurapu } 6349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6372f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood public void addListener(int uid) { 6382e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn synchronized(mListeners) { 6392e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn if (mClientUids.indexOfKey(uid) >= 0) { 6402e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn // Shouldn't be here -- already have this uid. 6412e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn Log.w(TAG, "Duplicate add listener for uid " + uid); 6422e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn return; 6432e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn } 6442e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn mClientUids.put(uid, 0); 6452e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn if (mNavigating) { 6462e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn try { 6472e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn mBatteryStats.noteStartGps(uid); 6482e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn } catch (RemoteException e) { 6492e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn Log.w(TAG, "RemoteException in addListener"); 6502e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn } 6512f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } 6522f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } 6532f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } 6542f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood 6552f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood public void removeListener(int uid) { 6562e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn synchronized(mListeners) { 6572e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn if (mClientUids.indexOfKey(uid) < 0) { 6582e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn // Shouldn't be here -- don't have this uid. 6592e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn Log.w(TAG, "Unneeded remove listener for uid " + uid); 6602e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn return; 6612e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn } 6622e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn mClientUids.delete(uid); 6632e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn if (mNavigating) { 6642e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn try { 6652e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn mBatteryStats.noteStopGps(uid); 6662e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn } catch (RemoteException e) { 6672e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn Log.w(TAG, "RemoteException in removeListener"); 6682e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn } 6692f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } 6702f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } 6712f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } 6722f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood 6739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public boolean sendExtraCommand(String command, Bundle extras) { 6749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ("delete_aiding_data".equals(command)) { 6769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return deleteAidingData(extras); 6779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 67893bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood if ("force_time_injection".equals(command)) { 67993bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood return forceTimeInjection(); 68093bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood } 68193bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood if ("force_xtra_injection".equals(command)) { 68293bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood if (native_supports_xtra() && mNetworkThread != null) { 68393bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood xtraDownloadRequest(); 68493bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood return true; 68593bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood } 68693bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood return false; 68793bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood } 6889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.w(TAG, "sendExtraCommand: unknown command " + command); 6909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 6919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean deleteAidingData(Bundle extras) { 6949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int flags; 6959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras == null) { 6979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project flags = GPS_DELETE_ALL; 6989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 6999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project flags = 0; 7009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("ephemeris")) flags |= GPS_DELETE_EPHEMERIS; 7019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("almanac")) flags |= GPS_DELETE_ALMANAC; 7029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("position")) flags |= GPS_DELETE_POSITION; 7039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("time")) flags |= GPS_DELETE_TIME; 7049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("iono")) flags |= GPS_DELETE_IONO; 7059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("utc")) flags |= GPS_DELETE_UTC; 7069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("health")) flags |= GPS_DELETE_HEALTH; 7079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("svdir")) flags |= GPS_DELETE_SVDIR; 7089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("svsteer")) flags |= GPS_DELETE_SVSTEER; 7099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("sadata")) flags |= GPS_DELETE_SADATA; 7109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("rti")) flags |= GPS_DELETE_RTI; 7119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("celldb-info")) flags |= GPS_DELETE_CELLDB_INFO; 7129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (extras.getBoolean("all")) flags |= GPS_DELETE_ALL; 7139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (flags != 0) { 7169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project native_delete_aiding_data(flags); 7179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 7189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 7219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 72393bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood private boolean forceTimeInjection() { 72493bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood if (Config.LOGD) Log.d(TAG, "forceTimeInjection"); 72593bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood if (mNetworkThread != null) { 72693bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood mNetworkThread.timeInjectRequest(); 72793bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood return true; 72893bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood } 72993bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood return false; 73093bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood } 73193bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood 7329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void startNavigating() { 7339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mStarted) { 73429c84340a14e70419449628ab193d11b7a609e9aMike Lockwood if (DEBUG) Log.d(TAG, "startNavigating"); 7359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStarted = true; 736bcab8df83e6e769a7cbcc742e72b47d665998793Mike Lockwood int positionMode; 7372bb99d1e2f0296dd8b09a451575f70f49da30a1bMike Lockwood if (Settings.Secure.getInt(mContext.getContentResolver(), 738660bbfcc54d48d5d32e64da683c76b9c372c19b1Mike Lockwood Settings.Secure.ASSISTED_GPS_ENABLED, 1) != 0) { 739bcab8df83e6e769a7cbcc742e72b47d665998793Mike Lockwood positionMode = GPS_POSITION_MODE_MS_BASED; 740bcab8df83e6e769a7cbcc742e72b47d665998793Mike Lockwood } else { 741bcab8df83e6e769a7cbcc742e72b47d665998793Mike Lockwood positionMode = GPS_POSITION_MODE_STANDALONE; 742bcab8df83e6e769a7cbcc742e72b47d665998793Mike Lockwood } 743bcab8df83e6e769a7cbcc742e72b47d665998793Mike Lockwood 744bcab8df83e6e769a7cbcc742e72b47d665998793Mike Lockwood if (!native_start(positionMode, false, mFixInterval)) { 7459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStarted = false; 7469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.e(TAG, "native_start failed in startNavigating()"); 7470632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood return; 7489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // reset SV count to zero 75115e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood updateStatus(LocationProvider.TEMPORARILY_UNAVAILABLE, 0); 75229c84340a14e70419449628ab193d11b7a609e9aMike Lockwood mFixCount = 0; 75329c84340a14e70419449628ab193d11b7a609e9aMike Lockwood mFixRequestTime = System.currentTimeMillis(); 7540632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood // set timer to give up if we do not receive a fix within NO_FIX_TIMEOUT 7550632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood // and our fix interval is not short 7560632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood if (mFixInterval >= NO_FIX_TIMEOUT) { 7570632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, 7580632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood SystemClock.elapsedRealtime() + NO_FIX_TIMEOUT * 1000, mTimeoutIntent); 7590632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood } 7609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void stopNavigating() { 76429c84340a14e70419449628ab193d11b7a609e9aMike Lockwood if (DEBUG) Log.d(TAG, "stopNavigating"); 7659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mStarted) { 7669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mStarted = false; 7679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project native_stop(); 7689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTTFF = 0; 7699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLastFixTime = 0; 7709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocationFlags = LOCATION_INVALID; 7719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // reset SV count to zero 77315e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood updateStatus(LocationProvider.TEMPORARILY_UNAVAILABLE, 0); 7749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 7769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7770632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood private void hibernate() { 7780632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood // stop GPS until our next fix interval arrives 7790632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood stopNavigating(); 7800632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood mFixCount = 0; 7810632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood mAlarmManager.cancel(mTimeoutIntent); 7820632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood mAlarmManager.cancel(mWakeupIntent); 7830632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood long now = SystemClock.elapsedRealtime(); 7840632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood mAlarmManager.set(AlarmManager.ELAPSED_REALTIME_WAKEUP, 7850632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood SystemClock.elapsedRealtime() + mFixInterval * 1000, mWakeupIntent); 7860632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood } 7870632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood 7889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 7899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * called from native code to update our position. 7909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 7919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void reportLocation(int flags, double latitude, double longitude, double altitude, 7929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float speed, float bearing, float accuracy, long timestamp) { 79329c84340a14e70419449628ab193d11b7a609e9aMike Lockwood if (VERBOSE) Log.v(TAG, "reportLocation lat: " + latitude + " long: " + longitude + 7949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project " timestamp: " + timestamp); 7959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 7969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLastFixTime = System.currentTimeMillis(); 7979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // report time to first fix 7989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mTTFF == 0 && (flags & LOCATION_HAS_LAT_LONG) == LOCATION_HAS_LAT_LONG) { 7999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mTTFF = (int)(mLastFixTime - mFixRequestTime); 8009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Config.LOGD) Log.d(TAG, "TTFF: " + mTTFF); 8019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // notify status listeners 8039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized(mListeners) { 8049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int size = mListeners.size(); 8059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < size; i++) { 8069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Listener listener = mListeners.get(i); 8079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 8089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project listener.mListener.onFirstFix(mTTFF); 8099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 8109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.w(TAG, "RemoteException in stopNavigating"); 8119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mListeners.remove(listener); 8129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // adjust for size of list changing 8139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size--; 8149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mLocation) { 8209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocationFlags = flags; 8219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((flags & LOCATION_HAS_LAT_LONG) == LOCATION_HAS_LAT_LONG) { 8229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocation.setLatitude(latitude); 8239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocation.setLongitude(longitude); 8249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocation.setTime(timestamp); 8259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((flags & LOCATION_HAS_ALTITUDE) == LOCATION_HAS_ALTITUDE) { 8279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocation.setAltitude(altitude); 8289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 8299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocation.removeAltitude(); 8309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((flags & LOCATION_HAS_SPEED) == LOCATION_HAS_SPEED) { 8329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocation.setSpeed(speed); 8339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 8349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocation.removeSpeed(); 8359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((flags & LOCATION_HAS_BEARING) == LOCATION_HAS_BEARING) { 8379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocation.setBearing(bearing); 8389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 8399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocation.removeBearing(); 8409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((flags & LOCATION_HAS_ACCURACY) == LOCATION_HAS_ACCURACY) { 8429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocation.setAccuracy(accuracy); 8439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 8449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocation.removeAccuracy(); 8459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 84715e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood try { 848275555c8eb3fb5df6e7320873b88b77cdde85a9eMike Lockwood mLocationManager.reportLocation(mLocation); 84915e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } catch (RemoteException e) { 85015e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood Log.e(TAG, "RemoteException calling reportLocation"); 85115e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood } 8529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 85415e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood if (mStarted && mStatus != LocationProvider.AVAILABLE) { 8550632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood mAlarmManager.cancel(mTimeoutIntent); 8569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // send an intent to notify that the GPS is receiving fixes. 8579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Intent intent = new Intent(GPS_FIX_CHANGE_ACTION); 8589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project intent.putExtra(EXTRA_ENABLED, true); 8599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContext.sendBroadcast(intent); 86015e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood updateStatus(LocationProvider.AVAILABLE, mSvCount); 8619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 86229c84340a14e70419449628ab193d11b7a609e9aMike Lockwood 86329c84340a14e70419449628ab193d11b7a609e9aMike Lockwood if (mFixCount++ >= MIN_FIX_COUNT && mFixInterval > 1) { 86429c84340a14e70419449628ab193d11b7a609e9aMike Lockwood if (DEBUG) Log.d(TAG, "exceeded MIN_FIX_COUNT"); 8650632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood hibernate(); 86629c84340a14e70419449628ab193d11b7a609e9aMike Lockwood } 8679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 8689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 8709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * called from native code to update our status 8719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 8729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void reportStatus(int status) { 87329c84340a14e70419449628ab193d11b7a609e9aMike Lockwood if (VERBOSE) Log.v(TAG, "reportStatus status: " + status); 8749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 8752e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn synchronized(mListeners) { 8762e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn boolean wasNavigating = mNavigating; 8772e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn mNavigating = (status == GPS_STATUS_SESSION_BEGIN); 878dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood 879dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood if (mNavigating && !mWakeLock.isHeld()) { 8800528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood if (DEBUG) Log.d(TAG, "Acquiring wakelock"); 8810528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood mWakeLock.acquire(); 8820528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood } 883dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood 884dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood if (wasNavigating != mNavigating) { 885dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood int size = mListeners.size(); 886dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood for (int i = 0; i < size; i++) { 887dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood Listener listener = mListeners.get(i); 888dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood try { 889dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood if (mNavigating) { 890dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood listener.mListener.onGpsStarted(); 891dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood } else { 892dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood listener.mListener.onGpsStopped(); 893dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood } 894dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood } catch (RemoteException e) { 895dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood Log.w(TAG, "RemoteException in reportStatus"); 896dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood mListeners.remove(listener); 897dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood // adjust for size of list changing 898dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood size--; 899dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood } 900dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood } 901dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood 9022e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn try { 903dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood // update battery stats 904dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood for (int i=mClientUids.size() - 1; i >= 0; i--) { 905dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood int uid = mClientUids.keyAt(i); 906dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood if (mNavigating) { 907dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood mBatteryStats.noteStartGps(uid); 908dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood } else { 909dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood mBatteryStats.noteStopGps(uid); 910dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood } 9119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9122e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn } catch (RemoteException e) { 9132e418428987132ea66533cbc05f9c526eb59519aDianne Hackborn Log.w(TAG, "RemoteException in reportStatus"); 9149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 916dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood // send an intent to notify that the GPS has been enabled or disabled. 917dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood Intent intent = new Intent(GPS_ENABLED_CHANGE_ACTION); 918dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood intent.putExtra(EXTRA_ENABLED, mNavigating); 919dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood mContext.sendBroadcast(intent); 9202f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood } 9212f82c4eb0b4d315481ad79725ad6f52c5ec69685Mike Lockwood 922dbd6fd8ebb60dd7bb243f9c78db994a8e7e5b5c9Mike Lockwood if (status == GPS_STATUS_ENGINE_OFF && mWakeLock.isHeld()) { 9230528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood if (DEBUG) Log.d(TAG, "Releasing wakelock"); 9240528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood mWakeLock.release(); 9250528b9b26a9d64ba43acd0e334638303d514b8ebMike Lockwood } 9269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /** 9309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * called from native code to update SV info 9319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 9329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void reportSvStatus() { 9339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int svCount = native_read_sv_status(mSvs, mSnrs, mSvElevations, mSvAzimuths, mSvMasks); 9359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized(mListeners) { 9379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int size = mListeners.size(); 9389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < size; i++) { 9399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Listener listener = mListeners.get(i); 9409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 9419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project listener.mListener.onSvStatusChanged(svCount, mSvs, mSnrs, 9429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSvElevations, mSvAzimuths, mSvMasks[EPHEMERIS_MASK], 9439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mSvMasks[ALMANAC_MASK], mSvMasks[USED_FOR_FIX_MASK]); 9449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (RemoteException e) { 9459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.w(TAG, "RemoteException in reportSvInfo"); 9469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mListeners.remove(listener); 9479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // adjust for size of list changing 9489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project size--; 9499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 95329c84340a14e70419449628ab193d11b7a609e9aMike Lockwood if (VERBOSE) { 95429c84340a14e70419449628ab193d11b7a609e9aMike Lockwood Log.v(TAG, "SV count: " + svCount + 9559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project " ephemerisMask: " + Integer.toHexString(mSvMasks[EPHEMERIS_MASK]) + 9569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project " almanacMask: " + Integer.toHexString(mSvMasks[ALMANAC_MASK])); 9579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project for (int i = 0; i < svCount; i++) { 95829c84340a14e70419449628ab193d11b7a609e9aMike Lockwood Log.v(TAG, "sv: " + mSvs[i] + 9599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project " snr: " + (float)mSnrs[i]/10 + 9609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project " elev: " + mSvElevations[i] + 9619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project " azimuth: " + mSvAzimuths[i] + 9629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ((mSvMasks[EPHEMERIS_MASK] & (1 << (mSvs[i] - 1))) == 0 ? " " : " E") + 9639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ((mSvMasks[ALMANAC_MASK] & (1 << (mSvs[i] - 1))) == 0 ? " " : " A") + 9649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ((mSvMasks[USED_FOR_FIX_MASK] & (1 << (mSvs[i] - 1))) == 0 ? "" : "U")); 9659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 9689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project updateStatus(mStatus, svCount); 9699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 97015e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood if (mNavigating && mStatus == LocationProvider.AVAILABLE && mLastFixTime > 0 && 9710632ca7bbea5dbd89a584cc3cd6a0630a767e94bMike Lockwood System.currentTimeMillis() - mLastFixTime > RECENT_FIX_TIMEOUT * 1000) { 9729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // send an intent to notify that the GPS is no longer receiving fixes. 9739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Intent intent = new Intent(GPS_FIX_CHANGE_ACTION); 9749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project intent.putExtra(EXTRA_ENABLED, false); 9759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mContext.sendBroadcast(intent); 97615e3d0f082d551f8819fbe4b0d502cc108627876Mike Lockwood updateStatus(LocationProvider.TEMPORARILY_UNAVAILABLE, mSvCount); 9779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 9789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 97958bda987665af759c379cd494ff4873ac61acf29Mike Lockwood 98058bda987665af759c379cd494ff4873ac61acf29Mike Lockwood /** 981e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood * called from native code to update AGPS status 98258bda987665af759c379cd494ff4873ac61acf29Mike Lockwood */ 983e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood private void reportAGpsStatus(int type, int status) { 98458bda987665af759c379cd494ff4873ac61acf29Mike Lockwood switch (status) { 985e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood case GPS_REQUEST_AGPS_DATA_CONN: 98658bda987665af759c379cd494ff4873ac61acf29Mike Lockwood int result = mConnMgr.startUsingNetworkFeature( 98758bda987665af759c379cd494ff4873ac61acf29Mike Lockwood ConnectivityManager.TYPE_MOBILE, Phone.FEATURE_ENABLE_SUPL); 98858bda987665af759c379cd494ff4873ac61acf29Mike Lockwood if (result == Phone.APN_ALREADY_ACTIVE) { 989b362a9ab91bb4c05ef1d5c4e7019499257c7f849Mike Lockwood if (mAGpsApn != null) { 990b362a9ab91bb4c05ef1d5c4e7019499257c7f849Mike Lockwood native_agps_data_conn_open(mAGpsApn); 991b362a9ab91bb4c05ef1d5c4e7019499257c7f849Mike Lockwood mAGpsDataConnectionState = AGPS_DATA_CONNECTION_OPEN; 992b362a9ab91bb4c05ef1d5c4e7019499257c7f849Mike Lockwood } else { 993b362a9ab91bb4c05ef1d5c4e7019499257c7f849Mike Lockwood Log.e(TAG, "mAGpsApn not set when receiving Phone.APN_ALREADY_ACTIVE"); 994b362a9ab91bb4c05ef1d5c4e7019499257c7f849Mike Lockwood native_agps_data_conn_failed(); 995b362a9ab91bb4c05ef1d5c4e7019499257c7f849Mike Lockwood } 99658bda987665af759c379cd494ff4873ac61acf29Mike Lockwood } else if (result == Phone.APN_REQUEST_STARTED) { 997e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood mAGpsDataConnectionState = AGPS_DATA_CONNECTION_OPENING; 99858bda987665af759c379cd494ff4873ac61acf29Mike Lockwood } else { 999e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood native_agps_data_conn_failed(); 100058bda987665af759c379cd494ff4873ac61acf29Mike Lockwood } 100158bda987665af759c379cd494ff4873ac61acf29Mike Lockwood break; 1002e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood case GPS_RELEASE_AGPS_DATA_CONN: 1003e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood if (mAGpsDataConnectionState != AGPS_DATA_CONNECTION_CLOSED) { 100458bda987665af759c379cd494ff4873ac61acf29Mike Lockwood mConnMgr.stopUsingNetworkFeature( 100558bda987665af759c379cd494ff4873ac61acf29Mike Lockwood ConnectivityManager.TYPE_MOBILE, Phone.FEATURE_ENABLE_SUPL); 1006e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood native_agps_data_conn_closed(); 1007e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood mAGpsDataConnectionState = AGPS_DATA_CONNECTION_CLOSED; 100858bda987665af759c379cd494ff4873ac61acf29Mike Lockwood } 100958bda987665af759c379cd494ff4873ac61acf29Mike Lockwood break; 1010e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood case GPS_AGPS_DATA_CONNECTED: 1011e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood // Log.d(TAG, "GPS_AGPS_DATA_CONNECTED"); 101258bda987665af759c379cd494ff4873ac61acf29Mike Lockwood break; 1013e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood case GPS_AGPS_DATA_CONN_DONE: 1014e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood // Log.d(TAG, "GPS_AGPS_DATA_CONN_DONE"); 101558bda987665af759c379cd494ff4873ac61acf29Mike Lockwood break; 1016e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood case GPS_AGPS_DATA_CONN_FAILED: 1017e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood // Log.d(TAG, "GPS_AGPS_DATA_CONN_FAILED"); 101858bda987665af759c379cd494ff4873ac61acf29Mike Lockwood break; 101958bda987665af759c379cd494ff4873ac61acf29Mike Lockwood } 102058bda987665af759c379cd494ff4873ac61acf29Mike Lockwood } 102158bda987665af759c379cd494ff4873ac61acf29Mike Lockwood 1022b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood /** 1023b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood * called from native code to report NMEA data received 1024b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood */ 1025b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood private void reportNmea(int index, long timestamp) { 1026b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood synchronized(mListeners) { 1027b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood int size = mListeners.size(); 1028b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood if (size > 0) { 1029b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood // don't bother creating the String if we have no listeners 1030b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood int length = native_read_nmea(index, mNmeaBuffer, mNmeaBuffer.length); 1031b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood String nmea = new String(mNmeaBuffer, 0, length); 1032b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood 1033b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood for (int i = 0; i < size; i++) { 1034b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood Listener listener = mListeners.get(i); 1035b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood try { 1036b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood listener.mListener.onNmeaReceived(timestamp, nmea); 1037b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood } catch (RemoteException e) { 1038b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood Log.w(TAG, "RemoteException in reportNmea"); 1039b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood mListeners.remove(listener); 1040b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood // adjust for size of list changing 1041b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood size--; 1042b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood } 1043b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood } 1044b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood } 1045b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood } 1046b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood } 1047b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood 10489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private void xtraDownloadRequest() { 10499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Config.LOGD) Log.d(TAG, "xtraDownloadRequest"); 10509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mNetworkThread != null) { 10519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNetworkThread.xtraDownloadRequest(); 10529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 10549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 105522d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie //============================================================= 105622d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie // NI Client support 105722d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie //============================================================= 105822d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie private final INetInitiatedListener mNetInitiatedListener = new INetInitiatedListener.Stub() { 105922d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie // Sends a response for an NI reqeust to HAL. 106022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie public boolean sendNiResponse(int notificationId, int userResponse) 106122d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie { 106222d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie // TODO Add Permission check 106322d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie 106422d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie StringBuilder extrasBuf = new StringBuilder(); 106522d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie 106622d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie if (Config.LOGD) Log.d(TAG, "sendNiResponse, notifId: " + notificationId + 106722d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie ", response: " + userResponse); 106822d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie 106922d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie native_send_ni_response(notificationId, userResponse); 107022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie 107122d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie return true; 107222d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie } 107322d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie }; 107422d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie 107522d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie public INetInitiatedListener getNetInitiatedListener() { 107622d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie return mNetInitiatedListener; 107722d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie } 107822d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie 107922d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie // Called by JNI function to report an NI request. 108022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie @SuppressWarnings("deprecation") 108122d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie public void reportNiNotification( 108222d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie int notificationId, 108322d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie int niType, 108422d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie int notifyFlags, 108522d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie int timeout, 108622d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie int defaultResponse, 108722d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie String requestorId, 108822d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie String text, 108922d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie int requestorIdEncoding, 109022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie int textEncoding, 109122d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie String extras // Encoded extra data 109222d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie ) 109322d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie { 109422d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie Log.i(TAG, "reportNiNotification: entered"); 109522d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie Log.i(TAG, "notificationId: " + notificationId + 109622d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie ", niType: " + niType + 109722d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie ", notifyFlags: " + notifyFlags + 109822d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie ", timeout: " + timeout + 109922d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie ", defaultResponse: " + defaultResponse); 110022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie 110122d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie Log.i(TAG, "requestorId: " + requestorId + 110222d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie ", text: " + text + 110322d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie ", requestorIdEncoding: " + requestorIdEncoding + 110422d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie ", textEncoding: " + textEncoding); 110522d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie 110622d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie GpsNiNotification notification = new GpsNiNotification(); 110722d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie 110822d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie notification.notificationId = notificationId; 110922d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie notification.niType = niType; 111022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie notification.needNotify = (notifyFlags & GpsNetInitiatedHandler.GPS_NI_NEED_NOTIFY) != 0; 111122d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie notification.needVerify = (notifyFlags & GpsNetInitiatedHandler.GPS_NI_NEED_VERIFY) != 0; 111222d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie notification.privacyOverride = (notifyFlags & GpsNetInitiatedHandler.GPS_NI_PRIVACY_OVERRIDE) != 0; 111322d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie notification.timeout = timeout; 111422d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie notification.defaultResponse = defaultResponse; 111522d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie notification.requestorId = requestorId; 111622d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie notification.text = text; 111722d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie notification.requestorIdEncoding = requestorIdEncoding; 111822d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie notification.textEncoding = textEncoding; 111922d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie 112022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie // Process extras, assuming the format is 112122d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie // one of more lines of "key = value" 112222d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie Bundle bundle = new Bundle(); 112322d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie 112422d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie if (extras == null) extras = ""; 112522d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie Properties extraProp = new Properties(); 112622d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie 112722d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie try { 112822d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie extraProp.load(new StringBufferInputStream(extras)); 112922d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie } 113022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie catch (IOException e) 113122d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie { 113222d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie Log.e(TAG, "reportNiNotification cannot parse extras data: " + extras); 113322d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie } 113422d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie 113522d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie for (Entry<Object, Object> ent : extraProp.entrySet()) 113622d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie { 113722d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie bundle.putString((String) ent.getKey(), (String) ent.getValue()); 113822d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie } 113922d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie 114022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie notification.extras = bundle; 114122d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie 114222d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie mNIHandler.handleNiNotification(notification); 114322d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie } 114422d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie 11459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private class GpsEventThread extends Thread { 11469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public GpsEventThread() { 11489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super("GpsEventThread"); 11499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void run() { 11529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Config.LOGD) Log.d(TAG, "GpsEventThread starting"); 1153d654f9f727b415b153c7190832db4b65f6943f32Mike Lockwood // Exit as soon as disable() is called instead of waiting for the GPS to stop. 1154d654f9f727b415b153c7190832db4b65f6943f32Mike Lockwood while (mEnabled) { 11559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // this will wait for an event from the GPS, 11569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // which will be reported via reportLocation or reportStatus 11579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project native_wait_for_event(); 11589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Config.LOGD) Log.d(TAG, "GpsEventThread exiting"); 11609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private class GpsNetworkThread extends Thread { 11649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private long mNextNtpTime = 0; 11669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private long mNextXtraTime = 0; 116793bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood private boolean mTimeInjectRequested = false; 11689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mXtraDownloadRequested = false; 11699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private boolean mDone = false; 11709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public GpsNetworkThread() { 11729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project super("GpsNetworkThread"); 11739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void run() { 11769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (mNetworkThreadLock) { 11779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mDone) { 11789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project runLocked(); 11799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project public void runLocked() { 11849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Config.LOGD) Log.d(TAG, "NetworkThread starting"); 11859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project SntpClient client = new SntpClient(); 11879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project GpsXtraDownloader xtraDownloader = null; 11889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (native_supports_xtra()) { 11909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project xtraDownloader = new GpsXtraDownloader(mContext, mProperties); 11919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 11929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 11939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // thread exits after disable() is called 11949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project while (!mDone) { 11959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long waitTime = getWaitTime(); 11969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project do { 11979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized (this) { 11989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project try { 11999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mNetworkAvailable) { 12009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Config.LOGD) Log.d(TAG, 12019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project "NetworkThread wait for network"); 12029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project wait(); 12039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else if (waitTime > 0) { 12049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Config.LOGD) { 12059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.d(TAG, "NetworkThread wait for " + 12069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project waitTime + "ms"); 12079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project wait(waitTime); 12099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } catch (InterruptedException e) { 12119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Config.LOGD) { 12129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.d(TAG, "InterruptedException in GpsNetworkThread"); 12139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project waitTime = getWaitTime(); 1217e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood } while (!mDone && ((!mXtraDownloadRequested && 1218a9e546169b3c2c9c5f248d2f3abe3b934f48695dMike Lockwood !mTimeInjectRequested && waitTime > 0) 12199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project || !mNetworkAvailable)); 12209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Config.LOGD) Log.d(TAG, "NetworkThread out of wake loop"); 12219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!mDone) { 12239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mNtpServer != null && 122493bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood (mTimeInjectRequested || mNextNtpTime <= System.currentTimeMillis())) { 12259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Config.LOGD) { 12269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.d(TAG, "Requesting time from NTP server " + mNtpServer); 12279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 122893bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood mTimeInjectRequested = false; 12299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (client.requestTime(mNtpServer, 10000)) { 12309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long time = client.getNtpTime(); 12319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long timeReference = client.getNtpTimeReference(); 12329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int certainty = (int)(client.getRoundTripTime()/2); 12339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Config.LOGD) Log.d(TAG, "calling native_inject_time: " + 12359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project time + " reference: " + timeReference 12369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project + " certainty: " + certainty); 12379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project native_inject_time(time, timeReference, certainty); 12399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNextNtpTime = System.currentTimeMillis() + NTP_INTERVAL; 12409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 12419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Config.LOGD) Log.d(TAG, "requestTime failed"); 12429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNextNtpTime = System.currentTimeMillis() + RETRY_INTERVAL; 12439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if ((mXtraDownloadRequested || 12479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project (mNextXtraTime > 0 && mNextXtraTime <= System.currentTimeMillis())) 12489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project && xtraDownloader != null) { 124993bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood mXtraDownloadRequested = false; 12509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project byte[] data = xtraDownloader.downloadXtraData(); 12519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (data != null) { 12529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Config.LOGD) { 12539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project Log.d(TAG, "calling native_inject_xtra_data"); 12549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project native_inject_xtra_data(data, data.length); 12569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNextXtraTime = 0; 12579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 12589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mNextXtraTime = System.currentTimeMillis() + RETRY_INTERVAL; 12599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Config.LOGD) Log.d(TAG, "NetworkThread exiting"); 12649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized void xtraDownloadRequest() { 12679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mXtraDownloadRequested = true; 12689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project notify(); 12699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 127193bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood synchronized void timeInjectRequest() { 127293bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood mTimeInjectRequested = true; 127393bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood notify(); 127493bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood } 127593bc44d72125cfe798183b5b6891716dadac0ed7Mike Lockwood 12769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized void signal() { 12779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project notify(); 12789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project synchronized void setDone() { 12819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (Config.LOGD) Log.d(TAG, "stopping NetworkThread"); 12829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDone = true; 12839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project notify(); 12849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 12869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private long getWaitTime() { 12879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long now = System.currentTimeMillis(); 12889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long waitTime = Long.MAX_VALUE; 12899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mNtpServer != null) { 12909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project waitTime = mNextNtpTime - now; 12919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mNextXtraTime != 0) { 12939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long xtraWaitTime = mNextXtraTime - now; 12949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (xtraWaitTime < waitTime) { 12959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project waitTime = xtraWaitTime; 12969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 12989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (waitTime < 0) { 12999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project waitTime = 0; 13009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return waitTime; 13029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 13049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // for GPS SV statistics 13069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int MAX_SVS = 32; 13079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int EPHEMERIS_MASK = 0; 13089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int ALMANAC_MASK = 1; 13099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static final int USED_FOR_FIX_MASK = 2; 13109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // preallocated arrays, to avoid memory allocation in reportStatus() 13129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mSvs[] = new int[MAX_SVS]; 13139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private float mSnrs[] = new float[MAX_SVS]; 13149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private float mSvElevations[] = new float[MAX_SVS]; 13159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private float mSvAzimuths[] = new float[MAX_SVS]; 13169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mSvMasks[] = new int[3]; 13179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private int mSvCount; 1318b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood // preallocated to avoid memory allocation in reportNmea() 1319b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood private byte[] mNmeaBuffer = new byte[120]; 13209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project static { class_init_native(); } 13229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static native void class_init_native(); 13239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private static native boolean native_is_supported(); 13249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 13259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native boolean native_init(); 13269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native void native_disable(); 13279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native void native_cleanup(); 1328105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project private native boolean native_start(int positionMode, boolean singleFix, int fixInterval); 13299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native boolean native_stop(); 13309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native void native_set_fix_frequency(int fixFrequency); 13319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native void native_delete_aiding_data(int flags); 13329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native void native_wait_for_event(); 13339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // returns number of SVs 13349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // mask[0] is ephemeris mask and mask[1] is almanac mask 13359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native int native_read_sv_status(int[] svs, float[] snrs, 13369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project float[] elevations, float[] azimuths, int[] masks); 1337b16e7800be4f879135f239f1f8f586f3712df01eMike Lockwood private native int native_read_nmea(int index, byte[] buffer, int bufferSize); 1338d26ce0d903f5141a346d67b2b94437ef3e2880aaMike Lockwood private native void native_inject_location(double latitude, double longitude, float accuracy); 1339d26ce0d903f5141a346d67b2b94437ef3e2880aaMike Lockwood 13409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // XTRA Support 13419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native void native_inject_time(long time, long timeReference, int uncertainty); 13429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native boolean native_supports_xtra(); 13439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project private native void native_inject_xtra_data(byte[] data, int length); 1344105925376f8d0f6b318c9938c7b83ef7fef094daThe Android Open Source Project 1345e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood // AGPS Support 1346e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood private native void native_agps_data_conn_open(String apn); 1347e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood private native void native_agps_data_conn_closed(); 1348e3635c9693c4cd9650684f14e19dcabcea0d488aMike Lockwood private native void native_agps_data_conn_failed(); 1349a9e546169b3c2c9c5f248d2f3abe3b934f48695dMike Lockwood private native void native_set_agps_server(int type, String hostname, int port); 135022d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie 135122d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie // Network-initiated (NI) Support 135222d1f9fb23015471de6af1a70e40fb5c82ecb665Danke Xie private native void native_send_ni_response(int notificationId, int userResponse); 13539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1354