Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 2746ab5b authored by Garfield Tan's avatar Garfield Tan
Browse files

Add some compatibility support for resizing.

This includes changes to:
1) Allow app crash at most twice during resizing w/o interrupting
resizing process -- this is also necessary to support relaunching pre-N
app when user force maximizing/restoring pre-N apps.
2) Add crash tag to indicate that a crash happens during resizing.

This is one of starter tasks to improve large display UX, and a
spiritual cherry pick of a6364ef4af9e7e78934859f0ae2ea48e678a09c2 and
19bda6841f321ba780577265c90b0d4b7a066b1f.

Bug: 111840655
Test: go/wm-smoke
Change-Id: Ief9e1ee9cefbfd5cfd5047158f2bb1a12b19ed6f
parent 3b8a4cec
Loading
Loading
Loading
Loading
+9 −0
Original line number Diff line number Diff line
@@ -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;
@@ -332,6 +333,12 @@ public class ApplicationErrorReport implements Parcelable {
         */
        public String stackTrace;

        /**
         * Crash tag for some context.
         * @hide
         */
        public String crashTag;

        /**
         * Create an uninitialized instance of 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);
+12 −0
Original line number Diff line number Diff line
@@ -11869,6 +11869,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;
@@ -12023,6 +12032,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
+36 −0
Original line number Diff line number Diff line
@@ -338,6 +338,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.
@@ -2616,6 +2627,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);
@@ -2737,6 +2757,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;
@@ -3016,6 +3041,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) {
+10 −1
Original line number Diff line number Diff line
@@ -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;
+5 −0
Original line number Diff line number Diff line
@@ -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()) {
Loading