Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Missing method HardwareBuffer.Create(...) #8703

Closed
Steph55 opened this issue Feb 7, 2024 · 2 comments · Fixed by #8707
Closed

Missing method HardwareBuffer.Create(...) #8703

Steph55 opened this issue Feb 7, 2024 · 2 comments · Fixed by #8707
Assignees
Labels
Area: Mono.Android Issues with the Android API binding (Mono.Android.dll). bug Component does not function as intended.
Milestone

Comments

@Steph55
Copy link

Steph55 commented Feb 7, 2024

Android application type

.NET Android (net7.0-android, net8.0-android, etc.)

Affected platform version

VS 2022

Description

I have been trying for a while to figure out how to create an Android HardwareBuffer with Xamarin. With Android, it is easy, we simply need to call HardwareBuffer.Create(), but I cannot find the equivalent in Xamarin. How should I proceed or is this function missing?

Steps to Reproduce

Create a Net 8 Xamarin project using Android.Hardware. Then try to figure out how to call HardwareBuffer.Create()

Did you find any workaround?

No

Relevant log output

No response

@Steph55 Steph55 added the needs-triage Issues that need to be assigned. label Feb 7, 2024
@jonpryor
Copy link
Member

jonpryor commented Feb 7, 2024

@jpobst: looking at the build log for Mono.Android.csproj, I see:

bj/Debug/net9.0/android-34/mcw/api-34.xml(32327,10): warning BG8800: Unknown parameter type 'Android.Hardware.HardwareBufferUsage' for member 'Android.Hardware.HardwareBuffer.Create (int, int, Android.Hardware.HardwareBufferFormat, int, Android.Hardware.HardwareBufferUsage)'

Looks like a "bad enumification" prevented HardwareBuffer.create() from being bound. :-/

@jpobst jpobst added Area: Mono.Android Issues with the Android API binding (Mono.Android.dll). and removed needs-triage Issues that need to be assigned. labels Feb 7, 2024
@jpobst
Copy link
Contributor

jpobst commented Feb 7, 2024

This will be fixed by #8707, however we cannot add new API to the shipped "contract" net8.0-android. Thus, this will not be available until .NET 9.

In the meantime, you should be able to copy the binding for HardwareBuffer.Create (...) into your project to be able to use it:

static readonly JniPeerMembers _members = new XAPeerMembers ("android/hardware/HardwareBuffer", typeof (HardwareBuffer));

public static unsafe Android.Hardware.HardwareBuffer Create (int width, int height, Android.Hardware.HardwareBufferFormat format, int layers, long usage)
{
	const string __id = "create.(IIIIJ)Landroid/hardware/HardwareBuffer;";
	try {
		JniArgumentValue* __args = stackalloc JniArgumentValue [5];
		__args [0] = new JniArgumentValue (width);
		__args [1] = new JniArgumentValue (height);
		__args [2] = new JniArgumentValue ((int) format);
		__args [3] = new JniArgumentValue (layers);
		__args [4] = new JniArgumentValue (usage);
		var __rm = _members.StaticMethods.InvokeObjectMethod (__id, __args);
		return global::Java.Lang.Object.GetObject<Android.Hardware.HardwareBuffer> (__rm.Handle, JniHandleOwnership.TransferLocalRef)!;
	} finally {
	}
}

@jpobst jpobst added this to the .NET 9 milestone Feb 7, 2024
@jpobst jpobst changed the title Where is the static function HardwareBuffer.Create() Missing method HardwareBuffer.Create(...) Feb 9, 2024
@jpobst jpobst added the bug Component does not function as intended. label Feb 9, 2024
jonpryor pushed a commit that referenced this issue Mar 13, 2024
…8707)

Fixes: #8703

#8730 reported that we did not bind
[`HardwareBuffer.create(int width, int height, int format, int layers, long usage)`][0].

Indeed, in the build logs for `src/Mono.Android`, there is a BG8800
warning about it!

	obj/Debug/net9.0/android-34/mcw/api-34.xml(32327,10): warning BG8800:
	  Unknown parameter type 'Android.Hardware.HardwareBufferUsage' for member
	  'Android.Hardware.HardwareBuffer.Create (int, int, Android.Hardware.HardwareBufferFormat, int, Android.Hardware.HardwareBufferUsage)'

The BG8800 was generated because we attempted to map `long usage` to
an `enum`, but no enum was created as the values are of type `long`,
not `int`.

Manually create a `long`-based `HardwareBufferUsage` enum:

	[Flags]
	/* partial */ enum HardwareBufferUsage : long {
	    None = 0,
	    UsageComposerOverlay = 0x800,
	    // …
	}

However, `generator` does not support `long` enums, and generates
marshalling code using an `int`.  Thus, we need to manually bind
`HardwareBuffer.create()` and [`HardwareBuffer.getUsage()`][1] so we
can replace the `int` machinery with `long`.

While we're at it, audit all of the `BG8800` warnings that are caused
by improper enumification and fix them:

	warning BG8800: Unknown parameter type 'Android.Hardware.HardwareBufferUsage' for member 'Android.Hardware.HardwareBuffer.Create (int, int, Android.Hardware.HardwareBufferFormat, int, Android.Hardware.Hardw...
	warning BG8800: Unknown parameter type 'Android.Hardware.HardwareBufferUsage' for member 'Android.Hardware.HardwareBuffer.IsSupported (int, int, Android.Hardware.HardwareBufferFormat, int, Android.Hardware....
	warning BG8800: Unknown parameter type 'Android.App.Bind' for member 'Android.Content.Context'.
	warning BG8800: Unknown parameter type 'Android.App.Bind' for member 'Android.Content.Context.BindIsolatedService (Android.Content.Intent, Android.App.Bind, java.lang.String, java.util.concurrent.Executor, ...
	warning BG8800: Unknown parameter type 'Android.Graphics.ImageDecoderAllocatorType' for member 'Android.Graphics.ImageDecoder.SetAllocator (Android.Graphics.ImageDecoderAllocatorType)'.
	warning BG8800: Unknown parameter type 'Android.Net.WpsFailureReason' for member 'Android.Net.Wifi.WifiManager.WpsCallback.OnFailed (Android.Net.WpsFailureReason)'.
	warning BG8800: Unknown parameter type 'Android.OS.DeviceTemperatureSource' for member 'Android.OS.HardwarePropertiesManager.GetDeviceTemperatures (Android.OS.DeviceTemperatureType, Android.OS.DeviceTempera...
	warning BG8800: Unknown parameter type 'Android.Telephony.Mbms.DownloadStatus' for member 'Android.Telephony.Mbms.DownloadStatusListener.OnStatusUpdated (Android.Telephony.Mbms.DownloadRequest, Android.Tel...
	warning BG8800: Unknown parameter type 'Android.Telephony.StreamingMethod' for member 'Android.Telephony.Mbms.StreamingServiceCallback.OnStreamMethodUpdated (Android.Telephony.StreamingMethod)'.
	warning BG8800: Unknown parameter type 'Android.Telephony.StreamingState' for member 'Android.Telephony.Mbms.StreamingServiceCallback.OnStreamStateUpdated (Android.Telephony.StreamingState, Android.Telepho...
	warning BG8800: Unknown parameter type 'Android.Icu.Text.CollatorReorderCodes' for member 'Android.Icu.Text.Collator.GetEquivalentReorderCodes (Android.Icu.Text.CollatorReorderCodes)'.
	warning BG8800: Unknown parameter type 'params Android.Icu.Text.CollatorReorderCodes[]' for member 'Android.Icu.Text.Collator.SetReorderCodes (params Android.Icu.Text.CollatorReorderCodes[])'.

This results in new API being surfaced that was previously not being
bound, requiring updates to
`src/Mono.Android/PublicAPI/API-34/PublicAPI.Unshipped.txt`.

One of these new APIs is [`WpsCallback.OnFailed(WpsFailureReason)`][2],
which is a *new* `abstract` method on an existing non-`abstract` type.
Although this is a breaking change, this type previously could not have
been inherited from as the Java-side `abstract` method would not have
been implemented; consider this C# code:

	// This C# code compiles, no warnings or errors:
	class MyCallback : Android.Net.Wifi.WifiManager.WpsCallback {
	    public override void OnStarted(string? pin) {}
	    public override void OnSucceeded() {}
	}

However, the `.csproj` containing `MyCallback` will fail to build:

	obj/Debug/net8.0-android/android/src/crc64475861335642e0f6/MyCallback.java(4,8):
	  javac error JAVAC0000:
	  error: MyCallback is not abstract and does not override abstract method onFailed(int) in WpsCallback

Thus, add it as an "acceptable breakage".

[0]: https://developer.android.com/reference/android/hardware/HardwareBuffer?hl=en#create(int,%20int,%20int,%20int,%20long)
[1]: https://developer.android.com/reference/android/hardware/HardwareBuffer?hl=en#getUsage()
[2]: https://developer.android.com/reference/android/net/wifi/WifiManager.WpsCallback?hl=en#onFailed(int)
@github-actions github-actions bot locked and limited conversation to collaborators Apr 13, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Area: Mono.Android Issues with the Android API binding (Mono.Android.dll). bug Component does not function as intended.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants