summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAmith Yamasani <yamasani@google.com>2009-10-08 18:28:01 -0700
committerAmith Yamasani <yamasani@google.com>2009-10-19 15:16:26 -0700
commitf37447bad3773b62176baa837908daf6edb44273 (patch)
treefb8f45b23288aeb84873c7e7735373505a98c977
parentb5d69242d10021f82632d62c30b1ce63785c9386 (diff)
downloadframeworks_base-f37447bad3773b62176baa837908daf6edb44273.zip
frameworks_base-f37447bad3773b62176baa837908daf6edb44273.tar.gz
frameworks_base-f37447bad3773b62176baa837908daf6edb44273.tar.bz2
Proper fix for zero signal strength and no_service. Fixes #2176141
Track phone service state changes and use a separate timer for out-of-service since the hunting can timeout on some devices. Store the timeout value in the config.xml, as it is device/network specific. Settings App will also change to use the hunting duration to compute the cost of zero signal.
-rw-r--r--core/java/android/os/BatteryStats.java20
-rw-r--r--core/java/com/android/internal/app/IBatteryStats.aidl2
-rw-r--r--core/java/com/android/internal/os/BatteryStatsImpl.java100
-rw-r--r--core/java/com/android/internal/os/PowerProfile.java5
-rw-r--r--core/res/res/values/config.xml4
-rw-r--r--core/res/res/xml/power_profile.xml4
-rw-r--r--services/java/com/android/server/TelephonyRegistry.java2
-rw-r--r--services/java/com/android/server/am/BatteryStatsService.java7
8 files changed, 117 insertions, 27 deletions
diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java
index a49a27a0..b706c5c 100644
--- a/core/java/android/os/BatteryStats.java
+++ b/core/java/android/os/BatteryStats.java
@@ -130,6 +130,7 @@ public abstract class BatteryStats implements Parcelable {
private static final String MISC_DATA = "m";
private static final String SCREEN_BRIGHTNESS_DATA = "br";
private static final String SIGNAL_STRENGTH_TIME_DATA = "sgt";
+ private static final String SIGNAL_SCANNING_TIME_DATA = "sst";
private static final String SIGNAL_STRENGTH_COUNT_DATA = "sgc";
private static final String DATA_CONNECTION_TIME_DATA = "dct";
private static final String DATA_CONNECTION_COUNT_DATA = "dcc";
@@ -440,6 +441,15 @@ public abstract class BatteryStats implements Parcelable {
long batteryRealtime, int which);
/**
+ * Returns the time in microseconds that the phone has been trying to
+ * acquire a signal.
+ *
+ * {@hide}
+ */
+ public abstract long getPhoneSignalScanningTime(
+ long batteryRealtime, int which);
+
+ /**
* Returns the number of times the phone has entered the given signal strength.
*
* {@hide}
@@ -823,6 +833,8 @@ public abstract class BatteryStats implements Parcelable {
args[i] = getPhoneSignalStrengthTime(i, batteryRealtime, which) / 1000;
}
dumpLine(pw, 0 /* uid */, category, SIGNAL_STRENGTH_TIME_DATA, args);
+ dumpLine(pw, 0 /* uid */, category, SIGNAL_SCANNING_TIME_DATA,
+ getPhoneSignalScanningTime(batteryRealtime, which) / 1000);
for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) {
args[i] = getPhoneSignalStrengthCount(i, which);
}
@@ -1130,7 +1142,13 @@ public abstract class BatteryStats implements Parcelable {
}
if (!didOne) sb.append("No activity");
pw.println(sb.toString());
-
+
+ sb.setLength(0);
+ sb.append(prefix);
+ sb.append(" Signal scanning time: ");
+ formatTimeMs(sb, getPhoneSignalScanningTime(batteryRealtime, which) / 1000);
+ pw.println(sb.toString());
+
sb.setLength(0);
sb.append(prefix);
sb.append(" Radio types: ");
diff --git a/core/java/com/android/internal/app/IBatteryStats.aidl b/core/java/com/android/internal/app/IBatteryStats.aidl
index 4bac593..d5ccdeb 100644
--- a/core/java/com/android/internal/app/IBatteryStats.aidl
+++ b/core/java/com/android/internal/app/IBatteryStats.aidl
@@ -37,7 +37,7 @@ interface IBatteryStats {
void notePhoneOff();
void notePhoneSignalStrength(in SignalStrength signalStrength);
void notePhoneDataConnectionState(int dataType, boolean hasData);
- void noteAirplaneMode(boolean isAirplaneMode);
+ void notePhoneState(int phoneState);
void noteWifiOn(int uid);
void noteWifiOff(int uid);
void noteWifiRunning();
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java
index 4b26b8f..8698cb7 100644
--- a/core/java/com/android/internal/os/BatteryStatsImpl.java
+++ b/core/java/com/android/internal/os/BatteryStatsImpl.java
@@ -24,6 +24,7 @@ import android.os.ParcelFormatException;
import android.os.Parcelable;
import android.os.Process;
import android.os.SystemClock;
+import android.telephony.ServiceState;
import android.telephony.SignalStrength;
import android.telephony.TelephonyManager;
import android.util.Log;
@@ -56,7 +57,7 @@ public final class BatteryStatsImpl extends BatteryStats {
private static final int MAGIC = 0xBA757475; // 'BATSTATS'
// Current on-disk Parcel version
- private static final int VERSION = 40;
+ private static final int VERSION = 41;
private static int sNumSpeedSteps;
@@ -117,7 +118,9 @@ public final class BatteryStatsImpl extends BatteryStats {
int mPhoneSignalStrengthBin = -1;
final StopwatchTimer[] mPhoneSignalStrengthsTimer =
new StopwatchTimer[NUM_SIGNAL_STRENGTH_BINS];
-
+
+ StopwatchTimer mPhoneSignalScanningTimer;
+
int mPhoneDataConnectionType = -1;
final StopwatchTimer[] mPhoneDataConnectionsTimer =
new StopwatchTimer[NUM_DATA_CONNECTION_TYPES];
@@ -169,6 +172,8 @@ public final class BatteryStatsImpl extends BatteryStats {
private int mBluetoothPingCount;
private int mBluetoothPingStart = -1;
+ private int mPhoneServiceState = -1;
+
/*
* Holds a SamplingTimer associated with each kernel wakelock name being tracked.
*/
@@ -681,6 +686,8 @@ public final class BatteryStatsImpl extends BatteryStats {
*/
long mAcquireTime;
+ long mTimeout;
+
StopwatchTimer(int type, ArrayList<StopwatchTimer> timerPool,
ArrayList<Unpluggable> unpluggables, Parcel in) {
super(type, unpluggables, in);
@@ -694,6 +701,10 @@ public final class BatteryStatsImpl extends BatteryStats {
mTimerPool = timerPool;
}
+ void setTimeout(long timeout) {
+ mTimeout = timeout;
+ }
+
public void writeToParcel(Parcel out, long batteryRealtime) {
super.writeToParcel(out, batteryRealtime);
out.writeLong(mUpdateTime);
@@ -797,6 +808,9 @@ public final class BatteryStatsImpl extends BatteryStats {
@Override
protected long computeRunTimeLocked(long curBatteryRealtime) {
+ if (mTimeout > 0 && curBatteryRealtime > mUpdateTime + mTimeout) {
+ curBatteryRealtime = mUpdateTime + mTimeout;
+ }
return mTotalTime + (mNesting > 0
? (curBatteryRealtime - mUpdateTime)
/ (mTimerPool != null ? mTimerPool.size() : 1)
@@ -1123,34 +1137,59 @@ public final class BatteryStatsImpl extends BatteryStats {
}
}
- public void noteAirplaneModeLocked(boolean isAirplaneMode) {
- final int bin = mPhoneSignalStrengthBin;
- if (bin >= 0) {
- if (!isAirplaneMode) {
- if (!mPhoneSignalStrengthsTimer[bin].isRunningLocked()) {
- mPhoneSignalStrengthsTimer[bin].startRunningLocked(this);
- }
- } else {
- for (int i = 0; i < NUM_SIGNAL_STRENGTH_BINS; i++) {
- while (mPhoneSignalStrengthsTimer[i].isRunningLocked()) {
- mPhoneSignalStrengthsTimer[i].stopRunningLocked(this);
- }
+ /**
+ * Telephony stack updates the phone state.
+ * @param state phone state from ServiceState.getState()
+ */
+ public void notePhoneStateLocked(int state) {
+ int bin = mPhoneSignalStrengthBin;
+ boolean isAirplaneMode = state == ServiceState.STATE_POWER_OFF;
+ // Stop all timers
+ if (isAirplaneMode || state == ServiceState.STATE_OUT_OF_SERVICE) {
+ for (int i = 0; i < NUM_SIGNAL_STRENGTH_BINS; i++) {
+ while (mPhoneSignalStrengthsTimer[i].isRunningLocked()) {
+ mPhoneSignalStrengthsTimer[i].stopRunningLocked(this);
}
}
}
+ // Stop Signal Scanning timer, in case we're going into service
+ while (mPhoneSignalScanningTimer.isRunningLocked()) {
+ mPhoneSignalScanningTimer.stopRunningLocked(this);
+ }
+
+ // If we're back in service or continuing in service, restart the old timer.
+ if (state == ServiceState.STATE_IN_SERVICE) {
+ if (bin == -1) bin = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
+ if (!mPhoneSignalStrengthsTimer[bin].isRunningLocked()) {
+ mPhoneSignalStrengthsTimer[bin].startRunningLocked(this);
+ }
+ } else if (state == ServiceState.STATE_OUT_OF_SERVICE) {
+ mPhoneSignalStrengthBin = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
+ if (!mPhoneSignalStrengthsTimer[mPhoneSignalStrengthBin].isRunningLocked()) {
+ mPhoneSignalStrengthsTimer[mPhoneSignalStrengthBin].startRunningLocked(this);
+ }
+ if (!mPhoneSignalScanningTimer.isRunningLocked()) {
+ mPhoneSignalScanningTimer.startRunningLocked(this);
+ }
+ }
+ mPhoneServiceState = state;
}
public void notePhoneSignalStrengthLocked(SignalStrength signalStrength) {
// Bin the strength.
int bin;
-
+ if (mPhoneServiceState == ServiceState.STATE_POWER_OFF
+ || mPhoneServiceState == ServiceState.STATE_OUT_OF_SERVICE) {
+ // Ignore any signal strength changes when radio was turned off or out of service.
+ return;
+ }
if (!signalStrength.isGsm()) {
int dBm = signalStrength.getCdmaDbm();
- if (dBm >= -75) bin = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
- else if (dBm >= -85) bin = SIGNAL_STRENGTH_GREAT;
- else if (dBm >= -95) bin = SIGNAL_STRENGTH_GOOD;
- else if (dBm >= -100) bin = SIGNAL_STRENGTH_MODERATE;
- else bin = SIGNAL_STRENGTH_POOR;
+ if (dBm >= -75) bin = SIGNAL_STRENGTH_GREAT;
+ else if (dBm >= -85) bin = SIGNAL_STRENGTH_GOOD;
+ else if (dBm >= -95) bin = SIGNAL_STRENGTH_MODERATE;
+ else if (dBm >= -100) bin = SIGNAL_STRENGTH_POOR;
+ else bin = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
} else {
int asu = signalStrength.getGsmSignalStrength();
if (asu < 0 || asu >= 99) bin = SIGNAL_STRENGTH_NONE_OR_UNKNOWN;
@@ -1328,7 +1367,13 @@ public final class BatteryStatsImpl extends BatteryStats {
return mPhoneSignalStrengthsTimer[strengthBin].getTotalTimeLocked(
batteryRealtime, which);
}
-
+
+ @Override public long getPhoneSignalScanningTime(
+ long batteryRealtime, int which) {
+ return mPhoneSignalScanningTimer.getTotalTimeLocked(
+ batteryRealtime, which);
+ }
+
@Override public int getPhoneSignalStrengthCount(int dataType, int which) {
return mPhoneDataConnectionsTimer[dataType].getCountLocked(which);
}
@@ -2653,6 +2698,7 @@ public final class BatteryStatsImpl extends BatteryStats {
for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) {
mPhoneSignalStrengthsTimer[i] = new StopwatchTimer(-200-i, null, mUnpluggables);
}
+ mPhoneSignalScanningTimer = new StopwatchTimer(-200+1, null, mUnpluggables);
for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
mPhoneDataConnectionsTimer[i] = new StopwatchTimer(-300-i, null, mUnpluggables);
}
@@ -2679,6 +2725,12 @@ public final class BatteryStatsImpl extends BatteryStats {
if (sNumSpeedSteps == 0) sNumSpeedSteps = steps;
}
+ public void setRadioScanningTimeout(long timeout) {
+ if (mPhoneSignalScanningTimer != null) {
+ mPhoneSignalScanningTimer.setTimeout(timeout);
+ }
+ }
+
@Override
public int getStartCount() {
return mStartCount;
@@ -3114,6 +3166,7 @@ public final class BatteryStatsImpl extends BatteryStats {
for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) {
mPhoneSignalStrengthsTimer[i].readSummaryFromParcelLocked(in);
}
+ mPhoneSignalScanningTimer.readSummaryFromParcelLocked(in);
for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
mPhoneDataConnectionsTimer[i].readSummaryFromParcelLocked(in);
}
@@ -3257,6 +3310,7 @@ public final class BatteryStatsImpl extends BatteryStats {
for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) {
mPhoneSignalStrengthsTimer[i].writeSummaryFromParcelLocked(out, NOWREAL);
}
+ mPhoneSignalScanningTimer.writeSummaryFromParcelLocked(out, NOWREAL);
for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
mPhoneDataConnectionsTimer[i].writeSummaryFromParcelLocked(out, NOWREAL);
}
@@ -3418,6 +3472,7 @@ public final class BatteryStatsImpl extends BatteryStats {
for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) {
mPhoneSignalStrengthsTimer[i] = new StopwatchTimer(-200-i, null, mUnpluggables, in);
}
+ mPhoneSignalScanningTimer = new StopwatchTimer(-200+1, null, mUnpluggables, in);
for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
mPhoneDataConnectionsTimer[i] = new StopwatchTimer(-300-i, null, mUnpluggables, in);
}
@@ -3513,6 +3568,7 @@ public final class BatteryStatsImpl extends BatteryStats {
for (int i=0; i<NUM_SIGNAL_STRENGTH_BINS; i++) {
mPhoneSignalStrengthsTimer[i].writeToParcel(out, batteryRealtime);
}
+ mPhoneSignalScanningTimer.writeToParcel(out, batteryRealtime);
for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
mPhoneDataConnectionsTimer[i].writeToParcel(out, batteryRealtime);
}
@@ -3598,6 +3654,8 @@ public final class BatteryStatsImpl extends BatteryStats {
pr.println("*** Signal strength #" + i + ":");
mPhoneSignalStrengthsTimer[i].logState(pr, " ");
}
+ pr.println("*** Signal scanning :");
+ mPhoneSignalScanningTimer.logState(pr, " ");
for (int i=0; i<NUM_DATA_CONNECTION_TYPES; i++) {
pr.println("*** Data connection type #" + i + ":");
mPhoneDataConnectionsTimer[i].logState(pr, " ");
diff --git a/core/java/com/android/internal/os/PowerProfile.java b/core/java/com/android/internal/os/PowerProfile.java
index 4b4b717..2369d25 100644
--- a/core/java/com/android/internal/os/PowerProfile.java
+++ b/core/java/com/android/internal/os/PowerProfile.java
@@ -97,6 +97,11 @@ public class PowerProfile {
public static final String POWER_RADIO_ON = "radio.on";
/**
+ * Power consumption when cell radio is hunting for a signal.
+ */
+ public static final String POWER_RADIO_SCANNING = "radio.scanning";
+
+ /**
* Power consumption when talking on the phone.
*/
public static final String POWER_RADIO_ACTIVE = "radio.active";
diff --git a/core/res/res/values/config.xml b/core/res/res/values/config.xml
index 45fcaa59..780f611 100644
--- a/core/res/res/values/config.xml
+++ b/core/res/res/values/config.xml
@@ -40,6 +40,10 @@
<!-- The duration (in milliseconds) of a long animation. -->
<integer name="config_longAnimTime">400</integer>
+ <!-- The duration (in milliseconds) that the radio will scan for a signal
+ when there's no network connection. If the scan doesn't timeout, use zero -->
+ <integer name="config_radioScanningTimeout">0</integer>
+
<!-- XXXXX NOTE THE FOLLOWING RESOURCES USE THE WRONG NAMING CONVENTION.
Please don't copy them, copy anything else. -->
diff --git a/core/res/res/xml/power_profile.xml b/core/res/res/xml/power_profile.xml
index 710b71e..ce623e8 100644
--- a/core/res/res/xml/power_profile.xml
+++ b/core/res/res/xml/power_profile.xml
@@ -29,10 +29,12 @@
<item name="dsp.audio">0.1</item>
<item name="dsp.video">0.1</item>
<item name="radio.active">1</item>
+ <!-- The current consumed by the radio when it is scanning for a signal -->
+ <item name="radio.scanning">0.5</item>
<item name="gps.on">1</item>
<!-- Current consumed by the radio at different signal strengths, when paging -->
<array name="radio.on"> <!-- Strength 0 to BINS-1 -->
- <value>1</value>
+ <value>0.2</value>
<value>0.1</value>
</array>
<!-- Different CPU speeds as reported in
diff --git a/services/java/com/android/server/TelephonyRegistry.java b/services/java/com/android/server/TelephonyRegistry.java
index 101b075..47cb6ad 100644
--- a/services/java/com/android/server/TelephonyRegistry.java
+++ b/services/java/com/android/server/TelephonyRegistry.java
@@ -477,7 +477,7 @@ class TelephonyRegistry extends ITelephonyRegistry.Stub {
private void broadcastServiceStateChanged(ServiceState state) {
long ident = Binder.clearCallingIdentity();
try {
- mBatteryStats.noteAirplaneMode(state.getState() == ServiceState.STATE_POWER_OFF);
+ mBatteryStats.notePhoneState(state.getState());
} catch (RemoteException re) {
// Can't do much
} finally {
diff --git a/services/java/com/android/server/am/BatteryStatsService.java b/services/java/com/android/server/am/BatteryStatsService.java
index 61537f5..5a1619a 100644
--- a/services/java/com/android/server/am/BatteryStatsService.java
+++ b/services/java/com/android/server/am/BatteryStatsService.java
@@ -51,6 +51,9 @@ public final class BatteryStatsService extends IBatteryStats.Stub {
mContext = context;
ServiceManager.addService("batteryinfo", asBinder());
mStats.setNumSpeedSteps(new PowerProfile(mContext).getNumSpeedSteps());
+ mStats.setRadioScanningTimeout(mContext.getResources().getInteger(
+ com.android.internal.R.integer.config_radioScanningTimeout)
+ * 1000L);
}
public void shutdown() {
@@ -195,10 +198,10 @@ public final class BatteryStatsService extends IBatteryStats.Stub {
}
}
- public void noteAirplaneMode(boolean airplaneMode) {
+ public void notePhoneState(int state) {
enforceCallingPermission();
synchronized (mStats) {
- mStats.noteAirplaneModeLocked(airplaneMode);
+ mStats.notePhoneStateLocked(state);
}
}