diff options
Diffstat (limited to 'core/java/com')
8 files changed, 513 insertions, 75 deletions
diff --git a/core/java/com/android/internal/os/BatteryStatsImpl.java b/core/java/com/android/internal/os/BatteryStatsImpl.java index 20bb95e..d0c7f8c 100644 --- a/core/java/com/android/internal/os/BatteryStatsImpl.java +++ b/core/java/com/android/internal/os/BatteryStatsImpl.java @@ -94,7 +94,7 @@ public final class BatteryStatsImpl extends BatteryStats { private static final int MAGIC = 0xBA757475; // 'BATSTATS' // Current on-disk Parcel version - private static final int VERSION = 116 + (USE_OLD_HISTORY ? 1000 : 0); + private static final int VERSION = 118 + (USE_OLD_HISTORY ? 1000 : 0); // Maximum number of items we will record in the history. private static final int MAX_HISTORY_ITEMS = 2000; @@ -208,7 +208,7 @@ public final class BatteryStatsImpl extends BatteryStats { final HistoryItem mHistoryLastLastWritten = new HistoryItem(); final HistoryItem mHistoryReadTmp = new HistoryItem(); final HistoryItem mHistoryAddTmp = new HistoryItem(); - final HashMap<HistoryTag, Integer> mHistoryTagPool = new HashMap<HistoryTag, Integer>(); + final HashMap<HistoryTag, Integer> mHistoryTagPool = new HashMap(); String[] mReadHistoryStrings; int[] mReadHistoryUids; int mReadHistoryChars; @@ -227,6 +227,38 @@ public final class BatteryStatsImpl extends BatteryStats { HistoryItem mHistoryLastEnd; HistoryItem mHistoryCache; + // Used by computeHistoryStepDetails + HistoryStepDetails mLastHistoryStepDetails = null; + byte mLastHistoryStepLevel = 0; + final HistoryStepDetails mCurHistoryStepDetails = new HistoryStepDetails(); + final HistoryStepDetails mReadHistoryStepDetails = new HistoryStepDetails(); + final HistoryStepDetails mTmpHistoryStepDetails = new HistoryStepDetails(); + /** + * Total time (in 1/100 sec) spent executing in user code. + */ + long mLastStepCpuUserTime; + long mCurStepCpuUserTime; + /** + * Total time (in 1/100 sec) spent executing in kernel code. + */ + long mLastStepCpuSystemTime; + long mCurStepCpuSystemTime; + /** + * Times from /proc/stat + */ + long mLastStepStatUserTime; + long mLastStepStatSystemTime; + long mLastStepStatIOWaitTime; + long mLastStepStatIrqTime; + long mLastStepStatSoftIrqTime; + long mLastStepStatIdleTime; + long mCurStepStatUserTime; + long mCurStepStatSystemTime; + long mCurStepStatIOWaitTime; + long mCurStepStatIrqTime; + long mCurStepStatSoftIrqTime; + long mCurStepStatIdleTime; + private HistoryItem mHistoryIterator; private boolean mReadOverflow; private boolean mIteratingHistory; @@ -1938,6 +1970,10 @@ public final class BatteryStatsImpl extends BatteryStats { static final int STATE_BATTERY_PLUG_MASK = 0x00000003; static final int STATE_BATTERY_PLUG_SHIFT = 24; + // We use the low bit of the battery state int to indicate that we have full details + // from a battery level change. + static final int BATTERY_DELTA_LEVEL_FLAG = 0x00000001; + public void writeHistoryDelta(Parcel dest, HistoryItem cur, HistoryItem last) { if (last == null || cur.cmd != HistoryItem.CMD_UPDATE) { dest.writeInt(DELTA_TIME_ABS); @@ -1958,7 +1994,11 @@ public final class BatteryStatsImpl extends BatteryStats { deltaTimeToken = (int)deltaTime; } int firstToken = deltaTimeToken | (cur.states&DELTA_STATE_MASK); - final int batteryLevelInt = buildBatteryLevelInt(cur); + final int includeStepDetails = mLastHistoryStepLevel > cur.batteryLevel + ? BATTERY_DELTA_LEVEL_FLAG : 0; + final boolean computeStepDetails = includeStepDetails != 0 + || mLastHistoryStepDetails == null; + final int batteryLevelInt = buildBatteryLevelInt(cur) | includeStepDetails; final boolean batteryLevelIntChanged = batteryLevelInt != lastBatteryLevelInt; if (batteryLevelIntChanged) { firstToken |= DELTA_BATTERY_LEVEL_FLAG; @@ -2040,12 +2080,26 @@ public final class BatteryStatsImpl extends BatteryStats { + cur.eventTag.poolIdx + " " + cur.eventTag.uid + ":" + cur.eventTag.string); } + if (computeStepDetails) { + computeHistoryStepDetails(mCurHistoryStepDetails, mLastHistoryStepDetails); + if (includeStepDetails != 0) { + mCurHistoryStepDetails.writeToParcel(dest); + } + cur.stepDetails = mCurHistoryStepDetails; + mLastHistoryStepDetails = mCurHistoryStepDetails; + } else { + cur.stepDetails = null; + } + if (mLastHistoryStepLevel < cur.batteryLevel) { + mLastHistoryStepDetails = null; + } + mLastHistoryStepLevel = cur.batteryLevel; } private int buildBatteryLevelInt(HistoryItem h) { return ((((int)h.batteryLevel)<<25)&0xfe000000) - | ((((int)h.batteryTemperature)<<14)&0x01ffc000) - | (((int)h.batteryVoltage)&0x00003fff); + | ((((int)h.batteryTemperature)<<14)&0x01ff8000) + | ((((int)h.batteryVoltage)<<1)&0x00007fff); } private int buildStateInt(HistoryItem h) { @@ -2063,6 +2117,98 @@ public final class BatteryStatsImpl extends BatteryStats { | (h.states&(~DELTA_STATE_MASK)); } + private void computeHistoryStepDetails(final HistoryStepDetails out, + final HistoryStepDetails last) { + final HistoryStepDetails tmp = last != null ? mTmpHistoryStepDetails : out; + + // Perform a CPU update right after we do this collection, so we have started + // collecting good data for the next step. + requestImmediateCpuUpdate(); + + if (last == null) { + // We are not generating a delta, so all we need to do is reset the stats + // we will later be doing a delta from. + final int NU = mUidStats.size(); + for (int i=0; i<NU; i++) { + final BatteryStatsImpl.Uid uid = mUidStats.valueAt(i); + uid.mLastStepUserTime = uid.mCurStepUserTime; + uid.mLastStepSystemTime = uid.mCurStepSystemTime; + } + mLastStepCpuUserTime = mCurStepCpuUserTime; + mLastStepCpuSystemTime = mCurStepCpuSystemTime; + mLastStepStatUserTime = mCurStepStatUserTime; + mLastStepStatSystemTime = mCurStepStatSystemTime; + mLastStepStatIOWaitTime = mCurStepStatIOWaitTime; + mLastStepStatIrqTime = mCurStepStatIrqTime; + mLastStepStatSoftIrqTime = mCurStepStatSoftIrqTime; + mLastStepStatIdleTime = mCurStepStatIdleTime; + tmp.clear(); + return; + } + if (DEBUG) { + Slog.d(TAG, "Step stats last: user=" + mLastStepCpuUserTime + " sys=" + + mLastStepStatSystemTime + " io=" + mLastStepStatIOWaitTime + + " irq=" + mLastStepStatIrqTime + " sirq=" + + mLastStepStatSoftIrqTime + " idle=" + mLastStepStatIdleTime); + Slog.d(TAG, "Step stats cur: user=" + mCurStepCpuUserTime + " sys=" + + mCurStepStatSystemTime + " io=" + mCurStepStatIOWaitTime + + " irq=" + mCurStepStatIrqTime + " sirq=" + + mCurStepStatSoftIrqTime + " idle=" + mCurStepStatIdleTime); + } + out.userTime = (int)(mCurStepCpuUserTime - mLastStepCpuUserTime); + out.systemTime = (int)(mCurStepCpuSystemTime - mLastStepCpuSystemTime); + out.statUserTime = (int)(mCurStepStatUserTime - mLastStepStatUserTime); + out.statSystemTime = (int)(mCurStepStatSystemTime - mLastStepStatSystemTime); + out.statIOWaitTime = (int)(mCurStepStatIOWaitTime - mLastStepStatIOWaitTime); + out.statIrqTime = (int)(mCurStepStatIrqTime - mLastStepStatIrqTime); + out.statSoftIrqTime = (int)(mCurStepStatSoftIrqTime - mLastStepStatSoftIrqTime); + out.statIdlTime = (int)(mCurStepStatIdleTime - mLastStepStatIdleTime); + out.appCpuUid1 = out.appCpuUid2 = out.appCpuUid3 = -1; + out.appCpuUTime1 = out.appCpuUTime2 = out.appCpuUTime3 = 0; + out.appCpuSTime1 = out.appCpuSTime2 = out.appCpuSTime3 = 0; + final int NU = mUidStats.size(); + for (int i=0; i<NU; i++) { + final BatteryStatsImpl.Uid uid = mUidStats.valueAt(i); + final int totalUTime = (int)(uid.mCurStepUserTime - uid.mLastStepUserTime); + final int totalSTime = (int)(uid.mCurStepSystemTime - uid.mLastStepSystemTime); + final int totalTime = totalUTime + totalSTime; + uid.mLastStepUserTime = uid.mCurStepUserTime; + uid.mLastStepSystemTime = uid.mCurStepSystemTime; + if (totalTime <= (out.appCpuUTime3+out.appCpuSTime3)) { + continue; + } + if (totalTime <= (out.appCpuUTime2+out.appCpuSTime2)) { + out.appCpuUid3 = uid.mUid; + out.appCpuUTime3 = totalUTime; + out.appCpuSTime3 = totalSTime; + } else { + out.appCpuUid3 = out.appCpuUid2; + out.appCpuUTime3 = out.appCpuUTime2; + out.appCpuSTime3 = out.appCpuSTime2; + if (totalTime <= (out.appCpuUTime1+out.appCpuSTime1)) { + out.appCpuUid2 = uid.mUid; + out.appCpuUTime2 = totalUTime; + out.appCpuSTime2 = totalSTime; + } else { + out.appCpuUid2 = out.appCpuUid1; + out.appCpuUTime2 = out.appCpuUTime1; + out.appCpuSTime2 = out.appCpuSTime1; + out.appCpuUid1 = uid.mUid; + out.appCpuUTime1 = totalUTime; + out.appCpuSTime1 = totalSTime; + } + } + } + mLastStepCpuUserTime = mCurStepCpuUserTime; + mLastStepCpuSystemTime = mCurStepCpuSystemTime; + mLastStepStatUserTime = mCurStepStatUserTime; + mLastStepStatSystemTime = mCurStepStatSystemTime; + mLastStepStatIOWaitTime = mCurStepStatIOWaitTime; + mLastStepStatIrqTime = mCurStepStatIrqTime; + mLastStepStatSoftIrqTime = mCurStepStatSoftIrqTime; + mLastStepStatIdleTime = mCurStepStatIdleTime; + } + public void readHistoryDelta(Parcel src, HistoryItem cur) { int firstToken = src.readInt(); int deltaTimeToken = firstToken&DELTA_TIME_MASK; @@ -2091,8 +2237,9 @@ public final class BatteryStatsImpl extends BatteryStats { cur.numReadInts += 2; } + final int batteryLevelInt; if ((firstToken&DELTA_BATTERY_LEVEL_FLAG) != 0) { - int batteryLevelInt = src.readInt(); + batteryLevelInt = src.readInt(); cur.batteryLevel = (byte)((batteryLevelInt>>25)&0x7f); cur.batteryTemperature = (short)((batteryLevelInt<<7)>>21); cur.batteryVoltage = (char)(batteryLevelInt&0x3fff); @@ -2102,6 +2249,8 @@ public final class BatteryStatsImpl extends BatteryStats { + " batteryLevel=" + cur.batteryLevel + " batteryTemp=" + cur.batteryTemperature + " batteryVolt=" + (int)cur.batteryVoltage); + } else { + batteryLevelInt = 0; } if ((firstToken&DELTA_STATE_FLAG) != 0) { @@ -2180,6 +2329,13 @@ public final class BatteryStatsImpl extends BatteryStats { } else { cur.eventCode = HistoryItem.EVENT_NONE; } + + if ((batteryLevelInt&BATTERY_DELTA_LEVEL_FLAG) != 0) { + cur.stepDetails = mReadHistoryStepDetails; + cur.stepDetails.readFromParcel(src); + } else { + cur.stepDetails = null; + } } @Override @@ -2207,6 +2363,7 @@ public final class BatteryStatsImpl extends BatteryStats { && (diffStates2&lastDiffStates2) == 0 && (mHistoryLastWritten.wakelockTag == null || cur.wakelockTag == null) && (mHistoryLastWritten.wakeReasonTag == null || cur.wakeReasonTag == null) + && mHistoryLastWritten.stepDetails == null && (mHistoryLastWritten.eventCode == HistoryItem.EVENT_NONE || cur.eventCode == HistoryItem.EVENT_NONE) && mHistoryLastWritten.batteryLevel == cur.batteryLevel @@ -2632,6 +2789,11 @@ public final class BatteryStatsImpl extends BatteryStats { } } + private void requestImmediateCpuUpdate() { + mHandler.removeMessages(MSG_UPDATE_WAKELOCKS); + mHandler.sendEmptyMessage(MSG_UPDATE_WAKELOCKS); + } + public void setRecordAllHistoryLocked(boolean enabled) { mRecordAllHistory = enabled; if (!enabled) { @@ -2823,6 +2985,10 @@ public final class BatteryStatsImpl extends BatteryStats { public int startAddingCpuLocked() { mHandler.removeMessages(MSG_UPDATE_WAKELOCKS); + if (!mOnBatteryInternal) { + return -1; + } + final int N = mPartialTimers.size(); if (N == 0) { mLastPartialTimers.clear(); @@ -2853,7 +3019,23 @@ public final class BatteryStatsImpl extends BatteryStats { return 0; } - public void finishAddingCpuLocked(int perc, int utime, int stime, long[] cpuSpeedTimes) { + public void finishAddingCpuLocked(int perc, int remainUTime, int remainSTtime, + int totalUTime, int totalSTime, int statUserTime, int statSystemTime, + int statIOWaitTime, int statIrqTime, int statSoftIrqTime, int statIdleTime, + long[] cpuSpeedTimes) { + if (DEBUG) Slog.d(TAG, "Adding cpu: tuser=" + totalUTime + " tsys=" + totalSTime + + " user=" + statUserTime + " sys=" + statSystemTime + + " io=" + statIOWaitTime + " irq=" + statIrqTime + + " sirq=" + statSoftIrqTime + " idle=" + statIdleTime); + mCurStepCpuUserTime += totalUTime; + mCurStepCpuSystemTime += totalSTime; + mCurStepStatUserTime += statUserTime; + mCurStepStatSystemTime += statSystemTime; + mCurStepStatIOWaitTime += statIOWaitTime; + mCurStepStatIrqTime += statIrqTime; + mCurStepStatSoftIrqTime += statSoftIrqTime; + mCurStepStatIdleTime += statIdleTime; + final int N = mPartialTimers.size(); if (perc != 0) { int num = 0; @@ -2874,26 +3056,24 @@ public final class BatteryStatsImpl extends BatteryStats { if (st.mInList) { Uid uid = st.mUid; if (uid != null && uid.mUid != Process.SYSTEM_UID) { - int myUTime = utime/num; - int mySTime = stime/num; - utime -= myUTime; - stime -= mySTime; + int myUTime = remainUTime/num; + int mySTime = remainSTtime/num; + remainUTime -= myUTime; + remainSTtime -= mySTime; num--; Uid.Proc proc = uid.getProcessStatsLocked("*wakelock*"); - proc.addCpuTimeLocked(myUTime, mySTime); - proc.addSpeedStepTimes(cpuSpeedTimes); + proc.addCpuTimeLocked(myUTime, mySTime, cpuSpeedTimes); } } } } // Just in case, collect any lost CPU time. - if (utime != 0 || stime != 0) { + if (remainUTime != 0 || remainSTtime != 0) { Uid uid = getUidStatsLocked(Process.SYSTEM_UID); if (uid != null) { Uid.Proc proc = uid.getProcessStatsLocked("*lost*"); - proc.addCpuTimeLocked(utime, stime); - proc.addSpeedStepTimes(cpuSpeedTimes); + proc.addCpuTimeLocked(remainUTime, remainSTtime, cpuSpeedTimes); } } } @@ -4214,6 +4394,14 @@ public final class BatteryStatsImpl extends BatteryStats { LongSamplingCounter mMobileRadioActiveCount; /** + * The CPU times we had at the last history details update. + */ + long mLastStepUserTime; + long mLastStepSystemTime; + long mCurStepUserTime; + long mCurStepSystemTime; + + /** * The statistics we have collected for this uid's wake locks. */ final OverflowArrayMap<Wakelock> mWakelockStats = new OverflowArrayMap<Wakelock>() { @@ -4876,6 +5064,9 @@ public final class BatteryStatsImpl extends BatteryStats { mPackageStats.clear(); } + mLastStepUserTime = mLastStepSystemTime = 0; + mCurStepUserTime = mCurStepSystemTime = 0; + if (!active) { if (mWifiRunningTimer != null) { mWifiRunningTimer.detach(); @@ -5678,9 +5869,22 @@ public final class BatteryStatsImpl extends BatteryStats { return BatteryStatsImpl.this; } - public void addCpuTimeLocked(int utime, int stime) { + public void addCpuTimeLocked(int utime, int stime, long[] speedStepBins) { mUserTime += utime; + mCurStepUserTime += utime; mSystemTime += stime; + mCurStepSystemTime += stime; + + for (int i = 0; i < mSpeedBins.length && i < speedStepBins.length; i++) { + long amt = speedStepBins[i]; + if (amt != 0) { + SamplingCounter c = mSpeedBins[i]; + if (c == null) { + mSpeedBins[i] = c = new SamplingCounter(mOnBatteryTimeBase); + } + c.addCountAtomic(speedStepBins[i]); + } + } } public void addForegroundTimeLocked(long ttime) { @@ -5770,20 +5974,6 @@ public final class BatteryStatsImpl extends BatteryStats { return val; } - /* Called by ActivityManagerService when CPU times are updated. */ - public void addSpeedStepTimes(long[] values) { - for (int i = 0; i < mSpeedBins.length && i < values.length; i++) { - long amt = values[i]; - if (amt != 0) { - SamplingCounter c = mSpeedBins[i]; - if (c == null) { - mSpeedBins[i] = c = new SamplingCounter(mOnBatteryTimeBase); - } - c.addCountAtomic(values[i]); - } - } - } - @Override public long getTimeAtCpuSpeedStep(int speedStep, int which) { if (speedStep < mSpeedBins.length) { @@ -6756,6 +6946,18 @@ public final class BatteryStatsImpl extends BatteryStats { mWakeupReasonStats.clear(); } + mLastHistoryStepDetails = null; + mLastStepCpuUserTime = mLastStepCpuSystemTime = 0; + mCurStepCpuUserTime = mCurStepCpuSystemTime = 0; + mLastStepCpuUserTime = mCurStepCpuUserTime = 0; + mLastStepCpuSystemTime = mCurStepCpuSystemTime = 0; + mLastStepStatUserTime = mCurStepStatUserTime = 0; + mLastStepStatSystemTime = mCurStepStatSystemTime = 0; + mLastStepStatIOWaitTime = mCurStepStatIOWaitTime = 0; + mLastStepStatIrqTime = mCurStepStatIrqTime = 0; + mLastStepStatSoftIrqTime = mCurStepStatSoftIrqTime = 0; + mLastStepStatIdleTime = mCurStepStatIdleTime = 0; + initDischarge(); clearHistoryLocked(); @@ -6872,7 +7074,7 @@ public final class BatteryStatsImpl extends BatteryStats { reset = true; mNumDischargeStepDurations = 0; } - mOnBattery = mOnBatteryInternal = onBattery; + mOnBattery = mOnBatteryInternal = true; mLastDischargeStepLevel = level; mMinDischargeStepLevel = level; mLastDischargeStepTime = -1; @@ -6900,7 +7102,7 @@ public final class BatteryStatsImpl extends BatteryStats { mDischargeAmountScreenOff = 0; updateTimeBasesLocked(true, !screenOn, uptime, realtime); } else { - mOnBattery = mOnBatteryInternal = onBattery; + mOnBattery = mOnBatteryInternal = false; pullPendingStateUpdatesLocked(); mHistoryCur.batteryLevel = (byte)level; mHistoryCur.states |= HistoryItem.STATE_BATTERY_PLUGGED_FLAG; diff --git a/core/java/com/android/internal/os/ProcessCpuTracker.java b/core/java/com/android/internal/os/ProcessCpuTracker.java index b5338df..501e0ec 100644 --- a/core/java/com/android/internal/os/ProcessCpuTracker.java +++ b/core/java/com/android/internal/os/ProcessCpuTracker.java @@ -152,6 +152,7 @@ public class ProcessCpuTracker { private int mRelIrqTime; private int mRelSoftIrqTime; private int mRelIdleTime; + private boolean mRelStatsAreGood; private int[] mCurPids; private int[] mCurThreadPids; @@ -285,10 +286,9 @@ public class ProcessCpuTracker { public void update() { if (DEBUG) Slog.v(TAG, "Update: " + this); - mLastSampleTime = mCurrentSampleTime; - mCurrentSampleTime = SystemClock.uptimeMillis(); - mLastSampleRealTime = mCurrentSampleRealTime; - mCurrentSampleRealTime = SystemClock.elapsedRealtime(); + + final long nowUptime = SystemClock.uptimeMillis(); + final long nowRealtime = SystemClock.elapsedRealtime(); final long[] sysCpu = mSystemCpuData; if (Process.readProcFile("/proc/stat", SYSTEM_CPU_FORMAT, @@ -304,30 +304,53 @@ public class ProcessCpuTracker { final long irqtime = sysCpu[5]; final long softirqtime = sysCpu[6]; - mRelUserTime = (int)(usertime - mBaseUserTime); - mRelSystemTime = (int)(systemtime - mBaseSystemTime); - mRelIoWaitTime = (int)(iowaittime - mBaseIoWaitTime); - mRelIrqTime = (int)(irqtime - mBaseIrqTime); - mRelSoftIrqTime = (int)(softirqtime - mBaseSoftIrqTime); - mRelIdleTime = (int)(idletime - mBaseIdleTime); - - if (DEBUG) { - Slog.i("Load", "Total U:" + sysCpu[0] + " N:" + sysCpu[1] - + " S:" + sysCpu[2] + " I:" + sysCpu[3] - + " W:" + sysCpu[4] + " Q:" + sysCpu[5] - + " O:" + sysCpu[6]); - Slog.i("Load", "Rel U:" + mRelUserTime + " S:" + mRelSystemTime - + " I:" + mRelIdleTime + " Q:" + mRelIrqTime); - } + // This code is trying to avoid issues with idle time going backwards, + // but currently it gets into situations where it triggers most of the time. :( + if (true || (usertime >= mBaseUserTime && systemtime >= mBaseSystemTime + && iowaittime >= mBaseIoWaitTime && irqtime >= mBaseIrqTime + && softirqtime >= mBaseSoftIrqTime && idletime >= mBaseIdleTime)) { + mRelUserTime = (int)(usertime - mBaseUserTime); + mRelSystemTime = (int)(systemtime - mBaseSystemTime); + mRelIoWaitTime = (int)(iowaittime - mBaseIoWaitTime); + mRelIrqTime = (int)(irqtime - mBaseIrqTime); + mRelSoftIrqTime = (int)(softirqtime - mBaseSoftIrqTime); + mRelIdleTime = (int)(idletime - mBaseIdleTime); + mRelStatsAreGood = true; + + if (DEBUG) { + Slog.i("Load", "Total U:" + sysCpu[0] + " N:" + sysCpu[1] + + " S:" + sysCpu[2] + " I:" + sysCpu[3] + + " W:" + sysCpu[4] + " Q:" + sysCpu[5] + + " O:" + sysCpu[6]); + Slog.i("Load", "Rel U:" + mRelUserTime + " S:" + mRelSystemTime + + " I:" + mRelIdleTime + " Q:" + mRelIrqTime); + } + + mBaseUserTime = usertime; + mBaseSystemTime = systemtime; + mBaseIoWaitTime = iowaittime; + mBaseIrqTime = irqtime; + mBaseSoftIrqTime = softirqtime; + mBaseIdleTime = idletime; - mBaseUserTime = usertime; - mBaseSystemTime = systemtime; - mBaseIoWaitTime = iowaittime; - mBaseIrqTime = irqtime; - mBaseSoftIrqTime = softirqtime; - mBaseIdleTime = idletime; + } else { + mRelUserTime = 0; + mRelSystemTime = 0; + mRelIoWaitTime = 0; + mRelIrqTime = 0; + mRelSoftIrqTime = 0; + mRelIdleTime = 0; + mRelStatsAreGood = false; + Slog.w(TAG, "/proc/stats has gone backwards; skipping CPU update"); + return; + } } + mLastSampleTime = mCurrentSampleTime; + mCurrentSampleTime = nowUptime; + mLastSampleRealTime = mCurrentSampleRealTime; + mCurrentSampleRealTime = nowRealtime; + final StrictMode.ThreadPolicy savedPolicy = StrictMode.allowThreadDiskReads(); try { mCurPids = collectStats("/proc", -1, mFirst, mCurPids, mProcStats); @@ -647,6 +670,10 @@ public class ProcessCpuTracker { return mRelIdleTime; } + final public boolean hasGoodLastStats() { + return mRelStatsAreGood; + } + final public float getTotalCpuPercent() { int denom = mRelUserTime+mRelSystemTime+mRelIrqTime+mRelIdleTime; if (denom <= 0) { diff --git a/core/java/com/android/internal/os/RuntimeInit.java b/core/java/com/android/internal/os/RuntimeInit.java index 29ccb6a..2539a35 100644 --- a/core/java/com/android/internal/os/RuntimeInit.java +++ b/core/java/com/android/internal/os/RuntimeInit.java @@ -233,6 +233,7 @@ public class RuntimeInit { } public static final void main(String[] argv) { + enableDdms(); if (argv.length == 2 && argv[1].equals("application")) { if (DEBUG) Slog.d(TAG, "RuntimeInit: Starting application"); redirectLogStreams(); @@ -365,9 +366,9 @@ public class RuntimeInit { } /** - * Enable debugging features. + * Enable DDMS. */ - static { + static final void enableDdms() { // Register handlers for DDM messages. android.ddm.DdmRegister.registerHandlers(); } diff --git a/core/java/com/android/internal/os/ZygoteConnection.java b/core/java/com/android/internal/os/ZygoteConnection.java index c9b44be..a55fe9a 100644 --- a/core/java/com/android/internal/os/ZygoteConnection.java +++ b/core/java/com/android/internal/os/ZygoteConnection.java @@ -399,7 +399,7 @@ class ZygoteConnection { throws IllegalArgumentException { int curArg = 0; - boolean seenRuntimeArgs = true; + boolean seenRuntimeArgs = false; for ( /* curArg */ ; curArg < args.length; curArg++) { String arg = args[curArg]; @@ -533,14 +533,18 @@ class ZygoteConnection { } } - if (!seenRuntimeArgs) { - throw new IllegalArgumentException("Unexpected argument : " + args[curArg]); - } - - remainingArgs = new String[args.length - curArg]; + if (abiListQuery) { + if (args.length - curArg > 0) { + throw new IllegalArgumentException("Unexpected arguments after --query-abi-list."); + } + } else { + if (!seenRuntimeArgs) { + throw new IllegalArgumentException("Unexpected argument : " + args[curArg]); + } - System.arraycopy(args, curArg, remainingArgs, 0, - remainingArgs.length); + remainingArgs = new String[args.length - curArg]; + System.arraycopy(args, curArg, remainingArgs, 0, remainingArgs.length); + } } } diff --git a/core/java/com/android/internal/os/ZygoteInit.java b/core/java/com/android/internal/os/ZygoteInit.java index 2477d94..400ea37 100644 --- a/core/java/com/android/internal/os/ZygoteInit.java +++ b/core/java/com/android/internal/os/ZygoteInit.java @@ -504,8 +504,8 @@ public class ZygoteInit { "--setgid=1000", "--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1032,3001,3002,3003,3006,3007", "--capabilities=" + capabilities + "," + capabilities, - "--runtime-init", "--nice-name=system_server", + "--runtime-args", "com.android.server.SystemServer", }; ZygoteConnection.Arguments parsedArgs = null; @@ -557,6 +557,7 @@ public class ZygoteInit { public static void main(String argv[]) { try { + RuntimeInit.enableDdms(); // Start profiling the zygote initialization. SamplingProfilerIntegration.start(); diff --git a/core/java/com/android/internal/view/ActionModeWrapper.java b/core/java/com/android/internal/view/ActionModeWrapper.java new file mode 100644 index 0000000..ef1981a --- /dev/null +++ b/core/java/com/android/internal/view/ActionModeWrapper.java @@ -0,0 +1,200 @@ +/* + * Copyright (C) 2015 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.android.internal.view; + +import android.content.Context; +import android.view.ActionMode; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; +import android.view.View; + +import com.android.internal.view.menu.MenuBuilder; +import com.android.internal.widget.ActionBarContextView; + +/** + * ActionMode implementation that wraps several actions modes and creates them on the fly depending + * on the ActionMode type chosen by the client. + */ +public class ActionModeWrapper extends ActionMode { + + private ActionMode mActionMode; + private final Context mContext; + private MenuBuilder mMenu; + private final ActionMode.Callback mCallback; + private boolean mTypeLocked = false; + + private CharSequence mTitle; + private CharSequence mSubtitle; + private View mCustomView; + + // Fields for StandaloneActionMode + private ActionBarContextView mActionModeView; + private boolean mIsFocusable; + + public ActionModeWrapper(Context context, ActionMode.Callback callback) { + mContext = context; + mMenu = new MenuBuilder(context).setDefaultShowAsAction( + MenuItem.SHOW_AS_ACTION_IF_ROOM); + mCallback = callback; + } + + @Override + public void setTitle(CharSequence title) { + if (mActionMode != null) { + mActionMode.setTitle(title); + } else { + mTitle = title; + } + } + + @Override + public void setTitle(int resId) { + if (mActionMode != null) { + mActionMode.setTitle(resId); + } else { + mTitle = resId != 0 ? mContext.getString(resId) : null; + } + } + + @Override + public void setSubtitle(CharSequence subtitle) { + if (mActionMode != null) { + mActionMode.setSubtitle(subtitle); + } else { + mSubtitle = subtitle; + } + } + + @Override + public void setSubtitle(int resId) { + if (mActionMode != null) { + mActionMode.setSubtitle(resId); + } else { + mSubtitle = resId != 0 ? mContext.getString(resId) : null; + } + } + + @Override + public void setCustomView(View view) { + if (mActionMode != null) { + mActionMode.setCustomView(view); + } else { + mCustomView = view; + } + } + + /** + * Set the current type as final and create the necessary ActionMode. After this call, any + * changes to the ActionMode type will be ignored. + */ + public void lockType() { + mTypeLocked = true; + switch (getType()) { + case ActionMode.TYPE_PRIMARY: + default: + mActionMode = new StandaloneActionMode( + mActionModeView.getContext(), + mActionModeView, mCallback, mIsFocusable, mMenu); + break; + case ActionMode.TYPE_FLOATING: + // Not implemented yet. + break; + } + + if (mActionMode == null) { + return; + } + + mActionMode.setTitle(mTitle); + mActionMode.setSubtitle(mSubtitle); + if (mCustomView != null) { + mActionMode.setCustomView(mCustomView); + } + + mTitle = null; + mSubtitle = null; + mCustomView = null; + } + + @Override + public void setType(int type) { + if (!mTypeLocked) { + super.setType(type); + } else { + throw new IllegalStateException( + "You can't change the ActionMode's type after onCreateActionMode."); + } + } + + @Override + public void invalidate() { + if (mActionMode != null) { + mActionMode.invalidate(); + } + } + + @Override + public void finish() { + if (mActionMode != null) { + mActionMode.finish(); + } + } + + @Override + public Menu getMenu() { + return mMenu; + } + + @Override + public CharSequence getTitle() { + if (mActionMode != null) { + return mActionMode.getTitle(); + } + return mTitle; + } + + @Override + public CharSequence getSubtitle() { + if (mActionMode != null) { + return mActionMode.getSubtitle(); + } + return mSubtitle; + } + + @Override + public View getCustomView() { + if (mActionMode != null) { + return mActionMode.getCustomView(); + } + return mCustomView; + } + + @Override + public MenuInflater getMenuInflater() { + return new MenuInflater(mContext); + } + + public void setActionModeView(ActionBarContextView actionModeView) { + mActionModeView = actionModeView; + } + + public void setFocusable(boolean focusable) { + mIsFocusable = focusable; + } + +} diff --git a/core/java/com/android/internal/view/StandaloneActionMode.java b/core/java/com/android/internal/view/StandaloneActionMode.java index d5d3602..2812b77 100644 --- a/core/java/com/android/internal/view/StandaloneActionMode.java +++ b/core/java/com/android/internal/view/StandaloneActionMode.java @@ -20,6 +20,7 @@ import com.android.internal.view.menu.MenuPopupHelper; import com.android.internal.view.menu.SubMenuBuilder; import com.android.internal.widget.ActionBarContextView; +import android.annotation.Nullable; import android.content.Context; import android.view.ActionMode; import android.view.Menu; @@ -41,13 +42,15 @@ public class StandaloneActionMode extends ActionMode implements MenuBuilder.Call private MenuBuilder mMenu; public StandaloneActionMode(Context context, ActionBarContextView view, - ActionMode.Callback callback, boolean isFocusable) { + ActionMode.Callback callback, boolean isFocusable, @Nullable MenuBuilder menuBuilder) { mContext = context; mContextView = view; mCallback = callback; - mMenu = new MenuBuilder(view.getContext()).setDefaultShowAsAction( - MenuItem.SHOW_AS_ACTION_IF_ROOM); + mMenu = (menuBuilder != null) + ? menuBuilder + : new MenuBuilder(view.getContext()).setDefaultShowAsAction( + MenuItem.SHOW_AS_ACTION_IF_ROOM); mMenu.setCallback(this); mFocusable = isFocusable; } @@ -64,12 +67,12 @@ public class StandaloneActionMode extends ActionMode implements MenuBuilder.Call @Override public void setTitle(int resId) { - setTitle(mContext.getString(resId)); + setTitle(resId != 0 ? mContext.getString(resId) : null); } @Override public void setSubtitle(int resId) { - setSubtitle(mContext.getString(resId)); + setSubtitle(resId != 0 ? mContext.getString(resId) : null); } @Override diff --git a/core/java/com/android/internal/widget/ActionBarContextView.java b/core/java/com/android/internal/widget/ActionBarContextView.java index 5d3f464..ae5999a 100644 --- a/core/java/com/android/internal/widget/ActionBarContextView.java +++ b/core/java/com/android/internal/widget/ActionBarContextView.java @@ -158,7 +158,7 @@ public class ActionBarContextView extends AbsActionBarView implements AnimatorLi removeView(mCustomView); } mCustomView = view; - if (mTitleLayout != null) { + if (view != null && mTitleLayout != null) { removeView(mTitleLayout); mTitleLayout = null; } |