diff options
Diffstat (limited to 'services/java/com/android/server/LocationManagerService.java')
-rw-r--r-- | services/java/com/android/server/LocationManagerService.java | 182 |
1 files changed, 116 insertions, 66 deletions
diff --git a/services/java/com/android/server/LocationManagerService.java b/services/java/com/android/server/LocationManagerService.java index ed9ee7927313..bc6fd71850d7 100644 --- a/services/java/com/android/server/LocationManagerService.java +++ b/services/java/com/android/server/LocationManagerService.java @@ -64,12 +64,14 @@ import android.telephony.TelephonyManager; import android.util.Config; import android.util.Log; +import com.android.internal.app.IBatteryStats; import com.android.internal.location.CellState; import com.android.internal.location.GpsLocationProvider; -import com.android.internal.location.LocationCollector; -import com.android.internal.location.LocationMasfClient; -import com.android.internal.location.NetworkLocationProvider; +import com.android.internal.location.ILocationCollector; +import com.android.internal.location.INetworkLocationManager; +import com.android.internal.location.INetworkLocationProvider; import com.android.internal.location.TrackProvider; +import com.android.server.am.BatteryStatsService; /** * The service class that manages LocationProviders and issues location @@ -77,7 +79,8 @@ import com.android.internal.location.TrackProvider; * * {@hide} */ -public class LocationManagerService extends ILocationManager.Stub { +public class LocationManagerService extends ILocationManager.Stub + implements INetworkLocationManager { private static final String TAG = "LocationManagerService"; // Minimum time interval between last known location writes, in milliseconds. @@ -121,13 +124,15 @@ public class LocationManagerService extends ILocationManager.Stub { private final Context mContext; private GpsLocationProvider mGpsLocationProvider; - private NetworkLocationProvider mNetworkLocationProvider; + private LocationProviderImpl mNetworkLocationProvider; + private INetworkLocationProvider mNetworkLocationInterface; private LocationWorkerHandler mLocationHandler; // Handler messages private static final int MESSAGE_HEARTBEAT = 1; private static final int MESSAGE_ACQUIRE_WAKE_LOCK = 2; private static final int MESSAGE_RELEASE_WAKE_LOCK = 3; + private static final int MESSAGE_SET_NETWORK_LOCATION_PROVIDER = 4; // Alarm manager and wakelock variables private final static String ALARM_INTENT = "com.android.location.ALARM_INTENT"; @@ -143,6 +148,11 @@ public class LocationManagerService extends ILocationManager.Stub { private boolean mWakeLockNetworkReceived = true; private boolean mWifiWakeLockAcquired = false; private boolean mCellWakeLockAcquired = false; + + private final IBatteryStats mBatteryStats; + + // The calling UID when we are in a clearCallingIdentity/restoreCallingIdentity block, or -1 + private int mCallingUid = -1; /** * Mapping from listener IBinder/PendingIntent to local Listener wrappers. @@ -199,10 +209,7 @@ public class LocationManagerService extends ILocationManager.Stub { private int mSignalStrength = -1; // Location collector - private LocationCollector mCollector; - - // Location MASF service - private LocationMasfClient mMasfClient; + private ILocationCollector mCollector; // Wifi Manager private WifiManager mWifiManager; @@ -417,15 +424,9 @@ public class LocationManagerService extends ILocationManager.Stub { private void _loadProvidersNoSync() { // Attempt to load "real" providers first - if (NetworkLocationProvider.isSupported()) { - // Create a network location provider - mNetworkLocationProvider = new NetworkLocationProvider(mContext, mMasfClient); - LocationProviderImpl.addProvider(mNetworkLocationProvider); - } - if (GpsLocationProvider.isSupported()) { // Create a gps location provider - mGpsLocationProvider = new GpsLocationProvider(mContext, mCollector); + mGpsLocationProvider = new GpsLocationProvider(mContext); LocationProviderImpl.addProvider(mGpsLocationProvider); } @@ -509,18 +510,15 @@ public class LocationManagerService extends ILocationManager.Stub { Log.d(TAG, "Constructed LocationManager Service"); } - // Initialize the LocationMasfClient - mMasfClient = new LocationMasfClient(mContext); - - // Create location collector - mCollector = new LocationCollector(mMasfClient); - // Alarm manager, needs to be done before calling loadProviders() below mAlarmManager = (AlarmManager) context.getSystemService(Context.ALARM_SERVICE); // Create a wake lock, needs to be done before calling loadProviders() below PowerManager powerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE); mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, WAKELOCK_KEY); + + // Battery statistics service to be notified when GPS turns on or off + mBatteryStats = BatteryStatsService.getService(); // Load providers loadProviders(); @@ -560,13 +558,27 @@ public class LocationManagerService extends ILocationManager.Stub { if (mWifiManager != null) { List<ScanResult> wifiScanResults = mWifiManager.getScanResults(); if (wifiScanResults != null && wifiScanResults.size() != 0) { - if (mNetworkLocationProvider != null) { - mNetworkLocationProvider.updateWifiScanResults(wifiScanResults); + if (mNetworkLocationInterface != null) { + mNetworkLocationInterface.updateWifiScanResults(wifiScanResults); } } } } + public void setNetworkLocationProvider(INetworkLocationProvider provider) { + mLocationHandler.removeMessages(MESSAGE_SET_NETWORK_LOCATION_PROVIDER); + Message m = Message.obtain(mLocationHandler, + MESSAGE_SET_NETWORK_LOCATION_PROVIDER, provider); + mLocationHandler.sendMessageAtFrontOfQueue(m); + } + + public void setLocationCollector(ILocationCollector collector) { + mCollector = collector; + if (mGpsLocationProvider != null) { + mGpsLocationProvider.setLocationCollector(mCollector); + } + } + private WifiManager.WifiLock getWifiWakelock() { if (mWifiLock == null && mWifiManager != null) { mWifiLock = mWifiManager.createWifiLock(WifiManager.WIFI_MODE_SCAN_ONLY, WIFILOCK_KEY); @@ -690,7 +702,8 @@ public class LocationManagerService extends ILocationManager.Stub { boolean shouldBeEnabled = isAllowedBySettings(name); // Collection is only allowed when network provider is being used - if (p.getName().equals(LocationManager.NETWORK_PROVIDER)) { + if (mCollector != null && + p.getName().equals(LocationManager.NETWORK_PROVIDER)) { mCollector.updateNetworkProviderStatus(shouldBeEnabled); } @@ -847,7 +860,7 @@ public class LocationManagerService extends ILocationManager.Stub { } } - private void _requestLocationUpdates(String provider, + private synchronized void _requestLocationUpdates(String provider, long minTime, float minDistance, Receiver receiver) { Object key = receiver.getKey(); if (Config.LOGD) { @@ -864,6 +877,7 @@ public class LocationManagerService extends ILocationManager.Stub { String[] packages = getPackageNames(); // so wakelock calls will succeed + mCallingUid = getCallingUid(); long identity = Binder.clearCallingIdentity(); try { UpdateRecord r = new UpdateRecord(provider, minTime, minDistance, receiver, packages); @@ -889,12 +903,16 @@ public class LocationManagerService extends ILocationManager.Stub { oldRecord.dispose(); } - if (impl instanceof NetworkLocationProvider) { - ((NetworkLocationProvider) impl).addListener(packages); - } - boolean isProviderEnabled = isAllowedBySettings(provider); if (isProviderEnabled) { + if (provider.equals(LocationManager.GPS_PROVIDER)) { + try { + mBatteryStats.noteRequestGpsOn(mCallingUid); + } catch (RemoteException e) { + Log.w(TAG, "Got RemoteException calling noteRequestGpsOff", e); + } + } + long minTimeForProvider = getMinTime(provider); impl.setMinTime(minTimeForProvider); impl.enableLocationTracking(true); @@ -904,7 +922,6 @@ public class LocationManagerService extends ILocationManager.Stub { mLocationHandler.removeMessages(MESSAGE_HEARTBEAT, provider); Message m = Message.obtain(mLocationHandler, MESSAGE_HEARTBEAT, provider); mLocationHandler.sendMessageAtTime(m, SystemClock.uptimeMillis() + 1000); - } else { try { // Notify the listener that updates are currently disabled @@ -919,6 +936,7 @@ public class LocationManagerService extends ILocationManager.Stub { } } finally { Binder.restoreCallingIdentity(identity); + mCallingUid = -1; } } @@ -942,13 +960,14 @@ public class LocationManagerService extends ILocationManager.Stub { } } - private void _removeUpdates(Receiver receiver) { + private synchronized void _removeUpdates(Receiver receiver) { Object key = receiver.getKey(); if (Config.LOGD) { Log.d(TAG, "_removeUpdates: listener = " + key); } // so wakelock calls will succeed + mCallingUid = getCallingUid(); long identity = Binder.clearCallingIdentity(); try { synchronized (mLocationListeners) { @@ -964,8 +983,8 @@ public class LocationManagerService extends ILocationManager.Stub { // Call dispose() on the obsolete update records. for (UpdateRecord record : oldRecords.values()) { if (record.mProvider.equals(LocationManager.NETWORK_PROVIDER)) { - if (mNetworkLocationProvider != null) { - mNetworkLocationProvider.removeListener(record.mPackages); + if (mNetworkLocationInterface != null) { + mNetworkLocationInterface.removeListener(record.mPackages); } } record.dispose(); @@ -973,6 +992,14 @@ public class LocationManagerService extends ILocationManager.Stub { // Accumulate providers providers.addAll(oldRecords.keySet()); } + + if (providers.contains("gps")) { + try { + mBatteryStats.noteRequestGpsOff(mCallingUid); + } catch (RemoteException e) { + Log.w(TAG, "Got RemoteException calling noteRequestGpsOff", e); + } + } mLocationListeners.remove(key); mLastFixBroadcast.remove(key); @@ -1010,6 +1037,7 @@ public class LocationManagerService extends ILocationManager.Stub { } } finally { Binder.restoreCallingIdentity(identity); + mCallingUid = -1; } } @@ -1426,7 +1454,7 @@ public class LocationManagerService extends ILocationManager.Stub { } writeLastKnownLocation(provider, loc); - if (p instanceof NetworkLocationProvider) { + if (p instanceof INetworkLocationProvider) { mWakeLockNetworkReceived = true; } else if (p instanceof GpsLocationProvider) { // Gps location received signal is in NetworkStateBroadcastReceiver @@ -1570,6 +1598,17 @@ public class LocationManagerService extends ILocationManager.Stub { // Update wakelock status so the next alarm is set before releasing wakelock updateWakelockStatus(mScreenOn); releaseWakeLock(); + } else if (msg.what == MESSAGE_SET_NETWORK_LOCATION_PROVIDER) { + synchronized (LocationManagerService.class) { + Log.d(TAG, "adding network location provider"); + mNetworkLocationInterface = + (INetworkLocationProvider)msg.obj; + mNetworkLocationInterface.addListener(getPackageNames()); + mNetworkLocationProvider = + (LocationProviderImpl)mNetworkLocationInterface; + LocationProviderImpl.addProvider(mNetworkLocationProvider); + updateProviders(); + } } } catch (Exception e) { // Log, don't crash! @@ -1590,7 +1629,9 @@ public class LocationManagerService extends ILocationManager.Stub { mLastCellState = new CellState(mTelephonyManager, cellLocation, asu); // Notify collector - mCollector.updateCellState(mLastCellState); + if (mCollector != null) { + mCollector.updateCellState(mLastCellState); + } // Updates providers List<LocationProviderImpl> providers = LocationProviderImpl.getProviders(); @@ -1648,7 +1689,9 @@ public class LocationManagerService extends ILocationManager.Stub { boolean plugged = intent.getIntExtra(BATTERY_EXTRA_PLUGGED, 0) != 0; // Notify collector battery state - mCollector.updateBatteryState(scale, level, plugged); + if (mCollector != null) { + mCollector.updateBatteryState(scale, level, plugged); + } } } } @@ -1666,9 +1709,11 @@ public class LocationManagerService extends ILocationManager.Stub { } // Notify provider and collector of Wifi scan results - mCollector.updateWifiScanResults(wifiScanResults); - if (mNetworkLocationProvider != null) { - mNetworkLocationProvider.updateWifiScanResults(wifiScanResults); + if (mCollector != null) { + mCollector.updateWifiScanResults(wifiScanResults); + } + if (mNetworkLocationInterface != null) { + mNetworkLocationInterface.updateWifiScanResults(wifiScanResults); } } else if (action.equals(ConnectivityManager.CONNECTIVITY_ACTION)) { @@ -1702,8 +1747,8 @@ public class LocationManagerService extends ILocationManager.Stub { } // Notify network provider of current wifi enabled state - if (mNetworkLocationProvider != null) { - mNetworkLocationProvider.updateWifiEnabledState(enabled); + if (mNetworkLocationInterface != null) { + mNetworkLocationInterface.updateWifiEnabledState(enabled); } } else if (action.equals(GpsLocationProvider.GPS_ENABLED_CHANGE_ACTION)) { @@ -1821,8 +1866,8 @@ public class LocationManagerService extends ILocationManager.Stub { } // Notify NetworkLocationProvider - if (mNetworkLocationProvider != null) { - mNetworkLocationProvider.updateCellLockStatus(mCellWakeLockAcquired); + if (mNetworkLocationInterface != null) { + mNetworkLocationInterface.updateCellLockStatus(mCellWakeLockAcquired); } // Acquire wifi lock @@ -1845,6 +1890,14 @@ public class LocationManagerService extends ILocationManager.Stub { && mGpsLocationProvider.isLocationTracking(); if (gpsActive) { mGpsLocationProvider.startNavigating(); + long identity = Binder.clearCallingIdentity(); + try { + mBatteryStats.noteStartGps(mCallingUid == -1 ? getCallingUid() : mCallingUid); + } catch (RemoteException e) { + Log.w(TAG, "RemoteException calling noteStartGps on BatteryStatsService", e); + } finally { + Binder.restoreCallingIdentity(identity); + } } } @@ -1853,6 +1906,14 @@ public class LocationManagerService extends ILocationManager.Stub { && mGpsLocationProvider.isLocationTracking(); if (gpsActive) { mGpsLocationProvider.stopNavigating(); + long identity = Binder.clearCallingIdentity(); + try { + mBatteryStats.noteStopGps(mCallingUid == -1 ? getCallingUid() : mCallingUid); + } catch (RemoteException e) { + Log.w(TAG, "RemoteException calling noteStopGps on BatteryStatsService", e); + } finally { + Binder.restoreCallingIdentity(identity); + } } } @@ -1877,7 +1938,6 @@ public class LocationManagerService extends ILocationManager.Stub { } if (!mScreenOn) { - // Stop the gps stopGps(); } @@ -1889,8 +1949,8 @@ public class LocationManagerService extends ILocationManager.Stub { } // Notify NetworkLocationProvider - if (mNetworkLocationProvider != null) { - mNetworkLocationProvider.updateCellLockStatus(mCellWakeLockAcquired); + if (mNetworkLocationInterface != null) { + mNetworkLocationInterface.updateCellLockStatus(mCellWakeLockAcquired); } // Release wake lock @@ -1907,14 +1967,10 @@ public class LocationManagerService extends ILocationManager.Stub { public String getFromLocation(double latitude, double longitude, int maxResults, String language, String country, String variant, String appName, List<Address> addrs) { - try { - Locale locale = new Locale(language, country, variant); - mMasfClient.reverseGeocode(locale, appName, latitude, longitude, maxResults, addrs); - return null; - } catch(IOException e) { - return e.getMessage(); - } catch(Exception e) { - Log.e(TAG, "getFromLocation got exception:", e); + if (mNetworkLocationInterface != null) { + return mNetworkLocationInterface.getFromLocation(latitude, longitude, maxResults, + language, country, variant, appName, addrs); + } else { return null; } } @@ -1923,17 +1979,11 @@ public class LocationManagerService extends ILocationManager.Stub { double lowerLeftLatitude, double lowerLeftLongitude, double upperRightLatitude, double upperRightLongitude, int maxResults, String language, String country, String variant, String appName, List<Address> addrs) { - - try { - Locale locale = new Locale(language, country, variant); - mMasfClient.forwardGeocode(locale, appName, locationName, - lowerLeftLatitude, lowerLeftLongitude, upperRightLatitude, upperRightLongitude, - maxResults, addrs); - return null; - } catch(IOException e) { - return e.getMessage(); - } catch(Exception e) { - Log.e(TAG, "getFromLocationName got exception:", e); + if (mNetworkLocationInterface != null) { + return mNetworkLocationInterface.getFromLocationName(locationName, lowerLeftLatitude, + lowerLeftLongitude, upperRightLatitude, upperRightLongitude, maxResults, + language, country, variant, appName, addrs); + } else { return null; } } |