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."
+ )
+ }
+ }
}