summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/java/android/app/ApplicationErrorReport.java9
-rw-r--r--services/core/java/com/android/server/am/ActivityManagerService.java12
-rw-r--r--services/core/java/com/android/server/am/ActivityRecord.java36
-rw-r--r--services/core/java/com/android/server/am/ActivityStack.java11
-rw-r--r--services/core/java/com/android/server/am/ActivityStackSupervisor.java5
-rw-r--r--services/core/java/com/android/server/am/ActivityTaskManagerService.java2
-rw-r--r--services/core/java/com/android/server/am/AppErrors.java10
-rw-r--r--services/core/java/com/android/server/am/WindowProcessController.java13
-rw-r--r--services/core/java/com/android/server/wm/TaskWindowContainerController.java6
9 files changed, 103 insertions, 1 deletions
diff --git a/core/java/android/app/ApplicationErrorReport.java b/core/java/android/app/ApplicationErrorReport.java
index e6452619b508..8874554f928c 100644
--- a/core/java/android/app/ApplicationErrorReport.java
+++ b/core/java/android/app/ApplicationErrorReport.java
@@ -29,6 +29,7 @@ import android.os.SystemProperties;
import android.provider.Settings;
import android.util.Printer;
import android.util.Slog;
+
import com.android.internal.util.FastPrintWriter;
import java.io.PrintWriter;
@@ -333,6 +334,12 @@ public class ApplicationErrorReport implements Parcelable {
public String stackTrace;
/**
+ * Crash tag for some context.
+ * @hide
+ */
+ public String crashTag;
+
+ /**
* Create an uninitialized instance of CrashInfo.
*/
public CrashInfo() {
@@ -416,6 +423,7 @@ public class ApplicationErrorReport implements Parcelable {
throwMethodName = in.readString();
throwLineNumber = in.readInt();
stackTrace = in.readString();
+ crashTag = in.readString();
}
/**
@@ -430,6 +438,7 @@ public class ApplicationErrorReport implements Parcelable {
dest.writeString(throwMethodName);
dest.writeInt(throwLineNumber);
dest.writeString(stackTrace);
+ dest.writeString(crashTag);
int total = dest.dataPosition()-start;
if (Binder.CHECK_PARCEL_SIZE && total > 20*1024) {
Slog.d("Error", "ERR: exClass=" + exceptionClassName);
diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java
index 3a7c00cbb141..0cf101cdcea3 100644
--- a/services/core/java/com/android/server/am/ActivityManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityManagerService.java
@@ -10578,6 +10578,15 @@ public class ActivityManagerService extends IActivityManager.Stub
StatsLog.write(StatsLog.WTF_OCCURRED, callingUid, tag, processName,
callingPid);
+ final int relaunchReason = r == null ? ActivityRecord.RELAUNCH_REASON_NONE
+ : r.getWindowProcessController().computeRelaunchReason();
+ final String relaunchReasonString = ActivityRecord.relaunchReasonToString(relaunchReason);
+ if (crashInfo.crashTag == null) {
+ crashInfo.crashTag = relaunchReasonString;
+ } else {
+ crashInfo.crashTag = crashInfo.crashTag + " " + relaunchReasonString;
+ }
+
addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
return r;
@@ -10732,6 +10741,9 @@ public class ActivityManagerService extends IActivityManager.Stub
if (Debug.isDebuggerConnected()) {
sb.append("Debugger: Connected\n");
}
+ if (crashInfo != null && crashInfo.crashTag != null && !crashInfo.crashTag.isEmpty()) {
+ sb.append("Crash-Tag: ").append(crashInfo.crashTag).append("\n");
+ }
sb.append("\n");
// Do the rest in a worker thread to avoid blocking the caller on I/O
diff --git a/services/core/java/com/android/server/am/ActivityRecord.java b/services/core/java/com/android/server/am/ActivityRecord.java
index 68e70a9634d1..19ea9554e720 100644
--- a/services/core/java/com/android/server/am/ActivityRecord.java
+++ b/services/core/java/com/android/server/am/ActivityRecord.java
@@ -339,6 +339,17 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo
int mStartingWindowState = STARTING_WINDOW_NOT_SHOWN;
boolean mTaskOverlay = false; // Task is always on-top of other activities in the task.
+ // This activity is not being relaunched, or being relaunched for a non-resize reason.
+ static final int RELAUNCH_REASON_NONE = 0;
+ // This activity is being relaunched due to windowing mode change.
+ static final int RELAUNCH_REASON_WINDOWING_MODE_RESIZE = 1;
+ // This activity is being relaunched due to a free-resize operation.
+ static final int RELAUNCH_REASON_FREE_RESIZE = 2;
+ // Marking the reason why this activity is being relaunched. Mainly used to track that this
+ // activity is being relaunched to fulfill a resize request due to compatibility issues, e.g. in
+ // pre-NYC apps that don't have a sense of being resized.
+ int mRelaunchReason = RELAUNCH_REASON_NONE;
+
TaskDescription taskDescription; // the recents information for this activity
boolean mLaunchTaskBehind; // this activity is actively being launched with
// ActivityOptions.setLaunchTaskBehind, will be cleared once launch is completed.
@@ -2617,6 +2628,15 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo
startFreezingScreenLocked(app, globalChanges);
forceNewConfig = false;
preserveWindow &= isResizeOnlyChange(changes);
+ final boolean hasResizeChange = hasResizeChange(changes & ~info.getRealConfigChanged());
+ if (hasResizeChange) {
+ final boolean isDragResizing =
+ getTask().getWindowContainerController().isDragResizing();
+ mRelaunchReason = isDragResizing ? RELAUNCH_REASON_FREE_RESIZE
+ : RELAUNCH_REASON_WINDOWING_MODE_RESIZE;
+ } else {
+ mRelaunchReason = RELAUNCH_REASON_NONE;
+ }
if (!attachedToProcess()) {
if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
"Config is destroying non-running " + this);
@@ -2738,6 +2758,11 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo
| CONFIG_SCREEN_LAYOUT)) == 0;
}
+ private static boolean hasResizeChange(int change) {
+ return (change & (CONFIG_SCREEN_SIZE | CONFIG_SMALLEST_SCREEN_SIZE | CONFIG_ORIENTATION
+ | CONFIG_SCREEN_LAYOUT)) != 0;
+ }
+
void relaunchActivityLocked(boolean andResume, boolean preserveWindow) {
if (service.mSuppressResizeConfigChanges && preserveWindow) {
configChangeFlags = 0;
@@ -3017,6 +3042,17 @@ final class ActivityRecord extends ConfigurationContainer implements AppWindowCo
mWindowContainerController.registerRemoteAnimations(definition);
}
+ static String relaunchReasonToString(int relaunchReason) {
+ switch (relaunchReason) {
+ case RELAUNCH_REASON_WINDOWING_MODE_RESIZE:
+ return "window_resize";
+ case RELAUNCH_REASON_FREE_RESIZE:
+ return "free_resize";
+ default:
+ return null;
+ }
+ }
+
@Override
public String toString() {
if (stringName != null) {
diff --git a/services/core/java/com/android/server/am/ActivityStack.java b/services/core/java/com/android/server/am/ActivityStack.java
index accb61f287ea..058c714148a4 100644
--- a/services/core/java/com/android/server/am/ActivityStack.java
+++ b/services/core/java/com/android/server/am/ActivityStack.java
@@ -72,6 +72,8 @@ import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_USER_LEAV
import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
+import static com.android.server.am.ActivityRecord.RELAUNCH_REASON_FREE_RESIZE;
+import static com.android.server.am.ActivityRecord.RELAUNCH_REASON_WINDOWING_MODE_RESIZE;
import static com.android.server.am.ActivityStack.ActivityState.DESTROYED;
import static com.android.server.am.ActivityStack.ActivityState.DESTROYING;
import static com.android.server.am.ActivityStack.ActivityState.FINISHING;
@@ -4483,7 +4485,14 @@ class ActivityStack<T extends StackWindowController> extends ConfigurationContai
hasVisibleActivities = true;
}
final boolean remove;
- if ((!r.haveState && !r.stateNotNeeded) || r.finishing) {
+ if ((r.mRelaunchReason == RELAUNCH_REASON_WINDOWING_MODE_RESIZE
+ || r.mRelaunchReason == RELAUNCH_REASON_FREE_RESIZE)
+ && r.launchCount < 3 && !r.finishing) {
+ // If the process crashed during a resize, always try to relaunch it, unless
+ // it has failed more than twice. Skip activities that's already finishing
+ // cleanly by itself.
+ remove = false;
+ } else if ((!r.haveState && !r.stateNotNeeded) || r.finishing) {
// Don't currently have state for the activity, or
// it is finishing -- always remove it.
remove = true;
diff --git a/services/core/java/com/android/server/am/ActivityStackSupervisor.java b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
index b08efde051b7..a7325754f178 100644
--- a/services/core/java/com/android/server/am/ActivityStackSupervisor.java
+++ b/services/core/java/com/android/server/am/ActivityStackSupervisor.java
@@ -74,6 +74,7 @@ import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
import static com.android.server.am.ActivityManagerService.ANIMATE;
import static com.android.server.am.ActivityManagerService.FIRST_SUPERVISOR_STACK_MSG;
+import static com.android.server.am.ActivityRecord.RELAUNCH_REASON_NONE;
import static com.android.server.am.ActivityStack.ActivityState.DESTROYED;
import static com.android.server.am.ActivityStack.ActivityState.DESTROYING;
import static com.android.server.am.ActivityStack.ActivityState.INITIALIZING;
@@ -2100,6 +2101,10 @@ public class ActivityStackSupervisor extends ConfigurationContainer implements D
if (isTopDisplayFocusedStack(r.getStack()) || fromTimeout) {
booting = checkFinishBootingLocked();
}
+
+ // When activity is idle, we consider the relaunch must be successful, so let's clear
+ // the flag.
+ r.mRelaunchReason = RELAUNCH_REASON_NONE;
}
if (allResumedActivitiesIdle()) {
diff --git a/services/core/java/com/android/server/am/ActivityTaskManagerService.java b/services/core/java/com/android/server/am/ActivityTaskManagerService.java
index 20f2ece9565c..ab1ba6cce2f5 100644
--- a/services/core/java/com/android/server/am/ActivityTaskManagerService.java
+++ b/services/core/java/com/android/server/am/ActivityTaskManagerService.java
@@ -1195,6 +1195,8 @@ public class ActivityTaskManagerService extends IActivityTaskManager.Stub {
if (!res) {
Slog.i(TAG, "Removing task failed to finish activity");
}
+ // Explicitly dismissing the activity so reset its relaunch flag.
+ r.mRelaunchReason = ActivityRecord.RELAUNCH_REASON_NONE;
} else {
res = tr.getStack().requestFinishActivityLocked(token, resultCode,
resultData, "app-request", true);
diff --git a/services/core/java/com/android/server/am/AppErrors.java b/services/core/java/com/android/server/am/AppErrors.java
index 27567a77f1f7..7652dd4d26e1 100644
--- a/services/core/java/com/android/server/am/AppErrors.java
+++ b/services/core/java/com/android/server/am/AppErrors.java
@@ -410,6 +410,10 @@ class AppErrors {
RescueParty.notePersistentAppCrash(mContext, r.uid);
}
+ final int relaunchReason = r != null
+ ? r.getWindowProcessController().computeRelaunchReason()
+ : ActivityRecord.RELAUNCH_REASON_NONE;
+
AppErrorResult result = new AppErrorResult();
TaskRecord task;
synchronized (mService) {
@@ -422,6 +426,12 @@ class AppErrors {
return;
}
+ // Suppress crash dialog if the process is being relaunched due to a crash during a free
+ // resize.
+ if (relaunchReason == ActivityRecord.RELAUNCH_REASON_FREE_RESIZE) {
+ return;
+ }
+
/**
* If this process was running instrumentation, finish now - it will be handled in
* {@link ActivityManagerService#handleAppDiedLocked}.
diff --git a/services/core/java/com/android/server/am/WindowProcessController.java b/services/core/java/com/android/server/am/WindowProcessController.java
index 6f3fb8eb9b72..d4c9bcb1c826 100644
--- a/services/core/java/com/android/server/am/WindowProcessController.java
+++ b/services/core/java/com/android/server/am/WindowProcessController.java
@@ -436,6 +436,19 @@ public class WindowProcessController {
return minTaskLayer;
}
+ int computeRelaunchReason() {
+ synchronized (mAtm.mGlobalLock) {
+ final int activitiesSize = mActivities.size();
+ for (int i = activitiesSize - 1; i >= 0; i--) {
+ final ActivityRecord r = mActivities.get(i);
+ if (r.mRelaunchReason != ActivityRecord.RELAUNCH_REASON_NONE) {
+ return r.mRelaunchReason;
+ }
+ }
+ }
+ return ActivityRecord.RELAUNCH_REASON_NONE;
+ }
+
void clearProfilerIfNeeded() {
if (mListener == null) return;
// Posting on handler so WM lock isn't held when we call into AM.
diff --git a/services/core/java/com/android/server/wm/TaskWindowContainerController.java b/services/core/java/com/android/server/wm/TaskWindowContainerController.java
index d83f28ccb31c..8b634b1bb938 100644
--- a/services/core/java/com/android/server/wm/TaskWindowContainerController.java
+++ b/services/core/java/com/android/server/wm/TaskWindowContainerController.java
@@ -209,6 +209,12 @@ public class TaskWindowContainerController
}
}
+ public boolean isDragResizing() {
+ synchronized (mWindowMap) {
+ return mContainer.isDragResizing();
+ }
+ }
+
void reportSnapshotChanged(TaskSnapshot snapshot) {
mHandler.obtainMessage(H.REPORT_SNAPSHOT_CHANGED, snapshot).sendToTarget();
}