DevHostBridge
Namespace: BlazorNative.Core
A full in-process mock of IMobileBridge for local development and tests — runs as a normal .NET app (no NativeAOT publish), with an in-memory key/value + secret store, route history, real-network HTTP passthrough, and settable status properties so every capability's denial-as-data paths are drivable headless.
public sealed class DevHostBridge : IMobileBridge, System.IDisposable
Inheritance Object → DevHostBridge
Implements IMobileBridge, IDisposable
Attributes NullableContextAttribute, NullableAttribute
Properties
ClipboardSnapshot
Snapshot of the in-memory clipboard — useful in tests.
public string ClipboardSnapshot { get; }
Property Value
GeolocationStatus
The status the next DevHostBridge.GetCurrentPositionAsync(CancellationToken) returns
(default GeolocationStatus.Granted). Set it to drive a denial /
restriction / unavailable / error path headless.
public GeolocationStatus GeolocationStatus { get; set; }
Property Value
GeolocationPosition
The fix returned when DevHostBridge.GeolocationStatus is Granted (Amsterdam by default). Ignored for every non-Granted status.
public GeolocationPosition GeolocationPosition { get; set; }
Property Value
NotificationStatus
The status the next notification op returns (default
NotificationStatus.Granted). Set it to drive a denial /
restriction / error path headless.
public NotificationStatus NotificationStatus { get; set; }
Property Value
Notifications
The notifications recorded by DevHostBridge.ShowNotificationAsync(NotificationSpec, CancellationToken) / DevHostBridge.ScheduleNotificationAsync(NotificationSpec, CancellationToken) and not yet cancelled — useful in tests to assert schedule/show/cancel bookkeeping headless.
public IReadOnlyList<NotificationSpec> Notifications { get; }
Property Value
IReadOnlyList<NotificationSpec>
BiometricAuthResult
The status the next DevHostBridge.AuthenticateAsync(String, CancellationToken) returns AND the
gate the pairing (DevHostBridge.GetSecretWithAuthAsync(String, String, CancellationToken)) checks: an auth-bound
secret is released only when this is BiometricStatus.Authenticated,
else the read is SecureStorageStatus.AuthFailed. Default
Authenticated. Set it to drive a failed / cancelled / locked-out / no-hardware
path headless.
public BiometricStatus BiometricAuthResult { get; set; }
Property Value
SecretSnapshot
Snapshot of the in-memory secret store — useful in tests.
public IReadOnlyDictionary<string, (string Value, bool RequireAuth)> SecretSnapshot { get; }
Property Value
IReadOnlyDictionary<String, (String, Boolean)>
CameraCaptureResult
The status the next DevHostBridge.CapturePhotoAsync(CaptureOptions, CancellationToken) returns (default
CameraStatus.Captured) AND what
DevHostBridge.CheckCameraAvailabilityAsync(CancellationToken) reports (Unavailable → Unavailable,
else Captured = "present + usable"). Set it to drive a cancel / denied /
unavailable / error path headless.
public CameraStatus CameraCaptureResult { get; set; }
Property Value
CameraCapturedPath
The file:// path a Captured result returns (default the canned fixture). Settable so a test can point the composition at another path.
public string? CameraCapturedPath { get; set; }
Property Value
CameraCapturedWidth
The final dimensions / size a Captured result reports (default the fixture's). Ignored for every non-Captured status.
public int CameraCapturedWidth { get; set; }
Property Value
CameraCapturedHeight
The final dimensions / size a Captured result reports (default the fixture's). Ignored for every non-Captured status.
public int CameraCapturedHeight { get; set; }
Property Value
CameraCapturedSizeBytes
The final dimensions / size a Captured result reports (default the fixture's). Ignored for every non-Captured status.
public long CameraCapturedSizeBytes { get; set; }
Property Value
PlatformInfo
Platform info as a raw JSON string (the WASM-era sync shape). Prefer IMobileBridge.GetPlatformInfoAsync(CancellationToken) for the typed form.
public string PlatformInfo { get; }
Property Value
StorageSnapshot
Snapshot of current storage — useful in tests.
public IReadOnlyDictionary<string, string> StorageSnapshot { get; }
Property Value
IReadOnlyDictionary<String, String>
RouteHistory
Full navigation history.
public IReadOnlyList<string> RouteHistory { get; }
Property Value
Constructors
DevHostBridge()
public DevHostBridge()
Methods
NavigateAsync(String, CancellationToken)
Navigates the host to route.
public ValueTask NavigateAsync(string route, CancellationToken ct = null)
Parameters
route String
Returns
GetCurrentRouteAsync(CancellationToken)
Returns the host's current route.
public ValueTask<string> GetCurrentRouteAsync(CancellationToken ct = null)
Parameters
Returns
ReadStorageAsync(String, CancellationToken)
Reads a plain (unencrypted) key/value entry — SharedPreferences on Android, UserDefaults on iOS. Null if the key is absent. For secrets use IMobileBridge.GetSecretAsync(String, CancellationToken).
public ValueTask<string?> ReadStorageAsync(string key, CancellationToken ct = null)
Parameters
key String
Returns
WriteStorageAsync(String, String, CancellationToken)
Writes a plain (unencrypted) key/value entry.
public ValueTask WriteStorageAsync(string key, string value, CancellationToken ct = null)
Parameters
key String
value String
Returns
DeleteStorageAsync(String, CancellationToken)
Deletes a plain key/value entry (a no-op if absent).
public ValueTask DeleteStorageAsync(string key, CancellationToken ct = null)
Parameters
key String
Returns
FetchAsync(BridgeHttpRequest, CancellationToken)
Performs an HTTP request through the host, which owns TLS, proxying
and permissions. Prefer the HttpClient registered by
AddBlazorNativeHttp(), which routes through this.
public async ValueTask<BridgeHttpResponse> FetchAsync(BridgeHttpRequest request, CancellationToken ct = null)
Parameters
request BridgeHttpRequest
Returns
Remarks:
The response is delivered once, complete: the host buffers the whole body and completes the call with a single BridgeHttpResponse whose BridgeHttpResponse.Body is UTF-8 text. There is no incremental delivery path, so streaming protocols (SSE, chunked-read, long-poll) degrade to polling and binary bodies are unsupported.
ClipboardReadAsync(CancellationToken)
Reads the system clipboard's text (empty if none). A host that predates this slot raises NotSupportedException.
public ValueTask<string> ClipboardReadAsync(CancellationToken ct = null)
Parameters
Returns
ClipboardWriteAsync(String, CancellationToken)
Writes text to the system clipboard.
public ValueTask ClipboardWriteAsync(string text, CancellationToken ct = null)
Parameters
text String
Returns
ShareAsync(String, CancellationToken)
Presents the OS share sheet with text.
public ValueTask ShareAsync(string text, CancellationToken ct = null)
Parameters
text String
Returns
GetCurrentPositionAsync(CancellationToken)
Requests-then-fetches the current position in one call: the whole permission dance runs host-side, and the terminal outcome is always a GeolocationResult — a denial is DATA, never an exception or a hang. The token abandons a never-completing call (e.g. the app killed during the prompt) as a cancel, never a leak.
public ValueTask<GeolocationResult> GetCurrentPositionAsync(CancellationToken ct = null)
Parameters
Returns
CheckGeolocationPermissionAsync(CancellationToken)
Reads the current geolocation permission WITHOUT prompting — for a UI that wants to show state before offering to locate.
public ValueTask<GeolocationStatus> CheckGeolocationPermissionAsync(CancellationToken ct = null)
Parameters
Returns
ScheduleNotificationAsync(NotificationSpec, CancellationToken)
Schedules a local notification to fire at NotificationSpec.When. The outcome is a NotificationStatus — a denial is DATA, never a throw.
public ValueTask<NotificationStatus> ScheduleNotificationAsync(NotificationSpec spec, CancellationToken ct = null)
Parameters
spec NotificationSpec
Returns
ShowNotificationAsync(NotificationSpec, CancellationToken)
Shows a local notification immediately.
public ValueTask<NotificationStatus> ShowNotificationAsync(NotificationSpec spec, CancellationToken ct = null)
Parameters
spec NotificationSpec
Returns
CancelNotificationAsync(Int32, CancellationToken)
Cancels a scheduled/shown notification by its NotificationSpec.Id.
public ValueTask<NotificationStatus> CancelNotificationAsync(int id, CancellationToken ct = null)
Parameters
id Int32
Returns
RequestNotificationPermissionAsync(CancellationToken)
Requests notification permission (may prompt).
public ValueTask<NotificationStatus> RequestNotificationPermissionAsync(CancellationToken ct = null)
Parameters
Returns
CheckNotificationPermissionAsync(CancellationToken)
Reads notification permission WITHOUT prompting.
public ValueTask<NotificationStatus> CheckNotificationPermissionAsync(CancellationToken ct = null)
Parameters
Returns
AuthenticateAsync(String, CancellationToken)
Shows an OS biometric prompt with reason and returns
a BiometricStatus — failure / cancellation / lockout / no-hardware
are all DATA, never a throw.
public ValueTask<BiometricStatus> AuthenticateAsync(string reason, CancellationToken ct = null)
Parameters
reason String
Returns
IsBiometricAvailableAsync(CancellationToken)
Checks biometric availability WITHOUT prompting;
BiometricStatus.Authenticated means "present + enrolled + ready".
public ValueTask<BiometricStatus> IsBiometricAvailableAsync(CancellationToken ct = null)
Parameters
Returns
SetSecretAsync(String, String, Boolean, CancellationToken)
Writes an encrypted-at-rest secret. When requireAuth
is true the secret is bound to biometric auth at the OS-key level, so it can only
be read back by IMobileBridge.GetSecretWithAuthAsync(String, String, CancellationToken). Values over
SecretResult.MaxValueBytes are rejected with a status, never crash.
public ValueTask<SecureStorageStatus> SetSecretAsync(string key, string value, bool requireAuth, CancellationToken ct = null)
Parameters
key String
value String
requireAuth Boolean
Returns
ValueTask<SecureStorageStatus>
GetSecretAsync(String, CancellationToken)
Reads a secret that is NOT auth-bound. The value rides
SecretResult.Value only on SecureStorageStatus.Ok.
public ValueTask<SecretResult> GetSecretAsync(string key, CancellationToken ct = null)
Parameters
key String
Returns
GetSecretWithAuthAsync(String, String, CancellationToken)
Reads an auth-bound secret, presenting a biometric prompt with
reason. The OS itself refuses the plaintext without a fresh auth.
public ValueTask<SecretResult> GetSecretWithAuthAsync(string key, string reason, CancellationToken ct = null)
Parameters
key String
reason String
Returns
DeleteSecretAsync(String, CancellationToken)
Deletes a secret (a no-op if absent).
public ValueTask<SecureStorageStatus> DeleteSecretAsync(string key, CancellationToken ct = null)
Parameters
key String
Returns
ValueTask<SecureStorageStatus>
CapturePhotoAsync(CaptureOptions, CancellationToken)
Captures a photo through the system camera. The image crosses back as
a file:// PATH in PhotoResult (the bytes stay on disk), which
is a valid BnImage.Src. A cancel / denied / no-camera outcome is a
CameraStatus value, never a throw. Use options to
bound the file size; the app owns the temp file after return.
public ValueTask<PhotoResult> CapturePhotoAsync(CaptureOptions options, CancellationToken ct = null)
Parameters
options CaptureOptions
Returns
CheckCameraAvailabilityAsync(CancellationToken)
Checks camera availability WITHOUT prompting or launching the UI;
CameraStatus.Captured means "present + usable",
CameraStatus.Unavailable means no camera.
public ValueTask<CameraStatus> CheckCameraAvailabilityAsync(CancellationToken ct = null)
Parameters
Returns
GetPlatformInfoAsync(CancellationToken)
Returns typed PlatformInfo for the running platform.
public ValueTask<PlatformInfo> GetPlatformInfoAsync(CancellationToken ct = null)
Parameters
Returns
InjectEvent(String, String)
Inject a native event programmatically — use from tests or DevTools UI.
public void InjectEvent(string name, string? payload = null)
Parameters
name String
payload String?
Dispose()
public void Dispose()
Events
NativeEvents
Raised when the native host pushes an event into .NET — a lifecycle callback, a notification tap-through, and the like.
public event Action<NativeEvent>? NativeEvents;