The Jetpack WindowManager library notifies your application when there’s a change in the posture of a foldable device so that you can modify the application’s layout.
The Jetpack WindowManager
window-testing
artifact includes a
WindowLayoutInfoPublisherRule
JUnit4 rule that can publish a custom WindowInfoLayout
to simulate a
FoldingFeature
in tests.
You can start by defining your test class and the testing rules:
Kotlin
import androidx.window.layout.FoldingFeature.Orientation.Companion.HORIZONTAL import androidx.window.layout.FoldingFeature.Orientation.Companion.VERTICAL import androidx.window.layout.FoldingFeature.State.Companion.FLAT import androidx.window.layout.FoldingFeature.State.Companion.HALF_OPENED import androidx.window.testing.layout.FoldingFeature import androidx.window.testing.layout.TestWindowLayoutInfo import androidx.window.testing.layout.WindowLayoutInfoPublisherRule @RunWith(AndroidJUnit4::class) class DisplayFeaturesActivityTest { private val activityRule = ActivityScenarioRule(DisplayFeaturesActivity::class.java) private val publisherRule = WindowLayoutInfoPublisherRule() @get:Rule val testRule: TestRule init { testRule = RuleChain.outerRule(publisherRule).around(activityRule) } @Test myTest() { // TODO } }
Java
import static androidx.window.layout.FoldingFeature.Orientation.HORIZONTAL; import static androidx.window.layout.FoldingFeature.Orientation.VERTICAL; import static androidx.window.layout.FoldingFeature.State.FLAT; import static androidx.window.layout.FoldingFeature.State.HALF_OPENED; import static androidx.window.testing.layout.DisplayFeatureTesting.createFoldingFeature; import static androidx.window.testing.layout.WindowLayoutInfoTesting.createWindowLayoutInfo; import androidx.window.layout.FoldingFeature; import androidx.window.layout.WindowLayoutInfo; import androidx.window.testing.layout.WindowLayoutInfoPublisherRule; @RunWith(AndroidJUnit4.class) public class DisplayFeaturesActivityJavaTest { private WindowLayoutInfoPublisherRule publisherRule = new WindowLayoutInfoPublisherRule(); @Rule public TestRule testRule; public DisplayFeaturesActivityJavaTest() { testRule = RuleChain.outerRule(publisherRule).around(activityRule); }; @Test public void myTest() { // TODO } }
We can simulate a half-opened foldable screen with a centered horizontal fold of zero width with the code:
Kotlin
val feature = FoldingFeature( activity = activity, state = HALF_OPENED, orientation = HORIZONTAL) val expected = TestWindowLayoutInfo(listOf(feature))
Java
FoldingFeature feature = createFoldingFeature( activity, -1, 0, HALF_OPENED, HORIZONTAL); WindowLayoutInfo expected = createWindowLayoutInfo( Collections.singletonList(feature) );
then use the WindowLayoutInfoPublisherRule
to publish it:
Kotlin
@Test myTest() { ... publisherRule.overrideWindowLayoutInfo(expected) ... }
Java
@Test public void myTest() { ... publisherRule.overrideWindowLayoutInfo(expected); ... }
The final step is to check that the activity layout we're testing behaves as expected using the available Espresso matchers.
Below is an example of a test simulating a FoldingFeature
with a
HALF_OPENED
vertical hinge in the screen’s center, and then using a matcher
to check that the layout is the one we expect:
Kotlin
@Test fun testDeviceOpen_Vertical() { activityRule.scenario.onActivity { activity -> val feature = FoldingFeature( activity = activity, state = HALF_OPENED, orientation = VERTICAL) val expected = TestWindowLayoutInfo(listOf(feature)) publisherRule.overrideWindowLayoutInfo(expected) } // Checks that start_layout is on the left of end_layout with a vertical folding feature. onView(withId(R.id.start_layout)) .check(isCompletelyLeftOf(withId(R.id.end_layout))) }
Java
@Test public void testDeviceOpen_Vertical() { activityRule .getScenario() .onActivity( activity -> { FoldingFeature feature = createFoldingFeature( activity, -1, 0, HALF_OPENED, VERTICAL); WindowLayoutInfo expected = createWindowLayoutInfo( Collections.singletonList(feature) ); publisherRule.overrideWindowLayoutInfo(expected); }); // Checks that start_layout is on the left of end_layout with a vertical folding feature. onView(withId(R.id.start_layout)) .check(isCompletelyLeftOf(withId(R.id.end_layout))); }