summaryrefslogtreecommitdiffstats
path: root/services
diff options
context:
space:
mode:
Diffstat (limited to 'services')
-rw-r--r--services/java/com/android/server/ProcessStats.java148
-rw-r--r--services/java/com/android/server/WifiService.java10
-rw-r--r--services/java/com/android/server/am/ActivityManagerService.java573
-rw-r--r--services/java/com/android/server/am/ProcessRecord.java28
-rw-r--r--services/java/com/android/server/am/ServiceRecord.java4
-rw-r--r--services/java/com/android/server/sip/SipService.java25
-rw-r--r--services/java/com/android/server/sip/SipSessionGroup.java105
-rw-r--r--services/java/com/android/server/sip/SipSessionListenerProxy.java2
-rw-r--r--services/surfaceflinger/DisplayHardware/HWComposer.cpp21
-rw-r--r--services/surfaceflinger/DisplayHardware/HWComposer.h5
-rw-r--r--services/surfaceflinger/SurfaceFlinger.cpp18
-rw-r--r--services/surfaceflinger/SurfaceFlinger.h1
12 files changed, 629 insertions, 311 deletions
diff --git a/services/java/com/android/server/ProcessStats.java b/services/java/com/android/server/ProcessStats.java
index 5bdadcc..43dbcc0 100644
--- a/services/java/com/android/server/ProcessStats.java
+++ b/services/java/com/android/server/ProcessStats.java
@@ -80,16 +80,24 @@ public class ProcessStats {
PROC_SPACE_TERM|PROC_OUT_LONG, // 11: major faults
PROC_SPACE_TERM,
PROC_SPACE_TERM|PROC_OUT_LONG, // 13: utime
- PROC_SPACE_TERM|PROC_OUT_LONG // 14: stime
+ PROC_SPACE_TERM|PROC_OUT_LONG, // 14: stime
+ PROC_SPACE_TERM,
+ PROC_SPACE_TERM,
+ PROC_SPACE_TERM,
+ PROC_SPACE_TERM,
+ PROC_SPACE_TERM,
+ PROC_SPACE_TERM,
+ PROC_SPACE_TERM|PROC_OUT_LONG, // 21: vsize
};
static final int PROCESS_FULL_STAT_MINOR_FAULTS = 1;
static final int PROCESS_FULL_STAT_MAJOR_FAULTS = 2;
static final int PROCESS_FULL_STAT_UTIME = 3;
static final int PROCESS_FULL_STAT_STIME = 4;
+ static final int PROCESS_FULL_STAT_VSIZE = 5;
- private final String[] mProcessFullStatsStringData = new String[5];
- private final long[] mProcessFullStatsData = new long[5];
+ private final String[] mProcessFullStatsStringData = new String[6];
+ private final long[] mProcessFullStatsData = new long[6];
private static final int[] SYSTEM_CPU_FORMAT = new int[] {
PROC_SPACE_TERM|PROC_COMBINE,
@@ -171,6 +179,8 @@ public class ProcessStats {
final ArrayList<Stats> threadStats;
final ArrayList<Stats> workingThreads;
+ public boolean interesting;
+
public String baseName;
public String name;
int nameWidth;
@@ -349,59 +359,62 @@ public class ProcessStats {
+ (parentPid < 0 ? "process" : "thread")
+ " pid " + pid + ": " + st);
- final long uptime = SystemClock.uptimeMillis();
+ if (st.interesting) {
+ final long uptime = SystemClock.uptimeMillis();
- final long[] procStats = mProcessStatsData;
- if (!Process.readProcFile(st.statFile.toString(),
- PROCESS_STATS_FORMAT, null, procStats, null)) {
- continue;
- }
-
- final long minfaults = procStats[PROCESS_STAT_MINOR_FAULTS];
- final long majfaults = procStats[PROCESS_STAT_MAJOR_FAULTS];
- final long utime = procStats[PROCESS_STAT_UTIME];
- final long stime = procStats[PROCESS_STAT_STIME];
-
- if (utime == st.base_utime && stime == st.base_stime) {
- st.rel_utime = 0;
- st.rel_stime = 0;
- st.rel_minfaults = 0;
- st.rel_majfaults = 0;
- if (st.active) {
- st.active = false;
+ final long[] procStats = mProcessStatsData;
+ if (!Process.readProcFile(st.statFile.toString(),
+ PROCESS_STATS_FORMAT, null, procStats, null)) {
+ continue;
}
- continue;
- }
- if (!st.active) {
- st.active = true;
- }
+ final long minfaults = procStats[PROCESS_STAT_MINOR_FAULTS];
+ final long majfaults = procStats[PROCESS_STAT_MAJOR_FAULTS];
+ final long utime = procStats[PROCESS_STAT_UTIME];
+ final long stime = procStats[PROCESS_STAT_STIME];
+
+ if (utime == st.base_utime && stime == st.base_stime) {
+ st.rel_utime = 0;
+ st.rel_stime = 0;
+ st.rel_minfaults = 0;
+ st.rel_majfaults = 0;
+ if (st.active) {
+ st.active = false;
+ }
+ continue;
+ }
- if (parentPid < 0) {
- getName(st, st.cmdlineFile);
- if (st.threadStats != null) {
- mCurThreadPids = collectStats(st.threadsDir, pid, false,
- mCurThreadPids, st.threadStats);
+ if (!st.active) {
+ st.active = true;
}
+
+ if (parentPid < 0) {
+ getName(st, st.cmdlineFile);
+ if (st.threadStats != null) {
+ mCurThreadPids = collectStats(st.threadsDir, pid, false,
+ mCurThreadPids, st.threadStats);
+ }
+ }
+
+ if (DEBUG) Slog.v("Load", "Stats changed " + st.name + " pid=" + st.pid
+ + " utime=" + utime + "-" + st.base_utime
+ + " stime=" + stime + "-" + st.base_stime
+ + " minfaults=" + minfaults + "-" + st.base_minfaults
+ + " majfaults=" + majfaults + "-" + st.base_majfaults);
+
+ st.rel_uptime = uptime - st.base_uptime;
+ st.base_uptime = uptime;
+ st.rel_utime = (int)(utime - st.base_utime);
+ st.rel_stime = (int)(stime - st.base_stime);
+ st.base_utime = utime;
+ st.base_stime = stime;
+ st.rel_minfaults = (int)(minfaults - st.base_minfaults);
+ st.rel_majfaults = (int)(majfaults - st.base_majfaults);
+ st.base_minfaults = minfaults;
+ st.base_majfaults = majfaults;
+ st.working = true;
}
- if (DEBUG) Slog.v("Load", "Stats changed " + st.name + " pid=" + st.pid
- + " utime=" + utime + "-" + st.base_utime
- + " stime=" + stime + "-" + st.base_stime
- + " minfaults=" + minfaults + "-" + st.base_minfaults
- + " majfaults=" + majfaults + "-" + st.base_majfaults);
-
- st.rel_uptime = uptime - st.base_uptime;
- st.base_uptime = uptime;
- st.rel_utime = (int)(utime - st.base_utime);
- st.rel_stime = (int)(stime - st.base_stime);
- st.base_utime = utime;
- st.base_stime = stime;
- st.rel_minfaults = (int)(minfaults - st.base_minfaults);
- st.rel_majfaults = (int)(majfaults - st.base_majfaults);
- st.base_minfaults = minfaults;
- st.base_majfaults = majfaults;
- st.working = true;
continue;
}
@@ -421,12 +434,24 @@ public class ProcessStats {
if (Process.readProcFile(st.statFile.toString(),
PROCESS_FULL_STATS_FORMAT, procStatsString,
procStats, null)) {
- st.baseName = procStatsString[0];
- st.base_minfaults = procStats[PROCESS_FULL_STAT_MINOR_FAULTS];
- st.base_majfaults = procStats[PROCESS_FULL_STAT_MAJOR_FAULTS];
- st.base_utime = procStats[PROCESS_FULL_STAT_UTIME];
- st.base_stime = procStats[PROCESS_FULL_STAT_STIME];
+ // This is a possible way to filter out processes that
+ // are actually kernel threads... do we want to? Some
+ // of them do use CPU, but there can be a *lot* that are
+ // not doing anything.
+ if (true || procStats[PROCESS_FULL_STAT_VSIZE] != 0) {
+ st.interesting = true;
+ st.baseName = procStatsString[0];
+ st.base_minfaults = procStats[PROCESS_FULL_STAT_MINOR_FAULTS];
+ st.base_majfaults = procStats[PROCESS_FULL_STAT_MAJOR_FAULTS];
+ st.base_utime = procStats[PROCESS_FULL_STAT_UTIME];
+ st.base_stime = procStats[PROCESS_FULL_STAT_STIME];
+ } else {
+ Slog.i(TAG, "Skipping kernel process pid " + pid
+ + " name " + procStatsString[0]);
+ st.baseName = procStatsString[0];
+ }
} else {
+ Slog.w(TAG, "Skipping unknown process pid " + pid);
st.baseName = "<unknown>";
st.base_utime = st.base_stime = 0;
st.base_minfaults = st.base_majfaults = 0;
@@ -438,7 +463,7 @@ public class ProcessStats {
mCurThreadPids = collectStats(st.threadsDir, pid, true,
mCurThreadPids, st.threadStats);
}
- } else {
+ } else if (st.interesting) {
st.name = st.baseName;
st.nameWidth = onMeasureProcessName(st.name);
}
@@ -452,7 +477,7 @@ public class ProcessStats {
st.rel_minfaults = 0;
st.rel_majfaults = 0;
st.added = true;
- if (!first) {
+ if (!first && st.interesting) {
st.working = true;
}
continue;
@@ -624,6 +649,14 @@ public class ProcessStats {
}
}
+ final public int countStats() {
+ return mProcStats.size();
+ }
+
+ final public Stats getStats(int index) {
+ return mProcStats.get(index);
+ }
+
final public int countWorkingStats() {
buildWorkingProcs();
return mWorkingProcs.size();
@@ -788,7 +821,8 @@ public class ProcessStats {
private void getName(Stats st, String cmdlineFile) {
String newName = st.name;
- if (st.name == null || st.name.equals("app_process")) {
+ if (st.name == null || st.name.equals("app_process")
+ || st.name.equals("<pre-initialized>")) {
String cmdName = readFile(cmdlineFile, '\0');
if (cmdName != null && cmdName.length() > 1) {
newName = cmdName;
diff --git a/services/java/com/android/server/WifiService.java b/services/java/com/android/server/WifiService.java
index c52567a..7b2a570 100644
--- a/services/java/com/android/server/WifiService.java
+++ b/services/java/com/android/server/WifiService.java
@@ -804,6 +804,16 @@ public class WifiService extends IWifiManager.Stub {
mWifiStateMachine.forgetNetwork(netId);
}
+ public void startWpsPbc(String bssid) {
+ enforceChangePermission();
+ mWifiStateMachine.startWpsPbc(bssid);
+ }
+
+ public void startWpsPin(String bssid, int apPin) {
+ enforceChangePermission();
+ mWifiStateMachine.startWpsPin(bssid, apPin);
+ }
+
private final BroadcastReceiver mReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
diff --git a/services/java/com/android/server/am/ActivityManagerService.java b/services/java/com/android/server/am/ActivityManagerService.java
index c896c94..8e22652 100644
--- a/services/java/com/android/server/am/ActivityManagerService.java
+++ b/services/java/com/android/server/am/ActivityManagerService.java
@@ -122,6 +122,8 @@ import java.io.PrintWriter;
import java.lang.IllegalStateException;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
@@ -145,6 +147,7 @@ public final class ActivityManagerService extends ActivityManagerNative
static final boolean DEBUG_BROADCAST = localLOGV || false;
static final boolean DEBUG_BROADCAST_LIGHT = DEBUG_BROADCAST || false;
static final boolean DEBUG_SERVICE = localLOGV || false;
+ static final boolean DEBUG_SERVICE_EXECUTING = localLOGV || false;
static final boolean DEBUG_VISBILITY = localLOGV || false;
static final boolean DEBUG_PROCESSES = localLOGV || false;
static final boolean DEBUG_PROVIDER = localLOGV || false;
@@ -153,6 +156,8 @@ public final class ActivityManagerService extends ActivityManagerNative
static final boolean DEBUG_RESULTS = localLOGV || false;
static final boolean DEBUG_BACKUP = localLOGV || false;
static final boolean DEBUG_CONFIGURATION = localLOGV || false;
+ static final boolean DEBUG_POWER = localLOGV || false;
+ static final boolean DEBUG_POWER_QUICK = DEBUG_POWER || false;
static final boolean VALIDATE_TOKENS = false;
static final boolean SHOW_ACTIVITY_START_TIME = true;
@@ -198,8 +203,16 @@ public final class ActivityManagerService extends ActivityManagerNative
// The minimum amount of time between successive GC requests for a process.
static final int GC_MIN_INTERVAL = 60*1000;
- // The rate at which we check for apps using excessive wake locks -- 15 mins.
- static final int WAKE_LOCK_CHECK_DELAY = 15*60*1000;
+ // The rate at which we check for apps using excessive power -- 15 mins.
+ static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
+
+ // The minimum sample duration we will allow before deciding we have
+ // enough data on wake locks to start killing things.
+ static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
+
+ // The minimum sample duration we will allow before deciding we have
+ // enough data on CPU usage to start killing things.
+ static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
// How long we allow a receiver to run before giving up on it.
static final int BROADCAST_TIMEOUT = 10*1000;
@@ -780,9 +793,14 @@ public final class ActivityManagerService extends ActivityManagerNative
boolean mDidAppSwitch;
/**
- * Last time (in realtime) at which we checked for wake lock usage.
+ * Last time (in realtime) at which we checked for power usage.
+ */
+ long mLastPowerCheckRealtime;
+
+ /**
+ * Last time (in uptime) at which we checked for power usage.
*/
- long mLastWakeLockCheckTime;
+ long mLastPowerCheckUptime;
/**
* Set while we are wanting to sleep, to prevent any
@@ -1195,12 +1213,10 @@ public final class ActivityManagerService extends ActivityManagerNative
} break;
case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
synchronized (ActivityManagerService.this) {
- checkExcessiveWakeLocksLocked(true);
+ checkExcessivePowerUsageLocked(true);
removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
- if (mSleeping) {
- Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
- sendMessageDelayed(nmsg, WAKE_LOCK_CHECK_DELAY);
- }
+ Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
+ sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
}
} break;
}
@@ -1395,7 +1411,8 @@ public final class ActivityManagerService extends ActivityManagerNative
systemDir, "batterystats.bin").toString());
mBatteryStatsService.getActiveStatistics().readLocked();
mBatteryStatsService.getActiveStatistics().writeAsyncLocked();
- mOnBattery = mBatteryStatsService.getActiveStatistics().getIsOnBattery();
+ mOnBattery = DEBUG_POWER ? true
+ : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
mBatteryStatsService.getActiveStatistics().setCallback(this);
mUsageStatsService = new UsageStatsService(new File(
@@ -1515,10 +1532,12 @@ public final class ActivityManagerService extends ActivityManagerNative
int perc = bstats.startAddingCpuLocked();
int totalUTime = 0;
int totalSTime = 0;
- final int N = mProcessStats.countWorkingStats();
+ final int N = mProcessStats.countStats();
for (int i=0; i<N; i++) {
- ProcessStats.Stats st
- = mProcessStats.getWorkingStats(i);
+ ProcessStats.Stats st = mProcessStats.getStats(i);
+ if (!st.working) {
+ continue;
+ }
ProcessRecord pr = mPidsSelfLocked.get(st.pid);
int otherUTime = (st.rel_utime*perc)/100;
int otherSTime = (st.rel_stime*perc)/100;
@@ -1529,6 +1548,7 @@ public final class ActivityManagerService extends ActivityManagerNative
ps.addCpuTimeLocked(st.rel_utime-otherUTime,
st.rel_stime-otherSTime);
ps.addSpeedStepTimes(cpuSpeedTimes);
+ pr.curCpuTime += (st.rel_utime+st.rel_stime) * 10;
} else {
BatteryStatsImpl.Uid.Proc ps =
bstats.getProcessStatsLocked(st.name, st.pid);
@@ -1565,7 +1585,7 @@ public final class ActivityManagerService extends ActivityManagerNative
updateCpuStatsNow();
synchronized (this) {
synchronized(mPidsSelfLocked) {
- mOnBattery = onBattery;
+ mOnBattery = DEBUG_POWER ? true : onBattery;
}
}
}
@@ -2795,6 +2815,16 @@ public final class ActivityManagerService extends ActivityManagerNative
ArrayList<Integer> firstPids = new ArrayList<Integer>(5);
SparseArray<Boolean> lastPids = new SparseArray<Boolean>(20);
+ if (mController != null) {
+ try {
+ // 0 == continue, -1 = kill process immediately
+ int res = mController.appEarlyNotResponding(app.processName, app.pid, annotation);
+ if (res < 0 && app.pid != MY_PID) Process.killProcess(app.pid);
+ } catch (RemoteException e) {
+ mController = null;
+ }
+ }
+
long anrTime = SystemClock.uptimeMillis();
if (MONITOR_CPU_USAGE) {
updateCpuStatsNow();
@@ -2845,10 +2875,6 @@ public final class ActivityManagerService extends ActivityManagerNative
}
}
- final ProcessStats processStats = new ProcessStats(true);
-
- File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids);
-
// Log the ANR to the main log.
StringBuilder info = mStringBuilder;
info.setLength(0);
@@ -2864,6 +2890,10 @@ public final class ActivityManagerService extends ActivityManagerNative
info.append("Parent: ").append(parent.shortComponentName).append("\n");
}
+ final ProcessStats processStats = new ProcessStats(true);
+
+ File tracesFile = dumpStackTraces(true, firstPids, processStats, lastPids);
+
String cpuInfo = null;
if (MONITOR_CPU_USAGE) {
updateCpuStatsNow();
@@ -3742,7 +3772,7 @@ public final class ActivityManagerService extends ActivityManagerNative
if (mFactoryTest != SystemServer.FACTORY_TEST_LOW_LEVEL) {
// Start looking for apps that are abusing wake locks.
Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
- mHandler.sendMessageDelayed(nmsg, WAKE_LOCK_CHECK_DELAY);
+ mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
// Tell anyone interested that we are done booting!
SystemProperties.set("sys.boot_completed", "1");
broadcastIntentLocked(null, null,
@@ -5655,10 +5685,10 @@ public final class ActivityManagerService extends ActivityManagerNative
}
// Initialize the wake times of all processes.
- checkExcessiveWakeLocksLocked(false);
+ checkExcessivePowerUsageLocked(false);
mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
- mHandler.sendMessageDelayed(nmsg, WAKE_LOCK_CHECK_DELAY);
+ mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
}
}
@@ -5708,7 +5738,6 @@ public final class ActivityManagerService extends ActivityManagerNative
mWindowManager.setEventDispatching(true);
mSleeping = false;
mMainStack.resumeTopActivityLocked(null);
- mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
}
}
@@ -7055,12 +7084,13 @@ public final class ActivityManagerService extends ActivityManagerNative
pw.println("Activity manager dump options:");
pw.println(" [-a] [-h] [cmd] ...");
pw.println(" cmd may be one of:");
- pw.println(" activities: activity stack state");
- pw.println(" broadcasts: broadcast state");
- pw.println(" intents: pending intent state");
- pw.println(" processes: process state");
- pw.println(" providers: content provider state");
- pw.println(" services: service state");
+ pw.println(" a[ctivities]: activity stack state");
+ pw.println(" b[roadcasts]: broadcast state");
+ pw.println(" i[ntents]: pending intent state");
+ pw.println(" p[rocesses]: process state");
+ pw.println(" o[om]: out of memory management");
+ pw.println(" prov[iders]: content provider state");
+ pw.println(" s[ervices]: service state");
pw.println(" service [name]: service client-side state");
return;
} else {
@@ -7092,6 +7122,11 @@ public final class ActivityManagerService extends ActivityManagerNative
dumpProcessesLocked(fd, pw, args, opti, true);
}
return;
+ } else if ("oom".equals(cmd) || "o".equals(cmd)) {
+ synchronized (this) {
+ dumpOomLocked(fd, pw, args, opti, true);
+ }
+ return;
} else if ("providers".equals(cmd) || "prov".equals(cmd)) {
synchronized (this) {
dumpProvidersLocked(fd, pw, args, opti, true);
@@ -7213,7 +7248,7 @@ public final class ActivityManagerService extends ActivityManagerNative
return true;
}
-
+
boolean dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
int opti, boolean dumpAll) {
boolean needSep = false;
@@ -7243,8 +7278,8 @@ public final class ActivityManagerService extends ActivityManagerNative
if (needSep) pw.println(" ");
needSep = true;
pw.println(" Running processes (most recent first):");
- dumpProcessList(pw, this, mLruProcesses, " ",
- "Proc", "PERS", true);
+ dumpProcessOomList(pw, this, mLruProcesses, " ",
+ "Proc", "PERS", false);
needSep = true;
}
@@ -7275,7 +7310,7 @@ public final class ActivityManagerService extends ActivityManagerNative
needSep = true;
pw.println(" Persisent processes that are starting:");
dumpProcessList(pw, this, mPersistentStartingProcesses, " ",
- "Starting Norm", "Restarting PERS", false);
+ "Starting Norm", "Restarting PERS");
}
if (mStartingProcesses.size() > 0) {
@@ -7283,7 +7318,7 @@ public final class ActivityManagerService extends ActivityManagerNative
needSep = true;
pw.println(" Processes that are starting:");
dumpProcessList(pw, this, mStartingProcesses, " ",
- "Starting Norm", "Starting PERS", false);
+ "Starting Norm", "Starting PERS");
}
if (mRemovedProcesses.size() > 0) {
@@ -7291,7 +7326,7 @@ public final class ActivityManagerService extends ActivityManagerNative
needSep = true;
pw.println(" Processes that are being removed:");
dumpProcessList(pw, this, mRemovedProcesses, " ",
- "Removed Norm", "Removed PERS", false);
+ "Removed Norm", "Removed PERS");
}
if (mProcessesOnHold.size() > 0) {
@@ -7299,26 +7334,10 @@ public final class ActivityManagerService extends ActivityManagerNative
needSep = true;
pw.println(" Processes that are on old until the system is ready:");
dumpProcessList(pw, this, mProcessesOnHold, " ",
- "OnHold Norm", "OnHold PERS", false);
+ "OnHold Norm", "OnHold PERS");
}
- if (mProcessesToGc.size() > 0) {
- if (needSep) pw.println(" ");
- needSep = true;
- pw.println(" Processes that are waiting to GC:");
- long now = SystemClock.uptimeMillis();
- for (int i=0; i<mProcessesToGc.size(); i++) {
- ProcessRecord proc = mProcessesToGc.get(i);
- pw.print(" Process "); pw.println(proc);
- pw.print(" lowMem="); pw.print(proc.reportLowMemory);
- pw.print(", last gced=");
- pw.print(now-proc.lastRequestedGc);
- pw.print(" ms ago, last lowMem=");
- pw.print(now-proc.lastLowMemory);
- pw.println(" ms ago");
-
- }
- }
+ needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll);
if (mProcessCrashTimes.getMap().size() > 0) {
if (needSep) pw.println(" ");
@@ -7382,6 +7401,12 @@ public final class ActivityManagerService extends ActivityManagerNative
pw.println(" mBooting=" + mBooting
+ " mBooted=" + mBooted
+ " mFactoryTest=" + mFactoryTest);
+ pw.print(" mLastPowerCheckRealtime=");
+ TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
+ pw.println("");
+ pw.print(" mLastPowerCheckUptime=");
+ TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
+ pw.println("");
pw.println(" mGoingToSleep=" + mMainStack.mGoingToSleep);
pw.println(" mLaunchingActivity=" + mMainStack.mLaunchingActivity);
pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
@@ -7390,6 +7415,75 @@ public final class ActivityManagerService extends ActivityManagerNative
return true;
}
+ boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
+ int opti, boolean needSep, boolean dumpAll) {
+ if (mProcessesToGc.size() > 0) {
+ if (needSep) pw.println(" ");
+ needSep = true;
+ pw.println(" Processes that are waiting to GC:");
+ long now = SystemClock.uptimeMillis();
+ for (int i=0; i<mProcessesToGc.size(); i++) {
+ ProcessRecord proc = mProcessesToGc.get(i);
+ pw.print(" Process "); pw.println(proc);
+ pw.print(" lowMem="); pw.print(proc.reportLowMemory);
+ pw.print(", last gced=");
+ pw.print(now-proc.lastRequestedGc);
+ pw.print(" ms ago, last lowMem=");
+ pw.print(now-proc.lastLowMemory);
+ pw.println(" ms ago");
+
+ }
+ }
+ return needSep;
+ }
+
+ boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
+ int opti, boolean dumpAll) {
+ boolean needSep = false;
+
+ if (mLruProcesses.size() > 0) {
+ ArrayList<ProcessRecord> procs = new ArrayList<ProcessRecord>(mLruProcesses);
+
+ Comparator<ProcessRecord> comparator = new Comparator<ProcessRecord>() {
+ @Override
+ public int compare(ProcessRecord object1, ProcessRecord object2) {
+ if (object1.setAdj != object2.setAdj) {
+ return object1.setAdj > object2.setAdj ? -1 : 1;
+ }
+ if (object1.setSchedGroup != object2.setSchedGroup) {
+ return object1.setSchedGroup > object2.setSchedGroup ? -1 : 1;
+ }
+ if (object1.keeping != object2.keeping) {
+ return object1.keeping ? -1 : 1;
+ }
+ if (object1.pid != object2.pid) {
+ return object1.pid > object2.pid ? -1 : 1;
+ }
+ return 0;
+ }
+ };
+
+ Collections.sort(procs, comparator);
+
+ if (needSep) pw.println(" ");
+ needSep = true;
+ pw.println(" Process OOM control:");
+ dumpProcessOomList(pw, this, procs, " ",
+ "Proc", "PERS", true);
+ needSep = true;
+ }
+
+ needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll);
+
+ pw.println(" ");
+ pw.println(" mHomeProcess: " + mHomeProcess);
+ if (mHeavyWeightProcess != null) {
+ pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
+ }
+
+ return true;
+ }
+
/**
* There are three ways to call this:
* - no service specified: dump all the services
@@ -7833,89 +7927,145 @@ public final class ActivityManagerService extends ActivityManagerNative
private static final int dumpProcessList(PrintWriter pw,
ActivityManagerService service, List list,
- String prefix, String normalLabel, String persistentLabel,
- boolean inclOomAdj) {
+ String prefix, String normalLabel, String persistentLabel) {
int numPers = 0;
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)
- + " #" + i + ":");
- r.dump(pw, prefix + " ");
- } else if (inclOomAdj) {
- String oomAdj;
- if (r.setAdj >= EMPTY_APP_ADJ) {
- oomAdj = buildOomTag("empty", null, r.setAdj, EMPTY_APP_ADJ);
- } else if (r.setAdj >= HIDDEN_APP_MIN_ADJ) {
- oomAdj = buildOomTag("bak", " ", r.setAdj, HIDDEN_APP_MIN_ADJ);
- } else if (r.setAdj >= HOME_APP_ADJ) {
- oomAdj = buildOomTag("home ", null, r.setAdj, HOME_APP_ADJ);
- } else if (r.setAdj >= SECONDARY_SERVER_ADJ) {
- 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) {
- oomAdj = buildOomTag("fore ", null, r.setAdj, FOREGROUND_APP_ADJ);
- } else if (r.setAdj >= CORE_SERVER_ADJ) {
- oomAdj = buildOomTag("core ", null, r.setAdj, CORE_SERVER_ADJ);
- } else if (r.setAdj >= SYSTEM_ADJ) {
- oomAdj = buildOomTag("sys ", null, r.setAdj, SYSTEM_ADJ);
+ pw.println(String.format("%s%s #%2d: %s",
+ prefix, (r.persistent ? persistentLabel : normalLabel),
+ i, r.toString()));
+ if (r.persistent) {
+ numPers++;
+ }
+ }
+ return numPers;
+ }
+
+ private static final void dumpProcessOomList(PrintWriter pw,
+ ActivityManagerService service, List<ProcessRecord> list,
+ String prefix, String normalLabel, String persistentLabel,
+ boolean inclDetails) {
+
+ final long curRealtime = SystemClock.elapsedRealtime();
+ final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
+ final long curUptime = SystemClock.uptimeMillis();
+ final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
+
+ final int N = list.size()-1;
+ for (int i=N; i>=0; i--) {
+ ProcessRecord r = list.get(i);
+ String oomAdj;
+ if (r.setAdj >= EMPTY_APP_ADJ) {
+ oomAdj = buildOomTag("empty", null, r.setAdj, EMPTY_APP_ADJ);
+ } else if (r.setAdj >= HIDDEN_APP_MIN_ADJ) {
+ oomAdj = buildOomTag("bak", " ", r.setAdj, HIDDEN_APP_MIN_ADJ);
+ } else if (r.setAdj >= HOME_APP_ADJ) {
+ oomAdj = buildOomTag("home ", null, r.setAdj, HOME_APP_ADJ);
+ } else if (r.setAdj >= SECONDARY_SERVER_ADJ) {
+ 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) {
+ oomAdj = buildOomTag("fore ", null, r.setAdj, FOREGROUND_APP_ADJ);
+ } else if (r.setAdj >= CORE_SERVER_ADJ) {
+ oomAdj = buildOomTag("core ", null, r.setAdj, CORE_SERVER_ADJ);
+ } else if (r.setAdj >= SYSTEM_ADJ) {
+ oomAdj = buildOomTag("sys ", null, r.setAdj, SYSTEM_ADJ);
+ } else {
+ oomAdj = Integer.toString(r.setAdj);
+ }
+ String schedGroup;
+ switch (r.setSchedGroup) {
+ case Process.THREAD_GROUP_BG_NONINTERACTIVE:
+ schedGroup = "B";
+ break;
+ case Process.THREAD_GROUP_DEFAULT:
+ schedGroup = "F";
+ break;
+ default:
+ schedGroup = Integer.toString(r.setSchedGroup);
+ break;
+ }
+ pw.println(String.format("%s%s #%2d: adj=%s/%s %s (%s)",
+ prefix, (r.persistent ? persistentLabel : normalLabel),
+ N-i, oomAdj, schedGroup, r.toShortString(), r.adjType));
+ if (r.adjSource != null || r.adjTarget != null) {
+ 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 {
- oomAdj = Integer.toString(r.setAdj);
- }
- String schedGroup;
- switch (r.setSchedGroup) {
- case Process.THREAD_GROUP_BG_NONINTERACTIVE:
- schedGroup = "B";
- break;
- case Process.THREAD_GROUP_DEFAULT:
- schedGroup = "F";
- break;
- default:
- schedGroup = Integer.toString(r.setSchedGroup);
- break;
+ 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}");
}
- pw.println(String.format("%s%s #%2d: adj=%s/%s %s (%s)",
- prefix, (r.persistent ? persistentLabel : normalLabel),
- N-i, oomAdj, schedGroup, r.toShortString(), r.adjType));
- if (r.adjSource != null || r.adjTarget != null) {
- 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}");
+ }
+ if (inclDetails) {
+ pw.print(prefix);
+ pw.print(" ");
+ pw.print("oom: max="); pw.print(r.maxAdj);
+ pw.print(" hidden="); pw.print(r.hiddenAdj);
+ pw.print(" curRaw="); pw.print(r.curRawAdj);
+ pw.print(" setRaw="); pw.print(r.setRawAdj);
+ pw.print(" cur="); pw.print(r.curAdj);
+ pw.print(" set="); pw.println(r.setAdj);
+ pw.print(prefix);
+ pw.print(" ");
+ pw.print("keeping="); pw.print(r.keeping);
+ pw.print(" hidden="); pw.print(r.hidden);
+ pw.print(" empty="); pw.println(r.empty);
+
+ if (!r.keeping) {
+ if (r.lastWakeTime != 0) {
+ long wtime;
+ BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
+ synchronized (stats) {
+ wtime = stats.getProcessWakeTime(r.info.uid,
+ r.pid, curRealtime);
+ }
+ long timeUsed = wtime - r.lastWakeTime;
+ pw.print(prefix);
+ pw.print(" ");
+ pw.print("keep awake over ");
+ TimeUtils.formatDuration(realtimeSince, pw);
+ pw.print(" used ");
+ TimeUtils.formatDuration(timeUsed, pw);
+ pw.print(" (");
+ pw.print((timeUsed*100)/realtimeSince);
+ pw.println("%)");
+ }
+ if (r.lastCpuTime != 0) {
+ long timeUsed = r.curCpuTime - r.lastCpuTime;
+ pw.print(prefix);
+ pw.print(" ");
+ pw.print("run cpu over ");
+ TimeUtils.formatDuration(uptimeSince, pw);
+ pw.print(" used ");
+ TimeUtils.formatDuration(timeUsed, pw);
+ pw.print(" (");
+ pw.print((timeUsed*100)/uptimeSince);
+ pw.println("%)");
}
}
- } else {
- pw.println(String.format("%s%s #%2d: %s",
- prefix, (r.persistent ? persistentLabel : normalLabel),
- i, r.toString()));
- }
- if (r.persistent) {
- numPers++;
}
}
- return numPers;
}
static final void dumpApplicationMemoryUsage(FileDescriptor fd,
@@ -8544,7 +8694,11 @@ public final class ActivityManagerService extends ActivityManagerNative
return null;
}
- private final void bumpServiceExecutingLocked(ServiceRecord r) {
+ private final void bumpServiceExecutingLocked(ServiceRecord r, String why) {
+ if (DEBUG_SERVICE) Log.v(TAG, ">>> EXECUTING "
+ + why + " of " + r + " in app " + r.app);
+ else if (DEBUG_SERVICE_EXECUTING) Log.v(TAG, ">>> EXECUTING "
+ + why + " of " + r.shortName);
long now = SystemClock.uptimeMillis();
if (r.executeNesting == 0 && r.app != null) {
if (r.app.executingServices.size() == 0) {
@@ -8582,8 +8736,7 @@ public final class ActivityManagerService extends ActivityManagerNative
grantUriPermissionUncheckedFromIntentLocked(si.targetPermissionUid,
r.packageName, si.intent, si.getUriPermissionsLocked());
}
- if (DEBUG_SERVICE) Slog.v(TAG, ">>> EXECUTING start of " + r);
- bumpServiceExecutingLocked(r);
+ bumpServiceExecutingLocked(r, "start");
if (!oomAdjusted) {
oomAdjusted = true;
updateOomAdjLocked(r.app);
@@ -8616,9 +8769,7 @@ public final class ActivityManagerService extends ActivityManagerNative
}
if ((!i.requested || rebind) && i.apps.size() > 0) {
try {
- if (DEBUG_SERVICE) Slog.v(TAG, ">>> EXECUTING bind of " + r
- + " in " + i + ": shouldUnbind=" + i.hasBound);
- bumpServiceExecutingLocked(r);
+ bumpServiceExecutingLocked(r, "bind");
r.app.thread.scheduleBindService(r, i.intent.getIntent(), rebind);
if (!rebind) {
i.requested = true;
@@ -8653,8 +8804,7 @@ public final class ActivityManagerService extends ActivityManagerNative
r.restartTime = r.lastActivity = SystemClock.uptimeMillis();
app.services.add(r);
- if (DEBUG_SERVICE) Slog.v(TAG, ">>> EXECUTING create of " + r + " " + r.intent);
- bumpServiceExecutingLocked(r);
+ bumpServiceExecutingLocked(r, "create");
updateLruProcessLocked(app, true, true);
boolean created = false;
@@ -8906,9 +9056,7 @@ public final class ActivityManagerService extends ActivityManagerNative
+ ": hasBound=" + ibr.hasBound);
if (r.app != null && r.app.thread != null && ibr.hasBound) {
try {
- if (DEBUG_SERVICE) Slog.v(TAG, ">>> EXECUTING bring down unbind of " + r
- + " for " + ibr);
- bumpServiceExecutingLocked(r);
+ bumpServiceExecutingLocked(r, "bring down unbind");
updateOomAdjLocked(r.app);
ibr.hasBound = false;
r.app.thread.scheduleUnbindService(r,
@@ -8959,12 +9107,7 @@ public final class ActivityManagerService extends ActivityManagerNative
r.app.services.remove(r);
if (r.app.thread != null) {
try {
- if (DEBUG_SERVICE) {
- RuntimeException here = new RuntimeException();
- here.fillInStackTrace();
- Slog.v(TAG, ">>> EXECUTING stop of " + r, here);
- }
- bumpServiceExecutingLocked(r);
+ bumpServiceExecutingLocked(r, "stop");
mStoppingServices.add(r);
updateOomAdjLocked(r.app);
r.app.thread.scheduleStopService(r);
@@ -9420,9 +9563,7 @@ public final class ActivityManagerService extends ActivityManagerNative
if (s.app != null && s.app.thread != null && b.intent.apps.size() == 0
&& b.intent.hasBound) {
try {
- if (DEBUG_SERVICE) Slog.v(TAG, ">>> EXECUTING unbind of " + s
- + " from " + b);
- bumpServiceExecutingLocked(s);
+ bumpServiceExecutingLocked(s, "unbind");
updateOomAdjLocked(s.app);
b.intent.hasBound = false;
// Assume the client doesn't want to know about a rebind;
@@ -9643,14 +9784,20 @@ public final class ActivityManagerService extends ActivityManagerNative
if (DEBUG_SERVICE) Slog.v(TAG, "<<< DONE EXECUTING " + r
+ ": nesting=" + r.executeNesting
+ ", inStopping=" + inStopping + ", app=" + r.app);
+ else if (DEBUG_SERVICE_EXECUTING) Slog.v(TAG, "<<< DONE EXECUTING " + r.shortName);
r.executeNesting--;
if (r.executeNesting <= 0 && r.app != null) {
+ if (DEBUG_SERVICE) Slog.v(TAG,
+ "Nesting at 0 of " + r.shortName);
r.app.executingServices.remove(r);
if (r.app.executingServices.size() == 0) {
+ if (DEBUG_SERVICE || DEBUG_SERVICE_EXECUTING) Slog.v(TAG,
+ "No more executingServices of " + r.shortName);
mHandler.removeMessages(SERVICE_TIMEOUT_MSG, r.app);
}
if (inStopping) {
- if (DEBUG_SERVICE) Slog.v(TAG, "doneExecuting remove stopping " + r);
+ if (DEBUG_SERVICE) Slog.v(TAG,
+ "doneExecuting remove stopping " + r);
mStoppingServices.remove(r);
}
updateOomAdjLocked(r.app);
@@ -9760,20 +9907,20 @@ public final class ActivityManagerService extends ActivityManagerNative
Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
return;
}
+ }
- long oldIdent = Binder.clearCallingIdentity();
- try {
- IBackupManager bm = IBackupManager.Stub.asInterface(
- ServiceManager.getService(Context.BACKUP_SERVICE));
- bm.agentConnected(agentPackageName, agent);
- } catch (RemoteException e) {
- // can't happen; the backup manager service is local
- } catch (Exception e) {
- Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
- e.printStackTrace();
- } finally {
- Binder.restoreCallingIdentity(oldIdent);
- }
+ long oldIdent = Binder.clearCallingIdentity();
+ try {
+ IBackupManager bm = IBackupManager.Stub.asInterface(
+ ServiceManager.getService(Context.BACKUP_SERVICE));
+ bm.agentConnected(agentPackageName, agent);
+ } catch (RemoteException e) {
+ // can't happen; the backup manager service is local
+ } catch (Exception e) {
+ Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
+ e.printStackTrace();
+ } finally {
+ Binder.restoreCallingIdentity(oldIdent);
}
}
@@ -11326,6 +11473,7 @@ public final class ActivityManagerService extends ActivityManagerNative
app.adjType = "fixed";
app.adjSeq = mAdjSeq;
app.curRawAdj = app.maxAdj;
+ app.keeping = true;
app.curSchedGroup = Process.THREAD_GROUP_DEFAULT;
return (app.curAdj=app.maxAdj);
}
@@ -11333,6 +11481,7 @@ public final class ActivityManagerService extends ActivityManagerNative
app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
app.adjSource = null;
app.adjTarget = null;
+ app.keeping = false;
app.empty = false;
app.hidden = false;
@@ -11462,6 +11611,9 @@ public final class ActivityManagerService extends ActivityManagerNative
if (adj > SECONDARY_SERVER_ADJ) {
app.adjType = "started-bg-services";
}
+ // Don't kill this process because it is doing work; it
+ // has said it is doing work.
+ app.keeping = true;
}
if (s.connections.size() > 0 && (adj > FOREGROUND_APP_ADJ
|| schedGroup == Process.THREAD_GROUP_BG_NONINTERACTIVE)) {
@@ -11495,6 +11647,9 @@ public final class ActivityManagerService extends ActivityManagerNative
if (!client.hidden) {
app.hidden = false;
}
+ if (client.keeping) {
+ app.keeping = true;
+ }
app.adjType = "service";
app.adjTypeCode = ActivityManager.RunningAppProcessInfo
.REASON_SERVICE_IN_USE;
@@ -11528,7 +11683,7 @@ public final class ActivityManagerService extends ActivityManagerNative
}
}
- // Finally, f this process has active services running in it, we
+ // Finally, if this process has active services running in it, we
// would like to avoid killing it unless it would prevent the current
// application from running. By default we put the process in
// with the rest of the background processes; as we scan through
@@ -11570,6 +11725,9 @@ public final class ActivityManagerService extends ActivityManagerNative
if (!client.hidden) {
app.hidden = false;
}
+ if (client.keeping) {
+ app.keeping = true;
+ }
app.adjType = "provider";
app.adjTypeCode = ActivityManager.RunningAppProcessInfo
.REASON_PROVIDER_IN_USE;
@@ -11589,6 +11747,7 @@ public final class ActivityManagerService extends ActivityManagerNative
adj = FOREGROUND_APP_ADJ;
schedGroup = Process.THREAD_GROUP_DEFAULT;
app.hidden = false;
+ app.keeping = true;
app.adjType = "provider";
app.adjTarget = cpr.name;
}
@@ -11606,6 +11765,9 @@ public final class ActivityManagerService extends ActivityManagerNative
schedGroup = Process.THREAD_GROUP_DEFAULT;
}
}
+ if (adj < HIDDEN_APP_MIN_ADJ) {
+ app.keeping = true;
+ }
app.curAdj = adj;
app.curSchedGroup = schedGroup;
@@ -11743,57 +11905,99 @@ public final class ActivityManagerService extends ActivityManagerNative
}
}
- final void checkExcessiveWakeLocksLocked(boolean doKills) {
+ final void checkExcessivePowerUsageLocked(boolean doKills) {
+ updateCpuStatsNow();
+
BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
- if (mLastWakeLockCheckTime == 0) {
- doKills = false;
+ boolean doWakeKills = doKills;
+ boolean doCpuKills = doKills;
+ if (mLastPowerCheckRealtime == 0) {
+ doWakeKills = false;
+ }
+ if (mLastPowerCheckUptime == 0) {
+ doCpuKills = false;
}
if (stats.isScreenOn()) {
- doKills = false;
+ doWakeKills = false;
}
final long curRealtime = SystemClock.elapsedRealtime();
- final long timeSince = curRealtime - mLastWakeLockCheckTime;
- mLastWakeLockCheckTime = curRealtime;
- if (timeSince < (WAKE_LOCK_CHECK_DELAY/3)) {
- doKills = false;
+ final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
+ final long curUptime = SystemClock.uptimeMillis();
+ final long uptimeSince = curUptime - mLastPowerCheckUptime;
+ mLastPowerCheckRealtime = curRealtime;
+ mLastPowerCheckUptime = curUptime;
+ if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
+ doWakeKills = false;
+ }
+ if (uptimeSince < CPU_MIN_CHECK_DURATION) {
+ doCpuKills = false;
}
int i = mLruProcesses.size();
while (i > 0) {
i--;
ProcessRecord app = mLruProcesses.get(i);
- if (app.curAdj >= HIDDEN_APP_MIN_ADJ) {
+ if (!app.keeping) {
long wtime;
synchronized (stats) {
wtime = stats.getProcessWakeTime(app.info.uid,
app.pid, curRealtime);
}
- long timeUsed = wtime - app.lastWakeTime;
- if (false) {
+ long wtimeUsed = wtime - app.lastWakeTime;
+ long cputimeUsed = app.curCpuTime - app.lastCpuTime;
+ if (DEBUG_POWER) {
StringBuilder sb = new StringBuilder(128);
sb.append("Wake for ");
app.toShortString(sb);
sb.append(": over ");
- TimeUtils.formatDuration(timeSince, sb);
+ TimeUtils.formatDuration(realtimeSince, sb);
+ sb.append(" used ");
+ TimeUtils.formatDuration(wtimeUsed, sb);
+ sb.append(" (");
+ sb.append((wtimeUsed*100)/realtimeSince);
+ sb.append("%)");
+ Slog.i(TAG, sb.toString());
+ sb.setLength(0);
+ sb.append("CPU for ");
+ app.toShortString(sb);
+ sb.append(": over ");
+ TimeUtils.formatDuration(uptimeSince, sb);
sb.append(" used ");
- TimeUtils.formatDuration(timeUsed, sb);
+ TimeUtils.formatDuration(cputimeUsed, sb);
sb.append(" (");
- sb.append((timeUsed*100)/timeSince);
+ sb.append((cputimeUsed*100)/uptimeSince);
sb.append("%)");
Slog.i(TAG, sb.toString());
}
// If a process has held a wake lock for more
// than 50% of the time during this period,
// that sounds pad. Kill!
- if (doKills && timeSince > 0
- && ((timeUsed*100)/timeSince) >= 50) {
- Slog.i(TAG, "Excessive wake lock in " + app.processName
- + " (pid " + app.pid + "): held " + timeUsed
- + " during " + timeSince);
+ if (doWakeKills && realtimeSince > 0
+ && ((wtimeUsed*100)/realtimeSince) >= 50) {
+ synchronized (stats) {
+ stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
+ realtimeSince, wtimeUsed);
+ }
+ Slog.w(TAG, "Excessive wake lock in " + app.processName
+ + " (pid " + app.pid + "): held " + wtimeUsed
+ + " during " + realtimeSince);
EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
app.processName, app.setAdj, "excessive wake lock");
Process.killProcessQuiet(app.pid);
+ } else if (doCpuKills && uptimeSince > 0
+ && ((cputimeUsed*100)/uptimeSince) >= 50) {
+ synchronized (stats) {
+ stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
+ uptimeSince, cputimeUsed);
+ }
+ Slog.w(TAG, "Excessive CPU in " + app.processName
+ + " (pid " + app.pid + "): used " + cputimeUsed
+ + " during " + uptimeSince);
+ EventLog.writeEvent(EventLogTags.AM_KILL, app.pid,
+ app.processName, app.setAdj, "excessive cpu");
+ Process.killProcessQuiet(app.pid);
} else {
app.lastWakeTime = wtime;
+ app.lastCpuTime = app.curCpuTime;
}
}
}
@@ -11807,6 +12011,8 @@ public final class ActivityManagerService extends ActivityManagerNative
return true;
}
+ final boolean wasKeeping = app.keeping;
+
int adj = computeOomAdjLocked(app, hiddenAdj, TOP_APP, false);
if ((app.pid != 0 && app.pid != MY_PID) || Process.supportsProcesses()) {
@@ -11821,13 +12027,20 @@ public final class ActivityManagerService extends ActivityManagerNative
// Likewise do a gc when an app is moving in to the
// background (such as a service stopping).
scheduleAppGcLocked(app);
- // And note its current wake lock time.
+ }
+
+ if (wasKeeping && !app.keeping) {
+ // This app is no longer something we want to keep. Note
+ // its current wake lock time to later know to kill it if
+ // it is not behaving well.
BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
synchronized (stats) {
app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
app.pid, SystemClock.elapsedRealtime());
}
+ app.lastCpuTime = app.curCpuTime;
}
+
app.setRawAdj = app.curRawAdj;
}
if (adj != app.setAdj) {
diff --git a/services/java/com/android/server/am/ProcessRecord.java b/services/java/com/android/server/am/ProcessRecord.java
index 67df707..404c6be 100644
--- a/services/java/com/android/server/am/ProcessRecord.java
+++ b/services/java/com/android/server/am/ProcessRecord.java
@@ -60,6 +60,7 @@ class ProcessRecord {
int setAdj; // Last set OOM adjustment for this process
int curSchedGroup; // Currently desired scheduling class
int setSchedGroup; // Last set to background scheduling class
+ boolean keeping; // Actively running code so don't kill due to that?
boolean setIsForeground; // Running foreground UI when last set?
boolean foregroundServices; // Running any services that are foreground?
boolean bad; // True if disabled in the bad process list
@@ -75,6 +76,8 @@ class ProcessRecord {
ComponentName instrumentationResultClass;// copy of instrumentationClass
BroadcastRecord curReceiver;// receiver currently running in the app
long lastWakeTime; // How long proc held wake lock at last check
+ long lastCpuTime; // How long proc has run CPU at last check
+ long curCpuTime; // How long proc has run CPU most recently
long lastRequestedGc; // When we last asked the app to do a gc
long lastLowMemory; // When we last told the app that memory is low
boolean reportLowMemory; // Set to true when waiting to report low mem
@@ -131,13 +134,6 @@ class ProcessRecord {
void dump(PrintWriter pw, String prefix) {
final long now = SystemClock.uptimeMillis();
- long wtime;
- synchronized (batteryStats.getBatteryStats()) {
- wtime = batteryStats.getBatteryStats().getProcessWakeTime(info.uid,
- pid, SystemClock.elapsedRealtime());
- }
- long timeUsed = wtime - lastWakeTime;
-
if (info.className != null) {
pw.print(prefix); pw.print("class="); pw.println(info.className);
}
@@ -170,6 +166,7 @@ class ProcessRecord {
pw.print(prefix); pw.print("lastActivityTime=");
TimeUtils.formatDuration(lastActivityTime, now, pw);
pw.print(" lruWeight="); pw.print(lruWeight);
+ pw.print(" keeping="); pw.print(keeping);
pw.print(" hidden="); pw.print(hidden);
pw.print(" empty="); pw.println(empty);
pw.print(prefix); pw.print("oom: max="); pw.print(maxAdj);
@@ -188,9 +185,20 @@ class ProcessRecord {
pw.print(" persistentActivities="); pw.println(persistentActivities);
pw.print(prefix); pw.print("adjSeq="); pw.print(adjSeq);
pw.print(" lruSeq="); pw.println(lruSeq);
- pw.print(prefix); pw.print("lastWakeTime="); pw.print(lastWakeTime);
- pw.print(" time used=");
- TimeUtils.formatDuration(timeUsed, pw); pw.println("");
+ if (!keeping) {
+ long wtime;
+ synchronized (batteryStats.getBatteryStats()) {
+ wtime = batteryStats.getBatteryStats().getProcessWakeTime(info.uid,
+ pid, SystemClock.elapsedRealtime());
+ }
+ long timeUsed = wtime - lastWakeTime;
+ pw.print(prefix); pw.print("lastWakeTime="); pw.print(lastWakeTime);
+ pw.print(" time used=");
+ TimeUtils.formatDuration(timeUsed, pw); pw.println("");
+ pw.print(prefix); pw.print("lastCpuTime="); pw.print(lastCpuTime);
+ pw.print(" time used=");
+ TimeUtils.formatDuration(curCpuTime-lastCpuTime, pw); pw.println("");
+ }
pw.print(prefix); pw.print("lastRequestedGc=");
TimeUtils.formatDuration(lastRequestedGc, now, pw);
pw.print(" lastLowMemory=");
diff --git a/services/java/com/android/server/am/ServiceRecord.java b/services/java/com/android/server/am/ServiceRecord.java
index f35a68e..e5aceb4 100644
--- a/services/java/com/android/server/am/ServiceRecord.java
+++ b/services/java/com/android/server/am/ServiceRecord.java
@@ -347,7 +347,9 @@ class ServiceRecord extends Binder {
// If it gave us a garbage notification, it doesn't
// get to be foreground.
ams.setServiceForeground(name, ServiceRecord.this,
- localForegroundId, null, true);
+ 0, null, true);
+ ams.crashApplication(appUid, appPid, localPackageName,
+ "Bad notification for startForeground: " + e);
}
}
});
diff --git a/services/java/com/android/server/sip/SipService.java b/services/java/com/android/server/sip/SipService.java
index f1dcd5a..3f43e1c 100644
--- a/services/java/com/android/server/sip/SipService.java
+++ b/services/java/com/android/server/sip/SipService.java
@@ -30,8 +30,8 @@ import android.net.sip.ISipSessionListener;
import android.net.sip.SipErrorCode;
import android.net.sip.SipManager;
import android.net.sip.SipProfile;
+import android.net.sip.SipSession;
import android.net.sip.SipSessionAdapter;
-import android.net.sip.SipSessionState;
import android.net.wifi.WifiManager;
import android.os.Binder;
import android.os.Bundle;
@@ -143,7 +143,7 @@ public final class SipService extends ISipService.Stub {
}
private void openToReceiveCalls(SipProfile localProfile) {
- open3(localProfile, SipManager.SIP_INCOMING_CALL_ACTION, null);
+ open3(localProfile, SipManager.ACTION_SIP_INCOMING_CALL, null);
}
public synchronized void open3(SipProfile localProfile,
@@ -255,15 +255,15 @@ public final class SipService extends ISipService.Stub {
private void notifyProfileAdded(SipProfile localProfile) {
if (DEBUG) Log.d(TAG, "notify: profile added: " + localProfile);
- Intent intent = new Intent(SipManager.SIP_ADD_PHONE_ACTION);
- intent.putExtra(SipManager.LOCAL_URI_KEY, localProfile.getUriString());
+ Intent intent = new Intent(SipManager.ACTION_SIP_ADD_PHONE);
+ intent.putExtra(SipManager.EXTRA_LOCAL_URI, localProfile.getUriString());
mContext.sendBroadcast(intent);
}
private void notifyProfileRemoved(SipProfile localProfile) {
if (DEBUG) Log.d(TAG, "notify: profile removed: " + localProfile);
- Intent intent = new Intent(SipManager.SIP_REMOVE_PHONE_ACTION);
- intent.putExtra(SipManager.LOCAL_URI_KEY, localProfile.getUriString());
+ Intent intent = new Intent(SipManager.ACTION_SIP_REMOVE_PHONE);
+ intent.putExtra(SipManager.EXTRA_LOCAL_URI, localProfile.getUriString());
mContext.sendBroadcast(intent);
}
@@ -474,8 +474,8 @@ public final class SipService extends ISipService.Stub {
// send out incoming call broadcast
addPendingSession(session);
Intent intent = SipManager.createIncomingCallBroadcast(
- mIncomingCallBroadcastAction, session.getCallId(),
- sessionDescription);
+ session.getCallId(), sessionDescription)
+ .setAction(mIncomingCallBroadcastAction);
if (DEBUG) Log.d(TAG, " ringing~~ " + getUri() + ": "
+ caller.getUri() + ": " + session.getCallId()
+ " " + mIncomingCallBroadcastAction);
@@ -613,10 +613,10 @@ public final class SipService extends ISipService.Stub {
try {
int state = (mSession == null)
- ? SipSessionState.READY_TO_CALL
+ ? SipSession.State.READY_TO_CALL
: mSession.getState();
- if ((state == SipSessionState.REGISTERING)
- || (state == SipSessionState.DEREGISTERING)) {
+ if ((state == SipSession.State.REGISTERING)
+ || (state == SipSession.State.DEREGISTERING)) {
mProxy.onRegistering(mSession);
} else if (mRegistered) {
int duration = (int)
@@ -1138,7 +1138,8 @@ public final class SipService extends ISipService.Stub {
event.mTriggerTime += event.mPeriod;
// run the callback in a new thread to prevent deadlock
- new Thread(event.mCallback).start();
+ new Thread(event.mCallback, "SipServiceTimerCallbackThread")
+ .start();
}
if (DEBUG_TIMER) {
Log.d(TAG, "after timeout execution");
diff --git a/services/java/com/android/server/sip/SipSessionGroup.java b/services/java/com/android/server/sip/SipSessionGroup.java
index b4c2241..66a2c05 100644
--- a/services/java/com/android/server/sip/SipSessionGroup.java
+++ b/services/java/com/android/server/sip/SipSessionGroup.java
@@ -25,11 +25,10 @@ import gov.nist.javax.sip.message.SIPMessage;
import android.net.sip.ISipSession;
import android.net.sip.ISipSessionListener;
-import android.net.sip.SessionDescription;
import android.net.sip.SipErrorCode;
import android.net.sip.SipProfile;
+import android.net.sip.SipSession;
import android.net.sip.SipSessionAdapter;
-import android.net.sip.SipSessionState;
import android.text.TextUtils;
import android.util.Log;
@@ -121,7 +120,7 @@ class SipSessionGroup implements SipListener {
reset(localIp);
}
- void reset(String localIp) throws SipException, IOException {
+ synchronized void reset(String localIp) throws SipException, IOException {
mLocalIp = localIp;
if (localIp == null) return;
@@ -301,7 +300,7 @@ class SipSessionGroup implements SipListener {
boolean processed = (session != null) && session.process(event);
if (isLoggable && processed) {
Log.d(TAG, "new state after: "
- + SipSessionState.toString(session.mState));
+ + SipSession.State.toString(session.mState));
}
} catch (Throwable e) {
Log.w(TAG, "event process error: " + event, e);
@@ -332,7 +331,7 @@ class SipSessionGroup implements SipListener {
public boolean process(EventObject evt) throws SipException {
if (isLoggable(this, evt)) Log.d(TAG, " ~~~~~ " + this + ": "
- + SipSessionState.toString(mState) + ": processing "
+ + SipSession.State.toString(mState) + ": processing "
+ log(evt));
if (isRequestEvent(Request.INVITE, evt)) {
RequestEvent event = (RequestEvent) evt;
@@ -342,13 +341,16 @@ class SipSessionGroup implements SipListener {
newSession.mDialog = newSession.mServerTransaction.getDialog();
newSession.mInviteReceived = event;
newSession.mPeerProfile = createPeerProfile(event.getRequest());
- newSession.mState = SipSessionState.INCOMING_CALL;
+ newSession.mState = SipSession.State.INCOMING_CALL;
newSession.mPeerSessionDescription =
extractContent(event.getRequest());
addSipSession(newSession);
mProxy.onRinging(newSession, newSession.mPeerProfile,
newSession.mPeerSessionDescription);
return true;
+ } else if (isRequestEvent(Request.OPTIONS, evt)) {
+ mSipHelper.sendResponse((RequestEvent) evt, Response.OK);
+ return true;
} else {
return false;
}
@@ -358,7 +360,7 @@ class SipSessionGroup implements SipListener {
class SipSessionImpl extends ISipSession.Stub {
SipProfile mPeerProfile;
SipSessionListenerProxy mProxy = new SipSessionListenerProxy();
- int mState = SipSessionState.READY_TO_CALL;
+ int mState = SipSession.State.READY_TO_CALL;
RequestEvent mInviteReceived;
Dialog mDialog;
ServerTransaction mServerTransaction;
@@ -378,7 +380,7 @@ class SipSessionGroup implements SipListener {
sleep(timeout);
if (mRunning) timeout();
}
- }).start();
+ }, "SipSessionTimerThread").start();
}
synchronized void cancel() {
@@ -413,7 +415,7 @@ class SipSessionGroup implements SipListener {
mInCall = false;
removeSipSession(this);
mPeerProfile = null;
- mState = SipSessionState.READY_TO_CALL;
+ mState = SipSession.State.READY_TO_CALL;
mInviteReceived = null;
mDialog = null;
mServerTransaction = null;
@@ -470,7 +472,7 @@ class SipSessionGroup implements SipListener {
onError(e);
}
}
- }).start();
+ }, "SipSessionAsyncCmdThread").start();
}
public void makeCall(SipProfile peerProfile, String sessionDescription,
@@ -520,10 +522,10 @@ class SipSessionGroup implements SipListener {
}
public void sendKeepAlive() {
- mState = SipSessionState.PINGING;
+ mState = SipSession.State.PINGING;
try {
processCommand(new OptionsCommand());
- while (SipSessionState.PINGING == mState) {
+ while (SipSession.State.PINGING == mState) {
Thread.sleep(1000);
}
} catch (SipException e) {
@@ -550,7 +552,7 @@ class SipSessionGroup implements SipListener {
try {
String s = super.toString();
return s.substring(s.indexOf("@")) + ":"
- + SipSessionState.toString(mState);
+ + SipSession.State.toString(mState);
} catch (Throwable e) {
return super.toString();
}
@@ -558,7 +560,7 @@ class SipSessionGroup implements SipListener {
public boolean process(EventObject evt) throws SipException {
if (isLoggable(this, evt)) Log.d(TAG, " ~~~~~ " + this + ": "
- + SipSessionState.toString(mState) + ": processing "
+ + SipSession.State.toString(mState) + ": processing "
+ log(evt));
synchronized (SipSessionGroup.this) {
if (isClosed()) return false;
@@ -574,30 +576,30 @@ class SipSessionGroup implements SipListener {
boolean processed;
switch (mState) {
- case SipSessionState.REGISTERING:
- case SipSessionState.DEREGISTERING:
+ case SipSession.State.REGISTERING:
+ case SipSession.State.DEREGISTERING:
processed = registeringToReady(evt);
break;
- case SipSessionState.PINGING:
+ case SipSession.State.PINGING:
processed = keepAliveProcess(evt);
break;
- case SipSessionState.READY_TO_CALL:
+ case SipSession.State.READY_TO_CALL:
processed = readyForCall(evt);
break;
- case SipSessionState.INCOMING_CALL:
+ case SipSession.State.INCOMING_CALL:
processed = incomingCall(evt);
break;
- case SipSessionState.INCOMING_CALL_ANSWERING:
+ case SipSession.State.INCOMING_CALL_ANSWERING:
processed = incomingCallToInCall(evt);
break;
- case SipSessionState.OUTGOING_CALL:
- case SipSessionState.OUTGOING_CALL_RING_BACK:
+ case SipSession.State.OUTGOING_CALL:
+ case SipSession.State.OUTGOING_CALL_RING_BACK:
processed = outgoingCall(evt);
break;
- case SipSessionState.OUTGOING_CALL_CANCELING:
+ case SipSession.State.OUTGOING_CALL_CANCELING:
processed = outgoingCallToReady(evt);
break;
- case SipSessionState.IN_CALL:
+ case SipSession.State.IN_CALL:
processed = inCall(evt);
break;
default:
@@ -625,6 +627,9 @@ class SipSessionGroup implements SipListener {
(TransactionTerminatedEvent) evt);
}
return true;
+ } else if (isRequestEvent(Request.OPTIONS, evt)) {
+ mSipHelper.sendResponse((RequestEvent) evt, Response.OK);
+ return true;
} else if (evt instanceof DialogTerminatedEvent) {
processDialogTerminated((DialogTerminatedEvent) evt);
return true;
@@ -644,8 +649,8 @@ class SipSessionGroup implements SipListener {
private void processTransactionTerminated(
TransactionTerminatedEvent event) {
switch (mState) {
- case SipSessionState.IN_CALL:
- case SipSessionState.READY_TO_CALL:
+ case SipSession.State.IN_CALL:
+ case SipSession.State.READY_TO_CALL:
Log.d(TAG, "Transaction terminated; do nothing");
break;
default:
@@ -664,27 +669,27 @@ class SipSessionGroup implements SipListener {
? event.getServerTransaction()
: event.getClientTransaction();
- if ((current != target) && (mState != SipSessionState.PINGING)) {
+ if ((current != target) && (mState != SipSession.State.PINGING)) {
Log.d(TAG, "not the current transaction; current=" + current
+ ", timed out=" + target);
return;
}
switch (mState) {
- case SipSessionState.REGISTERING:
- case SipSessionState.DEREGISTERING:
+ case SipSession.State.REGISTERING:
+ case SipSession.State.DEREGISTERING:
reset();
mProxy.onRegistrationTimeout(this);
break;
- case SipSessionState.INCOMING_CALL:
- case SipSessionState.INCOMING_CALL_ANSWERING:
- case SipSessionState.OUTGOING_CALL:
- case SipSessionState.OUTGOING_CALL_CANCELING:
+ case SipSession.State.INCOMING_CALL:
+ case SipSession.State.INCOMING_CALL_ANSWERING:
+ case SipSession.State.OUTGOING_CALL:
+ case SipSession.State.OUTGOING_CALL_CANCELING:
onError(SipErrorCode.TIME_OUT, event.toString());
break;
- case SipSessionState.PINGING:
+ case SipSession.State.PINGING:
reset();
mReRegisterFlag = true;
- mState = SipSessionState.READY_TO_CALL;
+ mState = SipSession.State.READY_TO_CALL;
break;
default:
@@ -758,7 +763,7 @@ class SipSessionGroup implements SipListener {
switch (statusCode) {
case Response.OK:
int state = mState;
- onRegistrationDone((state == SipSessionState.REGISTERING)
+ onRegistrationDone((state == SipSession.State.REGISTERING)
? getExpiryTime(((ResponseEvent) evt).getResponse())
: -1);
mLastNonce = null;
@@ -845,7 +850,7 @@ class SipSessionGroup implements SipListener {
generateTag());
mDialog = mClientTransaction.getDialog();
addSipSession(this);
- mState = SipSessionState.OUTGOING_CALL;
+ mState = SipSession.State.OUTGOING_CALL;
mProxy.onCalling(this);
startSessionTimer(cmd.getTimeout());
return true;
@@ -855,7 +860,7 @@ class SipSessionGroup implements SipListener {
generateTag(), duration);
mDialog = mClientTransaction.getDialog();
addSipSession(this);
- mState = SipSessionState.REGISTERING;
+ mState = SipSession.State.REGISTERING;
mProxy.onRegistering(this);
return true;
} else if (DEREGISTER == evt) {
@@ -863,7 +868,7 @@ class SipSessionGroup implements SipListener {
generateTag(), 0);
mDialog = mClientTransaction.getDialog();
addSipSession(this);
- mState = SipSessionState.DEREGISTERING;
+ mState = SipSession.State.DEREGISTERING;
mProxy.onRegistering(this);
return true;
}
@@ -878,7 +883,7 @@ class SipSessionGroup implements SipListener {
mLocalProfile,
((MakeCallCommand) evt).getSessionDescription(),
mServerTransaction);
- mState = SipSessionState.INCOMING_CALL_ANSWERING;
+ mState = SipSession.State.INCOMING_CALL_ANSWERING;
startSessionTimer(((MakeCallCommand) evt).getTimeout());
return true;
} else if (END_CALL == evt) {
@@ -919,8 +924,8 @@ class SipSessionGroup implements SipListener {
int statusCode = response.getStatusCode();
switch (statusCode) {
case Response.RINGING:
- if (mState == SipSessionState.OUTGOING_CALL) {
- mState = SipSessionState.OUTGOING_CALL_RING_BACK;
+ if (mState == SipSession.State.OUTGOING_CALL) {
+ mState = SipSession.State.OUTGOING_CALL_RING_BACK;
mProxy.onRingingBack(this);
cancelSessionTimer();
}
@@ -963,7 +968,7 @@ class SipSessionGroup implements SipListener {
// response comes back yet. We are cheating for not checking
// response.
mSipHelper.sendCancel(mClientTransaction);
- mState = SipSessionState.OUTGOING_CALL_CANCELING;
+ mState = SipSession.State.OUTGOING_CALL_CANCELING;
startSessionTimer(CANCEL_CALL_TIMER);
return true;
}
@@ -1019,7 +1024,7 @@ class SipSessionGroup implements SipListener {
} else if (isRequestEvent(Request.INVITE, evt)) {
// got Re-INVITE
RequestEvent event = mInviteReceived = (RequestEvent) evt;
- mState = SipSessionState.INCOMING_CALL;
+ mState = SipSession.State.INCOMING_CALL;
mPeerSessionDescription = extractContent(event.getRequest());
mServerTransaction = null;
mProxy.onRinging(this, mPeerProfile, mPeerSessionDescription);
@@ -1032,7 +1037,7 @@ class SipSessionGroup implements SipListener {
// to change call
mClientTransaction = mSipHelper.sendReinvite(mDialog,
((MakeCallCommand) evt).getSessionDescription());
- mState = SipSessionState.OUTGOING_CALL;
+ mState = SipSession.State.OUTGOING_CALL;
startSessionTimer(((MakeCallCommand) evt).getTimeout());
return true;
}
@@ -1060,14 +1065,14 @@ class SipSessionGroup implements SipListener {
}
private void establishCall() {
- mState = SipSessionState.IN_CALL;
+ mState = SipSession.State.IN_CALL;
mInCall = true;
cancelSessionTimer();
mProxy.onCallEstablished(this, mPeerSessionDescription);
}
private void fallbackToPreviousInCall(int errorCode, String message) {
- mState = SipSessionState.IN_CALL;
+ mState = SipSession.State.IN_CALL;
mProxy.onCallChangeFailed(this, errorCode, message);
}
@@ -1089,8 +1094,8 @@ class SipSessionGroup implements SipListener {
private void onError(int errorCode, String message) {
cancelSessionTimer();
switch (mState) {
- case SipSessionState.REGISTERING:
- case SipSessionState.DEREGISTERING:
+ case SipSession.State.REGISTERING:
+ case SipSession.State.DEREGISTERING:
onRegistrationFailed(errorCode, message);
break;
default:
@@ -1264,7 +1269,7 @@ class SipSessionGroup implements SipListener {
private static boolean isLoggable(SipSessionImpl s) {
if (s != null) {
switch (s.mState) {
- case SipSessionState.PINGING:
+ case SipSession.State.PINGING:
return DEBUG_PING;
}
}
diff --git a/services/java/com/android/server/sip/SipSessionListenerProxy.java b/services/java/com/android/server/sip/SipSessionListenerProxy.java
index a4cd102..f8be0a8 100644
--- a/services/java/com/android/server/sip/SipSessionListenerProxy.java
+++ b/services/java/com/android/server/sip/SipSessionListenerProxy.java
@@ -40,7 +40,7 @@ class SipSessionListenerProxy extends ISipSessionListener.Stub {
// One thread for each calling back.
// Note: Guarantee ordering if the issue becomes important. Currently,
// the chance of handling two callback events at a time is none.
- new Thread(runnable).start();
+ new Thread(runnable, "SipSessionCallbackThread").start();
}
public void onCalling(final ISipSession session) {
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index 129be4e..ff887e4 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -21,6 +21,7 @@
#include <sys/types.h>
#include <utils/Errors.h>
+#include <utils/String8.h>
#include <hardware/hardware.h>
@@ -100,5 +101,25 @@ hwc_layer_t* HWComposer::getLayers() const {
return mList ? mList->hwLayers : 0;
}
+void HWComposer::dump(String8& result, char* buffer, size_t SIZE) const {
+ if (mHwc && mList) {
+ result.append("Hardware Composer state:\n");
+
+ snprintf(buffer, SIZE, " numHwLayers=%u, flags=%08x\n",
+ mList->numHwLayers, mList->flags);
+ result.append(buffer);
+
+ for (size_t i=0 ; i<mList->numHwLayers ; i++) {
+ const hwc_layer_t& l(mList->hwLayers[i]);
+ snprintf(buffer, SIZE, " %8s | %08x | %08x | %02x | %04x | [%5d,%5d,%5d,%5d] | [%5d,%5d,%5d,%5d]\n",
+ l.compositionType ? "OVERLAY" : "FB",
+ l.hints, l.flags, l.transform, l.blending,
+ l.sourceCrop.left, l.sourceCrop.top, l.sourceCrop.right, l.sourceCrop.bottom,
+ l.displayFrame.left, l.displayFrame.top, l.displayFrame.right, l.displayFrame.bottom);
+ result.append(buffer);
+ }
+ }
+}
+
// ---------------------------------------------------------------------------
}; // namespace android
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h
index 22ff10c..5a9e9eb 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.h
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.h
@@ -27,6 +27,8 @@
namespace android {
// ---------------------------------------------------------------------------
+class String8;
+
class HWComposer
{
public:
@@ -54,6 +56,9 @@ public:
size_t getNumLayers() const;
hwc_layer_t* getLayers() const;
+ // for debugging
+ void dump(String8& out, char* scratch, size_t SIZE) const;
+
private:
hw_module_t const* mModule;
hwc_composer_device_t* mHwc;
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index b45f6fe..b353bff 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -85,6 +85,7 @@ SurfaceFlinger::SurfaceFlinger()
mFreezeDisplayTime(0),
mDebugRegion(0),
mDebugBackground(0),
+ mDebugDisableHWC(0),
mDebugInSwapBuffers(0),
mLastSwapBufferTime(0),
mDebugInTransaction(0),
@@ -768,6 +769,10 @@ void SurfaceFlinger::handleWorkList()
hwc_layer_t* const cur(hwc.getLayers());
for (size_t i=0 ; cur && i<count ; i++) {
currentLayers[i]->setGeometry(&cur[i]);
+ if (mDebugDisableHWC) {
+ cur[i].compositionType = HWC_FRAMEBUFFER;
+ cur[i].flags |= HWC_SKIP_LAYER;
+ }
}
}
}
@@ -901,6 +906,7 @@ void SurfaceFlinger::composeSurfaces(const Region& dirty)
continue;
}
}
+
const sp<LayerBase>& layer(layers[i]);
const Region clip(dirty.intersect(layer->visibleRegionScreen));
if (!clip.isEmpty()) {
@@ -1522,6 +1528,13 @@ status_t SurfaceFlinger::dump(int fd, const Vector<String16>& args)
result.append(buffer);
}
+ HWComposer& hwc(hw.getHwComposer());
+ snprintf(buffer, SIZE, " h/w composer %s and %s\n",
+ hwc.initCheck()==NO_ERROR ? "present" : "not present",
+ mDebugDisableHWC ? "disabled" : "enabled");
+ result.append(buffer);
+ hwc.dump(result, buffer, SIZE);
+
const GraphicBufferAllocator& alloc(GraphicBufferAllocator::get());
alloc.dump(result);
@@ -1580,6 +1593,11 @@ status_t SurfaceFlinger::onTransact(
n = data.readInt32();
mDebugBackground = n ? 1 : 0;
return NO_ERROR;
+ case 1008: // toggle use of hw composer
+ n = data.readInt32();
+ mDebugDisableHWC = n ? 1 : 0;
+ mHwWorkListDirty = true;
+ // fall-through...
case 1004:{ // repaint everything
Mutex::Autolock _l(mStateLock);
const DisplayHardware& hw(graphicPlane(0).displayHardware());
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 8e286e5..551e8e7 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -382,6 +382,7 @@ private:
// don't use a lock for these, we don't care
int mDebugRegion;
int mDebugBackground;
+ int mDebugDisableHWC;
volatile nsecs_t mDebugInSwapBuffers;
nsecs_t mLastSwapBufferTime;
volatile nsecs_t mDebugInTransaction;