AndroidX icon indicating copy to clipboard operation
AndroidX copied to clipboard

Xamarin.AndroidX.CameraExtensions: ProcessCameraProvider must implement ICameraProvider

Open VladislavAntonyuk opened this issue 6 months ago • 9 comments

Android framework version

net9.0-android

Affected platform version

.NET 9

Description

ProcessCameraProvider must implement ICameraProvider: https://developer.android.com/reference/androidx/camera/lifecycle/ProcessCameraProvider

Steps to Reproduce

async Task<CameraSelector> EnableModes(CameraInfo selectedCamera)
	{
		var cameraFutureCts = new TaskCompletionSource();
		var cameraSelector = selectedCamera.CameraSelector ?? throw new CameraException($"Unable to retrieve {nameof(CameraSelector)}");
		var cameraProviderFuture = ProcessCameraProvider.GetInstance(context) ?? throw new CameraException($"Unable to retrieve {nameof(ProcessCameraProvider)}");
		cameraProviderFuture.AddListener(new Runnable(() =>
		{
			var cameraProviderInstance = cameraProviderFuture.Get();
			if (cameraProviderInstance is not AndroidX.Camera.Core.ICameraProvider androidCameraProvider) // this is true, but must be false
			{
				cameraFutureCts.SetResult();
				return;
			}

			var extensionsManagerFuture = ExtensionsManager.GetInstanceAsync(context, androidCameraProvider);
			extensionsManagerFuture.AddListener(new Runnable(() =>
			{
				var extensionsManager = (ExtensionsManager)extensionsManagerFuture.Get()!;
				if (extensionsManager.IsExtensionAvailable(cameraSelector, extensionMode))
				{
					cameraSelector = extensionsManager.GetExtensionEnabledCameraSelector(cameraSelector, extensionMode);
				}

				cameraFutureCts.SetResult();
			}), ContextCompat.GetMainExecutor(context));
		}), ContextCompat.GetMainExecutor(context));

		await cameraFutureCts.Task;
		return cameraSelector;
	}

Did you find any workaround?

No response

Relevant log output


VladislavAntonyuk avatar Jun 26 '25 13:06 VladislavAntonyuk

So, are you saying the ICameraProvider type is missing?

Can you share what NuGet it is from and what namespace it's expected to be in? Thanks!

jonathanpeppers avatar Jun 26 '25 16:06 jonathanpeppers

Thank you for your fast reply. Both types are exist. The problem is in inheritance:

Currently:

ProcessCameraProvider : Java.Object

Should be:

ProcessCameraProvider : Java.Object, ICameraProvider.

So the problem appears when you try to use Xamarin.CameraX.CameraExtensions.

ExtensionsManager.GetInstanceAsync second parameter is ICameraProvider. According to the android docs it must be ProcessCameraProvider.

VladislavAntonyuk avatar Jun 26 '25 17:06 VladislavAntonyuk

Thank you for your fast reply. Both types are exist. The problem is in inheritance:

Currently:

ProcessCameraProvider : Java.Object

Should be:

ProcessCameraProvider : Java.Object, ICameraProvider.

So the problem appears when you try to use Xamarin.CameraX.CameraExtensions.

ExtensionsManager.GetInstanceAsync second parameter is ICameraProvider. According to the android docs it must be ProcessCameraProvider.

VladislavAntonyuk avatar Jun 26 '25 17:06 VladislavAntonyuk

Did this problem start happening with the recent update:

  • https://www.nuget.org/packages/Xamarin.AndroidX.Camera.Extensions/1.4.2.2

Or is the problem also there for older versions?

jonathanpeppers avatar Jun 26 '25 18:06 jonathanpeppers

It is the problem of the previous versions as well.

VladislavAntonyuk avatar Jun 26 '25 18:06 VladislavAntonyuk

There is likely a build warning in the current binding; that's preventing this from being bound to C# as expected.

jonathanpeppers avatar Jun 26 '25 18:06 jonathanpeppers

You can reproduce the issue from this PR in EnableModes method: https://github.com/CommunityToolkit/Maui/pull/2710/files

I would like to remove this check and pass cameraProvider directly to ExtensionManager:

if (cameraProviderInstance is not AndroidX.Camera.Core.ICameraProvider androidCameraProvider) // this is true, but must be false
			{
				cameraFutureCts.SetResult();
				return;
			}

VladislavAntonyuk avatar Jun 27 '25 00:06 VladislavAntonyuk

Morn

this might be the issue

<remove-node
        path="/api/package[@name='androidx.camera.extensions.internal.sessionprocessor']"
        />

https://github.com/dotnet/android-libraries/blob/main/source/androidx.camera/camera-extensions/Transforms/Metadata.xml#L15C5-L17C11

It is internal, but who knows. Needs deeper investigation.

moljac avatar Jul 07 '25 13:07 moljac

@jonathanpeppers , @moljac I have found a workaround using JavaCast:

var cameraProviderInstance = cameraProviderFuture.Get().JavaCast<AndroidX.Camera.Core.ICameraProvider>();

VladislavAntonyuk avatar Jul 16 '25 09:07 VladislavAntonyuk