Merge "GpsLocationProvider: optimize wake lock usage." into kraken

This commit is contained in:
Mike Lockwood
2010-04-14 16:35:29 -07:00
committed by Android (Google) Code Review

View File

@@ -222,6 +222,12 @@ public class GpsLocationProvider implements LocationProviderInterface {
// Wakelocks // Wakelocks
private final static String WAKELOCK_KEY = "GpsLocationProvider"; private final static String WAKELOCK_KEY = "GpsLocationProvider";
private final PowerManager.WakeLock mWakeLock; private final PowerManager.WakeLock mWakeLock;
// bitfield of pending messages to our Handler
// used only for messages that cannot have multiple instances queued
private int mPendingMessageBits;
// separate counter for ADD_LISTENER and REMOVE_LISTENER messages,
// which might have multiple instances queued
private int mPendingListenerMessages;
// Alarms // Alarms
private final static String ALARM_WAKEUP = "com.android.internal.location.ALARM_WAKEUP"; private final static String ALARM_WAKEUP = "com.android.internal.location.ALARM_WAKEUP";
@@ -323,6 +329,7 @@ public class GpsLocationProvider implements LocationProviderInterface {
// Create a wake lock // Create a wake lock
PowerManager powerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE); PowerManager powerManager = (PowerManager) mContext.getSystemService(Context.POWER_SERVICE);
mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, WAKELOCK_KEY); mWakeLock = powerManager.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, WAKELOCK_KEY);
mWakeLock.setReferenceCounted(false);
mAlarmManager = (AlarmManager)mContext.getSystemService(Context.ALARM_SERVICE); mAlarmManager = (AlarmManager)mContext.getSystemService(Context.ALARM_SERVICE);
mWakeupIntent = PendingIntent.getBroadcast(mContext, 0, new Intent(ALARM_WAKEUP), 0); mWakeupIntent = PendingIntent.getBroadcast(mContext, 0, new Intent(ALARM_WAKEUP), 0);
@@ -401,11 +408,7 @@ public class GpsLocationProvider implements LocationProviderInterface {
} }
public void updateNetworkState(int state, NetworkInfo info) { public void updateNetworkState(int state, NetworkInfo info) {
mHandler.removeMessages(UPDATE_NETWORK_STATE); sendMessage(UPDATE_NETWORK_STATE, state, info);
Message m = Message.obtain(mHandler, UPDATE_NETWORK_STATE);
m.arg1 = state;
m.obj = info;
mHandler.sendMessage(m);
} }
private void handleUpdateNetworkState(int state, NetworkInfo info) { private void handleUpdateNetworkState(int state, NetworkInfo info) {
@@ -434,12 +437,10 @@ public class GpsLocationProvider implements LocationProviderInterface {
if (mNetworkAvailable) { if (mNetworkAvailable) {
if (mInjectNtpTimePending) { if (mInjectNtpTimePending) {
mHandler.removeMessages(INJECT_NTP_TIME); sendMessage(INJECT_NTP_TIME, 0, null);
mHandler.sendMessage(Message.obtain(mHandler, INJECT_NTP_TIME));
} }
if (mDownloadXtraDataPending) { if (mDownloadXtraDataPending) {
mHandler.removeMessages(DOWNLOAD_XTRA_DATA); sendMessage(DOWNLOAD_XTRA_DATA, 0, null);
mHandler.sendMessage(Message.obtain(mHandler, DOWNLOAD_XTRA_DATA));
} }
} }
} }
@@ -485,6 +486,7 @@ public class GpsLocationProvider implements LocationProviderInterface {
} }
// send delayed message for next NTP injection // send delayed message for next NTP injection
// since this is delayed and not urgent we do not hold a wake lock here
mHandler.removeMessages(INJECT_NTP_TIME); mHandler.removeMessages(INJECT_NTP_TIME);
mHandler.sendMessageDelayed(Message.obtain(mHandler, INJECT_NTP_TIME), delay); mHandler.sendMessageDelayed(Message.obtain(mHandler, INJECT_NTP_TIME), delay);
} }
@@ -507,6 +509,7 @@ public class GpsLocationProvider implements LocationProviderInterface {
native_inject_xtra_data(data, data.length); native_inject_xtra_data(data, data.length);
} else { } else {
// try again later // try again later
// since this is delayed and not urgent we do not hold a wake lock here
mHandler.removeMessages(DOWNLOAD_XTRA_DATA); mHandler.removeMessages(DOWNLOAD_XTRA_DATA);
mHandler.sendMessageDelayed(Message.obtain(mHandler, DOWNLOAD_XTRA_DATA), RETRY_INTERVAL); mHandler.sendMessageDelayed(Message.obtain(mHandler, DOWNLOAD_XTRA_DATA), RETRY_INTERVAL);
} }
@@ -517,10 +520,7 @@ public class GpsLocationProvider implements LocationProviderInterface {
* Someday we might use this for network location injection to aid the GPS * Someday we might use this for network location injection to aid the GPS
*/ */
public void updateLocation(Location location) { public void updateLocation(Location location) {
mHandler.removeMessages(UPDATE_LOCATION); sendMessage(UPDATE_LOCATION, 0, location);
Message m = Message.obtain(mHandler, UPDATE_LOCATION);
m.obj = location;
mHandler.sendMessage(m);
} }
private void handleUpdateLocation(Location location) { private void handleUpdateLocation(Location location) {
@@ -614,10 +614,7 @@ public class GpsLocationProvider implements LocationProviderInterface {
*/ */
public void enable() { public void enable() {
synchronized (mHandler) { synchronized (mHandler) {
mHandler.removeMessages(ENABLE); sendMessage(ENABLE, 1, null);
Message m = Message.obtain(mHandler, ENABLE);
m.arg1 = 1;
mHandler.sendMessage(m);
} }
} }
@@ -649,10 +646,7 @@ public class GpsLocationProvider implements LocationProviderInterface {
*/ */
public void disable() { public void disable() {
synchronized (mHandler) { synchronized (mHandler) {
mHandler.removeMessages(ENABLE); sendMessage(ENABLE, 0, null);
Message m = Message.obtain(mHandler, ENABLE);
m.arg1 = 0;
mHandler.sendMessage(m);
} }
} }
@@ -713,10 +707,7 @@ public class GpsLocationProvider implements LocationProviderInterface {
public void enableLocationTracking(boolean enable) { public void enableLocationTracking(boolean enable) {
synchronized (mHandler) { synchronized (mHandler) {
mHandler.removeMessages(ENABLE_TRACKING); sendMessage(ENABLE_TRACKING, (enable ? 1 : 0), null);
Message m = Message.obtain(mHandler, ENABLE_TRACKING);
m.arg1 = (enable ? 1 : 0);
mHandler.sendMessage(m);
} }
} }
@@ -770,9 +761,13 @@ public class GpsLocationProvider implements LocationProviderInterface {
} }
public void addListener(int uid) { public void addListener(int uid) {
Message m = Message.obtain(mHandler, ADD_LISTENER); synchronized (mWakeLock) {
m.arg1 = uid; mPendingListenerMessages++;
mHandler.sendMessage(m); mWakeLock.acquire();
Message m = Message.obtain(mHandler, ADD_LISTENER);
m.arg1 = uid;
mHandler.sendMessage(m);
}
} }
private void handleAddListener(int uid) { private void handleAddListener(int uid) {
@@ -794,9 +789,13 @@ public class GpsLocationProvider implements LocationProviderInterface {
} }
public void removeListener(int uid) { public void removeListener(int uid) {
Message m = Message.obtain(mHandler, REMOVE_LISTENER); synchronized (mWakeLock) {
m.arg1 = uid; mPendingListenerMessages++;
mHandler.sendMessage(m); mWakeLock.acquire();
Message m = Message.obtain(mHandler, REMOVE_LISTENER);
m.arg1 = uid;
mHandler.sendMessage(m);
}
} }
private void handleRemoveListener(int uid) { private void handleRemoveListener(int uid) {
@@ -823,8 +822,7 @@ public class GpsLocationProvider implements LocationProviderInterface {
return deleteAidingData(extras); return deleteAidingData(extras);
} }
if ("force_time_injection".equals(command)) { if ("force_time_injection".equals(command)) {
mHandler.removeMessages(INJECT_NTP_TIME); sendMessage(INJECT_NTP_TIME, 0, null);
mHandler.sendMessage(Message.obtain(mHandler, INJECT_NTP_TIME));
return true; return true;
} }
if ("force_xtra_injection".equals(command)) { if ("force_xtra_injection".equals(command)) {
@@ -1037,12 +1035,6 @@ public class GpsLocationProvider implements LocationProviderInterface {
break; break;
} }
// beware, the events can come out of order
if ((mNavigating || mEngineOn) && !mWakeLock.isHeld()) {
if (DEBUG) Log.d(TAG, "Acquiring wakelock");
mWakeLock.acquire();
}
if (wasNavigating != mNavigating) { if (wasNavigating != mNavigating) {
int size = mListeners.size(); int size = mListeners.size();
for (int i = 0; i < size; i++) { for (int i = 0; i < size; i++) {
@@ -1080,12 +1072,6 @@ public class GpsLocationProvider implements LocationProviderInterface {
intent.putExtra(LocationManager.EXTRA_GPS_ENABLED, mNavigating); intent.putExtra(LocationManager.EXTRA_GPS_ENABLED, mNavigating);
mContext.sendBroadcast(intent); mContext.sendBroadcast(intent);
} }
// beware, the events can come out of order
if (!mNavigating && !mEngineOn && mWakeLock.isHeld()) {
if (DEBUG) Log.d(TAG, "Releasing wakelock");
mWakeLock.release();
}
} }
} }
@@ -1213,8 +1199,7 @@ public class GpsLocationProvider implements LocationProviderInterface {
*/ */
private void xtraDownloadRequest() { private void xtraDownloadRequest() {
if (DEBUG) Log.d(TAG, "xtraDownloadRequest"); if (DEBUG) Log.d(TAG, "xtraDownloadRequest");
mHandler.removeMessages(DOWNLOAD_XTRA_DATA); sendMessage(DOWNLOAD_XTRA_DATA, 0, null);
mHandler.sendMessage(Message.obtain(mHandler, DOWNLOAD_XTRA_DATA));
} }
//============================================================= //=============================================================
@@ -1329,11 +1314,25 @@ public class GpsLocationProvider implements LocationProviderInterface {
} }
} }
private void sendMessage(int message, int arg, Object obj) {
// hold a wake lock while messages are pending
synchronized (mWakeLock) {
mPendingMessageBits |= (1 << message);
mWakeLock.acquire();
mHandler.removeMessages(message);
Message m = Message.obtain(mHandler, message);
m.arg1 = arg;
m.obj = obj;
mHandler.sendMessage(m);
}
}
private final class ProviderHandler extends Handler { private final class ProviderHandler extends Handler {
@Override @Override
public void handleMessage(Message msg) public void handleMessage(Message msg)
{ {
switch (msg.what) { int message = msg.what;
switch (message) {
case ENABLE: case ENABLE:
if (msg.arg1 == 1) { if (msg.arg1 == 1) {
handleEnable(); handleEnable();
@@ -1365,6 +1364,16 @@ public class GpsLocationProvider implements LocationProviderInterface {
handleRemoveListener(msg.arg1); handleRemoveListener(msg.arg1);
break; break;
} }
// release wake lock if no messages are pending
synchronized (mWakeLock) {
mPendingMessageBits &= ~(1 << message);
if (message == ADD_LISTENER || message == REMOVE_LISTENER) {
mPendingListenerMessages--;
}
if (mPendingMessageBits == 0 && mPendingListenerMessages == 0) {
mWakeLock.release();
}
}
} }
}; };