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

Commit f2a91a3d authored by Mariia Sandrikova's avatar Mariia Sandrikova Committed by Andrii Kulian
Browse files

Enable forced focus for resumed split screen activities

This is needed because some game engines wait until they get focus before drawing the content of the app so they are blacked out when they are resumed and do not have focus yet.

Bug: 203398248
Test: atest FrameworksCoreTests:ViewRootImplTest#whenDispatchFakeFocus_noFocusAfterwards
Change-Id: I5675b32fbb9f60a7373fadbce379d571168436e7
parent ccf864a8
Loading
Loading
Loading
Loading
+13 −2
Original line number Original line Diff line number Diff line
@@ -4227,7 +4227,8 @@ public final class ActivityThread extends ClientTransactionHandler


    private void scheduleResume(ActivityClientRecord r) {
    private void scheduleResume(ActivityClientRecord r) {
        final ClientTransaction transaction = ClientTransaction.obtain(this.mAppThread, r.token);
        final ClientTransaction transaction = ClientTransaction.obtain(this.mAppThread, r.token);
        transaction.setLifecycleStateRequest(ResumeActivityItem.obtain(/* isForward */ false));
        transaction.setLifecycleStateRequest(ResumeActivityItem.obtain(/* isForward */ false,
                /* shouldSendCompatFakeFocus */ false));
        executeTransaction(transaction);
        executeTransaction(transaction);
    }
    }


@@ -4895,7 +4896,7 @@ public final class ActivityThread extends ClientTransactionHandler


    @Override
    @Override
    public void handleResumeActivity(ActivityClientRecord r, boolean finalStateRequest,
    public void handleResumeActivity(ActivityClientRecord r, boolean finalStateRequest,
            boolean isForward, String reason) {
            boolean isForward, boolean shouldSendCompatFakeFocus, String reason) {
        // If we are getting ready to gc after going to the background, well
        // If we are getting ready to gc after going to the background, well
        // we are back active so skip it.
        // we are back active so skip it.
        unscheduleGcIdler();
        unscheduleGcIdler();
@@ -5002,6 +5003,16 @@ public final class ActivityThread extends ClientTransactionHandler
            if (r.activity.mVisibleFromClient) {
            if (r.activity.mVisibleFromClient) {
                r.activity.makeVisible();
                r.activity.makeVisible();
            }
            }

            if (shouldSendCompatFakeFocus) {
                // Attaching to a window is asynchronous with the activity being resumed,
                // so it's possible we will need to send a fake focus event after attaching
                if (impl != null) {
                    impl.dispatchCompatFakeFocus();
                } else {
                    r.window.getDecorView().fakeFocusAfterAttachingToWindow();
                }
            }
        }
        }


        r.nextIdle = mNewActivities;
        r.nextIdle = mNewActivities;
+2 −1
Original line number Original line Diff line number Diff line
@@ -108,7 +108,8 @@ public abstract class ClientTransactionHandler {
     * @param reason Reason for performing this operation.
     * @param reason Reason for performing this operation.
     */
     */
    public abstract void handleResumeActivity(@NonNull ActivityClientRecord r,
    public abstract void handleResumeActivity(@NonNull ActivityClientRecord r,
            boolean finalStateRequest, boolean isForward, String reason);
            boolean finalStateRequest, boolean isForward, boolean shouldSendCompatFakeFocus,
            String reason);


    /**
    /**
     * Notify the activity about top resumed state change.
     * Notify the activity about top resumed state change.
+17 −5
Original line number Original line Diff line number Diff line
@@ -39,6 +39,9 @@ public class ResumeActivityItem extends ActivityLifecycleItem {
    private int mProcState;
    private int mProcState;
    private boolean mUpdateProcState;
    private boolean mUpdateProcState;
    private boolean mIsForward;
    private boolean mIsForward;
    // Whether we should send compat fake focus when the activity is resumed. This is needed
    // because some game engines wait to get focus before drawing the content of the app.
    private boolean mShouldSendCompatFakeFocus;


    @Override
    @Override
    public void preExecute(ClientTransactionHandler client, IBinder token) {
    public void preExecute(ClientTransactionHandler client, IBinder token) {
@@ -52,7 +55,7 @@ public class ResumeActivityItem extends ActivityLifecycleItem {
            PendingTransactionActions pendingActions) {
            PendingTransactionActions pendingActions) {
        Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityResume");
        Trace.traceBegin(TRACE_TAG_ACTIVITY_MANAGER, "activityResume");
        client.handleResumeActivity(r, true /* finalStateRequest */, mIsForward,
        client.handleResumeActivity(r, true /* finalStateRequest */, mIsForward,
                "RESUME_ACTIVITY");
                mShouldSendCompatFakeFocus, "RESUME_ACTIVITY");
        Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
        Trace.traceEnd(TRACE_TAG_ACTIVITY_MANAGER);
    }
    }


@@ -74,7 +77,8 @@ public class ResumeActivityItem extends ActivityLifecycleItem {
    private ResumeActivityItem() {}
    private ResumeActivityItem() {}


    /** Obtain an instance initialized with provided params. */
    /** Obtain an instance initialized with provided params. */
    public static ResumeActivityItem obtain(int procState, boolean isForward) {
    public static ResumeActivityItem obtain(int procState, boolean isForward,
            boolean shouldSendCompatFakeFocus) {
        ResumeActivityItem instance = ObjectPool.obtain(ResumeActivityItem.class);
        ResumeActivityItem instance = ObjectPool.obtain(ResumeActivityItem.class);
        if (instance == null) {
        if (instance == null) {
            instance = new ResumeActivityItem();
            instance = new ResumeActivityItem();
@@ -82,12 +86,13 @@ public class ResumeActivityItem extends ActivityLifecycleItem {
        instance.mProcState = procState;
        instance.mProcState = procState;
        instance.mUpdateProcState = true;
        instance.mUpdateProcState = true;
        instance.mIsForward = isForward;
        instance.mIsForward = isForward;
        instance.mShouldSendCompatFakeFocus = shouldSendCompatFakeFocus;


        return instance;
        return instance;
    }
    }


    /** Obtain an instance initialized with provided params. */
    /** Obtain an instance initialized with provided params. */
    public static ResumeActivityItem obtain(boolean isForward) {
    public static ResumeActivityItem obtain(boolean isForward, boolean shouldSendCompatFakeFocus) {
        ResumeActivityItem instance = ObjectPool.obtain(ResumeActivityItem.class);
        ResumeActivityItem instance = ObjectPool.obtain(ResumeActivityItem.class);
        if (instance == null) {
        if (instance == null) {
            instance = new ResumeActivityItem();
            instance = new ResumeActivityItem();
@@ -95,6 +100,7 @@ public class ResumeActivityItem extends ActivityLifecycleItem {
        instance.mProcState = ActivityManager.PROCESS_STATE_UNKNOWN;
        instance.mProcState = ActivityManager.PROCESS_STATE_UNKNOWN;
        instance.mUpdateProcState = false;
        instance.mUpdateProcState = false;
        instance.mIsForward = isForward;
        instance.mIsForward = isForward;
        instance.mShouldSendCompatFakeFocus = shouldSendCompatFakeFocus;


        return instance;
        return instance;
    }
    }
@@ -105,6 +111,7 @@ public class ResumeActivityItem extends ActivityLifecycleItem {
        mProcState = ActivityManager.PROCESS_STATE_UNKNOWN;
        mProcState = ActivityManager.PROCESS_STATE_UNKNOWN;
        mUpdateProcState = false;
        mUpdateProcState = false;
        mIsForward = false;
        mIsForward = false;
        mShouldSendCompatFakeFocus = false;
        ObjectPool.recycle(this);
        ObjectPool.recycle(this);
    }
    }


@@ -117,6 +124,7 @@ public class ResumeActivityItem extends ActivityLifecycleItem {
        dest.writeInt(mProcState);
        dest.writeInt(mProcState);
        dest.writeBoolean(mUpdateProcState);
        dest.writeBoolean(mUpdateProcState);
        dest.writeBoolean(mIsForward);
        dest.writeBoolean(mIsForward);
        dest.writeBoolean(mShouldSendCompatFakeFocus);
    }
    }


    /** Read from Parcel. */
    /** Read from Parcel. */
@@ -124,6 +132,7 @@ public class ResumeActivityItem extends ActivityLifecycleItem {
        mProcState = in.readInt();
        mProcState = in.readInt();
        mUpdateProcState = in.readBoolean();
        mUpdateProcState = in.readBoolean();
        mIsForward = in.readBoolean();
        mIsForward = in.readBoolean();
        mShouldSendCompatFakeFocus = in.readBoolean();
    }
    }


    public static final @NonNull Creator<ResumeActivityItem> CREATOR =
    public static final @NonNull Creator<ResumeActivityItem> CREATOR =
@@ -147,7 +156,8 @@ public class ResumeActivityItem extends ActivityLifecycleItem {
        }
        }
        final ResumeActivityItem other = (ResumeActivityItem) o;
        final ResumeActivityItem other = (ResumeActivityItem) o;
        return mProcState == other.mProcState && mUpdateProcState == other.mUpdateProcState
        return mProcState == other.mProcState && mUpdateProcState == other.mUpdateProcState
                && mIsForward == other.mIsForward;
                && mIsForward == other.mIsForward
                && mShouldSendCompatFakeFocus == other.mShouldSendCompatFakeFocus;
    }
    }


    @Override
    @Override
@@ -156,12 +166,14 @@ public class ResumeActivityItem extends ActivityLifecycleItem {
        result = 31 * result + mProcState;
        result = 31 * result + mProcState;
        result = 31 * result + (mUpdateProcState ? 1 : 0);
        result = 31 * result + (mUpdateProcState ? 1 : 0);
        result = 31 * result + (mIsForward ? 1 : 0);
        result = 31 * result + (mIsForward ? 1 : 0);
        result = 31 * result + (mShouldSendCompatFakeFocus ? 1 : 0);
        return result;
        return result;
    }
    }


    @Override
    @Override
    public String toString() {
    public String toString() {
        return "ResumeActivityItem{procState=" + mProcState
        return "ResumeActivityItem{procState=" + mProcState
                + ",updateProcState=" + mUpdateProcState + ",isForward=" + mIsForward + "}";
                + ",updateProcState=" + mUpdateProcState + ",isForward=" + mIsForward
                + ",shouldSendCompatFakeFocus=" + mShouldSendCompatFakeFocus + "}";
    }
    }
}
}
+2 −1
Original line number Original line Diff line number Diff line
@@ -226,7 +226,8 @@ public class TransactionExecutor {
                    break;
                    break;
                case ON_RESUME:
                case ON_RESUME:
                    mTransactionHandler.handleResumeActivity(r, false /* finalStateRequest */,
                    mTransactionHandler.handleResumeActivity(r, false /* finalStateRequest */,
                            r.isForward, "LIFECYCLER_RESUME_ACTIVITY");
                            r.isForward, false /* shouldSendCompatFakeFocus */,
                            "LIFECYCLER_RESUME_ACTIVITY");
                    break;
                    break;
                case ON_PAUSE:
                case ON_PAUSE:
                    mTransactionHandler.handlePauseActivity(r, false /* finished */,
                    mTransactionHandler.handlePauseActivity(r, false /* finished */,
+2 −1
Original line number Original line Diff line number Diff line
@@ -202,7 +202,8 @@ public class TransactionExecutorHelper {
                lifecycleItem = StopActivityItem.obtain(0 /* configChanges */);
                lifecycleItem = StopActivityItem.obtain(0 /* configChanges */);
                break;
                break;
            default:
            default:
                lifecycleItem = ResumeActivityItem.obtain(false /* isForward */);
                lifecycleItem = ResumeActivityItem.obtain(false /* isForward */,
                        false /* shouldSendCompatFakeFocus */);
                break;
                break;
        }
        }


Loading