From f84116fb0835eb82060234ac26d619de55ca1a19 Mon Sep 17 00:00:00 2001 From: Brett Chabot Date: Tue, 19 Dec 2023 09:31:38 -0800 Subject: [PATCH] Attempt to add better error reporting when espresso device is used without INTERNET permission. Currently if a test attempts to use espresso-device on an emulator without the INTERNET permission, they will see a cryptic error like ``` Caused by: java.net.SocketException: socket failed: EPERM (Operation not permitted) ``` This change adds an explicit check to see if the current process has the INTERNET permission, and if it doesn't, throw a specific error message. This change also adds a uses-permission INTERNET entry to espresso-device's manifest. This should help grant the INTERNET permission automatically in development environments where the build system auto-merges manifest permission entries into the target process manifest. PiperOrigin-RevId: 592259503 --- espresso/device/CHANGELOG.md | 2 ++ .../test/espresso/device/AndroidManifest.xml | 5 +++- .../controller/emulator/EmulatorController.kt | 29 +++++++++++++++++-- 3 files changed, 33 insertions(+), 3 deletions(-) diff --git a/espresso/device/CHANGELOG.md b/espresso/device/CHANGELOG.md index 8e6a2b2c4..a87dc1c7f 100644 --- a/espresso/device/CHANGELOG.md +++ b/espresso/device/CHANGELOG.md @@ -6,6 +6,8 @@ **Bug Fixes** +* Add better error messaging when process does not have INTERNET permission + **New Features** **Breaking Changes** diff --git a/espresso/device/java/androidx/test/espresso/device/AndroidManifest.xml b/espresso/device/java/androidx/test/espresso/device/AndroidManifest.xml index 9a579e7b4..100598446 100644 --- a/espresso/device/java/androidx/test/espresso/device/AndroidManifest.xml +++ b/espresso/device/java/androidx/test/espresso/device/AndroidManifest.xml @@ -17,8 +17,11 @@ + + + + android:targetSdkVersion="34" /> \ No newline at end of file diff --git a/espresso/device/java/androidx/test/espresso/device/controller/emulator/EmulatorController.kt b/espresso/device/java/androidx/test/espresso/device/controller/emulator/EmulatorController.kt index 9c8567c49..6bdd94af7 100644 --- a/espresso/device/java/androidx/test/espresso/device/controller/emulator/EmulatorController.kt +++ b/espresso/device/java/androidx/test/espresso/device/controller/emulator/EmulatorController.kt @@ -15,6 +15,9 @@ */ package androidx.test.espresso.device.controller.emulator +import android.Manifest.permission +import android.content.pm.PackageManager.PERMISSION_GRANTED +import android.os.Process import android.util.Log import androidx.annotation.RestrictTo import androidx.annotation.RestrictTo.Scope @@ -25,12 +28,12 @@ import androidx.test.espresso.device.common.getDeviceApiLevel import androidx.test.espresso.device.common.setAccelerometerRotationSetting import androidx.test.espresso.device.controller.DeviceControllerOperationException import androidx.test.espresso.device.controller.DeviceMode +import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation import androidx.test.platform.device.DeviceController import androidx.test.platform.device.UnsupportedDeviceOperationException import com.android.emulator.control.EmulatorControllerGrpc import com.android.emulator.control.ParameterValue import com.android.emulator.control.PhysicalModelValue -import com.android.emulator.control.PhysicalModelValue.PhysicalType import com.android.emulator.control.Posture import com.android.emulator.control.Posture.PostureValue import io.grpc.StatusRuntimeException @@ -72,12 +75,13 @@ constructor( PostureValue.POSTURE_HALF_OPENED } val posture: Posture = Posture.newBuilder().setValue(postureValue).build() + checkInternetPermission() try { emulatorControllerStub.setPosture(posture) } catch (e: StatusRuntimeException) { throw DeviceControllerOperationException( "Failed to set device mode. Please make sure the connected Emulator is foldable, the Android Emulator version" + - " is updated to 33.1.11+, and the controller gRPC service is enabled on the emulator." + + " is updated to 33.1.11+, and the controller gRPC service is enabled on the emulator" + " See https://developer.android.com/studio/preview/features#set_up_your_project_for_the_espresso_device_api for set up instructions.", e ) @@ -98,6 +102,8 @@ constructor( } } + checkInternetPermission() + try { val physicalModelValue: PhysicalModelValue = emulatorControllerStub.getPhysicalModel( @@ -130,4 +136,23 @@ constructor( ) } } + + /** + * Making a connection to the Emulator GRPC requires the INTERNET permission. This method checks + * if the current process has the permission, and if not, throws a meaninful error message. + */ + private fun checkInternetPermission() { + if ( + getInstrumentation() + .getTargetContext() + .checkPermission(permission.INTERNET, Process.myPid(), Process.myUid()) != + PERMISSION_GRANTED + ) { + throw DeviceControllerOperationException( + "The current process does not have the INTERNET permission. Ensure the app-under-test has '' in its AndroidManifest.xml. See " + + "See https://developer.android.com/studio/preview/features#set_up_your_project_for_the_espresso_device_api for set up instructions." + ) + } + } }