Skip to content

Commit

Permalink
Fix DisplaySizeRule for failing tests and support using DisplaySizeRu…
Browse files Browse the repository at this point in the history
…le without ActivityScenario/AndroidComposeTestRule

This simplifies the implementation of DisplaySizeRule using "wm size reset" and supports resetting the display size without an activity in the resumed state.

PiperOrigin-RevId: 723574207
  • Loading branch information
Paige McAuliffe authored and copybara-androidxtest committed Feb 5, 2025
1 parent 2f61dbe commit 978a6e4
Show file tree
Hide file tree
Showing 2 changed files with 4 additions and 69 deletions.
3 changes: 3 additions & 0 deletions espresso/device/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@
`androidx.test.espresso:espresso-device:{version}` is released.

**Bug Fixes**
Fix DisplaySizeRule not consistently restoring to original emulator state for
failing tests
Support using DisplaySizeRule without an activity in the resumed state

**New Features**

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,21 +15,9 @@
*/
package androidx.test.espresso.device.rules

import android.app.Activity
import android.content.res.Configuration
import android.util.Log
import android.view.View
import android.view.ViewGroup
import androidx.test.espresso.device.common.calculateCurrentDisplayWidthAndHeightPx
import androidx.test.espresso.device.common.executeShellCommand
import androidx.test.espresso.device.common.getDeviceApiLevel
import androidx.test.espresso.device.common.getResumedActivityOrNull
import androidx.test.espresso.device.controller.DeviceControllerOperationException
import androidx.test.platform.device.UnsupportedDeviceOperationException
import androidx.test.runner.lifecycle.ActivityLifecycleCallback
import androidx.test.runner.lifecycle.ActivityLifecycleMonitorRegistry
import androidx.test.runner.lifecycle.Stage
import java.util.concurrent.CountDownLatch
import org.junit.rules.TestRule
import org.junit.runner.Description
import org.junit.runners.model.Statement
Expand All @@ -45,64 +33,8 @@ class DisplaySizeRule : TestRule {
)
}

val startingDisplaySize = calculateCurrentDisplayWidthAndHeightPx()
statement.evaluate()

if (startingDisplaySize != calculateCurrentDisplayWidthAndHeightPx()) {
val activity = getResumedActivityOrNull()
if (activity != null) {
val latch = CountDownLatch(1)
val container: ViewGroup =
activity.getWindow().findViewById(android.R.id.content) as ViewGroup
val activityView: View =
object : View(activity) {
override fun onConfigurationChanged(newConfig: Configuration?) {
super.onConfigurationChanged(newConfig)
if (startingDisplaySize == calculateCurrentDisplayWidthAndHeightPx()) {
if (Log.isLoggable(TAG, Log.DEBUG)) {
Log.d(
TAG,
"View configuration changed. Display size restored to starting size."
)
}
latch.countDown()
}
}
}
activity.runOnUiThread { container.addView(activityView) }
val activityLifecyleCallback: ActivityLifecycleCallback =
object : ActivityLifecycleCallback {
override fun onActivityLifecycleChanged(activity: Activity, stage: Stage) {
if (
activity.getLocalClassName() == activity.getLocalClassName() &&
stage == Stage.PAUSED &&
startingDisplaySize == calculateCurrentDisplayWidthAndHeightPx()
) {
if (Log.isLoggable(TAG, Log.DEBUG)) {
Log.d(TAG, "Activity restarted. Display size restored to starting size.")
}
latch.countDown()
}
}
}
ActivityLifecycleMonitorRegistry.getInstance()
.addLifecycleCallback(activityLifecyleCallback)

executeShellCommand(
"wm size ${startingDisplaySize.first}x${startingDisplaySize.second}"
)
latch.await()

activity.runOnUiThread { container.removeView(activityView) }
ActivityLifecycleMonitorRegistry.getInstance()
.removeLifecycleCallback(activityLifecyleCallback)
} else {
throw DeviceControllerOperationException(
"Device could not be set to the requested display size because there are no activities in" +
" the resumed stage."
)
}
}
executeShellCommand("wm size reset")
}
}
}
Expand Down

0 comments on commit 978a6e4

Please sign in to comment.