Loading services/core/java/com/android/server/am/ActiveServices.java +6 −2 Original line number Diff line number Diff line Loading @@ -1926,6 +1926,9 @@ public final class ActiveServices { if (r.restartDelay == 0) { r.restartCount++; r.restartDelay = minDuration; } else if (r.crashCount > 1) { r.restartDelay = mAm.mConstants.BOUND_SERVICE_CRASH_RESTART_DURATION * (r.crashCount - 1); } else { // If it has been a "reasonably long time" since the service // was started, then reset our restart duration back to Loading Loading @@ -3129,7 +3132,8 @@ public final class ActiveServices { // Any services running in the application may need to be placed // back in the pending list. if (allowRestart && sr.crashCount >= 2 && (sr.serviceInfo.applicationInfo.flags if (allowRestart && sr.crashCount >= mAm.mConstants.BOUND_SERVICE_MAX_CRASH_RETRY && (sr.serviceInfo.applicationInfo.flags &ApplicationInfo.FLAG_PERSISTENT) == 0) { Slog.w(TAG, "Service crashed " + sr.crashCount + " times, stopping: " + sr); Loading services/core/java/com/android/server/am/ActivityManagerConstants.java +18 −0 Original line number Diff line number Diff line Loading @@ -32,6 +32,7 @@ import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER_QUICK * Settings constants that can modify the activity manager's behavior. */ final class ActivityManagerConstants extends ContentObserver { // Key names stored in the settings value. private static final String KEY_MAX_CACHED_PROCESSES = "max_cached_processes"; private static final String KEY_BACKGROUND_SETTLE_TIME = "background_settle_time"; Loading Loading @@ -63,6 +64,8 @@ final class ActivityManagerConstants extends ContentObserver { static final String KEY_SERVICE_MIN_RESTART_TIME_BETWEEN = "service_min_restart_time_between"; static final String KEY_MAX_SERVICE_INACTIVITY = "service_max_inactivity"; static final String KEY_BG_START_TIMEOUT = "service_bg_start_timeout"; static final String KEY_BOUND_SERVICE_CRASH_RESTART_DURATION = "service_crash_restart_duration"; static final String KEY_BOUND_SERVICE_CRASH_MAX_RETRY = "service_crash_max_retry"; private static final int DEFAULT_MAX_CACHED_PROCESSES = 32; private static final long DEFAULT_BACKGROUND_SETTLE_TIME = 60*1000; Loading @@ -88,6 +91,9 @@ final class ActivityManagerConstants extends ContentObserver { private static final long DEFAULT_SERVICE_MIN_RESTART_TIME_BETWEEN = 10*1000; private static final long DEFAULT_MAX_SERVICE_INACTIVITY = 30*60*1000; private static final long DEFAULT_BG_START_TIMEOUT = 15*1000; private static final long DEFAULT_BOUND_SERVICE_CRASH_RESTART_DURATION = 30*60_000; private static final int DEFAULT_BOUND_SERVICE_CRASH_MAX_RETRY = 16; // Maximum number of cached processes we will allow. public int MAX_CACHED_PROCESSES = DEFAULT_MAX_CACHED_PROCESSES; Loading Loading @@ -190,6 +196,12 @@ final class ActivityManagerConstants extends ContentObserver { // allowing the next pending start to run. public long BG_START_TIMEOUT = DEFAULT_BG_START_TIMEOUT; // Initial backoff delay for retrying bound foreground services public long BOUND_SERVICE_CRASH_RESTART_DURATION = DEFAULT_BOUND_SERVICE_CRASH_RESTART_DURATION; // Maximum number of retries for bound foreground services that crash soon after start public long BOUND_SERVICE_MAX_CRASH_RETRY = DEFAULT_BOUND_SERVICE_CRASH_MAX_RETRY; private final ActivityManagerService mService; private ContentResolver mResolver; private final KeyValueListParser mParser = new KeyValueListParser(','); Loading Loading @@ -308,6 +320,12 @@ final class ActivityManagerConstants extends ContentObserver { DEFAULT_MAX_SERVICE_INACTIVITY); BG_START_TIMEOUT = mParser.getLong(KEY_BG_START_TIMEOUT, DEFAULT_BG_START_TIMEOUT); BOUND_SERVICE_CRASH_RESTART_DURATION = mParser.getLong( KEY_BOUND_SERVICE_CRASH_RESTART_DURATION, DEFAULT_BOUND_SERVICE_CRASH_RESTART_DURATION); BOUND_SERVICE_MAX_CRASH_RETRY = mParser.getInt(KEY_BOUND_SERVICE_CRASH_MAX_RETRY, DEFAULT_BOUND_SERVICE_CRASH_MAX_RETRY); updateMaxCachedProcesses(); } } Loading services/core/java/com/android/server/am/AppErrorDialog.java +2 −4 Original line number Diff line number Diff line Loading @@ -40,7 +40,6 @@ final class AppErrorDialog extends BaseErrorDialog implements View.OnClickListen private final ProcessRecord mProc; private final boolean mRepeating; private final boolean mIsRestartable; private CharSequence mName; static int CANT_SHOW = -1; Loading Loading @@ -110,17 +109,16 @@ final class AppErrorDialog extends BaseErrorDialog implements View.OnClickListen LayoutInflater.from(context).inflate( com.android.internal.R.layout.app_error_dialog, frame, true); boolean hasRestart = !mRepeating && mIsRestartable; final boolean hasReceiver = mProc.errorReportReceiver != null; final TextView restart = findViewById(com.android.internal.R.id.aerr_restart); restart.setOnClickListener(this); restart.setVisibility(hasRestart ? View.VISIBLE : View.GONE); restart.setVisibility(mIsRestartable ? View.VISIBLE : View.GONE); final TextView report = findViewById(com.android.internal.R.id.aerr_report); report.setOnClickListener(this); report.setVisibility(hasReceiver ? View.VISIBLE : View.GONE); final TextView close = findViewById(com.android.internal.R.id.aerr_close); close.setVisibility(!hasRestart ? View.VISIBLE : View.GONE); close.setVisibility(mRepeating ? View.VISIBLE : View.GONE); close.setOnClickListener(this); boolean showMute = !Build.IS_USER && Settings.Global.getInt(context.getContentResolver(), Loading services/core/java/com/android/server/am/AppErrors.java +34 −22 Original line number Diff line number Diff line Loading @@ -55,7 +55,6 @@ import java.io.PrintWriter; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Set; import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST; Loading Loading @@ -593,20 +592,46 @@ class AppErrors { boolean handleAppCrashLocked(ProcessRecord app, String reason, String shortMsg, String longMsg, String stackTrace, AppErrorDialog.Data data) { long now = SystemClock.uptimeMillis(); boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), final long now = SystemClock.uptimeMillis(); final boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; final boolean procIsBoundForeground = (app.curProcState == ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE); Long crashTime; Long crashTimePersistent; boolean tryAgain = false; if (!app.isolated) { crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); crashTimePersistent = mProcessCrashTimesPersistent.get(app.info.processName, app.uid); } else { crashTime = crashTimePersistent = null; } // Bump up the crash count of any services currently running in the proc. for (int i = app.services.size() - 1; i >= 0; i--) { // Any services running in the application need to be placed // back in the pending list. ServiceRecord sr = app.services.valueAt(i); // If the service was restarted a while ago, then reset crash count, else increment it. if (now > sr.restartTime + ProcessList.MIN_CRASH_INTERVAL) { sr.crashCount = 1; } else { sr.crashCount++; } // Allow restarting for started or bound foreground services that are crashing. // This includes wallpapers. if (sr.crashCount < mService.mConstants.BOUND_SERVICE_MAX_CRASH_RETRY && (sr.isForeground || procIsBoundForeground)) { tryAgain = true; } } if (crashTime != null && now < crashTime + ProcessList.MIN_CRASH_INTERVAL) { // This process loses! // The process crashed again very quickly. If it was a bound foreground service, let's // try to restart again in a while, otherwise the process loses! Slog.w(TAG, "Process " + app.info.processName + " has crashed too many times: killing!"); EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, Loading @@ -631,7 +656,7 @@ class AppErrors { // Don't let services in this process be restarted and potentially // annoy the user repeatedly. Unless it is persistent, since those // processes run critical code. mService.removeProcessLocked(app, false, false, "crash"); mService.removeProcessLocked(app, false, tryAgain, "crash"); mService.mStackSupervisor.resumeFocusedStackTopActivityLocked(); if (!showBackground) { return false; Loading @@ -650,22 +675,9 @@ class AppErrors { } } boolean procIsBoundForeground = (app.curProcState == ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE); // Bump up the crash count of any services currently running in the proc. for (int i=app.services.size()-1; i>=0; i--) { // Any services running in the application need to be placed // back in the pending list. ServiceRecord sr = app.services.valueAt(i); sr.crashCount++; // Allow restarting for started or bound foreground services that are crashing the // first time. This includes wallpapers. if ((data != null) && (sr.crashCount <= 1) && (sr.isForeground || procIsBoundForeground)) { if (data != null && tryAgain) { data.isRestartableForService = true; } } // If the crashing process is what we consider to be the "home process" and it has been // replaced by a third-party app, clear the package preferred activities from packages Loading @@ -690,7 +702,7 @@ class AppErrors { if (!app.isolated) { // XXX Can't keep track of crash times for isolated processes, // because they don't have a perisistent identity. // because they don't have a persistent identity. mProcessCrashTimes.put(app.info.processName, app.uid, now); mProcessCrashTimesPersistent.put(app.info.processName, app.uid, now); } Loading tests/ServiceCrashTest/Android.mk 0 → 100644 +19 −0 Original line number Diff line number Diff line LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE_TAGS := tests # Only compile source java files in this apk. LOCAL_SRC_FILES := $(call all-java-files-under, src) LOCAL_PACKAGE_NAME := ServiceCrashTest LOCAL_CERTIFICATE := platform LOCAL_JAVA_LIBRARIES := legacy-android-test LOCAL_STATIC_JAVA_LIBRARIES := compatibility-device-util android-support-test include $(BUILD_PACKAGE) # Use the following include to make our test apk. include $(call all-makefiles-under,$(LOCAL_PATH)) Loading
services/core/java/com/android/server/am/ActiveServices.java +6 −2 Original line number Diff line number Diff line Loading @@ -1926,6 +1926,9 @@ public final class ActiveServices { if (r.restartDelay == 0) { r.restartCount++; r.restartDelay = minDuration; } else if (r.crashCount > 1) { r.restartDelay = mAm.mConstants.BOUND_SERVICE_CRASH_RESTART_DURATION * (r.crashCount - 1); } else { // If it has been a "reasonably long time" since the service // was started, then reset our restart duration back to Loading Loading @@ -3129,7 +3132,8 @@ public final class ActiveServices { // Any services running in the application may need to be placed // back in the pending list. if (allowRestart && sr.crashCount >= 2 && (sr.serviceInfo.applicationInfo.flags if (allowRestart && sr.crashCount >= mAm.mConstants.BOUND_SERVICE_MAX_CRASH_RETRY && (sr.serviceInfo.applicationInfo.flags &ApplicationInfo.FLAG_PERSISTENT) == 0) { Slog.w(TAG, "Service crashed " + sr.crashCount + " times, stopping: " + sr); Loading
services/core/java/com/android/server/am/ActivityManagerConstants.java +18 −0 Original line number Diff line number Diff line Loading @@ -32,6 +32,7 @@ import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER_QUICK * Settings constants that can modify the activity manager's behavior. */ final class ActivityManagerConstants extends ContentObserver { // Key names stored in the settings value. private static final String KEY_MAX_CACHED_PROCESSES = "max_cached_processes"; private static final String KEY_BACKGROUND_SETTLE_TIME = "background_settle_time"; Loading Loading @@ -63,6 +64,8 @@ final class ActivityManagerConstants extends ContentObserver { static final String KEY_SERVICE_MIN_RESTART_TIME_BETWEEN = "service_min_restart_time_between"; static final String KEY_MAX_SERVICE_INACTIVITY = "service_max_inactivity"; static final String KEY_BG_START_TIMEOUT = "service_bg_start_timeout"; static final String KEY_BOUND_SERVICE_CRASH_RESTART_DURATION = "service_crash_restart_duration"; static final String KEY_BOUND_SERVICE_CRASH_MAX_RETRY = "service_crash_max_retry"; private static final int DEFAULT_MAX_CACHED_PROCESSES = 32; private static final long DEFAULT_BACKGROUND_SETTLE_TIME = 60*1000; Loading @@ -88,6 +91,9 @@ final class ActivityManagerConstants extends ContentObserver { private static final long DEFAULT_SERVICE_MIN_RESTART_TIME_BETWEEN = 10*1000; private static final long DEFAULT_MAX_SERVICE_INACTIVITY = 30*60*1000; private static final long DEFAULT_BG_START_TIMEOUT = 15*1000; private static final long DEFAULT_BOUND_SERVICE_CRASH_RESTART_DURATION = 30*60_000; private static final int DEFAULT_BOUND_SERVICE_CRASH_MAX_RETRY = 16; // Maximum number of cached processes we will allow. public int MAX_CACHED_PROCESSES = DEFAULT_MAX_CACHED_PROCESSES; Loading Loading @@ -190,6 +196,12 @@ final class ActivityManagerConstants extends ContentObserver { // allowing the next pending start to run. public long BG_START_TIMEOUT = DEFAULT_BG_START_TIMEOUT; // Initial backoff delay for retrying bound foreground services public long BOUND_SERVICE_CRASH_RESTART_DURATION = DEFAULT_BOUND_SERVICE_CRASH_RESTART_DURATION; // Maximum number of retries for bound foreground services that crash soon after start public long BOUND_SERVICE_MAX_CRASH_RETRY = DEFAULT_BOUND_SERVICE_CRASH_MAX_RETRY; private final ActivityManagerService mService; private ContentResolver mResolver; private final KeyValueListParser mParser = new KeyValueListParser(','); Loading Loading @@ -308,6 +320,12 @@ final class ActivityManagerConstants extends ContentObserver { DEFAULT_MAX_SERVICE_INACTIVITY); BG_START_TIMEOUT = mParser.getLong(KEY_BG_START_TIMEOUT, DEFAULT_BG_START_TIMEOUT); BOUND_SERVICE_CRASH_RESTART_DURATION = mParser.getLong( KEY_BOUND_SERVICE_CRASH_RESTART_DURATION, DEFAULT_BOUND_SERVICE_CRASH_RESTART_DURATION); BOUND_SERVICE_MAX_CRASH_RETRY = mParser.getInt(KEY_BOUND_SERVICE_CRASH_MAX_RETRY, DEFAULT_BOUND_SERVICE_CRASH_MAX_RETRY); updateMaxCachedProcesses(); } } Loading
services/core/java/com/android/server/am/AppErrorDialog.java +2 −4 Original line number Diff line number Diff line Loading @@ -40,7 +40,6 @@ final class AppErrorDialog extends BaseErrorDialog implements View.OnClickListen private final ProcessRecord mProc; private final boolean mRepeating; private final boolean mIsRestartable; private CharSequence mName; static int CANT_SHOW = -1; Loading Loading @@ -110,17 +109,16 @@ final class AppErrorDialog extends BaseErrorDialog implements View.OnClickListen LayoutInflater.from(context).inflate( com.android.internal.R.layout.app_error_dialog, frame, true); boolean hasRestart = !mRepeating && mIsRestartable; final boolean hasReceiver = mProc.errorReportReceiver != null; final TextView restart = findViewById(com.android.internal.R.id.aerr_restart); restart.setOnClickListener(this); restart.setVisibility(hasRestart ? View.VISIBLE : View.GONE); restart.setVisibility(mIsRestartable ? View.VISIBLE : View.GONE); final TextView report = findViewById(com.android.internal.R.id.aerr_report); report.setOnClickListener(this); report.setVisibility(hasReceiver ? View.VISIBLE : View.GONE); final TextView close = findViewById(com.android.internal.R.id.aerr_close); close.setVisibility(!hasRestart ? View.VISIBLE : View.GONE); close.setVisibility(mRepeating ? View.VISIBLE : View.GONE); close.setOnClickListener(this); boolean showMute = !Build.IS_USER && Settings.Global.getInt(context.getContentResolver(), Loading
services/core/java/com/android/server/am/AppErrors.java +34 −22 Original line number Diff line number Diff line Loading @@ -55,7 +55,6 @@ import java.io.PrintWriter; import java.util.ArrayList; import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Set; import static com.android.server.Watchdog.NATIVE_STACKS_OF_INTEREST; Loading Loading @@ -593,20 +592,46 @@ class AppErrors { boolean handleAppCrashLocked(ProcessRecord app, String reason, String shortMsg, String longMsg, String stackTrace, AppErrorDialog.Data data) { long now = SystemClock.uptimeMillis(); boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), final long now = SystemClock.uptimeMillis(); final boolean showBackground = Settings.Secure.getInt(mContext.getContentResolver(), Settings.Secure.ANR_SHOW_BACKGROUND, 0) != 0; final boolean procIsBoundForeground = (app.curProcState == ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE); Long crashTime; Long crashTimePersistent; boolean tryAgain = false; if (!app.isolated) { crashTime = mProcessCrashTimes.get(app.info.processName, app.uid); crashTimePersistent = mProcessCrashTimesPersistent.get(app.info.processName, app.uid); } else { crashTime = crashTimePersistent = null; } // Bump up the crash count of any services currently running in the proc. for (int i = app.services.size() - 1; i >= 0; i--) { // Any services running in the application need to be placed // back in the pending list. ServiceRecord sr = app.services.valueAt(i); // If the service was restarted a while ago, then reset crash count, else increment it. if (now > sr.restartTime + ProcessList.MIN_CRASH_INTERVAL) { sr.crashCount = 1; } else { sr.crashCount++; } // Allow restarting for started or bound foreground services that are crashing. // This includes wallpapers. if (sr.crashCount < mService.mConstants.BOUND_SERVICE_MAX_CRASH_RETRY && (sr.isForeground || procIsBoundForeground)) { tryAgain = true; } } if (crashTime != null && now < crashTime + ProcessList.MIN_CRASH_INTERVAL) { // This process loses! // The process crashed again very quickly. If it was a bound foreground service, let's // try to restart again in a while, otherwise the process loses! Slog.w(TAG, "Process " + app.info.processName + " has crashed too many times: killing!"); EventLog.writeEvent(EventLogTags.AM_PROCESS_CRASHED_TOO_MUCH, Loading @@ -631,7 +656,7 @@ class AppErrors { // Don't let services in this process be restarted and potentially // annoy the user repeatedly. Unless it is persistent, since those // processes run critical code. mService.removeProcessLocked(app, false, false, "crash"); mService.removeProcessLocked(app, false, tryAgain, "crash"); mService.mStackSupervisor.resumeFocusedStackTopActivityLocked(); if (!showBackground) { return false; Loading @@ -650,22 +675,9 @@ class AppErrors { } } boolean procIsBoundForeground = (app.curProcState == ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE); // Bump up the crash count of any services currently running in the proc. for (int i=app.services.size()-1; i>=0; i--) { // Any services running in the application need to be placed // back in the pending list. ServiceRecord sr = app.services.valueAt(i); sr.crashCount++; // Allow restarting for started or bound foreground services that are crashing the // first time. This includes wallpapers. if ((data != null) && (sr.crashCount <= 1) && (sr.isForeground || procIsBoundForeground)) { if (data != null && tryAgain) { data.isRestartableForService = true; } } // If the crashing process is what we consider to be the "home process" and it has been // replaced by a third-party app, clear the package preferred activities from packages Loading @@ -690,7 +702,7 @@ class AppErrors { if (!app.isolated) { // XXX Can't keep track of crash times for isolated processes, // because they don't have a perisistent identity. // because they don't have a persistent identity. mProcessCrashTimes.put(app.info.processName, app.uid, now); mProcessCrashTimesPersistent.put(app.info.processName, app.uid, now); } Loading
tests/ServiceCrashTest/Android.mk 0 → 100644 +19 −0 Original line number Diff line number Diff line LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE_TAGS := tests # Only compile source java files in this apk. LOCAL_SRC_FILES := $(call all-java-files-under, src) LOCAL_PACKAGE_NAME := ServiceCrashTest LOCAL_CERTIFICATE := platform LOCAL_JAVA_LIBRARIES := legacy-android-test LOCAL_STATIC_JAVA_LIBRARIES := compatibility-device-util android-support-test include $(BUILD_PACKAGE) # Use the following include to make our test apk. include $(call all-makefiles-under,$(LOCAL_PATH))