Package 

Class OrigonClient

  • All Implemented Interfaces:
    java.lang.AutoCloseable

    
    public final class OrigonClient
     implements AutoCloseable
                        

    The primary interface to the Origon platform on Android.

    Backed by libsession.so via SessionBridge. One instance owns one native handle and one smol executor; create at app start, call close (or use use { }) at app shutdown.

    All fallible methods throw SessionException with a structured kind / statusCode / code / message.

    • Method Detail

      • setAttributes

         final Unit setAttributes(JsonObject attributes)

        Replace session-level attributes injected as data.attributes on subsequent startCall / startChat calls. Pass null to clear.

      • startCall

         final StartSessionResponse startCall(StartCallOptions options)

        Start a voice call. Posts /session/start and brings the media plane up.

        Returning does not mean the media plane is connected. The MoQ dial runs in the background: connect success arrives as a ClientEvent.Connected and a dial failure as a ClientEvent.Disconnected (TransportClosed) on the event stream — not as a thrown SessionException. Calling endSession with the returned id while still dialing cancels the in-flight dial. Throws only for the /session/start HTTP failure or a malformed request.

      • startChat

         final StartSessionResponse startChat(StartChatOptions options)

        Start a chat, sending the visitor's first message as part of the call.

        The first message is required — see StartChatOptions for why. The session id comes back BEFORE the message is sent, so the provisional MessageAdded event always has a session to belong to.

        A first message that fails to DELIVER does not throw: the session is live and the failure arrives as MessageUpdated with status = FAILED, so the user can retry. Only a TERMINAL refusal (the session is already gone) throws — returning normally would leave the app rendering a composer on a dead conversation.

      • joinCall

         final Unit joinCall(JoinInput input)

        Attach to a voice call whose StartSessionResponse was obtained out of band (multi-device handoff, deeplink, persisted session).

        Like startCall, the MoQ dial runs in the background — returning here does not mean it is connected; await the Connected / Disconnected event.

      • joinChat

         final Unit joinChat(JoinInput input)

        Attach to an existing chat obtained out of band — the agent / chat-offered path. Completes the attach before returning.

        Takes no first message, unlike startChat: joining is entering a room whose first-message gate is ALREADY released — the visitor has spoken, which is why this participant is being offered the conversation — so there is no deadline left to race.

      • setAudioOutput

         final Unit setAudioOutput(AudioOutputRoute route)

        Override the audio output route (speaker / receiver / Bluetooth).

        Process-global — affects the app's single active voice session, so it takes no session id. A no-op when no call is active. UI typically wraps this as a boolean speaker toggle (AudioOutputRoute.SPEAKER / AudioOutputRoute.AUTOMATIC).

        May block while the audio output stream is reopened; call it off the main thread.

      • notifyTyping

         final Unit notifyTyping(String id)

        Chat-only — register a keystroke on the named session. Cheap to call from a TextWatcher; the SDK debounces outbound <sessionUrl>/typing POSTs so only one wire call fires per typing burst.

      • stopTyping

         final Unit stopTyping(String id)

        Chat-only — force outbound typing state to "off" immediately, cancelling any in-flight debounce. UI fires this on empty-text transitions; the SDK also fires it implicitly on sendMessage and on endSession.

      • uploadAttachment

         final Attachment uploadAttachment(String path, String fileName, String uploadId, Function1<UploadProgress, Unit> onProgress)

        Upload a file from the local filesystem against the widget this client was created for, and return the server-issued Attachment. The SDK streams the body straight from disk; auto-detects MIME from a 256-byte head plus the fileName extension. Runs on Dispatchers.IO.

        There is no sessionId and no session prerequisite — an attachment can be the first thing a visitor sends.

        uploadId doubles as the cancellation key — pass it as attachmentId to deleteAttachment while the upload is in flight to abort it (throws with kind = ERROR_CANCELLED). After completion, use the server-issued attachment.id for deletion.

        onProgress fires from a JNI worker thread; hop to the main thread before touching UI state. percent is null when the total size is unknown.

        Throws SessionException: ERROR_OTHER for filesystem errors, ERROR_ATTACHMENT for precheck failures (empty_file, policy_unsupported_type, policy_type_disabled, policy_too_large), ERROR_HTTP / ERROR_SERVER_UNAVAILABLE for wire failures, ERROR_CANCELLED when cancelled.

      • uploadAttachment

         final Attachment uploadAttachment(Uri uri, String fileName, String uploadId, Function1<UploadProgress, Unit> onProgress)

        Convenience overload that copies a content:// (or file:// / android.resource://) uri into the app's cache dir before uploading, then deletes the cache file once the upload settles. The SDK can't open content:// URIs directly.

      • deleteAttachment

         final Unit deleteAttachment(String attachmentId)

        Cancel an in-flight upload or delete a completed attachment. Session-less like uploadAttachment.

        attachmentId is dual-purpose: it can be either the uploadId passed to uploadAttachment (cancels the in-flight upload — no network call, the upload's awaiter throws SessionException with kind = SessionBridge.ERROR_CANCELLED) or the server-issued attachment.id of a completed upload (issues DELETE on the server). The SDK figures it out: it checks its in-flight uploads table first, then falls through to the wire call.

        Runs on Dispatchers.IO. The server is idempotent on a missing object and answers 204, so a successful return does not prove the id existed; a 404 means the route did not match. An id that could not form a usable path is refused by the SDK before any request.

      • pollEvent

         final ClientEvent pollEvent()

        Polls the next event. Returns null when the queue is idle.