Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP Try using UiDevice to set screen orientation #1912

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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