Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

UI Controls, Dialogs and Fullscreen

The UI API allows plugins to trigger native Android toast notifications, display blocking confirmation dialogs, and toggle edge-to-edge full-screen mode.

Required Permissions: None (Safe native UI methods).


Native Toast Notifications

dioxamine.showToast()

Displays a native Android toast popup message.

dioxamine.showToast(message: string, duration?: 'short' | 'long'): void

Parameters

  • message (string): The text to display.
  • duration (string, optional): Either 'short' (2 seconds) or 'long' (3.5 seconds). Default: 'short'.

Example

dioxamine.showToast("Settings saved successfully", "short");

Native Material Confirmation Dialogs

dioxamine.showDialog()

Displays a native Material 3 alert dialog and waits for user button selection.

dioxamine.showDialog(options: {
    title: string;
    message: string;
    buttons?: string[];
}): Promise<{ buttonIndex: number }>

Parameters

  • title (string): Dialog heading text.
  • message (string): Descriptive dialog body text.
  • buttons (string[], optional): Array of button labels in order. Default: ['OK'].

Returns

A Promise resolving to { buttonIndex: number }, where buttonIndex corresponds to the clicked button index (0-based). If dismissed without clicking a button, returns -1.

Example

async function confirmReboot() {
    const res = await dioxamine.showDialog({
        title: "Reboot Device",
        message: "Are you sure you want to reboot the target device into Recovery mode?",
        buttons: ["Cancel", "Reboot to Recovery"]
    });

    if (res.buttonIndex === 1) {
        await dioxamine.shellExec("reboot recovery");
        dioxamine.showToast("Rebooting...", "short");
    }
}

Fullscreen Controls

dioxamine.setFullScreen() / dioxamine.fullScreen()

Dynamically toggles whether Dioxamine’s top bar is visible or hidden, giving the plugin the entire screen.

dioxamine.setFullScreen(enable: boolean): void

Parameters

  • enable (boolean): Pass true to enter full-screen mode (hide top bar) or false to restore the windowed top bar.

Note

dioxamine.fullScreen(enable) is also supported as an alias for dioxamine.setFullScreen(enable).

Example

// Toggle fullscreen based on user button click
let isFull = false;

document.getElementById('toggle-fullscreen-btn').addEventListener('click', () => {
    isFull = !isFull;
    dioxamine.setFullScreen(isFull);
});

Exiting and Closing Plugins

1. System Back Gesture / Back Button

Users can exit any plugin at any time by performing the standard Android Back gesture (swiping from the left/right screen edge) or pressing the system Back button.

2. Programmatic Exit (dioxamine.exitPlugin())

Plugins can also provide an in-app “Exit” or “Close” button in their web UI:

dioxamine.exitPlugin(): void

Example

document.getElementById('close-btn').addEventListener('click', () => {
    dioxamine.exitPlugin();
});

Note

dioxamine.closePlugin() is also supported as an alias.


Hardware and System Button Interception (Back and Volume Keys)

By default, pressing the system Back button or performing a back gesture navigates back through internal web history or closes the plugin screen, while pressing the Volume buttons adjusts Android’s system media volume.

Plugins can request button passing to intercept these buttons directly, preventing the default app action and handling the events in JavaScript.

Required Permissions: None (Safe native UI controls).

1. Back Button Interception

When back button interception is requested and granted, pressing the Android Back button or performing an edge-swipe gesture will not close the plugin. Instead, the app passes the back event directly to the plugin’s JavaScript handler. The plugin can then decide what to do (e.g., dismiss an in-app modal, navigate internal SPA routes, or call dioxamine.exitPlugin() / dioxamine.defaultBack()).

dioxamine.onBackButton(listener)

Registers a listener callback for the back button. Setting a function automatically enables back button interception. Passing null or false disables interception.

dioxamine.onBackButton(listener: ((event: ButtonEvent) => void) | null): void

dioxamine.setInterceptBackButton(enable)

Explicitly toggles whether the app intercepts back button presses and passes them to the plugin.

dioxamine.setInterceptBackButton(enable: boolean): void
dioxamine.isInterceptingBackButton(): boolean

dioxamine.defaultBack()

Performs the app’s default back action (navigates web history if available, or closes the plugin). Useful when the plugin decides not to handle a particular back press.

dioxamine.defaultBack(): void

Example: In-Plugin Modal Back Handling

let isModalOpen = false;

// Registering onBackButton automatically enables back button interception
dioxamine.onBackButton((event) => {
    console.log("Back button pressed:", event);
    if (isModalOpen) {
        // Dismiss in-plugin dialog
        closeModal();
    } else {
        // No modal open: perform default back action or exit
        dioxamine.exitPlugin();
    }
});

// To stop intercepting back button:
// dioxamine.onBackButton(null);

User Safety Escape Hatch

To ensure users are never permanently trapped by a frozen or buggy plugin:

  • Windowed Mode: Tapping the native TopAppBar back arrow icon always closes the plugin immediately.
  • Fullscreen / Gesture Navigation: Pressing the back button or swiping the back gesture 3 times in rapid succession (within 2 seconds) triggers an emergency escape hatch that prompts the user and force-exits the plugin.

2. Volume Buttons Interception

When volume button interception is enabled, pressing the physical Volume Up, Volume Down, or Volume Mute buttons on the device will not trigger the Android volume slider. The event is intercepted and forwarded directly to the plugin.

dioxamine.onVolumeButton(listener)

Registers a listener callback for volume button events (down and up). Passing a function automatically enables volume key interception. Passing null or false disables it.

dioxamine.onVolumeButton(listener: ((event: VolumeButtonEvent) => void) | null): void

dioxamine.setInterceptVolumeButtons(enable)

Explicitly toggles whether the app intercepts hardware volume buttons.

dioxamine.setInterceptVolumeButtons(enable: boolean): void
dioxamine.isInterceptingVolumeButtons(): boolean

Event Object Structure

Volume button events contain the following properties:

  • button (string): 'volume_up', 'volume_down', or 'volume_mute'.
  • direction (string): 'up', 'down', or 'mute'.
  • action (string): 'down' (key press) or 'up' (key release).
  • key (string): 'VolumeUp', 'VolumeDown', or 'VolumeMute'.
  • keyCode (number): Android keycode (24 for Volume Up, 25 for Volume Down, 164 for Volume Mute).
  • repeatCount (number): Repeat counter when button is held down (0 for initial press).

Example: Remote Control Volume

// Intercept volume buttons and forward to remote ADB device
dioxamine.onVolumeButton(async (event) => {
    if (event.action !== 'down') return;

    if (event.direction === 'up') {
        console.log("Volume Up pressed - sending ADB keyevent 24");
        await dioxamine.adb.shellExec("input keyevent 24");
    } else if (event.direction === 'down') {
        console.log("Volume Down pressed - sending ADB keyevent 25");
        await dioxamine.adb.shellExec("input keyevent 25");
    }
});

// To restore normal system volume behavior:
// dioxamine.setInterceptVolumeButtons(false);

3. Unified Button API (dioxamine.buttons.*)

All button methods are also available under the dioxamine.buttons namespace:

// Configure both button interceptors at once
dioxamine.buttons.setIntercept({ back: true, volume: true });

// Check current status
const isBackIntercepted = dioxamine.buttons.isInterceptingBackButton();
const isVolumeIntercepted = dioxamine.buttons.isInterceptingVolumeButtons();

// Asynchronous status check
const status = await dioxamine.buttons.getStatusAsync();
// status => { back: true, volume: true }

// Unified button listener for all buttons (back and volume)
dioxamine.buttons.onButton((event) => {
    console.log("Button event:", event.button, event.action);
});

4. DOM Custom Events

Button presses also dispatch DOM Custom Events on the window object:

  • 'dioxamine-back-button': Dispatched when the back button is pressed.
  • 'dioxamine-volume-button': Dispatched on volume button down and up.
  • 'dioxamine-button': Dispatched for both back and volume buttons.
window.addEventListener('dioxamine-back-button', (e) => {
    console.log("DOM Back Event:", e.detail);
});

window.addEventListener('dioxamine-volume-button', (e) => {
    console.log("DOM Volume Event:", e.detail);
});

dioxamine.openBrowser() / dioxamine.openUrl()

Opens an external web URL directly in the default web browser of the host Android device running Dioxamine (not on the connected ADB device).

To protect user safety and prevent unauthorized redirects or phishing attacks, Dioxamine presents a native confirmation dialog to the user displaying the target URL and origin plugin name before launching the browser.

dioxamine.openBrowser(url: string): Promise<{ success: boolean }>

Parameters

  • url (string): The web address to open. Must begin with http:// or https:// and have a valid host (maximum length: 2048 characters).

Returns

A Promise resolving to { success: true } when the user approves the prompt and the browser is launched. If the user dismisses or clicks Cancel, the promise rejects with "User cancelled opening external link". If no browser application is available or the URL format is invalid, it rejects with a descriptive error.

Example

// Open external documentation or repository in host device browser
document.getElementById('docs-link').addEventListener('click', () => {
    dioxamine.openBrowser("https://example.com/docs")
        .then(() => {
            console.log("Browser opened successfully");
        })
        .catch(err => {
            if (err.message.includes("cancelled")) {
                console.log("User cancelled browser launch");
            } else {
                dioxamine.showToast("Failed to open browser: " + err.message, "short");
            }
        });
});

Note

dioxamine.openUrl(url) is also supported as an alias.


Host App Version and Metadata

Plugins can inspect the running Dioxamine application version and identifiers synchronously or asynchronously to perform capability checks or display version info.

dioxamine.getAppVersion() / dioxamine.getVersion()

Returns the host Dioxamine application version information synchronously.

dioxamine.getAppVersion(): AppVersionInfo

dioxamine.getAppVersionAsync() / dioxamine.getVersionAsync()

Returns a Promise resolving to the host Dioxamine application version information.

dioxamine.getAppVersionAsync(): Promise<AppVersionInfo>

dioxamine.appVersion (Property Getter)

Shorthand getter returning the same AppVersionInfo object synchronously.

AppVersionInfo Object Structure

interface AppVersionInfo {
    versionName: string;    // Human-readable release version (e.g. "0.0.4")
    versionCode: number;    // Monotonically increasing build integer (e.g. 10004)
    version: string;        // Alias for versionName (e.g. "0.0.4")
    appName: string;        // Host application title ("Dioxamine")
    applicationId: string;  // Android package identifier ("io.github.rhythmcache.dioxamine")
}

Example

// Synchronous check
const appInfo = dioxamine.getAppVersion();
console.log(`Running on ${appInfo.appName} v${appInfo.versionName} (build ${appInfo.versionCode})`);

// Feature check based on app version code
if (appInfo.versionCode >= 10004) {
    console.log("Hardware button interception is supported by this Dioxamine build");
}

// Or using the property shorthand
document.getElementById('version-tag').textContent = `Dioxamine v${dioxamine.appVersion.versionName}`;

Vibration and Haptic Feedback

Plugins can trigger native tactile feedback for clicks, toggles, errors, success events, or custom durations.

dioxamine.vibrate()

Triggers physical device vibration for a specified duration in milliseconds.

dioxamine.vibrate(durationMs?: number): void
  • durationMs (number, optional): Vibration length in milliseconds (clamped between 1ms and 3000ms). Default: 50.
// Quick 100ms vibration
dioxamine.vibrate(100);

dioxamine.haptics

Rich haptic effects matching modern Android system interaction patterns.

dioxamine.haptics.selection()

Triggers a subtle tick feedback, suitable for sliders, picker adjustments, and small clicks.

dioxamine.haptics.selection();

dioxamine.haptics.impact(style)

Triggers physical impact feedback.

  • style: 'light' | 'medium' | 'heavy'.
dioxamine.haptics.impact('light');
dioxamine.haptics.impact('heavy');

dioxamine.haptics.notification(type)

Triggers pattern feedback for user notification outcomes.

  • type: 'success' | 'warning' | 'error'.
// Double-click error feedback
dioxamine.haptics.notification('error');

// Success feedback
dioxamine.haptics.notification('success');

dioxamine.haptics.cancel()

Cancels any ongoing vibration immediately.

dioxamine.haptics.cancel();