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

Commit 00403159 authored by Massimo Carli's avatar Massimo Carli Committed by Android (Google) Code Review
Browse files

Merge "[65/n] Exclude Tasks without Activities from Letterboxing" into main

parents 45d3fc74 b6ccc323
Loading
Loading
Loading
Loading
+21 −2
Original line number Diff line number Diff line
@@ -114,6 +114,8 @@ public class AppCompatTaskInfo implements Parcelable {
    public static final int FLAG_OPT_OUT_EDGE_TO_EDGE = FLAG_BASE << 11;
    /** Top activity flag for whether activity is letterboxed for a safe region. */
    public static final int FLAG_SAFE_REGION_LETTERBOXED = FLAG_BASE << 12;
    /** The related task is a leaf task. */
    public static final int FLAG_IS_LEAF_TASK = FLAG_BASE << 13;

    @Retention(RetentionPolicy.SOURCE)
    @IntDef(flag = true, value = {
@@ -130,7 +132,8 @@ public class AppCompatTaskInfo implements Parcelable {
            FLAG_HAS_MIN_ASPECT_RATIO_OVERRIDE,
            FLAG_ENABLE_RESTART_MENU_FOR_DISPLAY_MOVE,
            FLAG_OPT_OUT_EDGE_TO_EDGE,
            FLAG_SAFE_REGION_LETTERBOXED
            FLAG_SAFE_REGION_LETTERBOXED,
            FLAG_IS_LEAF_TASK
    })
    public @interface TopActivityFlag {}

@@ -145,7 +148,8 @@ public class AppCompatTaskInfo implements Parcelable {
    private static final int FLAGS_ORGANIZER_INTERESTED = FLAG_IS_FROM_LETTERBOX_DOUBLE_TAP
            | FLAG_ELIGIBLE_FOR_USER_ASPECT_RATIO_BUTTON | FLAG_FULLSCREEN_OVERRIDE_SYSTEM
            | FLAG_FULLSCREEN_OVERRIDE_USER | FLAG_HAS_MIN_ASPECT_RATIO_OVERRIDE
            | FLAG_OPT_OUT_EDGE_TO_EDGE | FLAG_ENABLE_RESTART_MENU_FOR_DISPLAY_MOVE;
            | FLAG_OPT_OUT_EDGE_TO_EDGE | FLAG_ENABLE_RESTART_MENU_FOR_DISPLAY_MOVE
            | FLAG_IS_LEAF_TASK;

    @TopActivityFlag
    private static final int FLAGS_COMPAT_UI_INTERESTED = FLAGS_ORGANIZER_INTERESTED
@@ -221,6 +225,20 @@ public class AppCompatTaskInfo implements Parcelable {
        return isTopActivityFlagEnabled(FLAG_ELIGIBLE_FOR_LETTERBOX_EDU);
    }

    /**
     * Set if the current Task is a leaf task.
     */
    public void setIsLeafTask(boolean isLeafTask) {
        setTopActivityFlag(FLAG_IS_LEAF_TASK, isLeafTask);
    }

    /**
     * @return {@code true} if the task is a leaf task.
     */
    public boolean isLeafTask() {
        return isTopActivityFlagEnabled(FLAG_IS_LEAF_TASK);
    }

    /**
     * Sets the top activity flag to be eligible for letterbox education.
     */
@@ -467,6 +485,7 @@ public class AppCompatTaskInfo implements Parcelable {
    @Override
    public String toString() {
        return "AppCompatTaskInfo { topActivityInSizeCompat=" + isTopActivityInSizeCompat()
                + " isLeafTask= " + isLeafTask()
                + " eligibleForLetterboxEducation= " + eligibleForLetterboxEducation()
                + " isLetterboxEducationEnabled= " + isLetterboxEducationEnabled()
                + " isLetterboxDoubleTapEnabled= " + isLetterboxDoubleTapEnabled()
+22 −0
Original line number Diff line number Diff line
@@ -61,3 +61,25 @@ fun Change.asLetterboxLifecycleEventType() = when {
    isOpeningType(mode) -> OPEN
    else -> NONE
}

/**
 * Logic to skip a [Change] if not related to Letterboxing. We always skip changes about closing.
 * We skip the changes for tasks which are not leaves. The isLeaf information for changes with
 * activity target is always false but those changes cannot be skipped.
 *
 * No leaf task    -> isChangeForALeafTask()==false  isActivityChange()==false     Skip
 * leaf task       -> isChangeForALeafTask()==true   isActivityChange()==false     No Skip
 * Activity change -> isChangeForALeafTask()==false  isActivityChange()==true      No Skip
 */
fun Change.shouldSkipForLetterbox(): Boolean =
    isClosingType(mode) || !(isChangeForALeafTask() || isActivityChange())

/**
 * Returns [true] if the [Change] is about an [Activity] and so it contains a
 * [ActivityTransitionInfo].
 */
fun Change.isActivityChange(): Boolean = activityTransitionInfo != null

/** Returns [true] if the Task hosts Activities */
fun Change.isChangeForALeafTask(): Boolean =
    taskInfo?.appCompatTaskInfo?.isLeafTask() ?: false
+4 −5
Original line number Diff line number Diff line
@@ -16,9 +16,8 @@

package com.android.wm.shell.compatui.letterbox.lifecycle

import android.window.TransitionInfo
import android.window.TransitionInfo.Change
import com.android.wm.shell.dagger.WMSingleton
import com.android.wm.shell.shared.TransitionUtil.isClosingType
import javax.inject.Inject

/**
@@ -28,11 +27,11 @@ import javax.inject.Inject
@WMSingleton
class SkipLetterboxLifecycleEventFactory @Inject constructor() : LetterboxLifecycleEventFactory {

    // We also ignore closing Changes.
    override fun canHandle(change: TransitionInfo.Change): Boolean = isClosingType(change.mode)
    // We also ignore closing Changes or changes related to Tasks without any activity.
    override fun canHandle(change: Change): Boolean = change.shouldSkipForLetterbox()

    // Although this LetterboxLifecycleEventFactory is able to handle the specific Change
    // it returns an empty LetterboxLifecycleEvent to basically ignore the Change.
    override fun createLifecycleEvent(change: TransitionInfo.Change): LetterboxLifecycleEvent? =
    override fun createLifecycleEvent(change: Change): LetterboxLifecycleEvent? =
        null
}
+43 −2
Original line number Diff line number Diff line
@@ -54,13 +54,54 @@ class SkipLetterboxLifecycleEventFactoryTest : ShellTestCase() {
    }

    @Test
    fun `Factory is skipped when Change is not closing one`() {
    fun `Factory is active when Change is for a Task which is NOT a leaf`() {
        runTestScenario { r ->
            testLetterboxLifecycleEventFactory(r.getLetterboxLifecycleEventFactory()) {
                inputChange {
                    mode = TRANSIT_OPEN
                    runningTaskInfo { ti ->
                        ti.appCompatTaskInfo.setIsLeafTask(false)
                    }
                }
                validateCanHandle { canHandle ->
                    assert(canHandle)
                }
                validateCreateLifecycleEvent { event ->
                    assert(event == null)
                }
            }
        }
    }

    @Test
    fun `Factory is skipped when Change is not closing for a Task which is NOT a leaf`() {
        runTestScenario { r ->
            testLetterboxLifecycleEventFactory(r.getLetterboxLifecycleEventFactory()) {
                inputChange {
                    mode = TRANSIT_OPEN
                    runningTaskInfo { ti ->
                        ti.appCompatTaskInfo.setIsLeafTask(true)
                    }
                }
                validateCanHandle { canHandle ->
                    assert(!canHandle)
                }
                validateCreateLifecycleEvent { event ->
                    assert(event != null)
                    assert(event?.type == LetterboxLifecycleEventType.NONE)
                }
            }
        }
    }

    @Test
    fun `Factory is skipped when Change is not closing for an Activity Transition`() {
        runTestScenario { r ->
            testLetterboxLifecycleEventFactory(r.getLetterboxLifecycleEventFactory()) {
                inputChange {
                    mode = TRANSIT_OPEN
                    activityTransitionInfo {
                        taskId = 10
                        this.taskId = 10
                    }
                }
                validateCanHandle { canHandle ->
+1 −1
Original line number Diff line number Diff line
@@ -139,7 +139,7 @@ final class AppCompatUtils {
            @Nullable ActivityRecord top) {
        final AppCompatTaskInfo appCompatTaskInfo = info.appCompatTaskInfo;
        clearAppCompatTaskInfo(appCompatTaskInfo);

        appCompatTaskInfo.setIsLeafTask(task.isLeafTask());
        if (top == null) {
            return;
        }