Aperture: Don't start app if no cameras are found on the device
Change-Id: Ia9bce63c36592fc3d602749f1e27ab941ebe0e93
diff --git a/app/src/main/java/org/lineageos/aperture/CameraActivity.kt b/app/src/main/java/org/lineageos/aperture/CameraActivity.kt
index 5f16937..a08b766 100644
--- a/app/src/main/java/org/lineageos/aperture/CameraActivity.kt
+++ b/app/src/main/java/org/lineageos/aperture/CameraActivity.kt
@@ -614,7 +614,12 @@
}
// Select a camera
- camera = cameraManager.getCameraOfFacingOrFirstAvailable(initialCameraFacing, cameraMode)
+ camera = cameraManager.getCameraOfFacingOrFirstAvailable(
+ initialCameraFacing, cameraMode
+ ) ?: run {
+ noCamera()
+ return
+ }
// Setup window insets
ViewCompat.setOnApplyWindowInsetsListener(mainLayout) { _, windowInsets ->
@@ -1507,6 +1512,9 @@
)
else -> camera
+ } ?: run {
+ noCamera()
+ return
}
// If the current camera doesn't support the selected camera mode
@@ -1514,7 +1522,10 @@
if (!camera.supportsCameraMode(cameraMode)) {
camera = cameraManager.getCameraOfFacingOrFirstAvailable(
camera.cameraFacing, cameraMode
- )
+ ) ?: run {
+ noCamera()
+ return
+ }
}
// Fallback to ExtensionMode.NONE if necessary
@@ -1882,7 +1893,11 @@
(flipCameraButton.drawable as AnimatedVectorDrawable).start()
- camera = cameraManager.getNextCamera(camera, cameraMode)
+ camera = cameraManager.getNextCamera(camera, cameraMode) ?: run {
+ noCamera()
+ return
+ }
+
sharedPreferences.lastCameraFacing = camera.cameraFacing
bindCameraUseCases()
@@ -2448,6 +2463,16 @@
}
/**
+ * Show a toast warning the user that no camera is available and close the activity.
+ */
+ private fun noCamera() {
+ Toast.makeText(
+ this, R.string.error_no_cameras_available, Toast.LENGTH_LONG
+ ).show()
+ finish()
+ }
+
+ /**
* Zoom out by a power of 2.
*/
private fun zoomOut() {
diff --git a/app/src/main/java/org/lineageos/aperture/camera/CameraManager.kt b/app/src/main/java/org/lineageos/aperture/camera/CameraManager.kt
index f394d28..f07db70 100644
--- a/app/src/main/java/org/lineageos/aperture/camera/CameraManager.kt
+++ b/app/src/main/java/org/lineageos/aperture/camera/CameraManager.kt
@@ -179,9 +179,15 @@
}
}
+ /**
+ * Get a suitable [Camera] for the provided [CameraFacing] and [CameraMode].
+ * @param cameraFacing The requested [CameraFacing]
+ * @param cameraMode The requested [CameraMode]
+ * @return A [Camera] that is compatible with the provided configuration or null
+ */
fun getCameraOfFacingOrFirstAvailable(
cameraFacing: CameraFacing, cameraMode: CameraMode
- ): Camera {
+ ): Camera? {
val camera = when (cameraFacing) {
CameraFacing.BACK -> mainBackCamera
CameraFacing.FRONT -> mainFrontCamera
@@ -190,17 +196,23 @@
}
return camera?.let {
if (cameraMode == CameraMode.VIDEO && !it.supportsVideoRecording) {
- availableCamerasSupportingVideoRecording.first()
+ availableCamerasSupportingVideoRecording.firstOrNull()
} else {
it
}
} ?: when (cameraMode) {
- CameraMode.VIDEO -> availableCamerasSupportingVideoRecording.first()
- else -> availableCameras.first()
+ CameraMode.VIDEO -> availableCamerasSupportingVideoRecording.firstOrNull()
+ else -> availableCameras.firstOrNull()
}
}
- fun getNextCamera(camera: Camera, cameraMode: CameraMode): Camera {
+ /**
+ * Return the next camera, used for flip camera.
+ * @param camera The current [Camera] used
+ * @param cameraMode The current [CameraMode]
+ * @return The next camera, may return null if all the cameras disappeared
+ */
+ fun getNextCamera(camera: Camera, cameraMode: CameraMode): Camera? {
val cameras = when (cameraMode) {
CameraMode.VIDEO -> availableCamerasSupportingVideoRecording
else -> availableCameras
@@ -218,7 +230,7 @@
) + 1
return if (newCameraIndex >= cameras.size) {
- cameras.first()
+ cameras.firstOrNull()
} else {
cameras[newCameraIndex]
}
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index ca98ce5..a5ba743 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -165,6 +165,7 @@
<string name="error_do_not_disturb_mode_enabled">Do Not Disturb mode is enabled. Disable it and reopen the app.</string>
<string name="error_unknown_recoverable">A recoverable unknown error has been found. Please report this to the developers.</string>
<string name="error_unknown_critical">A critical unknown error has been found. Please report this to the developers.</string>
+ <string name="error_no_cameras_available">No cameras were found on the device, cannot start the app.</string>
<!-- Gesture actions -->
<string name="gesture_action_shutter">Shutter</string>