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:
@ -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) {
|
||||||
|
@ -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--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user