Skip to content

Commit

Permalink
Add a failure reason to the MediaCaptureFailedEventArgs (#2085)
Browse files Browse the repository at this point in the history
* Add a failure reason to the MediaCaptureFailedEventArgs

* Update Unit Test to validate error message

---------

Co-authored-by: Shaun Lawrence <17139988+bijington@users.noreply.github.com>
Co-authored-by: Brandon Minnick <13558917+brminnick@users.noreply.github.com>
  • Loading branch information
3 people authored Aug 19, 2024
1 parent d0e7574 commit 1bca31f
Show file tree
Hide file tree
Showing 7 changed files with 67 additions and 15 deletions.
9 changes: 8 additions & 1 deletion src/CommunityToolkit.Maui.Camera/CameraManager.android.cs
Original file line number Diff line number Diff line change
Expand Up @@ -276,13 +276,15 @@ public override void OnCaptureSuccess(IImageProxy image)

if (img is null)
{
cameraView.OnMediaCapturedFailed("Unable to obtain Image data.");
return;
}

var buffer = GetFirstPlane(img.GetPlanes())?.Buffer;

if (buffer is null)
{
cameraView.OnMediaCapturedFailed("Unable to obtain a buffer for the image plane.");
image.Close();
return;
}
Expand All @@ -294,6 +296,11 @@ public override void OnCaptureSuccess(IImageProxy image)
var memStream = new MemoryStream(imgData);
cameraView.OnMediaCaptured(memStream);
}
catch (System.Exception ex)
{
cameraView.OnMediaCapturedFailed(ex.Message);
throw;
}
finally
{
image.Close();
Expand All @@ -313,7 +320,7 @@ public override void OnCaptureSuccess(IImageProxy image)
public override void OnError(ImageCaptureException exception)
{
base.OnError(exception);
cameraView.OnMediaCapturedFailed();
cameraView.OnMediaCapturedFailed(exception.Message ?? "An unknown error occurred.");
}
}

Expand Down
14 changes: 12 additions & 2 deletions src/CommunityToolkit.Maui.Camera/CameraManager.macios.cs
Original file line number Diff line number Diff line change
Expand Up @@ -199,10 +199,15 @@ protected virtual async partial ValueTask PlatformTakePicture(CancellationToken
var result = await wrapper.Task.WaitAsync(token);
var data = result.Photo.FileDataRepresentation;

if (result.Error is not null)
{
cameraView.OnMediaCapturedFailed(result.Error.LocalizedFailureReason);
return;
}

if (data is null)
{
// TODO: Pass NSError information
cameraView.OnMediaCapturedFailed();
cameraView.OnMediaCapturedFailed("Unable to retrieve the file data representation from the captured result.");
return;
}

Expand All @@ -214,6 +219,11 @@ protected virtual async partial ValueTask PlatformTakePicture(CancellationToken

cameraView.OnMediaCaptured(new MemoryStream(dataBytes));
}
catch (Exception ex)
{
cameraView.OnMediaCapturedFailed(ex.Message);
throw;
}
finally
{
ArrayPool<byte>.Shared.Return(dataBytes);
Expand Down
14 changes: 11 additions & 3 deletions src/CommunityToolkit.Maui.Camera/CameraManager.windows.cs
Original file line number Diff line number Diff line change
Expand Up @@ -95,11 +95,19 @@ protected virtual async partial ValueTask PlatformTakePicture(CancellationToken

MemoryStream memoryStream = new();

await mediaCapture.CapturePhotoToStreamAsync(ImageEncodingProperties.CreateJpeg(), memoryStream.AsRandomAccessStream());
try
{
await mediaCapture.CapturePhotoToStreamAsync(ImageEncodingProperties.CreateJpeg(), memoryStream.AsRandomAccessStream());

memoryStream.Position = 0;
memoryStream.Position = 0;

cameraView.OnMediaCaptured(memoryStream);
cameraView.OnMediaCaptured(memoryStream);
}
catch (Exception ex)
{
cameraView.OnMediaCapturedFailed(ex.Message);
throw;
}
}

protected virtual void Dispose(bool disposing)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,8 @@ public interface ICameraView : IView, IAsynchronousHandler
/// <summary>
/// Occurs when an image capture fails.
/// </summary>
void OnMediaCapturedFailed();
/// <param name="failureReason">A string containing the reason why the capture attempt failed.</param>
void OnMediaCapturedFailed(string failureReason);

/// <summary>
/// Triggers the camera to capture an image.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,17 @@
/// </summary>
public class MediaCaptureFailedEventArgs : EventArgs
{
/// <summary>
/// Creates a new instance of <see cref="MediaCaptureFailedEventArgs"/>.
/// </summary>
/// <param name="failureReason">A string containing the reason why the capture attempt failed.</param>
public MediaCaptureFailedEventArgs(string failureReason)
{
FailureReason = failureReason;
}

/// <summary>
/// Gets the reason why the capture attempt failed.
/// </summary>
public string FailureReason { get; }
}
4 changes: 2 additions & 2 deletions src/CommunityToolkit.Maui.Camera/Views/CameraView.shared.cs
Original file line number Diff line number Diff line change
Expand Up @@ -201,9 +201,9 @@ public void OnMediaCaptured(Stream imageData)
}

/// <inheritdoc cref="ICameraView.OnMediaCapturedFailed"/>
public void OnMediaCapturedFailed()
public void OnMediaCapturedFailed(string failureReason)
{
weakEventManager.HandleEvent(this, new MediaCaptureFailedEventArgs(), nameof(MediaCaptureFailed));
weakEventManager.HandleEvent(this, new MediaCaptureFailedEventArgs(failureReason), nameof(MediaCaptureFailed));
}

/// <inheritdoc cref="ICameraView.GetAvailableCameras"/>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -61,14 +61,27 @@ public void OnMediaCaptured_RaisesMediaCapturedEvent()
Assert.True(eventRaised);
}

[Fact]
public void OnMediaCapturedFailed_RaisesMediaCaptureFailedEvent()
[Fact(Timeout = (int)TestDuration.Short)]
public async Task OnMediaCapturedFailed_RaisesMediaCaptureFailedEvent()
{
bool eventRaised = false;
cameraView.MediaCaptureFailed += (sender, args) => eventRaised = true;
const string failureMessage = "Proof that this test passes";

bool wasEventRaised = false;
var mediaCaptureFailedTcs = new TaskCompletionSource<MediaCaptureFailedEventArgs>();
cameraView.MediaCaptureFailed += HandleMediaCaptureFailed;

cameraView.OnMediaCapturedFailed();
cameraView.OnMediaCapturedFailed(failureMessage);

Assert.True(eventRaised);
var mediaCaptureFailedEventArgs = await mediaCaptureFailedTcs.Task;

Assert.True(wasEventRaised);
Assert.Equal(failureMessage, mediaCaptureFailedEventArgs.FailureReason);

void HandleMediaCaptureFailed(object? sender, MediaCaptureFailedEventArgs e)
{
cameraView.MediaCaptureFailed -= HandleMediaCaptureFailed;
wasEventRaised = true;
mediaCaptureFailedTcs.SetResult(e);
}
}
}

0 comments on commit 1bca31f

Please sign in to comment.