Skip to content

Commit 0f85de2

Browse files
Incorporate Pedro's Review Comments
1 parent e68d299 commit 0f85de2

9 files changed

Lines changed: 65 additions & 63 deletions

src/CommunityToolkit.Maui.Camera/CameraManager.android.cs

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ namespace CommunityToolkit.Maui.Core;
1919
[SupportedOSPlatform("android21.0")]
2020
partial class CameraManager
2121
{
22-
readonly Context context = mauiContext.Context ?? throw new CameraViewException($"Unable to retrieve {nameof(Context)}");
22+
readonly Context context = mauiContext.Context ?? throw new CameraException($"Unable to retrieve {nameof(Context)}");
2323

2424
NativePlatformCameraPreviewView? previewView;
2525
IExecutorService? cameraExecutor;
@@ -47,7 +47,7 @@ public NativePlatformCameraPreviewView CreatePlatformView()
4747
{
4848
previewView.SetScaleType(NativePlatformCameraPreviewView.ScaleType.FitCenter);
4949
}
50-
cameraExecutor = Executors.NewSingleThreadExecutor() ?? throw new CameraViewException($"Unable to retrieve {nameof(IExecutorService)}");
50+
cameraExecutor = Executors.NewSingleThreadExecutor() ?? throw new CameraException($"Unable to retrieve {nameof(IExecutorService)}");
5151

5252
return previewView;
5353
}
@@ -64,12 +64,7 @@ public partial void UpdateFlashMode(CameraFlashMode flashMode)
6464

6565
public partial void UpdateZoom(float zoomLevel)
6666
{
67-
if (cameraControl is null)
68-
{
69-
return;
70-
}
71-
72-
cameraControl.SetZoomRatio(zoomLevel);
67+
cameraControl?.SetZoomRatio(zoomLevel);
7368
}
7469

7570
public async partial ValueTask UpdateCaptureResolution(Size resolution, CancellationToken token)
@@ -155,15 +150,15 @@ protected virtual async partial Task PlatformConnectCamera(CancellationToken tok
155150

156151
cameraProviderFuture.AddListener(new Runnable(async () =>
157152
{
158-
processCameraProvider = (ProcessCameraProvider)(cameraProviderFuture.Get() ?? throw new CameraViewException($"Unable to retrieve {nameof(ProcessCameraProvider)}"));
153+
processCameraProvider = (ProcessCameraProvider)(cameraProviderFuture.Get() ?? throw new CameraException($"Unable to retrieve {nameof(ProcessCameraProvider)}"));
159154

160155
if (cameraProvider.AvailableCameras is null)
161156
{
162157
await cameraProvider.RefreshAvailableCameras(token);
163158

164-
if (cameraProvider.AvailableCameras is null || cameraProvider.AvailableCameras.Count < 1)
159+
if (cameraProvider.AvailableCameras is null)
165160
{
166-
throw new CameraViewException("No camera available on device");
161+
throw new CameraException("Unable to refresh available cameras");
167162
}
168163
}
169164

@@ -173,7 +168,7 @@ protected virtual async partial Task PlatformConnectCamera(CancellationToken tok
173168

174169
}), ContextCompat.GetMainExecutor(context));
175170

176-
await cameraProviderTCS.Task;
171+
await cameraProviderTCS.Task.WaitAsync(token);
177172
}
178173

179174
protected async Task StartUseCase(CancellationToken token)
@@ -213,18 +208,18 @@ protected virtual async partial Task PlatformStartCameraPreview(CancellationToke
213208
await cameraProvider.RefreshAvailableCameras(token);
214209
}
215210

216-
cameraView.SelectedCamera = cameraProvider.AvailableCameras?.FirstOrDefault() ?? throw new CameraViewException("No camera available on device");
211+
cameraView.SelectedCamera = cameraProvider.AvailableCameras?.FirstOrDefault() ?? throw new CameraException("No camera available on device");
217212
}
218213

219-
var cameraSelector = cameraView.SelectedCamera.CameraSelector ?? throw new CameraViewException($"Unable to retrieve {nameof(CameraSelector)}");
214+
var cameraSelector = cameraView.SelectedCamera.CameraSelector ?? throw new CameraException($"Unable to retrieve {nameof(CameraSelector)}");
220215

221216
var owner = (ILifecycleOwner)context;
222217
camera = processCameraProvider.BindToLifecycle(owner, cameraSelector, cameraPreview, imageCapture);
223218

224219
cameraControl = camera.CameraControl;
225220

226221
//start the camera with AutoFocus
227-
MeteringPoint point = previewView.MeteringPointFactory.CreatePoint(previewView.Width / 2, previewView.Height / 2, 0.1F);
222+
MeteringPoint point = previewView.MeteringPointFactory.CreatePoint(previewView.Width / 2.0f, previewView.Height / 2.0f, 0.1f);
228223
FocusMeteringAction action = new FocusMeteringAction.Builder(point)
229224
.DisableAutoCancel()
230225
.Build();

src/CommunityToolkit.Maui.Camera/CameraManager.macios.cs

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
using CoreMedia;
88
using Foundation;
99
using UIKit;
10-
using static UIKit.UIGestureRecognizer;
1110

1211
namespace CommunityToolkit.Maui.Core;
1312

@@ -64,7 +63,7 @@ public partial void UpdateZoom(float zoomLevel)
6463
captureDevice.LockForConfiguration(out NSError error);
6564
if (error is not null)
6665
{
67-
System.Diagnostics.Trace.WriteLine(error);
66+
Trace.WriteLine(error);
6867
return;
6968
}
7069

@@ -89,21 +88,21 @@ public async partial ValueTask UpdateCaptureResolution(Size resolution, Cancella
8988
if (cameraView.SelectedCamera is null)
9089
{
9190
await cameraProvider.RefreshAvailableCameras(token);
92-
cameraView.SelectedCamera = cameraProvider.AvailableCameras?.FirstOrDefault() ?? throw new CameraViewException("No camera available on device");
91+
cameraView.SelectedCamera = cameraProvider.AvailableCameras?.FirstOrDefault() ?? throw new CameraException("No camera available on device");
9392
}
9493

9594
var filteredFormatList = cameraView.SelectedCamera.SupportedFormats.Where(f =>
9695
{
9796
var d = ((CMVideoFormatDescription)f.FormatDescription).Dimensions;
9897
return d.Width <= resolution.Width && d.Height <= resolution.Height;
99-
});
98+
}).ToList();
10099

101100
filteredFormatList = (filteredFormatList.Any() ? filteredFormatList : cameraView.SelectedCamera.SupportedFormats)
102101
.OrderByDescending(f =>
103102
{
104103
var d = ((CMVideoFormatDescription)f.FormatDescription).Dimensions;
105104
return d.Width * d.Height;
106-
});
105+
}).ToList();
107106

108107
if (filteredFormatList.Any())
109108
{
@@ -119,9 +118,9 @@ protected virtual async partial Task PlatformConnectCamera(CancellationToken tok
119118
{
120119
await cameraProvider.RefreshAvailableCameras(token);
121120

122-
if (cameraProvider.AvailableCameras is null || cameraProvider.AvailableCameras.Count < 1)
121+
if (cameraProvider.AvailableCameras is null)
123122
{
124-
throw new CameraViewException("No camera available on device");
123+
throw new CameraException("Unable to refresh cameras");
125124
}
126125
}
127126

@@ -146,11 +145,11 @@ protected virtual async partial Task PlatformStartCameraPreview(CancellationToke
146145
if (cameraView.SelectedCamera is null)
147146
{
148147
await cameraProvider.RefreshAvailableCameras(token);
149-
cameraView.SelectedCamera = cameraProvider.AvailableCameras?.FirstOrDefault() ?? throw new CameraViewException("No camera available on device");
148+
cameraView.SelectedCamera = cameraProvider.AvailableCameras?.FirstOrDefault() ?? throw new CameraException("No camera available on device");
150149
}
151150

152-
captureDevice = cameraView.SelectedCamera.CaptureDevice ?? throw new CameraViewException($"No Camera found");
153-
captureInput = new AVCaptureDeviceInput(captureDevice, out var err);
151+
captureDevice = cameraView.SelectedCamera.CaptureDevice ?? throw new CameraException($"No Camera found");
152+
captureInput = new AVCaptureDeviceInput(captureDevice, out _);
154153
captureSession.AddInput(captureInput);
155154

156155
if (photoOutput is null)

src/CommunityToolkit.Maui.Camera/CameraManager.windows.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -117,9 +117,9 @@ protected virtual async partial Task PlatformConnectCamera(CancellationToken tok
117117
{
118118
await cameraProvider.RefreshAvailableCameras(token);
119119

120-
if (cameraProvider.AvailableCameras is null || cameraProvider.AvailableCameras.Count < 1)
120+
if (cameraProvider.AvailableCameras is null)
121121
{
122-
throw new CameraViewException("No camera available on device");
122+
throw new CameraException("Unable to refresh cameras");
123123
}
124124
}
125125

src/CommunityToolkit.Maui.Camera/Handlers/CameraViewHandler.shared.cs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ public class CameraViewHandler : ViewHandler<ICameraView, NativePlatformCameraPr
3636
[nameof(ICameraView.StopCameraPreview)] = MapStopCameraPreview
3737
};
3838

39-
readonly ICameraProvider cameraProvider = IPlatformApplication.Current?.Services.GetRequiredService<ICameraProvider>() ?? throw new CameraViewException($"{nameof(CameraProvider)} not found");
39+
readonly ICameraProvider cameraProvider = IPlatformApplication.Current?.Services.GetRequiredService<ICameraProvider>() ?? throw new CameraException($"{nameof(CameraProvider)} not found");
4040

4141
CameraManager? cameraManager;
4242

@@ -90,9 +90,11 @@ protected override async void ConnectHandler(NativePlatformCameraPreviewView pla
9090
{
9191
base.ConnectHandler(platformView);
9292

93+
var cancellationTokenSource = new CancellationTokenSource(TimeSpan.FromSeconds(3));
94+
9395
await (cameraManager?.ArePermissionsGranted() ?? Task.CompletedTask);
94-
await (cameraManager?.ConnectCamera(CancellationToken.None) ?? Task.CompletedTask);
95-
await cameraProvider.RefreshAvailableCameras(CancellationToken.None);
96+
await (cameraManager?.ConnectCamera(cancellationTokenSource.Token) ?? Task.CompletedTask);
97+
await cameraProvider.RefreshAvailableCameras(cancellationTokenSource.Token);
9698
}
9799

98100
/// <inheritdoc/>

src/CommunityToolkit.Maui.Camera/Primitives/CameraViewException.shared.cs renamed to src/CommunityToolkit.Maui.Camera/Primitives/CameraException.shared.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ namespace CommunityToolkit.Maui.Core;
55
/// experiences a critical error.
66
/// </summary>
77
/// <param name="message">The specific error message indicating what error has occurred.</param>
8-
public class CameraViewException(string message) : Exception(message)
8+
public class CameraException(string message) : Exception(message)
99
{
1010

1111
}

src/CommunityToolkit.Maui.Camera/Primitives/CameraViewDefaults.cs renamed to src/CommunityToolkit.Maui.Camera/Primitives/CameraViewDefaults.shared.cs

File renamed without changes.

src/CommunityToolkit.Maui.Camera/Providers/CameraProvider.android.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ public async partial ValueTask RefreshAvailableCameras(CancellationToken token)
2525

2626
cameraProviderFuture.AddListener(new Runnable(() =>
2727
{
28-
var processCameraProvider = (ProcessCameraProvider)(cameraProviderFuture.Get() ?? throw new CameraViewException($"Unable to retrieve {nameof(ProcessCameraProvider)}"));
28+
var processCameraProvider = (ProcessCameraProvider)(cameraProviderFuture.Get() ?? throw new CameraException($"Unable to retrieve {nameof(ProcessCameraProvider)}"));
2929
var availableCameras = new List<CameraInfo>();
3030

3131
foreach (var cameraXInfo in processCameraProvider.AvailableCameraInfos)
@@ -86,6 +86,6 @@ public async partial ValueTask RefreshAvailableCameras(CancellationToken token)
8686

8787
}), ContextCompat.GetMainExecutor(context));
8888

89-
await cameraFutureTCS.Task;
89+
await cameraFutureTCS.Task.WaitAsync(token);
9090
}
9191
}

src/CommunityToolkit.Maui.Camera/Providers/CameraProvider.macios.cs

Lines changed: 34 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -8,36 +8,11 @@ namespace CommunityToolkit.Maui.Core;
88

99
partial class CameraProvider
1010
{
11+
static readonly AVCaptureDeviceType[] captureDevices = InitializeCaptureDevices();
12+
1113
public partial ValueTask RefreshAvailableCameras(CancellationToken token)
1214
{
13-
AVCaptureDeviceType[] deviceTypes =
14-
[
15-
AVCaptureDeviceType.BuiltInWideAngleCamera,
16-
AVCaptureDeviceType.BuiltInTelephotoCamera,
17-
AVCaptureDeviceType.BuiltInDualCamera
18-
];
19-
20-
if (UIDevice.CurrentDevice.CheckSystemVersion(11, 1))
21-
{
22-
deviceTypes = [.. deviceTypes,
23-
AVCaptureDeviceType.BuiltInTrueDepthCamera];
24-
}
25-
26-
if (UIDevice.CurrentDevice.CheckSystemVersion(13, 0))
27-
{
28-
deviceTypes = [.. deviceTypes,
29-
AVCaptureDeviceType.BuiltInUltraWideCamera,
30-
AVCaptureDeviceType.BuiltInTripleCamera,
31-
AVCaptureDeviceType.BuiltInDualWideCamera];
32-
}
33-
34-
if (UIDevice.CurrentDevice.CheckSystemVersion(15, 4))
35-
{
36-
deviceTypes = [.. deviceTypes,
37-
AVCaptureDeviceType.BuiltInLiDarDepthCamera];
38-
}
39-
40-
var discoverySession = AVCaptureDeviceDiscoverySession.Create(deviceTypes, AVMediaTypes.Video, AVCaptureDevicePosition.Unspecified);
15+
var discoverySession = AVCaptureDeviceDiscoverySession.Create(captureDevices, AVMediaTypes.Video, AVCaptureDevicePosition.Unspecified);
4116
var availableCameras = new List<CameraInfo>();
4217

4318
foreach (var device in discoverySession.Devices)
@@ -90,4 +65,35 @@ public partial ValueTask RefreshAvailableCameras(CancellationToken token)
9065
return ValueTask.CompletedTask;
9166
}
9267

68+
static AVCaptureDeviceType[] InitializeCaptureDevices()
69+
{
70+
AVCaptureDeviceType[] deviceTypes =
71+
[
72+
AVCaptureDeviceType.BuiltInWideAngleCamera,
73+
AVCaptureDeviceType.BuiltInTelephotoCamera,
74+
AVCaptureDeviceType.BuiltInDualCamera
75+
];
76+
77+
if (UIDevice.CurrentDevice.CheckSystemVersion(11, 1))
78+
{
79+
deviceTypes = [.. deviceTypes,
80+
AVCaptureDeviceType.BuiltInTrueDepthCamera];
81+
}
82+
83+
if (UIDevice.CurrentDevice.CheckSystemVersion(13, 0))
84+
{
85+
deviceTypes = [.. deviceTypes,
86+
AVCaptureDeviceType.BuiltInUltraWideCamera,
87+
AVCaptureDeviceType.BuiltInTripleCamera,
88+
AVCaptureDeviceType.BuiltInDualWideCamera];
89+
}
90+
91+
if (UIDevice.CurrentDevice.CheckSystemVersion(15, 4))
92+
{
93+
deviceTypes = [.. deviceTypes,
94+
AVCaptureDeviceType.BuiltInLiDarDepthCamera];
95+
}
96+
97+
return deviceTypes;
98+
}
9399
}

src/CommunityToolkit.Maui.Camera/Views/CameraView.shared.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,7 @@ public bool IsTorchOn
174174
set => SetValue(IsTorchOnProperty, value);
175175
}
176176

177-
static ICameraProvider CameraProvider => IPlatformApplication.Current?.Services.GetRequiredService<ICameraProvider>() ?? throw new CameraViewException("Unable to retrieve CameraProvider");
177+
static ICameraProvider CameraProvider => IPlatformApplication.Current?.Services.GetRequiredService<ICameraProvider>() ?? throw new CameraException("Unable to retrieve CameraProvider");
178178

179179
[EditorBrowsable(EditorBrowsableState.Never)]
180180
bool ICameraView.IsAvailable
@@ -214,7 +214,7 @@ public async ValueTask<IReadOnlyList<CameraInfo>> GetAvailableCameras(Cancellati
214214

215215
if (CameraProvider.AvailableCameras is null)
216216
{
217-
throw new CameraViewException("No cameras found on device");
217+
throw new CameraException("Unable to refresh available cameras");
218218
}
219219
}
220220

0 commit comments

Comments
 (0)