Possibly fix an issue where we thought an app was always using GPS.

There may be some race conditions in the gps provider where it can cause a uid
to be double booked for gps usage and never released.  Address this by tweaking
some locking (so mLocation and the uid array are protected by a lock both when
reading and writing).  Also add some code to log a warning if someone tries to
note a particular uid multiple times, since the code will break in that case.

Finally, fix a problem in the battery stats where we weren't allowing a new Uid
structure to be created in many cases for calls coming in.
This commit is contained in:
Dianne Hackborn
2009-06-22 20:00:17 -07:00
parent 61ab270c17
commit 2e41842898
2 changed files with 64 additions and 89 deletions

View File

@ -984,11 +984,11 @@ public final class BatteryStatsImpl extends BatteryStats {
} }
public void noteStartGps(int uid) { public void noteStartGps(int uid) {
mUidStats.get(uid).noteStartGps(); getUidStatsLocked(uid).noteStartGps();
} }
public void noteStopGps(int uid) { public void noteStopGps(int uid) {
mUidStats.get(uid).noteStopGps(); getUidStatsLocked(uid).noteStopGps();
} }
public void noteScreenOnLocked() { public void noteScreenOnLocked() {
@ -1032,10 +1032,7 @@ public final class BatteryStatsImpl extends BatteryStats {
} }
public void noteUserActivityLocked(int uid, int event) { public void noteUserActivityLocked(int uid, int event) {
Uid u = mUidStats.get(uid); getUidStatsLocked(uid).noteUserActivityLocked(event);
if (u != null) {
u.noteUserActivityLocked(event);
}
} }
public void notePhoneOnLocked() { public void notePhoneOnLocked() {
@ -1115,16 +1112,10 @@ public final class BatteryStatsImpl extends BatteryStats {
} }
if (mWifiOnUid != uid) { if (mWifiOnUid != uid) {
if (mWifiOnUid >= 0) { if (mWifiOnUid >= 0) {
Uid u = mUidStats.get(mWifiOnUid); getUidStatsLocked(mWifiOnUid).noteWifiTurnedOffLocked();
if (u != null) {
u.noteWifiTurnedOffLocked();
}
} }
mWifiOnUid = uid; mWifiOnUid = uid;
Uid u = mUidStats.get(uid); getUidStatsLocked(uid).noteWifiTurnedOnLocked();
if (u != null) {
u.noteWifiTurnedOnLocked();
}
} }
} }
@ -1134,10 +1125,7 @@ public final class BatteryStatsImpl extends BatteryStats {
mWifiOnTimer.stopRunningLocked(this); mWifiOnTimer.stopRunningLocked(this);
} }
if (mWifiOnUid >= 0) { if (mWifiOnUid >= 0) {
Uid u = mUidStats.get(mWifiOnUid); getUidStatsLocked(mWifiOnUid).noteWifiTurnedOffLocked();
if (u != null) {
u.noteWifiTurnedOffLocked();
}
mWifiOnUid = -1; mWifiOnUid = -1;
} }
} }
@ -1147,10 +1135,7 @@ public final class BatteryStatsImpl extends BatteryStats {
mAudioOn = true; mAudioOn = true;
mAudioOnTimer.startRunningLocked(this); mAudioOnTimer.startRunningLocked(this);
} }
Uid u = mUidStats.get(uid); getUidStatsLocked(uid).noteAudioTurnedOnLocked();
if (u != null) {
u.noteAudioTurnedOnLocked();
}
} }
public void noteAudioOffLocked(int uid) { public void noteAudioOffLocked(int uid) {
@ -1158,10 +1143,7 @@ public final class BatteryStatsImpl extends BatteryStats {
mAudioOn = false; mAudioOn = false;
mAudioOnTimer.stopRunningLocked(this); mAudioOnTimer.stopRunningLocked(this);
} }
Uid u = mUidStats.get(uid); getUidStatsLocked(uid).noteAudioTurnedOffLocked();
if (u != null) {
u.noteAudioTurnedOffLocked();
}
} }
public void noteVideoOnLocked(int uid) { public void noteVideoOnLocked(int uid) {
@ -1169,10 +1151,7 @@ public final class BatteryStatsImpl extends BatteryStats {
mVideoOn = true; mVideoOn = true;
mVideoOnTimer.startRunningLocked(this); mVideoOnTimer.startRunningLocked(this);
} }
Uid u = mUidStats.get(uid); getUidStatsLocked(uid).noteVideoTurnedOnLocked();
if (u != null) {
u.noteVideoTurnedOnLocked();
}
} }
public void noteVideoOffLocked(int uid) { public void noteVideoOffLocked(int uid) {
@ -1180,10 +1159,7 @@ public final class BatteryStatsImpl extends BatteryStats {
mVideoOn = false; mVideoOn = false;
mVideoOnTimer.stopRunningLocked(this); mVideoOnTimer.stopRunningLocked(this);
} }
Uid u = mUidStats.get(uid); getUidStatsLocked(uid).noteVideoTurnedOffLocked();
if (u != null) {
u.noteVideoTurnedOffLocked();
}
} }
public void noteWifiRunningLocked() { public void noteWifiRunningLocked() {
@ -1215,45 +1191,27 @@ public final class BatteryStatsImpl extends BatteryStats {
} }
public void noteFullWifiLockAcquiredLocked(int uid) { public void noteFullWifiLockAcquiredLocked(int uid) {
Uid u = mUidStats.get(uid); getUidStatsLocked(uid).noteFullWifiLockAcquiredLocked();
if (u != null) {
u.noteFullWifiLockAcquiredLocked();
}
} }
public void noteFullWifiLockReleasedLocked(int uid) { public void noteFullWifiLockReleasedLocked(int uid) {
Uid u = mUidStats.get(uid); getUidStatsLocked(uid).noteFullWifiLockReleasedLocked();
if (u != null) {
u.noteFullWifiLockReleasedLocked();
}
} }
public void noteScanWifiLockAcquiredLocked(int uid) { public void noteScanWifiLockAcquiredLocked(int uid) {
Uid u = mUidStats.get(uid); getUidStatsLocked(uid).noteScanWifiLockAcquiredLocked();
if (u != null) {
u.noteScanWifiLockAcquiredLocked();
}
} }
public void noteScanWifiLockReleasedLocked(int uid) { public void noteScanWifiLockReleasedLocked(int uid) {
Uid u = mUidStats.get(uid); getUidStatsLocked(uid).noteScanWifiLockReleasedLocked();
if (u != null) {
u.noteScanWifiLockReleasedLocked();
}
} }
public void noteWifiMulticastEnabledLocked(int uid) { public void noteWifiMulticastEnabledLocked(int uid) {
Uid u = mUidStats.get(uid); getUidStatsLocked(uid).noteWifiMulticastEnabledLocked();
if (u != null) {
u.noteWifiMulticastEnabledLocked();
}
} }
public void noteWifiMulticastDisabledLocked(int uid) { public void noteWifiMulticastDisabledLocked(int uid) {
Uid u = mUidStats.get(uid); getUidStatsLocked(uid).noteWifiMulticastDisabledLocked();
if (u != null) {
u.noteWifiMulticastDisabledLocked();
}
} }
@Override public long getScreenOnTime(long batteryRealtime, int which) { @Override public long getScreenOnTime(long batteryRealtime, int which) {

View File

@ -621,23 +621,37 @@ public class GpsLocationProvider extends ILocationProvider.Stub {
} }
public void addListener(int uid) { public void addListener(int uid) {
mClientUids.put(uid, 0); synchronized(mListeners) {
if (mNavigating) { if (mClientUids.indexOfKey(uid) >= 0) {
try { // Shouldn't be here -- already have this uid.
mBatteryStats.noteStartGps(uid); Log.w(TAG, "Duplicate add listener for uid " + uid);
} catch (RemoteException e) { return;
Log.w(TAG, "RemoteException in addListener"); }
mClientUids.put(uid, 0);
if (mNavigating) {
try {
mBatteryStats.noteStartGps(uid);
} catch (RemoteException e) {
Log.w(TAG, "RemoteException in addListener");
}
} }
} }
} }
public void removeListener(int uid) { public void removeListener(int uid) {
mClientUids.delete(uid); synchronized(mListeners) {
if (mNavigating) { if (mClientUids.indexOfKey(uid) < 0) {
try { // Shouldn't be here -- don't have this uid.
mBatteryStats.noteStopGps(uid); Log.w(TAG, "Unneeded remove listener for uid " + uid);
} catch (RemoteException e) { return;
Log.w(TAG, "RemoteException in removeListener"); }
mClientUids.delete(uid);
if (mNavigating) {
try {
mBatteryStats.noteStopGps(uid);
} catch (RemoteException e) {
Log.w(TAG, "RemoteException in removeListener");
}
} }
} }
} }
@ -836,30 +850,33 @@ public class GpsLocationProvider extends ILocationProvider.Stub {
private void reportStatus(int status) { private void reportStatus(int status) {
if (VERBOSE) Log.v(TAG, "reportStatus status: " + status); if (VERBOSE) Log.v(TAG, "reportStatus status: " + status);
boolean wasNavigating = mNavigating; synchronized(mListeners) {
mNavigating = (status == GPS_STATUS_SESSION_BEGIN); boolean wasNavigating = mNavigating;
mNavigating = (status == GPS_STATUS_SESSION_BEGIN);
if (wasNavigating != mNavigating) {
if (wasNavigating == mNavigating) {
return;
}
if (mNavigating) { if (mNavigating) {
if (DEBUG) Log.d(TAG, "Acquiring wakelock"); if (DEBUG) Log.d(TAG, "Acquiring wakelock");
mWakeLock.acquire(); mWakeLock.acquire();
} }
synchronized(mListeners) {
int size = mListeners.size(); int size = mListeners.size();
for (int i = 0; i < size; i++) { for (int i = 0; i < size; i++) {
Listener listener = mListeners.get(i); Listener listener = mListeners.get(i);
try { try {
if (mNavigating) { if (mNavigating) {
listener.mListener.onGpsStarted(); listener.mListener.onGpsStarted();
} else { } else {
listener.mListener.onGpsStopped(); listener.mListener.onGpsStopped();
}
} catch (RemoteException e) {
Log.w(TAG, "RemoteException in reportStatus");
mListeners.remove(listener);
// adjust for size of list changing
size--;
} }
} catch (RemoteException e) {
Log.w(TAG, "RemoteException in reportStatus");
mListeners.remove(listener);
// adjust for size of list changing
size--;
} }
} }