Skip to main content

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​

String

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​

GeolocationStatus

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​

GeolocationPosition

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​

NotificationStatus

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​

BiometricStatus

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​

CameraStatus

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​

String

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​

Int32

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​

Int32

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​

Int64

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​

String

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​

IReadOnlyList<String>

Constructors​

DevHostBridge()​

public DevHostBridge()

Methods​

Navigates the host to route.

public ValueTask NavigateAsync(string route, CancellationToken ct = null)

Parameters​

route String

ct CancellationToken

Returns​

ValueTask

GetCurrentRouteAsync(CancellationToken)​

Returns the host's current route.

public ValueTask<string> GetCurrentRouteAsync(CancellationToken ct = null)

Parameters​

ct CancellationToken

Returns​

ValueTask<String>

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

ct CancellationToken

Returns​

ValueTask<String>

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

ct CancellationToken

Returns​

ValueTask

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

ct CancellationToken

Returns​

ValueTask

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

ct CancellationToken

Returns​

ValueTask<BridgeHttpResponse>

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​

ct CancellationToken

Returns​

ValueTask<String>

ClipboardWriteAsync(String, CancellationToken)​

Writes text to the system clipboard.

public ValueTask ClipboardWriteAsync(string text, CancellationToken ct = null)

Parameters​

text String

ct CancellationToken

Returns​

ValueTask

ShareAsync(String, CancellationToken)​

Presents the OS share sheet with text.

public ValueTask ShareAsync(string text, CancellationToken ct = null)

Parameters​

text String

ct CancellationToken

Returns​

ValueTask

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​

ct CancellationToken

Returns​

ValueTask<GeolocationResult>

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​

ct CancellationToken

Returns​

ValueTask<GeolocationStatus>

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

ct CancellationToken

Returns​

ValueTask<NotificationStatus>

ShowNotificationAsync(NotificationSpec, CancellationToken)​

Shows a local notification immediately.

public ValueTask<NotificationStatus> ShowNotificationAsync(NotificationSpec spec, CancellationToken ct = null)

Parameters​

spec NotificationSpec

ct CancellationToken

Returns​

ValueTask<NotificationStatus>

CancelNotificationAsync(Int32, CancellationToken)​

Cancels a scheduled/shown notification by its NotificationSpec.Id.

public ValueTask<NotificationStatus> CancelNotificationAsync(int id, CancellationToken ct = null)

Parameters​

id Int32

ct CancellationToken

Returns​

ValueTask<NotificationStatus>

RequestNotificationPermissionAsync(CancellationToken)​

Requests notification permission (may prompt).

public ValueTask<NotificationStatus> RequestNotificationPermissionAsync(CancellationToken ct = null)

Parameters​

ct CancellationToken

Returns​

ValueTask<NotificationStatus>

CheckNotificationPermissionAsync(CancellationToken)​

Reads notification permission WITHOUT prompting.

public ValueTask<NotificationStatus> CheckNotificationPermissionAsync(CancellationToken ct = null)

Parameters​

ct CancellationToken

Returns​

ValueTask<NotificationStatus>

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

ct CancellationToken

Returns​

ValueTask<BiometricStatus>

IsBiometricAvailableAsync(CancellationToken)​

Checks biometric availability WITHOUT prompting; BiometricStatus.Authenticated means "present + enrolled + ready".

public ValueTask<BiometricStatus> IsBiometricAvailableAsync(CancellationToken ct = null)

Parameters​

ct CancellationToken

Returns​

ValueTask<BiometricStatus>

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

ct CancellationToken

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

ct CancellationToken

Returns​

ValueTask<SecretResult>

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

ct CancellationToken

Returns​

ValueTask<SecretResult>

DeleteSecretAsync(String, CancellationToken)​

Deletes a secret (a no-op if absent).

public ValueTask<SecureStorageStatus> DeleteSecretAsync(string key, CancellationToken ct = null)

Parameters​

key String

ct CancellationToken

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

ct CancellationToken

Returns​

ValueTask<PhotoResult>

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​

ct CancellationToken

Returns​

ValueTask<CameraStatus>

GetPlatformInfoAsync(CancellationToken)​

Returns typed PlatformInfo for the running platform.

public ValueTask<PlatformInfo> GetPlatformInfoAsync(CancellationToken ct = null)

Parameters​

ct CancellationToken

Returns​

ValueTask<PlatformInfo>

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;