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

Commit 6f7fa5b9 authored by Massimo Carli's avatar Massimo Carli
Browse files

[63/n] Create LetterboxDependenciesHelper to handle different form factors

Other form factors (e.g. Auto) have different Dagger dependencies and
they need to understand if Desktop Windowing is available.

LetterboxDependenciesHelper allows to encapsulate all the configurations
related to the availability of other features on different form factors.
For instance, on Auto, Desktop Windowing is not available and we should
then treat the related transactions differently.

Flag: EXEMPT refactoring
Bug: 423915680
Test: atest WMShellUnitTests:DefaultLetterboxDependenciesHelperTest

Change-Id: I553990b37994374b24db93c2522927c39e83ee51
parent 9a86247f
Loading
Loading
Loading
Loading
+30 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2025 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

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

import android.window.TransitionInfo
import com.android.wm.shell.desktopmode.multidesks.DesksOrganizer

/**
 * Default [LetterboxDependenciesHelper] implementation using Desktop Windowing dependencies.
 */
class DefaultLetterboxDependenciesHelper(val desksOrganizer: DesksOrganizer) :
    LetterboxDependenciesHelper {

    override fun isDesktopWindowingAction(change: TransitionInfo.Change): Boolean =
        desksOrganizer.isDeskChange(change)
}
+32 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2025 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

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

import android.window.TransitionInfo.Change

/**
 * [LetterboxDependenciesHelper] implementation that ignores Desktop Windowing changes or other
 * transitions not related to the Letterbox implementation in Shell. It can be used by form factors
 * that don't allow the Desktop Windowing feature (a.g. Auto).
 */
class IgnoreLetterboxDependenciesHelper : LetterboxDependenciesHelper {
    /**
     * We should ignore all the changes related to Desktop Windowing when the feature is not
     * available.
     */
    override fun isDesktopWindowingAction(change: Change): Boolean = false
}
+31 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2025 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

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

import android.window.TransitionInfo.Change

/**
 * Abstraction for the information about the dependencies between the Letterbox implementation in
 * Shell and other features in Shell not always available.
 */
interface LetterboxDependenciesHelper {

    /**
     * Tells if the [Change] is related to Desktop Windowing.
     */
    fun isDesktopWindowingAction(change: Change): Boolean
}
+90 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2025 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

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

import android.testing.AndroidTestingRunner
import androidx.test.filters.SmallTest
import com.android.wm.shell.ShellTestCase
import com.android.wm.shell.desktopmode.multidesks.DesksOrganizer
import com.android.wm.shell.util.testLetterboxDependenciesHelper
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.kotlin.any
import org.mockito.kotlin.doReturn
import org.mockito.kotlin.mock
import java.util.function.Consumer

/**
 * Tests for [DefaultLetterboxDependenciesHelper].
 *
 * Build/Install/Run:
 *  atest WMShellUnitTests:DefaultLetterboxDependenciesHelperTest
 */
@RunWith(AndroidTestingRunner::class)
@SmallTest
class DefaultLetterboxDependenciesHelperTest : ShellTestCase() {

    @Test
    fun `Default implementation returns true if isDeskChange is true`() {
        runTestScenario { r ->
            testLetterboxDependenciesHelper(r.getLetterboxLifecycleEventFactory()) {
                inputChange { }
                r.configureDeskChangeChecker(isDeskChange = true)
                validateIsDesktopWindowingAction { isDeskChange ->
                    assert(isDeskChange)
                }
            }
        }
    }

    @Test
    fun `Default implementation returns false if isDeskChange is false`() {
        runTestScenario { r ->
            testLetterboxDependenciesHelper(r.getLetterboxLifecycleEventFactory()) {
                inputChange { }
                r.configureDeskChangeChecker(isDeskChange = true)
                validateIsDesktopWindowingAction { isDeskChange ->
                    assert(!isDeskChange)
                }
            }
        }
    }

    /**
     * Runs a test scenario providing a Robot.
     */
    fun runTestScenario(consumer: Consumer<LetterboxDependenciesHelperRobotTest>) {
        val robot = LetterboxDependenciesHelperRobotTest()
        consumer.accept(robot)
    }

    /**
     * Robot contextual to [LetterboxDependenciesHelper].
     */
    class LetterboxDependenciesHelperRobotTest {

        private val desksOrganizer = mock<DesksOrganizer>()

        fun configureDeskChangeChecker(isDeskChange: Boolean) {
            doReturn(isDeskChange).`when`(desksOrganizer).isDeskChange(any())
        }

        fun getLetterboxLifecycleEventFactory(): () -> LetterboxDependenciesHelper = {
            DefaultLetterboxDependenciesHelper(desksOrganizer)
        }
    }
}
+47 −0
Original line number Diff line number Diff line
/*
 * Copyright (C) 2025 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.android.wm.shell.util

import com.android.wm.shell.compatui.letterbox.config.LetterboxDependenciesHelper

@DslMarker
annotation class LetterboxDependenciesHelperTagMarker

@LetterboxDependenciesHelperTagMarker
class LetterboxDependenciesHelperTestContext(
    private val testSubjectFactory: () -> LetterboxDependenciesHelper
) : BaseChangeTestContext() {

    val deskId: Int = -1

    fun validateIsDesktopWindowingAction(verifier: (Boolean) -> Unit) {
        // We execute the test subject using the input
        verifier(testSubjectFactory().isDesktopWindowingAction(inputObject))
    }
}

/**
 * Function to run tests for the different [LetterboxDependenciesHelper] implementations.
 */
fun testLetterboxDependenciesHelper(
    testSubjectFactory: () -> LetterboxDependenciesHelper,
    init: LetterboxDependenciesHelperTestContext.() -> Unit
): LetterboxDependenciesHelperTestContext {
    val testContext = LetterboxDependenciesHelperTestContext(testSubjectFactory)
    testContext.init()
    return testContext
}