Merge change 1150 into donut
* changes:
location: Location Manager wakelock cleanup
diff --git a/location/java/android/location/ILocationProvider.aidl b/location/java/android/location/ILocationProvider.aidl
index e3e374d..6c23f83 100644
--- a/location/java/android/location/ILocationProvider.aidl
+++ b/location/java/android/location/ILocationProvider.aidl
@@ -44,6 +44,4 @@
boolean sendExtraCommand(String command, inout Bundle extras);
void addListener(int uid);
void removeListener(int uid);
- void wakeLockAcquired();
- void wakeLockReleased();
}
diff --git a/location/java/com/android/internal/location/GpsLocationProvider.java b/location/java/com/android/internal/location/GpsLocationProvider.java
index 97b6a62..21c7adb 100644
--- a/location/java/com/android/internal/location/GpsLocationProvider.java
+++ b/location/java/com/android/internal/location/GpsLocationProvider.java
@@ -34,6 +34,7 @@
import android.net.SntpClient;
import android.os.Bundle;
import android.os.IBinder;
+import android.os.PowerManager;
import android.os.RemoteException;
import android.os.ServiceManager;
import android.os.SystemClock;
@@ -207,6 +208,10 @@
private int mSuplDataConnectionState;
private final ConnectivityManager mConnMgr;
+ // Wakelocks
+ private final static String WAKELOCK_KEY = "GpsLocationProvider";
+ private final PowerManager.WakeLock mWakeLock;
+
// Alarms
private final static String ALARM_WAKEUP = "com.android.internal.location.ALARM_WAKEUP";
private final AlarmManager mAlarmManager;
@@ -307,6 +312,10 @@
mContext = context;
mLocationManager = locationManager;
+ // Create a wake lock
+ PowerManager powerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
+ mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, WAKELOCK_KEY);
+
mAlarmManager = (AlarmManager)mContext.getSystemService(Context.ALARM_SERVICE);
mWakeupIntent = PendingIntent.getBroadcast(mContext, 0, new Intent(ALARM_WAKEUP), 0);
@@ -574,12 +583,6 @@
}
}
- public void wakeLockAcquired() {
- }
-
- public void wakeLockReleased() {
- }
-
public void addListener(int uid) {
mClientUids.put(uid, 0);
if (mNavigating) {
@@ -767,6 +770,10 @@
mNavigating = (status == GPS_STATUS_SESSION_BEGIN);
if (wasNavigating != mNavigating) {
+ if (mNavigating) {
+ if (DEBUG) Log.d(TAG, "Acquiring wakelock");
+ mWakeLock.acquire();
+ }
synchronized(mListeners) {
int size = mListeners.size();
for (int i = 0; i < size; i++) {
@@ -804,6 +811,11 @@
Intent intent = new Intent(GPS_ENABLED_CHANGE_ACTION);
intent.putExtra(EXTRA_ENABLED, mNavigating);
mContext.sendBroadcast(intent);
+
+ if (!mNavigating) {
+ if (DEBUG) Log.d(TAG, "Releasing wakelock");
+ mWakeLock.release();
+ }
}
}
diff --git a/location/java/com/android/internal/location/LocationProviderProxy.java b/location/java/com/android/internal/location/LocationProviderProxy.java
index abca28f..80303f4 100644
--- a/location/java/com/android/internal/location/LocationProviderProxy.java
+++ b/location/java/com/android/internal/location/LocationProviderProxy.java
@@ -231,20 +231,4 @@
Log.e(TAG, "removeListener failed", e);
}
}
-
- public void wakeLockAcquired() {
- try {
- mProvider.wakeLockAcquired();
- } catch (RemoteException e) {
- Log.e(TAG, "wakeLockAcquired failed", e);
- }
- }
-
- public void wakeLockReleased() {
- try {
- mProvider.wakeLockReleased();
- } catch (RemoteException e) {
- Log.e(TAG, "wakeLockReleased failed", e);
- }
- }
}
diff --git a/location/java/com/android/internal/location/MockProvider.java b/location/java/com/android/internal/location/MockProvider.java
index d81d0ab..f167a44 100644
--- a/location/java/com/android/internal/location/MockProvider.java
+++ b/location/java/com/android/internal/location/MockProvider.java
@@ -182,12 +182,6 @@
public void removeListener(int uid) {
}
- public void wakeLockAcquired() {
- }
-
- public void wakeLockReleased() {
- }
-
public void dump(PrintWriter pw, String prefix) {
pw.println(prefix + mName);
pw.println(prefix + "mHasLocation=" + mHasLocation);
diff --git a/services/java/com/android/server/LocationManagerService.java b/services/java/com/android/server/LocationManagerService.java
index 9af729e..9750d4d 100644
--- a/services/java/com/android/server/LocationManagerService.java
+++ b/services/java/com/android/server/LocationManagerService.java
@@ -33,7 +33,6 @@
import java.util.Set;
import java.util.regex.Pattern;
-import android.app.AlarmManager;
import android.app.PendingIntent;
import android.content.BroadcastReceiver;
import android.content.ContentQueryMap;
@@ -132,16 +131,10 @@
// Handler messages
private static final int MESSAGE_LOCATION_CHANGED = 1;
- // Alarm manager and wakelock variables
- private final static String ALARM_INTENT = "com.android.location.ALARM_INTENT";
+ // wakelock variables
private final static String WAKELOCK_KEY = "LocationManagerService";
- private AlarmManager mAlarmManager;
- private long mAlarmInterval = 0;
private PowerManager.WakeLock mWakeLock = null;
private int mPendingBroadcasts;
- private long mWakeLockAcquireTime = 0;
- private boolean mWakeLockGpsReceived = true;
- private boolean mWakeLockNetworkReceived = true;
/**
* List of all receivers.
@@ -388,24 +381,22 @@
public void onSendFinished(PendingIntent pendingIntent, Intent intent,
int resultCode, String resultData, Bundle resultExtras) {
- decrementPendingBroadcasts();
- }
-
- // this must be called while synchronized by callerin a synchronized block
- // containing the sending of the broadcaset
- private void incrementPendingBroadcastsLocked() {
- if (mPendingBroadcasts++ == 0) {
- synchronized (mLock) {
- LocationManagerService.this.incrementPendingBroadcastsLocked();
- }
+ synchronized (this) {
+ decrementPendingBroadcastsLocked();
}
}
- private void decrementPendingBroadcasts() {
- synchronized (this) {
- if (--mPendingBroadcasts == 0) {
- LocationManagerService.this.decrementPendingBroadcasts();
- }
+ // this must be called while synchronized by caller in a synchronized block
+ // containing the sending of the broadcaset
+ private void incrementPendingBroadcastsLocked() {
+ if (mPendingBroadcasts++ == 0) {
+ LocationManagerService.this.incrementPendingBroadcasts();
+ }
+ }
+
+ private void decrementPendingBroadcastsLocked() {
+ if (--mPendingBroadcasts == 0) {
+ LocationManagerService.this.decrementPendingBroadcasts();
}
}
}
@@ -413,7 +404,12 @@
public void locationCallbackFinished(ILocationListener listener) {
Receiver receiver = getReceiver(listener);
if (receiver != null) {
- receiver.decrementPendingBroadcasts();
+ synchronized (receiver) {
+ // so wakelock calls will succeed
+ long identity = Binder.clearCallingIdentity();
+ receiver.decrementPendingBroadcastsLocked();
+ Binder.restoreCallingIdentity(identity);
+ }
}
}
@@ -526,15 +522,6 @@
mProvidersByName.remove(provider.getName());
}
- /**
- * Load providers from /data/location/<provider_name>/
- * class
- * kml
- * nmea
- * track
- * location
- * properties
- */
private void loadProviders() {
synchronized (mLock) {
if (sProvidersLoaded) {
@@ -585,30 +572,20 @@
}
private void initialize() {
- // Alarm manager, needs to be done before calling loadProviders() below
- mAlarmManager = (AlarmManager) mContext.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);
-
+
// Load providers
loadProviders();
// Register for Network (Wifi or Mobile) updates
- NetworkStateBroadcastReceiver networkReceiver = new NetworkStateBroadcastReceiver();
- IntentFilter networkIntentFilter = new IntentFilter();
- networkIntentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
- networkIntentFilter.addAction(GpsLocationProvider.GPS_ENABLED_CHANGE_ACTION);
- mContext.registerReceiver(networkReceiver, networkIntentFilter);
-
- // Register for power updates
- PowerStateBroadcastReceiver powerStateReceiver = new PowerStateBroadcastReceiver();
IntentFilter intentFilter = new IntentFilter();
- intentFilter.addAction(ALARM_INTENT);
+ intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
+ // Register for Package Manager updates
intentFilter.addAction(Intent.ACTION_PACKAGE_REMOVED);
intentFilter.addAction(Intent.ACTION_PACKAGE_RESTARTED);
- mContext.registerReceiver(powerStateReceiver, intentFilter);
+ mContext.registerReceiver(mBroadcastReceiver, intentFilter);
// listen for settings changes
ContentResolver resolver = mContext.getContentResolver();
@@ -825,12 +802,10 @@
if (listeners > 0) {
p.setMinTime(getMinTimeLocked(provider));
p.enableLocationTracking(true);
- updateWakelockStatusLocked();
}
} else {
p.enableLocationTracking(false);
p.disable();
- updateWakelockStatusLocked();
}
}
@@ -1020,7 +995,6 @@
long minTimeForProvider = getMinTimeLocked(provider);
proxy.setMinTime(minTimeForProvider);
proxy.enableLocationTracking(true);
- updateWakelockStatusLocked();
} else {
// Notify the listener that updates are currently disabled
receiver.callProviderEnabledLocked(provider, false);
@@ -1109,8 +1083,6 @@
}
}
}
-
- updateWakelockStatusLocked();
} finally {
Binder.restoreCallingIdentity(identity);
}
@@ -1258,13 +1230,13 @@
Intent enteredIntent = new Intent();
enteredIntent.putExtra(LocationManager.KEY_PROXIMITY_ENTERING, true);
try {
- synchronized (mLock) {
- // synchronize to ensure incrementPendingBroadcastsLocked()
+ synchronized (this) {
+ // synchronize to ensure incrementPendingBroadcasts()
// is called before decrementPendingBroadcasts()
intent.send(mContext, 0, enteredIntent, this, mLocationHandler);
// call this after broadcasting so we do not increment
// if we throw an exeption.
- incrementPendingBroadcastsLocked();
+ incrementPendingBroadcasts();
}
} catch (PendingIntent.CanceledException e) {
if (LOCAL_LOGV) {
@@ -1283,13 +1255,13 @@
Intent exitedIntent = new Intent();
exitedIntent.putExtra(LocationManager.KEY_PROXIMITY_ENTERING, false);
try {
- synchronized (mLock) {
- // synchronize to ensure incrementPendingBroadcastsLocked()
+ synchronized (this) {
+ // synchronize to ensure incrementPendingBroadcasts()
// is called before decrementPendingBroadcasts()
intent.send(mContext, 0, exitedIntent, this, mLocationHandler);
// call this after broadcasting so we do not increment
// if we throw an exeption.
- incrementPendingBroadcastsLocked();
+ incrementPendingBroadcasts();
}
} catch (PendingIntent.CanceledException e) {
if (LOCAL_LOGV) {
@@ -1346,7 +1318,11 @@
public void onSendFinished(PendingIntent pendingIntent, Intent intent,
int resultCode, String resultData, Bundle resultExtras) {
- decrementPendingBroadcasts();
+ // synchronize to ensure incrementPendingBroadcasts()
+ // is called before decrementPendingBroadcasts()
+ synchronized (this) {
+ decrementPendingBroadcasts();
+ }
}
}
@@ -1581,11 +1557,6 @@
}
writeLastKnownLocationLocked(provider, location);
- if (LocationManager.NETWORK_PROVIDER.equals(p.getName())) {
- mWakeLockNetworkReceived = true;
- }
- // Gps location received signal is in NetworkStateBroadcastReceiver
-
// Fetch latest status update time
long newStatusUpdateTime = p.getStatusUpdateTime();
@@ -1668,7 +1639,6 @@
}
handleLocationChangedLocked(location);
- updateWakelockStatusLocked();
}
}
} catch (Exception e) {
@@ -1678,20 +1648,12 @@
}
}
- private class PowerStateBroadcastReceiver extends BroadcastReceiver {
- @Override public void onReceive(Context context, Intent intent) {
+ private final BroadcastReceiver mBroadcastReceiver = new BroadcastReceiver() {
+ @Override
+ public void onReceive(Context context, Intent intent) {
String action = intent.getAction();
- if (action.equals(ALARM_INTENT)) {
- synchronized (mLock) {
- log("PowerStateBroadcastReceiver: Alarm received");
- // Have to do this immediately, rather than posting a
- // message, so we execute our code while the system
- // is holding a wake lock until the alarm broadcast
- // is finished.
- acquireWakeLockLocked();
- }
- } else if (action.equals(Intent.ACTION_PACKAGE_REMOVED)
+ if (action.equals(Intent.ACTION_PACKAGE_REMOVED)
|| action.equals(Intent.ACTION_PACKAGE_RESTARTED)) {
synchronized (mLock) {
int uid = intent.getIntExtra(Intent.EXTRA_UID, -1);
@@ -1733,15 +1695,7 @@
}
}
}
- }
- }
- }
-
- private class NetworkStateBroadcastReceiver extends BroadcastReceiver {
- @Override public void onReceive(Context context, Intent intent) {
- String action = intent.getAction();
-
- if (action.equals(ConnectivityManager.CONNECTIVITY_ACTION)) {
+ } else if (action.equals(ConnectivityManager.CONNECTIVITY_ACTION)) {
boolean noConnectivity =
intent.getBooleanExtra(ConnectivityManager.EXTRA_NO_CONNECTIVITY, false);
if (!noConnectivity) {
@@ -1759,146 +1713,43 @@
}
}
}
- } else if (action.equals(GpsLocationProvider.GPS_ENABLED_CHANGE_ACTION)) {
-
- final boolean enabled = intent.getBooleanExtra(GpsLocationProvider.EXTRA_ENABLED,
- false);
-
- synchronized (mLock) {
- if (!enabled) {
- // When GPS is disabled, we are OK to release wake-lock
- mWakeLockGpsReceived = true;
- }
- }
}
-
}
- }
+ };
// Wake locks
- private void updateWakelockStatusLocked() {
- log("updateWakelockStatus()");
-
- long callerId = Binder.clearCallingIdentity();
-
- boolean needsLock = (mPendingBroadcasts > 0);
- long minTime = Integer.MAX_VALUE;
-
- if (mNetworkLocationProvider != null && mNetworkLocationProvider.isLocationTracking()) {
- needsLock = true;
- minTime = Math.min(mNetworkLocationProvider.getMinTime(), minTime);
- }
-
- if (mGpsLocationProvider != null && mGpsLocationProvider.isLocationTracking()) {
- needsLock = true;
- minTime = Math.min(mGpsLocationProvider.getMinTime(), minTime);
- }
-
- PendingIntent sender =
- PendingIntent.getBroadcast(mContext, 0, new Intent(ALARM_INTENT), 0);
-
- // Cancel existing alarm
- log("Cancelling existing alarm");
- mAlarmManager.cancel(sender);
-
- if (needsLock) {
- long now = SystemClock.elapsedRealtime();
- mAlarmManager.set(
- AlarmManager.ELAPSED_REALTIME_WAKEUP, now + minTime, sender);
- mAlarmInterval = minTime;
- log("Creating a new wakelock alarm with minTime = " + minTime);
- } else {
- log("No need for alarm");
- mAlarmInterval = -1;
-
- releaseWakeLockLocked();
- }
- Binder.restoreCallingIdentity(callerId);
- }
-
- private void acquireWakeLockLocked() {
- try {
- acquireWakeLockXLocked();
- } catch (Exception e) {
- // This is to catch a runtime exception thrown when we try to release an
- // already released lock.
- Log.e(TAG, "exception in acquireWakeLock()", e);
- }
- }
-
- private void acquireWakeLockXLocked() {
- if (mWakeLock.isHeld()) {
- log("Must release wakelock before acquiring");
- mWakeLockAcquireTime = 0;
- mWakeLock.release();
- }
-
- boolean networkActive = (mNetworkLocationProvider != null)
- && mNetworkLocationProvider.isLocationTracking();
- boolean gpsActive = (mGpsLocationProvider != null)
- && mGpsLocationProvider.isLocationTracking();
-
- boolean needsLock = networkActive || gpsActive;
- if (!needsLock) {
- log("No need for Lock!");
- return;
- }
-
- mWakeLockGpsReceived = !gpsActive;
- mWakeLockNetworkReceived = !networkActive;
-
- // Acquire wake lock
- mWakeLock.acquire();
- mWakeLockAcquireTime = SystemClock.elapsedRealtime();
- log("Acquired wakelock");
-
- if (mNetworkLocationProvider != null) {
- mNetworkLocationProvider.wakeLockAcquired();
- }
- if (mGpsLocationProvider != null) {
- mGpsLocationProvider.wakeLockAcquired();
- }
- }
-
- private void releaseWakeLockLocked() {
- try {
- releaseWakeLockXLocked();
- } catch (Exception e) {
- // This is to catch a runtime exception thrown when we try to release an
- // already released lock.
- Log.e(TAG, "exception in releaseWakeLock()", e);
- }
- }
-
- private void releaseWakeLockXLocked() {
- if (mNetworkLocationProvider != null) {
- mNetworkLocationProvider.wakeLockReleased();
- }
- if (mGpsLocationProvider != null) {
- mGpsLocationProvider.wakeLockReleased();
- }
-
- // Release wake lock
- mWakeLockAcquireTime = 0;
- if (mWakeLock.isHeld()) {
- log("Released wakelock");
- mWakeLock.release();
- } else {
- log("Can't release wakelock again!");
- }
- }
-
- private void incrementPendingBroadcastsLocked() {
- if (mPendingBroadcasts++ == 0) {
- updateWakelockStatusLocked();
+ private void incrementPendingBroadcasts() {
+ synchronized (mWakeLock) {
+ if (mPendingBroadcasts++ == 0) {
+ try {
+ mWakeLock.acquire();
+ log("Acquired wakelock");
+ } catch (Exception e) {
+ // This is to catch a runtime exception thrown when we try to release an
+ // already released lock.
+ Log.e(TAG, "exception in acquireWakeLock()", e);
+ }
+ }
}
}
private void decrementPendingBroadcasts() {
- synchronized (mLock) {
+ synchronized (mWakeLock) {
if (--mPendingBroadcasts == 0) {
- updateWakelockStatusLocked();
+ try {
+ // Release wake lock
+ if (mWakeLock.isHeld()) {
+ mWakeLock.release();
+ log("Released wakelock");
+ } else {
+ log("Can't release wakelock again!");
+ }
+ } catch (Exception e) {
+ // This is to catch a runtime exception thrown when we try to release an
+ // already released lock.
+ Log.e(TAG, "exception in releaseWakeLock()", e);
+ }
}
}
}
@@ -2069,7 +1920,7 @@
protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
if (mContext.checkCallingOrSelfPermission(android.Manifest.permission.DUMP)
!= PackageManager.PERMISSION_GRANTED) {
- pw.println("Permission Denial: can't dump AlarmManager from from pid="
+ pw.println("Permission Denial: can't dump LocationManagerService from from pid="
+ Binder.getCallingPid()
+ ", uid=" + Binder.getCallingUid());
return;
@@ -2081,10 +1932,6 @@
pw.println(" mGpsLocationProvider=" + mGpsLocationProvider);
pw.println(" mNetworkLocationProvider=" + mNetworkLocationProvider);
pw.println(" mCollector=" + mCollector);
- pw.println(" mAlarmInterval=" + mAlarmInterval
- + " mWakeLockAcquireTime=" + mWakeLockAcquireTime);
- pw.println(" mWakeLockGpsReceived=" + mWakeLockGpsReceived
- + " mWakeLockNetworkReceived=" + mWakeLockNetworkReceived);
pw.println(" Listeners:");
int N = mReceivers.size();
for (int i=0; i<N; i++) {
diff --git a/test-runner/android/test/TestLocationProvider.java b/test-runner/android/test/TestLocationProvider.java
index 08603e3..dded745 100644
--- a/test-runner/android/test/TestLocationProvider.java
+++ b/test-runner/android/test/TestLocationProvider.java
@@ -169,12 +169,6 @@
public void removeListener(int uid) {
}
- public void wakeLockAcquired() {
- }
-
- public void wakeLockReleased() {
- }
-
private void updateLocation() {
long time = SystemClock.uptimeMillis();
long multiplier = (time/5000)%500000;