diff options
author | Dianne Hackborn <hackbod@google.com> | 2010-06-11 10:53:16 -0700 |
---|---|---|
committer | Android (Google) Code Review <android-gerrit@google.com> | 2010-06-11 10:53:16 -0700 |
commit | 9f8cc518e14c7a34bc52da712afbf02d84585f67 (patch) | |
tree | 20132f8e7504a7f481fc31c89370bcbbc157c807 | |
parent | f5eafe40cd3f0890dd4ce98a63c8f95b786a3dd9 (diff) | |
parent | 32907cfb38bda2d3c052cf5139c5b592678fedbb (diff) | |
download | frameworks_base-9f8cc518e14c7a34bc52da712afbf02d84585f67.zip frameworks_base-9f8cc518e14c7a34bc52da712afbf02d84585f67.tar.gz frameworks_base-9f8cc518e14c7a34bc52da712afbf02d84585f67.tar.bz2 |
Merge "Adjust activity manager process OOM adj." into kraken
-rw-r--r-- | api/current.xml | 13 | ||||
-rw-r--r-- | core/java/android/app/ActivityManager.java | 18 | ||||
-rw-r--r-- | core/java/android/os/BatteryStats.java | 83 | ||||
-rw-r--r-- | core/java/com/android/internal/os/BatteryStatsImpl.java | 236 | ||||
-rw-r--r-- | services/java/com/android/server/am/ActivityManagerService.java | 142 | ||||
-rw-r--r-- | services/java/com/android/server/am/BatteryStatsService.java | 2 |
6 files changed, 419 insertions, 75 deletions
diff --git a/api/current.xml b/api/current.xml index 8dd57f0..41b0423 100644 --- a/api/current.xml +++ b/api/current.xml @@ -21763,7 +21763,18 @@ type="int" transient="false" volatile="false" - value="150" + value="170" + static="true" + final="true" + deprecated="not deprecated" + visibility="public" +> +</field> +<field name="IMPORTANCE_PERCEPTIBLE" + type="int" + transient="false" + volatile="false" + value="130" static="true" final="true" deprecated="not deprecated" diff --git a/core/java/android/app/ActivityManager.java b/core/java/android/app/ActivityManager.java index 793b9d2..7f95bf5 100644 --- a/core/java/android/app/ActivityManager.java +++ b/core/java/android/app/ActivityManager.java @@ -726,16 +726,24 @@ public class ActivityManager { public static final int IMPORTANCE_FOREGROUND = 100; /** - * Constant for {@link #importance}: this process is running a - * heavy-weight application and thus should not be killed. + * Constant for {@link #importance}: this process is running something + * that is actively visible to the user, though not in the immediate + * foreground. */ - public static final int IMPORTANCE_HEAVY_WEIGHT = 150; + public static final int IMPORTANCE_VISIBLE = 200; /** * Constant for {@link #importance}: this process is running something - * that is considered to be actively visible to the user. + * that is considered to be actively perceptible to the user. An + * example would be an application performing background music playback. */ - public static final int IMPORTANCE_VISIBLE = 200; + public static final int IMPORTANCE_PERCEPTIBLE = 130; + + /** + * Constant for {@link #importance}: this process is running a + * heavy-weight application and thus should not be killed. + */ + public static final int IMPORTANCE_HEAVY_WEIGHT = 170; /** * Constant for {@link #importance}: this process is contains services diff --git a/core/java/android/os/BatteryStats.java b/core/java/android/os/BatteryStats.java index d114bff..4adeaeb 100644 --- a/core/java/android/os/BatteryStats.java +++ b/core/java/android/os/BatteryStats.java @@ -51,50 +51,36 @@ public abstract class BatteryStats implements Parcelable { /** * A constant indicating a sensor timer. - * - * {@hide} */ public static final int SENSOR = 3; /** * A constant indicating a a wifi turn on timer - * - * {@hide} */ public static final int WIFI_TURNED_ON = 4; /** * A constant indicating a full wifi lock timer - * - * {@hide} */ public static final int FULL_WIFI_LOCK = 5; /** * A constant indicating a scan wifi lock timer - * - * {@hide} */ public static final int SCAN_WIFI_LOCK = 6; /** * A constant indicating a wifi multicast timer - * - * {@hide} */ public static final int WIFI_MULTICAST_ENABLED = 7; /** * A constant indicating an audio turn on timer - * - * {@hide} */ public static final int AUDIO_TURNED_ON = 7; /** * A constant indicating a video turn on timer - * - * {@hide} */ public static final int VIDEO_TURNED_ON = 8; @@ -391,6 +377,61 @@ public abstract class BatteryStats implements Parcelable { } } + public final class BatteryHistoryRecord implements Parcelable { + public BatteryHistoryRecord next; + + public long time; + public byte batteryLevel; + + public static final int STATE_SCREEN_MASK = 0x000000f; + public static final int STATE_SCREEN_SHIFT = 0; + public static final int STATE_SIGNAL_STRENGTH_MASK = 0x00000f0; + public static final int STATE_SIGNAL_STRENGTH_SHIFT = 4; + public static final int STATE_PHONE_STATE_MASK = 0x0000f00; + public static final int STATE_PHONE_STATE_SHIFT = 8; + public static final int STATE_DATA_CONNECTION_MASK = 0x000f000; + public static final int STATE_DATA_CONNECTION_SHIFT = 12; + + public static final int STATE_BATTERY_PLUGGED_FLAG = 1<<30; + public static final int STATE_SCREEN_ON_FLAG = 1<<29; + public static final int STATE_GPS_ON_FLAG = 1<<28; + public static final int STATE_PHONE_ON_FLAG = 1<<27; + public static final int STATE_WIFI_ON_FLAG = 1<<26; + public static final int STATE_WIFI_RUNNING_FLAG = 1<<25; + public static final int STATE_WIFI_FULL_LOCK_FLAG = 1<<24; + public static final int STATE_WIFI_SCAN_LOCK_FLAG = 1<<23; + public static final int STATE_WIFI_MULTICAST_ON_FLAG = 1<<22; + public static final int STATE_BLUETOOTH_ON_FLAG = 1<<21; + public static final int STATE_AUDIO_ON_FLAG = 1<<20; + public static final int STATE_VIDEO_ON_FLAG = 1<<19; + + public int states; + + public BatteryHistoryRecord() { + } + + public BatteryHistoryRecord(long time, Parcel src) { + this.time = time; + batteryLevel = (byte)src.readInt(); + states = src.readInt(); + } + + public int describeContents() { + return 0; + } + + public void writeToParcel(Parcel dest, int flags) { + dest.writeLong(time); + dest.writeInt(batteryLevel); + dest.writeInt(states); + } + } + + /** + * Return the current history of battery state changes. + */ + public abstract BatteryHistoryRecord getHistory(); + /** * Returns the number of times the device has been started. */ @@ -1443,6 +1484,20 @@ public abstract class BatteryStats implements Parcelable { */ @SuppressWarnings("unused") public void dumpLocked(PrintWriter pw) { + BatteryHistoryRecord rec = getHistory(); + if (rec != null) { + pw.println("Battery History:"); + while (rec != null) { + pw.print(" "); + pw.print(rec.time); + pw.print(" "); + pw.print(rec.batteryLevel); + pw.print(" "); + pw.println(Integer.toHexString(rec.states)); + rec = rec.next; + } + } + pw.println("Total Statistics (Current and Historic):"); pw.println(" System starts: " + getStartCount() + ", currently on battery: " + getIsOnBattery()); diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java index aadb576..3833725 100644 --- a/core/java/com/android/internal/os/BatteryStatsImpl.java +++ b/core/java/com/android/internal/os/BatteryStatsImpl.java @@ -56,12 +56,13 @@ import java.util.concurrent.atomic.AtomicInteger; public final class BatteryStatsImpl extends BatteryStats { private static final String TAG = "BatteryStatsImpl"; private static final boolean DEBUG = false; - + private static final boolean DEBUG_HISTORY = false; + // In-memory Parcel magic number, used to detect attempts to unmarshall bad data private static final int MAGIC = 0xBA757475; // 'BATSTATS' // Current on-disk Parcel version - private static final int VERSION = 43; + private static final int VERSION = 44; // The maximum number of names wakelocks we will keep track of // per uid; once the limit is reached, we batch the remaining wakelocks @@ -94,6 +95,11 @@ public final class BatteryStatsImpl extends BatteryStats { // is unplugged from power. final ArrayList<Unpluggable> mUnpluggables = new ArrayList<Unpluggable>(); + BatteryHistoryRecord mHistory; + BatteryHistoryRecord mHistoryEnd; + BatteryHistoryRecord mHistoryCache; + final BatteryHistoryRecord mHistoryCur = new BatteryHistoryRecord(); + int mStartCount; long mBatteryUptime; @@ -1042,6 +1048,37 @@ public final class BatteryStatsImpl extends BatteryStats { mBtHeadset = headset; } + void addHistoryRecord(long curTime) { + BatteryHistoryRecord rec = mHistoryCache; + if (rec != null) { + mHistoryCache = rec.next; + } else { + rec = new BatteryHistoryRecord(); + } + rec.time = curTime; + rec.batteryLevel = mHistoryCur.batteryLevel; + rec.states = mHistoryCur.states; + addHistoryRecord(rec); + } + + void addHistoryRecord(BatteryHistoryRecord rec) { + rec.next = null; + if (mHistoryEnd != null) { + mHistoryEnd.next = rec; + mHistoryEnd = rec; + } else { + mHistory = mHistoryEnd = rec; + } + } + + void clearHistory() { + if (mHistory != null) { + mHistoryEnd.next = mHistoryCache; + mHistoryCache = mHistory; + mHistory = mHistoryEnd = null; + } + } + public void doUnplug(long batteryUptime, long batteryRealtime) { for (int iu = mUidStats.size() - 1; iu >= 0; iu--) { Uid u = mUidStats.valueAt(iu); @@ -1094,16 +1131,37 @@ public final class BatteryStatsImpl extends BatteryStats { mBluetoothPingStart = -1; } + int mGpsNesting; + public void noteStartGps(int uid) { + if (mGpsNesting == 0) { + mHistoryCur.states |= BatteryHistoryRecord.STATE_GPS_ON_FLAG; + if (DEBUG_HISTORY) Slog.v(TAG, "Start GPS to: " + + Integer.toHexString(mHistoryCur.states)); + addHistoryRecord(SystemClock.elapsedRealtime()); + } + mGpsNesting++; getUidStatsLocked(uid).noteStartGps(); } public void noteStopGps(int uid) { + mGpsNesting--; + if (mGpsNesting == 0) { + mHistoryCur.states &= ~BatteryHistoryRecord.STATE_GPS_ON_FLAG; + if (DEBUG_HISTORY) Slog.v(TAG, "Stop GPS to: " + + Integer.toHexString(mHistoryCur.states)); + addHistoryRecord(SystemClock.elapsedRealtime()); + } getUidStatsLocked(uid).noteStopGps(); } public void noteScreenOnLocked() { if (!mScreenOn) { + mHistoryCur.states |= BatteryHistoryRecord.STATE_SCREEN_ON_FLAG; + if (DEBUG_HISTORY) Slog.v(TAG, "Screen on to: " + + Integer.toHexString(mHistoryCur.states)); + addHistoryRecord(SystemClock.elapsedRealtime()); + mGpsNesting++; mScreenOn = true; mScreenOnTimer.startRunningLocked(this); if (mScreenBrightnessBin >= 0) { @@ -1114,6 +1172,10 @@ public final class BatteryStatsImpl extends BatteryStats { public void noteScreenOffLocked() { if (mScreenOn) { + mHistoryCur.states &= ~BatteryHistoryRecord.STATE_SCREEN_ON_FLAG; + if (DEBUG_HISTORY) Slog.v(TAG, "Screen off to: " + + Integer.toHexString(mHistoryCur.states)); + addHistoryRecord(SystemClock.elapsedRealtime()); mScreenOn = false; mScreenOnTimer.stopRunningLocked(this); if (mScreenBrightnessBin >= 0) { @@ -1128,6 +1190,11 @@ public final class BatteryStatsImpl extends BatteryStats { if (bin < 0) bin = 0; else if (bin >= NUM_SCREEN_BRIGHTNESS_BINS) bin = NUM_SCREEN_BRIGHTNESS_BINS-1; if (mScreenBrightnessBin != bin) { + mHistoryCur.states = (mHistoryCur.states&~BatteryHistoryRecord.STATE_SCREEN_MASK) + | (bin << BatteryHistoryRecord.STATE_SCREEN_SHIFT); + if (DEBUG_HISTORY) Slog.v(TAG, "Screen brightness " + bin + " to: " + + Integer.toHexString(mHistoryCur.states)); + addHistoryRecord(SystemClock.elapsedRealtime()); if (mScreenOn) { if (mScreenBrightnessBin >= 0) { mScreenBrightnessTimer[mScreenBrightnessBin].stopRunningLocked(this); @@ -1148,6 +1215,10 @@ public final class BatteryStatsImpl extends BatteryStats { public void notePhoneOnLocked() { if (!mPhoneOn) { + mHistoryCur.states |= BatteryHistoryRecord.STATE_PHONE_ON_FLAG; + if (DEBUG_HISTORY) Slog.v(TAG, "Phone on to: " + + Integer.toHexString(mHistoryCur.states)); + addHistoryRecord(SystemClock.elapsedRealtime()); mPhoneOn = true; mPhoneOnTimer.startRunningLocked(this); } @@ -1155,6 +1226,10 @@ public final class BatteryStatsImpl extends BatteryStats { public void notePhoneOffLocked() { if (mPhoneOn) { + mHistoryCur.states &= ~BatteryHistoryRecord.STATE_PHONE_ON_FLAG; + if (DEBUG_HISTORY) Slog.v(TAG, "Phone off to: " + + Integer.toHexString(mHistoryCur.states)); + addHistoryRecord(SystemClock.elapsedRealtime()); mPhoneOn = false; mPhoneOnTimer.stopRunningLocked(this); } @@ -1195,7 +1270,15 @@ public final class BatteryStatsImpl extends BatteryStats { mPhoneSignalScanningTimer.startRunningLocked(this); } } - mPhoneServiceState = state; + + if (mPhoneServiceState != state) { + mHistoryCur.states = (mHistoryCur.states&~BatteryHistoryRecord.STATE_PHONE_STATE_MASK) + | (state << BatteryHistoryRecord.STATE_PHONE_STATE_SHIFT); + if (DEBUG_HISTORY) Slog.v(TAG, "Phone state " + bin + " to: " + + Integer.toHexString(mHistoryCur.states)); + addHistoryRecord(SystemClock.elapsedRealtime()); + mPhoneServiceState = state; + } } public void notePhoneSignalStrengthLocked(SignalStrength signalStrength) { @@ -1222,6 +1305,11 @@ public final class BatteryStatsImpl extends BatteryStats { else bin = SIGNAL_STRENGTH_POOR; } if (mPhoneSignalStrengthBin != bin) { + mHistoryCur.states = (mHistoryCur.states&~BatteryHistoryRecord.STATE_SIGNAL_STRENGTH_MASK) + | (bin << BatteryHistoryRecord.STATE_SIGNAL_STRENGTH_SHIFT); + if (DEBUG_HISTORY) Slog.v(TAG, "Signal strength " + bin + " to: " + + Integer.toHexString(mHistoryCur.states)); + addHistoryRecord(SystemClock.elapsedRealtime()); if (mPhoneSignalStrengthBin >= 0) { mPhoneSignalStrengthsTimer[mPhoneSignalStrengthBin].stopRunningLocked(this); } @@ -1250,6 +1338,11 @@ public final class BatteryStatsImpl extends BatteryStats { } if (DEBUG) Log.i(TAG, "Phone Data Connection -> " + dataType + " = " + hasData); if (mPhoneDataConnectionType != bin) { + mHistoryCur.states = (mHistoryCur.states&~BatteryHistoryRecord.STATE_DATA_CONNECTION_MASK) + | (bin << BatteryHistoryRecord.STATE_DATA_CONNECTION_SHIFT); + if (DEBUG_HISTORY) Slog.v(TAG, "Data connection " + bin + " to: " + + Integer.toHexString(mHistoryCur.states)); + addHistoryRecord(SystemClock.elapsedRealtime()); if (mPhoneDataConnectionType >= 0) { mPhoneDataConnectionsTimer[mPhoneDataConnectionType].stopRunningLocked(this); } @@ -1260,6 +1353,10 @@ public final class BatteryStatsImpl extends BatteryStats { public void noteWifiOnLocked(int uid) { if (!mWifiOn) { + mHistoryCur.states |= BatteryHistoryRecord.STATE_WIFI_ON_FLAG; + if (DEBUG_HISTORY) Slog.v(TAG, "WIFI on to: " + + Integer.toHexString(mHistoryCur.states)); + addHistoryRecord(SystemClock.elapsedRealtime()); mWifiOn = true; mWifiOnTimer.startRunningLocked(this); } @@ -1274,6 +1371,10 @@ public final class BatteryStatsImpl extends BatteryStats { public void noteWifiOffLocked(int uid) { if (mWifiOn) { + mHistoryCur.states &= ~BatteryHistoryRecord.STATE_WIFI_ON_FLAG; + if (DEBUG_HISTORY) Slog.v(TAG, "WIFI off to: " + + Integer.toHexString(mHistoryCur.states)); + addHistoryRecord(SystemClock.elapsedRealtime()); mWifiOn = false; mWifiOnTimer.stopRunningLocked(this); } @@ -1285,6 +1386,10 @@ public final class BatteryStatsImpl extends BatteryStats { public void noteAudioOnLocked(int uid) { if (!mAudioOn) { + mHistoryCur.states |= BatteryHistoryRecord.STATE_AUDIO_ON_FLAG; + if (DEBUG_HISTORY) Slog.v(TAG, "Audio on to: " + + Integer.toHexString(mHistoryCur.states)); + addHistoryRecord(SystemClock.elapsedRealtime()); mAudioOn = true; mAudioOnTimer.startRunningLocked(this); } @@ -1293,6 +1398,10 @@ public final class BatteryStatsImpl extends BatteryStats { public void noteAudioOffLocked(int uid) { if (mAudioOn) { + mHistoryCur.states &= ~BatteryHistoryRecord.STATE_AUDIO_ON_FLAG; + if (DEBUG_HISTORY) Slog.v(TAG, "Audio off to: " + + Integer.toHexString(mHistoryCur.states)); + addHistoryRecord(SystemClock.elapsedRealtime()); mAudioOn = false; mAudioOnTimer.stopRunningLocked(this); } @@ -1301,6 +1410,10 @@ public final class BatteryStatsImpl extends BatteryStats { public void noteVideoOnLocked(int uid) { if (!mVideoOn) { + mHistoryCur.states |= BatteryHistoryRecord.STATE_VIDEO_ON_FLAG; + if (DEBUG_HISTORY) Slog.v(TAG, "Video on to: " + + Integer.toHexString(mHistoryCur.states)); + addHistoryRecord(SystemClock.elapsedRealtime()); mVideoOn = true; mVideoOnTimer.startRunningLocked(this); } @@ -1309,6 +1422,10 @@ public final class BatteryStatsImpl extends BatteryStats { public void noteVideoOffLocked(int uid) { if (mVideoOn) { + mHistoryCur.states &= ~BatteryHistoryRecord.STATE_VIDEO_ON_FLAG; + if (DEBUG_HISTORY) Slog.v(TAG, "Video off to: " + + Integer.toHexString(mHistoryCur.states)); + addHistoryRecord(SystemClock.elapsedRealtime()); mVideoOn = false; mVideoOnTimer.stopRunningLocked(this); } @@ -1317,6 +1434,10 @@ public final class BatteryStatsImpl extends BatteryStats { public void noteWifiRunningLocked() { if (!mWifiRunning) { + mHistoryCur.states |= BatteryHistoryRecord.STATE_WIFI_RUNNING_FLAG; + if (DEBUG_HISTORY) Slog.v(TAG, "WIFI running to: " + + Integer.toHexString(mHistoryCur.states)); + addHistoryRecord(SystemClock.elapsedRealtime()); mWifiRunning = true; mWifiRunningTimer.startRunningLocked(this); } @@ -1324,6 +1445,10 @@ public final class BatteryStatsImpl extends BatteryStats { public void noteWifiStoppedLocked() { if (mWifiRunning) { + mHistoryCur.states &= ~BatteryHistoryRecord.STATE_WIFI_RUNNING_FLAG; + if (DEBUG_HISTORY) Slog.v(TAG, "WIFI stopped to: " + + Integer.toHexString(mHistoryCur.states)); + addHistoryRecord(SystemClock.elapsedRealtime()); mWifiRunning = false; mWifiRunningTimer.stopRunningLocked(this); } @@ -1331,6 +1456,10 @@ public final class BatteryStatsImpl extends BatteryStats { public void noteBluetoothOnLocked() { if (!mBluetoothOn) { + mHistoryCur.states |= BatteryHistoryRecord.STATE_BLUETOOTH_ON_FLAG; + if (DEBUG_HISTORY) Slog.v(TAG, "Bluetooth on to: " + + Integer.toHexString(mHistoryCur.states)); + addHistoryRecord(SystemClock.elapsedRealtime()); mBluetoothOn = true; mBluetoothOnTimer.startRunningLocked(this); } @@ -1338,32 +1467,84 @@ public final class BatteryStatsImpl extends BatteryStats { public void noteBluetoothOffLocked() { if (mBluetoothOn) { + mHistoryCur.states &= ~BatteryHistoryRecord.STATE_BLUETOOTH_ON_FLAG; + if (DEBUG_HISTORY) Slog.v(TAG, "Bluetooth off to: " + + Integer.toHexString(mHistoryCur.states)); + addHistoryRecord(SystemClock.elapsedRealtime()); mBluetoothOn = false; mBluetoothOnTimer.stopRunningLocked(this); } } + int mWifiFullLockNesting = 0; + public void noteFullWifiLockAcquiredLocked(int uid) { + if (mWifiFullLockNesting == 0) { + mHistoryCur.states |= BatteryHistoryRecord.STATE_WIFI_FULL_LOCK_FLAG; + if (DEBUG_HISTORY) Slog.v(TAG, "WIFI full lock on to: " + + Integer.toHexString(mHistoryCur.states)); + addHistoryRecord(SystemClock.elapsedRealtime()); + } + mWifiFullLockNesting++; getUidStatsLocked(uid).noteFullWifiLockAcquiredLocked(); } public void noteFullWifiLockReleasedLocked(int uid) { + mWifiFullLockNesting--; + if (mWifiFullLockNesting == 0) { + mHistoryCur.states &= ~BatteryHistoryRecord.STATE_WIFI_FULL_LOCK_FLAG; + if (DEBUG_HISTORY) Slog.v(TAG, "WIFI full lock off to: " + + Integer.toHexString(mHistoryCur.states)); + addHistoryRecord(SystemClock.elapsedRealtime()); + } getUidStatsLocked(uid).noteFullWifiLockReleasedLocked(); } + int mWifiScanLockNesting = 0; + public void noteScanWifiLockAcquiredLocked(int uid) { + if (mWifiScanLockNesting == 0) { + mHistoryCur.states |= BatteryHistoryRecord.STATE_WIFI_SCAN_LOCK_FLAG; + if (DEBUG_HISTORY) Slog.v(TAG, "WIFI scan lock on to: " + + Integer.toHexString(mHistoryCur.states)); + addHistoryRecord(SystemClock.elapsedRealtime()); + } + mWifiScanLockNesting++; getUidStatsLocked(uid).noteScanWifiLockAcquiredLocked(); } public void noteScanWifiLockReleasedLocked(int uid) { + mWifiScanLockNesting--; + if (mWifiScanLockNesting == 0) { + mHistoryCur.states &= ~BatteryHistoryRecord.STATE_WIFI_SCAN_LOCK_FLAG; + if (DEBUG_HISTORY) Slog.v(TAG, "WIFI scan lock off to: " + + Integer.toHexString(mHistoryCur.states)); + addHistoryRecord(SystemClock.elapsedRealtime()); + } getUidStatsLocked(uid).noteScanWifiLockReleasedLocked(); } + int mWifiMulticastNesting = 0; + public void noteWifiMulticastEnabledLocked(int uid) { + if (mWifiMulticastNesting == 0) { + mHistoryCur.states |= BatteryHistoryRecord.STATE_WIFI_MULTICAST_ON_FLAG; + if (DEBUG_HISTORY) Slog.v(TAG, "WIFI multicast on to: " + + Integer.toHexString(mHistoryCur.states)); + addHistoryRecord(SystemClock.elapsedRealtime()); + } + mWifiMulticastNesting++; getUidStatsLocked(uid).noteWifiMulticastEnabledLocked(); } public void noteWifiMulticastDisabledLocked(int uid) { + mWifiMulticastNesting--; + if (mWifiMulticastNesting == 0) { + mHistoryCur.states &= ~BatteryHistoryRecord.STATE_WIFI_MULTICAST_ON_FLAG; + if (DEBUG_HISTORY) Slog.v(TAG, "WIFI multicast off to: " + + Integer.toHexString(mHistoryCur.states)); + addHistoryRecord(SystemClock.elapsedRealtime()); + } getUidStatsLocked(uid).noteWifiMulticastDisabledLocked(); } @@ -2766,6 +2947,11 @@ public final class BatteryStatsImpl extends BatteryStats { } @Override + public BatteryHistoryRecord getHistory() { + return mHistory; + } + + @Override public int getStartCount() { return mStartCount; } @@ -2784,6 +2970,12 @@ public final class BatteryStatsImpl extends BatteryStats { long mSecRealtime = SystemClock.elapsedRealtime(); long realtime = mSecRealtime * 1000; if (onBattery) { + clearHistory(); + mHistoryCur.batteryLevel = (byte)level; + mHistoryCur.states &= ~BatteryHistoryRecord.STATE_BATTERY_PLUGGED_FLAG; + if (DEBUG_HISTORY) Slog.v(TAG, "Battery unplugged to: " + + Integer.toHexString(mHistoryCur.states)); + addHistoryRecord(mSecRealtime); mTrackBatteryUptimeStart = uptime; mTrackBatteryRealtimeStart = realtime; mUnpluggedBatteryUptime = getBatteryUptimeLocked(uptime); @@ -2791,6 +2983,11 @@ public final class BatteryStatsImpl extends BatteryStats { mDischargeCurrentLevel = mDischargeStartLevel = level; doUnplug(mUnpluggedBatteryUptime, mUnpluggedBatteryRealtime); } else { + mHistoryCur.batteryLevel = (byte)level; + mHistoryCur.states |= BatteryHistoryRecord.STATE_BATTERY_PLUGGED_FLAG; + if (DEBUG_HISTORY) Slog.v(TAG, "Battery plugged to: " + + Integer.toHexString(mHistoryCur.states)); + addHistoryRecord(mSecRealtime); mTrackBatteryPastUptime += uptime - mTrackBatteryUptimeStart; mTrackBatteryPastRealtime += realtime - mTrackBatteryRealtimeStart; mDischargeCurrentLevel = level; @@ -2806,7 +3003,11 @@ public final class BatteryStatsImpl extends BatteryStats { } public void recordCurrentLevel(int level) { - mDischargeCurrentLevel = level; + if (mDischargeCurrentLevel != level) { + mDischargeCurrentLevel = level; + mHistoryCur.batteryLevel = (byte)level; + addHistoryRecord(SystemClock.elapsedRealtime()); + } } public void updateKernelWakelocksLocked() { @@ -3146,6 +3347,24 @@ public final class BatteryStatsImpl extends BatteryStats { return 0; } + void readHistory(Parcel in) { + mHistory = mHistoryEnd = mHistoryCache = null; + long time; + while ((time=in.readLong()) >= 0) { + BatteryHistoryRecord rec = new BatteryHistoryRecord(time, in); + addHistoryRecord(rec); + } + } + + void writeHistory(Parcel out) { + BatteryHistoryRecord rec = mHistory; + while (rec != null) { + if (rec.time >= 0) rec.writeToParcel(out, 0); + rec = rec.next; + } + out.writeLong(-1); + } + private void readSummaryFromParcel(Parcel in) { final int version = in.readInt(); if (version != VERSION) { @@ -3154,6 +3373,8 @@ public final class BatteryStatsImpl extends BatteryStats { return; } + readHistory(in); + mStartCount = in.readInt(); mBatteryUptime = in.readLong(); mBatteryLastUptime = in.readLong(); @@ -3325,6 +3546,8 @@ public final class BatteryStatsImpl extends BatteryStats { out.writeInt(VERSION); + writeHistory(out); + out.writeInt(mStartCount); out.writeLong(computeBatteryUptime(NOW_SYS, STATS_TOTAL)); out.writeLong(computeBatteryUptime(NOW_SYS, STATS_CURRENT)); @@ -3493,6 +3716,8 @@ public final class BatteryStatsImpl extends BatteryStats { throw new ParcelFormatException("Bad magic number"); } + readHistory(in); + mStartCount = in.readInt(); mBatteryUptime = in.readLong(); mBatteryLastUptime = in.readLong(); @@ -3591,6 +3816,9 @@ public final class BatteryStatsImpl extends BatteryStats { final long batteryRealtime = getBatteryRealtimeLocked(uSecRealtime); out.writeInt(MAGIC); + + writeHistory(out); + out.writeInt(mStartCount); out.writeLong(mBatteryUptime); out.writeLong(mBatteryLastUptime); diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java index cfcac86..0946ba2 100644 --- a/services/java/com/android/server/am/ActivityManagerService.java +++ b/services/java/com/android/server/am/ActivityManagerService.java @@ -288,6 +288,17 @@ public final class ActivityManagerService extends ActivityManagerNative implemen // system/rootdir/init.rc on startup. static final int SECONDARY_SERVER_ADJ; + // This is a process with a heavy-weight application. It is in the + // background, but we want to try to avoid killing it. Value set in + // system/rootdir/init.rc on startup. + static final int HEAVY_WEIGHT_APP_ADJ; + + // This is a process only hosting components that are perceptible to the + // user, and we really want to avoid killing them, but they are not + // immediately visible. An example is background music playback. Value set in + // system/rootdir/init.rc on startup. + static final int PERCEPTIBLE_APP_ADJ; + // This is a process only hosting activities that are visible to the // user, so we'd prefer they don't disappear. Value set in // system/rootdir/init.rc on startup. @@ -313,6 +324,8 @@ public final class ActivityManagerService extends ActivityManagerNative implemen static final int HOME_APP_MEM; static final int BACKUP_APP_MEM; static final int SECONDARY_SERVER_MEM; + static final int HEAVY_WEIGHT_APP_MEM; + static final int PERCEPTIBLE_APP_MEM; static final int VISIBLE_APP_MEM; static final int FOREGROUND_APP_MEM; @@ -333,37 +346,40 @@ public final class ActivityManagerService extends ActivityManagerNative implemen // been idle for less than 120 seconds. static final long EMPTY_APP_IDLE_OFFSET = 120*1000; + static int getIntProp(String name, boolean allowZero) { + String str = SystemProperties.get(name); + if (str == null) { + throw new IllegalArgumentException("Property not defined: " + name); + } + int val = Integer.valueOf(str); + if (val == 0 && !allowZero) { + throw new IllegalArgumentException("Property must not be zero: " + name); + } + return val; + } + static { // These values are set in system/rootdir/init.rc on startup. - FOREGROUND_APP_ADJ = - Integer.valueOf(SystemProperties.get("ro.FOREGROUND_APP_ADJ")); - VISIBLE_APP_ADJ = - Integer.valueOf(SystemProperties.get("ro.VISIBLE_APP_ADJ")); - SECONDARY_SERVER_ADJ = - Integer.valueOf(SystemProperties.get("ro.SECONDARY_SERVER_ADJ")); - BACKUP_APP_ADJ = - Integer.valueOf(SystemProperties.get("ro.BACKUP_APP_ADJ")); - HOME_APP_ADJ = - Integer.valueOf(SystemProperties.get("ro.HOME_APP_ADJ")); - HIDDEN_APP_MIN_ADJ = - Integer.valueOf(SystemProperties.get("ro.HIDDEN_APP_MIN_ADJ")); - EMPTY_APP_ADJ = - Integer.valueOf(SystemProperties.get("ro.EMPTY_APP_ADJ")); - HIDDEN_APP_MAX_ADJ = EMPTY_APP_ADJ-1; - FOREGROUND_APP_MEM = - Integer.valueOf(SystemProperties.get("ro.FOREGROUND_APP_MEM"))*PAGE_SIZE; - VISIBLE_APP_MEM = - Integer.valueOf(SystemProperties.get("ro.VISIBLE_APP_MEM"))*PAGE_SIZE; - SECONDARY_SERVER_MEM = - Integer.valueOf(SystemProperties.get("ro.SECONDARY_SERVER_MEM"))*PAGE_SIZE; - BACKUP_APP_MEM = - Integer.valueOf(SystemProperties.get("ro.BACKUP_APP_MEM"))*PAGE_SIZE; - HOME_APP_MEM = - Integer.valueOf(SystemProperties.get("ro.HOME_APP_MEM"))*PAGE_SIZE; - HIDDEN_APP_MEM = - Integer.valueOf(SystemProperties.get("ro.HIDDEN_APP_MEM"))*PAGE_SIZE; - EMPTY_APP_MEM = - Integer.valueOf(SystemProperties.get("ro.EMPTY_APP_MEM"))*PAGE_SIZE; + FOREGROUND_APP_ADJ = getIntProp("ro.FOREGROUND_APP_ADJ", true); + VISIBLE_APP_ADJ = getIntProp("ro.VISIBLE_APP_ADJ", true); + PERCEPTIBLE_APP_ADJ = getIntProp("ro.PERCEPTIBLE_APP_ADJ", true); + HEAVY_WEIGHT_APP_ADJ = getIntProp("ro.HEAVY_WEIGHT_APP_ADJ", true); + SECONDARY_SERVER_ADJ = getIntProp("ro.SECONDARY_SERVER_ADJ", true); + BACKUP_APP_ADJ = getIntProp("ro.BACKUP_APP_ADJ", true); + HOME_APP_ADJ = getIntProp("ro.HOME_APP_ADJ", true); + HIDDEN_APP_MIN_ADJ = getIntProp("ro.HIDDEN_APP_MIN_ADJ", true); + EMPTY_APP_ADJ = getIntProp("ro.EMPTY_APP_ADJ", true); + // These days we use the last empty slot for hidden apps as well. + HIDDEN_APP_MAX_ADJ = EMPTY_APP_ADJ; + FOREGROUND_APP_MEM = getIntProp("ro.FOREGROUND_APP_MEM", false)*PAGE_SIZE; + VISIBLE_APP_MEM = getIntProp("ro.VISIBLE_APP_MEM", false)*PAGE_SIZE; + PERCEPTIBLE_APP_MEM = getIntProp("ro.PERCEPTIBLE_APP_MEM", false)*PAGE_SIZE; + HEAVY_WEIGHT_APP_MEM = getIntProp("ro.HEAVY_WEIGHT_APP_MEM", false)*PAGE_SIZE; + SECONDARY_SERVER_MEM = getIntProp("ro.SECONDARY_SERVER_MEM", false)*PAGE_SIZE; + BACKUP_APP_MEM = getIntProp("ro.BACKUP_APP_MEM", false)*PAGE_SIZE; + HOME_APP_MEM = getIntProp("ro.HOME_APP_MEM", false)*PAGE_SIZE; + HIDDEN_APP_MEM = getIntProp("ro.HIDDEN_APP_MEM", false)*PAGE_SIZE; + EMPTY_APP_MEM = getIntProp("ro.EMPTY_APP_MEM", false)*PAGE_SIZE; } static final int MY_PID = Process.myPid(); @@ -4974,8 +4990,8 @@ public final class ActivityManagerService extends ActivityManagerNative implemen (rec.lastLowMemory+GC_MIN_INTERVAL) <= now) { // The low memory report is overriding any current // state for a GC request. Make sure to do - // visible/foreground processes first. - if (rec.setAdj <= VISIBLE_APP_ADJ) { + // heavy/important/visible/foreground processes first. + if (rec.setAdj <= HEAVY_WEIGHT_APP_ADJ) { rec.lastRequestedGc = 0; } else { rec.lastRequestedGc = rec.lastLowMemory; @@ -8102,8 +8118,8 @@ public final class ActivityManagerService extends ActivityManagerNative implemen r.conProviders.put(cpr, new Integer(cnt.intValue()+1)); } cpr.clients.add(r); - if (cpr.app != null && r.setAdj >= VISIBLE_APP_ADJ) { - // If this is a visible app accessing the provider, + if (cpr.app != null && r.setAdj <= PERCEPTIBLE_APP_ADJ) { + // If this is a perceptible app accessing the provider, // make sure to count it as being accessed and thus // back up on the LRU list. This is good because // content providers are often expensive to start. @@ -9741,10 +9757,12 @@ public final class ActivityManagerService extends ActivityManagerNative implemen currApp.lru = 0; } else if (adj >= SECONDARY_SERVER_ADJ) { currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_SERVICE; + } else if (adj >= HEAVY_WEIGHT_APP_ADJ) { + currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_HEAVY_WEIGHT; + } else if (adj >= PERCEPTIBLE_APP_ADJ) { + currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_PERCEPTIBLE; } else if (adj >= VISIBLE_APP_ADJ) { currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_VISIBLE; - } else if (app == mHeavyWeightProcess) { - currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_HEAVY_WEIGHT; } else { currApp.importance = ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND; } @@ -10006,7 +10024,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen needSep = true; pw.println(" Running processes (most recent first):"); dumpProcessList(pw, this, mLruProcesses, " ", - "App ", "PERS", true); + "Proc", "PERS", true); needSep = true; } @@ -10502,7 +10520,8 @@ public final class ActivityManagerService extends ActivityManagerNative implemen String prefix, String normalLabel, String persistentLabel, boolean inclOomAdj) { int numPers = 0; - for (int i=list.size()-1; i>=0; i--) { + final int N = list.size()-1; + for (int i=N; i>=0; i--) { ProcessRecord r = (ProcessRecord)list.get(i); if (false) { pw.println(prefix + (r.persistent ? persistentLabel : normalLabel) @@ -10520,6 +10539,10 @@ public final class ActivityManagerService extends ActivityManagerNative implemen oomAdj = buildOomTag("svc", " ", r.setAdj, SECONDARY_SERVER_ADJ); } else if (r.setAdj >= BACKUP_APP_ADJ) { oomAdj = buildOomTag("bckup", null, r.setAdj, BACKUP_APP_ADJ); + } else if (r.setAdj >= HEAVY_WEIGHT_APP_ADJ) { + oomAdj = buildOomTag("hvy ", null, r.setAdj, HEAVY_WEIGHT_APP_ADJ); + } else if (r.setAdj >= PERCEPTIBLE_APP_ADJ) { + oomAdj = buildOomTag("prcp ", null, r.setAdj, PERCEPTIBLE_APP_ADJ); } else if (r.setAdj >= VISIBLE_APP_ADJ) { oomAdj = buildOomTag("vis ", null, r.setAdj, VISIBLE_APP_ADJ); } else if (r.setAdj >= FOREGROUND_APP_ADJ) { @@ -10545,10 +10568,27 @@ public final class ActivityManagerService extends ActivityManagerNative implemen } pw.println(String.format("%s%s #%2d: adj=%s/%s %s (%s)", prefix, (r.persistent ? persistentLabel : normalLabel), - i, oomAdj, schedGroup, r.toShortString(), r.adjType)); + N-i, oomAdj, schedGroup, r.toShortString(), r.adjType)); if (r.adjSource != null || r.adjTarget != null) { - pw.println(prefix + " " + r.adjTarget - + "<=" + r.adjSource); + pw.print(prefix); + pw.print(" "); + if (r.adjTarget instanceof ComponentName) { + pw.print(((ComponentName)r.adjTarget).flattenToShortString()); + } else if (r.adjTarget != null) { + pw.print(r.adjTarget.toString()); + } else { + pw.print("{null}"); + } + pw.print("<="); + if (r.adjSource instanceof ProcessRecord) { + pw.print("Proc{"); + pw.print(((ProcessRecord)r.adjSource).toShortString()); + pw.println("}"); + } else if (r.adjSource != null) { + pw.println(r.adjSource.toString()); + } else { + pw.println("{null}"); + } } } else { pw.println(String.format("%s%s #%2d: %s", @@ -14092,11 +14132,6 @@ public final class ActivityManagerService extends ActivityManagerNative implemen adj = FOREGROUND_APP_ADJ; schedGroup = Process.THREAD_GROUP_DEFAULT; app.adjType = "instrumentation"; - } else if (app == mHeavyWeightProcess) { - // We don't want to kill the current heavy-weight process. - adj = FOREGROUND_APP_ADJ; - schedGroup = Process.THREAD_GROUP_DEFAULT; - app.adjType = "heavy"; } else if (app.persistentActivities > 0) { // Special persistent activities... shouldn't be used these days. adj = FOREGROUND_APP_ADJ; @@ -14117,15 +14152,20 @@ public final class ActivityManagerService extends ActivityManagerNative implemen app.adjType = "exec-service"; } else if (app.foregroundServices) { // The user is aware of this app, so make it visible. - adj = VISIBLE_APP_ADJ; + adj = PERCEPTIBLE_APP_ADJ; schedGroup = Process.THREAD_GROUP_DEFAULT; app.adjType = "foreground-service"; } else if (app.forcingToForeground != null) { // The user is aware of this app, so make it visible. - adj = VISIBLE_APP_ADJ; + adj = PERCEPTIBLE_APP_ADJ; schedGroup = Process.THREAD_GROUP_DEFAULT; app.adjType = "force-foreground"; app.adjSource = app.forcingToForeground; + } else if (app == mHeavyWeightProcess) { + // We don't want to kill the current heavy-weight process. + adj = HEAVY_WEIGHT_APP_ADJ; + schedGroup = Process.THREAD_GROUP_DEFAULT; + app.adjType = "heavy"; } else if (app == mHomeProcess) { // This process is hosting what we currently consider to be the // home app, so we don't want to let it go into the background. @@ -14220,7 +14260,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen ProcessRecord client = cr.binding.client; int myHiddenAdj = hiddenAdj; if (myHiddenAdj > client.hiddenAdj) { - if (client.hiddenAdj > VISIBLE_APP_ADJ) { + if (client.hiddenAdj >= VISIBLE_APP_ADJ) { myHiddenAdj = client.hiddenAdj; } else { myHiddenAdj = VISIBLE_APP_ADJ; @@ -14229,7 +14269,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen int clientAdj = computeOomAdjLocked( client, myHiddenAdj, TOP_APP, true); if (adj > clientAdj) { - adj = clientAdj > VISIBLE_APP_ADJ + adj = clientAdj >= VISIBLE_APP_ADJ ? clientAdj : VISIBLE_APP_ADJ; if (!client.hidden) { app.hidden = false; @@ -14340,7 +14380,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj); if (adj > app.maxAdj) { adj = app.maxAdj; - if (app.maxAdj <= VISIBLE_APP_ADJ) { + if (app.maxAdj <= PERCEPTIBLE_APP_ADJ) { schedGroup = Process.THREAD_GROUP_DEFAULT; } } @@ -14392,7 +14432,7 @@ public final class ActivityManagerService extends ActivityManagerNative implemen if (canGcNowLocked()) { while (mProcessesToGc.size() > 0) { ProcessRecord proc = mProcessesToGc.remove(0); - if (proc.curRawAdj > VISIBLE_APP_ADJ || proc.reportLowMemory) { + if (proc.curRawAdj > PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) { if ((proc.lastRequestedGc+GC_MIN_INTERVAL) <= SystemClock.uptimeMillis()) { // To avoid spamming the system, we will GC processes one diff --git a/services/java/com/android/server/am/BatteryStatsService.java b/services/java/com/android/server/am/BatteryStatsService.java index 33bbc13..ba13c51 100644 --- a/services/java/com/android/server/am/BatteryStatsService.java +++ b/services/java/com/android/server/am/BatteryStatsService.java @@ -96,6 +96,7 @@ public final class BatteryStatsService extends IBatteryStats.Stub { public void noteStartWakelock(int uid, String name, int type) { enforceCallingPermission(); synchronized (mStats) { + Slog.i("battery", "Start wake lock: " + uid + " " + name); mStats.getUidStatsLocked(uid).noteStartWakeLocked(name, type); } } @@ -103,6 +104,7 @@ public final class BatteryStatsService extends IBatteryStats.Stub { public void noteStopWakelock(int uid, String name, int type) { enforceCallingPermission(); synchronized (mStats) { + Slog.i("battery", "Stop wake lock: " + uid + " " + name); mStats.getUidStatsLocked(uid).noteStopWakeLocked(name, type); } } |