Introduce `FSEventStreamCreateOptions` to avoid a slew of .ctor overrides, and make it easier to specify `DeviceToWatch` and `SinceWhenId`. `SinceWhenId` was previously only exposed on the "low level" .ctor, and it's a rather important parameter for supporting events that may have happened while the application was not running.
Make the existing constructors wrap `FSEventStreamCreateOptions` to avoid API break.
This is a followup to #14318. When using device-relative watches, files can be tracked via a tuple of their device ID and inode instead of paths. #14318 exposes inode data on `FSEvent`.
Implements support for `FSEventStreamCreateFlags.UseExtendedData`, fixing #12007.
When `.UseExtendedData` is specified, the event data type changes from `CFString` to `CFDictionary`; the dictionary contains the path (`path` key) and inode (`fileID` key) information for the file and may be extended in the future with other fields. Previously this was crashing because we assumed `CFString` always.
Further add a convenience constructor for monitoring a single path, add the missing `UnscheduleFromRunLoop` APIs, and add `SetDispatchQueue` to allow using dispatch queues directly instead of run loops.
Finally, this PR adds a fairly exhaustive file system test which covers the existing (non-extended) and fixed (extended) creation modes, along with using a dispatch queue instead of run loop.
Fixes https://github.com/xamarin/xamarin-macios/issues/12007
The FSEventStreamCreate method takes a pointer to a structure with context information,
which contains a user-defined pointer value in addition to a few callbacks. Previously
we were passing the GCHandle as a pointer to this structure, which is obviously quite
wrong (as evidenced by a native crash when calling FSEventStreamCreate).
Changes:
* Modify the code to provide the expected context structure instead with the GCHandle
as a field in that structure.
* Add a release callback to the context structure to release the GCHandle.
* This avoids the need for storing the GCHandle as a field in the FSEventStream instance.
* It also avoids also the need for overriding Dispose to release said GCHandle.
* Modify the callback code to use the [UnmanagedCallersOnly] attribute for .NET
(ref: #10470).
This was a regression introduced in 8c99bdc9ad.
Fixes https://github.com/xamarin/xamarin-macios/issues/13325.