Skip to content

Commit

Permalink
WIP Try using UiDevice to set screen orientation
Browse files Browse the repository at this point in the history
PiperOrigin-RevId: 562907287
  • Loading branch information
Paige McAuliffe authored and copybara-androidxtest committed Sep 14, 2023
1 parent 70ba563 commit 57afda0
Show file tree
Hide file tree
Showing 3 changed files with 11 additions and 74 deletions.
2 changes: 1 addition & 1 deletion build_extensions/axt_versions.bzl
Expand Up @@ -39,7 +39,7 @@ ANDROIDX_TRACING_VERSION = "1.1.0"
ANDROIDX_VIEWPAGER_VERSION = "1.0.0"
ANDROIDX_WINDOW_VERSION = "1.1.0"
GOOGLE_MATERIAL_VERSION = "1.4.0"
UIAUTOMATOR_VERSION = "2.2.0"
UIAUTOMATOR_VERSION = "2.3.0-alpha04"
JANK_VERSION = "1.0.1"

# this should match the kotlin toolchain version eg bazel_rules/rules_kotlin/toolchains/kotlin_jvm/kt_jvm_toolchains.bzl KT_VERSION
Expand Down
Expand Up @@ -32,9 +32,11 @@ kt_android_library(
"PhysicalDeviceController.kt",
],
deps = [
"//espresso/device/java/androidx/test/espresso/device/action",
"//espresso/device/java/androidx/test/espresso/device/common",
"//espresso/device/java/androidx/test/espresso/device/controller",
"//opensource/androidx:annotation",
"//runner/monitor",
"@maven//:androidx_test_uiautomator_uiautomator",
],
)
Expand Up @@ -16,24 +16,12 @@

package androidx.test.espresso.device.controller

import android.os.Handler
import android.os.HandlerThread
import android.provider.Settings.System
import android.util.Log
import android.view.Surface
import androidx.annotation.RestrictTo
import androidx.test.espresso.device.common.AccelerometerRotation
import androidx.test.espresso.device.common.SettingsObserver
import androidx.test.espresso.device.common.executeShellCommand
import androidx.test.espresso.device.common.getAccelerometerRotationSetting
import androidx.test.espresso.device.common.getDeviceApiLevel
import androidx.test.espresso.device.common.getMapOfDeviceStateNamesToIdentifiers
import androidx.test.espresso.device.common.setAccelerometerRotationSetting
import androidx.test.espresso.device.action.ScreenOrientation
import androidx.test.platform.app.InstrumentationRegistry
import androidx.test.platform.device.DeviceController
import androidx.test.platform.device.UnsupportedDeviceOperationException
import java.util.concurrent.CountDownLatch
import java.util.concurrent.TimeUnit
import androidx.test.uiautomator.UiDevice

/**
* Implementation of {@link DeviceController} for tests run on a physical device.
Expand All @@ -49,65 +37,12 @@ class PhysicalDeviceController() : DeviceController {
}

override fun setScreenOrientation(screenOrientation: Int) {
// Executing shell commands requires API 21+
if (getDeviceApiLevel() < 21) {
throw UnsupportedDeviceOperationException(
"Setting screen orientation is not suported on physical devices with APIs below 21."
)
}

// TODO(b/296910911) Support setting screen orientation on folded devices
val supportedDeviceStates = getMapOfDeviceStateNamesToIdentifiers()
if (supportedDeviceStates.isNotEmpty()) {
val currentDeviceStateIdentifier = executeShellCommand("cmd device_state print-state").trim()
if (currentDeviceStateIdentifier != getMapOfDeviceStateNamesToIdentifiers().get("OPENED")) {
throw UnsupportedDeviceOperationException(
"Setting screen orientation is not suported on physical foldable devices that are not in flat mode."
)
}
}

// System user_rotation values must be one of the Surface rotation constants and these values
// can indicate different orientations on different devices, since we check if the device is
// already in correct orientation in ScreenOrientationAction, set user_rotation to its opposite
// here to rotate the device to the opposite orientation
val startingUserRotation =
executeShellCommand("settings get system user_rotation").trim().toInt()
val userRotationToSet =
if (
startingUserRotation == Surface.ROTATION_0 || startingUserRotation == Surface.ROTATION_270
) {
Surface.ROTATION_90
} else {
Surface.ROTATION_0
}

// Setting screen orientation with the USER_ROTATION setting requires ACCELEROMETER_ROTATION to
// be disabled
if (getAccelerometerRotationSetting() != AccelerometerRotation.DISABLED) {
Log.d(TAG, "Disabling auto-rotate.")
setAccelerometerRotationSetting(AccelerometerRotation.DISABLED)
}

val settingsLatch: CountDownLatch = CountDownLatch(1)
val thread: HandlerThread = HandlerThread("Observer_Thread")
thread.start()
val runnableHandler: Handler = Handler(thread.getLooper())
val context = InstrumentationRegistry.getInstrumentation().getTargetContext()
val settingsObserver: SettingsObserver =
SettingsObserver(runnableHandler, context, settingsLatch, System.USER_ROTATION)
settingsObserver.observe()
executeShellCommand("settings put system user_rotation ${userRotationToSet}")
settingsLatch.await(5, TimeUnit.SECONDS)
settingsObserver.stopObserver()
thread.quitSafely()

if (
executeShellCommand("settings get system user_rotation").trim().toInt() != userRotationToSet
) {
throw DeviceControllerOperationException(
"Device could not be set to the requested screen orientation."
)
val uiDevice = UiDevice.getInstance(InstrumentationRegistry.getInstrumentation())
uiDevice.unfreezeRotation()
if (screenOrientation == ScreenOrientation.PORTRAIT.getOrientation()) {
uiDevice.setOrientationPortrait()
} else if (screenOrientation == ScreenOrientation.LANDSCAPE.getOrientation()) {
uiDevice.setOrientationLandscape()
}
}

Expand Down

0 comments on commit 57afda0

Please sign in to comment.