SmartSpectraSdk
Entry point for the SmartSpectra SDK. Most apps use the shared singleton initialized by AndroidX Startup, or call [initialize] with a custom [SmartSpectraConfig] before accessing [shared].
class SmartSpectraSdk
Methods
-
public suspend fun start()Begin processing the selected input. In custom mode, await this call before submitting frames. Camera capture is the default until [useCustomInput] is called.
-
public suspend fun stop()Stop processing. Call [start] again to resume.
-
public fun useCustomInput(frameTransform: FrameTransform = FrameTransform.NONE): CustomInputSelect caller-supplied frames while stopped. No camera discovery, capture, or camera permission is required. Replacing the source invalidates older handles. Throws [SmartSpectraException] with INVALID_STATE during processing or startup.
-
public fun useCamera(selection: CameraSelection)Select SDK camera capture while stopped. Default prefers front, then the first discovered camera. Explicit selections never fall back. Resolution happens when capture starts; unavailable cameras report INPUT_UNAVAILABLE. Throws CONFIGURATION_FAILED for an empty ID and INVALID_STATE while busy. Rejected requests preserve the previous source. Stop/start/reset retain the chosen selection until another source is selected.
-
@Deprecated("Pass an explicit CameraSelection, such as Default or ById(id).") public fun useCamera() -
public suspend fun reset()Stop processing and clear measurement output, retaining the selected input, transform, configuration, and custom-input handle. Call [start] to begin again. Safe to call while stopped; teardown runs off the caller’s thread.
-
public fun requestInsight(text: String): IntDispatch an on-demand insight request alongside the vitals samples buffered since the last send. Requires an active measurement: the engine owns the insight session for the duration of a session, so call this after [start].
-
@SmartSpectraTestingApi public fun setVideoInputEnabled(enabled: Boolean)Enables or disables video-frame input mode for automated testing. While enabled, the SDK does not open the device camera (so no camera hardware or
CAMERApermission is needed) and expects the caller to supply frames through [addVideoFrame]. Select only while stopped; after stopping, toggle back tofalseto return to normal camera capture. Throws [SmartSpectraException] with INVALID_STATE if processing or startup is active. New integrations should use [useCustomInput], which requires no testing opt-in. -
@SmartSpectraTestingApi public fun addVideoFrame(frame: Bitmap, timestampUs: Long)Feeds one decoded video frame into the measurement pipeline while video-frame input mode is active (see [setVideoInputEnabled]). Call after [start] has completed. Decode your recorded clip however you like (for example
MediaMetadataRetrieverorMediaCodec) and deliver frames in playback order. Throws [SmartSpectraException] when video input has not been selected or the frame is rejected. Use [CustomInput.sendFrame] for typed per-frame return values. -
public suspend fun availableCameras(context: Context): List<CameraInfo>Discover camera IDs, optional names, and facing without initializing SmartSpectra, authenticating, or starting capture. No permission prompt is shown. Visibility depends on platform permissions; a snapshot does not guarantee a later capture will succeed. Throws INPUT_UNAVAILABLE when discovery fails. Android currently provides no display names.
-
@JvmStatic @JvmOverloads fun initialize( context: Context, config: SmartSpectraConfig = SmartSpectraConfig(), ): SmartSpectraSdkInitialize the shared SDK instance and apply the provided configuration.
Properties
-
val config: SmartSpectraConfig -
public val metrics: LiveData<Metrics?> = _metricsLatest metrics snapshot (keep-latest). Suitable for scalar state such as pulse rate or status. For the per-sample traces, prefer [metricsFlow]: LiveData can drop intermediate emits under main-thread congestion, losing trace samples.
-
public val metricsFlow: SharedFlow<Metrics> = _metricsFlow.asSharedFlow()Every metrics emission, in order — lossless streaming. Prefer this over [metrics] for the per-sample traces; deliveries are buffered, so nothing is dropped under consumer main-thread congestion.
-
public val insight: LiveData<Insight?> = _insight -
public val imageOutput: LiveData<Bitmap?> = _imageOutputLatest engine display frame as an ARGB_8888 [Bitmap], or
nullwhile image output is disabled. The bitmap is reused from a small internal pool and refilled on later frames.ImageView.setImageBitmapkeeps the reference (it does not copy) and reads the pixels at draw time, so displaying each frame as it arrives is safe — the pool covers the delivery latency. You MUST copy it (Bitmap.copy(...)or draw into your own bitmap) if you retain or cache it, or refresh the view slower than frames arrive; otherwise its pixels change under you. -
val processingStatus: LiveData<ProcessingStatus> -
val validationStatus: LiveData<ValidationStatus?> = _validationStatus -
val error: LiveData<SmartSpectraError?> = _error -
val version: String -
val shared: SmartSpectraSdkShared SmartSpectra SDK instance.
SmartSpectraConfig
Configuration for [SmartSpectraSdk]. Most apps access configuration through [SmartSpectraSdk.config], or pass a prebuilt config to [SmartSpectraSdk.initialize] before using [SmartSpectraSdk.shared].
public class SmartSpectraConfig()
Properties
-
@Deprecated("Use sdk.useCamera(CameraSelection.Front), Back, or ById instead.") public var cameraPosition: CameraPositionLegacy facing preference; defaults to front and updates active capture. Deprecated: use [SmartSpectraSdk.useCamera] with an explicit [CameraSelection]. After typed selection, this preference applies again only after legacy
useCamera(). -
public var apiKey: String? = null -
public var logLevel: SmartSpectraLogLevel = SmartSpectraLogLevel.DEFAULTVerbosity of SDK logging — both the SDK’s own logging and the native engine. Set it before [SmartSpectraSdk.initialize] for full effect; later changes apply to the SDK’s own logging immediately and to the engine when the next measurement session starts. Defaults to [SmartSpectraLogLevel.WARNING] (warnings and errors only).
-
public var imageOutputEnabled: Boolean = true -
public var enableTelemetry: Boolean = trueControls whether the SDK reports anonymous, aggregate usage telemetry. On by default; set
falseto opt out. When enabled, the SDK sends a per-session summary — no raw frames, metric values, file paths, or user/device identifiers — to help Presage improve SDK reliability. Reporting is best-effort and never blocks a measurement. Read when a measurement session starts. -
public var previewSurfaceProvider: Preview.SurfaceProvider?Optional CameraX preview surface supplied by a host app. When set, the SDK binds a CameraX [Preview] use case alongside image analysis so the host can display the camera stream through a native
PreviewViewwithout consuming bitmap image-output frames. -
public var requestedMetrics: List<MetricType>?Metrics the SDK requests for authorization and output. The getter never returns
null— when no list has been set (or after explicitly settingnull), it falls back to [breathingMetrics]. The setter acceptsnullto reset back to that default. -
public val breathingMetrics: List<MetricType> = listOf( MetricType.CHEST_BREATHING, MetricType.ABDOMEN_BREATHING, MetricType.BREATHING_RATE, MetricType.BREATHING_AMPLITUDE, MetricType.APNEA, MetricType.RESPIRATORY_LINE_LENGTH, MetricType.BASELINE, MetricType.INHALE_EXHALE_RATIO, )Breathing metric bundle. Equivalent to leaving [requestedMetrics] unset.
-
public val cardioMetrics: List<MetricType> = listOf( MetricType.PULSE_RATE, MetricType.ARTERIAL_PRESSURE_TRACE, MetricType.HRV, )Cardio metric bundle (pulse rate, arterial pressure trace, HRV). Combine with [breathingMetrics] for the typical “vitals” bundle.
-
public val faceMetrics: List<MetricType> = listOf( MetricType.FACE_LANDMARKS, MetricType.BLINKING, MetricType.TALKING, MetricType.EXPRESSIONS, )Face metric bundle (landmarks, blinking, talking, expressions). Requires the face-metrics-enabled bundle.
-
public val edaMetrics: List<MetricType> = listOf( MetricType.EDA_TRACE, )EDA Proxy (electrodermal activity) trace metric bundle.
CameraPosition
public fun fromLensFacing(@CameraSelector.LensFacing lensFacing: Int): CameraPosition = when (lensFacing)FRONTBACK
CustomInput
Caller-supplied frame input, obtained from [SmartSpectraSdk.useCustomInput]. The handle survives stop/start and reset; selecting another source invalidates it. Submit after start completes, from a worker thread, in timestamp order.
public fun sendFrame(frame: VideoFrame, timestampUs: Long): FrameSubmissionResult
Consumes the borrowed pixels before returning. Timestamps are strictly increasing microseconds on one monotonic timeline per run. Gaps greater than two seconds are rejected; stop and start the SDK to begin a fresh timeline after an interruption. Inspect the returned result: timestamp rejections do not end the session or publish a global SDK error. A later frame on the accepted timeline can still be sent. Calls are serialized; no queue of caller-owned buffers is retained.
public fun sendFrame(frame: Bitmap, timestampUs: Long): FrameSubmissionResult
Copies a bitmap for submission. The caller retains ownership of the bitmap.
public fun sendFrame(frame: ImageProxy): FrameSubmissionResult
Submits a full YUV_420_888 image, applying its clockwise rotationDegrees metadata before the selected session transform. Uses its capture timestamp converted from nanoseconds to microseconds. The caller must close the image after this returns. Unrotated images borrow the planes directly; rotated images require a pixel copy. Cropped images are rejected. Plane buffer positions and limits are preserved.
FrameTransform
Spatial transform applied to every frame in a custom-input session.
NONEROTATE_90_CWROTATE_90_CCWROTATE_180MIRROR_HORIZONTALMIRROR_VERTICAL
PixelFormat
Pixel layout of a [VideoFrame.Packed] buffer.
RGBBGRRGBABGRANV12NV21YUYV
ProcessingStatus
IDLESTARTINGRUNNINGSTOPPINGERROR
ValidationStatus
public data class ValidationStatus( val code: ValidationCode, val hint: String, )
Properties
-
val code: ValidationCode -
val hint: String
ValidationCode
val wireValue: IntOKNO_FACE_FOUNDMULTIPLE_FACES_FOUNDFACE_NOT_CENTEREDFACE_SIZE_OUT_OF_RANGETOO_DARKTOO_BRIGHTCHEST_NOT_VISIBLECAMERA_TUNINGFRAME_RATE_TOO_LOWEXCESSIVE_MOTIONFACE_TOO_CLOSEFACE_TOO_FARFACE_TOO_HIGHFACE_TOO_LOWFACE_NOT_FORWARD
SmartSpectraError
A typed error from the SmartSpectra SDK. Lifecycle methods throw [SmartSpectraException] wrapping this type, and async pipeline failures are published on [SmartSpectraSdk.error].
public data class SmartSpectraError( val code: Code, val message: String, val retryable: Boolean = false, )
Properties
-
val code: Code -
val message: String -
val retryable: Boolean = false
SmartSpectraError.Code
SDK error codes. Raw values are stable across SDK versions and match the C++/Swift wire values.
INVALID_STATEAUTHENTICATION_FAILEDCONFIGURATION_FAILEDCREDIT_EXHAUSTEDNETWORK_ERRORSERVER_ERRORINPUT_UNAVAILABLEPROCESSING_FAILEDFRAME_CONVERSION_FAILEDNON_MONOTONIC_TIMESTAMPTIMESTAMP_GAP
SmartSpectraException
public class SmartSpectraException( public val error: SmartSpectraError, ) : RuntimeException(error.message)
Properties
-
val error: SmartSpectraError
CameraSelection
Requested camera: CameraSelection.Default, Front, Back, or CameraSelection.ById(id) for an exact ID from [SmartSpectraSdk.availableCameras].
CameraSelection.Default
Prefer front, otherwise use the first camera in discovery order.
public data object CameraSelection.Default : CameraSelection
CameraSelection.Front
public data object CameraSelection.Front : CameraSelection
CameraSelection.Back
public data object CameraSelection.Back : CameraSelection
CameraSelection.ById
An opaque, device-local camera ID. An unavailable ID fails without fallback.
public data class CameraSelection.ById(val id: String) : CameraSelection
Properties
-
val id: String
CameraFacing
Camera facing, including cameras that have no front/back position.
FRONTBACKUNKNOWN
CameraLensType
Best-effort lens classification, independent of digital zoom. Android compares the nominal view with the default camera of the same facing. Missing metadata and logical cameras combining multiple lenses report [UNKNOWN].
UNKNOWNWIDE_ANGLEULTRA_WIDETELEPHOTO
CameraInfo
A discoverable camera; availability may change before capture starts.
public data class CameraInfo( val id: String, val name: String? = null, val facing: CameraFacing = CameraFacing.UNKNOWN, val lensType: CameraLensType = CameraLensType.UNKNOWN, )
Properties
-
val id: String -
val name: String? = null -
val facing: CameraFacing = CameraFacing.UNKNOWN -
val lensType: CameraLensType = CameraLensType.UNKNOWN
SmartSpectraLogLevel
Verbosity of SDK logging, set via [SmartSpectraConfig.logLevel]. Levels are cumulative: a level shows its own messages plus everything more severe. The setting covers both the SDK logging and the native engine. [DEBUG] cannot restore debug-only statements that were compiled out of the release engine binary. Wire values are stable across SDK versions and match the C++ SmartSpectraLogLevel values.
DEBUGINFOWARNINGERRORNONE
FramePlane
A borrowed direct buffer with row and pixel strides in bytes.
public data class FramePlane( val buffer: ByteBuffer, val rowStride: Int, val pixelStride: Int, )
Properties
-
val buffer: ByteBuffer -
val rowStride: Int -
val pixelStride: Int
VideoFrame
Caller-owned pixels. Buffers must be direct; only bytes between position and limit are used. Submission leaves those positions and limits unchanged. Keep the buffers alive and unchanged until [CustomInput.sendFrame] returns, then reuse them freely.
VideoFrame.Packed
A single buffer. NV12/NV21 require even dimensions and row stride, with the UV/VU plane immediately after rowStride * height bytes, using the same stride. YUYV requires an even width. Include padding after the final row.
public data class VideoFrame.Packed( val buffer: ByteBuffer, val width: Int, val height: Int, val rowStride: Int, val pixelFormat: PixelFormat, ) : VideoFrame
Properties
-
val buffer: ByteBuffer -
val width: Int -
val height: Int -
val rowStride: Int -
val pixelFormat: PixelFormat
VideoFrame.Yuv420
Flexible YUV 4:2:0 planes. Y pixel stride must be 1; U and V must share pixel stride 1 or 2. Chroma dimensions round up for odd image dimensions. Padding after a plane’s final sample is optional.
public data class VideoFrame.Yuv420( val width: Int, val height: Int, val y: FramePlane, val u: FramePlane, val v: FramePlane, ) : VideoFrame
Properties
-
val width: Int -
val height: Int -
val y: FramePlane -
val u: FramePlane -
val v: FramePlane
FrameSubmissionResult
Result of a frame submission; acceptance does not mean processing has finished.
FrameSubmissionResult.Accepted
public data object FrameSubmissionResult.Accepted : FrameSubmissionResult
FrameSubmissionResult.Rejected
public data class FrameSubmissionResult.Rejected(val error: SmartSpectraError) : FrameSubmissionResult
Properties
-
val error: SmartSpectraError