diff --git a/samples/CommunityToolkit.Maui.Sample/Pages/Views/CameraView/CameraViewPage.xaml b/samples/CommunityToolkit.Maui.Sample/Pages/Views/CameraView/CameraViewPage.xaml index d90bcd224..ed5edd3a9 100644 --- a/samples/CommunityToolkit.Maui.Sample/Pages/Views/CameraView/CameraViewPage.xaml +++ b/samples/CommunityToolkit.Maui.Sample/Pages/Views/CameraView/CameraViewPage.xaml @@ -64,7 +64,7 @@ PlatformStopVideoRecording(CancellationToken token) @@ -415,7 +434,9 @@ async Task EnableModes(CameraInfo selectedCamera, CancellationTo return; } - var extensionsManagerFuture = ExtensionsManager.GetInstanceAsync(context, cameraProviderInstance); + var extensionsManagerFuture = ExtensionsManager.GetInstanceAsync(context, cameraProviderInstance) + ?? throw new InvalidOperationException("Unable to get listenable future for camera provider");; + extensionsManagerFuture.AddListener(new Runnable(() => { var extensionsManager = (ExtensionsManager?)extensionsManagerFuture.Get(); @@ -455,10 +476,10 @@ void SetImageCaptureTargetRotation(int rotation) sealed class ImageCallBack(ICameraView cameraView) : ImageCapture.OnImageCapturedCallback { - public override void OnCaptureSuccess(IImageProxy image) + public override void OnCaptureSuccess(IImageProxy? image) { base.OnCaptureSuccess(image); - var img = image.Image; + var img = image?.Image; if (img is null) { @@ -471,7 +492,7 @@ public override void OnCaptureSuccess(IImageProxy image) if (buffer is null) { cameraView.OnMediaCapturedFailed("Unable to obtain a buffer for the image plane."); - image.Close(); + image?.Close(); return; } @@ -489,7 +510,7 @@ public override void OnCaptureSuccess(IImageProxy image) } finally { - image.Close(); + image?.Close(); } static Image.Plane? GetFirstPlane(Image.Plane[]? planes) @@ -503,10 +524,10 @@ public override void OnCaptureSuccess(IImageProxy image) } } - public override void OnError(ImageCaptureException exception) + public override void OnError(ImageCaptureException? exception) { base.OnError(exception); - cameraView.OnMediaCapturedFailed(exception.Message ?? "An unknown error occurred."); + cameraView.OnMediaCapturedFailed(exception?.Message ?? "An unknown error occurred."); } } @@ -514,13 +535,15 @@ sealed class ResolutionFilter(Android.Util.Size size) : Object, IResolutionFilte { public Android.Util.Size TargetSize { get; set; } = size; - public IList Filter(IList supportedSizes, int rotationDegrees) + public IList Filter(IList? supportedSizes, int rotationDegrees) { - var filteredList = supportedSizes + var filteredList = supportedSizes? .Where(size => size.Width <= TargetSize.Width && size.Height <= TargetSize.Height) .OrderByDescending(size => size.Width * size.Height).ToList(); - return filteredList.Count is 0 ? supportedSizes : filteredList; + return filteredList is null || filteredList.Count is 0 + ? supportedSizes ?? [] + : filteredList; } } diff --git a/src/CommunityToolkit.Maui.Camera/CommunityToolkit.Maui.Camera.csproj b/src/CommunityToolkit.Maui.Camera/CommunityToolkit.Maui.Camera.csproj index 40961c96c..8de19b790 100644 --- a/src/CommunityToolkit.Maui.Camera/CommunityToolkit.Maui.Camera.csproj +++ b/src/CommunityToolkit.Maui.Camera/CommunityToolkit.Maui.Camera.csproj @@ -52,10 +52,12 @@ - - - + + + + + diff --git a/src/CommunityToolkit.Maui.Camera/Providers/CameraProvider.android.cs b/src/CommunityToolkit.Maui.Camera/Providers/CameraProvider.android.cs index f908040cd..c5a45ca1f 100644 --- a/src/CommunityToolkit.Maui.Camera/Providers/CameraProvider.android.cs +++ b/src/CommunityToolkit.Maui.Camera/Providers/CameraProvider.android.cs @@ -30,6 +30,14 @@ public async partial ValueTask RefreshAvailableCameras(CancellationToken token) foreach (var cameraXInfo in processCameraProvider.AvailableCameraInfos) { var camera2Info = Camera2CameraInfo.From(cameraXInfo); + if (camera2Info is null) + { + // `Camera2CameraInfo.From` should never return `null` + // According to the Android Docs, `Camera2CameraInfo.From` returns a `NonNull` + // `Camera2CameraInfo.From` returning a nullable `Camera2CameraInfo` object is likely a C# binding mistake + // https://developer.android.com/reference/androidx/camera/camera2/interop/Camera2CameraInfo + continue; + } var (name, position) = cameraXInfo.LensFacing switch { @@ -68,13 +76,13 @@ public async partial ValueTask RefreshAvailableCameras(CancellationToken token) } var cameraInfo = new CameraInfo(name, - camera2Info.CameraId, + camera2Info.CameraId ?? throw new InvalidOperationException("Unable to retrieve Camera ID"), position, cameraXInfo.HasFlashUnit, - (cameraXInfo.ZoomState.Value as IZoomState)?.MinZoomRatio ?? 1.0f, - (cameraXInfo.ZoomState.Value as IZoomState)?.MaxZoomRatio ?? 1.0f, + (cameraXInfo.ZoomState?.Value as IZoomState)?.MinZoomRatio ?? 1.0f, + (cameraXInfo.ZoomState?.Value as IZoomState)?.MaxZoomRatio ?? 1.0f, supportedResolutions, - cameraXInfo.CameraSelector); + cameraXInfo.CameraSelector ?? throw new InvalidOperationException($"Unable to retrieve {nameof(ICameraInfo.CameraSelector)}")); availableCameras.Add(cameraInfo); }